mirror of
https://github.com/infiniteCable2/openpilot.git
synced 2026-08-05 16:26:10 +08:00
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:
File diff suppressed because one or more lines are too long
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user