From baef3a263212b20d93318c295184224a6a898eeb Mon Sep 17 00:00:00 2001 From: Zefa Chen Date: Fri, 27 Dec 2024 10:58:04 +0800 Subject: [PATCH 01/13] phy: rockchip: csi2-dphy: mipi csi2 dphy dual init host_sel when work dual camera mode only valid for rk3566/rk3568 Signed-off-by: Zefa Chen Change-Id: I2c808fcccf201a84097acac3399b412eb251b28e --- .../phy/rockchip/phy-rockchip-csi2-dphy-hw.c | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/drivers/phy/rockchip/phy-rockchip-csi2-dphy-hw.c b/drivers/phy/rockchip/phy-rockchip-csi2-dphy-hw.c index 0c7ad151973e..e644a1a0367e 100644 --- a/drivers/phy/rockchip/phy-rockchip-csi2-dphy-hw.c +++ b/drivers/phy/rockchip/phy-rockchip-csi2-dphy-hw.c @@ -659,12 +659,17 @@ static void csi2_dphy_config_dual_mode(struct csi2_dphy *dphy, write_grf_reg(hw, GRF_DPHY_CSI2PHY_CLKLANE_EN, 0x1); if (hw->drv_data->chip_id < CHIP_ID_RK3588) { write_grf_reg(hw, GRF_DPHY_CSI2PHY_LANE_SEL, val); - if (is_cif) + if (is_cif) { write_grf_reg(hw, GRF_DPHY_CIF_CSI2PHY_SEL, GRF_CSI2PHY_SEL_SPLIT_0_1); - else + write_grf_reg(hw, GRF_DPHY_ISP_CSI2PHY_SEL, + GRF_CSI2PHY_SEL_SPLIT_2_3); + } else { write_grf_reg(hw, GRF_DPHY_ISP_CSI2PHY_SEL, GRF_CSI2PHY_SEL_SPLIT_0_1); + write_grf_reg(hw, GRF_DPHY_CIF_CSI2PHY_SEL, + GRF_CSI2PHY_SEL_SPLIT_2_3); + } } else if (hw->drv_data->chip_id == CHIP_ID_RK3588) { write_sys_grf_reg(hw, GRF_DPHY_CSIHOST2_SEL, 0x0); write_sys_grf_reg(hw, GRF_DPHY_CSI2PHY_LANE_SEL, val); @@ -685,12 +690,17 @@ static void csi2_dphy_config_dual_mode(struct csi2_dphy *dphy, write_grf_reg(hw, GRF_DPHY_CSI2PHY_CLKLANE1_EN, 0x1); if (hw->drv_data->chip_id < CHIP_ID_RK3588) { write_grf_reg(hw, GRF_DPHY_CSI2PHY_LANE_SEL, val); - if (is_cif) + if (is_cif) { write_grf_reg(hw, GRF_DPHY_CIF_CSI2PHY_SEL, - GRF_CSI2PHY_SEL_SPLIT_2_3); - else + GRF_CSI2PHY_SEL_SPLIT_2_3); write_grf_reg(hw, GRF_DPHY_ISP_CSI2PHY_SEL, - GRF_CSI2PHY_SEL_SPLIT_2_3); + GRF_CSI2PHY_SEL_SPLIT_0_1); + } else { + write_grf_reg(hw, GRF_DPHY_ISP_CSI2PHY_SEL, + GRF_CSI2PHY_SEL_SPLIT_2_3); + write_grf_reg(hw, GRF_DPHY_CIF_CSI2PHY_SEL, + GRF_CSI2PHY_SEL_SPLIT_0_1); + } } else if (hw->drv_data->chip_id == CHIP_ID_RK3588) { write_sys_grf_reg(hw, GRF_DPHY_CSIHOST3_SEL, 0x1); write_sys_grf_reg(hw, GRF_DPHY_CSI2PHY_LANE_SEL, val); From 0d7d8acd16a70b9e78ba12a22c26e5b6e3ae6fcd Mon Sep 17 00:00:00 2001 From: Zefa Chen Date: Mon, 6 Jan 2025 11:50:18 +0800 Subject: [PATCH 02/13] media: rockchip: vicap fixes error fps print of proc when work in online Signed-off-by: Zefa Chen Change-Id: I257f5df24fb5adc9ab9ddd3321ef3ff21ea88034 --- drivers/media/platform/rockchip/cif/capture.c | 2 +- drivers/media/platform/rockchip/cif/procfs.c | 17 +++++++++++++---- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/media/platform/rockchip/cif/capture.c b/drivers/media/platform/rockchip/cif/capture.c index 7f1a64f798c7..b4fbe17a1ed1 100644 --- a/drivers/media/platform/rockchip/cif/capture.c +++ b/drivers/media/platform/rockchip/cif/capture.c @@ -13070,7 +13070,7 @@ static void rkcif_toisp_check_stop_status(struct sditf_priv *priv, (priv->hdr_cfg.hdr_mode == HDR_X3 && stream->id == 2))) sditf_disable_immediately(priv); cur_time = rkcif_time_get_ns(stream->cifdev); - stream->readout.readout_time = cur_time - stream->readout.fs_timestamp; + 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) diff --git a/drivers/media/platform/rockchip/cif/procfs.c b/drivers/media/platform/rockchip/cif/procfs.c index a8022ff7b9cf..badee96a50a7 100644 --- a/drivers/media/platform/rockchip/cif/procfs.c +++ b/drivers/media/platform/rockchip/cif/procfs.c @@ -571,8 +571,11 @@ static void rkcif_show_format(struct rkcif_device *dev, struct seq_file *f) timestamp0 = stream->fps_stats.frm0_timestamp; timestamp1 = stream->fps_stats.frm1_timestamp; spin_unlock_irqrestore(&stream->fps_lock, flags); - fps = timestamp0 > timestamp1 ? - timestamp0 - timestamp1 : timestamp1 - timestamp0; + if (dev->sditf[0] && dev->sditf[0]->mode.rdbk_mode < RKISP_VICAP_RDBK_AIQ) + fps = dev->stream[0].readout.total_time; + else + fps = timestamp0 > timestamp1 ? + timestamp0 - timestamp1 : timestamp1 - timestamp0; fps = div_u64(fps, 1000000); seq_puts(f, "Output Info:\n"); @@ -588,10 +591,16 @@ static void rkcif_show_format(struct rkcif_device *dev, struct seq_file *f) if (dev->hdr.hdr_mode == NO_HDR || dev->hdr.hdr_mode == HDR_COMPR) { time_val = div_u64(stream->readout.readout_time, 1000000); - seq_printf(f, "\treadout:%u ms\n", time_val); + 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); } else { time_val = div_u64(stream->readout.readout_time, 1000000); - seq_printf(f, "\tsingle readout:%u ms\n", time_val); + 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); From f61210ec086baeb612ef60e63ecf3951e13bdfc4 Mon Sep 17 00:00:00 2001 From: Zefa Chen Date: Thu, 9 Jan 2025 11:46:53 +0800 Subject: [PATCH 03/13] media: rockchip: vicap clean crop mask after stop stream Signed-off-by: Zefa Chen Change-Id: I16eba981614ca49d8e4dbc5bb011d3237835c6ad --- drivers/media/platform/rockchip/cif/capture.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/platform/rockchip/cif/capture.c b/drivers/media/platform/rockchip/cif/capture.c index b4fbe17a1ed1..5bd829ae4475 100644 --- a/drivers/media/platform/rockchip/cif/capture.c +++ b/drivers/media/platform/rockchip/cif/capture.c @@ -6494,6 +6494,7 @@ void rkcif_do_stop_stream(struct rkcif_stream *stream, kfifo_free(&stream->dcg_kfifo); } + stream->crop_mask = 0; } if (mode == RKCIF_STREAM_MODE_CAPTURE) { tasklet_disable(&stream->vb_done_tasklet); From e0747a9113804fab91aaa1214a5c861b8cc92266 Mon Sep 17 00:00:00 2001 From: Zefa Chen Date: Fri, 10 Jan 2025 11:09:32 +0800 Subject: [PATCH 04/13] media: rockchip: vicap fixes error of thunderboot change to online in hdr mode Signed-off-by: Zefa Chen Change-Id: I90f4f82d5f380961a3c61634f4233e35973f64c6 --- drivers/media/platform/rockchip/cif/capture.c | 9 ++++++++- drivers/media/platform/rockchip/cif/subdev-itf.c | 4 ++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/rockchip/cif/capture.c b/drivers/media/platform/rockchip/cif/capture.c index 5bd829ae4475..ad93c6feee3a 100644 --- a/drivers/media/platform/rockchip/cif/capture.c +++ b/drivers/media/platform/rockchip/cif/capture.c @@ -11136,6 +11136,10 @@ static void rkcif_line_wake_up_rdbk(struct rkcif_stream *stream, int mipi_id) stream->cur_stream_mode |= RKCIF_STREAM_MODE_TOISP; stream->cifdev->wait_line = 0; stream->is_line_wake_up = false; + v4l2_dbg(3, rkcif_debug, &stream->cifdev->v4l2_dev, + "stream[%d] frame_idx %d, last_rx_buf_idx %d cur dma buf %x, change to online\n", + stream->id, stream->frame_idx, stream->last_rx_buf_idx, + (u32)active_buf->dummy.dma_addr); if (stream->cifdev->hdr.hdr_mode == NO_HDR || (priv->hdr_cfg.hdr_mode == HDR_X2 && stream->id == 1) || (priv->hdr_cfg.hdr_mode == HDR_X3 && stream->id == 2)) { @@ -14467,7 +14471,10 @@ void rkcif_irq_pingpong_v1(struct rkcif_device *cif_dev) } else { spin_lock_irqsave(&stream->fps_lock, flags); stream->readout.fs_timestamp = rkcif_time_get_ns(cif_dev); - stream->frame_idx++; + if (cif_dev->hdr.hdr_mode == HDR_X2 || cif_dev->hdr.hdr_mode == HDR_X3) + stream->frame_idx = cif_dev->stream[0].frame_idx; + else + stream->frame_idx++; if (cif_dev->channels[0].capture_info.mode == RKMODULE_MULTI_CH_TO_MULTI_ISP && cif_dev->sditf[stream->id]) sditf_event_inc_sof(cif_dev->sditf[stream->id]); diff --git a/drivers/media/platform/rockchip/cif/subdev-itf.c b/drivers/media/platform/rockchip/cif/subdev-itf.c index ce0378e60105..df8d7ca79cfc 100644 --- a/drivers/media/platform/rockchip/cif/subdev-itf.c +++ b/drivers/media/platform/rockchip/cif/subdev-itf.c @@ -1298,8 +1298,8 @@ static int sditf_s_rx_buffer(struct v4l2_subdev *sd, } rx_buf = to_cif_rx_buf(dbufs); - v4l2_dbg(3, rkcif_debug, &cif_dev->v4l2_dev, "buf back to vicap 0x%x\n", - (u32)rx_buf->dummy.dma_addr); + v4l2_dbg(3, rkcif_debug, &cif_dev->v4l2_dev, "type %d buf back to vicap 0x%x, is_switch %d\n", + dbufs->type, (u32)rx_buf->dummy.dma_addr, dbufs->is_switch); spin_lock_irqsave(&stream->vbq_lock, flags); stream->last_rx_buf_idx = dbufs->sequence + 1; atomic_inc(&stream->buf_cnt); From 61397641fba52692384e664acd4771b3225313cd Mon Sep 17 00:00:00 2001 From: Zefa Chen Date: Fri, 10 Jan 2025 17:15:50 +0800 Subject: [PATCH 05/13] media: rockchip: vicap fixes warning of compile MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/media/platform/rockchip/cif/dev.c:1461:6: warning: no previous prototype for ‘rkcif_set_sensor_streamon_in_sync_mode’ [-Wmissing-prototypes] drivers/media/platform/rockchip/cif/dev.c:2477:6: warning: no previous prototype for ‘rkcif_set_sensor_stream’ [-Wmissing-prototypes] Signed-off-by: Zefa Chen Change-Id: I7df0b1505e763b51e277f70f7a46d4eb163a82d6 --- drivers/media/platform/rockchip/cif/capture.c | 2 -- drivers/media/platform/rockchip/cif/dev.c | 2 +- drivers/media/platform/rockchip/cif/dev.h | 2 ++ 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/rockchip/cif/capture.c b/drivers/media/platform/rockchip/cif/capture.c index ad93c6feee3a..dfcefbfe25df 100644 --- a/drivers/media/platform/rockchip/cif/capture.c +++ b/drivers/media/platform/rockchip/cif/capture.c @@ -13504,8 +13504,6 @@ static void rkcif_sensor_quick_streaming_cb(void *data) RKMODULE_SET_QUICK_STREAM, &on); } -extern void rkcif_set_sensor_streamon_in_sync_mode(struct rkcif_device *cif_dev); - static int rkcif_terminal_sensor_set_stream(struct rkcif_device *cif_dev, int on) { struct rkcif_pipeline *p = &cif_dev->pipe; diff --git a/drivers/media/platform/rockchip/cif/dev.c b/drivers/media/platform/rockchip/cif/dev.c index 70ee9a531acc..319d7527cc17 100644 --- a/drivers/media/platform/rockchip/cif/dev.c +++ b/drivers/media/platform/rockchip/cif/dev.c @@ -2474,7 +2474,7 @@ static void rkcif_init_reset_monitor(struct rkcif_device *dev) INIT_WORK(&dev->reset_work.work, rkcif_reset_work); } -void rkcif_set_sensor_stream(struct work_struct *work) +static void rkcif_set_sensor_stream(struct work_struct *work) { struct rkcif_sensor_work *sensor_work = container_of(work, struct rkcif_sensor_work, diff --git a/drivers/media/platform/rockchip/cif/dev.h b/drivers/media/platform/rockchip/cif/dev.h index 8454e21e95e5..baf1582290f8 100644 --- a/drivers/media/platform/rockchip/cif/dev.h +++ b/drivers/media/platform/rockchip/cif/dev.h @@ -1173,4 +1173,6 @@ void rkcif_reinit_right_half_config(struct rkcif_stream *stream); 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); #endif From a3ad373b3feb2fb4b8330724f58f81aad33a65d4 Mon Sep 17 00:00:00 2001 From: Zhang Yubing Date: Mon, 16 Dec 2024 15:39:06 +0800 Subject: [PATCH 06/13] arm64: dts: rockchip: rk3576: support vop dclk reset Change-Id: I93552e3d8e5c20dabc5061b8cb8071846ce3b27a Signed-off-by: Zhang Yubing --- arch/arm64/boot/dts/rockchip/rk3576.dtsi | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3576.dtsi b/arch/arm64/boot/dts/rockchip/rk3576.dtsi index 9dd309efd801..e25899a39eff 100644 --- a/arch/arm64/boot/dts/rockchip/rk3576.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3576.dtsi @@ -3400,6 +3400,12 @@ "dclk_src_vp0", "dclk_src_vp1", "dclk_src_vp2"; + resets = <&cru SRST_D_VP0>, + <&cru SRST_D_VP1>, + <&cru SRST_D_VP2>; + reset-names = "dclk_vp0", + "dclk_vp1", + "dclk_vp2"; rockchip,aclk-normal-mode-rates = <500000000>; rockchip,aclk-reset-mode-rates = <594000000>; rockchip,aclk-advanced-mode-rates = <702000000>; From cd51e4eb733850648d5ee34b118b8a3ef4b89682 Mon Sep 17 00:00:00 2001 From: Zhang Yubing Date: Tue, 17 Dec 2024 10:27:25 +0800 Subject: [PATCH 07/13] drm/bridge: synopsys: dw-hdmi-qp: support pre disable/post enable crtc Change-Id: If11faf7c1ca6079f2f6fef4c8b914b07615b65b3 Signed-off-by: Zhang Yubing --- drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 5 +++ drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 44 ++++++++++++++++++++ include/drm/bridge/dw_hdmi.h | 2 + 3 files changed, 51 insertions(+) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c index 36ba988e288a..8dbe50439f84 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c @@ -3496,6 +3496,8 @@ static void dw_hdmi_qp_bridge_atomic_disable(struct drm_bridge *bridge, extcon_set_state_sync(hdmi->extcon, EXTCON_DISP_HDMI, false); 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); if (hdmi->dclk_en) { @@ -3570,6 +3572,9 @@ static void dw_hdmi_qp_bridge_atomic_enable(struct drm_bridge *bridge, if (link_cfg && link_cfg->frl_mode) queue_work(hdmi->workqueue, &hdmi->flt_work); + if (hdmi->plat_data->crtc_post_enable) + hdmi->plat_data->crtc_post_enable(data, bridge->encoder->crtc); + dw_hdmi_qp_init_audio_infoframe(hdmi); dw_hdmi_qp_audio_enable(hdmi); hdmi_clk_regenerator_update_pixel_clock(hdmi); diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c index 232d6a60e406..e05b61cea886 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c @@ -3200,6 +3200,46 @@ static void dw_hdmi_rockchip_get_mode_color_caps(struct drm_connector *connector hdmi->mode_color_caps, &connector->base, property); } +static void dw_hdmi_rockchip_crtc_post_enable(void *data, struct drm_crtc *crtc) +{ + struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data; + int output_if; + + switch (hdmi->id) { + case 0: + output_if = VOP_OUTPUT_IF_HDMI0; + break; + case 1: + output_if = VOP_OUTPUT_IF_HDMI1; + break; + default: + dev_err(hdmi->dev, "invalid id:%d\n", hdmi->id); + return; + } + + rockchip_drm_crtc_output_post_enable(crtc, output_if); +} + +static void dw_hdmi_rockchip_crtc_pre_disable(void *data, struct drm_crtc *crtc) +{ + struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data; + int output_if; + + switch (hdmi->id) { + case 0: + output_if = VOP_OUTPUT_IF_HDMI0; + break; + case 1: + output_if = VOP_OUTPUT_IF_HDMI1; + break; + default: + dev_err(hdmi->dev, "invalid id:%d\n", hdmi->id); + return; + } + + rockchip_drm_crtc_output_pre_disable(crtc, output_if); +} + static const struct drm_prop_enum_list color_depth_enum_list[] = { { 0, "Automatic" }, /* Prefer highest color depth */ { 8, "24bit" }, @@ -4433,6 +4473,10 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, dw_hdmi_rockchip_force_frl_rate; plat_data->get_mode_color_caps = dw_hdmi_rockchip_get_mode_color_caps; + plat_data->crtc_pre_disable = + dw_hdmi_rockchip_crtc_pre_disable; + plat_data->crtc_post_enable = + dw_hdmi_rockchip_crtc_post_enable; plat_data->property_ops = &dw_hdmi_rockchip_property_ops; secondary = rockchip_hdmi_find_by_id(dev->driver, !hdmi->id); diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h index d02952ceafeb..9580f6e43d3c 100644 --- a/include/drm/bridge/dw_hdmi.h +++ b/include/drm/bridge/dw_hdmi.h @@ -284,6 +284,8 @@ struct dw_hdmi_plat_data { void (*force_frl_rate)(void *data, u8 rate); void (*get_mode_color_caps)(struct drm_connector *connector, struct drm_display_info *info, void *data); + void (*crtc_pre_disable)(void *data, struct drm_crtc *crtc); + void (*crtc_post_enable)(void *data, struct drm_crtc *crtc); /* Vendor Property support */ const struct dw_hdmi_property_ops *property_ops; From fdcec7349c51b02ecb2d1b1f81537cd2e7b83eb1 Mon Sep 17 00:00:00 2001 From: Zhang Yubing Date: Tue, 17 Dec 2024 11:10:42 +0800 Subject: [PATCH 08/13] drm/rockchip: vop2: reset dclk after config stream output In RK3576, DP0 attach to VP1 or VP2 will cause vertical stripe. It need reset dclk after config stream output to avoid this issue. Change-Id: I00112e8541828ed53a2ea91e7d79f8d148a7b3df Signed-off-by: Zhang Yubing --- drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index 050e9864a388..22ae57c407c3 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -1070,6 +1070,7 @@ static DRM_ENUM_NAME_FN(drm_get_bus_format_name, drm_bus_format_enum_list) static inline void vop2_cfg_done(struct drm_crtc *crtc); static void vop2_wait_for_fs_by_done_bit_status(struct vop2_video_port *vp); +static int vop2_clk_reset(struct reset_control *rstc); static inline struct vop2_video_port *to_vop2_video_port(struct drm_crtc *crtc) { @@ -1267,6 +1268,9 @@ static void vop2_crtc_output_post_enable(struct drm_crtc *crtc, int intf) vop2_wait_for_fs_by_done_bit_status(vp); } + if (!vp->loader_protect) + vop2_clk_reset(vp->dclk_rst); + drm_info(vop2, "vop enable intf:%x\n", intf); } @@ -10303,8 +10307,6 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_sta vop3_mcu_mode_setup(crtc); } - if (!vp->loader_protect) - vop2_clk_reset(vp->dclk_rst); if (vcstate->dsc_enable) rk3588_vop2_dsc_cfg_done(crtc); drm_crtc_vblank_on(crtc); From 4036781b831b361d965c56e1f0d1be9bdffcf074 Mon Sep 17 00:00:00 2001 From: Xing Zheng Date: Thu, 9 Jan 2025 17:13:59 +0800 Subject: [PATCH 09/13] ASoC: codecs: rk730: fix and update some clock configurations This patch removes the two uncommon sampling rates of 12000 and 24000Hz, because they are not in the definition of SNDRV_PCM_RATE_8000_192000 in the sound framework: ... #define SNDRV_PCM_RATE_11025 (1U<<2) /* 11025Hz */ #define SNDRV_PCM_RATE_16000 (1U<<3) /* 16000Hz */ #define SNDRV_PCM_RATE_22050 (1U<<4) /* 22050Hz */ #define SNDRV_PCM_RATE_32000 (1U<<5) /* 32000Hz */ ... According to the configuration of the sampling rate group clock, the configuration of 11025 and 22050Hz is added. And, it is changed to select the appropriate mclk in the coeff_clk array according to the sampling by the codec by default. If you need to use the previous fixed FS method, you need to specify the property "rockchip,mclk-fs-fixed" in the dts node. Change-Id: Iae4478b807f4e6eb88bf6cc9f431ce2f725a5b36 Signed-off-by: Xing Zheng --- sound/soc/codecs/rk730.c | 69 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/rk730.c b/sound/soc/codecs/rk730.c index 38b941962a35..a3a8f2a29e96 100644 --- a/sound/soc/codecs/rk730.c +++ b/sound/soc/codecs/rk730.c @@ -55,6 +55,7 @@ struct rk730_priv { struct clk *mclk; unsigned int sysclk; atomic_t mix_mode; + bool fixed_mclk_fs; }; /* ADC Digital Volume */ @@ -666,6 +667,16 @@ static const struct _coeff_div coeff_div[] = { {8192000, 32000, 0xe, 0x3, 0x0}, {8192000, 64000, 0xe, 0x3, 0x0}, {8192000, 128000, 0xe, 0x3, 0x0}, + + /* uncommon sample rate groups */ + {12288000, 11025, 0x1, 0x1, 0x0}, + {12288000, 22050, 0x1, 0x1, 0x0}, + {12000000, 11025, 0x4, 0x1, 0x0}, + {12000000, 22050, 0x4, 0x1, 0x0}, + {24000000, 11025, 0xa, 0x1, 0x0}, + {24000000, 22050, 0xa, 0x1, 0x0}, + {11289600, 11025, 0xd, 0x1, 0x0}, + {11289600, 22050, 0xd, 0x1, 0x0}, }; static inline int get_coeff(int mclk, int rate) @@ -679,16 +690,49 @@ static inline int get_coeff(int mclk, int rate) return -EINVAL; } +struct _coeff_clk { + int mclk; + int rate; +}; + +/* codec selects the required mclk and sets it by itself */ +static const struct _coeff_clk coeff_clk[] = { + /* mclks */ + {12288000, 48000}, + {12288000, 96000}, + {12288000, 192000}, + {11289600, 44100}, + {11289600, 88200}, + {11289600, 176000}, + {8192000, 8000}, + {8192000, 16000}, + {8192000, 32000}, + {8192000, 64000}, + {8192000, 128000}, + /* uncommon sample rate groups */ + {11289600, 11025}, + {11289600, 22050}, +}; + +static inline int get_coeff_clk(int rate) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(coeff_clk); i++) { + if (coeff_clk[i].rate == rate) + return coeff_clk[i].mclk; + } + return -EINVAL; +} + static unsigned int samplerate_to_bit(unsigned int samplerate) { switch (samplerate) { case 8000: case 11025: - case 12000: return 0; case 16000: case 22050: - case 24000: return 1; case 32000: case 44100: @@ -716,6 +760,24 @@ static int rk730_dai_hw_params(struct snd_pcm_substream *substream, unsigned int rate; int coeff; + if (!rk730->fixed_mclk_fs) { + rk730->sysclk = get_coeff_clk(params_rate(params)); + if ((int)rk730->sysclk < 0) { + dev_err(component->dev, + "Unable to lookup coeff clk with sample rate %dHz\n", + params_rate(params)); + return -EINVAL; + } + dev_info(component->dev, "%s: Lookup mclk:%d for rate:%d\n", + __func__, rk730->sysclk, params_rate(params)); + + if (clk_set_rate(rk730->mclk, rk730->sysclk) < 0) { + dev_err(component->dev, + "Unable to set mclk %dHz\n", rk730->sysclk); + return -EINVAL; + } + } + coeff = get_coeff(rk730->sysclk, params_rate(params)); if (coeff < 0) coeff = get_coeff(rk730->sysclk / 2, params_rate(params)); @@ -1131,6 +1193,9 @@ static int rk730_i2c_probe(struct i2c_client *i2c, if (IS_ERR(rk730->mclk)) return PTR_ERR(rk730->mclk); + rk730->fixed_mclk_fs = + device_property_read_bool(&i2c->dev, "rockchip,mclk-fs-fixed"); + i2c_set_clientdata(i2c, rk730); ret = devm_snd_soc_register_component(&i2c->dev, From c48bb00056c4682ff7b159a7388328d11ee63853 Mon Sep 17 00:00:00 2001 From: Xing Zheng Date: Thu, 9 Jan 2025 17:26:34 +0800 Subject: [PATCH 10/13] ASoC: rockchip: sai: add support "rockchip,mclk-no-set" property Sometimes the mclk frequency needs to be set by the external codec according to the sampling rate, rather than just keeping a fixed multiple of the sampling rate. In this case, through the property of "rockchip,mclk-no-set", the SAI will not modify the mclk frequency again after the codec sets it. Change-Id: I9bacebb397b9219b773b9953afabd1c5156c8a19 Signed-off-by: Xing Zheng --- sound/soc/rockchip/rockchip_sai.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/sound/soc/rockchip/rockchip_sai.c b/sound/soc/rockchip/rockchip_sai.c index 077a66e8c761..c1d5d23de49d 100644 --- a/sound/soc/rockchip/rockchip_sai.c +++ b/sound/soc/rockchip/rockchip_sai.c @@ -75,6 +75,7 @@ struct rk_sai_dev { bool is_clk_auto; bool is_mclk_calibrate; bool is_tx_auto_gate; /* auto gate clk when TX FIFO empty */ + bool no_set_mclk; }; static const struct sai_of_quirks { @@ -630,7 +631,7 @@ static int rockchip_sai_hw_params(struct snd_pcm_substream *substream, if (sai->is_master_mode) { bclk_rate = sai->fw_ratio * slot_width * ch_per_lane * params_rate(params); - if (sai->is_clk_auto) + if (sai->is_clk_auto && !sai->no_set_mclk) clk_set_rate(sai->mclk, bclk_rate); mclk_rate = clk_get_rate(sai->mclk); @@ -921,9 +922,11 @@ static int rockchip_sai_set_sysclk(struct snd_soc_dai *dai, int clk_id, return ret; } - ret = clk_set_rate(sai->mclk, freq); - if (ret) - dev_err(sai->dev, "Failed to set mclk %d\n", ret); + if (!sai->no_set_mclk) { + ret = clk_set_rate(sai->mclk, freq); + if (ret) + dev_err(sai->dev, "Failed to set mclk %d\n", ret); + } return ret; } @@ -1974,6 +1977,9 @@ static int rockchip_sai_probe(struct platform_device *pdev) dev_info(&pdev->dev, "Have mclk compensation feature\n"); } + sai->no_set_mclk = + device_property_read_bool(&pdev->dev, "rockchip,mclk-no-set"); + sai->mclk = devm_clk_get(&pdev->dev, "mclk"); if (IS_ERR(sai->mclk)) { dev_err(&pdev->dev, "Failed to get mclk\n"); From 8a89e948a225b44434134aa7528f8d13ea278314 Mon Sep 17 00:00:00 2001 From: Xing Zheng Date: Thu, 9 Jan 2025 17:21:10 +0800 Subject: [PATCH 11/13] ARM: dts: rockchip: rk3506g-demo-display-control: fix noise dues to mclk and coeffs without matched The requirements of rk3506 codec are mainly divided into three sampling rate groups: 48/44.1/32kHz. And, the rk3506 codec has internal frequency division, the driver limits these three mclk inputs: #define MCLK_REFERENCE_8000 32768000 #define MCLK_REFERENCE_11025 45158400 #define MCLK_REFERENCE_12000 49152000 Therefore, it is necessary to add the "rockchip,mclk-no-set" property to the SAI4 to avoid switching the mclk frequency in the function of rockchip_sai_set_sysclk() after the codec configures mclk, causing the codec filter to work abnormally. Change-Id: Ic6cd0688287eb4c92c3b27bba4f60c46610c9006 Signed-off-by: Xing Zheng --- arch/arm/boot/dts/rk3506g-demo-display-control.dts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/boot/dts/rk3506g-demo-display-control.dts b/arch/arm/boot/dts/rk3506g-demo-display-control.dts index ec9438ffc3f8..1688896903ce 100644 --- a/arch/arm/boot/dts/rk3506g-demo-display-control.dts +++ b/arch/arm/boot/dts/rk3506g-demo-display-control.dts @@ -591,6 +591,7 @@ &sai1 { status = "okay"; + rockchip,mclk-no-set; pinctrl-names = "default"; pinctrl-0 = <&rm_io9_sai1_sclk &rm_io10_sai1_lrck @@ -600,6 +601,7 @@ &sai4 { status = "okay"; + rockchip,mclk-no-set; }; &saradc { From 00baab7edf25ef4f4350e1e0540d995cfd0202c1 Mon Sep 17 00:00:00 2001 From: William Wu Date: Tue, 14 Jan 2025 18:05:31 +0800 Subject: [PATCH 12/13] ARM: configs: rv1126-tb.config: Remove unused CONFIG_USB_DWC3_ROCKCHIP_INNO Change-Id: I5fb6b42f0d04885df5934465ab8cc57726089a4e Signed-off-by: William Wu --- arch/arm/configs/rv1126-tb.config | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/configs/rv1126-tb.config b/arch/arm/configs/rv1126-tb.config index 729df48a8cb0..49ce46ec1b4e 100644 --- a/arch/arm/configs/rv1126-tb.config +++ b/arch/arm/configs/rv1126-tb.config @@ -54,7 +54,6 @@ CONFIG_USB=m # CONFIG_USB_CONFIGFS_RNDIS is not set CONFIG_USB_DWC3=m CONFIG_USB_DWC3_OF_SIMPLE=m -CONFIG_USB_DWC3_ROCKCHIP_INNO=m CONFIG_USB_EHCI_HCD=m CONFIG_USB_EHCI_HCD_PLATFORM=m CONFIG_USB_HID=m From 9541ea94fb2af43fb641fdfa144802d1103ce6ba Mon Sep 17 00:00:00 2001 From: William Wu Date: Tue, 14 Jan 2025 18:07:41 +0800 Subject: [PATCH 13/13] Revert "usb: dwc3: add a new glue layer for rockchip SoCs with INNO PHY" This reverts commit 0cbdc8c1daf2bd9a42e653f4d85ad70c549b7265. The legacy glue layer driver dwc3-rockchip-inno.c is only used for RK3328/RK3228H platforms, and now they use the dwc3 core driver instead of the legacy driver, so let's discard the legacy driver. Change-Id: Ib1f43aacddea0e0155aa75b0efb58452b0514860 Signed-off-by: William Wu --- drivers/usb/dwc3/Kconfig | 9 - drivers/usb/dwc3/Makefile | 1 - drivers/usb/dwc3/dwc3-rockchip-inno.c | 282 -------------------------- 3 files changed, 292 deletions(-) delete mode 100644 drivers/usb/dwc3/dwc3-rockchip-inno.c diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index 506a42cff11d..864fef540a39 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig @@ -118,15 +118,6 @@ config USB_DWC3_OF_SIMPLE Currently supports Xilinx and Qualcomm DWC USB3 IP. Say 'Y' or 'M' if you have one such device. -config USB_DWC3_ROCKCHIP_INNO - bool "Rockchip Platforms with INNO PHY" - depends on OF && COMMON_CLK && (ARCH_ROCKCHIP || COMPILE_TEST) - default USB_DWC3 && PHY_ROCKCHIP_INNO_USB3 && NO_GKI - help - Support of USB2/3 functionality in Rockchip platforms - with INNO USB 3.0 PHY IP inside. - say 'Y' or 'M' if you have one such device. - config USB_DWC3_ST tristate "STMicroelectronics Platforms" depends on (ARCH_STI || COMPILE_TEST) && OF diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile index 5dccf31b1b5b..9f66bd82b639 100644 --- a/drivers/usb/dwc3/Makefile +++ b/drivers/usb/dwc3/Makefile @@ -50,7 +50,6 @@ obj-$(CONFIG_USB_DWC3_HAPS) += dwc3-haps.o obj-$(CONFIG_USB_DWC3_KEYSTONE) += dwc3-keystone.o obj-$(CONFIG_USB_DWC3_MESON_G12A) += dwc3-meson-g12a.o obj-$(CONFIG_USB_DWC3_OF_SIMPLE) += dwc3-of-simple.o -obj-$(CONFIG_USB_DWC3_ROCKCHIP_INNO) += dwc3-rockchip-inno.o obj-$(CONFIG_USB_DWC3_ST) += dwc3-st.o obj-$(CONFIG_USB_DWC3_QCOM) += dwc3-qcom.o obj-$(CONFIG_USB_DWC3_IMX8MP) += dwc3-imx8mp.o diff --git a/drivers/usb/dwc3/dwc3-rockchip-inno.c b/drivers/usb/dwc3/dwc3-rockchip-inno.c deleted file mode 100644 index 753cf58f68d6..000000000000 --- a/drivers/usb/dwc3/dwc3-rockchip-inno.c +++ /dev/null @@ -1,282 +0,0 @@ -/** - * dwc3-rockchip-inno.c - Rockchip DWC3 Specific Glue layer with INNO PHY - * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd - * - * Authors: William Wu - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 of - * the License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "core.h" - -#define XHCI_TSTCTRL_MASK (0xf << 28) -struct dwc3_rockchip { - struct device *dev; - struct clk **clks; - int num_clocks; - struct dwc3 *dwc; - struct usb_phy *phy; - struct notifier_block u3phy_nb; - struct work_struct u3_work; - struct mutex lock; -}; - -static int u3phy_disconnect_det_notifier(struct notifier_block *nb, - unsigned long event, void *p) -{ - struct dwc3_rockchip *rockchip = - container_of(nb, struct dwc3_rockchip, u3phy_nb); - - schedule_work(&rockchip->u3_work); - - return NOTIFY_DONE; -} - -static void u3phy_disconnect_det_work(struct work_struct *work) -{ - struct dwc3_rockchip *rockchip = - container_of(work, struct dwc3_rockchip, u3_work); - struct usb_hcd *hcd = dev_get_drvdata(&rockchip->dwc->xhci->dev); - u32 count = 0; - - mutex_lock(&rockchip->lock); - - if (hcd->state != HC_STATE_HALT) - dwc3_host_exit(rockchip->dwc); - - if (rockchip->phy) - usb_phy_shutdown(rockchip->phy); - - while (hcd->state != HC_STATE_HALT) { - if (++count > 1000) { - dev_err(rockchip->dev, - "wait for HCD remove 1s timeout!\n"); - break; - } - usleep_range(1000, 1100); - } - - if (hcd->state == HC_STATE_HALT) - dwc3_host_init(rockchip->dwc); - - if (rockchip->phy) - usb_phy_init(rockchip->phy); - - mutex_unlock(&rockchip->lock); -} - -static int dwc3_rockchip_probe(struct platform_device *pdev) -{ - struct dwc3_rockchip *rockchip; - struct device *dev = &pdev->dev; - struct device_node *np = dev->of_node, *child; - struct platform_device *child_pdev; - - unsigned int count; - int ret; - int i; - - rockchip = devm_kzalloc(dev, sizeof(*rockchip), GFP_KERNEL); - if (!rockchip) - return -ENOMEM; - - child = of_get_child_by_name(np, "dwc3"); - if (!child) { - dev_err(dev, "failed to find dwc3 core node\n"); - return -ENODEV; - } - - count = of_clk_get_parent_count(np); - if (!count) - return -ENOENT; - - rockchip->num_clocks = count; - - rockchip->clks = devm_kcalloc(dev, rockchip->num_clocks, - sizeof(struct clk *), GFP_KERNEL); - if (!rockchip->clks) - return -ENOMEM; - - platform_set_drvdata(pdev, rockchip); - rockchip->dev = dev; - - for (i = 0; i < rockchip->num_clocks; i++) { - struct clk *clk; - - clk = of_clk_get(np, i); - if (IS_ERR(clk)) { - ret = PTR_ERR(clk); - goto err0; - } - - ret = clk_prepare_enable(clk); - if (ret < 0) { - clk_put(clk); - goto err0; - } - - rockchip->clks[i] = clk; - } - - pm_runtime_set_active(dev); - pm_runtime_enable(dev); - ret = pm_runtime_get_sync(dev); - if (ret < 0) { - dev_err(dev, "get_sync failed with err %d\n", ret); - goto err1; - } - - ret = of_platform_populate(np, NULL, NULL, dev); - if (ret) - goto err1; - - child_pdev = of_find_device_by_node(child); - if (!child_pdev) { - dev_err(dev, "failed to find dwc3 core device\n"); - ret = -ENODEV; - goto err2; - } - - rockchip->dwc = platform_get_drvdata(child_pdev); - if (!rockchip->dwc || !rockchip->dwc->xhci) { - dev_dbg(dev, "failed to get drvdata dwc3\n"); - ret = -EPROBE_DEFER; - goto err2; - } - - mutex_init(&rockchip->lock); - - rockchip->phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3); - if (rockchip->phy) { - INIT_WORK(&rockchip->u3_work, u3phy_disconnect_det_work); - rockchip->u3phy_nb.notifier_call = - u3phy_disconnect_det_notifier; - usb_register_notifier(rockchip->phy, &rockchip->u3phy_nb); - } - - return 0; - -err2: - of_platform_depopulate(dev); -err1: - pm_runtime_put_sync(dev); - pm_runtime_disable(dev); -err0: - for (i = 0; i < rockchip->num_clocks && rockchip->clks[i]; i++) { - if (!pm_runtime_status_suspended(dev)) - clk_disable(rockchip->clks[i]); - clk_unprepare(rockchip->clks[i]); - clk_put(rockchip->clks[i]); - } - - return ret; -} - -static int dwc3_rockchip_remove(struct platform_device *pdev) -{ - struct dwc3_rockchip *rockchip = platform_get_drvdata(pdev); - struct device *dev = &pdev->dev; - int i; - - of_platform_depopulate(dev); - - pm_runtime_put_sync(dev); - pm_runtime_disable(dev); - - for (i = 0; i < rockchip->num_clocks; i++) { - if (!pm_runtime_status_suspended(dev)) - clk_disable(rockchip->clks[i]); - clk_unprepare(rockchip->clks[i]); - clk_put(rockchip->clks[i]); - } - - return 0; -} - -#ifdef CONFIG_PM -static int dwc3_rockchip_runtime_suspend(struct device *dev) -{ - struct dwc3_rockchip *rockchip = dev_get_drvdata(dev); - int i; - - for (i = 0; i < rockchip->num_clocks; i++) - clk_disable(rockchip->clks[i]); - - return 0; -} - -static int dwc3_rockchip_runtime_resume(struct device *dev) -{ - struct dwc3_rockchip *rockchip = dev_get_drvdata(dev); - int ret; - int i; - - for (i = 0; i < rockchip->num_clocks; i++) { - ret = clk_enable(rockchip->clks[i]); - if (ret < 0) { - while (--i >= 0) - clk_disable(rockchip->clks[i]); - return ret; - } - } - - return 0; -} - -static const struct dev_pm_ops dwc3_rockchip_dev_pm_ops = { - SET_RUNTIME_PM_OPS(dwc3_rockchip_runtime_suspend, - dwc3_rockchip_runtime_resume, NULL) -}; - -#define DEV_PM_OPS (&dwc3_rockchip_dev_pm_ops) -#else -#define DEV_PM_OPS NULL -#endif /* CONFIG_PM */ - -static const struct of_device_id rockchip_dwc3_match[] = { - { .compatible = "rockchip,rk3328-dwc3" }, - { /* Sentinel */ } -}; -MODULE_DEVICE_TABLE(of, rockchip_dwc3_match); - -static struct platform_driver dwc3_rockchip_driver = { - .probe = dwc3_rockchip_probe, - .remove = dwc3_rockchip_remove, - .driver = { - .name = "rockchip-inno-dwc3", - .pm = DEV_PM_OPS, - .of_match_table = rockchip_dwc3_match, - }, -}; - -module_platform_driver(dwc3_rockchip_driver); - -MODULE_ALIAS("platform:rockchip-inno-dwc3"); -MODULE_AUTHOR("William Wu "); -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("DesignWare USB3 rockchip-inno Glue Layer");