From 4122e58de96c11cc938d75557b12ea4c37c38e2e Mon Sep 17 00:00:00 2001 From: "wei.luo" Date: Sun, 18 Feb 2024 09:49:21 +0800 Subject: [PATCH 01/34] mfd: display-serdes: fix building error Fixes: c60873aaf6d9 ("mfd: display-serdes: add error detection and recovery function") Signed-off-by: Luo wei Change-Id: Idcafd226b6e338f6c6180f61212ac7a09d8081b7 --- drivers/mfd/display-serdes/serdes-i2c.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mfd/display-serdes/serdes-i2c.c b/drivers/mfd/display-serdes/serdes-i2c.c index b02a64b04291..9f357ecba9ca 100644 --- a/drivers/mfd/display-serdes/serdes-i2c.c +++ b/drivers/mfd/display-serdes/serdes-i2c.c @@ -31,7 +31,7 @@ int serdes_i2c_set_sequence(struct serdes *serdes) if (ret < 0) { SERDES_DBG_MFD("%s failed to write reg %04x, ret %d, again now\n", - serdes->dev, + dev_name(serdes->dev), serdes->serdes_init_seq->reg_sequence[i].reg, ret); ret = serdes_reg_write(serdes, serdes->serdes_init_seq->reg_sequence[i].reg, @@ -111,7 +111,7 @@ static int serdes_i2c_set_sequence_backup(struct serdes *serdes) serdes->serdes_backup_seq->reg_sequence[i].def); if (ret < 0) { SERDES_DBG_MFD("%s failed to write reg %04x, ret %d, again now\n", - serdes->dev, + dev_name(serdes->dev), serdes->serdes_backup_seq->reg_sequence[i].reg, ret); ret = serdes_reg_write(serdes, serdes->serdes_backup_seq->reg_sequence[i].reg, From f938361535e5ecfc51905c9ae182ea11a03c27b4 Mon Sep 17 00:00:00 2001 From: Cai YiWei Date: Mon, 5 Feb 2024 15:31:32 +0800 Subject: [PATCH 02/34] media: rockchip: isp: fix mp wrap buf from rockit no output Change-Id: I88fa7707ce8a67846951c0fc6287f81d8c3719ee Signed-off-by: Cai YiWei --- .../media/platform/rockchip/isp/capture_v32.c | 8 ++++--- .../media/platform/rockchip/isp/isp_rockit.c | 22 ++++++++++--------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/drivers/media/platform/rockchip/isp/capture_v32.c b/drivers/media/platform/rockchip/isp/capture_v32.c index a0d60cbd16e6..10066eac5953 100644 --- a/drivers/media/platform/rockchip/isp/capture_v32.c +++ b/drivers/media/platform/rockchip/isp/capture_v32.c @@ -752,8 +752,7 @@ static int mp_config_mi(struct rkisp_stream *stream) mi_frame_end_int_enable(stream); /* set up first buffer */ - if (!dev->cap_dev.wrap_line || stream->dummy_buf.mem_priv) - mi_frame_end(stream, FRAME_INIT); + mi_frame_end(stream, FRAME_INIT); rkisp_unite_write(dev, stream->config->mi.y_offs_cnt_init, 0, false); rkisp_unite_write(dev, stream->config->mi.cb_offs_cnt_init, 0, false); @@ -1422,7 +1421,10 @@ static int mi_frame_end(struct rkisp_stream *stream, u32 state) struct rkisp_buffer *buf = NULL; u32 i; - if (stream->id == RKISP_STREAM_VIR) + /* STREAM_VIR or STREAM_MP wrap buf from rockit */ + if (stream->id == RKISP_STREAM_VIR || + (stream->id == RKISP_STREAM_MP && dev->cap_dev.wrap_line && + !stream->dummy_buf.mem_priv && stream->dummy_buf.dma_addr)) return 0; if (dev->cap_dev.is_done_early && diff --git a/drivers/media/platform/rockchip/isp/isp_rockit.c b/drivers/media/platform/rockchip/isp/isp_rockit.c index c8682492aaaf..93d8253282b4 100644 --- a/drivers/media/platform/rockchip/isp/isp_rockit.c +++ b/drivers/media/platform/rockchip/isp/isp_rockit.c @@ -176,17 +176,19 @@ int rkisp_rockit_buf_queue(struct rockit_cfg *input_rockit_cfg) isprk_buf->isp_buf.buff_addr[i] = isprk_buf->buff_addr; } - if (ispdev->cap_dev.wrap_line && stream->id == RKISP_STREAM_MP && isprk_buf) { - val = isprk_buf->buff_addr; - reg = stream->config->mi.y_base_ad_init; - rkisp_write(ispdev, reg, val, false); + if (ispdev->cap_dev.wrap_line && stream->id == RKISP_STREAM_MP) { + if (isprk_buf) { + val = isprk_buf->buff_addr; + reg = stream->config->mi.y_base_ad_init; + rkisp_write(ispdev, reg, val, false); - bytesperline = stream->out_fmt.plane_fmt[0].bytesperline; - val += bytesperline * ispdev->cap_dev.wrap_line; - reg = stream->config->mi.cb_base_ad_init; - rkisp_write(ispdev, reg, val, false); - stream->dummy_buf.dma_addr = isprk_buf->buff_addr; - v4l2_info(&ispdev->v4l2_dev, "rockit wrap buf:0x%x\n", isprk_buf->buff_addr); + bytesperline = stream->out_fmt.plane_fmt[0].bytesperline; + val += bytesperline * ispdev->cap_dev.wrap_line; + reg = stream->config->mi.cb_base_ad_init; + rkisp_write(ispdev, reg, val, false); + stream->dummy_buf.dma_addr = isprk_buf->buff_addr; + v4l2_info(&ispdev->v4l2_dev, "rockit wrap buf:0x%x\n", isprk_buf->buff_addr); + } return -EINVAL; } From d55e030c51ab755df27bd63a95bef38524ff78ff Mon Sep 17 00:00:00 2001 From: Zhihua Wang Date: Wed, 24 Jan 2024 19:06:53 +0800 Subject: [PATCH 03/34] ARM: dts: rockchip: rv1106-evb-dual-cam add sc530ai Signed-off-by: Zhihua Wang Change-Id: Ia073eb82e135466844e6474883f4b0f70aeacbf0 --- arch/arm/boot/dts/rv1106-evb-dual-cam.dtsi | 56 ++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/arch/arm/boot/dts/rv1106-evb-dual-cam.dtsi b/arch/arm/boot/dts/rv1106-evb-dual-cam.dtsi index bd3d8fe80a0b..43a2c4f14b1b 100644 --- a/arch/arm/boot/dts/rv1106-evb-dual-cam.dtsi +++ b/arch/arm/boot/dts/rv1106-evb-dual-cam.dtsi @@ -44,6 +44,12 @@ remote-endpoint = <&sc301iot_out>; data-lanes = <1 2>; }; + + csi_dphy_input6: endpoint@4 { + reg = <4>; + remote-endpoint = <&sc530ai_out>; + data-lanes = <1 2>; + }; }; port@1 { @@ -88,6 +94,12 @@ remote-endpoint = <&sc301iot_1_out>; data-lanes = <1 2>; }; + + csi_dphy_input7: endpoint@4 { + reg = <4>; + remote-endpoint = <&sc530ai_1_out>; + data-lanes = <1 2>; + }; }; port@1 { @@ -175,6 +187,28 @@ }; }; + sc530ai: sc530ai@30 { + compatible = "smartsens,sc530ai"; + status = "okay"; + reg = <0x30>; + clocks = <&cru MCLK_REF_MIPI0>; + clock-names = "xvclk"; + reset-gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>; + pwdn-gpios = <&gpio3 RK_PD2 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&mipi_refclk_out0>; + rockchip,camera-module-index = <0>; + rockchip,camera-module-facing = "back"; + rockchip,camera-module-name = "CMK-OT2115-PC1"; + rockchip,camera-module-lens-name = "30IRC-F16"; + port { + sc530ai_out: endpoint { + remote-endpoint = <&csi_dphy_input6>; + data-lanes = <1 2>; + }; + }; + }; + sc4336: sc4336@30 { compatible = "smartsens,sc4336"; status = "okay"; @@ -240,6 +274,28 @@ }; }; }; + + sc530ai_1: sc530ai_1@32 { + compatible = "smartsens,sc530ai"; + status = "okay"; + reg = <0x32>; + clocks = <&cru MCLK_REF_MIPI1>; + clock-names = "xvclk"; + reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>; + pwdn-gpios = <&gpio3 RK_PA4 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&mipi_refclk_out1>; + rockchip,camera-module-index = <1>; + rockchip,camera-module-facing = "back"; + rockchip,camera-module-name = "CMK-OT2115-PC1"; + rockchip,camera-module-lens-name = "30IRC-F16"; + port { + sc530ai_1_out: endpoint { + remote-endpoint = <&csi_dphy_input7>; + data-lanes = <1 2>; + }; + }; + }; }; &mipi0_csi2 { From 8d3794f358d07fed8ec4ea1b281a72b1269d6664 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sat, 12 Feb 2022 14:50:48 -0600 Subject: [PATCH 04/34] UPSTREAM: gpio: rockchip: Reset int_bothedge when changing trigger With v2 hardware, an IRQ can be configured to trigger on both edges via a bit in the int_bothedge register. Currently, the driver sets this bit when changing the trigger type to IRQ_TYPE_EDGE_BOTH, but fails to reset this bit if the trigger type is later changed to something else. This causes spurious IRQs, and when using gpio-keys with wakeup-event-action set to EV_ACT_(DE)ASSERTED, those IRQs translate into spurious wakeups. Fixes: 3bcbd1a85b68 ("gpio/rockchip: support next version gpio controller") Reported-by: Guillaume Savaton Tested-by: Guillaume Savaton Signed-off-by: Samuel Holland Signed-off-by: Bartosz Golaszewski (cherry picked from commit 7920af5c826cb4a7ada1ae26fdd317642805adc2) Signed-off-by: Steven Liu Change-Id: I8b4645a81e553957a77cca84e4152f1e38dd1852 --- drivers/gpio/gpio-rockchip.c | 56 +++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c index b9327a33ec1d..a42c289c43dd 100644 --- a/drivers/gpio/gpio-rockchip.c +++ b/drivers/gpio/gpio-rockchip.c @@ -417,10 +417,8 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type) level = rockchip_gpio_readl(bank, bank->gpio_regs->int_type); polarity = rockchip_gpio_readl(bank, bank->gpio_regs->int_polarity); - switch (type) { - case IRQ_TYPE_EDGE_BOTH: + if (type == IRQ_TYPE_EDGE_BOTH) { if (bank->gpio_type == GPIO_TYPE_V2) { - bank->toggle_edge_mode &= ~mask; rockchip_gpio_writel_bit(bank, d->hwirq, 1, bank->gpio_regs->int_bothedge); goto out; @@ -438,30 +436,34 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type) else polarity |= mask; } - break; - case IRQ_TYPE_EDGE_RISING: - bank->toggle_edge_mode &= ~mask; - level |= mask; - polarity |= mask; - break; - case IRQ_TYPE_EDGE_FALLING: - bank->toggle_edge_mode &= ~mask; - level |= mask; - polarity &= ~mask; - break; - case IRQ_TYPE_LEVEL_HIGH: - bank->toggle_edge_mode &= ~mask; - level &= ~mask; - polarity |= mask; - break; - case IRQ_TYPE_LEVEL_LOW: - bank->toggle_edge_mode &= ~mask; - level &= ~mask; - polarity &= ~mask; - break; - default: - ret = -EINVAL; - goto out; + } else { + if (bank->gpio_type == GPIO_TYPE_V2) { + rockchip_gpio_writel_bit(bank, d->hwirq, 0, + bank->gpio_regs->int_bothedge); + } else { + bank->toggle_edge_mode &= ~mask; + } + switch (type) { + case IRQ_TYPE_EDGE_RISING: + level |= mask; + polarity |= mask; + break; + case IRQ_TYPE_EDGE_FALLING: + level |= mask; + polarity &= ~mask; + break; + case IRQ_TYPE_LEVEL_HIGH: + level &= ~mask; + polarity |= mask; + break; + case IRQ_TYPE_LEVEL_LOW: + level &= ~mask; + polarity &= ~mask; + break; + default: + ret = -EINVAL; + goto out; + } } rockchip_gpio_writel(bank, level, bank->gpio_regs->int_type); From ffe673b0e529e596e986cd89e505417a60ec3386 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 4 Apr 2023 09:25:23 +0200 Subject: [PATCH 05/34] BACKPORT: USB: dwc3: refactor clock lookups The probe callback has become unwieldy so break out the clock lookups into a new helper function to improve readability. Acked-by: Thinh Nguyen Signed-off-by: Johan Hovold Link: https://lore.kernel.org/r/20230404072524.19014-11-johan+linaro@kernel.org Signed-off-by: Greg Kroah-Hartman Signed-off-by: William Wu (cherry picked from commit bd82857424d37897ad994381f7c580dacf2e2988) Change-Id: Iefc63ea7b7c516bd85bb2c20c86f1d899875497e --- drivers/usb/dwc3/core.c | 116 +++++++++++++++++++++------------------- 1 file changed, 61 insertions(+), 55 deletions(-) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index a4da4b474ea9..8aa5799b456b 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -1771,6 +1771,64 @@ static struct extcon_dev *dwc3_get_extcon(struct dwc3 *dwc) return edev; } +static int dwc3_get_clocks(struct dwc3 *dwc) +{ + struct device *dev = dwc->dev; + + if (!dev->of_node) + return 0; + + /* + * Clocks are optional, but new DT platforms should support all clocks + * as required by the DT-binding. + * Some devices have different clock names in legacy device trees, + * check for them to retain backwards compatibility. + */ + dwc->bus_clk = devm_clk_get_optional(dev, "bus_early"); + if (IS_ERR(dwc->bus_clk)) { + return dev_err_probe(dev, PTR_ERR(dwc->bus_clk), + "could not get bus clock\n"); + } + + if (dwc->bus_clk == NULL) { + dwc->bus_clk = devm_clk_get_optional(dev, "bus_clk"); + if (IS_ERR(dwc->bus_clk)) { + return dev_err_probe(dev, PTR_ERR(dwc->bus_clk), + "could not get bus clock\n"); + } + } + + dwc->ref_clk = devm_clk_get_optional(dev, "ref"); + if (IS_ERR(dwc->ref_clk)) { + return dev_err_probe(dev, PTR_ERR(dwc->ref_clk), + "could not get ref clock\n"); + } + + if (dwc->ref_clk == NULL) { + dwc->ref_clk = devm_clk_get_optional(dev, "ref_clk"); + if (IS_ERR(dwc->ref_clk)) { + return dev_err_probe(dev, PTR_ERR(dwc->ref_clk), + "could not get ref clock\n"); + } + } + + dwc->susp_clk = devm_clk_get_optional(dev, "suspend"); + if (IS_ERR(dwc->susp_clk)) { + return dev_err_probe(dev, PTR_ERR(dwc->susp_clk), + "could not get suspend clock\n"); + } + + if (dwc->susp_clk == NULL) { + dwc->susp_clk = devm_clk_get_optional(dev, "suspend_clk"); + if (IS_ERR(dwc->susp_clk)) { + return dev_err_probe(dev, PTR_ERR(dwc->susp_clk), + "could not get suspend clock\n"); + } + } + + return 0; +} + static int dwc3_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -1821,61 +1879,9 @@ static int dwc3_probe(struct platform_device *pdev) goto put_usb_psy; } - if (dev->of_node) { - /* - * Clocks are optional, but new DT platforms should support all - * clocks as required by the DT-binding. - * Some devices have different clock names in legacy device trees, - * check for them to retain backwards compatibility. - */ - dwc->bus_clk = devm_clk_get_optional(dev, "bus_early"); - if (IS_ERR(dwc->bus_clk)) { - ret = dev_err_probe(dev, PTR_ERR(dwc->bus_clk), - "could not get bus clock\n"); - goto put_usb_psy; - } - - if (dwc->bus_clk == NULL) { - dwc->bus_clk = devm_clk_get_optional(dev, "bus_clk"); - if (IS_ERR(dwc->bus_clk)) { - ret = dev_err_probe(dev, PTR_ERR(dwc->bus_clk), - "could not get bus clock\n"); - goto put_usb_psy; - } - } - - dwc->ref_clk = devm_clk_get_optional(dev, "ref"); - if (IS_ERR(dwc->ref_clk)) { - ret = dev_err_probe(dev, PTR_ERR(dwc->ref_clk), - "could not get ref clock\n"); - goto put_usb_psy; - } - - if (dwc->ref_clk == NULL) { - dwc->ref_clk = devm_clk_get_optional(dev, "ref_clk"); - if (IS_ERR(dwc->ref_clk)) { - ret = dev_err_probe(dev, PTR_ERR(dwc->ref_clk), - "could not get ref clock\n"); - goto put_usb_psy; - } - } - - dwc->susp_clk = devm_clk_get_optional(dev, "suspend"); - if (IS_ERR(dwc->susp_clk)) { - ret = dev_err_probe(dev, PTR_ERR(dwc->susp_clk), - "could not get suspend clock\n"); - goto put_usb_psy; - } - - if (dwc->susp_clk == NULL) { - dwc->susp_clk = devm_clk_get_optional(dev, "suspend_clk"); - if (IS_ERR(dwc->susp_clk)) { - ret = dev_err_probe(dev, PTR_ERR(dwc->susp_clk), - "could not get suspend clock\n"); - goto put_usb_psy; - } - } - } + ret = dwc3_get_clocks(dwc); + if (ret) + goto put_usb_psy; ret = reset_control_deassert(dwc->reset); if (ret) From ef32b29caa4e306a344ee815835594b7a01d6075 Mon Sep 17 00:00:00 2001 From: Sebastian Reichel Date: Fri, 20 Oct 2023 16:11:41 +0200 Subject: [PATCH 06/34] UPSTREAM: usb: dwc3: add optional PHY interface clocks On Rockchip RK3588 one of the DWC3 cores is integrated weirdly and requires two extra clocks to be enabled. Without these extra clocks hot-plugging USB devices is broken. Signed-off-by: Sebastian Reichel Acked-by: Thinh Nguyen Link: https://lore.kernel.org/r/20231020150022.48725-3-sebastian.reichel@collabora.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: William Wu (cherry picked from commit 97789b93b792fc97ad4476b79e0f38ffa8e7e0ee) Change-Id: Ib6268cb1de3560c4a5f1f1af898cb8869bb3ca4f --- drivers/usb/dwc3/core.c | 28 ++++++++++++++++++++++++++++ drivers/usb/dwc3/core.h | 4 ++++ 2 files changed, 32 insertions(+) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 8aa5799b456b..93a524361a5e 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -853,8 +853,20 @@ static int dwc3_clk_enable(struct dwc3 *dwc) if (ret) goto disable_ref_clk; + ret = clk_prepare_enable(dwc->utmi_clk); + if (ret) + goto disable_susp_clk; + + ret = clk_prepare_enable(dwc->pipe_clk); + if (ret) + goto disable_utmi_clk; + return 0; +disable_utmi_clk: + clk_disable_unprepare(dwc->utmi_clk); +disable_susp_clk: + clk_disable_unprepare(dwc->susp_clk); disable_ref_clk: clk_disable_unprepare(dwc->ref_clk); disable_bus_clk: @@ -864,6 +876,8 @@ disable_bus_clk: static void dwc3_clk_disable(struct dwc3 *dwc) { + clk_disable_unprepare(dwc->pipe_clk); + clk_disable_unprepare(dwc->utmi_clk); clk_disable_unprepare(dwc->susp_clk); clk_disable_unprepare(dwc->ref_clk); clk_disable_unprepare(dwc->bus_clk); @@ -1826,6 +1840,20 @@ static int dwc3_get_clocks(struct dwc3 *dwc) } } + /* specific to Rockchip RK3588 */ + dwc->utmi_clk = devm_clk_get_optional(dev, "utmi"); + if (IS_ERR(dwc->utmi_clk)) { + return dev_err_probe(dev, PTR_ERR(dwc->utmi_clk), + "could not get utmi clock\n"); + } + + /* specific to Rockchip RK3588 */ + dwc->pipe_clk = devm_clk_get_optional(dev, "pipe"); + if (IS_ERR(dwc->pipe_clk)) { + return dev_err_probe(dev, PTR_ERR(dwc->pipe_clk), + "could not get pipe clock\n"); + } + return 0; } diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index f90b876f7188..a6b44c0179bf 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -990,6 +990,8 @@ struct dwc3_scratchpad_array { * @bus_clk: clock for accessing the registers * @ref_clk: reference clock * @susp_clk: clock used when the SS phy is in low power (S3) state + * @utmi_clk: clock used for USB2 PHY communication + * @pipe_clk: clock used for USB3 PHY communication * @reset: reset control * @regs: base address for our registers * @regs_size: address space size @@ -1158,6 +1160,8 @@ struct dwc3 { struct clk *bus_clk; struct clk *ref_clk; struct clk *susp_clk; + struct clk *utmi_clk; + struct clk *pipe_clk; struct reset_control *reset; From f3fcf22888f88e4d8288e6b23dae383eda4afa4e Mon Sep 17 00:00:00 2001 From: Liang Chen Date: Tue, 20 Feb 2024 14:34:32 +0800 Subject: [PATCH 07/34] ARM: rockchip: rv1106_pm: optimize pvtpll save/restore process flow Pvtpll length must configure before enable pvtpll, otherwise pvtpll may output wrong frequency. Signed-off-by: Liang Chen Change-Id: I432d10b53bf5853c724fb9e4e54256a3dd3e146b --- arch/arm/mach-rockchip/rv1106_pm.c | 46 +++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-rockchip/rv1106_pm.c b/arch/arm/mach-rockchip/rv1106_pm.c index 1d7b30a3ad08..1d31e1dbe198 100644 --- a/arch/arm/mach-rockchip/rv1106_pm.c +++ b/arch/arm/mach-rockchip/rv1106_pm.c @@ -27,6 +27,24 @@ #define RV1106_PM_REG_REGION_MEM_SIZE SZ_4K +#define CRU_PVTPLL0_CON0_L 0x00 +#define CRU_PVTPLL0_CON0_H 0x04 +#define CRU_PVTPLL0_CON1_L 0x08 +#define CRU_PVTPLL0_CON1_H 0x0c +#define CRU_PVTPLL0_CON2_L 0x10 +#define CRU_PVTPLL0_CON2_H 0x14 +#define CRU_PVTPLL0_CON3_L 0x18 +#define CRU_PVTPLL0_CON3_H 0x1c + +#define CRU_PVTPLL1_CON0_L 0x30 +#define CRU_PVTPLL1_CON0_H 0x34 +#define CRU_PVTPLL1_CON1_L 0x38 +#define CRU_PVTPLL1_CON1_H 0x3c +#define CRU_PVTPLL1_CON2_L 0x40 +#define CRU_PVTPLL1_CON2_H 0x44 +#define CRU_PVTPLL1_CON3_L 0x48 +#define CRU_PVTPLL1_CON3_H 0x4c + enum { RV1106_GPIO_PULL_NONE, RV1106_GPIO_PULL_UP, @@ -114,10 +132,6 @@ static struct reg_region vd_core_reg_rgns[] = { { REG_REGION(0x300, 0x310, 4, &corecru_base, WMSK_VAL)}, { REG_REGION(0x800, 0x804, 4, &corecru_base, WMSK_VAL)}, - /* pvtpll_cru */ - { REG_REGION(0x00, 0x24, 4, &pvtpllcru_base, WMSK_VAL)}, - { REG_REGION(0x30, 0x54, 4, &pvtpllcru_base, WMSK_VAL)}, - /* core_sgrf */ { REG_REGION(0x004, 0x014, 4, &coresgrf_base, 0)}, { REG_REGION(0x000, 0x000, 4, &coresgrf_base, 0)}, @@ -1028,6 +1042,28 @@ static void gpio_restore(void) static struct uart_debug_ctx debug_port_save; static u32 cru_mode; +static u32 pvtpll0_length, pvtpll1_length; + +static void pvtpllcru_save(void) +{ + pvtpll0_length = readl_relaxed(pvtpllcru_base + CRU_PVTPLL0_CON0_H); + pvtpll1_length = readl_relaxed(pvtpllcru_base + CRU_PVTPLL1_CON0_H); +} + +static void pvtpllcru_restore(void) +{ + writel_relaxed(0x00030000, pvtpllcru_base + CRU_PVTPLL0_CON0_L); + writel_relaxed(0x007f0000 | pvtpll0_length, pvtpllcru_base + CRU_PVTPLL0_CON0_H); + writel_relaxed(0xffff0018, pvtpllcru_base + CRU_PVTPLL0_CON1_L); + writel_relaxed(0xffff0004, pvtpllcru_base + CRU_PVTPLL0_CON2_H); + writel_relaxed(0x00030003, pvtpllcru_base + CRU_PVTPLL0_CON0_L); + + writel_relaxed(0x00030000, pvtpllcru_base + CRU_PVTPLL1_CON0_L); + writel_relaxed(0x007f0000 | pvtpll1_length, pvtpllcru_base + CRU_PVTPLL1_CON0_H); + writel_relaxed(0xffff0018, pvtpllcru_base + CRU_PVTPLL1_CON1_L); + writel_relaxed(0xffff0004, pvtpllcru_base + CRU_PVTPLL1_CON2_H); + writel_relaxed(0x00030003, pvtpllcru_base + CRU_PVTPLL1_CON0_L); +} static void vd_log_regs_save(void) { @@ -1038,6 +1074,7 @@ static void vd_log_regs_save(void) gic400_save(); rkpm_printch('b'); + pvtpllcru_save(); rkpm_reg_rgn_save(vd_core_reg_rgns, ARRAY_SIZE(vd_core_reg_rgns)); rkpm_printch('c'); rkpm_reg_rgn_save(vd_log_reg_rgns, ARRAY_SIZE(vd_log_reg_rgns)); @@ -1056,6 +1093,7 @@ static void vd_log_regs_restore(void) rkpm_reg_rgn_restore(vd_core_reg_rgns, ARRAY_SIZE(vd_core_reg_rgns)); rkpm_reg_rgn_restore(vd_log_reg_rgns, ARRAY_SIZE(vd_log_reg_rgns)); + pvtpllcru_restore(); /* wait lock */ pm_pll_wait_lock(RV1106_APLL_ID); From 25c456719d40272e5da224021cdddc76bdc48840 Mon Sep 17 00:00:00 2001 From: Liang Chen Date: Tue, 20 Feb 2024 15:14:57 +0800 Subject: [PATCH 08/34] clk: rockchip: rv1106: optimize calibrate step for cru pvtpll The frequency of pvtpll may unstable when calibrate, if the step is too small, it will stride a too big length and adjust back again, that is bad. Signed-off-by: Liang Chen Change-Id: I96227b37cde45ae86df68777da8f32467f8926e6 --- drivers/clk/rockchip/clk-rv1106.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/clk/rockchip/clk-rv1106.c b/drivers/clk/rockchip/clk-rv1106.c index f61cbbf2e81d..84d0099ddcab 100644 --- a/drivers/clk/rockchip/clk-rv1106.c +++ b/drivers/clk/rockchip/clk-rv1106.c @@ -1007,12 +1007,16 @@ static void _cru_pvtpll_calibrate(int count_offset, int length_offset, int targe writel_relaxed(val, rv1106_cru_base + length_offset); usleep_range(2000, 2100); rate1 = readl_relaxed(rv1106_cru_base + count_offset); - if ((rate1 < target_rate) || (rate1 >= rate0)) + if (rate1 < target_rate) return; if (abs(rate1 - target_rate) < (target_rate >> 5)) return; - step = rate0 - rate1; + if (rate1 < rate0) + step = rate0 - rate1; + else + step = 5; + step = max_t(unsigned int, step, 5); delta = rate1 - target_rate; length += delta / step; val = HIWORD_UPDATE(length, PVTPLL_LENGTH_SEL_MASK, PVTPLL_LENGTH_SEL_SHIFT); From e84d9bd50a8932a3024160d2ee7c333cbfa8c341 Mon Sep 17 00:00:00 2001 From: Cai YiWei Date: Fri, 27 Oct 2023 15:11:45 +0800 Subject: [PATCH 09/34] media: rockchip: isp: add ioctl to get bay3d buf Change-Id: Id65390eab9f1dc2d64405def56e854078ceba037 Signed-off-by: Cai YiWei --- drivers/media/platform/rockchip/isp/common.c | 54 ++++++-- drivers/media/platform/rockchip/isp/common.h | 1 + .../media/platform/rockchip/isp/isp_params.c | 8 ++ .../media/platform/rockchip/isp/isp_params.h | 4 + .../platform/rockchip/isp/isp_params_v21.c | 14 ++ .../platform/rockchip/isp/isp_params_v32.c | 25 +++- .../platform/rockchip/isp/isp_params_v3x.c | 106 +++++++++------ .../platform/rockchip/isp/isp_params_v3x.h | 6 +- drivers/media/platform/rockchip/isp/procfs.c | 30 ++--- .../media/platform/rockchip/isp/regs_v3x.h | 2 +- drivers/media/platform/rockchip/isp/rkisp.c | 123 ++++++++---------- include/uapi/linux/rk-isp2-config.h | 20 +++ 12 files changed, 255 insertions(+), 138 deletions(-) diff --git a/drivers/media/platform/rockchip/isp/common.c b/drivers/media/platform/rockchip/isp/common.c index 80536de52a56..7a1607ebf453 100644 --- a/drivers/media/platform/rockchip/isp/common.c +++ b/drivers/media/platform/rockchip/isp/common.c @@ -192,6 +192,42 @@ void rkisp_update_regs(struct rkisp_device *dev, u32 start, u32 end) } } +int rkisp_buf_get_fd(struct rkisp_device *dev, + struct rkisp_dummy_buffer *buf, bool try_fd) +{ + const struct vb2_mem_ops *g_ops = dev->hw_dev->mem_ops; + bool new_dbuf = false; + + if (!buf || !buf->mem_priv) + return -EINVAL; + if (try_fd && buf->is_need_dmafd) + return 0; + if (try_fd) { + buf->is_need_dbuf = true; + buf->is_need_dmafd = true; + } + + if (buf->is_need_dbuf && !buf->dbuf) { + buf->dbuf = g_ops->get_dmabuf(buf->mem_priv, O_RDWR); + new_dbuf = true; + } + + if (buf->is_need_dmafd) { + buf->dma_fd = dma_buf_fd(buf->dbuf, O_CLOEXEC); + if (buf->dma_fd < 0) { + if (new_dbuf) { + dma_buf_put(buf->dbuf); + buf->dbuf = NULL; + buf->is_need_dbuf = false; + } + buf->is_need_dmafd = false; + return -EINVAL; + } + get_dma_buf(buf->dbuf); + } + return 0; +} + int rkisp_alloc_buffer(struct rkisp_device *dev, struct rkisp_dummy_buffer *buf) { @@ -228,17 +264,13 @@ int rkisp_alloc_buffer(struct rkisp_device *dev, } if (buf->is_need_vaddr) buf->vaddr = g_ops->vaddr(mem_priv); - if (buf->is_need_dbuf) { - buf->dbuf = g_ops->get_dmabuf(mem_priv, O_RDWR); - if (buf->is_need_dmafd) { - buf->dma_fd = dma_buf_fd(buf->dbuf, O_CLOEXEC); - if (buf->dma_fd < 0) { - dma_buf_put(buf->dbuf); - ret = buf->dma_fd; - goto err; - } - get_dma_buf(buf->dbuf); - } + ret = rkisp_buf_get_fd(dev, buf, false); + if (ret < 0) { + g_ops->put(buf->mem_priv); + buf->mem_priv = NULL; + buf->vaddr = NULL; + buf->size = 0; + goto err; } v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev, "%s buf:0x%x~0x%x size:%d\n", __func__, diff --git a/drivers/media/platform/rockchip/isp/common.h b/drivers/media/platform/rockchip/isp/common.h index 7f6e41e699b6..8d4fd4649215 100644 --- a/drivers/media/platform/rockchip/isp/common.h +++ b/drivers/media/platform/rockchip/isp/common.h @@ -187,6 +187,7 @@ void rkisp_next_clear_reg_cache_bits(struct rkisp_device *dev, u32 reg, u32 mask void rkisp_update_regs(struct rkisp_device *dev, u32 start, u32 end); +int rkisp_buf_get_fd(struct rkisp_device *dev, struct rkisp_dummy_buffer *buf, bool try_fd); int rkisp_alloc_buffer(struct rkisp_device *dev, struct rkisp_dummy_buffer *buf); void rkisp_free_buffer(struct rkisp_device *dev, struct rkisp_dummy_buffer *buf); void rkisp_prepare_buffer(struct rkisp_device *dev, struct rkisp_dummy_buffer *buf); diff --git a/drivers/media/platform/rockchip/isp/isp_params.c b/drivers/media/platform/rockchip/isp/isp_params.c index 03fd7fce0d7e..3c4379ef479b 100644 --- a/drivers/media/platform/rockchip/isp/isp_params.c +++ b/drivers/media/platform/rockchip/isp/isp_params.c @@ -487,6 +487,14 @@ int rkisp_params_info2ddr_cfg(struct rkisp_isp_params_vdev *params_vdev, return ret; } +void rkisp_params_get_bay3d_buffd(struct rkisp_isp_params_vdev *params_vdev, + struct rkisp_bay3dbuf_info *bay3dbuf) +{ + memset(bay3dbuf, -1, sizeof(*bay3dbuf)); + if (params_vdev->ops->get_bay3d_buffd) + params_vdev->ops->get_bay3d_buffd(params_vdev, bay3dbuf); +} + int rkisp_register_params_vdev(struct rkisp_isp_params_vdev *params_vdev, struct v4l2_device *v4l2_dev, struct rkisp_device *dev) diff --git a/drivers/media/platform/rockchip/isp/isp_params.h b/drivers/media/platform/rockchip/isp/isp_params.h index 2d58aba98d16..b6bbf1d7ec66 100644 --- a/drivers/media/platform/rockchip/isp/isp_params.h +++ b/drivers/media/platform/rockchip/isp/isp_params.h @@ -42,6 +42,8 @@ struct rkisp_isp_params_ops { void (*fop_release)(struct rkisp_isp_params_vdev *params_vdev); bool (*check_bigmode)(struct rkisp_isp_params_vdev *params_vdev); int (*info2ddr_cfg)(struct rkisp_isp_params_vdev *params_vdev, void *arg); + void (*get_bay3d_buffd)(struct rkisp_isp_params_vdev *params_vdev, + struct rkisp_bay3dbuf_info *bay3dbuf); }; /* @@ -147,4 +149,6 @@ void rkisp_params_meshbuf_free(struct rkisp_isp_params_vdev *params_vdev, u64 id void rkisp_params_stream_stop(struct rkisp_isp_params_vdev *params_vdev); bool rkisp_params_check_bigmode(struct rkisp_isp_params_vdev *params_vdev); int rkisp_params_info2ddr_cfg(struct rkisp_isp_params_vdev *params_vdev, void *arg); +void rkisp_params_get_bay3d_buffd(struct rkisp_isp_params_vdev *params_vdev, + struct rkisp_bay3dbuf_info *bay3dbuf); #endif /* _RKISP_ISP_PARAM_H */ diff --git a/drivers/media/platform/rockchip/isp/isp_params_v21.c b/drivers/media/platform/rockchip/isp/isp_params_v21.c index e13e97ca53d0..c6f22d603754 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v21.c +++ b/drivers/media/platform/rockchip/isp/isp_params_v21.c @@ -3973,6 +3973,19 @@ end: return ispdev->is_bigmode = is_bigmode; } +static void +rkisp_params_get_bay3d_buffd_v21(struct rkisp_isp_params_vdev *params_vdev, + struct rkisp_bay3dbuf_info *bay3dbuf) +{ + struct rkisp_isp_params_val_v21 *priv_val = params_vdev->priv_val; + struct rkisp_dummy_buffer *buf = &priv_val->buf_3dnr; + + if (rkisp_buf_get_fd(params_vdev->dev, buf, true) < 0) + return; + bay3dbuf->iir_fd = buf->dma_fd; + bay3dbuf->iir_size = buf->size; +} + /* Not called when the camera active, thus not isr protection. */ static void rkisp_params_first_cfg_v2x(struct rkisp_isp_params_vdev *params_vdev) @@ -4330,6 +4343,7 @@ static struct rkisp_isp_params_ops rkisp_isp_params_ops_tbl = { .stream_stop = rkisp_params_stream_stop_v2x, .fop_release = rkisp_params_fop_release_v2x, .check_bigmode = rkisp_params_check_bigmode_v21, + .get_bay3d_buffd = rkisp_params_get_bay3d_buffd_v21, }; int rkisp_init_params_vdev_v21(struct rkisp_isp_params_vdev *params_vdev) diff --git a/drivers/media/platform/rockchip/isp/isp_params_v32.c b/drivers/media/platform/rockchip/isp/isp_params_v32.c index 23072b4628de..ac46505c917d 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v32.c +++ b/drivers/media/platform/rockchip/isp/isp_params_v32.c @@ -5209,9 +5209,9 @@ rkisp_params_info2ddr_cfg_v32(struct rkisp_isp_params_vdev *params_vdev, void *a priv_val->buf_info_owner = cfg->owner; return 0; case RKISP_INFO2DRR_OWNER_GAIN: - ctrl = ISP3X_GAIN_2DDR_mode(cfg->u.gain.gain2ddr_mode); + ctrl = ISP3X_GAIN_2DDR_MODE(cfg->u.gain.gain2ddr_mode); ctrl |= ISP3X_GAIN_2DDR_EN; - mask = ISP3X_GAIN_2DDR_mode(3); + mask = ISP3X_GAIN_2DDR_MODE(3); reg = ISP3X_GAIN_CTRL; if (cfg->wsize) @@ -5296,6 +5296,26 @@ err: return -ENOMEM; } +static void +rkisp_params_get_bay3d_buffd_v32(struct rkisp_isp_params_vdev *params_vdev, + struct rkisp_bay3dbuf_info *bay3dbuf) +{ + struct rkisp_isp_params_val_v32 *priv_val = params_vdev->priv_val; + struct rkisp_dummy_buffer *buf; + + buf = &priv_val->buf_3dnr_iir; + if (rkisp_buf_get_fd(params_vdev->dev, buf, true) < 0) + return; + bay3dbuf->iir_fd = buf->dma_fd; + bay3dbuf->iir_size = buf->size; + + buf = &priv_val->buf_3dnr_ds; + if (rkisp_buf_get_fd(params_vdev->dev, buf, true) < 0) + return; + bay3dbuf->u.v32.ds_fd = buf->dma_fd; + bay3dbuf->u.v32.ds_size = buf->size; +} + static void rkisp_params_stream_stop_v32(struct rkisp_isp_params_vdev *params_vdev) { @@ -5529,6 +5549,7 @@ static struct rkisp_isp_params_ops rkisp_isp_params_ops_tbl = { .fop_release = rkisp_params_fop_release_v32, .check_bigmode = rkisp_params_check_bigmode_v32, .info2ddr_cfg = rkisp_params_info2ddr_cfg_v32, + .get_bay3d_buffd = rkisp_params_get_bay3d_buffd_v32, }; int rkisp_init_params_vdev_v32(struct rkisp_isp_params_vdev *params_vdev) diff --git a/drivers/media/platform/rockchip/isp/isp_params_v3x.c b/drivers/media/platform/rockchip/isp/isp_params_v3x.c index 0491cc9bd8ba..96333d4e72a0 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v3x.c +++ b/drivers/media/platform/rockchip/isp/isp_params_v3x.c @@ -3526,26 +3526,26 @@ isp_bay3d_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) return; if (en) { - if (!priv_val->buf_3dnr_iir[id].mem_priv) { + if (!priv_val->buf_3dnr_iir.mem_priv) { dev_err(ispdev->dev, "no bay3d buffer available\n"); return; } - value = priv_val->buf_3dnr_iir[id].size; + value = priv_val->buf_3dnr_iir.size; isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_IIR_WR_SIZE, id); - value = priv_val->buf_3dnr_iir[id].dma_addr; + value = priv_val->buf_3dnr_iir.dma_addr + value * id; isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_IIR_WR_BASE, id); isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_IIR_RD_BASE, id); - value = priv_val->buf_3dnr_cur[id].size; + value = priv_val->buf_3dnr_cur.size; isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_CUR_WR_SIZE, id); - value = priv_val->buf_3dnr_cur[id].dma_addr; + value = priv_val->buf_3dnr_cur.dma_addr + value * id; isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_CUR_WR_BASE, id); isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_CUR_RD_BASE, id); - value = priv_val->buf_3dnr_ds[id].size; + value = priv_val->buf_3dnr_ds.size; isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_DS_WR_SIZE, id); - value = priv_val->buf_3dnr_ds[id].dma_addr; + value = priv_val->buf_3dnr_ds.dma_addr + value * id; isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_DS_WR_BASE, id); isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_DS_RD_BASE, id); @@ -4164,42 +4164,41 @@ rkisp_alloc_internal_buf(struct rkisp_isp_params_vdev *params_vdev, if (ispdev->hw_dev->unite) w = ALIGN(isp_sdev->in_crop.width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL, 16); - for (id = 0; id <= !!ispdev->hw_dev->unite; id++) { - size = ALIGN((w + w / 8) * h * 2, 16); + size = ALIGN((w + w / 8) * h * 2, 16); - priv_val->buf_3dnr_iir[id].size = size; - ret = rkisp_alloc_buffer(ispdev, &priv_val->buf_3dnr_iir[id]); - if (ret) { - dev_err(ispdev->dev, "alloc bay3d iir buf fail:%d\n", ret); - goto err_3dnr; - } + if (ispdev->hw_dev->unite) + size *= 2; + priv_val->buf_3dnr_iir.size = size; + ret = rkisp_alloc_buffer(ispdev, &priv_val->buf_3dnr_iir); + if (ret) { + dev_err(ispdev->dev, "alloc bay3d iir buf fail:%d\n", ret); + goto err_3dnr; + } + priv_val->buf_3dnr_cur.size = size; + ret = rkisp_alloc_buffer(ispdev, &priv_val->buf_3dnr_cur); + if (ret) { + rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_iir); + dev_err(ispdev->dev, "alloc bay3d cur buf fail:%d\n", ret); + goto err_3dnr; + } - priv_val->buf_3dnr_cur[id].size = size; - ret = rkisp_alloc_buffer(ispdev, &priv_val->buf_3dnr_cur[id]); - if (ret) { - rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_iir[id]); - dev_err(ispdev->dev, "alloc bay3d cur buf fail:%d\n", ret); - goto err_3dnr; - } - - size = 2 * ALIGN(w * h / 64, 16); - priv_val->buf_3dnr_ds[id].size = size; - ret = rkisp_alloc_buffer(ispdev, &priv_val->buf_3dnr_ds[id]); - if (ret) { - rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_iir[id]); - rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_cur[id]); - dev_err(ispdev->dev, "alloc bay3d ds buf fail:%d\n", ret); - goto err_3dnr; - } + size = 2 * ALIGN(w * h / 64, 16); + if (ispdev->hw_dev->unite) + size *= 2; + priv_val->buf_3dnr_ds.size = size; + ret = rkisp_alloc_buffer(ispdev, &priv_val->buf_3dnr_ds); + if (ret) { + rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_iir); + rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_cur); + dev_err(ispdev->dev, "alloc bay3d ds buf fail:%d\n", ret); + goto err_3dnr; } } return 0; err_3dnr: - for (id -= 1; id >= 0; id--) { - rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_iir[id]); - rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_cur[id]); - rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_ds[id]); - } + rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_iir); + rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_cur); + rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_ds); id = ispdev->hw_dev->unite ? 1 : 0; i = ISP3X_3DLUT_BUF_NUM; err_3dlut: @@ -4393,6 +4392,32 @@ end: return ispdev->is_bigmode = is_bigmode; } +static void +rkisp_params_get_bay3d_buffd_v3x(struct rkisp_isp_params_vdev *params_vdev, + struct rkisp_bay3dbuf_info *bay3dbuf) +{ + struct rkisp_isp_params_val_v3x *priv_val = params_vdev->priv_val; + struct rkisp_dummy_buffer *buf; + + buf = &priv_val->buf_3dnr_iir; + if (rkisp_buf_get_fd(params_vdev->dev, buf, true) < 0) + return; + bay3dbuf->iir_fd = buf->dma_fd; + bay3dbuf->iir_size = buf->size; + + buf = &priv_val->buf_3dnr_cur; + if (rkisp_buf_get_fd(params_vdev->dev, buf, true) < 0) + return; + bay3dbuf->u.v30.cur_fd = buf->dma_fd; + bay3dbuf->u.v30.cur_size = buf->size; + + buf = &priv_val->buf_3dnr_ds; + if (rkisp_buf_get_fd(params_vdev->dev, buf, true) < 0) + return; + bay3dbuf->u.v30.ds_fd = buf->dma_fd; + bay3dbuf->u.v30.ds_size = buf->size; +} + /* Not called when the camera active, thus not isr protection. */ static void rkisp_params_first_cfg_v3x(struct rkisp_isp_params_vdev *params_vdev) @@ -4615,10 +4640,10 @@ rkisp_params_stream_stop_v3x(struct rkisp_isp_params_vdev *params_vdev) priv_val = (struct rkisp_isp_params_val_v3x *)params_vdev->priv_val; tasklet_disable(&priv_val->lsc_tasklet); + rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_iir); + rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_cur); + rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_ds); for (id = 0; id <= !!ispdev->hw_dev->unite; id++) { - rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_iir[id]); - rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_cur[id]); - rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_ds[id]); for (i = 0; i < ISP3X_3DLUT_BUF_NUM; i++) rkisp_free_buffer(ispdev, &priv_val->buf_3dlut[id][i]); } @@ -4859,6 +4884,7 @@ static struct rkisp_isp_params_ops rkisp_isp_params_ops_tbl = { .stream_stop = rkisp_params_stream_stop_v3x, .fop_release = rkisp_params_fop_release_v3x, .check_bigmode = rkisp_params_check_bigmode_v3x, + .get_bay3d_buffd = rkisp_params_get_bay3d_buffd_v3x, }; int rkisp_init_params_vdev_v3x(struct rkisp_isp_params_vdev *params_vdev) diff --git a/drivers/media/platform/rockchip/isp/isp_params_v3x.h b/drivers/media/platform/rockchip/isp/isp_params_v3x.h index 0d5041ddf6f4..b7bc923521c8 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v3x.h +++ b/drivers/media/platform/rockchip/isp/isp_params_v3x.h @@ -183,9 +183,9 @@ struct rkisp_isp_params_val_v3x { struct rkisp_dummy_buffer buf_cac[ISP3_UNITE_MAX][ISP3X_MESH_BUF_NUM]; u32 buf_cac_idx[ISP3_UNITE_MAX]; - struct rkisp_dummy_buffer buf_3dnr_iir[ISP3_UNITE_MAX]; - struct rkisp_dummy_buffer buf_3dnr_cur[ISP3_UNITE_MAX]; - struct rkisp_dummy_buffer buf_3dnr_ds[ISP3_UNITE_MAX]; + struct rkisp_dummy_buffer buf_3dnr_iir; + struct rkisp_dummy_buffer buf_3dnr_cur; + struct rkisp_dummy_buffer buf_3dnr_ds; bool dhaz_en; bool drc_en; diff --git a/drivers/media/platform/rockchip/isp/procfs.c b/drivers/media/platform/rockchip/isp/procfs.c index cf2949d5e9db..223f674d99ea 100644 --- a/drivers/media/platform/rockchip/isp/procfs.c +++ b/drivers/media/platform/rockchip/isp/procfs.c @@ -1009,23 +1009,23 @@ static void rkisp_proc_dump_mem(struct rkisp_device *dev) if (dev->isp_ver == ISP_V30) { struct rkisp_isp_params_val_v3x *p = dev->params_vdev.priv_val; - if (p->buf_3dnr_iir[0].mem_priv) { - if (!p->buf_3dnr_iir[0].is_need_vaddr) - p->buf_3dnr_iir[0].vaddr = g_ops->vaddr(p->buf_3dnr_iir[0].mem_priv); - iir_addr = p->buf_3dnr_iir[0].vaddr; - iir_size = p->buf_3dnr_iir[0].size; + if (p->buf_3dnr_iir.mem_priv) { + if (!p->buf_3dnr_iir.is_need_vaddr) + p->buf_3dnr_iir.vaddr = g_ops->vaddr(p->buf_3dnr_iir.mem_priv); + iir_addr = p->buf_3dnr_iir.vaddr; + iir_size = p->buf_3dnr_iir.size; } - if (p->buf_3dnr_cur[0].mem_priv) { - if (!p->buf_3dnr_cur[0].is_need_vaddr) - p->buf_3dnr_cur[0].vaddr = g_ops->vaddr(p->buf_3dnr_cur[0].mem_priv); - cur_addr = p->buf_3dnr_cur[0].vaddr; - cur_size = p->buf_3dnr_cur[0].size; + if (p->buf_3dnr_cur.mem_priv) { + if (!p->buf_3dnr_cur.is_need_vaddr) + p->buf_3dnr_cur.vaddr = g_ops->vaddr(p->buf_3dnr_cur.mem_priv); + cur_addr = p->buf_3dnr_cur.vaddr; + cur_size = p->buf_3dnr_cur.size; } - if (p->buf_3dnr_ds[0].mem_priv) { - if (!p->buf_3dnr_ds[0].is_need_vaddr) - p->buf_3dnr_ds[0].vaddr = g_ops->vaddr(p->buf_3dnr_ds[0].mem_priv); - ds_addr = p->buf_3dnr_ds[0].vaddr; - ds_size = p->buf_3dnr_ds[0].size; + if (p->buf_3dnr_ds.mem_priv) { + if (!p->buf_3dnr_ds.is_need_vaddr) + p->buf_3dnr_ds.vaddr = g_ops->vaddr(p->buf_3dnr_ds.mem_priv); + ds_addr = p->buf_3dnr_ds.vaddr; + ds_size = p->buf_3dnr_ds.size; } } diff --git a/drivers/media/platform/rockchip/isp/regs_v3x.h b/drivers/media/platform/rockchip/isp/regs_v3x.h index 5e4c85710ee1..0fe2e47254dd 100644 --- a/drivers/media/platform/rockchip/isp/regs_v3x.h +++ b/drivers/media/platform/rockchip/isp/regs_v3x.h @@ -2230,7 +2230,7 @@ /* GAIN */ #define ISP3X_GAIN_2DDR_EN BIT(24) -#define ISP3X_GAIN_2DDR_mode(a) (((a) & 0x3) << 25) +#define ISP3X_GAIN_2DDR_MODE(a) (((a) & 0x3) << 25) /* DPCC */ #define ISP3X_DPCC_WORKING BIT(30) diff --git a/drivers/media/platform/rockchip/isp/rkisp.c b/drivers/media/platform/rockchip/isp/rkisp.c index e09db6296f0f..18a4d871ba9c 100644 --- a/drivers/media/platform/rockchip/isp/rkisp.c +++ b/drivers/media/platform/rockchip/isp/rkisp.c @@ -3623,6 +3623,9 @@ static long rkisp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) case RKISP_VICAP_CMD_MODE: ret = rkisp_set_work_mode_by_vicap(isp_dev, arg); break; + case RKISP_CMD_GET_BAY3D_BUFFD: + rkisp_params_get_bay3d_buffd(&isp_dev->params_vdev, arg); + break; default: ret = -ENOIOCTLCMD; } @@ -3635,103 +3638,91 @@ static long rkisp_compat_ioctl32(struct v4l2_subdev *sd, unsigned int cmd, unsigned long arg) { void __user *up = compat_ptr(arg); - struct isp2x_csi_trigger trigger; - struct rkisp_thunderboot_resmem resmem; - struct rkisp_ldchbuf_info ldchbuf; - struct rkisp_ldchbuf_size ldchsize; - struct rkisp_meshbuf_info meshbuf; - struct rkisp_meshbuf_size meshsize; - struct rkisp_thunderboot_shmem shmem; - struct isp2x_buf_idxfd idxfd; - struct rkisp_info2ddr info2ddr; + void *pbuf = NULL; long ret = 0; - u64 module_id; + u32 size = 0; + bool cp_t_us = false, cp_f_us = false; - if (!up && cmd != RKISP_CMD_FREE_SHARED_BUF) + if (!up && + cmd != RKISP_CMD_FREE_SHARED_BUF && + cmd != RKISP_CMD_MULTI_DEV_FORCE_ENUM) return -EINVAL; switch (cmd) { case RKISP_CMD_TRIGGER_READ_BACK: - if (copy_from_user(&trigger, up, sizeof(trigger))) - return -EFAULT; - ret = rkisp_ioctl(sd, cmd, &trigger); + size = sizeof(struct isp2x_csi_trigger); + cp_f_us = true; break; case RKISP_CMD_GET_SHARED_BUF: - if (!IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP)) { - ret = -ENOIOCTLCMD; - break; - } - ret = rkisp_ioctl(sd, cmd, &resmem); - if (!ret && copy_to_user(up, &resmem, sizeof(resmem))) - ret = -EFAULT; + if (!IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP)) + return -ENOIOCTLCMD; + size = sizeof(struct rkisp_thunderboot_resmem); + cp_t_us = true; break; case RKISP_CMD_FREE_SHARED_BUF: - if (!IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP)) { - ret = -ENOIOCTLCMD; - break; - } - ret = rkisp_ioctl(sd, cmd, NULL); + if (!IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP)) + return -ENOIOCTLCMD; + case RKISP_CMD_MULTI_DEV_FORCE_ENUM: break; case RKISP_CMD_GET_LDCHBUF_INFO: - ret = rkisp_ioctl(sd, cmd, &ldchbuf); - if (!ret && copy_to_user(up, &ldchbuf, sizeof(ldchbuf))) - ret = -EFAULT; + size = sizeof(struct rkisp_ldchbuf_info); + cp_t_us = true; break; case RKISP_CMD_SET_LDCHBUF_SIZE: - if (copy_from_user(&ldchsize, up, sizeof(ldchsize))) - return -EFAULT; - ret = rkisp_ioctl(sd, cmd, &ldchsize); + size = sizeof(struct rkisp_ldchbuf_size); + cp_f_us = true; break; case RKISP_CMD_GET_MESHBUF_INFO: - if (copy_from_user(&meshbuf, up, sizeof(meshbuf))) - return -EFAULT; - ret = rkisp_ioctl(sd, cmd, &meshbuf); - if (!ret && copy_to_user(up, &meshbuf, sizeof(meshbuf))) - ret = -EFAULT; + size = sizeof(struct rkisp_meshbuf_info); + cp_f_us = true; + cp_t_us = true; break; case RKISP_CMD_SET_MESHBUF_SIZE: - if (copy_from_user(&meshsize, up, sizeof(meshsize))) - return -EFAULT; - ret = rkisp_ioctl(sd, cmd, &meshsize); + size = sizeof(struct rkisp_meshbuf_size); + cp_f_us = true; break; case RKISP_CMD_GET_SHM_BUFFD: - if (!IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP)) { - ret = -ENOIOCTLCMD; - break; - } - if (copy_from_user(&shmem, up, sizeof(shmem))) - return -EFAULT; - ret = rkisp_ioctl(sd, cmd, &shmem); - if (!ret && copy_to_user(up, &shmem, sizeof(shmem))) - ret = -EFAULT; + if (!IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP)) + return -ENOIOCTLCMD; + size = sizeof(struct rkisp_thunderboot_shmem); + cp_f_us = true; + cp_t_us = true; break; case RKISP_CMD_GET_FBCBUF_FD: - ret = rkisp_ioctl(sd, cmd, &idxfd); - if (!ret && copy_to_user(up, &idxfd, sizeof(idxfd))) - ret = -EFAULT; + size = sizeof(struct isp2x_buf_idxfd); + cp_t_us = true; break; case RKISP_CMD_INFO2DDR: - if (copy_from_user(&info2ddr, up, sizeof(info2ddr))) - return -EFAULT; - ret = rkisp_ioctl(sd, cmd, &info2ddr); - if (!ret && copy_to_user(up, &info2ddr, sizeof(info2ddr))) - ret = -EFAULT; + size = sizeof(struct rkisp_info2ddr); + cp_f_us = true; + cp_t_us = true; break; case RKISP_CMD_MESHBUF_FREE: - if (copy_from_user(&module_id, up, sizeof(module_id))) - return -EFAULT; - ret = rkisp_ioctl(sd, cmd, &module_id); + size = sizeof(u64); + cp_f_us = true; break; - case RKISP_CMD_MULTI_DEV_FORCE_ENUM: - ret = rkisp_ioctl(sd, cmd, NULL); - break; - case RKISP_VICAP_CMD_SET_STREAM: - ret = rkisp_ioctl(sd, cmd, NULL); + case RKISP_CMD_GET_BAY3D_BUFFD: + size = sizeof(struct rkisp_bay3dbuf_info); + cp_t_us = true; break; default: - ret = -ENOIOCTLCMD; + return -ENOIOCTLCMD; } + if (size) { + pbuf = kmalloc(size, GFP_KERNEL); + if (!pbuf) + return -ENOMEM; + } + if (cp_f_us && copy_from_user(pbuf, up, size)) { + ret = -EFAULT; + goto free_buf; + } + ret = rkisp_ioctl(sd, cmd, pbuf); + if (!ret && cp_t_us && copy_to_user(up, pbuf, size)) + ret = -EFAULT; +free_buf: + kfree(pbuf); return ret; } #endif diff --git a/include/uapi/linux/rk-isp2-config.h b/include/uapi/linux/rk-isp2-config.h index fc5177820177..7ea04e6f9477 100644 --- a/include/uapi/linux/rk-isp2-config.h +++ b/include/uapi/linux/rk-isp2-config.h @@ -58,6 +58,9 @@ #define RKISP_CMD_MULTI_DEV_FORCE_ENUM \ _IO('V', BASE_VIDIOC_PRIVATE + 13) +#define RKISP_CMD_GET_BAY3D_BUFFD \ + _IOR('V', BASE_VIDIOC_PRIVATE + 15, struct rkisp_bay3dbuf_info) + /****************ISP VIDEO IOCTL******************************/ #define RKISP_CMD_GET_CSI_MEMORY_MODE \ @@ -318,6 +321,23 @@ struct isp2x_mesh_head { __u32 data_oft; } __attribute__ ((packed)); +struct rkisp_bay3dbuf_info { + int iir_fd; + int iir_size; + union { + struct { + int cur_fd; + int cur_size; + int ds_fd; + int ds_size; + } v30; + struct { + int ds_fd; + int ds_size; + } v32; + } u; +} __attribute__ ((packed)); + #define RKISP_CMSK_WIN_MAX 12 #define RKISP_CMSK_WIN_MAX_V30 8 #define RKISP_CMSK_MOSAIC_MODE 0 From 6c66737840df230b340c0073768563a71c881c9d Mon Sep 17 00:00:00 2001 From: Cai YiWei Date: Thu, 21 Sep 2023 16:46:07 +0800 Subject: [PATCH 10/34] media: rockchip: isp: fix isp32 lite frame buffer data read Change-Id: I1e8e19185bce2800a0aee2a1623b204adb07355d Signed-off-by: Cai YiWei --- drivers/media/platform/rockchip/isp/rkisp.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/media/platform/rockchip/isp/rkisp.c b/drivers/media/platform/rockchip/isp/rkisp.c index 18a4d871ba9c..5d29e8030a63 100644 --- a/drivers/media/platform/rockchip/isp/rkisp.c +++ b/drivers/media/platform/rockchip/isp/rkisp.c @@ -856,6 +856,19 @@ run_next: else dev->irq_ends_mask &= ~ISP_FRAME_BP; + if (hw->is_frm_buf) { + val = ISP32L_WR_FRM_BUF_EN | ISP32L_RD_FRM_BUF_EN | + ISP32L_AXI_CONF_RD_ST_MODE | ISP32L_AXI_CONF_RD_DIS | + ISP32L_FRM_BUF_FORCE_UPD; + rkisp_write(dev, ISP32L_AXI_CONF_RD_CTRL, val, true); + + val = ISP32L_WR_FRM_BUF_EN | ISP32L_RD_FRM_BUF_EN | + ISP32L_AXI_CONF_RD_ST_MODE | ISP32L_AXI_CONF_RD_DIS | + ISP32L_AXI_CONF_RD_ST; + rkisp_write(dev, ISP32L_AXI_CONF_RD_CTRL, val, true); + udelay(25); + } + val = rkisp_read(dev, CSI2RX_CTRL0, true); val &= ~SW_IBUF_OP_MODE(0xf); tmp = SW_IBUF_OP_MODE(dev->rd_mode); From c4c06227b02a3af6274f6ea0780cce7c79530293 Mon Sep 17 00:00:00 2001 From: Cai YiWei Date: Tue, 2 Jan 2024 11:52:52 +0800 Subject: [PATCH 11/34] media: rockchip: isp: add RKISP_CMD_SET_TB_HEAD_V32 API Change-Id: I07ae10d69ae977ff5932c377e24eefbd48387946 Signed-off-by: Cai YiWei --- drivers/media/platform/rockchip/isp/rkisp.c | 8 +++++++- include/uapi/linux/rk-isp2-config.h | 1 + include/uapi/linux/rk-isp32-config.h | 3 +++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/rockchip/isp/rkisp.c b/drivers/media/platform/rockchip/isp/rkisp.c index b90a411b4622..e09db6296f0f 100644 --- a/drivers/media/platform/rockchip/isp/rkisp.c +++ b/drivers/media/platform/rockchip/isp/rkisp.c @@ -3508,7 +3508,8 @@ static long rkisp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) rkisp_get_info(isp_dev, arg); break; case RKISP_CMD_GET_TB_HEAD_V32: - if (isp_dev->tb_head.complete != RKISP_TB_OK) { + if (isp_dev->tb_head.complete != RKISP_TB_OK || + (!isp_dev->is_rtt_suspend && !isp_dev->is_pre_on)) { ret = -EINVAL; break; } @@ -3518,6 +3519,11 @@ static long rkisp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) memcpy(&tb_head_v32->cfg, isp_dev->params_vdev.isp32_params, sizeof(struct isp32_isp_params_cfg)); break; + case RKISP_CMD_SET_TB_HEAD_V32: + tb_head_v32 = arg; + memcpy(&isp_dev->tb_head, tb_head_v32, + sizeof(struct rkisp_thunderboot_resmem_head)); + break; case RKISP_CMD_GET_SHARED_BUF: if (!IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP)) { ret = -ENOIOCTLCMD; diff --git a/include/uapi/linux/rk-isp2-config.h b/include/uapi/linux/rk-isp2-config.h index 50949e0752bc..fc5177820177 100644 --- a/include/uapi/linux/rk-isp2-config.h +++ b/include/uapi/linux/rk-isp2-config.h @@ -52,6 +52,7 @@ _IOW('V', BASE_VIDIOC_PRIVATE + 11, long long) /* BASE_VIDIOC_PRIVATE + 12 for RKISP_CMD_GET_TB_HEAD_V32 */ +/* BASE_VIDIOC_PRIVATE + 14 for RKISP_CMD_SET_TB_HEAD_V32 */ /* for all isp device stop and no power off but resolution change */ #define RKISP_CMD_MULTI_DEV_FORCE_ENUM \ diff --git a/include/uapi/linux/rk-isp32-config.h b/include/uapi/linux/rk-isp32-config.h index ecd4eaef2cd3..218023c93f14 100644 --- a/include/uapi/linux/rk-isp32-config.h +++ b/include/uapi/linux/rk-isp32-config.h @@ -14,6 +14,9 @@ #define RKISP_CMD_GET_TB_HEAD_V32 \ _IOR('V', BASE_VIDIOC_PRIVATE + 12, struct rkisp32_thunderboot_resmem_head) +#define RKISP_CMD_SET_TB_HEAD_V32 \ + _IOW('V', BASE_VIDIOC_PRIVATE + 14, struct rkisp32_thunderboot_resmem_head) + #define ISP32_MODULE_DPCC ISP3X_MODULE_DPCC #define ISP32_MODULE_BLS ISP3X_MODULE_BLS #define ISP32_MODULE_SDG ISP3X_MODULE_SDG From e0a6d5fa869c8ba0d109a415ca1bfa2d601d12df Mon Sep 17 00:00:00 2001 From: Cai YiWei Date: Tue, 3 Oct 2023 14:50:46 +0800 Subject: [PATCH 12/34] media: rockchip: isp: support 8k for isp32 lite Change-Id: I2ebd5bff4be4b646564a874ce801cc8c9bf261e1 Signed-off-by: Cai YiWei --- drivers/media/platform/rockchip/isp/capture.c | 43 +++- .../media/platform/rockchip/isp/capture_v30.c | 18 +- .../media/platform/rockchip/isp/capture_v32.c | 69 +++++- drivers/media/platform/rockchip/isp/common.c | 91 ++++--- drivers/media/platform/rockchip/isp/common.h | 18 +- drivers/media/platform/rockchip/isp/dev.c | 10 +- drivers/media/platform/rockchip/isp/dev.h | 41 +++- drivers/media/platform/rockchip/isp/dmarx.c | 38 ++- drivers/media/platform/rockchip/isp/hw.c | 12 +- .../media/platform/rockchip/isp/isp_params.c | 9 +- .../platform/rockchip/isp/isp_params_v1x.c | 1 + .../platform/rockchip/isp/isp_params_v21.c | 8 +- .../platform/rockchip/isp/isp_params_v2x.c | 1 + .../platform/rockchip/isp/isp_params_v32.c | 225 ++++++++---------- .../platform/rockchip/isp/isp_params_v32.h | 12 +- .../platform/rockchip/isp/isp_params_v3x.c | 132 +++------- .../platform/rockchip/isp/isp_params_v3x.h | 18 +- .../media/platform/rockchip/isp/isp_stats.c | 10 +- .../media/platform/rockchip/isp/isp_stats.h | 1 + .../platform/rockchip/isp/isp_stats_v1x.c | 14 +- .../platform/rockchip/isp/isp_stats_v21.c | 17 +- .../platform/rockchip/isp/isp_stats_v2x.c | 14 +- .../platform/rockchip/isp/isp_stats_v32.c | 62 +++-- .../platform/rockchip/isp/isp_stats_v3x.c | 52 ++-- drivers/media/platform/rockchip/isp/procfs.c | 188 +++++++-------- drivers/media/platform/rockchip/isp/regs.c | 99 +++++--- .../media/platform/rockchip/isp/regs_v2x.h | 11 +- drivers/media/platform/rockchip/isp/rkisp.c | 162 ++++++++----- drivers/media/platform/rockchip/isp/rkisp.h | 2 + 29 files changed, 751 insertions(+), 627 deletions(-) diff --git a/drivers/media/platform/rockchip/isp/capture.c b/drivers/media/platform/rockchip/isp/capture.c index 76165eb4ba92..e7c26e59e254 100644 --- a/drivers/media/platform/rockchip/isp/capture.c +++ b/drivers/media/platform/rockchip/isp/capture.c @@ -669,6 +669,19 @@ static int rkisp_set_fmt(struct rkisp_stream *stream, return -EINVAL; } + if ((dev->unite_div == ISP_UNITE_DIV4 || + (dev->isp_ver == ISP_V32_L && + stream->id == RKISP_STREAM_SP && + dev->unite_div == ISP_UNITE_DIV2)) && + (pixm->width != dev->isp_sdev.out_crop.width || + pixm->height != dev->isp_sdev.out_crop.height)) { + pixm->width = dev->isp_sdev.out_crop.width; + pixm->height = dev->isp_sdev.out_crop.height; + v4l2_warn(&dev->v4l2_dev, + "%s no support scale force to %dx%d\n", + __func__, pixm->width, pixm->height); + } + /* do checks on resolution */ restrict_rsz_resolution(stream, config, &max_rsz); if (stream->id == RKISP_STREAM_MP || @@ -1471,8 +1484,7 @@ static struct v4l2_rect *rkisp_update_crop(struct rkisp_stream *stream, const struct v4l2_rect *in) { struct rkisp_device *dev = stream->ispdev; - bool is_unite = !!dev->hw_dev->unite; - u32 align = is_unite ? 4 : 2; + u32 align = (dev->unite_div > ISP_UNITE_DIV1) ? 4 : 2; /* Not crop for MP bayer raw data and dmatx path */ if ((stream->id == RKISP_STREAM_MP && @@ -1492,6 +1504,7 @@ static struct v4l2_rect *rkisp_update_crop(struct rkisp_stream *stream, sel->left = ALIGN(sel->left, 2); sel->width = ALIGN(sel->width, align); + sel->height = ALIGN(sel->height, align); sel->left = clamp_t(u32, sel->left, 0, in->width - STREAM_MIN_MP_SP_INPUT_WIDTH); sel->top = clamp_t(u32, sel->top, 0, @@ -1500,11 +1513,19 @@ static struct v4l2_rect *rkisp_update_crop(struct rkisp_stream *stream, in->width - sel->left); sel->height = clamp_t(u32, sel->height, STREAM_MIN_MP_SP_INPUT_HEIGHT, in->height - sel->top); - if (is_unite && (sel->width + 2 * sel->left) != in->width) { + if (dev->unite_div > ISP_UNITE_DIV1 && + (sel->width + 2 * sel->left) != in->width) { sel->left = ALIGN_DOWN((in->width - sel->width) / 2, 2); v4l2_warn(&dev->v4l2_dev, - "try horizontal center crop(%d,%d)/%dx%d for dual isp\n", - sel->left, sel->top, sel->width, sel->height); + "try horizontal center left:%d width:%d for unite mode\n", + sel->left, sel->width); + } + if (dev->unite_div == ISP_UNITE_DIV4 && + (sel->height + 2 * sel->top) != in->height) { + sel->top = ALIGN_DOWN((in->height - sel->height) / 2, 2); + v4l2_warn(&dev->v4l2_dev, + "try vertical center top:%d height:%d for unite mode\n", + sel->top, sel->height); } stream->is_crop_upd = true; return sel; @@ -1764,11 +1785,15 @@ int rkisp_register_stream_vdevs(struct rkisp_device *dev) CIF_ISP_INPUT_H_MAX_V32_UNITE : CIF_ISP_INPUT_H_MAX_V32; ret = rkisp_register_stream_v32(dev); } else if (dev->isp_ver == ISP_V32_L) { - st_cfg->max_rsz_width = CIF_ISP_INPUT_W_MAX_V32_L; - st_cfg->max_rsz_height = CIF_ISP_INPUT_H_MAX_V32_L; + st_cfg->max_rsz_width = dev->hw_dev->unite ? + CIF_ISP_INPUT_W_MAX_V32_L_UNITE : CIF_ISP_INPUT_W_MAX_V32_L; + st_cfg->max_rsz_height = dev->hw_dev->unite ? + CIF_ISP_INPUT_H_MAX_V32_L_UNITE : CIF_ISP_INPUT_H_MAX_V32_L; st_cfg = &rkisp_sp_stream_config; - st_cfg->max_rsz_width = CIF_ISP_INPUT_W_MAX_V32_L; - st_cfg->max_rsz_height = CIF_ISP_INPUT_H_MAX_V32_L; + st_cfg->max_rsz_width = dev->hw_dev->unite ? + CIF_ISP_INPUT_W_MAX_V32_L_UNITE : CIF_ISP_INPUT_W_MAX_V32_L; + st_cfg->max_rsz_height = dev->hw_dev->unite ? + CIF_ISP_INPUT_H_MAX_V32_L_UNITE : CIF_ISP_INPUT_H_MAX_V32_L; ret = rkisp_register_stream_v32(dev); } diff --git a/drivers/media/platform/rockchip/isp/capture_v30.c b/drivers/media/platform/rockchip/isp/capture_v30.c index 992378a87e67..801aad3d68b1 100644 --- a/drivers/media/platform/rockchip/isp/capture_v30.c +++ b/drivers/media/platform/rockchip/isp/capture_v30.c @@ -635,7 +635,8 @@ static int fbc_config_mi(struct rkisp_stream *stream) u32 left_w = (stream->out_fmt.width / 2) & ~0xf; offs += left_w * mult; - rkisp_next_write(stream->ispdev, ISP3X_MPFBC_HEAD_OFFSET, offs, false); + rkisp_idx_write(stream->ispdev, ISP3X_MPFBC_HEAD_OFFSET, + offs, ISP_UNITE_RIGHT, false); } rkisp_unite_set_bits(stream->ispdev, ISP3X_MI_WR_CTRL, 0, CIF_MI_CTRL_INIT_BASE_EN | CIF_MI_CTRL_INIT_OFFSET_EN, false); @@ -784,18 +785,18 @@ static void update_mi(struct rkisp_stream *stream) reg = stream->config->mi.y_base_ad_init; val = stream->next_buf->buff_addr[RKISP_PLANE_Y]; val += ((stream->out_fmt.width / div) & ~0xf); - rkisp_next_write(dev, reg, val, false); + rkisp_idx_write(dev, reg, val, ISP_UNITE_RIGHT, false); reg = stream->config->mi.cb_base_ad_init; val = stream->next_buf->buff_addr[RKISP_PLANE_CB]; val += ((stream->out_fmt.width / div) & ~0xf) * mult; - rkisp_next_write(dev, reg, val, false); + rkisp_idx_write(dev, reg, val, ISP_UNITE_RIGHT, false); if (stream->id != RKISP_STREAM_FBC && stream->id != RKISP_STREAM_BP) { reg = stream->config->mi.cr_base_ad_init; val = stream->next_buf->buff_addr[RKISP_PLANE_CR]; val += ((stream->out_fmt.width / div) & ~0xf); - rkisp_next_write(dev, reg, val, false); + rkisp_idx_write(dev, reg, val, ISP_UNITE_RIGHT, false); } } @@ -836,9 +837,12 @@ static void update_mi(struct rkisp_stream *stream) v4l2_dbg(2, rkisp_debug, &dev->v4l2_dev, "%s stream:%d Y:0x%x CB:0x%x | Y_SHD:0x%x, right\n", __func__, stream->id, - rkisp_next_read(dev, stream->config->mi.y_base_ad_init, false), - rkisp_next_read(dev, stream->config->mi.cb_base_ad_init, false), - rkisp_next_read(dev, stream->config->mi.y_base_ad_shd, true)); + rkisp_idx_read(dev, stream->config->mi.y_base_ad_init, + ISP_UNITE_RIGHT, false), + rkisp_idx_read(dev, stream->config->mi.cb_base_ad_init, + ISP_UNITE_RIGHT, false), + rkisp_idx_read(dev, stream->config->mi.y_base_ad_shd, + ISP_UNITE_RIGHT, true)); } static struct streams_ops rkisp_mp_streams_ops = { diff --git a/drivers/media/platform/rockchip/isp/capture_v32.c b/drivers/media/platform/rockchip/isp/capture_v32.c index 10066eac5953..e48697b5b8c9 100644 --- a/drivers/media/platform/rockchip/isp/capture_v32.c +++ b/drivers/media/platform/rockchip/isp/capture_v32.c @@ -1025,6 +1025,8 @@ static void update_mi(struct rkisp_stream *stream) { struct rkisp_device *dev = stream->ispdev; struct rkisp_dummy_buffer *dummy_buf = &stream->dummy_buf; + struct v4l2_pix_format_mplane *out_fmt = &stream->out_fmt; + u32 div = stream->out_isp_fmt.fourcc == V4L2_PIX_FMT_UYVY ? 1 : 2; u32 val, reg; bool is_cr_cfg = false; @@ -1048,22 +1050,63 @@ static void update_mi(struct rkisp_stream *stream) rkisp_write(dev, reg, val, false); } - if (dev->hw_dev->unite) { + if (dev->unite_div > ISP_UNITE_DIV1) { + /* right of image, or right top of image */ reg = stream->config->mi.y_base_ad_init; val = stream->next_buf->buff_addr[RKISP_PLANE_Y]; - val += ((stream->out_fmt.width / 2) & ~0xf); - rkisp_next_write(dev, reg, val, false); + val += ((out_fmt->width / div) & ~0xf); + rkisp_idx_write(dev, reg, val, ISP_UNITE_RIGHT, false); reg = stream->config->mi.cb_base_ad_init; val = stream->next_buf->buff_addr[RKISP_PLANE_CB]; - val += ((stream->out_fmt.width / 2) & ~0xf); - rkisp_next_write(dev, reg, val, false); + val += ((out_fmt->width / div) & ~0xf); + rkisp_idx_write(dev, reg, val, ISP_UNITE_RIGHT, false); if (is_cr_cfg) { reg = stream->config->mi.cr_base_ad_init; val = stream->next_buf->buff_addr[RKISP_PLANE_CR]; - val += ((stream->out_fmt.width / 2) & ~0xf); - rkisp_next_write(dev, reg, val, false); + val += ((out_fmt->width / div) & ~0xf); + rkisp_idx_write(dev, reg, val, ISP_UNITE_RIGHT, false); + } + } + + if (dev->unite_div == ISP_UNITE_DIV4) { + /* left bottom of image */ + reg = stream->config->mi.y_base_ad_init; + val = stream->next_buf->buff_addr[RKISP_PLANE_Y]; + val += (out_fmt->plane_fmt[0].bytesperline * out_fmt->height / 2); + rkisp_idx_write(dev, reg, val, ISP_UNITE_LEFT_B, false); + + reg = stream->config->mi.cb_base_ad_init; + val = stream->next_buf->buff_addr[RKISP_PLANE_CB]; + val += (out_fmt->plane_fmt[1].sizeimage / 2); + rkisp_idx_write(dev, reg, val, ISP_UNITE_LEFT_B, false); + + if (is_cr_cfg) { + reg = stream->config->mi.cr_base_ad_init; + val = stream->next_buf->buff_addr[RKISP_PLANE_CR]; + val += (out_fmt->plane_fmt[2].sizeimage / 2); + rkisp_idx_write(dev, reg, val, ISP_UNITE_LEFT_B, false); + } + /* right bottom of image */ + reg = stream->config->mi.y_base_ad_init; + val = stream->next_buf->buff_addr[RKISP_PLANE_Y]; + val += (out_fmt->plane_fmt[0].bytesperline * out_fmt->height / 2) + + ((out_fmt->width / div) & ~0xf); + rkisp_idx_write(dev, reg, val, ISP_UNITE_RIGHT_B, false); + + reg = stream->config->mi.cb_base_ad_init; + val = stream->next_buf->buff_addr[RKISP_PLANE_CB]; + val += (out_fmt->plane_fmt[1].sizeimage / 2) + + ((out_fmt->width / div) & ~0xf); + rkisp_idx_write(dev, reg, val, ISP_UNITE_RIGHT_B, false); + + if (is_cr_cfg) { + reg = stream->config->mi.cr_base_ad_init; + val = stream->next_buf->buff_addr[RKISP_PLANE_CR]; + val += (out_fmt->plane_fmt[2].sizeimage / 2) + + ((out_fmt->width / div) & ~0xf); + rkisp_idx_write(dev, reg, val, ISP_UNITE_RIGHT_B, false); } } @@ -1111,15 +1154,15 @@ static void update_mi(struct rkisp_stream *stream) } else if (dummy_buf->mem_priv) { val = dummy_buf->dma_addr; reg = stream->config->mi.y_base_ad_init; - rkisp_write(dev, reg, val, false); + rkisp_unite_write(dev, reg, val, false); /* wrap buf ENC */ if (dev->isp_ver == ISP_V32) val += stream->out_fmt.plane_fmt[0].bytesperline * dev->cap_dev.wrap_line; reg = stream->config->mi.cb_base_ad_init; - rkisp_write(dev, reg, val, false); + rkisp_unite_write(dev, reg, val, false); if (is_cr_cfg) { reg = stream->config->mi.cr_base_ad_init; - rkisp_write(dev, reg, val, false); + rkisp_unite_write(dev, reg, val, false); } } else if (stream->is_using_resmem) { /* resmem for fast stream NV12 output */ @@ -1138,7 +1181,7 @@ static void update_mi(struct rkisp_stream *stream) /* no next buf to preclose mi */ stream->ops->disable_mi(stream); /* no buf, force to close mi */ - if (!stream->curr_buf) + if (!stream->curr_buf && dev->hw_dev->is_single) stream_self_update(stream); } @@ -2304,8 +2347,8 @@ void rkisp_mi_v32_isr(u32 mis_val, struct rkisp_device *dev) v4l2_dbg(3, rkisp_debug, &dev->v4l2_dev, "mi isr:0x%x\n", mis_val); - if (dev->hw_dev->unite == ISP_UNITE_ONE && - dev->unite_index == ISP_UNITE_LEFT) { + if ((dev->unite_div == ISP_UNITE_DIV2 && dev->unite_index != ISP_UNITE_RIGHT) || + (dev->unite_div == ISP_UNITE_DIV4 && dev->unite_index != ISP_UNITE_RIGHT_B)) { rkisp_write(dev, ISP3X_MI_ICR, mis_val, true); goto end; } diff --git a/drivers/media/platform/rockchip/isp/common.c b/drivers/media/platform/rockchip/isp/common.c index 7a1607ebf453..49d9f2427a45 100644 --- a/drivers/media/platform/rockchip/isp/common.c +++ b/drivers/media/platform/rockchip/isp/common.c @@ -27,19 +27,31 @@ void rkisp_write(struct rkisp_device *dev, u32 reg, u32 val, bool is_direct) } } -void rkisp_next_write(struct rkisp_device *dev, u32 reg, u32 val, bool is_direct) +void rkisp_idx_write(struct rkisp_device *dev, u32 reg, u32 val, int idx, bool is_direct) { - u32 offset = RKISP_ISP_SW_MAX_SIZE + reg; - u32 *mem = dev->sw_base_addr + offset; - u32 *flag = dev->sw_base_addr + offset + RKISP_ISP_SW_REG_SIZE; + struct rkisp_hw_dev *hw = dev->hw_dev; + void __iomem *base_addr = hw->base_addr; + u32 *mem, *flag, offset = idx * RKISP_ISP_SW_MAX_SIZE; + if (!hw->unite) + offset = 0; + /* right for isp1 hardware */ + if (hw->unite == ISP_UNITE_TWO && (idx & 0x1)) + base_addr = hw->base_next_addr; + + mem = dev->sw_base_addr + reg + offset; + flag = dev->sw_base_addr + reg + RKISP_ISP_SW_REG_SIZE + offset; *mem = val; *flag = SW_REG_CACHE; if (dev->hw_dev->is_single || is_direct) { *flag = SW_REG_CACHE_SYNC; - if (dev->hw_dev->unite == ISP_UNITE_ONE) - return; - writel(val, dev->hw_dev->base_next_addr + reg); + if (dev->isp_ver == ISP_V32 && reg <= 0x200) + rv1106_sdmmc_get_lock(); + if (idx == ISP_UNITE_LEFT || + (hw->unite == ISP_UNITE_TWO && idx == ISP_UNITE_RIGHT)) + writel(val, base_addr + reg); + if (dev->isp_ver == ISP_V32 && reg <= 0x200) + rv1106_sdmmc_put_lock(); } } @@ -54,14 +66,22 @@ u32 rkisp_read(struct rkisp_device *dev, u32 reg, bool is_direct) return val; } -u32 rkisp_next_read(struct rkisp_device *dev, u32 reg, bool is_direct) +u32 rkisp_idx_read(struct rkisp_device *dev, u32 reg, int idx, bool is_direct) { - u32 val; + struct rkisp_hw_dev *hw = dev->hw_dev; + void __iomem *base_addr = hw->base_addr; + u32 val, offset = idx * RKISP_ISP_SW_MAX_SIZE; - if (dev->hw_dev->is_single || is_direct) - val = readl(dev->hw_dev->base_next_addr + reg); + if (!hw->unite) + offset = 0; + /* right for isp1 hardware */ + if (hw->unite == ISP_UNITE_TWO && (idx & 0x1)) + base_addr = hw->base_next_addr; + + if (hw->is_single || is_direct) + val = readl(base_addr + reg); else - val = *(u32 *)(dev->sw_base_addr + RKISP_ISP_SW_MAX_SIZE + reg); + val = *(u32 *)(dev->sw_base_addr + reg + offset); return val; } @@ -72,11 +92,11 @@ void rkisp_set_bits(struct rkisp_device *dev, u32 reg, u32 mask, u32 val, bool i rkisp_write(dev, reg, val | tmp, is_direct); } -void rkisp_next_set_bits(struct rkisp_device *dev, u32 reg, u32 mask, u32 val, bool is_direct) +void rkisp_idx_set_bits(struct rkisp_device *dev, u32 reg, u32 mask, u32 val, int idx, bool is_direct) { - u32 tmp = rkisp_next_read(dev, reg, is_direct) & ~mask; + u32 tmp = rkisp_idx_read(dev, reg, idx, is_direct) & ~mask; - rkisp_next_write(dev, reg, val | tmp, is_direct); + rkisp_idx_write(dev, reg, val | tmp, idx, is_direct); } void rkisp_clear_bits(struct rkisp_device *dev, u32 reg, u32 mask, bool is_direct) @@ -86,11 +106,11 @@ void rkisp_clear_bits(struct rkisp_device *dev, u32 reg, u32 mask, bool is_direc rkisp_write(dev, reg, tmp & ~mask, is_direct); } -void rkisp_next_clear_bits(struct rkisp_device *dev, u32 reg, u32 mask, bool is_direct) +void rkisp_idx_clear_bits(struct rkisp_device *dev, u32 reg, u32 mask, int idx, bool is_direct) { - u32 tmp = rkisp_next_read(dev, reg, is_direct); + u32 tmp = rkisp_idx_read(dev, reg, idx, is_direct); - rkisp_next_write(dev, reg, tmp & ~mask, is_direct); + rkisp_idx_write(dev, reg, tmp & ~mask, idx, is_direct); } void rkisp_write_reg_cache(struct rkisp_device *dev, u32 reg, u32 val) @@ -100,11 +120,14 @@ void rkisp_write_reg_cache(struct rkisp_device *dev, u32 reg, u32 val) *mem = val; } -void rkisp_next_write_reg_cache(struct rkisp_device *dev, u32 reg, u32 val) +void rkisp_idx_write_reg_cache(struct rkisp_device *dev, u32 reg, u32 val, int idx) { - u32 offset = RKISP_ISP_SW_MAX_SIZE + reg; - u32 *mem = dev->sw_base_addr + offset; + u32 offset = idx * RKISP_ISP_SW_MAX_SIZE; + u32 *mem; + if (!dev->hw_dev->unite) + offset = 0; + mem = dev->sw_base_addr + reg + offset; *mem = val; } @@ -113,9 +136,13 @@ u32 rkisp_read_reg_cache(struct rkisp_device *dev, u32 reg) return *(u32 *)(dev->sw_base_addr + reg); } -u32 rkisp_next_read_reg_cache(struct rkisp_device *dev, u32 reg) +u32 rkisp_idx_read_reg_cache(struct rkisp_device *dev, u32 reg, int idx) { - return *(u32 *)(dev->sw_base_addr + RKISP_ISP_SW_MAX_SIZE + reg); + u32 offset = idx * RKISP_ISP_SW_MAX_SIZE; + + if (!dev->hw_dev->unite) + offset = 0; + return *(u32 *)(dev->sw_base_addr + reg + offset); } void rkisp_set_reg_cache_bits(struct rkisp_device *dev, u32 reg, u32 mask, u32 val) @@ -125,11 +152,11 @@ void rkisp_set_reg_cache_bits(struct rkisp_device *dev, u32 reg, u32 mask, u32 v rkisp_write_reg_cache(dev, reg, val | tmp); } -void rkisp_next_set_reg_cache_bits(struct rkisp_device *dev, u32 reg, u32 mask, u32 val) +void rkisp_idx_set_reg_cache_bits(struct rkisp_device *dev, u32 reg, u32 mask, u32 val, int idx) { - u32 tmp = rkisp_next_read_reg_cache(dev, reg) & ~mask; + u32 tmp = rkisp_idx_read_reg_cache(dev, reg, idx) & ~mask; - rkisp_next_write_reg_cache(dev, reg, val | tmp); + rkisp_idx_write_reg_cache(dev, reg, val | tmp, idx); } void rkisp_clear_reg_cache_bits(struct rkisp_device *dev, u32 reg, u32 mask) @@ -139,11 +166,11 @@ void rkisp_clear_reg_cache_bits(struct rkisp_device *dev, u32 reg, u32 mask) rkisp_write_reg_cache(dev, reg, tmp & ~mask); } -void rkisp_next_clear_reg_cache_bits(struct rkisp_device *dev, u32 reg, u32 mask) +void rkisp_idx_clear_reg_cache_bits(struct rkisp_device *dev, u32 reg, u32 mask, int idx) { - u32 tmp = rkisp_next_read_reg_cache(dev, reg); + u32 tmp = rkisp_idx_read_reg_cache(dev, reg, idx); - rkisp_next_write_reg_cache(dev, reg, tmp & ~mask); + rkisp_idx_write_reg_cache(dev, reg, tmp & ~mask, idx); } void rkisp_update_regs(struct rkisp_device *dev, u32 start, u32 end) @@ -169,9 +196,9 @@ void rkisp_update_regs(struct rkisp_device *dev, u32 start, u32 end) continue; } - if (hw->unite == ISP_UNITE_ONE && dev->unite_index == ISP_UNITE_RIGHT) { - val = dev->sw_base_addr + i + RKISP_ISP_SW_MAX_SIZE; - flag = dev->sw_base_addr + i + RKISP_ISP_SW_MAX_SIZE + RKISP_ISP_SW_REG_SIZE; + if (hw->unite == ISP_UNITE_ONE && dev->unite_index > ISP_UNITE_LEFT) { + val += (RKISP_ISP_SW_MAX_SIZE * dev->unite_index / 4); + flag += (RKISP_ISP_SW_MAX_SIZE * dev->unite_index / 4); } if (*flag == SW_REG_CACHE) { diff --git a/drivers/media/platform/rockchip/isp/common.h b/drivers/media/platform/rockchip/isp/common.h index 8d4fd4649215..1c7d6a225616 100644 --- a/drivers/media/platform/rockchip/isp/common.h +++ b/drivers/media/platform/rockchip/isp/common.h @@ -174,16 +174,16 @@ u32 rkisp_read_reg_cache(struct rkisp_device *dev, u32 reg); void rkisp_set_reg_cache_bits(struct rkisp_device *dev, u32 reg, u32 mask, u32 val); void rkisp_clear_reg_cache_bits(struct rkisp_device *dev, u32 reg, u32 mask); -/* for dual isp, config for next isp reg */ -void rkisp_next_write(struct rkisp_device *dev, u32 reg, u32 val, bool is_direct); -u32 rkisp_next_read(struct rkisp_device *dev, u32 reg, bool is_direct); -void rkisp_next_set_bits(struct rkisp_device *dev, u32 reg, u32 mask, u32 val, bool is_direct); -void rkisp_next_clear_bits(struct rkisp_device *dev, u32 reg, u32 mask, bool is_direct); +/* for unite mode, config for diff isp reg */ +void rkisp_idx_write(struct rkisp_device *dev, u32 reg, u32 val, int idx, bool is_direct); +u32 rkisp_idx_read(struct rkisp_device *dev, u32 reg, int idx, bool is_direct); +void rkisp_idx_set_bits(struct rkisp_device *dev, u32 reg, u32 mask, u32 val, int idx, bool is_direct); +void rkisp_idx_clear_bits(struct rkisp_device *dev, u32 reg, u32 mask, int idx, bool is_direct); -void rkisp_next_write_reg_cache(struct rkisp_device *dev, u32 reg, u32 val); -u32 rkisp_next_read_reg_cache(struct rkisp_device *dev, u32 reg); -void rkisp_next_set_reg_cache_bits(struct rkisp_device *dev, u32 reg, u32 mask, u32 val); -void rkisp_next_clear_reg_cache_bits(struct rkisp_device *dev, u32 reg, u32 mask); +void rkisp_idx_write_reg_cache(struct rkisp_device *dev, u32 reg, u32 val, int idx); +u32 rkisp_idx_read_reg_cache(struct rkisp_device *dev, u32 reg, int idx); +void rkisp_idx_set_reg_cache_bits(struct rkisp_device *dev, u32 reg, u32 mask, u32 val, int idx); +void rkisp_idx_clear_reg_cache_bits(struct rkisp_device *dev, u32 reg, u32 mask, int idx); void rkisp_update_regs(struct rkisp_device *dev, u32 start, u32 end); diff --git a/drivers/media/platform/rockchip/isp/dev.c b/drivers/media/platform/rockchip/isp/dev.c index fd10c6898e8b..fe26b2befcb3 100644 --- a/drivers/media/platform/rockchip/isp/dev.c +++ b/drivers/media/platform/rockchip/isp/dev.c @@ -183,7 +183,7 @@ static int __isp_pipeline_s_isp_clk(struct rkisp_pipeline *p) struct v4l2_subdev *sd; struct v4l2_ctrl *ctrl; u64 data_rate = 0; - int i, fps; + int i, fps, size; hw_dev->isp_size[dev->dev_id].is_on = true; if (hw_dev->is_runing) { @@ -200,14 +200,16 @@ static int __isp_pipeline_s_isp_clk(struct rkisp_pipeline *p) fps = hw_dev->isp_size[i].fps; if (!fps) fps = 30; - data_rate += (fps * hw_dev->isp_size[i].size); + size = hw_dev->isp_size[i].size * hw_dev->isp[i]->unite_div; + data_rate += (fps * size); } } else { i = dev->dev_id; fps = hw_dev->isp_size[i].fps; if (!fps) fps = 30; - data_rate = fps * hw_dev->isp_size[i].size; + size = hw_dev->isp_size[i].size * dev->unite_div; + data_rate = fps * size; } goto end; } @@ -870,7 +872,7 @@ static int rkisp_plat_probe(struct platform_device *pdev) return ret; if (isp_dev->hw_dev->unite) - mult = 2; + mult = ISP_UNITE_MAX; isp_dev->sw_base_addr = devm_kzalloc(dev, RKISP_ISP_SW_MAX_SIZE * mult, GFP_KERNEL); if (!isp_dev->sw_base_addr) return -ENOMEM; diff --git a/drivers/media/platform/rockchip/isp/dev.h b/drivers/media/platform/rockchip/isp/dev.h index 3e6586428fb8..3fad153744df 100644 --- a/drivers/media/platform/rockchip/isp/dev.h +++ b/drivers/media/platform/rockchip/isp/dev.h @@ -114,13 +114,24 @@ enum { ISP_UNITE_ONE = 2, }; -/* left and right index - * ISP_UNITE_LEFT: left of image to isp process - * ISP_UNITE_RIGHT: right of image to isp process +/* image segmentation index + * ISP_UNITE_LEFT: left of image, or left top of image + * ISP_UNITE_RIGHT: right of image, or right top of image + * ISP_UNITE_LEFT_B: left bottom of image + * ISP_UNITE_RIGHT_B: right bottom of image */ enum { ISP_UNITE_LEFT = 0, - ISP_UNITE_RIGHT = 1, + ISP_UNITE_RIGHT, + ISP_UNITE_LEFT_B, + ISP_UNITE_RIGHT_B, + ISP_UNITE_MAX, +}; + +enum { + ISP_UNITE_DIV1 = 1, + ISP_UNITE_DIV2 = 2, + ISP_UNITE_DIV4 = 4, }; /* @@ -286,32 +297,36 @@ struct rkisp_device { u8 multi_index; u8 rawaf_irq_cnt; u8 unite_index; + u8 unite_div; }; static inline void rkisp_unite_write(struct rkisp_device *dev, u32 reg, u32 val, bool is_direct) { - rkisp_write(dev, reg, val, is_direct); - if (dev->hw_dev->unite) - rkisp_next_write(dev, reg, val, is_direct); + int i; + + for (i = 0; i < dev->unite_div; i++) + rkisp_idx_write(dev, reg, val, i, is_direct); } static inline void rkisp_unite_set_bits(struct rkisp_device *dev, u32 reg, u32 mask, u32 val, bool is_direct) { - rkisp_set_bits(dev, reg, mask, val, is_direct); - if (dev->hw_dev->unite) - rkisp_next_set_bits(dev, reg, mask, val, is_direct); + int i; + + for (i = 0; i < dev->unite_div; i++) + rkisp_idx_set_bits(dev, reg, mask, val, i, is_direct); } static inline void rkisp_unite_clear_bits(struct rkisp_device *dev, u32 reg, u32 mask, bool is_direct) { - rkisp_clear_bits(dev, reg, mask, is_direct); - if (dev->hw_dev->unite) - rkisp_next_clear_bits(dev, reg, mask, is_direct); + int i; + + for (i = 0; i < dev->unite_div; i++) + rkisp_idx_clear_bits(dev, reg, mask, i, is_direct); } static inline bool rkisp_link_sensor(u32 isp_inp) diff --git a/drivers/media/platform/rockchip/isp/dmarx.c b/drivers/media/platform/rockchip/isp/dmarx.c index 1f1c02806b4d..fbbb653d6b1b 100644 --- a/drivers/media/platform/rockchip/isp/dmarx.c +++ b/drivers/media/platform/rockchip/isp/dmarx.c @@ -365,6 +365,7 @@ static void update_rawrd(struct rkisp_stream *stream) struct rkisp_device *dev = stream->ispdev; void __iomem *base = dev->base_addr; struct capture_fmt *fmt = &stream->out_isp_fmt; + u32 offs, offs_h = stream->out_fmt.width / 2 - RKMOUDLE_UNITE_EXTEND_PIXEL; u32 val = 0; if (stream->curr_buf) { @@ -375,15 +376,22 @@ static void update_rawrd(struct rkisp_stream *stream) } val += stream->curr_buf->buff_addr[RKISP_PLANE_Y]; rkisp_write(dev, stream->config->mi.y_base_ad_init, val, false); - if (dev->hw_dev->unite) { - u32 offs = stream->out_fmt.width / 2 - RKMOUDLE_UNITE_EXTEND_PIXEL; - if (stream->memory) - offs *= DIV_ROUND_UP(fmt->bpp[0], 8); - else - offs = offs * fmt->bpp[0] / 8; - val += offs; - rkisp_next_write(dev, stream->config->mi.y_base_ad_init, val, false); + if (stream->memory) + offs_h *= DIV_ROUND_UP(fmt->bpp[0], 8); + else + offs_h = offs_h * fmt->bpp[0] / 8; + if (dev->unite_div > ISP_UNITE_DIV1) + rkisp_idx_write(dev, stream->config->mi.y_base_ad_init, + val + offs_h, ISP_UNITE_RIGHT, false); + if (dev->unite_div == ISP_UNITE_DIV4) { + offs = stream->out_fmt.plane_fmt[0].bytesperline * + (stream->out_fmt.height / 2 - RKMOUDLE_UNITE_EXTEND_PIXEL); + rkisp_idx_write(dev, stream->config->mi.y_base_ad_init, + val + offs, ISP_UNITE_LEFT_B, false); + offs += offs_h; + rkisp_idx_write(dev, stream->config->mi.y_base_ad_init, + val + offs, ISP_UNITE_RIGHT_B, false); } stream->frame_end = false; if (stream->id == RKISP_STREAM_RAWRD2 && stream->out_isp_fmt.fmt_type == FMT_YUV) { @@ -1131,21 +1139,27 @@ void rkisp_rawrd_set_pic_size(struct rkisp_device *dev, { struct rkisp_isp_subdev *sdev = &dev->isp_sdev; u8 mult = sdev->in_fmt.fmt_type == FMT_YUV ? 2 : 1; - bool is_unite = !!dev->hw_dev->unite; - u32 w = !is_unite ? width : width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + u32 w, h; /* rx height should equal to isp height + offset for read back mode */ height = sdev->in_crop.top + sdev->in_crop.height; + w = width; + h = height; + if (dev->unite_div > ISP_UNITE_DIV1) + w = width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + if (dev->unite_div == ISP_UNITE_DIV4) + h = height / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + /* isp20 extend line for normal read back mode to fix internal bug */ if (dev->isp_ver == ISP_V20 && sdev->in_fmt.fmt_type == FMT_BAYER && sdev->out_fmt.fmt_type != FMT_BAYER && dev->rd_mode == HDR_RDBK_FRAME1) - height += RKMODULE_EXTEND_LINE; + h += RKMODULE_EXTEND_LINE; w *= mult; - rkisp_unite_write(dev, CSI2RX_RAW_RD_PIC_SIZE, height << 16 | w, false); + rkisp_unite_write(dev, CSI2RX_RAW_RD_PIC_SIZE, h << 16 | w, false); } void rkisp_dmarx_get_frame(struct rkisp_device *dev, u32 *id, diff --git a/drivers/media/platform/rockchip/isp/hw.c b/drivers/media/platform/rockchip/isp/hw.c index 6457772f7b89..0cc37e546517 100644 --- a/drivers/media/platform/rockchip/isp/hw.c +++ b/drivers/media/platform/rockchip/isp/hw.c @@ -111,7 +111,7 @@ static void default_sw_reg_flag(struct rkisp_device *dev) ISP3X_RAWHIST_BIG1_BASE, ISP3X_RAWHIST_BIG2_BASE, ISP3X_RAWHIST_BIG3_BASE, ISP3X_RAWAF_CTRL, ISP3X_RAWAWB_CTRL, }; - u32 i, *flag, *reg, size; + u32 i, j, *flag, *reg, size; switch (dev->isp_ver) { case ISP_V20: @@ -138,7 +138,7 @@ static void default_sw_reg_flag(struct rkisp_device *dev) for (i = 0; i < size; i++) { flag = dev->sw_base_addr + reg[i] + RKISP_ISP_SW_REG_SIZE; *flag = SW_REG_CACHE; - if (dev->hw_dev->unite) { + for (j = 1; j < ISP_UNITE_MAX && dev->hw_dev->unite; j++) { flag += RKISP_ISP_SW_MAX_SIZE / 4; *flag = SW_REG_CACHE; } @@ -1311,8 +1311,10 @@ void rkisp_hw_enum_isp_size(struct rkisp_hw_dev *hw_dev) hw_dev->is_single = false; w = isp->isp_sdev.in_crop.width; h = isp->isp_sdev.in_crop.height; - if (hw_dev->unite) + if (isp->unite_div > ISP_UNITE_DIV1) w = w / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + if (isp->unite_div == ISP_UNITE_DIV4) + h = h / 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; @@ -1339,7 +1341,7 @@ static int __maybe_unused rkisp_runtime_resume(struct device *dev) void __iomem *base = hw_dev->base_addr; struct rkisp_device *isp; int mult = hw_dev->unite ? 2 : 1; - int ret, i; + int ret, i, j; void *buf; ret = pinctrl_pm_select_default_state(dev); @@ -1362,7 +1364,7 @@ static int __maybe_unused rkisp_runtime_resume(struct device *dev) buf = isp->sw_base_addr; memset(buf, 0, RKISP_ISP_SW_MAX_SIZE * mult); memcpy_fromio(buf, base, RKISP_ISP_SW_REG_SIZE); - if (hw_dev->unite) { + for (j = 1; j < ISP_UNITE_MAX && hw_dev->unite; j++) { buf += RKISP_ISP_SW_MAX_SIZE; base = hw_dev->base_next_addr; memcpy_fromio(buf, base, RKISP_ISP_SW_REG_SIZE); diff --git a/drivers/media/platform/rockchip/isp/isp_params.c b/drivers/media/platform/rockchip/isp/isp_params.c index 3c4379ef479b..47f563c6ad80 100644 --- a/drivers/media/platform/rockchip/isp/isp_params.c +++ b/drivers/media/platform/rockchip/isp/isp_params.c @@ -46,8 +46,7 @@ static int rkisp_params_g_fmt_meta_out(struct file *file, void *fh, memset(meta, 0, sizeof(*meta)); meta->dataformat = params_vdev->vdev_fmt.fmt.meta.dataformat; - meta->buffersize = params_vdev->vdev_fmt.fmt.meta.buffersize; - + params_vdev->ops->get_param_size(params_vdev, &meta->buffersize); return 0; } @@ -349,11 +348,7 @@ static int rkisp_init_params_vdev(struct rkisp_isp_params_vdev *params_vdev) else ret = rkisp_init_params_vdev_v32(params_vdev); - params_vdev->vdev_fmt.fmt.meta.dataformat = - V4L2_META_FMT_RK_ISP1_PARAMS; - if (params_vdev->ops && params_vdev->ops->get_param_size) - params_vdev->ops->get_param_size(params_vdev, - ¶ms_vdev->vdev_fmt.fmt.meta.buffersize); + params_vdev->vdev_fmt.fmt.meta.dataformat = V4L2_META_FMT_RK_ISP1_PARAMS; return ret; } diff --git a/drivers/media/platform/rockchip/isp/isp_params_v1x.c b/drivers/media/platform/rockchip/isp/isp_params_v1x.c index 4ca6c6dbbd2c..98972a15fe2d 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v1x.c +++ b/drivers/media/platform/rockchip/isp/isp_params_v1x.c @@ -2239,6 +2239,7 @@ static void rkisp1_get_param_size_v1x(struct rkisp_isp_params_vdev *params_vdev, unsigned int sizes[]) { sizes[0] = sizeof(struct rkisp1_isp_params_cfg); + params_vdev->vdev_fmt.fmt.meta.buffersize = sizes[0]; } /* Not called when the camera active, thus not isr protection. */ diff --git a/drivers/media/platform/rockchip/isp/isp_params_v21.c b/drivers/media/platform/rockchip/isp/isp_params_v21.c index c6f22d603754..f30b5434f7bd 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v21.c +++ b/drivers/media/platform/rockchip/isp/isp_params_v21.c @@ -4105,6 +4105,7 @@ rkisp_get_param_size_v2x(struct rkisp_isp_params_vdev *params_vdev, unsigned int sizes[]) { sizes[0] = sizeof(struct isp2x_isp_params_cfg); + params_vdev->vdev_fmt.fmt.meta.buffersize = sizes[0]; } static void @@ -4350,13 +4351,16 @@ int rkisp_init_params_vdev_v21(struct rkisp_isp_params_vdev *params_vdev) { struct device *dev = params_vdev->dev->dev; struct rkisp_isp_params_val_v21 *priv_val; - int i, ret; + int i, ret, size; priv_val = kzalloc(sizeof(*priv_val), GFP_KERNEL); if (!priv_val) return -ENOMEM; - params_vdev->isp21_params = vmalloc(sizeof(*params_vdev->isp21_params)); + size = sizeof(struct isp21_isp_params_cfg); + if (params_vdev->dev->hw_dev->unite) + size *= ISP_UNITE_MAX; + params_vdev->isp21_params = vmalloc(size); if (!params_vdev->isp21_params) { kfree(priv_val); return -ENOMEM; diff --git a/drivers/media/platform/rockchip/isp/isp_params_v2x.c b/drivers/media/platform/rockchip/isp/isp_params_v2x.c index c1497a92ffd1..e0154623813c 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v2x.c +++ b/drivers/media/platform/rockchip/isp/isp_params_v2x.c @@ -4196,6 +4196,7 @@ rkisp_get_param_size_v2x(struct rkisp_isp_params_vdev *params_vdev, unsigned int sizes[]) { sizes[0] = sizeof(struct isp2x_isp_params_cfg); + params_vdev->vdev_fmt.fmt.meta.buffersize = sizes[0]; } static void diff --git a/drivers/media/platform/rockchip/isp/isp_params_v32.c b/drivers/media/platform/rockchip/isp/isp_params_v32.c index ac46505c917d..d1b1b31640cb 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v32.c +++ b/drivers/media/platform/rockchip/isp/isp_params_v32.c @@ -49,10 +49,7 @@ static inline void isp3_param_write(struct rkisp_isp_params_vdev *params_vdev, u32 value, u32 addr, u32 id) { - if (id == ISP3_LEFT) - rkisp_write(params_vdev->dev, addr, value, false); - else - rkisp_next_write(params_vdev->dev, addr, value, false); + rkisp_idx_write(params_vdev->dev, addr, value, id, false); } static inline u32 @@ -64,45 +61,27 @@ isp3_param_read_direct(struct rkisp_isp_params_vdev *params_vdev, u32 addr) static inline u32 isp3_param_read(struct rkisp_isp_params_vdev *params_vdev, u32 addr, u32 id) { - u32 val; - - if (id == ISP3_LEFT) - val = rkisp_read(params_vdev->dev, addr, false); - else - val = rkisp_next_read(params_vdev->dev, addr, false); - return val; + return rkisp_idx_read(params_vdev->dev, addr, id, false); } static inline u32 isp3_param_read_cache(struct rkisp_isp_params_vdev *params_vdev, u32 addr, u32 id) { - u32 val; - - if (id == ISP3_LEFT) - val = rkisp_read_reg_cache(params_vdev->dev, addr); - else - val = rkisp_next_read_reg_cache(params_vdev->dev, addr); - return val; + return rkisp_idx_read_reg_cache(params_vdev->dev, addr, id); } static inline void isp3_param_set_bits(struct rkisp_isp_params_vdev *params_vdev, u32 reg, u32 bit_mask, u32 id) { - if (id == ISP3_LEFT) - rkisp_set_bits(params_vdev->dev, reg, 0, bit_mask, false); - else - rkisp_next_set_bits(params_vdev->dev, reg, 0, bit_mask, false); + rkisp_idx_set_bits(params_vdev->dev, reg, 0, bit_mask, id, false); } static inline void isp3_param_clear_bits(struct rkisp_isp_params_vdev *params_vdev, u32 reg, u32 bit_mask, u32 id) { - if (id == ISP3_LEFT) - rkisp_clear_bits(params_vdev->dev, reg, bit_mask, false); - else - rkisp_next_clear_bits(params_vdev->dev, reg, bit_mask, false); + rkisp_idx_clear_bits(params_vdev->dev, reg, bit_mask, id, false); } static void @@ -1107,8 +1086,10 @@ isp_rawaf_config(struct rkisp_isp_params_vdev *params_vdev, arg->num_afm_win); struct isp2x_window win_ae; - if (dev->hw_dev->unite) + if (dev->unite_div > ISP_UNITE_DIV1) width = width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + if (dev->unite_div == ISP_UNITE_DIV4) + height = height / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; for (i = 0; i < num_of_win; i++) { h_size = arg->win[i].h_size; @@ -1367,8 +1348,11 @@ isp_rawaelite_config(struct rkisp_isp_params_vdev *params_vdev, ISP_PACK_2SHORT(h_offs, v_offs), ISP3X_RAWAE_LITE_OFFSET, id); - if (ispdev->hw_dev->unite) + if (ispdev->unite_div > ISP_UNITE_DIV1) width = width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + if (ispdev->unite_div == ISP_UNITE_DIV4) + height = height / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + h_size = arg->win.h_size; v_size = arg->win.v_size; if (!h_size || h_size + h_offs + 1 > width) @@ -1462,8 +1446,10 @@ isp_rawaebig_config(struct rkisp_isp_params_vdev *params_vdev, ISP_PACK_2SHORT(h_offs, v_offs), addr + ISP3X_RAWAE_BIG_OFFSET, id); - if (ispdev->hw_dev->unite) + if (ispdev->unite_div > ISP_UNITE_DIV1) width = width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + if (ispdev->unite_div == ISP_UNITE_DIV4) + height = height / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; h_size = arg->win.h_size; v_size = arg->win.v_size; if (!h_size || h_size + h_offs + 1 > width) @@ -1655,15 +1641,17 @@ isp_rawawb_config(struct rkisp_isp_params_vdev *params_vdev, value |= !!arg->ds16x8_mode_en << 7; isp3_param_write(params_vdev, value, ISP3X_RAWAWB_BLK_CTRL, id); - h_offs = arg->h_offs & ~0x1; v_offs = arg->v_offs & ~0x1; isp3_param_write(params_vdev, ISP_PACK_2SHORT(h_offs, v_offs), ISP3X_RAWAWB_WIN_OFFS, id); - if (dev->hw_dev->unite) + if (dev->unite_div > ISP_UNITE_DIV1) width = width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + if (dev->unite_div == ISP_UNITE_DIV4) + height = height / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + h_size = arg->h_size; v_size = arg->v_size; if (!h_size || h_size + h_offs > width) @@ -2344,8 +2332,11 @@ isp_rawhstlite_config(struct rkisp_isp_params_vdev *params_vdev, ISP_PACK_2SHORT(h_offs, v_offs), ISP3X_RAWHIST_LITE_OFFS, id); - if (ispdev->hw_dev->unite) + if (ispdev->unite_div > ISP_UNITE_DIV1) width = width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + if (ispdev->unite_div == ISP_UNITE_DIV4) + height = height / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + h_size = arg->win.h_size; v_size = arg->win.v_size; if (!h_size || h_size + h_offs + 1 > width) @@ -2499,8 +2490,11 @@ isp_rawhstbig_config(struct rkisp_isp_params_vdev *params_vdev, ISP_PACK_2SHORT(h_offs, v_offs), addr + ISP3X_RAWHIST_BIG_OFFS, id); - if (dev->hw_dev->unite) + if (dev->unite_div > ISP_UNITE_DIV1) width = width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + if (dev->unite_div == ISP_UNITE_DIV4) + height = height / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + h_size = arg->win.h_size; v_size = arg->win.v_size; if (!h_size || h_size + h_offs + 1 > width) @@ -4411,7 +4405,7 @@ rkisp_alloc_internal_buf(struct rkisp_isp_params_vdev *params_vdev, module_en_update = new_params->module_en_update; module_ens = new_params->module_ens; - for (id = 0; id <= !!dev->hw_dev->unite; id++) { + for (id = 0; id < dev->unite_div; id++) { priv_val->buf_3dlut_idx[id] = 0; for (i = 0; i < ISP32_3DLUT_BUF_NUM; i++) { if (priv_val->buf_3dlut[id][i].mem_priv) @@ -4438,8 +4432,10 @@ rkisp_alloc_internal_buf(struct rkisp_isp_params_vdev *params_vdev, u32 val, wrap_line, wsize, div; bool is_alloc; - if (dev->hw_dev->unite) + if (dev->unite_div > ISP_UNITE_DIV1) w = ALIGN(isp_sdev->in_crop.width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL, 16); + if (dev->unite_div == ISP_UNITE_DIV4) + h = ALIGN(isp_sdev->in_crop.height / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL, 16); priv_val->is_lo8x8 = (!new_params->others.bay3d_cfg.lo4x8_en && !new_params->others.bay3d_cfg.lo4x4_en); @@ -4459,8 +4455,8 @@ rkisp_alloc_internal_buf(struct rkisp_isp_params_vdev *params_vdev, div = is_bwopt_dis ? 1 : 2; val = ALIGN(wsize * h / div, 16); priv_val->bay3d_iir_size = val; - if (dev->hw_dev->unite) - val *= 2; + if (dev->unite_div > ISP_UNITE_DIV1) + val *= dev->unite_div; is_alloc = true; if (priv_val->buf_3dnr_iir.mem_priv) { if (val > priv_val->buf_3dnr_iir.size) @@ -4482,8 +4478,8 @@ rkisp_alloc_internal_buf(struct rkisp_isp_params_vdev *params_vdev, /* pixel to Byte and align */ val = ALIGN(val * 2, 16); priv_val->bay3d_ds_size = val; - if (dev->hw_dev->unite) - val *= 2; + if (dev->unite_div > ISP_UNITE_DIV1) + val *= dev->unite_div; is_alloc = true; if (priv_val->buf_3dnr_ds.mem_priv) { if (val > priv_val->buf_3dnr_ds.size) @@ -4542,8 +4538,7 @@ rkisp_alloc_internal_buf(struct rkisp_isp_params_vdev *params_vdev, if (dev->isp_ver == ISP_V32_L) { if (dev->hw_dev->is_frm_buf && !priv_val->buf_frm.mem_priv) { priv_val->buf_frm.size = ISP32_LITE_FRM_BUF_SIZE; - if (dev->hw_dev->unite) - priv_val->buf_frm.size *= 2; + priv_val->buf_frm.size *= dev->unite_div; ret = rkisp_alloc_buffer(dev, &priv_val->buf_frm); if (ret) { dev_err(dev->dev, "alloc frm buf fail:%d\n", ret); @@ -4573,7 +4568,7 @@ free_3dnr: rkisp_free_buffer(dev, &priv_val->buf_3dnr_iir); rkisp_free_buffer(dev, &priv_val->buf_3dnr_ds); err_3dnr: - id = dev->hw_dev->unite ? 1 : 0; + id = dev->unite_div - 1; i = ISP32_3DLUT_BUF_NUM; err_3dlut: for (; id >= 0; id--) { @@ -4598,6 +4593,8 @@ rkisp_params_check_bigmode_v32_lite(struct rkisp_isp_params_vdev *params_vdev) int i = 0, j = 0; bool is_bigmode = false; + if (hw->unite == ISP_UNITE_ONE) + hw->is_frm_buf = true; using_frm_buf: if (hw->is_frm_buf) { ispdev->multi_index = 0; @@ -4941,15 +4938,14 @@ static void rkisp_params_first_cfg_v32(struct rkisp_isp_params_vdev *params_vdev) { struct rkisp_device *dev = params_vdev->dev; - struct rkisp_hw_dev *hw = dev->hw_dev; - struct rkisp_isp_params_val_v32 *priv_val = - (struct rkisp_isp_params_val_v32 *)params_vdev->priv_val; + struct rkisp_isp_params_val_v32 *priv_val = params_vdev->priv_val; + struct isp32_isp_params_cfg *params = params_vdev->isp32_params; + int i; rkisp_params_check_bigmode_v32(params_vdev); spin_lock(¶ms_vdev->config_lock); /* override the default things */ - if (!params_vdev->isp32_params->module_cfg_update && - !params_vdev->isp32_params->module_en_update) + if (!params->module_cfg_update && !params->module_en_update) dev_warn(dev->dev, "can not get first iq setting in stream on\n"); priv_val->bay3d_en = 0; @@ -4958,39 +4954,28 @@ rkisp_params_first_cfg_v32(struct rkisp_isp_params_vdev *params_vdev) priv_val->lsc_en = 0; priv_val->mge_en = 0; priv_val->lut3d_en = 0; - if (hw->unite) { - if (dev->is_bigmode) - rkisp_next_set_bits(dev, ISP3X_ISP_CTRL1, 0, - ISP3X_BIGMODE_MANUAL | ISP3X_BIGMODE_FORCE_EN, false); - __isp_isr_meas_config(params_vdev, params_vdev->isp32_params + 1, RKISP_PARAMS_ALL, 1); - __isp_isr_other_config(params_vdev, params_vdev->isp32_params + 1, RKISP_PARAMS_ALL, 1); - __isp_isr_other_en(params_vdev, params_vdev->isp32_params + 1, RKISP_PARAMS_ALL, 1); - __isp_isr_meas_en(params_vdev, params_vdev->isp32_params + 1, RKISP_PARAMS_ALL, 1); - } if (dev->is_bigmode) - rkisp_set_bits(dev, ISP3X_ISP_CTRL1, 0, - ISP3X_BIGMODE_MANUAL | ISP3X_BIGMODE_FORCE_EN, false); - - __isp_isr_meas_config(params_vdev, params_vdev->isp32_params, RKISP_PARAMS_ALL, 0); - __isp_isr_other_config(params_vdev, params_vdev->isp32_params, RKISP_PARAMS_ALL, 0); - __isp_isr_other_en(params_vdev, params_vdev->isp32_params, RKISP_PARAMS_ALL, 0); - __isp_isr_meas_en(params_vdev, params_vdev->isp32_params, RKISP_PARAMS_ALL, 0); - + rkisp_unite_set_bits(dev, ISP3X_ISP_CTRL1, 0, + ISP3X_BIGMODE_MANUAL | ISP3X_BIGMODE_FORCE_EN, false); + for (i = 0; i < dev->unite_div; i++) { + __isp_isr_meas_config(params_vdev, params + i, RKISP_PARAMS_ALL, i); + __isp_isr_other_config(params_vdev, params + i, RKISP_PARAMS_ALL, i); + __isp_isr_other_en(params_vdev, params + i, RKISP_PARAMS_ALL, i); + __isp_isr_meas_en(params_vdev, params + i, RKISP_PARAMS_ALL, i); + } spin_unlock(¶ms_vdev->config_lock); if (dev->hw_dev->is_frm_buf && priv_val->buf_frm.mem_priv) { u32 size = priv_val->buf_frm.size; u32 addr = priv_val->buf_frm.dma_addr; - if (hw->unite) { - size /= 2; - isp3_param_write(params_vdev, size, ISP32L_FRM_BUF_WR_SIZE, 1); - isp3_param_write(params_vdev, addr + size, ISP32L_FRM_BUF_WR_BASE, 1); - isp3_param_write(params_vdev, addr + size, ISP32L_FRM_BUF_RD_BASE, 1); + if (dev->unite_div) + size /= dev->unite_div; + for (i = 0; i < dev->unite_div; i++) { + isp3_param_write(params_vdev, size, ISP32L_FRM_BUF_WR_SIZE, i); + isp3_param_write(params_vdev, addr + size * i, ISP32L_FRM_BUF_WR_BASE, i); + isp3_param_write(params_vdev, addr + size * i, ISP32L_FRM_BUF_RD_BASE, i); } - isp3_param_write(params_vdev, size, ISP32L_FRM_BUF_WR_SIZE, 0); - isp3_param_write(params_vdev, addr, ISP32L_FRM_BUF_WR_BASE, 0); - isp3_param_write(params_vdev, addr, ISP32L_FRM_BUF_RD_BASE, 0); } if (dev->hw_dev->is_single && (dev->isp_state & ISP_START)) rkisp_set_bits(dev, ISP3X_ISP_CTRL0, 0, CIF_ISP_CTRL_ISP_CFG_UPD, true); @@ -5004,10 +4989,9 @@ static void rkisp_save_first_param_v32(struct rkisp_isp_params_vdev *params_vdev static void rkisp_clear_first_param_v32(struct rkisp_isp_params_vdev *params_vdev) { - u32 size = sizeof(struct isp32_isp_params_cfg); + u32 mult = params_vdev->dev->hw_dev->unite ? ISP_UNITE_MAX : 1; + u32 size = sizeof(struct isp32_isp_params_cfg) * mult; - if (params_vdev->dev->hw_dev->unite) - size *= 2; memset(params_vdev->isp32_params, 0, size); } @@ -5117,9 +5101,10 @@ static void rkisp_get_param_size_v32(struct rkisp_isp_params_vdev *params_vdev, unsigned int sizes[]) { - u32 mult = params_vdev->dev->hw_dev->unite ? 2 : 1; + u32 mult = params_vdev->dev->unite_div; sizes[0] = sizeof(struct isp32_isp_params_cfg) * mult; + params_vdev->vdev_fmt.fmt.meta.buffersize = sizes[0]; } static void @@ -5173,7 +5158,7 @@ rkisp_params_free_meshbuf_v32(struct rkisp_isp_params_vdev *params_vdev, { int id; - for (id = 0; id <= !!params_vdev->dev->hw_dev->unite; id++) + for (id = 0; id < params_vdev->dev->unite_div; id++) rkisp_deinit_mesh_buf(params_vdev, module_id, id); } @@ -5332,7 +5317,7 @@ rkisp_params_stream_stop_v32(struct rkisp_isp_params_vdev *params_vdev) rkisp_free_buffer(ispdev, &priv_val->buf_lsclut[i]); for (i = 0; i < RKISP_STATS_DDR_BUF_NUM; i++) rkisp_free_buffer(ispdev, &ispdev->stats_vdev.stats_buf[i]); - for (id = 0; id <= !!ispdev->hw_dev->unite; id++) { + for (id = 0; id < ispdev->unite_div; id++) { for (i = 0; i < ISP32_3DLUT_BUF_NUM; i++) rkisp_free_buffer(ispdev, &priv_val->buf_3dlut[id][i]); } @@ -5348,7 +5333,7 @@ rkisp_params_fop_release_v32(struct rkisp_isp_params_vdev *params_vdev) { int id; - for (id = 0; id <= !!params_vdev->dev->hw_dev->unite; id++) { + for (id = 0; id < params_vdev->dev->unite_div; id++) { rkisp_deinit_mesh_buf(params_vdev, ISP32_MODULE_LDCH, id); rkisp_deinit_mesh_buf(params_vdev, ISP32_MODULE_CAC, id); } @@ -5358,14 +5343,14 @@ rkisp_params_fop_release_v32(struct rkisp_isp_params_vdev *params_vdev) static void rkisp_params_disable_isp_v32(struct rkisp_isp_params_vdev *params_vdev) { + int i; + params_vdev->isp32_params->module_ens = 0; params_vdev->isp32_params->module_en_update = 0x7ffffffffff; - __isp_isr_other_en(params_vdev, params_vdev->isp32_params, RKISP_PARAMS_ALL, 0); - __isp_isr_meas_en(params_vdev, params_vdev->isp32_params, RKISP_PARAMS_ALL, 0); - if (params_vdev->dev->hw_dev->unite) { - __isp_isr_other_en(params_vdev, params_vdev->isp32_params, RKISP_PARAMS_ALL, 1); - __isp_isr_meas_en(params_vdev, params_vdev->isp32_params, RKISP_PARAMS_ALL, 1); + for (i = 0; i < params_vdev->dev->unite_div; i++) { + __isp_isr_other_en(params_vdev, params_vdev->isp32_params, RKISP_PARAMS_ALL, i); + __isp_isr_meas_en(params_vdev, params_vdev->isp32_params, RKISP_PARAMS_ALL, i); } } @@ -5409,9 +5394,10 @@ static void rkisp_params_cfg_v32(struct rkisp_isp_params_vdev *params_vdev, u32 frame_id, enum rkisp_params_type type) { - struct rkisp_hw_dev *hw = params_vdev->dev->hw_dev; + struct rkisp_device *dev = params_vdev->dev; struct isp32_isp_params_cfg *new_params = NULL; struct rkisp_buffer *cur_buf = params_vdev->cur_buf; + int i; spin_lock(¶ms_vdev->config_lock); if (!params_vdev->streamon) @@ -5427,30 +5413,24 @@ rkisp_params_cfg_v32(struct rkisp_isp_params_vdev *params_vdev, list_del(&cur_buf->queue); if (list_empty(¶ms_vdev->params)) break; - else if (new_params->module_en_update || - (new_params->module_cfg_update & ISP32_MODULE_FORCE)) { + for (i = 0; i < dev->unite_div; i++) { /* update en immediately */ - __isp_isr_meas_config(params_vdev, new_params, RKISP_PARAMS_ALL, 0); - __isp_isr_other_config(params_vdev, new_params, RKISP_PARAMS_ALL, 0); - __isp_isr_other_en(params_vdev, new_params, RKISP_PARAMS_ALL, 0); - __isp_isr_meas_en(params_vdev, new_params, RKISP_PARAMS_ALL, 0); - new_params->module_cfg_update = 0; - if (hw->unite) { - struct isp32_isp_params_cfg *params = new_params + 1; - - __isp_isr_meas_config(params_vdev, params, RKISP_PARAMS_ALL, 1); - __isp_isr_other_config(params_vdev, params, RKISP_PARAMS_ALL, 1); - __isp_isr_other_en(params_vdev, params, RKISP_PARAMS_ALL, 1); - __isp_isr_meas_en(params_vdev, params, RKISP_PARAMS_ALL, 1); - params->module_cfg_update = 0; + if (new_params->module_en_update || + (new_params->module_cfg_update & ISP32_MODULE_FORCE)) { + __isp_isr_meas_config(params_vdev, + new_params, RKISP_PARAMS_ALL, i); + __isp_isr_other_config(params_vdev, + new_params, RKISP_PARAMS_ALL, i); + __isp_isr_other_en(params_vdev, + new_params, RKISP_PARAMS_ALL, i); + __isp_isr_meas_en(params_vdev, + new_params, RKISP_PARAMS_ALL, i); + new_params->module_cfg_update = 0; } - } - if (new_params->module_cfg_update & - (ISP32_MODULE_LDCH | ISP32_MODULE_CAC)) { - module_data_abandon(params_vdev, new_params, 0); - if (hw->unite) - module_data_abandon(params_vdev, new_params, 1); - + if (new_params->module_cfg_update & + (ISP32_MODULE_LDCH | ISP32_MODULE_CAC)) + module_data_abandon(params_vdev, new_params, i); + new_params++; } vb2_buffer_done(&cur_buf->vb.vb2_buf, VB2_BUF_STATE_DONE); cur_buf = NULL; @@ -5467,21 +5447,16 @@ rkisp_params_cfg_v32(struct rkisp_isp_params_vdev *params_vdev, goto unlock; new_params = (struct isp32_isp_params_cfg *)(cur_buf->vaddr[0]); - if (hw->unite) { - __isp_isr_meas_config(params_vdev, new_params + 1, type, 1); - __isp_isr_other_config(params_vdev, new_params + 1, type, 1); - __isp_isr_other_en(params_vdev, new_params + 1, type, 1); - __isp_isr_meas_en(params_vdev, new_params + 1, type, 1); + for (i = 0; i < dev->unite_div; i++) { + __isp_isr_meas_config(params_vdev, new_params, type, i); + __isp_isr_other_config(params_vdev, new_params, type, i); + __isp_isr_other_en(params_vdev, new_params, type, i); + __isp_isr_meas_en(params_vdev, new_params, type, i); + if (type != RKISP_PARAMS_IMD) + new_params->module_cfg_update = 0; + new_params++; } - __isp_isr_meas_config(params_vdev, new_params, type, 0); - __isp_isr_other_config(params_vdev, new_params, type, 0); - __isp_isr_other_en(params_vdev, new_params, type, 0); - __isp_isr_meas_en(params_vdev, new_params, type, 0); - if (type != RKISP_PARAMS_IMD) { - new_params->module_cfg_update = 0; - if (hw->unite) - (new_params++)->module_cfg_update = 0; vb2_buffer_done(&cur_buf->vb.vb2_buf, VB2_BUF_STATE_DONE); cur_buf = NULL; } @@ -5495,15 +5470,13 @@ static void rkisp_params_clear_fstflg(struct rkisp_isp_params_vdev *params_vdev) { u32 value = isp3_param_read(params_vdev, ISP3X_ISP_CTRL1, 0); + int i; value &= (ISP3X_YNR_FST_FRAME | ISP3X_ADRC_FST_FRAME | ISP3X_DHAZ_FST_FRAME | ISP3X_CNR_FST_FRAME | ISP3X_RAW3D_FST_FRAME | ISP32_SHP_FST_FRAME); - if (value) { - isp3_param_clear_bits(params_vdev, ISP3X_ISP_CTRL1, value, 0); - if (params_vdev->dev->hw_dev->unite) - isp3_param_clear_bits(params_vdev, ISP3X_ISP_CTRL1, value, 1); - } + for (i = 0; i < params_vdev->dev->unite_div && value; i++) + isp3_param_clear_bits(params_vdev, ISP3X_ISP_CTRL1, value, i); } static void @@ -5563,7 +5536,7 @@ int rkisp_init_params_vdev_v32(struct rkisp_isp_params_vdev *params_vdev) size = sizeof(struct isp32_isp_params_cfg); if (params_vdev->dev->hw_dev->unite) - size *= 2; + size *= ISP_UNITE_MAX; params_vdev->isp32_params = vmalloc(size); if (!params_vdev->isp32_params) { kfree(priv_val); diff --git a/drivers/media/platform/rockchip/isp/isp_params_v32.h b/drivers/media/platform/rockchip/isp/isp_params_v32.h index e1d91488d177..62c89ef9c1db 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v32.h +++ b/drivers/media/platform/rockchip/isp/isp_params_v32.h @@ -175,14 +175,14 @@ struct rkisp_isp_params_ops_v32 { struct rkisp_isp_params_val_v32 { struct tasklet_struct lsc_tasklet; - struct rkisp_dummy_buffer buf_3dlut[ISP3_UNITE_MAX][ISP32_3DLUT_BUF_NUM]; - u32 buf_3dlut_idx[ISP3_UNITE_MAX]; + struct rkisp_dummy_buffer buf_3dlut[ISP_UNITE_MAX][ISP32_3DLUT_BUF_NUM]; + u32 buf_3dlut_idx[ISP_UNITE_MAX]; - struct rkisp_dummy_buffer buf_ldch[ISP3_UNITE_MAX][ISP3X_MESH_BUF_NUM]; - u32 buf_ldch_idx[ISP3_UNITE_MAX]; + struct rkisp_dummy_buffer buf_ldch[ISP_UNITE_MAX][ISP3X_MESH_BUF_NUM]; + u32 buf_ldch_idx[ISP_UNITE_MAX]; - struct rkisp_dummy_buffer buf_cac[ISP3_UNITE_MAX][ISP3X_MESH_BUF_NUM]; - u32 buf_cac_idx[ISP3_UNITE_MAX]; + struct rkisp_dummy_buffer buf_cac[ISP_UNITE_MAX][ISP3X_MESH_BUF_NUM]; + u32 buf_cac_idx[ISP_UNITE_MAX]; struct rkisp_dummy_buffer buf_lsclut[ISP32_LSC_LUT_BUF_NUM]; u32 buf_lsclut_idx; diff --git a/drivers/media/platform/rockchip/isp/isp_params_v3x.c b/drivers/media/platform/rockchip/isp/isp_params_v3x.c index 96333d4e72a0..613fdc00d02d 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v3x.c +++ b/drivers/media/platform/rockchip/isp/isp_params_v3x.c @@ -28,79 +28,49 @@ static inline void isp3_param_write_direct(struct rkisp_isp_params_vdev *params_vdev, u32 value, u32 addr, u32 id) { - if (id == ISP3_LEFT) - rkisp_write(params_vdev->dev, addr, value, true); - else - rkisp_next_write(params_vdev->dev, addr, value, true); + rkisp_idx_write(params_vdev->dev, addr, value, id, true); } static inline void isp3_param_write(struct rkisp_isp_params_vdev *params_vdev, u32 value, u32 addr, u32 id) { - if (id == ISP3_LEFT) - rkisp_write(params_vdev->dev, addr, value, false); - else - rkisp_next_write(params_vdev->dev, addr, value, false); + rkisp_idx_write(params_vdev->dev, addr, value, id, false); } static inline u32 isp3_param_read_direct(struct rkisp_isp_params_vdev *params_vdev, u32 addr, u32 id) { - u32 val; - - if (id == ISP3_LEFT) - val = rkisp_read(params_vdev->dev, addr, true); - else - val = rkisp_next_read(params_vdev->dev, addr, true); - return val; + return rkisp_idx_read(params_vdev->dev, addr, id, true); } static inline u32 isp3_param_read(struct rkisp_isp_params_vdev *params_vdev, u32 addr, u32 id) { - u32 val; - - if (id == ISP3_LEFT) - val = rkisp_read(params_vdev->dev, addr, false); - else - val = rkisp_next_read(params_vdev->dev, addr, false); - return val; + return rkisp_idx_read(params_vdev->dev, addr, id, false); } static inline u32 isp3_param_read_cache(struct rkisp_isp_params_vdev *params_vdev, u32 addr, u32 id) { - u32 val; - - if (id == ISP3_LEFT) - val = rkisp_read_reg_cache(params_vdev->dev, addr); - else - val = rkisp_next_read_reg_cache(params_vdev->dev, addr); - return val; + return rkisp_idx_read_reg_cache(params_vdev->dev, addr, id); } static inline void isp3_param_set_bits(struct rkisp_isp_params_vdev *params_vdev, u32 reg, u32 bit_mask, u32 id) { - if (id == ISP3_LEFT) - rkisp_set_bits(params_vdev->dev, reg, 0, bit_mask, false); - else - rkisp_next_set_bits(params_vdev->dev, reg, 0, bit_mask, false); + rkisp_idx_set_bits(params_vdev->dev, reg, 0, bit_mask, id, false); } static inline void isp3_param_clear_bits(struct rkisp_isp_params_vdev *params_vdev, u32 reg, u32 bit_mask, u32 id) { - if (id == ISP3_LEFT) - rkisp_clear_bits(params_vdev->dev, reg, bit_mask, false); - else - rkisp_next_clear_bits(params_vdev->dev, reg, bit_mask, false); + rkisp_idx_clear_bits(params_vdev->dev, reg, bit_mask, id, false); } static void @@ -3531,19 +3501,19 @@ isp_bay3d_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) return; } - value = priv_val->buf_3dnr_iir.size; + value = priv_val->bay3d_iir_size; isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_IIR_WR_SIZE, id); value = priv_val->buf_3dnr_iir.dma_addr + value * id; isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_IIR_WR_BASE, id); isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_IIR_RD_BASE, id); - value = priv_val->buf_3dnr_cur.size; + value = priv_val->bay3d_iir_size; isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_CUR_WR_SIZE, id); value = priv_val->buf_3dnr_cur.dma_addr + value * id; isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_CUR_WR_BASE, id); isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_CUR_RD_BASE, id); - value = priv_val->buf_3dnr_ds.size; + value = priv_val->bay3d_ds_size; isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_DS_WR_SIZE, id); value = priv_val->buf_3dnr_ds.dma_addr + value * id; isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_DS_WR_BASE, id); @@ -4166,6 +4136,7 @@ rkisp_alloc_internal_buf(struct rkisp_isp_params_vdev *params_vdev, size = ALIGN((w + w / 8) * h * 2, 16); + priv_val->bay3d_iir_size = size; if (ispdev->hw_dev->unite) size *= 2; priv_val->buf_3dnr_iir.size = size; @@ -4183,6 +4154,7 @@ rkisp_alloc_internal_buf(struct rkisp_isp_params_vdev *params_vdev, } size = 2 * ALIGN(w * h / 64, 16); + priv_val->bay3d_ds_size = size; if (ispdev->hw_dev->unite) size *= 2; priv_val->buf_3dnr_ds.size = size; @@ -4423,15 +4395,14 @@ static void rkisp_params_first_cfg_v3x(struct rkisp_isp_params_vdev *params_vdev) { struct rkisp_device *dev = params_vdev->dev; - struct rkisp_isp_params_val_v3x *priv_val = - (struct rkisp_isp_params_val_v3x *)params_vdev->priv_val; - struct rkisp_hw_dev *hw = params_vdev->dev->hw_dev; + struct rkisp_isp_params_val_v3x *priv_val = params_vdev->priv_val; + struct isp3x_isp_params_cfg *params = params_vdev->isp3x_params; + int i; dev->is_bigmode = rkisp_params_check_bigmode_v3x(params_vdev); spin_lock(¶ms_vdev->config_lock); /* override the default things */ - if (!params_vdev->isp3x_params->module_cfg_update && - !params_vdev->isp3x_params->module_en_update) + if (!params->module_cfg_update && !params->module_en_update) dev_warn(dev->dev, "can not get first iq setting in stream on\n"); priv_val->bay3d_en = 0; @@ -4440,22 +4411,15 @@ rkisp_params_first_cfg_v3x(struct rkisp_isp_params_vdev *params_vdev) priv_val->lsc_en = 0; priv_val->mge_en = 0; priv_val->lut3d_en = 0; - if (hw->unite) { - if (dev->is_bigmode) - rkisp_next_set_bits(params_vdev->dev, ISP3X_ISP_CTRL1, 0, - ISP3X_BIGMODE_MANUAL | ISP3X_BIGMODE_FORCE_EN, false); - __isp_isr_meas_config(params_vdev, params_vdev->isp3x_params + 1, RKISP_PARAMS_ALL, 1); - __isp_isr_other_config(params_vdev, params_vdev->isp3x_params + 1, RKISP_PARAMS_ALL, 1); - __isp_isr_other_en(params_vdev, params_vdev->isp3x_params + 1, RKISP_PARAMS_ALL, 1); - __isp_isr_meas_en(params_vdev, params_vdev->isp3x_params + 1, RKISP_PARAMS_ALL, 1); - } if (dev->is_bigmode) - rkisp_set_bits(params_vdev->dev, ISP3X_ISP_CTRL1, 0, - ISP3X_BIGMODE_MANUAL | ISP3X_BIGMODE_FORCE_EN, false); - __isp_isr_meas_config(params_vdev, params_vdev->isp3x_params, RKISP_PARAMS_ALL, 0); - __isp_isr_other_config(params_vdev, params_vdev->isp3x_params, RKISP_PARAMS_ALL, 0); - __isp_isr_other_en(params_vdev, params_vdev->isp3x_params, RKISP_PARAMS_ALL, 0); - __isp_isr_meas_en(params_vdev, params_vdev->isp3x_params, RKISP_PARAMS_ALL, 0); + rkisp_unite_set_bits(dev, ISP3X_ISP_CTRL1, 0, + ISP3X_BIGMODE_MANUAL | ISP3X_BIGMODE_FORCE_EN, false); + for (i = 0; i < dev->unite_div; i++) { + __isp_isr_meas_config(params_vdev, params + i, RKISP_PARAMS_ALL, i); + __isp_isr_other_config(params_vdev, params + i, RKISP_PARAMS_ALL, i); + __isp_isr_other_en(params_vdev, params + i, RKISP_PARAMS_ALL, i); + __isp_isr_meas_en(params_vdev, params + i, RKISP_PARAMS_ALL, i); + } spin_unlock(¶ms_vdev->config_lock); } @@ -4471,7 +4435,7 @@ static void rkisp_save_first_param_v3x(struct rkisp_isp_params_vdev *params_vdev static void rkisp_clear_first_param_v3x(struct rkisp_isp_params_vdev *params_vdev) { - u32 mult = params_vdev->dev->hw_dev->unite ? ISP3_UNITE_MAX : 1; + u32 mult = params_vdev->dev->hw_dev->unite ? ISP_UNITE_MAX : 1; u32 size = sizeof(struct isp3x_isp_params_cfg) * mult; memset(params_vdev->isp3x_params, 0, size); @@ -4570,9 +4534,10 @@ static void rkisp_get_param_size_v3x(struct rkisp_isp_params_vdev *params_vdev, unsigned int sizes[]) { - u32 mult = params_vdev->dev->hw_dev->unite ? ISP3_UNITE_MAX : 1; + u32 mult = params_vdev->dev->unite_div; sizes[0] = sizeof(struct isp3x_isp_params_cfg) * mult; + params_vdev->vdev_fmt.fmt.meta.buffersize = sizes[0]; } static void @@ -4803,43 +4768,14 @@ static void rkisp_params_clear_fstflg(struct rkisp_isp_params_vdev *params_vdev) { struct rkisp_device *dev = params_vdev->dev; - struct rkisp_hw_dev *hw_dev = dev->hw_dev; - u32 value; + u32 value, i; value = rkisp_read(dev, ISP3X_ISP_CTRL1, false); - if (value & ISP3X_YNR_FST_FRAME) - rkisp_clear_bits(params_vdev->dev, ISP3X_ISP_CTRL1, - ISP3X_YNR_FST_FRAME, false); - if (value & ISP3X_ADRC_FST_FRAME) - rkisp_clear_bits(params_vdev->dev, ISP3X_ISP_CTRL1, - ISP3X_ADRC_FST_FRAME, false); - if (value & ISP3X_DHAZ_FST_FRAME) - rkisp_clear_bits(params_vdev->dev, ISP3X_ISP_CTRL1, - ISP3X_DHAZ_FST_FRAME, false); - if (value & ISP3X_CNR_FST_FRAME) - rkisp_clear_bits(params_vdev->dev, ISP3X_ISP_CTRL1, - ISP3X_CNR_FST_FRAME, false); - if (value & ISP3X_RAW3D_FST_FRAME) - rkisp_clear_bits(params_vdev->dev, ISP3X_ISP_CTRL1, - ISP3X_RAW3D_FST_FRAME, false); - if (hw_dev->unite) { - value = rkisp_next_read(dev, ISP3X_ISP_CTRL1, false); - if (value & ISP3X_YNR_FST_FRAME) - rkisp_next_clear_bits(params_vdev->dev, ISP3X_ISP_CTRL1, - ISP3X_YNR_FST_FRAME, false); - if (value & ISP3X_ADRC_FST_FRAME) - rkisp_next_clear_bits(params_vdev->dev, ISP3X_ISP_CTRL1, - ISP3X_ADRC_FST_FRAME, false); - if (value & ISP3X_DHAZ_FST_FRAME) - rkisp_next_clear_bits(params_vdev->dev, ISP3X_ISP_CTRL1, - ISP3X_DHAZ_FST_FRAME, false); - if (value & ISP3X_CNR_FST_FRAME) - rkisp_next_clear_bits(params_vdev->dev, ISP3X_ISP_CTRL1, - ISP3X_CNR_FST_FRAME, false); - if (value & ISP3X_RAW3D_FST_FRAME) - rkisp_next_clear_bits(params_vdev->dev, ISP3X_ISP_CTRL1, - ISP3X_RAW3D_FST_FRAME, false); - } + value &= ISP3X_YNR_FST_FRAME | ISP3X_ADRC_FST_FRAME | + ISP3X_DHAZ_FST_FRAME | ISP3X_CNR_FST_FRAME | + ISP3X_RAW3D_FST_FRAME; + for (i = 0; i < dev->unite_div && value; i++) + rkisp_idx_clear_bits(dev, ISP3X_ISP_CTRL1, value, i, false); } static void @@ -4899,7 +4835,7 @@ int rkisp_init_params_vdev_v3x(struct rkisp_isp_params_vdev *params_vdev) size = sizeof(struct isp3x_isp_params_cfg); if (ispdev->hw_dev->unite) - size *= 2; + size *= ISP_UNITE_MAX; params_vdev->isp3x_params = vmalloc(size); if (!params_vdev->isp3x_params) { kfree(priv_val); diff --git a/drivers/media/platform/rockchip/isp/isp_params_v3x.h b/drivers/media/platform/rockchip/isp/isp_params_v3x.h index b7bc923521c8..4d0a75ce312a 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v3x.h +++ b/drivers/media/platform/rockchip/isp/isp_params_v3x.h @@ -171,21 +171,23 @@ struct rkisp_isp_params_ops_v3x { struct rkisp_isp_params_val_v3x { struct tasklet_struct lsc_tasklet; - struct rkisp_dummy_buffer buf_3dlut[ISP3_UNITE_MAX][ISP3X_3DLUT_BUF_NUM]; - u32 buf_3dlut_idx[ISP3_UNITE_MAX]; + struct rkisp_dummy_buffer buf_3dlut[ISP_UNITE_MAX][ISP3X_3DLUT_BUF_NUM]; + u32 buf_3dlut_idx[ISP_UNITE_MAX]; - struct rkisp_dummy_buffer buf_ldch[ISP3_UNITE_MAX][ISP3X_MESH_BUF_NUM]; - u32 buf_ldch_idx[ISP3_UNITE_MAX]; + struct rkisp_dummy_buffer buf_ldch[ISP_UNITE_MAX][ISP3X_MESH_BUF_NUM]; + u32 buf_ldch_idx[ISP_UNITE_MAX]; - struct rkisp_dummy_buffer buf_lsclut[ISP3_UNITE_MAX][ISP3X_LSC_LUT_BUF_NUM]; - u32 buf_lsclut_idx[ISP3_UNITE_MAX]; + struct rkisp_dummy_buffer buf_lsclut[ISP_UNITE_MAX][ISP3X_LSC_LUT_BUF_NUM]; + u32 buf_lsclut_idx[ISP_UNITE_MAX]; - struct rkisp_dummy_buffer buf_cac[ISP3_UNITE_MAX][ISP3X_MESH_BUF_NUM]; - u32 buf_cac_idx[ISP3_UNITE_MAX]; + struct rkisp_dummy_buffer buf_cac[ISP_UNITE_MAX][ISP3X_MESH_BUF_NUM]; + u32 buf_cac_idx[ISP_UNITE_MAX]; struct rkisp_dummy_buffer buf_3dnr_iir; struct rkisp_dummy_buffer buf_3dnr_cur; struct rkisp_dummy_buffer buf_3dnr_ds; + u32 bay3d_ds_size; + u32 bay3d_iir_size; bool dhaz_en; bool drc_en; diff --git a/drivers/media/platform/rockchip/isp/isp_stats.c b/drivers/media/platform/rockchip/isp/isp_stats.c index 5c223ae5045b..fe6805a7dd8b 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats.c +++ b/drivers/media/platform/rockchip/isp/isp_stats.c @@ -44,7 +44,7 @@ static int rkisp_stats_g_fmt_meta_cap(struct file *file, void *priv, memset(meta, 0, sizeof(*meta)); meta->dataformat = stats_vdev->vdev_fmt.fmt.meta.dataformat; - meta->buffersize = stats_vdev->vdev_fmt.fmt.meta.buffersize; + stats_vdev->ops->get_stat_size(stats_vdev, &meta->buffersize); return 0; } @@ -132,8 +132,7 @@ static int rkisp_stats_vb2_queue_setup(struct vb2_queue *vq, *num_buffers = clamp_t(u32, *num_buffers, RKISP_ISP_STATS_REQ_BUFS_MIN, RKISP_ISP_STATS_REQ_BUFS_MAX); - - sizes[0] = stats_vdev->vdev_fmt.fmt.meta.buffersize; + stats_vdev->ops->get_stat_size(stats_vdev, sizes); INIT_LIST_HEAD(&stats_vdev->stat); return 0; @@ -166,9 +165,9 @@ static void rkisp_stats_vb2_buf_queue(struct vb2_buffer *vb) dev_info(dev->dev, "tb stat seq:%d meas_type:0x%x\n", buf->frame_id, buf->meas_type); - memcpy(stats_buf->vaddr[0], buf, sizeof(struct rkisp32_isp_stat_buffer)); + memcpy(stats_buf->vaddr[0], buf, size); buf->meas_type = 0; - vb2_set_plane_payload(vb, 0, sizeof(struct rkisp32_isp_stat_buffer)); + vb2_set_plane_payload(vb, 0, size); vbuf->sequence = buf->frame_id; spin_unlock_irqrestore(&stats_dev->rd_lock, flags); vb2_buffer_done(vb, VB2_BUF_STATE_DONE); @@ -286,6 +285,7 @@ static void rkisp_init_stats_vdev(struct rkisp_isp_stats_vdev *stats_vdev) stats_vdev->rd_buf_idx = 0; stats_vdev->wr_buf_idx = 0; memset(stats_vdev->stats_buf, 0, sizeof(stats_vdev->stats_buf)); + stats_vdev->vdev_fmt.fmt.meta.dataformat = V4L2_META_FMT_RK_ISP1_STAT_3A; if (stats_vdev->dev->isp_ver <= ISP_V13) rkisp_init_stats_vdev_v1x(stats_vdev); diff --git a/drivers/media/platform/rockchip/isp/isp_stats.h b/drivers/media/platform/rockchip/isp/isp_stats.h index 5e10d8f3d545..4ccf8b827410 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats.h +++ b/drivers/media/platform/rockchip/isp/isp_stats.h @@ -34,6 +34,7 @@ struct rkisp_isp_stats_ops { void (*send_meas)(struct rkisp_isp_stats_vdev *stats_vdev, struct rkisp_isp_readout_work *meas_work); void (*rdbk_enable)(struct rkisp_isp_stats_vdev *stats_vdev, bool en); + void (*get_stat_size)(struct rkisp_isp_stats_vdev *stats_vdev, unsigned int sizes[]); }; /* diff --git a/drivers/media/platform/rockchip/isp/isp_stats_v1x.c b/drivers/media/platform/rockchip/isp/isp_stats_v1x.c index dce904b5f7c5..3829156cd4b8 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats_v1x.c +++ b/drivers/media/platform/rockchip/isp/isp_stats_v1x.c @@ -390,19 +390,23 @@ rkisp_stats_rdbk_enable_v1x(struct rkisp_isp_stats_vdev *stats_vdev, bool en) { } +static void +rkisp_get_stat_size_v1x(struct rkisp_isp_stats_vdev *stats_vdev, + unsigned int sizes[]) +{ + sizes[0] = sizeof(struct rkisp1_stat_buffer); + stats_vdev->vdev_fmt.fmt.meta.buffersize = sizes[0]; +} + static struct rkisp_isp_stats_ops rkisp_isp_stats_ops_tbl = { .isr_hdl = rkisp1_stats_isr_v1x, .send_meas = rkisp1_stats_send_meas_v1x, .rdbk_enable = rkisp_stats_rdbk_enable_v1x, + .get_stat_size = rkisp_get_stat_size_v1x, }; void rkisp_init_stats_vdev_v1x(struct rkisp_isp_stats_vdev *stats_vdev) { - stats_vdev->vdev_fmt.fmt.meta.dataformat = - V4L2_META_FMT_RK_ISP1_STAT_3A; - stats_vdev->vdev_fmt.fmt.meta.buffersize = - sizeof(struct rkisp1_stat_buffer); - stats_vdev->ops = &rkisp_isp_stats_ops_tbl; if (stats_vdev->dev->isp_ver == ISP_V12 || stats_vdev->dev->isp_ver == ISP_V13) { diff --git a/drivers/media/platform/rockchip/isp/isp_stats_v21.c b/drivers/media/platform/rockchip/isp/isp_stats_v21.c index c6308645ac53..196b2fe4b533 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats_v21.c +++ b/drivers/media/platform/rockchip/isp/isp_stats_v21.c @@ -1120,10 +1120,19 @@ rkisp_stats_rdbk_enable_v21(struct rkisp_isp_stats_vdev *stats_vdev, bool en) stats_vdev->rdbk_mode = en; } +static void +rkisp_get_stat_size_v21(struct rkisp_isp_stats_vdev *stats_vdev, + unsigned int sizes[]) +{ + sizes[0] = sizeof(struct rkisp_isp2x_stat_buffer); + stats_vdev->vdev_fmt.fmt.meta.buffersize = sizes[0]; +} + static struct rkisp_isp_stats_ops rkisp_isp_stats_ops_tbl = { .isr_hdl = rkisp_stats_isr_v21, .send_meas = rkisp_stats_send_meas_v21, .rdbk_enable = rkisp_stats_rdbk_enable_v21, + .get_stat_size = rkisp_get_stat_size_v21, }; void rkisp_stats_first_ddr_config_v21(struct rkisp_isp_stats_vdev *stats_vdev) @@ -1149,20 +1158,16 @@ void rkisp_stats_first_ddr_config_v21(struct rkisp_isp_stats_vdev *stats_vdev) void rkisp_init_stats_vdev_v21(struct rkisp_isp_stats_vdev *stats_vdev) { + int mult = stats_vdev->dev->hw_dev->unite ? ISP_UNITE_MAX : 1; int i; - stats_vdev->vdev_fmt.fmt.meta.dataformat = - V4L2_META_FMT_RK_ISP1_STAT_3A; - stats_vdev->vdev_fmt.fmt.meta.buffersize = - sizeof(struct rkisp_isp2x_stat_buffer); - stats_vdev->ops = &rkisp_isp_stats_ops_tbl; stats_vdev->priv_ops = &rkisp_stats_reg_ops_v21; stats_vdev->rd_stats_from_ddr = false; for (i = 0; i < RKISP_STATS_DDR_BUF_NUM; i++) { stats_vdev->stats_buf[i].is_need_vaddr = true; - stats_vdev->stats_buf[i].size = RKISP_RD_STATS_BUF_SIZE; + stats_vdev->stats_buf[i].size = RKISP_RD_STATS_BUF_SIZE * mult; rkisp_alloc_buffer(stats_vdev->dev, &stats_vdev->stats_buf[i]); } } diff --git a/drivers/media/platform/rockchip/isp/isp_stats_v2x.c b/drivers/media/platform/rockchip/isp/isp_stats_v2x.c index b69b48f770b5..0c73712eb87e 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats_v2x.c +++ b/drivers/media/platform/rockchip/isp/isp_stats_v2x.c @@ -1458,10 +1458,19 @@ rkisp_stats_rdbk_enable_v2x(struct rkisp_isp_stats_vdev *stats_vdev, bool en) stats_vdev->rdbk_mode = en; } +static void +rkisp_get_stat_size_v2x(struct rkisp_isp_stats_vdev *stats_vdev, + unsigned int sizes[]) +{ + sizes[0] = sizeof(struct rkisp_isp2x_stat_buffer); + stats_vdev->vdev_fmt.fmt.meta.buffersize = sizes[0]; +} + static struct rkisp_isp_stats_ops rkisp_isp_stats_ops_tbl = { .isr_hdl = rkisp_stats_isr_v2x, .send_meas = rkisp_stats_send_meas_v2x, .rdbk_enable = rkisp_stats_rdbk_enable_v2x, + .get_stat_size = rkisp_get_stat_size_v2x, }; void rkisp_stats_first_ddr_config_v2x(struct rkisp_isp_stats_vdev *stats_vdev) @@ -1491,11 +1500,6 @@ void rkisp_stats_first_ddr_config_v2x(struct rkisp_isp_stats_vdev *stats_vdev) void rkisp_init_stats_vdev_v2x(struct rkisp_isp_stats_vdev *stats_vdev) { - stats_vdev->vdev_fmt.fmt.meta.dataformat = - V4L2_META_FMT_RK_ISP1_STAT_3A; - stats_vdev->vdev_fmt.fmt.meta.buffersize = - sizeof(struct rkisp_isp2x_stat_buffer); - stats_vdev->ops = &rkisp_isp_stats_ops_tbl; stats_vdev->priv_ops = &rkisp_stats_reg_ops_v2x; diff --git a/drivers/media/platform/rockchip/isp/isp_stats_v32.c b/drivers/media/platform/rockchip/isp/isp_stats_v32.c index 6e73379ab154..b1d2e8fc830e 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats_v32.c +++ b/drivers/media/platform/rockchip/isp/isp_stats_v32.c @@ -430,6 +430,7 @@ rkisp_stats_update_buf(struct rkisp_isp_stats_vdev *stats_vdev) unsigned long flags; u32 size = stats_vdev->vdev_fmt.fmt.meta.buffersize; u32 val = 0; + int i; spin_lock_irqsave(&stats_vdev->rd_lock, flags); if (!stats_vdev->nxt_buf && !list_empty(&stats_vdev->stat)) { @@ -454,11 +455,9 @@ rkisp_stats_update_buf(struct rkisp_isp_stats_vdev *stats_vdev) val = stats_vdev->stats_buf[0].dma_addr; } - if (val) { - rkisp_write(dev, ISP3X_MI_3A_WR_BASE, val, false); - if (dev->hw_dev->unite) - rkisp_next_write(dev, ISP3X_MI_3A_WR_BASE, val + size / 2, false); - } + for (i = 0; i < dev->unite_div && val; i++) + rkisp_idx_write(dev, ISP3X_MI_3A_WR_BASE, + val + i * size / dev->unite_div, i, false); } static void @@ -920,21 +919,30 @@ rkisp_stats_send_meas_lite(struct rkisp_isp_stats_vdev *stats_vdev, struct rkisp_isp_readout_work *meas_work) { struct rkisp_device *dev = stats_vdev->dev; + struct rkisp_hw_dev *hw = dev->hw_dev; struct rkisp_isp_params_vdev *params_vdev = &dev->params_vdev; unsigned int cur_frame_id = meas_work->frame_id; - struct rkisp_buffer *cur_buf = NULL; + struct rkisp_buffer *cur_buf = stats_vdev->cur_buf; struct rkisp32_lite_stat_buffer *cur_stat_buf = NULL; - u32 size = sizeof(struct rkisp32_lite_stat_buffer); + u32 size = stats_vdev->vdev_fmt.fmt.meta.buffersize; - spin_lock(&stats_vdev->rd_lock); - if (!list_empty(&stats_vdev->stat)) { - cur_buf = list_first_entry(&stats_vdev->stat, struct rkisp_buffer, queue); - list_del(&cur_buf->queue); + if (hw->unite != ISP_UNITE_ONE || dev->unite_index == ISP_UNITE_LEFT) { + spin_lock(&stats_vdev->rd_lock); + if (!list_empty(&stats_vdev->stat)) { + cur_buf = list_first_entry(&stats_vdev->stat, struct rkisp_buffer, queue); + list_del(&cur_buf->queue); + stats_vdev->cur_buf = cur_buf; + } + spin_unlock(&stats_vdev->rd_lock); } - spin_unlock(&stats_vdev->rd_lock); if (cur_buf) { - cur_stat_buf = (struct rkisp32_lite_stat_buffer *)(cur_buf->vaddr[0]); + cur_stat_buf = cur_buf->vaddr[0]; + if (dev->unite_index > ISP_UNITE_LEFT) + cur_stat_buf += dev->unite_index; + if ((dev->unite_div == ISP_UNITE_DIV2 && dev->unite_index != ISP_UNITE_RIGHT) || + (dev->unite_div == ISP_UNITE_DIV4 && dev->unite_index != ISP_UNITE_RIGHT_B)) + cur_buf = NULL; cur_stat_buf->frame_id = cur_frame_id; cur_stat_buf->params_id = params_vdev->cur_frame_id; cur_stat_buf->params.info2ddr.buf_fd = -1; @@ -972,6 +980,7 @@ rkisp_stats_send_meas_lite(struct rkisp_isp_stats_vdev *stats_vdev, cur_buf->vb.sequence = cur_frame_id; cur_buf->vb.vb2_buf.timestamp = meas_work->timestamp; vb2_buffer_done(&cur_buf->vb.vb2_buf, VB2_BUF_STATE_DONE); + stats_vdev->cur_buf = NULL; } v4l2_dbg(4, rkisp_debug, &dev->v4l2_dev, "%s seq:%d params_id:%d ris:0x%x buf:%p meas_type:0x%x\n", @@ -1064,21 +1073,36 @@ rkisp_stats_rdbk_enable_v32(struct rkisp_isp_stats_vdev *stats_vdev, bool en) stats_vdev->rdbk_mode = en; } +static void +rkisp_get_stat_size_v32(struct rkisp_isp_stats_vdev *stats_vdev, + unsigned int sizes[]) +{ + int mult = stats_vdev->dev->unite_div; + + if (stats_vdev->dev->isp_ver == ISP_V32) + sizes[0] = ALIGN(sizeof(struct rkisp32_isp_stat_buffer), 16); + else + sizes[0] = sizeof(struct rkisp32_lite_stat_buffer); + sizes[0] *= mult; + stats_vdev->vdev_fmt.fmt.meta.buffersize = sizes[0]; +} + static struct rkisp_isp_stats_ops rkisp_isp_stats_ops_tbl = { .isr_hdl = rkisp_stats_isr_v32, .send_meas = rkisp_stats_send_meas_v32, .rdbk_enable = rkisp_stats_rdbk_enable_v32, + .get_stat_size = rkisp_get_stat_size_v32, }; void rkisp_stats_first_ddr_config_v32(struct rkisp_isp_stats_vdev *stats_vdev) { struct rkisp_device *dev = stats_vdev->dev; - u32 size = stats_vdev->vdev_fmt.fmt.meta.buffersize; - u32 div = dev->hw_dev->unite ? 2 : 1; + u32 size = 0, div = dev->unite_div; if (dev->isp_sdev.in_fmt.fmt_type == FMT_YUV) return; + rkisp_get_stat_size_v32(stats_vdev, &size); stats_vdev->stats_buf[0].is_need_vaddr = true; stats_vdev->stats_buf[0].size = size; if (rkisp_alloc_buffer(dev, &stats_vdev->stats_buf[0])) @@ -1107,21 +1131,13 @@ void rkisp_stats_next_ddr_config_v32(struct rkisp_isp_stats_vdev *stats_vdev) void rkisp_init_stats_vdev_v32(struct rkisp_isp_stats_vdev *stats_vdev) { - int mult = stats_vdev->dev->hw_dev->unite ? 2 : 1; - u32 size; - - stats_vdev->vdev_fmt.fmt.meta.dataformat = - V4L2_META_FMT_RK_ISP1_STAT_3A; if (stats_vdev->dev->isp_ver == ISP_V32) { stats_vdev->priv_ops = &stats_ddr_ops_v32; stats_vdev->rd_stats_from_ddr = true; - size = ALIGN(sizeof(struct rkisp32_isp_stat_buffer), 16); } else { stats_vdev->priv_ops = NULL; stats_vdev->rd_stats_from_ddr = false; - size = sizeof(struct rkisp32_lite_stat_buffer); } - stats_vdev->vdev_fmt.fmt.meta.buffersize = size * mult; stats_vdev->ops = &rkisp_isp_stats_ops_tbl; } diff --git a/drivers/media/platform/rockchip/isp/isp_stats_v3x.c b/drivers/media/platform/rockchip/isp/isp_stats_v3x.c index b74736d721ce..979e50dd46ed 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats_v3x.c +++ b/drivers/media/platform/rockchip/isp/isp_stats_v3x.c @@ -33,7 +33,7 @@ static void isp3_module_done(struct rkisp_isp_stats_vdev *stats_vdev, { void __iomem *base; - if (id == ISP3_LEFT) + if (id == ISP_UNITE_LEFT || id == ISP_UNITE_LEFT_B) base = stats_vdev->dev->hw_dev->base_addr; else base = stats_vdev->dev->hw_dev->base_next_addr; @@ -44,13 +44,7 @@ static void isp3_module_done(struct rkisp_isp_stats_vdev *stats_vdev, static u32 isp3_stats_read(struct rkisp_isp_stats_vdev *stats_vdev, u32 addr, u32 id) { - u32 val; - - if (id == ISP3_LEFT) - val = rkisp_read(stats_vdev->dev, addr, true); - else - val = rkisp_next_read(stats_vdev->dev, addr, true); - return val; + return rkisp_idx_read(stats_vdev->dev, addr, id, true); } static int @@ -1092,7 +1086,7 @@ rkisp_stats_isr_v3x(struct rkisp_isp_stats_vdev *stats_vdev, u32 iq_isr_mask = ISP3X_SIAWB_DONE | ISP3X_SIAF_FIN | ISP3X_EXP_END | ISP3X_SIHST_RDY | ISP3X_AFM_SUM_OF | ISP3X_AFM_LUM_OF; u32 cur_frame_id, isp_mis_tmp = 0, iq_3a_mask = 0; - u32 wr_buf_idx, temp_isp_ris, temp_isp3a_ris; + u32 i, wr_buf_idx, temp_isp_ris, temp_isp3a_ris; rkisp_dmarx_get_frame(stats_vdev->dev, &cur_frame_id, NULL, NULL, true); @@ -1136,12 +1130,10 @@ rkisp_stats_isr_v3x(struct rkisp_isp_stats_vdev *stats_vdev, stats_vdev->wr_buf_idx = wr_buf_idx; rkisp_finish_buffer(dev, &stats_vdev->stats_buf[wr_buf_idx]); - rkisp_write(dev, ISP3X_MI_3A_WR_BASE, - stats_vdev->stats_buf[wr_buf_idx].dma_addr, false); - if (dev->hw_dev->unite) - rkisp_next_write(dev, ISP3X_MI_3A_WR_BASE, - stats_vdev->stats_buf[wr_buf_idx].dma_addr + - ISP3X_RD_STATS_BUF_SIZE, false); + for (i = 0; i < dev->unite_div; i++) + rkisp_idx_write(dev, ISP3X_MI_3A_WR_BASE, + stats_vdev->stats_buf[wr_buf_idx].dma_addr + + i * ISP3X_RD_STATS_BUF_SIZE, i, false); } if (isp_ris & ISP3X_FRAME) { @@ -1169,16 +1161,27 @@ rkisp_stats_rdbk_enable_v3x(struct rkisp_isp_stats_vdev *stats_vdev, bool en) stats_vdev->rdbk_mode = en; } +static void +rkisp_get_stat_size_v3x(struct rkisp_isp_stats_vdev *stats_vdev, + unsigned int sizes[]) +{ + int mult = stats_vdev->dev->unite_div; + + sizes[0] = sizeof(struct rkisp3x_isp_stat_buffer) * mult; + stats_vdev->vdev_fmt.fmt.meta.buffersize = sizes[0]; +} + static struct rkisp_isp_stats_ops rkisp_isp_stats_ops_tbl = { .isr_hdl = rkisp_stats_isr_v3x, .send_meas = rkisp_stats_send_meas_v3x, .rdbk_enable = rkisp_stats_rdbk_enable_v3x, + .get_stat_size = rkisp_get_stat_size_v3x, }; void rkisp_stats_first_ddr_config_v3x(struct rkisp_isp_stats_vdev *stats_vdev) { struct rkisp_device *dev = stats_vdev->dev; - int i, mult = dev->hw_dev->unite ? 2 : 1; + int i, mult = dev->unite_div; if (dev->isp_sdev.in_fmt.fmt_type == FMT_YUV) return; @@ -1202,12 +1205,10 @@ void rkisp_stats_first_ddr_config_v3x(struct rkisp_isp_stats_vdev *stats_vdev) ISP3X_RD_STATS_BUF_SIZE, false); rkisp_unite_set_bits(dev, ISP3X_SWS_CFG, 0, ISP3X_3A_DDR_WRITE_EN, false); - rkisp_write(dev, ISP3X_MI_3A_WR_BASE, - stats_vdev->stats_buf[0].dma_addr, false); - if (dev->hw_dev->unite) - rkisp_next_write(dev, ISP3X_MI_3A_WR_BASE, - stats_vdev->stats_buf[0].dma_addr + - ISP3X_RD_STATS_BUF_SIZE, false); + for (i = 0; i < dev->unite_div; i++) + rkisp_idx_write(dev, ISP3X_MI_3A_WR_BASE, + stats_vdev->stats_buf[0].dma_addr + + i * ISP3X_RD_STATS_BUF_SIZE, i, false); return; err: @@ -1218,13 +1219,6 @@ err: void rkisp_init_stats_vdev_v3x(struct rkisp_isp_stats_vdev *stats_vdev) { - int mult = stats_vdev->dev->hw_dev->unite ? 2 : 1; - - stats_vdev->vdev_fmt.fmt.meta.dataformat = - V4L2_META_FMT_RK_ISP1_STAT_3A; - stats_vdev->vdev_fmt.fmt.meta.buffersize = - mult * sizeof(struct rkisp3x_isp_stat_buffer); - stats_vdev->ops = &rkisp_isp_stats_ops_tbl; stats_vdev->priv_ops = &stats_reg_ops_v3x; stats_vdev->rd_stats_from_ddr = false; diff --git a/drivers/media/platform/rockchip/isp/procfs.c b/drivers/media/platform/rockchip/isp/procfs.c index 223f674d99ea..55c205f7ed21 100644 --- a/drivers/media/platform/rockchip/isp/procfs.c +++ b/drivers/media/platform/rockchip/isp/procfs.c @@ -380,242 +380,242 @@ static void isp30_unite_show(struct rkisp_device *dev, struct seq_file *p) }; u32 v0, v1; - v0 = rkisp_read(dev, ISP3X_CMSK_CTRL0, false); - v1 = rkisp_next_read(dev, ISP3X_CMSK_CTRL0, false); + v0 = rkisp_idx_read(dev, ISP3X_CMSK_CTRL0, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_CMSK_CTRL0, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "CMSK", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_DPCC0_MODE, false); - v1 = rkisp_next_read(dev, ISP3X_DPCC0_MODE, false); + v0 = rkisp_idx_read(dev, ISP3X_DPCC0_MODE, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_DPCC0_MODE, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "DPCC0", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_DPCC1_MODE, false); - v1 = rkisp_next_read(dev, ISP3X_DPCC1_MODE, false); + v0 = rkisp_idx_read(dev, ISP3X_DPCC1_MODE, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_DPCC1_MODE, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "DPCC1", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_DPCC2_MODE, false); - v1 = rkisp_next_read(dev, ISP3X_DPCC2_MODE, false); + v0 = rkisp_idx_read(dev, ISP3X_DPCC2_MODE, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_DPCC2_MODE, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "DPCC2", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_BLS_CTRL, false); - v1 = rkisp_next_read(dev, ISP3X_BLS_CTRL, false); + v0 = rkisp_idx_read(dev, ISP3X_BLS_CTRL, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_BLS_CTRL, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "BLS", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_ISP_CTRL0, false); - v1 = rkisp_next_read(dev, ISP3X_ISP_CTRL0, false); + v0 = rkisp_idx_read(dev, ISP3X_ISP_CTRL0, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_ISP_CTRL0, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "SDG", (v0 & BIT(6)) ? "ON" : "OFF", v0, (v1 & BIT(6)) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_LSC_CTRL, false); - v1 = rkisp_next_read(dev, ISP3X_LSC_CTRL, false); + v0 = rkisp_idx_read(dev, ISP3X_LSC_CTRL, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_LSC_CTRL, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "LSC", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_ISP_CTRL0, false); - v1 = rkisp_next_read(dev, ISP3X_ISP_CTRL0, false); + v0 = rkisp_idx_read(dev, ISP3X_ISP_CTRL0, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_ISP_CTRL0, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x) gain:0x%08x 0x%08x, Right %s(0x%x) gain:0x%08x 0x%08x\n", "AWBGAIN", (v0 & BIT(7)) ? "ON" : "OFF", v0, - rkisp_read(dev, ISP3X_ISP_AWB_GAIN0_G, false), - rkisp_read(dev, ISP3X_ISP_AWB_GAIN0_RB, false), + rkisp_idx_read(dev, ISP3X_ISP_AWB_GAIN0_G, ISP_UNITE_LEFT, false), + rkisp_idx_read(dev, ISP3X_ISP_AWB_GAIN0_RB, ISP_UNITE_LEFT, false), (v1 & BIT(7)) ? "ON" : "OFF", v1, - rkisp_next_read(dev, ISP3X_ISP_AWB_GAIN0_G, false), - rkisp_next_read(dev, ISP3X_ISP_AWB_GAIN0_RB, false)); - v0 = rkisp_read(dev, ISP3X_DEBAYER_CONTROL, false); - v1 = rkisp_next_read(dev, ISP3X_DEBAYER_CONTROL, false); + rkisp_idx_read(dev, ISP3X_ISP_AWB_GAIN0_G, ISP_UNITE_RIGHT, false), + rkisp_idx_read(dev, ISP3X_ISP_AWB_GAIN0_RB, ISP_UNITE_RIGHT, false)); + v0 = rkisp_idx_read(dev, ISP3X_DEBAYER_CONTROL, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_DEBAYER_CONTROL, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "DEBAYER", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_CCM_CTRL, false); - v1 = rkisp_next_read(dev, ISP3X_CCM_CTRL, false); + v0 = rkisp_idx_read(dev, ISP3X_CCM_CTRL, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_CCM_CTRL, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "CCM", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_GAMMA_OUT_CTRL, false); - v1 = rkisp_next_read(dev, ISP3X_GAMMA_OUT_CTRL, false); + v0 = rkisp_idx_read(dev, ISP3X_GAMMA_OUT_CTRL, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_GAMMA_OUT_CTRL, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "GAMMA_OUT", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_CPROC_CTRL, false); - v1 = rkisp_next_read(dev, ISP3X_CPROC_CTRL, false); + v0 = rkisp_idx_read(dev, ISP3X_CPROC_CTRL, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_CPROC_CTRL, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "CPROC", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_IMG_EFF_CTRL, false); - v1 = rkisp_next_read(dev, ISP3X_IMG_EFF_CTRL, false); + v0 = rkisp_idx_read(dev, ISP3X_IMG_EFF_CTRL, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_IMG_EFF_CTRL, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x) effect:%s, Right %s(0x%x) effect:%s\n", "IE", (v0 & 1) ? "ON" : "OFF", v0, effect[(v0 & CIF_IMG_EFF_CTRL_MODE_MASK) >> 1], (v1 & 1) ? "ON" : "OFF", v1, effect[(v1 & CIF_IMG_EFF_CTRL_MODE_MASK) >> 1]); - v0 = rkisp_read(dev, ISP3X_DRC_CTRL0, false); - v1 = rkisp_next_read(dev, ISP3X_DRC_CTRL0, false); + v0 = rkisp_idx_read(dev, ISP3X_DRC_CTRL0, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_DRC_CTRL0, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "HDRDRC", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_HDRMGE_CTRL, false); - v1 = rkisp_next_read(dev, ISP3X_HDRMGE_CTRL, false); + v0 = rkisp_idx_read(dev, ISP3X_HDRMGE_CTRL, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_HDRMGE_CTRL, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "HDRMGE", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_BAYNR_CTRL, false); - v1 = rkisp_next_read(dev, ISP3X_BAYNR_CTRL, false); + v0 = rkisp_idx_read(dev, ISP3X_BAYNR_CTRL, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_BAYNR_CTRL, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "BAYNR", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_BAY3D_CTRL, false); - v1 = rkisp_next_read(dev, ISP3X_BAY3D_CTRL, false); + v0 = rkisp_idx_read(dev, ISP3X_BAY3D_CTRL, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_BAY3D_CTRL, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "BAY3D", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_YNR_GLOBAL_CTRL, false); - v1 = rkisp_next_read(dev, ISP3X_YNR_GLOBAL_CTRL, false); + v0 = rkisp_idx_read(dev, ISP3X_YNR_GLOBAL_CTRL, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_YNR_GLOBAL_CTRL, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "YNR", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_CNR_CTRL, false); - v1 = rkisp_next_read(dev, ISP3X_CNR_CTRL, false); + v0 = rkisp_idx_read(dev, ISP3X_CNR_CTRL, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_CNR_CTRL, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "CNR", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_SHARP_EN, false); - v1 = rkisp_next_read(dev, ISP3X_SHARP_EN, false); + v0 = rkisp_idx_read(dev, ISP3X_SHARP_EN, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_SHARP_EN, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "SHARP", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_GIC_CONTROL, false); - v1 = rkisp_next_read(dev, ISP3X_GIC_CONTROL, false); + v0 = rkisp_idx_read(dev, ISP3X_GIC_CONTROL, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_GIC_CONTROL, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "GIC", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_DHAZ_CTRL, false); - v1 = rkisp_next_read(dev, ISP3X_DHAZ_CTRL, false); + v0 = rkisp_idx_read(dev, ISP3X_DHAZ_CTRL, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_DHAZ_CTRL, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "DHAZ", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_3DLUT_CTRL, false); - v1 = rkisp_next_read(dev, ISP3X_3DLUT_CTRL, false); + v0 = rkisp_idx_read(dev, ISP3X_3DLUT_CTRL, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_3DLUT_CTRL, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "3DLUT", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_LDCH_STS, false); - v1 = rkisp_next_read(dev, ISP3X_LDCH_STS, false); + v0 = rkisp_idx_read(dev, ISP3X_LDCH_STS, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_LDCH_STS, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "LDCH", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_ISP_CTRL0, false); - v1 = rkisp_next_read(dev, ISP3X_ISP_CTRL0, false); + v0 = rkisp_idx_read(dev, ISP3X_ISP_CTRL0, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_ISP_CTRL0, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "CSM", (v0 & full_range_flg) ? "FULL" : "LIMIT", v0, (v1 & full_range_flg) ? "FULL" : "LIMIT", v1); - v0 = rkisp_read(dev, ISP3X_CAC_CTRL, false); - v1 = rkisp_next_read(dev, ISP3X_CAC_CTRL, false); + v0 = rkisp_idx_read(dev, ISP3X_CAC_CTRL, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_CAC_CTRL, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "CAC", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_GAIN_CTRL, false); - v1 = rkisp_next_read(dev, ISP3X_GAIN_CTRL, false); + v0 = rkisp_idx_read(dev, ISP3X_GAIN_CTRL, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_GAIN_CTRL, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "GAIN", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_RAWAF_CTRL, false); - v1 = rkisp_next_read(dev, ISP3X_RAWAF_CTRL, false); + v0 = rkisp_idx_read(dev, ISP3X_RAWAF_CTRL, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_RAWAF_CTRL, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "RAWAF", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_RAWAWB_CTRL, false); - v1 = rkisp_next_read(dev, ISP3X_RAWAWB_CTRL, false); + v0 = rkisp_idx_read(dev, ISP3X_RAWAWB_CTRL, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_RAWAWB_CTRL, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "RAWAWB", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_RAWAE_LITE_CTRL, false); - v1 = rkisp_next_read(dev, ISP3X_RAWAE_LITE_CTRL, false); + v0 = rkisp_idx_read(dev, ISP3X_RAWAE_LITE_CTRL, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_RAWAE_LITE_CTRL, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "RAWAE0", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_RAWAE_BIG2_BASE, false); - v1 = rkisp_next_read(dev, ISP3X_RAWAE_BIG2_BASE, false); + v0 = rkisp_idx_read(dev, ISP3X_RAWAE_BIG2_BASE, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_RAWAE_BIG2_BASE, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "RAWAE1", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_RAWAE_BIG3_BASE, false); - v1 = rkisp_next_read(dev, ISP3X_RAWAE_BIG3_BASE, false); + v0 = rkisp_idx_read(dev, ISP3X_RAWAE_BIG3_BASE, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_RAWAE_BIG3_BASE, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "RAWAE2", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_RAWAE_BIG1_BASE, false); - v1 = rkisp_next_read(dev, ISP3X_RAWAE_BIG1_BASE, false); + v0 = rkisp_idx_read(dev, ISP3X_RAWAE_BIG1_BASE, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_RAWAE_BIG1_BASE, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "RAWAE3", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_RAWHIST_LITE_CTRL, false); - v1 = rkisp_next_read(dev, ISP3X_RAWHIST_LITE_CTRL, false); + v0 = rkisp_idx_read(dev, ISP3X_RAWHIST_LITE_CTRL, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_RAWHIST_LITE_CTRL, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "RAWHIST0", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_RAWHIST_BIG2_BASE, false); - v1 = rkisp_next_read(dev, ISP3X_RAWHIST_BIG2_BASE, false); + v0 = rkisp_idx_read(dev, ISP3X_RAWHIST_BIG2_BASE, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_RAWHIST_BIG2_BASE, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "RAWHIST1", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_RAWHIST_BIG3_BASE, false); - v1 = rkisp_next_read(dev, ISP3X_RAWHIST_BIG3_BASE, false); + v0 = rkisp_idx_read(dev, ISP3X_RAWHIST_BIG3_BASE, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_RAWHIST_BIG3_BASE, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "RAWHIST2", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_RAWHIST_BIG1_BASE, false); - v1 = rkisp_next_read(dev, ISP3X_RAWHIST_BIG1_BASE, false); + v0 = rkisp_idx_read(dev, ISP3X_RAWHIST_BIG1_BASE, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_RAWHIST_BIG1_BASE, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "RAWHIST3", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_ISP_CTRL1, true); - v1 = rkisp_next_read(dev, ISP3X_ISP_CTRL1, true); + v0 = rkisp_idx_read(dev, ISP3X_ISP_CTRL1, ISP_UNITE_LEFT, true); + v1 = rkisp_idx_read(dev, ISP3X_ISP_CTRL1, ISP_UNITE_RIGHT, true); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "BigMode", v0 & BIT(28) ? "ON" : "OFF", v0, v1 & BIT(28) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_ISP_DEBUG1, true); - v1 = rkisp_next_read(dev, ISP3X_ISP_DEBUG1, true); + v0 = rkisp_idx_read(dev, ISP3X_ISP_DEBUG1, ISP_UNITE_LEFT, true); + v1 = rkisp_idx_read(dev, ISP3X_ISP_DEBUG1, ISP_UNITE_RIGHT, true); seq_printf(p, "%-10s space full status group. Left:0x%x Right:0x%x\n" "\t ibuf2(L:0x%x R:0x%x) ibuf1(L:0x%x R:0x%x)\n" "\t ibuf0(L:0x%x R:0x%x) mpfbc_infifo(L:0x%x R:0x%x)\n" @@ -626,8 +626,8 @@ static void isp30_unite_show(struct rkisp_device *dev, struct seq_file *p) (v0 >> 20) & 0xf, (v1 >> 20) & 0xf, (v0 >> 16) & 0xf, (v1 >> 16) & 0xf, (v0 >> 12) & 0xf, (v1 >> 12) & 0xf, (v0 >> 8) & 0xf, (v1 >> 8) & 0xf, (v0 >> 4) & 0xf, (v1 >> 4) & 0xf, v0 & 0xf, v1 & 0xf); - v0 = rkisp_read(dev, ISP3X_ISP_DEBUG2, true); - v1 = rkisp_next_read(dev, ISP3X_ISP_DEBUG2, true); + v0 = rkisp_idx_read(dev, ISP3X_ISP_DEBUG2, ISP_UNITE_LEFT, true); + v1 = rkisp_idx_read(dev, ISP3X_ISP_DEBUG2, ISP_UNITE_RIGHT, true); seq_printf(p, "%-10s Left:0x%x Right:0x%x\n" "\t bay3d_fifo_full iir(L:%d R:%d) cur(L:%d R:%d)\n" "\t module outform vertical counter(L:%d R:%d), out frame counter:(L:%d R:%d)\n" @@ -636,8 +636,8 @@ static void isp30_unite_show(struct rkisp_device *dev, struct seq_file *p) !!(v0 & BIT(31)), !!(v1 & BIT(31)), !!(v0 & BIT(30)), !!(v1 & BIT(30)), (v0 >> 16) & 0x3fff, (v1 >> 16) & 0x3fff, (v0 >> 14) & 0x3, (v1 >> 14) & 0x3, v0 & 0x3fff, v1 & 0x3fff); - v0 = rkisp_read(dev, ISP3X_ISP_DEBUG3, true); - v1 = rkisp_next_read(dev, ISP3X_ISP_DEBUG3, true); + v0 = rkisp_idx_read(dev, ISP3X_ISP_DEBUG3, ISP_UNITE_LEFT, true); + v1 = rkisp_idx_read(dev, ISP3X_ISP_DEBUG3, ISP_UNITE_RIGHT, true); seq_printf(p, "%-10s isp pipeline group Left:0x%x Right:0x%x\n" "\t mge(L:%d %d R:%d %d) rawnr(L:%d %d R:%d %d)\n" "\t bay3d(L:%d %d R:%d %d) tmo(L:%d %d R:%d %d)\n" @@ -976,14 +976,14 @@ static int isp_show(struct seq_file *p, void *v) rkisp_read(dev, i + 12, true)); } else { seq_printf(p, "%04x: %08x %08x %08x %08x | %08x %08x %08x %08x\n", i, - rkisp_read(dev, i, true), - rkisp_read(dev, i + 4, true), - rkisp_read(dev, i + 8, true), - rkisp_read(dev, i + 12, true), - rkisp_next_read(dev, i, true), - rkisp_next_read(dev, i + 4, true), - rkisp_next_read(dev, i + 8, true), - rkisp_next_read(dev, i + 12, true)); + rkisp_idx_read(dev, i, ISP_UNITE_LEFT, true), + rkisp_idx_read(dev, i + 4, ISP_UNITE_LEFT, true), + rkisp_idx_read(dev, i + 8, ISP_UNITE_LEFT, true), + rkisp_idx_read(dev, i + 12, ISP_UNITE_LEFT, true), + rkisp_idx_read(dev, i, ISP_UNITE_RIGHT, true), + rkisp_idx_read(dev, i + 4, ISP_UNITE_RIGHT, true), + rkisp_idx_read(dev, i + 8, ISP_UNITE_RIGHT, true), + rkisp_idx_read(dev, i + 12, ISP_UNITE_RIGHT, true)); } } } diff --git a/drivers/media/platform/rockchip/isp/regs.c b/drivers/media/platform/rockchip/isp/regs.c index 17af5ef7349b..90c1b6d76f7f 100644 --- a/drivers/media/platform/rockchip/isp/regs.c +++ b/drivers/media/platform/rockchip/isp/regs.c @@ -53,11 +53,10 @@ void rkisp_config_dcrop(struct rkisp_stream *stream, { struct rkisp_device *dev = stream->ispdev; u32 val = stream->config->dual_crop.yuvmode_mask; - bool is_unite = !!dev->hw_dev->unite; struct v4l2_rect tmp = *rect; u32 reg; - if (is_unite) { + if (dev->unite_div > ISP_UNITE_DIV1) { tmp.width /= 2; if (stream->id == RKISP_STREAM_FBC) tmp.width &= ~0xf; @@ -67,6 +66,8 @@ void rkisp_config_dcrop(struct rkisp_stream *stream, reg = stream->config->dual_crop.h_size; rkisp_write(dev, reg, tmp.width, false); + if (dev->unite_div == ISP_UNITE_DIV4) + tmp.height /= 2; reg = stream->config->dual_crop.v_offset; rkisp_unite_write(dev, reg, tmp.top, false); reg = stream->config->dual_crop.v_size; @@ -76,21 +77,23 @@ void rkisp_config_dcrop(struct rkisp_stream *stream, val |= CIF_DUAL_CROP_GEN_CFG_UPD; else val |= CIF_DUAL_CROP_CFG_UPD; - if (is_unite) { + + if (dev->unite_div > ISP_UNITE_DIV1) { u32 right_w, left_w = tmp.width; reg = stream->config->dual_crop.h_offset; - rkisp_next_write(dev, reg, RKMOUDLE_UNITE_EXTEND_PIXEL, false); + rkisp_idx_write(dev, reg, RKMOUDLE_UNITE_EXTEND_PIXEL, ISP_UNITE_RIGHT, false); reg = stream->config->dual_crop.h_size; right_w = rect->width - left_w; - rkisp_next_write(dev, reg, right_w, false); + rkisp_idx_write(dev, reg, right_w, ISP_UNITE_RIGHT, false); + reg = stream->config->dual_crop.ctrl; - rkisp_next_set_bits(dev, reg, 0, val, false); + rkisp_idx_set_bits(dev, reg, 0, val, ISP_UNITE_RIGHT, false); /* output with scale */ if (stream->out_fmt.width < rect->width) { left_w += RKMOUDLE_UNITE_EXTEND_PIXEL; reg = stream->config->dual_crop.h_size; - rkisp_write(dev, reg, left_w, false); + rkisp_idx_write(dev, reg, left_w, ISP_UNITE_LEFT, false); } v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev, "left dcrop (%d, %d) %dx%d\n", @@ -99,6 +102,23 @@ void rkisp_config_dcrop(struct rkisp_stream *stream, "right dcrop (%d, %d) %dx%d\n", RKMOUDLE_UNITE_EXTEND_PIXEL, tmp.top, right_w, tmp.height); } + if (dev->unite_div == ISP_UNITE_DIV4) { + reg = stream->config->dual_crop.h_offset; + rkisp_idx_write(dev, reg, tmp.left, ISP_UNITE_LEFT_B, false); + rkisp_idx_write(dev, reg, RKMOUDLE_UNITE_EXTEND_PIXEL, ISP_UNITE_RIGHT_B, false); + + reg = stream->config->dual_crop.h_size; + rkisp_idx_write(dev, reg, tmp.width, ISP_UNITE_LEFT_B, false); + rkisp_idx_write(dev, reg, tmp.width, ISP_UNITE_RIGHT_B, false); + + reg = stream->config->dual_crop.v_offset; + rkisp_idx_write(dev, reg, RKMOUDLE_UNITE_EXTEND_PIXEL, ISP_UNITE_LEFT_B, false); + rkisp_idx_write(dev, reg, RKMOUDLE_UNITE_EXTEND_PIXEL, ISP_UNITE_RIGHT_B, false); + + reg = stream->config->dual_crop.ctrl; + rkisp_idx_set_bits(dev, reg, 0, val, ISP_UNITE_LEFT_B, false); + rkisp_idx_set_bits(dev, reg, 0, val, ISP_UNITE_RIGHT_B, false); + } if (val) { reg = stream->config->dual_crop.ctrl; rkisp_set_bits(dev, reg, 0, val, false); @@ -218,7 +238,7 @@ static void set_scale(struct rkisp_stream *stream, struct v4l2_rect *in_y, rkisp_write(dev, scale_vc_addr, scale_vc, false); } - if (dev->hw_dev->unite) { + if (dev->unite_div > ISP_UNITE_DIV1) { u32 hy_size_reg, hc_size_reg, hy_offs_mi_reg, hc_offs_mi_reg, in_crop_offs_reg; u32 isp_in_w = in_y->width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; u32 scl_w = out_y->width / 2; @@ -271,11 +291,13 @@ static void set_scale(struct rkisp_stream *stream, struct v4l2_rect *in_y, extend = right_crop_y & ~0x1; reg = stream->config->dual_crop.h_offset; - rkisp_next_write(dev, reg, extend, false); + rkisp_idx_write(dev, reg, extend, ISP_UNITE_RIGHT, false); reg = stream->config->dual_crop.h_size; - rkisp_next_write(dev, reg, isp_in_w - extend, false); + rkisp_idx_write(dev, reg, isp_in_w - extend, ISP_UNITE_RIGHT, false); reg = stream->config->dual_crop.ctrl; - rkisp_next_write(dev, reg, rkisp_next_read_reg_cache(dev, reg), false); + rkisp_idx_write(dev, reg, + rkisp_idx_read_reg_cache(dev, reg, ISP_UNITE_RIGHT), + ISP_UNITE_RIGHT, false); } right_scl_in_y = right_crop_y - extend; right_scl_in_c = right_crop_c - extend; @@ -288,25 +310,26 @@ static void set_scale(struct rkisp_stream *stream, struct v4l2_rect *in_y, rkisp_write(dev, in_crop_offs_reg, 0, false); /* right isp */ - rkisp_next_write(dev, hy_size_reg, scl_w, false); - rkisp_next_write(dev, hc_size_reg, scl_w, false); - rkisp_next_write(dev, scale_hy_addr, scale_hy, false); - rkisp_next_write(dev, scale_hcb_addr, scale_hc, false); - rkisp_next_write(dev, scale_hcr_addr, scale_hc, false); - rkisp_next_write(dev, scale_vy_addr, scale_vy, false); - rkisp_next_write(dev, scale_vc_addr, scale_vc, false); - rkisp_next_write(dev, stream->config->rsz.phase_hy, phase_left_y, false); - rkisp_next_write(dev, stream->config->rsz.phase_hc, phase_left_c, false); - rkisp_next_write(dev, stream->config->rsz.phase_vy, 0, false); - rkisp_next_write(dev, stream->config->rsz.phase_vc, 0, false); - rkisp_next_write(dev, hy_offs_mi_reg, scl_w & 15, false); - rkisp_next_write(dev, hc_offs_mi_reg, scl_w & 15, false); - rkisp_next_write(dev, in_crop_offs_reg, - right_scl_in_c << 4 | right_scl_in_y, false); + rkisp_idx_write(dev, hy_size_reg, scl_w, ISP_UNITE_RIGHT, false); + rkisp_idx_write(dev, hc_size_reg, scl_w, ISP_UNITE_RIGHT, false); + rkisp_idx_write(dev, scale_hy_addr, scale_hy, ISP_UNITE_RIGHT, false); + rkisp_idx_write(dev, scale_hcb_addr, scale_hc, ISP_UNITE_RIGHT, false); + rkisp_idx_write(dev, scale_hcr_addr, scale_hc, ISP_UNITE_RIGHT, false); + rkisp_idx_write(dev, scale_vy_addr, scale_vy, ISP_UNITE_RIGHT, false); + rkisp_idx_write(dev, scale_vc_addr, scale_vc, ISP_UNITE_RIGHT, false); + rkisp_idx_write(dev, stream->config->rsz.phase_hy, phase_left_y, ISP_UNITE_RIGHT, false); + rkisp_idx_write(dev, stream->config->rsz.phase_hc, phase_left_c, ISP_UNITE_RIGHT, false); + rkisp_idx_write(dev, stream->config->rsz.phase_vy, 0, ISP_UNITE_RIGHT, false); + rkisp_idx_write(dev, stream->config->rsz.phase_vc, 0, ISP_UNITE_RIGHT, false); + rkisp_idx_write(dev, hy_offs_mi_reg, scl_w & 15, ISP_UNITE_RIGHT, false); + rkisp_idx_write(dev, hc_offs_mi_reg, scl_w & 15, ISP_UNITE_RIGHT, false); + rkisp_idx_write(dev, in_crop_offs_reg, + right_scl_in_c << 4 | right_scl_in_y, ISP_UNITE_RIGHT, false); rsz_ctrl |= ISP3X_SCL_CLIP_EN; - rkisp_next_write(dev, rsz_ctrl_addr, - rsz_ctrl | ISP3X_SCL_HPHASE_EN | ISP3X_SCL_IN_CLIP_EN, false); + rkisp_idx_write(dev, rsz_ctrl_addr, + rsz_ctrl | ISP3X_SCL_HPHASE_EN | ISP3X_SCL_IN_CLIP_EN, + ISP_UNITE_RIGHT, false); v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev, "scl:%dx%d, scl factor[hy:%d hc:%d vy:%d vc:%d]\n", scl_w, out_y->height, scale_hy, scale_hc, scale_vy, scale_vc); @@ -328,12 +351,12 @@ static void set_bilinear_scale(struct rkisp_stream *stream, struct v4l2_rect *in u32 rsz_ctrl = 0, val, hy, hc; bool is_avg = false; - rkisp_write(dev, ISP32_SELF_SCALE_HY_OFFS, 0, true); - rkisp_write(dev, ISP32_SELF_SCALE_HC_OFFS, 0, true); - rkisp_write(dev, ISP32_SELF_SCALE_PHASE_HY, 0, true); - rkisp_write(dev, ISP32_SELF_SCALE_PHASE_HC, 0, true); - rkisp_write(dev, ISP32_SELF_SCALE_PHASE_VY, 0, true); - rkisp_write(dev, ISP32_SELF_SCALE_PHASE_VC, 0, true); + rkisp_unite_write(dev, ISP32_SELF_SCALE_HY_OFFS, 0, true); + rkisp_unite_write(dev, ISP32_SELF_SCALE_HC_OFFS, 0, true); + rkisp_unite_write(dev, ISP32_SELF_SCALE_PHASE_HY, 0, true); + rkisp_unite_write(dev, ISP32_SELF_SCALE_PHASE_HC, 0, true); + rkisp_unite_write(dev, ISP32_SELF_SCALE_PHASE_VY, 0, true); + rkisp_unite_write(dev, ISP32_SELF_SCALE_PHASE_VC, 0, true); val = in_y->width | in_y->height << 16; rkisp_write(dev, ISP32_SELF_SCALE_SRC_SIZE, val, false); @@ -386,10 +409,10 @@ void rkisp_config_rsz(struct rkisp_stream *stream, struct v4l2_rect *in_y, } /* No phase offset */ - rkisp_write(dev, stream->config->rsz.phase_hy, 0, true); - rkisp_write(dev, stream->config->rsz.phase_hc, 0, true); - rkisp_write(dev, stream->config->rsz.phase_vy, 0, true); - rkisp_write(dev, stream->config->rsz.phase_vc, 0, true); + rkisp_unite_write(dev, stream->config->rsz.phase_hy, 0, true); + rkisp_unite_write(dev, stream->config->rsz.phase_hc, 0, true); + rkisp_unite_write(dev, stream->config->rsz.phase_vy, 0, true); + rkisp_unite_write(dev, stream->config->rsz.phase_vc, 0, true); /* Linear interpolation */ for (i = 0; i < 64; i++) { diff --git a/drivers/media/platform/rockchip/isp/regs_v2x.h b/drivers/media/platform/rockchip/isp/regs_v2x.h index 2f3c1009ae4e..045c5a8eb386 100644 --- a/drivers/media/platform/rockchip/isp/regs_v2x.h +++ b/drivers/media/platform/rockchip/isp/regs_v2x.h @@ -2696,15 +2696,10 @@ static inline void mi_raw_length(struct rkisp_stream *stream) stream->config->mi.length == MI_RAW1_RD_LENGTH || stream->config->mi.length == MI_RAW2_RD_LENGTH) is_direct = false; - rkisp_write(stream->ispdev, stream->config->mi.length, - stream->out_fmt.plane_fmt[0].bytesperline, is_direct); + rkisp_unite_write(stream->ispdev, stream->config->mi.length, + stream->out_fmt.plane_fmt[0].bytesperline, is_direct); if (stream->ispdev->isp_ver == ISP_V21 || stream->ispdev->isp_ver == ISP_V30) - rkisp_set_bits(stream->ispdev, MI_RD_CTRL2, 0, BIT(30), false); - if (stream->ispdev->hw_dev->unite) { - rkisp_next_write(stream->ispdev, stream->config->mi.length, - stream->out_fmt.plane_fmt[0].bytesperline, is_direct); - rkisp_next_set_bits(stream->ispdev, MI_RD_CTRL2, 0, BIT(30), false); - } + rkisp_unite_set_bits(stream->ispdev, MI_RD_CTRL2, 0, BIT(30), false); } static inline void rx_force_upd(void __iomem *base) diff --git a/drivers/media/platform/rockchip/isp/rkisp.c b/drivers/media/platform/rockchip/isp/rkisp.c index 5d29e8030a63..cc9d38f80991 100644 --- a/drivers/media/platform/rockchip/isp/rkisp.c +++ b/drivers/media/platform/rockchip/isp/rkisp.c @@ -219,8 +219,10 @@ int rkisp_align_sensor_resolution(struct rkisp_device *dev, CIF_ISP_INPUT_H_MAX_V32_UNITE : CIF_ISP_INPUT_H_MAX_V32; break; case ISP_V32_L: - max_w = CIF_ISP_INPUT_W_MAX_V32_L; - max_h = CIF_ISP_INPUT_H_MAX_V32_L; + max_w = dev->hw_dev->unite ? + CIF_ISP_INPUT_W_MAX_V32_L_UNITE : CIF_ISP_INPUT_W_MAX_V32_L; + max_h = dev->hw_dev->unite ? + CIF_ISP_INPUT_H_MAX_V32_L_UNITE : CIF_ISP_INPUT_H_MAX_V32_L; break; default: max_w = CIF_ISP_INPUT_W_MAX; @@ -494,7 +496,7 @@ static void rkisp_dvfs(struct rkisp_device *dev) { struct rkisp_hw_dev *hw = dev->hw_dev; u64 data_rate = 0; - int i, fps, num = 0; + int i, fps, size, num = 0; if (!hw->is_dvfs) return; @@ -505,7 +507,8 @@ static void rkisp_dvfs(struct rkisp_device *dev) fps = hw->isp_size[i].fps; if (!fps) fps = 30; - data_rate += (fps * hw->isp_size[i].size); + size = hw->isp_size[i].size * hw->isp[i]->unite_div; + data_rate += (fps * size); num++; } do_div(data_rate, 1000 * 1000); @@ -937,8 +940,10 @@ static void rkisp_rdbk_trigger_handle(struct rkisp_device *dev, u32 cmd) is_try = true; times = 0; if (hw->unite == ISP_UNITE_ONE) { - if (dev->sw_rd_cnt < 2) + if (hw->is_multi_overflow && dev->sw_rd_cnt < 2) isp->unite_index = ISP_UNITE_RIGHT; + else if (hw->is_frm_buf) + isp->unite_index++; if (!hw->is_multi_overflow || (dev->sw_rd_cnt & 0x1)) is_try = false; } @@ -998,24 +1003,27 @@ static void rkisp_rdbk_trigger_handle(struct rkisp_device *dev, u32 cmd) hw->is_idle = false; /* this frame will read count by isp */ isp->sw_rd_cnt = 0; - /* frame double for multi camera resolution out of hardware limit - * first for HW save this camera information, and second to output image - */ isp->is_frame_double = false; - if (hw->is_multi_overflow && - (hw->unite == ISP_UNITE_ONE || - (hw->pre_dev_id != -1 && hw->pre_dev_id != id))) { - isp->is_frame_double = true; - isp->sw_rd_cnt = 1; - times = 0; - } - /* resolution out of hardware limit - * frame is vertically divided into left and right - */ isp->unite_index = ISP_UNITE_LEFT; - if (hw->unite == ISP_UNITE_ONE) { - isp->sw_rd_cnt *= 2; - isp->sw_rd_cnt += 1; + if (hw->is_multi_overflow) { + /* frame double for multi camera resolution out of hardware limit + * first for HW save this camera information, and second to output image + */ + if ((hw->unite == ISP_UNITE_ONE || + (hw->pre_dev_id != -1 && hw->pre_dev_id != id))) { + isp->is_frame_double = true; + isp->sw_rd_cnt = 1; + times = 0; + } + /* resolution out of hardware limit + * frame is vertically divided into left and right + */ + if (hw->unite == ISP_UNITE_ONE) { + isp->sw_rd_cnt *= 2; + isp->sw_rd_cnt += 1; + } + } else if (hw->is_frm_buf) { + isp->sw_rd_cnt += (isp->unite_div - 1); } /* first frame handle twice for thunderboot * first output stats to AIQ and wait new params to run second @@ -1180,15 +1188,17 @@ static void rkisp_config_ism(struct rkisp_device *dev) { struct v4l2_rect *out_crop = &dev->isp_sdev.out_crop; u32 width = out_crop->width, mult = 1; - u32 unite = dev->hw_dev->unite; + u32 height = out_crop->height; /* isp2.0 no ism */ if (dev->isp_ver == ISP_V20 || dev->isp_ver == ISP_V21 || dev->isp_ver == ISP_V32_L) return; - if (unite) + if (dev->unite_div > ISP_UNITE_DIV1) width = width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + if (dev->unite_div == ISP_UNITE_DIV4) + height = height / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; rkisp_unite_write(dev, CIF_ISP_IS_RECENTER, 0, false); rkisp_unite_write(dev, CIF_ISP_IS_MAX_DX, 0, false); rkisp_unite_write(dev, CIF_ISP_IS_MAX_DY, 0, false); @@ -1198,7 +1208,7 @@ static void rkisp_config_ism(struct rkisp_device *dev) rkisp_unite_write(dev, CIF_ISP_IS_H_SIZE, width, false); if (dev->cap_dev.stream[RKISP_STREAM_SP].interlaced) mult = 2; - rkisp_unite_write(dev, CIF_ISP_IS_V_SIZE, out_crop->height / mult, false); + rkisp_unite_write(dev, CIF_ISP_IS_V_SIZE, height / mult, false); if (dev->isp_ver == ISP_V30 || dev->isp_ver == ISP_V32) return; @@ -1533,18 +1543,17 @@ static void rkisp_config_cmsk_dual(struct rkisp_device *dev, val = ISP3X_SW_CMSK_YUV(left.win[i].cover_color_y, left.win[i].cover_color_u, left.win[i].cover_color_v); - rkisp_write(dev, ISP3X_CMSK_YUV0 + i * 4, val, false); - rkisp_next_write(dev, ISP3X_CMSK_YUV0 + i * 4, val, false); + rkisp_unite_write(dev, ISP3X_CMSK_YUV0 + i * 4, val, false); val = ISP_PACK_2SHORT(left.win[i].h_offs, left.win[i].v_offs); - rkisp_write(dev, ISP3X_CMSK_OFFS0 + i * 8, val, false); + rkisp_idx_write(dev, ISP3X_CMSK_OFFS0 + i * 8, val, ISP_UNITE_LEFT, false); val = ISP_PACK_2SHORT(left.win[i].h_size, left.win[i].v_size); - rkisp_write(dev, ISP3X_CMSK_SIZE0 + i * 8, val, false); + rkisp_idx_write(dev, ISP3X_CMSK_SIZE0 + i * 8, val, ISP_UNITE_LEFT, false); val = ISP_PACK_2SHORT(right.win[i].h_offs, right.win[i].v_offs); - rkisp_next_write(dev, ISP3X_CMSK_OFFS0 + i * 8, val, false); + rkisp_idx_write(dev, ISP3X_CMSK_OFFS0 + i * 8, val, ISP_UNITE_RIGHT, false); val = ISP_PACK_2SHORT(right.win[i].h_size, right.win[i].v_size); - rkisp_next_write(dev, ISP3X_CMSK_SIZE0 + i * 8, val, false); + rkisp_idx_write(dev, ISP3X_CMSK_SIZE0 + i * 8, val, ISP_UNITE_RIGHT, false); } w += RKMOUDLE_UNITE_EXTEND_PIXEL; @@ -1577,33 +1586,34 @@ static void rkisp_config_cmsk_dual(struct rkisp_device *dev, ctrl = 0; if (right.win[0].win_en) { ctrl |= ISP3X_SW_CMSK_EN_MP; - rkisp_next_write(dev, ISP3X_CMSK_CTRL1, right.win[0].win_en, false); + rkisp_idx_write(dev, ISP3X_CMSK_CTRL1, right.win[0].win_en, ISP_UNITE_RIGHT, false); val = right.win[0].mode; - rkisp_next_write(dev, ISP3X_CMSK_CTRL4, val, false); + rkisp_idx_write(dev, ISP3X_CMSK_CTRL4, val, ISP_UNITE_RIGHT, false); } if (right.win[1].win_en) { ctrl |= ISP3X_SW_CMSK_EN_SP; - rkisp_next_write(dev, ISP3X_CMSK_CTRL2, right.win[1].win_en, false); + rkisp_idx_write(dev, ISP3X_CMSK_CTRL2, right.win[1].win_en, ISP_UNITE_RIGHT, false); val = right.win[1].mode; - rkisp_next_write(dev, ISP3X_CMSK_CTRL5, val, false); + rkisp_idx_write(dev, ISP3X_CMSK_CTRL5, val, ISP_UNITE_RIGHT, false); } if (right.win[2].win_en) { ctrl |= ISP3X_SW_CMSK_EN_BP; - rkisp_next_write(dev, ISP3X_CMSK_CTRL3, right.win[2].win_en, false); + rkisp_idx_write(dev, ISP3X_CMSK_CTRL3, right.win[2].win_en, ISP_UNITE_RIGHT, false); val = right.win[2].mode; - rkisp_next_write(dev, ISP3X_CMSK_CTRL6, val, false); + rkisp_idx_write(dev, ISP3X_CMSK_CTRL6, val, ISP_UNITE_RIGHT, false); } if (ctrl) { val = ISP_PACK_2SHORT(w, height); - rkisp_next_write(dev, ISP3X_CMSK_PIC_SIZE, val, false); + rkisp_idx_write(dev, ISP3X_CMSK_PIC_SIZE, val, ISP_UNITE_RIGHT, false); ctrl |= ISP3X_SW_CMSK_EN | ISP3X_SW_CMSK_ORDER_MODE; } - rkisp_next_write(dev, ISP3X_CMSK_CTRL0, ctrl, false); + rkisp_idx_write(dev, ISP3X_CMSK_CTRL0, ctrl, ISP_UNITE_RIGHT, false); - val = rkisp_next_read(dev, ISP3X_CMSK_CTRL0, true); + val = rkisp_idx_read(dev, ISP3X_CMSK_CTRL0, ISP_UNITE_RIGHT, true); if (dev->hw_dev->is_single && ((val & ISP32_SW_CMSK_EN_PATH) != (val & ISP32_SW_CMSK_EN_PATH_SHD))) - rkisp_next_write(dev, ISP3X_CMSK_CTRL0, val | ISP3X_SW_CMSK_FORCE_UPD, false); + rkisp_idx_write(dev, ISP3X_CMSK_CTRL0, val | ISP3X_SW_CMSK_FORCE_UPD, + ISP_UNITE_RIGHT, false); } static void rkisp_config_cmsk(struct rkisp_device *dev) @@ -1638,20 +1648,20 @@ static int rkisp_config_isp(struct rkisp_device *dev) struct ispsd_out_fmt *out_fmt; struct v4l2_rect *in_crop; struct rkisp_sensor_info *sensor; - bool is_unite = !!dev->hw_dev->unite; u32 isp_ctrl = 0; u32 irq_mask = 0; u32 signal = 0; u32 acq_mult = 0; u32 acq_prop = 0; u32 extend_line = 0; - u32 width; + u32 width, height; sensor = dev->active_sensor; in_fmt = &dev->isp_sdev.in_fmt; out_fmt = &dev->isp_sdev.out_fmt; in_crop = &dev->isp_sdev.in_crop; width = in_crop->width; + height = in_crop->height; if (in_fmt->fmt_type == FMT_BAYER) { acq_mult = 1; @@ -1741,8 +1751,10 @@ static int rkisp_config_isp(struct rkisp_device *dev) rkisp_unite_write(dev, CIF_ISP_ACQ_PROP, acq_prop, false); rkisp_unite_write(dev, CIF_ISP_ACQ_NR_FRAMES, 0, true); - if (is_unite) + if (dev->unite_div > ISP_UNITE_DIV1) width = width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + if (dev->unite_div == ISP_UNITE_DIV4) + height = height / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; /* Acquisition Size */ rkisp_unite_write(dev, CIF_ISP_ACQ_H_OFFS, acq_mult * in_crop->left, false); rkisp_unite_write(dev, CIF_ISP_ACQ_V_OFFS, in_crop->top, false); @@ -1754,11 +1766,11 @@ static int rkisp_config_isp(struct rkisp_device *dev) rkisp_unite_write(dev, CIF_ISP_OUT_H_SIZE, width, false); if (dev->cap_dev.stream[RKISP_STREAM_SP].interlaced) { - rkisp_unite_write(dev, CIF_ISP_ACQ_V_SIZE, in_crop->height / 2, false); - rkisp_unite_write(dev, CIF_ISP_OUT_V_SIZE, in_crop->height / 2, false); + rkisp_unite_write(dev, CIF_ISP_ACQ_V_SIZE, height / 2, false); + rkisp_unite_write(dev, CIF_ISP_OUT_V_SIZE, height / 2, false); } else { - rkisp_unite_write(dev, CIF_ISP_ACQ_V_SIZE, in_crop->height + extend_line, false); - rkisp_unite_write(dev, CIF_ISP_OUT_V_SIZE, in_crop->height + extend_line, false); + rkisp_unite_write(dev, CIF_ISP_ACQ_V_SIZE, height + extend_line, false); + rkisp_unite_write(dev, CIF_ISP_OUT_V_SIZE, height + extend_line, false); } /* interrupt mask */ @@ -2076,16 +2088,13 @@ static int rkisp_isp_stop(struct rkisp_device *dev) /* stop ISP */ val = rkisp_read(dev, CIF_ISP_CTRL, true); val &= ~(CIF_ISP_CTRL_ISP_INFORM_ENABLE | CIF_ISP_CTRL_ISP_ENABLE); - rkisp_write(dev, CIF_ISP_CTRL, val, true); + rkisp_unite_write(dev, CIF_ISP_CTRL, val, true); val = rkisp_read(dev, CIF_ISP_CTRL, true); val |= CIF_ISP_CTRL_ISP_CFG_UPD; - rkisp_write(dev, CIF_ISP_CTRL, val, true); + rkisp_unite_write(dev, CIF_ISP_CTRL, val, true); rkisp_clear_reg_cache_bits(dev, CIF_ISP_CTRL, CIF_ISP_CTRL_ISP_CFG_UPD); - if (hw->unite == ISP_UNITE_TWO) { - rkisp_next_write(dev, CIF_ISP_CTRL, val, true); - rkisp_next_clear_reg_cache_bits(dev, CIF_ISP_CTRL, CIF_ISP_CTRL_ISP_CFG_UPD); - } + readx_poll_timeout_atomic(readl, base + CIF_ISP_RIS, val, val & CIF_ISP_OFF, 20, 100); v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev, @@ -2113,9 +2122,7 @@ static int rkisp_isp_stop(struct rkisp_device *dev) writel(0, base + CIF_ISP_CSI0_MASK2); writel(0, base + CIF_ISP_CSI0_MASK3); } else if (dev->isp_ver >= ISP_V20) { - writel(0, base + CSI2RX_CSI2_RESETN); - if (hw->unite == ISP_UNITE_TWO) - rkisp_next_write(dev, CSI2RX_CSI2_RESETN, 0, true); + rkisp_unite_write(dev, CSI2RX_CSI2_RESETN, 0, true); } hw->is_dvfs = false; @@ -2623,6 +2630,8 @@ static void rkisp_isp_sd_try_crop(struct v4l2_subdev *sd, struct rkisp_isp_subdev *isp_sd = sd_to_isp_sd(sd); struct rkisp_device *dev = sd_to_isp_dev(sd); struct v4l2_rect in_crop = isp_sd->in_crop; + struct rkisp_hw_dev *hw = dev->hw_dev; + u32 size; crop->left = ALIGN(crop->left, 2); crop->width = ALIGN(crop->width, 2); @@ -2631,6 +2640,28 @@ static void rkisp_isp_sd_try_crop(struct v4l2_subdev *sd, /* update sensor info if sensor link be changed */ rkisp_update_sensor_info(dev); rkisp_align_sensor_resolution(dev, crop, true); + if (hw->unite == ISP_UNITE_TWO && hw->isp_ver == ISP_V30) { + dev->unite_div = ISP_UNITE_DIV2; + } else { + dev->unite_div = ISP_UNITE_DIV1; + switch (dev->isp_ver) { + case ISP_V30: + size = CIF_ISP_INPUT_W_MAX_V30 * CIF_ISP_INPUT_H_MAX_V30; + break; + case ISP_V32: + size = CIF_ISP_INPUT_W_MAX_V32 * CIF_ISP_INPUT_H_MAX_V32; + break; + case ISP_V32_L: + size = CIF_ISP_INPUT_W_MAX_V32_L * CIF_ISP_INPUT_H_MAX_V32_L; + break; + default: + return; + } + if (crop->width * crop->height > size * 2) + dev->unite_div = ISP_UNITE_DIV4; + else if (crop->width * crop->height > size) + dev->unite_div = ISP_UNITE_DIV2; + } } else if (pad == RKISP_ISP_PAD_SOURCE_PATH) { crop->left = clamp_t(u32, crop->left, 0, in_crop.width); crop->top = clamp_t(u32, crop->top, 0, in_crop.height); @@ -2695,8 +2726,10 @@ static int rkisp_isp_sd_get_selection(struct v4l2_subdev *sd, CIF_ISP_INPUT_H_MAX_V32_UNITE : CIF_ISP_INPUT_H_MAX_V32; break; case ISP_V32_L: - max_w = CIF_ISP_INPUT_W_MAX_V32_L; - max_h = CIF_ISP_INPUT_H_MAX_V32_L; + max_w = dev->hw_dev->unite ? + CIF_ISP_INPUT_W_MAX_V32_L_UNITE : CIF_ISP_INPUT_W_MAX_V32_L; + max_h = dev->hw_dev->unite ? + CIF_ISP_INPUT_H_MAX_V32_L_UNITE : CIF_ISP_INPUT_H_MAX_V32_L; break; default: max_w = CIF_ISP_INPUT_W_MAX; @@ -2956,8 +2989,9 @@ static void rkisp_rx_qbuf_online(struct rkisp_stream *stream, { struct rkisp_device *dev = stream->ispdev; u32 val = pool->buf.buff_addr[RKISP_PLANE_Y]; + u32 reg = stream->config->mi.y_base_ad_init; - rkisp_write(dev, stream->config->mi.y_base_ad_init, val, false); + rkisp_write(dev, reg, val, false); if (dev->hw_dev->unite == ISP_UNITE_TWO) { u32 offs = stream->out_fmt.width / 2 - RKMOUDLE_UNITE_EXTEND_PIXEL; @@ -2966,7 +3000,7 @@ static void rkisp_rx_qbuf_online(struct rkisp_stream *stream, else offs = offs * stream->out_isp_fmt.bpp[0] / 8; val += offs; - rkisp_next_write(dev, stream->config->mi.y_base_ad_init, val, false); + rkisp_idx_write(dev, reg, val, ISP_UNITE_RIGHT, false); } } @@ -3435,11 +3469,12 @@ static int rkisp_get_info(struct rkisp_device *dev, struct rkisp_isp_info *info) if (dev->is_bigmode) mode |= RKISP_ISP_BIGMODE; info->mode = mode; - if (dev->hw_dev->unite) + info->act_width = in_crop->width; + if (dev->unite_div > ISP_UNITE_DIV1) info->act_width = in_crop->width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; - else - info->act_width = in_crop->width; info->act_height = in_crop->height; + if (dev->unite_div == ISP_UNITE_DIV4) + info->act_height = in_crop->height / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; return 0; } @@ -3845,6 +3880,7 @@ int rkisp_register_isp_subdev(struct rkisp_device *isp_dev, goto err_cleanup_media_entity; } + isp_dev->unite_div = ISP_UNITE_DIV1; rkisp_isp_sd_init_default_fmt(isp_sdev); isp_dev->hdr.sensor = NULL; isp_dev->isp_state = ISP_STOP; diff --git a/drivers/media/platform/rockchip/isp/rkisp.h b/drivers/media/platform/rockchip/isp/rkisp.h index 76f8ce05e424..ebd37c274cfb 100644 --- a/drivers/media/platform/rockchip/isp/rkisp.h +++ b/drivers/media/platform/rockchip/isp/rkisp.h @@ -61,6 +61,8 @@ #define CIF_ISP_INPUT_H_MAX_V32_UNITE 2160 #define CIF_ISP_INPUT_W_MAX_V32_L 4224 #define CIF_ISP_INPUT_H_MAX_V32_L 3136 +#define CIF_ISP_INPUT_W_MAX_V32_L_UNITE 8192 +#define CIF_ISP_INPUT_H_MAX_V32_L_UNITE 6144 #define CIF_ISP_INPUT_W_MIN 272 #define CIF_ISP_INPUT_H_MIN 256 #define CIF_ISP_OUTPUT_W_MAX CIF_ISP_INPUT_W_MAX From bd99973c0a88fc9f548d5ff8eba194968d07cff4 Mon Sep 17 00:00:00 2001 From: Cai YiWei Date: Tue, 30 Jan 2024 15:04:37 +0800 Subject: [PATCH 13/34] media: rockchip: isp: version v2.5.0 Change-Id: Ic885032c2e177a714cacfb0609032366e66aac3c Signed-off-by: Cai YiWei --- drivers/media/platform/rockchip/isp/version.h | 21 +++++++++++++++++++ include/uapi/linux/rk-isp2-config.h | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/rockchip/isp/version.h b/drivers/media/platform/rockchip/isp/version.h index 8981e4709131..918ee8a8d9e9 100644 --- a/drivers/media/platform/rockchip/isp/version.h +++ b/drivers/media/platform/rockchip/isp/version.h @@ -483,6 +483,27 @@ * 20.more time to wait isp end * 21.add mode for rv1106 suspend without rtt * 22.fix is_on false cause pm isp die + * + * v2.5.0 (AIQ v5.5.0) + * 1.wrap mode first done don't send event + * 2.fix 4k and dual_sensor pm oneframe error + * 3.isp32 using ktime_get_boottime_ns + * 4.fix wait timeout with thunderboot + * 5.add buf cnt info to procfs + * 6.sync irq_ends + * 7.fix resume mi no enable + * 8.fix isp32 lost buf + * 9.frame start to check and config next buf + * 10.fix isp stop to enable isp ctrl + * 11.fix isp32 buf no update to hw + * 12.add rkisp_buf_dbg + * 13.fix isp stop to read stats buf + * 14.support multiple wrap + * 15.dvbm buf support from rockit + * 16.add RKISP_CMD_SET_TB_HEAD_V32 API + * 17.add ioctl to get bay3d buf + * 18.fix isp32 lite frame buffer data read + * 19.support 8k for isp32 lite */ #define RKISP_DRIVER_VERSION RKISP_API_VERSION diff --git a/include/uapi/linux/rk-isp2-config.h b/include/uapi/linux/rk-isp2-config.h index 7ea04e6f9477..3950cf3394d8 100644 --- a/include/uapi/linux/rk-isp2-config.h +++ b/include/uapi/linux/rk-isp2-config.h @@ -11,7 +11,7 @@ #include #include -#define RKISP_API_VERSION KERNEL_VERSION(2, 4, 0) +#define RKISP_API_VERSION KERNEL_VERSION(2, 5, 0) /****************ISP SUBDEV IOCTL*****************************/ From 8f8a13a24d69f44d72134535ceda6423572a7841 Mon Sep 17 00:00:00 2001 From: Tony Xie Date: Wed, 13 Sep 2023 15:50:06 +0800 Subject: [PATCH 14/34] irqchip/gicv3: support config amp os irqs Signed-off-by: Tony Xie Change-Id: I0abcf9fd44514b1aac06aa6977df2859ebd01459 --- drivers/irqchip/irq-gic-v3.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 192a9b1be185..ec162f3c25ba 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -37,6 +37,10 @@ #include "irq-gic-common.h" +#ifdef CONFIG_ROCKCHIP_AMP +#include +#endif + #define GICD_INT_NMI_PRI (GICD_INT_DEF_PRI & ~0x80) #define FLAGS_WORKAROUND_GICR_WAKER_MSM8996 (1ULL << 0) @@ -368,6 +372,10 @@ static void gic_poke_irq(struct irq_data *d, u32 offset) static void gic_mask_irq(struct irq_data *d) { +#ifdef CONFIG_ROCKCHIP_AMP + if (rockchip_amp_check_amp_irq(gic_irq(d))) + return; +#endif gic_poke_irq(d, GICD_ICENABLER); } @@ -388,6 +396,10 @@ static void gic_eoimode1_mask_irq(struct irq_data *d) static void gic_unmask_irq(struct irq_data *d) { +#ifdef CONFIG_ROCKCHIP_AMP + if (rockchip_amp_check_amp_irq(gic_irq(d))) + return; +#endif gic_poke_irq(d, GICD_ISENABLER); } @@ -565,6 +577,10 @@ static bool gic_arm64_erratum_2941627_needed(struct irq_data *d) static void gic_eoi_irq(struct irq_data *d) { +#ifdef CONFIG_ROCKCHIP_AMP + if (rockchip_amp_check_amp_irq(gic_irq(d))) + return; +#endif write_gicreg(gic_irq(d), ICC_EOIR1_EL1); isb(); @@ -849,8 +865,18 @@ static void __init gic_dist_init(void) * enabled. */ affinity = gic_mpidr_to_affinity(cpu_logical_map(smp_processor_id())); - for (i = 32; i < GIC_LINE_NR; i++) + for (i = 32; i < GIC_LINE_NR; i++) { +#ifdef CONFIG_ROCKCHIP_AMP + u64 affinity_amp; + + if (rockchip_amp_need_init_amp_irq(i)) { + affinity_amp = rockchip_amp_get_irq_aff(i); + gic_write_irouter(affinity_amp, base + GICD_IROUTER + i * 8); + continue; + } +#endif gic_write_irouter(affinity, base + GICD_IROUTER + i * 8); + } for (i = 0; i < GIC_ESPI_NR; i++) gic_write_irouter(affinity, base + GICD_IROUTERnE + i * 8); @@ -1281,6 +1307,10 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, int enabled; u64 val; +#ifdef CONFIG_ROCKCHIP_AMP + if (rockchip_amp_check_amp_irq(gic_irq(d))) + return -EINVAL; +#endif if (force) cpu = cpumask_first(mask_val); else @@ -1880,6 +1910,9 @@ static int __init gic_init_bases(void __iomem *dist_base, gic_update_rdist_properties(); +#ifdef CONFIG_ROCKCHIP_AMP + rockchip_amp_get_gic_info(GIC_LINE_NR, GIC_V3); +#endif gic_dist_init(); gic_cpu_init(); gic_smp_init(); From 3bdcd9e58245e62561cc97b90e8615454b7315ea Mon Sep 17 00:00:00 2001 From: Tony Xie Date: Wed, 25 Oct 2023 10:40:40 +0800 Subject: [PATCH 15/34] soc: rockchip: amp: support init gpio group irqs for amp Signed-off-by: Tony Xie Change-Id: If152a54aa00b18aedf919b6053fb6d2fff853b07 --- drivers/soc/rockchip/rockchip_amp.c | 219 +++++++++++++++++++++------- 1 file changed, 168 insertions(+), 51 deletions(-) diff --git a/drivers/soc/rockchip/rockchip_amp.c b/drivers/soc/rockchip/rockchip_amp.c index 6f5bdc678756..b3a744036987 100644 --- a/drivers/soc/rockchip/rockchip_amp.c +++ b/drivers/soc/rockchip/rockchip_amp.c @@ -26,6 +26,7 @@ #define GPIO_GROUP_PRIO_MAX 3 #define MAX_GIC_SPI_NUM (1020) +#define AMP_GIC_INFO_DUMP 0 #define AMP_GIC_DBG(fmt, arg...) do { if (0) { pr_warn(fmt, ##arg); } } while (0) enum amp_cpu_ctrl_status { @@ -39,6 +40,12 @@ enum amp_cpu_ctrl_status { #define AMP_FLAG_CPU_EL2_HYP BIT(2) #define AMP_FLAG_CPU_ARM32_T BIT(3) +enum { + GPIO_IRQ_GROUP_DISABLE = 0x0, + GPIO_IRQ_GROUP_EN_BANK_TYPE = 0x1, + GPIO_IRQ_GROUP_EN_GROUP_TYPE = 0x2, +}; + struct rkamp_device { struct device *dev; struct clk_bulk_data *clks; @@ -54,14 +61,27 @@ static struct { u64 cpu_id; } cpu_boot_info[CONFIG_NR_CPUS]; -struct amp_gpio_group_s { - u32 bank_id; +struct amp_gpio_group_prio_group_info { u32 prio; u64 irq_aff[AMP_AFF_MAX_CPU]; u32 irq_id[AMP_AFF_MAX_CPU]; u32 en[AMP_AFF_MAX_CPU]; }; +struct amp_gpio_group_bank_type_info { + u32 hw_irq; + u32 prio; + u64 aff; +}; + +struct amp_gpio_group_info_t { + u32 group_en; + u32 bank_id; + struct amp_gpio_group_bank_type_info bank_type_info; + struct amp_gpio_group_prio_group_info prio_group[GPIO_GROUP_PRIO_MAX]; + +}; + struct amp_irq_cfg_s { u64 aff; u32 prio; @@ -78,7 +98,7 @@ static struct amp_gic_ctrl_s { u32 flag; } aff_to_cpumask[AMP_AFF_MAX_CLUSTER][AMP_AFF_MAX_CPU]; struct amp_irq_cfg_s irqs_cfg[MAX_GIC_SPI_NUM]; - struct amp_gpio_group_s gpio_grp[GPIO_BANK_NUM][GPIO_GROUP_PRIO_MAX]; + struct amp_gpio_group_info_t gpio_grp[GPIO_BANK_NUM]; u32 gpio_banks; } amp_ctrl; @@ -304,60 +324,103 @@ u64 rockchip_amp_get_irq_aff(u32 irq) return amp_ctrl.irqs_cfg[irq].aff; } -static int gic_amp_get_gpio_prio_group_info(struct device_node *np, - struct amp_gic_ctrl_s *amp_ctrl, - int prio_id) +static int amp_gic_get_gpio_group_bank_type_config(struct device_node *np, + struct amp_gic_ctrl_s *amp_ctrl, + struct amp_gpio_group_info_t *gpio_grp) { - u32 gpio_bank, prio, irq_id; + u32 prio, irq; u64 irq_aff; - int i, count0, count1; - struct amp_gpio_group_s *gpio_grp; + struct amp_gpio_group_bank_type_info *bank_type_info; struct amp_irq_cfg_s *irqs_cfg; - if (prio_id >= GPIO_GROUP_PRIO_MAX) + bank_type_info = &gpio_grp->bank_type_info; + if (of_property_read_u32_array(np, "hw-irq", &irq, 1)) return -EINVAL; - if (of_property_read_u32_array(np, "gpio-bank", &gpio_bank, 1)) + if (of_property_read_u64_array(np, "hw-irq-cpu-aff", &irq_aff, 1)) return -EINVAL; - if (gpio_bank >= amp_ctrl->gpio_banks) - return -EINVAL; - - gpio_grp = &_ctrl->gpio_grp[gpio_bank][prio_id]; if (of_property_read_u32_array(np, "prio", &prio, 1)) return -EINVAL; - if (gpio_bank >= GPIO_BANK_NUM) + bank_type_info->aff = irq_aff; + bank_type_info->hw_irq = irq; + bank_type_info->prio = prio; + + irqs_cfg = &_ctrl->irqs_cfg[irq]; + + irqs_cfg->prio = prio; + irqs_cfg->aff = irq_aff; + + if (amp_ctrl->gic_version == GIC_V2) { + irqs_cfg->cpumask = amp_get_cpumask_bit(irq_aff); + if (!irqs_cfg->cpumask) { + pr_err(" %s: get cpumask error\n", __func__); + return -EINVAL; + } + } + irqs_cfg->amp_flag = 1; + + AMP_GIC_DBG(" %s bank-%d: hw-irq-%d aff-%llx(%x) prio-%x flag-%d\n", + __func__, gpio_grp->bank_id, irq, irqs_cfg->aff, + irqs_cfg->cpumask, irqs_cfg->prio, irqs_cfg->amp_flag); + + return 0; +} + +static int gic_amp_get_gpio_prio_group_config(struct device_node *np, + struct amp_gic_ctrl_s *amp_ctrl, + struct amp_gpio_group_info_t *gpio_grp, + int prio_id) +{ + u32 prio, irq_id; + u64 irq_aff; + int i, count0, count1, count2; + struct amp_irq_cfg_s *irqs_cfg; + struct amp_gpio_group_prio_group_info *prio_grp; + + if (prio_id >= GPIO_GROUP_PRIO_MAX) return -EINVAL; - AMP_GIC_DBG("%s: gpio-%d, group prio:%d-%x\n", - __func__, gpio_bank, prio_id, prio); - - count0 = of_property_count_u32_elems(np, "girq-id"); - count1 = of_property_count_u64_elems(np, "girq-aff"); - - if (count0 != count1) + if (of_property_read_u32_array(np, "group-prio", &prio, 1)) return -EINVAL; - gpio_grp->prio = prio; + prio_grp = &gpio_grp->prio_group[prio_id]; + prio_grp->prio = prio; + + count0 = of_property_count_u32_elems(np, "group-irq-id"); + count1 = of_property_count_u64_elems(np, "group-irq-aff"); + count2 = of_property_count_u32_elems(np, "group-irq-en"); + + AMP_GIC_DBG(" %s: bank-%d, group prio [%d]=0x%x\n", + __func__, gpio_grp->bank_id, prio_id, prio); + + if (!(count0 == count1 && count0 == count2 && count0)) { + pr_err("%s: group-irq count is error(%d %d %d)\n", + __func__, count0, count1, count2); + return -EINVAL; + } + + if (count0 >= AMP_AFF_MAX_CPU) + pr_err("%s: prio group is overflow\n", __func__); for (i = 0; i < count0; i++) { - of_property_read_u32_index(np, "girq-id", i, &irq_id); - gpio_grp->irq_id[i] = irq_id; - of_property_read_u64_index(np, "girq-aff", i, &irq_aff); + of_property_read_u32_index(np, "group-irq-id", i, &irq_id); + prio_grp->irq_id[i] = irq_id; - gpio_grp->irq_aff[i] = irq_aff; + of_property_read_u64_index(np, "group-irq-aff", i, &irq_aff); + prio_grp->irq_aff[i] = irq_aff; - of_property_read_u32_index(np, "girq-en", i, &gpio_grp->en[i]); + of_property_read_u32_index(np, "group-irq-en", i, &prio_grp->en[i]); irqs_cfg = &_ctrl->irqs_cfg[irq_id]; - AMP_GIC_DBG(" %s: group cpu-%d, irq-%d: prio-%x, aff-%llx en-%d\n", - __func__, i, gpio_grp->irq_id[i], gpio_grp->prio, - gpio_grp->irq_aff[i], gpio_grp->en[i]); + AMP_GIC_DBG(" %s: cpu_idx-%d irq-%d: prio-%x aff-%llx grp_en-%d\n", + __func__, i, prio_grp->irq_id[i], prio_grp->prio, + prio_grp->irq_aff[i], prio_grp->en[i]); - if (gpio_grp->en[i]) { - irqs_cfg->prio = gpio_grp->prio; + if (prio_grp->en[i]) { + irqs_cfg->prio = prio_grp->prio; irqs_cfg->aff = irq_aff; if (amp_ctrl->gic_version == GIC_V2) { irqs_cfg->cpumask = amp_get_cpumask_bit(irq_aff); @@ -369,17 +432,17 @@ static int gic_amp_get_gpio_prio_group_info(struct device_node *np, irqs_cfg->amp_flag = 1; } - AMP_GIC_DBG(" %s: prio-%x aff-%llx cpumaks-%x flag-%d\n", - __func__, irqs_cfg->prio, irqs_cfg->aff, - irqs_cfg->cpumask, irqs_cfg->amp_flag); + AMP_GIC_DBG(" %s irq-%d: prio-%x aff-%llx(%x) flag-%d\n", + __func__, prio_grp->irq_id[i], irqs_cfg->prio, + irqs_cfg->aff, irqs_cfg->cpumask, irqs_cfg->amp_flag); } return 0; } -static int gic_amp_gpio_group_get_info(struct device_node *group_node, - struct amp_gic_ctrl_s *amp_ctrl, - int idx) +static int amp_gic_get_gpio_group_type_config(struct device_node *group_node, + struct amp_gic_ctrl_s *amp_ctrl, + struct amp_gpio_group_info_t *gpio_grp) { int i = 0; struct device_node *node; @@ -388,8 +451,8 @@ static int gic_amp_gpio_group_get_info(struct device_node *group_node, for_each_available_child_of_node(group_node, node) { if (i >= GPIO_GROUP_PRIO_MAX) break; - if (!gic_amp_get_gpio_prio_group_info(node, amp_ctrl, - i)) { + if (!gic_amp_get_gpio_prio_group_config(node, amp_ctrl, + gpio_grp, i)) { i++; } } @@ -397,27 +460,64 @@ static int gic_amp_gpio_group_get_info(struct device_node *group_node, return 0; } -static void gic_of_get_gpio_group(struct device_node *np, - struct amp_gic_ctrl_s *amp_ctrl) +static void amp_gic_get_gpio_group_config(struct device_node *node, + struct amp_gic_ctrl_s *amp_ctrl) +{ + struct device_node *bank_node; + struct amp_gpio_group_info_t *gpio_grp; + u32 gpio_bank, group_en; + + if (of_property_read_u32_array(node, "gpio-bank-id", &gpio_bank, 1)) + return; + + if (gpio_bank >= amp_ctrl->gpio_banks) + return; + + if (of_property_read_u32_array(node, "group-irq-en", &group_en, 1)) + return; + + gpio_grp = &_ctrl->gpio_grp[gpio_bank]; + gpio_grp->bank_id = gpio_bank; + + gpio_grp->group_en = group_en; + + AMP_GIC_DBG("%s: bank-%d group-en-%d\n", __func__, gpio_bank, group_en); + + if (group_en == GPIO_IRQ_GROUP_EN_BANK_TYPE) { + bank_node = of_get_child_by_name(node, "bank-type-cfg"); + if (!bank_node) { + pr_err("%s: group_irq_en from dtsi is error\n", __func__); + return; + } + amp_gic_get_gpio_group_bank_type_config(bank_node, amp_ctrl, gpio_grp); + of_node_put(bank_node); + } else if (group_en == GPIO_IRQ_GROUP_EN_GROUP_TYPE) { + amp_gic_get_gpio_group_type_config(node, amp_ctrl, gpio_grp); + } +} + +static void amp_gic_get_gpios_group_config(struct device_node *np, + struct amp_gic_ctrl_s *amp_ctrl) { struct device_node *gpio_group_node, *node; - int i = 0; if (of_property_read_u32_array(np, "gpio-group-banks", &_ctrl->gpio_banks, 1)) return; + if (amp_ctrl->gpio_banks >= GPIO_BANK_NUM) { + pr_err("%s: gpio_banks is overflow\n", __func__); + return; + } + gpio_group_node = of_get_child_by_name(np, "gpio-group"); if (gpio_group_node) { for_each_available_child_of_node(gpio_group_node, node) { - if (i >= amp_ctrl->gpio_banks) - break; - if (!gic_amp_gpio_group_get_info(node, amp_ctrl, i)) - i++; + amp_gic_get_gpio_group_config(node, amp_ctrl); } + of_node_put(gpio_group_node); } - of_node_put(gpio_group_node); } static int amp_gic_get_cpumask(struct device_node *np, struct amp_gic_ctrl_s *amp_ctrl) @@ -518,6 +618,22 @@ static void amp_gic_get_irqs_config(struct device_node *np, } } +static void amp_gic_irqs_config_dump(struct amp_gic_ctrl_s *amp_ctrl) +{ + int irq; + struct amp_irq_cfg_s *irqs_cfg; + +#if !AMP_GIC_INFO_DUMP + return; +#endif + irqs_cfg = amp_ctrl->irqs_cfg; + for (irq = 32; irq < MAX_GIC_SPI_NUM; irq++) { + AMP_GIC_DBG(" %s: irq-%d aff-%llx(%x) prio-%x flag-%d\n", + __func__, irq, irqs_cfg[irq].aff, irqs_cfg[irq].cpumask, + irqs_cfg[irq].prio, irqs_cfg[irq].amp_flag); + } +} + void rockchip_amp_get_gic_info(u32 spis_num, enum gic_type gic_version) { struct device_node *np; @@ -534,8 +650,9 @@ void rockchip_amp_get_gic_info(u32 spis_num, enum gic_type gic_version) goto exit; } - gic_of_get_gpio_group(np, &_ctrl); + amp_gic_get_gpios_group_config(np, &_ctrl); amp_gic_get_irqs_config(np, &_ctrl); + amp_gic_irqs_config_dump(&_ctrl); exit: of_node_put(np); From 80d2eb708083228dd15b07ec10db502eb17fd708 Mon Sep 17 00:00:00 2001 From: Zain Wang Date: Thu, 22 Feb 2024 11:51:58 +0800 Subject: [PATCH 16/34] arm64: dts: rockchip: rk3308-amp: define CPU_GET_AFFINITY Signed-off-by: Zain Wang Change-Id: I7676d07e010a6ef6643b4cdc269379ad39aa806a --- arch/arm64/boot/dts/rockchip/rk3308b-amp.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3308b-amp.dtsi b/arch/arm64/boot/dts/rockchip/rk3308b-amp.dtsi index 5a4548d8149d..171424d55d1c 100644 --- a/arch/arm64/boot/dts/rockchip/rk3308b-amp.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3308b-amp.dtsi @@ -5,6 +5,8 @@ #include +#define CPU_GET_AFFINITY(cpu, cluster) ((cpu) << 0 | ((cluster) << 8)) + / { rockchip_amp: rockchip-amp { compatible = "rockchip,amp"; From faf92ec69026b59c718f92d7e0de630d24f66e00 Mon Sep 17 00:00:00 2001 From: Zain Wang Date: Thu, 22 Feb 2024 11:53:38 +0800 Subject: [PATCH 17/34] arm64: dts: rockchip: rk3562-amp: define CPU_GET_AFFINITY Signed-off-by: Zain Wang Change-Id: Ia5144a800de1dc014269969f1eadbf67a373827c --- arch/arm64/boot/dts/rockchip/rk3562-amp.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3562-amp.dtsi b/arch/arm64/boot/dts/rockchip/rk3562-amp.dtsi index e2872709e2b7..a7d3fdf166b3 100644 --- a/arch/arm64/boot/dts/rockchip/rk3562-amp.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3562-amp.dtsi @@ -5,6 +5,8 @@ #include +#define CPU_GET_AFFINITY(cpu, cluster) ((cpu) << 0 | ((cluster) << 8)) + / { rockchip_amp: rockchip-amp { compatible = "rockchip,amp"; From 11b3eda762d2fd2f5a4d317c2eff2227ed751fc1 Mon Sep 17 00:00:00 2001 From: Weiwen Chen Date: Thu, 12 Oct 2023 10:19:46 +0800 Subject: [PATCH 18/34] ARM: dts: rockchip: add rv1106g-evb2-v12-spi-nand-tb.dts Signed-off-by: Weiwen Chen Change-Id: I8090c6b2e95aa956cbe36c5aa344b9858c689094 --- arch/arm/boot/dts/Makefile | 1 + .../boot/dts/rv1106g-evb2-v12-spi-nand-tb.dts | 40 +++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 arch/arm/boot/dts/rv1106g-evb2-v12-spi-nand-tb.dts diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index 2151bee625f5..17ea10457c80 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -1012,6 +1012,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \ rv1106g-evb2-v12-nofastae-emmc.dtb \ rv1106g-evb2-v12-nofastae-spi-nand.dtb \ rv1106g-evb2-v12-nofastae-spi-nor.dtb \ + rv1106g-evb2-v12-spi-nand-tb.dtb \ rv1106g-evb2-v12-wakeup.dtb \ rv1106g-smart-door-lock-rmsl-v10.dtb \ rv1106g-smart-door-lock-rmsl-v12.dtb \ diff --git a/arch/arm/boot/dts/rv1106g-evb2-v12-spi-nand-tb.dts b/arch/arm/boot/dts/rv1106g-evb2-v12-spi-nand-tb.dts new file mode 100644 index 000000000000..8ac396d440ed --- /dev/null +++ b/arch/arm/boot/dts/rv1106g-evb2-v12-spi-nand-tb.dts @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2024 Rockchip Electronics Co., Ltd. + */ + +/dts-v1/; + +#include "rv1106g-evb2-v10.dts" + +/ { + model = "Rockchip RV1106G EVB2 V12 Board On Spi Nand"; + compatible = "rockchip,rv1106g-evb2-v12", "rockchip,rv1106"; + + chosen { + bootargs = "loglevel=0 rootfstype=erofs rootflags=dax console=ttyFIQ0 root=/dev/rd0 snd_soc_core.prealloc_buffer_size_kbytes=16 coherent_pool=0 driver_async_probe=dwmmc_rockchip"; + }; +}; + +/delete-node/ &thunder_boot_spi_nor; + +&emmc { + status = "disabled"; +}; + +&rkisp_thunderboot { + /* reg's offset MUST match with RTOS */ + /* + * vicap, capture raw10, ceil(w*10/8/256)*256*h *4(buf num) + * e.g. 2304x1296: 0xf30000 + */ + reg = <0x00860000 0xf30000>; +}; + +&ramdisk_r { + reg = <0x1790000 (20 * 0x00100000)>; +}; + +&ramdisk_c { + reg = <0x2b90000 (10 * 0x00100000)>; +}; From dc7bc9ebe71b2c28b1888e1ea3eb5e2fdb0ccb4b Mon Sep 17 00:00:00 2001 From: Tony Xie Date: Wed, 25 Oct 2023 11:50:18 +0800 Subject: [PATCH 19/34] dt-bindings: soc: rockchip-amp: remove CPU_GET_AFFINITY() to dtsi file Signed-off-by: Tony Xie Change-Id: I472ba149c529f70520963711147ef25d1905bf53 --- include/dt-bindings/soc/rockchip-amp.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/dt-bindings/soc/rockchip-amp.h b/include/dt-bindings/soc/rockchip-amp.h index 0681e92ef4da..1dd55a0dec96 100644 --- a/include/dt-bindings/soc/rockchip-amp.h +++ b/include/dt-bindings/soc/rockchip-amp.h @@ -2,6 +2,5 @@ #ifndef _DT_BINDINGS_SOC_ROCKCHIP_AMP_H #define _DT_BINDINGS_SOC_ROCKCHIP_AMP_H -#define CPU_GET_AFFINITY(cpu, cluster) ((cpu) << 0 | ((cluster) << 8)) #define GIC_AMP_IRQ_CFG_ROUTE(_irq, _prio, _aff) (_irq) (_prio) (_aff) #endif From 68598ecbf31fa8c8d9e2fced7722f1e3dd6b4d5c Mon Sep 17 00:00:00 2001 From: Jianwei Fan Date: Thu, 22 Feb 2024 11:46:35 +0800 Subject: [PATCH 20/34] media: i2c: lt8668sx: fix kernel-6.1 compile errors Signed-off-by: Jianwei Fan Change-Id: I3f06b045ff2f1d23be06248eb53b642ddf711f08 --- drivers/media/i2c/lt8668sx.c | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/drivers/media/i2c/lt8668sx.c b/drivers/media/i2c/lt8668sx.c index 8d5b63a7e39c..005475b1cec6 100644 --- a/drivers/media/i2c/lt8668sx.c +++ b/drivers/media/i2c/lt8668sx.c @@ -107,7 +107,7 @@ static const s64 link_freq_cphy_rgb_menu_items[] = { }; struct lt8668sx { - struct v4l2_fwnode_bus_mipi_csi2 bus; + struct v4l2_mbus_config_mipi_csi2 bus; struct v4l2_subdev sd; struct media_pad pad; struct v4l2_ctrl_handler hdl; @@ -960,15 +960,9 @@ static int lt8668sx_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad, struct v4l2_mbus_config *cfg) { struct lt8668sx *lt8668sx = to_lt8668sx(sd); - u32 lane_num = lt8668sx->bus_cfg.bus.mipi_csi2.num_data_lanes; - u32 val = 0; - - val = 1 << (lane_num - 1) | - V4L2_MBUS_CSI2_CHANNEL_0 | - V4L2_MBUS_CSI2_CONTINUOUS_CLOCK; cfg->type = lt8668sx->bus_cfg.bus_type; - cfg->flags = val; + cfg->bus.mipi_csi2 = lt8668sx->bus_cfg.bus.mipi_csi2; return 0; } @@ -993,7 +987,7 @@ static int lt8668sx_s_stream(struct v4l2_subdev *sd, int on) } static int lt8668sx_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { struct lt8668sx *lt8668sx = to_lt8668sx(sd); @@ -1011,7 +1005,7 @@ static int lt8668sx_enum_mbus_code(struct v4l2_subdev *sd, } static int lt8668sx_enum_frame_sizes(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { struct lt8668sx *lt8668sx = to_lt8668sx(sd); @@ -1031,7 +1025,7 @@ static int lt8668sx_enum_frame_sizes(struct v4l2_subdev *sd, } static int lt8668sx_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct lt8668sx *lt8668sx = to_lt8668sx(sd); @@ -1066,7 +1060,7 @@ static int lt8668sx_get_fmt(struct v4l2_subdev *sd, } static int lt8668sx_enum_frame_interval(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_interval_enum *fie) { struct lt8668sx *lt8668sx = to_lt8668sx(sd); @@ -1084,7 +1078,7 @@ static int lt8668sx_enum_frame_interval(struct v4l2_subdev *sd, } static int lt8668sx_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct lt8668sx *lt8668sx = to_lt8668sx(sd); @@ -1092,7 +1086,7 @@ static int lt8668sx_set_fmt(struct v4l2_subdev *sd, /* is overwritten by get_fmt */ u32 code = format->format.code; - int ret = lt8668sx_get_fmt(sd, cfg, format); + int ret = lt8668sx_get_fmt(sd, sd_state, format); format->format.code = code; @@ -1279,7 +1273,7 @@ static int lt8668sx_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { struct lt8668sx *lt8668sx = to_lt8668sx(sd); struct v4l2_mbus_framefmt *try_fmt = - v4l2_subdev_get_try_format(sd, fh->pad, 0); + v4l2_subdev_get_try_format(sd, fh->state, 0); const struct lt8668sx_mode *def_mode = <8668sx->support_modes[0]; mutex_lock(<8668sx->confctl_mutex); @@ -1700,7 +1694,7 @@ static int lt8668sx_probe(struct i2c_client *client, snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s %s", lt8668sx->module_index, facing, LT8668SX_NAME, dev_name(sd->dev)); - err = v4l2_async_register_subdev_sensor_common(sd); + err = v4l2_async_register_subdev_sensor(sd); if (err < 0) { v4l2_err(sd, "v4l2 register subdev failed! err:%d\n", err); goto err_clean_entity; @@ -1735,7 +1729,7 @@ err_work_queues: return err; } -static int lt8668sx_remove(struct i2c_client *client) +static void lt8668sx_remove(struct i2c_client *client) { struct v4l2_subdev *sd = i2c_get_clientdata(client); struct lt8668sx *lt8668sx = to_lt8668sx(sd); @@ -1754,8 +1748,6 @@ static int lt8668sx_remove(struct i2c_client *client) v4l2_ctrl_handler_free(<8668sx->hdl); mutex_destroy(<8668sx->confctl_mutex); clk_disable_unprepare(lt8668sx->xvclk); - - return 0; } #if IS_ENABLED(CONFIG_OF) From ecf409630c9bb4b64460a95e7763ecb73281a715 Mon Sep 17 00:00:00 2001 From: Lan Honglin Date: Thu, 22 Feb 2024 14:25:42 +0800 Subject: [PATCH 21/34] media: i2c: add sc3336p sensor driver Change-Id: I917458b8c8bb9f8d85d203d545ec11015c98b2e5 Signed-off-by: Lan Honglin --- drivers/media/i2c/Kconfig | 10 + drivers/media/i2c/Makefile | 1 + drivers/media/i2c/sc3336p.c | 1921 +++++++++++++++++++++++++++++++++++ 3 files changed, 1932 insertions(+) create mode 100644 drivers/media/i2c/sc3336p.c diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index 9185d980e2bf..813d535154a9 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -2172,6 +2172,16 @@ config VIDEO_SC3336 This is a Video4Linux2 sensor driver for the SmartSens SC3336 camera. +config VIDEO_SC3336P + tristate "SmartSens SC3336P sensor support" + depends on I2C && VIDEO_V4L2 + select MEDIA_CONTROLLER + select VIDEO_V4L2_SUBDEV_API + select V4L2_FWNODE + help + This is a Video4Linux2 sensor driver for the SmartSens + SC3336P camera. + config VIDEO_SC3338 tristate "SmartSens SC3338 sensor support" depends on I2C && VIDEO_V4L2 diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile index 99a67255a5ed..1e55e5d5be80 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile @@ -146,6 +146,7 @@ obj-$(CONFIG_VIDEO_SC2336) += sc2336.o obj-$(CONFIG_VIDEO_SC2355) += sc2355.o obj-$(CONFIG_VIDEO_SC301IOT) += sc301iot.o obj-$(CONFIG_VIDEO_SC3336) += sc3336.o +obj-$(CONFIG_VIDEO_SC3336P) += sc3336p.o obj-$(CONFIG_VIDEO_SC3338) += sc3338.o obj-$(CONFIG_VIDEO_SC401AI) += sc401ai.o obj-$(CONFIG_VIDEO_SC4210) += sc4210.o diff --git a/drivers/media/i2c/sc3336p.c b/drivers/media/i2c/sc3336p.c new file mode 100644 index 000000000000..efa3b68d5e32 --- /dev/null +++ b/drivers/media/i2c/sc3336p.c @@ -0,0 +1,1921 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * sc3336p driver + * + * Copyright (C) 2020 Rockchip Electronics Co., Ltd. + * + * V0.0X01.0X01 first version + */ + +//#define DEBUG +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../platform/rockchip/isp/rkisp_tb_helper.h" +#include "cam-tb-setup.h" +#include "cam-sleep-wakeup.h" + +#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x01) + +#ifndef V4L2_CID_DIGITAL_GAIN +#define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN +#endif + +#define SC3336P_LANES 2 +#define SC3336P_BITS_PER_SAMPLE 10 +#define SC3336P_LINK_FREQ_255M 127500000 +#define SC3336P_LINK_FREQ_495M 247500000 + +#define PIXEL_RATE_WITH_255M_10BIT (SC3336P_LINK_FREQ_255M * 2 * \ + SC3336P_LANES / SC3336P_BITS_PER_SAMPLE) +#define PIXEL_RATE_WITH_495M_10BIT (SC3336P_LINK_FREQ_495M * 2 * \ + SC3336P_LANES / SC3336P_BITS_PER_SAMPLE) + +#define SC3336P_XVCLK_FREQ 24000000 + +#define CHIP_ID 0x9c41 +#define SC3336P_REG_CHIP_ID 0x3107 + +#define SC3336P_REG_CTRL_MODE 0x0100 +#define SC3336P_MODE_SW_STANDBY 0x0 +#define SC3336P_MODE_STREAMING BIT(0) + +#define SC3336P_REG_EXPOSURE_H 0x3e00 +#define SC3336P_REG_EXPOSURE_M 0x3e01 +#define SC3336P_REG_EXPOSURE_L 0x3e02 +#define SC3336P_EXPOSURE_MIN 1 +#define SC3336P_EXPOSURE_STEP 1 +#define SC3336P_VTS_MAX 0x7fff + +#define SC3336P_REG_DIG_GAIN 0x3e06 +#define SC3336P_REG_DIG_FINE_GAIN 0x3e07 +#define SC3336P_REG_ANA_GAIN 0x3e09 +#define SC3336P_GAIN_MIN 0x0080 +#define SC3336P_GAIN_MAX (99614) //48.64*16*128 +#define SC3336P_GAIN_STEP 1 +#define SC3336P_GAIN_DEFAULT 0x80 + + +#define SC3336P_REG_GROUP_HOLD 0x3812 +#define SC3336P_GROUP_HOLD_START 0x00 +#define SC3336P_GROUP_HOLD_END 0x30 + +#define SC3336P_REG_TEST_PATTERN 0x4501 +#define SC3336P_TEST_PATTERN_BIT_MASK BIT(3) + +#define SC3336P_REG_VTS_H 0x320e +#define SC3336P_REG_VTS_L 0x320f + +#define SC3336P_FLIP_MIRROR_REG 0x3221 + +#define SC3336P_FETCH_EXP_H(VAL) (((VAL) >> 12) & 0xF) +#define SC3336P_FETCH_EXP_M(VAL) (((VAL) >> 4) & 0xFF) +#define SC3336P_FETCH_EXP_L(VAL) (((VAL) & 0xF) << 4) + +#define SC3336P_FETCH_AGAIN_H(VAL) (((VAL) >> 8) & 0x03) +#define SC3336P_FETCH_AGAIN_L(VAL) ((VAL) & 0xFF) + +#define SC3336P_FETCH_MIRROR(VAL, ENABLE) (ENABLE ? VAL | 0x06 : VAL & 0xf9) +#define SC3336P_FETCH_FLIP(VAL, ENABLE) (ENABLE ? VAL | 0x60 : VAL & 0x9f) + +#define REG_DELAY 0xFFFE +#define REG_NULL 0xFFFF + +#define SC3336P_REG_VALUE_08BIT 1 +#define SC3336P_REG_VALUE_16BIT 2 +#define SC3336P_REG_VALUE_24BIT 3 + +#define OF_CAMERA_PINCTRL_STATE_DEFAULT "rockchip,camera_default" +#define OF_CAMERA_PINCTRL_STATE_SLEEP "rockchip,camera_sleep" +#define SC3336P_NAME "sc3336p" + +static const char * const sc3336p_supply_names[] = { + "avdd", /* Analog power */ + "dovdd", /* Digital I/O power */ + "dvdd", /* Digital core power */ +}; + +#define SC3336P_NUM_SUPPLIES ARRAY_SIZE(sc3336p_supply_names) + +struct regval { + u16 addr; + u8 val; +}; + +struct sc3336p_mode { + u32 bus_fmt; + u32 width; + u32 height; + struct v4l2_fract max_fps; + u32 hts_def; + u32 vts_def; + u32 exp_def; + const struct regval *reg_list; + u32 hdr_mode; + u32 xvclk_freq; + u32 link_freq_idx; + u32 vc[PAD_MAX]; +}; + +struct sc3336p { + struct i2c_client *client; + struct clk *xvclk; + struct gpio_desc *reset_gpio; + struct gpio_desc *pwdn_gpio; + struct regulator_bulk_data supplies[SC3336P_NUM_SUPPLIES]; + + struct pinctrl *pinctrl; + struct pinctrl_state *pins_default; + struct pinctrl_state *pins_sleep; + + struct v4l2_subdev subdev; + struct media_pad pad; + struct v4l2_ctrl_handler ctrl_handler; + struct v4l2_ctrl *exposure; + struct v4l2_ctrl *anal_gain; + struct v4l2_ctrl *digi_gain; + struct v4l2_ctrl *hblank; + struct v4l2_ctrl *vblank; + struct v4l2_ctrl *pixel_rate; + struct v4l2_ctrl *link_freq; + struct v4l2_ctrl *test_pattern; + struct mutex mutex; + struct v4l2_fract cur_fps; + bool streaming; + bool power_on; + const struct sc3336p_mode *cur_mode; + u32 module_index; + const char *module_facing; + const char *module_name; + const char *len_name; + u32 cur_vts; + bool has_init_exp; + bool is_thunderboot; + bool is_first_streamoff; + struct preisp_hdrae_exp_s init_hdrae_exp; + struct cam_sw_info *cam_sw_inf; +}; + +#define to_sc3336p(sd) container_of(sd, struct sc3336p, subdev) + +/* + * Xclk 24Mhz + */ +static const struct regval sc3336p_global_regs[] = { + {REG_NULL, 0x00}, +}; + +/* + * Xclk 24Mhz + * max_framerate 60fps + * mipi_datarate per lane 255Mbps, 2lane + */ +static const struct regval sc3336p_linear_10_1152x648_60fps_regs[] = { + {0x0103, 0x01}, + {0x301f, 0x04}, + {0x36e9, 0x80}, + {0x37f9, 0x80}, + {0x30b8, 0x33}, + {0x3208, 0x04}, + {0x3209, 0x80}, + {0x320a, 0x02}, + {0x320b, 0x88}, + {0x320c, 0x05}, + {0x320d, 0x00}, + {0x320e, 0x02}, + {0x320f, 0x98}, + {0x3211, 0x02}, + {0x3213, 0x02}, + {0x3215, 0x31}, + {0x3220, 0x01}, + {0x3253, 0x10}, + {0x325f, 0x20}, + {0x3301, 0x04}, + {0x3306, 0x50}, + {0x3309, 0xf8}, + {0x330a, 0x00}, + {0x330b, 0xd8}, + {0x3314, 0x13}, + {0x331f, 0xe9}, + {0x3333, 0x10}, + {0x3334, 0x40}, + {0x335e, 0x06}, + {0x335f, 0x0a}, + {0x3364, 0x5e}, + {0x337c, 0x02}, + {0x337d, 0x0e}, + {0x3390, 0x01}, + {0x3391, 0x03}, + {0x3392, 0x07}, + {0x3393, 0x04}, + {0x3394, 0x04}, + {0x3395, 0x04}, + {0x3396, 0x08}, + {0x3397, 0x0b}, + {0x3398, 0x1f}, + {0x3399, 0x04}, + {0x339a, 0x0a}, + {0x339b, 0x3a}, + {0x339c, 0x60}, + {0x33a2, 0x04}, + {0x33ac, 0x08}, + {0x33ad, 0x1c}, + {0x33ae, 0x10}, + {0x33af, 0x30}, + {0x33b1, 0x80}, + {0x33b3, 0x48}, + {0x33f9, 0x60}, + {0x33fb, 0x74}, + {0x33fc, 0x4b}, + {0x33fd, 0x5f}, + {0x349f, 0x03}, + {0x34a6, 0x4b}, + {0x34a7, 0x5f}, + {0x34a8, 0x20}, + {0x34a9, 0x18}, + {0x34aa, 0x00}, + {0x34ab, 0xe8}, + {0x34ac, 0x01}, + {0x34ad, 0x00}, + {0x34f8, 0x5f}, + {0x34f9, 0x18}, + {0x3630, 0xc0}, + {0x3631, 0x84}, + {0x3632, 0x64}, + {0x3633, 0x32}, + {0x363b, 0x03}, + {0x363c, 0x08}, + {0x3641, 0x38}, + {0x3670, 0x4e}, + {0x3674, 0xf0}, + {0x3675, 0xc0}, + {0x3676, 0xc0}, + {0x3677, 0x86}, + {0x3678, 0x86}, + {0x3679, 0x86}, + {0x367c, 0x48}, + {0x367d, 0x49}, + {0x367e, 0x4b}, + {0x367f, 0x5f}, + {0x3690, 0x22}, + {0x3691, 0x22}, + {0x3692, 0x33}, + {0x369c, 0x4b}, + {0x369d, 0x4f}, + {0x36b0, 0x87}, + {0x36b1, 0x90}, + {0x36b2, 0xa1}, + {0x36b3, 0xc8}, + {0x36b4, 0x49}, + {0x36b5, 0x4b}, + {0x36b6, 0x4f}, + {0x36ea, 0x11}, + {0x36eb, 0x0d}, + {0x36ec, 0x2c}, + {0x36ed, 0x26}, + {0x370f, 0x01}, + {0x3722, 0x09}, + {0x3724, 0x41}, + {0x3725, 0xc1}, + {0x3771, 0x09}, + {0x3772, 0x09}, + {0x3773, 0x05}, + {0x377a, 0x48}, + {0x377b, 0x5f}, + {0x37fa, 0x11}, + {0x37fb, 0x33}, + {0x37fc, 0x11}, + {0x37fd, 0x08}, + {0x3904, 0x04}, + {0x3905, 0x8c}, + {0x391d, 0x04}, + {0x391f, 0x49}, + {0x3921, 0x20}, + {0x3926, 0x21}, + {0x3933, 0x80}, + {0x3934, 0x08}, + {0x3935, 0x00}, + {0x3936, 0x90}, + {0x3937, 0x79}, + {0x3938, 0x77}, + {0x3939, 0x00}, + {0x393a, 0x00}, + {0x393b, 0x00}, + {0x393c, 0x28}, + {0x39dc, 0x02}, + {0x3e01, 0x29}, + {0x3e02, 0x00}, + {0x3e09, 0x00}, + {0x440d, 0x10}, + {0x440e, 0x01}, + {0x4509, 0x20}, + {0x4819, 0x04}, + {0x481b, 0x02}, + {0x481d, 0x07}, + {0x481f, 0x02}, + {0x4821, 0x07}, + {0x4823, 0x02}, + {0x4825, 0x02}, + {0x4827, 0x02}, + {0x4829, 0x03}, + {0x5000, 0x46}, + {0x5780, 0x76}, + {0x5784, 0x10}, + {0x5785, 0x04}, + {0x5787, 0x0a}, + {0x5788, 0x0a}, + {0x5789, 0x04}, + {0x578a, 0x0a}, + {0x578b, 0x0a}, + {0x578c, 0x04}, + {0x578d, 0x40}, + {0x5790, 0x08}, + {0x5791, 0x04}, + {0x5792, 0x04}, + {0x5793, 0x08}, + {0x5794, 0x04}, + {0x5795, 0x04}, + {0x5799, 0x46}, + {0x579a, 0x77}, + {0x57a1, 0x04}, + {0x57a8, 0xd2}, + {0x57aa, 0x2a}, + {0x57ab, 0x7f}, + {0x57ac, 0x00}, + {0x57ad, 0x00}, + {0x5900, 0xf1}, + {0x5901, 0x04}, + {0x5988, 0x70}, + {0x59e2, 0x08}, + {0x59e3, 0x03}, + {0x59e4, 0x00}, + {0x59e5, 0x10}, + {0x59e6, 0x06}, + {0x59e7, 0x00}, + {0x59e8, 0x08}, + {0x59e9, 0x02}, + {0x59ea, 0x00}, + {0x59eb, 0x10}, + {0x59ec, 0x04}, + {0x59ed, 0x00}, + {0x5ae0, 0xfe}, + {0x5ae1, 0x40}, + {0x5ae2, 0x38}, + {0x5ae3, 0x30}, + {0x5ae4, 0x28}, + {0x5ae5, 0x38}, + {0x5ae6, 0x30}, + {0x5ae7, 0x28}, + {0x5ae8, 0x3f}, + {0x5ae9, 0x34}, + {0x5aea, 0x2c}, + {0x5aeb, 0x3f}, + {0x5aec, 0x34}, + {0x5aed, 0x2c}, + {0x36e9, 0x54}, + {0x37f9, 0x47}, + {REG_NULL, 0x00}, +}; + +/* + * Xclk 24Mhz + * max_framerate 30fps + * mipi_datarate per lane 495Mbps, 2lane + */ +static const struct regval sc3336p_linear_10_2304x1296_30fps_regs[] = { + {0x0103, 0x01}, + {0x36e9, 0x80}, + {0x37f9, 0x80}, + {0x301f, 0x02}, + {0x30b8, 0x33}, + {0x320e, 0x05}, + {0x320f, 0x28}, + {0x3253, 0x10}, + {0x325f, 0x20}, + {0x3301, 0x04}, + {0x3306, 0x50}, + {0x3309, 0xf8}, + {0x330a, 0x00}, + {0x330b, 0xd8}, + {0x3314, 0x13}, + {0x331f, 0xe9}, + {0x3333, 0x10}, + {0x3334, 0x40}, + {0x335e, 0x06}, + {0x335f, 0x0a}, + {0x3364, 0x5e}, + {0x337c, 0x02}, + {0x337d, 0x0e}, + {0x3390, 0x01}, + {0x3391, 0x03}, + {0x3392, 0x07}, + {0x3393, 0x04}, + {0x3394, 0x04}, + {0x3395, 0x04}, + {0x3396, 0x08}, + {0x3397, 0x0b}, + {0x3398, 0x1f}, + {0x3399, 0x04}, + {0x339a, 0x0a}, + {0x339b, 0x3a}, + {0x339c, 0x60}, + {0x33a2, 0x04}, + {0x33ac, 0x08}, + {0x33ad, 0x1c}, + {0x33ae, 0x10}, + {0x33af, 0x30}, + {0x33b1, 0x80}, + {0x33b3, 0x48}, + {0x33f9, 0x60}, + {0x33fb, 0x74}, + {0x33fc, 0x4b}, + {0x33fd, 0x5f}, + {0x349f, 0x03}, + {0x34a6, 0x4b}, + {0x34a7, 0x5f}, + {0x34a8, 0x20}, + {0x34a9, 0x18}, + {0x34aa, 0x00}, + {0x34ab, 0xe8}, + {0x34ac, 0x01}, + {0x34ad, 0x00}, + {0x34f8, 0x5f}, + {0x34f9, 0x18}, + {0x3630, 0xc0}, + {0x3631, 0x84}, + {0x3632, 0x64}, + {0x3633, 0x32}, + {0x363b, 0x03}, + {0x363c, 0x08}, + {0x3641, 0x38}, + {0x3670, 0x4e}, + {0x3674, 0xf0}, + {0x3675, 0xc0}, + {0x3676, 0xc0}, + {0x3677, 0x86}, + {0x3678, 0x86}, + {0x3679, 0x86}, + {0x367c, 0x48}, + {0x367d, 0x49}, + {0x367e, 0x4b}, + {0x367f, 0x5f}, + {0x3690, 0x22}, + {0x3691, 0x22}, + {0x3692, 0x33}, + {0x369c, 0x4b}, + {0x369d, 0x4f}, + {0x36b0, 0x87}, + {0x36b1, 0x90}, + {0x36b2, 0xa1}, + {0x36b3, 0xc8}, + {0x36b4, 0x49}, + {0x36b5, 0x4b}, + {0x36b6, 0x4f}, + {0x36ea, 0x0b}, + {0x36eb, 0x0d}, + {0x36ec, 0x1c}, + {0x36ed, 0x26}, + {0x370f, 0x01}, + {0x3722, 0x09}, + {0x3724, 0x41}, + {0x3725, 0xc1}, + {0x3771, 0x09}, + {0x3772, 0x09}, + {0x3773, 0x05}, + {0x377a, 0x48}, + {0x377b, 0x5f}, + {0x37fa, 0x0b}, + {0x37fb, 0x33}, + {0x37fc, 0x11}, + {0x37fd, 0x08}, + {0x3904, 0x04}, + {0x3905, 0x8c}, + {0x391d, 0x04}, + {0x391f, 0x49}, + {0x3921, 0x20}, + {0x3926, 0x21}, + {0x3933, 0x80}, + {0x3934, 0x08}, + {0x3935, 0x00}, + {0x3936, 0x90}, + {0x3937, 0x79}, + {0x3938, 0x77}, + {0x3939, 0x00}, + {0x393a, 0x00}, + {0x393b, 0x00}, + {0x393c, 0x28}, + {0x39dc, 0x02}, + {0x3e01, 0x52}, + {0x3e02, 0x00}, + {0x3e09, 0x00}, + {0x440d, 0x10}, + {0x440e, 0x01}, + {0x4509, 0x20}, + {0x5780, 0x76}, + {0x5784, 0x10}, + {0x5785, 0x04}, + {0x5787, 0x0a}, + {0x5788, 0x0a}, + {0x5789, 0x04}, + {0x578a, 0x0a}, + {0x578b, 0x0a}, + {0x578c, 0x04}, + {0x578d, 0x40}, + {0x5790, 0x08}, + {0x5791, 0x04}, + {0x5792, 0x04}, + {0x5793, 0x08}, + {0x5794, 0x04}, + {0x5795, 0x04}, + {0x5799, 0x46}, + {0x579a, 0x77}, + {0x57a1, 0x04}, + {0x57a8, 0xd2}, + {0x57aa, 0x2a}, + {0x57ab, 0x7f}, + {0x57ac, 0x00}, + {0x57ad, 0x00}, + {0x59e2, 0x08}, + {0x59e3, 0x03}, + {0x59e4, 0x00}, + {0x59e5, 0x10}, + {0x59e6, 0x06}, + {0x59e7, 0x00}, + {0x59e8, 0x08}, + {0x59e9, 0x02}, + {0x59ea, 0x00}, + {0x59eb, 0x10}, + {0x59ec, 0x04}, + {0x59ed, 0x00}, + {0x5ae0, 0xfe}, + {0x5ae1, 0x40}, + {0x5ae2, 0x38}, + {0x5ae3, 0x30}, + {0x5ae4, 0x28}, + {0x5ae5, 0x38}, + {0x5ae6, 0x30}, + {0x5ae7, 0x28}, + {0x5ae8, 0x3f}, + {0x5ae9, 0x34}, + {0x5aea, 0x2c}, + {0x5aeb, 0x3f}, + {0x5aec, 0x34}, + {0x5aed, 0x2c}, + {0x36e9, 0x53}, + {0x37f9, 0x27}, + {REG_NULL, 0x00}, +}; + +static const struct sc3336p_mode supported_modes[] = { + { + .width = 2304, + .height = 1296, + .max_fps = { + .numerator = 10000, + .denominator = 300000, + }, + .exp_def = 0x0080, + .hts_def = 0x05dc, + .vts_def = 0x0528, + .bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10, + .reg_list = sc3336p_linear_10_2304x1296_30fps_regs, + .hdr_mode = NO_HDR, + .xvclk_freq = SC3336P_XVCLK_FREQ, + .link_freq_idx = 1, + .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0, + }, + { + .width = 1152, + .height = 648, + .max_fps = { + .numerator = 10000, + .denominator = 600000, + }, + .exp_def = 0x0080, + .hts_def = 0x0500, + .vts_def = 0x0298, + .bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10, + .reg_list = sc3336p_linear_10_1152x648_60fps_regs, + .hdr_mode = NO_HDR, + .xvclk_freq = SC3336P_XVCLK_FREQ, + .link_freq_idx = 0, + .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0, + }, +}; + +static const s64 link_freq_menu_items[] = { + SC3336P_LINK_FREQ_255M, + SC3336P_LINK_FREQ_495M, +}; + +static const char * const sc3336p_test_pattern_menu[] = { + "Disabled", + "Vertical Color Bar Type 1", + "Vertical Color Bar Type 2", + "Vertical Color Bar Type 3", + "Vertical Color Bar Type 4", +}; + +/* Write registers up to 4 at a time */ +static int sc3336p_write_reg(struct i2c_client *client, u16 reg, + u32 len, u32 val) +{ + u32 buf_i, val_i; + u8 buf[6]; + u8 *val_p; + __be32 val_be; + + if (len > 4) + return -EINVAL; + + buf[0] = reg >> 8; + buf[1] = reg & 0xff; + + val_be = cpu_to_be32(val); + val_p = (u8 *)&val_be; + buf_i = 2; + val_i = 4 - len; + + while (val_i < 4) + buf[buf_i++] = val_p[val_i++]; + + if (i2c_master_send(client, buf, len + 2) != len + 2) + return -EIO; + return 0; +} + +static int sc3336p_write_array(struct i2c_client *client, + const struct regval *regs) +{ + u32 i; + int ret = 0; + + for (i = 0; ret == 0 && regs[i].addr != REG_NULL; i++) + ret = sc3336p_write_reg(client, regs[i].addr, + SC3336P_REG_VALUE_08BIT, regs[i].val); + + return ret; +} + +/* Read registers up to 4 at a time */ +static int sc3336p_read_reg(struct i2c_client *client, u16 reg, unsigned int len, + u32 *val) +{ + struct i2c_msg msgs[2]; + u8 *data_be_p; + __be32 data_be = 0; + __be16 reg_addr_be = cpu_to_be16(reg); + int ret; + + if (len > 4 || !len) + return -EINVAL; + + data_be_p = (u8 *)&data_be; + /* Write register address */ + msgs[0].addr = client->addr; + msgs[0].flags = 0; + msgs[0].len = 2; + msgs[0].buf = (u8 *)®_addr_be; + + /* Read data from register */ + msgs[1].addr = client->addr; + msgs[1].flags = I2C_M_RD; + msgs[1].len = len; + msgs[1].buf = &data_be_p[4 - len]; + + ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); + if (ret != ARRAY_SIZE(msgs)) + return -EIO; + + *val = be32_to_cpu(data_be); + + return 0; +} + +static int sc3336p_set_gain_reg(struct sc3336p *sc3336p, u32 gain) +{ + struct i2c_client *client = sc3336p->client; + u32 coarse_again = 0, coarse_dgain = 0, fine_dgain = 0; + int ret = 0, gain_factor; + + if (gain < SC3336P_GAIN_MIN) + gain = SC3336P_GAIN_MIN; + else if (gain > SC3336P_GAIN_MAX) + gain = SC3336P_GAIN_MAX; + + gain_factor = gain * 1000 / 128; + if (gain_factor < 1520) { + coarse_again = 0x00; + coarse_dgain = 0x00; + fine_dgain = gain_factor * 128 / 1000; + } else if (gain_factor < 3040) { + coarse_again = 0x40; + coarse_dgain = 0x00; + fine_dgain = gain_factor * 128 / 1520; + } else if (gain_factor < 6080) { + coarse_again = 0x48; + coarse_dgain = 0x00; + fine_dgain = gain_factor * 128 / 3040; + } else if (gain_factor < 12160) { + coarse_again = 0x49; + coarse_dgain = 0x00; + fine_dgain = gain_factor * 128 / 6080; + } else if (gain_factor < 24320) { + coarse_again = 0x4b; + coarse_dgain = 0x00; + fine_dgain = gain_factor * 128 / 12160; + } else if (gain_factor < 48640) { + coarse_again = 0x4f; + coarse_dgain = 0x00; + fine_dgain = gain_factor * 128 / 24320; + } else if (gain_factor < 48640 * 2) { + //open dgain begin max digital gain 4X + coarse_again = 0x5f; + coarse_dgain = 0x00; + fine_dgain = gain_factor * 128 / 48640; + } else if (gain_factor < 48640 * 4) { + coarse_again = 0x5f; + coarse_dgain = 0x01; + fine_dgain = gain_factor * 128 / 48640 / 2; + } else if (gain_factor < 48640 * 8) { + coarse_again = 0x5f; + coarse_dgain = 0x03; + fine_dgain = gain_factor * 128 / 48640 / 4; + } else if (gain_factor < 48640 * 16) { + coarse_again = 0x5f; + coarse_dgain = 0x07; + fine_dgain = gain_factor * 128 / 48640 / 8; + } + dev_dbg(&client->dev, "c_again: 0x%x, c_dgain: 0x%x, f_dgain: 0x%0x\n", + coarse_again, coarse_dgain, fine_dgain); + + ret = sc3336p_write_reg(sc3336p->client, + SC3336P_REG_DIG_GAIN, + SC3336P_REG_VALUE_08BIT, + coarse_dgain); + ret |= sc3336p_write_reg(sc3336p->client, + SC3336P_REG_DIG_FINE_GAIN, + SC3336P_REG_VALUE_08BIT, + fine_dgain); + ret |= sc3336p_write_reg(sc3336p->client, + SC3336P_REG_ANA_GAIN, + SC3336P_REG_VALUE_08BIT, + coarse_again); + + return ret; +} + +static int sc3336p_get_reso_dist(const struct sc3336p_mode *mode, + struct v4l2_mbus_framefmt *framefmt) +{ + return abs(mode->width - framefmt->width) + + abs(mode->height - framefmt->height); +} + +static const struct sc3336p_mode * +sc3336p_find_best_fit(struct v4l2_subdev_format *fmt) +{ + struct v4l2_mbus_framefmt *framefmt = &fmt->format; + int dist; + int cur_best_fit = 0; + int cur_best_fit_dist = -1; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(supported_modes); i++) { + dist = sc3336p_get_reso_dist(&supported_modes[i], framefmt); + if (cur_best_fit_dist == -1 || dist < cur_best_fit_dist) { + cur_best_fit_dist = dist; + cur_best_fit = i; + } + } + + return &supported_modes[cur_best_fit]; +} + +static int sc3336p_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *fmt) +{ + struct sc3336p *sc3336p = to_sc3336p(sd); + const struct sc3336p_mode *mode; + s64 h_blank, vblank_def; + u64 dst_link_freq = 0; + u64 dst_pixel_rate = 0; + + mutex_lock(&sc3336p->mutex); + + mode = sc3336p_find_best_fit(fmt); + fmt->format.code = mode->bus_fmt; + fmt->format.width = mode->width; + fmt->format.height = mode->height; + fmt->format.field = V4L2_FIELD_NONE; + if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { +#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API + *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format; +#else + mutex_unlock(&sc3336p->mutex); + return -ENOTTY; +#endif + } else { + sc3336p->cur_mode = mode; + h_blank = mode->hts_def - mode->width; + __v4l2_ctrl_modify_range(sc3336p->hblank, h_blank, + h_blank, 1, h_blank); + vblank_def = mode->vts_def - mode->height; + __v4l2_ctrl_modify_range(sc3336p->vblank, vblank_def, + SC3336P_VTS_MAX - mode->height, + 1, vblank_def); + dst_link_freq = mode->link_freq_idx; + dst_pixel_rate = (u32)link_freq_menu_items[mode->link_freq_idx] / + SC3336P_BITS_PER_SAMPLE * 2 * SC3336P_LANES; + __v4l2_ctrl_s_ctrl_int64(sc3336p->pixel_rate, + dst_pixel_rate); + __v4l2_ctrl_s_ctrl(sc3336p->link_freq, + dst_link_freq); + sc3336p->cur_fps = mode->max_fps; + } + + mutex_unlock(&sc3336p->mutex); + + return 0; +} + +static int sc3336p_get_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *fmt) +{ + struct sc3336p *sc3336p = to_sc3336p(sd); + const struct sc3336p_mode *mode = sc3336p->cur_mode; + + mutex_lock(&sc3336p->mutex); + if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { +#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API + fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad); +#else + mutex_unlock(&sc3336p->mutex); + return -ENOTTY; +#endif + } else { + fmt->format.width = mode->width; + fmt->format.height = mode->height; + fmt->format.code = mode->bus_fmt; + fmt->format.field = V4L2_FIELD_NONE; + /* format info: width/height/data type/virctual channel */ + if (fmt->pad < PAD_MAX && mode->hdr_mode != NO_HDR) + fmt->reserved[0] = mode->vc[fmt->pad]; + else + fmt->reserved[0] = mode->vc[PAD0]; + } + mutex_unlock(&sc3336p->mutex); + + return 0; +} + +static int sc3336p_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) +{ + struct sc3336p *sc3336p = to_sc3336p(sd); + + if (code->index != 0) + return -EINVAL; + code->code = sc3336p->cur_mode->bus_fmt; + + return 0; +} + +static int sc3336p_enum_frame_sizes(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_frame_size_enum *fse) +{ + if (fse->index >= ARRAY_SIZE(supported_modes)) + return -EINVAL; + + if (fse->code != supported_modes[0].bus_fmt) + return -EINVAL; + + fse->min_width = supported_modes[fse->index].width; + fse->max_width = supported_modes[fse->index].width; + fse->max_height = supported_modes[fse->index].height; + fse->min_height = supported_modes[fse->index].height; + + return 0; +} + +static int sc3336p_enable_test_pattern(struct sc3336p *sc3336p, u32 pattern) +{ + u32 val = 0; + int ret = 0; + + ret = sc3336p_read_reg(sc3336p->client, SC3336P_REG_TEST_PATTERN, + SC3336P_REG_VALUE_08BIT, &val); + if (pattern) + val |= SC3336P_TEST_PATTERN_BIT_MASK; + else + val &= ~SC3336P_TEST_PATTERN_BIT_MASK; + + ret |= sc3336p_write_reg(sc3336p->client, SC3336P_REG_TEST_PATTERN, + SC3336P_REG_VALUE_08BIT, val); + return ret; +} + +static int sc3336p_g_frame_interval(struct v4l2_subdev *sd, + struct v4l2_subdev_frame_interval *fi) +{ + struct sc3336p *sc3336p = to_sc3336p(sd); + const struct sc3336p_mode *mode = sc3336p->cur_mode; + + if (sc3336p->streaming) + fi->interval = sc3336p->cur_fps; + else + fi->interval = mode->max_fps; + return 0; +} + +static int sc3336p_g_mbus_config(struct v4l2_subdev *sd, + unsigned int pad_id, + struct v4l2_mbus_config *config) +{ + struct sc3336p *sc3336p = to_sc3336p(sd); + const struct sc3336p_mode *mode = sc3336p->cur_mode; + + u32 val = 1 << (SC3336P_LANES - 1) | + V4L2_MBUS_CSI2_CHANNEL_0 | + V4L2_MBUS_CSI2_CONTINUOUS_CLOCK; + + if (mode->hdr_mode != NO_HDR) + val |= V4L2_MBUS_CSI2_CHANNEL_1; + if (mode->hdr_mode == HDR_X3) + val |= V4L2_MBUS_CSI2_CHANNEL_2; + + config->type = V4L2_MBUS_CSI2_DPHY; + config->flags = val; + + return 0; +} + +static void sc3336p_get_module_inf(struct sc3336p *sc3336p, + struct rkmodule_inf *inf) +{ + memset(inf, 0, sizeof(*inf)); + strscpy(inf->base.sensor, SC3336P_NAME, sizeof(inf->base.sensor)); + strscpy(inf->base.module, sc3336p->module_name, + sizeof(inf->base.module)); + strscpy(inf->base.lens, sc3336p->len_name, sizeof(inf->base.lens)); +} + +static long sc3336p_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) +{ + struct sc3336p *sc3336p = to_sc3336p(sd); + struct rkmodule_hdr_cfg *hdr; + u32 i, h, w; + long ret = 0; + u32 stream = 0; + + switch (cmd) { + case RKMODULE_GET_MODULE_INFO: + sc3336p_get_module_inf(sc3336p, (struct rkmodule_inf *)arg); + break; + case RKMODULE_GET_HDR_CFG: + hdr = (struct rkmodule_hdr_cfg *)arg; + hdr->esp.mode = HDR_NORMAL_VC; + hdr->hdr_mode = sc3336p->cur_mode->hdr_mode; + break; + case RKMODULE_SET_HDR_CFG: + hdr = (struct rkmodule_hdr_cfg *)arg; + w = sc3336p->cur_mode->width; + h = sc3336p->cur_mode->height; + for (i = 0; i < ARRAY_SIZE(supported_modes); i++) { + if (w == supported_modes[i].width && + h == supported_modes[i].height && + supported_modes[i].hdr_mode == hdr->hdr_mode) { + sc3336p->cur_mode = &supported_modes[i]; + break; + } + } + if (i == ARRAY_SIZE(supported_modes)) { + dev_err(&sc3336p->client->dev, + "not find hdr mode:%d %dx%d config\n", + hdr->hdr_mode, w, h); + ret = -EINVAL; + } else { + w = sc3336p->cur_mode->hts_def - sc3336p->cur_mode->width; + h = sc3336p->cur_mode->vts_def - sc3336p->cur_mode->height; + __v4l2_ctrl_modify_range(sc3336p->hblank, w, w, 1, w); + __v4l2_ctrl_modify_range(sc3336p->vblank, h, + SC3336P_VTS_MAX - sc3336p->cur_mode->height, 1, h); + sc3336p->cur_fps = sc3336p->cur_mode->max_fps; + } + break; + case PREISP_CMD_SET_HDRAE_EXP: + break; + case RKMODULE_SET_QUICK_STREAM: + + stream = *((u32 *)arg); + + if (stream) + ret = sc3336p_write_reg(sc3336p->client, SC3336P_REG_CTRL_MODE, + SC3336P_REG_VALUE_08BIT, SC3336P_MODE_STREAMING); + else + ret = sc3336p_write_reg(sc3336p->client, SC3336P_REG_CTRL_MODE, + SC3336P_REG_VALUE_08BIT, SC3336P_MODE_SW_STANDBY); + break; + default: + ret = -ENOIOCTLCMD; + break; + } + + return ret; +} + +#ifdef CONFIG_COMPAT +static long sc3336p_compat_ioctl32(struct v4l2_subdev *sd, + unsigned int cmd, unsigned long arg) +{ + void __user *up = compat_ptr(arg); + struct rkmodule_inf *inf; + struct rkmodule_hdr_cfg *hdr; + struct preisp_hdrae_exp_s *hdrae; + long ret; + u32 stream = 0; + + switch (cmd) { + case RKMODULE_GET_MODULE_INFO: + inf = kzalloc(sizeof(*inf), GFP_KERNEL); + if (!inf) { + ret = -ENOMEM; + return ret; + } + + ret = sc3336p_ioctl(sd, cmd, inf); + if (!ret) { + if (copy_to_user(up, inf, sizeof(*inf))) + ret = -EFAULT; + } + kfree(inf); + break; + case RKMODULE_GET_HDR_CFG: + hdr = kzalloc(sizeof(*hdr), GFP_KERNEL); + if (!hdr) { + ret = -ENOMEM; + return ret; + } + + ret = sc3336p_ioctl(sd, cmd, hdr); + if (!ret) { + if (copy_to_user(up, hdr, sizeof(*hdr))) + ret = -EFAULT; + } + kfree(hdr); + break; + case RKMODULE_SET_HDR_CFG: + hdr = kzalloc(sizeof(*hdr), GFP_KERNEL); + if (!hdr) { + ret = -ENOMEM; + return ret; + } + + ret = copy_from_user(hdr, up, sizeof(*hdr)); + if (!ret) + ret = sc3336p_ioctl(sd, cmd, hdr); + else + ret = -EFAULT; + kfree(hdr); + break; + case PREISP_CMD_SET_HDRAE_EXP: + hdrae = kzalloc(sizeof(*hdrae), GFP_KERNEL); + if (!hdrae) { + ret = -ENOMEM; + return ret; + } + + ret = copy_from_user(hdrae, up, sizeof(*hdrae)); + if (!ret) + ret = sc3336p_ioctl(sd, cmd, hdrae); + else + ret = -EFAULT; + kfree(hdrae); + break; + case RKMODULE_SET_QUICK_STREAM: + ret = copy_from_user(&stream, up, sizeof(u32)); + if (!ret) + ret = sc3336p_ioctl(sd, cmd, &stream); + else + ret = -EFAULT; + break; + default: + ret = -ENOIOCTLCMD; + break; + } + + return ret; +} +#endif + +static int __sc3336p_start_stream(struct sc3336p *sc3336p) +{ + int ret; + + if (!sc3336p->is_thunderboot) { + ret = sc3336p_write_array(sc3336p->client, sc3336p->cur_mode->reg_list); + if (ret) + return ret; + /* In case these controls are set before streaming */ + ret = __v4l2_ctrl_handler_setup(&sc3336p->ctrl_handler); + if (ret) + return ret; + if (sc3336p->has_init_exp && sc3336p->cur_mode->hdr_mode != NO_HDR) { + ret = sc3336p_ioctl(&sc3336p->subdev, PREISP_CMD_SET_HDRAE_EXP, + &sc3336p->init_hdrae_exp); + if (ret) { + dev_err(&sc3336p->client->dev, + "init exp fail in hdr mode\n"); + return ret; + } + } + } + ret = sc3336p_write_reg(sc3336p->client, SC3336P_REG_CTRL_MODE, + SC3336P_REG_VALUE_08BIT, SC3336P_MODE_STREAMING); + return ret; +} + +static int __sc3336p_stop_stream(struct sc3336p *sc3336p) +{ + sc3336p->has_init_exp = false; + if (sc3336p->is_thunderboot) + sc3336p->is_first_streamoff = true; + return sc3336p_write_reg(sc3336p->client, SC3336P_REG_CTRL_MODE, + SC3336P_REG_VALUE_08BIT, SC3336P_MODE_SW_STANDBY); +} + +static int __sc3336p_power_on(struct sc3336p *sc3336p); +static int sc3336p_s_stream(struct v4l2_subdev *sd, int on) +{ + struct sc3336p *sc3336p = to_sc3336p(sd); + struct i2c_client *client = sc3336p->client; + int ret = 0; + + mutex_lock(&sc3336p->mutex); + on = !!on; + if (on == sc3336p->streaming) + goto unlock_and_return; + if (on) { + if (sc3336p->is_thunderboot && rkisp_tb_get_state() == RKISP_TB_NG) { + sc3336p->is_thunderboot = false; + __sc3336p_power_on(sc3336p); + } + ret = pm_runtime_get_sync(&client->dev); + if (ret < 0) { + pm_runtime_put_noidle(&client->dev); + goto unlock_and_return; + } + ret = __sc3336p_start_stream(sc3336p); + if (ret) { + v4l2_err(sd, "start stream failed while write regs\n"); + pm_runtime_put(&client->dev); + goto unlock_and_return; + } + } else { + __sc3336p_stop_stream(sc3336p); + pm_runtime_put(&client->dev); + } + + sc3336p->streaming = on; +unlock_and_return: + mutex_unlock(&sc3336p->mutex); + return ret; +} + +static int sc3336p_s_power(struct v4l2_subdev *sd, int on) +{ + struct sc3336p *sc3336p = to_sc3336p(sd); + struct i2c_client *client = sc3336p->client; + int ret = 0; + + mutex_lock(&sc3336p->mutex); + + /* If the power state is not modified - no work to do. */ + if (sc3336p->power_on == !!on) + goto unlock_and_return; + + if (on) { + ret = pm_runtime_get_sync(&client->dev); + if (ret < 0) { + pm_runtime_put_noidle(&client->dev); + goto unlock_and_return; + } + + if (!sc3336p->is_thunderboot) { + ret = sc3336p_write_array(sc3336p->client, sc3336p_global_regs); + if (ret) { + v4l2_err(sd, "could not set init registers\n"); + pm_runtime_put_noidle(&client->dev); + goto unlock_and_return; + } + } + + sc3336p->power_on = true; + } else { + pm_runtime_put(&client->dev); + sc3336p->power_on = false; + } + +unlock_and_return: + mutex_unlock(&sc3336p->mutex); + + return ret; +} + +/* Calculate the delay in us by clock rate and clock cycles */ +static inline u32 sc3336p_cal_delay(u32 cycles, struct sc3336p *sc3336p) +{ + return DIV_ROUND_UP(cycles, sc3336p->cur_mode->xvclk_freq / 1000 / 1000); +} + +static int __sc3336p_power_on(struct sc3336p *sc3336p) +{ + int ret; + u32 delay_us; + struct device *dev = &sc3336p->client->dev; + + if (!IS_ERR_OR_NULL(sc3336p->pins_default)) { + ret = pinctrl_select_state(sc3336p->pinctrl, + sc3336p->pins_default); + if (ret < 0) + dev_err(dev, "could not set pins\n"); + } + ret = clk_set_rate(sc3336p->xvclk, sc3336p->cur_mode->xvclk_freq); + if (ret < 0) + dev_warn(dev, "Failed to set xvclk rate (%dHz)\n", sc3336p->cur_mode->xvclk_freq); + if (clk_get_rate(sc3336p->xvclk) != sc3336p->cur_mode->xvclk_freq) + dev_warn(dev, "xvclk mismatched, modes are based on %dHz\n", + sc3336p->cur_mode->xvclk_freq); + ret = clk_prepare_enable(sc3336p->xvclk); + if (ret < 0) { + dev_err(dev, "Failed to enable xvclk\n"); + return ret; + } + + cam_sw_regulator_bulk_init(sc3336p->cam_sw_inf, SC3336P_NUM_SUPPLIES, sc3336p->supplies); + + if (sc3336p->is_thunderboot) + return 0; + + if (!IS_ERR(sc3336p->reset_gpio)) + gpiod_set_value_cansleep(sc3336p->reset_gpio, 0); + + ret = regulator_bulk_enable(SC3336P_NUM_SUPPLIES, sc3336p->supplies); + if (ret < 0) { + dev_err(dev, "Failed to enable regulators\n"); + goto disable_clk; + } + + if (!IS_ERR(sc3336p->reset_gpio)) + gpiod_set_value_cansleep(sc3336p->reset_gpio, 1); + + usleep_range(500, 1000); + + if (!IS_ERR(sc3336p->pwdn_gpio)) + gpiod_set_value_cansleep(sc3336p->pwdn_gpio, 1); + + if (!IS_ERR(sc3336p->reset_gpio)) + usleep_range(6000, 8000); + else + usleep_range(12000, 16000); + + /* 8192 cycles prior to first SCCB transaction */ + delay_us = sc3336p_cal_delay(8192, sc3336p); + usleep_range(delay_us, delay_us * 2); + + return 0; + +disable_clk: + clk_disable_unprepare(sc3336p->xvclk); + + return ret; +} + +static void __sc3336p_power_off(struct sc3336p *sc3336p) +{ + int ret; + struct device *dev = &sc3336p->client->dev; + + clk_disable_unprepare(sc3336p->xvclk); + if (sc3336p->is_thunderboot) { + if (sc3336p->is_first_streamoff) { + sc3336p->is_thunderboot = false; + sc3336p->is_first_streamoff = false; + } else { + return; + } + } + + if (!IS_ERR(sc3336p->pwdn_gpio)) + gpiod_set_value_cansleep(sc3336p->pwdn_gpio, 0); + clk_disable_unprepare(sc3336p->xvclk); + if (!IS_ERR(sc3336p->reset_gpio)) + gpiod_set_value_cansleep(sc3336p->reset_gpio, 0); + if (!IS_ERR_OR_NULL(sc3336p->pins_sleep)) { + ret = pinctrl_select_state(sc3336p->pinctrl, + sc3336p->pins_sleep); + if (ret < 0) + dev_dbg(dev, "could not set pins\n"); + } + regulator_bulk_disable(SC3336P_NUM_SUPPLIES, sc3336p->supplies); +} + +#if IS_REACHABLE(CONFIG_VIDEO_CAM_SLEEP_WAKEUP) +static int __maybe_unused sc3336p_resume(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct sc3336p *sc3336p = to_sc3336p(sd); + + cam_sw_prepare_wakeup(sc3336p->cam_sw_inf, dev); + + usleep_range(4000, 5000); + cam_sw_write_array(sc3336p->cam_sw_inf); + + if (__v4l2_ctrl_handler_setup(&sc3336p->ctrl_handler)) + dev_err(dev, "__v4l2_ctrl_handler_setup fail!"); + + return 0; +} + +static int __maybe_unused sc3336p_suspend(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct sc3336p *sc3336p = to_sc3336p(sd); + + cam_sw_write_array_cb_init(sc3336p->cam_sw_inf, client, + (void *)sc3336p->cur_mode->reg_list, + (sensor_write_array)sc3336p_write_array); + cam_sw_prepare_sleep(sc3336p->cam_sw_inf); + + return 0; +} +#else +#define sc3336p_resume NULL +#define sc3336p_suspend NULL +#endif + +static int __maybe_unused sc3336p_runtime_resume(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct sc3336p *sc3336p = to_sc3336p(sd); + + return __sc3336p_power_on(sc3336p); +} + +static int __maybe_unused sc3336p_runtime_suspend(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct sc3336p *sc3336p = to_sc3336p(sd); + + __sc3336p_power_off(sc3336p); + + return 0; +} + +#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API +static int sc3336p_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) +{ + struct sc3336p *sc3336p = to_sc3336p(sd); + struct v4l2_mbus_framefmt *try_fmt = + v4l2_subdev_get_try_format(sd, fh->pad, 0); + const struct sc3336p_mode *def_mode = &supported_modes[0]; + + mutex_lock(&sc3336p->mutex); + /* Initialize try_fmt */ + try_fmt->width = def_mode->width; + try_fmt->height = def_mode->height; + try_fmt->code = def_mode->bus_fmt; + try_fmt->field = V4L2_FIELD_NONE; + + mutex_unlock(&sc3336p->mutex); + /* No crop or compose */ + + return 0; +} +#endif + +static int sc3336p_enum_frame_interval(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_frame_interval_enum *fie) +{ + if (fie->index >= ARRAY_SIZE(supported_modes)) + return -EINVAL; + + fie->code = supported_modes[fie->index].bus_fmt; + fie->width = supported_modes[fie->index].width; + fie->height = supported_modes[fie->index].height; + fie->interval = supported_modes[fie->index].max_fps; + fie->reserved[0] = supported_modes[fie->index].hdr_mode; + return 0; +} + +static const struct dev_pm_ops sc3336p_pm_ops = { + SET_RUNTIME_PM_OPS(sc3336p_runtime_suspend, + sc3336p_runtime_resume, NULL) + SET_LATE_SYSTEM_SLEEP_PM_OPS(sc3336p_suspend, sc3336p_resume) +}; + +#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API +static const struct v4l2_subdev_internal_ops sc3336p_internal_ops = { + .open = sc3336p_open, +}; +#endif + +static const struct v4l2_subdev_core_ops sc3336p_core_ops = { + .s_power = sc3336p_s_power, + .ioctl = sc3336p_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl32 = sc3336p_compat_ioctl32, +#endif +}; + +static const struct v4l2_subdev_video_ops sc3336p_video_ops = { + .s_stream = sc3336p_s_stream, + .g_frame_interval = sc3336p_g_frame_interval, +}; + +static const struct v4l2_subdev_pad_ops sc3336p_pad_ops = { + .enum_mbus_code = sc3336p_enum_mbus_code, + .enum_frame_size = sc3336p_enum_frame_sizes, + .enum_frame_interval = sc3336p_enum_frame_interval, + .get_fmt = sc3336p_get_fmt, + .set_fmt = sc3336p_set_fmt, + .get_mbus_config = sc3336p_g_mbus_config, +}; + +static const struct v4l2_subdev_ops sc3336p_subdev_ops = { + .core = &sc3336p_core_ops, + .video = &sc3336p_video_ops, + .pad = &sc3336p_pad_ops, +}; + +static void sc3336p_modify_fps_info(struct sc3336p *sc3336p) +{ + const struct sc3336p_mode *mode = sc3336p->cur_mode; + + sc3336p->cur_fps.denominator = mode->max_fps.denominator * mode->vts_def / + sc3336p->cur_vts; +} + +static int sc3336p_set_ctrl(struct v4l2_ctrl *ctrl) +{ + struct sc3336p *sc3336p = container_of(ctrl->handler, + struct sc3336p, ctrl_handler); + struct i2c_client *client = sc3336p->client; + s64 max; + int ret = 0; + u32 val = 0; + + /* Propagate change of current control to all related controls */ + switch (ctrl->id) { + case V4L2_CID_VBLANK: + /* Update max exposure while meeting expected vblanking */ + max = sc3336p->cur_mode->height + ctrl->val - 8; + __v4l2_ctrl_modify_range(sc3336p->exposure, + sc3336p->exposure->minimum, max, + sc3336p->exposure->step, + sc3336p->exposure->default_value); + break; + } + + if (!pm_runtime_get_if_in_use(&client->dev)) + return 0; + + switch (ctrl->id) { + case V4L2_CID_EXPOSURE: + dev_dbg(&client->dev, "set exposure 0x%x\n", ctrl->val); + if (sc3336p->cur_mode->hdr_mode == NO_HDR) { + val = ctrl->val; + /* 4 least significant bits of expsoure are fractional part */ + ret = sc3336p_write_reg(sc3336p->client, + SC3336P_REG_EXPOSURE_H, + SC3336P_REG_VALUE_08BIT, + SC3336P_FETCH_EXP_H(val)); + ret |= sc3336p_write_reg(sc3336p->client, + SC3336P_REG_EXPOSURE_M, + SC3336P_REG_VALUE_08BIT, + SC3336P_FETCH_EXP_M(val)); + ret |= sc3336p_write_reg(sc3336p->client, + SC3336P_REG_EXPOSURE_L, + SC3336P_REG_VALUE_08BIT, + SC3336P_FETCH_EXP_L(val)); + } + break; + case V4L2_CID_ANALOGUE_GAIN: + dev_dbg(&client->dev, "set gain 0x%x\n", ctrl->val); + if (sc3336p->cur_mode->hdr_mode == NO_HDR) + ret = sc3336p_set_gain_reg(sc3336p, ctrl->val); + break; + case V4L2_CID_VBLANK: + dev_dbg(&client->dev, "set vblank 0x%x\n", ctrl->val); + ret = sc3336p_write_reg(sc3336p->client, + SC3336P_REG_VTS_H, + SC3336P_REG_VALUE_08BIT, + (ctrl->val + sc3336p->cur_mode->height) + >> 8); + ret |= sc3336p_write_reg(sc3336p->client, + SC3336P_REG_VTS_L, + SC3336P_REG_VALUE_08BIT, + (ctrl->val + sc3336p->cur_mode->height) + & 0xff); + sc3336p->cur_vts = ctrl->val + sc3336p->cur_mode->height; + if (sc3336p->cur_vts != sc3336p->cur_mode->vts_def) + sc3336p_modify_fps_info(sc3336p); + break; + case V4L2_CID_TEST_PATTERN: + ret = sc3336p_enable_test_pattern(sc3336p, ctrl->val); + break; + case V4L2_CID_HFLIP: + ret = sc3336p_read_reg(sc3336p->client, SC3336P_FLIP_MIRROR_REG, + SC3336P_REG_VALUE_08BIT, &val); + ret |= sc3336p_write_reg(sc3336p->client, SC3336P_FLIP_MIRROR_REG, + SC3336P_REG_VALUE_08BIT, + SC3336P_FETCH_MIRROR(val, ctrl->val)); + break; + case V4L2_CID_VFLIP: + ret = sc3336p_read_reg(sc3336p->client, SC3336P_FLIP_MIRROR_REG, + SC3336P_REG_VALUE_08BIT, &val); + ret |= sc3336p_write_reg(sc3336p->client, SC3336P_FLIP_MIRROR_REG, + SC3336P_REG_VALUE_08BIT, + SC3336P_FETCH_FLIP(val, ctrl->val)); + break; + default: + dev_warn(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n", + __func__, ctrl->id, ctrl->val); + break; + } + + pm_runtime_put(&client->dev); + + return ret; +} + +static const struct v4l2_ctrl_ops sc3336p_ctrl_ops = { + .s_ctrl = sc3336p_set_ctrl, +}; + +static int sc3336p_initialize_controls(struct sc3336p *sc3336p) +{ + const struct sc3336p_mode *mode; + struct v4l2_ctrl_handler *handler; + s64 exposure_max, vblank_def; + u32 h_blank; + int ret; + u64 dst_link_freq = 0; + u64 dst_pixel_rate = 0; + + handler = &sc3336p->ctrl_handler; + mode = sc3336p->cur_mode; + ret = v4l2_ctrl_handler_init(handler, 9); + if (ret) + return ret; + handler->lock = &sc3336p->mutex; + + sc3336p->link_freq = v4l2_ctrl_new_int_menu(handler, NULL, + V4L2_CID_LINK_FREQ, + ARRAY_SIZE(link_freq_menu_items) - 1, 0, link_freq_menu_items); + if (sc3336p->link_freq) + sc3336p->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; + + dst_link_freq = mode->link_freq_idx; + dst_pixel_rate = (u32)link_freq_menu_items[mode->link_freq_idx] / + SC3336P_BITS_PER_SAMPLE * 2 * SC3336P_LANES; + sc3336p->pixel_rate = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE, + 0, PIXEL_RATE_WITH_495M_10BIT, 1, dst_pixel_rate); + + __v4l2_ctrl_s_ctrl(sc3336p->link_freq, dst_link_freq); + + h_blank = mode->hts_def - mode->width; + sc3336p->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK, + h_blank, h_blank, 1, h_blank); + if (sc3336p->hblank) + sc3336p->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; + vblank_def = mode->vts_def - mode->height; + sc3336p->vblank = v4l2_ctrl_new_std(handler, &sc3336p_ctrl_ops, + V4L2_CID_VBLANK, vblank_def, + SC3336P_VTS_MAX - mode->height, + 1, vblank_def); + exposure_max = mode->vts_def - 8; + sc3336p->exposure = v4l2_ctrl_new_std(handler, &sc3336p_ctrl_ops, + V4L2_CID_EXPOSURE, SC3336P_EXPOSURE_MIN, + exposure_max, SC3336P_EXPOSURE_STEP, + mode->exp_def); + sc3336p->anal_gain = v4l2_ctrl_new_std(handler, &sc3336p_ctrl_ops, + V4L2_CID_ANALOGUE_GAIN, SC3336P_GAIN_MIN, + SC3336P_GAIN_MAX, SC3336P_GAIN_STEP, + SC3336P_GAIN_DEFAULT); + sc3336p->test_pattern = v4l2_ctrl_new_std_menu_items(handler, + &sc3336p_ctrl_ops, + V4L2_CID_TEST_PATTERN, + ARRAY_SIZE(sc3336p_test_pattern_menu) - 1, + 0, 0, sc3336p_test_pattern_menu); + v4l2_ctrl_new_std(handler, &sc3336p_ctrl_ops, + V4L2_CID_HFLIP, 0, 1, 1, 0); + v4l2_ctrl_new_std(handler, &sc3336p_ctrl_ops, + V4L2_CID_VFLIP, 0, 1, 1, 0); + if (handler->error) { + ret = handler->error; + dev_err(&sc3336p->client->dev, + "Failed to init controls(%d)\n", ret); + goto err_free_handler; + } + + sc3336p->subdev.ctrl_handler = handler; + sc3336p->has_init_exp = false; + sc3336p->cur_fps = mode->max_fps; + + return 0; + +err_free_handler: + v4l2_ctrl_handler_free(handler); + + return ret; +} + +static int sc3336p_check_sensor_id(struct sc3336p *sc3336p, + struct i2c_client *client) +{ + struct device *dev = &sc3336p->client->dev; + u32 id = 0; + int ret; + + if (sc3336p->is_thunderboot) { + dev_info(dev, "Enable thunderboot mode, skip sensor id check\n"); + return 0; + } + + ret = sc3336p_read_reg(client, SC3336P_REG_CHIP_ID, + SC3336P_REG_VALUE_16BIT, &id); + if (id != CHIP_ID) { + dev_err(dev, "Unexpected sensor id(%06x), ret(%d)\n", id, ret); + return -ENODEV; + } + + dev_info(dev, "Detected OV%06x sensor\n", CHIP_ID); + + return 0; +} + +static int sc3336p_configure_regulators(struct sc3336p *sc3336p) +{ + unsigned int i; + + for (i = 0; i < SC3336P_NUM_SUPPLIES; i++) + sc3336p->supplies[i].supply = sc3336p_supply_names[i]; + + return devm_regulator_bulk_get(&sc3336p->client->dev, + SC3336P_NUM_SUPPLIES, + sc3336p->supplies); +} + +static int sc3336p_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct device *dev = &client->dev; + struct device_node *node = dev->of_node; + struct sc3336p *sc3336p; + struct v4l2_subdev *sd; + char facing[2]; + int ret; + int i, hdr_mode = 0; + + dev_info(dev, "driver version: %02x.%02x.%02x", + DRIVER_VERSION >> 16, + (DRIVER_VERSION & 0xff00) >> 8, + DRIVER_VERSION & 0x00ff); + + sc3336p = devm_kzalloc(dev, sizeof(*sc3336p), GFP_KERNEL); + if (!sc3336p) + return -ENOMEM; + + ret = of_property_read_u32(node, RKMODULE_CAMERA_MODULE_INDEX, + &sc3336p->module_index); + ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_FACING, + &sc3336p->module_facing); + ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_NAME, + &sc3336p->module_name); + ret |= of_property_read_string(node, RKMODULE_CAMERA_LENS_NAME, + &sc3336p->len_name); + if (ret) { + dev_err(dev, "could not get module information!\n"); + return -EINVAL; + } + + sc3336p->is_thunderboot = IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP); + + sc3336p->client = client; + for (i = 0; i < ARRAY_SIZE(supported_modes); i++) { + if (hdr_mode == supported_modes[i].hdr_mode) { + sc3336p->cur_mode = &supported_modes[i]; + break; + } + } + if (i == ARRAY_SIZE(supported_modes)) + sc3336p->cur_mode = &supported_modes[0]; + + sc3336p->xvclk = devm_clk_get(dev, "xvclk"); + if (IS_ERR(sc3336p->xvclk)) { + dev_err(dev, "Failed to get xvclk\n"); + return -EINVAL; + } + + if (!sc3336p->is_thunderboot) + sc3336p->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); + else + sc3336p->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_ASIS); + if (IS_ERR(sc3336p->reset_gpio)) + dev_warn(dev, "Failed to get reset-gpios\n"); + + if (!sc3336p->is_thunderboot) + sc3336p->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW); + else + sc3336p->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_ASIS); + if (IS_ERR(sc3336p->pwdn_gpio)) + dev_warn(dev, "Failed to get pwdn-gpios\n"); + + sc3336p->pinctrl = devm_pinctrl_get(dev); + if (!IS_ERR(sc3336p->pinctrl)) { + sc3336p->pins_default = + pinctrl_lookup_state(sc3336p->pinctrl, + OF_CAMERA_PINCTRL_STATE_DEFAULT); + if (IS_ERR(sc3336p->pins_default)) + dev_err(dev, "could not get default pinstate\n"); + + sc3336p->pins_sleep = + pinctrl_lookup_state(sc3336p->pinctrl, + OF_CAMERA_PINCTRL_STATE_SLEEP); + if (IS_ERR(sc3336p->pins_sleep)) + dev_err(dev, "could not get sleep pinstate\n"); + } else { + dev_err(dev, "no pinctrl\n"); + } + + ret = sc3336p_configure_regulators(sc3336p); + if (ret) { + dev_err(dev, "Failed to get power regulators\n"); + return ret; + } + + mutex_init(&sc3336p->mutex); + + sd = &sc3336p->subdev; + v4l2_i2c_subdev_init(sd, client, &sc3336p_subdev_ops); + ret = sc3336p_initialize_controls(sc3336p); + if (ret) + goto err_destroy_mutex; + + ret = __sc3336p_power_on(sc3336p); + if (ret) + goto err_free_handler; + + ret = sc3336p_check_sensor_id(sc3336p, client); + if (ret) + goto err_power_off; + +#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API + sd->internal_ops = &sc3336p_internal_ops; + sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | + V4L2_SUBDEV_FL_HAS_EVENTS; +#endif +#if defined(CONFIG_MEDIA_CONTROLLER) + sc3336p->pad.flags = MEDIA_PAD_FL_SOURCE; + sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; + ret = media_entity_pads_init(&sd->entity, 1, &sc3336p->pad); + if (ret < 0) + goto err_power_off; +#endif + + if (!sc3336p->cam_sw_inf) { + sc3336p->cam_sw_inf = cam_sw_init(); + cam_sw_clk_init(sc3336p->cam_sw_inf, sc3336p->xvclk, SC3336P_XVCLK_FREQ); + cam_sw_reset_pin_init(sc3336p->cam_sw_inf, sc3336p->reset_gpio, 0); + if (!IS_ERR(sc3336p->pwdn_gpio)) + cam_sw_pwdn_pin_init(sc3336p->cam_sw_inf, sc3336p->pwdn_gpio, 0); + } + + memset(facing, 0, sizeof(facing)); + if (strcmp(sc3336p->module_facing, "back") == 0) + facing[0] = 'b'; + else + facing[0] = 'f'; + + snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s %s", + sc3336p->module_index, facing, + SC3336P_NAME, dev_name(sd->dev)); + ret = v4l2_async_register_subdev_sensor_common(sd); + if (ret) { + dev_err(dev, "v4l2 async register subdev failed\n"); + goto err_clean_entity; + } + + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + if (sc3336p->is_thunderboot) + pm_runtime_get_sync(dev); + else + pm_runtime_idle(dev); + + return 0; + +err_clean_entity: +#if defined(CONFIG_MEDIA_CONTROLLER) + media_entity_cleanup(&sd->entity); +#endif +err_power_off: + __sc3336p_power_off(sc3336p); +err_free_handler: + v4l2_ctrl_handler_free(&sc3336p->ctrl_handler); +err_destroy_mutex: + mutex_destroy(&sc3336p->mutex); + + return ret; +} + +static int sc3336p_remove(struct i2c_client *client) +{ + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct sc3336p *sc3336p = to_sc3336p(sd); + + v4l2_async_unregister_subdev(sd); +#if defined(CONFIG_MEDIA_CONTROLLER) + media_entity_cleanup(&sd->entity); +#endif + v4l2_ctrl_handler_free(&sc3336p->ctrl_handler); + mutex_destroy(&sc3336p->mutex); + + cam_sw_deinit(sc3336p->cam_sw_inf); + + pm_runtime_disable(&client->dev); + if (!pm_runtime_status_suspended(&client->dev)) + __sc3336p_power_off(sc3336p); + pm_runtime_set_suspended(&client->dev); + + return 0; +} + +#if IS_ENABLED(CONFIG_OF) +static const struct of_device_id sc3336p_of_match[] = { + { .compatible = "smartsens,sc3336p" }, + {}, +}; +MODULE_DEVICE_TABLE(of, sc3336p_of_match); +#endif + +static const struct i2c_device_id sc3336p_match_id[] = { + { "smartsens,sc3336p", 0 }, + { }, +}; + +static struct i2c_driver sc3336p_i2c_driver = { + .driver = { + .name = SC3336P_NAME, + .pm = &sc3336p_pm_ops, + .of_match_table = of_match_ptr(sc3336p_of_match), + }, + .probe = &sc3336p_probe, + .remove = &sc3336p_remove, + .id_table = sc3336p_match_id, +}; + +static int __init sensor_mod_init(void) +{ + return i2c_add_driver(&sc3336p_i2c_driver); +} + +static void __exit sensor_mod_exit(void) +{ + i2c_del_driver(&sc3336p_i2c_driver); +} + +#if defined(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP) && !defined(CONFIG_INITCALL_ASYNC) +subsys_initcall(sensor_mod_init); +#else +device_initcall_sync(sensor_mod_init); +#endif +module_exit(sensor_mod_exit); + +MODULE_DESCRIPTION("smartsens sc3336p sensor driver"); +MODULE_LICENSE("GPL"); From c1ea5f751eff48b7aa9954ff40dca91e80ae4670 Mon Sep 17 00:00:00 2001 From: Zhibin Huang Date: Wed, 21 Feb 2024 18:21:22 +0800 Subject: [PATCH 22/34] misc: rk628: bt1120-2-hdmi: set bus_format for bt1120 Type: Fix Redmine ID: N/A Associated modifications: N/A Test: N/A Signed-off-by: Zhibin Huang Change-Id: I5e285e5c14e639a552936835b726da6e71a2e998 --- drivers/misc/rk628/rk628_hdmitx.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/misc/rk628/rk628_hdmitx.c b/drivers/misc/rk628/rk628_hdmitx.c index abd86c8d936e..b5d7ab46a631 100644 --- a/drivers/misc/rk628/rk628_hdmitx.c +++ b/drivers/misc/rk628/rk628_hdmitx.c @@ -741,6 +741,17 @@ static int rk628_hdmi_bridge_attach(struct drm_bridge *bridge, return ret; } + if (rk628_input_is_bt1120(hdmi->rk628)) { + u32 bus_format = MEDIA_BUS_FMT_YUYV8_1X16; + + ret = drm_display_info_set_bus_formats(&connector->display_info, + &bus_format, 1); + if (ret) { + dev_err(hdmi->dev, "Failed to set bus formats\n"); + return ret; + } + } + drm_connector_helper_add(connector, &rk628_hdmi_connector_helper_funcs); drm_connector_attach_encoder(connector, bridge->encoder); From 466091d79d2216352970b9fafabe56e431825f94 Mon Sep 17 00:00:00 2001 From: Jianwei Fan Date: Mon, 19 Feb 2024 16:06:19 +0800 Subject: [PATCH 23/34] arm64: dts: rockchip: rk3588-evb: rk628 change the interrupt to rise edge trigger Change-Id: I6c3905d2e1440ae82654e3a3f62b762c1f1e2ec7 Signed-off-by: Jianwei Fan --- .../boot/dts/rockchip/rk3588-evb1-lp4-v10-rk628-hdmi2csi.dts | 4 ++-- .../boot/dts/rockchip/rk3588-evb7-v11-rk628-hdmi2csi.dts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3588-evb1-lp4-v10-rk628-hdmi2csi.dts b/arch/arm64/boot/dts/rockchip/rk3588-evb1-lp4-v10-rk628-hdmi2csi.dts index 8aa1a74159ff..eb1b5cfd95a4 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-evb1-lp4-v10-rk628-hdmi2csi.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588-evb1-lp4-v10-rk628-hdmi2csi.dts @@ -108,7 +108,7 @@ pinctrl-names = "default"; pinctrl-0 = <&rk628_pin_1>; interrupt-parent = <&gpio1>; - interrupts = ; + interrupts = ; enable-gpios = <&gpio1 RK_PB3 GPIO_ACTIVE_HIGH>; reset-gpios = <&gpio1 RK_PB2 GPIO_ACTIVE_HIGH>; plugin-det-gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_LOW>; @@ -148,7 +148,7 @@ pinctrl-names = "default"; pinctrl-0 = <&rk628_pin>; interrupt-parent = <&gpio2>; - interrupts = ; + interrupts = ; enable-gpios = <&gpio1 RK_PA0 GPIO_ACTIVE_HIGH>; reset-gpios = <&gpio4 RK_PC6 GPIO_ACTIVE_HIGH>; plugin-det-gpios = <&gpio1 RK_PA1 GPIO_ACTIVE_LOW>; diff --git a/arch/arm64/boot/dts/rockchip/rk3588-evb7-v11-rk628-hdmi2csi.dts b/arch/arm64/boot/dts/rockchip/rk3588-evb7-v11-rk628-hdmi2csi.dts index a0de491c2efc..64813821ff5d 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-evb7-v11-rk628-hdmi2csi.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588-evb7-v11-rk628-hdmi2csi.dts @@ -78,7 +78,7 @@ pinctrl-names = "default"; pinctrl-0 = <&rk628_pin>; interrupt-parent = <&gpio1>; - interrupts = ; + interrupts = ; enable-gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_HIGH>; reset-gpios = <&gpio1 RK_PB1 GPIO_ACTIVE_HIGH>; plugin-det-gpios = <&gpio2 RK_PB6 GPIO_ACTIVE_LOW>; From 2424e1c910554886913dc536aacfcf08966a7855 Mon Sep 17 00:00:00 2001 From: Zhibin Huang Date: Thu, 22 Feb 2024 08:28:25 +0800 Subject: [PATCH 24/34] misc: rk628: bt1120: add yc-swap and uv-swap property Type: Function Redmine ID: N/A Associated modifications: N/A Test: N/A Signed-off-by: Zhibin Huang Change-Id: Ie1c54ac3fbc01d76d32eff8d2857f68339654b70 --- drivers/misc/rk628/rk628.h | 5 ++++- drivers/misc/rk628/rk628_rgb.c | 22 ++++++++++++++++++++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/drivers/misc/rk628/rk628.h b/drivers/misc/rk628/rk628.h index 4d58c350a53a..b870d604fcc6 100644 --- a/drivers/misc/rk628/rk628.h +++ b/drivers/misc/rk628/rk628.h @@ -135,7 +135,8 @@ #define DUAL_DATA_SWAP BIT(6) #define DEC_DUALEDGE_EN BIT(5) #define SW_PROGRESS_EN BIT(4) -#define SW_YC_SWAP BIT(3) +#define SW_BT1120_YC_SWAP BIT(3) +#define SW_BT1120_UV_SWAP BIT(2) #define SW_CAP_EN_ASYNC BIT(1) #define SW_CAP_EN_PSYNC BIT(0) #define GRF_RGB_DEC_CON1 0x0044 @@ -541,6 +542,8 @@ struct rk628_combtxphy { struct rk628_rgb { struct regulator *vccio_rgb; bool bt1120_dual_edge; + bool bt1120_yc_swap; + bool bt1120_uv_swap; }; struct rk628 { diff --git a/drivers/misc/rk628/rk628_rgb.c b/drivers/misc/rk628/rk628_rgb.c index 8cbe0bff3ec7..dee837731c9e 100644 --- a/drivers/misc/rk628/rk628_rgb.c +++ b/drivers/misc/rk628/rk628_rgb.c @@ -16,14 +16,26 @@ int rk628_rgb_parse(struct rk628 *rk628, struct device_node *rgb_np) { int ret = 0; + /* input/output: rgb/bt1120 */ rk628->rgb.vccio_rgb = devm_regulator_get_optional(rk628->dev, "vccio-rgb"); if (IS_ERR(rk628->rgb.vccio_rgb)) rk628->rgb.vccio_rgb = NULL; + /* input/output: bt1120 */ if ((rk628_input_is_bt1120(rk628) || rk628_output_is_bt1120(rk628)) && of_property_read_bool(rk628->dev->of_node, "bt1120-dual-edge")) rk628->rgb.bt1120_dual_edge = true; + /* input: bt1120 */ + if (rk628_input_is_bt1120(rk628)) { + if (of_property_read_bool(rk628->dev->of_node, "bt1120-yc-swap")) + rk628->rgb.bt1120_yc_swap = true; + + if (of_property_read_bool(rk628->dev->of_node, "bt1120-uv-swap")) + rk628->rgb.bt1120_uv_swap = true; + } + + /* output: rgb/bt1120 */ if (rk628_output_is_bt1120(rk628) || rk628_output_is_rgb(rk628)) ret = rk628_panel_info_get(rk628, rgb_np); @@ -300,8 +312,14 @@ static void rk628_bt1120_decoder_enable(struct rk628 *rk628) SW_BT_DATA_OEN | SW_INPUT_MODE(INPUT_MODE_BT1120)); rk628_i2c_write(rk628, GRF_CSC_CTRL_CON, SW_Y2R_EN(1)); rk628_i2c_update_bits(rk628, GRF_RGB_DEC_CON0, - SW_CAP_EN_PSYNC | SW_CAP_EN_ASYNC | SW_PROGRESS_EN, - SW_CAP_EN_PSYNC | SW_CAP_EN_ASYNC | SW_PROGRESS_EN); + SW_CAP_EN_PSYNC | SW_CAP_EN_ASYNC | + SW_PROGRESS_EN | + SW_BT1120_YC_SWAP | + SW_BT1120_UV_SWAP, + SW_CAP_EN_PSYNC | SW_CAP_EN_ASYNC | + SW_PROGRESS_EN | + (rk628->rgb.bt1120_yc_swap ? SW_BT1120_YC_SWAP : 0) | + (rk628->rgb.bt1120_uv_swap ? SW_BT1120_UV_SWAP : 0)); } static void rk628_bt1120_encoder_enable(struct rk628 *rk628) From fbdf3d8d033633a2f96a1eb55d55dd48ba61aa5d Mon Sep 17 00:00:00 2001 From: Binyuan Lan Date: Tue, 23 Jan 2024 13:20:18 +0000 Subject: [PATCH 25/34] ASoC: rockchip: rk817-codec: fix pop from DAC_DIG_CLK_DIS and DAC_DIG_CLK_EN Signed-off-by: Binyuan Lan Change-Id: Idfa31a4f3484f1641ebcf46d237244e98e378e93 --- sound/soc/codecs/rk817_codec.c | 142 ++++++++++++++++++++++----------- 1 file changed, 94 insertions(+), 48 deletions(-) diff --git a/sound/soc/codecs/rk817_codec.c b/sound/soc/codecs/rk817_codec.c index 8c767cec57ac..627d16b6dd67 100644 --- a/sound/soc/codecs/rk817_codec.c +++ b/sound/soc/codecs/rk817_codec.c @@ -238,16 +238,22 @@ static int rk817_codec_ctl_gpio(struct rk817_codec_priv *rk817, { if ((gpio & CODEC_SET_SPK) && rk817->spk_ctl_gpio) { + if (level && rk817->spk_mute_delay) + msleep(rk817->spk_mute_delay); gpiod_set_value(rk817->spk_ctl_gpio, level); DBG("%s set spk clt %d\n", __func__, level); - msleep(rk817->spk_mute_delay); + if (!level && rk817->spk_mute_delay) + msleep(rk817->spk_mute_delay); } if ((gpio & CODEC_SET_HP) && rk817->hp_ctl_gpio) { + if (level && rk817->hp_mute_delay) + msleep(rk817->hp_mute_delay); gpiod_set_value(rk817->hp_ctl_gpio, level); DBG("%s set hp clt %d\n", __func__, level); - msleep(rk817->hp_mute_delay); + if (!level && rk817->hp_mute_delay) + msleep(rk817->hp_mute_delay); } return 0; @@ -267,12 +273,12 @@ static int rk817_reset(struct snd_soc_component *component) snd_soc_component_write(component, RK817_CODEC_APLL_CFG5, 0x00); snd_soc_component_write(component, RK817_CODEC_DTOP_DIGEN_CLKE, 0x00); if (rk817->chip_ver <= 0x4) { - DBG("%s (%d): SMIC TudorAG and previous versions\n", + DBG("%s (%d): 0x4 and previous versions\n", __func__, __LINE__); snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x0c); snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0x95); } else { - DBG("%s (%d): SMIC TudorAG version later\n", + DBG("%s (%d): 0x4 version later\n", __func__, __LINE__); snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x04); snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0xa5); @@ -282,6 +288,77 @@ static int rk817_reset(struct snd_soc_component *component) return 0; } +static int rk817_restart_dac_digital_clk(struct snd_soc_component *component) +{ + snd_soc_component_update_bits(component, RK817_CODEC_ADAC_CFG1, + PWD_DACBIAS_MASK, PWD_DACBIAS_DOWN); + usleep_range(500, 600); + snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, + DAC_DIG_CLK_MASK, DAC_DIG_CLK_DIS); + usleep_range(500, 600); + snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, + DAC_DIG_CLK_MASK, DAC_DIG_CLK_EN); + DBG("%s: %d - Playback DIG CLK OPS\n", __func__, __LINE__); + usleep_range(500, 600); + snd_soc_component_update_bits(component, RK817_CODEC_ADAC_CFG1, + PWD_DACBIAS_MASK, PWD_DACBIAS_ON); + + return 0; +} + +static int rk817_restart_dac_digital_clk_and_apll(struct snd_soc_component *component) +{ + snd_soc_component_update_bits(component, RK817_CODEC_ADAC_CFG1, + PWD_DACBIAS_MASK, PWD_DACBIAS_DOWN); + usleep_range(500, 600); + snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, + DAC_DIG_CLK_MASK, DAC_DIG_CLK_DIS); + usleep_range(500, 600); + snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, + DAC_DIG_CLK_MASK, DAC_DIG_CLK_EN); + DBG("%s: %d - Playback DIG CLK OPS\n", __func__, __LINE__); + snd_soc_component_update_bits(component, RK817_CODEC_APLL_CFG5, + PLL_PW_DOWN, PLL_PW_DOWN); + usleep_range(50, 60); + snd_soc_component_update_bits(component, RK817_CODEC_APLL_CFG5, + PLL_PW_DOWN, PLL_PW_UP); + usleep_range(500, 600); + snd_soc_component_update_bits(component, RK817_CODEC_ADAC_CFG1, + PWD_DACBIAS_MASK, PWD_DACBIAS_ON); + + return 0; +} + +static int rk817_restart_adc_digital_clk(struct snd_soc_component *component) +{ + snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, + ADC_DIG_CLK_MASK, ADC_DIG_CLK_DIS); + usleep_range(500, 600); + snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, + ADC_DIG_CLK_MASK, ADC_DIG_CLK_EN); + DBG("%s: %d - Capture DIG CLK OPS\n", __func__, __LINE__); + + return 0; +} + +static int rk817_restart_adc_digital_clk_and_apll(struct snd_soc_component *component) +{ + snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, + ADC_DIG_CLK_MASK, ADC_DIG_CLK_DIS); + usleep_range(500, 600); + snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, + ADC_DIG_CLK_MASK, ADC_DIG_CLK_EN); + DBG("%s: %d - Capture DIG CLK OPS\n", __func__, __LINE__); + snd_soc_component_update_bits(component, RK817_CODEC_APLL_CFG5, + PLL_PW_DOWN, PLL_PW_DOWN); + usleep_range(50, 60); + snd_soc_component_update_bits(component, RK817_CODEC_APLL_CFG5, + PLL_PW_DOWN, PLL_PW_UP); + usleep_range(500, 600); + + return 0; +} + static struct rk817_reg_val_typ playback_power_up_list[] = { {RK817_CODEC_AREF_RTCFG1, 0x40}, {RK817_CODEC_DDAC_POPD_DACST, 0x02}, @@ -380,22 +457,16 @@ static int rk817_codec_power_up(struct snd_soc_component *component, int type) /* configure APLL CFG0/4 */ if (rk817->chip_ver <= 0x4) { - DBG("%s (%d): SMIC TudorAG and previous versions\n", + DBG("%s (%d): 0x4 and previous versions\n", __func__, __LINE__); snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x0c); snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0x95); } else { - DBG("%s: SMIC TudorAG version later\n", __func__); + DBG("%s: 0x4 version later\n", __func__); snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x04); snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0xa5); } - - snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, - DAC_DIG_CLK_MASK, DAC_DIG_CLK_DIS); - usleep_range(2000, 2500); - snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, - DAC_DIG_CLK_MASK, DAC_DIG_CLK_EN); - DBG("%s: %d - Playback DIG CLK OPS\n", __func__, __LINE__); + rk817_restart_dac_digital_clk(component); } if (type & RK817_CODEC_CAPTURE) { @@ -411,22 +482,17 @@ static int rk817_codec_power_up(struct snd_soc_component *component, int type) /* configure APLL CFG0/4 */ if (rk817->chip_ver <= 0x4) { - DBG("%s (%d): SMIC TudorAG and previous versions\n", + DBG("%s (%d): 0x4 and previous versions\n", __func__, __LINE__); snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x0c); snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0x95); } else { - DBG("%s: SMIC TudorAG version later\n", __func__); + DBG("%s: 0x4 version later\n", __func__); snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x04); snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0xa5); } - snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, - ADC_DIG_CLK_MASK, ADC_DIG_CLK_DIS); - usleep_range(2000, 2500); - snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, - ADC_DIG_CLK_MASK, ADC_DIG_CLK_EN); - DBG("%s: %d - Capture DIG CLK OPS\n", __func__, __LINE__); + rk817_restart_adc_digital_clk(component); if (rk817->mic_in_differential) snd_soc_component_update_bits(component, @@ -948,25 +1014,19 @@ static int rk817_hw_params(struct snd_pcm_substream *substream, unsigned int rate = params_rate(params); unsigned char apll_cfg3_val; unsigned char dtop_digen_sr_lmt0; - unsigned char dtop_digen_clke; DBG("%s : sample rate = %dHz\n", __func__, rate); if (rk817->chip_ver <= 0x4) { - DBG("%s: SMIC TudorAG and previous versions\n", __func__); + DBG("%s: 0x4 and previous versions\n", __func__); snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x0c); snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0x95); } else { - DBG("%s: SMIC TudorAG version later\n", __func__); + DBG("%s: 0x4 version later\n", __func__); snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x04); snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0xa5); } - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - dtop_digen_clke = DAC_DIG_CLK_EN; - else - dtop_digen_clke = ADC_DIG_CLK_EN; - switch (rate) { case 8000: apll_cfg3_val = 0x03; @@ -998,19 +1058,12 @@ static int rk817_hw_params(struct snd_pcm_substream *substream, */ if (!((substream->stream == SNDRV_PCM_STREAM_CAPTURE) && rk817->pdmdata_out_enable)) { snd_soc_component_write(component, RK817_CODEC_APLL_CFG3, apll_cfg3_val); - /* The 0x00 contains ADC_DIG_CLK_DIS and DAC_DIG_CLK_DIS */ - snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, - dtop_digen_clke, 0x00); snd_soc_component_update_bits(component, RK817_CODEC_DDAC_SR_LMT0, DACSRT_MASK, dtop_digen_sr_lmt0); - snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, - dtop_digen_clke, dtop_digen_clke); - snd_soc_component_update_bits(component, RK817_CODEC_APLL_CFG5, - PLL_PW_DOWN, PLL_PW_DOWN); - usleep_range(50, 60); - snd_soc_component_update_bits(component, RK817_CODEC_APLL_CFG5, - PLL_PW_DOWN, PLL_PW_UP); - usleep_range(500, 600); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + rk817_restart_dac_digital_clk_and_apll(component); + else + rk817_restart_adc_digital_clk_and_apll(component); } switch (params_format(params)) { @@ -1048,14 +1101,7 @@ static int rk817_digital_mute_dac(struct snd_soc_dai *dai, int mute, int stream) snd_soc_component_update_bits(component, RK817_CODEC_DDAC_MUTE_MIXCTL, DACMT_ENABLE, DACMT_ENABLE); - snd_soc_component_write(component, RK817_CODEC_ADAC_CFG1, - PWD_DACBIAS_DOWN | PWD_DACD_DOWN | - PWD_DACL_DOWN | PWD_DACR_DOWN); - /* Reset DAC DTOP_DIGEN_CLKE for playback stopped */ - snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, - DAC_DIG_CLK_EN, DAC_DIG_CLK_DIS); - snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, - DAC_DIG_CLK_EN, DAC_DIG_CLK_EN); + rk817_restart_dac_digital_clk(component); snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, I2SRX_EN_MASK, I2SRX_DIS); } else { From 4422957f7533d7a974b543a715347b722c0e7f80 Mon Sep 17 00:00:00 2001 From: Cody Xie Date: Tue, 23 Jan 2024 10:35:24 +0800 Subject: [PATCH 26/34] arm64: dts: rockchip: rk3588-vehicle-evb-v21/v22: Use vehicle dummy driver for gear selection Change-Id: I2ed1289f3a14361af15f09def32b654363c8a82a Signed-off-by: Cody Xie --- .../dts/rockchip/rk3588-vehicle-evb-v21.dts | 21 +++++-------------- .../dts/rockchip/rk3588-vehicle-evb-v22.dts | 21 +++++-------------- 2 files changed, 10 insertions(+), 32 deletions(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v21.dts b/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v21.dts index 258ec54f349b..7d198395247a 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v21.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v21.dts @@ -35,23 +35,12 @@ #sound-dai-cells = <1>; status = "okay"; }; - gpio-keys { - compatible = "gpio-keys"; - autorepeat; - reverse { - label = "GPIO Key Reverse"; - linux,code = ; - gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; - debounce-interval = <100>; - }; - - park { - label = "GPIO Key Park"; - linux,code = ; - gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>; - debounce-interval = <100>; - }; + vehicle_dummy: vehicle_dummy { + status = "okay"; + compatible = "rockchip,vehicle-dummy-gpio"; + reverse-gpio = <&gpio0 RK_PA4 GPIO_ACTIVE_HIGH>; + park-gpio = <&gpio0 RK_PB2 GPIO_ACTIVE_HIGH>; }; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v22.dts b/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v22.dts index f1ec17c12157..626273eb1029 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v22.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v22.dts @@ -299,23 +299,12 @@ #sound-dai-cells = <1>; status = "okay"; }; - gpio-keys { - compatible = "gpio-keys"; - autorepeat; - reverse { - label = "GPIO Key Reverse"; - linux,code = ; - gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; - debounce-interval = <100>; - }; - - park { - label = "GPIO Key Park"; - linux,code = ; - gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>; - debounce-interval = <100>; - }; + vehicle_dummy: vehicle_dummy { + status = "okay"; + compatible = "rockchip,vehicle-dummy-gpio"; + reverse-gpio = <&gpio0 RK_PA4 GPIO_ACTIVE_HIGH>; + park-gpio = <&gpio0 RK_PB2 GPIO_ACTIVE_HIGH>; }; vcc3v3_pcie_wifi: vcc3v3-pcie-wifi { From 3c7417b499e34fe0d841a408bf9e0959b808d13f Mon Sep 17 00:00:00 2001 From: Luo Wei Date: Mon, 26 Feb 2024 17:16:21 +0800 Subject: [PATCH 27/34] arm64: dts: rockchip: rk3588-vehicle-evb: maxim support 1080p display dsi0-> ->max96752->720P max96789 dsi1-> ->max96752->1080P dp0/edp0-> ->max96752->720P max96745 edp1/edp1-> ->max96752->720P Signed-off-by: Luo Wei Change-Id: I6f3c51ce40a6f11f0e135a6e649b2f5e7a8ba752 --- ...ehicle-serdes-mfd-display-maxim-split.dtsi | 78 +++++++++---------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3588-vehicle-serdes-mfd-display-maxim-split.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-vehicle-serdes-mfd-display-maxim-split.dtsi index 7dd62e5150fe..44d71e44dd78 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-vehicle-serdes-mfd-display-maxim-split.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588-vehicle-serdes-mfd-display-maxim-split.dtsi @@ -489,57 +489,57 @@ 0322 0024 //Init Default 0326 00E4 - //HSYNC_WIDTH_L - 0385 0038 - //VSYNC_WIDTH_L - 0386 0008 + //HSYNC_WIDTH_L HSYNC=32 + 0385 0020 + //VSYNC_WIDTH_L VSYNC=2 + 0386 0002 //HSYNC_WIDTH_H/VSYNC_WIDTH_H 0387 0000 - //VFP_L + //VFP_L VFP=200 03A5 00C8 //VBP_H 03A7 0000 - //VFP_H/VBP_L - 03A6 0020 - //VRES_L + //VFP_H/VBP_L VBP=8 + 03A6 0008 + //VRES_L VRES=0X02D0=720 03A8 00D0 //VRES_H 03A9 0002 - //HFP_L + //HFP_L HFP=56 03AA 0038 //HBP_H - 03AC 0002 - //HFP_H/HBP_L - 03AB 0000 - //HRES_L + 03AC 0003 + //HFP_H/HBP_L(4bit) HBP=56 + 03AB 0008 + //HRES_L HRES=0X0780=1920 03AD 0080 //HRES_H 03AE 0007 //Disable FIFO/DESKEW_EN 03A4 00C0 - //HSYNC_WIDTH_L - 0395 0038 - //VSYNC_WIDTH_L - 0396 0008 + //HSYNC_WIDTH_L HSYNC=40 + 0395 0028 + //VSYNC_WIDTH_L VSYNC=20 + 0396 0014 //HSYNC_WIDTH_H/VSYNC_WIDTH_H 0397 0000 - //VFP_L - 03B1 00C8 + //VFP_L VFP=15 + 03B1 000F //VBP_H 03B3 0000 - //VFP_H/VBP_L - 03B2 0020 - //VRES_L - 03B4 00D0 + //VFP_H/VBP_L VBP=10 + 03B2 000A + //VRES_L VRES=0X0438=1080 + 03B4 0038 //VRES_H - 03B5 0002 - //HFP_L - 03B6 0038 + 03B5 0004 + //HFP_L HFP=140 + 03B6 008C //HBP_H - 03B8 0002 - //HFP_H/HBP_L - 03B7 0000 - //HRES_L + 03B8 0006 + //HFP_H/HBP_L HBP=100 + 03B7 0004 + //HRES_L HRES=0X0780=1920 03B9 0080 //HRES_H 03BA 0007 @@ -870,15 +870,15 @@ panel-size= <346 194>; panel-timing { - clock-frequency = <115200000>; + clock-frequency = <148500000>; hactive = <1920>; - vactive = <720>; - hfront-porch = <56>; - hsync-len = <32>; - hback-porch = <56>; - vfront-porch = <200>; - vsync-len = <2>; - vback-porch = <8>; + vactive = <1080>; + hfront-porch = <140>; + hsync-len = <40>; + hback-porch = <100>; + vfront-porch = <15>; + vsync-len = <20>; + vback-porch = <10>; hsync-active = <0>; vsync-active = <0>; de-active = <0>; @@ -2434,5 +2434,5 @@ &vp3 { assigned-clocks = <&cru DCLK_VOP3>; - assigned-clock-parents = <&cru PLL_V0PLL>; + assigned-clock-parents = <&cru PLL_GPLL>; }; From e4247367325a5aa175be7f762dc0a5303e0c620b Mon Sep 17 00:00:00 2001 From: Herman Chen Date: Mon, 26 Feb 2024 14:50:40 +0800 Subject: [PATCH 28/34] video: rockchip: mpp: rkvenc2: Fix rw_sem error Use the pointer copy to replace rwsem entry copy. https://redmine.rock-chips.com/issues/461476 DEBUG_RWSEMS_WARN_ON(sem->magic != sem): count = 0x100, magic = 0xffffff81036e2a80, owner = 0xffffff81037f8001, curr 0xffffff81037f8000, list not empty WARNING: CPU: 0 PID: 171 at kernel/locking/rwsem.c:1468 __up_read+0x1dc/0x264 Modules linked in: bcmdhd(O) dhd_static_buf CPU: 0 PID: 171 Comm: irq/47-fdbe0000 Tainted: G O 5.10.160 #13 Hardware name: Rockchip RK3588S TABLET V11 Board (DT) pstate: 60c00009 (nZCv daif +PAN +UAO TCO BTYPE=-) pc : __up_read+0x1dc/0x264 lr : __up_read+0x1dc/0x264 sp : ffffffc00ca83bb0 x29: ffffffc00ca83bb0 x28: 0000000000000000 x27: ffffffc0080e1000 x26: ffffffc0080e16e0 x25: ffffffc0080e17c0 x24: ffffff8103504080 x23: ffffff8299eeec00 x22: ffffff817ecf8038 x21: ffffff817ecf8088 x20: ffffffc00a725000 x19: ffffff81036e3280 x18: 0000000000000030 x17: 0000000000004d49 x16: 0000000000021f36 x15: ffffffc00a746570 x14: 0000000000000086 x13: ffffffc00964a930 x12: 0000000000000003 x11: fffffffffffe5a28 x10: fffffffffffe5a08 x9 : ffffffc0081b3290 x8 : ffffffc00a748b78 x7 : ffffffc00a7f8b78 x6 : 0000000000000001 x5 : 0000000000000000 x4 : ffffff84fd5b5df8 x3 : ffffff84fd5c6730 x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffffff81037f8000 Call trace: __up_read+0x1dc/0x264 up_read+0x44/0x70 mpp_task_finalize+0x6c/0xb4 rkvenc_free_task+0x20/0x7c mpp_free_task+0x50/0x114 mpp_taskqueue_pop_running.isra.0+0x80/0xbc mpp_task_finish+0xb8/0x180 rkvenc_isr+0xd0/0x2ec mpp_dev_isr_sched+0x70/0xd0 irq_thread_fn+0x30/0xa0 irq_thread+0x1d4/0x2d0 kthread+0x150/0x154 ret_from_fork+0x10/0x1c Fixes: 99582ba73a65 ("video: rockchip: mpp: rkvenc2: Fix dual core issue") Signed-off-by: Herman Chen Change-Id: Id3ecd4b03a9676183a80774fd571f86918281cb9 --- drivers/video/rockchip/mpp/mpp_iommu.c | 3 ++- drivers/video/rockchip/mpp/mpp_iommu.h | 11 ++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/video/rockchip/mpp/mpp_iommu.c b/drivers/video/rockchip/mpp/mpp_iommu.c index 1abbfb74f4e2..b19da6e67c0a 100644 --- a/drivers/video/rockchip/mpp/mpp_iommu.c +++ b/drivers/video/rockchip/mpp/mpp_iommu.c @@ -529,7 +529,8 @@ mpp_iommu_probe(struct device *dev) goto err_put_group; } - init_rwsem(&info->rw_sem); + init_rwsem(&info->rw_sem_self); + info->rw_sem = &info->rw_sem_self; spin_lock_init(&info->dev_lock); info->dev = dev; info->pdev = pdev; diff --git a/drivers/video/rockchip/mpp/mpp_iommu.h b/drivers/video/rockchip/mpp/mpp_iommu.h index 87d1b5c612d2..2787fc069df7 100644 --- a/drivers/video/rockchip/mpp/mpp_iommu.h +++ b/drivers/video/rockchip/mpp/mpp_iommu.h @@ -68,7 +68,8 @@ struct mpp_rk_iommu { struct mpp_dev; struct mpp_iommu_info { - struct rw_semaphore rw_sem; + struct rw_semaphore *rw_sem; + struct rw_semaphore rw_sem_self; struct device *dev; struct platform_device *pdev; @@ -126,7 +127,7 @@ int mpp_iommu_dev_deactivate(struct mpp_iommu_info *info, struct mpp_dev *dev); static inline int mpp_iommu_down_read(struct mpp_iommu_info *info) { if (info) - down_read(&info->rw_sem); + down_read(info->rw_sem); return 0; } @@ -134,7 +135,7 @@ static inline int mpp_iommu_down_read(struct mpp_iommu_info *info) static inline int mpp_iommu_up_read(struct mpp_iommu_info *info) { if (info) - up_read(&info->rw_sem); + up_read(info->rw_sem); return 0; } @@ -142,7 +143,7 @@ static inline int mpp_iommu_up_read(struct mpp_iommu_info *info) static inline int mpp_iommu_down_write(struct mpp_iommu_info *info) { if (info) - down_write(&info->rw_sem); + down_write(info->rw_sem); return 0; } @@ -150,7 +151,7 @@ static inline int mpp_iommu_down_write(struct mpp_iommu_info *info) static inline int mpp_iommu_up_write(struct mpp_iommu_info *info) { if (info) - up_write(&info->rw_sem); + up_write(info->rw_sem); return 0; } From 3402a5b4343b453b897d668a0d2bf5d7ad727a10 Mon Sep 17 00:00:00 2001 From: Finley Xiao Date: Fri, 19 Jan 2024 16:18:00 +0800 Subject: [PATCH 29/34] soc: rockchip: power-domain: Add pd status module param for debug Change-Id: I9edf5741a95f877dda22b2fa75eabe288403ed33 Signed-off-by: Finley Xiao --- drivers/soc/rockchip/pm_domains.c | 90 +++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/drivers/soc/rockchip/pm_domains.c b/drivers/soc/rockchip/pm_domains.c index 5a60ae717ad4..066e059ea27e 100644 --- a/drivers/soc/rockchip/pm_domains.c +++ b/drivers/soc/rockchip/pm_domains.c @@ -132,6 +132,96 @@ module_param_named(always_on, pm_domain_always_on, bool, 0644); MODULE_PARM_DESC(always_on, "Always keep pm domains power on except for system suspend."); +#if 0 +#define NAME_LEN 20 + +static bool rockchip_pmu_domain_is_on(struct rockchip_pm_domain *pd); +static int rockchip_pd_power(struct rockchip_pm_domain *pd, bool power_on); +static void rockchip_pmu_lock(struct rockchip_pm_domain *pd); +static void rockchip_pmu_unlock(struct rockchip_pm_domain *pd); + +/* + * power on : echo gpu 1 > /sys/module/pm_domains/parameters/status + * power off: echo gpu 0 > /sys/module/pm_domains/parameters/status + */ +static int pd_set_status(const char *val, const struct kernel_param *kp) +{ + struct generic_pm_domain *genpd; + struct rockchip_pm_domain *pd; + char name[NAME_LEN] = { 0 }; + int status = 0; + int i; + bool is_on; + + if (!g_pmu) + return 0; + + if (strlen(val) > (NAME_LEN - 2)) + return -EINVAL; + + if (sscanf(val, "%s %d", name, &status) != 2) { + pr_info("power on : echo gpu 1 > /sys/module/pm_domains/parameters/status\n"); + pr_info("power off: echo gpu 0 > /sys/module/pm_domains/parameters/status\n"); + return -EINVAL; + } + + for (i = 0; i < g_pmu->genpd_data.num_domains; i++) { + genpd = g_pmu->genpd_data.domains[i]; + if (!genpd) + continue; + if (strncmp(genpd->name, name, strlen(name))) + continue; + pd = container_of(genpd, struct rockchip_pm_domain, genpd); + pr_info("set %s %d\n", genpd->name, status); + if (!rockchip_pd_power(pd, status)) { + rockchip_pmu_lock(pd); + is_on = rockchip_pmu_domain_is_on(pd); + rockchip_pmu_unlock(pd); + pr_info("get %s %d\n", genpd->name, is_on); + } + break; + } + + return 0; +} + +/* + * cat /sys/module/pm_domains/parameters/status + */ +static int pd_get_status(char *buffer, const struct kernel_param *kp) +{ + struct generic_pm_domain *genpd; + struct rockchip_pm_domain *pd; + int i; + int len = 0; + bool is_on; + + if (!g_pmu) + return 0; + + for (i = 0; i < g_pmu->genpd_data.num_domains; i++) { + genpd = g_pmu->genpd_data.domains[i]; + if (!genpd) + continue; + pd = container_of(genpd, struct rockchip_pm_domain, genpd); + rockchip_pmu_lock(pd); + is_on = rockchip_pmu_domain_is_on(pd); + rockchip_pmu_unlock(pd); + len += sprintf(buffer + len, "%s %d\n", genpd->name, is_on); + } + + return len; +} + +static const struct kernel_param_ops pd_status_ops = { + .set = pd_set_status, + .get = pd_get_status, +}; + +module_param_cb(status, &pd_status_ops, NULL, 0600); +MODULE_PARM_DESC(status, "Change pd status."); +#endif + static void rockchip_pmu_lock(struct rockchip_pm_domain *pd) { mutex_lock(&pd->pmu->mutex); From 8679c3ff3cd2bb8074aa2c354ee2d62886e8eee1 Mon Sep 17 00:00:00 2001 From: Zain Wang Date: Wed, 7 Feb 2024 14:47:18 +0800 Subject: [PATCH 30/34] arm64: dts: rockchip: rk3568-amp: add configs for amp irqs Signed-off-by: Zain Wang Change-Id: I9509b9dbaffc081aefe53e4ca1bf97cff7a339c0 --- arch/arm64/boot/dts/rockchip/rk3568-amp.dtsi | 115 ++++++++++++++++++- 1 file changed, 114 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3568-amp.dtsi b/arch/arm64/boot/dts/rockchip/rk3568-amp.dtsi index 8de181dd05cf..53b1f54156ef 100644 --- a/arch/arm64/boot/dts/rockchip/rk3568-amp.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3568-amp.dtsi @@ -3,6 +3,22 @@ * Copyright (c) 2023 Rockchip Electronics Co., Ltd. */ +#include + +#define CPU_GET_AFFINITY(cpu, cluster) ((cpu) << 8) +#define RSVD0_IRQn 283 +#define RSVD_IRQn(_N) (RSVD0_IRQn + (_N)) +#define AMP_CPUOFF_REQ_IRQ(cpu) RSVD_IRQn(11 + (cpu)) /* gic irq: 294 */ +#define GIC_TOUCH_REQ_IRQ(cpu) (AMP_CPUOFF_REQ_IRQ(4) + cpu) /* gic irq: 298 */ +#define GPIO_IRQ_GROUP_DISABLE 0x0 +#define GPIO_IRQ_GROUP_EN_BANK_TYPE 0x1 +#define GPIO_IRQ_GROUP_EN_GROUP_TYPE 0x2 +#define GPIO4_IRQn 69 +#define GPIO3_IRQn 68 +#define GPIO2_IRQn 67 +#define GPIO1_IRQn 66 +#define GPIO0_IRQn 65 + / { rockchip_amp: rockchip-amp { compatible = "rockchip,rk3568-amp"; @@ -14,11 +30,108 @@ pinctrl-0 = <&uart4m1_xfer>; status = "okay"; + amp-irqs = /bits/ 64 < + GIC_AMP_IRQ_CFG_ROUTE(152, 0xd0, CPU_GET_AFFINITY(3, 0)) + GIC_AMP_IRQ_CFG_ROUTE(AMP_CPUOFF_REQ_IRQ(3), 0xd0, CPU_GET_AFFINITY(3, 0)) + GIC_AMP_IRQ_CFG_ROUTE(GIC_TOUCH_REQ_IRQ(3), 0xd0, CPU_GET_AFFINITY(3, 0))>; + + gpio-group-banks = <5>; + gpio-group { + status = "disabled"; + amp-gpio0 { + gpio-bank-id = <0>; + group-irq-en = ; + bank-type-cfg { + hw-irq = ; + hw-irq-cpu-aff = /bits/ 64 ; + prio = <0xd0>; + status = "disabled"; + }; + }; + amp-gpio1 { + gpio-bank-id = <1>; + group-irq-en = ; + bank-type-cfg { + hw-irq = ; + hw-irq-cpu-aff = /bits/ 64 ; + prio = <0xd0>; + status = "disabled"; + }; + }; + amp-gpio2 { + gpio-bank-id = <2>; + group-irq-en = ; + bank-type-cfg { + hw-irq = ; + hw-irq-cpu-aff = /bits/ 64 ; + prio = <0xd0>; + status = "disabled"; + }; + }; + + amp-gpio3 { + gpio-bank-id = <3>; + group-irq-en = ; + bank-type-cfg { + hw-irq = ; + hw-irq-cpu-aff = /bits/ 64 ; + prio = <0xd0>; + status = "disabled"; + }; + }; + + amp-gpio4 { + gpio-bank-id = <4>; + group-irq-en = ; + bank-type-cfg { + hw-irq = ; + hw-irq-cpu-aff = /bits/ 64 ; + prio = <0xd0>; + status = "disabled"; + }; + + prio-group0 { + group-prio = <0x80>; + group-irq-id = ; + group-irq-aff = /bits/ 64 ; + group-irq-en = <0x1 0x1 0x1 0x1>; + status = "disabled"; + }; + prio-group1 { + group-prio = <0x90>; + group-irq-id = ; + group-irq-aff = /bits/ 64 ; + group-irq-en = <0x0 0x1 0x1 0x1>; + status = "disabled"; + }; + + prio-group2 { + group-prio = <0xA0>; + group-irq-id = ; + group-irq-aff = /bits/ 64 ; + group-irq-en = <0x1 0x1 0x1 0x1>; + status = "disabled"; + }; + }; + }; + amp_cpus: amp-cpus { amp-cpu3 { id = <0x0 0x300>; entry = <0x0 0x2800000>; - boot-on = <0>; + boot-on = <1>; mode = <0>; }; }; From df9eb20bbf8104f56f2168cbebba212512cb39a4 Mon Sep 17 00:00:00 2001 From: Zain Wang Date: Wed, 21 Feb 2024 17:04:27 +0800 Subject: [PATCH 31/34] arm64: dts: rockchip: rk3588-amp: add configs for amp irqs Signed-off-by: Zain Wang Change-Id: Ia925cbce88d38fe22a61de3be5ffdd1936fe1119 --- arch/arm64/boot/dts/rockchip/rk3588-amp.dtsi | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3588-amp.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-amp.dtsi index 1d5e50466286..a02840811a54 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-amp.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588-amp.dtsi @@ -5,6 +5,8 @@ #include +#define CPU_GET_AFFINITY(cpu, cluster) ((cpu) << 8) + / { rockchip_amp: rockchip-amp { compatible = "rockchip,amp"; @@ -17,6 +19,18 @@ pinctrl-names = "default"; pinctrl-0 = <&uart5m0_xfer>; + amp-irqs = /bits/ 64 < + /* GPIO EXT */ + GIC_AMP_IRQ_CFG_ROUTE(314, 0xd0, CPU_GET_AFFINITY(3, 0)) + GIC_AMP_IRQ_CFG_ROUTE(315, 0xd0, CPU_GET_AFFINITY(3, 0)) + GIC_AMP_IRQ_CFG_ROUTE(316, 0xd0, CPU_GET_AFFINITY(3, 0)) + GIC_AMP_IRQ_CFG_ROUTE(317, 0xd0, CPU_GET_AFFINITY(3, 0)) + GIC_AMP_IRQ_CFG_ROUTE(318, 0xd0, CPU_GET_AFFINITY(3, 0)) + /* UART5 */ + GIC_AMP_IRQ_CFG_ROUTE(368, 0xd0, CPU_GET_AFFINITY(3, 0)) + /* MAILBOX */ + GIC_AMP_IRQ_CFG_ROUTE(100, 0xd0, CPU_GET_AFFINITY(3, 0))>; + status = "okay"; }; From 07139001946a80e9a091074a58053fee738a59e2 Mon Sep 17 00:00:00 2001 From: Cai YiWei Date: Fri, 27 Oct 2023 15:11:45 +0800 Subject: [PATCH 32/34] media: rockchip: isp: add ioctl to get bay3d buf Change-Id: Id65390eab9f1dc2d64405def56e854078ceba037 Signed-off-by: Cai YiWei --- drivers/media/platform/rockchip/isp/common.c | 54 ++++++-- drivers/media/platform/rockchip/isp/common.h | 1 + .../media/platform/rockchip/isp/isp_params.c | 8 ++ .../media/platform/rockchip/isp/isp_params.h | 4 + .../platform/rockchip/isp/isp_params_v21.c | 14 ++ .../platform/rockchip/isp/isp_params_v32.c | 25 +++- .../platform/rockchip/isp/isp_params_v3x.c | 106 +++++++++------ .../platform/rockchip/isp/isp_params_v3x.h | 6 +- drivers/media/platform/rockchip/isp/procfs.c | 36 ++--- .../media/platform/rockchip/isp/regs_v3x.h | 2 +- drivers/media/platform/rockchip/isp/rkisp.c | 123 ++++++++---------- include/uapi/linux/rk-isp2-config.h | 20 +++ 12 files changed, 258 insertions(+), 141 deletions(-) diff --git a/drivers/media/platform/rockchip/isp/common.c b/drivers/media/platform/rockchip/isp/common.c index 4feef3d3d96e..f1e41f67e893 100644 --- a/drivers/media/platform/rockchip/isp/common.c +++ b/drivers/media/platform/rockchip/isp/common.c @@ -192,6 +192,42 @@ void rkisp_update_regs(struct rkisp_device *dev, u32 start, u32 end) } } +int rkisp_buf_get_fd(struct rkisp_device *dev, + struct rkisp_dummy_buffer *buf, bool try_fd) +{ + const struct vb2_mem_ops *g_ops = dev->hw_dev->mem_ops; + bool new_dbuf = false; + + if (!buf || !buf->mem_priv) + return -EINVAL; + if (try_fd && buf->is_need_dmafd) + return 0; + if (try_fd) { + buf->is_need_dbuf = true; + buf->is_need_dmafd = true; + } + + if (buf->is_need_dbuf && !buf->dbuf) { + buf->dbuf = g_ops->get_dmabuf(&buf->vb, buf->mem_priv, O_RDWR); + new_dbuf = true; + } + + if (buf->is_need_dmafd) { + buf->dma_fd = dma_buf_fd(buf->dbuf, O_CLOEXEC); + if (buf->dma_fd < 0) { + if (new_dbuf) { + dma_buf_put(buf->dbuf); + buf->dbuf = NULL; + buf->is_need_dbuf = false; + } + buf->is_need_dmafd = false; + return -EINVAL; + } + get_dma_buf(buf->dbuf); + } + return 0; +} + static void rkisp_init_dummy_vb2(struct rkisp_device *dev, struct rkisp_dummy_buffer *buf) { @@ -240,17 +276,13 @@ int rkisp_alloc_buffer(struct rkisp_device *dev, } if (buf->is_need_vaddr) buf->vaddr = g_ops->vaddr(&buf->vb, mem_priv); - if (buf->is_need_dbuf) { - buf->dbuf = g_ops->get_dmabuf(&buf->vb, mem_priv, O_RDWR); - if (buf->is_need_dmafd) { - buf->dma_fd = dma_buf_fd(buf->dbuf, O_CLOEXEC); - if (buf->dma_fd < 0) { - dma_buf_put(buf->dbuf); - ret = buf->dma_fd; - goto err; - } - get_dma_buf(buf->dbuf); - } + ret = rkisp_buf_get_fd(dev, buf, false); + if (ret < 0) { + g_ops->put(buf->mem_priv); + buf->mem_priv = NULL; + buf->vaddr = NULL; + buf->size = 0; + goto err; } v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev, "%s buf:0x%x~0x%x size:%d\n", __func__, diff --git a/drivers/media/platform/rockchip/isp/common.h b/drivers/media/platform/rockchip/isp/common.h index 9bdaafac5fc1..8cb433b293b7 100644 --- a/drivers/media/platform/rockchip/isp/common.h +++ b/drivers/media/platform/rockchip/isp/common.h @@ -189,6 +189,7 @@ void rkisp_next_clear_reg_cache_bits(struct rkisp_device *dev, u32 reg, u32 mask void rkisp_update_regs(struct rkisp_device *dev, u32 start, u32 end); +int rkisp_buf_get_fd(struct rkisp_device *dev, struct rkisp_dummy_buffer *buf, bool try_fd); int rkisp_alloc_buffer(struct rkisp_device *dev, struct rkisp_dummy_buffer *buf); void rkisp_free_buffer(struct rkisp_device *dev, struct rkisp_dummy_buffer *buf); void rkisp_prepare_buffer(struct rkisp_device *dev, struct rkisp_dummy_buffer *buf); diff --git a/drivers/media/platform/rockchip/isp/isp_params.c b/drivers/media/platform/rockchip/isp/isp_params.c index 03fd7fce0d7e..3c4379ef479b 100644 --- a/drivers/media/platform/rockchip/isp/isp_params.c +++ b/drivers/media/platform/rockchip/isp/isp_params.c @@ -487,6 +487,14 @@ int rkisp_params_info2ddr_cfg(struct rkisp_isp_params_vdev *params_vdev, return ret; } +void rkisp_params_get_bay3d_buffd(struct rkisp_isp_params_vdev *params_vdev, + struct rkisp_bay3dbuf_info *bay3dbuf) +{ + memset(bay3dbuf, -1, sizeof(*bay3dbuf)); + if (params_vdev->ops->get_bay3d_buffd) + params_vdev->ops->get_bay3d_buffd(params_vdev, bay3dbuf); +} + int rkisp_register_params_vdev(struct rkisp_isp_params_vdev *params_vdev, struct v4l2_device *v4l2_dev, struct rkisp_device *dev) diff --git a/drivers/media/platform/rockchip/isp/isp_params.h b/drivers/media/platform/rockchip/isp/isp_params.h index 2d58aba98d16..b6bbf1d7ec66 100644 --- a/drivers/media/platform/rockchip/isp/isp_params.h +++ b/drivers/media/platform/rockchip/isp/isp_params.h @@ -42,6 +42,8 @@ struct rkisp_isp_params_ops { void (*fop_release)(struct rkisp_isp_params_vdev *params_vdev); bool (*check_bigmode)(struct rkisp_isp_params_vdev *params_vdev); int (*info2ddr_cfg)(struct rkisp_isp_params_vdev *params_vdev, void *arg); + void (*get_bay3d_buffd)(struct rkisp_isp_params_vdev *params_vdev, + struct rkisp_bay3dbuf_info *bay3dbuf); }; /* @@ -147,4 +149,6 @@ void rkisp_params_meshbuf_free(struct rkisp_isp_params_vdev *params_vdev, u64 id void rkisp_params_stream_stop(struct rkisp_isp_params_vdev *params_vdev); bool rkisp_params_check_bigmode(struct rkisp_isp_params_vdev *params_vdev); int rkisp_params_info2ddr_cfg(struct rkisp_isp_params_vdev *params_vdev, void *arg); +void rkisp_params_get_bay3d_buffd(struct rkisp_isp_params_vdev *params_vdev, + struct rkisp_bay3dbuf_info *bay3dbuf); #endif /* _RKISP_ISP_PARAM_H */ diff --git a/drivers/media/platform/rockchip/isp/isp_params_v21.c b/drivers/media/platform/rockchip/isp/isp_params_v21.c index e13e97ca53d0..c6f22d603754 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v21.c +++ b/drivers/media/platform/rockchip/isp/isp_params_v21.c @@ -3973,6 +3973,19 @@ end: return ispdev->is_bigmode = is_bigmode; } +static void +rkisp_params_get_bay3d_buffd_v21(struct rkisp_isp_params_vdev *params_vdev, + struct rkisp_bay3dbuf_info *bay3dbuf) +{ + struct rkisp_isp_params_val_v21 *priv_val = params_vdev->priv_val; + struct rkisp_dummy_buffer *buf = &priv_val->buf_3dnr; + + if (rkisp_buf_get_fd(params_vdev->dev, buf, true) < 0) + return; + bay3dbuf->iir_fd = buf->dma_fd; + bay3dbuf->iir_size = buf->size; +} + /* Not called when the camera active, thus not isr protection. */ static void rkisp_params_first_cfg_v2x(struct rkisp_isp_params_vdev *params_vdev) @@ -4330,6 +4343,7 @@ static struct rkisp_isp_params_ops rkisp_isp_params_ops_tbl = { .stream_stop = rkisp_params_stream_stop_v2x, .fop_release = rkisp_params_fop_release_v2x, .check_bigmode = rkisp_params_check_bigmode_v21, + .get_bay3d_buffd = rkisp_params_get_bay3d_buffd_v21, }; int rkisp_init_params_vdev_v21(struct rkisp_isp_params_vdev *params_vdev) diff --git a/drivers/media/platform/rockchip/isp/isp_params_v32.c b/drivers/media/platform/rockchip/isp/isp_params_v32.c index 23072b4628de..ac46505c917d 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v32.c +++ b/drivers/media/platform/rockchip/isp/isp_params_v32.c @@ -5209,9 +5209,9 @@ rkisp_params_info2ddr_cfg_v32(struct rkisp_isp_params_vdev *params_vdev, void *a priv_val->buf_info_owner = cfg->owner; return 0; case RKISP_INFO2DRR_OWNER_GAIN: - ctrl = ISP3X_GAIN_2DDR_mode(cfg->u.gain.gain2ddr_mode); + ctrl = ISP3X_GAIN_2DDR_MODE(cfg->u.gain.gain2ddr_mode); ctrl |= ISP3X_GAIN_2DDR_EN; - mask = ISP3X_GAIN_2DDR_mode(3); + mask = ISP3X_GAIN_2DDR_MODE(3); reg = ISP3X_GAIN_CTRL; if (cfg->wsize) @@ -5296,6 +5296,26 @@ err: return -ENOMEM; } +static void +rkisp_params_get_bay3d_buffd_v32(struct rkisp_isp_params_vdev *params_vdev, + struct rkisp_bay3dbuf_info *bay3dbuf) +{ + struct rkisp_isp_params_val_v32 *priv_val = params_vdev->priv_val; + struct rkisp_dummy_buffer *buf; + + buf = &priv_val->buf_3dnr_iir; + if (rkisp_buf_get_fd(params_vdev->dev, buf, true) < 0) + return; + bay3dbuf->iir_fd = buf->dma_fd; + bay3dbuf->iir_size = buf->size; + + buf = &priv_val->buf_3dnr_ds; + if (rkisp_buf_get_fd(params_vdev->dev, buf, true) < 0) + return; + bay3dbuf->u.v32.ds_fd = buf->dma_fd; + bay3dbuf->u.v32.ds_size = buf->size; +} + static void rkisp_params_stream_stop_v32(struct rkisp_isp_params_vdev *params_vdev) { @@ -5529,6 +5549,7 @@ static struct rkisp_isp_params_ops rkisp_isp_params_ops_tbl = { .fop_release = rkisp_params_fop_release_v32, .check_bigmode = rkisp_params_check_bigmode_v32, .info2ddr_cfg = rkisp_params_info2ddr_cfg_v32, + .get_bay3d_buffd = rkisp_params_get_bay3d_buffd_v32, }; int rkisp_init_params_vdev_v32(struct rkisp_isp_params_vdev *params_vdev) diff --git a/drivers/media/platform/rockchip/isp/isp_params_v3x.c b/drivers/media/platform/rockchip/isp/isp_params_v3x.c index 0491cc9bd8ba..96333d4e72a0 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v3x.c +++ b/drivers/media/platform/rockchip/isp/isp_params_v3x.c @@ -3526,26 +3526,26 @@ isp_bay3d_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) return; if (en) { - if (!priv_val->buf_3dnr_iir[id].mem_priv) { + if (!priv_val->buf_3dnr_iir.mem_priv) { dev_err(ispdev->dev, "no bay3d buffer available\n"); return; } - value = priv_val->buf_3dnr_iir[id].size; + value = priv_val->buf_3dnr_iir.size; isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_IIR_WR_SIZE, id); - value = priv_val->buf_3dnr_iir[id].dma_addr; + value = priv_val->buf_3dnr_iir.dma_addr + value * id; isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_IIR_WR_BASE, id); isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_IIR_RD_BASE, id); - value = priv_val->buf_3dnr_cur[id].size; + value = priv_val->buf_3dnr_cur.size; isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_CUR_WR_SIZE, id); - value = priv_val->buf_3dnr_cur[id].dma_addr; + value = priv_val->buf_3dnr_cur.dma_addr + value * id; isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_CUR_WR_BASE, id); isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_CUR_RD_BASE, id); - value = priv_val->buf_3dnr_ds[id].size; + value = priv_val->buf_3dnr_ds.size; isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_DS_WR_SIZE, id); - value = priv_val->buf_3dnr_ds[id].dma_addr; + value = priv_val->buf_3dnr_ds.dma_addr + value * id; isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_DS_WR_BASE, id); isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_DS_RD_BASE, id); @@ -4164,42 +4164,41 @@ rkisp_alloc_internal_buf(struct rkisp_isp_params_vdev *params_vdev, if (ispdev->hw_dev->unite) w = ALIGN(isp_sdev->in_crop.width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL, 16); - for (id = 0; id <= !!ispdev->hw_dev->unite; id++) { - size = ALIGN((w + w / 8) * h * 2, 16); + size = ALIGN((w + w / 8) * h * 2, 16); - priv_val->buf_3dnr_iir[id].size = size; - ret = rkisp_alloc_buffer(ispdev, &priv_val->buf_3dnr_iir[id]); - if (ret) { - dev_err(ispdev->dev, "alloc bay3d iir buf fail:%d\n", ret); - goto err_3dnr; - } + if (ispdev->hw_dev->unite) + size *= 2; + priv_val->buf_3dnr_iir.size = size; + ret = rkisp_alloc_buffer(ispdev, &priv_val->buf_3dnr_iir); + if (ret) { + dev_err(ispdev->dev, "alloc bay3d iir buf fail:%d\n", ret); + goto err_3dnr; + } + priv_val->buf_3dnr_cur.size = size; + ret = rkisp_alloc_buffer(ispdev, &priv_val->buf_3dnr_cur); + if (ret) { + rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_iir); + dev_err(ispdev->dev, "alloc bay3d cur buf fail:%d\n", ret); + goto err_3dnr; + } - priv_val->buf_3dnr_cur[id].size = size; - ret = rkisp_alloc_buffer(ispdev, &priv_val->buf_3dnr_cur[id]); - if (ret) { - rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_iir[id]); - dev_err(ispdev->dev, "alloc bay3d cur buf fail:%d\n", ret); - goto err_3dnr; - } - - size = 2 * ALIGN(w * h / 64, 16); - priv_val->buf_3dnr_ds[id].size = size; - ret = rkisp_alloc_buffer(ispdev, &priv_val->buf_3dnr_ds[id]); - if (ret) { - rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_iir[id]); - rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_cur[id]); - dev_err(ispdev->dev, "alloc bay3d ds buf fail:%d\n", ret); - goto err_3dnr; - } + size = 2 * ALIGN(w * h / 64, 16); + if (ispdev->hw_dev->unite) + size *= 2; + priv_val->buf_3dnr_ds.size = size; + ret = rkisp_alloc_buffer(ispdev, &priv_val->buf_3dnr_ds); + if (ret) { + rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_iir); + rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_cur); + dev_err(ispdev->dev, "alloc bay3d ds buf fail:%d\n", ret); + goto err_3dnr; } } return 0; err_3dnr: - for (id -= 1; id >= 0; id--) { - rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_iir[id]); - rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_cur[id]); - rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_ds[id]); - } + rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_iir); + rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_cur); + rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_ds); id = ispdev->hw_dev->unite ? 1 : 0; i = ISP3X_3DLUT_BUF_NUM; err_3dlut: @@ -4393,6 +4392,32 @@ end: return ispdev->is_bigmode = is_bigmode; } +static void +rkisp_params_get_bay3d_buffd_v3x(struct rkisp_isp_params_vdev *params_vdev, + struct rkisp_bay3dbuf_info *bay3dbuf) +{ + struct rkisp_isp_params_val_v3x *priv_val = params_vdev->priv_val; + struct rkisp_dummy_buffer *buf; + + buf = &priv_val->buf_3dnr_iir; + if (rkisp_buf_get_fd(params_vdev->dev, buf, true) < 0) + return; + bay3dbuf->iir_fd = buf->dma_fd; + bay3dbuf->iir_size = buf->size; + + buf = &priv_val->buf_3dnr_cur; + if (rkisp_buf_get_fd(params_vdev->dev, buf, true) < 0) + return; + bay3dbuf->u.v30.cur_fd = buf->dma_fd; + bay3dbuf->u.v30.cur_size = buf->size; + + buf = &priv_val->buf_3dnr_ds; + if (rkisp_buf_get_fd(params_vdev->dev, buf, true) < 0) + return; + bay3dbuf->u.v30.ds_fd = buf->dma_fd; + bay3dbuf->u.v30.ds_size = buf->size; +} + /* Not called when the camera active, thus not isr protection. */ static void rkisp_params_first_cfg_v3x(struct rkisp_isp_params_vdev *params_vdev) @@ -4615,10 +4640,10 @@ rkisp_params_stream_stop_v3x(struct rkisp_isp_params_vdev *params_vdev) priv_val = (struct rkisp_isp_params_val_v3x *)params_vdev->priv_val; tasklet_disable(&priv_val->lsc_tasklet); + rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_iir); + rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_cur); + rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_ds); for (id = 0; id <= !!ispdev->hw_dev->unite; id++) { - rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_iir[id]); - rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_cur[id]); - rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_ds[id]); for (i = 0; i < ISP3X_3DLUT_BUF_NUM; i++) rkisp_free_buffer(ispdev, &priv_val->buf_3dlut[id][i]); } @@ -4859,6 +4884,7 @@ static struct rkisp_isp_params_ops rkisp_isp_params_ops_tbl = { .stream_stop = rkisp_params_stream_stop_v3x, .fop_release = rkisp_params_fop_release_v3x, .check_bigmode = rkisp_params_check_bigmode_v3x, + .get_bay3d_buffd = rkisp_params_get_bay3d_buffd_v3x, }; int rkisp_init_params_vdev_v3x(struct rkisp_isp_params_vdev *params_vdev) diff --git a/drivers/media/platform/rockchip/isp/isp_params_v3x.h b/drivers/media/platform/rockchip/isp/isp_params_v3x.h index 0d5041ddf6f4..b7bc923521c8 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v3x.h +++ b/drivers/media/platform/rockchip/isp/isp_params_v3x.h @@ -183,9 +183,9 @@ struct rkisp_isp_params_val_v3x { struct rkisp_dummy_buffer buf_cac[ISP3_UNITE_MAX][ISP3X_MESH_BUF_NUM]; u32 buf_cac_idx[ISP3_UNITE_MAX]; - struct rkisp_dummy_buffer buf_3dnr_iir[ISP3_UNITE_MAX]; - struct rkisp_dummy_buffer buf_3dnr_cur[ISP3_UNITE_MAX]; - struct rkisp_dummy_buffer buf_3dnr_ds[ISP3_UNITE_MAX]; + struct rkisp_dummy_buffer buf_3dnr_iir; + struct rkisp_dummy_buffer buf_3dnr_cur; + struct rkisp_dummy_buffer buf_3dnr_ds; bool dhaz_en; bool drc_en; diff --git a/drivers/media/platform/rockchip/isp/procfs.c b/drivers/media/platform/rockchip/isp/procfs.c index 9e872088351e..8a0433118461 100644 --- a/drivers/media/platform/rockchip/isp/procfs.c +++ b/drivers/media/platform/rockchip/isp/procfs.c @@ -1009,26 +1009,26 @@ static void rkisp_proc_dump_mem(struct rkisp_device *dev) if (dev->isp_ver == ISP_V30) { struct rkisp_isp_params_val_v3x *p = dev->params_vdev.priv_val; - if (p->buf_3dnr_iir[0].mem_priv) { - if (!p->buf_3dnr_iir[0].is_need_vaddr) - p->buf_3dnr_iir[0].vaddr = - g_ops->vaddr(NULL, p->buf_3dnr_iir[0].mem_priv); - iir_addr = p->buf_3dnr_iir[0].vaddr; - iir_size = p->buf_3dnr_iir[0].size; + if (p->buf_3dnr_iir.mem_priv) { + if (!p->buf_3dnr_iir.is_need_vaddr) + p->buf_3dnr_iir.vaddr = + g_ops->vaddr(NULL, p->buf_3dnr_iir.mem_priv); + iir_addr = p->buf_3dnr_iir.vaddr; + iir_size = p->buf_3dnr_iir.size; } - if (p->buf_3dnr_cur[0].mem_priv) { - if (!p->buf_3dnr_cur[0].is_need_vaddr) - p->buf_3dnr_cur[0].vaddr = - g_ops->vaddr(NULL, p->buf_3dnr_cur[0].mem_priv); - cur_addr = p->buf_3dnr_cur[0].vaddr; - cur_size = p->buf_3dnr_cur[0].size; + if (p->buf_3dnr_cur.mem_priv) { + if (!p->buf_3dnr_cur.is_need_vaddr) + p->buf_3dnr_cur.vaddr = + g_ops->vaddr(NULL, p->buf_3dnr_cur.mem_priv); + cur_addr = p->buf_3dnr_cur.vaddr; + cur_size = p->buf_3dnr_cur.size; } - if (p->buf_3dnr_ds[0].mem_priv) { - if (!p->buf_3dnr_ds[0].is_need_vaddr) - p->buf_3dnr_ds[0].vaddr = - g_ops->vaddr(NULL, p->buf_3dnr_ds[0].mem_priv); - ds_addr = p->buf_3dnr_ds[0].vaddr; - ds_size = p->buf_3dnr_ds[0].size; + if (p->buf_3dnr_ds.mem_priv) { + if (!p->buf_3dnr_ds.is_need_vaddr) + p->buf_3dnr_ds.vaddr = + g_ops->vaddr(NULL, p->buf_3dnr_ds.mem_priv); + ds_addr = p->buf_3dnr_ds.vaddr; + ds_size = p->buf_3dnr_ds.size; } } diff --git a/drivers/media/platform/rockchip/isp/regs_v3x.h b/drivers/media/platform/rockchip/isp/regs_v3x.h index 5e4c85710ee1..0fe2e47254dd 100644 --- a/drivers/media/platform/rockchip/isp/regs_v3x.h +++ b/drivers/media/platform/rockchip/isp/regs_v3x.h @@ -2230,7 +2230,7 @@ /* GAIN */ #define ISP3X_GAIN_2DDR_EN BIT(24) -#define ISP3X_GAIN_2DDR_mode(a) (((a) & 0x3) << 25) +#define ISP3X_GAIN_2DDR_MODE(a) (((a) & 0x3) << 25) /* DPCC */ #define ISP3X_DPCC_WORKING BIT(30) diff --git a/drivers/media/platform/rockchip/isp/rkisp.c b/drivers/media/platform/rockchip/isp/rkisp.c index 441ba1a73bdd..b6d0271e7ffe 100644 --- a/drivers/media/platform/rockchip/isp/rkisp.c +++ b/drivers/media/platform/rockchip/isp/rkisp.c @@ -3595,6 +3595,9 @@ static long rkisp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) case RKISP_VICAP_CMD_MODE: ret = rkisp_set_work_mode_by_vicap(isp_dev, arg); break; + case RKISP_CMD_GET_BAY3D_BUFFD: + rkisp_params_get_bay3d_buffd(&isp_dev->params_vdev, arg); + break; default: ret = -ENOIOCTLCMD; } @@ -3607,103 +3610,91 @@ static long rkisp_compat_ioctl32(struct v4l2_subdev *sd, unsigned int cmd, unsigned long arg) { void __user *up = compat_ptr(arg); - struct isp2x_csi_trigger trigger; - struct rkisp_thunderboot_resmem resmem; - struct rkisp_ldchbuf_info ldchbuf; - struct rkisp_ldchbuf_size ldchsize; - struct rkisp_meshbuf_info meshbuf; - struct rkisp_meshbuf_size meshsize; - struct rkisp_thunderboot_shmem shmem; - struct isp2x_buf_idxfd idxfd; - struct rkisp_info2ddr info2ddr; + void *pbuf = NULL; long ret = 0; - u64 module_id; + u32 size = 0; + bool cp_t_us = false, cp_f_us = false; - if (!up && cmd != RKISP_CMD_FREE_SHARED_BUF) + if (!up && + cmd != RKISP_CMD_FREE_SHARED_BUF && + cmd != RKISP_CMD_MULTI_DEV_FORCE_ENUM) return -EINVAL; switch (cmd) { case RKISP_CMD_TRIGGER_READ_BACK: - if (copy_from_user(&trigger, up, sizeof(trigger))) - return -EFAULT; - ret = rkisp_ioctl(sd, cmd, &trigger); + size = sizeof(struct isp2x_csi_trigger); + cp_f_us = true; break; case RKISP_CMD_GET_SHARED_BUF: - if (!IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP)) { - ret = -ENOIOCTLCMD; - break; - } - ret = rkisp_ioctl(sd, cmd, &resmem); - if (!ret && copy_to_user(up, &resmem, sizeof(resmem))) - ret = -EFAULT; + if (!IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP)) + return -ENOIOCTLCMD; + size = sizeof(struct rkisp_thunderboot_resmem); + cp_t_us = true; break; case RKISP_CMD_FREE_SHARED_BUF: - if (!IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP)) { - ret = -ENOIOCTLCMD; - break; - } - ret = rkisp_ioctl(sd, cmd, NULL); + if (!IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP)) + return -ENOIOCTLCMD; + case RKISP_CMD_MULTI_DEV_FORCE_ENUM: break; case RKISP_CMD_GET_LDCHBUF_INFO: - ret = rkisp_ioctl(sd, cmd, &ldchbuf); - if (!ret && copy_to_user(up, &ldchbuf, sizeof(ldchbuf))) - ret = -EFAULT; + size = sizeof(struct rkisp_ldchbuf_info); + cp_t_us = true; break; case RKISP_CMD_SET_LDCHBUF_SIZE: - if (copy_from_user(&ldchsize, up, sizeof(ldchsize))) - return -EFAULT; - ret = rkisp_ioctl(sd, cmd, &ldchsize); + size = sizeof(struct rkisp_ldchbuf_size); + cp_f_us = true; break; case RKISP_CMD_GET_MESHBUF_INFO: - if (copy_from_user(&meshbuf, up, sizeof(meshbuf))) - return -EFAULT; - ret = rkisp_ioctl(sd, cmd, &meshbuf); - if (!ret && copy_to_user(up, &meshbuf, sizeof(meshbuf))) - ret = -EFAULT; + size = sizeof(struct rkisp_meshbuf_info); + cp_f_us = true; + cp_t_us = true; break; case RKISP_CMD_SET_MESHBUF_SIZE: - if (copy_from_user(&meshsize, up, sizeof(meshsize))) - return -EFAULT; - ret = rkisp_ioctl(sd, cmd, &meshsize); + size = sizeof(struct rkisp_meshbuf_size); + cp_f_us = true; break; case RKISP_CMD_GET_SHM_BUFFD: - if (!IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP)) { - ret = -ENOIOCTLCMD; - break; - } - if (copy_from_user(&shmem, up, sizeof(shmem))) - return -EFAULT; - ret = rkisp_ioctl(sd, cmd, &shmem); - if (!ret && copy_to_user(up, &shmem, sizeof(shmem))) - ret = -EFAULT; + if (!IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP)) + return -ENOIOCTLCMD; + size = sizeof(struct rkisp_thunderboot_shmem); + cp_f_us = true; + cp_t_us = true; break; case RKISP_CMD_GET_FBCBUF_FD: - ret = rkisp_ioctl(sd, cmd, &idxfd); - if (!ret && copy_to_user(up, &idxfd, sizeof(idxfd))) - ret = -EFAULT; + size = sizeof(struct isp2x_buf_idxfd); + cp_t_us = true; break; case RKISP_CMD_INFO2DDR: - if (copy_from_user(&info2ddr, up, sizeof(info2ddr))) - return -EFAULT; - ret = rkisp_ioctl(sd, cmd, &info2ddr); - if (!ret && copy_to_user(up, &info2ddr, sizeof(info2ddr))) - ret = -EFAULT; + size = sizeof(struct rkisp_info2ddr); + cp_f_us = true; + cp_t_us = true; break; case RKISP_CMD_MESHBUF_FREE: - if (copy_from_user(&module_id, up, sizeof(module_id))) - return -EFAULT; - ret = rkisp_ioctl(sd, cmd, &module_id); + size = sizeof(u64); + cp_f_us = true; break; - case RKISP_CMD_MULTI_DEV_FORCE_ENUM: - ret = rkisp_ioctl(sd, cmd, NULL); - break; - case RKISP_VICAP_CMD_SET_STREAM: - ret = rkisp_ioctl(sd, cmd, NULL); + case RKISP_CMD_GET_BAY3D_BUFFD: + size = sizeof(struct rkisp_bay3dbuf_info); + cp_t_us = true; break; default: - ret = -ENOIOCTLCMD; + return -ENOIOCTLCMD; } + if (size) { + pbuf = kmalloc(size, GFP_KERNEL); + if (!pbuf) + return -ENOMEM; + } + if (cp_f_us && copy_from_user(pbuf, up, size)) { + ret = -EFAULT; + goto free_buf; + } + ret = rkisp_ioctl(sd, cmd, pbuf); + if (!ret && cp_t_us && copy_to_user(up, pbuf, size)) + ret = -EFAULT; +free_buf: + kfree(pbuf); return ret; } #endif diff --git a/include/uapi/linux/rk-isp2-config.h b/include/uapi/linux/rk-isp2-config.h index fc5177820177..7ea04e6f9477 100644 --- a/include/uapi/linux/rk-isp2-config.h +++ b/include/uapi/linux/rk-isp2-config.h @@ -58,6 +58,9 @@ #define RKISP_CMD_MULTI_DEV_FORCE_ENUM \ _IO('V', BASE_VIDIOC_PRIVATE + 13) +#define RKISP_CMD_GET_BAY3D_BUFFD \ + _IOR('V', BASE_VIDIOC_PRIVATE + 15, struct rkisp_bay3dbuf_info) + /****************ISP VIDEO IOCTL******************************/ #define RKISP_CMD_GET_CSI_MEMORY_MODE \ @@ -318,6 +321,23 @@ struct isp2x_mesh_head { __u32 data_oft; } __attribute__ ((packed)); +struct rkisp_bay3dbuf_info { + int iir_fd; + int iir_size; + union { + struct { + int cur_fd; + int cur_size; + int ds_fd; + int ds_size; + } v30; + struct { + int ds_fd; + int ds_size; + } v32; + } u; +} __attribute__ ((packed)); + #define RKISP_CMSK_WIN_MAX 12 #define RKISP_CMSK_WIN_MAX_V30 8 #define RKISP_CMSK_MOSAIC_MODE 0 From 474d365d35c6fd1df2a04c029f25093cb921f432 Mon Sep 17 00:00:00 2001 From: Cai YiWei Date: Thu, 21 Sep 2023 16:46:07 +0800 Subject: [PATCH 33/34] media: rockchip: isp: fix isp32 lite frame buffer data read Change-Id: I1e8e19185bce2800a0aee2a1623b204adb07355d Signed-off-by: Cai YiWei --- drivers/media/platform/rockchip/isp/rkisp.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/media/platform/rockchip/isp/rkisp.c b/drivers/media/platform/rockchip/isp/rkisp.c index b6d0271e7ffe..74b8dab09249 100644 --- a/drivers/media/platform/rockchip/isp/rkisp.c +++ b/drivers/media/platform/rockchip/isp/rkisp.c @@ -843,6 +843,19 @@ run_next: else dev->irq_ends_mask &= ~ISP_FRAME_BP; + if (hw->is_frm_buf) { + val = ISP32L_WR_FRM_BUF_EN | ISP32L_RD_FRM_BUF_EN | + ISP32L_AXI_CONF_RD_ST_MODE | ISP32L_AXI_CONF_RD_DIS | + ISP32L_FRM_BUF_FORCE_UPD; + rkisp_write(dev, ISP32L_AXI_CONF_RD_CTRL, val, true); + + val = ISP32L_WR_FRM_BUF_EN | ISP32L_RD_FRM_BUF_EN | + ISP32L_AXI_CONF_RD_ST_MODE | ISP32L_AXI_CONF_RD_DIS | + ISP32L_AXI_CONF_RD_ST; + rkisp_write(dev, ISP32L_AXI_CONF_RD_CTRL, val, true); + udelay(25); + } + val = rkisp_read(dev, CSI2RX_CTRL0, true); val &= ~SW_IBUF_OP_MODE(0xf); tmp = SW_IBUF_OP_MODE(dev->rd_mode); From 3e0f15851925bfb45bfd19e16314ec3a389e3419 Mon Sep 17 00:00:00 2001 From: Cai YiWei Date: Tue, 3 Oct 2023 14:50:46 +0800 Subject: [PATCH 34/34] media: rockchip: isp: support 8k for isp32 lite Change-Id: I2ebd5bff4be4b646564a874ce801cc8c9bf261e1 Signed-off-by: Cai YiWei --- drivers/media/platform/rockchip/isp/capture.c | 43 +++- .../media/platform/rockchip/isp/capture_v30.c | 18 +- .../media/platform/rockchip/isp/capture_v32.c | 69 +++++- drivers/media/platform/rockchip/isp/common.c | 91 ++++--- drivers/media/platform/rockchip/isp/common.h | 18 +- drivers/media/platform/rockchip/isp/dev.c | 10 +- drivers/media/platform/rockchip/isp/dev.h | 41 +++- drivers/media/platform/rockchip/isp/dmarx.c | 38 ++- drivers/media/platform/rockchip/isp/hw.c | 12 +- .../media/platform/rockchip/isp/isp_params.c | 9 +- .../platform/rockchip/isp/isp_params_v1x.c | 1 + .../platform/rockchip/isp/isp_params_v21.c | 8 +- .../platform/rockchip/isp/isp_params_v2x.c | 1 + .../platform/rockchip/isp/isp_params_v32.c | 225 ++++++++---------- .../platform/rockchip/isp/isp_params_v32.h | 12 +- .../platform/rockchip/isp/isp_params_v3x.c | 132 +++------- .../platform/rockchip/isp/isp_params_v3x.h | 18 +- .../media/platform/rockchip/isp/isp_stats.c | 10 +- .../media/platform/rockchip/isp/isp_stats.h | 1 + .../platform/rockchip/isp/isp_stats_v1x.c | 14 +- .../platform/rockchip/isp/isp_stats_v21.c | 17 +- .../platform/rockchip/isp/isp_stats_v2x.c | 14 +- .../platform/rockchip/isp/isp_stats_v32.c | 62 +++-- .../platform/rockchip/isp/isp_stats_v3x.c | 52 ++-- drivers/media/platform/rockchip/isp/procfs.c | 188 +++++++-------- drivers/media/platform/rockchip/isp/regs.c | 99 +++++--- .../media/platform/rockchip/isp/regs_v2x.h | 11 +- drivers/media/platform/rockchip/isp/rkisp.c | 162 ++++++++----- drivers/media/platform/rockchip/isp/rkisp.h | 2 + 29 files changed, 751 insertions(+), 627 deletions(-) diff --git a/drivers/media/platform/rockchip/isp/capture.c b/drivers/media/platform/rockchip/isp/capture.c index 76165eb4ba92..e7c26e59e254 100644 --- a/drivers/media/platform/rockchip/isp/capture.c +++ b/drivers/media/platform/rockchip/isp/capture.c @@ -669,6 +669,19 @@ static int rkisp_set_fmt(struct rkisp_stream *stream, return -EINVAL; } + if ((dev->unite_div == ISP_UNITE_DIV4 || + (dev->isp_ver == ISP_V32_L && + stream->id == RKISP_STREAM_SP && + dev->unite_div == ISP_UNITE_DIV2)) && + (pixm->width != dev->isp_sdev.out_crop.width || + pixm->height != dev->isp_sdev.out_crop.height)) { + pixm->width = dev->isp_sdev.out_crop.width; + pixm->height = dev->isp_sdev.out_crop.height; + v4l2_warn(&dev->v4l2_dev, + "%s no support scale force to %dx%d\n", + __func__, pixm->width, pixm->height); + } + /* do checks on resolution */ restrict_rsz_resolution(stream, config, &max_rsz); if (stream->id == RKISP_STREAM_MP || @@ -1471,8 +1484,7 @@ static struct v4l2_rect *rkisp_update_crop(struct rkisp_stream *stream, const struct v4l2_rect *in) { struct rkisp_device *dev = stream->ispdev; - bool is_unite = !!dev->hw_dev->unite; - u32 align = is_unite ? 4 : 2; + u32 align = (dev->unite_div > ISP_UNITE_DIV1) ? 4 : 2; /* Not crop for MP bayer raw data and dmatx path */ if ((stream->id == RKISP_STREAM_MP && @@ -1492,6 +1504,7 @@ static struct v4l2_rect *rkisp_update_crop(struct rkisp_stream *stream, sel->left = ALIGN(sel->left, 2); sel->width = ALIGN(sel->width, align); + sel->height = ALIGN(sel->height, align); sel->left = clamp_t(u32, sel->left, 0, in->width - STREAM_MIN_MP_SP_INPUT_WIDTH); sel->top = clamp_t(u32, sel->top, 0, @@ -1500,11 +1513,19 @@ static struct v4l2_rect *rkisp_update_crop(struct rkisp_stream *stream, in->width - sel->left); sel->height = clamp_t(u32, sel->height, STREAM_MIN_MP_SP_INPUT_HEIGHT, in->height - sel->top); - if (is_unite && (sel->width + 2 * sel->left) != in->width) { + if (dev->unite_div > ISP_UNITE_DIV1 && + (sel->width + 2 * sel->left) != in->width) { sel->left = ALIGN_DOWN((in->width - sel->width) / 2, 2); v4l2_warn(&dev->v4l2_dev, - "try horizontal center crop(%d,%d)/%dx%d for dual isp\n", - sel->left, sel->top, sel->width, sel->height); + "try horizontal center left:%d width:%d for unite mode\n", + sel->left, sel->width); + } + if (dev->unite_div == ISP_UNITE_DIV4 && + (sel->height + 2 * sel->top) != in->height) { + sel->top = ALIGN_DOWN((in->height - sel->height) / 2, 2); + v4l2_warn(&dev->v4l2_dev, + "try vertical center top:%d height:%d for unite mode\n", + sel->top, sel->height); } stream->is_crop_upd = true; return sel; @@ -1764,11 +1785,15 @@ int rkisp_register_stream_vdevs(struct rkisp_device *dev) CIF_ISP_INPUT_H_MAX_V32_UNITE : CIF_ISP_INPUT_H_MAX_V32; ret = rkisp_register_stream_v32(dev); } else if (dev->isp_ver == ISP_V32_L) { - st_cfg->max_rsz_width = CIF_ISP_INPUT_W_MAX_V32_L; - st_cfg->max_rsz_height = CIF_ISP_INPUT_H_MAX_V32_L; + st_cfg->max_rsz_width = dev->hw_dev->unite ? + CIF_ISP_INPUT_W_MAX_V32_L_UNITE : CIF_ISP_INPUT_W_MAX_V32_L; + st_cfg->max_rsz_height = dev->hw_dev->unite ? + CIF_ISP_INPUT_H_MAX_V32_L_UNITE : CIF_ISP_INPUT_H_MAX_V32_L; st_cfg = &rkisp_sp_stream_config; - st_cfg->max_rsz_width = CIF_ISP_INPUT_W_MAX_V32_L; - st_cfg->max_rsz_height = CIF_ISP_INPUT_H_MAX_V32_L; + st_cfg->max_rsz_width = dev->hw_dev->unite ? + CIF_ISP_INPUT_W_MAX_V32_L_UNITE : CIF_ISP_INPUT_W_MAX_V32_L; + st_cfg->max_rsz_height = dev->hw_dev->unite ? + CIF_ISP_INPUT_H_MAX_V32_L_UNITE : CIF_ISP_INPUT_H_MAX_V32_L; ret = rkisp_register_stream_v32(dev); } diff --git a/drivers/media/platform/rockchip/isp/capture_v30.c b/drivers/media/platform/rockchip/isp/capture_v30.c index becf779ad925..abc4fc258586 100644 --- a/drivers/media/platform/rockchip/isp/capture_v30.c +++ b/drivers/media/platform/rockchip/isp/capture_v30.c @@ -635,7 +635,8 @@ static int fbc_config_mi(struct rkisp_stream *stream) u32 left_w = (stream->out_fmt.width / 2) & ~0xf; offs += left_w * mult; - rkisp_next_write(stream->ispdev, ISP3X_MPFBC_HEAD_OFFSET, offs, false); + rkisp_idx_write(stream->ispdev, ISP3X_MPFBC_HEAD_OFFSET, + offs, ISP_UNITE_RIGHT, false); } rkisp_unite_set_bits(stream->ispdev, ISP3X_MI_WR_CTRL, 0, CIF_MI_CTRL_INIT_BASE_EN | CIF_MI_CTRL_INIT_OFFSET_EN, false); @@ -784,18 +785,18 @@ static void update_mi(struct rkisp_stream *stream) reg = stream->config->mi.y_base_ad_init; val = stream->next_buf->buff_addr[RKISP_PLANE_Y]; val += ((stream->out_fmt.width / div) & ~0xf); - rkisp_next_write(dev, reg, val, false); + rkisp_idx_write(dev, reg, val, ISP_UNITE_RIGHT, false); reg = stream->config->mi.cb_base_ad_init; val = stream->next_buf->buff_addr[RKISP_PLANE_CB]; val += ((stream->out_fmt.width / div) & ~0xf) * mult; - rkisp_next_write(dev, reg, val, false); + rkisp_idx_write(dev, reg, val, ISP_UNITE_RIGHT, false); if (stream->id != RKISP_STREAM_FBC && stream->id != RKISP_STREAM_BP) { reg = stream->config->mi.cr_base_ad_init; val = stream->next_buf->buff_addr[RKISP_PLANE_CR]; val += ((stream->out_fmt.width / div) & ~0xf); - rkisp_next_write(dev, reg, val, false); + rkisp_idx_write(dev, reg, val, ISP_UNITE_RIGHT, false); } } @@ -836,9 +837,12 @@ static void update_mi(struct rkisp_stream *stream) v4l2_dbg(2, rkisp_debug, &dev->v4l2_dev, "%s stream:%d Y:0x%x CB:0x%x | Y_SHD:0x%x, right\n", __func__, stream->id, - rkisp_next_read(dev, stream->config->mi.y_base_ad_init, false), - rkisp_next_read(dev, stream->config->mi.cb_base_ad_init, false), - rkisp_next_read(dev, stream->config->mi.y_base_ad_shd, true)); + rkisp_idx_read(dev, stream->config->mi.y_base_ad_init, + ISP_UNITE_RIGHT, false), + rkisp_idx_read(dev, stream->config->mi.cb_base_ad_init, + ISP_UNITE_RIGHT, false), + rkisp_idx_read(dev, stream->config->mi.y_base_ad_shd, + ISP_UNITE_RIGHT, true)); } static struct streams_ops rkisp_mp_streams_ops = { diff --git a/drivers/media/platform/rockchip/isp/capture_v32.c b/drivers/media/platform/rockchip/isp/capture_v32.c index 52a7c6bfa1f0..24193d520b4c 100644 --- a/drivers/media/platform/rockchip/isp/capture_v32.c +++ b/drivers/media/platform/rockchip/isp/capture_v32.c @@ -1025,6 +1025,8 @@ static void update_mi(struct rkisp_stream *stream) { struct rkisp_device *dev = stream->ispdev; struct rkisp_dummy_buffer *dummy_buf = &stream->dummy_buf; + struct v4l2_pix_format_mplane *out_fmt = &stream->out_fmt; + u32 div = stream->out_isp_fmt.fourcc == V4L2_PIX_FMT_UYVY ? 1 : 2; u32 val, reg; bool is_cr_cfg = false; @@ -1048,22 +1050,63 @@ static void update_mi(struct rkisp_stream *stream) rkisp_write(dev, reg, val, false); } - if (dev->hw_dev->unite) { + if (dev->unite_div > ISP_UNITE_DIV1) { + /* right of image, or right top of image */ reg = stream->config->mi.y_base_ad_init; val = stream->next_buf->buff_addr[RKISP_PLANE_Y]; - val += ((stream->out_fmt.width / 2) & ~0xf); - rkisp_next_write(dev, reg, val, false); + val += ((out_fmt->width / div) & ~0xf); + rkisp_idx_write(dev, reg, val, ISP_UNITE_RIGHT, false); reg = stream->config->mi.cb_base_ad_init; val = stream->next_buf->buff_addr[RKISP_PLANE_CB]; - val += ((stream->out_fmt.width / 2) & ~0xf); - rkisp_next_write(dev, reg, val, false); + val += ((out_fmt->width / div) & ~0xf); + rkisp_idx_write(dev, reg, val, ISP_UNITE_RIGHT, false); if (is_cr_cfg) { reg = stream->config->mi.cr_base_ad_init; val = stream->next_buf->buff_addr[RKISP_PLANE_CR]; - val += ((stream->out_fmt.width / 2) & ~0xf); - rkisp_next_write(dev, reg, val, false); + val += ((out_fmt->width / div) & ~0xf); + rkisp_idx_write(dev, reg, val, ISP_UNITE_RIGHT, false); + } + } + + if (dev->unite_div == ISP_UNITE_DIV4) { + /* left bottom of image */ + reg = stream->config->mi.y_base_ad_init; + val = stream->next_buf->buff_addr[RKISP_PLANE_Y]; + val += (out_fmt->plane_fmt[0].bytesperline * out_fmt->height / 2); + rkisp_idx_write(dev, reg, val, ISP_UNITE_LEFT_B, false); + + reg = stream->config->mi.cb_base_ad_init; + val = stream->next_buf->buff_addr[RKISP_PLANE_CB]; + val += (out_fmt->plane_fmt[1].sizeimage / 2); + rkisp_idx_write(dev, reg, val, ISP_UNITE_LEFT_B, false); + + if (is_cr_cfg) { + reg = stream->config->mi.cr_base_ad_init; + val = stream->next_buf->buff_addr[RKISP_PLANE_CR]; + val += (out_fmt->plane_fmt[2].sizeimage / 2); + rkisp_idx_write(dev, reg, val, ISP_UNITE_LEFT_B, false); + } + /* right bottom of image */ + reg = stream->config->mi.y_base_ad_init; + val = stream->next_buf->buff_addr[RKISP_PLANE_Y]; + val += (out_fmt->plane_fmt[0].bytesperline * out_fmt->height / 2) + + ((out_fmt->width / div) & ~0xf); + rkisp_idx_write(dev, reg, val, ISP_UNITE_RIGHT_B, false); + + reg = stream->config->mi.cb_base_ad_init; + val = stream->next_buf->buff_addr[RKISP_PLANE_CB]; + val += (out_fmt->plane_fmt[1].sizeimage / 2) + + ((out_fmt->width / div) & ~0xf); + rkisp_idx_write(dev, reg, val, ISP_UNITE_RIGHT_B, false); + + if (is_cr_cfg) { + reg = stream->config->mi.cr_base_ad_init; + val = stream->next_buf->buff_addr[RKISP_PLANE_CR]; + val += (out_fmt->plane_fmt[2].sizeimage / 2) + + ((out_fmt->width / div) & ~0xf); + rkisp_idx_write(dev, reg, val, ISP_UNITE_RIGHT_B, false); } } @@ -1111,15 +1154,15 @@ static void update_mi(struct rkisp_stream *stream) } else if (dummy_buf->mem_priv) { val = dummy_buf->dma_addr; reg = stream->config->mi.y_base_ad_init; - rkisp_write(dev, reg, val, false); + rkisp_unite_write(dev, reg, val, false); /* wrap buf ENC */ if (dev->isp_ver == ISP_V32) val += stream->out_fmt.plane_fmt[0].bytesperline * dev->cap_dev.wrap_line; reg = stream->config->mi.cb_base_ad_init; - rkisp_write(dev, reg, val, false); + rkisp_unite_write(dev, reg, val, false); if (is_cr_cfg) { reg = stream->config->mi.cr_base_ad_init; - rkisp_write(dev, reg, val, false); + rkisp_unite_write(dev, reg, val, false); } } else if (stream->is_using_resmem) { /* resmem for fast stream NV12 output */ @@ -1138,7 +1181,7 @@ static void update_mi(struct rkisp_stream *stream) /* no next buf to preclose mi */ stream->ops->disable_mi(stream); /* no buf, force to close mi */ - if (!stream->curr_buf) + if (!stream->curr_buf && dev->hw_dev->is_single) stream_self_update(stream); } @@ -2304,8 +2347,8 @@ void rkisp_mi_v32_isr(u32 mis_val, struct rkisp_device *dev) v4l2_dbg(3, rkisp_debug, &dev->v4l2_dev, "mi isr:0x%x\n", mis_val); - if (dev->hw_dev->unite == ISP_UNITE_ONE && - dev->unite_index == ISP_UNITE_LEFT) { + if ((dev->unite_div == ISP_UNITE_DIV2 && dev->unite_index != ISP_UNITE_RIGHT) || + (dev->unite_div == ISP_UNITE_DIV4 && dev->unite_index != ISP_UNITE_RIGHT_B)) { rkisp_write(dev, ISP3X_MI_ICR, mis_val, true); goto end; } diff --git a/drivers/media/platform/rockchip/isp/common.c b/drivers/media/platform/rockchip/isp/common.c index f1e41f67e893..31fe49bd32f1 100644 --- a/drivers/media/platform/rockchip/isp/common.c +++ b/drivers/media/platform/rockchip/isp/common.c @@ -27,19 +27,31 @@ void rkisp_write(struct rkisp_device *dev, u32 reg, u32 val, bool is_direct) } } -void rkisp_next_write(struct rkisp_device *dev, u32 reg, u32 val, bool is_direct) +void rkisp_idx_write(struct rkisp_device *dev, u32 reg, u32 val, int idx, bool is_direct) { - u32 offset = RKISP_ISP_SW_MAX_SIZE + reg; - u32 *mem = dev->sw_base_addr + offset; - u32 *flag = dev->sw_base_addr + offset + RKISP_ISP_SW_REG_SIZE; + struct rkisp_hw_dev *hw = dev->hw_dev; + void __iomem *base_addr = hw->base_addr; + u32 *mem, *flag, offset = idx * RKISP_ISP_SW_MAX_SIZE; + if (!hw->unite) + offset = 0; + /* right for isp1 hardware */ + if (hw->unite == ISP_UNITE_TWO && (idx & 0x1)) + base_addr = hw->base_next_addr; + + mem = dev->sw_base_addr + reg + offset; + flag = dev->sw_base_addr + reg + RKISP_ISP_SW_REG_SIZE + offset; *mem = val; *flag = SW_REG_CACHE; if (dev->hw_dev->is_single || is_direct) { *flag = SW_REG_CACHE_SYNC; - if (dev->hw_dev->unite == ISP_UNITE_ONE) - return; - writel(val, dev->hw_dev->base_next_addr + reg); + if (dev->isp_ver == ISP_V32 && reg <= 0x200) + rv1106_sdmmc_get_lock(); + if (idx == ISP_UNITE_LEFT || + (hw->unite == ISP_UNITE_TWO && idx == ISP_UNITE_RIGHT)) + writel(val, base_addr + reg); + if (dev->isp_ver == ISP_V32 && reg <= 0x200) + rv1106_sdmmc_put_lock(); } } @@ -54,14 +66,22 @@ u32 rkisp_read(struct rkisp_device *dev, u32 reg, bool is_direct) return val; } -u32 rkisp_next_read(struct rkisp_device *dev, u32 reg, bool is_direct) +u32 rkisp_idx_read(struct rkisp_device *dev, u32 reg, int idx, bool is_direct) { - u32 val; + struct rkisp_hw_dev *hw = dev->hw_dev; + void __iomem *base_addr = hw->base_addr; + u32 val, offset = idx * RKISP_ISP_SW_MAX_SIZE; - if (dev->hw_dev->is_single || is_direct) - val = readl(dev->hw_dev->base_next_addr + reg); + if (!hw->unite) + offset = 0; + /* right for isp1 hardware */ + if (hw->unite == ISP_UNITE_TWO && (idx & 0x1)) + base_addr = hw->base_next_addr; + + if (hw->is_single || is_direct) + val = readl(base_addr + reg); else - val = *(u32 *)(dev->sw_base_addr + RKISP_ISP_SW_MAX_SIZE + reg); + val = *(u32 *)(dev->sw_base_addr + reg + offset); return val; } @@ -72,11 +92,11 @@ void rkisp_set_bits(struct rkisp_device *dev, u32 reg, u32 mask, u32 val, bool i rkisp_write(dev, reg, val | tmp, is_direct); } -void rkisp_next_set_bits(struct rkisp_device *dev, u32 reg, u32 mask, u32 val, bool is_direct) +void rkisp_idx_set_bits(struct rkisp_device *dev, u32 reg, u32 mask, u32 val, int idx, bool is_direct) { - u32 tmp = rkisp_next_read(dev, reg, is_direct) & ~mask; + u32 tmp = rkisp_idx_read(dev, reg, idx, is_direct) & ~mask; - rkisp_next_write(dev, reg, val | tmp, is_direct); + rkisp_idx_write(dev, reg, val | tmp, idx, is_direct); } void rkisp_clear_bits(struct rkisp_device *dev, u32 reg, u32 mask, bool is_direct) @@ -86,11 +106,11 @@ void rkisp_clear_bits(struct rkisp_device *dev, u32 reg, u32 mask, bool is_direc rkisp_write(dev, reg, tmp & ~mask, is_direct); } -void rkisp_next_clear_bits(struct rkisp_device *dev, u32 reg, u32 mask, bool is_direct) +void rkisp_idx_clear_bits(struct rkisp_device *dev, u32 reg, u32 mask, int idx, bool is_direct) { - u32 tmp = rkisp_next_read(dev, reg, is_direct); + u32 tmp = rkisp_idx_read(dev, reg, idx, is_direct); - rkisp_next_write(dev, reg, tmp & ~mask, is_direct); + rkisp_idx_write(dev, reg, tmp & ~mask, idx, is_direct); } void rkisp_write_reg_cache(struct rkisp_device *dev, u32 reg, u32 val) @@ -100,11 +120,14 @@ void rkisp_write_reg_cache(struct rkisp_device *dev, u32 reg, u32 val) *mem = val; } -void rkisp_next_write_reg_cache(struct rkisp_device *dev, u32 reg, u32 val) +void rkisp_idx_write_reg_cache(struct rkisp_device *dev, u32 reg, u32 val, int idx) { - u32 offset = RKISP_ISP_SW_MAX_SIZE + reg; - u32 *mem = dev->sw_base_addr + offset; + u32 offset = idx * RKISP_ISP_SW_MAX_SIZE; + u32 *mem; + if (!dev->hw_dev->unite) + offset = 0; + mem = dev->sw_base_addr + reg + offset; *mem = val; } @@ -113,9 +136,13 @@ u32 rkisp_read_reg_cache(struct rkisp_device *dev, u32 reg) return *(u32 *)(dev->sw_base_addr + reg); } -u32 rkisp_next_read_reg_cache(struct rkisp_device *dev, u32 reg) +u32 rkisp_idx_read_reg_cache(struct rkisp_device *dev, u32 reg, int idx) { - return *(u32 *)(dev->sw_base_addr + RKISP_ISP_SW_MAX_SIZE + reg); + u32 offset = idx * RKISP_ISP_SW_MAX_SIZE; + + if (!dev->hw_dev->unite) + offset = 0; + return *(u32 *)(dev->sw_base_addr + reg + offset); } void rkisp_set_reg_cache_bits(struct rkisp_device *dev, u32 reg, u32 mask, u32 val) @@ -125,11 +152,11 @@ void rkisp_set_reg_cache_bits(struct rkisp_device *dev, u32 reg, u32 mask, u32 v rkisp_write_reg_cache(dev, reg, val | tmp); } -void rkisp_next_set_reg_cache_bits(struct rkisp_device *dev, u32 reg, u32 mask, u32 val) +void rkisp_idx_set_reg_cache_bits(struct rkisp_device *dev, u32 reg, u32 mask, u32 val, int idx) { - u32 tmp = rkisp_next_read_reg_cache(dev, reg) & ~mask; + u32 tmp = rkisp_idx_read_reg_cache(dev, reg, idx) & ~mask; - rkisp_next_write_reg_cache(dev, reg, val | tmp); + rkisp_idx_write_reg_cache(dev, reg, val | tmp, idx); } void rkisp_clear_reg_cache_bits(struct rkisp_device *dev, u32 reg, u32 mask) @@ -139,11 +166,11 @@ void rkisp_clear_reg_cache_bits(struct rkisp_device *dev, u32 reg, u32 mask) rkisp_write_reg_cache(dev, reg, tmp & ~mask); } -void rkisp_next_clear_reg_cache_bits(struct rkisp_device *dev, u32 reg, u32 mask) +void rkisp_idx_clear_reg_cache_bits(struct rkisp_device *dev, u32 reg, u32 mask, int idx) { - u32 tmp = rkisp_next_read_reg_cache(dev, reg); + u32 tmp = rkisp_idx_read_reg_cache(dev, reg, idx); - rkisp_next_write_reg_cache(dev, reg, tmp & ~mask); + rkisp_idx_write_reg_cache(dev, reg, tmp & ~mask, idx); } void rkisp_update_regs(struct rkisp_device *dev, u32 start, u32 end) @@ -169,9 +196,9 @@ void rkisp_update_regs(struct rkisp_device *dev, u32 start, u32 end) continue; } - if (hw->unite == ISP_UNITE_ONE && dev->unite_index == ISP_UNITE_RIGHT) { - val = dev->sw_base_addr + i + RKISP_ISP_SW_MAX_SIZE; - flag = dev->sw_base_addr + i + RKISP_ISP_SW_MAX_SIZE + RKISP_ISP_SW_REG_SIZE; + if (hw->unite == ISP_UNITE_ONE && dev->unite_index > ISP_UNITE_LEFT) { + val += (RKISP_ISP_SW_MAX_SIZE * dev->unite_index / 4); + flag += (RKISP_ISP_SW_MAX_SIZE * dev->unite_index / 4); } if (*flag == SW_REG_CACHE) { diff --git a/drivers/media/platform/rockchip/isp/common.h b/drivers/media/platform/rockchip/isp/common.h index 8cb433b293b7..f5c1a1391cd5 100644 --- a/drivers/media/platform/rockchip/isp/common.h +++ b/drivers/media/platform/rockchip/isp/common.h @@ -176,16 +176,16 @@ u32 rkisp_read_reg_cache(struct rkisp_device *dev, u32 reg); void rkisp_set_reg_cache_bits(struct rkisp_device *dev, u32 reg, u32 mask, u32 val); void rkisp_clear_reg_cache_bits(struct rkisp_device *dev, u32 reg, u32 mask); -/* for dual isp, config for next isp reg */ -void rkisp_next_write(struct rkisp_device *dev, u32 reg, u32 val, bool is_direct); -u32 rkisp_next_read(struct rkisp_device *dev, u32 reg, bool is_direct); -void rkisp_next_set_bits(struct rkisp_device *dev, u32 reg, u32 mask, u32 val, bool is_direct); -void rkisp_next_clear_bits(struct rkisp_device *dev, u32 reg, u32 mask, bool is_direct); +/* for unite mode, config for diff isp reg */ +void rkisp_idx_write(struct rkisp_device *dev, u32 reg, u32 val, int idx, bool is_direct); +u32 rkisp_idx_read(struct rkisp_device *dev, u32 reg, int idx, bool is_direct); +void rkisp_idx_set_bits(struct rkisp_device *dev, u32 reg, u32 mask, u32 val, int idx, bool is_direct); +void rkisp_idx_clear_bits(struct rkisp_device *dev, u32 reg, u32 mask, int idx, bool is_direct); -void rkisp_next_write_reg_cache(struct rkisp_device *dev, u32 reg, u32 val); -u32 rkisp_next_read_reg_cache(struct rkisp_device *dev, u32 reg); -void rkisp_next_set_reg_cache_bits(struct rkisp_device *dev, u32 reg, u32 mask, u32 val); -void rkisp_next_clear_reg_cache_bits(struct rkisp_device *dev, u32 reg, u32 mask); +void rkisp_idx_write_reg_cache(struct rkisp_device *dev, u32 reg, u32 val, int idx); +u32 rkisp_idx_read_reg_cache(struct rkisp_device *dev, u32 reg, int idx); +void rkisp_idx_set_reg_cache_bits(struct rkisp_device *dev, u32 reg, u32 mask, u32 val, int idx); +void rkisp_idx_clear_reg_cache_bits(struct rkisp_device *dev, u32 reg, u32 mask, int idx); void rkisp_update_regs(struct rkisp_device *dev, u32 start, u32 end); diff --git a/drivers/media/platform/rockchip/isp/dev.c b/drivers/media/platform/rockchip/isp/dev.c index 2bb51ca8e6ff..11596db90c8e 100644 --- a/drivers/media/platform/rockchip/isp/dev.c +++ b/drivers/media/platform/rockchip/isp/dev.c @@ -183,7 +183,7 @@ static int __isp_pipeline_s_isp_clk(struct rkisp_pipeline *p) struct v4l2_subdev *sd; struct v4l2_ctrl *ctrl; u64 data_rate = 0; - int i, fps; + int i, fps, size; hw_dev->isp_size[dev->dev_id].is_on = true; if (hw_dev->is_runing) { @@ -200,14 +200,16 @@ static int __isp_pipeline_s_isp_clk(struct rkisp_pipeline *p) fps = hw_dev->isp_size[i].fps; if (!fps) fps = 30; - data_rate += (fps * hw_dev->isp_size[i].size); + size = hw_dev->isp_size[i].size * hw_dev->isp[i]->unite_div; + data_rate += (fps * size); } } else { i = dev->dev_id; fps = hw_dev->isp_size[i].fps; if (!fps) fps = 30; - data_rate = fps * hw_dev->isp_size[i].size; + size = hw_dev->isp_size[i].size * dev->unite_div; + data_rate = fps * size; } goto end; } @@ -868,7 +870,7 @@ static int rkisp_plat_probe(struct platform_device *pdev) return ret; if (isp_dev->hw_dev->unite) - mult = 2; + mult = ISP_UNITE_MAX; isp_dev->sw_base_addr = devm_kzalloc(dev, RKISP_ISP_SW_MAX_SIZE * mult, GFP_KERNEL); if (!isp_dev->sw_base_addr) return -ENOMEM; diff --git a/drivers/media/platform/rockchip/isp/dev.h b/drivers/media/platform/rockchip/isp/dev.h index 1c726a63cad3..6872f71364a3 100644 --- a/drivers/media/platform/rockchip/isp/dev.h +++ b/drivers/media/platform/rockchip/isp/dev.h @@ -114,13 +114,24 @@ enum { ISP_UNITE_ONE = 2, }; -/* left and right index - * ISP_UNITE_LEFT: left of image to isp process - * ISP_UNITE_RIGHT: right of image to isp process +/* image segmentation index + * ISP_UNITE_LEFT: left of image, or left top of image + * ISP_UNITE_RIGHT: right of image, or right top of image + * ISP_UNITE_LEFT_B: left bottom of image + * ISP_UNITE_RIGHT_B: right bottom of image */ enum { ISP_UNITE_LEFT = 0, - ISP_UNITE_RIGHT = 1, + ISP_UNITE_RIGHT, + ISP_UNITE_LEFT_B, + ISP_UNITE_RIGHT_B, + ISP_UNITE_MAX, +}; + +enum { + ISP_UNITE_DIV1 = 1, + ISP_UNITE_DIV2 = 2, + ISP_UNITE_DIV4 = 4, }; /* @@ -286,32 +297,36 @@ struct rkisp_device { u8 multi_index; u8 rawaf_irq_cnt; u8 unite_index; + u8 unite_div; }; static inline void rkisp_unite_write(struct rkisp_device *dev, u32 reg, u32 val, bool is_direct) { - rkisp_write(dev, reg, val, is_direct); - if (dev->hw_dev->unite) - rkisp_next_write(dev, reg, val, is_direct); + int i; + + for (i = 0; i < dev->unite_div; i++) + rkisp_idx_write(dev, reg, val, i, is_direct); } static inline void rkisp_unite_set_bits(struct rkisp_device *dev, u32 reg, u32 mask, u32 val, bool is_direct) { - rkisp_set_bits(dev, reg, mask, val, is_direct); - if (dev->hw_dev->unite) - rkisp_next_set_bits(dev, reg, mask, val, is_direct); + int i; + + for (i = 0; i < dev->unite_div; i++) + rkisp_idx_set_bits(dev, reg, mask, val, i, is_direct); } static inline void rkisp_unite_clear_bits(struct rkisp_device *dev, u32 reg, u32 mask, bool is_direct) { - rkisp_clear_bits(dev, reg, mask, is_direct); - if (dev->hw_dev->unite) - rkisp_next_clear_bits(dev, reg, mask, is_direct); + int i; + + for (i = 0; i < dev->unite_div; i++) + rkisp_idx_clear_bits(dev, reg, mask, i, is_direct); } static inline bool rkisp_link_sensor(u32 isp_inp) diff --git a/drivers/media/platform/rockchip/isp/dmarx.c b/drivers/media/platform/rockchip/isp/dmarx.c index e610f19351bc..1bf041e4db03 100644 --- a/drivers/media/platform/rockchip/isp/dmarx.c +++ b/drivers/media/platform/rockchip/isp/dmarx.c @@ -364,6 +364,7 @@ static void update_rawrd(struct rkisp_stream *stream) struct rkisp_device *dev = stream->ispdev; void __iomem *base = dev->base_addr; struct capture_fmt *fmt = &stream->out_isp_fmt; + u32 offs, offs_h = stream->out_fmt.width / 2 - RKMOUDLE_UNITE_EXTEND_PIXEL; u32 val = 0; if (stream->curr_buf) { @@ -374,15 +375,22 @@ static void update_rawrd(struct rkisp_stream *stream) } val += stream->curr_buf->buff_addr[RKISP_PLANE_Y]; rkisp_write(dev, stream->config->mi.y_base_ad_init, val, false); - if (dev->hw_dev->unite) { - u32 offs = stream->out_fmt.width / 2 - RKMOUDLE_UNITE_EXTEND_PIXEL; - if (stream->memory) - offs *= DIV_ROUND_UP(fmt->bpp[0], 8); - else - offs = offs * fmt->bpp[0] / 8; - val += offs; - rkisp_next_write(dev, stream->config->mi.y_base_ad_init, val, false); + if (stream->memory) + offs_h *= DIV_ROUND_UP(fmt->bpp[0], 8); + else + offs_h = offs_h * fmt->bpp[0] / 8; + if (dev->unite_div > ISP_UNITE_DIV1) + rkisp_idx_write(dev, stream->config->mi.y_base_ad_init, + val + offs_h, ISP_UNITE_RIGHT, false); + if (dev->unite_div == ISP_UNITE_DIV4) { + offs = stream->out_fmt.plane_fmt[0].bytesperline * + (stream->out_fmt.height / 2 - RKMOUDLE_UNITE_EXTEND_PIXEL); + rkisp_idx_write(dev, stream->config->mi.y_base_ad_init, + val + offs, ISP_UNITE_LEFT_B, false); + offs += offs_h; + rkisp_idx_write(dev, stream->config->mi.y_base_ad_init, + val + offs, ISP_UNITE_RIGHT_B, false); } stream->frame_end = false; if (stream->id == RKISP_STREAM_RAWRD2 && stream->out_isp_fmt.fmt_type == FMT_YUV) { @@ -1130,21 +1138,27 @@ void rkisp_rawrd_set_pic_size(struct rkisp_device *dev, { struct rkisp_isp_subdev *sdev = &dev->isp_sdev; u8 mult = sdev->in_fmt.fmt_type == FMT_YUV ? 2 : 1; - bool is_unite = !!dev->hw_dev->unite; - u32 w = !is_unite ? width : width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + u32 w, h; /* rx height should equal to isp height + offset for read back mode */ height = sdev->in_crop.top + sdev->in_crop.height; + w = width; + h = height; + if (dev->unite_div > ISP_UNITE_DIV1) + w = width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + if (dev->unite_div == ISP_UNITE_DIV4) + h = height / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + /* isp20 extend line for normal read back mode to fix internal bug */ if (dev->isp_ver == ISP_V20 && sdev->in_fmt.fmt_type == FMT_BAYER && sdev->out_fmt.fmt_type != FMT_BAYER && dev->rd_mode == HDR_RDBK_FRAME1) - height += RKMODULE_EXTEND_LINE; + h += RKMODULE_EXTEND_LINE; w *= mult; - rkisp_unite_write(dev, CSI2RX_RAW_RD_PIC_SIZE, height << 16 | w, false); + rkisp_unite_write(dev, CSI2RX_RAW_RD_PIC_SIZE, h << 16 | w, false); } void rkisp_dmarx_get_frame(struct rkisp_device *dev, u32 *id, diff --git a/drivers/media/platform/rockchip/isp/hw.c b/drivers/media/platform/rockchip/isp/hw.c index 4e6cc8fffeaf..4b4bb36bb4e2 100644 --- a/drivers/media/platform/rockchip/isp/hw.c +++ b/drivers/media/platform/rockchip/isp/hw.c @@ -111,7 +111,7 @@ static void default_sw_reg_flag(struct rkisp_device *dev) ISP3X_RAWHIST_BIG1_BASE, ISP3X_RAWHIST_BIG2_BASE, ISP3X_RAWHIST_BIG3_BASE, ISP3X_RAWAF_CTRL, ISP3X_RAWAWB_CTRL, }; - u32 i, *flag, *reg, size; + u32 i, j, *flag, *reg, size; switch (dev->isp_ver) { case ISP_V20: @@ -138,7 +138,7 @@ static void default_sw_reg_flag(struct rkisp_device *dev) for (i = 0; i < size; i++) { flag = dev->sw_base_addr + reg[i] + RKISP_ISP_SW_REG_SIZE; *flag = SW_REG_CACHE; - if (dev->hw_dev->unite) { + for (j = 1; j < ISP_UNITE_MAX && dev->hw_dev->unite; j++) { flag += RKISP_ISP_SW_MAX_SIZE / 4; *flag = SW_REG_CACHE; } @@ -1265,8 +1265,10 @@ void rkisp_hw_enum_isp_size(struct rkisp_hw_dev *hw_dev) hw_dev->is_single = false; w = isp->isp_sdev.in_crop.width; h = isp->isp_sdev.in_crop.height; - if (hw_dev->unite) + if (isp->unite_div > ISP_UNITE_DIV1) w = w / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + if (isp->unite_div == ISP_UNITE_DIV4) + h = h / 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; @@ -1293,7 +1295,7 @@ static int __maybe_unused rkisp_runtime_resume(struct device *dev) void __iomem *base = hw_dev->base_addr; struct rkisp_device *isp; int mult = hw_dev->unite ? 2 : 1; - int ret, i; + int ret, i, j; void *buf; ret = pinctrl_pm_select_default_state(dev); @@ -1316,7 +1318,7 @@ static int __maybe_unused rkisp_runtime_resume(struct device *dev) buf = isp->sw_base_addr; memset(buf, 0, RKISP_ISP_SW_MAX_SIZE * mult); memcpy_fromio(buf, base, RKISP_ISP_SW_REG_SIZE); - if (hw_dev->unite) { + for (j = 1; j < ISP_UNITE_MAX && hw_dev->unite; j++) { buf += RKISP_ISP_SW_MAX_SIZE; base = hw_dev->base_next_addr; memcpy_fromio(buf, base, RKISP_ISP_SW_REG_SIZE); diff --git a/drivers/media/platform/rockchip/isp/isp_params.c b/drivers/media/platform/rockchip/isp/isp_params.c index 3c4379ef479b..47f563c6ad80 100644 --- a/drivers/media/platform/rockchip/isp/isp_params.c +++ b/drivers/media/platform/rockchip/isp/isp_params.c @@ -46,8 +46,7 @@ static int rkisp_params_g_fmt_meta_out(struct file *file, void *fh, memset(meta, 0, sizeof(*meta)); meta->dataformat = params_vdev->vdev_fmt.fmt.meta.dataformat; - meta->buffersize = params_vdev->vdev_fmt.fmt.meta.buffersize; - + params_vdev->ops->get_param_size(params_vdev, &meta->buffersize); return 0; } @@ -349,11 +348,7 @@ static int rkisp_init_params_vdev(struct rkisp_isp_params_vdev *params_vdev) else ret = rkisp_init_params_vdev_v32(params_vdev); - params_vdev->vdev_fmt.fmt.meta.dataformat = - V4L2_META_FMT_RK_ISP1_PARAMS; - if (params_vdev->ops && params_vdev->ops->get_param_size) - params_vdev->ops->get_param_size(params_vdev, - ¶ms_vdev->vdev_fmt.fmt.meta.buffersize); + params_vdev->vdev_fmt.fmt.meta.dataformat = V4L2_META_FMT_RK_ISP1_PARAMS; return ret; } diff --git a/drivers/media/platform/rockchip/isp/isp_params_v1x.c b/drivers/media/platform/rockchip/isp/isp_params_v1x.c index 4ca6c6dbbd2c..98972a15fe2d 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v1x.c +++ b/drivers/media/platform/rockchip/isp/isp_params_v1x.c @@ -2239,6 +2239,7 @@ static void rkisp1_get_param_size_v1x(struct rkisp_isp_params_vdev *params_vdev, unsigned int sizes[]) { sizes[0] = sizeof(struct rkisp1_isp_params_cfg); + params_vdev->vdev_fmt.fmt.meta.buffersize = sizes[0]; } /* Not called when the camera active, thus not isr protection. */ diff --git a/drivers/media/platform/rockchip/isp/isp_params_v21.c b/drivers/media/platform/rockchip/isp/isp_params_v21.c index c6f22d603754..f30b5434f7bd 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v21.c +++ b/drivers/media/platform/rockchip/isp/isp_params_v21.c @@ -4105,6 +4105,7 @@ rkisp_get_param_size_v2x(struct rkisp_isp_params_vdev *params_vdev, unsigned int sizes[]) { sizes[0] = sizeof(struct isp2x_isp_params_cfg); + params_vdev->vdev_fmt.fmt.meta.buffersize = sizes[0]; } static void @@ -4350,13 +4351,16 @@ int rkisp_init_params_vdev_v21(struct rkisp_isp_params_vdev *params_vdev) { struct device *dev = params_vdev->dev->dev; struct rkisp_isp_params_val_v21 *priv_val; - int i, ret; + int i, ret, size; priv_val = kzalloc(sizeof(*priv_val), GFP_KERNEL); if (!priv_val) return -ENOMEM; - params_vdev->isp21_params = vmalloc(sizeof(*params_vdev->isp21_params)); + size = sizeof(struct isp21_isp_params_cfg); + if (params_vdev->dev->hw_dev->unite) + size *= ISP_UNITE_MAX; + params_vdev->isp21_params = vmalloc(size); if (!params_vdev->isp21_params) { kfree(priv_val); return -ENOMEM; diff --git a/drivers/media/platform/rockchip/isp/isp_params_v2x.c b/drivers/media/platform/rockchip/isp/isp_params_v2x.c index c1497a92ffd1..e0154623813c 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v2x.c +++ b/drivers/media/platform/rockchip/isp/isp_params_v2x.c @@ -4196,6 +4196,7 @@ rkisp_get_param_size_v2x(struct rkisp_isp_params_vdev *params_vdev, unsigned int sizes[]) { sizes[0] = sizeof(struct isp2x_isp_params_cfg); + params_vdev->vdev_fmt.fmt.meta.buffersize = sizes[0]; } static void diff --git a/drivers/media/platform/rockchip/isp/isp_params_v32.c b/drivers/media/platform/rockchip/isp/isp_params_v32.c index ac46505c917d..d1b1b31640cb 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v32.c +++ b/drivers/media/platform/rockchip/isp/isp_params_v32.c @@ -49,10 +49,7 @@ static inline void isp3_param_write(struct rkisp_isp_params_vdev *params_vdev, u32 value, u32 addr, u32 id) { - if (id == ISP3_LEFT) - rkisp_write(params_vdev->dev, addr, value, false); - else - rkisp_next_write(params_vdev->dev, addr, value, false); + rkisp_idx_write(params_vdev->dev, addr, value, id, false); } static inline u32 @@ -64,45 +61,27 @@ isp3_param_read_direct(struct rkisp_isp_params_vdev *params_vdev, u32 addr) static inline u32 isp3_param_read(struct rkisp_isp_params_vdev *params_vdev, u32 addr, u32 id) { - u32 val; - - if (id == ISP3_LEFT) - val = rkisp_read(params_vdev->dev, addr, false); - else - val = rkisp_next_read(params_vdev->dev, addr, false); - return val; + return rkisp_idx_read(params_vdev->dev, addr, id, false); } static inline u32 isp3_param_read_cache(struct rkisp_isp_params_vdev *params_vdev, u32 addr, u32 id) { - u32 val; - - if (id == ISP3_LEFT) - val = rkisp_read_reg_cache(params_vdev->dev, addr); - else - val = rkisp_next_read_reg_cache(params_vdev->dev, addr); - return val; + return rkisp_idx_read_reg_cache(params_vdev->dev, addr, id); } static inline void isp3_param_set_bits(struct rkisp_isp_params_vdev *params_vdev, u32 reg, u32 bit_mask, u32 id) { - if (id == ISP3_LEFT) - rkisp_set_bits(params_vdev->dev, reg, 0, bit_mask, false); - else - rkisp_next_set_bits(params_vdev->dev, reg, 0, bit_mask, false); + rkisp_idx_set_bits(params_vdev->dev, reg, 0, bit_mask, id, false); } static inline void isp3_param_clear_bits(struct rkisp_isp_params_vdev *params_vdev, u32 reg, u32 bit_mask, u32 id) { - if (id == ISP3_LEFT) - rkisp_clear_bits(params_vdev->dev, reg, bit_mask, false); - else - rkisp_next_clear_bits(params_vdev->dev, reg, bit_mask, false); + rkisp_idx_clear_bits(params_vdev->dev, reg, bit_mask, id, false); } static void @@ -1107,8 +1086,10 @@ isp_rawaf_config(struct rkisp_isp_params_vdev *params_vdev, arg->num_afm_win); struct isp2x_window win_ae; - if (dev->hw_dev->unite) + if (dev->unite_div > ISP_UNITE_DIV1) width = width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + if (dev->unite_div == ISP_UNITE_DIV4) + height = height / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; for (i = 0; i < num_of_win; i++) { h_size = arg->win[i].h_size; @@ -1367,8 +1348,11 @@ isp_rawaelite_config(struct rkisp_isp_params_vdev *params_vdev, ISP_PACK_2SHORT(h_offs, v_offs), ISP3X_RAWAE_LITE_OFFSET, id); - if (ispdev->hw_dev->unite) + if (ispdev->unite_div > ISP_UNITE_DIV1) width = width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + if (ispdev->unite_div == ISP_UNITE_DIV4) + height = height / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + h_size = arg->win.h_size; v_size = arg->win.v_size; if (!h_size || h_size + h_offs + 1 > width) @@ -1462,8 +1446,10 @@ isp_rawaebig_config(struct rkisp_isp_params_vdev *params_vdev, ISP_PACK_2SHORT(h_offs, v_offs), addr + ISP3X_RAWAE_BIG_OFFSET, id); - if (ispdev->hw_dev->unite) + if (ispdev->unite_div > ISP_UNITE_DIV1) width = width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + if (ispdev->unite_div == ISP_UNITE_DIV4) + height = height / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; h_size = arg->win.h_size; v_size = arg->win.v_size; if (!h_size || h_size + h_offs + 1 > width) @@ -1655,15 +1641,17 @@ isp_rawawb_config(struct rkisp_isp_params_vdev *params_vdev, value |= !!arg->ds16x8_mode_en << 7; isp3_param_write(params_vdev, value, ISP3X_RAWAWB_BLK_CTRL, id); - h_offs = arg->h_offs & ~0x1; v_offs = arg->v_offs & ~0x1; isp3_param_write(params_vdev, ISP_PACK_2SHORT(h_offs, v_offs), ISP3X_RAWAWB_WIN_OFFS, id); - if (dev->hw_dev->unite) + if (dev->unite_div > ISP_UNITE_DIV1) width = width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + if (dev->unite_div == ISP_UNITE_DIV4) + height = height / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + h_size = arg->h_size; v_size = arg->v_size; if (!h_size || h_size + h_offs > width) @@ -2344,8 +2332,11 @@ isp_rawhstlite_config(struct rkisp_isp_params_vdev *params_vdev, ISP_PACK_2SHORT(h_offs, v_offs), ISP3X_RAWHIST_LITE_OFFS, id); - if (ispdev->hw_dev->unite) + if (ispdev->unite_div > ISP_UNITE_DIV1) width = width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + if (ispdev->unite_div == ISP_UNITE_DIV4) + height = height / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + h_size = arg->win.h_size; v_size = arg->win.v_size; if (!h_size || h_size + h_offs + 1 > width) @@ -2499,8 +2490,11 @@ isp_rawhstbig_config(struct rkisp_isp_params_vdev *params_vdev, ISP_PACK_2SHORT(h_offs, v_offs), addr + ISP3X_RAWHIST_BIG_OFFS, id); - if (dev->hw_dev->unite) + if (dev->unite_div > ISP_UNITE_DIV1) width = width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + if (dev->unite_div == ISP_UNITE_DIV4) + height = height / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + h_size = arg->win.h_size; v_size = arg->win.v_size; if (!h_size || h_size + h_offs + 1 > width) @@ -4411,7 +4405,7 @@ rkisp_alloc_internal_buf(struct rkisp_isp_params_vdev *params_vdev, module_en_update = new_params->module_en_update; module_ens = new_params->module_ens; - for (id = 0; id <= !!dev->hw_dev->unite; id++) { + for (id = 0; id < dev->unite_div; id++) { priv_val->buf_3dlut_idx[id] = 0; for (i = 0; i < ISP32_3DLUT_BUF_NUM; i++) { if (priv_val->buf_3dlut[id][i].mem_priv) @@ -4438,8 +4432,10 @@ rkisp_alloc_internal_buf(struct rkisp_isp_params_vdev *params_vdev, u32 val, wrap_line, wsize, div; bool is_alloc; - if (dev->hw_dev->unite) + if (dev->unite_div > ISP_UNITE_DIV1) w = ALIGN(isp_sdev->in_crop.width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL, 16); + if (dev->unite_div == ISP_UNITE_DIV4) + h = ALIGN(isp_sdev->in_crop.height / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL, 16); priv_val->is_lo8x8 = (!new_params->others.bay3d_cfg.lo4x8_en && !new_params->others.bay3d_cfg.lo4x4_en); @@ -4459,8 +4455,8 @@ rkisp_alloc_internal_buf(struct rkisp_isp_params_vdev *params_vdev, div = is_bwopt_dis ? 1 : 2; val = ALIGN(wsize * h / div, 16); priv_val->bay3d_iir_size = val; - if (dev->hw_dev->unite) - val *= 2; + if (dev->unite_div > ISP_UNITE_DIV1) + val *= dev->unite_div; is_alloc = true; if (priv_val->buf_3dnr_iir.mem_priv) { if (val > priv_val->buf_3dnr_iir.size) @@ -4482,8 +4478,8 @@ rkisp_alloc_internal_buf(struct rkisp_isp_params_vdev *params_vdev, /* pixel to Byte and align */ val = ALIGN(val * 2, 16); priv_val->bay3d_ds_size = val; - if (dev->hw_dev->unite) - val *= 2; + if (dev->unite_div > ISP_UNITE_DIV1) + val *= dev->unite_div; is_alloc = true; if (priv_val->buf_3dnr_ds.mem_priv) { if (val > priv_val->buf_3dnr_ds.size) @@ -4542,8 +4538,7 @@ rkisp_alloc_internal_buf(struct rkisp_isp_params_vdev *params_vdev, if (dev->isp_ver == ISP_V32_L) { if (dev->hw_dev->is_frm_buf && !priv_val->buf_frm.mem_priv) { priv_val->buf_frm.size = ISP32_LITE_FRM_BUF_SIZE; - if (dev->hw_dev->unite) - priv_val->buf_frm.size *= 2; + priv_val->buf_frm.size *= dev->unite_div; ret = rkisp_alloc_buffer(dev, &priv_val->buf_frm); if (ret) { dev_err(dev->dev, "alloc frm buf fail:%d\n", ret); @@ -4573,7 +4568,7 @@ free_3dnr: rkisp_free_buffer(dev, &priv_val->buf_3dnr_iir); rkisp_free_buffer(dev, &priv_val->buf_3dnr_ds); err_3dnr: - id = dev->hw_dev->unite ? 1 : 0; + id = dev->unite_div - 1; i = ISP32_3DLUT_BUF_NUM; err_3dlut: for (; id >= 0; id--) { @@ -4598,6 +4593,8 @@ rkisp_params_check_bigmode_v32_lite(struct rkisp_isp_params_vdev *params_vdev) int i = 0, j = 0; bool is_bigmode = false; + if (hw->unite == ISP_UNITE_ONE) + hw->is_frm_buf = true; using_frm_buf: if (hw->is_frm_buf) { ispdev->multi_index = 0; @@ -4941,15 +4938,14 @@ static void rkisp_params_first_cfg_v32(struct rkisp_isp_params_vdev *params_vdev) { struct rkisp_device *dev = params_vdev->dev; - struct rkisp_hw_dev *hw = dev->hw_dev; - struct rkisp_isp_params_val_v32 *priv_val = - (struct rkisp_isp_params_val_v32 *)params_vdev->priv_val; + struct rkisp_isp_params_val_v32 *priv_val = params_vdev->priv_val; + struct isp32_isp_params_cfg *params = params_vdev->isp32_params; + int i; rkisp_params_check_bigmode_v32(params_vdev); spin_lock(¶ms_vdev->config_lock); /* override the default things */ - if (!params_vdev->isp32_params->module_cfg_update && - !params_vdev->isp32_params->module_en_update) + if (!params->module_cfg_update && !params->module_en_update) dev_warn(dev->dev, "can not get first iq setting in stream on\n"); priv_val->bay3d_en = 0; @@ -4958,39 +4954,28 @@ rkisp_params_first_cfg_v32(struct rkisp_isp_params_vdev *params_vdev) priv_val->lsc_en = 0; priv_val->mge_en = 0; priv_val->lut3d_en = 0; - if (hw->unite) { - if (dev->is_bigmode) - rkisp_next_set_bits(dev, ISP3X_ISP_CTRL1, 0, - ISP3X_BIGMODE_MANUAL | ISP3X_BIGMODE_FORCE_EN, false); - __isp_isr_meas_config(params_vdev, params_vdev->isp32_params + 1, RKISP_PARAMS_ALL, 1); - __isp_isr_other_config(params_vdev, params_vdev->isp32_params + 1, RKISP_PARAMS_ALL, 1); - __isp_isr_other_en(params_vdev, params_vdev->isp32_params + 1, RKISP_PARAMS_ALL, 1); - __isp_isr_meas_en(params_vdev, params_vdev->isp32_params + 1, RKISP_PARAMS_ALL, 1); - } if (dev->is_bigmode) - rkisp_set_bits(dev, ISP3X_ISP_CTRL1, 0, - ISP3X_BIGMODE_MANUAL | ISP3X_BIGMODE_FORCE_EN, false); - - __isp_isr_meas_config(params_vdev, params_vdev->isp32_params, RKISP_PARAMS_ALL, 0); - __isp_isr_other_config(params_vdev, params_vdev->isp32_params, RKISP_PARAMS_ALL, 0); - __isp_isr_other_en(params_vdev, params_vdev->isp32_params, RKISP_PARAMS_ALL, 0); - __isp_isr_meas_en(params_vdev, params_vdev->isp32_params, RKISP_PARAMS_ALL, 0); - + rkisp_unite_set_bits(dev, ISP3X_ISP_CTRL1, 0, + ISP3X_BIGMODE_MANUAL | ISP3X_BIGMODE_FORCE_EN, false); + for (i = 0; i < dev->unite_div; i++) { + __isp_isr_meas_config(params_vdev, params + i, RKISP_PARAMS_ALL, i); + __isp_isr_other_config(params_vdev, params + i, RKISP_PARAMS_ALL, i); + __isp_isr_other_en(params_vdev, params + i, RKISP_PARAMS_ALL, i); + __isp_isr_meas_en(params_vdev, params + i, RKISP_PARAMS_ALL, i); + } spin_unlock(¶ms_vdev->config_lock); if (dev->hw_dev->is_frm_buf && priv_val->buf_frm.mem_priv) { u32 size = priv_val->buf_frm.size; u32 addr = priv_val->buf_frm.dma_addr; - if (hw->unite) { - size /= 2; - isp3_param_write(params_vdev, size, ISP32L_FRM_BUF_WR_SIZE, 1); - isp3_param_write(params_vdev, addr + size, ISP32L_FRM_BUF_WR_BASE, 1); - isp3_param_write(params_vdev, addr + size, ISP32L_FRM_BUF_RD_BASE, 1); + if (dev->unite_div) + size /= dev->unite_div; + for (i = 0; i < dev->unite_div; i++) { + isp3_param_write(params_vdev, size, ISP32L_FRM_BUF_WR_SIZE, i); + isp3_param_write(params_vdev, addr + size * i, ISP32L_FRM_BUF_WR_BASE, i); + isp3_param_write(params_vdev, addr + size * i, ISP32L_FRM_BUF_RD_BASE, i); } - isp3_param_write(params_vdev, size, ISP32L_FRM_BUF_WR_SIZE, 0); - isp3_param_write(params_vdev, addr, ISP32L_FRM_BUF_WR_BASE, 0); - isp3_param_write(params_vdev, addr, ISP32L_FRM_BUF_RD_BASE, 0); } if (dev->hw_dev->is_single && (dev->isp_state & ISP_START)) rkisp_set_bits(dev, ISP3X_ISP_CTRL0, 0, CIF_ISP_CTRL_ISP_CFG_UPD, true); @@ -5004,10 +4989,9 @@ static void rkisp_save_first_param_v32(struct rkisp_isp_params_vdev *params_vdev static void rkisp_clear_first_param_v32(struct rkisp_isp_params_vdev *params_vdev) { - u32 size = sizeof(struct isp32_isp_params_cfg); + u32 mult = params_vdev->dev->hw_dev->unite ? ISP_UNITE_MAX : 1; + u32 size = sizeof(struct isp32_isp_params_cfg) * mult; - if (params_vdev->dev->hw_dev->unite) - size *= 2; memset(params_vdev->isp32_params, 0, size); } @@ -5117,9 +5101,10 @@ static void rkisp_get_param_size_v32(struct rkisp_isp_params_vdev *params_vdev, unsigned int sizes[]) { - u32 mult = params_vdev->dev->hw_dev->unite ? 2 : 1; + u32 mult = params_vdev->dev->unite_div; sizes[0] = sizeof(struct isp32_isp_params_cfg) * mult; + params_vdev->vdev_fmt.fmt.meta.buffersize = sizes[0]; } static void @@ -5173,7 +5158,7 @@ rkisp_params_free_meshbuf_v32(struct rkisp_isp_params_vdev *params_vdev, { int id; - for (id = 0; id <= !!params_vdev->dev->hw_dev->unite; id++) + for (id = 0; id < params_vdev->dev->unite_div; id++) rkisp_deinit_mesh_buf(params_vdev, module_id, id); } @@ -5332,7 +5317,7 @@ rkisp_params_stream_stop_v32(struct rkisp_isp_params_vdev *params_vdev) rkisp_free_buffer(ispdev, &priv_val->buf_lsclut[i]); for (i = 0; i < RKISP_STATS_DDR_BUF_NUM; i++) rkisp_free_buffer(ispdev, &ispdev->stats_vdev.stats_buf[i]); - for (id = 0; id <= !!ispdev->hw_dev->unite; id++) { + for (id = 0; id < ispdev->unite_div; id++) { for (i = 0; i < ISP32_3DLUT_BUF_NUM; i++) rkisp_free_buffer(ispdev, &priv_val->buf_3dlut[id][i]); } @@ -5348,7 +5333,7 @@ rkisp_params_fop_release_v32(struct rkisp_isp_params_vdev *params_vdev) { int id; - for (id = 0; id <= !!params_vdev->dev->hw_dev->unite; id++) { + for (id = 0; id < params_vdev->dev->unite_div; id++) { rkisp_deinit_mesh_buf(params_vdev, ISP32_MODULE_LDCH, id); rkisp_deinit_mesh_buf(params_vdev, ISP32_MODULE_CAC, id); } @@ -5358,14 +5343,14 @@ rkisp_params_fop_release_v32(struct rkisp_isp_params_vdev *params_vdev) static void rkisp_params_disable_isp_v32(struct rkisp_isp_params_vdev *params_vdev) { + int i; + params_vdev->isp32_params->module_ens = 0; params_vdev->isp32_params->module_en_update = 0x7ffffffffff; - __isp_isr_other_en(params_vdev, params_vdev->isp32_params, RKISP_PARAMS_ALL, 0); - __isp_isr_meas_en(params_vdev, params_vdev->isp32_params, RKISP_PARAMS_ALL, 0); - if (params_vdev->dev->hw_dev->unite) { - __isp_isr_other_en(params_vdev, params_vdev->isp32_params, RKISP_PARAMS_ALL, 1); - __isp_isr_meas_en(params_vdev, params_vdev->isp32_params, RKISP_PARAMS_ALL, 1); + for (i = 0; i < params_vdev->dev->unite_div; i++) { + __isp_isr_other_en(params_vdev, params_vdev->isp32_params, RKISP_PARAMS_ALL, i); + __isp_isr_meas_en(params_vdev, params_vdev->isp32_params, RKISP_PARAMS_ALL, i); } } @@ -5409,9 +5394,10 @@ static void rkisp_params_cfg_v32(struct rkisp_isp_params_vdev *params_vdev, u32 frame_id, enum rkisp_params_type type) { - struct rkisp_hw_dev *hw = params_vdev->dev->hw_dev; + struct rkisp_device *dev = params_vdev->dev; struct isp32_isp_params_cfg *new_params = NULL; struct rkisp_buffer *cur_buf = params_vdev->cur_buf; + int i; spin_lock(¶ms_vdev->config_lock); if (!params_vdev->streamon) @@ -5427,30 +5413,24 @@ rkisp_params_cfg_v32(struct rkisp_isp_params_vdev *params_vdev, list_del(&cur_buf->queue); if (list_empty(¶ms_vdev->params)) break; - else if (new_params->module_en_update || - (new_params->module_cfg_update & ISP32_MODULE_FORCE)) { + for (i = 0; i < dev->unite_div; i++) { /* update en immediately */ - __isp_isr_meas_config(params_vdev, new_params, RKISP_PARAMS_ALL, 0); - __isp_isr_other_config(params_vdev, new_params, RKISP_PARAMS_ALL, 0); - __isp_isr_other_en(params_vdev, new_params, RKISP_PARAMS_ALL, 0); - __isp_isr_meas_en(params_vdev, new_params, RKISP_PARAMS_ALL, 0); - new_params->module_cfg_update = 0; - if (hw->unite) { - struct isp32_isp_params_cfg *params = new_params + 1; - - __isp_isr_meas_config(params_vdev, params, RKISP_PARAMS_ALL, 1); - __isp_isr_other_config(params_vdev, params, RKISP_PARAMS_ALL, 1); - __isp_isr_other_en(params_vdev, params, RKISP_PARAMS_ALL, 1); - __isp_isr_meas_en(params_vdev, params, RKISP_PARAMS_ALL, 1); - params->module_cfg_update = 0; + if (new_params->module_en_update || + (new_params->module_cfg_update & ISP32_MODULE_FORCE)) { + __isp_isr_meas_config(params_vdev, + new_params, RKISP_PARAMS_ALL, i); + __isp_isr_other_config(params_vdev, + new_params, RKISP_PARAMS_ALL, i); + __isp_isr_other_en(params_vdev, + new_params, RKISP_PARAMS_ALL, i); + __isp_isr_meas_en(params_vdev, + new_params, RKISP_PARAMS_ALL, i); + new_params->module_cfg_update = 0; } - } - if (new_params->module_cfg_update & - (ISP32_MODULE_LDCH | ISP32_MODULE_CAC)) { - module_data_abandon(params_vdev, new_params, 0); - if (hw->unite) - module_data_abandon(params_vdev, new_params, 1); - + if (new_params->module_cfg_update & + (ISP32_MODULE_LDCH | ISP32_MODULE_CAC)) + module_data_abandon(params_vdev, new_params, i); + new_params++; } vb2_buffer_done(&cur_buf->vb.vb2_buf, VB2_BUF_STATE_DONE); cur_buf = NULL; @@ -5467,21 +5447,16 @@ rkisp_params_cfg_v32(struct rkisp_isp_params_vdev *params_vdev, goto unlock; new_params = (struct isp32_isp_params_cfg *)(cur_buf->vaddr[0]); - if (hw->unite) { - __isp_isr_meas_config(params_vdev, new_params + 1, type, 1); - __isp_isr_other_config(params_vdev, new_params + 1, type, 1); - __isp_isr_other_en(params_vdev, new_params + 1, type, 1); - __isp_isr_meas_en(params_vdev, new_params + 1, type, 1); + for (i = 0; i < dev->unite_div; i++) { + __isp_isr_meas_config(params_vdev, new_params, type, i); + __isp_isr_other_config(params_vdev, new_params, type, i); + __isp_isr_other_en(params_vdev, new_params, type, i); + __isp_isr_meas_en(params_vdev, new_params, type, i); + if (type != RKISP_PARAMS_IMD) + new_params->module_cfg_update = 0; + new_params++; } - __isp_isr_meas_config(params_vdev, new_params, type, 0); - __isp_isr_other_config(params_vdev, new_params, type, 0); - __isp_isr_other_en(params_vdev, new_params, type, 0); - __isp_isr_meas_en(params_vdev, new_params, type, 0); - if (type != RKISP_PARAMS_IMD) { - new_params->module_cfg_update = 0; - if (hw->unite) - (new_params++)->module_cfg_update = 0; vb2_buffer_done(&cur_buf->vb.vb2_buf, VB2_BUF_STATE_DONE); cur_buf = NULL; } @@ -5495,15 +5470,13 @@ static void rkisp_params_clear_fstflg(struct rkisp_isp_params_vdev *params_vdev) { u32 value = isp3_param_read(params_vdev, ISP3X_ISP_CTRL1, 0); + int i; value &= (ISP3X_YNR_FST_FRAME | ISP3X_ADRC_FST_FRAME | ISP3X_DHAZ_FST_FRAME | ISP3X_CNR_FST_FRAME | ISP3X_RAW3D_FST_FRAME | ISP32_SHP_FST_FRAME); - if (value) { - isp3_param_clear_bits(params_vdev, ISP3X_ISP_CTRL1, value, 0); - if (params_vdev->dev->hw_dev->unite) - isp3_param_clear_bits(params_vdev, ISP3X_ISP_CTRL1, value, 1); - } + for (i = 0; i < params_vdev->dev->unite_div && value; i++) + isp3_param_clear_bits(params_vdev, ISP3X_ISP_CTRL1, value, i); } static void @@ -5563,7 +5536,7 @@ int rkisp_init_params_vdev_v32(struct rkisp_isp_params_vdev *params_vdev) size = sizeof(struct isp32_isp_params_cfg); if (params_vdev->dev->hw_dev->unite) - size *= 2; + size *= ISP_UNITE_MAX; params_vdev->isp32_params = vmalloc(size); if (!params_vdev->isp32_params) { kfree(priv_val); diff --git a/drivers/media/platform/rockchip/isp/isp_params_v32.h b/drivers/media/platform/rockchip/isp/isp_params_v32.h index e1d91488d177..62c89ef9c1db 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v32.h +++ b/drivers/media/platform/rockchip/isp/isp_params_v32.h @@ -175,14 +175,14 @@ struct rkisp_isp_params_ops_v32 { struct rkisp_isp_params_val_v32 { struct tasklet_struct lsc_tasklet; - struct rkisp_dummy_buffer buf_3dlut[ISP3_UNITE_MAX][ISP32_3DLUT_BUF_NUM]; - u32 buf_3dlut_idx[ISP3_UNITE_MAX]; + struct rkisp_dummy_buffer buf_3dlut[ISP_UNITE_MAX][ISP32_3DLUT_BUF_NUM]; + u32 buf_3dlut_idx[ISP_UNITE_MAX]; - struct rkisp_dummy_buffer buf_ldch[ISP3_UNITE_MAX][ISP3X_MESH_BUF_NUM]; - u32 buf_ldch_idx[ISP3_UNITE_MAX]; + struct rkisp_dummy_buffer buf_ldch[ISP_UNITE_MAX][ISP3X_MESH_BUF_NUM]; + u32 buf_ldch_idx[ISP_UNITE_MAX]; - struct rkisp_dummy_buffer buf_cac[ISP3_UNITE_MAX][ISP3X_MESH_BUF_NUM]; - u32 buf_cac_idx[ISP3_UNITE_MAX]; + struct rkisp_dummy_buffer buf_cac[ISP_UNITE_MAX][ISP3X_MESH_BUF_NUM]; + u32 buf_cac_idx[ISP_UNITE_MAX]; struct rkisp_dummy_buffer buf_lsclut[ISP32_LSC_LUT_BUF_NUM]; u32 buf_lsclut_idx; diff --git a/drivers/media/platform/rockchip/isp/isp_params_v3x.c b/drivers/media/platform/rockchip/isp/isp_params_v3x.c index 96333d4e72a0..613fdc00d02d 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v3x.c +++ b/drivers/media/platform/rockchip/isp/isp_params_v3x.c @@ -28,79 +28,49 @@ static inline void isp3_param_write_direct(struct rkisp_isp_params_vdev *params_vdev, u32 value, u32 addr, u32 id) { - if (id == ISP3_LEFT) - rkisp_write(params_vdev->dev, addr, value, true); - else - rkisp_next_write(params_vdev->dev, addr, value, true); + rkisp_idx_write(params_vdev->dev, addr, value, id, true); } static inline void isp3_param_write(struct rkisp_isp_params_vdev *params_vdev, u32 value, u32 addr, u32 id) { - if (id == ISP3_LEFT) - rkisp_write(params_vdev->dev, addr, value, false); - else - rkisp_next_write(params_vdev->dev, addr, value, false); + rkisp_idx_write(params_vdev->dev, addr, value, id, false); } static inline u32 isp3_param_read_direct(struct rkisp_isp_params_vdev *params_vdev, u32 addr, u32 id) { - u32 val; - - if (id == ISP3_LEFT) - val = rkisp_read(params_vdev->dev, addr, true); - else - val = rkisp_next_read(params_vdev->dev, addr, true); - return val; + return rkisp_idx_read(params_vdev->dev, addr, id, true); } static inline u32 isp3_param_read(struct rkisp_isp_params_vdev *params_vdev, u32 addr, u32 id) { - u32 val; - - if (id == ISP3_LEFT) - val = rkisp_read(params_vdev->dev, addr, false); - else - val = rkisp_next_read(params_vdev->dev, addr, false); - return val; + return rkisp_idx_read(params_vdev->dev, addr, id, false); } static inline u32 isp3_param_read_cache(struct rkisp_isp_params_vdev *params_vdev, u32 addr, u32 id) { - u32 val; - - if (id == ISP3_LEFT) - val = rkisp_read_reg_cache(params_vdev->dev, addr); - else - val = rkisp_next_read_reg_cache(params_vdev->dev, addr); - return val; + return rkisp_idx_read_reg_cache(params_vdev->dev, addr, id); } static inline void isp3_param_set_bits(struct rkisp_isp_params_vdev *params_vdev, u32 reg, u32 bit_mask, u32 id) { - if (id == ISP3_LEFT) - rkisp_set_bits(params_vdev->dev, reg, 0, bit_mask, false); - else - rkisp_next_set_bits(params_vdev->dev, reg, 0, bit_mask, false); + rkisp_idx_set_bits(params_vdev->dev, reg, 0, bit_mask, id, false); } static inline void isp3_param_clear_bits(struct rkisp_isp_params_vdev *params_vdev, u32 reg, u32 bit_mask, u32 id) { - if (id == ISP3_LEFT) - rkisp_clear_bits(params_vdev->dev, reg, bit_mask, false); - else - rkisp_next_clear_bits(params_vdev->dev, reg, bit_mask, false); + rkisp_idx_clear_bits(params_vdev->dev, reg, bit_mask, id, false); } static void @@ -3531,19 +3501,19 @@ isp_bay3d_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) return; } - value = priv_val->buf_3dnr_iir.size; + value = priv_val->bay3d_iir_size; isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_IIR_WR_SIZE, id); value = priv_val->buf_3dnr_iir.dma_addr + value * id; isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_IIR_WR_BASE, id); isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_IIR_RD_BASE, id); - value = priv_val->buf_3dnr_cur.size; + value = priv_val->bay3d_iir_size; isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_CUR_WR_SIZE, id); value = priv_val->buf_3dnr_cur.dma_addr + value * id; isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_CUR_WR_BASE, id); isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_CUR_RD_BASE, id); - value = priv_val->buf_3dnr_ds.size; + value = priv_val->bay3d_ds_size; isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_DS_WR_SIZE, id); value = priv_val->buf_3dnr_ds.dma_addr + value * id; isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_DS_WR_BASE, id); @@ -4166,6 +4136,7 @@ rkisp_alloc_internal_buf(struct rkisp_isp_params_vdev *params_vdev, size = ALIGN((w + w / 8) * h * 2, 16); + priv_val->bay3d_iir_size = size; if (ispdev->hw_dev->unite) size *= 2; priv_val->buf_3dnr_iir.size = size; @@ -4183,6 +4154,7 @@ rkisp_alloc_internal_buf(struct rkisp_isp_params_vdev *params_vdev, } size = 2 * ALIGN(w * h / 64, 16); + priv_val->bay3d_ds_size = size; if (ispdev->hw_dev->unite) size *= 2; priv_val->buf_3dnr_ds.size = size; @@ -4423,15 +4395,14 @@ static void rkisp_params_first_cfg_v3x(struct rkisp_isp_params_vdev *params_vdev) { struct rkisp_device *dev = params_vdev->dev; - struct rkisp_isp_params_val_v3x *priv_val = - (struct rkisp_isp_params_val_v3x *)params_vdev->priv_val; - struct rkisp_hw_dev *hw = params_vdev->dev->hw_dev; + struct rkisp_isp_params_val_v3x *priv_val = params_vdev->priv_val; + struct isp3x_isp_params_cfg *params = params_vdev->isp3x_params; + int i; dev->is_bigmode = rkisp_params_check_bigmode_v3x(params_vdev); spin_lock(¶ms_vdev->config_lock); /* override the default things */ - if (!params_vdev->isp3x_params->module_cfg_update && - !params_vdev->isp3x_params->module_en_update) + if (!params->module_cfg_update && !params->module_en_update) dev_warn(dev->dev, "can not get first iq setting in stream on\n"); priv_val->bay3d_en = 0; @@ -4440,22 +4411,15 @@ rkisp_params_first_cfg_v3x(struct rkisp_isp_params_vdev *params_vdev) priv_val->lsc_en = 0; priv_val->mge_en = 0; priv_val->lut3d_en = 0; - if (hw->unite) { - if (dev->is_bigmode) - rkisp_next_set_bits(params_vdev->dev, ISP3X_ISP_CTRL1, 0, - ISP3X_BIGMODE_MANUAL | ISP3X_BIGMODE_FORCE_EN, false); - __isp_isr_meas_config(params_vdev, params_vdev->isp3x_params + 1, RKISP_PARAMS_ALL, 1); - __isp_isr_other_config(params_vdev, params_vdev->isp3x_params + 1, RKISP_PARAMS_ALL, 1); - __isp_isr_other_en(params_vdev, params_vdev->isp3x_params + 1, RKISP_PARAMS_ALL, 1); - __isp_isr_meas_en(params_vdev, params_vdev->isp3x_params + 1, RKISP_PARAMS_ALL, 1); - } if (dev->is_bigmode) - rkisp_set_bits(params_vdev->dev, ISP3X_ISP_CTRL1, 0, - ISP3X_BIGMODE_MANUAL | ISP3X_BIGMODE_FORCE_EN, false); - __isp_isr_meas_config(params_vdev, params_vdev->isp3x_params, RKISP_PARAMS_ALL, 0); - __isp_isr_other_config(params_vdev, params_vdev->isp3x_params, RKISP_PARAMS_ALL, 0); - __isp_isr_other_en(params_vdev, params_vdev->isp3x_params, RKISP_PARAMS_ALL, 0); - __isp_isr_meas_en(params_vdev, params_vdev->isp3x_params, RKISP_PARAMS_ALL, 0); + rkisp_unite_set_bits(dev, ISP3X_ISP_CTRL1, 0, + ISP3X_BIGMODE_MANUAL | ISP3X_BIGMODE_FORCE_EN, false); + for (i = 0; i < dev->unite_div; i++) { + __isp_isr_meas_config(params_vdev, params + i, RKISP_PARAMS_ALL, i); + __isp_isr_other_config(params_vdev, params + i, RKISP_PARAMS_ALL, i); + __isp_isr_other_en(params_vdev, params + i, RKISP_PARAMS_ALL, i); + __isp_isr_meas_en(params_vdev, params + i, RKISP_PARAMS_ALL, i); + } spin_unlock(¶ms_vdev->config_lock); } @@ -4471,7 +4435,7 @@ static void rkisp_save_first_param_v3x(struct rkisp_isp_params_vdev *params_vdev static void rkisp_clear_first_param_v3x(struct rkisp_isp_params_vdev *params_vdev) { - u32 mult = params_vdev->dev->hw_dev->unite ? ISP3_UNITE_MAX : 1; + u32 mult = params_vdev->dev->hw_dev->unite ? ISP_UNITE_MAX : 1; u32 size = sizeof(struct isp3x_isp_params_cfg) * mult; memset(params_vdev->isp3x_params, 0, size); @@ -4570,9 +4534,10 @@ static void rkisp_get_param_size_v3x(struct rkisp_isp_params_vdev *params_vdev, unsigned int sizes[]) { - u32 mult = params_vdev->dev->hw_dev->unite ? ISP3_UNITE_MAX : 1; + u32 mult = params_vdev->dev->unite_div; sizes[0] = sizeof(struct isp3x_isp_params_cfg) * mult; + params_vdev->vdev_fmt.fmt.meta.buffersize = sizes[0]; } static void @@ -4803,43 +4768,14 @@ static void rkisp_params_clear_fstflg(struct rkisp_isp_params_vdev *params_vdev) { struct rkisp_device *dev = params_vdev->dev; - struct rkisp_hw_dev *hw_dev = dev->hw_dev; - u32 value; + u32 value, i; value = rkisp_read(dev, ISP3X_ISP_CTRL1, false); - if (value & ISP3X_YNR_FST_FRAME) - rkisp_clear_bits(params_vdev->dev, ISP3X_ISP_CTRL1, - ISP3X_YNR_FST_FRAME, false); - if (value & ISP3X_ADRC_FST_FRAME) - rkisp_clear_bits(params_vdev->dev, ISP3X_ISP_CTRL1, - ISP3X_ADRC_FST_FRAME, false); - if (value & ISP3X_DHAZ_FST_FRAME) - rkisp_clear_bits(params_vdev->dev, ISP3X_ISP_CTRL1, - ISP3X_DHAZ_FST_FRAME, false); - if (value & ISP3X_CNR_FST_FRAME) - rkisp_clear_bits(params_vdev->dev, ISP3X_ISP_CTRL1, - ISP3X_CNR_FST_FRAME, false); - if (value & ISP3X_RAW3D_FST_FRAME) - rkisp_clear_bits(params_vdev->dev, ISP3X_ISP_CTRL1, - ISP3X_RAW3D_FST_FRAME, false); - if (hw_dev->unite) { - value = rkisp_next_read(dev, ISP3X_ISP_CTRL1, false); - if (value & ISP3X_YNR_FST_FRAME) - rkisp_next_clear_bits(params_vdev->dev, ISP3X_ISP_CTRL1, - ISP3X_YNR_FST_FRAME, false); - if (value & ISP3X_ADRC_FST_FRAME) - rkisp_next_clear_bits(params_vdev->dev, ISP3X_ISP_CTRL1, - ISP3X_ADRC_FST_FRAME, false); - if (value & ISP3X_DHAZ_FST_FRAME) - rkisp_next_clear_bits(params_vdev->dev, ISP3X_ISP_CTRL1, - ISP3X_DHAZ_FST_FRAME, false); - if (value & ISP3X_CNR_FST_FRAME) - rkisp_next_clear_bits(params_vdev->dev, ISP3X_ISP_CTRL1, - ISP3X_CNR_FST_FRAME, false); - if (value & ISP3X_RAW3D_FST_FRAME) - rkisp_next_clear_bits(params_vdev->dev, ISP3X_ISP_CTRL1, - ISP3X_RAW3D_FST_FRAME, false); - } + value &= ISP3X_YNR_FST_FRAME | ISP3X_ADRC_FST_FRAME | + ISP3X_DHAZ_FST_FRAME | ISP3X_CNR_FST_FRAME | + ISP3X_RAW3D_FST_FRAME; + for (i = 0; i < dev->unite_div && value; i++) + rkisp_idx_clear_bits(dev, ISP3X_ISP_CTRL1, value, i, false); } static void @@ -4899,7 +4835,7 @@ int rkisp_init_params_vdev_v3x(struct rkisp_isp_params_vdev *params_vdev) size = sizeof(struct isp3x_isp_params_cfg); if (ispdev->hw_dev->unite) - size *= 2; + size *= ISP_UNITE_MAX; params_vdev->isp3x_params = vmalloc(size); if (!params_vdev->isp3x_params) { kfree(priv_val); diff --git a/drivers/media/platform/rockchip/isp/isp_params_v3x.h b/drivers/media/platform/rockchip/isp/isp_params_v3x.h index b7bc923521c8..4d0a75ce312a 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v3x.h +++ b/drivers/media/platform/rockchip/isp/isp_params_v3x.h @@ -171,21 +171,23 @@ struct rkisp_isp_params_ops_v3x { struct rkisp_isp_params_val_v3x { struct tasklet_struct lsc_tasklet; - struct rkisp_dummy_buffer buf_3dlut[ISP3_UNITE_MAX][ISP3X_3DLUT_BUF_NUM]; - u32 buf_3dlut_idx[ISP3_UNITE_MAX]; + struct rkisp_dummy_buffer buf_3dlut[ISP_UNITE_MAX][ISP3X_3DLUT_BUF_NUM]; + u32 buf_3dlut_idx[ISP_UNITE_MAX]; - struct rkisp_dummy_buffer buf_ldch[ISP3_UNITE_MAX][ISP3X_MESH_BUF_NUM]; - u32 buf_ldch_idx[ISP3_UNITE_MAX]; + struct rkisp_dummy_buffer buf_ldch[ISP_UNITE_MAX][ISP3X_MESH_BUF_NUM]; + u32 buf_ldch_idx[ISP_UNITE_MAX]; - struct rkisp_dummy_buffer buf_lsclut[ISP3_UNITE_MAX][ISP3X_LSC_LUT_BUF_NUM]; - u32 buf_lsclut_idx[ISP3_UNITE_MAX]; + struct rkisp_dummy_buffer buf_lsclut[ISP_UNITE_MAX][ISP3X_LSC_LUT_BUF_NUM]; + u32 buf_lsclut_idx[ISP_UNITE_MAX]; - struct rkisp_dummy_buffer buf_cac[ISP3_UNITE_MAX][ISP3X_MESH_BUF_NUM]; - u32 buf_cac_idx[ISP3_UNITE_MAX]; + struct rkisp_dummy_buffer buf_cac[ISP_UNITE_MAX][ISP3X_MESH_BUF_NUM]; + u32 buf_cac_idx[ISP_UNITE_MAX]; struct rkisp_dummy_buffer buf_3dnr_iir; struct rkisp_dummy_buffer buf_3dnr_cur; struct rkisp_dummy_buffer buf_3dnr_ds; + u32 bay3d_ds_size; + u32 bay3d_iir_size; bool dhaz_en; bool drc_en; diff --git a/drivers/media/platform/rockchip/isp/isp_stats.c b/drivers/media/platform/rockchip/isp/isp_stats.c index 5c223ae5045b..fe6805a7dd8b 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats.c +++ b/drivers/media/platform/rockchip/isp/isp_stats.c @@ -44,7 +44,7 @@ static int rkisp_stats_g_fmt_meta_cap(struct file *file, void *priv, memset(meta, 0, sizeof(*meta)); meta->dataformat = stats_vdev->vdev_fmt.fmt.meta.dataformat; - meta->buffersize = stats_vdev->vdev_fmt.fmt.meta.buffersize; + stats_vdev->ops->get_stat_size(stats_vdev, &meta->buffersize); return 0; } @@ -132,8 +132,7 @@ static int rkisp_stats_vb2_queue_setup(struct vb2_queue *vq, *num_buffers = clamp_t(u32, *num_buffers, RKISP_ISP_STATS_REQ_BUFS_MIN, RKISP_ISP_STATS_REQ_BUFS_MAX); - - sizes[0] = stats_vdev->vdev_fmt.fmt.meta.buffersize; + stats_vdev->ops->get_stat_size(stats_vdev, sizes); INIT_LIST_HEAD(&stats_vdev->stat); return 0; @@ -166,9 +165,9 @@ static void rkisp_stats_vb2_buf_queue(struct vb2_buffer *vb) dev_info(dev->dev, "tb stat seq:%d meas_type:0x%x\n", buf->frame_id, buf->meas_type); - memcpy(stats_buf->vaddr[0], buf, sizeof(struct rkisp32_isp_stat_buffer)); + memcpy(stats_buf->vaddr[0], buf, size); buf->meas_type = 0; - vb2_set_plane_payload(vb, 0, sizeof(struct rkisp32_isp_stat_buffer)); + vb2_set_plane_payload(vb, 0, size); vbuf->sequence = buf->frame_id; spin_unlock_irqrestore(&stats_dev->rd_lock, flags); vb2_buffer_done(vb, VB2_BUF_STATE_DONE); @@ -286,6 +285,7 @@ static void rkisp_init_stats_vdev(struct rkisp_isp_stats_vdev *stats_vdev) stats_vdev->rd_buf_idx = 0; stats_vdev->wr_buf_idx = 0; memset(stats_vdev->stats_buf, 0, sizeof(stats_vdev->stats_buf)); + stats_vdev->vdev_fmt.fmt.meta.dataformat = V4L2_META_FMT_RK_ISP1_STAT_3A; if (stats_vdev->dev->isp_ver <= ISP_V13) rkisp_init_stats_vdev_v1x(stats_vdev); diff --git a/drivers/media/platform/rockchip/isp/isp_stats.h b/drivers/media/platform/rockchip/isp/isp_stats.h index 5e10d8f3d545..4ccf8b827410 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats.h +++ b/drivers/media/platform/rockchip/isp/isp_stats.h @@ -34,6 +34,7 @@ struct rkisp_isp_stats_ops { void (*send_meas)(struct rkisp_isp_stats_vdev *stats_vdev, struct rkisp_isp_readout_work *meas_work); void (*rdbk_enable)(struct rkisp_isp_stats_vdev *stats_vdev, bool en); + void (*get_stat_size)(struct rkisp_isp_stats_vdev *stats_vdev, unsigned int sizes[]); }; /* diff --git a/drivers/media/platform/rockchip/isp/isp_stats_v1x.c b/drivers/media/platform/rockchip/isp/isp_stats_v1x.c index dce904b5f7c5..3829156cd4b8 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats_v1x.c +++ b/drivers/media/platform/rockchip/isp/isp_stats_v1x.c @@ -390,19 +390,23 @@ rkisp_stats_rdbk_enable_v1x(struct rkisp_isp_stats_vdev *stats_vdev, bool en) { } +static void +rkisp_get_stat_size_v1x(struct rkisp_isp_stats_vdev *stats_vdev, + unsigned int sizes[]) +{ + sizes[0] = sizeof(struct rkisp1_stat_buffer); + stats_vdev->vdev_fmt.fmt.meta.buffersize = sizes[0]; +} + static struct rkisp_isp_stats_ops rkisp_isp_stats_ops_tbl = { .isr_hdl = rkisp1_stats_isr_v1x, .send_meas = rkisp1_stats_send_meas_v1x, .rdbk_enable = rkisp_stats_rdbk_enable_v1x, + .get_stat_size = rkisp_get_stat_size_v1x, }; void rkisp_init_stats_vdev_v1x(struct rkisp_isp_stats_vdev *stats_vdev) { - stats_vdev->vdev_fmt.fmt.meta.dataformat = - V4L2_META_FMT_RK_ISP1_STAT_3A; - stats_vdev->vdev_fmt.fmt.meta.buffersize = - sizeof(struct rkisp1_stat_buffer); - stats_vdev->ops = &rkisp_isp_stats_ops_tbl; if (stats_vdev->dev->isp_ver == ISP_V12 || stats_vdev->dev->isp_ver == ISP_V13) { diff --git a/drivers/media/platform/rockchip/isp/isp_stats_v21.c b/drivers/media/platform/rockchip/isp/isp_stats_v21.c index c6308645ac53..196b2fe4b533 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats_v21.c +++ b/drivers/media/platform/rockchip/isp/isp_stats_v21.c @@ -1120,10 +1120,19 @@ rkisp_stats_rdbk_enable_v21(struct rkisp_isp_stats_vdev *stats_vdev, bool en) stats_vdev->rdbk_mode = en; } +static void +rkisp_get_stat_size_v21(struct rkisp_isp_stats_vdev *stats_vdev, + unsigned int sizes[]) +{ + sizes[0] = sizeof(struct rkisp_isp2x_stat_buffer); + stats_vdev->vdev_fmt.fmt.meta.buffersize = sizes[0]; +} + static struct rkisp_isp_stats_ops rkisp_isp_stats_ops_tbl = { .isr_hdl = rkisp_stats_isr_v21, .send_meas = rkisp_stats_send_meas_v21, .rdbk_enable = rkisp_stats_rdbk_enable_v21, + .get_stat_size = rkisp_get_stat_size_v21, }; void rkisp_stats_first_ddr_config_v21(struct rkisp_isp_stats_vdev *stats_vdev) @@ -1149,20 +1158,16 @@ void rkisp_stats_first_ddr_config_v21(struct rkisp_isp_stats_vdev *stats_vdev) void rkisp_init_stats_vdev_v21(struct rkisp_isp_stats_vdev *stats_vdev) { + int mult = stats_vdev->dev->hw_dev->unite ? ISP_UNITE_MAX : 1; int i; - stats_vdev->vdev_fmt.fmt.meta.dataformat = - V4L2_META_FMT_RK_ISP1_STAT_3A; - stats_vdev->vdev_fmt.fmt.meta.buffersize = - sizeof(struct rkisp_isp2x_stat_buffer); - stats_vdev->ops = &rkisp_isp_stats_ops_tbl; stats_vdev->priv_ops = &rkisp_stats_reg_ops_v21; stats_vdev->rd_stats_from_ddr = false; for (i = 0; i < RKISP_STATS_DDR_BUF_NUM; i++) { stats_vdev->stats_buf[i].is_need_vaddr = true; - stats_vdev->stats_buf[i].size = RKISP_RD_STATS_BUF_SIZE; + stats_vdev->stats_buf[i].size = RKISP_RD_STATS_BUF_SIZE * mult; rkisp_alloc_buffer(stats_vdev->dev, &stats_vdev->stats_buf[i]); } } diff --git a/drivers/media/platform/rockchip/isp/isp_stats_v2x.c b/drivers/media/platform/rockchip/isp/isp_stats_v2x.c index b69b48f770b5..0c73712eb87e 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats_v2x.c +++ b/drivers/media/platform/rockchip/isp/isp_stats_v2x.c @@ -1458,10 +1458,19 @@ rkisp_stats_rdbk_enable_v2x(struct rkisp_isp_stats_vdev *stats_vdev, bool en) stats_vdev->rdbk_mode = en; } +static void +rkisp_get_stat_size_v2x(struct rkisp_isp_stats_vdev *stats_vdev, + unsigned int sizes[]) +{ + sizes[0] = sizeof(struct rkisp_isp2x_stat_buffer); + stats_vdev->vdev_fmt.fmt.meta.buffersize = sizes[0]; +} + static struct rkisp_isp_stats_ops rkisp_isp_stats_ops_tbl = { .isr_hdl = rkisp_stats_isr_v2x, .send_meas = rkisp_stats_send_meas_v2x, .rdbk_enable = rkisp_stats_rdbk_enable_v2x, + .get_stat_size = rkisp_get_stat_size_v2x, }; void rkisp_stats_first_ddr_config_v2x(struct rkisp_isp_stats_vdev *stats_vdev) @@ -1491,11 +1500,6 @@ void rkisp_stats_first_ddr_config_v2x(struct rkisp_isp_stats_vdev *stats_vdev) void rkisp_init_stats_vdev_v2x(struct rkisp_isp_stats_vdev *stats_vdev) { - stats_vdev->vdev_fmt.fmt.meta.dataformat = - V4L2_META_FMT_RK_ISP1_STAT_3A; - stats_vdev->vdev_fmt.fmt.meta.buffersize = - sizeof(struct rkisp_isp2x_stat_buffer); - stats_vdev->ops = &rkisp_isp_stats_ops_tbl; stats_vdev->priv_ops = &rkisp_stats_reg_ops_v2x; diff --git a/drivers/media/platform/rockchip/isp/isp_stats_v32.c b/drivers/media/platform/rockchip/isp/isp_stats_v32.c index 6e73379ab154..b1d2e8fc830e 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats_v32.c +++ b/drivers/media/platform/rockchip/isp/isp_stats_v32.c @@ -430,6 +430,7 @@ rkisp_stats_update_buf(struct rkisp_isp_stats_vdev *stats_vdev) unsigned long flags; u32 size = stats_vdev->vdev_fmt.fmt.meta.buffersize; u32 val = 0; + int i; spin_lock_irqsave(&stats_vdev->rd_lock, flags); if (!stats_vdev->nxt_buf && !list_empty(&stats_vdev->stat)) { @@ -454,11 +455,9 @@ rkisp_stats_update_buf(struct rkisp_isp_stats_vdev *stats_vdev) val = stats_vdev->stats_buf[0].dma_addr; } - if (val) { - rkisp_write(dev, ISP3X_MI_3A_WR_BASE, val, false); - if (dev->hw_dev->unite) - rkisp_next_write(dev, ISP3X_MI_3A_WR_BASE, val + size / 2, false); - } + for (i = 0; i < dev->unite_div && val; i++) + rkisp_idx_write(dev, ISP3X_MI_3A_WR_BASE, + val + i * size / dev->unite_div, i, false); } static void @@ -920,21 +919,30 @@ rkisp_stats_send_meas_lite(struct rkisp_isp_stats_vdev *stats_vdev, struct rkisp_isp_readout_work *meas_work) { struct rkisp_device *dev = stats_vdev->dev; + struct rkisp_hw_dev *hw = dev->hw_dev; struct rkisp_isp_params_vdev *params_vdev = &dev->params_vdev; unsigned int cur_frame_id = meas_work->frame_id; - struct rkisp_buffer *cur_buf = NULL; + struct rkisp_buffer *cur_buf = stats_vdev->cur_buf; struct rkisp32_lite_stat_buffer *cur_stat_buf = NULL; - u32 size = sizeof(struct rkisp32_lite_stat_buffer); + u32 size = stats_vdev->vdev_fmt.fmt.meta.buffersize; - spin_lock(&stats_vdev->rd_lock); - if (!list_empty(&stats_vdev->stat)) { - cur_buf = list_first_entry(&stats_vdev->stat, struct rkisp_buffer, queue); - list_del(&cur_buf->queue); + if (hw->unite != ISP_UNITE_ONE || dev->unite_index == ISP_UNITE_LEFT) { + spin_lock(&stats_vdev->rd_lock); + if (!list_empty(&stats_vdev->stat)) { + cur_buf = list_first_entry(&stats_vdev->stat, struct rkisp_buffer, queue); + list_del(&cur_buf->queue); + stats_vdev->cur_buf = cur_buf; + } + spin_unlock(&stats_vdev->rd_lock); } - spin_unlock(&stats_vdev->rd_lock); if (cur_buf) { - cur_stat_buf = (struct rkisp32_lite_stat_buffer *)(cur_buf->vaddr[0]); + cur_stat_buf = cur_buf->vaddr[0]; + if (dev->unite_index > ISP_UNITE_LEFT) + cur_stat_buf += dev->unite_index; + if ((dev->unite_div == ISP_UNITE_DIV2 && dev->unite_index != ISP_UNITE_RIGHT) || + (dev->unite_div == ISP_UNITE_DIV4 && dev->unite_index != ISP_UNITE_RIGHT_B)) + cur_buf = NULL; cur_stat_buf->frame_id = cur_frame_id; cur_stat_buf->params_id = params_vdev->cur_frame_id; cur_stat_buf->params.info2ddr.buf_fd = -1; @@ -972,6 +980,7 @@ rkisp_stats_send_meas_lite(struct rkisp_isp_stats_vdev *stats_vdev, cur_buf->vb.sequence = cur_frame_id; cur_buf->vb.vb2_buf.timestamp = meas_work->timestamp; vb2_buffer_done(&cur_buf->vb.vb2_buf, VB2_BUF_STATE_DONE); + stats_vdev->cur_buf = NULL; } v4l2_dbg(4, rkisp_debug, &dev->v4l2_dev, "%s seq:%d params_id:%d ris:0x%x buf:%p meas_type:0x%x\n", @@ -1064,21 +1073,36 @@ rkisp_stats_rdbk_enable_v32(struct rkisp_isp_stats_vdev *stats_vdev, bool en) stats_vdev->rdbk_mode = en; } +static void +rkisp_get_stat_size_v32(struct rkisp_isp_stats_vdev *stats_vdev, + unsigned int sizes[]) +{ + int mult = stats_vdev->dev->unite_div; + + if (stats_vdev->dev->isp_ver == ISP_V32) + sizes[0] = ALIGN(sizeof(struct rkisp32_isp_stat_buffer), 16); + else + sizes[0] = sizeof(struct rkisp32_lite_stat_buffer); + sizes[0] *= mult; + stats_vdev->vdev_fmt.fmt.meta.buffersize = sizes[0]; +} + static struct rkisp_isp_stats_ops rkisp_isp_stats_ops_tbl = { .isr_hdl = rkisp_stats_isr_v32, .send_meas = rkisp_stats_send_meas_v32, .rdbk_enable = rkisp_stats_rdbk_enable_v32, + .get_stat_size = rkisp_get_stat_size_v32, }; void rkisp_stats_first_ddr_config_v32(struct rkisp_isp_stats_vdev *stats_vdev) { struct rkisp_device *dev = stats_vdev->dev; - u32 size = stats_vdev->vdev_fmt.fmt.meta.buffersize; - u32 div = dev->hw_dev->unite ? 2 : 1; + u32 size = 0, div = dev->unite_div; if (dev->isp_sdev.in_fmt.fmt_type == FMT_YUV) return; + rkisp_get_stat_size_v32(stats_vdev, &size); stats_vdev->stats_buf[0].is_need_vaddr = true; stats_vdev->stats_buf[0].size = size; if (rkisp_alloc_buffer(dev, &stats_vdev->stats_buf[0])) @@ -1107,21 +1131,13 @@ void rkisp_stats_next_ddr_config_v32(struct rkisp_isp_stats_vdev *stats_vdev) void rkisp_init_stats_vdev_v32(struct rkisp_isp_stats_vdev *stats_vdev) { - int mult = stats_vdev->dev->hw_dev->unite ? 2 : 1; - u32 size; - - stats_vdev->vdev_fmt.fmt.meta.dataformat = - V4L2_META_FMT_RK_ISP1_STAT_3A; if (stats_vdev->dev->isp_ver == ISP_V32) { stats_vdev->priv_ops = &stats_ddr_ops_v32; stats_vdev->rd_stats_from_ddr = true; - size = ALIGN(sizeof(struct rkisp32_isp_stat_buffer), 16); } else { stats_vdev->priv_ops = NULL; stats_vdev->rd_stats_from_ddr = false; - size = sizeof(struct rkisp32_lite_stat_buffer); } - stats_vdev->vdev_fmt.fmt.meta.buffersize = size * mult; stats_vdev->ops = &rkisp_isp_stats_ops_tbl; } diff --git a/drivers/media/platform/rockchip/isp/isp_stats_v3x.c b/drivers/media/platform/rockchip/isp/isp_stats_v3x.c index b74736d721ce..979e50dd46ed 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats_v3x.c +++ b/drivers/media/platform/rockchip/isp/isp_stats_v3x.c @@ -33,7 +33,7 @@ static void isp3_module_done(struct rkisp_isp_stats_vdev *stats_vdev, { void __iomem *base; - if (id == ISP3_LEFT) + if (id == ISP_UNITE_LEFT || id == ISP_UNITE_LEFT_B) base = stats_vdev->dev->hw_dev->base_addr; else base = stats_vdev->dev->hw_dev->base_next_addr; @@ -44,13 +44,7 @@ static void isp3_module_done(struct rkisp_isp_stats_vdev *stats_vdev, static u32 isp3_stats_read(struct rkisp_isp_stats_vdev *stats_vdev, u32 addr, u32 id) { - u32 val; - - if (id == ISP3_LEFT) - val = rkisp_read(stats_vdev->dev, addr, true); - else - val = rkisp_next_read(stats_vdev->dev, addr, true); - return val; + return rkisp_idx_read(stats_vdev->dev, addr, id, true); } static int @@ -1092,7 +1086,7 @@ rkisp_stats_isr_v3x(struct rkisp_isp_stats_vdev *stats_vdev, u32 iq_isr_mask = ISP3X_SIAWB_DONE | ISP3X_SIAF_FIN | ISP3X_EXP_END | ISP3X_SIHST_RDY | ISP3X_AFM_SUM_OF | ISP3X_AFM_LUM_OF; u32 cur_frame_id, isp_mis_tmp = 0, iq_3a_mask = 0; - u32 wr_buf_idx, temp_isp_ris, temp_isp3a_ris; + u32 i, wr_buf_idx, temp_isp_ris, temp_isp3a_ris; rkisp_dmarx_get_frame(stats_vdev->dev, &cur_frame_id, NULL, NULL, true); @@ -1136,12 +1130,10 @@ rkisp_stats_isr_v3x(struct rkisp_isp_stats_vdev *stats_vdev, stats_vdev->wr_buf_idx = wr_buf_idx; rkisp_finish_buffer(dev, &stats_vdev->stats_buf[wr_buf_idx]); - rkisp_write(dev, ISP3X_MI_3A_WR_BASE, - stats_vdev->stats_buf[wr_buf_idx].dma_addr, false); - if (dev->hw_dev->unite) - rkisp_next_write(dev, ISP3X_MI_3A_WR_BASE, - stats_vdev->stats_buf[wr_buf_idx].dma_addr + - ISP3X_RD_STATS_BUF_SIZE, false); + for (i = 0; i < dev->unite_div; i++) + rkisp_idx_write(dev, ISP3X_MI_3A_WR_BASE, + stats_vdev->stats_buf[wr_buf_idx].dma_addr + + i * ISP3X_RD_STATS_BUF_SIZE, i, false); } if (isp_ris & ISP3X_FRAME) { @@ -1169,16 +1161,27 @@ rkisp_stats_rdbk_enable_v3x(struct rkisp_isp_stats_vdev *stats_vdev, bool en) stats_vdev->rdbk_mode = en; } +static void +rkisp_get_stat_size_v3x(struct rkisp_isp_stats_vdev *stats_vdev, + unsigned int sizes[]) +{ + int mult = stats_vdev->dev->unite_div; + + sizes[0] = sizeof(struct rkisp3x_isp_stat_buffer) * mult; + stats_vdev->vdev_fmt.fmt.meta.buffersize = sizes[0]; +} + static struct rkisp_isp_stats_ops rkisp_isp_stats_ops_tbl = { .isr_hdl = rkisp_stats_isr_v3x, .send_meas = rkisp_stats_send_meas_v3x, .rdbk_enable = rkisp_stats_rdbk_enable_v3x, + .get_stat_size = rkisp_get_stat_size_v3x, }; void rkisp_stats_first_ddr_config_v3x(struct rkisp_isp_stats_vdev *stats_vdev) { struct rkisp_device *dev = stats_vdev->dev; - int i, mult = dev->hw_dev->unite ? 2 : 1; + int i, mult = dev->unite_div; if (dev->isp_sdev.in_fmt.fmt_type == FMT_YUV) return; @@ -1202,12 +1205,10 @@ void rkisp_stats_first_ddr_config_v3x(struct rkisp_isp_stats_vdev *stats_vdev) ISP3X_RD_STATS_BUF_SIZE, false); rkisp_unite_set_bits(dev, ISP3X_SWS_CFG, 0, ISP3X_3A_DDR_WRITE_EN, false); - rkisp_write(dev, ISP3X_MI_3A_WR_BASE, - stats_vdev->stats_buf[0].dma_addr, false); - if (dev->hw_dev->unite) - rkisp_next_write(dev, ISP3X_MI_3A_WR_BASE, - stats_vdev->stats_buf[0].dma_addr + - ISP3X_RD_STATS_BUF_SIZE, false); + for (i = 0; i < dev->unite_div; i++) + rkisp_idx_write(dev, ISP3X_MI_3A_WR_BASE, + stats_vdev->stats_buf[0].dma_addr + + i * ISP3X_RD_STATS_BUF_SIZE, i, false); return; err: @@ -1218,13 +1219,6 @@ err: void rkisp_init_stats_vdev_v3x(struct rkisp_isp_stats_vdev *stats_vdev) { - int mult = stats_vdev->dev->hw_dev->unite ? 2 : 1; - - stats_vdev->vdev_fmt.fmt.meta.dataformat = - V4L2_META_FMT_RK_ISP1_STAT_3A; - stats_vdev->vdev_fmt.fmt.meta.buffersize = - mult * sizeof(struct rkisp3x_isp_stat_buffer); - stats_vdev->ops = &rkisp_isp_stats_ops_tbl; stats_vdev->priv_ops = &stats_reg_ops_v3x; stats_vdev->rd_stats_from_ddr = false; diff --git a/drivers/media/platform/rockchip/isp/procfs.c b/drivers/media/platform/rockchip/isp/procfs.c index 8a0433118461..572957ade33b 100644 --- a/drivers/media/platform/rockchip/isp/procfs.c +++ b/drivers/media/platform/rockchip/isp/procfs.c @@ -380,242 +380,242 @@ static void isp30_unite_show(struct rkisp_device *dev, struct seq_file *p) }; u32 v0, v1; - v0 = rkisp_read(dev, ISP3X_CMSK_CTRL0, false); - v1 = rkisp_next_read(dev, ISP3X_CMSK_CTRL0, false); + v0 = rkisp_idx_read(dev, ISP3X_CMSK_CTRL0, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_CMSK_CTRL0, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "CMSK", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_DPCC0_MODE, false); - v1 = rkisp_next_read(dev, ISP3X_DPCC0_MODE, false); + v0 = rkisp_idx_read(dev, ISP3X_DPCC0_MODE, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_DPCC0_MODE, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "DPCC0", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_DPCC1_MODE, false); - v1 = rkisp_next_read(dev, ISP3X_DPCC1_MODE, false); + v0 = rkisp_idx_read(dev, ISP3X_DPCC1_MODE, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_DPCC1_MODE, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "DPCC1", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_DPCC2_MODE, false); - v1 = rkisp_next_read(dev, ISP3X_DPCC2_MODE, false); + v0 = rkisp_idx_read(dev, ISP3X_DPCC2_MODE, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_DPCC2_MODE, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "DPCC2", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_BLS_CTRL, false); - v1 = rkisp_next_read(dev, ISP3X_BLS_CTRL, false); + v0 = rkisp_idx_read(dev, ISP3X_BLS_CTRL, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_BLS_CTRL, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "BLS", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_ISP_CTRL0, false); - v1 = rkisp_next_read(dev, ISP3X_ISP_CTRL0, false); + v0 = rkisp_idx_read(dev, ISP3X_ISP_CTRL0, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_ISP_CTRL0, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "SDG", (v0 & BIT(6)) ? "ON" : "OFF", v0, (v1 & BIT(6)) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_LSC_CTRL, false); - v1 = rkisp_next_read(dev, ISP3X_LSC_CTRL, false); + v0 = rkisp_idx_read(dev, ISP3X_LSC_CTRL, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_LSC_CTRL, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "LSC", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_ISP_CTRL0, false); - v1 = rkisp_next_read(dev, ISP3X_ISP_CTRL0, false); + v0 = rkisp_idx_read(dev, ISP3X_ISP_CTRL0, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_ISP_CTRL0, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x) gain:0x%08x 0x%08x, Right %s(0x%x) gain:0x%08x 0x%08x\n", "AWBGAIN", (v0 & BIT(7)) ? "ON" : "OFF", v0, - rkisp_read(dev, ISP3X_ISP_AWB_GAIN0_G, false), - rkisp_read(dev, ISP3X_ISP_AWB_GAIN0_RB, false), + rkisp_idx_read(dev, ISP3X_ISP_AWB_GAIN0_G, ISP_UNITE_LEFT, false), + rkisp_idx_read(dev, ISP3X_ISP_AWB_GAIN0_RB, ISP_UNITE_LEFT, false), (v1 & BIT(7)) ? "ON" : "OFF", v1, - rkisp_next_read(dev, ISP3X_ISP_AWB_GAIN0_G, false), - rkisp_next_read(dev, ISP3X_ISP_AWB_GAIN0_RB, false)); - v0 = rkisp_read(dev, ISP3X_DEBAYER_CONTROL, false); - v1 = rkisp_next_read(dev, ISP3X_DEBAYER_CONTROL, false); + rkisp_idx_read(dev, ISP3X_ISP_AWB_GAIN0_G, ISP_UNITE_RIGHT, false), + rkisp_idx_read(dev, ISP3X_ISP_AWB_GAIN0_RB, ISP_UNITE_RIGHT, false)); + v0 = rkisp_idx_read(dev, ISP3X_DEBAYER_CONTROL, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_DEBAYER_CONTROL, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "DEBAYER", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_CCM_CTRL, false); - v1 = rkisp_next_read(dev, ISP3X_CCM_CTRL, false); + v0 = rkisp_idx_read(dev, ISP3X_CCM_CTRL, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_CCM_CTRL, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "CCM", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_GAMMA_OUT_CTRL, false); - v1 = rkisp_next_read(dev, ISP3X_GAMMA_OUT_CTRL, false); + v0 = rkisp_idx_read(dev, ISP3X_GAMMA_OUT_CTRL, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_GAMMA_OUT_CTRL, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "GAMMA_OUT", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_CPROC_CTRL, false); - v1 = rkisp_next_read(dev, ISP3X_CPROC_CTRL, false); + v0 = rkisp_idx_read(dev, ISP3X_CPROC_CTRL, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_CPROC_CTRL, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "CPROC", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_IMG_EFF_CTRL, false); - v1 = rkisp_next_read(dev, ISP3X_IMG_EFF_CTRL, false); + v0 = rkisp_idx_read(dev, ISP3X_IMG_EFF_CTRL, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_IMG_EFF_CTRL, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x) effect:%s, Right %s(0x%x) effect:%s\n", "IE", (v0 & 1) ? "ON" : "OFF", v0, effect[(v0 & CIF_IMG_EFF_CTRL_MODE_MASK) >> 1], (v1 & 1) ? "ON" : "OFF", v1, effect[(v1 & CIF_IMG_EFF_CTRL_MODE_MASK) >> 1]); - v0 = rkisp_read(dev, ISP3X_DRC_CTRL0, false); - v1 = rkisp_next_read(dev, ISP3X_DRC_CTRL0, false); + v0 = rkisp_idx_read(dev, ISP3X_DRC_CTRL0, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_DRC_CTRL0, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "HDRDRC", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_HDRMGE_CTRL, false); - v1 = rkisp_next_read(dev, ISP3X_HDRMGE_CTRL, false); + v0 = rkisp_idx_read(dev, ISP3X_HDRMGE_CTRL, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_HDRMGE_CTRL, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "HDRMGE", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_BAYNR_CTRL, false); - v1 = rkisp_next_read(dev, ISP3X_BAYNR_CTRL, false); + v0 = rkisp_idx_read(dev, ISP3X_BAYNR_CTRL, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_BAYNR_CTRL, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "BAYNR", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_BAY3D_CTRL, false); - v1 = rkisp_next_read(dev, ISP3X_BAY3D_CTRL, false); + v0 = rkisp_idx_read(dev, ISP3X_BAY3D_CTRL, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_BAY3D_CTRL, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "BAY3D", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_YNR_GLOBAL_CTRL, false); - v1 = rkisp_next_read(dev, ISP3X_YNR_GLOBAL_CTRL, false); + v0 = rkisp_idx_read(dev, ISP3X_YNR_GLOBAL_CTRL, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_YNR_GLOBAL_CTRL, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "YNR", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_CNR_CTRL, false); - v1 = rkisp_next_read(dev, ISP3X_CNR_CTRL, false); + v0 = rkisp_idx_read(dev, ISP3X_CNR_CTRL, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_CNR_CTRL, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "CNR", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_SHARP_EN, false); - v1 = rkisp_next_read(dev, ISP3X_SHARP_EN, false); + v0 = rkisp_idx_read(dev, ISP3X_SHARP_EN, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_SHARP_EN, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "SHARP", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_GIC_CONTROL, false); - v1 = rkisp_next_read(dev, ISP3X_GIC_CONTROL, false); + v0 = rkisp_idx_read(dev, ISP3X_GIC_CONTROL, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_GIC_CONTROL, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "GIC", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_DHAZ_CTRL, false); - v1 = rkisp_next_read(dev, ISP3X_DHAZ_CTRL, false); + v0 = rkisp_idx_read(dev, ISP3X_DHAZ_CTRL, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_DHAZ_CTRL, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "DHAZ", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_3DLUT_CTRL, false); - v1 = rkisp_next_read(dev, ISP3X_3DLUT_CTRL, false); + v0 = rkisp_idx_read(dev, ISP3X_3DLUT_CTRL, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_3DLUT_CTRL, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "3DLUT", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_LDCH_STS, false); - v1 = rkisp_next_read(dev, ISP3X_LDCH_STS, false); + v0 = rkisp_idx_read(dev, ISP3X_LDCH_STS, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_LDCH_STS, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "LDCH", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_ISP_CTRL0, false); - v1 = rkisp_next_read(dev, ISP3X_ISP_CTRL0, false); + v0 = rkisp_idx_read(dev, ISP3X_ISP_CTRL0, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_ISP_CTRL0, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "CSM", (v0 & full_range_flg) ? "FULL" : "LIMIT", v0, (v1 & full_range_flg) ? "FULL" : "LIMIT", v1); - v0 = rkisp_read(dev, ISP3X_CAC_CTRL, false); - v1 = rkisp_next_read(dev, ISP3X_CAC_CTRL, false); + v0 = rkisp_idx_read(dev, ISP3X_CAC_CTRL, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_CAC_CTRL, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "CAC", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_GAIN_CTRL, false); - v1 = rkisp_next_read(dev, ISP3X_GAIN_CTRL, false); + v0 = rkisp_idx_read(dev, ISP3X_GAIN_CTRL, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_GAIN_CTRL, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "GAIN", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_RAWAF_CTRL, false); - v1 = rkisp_next_read(dev, ISP3X_RAWAF_CTRL, false); + v0 = rkisp_idx_read(dev, ISP3X_RAWAF_CTRL, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_RAWAF_CTRL, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "RAWAF", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_RAWAWB_CTRL, false); - v1 = rkisp_next_read(dev, ISP3X_RAWAWB_CTRL, false); + v0 = rkisp_idx_read(dev, ISP3X_RAWAWB_CTRL, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_RAWAWB_CTRL, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "RAWAWB", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_RAWAE_LITE_CTRL, false); - v1 = rkisp_next_read(dev, ISP3X_RAWAE_LITE_CTRL, false); + v0 = rkisp_idx_read(dev, ISP3X_RAWAE_LITE_CTRL, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_RAWAE_LITE_CTRL, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "RAWAE0", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_RAWAE_BIG2_BASE, false); - v1 = rkisp_next_read(dev, ISP3X_RAWAE_BIG2_BASE, false); + v0 = rkisp_idx_read(dev, ISP3X_RAWAE_BIG2_BASE, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_RAWAE_BIG2_BASE, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "RAWAE1", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_RAWAE_BIG3_BASE, false); - v1 = rkisp_next_read(dev, ISP3X_RAWAE_BIG3_BASE, false); + v0 = rkisp_idx_read(dev, ISP3X_RAWAE_BIG3_BASE, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_RAWAE_BIG3_BASE, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "RAWAE2", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_RAWAE_BIG1_BASE, false); - v1 = rkisp_next_read(dev, ISP3X_RAWAE_BIG1_BASE, false); + v0 = rkisp_idx_read(dev, ISP3X_RAWAE_BIG1_BASE, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_RAWAE_BIG1_BASE, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "RAWAE3", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_RAWHIST_LITE_CTRL, false); - v1 = rkisp_next_read(dev, ISP3X_RAWHIST_LITE_CTRL, false); + v0 = rkisp_idx_read(dev, ISP3X_RAWHIST_LITE_CTRL, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_RAWHIST_LITE_CTRL, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "RAWHIST0", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_RAWHIST_BIG2_BASE, false); - v1 = rkisp_next_read(dev, ISP3X_RAWHIST_BIG2_BASE, false); + v0 = rkisp_idx_read(dev, ISP3X_RAWHIST_BIG2_BASE, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_RAWHIST_BIG2_BASE, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "RAWHIST1", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_RAWHIST_BIG3_BASE, false); - v1 = rkisp_next_read(dev, ISP3X_RAWHIST_BIG3_BASE, false); + v0 = rkisp_idx_read(dev, ISP3X_RAWHIST_BIG3_BASE, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_RAWHIST_BIG3_BASE, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "RAWHIST2", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_RAWHIST_BIG1_BASE, false); - v1 = rkisp_next_read(dev, ISP3X_RAWHIST_BIG1_BASE, false); + v0 = rkisp_idx_read(dev, ISP3X_RAWHIST_BIG1_BASE, ISP_UNITE_LEFT, false); + v1 = rkisp_idx_read(dev, ISP3X_RAWHIST_BIG1_BASE, ISP_UNITE_RIGHT, false); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "RAWHIST3", (v0 & 1) ? "ON" : "OFF", v0, (v1 & 1) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_ISP_CTRL1, true); - v1 = rkisp_next_read(dev, ISP3X_ISP_CTRL1, true); + v0 = rkisp_idx_read(dev, ISP3X_ISP_CTRL1, ISP_UNITE_LEFT, true); + v1 = rkisp_idx_read(dev, ISP3X_ISP_CTRL1, ISP_UNITE_RIGHT, true); seq_printf(p, "%-10s Left %s(0x%x), Right %s(0x%x)\n", "BigMode", v0 & BIT(28) ? "ON" : "OFF", v0, v1 & BIT(28) ? "ON" : "OFF", v1); - v0 = rkisp_read(dev, ISP3X_ISP_DEBUG1, true); - v1 = rkisp_next_read(dev, ISP3X_ISP_DEBUG1, true); + v0 = rkisp_idx_read(dev, ISP3X_ISP_DEBUG1, ISP_UNITE_LEFT, true); + v1 = rkisp_idx_read(dev, ISP3X_ISP_DEBUG1, ISP_UNITE_RIGHT, true); seq_printf(p, "%-10s space full status group. Left:0x%x Right:0x%x\n" "\t ibuf2(L:0x%x R:0x%x) ibuf1(L:0x%x R:0x%x)\n" "\t ibuf0(L:0x%x R:0x%x) mpfbc_infifo(L:0x%x R:0x%x)\n" @@ -626,8 +626,8 @@ static void isp30_unite_show(struct rkisp_device *dev, struct seq_file *p) (v0 >> 20) & 0xf, (v1 >> 20) & 0xf, (v0 >> 16) & 0xf, (v1 >> 16) & 0xf, (v0 >> 12) & 0xf, (v1 >> 12) & 0xf, (v0 >> 8) & 0xf, (v1 >> 8) & 0xf, (v0 >> 4) & 0xf, (v1 >> 4) & 0xf, v0 & 0xf, v1 & 0xf); - v0 = rkisp_read(dev, ISP3X_ISP_DEBUG2, true); - v1 = rkisp_next_read(dev, ISP3X_ISP_DEBUG2, true); + v0 = rkisp_idx_read(dev, ISP3X_ISP_DEBUG2, ISP_UNITE_LEFT, true); + v1 = rkisp_idx_read(dev, ISP3X_ISP_DEBUG2, ISP_UNITE_RIGHT, true); seq_printf(p, "%-10s Left:0x%x Right:0x%x\n" "\t bay3d_fifo_full iir(L:%d R:%d) cur(L:%d R:%d)\n" "\t module outform vertical counter(L:%d R:%d), out frame counter:(L:%d R:%d)\n" @@ -636,8 +636,8 @@ static void isp30_unite_show(struct rkisp_device *dev, struct seq_file *p) !!(v0 & BIT(31)), !!(v1 & BIT(31)), !!(v0 & BIT(30)), !!(v1 & BIT(30)), (v0 >> 16) & 0x3fff, (v1 >> 16) & 0x3fff, (v0 >> 14) & 0x3, (v1 >> 14) & 0x3, v0 & 0x3fff, v1 & 0x3fff); - v0 = rkisp_read(dev, ISP3X_ISP_DEBUG3, true); - v1 = rkisp_next_read(dev, ISP3X_ISP_DEBUG3, true); + v0 = rkisp_idx_read(dev, ISP3X_ISP_DEBUG3, ISP_UNITE_LEFT, true); + v1 = rkisp_idx_read(dev, ISP3X_ISP_DEBUG3, ISP_UNITE_RIGHT, true); seq_printf(p, "%-10s isp pipeline group Left:0x%x Right:0x%x\n" "\t mge(L:%d %d R:%d %d) rawnr(L:%d %d R:%d %d)\n" "\t bay3d(L:%d %d R:%d %d) tmo(L:%d %d R:%d %d)\n" @@ -976,14 +976,14 @@ static int isp_show(struct seq_file *p, void *v) rkisp_read(dev, i + 12, true)); } else { seq_printf(p, "%04x: %08x %08x %08x %08x | %08x %08x %08x %08x\n", i, - rkisp_read(dev, i, true), - rkisp_read(dev, i + 4, true), - rkisp_read(dev, i + 8, true), - rkisp_read(dev, i + 12, true), - rkisp_next_read(dev, i, true), - rkisp_next_read(dev, i + 4, true), - rkisp_next_read(dev, i + 8, true), - rkisp_next_read(dev, i + 12, true)); + rkisp_idx_read(dev, i, ISP_UNITE_LEFT, true), + rkisp_idx_read(dev, i + 4, ISP_UNITE_LEFT, true), + rkisp_idx_read(dev, i + 8, ISP_UNITE_LEFT, true), + rkisp_idx_read(dev, i + 12, ISP_UNITE_LEFT, true), + rkisp_idx_read(dev, i, ISP_UNITE_RIGHT, true), + rkisp_idx_read(dev, i + 4, ISP_UNITE_RIGHT, true), + rkisp_idx_read(dev, i + 8, ISP_UNITE_RIGHT, true), + rkisp_idx_read(dev, i + 12, ISP_UNITE_RIGHT, true)); } } } diff --git a/drivers/media/platform/rockchip/isp/regs.c b/drivers/media/platform/rockchip/isp/regs.c index 17af5ef7349b..90c1b6d76f7f 100644 --- a/drivers/media/platform/rockchip/isp/regs.c +++ b/drivers/media/platform/rockchip/isp/regs.c @@ -53,11 +53,10 @@ void rkisp_config_dcrop(struct rkisp_stream *stream, { struct rkisp_device *dev = stream->ispdev; u32 val = stream->config->dual_crop.yuvmode_mask; - bool is_unite = !!dev->hw_dev->unite; struct v4l2_rect tmp = *rect; u32 reg; - if (is_unite) { + if (dev->unite_div > ISP_UNITE_DIV1) { tmp.width /= 2; if (stream->id == RKISP_STREAM_FBC) tmp.width &= ~0xf; @@ -67,6 +66,8 @@ void rkisp_config_dcrop(struct rkisp_stream *stream, reg = stream->config->dual_crop.h_size; rkisp_write(dev, reg, tmp.width, false); + if (dev->unite_div == ISP_UNITE_DIV4) + tmp.height /= 2; reg = stream->config->dual_crop.v_offset; rkisp_unite_write(dev, reg, tmp.top, false); reg = stream->config->dual_crop.v_size; @@ -76,21 +77,23 @@ void rkisp_config_dcrop(struct rkisp_stream *stream, val |= CIF_DUAL_CROP_GEN_CFG_UPD; else val |= CIF_DUAL_CROP_CFG_UPD; - if (is_unite) { + + if (dev->unite_div > ISP_UNITE_DIV1) { u32 right_w, left_w = tmp.width; reg = stream->config->dual_crop.h_offset; - rkisp_next_write(dev, reg, RKMOUDLE_UNITE_EXTEND_PIXEL, false); + rkisp_idx_write(dev, reg, RKMOUDLE_UNITE_EXTEND_PIXEL, ISP_UNITE_RIGHT, false); reg = stream->config->dual_crop.h_size; right_w = rect->width - left_w; - rkisp_next_write(dev, reg, right_w, false); + rkisp_idx_write(dev, reg, right_w, ISP_UNITE_RIGHT, false); + reg = stream->config->dual_crop.ctrl; - rkisp_next_set_bits(dev, reg, 0, val, false); + rkisp_idx_set_bits(dev, reg, 0, val, ISP_UNITE_RIGHT, false); /* output with scale */ if (stream->out_fmt.width < rect->width) { left_w += RKMOUDLE_UNITE_EXTEND_PIXEL; reg = stream->config->dual_crop.h_size; - rkisp_write(dev, reg, left_w, false); + rkisp_idx_write(dev, reg, left_w, ISP_UNITE_LEFT, false); } v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev, "left dcrop (%d, %d) %dx%d\n", @@ -99,6 +102,23 @@ void rkisp_config_dcrop(struct rkisp_stream *stream, "right dcrop (%d, %d) %dx%d\n", RKMOUDLE_UNITE_EXTEND_PIXEL, tmp.top, right_w, tmp.height); } + if (dev->unite_div == ISP_UNITE_DIV4) { + reg = stream->config->dual_crop.h_offset; + rkisp_idx_write(dev, reg, tmp.left, ISP_UNITE_LEFT_B, false); + rkisp_idx_write(dev, reg, RKMOUDLE_UNITE_EXTEND_PIXEL, ISP_UNITE_RIGHT_B, false); + + reg = stream->config->dual_crop.h_size; + rkisp_idx_write(dev, reg, tmp.width, ISP_UNITE_LEFT_B, false); + rkisp_idx_write(dev, reg, tmp.width, ISP_UNITE_RIGHT_B, false); + + reg = stream->config->dual_crop.v_offset; + rkisp_idx_write(dev, reg, RKMOUDLE_UNITE_EXTEND_PIXEL, ISP_UNITE_LEFT_B, false); + rkisp_idx_write(dev, reg, RKMOUDLE_UNITE_EXTEND_PIXEL, ISP_UNITE_RIGHT_B, false); + + reg = stream->config->dual_crop.ctrl; + rkisp_idx_set_bits(dev, reg, 0, val, ISP_UNITE_LEFT_B, false); + rkisp_idx_set_bits(dev, reg, 0, val, ISP_UNITE_RIGHT_B, false); + } if (val) { reg = stream->config->dual_crop.ctrl; rkisp_set_bits(dev, reg, 0, val, false); @@ -218,7 +238,7 @@ static void set_scale(struct rkisp_stream *stream, struct v4l2_rect *in_y, rkisp_write(dev, scale_vc_addr, scale_vc, false); } - if (dev->hw_dev->unite) { + if (dev->unite_div > ISP_UNITE_DIV1) { u32 hy_size_reg, hc_size_reg, hy_offs_mi_reg, hc_offs_mi_reg, in_crop_offs_reg; u32 isp_in_w = in_y->width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; u32 scl_w = out_y->width / 2; @@ -271,11 +291,13 @@ static void set_scale(struct rkisp_stream *stream, struct v4l2_rect *in_y, extend = right_crop_y & ~0x1; reg = stream->config->dual_crop.h_offset; - rkisp_next_write(dev, reg, extend, false); + rkisp_idx_write(dev, reg, extend, ISP_UNITE_RIGHT, false); reg = stream->config->dual_crop.h_size; - rkisp_next_write(dev, reg, isp_in_w - extend, false); + rkisp_idx_write(dev, reg, isp_in_w - extend, ISP_UNITE_RIGHT, false); reg = stream->config->dual_crop.ctrl; - rkisp_next_write(dev, reg, rkisp_next_read_reg_cache(dev, reg), false); + rkisp_idx_write(dev, reg, + rkisp_idx_read_reg_cache(dev, reg, ISP_UNITE_RIGHT), + ISP_UNITE_RIGHT, false); } right_scl_in_y = right_crop_y - extend; right_scl_in_c = right_crop_c - extend; @@ -288,25 +310,26 @@ static void set_scale(struct rkisp_stream *stream, struct v4l2_rect *in_y, rkisp_write(dev, in_crop_offs_reg, 0, false); /* right isp */ - rkisp_next_write(dev, hy_size_reg, scl_w, false); - rkisp_next_write(dev, hc_size_reg, scl_w, false); - rkisp_next_write(dev, scale_hy_addr, scale_hy, false); - rkisp_next_write(dev, scale_hcb_addr, scale_hc, false); - rkisp_next_write(dev, scale_hcr_addr, scale_hc, false); - rkisp_next_write(dev, scale_vy_addr, scale_vy, false); - rkisp_next_write(dev, scale_vc_addr, scale_vc, false); - rkisp_next_write(dev, stream->config->rsz.phase_hy, phase_left_y, false); - rkisp_next_write(dev, stream->config->rsz.phase_hc, phase_left_c, false); - rkisp_next_write(dev, stream->config->rsz.phase_vy, 0, false); - rkisp_next_write(dev, stream->config->rsz.phase_vc, 0, false); - rkisp_next_write(dev, hy_offs_mi_reg, scl_w & 15, false); - rkisp_next_write(dev, hc_offs_mi_reg, scl_w & 15, false); - rkisp_next_write(dev, in_crop_offs_reg, - right_scl_in_c << 4 | right_scl_in_y, false); + rkisp_idx_write(dev, hy_size_reg, scl_w, ISP_UNITE_RIGHT, false); + rkisp_idx_write(dev, hc_size_reg, scl_w, ISP_UNITE_RIGHT, false); + rkisp_idx_write(dev, scale_hy_addr, scale_hy, ISP_UNITE_RIGHT, false); + rkisp_idx_write(dev, scale_hcb_addr, scale_hc, ISP_UNITE_RIGHT, false); + rkisp_idx_write(dev, scale_hcr_addr, scale_hc, ISP_UNITE_RIGHT, false); + rkisp_idx_write(dev, scale_vy_addr, scale_vy, ISP_UNITE_RIGHT, false); + rkisp_idx_write(dev, scale_vc_addr, scale_vc, ISP_UNITE_RIGHT, false); + rkisp_idx_write(dev, stream->config->rsz.phase_hy, phase_left_y, ISP_UNITE_RIGHT, false); + rkisp_idx_write(dev, stream->config->rsz.phase_hc, phase_left_c, ISP_UNITE_RIGHT, false); + rkisp_idx_write(dev, stream->config->rsz.phase_vy, 0, ISP_UNITE_RIGHT, false); + rkisp_idx_write(dev, stream->config->rsz.phase_vc, 0, ISP_UNITE_RIGHT, false); + rkisp_idx_write(dev, hy_offs_mi_reg, scl_w & 15, ISP_UNITE_RIGHT, false); + rkisp_idx_write(dev, hc_offs_mi_reg, scl_w & 15, ISP_UNITE_RIGHT, false); + rkisp_idx_write(dev, in_crop_offs_reg, + right_scl_in_c << 4 | right_scl_in_y, ISP_UNITE_RIGHT, false); rsz_ctrl |= ISP3X_SCL_CLIP_EN; - rkisp_next_write(dev, rsz_ctrl_addr, - rsz_ctrl | ISP3X_SCL_HPHASE_EN | ISP3X_SCL_IN_CLIP_EN, false); + rkisp_idx_write(dev, rsz_ctrl_addr, + rsz_ctrl | ISP3X_SCL_HPHASE_EN | ISP3X_SCL_IN_CLIP_EN, + ISP_UNITE_RIGHT, false); v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev, "scl:%dx%d, scl factor[hy:%d hc:%d vy:%d vc:%d]\n", scl_w, out_y->height, scale_hy, scale_hc, scale_vy, scale_vc); @@ -328,12 +351,12 @@ static void set_bilinear_scale(struct rkisp_stream *stream, struct v4l2_rect *in u32 rsz_ctrl = 0, val, hy, hc; bool is_avg = false; - rkisp_write(dev, ISP32_SELF_SCALE_HY_OFFS, 0, true); - rkisp_write(dev, ISP32_SELF_SCALE_HC_OFFS, 0, true); - rkisp_write(dev, ISP32_SELF_SCALE_PHASE_HY, 0, true); - rkisp_write(dev, ISP32_SELF_SCALE_PHASE_HC, 0, true); - rkisp_write(dev, ISP32_SELF_SCALE_PHASE_VY, 0, true); - rkisp_write(dev, ISP32_SELF_SCALE_PHASE_VC, 0, true); + rkisp_unite_write(dev, ISP32_SELF_SCALE_HY_OFFS, 0, true); + rkisp_unite_write(dev, ISP32_SELF_SCALE_HC_OFFS, 0, true); + rkisp_unite_write(dev, ISP32_SELF_SCALE_PHASE_HY, 0, true); + rkisp_unite_write(dev, ISP32_SELF_SCALE_PHASE_HC, 0, true); + rkisp_unite_write(dev, ISP32_SELF_SCALE_PHASE_VY, 0, true); + rkisp_unite_write(dev, ISP32_SELF_SCALE_PHASE_VC, 0, true); val = in_y->width | in_y->height << 16; rkisp_write(dev, ISP32_SELF_SCALE_SRC_SIZE, val, false); @@ -386,10 +409,10 @@ void rkisp_config_rsz(struct rkisp_stream *stream, struct v4l2_rect *in_y, } /* No phase offset */ - rkisp_write(dev, stream->config->rsz.phase_hy, 0, true); - rkisp_write(dev, stream->config->rsz.phase_hc, 0, true); - rkisp_write(dev, stream->config->rsz.phase_vy, 0, true); - rkisp_write(dev, stream->config->rsz.phase_vc, 0, true); + rkisp_unite_write(dev, stream->config->rsz.phase_hy, 0, true); + rkisp_unite_write(dev, stream->config->rsz.phase_hc, 0, true); + rkisp_unite_write(dev, stream->config->rsz.phase_vy, 0, true); + rkisp_unite_write(dev, stream->config->rsz.phase_vc, 0, true); /* Linear interpolation */ for (i = 0; i < 64; i++) { diff --git a/drivers/media/platform/rockchip/isp/regs_v2x.h b/drivers/media/platform/rockchip/isp/regs_v2x.h index 2f3c1009ae4e..045c5a8eb386 100644 --- a/drivers/media/platform/rockchip/isp/regs_v2x.h +++ b/drivers/media/platform/rockchip/isp/regs_v2x.h @@ -2696,15 +2696,10 @@ static inline void mi_raw_length(struct rkisp_stream *stream) stream->config->mi.length == MI_RAW1_RD_LENGTH || stream->config->mi.length == MI_RAW2_RD_LENGTH) is_direct = false; - rkisp_write(stream->ispdev, stream->config->mi.length, - stream->out_fmt.plane_fmt[0].bytesperline, is_direct); + rkisp_unite_write(stream->ispdev, stream->config->mi.length, + stream->out_fmt.plane_fmt[0].bytesperline, is_direct); if (stream->ispdev->isp_ver == ISP_V21 || stream->ispdev->isp_ver == ISP_V30) - rkisp_set_bits(stream->ispdev, MI_RD_CTRL2, 0, BIT(30), false); - if (stream->ispdev->hw_dev->unite) { - rkisp_next_write(stream->ispdev, stream->config->mi.length, - stream->out_fmt.plane_fmt[0].bytesperline, is_direct); - rkisp_next_set_bits(stream->ispdev, MI_RD_CTRL2, 0, BIT(30), false); - } + rkisp_unite_set_bits(stream->ispdev, MI_RD_CTRL2, 0, BIT(30), false); } static inline void rx_force_upd(void __iomem *base) diff --git a/drivers/media/platform/rockchip/isp/rkisp.c b/drivers/media/platform/rockchip/isp/rkisp.c index 74b8dab09249..a12837374dcf 100644 --- a/drivers/media/platform/rockchip/isp/rkisp.c +++ b/drivers/media/platform/rockchip/isp/rkisp.c @@ -219,8 +219,10 @@ int rkisp_align_sensor_resolution(struct rkisp_device *dev, CIF_ISP_INPUT_H_MAX_V32_UNITE : CIF_ISP_INPUT_H_MAX_V32; break; case ISP_V32_L: - max_w = CIF_ISP_INPUT_W_MAX_V32_L; - max_h = CIF_ISP_INPUT_H_MAX_V32_L; + max_w = dev->hw_dev->unite ? + CIF_ISP_INPUT_W_MAX_V32_L_UNITE : CIF_ISP_INPUT_W_MAX_V32_L; + max_h = dev->hw_dev->unite ? + CIF_ISP_INPUT_H_MAX_V32_L_UNITE : CIF_ISP_INPUT_H_MAX_V32_L; break; default: max_w = CIF_ISP_INPUT_W_MAX; @@ -481,7 +483,7 @@ static void rkisp_dvfs(struct rkisp_device *dev) { struct rkisp_hw_dev *hw = dev->hw_dev; u64 data_rate = 0; - int i, fps, num = 0; + int i, fps, size, num = 0; if (!hw->is_dvfs) return; @@ -492,7 +494,8 @@ static void rkisp_dvfs(struct rkisp_device *dev) fps = hw->isp_size[i].fps; if (!fps) fps = 30; - data_rate += (fps * hw->isp_size[i].size); + size = hw->isp_size[i].size * hw->isp[i]->unite_div; + data_rate += (fps * size); num++; } do_div(data_rate, 1000 * 1000); @@ -924,8 +927,10 @@ static void rkisp_rdbk_trigger_handle(struct rkisp_device *dev, u32 cmd) is_try = true; times = 0; if (hw->unite == ISP_UNITE_ONE) { - if (dev->sw_rd_cnt < 2) + if (hw->is_multi_overflow && dev->sw_rd_cnt < 2) isp->unite_index = ISP_UNITE_RIGHT; + else if (hw->is_frm_buf) + isp->unite_index++; if (!hw->is_multi_overflow || (dev->sw_rd_cnt & 0x1)) is_try = false; } @@ -985,24 +990,27 @@ static void rkisp_rdbk_trigger_handle(struct rkisp_device *dev, u32 cmd) hw->is_idle = false; /* this frame will read count by isp */ isp->sw_rd_cnt = 0; - /* frame double for multi camera resolution out of hardware limit - * first for HW save this camera information, and second to output image - */ isp->is_frame_double = false; - if (hw->is_multi_overflow && - (hw->unite == ISP_UNITE_ONE || - (hw->pre_dev_id != -1 && hw->pre_dev_id != id))) { - isp->is_frame_double = true; - isp->sw_rd_cnt = 1; - times = 0; - } - /* resolution out of hardware limit - * frame is vertically divided into left and right - */ isp->unite_index = ISP_UNITE_LEFT; - if (hw->unite == ISP_UNITE_ONE) { - isp->sw_rd_cnt *= 2; - isp->sw_rd_cnt += 1; + if (hw->is_multi_overflow) { + /* frame double for multi camera resolution out of hardware limit + * first for HW save this camera information, and second to output image + */ + if ((hw->unite == ISP_UNITE_ONE || + (hw->pre_dev_id != -1 && hw->pre_dev_id != id))) { + isp->is_frame_double = true; + isp->sw_rd_cnt = 1; + times = 0; + } + /* resolution out of hardware limit + * frame is vertically divided into left and right + */ + if (hw->unite == ISP_UNITE_ONE) { + isp->sw_rd_cnt *= 2; + isp->sw_rd_cnt += 1; + } + } else if (hw->is_frm_buf) { + isp->sw_rd_cnt += (isp->unite_div - 1); } /* first frame handle twice for thunderboot * first output stats to AIQ and wait new params to run second @@ -1167,15 +1175,17 @@ static void rkisp_config_ism(struct rkisp_device *dev) { struct v4l2_rect *out_crop = &dev->isp_sdev.out_crop; u32 width = out_crop->width, mult = 1; - u32 unite = dev->hw_dev->unite; + u32 height = out_crop->height; /* isp2.0 no ism */ if (dev->isp_ver == ISP_V20 || dev->isp_ver == ISP_V21 || dev->isp_ver == ISP_V32_L) return; - if (unite) + if (dev->unite_div > ISP_UNITE_DIV1) width = width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + if (dev->unite_div == ISP_UNITE_DIV4) + height = height / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; rkisp_unite_write(dev, CIF_ISP_IS_RECENTER, 0, false); rkisp_unite_write(dev, CIF_ISP_IS_MAX_DX, 0, false); rkisp_unite_write(dev, CIF_ISP_IS_MAX_DY, 0, false); @@ -1185,7 +1195,7 @@ static void rkisp_config_ism(struct rkisp_device *dev) rkisp_unite_write(dev, CIF_ISP_IS_H_SIZE, width, false); if (dev->cap_dev.stream[RKISP_STREAM_SP].interlaced) mult = 2; - rkisp_unite_write(dev, CIF_ISP_IS_V_SIZE, out_crop->height / mult, false); + rkisp_unite_write(dev, CIF_ISP_IS_V_SIZE, height / mult, false); if (dev->isp_ver == ISP_V30 || dev->isp_ver == ISP_V32) return; @@ -1520,18 +1530,17 @@ static void rkisp_config_cmsk_dual(struct rkisp_device *dev, val = ISP3X_SW_CMSK_YUV(left.win[i].cover_color_y, left.win[i].cover_color_u, left.win[i].cover_color_v); - rkisp_write(dev, ISP3X_CMSK_YUV0 + i * 4, val, false); - rkisp_next_write(dev, ISP3X_CMSK_YUV0 + i * 4, val, false); + rkisp_unite_write(dev, ISP3X_CMSK_YUV0 + i * 4, val, false); val = ISP_PACK_2SHORT(left.win[i].h_offs, left.win[i].v_offs); - rkisp_write(dev, ISP3X_CMSK_OFFS0 + i * 8, val, false); + rkisp_idx_write(dev, ISP3X_CMSK_OFFS0 + i * 8, val, ISP_UNITE_LEFT, false); val = ISP_PACK_2SHORT(left.win[i].h_size, left.win[i].v_size); - rkisp_write(dev, ISP3X_CMSK_SIZE0 + i * 8, val, false); + rkisp_idx_write(dev, ISP3X_CMSK_SIZE0 + i * 8, val, ISP_UNITE_LEFT, false); val = ISP_PACK_2SHORT(right.win[i].h_offs, right.win[i].v_offs); - rkisp_next_write(dev, ISP3X_CMSK_OFFS0 + i * 8, val, false); + rkisp_idx_write(dev, ISP3X_CMSK_OFFS0 + i * 8, val, ISP_UNITE_RIGHT, false); val = ISP_PACK_2SHORT(right.win[i].h_size, right.win[i].v_size); - rkisp_next_write(dev, ISP3X_CMSK_SIZE0 + i * 8, val, false); + rkisp_idx_write(dev, ISP3X_CMSK_SIZE0 + i * 8, val, ISP_UNITE_RIGHT, false); } w += RKMOUDLE_UNITE_EXTEND_PIXEL; @@ -1564,33 +1573,34 @@ static void rkisp_config_cmsk_dual(struct rkisp_device *dev, ctrl = 0; if (right.win[0].win_en) { ctrl |= ISP3X_SW_CMSK_EN_MP; - rkisp_next_write(dev, ISP3X_CMSK_CTRL1, right.win[0].win_en, false); + rkisp_idx_write(dev, ISP3X_CMSK_CTRL1, right.win[0].win_en, ISP_UNITE_RIGHT, false); val = right.win[0].mode; - rkisp_next_write(dev, ISP3X_CMSK_CTRL4, val, false); + rkisp_idx_write(dev, ISP3X_CMSK_CTRL4, val, ISP_UNITE_RIGHT, false); } if (right.win[1].win_en) { ctrl |= ISP3X_SW_CMSK_EN_SP; - rkisp_next_write(dev, ISP3X_CMSK_CTRL2, right.win[1].win_en, false); + rkisp_idx_write(dev, ISP3X_CMSK_CTRL2, right.win[1].win_en, ISP_UNITE_RIGHT, false); val = right.win[1].mode; - rkisp_next_write(dev, ISP3X_CMSK_CTRL5, val, false); + rkisp_idx_write(dev, ISP3X_CMSK_CTRL5, val, ISP_UNITE_RIGHT, false); } if (right.win[2].win_en) { ctrl |= ISP3X_SW_CMSK_EN_BP; - rkisp_next_write(dev, ISP3X_CMSK_CTRL3, right.win[2].win_en, false); + rkisp_idx_write(dev, ISP3X_CMSK_CTRL3, right.win[2].win_en, ISP_UNITE_RIGHT, false); val = right.win[2].mode; - rkisp_next_write(dev, ISP3X_CMSK_CTRL6, val, false); + rkisp_idx_write(dev, ISP3X_CMSK_CTRL6, val, ISP_UNITE_RIGHT, false); } if (ctrl) { val = ISP_PACK_2SHORT(w, height); - rkisp_next_write(dev, ISP3X_CMSK_PIC_SIZE, val, false); + rkisp_idx_write(dev, ISP3X_CMSK_PIC_SIZE, val, ISP_UNITE_RIGHT, false); ctrl |= ISP3X_SW_CMSK_EN | ISP3X_SW_CMSK_ORDER_MODE; } - rkisp_next_write(dev, ISP3X_CMSK_CTRL0, ctrl, false); + rkisp_idx_write(dev, ISP3X_CMSK_CTRL0, ctrl, ISP_UNITE_RIGHT, false); - val = rkisp_next_read(dev, ISP3X_CMSK_CTRL0, true); + val = rkisp_idx_read(dev, ISP3X_CMSK_CTRL0, ISP_UNITE_RIGHT, true); if (dev->hw_dev->is_single && ((val & ISP32_SW_CMSK_EN_PATH) != (val & ISP32_SW_CMSK_EN_PATH_SHD))) - rkisp_next_write(dev, ISP3X_CMSK_CTRL0, val | ISP3X_SW_CMSK_FORCE_UPD, false); + rkisp_idx_write(dev, ISP3X_CMSK_CTRL0, val | ISP3X_SW_CMSK_FORCE_UPD, + ISP_UNITE_RIGHT, false); } static void rkisp_config_cmsk(struct rkisp_device *dev) @@ -1625,20 +1635,20 @@ static int rkisp_config_isp(struct rkisp_device *dev) struct ispsd_out_fmt *out_fmt; struct v4l2_rect *in_crop; struct rkisp_sensor_info *sensor; - bool is_unite = !!dev->hw_dev->unite; u32 isp_ctrl = 0; u32 irq_mask = 0; u32 signal = 0; u32 acq_mult = 0; u32 acq_prop = 0; u32 extend_line = 0; - u32 width; + u32 width, height; sensor = dev->active_sensor; in_fmt = &dev->isp_sdev.in_fmt; out_fmt = &dev->isp_sdev.out_fmt; in_crop = &dev->isp_sdev.in_crop; width = in_crop->width; + height = in_crop->height; if (in_fmt->fmt_type == FMT_BAYER) { acq_mult = 1; @@ -1727,8 +1737,10 @@ static int rkisp_config_isp(struct rkisp_device *dev) rkisp_unite_write(dev, CIF_ISP_ACQ_PROP, acq_prop, false); rkisp_unite_write(dev, CIF_ISP_ACQ_NR_FRAMES, 0, true); - if (is_unite) + if (dev->unite_div > ISP_UNITE_DIV1) width = width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + if (dev->unite_div == ISP_UNITE_DIV4) + height = height / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; /* Acquisition Size */ rkisp_unite_write(dev, CIF_ISP_ACQ_H_OFFS, acq_mult * in_crop->left, false); rkisp_unite_write(dev, CIF_ISP_ACQ_V_OFFS, in_crop->top, false); @@ -1740,11 +1752,11 @@ static int rkisp_config_isp(struct rkisp_device *dev) rkisp_unite_write(dev, CIF_ISP_OUT_H_SIZE, width, false); if (dev->cap_dev.stream[RKISP_STREAM_SP].interlaced) { - rkisp_unite_write(dev, CIF_ISP_ACQ_V_SIZE, in_crop->height / 2, false); - rkisp_unite_write(dev, CIF_ISP_OUT_V_SIZE, in_crop->height / 2, false); + rkisp_unite_write(dev, CIF_ISP_ACQ_V_SIZE, height / 2, false); + rkisp_unite_write(dev, CIF_ISP_OUT_V_SIZE, height / 2, false); } else { - rkisp_unite_write(dev, CIF_ISP_ACQ_V_SIZE, in_crop->height + extend_line, false); - rkisp_unite_write(dev, CIF_ISP_OUT_V_SIZE, in_crop->height + extend_line, false); + rkisp_unite_write(dev, CIF_ISP_ACQ_V_SIZE, height + extend_line, false); + rkisp_unite_write(dev, CIF_ISP_OUT_V_SIZE, height + extend_line, false); } /* interrupt mask */ @@ -2048,16 +2060,13 @@ static int rkisp_isp_stop(struct rkisp_device *dev) /* stop ISP */ val = rkisp_read(dev, CIF_ISP_CTRL, true); val &= ~(CIF_ISP_CTRL_ISP_INFORM_ENABLE | CIF_ISP_CTRL_ISP_ENABLE); - rkisp_write(dev, CIF_ISP_CTRL, val, true); + rkisp_unite_write(dev, CIF_ISP_CTRL, val, true); val = rkisp_read(dev, CIF_ISP_CTRL, true); val |= CIF_ISP_CTRL_ISP_CFG_UPD; - rkisp_write(dev, CIF_ISP_CTRL, val, true); + rkisp_unite_write(dev, CIF_ISP_CTRL, val, true); rkisp_clear_reg_cache_bits(dev, CIF_ISP_CTRL, CIF_ISP_CTRL_ISP_CFG_UPD); - if (hw->unite == ISP_UNITE_TWO) { - rkisp_next_write(dev, CIF_ISP_CTRL, val, true); - rkisp_next_clear_reg_cache_bits(dev, CIF_ISP_CTRL, CIF_ISP_CTRL_ISP_CFG_UPD); - } + readx_poll_timeout_atomic(readl, base + CIF_ISP_RIS, val, val & CIF_ISP_OFF, 20, 100); v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev, @@ -2085,9 +2094,7 @@ static int rkisp_isp_stop(struct rkisp_device *dev) writel(0, base + CIF_ISP_CSI0_MASK2); writel(0, base + CIF_ISP_CSI0_MASK3); } else if (dev->isp_ver >= ISP_V20) { - writel(0, base + CSI2RX_CSI2_RESETN); - if (hw->unite == ISP_UNITE_TWO) - rkisp_next_write(dev, CSI2RX_CSI2_RESETN, 0, true); + rkisp_unite_write(dev, CSI2RX_CSI2_RESETN, 0, true); } hw->is_dvfs = false; @@ -2595,6 +2602,8 @@ static void rkisp_isp_sd_try_crop(struct v4l2_subdev *sd, struct rkisp_isp_subdev *isp_sd = sd_to_isp_sd(sd); struct rkisp_device *dev = sd_to_isp_dev(sd); struct v4l2_rect in_crop = isp_sd->in_crop; + struct rkisp_hw_dev *hw = dev->hw_dev; + u32 size; crop->left = ALIGN(crop->left, 2); crop->width = ALIGN(crop->width, 2); @@ -2603,6 +2612,28 @@ static void rkisp_isp_sd_try_crop(struct v4l2_subdev *sd, /* update sensor info if sensor link be changed */ rkisp_update_sensor_info(dev); rkisp_align_sensor_resolution(dev, crop, true); + if (hw->unite == ISP_UNITE_TWO && hw->isp_ver == ISP_V30) { + dev->unite_div = ISP_UNITE_DIV2; + } else { + dev->unite_div = ISP_UNITE_DIV1; + switch (dev->isp_ver) { + case ISP_V30: + size = CIF_ISP_INPUT_W_MAX_V30 * CIF_ISP_INPUT_H_MAX_V30; + break; + case ISP_V32: + size = CIF_ISP_INPUT_W_MAX_V32 * CIF_ISP_INPUT_H_MAX_V32; + break; + case ISP_V32_L: + size = CIF_ISP_INPUT_W_MAX_V32_L * CIF_ISP_INPUT_H_MAX_V32_L; + break; + default: + return; + } + if (crop->width * crop->height > size * 2) + dev->unite_div = ISP_UNITE_DIV4; + else if (crop->width * crop->height > size) + dev->unite_div = ISP_UNITE_DIV2; + } } else if (pad == RKISP_ISP_PAD_SOURCE_PATH) { crop->left = clamp_t(u32, crop->left, 0, in_crop.width); crop->top = clamp_t(u32, crop->top, 0, in_crop.height); @@ -2667,8 +2698,10 @@ static int rkisp_isp_sd_get_selection(struct v4l2_subdev *sd, CIF_ISP_INPUT_H_MAX_V32_UNITE : CIF_ISP_INPUT_H_MAX_V32; break; case ISP_V32_L: - max_w = CIF_ISP_INPUT_W_MAX_V32_L; - max_h = CIF_ISP_INPUT_H_MAX_V32_L; + max_w = dev->hw_dev->unite ? + CIF_ISP_INPUT_W_MAX_V32_L_UNITE : CIF_ISP_INPUT_W_MAX_V32_L; + max_h = dev->hw_dev->unite ? + CIF_ISP_INPUT_H_MAX_V32_L_UNITE : CIF_ISP_INPUT_H_MAX_V32_L; break; default: max_w = CIF_ISP_INPUT_W_MAX; @@ -2931,8 +2964,9 @@ static void rkisp_rx_qbuf_online(struct rkisp_stream *stream, { struct rkisp_device *dev = stream->ispdev; u32 val = pool->buf.buff_addr[RKISP_PLANE_Y]; + u32 reg = stream->config->mi.y_base_ad_init; - rkisp_write(dev, stream->config->mi.y_base_ad_init, val, false); + rkisp_write(dev, reg, val, false); if (dev->hw_dev->unite == ISP_UNITE_TWO) { u32 offs = stream->out_fmt.width / 2 - RKMOUDLE_UNITE_EXTEND_PIXEL; @@ -2941,7 +2975,7 @@ static void rkisp_rx_qbuf_online(struct rkisp_stream *stream, else offs = offs * stream->out_isp_fmt.bpp[0] / 8; val += offs; - rkisp_next_write(dev, stream->config->mi.y_base_ad_init, val, false); + rkisp_idx_write(dev, reg, val, ISP_UNITE_RIGHT, false); } } @@ -3407,11 +3441,12 @@ static int rkisp_get_info(struct rkisp_device *dev, struct rkisp_isp_info *info) if (dev->is_bigmode) mode |= RKISP_ISP_BIGMODE; info->mode = mode; - if (dev->hw_dev->unite) + info->act_width = in_crop->width; + if (dev->unite_div > ISP_UNITE_DIV1) info->act_width = in_crop->width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; - else - info->act_width = in_crop->width; info->act_height = in_crop->height; + if (dev->unite_div == ISP_UNITE_DIV4) + info->act_height = in_crop->height / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; return 0; } @@ -3817,6 +3852,7 @@ int rkisp_register_isp_subdev(struct rkisp_device *isp_dev, goto err_cleanup_media_entity; } + isp_dev->unite_div = ISP_UNITE_DIV1; rkisp_isp_sd_init_default_fmt(isp_sdev); isp_dev->hdr.sensor = NULL; isp_dev->isp_state = ISP_STOP; diff --git a/drivers/media/platform/rockchip/isp/rkisp.h b/drivers/media/platform/rockchip/isp/rkisp.h index 76f8ce05e424..ebd37c274cfb 100644 --- a/drivers/media/platform/rockchip/isp/rkisp.h +++ b/drivers/media/platform/rockchip/isp/rkisp.h @@ -61,6 +61,8 @@ #define CIF_ISP_INPUT_H_MAX_V32_UNITE 2160 #define CIF_ISP_INPUT_W_MAX_V32_L 4224 #define CIF_ISP_INPUT_H_MAX_V32_L 3136 +#define CIF_ISP_INPUT_W_MAX_V32_L_UNITE 8192 +#define CIF_ISP_INPUT_H_MAX_V32_L_UNITE 6144 #define CIF_ISP_INPUT_W_MIN 272 #define CIF_ISP_INPUT_H_MIN 256 #define CIF_ISP_OUTPUT_W_MAX CIF_ISP_INPUT_W_MAX