diff --git a/drivers/gpu/arm/bifrost/backend/gpu/mali_kbase_devfreq.c b/drivers/gpu/arm/bifrost/backend/gpu/mali_kbase_devfreq.c index 9b8628041888..0712439e37a5 100644 --- a/drivers/gpu/arm/bifrost/backend/gpu/mali_kbase_devfreq.c +++ b/drivers/gpu/arm/bifrost/backend/gpu/mali_kbase_devfreq.c @@ -597,7 +597,7 @@ int kbase_devfreq_init(struct kbase_device *kbdev) &ondemand_data.upthreshold); of_property_read_u32(np, "downdifferential", &ondemand_data.downdifferential); - kbdev->devfreq = devfreq_add_device(kbdev->dev, dp, "simple_ondemand", NULL); + kbdev->devfreq = devfreq_add_device(kbdev->dev, dp, "simple_ondemand", &ondemand_data); if (IS_ERR(kbdev->devfreq)) { err = PTR_ERR(kbdev->devfreq); kbdev->devfreq = NULL; diff --git a/drivers/gpu/arm/bifrost/mali_kbase_gpu_metrics.c b/drivers/gpu/arm/bifrost/mali_kbase_gpu_metrics.c index 7b33f86644ea..8e00c0dc830e 100644 --- a/drivers/gpu/arm/bifrost/mali_kbase_gpu_metrics.c +++ b/drivers/gpu/arm/bifrost/mali_kbase_gpu_metrics.c @@ -67,7 +67,7 @@ static inline void gpu_metrics_ctx_flag_clear(struct kbase_gpu_metrics_ctx *gpu_ static inline void validate_tracepoint_data(struct kbase_gpu_metrics_ctx *gpu_metrics_ctx, u64 start_time, u64 end_time, u64 total_active) { -#ifdef CONFIG_MALI_BIFROST_DEBUG +#if 0 WARN(total_active > NSEC_PER_SEC, "total_active %llu > 1 second for aid %u active_cnt %u", total_active, gpu_metrics_ctx->aid, gpu_metrics_ctx->active_cnt); diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index 1b701b1133cb..5c4e21cb8144 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -1326,7 +1326,7 @@ static int analogix_dp_get_modes(struct drm_connector *connector) if (dp->plat_data->get_modes) num_modes += dp->plat_data->get_modes(dp->plat_data, connector); - if (num_modes > 0 && dp->plat_data->split_mode) { + if (num_modes > 0 && dp->plat_data->split_mode && !dp->plat_data->dual_channel_mode) { struct drm_display_mode *mode; list_for_each_entry(mode, &connector->probed_modes, head) diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c index dc10a0ced204..4ad6551ede24 100644 --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c @@ -699,7 +699,9 @@ static int rockchip_dp_probe(struct platform_device *pdev) if (IS_ERR(dp->adp)) return PTR_ERR(dp->adp); - if (dp->data->split_mode && device_property_read_bool(dev, "split-mode")) { + if (dp->data->split_mode && + (device_property_read_bool(dev, "split-mode") || + device_property_read_bool(dev, "dual-channel"))) { struct rockchip_dp_device *secondary = rockchip_dp_find_by_id(dev->driver, !dp->id); if (!secondary) { @@ -709,6 +711,7 @@ static int rockchip_dp_probe(struct platform_device *pdev) dp->plat_data.right = secondary->adp; dp->plat_data.split_mode = true; + dp->plat_data.dual_channel_mode = device_property_read_bool(dev, "dual-channel"); secondary->plat_data.panel = dp->plat_data.panel; secondary->plat_data.left = dp->adp; secondary->plat_data.split_mode = true; diff --git a/drivers/media/i2c/cam-sleep-wakeup.c b/drivers/media/i2c/cam-sleep-wakeup.c index f8a6c83369b4..22053f86e232 100644 --- a/drivers/media/i2c/cam-sleep-wakeup.c +++ b/drivers/media/i2c/cam-sleep-wakeup.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -155,9 +156,6 @@ int cam_sw_prepare_wakeup(struct cam_sw_info *info, struct device *dev) return -EINVAL; } - if (!IS_ERR(info->pin.reset_gpio)) - gpiod_set_value_cansleep(info->pin.reset_gpio, info->pin.reset_active_state); - if (!IS_ERR(info->pin.supplies) && info->pin.supplies_num) { ret = regulator_bulk_enable(info->pin.supplies_num, info->pin.supplies); if (ret != 0) @@ -183,7 +181,7 @@ int cam_sw_prepare_sleep(struct cam_sw_info *info) gpiod_set_value_cansleep(info->pin.pwdn_gpio, !info->pin.pwdn_active_state); if (!IS_ERR(info->pin.reset_gpio)) - gpiod_set_value_cansleep(info->pin.reset_gpio, !info->pin.reset_active_state); + gpiod_set_value_cansleep(info->pin.reset_gpio, info->pin.reset_active_state); if (!IS_ERR_OR_NULL(info->pin.pins_sleep)) pinctrl_select_state(info->pin.pinctrl, info->pin.pins_sleep); diff --git a/drivers/media/i2c/os04d10.c b/drivers/media/i2c/os04d10.c index e14b53d2d997..24e34034bc6e 100644 --- a/drivers/media/i2c/os04d10.c +++ b/drivers/media/i2c/os04d10.c @@ -171,6 +171,308 @@ static const struct regval os04d10_global_regs[] = { {REG_NULL, 0x00}, }; +/* + * Xclk 24Mhz + * max_framerate 120fps + * mipi_datarate per lane 720Mbps, 2lane + * 4X4 binning to 640X360 + */ +static const struct regval os04d10_linear_10_640x360_regs[] = { + {0xfd, 0x00}, + {0x20, 0x00}, + {0x20, 0x01}, + {0x20, 0x01}, + {0x20, 0x01}, + {0x20, 0x01}, + {0x41, 0xa8}, + {0x45, 0x24}, + {0x30, 0x02}, + {0x31, 0x24}, + {0x35, 0xc9}, + {0x38, 0x15}, + {0xfd, 0x01}, + {0x03, 0x00}, + {0x04, 0x04}, + {0x06, 0x01}, + {0x24, 0xff}, + {0x31, 0x26}, + {0x02, 0x01}, + {0x42, 0x5a}, + {0x47, 0x0c}, + {0x45, 0x02}, + {0x48, 0x0c}, + {0x4b, 0x88}, + {0xd4, 0x05}, + {0xd5, 0xd2}, + {0xd7, 0x05}, + {0xd8, 0xd2}, + {0x50, 0x01}, + {0x51, 0x11}, + {0x52, 0x18}, + {0x53, 0x01}, + {0x54, 0x01}, + {0x55, 0x01}, + {0x57, 0x08}, + {0x5c, 0x40}, + {0x7c, 0x06}, + {0x7d, 0x05}, + {0x7e, 0x05}, + {0x7f, 0x05}, + {0x90, 0x60}, + {0x91, 0x0f}, + {0x92, 0x35}, + {0x93, 0x36}, + {0x94, 0x0f}, + {0x95, 0x7e}, + {0x98, 0x5d}, + {0xa8, 0x50}, + {0xaa, 0x14}, + {0xab, 0x05}, + {0xac, 0x14}, + {0xad, 0x05}, + {0xae, 0x4a}, + {0xaf, 0x0e}, + {0xb2, 0x07}, + {0xb3, 0x0c}, + {0xc9, 0x28}, + {0xca, 0x5e}, + {0xcb, 0x5e}, + {0xcc, 0x5e}, + {0xcd, 0x5e}, + {0xce, 0x5c}, + {0xcf, 0x5c}, + {0xd0, 0x5c}, + {0xd1, 0x5c}, + {0xd2, 0x7c}, + {0xd3, 0x7c}, + {0xdb, 0x0f}, + {0xfd, 0x01}, + {0x46, 0x77}, + {0xdd, 0x00}, + {0xde, 0x3f}, + {0xfd, 0x03}, + {0x2b, 0x0a}, + {0x01, 0x22}, + {0x02, 0x03}, + {0x00, 0x06}, + {0x2a, 0x22}, + {0x29, 0x0b}, + {0x1e, 0x10}, + {0x1f, 0x02}, + {0x1a, 0x24}, + {0x1b, 0x62}, + {0x1c, 0xce}, + {0x1d, 0xd3}, + {0x04, 0x0f}, + {0x36, 0x00}, + {0x37, 0x05}, + {0x38, 0x09}, + {0x39, 0x19}, + {0x3a, 0x38}, + {0x3b, 0x22}, + {0x3c, 0x22}, + {0x3d, 0x22}, + {0x3e, 0x03}, + {0xfd, 0x02}, + {0xc1, 0x05}, + {0x8c, 0x03}, + {0x8d, 0x01}, + {0x95, 0x02}, + {0x98, 0x02}, + {0x5e, 0x22}, + {0xa1, 0x00}, + {0xa2, 0x01}, + {0xa3, 0x68}, + {0xa5, 0x02}, + {0xa6, 0x02}, + {0xa7, 0x80}, + {0x8e, 0x02}, + {0x8f, 0x80}, + {0x90, 0x01}, + {0x91, 0x68}, + {0xce, 0x65}, + {0xfd, 0x03}, + {0x03, 0x30}, + {0x05, 0x00}, + {0x12, 0x70}, + {0x13, 0x70}, + {0x16, 0x13}, + {0x21, 0xca}, + {0x27, 0x95}, + {0x2c, 0x55}, + {0x2d, 0x08}, + {0x2e, 0xca}, + {0x3f, 0xe7}, + {0xfd, 0x00}, + {0x8b, 0x01}, + {0x8d, 0x00}, + {0xfd, 0x01}, + {0x01, 0x02}, + {0xfd, 0x05}, + {0xc4, 0x62}, + {0xc5, 0x62}, + {0xc6, 0x62}, + {0xc7, 0x62}, + {0xce, 0x3e}, + {0xf0, 0x40}, + {0xf1, 0x40}, + {0xf2, 0x40}, + {0xf3, 0x40}, + {0xf4, 0x00}, + {0xf9, 0x03}, + {0xfa, 0x5d}, + {0xfb, 0x6b}, + {0xb1, 0x01}, + {REG_NULL, 0x00}, +}; + +/* + * Xclk 24Mhz + * max_framerate 30fps + * mipi_datarate per lane 720Mbps, 2lane + * raw 10 + * 2560 x 1440 + */ +static const struct regval os04d10_linear_10_2560x1440_regs[] = { + {0xfd, 0x00}, + {0x20, 0x00}, + {0x20, 0x01}, + {0x20, 0x01}, + {0x20, 0x01}, + {0x20, 0x01}, + {0x41, 0xa8}, + {0x45, 0x24}, + {0x31, 0x20}, + {0x38, 0x15}, + {0xfd, 0x01}, + {0x03, 0x00}, + {0x04, 0x04}, + {0x06, 0x01}, + {0x24, 0xff}, + {0x02, 0x01}, + {0x42, 0x5a}, + {0x47, 0x0c}, + {0x45, 0x02}, + {0x48, 0x0c}, + {0x4b, 0x88}, + {0xd4, 0x05}, + {0xd5, 0xd2}, + {0xd7, 0x05}, + {0xd8, 0xd2}, + {0x50, 0x01}, + {0x51, 0x11}, + {0x52, 0x18}, + {0x53, 0x01}, + {0x54, 0x01}, + {0x55, 0x01}, + {0x57, 0x08}, + {0x5c, 0x40}, + {0x7c, 0x06}, + {0x7d, 0x05}, + {0x7e, 0x05}, + {0x7f, 0x05}, + {0x90, 0x60}, + {0x91, 0x0f}, + {0x92, 0x35}, + {0x93, 0x36}, + {0x94, 0x0f}, + {0x95, 0x7e}, + {0x98, 0x5d}, + {0xa8, 0x50}, + {0xaa, 0x14}, + {0xab, 0x05}, + {0xac, 0x14}, + {0xad, 0x05}, + {0xae, 0x4a}, + {0xaf, 0x0e}, + {0xb2, 0x07}, + {0xb3, 0x0c}, + {0xc9, 0x28}, + {0xca, 0x5e}, + {0xcb, 0x5e}, + {0xcc, 0x5e}, + {0xcd, 0x5e}, + {0xce, 0x5c}, + {0xcf, 0x5c}, + {0xd0, 0x5c}, + {0xd1, 0x5c}, + {0xd2, 0x7c}, + {0xd3, 0x7c}, + {0xdb, 0x0f}, + {0xfd, 0x01}, + {0x46, 0x77}, + {0xdd, 0x00}, + {0xde, 0x3f}, + {0xfd, 0x03}, + {0x2b, 0x0a}, + {0x01, 0x22}, + {0x02, 0x03}, + {0x00, 0x06}, + {0x2a, 0x22}, + {0x29, 0x0b}, + {0x1e, 0x10}, + {0x1f, 0x02}, + {0x1a, 0x24}, + {0x1b, 0x62}, + {0x1c, 0xce}, + {0x1d, 0xd3}, + {0x04, 0x0f}, + {0x36, 0x00}, + {0x37, 0x05}, + {0x38, 0x09}, + {0x39, 0x19}, + {0x3a, 0x38}, + {0x3b, 0x22}, + {0x3c, 0x22}, + {0x3d, 0x22}, + {0x3e, 0x03}, + {0xfd, 0x02}, + {0x5e, 0x22}, + {0xa1, 0x04}, + {0xa2, 0x05}, + {0xa3, 0xa0}, + {0xa5, 0x04}, + {0xa6, 0x0a}, + {0xa7, 0x00}, + {0x8e, 0x0a}, + {0x8f, 0x00}, + {0x90, 0x05}, + {0x91, 0xa0}, + {0xce, 0x65}, + {0xfd, 0x03}, + {0x03, 0x30}, + {0x05, 0x00}, + {0x12, 0x70}, + {0x13, 0x70}, + {0x16, 0x13}, + {0x21, 0xca}, + {0x27, 0x95}, + {0x2c, 0x55}, + {0x2d, 0x08}, + {0x2e, 0xca}, + {0x3f, 0xe7}, + {0xfd, 0x00}, + {0x8b, 0x01}, + {0x8d, 0x00}, + {0xfd, 0x01}, + {0x01, 0x02}, + {0xfd, 0x05}, + {0xc4, 0x62}, + {0xc5, 0x62}, + {0xc6, 0x62}, + {0xc7, 0x62}, + {0xf0, 0x40}, + {0xf1, 0x40}, + {0xf2, 0x40}, + {0xf3, 0x40}, + {0xf4, 0x00}, + {0xf9, 0x03}, + {0xfa, 0x5d}, + {0xfb, 0x6b}, + {0xb1, 0x01}, + {REG_NULL, 0x00}, +}; + /* * Xclk 24Mhz * max_framerate 15fps @@ -307,6 +609,21 @@ static const struct regval os04d10_linear_10_2568x1448_regs[] = { }; static const struct os04d10_mode supported_modes[] = { + { + .width = 2560, + .height = 1440, + .max_fps = { + .numerator = 10000, + .denominator = 300000, + }, + .exp_def = 0x0080, + .hts_def = 0x032e, + .vts_def = 0x05c1, + .bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10, + .reg_list = os04d10_linear_10_2560x1440_regs, + .hdr_mode = NO_HDR, + .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0, + }, { .width = 2568, .height = 1448, @@ -321,6 +638,21 @@ static const struct os04d10_mode supported_modes[] = { .reg_list = os04d10_linear_10_2568x1448_regs, .hdr_mode = NO_HDR, .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0, + }, + { + .width = 640, + .height = 360, + .max_fps = { + .numerator = 10000, + .denominator = 1200000, + }, + .exp_def = 0x0080, + .hts_def = 0x032e, + .vts_def = 0x0171, + .bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10, + .reg_list = os04d10_linear_10_640x360_regs, + .hdr_mode = NO_HDR, + .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0, } }; @@ -871,32 +1203,30 @@ static int __os04d10_power_on(struct os04d10 *os04d10) dev_err(dev, "could not set pins\n"); } - if (os04d10->is_thunderboot) - return 0; + if (!os04d10->is_thunderboot) { + if (!IS_ERR(os04d10->reset_gpio)) + gpiod_set_value_cansleep(os04d10->reset_gpio, 0); - if (!IS_ERR(os04d10->reset_gpio)) - gpiod_set_value_cansleep(os04d10->reset_gpio, 0); + usleep_range(5000, 6000); - usleep_range(5000, 6000); + ret = regulator_bulk_enable(OS04D10_NUM_SUPPLIES, os04d10->supplies); + if (ret < 0) { + dev_err(dev, "Failed to enable regulators\n"); + goto disable_clk; + } - ret = regulator_bulk_enable(OS04D10_NUM_SUPPLIES, os04d10->supplies); - if (ret < 0) { - dev_err(dev, "Failed to enable regulators\n"); - goto disable_clk; - } + if (!IS_ERR(os04d10->reset_gpio)) + gpiod_set_value_cansleep(os04d10->reset_gpio, 1); - if (!IS_ERR(os04d10->reset_gpio)) - gpiod_set_value_cansleep(os04d10->reset_gpio, 1); + usleep_range(500, 1000); - usleep_range(500, 1000); + if (!IS_ERR(os04d10->reset_gpio)) + usleep_range(8000, 10000); + else + usleep_range(12000, 16000); - if (!IS_ERR(os04d10->reset_gpio)) - usleep_range(8000, 10000); - else usleep_range(12000, 16000); - - usleep_range(12000, 16000); - + } ret = clk_set_rate(os04d10->xvclk, OS04D10_XVCLK_FREQ); if (ret < 0) dev_warn(dev, "Failed to set xvclk rate (24MHz)\n"); @@ -908,6 +1238,9 @@ static int __os04d10_power_on(struct os04d10 *os04d10) return ret; } + if (os04d10->is_thunderboot) + return 0; + /* 8192 cycles prior to first SCCB transaction */ delay_us = os04d10_cal_delay(8192); usleep_range(delay_us, delay_us * 2); @@ -1352,7 +1685,7 @@ static int os04d10_probe(struct i2c_client *client, if (IS_ERR(os04d10->reset_gpio)) dev_warn(dev, "Failed to get reset-gpios\n"); - if (!IS_ERR(os04d10->reset_gpio)) + if (!IS_ERR(os04d10->reset_gpio) && !os04d10->is_thunderboot) gpiod_set_value_cansleep(os04d10->reset_gpio, 0); os04d10->pinctrl = devm_pinctrl_get(dev); diff --git a/drivers/media/platform/rockchip/cif/capture.c b/drivers/media/platform/rockchip/cif/capture.c index 442ee5a86df5..61e69d22d7c6 100644 --- a/drivers/media/platform/rockchip/cif/capture.c +++ b/drivers/media/platform/rockchip/cif/capture.c @@ -4515,6 +4515,7 @@ void rkcif_free_rx_buf(struct rkcif_stream *stream, int buf_num) phys_addr_t resmem_free_start; phys_addr_t resmem_free_end; u32 share_head_size = 0; + u32 rtt_min_size = 0; if (!priv) return; @@ -4523,7 +4524,7 @@ void rkcif_free_rx_buf(struct rkcif_stream *stream, int buf_num) if (!sd) return; - if (dev->is_rtt_suspend && dev->is_thunderboot) { + if ((dev->is_rtt_suspend || dev->is_aov_reserved) && dev->is_thunderboot) { stream->curr_buf_toisp = NULL; stream->next_buf_toisp = NULL; INIT_LIST_HEAD(&stream->rx_buf_head); @@ -4542,7 +4543,14 @@ void rkcif_free_rx_buf(struct rkcif_stream *stream, int buf_num) v4l2_info(&stream->cifdev->v4l2_dev, "share mem head error, rtt head size %d, arm head size %d\n", dev->share_mem_size, share_head_size); - resmem_free_start = dev->resmem_pa + share_head_size + dev->nr_buf_size; + if (share_head_size + dev->nr_buf_size > stream->pixm.plane_fmt[0].sizeimage) + rtt_min_size = share_head_size + dev->nr_buf_size; + else + rtt_min_size = stream->pixm.plane_fmt[0].sizeimage; + if (dev->is_rtt_suspend) + resmem_free_start = dev->resmem_pa + rtt_min_size; + else + resmem_free_start = dev->resmem_pa + stream->pixm.plane_fmt[0].sizeimage; resmem_free_end = dev->resmem_pa + dev->resmem_size; v4l2_info(&stream->cifdev->v4l2_dev, "free reserved mem start 0x%x, end 0x%x, share_head_size 0x%x, nr_buf_size 0x%x\n", @@ -4550,6 +4558,10 @@ void rkcif_free_rx_buf(struct rkcif_stream *stream, int buf_num) free_reserved_area(phys_to_virt(resmem_free_start), phys_to_virt(resmem_free_end), -1, "rkisp_thunderboot"); + if (dev->is_rtt_suspend) + dev->resmem_size = rtt_min_size; + else + dev->resmem_size = stream->pixm.plane_fmt[0].sizeimage; } atomic_set(&stream->buf_cnt, 0); stream->total_buf_num = 0; @@ -4638,7 +4650,7 @@ int rkcif_init_rx_buf(struct rkcif_stream *stream, int buf_num) dummy->size = pixm->plane_fmt[0].sizeimage; dummy->is_need_vaddr = true; dummy->is_need_dbuf = true; - if (dev->is_thunderboot) { + if (dev->is_thunderboot || dev->is_rtt_suspend || dev->is_aov_reserved) { if (i == 0) rkcif_get_resmem_head(dev); buf->buf_idx = i; @@ -7222,8 +7234,6 @@ static bool rkcif_check_can_be_online(struct rkcif_device *cif_dev) static int rkcif_do_reset_work(struct rkcif_device *cif_dev, enum rkmodule_reset_src reset_src); -static bool rkcif_check_single_dev_stream_on(struct rkcif_hw *hw); - static long rkcif_ioctl_default(struct file *file, void *fh, bool valid_prio, unsigned int cmd, void *arg) { @@ -10394,7 +10404,7 @@ static bool rkcif_check_buffer_prepare(struct rkcif_stream *stream) return is_update; } -static bool rkcif_check_single_dev_stream_on(struct rkcif_hw *hw) +bool rkcif_check_single_dev_stream_on(struct rkcif_hw *hw) { struct rkcif_device *cif_dev = NULL; struct rkcif_stream *stream = NULL; diff --git a/drivers/media/platform/rockchip/cif/dev.c b/drivers/media/platform/rockchip/cif/dev.c index aa61c6abb9c6..b4d5c60b620e 100644 --- a/drivers/media/platform/rockchip/cif/dev.c +++ b/drivers/media/platform/rockchip/cif/dev.c @@ -2128,6 +2128,7 @@ static int rkcif_get_reserved_mem(struct rkcif_device *cif_dev) cif_dev->is_thunderboot = false; cif_dev->is_rtt_suspend = false; + cif_dev->is_aov_reserved = false; /* Get reserved memory region from Device-tree */ np = of_parse_phandle(dev->of_node, "memory-region-thunderboot", 0); if (!np) { @@ -2149,6 +2150,8 @@ static int rkcif_get_reserved_mem(struct rkcif_device *cif_dev) if (device_property_read_bool(dev, "rtt-suspend")) cif_dev->is_rtt_suspend = true; + if (device_property_read_bool(dev, "aov-reserved")) + cif_dev->is_aov_reserved = true; if (IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP)) cif_dev->is_thunderboot = true; dev_info(dev, "Allocated reserved memory, paddr: 0x%x, size 0x%x\n", diff --git a/drivers/media/platform/rockchip/cif/dev.h b/drivers/media/platform/rockchip/cif/dev.h index 31316c003a16..912e41abb48a 100644 --- a/drivers/media/platform/rockchip/cif/dev.h +++ b/drivers/media/platform/rockchip/cif/dev.h @@ -907,6 +907,7 @@ struct rkcif_device { bool is_rdbk_to_online; bool is_support_tools; bool is_rtt_suspend; + bool is_aov_reserved; bool sensor_state_change; bool is_toisp_reset; int rdbk_debug; @@ -1032,4 +1033,6 @@ static inline u64 rkcif_time_get_ns(struct rkcif_device *dev) return ktime_get_ns(); } +bool rkcif_check_single_dev_stream_on(struct rkcif_hw *hw); + #endif diff --git a/drivers/media/platform/rockchip/cif/subdev-itf.c b/drivers/media/platform/rockchip/cif/subdev-itf.c index 2129abecd246..e6d403497e56 100644 --- a/drivers/media/platform/rockchip/cif/subdev-itf.c +++ b/drivers/media/platform/rockchip/cif/subdev-itf.c @@ -823,6 +823,7 @@ static int sditf_s_rx_buffer(struct v4l2_subdev *sd, u32 diff_time = 1000000; u32 early_time = 0; bool is_free = false; + bool is_single_dev = false; if (!buf) { v4l2_err(&cif_dev->v4l2_dev, "buf is NULL\n"); @@ -863,9 +864,12 @@ static int sditf_s_rx_buffer(struct v4l2_subdev *sd, stream->last_rx_buf_idx = dbufs->sequence + 1; atomic_inc(&stream->buf_cnt); + is_single_dev = rkcif_check_single_dev_stream_on(cif_dev->hw_dev); if (!list_empty(&stream->rx_buf_head) && cif_dev->is_thunderboot && - (!cif_dev->is_rtt_suspend) && + ((!cif_dev->is_rtt_suspend && + !cif_dev->is_aov_reserved) || + !is_single_dev) && (dbufs->type == BUF_SHORT || (dbufs->type != BUF_SHORT && (!dbufs->is_switch)))) { spin_lock_irqsave(&cif_dev->buffree_lock, buffree_flags); @@ -894,7 +898,9 @@ static int sditf_s_rx_buffer(struct v4l2_subdev *sd, offset = rx_buf->dummy.size - stream->pixm.plane_fmt[0].bytesperline * 3; memset(rx_buf->dummy.vaddr + offset, 0x00, stream->pixm.plane_fmt[0].bytesperline * 3); - if (cif_dev->is_thunderboot) + if (cif_dev->is_thunderboot || + cif_dev->is_rtt_suspend || + cif_dev->is_aov_reserved) dma_sync_single_for_device(cif_dev->dev, rx_buf->dummy.dma_addr + rx_buf->dummy.size - stream->pixm.plane_fmt[0].bytesperline * 3, diff --git a/drivers/mfd/rkx110_x120/pattern_gen.c b/drivers/mfd/rkx110_x120/pattern_gen.c index 8ad25745280a..32762f16c035 100644 --- a/drivers/mfd/rkx110_x120/pattern_gen.c +++ b/drivers/mfd/rkx110_x120/pattern_gen.c @@ -9,6 +9,7 @@ #include "rkx110_x120.h" #include "rkx110_x120_display.h" +#include "rkx120_dsi_tx.h" #include "hal/cru_api.h" #define PATTERN_GEN_PATTERN_CTRL 0x0000 @@ -114,7 +115,7 @@ static void pattern_start_stream(struct pattern_gen *pattern_gen, bool is_patter return; if (pattern_gen->chip != &serdes->chip[DEVICE_LOCAL]) - return; + goto out; if (!strcmp(pattern_gen->name, "lvds0")) { hwclk_reset_deassert(serdes->chip[DEVICE_LOCAL].hwclk, @@ -170,6 +171,12 @@ static void pattern_start_stream(struct pattern_gen *pattern_gen, bool is_patter } rk_serdes_display_video_start(serdes, pattern_gen->route, true); + +out: + if (pattern_gen->route->remote0_port0 == RK_SERDES_DSI_TX0) + rkx120_dsi_tx_reset(serdes, DEVICE_REMOTE0); + if (pattern_gen->route->remote1_port0 == RK_SERDES_DSI_TX0) + rkx120_dsi_tx_reset(serdes, DEVICE_REMOTE1); } static void pattern_switch_clk_to_pattern(struct pattern_gen *pattern_gen, struct videomode *vm) diff --git a/drivers/mfd/rkx110_x120/rkx110_x120.h b/drivers/mfd/rkx110_x120/rkx110_x120.h index 319a3286d895..ca875c91eccb 100644 --- a/drivers/mfd/rkx110_x120/rkx110_x120.h +++ b/drivers/mfd/rkx110_x120/rkx110_x120.h @@ -363,6 +363,8 @@ int rkx120_display_linkrx_enable(struct rk_serdes *serdes, int rkx120_rgb_tx_enable(struct rk_serdes *serdes, struct rk_serdes_route *route, u8 remote_id); int rkx120_lvds_tx_enable(struct rk_serdes *serdes, struct rk_serdes_route *route, u8 remote_id, u8 phy_id); +int rkx120_lvds_tx_disable(struct rk_serdes *serdes, struct rk_serdes_route *route, u8 remote_id, + u8 phy_id); void rkx120_linkrx_gpi_gpo_mux_cfg(struct rk_serdes *serdes, u32 mux, u8 remote_id); void rkx110_linktx_gpi_gpo_mux_cfg(struct rk_serdes *serdes, u32 mux, u8 remote_id); int rkx110_rgb_rx_enable(struct rk_serdes *serdes, struct rk_serdes_route *route); diff --git a/drivers/mfd/rkx110_x120/rkx110_x120_display.c b/drivers/mfd/rkx110_x120/rkx110_x120_display.c index 319edd1f38fc..dff07ed21230 100644 --- a/drivers/mfd/rkx110_x120/rkx110_x120_display.c +++ b/drivers/mfd/rkx110_x120/rkx110_x120_display.c @@ -185,11 +185,65 @@ int rk_serdes_display_route_enable(struct rk_serdes *serdes, struct rk_serdes_ro int rk_serdes_display_route_disable(struct rk_serdes *serdes, struct rk_serdes_route *route) { - if (route->remote0_port0 & RK_SERDES_DSI_TX0) - rkx120_dsi_tx_disable(serdes, route, DEVICE_REMOTE0); + if (route->remote0_port0) { + switch (route->remote0_port0) { + case RK_SERDES_RGB_TX: + break; + case RK_SERDES_LVDS_TX0: + rkx120_lvds_tx_disable(serdes, route, DEVICE_REMOTE0, 0); + break; + case RK_SERDES_LVDS_TX1: + rkx120_lvds_tx_disable(serdes, route, DEVICE_REMOTE0, 1); + break; + case RK_SERDES_DUAL_LVDS_TX: + rkx120_lvds_tx_disable(serdes, route, DEVICE_REMOTE0, 0); + rkx120_lvds_tx_disable(serdes, route, DEVICE_REMOTE0, 1); + break; + case RK_SERDES_DSI_TX0: + rkx120_dsi_tx_disable(serdes, route, DEVICE_REMOTE0); + break; + default: + dev_err(serdes->dev, "undefined remote0_port0\n"); + break; + } + } - if (route->remote1_port0 & RK_SERDES_DSI_TX0) - rkx120_dsi_tx_disable(serdes, route, DEVICE_REMOTE1); + if (route->remote1_port0) { + switch (route->remote1_port0) { + case RK_SERDES_RGB_TX: + break; + case RK_SERDES_LVDS_TX0: + rkx120_lvds_tx_disable(serdes, route, DEVICE_REMOTE1, 0); + break; + case RK_SERDES_LVDS_TX1: + rkx120_lvds_tx_disable(serdes, route, DEVICE_REMOTE1, 1); + break; + case RK_SERDES_DUAL_LVDS_TX: + rkx120_lvds_tx_disable(serdes, route, DEVICE_REMOTE1, 0); + rkx120_lvds_tx_disable(serdes, route, DEVICE_REMOTE1, 1); + break; + case RK_SERDES_DSI_TX0: + rkx120_dsi_tx_disable(serdes, route, DEVICE_REMOTE1); + break; + default: + dev_err(serdes->dev, "undefined remote1_port0\n"); + break; + } + } + + if (route->remote0_port1) { + switch (route->remote0_port1) { + case RK_SERDES_LVDS_TX0: + rkx120_lvds_tx_disable(serdes, route, DEVICE_REMOTE0, 0); + break; + case RK_SERDES_LVDS_TX1: + rkx120_lvds_tx_disable(serdes, route, DEVICE_REMOTE0, 1); + break; + default: + dev_err(serdes->dev, "undefined remote0_port1\n"); + break; + } + } if (serdes->version == SERDES_V1) { rk_serdes_display_video_start(serdes, route, false); diff --git a/drivers/mfd/rkx110_x120/rkx120.c b/drivers/mfd/rkx110_x120/rkx120.c index 2f38af1fe0db..eb7cfaff00a1 100644 --- a/drivers/mfd/rkx110_x120/rkx120.c +++ b/drivers/mfd/rkx110_x120/rkx120.c @@ -327,3 +327,14 @@ int rkx120_lvds_tx_enable(struct rk_serdes *serdes, struct rk_serdes_route *rout return 0; } + +int rkx120_lvds_tx_disable(struct rk_serdes *serdes, struct rk_serdes_route *route, u8 remote_id, + u8 phy_id) +{ + struct rk_serdes_panel *sd_panel = container_of(route, struct rk_serdes_panel, route); + struct rkx120_combtxphy *combtxphy = &sd_panel->combtxphy; + + rkx120_combtxphy_power_off(serdes, combtxphy, remote_id, phy_id); + + return 0; +} diff --git a/drivers/mfd/rkx110_x120/rkx120_combtxphy.c b/drivers/mfd/rkx110_x120/rkx120_combtxphy.c index 6e516c7826b3..7537c66bdc4e 100644 --- a/drivers/mfd/rkx110_x120/rkx120_combtxphy.c +++ b/drivers/mfd/rkx110_x120/rkx120_combtxphy.c @@ -307,6 +307,19 @@ static void rkx120_combtxphy_lvds_power_on(struct rk_serdes *des, des->i2c_write_reg(client, grf_base + GRF_MIPITX_CON13, TX_IDLE(0)); } +static void rkx120_combtxphy_lvds_power_off(struct rk_serdes *des, + struct rkx120_combtxphy *combtxphy, + u8 dev_id, u8 phy_id) +{ + struct i2c_client *client = des->chip[dev_id].client; + u32 grf_base = (phy_id == 0) ? + RKX120_GRF_MIPI0_BASE : RKX120_GRF_MIPI1_BASE; + + des->i2c_write_reg(client, grf_base + GRF_MIPITX_CON14, TX_PD(0)); + des->i2c_write_reg(client, grf_base + GRF_MIPITX_CON0, PHYSHUTDWN(0)); + des->i2c_write_reg(client, grf_base + GRF_MIPITX_CON1, PWON_PLL(0)); +} + void rkx120_combtxphy_power_on(struct rk_serdes *des, struct rkx120_combtxphy *combtxphy, u8 dev_id, u8 phy_id) { @@ -330,6 +343,7 @@ void rkx120_combtxphy_power_off(struct rk_serdes *des, struct rkx120_combtxphy * rkx120_combtxphy_dsi_power_off(des, dev_id); break; case COMBTX_PHY_MODE_VIDEO_LVDS: + rkx120_combtxphy_lvds_power_off(des, combtxphy, dev_id, phy_id); break; case COMBTX_PHY_MODE_GPIO: break; diff --git a/drivers/mfd/rkx110_x120/rkx120_dsi_tx.c b/drivers/mfd/rkx110_x120/rkx120_dsi_tx.c index 4e262c4ea1d9..86c5e4dc81d6 100644 --- a/drivers/mfd/rkx110_x120/rkx120_dsi_tx.c +++ b/drivers/mfd/rkx110_x120/rkx120_dsi_tx.c @@ -1181,3 +1181,9 @@ void rkx120_dsi_tx_disable(struct rk_serdes *des, struct rk_serdes_route *route, dsi_write(des, remote_id, DSI_MODE_CFG, CMD_VIDEO_MODE(COMMAND_MODE)); dsi_write(des, remote_id, DSI_PWR_UP, POWER_UP); } + +void rkx120_dsi_tx_reset(struct rk_serdes *des, u8 remote_id) +{ + dsi_write(des, remote_id, DSI_PWR_UP, RESET); + dsi_write(des, remote_id, DSI_PWR_UP, POWER_UP); +} diff --git a/drivers/mfd/rkx110_x120/rkx120_dsi_tx.h b/drivers/mfd/rkx110_x120/rkx120_dsi_tx.h index 1703766c3608..b426fc583f22 100644 --- a/drivers/mfd/rkx110_x120/rkx120_dsi_tx.h +++ b/drivers/mfd/rkx110_x120/rkx120_dsi_tx.h @@ -20,4 +20,5 @@ void rkx120_dsi_tx_post_disable(struct rk_serdes *serdes, struct rk_serdes_route *route, u8 remote_id); void rkx120_dsi_tx_disable(struct rk_serdes *serdes, struct rk_serdes_route *route, u8 remote_id); +void rkx120_dsi_tx_reset(struct rk_serdes *des, u8 remote_id); #endif diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx-hdmi.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx-hdmi.c index b414bf8747d7..0ff63760be46 100644 --- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx-hdmi.c +++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx-hdmi.c @@ -892,7 +892,7 @@ static inline void hdptx_grf_write(struct rockchip_hdptx_phy *hdptx, u32 reg, u3 regmap_write(hdptx->grf, reg, val); } -static inline u8 hdptx_grf_read(struct rockchip_hdptx_phy *hdptx, u32 reg) +static inline u32 hdptx_grf_read(struct rockchip_hdptx_phy *hdptx, u32 reg) { u32 val; @@ -2045,12 +2045,48 @@ static void rockchip_hdptx_phy_runtime_disable(void *data) pm_runtime_disable(hdptx->dev); } +#define PLL_REF_CLK 24000000ULL + static unsigned long hdptx_phy_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { struct rockchip_hdptx_phy *hdptx = to_rockchip_hdptx_phy(hw); + u8 mdiv, sdiv, sdm_num, sdm_deno, sdc_n, sdc_num, sdc_deno; + u64 fout, sdm; + u32 val; + bool sdm_en, sdm_num_sign; - return hdptx->rate; + if (hdptx->rate) + return hdptx->rate; + + val = hdptx_grf_read(hdptx, GRF_HDPTX_CON0); + if (!(val & HDPTX_I_PLL_EN)) + return 0; + + mdiv = hdptx_read(hdptx, CMN_REG0051); + sdm_en = hdptx_read(hdptx, CMN_REG005E) & ROPLL_SDM_EN_MASK; + sdm_num_sign = hdptx_read(hdptx, CMN_REG0064) & ROPLL_SDM_NUM_SIGN_RBR_MASK; + sdm_num = hdptx_read(hdptx, CMN_REG0065); + sdm_deno = hdptx_read(hdptx, CMN_REG0060); + sdc_n = (hdptx_read(hdptx, CMN_REG0069) & ROPLL_SDC_N_RBR_MASK) + 3; + sdc_num = hdptx_read(hdptx, CMN_REG006C); + sdc_deno = hdptx_read(hdptx, CMN_REG0070); + sdiv = ((hdptx_read(hdptx, CMN_REG0086) & PLL_PCG_POSTDIV_SEL_MASK) >> 4) + 1; + + fout = PLL_REF_CLK * mdiv; + if (sdm_en) { + sdm = div_u64(PLL_REF_CLK * sdc_deno * mdiv * sdm_num, + 16 * sdm_deno * (sdc_deno * sdc_n - sdc_num)); + + if (sdm_num_sign) + fout = fout - sdm; + else + fout = fout + sdm; + } + + fout = div_u64(fout * 2, sdiv * 10); + + return fout; } static long hdptx_phy_clk_round_rate(struct clk_hw *hw, unsigned long rate, diff --git a/include/drm/bridge/analogix_dp.h b/include/drm/bridge/analogix_dp.h index 09f0dfeff6e8..46e29e4c2096 100644 --- a/include/drm/bridge/analogix_dp.h +++ b/include/drm/bridge/analogix_dp.h @@ -43,6 +43,7 @@ struct analogix_dp_plat_data { bool ssc; bool split_mode; + bool dual_channel_mode; /* split with other display interface */ bool dual_connector_split;