From cd80332fad862545830a96cb52cca7fe64433256 Mon Sep 17 00:00:00 2001 From: Jianwei Fan Date: Wed, 17 Jan 2024 06:02:03 +0000 Subject: [PATCH 01/13] media: rockchip: vicap update frame buffer with real frame phase when work with multi_dev combine to one Signed-off-by: Zefa Chen Change-Id: Ice0b4671955ceeede83c3496b741ae81d73602d9 --- drivers/media/platform/rockchip/cif/capture.c | 116 +++++++++++++++++- drivers/media/platform/rockchip/cif/dev.h | 1 + 2 files changed, 111 insertions(+), 6 deletions(-) diff --git a/drivers/media/platform/rockchip/cif/capture.c b/drivers/media/platform/rockchip/cif/capture.c index b68234830445..68bce3203255 100644 --- a/drivers/media/platform/rockchip/cif/capture.c +++ b/drivers/media/platform/rockchip/cif/capture.c @@ -1847,6 +1847,52 @@ RDBK_TOISP_UNMATCH: spin_unlock_irqrestore(&dev->hdr_lock, flags); } +static void rkcif_get_other_dev_update_frame_addr(struct rkcif_stream *stream, + int dev_idx, + u32 *frm_addr_y, + u32 *frm_addr_uv) +{ + struct v4l2_mbus_config *mbus_cfg = &stream->cifdev->active_sensor->mbus; + u32 intstat = stream->cifdev->other_intstat[dev_idx]; + int frame_phase = 0; + + switch (stream->id) { + case RKCIF_STREAM_MIPI_ID0: + frame_phase = SW_FRM_END_ID0(intstat); + break; + case RKCIF_STREAM_MIPI_ID1: + frame_phase = SW_FRM_END_ID1(intstat); + break; + case RKCIF_STREAM_MIPI_ID2: + frame_phase = SW_FRM_END_ID2(intstat); + break; + case RKCIF_STREAM_MIPI_ID3: + frame_phase = SW_FRM_END_ID3(intstat); + break; + } + + if (frame_phase == 0) + return; + + if (mbus_cfg->type == V4L2_MBUS_CSI2_DPHY || + mbus_cfg->type == V4L2_MBUS_CSI2_CPHY || + mbus_cfg->type == V4L2_MBUS_CCP2) { + *frm_addr_y = frame_phase & CIF_CSI_FRAME0_READY ? + get_reg_index_of_frm0_y_addr(stream->id) : + get_reg_index_of_frm1_y_addr(stream->id); + *frm_addr_uv = frame_phase & CIF_CSI_FRAME0_READY ? + get_reg_index_of_frm0_uv_addr(stream->id) : + get_reg_index_of_frm1_uv_addr(stream->id); + } else { + *frm_addr_y = frame_phase & CIF_CSI_FRAME0_READY ? + get_dvp_reg_index_of_frm0_y_addr(stream->id) : + get_dvp_reg_index_of_frm1_y_addr(stream->id); + *frm_addr_uv = frame_phase & CIF_CSI_FRAME0_READY ? + get_dvp_reg_index_of_frm0_uv_addr(stream->id) : + get_dvp_reg_index_of_frm1_uv_addr(stream->id); + } +} + static void rkcif_write_buff_addr_multi_dev_combine(struct rkcif_stream *stream, u32 frm_addr_y, u32 frm_addr_uv, u32 buff_addr_y, u32 buff_addr_cbcr, @@ -1858,8 +1904,11 @@ static void rkcif_write_buff_addr_multi_dev_combine(struct rkcif_stream *stream, int addr_offset = 0; int i = 0; int tmp_host_index = dev->csi_host_idx; + u32 tmp_frm_addr_y, tmp_frm_addr_uv; for (i = 0; i < capture_info->multi_dev.dev_num; i++) { + tmp_frm_addr_y = frm_addr_y; + tmp_frm_addr_uv = frm_addr_uv; if (is_dummy_buf) { addr_y = buff_addr_y; } else { @@ -1867,7 +1916,11 @@ static void rkcif_write_buff_addr_multi_dev_combine(struct rkcif_stream *stream, addr_y = buff_addr_y + addr_offset * i; } dev->csi_host_idx = capture_info->multi_dev.dev_idx[i]; - rkcif_write_register(dev, frm_addr_y, addr_y); + if (i < capture_info->multi_dev.dev_num - 1) + rkcif_get_other_dev_update_frame_addr(stream, i, + &tmp_frm_addr_y, + &tmp_frm_addr_uv); + rkcif_write_register(dev, tmp_frm_addr_y, addr_y); if (stream->cif_fmt_out->fmt_type != CIF_FMT_TYPE_RAW && frm_addr_uv && buff_addr_cbcr) { if (is_dummy_buf) { @@ -1876,7 +1929,7 @@ static void rkcif_write_buff_addr_multi_dev_combine(struct rkcif_stream *stream, addr_offset = dev->channels[stream->id].left_virtual_width; addr_cbcr = buff_addr_cbcr + addr_offset * i; } - rkcif_write_register(dev, frm_addr_uv, addr_cbcr); + rkcif_write_register(dev, tmp_frm_addr_uv, addr_cbcr); } } dev->csi_host_idx = tmp_host_index; @@ -4993,12 +5046,26 @@ static void rkcif_do_cru_reset(struct rkcif_device *dev) void rkcif_do_soft_reset(struct rkcif_device *dev) { + struct csi_channel_info *channel = &dev->channels[0]; + int tmp_csi_host_idx = 0; + int i = 0; + if (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) - rkcif_write_register_or(dev, CIF_REG_MIPI_LVDS_CTRL, 0x000A0000); - else + dev->active_sensor->mbus.type == V4L2_MBUS_CCP2) { + if (channel->capture_info.mode == RKMODULE_MULTI_DEV_COMBINE_ONE) { + tmp_csi_host_idx = dev->csi_host_idx; + for (i = 0; i < channel->capture_info.multi_dev.dev_num; i++) { + dev->csi_host_idx = channel->capture_info.multi_dev.dev_idx[i]; + rkcif_write_register_or(dev, CIF_REG_MIPI_LVDS_CTRL, 0x000A0000); + } + dev->csi_host_idx = tmp_csi_host_idx; + } else { + rkcif_write_register_or(dev, CIF_REG_MIPI_LVDS_CTRL, 0x000A0000); + } + } else { rkcif_write_register_or(dev, CIF_REG_DVP_CTRL, 0x000A0000); + } usleep_range(10, 20); v4l2_dbg(1, rkcif_debug, &dev->v4l2_dev, "vicap do soft reset 0x%x\n", 0x000A0000); @@ -5098,6 +5165,7 @@ void rkcif_do_stop_stream(struct rkcif_stream *stream, struct rkcif_buffer *buf = NULL; int ret; struct rkcif_hw *hw_dev = dev->hw_dev; + struct rkmodule_capture_info *capture_info = &dev->channels[0].capture_info; bool can_reset = true; int i; unsigned long flags; @@ -5240,6 +5308,10 @@ void rkcif_do_stop_stream(struct rkcif_stream *stream, if (dev->can_be_reset && dev->chip_id >= CHIP_RK3588_CIF) { rkcif_do_soft_reset(dev); atomic_set(&dev->streamoff_cnt, 0); + if (capture_info->mode == RKMODULE_MULTI_DEV_COMBINE_ONE) { + for (i = 0; i < capture_info->multi_dev.dev_num - 1; i++) + dev->other_intstat[i] = 0; + } } if (dev->can_be_reset && can_reset) { dev->can_be_reset = false; @@ -11375,17 +11447,39 @@ static void rkcif_check_mipi_interlaced_frame_id(struct rkcif_stream *stream) stream->last_fs_interlaced_phase = fs_interlaced_phase; } +static void rkcif_save_other_intstat_with_combine_mode(struct rkcif_device *cif_dev) +{ + struct rkmodule_capture_info *capture_info = &cif_dev->channels[0].capture_info; + int i = 0; + int tmp_csi_host = 0; + + if (capture_info->mode == RKMODULE_MULTI_DEV_COMBINE_ONE) { + tmp_csi_host = cif_dev->csi_host_idx; + for (i = 0; i < capture_info->multi_dev.dev_num - 1; i++) { + cif_dev->csi_host_idx = capture_info->multi_dev.dev_idx[i]; + cif_dev->other_intstat[i] = rkcif_read_register(cif_dev, CIF_REG_MIPI_LVDS_INTSTAT); + if (cif_dev->other_intstat[i]) + rkcif_write_register(cif_dev, + CIF_REG_MIPI_LVDS_INTSTAT, + cif_dev->other_intstat[i]); + } + cif_dev->csi_host_idx = tmp_csi_host; + } +} + /* pingpong irq for rk3588 and next */ void rkcif_irq_pingpong_v1(struct rkcif_device *cif_dev) { struct rkcif_stream *stream; struct rkcif_stream *detect_stream = &cif_dev->stream[0]; struct v4l2_mbus_config *mbus; + struct csi_channel_info *channel = &cif_dev->channels[0]; unsigned int intstat, i = 0xff; unsigned long flags; bool is_update = false; int ret = 0; int on = 0; + int tmp_csi_host_idx = 0; if (!cif_dev->active_sensor) return; @@ -11402,6 +11496,7 @@ void rkcif_irq_pingpong_v1(struct rkcif_device *cif_dev) cif_dev->err_state_work.lastline = lastline; cif_dev->err_state_work.intstat = intstat; + rkcif_save_other_intstat_with_combine_mode(cif_dev); /* clear all interrupts that has been triggered */ if (intstat) { rkcif_write_register(cif_dev, CIF_REG_MIPI_LVDS_INTSTAT, intstat); @@ -11424,7 +11519,16 @@ void rkcif_irq_pingpong_v1(struct rkcif_device *cif_dev) } cif_dev->irq_stats.csi_size_err_cnt++; cif_dev->err_state |= RKCIF_ERR_SIZE; - rkcif_write_register_or(cif_dev, CIF_REG_MIPI_LVDS_CTRL, 0x000A0000); + if (cif_dev->channels[0].capture_info.mode == RKMODULE_MULTI_DEV_COMBINE_ONE) { + tmp_csi_host_idx = cif_dev->csi_host_idx; + for (i = 0; i < channel->capture_info.multi_dev.dev_num; i++) { + cif_dev->csi_host_idx = channel->capture_info.multi_dev.dev_idx[i]; + rkcif_write_register_or(cif_dev, CIF_REG_MIPI_LVDS_CTRL, 0x000A0000); + } + cif_dev->csi_host_idx = tmp_csi_host_idx; + } else { + rkcif_write_register_or(cif_dev, CIF_REG_MIPI_LVDS_CTRL, 0x000A0000); + } return; } diff --git a/drivers/media/platform/rockchip/cif/dev.h b/drivers/media/platform/rockchip/cif/dev.h index 9f2113408f96..dfc0a690191c 100644 --- a/drivers/media/platform/rockchip/cif/dev.h +++ b/drivers/media/platform/rockchip/cif/dev.h @@ -939,6 +939,7 @@ struct rkcif_device { int sensor_state; u32 intr_mask; struct delayed_work work_deal_err; + u32 other_intstat[RKMODULE_MULTI_DEV_NUM]; }; extern struct platform_driver rkcif_plat_drv; From 079fa67494942657b96ed069c0dba21a5d57b88e Mon Sep 17 00:00:00 2001 From: Finley Xiao Date: Tue, 6 Feb 2024 18:34:26 +0800 Subject: [PATCH 02/13] soc: rockchip: ipa: Avoid NULL pointer when get static power Signed-off-by: Finley Xiao Change-Id: I5804b89c205d1d31cd933769bf4e41081d7625c5 --- drivers/soc/rockchip/rockchip_ipa.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/soc/rockchip/rockchip_ipa.c b/drivers/soc/rockchip/rockchip_ipa.c index e8982b7defee..51cbdabfd88f 100644 --- a/drivers/soc/rockchip/rockchip_ipa.c +++ b/drivers/soc/rockchip/rockchip_ipa.c @@ -200,6 +200,9 @@ rockchip_ipa_get_static_power(struct ipa_power_model_data *data, int temp; int ret; + if (!data) + return 0; + ret = data->tz->ops->get_temp(data->tz, &temp); if (ret) { pr_err("%s:failed to read %s temp\n", From bed6817b766a80ed9d49bbad3b5e3c6935778907 Mon Sep 17 00:00:00 2001 From: Yandong Lin Date: Tue, 6 Feb 2024 14:41:47 +0800 Subject: [PATCH 03/13] video: rockchip: mpp: fix get drv data type err Fix issue that he drvdata obtained through dev_get_drvdata does not match the converted type. Change-Id: I4f5835c2fed609714ac6cb94197ca84a489a3d23 Signed-off-by: Yandong Lin --- drivers/video/rockchip/mpp/mpp_av1dec.c | 30 ++++-------------------- drivers/video/rockchip/mpp/mpp_rkvdec.c | 25 ++++++++++---------- drivers/video/rockchip/mpp/mpp_rkvdec2.c | 7 +++--- drivers/video/rockchip/mpp/mpp_rkvenc.c | 7 +++--- drivers/video/rockchip/mpp/mpp_vdpp.c | 29 ++++------------------- 5 files changed, 31 insertions(+), 67 deletions(-) diff --git a/drivers/video/rockchip/mpp/mpp_av1dec.c b/drivers/video/rockchip/mpp/mpp_av1dec.c index b2449a870158..fcc3ed690499 100644 --- a/drivers/video/rockchip/mpp/mpp_av1dec.c +++ b/drivers/video/rockchip/mpp/mpp_av1dec.c @@ -1168,7 +1168,7 @@ static int av1dec_probe(struct platform_device *pdev) return -ENOMEM; mpp = &dec->mpp; - platform_set_drvdata(pdev, dec); + platform_set_drvdata(pdev, mpp); if (pdev->dev.of_node) { match = of_match_node(mpp_av1dec_dt_match, pdev->dev.of_node); @@ -1220,39 +1220,19 @@ failed_get_irq: static int av1dec_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct av1dec_dev *dec = platform_get_drvdata(pdev); + struct mpp_dev *mpp = platform_get_drvdata(pdev); dev_info(dev, "remove device\n"); - mpp_dev_remove(&dec->mpp); - av1dec_procfs_remove(&dec->mpp); + mpp_dev_remove(mpp); + av1dec_procfs_remove(mpp); return 0; } -static void av1dec_shutdown(struct platform_device *pdev) -{ - int ret; - int val; - struct device *dev = &pdev->dev; - struct av1dec_dev *dec = platform_get_drvdata(pdev); - struct mpp_dev *mpp = &dec->mpp; - - dev_info(dev, "shutdown device\n"); - - atomic_inc(&mpp->srv->shutdown_request); - ret = readx_poll_timeout(atomic_read, - &mpp->task_count, - val, val == 0, 1000, 200000); - if (ret == -ETIMEDOUT) - dev_err(dev, "wait total running time out\n"); - - dev_info(dev, "shutdown success\n"); -} - struct platform_driver rockchip_av1dec_driver = { .probe = av1dec_probe, .remove = av1dec_remove, - .shutdown = av1dec_shutdown, + .shutdown = mpp_dev_shutdown, .driver = { .name = AV1DEC_DRIVER_NAME, .of_match_table = of_match_ptr(mpp_av1dec_dt_match), diff --git a/drivers/video/rockchip/mpp/mpp_rkvdec.c b/drivers/video/rockchip/mpp/mpp_rkvdec.c index 4310a09a5ce0..a345273833a5 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvdec.c +++ b/drivers/video/rockchip/mpp/mpp_rkvdec.c @@ -329,8 +329,8 @@ static int devfreq_target(struct device *dev, struct dev_pm_opp *opp; unsigned long target_volt, target_freq; unsigned long aclk_rate_hz, core_rate_hz, cabac_rate_hz; - - struct rkvdec_dev *dec = dev_get_drvdata(dev); + struct mpp_dev *mpp = dev_get_drvdata(dev); + struct rkvdec_dev *dec = to_rkvdec_dev(mpp); struct devfreq *devfreq = dec->devfreq; struct devfreq_dev_status *stat = &devfreq->last_status; unsigned long old_clk_rate = stat->current_frequency; @@ -396,7 +396,8 @@ static int devfreq_target(struct device *dev, static int devfreq_get_cur_freq(struct device *dev, unsigned long *freq) { - struct rkvdec_dev *dec = dev_get_drvdata(dev); + struct mpp_dev *mpp = dev_get_drvdata(dev); + struct rkvdec_dev *dec = to_rkvdec_dev(mpp); *freq = clk_get_rate(dec->aclk_info.clk); @@ -406,7 +407,8 @@ static int devfreq_get_cur_freq(struct device *dev, static int devfreq_get_dev_status(struct device *dev, struct devfreq_dev_status *stat) { - struct rkvdec_dev *dec = dev_get_drvdata(dev); + struct mpp_dev *mpp = dev_get_drvdata(dev); + struct rkvdec_dev *dec = to_rkvdec_dev(mpp); struct devfreq *devfreq = dec->devfreq; memcpy(stat, &devfreq->last_status, sizeof(*stat)); @@ -420,12 +422,11 @@ static struct devfreq_dev_profile devfreq_profile = { .get_dev_status = devfreq_get_dev_status, }; -static unsigned long -model_static_power(struct devfreq *devfreq, - unsigned long voltage) +static unsigned long model_static_power(struct devfreq *devfreq, unsigned long voltage) { struct device *dev = devfreq->dev.parent; - struct rkvdec_dev *dec = dev_get_drvdata(dev); + struct mpp_dev *mpp = dev_get_drvdata(dev); + struct rkvdec_dev *dec = to_rkvdec_dev(mpp); struct thermal_zone_device *tz = dec->thermal_zone; int temperature; @@ -1387,7 +1388,7 @@ static int rkvdec_devfreq_init(struct mpp_dev *mpp) /* power simplle init */ ret = power_model_simple_init(mpp); - if (!ret && dec->devfreq) { + if (!ret) { dec->devfreq_cooling = of_devfreq_cooling_register_power(mpp->dev->of_node, dec->devfreq, @@ -2018,11 +2019,11 @@ static int rkvdec_probe(struct platform_device *pdev) static int rkvdec_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct rkvdec_dev *dec = platform_get_drvdata(pdev); + struct mpp_dev *mpp = platform_get_drvdata(pdev); dev_info(dev, "remove device\n"); - mpp_dev_remove(&dec->mpp); - rkvdec_procfs_remove(&dec->mpp); + mpp_dev_remove(mpp); + rkvdec_procfs_remove(mpp); return 0; } diff --git a/drivers/video/rockchip/mpp/mpp_rkvdec2.c b/drivers/video/rockchip/mpp/mpp_rkvdec2.c index decd5e25c252..5a910158bed1 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvdec2.c +++ b/drivers/video/rockchip/mpp/mpp_rkvdec2.c @@ -713,8 +713,8 @@ static int rkvdec2_devfreq_target(struct device *dev, struct dev_pm_opp *opp; unsigned long target_volt, target_freq; int ret = 0; - - struct rkvdec2_dev *dec = dev_get_drvdata(dev); + struct mpp_dev *mpp = dev_get_drvdata(dev); + struct rkvdec2_dev *dec = to_rkvdec2_dev(mpp); struct devfreq *devfreq = dec->devfreq; struct devfreq_dev_status *stat = &devfreq->last_status; unsigned long old_clk_rate = stat->current_frequency; @@ -776,7 +776,8 @@ static int rkvdec2_devfreq_get_dev_status(struct device *dev, static int rkvdec2_devfreq_get_cur_freq(struct device *dev, unsigned long *freq) { - struct rkvdec2_dev *dec = dev_get_drvdata(dev); + struct mpp_dev *mpp = dev_get_drvdata(dev); + struct rkvdec2_dev *dec = to_rkvdec2_dev(mpp); *freq = dec->core_last_rate_hz; diff --git a/drivers/video/rockchip/mpp/mpp_rkvenc.c b/drivers/video/rockchip/mpp/mpp_rkvenc.c index 624d15e6783b..4e0d68c7479f 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvenc.c +++ b/drivers/video/rockchip/mpp/mpp_rkvenc.c @@ -852,8 +852,8 @@ static int rkvenc_devfreq_target(struct device *dev, struct dev_pm_opp *opp; unsigned long target_volt, target_freq; int ret = 0; - - struct rkvenc_dev *enc = dev_get_drvdata(dev); + struct mpp_dev *mpp = dev_get_drvdata(dev); + struct rkvenc_dev *enc = to_rkvenc_dev(mpp); struct devfreq *devfreq = enc->devfreq; struct devfreq_dev_status *stat = &devfreq->last_status; unsigned long old_clk_rate = stat->current_frequency; @@ -915,7 +915,8 @@ static int rkvenc_devfreq_get_dev_status(struct device *dev, static int rkvenc_devfreq_get_cur_freq(struct device *dev, unsigned long *freq) { - struct rkvenc_dev *enc = dev_get_drvdata(dev); + struct mpp_dev *mpp = dev_get_drvdata(dev); + struct rkvenc_dev *enc = to_rkvenc_dev(mpp); *freq = enc->core_last_rate_hz; diff --git a/drivers/video/rockchip/mpp/mpp_vdpp.c b/drivers/video/rockchip/mpp/mpp_vdpp.c index c0dc382a1872..031a975e00bf 100644 --- a/drivers/video/rockchip/mpp/mpp_vdpp.c +++ b/drivers/video/rockchip/mpp/mpp_vdpp.c @@ -696,9 +696,8 @@ static int vdpp_probe(struct platform_device *pdev) vdpp = devm_kzalloc(dev, sizeof(struct vdpp_dev), GFP_KERNEL); if (!vdpp) return -ENOMEM; - platform_set_drvdata(pdev, vdpp); - mpp = &vdpp->mpp; + platform_set_drvdata(pdev, mpp); if (pdev->dev.of_node) { match = of_match_node(mpp_vdpp_dt_match, pdev->dev.of_node); if (match) @@ -745,37 +744,19 @@ static int vdpp_probe(struct platform_device *pdev) static int vdpp_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct vdpp_dev *vdpp = platform_get_drvdata(pdev); + struct mpp_dev *mpp = platform_get_drvdata(pdev); dev_info(dev, "remove device\n"); - mpp_dev_remove(&vdpp->mpp); - vdpp_procfs_remove(&vdpp->mpp); + mpp_dev_remove(mpp); + vdpp_procfs_remove(mpp); return 0; } -static void vdpp_shutdown(struct platform_device *pdev) -{ - int ret; - int val; - struct device *dev = &pdev->dev; - struct vdpp_dev *vdpp = platform_get_drvdata(pdev); - struct mpp_dev *mpp = &vdpp->mpp; - - dev_info(dev, "shutdown device\n"); - - atomic_inc(&mpp->srv->shutdown_request); - ret = readx_poll_timeout(atomic_read, - &mpp->task_count, - val, val == 0, 20000, 200000); - if (ret == -ETIMEDOUT) - dev_err(dev, "wait total running time out\n"); -} - struct platform_driver rockchip_vdpp_driver = { .probe = vdpp_probe, .remove = vdpp_remove, - .shutdown = vdpp_shutdown, + .shutdown = mpp_dev_shutdown, .driver = { .name = VDPP_DRIVER_NAME, .of_match_table = of_match_ptr(mpp_vdpp_dt_match), From edbfad5e8605a8d36334fd6637e72e0f93628850 Mon Sep 17 00:00:00 2001 From: Jianwei Fan Date: Mon, 22 Jan 2024 09:50:14 +0000 Subject: [PATCH 04/13] media: i2c: rk628: add suspend and resume support Change-Id: I8da6815fe9f95d7e29e7dd0fad186e2dbbc35b42 Signed-off-by: Jianwei Fan --- drivers/media/i2c/rk628/rk628_bt1120_v4l2.c | 132 ++++++++++++++---- drivers/media/i2c/rk628/rk628_csi_v4l2.c | 141 +++++++++++++++----- 2 files changed, 214 insertions(+), 59 deletions(-) diff --git a/drivers/media/i2c/rk628/rk628_bt1120_v4l2.c b/drivers/media/i2c/rk628/rk628_bt1120_v4l2.c index bfb1653c80d8..0a713ae6d37d 100644 --- a/drivers/media/i2c/rk628/rk628_bt1120_v4l2.c +++ b/drivers/media/i2c/rk628/rk628_bt1120_v4l2.c @@ -820,13 +820,12 @@ static int rk628_hdmirx_phy_setup(struct v4l2_subdev *sd) return 0; } - -static void rk628_bt1120_initial_setup(struct v4l2_subdev *sd) +static void rk628_bt1120_initial(struct v4l2_subdev *sd) { struct rk628_bt1120 *bt1120 = to_bt1120(sd); struct v4l2_subdev_edid def_edid; - /* selete int io function */ + /* select int io function */ rk628_i2c_write(bt1120->rk628, GRF_GPIO3AB_SEL_CON, 0x30002000); rk628_i2c_write(bt1120->rk628, GRF_GPIO1AB_SEL_CON, HIWORD_UPDATE(0x7, 11, 8)); /* I2S_SCKM0 */ @@ -873,7 +872,13 @@ static void rk628_bt1120_initial_setup(struct v4l2_subdev *sd) def_edid.edid = edid_init_data; rk628_bt1120_s_edid(sd, &def_edid); rk628_hdmirx_set_hdcp(bt1120->rk628, &bt1120->hdcp, false); +} +static void rk628_bt1120_initial_setup(struct v4l2_subdev *sd) +{ + struct rk628_bt1120 *bt1120 = to_bt1120(sd); + + rk628_bt1120_initial(sd); if (tx_5v_power_present(sd)) schedule_delayed_work(&bt1120->delayed_work_enable_hotplug, 4000); } @@ -1685,6 +1690,91 @@ static irqreturn_t plugin_detect_irq(int irq, void *dev_id) return IRQ_HANDLED; } +static int rk628_bt1120_power_on(struct rk628_bt1120 *bt1120) +{ + clk_prepare_enable(bt1120->soc_24M); + if (bt1120->enable_gpio) { + gpiod_set_value(bt1120->enable_gpio, 1); + usleep_range(10000, 11000); + } + gpiod_set_value(bt1120->reset_gpio, 0); + usleep_range(10000, 11000); + gpiod_set_value(bt1120->reset_gpio, 1); + usleep_range(10000, 11000); + gpiod_set_value(bt1120->reset_gpio, 0); + usleep_range(10000, 11000); + + if (bt1120->power_gpio) { + gpiod_set_value(bt1120->power_gpio, 1); + usleep_range(10000, 11000); + } + + return 0; +} + +static int rk628_bt1120_power_off(struct rk628_bt1120 *bt1120) +{ + if (bt1120->enable_gpio) { + gpiod_set_value(bt1120->enable_gpio, 0); + usleep_range(10000, 11000); + } + gpiod_set_value(bt1120->reset_gpio, 1); + usleep_range(10000, 11000); + gpiod_set_value(bt1120->reset_gpio, 0); + usleep_range(10000, 11000); + gpiod_set_value(bt1120->reset_gpio, 1); + usleep_range(10000, 11000); + + if (bt1120->power_gpio) { + gpiod_set_value(bt1120->power_gpio, 0); + usleep_range(10000, 11000); + } + clk_disable_unprepare(bt1120->soc_24M); + + return 0; +} + +static int rk628_bt1120_resume(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct rk628_bt1120 *bt1120 = to_bt1120(sd); + + v4l2_info(sd, "%s: resume!\n", __func__); + + rk628_bt1120_power_on(bt1120); + rk628_cru_initialize(bt1120->rk628); + rk628_bt1120_initial(sd); + rk628_hdmirx_plugout(sd); + enable_irq(bt1120->hdmirx_irq); + schedule_delayed_work(&bt1120->delayed_work_enable_hotplug, + msecs_to_jiffies(500)); + + return 0; +} + +static int rk628_bt1120_suspend(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct rk628_bt1120 *bt1120 = to_bt1120(sd); + + v4l2_info(sd, "%s: suspend!\n", __func__); + + disable_irq(bt1120->hdmirx_irq); + cancel_delayed_work_sync(&bt1120->delayed_work_res_change); + cancel_delayed_work_sync(&bt1120->delayed_work_enable_hotplug); + rk628_hdmirx_audio_cancel_work_audio(bt1120->audio_info, true); + rk628_bt1120_power_off(bt1120); + + return 0; +} + +static const struct dev_pm_ops rk628_bt1120_pm_ops = { + .suspend = rk628_bt1120_suspend, + .resume = rk628_bt1120_resume, +}; + static int rk628_bt1120_probe_of(struct rk628_bt1120 *bt1120) { struct device *dev = bt1120->dev; @@ -1701,28 +1791,27 @@ static int rk628_bt1120_probe_of(struct rk628_bt1120 *bt1120) ret = PTR_ERR(bt1120->soc_24M); dev_err(dev, "Unable to get soc_24M: %d\n", ret); } - clk_prepare_enable(bt1120->soc_24M); bt1120->enable_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_LOW); if (IS_ERR(bt1120->enable_gpio)) { ret = PTR_ERR(bt1120->enable_gpio); dev_err(dev, "failed to request enable GPIO: %d\n", ret); - goto clk_put; + return ret; } bt1120->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); if (IS_ERR(bt1120->reset_gpio)) { ret = PTR_ERR(bt1120->reset_gpio); dev_err(dev, "failed to request reset GPIO: %d\n", ret); - goto clk_put; + return ret; } bt1120->power_gpio = devm_gpiod_get_optional(dev, "power", GPIOD_OUT_HIGH); if (IS_ERR(bt1120->power_gpio)) { dev_err(dev, "failed to get power gpio\n"); ret = PTR_ERR(bt1120->power_gpio); - goto clk_put; + return ret; } bt1120->plugin_det_gpio = devm_gpiod_get_optional(dev, "plugin-det", @@ -1730,26 +1819,10 @@ static int rk628_bt1120_probe_of(struct rk628_bt1120 *bt1120) if (IS_ERR(bt1120->plugin_det_gpio)) { dev_err(dev, "failed to get hdmirx det gpio\n"); ret = PTR_ERR(bt1120->plugin_det_gpio); - goto clk_put; + return ret; } bt1120->rk628->hdmirx_det_gpio = bt1120->plugin_det_gpio; - if (bt1120->enable_gpio) { - gpiod_set_value(bt1120->enable_gpio, 1); - usleep_range(10000, 11000); - } - gpiod_set_value(bt1120->reset_gpio, 0); - usleep_range(10000, 11000); - gpiod_set_value(bt1120->reset_gpio, 1); - usleep_range(10000, 11000); - gpiod_set_value(bt1120->reset_gpio, 0); - usleep_range(10000, 11000); - - if (bt1120->power_gpio) { - gpiod_set_value(bt1120->power_gpio, 1); - usleep_range(500, 510); - } - if (of_property_read_bool(dev->of_node, "hdcp-enable")) hdcp1x_enable = true; @@ -1769,14 +1842,14 @@ static int rk628_bt1120_probe_of(struct rk628_bt1120 *bt1120) if (!ep) { dev_err(dev, "missing endpoint node\n"); ret = -EINVAL; - goto clk_put; + return ret; } ret = v4l2_fwnode_endpoint_alloc_parse(of_fwnode_handle(ep), &endpoint); of_node_put(ep); if (ret) { dev_err(dev, "failed to parse endpoint\n"); - goto clk_put; + return ret; } bt1120->enable_hdcp = hdcp1x_enable; @@ -1793,9 +1866,6 @@ static int rk628_bt1120_probe_of(struct rk628_bt1120 *bt1120) v4l2_fwnode_endpoint_free(&endpoint); -clk_put: - clk_disable_unprepare(bt1120->soc_24M); - return ret; } @@ -1855,6 +1925,7 @@ static int rk628_bt1120_probe(struct i2c_client *client, return err; } + rk628_bt1120_power_on(bt1120); rk628_cru_initialize(rk628); rk628_version_parse(rk628); @@ -2007,6 +2078,7 @@ err_hdl: mutex_destroy(&bt1120->confctl_mutex); media_entity_cleanup(&sd->entity); v4l2_ctrl_handler_free(&bt1120->hdl); + rk628_bt1120_power_off(bt1120); return err; } @@ -2039,6 +2111,7 @@ static int rk628_bt1120_remove(struct i2c_client *client) rk628_control_assert(bt1120->rk628, RGU_CLK_RX); rk628_control_assert(bt1120->rk628, RGU_VOP); rk628_control_assert(bt1120->rk628, RGU_BT1120DEC); + rk628_bt1120_power_off(bt1120); return 0; } @@ -2059,6 +2132,7 @@ MODULE_DEVICE_TABLE(of, rk628_bt1120_of_match); static struct i2c_driver rk628_bt1120_i2c_driver = { .driver = { .name = "rk628-bt1120-v4l2", + .pm = &rk628_bt1120_pm_ops, .of_match_table = of_match_ptr(rk628_bt1120_of_match), }, .id_table = rk628_bt1120_i2c_id, diff --git a/drivers/media/i2c/rk628/rk628_csi_v4l2.c b/drivers/media/i2c/rk628/rk628_csi_v4l2.c index bf0a32710aee..82d7d064266f 100644 --- a/drivers/media/i2c/rk628/rk628_csi_v4l2.c +++ b/drivers/media/i2c/rk628/rk628_csi_v4l2.c @@ -1277,14 +1277,14 @@ static int rk628_hdmirx_phy_setup(struct v4l2_subdev *sd) return 0; } -static void rk628_csi_initial_setup(struct v4l2_subdev *sd) +static void rk628_csi_initial(struct v4l2_subdev *sd) { struct rk628_csi *csi = to_csi(sd); struct v4l2_subdev_edid def_edid; u32 mask = SW_OUTPUT_MODE_MASK; u32 val = SW_OUTPUT_MODE(OUTPUT_MODE_CSI); - /* selete int io function */ + /* select int io function */ rk628_i2c_write(csi->rk628, GRF_GPIO3AB_SEL_CON, 0x30002000); rk628_i2c_write(csi->rk628, GRF_GPIO1AB_SEL_CON, HIWORD_UPDATE(0xf, 11, 8)); /* I2S_SCKM0 */ @@ -1341,7 +1341,13 @@ static void rk628_csi_initial_setup(struct v4l2_subdev *sd) def_edid.edid = edid_init_data; rk628_csi_s_edid(sd, &def_edid); rk628_hdmirx_set_hdcp(csi->rk628, &csi->hdcp, false); +} +static void rk628_csi_initial_setup(struct v4l2_subdev *sd) +{ + struct rk628_csi *csi = to_csi(sd); + + rk628_csi_initial(sd); if (csi->rk628->version >= RK628F_VERSION) { csi->rk628->mipi_timing[0] = rk628f_csi0_mipi; csi->rk628->mipi_timing[1] = rk628f_csi1_mipi; @@ -2644,6 +2650,91 @@ static irqreturn_t plugin_detect_irq(int irq, void *dev_id) return IRQ_HANDLED; } +static int rk628_csi_power_on(struct rk628_csi *csi) +{ + clk_prepare_enable(csi->soc_24M); + if (csi->enable_gpio) { + gpiod_set_value(csi->enable_gpio, 1); + usleep_range(10000, 11000); + } + gpiod_set_value(csi->reset_gpio, 0); + usleep_range(10000, 11000); + gpiod_set_value(csi->reset_gpio, 1); + usleep_range(10000, 11000); + gpiod_set_value(csi->reset_gpio, 0); + usleep_range(10000, 11000); + + if (csi->power_gpio) { + gpiod_set_value(csi->power_gpio, 1); + usleep_range(10000, 11000); + } + + return 0; +} + +static int rk628_csi_power_off(struct rk628_csi *csi) +{ + if (csi->enable_gpio) { + gpiod_set_value(csi->enable_gpio, 0); + usleep_range(10000, 11000); + } + gpiod_set_value(csi->reset_gpio, 1); + usleep_range(10000, 11000); + gpiod_set_value(csi->reset_gpio, 0); + usleep_range(10000, 11000); + gpiod_set_value(csi->reset_gpio, 1); + usleep_range(10000, 11000); + + if (csi->power_gpio) { + gpiod_set_value(csi->power_gpio, 0); + usleep_range(10000, 11000); + } + clk_disable_unprepare(csi->soc_24M); + + return 0; +} + +static int rk628_csi_resume(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct rk628_csi *csi = to_csi(sd); + + v4l2_info(sd, "%s: resume!\n", __func__); + + rk628_csi_power_on(csi); + rk628_cru_initialize(csi->rk628); + rk628_csi_initial(sd); + rk628_hdmirx_plugout(sd); + enable_irq(csi->hdmirx_irq); + schedule_delayed_work(&csi->delayed_work_enable_hotplug, + msecs_to_jiffies(500)); + + return 0; +} + +static int rk628_csi_suspend(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct rk628_csi *csi = to_csi(sd); + + v4l2_info(sd, "%s: suspend!\n", __func__); + + disable_irq(csi->hdmirx_irq); + cancel_delayed_work_sync(&csi->delayed_work_res_change); + cancel_delayed_work_sync(&csi->delayed_work_enable_hotplug); + rk628_hdmirx_audio_cancel_work_audio(csi->audio_info, true); + rk628_csi_power_off(csi); + + return 0; +} + +static const struct dev_pm_ops rk628_csi_pm_ops = { + .suspend = rk628_csi_suspend, + .resume = rk628_csi_resume, +}; + static int rk628_csi_probe_of(struct rk628_csi *csi) { struct device *dev = csi->dev; @@ -2661,28 +2752,27 @@ static int rk628_csi_probe_of(struct rk628_csi *csi) ret = PTR_ERR(csi->soc_24M); dev_err(dev, "Unable to get soc_24M: %d\n", ret); } - clk_prepare_enable(csi->soc_24M); csi->enable_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_LOW); if (IS_ERR(csi->enable_gpio)) { ret = PTR_ERR(csi->enable_gpio); dev_err(dev, "failed to request enable GPIO: %d\n", ret); - goto clk_put; + return ret; } csi->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); if (IS_ERR(csi->reset_gpio)) { ret = PTR_ERR(csi->reset_gpio); dev_err(dev, "failed to request reset GPIO: %d\n", ret); - goto clk_put; + return ret; } csi->power_gpio = devm_gpiod_get_optional(dev, "power", GPIOD_OUT_HIGH); if (IS_ERR(csi->power_gpio)) { dev_err(dev, "failed to get power gpio\n"); ret = PTR_ERR(csi->power_gpio); - goto clk_put; + return ret; } csi->plugin_det_gpio = devm_gpiod_get_optional(dev, "plugin-det", @@ -2690,26 +2780,10 @@ static int rk628_csi_probe_of(struct rk628_csi *csi) if (IS_ERR(csi->plugin_det_gpio)) { dev_err(dev, "failed to get hdmirx det gpio\n"); ret = PTR_ERR(csi->plugin_det_gpio); - goto clk_put; + return ret; } csi->rk628->hdmirx_det_gpio = csi->plugin_det_gpio; - if (csi->enable_gpio) { - gpiod_set_value(csi->enable_gpio, 1); - usleep_range(10000, 11000); - } - gpiod_set_value(csi->reset_gpio, 0); - usleep_range(10000, 11000); - gpiod_set_value(csi->reset_gpio, 1); - usleep_range(10000, 11000); - gpiod_set_value(csi->reset_gpio, 0); - usleep_range(10000, 11000); - - if (csi->power_gpio) { - gpiod_set_value(csi->power_gpio, 1); - usleep_range(500, 510); - } - if (of_property_read_bool(dev->of_node, "hdcp-enable")) hdcp1x_enable = true; @@ -2736,7 +2810,7 @@ static int rk628_csi_probe_of(struct rk628_csi *csi) if (!ep) { dev_err(dev, "missing endpoint node\n"); ret = -EINVAL; - goto clk_put; + return ret; } ret = v4l2_fwnode_endpoint_alloc_parse(of_fwnode_handle(ep), &endpoint); @@ -2771,8 +2845,6 @@ free_endpoint: v4l2_fwnode_endpoint_free(&endpoint); put_node: of_node_put(ep); -clk_put: - clk_disable_unprepare(csi->soc_24M); return ret; } @@ -2929,6 +3001,7 @@ static int rk628_csi_probe(struct i2c_client *client, return err; } + rk628_csi_power_on(csi); rk628_cru_initialize(csi->rk628); rk628_version_parse(rk628); @@ -2939,14 +3012,15 @@ static int rk628_csi_probe(struct i2c_client *client, v4l2_info(sd, "get multi dev info failed, not use dual mipi mode\n"); } - v4l2_subdev_init(sd, &rk628_csi_ops); + v4l2_i2c_subdev_init(sd, client, &rk628_csi_ops); sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS; /* i2c access, read chip id*/ err = rk628_i2c_read(csi->rk628, CSITX_CSITX_VERSION, &val); if (err) { v4l2_err(sd, "i2c access failed! err:%d\n", err); - return -ENODEV; + err = -ENODEV; + goto power_off; } v4l2_dbg(1, debug, sd, "CSITX VERSION: %#x\n", val); @@ -2954,7 +3028,8 @@ static int rk628_csi_probe(struct i2c_client *client, err = rk628_i2c_read(csi->rk628, CSITX1_CSITX_VERSION, &val); if (err) { v4l2_err(sd, "i2c access failed! err:%d\n", err); - return -ENODEV; + err = -ENODEV; + goto power_off; } v4l2_dbg(1, debug, sd, "CSITX1 VERSION: %#x\n", val); } @@ -2964,7 +3039,8 @@ static int rk628_csi_probe(struct i2c_client *client, csi->txphy = rk628_txphy_register(rk628); if (!csi->txphy) { v4l2_err(sd, "register txphy failed\n"); - return -ENOMEM; + err = -ENOMEM; + goto power_off; } /* control handlers */ @@ -3112,6 +3188,9 @@ err_hdl: mutex_destroy(&csi->confctl_mutex); media_entity_cleanup(&sd->entity); v4l2_ctrl_handler_free(&csi->hdl); +power_off: + rk628_csi_power_off(csi); + return err; } @@ -3153,6 +3232,7 @@ static int rk628_csi_remove(struct i2c_client *client) rk628_control_assert(csi->rk628, RGU_CSI); if (csi->rk628->version >= RK628F_VERSION) rk628_control_assert(csi->rk628, RGU_CSI1); + rk628_csi_power_off(csi); #if KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE return 0; #endif @@ -3161,6 +3241,7 @@ static int rk628_csi_remove(struct i2c_client *client) static struct i2c_driver rk628_csi_i2c_driver = { .driver = { .name = "rk628-csi-v4l2", + .pm = &rk628_csi_pm_ops, .of_match_table = of_match_ptr(rk628_csi_of_match), }, .id_table = rk628_csi_i2c_id, From fb8c650f263a5add684949a261e6e6c42278eb32 Mon Sep 17 00:00:00 2001 From: Zhibin Huang Date: Tue, 30 Jan 2024 11:56:50 +0000 Subject: [PATCH 05/13] drm/panel: panel-simple: power-on and power-off timing optimization 1. move the dsi sequence from prepare/unprepare to resume/suspend 2. remove duplicate unprepare times Type: Fix Redmine ID: 460825 Associated modifications: commit 3235b0f20a0a ("drm/panel: panel-simple: Use runtime pm to avoid excessive unprepare / prepare") commit e5e30dfcf3db ("drm: panel: simple: Defer unprepare delay till next prepare to shorten it") Test: N/A Signed-off-by: Zhibin Huang Change-Id: I05c907ac25f40126f2d1751346ecb09f4252cf46 --- drivers/gpu/drm/panel/panel-simple.c | 68 ++++++++++++++++------------ 1 file changed, 38 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 89238f75dfd1..205dacba201c 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -218,6 +218,8 @@ struct panel_simple { struct drm_dsc_picture_parameter_set *pps; enum drm_panel_orientation orientation; + + bool loader_protect; }; static inline void panel_simple_msleep(unsigned int msecs) @@ -536,6 +538,8 @@ int panel_simple_loader_protect(struct drm_panel *panel) struct panel_simple *p = to_panel_simple(panel); int err; + p->loader_protect = true; + err = pm_runtime_get_sync(panel->dev); if (err < 0) { pm_runtime_put_autosuspend(panel->dev); @@ -567,15 +571,25 @@ static int panel_simple_disable(struct drm_panel *panel) static int panel_simple_suspend(struct device *dev) { struct panel_simple *p = dev_get_drvdata(dev); + struct drm_panel *panel = &p->base; + + if (p->desc->exit_seq) { + if (p->desc->cmd_type == CMD_TYPE_SPI) { + if (panel_simple_xfer_spi_cmd_seq(p, p->desc->exit_seq)) { + dev_err(panel->dev, "failed to send exit spi cmds seq\n"); + return -EINVAL; + } + } else { + if (p->dsi) + panel_simple_xfer_dsi_cmd_seq(p, p->desc->exit_seq); + } + } gpiod_set_value_cansleep(p->reset_gpio, 1); gpiod_set_value_cansleep(p->enable_gpio, 0); panel_simple_regulator_disable(p); - if (p->desc->delay.unprepare) - panel_simple_msleep(p->desc->delay.unprepare); - p->unprepared_time = ktime_get_boottime(); kfree(p->edid); @@ -593,18 +607,6 @@ static int panel_simple_unprepare(struct drm_panel *panel) if (!p->prepared) return 0; - if (p->desc->exit_seq) { - if (p->desc->cmd_type == CMD_TYPE_SPI) { - if (panel_simple_xfer_spi_cmd_seq(p, p->desc->exit_seq)) { - dev_err(panel->dev, "failed to send exit spi cmds seq\n"); - return -EINVAL; - } - } else { - if (p->dsi) - panel_simple_xfer_dsi_cmd_seq(p, p->desc->exit_seq); - } - } - pm_runtime_mark_last_busy(panel->dev); ret = pm_runtime_put_autosuspend(panel->dev); if (ret < 0) @@ -617,6 +619,7 @@ static int panel_simple_unprepare(struct drm_panel *panel) static int panel_simple_resume(struct device *dev) { struct panel_simple *p = dev_get_drvdata(dev); + struct drm_panel *panel = &p->base; int err; panel_simple_wait(p->unprepared_time, p->desc->delay.unprepare); @@ -634,22 +637,9 @@ static int panel_simple_resume(struct device *dev) p->prepared_time = ktime_get_boottime(); - return 0; -} - -static int panel_simple_prepare(struct drm_panel *panel) -{ - struct panel_simple *p = to_panel_simple(panel); - int ret; - - /* Preparing when already prepared is a no-op */ - if (p->prepared) + if (p->loader_protect) { + p->loader_protect = false; return 0; - - ret = pm_runtime_get_sync(panel->dev); - if (ret < 0) { - pm_runtime_put_autosuspend(panel->dev); - return ret; } gpiod_set_value_cansleep(p->reset_gpio, 1); @@ -674,6 +664,24 @@ static int panel_simple_prepare(struct drm_panel *panel) } } + return 0; +} + +static int panel_simple_prepare(struct drm_panel *panel) +{ + struct panel_simple *p = to_panel_simple(panel); + int ret; + + /* Preparing when already prepared is a no-op */ + if (p->prepared) + return 0; + + ret = pm_runtime_get_sync(panel->dev); + if (ret < 0) { + pm_runtime_put_autosuspend(panel->dev); + return ret; + } + p->prepared = true; return 0; From a8d4e9553d050a629a6ab54b948c63df468be486 Mon Sep 17 00:00:00 2001 From: Zhibin Huang Date: Tue, 6 Feb 2024 15:27:09 +0000 Subject: [PATCH 06/13] misc: rk628: unify the node name of interface in dts Type: Fix Redmine ID: N/A Associated modifications: N/A Test: N/A Signed-off-by: Zhibin Huang Change-Id: I59a56b3def8f20121cb9bf53b65fc5ef3bdad6e7 --- drivers/misc/rk628/rk628.c | 30 ++++++++++++++++++++---------- drivers/misc/rk628/rk628_dsi.c | 5 ++++- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/drivers/misc/rk628/rk628.c b/drivers/misc/rk628/rk628.c index 4cbba8aa6cda..ac3387c5437c 100644 --- a/drivers/misc/rk628/rk628.c +++ b/drivers/misc/rk628/rk628.c @@ -723,40 +723,50 @@ static int rk628_display_route_info_parse(struct rk628 *rk628) int ret = 0; u32 val; - if (of_property_read_bool(rk628->dev->of_node, "rk628,hdmi-in")) { + if (of_property_read_bool(rk628->dev->of_node, "rk628-hdmi-in") || + of_property_read_bool(rk628->dev->of_node, "rk628,hdmi-in")) { rk628->input_mode = BIT(INPUT_MODE_HDMI); - } else if (of_property_read_bool(rk628->dev->of_node, "rk628,rgb-in")) { + } else if (of_property_read_bool(rk628->dev->of_node, "rk628-rgb-in") || + of_property_read_bool(rk628->dev->of_node, "rk628,rgb-in")) { rk628->input_mode = BIT(INPUT_MODE_RGB); ret = rk628_rgb_parse(rk628, NULL); - } else if (of_property_read_bool(rk628->dev->of_node, "rk628,bt1120-in")) { + } else if (of_property_read_bool(rk628->dev->of_node, "rk628-bt1120-in") || + of_property_read_bool(rk628->dev->of_node, "rk628,bt1120-in")) { rk628->input_mode = BIT(INPUT_MODE_BT1120); ret = rk628_rgb_parse(rk628, NULL); } else { rk628->input_mode = BIT(INPUT_MODE_RGB); } - if ((np = of_get_child_by_name(rk628->dev->of_node, "rk628-gvi"))) { + if ((np = of_get_child_by_name(rk628->dev->of_node, "rk628-gvi-out")) || + (np = of_get_child_by_name(rk628->dev->of_node, "rk628-gvi"))) { rk628->output_mode |= BIT(OUTPUT_MODE_GVI); ret = rk628_gvi_parse(rk628, np); - } else if ((np = of_get_child_by_name(rk628->dev->of_node, "rk628-lvds"))) { + } else if ((np = of_get_child_by_name(rk628->dev->of_node, "rk628-lvds-out")) || + (np = of_get_child_by_name(rk628->dev->of_node, "rk628-lvds"))) { rk628->output_mode |= BIT(OUTPUT_MODE_LVDS); ret = rk628_lvds_parse(rk628, np); - } else if ((np = of_get_child_by_name(rk628->dev->of_node, "rk628-dsi"))) { + } else if ((np = of_get_child_by_name(rk628->dev->of_node, "rk628-dsi-out")) || + (np = of_get_child_by_name(rk628->dev->of_node, "rk628-dsi"))) { rk628->output_mode |= BIT(OUTPUT_MODE_DSI); ret = rk628_dsi_parse(rk628, np); - } else if (of_property_read_bool(rk628->dev->of_node, "rk628,csi-out")) { + } else if (of_property_read_bool(rk628->dev->of_node, "rk628-csi-out") || + of_property_read_bool(rk628->dev->of_node, "rk628,csi-out")) { rk628->output_mode |= BIT(OUTPUT_MODE_CSI); } if (np) of_node_put(np); - if (of_property_read_bool(rk628->dev->of_node, "rk628,hdmi-out")) + if (of_property_read_bool(rk628->dev->of_node, "rk628-hdmi-out") || + of_property_read_bool(rk628->dev->of_node, "rk628,hdmi-out")) rk628->output_mode |= BIT(OUTPUT_MODE_HDMI); - if (of_property_read_bool(rk628->dev->of_node, "rk628-rgb")) { + if (of_property_read_bool(rk628->dev->of_node, "rk628-rgb-out") || + of_property_read_bool(rk628->dev->of_node, "rk628-rgb")) { rk628->output_mode |= BIT(OUTPUT_MODE_RGB); ret = rk628_rgb_parse(rk628, NULL); - } else if (of_property_read_bool(rk628->dev->of_node, "rk628-bt1120")) { + } else if (of_property_read_bool(rk628->dev->of_node, "rk628-bt1120-out") || + of_property_read_bool(rk628->dev->of_node, "rk628-bt1120")) { rk628->output_mode |= BIT(OUTPUT_MODE_BT1120); ret = rk628_rgb_parse(rk628, NULL); } diff --git a/drivers/misc/rk628/rk628_dsi.c b/drivers/misc/rk628/rk628_dsi.c index 9f93bfe35ffe..6a49ed10e783 100644 --- a/drivers/misc/rk628/rk628_dsi.c +++ b/drivers/misc/rk628/rk628_dsi.c @@ -830,7 +830,10 @@ static u32 rk628_dsi_get_lane_rate(const struct rk628_dsi *dsi) u32 max_lane_rate = 1500; u8 bpp, lanes; - dsi_np = of_find_node_by_name(dsi->rk628->dev->of_node, "rk628-dsi"); + dsi_np = of_find_node_by_name(dsi->rk628->dev->of_node, "rk628-dsi-out"); + if (!dsi_np) + dsi_np = of_find_node_by_name(dsi->rk628->dev->of_node, + "rk628-dsi"); if (dsi_np && !of_property_read_u32(dsi_np, "rockchip,lane-mbps", &value)) { lane_rate = value; } else { From 25aeddc5167cc876c5b890699d3dd24b0a09a534 Mon Sep 17 00:00:00 2001 From: Zhibin Huang Date: Tue, 6 Feb 2024 15:29:39 +0000 Subject: [PATCH 07/13] arm64: dts: rockchip: rk3568-evb-rk628: unify the node name of interface in dts Type: N/A Redmine ID: N/A Associated modifications: https://10.10.10.29/c/rk/kernel/+/210058 Test: N/A Signed-off-by: Zhibin Huang Change-Id: I6e11cb752ca57f3a34678cbf44379d3be3b47985 --- .../boot/dts/rockchip/rk3568-evb-rk628-hdmi2dsi-ddr4-v10.dts | 4 ++-- .../dts/rockchip/rk3568-evb-rk628-hdmi2dsi-dual-ddr4-v10.dts | 4 ++-- .../boot/dts/rockchip/rk3568-evb-rk628-hdmi2gvi-ddr4-v10.dts | 4 ++-- .../boot/dts/rockchip/rk3568-evb-rk628-hdmi2lvds-ddr4-v10.dts | 4 ++-- .../dts/rockchip/rk3568-evb-rk628-hdmi2lvds-dual-ddr4-v10.dts | 4 ++-- .../boot/dts/rockchip/rk3568-evb-rk628-rgb2dsi-ddr4-v10.dts | 4 ++-- .../boot/dts/rockchip/rk3568-evb-rk628-rgb2gvi-ddr4-v10.dts | 4 ++-- .../boot/dts/rockchip/rk3568-evb-rk628-rgb2hdmi-ddr4-v10.dts | 4 ++-- .../boot/dts/rockchip/rk3568-evb-rk628-rgb2lvds-ddr4-v10.dts | 4 ++-- .../dts/rockchip/rk3568-evb-rk628-rgb2lvds-dual-ddr4-v10.dts | 4 ++-- 10 files changed, 20 insertions(+), 20 deletions(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2dsi-ddr4-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2dsi-ddr4-v10.dts index 4ecd56149a24..1397d9b3522b 100644 --- a/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2dsi-ddr4-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2dsi-ddr4-v10.dts @@ -24,8 +24,8 @@ panel-unprepare-delay-ms = <10>; panel-disable-delay-ms = <60>; - rk628,hdmi-in; - rk628-dsi { + rk628-hdmi-in; + rk628-dsi-out { //rockchip,dual-channel; dsi,eotp; dsi,video-mode; diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2dsi-dual-ddr4-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2dsi-dual-ddr4-v10.dts index 0892e5e9ee47..80a73eefe453 100644 --- a/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2dsi-dual-ddr4-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2dsi-dual-ddr4-v10.dts @@ -22,8 +22,8 @@ panel-disable-delay-ms = <240>; panel-init-delay-ms = <240>; - rk628,hdmi-in; - rk628-dsi { + rk628-hdmi-in; + rk628-dsi-out { rockchip,lane-mbps = <1100>; rockchip,dual-channel; dsi,eotp; diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2gvi-ddr4-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2gvi-ddr4-v10.dts index 93631f254526..42e965bb0aa8 100644 --- a/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2gvi-ddr4-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2gvi-ddr4-v10.dts @@ -31,8 +31,8 @@ clocks = <&pmucru CLK_WIFI>; clock-names = "soc_24M"; - rk628,hdmi-in; - rk628-gvi { + rk628-hdmi-in; + rk628-gvi-out { /* "rgb666" * "rgb888" * "rgb101010" diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2lvds-ddr4-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2lvds-ddr4-v10.dts index 66f0401fb329..b26fd1b3d910 100644 --- a/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2lvds-ddr4-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2lvds-ddr4-v10.dts @@ -22,8 +22,8 @@ panel-unprepare-delay-ms = <10>; panel-disable-delay-ms = <60>; - rk628,hdmi-in; - rk628-lvds { + rk628-hdmi-in; + rk628-lvds-out { /* "jeida_18","vesa_24","vesa_18" */ bus-format = "jeida_24"; diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2lvds-dual-ddr4-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2lvds-dual-ddr4-v10.dts index b48bb44cc2bf..faaeddaf437c 100644 --- a/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2lvds-dual-ddr4-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2lvds-dual-ddr4-v10.dts @@ -25,8 +25,8 @@ panel-unprepare-delay-ms = <10>; panel-disable-delay-ms = <60>; - rk628,hdmi-in; - rk628-lvds { + rk628-hdmi-in; + rk628-lvds-out { /* "jeida_18","vesa_24","vesa_18" */ bus-format = "vesa_24"; diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2dsi-ddr4-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2dsi-ddr4-v10.dts index 804640323de1..8dd6d3e66cc8 100644 --- a/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2dsi-ddr4-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2dsi-ddr4-v10.dts @@ -55,8 +55,8 @@ panel-unprepare-delay-ms = <10>; panel-disable-delay-ms = <60>; - rk628,rgb-in; - rk628-dsi { + rk628-rgb-in; + rk628-dsi-out { //rockchip,dual-channel; dsi,eotp; dsi,video-mode; diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2gvi-ddr4-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2gvi-ddr4-v10.dts index 9b47d9eda21a..cf252d31c559 100644 --- a/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2gvi-ddr4-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2gvi-ddr4-v10.dts @@ -62,8 +62,8 @@ clocks = <&pmucru CLK_WIFI>; clock-names = "soc_24M"; - rk628,rgb-in; - rk628-gvi { + rk628-rgb-in; + rk628-gvi-out { /* "rgb666" * "rgb888" * "rgb101010" diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2hdmi-ddr4-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2hdmi-ddr4-v10.dts index 83b62f996aff..16d185cb7ad6 100644 --- a/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2hdmi-ddr4-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2hdmi-ddr4-v10.dts @@ -23,8 +23,8 @@ pinctrl-names = "default"; pinctrl-0 = <&rk628_reset &refclk_pins>; - rk628,rgb-in; - rk628,hdmi-out; + rk628-rgb-in; + rk628-hdmi-out; status = "okay"; port { diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2lvds-ddr4-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2lvds-ddr4-v10.dts index 28adb73ce751..01a62e8f8850 100644 --- a/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2lvds-ddr4-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2lvds-ddr4-v10.dts @@ -56,8 +56,8 @@ panel-unprepare-delay-ms = <10>; panel-disable-delay-ms = <60>; - rk628,rgb-in; - rk628-lvds { + rk628-rgb-in; + rk628-lvds-out { /* "jeida_18","vesa_24","vesa_18" */ bus-format = "jeida_24"; diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2lvds-dual-ddr4-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2lvds-dual-ddr4-v10.dts index 65321128ec17..82e344a37036 100644 --- a/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2lvds-dual-ddr4-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2lvds-dual-ddr4-v10.dts @@ -57,8 +57,8 @@ panel-unprepare-delay-ms = <10>; panel-disable-delay-ms = <60>; - rk628,rgb-in; - rk628-lvds { + rk628-rgb-in; + rk628-lvds-out { /* "jeida_18","vesa_24","vesa_18" */ bus-format = "vesa_24"; From 379dfa43505725a7f14b237372f42aee460c7786 Mon Sep 17 00:00:00 2001 From: Zhibin Huang Date: Tue, 6 Feb 2024 15:31:28 +0000 Subject: [PATCH 08/13] ARM: dts: rockchip: rk3036-evb1-ddr3-v10: unify the rk628 node name of interface in dts Type: Fix Redmine ID: N/A Associated modifications: https://10.10.10.29/c/rk/kernel/+/210058 Test: N/A Signed-off-by: Zhibin Huang Change-Id: Ic650b9ddda9f9202e430f7459ee86f0b73fac479 --- arch/arm/boot/dts/rk3036-evb1-ddr3-v10.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/rk3036-evb1-ddr3-v10.dts b/arch/arm/boot/dts/rk3036-evb1-ddr3-v10.dts index 85a1c67e79fc..7539bd2846b5 100644 --- a/arch/arm/boot/dts/rk3036-evb1-ddr3-v10.dts +++ b/arch/arm/boot/dts/rk3036-evb1-ddr3-v10.dts @@ -226,8 +226,8 @@ reset-gpios = <&gpio0 RK_PA3 GPIO_ACTIVE_LOW>; plugin-det-gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_LOW>; status = "okay"; - rk628,hdmi-in; - rk628-dsi { + rk628-hdmi-in; + rk628-dsi-out { //rockchip,dual-channel; dsi,eotp; dsi,video-mode; From ae97b71b7a2387d1eadd6398e63769dc1b8a4374 Mon Sep 17 00:00:00 2001 From: Zhibin Huang Date: Sun, 4 Feb 2024 07:20:21 +0000 Subject: [PATCH 09/13] misc: rk628: optimize input and output mode information 1. Fixed the issue where the log displays input and output mode information abnormally in some scenarios. 2. The input and output mode information of log and summary are obtained from the same function to facilitate later maintenance. Type: Fix Redmine ID: N/A Associated modifications: N/A Test: dmesg | grep "rk628.*input_mode.*output_mode" cat /sys/kernel/debug/rk628/2-0050/summary Signed-off-by: Zhibin Huang Change-Id: I9c4549d1673417701dc929432b96fa802632e63c --- drivers/misc/rk628/rk628.c | 137 +++++++++++++------------------------ 1 file changed, 49 insertions(+), 88 deletions(-) diff --git a/drivers/misc/rk628/rk628.c b/drivers/misc/rk628/rk628.c index ac3387c5437c..a2781653a3c7 100644 --- a/drivers/misc/rk628/rk628.c +++ b/drivers/misc/rk628/rk628.c @@ -672,49 +672,56 @@ static bool rk628_display_route_check(struct rk628 *rk628) return true; } -static void rk628_final_display_route(struct rk628 *rk628) +static void rk628_current_display_route(struct rk628 *rk628, char *input_s, + int input_s_len, char *output_s, + int output_s_len) { - char *input = NULL; - char *output = NULL; - char buf[20]; + *input_s = '\0'; + *output_s = '\0'; - if (rk628_input_is_hdmi(rk628)) - input = "hdmi"; + if (rk628_input_is_rgb(rk628)) + strlcat(input_s, "RGB", input_s_len); else if (rk628_input_is_bt1120(rk628)) - input = "bt1120"; + strlcat(input_s, "BT1120", input_s_len); + else if (rk628_input_is_hdmi(rk628)) + strlcat(input_s, "HDMI", input_s_len); else - input = "rgb"; + strlcat(input_s, "unknown", input_s_len); + + if (rk628_output_is_rgb(rk628)) + strlcat(output_s, "RGB ", output_s_len); + + if (rk628_output_is_bt1120(rk628)) + strlcat(output_s, "BT1120 ", output_s_len); if (rk628_output_is_gvi(rk628)) - output = "gvi"; - else if (rk628_output_is_lvds(rk628)) - output = "lvds"; - else if (rk628_output_is_dsi(rk628)) - output = "dsi"; - else if (rk628_output_is_csi(rk628)) - output = "csi"; + strlcat(output_s, "GVI ", output_s_len); - if (rk628_output_is_bt1120(rk628)) { - if (output) - sprintf(buf, "%s & %s", output, "bt1120"); - else - output = "bt1120"; - } else if (rk628_output_is_rgb(rk628)) { - if (output) - sprintf(buf, "%s & %s", output, "rgb"); - else - output = "rgb"; - } + if (rk628_output_is_lvds(rk628)) + strncat(output_s, "LVDS ", output_s_len); - if (rk628_output_is_hdmi(rk628)) { - if (output) - sprintf(buf, "%s & %s", output, "hdmi"); - else - output = "hdmi"; - } + if (rk628_output_is_dsi(rk628)) + strlcat(output_s, "DSI ", output_s_len); - dev_info(rk628->dev, "input_mode:%s output_mode:%s\n", input, - hweight32(rk628->output_mode) > 1 ? buf : output); + if (rk628_output_is_csi(rk628)) + strlcat(output_s, "CSI ", output_s_len); + + if (rk628_output_is_hdmi(rk628)) + strlcat(output_s, "HDMI ", output_s_len); + + if (!strlen(output_s)) + strlcat(output_s, "unknown", output_s_len); +} + +static void rk628_show_current_display_route(struct rk628 *rk628) +{ + char input_s[10], output_s[30]; + + rk628_current_display_route(rk628, input_s, sizeof(input_s), + output_s, sizeof(output_s)); + + dev_info(rk628->dev, "input_mode: %s, output_mode: %s\n", input_s, + output_s); } static int rk628_display_route_info_parse(struct rk628 *rk628) @@ -889,25 +896,6 @@ static int rk628_display_timings_get(struct rk628 *rk628) pr_info(args); \ } while (0) -static void rk628_show_input_mode(struct seq_file *s) -{ - struct rk628 *rk628 = s->private; - char input_s[10] = {0}; - - /* show input mode */ - if (rk628_input_is_hdmi(rk628)) - strcpy(input_s, "HDMI"); - else if (rk628_input_is_bt1120(rk628)) - strcpy(input_s, "BT1120"); - else if (rk628_input_is_rgb(rk628)) - strcpy(input_s, "RGB"); - - if (!strlen(input_s)) - strcpy(input_s, "unknown "); - - DEBUG_PRINT("input: %s\n", input_s); -} - static void rk628_show_resolution(struct seq_file *s) { struct rk628 *rk628 = s->private; @@ -1005,38 +993,6 @@ static void rk628_show_input_resolution(struct seq_file *s) rk628_show_resolution(s); } -static void rk628_show_output_mode(struct seq_file *s) -{ - struct rk628 *rk628 = s->private; - char output_s[30] = {0}; - char *p = output_s; - - if (rk628_output_is_gvi(rk628)) - strcpy(p, "GVI "); - else if (rk628_output_is_lvds(rk628)) - strcpy(p, "LVDS "); - else if (rk628_output_is_dsi(rk628)) - strcpy(p, "DSI "); - else if (rk628_output_is_csi(rk628)) - strcpy(p, "CSI "); - p += strlen(p); - - if (rk628_output_is_hdmi(rk628)) { - strcpy(p, "HDMI "); - p += strlen(p); - } - - if (rk628_output_is_rgb(rk628)) - strcpy(p, "RGB "); - else if (rk628_output_is_bt1120(rk628)) - strcpy(p, "BT1120 "); - - if (!strlen(output_s)) - strcpy(p, "unknown "); - - DEBUG_PRINT("output: %s\n", output_s); -} - static void rk628_show_output_resolution(struct seq_file *s) { struct rk628 *rk628 = s->private; @@ -1147,16 +1103,20 @@ static void rk628_show_csc_info(struct seq_file *s) static int rk628_debugfs_dump(struct seq_file *s, void *data) { struct rk628 *rk628 = s->private; + char input_s[10], output_s[30]; u32 val; int sw_hsync_pol, sw_vsync_pol; u32 dsp_frame_v_start, dsp_frame_h_start; + rk628_current_display_route(rk628, input_s, sizeof(input_s), + output_s, sizeof(output_s)); + /* show input info */ - rk628_show_input_mode(s); + DEBUG_PRINT("input: %s\n", input_s); rk628_show_input_resolution(s); /* show output info */ - rk628_show_output_mode(s); + DEBUG_PRINT("output: %s\n", output_s); rk628_show_output_resolution(s); /* show csc info */ @@ -1453,13 +1413,14 @@ rk628_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) if (ret) goto err_clk; + rk628_show_current_display_route(rk628); + if (!rk628_display_route_check(rk628)) { dev_err(dev, "display route check err\n"); ret = -EINVAL; goto err_clk; } - rk628_final_display_route(rk628); rk628_pwr_consumption_init(rk628); #ifdef CONFIG_FB From 5fe35955d774cc30268c13ee4d8b7a5709505269 Mon Sep 17 00:00:00 2001 From: Huang zhibao Date: Mon, 13 Nov 2023 10:56:37 +0800 Subject: [PATCH 10/13] input: rockchip_pwm_remotectl: add pwm v4 support Change-Id: I40d1571c3285165683845df8c48fe45d7fcac01d Signed-off-by: Huang zhibao --- .../input/remotectl/rockchip_pwm_remotectl.c | 443 ++++++++++++++---- .../input/remotectl/rockchip_pwm_remotectl.h | 130 +++-- 2 files changed, 443 insertions(+), 130 deletions(-) diff --git a/drivers/input/remotectl/rockchip_pwm_remotectl.c b/drivers/input/remotectl/rockchip_pwm_remotectl.c index fa3d7650d8ff..606c0857831a 100644 --- a/drivers/input/remotectl/rockchip_pwm_remotectl.c +++ b/drivers/input/remotectl/rockchip_pwm_remotectl.c @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +// SPDX-License-Identifier: GPL-2.0 #include #include @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -19,8 +20,6 @@ #include #include "rockchip_pwm_remotectl.h" - - /* * sys/module/rk_pwm_remotectl/parameters, * modify code_print to change the value @@ -56,8 +55,46 @@ struct rkxx_remotectl_button { struct rkxx_remote_key_table key_table[MAX_NUM_KEYS]; }; +struct rk_remote_pwm_regs { + unsigned long ctrl; + unsigned long version; + unsigned long enable; + unsigned long clk_ctrl; + unsigned long offset; + unsigned long rpt; + unsigned long hpr; + unsigned long lpr; + unsigned long intsts; + unsigned long int_en; + unsigned long pwrmatch_arbiter; + unsigned long pwrmatch_ctrl; + unsigned long pwrmatch_lpre; + unsigned long pwrmatch_hpre; + unsigned long pwrmatch_ld; + unsigned long pwrmatch_hd_zero; + unsigned long pwrmatch_hd_one; + unsigned long pwrmatch_value0; + unsigned long pwrcapture_value; +}; + +struct rk_remote_pwm_funcs { + irqreturn_t (*irq_handler)(int irq, void *data); + void (*int_ctrl)(struct platform_device *pdev, int work_mode); + int (*init_hw)(struct platform_device *pdev); +}; + +struct rk_remote_pwm_data { + struct rk_remote_pwm_regs regs; + struct rk_remote_pwm_funcs funcs; + unsigned int prescaler; + u32 enable_conf; + int pwm_version; + int pwrmactch_key_max; +}; + struct rkxx_remotectl_drvdata { void __iomem *base; + int pwm_version; int state; int nbuttons; int scandata; @@ -81,10 +118,60 @@ struct rkxx_remotectl_drvdata { struct timer_list timer; struct tasklet_struct remote_tasklet; struct wake_lock remotectl_wake_lock; + const struct rk_remote_pwm_data *pwm_data; }; +static irqreturn_t rockchip_pwm_irq(int irq, void *dev_id); +static irqreturn_t rockchip_pwm_irq_v4(int irq, void *dev_id); +static int rk_pwm_remotectl_hw_init(struct platform_device *pdev); +static int rk_pwm_remotectl_hw_init_v4(struct platform_device *pdev); +static void rk_pwm_int_ctrl(struct platform_device *pdev, int work_mode); +static void rk_pwm_int_ctrl_v4(struct platform_device *pdev, int work_mode); + static struct rkxx_remotectl_button *remotectl_button; +struct rk_remote_pwm_data pwm_data_v1 = { + .regs = { + .version = 0x5c, + .ctrl = 0x0c, + }, + .prescaler = 1, + .pwm_version = 1, + .funcs = { + .irq_handler = rockchip_pwm_irq, + .int_ctrl = rk_pwm_int_ctrl, + .init_hw = rk_pwm_remotectl_hw_init, + }, +}; + +struct rk_remote_pwm_data pwm_data_v4 = { + .regs = { + .version = 0x0, + .enable = 0x4, + .clk_ctrl = 0x8, + .ctrl = 0xc, + .hpr = 0x2c, + .lpr = 0x30, + .intsts = 0x70, + .int_en = 0x74, + .pwrmatch_arbiter = 0x100, + .pwrmatch_ctrl = 0x104, + .pwrmatch_lpre = 0x108, + .pwrmatch_hpre = 0x10c, + .pwrmatch_ld = 0x110, + .pwrmatch_hd_zero = 0x114, + .pwrmatch_hd_one = 0x118, + .pwrmatch_value0 = 0x11c, + .pwrcapture_value = 0x15c, + }, + .pwm_version = 4, + .funcs = { + .irq_handler = rockchip_pwm_irq_v4, + .int_ctrl = rk_pwm_int_ctrl_v4, + .init_hw = rk_pwm_remotectl_hw_init_v4, + }, +}; + static int remotectl_keybd_num_lookup(struct rkxx_remotectl_drvdata *ddata) { int i; @@ -100,7 +187,6 @@ static int remotectl_keybd_num_lookup(struct rkxx_remotectl_drvdata *ddata) return 0; } - static int remotectl_keycode_lookup(struct rkxx_remotectl_drvdata *ddata) { int i; @@ -137,7 +223,6 @@ static int rk_remotectl_get_irkeybd_count(struct platform_device *pdev) return boardnum; } - static int rk_remotectl_parse_ir_keys(struct platform_device *pdev) { struct rkxx_remotectl_drvdata *ddata = platform_get_drvdata(pdev); @@ -182,8 +267,6 @@ static int rk_remotectl_parse_ir_keys(struct platform_device *pdev) return 0; } - - static void rk_pwm_remotectl_do_something(unsigned long data) { struct rkxx_remotectl_drvdata *ddata; @@ -359,70 +442,184 @@ static irqreturn_t rockchip_pwm_irq(int irq, void *dev_id) return IRQ_HANDLED; } -static int rk_pwm_pwrkey_wakeup_init(struct platform_device *pdev) +static irqreturn_t rockchip_pwm_irq_v4(int irq, void *dev_id) +{ + struct rkxx_remotectl_drvdata *ddata = dev_id; + int tmp; + int val; + irqreturn_t ret = IRQ_NONE; + + val = readl_relaxed(ddata->base + PWM_REG_INTSTS_V4); + + if (val & CAP_LPR_INT) { + writel_relaxed(CAP_LPR_INT, ddata->base + PWM_REG_INTSTS_V4); + tmp = readl_relaxed(ddata->base + PWM_REG_HPR_V4); + ddata->period = ddata->pwm_freq_nstime * tmp / 1000; + DBG("period = %ld\n", ddata->period); + tasklet_hi_schedule(&ddata->remote_tasklet); + ret = IRQ_HANDLED; + } else if (val & CAP_HPR_INT) { + writel_relaxed(CAP_HPR_INT, ddata->base + PWM_REG_INTSTS_V4); + tmp = readl_relaxed(ddata->base + PWM_REG_LPR_V4); + DBG("lpr = %d\n", tmp); + ret = IRQ_HANDLED; + } + + if (val & PWR_INT) { + writel_relaxed(PWR_INT, ddata->base + PWM_REG_INTSTS_V4); + tmp = readl_relaxed(ddata->base + PWM_REG_CAPTURE_VALUE_V4); + DBG("##### cap_val = 0x%0x\n", tmp); + ddata->pwrkey_wakeup = 1; + ret = IRQ_HANDLED; + } + + if (ddata->state == RMC_PRELOAD) + wake_lock_timeout(&ddata->remotectl_wake_lock, HZ); + + return ret; +} + +static int rk_pwmkey_convert_val(int min, int max, int freq_nstime) +{ + int val, min_temp, max_temp; + + min_temp = min * 1000 / freq_nstime; + max_temp = max * 1000 / freq_nstime; + val = (max_temp & 0xffff) << 16 | (min_temp & 0xffff); + + return val; +} + +static int rockchip_pwm_set_pwrmatch(struct platform_device *pdev) { struct rkxx_remotectl_drvdata *ddata = platform_get_drvdata(pdev); - int val, min_temp, max_temp; unsigned int pwm_id = ddata->remote_pwm_id; int version; - int i, j; - int num = 0; - int ret = -1; int pwr_irq; + int val; + int ret; - ddata->pwm_pwrkey_capture = 0; version = readl_relaxed(ddata->base + RK_PWM_VERSION_ID(pwm_id)); - dev_info(&pdev->dev, "pwm version is 0x%x\n", version & 0xffff0000); + DBG("remote pwm version is 0x%x\n", version); if (((version >> 24) & 0xFF) < 2) { dev_info(&pdev->dev, "pwm version is less v2.0\n"); + ret = -EINVAL; goto end; } pwr_irq = platform_get_irq(pdev, 1); if (pwr_irq < 0) { dev_err(&pdev->dev, "cannot find PWR IRQ\n"); + ret = pwr_irq; goto end; } ret = devm_request_irq(&pdev->dev, pwr_irq, rockchip_pwm_pwrirq, - IRQF_NO_SUSPEND, "rk_pwm_pwr_irq", ddata); + IRQF_NO_SUSPEND, "rk_pwm_pwr_irq", ddata); if (ret) { dev_err(&pdev->dev, "cannot claim PWR_IRQ!!!\n"); goto end; } - val = readl_relaxed(ddata->base + PWM_REG_CTRL); - val = (val & 0xFFFFFFFE) | PWM_DISABLE; - writel_relaxed(val, ddata->base + PWM_REG_CTRL); + val = readl_relaxed(ddata->base + PWM_REG_INT_EN(pwm_id)); + val = (val & 0xFFFFFF7F) | PWM_PWR_INT_ENABLE; + writel_relaxed(val, ddata->base + PWM_REG_INT_EN(pwm_id)); + val = CH3_PWRKEY_ENABLE; + writel_relaxed(val, ddata->base + PWM_REG_PWRMATCH_CTRL(pwm_id)); + + val = readl_relaxed(ddata->base + PWM_REG_CTRL); + val = (val & 0xFFFFFFFE) | PWM_ENABLE; + writel_relaxed(val, ddata->base + PWM_REG_CTRL); + return 0; +end: + return ret; +} + +static int rockchip_pwm_set_pwrmatch_v4(struct rkxx_remotectl_drvdata *pd) +{ + int version; + int channel_id; + int val; + + version = readl_relaxed(pd->base + PWM_REG_VERSION_V4); + DBG("remote pwm version is 0x%x\n", version); + channel_id = (version & CHANNLE_INDEX_MASK) >> CHANNLE_INDEX_SHIFT; + val = BIT(channel_id) << PWRMATCH_READ_LOCK_SHIFT | + BIT(channel_id) << PWRMATCH_GRANT_SHIFT; + writel_relaxed(val, pd->base + PWM_REG_MATCH_ARBITER_V4); + writel_relaxed(PWRKEY_EN(true), + pd->base + PWM_REG_MATCH_CTRL_V4); + + return 0; +} + +static void rockchip_pwrmatch_set_nec_param(struct rkxx_remotectl_drvdata *pd) +{ + unsigned int pwm_id = pd->remote_pwm_id; + void __iomem *reg; + int freq_nstime; + int val; + + freq_nstime = pd->pwm_freq_nstime; //preloader low min:8000us, max:10000us - min_temp = RK_PWM_TIME_PRE_MIN_LOW * 1000 / ddata->pwm_freq_nstime; - max_temp = RK_PWM_TIME_PRE_MAX_LOW * 1000 / ddata->pwm_freq_nstime; - val = (max_temp & 0xffff) << 16 | (min_temp & 0xffff); - writel_relaxed(val, ddata->base + PWM_REG_PWRMATCH_LPRE(pwm_id)); + val = rk_pwmkey_convert_val(RK_PWM_TIME_PRE_MIN_LOW, + RK_PWM_TIME_PRE_MAX_LOW, freq_nstime); + if (pd->pwm_data->pwm_version < 4) + reg = pd->base + PWM_REG_PWRMATCH_LPRE(pwm_id); + else + reg = pd->base + PWM_REG_MATCH_LPRE_V4; + writel_relaxed(val, reg); //preloader higt min:4000us, max:5000us - min_temp = RK_PWM_TIME_PRE_MIN * 1000 / ddata->pwm_freq_nstime; - max_temp = RK_PWM_TIME_PRE_MAX * 1000 / ddata->pwm_freq_nstime; - val = (max_temp & 0xffff) << 16 | (min_temp & 0xffff); - writel_relaxed(val, ddata->base + PWM_REG_PWRMATCH_HPRE(pwm_id)); + val = rk_pwmkey_convert_val(RK_PWM_TIME_PRE_MIN, + RK_PWM_TIME_PRE_MAX, freq_nstime); + if (pd->pwm_data->pwm_version < 4) + reg = pd->base + PWM_REG_PWRMATCH_HPRE(pwm_id); + else + reg = pd->base + PWM_REG_MATCH_HPRE_V4; + writel_relaxed(val, reg); //logic 0/1 low min:480us, max 700us - min_temp = RK_PWM_TIME_BIT_MIN_LOW * 1000 / ddata->pwm_freq_nstime; - max_temp = RK_PWM_TIME_BIT_MAX_LOW * 1000 / ddata->pwm_freq_nstime; - val = (max_temp & 0xffff) << 16 | (min_temp & 0xffff); - writel_relaxed(val, ddata->base + PWM_REG_PWRMATCH_LD(pwm_id)); + val = rk_pwmkey_convert_val(RK_PWM_TIME_BIT_MIN_LOW, + RK_PWM_TIME_BIT_MAX_LOW, freq_nstime); + if (pd->pwm_data->pwm_version < 4) + reg = pd->base + PWM_REG_PWRMATCH_LD(pwm_id); + else + reg = pd->base + PWM_REG_MATCH_LD_V4; + writel_relaxed(val, reg); //logic 0 higt min:480us, max 700us - min_temp = RK_PWM_TIME_BIT0_MIN * 1000 / ddata->pwm_freq_nstime; - max_temp = RK_PWM_TIME_BIT0_MAX * 1000 / ddata->pwm_freq_nstime; - val = (max_temp & 0xffff) << 16 | (min_temp & 0xffff); - writel_relaxed(val, ddata->base + PWM_REG_PWRMATCH_HD_ZERO(pwm_id)); + val = rk_pwmkey_convert_val(RK_PWM_TIME_BIT0_MIN, + RK_PWM_TIME_BIT0_MAX, freq_nstime); + if (pd->pwm_data->pwm_version < 4) + reg = pd->base + PWM_REG_PWRMATCH_HD_ZERO(pwm_id); + else + reg = pd->base + PWM_REG_MATCH_HD_ZERO_V4; + writel_relaxed(val, reg); //logic 1 higt min:1300us, max 2000us - min_temp = RK_PWM_TIME_BIT1_MIN * 1000 / ddata->pwm_freq_nstime; - max_temp = RK_PWM_TIME_BIT1_MAX * 1000 / ddata->pwm_freq_nstime; - val = (max_temp & 0xffff) << 16 | (min_temp & 0xffff); - writel_relaxed(val, ddata->base + PWM_REG_PWRMATCH_HD_ONE(pwm_id)); + val = rk_pwmkey_convert_val(RK_PWM_TIME_BIT1_MIN, + RK_PWM_TIME_BIT1_MAX, freq_nstime); + if (pd->pwm_data->pwm_version < 4) + reg = pd->base + PWM_REG_PWRMATCH_HD_ONE(pwm_id); + else + reg = pd->base + PWM_REG_MATCH_HD_ONE_V4; + writel_relaxed(val, reg); +} - for (j = 0; j < ddata->maxkeybdnum; j++) { +static void rockchip_pwrmatch_set_pwrkey(struct rkxx_remotectl_drvdata *pd) +{ + unsigned int pwm_id = pd->remote_pwm_id; + void __iomem *reg; + int i, j; + int num = 0, num_max; + + if (pd->pwm_data->pwm_version < 4) { + reg = pd->base + PWM_PWRMATCH_VALUE(pwm_id); + num_max = PWM_PWR_KEY_CAPURURE_MAX; + } else { + reg = pd->base + PWM_REG_CAPTURE_VALUE0_V4; + num_max = PWM_PWR_KEY_CAPURURE_MAX_V4; + } + for (j = 0; j < pd->maxkeybdnum; j++) { for (i = 0; i < remotectl_button[j].nbuttons; i++) { int scancode, usercode, pwrkey; @@ -434,71 +631,122 @@ static int rk_pwm_pwrkey_wakeup_init(struct platform_device *pdev) pwrkey = usercode; pwrkey |= (scancode << 24) | ((~scancode & 0xff) << 16); DBG("pwrkey = %x\n", pwrkey); - writel_relaxed(pwrkey, ddata->base - + PWM_PWRMATCH_VALUE(pwm_id) + num * 4); + writel_relaxed(pwrkey, reg + num * 4); num++; - if (num >= PWM_PWR_KEY_CAPURURE_MAX) + if (num >= num_max) break; } } +} - val = readl_relaxed(ddata->base + PWM_REG_INT_EN(pwm_id)); - val = (val & 0xFFFFFF7F) | PWM_PWR_INT_ENABLE; - writel_relaxed(val, ddata->base + PWM_REG_INT_EN(pwm_id)); +static int rk_pwm_pwrkey_wakeup_init(struct platform_device *pdev) +{ + struct rkxx_remotectl_drvdata *ddata = platform_get_drvdata(pdev); + int ret = -1; - val = CH3_PWRKEY_ENABLE; - writel_relaxed(val, ddata->base + PWM_REG_PWRMATCH_CTRL(pwm_id)); - - val = readl_relaxed(ddata->base + PWM_REG_CTRL); - val = (val & 0xFFFFFFFE) | PWM_ENABLE; - writel_relaxed(val, ddata->base + PWM_REG_CTRL); + ddata->pwm_pwrkey_capture = 0; + if (ddata->pwm_data->pwm_version < 4) { + ret = rockchip_pwm_set_pwrmatch(pdev); + if (ret < 0) + goto end; + } else { + rockchip_pwm_set_pwrmatch_v4(ddata); + } + rockchip_pwrmatch_set_nec_param(ddata); + rockchip_pwrmatch_set_pwrkey(ddata); ddata->pwm_pwrkey_capture = 1; end: return ret; } -static void rk_pwm_int_ctrl(void __iomem *pwm_base, uint pwm_id, int ctrl) +static void rk_pwm_int_ctrl(struct platform_device *pdev, int work_mode) { + struct rkxx_remotectl_drvdata *ddata = platform_get_drvdata(pdev); int val; + int pwm_id = ddata->remote_pwm_id; if (pwm_id > 3) return; - val = readl_relaxed(pwm_base + PWM_REG_INT_EN(pwm_id)); - if (ctrl) { + val = readl_relaxed(ddata->base + PWM_REG_INT_EN(pwm_id)); + if (work_mode) { val |= PWM_CH_INT_ENABLE(pwm_id); DBG("pwm int enabled, value is 0x%x\n", val); - writel_relaxed(val, pwm_base + PWM_REG_INT_EN(pwm_id)); + writel_relaxed(val, ddata->base + PWM_REG_INT_EN(pwm_id)); } else { val &= ~PWM_CH_INT_ENABLE(pwm_id); DBG("pwm int disabled, value is 0x%x\n", val); } - writel_relaxed(val, pwm_base + PWM_REG_INT_EN(pwm_id)); + writel_relaxed(val, ddata->base + PWM_REG_INT_EN(pwm_id)); } -static int rk_pwm_remotectl_hw_init(void __iomem *pwm_base, uint pwm_id) +static void rk_pwm_int_ctrl_v4(struct platform_device *pdev, int work_mode) { + struct rkxx_remotectl_drvdata *ddata = platform_get_drvdata(pdev); int val; - if (pwm_id > 3) - return -1; + if (work_mode) { + val = CAP_LPR_INT_EN(true) | CAP_HPR_INT_EN(true) | PWR_INT_EN(false); + writel_relaxed(val, ddata->base + PWM_REG_INT_EN_V4); + } else { + val = CAP_LPR_INT_EN(false) | CAP_HPR_INT_EN(false) | PWR_INT_EN(true); + writel_relaxed(val, ddata->base + PWM_REG_INT_EN_V4); + } +} + +static int rk_pwm_remotectl_hw_init(struct platform_device *pdev) +{ + int val; + struct rkxx_remotectl_drvdata *ddata = platform_get_drvdata(pdev); + //1. disabled pwm - val = readl_relaxed(pwm_base + PWM_REG_CTRL); + val = readl_relaxed(ddata->base + PWM_REG_CTRL); val = (val & 0xFFFFFFFE) | PWM_DISABLE; - writel_relaxed(val, pwm_base + PWM_REG_CTRL); + writel_relaxed(val, ddata->base + PWM_REG_CTRL); + //2. capture mode - val = readl_relaxed(pwm_base + PWM_REG_CTRL); + val = readl_relaxed(ddata->base + PWM_REG_CTRL); val = (val & 0xFFFFFFF9) | PWM_MODE_CAPTURE; - writel_relaxed(val, pwm_base + PWM_REG_CTRL); + writel_relaxed(val, ddata->base + PWM_REG_CTRL); + //set clk div, clk div to 64 - val = readl_relaxed(pwm_base + PWM_REG_CTRL); + val = readl_relaxed(ddata->base + PWM_REG_CTRL); val = (val & 0xFF0001FF) | PWM_DIV64; - writel_relaxed(val, pwm_base + PWM_REG_CTRL); + writel_relaxed(val, ddata->base + PWM_REG_CTRL); + //4. enabled pwm int - rk_pwm_int_ctrl(pwm_base, pwm_id, PWM_INT_ENABLE); + ddata->pwm_data->funcs.int_ctrl(pdev, IR_WORK_MODE); + //5. enabled pwm - val = readl_relaxed(pwm_base + PWM_REG_CTRL); + val = readl_relaxed(ddata->base + PWM_REG_CTRL); val = (val & 0xFFFFFFFE) | PWM_ENABLE; - writel_relaxed(val, pwm_base + PWM_REG_CTRL); + writel_relaxed(val, ddata->base + PWM_REG_CTRL); + + return 0; +} + +static int rk_pwm_remotectl_hw_init_v4(struct platform_device *pdev) +{ + int val; + struct rkxx_remotectl_drvdata *ddata = platform_get_drvdata(pdev); + + //1. disabled pwm + val = PWM_EN(false) | PWM_CLK_EN(false); + writel_relaxed(val, ddata->base + PWM_REG_ENABLE_V4); + + //2. capture mode + val = PWM_MODE(CAPTURE_MODE); + writel_relaxed(val, ddata->base + PWM_REG_CTRL_V4); + + //3. set clk div, clk div to 64 + val = CLK_SCALE(32); + writel_relaxed(val, ddata->base + PWM_REG_CLK_CTRL_V4); + + //4. enabled pwm int + ddata->pwm_data->funcs.int_ctrl(pdev, IR_WORK_MODE); + + //5. enabled pwm + val = PWM_EN(true) | PWM_CLK_EN(true); + writel_relaxed(val, ddata->base + PWM_REG_ENABLE_V4); return 0; } @@ -573,9 +821,18 @@ static inline void rk_pwm_wakeup(struct input_dev *input) input_sync(input); } +static const struct of_device_id rk_pwm_of_match[] = { + { .compatible = "rockchip,remotectl-pwm", .data = &pwm_data_v1}, + { .compatible = "rockchip,remotectl-pwm-v4", .data = &pwm_data_v4}, + { } +}; + +MODULE_DEVICE_TABLE(of, rk_pwm_of_match); + static int rk_pwm_probe(struct platform_device *pdev) { struct rkxx_remotectl_drvdata *ddata; + const struct of_device_id *id; struct device_node *np = pdev->dev.of_node; struct resource *r; struct input_dev *input; @@ -592,20 +849,27 @@ static int rk_pwm_probe(struct platform_device *pdev) int count; pr_err(".. rk pwm remotectl v2.0 init\n"); + id = of_match_device(rk_pwm_of_match, &pdev->dev); + if (!id) + return -EINVAL; + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!r) { dev_err(&pdev->dev, "no memory resources defined\n"); return -ENODEV; } + ddata = devm_kzalloc(&pdev->dev, sizeof(struct rkxx_remotectl_drvdata), GFP_KERNEL); if (!ddata) { - dev_err(&pdev->dev, "failed to allocate memory\n"); return -ENOMEM; } + + ddata->pwm_data = id->data; ddata->state = RMC_PRELOAD; ddata->temp_period = 0; ddata->base = devm_ioremap_resource(&pdev->dev, r); + if (IS_ERR(ddata->base)) return PTR_ERR(ddata->base); count = of_property_count_strings(np, "clock-names"); @@ -675,14 +939,17 @@ static int rk_pwm_probe(struct platform_device *pdev) } ddata->irq = irq; ddata->wakeup = 1; - of_property_read_u32(np, "remote_pwm_id", &pwm_id); - pwm_id %= 4; - ddata->remote_pwm_id = pwm_id; - if (pwm_id > 3) { - dev_err(&pdev->dev, "pwm id error\n"); - goto error_pclk; + + if (ddata->pwm_data->pwm_version < 4) { + of_property_read_u32(np, "remote_pwm_id", &pwm_id); + pwm_id %= 4; + ddata->remote_pwm_id = pwm_id; + if (pwm_id > 3) { + dev_err(&pdev->dev, "pwm id error\n"); + goto error_pclk; + } + DBG("remotectl: remote pwm id=0x%x\n", pwm_id); } - DBG("remotectl: remote pwm id=0x%x\n", pwm_id); of_property_read_u32(np, "handle_cpu_id", &cpu_id); ddata->handle_cpu_id = cpu_id; DBG("remotectl: handle cpu id=0x%x\n", cpu_id); @@ -710,29 +977,25 @@ static int rk_pwm_probe(struct platform_device *pdev) cpumask_clear(&cpumask); cpumask_set_cpu(cpu_id, &cpumask); irq_set_affinity_hint(irq, &cpumask); - ret = devm_request_irq(&pdev->dev, irq, rockchip_pwm_irq, + ret = devm_request_irq(&pdev->dev, irq, ddata->pwm_data->funcs.irq_handler, IRQF_NO_SUSPEND, "rk_pwm_irq", ddata); if (ret) { dev_err(&pdev->dev, "cannot claim IRQ %d\n", irq); goto error_irq; } - pwm_freq = clk_get_rate(clk) / 64; ddata->pwm_freq_nstime = 1000000000 / pwm_freq; - rk_pwm_remotectl_hw_init(ddata->base, pwm_id); - + ddata->pwm_data->funcs.init_hw(pdev); ret = rk_pwm_pwrkey_wakeup_init(pdev); if (!ret) { dev_info(&pdev->dev, "Controller support pwrkey capture\n"); goto end; } - ret = rk_pwm_sip_wakeup_init(pdev); if (ret) dev_info(&pdev->dev, "Donot support ATF Wakeup\n"); else dev_info(&pdev->dev, "Support ATF Wakeup\n"); - DBG("rk pwm remotectl init end!\n"); end: return 0; @@ -754,15 +1017,13 @@ static int rk_pwm_remove(struct platform_device *pdev) static int remotectl_suspend(struct device *dev) { int cpu = 0; - int pwm_id; struct cpumask cpumask; struct platform_device *pdev = to_platform_device(dev); struct rkxx_remotectl_drvdata *ddata = platform_get_drvdata(pdev); if (ddata->pwm_pwrkey_capture) { - pwm_id = ddata->remote_pwm_id; ddata->pwrkey_wakeup = 0; - rk_pwm_int_ctrl(ddata->base, pwm_id, PWM_INT_DISABLE); + ddata->pwm_data->funcs.int_ctrl(pdev, IR_SUSPEND_MODE); } cpumask_clear(&cpumask); cpumask_set_cpu(cpu, &cpumask); @@ -770,11 +1031,9 @@ static int remotectl_suspend(struct device *dev) return 0; } - static int remotectl_resume(struct device *dev) { struct cpumask cpumask; - int pwm_id; struct platform_device *pdev = to_platform_device(dev); struct rkxx_remotectl_drvdata *ddata = platform_get_drvdata(pdev); int state; @@ -791,8 +1050,7 @@ static int remotectl_resume(struct device *dev) if (state == REMOTECTL_PWRKEY_WAKEUP) rk_pwm_wakeup(ddata->input); } else if (ddata->pwm_pwrkey_capture) { - pwm_id = ddata->remote_pwm_id; - rk_pwm_int_ctrl(ddata->base, pwm_id, PWM_INT_ENABLE); + ddata->pwm_data->funcs.int_ctrl(pdev, IR_WORK_MODE); if (ddata->pwrkey_wakeup == 0) return 0; ddata->pwrkey_wakeup = 0; @@ -808,13 +1066,6 @@ static const struct dev_pm_ops remotectl_pm_ops = { }; #endif -static const struct of_device_id rk_pwm_of_match[] = { - { .compatible = "rockchip,remotectl-pwm"}, - { } -}; - -MODULE_DEVICE_TABLE(of, rk_pwm_of_match); - static struct platform_driver rk_pwm_driver = { .driver = { .name = "remotectl-pwm", diff --git a/drivers/input/remotectl/rockchip_pwm_remotectl.h b/drivers/input/remotectl/rockchip_pwm_remotectl.h index 5126a3edb5d5..1232e799efb5 100644 --- a/drivers/input/remotectl/rockchip_pwm_remotectl.h +++ b/drivers/input/remotectl/rockchip_pwm_remotectl.h @@ -6,6 +6,7 @@ #define MAX_NUM_KEYS 60 #define PWM_PWR_KEY_CAPURURE_MAX 10 +#define PWM_PWR_KEY_CAPURURE_MAX_V4 16 /* PWM0 registers */ #define PWM_REG_CNTR 0x00 /* Counter Register */ @@ -93,52 +94,109 @@ enum pwm_div { PWM_DIV128 = (0x7 << 12), }; +/* + * regs for pwm v4 + */ +#define PWM_REG_VERSION_V4 0x0 +#define PWM_REG_ENABLE_V4 0x4 +#define PWM_REG_CLK_CTRL_V4 0x8 +#define PWM_REG_CTRL_V4 0xC +#define PWM_REG_HPR_V4 0x2C +#define PWM_REG_LPR_V4 0x30 +#define PWM_REG_INTSTS_V4 0x70 +#define PWM_REG_INT_EN_V4 0x74 +#define PWM_REG_MATCH_ARBITER_V4 0x100 +#define PWM_REG_MATCH_CTRL_V4 0x104 +#define PWM_REG_MATCH_LPRE_V4 0x108 +#define PWM_REG_MATCH_HPRE_V4 0x10C +#define PWM_REG_MATCH_LD_V4 0x110 +#define PWM_REG_MATCH_HD_ZERO_V4 0x114 +#define PWM_REG_MATCH_HD_ONE_V4 0x118 +#define PWM_REG_CAPTURE_VALUE0_V4 0x11C +#define PWM_REG_CAPTURE_VALUE_V4 0x15C + + +#define HIWORD_UPDATE(v, l, h) (((v) << (l)) | (GENMASK(h, l) << 16)) + +/* VERSION_ID */ +#define CHANNLE_INDEX_SHIFT 4 +#define CHANNLE_INDEX_MASK (0xf << CHANNLE_INDEX_SHIFT) + +/* PWM_CTRL */ +#define PWM_MODE(v) HIWORD_UPDATE(v, 0, 1) +#define CAPTURE_MODE 2 +#define CLK_SCALE(v) HIWORD_UPDATE(v, 4, 12) + +/* INTSTS */ +#define CAP_LPR_INTSTS_SHIFT 0 +#define CAP_HPR_INTSTS_SHIFT 1 +#define PWR_INTSTS_SHIFT 5 +#define CAP_LPR_INT BIT(CAP_LPR_INTSTS_SHIFT) +#define CAP_HPR_INT BIT(CAP_HPR_INTSTS_SHIFT) +#define PWR_INT BIT(PWR_INTSTS_SHIFT) + +/* INT_EN */ +#define CAP_LPR_INT_EN(v) HIWORD_UPDATE(v, 0, 0) +#define CAP_HPR_INT_EN(v) HIWORD_UPDATE(v, 1, 1) +#define PWR_INT_EN(v) HIWORD_UPDATE(v, 5, 5) + +/* INT_MASK */ +#define CAP_LPR_INT_MASK(v) HIWORD_UPDATE(v, 0, 0) +#define CAP_HPR_INT_MASK(v) HIWORD_UPDATE(v, 1, 1) +#define PWR_INT_MASK(v) HIWORD_UPDATE(v, 5, 5) + +/* PWRMATCH_ARBITER */ +#define PWRMATCH_GRANT_SHIFT 0 +#define PWRMATCH_READ_LOCK_SHIFT 16 +#define PWRKEY_EN(v) HIWORD_UPDATE(v, 0, 0) +#define PWM_CLK_EN(v) HIWORD_UPDATE(v, 0, 0) +#define PWM_EN(v) HIWORD_UPDATE(v, 1, 1) + + /* NEC Protocol */ -#define RK_PWM_TIME_PRE_MIN 4000 -#define RK_PWM_TIME_PRE_MAX 5000 +#define RK_PWM_TIME_PRE_MIN 4000 +#define RK_PWM_TIME_PRE_MAX 5000 -#define RK_PWM_TIME_PRE_MIN_LOW 8000 -#define RK_PWM_TIME_PRE_MAX_LOW 10000 +#define RK_PWM_TIME_PRE_MIN_LOW 8000 +#define RK_PWM_TIME_PRE_MAX_LOW 10000 -#define RK_PWM_TIME_BIT0_MIN 390 -#define RK_PWM_TIME_BIT0_MAX 730 +#define RK_PWM_TIME_BIT0_MIN 390 +#define RK_PWM_TIME_BIT0_MAX 730 -#define RK_PWM_TIME_BIT1_MIN 1300 -#define RK_PWM_TIME_BIT1_MAX 2000 +#define RK_PWM_TIME_BIT1_MIN 1300 +#define RK_PWM_TIME_BIT1_MAX 2000 -#define RK_PWM_TIME_BIT_MIN_LOW 390 -#define RK_PWM_TIME_BIT_MAX_LOW 730 +#define RK_PWM_TIME_BIT_MIN_LOW 390 +#define RK_PWM_TIME_BIT_MAX_LOW 730 -#define RK_PWM_TIME_RPT_MIN 2000 -#define RK_PWM_TIME_RPT_MAX 2500 +#define RK_PWM_TIME_RPT_MIN 2000 +#define RK_PWM_TIME_RPT_MAX 2500 -#define RK_PWM_TIME_SEQ1_MIN 95000 -#define RK_PWM_TIME_SEQ1_MAX 98000 +#define RK_PWM_TIME_SEQ1_MIN 95000 +#define RK_PWM_TIME_SEQ1_MAX 98000 -#define RK_PWM_TIME_SEQ2_MIN 30000 -#define RK_PWM_TIME_SEQ2_MAX 55000 +#define RK_PWM_TIME_SEQ2_MIN 30000 +#define RK_PWM_TIME_SEQ2_MAX 55000 -#define PWM_REG_INTSTS(n) ((3 - (n)) * 0x10 + 0x10) -#define PWM_REG_INT_EN(n) ((3 - (n)) * 0x10 + 0x14) -#define RK_PWM_VERSION_ID(n) ((3 - (n)) * 0x10 + 0x2c) -#define PWM_REG_PWRMATCH_CTRL(n) ((3 - (n)) * 0x10 + 0x50) -#define PWM_REG_PWRMATCH_LPRE(n) ((3 - (n)) * 0x10 + 0x54) -#define PWM_REG_PWRMATCH_HPRE(n) ((3 - (n)) * 0x10 + 0x58) -#define PWM_REG_PWRMATCH_LD(n) ((3 - (n)) * 0x10 + 0x5C) -#define PWM_REG_PWRMATCH_HD_ZERO(n) ((3 - (n)) * 0x10 + 0x60) -#define PWM_REG_PWRMATCH_HD_ONE(n) ((3 - (n)) * 0x10 + 0x64) -#define PWM_PWRMATCH_VALUE(n) ((3 - (n)) * 0x10 + 0x68) -#define PWM_PWRCAPTURE_VALUE(n) ((3 - (n)) * 0x10 + 0x9c) - -#define PWM_CH_INT(n) BIT(n) -#define PWM_CH_POL(n) BIT(n+8) - -#define PWM_CH_INT_ENABLE(n) BIT(n) -#define PWM_PWR_INT_ENABLE BIT(7) -#define CH3_PWRKEY_ENABLE BIT(3) +#define PWM_REG_INTSTS(n) ((3 - (n)) * 0x10 + 0x10) +#define PWM_REG_INT_EN(n) ((3 - (n)) * 0x10 + 0x14) +#define RK_PWM_VERSION_ID(n) ((3 - (n)) * 0x10 + 0x2c) +#define PWM_REG_PWRMATCH_CTRL(n) ((3 - (n)) * 0x10 + 0x50) +#define PWM_REG_PWRMATCH_LPRE(n) ((3 - (n)) * 0x10 + 0x54) +#define PWM_REG_PWRMATCH_HPRE(n) ((3 - (n)) * 0x10 + 0x58) +#define PWM_REG_PWRMATCH_LD(n) ((3 - (n)) * 0x10 + 0x5C) +#define PWM_REG_PWRMATCH_HD_ZERO(n) ((3 - (n)) * 0x10 + 0x60) +#define PWM_REG_PWRMATCH_HD_ONE(n) ((3 - (n)) * 0x10 + 0x64) +#define PWM_PWRMATCH_VALUE(n) ((3 - (n)) * 0x10 + 0x68) +#define PWM_PWRCAPTURE_VALUE(n) ((3 - (n)) * 0x10 + 0x9c) +#define PWM_CH_INT(n) BIT(n) +#define PWM_CH_POL(n) BIT(n+8) +#define PWM_CH_INT_ENABLE(n) BIT(n) +#define PWM_PWR_INT_ENABLE BIT(7) +#define CH3_PWRKEY_ENABLE BIT(3) typedef enum _RMC_STATE { @@ -149,6 +207,10 @@ typedef enum _RMC_STATE { RMC_SEQUENCE, } eRMC_STATE; +enum { + IR_SUSPEND_MODE = 0, + IR_WORK_MODE +}; struct RKxx_remotectl_platform_data { int nbuttons; From 9de9c7ccf99ccb542b307fe13d89348e55a3921f Mon Sep 17 00:00:00 2001 From: Yandong Lin Date: Tue, 6 Feb 2024 14:41:47 +0800 Subject: [PATCH 11/13] video: rockchip: mpp: fix get drv data type err Fix issue that he drvdata obtained through dev_get_drvdata does not match the converted type. Change-Id: I4f5835c2fed609714ac6cb94197ca84a489a3d23 Signed-off-by: Yandong Lin --- drivers/video/rockchip/mpp/mpp_av1dec.c | 30 ++++-------------------- drivers/video/rockchip/mpp/mpp_rkvdec.c | 16 +++++++------ drivers/video/rockchip/mpp/mpp_rkvdec2.c | 7 +++--- drivers/video/rockchip/mpp/mpp_rkvenc.c | 7 +++--- drivers/video/rockchip/mpp/mpp_vdpp.c | 29 ++++------------------- 5 files changed, 27 insertions(+), 62 deletions(-) diff --git a/drivers/video/rockchip/mpp/mpp_av1dec.c b/drivers/video/rockchip/mpp/mpp_av1dec.c index 5dd5f59639d3..2d2055afc1a4 100644 --- a/drivers/video/rockchip/mpp/mpp_av1dec.c +++ b/drivers/video/rockchip/mpp/mpp_av1dec.c @@ -994,7 +994,7 @@ static int av1dec_probe(struct platform_device *pdev) return -ENOMEM; mpp = &dec->mpp; - platform_set_drvdata(pdev, dec); + platform_set_drvdata(pdev, mpp); if (pdev->dev.of_node) { match = of_match_node(mpp_av1dec_dt_match, pdev->dev.of_node); @@ -1042,39 +1042,19 @@ failed_get_irq: static int av1dec_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct av1dec_dev *dec = platform_get_drvdata(pdev); + struct mpp_dev *mpp = platform_get_drvdata(pdev); dev_info(dev, "remove device\n"); - mpp_dev_remove(&dec->mpp); - av1dec_procfs_remove(&dec->mpp); + mpp_dev_remove(mpp); + av1dec_procfs_remove(mpp); return 0; } -static void av1dec_shutdown(struct platform_device *pdev) -{ - int ret; - int val; - struct device *dev = &pdev->dev; - struct av1dec_dev *dec = platform_get_drvdata(pdev); - struct mpp_dev *mpp = &dec->mpp; - - dev_info(dev, "shutdown device\n"); - - atomic_inc(&mpp->srv->shutdown_request); - ret = readx_poll_timeout(atomic_read, - &mpp->task_count, - val, val == 0, 1000, 200000); - if (ret == -ETIMEDOUT) - dev_err(dev, "wait total running time out\n"); - - dev_info(dev, "shutdown success\n"); -} - struct platform_driver rockchip_av1dec_driver = { .probe = av1dec_probe, .remove = av1dec_remove, - .shutdown = av1dec_shutdown, + .shutdown = mpp_dev_shutdown, .driver = { .name = AV1DEC_DRIVER_NAME, .of_match_table = of_match_ptr(mpp_av1dec_dt_match), diff --git a/drivers/video/rockchip/mpp/mpp_rkvdec.c b/drivers/video/rockchip/mpp/mpp_rkvdec.c index 629ddcb218c1..b060e12b20a8 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvdec.c +++ b/drivers/video/rockchip/mpp/mpp_rkvdec.c @@ -325,8 +325,8 @@ static int devfreq_target(struct device *dev, struct dev_pm_opp *opp; unsigned long target_volt, target_freq; unsigned long aclk_rate_hz, core_rate_hz, cabac_rate_hz; - - struct rkvdec_dev *dec = dev_get_drvdata(dev); + struct mpp_dev *mpp = dev_get_drvdata(dev); + struct rkvdec_dev *dec = to_rkvdec_dev(mpp); struct devfreq *devfreq = dec->devfreq; struct devfreq_dev_status *stat = &devfreq->last_status; unsigned long old_clk_rate = stat->current_frequency; @@ -392,7 +392,8 @@ static int devfreq_target(struct device *dev, static int devfreq_get_cur_freq(struct device *dev, unsigned long *freq) { - struct rkvdec_dev *dec = dev_get_drvdata(dev); + struct mpp_dev *mpp = dev_get_drvdata(dev); + struct rkvdec_dev *dec = to_rkvdec_dev(mpp); *freq = clk_get_rate(dec->aclk_info.clk); @@ -402,7 +403,8 @@ static int devfreq_get_cur_freq(struct device *dev, static int devfreq_get_dev_status(struct device *dev, struct devfreq_dev_status *stat) { - struct rkvdec_dev *dec = dev_get_drvdata(dev); + struct mpp_dev *mpp = dev_get_drvdata(dev); + struct rkvdec_dev *dec = to_rkvdec_dev(mpp); struct devfreq *devfreq = dec->devfreq; memcpy(stat, &devfreq->last_status, sizeof(*stat)); @@ -1904,11 +1906,11 @@ static int rkvdec_probe(struct platform_device *pdev) static int rkvdec_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct rkvdec_dev *dec = platform_get_drvdata(pdev); + struct mpp_dev *mpp = platform_get_drvdata(pdev); dev_info(dev, "remove device\n"); - mpp_dev_remove(&dec->mpp); - rkvdec_procfs_remove(&dec->mpp); + mpp_dev_remove(mpp); + rkvdec_procfs_remove(mpp); return 0; } diff --git a/drivers/video/rockchip/mpp/mpp_rkvdec2.c b/drivers/video/rockchip/mpp/mpp_rkvdec2.c index 305996c676fe..65b477be400b 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvdec2.c +++ b/drivers/video/rockchip/mpp/mpp_rkvdec2.c @@ -711,8 +711,8 @@ static int rkvdec2_devfreq_target(struct device *dev, struct dev_pm_opp *opp; unsigned long target_volt, target_freq; int ret = 0; - - struct rkvdec2_dev *dec = dev_get_drvdata(dev); + struct mpp_dev *mpp = dev_get_drvdata(dev); + struct rkvdec2_dev *dec = to_rkvdec2_dev(mpp); struct devfreq *devfreq = dec->devfreq; struct devfreq_dev_status *stat = &devfreq->last_status; unsigned long old_clk_rate = stat->current_frequency; @@ -774,7 +774,8 @@ static int rkvdec2_devfreq_get_dev_status(struct device *dev, static int rkvdec2_devfreq_get_cur_freq(struct device *dev, unsigned long *freq) { - struct rkvdec2_dev *dec = dev_get_drvdata(dev); + struct mpp_dev *mpp = dev_get_drvdata(dev); + struct rkvdec2_dev *dec = to_rkvdec2_dev(mpp); *freq = dec->core_last_rate_hz; diff --git a/drivers/video/rockchip/mpp/mpp_rkvenc.c b/drivers/video/rockchip/mpp/mpp_rkvenc.c index 5419954a8017..3e02712b0f60 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvenc.c +++ b/drivers/video/rockchip/mpp/mpp_rkvenc.c @@ -850,8 +850,8 @@ static int rkvenc_devfreq_target(struct device *dev, struct dev_pm_opp *opp; unsigned long target_volt, target_freq; int ret = 0; - - struct rkvenc_dev *enc = dev_get_drvdata(dev); + struct mpp_dev *mpp = dev_get_drvdata(dev); + struct rkvenc_dev *enc = to_rkvenc_dev(mpp); struct devfreq *devfreq = enc->devfreq; struct devfreq_dev_status *stat = &devfreq->last_status; unsigned long old_clk_rate = stat->current_frequency; @@ -913,7 +913,8 @@ static int rkvenc_devfreq_get_dev_status(struct device *dev, static int rkvenc_devfreq_get_cur_freq(struct device *dev, unsigned long *freq) { - struct rkvenc_dev *enc = dev_get_drvdata(dev); + struct mpp_dev *mpp = dev_get_drvdata(dev); + struct rkvenc_dev *enc = to_rkvenc_dev(mpp); *freq = enc->core_last_rate_hz; diff --git a/drivers/video/rockchip/mpp/mpp_vdpp.c b/drivers/video/rockchip/mpp/mpp_vdpp.c index c0dc382a1872..031a975e00bf 100644 --- a/drivers/video/rockchip/mpp/mpp_vdpp.c +++ b/drivers/video/rockchip/mpp/mpp_vdpp.c @@ -696,9 +696,8 @@ static int vdpp_probe(struct platform_device *pdev) vdpp = devm_kzalloc(dev, sizeof(struct vdpp_dev), GFP_KERNEL); if (!vdpp) return -ENOMEM; - platform_set_drvdata(pdev, vdpp); - mpp = &vdpp->mpp; + platform_set_drvdata(pdev, mpp); if (pdev->dev.of_node) { match = of_match_node(mpp_vdpp_dt_match, pdev->dev.of_node); if (match) @@ -745,37 +744,19 @@ static int vdpp_probe(struct platform_device *pdev) static int vdpp_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct vdpp_dev *vdpp = platform_get_drvdata(pdev); + struct mpp_dev *mpp = platform_get_drvdata(pdev); dev_info(dev, "remove device\n"); - mpp_dev_remove(&vdpp->mpp); - vdpp_procfs_remove(&vdpp->mpp); + mpp_dev_remove(mpp); + vdpp_procfs_remove(mpp); return 0; } -static void vdpp_shutdown(struct platform_device *pdev) -{ - int ret; - int val; - struct device *dev = &pdev->dev; - struct vdpp_dev *vdpp = platform_get_drvdata(pdev); - struct mpp_dev *mpp = &vdpp->mpp; - - dev_info(dev, "shutdown device\n"); - - atomic_inc(&mpp->srv->shutdown_request); - ret = readx_poll_timeout(atomic_read, - &mpp->task_count, - val, val == 0, 20000, 200000); - if (ret == -ETIMEDOUT) - dev_err(dev, "wait total running time out\n"); -} - struct platform_driver rockchip_vdpp_driver = { .probe = vdpp_probe, .remove = vdpp_remove, - .shutdown = vdpp_shutdown, + .shutdown = mpp_dev_shutdown, .driver = { .name = VDPP_DRIVER_NAME, .of_match_table = of_match_ptr(mpp_vdpp_dt_match), From a73c8e037d980b31a81329a96a80c8562131a4e9 Mon Sep 17 00:00:00 2001 From: Sandy Huang Date: Tue, 6 Feb 2024 18:42:46 +0800 Subject: [PATCH 12/13] drm/rockchip: vop2: primary plane need consider win possible_crtcs Signed-off-by: Sandy Huang Change-Id: I4a7529bfd70a39970ffeb7ddaca0d37dfc0d7b0c --- drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index b9162f87f54e..e8c61d8fbbb6 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -11299,6 +11299,12 @@ static int vop2_crtc_create_post_csc_property(struct vop2 *vop2, struct drm_crtc #define RK3566_MIRROR_PLANE_MASK (BIT(ROCKCHIP_VOP2_CLUSTER1) | BIT(ROCKCHIP_VOP2_ESMART1) | \ BIT(ROCKCHIP_VOP2_SMART1)) +static inline bool vop2_win_can_link_to_vp(struct vop2_video_port *vp, struct vop2_win *win) +{ + return (!win->possible_crtcs || + (win->possible_crtcs && (win->possible_crtcs & BIT(vp->id)))); +} + /* * Returns: * Registered crtc number on success, negative error code on failure. @@ -11414,14 +11420,17 @@ static int vop2_create_crtc(struct vop2 *vop2) plane_mask &= ~RK3566_MIRROR_PLANE_MASK; } } + find_primary_plane = false; if (vp->primary_plane_phy_id >= 0) { win = vop2_find_win_by_phys_id(vop2, vp->primary_plane_phy_id); - if (win) { + if (win && vop2_win_can_link_to_vp(vp, win)) { find_primary_plane = true; win->type = DRM_PLANE_TYPE_PRIMARY; } - } else { + } + + if (!find_primary_plane) { j = 0; while (j < vop2->registered_num_wins) { be_used_for_primary_plane = false; @@ -11434,6 +11443,9 @@ static int vop2_create_crtc(struct vop2 *vop2) if (win->type != DRM_PLANE_TYPE_PRIMARY) continue; + if (!vop2_win_can_link_to_vp(vp, win)) + continue; + for (k = 0; k < vop2_data->nr_vps; k++) { if (win->phys_id == vop2->vps[k].primary_plane_phy_id) { be_used_for_primary_plane = true; From 19e4b7da3917191c274947a3c351fb8419c86a93 Mon Sep 17 00:00:00 2001 From: Binyuan Lan Date: Tue, 23 Jan 2024 13:20:18 +0000 Subject: [PATCH 13/13] ASoC: rockchip: rk817-codec: fix pop from DAC_DIG_CLK_DIS and DAC_DIG_CLK_EN Signed-off-by: Binyuan Lan Change-Id: Idfa31a4f3484f1641ebcf46d237244e98e378e93 --- sound/soc/codecs/rk817_codec.c | 142 ++++++++++++++++++++++----------- 1 file changed, 94 insertions(+), 48 deletions(-) diff --git a/sound/soc/codecs/rk817_codec.c b/sound/soc/codecs/rk817_codec.c index 51388b2e6d48..400be6d5c3d4 100644 --- a/sound/soc/codecs/rk817_codec.c +++ b/sound/soc/codecs/rk817_codec.c @@ -231,16 +231,22 @@ static int rk817_codec_ctl_gpio(struct rk817_codec_priv *rk817, { if ((gpio & CODEC_SET_SPK) && rk817->spk_ctl_gpio) { + if (level && rk817->spk_mute_delay) + msleep(rk817->spk_mute_delay); gpiod_set_value(rk817->spk_ctl_gpio, level); DBG("%s set spk clt %d\n", __func__, level); - msleep(rk817->spk_mute_delay); + if (!level && rk817->spk_mute_delay) + msleep(rk817->spk_mute_delay); } if ((gpio & CODEC_SET_HP) && rk817->hp_ctl_gpio) { + if (level && rk817->hp_mute_delay) + msleep(rk817->hp_mute_delay); gpiod_set_value(rk817->hp_ctl_gpio, level); DBG("%s set hp clt %d\n", __func__, level); - msleep(rk817->hp_mute_delay); + if (!level && rk817->hp_mute_delay) + msleep(rk817->hp_mute_delay); } return 0; @@ -260,12 +266,12 @@ static int rk817_reset(struct snd_soc_component *component) snd_soc_component_write(component, RK817_CODEC_APLL_CFG5, 0x00); snd_soc_component_write(component, RK817_CODEC_DTOP_DIGEN_CLKE, 0x00); if (rk817->chip_ver <= 0x4) { - DBG("%s (%d): SMIC TudorAG and previous versions\n", + DBG("%s (%d): 0x4 and previous versions\n", __func__, __LINE__); snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x0c); snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0x95); } else { - DBG("%s (%d): SMIC TudorAG version later\n", + DBG("%s (%d): 0x4 version later\n", __func__, __LINE__); snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x04); snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0xa5); @@ -275,6 +281,77 @@ static int rk817_reset(struct snd_soc_component *component) return 0; } +static int rk817_restart_dac_digital_clk(struct snd_soc_component *component) +{ + snd_soc_component_update_bits(component, RK817_CODEC_ADAC_CFG1, + PWD_DACBIAS_MASK, PWD_DACBIAS_DOWN); + usleep_range(500, 600); + snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, + DAC_DIG_CLK_MASK, DAC_DIG_CLK_DIS); + usleep_range(500, 600); + snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, + DAC_DIG_CLK_MASK, DAC_DIG_CLK_EN); + DBG("%s: %d - Playback DIG CLK OPS\n", __func__, __LINE__); + usleep_range(500, 600); + snd_soc_component_update_bits(component, RK817_CODEC_ADAC_CFG1, + PWD_DACBIAS_MASK, PWD_DACBIAS_ON); + + return 0; +} + +static int rk817_restart_dac_digital_clk_and_apll(struct snd_soc_component *component) +{ + snd_soc_component_update_bits(component, RK817_CODEC_ADAC_CFG1, + PWD_DACBIAS_MASK, PWD_DACBIAS_DOWN); + usleep_range(500, 600); + snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, + DAC_DIG_CLK_MASK, DAC_DIG_CLK_DIS); + usleep_range(500, 600); + snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, + DAC_DIG_CLK_MASK, DAC_DIG_CLK_EN); + DBG("%s: %d - Playback DIG CLK OPS\n", __func__, __LINE__); + snd_soc_component_update_bits(component, RK817_CODEC_APLL_CFG5, + PLL_PW_DOWN, PLL_PW_DOWN); + usleep_range(50, 60); + snd_soc_component_update_bits(component, RK817_CODEC_APLL_CFG5, + PLL_PW_DOWN, PLL_PW_UP); + usleep_range(500, 600); + snd_soc_component_update_bits(component, RK817_CODEC_ADAC_CFG1, + PWD_DACBIAS_MASK, PWD_DACBIAS_ON); + + return 0; +} + +static int rk817_restart_adc_digital_clk(struct snd_soc_component *component) +{ + snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, + ADC_DIG_CLK_MASK, ADC_DIG_CLK_DIS); + usleep_range(500, 600); + snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, + ADC_DIG_CLK_MASK, ADC_DIG_CLK_EN); + DBG("%s: %d - Capture DIG CLK OPS\n", __func__, __LINE__); + + return 0; +} + +static int rk817_restart_adc_digital_clk_and_apll(struct snd_soc_component *component) +{ + snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, + ADC_DIG_CLK_MASK, ADC_DIG_CLK_DIS); + usleep_range(500, 600); + snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, + ADC_DIG_CLK_MASK, ADC_DIG_CLK_EN); + DBG("%s: %d - Capture DIG CLK OPS\n", __func__, __LINE__); + snd_soc_component_update_bits(component, RK817_CODEC_APLL_CFG5, + PLL_PW_DOWN, PLL_PW_DOWN); + usleep_range(50, 60); + snd_soc_component_update_bits(component, RK817_CODEC_APLL_CFG5, + PLL_PW_DOWN, PLL_PW_UP); + usleep_range(500, 600); + + return 0; +} + static struct rk817_reg_val_typ playback_power_up_list[] = { {RK817_CODEC_AREF_RTCFG1, 0x40}, {RK817_CODEC_DDAC_POPD_DACST, 0x02}, @@ -373,22 +450,16 @@ static int rk817_codec_power_up(struct snd_soc_component *component, int type) /* configure APLL CFG0/4 */ if (rk817->chip_ver <= 0x4) { - DBG("%s (%d): SMIC TudorAG and previous versions\n", + DBG("%s (%d): 0x4 and previous versions\n", __func__, __LINE__); snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x0c); snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0x95); } else { - DBG("%s: SMIC TudorAG version later\n", __func__); + DBG("%s: 0x4 version later\n", __func__); snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x04); snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0xa5); } - - snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, - DAC_DIG_CLK_MASK, DAC_DIG_CLK_DIS); - usleep_range(2000, 2500); - snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, - DAC_DIG_CLK_MASK, DAC_DIG_CLK_EN); - DBG("%s: %d - Playback DIG CLK OPS\n", __func__, __LINE__); + rk817_restart_dac_digital_clk(component); } if (type & RK817_CODEC_CAPTURE) { @@ -404,22 +475,17 @@ static int rk817_codec_power_up(struct snd_soc_component *component, int type) /* configure APLL CFG0/4 */ if (rk817->chip_ver <= 0x4) { - DBG("%s (%d): SMIC TudorAG and previous versions\n", + DBG("%s (%d): 0x4 and previous versions\n", __func__, __LINE__); snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x0c); snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0x95); } else { - DBG("%s: SMIC TudorAG version later\n", __func__); + DBG("%s: 0x4 version later\n", __func__); snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x04); snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0xa5); } - snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, - ADC_DIG_CLK_MASK, ADC_DIG_CLK_DIS); - usleep_range(2000, 2500); - snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, - ADC_DIG_CLK_MASK, ADC_DIG_CLK_EN); - DBG("%s: %d - Capture DIG CLK OPS\n", __func__, __LINE__); + rk817_restart_adc_digital_clk(component); if (rk817->mic_in_differential) snd_soc_component_update_bits(component, @@ -941,25 +1007,19 @@ static int rk817_hw_params(struct snd_pcm_substream *substream, unsigned int rate = params_rate(params); unsigned char apll_cfg3_val; unsigned char dtop_digen_sr_lmt0; - unsigned char dtop_digen_clke; DBG("%s : sample rate = %dHz\n", __func__, rate); if (rk817->chip_ver <= 0x4) { - DBG("%s: SMIC TudorAG and previous versions\n", __func__); + DBG("%s: 0x4 and previous versions\n", __func__); snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x0c); snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0x95); } else { - DBG("%s: SMIC TudorAG version later\n", __func__); + DBG("%s: 0x4 version later\n", __func__); snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x04); snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0xa5); } - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - dtop_digen_clke = DAC_DIG_CLK_EN; - else - dtop_digen_clke = ADC_DIG_CLK_EN; - switch (rate) { case 8000: apll_cfg3_val = 0x03; @@ -991,19 +1051,12 @@ static int rk817_hw_params(struct snd_pcm_substream *substream, */ if (!((substream->stream == SNDRV_PCM_STREAM_CAPTURE) && rk817->pdmdata_out_enable)) { snd_soc_component_write(component, RK817_CODEC_APLL_CFG3, apll_cfg3_val); - /* The 0x00 contains ADC_DIG_CLK_DIS and DAC_DIG_CLK_DIS */ - snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, - dtop_digen_clke, 0x00); snd_soc_component_update_bits(component, RK817_CODEC_DDAC_SR_LMT0, DACSRT_MASK, dtop_digen_sr_lmt0); - snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, - dtop_digen_clke, dtop_digen_clke); - snd_soc_component_update_bits(component, RK817_CODEC_APLL_CFG5, - PLL_PW_DOWN, PLL_PW_DOWN); - usleep_range(50, 60); - snd_soc_component_update_bits(component, RK817_CODEC_APLL_CFG5, - PLL_PW_DOWN, PLL_PW_UP); - usleep_range(500, 600); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + rk817_restart_dac_digital_clk_and_apll(component); + else + rk817_restart_adc_digital_clk_and_apll(component); } switch (params_format(params)) { @@ -1041,14 +1094,7 @@ static int rk817_digital_mute_dac(struct snd_soc_dai *dai, int mute, int stream) snd_soc_component_update_bits(component, RK817_CODEC_DDAC_MUTE_MIXCTL, DACMT_ENABLE, DACMT_ENABLE); - snd_soc_component_write(component, RK817_CODEC_ADAC_CFG1, - PWD_DACBIAS_DOWN | PWD_DACD_DOWN | - PWD_DACL_DOWN | PWD_DACR_DOWN); - /* Reset DAC DTOP_DIGEN_CLKE for playback stopped */ - snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, - DAC_DIG_CLK_EN, DAC_DIG_CLK_DIS); - snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, - DAC_DIG_CLK_EN, DAC_DIG_CLK_EN); + rk817_restart_dac_digital_clk(component); snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, I2SRX_EN_MASK, I2SRX_DIS); } else {