camerad: driver camera BPS magic (#37873)

* update blob

* fixed

* didnt catch this

* add back

* needs BLC built in

* for real

---------

Co-authored-by: Comma Device <device@comma.ai>
This commit is contained in:
ZwX1616
2026-04-21 21:04:06 -07:00
committed by GitHub
parent 571a547671
commit ca04b70d0a
5 changed files with 63 additions and 26 deletions
File diff suppressed because one or more lines are too long
+2 -2
View File
@@ -1,9 +1,9 @@
#include "cdm.h"
#include "stddef.h"
int write_dmi(uint8_t *dst, uint64_t *addr, uint32_t length, uint32_t dmi_addr, uint8_t sel) {
int write_dmi(uint8_t *dst, uint64_t *addr, uint32_t length, uint32_t dmi_addr, uint8_t sel, uint8_t opcode) {
struct cdm_dmi_cmd *cmd = (struct cdm_dmi_cmd*)dst;
cmd->cmd = CAM_CDM_CMD_DMI_32;
cmd->cmd = opcode;
cmd->length = length - 1;
cmd->reserved = 0;
cmd->addr = 0; // gets patched in
+5 -5
View File
@@ -6,11 +6,6 @@
#include <vector>
#include <memory>
// our helpers
int write_random(uint8_t *dst, const std::vector<uint32_t> &vals);
int write_cont(uint8_t *dst, uint32_t reg, const std::vector<uint32_t> &vals);
int write_dmi(uint8_t *dst, uint64_t *addr, uint32_t length, uint32_t dmi_addr, uint8_t sel);
// from drivers/media/platform/msm/camera/cam_cdm/cam_cdm_util.{c,h}
enum cam_cdm_command {
@@ -32,6 +27,11 @@ enum cam_cdm_command {
CAM_CDM_CMD_PRIVATE_BASE_MAX = 0x7F
};
// our helpers
int write_random(uint8_t *dst, const std::vector<uint32_t> &vals);
int write_cont(uint8_t *dst, uint32_t reg, const std::vector<uint32_t> &vals);
int write_dmi(uint8_t *dst, uint64_t *addr, uint32_t length, uint32_t dmi_addr, uint8_t sel, uint8_t opcode = CAM_CDM_CMD_DMI_32);
/**
* struct cdm_regrandom_cmd - Definition for CDM random register command.
* @count: Number of register writes
+49 -13
View File
@@ -467,7 +467,7 @@ void SpectraCamera::config_bps(int idx, int request_id) {
*/
int size = sizeof(struct cam_packet) + sizeof(struct cam_cmd_buf_desc)*2 + sizeof(struct cam_buf_io_cfg)*2;
size += sizeof(struct cam_patch_desc)*9;
size += sizeof(struct cam_patch_desc)*12;
uint32_t cam_packet_handle = 0;
auto pkt = m->mem_mgr.alloc<struct cam_packet>(size, &cam_packet_handle);
@@ -545,8 +545,15 @@ void SpectraCamera::config_bps(int idx, int request_id) {
int cdm_len = 0;
if (bps_lin_reg.size() == 0) {
// set first knee pt to do BLC
uint32_t new_knee[8];
new_knee[0] = sensor->black_level << (14 - sensor->bits_per_pixel);
for (int i = 0; i < 7; i++) {
uint32_t pts = sensor->linearization_pts[i / 2];
new_knee[i + 1] = (i % 2 == 0) ? (pts >> 16) : (pts & 0xffff);
}
for (int i = 0; i < 4; i++) {
bps_lin_reg.push_back(((sensor->linearization_pts[i] & 0xffff) << 0x10) | (sensor->linearization_pts[i] >> 0x10));
bps_lin_reg.push_back((new_knee[2*i + 1] << 16) | new_knee[2*i]);
}
}
@@ -569,20 +576,24 @@ void SpectraCamera::config_bps(int idx, int request_id) {
0x00000080,
0x00800066,
});
// linearization, EN=0
// linearization
cdm_len += write_cont((unsigned char *)bps_cdm_program_array.ptr + cdm_len, 0x1868, bps_lin_reg);
cdm_len += write_cont((unsigned char *)bps_cdm_program_array.ptr + cdm_len, 0x1878, bps_lin_reg);
cdm_len += write_cont((unsigned char *)bps_cdm_program_array.ptr + cdm_len, 0x1888, bps_lin_reg);
cdm_len += write_cont((unsigned char *)bps_cdm_program_array.ptr + cdm_len, 0x1898, bps_lin_reg);
/*
uint8_t *start = (unsigned char *)bps_cdm_program_array.ptr + cdm_len;
uint64_t addr;
cdm_len += write_dmi((unsigned char *)bps_cdm_program_array.ptr + cdm_len, &addr, sensor->linearization_lut.size()*sizeof(uint32_t), 0x1808, 1);
patches.push_back(addr - (uint64_t)start);
*/
cdm_len += write_dmi((unsigned char *)bps_cdm_program_array.ptr + cdm_len, &addr, sensor->linearization_lut.size()*sizeof(uint32_t), 0x1808, 1, CAM_CDM_CMD_DMI);
patches.push_back(addr - (uint64_t)bps_cdm_program_array.ptr);
// color correction
cdm_len += write_cont((unsigned char *)bps_cdm_program_array.ptr + cdm_len, 0x2e68, bps_ccm_reg);
// gamma
for (uint8_t ch = 1; ch <= 3; ch++) {
cdm_len += write_dmi((unsigned char *)bps_cdm_program_array.ptr + cdm_len, &addr, sensor->gamma_lut_rgb.size()*sizeof(uint32_t), 0x3208, ch, CAM_CDM_CMD_DMI);
patches.push_back(addr - (uint64_t)bps_cdm_program_array.ptr);
}
cdm_len += build_common_ife_bps((unsigned char *)bps_cdm_program_array.ptr + cdm_len, cc, sensor.get(), patches, false);
pa->length = cdm_len - 1;
@@ -664,11 +675,16 @@ void SpectraCamera::config_bps(int idx, int request_id) {
// *** patches ***
{
assert(patches.size() == 0 | patches.size() == 1);
assert(patches.size() == 0 || patches.size() == 4);
pkt->patch_offset = sizeof(struct cam_cmd_buf_desc)*pkt->num_cmd_buf + sizeof(struct cam_buf_io_cfg)*pkt->num_io_configs;
if (patches.size() > 0) {
add_patch(pkt.get(), bps_cmd.handle, patches[0], bps_linearization_lut.handle, 0);
// linearization LUT
add_patch(pkt.get(), bps_cdm_program_array.handle, patches[0], bps_linearization_lut.handle, 0);
// gamma LUTs
for (int i = 0; i < 3; i++) {
add_patch(pkt.get(), bps_cdm_program_array.handle, patches[i+1], bps_gamma_lut.handle, 0);
}
}
// input frame
@@ -1170,10 +1186,30 @@ void SpectraCamera::configICP() {
bps_cdm_striping_bl.init(m, 0xa100, 0x20, true, m->icp_device_iommu);
// LUTs
/*
assert(sensor->linearization_lut.size() == 36);
bps_linearization_lut.init(m, sensor->linearization_lut.size()*sizeof(uint32_t), 0x20, true, m->icp_device_iommu);
memcpy(bps_linearization_lut.ptr, sensor->linearization_lut.data(), bps_linearization_lut.size);
*/
// bit shift linearization_lut to bps specs, also compensate for black level here
uint32_t bl = sensor->black_level << (14 - sensor->bits_per_pixel);
uint32_t* bps_lut = (uint32_t*)bps_linearization_lut.ptr;
for (size_t i = 0; i < sensor->linearization_lut.size(); i++) {
size_t seg = i / 4;
size_t ch = i % 4;
if (seg == 0) {
bps_lut[i] = 0;
continue;
}
uint32_t e = sensor->linearization_lut[(seg - 1) * 4 + ch];
uint32_t base = e & 0x3fff;
uint32_t slope_q11 = (e >> 14) & 0x3fff;
uint32_t slope_q12 = std::min<uint32_t>(slope_q11 << 1, 0x3fff);
base = (base > bl) ? (base - bl) : 0;
bps_lut[i] = base | (slope_q12 << 14);
}
assert(sensor->gamma_lut_rgb.size() == 64);
bps_gamma_lut.init(m, sensor->gamma_lut_rgb.size()*sizeof(uint32_t), 0x20, true, m->icp_device_iommu);
memcpy(bps_gamma_lut.ptr, sensor->gamma_lut_rgb.data(), bps_gamma_lut.size);
}
void SpectraCamera::configCSIPHY() {
+1
View File
@@ -173,6 +173,7 @@ public:
SpectraBuf bps_iq;
SpectraBuf bps_striping;
SpectraBuf bps_linearization_lut;
SpectraBuf bps_gamma_lut;
std::vector<uint32_t> bps_lin_reg;
std::vector<uint32_t> bps_ccm_reg;