diff --git a/arch/arm64/boot/dts/rockchip/rk3576-evb1-v10-rk628-hdmi2csi.dts b/arch/arm64/boot/dts/rockchip/rk3576-evb1-v10-rk628-hdmi2csi.dts index b80e0e95be36..d70ebb39783f 100644 --- a/arch/arm64/boot/dts/rockchip/rk3576-evb1-v10-rk628-hdmi2csi.dts +++ b/arch/arm64/boot/dts/rockchip/rk3576-evb1-v10-rk628-hdmi2csi.dts @@ -90,11 +90,12 @@ pinctrl-names = "default"; pinctrl-0 = <&rk628_pin>; interrupt-parent = <&gpio3>; - interrupts = ; + interrupts = ; enable-gpios = <&gpio3 RK_PD0 GPIO_ACTIVE_HIGH>; reset-gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>; plugin-det-gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_LOW>; continues-clk = <1>; + cec-enable; rockchip,camera-module-index = <0>; rockchip,camera-module-facing = "back"; diff --git a/arch/arm64/boot/dts/rockchip/rk3576-evb2-rk628-hdmi2csi.dtsi b/arch/arm64/boot/dts/rockchip/rk3576-evb2-rk628-hdmi2csi.dtsi index 9964eb31f7c9..80cc748d91b0 100644 --- a/arch/arm64/boot/dts/rockchip/rk3576-evb2-rk628-hdmi2csi.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3576-evb2-rk628-hdmi2csi.dtsi @@ -82,7 +82,7 @@ pinctrl-names = "default"; pinctrl-0 = <&rk628_hdmiin_pin>; interrupt-parent = <&gpio3>; - interrupts = ; + interrupts = ; reset-gpios = <&gpio3 RK_PD2 GPIO_ACTIVE_LOW>; plugin-det-gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_LOW>; continues-clk = <1>; diff --git a/arch/arm64/boot/dts/rockchip/rk3588-evb1-lp4-v10-rk628-hdmi2csi.dts b/arch/arm64/boot/dts/rockchip/rk3588-evb1-lp4-v10-rk628-hdmi2csi.dts index eb1b5cfd95a4..8aa1a74159ff 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-evb1-lp4-v10-rk628-hdmi2csi.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588-evb1-lp4-v10-rk628-hdmi2csi.dts @@ -108,7 +108,7 @@ pinctrl-names = "default"; pinctrl-0 = <&rk628_pin_1>; interrupt-parent = <&gpio1>; - interrupts = ; + interrupts = ; enable-gpios = <&gpio1 RK_PB3 GPIO_ACTIVE_HIGH>; reset-gpios = <&gpio1 RK_PB2 GPIO_ACTIVE_HIGH>; plugin-det-gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_LOW>; @@ -148,7 +148,7 @@ pinctrl-names = "default"; pinctrl-0 = <&rk628_pin>; interrupt-parent = <&gpio2>; - interrupts = ; + interrupts = ; enable-gpios = <&gpio1 RK_PA0 GPIO_ACTIVE_HIGH>; reset-gpios = <&gpio4 RK_PC6 GPIO_ACTIVE_HIGH>; plugin-det-gpios = <&gpio1 RK_PA1 GPIO_ACTIVE_LOW>; diff --git a/arch/arm64/boot/dts/rockchip/rk3588-evb7-v11-rk628-hdmi2csi.dts b/arch/arm64/boot/dts/rockchip/rk3588-evb7-v11-rk628-hdmi2csi.dts index 78062aa3bb42..851561f3121d 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-evb7-v11-rk628-hdmi2csi.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588-evb7-v11-rk628-hdmi2csi.dts @@ -98,7 +98,7 @@ pinctrl-names = "default"; pinctrl-0 = <&rk628_pin>; interrupt-parent = <&gpio1>; - interrupts = ; + interrupts = ; enable-gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_HIGH>; reset-gpios = <&gpio1 RK_PB1 GPIO_ACTIVE_HIGH>; plugin-det-gpios = <&gpio2 RK_PB6 GPIO_ACTIVE_LOW>; diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c index 6b52af19e886..223f77d167e1 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c @@ -1792,6 +1792,14 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi) return 0; } +static bool is_hdmi2_mode(const struct drm_display_mode *mode) +{ + if (mode->clock > 340000 && mode->clock <= 600000) + return true; + + return false; +} + static enum drm_mode_status dw_hdmi_rockchip_mode_valid(struct dw_hdmi *dw_hdmi, void *data, const struct drm_display_info *info, @@ -1821,6 +1829,28 @@ dw_hdmi_rockchip_mode_valid(struct dw_hdmi *dw_hdmi, void *data, hdmi = to_rockchip_hdmi(encoder); + if (!hdmi->skip_check_420_mode) { + /* edid isn't support yuv420 and max_tmds_clock is less than mode pixel clk */ + if (mode->clock < 600000 && connector->display_info.max_tmds_clock < mode->clock && + (!drm_mode_is_420(&connector->display_info, mode) || + !connector->ycbcr_420_allowed)) + return MODE_BAD; + + /* edid isn't support yuv420 and hdmitx only support hdmi1.4 clk */ + if (hdmi->max_tmdsclk <= 340000 && is_hdmi2_mode(mode) && + !drm_mode_is_420(&connector->display_info, mode)) + return MODE_BAD; + + /* + * hdmi cts hf1-31 required filtering yuv420 mode that frequency + * exceeds the max_tmds_clock of edid. + */ + if (drm_mode_is_420(&connector->display_info, mode) && + connector->display_info.max_tmds_clock < (mode->clock / 2) && + is_hdmi2_mode(mode)) + return MODE_BAD; + }; + if (hdmi->is_hdmi_qp) { if (!hdmi->enable_gpio && mode->clock > 600000) return MODE_BAD; @@ -1836,23 +1866,6 @@ dw_hdmi_rockchip_mode_valid(struct dw_hdmi *dw_hdmi, void *data, if (mode->clock > INT_MAX / 1000) return MODE_BAD; - /* - * If sink max TMDS clock < 340MHz, we should check the mode pixel - * clock > 340MHz is YCbCr420 or not and whether the platform supports - * YCbCr420. - */ - if (!hdmi->skip_check_420_mode) { - if (mode->clock > 340000 && - connector->display_info.max_tmds_clock < 340000 && - (!drm_mode_is_420(&connector->display_info, mode) || - !connector->ycbcr_420_allowed)) - return MODE_BAD; - - if (hdmi->max_tmdsclk <= 340000 && mode->clock > 340000 && - !drm_mode_is_420(&connector->display_info, mode)) - return MODE_BAD; - }; - if (hdmi->phy) { if (hdmi->is_hdmi_qp) phy_set_bus_width(hdmi->phy, mode->clock * 10); diff --git a/drivers/media/i2c/rk628/rk628.h b/drivers/media/i2c/rk628/rk628.h index 7a5146b16d87..e331e26f0f74 100644 --- a/drivers/media/i2c/rk628/rk628.h +++ b/drivers/media/i2c/rk628/rk628.h @@ -228,6 +228,9 @@ #define GRF_SOC_VERSION 0x0200 #define GRF_MAX_REGISTER GRF_SOC_VERSION +#define RK628_DEFAULT_WIDTH 64 +#define RK628_DEFAULT_HEIGHT 64 + enum { COMBTXPHY_MODULEA_EN = BIT(0), COMBTXPHY_MODULEB_EN = BIT(1), diff --git a/drivers/media/i2c/rk628/rk628_bt1120_v4l2.c b/drivers/media/i2c/rk628/rk628_bt1120_v4l2.c index 17714a133ab1..5072cc41288a 100644 --- a/drivers/media/i2c/rk628/rk628_bt1120_v4l2.c +++ b/drivers/media/i2c/rk628/rk628_bt1120_v4l2.c @@ -938,10 +938,6 @@ static void rk628_bt1120_enable_interrupts(struct v4l2_subdev *sd, bool en) rk628_i2c_write(bt1120->rk628, HDMI_RX_MD_IEN_CLR, md_mask); rk628_i2c_write(bt1120->rk628, HDMI_RX_PDEC_IEN_CLR, pdec_mask); rk628_i2c_write(bt1120->rk628, HDMI_RX_AUD_FIFO_IEN_CLR, 0x1f); - if (bt1120->cec && bt1120->cec->adap) { - rk628_i2c_write(bt1120->rk628, HDMI_RX_AUD_CEC_IEN_SET, 0); - rk628_i2c_write(bt1120->rk628, HDMI_RX_AUD_CEC_IEN_CLR, ~0); - } bt1120->vid_ints_en = false; } usleep_range(5000, 5000); diff --git a/drivers/media/i2c/rk628/rk628_csi_v4l2.c b/drivers/media/i2c/rk628/rk628_csi_v4l2.c index c9bfec4738e0..5a81de8e14c6 100644 --- a/drivers/media/i2c/rk628/rk628_csi_v4l2.c +++ b/drivers/media/i2c/rk628/rk628_csi_v4l2.c @@ -876,6 +876,11 @@ static void enable_stream(struct v4l2_subdev *sd, bool en) v4l2_dbg(1, debug, sd, "%s: %sable\n", __func__, en ? "en" : "dis"); if (en) { + if (!tx_5v_power_present(sd) || csi->nosignal) { + v4l2_err(sd, "%s: hdmi no signal or unplug!\n", __func__); + return; + } + if (rk628_hdmirx_scdc_ced_err(csi->rk628)) { rk628_hdmirx_plugout(sd); schedule_delayed_work(&csi->delayed_work_enable_hotplug, @@ -1538,10 +1543,6 @@ static void rk628_csi_enable_interrupts(struct v4l2_subdev *sd, bool en) rk628_i2c_write(csi->rk628, HDMI_RX_MD_IEN_CLR, md_mask); rk628_i2c_write(csi->rk628, HDMI_RX_PDEC_IEN_CLR, pdec_mask); rk628_i2c_write(csi->rk628, HDMI_RX_AUD_FIFO_IEN_CLR, 0x1f); - if (csi->cec && csi->cec->adap) { - rk628_i2c_write(csi->rk628, HDMI_RX_AUD_CEC_IEN_SET, 0); - rk628_i2c_write(csi->rk628, HDMI_RX_AUD_CEC_IEN_CLR, ~0); - } csi->vid_ints_en = false; } usleep_range(5000, 5000); @@ -2007,13 +2008,20 @@ static int rk628_csi_get_fmt(struct v4l2_subdev *sd, { struct rk628_csi *csi = to_csi(sd); - mutex_lock(&csi->confctl_mutex); + /* The application don't wants this to be blocked, so use mutex_trylock() */ + if (!mutex_trylock(&csi->confctl_mutex)) { + format->format.code = csi->mbus_fmt_code; + format->format.width = RK628_DEFAULT_WIDTH; + format->format.height = RK628_DEFAULT_HEIGHT; + format->format.field = V4L2_FIELD_NONE; + return 0; + } + format->format.code = csi->mbus_fmt_code; - format->format.width = csi->timings.bt.width; + format->format.width = ALIGN_DOWN(csi->timings.bt.width, 8); format->format.height = csi->timings.bt.height; format->format.field = csi->timings.bt.interlaced ? V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE; - mutex_unlock(&csi->confctl_mutex); if (csi->plat_data->tx_mode == CSI_MODE) { if (csi->timings.bt.pixelclock > 150000000 || csi->csi_lanes_in_use <= 2) { @@ -2057,6 +2065,7 @@ static int rk628_csi_get_fmt(struct v4l2_subdev *sd, __v4l2_ctrl_s_ctrl_int64(csi->pixel_rate, RK628_CSI_PIXEL_RATE_HIGH); } + mutex_unlock(&csi->confctl_mutex); v4l2_dbg(1, debug, sd, "%s: fmt code:%d, w:%d, h:%d, field code:%d\n", __func__, format->format.code, format->format.width, format->format.height, format->format.field); diff --git a/drivers/spi/spidev-rkmst.c b/drivers/spi/spidev-rkmst.c index 118aa3c4b559..c52cb194f2cc 100644 --- a/drivers/spi/spidev-rkmst.c +++ b/drivers/spi/spidev-rkmst.c @@ -617,6 +617,12 @@ MODULE_DEVICE_TABLE(of, spidev_rkmst_dt_match); #endif /* CONFIG_OF */ +static const struct spi_device_id spidev_rkmst_spi_ids[] = { + { .name = "spi-obj-master" }, + {}, +}; +MODULE_DEVICE_TABLE(spi, spidev_rkmst_spi_ids); + static struct spi_driver spidev_rkmst_driver = { .driver = { .name = "spidev_rkmst", @@ -625,6 +631,7 @@ static struct spi_driver spidev_rkmst_driver = { }, .probe = spidev_rkmst_probe, .remove = spidev_rkmst_remove, + .id_table = spidev_rkmst_spi_ids, }; module_spi_driver(spidev_rkmst_driver); diff --git a/drivers/spi/spidev-rkslv.c b/drivers/spi/spidev-rkslv.c index e0971ac52a1e..79df8ba87ef0 100644 --- a/drivers/spi/spidev-rkslv.c +++ b/drivers/spi/spidev-rkslv.c @@ -395,7 +395,13 @@ MODULE_DEVICE_TABLE(of, spidev_rkslv_dt_match); #endif /* CONFIG_OF */ -static struct spi_driver spidev_rkmst_driver = { +static const struct spi_device_id spidev_rkslv_spi_ids[] = { + { .name = "spi-obj-slave" }, + {}, +}; +MODULE_DEVICE_TABLE(spi, spidev_rkslv_spi_ids); + +static struct spi_driver spidev_rkslv_driver = { .driver = { .name = "spidev_rkslv", .owner = THIS_MODULE, @@ -403,8 +409,9 @@ static struct spi_driver spidev_rkmst_driver = { }, .probe = spidev_rkslv_probe, .remove = spidev_rkslv_remove, + .id_table = spidev_rkslv_spi_ids, }; -module_spi_driver(spidev_rkmst_driver); +module_spi_driver(spidev_rkslv_driver); MODULE_AUTHOR("Jon Lin "); MODULE_DESCRIPTION("ROCKCHIP SPI Object Slave Driver"); diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index 067ed299aca6..780a027d9402 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c @@ -700,6 +700,7 @@ static const struct spi_device_id spidev_spi_ids[] = { { .name = "m53cpld" }, { .name = "spi-petra" }, { .name = "spi-authenta" }, + { .name = "spidev" }, {}, }; MODULE_DEVICE_TABLE(spi, spidev_spi_ids);