mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 11:26:02 +09:00
media: rockchip: isp: enum multi isp size at power on
Change-Id: Iace3eb94bef514413708958c383f591b082cb341 Signed-off-by: Cai YiWei <cyw@rock-chips.com>
This commit is contained in:
@@ -947,8 +947,7 @@ static void restrict_rsz_resolution(struct rkisp_stream *stream,
|
||||
max_rsz->width = t->out_fmt.width / 4;
|
||||
max_rsz->height = t->out_fmt.height / 4;
|
||||
} else if (stream->id == RKISP_STREAM_LUMA) {
|
||||
bool bigmode = rkisp_params_check_bigmode(&dev->params_vdev);
|
||||
u32 div = bigmode ? 32 : 16;
|
||||
u32 div = dev->is_bigmode ? 32 : 16;
|
||||
|
||||
max_rsz->width = input_win->width / div;
|
||||
max_rsz->height = input_win->height / div;
|
||||
|
||||
@@ -246,5 +246,8 @@ struct rkisp_device {
|
||||
bool is_bigmode;
|
||||
|
||||
struct rkisp_vicap_input vicap_in;
|
||||
|
||||
u8 multi_mode;
|
||||
u8 multi_index;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -803,14 +803,20 @@ static int rkisp_hw_probe(struct platform_device *pdev)
|
||||
if (!hw_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
match_data = match->data;
|
||||
hw_dev->is_unite = match_data->unite;
|
||||
dev_set_drvdata(dev, hw_dev);
|
||||
hw_dev->dev = dev;
|
||||
hw_dev->is_thunderboot = IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP);
|
||||
dev_info(dev, "is_thunderboot: %d\n", hw_dev->is_thunderboot);
|
||||
hw_dev->max_in.w = 0;
|
||||
hw_dev->max_in.h = 0;
|
||||
hw_dev->max_in.fps = 0;
|
||||
of_property_read_u32_array(node, "max-input", &hw_dev->max_in.w, 3);
|
||||
memset(&hw_dev->max_in, 0, sizeof(hw_dev->max_in));
|
||||
if (!of_property_read_u32_array(node, "max-input", &hw_dev->max_in.w, 3)) {
|
||||
hw_dev->max_in.is_fix = true;
|
||||
if (hw_dev->is_unite) {
|
||||
hw_dev->max_in.w /= 2;
|
||||
hw_dev->max_in.w += RKMOUDLE_UNITE_EXTEND_PIXEL;
|
||||
}
|
||||
}
|
||||
dev_info(dev, "max input:%dx%d@%dfps\n",
|
||||
hw_dev->max_in.w, hw_dev->max_in.h, hw_dev->max_in.fps);
|
||||
hw_dev->grf = syscon_regmap_lookup_by_phandle(node, "rockchip,grf");
|
||||
@@ -836,7 +842,6 @@ static int rkisp_hw_probe(struct platform_device *pdev)
|
||||
goto err;
|
||||
}
|
||||
|
||||
match_data = match->data;
|
||||
hw_dev->base_next_addr = NULL;
|
||||
if (match_data->unite) {
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
||||
@@ -971,6 +976,7 @@ static int __maybe_unused rkisp_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct rkisp_hw_dev *hw_dev = dev_get_drvdata(dev);
|
||||
void __iomem *base = hw_dev->base_addr;
|
||||
struct rkisp_device *isp;
|
||||
int mult = hw_dev->is_unite ? 2 : 1;
|
||||
int ret, i;
|
||||
|
||||
@@ -979,15 +985,33 @@ static int __maybe_unused rkisp_runtime_resume(struct device *dev)
|
||||
return ret;
|
||||
|
||||
enable_sys_clk(hw_dev);
|
||||
|
||||
memset(hw_dev->isp_size, 0, sizeof(hw_dev->isp_size));
|
||||
if (!hw_dev->max_in.is_fix) {
|
||||
hw_dev->max_in.w = 0;
|
||||
hw_dev->max_in.h = 0;
|
||||
}
|
||||
for (i = 0; i < hw_dev->dev_num; i++) {
|
||||
struct rkisp_device *isp = hw_dev->isp[i];
|
||||
void *buf;
|
||||
u32 w, h;
|
||||
|
||||
isp = hw_dev->isp[i];
|
||||
if (!isp || (isp && !isp->is_hw_link))
|
||||
continue;
|
||||
if (hw_dev->dev_link_num++)
|
||||
hw_dev->is_single = false;
|
||||
w = isp->isp_sdev.in_crop.width;
|
||||
h = isp->isp_sdev.in_crop.height;
|
||||
if (hw_dev->is_unite)
|
||||
w = w / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL;
|
||||
hw_dev->isp_size[i].w = w;
|
||||
hw_dev->isp_size[i].h = h;
|
||||
hw_dev->isp_size[i].size = w * h;
|
||||
if (!hw_dev->max_in.is_fix) {
|
||||
if (hw_dev->max_in.w < w)
|
||||
hw_dev->max_in.w = w;
|
||||
if (hw_dev->max_in.h < h)
|
||||
hw_dev->max_in.h = h;
|
||||
}
|
||||
buf = isp->sw_base_addr;
|
||||
memset(buf, 0, RKISP_ISP_SW_MAX_SIZE * mult);
|
||||
memcpy_fromio(buf, base, RKISP_ISP_SW_REG_SIZE);
|
||||
@@ -998,6 +1022,12 @@ static int __maybe_unused rkisp_runtime_resume(struct device *dev)
|
||||
}
|
||||
default_sw_reg_flag(hw_dev->isp[i]);
|
||||
}
|
||||
for (i = 0; i < hw_dev->dev_num; i++) {
|
||||
isp = hw_dev->isp[i];
|
||||
if (!isp || (isp && !isp->is_hw_link))
|
||||
continue;
|
||||
rkisp_params_check_bigmode(&isp->params_vdev);
|
||||
}
|
||||
hw_dev->monitor.is_en = rkisp_monitor;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -40,6 +40,12 @@ struct rkisp_sram {
|
||||
u32 size;
|
||||
};
|
||||
|
||||
struct rkisp_size_info {
|
||||
u32 w;
|
||||
u32 h;
|
||||
u32 size;
|
||||
};
|
||||
|
||||
struct rkisp_hw_dev {
|
||||
const struct isp_match_data *match_data;
|
||||
struct platform_device *pdev;
|
||||
@@ -55,6 +61,7 @@ struct rkisp_hw_dev {
|
||||
int mipi_irq;
|
||||
enum rkisp_isp_ver isp_ver;
|
||||
struct rkisp_device *isp[DEV_MAX];
|
||||
struct rkisp_size_info isp_size[DEV_MAX];
|
||||
int dev_num;
|
||||
int dev_link_num;
|
||||
int cur_dev_id;
|
||||
|
||||
@@ -78,6 +78,7 @@ struct max_input {
|
||||
u32 w;
|
||||
u32 h;
|
||||
u32 fps;
|
||||
bool is_fix;
|
||||
};
|
||||
|
||||
struct rkisp_ispp_mode {
|
||||
|
||||
@@ -3795,35 +3795,161 @@ rkisp_alloc_bay3d_buf(struct rkisp_isp_params_vdev *params_vdev,
|
||||
static bool
|
||||
rkisp_params_check_bigmode_v21(struct rkisp_isp_params_vdev *params_vdev)
|
||||
{
|
||||
struct rkisp_device *ispdev = params_vdev->dev;
|
||||
struct device *dev = params_vdev->dev->dev;
|
||||
struct rkisp_hw_dev *hw = params_vdev->dev->hw_dev;
|
||||
struct v4l2_rect *out_crop = ¶ms_vdev->dev->isp_sdev.out_crop;
|
||||
u32 width = hw->max_in.w ? hw->max_in.w : out_crop->width;
|
||||
u32 height = hw->max_in.h ? hw->max_in.h : out_crop->height;
|
||||
u32 size = width * height;
|
||||
struct v4l2_rect *crop = ¶ms_vdev->dev->isp_sdev.in_crop;
|
||||
u32 width = hw->max_in.w, height = hw->max_in.h, size = width * height;
|
||||
u32 bigmode_max_w, bigmode_max_size;
|
||||
int k = 0, idx1[DEV_MAX] = { 0 };
|
||||
int n = 0, idx2[DEV_MAX] = { 0 };
|
||||
int i = 0, j = 0;
|
||||
bool is_bigmode = false;
|
||||
|
||||
if (hw->dev_link_num > 2) {
|
||||
switch (hw->dev_link_num) {
|
||||
case 4:
|
||||
bigmode_max_w = ISP21_VIR4_AUTO_BIGMODE_WIDTH;
|
||||
bigmode_max_size = ISP21_VIR4_NOBIG_OVERFLOW_SIZE;
|
||||
if (width > ISP21_VIR4_MAX_WIDTH || size > ISP21_VIR4_MAX_SIZE)
|
||||
dev_err(dev, "%dx%d > max:3840x2160 for %d virtual isp\n",
|
||||
width, height, hw->dev_link_num);
|
||||
} else if (hw->dev_link_num > 1) {
|
||||
ispdev->multi_index = ispdev->dev_id;
|
||||
ispdev->multi_mode = 2;
|
||||
/* internal buf of hw divided to four parts
|
||||
* bigmode nobigmode
|
||||
* _________ max width:1920 max width:960
|
||||
* |_sensor0_| max size:1920*1080 max size:960*540
|
||||
* |_sensor1_| max size:1920*1080 max size:960*540
|
||||
* |_sensor2_| max size:1920*1080 max size:960*540
|
||||
* |_sensor3_| max size:1920*1080 max size:960*540
|
||||
*/
|
||||
for (i = 0; i < hw->dev_num; i++) {
|
||||
if (hw->isp_size[i].w <= ISP21_VIR4_MAX_WIDTH &&
|
||||
hw->isp_size[i].size <= ISP21_VIR4_MAX_SIZE)
|
||||
continue;
|
||||
dev_err(dev, "four virtual isp max:1920x1080, isp%d:%dx%d\n",
|
||||
i, hw->isp_size[i].w, hw->isp_size[i].h);
|
||||
is_bigmode = true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
bigmode_max_w = ISP21_VIR4_AUTO_BIGMODE_WIDTH;
|
||||
bigmode_max_size = ISP21_VIR4_NOBIG_OVERFLOW_SIZE;
|
||||
ispdev->multi_index = ispdev->dev_id;
|
||||
ispdev->multi_mode = 2;
|
||||
/* case0: bigmode nobigmode
|
||||
* _________ max width:1920 max width:960
|
||||
* |_sensor0_| max size:1920*1080 max size:960*540
|
||||
* |_sensor1_| max size:1920*1080 max size:960*540
|
||||
* |_sensor2_| max size:1920*1080 max size:960*540
|
||||
* |_________|
|
||||
*
|
||||
* case1: bigmode special reg cfg
|
||||
* _________ max width:4096
|
||||
* | sensor0 | max size:1920*1080*2 mode=0 index=0
|
||||
* |_________|
|
||||
* |_sensor1_| max size:1920*1080 mode=2 index=2
|
||||
* |_sensor2_| max size:1920*1080 mode=2 index=3
|
||||
* max width:1920
|
||||
*/
|
||||
for (i = 0; i < hw->dev_num; i++) {
|
||||
if (!hw->isp_size[i].size) {
|
||||
if (i < hw->dev_link_num)
|
||||
idx2[n++] = i;
|
||||
continue;
|
||||
}
|
||||
if (hw->isp_size[i].w <= ISP21_VIR4_MAX_WIDTH &&
|
||||
hw->isp_size[i].size <= ISP21_VIR4_MAX_SIZE)
|
||||
continue;
|
||||
idx1[k++] = i;
|
||||
}
|
||||
if (k) {
|
||||
is_bigmode = true;
|
||||
if (k != 1 ||
|
||||
(hw->isp_size[idx1[0]].size > ISP21_VIR4_MAX_SIZE * 2)) {
|
||||
dev_err(dev, "three virtual isp max:1920x1080\n");
|
||||
} else {
|
||||
if (idx1[0] == ispdev->dev_id) {
|
||||
ispdev->multi_mode = 0;
|
||||
ispdev->multi_index = 0;
|
||||
} else {
|
||||
ispdev->multi_mode = 2;
|
||||
if (ispdev->multi_index == 0 ||
|
||||
ispdev->multi_index == 1)
|
||||
ispdev->multi_index = 3;
|
||||
}
|
||||
}
|
||||
} else if (ispdev->multi_index >= hw->dev_link_num) {
|
||||
ispdev->multi_index = idx2[ispdev->multi_index - hw->dev_link_num];
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
bigmode_max_w = ISP21_VIR2_AUTO_BIGMODE_WIDTH;
|
||||
bigmode_max_size = ISP21_VIR2_NOBIG_OVERFLOW_SIZE;
|
||||
if (width > ISP21_VIR2_MAX_WIDTH || size > ISP21_VIR2_MAX_SIZE)
|
||||
dev_err(dev, "%dx%d > max:1920x1080 for %d virtual isp\n",
|
||||
width, height, hw->dev_link_num);
|
||||
} else {
|
||||
ispdev->multi_index = ispdev->dev_id;
|
||||
ispdev->multi_mode = 1;
|
||||
/* case0: bigmode nobigmode
|
||||
* _________ max width:3840 max width:1920
|
||||
* | sensor0 | max size:3840*2160 max size:1920*1080
|
||||
* |_________|
|
||||
* | sensor1 | max size:3840*2160 max size:1920*1080
|
||||
* |_________|
|
||||
*
|
||||
* case1: bigmode special reg cfg
|
||||
* _________ max width:4096
|
||||
* | sensor0 | max size:1920*1080*3 mode=0 index=0
|
||||
* | |
|
||||
* |_________|
|
||||
* |_sensor1_| max size:1920*1080 mode=2 index=3
|
||||
* max width:1920
|
||||
*/
|
||||
for (i = 0; i < hw->dev_num; i++) {
|
||||
if (!hw->isp_size[i].size) {
|
||||
if (i < hw->dev_link_num)
|
||||
idx2[n++] = i;
|
||||
continue;
|
||||
}
|
||||
if (hw->isp_size[i].w <= ISP21_VIR2_MAX_WIDTH &&
|
||||
hw->isp_size[i].size <= ISP21_VIR2_MAX_SIZE) {
|
||||
if (hw->isp_size[i].w > ISP21_VIR4_MAX_WIDTH ||
|
||||
hw->isp_size[i].size > ISP21_VIR4_MAX_SIZE)
|
||||
j++;
|
||||
continue;
|
||||
}
|
||||
idx1[k++] = i;
|
||||
}
|
||||
if (k) {
|
||||
is_bigmode = true;
|
||||
if (k == 2 || j ||
|
||||
hw->isp_size[idx1[k - 1]].size > ISP21_VIR4_MAX_SIZE * 3) {
|
||||
dev_err(dev, "two virtual isp max:3840x2160\n");
|
||||
} else {
|
||||
if (idx1[0] == ispdev->dev_id) {
|
||||
ispdev->multi_mode = 0;
|
||||
ispdev->multi_index = 0;
|
||||
} else {
|
||||
ispdev->multi_mode = 2;
|
||||
ispdev->multi_index = 3;
|
||||
}
|
||||
}
|
||||
} else if (ispdev->multi_index >= hw->dev_link_num) {
|
||||
ispdev->multi_index = idx2[ispdev->multi_index - hw->dev_link_num];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
bigmode_max_w = ISP21_AUTO_BIGMODE_WIDTH;
|
||||
bigmode_max_size = ISP21_NOBIG_OVERFLOW_SIZE;
|
||||
ispdev->multi_mode = 0;
|
||||
ispdev->multi_index = 0;
|
||||
width = crop->width;
|
||||
height = crop->height;
|
||||
size = width * height;
|
||||
break;
|
||||
}
|
||||
|
||||
if (width > bigmode_max_w || size > bigmode_max_size)
|
||||
if (!is_bigmode &&
|
||||
(width > bigmode_max_w || size > bigmode_max_size))
|
||||
is_bigmode = true;
|
||||
return is_bigmode;
|
||||
|
||||
return ispdev->is_bigmode = is_bigmode;
|
||||
}
|
||||
|
||||
/* Not called when the camera active, thus not isr protection. */
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#define ISP32_VIR2_NOBIG_OVERFLOW_SIZE (960 * 540)
|
||||
#define ISP32_VIR2_AUTO_BIGMODE_WIDTH 960
|
||||
#define ISP32_VIR4_NOBIG_OVERFLOW_SIZE (640 * 400)
|
||||
#define ISP32_VIR4_AUTO_BIGMODE_WIDTH 1280
|
||||
#define ISP32_VIR4_AUTO_BIGMODE_WIDTH 640
|
||||
|
||||
#define ISP32_VIR2_MAX_WIDTH 1920
|
||||
#define ISP32_VIR2_MAX_SIZE (1920 * 1080)
|
||||
@@ -4179,35 +4179,159 @@ err_3dlut:
|
||||
static bool
|
||||
rkisp_params_check_bigmode_v32(struct rkisp_isp_params_vdev *params_vdev)
|
||||
{
|
||||
struct rkisp_device *ispdev = params_vdev->dev;
|
||||
struct device *dev = params_vdev->dev->dev;
|
||||
struct rkisp_hw_dev *hw = params_vdev->dev->hw_dev;
|
||||
struct v4l2_rect *out_crop = ¶ms_vdev->dev->isp_sdev.out_crop;
|
||||
u32 width = hw->max_in.w ? hw->max_in.w : out_crop->width;
|
||||
u32 height = hw->max_in.h ? hw->max_in.h : out_crop->height;
|
||||
u32 size = width * height;
|
||||
struct v4l2_rect *crop = ¶ms_vdev->dev->isp_sdev.in_crop;
|
||||
u32 width = hw->max_in.w, height = hw->max_in.h, size = width * height;
|
||||
u32 bigmode_max_w, bigmode_max_size;
|
||||
int k = 0, idx1[DEV_MAX] = { 0 };
|
||||
int n = 0, idx2[DEV_MAX] = { 0 };
|
||||
int i = 0, j = 0;
|
||||
bool is_bigmode = false;
|
||||
|
||||
if (hw->dev_link_num > 2) {
|
||||
switch (hw->dev_link_num) {
|
||||
case 4:
|
||||
bigmode_max_w = ISP32_VIR4_AUTO_BIGMODE_WIDTH;
|
||||
bigmode_max_size = ISP32_VIR4_NOBIG_OVERFLOW_SIZE;
|
||||
if (width > ISP32_VIR4_MAX_WIDTH || size > ISP32_VIR4_MAX_SIZE)
|
||||
dev_err(dev, "%dx%d > max:2560x1536 for %d virtual isp\n",
|
||||
width, height, hw->dev_link_num);
|
||||
} else if (hw->dev_link_num > 1) {
|
||||
ispdev->multi_index = ispdev->dev_id;
|
||||
ispdev->multi_mode = 2;
|
||||
/* internal buf of hw divided to four parts
|
||||
* bigmode nobigmode
|
||||
* _________ max width:1280 max width:640
|
||||
* |_sensor0_| max size:1280*800 max size:640*400
|
||||
* |_sensor1_| max size:1280*800 max size:640*400
|
||||
* |_sensor2_| max size:1280*800 max size:640*400
|
||||
* |_sensor3_| max size:1280*800 max size:640*400
|
||||
*/
|
||||
for (i = 0; i < hw->dev_num; i++) {
|
||||
if (hw->isp_size[i].w <= ISP32_VIR4_MAX_WIDTH &&
|
||||
hw->isp_size[i].size <= ISP32_VIR4_MAX_SIZE)
|
||||
continue;
|
||||
dev_err(dev, "four virtual isp max:1280x800\n");
|
||||
is_bigmode = true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
bigmode_max_w = ISP32_VIR4_AUTO_BIGMODE_WIDTH;
|
||||
bigmode_max_size = ISP32_VIR4_NOBIG_OVERFLOW_SIZE;
|
||||
ispdev->multi_index = ispdev->dev_id;
|
||||
ispdev->multi_mode = 2;
|
||||
/* case0: bigmode nobigmode
|
||||
* _________ max width:1280 max width:640
|
||||
* |_sensor0_| max size:1280*800 max size:640*400
|
||||
* |_sensor1_| max size:1280*800 max size:640*400
|
||||
* |_sensor2_| max size:1280*800 max size:640*400
|
||||
* |_________|
|
||||
*
|
||||
* case1: bigmode special reg cfg
|
||||
* _________ max width:3072
|
||||
* | sensor0 | max size:1280*800*2 mode=0 index=0
|
||||
* |_________|
|
||||
* |_sensor1_| max size:1280*800 mode=2 index=2
|
||||
* |_sensor2_| max size:1280*800 mode=2 index=3
|
||||
* max width:1280
|
||||
*/
|
||||
for (i = 0; i < hw->dev_num; i++) {
|
||||
if (!hw->isp_size[i].size) {
|
||||
if (i < hw->dev_link_num)
|
||||
idx2[n++] = i;
|
||||
continue;
|
||||
}
|
||||
if (hw->isp_size[i].w <= ISP32_VIR4_MAX_WIDTH &&
|
||||
hw->isp_size[i].size <= ISP32_VIR4_MAX_SIZE)
|
||||
continue;
|
||||
idx1[k++] = i;
|
||||
}
|
||||
if (k) {
|
||||
is_bigmode = true;
|
||||
if (k != 1 ||
|
||||
(hw->isp_size[idx1[0]].size > ISP32_VIR4_MAX_SIZE * 2)) {
|
||||
dev_err(dev, "three virtual isp max:1280x800\n");
|
||||
} else {
|
||||
if (idx1[0] == ispdev->dev_id) {
|
||||
ispdev->multi_mode = 0;
|
||||
ispdev->multi_index = 0;
|
||||
} else {
|
||||
ispdev->multi_mode = 2;
|
||||
if (ispdev->multi_index == 0 ||
|
||||
ispdev->multi_index == 1)
|
||||
ispdev->multi_index = 3;
|
||||
}
|
||||
}
|
||||
} else if (ispdev->multi_index >= hw->dev_link_num) {
|
||||
ispdev->multi_index = idx2[ispdev->multi_index - hw->dev_link_num];
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
bigmode_max_w = ISP32_VIR2_AUTO_BIGMODE_WIDTH;
|
||||
bigmode_max_size = ISP32_VIR2_NOBIG_OVERFLOW_SIZE;
|
||||
if (width > ISP32_VIR2_MAX_WIDTH || size > ISP32_VIR2_MAX_SIZE)
|
||||
dev_err(dev, "%dx%d > max:3840x2160 for %d virtual isp\n",
|
||||
width, height, hw->dev_link_num);
|
||||
} else {
|
||||
ispdev->multi_index = ispdev->dev_id;
|
||||
ispdev->multi_mode = 1;
|
||||
/* case0: bigmode nobigmode
|
||||
* _________ max width:1920 max width:1920
|
||||
* | sensor0 | max size:1920*1080 max size:1920*1080
|
||||
* |_________|
|
||||
* | sensor1 | max size:1920*1080 max size:1920*1080
|
||||
* |_________|
|
||||
*
|
||||
* case1: bigmode special reg cfg
|
||||
* _________ max width:3072
|
||||
* | sensor0 | max size:1280*800*3 mode=0 index=0
|
||||
* | |
|
||||
* |_________|
|
||||
* |_sensor1_| max size:1280*800 mode=2 index=3
|
||||
* max width:1280
|
||||
*/
|
||||
for (i = 0; i < hw->dev_num; i++) {
|
||||
if (!hw->isp_size[i].size) {
|
||||
if (i < hw->dev_link_num)
|
||||
idx2[n++] = i;
|
||||
continue;
|
||||
}
|
||||
if (hw->isp_size[i].w <= ISP32_VIR2_MAX_WIDTH &&
|
||||
hw->isp_size[i].size <= ISP32_VIR2_MAX_SIZE) {
|
||||
if (hw->isp_size[i].w > ISP32_VIR4_MAX_WIDTH ||
|
||||
hw->isp_size[i].size > ISP32_VIR4_MAX_SIZE)
|
||||
j++;
|
||||
continue;
|
||||
}
|
||||
idx1[k++] = i;
|
||||
}
|
||||
if (k) {
|
||||
is_bigmode = true;
|
||||
if (k == 2 || j ||
|
||||
hw->isp_size[idx1[k - 1]].size > ISP32_VIR4_MAX_SIZE * 3) {
|
||||
dev_err(dev, "two virtual isp max:1920x1080\n");
|
||||
} else {
|
||||
if (idx1[0] == ispdev->dev_id) {
|
||||
ispdev->multi_mode = 0;
|
||||
ispdev->multi_index = 0;
|
||||
} else {
|
||||
ispdev->multi_mode = 2;
|
||||
ispdev->multi_index = 3;
|
||||
}
|
||||
}
|
||||
} else if (ispdev->multi_index >= hw->dev_link_num) {
|
||||
ispdev->multi_index = idx2[ispdev->multi_index - hw->dev_link_num];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
bigmode_max_w = ISP32_AUTO_BIGMODE_WIDTH;
|
||||
bigmode_max_size = ISP32_NOBIG_OVERFLOW_SIZE;
|
||||
ispdev->multi_mode = 0;
|
||||
ispdev->multi_index = 0;
|
||||
width = crop->width;
|
||||
height = crop->height;
|
||||
size = width * height;
|
||||
break;
|
||||
}
|
||||
|
||||
if (width > bigmode_max_w || size > bigmode_max_size)
|
||||
if (!is_bigmode &&
|
||||
(width > bigmode_max_w || size > bigmode_max_size))
|
||||
is_bigmode = true;
|
||||
return is_bigmode;
|
||||
return ispdev->is_bigmode = is_bigmode;
|
||||
}
|
||||
|
||||
/* Not called when the camera active, thus not isr protection. */
|
||||
|
||||
@@ -4212,40 +4212,165 @@ err_3dlut:
|
||||
static bool
|
||||
rkisp_params_check_bigmode_v3x(struct rkisp_isp_params_vdev *params_vdev)
|
||||
{
|
||||
struct device *dev = params_vdev->dev->dev;
|
||||
struct rkisp_hw_dev *hw = params_vdev->dev->hw_dev;
|
||||
struct v4l2_rect *out_crop = ¶ms_vdev->dev->isp_sdev.out_crop;
|
||||
u32 width = hw->max_in.w ? hw->max_in.w : out_crop->width;
|
||||
u32 height = hw->max_in.h ? hw->max_in.h : out_crop->height;
|
||||
u32 size = width * height;
|
||||
struct rkisp_device *ispdev = params_vdev->dev;
|
||||
struct device *dev = ispdev->dev;
|
||||
struct rkisp_hw_dev *hw = ispdev->hw_dev;
|
||||
struct v4l2_rect *crop = ¶ms_vdev->dev->isp_sdev.in_crop;
|
||||
u32 width = hw->max_in.w, height = hw->max_in.h, size = width * height;
|
||||
u32 bigmode_max_w, bigmode_max_size;
|
||||
int k = 0, idx1[DEV_MAX] = { 0 };
|
||||
int n = 0, idx2[DEV_MAX] = { 0 };
|
||||
int i = 0, j = 0;
|
||||
bool is_bigmode = false;
|
||||
|
||||
if (hw->dev_link_num > 2) {
|
||||
switch (hw->dev_link_num) {
|
||||
case 4:
|
||||
bigmode_max_w = ISP3X_VIR4_AUTO_BIGMODE_WIDTH;
|
||||
bigmode_max_size = ISP3X_VIR4_NOBIG_OVERFLOW_SIZE;
|
||||
if (width > ISP3X_VIR4_MAX_WIDTH || size > ISP3X_VIR4_MAX_SIZE)
|
||||
dev_err(dev, "%dx%d > max:2560x1536 for %d virtual isp\n",
|
||||
width, height, hw->dev_link_num);
|
||||
} else if (hw->dev_link_num > 1) {
|
||||
ispdev->multi_index = ispdev->dev_id;
|
||||
ispdev->multi_mode = 2;
|
||||
/* internal buf of hw divided to four parts
|
||||
* bigmode nobigmode
|
||||
* _________ max width:2560 max width:1280
|
||||
* |_sensor0_| max size:2560*1536 max size:1280*800
|
||||
* |_sensor1_| max size:2560*1536 max size:1280*800
|
||||
* |_sensor2_| max size:2560*1536 max size:1280*800
|
||||
* |_sensor3_| max size:2560*1536 max size:1280*800
|
||||
*/
|
||||
for (i = 0; i < hw->dev_num; i++) {
|
||||
if (hw->isp_size[i].w <= ISP3X_VIR4_MAX_WIDTH &&
|
||||
hw->isp_size[i].size <= ISP3X_VIR4_MAX_SIZE)
|
||||
continue;
|
||||
dev_err(dev, "four virtual isp max:%dx1536\n",
|
||||
hw->is_unite ? (2560 - RKMOUDLE_UNITE_EXTEND_PIXEL) * 2 : 2560);
|
||||
is_bigmode = true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
bigmode_max_w = ISP3X_VIR4_AUTO_BIGMODE_WIDTH;
|
||||
bigmode_max_size = ISP3X_VIR4_NOBIG_OVERFLOW_SIZE;
|
||||
ispdev->multi_index = ispdev->dev_id;
|
||||
ispdev->multi_mode = 2;
|
||||
/* case0: bigmode nobigmode
|
||||
* _________ max width:2560 max width:1280
|
||||
* |_sensor0_| max size:2560*1536 max size:1280*800
|
||||
* |_sensor1_| max size:2560*1536 max size:1280*800
|
||||
* |_sensor2_| max size:2560*1536 max size:1280*800
|
||||
* |_________|
|
||||
*
|
||||
* case1: bigmode special reg cfg
|
||||
* _________ max width:4672
|
||||
* | sensor0 | max size:2560*1536*2 mode=0 index=0
|
||||
* |_________|
|
||||
* |_sensor1_| max size:2560*1536 mode=2 index=2
|
||||
* |_sensor2_| max size:2560*1536 mode=2 index=3
|
||||
* max width:2560
|
||||
*/
|
||||
for (i = 0; i < hw->dev_num; i++) {
|
||||
if (!hw->isp_size[i].size) {
|
||||
if (i < hw->dev_link_num)
|
||||
idx2[n++] = i;
|
||||
continue;
|
||||
}
|
||||
if (hw->isp_size[i].w <= ISP3X_VIR4_MAX_WIDTH &&
|
||||
hw->isp_size[i].size <= ISP3X_VIR4_MAX_SIZE)
|
||||
continue;
|
||||
idx1[k++] = i;
|
||||
}
|
||||
if (k) {
|
||||
is_bigmode = true;
|
||||
if (k != 1 ||
|
||||
(hw->isp_size[idx1[0]].size > ISP3X_VIR4_MAX_SIZE * 2)) {
|
||||
dev_err(dev, "three virtual isp max:%dx1536\n",
|
||||
hw->is_unite ? (2560 - RKMOUDLE_UNITE_EXTEND_PIXEL) * 2 : 2560);
|
||||
} else {
|
||||
if (idx1[0] == ispdev->dev_id) {
|
||||
ispdev->multi_mode = 0;
|
||||
ispdev->multi_index = 0;
|
||||
} else {
|
||||
ispdev->multi_mode = 2;
|
||||
if (ispdev->multi_index == 0 ||
|
||||
ispdev->multi_index == 1)
|
||||
ispdev->multi_index = 3;
|
||||
}
|
||||
}
|
||||
} else if (ispdev->multi_index >= hw->dev_link_num) {
|
||||
ispdev->multi_index = idx2[ispdev->multi_index - hw->dev_link_num];
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
bigmode_max_w = ISP3X_VIR2_AUTO_BIGMODE_WIDTH;
|
||||
bigmode_max_size = ISP3X_VIR2_NOBIG_OVERFLOW_SIZE;
|
||||
if (width > ISP3X_VIR2_MAX_WIDTH || size > ISP3X_VIR2_MAX_SIZE)
|
||||
dev_err(dev, "%dx%d > max:3840x2160 for %d virtual isp\n",
|
||||
width, height, hw->dev_link_num);
|
||||
} else {
|
||||
ispdev->multi_index = ispdev->dev_id;
|
||||
ispdev->multi_mode = 1;
|
||||
/* case0: bigmode nobigmode
|
||||
* _________ max width:3840 max width:1920
|
||||
* | sensor0 | max size:3840*2160 max size:1920*1080
|
||||
* |_________|
|
||||
* | sensor1 | max size:3840*2160 max size:1920*1080
|
||||
* |_________|
|
||||
*
|
||||
* case1: bigmode special reg cfg
|
||||
* _________ max width:4672
|
||||
* | sensor0 | max size:2560*2160*3 mode=0 index=0
|
||||
* | |
|
||||
* |_________|
|
||||
* |_sensor1_| max size:2560*1536 mode=2 index=3
|
||||
* max width:2560
|
||||
*/
|
||||
for (i = 0; i < hw->dev_num; i++) {
|
||||
if (!hw->isp_size[i].size) {
|
||||
if (i < hw->dev_link_num)
|
||||
idx2[n++] = i;
|
||||
continue;
|
||||
}
|
||||
if (hw->isp_size[i].w <= ISP3X_VIR2_MAX_WIDTH &&
|
||||
hw->isp_size[i].size <= ISP3X_VIR2_MAX_SIZE) {
|
||||
if (hw->isp_size[i].w > ISP3X_VIR4_MAX_WIDTH ||
|
||||
hw->isp_size[i].size > ISP3X_VIR4_MAX_SIZE)
|
||||
j++;
|
||||
continue;
|
||||
}
|
||||
idx1[k++] = i;
|
||||
}
|
||||
if (k) {
|
||||
is_bigmode = true;
|
||||
if (k == 2 || j ||
|
||||
hw->isp_size[idx1[k - 1]].size > ISP3X_VIR4_MAX_SIZE * 3) {
|
||||
dev_err(dev, "two virtual isp max:%dx2160\n",
|
||||
hw->is_unite ? (3840 - RKMOUDLE_UNITE_EXTEND_PIXEL) * 2 : 3840);
|
||||
} else {
|
||||
if (idx1[0] == ispdev->dev_id) {
|
||||
ispdev->multi_mode = 0;
|
||||
ispdev->multi_index = 0;
|
||||
} else {
|
||||
ispdev->multi_mode = 2;
|
||||
ispdev->multi_index = 3;
|
||||
}
|
||||
}
|
||||
} else if (ispdev->multi_index >= hw->dev_link_num) {
|
||||
ispdev->multi_index = idx2[ispdev->multi_index - hw->dev_link_num];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
bigmode_max_w = ISP3X_AUTO_BIGMODE_WIDTH;
|
||||
bigmode_max_size = ISP3X_NOBIG_OVERFLOW_SIZE;
|
||||
ispdev->multi_mode = 0;
|
||||
ispdev->multi_index = 0;
|
||||
width = crop->width;
|
||||
if (hw->is_unite)
|
||||
width = width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL;
|
||||
height = crop->height;
|
||||
size = width * height;
|
||||
break;
|
||||
}
|
||||
|
||||
if (hw->is_unite) {
|
||||
width = width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL;
|
||||
size = width * out_crop->height;
|
||||
}
|
||||
|
||||
if (width > bigmode_max_w || size > bigmode_max_size)
|
||||
if (!is_bigmode &&
|
||||
(width > bigmode_max_w || size > bigmode_max_size))
|
||||
is_bigmode = true;
|
||||
return is_bigmode;
|
||||
|
||||
return ispdev->is_bigmode = is_bigmode;
|
||||
}
|
||||
|
||||
/* Not called when the camera active, thus not isr protection. */
|
||||
|
||||
@@ -617,31 +617,15 @@ void rkisp_trigger_read_back(struct rkisp_device *dev, u8 dma2frm, u32 mode, boo
|
||||
/* sensor mode & index */
|
||||
if (dev->isp_ver == ISP_V21 || dev->isp_ver == ISP_V30 ||
|
||||
dev->isp_ver == ISP_V32) {
|
||||
u32 mode = hw->dev_link_num >= 3 ? 2 : hw->dev_link_num - 1;
|
||||
u32 index = dev->dev_id;
|
||||
|
||||
if (index >= hw->dev_link_num) {
|
||||
int i, num = 0, off[4] = { 0 };
|
||||
struct rkisp_device *isp;
|
||||
|
||||
for (i = 0; i < hw->dev_link_num; i++) {
|
||||
isp = hw->isp[i];
|
||||
if (isp && isp->is_hw_link)
|
||||
continue;
|
||||
off[num++] = i;
|
||||
}
|
||||
if (num == 1)
|
||||
index = off[0];
|
||||
else
|
||||
index = off[index - hw->dev_link_num];
|
||||
}
|
||||
val = rkisp_read_reg_cache(dev, ISP_ACQ_H_OFFS);
|
||||
val |= ISP21_SENSOR_MODE(mode) | ISP21_SENSOR_INDEX(index);
|
||||
val |= ISP21_SENSOR_MODE(dev->multi_mode) |
|
||||
ISP21_SENSOR_INDEX(dev->multi_index);
|
||||
writel(val, hw->base_addr + ISP_ACQ_H_OFFS);
|
||||
if (hw->is_unite)
|
||||
writel(val, hw->base_next_addr + ISP_ACQ_H_OFFS);
|
||||
v4l2_dbg(2, rkisp_debug, &dev->v4l2_dev,
|
||||
"sensor mode:%d index:%d | 0x%x\n", mode, index, val);
|
||||
"sensor mode:%d index:%d | 0x%x\n",
|
||||
dev->multi_mode, dev->multi_index, val);
|
||||
}
|
||||
is_upd = true;
|
||||
}
|
||||
@@ -3120,7 +3104,7 @@ static int rkisp_get_info(struct rkisp_device *dev, struct rkisp_isp_info *info)
|
||||
mode = RKISP_ISP_COMPR;
|
||||
info->compr_bit = bit;
|
||||
|
||||
if (rkisp_params_check_bigmode(&dev->params_vdev))
|
||||
if (dev->is_bigmode)
|
||||
mode |= RKISP_ISP_BIGMODE;
|
||||
info->mode = mode;
|
||||
if (dev->hw_dev->is_unite)
|
||||
|
||||
Reference in New Issue
Block a user