From 49f88ec9c5b8ed1299ee7c1a659e4e8b5663b29c Mon Sep 17 00:00:00 2001 From: Damon Ding Date: Mon, 31 Mar 2025 17:01:17 +0800 Subject: [PATCH 01/57] clk: rockchip: rk3576: expand pll rate table to support 152.6M vop dclk rate Change-Id: Icd91181488730c2f88a3e8a9f6282afcc87123f8 Signed-off-by: Damon Ding --- drivers/clk/rockchip/clk-rk3576.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/rockchip/clk-rk3576.c b/drivers/clk/rockchip/clk-rk3576.c index 095157d5a34b..4f493784d090 100644 --- a/drivers/clk/rockchip/clk-rk3576.c +++ b/drivers/clk/rockchip/clk-rk3576.c @@ -91,6 +91,7 @@ static struct rockchip_pll_rate_table rk3576_pll_rates[] = { RK3588_PLL_RATE(773000000, 2, 258, 2, 43690), RK3588_PLL_RATE(722534400, 8, 963, 2, 24850), RK3588_PLL_RATE(697000000, 2, 232, 2, 21845), + RK3588_PLL_RATE(610400000, 3, 305, 2, 13107), RK3588_PLL_RATE(604800000, 1, 101, 2, 52428), RK3588_PLL_RATE(600000000, 2, 200, 2, 0), RK3588_PLL_RATE(594000000, 2, 198, 2, 0), From 381343d4fbf2e434ea0ba9d9330bca49be43eda8 Mon Sep 17 00:00:00 2001 From: Xing Zheng Date: Mon, 31 Mar 2025 21:34:05 +0800 Subject: [PATCH 02/57] ASoC: codecs: rk_dsm: Fix the silence during recover from XRUN Here we need to restore the volume and ioswitch status. Otherwise, there will be no sound if you restore from the xrun state. Signed-off-by: Xing Zheng Change-Id: I96e4bbcde035a700e2e18ee8782d75cdac2b18be --- sound/soc/codecs/rk_dsm.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/sound/soc/codecs/rk_dsm.c b/sound/soc/codecs/rk_dsm.c index 9a189b7fcea3..07e3793ae51b 100644 --- a/sound/soc/codecs/rk_dsm.c +++ b/sound/soc/codecs/rk_dsm.c @@ -520,6 +520,19 @@ static int rk_dsm_pcm_trigger(struct snd_pcm_substream *substream, snd_soc_component_get_drvdata(dai->component); switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + /** + * NOTE: Recover DAC volumes and switch RKDSM_ON_FUNC after hw_param() + * again, avoid to incorrect silence during recover from XRUN. + */ + regmap_write(rd->regmap, DACVOLL0, rd->vols.vol_l); + regmap_write(rd->regmap, DACVOLR0, rd->vols.vol_r); + regmap_write(rd->regmap, DACVOGP, rd->vols.polarity); + if (rd->data && rd->data->iomux_switch) + rd->data->iomux_switch(rd->dev, RKDSM_ON_FUNC); + break; case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: From e19545e128d1ff1c909d9391022206331c4f2af0 Mon Sep 17 00:00:00 2001 From: Chaoyi Chen Date: Fri, 28 Mar 2025 14:31:15 +0800 Subject: [PATCH 03/57] drm/rockchip: vop: Add support for force mcu rdn The RV1126B introduce force RDN feature in MCU interface, which allow to output high voltage level on the MCU_RDN line when MCU is sending data, especially for data in the write direction. This feature helps avoid unintended level flips on the RDN line. Change-Id: I47d46e720e4ec44439570b216bddd694482851c7 Signed-off-by: Chaoyi Chen --- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 5 +++++ drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 1 + drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 2 ++ drivers/gpu/drm/rockchip/rockchip_vop_reg.h | 1 + 4 files changed, 9 insertions(+) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 10e31fb0b468..e3e55d9e9ca4 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -3719,21 +3719,26 @@ static void vop_crtc_send_mcu_cmd(struct drm_crtc *crtc, u32 type, u32 value) if (vop && vop->is_enabled) { switch (type) { case MCU_WRCMD: + VOP_CTRL_SET(vop, mcu_force_rdn, 1); VOP_CTRL_SET(vop, mcu_rs, 0); VOP_CTRL_SET(vop, mcu_rw_bypass_port, value); VOP_CTRL_SET(vop, mcu_rs, 1); break; case MCU_WRDATA: + VOP_CTRL_SET(vop, mcu_force_rdn, 1); VOP_CTRL_SET(vop, mcu_rs, 1); VOP_CTRL_SET(vop, mcu_rw_bypass_port, value); break; case MCU_RDDATA: + VOP_CTRL_SET(vop, mcu_force_rdn, 0); VOP_CTRL_SET(vop, mcu_rs, 1); val = VOP_CTRL_GET(vop, mcu_rw_bypass_port); DRM_DEBUG_DRIVER("mcu read reg[0x%02x] = 0x%02x", value, val); break; case MCU_SETBYPASS: VOP_CTRL_SET(vop, mcu_bypass, value ? 1 : 0); + if (!value) + VOP_CTRL_SET(vop, mcu_force_rdn, 1); break; default: break; diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h index 8a701fb77903..449c75963fc0 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h @@ -457,6 +457,7 @@ struct vop_ctrl { struct vop_reg mcu_bypass; struct vop_reg mcu_type; struct vop_reg mcu_rw_bypass_port; + struct vop_reg mcu_force_rdn; /* bt1120 */ struct vop_reg bt1120_uv_swap; diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c index e4df700d012d..616c1b2e3a5d 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c @@ -1943,6 +1943,8 @@ static const struct vop_ctrl rv1126b_ctrl_data = { .bt1120_yc_swap = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x1, 30), .bt1120_en = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x1, 31), + .mcu_force_rdn = VOP_REG(RV1126B_DSP_CTRL1, 0x1, 21), + .dsp_interlace = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 0), .dither_up_en = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 2), .overlay_mode = VOP_REG(RK3366_LIT_DSP_CTRL2, 0x1, 4), diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.h b/drivers/gpu/drm/rockchip/rockchip_vop_reg.h index c1086ab10700..d175c742c613 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.h +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.h @@ -1039,6 +1039,7 @@ #define RV1126_GRF_IOFUNC_CON3 0x1026c +#define RV1126B_DSP_CTRL1 0x0024 #define RV1126B_CLK_CNT 0x0040 #define RV1126B_GRF_VOP_LCDC_CON 0x30b9c #define RV1126B_WB_CTRL 0x0280 From d8a328212559bda33b37c97fb1dfe18b5cb887a6 Mon Sep 17 00:00:00 2001 From: Chaoyi Chen Date: Mon, 31 Mar 2025 10:42:06 +0800 Subject: [PATCH 04/57] drm/rockchip: vop: Add bt656 support for RV1126B Change-Id: I6e67a045fa6326c7924a6848948cf7ec9e9872f3 Signed-off-by: Chaoyi Chen --- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 12 ++++++------ drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 1 + 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index e3e55d9e9ca4..868d11eec026 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -3444,10 +3444,10 @@ vop_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode) /* * Dclk need to be double if BT656 interface and vop version >= 2.12. - * That is RV1126/RV1106/RK3576_LITE/RK3506 + * That is RV1126/RV1106/RK3576_LITE/RK3506/RV1126B */ if (mode->flags & DRM_MODE_FLAG_DBLCLK || - (VOP_MAJOR(vop->version) == 2 && VOP_MINOR(vop->version) >= 12 && + (vop->version >= VOP_VERSION_RV1106 && vop->version <= VOP_VERSION_RK3288 && s->output_if & VOP_OUTPUT_IF_BT656)) request_clock *= 2; clock = clk_round_rate(vop->dclk, request_clock * 1000) / 1000; @@ -3903,10 +3903,10 @@ static bool vop_crtc_mode_fixup(struct drm_crtc *crtc, /* * Dclk need to be double if BT656 interface and vop version >= 2.12. - * That is RV1126/RV1106/RK3576_LITE/RK3506 + * That is RV1126/RV1106/RK3576_LITE/RK3506/RV1126B */ if (mode->flags & DRM_MODE_FLAG_DBLCLK || - (VOP_MAJOR(vop->version) == 2 && VOP_MINOR(vop->version) >= 12 && + (vop->version >= VOP_VERSION_RV1106 && vop->version <= VOP_VERSION_RK3288 && s->output_if & VOP_OUTPUT_IF_BT656)) adj_mode->crtc_clock *= 2; @@ -4010,11 +4010,11 @@ static void vop_update_csc(struct drm_crtc *crtc) u32 val; /* - * When using BT656, set RV1126/RV1106/RK3576_LITE/RK3506 to P8888 mode. + * When using BT656, set RV1126/RV1106/RK3576_LITE/RK3506/RV1126B to P8888 mode. */ if ((s->output_mode == ROCKCHIP_OUT_MODE_AAAA && !(vop->data->feature & VOP_FEATURE_OUTPUT_10BIT)) || - (VOP_MAJOR(vop->version) == 2 && VOP_MINOR(vop->version) >= 12 && + (vop->version >= VOP_VERSION_RV1106 && vop->version <= VOP_VERSION_RK3288 && s->output_if & VOP_OUTPUT_IF_BT656)) s->output_mode = ROCKCHIP_OUT_MODE_P888; diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c index 616c1b2e3a5d..e5075412065e 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c @@ -1942,6 +1942,7 @@ static const struct vop_ctrl rv1126b_ctrl_data = { .mipi_pin_pol = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x7, 26), .bt1120_yc_swap = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x1, 30), .bt1120_en = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x1, 31), + .bt656_en = VOP_REG(RK3366_LIT_DSP_CTRL0, 0x1, 6), .mcu_force_rdn = VOP_REG(RV1126B_DSP_CTRL1, 0x1, 21), From cd08e1a5ca8ef5c5051e57f97c5c5f55a89b80af Mon Sep 17 00:00:00 2001 From: Chaoyi Chen Date: Mon, 31 Mar 2025 10:57:07 +0800 Subject: [PATCH 05/57] drm/rockchip: vop: Add interlace mode support for RV1126B Change-Id: Ieffc2d9a2862b854895a77befe8d201fea9ad984 Signed-off-by: Chaoyi Chen --- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 6 ++++-- drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 868d11eec026..0b8ea45eba6f 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -2626,7 +2626,8 @@ static void vop_plane_atomic_update(struct drm_plane *plane, } if ((vop->version == VOP_VERSION_RK3036 || vop->version == VOP_VERSION_RK3506 || - vop->version == VOP_VERSION_RK3576_LITE) && + vop->version == VOP_VERSION_RK3576_LITE || + vop->version == VOP_VERSION_RV1126B) && (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)) dsp_h = dsp_h / 2; @@ -2643,7 +2644,8 @@ static void vop_plane_atomic_update(struct drm_plane *plane, dsp_sty = dest->y1 + mode->crtc_vtotal - mode->crtc_vsync_start; if ((vop->version == VOP_VERSION_RK3036 || vop->version == VOP_VERSION_RK3506 || - vop->version == VOP_VERSION_RK3576_LITE) && + vop->version == VOP_VERSION_RK3576_LITE || + vop->version == VOP_VERSION_RV1126B) && (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)) dsp_sty = dest->y1 / 2 + mode->crtc_vtotal - mode->crtc_vsync_start; dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff); diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c index e5075412065e..b5f1d7652306 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c @@ -1639,6 +1639,7 @@ static const struct vop_win_phy px30_win23_data = { .csc_mode = VOP_REG(RK3368_WIN2_CTRL0, 0x3, 2), .format = VOP_REG(RK3368_WIN2_CTRL0, 0x3, 5), .rb_swap = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 20), + .interlace_read = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 1), .dsp_info = VOP_REG(RK3368_WIN2_DSP_INFO0, 0x0fff0fff, 0), .dsp_st = VOP_REG(RK3368_WIN2_DSP_ST0, 0x1fff1fff, 0), .yrgb_mst = VOP_REG(RK3368_WIN2_MST0, 0xffffffff, 0), From 8ad85fa81d789a2a99983794131e6393c4144880 Mon Sep 17 00:00:00 2001 From: Zitong Cai Date: Fri, 28 Mar 2025 17:30:31 +0800 Subject: [PATCH 06/57] arm64: configs: rk3588_vehicle: Disable CONFIG_MFD_MAX96745 and CONFIG_MFD_MAX96755F Change-Id: I3502e51aa408af9f92ecc36ad7288323eac35cf5 Signed-off-by: Zitong Cai --- arch/arm64/configs/rk3588_vehicle.config | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/arch/arm64/configs/rk3588_vehicle.config b/arch/arm64/configs/rk3588_vehicle.config index 42026d98f983..329f4bbe6299 100644 --- a/arch/arm64/configs/rk3588_vehicle.config +++ b/arch/arm64/configs/rk3588_vehicle.config @@ -22,7 +22,6 @@ CONFIG_CPU_IDLE_GOV_TEO=y # CONFIG_CPU_RK3528 is not set # CONFIG_CPU_RK3562 is not set # CONFIG_CPU_RK3568 is not set -# CONFIG_CRYPTO_DEV_ROCKCHIP_V1 is not set # CONFIG_CRYPTO_DEV_ROCKCHIP_V3 is not set # CONFIG_DRM_MAXIM_MAX96745 is not set # CONFIG_DRM_MAXIM_MAX96755F is not set @@ -34,13 +33,15 @@ CONFIG_GPIO_NCA9539=y # CONFIG_HALL_DEVICE is not set CONFIG_HZ=1000 CONFIG_HZ_1000=y -# CONFIG_HZ_300 is not set +# CONFIG_HZ_250 is not set # CONFIG_IIO_ST_LSM6DSR is not set # CONFIG_INPUT_TABLET is not set # CONFIG_LIGHT_DEVICE is not set CONFIG_LOG_BUF_SHIFT=20 # CONFIG_MALI400 is not set # CONFIG_MALI_MIDGARD is not set +# CONFIG_MFD_MAX96745 is not set +# CONFIG_MFD_MAX96755F is not set # CONFIG_MFD_RK618 is not set # CONFIG_MFD_RK630_I2C is not set # CONFIG_MFD_RKX110_X120 is not set @@ -56,15 +57,9 @@ CONFIG_REALTEK_PHY=y # CONFIG_REGULATOR_WL2868C is not set # CONFIG_REGULATOR_XZ3216 is not set # CONFIG_ROCKCHIP_CHARGER_MANAGER is not set -# CONFIG_ROCKCHIP_CLK_BOOST is not set # CONFIG_ROCKCHIP_CLK_INV is not set # CONFIG_ROCKCHIP_CLK_PVTM is not set -# CONFIG_ROCKCHIP_DDRCLK_SIP is not set -# CONFIG_ROCKCHIP_DDRCLK_SIP_V2 is not set CONFIG_ROCKCHIP_DRM_DIRECT_SHOW=y -# CONFIG_ROCKCHIP_PLL_RK3066 is not set -# CONFIG_ROCKCHIP_PLL_RK3399 is not set -# CONFIG_ROCKCHIP_SERDES_DRM_PANEL is not set CONFIG_RTC_DRV_S35390A=y # CONFIG_SLUB_SYSFS is not set # CONFIG_SND_SOC_AW883XX is not set @@ -118,9 +113,6 @@ CONFIG_VIDEO_MAXIM_SERDES=y # CONFIG_VIDEO_RK628_BT1120 is not set # CONFIG_VIDEO_RK628_CSI is not set # CONFIG_VIDEO_RK_IRCUT is not set -# CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V1X is not set -# CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V21 is not set -# CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V32 is not set # CONFIG_VIDEO_S5K3L6XX is not set # CONFIG_VIDEO_S5KJN1 is not set # CONFIG_VIDEO_SGM3784 is not set @@ -141,10 +133,10 @@ CONFIG_SERDES_DISPLAY_CHIP_ROHM=y CONFIG_SERDES_DISPLAY_CHIP_ROHM_BU18RL82=y CONFIG_SERDES_DISPLAY_CHIP_ROHM_BU18TL82=y CONFIG_VIDEO_MAXIM_CAM_DUMMY=y +CONFIG_VIDEO_MAXIM_CAM_OS04A10=y CONFIG_VIDEO_MAXIM_CAM_OV231X=y CONFIG_VIDEO_MAXIM_CAM_OX01F10=y CONFIG_VIDEO_MAXIM_CAM_OX03J10=y -CONFIG_VIDEO_MAXIM_CAM_OS04A10=y CONFIG_VIDEO_MAXIM_CAM_SC320AT=y # CONFIG_VIDEO_MAXIM_DES_MAXIM2C is not set CONFIG_VIDEO_MAXIM_DES_MAXIM4C=y From 82294562bcb794e29b1472ba85202e2c44b80233 Mon Sep 17 00:00:00 2001 From: Sandy Huang Date: Fri, 21 Feb 2025 09:31:06 +0800 Subject: [PATCH 07/57] drm/rockchip: drv: move clk unprotect to the end of drm_bind rockchip_drm_bind() may be delayed for others driver delay probe, this maybe cause rockchip_drm_show_logo() be called after rockchip_clocks_loader_unprotect() and lead to display error, so move clk unprotect to the end of drm_bind. Signed-off-by: Sandy Huang Change-Id: I6eeae1c1307f91777fec23c66c5d5413443335d0 --- drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 1 + drivers/gpu/drm/rockchip/rockchip_drm_logo.c | 6 +++--- drivers/gpu/drm/rockchip/rockchip_drm_logo.h | 8 ++++++++ 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c index 938ca72fc9c3..fed632d849f2 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c @@ -1906,6 +1906,7 @@ static int rockchip_drm_bind(struct device *dev) goto err_drm_fbdev_fini; rockchip_drm_error_event_init(drm_dev); + rockchip_clocks_loader_unprotect(); return 0; err_drm_fbdev_fini: diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_logo.c b/drivers/gpu/drm/rockchip/rockchip_drm_logo.c index 1be914c14841..2b7076fac108 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_logo.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_logo.c @@ -1316,7 +1316,7 @@ static const char *const loader_protect_clocks[] __initconst = { "dclk_vp3", }; -static struct clk **loader_clocks __initdata; +static struct clk **loader_clocks; static int __init rockchip_clocks_loader_protect(void) { int nclocks = ARRAY_SIZE(loader_protect_clocks); @@ -1340,7 +1340,7 @@ static int __init rockchip_clocks_loader_protect(void) } arch_initcall_sync(rockchip_clocks_loader_protect); -static int __init rockchip_clocks_loader_unprotect(void) +int rockchip_clocks_loader_unprotect(void) { int i; @@ -1354,8 +1354,8 @@ static int __init rockchip_clocks_loader_unprotect(void) clk_disable_unprepare(clk); } kfree(loader_clocks); + loader_clocks = NULL; return 0; } -late_initcall_sync(rockchip_clocks_loader_unprotect); #endif diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_logo.h b/drivers/gpu/drm/rockchip/rockchip_drm_logo.h index 7e1b1d2dfdf4..ab3fe550713c 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_logo.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_logo.h @@ -42,5 +42,13 @@ struct rockchip_drm_mode_set { void rockchip_drm_show_logo(struct drm_device *drm_dev); void rockchip_free_loader_memory(struct drm_device *drm); +#ifndef MODULE +int rockchip_clocks_loader_unprotect(void); +#else +static inline int rockchip_clocks_loader_unprotect(void) +{ + return 0; +} +#endif #endif From 92839a32ddf3539ad4e6b401d49fe5d626b161d7 Mon Sep 17 00:00:00 2001 From: Weiwen Chen Date: Mon, 31 Mar 2025 20:10:29 +0800 Subject: [PATCH 08/57] arm64: dts: rockchip: add rv1126b-evb1-v10-spi-nor board Signed-off-by: Weiwen Chen Change-Id: Ifcaab6437037db442cf58769843d33489c8ef74e --- arch/arm64/boot/dts/rockchip/Makefile | 1 + .../dts/rockchip/rv1126b-evb1-v10-spi-nor.dts | 25 +++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 arch/arm64/boot/dts/rockchip/rv1126b-evb1-v10-spi-nor.dts diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile index dd9a3600f1fd..fd92ab54e674 100644 --- a/arch/arm64/boot/dts/rockchip/Makefile +++ b/arch/arm64/boot/dts/rockchip/Makefile @@ -365,6 +365,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-tablet-v10.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-tablet-v11.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb1-v10.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb1-v10-bt-sco.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb1-v10-spi-nor.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb2-v10.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb2-v10-mcu-k350c4516t.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb2-v10-rgb-Q7050ITH2641AA1T.dtb diff --git a/arch/arm64/boot/dts/rockchip/rv1126b-evb1-v10-spi-nor.dts b/arch/arm64/boot/dts/rockchip/rv1126b-evb1-v10-spi-nor.dts new file mode 100644 index 000000000000..dcbcf18e5ec8 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rv1126b-evb1-v10-spi-nor.dts @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2025 Rockchip Electronics Co., Ltd. + */ + +/dts-v1/; +#include "rv1126b-evb1-v10.dts" + +/ { + model = "Rockchip RV1126B EVB1 V10 Board"; + compatible = "rockchip,rv1126b-evb1-v10-spi-nor", "rockchip,rv1126b"; + +}; + +&fspi0 { + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <75000000>; + spi-rx-bus-width = <4>; + spi-tx-bus-width = <1>; + }; +}; From f50bd319c1881a0569edec8ed44bf89fd2876959 Mon Sep 17 00:00:00 2001 From: Weiwen Chen Date: Mon, 31 Mar 2025 20:11:22 +0800 Subject: [PATCH 09/57] ARM: dts: rockchip: add rv1126b-evb1-v10-spi-nor board Signed-off-by: Weiwen Chen Change-Id: I62d8b4621286aa52acf8515d37eb470b04ba8965 --- arch/arm/boot/dts/Makefile | 1 + arch/arm/boot/dts/rv1126b-evb1-v10-spi-nor.dts | 6 ++++++ 2 files changed, 7 insertions(+) create mode 100644 arch/arm/boot/dts/rv1126b-evb1-v10-spi-nor.dts diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index ee686acdecda..479c19b387bd 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -1177,6 +1177,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \ rv1126-evb-ddr3-v13.dtb \ rv1126b-evb1-v10.dtb \ rv1126b-evb1-v10-bt-sco.dtb \ + rv1126b-evb1-v10-spi-nor.dtb \ rv1126b-evb2-v10.dtb \ rv1126b-evb2-v10-mcu-k350c4516t.dtb \ rv1126b-evb2-v10-rgb-Q7050ITH2641AA1T.dtb \ diff --git a/arch/arm/boot/dts/rv1126b-evb1-v10-spi-nor.dts b/arch/arm/boot/dts/rv1126b-evb1-v10-spi-nor.dts new file mode 100644 index 000000000000..e9f6a400b3a0 --- /dev/null +++ b/arch/arm/boot/dts/rv1126b-evb1-v10-spi-nor.dts @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2025 Rockchip Electronics Co., Ltd. + */ + +#include "arm64/rockchip/rv1126b-evb1-v10-spi-nor.dts" From 1e875f91104a1ab2931d30f521715426b46abd70 Mon Sep 17 00:00:00 2001 From: Su Yuefu Date: Mon, 31 Mar 2025 20:13:01 +0800 Subject: [PATCH 10/57] arm64: dts: rockchip: rv1126b-evb3-v10: Add SDMMC0 for SDCard Signed-off-by: Su Yuefu Change-Id: I94ec91fcf7cb0a3b3d32bc6f48369e4569bb420a --- .../boot/dts/rockchip/rv1126b-evb3-v10.dts | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rv1126b-evb3-v10.dts b/arch/arm64/boot/dts/rockchip/rv1126b-evb3-v10.dts index 6da087f73bc4..ace5e09058d4 100644 --- a/arch/arm64/boot/dts/rockchip/rv1126b-evb3-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rv1126b-evb3-v10.dts @@ -115,6 +115,28 @@ vin-supply = <&vccsys_stb>; }; + vcc_sd: vcc-sd { + compatible = "regulator-fixed"; + gpio = <&gpio7 RK_PA2 GPIO_ACTIVE_LOW>; + regulator-name = "vcc_sd"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + enable-active-low; + vin-supply = <&vcc_3v3>; + }; + + vccio_sd: vccio-sd { + compatible = "regulator-gpio"; + regulator-boot-on; + regulator-name = "vccio_sd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + gpios = <&gpio7 RK_PA3 GPIO_ACTIVE_LOW>; + vin-supply = <&vccsys_stb>; + states = <1800000 0x0 + 3300000 0x1>; + }; + vdd_log: vdd-log { compatible = "pwm-regulator"; pwms = <&pwm1_4ch_2 0 25000 1>; @@ -210,6 +232,20 @@ status = "okay"; }; +&sdmmc0 { + max-frequency = <200000000>; + no-sdio; + no-mmc; + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; + disable-wp; + sd-uhs-sdr104; + vmmc-supply = <&vcc_sd>; + vqmmc-supply = <&vccio_sd>; + status = "okay"; +}; + &usb2phy_host { phy-supply = <&vcc5v0_host>; }; From d61c690c976a4f6d39680056191c8737875550da Mon Sep 17 00:00:00 2001 From: Huibin Hong Date: Sat, 29 Mar 2025 13:08:16 +0800 Subject: [PATCH 11/57] ARM: configs: rv1126b-evb: enable ROCKCHIP_DEBUG Change-Id: I51bc12cb09fab7a782fb1d802ba0197fa9ec0408 Signed-off-by: Huibin Hong --- arch/arm/configs/rv1126b-evb.config | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/configs/rv1126b-evb.config b/arch/arm/configs/rv1126b-evb.config index b47e29dc2647..8f438225560c 100644 --- a/arch/arm/configs/rv1126b-evb.config +++ b/arch/arm/configs/rv1126b-evb.config @@ -29,6 +29,7 @@ CONFIG_PHY_ROCKCHIP_NANENG_COMBO_PHY=y CONFIG_RK_CMA_PROCFS=y CONFIG_RK_DMABUF_PROCFS=y CONFIG_RK_MEMBLOCK_PROCFS=y +CONFIG_ROCKCHIP_DEBUG=y CONFIG_ROCKCHIP_OPP=y CONFIG_ROCKCHIP_RGA_PROC_FS=y CONFIG_ROCKCHIP_VENDOR_STORAGE=y From 6c866b2ffc68512c69ac9e08925f23b1f3fb63af Mon Sep 17 00:00:00 2001 From: Huibin Hong Date: Sat, 29 Mar 2025 17:56:35 +0800 Subject: [PATCH 12/57] soc: rockchip: debug: disable os lock for edpcsr Change-Id: I59efc4705905880797ab14ce28726fb3542267f8 Signed-off-by: Huibin Hong --- drivers/soc/rockchip/rockchip_debug.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/soc/rockchip/rockchip_debug.c b/drivers/soc/rockchip/rockchip_debug.c index 67d14064d1c5..dbc05b9cad27 100644 --- a/drivers/soc/rockchip/rockchip_debug.c +++ b/drivers/soc/rockchip/rockchip_debug.c @@ -79,6 +79,8 @@ #define PMPCSR_LO 0x200 #define PMPCSR_HI 0x204 +#define EDOSLAR 0x300 + #define NUM_CPU_SAMPLES 100 #define NUM_SAMPLES_TO_PRINT 32 @@ -139,6 +141,9 @@ static int rockchip_debug_dump_edpcsr(struct fiq_debugger_output *output) /* Unlock EDLSR.SLK so that EDPCSRhi gets populated */ writel(EDLAR_UNLOCK, base + EDLAR); + /* Disabled os lock */ + writel(0, base + EDOSLAR); + /* Try to read a bunch of times if CPU is actually running */ for (j = 0; j < NUM_CPU_SAMPLES && printed < NUM_SAMPLES_TO_PRINT; j++) { @@ -299,6 +304,9 @@ static int rockchip_panic_notify_edpcsr(struct notifier_block *nb, /* Unlock EDLSR.SLK so that EDPCSRhi gets populated */ writel(EDLAR_UNLOCK, base + EDLAR); + /* Disabled os lock */ + writel(0, base + EDOSLAR); + pr_err("CPU%d online:%d\n", i, cpu_online(i)); /* Try to read a bunch of times if CPU is actually running */ @@ -533,6 +541,8 @@ static int rockchip_hardlock_notify(struct notifier_block *nb, base = rockchip_cpu_debug[cpu]; /* Unlock EDLSR.SLK so that EDPCSRhi gets populated */ writel(EDLAR_UNLOCK, base + EDLAR); + /* Disabled os lock */ + writel(0, base + EDOSLAR); if (sizeof(edpcsr) == 8) edpcsr = ((u64)readl(base + EDPCSR_LO)) | ((u64)readl(base + EDPCSR_HI) << 32); From a2a001d40b856f0c55d82b1c81994f2be9aa872d Mon Sep 17 00:00:00 2001 From: Su Yuefu Date: Mon, 31 Mar 2025 20:42:28 +0800 Subject: [PATCH 13/57] arm64: dts: rockchip: rv1126b-evb3-v10: Add saradc0 support Signed-off-by: Su Yuefu Change-Id: I0992674c69280e3e2fd9b11f2f29881da3250f86 --- arch/arm64/boot/dts/rockchip/rv1126b-evb3-v10.dts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rv1126b-evb3-v10.dts b/arch/arm64/boot/dts/rockchip/rv1126b-evb3-v10.dts index ace5e09058d4..213ef26dad72 100644 --- a/arch/arm64/boot/dts/rockchip/rv1126b-evb3-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rv1126b-evb3-v10.dts @@ -232,6 +232,10 @@ status = "okay"; }; +&saradc0 { + vref-supply = <&vcc_1v8>; +}; + &sdmmc0 { max-frequency = <200000000>; no-sdio; From 3cac6fc38e4964c9e0e75cd51e0a3b93d749371a Mon Sep 17 00:00:00 2001 From: Sach Lin Date: Mon, 24 Mar 2025 07:26:10 +0000 Subject: [PATCH 14/57] arm64: dts: rockchip: rv1126b-evb1-v10: Enable avsp Signed-off-by: Sach Lin Change-Id: I0071ff31c058c632f5d1b63fb2900b4b4424c6ab --- arch/arm64/boot/dts/rockchip/rv1126b-evb1-v10.dts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rv1126b-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rv1126b-evb1-v10.dts index 9eadbf6f6877..727f08d44a7b 100644 --- a/arch/arm64/boot/dts/rockchip/rv1126b-evb1-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rv1126b-evb1-v10.dts @@ -415,6 +415,14 @@ status = "okay"; }; +&rkavsp { + status = "okay"; +}; + +&rkavsp_mmu { + status = "okay"; +}; + &rkfec { status = "okay"; }; From c381f4a7e1d2a346ea3e975b4711ffd5ff0f4e76 Mon Sep 17 00:00:00 2001 From: ZhengRong Ruan Date: Mon, 31 Mar 2025 21:10:51 +0800 Subject: [PATCH 15/57] Revert "arm64: configs: enable mpp configs for rv1126b" This reverts commit 3555e6e9ee4170048af2bea0e0512564b0bc7b44. support rockit mpp. Change-Id: Icf36561fe8101001c3280956b3bef751bc971748 Signed-off-by: ZhengRong Ruan --- arch/arm64/configs/rv1126b_defconfig | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/arch/arm64/configs/rv1126b_defconfig b/arch/arm64/configs/rv1126b_defconfig index a8993723222e..e2cd25a7e53a 100644 --- a/arch/arm64/configs/rv1126b_defconfig +++ b/arch/arm64/configs/rv1126b_defconfig @@ -225,19 +225,6 @@ CONFIG_BACKLIGHT_PWM=y CONFIG_ROCKCHIP_MULTI_RGA=y CONFIG_ROCKCHIP_RGA_PROC_FS=y # CONFIG_ROCKCHIP_RGA_DEBUG_FS is not set -CONFIG_ROCKCHIP_MPP_SERVICE=y -CONFIG_ROCKCHIP_MPP_RKVDEC=y -CONFIG_ROCKCHIP_MPP_RKVDEC2=y -CONFIG_ROCKCHIP_MPP_RKVENC=y -CONFIG_ROCKCHIP_MPP_RKVENC2=y -CONFIG_ROCKCHIP_MPP_VDPU1=y -CONFIG_ROCKCHIP_MPP_VEPU1=y -CONFIG_ROCKCHIP_MPP_VDPU2=y -CONFIG_ROCKCHIP_MPP_VEPU2=y -CONFIG_ROCKCHIP_MPP_IEP2=y -CONFIG_ROCKCHIP_MPP_JPGDEC=y -CONFIG_ROCKCHIP_MPP_JPGENC=y -CONFIG_ROCKCHIP_MPP_AV1DEC=y CONFIG_ROCKCHIP_MPP_OSAL=y CONFIG_SOUND=y CONFIG_SND=y From cc082cd7b3850c0b14d54a57bf64aa5c0dcf6edd Mon Sep 17 00:00:00 2001 From: ZhengRong Ruan Date: Mon, 31 Mar 2025 21:10:51 +0800 Subject: [PATCH 16/57] arm64: configs: rv1126b_defconfig: enable CONFIG_DMABUF_HEAPS_SYSTEM to support rockit mpp Signed-off-by: ZhengRong Ruan Change-Id: I62ce6ea2809a6a9a92ffad1829df0b79e0c02adf --- arch/arm64/configs/rv1126b_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/rv1126b_defconfig b/arch/arm64/configs/rv1126b_defconfig index e2cd25a7e53a..980b2f94984f 100644 --- a/arch/arm64/configs/rv1126b_defconfig +++ b/arch/arm64/configs/rv1126b_defconfig @@ -279,6 +279,7 @@ CONFIG_RTC_DRV_RK808=y CONFIG_DMADEVICES=y CONFIG_ROCKCHIP_DMA=y CONFIG_DMABUF_HEAPS=y +CONFIG_DMABUF_HEAPS_SYSTEM=y CONFIG_DMABUF_HEAPS_ROCKCHIP=y CONFIG_DMABUF_HEAPS_ROCKCHIP_CMA_HEAP=y CONFIG_DMABUF_RK_HEAPS_DEBUG=y From 2ace7d1fb176ead6516ed87ec8d1973cfc42dd07 Mon Sep 17 00:00:00 2001 From: Chaoyi Chen Date: Mon, 31 Mar 2025 11:46:59 +0800 Subject: [PATCH 17/57] drm/bridge: sii902x: Only set CLK_RATIO_2X for DRM_MODE_FLAG_DBLCLK According to sii902x datasheet, the TClkSel (Bit[7:6] of reg 0x08, that is SII902X_TPI_PIXEL_REPETITION) selects the factor by which the input clock must be multiplied to give output clock frequency. Some interlace mode may not set DRM_MODE_FLAG_DBLCLK flag like 1080i, these mode should not enable CLK_RATIO_2X. This patch make sure we only set CLK_RATIO_2X when the mode has DRM_MODE_FLAG_DBLCLK flag. Change-Id: I1cc98693c9c8348667fabddc13d8f5ac4e689e09 Signed-off-by: Chaoyi Chen --- drivers/gpu/drm/bridge/sii902x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/sii902x.c b/drivers/gpu/drm/bridge/sii902x.c index 9c5c235090b2..689bb351a943 100644 --- a/drivers/gpu/drm/bridge/sii902x.c +++ b/drivers/gpu/drm/bridge/sii902x.c @@ -620,7 +620,7 @@ static void sii902x_bridge_mode_set(struct drm_bridge *bridge, if (ret) goto out; - if (sii902x->mode.flags & DRM_MODE_FLAG_INTERLACE) + if (sii902x->mode.flags & DRM_MODE_FLAG_DBLCLK) ratio = SII902X_TPI_CLK_RATIO_2X; else ratio = SII902X_TPI_CLK_RATIO_1X; From 5d1fb00c3526f8c2a0d62058c86ce2f8f36b1cc9 Mon Sep 17 00:00:00 2001 From: Jianlong Wang Date: Wed, 19 Mar 2025 10:39:41 +0800 Subject: [PATCH 18/57] arm64: dts: rockchip: rk3358m-automotive-ddr3-v11: Adjust some configs based on hardware 1\ fix rmii_pins for rxer is not used in rmii 2\ regulators for serdes should be always on 3\ add rk3358m-automotive-ddr3-v11-linux-tb Change-Id: Ic12c214a51ad023738ee98b4d202742640de1ab9 Signed-off-by: Jianlong Wang --- arch/arm64/boot/dts/rockchip/Makefile | 1 + .../rk3358m-automotive-ddr3-v11-linux-tb.dts | 59 +++++++++++++++++++ .../rk3358m-automotive-ddr3-v11-linux.dts | 47 +-------------- .../rockchip/rk3358m-automotive-ddr3-v11.dtsi | 19 ++++++ 4 files changed, 80 insertions(+), 46 deletions(-) create mode 100644 arch/arm64/boot/dts/rockchip/rk3358m-automotive-ddr3-v11-linux-tb.dts diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile index fd92ab54e674..ed84845a847b 100644 --- a/arch/arm64/boot/dts/rockchip/Makefile +++ b/arch/arm64/boot/dts/rockchip/Makefile @@ -56,6 +56,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-roc-cc.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-roc-pc.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3358-evb-ddr3-v10-linux.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3358m-automotive-ddr3-v11-linux.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3358m-automotive-ddr3-v11-linux-tb.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3358m-vehicle-v10.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-evb-act8846.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-geekbox.dtb diff --git a/arch/arm64/boot/dts/rockchip/rk3358m-automotive-ddr3-v11-linux-tb.dts b/arch/arm64/boot/dts/rockchip/rk3358m-automotive-ddr3-v11-linux-tb.dts new file mode 100644 index 000000000000..a63903fe2822 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3358m-automotive-ddr3-v11-linux-tb.dts @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2024 Rockchip Electronics Co., Ltd. + * + */ + +/dts-v1/; + +#include "rk3358m-automotive-ddr3-v11-linux.dts" + +/ { + model = "Rockchip RK3358M AUTOMOTIVE DDR3 V11 Linux TB board"; + compatible = "rockchip,rk3358m-automotive-ddr3-v11-linux", "rockchip,px30", "rockchip,rk3358"; + + chosen { + bootargs = "earlycon=uart8250,mmio32,0xff160000 console=ttyFIQ0 skip_initramfs root=/dev/rd0 rootfstype=squashfs init=/sbin/init"; + }; + + /* + * This memory mapping range represents a 512MB memory space + * starting from the physical address 0x00000000 + * where: + * 0x00000000 - base address + * 0x0 - address cells + * 0x0 - size cells + * 0x20000000 - memory size (512MB) + * Note: The actual available memory size depends on the hardware design + * and may differ from the 512MB defined here. + * Adjustment is needed based on the specific hardware memory configuration. + */ + memory: memory { + device_type = "memory"; + reg = <0x00000000 0x0 0x0 0x20000000>; + }; + + ramdisk: ramdisk { + compatible = "rockchip,ramdisk"; + memory-region = <&ramdisk_r>; + }; + + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + atf: atf@0 { + reg = <0x0 0x00000 0x0 0x200000>; + no-map; + }; + + mmc_dma_buf@200000 { + reg = <0x0 0x200000 0x0 0x200000>; + }; + + ramdisk_r: ramdisk_r@4000000 { + /* Do not exceed 132MB which used by TEE */ + reg = <0x0 0x4000000 0x0 0x2000000>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3358m-automotive-ddr3-v11-linux.dts b/arch/arm64/boot/dts/rockchip/rk3358m-automotive-ddr3-v11-linux.dts index 8252455991e3..b9f2110a61df 100644 --- a/arch/arm64/boot/dts/rockchip/rk3358m-automotive-ddr3-v11-linux.dts +++ b/arch/arm64/boot/dts/rockchip/rk3358m-automotive-ddr3-v11-linux.dts @@ -10,51 +10,6 @@ #include "rk3358-linux.dtsi" / { - model = "Rockchip RK3358M AUTOMOTIVE DDR3 V11 board"; + model = "Rockchip RK3358M AUTOMOTIVE DDR3 V11 Linux board"; compatible = "rockchip,rk3358m-automotive-ddr3-v11-linux", "rockchip,px30", "rockchip,rk3358"; - - chosen { - bootargs = "earlycon=uart8250,mmio32,0xff160000 console=ttyFIQ0 skip_initramfs root=/dev/rd0 rootfstype=squashfs init=/sbin/init"; - }; - - /* - * This memory mapping range represents a 512MB memory space - * starting from the physical address 0x00000000 - * where: - * 0x00000000 - base address - * 0x0 - address cells - * 0x0 - size cells - * 0x20000000 - memory size (512MB) - * Note: The actual available memory size depends on the hardware design - * and may differ from the 512MB defined here. - * Adjustment is needed based on the specific hardware memory configuration. - */ - memory: memory { - device_type = "memory"; - reg = <0x00000000 0x0 0x0 0x20000000>; - }; - - ramdisk: ramdisk { - compatible = "rockchip,ramdisk"; - memory-region = <&ramdisk_r>; - }; - - reserved-memory { - #address-cells = <2>; - #size-cells = <2>; - ranges; - atf: atf@0 { - reg = <0x0 0x00000 0x0 0x200000>; - no-map; - }; - - mmc_dma_buf@200000 { - reg = <0x0 0x200000 0x0 0x200000>; - }; - - ramdisk_r: ramdisk_r@4000000 { - /* Do not exceed 132MB which used by TEE */ - reg = <0x0 0x4000000 0x0 0x2000000>; - }; - }; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3358m-automotive-ddr3-v11.dtsi b/arch/arm64/boot/dts/rockchip/rk3358m-automotive-ddr3-v11.dtsi index fba82b6ffe53..770b29bcdce3 100644 --- a/arch/arm64/boot/dts/rockchip/rk3358m-automotive-ddr3-v11.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3358m-automotive-ddr3-v11.dtsi @@ -201,6 +201,8 @@ snps,reset-gpio = <&gpio2 12 GPIO_ACTIVE_LOW>; snps,reset-active-low; snps,reset-delays-us = <0 50000 50000>; + pinctrl-names = "default"; + pinctrl-0 = <&rmii_pins_fixed &mac_refclk_12ma>; status = "okay"; }; @@ -422,6 +424,7 @@ }; vcc1v8_ser: LDO_REG8 { + regulator-always-on; regulator-boot-on; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; @@ -434,6 +437,7 @@ }; vdd1v2_ser: LDO_REG9 { + regulator-always-on; regulator-boot-on; regulator-min-microvolt = <1200000>; regulator-max-microvolt = <1200000>; @@ -553,6 +557,21 @@ }; &pinctrl { + gmac { + rmii_pins_fixed: rmii-pins-fixed { + rockchip,pins = + <2 RK_PA0 2 &pcfg_pull_none_12ma>, /* mac_txen */ + <2 RK_PA1 2 &pcfg_pull_none_12ma>, /* mac_txd1 */ + <2 RK_PA2 2 &pcfg_pull_none_12ma>, /* mac_txd0 */ + <2 RK_PA3 2 &pcfg_pull_none>, /* mac_rxd0 */ + <2 RK_PA4 2 &pcfg_pull_none>, /* mac_rxd1 */ + //<2 RK_PA5 2 &pcfg_pull_none>, /* mac_rxer */ + <2 RK_PA6 2 &pcfg_pull_none>, /* mac_rxdv */ + <2 RK_PA7 2 &pcfg_pull_none>, /* mac_mdio */ + <2 RK_PB1 2 &pcfg_pull_none>; /* mac_mdc */ + }; + }; + lcd { lcd0_pwren: lcd0-pwren { rockchip,pins = <1 RK_PD6 RK_FUNC_GPIO &pcfg_output_high>; From 15974f7d704e8cb75afa7c1cbea1c755dfa8e677 Mon Sep 17 00:00:00 2001 From: Chaoyi Chen Date: Tue, 1 Apr 2025 09:50:49 +0800 Subject: [PATCH 19/57] drm/rockchip: vop: Add version for interlace_read reg for RV1126B Change-Id: Ie3bf300e8e5467a4ce4ceb52bee07bee44e5bdb7 Signed-off-by: Chaoyi Chen --- drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c index b5f1d7652306..2272f3994117 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c @@ -1639,7 +1639,7 @@ static const struct vop_win_phy px30_win23_data = { .csc_mode = VOP_REG(RK3368_WIN2_CTRL0, 0x3, 2), .format = VOP_REG(RK3368_WIN2_CTRL0, 0x3, 5), .rb_swap = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 20), - .interlace_read = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 1), + .interlace_read = VOP_REG_VER(RK3368_WIN2_CTRL0, 0x1, 1, 2, 0xf, -1), .dsp_info = VOP_REG(RK3368_WIN2_DSP_INFO0, 0x0fff0fff, 0), .dsp_st = VOP_REG(RK3368_WIN2_DSP_ST0, 0x1fff1fff, 0), .yrgb_mst = VOP_REG(RK3368_WIN2_MST0, 0xffffffff, 0), From 0286cc5b23dc6638f4ff451ada61a9e635c295be Mon Sep 17 00:00:00 2001 From: Sach Lin Date: Sun, 23 Mar 2025 02:59:04 +0000 Subject: [PATCH 20/57] ARM: configs: rv1126b_defconfig: Enable avsp +CONFIG_VIDEO_ROCKCHIP_AVSP=m Signed-off-by: Sach Lin Change-Id: Id6280d2677c5257ba4ca49b26d165e86422dab89 --- arch/arm/configs/rv1126b_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/configs/rv1126b_defconfig b/arch/arm/configs/rv1126b_defconfig index 18e7a3d5b3c8..396d926f83ed 100644 --- a/arch/arm/configs/rv1126b_defconfig +++ b/arch/arm/configs/rv1126b_defconfig @@ -125,6 +125,7 @@ CONFIG_MEDIA_CAMERA_SUPPORT=y CONFIG_MEDIA_PLATFORM_SUPPORT=y CONFIG_V4L_PLATFORM_DRIVERS=y CONFIG_VIDEO_ROCKCHIP_AIISP=m +CONFIG_VIDEO_ROCKCHIP_AVSP=m CONFIG_VIDEO_ROCKCHIP_CIF=m CONFIG_VIDEO_ROCKCHIP_ISP=m CONFIG_VIDEO_ROCKCHIP_VPSS=m From da87a99cf2d01abe052fde38f8db2955f89ecb10 Mon Sep 17 00:00:00 2001 From: Su Yuefu Date: Tue, 1 Apr 2025 10:59:56 +0800 Subject: [PATCH 21/57] arm64: dts: rockchip: rv1126b-evb3-v10: Add lcd/tp support Signed-off-by: Su Yuefu Change-Id: I60363f769840bceb603c5a8e53c0c4e10fba4849 --- .../boot/dts/rockchip/rv1126b-evb3-v10.dts | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rv1126b-evb3-v10.dts b/arch/arm64/boot/dts/rockchip/rv1126b-evb3-v10.dts index 213ef26dad72..00f83ea47ed6 100644 --- a/arch/arm64/boot/dts/rockchip/rv1126b-evb3-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rv1126b-evb3-v10.dts @@ -95,6 +95,14 @@ vin-supply = <&vcc1v8_pmu>; }; + vcc_mipi: vcc-mipi { + compatible = "regulator-fixed"; + regulator-name = "vcc_mipi"; + gpio = <&gpio7 RK_PA7 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-boot-on; + }; + vcc_1v8: vcc-1v8 { compatible = "regulator-fixed"; regulator-name = "vcc_1v8"; @@ -177,10 +185,30 @@ }; }; +&backlight { + pwms = <&pwm2_8ch_7 0 25000 0>; +}; + &cpu0 { cpu-supply = <&vdd_cpu>; }; +&display_subsystem { + status = "okay"; +}; + +&dsi { + status = "okay"; +}; + +&dsi_in_vop { + status = "okay"; +}; + +&dsi_panel { + power-supply = <&vcc_mipi>; +}; + &fspi0 { status = "okay"; @@ -193,6 +221,26 @@ }; }; +&i2c4 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c4m3_pins>; + + gt1x: gt1x@14 { + compatible = "goodix,gt1x"; + reg = <0x14>; + pinctrl-names = "default"; + pinctrl-0 = <&touch_gpio>; + power-supply = <&vcc_mipi>; + goodix,rst-gpio = <&gpio5 RK_PD6 GPIO_ACTIVE_HIGH>; + goodix,irq-gpio = <&gpio3 RK_PB7 IRQ_TYPE_LEVEL_LOW>; + }; +}; + +&mipi_dphy { + status = "okay"; +}; + &rkaiisp { status = "okay"; }; @@ -209,7 +257,19 @@ rknpu-supply = <&vdd_npu>; }; +&route_dsi { + status = "okay"; +}; + &pinctrl { + touch { + touch_gpio: touch-gpio { + rockchip,pins = + <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>, + <5 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + usb { vcc5v0_host_en: vcc5v0-host-en { rockchip,pins = <7 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; @@ -232,6 +292,10 @@ status = "okay"; }; +&pwm2_8ch_7 { + status = "okay"; +}; + &saradc0 { vref-supply = <&vcc_1v8>; }; From 48498c68b5da4c658d7c363dfbbfb6632ca1d324 Mon Sep 17 00:00:00 2001 From: Algea Cao Date: Fri, 14 Mar 2025 11:24:58 +0800 Subject: [PATCH 22/57] drm/bridge: synopsys: dw-hdmi-qp: Call handle_plugged_change() when hdmi plug Notify linux userspace hdmi has been plugged in or out and audio needs to be reset. Fixes: b84c5d0c819a ("drm/bridge: synopsys: dw-hdmi-qp: Only set extcon status when hdmi plug/unplug") Change-Id: I7e7f3da2849ae4bb70d838281001a4ead2b7c03a Signed-off-by: Algea Cao Signed-off-by: XiaoTan Luo --- drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c index 81c22c3b89be..88e612945a3b 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c @@ -2646,10 +2646,13 @@ dw_hdmi_connector_detect(struct drm_connector *connector, bool force) } out: - if (result == connector_status_connected) + if (result == connector_status_connected) { extcon_set_state_sync(hdmi->extcon, EXTCON_DISP_HDMI, true); - else + handle_plugged_change(hdmi, true); + } else { extcon_set_state_sync(hdmi->extcon, EXTCON_DISP_HDMI, false); + handle_plugged_change(hdmi, false); + } return result; } @@ -3577,7 +3580,6 @@ static void dw_hdmi_qp_bridge_atomic_disable(struct drm_bridge *bridge, dw_hdmi_qp_hdcp_disable(hdmi, conn_state); - handle_plugged_change(hdmi, false); if (hdmi->plat_data->crtc_pre_disable) hdmi->plat_data->crtc_pre_disable(data, bridge->encoder->crtc); mutex_lock(&hdmi->mutex); @@ -3661,8 +3663,6 @@ static void dw_hdmi_qp_bridge_atomic_enable(struct drm_bridge *bridge, dw_hdmi_qp_audio_enable(hdmi); hdmi_clk_regenerator_update_pixel_clock(hdmi); - handle_plugged_change(hdmi, true); - if (hdmi->panel) drm_panel_enable(hdmi->panel); From 84e5716948a034cb9c27c0a0283c18187d65d328 Mon Sep 17 00:00:00 2001 From: Ye Zhang Date: Mon, 31 Mar 2025 16:05:47 +0800 Subject: [PATCH 23/57] clk: rockchip: clk-pvtpll: Add pm suspend/resume support Signed-off-by: Ye Zhang Change-Id: I436c08ef3ad6cf8d245a448cb62a90a613e5330a --- drivers/clk/rockchip/clk-pvtpll.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/clk/rockchip/clk-pvtpll.c b/drivers/clk/rockchip/clk-pvtpll.c index fae8d76d2491..7cee8ddc5bd1 100644 --- a/drivers/clk/rockchip/clk-pvtpll.c +++ b/drivers/clk/rockchip/clk-pvtpll.c @@ -719,9 +719,27 @@ static int rockchip_clock_pvtpll_remove(struct platform_device *pdev) return 0; } +static int rockchip_clock_pvtpll_resume(struct device *dev) +{ + struct rockchip_clock_pvtpll *pvtpll = dev_get_drvdata(dev); + struct pvtpll_table *table; + + table = rockchip_get_pvtpll_settings(pvtpll, pvtpll->cur_rate); + if (!table) + return 0; + + pvtpll->info->config(pvtpll, table); + + return 0; +} + +static DEFINE_SIMPLE_DEV_PM_OPS(rockchip_clock_pvtpll_pm_ops, NULL, + rockchip_clock_pvtpll_resume); + static struct platform_driver rockchip_clock_pvtpll_driver = { .driver = { .name = "rockchip-clcok-pvtpll", + .pm = pm_sleep_ptr(&rockchip_clock_pvtpll_pm_ops), .of_match_table = rockchip_clock_pvtpll_match, }, .probe = rockchip_clock_pvtpll_probe, From 548b6415771a0feeb0ba3a2e2f837e540871d6ae Mon Sep 17 00:00:00 2001 From: Sandy Huang Date: Thu, 27 Mar 2025 20:10:03 +0800 Subject: [PATCH 24/57] drm/rockchip: vop2: adjust bt1886 eotf for sdr2hdr for rk3568/rk3588 (1) sdr2hdr_tf use software config instead of hardware init; (2) sdr2hdr_bt1886eotf dst range use 500 nit; (3) sdr2hdr_bt1886eotf y0-y43 must multiply by 2 due to some special IC designs. Signed-off-by: Sandy Huang Change-Id: I58afff82c49f6ebbedad350bccc383e9fad11c2f --- drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 17 +++++++--- drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 34 ++++++++++---------- 2 files changed, 29 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index f74775464357..3fd603febdf3 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -1549,20 +1549,27 @@ static void vop2_load_sdr2hdr_table(struct vop2_video_port *vp, int sdr2hdr_tf) const struct vop2_video_port_regs *regs = vp->regs; uint32_t sdr2hdr_eotf_oetf_yn[65]; uint32_t sdr2hdr_oetf_dx_dxpow[64]; - int i; + int i, bt1886_eotf_coe = 1; for (i = 0; i < 65; i++) { + /* + * rk3568/rk3588 sdr2hdr bt1886 eotf dx << 1 by mistake, so add + * bt1886_eotf_coe to adapt it. + */ + if (i == 64) + bt1886_eotf_coe = 0; + if (sdr2hdr_tf == SDR2HDR_FOR_BT2020) sdr2hdr_eotf_oetf_yn[i] = - table->sdr2hdr_bt1886eotf_yn_for_bt2020[i] + + (table->sdr2hdr_bt1886eotf_yn_for_bt2020[i] << bt1886_eotf_coe) + (table->sdr2hdr_st2084oetf_yn_for_bt2020[i] << 18); else if (sdr2hdr_tf == SDR2HDR_FOR_HDR) sdr2hdr_eotf_oetf_yn[i] = - table->sdr2hdr_bt1886eotf_yn_for_hdr[i] + + (table->sdr2hdr_bt1886eotf_yn_for_hdr[i] << bt1886_eotf_coe) + (table->sdr2hdr_st2084oetf_yn_for_hdr[i] << 18); else if (sdr2hdr_tf == SDR2HDR_FOR_HLG_HDR) sdr2hdr_eotf_oetf_yn[i] = - table->sdr2hdr_bt1886eotf_yn_for_hlg_hdr[i] + + (table->sdr2hdr_bt1886eotf_yn_for_hlg_hdr[i] << bt1886_eotf_coe) + (table->sdr2hdr_st2084oetf_yn_for_hlg_hdr[i] << 18); } @@ -11070,7 +11077,7 @@ static void vop2_setup_hdr10(struct vop2_video_port *vp, uint8_t win_phys_id) bool sdr2hdr_en = 0; bool sdr2hdr_tf = 0; bool hdr2sdr_tf_update = 1; - bool sdr2hdr_tf_update = 0; /* default sdr2hdr curve is 1000 nit */ + bool sdr2hdr_tf_update = 1; unsigned long win_mask = vp->win_mask; int phys_id; bool have_sdr_layer = false; diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c index 1651d719852c..2c4957ad8100 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c @@ -415,24 +415,24 @@ static const u32 sdr2hdr_bt1886eotf_yn_for_bt2020[65] = { }; static u32 sdr2hdr_bt1886eotf_yn_for_hdr[65] = { - /* dst_range 425int */ + /* dst_range 500 nit */ 0, - 5, 21, 49, 91, - 150, 225, 320, 434, - 569, 726, 905, 1108, - 1336, 1588, 1866, 2171, - 2502, 2862, 3250, 3667, - 3887, 4114, 4349, 4591, - 4841, 5099, 5364, 5638, - 5920, 6209, 6507, 6812, - 6968, 7126, 7287, 7449, - 7613, 7779, 7948, 8118, - 8291, 8466, 8643, 8822, - 9003, 9187, 9372, 9560, - 9655, 9750, 9846, 9942, - 10039, 10136, 10234, 10333, - 10432, 10531, 10631, 10732, - 10833, 10935, 11038, 11141, + 6, 29, 72, 135, + 221, 330, 463, 621, + 804, 1014, 1251, 1515, + 1807, 2126, 2475, 2853, + 3260, 3696, 4163, 4661, + 4921, 5189, 5464, 5748, + 6039, 6338, 6646, 6961, + 7284, 7615, 7954, 8301, + 8477, 8656, 8837, 9019, + 9204, 9391, 9580, 9771, + 9964, 10159, 10356, 10555, + 10756, 10959, 11165, 11372, + 11477, 11582, 11687, 11793, + 11900, 12007, 12115, 12223, + 12332, 12441, 12551, 12661, + 12772, 12883, 12995, 13107, }; static const u32 sdr2hdr_st2084oetf_yn_for_hlg_hdr[65] = { From e4496649f8250e63edc768d01cb43db679eb00af Mon Sep 17 00:00:00 2001 From: Su Yuefu Date: Tue, 1 Apr 2025 14:18:07 +0800 Subject: [PATCH 25/57] arm64: dts: rockchip: rv1126b-evb3-v10: fix npu regulator name error Signed-off-by: Su Yuefu Change-Id: I85fa6c13e0666f24d3200b34a3de7c0e59bea3be --- arch/arm64/boot/dts/rockchip/rv1126b-evb3-v10.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/rockchip/rv1126b-evb3-v10.dts b/arch/arm64/boot/dts/rockchip/rv1126b-evb3-v10.dts index 00f83ea47ed6..1c9833b607ef 100644 --- a/arch/arm64/boot/dts/rockchip/rv1126b-evb3-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rv1126b-evb3-v10.dts @@ -174,7 +174,7 @@ vdd_npu: vdd-npu { compatible = "pwm-regulator"; pwms = <&pwm1_4ch_1 0 25000 1>; - regulator-name = "vdd_cpu"; + regulator-name = "vdd_npu"; regulator-init-microvolt = <950000>; regulator-min-microvolt = <750000>; regulator-max-microvolt = <1100000>; From ff9c0474eca2155d9af36f67c40cddcc93ed2127 Mon Sep 17 00:00:00 2001 From: Su Yuefu Date: Tue, 1 Apr 2025 13:19:39 +0800 Subject: [PATCH 26/57] arm64: dts: rockchip: rv1126b-evb-cam-csi0: fix csi_dphy_input5 reg Signed-off-by: Su Yuefu Change-Id: I47cecaa1d6d2e800a30ef5bc42ddc9af27ac8e35 --- arch/arm64/boot/dts/rockchip/rv1126b-evb-cam-csi0.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/rockchip/rv1126b-evb-cam-csi0.dtsi b/arch/arm64/boot/dts/rockchip/rv1126b-evb-cam-csi0.dtsi index 2e4cd0299fdd..d706786b18f6 100644 --- a/arch/arm64/boot/dts/rockchip/rv1126b-evb-cam-csi0.dtsi +++ b/arch/arm64/boot/dts/rockchip/rv1126b-evb-cam-csi0.dtsi @@ -46,7 +46,7 @@ }; csi_dphy_input5: endpoint@6 { - reg = <5>; + reg = <6>; remote-endpoint = <&gc8613_out>; data-lanes = <1 2 3 4>; }; From b61ce5dfbb15892d9f8ed0c8efec855c97e72fd5 Mon Sep 17 00:00:00 2001 From: XiaoDong Huang Date: Mon, 31 Mar 2025 18:09:56 +0800 Subject: [PATCH 27/57] ARM: configs: rockchip: Add rv1126b-pm.config Signed-off-by: XiaoDong Huang Change-Id: Ia6ff37cb886fe8c1c50c167b6c91e2ac2d060810 --- arch/arm/configs/rv1126b-pm.config | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 arch/arm/configs/rv1126b-pm.config diff --git a/arch/arm/configs/rv1126b-pm.config b/arch/arm/configs/rv1126b-pm.config new file mode 100644 index 000000000000..ae75f6d56bed --- /dev/null +++ b/arch/arm/configs/rv1126b-pm.config @@ -0,0 +1,6 @@ +CONFIG_PM_DEBUG=y +CONFIG_PM_SLEEP=y +CONFIG_PM_SLEEP_DEBUG=y +CONFIG_PM_WAKELOCKS=y +CONFIG_SUSPEND=y +CONFIG_ROCKCHIP_SUSPEND_MODE=y From 7d6827ff3baa402fc0f4ee2438710a967e67d175 Mon Sep 17 00:00:00 2001 From: XiaoDong Huang Date: Mon, 31 Mar 2025 18:24:18 +0800 Subject: [PATCH 28/57] ARM: configs: rockchip: Add rv1126b-wakeup.config Signed-off-by: XiaoDong Huang Change-Id: I4e18ecc885b126def419d430d22edc9e2b583dae --- arch/arm/configs/rv1126b-wakeup.config | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 arch/arm/configs/rv1126b-wakeup.config diff --git a/arch/arm/configs/rv1126b-wakeup.config b/arch/arm/configs/rv1126b-wakeup.config new file mode 100644 index 000000000000..bcb2874830e8 --- /dev/null +++ b/arch/arm/configs/rv1126b-wakeup.config @@ -0,0 +1,5 @@ +CONFIG_INPUT=y +CONFIG_INPUT_EVDEV=y +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_GPIO=y +CONFIG_SND_JACK_INPUT_DEV=y From 12d2a304c69b81c16aebdbe9133e24b4c002a311 Mon Sep 17 00:00:00 2001 From: XiaoDong Huang Date: Mon, 31 Mar 2025 18:07:54 +0800 Subject: [PATCH 29/57] dt-bindings: suspend: add rv1126b pm related macros Signed-off-by: XiaoDong Huang Change-Id: I9398c62976fe7c17ef74bcc7d44caea110106653 --- .../dt-bindings/suspend/rockchip-rv1126b.h | 114 ++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 include/dt-bindings/suspend/rockchip-rv1126b.h diff --git a/include/dt-bindings/suspend/rockchip-rv1126b.h b/include/dt-bindings/suspend/rockchip-rv1126b.h new file mode 100644 index 000000000000..013e1317eda8 --- /dev/null +++ b/include/dt-bindings/suspend/rockchip-rv1126b.h @@ -0,0 +1,114 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Copyright (c) 2025 Rockchip Electronics Co., Ltd. + */ + +#ifndef __DT_BINDINGS_RV1126B_PM_H__ +#define __DT_BINDINGS_RV1126B_PM_H__ +/******************************bits ops************************************/ + +#ifndef BIT +#define BIT(nr) (1 << (nr)) +#endif + +#define RKPM_SLP_ARMPD BIT(0) +#define RKPM_SLP_ARMOFF BIT(1) +#define RKPM_SLP_ARMOFF_DDRPD BIT(2) +#define RKPM_SLP_ARMOFF_LOGOFF BIT(3) +#define RKPM_SLP_ARMOFF_PMUOFF BIT(4) + +#define RKPM_SLP_PMU_HW_PLLS_PD BIT(8) +#define RKPM_SLP_PMU_PMUALIVE_32K BIT(9) +#define RKPM_SLP_PMU_DIS_OSC BIT(10) + +#define RKPM_SLP_CLK_GT BIT(16) +#define RKPM_SLP_PMIC_LP BIT(17) + +#define RKPM_SLP_32K_EXT BIT(24) +#define RKPM_SLP_TIME_OUT_WKUP BIT(25) +#define RKPM_SLP_PMU_DBG BIT(26) +#define RKPM_SLP_LP_PR BIT(27) +#define RKPM_SLP_ARCH_TIMER_RESET BIT(28) + +/* the wake up source */ +#define RKPM_CPU0_WKUP_EN BIT(0) +#define RKPM_CPU1_WKUP_EN BIT(1) +#define RKPM_CPU2_WKUP_EN BIT(2) +#define RKPM_CPU3_WKUP_EN BIT(3) +#define RKPM_GPIO0_WKUP_EN BIT(4) +#define RKPM_SDMMC0_WKUP_EN BIT(5) +#define RKPM_SDMMC1_WKUP_EN BIT(6) +#define RKPM_SDIO_WKUP_EN BIT(7) +#define RKPM_USB_WKUP_EN BIT(8) +#define RKPM_UART0_WKUP_EN BIT(9) +#define RKPM_I2C2_WKUP_EN BIT(10) +#define RKPM_PWM1_WKUP_EN BIT(11) +#define RKPM_TIMER_WKUP_EN BIT(12) +#define RKPM_HPTIMER_WKUP_EN BIT(13) +#define RKPM_SYSINT_WKUP_EN BIT(14) +#define RKPM_AOV_WKUP_EN BIT(15) +#define RKPM_AAD_WKUP_EN BIT(16) +#define RKPM_TIMEOUT_WKUP_EN BIT(17) + +/* sleep pin */ +#define RKPM_SLEEP_PIN0_EN BIT(0) /* GPIO0_A3 */ +#define RKPM_SLEEP_PIN1_EN BIT(1) /* GPIO0_A4 */ +#define RKPM_SLEEP_PIN2_EN BIT(2) /* GPIO0_C1 */ + +#define RKPM_SLEEP_PIN0_ACT_LOW BIT(0) /* GPIO0_A3 */ +#define RKPM_SLEEP_PIN1_ACT_LOW BIT(1) /* GPIO0_A4 */ +#define RKPM_SLEEP_PIN2_ACT_LOW BIT(2) /* GPIO0_C1 */ + +/* io config */ +#define RKPM_IO_CFG_IOMUX_SFT 0 +#define RKPM_IO_CFG_GPIO_DIR_SFT 8 +#define RKPM_IO_CFG_GPIO_LVL_SFT 9 +#define RKPM_IO_CFG_PULL_SFT 10 +#define RKPM_IO_CFG_ID_SFT 16 + +#define RKPM_IO_CFG_IOMUX_MSK 0x3f +#define RKPM_IO_CFG_GPIO_DIR_MSK 0x1 +#define RKPM_IO_CFG_GPIO_LVL_MSK 0x1 +#define RKPM_IO_CFG_PULL_MSK 0x3 +#define RKPM_IO_CFG_ID_MSK 0xffff + +#define RKPM_IO_CFG_IOMUX_GPIO_VAL 0 +#define RKPM_IO_CFG_GPIO_DIR_INPUT_VAL 0 +#define RKPM_IO_CFG_GPIO_DIR_OUTPUT_VAL 1 +#define RKPM_IO_CFG_GPIO_LVL_LOW_VAL 0 +#define RKPM_IO_CFG_GPIO_LVL_HIGH_VAL 1 +#define RKPM_IO_CFG_PULL_NONE_VAL 0 +#define RKPM_IO_CFG_PULL_UP_VAL 1 +#define RKPM_IO_CFG_PULL_DOWN_VAL 2 + +#define RKPM_IO_CFG_IOMUX(func) ((func) << RKPM_IO_CFG_IOMUX_SFT) +#define RKPM_IO_CFG_GPIO_DIR_INPUT \ + (RKPM_IO_CFG_GPIO_DIR_INPUT_VAL << RKPM_IO_CFG_GPIO_DIR_SFT) +#define RKPM_IO_CFG_GPIO_DIR_OUTPUT \ + (RKPM_IO_CFG_GPIO_DIR_OUTPUT_VAL << RKPM_IO_CFG_GPIO_DIR_SFT) +#define RKPM_IO_CFG_GPIO_LVL_LOW \ + (RKPM_IO_CFG_GPIO_LVL_LOW_VAL << RKPM_IO_CFG_GPIO_LVL_SFT) +#define RKPM_IO_CFG_GPIO_LVL_HIGH \ + (RKPM_IO_CFG_GPIO_LVL_HIGH_VAL << RKPM_IO_CFG_GPIO_LVL_SFT) +#define RKPM_IO_CFG_PULL_NONE \ + (RKPM_IO_CFG_PULL_NONE_VAL << RKPM_IO_CFG_PULL_SFT) +#define RKPM_IO_CFG_PULL_UP \ + (RKPM_IO_CFG_PULL_UP_VAL << RKPM_IO_CFG_PULL_SFT) +#define RKPM_IO_CFG_PULL_DOWN \ + (RKPM_IO_CFG_PULL_DOWN_VAL << RKPM_IO_CFG_PULL_SFT) +#define RKPM_IO_CFG_ID(id) ((id) << RKPM_IO_CFG_ID_SFT) +#define RKPM_IO_CFG_IOMUX_GPIO \ + RKPM_IO_CFG_IOMUX(RKPM_IO_CFG_IOMUX_GPIO_VAL) + +#define RKPM_IO_CFG_GET_IOMUX(cfg) \ + (((cfg) >> RKPM_IO_CFG_IOMUX_SFT) & RKPM_IO_CFG_IOMUX_MSK) +#define RKPM_IO_CFG_GET_GPIO_DIR(cfg) \ + (((cfg) >> RKPM_IO_CFG_GPIO_DIR_SFT) & RKPM_IO_CFG_GPIO_DIR_MSK) +#define RKPM_IO_CFG_GET_GPIO_LVL(cfg) \ + (((cfg) >> RKPM_IO_CFG_GPIO_LVL_SFT) & RKPM_IO_CFG_GPIO_LVL_MSK) +#define RKPM_IO_CFG_GET_PULL(cfg) \ + (((cfg) >> RKPM_IO_CFG_PULL_SFT) & RKPM_IO_CFG_PULL_MSK) +#define RKPM_IO_CFG_GET_ID(cfg) \ + (((cfg) >> RKPM_IO_CFG_ID_SFT) & RKPM_IO_CFG_ID_MSK) + +#endif From b4606fb76f20130c2eeab2d41ad6a0cdfdcdfa37 Mon Sep 17 00:00:00 2001 From: XiaoDong Huang Date: Mon, 31 Mar 2025 18:11:10 +0800 Subject: [PATCH 30/57] arm64: dts: rockchip: rv1126b: add rockchip_suspend node Signed-off-by: XiaoDong Huang Change-Id: Ie48cf27fec8a2543aa1dd24c96ba8aaed2de4012 --- arch/arm64/boot/dts/rockchip/rv1126b.dtsi | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rv1126b.dtsi b/arch/arm64/boot/dts/rockchip/rv1126b.dtsi index 4b189c269450..218ad1a3e479 100644 --- a/arch/arm64/boot/dts/rockchip/rv1126b.dtsi +++ b/arch/arm64/boot/dts/rockchip/rv1126b.dtsi @@ -12,6 +12,7 @@ #include #include #include +#include / { compatible = "rockchip,rv1126b"; @@ -749,6 +750,25 @@ }; }; + rockchip_suspend: rockchip-suspend { + compatible = "rockchip,pm-config"; + status = "disabled"; + + rockchip,sleep-mode-config = < + (0 + | RKPM_SLP_ARMOFF_PMUOFF + | RKPM_SLP_PMU_PMUALIVE_32K + | RKPM_SLP_PMU_DIS_OSC + | RKPM_SLP_32K_EXT + ) + >; + rockchip,wakeup-config = < + (0 + | RKPM_GPIO0_WKUP_EN + ) + >; + }; + rockchip_system_monitor: rockchip-system-monitor { compatible = "rockchip,system-monitor"; }; From 347c68f5302127ac18cb290fead834796bf13978 Mon Sep 17 00:00:00 2001 From: XiaoDong Huang Date: Mon, 31 Mar 2025 18:12:54 +0800 Subject: [PATCH 31/57] arm64: dts: rockchip: rv1126b-evb2-v10: add node for system suspend Signed-off-by: XiaoDong Huang Change-Id: I40eab5d87e28d032b6a02e05a1907e1871a79b97 --- .../boot/dts/rockchip/rv1126b-evb2-v10.dts | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rv1126b-evb2-v10.dts b/arch/arm64/boot/dts/rockchip/rv1126b-evb2-v10.dts index 773e1a0e945e..017d63c53917 100644 --- a/arch/arm64/boot/dts/rockchip/rv1126b-evb2-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rv1126b-evb2-v10.dts @@ -12,6 +12,21 @@ model = "Rockchip RV1126B EVB2 V10 Board"; compatible = "rockchip,rv1126b-evb2-v10", "rockchip,rv1126b"; + gpio-keys { + compatible = "gpio-keys"; + autorepeat; + pinctrl-names = "default"; + pinctrl-0 = <&pwr_key>; + power-key { + gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; + linux,code = ; + label ="GPIO Key Power"; + debounce-interval = <100>; + wakeup-source; + /* gpio-key,wakeup; */ + }; + }; + vcc5v0_dcin: vcc5v0-dcin { compatible = "regulator-fixed"; regulator-name = "vcc5v0_dcin"; @@ -296,6 +311,12 @@ }; &pinctrl { + buttons { + pwr_key: pwr-key { + rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + sdmmc { /omit-if-no-ref/ sdmmc_volt: sdmmc-volt { @@ -350,10 +371,19 @@ rknpu-supply = <&vdd_npu>; }; +&rockchip_suspend { + status = "okay"; +}; + &route_dsi { status = "okay"; }; +&rtc { + rockchip,rtc-suspend-bypass; + status = "okay"; +}; + &sai2 { rockchip,sai-rx-route = <1 0 2 3>; status = "okay"; From 627a0334478517cee543dab0f26ba844e23086f9 Mon Sep 17 00:00:00 2001 From: Cai YiWei Date: Tue, 1 Apr 2025 14:32:58 +0800 Subject: [PATCH 32/57] media: rockchip: isp: fix isp35 b3dldc Change-Id: Icae67f569a3b3c3782ddb4562d538f9e63655de1 Signed-off-by: Cai YiWei --- .../platform/rockchip/isp/isp_params_v35.c | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/drivers/media/platform/rockchip/isp/isp_params_v35.c b/drivers/media/platform/rockchip/isp/isp_params_v35.c index 9995a76f3df1..7cb381ded56c 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v35.c +++ b/drivers/media/platform/rockchip/isp/isp_params_v35.c @@ -4033,12 +4033,13 @@ isp_bay3d_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) { struct rkisp_isp_params_val_v35 *priv = params_vdev->priv_val; struct rkisp_device *dev = params_vdev->dev; - u32 value, ctrl; + u32 value, ctrl, b3dldc_ctrl; ctrl = isp3_param_read_cache(params_vdev, ISP33_BAY3D_CTRL0, id); if (en == !!(ctrl & ISP35_MODULE_EN)) return; + b3dldc_ctrl = isp3_param_read_cache(params_vdev, ISP35_B3DLDC_CTRL, id); if (en) { if (!priv->buf_bay3d_iir[0].mem_priv || !priv->buf_bay3d_ds[0].mem_priv || @@ -4055,6 +4056,10 @@ isp_bay3d_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_IIR_RD_BASE, id); if (priv->bay3d_iir_rw_fmt == 3) { isp3_param_write(params_vdev, value, ISP35_B3DLDC_WR_ADDR, id); + if (b3dldc_ctrl & ISP35_B3DLDC_EN) { + b3dldc_ctrl |= ISP35_B3DLDC_FORCE_UPD; + isp3_param_write(params_vdev, b3dldc_ctrl, ISP35_B3DLDC_CTRL, id); + } value += priv->bay3d_iir_offs; } isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_IIR_WR_BASE, id); @@ -4115,6 +4120,12 @@ isp_bay3d_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) } else { ctrl &= ~(ISP35_MODULE_EN | ISP35_SELF_FORCE_UPD); isp3_param_write(params_vdev, ctrl, ISP33_BAY3D_CTRL0, id); + if (b3dldc_ctrl & ISP35_B3DLDC_EN) { + b3dldc_ctrl &= ~(ISP35_B3DLDC_FORCE_UPD | ISP35_B3DLDC_EN); + isp3_param_write(params_vdev, b3dldc_ctrl, ISP35_B3DLDC_CTRL, id); + + isp3_param_clear_bits(params_vdev, ISP35_B3DLDC_ADR_STS, ISP35_B3DLDC_EN, id); + } } } @@ -4914,14 +4925,14 @@ static int rkisp_init_mesh_buf(struct rkisp_isp_params_vdev *params_vdev, priv->buf_b3dldc_idx[id] = 0; buf = priv->buf_b3dldc[id]; /* b3d_ldch */ - mesh_w = ALIGN((ALIGN(mesh_w, 16) / 16 + 1) / 2, 2); + mesh_w = DIV_ROUND_UP(ALIGN(mesh_w, 16) / 16 + 1, 2); mesh_h = ALIGN(mesh_h, 8) / 8 + 1; - mesh_size = ALIGN(mesh_w * mesh_h, 16); + mesh_size = ALIGN(mesh_w * 4 * mesh_h, 16); priv->b3dldc_hsize = mesh_w; priv->b3dldch_vsize = mesh_h; /* b3d_ldcv */ mesh_h = ALIGN(meshsize->meas_height, 16) / 16 + 2; - mesh_size += (mesh_w * mesh_h); + mesh_size += (mesh_w * 4 * mesh_h); priv->b3dldcv_vsize = mesh_h; break; default: @@ -4957,7 +4968,7 @@ static int rkisp_init_mesh_buf(struct rkisp_isp_params_vdev *params_vdev, mesh_head->stat = MESH_BUF_INIT; mesh_head->data_oft = ALIGN(sizeof(struct isp2x_mesh_head), 16); mesh_head->data1_oft = mesh_head->data_oft + - ALIGN(priv->b3dldc_hsize * priv->b3dldch_vsize, 16); + ALIGN(priv->b3dldc_hsize * 4 * priv->b3dldch_vsize, 16); } buf++; } @@ -4992,6 +5003,10 @@ rkisp_params_get_meshbuf_inf_v35(struct rkisp_isp_params_vdev *params_vdev, priv->buf_ldch_idx[id] = 0; buf = priv->buf_ldch[id]; break; + case ISP35_MODULE_BAY3D: + priv->buf_b3dldc_idx[id] = 0; + buf = priv->buf_b3dldc[id]; + break; default: return; } From b63f278551eacdef139d32009513c42ffb729d8d Mon Sep 17 00:00:00 2001 From: Xing Zheng Date: Tue, 4 Mar 2025 21:37:08 +0800 Subject: [PATCH 33/57] ASoC: codecs: rk730: split VDW TX/RX for capture/playback And fix missing 0x1f for 32bit for VDW_T(R)X. Signed-off-by: Xing Zheng Change-Id: I885a2b289bd37461567cedf284f7326bfb3929c8 --- sound/soc/codecs/rk730.c | 60 ++++++++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 20 deletions(-) diff --git a/sound/soc/codecs/rk730.c b/sound/soc/codecs/rk730.c index a3a8f2a29e96..f21d15bb680c 100644 --- a/sound/soc/codecs/rk730.c +++ b/sound/soc/codecs/rk730.c @@ -792,26 +792,46 @@ static int rk730_dai_hw_params(struct snd_pcm_substream *substream, dev_info(component->dev, "%s:index %d mclk=%d rate=%d\n", __func__, coeff, coeff_div[coeff].mclk, coeff_div[coeff].rate); - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: - snd_soc_component_update_bits(component, RK730_DI2S_RXCR2, - RK730_DI2S_RXCR2_VDW_MASK, - RK730_DI2S_RXCR2_VDW(16)); - snd_soc_component_update_bits(component, RK730_DI2S_TXCR2, - RK730_DI2S_TXCR2_VDW_MASK, - RK730_DI2S_TXCR2_VDW(16)); - break; - case SNDRV_PCM_FORMAT_S24_LE: - case SNDRV_PCM_FORMAT_S32_LE: - snd_soc_component_update_bits(component, RK730_DI2S_RXCR2, - RK730_DI2S_RXCR2_VDW_MASK, - RK730_DI2S_RXCR2_VDW(24)); - snd_soc_component_update_bits(component, RK730_DI2S_TXCR2, - RK730_DI2S_TXCR2_VDW_MASK, - RK730_DI2S_TXCR2_VDW(24)); - break; - default: - return -EINVAL; + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + snd_soc_component_update_bits(component, RK730_DI2S_RXCR2, + RK730_DI2S_RXCR2_VDW_MASK, + RK730_DI2S_RXCR2_VDW(16)); + break; + case SNDRV_PCM_FORMAT_S24_LE: + snd_soc_component_update_bits(component, RK730_DI2S_RXCR2, + RK730_DI2S_RXCR2_VDW_MASK, + RK730_DI2S_RXCR2_VDW(24)); + break; + case SNDRV_PCM_FORMAT_S32_LE: + snd_soc_component_update_bits(component, RK730_DI2S_RXCR2, + RK730_DI2S_RXCR2_VDW_MASK, + RK730_DI2S_RXCR2_VDW(32)); + break; + default: + return -EINVAL; + } + } else { + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + snd_soc_component_update_bits(component, RK730_DI2S_TXCR2, + RK730_DI2S_TXCR2_VDW_MASK, + RK730_DI2S_TXCR2_VDW(16)); + break; + case SNDRV_PCM_FORMAT_S24_LE: + snd_soc_component_update_bits(component, RK730_DI2S_TXCR2, + RK730_DI2S_TXCR2_VDW_MASK, + RK730_DI2S_TXCR2_VDW(24)); + break; + case SNDRV_PCM_FORMAT_S32_LE: + snd_soc_component_update_bits(component, RK730_DI2S_TXCR2, + RK730_DI2S_TXCR2_VDW_MASK, + RK730_DI2S_TXCR2_VDW(32)); + break; + default: + return -EINVAL; + } } rate = samplerate_to_bit(params_rate(params)); From 2fe8584c3f11f14c6234e19f612ecffe79fa97e8 Mon Sep 17 00:00:00 2001 From: Xing Zheng Date: Mon, 31 Mar 2025 10:39:19 +0800 Subject: [PATCH 34/57] ASoC: codecs: rk730: add support control "ADC SDO SEL TX" for capturing route The 'ADCL ADCR DACL DACR' need to use 2ch/32bit format, for example: arecord -Dhw:0,0 -c 2 -r 48000 -fs32_le -t raw /tmp/record_2ch32bit.pcm Signed-off-by: Xing Zheng Change-Id: I93cba43c4e18eee4d82819c6036667d0a427f0e5 --- sound/soc/codecs/rk730.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sound/soc/codecs/rk730.c b/sound/soc/codecs/rk730.c index f21d15bb680c..a1423bd196b9 100644 --- a/sound/soc/codecs/rk730.c +++ b/sound/soc/codecs/rk730.c @@ -143,6 +143,14 @@ static const struct snd_kcontrol_new rk730_out2_switch = static SOC_ENUM_SINGLE_DECL(ana_ldo_volt_enum, RK730_LDO, 4, ana_ldo_volt_text); +static const char * const adc_sdo_sel_tx_text[] = { + "ADCL ADCR", "ADCL ADCR DACL DACR", "ADCL DACL", "ADCL DACR", + "ADCR DACL", "ADCR DACR", "DACL DACR", +}; + +static SOC_ENUM_SINGLE_DECL(adc_sdo_sel_tx_enum, RK730_DI2S_TXCR2, + 5, adc_sdo_sel_tx_text); + static int rk730_pll_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -477,6 +485,7 @@ static const struct snd_kcontrol_new rk730_snd_controls[] = { SOC_ENUM("Mic Bias Volt", micbias_volt_enum), SOC_ENUM("DAC HPF Center Freq", dac_hfp_center_freq_enum), SOC_ENUM("ADC CAPACITY TRIM", adc_capacity_trim_enum), + SOC_ENUM("ADC SDO SEL TX", adc_sdo_sel_tx_enum), SOC_SINGLE("ADC Volume Bypass Switch", RK730_DTOP_VUCTL, 7, 1, 0), SOC_SINGLE("DAC Volume Bypass Switch", RK730_DTOP_VUCTL, 6, 1, 0), SOC_SINGLE("ADC Fade Switch", RK730_DTOP_VUCTL, 5, 1, 0), From 50b60d3d4cbe4f2b518a024de4838ee3da510a53 Mon Sep 17 00:00:00 2001 From: Elaine Zhang Date: Tue, 25 Mar 2025 10:14:36 +0800 Subject: [PATCH 35/57] clk: rockchip: rv1126b: export secure clks Change-Id: I79fddf648f49b3c46103c7717661a479ddf7bc49 Signed-off-by: Elaine Zhang --- drivers/clk/rockchip/clk-rv1126b.c | 12 ++++++---- .../dt-bindings/clock/rockchip,rv1126b-cru.h | 22 +++++++++++++++++-- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/drivers/clk/rockchip/clk-rv1126b.c b/drivers/clk/rockchip/clk-rv1126b.c index 03c42a11db5e..ea567a8d856f 100644 --- a/drivers/clk/rockchip/clk-rv1126b.c +++ b/drivers/clk/rockchip/clk-rv1126b.c @@ -421,7 +421,7 @@ static struct rockchip_clk_branch rv1126b_clk_branches[] __initdata = { COMPOSITE_NODIV(TCLK_WDT_NS_SRC, "tclk_wdt_ns_src", mux_100m_24m_p, 0, RV1126B_CLKSEL_CON(46), 12, 1, MFLAGS, RV1126B_CLKGATE_CON(8), 0, GFLAGS), - COMPOSITE_NODIV(TCLK_WDT_S, "tclk_wdt_s", mux_100m_24m_p, 0, + COMPOSITE_NODIV(TCLK_WDT_S_SRC, "tclk_wdt_s_src", mux_100m_24m_p, 0, RV1126B_CLKSEL_CON(46), 13, 1, MFLAGS, RV1126B_CLKGATE_CON(8), 1, GFLAGS), COMPOSITE_NODIV(TCLK_WDT_HPMCU, "tclk_wdt_hpmcu", mux_100m_24m_p, 0, @@ -459,10 +459,10 @@ static struct rockchip_clk_branch rv1126b_clk_branches[] __initdata = { COMPOSITE_NODIV(CLK_PWM3, "clk_pwm3", mux_100m_24m_p, 0, RV1126B_CLKSEL_CON(50), 11, 1, MFLAGS, RV1126B_CLKGATE_CON(9), 3, GFLAGS), - COMPOSITE_NODIV(CLK_PKA_RKCE_SRC, "clk_pka_rkce_src", mux_300m_200m_p, 0, + COMPOSITE_NODIV(CLK_PKA_RKCE_SRC, "clk_pka_rkce_src", mux_300m_200m_p, CLK_IS_CRITICAL, RV1126B_CLKSEL_CON(50), 12, 1, MFLAGS, RV1126B_CLKGATE_CON(9), 4, GFLAGS), - COMPOSITE_NODIV(ACLK_RKCE_SRC, "aclk_rkce_src", mux_200m_24m_p, 0, + COMPOSITE_NODIV(ACLK_RKCE_SRC, "aclk_rkce_src", mux_200m_24m_p, CLK_IS_CRITICAL, RV1126B_CLKSEL_CON(50), 13, 1, MFLAGS, RV1126B_CLKGATE_CON(9), 5, GFLAGS), COMPOSITE_NODIV(ACLK_VCP_ROOT, "aclk_vcp_root", mux_500m_400m_200m_p, CLK_IS_CRITICAL, @@ -865,6 +865,10 @@ static struct rockchip_clk_branch rv1126b_clk_branches[] __initdata = { COMPOSITE_NODIV(CLK_TIMER4, "clk_timer4", clk_timer4_parents_p, 0, RV1126B_BUSCLKSEL_CON(2), 8, 2, MFLAGS, RV1126B_BUSCLKGATE_CON(2), 10, GFLAGS), + GATE(HCLK_RKRNG_NS, "hclk_rkrng_ns", "hclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(2), 15, GFLAGS), + GATE(HCLK_RKRNG_S_NS, "hclk_rkrng_s_ns", "hclk_bus_root", 0, + RV1126B_BUSCLKGATE_CON(2), 14, GFLAGS), GATE(CLK_TIMER5, "clk_timer5", "clk_timer_root", 0, RV1126B_BUSCLKGATE_CON(2), 11, GFLAGS), GATE(PCLK_I2C0, "pclk_i2c0", "pclk_bus_root", 0, @@ -948,7 +952,7 @@ static struct rockchip_clk_branch rv1126b_clk_branches[] __initdata = { GATE(MCLK_AUDIO_ADC_BUS, "mclk_audio_adc_bus", "mclk_sai2", 0, RV1126B_BUSCLKGATE_CON(5), 14, GFLAGS), FACTOR(MCLK_AUDIO_ADC_DIV4_BUS, "mclk_audio_adc_div4_bus", "mclk_audio_adc_bus", 0, 1, 4), - GATE(PCLK_RKCE, "pclk_rkce", "pclk_bus_root", 0, + GATE(PCLK_RKCE, "pclk_rkce", "pclk_bus_root", CLK_IS_CRITICAL, RV1126B_BUSCLKGATE_CON(6), 0, GFLAGS), GATE(HCLK_NS_RKCE, "hclk_ns_rkce", "hclk_bus_root", 0, RV1126B_BUSCLKGATE_CON(6), 1, GFLAGS), diff --git a/include/dt-bindings/clock/rockchip,rv1126b-cru.h b/include/dt-bindings/clock/rockchip,rv1126b-cru.h index 37e405ccb982..d622dc64221a 100644 --- a/include/dt-bindings/clock/rockchip,rv1126b-cru.h +++ b/include/dt-bindings/clock/rockchip,rv1126b-cru.h @@ -94,7 +94,7 @@ #define CLK_GMAC_125M 84 #define CLK_TIMER_ROOT 85 #define TCLK_WDT_NS_SRC 86 -#define TCLK_WDT_S 87 +#define TCLK_WDT_S_SRC 87 #define TCLK_WDT_HPMCU 88 #define CLK_CAN0 89 #define CLK_CAN1 90 @@ -369,8 +369,26 @@ #define ACLK_VPSL 359 #define CLK_CORE_VPSL 360 #define CLK_MACPHY 361 +#define HCLK_RKRNG_NS 362 +#define HCLK_RKRNG_S_NS 362 -#define CLK_NR_CLKS (CLK_MACPHY + 1) +/* secure clks */ +#define CLK_USER_OTPC_S 400 +#define CLK_SBPI_OTPC_S 401 +#define PCLK_OTPC_S 402 +#define PCLK_KEY_READER_S 403 +#define HCLK_KL_RKCE_S 404 +#define HCLK_RKCE_S 405 +#define PCLK_WDT_S 406 +#define TCLK_WDT_S 407 +#define CLK_STIMER0 408 +#define CLK_STIMER1 409 +#define PLK_STIMER 410 +#define HCLK_RKRNG_S 411 +#define CLK_PKA_RKCE_S 412 +#define ACLK_RKCE_S 413 + +#define CLK_NR_CLKS (ACLK_RKCE_S + 1) // ======================= TOPCRU module definition bank=0 ======================== // TOPCRU_SOFTRST_CON15(Offset:0xA3C) From 4b2b8ddec2c2d43b600b8d25207641378fe4667e Mon Sep 17 00:00:00 2001 From: Hu Kejun Date: Thu, 26 Oct 2023 17:50:17 +0800 Subject: [PATCH 36/57] media: i2c: otp_eeprom: support qsc data Signed-off-by: Hu Kejun Change-Id: I97762a54bb81816f3fd7b1a8de6d491a6b98f887 Signed-off-by: Zefa Chen --- drivers/media/i2c/otp_eeprom.c | 58 ++++++++++++++++++++++++++++++++++ drivers/media/i2c/otp_eeprom.h | 13 ++++++++ 2 files changed, 71 insertions(+) diff --git a/drivers/media/i2c/otp_eeprom.c b/drivers/media/i2c/otp_eeprom.c index 50c96e35f3fe..540e3f57fcd2 100644 --- a/drivers/media/i2c/otp_eeprom.c +++ b/drivers/media/i2c/otp_eeprom.c @@ -731,6 +731,58 @@ static void rkotp_read_af(struct eeprom_device *eeprom_dev, } +static void rkotp_read_qsc(struct eeprom_device *eeprom_dev, + struct otp_info *otp_ptr, + u32 base_addr) +{ + struct i2c_client *client = eeprom_dev->client; + struct device *dev = &eeprom_dev->client->dev; + u8 *qsc_calib = &otp_ptr->qsc_data.qsc_calib[0]; + u32 checksum = 0; + u32 temp = 0; + int i = 0; + int ret = 0; + + ret = read_reg_otp(client, base_addr, + 4, &otp_ptr->qsc_data.size); + checksum += otp_ptr->qsc_data.size; + base_addr += 4; + ret |= read_reg_otp(client, base_addr, + 2, &otp_ptr->qsc_data.version); + checksum += otp_ptr->qsc_data.version; + base_addr += 2; + ret |= read_reg_otp(client, base_addr, + 2, &otp_ptr->qsc_data.qsc_size); + checksum += otp_ptr->qsc_data.qsc_size; + base_addr += 2; + + ret |= read_reg_otp_buf(client, base_addr, RK_QSC_SIZE, qsc_calib); + base_addr += RK_QSC_SIZE; + + for (i = 0; i < RK_QSC_SIZE; i++) + checksum += qsc_calib[i]; + + for (i = 0; i < RK_QSC_RESERVED_SIZE; i++) { + ret |= read_reg_otp(client, base_addr, 1, &temp); + checksum += temp; + base_addr += 1; + } + + ret |= read_reg_otp(client, base_addr, + 1, &otp_ptr->qsc_data.checksum); + if ((checksum % 255 + 1) == otp_ptr->qsc_data.checksum && (!ret)) { + otp_ptr->qsc_data.flag = 0x01; + dev_info(dev, "qsc info:(data[0] 0x%x, checksum 0x%x)\n", + otp_ptr->qsc_data.qsc_calib[0], + (int)otp_ptr->qsc_data.checksum); + } else { + otp_ptr->qsc_data.flag = 0x00; + dev_info(dev, "qsc info: checksum err, checksum %d, reg_checksum %d\n", + (int)(checksum % 255 + 1), + (int)otp_ptr->qsc_data.checksum); + } +} + static int rkotp_read_data(struct eeprom_device *eeprom_dev) { struct i2c_client *client = eeprom_dev->client; @@ -780,6 +832,12 @@ static int rkotp_read_data(struct eeprom_device *eeprom_dev) base_addr + 1); base_addr += 0x20; break; + case RKOTP_QSC_ID: + rkotp_read_qsc(eeprom_dev, + otp_ptr, + base_addr + 1); + base_addr += 0x1010; + break; default: id = -1; break; diff --git a/drivers/media/i2c/otp_eeprom.h b/drivers/media/i2c/otp_eeprom.h index f284e6d59bb5..9ba9e76b64a5 100644 --- a/drivers/media/i2c/otp_eeprom.h +++ b/drivers/media/i2c/otp_eeprom.h @@ -58,6 +58,8 @@ #define RK_DCCMAP_SIZE 0x0200 #define RK_PDAF_RESERVED_SIZE 0x001e #define RK_AF_RESERVED_SIZE 0x0014 +#define RK_QSC_SIZE 0x1000 +#define RK_QSC_RESERVED_SIZE 0x0006 #define RKOTP_MAX_MODULE 0x0008 #define RKOTP_REG_START 0x0008//v1 0, v2 0x0008 @@ -66,6 +68,7 @@ #define RKOTP_LSC_ID 2 #define RKOTP_PDAF_ID 3 #define RKOTP_AF_ID 4 +#define RKOTP_QSC_ID 5 struct id_defination { u32 supplier_id; @@ -165,6 +168,15 @@ struct af_otp_info { u32 size; }; +struct qsc_otp_info { + u32 flag; + u32 version; + u32 qsc_size; + u8 qsc_calib[RK_QSC_SIZE]; + u32 checksum; + u32 size; +}; + struct otp_info { u32 flag; u32 total_checksum; @@ -174,6 +186,7 @@ struct otp_info { struct sfr_otp_info sfr_otp_data; struct pdaf_otp_info pdaf_data; struct af_otp_info af_data; + struct qsc_otp_info qsc_data; }; /* eeprom device structure */ From 917fb6ce45971f4570646ad2f094057e9b418af9 Mon Sep 17 00:00:00 2001 From: Zefa Chen Date: Sun, 7 Apr 2024 19:20:10 +0800 Subject: [PATCH 37/57] media: i2c: dw9800w add power control Signed-off-by: Zefa Chen Change-Id: Id5bb35d36c3438a3ddc63b5ba8448703b66b4cbf --- drivers/media/i2c/dw9800w.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/drivers/media/i2c/dw9800w.c b/drivers/media/i2c/dw9800w.c index 21fe6a40775b..ce534c9631f4 100644 --- a/drivers/media/i2c/dw9800w.c +++ b/drivers/media/i2c/dw9800w.c @@ -32,6 +32,12 @@ #define DW9800W_CHIP_ID 0xF2 #define DW9800W_REG_CHIP_ID 0x00 +static const char * const dw9800w_supply_names[] = { + "avdd", /* Analog power */ +}; + +#define DW9800W_NUM_SUPPLIES ARRAY_SIZE(dw9800w_supply_names) + enum mode_e { SAC2_MODE, SAC3_MODE, @@ -43,6 +49,7 @@ enum mode_e { /* dw9800w device structure */ struct dw9800w_device { + struct regulator_bulk_data supplies[DW9800W_NUM_SUPPLIES]; struct v4l2_ctrl_handler ctrls_vcm; struct v4l2_ctrl *focus; struct i2c_client *client; @@ -564,9 +571,19 @@ static int dw9800w_init_controls(struct dw9800w_device *dev_vcm) static int __dw9800w_set_power(struct dw9800w_device *dw9800w_dev, bool on) { + int ret = 0; + if (dw9800w_dev->power_gpio) gpiod_direction_output(dw9800w_dev->power_gpio, on); + if (on) { + ret = regulator_bulk_enable(DW9800W_NUM_SUPPLIES, dw9800w_dev->supplies); + if (ret < 0) + dev_err(&dw9800w_dev->client->dev, "Failed to enable regulators\n"); + usleep_range(5000, 6000); + } else { + regulator_bulk_disable(DW9800W_NUM_SUPPLIES, dw9800w_dev->supplies); + } return 0; } @@ -604,6 +621,18 @@ err: return -1; } +static int dw9800w_configure_regulators(struct dw9800w_device *dw9800w_dev) +{ + unsigned int i; + + for (i = 0; i < DW9800W_NUM_SUPPLIES; i++) + dw9800w_dev->supplies[i].supply = dw9800w_supply_names[i]; + + return devm_regulator_bulk_get(&dw9800w_dev->client->dev, + DW9800W_NUM_SUPPLIES, + dw9800w_dev->supplies); +} + static int dw9800w_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -693,6 +722,12 @@ static int dw9800w_probe(struct i2c_client *client, "Failed to get power-gpios, maybe no use\n"); } + ret = dw9800w_configure_regulators(dw9800w_dev); + if (ret) { + dev_err(&client->dev, "Failed to get power regulators\n"); + return ret; + } + ret = dw9800w_check_id(dw9800w_dev); if (ret) goto err_power_off; From eed49975bb40dcf86573476d405d689854b1870b Mon Sep 17 00:00:00 2001 From: Caesar Wang Date: Wed, 2 Apr 2025 09:39:22 +0800 Subject: [PATCH 38/57] arm64: dts: rockchip: Enable IRQ mode for fiq-debugger on RV1126B Switch the fiq-debugger driver to use IRQ mode instead of FIQ mode on RV1126B platforms. This change is necessary because: 1. The Trust Zone implementation of fiq-debugger is still under validation 2. IRQ mode provides more stable operation during early bring-up 3. Prevents potential system instability from FIQ handling conflicts Change-Id: I937182a5e0fe22ffafd0972a3834b83c2db0c16c Signed-off-by: Caesar Wang --- arch/arm64/boot/dts/rockchip/rv1126b.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/rockchip/rv1126b.dtsi b/arch/arm64/boot/dts/rockchip/rv1126b.dtsi index 218ad1a3e479..65de6728b29f 100644 --- a/arch/arm64/boot/dts/rockchip/rv1126b.dtsi +++ b/arch/arm64/boot/dts/rockchip/rv1126b.dtsi @@ -394,7 +394,7 @@ compatible = "rockchip,fiq-debugger"; rockchip,serial-id = <0>; rockchip,wake-irq = <0>; - rockchip,irq-mode-enable = <0>; + rockchip,irq-mode-enable = <1>; rockchip,baudrate = <1500000>; /* Only 115200 and 1500000 */ interrupts = ; status = "disabled"; From 5017b73f0b01eff4cb3460e6f42cfbd7b10bd5b8 Mon Sep 17 00:00:00 2001 From: Caesar Wang Date: Tue, 1 Apr 2025 10:46:42 +0800 Subject: [PATCH 39/57] arm64/configs: rockchip_linux_defconfig: Add RV1126B SoCs support Change-Id: Ie249d739625172814a14bf7a3ed6cee3d8e3cc97 Signed-off-by: Caesar Wang --- arch/arm64/configs/rockchip_linux_defconfig | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/arch/arm64/configs/rockchip_linux_defconfig b/arch/arm64/configs/rockchip_linux_defconfig index 895097420356..d3bd3c30fe0e 100644 --- a/arch/arm64/configs/rockchip_linux_defconfig +++ b/arch/arm64/configs/rockchip_linux_defconfig @@ -117,7 +117,9 @@ CONFIG_IP_NF_MANGLE=y CONFIG_CAN=y CONFIG_BT=y CONFIG_BT_RFCOMM=y +CONFIG_BT_RFCOMM_TTY=y CONFIG_BT_HIDP=y +CONFIG_BT_HS=y CONFIG_BT_HCIBTUSB=y CONFIG_BT_HCIUART=y CONFIG_BT_HCIUART_ATH3K=y @@ -205,6 +207,7 @@ CONFIG_R8168=y # CONFIG_NET_VENDOR_SIS is not set # CONFIG_NET_VENDOR_SMSC is not set CONFIG_STMMAC_ETH=y +# CONFIG_DWMAC_GENERIC is not set # CONFIG_NET_VENDOR_SUN is not set # CONFIG_NET_VENDOR_SYNOPSYS is not set # CONFIG_NET_VENDOR_TEHUTI is not set @@ -212,6 +215,7 @@ CONFIG_STMMAC_ETH=y # CONFIG_NET_VENDOR_VIA is not set # CONFIG_NET_VENDOR_WIZNET is not set CONFIG_MOTORCOMM_PHY=y +CONFIG_ROCKCHIP_FEPHY=y CONFIG_ROCKCHIP_PHY=y CONFIG_RK630_PHY=y CONFIG_CANFD_RK3576=y @@ -305,6 +309,7 @@ CONFIG_REGULATOR_GPIO=y CONFIG_REGULATOR_LP8752=y CONFIG_REGULATOR_MP8865=y CONFIG_REGULATOR_PWM=y +CONFIG_REGULATOR_RK801=y CONFIG_REGULATOR_RK806=y CONFIG_REGULATOR_RK808=y CONFIG_REGULATOR_RK860X=y @@ -317,6 +322,7 @@ CONFIG_USB_VIDEO_CLASS=y # CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV is not set CONFIG_V4L_PLATFORM_DRIVERS=y CONFIG_V4L_MEM2MEM_DRIVERS=y +CONFIG_VIDEO_ROCKCHIP_AIISP=y CONFIG_VIDEO_ROCKCHIP_CIF=y CONFIG_VIDEO_ROCKCHIP_RKISP1=y CONFIG_VIDEO_ROCKCHIP_ISP=y @@ -334,7 +340,10 @@ CONFIG_VIDEO_OV4689=y CONFIG_VIDEO_OV50C40=y CONFIG_VIDEO_OV5695=y CONFIG_VIDEO_OV7251=y +CONFIG_VIDEO_SC200AI=y CONFIG_VIDEO_SC4336=y +CONFIG_VIDEO_SC450AI=y +CONFIG_VIDEO_SC850SL=y CONFIG_VIDEO_LT6911UXC=y CONFIG_VIDEO_LT6911UXE=y CONFIG_VIDEO_LT7911D=y @@ -396,6 +405,7 @@ CONFIG_ROCKCHIP_MPP_IEP2=y CONFIG_ROCKCHIP_MPP_JPGDEC=y CONFIG_ROCKCHIP_MPP_JPGENC=y CONFIG_ROCKCHIP_MPP_AV1DEC=y +CONFIG_ROCKCHIP_MPP_OSAL=y CONFIG_SOUND=y CONFIG_SND=y CONFIG_SND_HRTIMER=y @@ -430,6 +440,7 @@ CONFIG_SND_SOC_ES8323=y CONFIG_SND_SOC_ES8326=y CONFIG_SND_SOC_RK3308=y CONFIG_SND_SOC_RK3328=y +CONFIG_SND_SOC_RK3506=y CONFIG_SND_SOC_RK3528=y CONFIG_SND_SOC_RK817=y CONFIG_SND_SOC_RK_CODEC_DIGITAL=y @@ -511,22 +522,28 @@ CONFIG_RTC_DRV_HYM8563=y CONFIG_RTC_DRV_RK808=y CONFIG_DMADEVICES=y CONFIG_PL330_DMA=y +CONFIG_ROCKCHIP_DMA=y CONFIG_RK_DMABUF_DEBUG=y CONFIG_SW_SYNC=y CONFIG_DMABUF_HEAPS=y CONFIG_DMABUF_SYSFS_STATS=y CONFIG_DMABUF_HEAPS_SYSTEM=y CONFIG_DMABUF_HEAPS_CMA=y +CONFIG_DMABUF_HEAPS_ROCKCHIP=y +CONFIG_DMABUF_HEAPS_ROCKCHIP_CMA_HEAP=y +CONFIG_DMABUF_RK_HEAPS_DEBUG=y CONFIG_STAGING=y CONFIG_COMMON_CLK_RK808=y CONFIG_COMMON_CLK_SCMI=y CONFIG_COMMON_CLK_PWM=y +CONFIG_ROCKCHIP_CLK_PVTPLL=y CONFIG_MAILBOX=y CONFIG_ROCKCHIP_MBOX=y CONFIG_ROCKCHIP_IOMMU=y CONFIG_ARM_SMMU_V3=y CONFIG_RPMSG_ROCKCHIP_MBOX=y CONFIG_RPMSG_VIRTIO=y +CONFIG_CPU_RV1126B=y CONFIG_CPU_PX30=y CONFIG_CPU_RK1808=y CONFIG_CPU_RK3328=y @@ -558,7 +575,6 @@ CONFIG_FIQ_DEBUGGER_CONSOLE_DEFAULT_ENABLE=y CONFIG_FIQ_DEBUGGER_TRUST_ZONE=y CONFIG_RK_CONSOLE_THREAD=y CONFIG_ROCKCHIP_DEBUG=y -CONFIG_PM_DEVFREQ=y CONFIG_DEVFREQ_GOV_PERFORMANCE=y CONFIG_DEVFREQ_GOV_POWERSAVE=y CONFIG_DEVFREQ_GOV_USERSPACE=y From 9c419b128cbf7c587c4dfb178c0a855c283a7cde Mon Sep 17 00:00:00 2001 From: Zefa Chen Date: Sun, 7 Apr 2024 19:20:57 +0800 Subject: [PATCH 40/57] media: i2c: dw9800v add sleep to wait power on Signed-off-by: Zefa Chen Change-Id: I8cbf147d28b80caf2dbe258709b13f1a0c309632 --- drivers/media/i2c/dw9800v.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/i2c/dw9800v.c b/drivers/media/i2c/dw9800v.c index f6468f45075a..1a29f4c981be 100644 --- a/drivers/media/i2c/dw9800v.c +++ b/drivers/media/i2c/dw9800v.c @@ -713,6 +713,7 @@ static int __dw9800v_set_power(struct dw9800v_device *dw9800v, bool on) goto unlock_and_return; } dw9800v->power_on = true; + usleep_range(5000, 6000); } else { ret = regulator_disable(dw9800v->supply); if (ret < 0) { From 307ba1ad8d35883f67d820e1585581864909f4f9 Mon Sep 17 00:00:00 2001 From: Zefa Chen Date: Sun, 7 Apr 2024 19:23:02 +0800 Subject: [PATCH 41/57] media: i2c: add imx766 sensor driver Signed-off-by: Zefa Chen Change-Id: I0b457aa9a66cdb8732fa30126bb5e148384e22f0 --- drivers/media/i2c/Kconfig | 13 + drivers/media/i2c/Makefile | 1 + drivers/media/i2c/imx766.c | 2359 ++++++++++++++++++++++++++++++++++++ 3 files changed, 2373 insertions(+) create mode 100644 drivers/media/i2c/imx766.c diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index 5f521b111836..a42301db7fca 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -837,6 +837,19 @@ config VIDEO_IMX586 To compile this driver as a module, choose M here: the module will be called imx586. +config VIDEO_IMX766 + tristate "Sony IMX766 sensor support" + depends on I2C && VIDEO_DEV + depends on MEDIA_CAMERA_SUPPORT + select MEDIA_CONTROLLER + select VIDEO_V4L2_SUBDEV_API + help + This is a Video4Linux2 sensor driver for the Sony + IMX766 camera. + + To compile this driver as a module, choose M here: the + module will be called imx766. + config VIDEO_JX_F37 tristate "Soi JX_F37 sensor support" depends on I2C && VIDEO_DEV diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile index d2353fbc6f42..9c89270f1ce5 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile @@ -105,6 +105,7 @@ obj-$(CONFIG_VIDEO_IMX492) += imx492.o obj-$(CONFIG_VIDEO_IMX498) += imx498.o obj-$(CONFIG_VIDEO_IMX577) += imx577.o obj-$(CONFIG_VIDEO_IMX586) += imx586.o +obj-$(CONFIG_VIDEO_IMX766) += imx766.o obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o obj-$(CONFIG_VIDEO_ISL7998X) += isl7998x.o obj-$(CONFIG_VIDEO_IT6616) += it6616.o diff --git a/drivers/media/i2c/imx766.c b/drivers/media/i2c/imx766.c new file mode 100644 index 000000000000..a1ad9cc879df --- /dev/null +++ b/drivers/media/i2c/imx766.c @@ -0,0 +1,2359 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * imx766 driver + * + * Copyright (C) 2025 Rockchip Electronics Co., Ltd. + * + * V0.0X01.0X01 add poweron function. + * V0.0X01.0X02 fix mclk issue when probe multiple camera. + * V0.0X01.0X03 add enum_frame_interval function. + * V0.0X01.0X04 add quick stream on/off + * V0.0X01.0X05 add function g_mbus_config + * V0.0X01.0X06 support capture spd data and embedded data + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "otp_eeprom.h" + +#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x06) + +#ifndef V4L2_CID_DIGITAL_GAIN +#define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN +#endif + +#define IMX766_LANES 4 +#define IMX766_BITS_PER_SAMPLE 10 +#define IMX766_LINK_FREQ_436MHZ 436000000 // 872/2 +/* pixel rate = link frequency * 2 * lanes / BITS_PER_SAMPLE */ +#define IMX766_PIXEL_RATE_FULL_SIZE 799200000 +#define IMX766_PIXEL_RATE_BINNING 348800000 +#define IMX766_XVCLK_FREQ 24000000 + +#define CHIP_ID 0x0766 +#define IMX766_REG_CHIP_ID 0x0016 + +#define IMX766_REG_CTRL_MODE 0x0100 +#define IMX766_MODE_SW_STANDBY 0x0 +#define IMX766_MODE_STREAMING BIT(0) + +#define IMX766_REG_EXPOSURE 0x0202 +#define IMX766_EXPOSURE_MIN 10 +#define IMX766_EXPOSURE_STEP 4 +#define IMX766_VTS_MAX (0xffff-0x48) + +#define IMX766_REG_GAIN_H 0x0204 +#define IMX766_REG_GAIN_L 0x0205 +#define IMX766_GAIN_MIN 0 +#define IMX766_GAIN_MAX 0x3F00 +#define IMX766_GAIN_STEP 1 +#define IMX766_GAIN_DEFAULT 0x0 + +#define IMX766_REG_TEST_PATTERN 0x0600 +#define IMX766_TEST_PATTERN_ENABLE 0x80 +#define IMX766_TEST_PATTERN_DISABLE 0x0 + +#define IMX766_REG_VTS 0x0340 + +#define REG_NULL 0xFFFF + +#define IMX766_REG_VALUE_08BIT 1 +#define IMX766_REG_VALUE_16BIT 2 +#define IMX766_REG_VALUE_24BIT 3 + +#define OF_CAMERA_PINCTRL_STATE_DEFAULT "rockchip,camera_default" +#define OF_CAMERA_PINCTRL_STATE_SLEEP "rockchip,camera_sleep" + +#define IMX766_NAME "imx766" + +static const char * const imx766_supply_names[] = { + "avdd", /* Analog power */ + "dovdd", /* Digital I/O power */ + "dvdd", /* Digital core power */ +}; + +#define IMX766_NUM_SUPPLIES ARRAY_SIZE(imx766_supply_names) + +struct regval { + u16 addr; + u8 val; +}; + +struct other_data { + u32 width; + u32 height; + u32 bus_fmt; + u32 data_type; + u32 data_bit; +}; + +struct imx766_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; + /* Shield Pix Data */ + const struct other_data *spd; + /* embedded Data */ + const struct other_data *ebd; + u32 hdr_mode; + u32 vc[PAD_MAX]; +}; + +struct imx766 { + struct i2c_client *client; + struct clk *xvclk; + struct gpio_desc *reset_gpio; + struct gpio_desc *pwdn_gpio; + struct gpio_desc *power_gpio; + struct regulator_bulk_data supplies[IMX766_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 *test_pattern; + struct mutex mutex; + bool streaming; + bool power_on; + const struct imx766_mode *cur_mode; + u32 cfg_num; + u32 module_index; + const char *module_facing; + const char *module_name; + const char *len_name; + struct v4l2_ctrl *link_freq; + struct v4l2_ctrl *pixel_rate; + struct otp_info *otp; + u32 spd_id; + u32 ebd_id; +}; + +#define to_imx766(sd) container_of(sd, struct imx766, subdev) + +/* + * Xclk 24Mhz + */ +static const struct regval imx766_global_regs[] = { + {0x0100, 0x00}, + {0x0136, 0x18}, + {0x0137, 0x00}, + {0x33F0, 0x09}, + {0x33F1, 0x05}, + {0x0111, 0x02}, + {0x33D3, 0x01}, + {0x3892, 0x01}, + {0x4C14, 0x00}, + {0x4C15, 0x07}, + {0x4C16, 0x00}, + {0x4C17, 0x1B}, + {0x4C1A, 0x00}, + {0x4C1B, 0x03}, + {0x4C1C, 0x00}, + {0x4C1D, 0x00}, + {0x4C1E, 0x00}, + {0x4C1F, 0x02}, + {0x4C20, 0x00}, + {0x4C21, 0x5F}, + {0x4C26, 0x00}, + {0x4C27, 0x43}, + {0x4C28, 0x00}, + {0x4C29, 0x09}, + {0x4C2A, 0x00}, + {0x4C2B, 0x4A}, + {0x4C2C, 0x00}, + {0x4C2D, 0x00}, + {0x4C2E, 0x00}, + {0x4C2F, 0x02}, + {0x4C30, 0x00}, + {0x4C31, 0xC6}, + {0x4C3E, 0x00}, + {0x4C3F, 0x55}, + {0x4C52, 0x00}, + {0x4C53, 0x97}, + {0x4CB4, 0x00}, + {0x4CB5, 0x55}, + {0x4CC8, 0x00}, + {0x4CC9, 0x97}, + {0x4D04, 0x00}, + {0x4D05, 0x4F}, + {0x4D74, 0x00}, + {0x4D75, 0x55}, + {0x4F06, 0x00}, + {0x4F07, 0x5F}, + {0x4F48, 0x00}, + {0x4F49, 0xC6}, + {0x544A, 0xFF}, + {0x544B, 0xFF}, + {0x544E, 0x01}, + {0x544F, 0xBD}, + {0x5452, 0xFF}, + {0x5453, 0xFF}, + {0x5456, 0x00}, + {0x5457, 0xA5}, + {0x545A, 0xFF}, + {0x545B, 0xFF}, + {0x545E, 0x00}, + {0x545F, 0xA5}, + {0x5496, 0x00}, + {0x5497, 0xA2}, + {0x54F6, 0x01}, + {0x54F7, 0x55}, + {0x54F8, 0x01}, + {0x54F9, 0x61}, + {0x5670, 0x00}, + {0x5671, 0x85}, + {0x5672, 0x01}, + {0x5673, 0x77}, + {0x5674, 0x01}, + {0x5675, 0x2F}, + {0x5676, 0x02}, + {0x5677, 0x55}, + {0x5678, 0x00}, + {0x5679, 0x85}, + {0x567A, 0x01}, + {0x567B, 0x77}, + {0x567C, 0x01}, + {0x567D, 0x2F}, + {0x567E, 0x02}, + {0x567F, 0x55}, + {0x5680, 0x00}, + {0x5681, 0x85}, + {0x5682, 0x01}, + {0x5683, 0x77}, + {0x5684, 0x01}, + {0x5685, 0x2F}, + {0x5686, 0x02}, + {0x5687, 0x55}, + {0x5688, 0x00}, + {0x5689, 0x85}, + {0x568A, 0x01}, + {0x568B, 0x77}, + {0x568C, 0x01}, + {0x568D, 0x2F}, + {0x568E, 0x02}, + {0x568F, 0x55}, + {0x5690, 0x01}, + {0x5691, 0x7A}, + {0x5692, 0x02}, + {0x5693, 0x6C}, + {0x5694, 0x01}, + {0x5695, 0x35}, + {0x5696, 0x02}, + {0x5697, 0x5B}, + {0x5698, 0x01}, + {0x5699, 0x7A}, + {0x569A, 0x02}, + {0x569B, 0x6C}, + {0x569C, 0x01}, + {0x569D, 0x35}, + {0x569E, 0x02}, + {0x569F, 0x5B}, + {0x56A0, 0x01}, + {0x56A1, 0x7A}, + {0x56A2, 0x02}, + {0x56A3, 0x6C}, + {0x56A4, 0x01}, + {0x56A5, 0x35}, + {0x56A6, 0x02}, + {0x56A7, 0x5B}, + {0x56A8, 0x01}, + {0x56A9, 0x80}, + {0x56AA, 0x02}, + {0x56AB, 0x72}, + {0x56AC, 0x01}, + {0x56AD, 0x2F}, + {0x56AE, 0x02}, + {0x56AF, 0x55}, + {0x5902, 0x0E}, + {0x5A50, 0x04}, + {0x5A51, 0x04}, + {0x5A69, 0x01}, + {0x5C49, 0x0D}, + {0x5D60, 0x08}, + {0x5D61, 0x08}, + {0x5D62, 0x08}, + {0x5D63, 0x08}, + {0x5D64, 0x08}, + {0x5D67, 0x08}, + {0x5D6C, 0x08}, + {0x5D6E, 0x08}, + {0x5D71, 0x08}, + {0x5D8E, 0x14}, + {0x5D90, 0x03}, + {0x5D91, 0x0A}, + {0x5D92, 0x1F}, + {0x5D93, 0x05}, + {0x5D97, 0x1F}, + {0x5D9A, 0x06}, + {0x5D9C, 0x1F}, + {0x5DA1, 0x1F}, + {0x5DA6, 0x1F}, + {0x5DA8, 0x1F}, + {0x5DAB, 0x1F}, + {0x5DC0, 0x06}, + {0x5DC1, 0x06}, + {0x5DC2, 0x07}, + {0x5DC3, 0x06}, + {0x5DC4, 0x07}, + {0x5DC7, 0x07}, + {0x5DCC, 0x07}, + {0x5DCE, 0x07}, + {0x5DD1, 0x07}, + {0x5E3E, 0x00}, + {0x5E3F, 0x00}, + {0x5E41, 0x00}, + {0x5E48, 0x00}, + {0x5E49, 0x00}, + {0x5E4A, 0x00}, + {0x5E4C, 0x00}, + {0x5E4D, 0x00}, + {0x5E4E, 0x00}, + {0x6026, 0x03}, + {0x6028, 0x03}, + {0x602A, 0x03}, + {0x602C, 0x03}, + {0x602F, 0x03}, + {0x6036, 0x03}, + {0x6038, 0x03}, + {0x603A, 0x03}, + {0x603C, 0x03}, + {0x603F, 0x03}, + {0x6074, 0x19}, + {0x6076, 0x19}, + {0x6078, 0x19}, + {0x607A, 0x19}, + {0x607D, 0x19}, + {0x6084, 0x32}, + {0x6086, 0x32}, + {0x6088, 0x32}, + {0x608A, 0x32}, + {0x608D, 0x32}, + {0x60C2, 0x4A}, + {0x60C4, 0x4A}, + {0x60CB, 0x4A}, + {0x60D2, 0x4A}, + {0x60D4, 0x4A}, + {0x60DB, 0x4A}, + {0x62F9, 0x14}, + {0x6305, 0x13}, + {0x6307, 0x13}, + {0x630A, 0x13}, + {0x630D, 0x0D}, + {0x6317, 0x0D}, + {0x632F, 0x2E}, + {0x6333, 0x2E}, + {0x6339, 0x2E}, + {0x6343, 0x2E}, + {0x6347, 0x2E}, + {0x634D, 0x2E}, + {0x6352, 0x00}, + {0x6353, 0x5F}, + {0x6366, 0x00}, + {0x6367, 0x5F}, + {0x638F, 0x95}, + {0x6393, 0x95}, + {0x6399, 0x95}, + {0x63A3, 0x95}, + {0x63A7, 0x95}, + {0x63AD, 0x95}, + {0x63B2, 0x00}, + {0x63B3, 0xC6}, + {0x63C6, 0x00}, + {0x63C7, 0xC6}, + {0x8BDB, 0x02}, + {0x8BDE, 0x02}, + {0x8BE1, 0x2D}, + {0x8BE4, 0x00}, + {0x8BE5, 0x00}, + {0x8BE6, 0x01}, + {0x9002, 0x14}, + {0x9200, 0xB5}, + {0x9201, 0x9E}, + {0x9202, 0xB5}, + {0x9203, 0x42}, + {0x9204, 0xB5}, + {0x9205, 0x43}, + {0x9206, 0xBD}, + {0x9207, 0x20}, + {0x9208, 0xBD}, + {0x9209, 0x22}, + {0x920A, 0xBD}, + {0x920B, 0x23}, + {0xB5D7, 0x10}, + {0xBD24, 0x00}, + {0xBD25, 0x00}, + {0xBD26, 0x00}, + {0xBD27, 0x00}, + {0xBD28, 0x00}, + {0xBD29, 0x00}, + {0xBD2A, 0x00}, + {0xBD2B, 0x00}, + {0xBD2C, 0x32}, + {0xBD2D, 0x70}, + {0xBD2E, 0x25}, + {0xBD2F, 0x30}, + {0xBD30, 0x3B}, + {0xBD31, 0xE0}, + {0xBD32, 0x69}, + {0xBD33, 0x40}, + {0xBD34, 0x25}, + {0xBD35, 0x90}, + {0xBD36, 0x58}, + {0xBD37, 0x00}, + {0xBD38, 0x00}, + {0xBD39, 0x00}, + {0xBD3A, 0x00}, + {0xBD3B, 0x00}, + {0xBD3C, 0x32}, + {0xBD3D, 0x70}, + {0xBD3E, 0x25}, + {0xBD3F, 0x90}, + {0xBD40, 0x58}, + {0xBD41, 0x00}, + {0x793B, 0x01}, + {0xACC6, 0x00}, + {0xACF5, 0x00}, + {0x793B, 0x00}, + {0x1F04, 0xB3}, + {0x1F05, 0x01}, + {0x1F06, 0x07}, + {0x1F07, 0x66}, + {0x1F08, 0x01}, + {0x4D18, 0x00}, + {0x4D19, 0x9D}, + {0x4D88, 0x00}, + {0x4D89, 0x97}, + {0x5C57, 0x0A}, + {0x5D94, 0x1F}, + {0x5D9E, 0x1F}, + {0x5E50, 0x23}, + {0x5E51, 0x20}, + {0x5E52, 0x07}, + {0x5E53, 0x20}, + {0x5E54, 0x07}, + {0x5E55, 0x27}, + {0x5E56, 0x0B}, + {0x5E57, 0x24}, + {0x5E58, 0x0B}, + {0x5E60, 0x24}, + {0x5E61, 0x24}, + {0x5E62, 0x1B}, + {0x5E63, 0x23}, + {0x5E64, 0x1B}, + {0x5E65, 0x28}, + {0x5E66, 0x22}, + {0x5E67, 0x28}, + {0x5E68, 0x23}, + {0x5E70, 0x25}, + {0x5E71, 0x24}, + {0x5E72, 0x20}, + {0x5E73, 0x24}, + {0x5E74, 0x20}, + {0x5E75, 0x28}, + {0x5E76, 0x27}, + {0x5E77, 0x29}, + {0x5E78, 0x24}, + {0x5E80, 0x25}, + {0x5E81, 0x25}, + {0x5E82, 0x24}, + {0x5E83, 0x25}, + {0x5E84, 0x23}, + {0x5E85, 0x2A}, + {0x5E86, 0x28}, + {0x5E87, 0x2A}, + {0x5E88, 0x28}, + {0x5E90, 0x24}, + {0x5E91, 0x24}, + {0x5E92, 0x28}, + {0x5E93, 0x29}, + {0x5E97, 0x25}, + {0x5E98, 0x25}, + {0x5E99, 0x2A}, + {0x5E9A, 0x2A}, + {0x5E9E, 0x3A}, + {0x5E9F, 0x3F}, + {0x5EA0, 0x17}, + {0x5EA1, 0x3F}, + {0x5EA2, 0x17}, + {0x5EA3, 0x32}, + {0x5EA4, 0x10}, + {0x5EA5, 0x33}, + {0x5EA6, 0x10}, + {0x5EAE, 0x3D}, + {0x5EAF, 0x48}, + {0x5EB0, 0x3B}, + {0x5EB1, 0x45}, + {0x5EB2, 0x37}, + {0x5EB3, 0x3A}, + {0x5EB4, 0x31}, + {0x5EB5, 0x3A}, + {0x5EB6, 0x31}, + {0x5EBE, 0x40}, + {0x5EBF, 0x48}, + {0x5EC0, 0x3F}, + {0x5EC1, 0x45}, + {0x5EC2, 0x3F}, + {0x5EC3, 0x3A}, + {0x5EC4, 0x32}, + {0x5EC5, 0x3A}, + {0x5EC6, 0x33}, + {0x5ECE, 0x4B}, + {0x5ECF, 0x4A}, + {0x5ED0, 0x48}, + {0x5ED1, 0x4C}, + {0x5ED2, 0x45}, + {0x5ED3, 0x3F}, + {0x5ED4, 0x3A}, + {0x5ED5, 0x3F}, + {0x5ED6, 0x3A}, + {0x5EDE, 0x48}, + {0x5EDF, 0x45}, + {0x5EE0, 0x3A}, + {0x5EE1, 0x3A}, + {0x5EE5, 0x4A}, + {0x5EE6, 0x4C}, + {0x5EE7, 0x3F}, + {0x5EE8, 0x3F}, + {0x5EEC, 0x06}, + {0x5EED, 0x06}, + {0x5EEE, 0x02}, + {0x5EEF, 0x06}, + {0x5EF0, 0x01}, + {0x5EF1, 0x09}, + {0x5EF2, 0x05}, + {0x5EF3, 0x06}, + {0x5EF4, 0x04}, + {0x5EFC, 0x07}, + {0x5EFD, 0x09}, + {0x5EFE, 0x05}, + {0x5EFF, 0x08}, + {0x5F00, 0x04}, + {0x5F01, 0x09}, + {0x5F02, 0x05}, + {0x5F03, 0x09}, + {0x5F04, 0x04}, + {0x5F0C, 0x08}, + {0x5F0D, 0x09}, + {0x5F0E, 0x06}, + {0x5F0F, 0x09}, + {0x5F10, 0x06}, + {0x5F11, 0x09}, + {0x5F12, 0x09}, + {0x5F13, 0x09}, + {0x5F14, 0x06}, + {0x5F1C, 0x09}, + {0x5F1D, 0x09}, + {0x5F1E, 0x09}, + {0x5F1F, 0x09}, + {0x5F20, 0x08}, + {0x5F21, 0x09}, + {0x5F22, 0x09}, + {0x5F23, 0x09}, + {0x5F24, 0x09}, + {0x5F2C, 0x09}, + {0x5F2D, 0x09}, + {0x5F2E, 0x09}, + {0x5F2F, 0x09}, + {0x5F33, 0x09}, + {0x5F34, 0x09}, + {0x5F35, 0x09}, + {0x5F36, 0x09}, + {0x5F3A, 0x01}, + {0x5F3D, 0x07}, + {0x5F3F, 0x01}, + {0x5F4B, 0x01}, + {0x5F4D, 0x04}, + {0x5F4F, 0x02}, + {0x5F51, 0x02}, + {0x5F5A, 0x02}, + {0x5F5B, 0x01}, + {0x5F5D, 0x03}, + {0x5F5E, 0x07}, + {0x5F5F, 0x01}, + {0x5F60, 0x01}, + {0x5F61, 0x01}, + {0x5F6A, 0x01}, + {0x5F6C, 0x01}, + {0x5F6D, 0x01}, + {0x5F6E, 0x04}, + {0x5F70, 0x02}, + {0x5F72, 0x02}, + {0x5F7A, 0x01}, + {0x5F7B, 0x03}, + {0x5F7C, 0x01}, + {0x5F7D, 0x01}, + {0x5F82, 0x01}, + {0x60C6, 0x4A}, + {0x60C8, 0x4A}, + {0x60D6, 0x4A}, + {0x60D8, 0x4A}, + {0x62E4, 0x33}, + {0x62E9, 0x33}, + {0x62EE, 0x1C}, + {0x62EF, 0x33}, + {0x62F3, 0x33}, + {0x62F6, 0x1C}, + {0x33F2, 0x01}, + {0x1F04, 0xA3}, + {0x1F05, 0x01}, + {0x406E, 0x00}, + {0x406F, 0x08}, + {0x4D08, 0x00}, + {0x4D09, 0x2C}, + {0x4D0E, 0x00}, + {0x4D0F, 0x64}, + {0x4D18, 0x00}, + {0x4D19, 0xB1}, + {0x4D1E, 0x00}, + {0x4D1F, 0xCB}, + {0x4D3A, 0x00}, + {0x4D3B, 0x91}, + {0x4D40, 0x00}, + {0x4D41, 0x64}, + {0x4D4C, 0x00}, + {0x4D4D, 0xE8}, + {0x4D52, 0x00}, + {0x4D53, 0xCB}, + {0x4D78, 0x00}, + {0x4D79, 0x2C}, + {0x4D7E, 0x00}, + {0x4D7F, 0x64}, + {0x4D88, 0x00}, + {0x4D89, 0xAB}, + {0x4D8E, 0x00}, + {0x4D8F, 0xCB}, + {0x4DA6, 0x00}, + {0x4DA7, 0xE7}, + {0x4DAC, 0x00}, + {0x4DAD, 0xCB}, + {0x5B98, 0x00}, + {0x5C52, 0x05}, + {0x5C57, 0x09}, + {0x5D94, 0x0A}, + {0x5D9E, 0x0A}, + {0x5E50, 0x22}, + {0x5E51, 0x22}, + {0x5E52, 0x07}, + {0x5E53, 0x20}, + {0x5E54, 0x06}, + {0x5E55, 0x23}, + {0x5E56, 0x0A}, + {0x5E57, 0x23}, + {0x5E58, 0x0A}, + {0x5E60, 0x25}, + {0x5E61, 0x29}, + {0x5E62, 0x1C}, + {0x5E63, 0x26}, + {0x5E64, 0x1C}, + {0x5E65, 0x2D}, + {0x5E66, 0x1E}, + {0x5E67, 0x2A}, + {0x5E68, 0x1E}, + {0x5E70, 0x26}, + {0x5E71, 0x26}, + {0x5E72, 0x22}, + {0x5E73, 0x23}, + {0x5E74, 0x20}, + {0x5E75, 0x28}, + {0x5E76, 0x23}, + {0x5E77, 0x28}, + {0x5E78, 0x23}, + {0x5E80, 0x28}, + {0x5E81, 0x28}, + {0x5E82, 0x29}, + {0x5E83, 0x27}, + {0x5E84, 0x26}, + {0x5E85, 0x2A}, + {0x5E86, 0x2D}, + {0x5E87, 0x2A}, + {0x5E88, 0x2A}, + {0x5E90, 0x26}, + {0x5E91, 0x23}, + {0x5E92, 0x28}, + {0x5E93, 0x28}, + {0x5E97, 0x2F}, + {0x5E98, 0x2E}, + {0x5E99, 0x32}, + {0x5E9A, 0x32}, + {0x5E9E, 0x50}, + {0x5E9F, 0x50}, + {0x5EA0, 0x1E}, + {0x5EA1, 0x50}, + {0x5EA2, 0x1D}, + {0x5EA3, 0x3E}, + {0x5EA4, 0x14}, + {0x5EA5, 0x3E}, + {0x5EA6, 0x14}, + {0x5EAE, 0x58}, + {0x5EAF, 0x5E}, + {0x5EB0, 0x4B}, + {0x5EB1, 0x5A}, + {0x5EB2, 0x4B}, + {0x5EB3, 0x4C}, + {0x5EB4, 0x3A}, + {0x5EB5, 0x4C}, + {0x5EB6, 0x38}, + {0x5EBE, 0x56}, + {0x5EBF, 0x57}, + {0x5EC0, 0x50}, + {0x5EC1, 0x55}, + {0x5EC2, 0x50}, + {0x5EC3, 0x46}, + {0x5EC4, 0x3E}, + {0x5EC5, 0x46}, + {0x5EC6, 0x3E}, + {0x5ECE, 0x5A}, + {0x5ECF, 0x5F}, + {0x5ED0, 0x5E}, + {0x5ED1, 0x5A}, + {0x5ED2, 0x5A}, + {0x5ED3, 0x50}, + {0x5ED4, 0x4C}, + {0x5ED5, 0x50}, + {0x5ED6, 0x4C}, + {0x5EDE, 0x57}, + {0x5EDF, 0x55}, + {0x5EE0, 0x46}, + {0x5EE1, 0x46}, + {0x5EE5, 0x73}, + {0x5EE6, 0x6E}, + {0x5EE7, 0x5F}, + {0x5EE8, 0x5A}, + {0x5EEC, 0x0A}, + {0x5EED, 0x0A}, + {0x5EEE, 0x0F}, + {0x5EEF, 0x0A}, + {0x5EF0, 0x0E}, + {0x5EF1, 0x08}, + {0x5EF2, 0x0C}, + {0x5EF3, 0x0C}, + {0x5EF4, 0x0F}, + {0x5EFC, 0x0A}, + {0x5EFD, 0x0A}, + {0x5EFE, 0x14}, + {0x5EFF, 0x0A}, + {0x5F00, 0x14}, + {0x5F01, 0x0A}, + {0x5F02, 0x14}, + {0x5F03, 0x0A}, + {0x5F04, 0x19}, + {0x5F0C, 0x0A}, + {0x5F0D, 0x0A}, + {0x5F0E, 0x0A}, + {0x5F0F, 0x05}, + {0x5F10, 0x0A}, + {0x5F11, 0x06}, + {0x5F12, 0x08}, + {0x5F13, 0x0A}, + {0x5F14, 0x0C}, + {0x5F1C, 0x0A}, + {0x5F1D, 0x0A}, + {0x5F1E, 0x0A}, + {0x5F1F, 0x0A}, + {0x5F20, 0x0A}, + {0x5F21, 0x0A}, + {0x5F22, 0x0A}, + {0x5F23, 0x0A}, + {0x5F24, 0x0A}, + {0x5F2C, 0x0A}, + {0x5F2D, 0x05}, + {0x5F2E, 0x06}, + {0x5F2F, 0x0A}, + {0x5F33, 0x0A}, + {0x5F34, 0x0A}, + {0x5F35, 0x0A}, + {0x5F36, 0x0A}, + {0x5F3A, 0x00}, + {0x5F3D, 0x02}, + {0x5F3F, 0x0A}, + {0x5F4A, 0x0A}, + {0x5F4B, 0x0A}, + {0x5F4D, 0x0F}, + {0x5F4F, 0x00}, + {0x5F51, 0x00}, + {0x5F5A, 0x00}, + {0x5F5B, 0x00}, + {0x5F5D, 0x0A}, + {0x5F5E, 0x02}, + {0x5F5F, 0x0A}, + {0x5F60, 0x0A}, + {0x5F61, 0x00}, + {0x5F6A, 0x00}, + {0x5F6C, 0x0A}, + {0x5F6D, 0x06}, + {0x5F6E, 0x0F}, + {0x5F70, 0x00}, + {0x5F72, 0x00}, + {0x5F7A, 0x00}, + {0x5F7B, 0x0A}, + {0x5F7C, 0x0A}, + {0x5F7D, 0x00}, + {0x5F82, 0x06}, + {0x60C6, 0x36}, + {0x60C8, 0x36}, + {0x60D6, 0x36}, + {0x60D8, 0x36}, + {0x62DF, 0x56}, + {0x62E0, 0x52}, + {0x62E4, 0x38}, + {0x62E5, 0x51}, + {0x62E9, 0x35}, + {0x62EA, 0x54}, + {0x62EE, 0x1D}, + {0x62EF, 0x38}, + {0x62F3, 0x33}, + {0x62F6, 0x26}, + {0x6412, 0x1E}, + {0x6413, 0x1E}, + {0x6414, 0x1E}, + {0x6415, 0x1E}, + {0x6416, 0x1E}, + {0x6417, 0x1E}, + {0x6418, 0x1E}, + {0x641A, 0x1E}, + {0x641B, 0x1E}, + {0x641C, 0x1E}, + {0x641D, 0x1E}, + {0x641E, 0x1E}, + {0x641F, 0x1E}, + {0x6420, 0x1E}, + {0x6421, 0x1E}, + {0x6422, 0x1E}, + {0x6424, 0x1E}, + {0x6425, 0x1E}, + {0x6426, 0x1E}, + {0x6427, 0x1E}, + {0x6428, 0x1E}, + {0x6429, 0x1E}, + {0x642A, 0x1E}, + {0x642B, 0x1E}, + {0x642C, 0x1E}, + {0x642E, 0x1E}, + {0x642F, 0x1E}, + {0x6430, 0x1E}, + {0x6431, 0x1E}, + {0x6432, 0x1E}, + {0x6433, 0x1E}, + {0x6434, 0x1E}, + {0x6435, 0x1E}, + {0x6436, 0x1E}, + {0x6438, 0x1E}, + {0x6439, 0x1E}, + {0x643A, 0x1E}, + {0x643B, 0x1E}, + {0x643D, 0x1E}, + {0x643E, 0x1E}, + {0x643F, 0x1E}, + {0x6441, 0x1E}, + {0x33F2, 0x02}, + {0x1F08, 0x00}, + {0xA307, 0x30}, + {0xA309, 0x30}, + {0xA30B, 0x30}, + {0xA406, 0x03}, + {0xA407, 0x48}, + {0xA408, 0x03}, + {0xA409, 0x48}, + {0xA40A, 0x03}, + {0xA40B, 0x48}, + {REG_NULL, 0x00}, +}; + +/* + * Xclk 24Mhz + * max_framerate 7fps + * mipi_datarate per lane 600Mbps + */ +static const struct regval imx766_4096x3072_regs[] = { + {0x0112, 0x0A}, + {0x0113, 0x0A}, + {0x0114, 0x03}, + {0x0342, 0xB7}, + {0x0343, 0x00}, + {0x0340, 0x0C}, + {0x0341, 0x5C}, + {0x0344, 0x00}, + {0x0345, 0x00}, + {0x0346, 0x00}, + {0x0347, 0x00}, + {0x0348, 0x1F}, + {0x0349, 0xFF}, + {0x034A, 0x17}, + {0x034B, 0xFF}, + {0x0900, 0x01}, + {0x0901, 0x22}, + {0x0902, 0x08}, + {0x3005, 0x02}, + {0x3120, 0x04}, + {0x3121, 0x01}, + {0x3200, 0x41}, + {0x3201, 0x41}, + {0x32D6, 0x00}, + {0x0408, 0x00}, + {0x0409, 0x00}, + {0x040A, 0x00}, + {0x040B, 0x00}, + {0x040C, 0x10}, + {0x040D, 0x00}, + {0x040E, 0x0C}, + {0x040F, 0x00}, + {0x034C, 0x10}, + {0x034D, 0x00}, + {0x034E, 0x0C}, + {0x034F, 0x00}, + {0x0301, 0x05}, + {0x0303, 0x02}, + {0x0305, 0x04}, + {0x0306, 0x01}, + {0x0307, 0x35}, + {0x030B, 0x04}, + {0x030D, 0x03}, + {0x030E, 0x01}, + {0x030F, 0xB4}, + {0x30CB, 0x00}, + {0x30CC, 0x10}, + {0x30CD, 0x00}, + {0x30CE, 0x03}, + {0x30CF, 0x00}, + {0x319C, 0x01}, + {0x3800, 0x01}, + {0x3801, 0x01}, + {0x3802, 0x02}, + {0x3847, 0x03}, + {0x38B0, 0x00}, + {0x38B1, 0x64}, + {0x38B2, 0x00}, + {0x38B3, 0x64}, + {0x38C4, 0x00}, + {0x38C5, 0x64}, + {0x4C3A, 0x02}, + {0x4C3B, 0xD2}, + {0x4C68, 0x04}, + {0x4C69, 0x7E}, + {0x4CF8, 0x16}, + {0x4CF9, 0xE0}, + {0x4DB8, 0x08}, + {0x4DB9, 0x98}, + {0x0202, 0x0C}, + {0x0203, 0x2C}, + {0x0224, 0x01}, + {0x0225, 0xF4}, + {0x313A, 0x01}, + {0x313B, 0xF4}, + {0x3803, 0x00}, + {0x3804, 0x17}, + {0x3805, 0xC0}, + {0x0204, 0x00}, + {0x0205, 0x00}, + {0x020E, 0x01}, + {0x020F, 0x00}, + {0x0216, 0x00}, + {0x0217, 0x00}, + {0x0218, 0x01}, + {0x0219, 0x00}, + {0x313C, 0x00}, + {0x313D, 0x00}, + {0x313E, 0x01}, + {0x313F, 0x00}, + {0x30B4, 0x01}, + {0x3066, 0x01}, + {0x3067, 0x30}, + {0x3068, 0x01}, + {0x3069, 0x30}, + {0x33D0, 0x00}, + {0x33D1, 0x00}, + {0x33D4, 0x01}, + {0x33DC, 0x0A}, + {0x33DD, 0x0A}, + {0x33DE, 0x0A}, + {0x33DF, 0x0A}, + {0x3070, 0x01}, + {0x3077, 0x01}, + {0x3078, 0x30}, + {0x3079, 0x01}, + {0x307A, 0x30}, + {0x307B, 0x01}, + {0x3080, 0x02}, + {0x3087, 0x02}, + {0x3088, 0x30}, + {0x3089, 0x02}, + {0x308A, 0x30}, + {0x308B, 0x02}, + {0x3901, 0x2B}, + {0x3902, 0x00}, + {0x3903, 0x12}, + {0x3905, 0x2B}, + {0x3906, 0x01}, + {0x3907, 0x12}, + {0x3909, 0x2B}, + {0x390A, 0x02}, + {0x390B, 0x12}, + {0x3911, 0x00}, + {REG_NULL, 0x00}, +}; + +static const struct other_data imx766_full_spd = { + .width = 4096, + .height = 768, + .bus_fmt = MEDIA_BUS_FMT_SPD_2X8, + .data_type = 0x30, + .data_bit = 10, +}; + +static const struct other_data imx766_full_ebd = { + .width = 320, + .height = 2, + .bus_fmt = MEDIA_BUS_FMT_EBD_1X8, +}; + +static const struct imx766_mode supported_modes[] = { + { + .bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10, + .width = 4096, + .height = 3072, + .max_fps = { + .numerator = 10000, + .denominator = 200000, + }, + .exp_def = 0x0C2C, + .hts_def = 0xB700, + .vts_def = 0x0C5C, + .reg_list = imx766_4096x3072_regs, + .spd = &imx766_full_spd, + .ebd = &imx766_full_ebd, + .hdr_mode = NO_HDR, + .vc[PAD0] = 0, + }, +}; + +static const s64 link_freq_menu_items[] = { + IMX766_LINK_FREQ_436MHZ +}; + +static const char * const imx766_test_pattern_menu[] = { + "Disabled", + "Vertical Color Bar Type 1", + "Vertical Color Bar Type 2", + "Vertical Color Bar Type 3", + "Vertical Color Bar Type 4" +}; + +#define WRITE_COUNT 5 +/* Write registers up to 4 at a time */ +static int imx766_write_reg(struct i2c_client *client, u16 reg, + int len, u32 val) +{ + u32 buf_i, val_i, 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++]; + i = 0; + while (i < WRITE_COUNT) { + if (i2c_master_send(client, buf, len + 2) == len + 2) + break; + i++; + } + if (i >= WRITE_COUNT) + return -EIO; + + return 0; +} + +static int imx766_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 = imx766_write_reg(client, regs[i].addr, + IMX766_REG_VALUE_08BIT, + regs[i].val); + return ret; +} + +/* Read registers up to 4 at a time */ +static int imx766_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 imx766_get_reso_dist(const struct imx766_mode *mode, + struct v4l2_mbus_framefmt *framefmt) +{ + return abs(mode->width - framefmt->width) + + abs(mode->height - framefmt->height); +} + +static const struct imx766_mode * + imx766_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 = imx766_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 imx766_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_format *fmt) +{ + struct imx766 *imx766 = to_imx766(sd); + const struct imx766_mode *mode; + s64 h_blank, vblank_def; + + mutex_lock(&imx766->mutex); + + mode = imx766_find_best_fit(fmt); + fmt->format.code = MEDIA_BUS_FMT_SRGGB10_1X10; + 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, sd_state, fmt->pad) = fmt->format; +#else + mutex_unlock(&imx766->mutex); + return -ENOTTY; +#endif + } else { + imx766->cur_mode = mode; + h_blank = mode->hts_def - mode->width; + __v4l2_ctrl_modify_range(imx766->hblank, h_blank, + h_blank, 1, h_blank); + vblank_def = mode->vts_def - mode->height; + __v4l2_ctrl_modify_range(imx766->vblank, vblank_def, + IMX766_VTS_MAX - mode->height, + 1, vblank_def); + if (mode->width == 4096 && mode->height == 3072) { + __v4l2_ctrl_s_ctrl(imx766->link_freq, + link_freq_menu_items[0]); + __v4l2_ctrl_s_ctrl_int64(imx766->pixel_rate, + IMX766_PIXEL_RATE_BINNING); + } else { + __v4l2_ctrl_s_ctrl(imx766->link_freq, + link_freq_menu_items[0]); + __v4l2_ctrl_s_ctrl_int64(imx766->pixel_rate, + IMX766_PIXEL_RATE_FULL_SIZE); + } + } + mutex_unlock(&imx766->mutex); + + return 0; +} + +static int imx766_get_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_format *fmt) +{ + struct imx766 *imx766 = to_imx766(sd); + const struct imx766_mode *mode = imx766->cur_mode; + + mutex_lock(&imx766->mutex); + if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { +#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API + fmt->format = *v4l2_subdev_get_try_format(sd, sd_state, fmt->pad); +#else + mutex_unlock(&imx766->mutex); + return -ENOTTY; +#endif + } else { + fmt->format.width = mode->width; + fmt->format.height = mode->height; + fmt->format.code = MEDIA_BUS_FMT_SRGGB10_1X10; + fmt->format.field = V4L2_FIELD_NONE; + /* to csi rawwr3, other rawwr also can use */ + if (fmt->pad == imx766->spd_id && mode->spd) { + fmt->format.width = mode->spd->width; + fmt->format.height = mode->spd->height; + fmt->format.code = mode->spd->bus_fmt; + //Set the vc channel to be consistent with the valid data + fmt->reserved[0] = 0; + } else if (fmt->pad == imx766->ebd_id && mode->ebd) { + fmt->format.width = mode->ebd->width; + fmt->format.height = mode->ebd->height; + fmt->format.code = mode->ebd->bus_fmt; + //Set the vc channel to be consistent with the valid data + fmt->reserved[0] = 0; + } + } + mutex_unlock(&imx766->mutex); + + return 0; +} + +static int imx766_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_mbus_code_enum *code) +{ + if (code->index != 0) + return -EINVAL; + code->code = MEDIA_BUS_FMT_SRGGB10_1X10; + + return 0; +} + +static int imx766_enum_frame_sizes(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_frame_size_enum *fse) +{ + if (fse->index >= ARRAY_SIZE(supported_modes)) + return -EINVAL; + + if (fse->code != MEDIA_BUS_FMT_SRGGB10_1X10) + 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 imx766_enable_test_pattern(struct imx766 *imx766, u32 pattern) +{ + u32 val; + + if (pattern) + val = (pattern - 1) | IMX766_TEST_PATTERN_ENABLE; + else + val = IMX766_TEST_PATTERN_DISABLE; + + return imx766_write_reg(imx766->client, + IMX766_REG_TEST_PATTERN, + IMX766_REG_VALUE_08BIT, + val); +} + +static int imx766_g_frame_interval(struct v4l2_subdev *sd, + struct v4l2_subdev_frame_interval *fi) +{ + struct imx766 *imx766 = to_imx766(sd); + const struct imx766_mode *mode = imx766->cur_mode; + + mutex_lock(&imx766->mutex); + fi->interval = mode->max_fps; + mutex_unlock(&imx766->mutex); + + return 0; +} + +static void imx766_get_otp(struct otp_info *otp, + struct rkmodule_inf *inf) +{ + u32 i, j; + u32 w, h; + + /* awb */ + if (otp->awb_data.flag) { + inf->awb.flag = 1; + inf->awb.r_value = otp->awb_data.r_ratio; + inf->awb.b_value = otp->awb_data.b_ratio; + inf->awb.gr_value = otp->awb_data.g_ratio; + inf->awb.gb_value = 0x0; + + inf->awb.golden_r_value = otp->awb_data.r_golden; + inf->awb.golden_b_value = otp->awb_data.b_golden; + inf->awb.golden_gr_value = otp->awb_data.g_golden; + inf->awb.golden_gb_value = 0x0; + } + + /* lsc */ + if (otp->lsc_data.flag) { + inf->lsc.flag = 1; + inf->lsc.width = otp->basic_data.size.width; + inf->lsc.height = otp->basic_data.size.height; + inf->lsc.table_size = otp->lsc_data.table_size; + + for (i = 0; i < 289; i++) { + inf->lsc.lsc_r[i] = (otp->lsc_data.data[i * 2] << 8) | + otp->lsc_data.data[i * 2 + 1]; + inf->lsc.lsc_gr[i] = (otp->lsc_data.data[i * 2 + 578] << 8) | + otp->lsc_data.data[i * 2 + 579]; + inf->lsc.lsc_gb[i] = (otp->lsc_data.data[i * 2 + 1156] << 8) | + otp->lsc_data.data[i * 2 + 1157]; + inf->lsc.lsc_b[i] = (otp->lsc_data.data[i * 2 + 1734] << 8) | + otp->lsc_data.data[i * 2 + 1735]; + } + } + + /* pdaf */ + if (otp->pdaf_data.flag) { + inf->pdaf.flag = 1; + inf->pdaf.gainmap_width = otp->pdaf_data.gainmap_width; + inf->pdaf.gainmap_height = otp->pdaf_data.gainmap_height; + inf->pdaf.dcc_mode = otp->pdaf_data.dcc_mode; + inf->pdaf.dcc_dir = otp->pdaf_data.dcc_dir; + inf->pdaf.dccmap_width = otp->pdaf_data.dccmap_width; + inf->pdaf.dccmap_height = otp->pdaf_data.dccmap_height; + w = otp->pdaf_data.gainmap_width; + h = otp->pdaf_data.gainmap_height; + for (i = 0; i < h; i++) { + for (j = 0; j < w; j++) { + inf->pdaf.gainmap[i * w + j] = + (otp->pdaf_data.gainmap[(i * w + j) * 2] << 8) | + otp->pdaf_data.gainmap[(i * w + j) * 2 + 1]; + } + } + w = otp->pdaf_data.dccmap_width; + h = otp->pdaf_data.dccmap_height; + for (i = 0; i < h; i++) { + for (j = 0; j < w; j++) { + inf->pdaf.dccmap[i * w + j] = + (otp->pdaf_data.dccmap[(i * w + j) * 2] << 8) | + otp->pdaf_data.dccmap[(i * w + j) * 2 + 1]; + } + } + } + + /* af */ + if (otp->af_data.flag) { + inf->af.flag = 1; + inf->af.dir_cnt = 1; + inf->af.af_otp[0].vcm_start = otp->af_data.af_inf; + inf->af.af_otp[0].vcm_end = otp->af_data.af_macro; + inf->af.af_otp[0].vcm_dir = 0; + } + +} + +static void imx766_get_module_inf(struct imx766 *imx766, + struct rkmodule_inf *inf) +{ + struct otp_info *otp = imx766->otp; + + memset(inf, 0, sizeof(*inf)); + strscpy(inf->base.sensor, IMX766_NAME, sizeof(inf->base.sensor)); + strscpy(inf->base.module, imx766->module_name, + sizeof(inf->base.module)); + strscpy(inf->base.lens, imx766->len_name, sizeof(inf->base.lens)); + if (otp) + imx766_get_otp(otp, inf); +} + +static int imx766_get_channel_info(struct imx766 *imx766, struct rkmodule_channel_info *ch_info) +{ + const struct imx766_mode *mode = imx766->cur_mode; + + if (ch_info->index < PAD0 || ch_info->index >= PAD_MAX) + return -EINVAL; + + if (ch_info->index == imx766->spd_id && mode->spd) { + ch_info->vc = 1; + ch_info->width = mode->spd->width; + ch_info->height = mode->spd->height; + ch_info->bus_fmt = mode->spd->bus_fmt; + ch_info->data_type = mode->spd->data_type; + ch_info->data_bit = mode->spd->data_bit; + } else { + ch_info->vc = imx766->cur_mode->vc[ch_info->index]; + ch_info->width = imx766->cur_mode->width; + ch_info->height = imx766->cur_mode->height; + ch_info->bus_fmt = imx766->cur_mode->bus_fmt; + } + return 0; +} + +static long imx766_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) +{ + struct imx766 *imx766 = to_imx766(sd); + struct rkmodule_hdr_cfg *hdr_cfg; + struct rkmodule_channel_info *ch_info; + long ret = 0; + u32 stream = 0; + u32 i, h, w; + + switch (cmd) { + case RKMODULE_SET_QUICK_STREAM: + + stream = *((u32 *)arg); + + if (stream) + ret = imx766_write_reg(imx766->client, + IMX766_REG_CTRL_MODE, + IMX766_REG_VALUE_08BIT, + IMX766_MODE_STREAMING); + else + ret = imx766_write_reg(imx766->client, + IMX766_REG_CTRL_MODE, + IMX766_REG_VALUE_08BIT, + IMX766_MODE_SW_STANDBY); + break; + case RKMODULE_SET_HDR_CFG: + hdr_cfg = (struct rkmodule_hdr_cfg *)arg; + w = imx766->cur_mode->width; + h = imx766->cur_mode->height; + for (i = 0; i < imx766->cfg_num; i++) { + if (w == supported_modes[i].width && + h == supported_modes[i].height && + supported_modes[i].hdr_mode == hdr_cfg->hdr_mode) { + imx766->cur_mode = &supported_modes[i]; + break; + } + } + if (i == imx766->cfg_num) { + dev_err(&imx766->client->dev, + "not find hdr mode:%d %dx%d config\n", + hdr_cfg->hdr_mode, w, h); + ret = -EINVAL; + } else { + w = imx766->cur_mode->hts_def - imx766->cur_mode->width; + h = imx766->cur_mode->vts_def - imx766->cur_mode->height; + __v4l2_ctrl_modify_range(imx766->hblank, w, w, 1, w); + __v4l2_ctrl_modify_range(imx766->vblank, h, + IMX766_VTS_MAX - imx766->cur_mode->height, + 1, h); + dev_info(&imx766->client->dev, + "sensor mode: %d\n", + imx766->cur_mode->hdr_mode); + } + break; + case RKMODULE_GET_HDR_CFG: + hdr_cfg = (struct rkmodule_hdr_cfg *)arg; + hdr_cfg->esp.mode = HDR_NORMAL_VC; + hdr_cfg->hdr_mode = imx766->cur_mode->hdr_mode; + break; + case RKMODULE_GET_MODULE_INFO: + imx766_get_module_inf(imx766, (struct rkmodule_inf *)arg); + break; + case RKMODULE_GET_CHANNEL_INFO: + ch_info = (struct rkmodule_channel_info *)arg; + ret = imx766_get_channel_info(imx766, ch_info); + break; + default: + ret = -ENOTTY; + break; + } + + return ret; +} + +#ifdef CONFIG_COMPAT +static long imx766_compat_ioctl32(struct v4l2_subdev *sd, + unsigned int cmd, unsigned long arg) +{ + void __user *up = compat_ptr(arg); + struct rkmodule_hdr_cfg *hdr; + struct rkmodule_inf *inf; + struct rkmodule_channel_info *ch_info; + long ret = 0; + u32 stream = 0; + + switch (cmd) { + case RKMODULE_GET_HDR_CFG: + hdr = kzalloc(sizeof(*hdr), GFP_KERNEL); + if (!hdr) { + ret = -ENOMEM; + return ret; + } + + ret = imx766_ioctl(sd, cmd, hdr); + if (!ret) { + ret = copy_to_user(up, hdr, sizeof(*hdr)); + if (ret) { + kfree(hdr); + return -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) { + kfree(hdr); + return -EFAULT; + } + ret = imx766_ioctl(sd, cmd, hdr); + kfree(hdr); + break; + case RKMODULE_SET_QUICK_STREAM: + ret = copy_from_user(&stream, up, sizeof(u32)); + if (ret) + return -EFAULT; + ret = imx766_ioctl(sd, cmd, &stream); + break; + case RKMODULE_GET_MODULE_INFO: + inf = kzalloc(sizeof(*inf), GFP_KERNEL); + if (!inf) { + ret = -ENOMEM; + return ret; + } + + ret = imx766_ioctl(sd, cmd, inf); + if (!ret) { + ret = copy_to_user(up, inf, sizeof(*inf)); + if (ret) + ret = -EFAULT; + } + kfree(inf); + break; + case RKMODULE_GET_CHANNEL_INFO: + ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL); + if (!ch_info) { + ret = -ENOMEM; + return ret; + } + ret = copy_from_user(ch_info, up, sizeof(*ch_info)); + if (!ret) { + ret = imx766_ioctl(sd, cmd, ch_info); + if (!ret) { + ret = copy_to_user(up, ch_info, sizeof(*ch_info)); + if (ret) + ret = -EFAULT; + } + } else { + ret = -EFAULT; + } + kfree(ch_info); + break; + default: + ret = -ENOTTY; + break; + } + return ret; +} +#endif + +/*--------------------------------------------------------------------------*/ + +#define IMX766_QSC_CONFIG_ADDR 0xC800 +#define IMX766_RD_QSC_KNOT_VALUE_OFFSET 0x86A9 +#define IMX766_QSC_EN 0x32D2 +static void imx766_config_qsc(struct imx766 *imx766) +{ + struct otp_info *otp = imx766->otp; + u8 *qsc_calib; + u32 i; + + if (otp && otp->qsc_data.flag) { + qsc_calib = &otp->qsc_data.qsc_calib[0]; + for (i = 0; i < 3072; i++) { + imx766_write_reg(imx766->client, IMX766_QSC_CONFIG_ADDR + i, + IMX766_REG_VALUE_08BIT, + qsc_calib[i]); + dev_dbg(&imx766->client->dev, + "set qscdata: qsc_calib[%d]: 0x%x\n", + i, qsc_calib[i]); + } + imx766_write_reg(imx766->client, IMX766_RD_QSC_KNOT_VALUE_OFFSET, + IMX766_REG_VALUE_08BIT, + 0x4E); + imx766_write_reg(imx766->client, IMX766_QSC_EN, + IMX766_REG_VALUE_08BIT, + 0x01); + } +} + +static int __imx766_start_stream(struct imx766 *imx766) +{ + int ret; + + ret = imx766_write_array(imx766->client, imx766->cur_mode->reg_list); + if (ret) + return ret; + + imx766_config_qsc(imx766); + + /* In case these controls are set before streaming */ + mutex_unlock(&imx766->mutex); + ret = v4l2_ctrl_handler_setup(&imx766->ctrl_handler); + mutex_lock(&imx766->mutex); + if (ret) + return ret; + + return imx766_write_reg(imx766->client, + IMX766_REG_CTRL_MODE, + IMX766_REG_VALUE_08BIT, + IMX766_MODE_STREAMING); +} + +static int __imx766_stop_stream(struct imx766 *imx766) +{ + return imx766_write_reg(imx766->client, + IMX766_REG_CTRL_MODE, + IMX766_REG_VALUE_08BIT, + IMX766_MODE_SW_STANDBY); +} + +static int imx766_s_stream(struct v4l2_subdev *sd, int on) +{ + struct imx766 *imx766 = to_imx766(sd); + struct i2c_client *client = imx766->client; + int ret = 0; + + mutex_lock(&imx766->mutex); + on = !!on; + if (on == imx766->streaming) + 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; + } + + ret = __imx766_start_stream(imx766); + if (ret) { + v4l2_err(sd, "start stream failed while write regs\n"); + pm_runtime_put(&client->dev); + goto unlock_and_return; + } + } else { + __imx766_stop_stream(imx766); + pm_runtime_put(&client->dev); + } + + imx766->streaming = on; + +unlock_and_return: + mutex_unlock(&imx766->mutex); + + return ret; +} + +static int imx766_s_power(struct v4l2_subdev *sd, int on) +{ + struct imx766 *imx766 = to_imx766(sd); + struct i2c_client *client = imx766->client; + int ret = 0; + + mutex_lock(&imx766->mutex); + + /* If the power state is not modified - no work to do. */ + if (imx766->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; + } + + ret = imx766_write_array(imx766->client, imx766_global_regs); + if (ret) { + v4l2_err(sd, "could not set init registers\n"); + pm_runtime_put_noidle(&client->dev); + goto unlock_and_return; + } + + imx766->power_on = true; + } else { + pm_runtime_put(&client->dev); + imx766->power_on = false; + } + +unlock_and_return: + mutex_unlock(&imx766->mutex); + + return ret; +} + +/* Calculate the delay in us by clock rate and clock cycles */ +static inline u32 imx766_cal_delay(u32 cycles) +{ + return DIV_ROUND_UP(cycles, IMX766_XVCLK_FREQ / 1000 / 1000); +} + +static int __imx766_power_on(struct imx766 *imx766) +{ + int ret; + u32 delay_us; + struct device *dev = &imx766->client->dev; + + if (!IS_ERR(imx766->power_gpio)) + gpiod_set_value_cansleep(imx766->power_gpio, 1); + usleep_range(10000, 12000); + + if (!IS_ERR_OR_NULL(imx766->pins_default)) { + ret = pinctrl_select_state(imx766->pinctrl, + imx766->pins_default); + if (ret < 0) + dev_err(dev, "could not set pins\n"); + } + ret = clk_set_rate(imx766->xvclk, IMX766_XVCLK_FREQ); + if (ret < 0) + dev_warn(dev, "Failed to set xvclk rate (24MHz)\n"); + if (clk_get_rate(imx766->xvclk) != IMX766_XVCLK_FREQ) + dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n"); + ret = clk_prepare_enable(imx766->xvclk); + if (ret < 0) { + dev_err(dev, "Failed to enable xvclk\n"); + return ret; + } + + if (!IS_ERR(imx766->reset_gpio)) + gpiod_set_value_cansleep(imx766->reset_gpio, 0); + usleep_range(10000, 12000); + + ret = regulator_bulk_enable(IMX766_NUM_SUPPLIES, imx766->supplies); + if (ret < 0) { + dev_err(dev, "Failed to enable regulators\n"); + goto disable_clk; + } + + if (!IS_ERR(imx766->reset_gpio)) + gpiod_set_value_cansleep(imx766->reset_gpio, 1); + + usleep_range(10000, 12000); + if (!IS_ERR(imx766->pwdn_gpio)) + gpiod_set_value_cansleep(imx766->pwdn_gpio, 1); + + /* 8192 cycles prior to first SCCB transaction */ + delay_us = imx766_cal_delay(8192); + usleep_range(delay_us, delay_us * 2); + + return 0; + +disable_clk: + clk_disable_unprepare(imx766->xvclk); + + return ret; +} + +static void __imx766_power_off(struct imx766 *imx766) +{ + int ret; + + if (!IS_ERR(imx766->power_gpio)) + gpiod_set_value_cansleep(imx766->power_gpio, 0); + + + if (!IS_ERR(imx766->pwdn_gpio)) + gpiod_set_value_cansleep(imx766->pwdn_gpio, 0); + clk_disable_unprepare(imx766->xvclk); + if (!IS_ERR(imx766->reset_gpio)) + gpiod_set_value_cansleep(imx766->reset_gpio, 0); + if (!IS_ERR_OR_NULL(imx766->pins_sleep)) { + ret = pinctrl_select_state(imx766->pinctrl, + imx766->pins_sleep); + if (ret < 0) + dev_dbg(&imx766->client->dev, "could not set pins\n"); + } + regulator_bulk_disable(IMX766_NUM_SUPPLIES, imx766->supplies); +} + +static int imx766_runtime_resume(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct imx766 *imx766 = to_imx766(sd); + + return __imx766_power_on(imx766); +} + +static int imx766_runtime_suspend(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct imx766 *imx766 = to_imx766(sd); + + __imx766_power_off(imx766); + + return 0; +} + +#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API +static int imx766_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) +{ + struct imx766 *imx766 = to_imx766(sd); + struct v4l2_mbus_framefmt *try_fmt = + v4l2_subdev_get_try_format(sd, fh->state, 0); + const struct imx766_mode *def_mode = &supported_modes[0]; + + mutex_lock(&imx766->mutex); + /* Initialize try_fmt */ + try_fmt->width = def_mode->width; + try_fmt->height = def_mode->height; + try_fmt->code = MEDIA_BUS_FMT_SRGGB10_1X10; + try_fmt->field = V4L2_FIELD_NONE; + + mutex_unlock(&imx766->mutex); + /* No crop or compose */ + + return 0; +} +#endif + +static int imx766_enum_frame_interval(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, + 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 int imx766_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id, + struct v4l2_mbus_config *config) +{ + config->type = V4L2_MBUS_CSI2_DPHY; + config->bus.mipi_csi2.num_data_lanes = IMX766_LANES; + + return 0; +} + +static const struct dev_pm_ops imx766_pm_ops = { + SET_RUNTIME_PM_OPS(imx766_runtime_suspend, + imx766_runtime_resume, NULL) +}; + +#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API +static const struct v4l2_subdev_internal_ops imx766_internal_ops = { + .open = imx766_open, +}; +#endif + +static const struct v4l2_subdev_core_ops imx766_core_ops = { + .s_power = imx766_s_power, + .ioctl = imx766_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl32 = imx766_compat_ioctl32, +#endif +}; + +static const struct v4l2_subdev_video_ops imx766_video_ops = { + .s_stream = imx766_s_stream, + .g_frame_interval = imx766_g_frame_interval, +}; + +static const struct v4l2_subdev_pad_ops imx766_pad_ops = { + .enum_mbus_code = imx766_enum_mbus_code, + .enum_frame_size = imx766_enum_frame_sizes, + .enum_frame_interval = imx766_enum_frame_interval, + .get_fmt = imx766_get_fmt, + .set_fmt = imx766_set_fmt, + .get_mbus_config = imx766_g_mbus_config, +}; + +static const struct v4l2_subdev_ops imx766_subdev_ops = { + .core = &imx766_core_ops, + .video = &imx766_video_ops, + .pad = &imx766_pad_ops, +}; + +static int imx766_set_gain_reg(struct imx766 *imx766, u32 a_gain) +{ + int ret = 0; + u32 gain_reg = 0; + + gain_reg = (16384 - (16384*1024 / a_gain)); + + if (gain_reg > 16128) //960 + gain_reg = 16128; + + ret = imx766_write_reg(imx766->client, + IMX766_REG_GAIN_H, + IMX766_REG_VALUE_08BIT, + ((gain_reg & 0x3f00) >> 8)); + ret |= imx766_write_reg(imx766->client, + IMX766_REG_GAIN_L, + IMX766_REG_VALUE_08BIT, + (gain_reg & 0xff)); + return ret; +} + +static int imx766_set_ctrl(struct v4l2_ctrl *ctrl) +{ + struct imx766 *imx766 = container_of(ctrl->handler, + struct imx766, ctrl_handler); + struct i2c_client *client = imx766->client; + s64 max; + int ret = 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 = imx766->cur_mode->height + ctrl->val - 4; + __v4l2_ctrl_modify_range(imx766->exposure, + imx766->exposure->minimum, max, + imx766->exposure->step, + imx766->exposure->default_value); + break; + } + + if (!pm_runtime_get_if_in_use(&client->dev)) + return 0; + + switch (ctrl->id) { + case V4L2_CID_EXPOSURE: + /* 4 least significant bits of expsoure are fractional part */ + ret = imx766_write_reg(imx766->client, + IMX766_REG_EXPOSURE, + IMX766_REG_VALUE_16BIT, + ctrl->val); + + break; + case V4L2_CID_ANALOGUE_GAIN: + ret = imx766_set_gain_reg(imx766, ctrl->val); + break; + case V4L2_CID_VBLANK: + ret = imx766_write_reg(imx766->client, + IMX766_REG_VTS, + IMX766_REG_VALUE_16BIT, + ctrl->val + imx766->cur_mode->height); + break; + case V4L2_CID_TEST_PATTERN: + ret = imx766_enable_test_pattern(imx766, 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 imx766_ctrl_ops = { + .s_ctrl = imx766_set_ctrl, +}; + +static int imx766_initialize_controls(struct imx766 *imx766) +{ + const struct imx766_mode *mode; + struct v4l2_ctrl_handler *handler; + s64 exposure_max, vblank_def; + u32 h_blank; + int ret; + + handler = &imx766->ctrl_handler; + mode = imx766->cur_mode; + ret = v4l2_ctrl_handler_init(handler, 8); + if (ret) + return ret; + handler->lock = &imx766->mutex; + + imx766->link_freq = v4l2_ctrl_new_int_menu(handler, NULL, + V4L2_CID_LINK_FREQ, 1, 0, + link_freq_menu_items); + + imx766->pixel_rate = v4l2_ctrl_new_std(handler, NULL, + V4L2_CID_PIXEL_RATE, 0, IMX766_PIXEL_RATE_BINNING, + 1, IMX766_PIXEL_RATE_BINNING); + + h_blank = mode->hts_def - mode->width; + imx766->hblank = v4l2_ctrl_new_std(handler, NULL, + V4L2_CID_HBLANK, h_blank, h_blank, 1, h_blank); + if (imx766->hblank) + imx766->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; + + vblank_def = mode->vts_def - mode->height; + imx766->vblank = v4l2_ctrl_new_std(handler, &imx766_ctrl_ops, + V4L2_CID_VBLANK, vblank_def, + IMX766_VTS_MAX - mode->height, + 1, vblank_def); + + exposure_max = mode->vts_def - 4; + imx766->exposure = v4l2_ctrl_new_std(handler, &imx766_ctrl_ops, + V4L2_CID_EXPOSURE, IMX766_EXPOSURE_MIN, + exposure_max, IMX766_EXPOSURE_STEP, + mode->exp_def); + + imx766->anal_gain = v4l2_ctrl_new_std(handler, &imx766_ctrl_ops, + V4L2_CID_ANALOGUE_GAIN, IMX766_GAIN_MIN, + IMX766_GAIN_MAX, IMX766_GAIN_STEP, + IMX766_GAIN_DEFAULT); + + imx766->test_pattern = v4l2_ctrl_new_std_menu_items(handler, + &imx766_ctrl_ops, V4L2_CID_TEST_PATTERN, + ARRAY_SIZE(imx766_test_pattern_menu) - 1, + 0, 0, imx766_test_pattern_menu); + + if (handler->error) { + ret = handler->error; + dev_err(&imx766->client->dev, + "Failed to init controls(%d)\n", ret); + goto err_free_handler; + } + + imx766->subdev.ctrl_handler = handler; + + return 0; + +err_free_handler: + v4l2_ctrl_handler_free(handler); + + return ret; +} + +static int imx766_check_sensor_id(struct imx766 *imx766, + struct i2c_client *client) +{ + struct device *dev = &imx766->client->dev; + int ret = 0; + u32 id = 0; + int i; + + for (i = 0; i < 5; i++) { + ret = imx766_read_reg(client, IMX766_REG_CHIP_ID, + IMX766_REG_VALUE_16BIT, &id); + if (id == CHIP_ID) + break; + usleep_range(300, 1500); + } + if (id != CHIP_ID) { + dev_err(dev, "Unexpected sensor id(%06x), ret(%d)\n", id, ret); + return -ENODEV; + } + + return 0; +} + +static int imx766_configure_regulators(struct imx766 *imx766) +{ + unsigned int i; + + for (i = 0; i < IMX766_NUM_SUPPLIES; i++) + imx766->supplies[i].supply = imx766_supply_names[i]; + + return devm_regulator_bulk_get(&imx766->client->dev, + IMX766_NUM_SUPPLIES, + imx766->supplies); +} + +static int imx766_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct device *dev = &client->dev; + struct device_node *node = dev->of_node; + struct imx766 *imx766; + struct v4l2_subdev *sd; + char facing[2]; + struct device_node *eeprom_ctrl_node; + struct i2c_client *eeprom_ctrl_client; + struct v4l2_subdev *eeprom_ctrl; + struct otp_info *otp_ptr; + int ret; + + dev_info(dev, "driver version: %02x.%02x.%02x", + DRIVER_VERSION >> 16, + (DRIVER_VERSION & 0xff00) >> 8, + DRIVER_VERSION & 0x00ff); + + imx766 = devm_kzalloc(dev, sizeof(*imx766), GFP_KERNEL); + if (!imx766) + return -ENOMEM; + + ret = of_property_read_u32(node, RKMODULE_CAMERA_MODULE_INDEX, + &imx766->module_index); + ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_FACING, + &imx766->module_facing); + ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_NAME, + &imx766->module_name); + ret |= of_property_read_string(node, RKMODULE_CAMERA_LENS_NAME, + &imx766->len_name); + if (ret) { + dev_err(dev, "could not get module information!\n"); + return -EINVAL; + } + + imx766->client = client; + imx766->cfg_num = ARRAY_SIZE(supported_modes); + imx766->cur_mode = &supported_modes[0]; + + imx766->xvclk = devm_clk_get(dev, "xvclk"); + if (IS_ERR(imx766->xvclk)) { + dev_err(dev, "Failed to get xvclk\n"); + return -EINVAL; + } + + imx766->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(imx766->reset_gpio)) + dev_warn(dev, "Failed to get reset-gpios\n"); + + imx766->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW); + if (IS_ERR(imx766->pwdn_gpio)) + dev_warn(dev, "Failed to get pwdn-gpios\n"); + + imx766->power_gpio = devm_gpiod_get(dev, "power", GPIOD_OUT_LOW); + if (IS_ERR(imx766->power_gpio)) + dev_warn(dev, "Failed to get power-gpios\n"); + + + ret = of_property_read_u32(node, + "rockchip,spd-id", + &imx766->spd_id); + if (ret != 0) { + imx766->spd_id = PAD_MAX; + dev_err(dev, + "failed get spd_id, will not to use spd\n"); + } + ret = of_property_read_u32(node, + "rockchip,ebd-id", + &imx766->ebd_id); + if (ret != 0) { + imx766->ebd_id = PAD_MAX; + dev_err(dev, + "failed get ebd_id, will not to use ebd\n"); + } + + ret = imx766_configure_regulators(imx766); + if (ret) { + dev_err(dev, "Failed to get power regulators\n"); + return ret; + } + + imx766->pinctrl = devm_pinctrl_get(dev); + if (!IS_ERR(imx766->pinctrl)) { + imx766->pins_default = + pinctrl_lookup_state(imx766->pinctrl, + OF_CAMERA_PINCTRL_STATE_DEFAULT); + if (IS_ERR(imx766->pins_default)) + dev_err(dev, "could not get default pinstate\n"); + + imx766->pins_sleep = + pinctrl_lookup_state(imx766->pinctrl, + OF_CAMERA_PINCTRL_STATE_SLEEP); + if (IS_ERR(imx766->pins_sleep)) + dev_err(dev, "could not get sleep pinstate\n"); + } + + mutex_init(&imx766->mutex); + + sd = &imx766->subdev; + v4l2_i2c_subdev_init(sd, client, &imx766_subdev_ops); + ret = imx766_initialize_controls(imx766); + if (ret) + goto err_destroy_mutex; + + ret = __imx766_power_on(imx766); + if (ret) + goto err_free_handler; + + ret = imx766_check_sensor_id(imx766, client); + if (ret) + goto err_power_off; + + eeprom_ctrl_node = of_parse_phandle(node, "eeprom-ctrl", 0); + if (eeprom_ctrl_node) { + eeprom_ctrl_client = + of_find_i2c_device_by_node(eeprom_ctrl_node); + of_node_put(eeprom_ctrl_node); + if (IS_ERR_OR_NULL(eeprom_ctrl_client)) { + dev_err(dev, "can not get node\n"); + goto continue_probe; + } + eeprom_ctrl = i2c_get_clientdata(eeprom_ctrl_client); + if (IS_ERR_OR_NULL(eeprom_ctrl)) { + dev_err(dev, "can not get eeprom i2c client\n"); + } else { + otp_ptr = devm_kzalloc(dev, sizeof(*otp_ptr), GFP_KERNEL); + if (!otp_ptr) + return -ENOMEM; + ret = v4l2_subdev_call(eeprom_ctrl, + core, ioctl, 0, otp_ptr); + if (!ret) { + imx766->otp = otp_ptr; + } else { + imx766->otp = NULL; + devm_kfree(dev, otp_ptr); + } + } + } + +continue_probe: + +#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API + sd->internal_ops = &imx766_internal_ops; + sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | + V4L2_SUBDEV_FL_HAS_EVENTS; +#endif +#if defined(CONFIG_MEDIA_CONTROLLER) + imx766->pad.flags = MEDIA_PAD_FL_SOURCE; + sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; + ret = media_entity_pads_init(&sd->entity, 1, &imx766->pad); + if (ret < 0) + goto err_power_off; +#endif + + memset(facing, 0, sizeof(facing)); + if (strcmp(imx766->module_facing, "back") == 0) + facing[0] = 'b'; + else + facing[0] = 'f'; + + snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s %s", + imx766->module_index, facing, + IMX766_NAME, dev_name(sd->dev)); + ret = v4l2_async_register_subdev_sensor(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); + pm_runtime_idle(dev); + + return 0; + +err_clean_entity: +#if defined(CONFIG_MEDIA_CONTROLLER) + media_entity_cleanup(&sd->entity); +#endif +err_power_off: + __imx766_power_off(imx766); +err_free_handler: + v4l2_ctrl_handler_free(&imx766->ctrl_handler); +err_destroy_mutex: + mutex_destroy(&imx766->mutex); + + return ret; +} + +static void imx766_remove(struct i2c_client *client) +{ + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct imx766 *imx766 = to_imx766(sd); + + v4l2_async_unregister_subdev(sd); +#if defined(CONFIG_MEDIA_CONTROLLER) + media_entity_cleanup(&sd->entity); +#endif + v4l2_ctrl_handler_free(&imx766->ctrl_handler); + mutex_destroy(&imx766->mutex); + + pm_runtime_disable(&client->dev); + if (!pm_runtime_status_suspended(&client->dev)) + __imx766_power_off(imx766); + pm_runtime_set_suspended(&client->dev); +} + +#if IS_ENABLED(CONFIG_OF) +static const struct of_device_id imx766_of_match[] = { + { .compatible = "sony,imx766" }, + {}, +}; +MODULE_DEVICE_TABLE(of, imx766_of_match); +#endif + +static const struct i2c_device_id imx766_match_id[] = { + { "sony,imx766", 0 }, + { }, +}; + +static struct i2c_driver imx766_i2c_driver = { + .driver = { + .name = IMX766_NAME, + .pm = &imx766_pm_ops, + .of_match_table = of_match_ptr(imx766_of_match), + }, + .probe = &imx766_probe, + .remove = &imx766_remove, + .id_table = imx766_match_id, +}; + +static int __init sensor_mod_init(void) +{ + return i2c_add_driver(&imx766_i2c_driver); +} + +static void __exit sensor_mod_exit(void) +{ + i2c_del_driver(&imx766_i2c_driver); +} + +device_initcall_sync(sensor_mod_init); +module_exit(sensor_mod_exit); + +MODULE_DESCRIPTION("Sony imx766 sensor driver"); +MODULE_LICENSE("GPL"); From 25e7edd1046376ac24caafd8c4f8d22603b9a6dc Mon Sep 17 00:00:00 2001 From: Jason Zhu Date: Tue, 25 Mar 2025 09:51:52 +0800 Subject: [PATCH 42/57] ASoC: rockchip: asrc: support rv1126b asrc 1.Support 32bit data format. 2.Get the real lrck frequency. 3.Disable the lrck filt. Change-Id: I51aeb6888185568d067046397fd8339fbd366f0b Signed-off-by: Jason Zhu --- sound/soc/rockchip/rockchip_asrc.c | 56 ++++++++++++++++++++++-------- sound/soc/rockchip/rockchip_asrc.h | 10 ++++++ 2 files changed, 52 insertions(+), 14 deletions(-) diff --git a/sound/soc/rockchip/rockchip_asrc.c b/sound/soc/rockchip/rockchip_asrc.c index b7d708f920e7..2dd6ef10be1a 100644 --- a/sound/soc/rockchip/rockchip_asrc.c +++ b/sound/soc/rockchip/rockchip_asrc.c @@ -22,6 +22,8 @@ #include "rockchip_asrc.h" +#define RV1126B_ASRC 0x04000000 + /* * structure: * tx: memory->asrc->sai->codec @@ -42,6 +44,7 @@ #define MAXBURST_PER_FIFO 8 #define DEFAULT_SAMPLE_RATE 48000 #define ASRC_DEFAULT_CLK 200000000 +#define ASRC_LRCK_SOURCE_FREQ_DEFAULT 98304000 /* Platform Definition */ /* rk3576 */ @@ -182,7 +185,6 @@ struct rk_asrc_soc_data { int (*lrck_clk_set)(struct device *dev); int (*lrck_clk_en)(struct device *dev); int (*lrck_clk_dis)(struct device *dev); - int lrck_source_freq; }; struct rockchip_asrc_pair { @@ -223,6 +225,9 @@ struct rockchip_asrc { int resample_rate; int dst_link_dai_id; /* This must be set firstly by amixer/tinymixer */ int src_link_dai_id; /* This must be set firstly by amixer/tinymixer */ + int lrck_src_freq; + int lrck_dst_freq; + int version; }; static int rockchip_asrc_calculate_ratio(struct rockchip_asrc *asrc, @@ -405,9 +410,15 @@ static int rockchip_asrc_hw_params(struct snd_pcm_substream *substream, asrc->sample_bits = 16; break; case SNDRV_PCM_FORMAT_S24_LE: + val = ASRC_IWL_24BIT | ASRC_OWL_24BIT | + ASRC_OFMT_32 | ASRC_IFMT_32 | + ASRC_ISJM(0) | ASRC_OSJM(0); + asrc->sample_bits = 32; + break; case SNDRV_PCM_FORMAT_S32_LE: val = ASRC_IWL_24BIT | ASRC_OWL_24BIT | - ASRC_OFMT_32 | ASRC_IFMT_32; + ASRC_OFMT_32 | ASRC_IFMT_32 | + ASRC_ISJM(8) | ASRC_OSJM(8); asrc->sample_bits = 32; break; default: @@ -528,6 +539,7 @@ static bool rockchip_asrc_readable_reg(struct device *dev, unsigned int reg) case ASRC_LRCK_MARGIN: case ASRC_FETCH_LEN: case ASRC_DMA_THRESH: + case ASRC_LRCK_FILT: case ASRC_INT_CON: case ASRC_INT_ST: case ASRC_ST: @@ -564,6 +576,7 @@ static bool rockchip_asrc_writeable_reg(struct device *dev, unsigned int reg) case ASRC_LRCK_MARGIN: case ASRC_FETCH_LEN: case ASRC_DMA_THRESH: + case ASRC_LRCK_FILT: case ASRC_INT_CON: case ASRC_INT_ST: case ASRC_FIFO_IN_WRCNT: @@ -1141,6 +1154,11 @@ static int rockchip_asrc_init(struct rockchip_asrc *asrc) ASRC_RATIO_TRACK_DIV_MSK | ASRC_RATIO_TRACK_PERIOD_MSK, ASRC_RATIO_TRACK_DIV(3) | ASRC_RATIO_TRACK_PERIOD(1023)); + if (asrc->version == RV1126B_ASRC) { + regmap_update_bits(asrc->regmap, ASRC_LRCK_FILT, + ASRC_LRCK_FILT_MSK, ASRC_LRCK_FILT_DIS); + } + return 0; } @@ -1290,7 +1308,7 @@ static void rockchip_asrc_lrck_div_set(struct rockchip_asrc *asrc) switch (asrc->src_link_dai_id) { case DAI_ID_ASRC0 ... DAI_ID_ASRC15: - src_lrck_div = asrc->soc_data->lrck_source_freq / asrc->sample_rate; + src_lrck_div = asrc->lrck_src_freq / asrc->sample_rate; break; case DAI_ID_SPDIF_TX0 ... DAI_ID_SPDIF_RX7: src_lrck_div = 128; @@ -1301,7 +1319,7 @@ static void rockchip_asrc_lrck_div_set(struct rockchip_asrc *asrc) switch (asrc->dst_link_dai_id) { case DAI_ID_ASRC0 ... DAI_ID_ASRC15: - dst_lrck_div = asrc->soc_data->lrck_source_freq / asrc->resample_rate; + dst_lrck_div = asrc->lrck_dst_freq / asrc->resample_rate; break; case DAI_ID_SPDIF_TX0 ... DAI_ID_SPDIF_RX7: dst_lrck_div = 128; @@ -1381,19 +1399,24 @@ static int rk3506_asrc_lrck_clk_set(struct device *dev) clk_set_parent(asrc->src_lrck, asrc->src_lrck_parent); clk_set_parent(asrc->dst_lrck, asrc->dst_lrck_parent); if (rockchip_asrc_is_link_mem(asrc->src_link_dai_id)) { - if (clk_set_rate(asrc->src_lrck_parent, asrc->soc_data->lrck_source_freq)) { + if (clk_set_rate(asrc->src_lrck_parent, asrc->lrck_src_freq)) { dev_err(asrc->dev, "Failed to set src_lrck_parent, freq is %d\n", - asrc->soc_data->lrck_source_freq); + asrc->lrck_src_freq); return -EINVAL; } + + asrc->lrck_src_freq = clk_get_rate(asrc->src_lrck_parent); } if (rockchip_asrc_is_link_mem(asrc->dst_link_dai_id)) { - if (clk_set_rate(asrc->dst_lrck_parent, asrc->soc_data->lrck_source_freq)) { + if (clk_set_rate(asrc->dst_lrck_parent, asrc->lrck_dst_freq)) { dev_err(asrc->dev, "Failed to set dst_lrck_parent, freq is %d\n", - asrc->soc_data->lrck_source_freq); + asrc->lrck_dst_freq); return -EINVAL; } + + /* get the real freq */ + asrc->lrck_dst_freq = clk_get_rate(asrc->dst_lrck_parent); } rockchip_asrc_lrck_div_set(asrc); @@ -1612,19 +1635,23 @@ static int rk3576_asrc_lrck_clk_set(struct device *dev) } if (rockchip_asrc_is_link_mem(asrc->src_link_dai_id)) { - if (clk_set_rate(asrc->cru_src0, asrc->soc_data->lrck_source_freq)) { + if (clk_set_rate(asrc->cru_src0, asrc->lrck_src_freq)) { dev_err(asrc->dev, "Failed to set cru_src0, freq is %d\n", - asrc->soc_data->lrck_source_freq); + asrc->lrck_src_freq); return -EINVAL; } + + asrc->lrck_src_freq = clk_get_rate(asrc->cru_src0); } if (rockchip_asrc_is_link_mem(asrc->dst_link_dai_id)) { - if (clk_set_rate(asrc->cru_src1, asrc->soc_data->lrck_source_freq)) { + if (clk_set_rate(asrc->cru_src1, asrc->lrck_dst_freq)) { dev_err(asrc->dev, "Failed to set cru_src1, freq is %d\n", - asrc->soc_data->lrck_source_freq); + asrc->lrck_dst_freq); return -EINVAL; } + + asrc->lrck_dst_freq = clk_get_rate(asrc->cru_src1); } rockchip_asrc_lrck_div_set(asrc); @@ -1664,7 +1691,6 @@ static const struct rk_asrc_soc_data rk3506_data = { .lrck_clk_set = rk3506_asrc_lrck_clk_set, .lrck_clk_en = rk3506_asrc_lrck_clk_en, .lrck_clk_dis = rk3506_asrc_lrck_clk_dis, - .lrck_source_freq = 98304000, }; static const struct rk_asrc_soc_data rk3576_data = { @@ -1672,7 +1698,6 @@ static const struct rk_asrc_soc_data rk3576_data = { .lrck_clk_set = rk3576_asrc_lrck_clk_set, .lrck_clk_en = rk3576_asrc_lrck_clk_en, .lrck_clk_dis = rk3576_asrc_lrck_clk_dis, - .lrck_source_freq = 49152000, }; static const struct of_device_id rockchip_asrc_match[] = { @@ -1694,6 +1719,8 @@ static int rockchip_asrc_probe(struct platform_device *pdev) if (!asrc) return -ENOMEM; + asrc->lrck_src_freq = ASRC_LRCK_SOURCE_FREQ_DEFAULT; + asrc->lrck_dst_freq = ASRC_LRCK_SOURCE_FREQ_DEFAULT; asrc->dev = &pdev->dev; asrc->pdev = pdev; dev_set_drvdata(&pdev->dev, asrc); @@ -1770,6 +1797,7 @@ static int rockchip_asrc_probe(struct platform_device *pdev) if (ret < 0) goto err_runtime_suspend; + regmap_read(asrc->regmap, ASRC_VERSION, &asrc->version); ret = rockchip_asrc_init(asrc); if (ret) { dev_err(&pdev->dev, "Asrc init error.\n"); diff --git a/sound/soc/rockchip/rockchip_asrc.h b/sound/soc/rockchip/rockchip_asrc.h index 383adcb16df8..15887e164280 100644 --- a/sound/soc/rockchip/rockchip_asrc.h +++ b/sound/soc/rockchip/rockchip_asrc.h @@ -23,6 +23,7 @@ #define ASRC_LRCK_MARGIN 0x0034 #define ASRC_FETCH_LEN 0x0040 #define ASRC_DMA_THRESH 0x0050 +#define ASRC_LRCK_FILT 0x0058 #define ASRC_INT_CON 0x0060 #define ASRC_INT_ST 0x0064 #define ASRC_ST 0x0070 @@ -124,6 +125,15 @@ #define ASRC_DMA_TX_THRESH_MSK (0xf << 0) #define ASRC_DMA_TX_THRESH(x) (x << 0) +/**********************ASRC_LRCK_FILT************************/ +#define ASRC_LRCK_DRIFT_MARGIN_MSK (0x7ff << 0) +#define ASRC_LRCK_DRIFT_MARGIN(x) (x << 0) +#define ASRC_LRCK_SUPER_MARGIN_MSK (0x7ff << 16) +#define ASRC_LRCK_SUPER_MARGIN(x) (x << 16) +#define ASRC_LRCK_FILT_MSK (0x1 << 31) +#define ASRC_LRCK_FILT_EN (0x1 << 31) +#define ASRC_LRCK_FILT_DIS (0x0 << 31) + /**********************ASRC_INT_CON************************/ #define ASRC_DST_LRCK_UNLOCK_MSK (0x1 << 12) #define ASRC_DST_LRCK_UNLOCK_EN (0x1 << 12) From f5a90370049999aed16acc9db0628f1cf4504f38 Mon Sep 17 00:00:00 2001 From: Zefa Chen Date: Mon, 31 Mar 2025 17:17:35 +0800 Subject: [PATCH 43/57] media: rockchip: vicap fixes error of sensor power cnt Change-Id: Ida5e7513c54dea465f2b90c1d2ba7d8922f88f17 Signed-off-by: Zefa Chen --- drivers/media/platform/rockchip/cif/capture.c | 16 +++++++++++----- drivers/media/platform/rockchip/cif/dev.c | 1 + drivers/media/platform/rockchip/cif/dev.h | 3 +++ drivers/media/platform/rockchip/cif/subdev-itf.c | 1 + 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/drivers/media/platform/rockchip/cif/capture.c b/drivers/media/platform/rockchip/cif/capture.c index 6fda40cdc31e..49a80dadd7d1 100644 --- a/drivers/media/platform/rockchip/cif/capture.c +++ b/drivers/media/platform/rockchip/cif/capture.c @@ -8561,7 +8561,7 @@ int rkcif_do_start_stream(struct rkcif_stream *stream, enum rkcif_stream_mode mo } } if (dev->chip_id >= CHIP_RK1808_CIF) { - if (dev->active_sensor && + if (dev->active_sensor && (dev->active_sensor->mbus.type == V4L2_MBUS_CSI2_DPHY || dev->active_sensor->mbus.type == V4L2_MBUS_CSI2_CPHY || dev->active_sensor->mbus.type == V4L2_MBUS_CCP2)) { @@ -8997,12 +8997,18 @@ void rkcif_stream_init(struct rkcif_device *dev, u32 id) stream->frame_loss = 0; } -static int rkcif_sensor_set_power(struct rkcif_stream *stream, int on) +int rkcif_sensor_set_power(struct rkcif_stream *stream, int on) { struct rkcif_device *cif_dev = stream->cifdev; struct sditf_priv *priv = cif_dev->sditf[0]; int i = 0; + if (!on && atomic_dec_if_positive(&cif_dev->sd_power_cnt)) + return 0; + + if (on && atomic_inc_return(&cif_dev->sd_power_cnt) > 1) + return 0; + if (cif_dev->terminal_sensor.sd) v4l2_subdev_call(cif_dev->terminal_sensor.sd, core, s_power, on); @@ -9068,11 +9074,11 @@ static int rkcif_fh_open(struct file *filp) ret = v4l2_pipeline_pm_get(&vnode->vdev.entity); v4l2_dbg(1, rkcif_debug, vdev, "open video, entity use_count %d\n", vnode->vdev.entity.use_count); + ret = rkcif_sensor_set_power(stream, on); mutex_unlock(&cifdev->stream_lock); if (ret < 0) vb2_fop_release(filp); } - ret = rkcif_sensor_set_power(stream, on); return ret; } @@ -9088,6 +9094,7 @@ static int rkcif_fh_release(struct file *filp) ret = vb2_fop_release(filp); if (!ret) { mutex_lock(&cifdev->stream_lock); + ret = rkcif_sensor_set_power(stream, on); v4l2_pipeline_pm_put(&vnode->vdev.entity); v4l2_dbg(1, rkcif_debug, vdev, "close video, entity use_count %d\n", vnode->vdev.entity.use_count); @@ -9095,7 +9102,6 @@ static int rkcif_fh_release(struct file *filp) } pm_runtime_put_sync(cifdev->dev); - ret = rkcif_sensor_set_power(stream, on); return ret; } @@ -10819,7 +10825,7 @@ void rkcif_irq_oneframe(struct rkcif_device *cif_dev) /* There are two irqs enabled: * - PST_INF_FRAME_END: cif FIFO is ready, this is prior to FRAME_END - * - FRAME_END: cif has saved frame to memory, a frame ready + * - FRAME_END: cif has saved frame to memory, a frame ready */ stream = &cif_dev->stream[RKCIF_STREAM_CIF]; diff --git a/drivers/media/platform/rockchip/cif/dev.c b/drivers/media/platform/rockchip/cif/dev.c index 24b33d0ec9ee..27d7a3da08ca 100644 --- a/drivers/media/platform/rockchip/cif/dev.c +++ b/drivers/media/platform/rockchip/cif/dev.c @@ -2876,6 +2876,7 @@ int rkcif_plat_init(struct rkcif_device *cif_dev, struct device_node *node, int atomic_set(&cif_dev->power_cnt, 0); atomic_set(&cif_dev->streamoff_cnt, 0); atomic_set(&cif_dev->sensor_off, 1); + atomic_set(&cif_dev->sd_power_cnt, 0); cif_dev->is_start_hdr = false; cif_dev->pipe.open = rkcif_pipeline_open; cif_dev->pipe.close = rkcif_pipeline_close; diff --git a/drivers/media/platform/rockchip/cif/dev.h b/drivers/media/platform/rockchip/cif/dev.h index 67bebcee90c9..89522611533e 100644 --- a/drivers/media/platform/rockchip/cif/dev.h +++ b/drivers/media/platform/rockchip/cif/dev.h @@ -967,6 +967,7 @@ struct rkcif_device { atomic_t power_cnt; atomic_t streamoff_cnt; atomic_t sensor_off; + atomic_t sd_power_cnt; struct mutex stream_lock; /* lock between streams */ struct mutex scale_lock; /* lock between scale dev */ struct mutex tools_lock; /* lock between tools dev */ @@ -1179,4 +1180,6 @@ void rkcif_modify_line_int(struct rkcif_stream *stream, bool en); void rkcif_set_sof(struct rkcif_device *cif_dev, u32 seq); void rkcif_set_sensor_streamon_in_sync_mode(struct rkcif_device *cif_dev); +int rkcif_sensor_set_power(struct rkcif_stream *stream, int on); + #endif diff --git a/drivers/media/platform/rockchip/cif/subdev-itf.c b/drivers/media/platform/rockchip/cif/subdev-itf.c index ec01bfd83c0e..d88c1f1ddeca 100644 --- a/drivers/media/platform/rockchip/cif/subdev-itf.c +++ b/drivers/media/platform/rockchip/cif/subdev-itf.c @@ -1244,6 +1244,7 @@ static int sditf_s_power(struct v4l2_subdev *sd, int on) pm_runtime_put_sync(cif_dev->dev); priv->mode.rdbk_mode = RKISP_VICAP_RDBK_AIQ; } + ret |= rkcif_sensor_set_power(&cif_dev->stream[0], on); v4l2_dbg(1, rkcif_debug, &node->vdev, "s_power %d, entity use_count %d\n", on, node->vdev.entity.use_count); mutex_unlock(&cif_dev->stream_lock); From de6d4897ec3a3cd6c45017860bbac2dac7ae3c40 Mon Sep 17 00:00:00 2001 From: Zefa Chen Date: Mon, 31 Mar 2025 17:23:19 +0800 Subject: [PATCH 44/57] media: rockchip: vicap fixes error of proc info Change-Id: I335d4b8c140864ffb9143005b77adc9b635052f1 Signed-off-by: Zefa Chen --- drivers/media/platform/rockchip/cif/capture.c | 10 ++++-- drivers/media/platform/rockchip/cif/procfs.c | 34 +++++++++---------- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/drivers/media/platform/rockchip/cif/capture.c b/drivers/media/platform/rockchip/cif/capture.c index 49a80dadd7d1..be3d39a21926 100644 --- a/drivers/media/platform/rockchip/cif/capture.c +++ b/drivers/media/platform/rockchip/cif/capture.c @@ -11976,6 +11976,7 @@ static void rkcif_update_stream(struct rkcif_device *cif_dev, mipi_id); if (ret && cif_dev->chip_id < CHIP_RK3588_CIF) return; + stream->last_frame_idx = stream->frame_idx; } else { ret = rkcif_update_new_buffer_wake_up_mode(stream); if (ret && cif_dev->chip_id < CHIP_RK3588_CIF) @@ -13608,6 +13609,12 @@ static void rkcif_toisp_check_stop_status(struct sditf_priv *priv, stream->stopping = false; wake_up(&stream->wq_stopped); } + if (!(stream->cur_stream_mode & RKCIF_STREAM_MODE_CAPTURE)) { + cur_time = rkcif_time_get_ns(stream->cifdev); + stream->readout.total_time = cur_time - stream->readout.fe_timestamp; + stream->readout.readout_time = cur_time - stream->readout.fs_timestamp; + stream->readout.fe_timestamp = cur_time; + } spin_lock_irqsave(&stream->cifdev->stream_spinlock, flags); if (stream->is_wait_stop_complete) { @@ -13753,9 +13760,6 @@ static void rkcif_toisp_check_stop_status(struct sditf_priv *priv, (priv->hdr_cfg.hdr_mode == HDR_X2 && stream->id == 1) || (priv->hdr_cfg.hdr_mode == HDR_X3 && stream->id == 2))) sditf_disable_immediately(priv); - cur_time = rkcif_time_get_ns(stream->cifdev); - stream->readout.total_time = cur_time - stream->readout.fs_timestamp; - stream->readout.fs_timestamp = cur_time; stream->buf_wake_up_cnt++; if (stream->frame_idx % 2) stream->fps_stats.frm0_timestamp = rkcif_time_get_ns(stream->cifdev); diff --git a/drivers/media/platform/rockchip/cif/procfs.c b/drivers/media/platform/rockchip/cif/procfs.c index 83fbb65c9de3..1956020b1f75 100644 --- a/drivers/media/platform/rockchip/cif/procfs.c +++ b/drivers/media/platform/rockchip/cif/procfs.c @@ -538,6 +538,7 @@ static void rkcif_show_format(struct rkcif_device *dev, struct seq_file *f) u64 fps, timestamp0, timestamp1; unsigned long flags; u32 time_val = 0; + u32 remainder = 0; if (atomic_read(&pipe->stream_cnt) < 1) return; @@ -586,7 +587,7 @@ static void rkcif_show_format(struct rkcif_device *dev, struct seq_file *f) else fps = timestamp0 > timestamp1 ? timestamp0 - timestamp1 : timestamp1 - timestamp0; - fps = div_u64(fps, 1000000); + fps = div_u64(fps, 1000); seq_puts(f, "Output Info:\n"); seq_printf(f, "\tformat:%s/%ux%u(%u,%u)\n", @@ -596,28 +597,27 @@ static void rkcif_show_format(struct rkcif_device *dev, struct seq_file *f) seq_printf(f, "\tcompact:%s\n", stream->is_compact ? "enable" : "disabled"); seq_printf(f, "\tframe amount:%d\n", stream->frame_idx - 1); if (dev->inf_id == RKCIF_MIPI_LVDS) { - time_val = div_u64(stream->readout.early_time, 1000000); - seq_printf(f, "\tearly:%u ms\n", time_val); + time_val = div_u64(stream->readout.early_time, 1000); + time_val = div_u64_rem(time_val, 1000, &remainder); + seq_printf(f, "\tearly:%u.%u ms\n", time_val, remainder); if (dev->hdr.hdr_mode == NO_HDR || dev->hdr.hdr_mode == HDR_COMPR) { - time_val = div_u64(stream->readout.readout_time, 1000000); - if (dev->sditf[0] && dev->sditf[0]->mode.rdbk_mode < RKISP_VICAP_RDBK_AIQ) - seq_puts(f, "\tsingle readout:N/A\n"); - else - seq_printf(f, "\tsingle readout:%u ms\n", time_val); + time_val = div_u64(stream->readout.readout_time, 1000); + time_val = div_u64_rem(time_val, 1000, &remainder); + seq_printf(f, "\tsingle readout:%u.%u ms\n", time_val, remainder); } else { - time_val = div_u64(stream->readout.readout_time, 1000000); - if (dev->sditf[0] && dev->sditf[0]->mode.rdbk_mode < RKISP_VICAP_RDBK_AIQ) - seq_puts(f, "\tsingle readout:N/A\n"); - else - seq_printf(f, "\tsingle readout:%u ms\n", time_val); - time_val = div_u64(stream->readout.total_time, 1000000); - seq_printf(f, "\ttotal readout:%u ms\n", time_val); + time_val = div_u64(stream->readout.readout_time, 1000); + time_val = div_u64_rem(time_val, 1000, &remainder); + seq_printf(f, "\tsingle readout:%u.%u ms\n", time_val, remainder); + time_val = div_u64(stream->readout.total_time, 1000); + time_val = div_u64_rem(time_val, 1000, &remainder); + seq_printf(f, "\ttotal readout:%u.%u ms\n", time_val, remainder); } } - seq_printf(f, "\trate:%llu ms\n", fps); - fps = div_u64(1000, fps); + time_val = div_u64_rem(fps, 1000, &remainder); + seq_printf(f, "\trate:%u.%u ms\n", time_val, remainder); + fps = div_u64(1000000, fps); seq_printf(f, "\tfps:%llu\n", fps); seq_puts(f, "\tirq statistics:\n"); seq_printf(f, "\t\t\ttotal:%llu\n", From d1b5f48c3a34694aa8ac0ecc3af5e39762be543c Mon Sep 17 00:00:00 2001 From: XiaoDong Huang Date: Tue, 1 Apr 2025 16:55:55 +0800 Subject: [PATCH 45/57] arm64: dts: rockchip: rv1126b-evb2-v10: add sleep-pin-config Signed-off-by: XiaoDong Huang Change-Id: I7b687c75c5c76bec742a932ddfd8192641b6db2c --- arch/arm64/boot/dts/rockchip/rv1126b-evb2-v10.dts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rv1126b-evb2-v10.dts b/arch/arm64/boot/dts/rockchip/rv1126b-evb2-v10.dts index 017d63c53917..40d5c4bf89ce 100644 --- a/arch/arm64/boot/dts/rockchip/rv1126b-evb2-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rv1126b-evb2-v10.dts @@ -373,6 +373,15 @@ &rockchip_suspend { status = "okay"; + + rockchip,sleep-pin-config = < + (0 + | RKPM_SLEEP_PIN0_EN + ) + (0 + | RKPM_SLEEP_PIN0_ACT_LOW + ) + >; }; &route_dsi { From a7874a7ba26d3e917fad30eef61ea71081728d20 Mon Sep 17 00:00:00 2001 From: Yao Xiao Date: Sat, 29 Mar 2025 11:50:38 +0800 Subject: [PATCH 46/57] arm64: dts: rockchip: add wifibt node for rv1126b evb2/3/4 Signed-off-by: Yao Xiao Change-Id: I467448ff61bddcacefcea659bdac09198972b3eb --- .../boot/dts/rockchip/rv1126b-evb2-v10.dts | 53 ++++++++++++++ .../boot/dts/rockchip/rv1126b-evb3-v10.dts | 58 +++++++++++++++ .../boot/dts/rockchip/rv1126b-evb4-v10.dts | 73 +++++++++++++++++++ 3 files changed, 184 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rv1126b-evb2-v10.dts b/arch/arm64/boot/dts/rockchip/rv1126b-evb2-v10.dts index 40d5c4bf89ce..bf2b2289d1af 100644 --- a/arch/arm64/boot/dts/rockchip/rv1126b-evb2-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rv1126b-evb2-v10.dts @@ -218,6 +218,26 @@ pwm-supply = <&vccsys_stb>; status = "okay"; }; + + wireless-bluetooth { + compatible = "bluetooth-platdata"; + uart_rts_gpios = <&gpio3 RK_PA6 GPIO_ACTIVE_LOW>; + pinctrl-names = "default", "rts_gpio"; + pinctrl-0 = <&uart2m0_rtsn_pins>; + pinctrl-1 = <&uart2_gpios>; + BT,power_gpio = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>; + status = "okay"; + }; + + wireless-wlan { + compatible = "wlan-platdata"; + rockchip,grf = <&grf>; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_wake_host>; + wifi_chip_type = "rk96x"; + WIFI,host_wake_irq = <&gpio0 RK_PC0 GPIO_ACTIVE_HIGH>; + status = "okay"; + }; }; &acdcdig_dsm { @@ -337,6 +357,18 @@ rockchip,pins = <0 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>; }; }; + + wireless-bluetooth { + uart2_gpios: uart2-gpios { + rockchip,pins = <3 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + wireless-wlan { + wifi_wake_host: wifi-wake-host { + rockchip,pins = <0 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; }; &pwm0_8ch_0 { @@ -426,6 +458,27 @@ status = "okay"; }; +&sdmmc1 { + bus-width = <1>; + cap-sd-highspeed; + no-sd; + no-mmc; + max-frequency = <200000000>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc1_clk_pins &sdmmc1_cmd_pins &sdmmc1_bus4_pins>; + keep-power-in-suspend; + non-removable; + //mmc-pwrseq = <&sdio_pwrseq>; + //sd-uhs-sdr104; + status = "okay"; +}; + +&uart2 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&uart2m0_xfer_pins &uart2m0_ctsn_pins>; +}; + &usb2phy_host { phy-supply = <&vcc5v0_host>; }; diff --git a/arch/arm64/boot/dts/rockchip/rv1126b-evb3-v10.dts b/arch/arm64/boot/dts/rockchip/rv1126b-evb3-v10.dts index 1c9833b607ef..727e7341355f 100644 --- a/arch/arm64/boot/dts/rockchip/rv1126b-evb3-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rv1126b-evb3-v10.dts @@ -11,6 +11,20 @@ model = "Rockchip RV1126B EVB3 V10 Board"; compatible = "rockchip,rv1126b-evb3-v10", "rockchip,rv1126b"; + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_enable_h>; + + /* + * On the module itself this is one of these (depending + * on the actual card populated): + * - SDIO_RESET_L_WL_REG_ON + * - PDN (power down when low) + */ + reset-gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>; + }; + vcc5v0_dcin: vcc5v0-dcin { compatible = "regulator-fixed"; regulator-name = "vcc5v0_dcin"; @@ -183,6 +197,26 @@ pwm-supply = <&vccsys_stb>; status = "okay"; }; + + wireless-bluetooth { + compatible = "bluetooth-platdata"; + uart_rts_gpios = <&gpio3 RK_PA6 GPIO_ACTIVE_LOW>; + pinctrl-names = "default", "rts_gpio"; + pinctrl-0 = <&uart2m0_rtsn_pins>; + pinctrl-1 = <&uart2_gpios>; + BT,power_gpio = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>; + status = "okay"; + }; + + wireless-wlan { + compatible = "wlan-platdata"; + rockchip,grf = <&grf>; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_wake_host>; + wifi_chip_type = "rk96x"; + WIFI,host_wake_irq = <&gpio0 RK_PB1 GPIO_ACTIVE_HIGH>; + status = "okay"; + }; }; &backlight { @@ -262,6 +296,12 @@ }; &pinctrl { + sdio-pwrseq { + wifi_enable_h: wifi-enable-h { + rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + touch { touch_gpio: touch-gpio { rockchip,pins = @@ -275,6 +315,18 @@ rockchip,pins = <7 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; }; }; + + wireless-bluetooth { + uart2_gpios: uart2-gpios { + rockchip,pins = <3 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + wireless-wlan { + wifi_wake_host: wifi-wake-host { + rockchip,pins = <0 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; }; &pwm1_4ch_0 { @@ -314,6 +366,12 @@ status = "okay"; }; +&uart2 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&uart2m0_xfer_pins &uart2m0_ctsn_pins>; +}; + &usb2phy_host { phy-supply = <&vcc5v0_host>; }; diff --git a/arch/arm64/boot/dts/rockchip/rv1126b-evb4-v10.dts b/arch/arm64/boot/dts/rockchip/rv1126b-evb4-v10.dts index 29ed7fe299ec..e9aae040fb69 100644 --- a/arch/arm64/boot/dts/rockchip/rv1126b-evb4-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rv1126b-evb4-v10.dts @@ -12,6 +12,20 @@ model = "Rockchip RV1126B EVB4 V10 Board"; compatible = "rockchip,rv1126b-evb4-v10", "rockchip,rv1126b"; + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_enable_h>; + + /* + * On the module itself this is one of these (depending + * on the actual card populated): + * - SDIO_RESET_L_WL_REG_ON + * - PDN (power down when low) + */ + reset-gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>; + }; + vcc_mipi: vcc-mipi { compatible = "regulator-fixed"; regulator-name = "vcc_mipi"; @@ -69,6 +83,26 @@ enable-gpios = <&gpio0 RK_PA3 GPIO_ACTIVE_HIGH>; pwm-supply = <&vcc5v0_sys>; }; + + wireless-bluetooth { + compatible = "bluetooth-platdata"; + uart_rts_gpios = <&gpio3 RK_PA6 GPIO_ACTIVE_LOW>; + pinctrl-names = "default", "rts_gpio"; + pinctrl-0 = <&uart2m0_rtsn_pins>; + pinctrl-1 = <&uart2_gpios>; + BT,power_gpio = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>; + status = "okay"; + }; + + wireless-wlan { + compatible = "wlan-platdata"; + rockchip,grf = <&grf>; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_wake_host>; + wifi_chip_type = "rk96x"; + WIFI,host_wake_irq = <&gpio0 RK_PB1 GPIO_ACTIVE_HIGH>; + status = "okay"; + }; }; &backlight { @@ -243,6 +277,12 @@ }; }; + sdio-pwrseq { + wifi_enable_h: wifi-enable-h { + rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + usb { typec5v_pwren: typec5v-pwren { rockchip,pins = <5 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>; @@ -252,6 +292,18 @@ rockchip,pins = <6 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>; }; }; + + wireless-bluetooth { + uart2_gpios: uart2-gpios { + rockchip,pins = <3 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + wireless-wlan { + wifi_wake_host: wifi-wake-host { + rockchip,pins = <0 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; }; &pwm0_8ch_0 { @@ -270,6 +322,27 @@ status = "okay"; }; +&sdmmc1 { + bus-width = <4>; + cap-sd-highspeed; + no-sd; + no-mmc; + max-frequency = <200000000>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc1_clk_pins &sdmmc1_cmd_pins &sdmmc1_bus4_pins>; + keep-power-in-suspend; + non-removable; + mmc-pwrseq = <&sdio_pwrseq>; + //sd-uhs-sdr104; + status = "okay"; +}; + +&uart2 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&uart2m0_xfer_pins &uart2m0_ctsn_pins>; +}; + &usb2phy_host { phy-supply = <&vcc5v0_host>; }; From 39f2db5482ac5dc5dc38a0a87a1f8afabe4ec3df Mon Sep 17 00:00:00 2001 From: Damon Ding Date: Mon, 31 Mar 2025 17:29:50 +0800 Subject: [PATCH 47/57] arm64: dts: rockchip: rk3576-evb1: enable logo display for module NV140QUM-N61 edp display board Change-Id: Id7dda7d50660dc9b85086cf9647d73bf67f0170c Signed-off-by: Damon Ding --- .../boot/dts/rockchip/rk3576-evb1-v10-edp-NV140QUM-N61.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3576-evb1-v10-edp-NV140QUM-N61.dts b/arch/arm64/boot/dts/rockchip/rk3576-evb1-v10-edp-NV140QUM-N61.dts index 013459c64ec3..120b55ba2ba7 100644 --- a/arch/arm64/boot/dts/rockchip/rk3576-evb1-v10-edp-NV140QUM-N61.dts +++ b/arch/arm64/boot/dts/rockchip/rk3576-evb1-v10-edp-NV140QUM-N61.dts @@ -90,7 +90,7 @@ }; &route_edp { - status = "disabled"; + status = "okay"; connect = <&vp0_out_edp>; }; From 2a59f8b444fbbc70e5dd329068ce50db6dfeac30 Mon Sep 17 00:00:00 2001 From: Yu Zheng Date: Mon, 31 Mar 2025 18:21:36 +0800 Subject: [PATCH 48/57] media: i2c: gc8613 use 30fps setting default Signed-off-by: Yu Zheng Change-Id: I8686db7d94243073b749646a871cb93cc465f83f --- drivers/media/i2c/gc8613.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/media/i2c/gc8613.c b/drivers/media/i2c/gc8613.c index c18cf06c2c9f..fa4c7962ca12 100644 --- a/drivers/media/i2c/gc8613.c +++ b/drivers/media/i2c/gc8613.c @@ -443,12 +443,12 @@ static const struct regval gc8613ya_dag_12bit_3840x2160_30fps_regs[] = { {0x025a, 0x98}, //30fps 0x08f8 - //{0x0340, 0x08}, - //{0x0341, 0xf8}, + {0x0340, 0x08}, + {0x0341, 0xf8}, //15fps:0x11f0 - {0x0340, 0x11}, - {0x0341, 0xf0}, + //{0x0340, 0x11}, + //{0x0341, 0xf0}, {0x0345, 0x02}, {0x0347, 0x02}, @@ -864,12 +864,12 @@ static const struct regval gc8613yn_dag_12bit_3840x2160_30fps_regs[] = { {0x025a, 0x98}, //30fps 0x08f8 - //{0x0340, 0x08}, - //{0x0341, 0xf8}, + {0x0340, 0x08}, + {0x0341, 0xf8}, //15fps:0x11f0 - {0x0340, 0x11}, - {0x0341, 0xf0}, + //{0x0340, 0x11}, + //{0x0341, 0xf0}, {0x0345, 0x02}, {0x0347, 0x02}, @@ -1253,11 +1253,11 @@ static const struct gc8613_mode supported_modes[] = { .height = 2160, .max_fps = { .numerator = 10000, - .denominator = 150000, + .denominator = 300000, }, .exp_def = 0x0327, .hts_def = 0x0310 * 8, - .vts_def = 0x08f8 * 2, + .vts_def = 0x08f8, .bus_fmt = MEDIA_BUS_FMT_SRGGB12_1X12, .reg_list[0] = gc8613yn_dag_12bit_3840x2160_30fps_regs, .reg_list[1] = gc8613ya_dag_12bit_3840x2160_30fps_regs, From 9d291a2f930a5df81d87a1a3c1668dc1c558623c Mon Sep 17 00:00:00 2001 From: Zorro Liu Date: Wed, 2 Apr 2025 14:17:33 +0800 Subject: [PATCH 49/57] drm/rockchip: ebc-dev: remove no use file Change-Id: Ia1a2f9c6815721ee07f19d161ddf7b4753e473f5 Signed-off-by: Zorro Liu --- .../gpu/drm/rockchip/ebc-dev/tcon/Makefile | 2 +- .../gpu/drm/rockchip/ebc-dev/tcon/eink_tcon.c | 301 ------------------ 2 files changed, 1 insertion(+), 302 deletions(-) delete mode 100644 drivers/gpu/drm/rockchip/ebc-dev/tcon/eink_tcon.c diff --git a/drivers/gpu/drm/rockchip/ebc-dev/tcon/Makefile b/drivers/gpu/drm/rockchip/ebc-dev/tcon/Makefile index 913d4813773b..c068e38bfff6 100644 --- a/drivers/gpu/drm/rockchip/ebc-dev/tcon/Makefile +++ b/drivers/gpu/drm/rockchip/ebc-dev/tcon/Makefile @@ -1,3 +1,3 @@ # SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_ROCKCHIP_EBC_DEV) += ebc_tcon.o eink_tcon.o +obj-$(CONFIG_ROCKCHIP_EBC_DEV) += ebc_tcon.o diff --git a/drivers/gpu/drm/rockchip/ebc-dev/tcon/eink_tcon.c b/drivers/gpu/drm/rockchip/ebc-dev/tcon/eink_tcon.c deleted file mode 100644 index 8c6f96cb991b..000000000000 --- a/drivers/gpu/drm/rockchip/ebc-dev/tcon/eink_tcon.c +++ /dev/null @@ -1,301 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright (c) 2020 Rockchip Electronics Co., Ltd. - * - * Author: Zorro Liu - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "ebc_tcon.h" - -#define HIWORD_UPDATE(x, l, h) (((x) << (l)) | (GENMASK(h, l) << 16)) -#define UPDATE(x, h, l) (((x) << (l)) & GENMASK((h), (l))) - -/* eink register define */ -#define EINK_IP_ENABLE 0x00 -#define EINK_SFT_UPDATE 0x04 -#define EINK_SIT_UPDATE 0x08 -#define EINK_PRE_IMAGE_BUF_ADDR 0x0c -#define EINK_CUR_IMAGE_BUF_ADDR 0x10 -#define EINK_IMAGE_PROCESS_BUF_ADDR 0x14 -#define EINK_LINE_DATA_ADDR_OFFSET 0x18 -#define EINK_IMAGE_WIDTH 0x1c -#define EINK_IMAGE_HEIGHT 0x20 -#define EINK_DATA_FORMAT 0x24 -#define EINK_IP_STATUS 0x28 -#define EINK_IP_VERSION 0x2c -#define EINK_IP_CLR_INT 0x30 -#define EINK_INT_SETTING0 0x34 -#define EINK_INT_SETTING1 0x38 -#define EINK_INT_SETTING2 0x3c -#define EINK_INT_SETTING3 0x40 -#define EINK_INT_SETTING4 0x44 -#define EINK_INT_SETTING5 0x48 -#define EINK_INT_SETTING6 0x4c -#define EINK_INT_SETTING7 0x50 -#define EINK_WF_SETTING0 0x54 -#define EINK_WF_SETTING1 0x58 -#define EINK_WF_SETTING2 0x5c -#define EINK_WF_SETTING3 0x60 -#define EINK_WF_SETTING4 0x64 -#define EINK_WF_SETTING5 0x68 -#define EINK_WF_SETTING6 0x6c -#define EINK_WF_SETTING7 0x70 - -struct eink_reg_data { - int addr; - int value; -}; - -static const struct eink_reg_data PANEL_1200x825_INIT[] = { - { EINK_SFT_UPDATE, 0x00030001 }, - { EINK_SIT_UPDATE, 0x00050000 }, - { EINK_LINE_DATA_ADDR_OFFSET, 0x000004b0 }, //width - { EINK_IMAGE_WIDTH, 0x000004af }, //width - 1 - { EINK_IMAGE_HEIGHT, 0x00000338 }, //height - 1 - - { EINK_INT_SETTING0, 0x0e56676f }, - { EINK_INT_SETTING1, 0x40674408 }, - { EINK_INT_SETTING2, 0xd7eb7743 }, - { EINK_INT_SETTING3, 0x19414d35 }, - { EINK_INT_SETTING4, 0x12561c00 }, - { EINK_INT_SETTING5, 0x05552e0a }, - { EINK_INT_SETTING6, 0x4a400e10 }, - { EINK_INT_SETTING7, 0x15496e2b }, - - { EINK_WF_SETTING0, 0xb3f33a52 }, - { EINK_WF_SETTING1, 0x2042b122 }, - { EINK_WF_SETTING2, 0xbdb0f3be }, - { EINK_WF_SETTING3, 0xe289a0ca }, - { EINK_WF_SETTING4, 0xb0d3b2c8 }, - { EINK_WF_SETTING5, 0x3a32ab20 }, - { EINK_WF_SETTING6, 0xa69a634c }, - { EINK_WF_SETTING7, 0xd87af2c0 }, -}; - -static const struct eink_reg_data PANEL_1872x1404_INIT[] = { - { EINK_SFT_UPDATE, 0x00030001 }, - { EINK_SIT_UPDATE, 0x00050000 }, - { EINK_LINE_DATA_ADDR_OFFSET, 0x00000750 }, //width - { EINK_IMAGE_WIDTH, 0x0000074f }, //width - 1 - { EINK_IMAGE_HEIGHT, 0x0000057c }, //height -1 - - { EINK_INT_SETTING0, 0x0e56676f }, - { EINK_INT_SETTING1, 0x40674408 }, - { EINK_INT_SETTING2, 0xb14a4643 }, - { EINK_INT_SETTING3, 0x19414d35 }, - { EINK_INT_SETTING4, 0x12561c00 }, - { EINK_INT_SETTING5, 0x05552e0a }, - { EINK_INT_SETTING6, 0x4a400e10 }, - { EINK_INT_SETTING7, 0x15496e2b }, - - { EINK_WF_SETTING0, 0xb3f33a52 }, - { EINK_WF_SETTING1, 0x2042b122 }, - { EINK_WF_SETTING2, 0x34b0708b }, - { EINK_WF_SETTING3, 0xe289a0ca }, - { EINK_WF_SETTING4, 0xb0d3b2c8 }, - { EINK_WF_SETTING5, 0x3a32ab20 }, - { EINK_WF_SETTING6, 0x2f9ae079 }, - { EINK_WF_SETTING7, 0xd87af2c0 }, -}; - -static inline void tcon_write(struct eink_tcon *tcon, unsigned int reg, - unsigned int value) -{ - regmap_write(tcon->regmap_base, reg, value); -} - -static inline unsigned int tcon_read(struct eink_tcon *tcon, unsigned int reg) -{ - unsigned int value; - - regmap_read(tcon->regmap_base, reg, &value); - - return value; -} - -static inline void tcon_update_bits(struct eink_tcon *tcon, unsigned int reg, - unsigned int mask, unsigned int val) -{ - regmap_update_bits(tcon->regmap_base, reg, mask, val); -} - -static int tcon_enable(struct eink_tcon *tcon, struct ebc_panel *panel) -{ - int reg_num = 0; - int i; - const struct eink_reg_data *pre_init_reg; - - clk_prepare_enable(tcon->pclk); - clk_prepare_enable(tcon->hclk); - pm_runtime_get_sync(tcon->dev); - - if ((panel->width == 1872) && (panel->height == 1404)) { - pre_init_reg = PANEL_1872x1404_INIT; - reg_num = ARRAY_SIZE(PANEL_1872x1404_INIT); - } else if ((panel->width == 1200) && (panel->height == 825)) { - pre_init_reg = PANEL_1200x825_INIT; - reg_num = ARRAY_SIZE(PANEL_1200x825_INIT); - } else { - pre_init_reg = PANEL_1872x1404_INIT; - reg_num = ARRAY_SIZE(PANEL_1872x1404_INIT); - } - for (i = 0; i < reg_num; i++) { - tcon_write(tcon, pre_init_reg[i].addr, pre_init_reg[i].value); - } - - enable_irq(tcon->irq); - - return 0; -} - -static void tcon_disable(struct eink_tcon *tcon) -{ - disable_irq(tcon->irq); - - pm_runtime_put_sync(tcon->dev); - clk_disable_unprepare(tcon->hclk); - clk_disable_unprepare(tcon->pclk); -} - -static void tcon_image_addr_set(struct eink_tcon *tcon, u32 pre_image_buf_addr, - u32 cur_image_buf_addr, u32 image_process_buf_addr) -{ - tcon_write(tcon, EINK_PRE_IMAGE_BUF_ADDR, pre_image_buf_addr); - tcon_write(tcon, EINK_CUR_IMAGE_BUF_ADDR, cur_image_buf_addr); - tcon_write(tcon, EINK_IMAGE_PROCESS_BUF_ADDR, image_process_buf_addr); -} - -static void tcon_frame_start(struct eink_tcon *tcon) -{ - tcon_write(tcon, EINK_IP_ENABLE, 1); -} - -static irqreturn_t tcon_irq_hanlder(int irq, void *dev_id) -{ - struct eink_tcon *tcon = (struct eink_tcon *)dev_id; - u32 intr_status; - - intr_status = tcon_read(tcon, EINK_IP_STATUS); - - if (intr_status & 0x1) { - tcon_update_bits(tcon, EINK_IP_CLR_INT, 0x1, 0x1); - - if (tcon->dsp_end_callback) - tcon->dsp_end_callback(); - } - - return IRQ_HANDLED; -} - -static struct regmap_config eink_regmap_config = { - .reg_bits = 32, - .val_bits = 32, - .reg_stride = 4, -}; - -static int eink_tcon_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct eink_tcon *tcon; - struct resource *res; - int ret; - - tcon = devm_kzalloc(dev, sizeof(*tcon), GFP_KERNEL); - if (!tcon) - return -ENOMEM; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - tcon->regs = devm_ioremap_resource(dev, res); - if (IS_ERR(tcon->regs)) - return PTR_ERR(tcon->regs); - - tcon->len = resource_size(res); - eink_regmap_config.max_register = resource_size(res) - 4; - eink_regmap_config.name = "rockchip,eink_tcon"; - tcon->regmap_base = devm_regmap_init_mmio(dev, tcon->regs, &eink_regmap_config); - if (IS_ERR(tcon->regmap_base)) - return PTR_ERR(tcon->regmap_base); - - tcon->hclk = devm_clk_get(dev, "hclk"); - if (IS_ERR(tcon->hclk)) { - ret = PTR_ERR(tcon->hclk); - dev_err(dev, "failed to get hclk clock: %d\n", ret); - return ret; - } - - tcon->pclk = devm_clk_get(dev, "pclk"); - if (IS_ERR(tcon->pclk)) { - ret = PTR_ERR(tcon->pclk); - dev_err(dev, "failed to get dclk clock: %d\n", ret); - return ret; - } - - tcon->irq = platform_get_irq(pdev, 0); - if (tcon->irq < 0) { - dev_err(dev, "No IRQ resource!\n"); - return tcon->irq; - } - - irq_set_status_flags(tcon->irq, IRQ_NOAUTOEN); - ret = devm_request_irq(dev, tcon->irq, tcon_irq_hanlder, - 0, dev_name(dev), tcon); - if (ret < 0) { - dev_err(dev, "failed to requeset irq: %d\n", ret); - return ret; - } - - tcon->dev = dev; - tcon->enable = tcon_enable; - tcon->disable = tcon_disable; - tcon->image_addr_set = tcon_image_addr_set; - tcon->frame_start = tcon_frame_start; - platform_set_drvdata(pdev, tcon); - - pm_runtime_enable(dev); - - return 0; -} - -static int eink_tcon_remove(struct platform_device *pdev) -{ - pm_runtime_disable(&pdev->dev); - - return 0; -} - -static const struct of_device_id eink_tcon_of_match[] = { - { .compatible = "rockchip,rk3568-eink-tcon" }, - {} -}; -MODULE_DEVICE_TABLE(of, eink_tcon_of_match); - -static struct platform_driver eink_tcon_driver = { - .driver = { - .name = "rk-eink-tcon", - .of_match_table = eink_tcon_of_match, - }, - .probe = eink_tcon_probe, - .remove = eink_tcon_remove, -}; -module_platform_driver(eink_tcon_driver); - -MODULE_AUTHOR("Zorro Liu "); -MODULE_DESCRIPTION("ROCKCHIP EINK tcon driver"); -MODULE_LICENSE("GPL v2"); From 39e732a120805e45a267244e0d170ffb5d87444c Mon Sep 17 00:00:00 2001 From: Su Yuefu Date: Wed, 2 Apr 2025 16:20:26 +0800 Subject: [PATCH 50/57] arm64: dts: rockchip: Add rv1126b-evb1-v10 dtsi Signed-off-by: Su Yuefu Change-Id: I8016c749633ba6509f973709e33e6aca7319e4da --- .../boot/dts/rockchip/rv1126b-evb1-v10.dts | 485 +---------------- .../boot/dts/rockchip/rv1126b-evb1-v10.dtsi | 491 ++++++++++++++++++ 2 files changed, 492 insertions(+), 484 deletions(-) create mode 100644 arch/arm64/boot/dts/rockchip/rv1126b-evb1-v10.dtsi diff --git a/arch/arm64/boot/dts/rockchip/rv1126b-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rv1126b-evb1-v10.dts index 727f08d44a7b..0108270ecbd1 100644 --- a/arch/arm64/boot/dts/rockchip/rv1126b-evb1-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rv1126b-evb1-v10.dts @@ -7,492 +7,9 @@ #include "rv1126b.dtsi" #include "rv1126b-evb.dtsi" #include "rv1126b-evb-cam-csi0.dtsi" +#include "rv1126b-evb1-v10.dtsi" / { model = "Rockchip RV1126B EVB1 V10 Board"; compatible = "rockchip,rv1126b-evb1-v10", "rockchip,rv1126b"; - - sdio_pwrseq: sdio-pwrseq { - compatible = "mmc-pwrseq-simple"; - pinctrl-names = "default"; - pinctrl-0 = <&wifi_enable_h>; - - /* - * On the module itself this is one of these (depending - * on the actual card populated): - * - SDIO_RESET_L_WL_REG_ON - * - PDN (power down when low) - */ - reset-gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>; - }; - - vcc5v0_sys: vcc5v0-sys { - compatible = "regulator-fixed"; - regulator-name = "vcc5v0_sys"; - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - vin-supply = <&vcc12v_dcin>; - status = "okay"; - }; - - vbus5v0_typec: vbus5v0-typec { - compatible = "regulator-fixed"; - regulator-name = "vbus5v0_typec"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - enable-active-high; - gpio = <&gpio5 RK_PD6 GPIO_ACTIVE_HIGH>; - vin-supply = <&vcc5v0_sys>; - pinctrl-names = "default"; - pinctrl-0 = <&typec5v_pwren>; - }; - - vcc5v0_host: vcc5v0-host { - compatible = "regulator-fixed"; - regulator-name = "vcc5v0_host"; - regulator-boot-on; - regulator-always-on; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - enable-active-high; - gpio = <&gpio5 RK_PA7 GPIO_ACTIVE_HIGH>; - vin-supply = <&vcc5v0_sys>; - pinctrl-names = "default"; - pinctrl-0 = <&vcc5v0_host_en>; - }; - - vcc_mipi: vcc-mipi { - compatible = "regulator-fixed"; - regulator-name = "vcc_mipi"; - gpio = <&gpio7 RK_PA2 GPIO_ACTIVE_HIGH>; - enable-active-high; - regulator-boot-on; - }; - - vcc_sd: vcc-sd { - compatible = "regulator-fixed"; - gpio = <&gpio0 RK_PB0 GPIO_ACTIVE_LOW>; - regulator-name = "vcc_sd"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - enable-active-low; - regulator-boot-on; // The legacy U-Boot GPIO driver needs this to set correct SDMMC0_PWREN value - vin-supply = <&vcc12v_dcin>; - }; - - vccio_sd: vccio-sd { - compatible = "regulator-gpio"; - regulator-boot-on; - regulator-name = "vccio_sd"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <3300000>; - pinctrl-names = "default"; - pinctrl-0 = <&sdmmc_volt>; - gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>; - vin-supply = <&vcc5v0_sys>; - states = <1800000 0x0 - 3300000 0x1>; - }; - - vdd_npu: vdd-npu { - compatible = "pwm-regulator"; - pwms = <&pwm0_8ch_0 0 25000 1>; - regulator-name = "vdd_npu"; - regulator-init-microvolt = <950000>; - regulator-min-microvolt = <750000>; - regulator-max-microvolt = <1100000>; - regulator-always-on; - regulator-boot-on; - enable-gpios = <&gpio0 RK_PA3 GPIO_ACTIVE_HIGH>; - pwm-supply = <&vcc5v0_sys>; - }; - - wireless-bluetooth { - compatible = "bluetooth-platdata"; - uart_rts_gpios = <&gpio3 RK_PA6 GPIO_ACTIVE_LOW>; - pinctrl-names = "default", "rts_gpio"; - pinctrl-0 = <&uart2m0_rtsn_pins>; - pinctrl-1 = <&uart2_gpios>; - BT,power_gpio = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>; - status = "okay"; - }; - - wireless-wlan { - compatible = "wlan-platdata"; - rockchip,grf = <&grf>; - pinctrl-names = "default"; - pinctrl-0 = <&wifi_wake_host>; - wifi_chip_type = "rk96x"; - WIFI,host_wake_irq = <&gpio0 RK_PB1 GPIO_ACTIVE_HIGH>; - status = "okay"; - }; -}; - -&acdcdig_dsm { - status = "okay"; - pa-ctl-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_HIGH>; -}; - -&acodec_sound { - status = "okay"; -}; - -&audio_codec { - status = "okay"; -}; - -&backlight { - pwms = <&pwm2_8ch_4 0 25000 0>; -}; - -&cpu0 { - cpu-supply = <&vdd_cpu>; -}; - -&display_subsystem { - status = "okay"; -}; - -&dsi { - status = "okay"; -}; - -&dsi_in_vop { - status = "okay"; -}; - -&dsi_panel { - power-supply = <&vcc_mipi>; -}; - -&emmc { - bus-width = <8>; - cap-mmc-highspeed; - non-removable; - mmc-hs200-1_8v; - rockchip,default-sample-phase = <90>; - no-sdio; - no-sd; - status = "okay"; -}; - -&fspi0 { - status = "okay"; - - flash@0 { - compatible = "spi-nand"; - reg = <0>; - spi-max-frequency = <75000000>; - spi-rx-bus-width = <4>; - spi-tx-bus-width = <1>; - }; -}; - -&gmac { - phy-mode = "rmii"; - clock_in_out = "input"; - phy-handle = <&rmii_phy>; - status = "okay"; -}; - -&i2c0 { - status = "okay"; - - rk801: rk801@27 { - compatible = "rockchip,rk801"; - status = "okay"; - reg = <0x27>; - interrupt-parent = <&gpio0>; - interrupts = ; - pwrctrl-gpios = <&gpio0 RK_PC1 GPIO_ACTIVE_HIGH>; - - pinctrl-names = "default"; - pinctrl-0 = <&pmic_int>; - rockchip,system-power-controller; - wakeup-source; - - vcc1-supply = <&vcc12v_dcin>; - vcc2-supply = <&vcc12v_dcin>; - vcc3-supply = <&vcc5v0_sys>; - vcc4-supply = <&vcc5v0_sys>; - vcc5-supply = <&vcc3v3_sys>; - vcc6-supply = <&vcc3v3_sys>; - vcc7-supply = <&vcc3v3_sys>; - - regulators { - vdd_cpu: DCDC_REG1 { - regulator-name = "vdd_cpu"; - regulator-min-microvolt = <500000>; - regulator-max-microvolt = <1500000>; - regulator-initial-mode = <0x1>; - regulator-boot-on; - regulator-always-on; - regulator-state-mem { - regulator-mode = <0x2>; - regulator-on-in-suspend; - regulator-suspend-microvolt = <950000>; - }; - }; - - vcc3v3_sys: DCDC_REG2 { - regulator-name = "vcc3v3_sys"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - regulator-initial-mode = <0x1>; - regulator-boot-on; - regulator-always-on; - regulator-state-mem { - regulator-mode = <0x2>; - regulator-on-in-suspend; - regulator-suspend-microvolt = <3300000>; - }; - }; - - vcc_ddr: DCDC_REG3 { - regulator-name = "vcc_ddr"; - regulator-boot-on; - regulator-always-on; - regulator-state-mem { - regulator-mode = <0x2>; - regulator-on-in-suspend; - }; - }; - - vdd_logic: DCDC_REG4 { - regulator-name = "vdd_logic"; - regulator-min-microvolt = <500000>; - regulator-max-microvolt = <1500000>; - regulator-initial-mode = <0x1>; - regulator-boot-on; - regulator-always-on; - regulator-state-mem { - regulator-mode = <0x2>; - regulator-on-in-suspend; - regulator-suspend-microvolt = <5000000>; - }; - }; - - vdd0v9_sys: LDO_REG1 { - regulator-name = "vdd0v9_sys"; - regulator-min-microvolt = <900000>; - regulator-max-microvolt = <900000>; - regulator-boot-on; - regulator-always-on; - regulator-state-mem { - regulator-on-in-suspend; - regulator-suspend-microvolt = <900000>; - }; - }; - - vcc_1v8: LDO_REG2 { - regulator-name = "vcc_1v8"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - regulator-boot-on; - regulator-always-on; - regulator-state-mem { - regulator-on-in-suspend; - regulator-suspend-microvolt = <1800000>; - }; - }; - - vcc_3v3: SWITCH_REG1 { - regulator-name = "vcc_3v3"; - regulator-boot-on; - regulator-always-on; - regulator-state-mem { - regulator-on-in-suspend; - }; - }; - }; - }; -}; - -&i2c4 { - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&i2c4m3_pins>; - - gt1x: gt1x@14 { - compatible = "goodix,gt1x"; - reg = <0x14>; - pinctrl-names = "default"; - pinctrl-0 = <&touch_gpio>; - power-supply = <&vcc_mipi>; - goodix,rst-gpio = <&gpio7 RK_PA7 GPIO_ACTIVE_HIGH>; - goodix,irq-gpio = <&gpio7 RK_PA6 IRQ_TYPE_LEVEL_LOW>; - }; -}; - -&mdio { - rmii_phy: ethernet-phy@2 { - compatible = "ethernet-phy-id0680.8101", "ethernet-phy-ieee802.3-c22"; - reg = <2>; - clocks = <&cru CLK_MACPHY>; - clock-frequency = <50000000>; - resets = <&cru SRST_RESETN_MACPHY>; - pinctrl-names = "default"; - pinctrl-0 = <&fephym1_pins>; - phy-is-integrated; - }; -}; - -&mipi_dphy { - status = "okay"; -}; - -&pinctrl { - pmic { - pmic_int: pmic-int { - rockchip,pins = <0 RK_PC0 RK_FUNC_GPIO &pcfg_pull_up>; - }; - }; - - sdio-pwrseq { - wifi_enable_h: wifi-enable-h { - rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>; - }; - }; - - sdmmc { - /omit-if-no-ref/ - sdmmc_volt: sdmmc-volt { - rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; - }; - }; - - touch { - touch_gpio: touch-gpio { - rockchip,pins = - <7 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, - <7 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>; - }; - }; - - usb { - typec5v_pwren: typec5v-pwren { - rockchip,pins = <5 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>; - }; - - vcc5v0_host_en: vcc5v0-host-en { - rockchip,pins = <5 RK_PA7 RK_FUNC_GPIO &pcfg_pull_none>; - }; - }; - - wireless-bluetooth { - uart2_gpios: uart2-gpios { - rockchip,pins = <3 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; - }; - }; - - wireless-wlan { - wifi_wake_host: wifi-wake-host { - rockchip,pins = <0 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>; - }; - }; -}; - -&pwm0_8ch_0 { - status = "okay"; -}; - -&pwm2_8ch_4 { - pinctrl-0 = <&pwm2m1_ch4_pins>; - status = "okay"; -}; - -&rkaiisp { - status = "okay"; -}; - -&rkaiisp_mmu { - status = "okay"; -}; - -&rkaiisp_vir0 { - status = "okay"; -}; - -&rkavsp { - status = "okay"; -}; - -&rkavsp_mmu { - status = "okay"; -}; - -&rkfec { - status = "okay"; -}; - -&rkfec_mmu { - status = "okay"; -}; - -&rknpu { - rknpu-supply = <&vdd_npu>; -}; - -&route_dsi { - status = "okay"; -}; - -&sai2 { - status = "okay"; - /delete-property/ pinctrl-names; - /delete-property/ pinctrl-0; -}; - -&saradc0 { - vref-supply = <&vcc_1v8>; -}; - -&sdmmc0 { - max-frequency = <200000000>; - no-sdio; - no-mmc; - bus-width = <4>; - cap-mmc-highspeed; - cap-sd-highspeed; - disable-wp; - sd-uhs-sdr104; - vmmc-supply = <&vcc_sd>; - vqmmc-supply = <&vccio_sd>; - status = "okay"; -}; - -&sdmmc1 { - bus-width = <4>; - cap-sd-highspeed; - no-sd; - no-mmc; - max-frequency = <200000000>; - pinctrl-names = "default"; - pinctrl-0 = <&sdmmc1_clk_pins &sdmmc1_cmd_pins &sdmmc1_bus4_pins>; - keep-power-in-suspend; - non-removable; - mmc-pwrseq = <&sdio_pwrseq>; - //sd-uhs-sdr104; - status = "okay"; -}; - -&uart2 { - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&uart2m0_xfer_pins &uart2m0_ctsn_pins>; -}; - -&usb2phy_host { - phy-supply = <&vcc5v0_host>; -}; - -&usb2phy_otg { - vbus-supply = <&vbus5v0_typec>; -}; - -&usb_drd_dwc3 { - dr_mode = "otg"; - extcon = <&usb2phy>; }; diff --git a/arch/arm64/boot/dts/rockchip/rv1126b-evb1-v10.dtsi b/arch/arm64/boot/dts/rockchip/rv1126b-evb1-v10.dtsi new file mode 100644 index 000000000000..c57ab9efd776 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rv1126b-evb1-v10.dtsi @@ -0,0 +1,491 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2025 Rockchip Electronics Co., Ltd. + * + */ + +/ { + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_enable_h>; + + /* + * On the module itself this is one of these (depending + * on the actual card populated): + * - SDIO_RESET_L_WL_REG_ON + * - PDN (power down when low) + */ + reset-gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>; + }; + + vcc5v0_sys: vcc5v0-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc12v_dcin>; + status = "okay"; + }; + + vbus5v0_typec: vbus5v0-typec { + compatible = "regulator-fixed"; + regulator-name = "vbus5v0_typec"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + gpio = <&gpio5 RK_PD6 GPIO_ACTIVE_HIGH>; + vin-supply = <&vcc5v0_sys>; + pinctrl-names = "default"; + pinctrl-0 = <&typec5v_pwren>; + }; + + vcc5v0_host: vcc5v0-host { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_host"; + regulator-boot-on; + regulator-always-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + gpio = <&gpio5 RK_PA7 GPIO_ACTIVE_HIGH>; + vin-supply = <&vcc5v0_sys>; + pinctrl-names = "default"; + pinctrl-0 = <&vcc5v0_host_en>; + }; + + vcc_mipi: vcc-mipi { + compatible = "regulator-fixed"; + regulator-name = "vcc_mipi"; + gpio = <&gpio7 RK_PA2 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-boot-on; + }; + + vcc_sd: vcc-sd { + compatible = "regulator-fixed"; + gpio = <&gpio0 RK_PB0 GPIO_ACTIVE_LOW>; + regulator-name = "vcc_sd"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + enable-active-low; + regulator-boot-on; // The legacy U-Boot GPIO driver needs this to set correct SDMMC0_PWREN value + vin-supply = <&vcc12v_dcin>; + }; + + vccio_sd: vccio-sd { + compatible = "regulator-gpio"; + regulator-boot-on; + regulator-name = "vccio_sd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_volt>; + gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>; + vin-supply = <&vcc5v0_sys>; + states = <1800000 0x0 + 3300000 0x1>; + }; + + vdd_npu: vdd-npu { + compatible = "pwm-regulator"; + pwms = <&pwm0_8ch_0 0 25000 1>; + regulator-name = "vdd_npu"; + regulator-init-microvolt = <950000>; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <1100000>; + regulator-always-on; + regulator-boot-on; + enable-gpios = <&gpio0 RK_PA3 GPIO_ACTIVE_HIGH>; + pwm-supply = <&vcc5v0_sys>; + }; + + wireless-bluetooth { + compatible = "bluetooth-platdata"; + uart_rts_gpios = <&gpio3 RK_PA6 GPIO_ACTIVE_LOW>; + pinctrl-names = "default", "rts_gpio"; + pinctrl-0 = <&uart2m0_rtsn_pins>; + pinctrl-1 = <&uart2_gpios>; + BT,power_gpio = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>; + status = "okay"; + }; + + wireless-wlan { + compatible = "wlan-platdata"; + rockchip,grf = <&grf>; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_wake_host>; + wifi_chip_type = "rk96x"; + WIFI,host_wake_irq = <&gpio0 RK_PB1 GPIO_ACTIVE_HIGH>; + status = "okay"; + }; +}; + +&acdcdig_dsm { + status = "okay"; + pa-ctl-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_HIGH>; +}; + +&acodec_sound { + status = "okay"; +}; + +&audio_codec { + status = "okay"; +}; + +&backlight { + pwms = <&pwm2_8ch_4 0 25000 0>; +}; + +&cpu0 { + cpu-supply = <&vdd_cpu>; +}; + +&display_subsystem { + status = "okay"; +}; + +&dsi { + status = "okay"; +}; + +&dsi_in_vop { + status = "okay"; +}; + +&dsi_panel { + power-supply = <&vcc_mipi>; +}; + +&emmc { + bus-width = <8>; + cap-mmc-highspeed; + non-removable; + mmc-hs200-1_8v; + rockchip,default-sample-phase = <90>; + no-sdio; + no-sd; + status = "okay"; +}; + +&fspi0 { + status = "okay"; + + flash@0 { + compatible = "spi-nand"; + reg = <0>; + spi-max-frequency = <75000000>; + spi-rx-bus-width = <4>; + spi-tx-bus-width = <1>; + }; +}; + +&gmac { + phy-mode = "rmii"; + clock_in_out = "input"; + phy-handle = <&rmii_phy>; + status = "okay"; +}; + +&i2c0 { + status = "okay"; + + rk801: rk801@27 { + compatible = "rockchip,rk801"; + status = "okay"; + reg = <0x27>; + interrupt-parent = <&gpio0>; + interrupts = ; + pwrctrl-gpios = <&gpio0 RK_PC1 GPIO_ACTIVE_HIGH>; + + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int>; + rockchip,system-power-controller; + wakeup-source; + + vcc1-supply = <&vcc12v_dcin>; + vcc2-supply = <&vcc12v_dcin>; + vcc3-supply = <&vcc5v0_sys>; + vcc4-supply = <&vcc5v0_sys>; + vcc5-supply = <&vcc3v3_sys>; + vcc6-supply = <&vcc3v3_sys>; + vcc7-supply = <&vcc3v3_sys>; + + regulators { + vdd_cpu: DCDC_REG1 { + regulator-name = "vdd_cpu"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1500000>; + regulator-initial-mode = <0x1>; + regulator-boot-on; + regulator-always-on; + regulator-state-mem { + regulator-mode = <0x2>; + regulator-on-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vcc3v3_sys: DCDC_REG2 { + regulator-name = "vcc3v3_sys"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-initial-mode = <0x1>; + regulator-boot-on; + regulator-always-on; + regulator-state-mem { + regulator-mode = <0x2>; + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name = "vcc_ddr"; + regulator-boot-on; + regulator-always-on; + regulator-state-mem { + regulator-mode = <0x2>; + regulator-on-in-suspend; + }; + }; + + vdd_logic: DCDC_REG4 { + regulator-name = "vdd_logic"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1500000>; + regulator-initial-mode = <0x1>; + regulator-boot-on; + regulator-always-on; + regulator-state-mem { + regulator-mode = <0x2>; + regulator-on-in-suspend; + regulator-suspend-microvolt = <5000000>; + }; + }; + + vdd0v9_sys: LDO_REG1 { + regulator-name = "vdd0v9_sys"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + regulator-boot-on; + regulator-always-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <900000>; + }; + }; + + vcc_1v8: LDO_REG2 { + regulator-name = "vcc_1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcc_3v3: SWITCH_REG1 { + regulator-name = "vcc_3v3"; + regulator-boot-on; + regulator-always-on; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + }; + }; +}; + +&i2c4 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c4m3_pins>; + + gt1x: gt1x@14 { + compatible = "goodix,gt1x"; + reg = <0x14>; + pinctrl-names = "default"; + pinctrl-0 = <&touch_gpio>; + power-supply = <&vcc_mipi>; + goodix,rst-gpio = <&gpio7 RK_PA7 GPIO_ACTIVE_HIGH>; + goodix,irq-gpio = <&gpio7 RK_PA6 IRQ_TYPE_LEVEL_LOW>; + }; +}; + +&mdio { + rmii_phy: ethernet-phy@2 { + compatible = "ethernet-phy-id0680.8101", "ethernet-phy-ieee802.3-c22"; + reg = <2>; + clocks = <&cru CLK_MACPHY>; + clock-frequency = <50000000>; + resets = <&cru SRST_RESETN_MACPHY>; + pinctrl-names = "default"; + pinctrl-0 = <&fephym1_pins>; + phy-is-integrated; + }; +}; + +&mipi_dphy { + status = "okay"; +}; + +&pinctrl { + pmic { + pmic_int: pmic-int { + rockchip,pins = <0 RK_PC0 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + sdio-pwrseq { + wifi_enable_h: wifi-enable-h { + rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + sdmmc { + /omit-if-no-ref/ + sdmmc_volt: sdmmc-volt { + rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + touch { + touch_gpio: touch-gpio { + rockchip,pins = + <7 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, + <7 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + usb { + typec5v_pwren: typec5v-pwren { + rockchip,pins = <5 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + vcc5v0_host_en: vcc5v0-host-en { + rockchip,pins = <5 RK_PA7 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + wireless-bluetooth { + uart2_gpios: uart2-gpios { + rockchip,pins = <3 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + wireless-wlan { + wifi_wake_host: wifi-wake-host { + rockchip,pins = <0 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; +}; + +&pwm0_8ch_0 { + status = "okay"; +}; + +&pwm2_8ch_4 { + pinctrl-0 = <&pwm2m1_ch4_pins>; + status = "okay"; +}; + +&rkaiisp { + status = "okay"; +}; + +&rkaiisp_mmu { + status = "okay"; +}; + +&rkaiisp_vir0 { + status = "okay"; +}; + +&rkavsp { + status = "okay"; +}; + +&rkavsp_mmu { + status = "okay"; +}; + +&rkfec { + status = "okay"; +}; + +&rkfec_mmu { + status = "okay"; +}; + +&rknpu { + rknpu-supply = <&vdd_npu>; +}; + +&route_dsi { + status = "okay"; +}; + +&sai2 { + status = "okay"; + /delete-property/ pinctrl-names; + /delete-property/ pinctrl-0; +}; + +&saradc0 { + vref-supply = <&vcc_1v8>; +}; + +&sdmmc0 { + max-frequency = <200000000>; + no-sdio; + no-mmc; + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; + disable-wp; + sd-uhs-sdr104; + vmmc-supply = <&vcc_sd>; + vqmmc-supply = <&vccio_sd>; + status = "okay"; +}; + +&sdmmc1 { + bus-width = <4>; + cap-sd-highspeed; + no-sd; + no-mmc; + max-frequency = <200000000>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc1_clk_pins &sdmmc1_cmd_pins &sdmmc1_bus4_pins>; + keep-power-in-suspend; + non-removable; + mmc-pwrseq = <&sdio_pwrseq>; + //sd-uhs-sdr104; + status = "okay"; +}; + +&uart2 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&uart2m0_xfer_pins &uart2m0_ctsn_pins>; +}; + +&usb2phy_host { + phy-supply = <&vcc5v0_host>; +}; + +&usb2phy_otg { + vbus-supply = <&vbus5v0_typec>; +}; + +&usb_drd_dwc3 { + dr_mode = "otg"; + extcon = <&usb2phy>; +}; From 6a11b8eb1032954528e804c0ab8ea3c61ecf87fc Mon Sep 17 00:00:00 2001 From: Su Yuefu Date: Wed, 2 Apr 2025 16:21:16 +0800 Subject: [PATCH 51/57] arm64: dts: rockchip: Add rv1126b-evb1-v10-dual-4k board Signed-off-by: Su Yuefu Change-Id: If8683ccea7ada3cee2a35705dc01d2eb44c99aab --- arch/arm64/boot/dts/rockchip/Makefile | 1 + .../dts/rockchip/rv1126b-evb1-v10-dual-4k.dts | 15 +++++++++++++++ 2 files changed, 16 insertions(+) create mode 100644 arch/arm64/boot/dts/rockchip/rv1126b-evb1-v10-dual-4k.dts diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile index ed84845a847b..cf4892da4769 100644 --- a/arch/arm64/boot/dts/rockchip/Makefile +++ b/arch/arm64/boot/dts/rockchip/Makefile @@ -366,6 +366,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-tablet-v10.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-tablet-v11.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb1-v10.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb1-v10-bt-sco.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb1-v10-dual-4k.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb1-v10-spi-nor.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb2-v10.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb2-v10-mcu-k350c4516t.dtb diff --git a/arch/arm64/boot/dts/rockchip/rv1126b-evb1-v10-dual-4k.dts b/arch/arm64/boot/dts/rockchip/rv1126b-evb1-v10-dual-4k.dts new file mode 100644 index 000000000000..b6f3660a033d --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rv1126b-evb1-v10-dual-4k.dts @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2025 Rockchip Electronics Co., Ltd. + */ + +/dts-v1/; +#include "rv1126b.dtsi" +#include "rv1126b-evb.dtsi" +#include "rv1126b-evb-dual-cam-4k.dtsi" +#include "rv1126b-evb1-v10.dtsi" + +/ { + model = "Rockchip RV1126B EVB1 V10 DUAL 4K Board"; + compatible = "rockchip,rv1126b-evb1-v10-dual-4k", "rockchip,rv1126b"; +}; From ae7f489bc0f178c414124bef2a54f21a9435606c Mon Sep 17 00:00:00 2001 From: Su Yuefu Date: Wed, 2 Apr 2025 16:21:48 +0800 Subject: [PATCH 52/57] ARM: dts: rockchip: Add rv1126b-evb1-v10-dual-4k board Signed-off-by: Su Yuefu Change-Id: Ib06aa05d91cc2b816ad659e0290ae0ee9e94a961 --- arch/arm/boot/dts/Makefile | 1 + arch/arm/boot/dts/rv1126b-evb1-v10-dual-4k.dts | 6 ++++++ 2 files changed, 7 insertions(+) create mode 100644 arch/arm/boot/dts/rv1126b-evb1-v10-dual-4k.dts diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index 479c19b387bd..2399b3e96c88 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -1177,6 +1177,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \ rv1126-evb-ddr3-v13.dtb \ rv1126b-evb1-v10.dtb \ rv1126b-evb1-v10-bt-sco.dtb \ + rv1126b-evb1-v10-dual-4k.dtb \ rv1126b-evb1-v10-spi-nor.dtb \ rv1126b-evb2-v10.dtb \ rv1126b-evb2-v10-mcu-k350c4516t.dtb \ diff --git a/arch/arm/boot/dts/rv1126b-evb1-v10-dual-4k.dts b/arch/arm/boot/dts/rv1126b-evb1-v10-dual-4k.dts new file mode 100644 index 000000000000..92f5229f3cb6 --- /dev/null +++ b/arch/arm/boot/dts/rv1126b-evb1-v10-dual-4k.dts @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2025 Rockchip Electronics Co., Ltd. + */ + +#include "arm64/rockchip/rv1126b-evb1-v10-dual-4k.dts" From b7aab6c829c85592e2fe4fb9c0b1f402c5ce9d4e Mon Sep 17 00:00:00 2001 From: Jon Lin Date: Tue, 1 Apr 2025 19:12:40 +0800 Subject: [PATCH 53/57] spi: spidev-rkmst: Fix wait for ready timeout Modify to the correct waiting time. By default, the slave ready must be confirmed by the ready signal, otherwise the function can only be realized by time redundancy. Change-Id: I721979a6bacc4cb2b58f434156ecb7b399a1dfb7 Signed-off-by: Jon Lin --- drivers/spi/spidev-rkmst.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spidev-rkmst.c b/drivers/spi/spidev-rkmst.c index c52cb194f2cc..5b90ce7b0153 100644 --- a/drivers/spi/spidev-rkmst.c +++ b/drivers/spi/spidev-rkmst.c @@ -143,7 +143,7 @@ static int spidev_mst_read(struct spidev_rkmst_data *spidev, void *rxbuf, size_t spi_message_init(&m); spi_message_add_tail(&t, &m); - ret = spidev_mst_wait_for_slave_ready(spidev, SPI_OBJ_MAX_XFER_SIZE); + ret = spidev_mst_wait_for_slave_ready(spidev, SPI_OBJ_DEFAULT_TIMEOUT_US); if (ret < 0) return ret; @@ -169,7 +169,7 @@ static int spidev_slv_write_and_read(struct spidev_rkmst_data *spidev, spi_message_init(&m); spi_message_add_tail(&t, &m); - ret = spidev_mst_wait_for_slave_ready(spidev, SPI_OBJ_MAX_XFER_SIZE); + ret = spidev_mst_wait_for_slave_ready(spidev, SPI_OBJ_DEFAULT_TIMEOUT_US); if (ret < 0) return ret; From 90b3d70d7918dd87ecedf9caee4831b184f63817 Mon Sep 17 00:00:00 2001 From: Xuhui Lin Date: Wed, 2 Apr 2025 09:41:31 +0800 Subject: [PATCH 54/57] spi: rockchip-slave: Add VER3_TYPE2 support Change-Id: I140648c4923acf91ed5238e8d831d7c0d373c9af Signed-off-by: Xuhui Lin --- drivers/spi/spi-rockchip-slave.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi-rockchip-slave.c b/drivers/spi/spi-rockchip-slave.c index 9ec9657b4fd7..4ce660fc734c 100644 --- a/drivers/spi/spi-rockchip-slave.c +++ b/drivers/spi/spi-rockchip-slave.c @@ -141,7 +141,8 @@ #define ROCKCHIP_SPI_VER2_TYPE1 0x05EC0002 #define ROCKCHIP_SPI_VER2_TYPE2 0x00110002 -#define ROCKCHIP_SPI_VER3 0x03110003 +#define ROCKCHIP_SPI_VER3_TYPE1 0x03110003 +#define ROCKCHIP_SPI_VER3_TYPE2 0x03120003 /* * The callback function may not be timely, and even cs has been released, so @@ -889,7 +890,8 @@ static int rockchip_spi_slave_probe(struct platform_device *pdev) init_completion(&rs->xfer_done); switch (rs->version) { - case ROCKCHIP_SPI_VER3: + case ROCKCHIP_SPI_VER3_TYPE2: + case ROCKCHIP_SPI_VER3_TYPE1: rs->ext_spi_clk = true; rs->dma_timeout = 16; rs->fixed_burst_size = 16; From 30478a01517be5e991292cbec64d5ed701b35da0 Mon Sep 17 00:00:00 2001 From: Cai YiWei Date: Tue, 1 Apr 2025 11:32:13 +0800 Subject: [PATCH 55/57] media: rockchip: vpss: fix wrap for vpss online Change-Id: I98aa2329b228f889ee08fbdf3239546087b928e0 Signed-off-by: Cai YiWei --- .../media/platform/rockchip/vpss/regs_v20.h | 2 +- .../media/platform/rockchip/vpss/stream_v20.c | 58 +++++++++++-------- .../media/platform/rockchip/vpss/vpss_dvbm.c | 11 ++-- .../platform/rockchip/vpss/vpss_rockit.c | 10 +++- 4 files changed, 51 insertions(+), 30 deletions(-) diff --git a/drivers/media/platform/rockchip/vpss/regs_v20.h b/drivers/media/platform/rockchip/vpss/regs_v20.h index b9c1b0b13e30..f6b01e3db9cf 100644 --- a/drivers/media/platform/rockchip/vpss/regs_v20.h +++ b/drivers/media/platform/rockchip/vpss/regs_v20.h @@ -263,7 +263,7 @@ /* VPSS2ENC_DEBUG */ #define RKVPSS2X_RO_VPSS2ENC_LINE_CNT(x) ((x) & 0x3fff) -#define RKVPSS2X_RO_VPSS2ENC_FRM_CNT(x) (((x) & 0xffffff) >> 16) +#define RKVPSS2X_RO_VPSS2ENC_FRM_CNT(x) (((x) >> 16) & 0xff) /* VPSS_CTRL_SHD */ diff --git a/drivers/media/platform/rockchip/vpss/stream_v20.c b/drivers/media/platform/rockchip/vpss/stream_v20.c index 196a7a6fc768..8fc95b210f39 100644 --- a/drivers/media/platform/rockchip/vpss/stream_v20.c +++ b/drivers/media/platform/rockchip/vpss/stream_v20.c @@ -826,7 +826,10 @@ static void stream_frame_start(struct rkvpss_stream *stream, u32 irq) !stream->dev->hw_dev->is_single) stream->ops->update_mi(stream); - if (dev->stream_vdev.wrap_line) { + if (dev->stream_vdev.wrap_line && stream->id == RKVPSS_OUTPUT_CH0) { + /* vpss can be holded by enc if isp input offline */ + if (!irq) + rkvpss_unite_set_bits(dev, RKVPSS_VPSS_CTRL, 0, RKVPSS_VPSS2ENC_PIPE_EN); rkvpss_rockit_frame_start(dev); rkvpss_dvbm_event(dev, ROCKIT_DVBM_START); } @@ -898,8 +901,8 @@ static void scl_update_mi(struct rkvpss_stream *stream) stream->ops->enable_mi(stream); } } else if (!stream->is_pause) { - /* wrap mode don't disable mi */ - if (stream->id != RKVPSS_OUTPUT_CH0 || !dev->stream_vdev.wrap_line) { + /* wrap mode don't disable mi for ch0 */ + if (!dev->stream_vdev.wrap_line || stream->id != RKVPSS_OUTPUT_CH0) { stream->is_pause = true; stream->ops->disable_mi(stream); } @@ -918,15 +921,11 @@ static void scl_config_mi(struct rkvpss_stream *stream) struct rkvpss_device *dev = stream->dev; struct capture_fmt *fmt = &stream->out_cap_fmt; struct v4l2_pix_format_mplane *out_fmt = &stream->out_fmt; - u32 reg, val, mask; - - v4l2_dbg(4, rkvpss_debug, &dev->v4l2_dev, - "%s stream:%d\n", __func__, stream->id); + u32 reg, val, mask, height = out_fmt->height; val = out_fmt->plane_fmt[0].bytesperline; reg = stream->config->mi.stride; rkvpss_unite_write(dev, reg, val); - rkvpss_unite_write(dev, reg, val); switch (fmt->fourcc) { case V4L2_PIX_FMT_RGB565: @@ -942,18 +941,27 @@ static void scl_config_mi(struct rkvpss_stream *stream) break; } - val = val * out_fmt->height; + val = val * height; reg = stream->config->mi.y_pic_size; rkvpss_unite_write(dev, reg, val); - if (dev->stream_vdev.wrap_line && stream->id == RKVPSS_OUTPUT_CH0) - val = out_fmt->plane_fmt[0].bytesperline * dev->stream_vdev.wrap_line; - else - val = out_fmt->plane_fmt[0].bytesperline * out_fmt->height; + if (dev->stream_vdev.wrap_line && stream->id == RKVPSS_OUTPUT_CH0) { + mask = RKVPSS_VPSS2ENC_SEL | RKVPSS2X_SENSOR_ID(7) | + RKVPSS_VPSS2ENC_CNT_SEL; + val = RKVPSS_VPSS2ENC_SEL | RKVPSS2X_VPSS2ENC_PATH_EN | + RKVPSS2X_SENSOR_ID(dev->dev_id); + rkvpss_unite_set_bits(dev, RKVPSS_VPSS_CTRL, mask, val); + + height = dev->stream_vdev.wrap_line; + } + val = out_fmt->plane_fmt[0].bytesperline * height; reg = stream->config->mi.y_size; rkvpss_unite_write(dev, reg, val); - val = out_fmt->plane_fmt[1].sizeimage; + if (dev->stream_vdev.wrap_line && stream->id == RKVPSS_OUTPUT_CH0) + val = out_fmt->plane_fmt[0].bytesperline * height / 2; + else + val = out_fmt->plane_fmt[1].sizeimage; reg = stream->config->mi.uv_size; rkvpss_unite_write(dev, reg, val); @@ -1154,14 +1162,14 @@ static void rkvpss_frame_end(struct rkvpss_stream *stream) struct rkvpss_buffer *buf = NULL; unsigned long lock_flags = 0; - v4l2_dbg(3, rkvpss_debug, &dev->v4l2_dev, - "%s stream:%d\n", __func__, stream->id); spin_lock_irqsave(&stream->vbq_lock, lock_flags); if (stream->curr_buf) { - buf = stream->curr_buf; - /* wrap mode use one buffer */ - if (stream->curr_buf->vb.vb2_buf.memory || !dev->stream_vdev.wrap_line) + /* rockit wrap mode use one buffer for ch0 */ + if (stream->curr_buf->vb.vb2_buf.memory || + !dev->stream_vdev.wrap_line || stream->id != RKVPSS_OUTPUT_CH0) { + buf = stream->curr_buf; stream->curr_buf = NULL; + } } spin_unlock_irqrestore(&stream->vbq_lock, lock_flags); @@ -1270,6 +1278,8 @@ static void rkvpss_buf_queue(struct vb2_buffer *vb) if (cap_fmt->mplanes == 1) { for (i = 0; i < cap_fmt->cplanes - 1; i++) { height = pixm->height; + if (dev->stream_vdev.wrap_line && stream->id == RKVPSS_OUTPUT_CH0) + height = dev->stream_vdev.wrap_line; size = (i == 0) ? pixm->plane_fmt[i].bytesperline * height : pixm->plane_fmt[i].sizeimage; @@ -1910,6 +1920,8 @@ static void rkvpss_stop_streaming(struct vb2_queue *queue) rkvpss_stream_stop(stream); rkvpss_pipeline_stream(dev, false); } + if (dev->stream_vdev.wrap_line && stream->id == RKVPSS_OUTPUT_CH0) + rkvpss_dvbm_deinit(dev); destroy_buf_queue(stream, VB2_BUF_STATE_ERROR); rkvpss_pipeline_close(dev); tasklet_disable(&stream->buf_done_tasklet); @@ -2022,7 +2034,8 @@ static int rkvpss_start_streaming(struct vb2_queue *queue, unsigned int count) v4l2_err(&dev->v4l2_dev, "start %s failed\n", node->vdev.name); goto pipe_close; } - + if (dev->stream_vdev.wrap_line && stream->id == RKVPSS_OUTPUT_CH0) + rkvpss_dvbm_init(stream); ret = rkvpss_pipeline_stream(dev, true); if (ret < 0) goto stop_stream; @@ -2037,6 +2050,8 @@ static int rkvpss_start_streaming(struct vb2_queue *queue, unsigned int count) mutex_unlock(&hw->dev_lock); return 0; stop_stream: + if (dev->stream_vdev.wrap_line && stream->id == RKVPSS_OUTPUT_CH0) + rkvpss_dvbm_deinit(dev); stream->streaming = false; rkvpss_stream_stop(stream); pipe_close: @@ -2758,9 +2773,6 @@ static int rkvpss_set_wrap_line(struct rkvpss_stream *stream, int *wrap_line) return -EINVAL; vpss_dev->stream_vdev.wrap_line = *wrap_line; - - //set_wrap todo - return 0; } diff --git a/drivers/media/platform/rockchip/vpss/vpss_dvbm.c b/drivers/media/platform/rockchip/vpss/vpss_dvbm.c index e87033d02298..8e0dc0f14bc6 100644 --- a/drivers/media/platform/rockchip/vpss/vpss_dvbm.c +++ b/drivers/media/platform/rockchip/vpss/vpss_dvbm.c @@ -20,7 +20,7 @@ static struct dvbm_port *g_dvbm; int rkvpss_dvbm_get(struct rkvpss_device *vpss_dev) { - struct device_node *np = vpss_dev->dev->of_node; + struct device_node *np = vpss_dev->hw_dev->dev->of_node; struct device_node *np_dvbm = of_parse_phandle(np, "dvbm", 0); int ret = 0; @@ -35,7 +35,10 @@ int rkvpss_dvbm_get(struct rkvpss_device *vpss_dev) } of_node_put(np_dvbm); - + if (IS_ERR_OR_NULL(g_dvbm)) { + g_dvbm = NULL; + ret = -EINVAL; + } return ret; } @@ -63,7 +66,7 @@ int rkvpss_dvbm_init(struct rkvpss_stream *stream) dvbm_cfg.cbuf_fstd = dvbm_cfg.ybuf_fstd / 2; rk_dvbm_ctrl(g_dvbm, DVBM_VPSS_SET_CFG, &dvbm_cfg); - rk_dvbm_link(g_dvbm, 0); + rk_dvbm_link(g_dvbm, vpss_dev->dev_id); return 0; } @@ -73,7 +76,7 @@ void rkvpss_dvbm_deinit(struct rkvpss_device *vpss_dev) pr_err("g_dvbm %p or vpss_dev %p is NULL\n", g_dvbm, vpss_dev); return; } - rk_dvbm_unlink(g_dvbm, 0); + rk_dvbm_unlink(g_dvbm, vpss_dev->dev_id); } int rkvpss_dvbm_event(struct rkvpss_device *vpss_dev, u32 event) diff --git a/drivers/media/platform/rockchip/vpss/vpss_rockit.c b/drivers/media/platform/rockchip/vpss/vpss_rockit.c index f419bcfa358b..5d6bf1f3315f 100644 --- a/drivers/media/platform/rockchip/vpss/vpss_rockit.c +++ b/drivers/media/platform/rockchip/vpss/vpss_rockit.c @@ -292,12 +292,17 @@ int rkvpss_rockit_buf_done(struct rkvpss_stream *stream, int cmd, struct rkvpss_ curr_buf->vb.sequence, curr_buf->dma[0]); } else { - //tosee if (!(stream->dev->stream_vdev.wrap_line && stream->id == RKVPSS_OUTPUT_CH0)) return 0; rockit_vpss_cfg->frame.u64PTS = vpss_dev->vpss_sdev.frame_timestamp; rockit_vpss_cfg->frame.u32TimeRef = vpss_dev->vpss_sdev.frame_seq; + rockit_vpss_cfg->frame.ispEncCnt = + RKVPSS2X_RO_VPSS2ENC_FRM_CNT(rkvpss_hw_read(vpss_dev->hw_dev, RKVPSS2X_VPSS2ENC_DEBUG)); + v4l2_dbg(2, rkvpss_debug, &vpss_dev->v4l2_dev, + "stream:%d seq:%d enc_frm_cnt:%d rockit buf done:0x%x\n", + stream->id, curr_buf->vb.sequence, + rockit_vpss_cfg->frame.ispEncCnt, curr_buf->dma[0]); } rockit_vpss_cfg->frame.u32Height = stream->out_fmt.height; @@ -571,7 +576,8 @@ void rkvpss_rockit_frame_start(struct rkvpss_device *dev) stream = &dev->stream_vdev.stream[i]; if (!stream->streaming) continue; - rkvpss_rockit_buf_done(stream, ROCKIT_DVBM_START, stream->curr_buf); + if (stream->curr_buf && !stream->curr_buf->vb.vb2_buf.memory) + rkvpss_rockit_buf_done(stream, ROCKIT_DVBM_START, stream->curr_buf); } } From 3592386bc957c481f6b645d68f4bd195bf1ab822 Mon Sep 17 00:00:00 2001 From: Liang Chen Date: Wed, 2 Apr 2025 16:08:56 +0800 Subject: [PATCH 56/57] clk: rockchip: add aisp pvtpll clk for rv1126b Change-Id: Ia92560172b1133a124d03ea37420fe3c3ca83ae0 Signed-off-by: Liang Chen --- drivers/clk/rockchip/clk-pvtpll.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/clk/rockchip/clk-pvtpll.c b/drivers/clk/rockchip/clk-pvtpll.c index 7cee8ddc5bd1..978f690af748 100644 --- a/drivers/clk/rockchip/clk-pvtpll.c +++ b/drivers/clk/rockchip/clk-pvtpll.c @@ -139,6 +139,11 @@ static struct pvtpll_table rv1103b_npu_pvtpll_table[] = { ROCKCHIP_PVTPLL_VOLT_SEL(700000000, 1, 32, 4), }; +static struct pvtpll_table rv1126b_aisp_pvtpll_table[] = { + /* rate_hz, ring_se, length */ + ROCKCHIP_PVTPLL(775000000, 0, 28), +}; + static struct pvtpll_table rv1126b_core_pvtpll_table[] = { /* rate_hz, ring_sel, length */ ROCKCHIP_PVTPLL_VOLT_SEL(1608000000, 0, 30, 0), @@ -590,6 +595,12 @@ static const struct rockchip_clock_pvtpll_info rv1103b_npu_pvtpll_data = { .pvtpll_calibrate = rv1103b_pvtpll_calibrate, }; +static const struct rockchip_clock_pvtpll_info rv1126b_aisp_pvtpll_data = { + .config = rv1103b_pvtpll_configs, + .table_size = ARRAY_SIZE(rv1126b_aisp_pvtpll_table), + .table = rv1126b_aisp_pvtpll_table, +}; + static const struct rockchip_clock_pvtpll_info rv1126b_core_pvtpll_data = { .config = rv1103b_pvtpll_configs, .table_size = ARRAY_SIZE(rv1126b_core_pvtpll_table), @@ -635,6 +646,10 @@ static const struct of_device_id rockchip_clock_pvtpll_match[] = { .compatible = "rockchip,rv1103b-npu-pvtpll", .data = (void *)&rv1103b_npu_pvtpll_data, }, + { + .compatible = "rockchip,rv1126b-aisp-pvtpll", + .data = (void *)&rv1126b_aisp_pvtpll_data, + }, { .compatible = "rockchip,rv1126b-core-pvtpll", .data = (void *)&rv1126b_core_pvtpll_data, From b5fd7789c8033d1431dcd6dc7ab5a095e6cb913a Mon Sep 17 00:00:00 2001 From: Liang Chen Date: Wed, 2 Apr 2025 16:13:33 +0800 Subject: [PATCH 57/57] arm64: dts: rockchip: rv1126b: add pvtpll node for aisp Change-Id: I5399fab8409d4c5b3be38f56da62edd0a2f4f5ea Signed-off-by: Liang Chen --- arch/arm64/boot/dts/rockchip/rv1126b.dtsi | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rv1126b.dtsi b/arch/arm64/boot/dts/rockchip/rv1126b.dtsi index 65de6728b29f..72a4a1c395a4 100644 --- a/arch/arm64/boot/dts/rockchip/rv1126b.dtsi +++ b/arch/arm64/boot/dts/rockchip/rv1126b.dtsi @@ -215,6 +215,15 @@ assigned-clock-rates = <550000000>; }; + pvtpll_aisp: pvtpll-aisp@21fc0000 { + compatible = "rockchip,rv1126b-aisp-pvtpll"; + reg = <0x21fc0000 0x100>; + #clock-cells = <0>; + clock-output-names = "clk_vcp_pvtpll"; + assigned-clocks = <&pvtpll_aisp>; + assigned-clock-rates = <775000000>; + }; + pvtpll_npu: pvtpll-npu@22080000 { compatible = "rockchip,rv1126b-npu-pvtpll", "syscon"; reg = <0x22080000 0x100>;