diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile index 084ac29ebfac..db2edb5c7352 100644 --- a/arch/arm64/boot/dts/rockchip/Makefile +++ b/arch/arm64/boot/dts/rockchip/Makefile @@ -275,6 +275,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-lp4-v10.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-lp4-v10-dsi-dsc-MV2100UZ1.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-lp4-v10-edp-8lanes-M280DCA.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-lp4-v10-edp-NV140QUM-N61.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-lp4-v10-hdmi2dp.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-lp4-v10-ipc-6x-linux.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-lp4-v10-linux.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-lp4-v10-linux-amp.dtb diff --git a/arch/arm64/boot/dts/rockchip/rk3576-evb1-v10-android9.dts b/arch/arm64/boot/dts/rockchip/rk3576-evb1-v10-android9.dts index d5a47852a72f..71e95fcbaf41 100644 --- a/arch/arm64/boot/dts/rockchip/rk3576-evb1-v10-android9.dts +++ b/arch/arm64/boot/dts/rockchip/rk3576-evb1-v10-android9.dts @@ -8,6 +8,7 @@ #include "rk3576.dtsi" #include "rk3576-evb1.dtsi" +#include "rk3576-virtual-poweroff.dtsi" #include "rk3576-evb1-cam-dcphy0.dtsi" #include "rk3576-android9.dtsi" diff --git a/arch/arm64/boot/dts/rockchip/rk3576-virtual-poweroff.dtsi b/arch/arm64/boot/dts/rockchip/rk3576-virtual-poweroff.dtsi new file mode 100644 index 000000000000..0c880d9552b9 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3576-virtual-poweroff.dtsi @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2024 Rockchip Electronics Co., Ltd. + * + */ + +&vcca_1v8_s0 { + regulator-state-mem { + regulator-on-in-suspend; + }; +}; + +&rk806 { + pinctrl-1 = <&rk806_dvs1_slp>; +}; + +&rockchip_suspend { + status = "okay"; + rockchip,sleep-debug-en = <1>; + rockchip,virtual-poweroff = <1>; + rockchip,virtual-poweroff-irqs = <132>; + + rockchip,sleep-mode-config = < + (0 + | RKPM_SLP_ARMOFF_LOGOFF + ) + >; + rockchip,wakeup-config = < + (0 + | RKPM_GPIO_WKUP_EN + | RKPM_PWM_WKUP_EN + ) + >; + rockchip,sleep-io-ret-config = < + (0 + | RKPM_VCCIO3_RET_EN + ) + >; + + rockchip,regulator-on-before-mem = <&vdd_npu_s0>; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3588-evb.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-evb.dtsi index c76ade45698f..a76388bb8181 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-evb.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588-evb.dtsi @@ -105,6 +105,24 @@ }; }; + edp0_sound: edp0-sound { + status = "disabled"; + compatible = "rockchip,hdmi"; + rockchip,mclk-fs = <128>; + rockchip,card-name = "rockchip-edp0"; + rockchip,cpu = <&i2s5_8ch>; + rockchip,codec = <&edp0 0>; + }; + + edp1_sound: edp1-sound { + status = "disabled"; + compatible = "rockchip,hdmi"; + rockchip,mclk-fs = <128>; + rockchip,card-name = "rockchip-edp1"; + rockchip,cpu = <&i2s6_8ch>; + rockchip,codec = <&edp1 0>; + }; + hdmi0_sound: hdmi0-sound { status = "disabled"; compatible = "rockchip,hdmi"; diff --git a/arch/arm64/boot/dts/rockchip/rk3588-evb1-lp4-v10-hdmi2dp.dts b/arch/arm64/boot/dts/rockchip/rk3588-evb1-lp4-v10-hdmi2dp.dts new file mode 100644 index 000000000000..d3f4e3a0a1e0 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3588-evb1-lp4-v10-hdmi2dp.dts @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2021 Rockchip Electronics Co., Ltd. + * + */ + +/dts-v1/; + +#include "rk3588-evb1-lp4.dtsi" +#include "rk3588-evb1-imx415.dtsi" +#include "rk3588-android.dtsi" + +/ { + model = "Rockchip RK3588 EVB1 LP4 V10 Board + RK HDMI to DP Ext Board"; + compatible = "rockchip,rk3588-evb1-lp4-v10-hdmi2dp", "rockchip,rk3588"; +}; + +&bt_sco { + status = "okay"; +}; + +&bt_sound { + status = "okay"; +}; + +&edp1 { + pinctrl-names = "default"; + pinctrl-0 = <&hdmim0_tx1_hpd>; + status = "okay"; +}; + +&edp1_in_vp1 { + status = "okay"; +}; + +&edp1_sound { + status = "okay"; +}; + +&hdmi1 { + status = "disabled"; +}; + +&hdmi1_in_vp1 { + status = "disabled"; +}; + +&hdmi1_sound { + status = "disabled"; +}; + +&hdptxphy1 { + status = "okay"; +}; + +&hdptxphy_hdmi1 { + status = "disabled"; +}; + +&i2s2_2ch { + status = "okay"; +}; + +&i2s6_8ch { + status = "okay"; +}; + +&route_edp1 { + status = "okay"; + connect = <&vp1_out_edp1>; +}; + +&route_hdmi1 { + status = "disabled"; +}; + +&vp1 { + assigned-clocks = <&cru DCLK_VOP1_SRC>; + assigned-clock-parents = <&cru PLL_V0PLL>; +}; + +&vp2 { + /delete-property/ assigned-clocks; + /delete-property/ assigned-clock-parents; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3588.dtsi b/arch/arm64/boot/dts/rockchip/rk3588.dtsi index c75f3d6dcf10..357e879cc0b4 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588.dtsi @@ -445,6 +445,7 @@ phy-names = "dp"; power-domains = <&power RK3588_PD_VO1>; rockchip,grf = <&vo1_grf>; + #sound-dai-cells = <1>; status = "disabled"; ports { diff --git a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi index 2cc2481592ec..fee6171e01ab 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi @@ -5176,6 +5176,7 @@ phy-names = "dp"; power-domains = <&power RK3588_PD_VO1>; rockchip,grf = <&vo1_grf>; + #sound-dai-cells = <1>; status = "disabled"; ports { diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c index 032aad4ce48f..8f082dc06058 100644 --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c @@ -419,11 +419,14 @@ static void rockchip_dp_drm_encoder_disable(struct drm_encoder *encoder, struct rockchip_crtc_state *s = to_rockchip_crtc_state(old_crtc->state); int ret; - if (dp->plat_data.split_mode) - s->output_if &= ~(VOP_OUTPUT_IF_eDP1 | VOP_OUTPUT_IF_eDP0); - else - s->output_if &= ~(dp->id ? VOP_OUTPUT_IF_eDP1 : VOP_OUTPUT_IF_eDP0); - s->output_if_left_panel &= ~(dp->id ? VOP_OUTPUT_IF_eDP1 : VOP_OUTPUT_IF_eDP0); + if (old_crtc->state->active_changed) { + if (dp->plat_data.split_mode) + s->output_if &= ~(VOP_OUTPUT_IF_eDP1 | VOP_OUTPUT_IF_eDP0); + else + s->output_if &= ~(dp->id ? VOP_OUTPUT_IF_eDP1 : VOP_OUTPUT_IF_eDP0); + s->output_if_left_panel &= ~(dp->id ? VOP_OUTPUT_IF_eDP1 : VOP_OUTPUT_IF_eDP0); + } + crtc = rockchip_dp_drm_get_new_crtc(encoder, state); /* No crtc means we're doing a full shutdown */ if (!crtc) diff --git a/drivers/gpu/drm/rockchip/dw-dp.c b/drivers/gpu/drm/rockchip/dw-dp.c index 4b9cf4fdd22f..296387d22397 100644 --- a/drivers/gpu/drm/rockchip/dw-dp.c +++ b/drivers/gpu/drm/rockchip/dw-dp.c @@ -46,6 +46,7 @@ #include "rockchip_drm_drv.h" #include "rockchip_drm_vop.h" +#include "rockchip_dp_mst_aux_client.h" #define DPTX_VERSION_NUMBER 0x0000 #define DPTX_VERSION_TYPE 0x0004 @@ -496,6 +497,7 @@ struct dw_dp { struct drm_dp_mst_topology_mgr mst_mgr; struct dw_dp_mst_enc mst_enc[DPTX_MAX_STREAMS]; struct list_head mst_conn_list; + struct rockchip_dp_aux_client *aux_client; struct drm_info_list *debugfs_files; }; @@ -3123,6 +3125,17 @@ static ssize_t dw_dp_aux_transfer(struct drm_dp_aux *aux, return ret; } +static ssize_t dw_dp_sim_aux_transfer(struct drm_dp_aux *aux, + struct drm_dp_aux_msg *msg) +{ + struct dw_dp *dp = container_of(aux, struct dw_dp, aux); + + if (dp->aux_client && dp->aux_client->transfer) + return dp->aux_client->transfer(dp->aux_client, aux, msg); + else + return dw_dp_aux_transfer(aux, msg); +} + static enum drm_mode_status dw_dp_bridge_mode_valid(struct drm_bridge *bridge, const struct drm_display_info *info, @@ -3845,6 +3858,7 @@ static int dw_dp_mst_encoder_atomic_check(struct drm_encoder *encoder, struct dw_dp_mst_conn *mst_conn = container_of(connector, struct dw_dp_mst_conn, connector); struct drm_dp_mst_topology_state *mst_state; + struct drm_dp_mst_atomic_payload *payload; int pbn, slot; mst_state = drm_atomic_get_mst_topology_state(crtc_state->state, &dp->mst_mgr); @@ -3905,6 +3919,14 @@ static int dw_dp_mst_encoder_atomic_check(struct drm_encoder *encoder, drm_dp_mst_update_slots(mst_state, DP_CAP_ANSI_8B10B); + payload = drm_atomic_get_mst_payload_state(mst_state, mst_conn->port); + if (dp->aux_client && !payload->vcpi) { + payload->vcpi = mst_enc->stream_id + 1; + dev_info(dp->dev, "[MST PORT:%p] assigned VCPI #%d\n", + payload->port, payload->vcpi); + mst_state->payload_mask |= BIT(payload->vcpi - 1); + } + return 0; } @@ -5353,6 +5375,17 @@ static const struct drm_encoder_funcs dw_dp_encoder_funcs = { .late_register = dw_dp_encoder_late_register, }; +static void dw_dp_mst_poll_hpd_irq(void *data) +{ + struct dw_dp *dp = data; + + mutex_lock(&dp->irq_lock); + dp->hotplug.long_hpd = false; + mutex_unlock(&dp->irq_lock); + + schedule_work(&dp->hpd_work); +} + static int dw_dp_bind(struct device *dev, struct device *master, void *data) { struct dw_dp *dp = dev_get_drvdata(dev); @@ -5402,6 +5435,12 @@ static int dw_dp_bind(struct device *dev, struct device *master, void *data) goto error_unregister_aux; } + if (dp->aux_client) { + dp->aux_client->register_hpd_irq(dp->aux_client, dw_dp_mst_poll_hpd_irq, dp); + dp->aux_client->register_transfer(dp->aux_client, dw_dp_aux_transfer); + dp->aux.transfer = dw_dp_sim_aux_transfer; + } + pm_runtime_enable(dp->dev); pm_runtime_get_sync(dp->dev); @@ -5684,6 +5723,11 @@ static int dw_dp_probe(struct platform_device *pdev) return ret; } + dp->aux_client = rockchip_dp_get_aux_client(dev->of_node, "rockchip,mst-sim"); + if (IS_ERR(dp->aux_client)) + return dev_err_probe(dev, PTR_ERR(dp->aux_client), + "failed to get dp aux_client\n"); + dp->bridge.of_node = dp->support_mst ? dp->mst_enc[0].port_node : dev->of_node; dp->bridge.funcs = &dw_dp_bridge_funcs; dp->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index d254de5ae4e6..922bdaa03d82 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -1464,9 +1464,6 @@ static void vop_crtc_load_lut(struct drm_crtc *crtc) if (!vop->is_enabled || !vop->lut || !vop->lut_regs) return; - if (WARN_ON(!drm_modeset_is_locked(&crtc->mutex))) - return; - if (!VOP_CTRL_SUPPORT(vop, update_gamma_lut)) { spin_lock(&vop->reg_lock); VOP_CTRL_SET(vop, dsp_lut_en, 0); diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index cfc7d20f0abd..4be03b33e8c1 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -3769,9 +3769,6 @@ static void vop2_crtc_load_lut(struct drm_crtc *crtc) if (!vop2->is_enabled || !vp->lut || !vop2->lut_regs) return; - if (WARN_ON(!drm_modeset_is_locked(&crtc->mutex))) - return; - if (vop2->version == VOP_VERSION_RK3568) { rk3568_crtc_load_lut(crtc); } else { @@ -6959,11 +6956,11 @@ static void vop2_crtc_csu_set_rate(struct drm_crtc *crtc) aclk_rate = clk_get_rate(vop2->aclk); dclk_rate = clk_get_rate(vp->dclk); - if (!dclk_rate) + if (!dclk_rate || !aclk_rate) return; - /* aclk >= 1/2 * dclk */ - csu_div = aclk_rate * 2 / dclk_rate; + /* aclk > 1/2 * dclk */ + csu_div = (aclk_rate - 1) * 2 / dclk_rate; rockchip_csu_set_div(vop2->csu_aclk, csu_div); } diff --git a/drivers/input/remotectl/rockchip_pwm_remotectl.c b/drivers/input/remotectl/rockchip_pwm_remotectl.c index 606c0857831a..83d73a77327f 100644 --- a/drivers/input/remotectl/rockchip_pwm_remotectl.c +++ b/drivers/input/remotectl/rockchip_pwm_remotectl.c @@ -1013,7 +1013,6 @@ static int rk_pwm_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM static int remotectl_suspend(struct device *dev) { int cpu = 0; @@ -1031,6 +1030,7 @@ static int remotectl_suspend(struct device *dev) return 0; } +#ifdef CONFIG_PM static int remotectl_resume(struct device *dev) { struct cpumask cpumask; @@ -1066,6 +1066,11 @@ static const struct dev_pm_ops remotectl_pm_ops = { }; #endif +static void rk_pwm_remotectl_shutdown(struct platform_device *pdev) +{ + remotectl_suspend(&pdev->dev); +} + static struct platform_driver rk_pwm_driver = { .driver = { .name = "remotectl-pwm", @@ -1075,6 +1080,7 @@ static struct platform_driver rk_pwm_driver = { #endif }, .remove = rk_pwm_remove, + .shutdown = rk_pwm_remotectl_shutdown, }; module_platform_driver_probe(rk_pwm_driver, rk_pwm_probe); diff --git a/drivers/media/i2c/maxim/remote/os04a10.c b/drivers/media/i2c/maxim/remote/os04a10.c index 471257f46a58..2a7c63ccf06e 100644 --- a/drivers/media/i2c/maxim/remote/os04a10.c +++ b/drivers/media/i2c/maxim/remote/os04a10.c @@ -107,6 +107,8 @@ #define OS04A10_NAME "os04a10" +#define USED_SYS_DEBUG + #define OS04A10_FLIP_REG 0x3820 #define MIRROR_BIT_MASK BIT(1) #define FLIP_BIT_MASK BIT(2) @@ -3028,7 +3030,7 @@ err_destroy_mutex: #if KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE static int os04a10_remove(struct i2c_client *client) #else -static int os04a10_remove(struct i2c_client *client) +static void os04a10_remove(struct i2c_client *client) #endif { struct v4l2_subdev *sd = i2c_get_clientdata(client); diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c index ef0edbd81896..a396e520fc1c 100644 --- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c +++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c @@ -1202,6 +1202,12 @@ retry_regulator: reset_control_deassert(rk_pcie->rsts); + ret = rk_pcie_clk_init(rk_pcie); + if (ret) { + dev_err(dev, "clock init failed\n"); + goto disable_phy; + } + /* * Misc interrupts was masked by default. However, they will be * unmasked by FW before jumpping into kernel. Mask all misc interrupts, @@ -1213,17 +1219,11 @@ retry_regulator: ret = rk_pcie_request_sys_irq(rk_pcie, pdev); if (ret) { dev_err(dev, "pcie irq init failed\n"); - goto disable_phy; + goto disable_clk; } platform_set_drvdata(pdev, rk_pcie); - ret = rk_pcie_clk_init(rk_pcie); - if (ret) { - dev_err(dev, "clock init failed\n"); - goto disable_phy; - } - dw_pcie_dbi_ro_wr_en(pci); rk_pcie_fast_link_setup(rk_pcie); @@ -1337,10 +1337,11 @@ remove_rst_wq: remove_irq_domain: if (rk_pcie->irq_domain) irq_domain_remove(rk_pcie->irq_domain); +disable_clk: + clk_bulk_disable_unprepare(rk_pcie->clk_cnt, rk_pcie->clks); disable_phy: phy_power_off(rk_pcie->phy); phy_exit(rk_pcie->phy); - clk_bulk_disable_unprepare(rk_pcie->clk_cnt, rk_pcie->clks); disable_vpcie3v3: rk_pcie_disable_power(rk_pcie); release_driver: