diff --git a/Documentation/devicetree/bindings/opp/rockchip-opp.txt b/Documentation/devicetree/bindings/opp/rockchip-opp.txt index 393b481c7d1b..8191133b0bb4 100644 --- a/Documentation/devicetree/bindings/opp/rockchip-opp.txt +++ b/Documentation/devicetree/bindings/opp/rockchip-opp.txt @@ -10,6 +10,10 @@ In 'operating-points-v2' table: - rockchip,opp-shared-dsu: Indicates the dsu also uses the opp table. +- rockchip,opp-shared-cci: Indicates the cci also uses the opp table. + +- rockchip,cpu-freq-percent: The percentage of cpu frequency. + - rockchip,leakage-voltage-sel: The property is an array of 3-tuples items, and each item consists of leakage and voltage selector like . diff --git a/arch/arm64/boot/dts/rockchip/rk3576.dtsi b/arch/arm64/boot/dts/rockchip/rk3576.dtsi index 55baaecd8f3c..f58f06520750 100644 --- a/arch/arm64/boot/dts/rockchip/rk3576.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3576.dtsi @@ -364,6 +364,7 @@ cluster0_opp_table: cluster0-opp-table { compatible = "operating-points-v2"; opp-shared; + rockchip,opp-shared-cci; nvmem-cells = <&cpul_leakage>; nvmem-cell-names = "leakage"; @@ -394,6 +395,8 @@ 675000 3 495000 4 >; + intermediate-threshold-freq = <816000>; + rockchip,reboot-freq = <1416000>; opp-408000000 { opp-hz = /bits/ 64 <408000000>; @@ -449,6 +452,7 @@ opp-microvolt-L4 = <787500 787500 950000>; opp-microvolt-L5 = <775000 775000 950000>; clock-latency-ns = <40000>; + opp-suspend; }; opp-2016000000 { opp-hz = /bits/ 64 <2016000000>; @@ -475,6 +479,7 @@ cluster1_opp_table: cluster1-opp-table { compatible = "operating-points-v2"; opp-shared; + rockchip,cpu-freq-percent = <90>; nvmem-cells = <&cpub_leakage>; nvmem-cell-names = "leakage"; @@ -504,6 +509,8 @@ 675000 3 495000 4 >; + intermediate-threshold-freq = <816000>; + rockchip,reboot-freq = <1608000>; opp-408000000 { opp-hz = /bits/ 64 <408000000>; @@ -559,6 +566,7 @@ opp-microvolt-L4 = <750000 750000 950000>; opp-microvolt-L5 = <737500 737500 950000>; clock-latency-ns = <40000>; + opp-suspend; }; opp-2016000000 { opp-hz = /bits/ 64 <2016000000>; @@ -1891,7 +1899,7 @@ clock-names = "clk_npu", "aclk0", "aclk1", "hclk_root", "aclk_cbuf", "hclk_cbuf"; assigned-clocks = <&cru CLK_RKNN_DSU0>; - assigned-clock-rates = <200000000>; + assigned-clock-rates = <198000000>; resets = <&cru SRST_A_RKNN0>, <&cru SRST_A_RKNN1>, <&cru SRST_A_RKNN_CBUF>, <&cru SRST_H_RKNN_CBUF>; reset-names = "srst_a0", "srst_a1", @@ -1935,6 +1943,7 @@ 675000 3 495000 4 >; + intermediate-threshold-freq = <300000>; rockchip,opp-clocks = <&cru ACLK_RKNN_CBUF>, <&cru HCLK_RKNN_CBUF>, <&cru PCLK_NPUTOP_ROOT>; @@ -2027,7 +2036,7 @@ clocks = <&scmi_clk CLK_GPU>, <&cru CLK_GPU>; clock-names = "clk_mali", "clk_gpu"; assigned-clocks = <&cru CLK_GPU>; - assigned-clock-rates = <200000000>; + assigned-clock-rates = <198000000>; power-domains = <&power RK3576_PD_GPU>; operating-points-v2 = <&gpu_opp_table>; #cooling-cells = <2>; @@ -2065,6 +2074,7 @@ 675000 3 495000 4 >; + intermediate-threshold-freq = <300000>; rockchip,opp-clocks = <&cru CLK_GPU>, <&cru PCLK_GPU_ROOT>; opp-300000000 { @@ -2335,12 +2345,12 @@ interrupt-names = "irq_vepu0"; clocks = <&cru ACLK_VEPU0>, <&cru HCLK_VEPU0>, <&cru CLK_VEPU0_CORE>; clock-names = "aclk_vcodec", "hclk_vcodec", "clk_core"; - rockchip,normal-rates = <400000000>, <0>, <700000000>; + rockchip,normal-rates = <400000000>, <0>, <702000000>; resets = <&cru SRST_A_VEPU0>, <&cru SRST_H_VEPU0>, <&cru SRST_VEPU0_CORE>; reset-names = "video_a", "video_h", "video_core"; assigned-clocks = <&cru ACLK_VEPU0>, <&cru CLK_VEPU0_CORE>; - assigned-clock-rates = <400000000>, <700000000>; + assigned-clock-rates = <400000000>, <702000000>; iommus = <&rkvenc0_mmu>; rockchip,srv = <&mpp_srv>; rockchip,taskqueue-node = <3>; @@ -2372,12 +2382,12 @@ interrupt-names = "irq_vepu1"; clocks = <&cru ACLK_VEPU1>, <&cru HCLK_VEPU1>, <&cru CLK_VEPU1_CORE>; clock-names = "aclk_vcodec", "hclk_vcodec", "clk_core"; - rockchip,normal-rates = <400000000>, <0>, <700000000>; + rockchip,normal-rates = <400000000>, <0>, <702000000>; resets = <&cru SRST_A_VEPU1>, <&cru SRST_H_VEPU1>, <&cru SRST_VEPU1_CORE>; reset-names = "video_a", "video_h", "video_core"; assigned-clocks = <&cru ACLK_VEPU1>, <&cru CLK_VEPU1_CORE>; - assigned-clock-rates = <400000000>, <700000000>; + assigned-clock-rates = <400000000>, <702000000>; iommus = <&rkvenc1_mmu>; rockchip,srv = <&mpp_srv>; rockchip,taskqueue-node = <3>; diff --git a/arch/arm64/configs/rk3588_vehicle.config b/arch/arm64/configs/rk3588_vehicle.config index ed11bde9aadb..fc0865126f09 100644 --- a/arch/arm64/configs/rk3588_vehicle.config +++ b/arch/arm64/configs/rk3588_vehicle.config @@ -37,11 +37,10 @@ CONFIG_HZ_1000=y # CONFIG_IIO_ST_LSM6DSR is not set # CONFIG_INPUT_TABLET is not set # CONFIG_LIGHT_DEVICE is not set -CONFIG_LOG_BUF_SHIFT=18 +CONFIG_LOG_BUF_SHIFT=20 # CONFIG_MALI400 is not set # CONFIG_MALI_MIDGARD is not set # CONFIG_MFD_RK618 is not set -# CONFIG_MFD_RK628 is not set # CONFIG_MFD_RK630_I2C is not set # CONFIG_MFD_RKX110_X120 is not set CONFIG_MFD_SERDES_DISPLAY=y @@ -65,7 +64,6 @@ CONFIG_ROCKCHIP_DRM_DIRECT_SHOW=y # CONFIG_ROCKCHIP_PLL_RK3066 is not set # CONFIG_ROCKCHIP_PLL_RK3399 is not set # CONFIG_ROCKCHIP_SERDES_DRM_PANEL is not set -# CONFIG_ROCKCHIP_VOP is not set CONFIG_SATA_AHCI_PLATFORM=m # CONFIG_SLUB_SYSFS is not set # CONFIG_SND_SOC_AW883XX is not set @@ -83,7 +81,6 @@ CONFIG_SATA_AHCI_PLATFORM=m # CONFIG_TOUCHSCREEN_GSL3673 is not set # CONFIG_TOUCHSCREEN_GSLX680_PAD is not set CONFIG_TOUCHSCREEN_GT1X=m -CONFIG_TOUCHSCREEN_HIMAX_CHIPSET=y CONFIG_TOUCHSCREEN_ILI210X=m # CONFIG_UCS12CM0 is not set # CONFIG_USB_ALI_M5632 is not set @@ -142,19 +139,13 @@ CONFIG_SERDES_DISPLAY_CHIP_ROCKCHIP_RKX121=y CONFIG_SERDES_DISPLAY_CHIP_ROHM=y CONFIG_SERDES_DISPLAY_CHIP_ROHM_BU18RL82=y CONFIG_SERDES_DISPLAY_CHIP_ROHM_BU18TL82=y -CONFIG_TOUCHSCREEN_HIMAX_COMMON=m -CONFIG_TOUCHSCREEN_HIMAX_DEBUG=y -# CONFIG_TOUCHSCREEN_HIMAX_EMBEDDED_FIRMWARE is not set -# CONFIG_TOUCHSCREEN_HIMAX_IC_HX83191 is not set -CONFIG_TOUCHSCREEN_HIMAX_IC_HX83192=m -# CONFIG_TOUCHSCREEN_HIMAX_IC_HX83193 is not set -CONFIG_TOUCHSCREEN_HIMAX_INCELL=y -# CONFIG_TOUCHSCREEN_HIMAX_INSPECT is not set CONFIG_VIDEO_MAXIM_CAM_OV231X=y CONFIG_VIDEO_MAXIM_CAM_OX01F10=y CONFIG_VIDEO_MAXIM_CAM_OX03J10=y CONFIG_VIDEO_MAXIM_CAM_SC320AT=y +# CONFIG_VIDEO_MAXIM_DES_MAXIM2C is not set CONFIG_VIDEO_MAXIM_DES_MAXIM4C=y CONFIG_VIDEO_MAXIM_SER_MAX9295=y CONFIG_VIDEO_MAXIM_SER_MAX96715=y CONFIG_VIDEO_MAXIM_SER_MAX96717=y +# CONFIG_VIDEO_REVERSE_IMAGE is not set diff --git a/drivers/cpufreq/rockchip-cpufreq.c b/drivers/cpufreq/rockchip-cpufreq.c index 236412c78068..8d5eef8c0a1a 100644 --- a/drivers/cpufreq/rockchip-cpufreq.c +++ b/drivers/cpufreq/rockchip-cpufreq.c @@ -43,11 +43,12 @@ struct cluster_info { struct list_head list_head; struct monitor_dev_info *mdev_info; struct rockchip_opp_info opp_info; - struct freq_qos_request dsu_qos_req; + struct freq_qos_request bus_qos_req; cpumask_t cpus; unsigned int idle_threshold_freq; + unsigned int cpu_freq_percent; bool is_idle_disabled; - bool is_opp_shared_dsu; + bool is_opp_shared_cpu_bus; unsigned long rate; unsigned long volt, mem_volt; }; @@ -490,7 +491,11 @@ static int rockchip_cpufreq_cluster_init(int cpu, struct cluster_info *cluster) of_node_put(np); return ret; } - cluster->is_opp_shared_dsu = of_property_read_bool(np, "rockchip,opp-shared-dsu"); + if (of_property_read_bool(np, "rockchip,opp-shared-dsu") || + of_property_read_bool(np, "rockchip,opp-shared-cci")) + cluster->is_opp_shared_cpu_bus = true; + of_property_read_u32(np, "rockchip,cpu-freq-percent", + &cluster->cpu_freq_percent); if (!of_property_read_u32(np, "rockchip,idle-threshold-freq", &freq)) cluster->idle_threshold_freq = freq; of_node_put(np); @@ -606,42 +611,42 @@ static int rockchip_cpufreq_remove_monitor(struct cluster_info *cluster) return 0; } -static int rockchip_cpufreq_remove_dsu_qos(struct cluster_info *cluster) +static int rockchip_cpufreq_remove_bus_qos(struct cluster_info *cluster) { struct cluster_info *ci; - if (!cluster->is_opp_shared_dsu) + if (!cluster->is_opp_shared_cpu_bus) return 0; list_for_each_entry(ci, &cluster_info_list, list_head) { - if (ci->is_opp_shared_dsu) + if (ci->is_opp_shared_cpu_bus) continue; - if (freq_qos_request_active(&ci->dsu_qos_req)) - freq_qos_remove_request(&ci->dsu_qos_req); + if (freq_qos_request_active(&ci->bus_qos_req)) + freq_qos_remove_request(&ci->bus_qos_req); } return 0; } -static int rockchip_cpufreq_add_dsu_qos_req(struct cluster_info *cluster, +static int rockchip_cpufreq_add_bus_qos_req(struct cluster_info *cluster, struct cpufreq_policy *policy) { struct device *dev = cluster->opp_info.dev; struct cluster_info *ci; int ret; - if (!cluster->is_opp_shared_dsu) + if (!cluster->is_opp_shared_cpu_bus) return 0; list_for_each_entry(ci, &cluster_info_list, list_head) { - if (ci->is_opp_shared_dsu) + if (ci->is_opp_shared_cpu_bus) continue; ret = freq_qos_add_request(&policy->constraints, - &ci->dsu_qos_req, + &ci->bus_qos_req, FREQ_QOS_MIN, FREQ_QOS_MIN_DEFAULT_VALUE); if (ret < 0) { - dev_err(dev, "failed to add dsu freq constraint\n"); + dev_err(dev, "failed to add cpu bus freq constraint\n"); goto error; } } @@ -649,7 +654,7 @@ static int rockchip_cpufreq_add_dsu_qos_req(struct cluster_info *cluster, return 0; error: - rockchip_cpufreq_remove_dsu_qos(cluster); + rockchip_cpufreq_remove_bus_qos(cluster); return ret; } @@ -667,11 +672,11 @@ static int rockchip_cpufreq_notifier(struct notifier_block *nb, if (event == CPUFREQ_CREATE_POLICY) { if (rockchip_cpufreq_add_monitor(cluster, policy)) return NOTIFY_BAD; - if (rockchip_cpufreq_add_dsu_qos_req(cluster, policy)) + if (rockchip_cpufreq_add_bus_qos_req(cluster, policy)) return NOTIFY_BAD; } else if (event == CPUFREQ_REMOVE_POLICY) { rockchip_cpufreq_remove_monitor(cluster); - rockchip_cpufreq_remove_dsu_qos(cluster); + rockchip_cpufreq_remove_bus_qos(cluster); } return NOTIFY_OK; @@ -735,21 +740,26 @@ static int rockchip_cpufreq_idle_state_disable(struct cpumask *cpumask, } #endif -#define cpu_to_dsu_freq(freq) ((freq) * 4 / 5) +#define cpu_to_bus_freq(freq) ((freq) * 4 / 5) -static int rockchip_cpufreq_update_dsu_req(struct cluster_info *cluster, +static int rockchip_cpufreq_update_bus_req(struct cluster_info *cluster, unsigned int freq) { struct device *dev = cluster->opp_info.dev; - unsigned int dsu_freq = rounddown(cpu_to_dsu_freq(freq), 100000); + unsigned int bus_freq = 0; - if (cluster->is_opp_shared_dsu || - !freq_qos_request_active(&cluster->dsu_qos_req)) + if (cluster->is_opp_shared_cpu_bus || + !freq_qos_request_active(&cluster->bus_qos_req)) return 0; - dev_dbg(dev, "cpu to dsu: %u -> %u\n", freq, dsu_freq); + if (cluster->cpu_freq_percent) + bus_freq = rounddown(freq * cluster->cpu_freq_percent / 100, 100000); + else + bus_freq = rounddown(cpu_to_bus_freq(freq), 100000); - return freq_qos_update_request(&cluster->dsu_qos_req, dsu_freq); + dev_dbg(dev, "cpu to bus: %u -> %u\n", freq, bus_freq); + + return freq_qos_update_request(&cluster->bus_qos_req, bus_freq); } static int rockchip_cpufreq_transition_notifier(struct notifier_block *nb, @@ -779,7 +789,7 @@ static int rockchip_cpufreq_transition_notifier(struct notifier_block *nb, false); cluster->is_idle_disabled = false; } - rockchip_cpufreq_update_dsu_req(cluster, freqs->new); + rockchip_cpufreq_update_bus_req(cluster, freqs->new); } return NOTIFY_OK; @@ -819,6 +829,7 @@ static int __init rockchip_cpufreq_driver_init(void) struct cluster_info *cluster, *pos; struct cpufreq_dt_platform_data pdata = {0}; int cpu, ret; + bool is_opp_shared_cpu_bus = false; for_each_possible_cpu(cpu) { cluster = rockchip_cluster_info_lookup(cpu); @@ -837,6 +848,8 @@ static int __init rockchip_cpufreq_driver_init(void) goto release_cluster_info; } list_add(&cluster->list_head, &cluster_info_list); + if (cluster->is_opp_shared_cpu_bus) + is_opp_shared_cpu_bus = true; } pdata.have_governor_per_policy = true; @@ -849,7 +862,7 @@ static int __init rockchip_cpufreq_driver_init(void) goto release_cluster_info; } - if (of_machine_is_compatible("rockchip,rk3588")) { + if (is_opp_shared_cpu_bus) { ret = cpufreq_register_notifier(&rockchip_cpufreq_transition_notifier_block, CPUFREQ_TRANSITION_NOTIFIER); if (ret) { diff --git a/drivers/media/i2c/rk628/rk628_csi_v4l2.c b/drivers/media/i2c/rk628/rk628_csi_v4l2.c index 5046a99f487e..75c0d5256087 100644 --- a/drivers/media/i2c/rk628/rk628_csi_v4l2.c +++ b/drivers/media/i2c/rk628/rk628_csi_v4l2.c @@ -129,6 +129,7 @@ struct rk628_csi { struct device *classdev; bool is_streaming; bool csi_ints_en; + bool dual_mipi_use; }; struct rk628_csi_mode { @@ -1344,7 +1345,7 @@ static void rk628_csi_initial(struct v4l2_subdev *sd) def_edid.pad = 0; def_edid.start_block = 0; def_edid.blocks = 2; - if (csi->rk628->version >= RK628F_VERSION) + if (csi->rk628->version >= RK628F_VERSION && csi->dual_mipi_use) def_edid.edid = rk628f_edid_init_data; else def_edid.edid = edid_init_data; @@ -2902,6 +2903,7 @@ static int rk628_csi_get_multi_dev_info(struct rk628_csi *csi) struct device_node *node = dev->of_node; struct device_node *multi_info_np; + csi->dual_mipi_use = false; multi_info_np = of_get_child_by_name(node, "multi-dev-info"); if (!multi_info_np) { dev_info(dev, "failed to get multi dev info\n"); @@ -2918,6 +2920,8 @@ static int rk628_csi_get_multi_dev_info(struct rk628_csi *csi) &csi->multi_dev_info.pixel_offset); of_property_read_u32(multi_info_np, "dev-num", &csi->multi_dev_info.dev_num); + + csi->dual_mipi_use = true; dev_info(dev, "multi dev left: mipi%d, multi dev right: mipi%d, combile mipi%d, dev num: %d\n", csi->multi_dev_info.dev_idx[0], csi->multi_dev_info.dev_idx[1], diff --git a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c index cf2fa4dbe931..b665ab31e9e5 100644 --- a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c +++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c @@ -145,17 +145,19 @@ static int rockchip_combphy_pcie_init(struct rockchip_combphy_priv *priv) static int rockchip_combphy_usb3_init(struct rockchip_combphy_priv *priv) { - const struct rockchip_combphy_cfg *phy_cfg = priv->cfg; + const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg; int ret = 0; if (device_property_present(priv->dev, "rockchip,dis-u3otg0-port")) { - ret = rockchip_combphy_param_write(priv->pipe_grf, &phy_cfg->grfcfg->u3otg0_port_en, false); + ret = rockchip_combphy_param_write(priv->pipe_grf, + &cfg->u3otg0_port_en, false); return ret; } else if (device_property_present(priv->dev, "rockchip,dis-u3otg1-port")) { - ret = rockchip_combphy_param_write(priv->pipe_grf, &phy_cfg->grfcfg->u3otg1_port_en, false); + ret = rockchip_combphy_param_write(priv->pipe_grf, + &cfg->u3otg1_port_en, false); if (of_device_is_compatible(priv->dev->of_node, "rockchip,rk3576-naneng-combphy")) rockchip_combphy_param_write(priv->phy_grf, - &phy_cfg->grfcfg->usb_mode_set, true); + &cfg->usb_mode_set, true); return ret; } @@ -312,7 +314,7 @@ static int rockchip_combphy_validate(struct phy *phy, enum phy_mode mode, int su return 0; } -static const struct phy_ops rochchip_combphy_ops = { +static const struct phy_ops rockchip_combphy_ops = { .init = rockchip_combphy_init, .exit = rockchip_combphy_exit, .validate = rockchip_combphy_validate, @@ -341,7 +343,7 @@ static struct phy *rockchip_combphy_xlate(struct device *dev, static int rockchip_combphy_parse_dt(struct device *dev, struct rockchip_combphy_priv *priv) { - const struct rockchip_combphy_cfg *phy_cfg = priv->cfg; + const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg; int ret, mac_id; u32 vals[4]; @@ -366,17 +368,20 @@ static int rockchip_combphy_parse_dt(struct device *dev, } if (device_property_present(dev, "rockchip,dis-u3otg0-port")) { - rockchip_combphy_param_write(priv->pipe_grf, &phy_cfg->grfcfg->u3otg0_port_en, false); + rockchip_combphy_param_write(priv->pipe_grf, + &cfg->u3otg0_port_en, false); } else if (device_property_present(dev, "rockchip,dis-u3otg1-port")) { - rockchip_combphy_param_write(priv->pipe_grf, &phy_cfg->grfcfg->u3otg1_port_en, false); + rockchip_combphy_param_write(priv->pipe_grf, + &cfg->u3otg1_port_en, false); if (of_device_is_compatible(dev->of_node, "rockchip,rk3576-naneng-combphy")) rockchip_combphy_param_write(priv->phy_grf, - &phy_cfg->grfcfg->usb_mode_set, true); + &cfg->usb_mode_set, true); } if (!device_property_read_u32(dev, "rockchip,sgmii-mac-sel", &mac_id) && (mac_id > 0)) - rockchip_combphy_param_write(priv->pipe_grf, &phy_cfg->grfcfg->pipe_sgmii_mac_sel, true); + rockchip_combphy_param_write(priv->pipe_grf, + &cfg->pipe_sgmii_mac_sel, true); if (!device_property_read_u32_array(dev, "rockchip,pcie1ln-sel-bits", vals, ARRAY_SIZE(vals))) @@ -449,7 +454,7 @@ static int rockchip_combphy_probe(struct platform_device *pdev) if (ret) return ret; - priv->phy = devm_phy_create(dev, NULL, &rochchip_combphy_ops); + priv->phy = devm_phy_create(dev, NULL, &rockchip_combphy_ops); if (IS_ERR(priv->phy)) { dev_err(dev, "failed to create combphy\n"); return PTR_ERR(priv->phy); diff --git a/drivers/ufs/host/ufs-rockchip.c b/drivers/ufs/host/ufs-rockchip.c index c0c0ba01d51b..c17b71c8859f 100644 --- a/drivers/ufs/host/ufs-rockchip.c +++ b/drivers/ufs/host/ufs-rockchip.c @@ -24,6 +24,25 @@ static inline bool ufshcd_is_hba_active(struct ufs_hba *hba) return ufshcd_readl(hba, REG_CONTROLLER_ENABLE) & CONTROLLER_ENABLE; } +static inline bool ufshcd_is_device_present(struct ufs_hba *hba) +{ + return ufshcd_readl(hba, REG_CONTROLLER_STATUS) & DEVICE_PRESENT; +} + +static int ufshcd_dme_link_startup(struct ufs_hba *hba) +{ + struct uic_command uic_cmd = {0}; + int ret; + + uic_cmd.command = UIC_CMD_DME_LINK_STARTUP; + + ret = ufshcd_send_uic_cmd(hba, &uic_cmd); + if (ret) + dev_err(hba->dev, + "dme-link-startup: error code %d\n", ret); + return ret; +} + static int ufs_rockchip_hce_enable_notify(struct ufs_hba *hba, enum ufs_notify_change_status status) { @@ -68,49 +87,6 @@ start: return err; } -static int ufs_rockchip_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op, - enum ufs_notify_change_status status) -{ - struct ufs_rockchip_host *host = ufshcd_get_variant(hba); - - if (status == PRE_CHANGE) - return 0; - - if (pm_op == UFS_RUNTIME_PM) - return 0; - - if (host->in_suspend) { - WARN_ON(1); - return 0; - } - - /* set ref clk out disable */ - clk_disable_unprepare(host->ref_out_clk); - - host->in_suspend = true; - - return 0; -} - -static int ufs_rockchip_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op) -{ - struct ufs_rockchip_host *host = ufshcd_get_variant(hba); - int err; - - if (!host->in_suspend) - return 0; - - /* set ref clk out enable */ - err = clk_prepare_enable(host->ref_out_clk); - if (err) { - dev_err(hba->dev, "failed to enable ref out clock %d\n", err); - return err; - } - - host->in_suspend = false; - return 0; -} - static void ufs_rockchip_set_pm_lvl(struct ufs_hba *hba) { hba->rpm_lvl = UFS_PM_LVL_1; @@ -356,8 +332,6 @@ static const struct ufs_hba_variant_ops ufs_hba_rk3576_vops = { .device_reset = ufs_rockchip_device_reset, .hce_enable_notify = ufs_rockchip_hce_enable_notify, .phy_initialization = ufs_rockchip_rk3576_phy_init, - .suspend = ufs_rockchip_suspend, - .resume = ufs_rockchip_resume, }; static const struct of_device_id ufs_rockchip_of_match[] = { @@ -388,6 +362,54 @@ static int ufs_rockchip_remove(struct platform_device *pdev) return 0; } +static int ufs_rockchip_restore_link(struct ufs_hba *hba, bool is_store) +{ + struct ufs_rockchip_host *host = ufshcd_get_variant(hba); + int err, retry = 3; + + if (is_store) { + host->ie = ufshcd_readl(hba, REG_INTERRUPT_ENABLE); + host->ahit = ufshcd_readl(hba, REG_AUTO_HIBERNATE_IDLE_TIMER); + return 0; + } + + /* Enable controller */ + err = ufshcd_hba_enable(hba); + if (err) + return err; + + /* Link startup and wait for DP */ + do { + err = ufshcd_dme_link_startup(hba); + if (!err && ufshcd_is_device_present(hba)) { + dev_dbg_ratelimited(hba->dev, "rockchip link startup successfully.\n"); + break; + } + } while (retry--); + + if (retry < 0) { + dev_err(hba->dev, "rockchip link startup failed.\n"); + return -ENXIO; + } + + /* Restore negotiated power mode */ + err = ufshcd_config_pwr_mode(hba, &(hba->pwr_info)); + if (err) + dev_err(hba->dev, "Failed to restore power mode, err = %d\n", err); + + /* Restore task and transfer list */ + ufshcd_writel(hba, 0xffffffff, REG_INTERRUPT_STATUS); + ufshcd_make_hba_operational(hba); + + /* Restore lost regs */ + ufshcd_writel(hba, host->ie, REG_INTERRUPT_ENABLE); + ufshcd_writel(hba, host->ahit, REG_AUTO_HIBERNATE_IDLE_TIMER); + ufshcd_writel(hba, 0x1, REG_UTP_TRANSFER_REQ_LIST_RUN_STOP); + ufshcd_writel(hba, 0x1, REG_UTP_TASK_REQ_LIST_RUN_STOP); + + return err; +} + static int ufs_rockchip_runtime_suspend(struct device *dev) { struct ufs_hba *hba = dev_get_drvdata(dev); @@ -399,6 +421,7 @@ static int ufs_rockchip_runtime_suspend(struct device *dev) return ret; clk_disable_unprepare(host->ref_out_clk); + ufs_rockchip_restore_link(hba, true); return 0; } @@ -415,11 +438,39 @@ static int ufs_rockchip_runtime_resume(struct device *dev) return err; } + ufs_rockchip_restore_link(hba, false); + return ufshcd_runtime_resume(dev); } +static int ufs_rockchip_suspend(struct device *dev) +{ + struct ufs_hba *hba = dev_get_drvdata(dev); + + if (pm_runtime_suspended(hba->dev)) + return 0; + + ufs_rockchip_restore_link(hba, true); + + return ufshcd_system_suspend(dev); +} + +static int ufs_rockchip_resume(struct device *dev) +{ + struct ufs_hba *hba = dev_get_drvdata(dev); + + if (pm_runtime_suspended(hba->dev)) + return 0; + + /* Reset device if possible */ + ufs_rockchip_device_reset(hba); + ufs_rockchip_restore_link(hba, false); + + return ufshcd_system_resume(dev); +} + static const struct dev_pm_ops ufs_rockchip_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(ufshcd_system_suspend, ufshcd_system_resume) + SET_SYSTEM_SLEEP_PM_OPS(ufs_rockchip_suspend, ufs_rockchip_resume) SET_RUNTIME_PM_OPS(ufs_rockchip_runtime_suspend, ufs_rockchip_runtime_resume, NULL) .prepare = ufshcd_suspend_prepare, .complete = ufshcd_resume_complete, diff --git a/drivers/ufs/host/ufs-rockchip.h b/drivers/ufs/host/ufs-rockchip.h index 202e99bd3c38..7f3c2602f37c 100644 --- a/drivers/ufs/host/ufs-rockchip.h +++ b/drivers/ufs/host/ufs-rockchip.h @@ -34,6 +34,8 @@ struct ufs_rockchip_host { uint64_t caps; uint32_t phy_config_mode; bool in_suspend; + u32 ie; + u32 ahit; }; #define ufs_sys_writel(base, val, reg) \ diff --git a/drivers/video/rockchip/mpp/mpp_common.h b/drivers/video/rockchip/mpp/mpp_common.h index 795f48afa105..4e013f336355 100644 --- a/drivers/video/rockchip/mpp/mpp_common.h +++ b/drivers/video/rockchip/mpp/mpp_common.h @@ -602,6 +602,7 @@ struct mpp_dev_ops { int (*free_session)(struct mpp_session *session); int (*dump_session)(struct mpp_session *session, struct seq_file *seq); int (*dump_dev)(struct mpp_dev *mpp); + int (*link_irq)(struct mpp_dev *mpp); }; struct mpp_taskqueue *mpp_taskqueue_init(struct device *dev); diff --git a/drivers/video/rockchip/mpp/mpp_rkvdec2.c b/drivers/video/rockchip/mpp/mpp_rkvdec2.c index aee97f36a899..1a67147c1600 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvdec2.c +++ b/drivers/video/rockchip/mpp/mpp_rkvdec2.c @@ -568,6 +568,8 @@ static int rkvdec_vdpu383_irq(struct mpp_dev *mpp) mpp->irq_status = readl_relaxed(link->reg_base + link->info->status_base); writel(link->info->status_mask, link->reg_base + link->info->status_base); + mpp_debug(DEBUG_IRQ_STATUS, "irq_status: %08x : %08x\n", irq_val, mpp->irq_status); + /* wake isr to handle current task */ if (mpp->irq_status & status_bits) return IRQ_WAKE_THREAD; @@ -676,59 +678,6 @@ static int rkvdec2_read_perf_sel(struct mpp_dev *mpp, u32 *regs, u32 s, u32 e) } static int rkvdec2_finish(struct mpp_dev *mpp, struct mpp_task *mpp_task) -{ - u32 i; - u32 dec_get; - s32 dec_length; - struct rkvdec2_task *task = to_rkvdec2_task(mpp_task); - struct mpp_request *req; - u32 s, e; - - mpp_debug_enter(); - - /* read register after running */ - for (i = 0; i < task->r_req_cnt; i++) { - req = &task->r_reqs[i]; - /* read perf register */ - if (req->offset >= RKVDEC_PERF_SEL_OFFSET) { - u32 off = req->offset - RKVDEC_PERF_SEL_OFFSET; - - s = off / sizeof(u32); - e = s + req->size / sizeof(u32); - rkvdec2_read_perf_sel(mpp, task->reg_sel, s, e); - } else { - s = req->offset / sizeof(u32); - e = s + req->size / sizeof(u32); - mpp_read_req(mpp, task->reg, s, e); - } - } - /* revert hack for irq status */ - task->reg[RKVDEC_REG_INT_EN_INDEX] = task->irq_status; - - /* revert hack for decoded length */ - dec_get = mpp_read_relaxed(mpp, RKVDEC_REG_RLC_BASE); - dec_length = dec_get - task->strm_addr; - task->reg[RKVDEC_REG_RLC_BASE_INDEX] = dec_length << 10; - mpp_debug(DEBUG_REGISTER, "dec_get %08x dec_length %d\n", dec_get, dec_length); - - if (mpp->srv->timing_en) { - s64 time_diff; - - mpp_task->on_finish = ktime_get(); - set_bit(TASK_TIMING_FINISH, &mpp_task->state); - - time_diff = ktime_us_delta(mpp_task->on_finish, mpp_task->on_create); - - if (mpp->timing_check && time_diff > (s64)mpp->timing_check) - mpp_task_dump_timing(mpp_task, time_diff); - } - - mpp_debug_leave(); - - return 0; -} - -static int rkvdec_vdpu383_finish(struct mpp_dev *mpp, struct mpp_task *mpp_task) { u32 i; u32 dec_get; @@ -1546,12 +1495,13 @@ static struct mpp_dev_ops rkvdec_vdpu383_dev_ops = { .run = rkvdec_vdpu383_run, .irq = rkvdec_vdpu383_irq, .isr = rkvdec_vdpu383_isr, - .finish = rkvdec_vdpu383_finish, + .finish = rkvdec2_finish, .result = rkvdec2_result, .free_task = rkvdec2_free_task, .ioctl = rkvdec2_control, .init_session = rkvdec2_init_session, .free_session = rkvdec2_free_session, + .link_irq = rkvdec_vdpu383_link_irq, }; static const struct mpp_dev_var rkvdec_v2_data = { diff --git a/drivers/video/rockchip/mpp/mpp_rkvdec2.h b/drivers/video/rockchip/mpp/mpp_rkvdec2.h index 07e374e9c5b1..01bc6f08d595 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvdec2.h +++ b/drivers/video/rockchip/mpp/mpp_rkvdec2.h @@ -56,7 +56,7 @@ #define RKVDEC_REG_RLC_BASE_INDEX (128) #define RKVDEC_REG_INT_EN 0x380 -#define RKVDEC_REG_INT_EN_INDEX (224) + #define RKVDEC_SOFT_RESET_READY BIT(9) #define RKVDEC_CABAC_END_STA BIT(8) #define RKVDEC_COLMV_REF_ERR_STA BIT(7) diff --git a/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c b/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c index 420db6ea52b8..90dce98b6138 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c +++ b/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c @@ -77,6 +77,8 @@ struct rkvdec_link_info rkvdec_link_v2_hw_info = { .err_flag_base = 0x010, .err_flag_bit = BIT(31), }, + .irq_base = 0x00, + .next_addr_base = 0x1c, }; /* vdpu34x link hw info for rk356x */ @@ -136,6 +138,8 @@ struct rkvdec_link_info rkvdec_link_rk356x_hw_info = { .err_flag_base = 0x010, .err_flag_bit = BIT(31), }, + .irq_base = 0x00, + .next_addr_base = 0x1c, }; /* vdpu382 link hw info */ @@ -195,10 +199,56 @@ struct rkvdec_link_info rkvdec_link_vdpu382_hw_info = { .err_flag_base = 0x024, .err_flag_bit = BIT(8), }, + .irq_base = 0x00, + .next_addr_base = 0x1c, }; /* vdpu382 link hw info */ struct rkvdec_link_info rkvdec_link_vdpu383_hw_info = { + .tb_reg_num = 256, + .tb_reg_next = 0, + .tb_reg_r = 1, + .tb_reg_second_en = -1, + .tb_reg_debug = 2, + .tb_reg_seg0 = 3, + .tb_reg_seg1 = 4, + .tb_reg_seg2 = 5, + + .part_w_num = 3, + .part_r_num = 2, + .part_w[0] = { + .tb_reg_off = 80, + .reg_start = 8, + .reg_num = 24, + }, + .part_w[1] = { + .tb_reg_off = 104, + .reg_start = 64, + .reg_num = 44, + }, + .part_w[2] = { + .tb_reg_off = 148, + .reg_start = 128, + .reg_num = 108, + }, + .part_r[0] = { + .tb_reg_off = 16, + .reg_start = 15, + .reg_num = 1, + }, + .part_r[1] = { + .tb_reg_off = 20, + .reg_start = 320, + .reg_num = 40, + }, + .tb_reg_int = 16, + .tb_reg_cycle = 27, + .reg_status = { + .dec_num_mask = 0x3fffffff, + .err_flag_base = 0x04c, + .err_flag_bit = 0x3fe, + }, + .next_addr_base = 0x20, .ip_reset_base = 0x44, .ip_reset_en = BIT(0), .irq_base = 0x48, @@ -233,11 +283,11 @@ static void rkvdec_link_status_update(struct rkvdec_link_dev *dev) error_ff1 = (readl(reg_base + err_flag_base) & err_flag_bit) ? 1 : 0; enable_ff1 = readl(reg_base + RKVDEC_LINK_EN_BASE); - dev->irq_status = readl(reg_base + RKVDEC_LINK_IRQ_BASE); + dev->irq_status = readl(reg_base + link_info->irq_base); dev->iova_curr = readl(reg_base + RKVDEC_LINK_CFG_ADDR_BASE); dev->link_mode = readl(reg_base + RKVDEC_LINK_MODE_BASE); dev->total = readl(reg_base + RKVDEC_LINK_TOTAL_NUM_BASE); - dev->iova_next = readl(reg_base + RKVDEC_LINK_NEXT_ADDR_BASE); + dev->iova_next = readl(reg_base + link_info->next_addr_base); do { val = readl(reg_base + RKVDEC_LINK_DEC_NUM_BASE); @@ -414,6 +464,7 @@ static int rkvdec2_link_finish(struct mpp_dev *mpp, struct mpp_task *mpp_task) u32 *tb_reg = (u32 *)table->vaddr; u32 off, s, n; u32 i; + u32 reg_ret_status; mpp_debug_enter(); @@ -424,7 +475,8 @@ static int rkvdec2_link_finish(struct mpp_dev *mpp, struct mpp_task *mpp_task) memcpy(&task->reg[s], &tb_reg[off], n * sizeof(u32)); } /* revert hack for irq status */ - task->reg[RKVDEC_REG_INT_EN_INDEX] = task->irq_status; + reg_ret_status = mpp->var->hw_info->reg_ret_status; + task->reg[reg_ret_status] = task->irq_status; mpp_debug_leave(); @@ -466,8 +518,10 @@ static void *rkvdec2_link_prepare(struct mpp_dev *mpp, } /* setup error mode flag */ - tb_reg[9] |= BIT(18) | BIT(9); - tb_reg[info->tb_reg_second_en] |= RKVDEC_WAIT_RESET_EN; + if (info->tb_reg_second_en > 0) { + tb_reg[9] |= BIT(18) | BIT(9); + tb_reg[info->tb_reg_second_en] |= RKVDEC_WAIT_RESET_EN; + } /* memset read registers */ part = info->part_r; @@ -477,6 +531,16 @@ static void *rkvdec2_link_prepare(struct mpp_dev *mpp, memset(&tb_reg[off], 0, n * sizeof(u32)); } + /* set node registers */ + if (info->tb_reg_debug > 0) + tb_reg[info->tb_reg_debug] = table->iova + info->part_r[0].tb_reg_off * sizeof(u32); + if (info->tb_reg_seg0 > 0) + tb_reg[info->tb_reg_seg0] = table->iova + info->part_w[0].tb_reg_off * sizeof(u32); + if (info->tb_reg_seg1 > 0) + tb_reg[info->tb_reg_seg1] = table->iova + info->part_w[1].tb_reg_off * sizeof(u32); + if (info->tb_reg_seg2 > 0) + tb_reg[info->tb_reg_seg2] = table->iova + info->part_w[2].tb_reg_off * sizeof(u32); + list_move_tail(&table->link, &link_dec->used_list); task->table = table; set_bit(TASK_STATE_PREPARE, &mpp_task->state); @@ -528,26 +592,26 @@ static int rkvdec2_link_reset(struct mpp_dev *mpp) static int rkvdec2_link_irq(struct mpp_dev *mpp) { struct rkvdec2_dev *dec = to_rkvdec2_dev(mpp); - struct rkvdec_link_dev *link_dec = dec->link_dec; + struct rkvdec_link_dev *link = dec->link_dec; u32 irq_status = 0; - irq_status = readl(link_dec->reg_base + RKVDEC_LINK_IRQ_BASE); + irq_status = readl(link->reg_base + link->info->irq_base); if (irq_status & RKVDEC_LINK_BIT_IRQ_RAW) { - u32 enabled = readl(link_dec->reg_base + RKVDEC_LINK_EN_BASE); + u32 enabled = readl(link->reg_base + RKVDEC_LINK_EN_BASE); if (!enabled) { u32 bus = mpp_read_relaxed(mpp, 273 * 4); if (bus & 0x7ffff) - dev_info(link_dec->dev, + dev_info(link->dev, "invalid bus status %08x\n", bus); } - link_dec->irq_status = irq_status; + link->irq_status = irq_status; mpp->irq_status = mpp_read_relaxed(mpp, RKVDEC_REG_INT_EN); - writel_relaxed(0, link_dec->reg_base + RKVDEC_LINK_IRQ_BASE); + writel_relaxed(0, link->reg_base + link->info->irq_base); } mpp_debug(DEBUG_IRQ_STATUS | DEBUG_LINK_TABLE, "irq_status: %08x : %08x\n", @@ -556,6 +620,29 @@ static int rkvdec2_link_irq(struct mpp_dev *mpp) return 0; } +int rkvdec_vdpu383_link_irq(struct mpp_dev *mpp) +{ + struct rkvdec2_dev *dec = to_rkvdec2_dev(mpp); + struct rkvdec_link_dev *link = dec->link_dec; + u32 irq_val; + u32 irq_bits = link->info->irq_mask >> 16; + + /* read irq and status */ + irq_val = readl_relaxed(link->reg_base + link->info->irq_base); + if (irq_val & irq_bits) { + link->irq_status = irq_val; + mpp->irq_status = readl_relaxed(link->reg_base + link->info->status_base); + + /* clear irq and status */ + writel_relaxed(0xffff0000, link->reg_base + link->info->irq_base); + writel_relaxed(0xffff0000, link->reg_base + link->info->status_base); + } + mpp_debug(DEBUG_IRQ_STATUS | DEBUG_LINK_TABLE, "irq_status: %08x : %08x\n", + irq_val, mpp->irq_status); + + return 0; +} + int rkvdec2_link_remove(struct mpp_dev *mpp, struct rkvdec_link_dev *link_dec) { mpp_debug_enter(); @@ -1094,8 +1181,12 @@ static int mpp_task_queue(struct mpp_dev *mpp, struct mpp_task *mpp_task) irqreturn_t rkvdec2_link_irq_proc(int irq, void *param) { struct mpp_dev *mpp = param; - int ret = rkvdec2_link_irq(mpp); + int ret; + if (mpp->dev_ops->link_irq) + ret = mpp->dev_ops->link_irq(mpp); + else + ret = rkvdec2_link_irq(mpp); if (!ret) rkvdec2_link_trigger_work(mpp); @@ -1515,6 +1606,7 @@ static int rkvdec2_soft_ccu_dequeue(struct mpp_taskqueue *queue) u32 timeout_flag = test_bit(TASK_STATE_TIMEOUT, &mpp_task->state); u32 abort_flag = test_bit(TASK_STATE_ABORT, &mpp_task->state); u32 timing_en = mpp->srv->timing_en; + u32 reg_ret_status = mpp->var->hw_info->reg_ret_status; if (irq_status || timeout_flag || abort_flag) { struct rkvdec2_task *task = to_rkvdec2_task(mpp_task); @@ -1540,7 +1632,7 @@ static int rkvdec2_soft_ccu_dequeue(struct mpp_taskqueue *queue) if (irq_status && mpp->dev_ops->finish) mpp->dev_ops->finish(mpp, mpp_task); else - task->reg[RKVDEC_REG_INT_EN_INDEX] = RKVDEC_TIMEOUT_STA; + task->reg[reg_ret_status] = RKVDEC_TIMEOUT_STA; set_bit(TASK_STATE_FINISH, &mpp_task->state); set_bit(TASK_STATE_DONE, &mpp_task->state); @@ -1780,13 +1872,14 @@ static int rkvdec2_soft_ccu_enqueue(struct mpp_dev *mpp, struct mpp_task *mpp_ta u32 i, reg_en, reg; struct rkvdec2_dev *dec = to_rkvdec2_dev(mpp); struct rkvdec2_task *task = to_rkvdec2_task(mpp_task); + struct rkvdec_link_dev *link_dec = dec->link_dec; u32 timing_en = mpp->srv->timing_en; mpp_debug_enter(); /* set reg for link */ reg = RKVDEC_LINK_BIT_CORE_WORK_MODE | RKVDEC_LINK_BIT_CCU_WORK_MODE; - writel_relaxed(reg, dec->link_dec->reg_base + RKVDEC_LINK_IRQ_BASE); + writel_relaxed(reg, link_dec->reg_base + link_dec->info->irq_base); /* set reg for ccu */ writel_relaxed(RKVDEC_CCU_BIT_WORK_EN, dec->ccu->reg_base + RKVDEC_CCU_WORK_BASE); @@ -2045,17 +2138,18 @@ irqreturn_t rkvdec2_hard_ccu_irq(int irq, void *param) u32 irq_status; struct mpp_dev *mpp = param; struct rkvdec2_dev *dec = to_rkvdec2_dev(mpp); + struct rkvdec_link_dev *link_dec = dec->link_dec; - irq_status = readl(dec->link_dec->reg_base + RKVDEC_LINK_IRQ_BASE); + irq_status = readl(link_dec->reg_base + link_dec->info->irq_base); dec->ccu->ccu_core_work_mode = readl(dec->ccu->reg_base + RKVDEC_CCU_CORE_WORK_BASE); if (irq_status & RKVDEC_LINK_BIT_IRQ_RAW) { - dec->link_dec->irq_status = irq_status; + link_dec->irq_status = irq_status; mpp->irq_status = mpp_read(mpp, RKVDEC_REG_INT_EN); mpp_debug(DEBUG_IRQ_STATUS, "core %d link_irq=%08x, core_irq=%08x\n", mpp->core_id, irq_status, mpp->irq_status); writel(irq_status & 0xfffff0ff, - dec->link_dec->reg_base + RKVDEC_LINK_IRQ_BASE); + link_dec->reg_base + link_dec->info->irq_base); kthread_queue_work(&mpp->queue->worker, &mpp->work); return IRQ_HANDLED; @@ -2067,6 +2161,7 @@ irqreturn_t rkvdec2_hard_ccu_irq(int irq, void *param) static int rkvdec2_hard_ccu_finish(struct rkvdec_link_info *hw, struct rkvdec2_task *task) { u32 i, off, s, n; + u32 reg_ret_status; struct rkvdec_link_part *part = hw->part_r; u32 *tb_reg = (u32 *)task->table->vaddr; @@ -2079,7 +2174,8 @@ static int rkvdec2_hard_ccu_finish(struct rkvdec_link_info *hw, struct rkvdec2_t memcpy(&task->reg[s], &tb_reg[off], n * sizeof(u32)); } /* revert hack for irq status */ - task->reg[RKVDEC_REG_INT_EN_INDEX] = task->irq_status; + reg_ret_status = task->mpp_task.hw_info->reg_ret_status; + task->reg[reg_ret_status] = task->irq_status; mpp_debug_leave(); @@ -2299,11 +2395,12 @@ static int rkvdec2_ccu_link_fix_rcb_regs(struct rkvdec2_dev *dec) int ret = 0; u32 i, val; u32 reg, reg_idx, rcb_size, rcb_offset; + struct rkvdec_link_dev *link_dec = dec->link_dec; if (!dec->rcb_iova && !dec->rcb_info_count) goto done; /* check whether fixed */ - val = readl(dec->link_dec->reg_base + RKVDEC_LINK_IRQ_BASE); + val = readl(link_dec->reg_base + link_dec->info->irq_base); if (val & RKVDEC_CCU_BIT_FIX_RCB) goto done; /* set registers */ @@ -2325,7 +2422,7 @@ static int rkvdec2_ccu_link_fix_rcb_regs(struct rkvdec2_dev *dec) } val |= RKVDEC_CCU_BIT_FIX_RCB; - writel(val, dec->link_dec->reg_base + RKVDEC_LINK_IRQ_BASE); + writel(val, link_dec->reg_base + link_dec->info->irq_base); done: return ret; } @@ -2355,15 +2452,16 @@ static int rkvdec2_hard_ccu_enqueue(struct rkvdec2_ccu *ccu, u32 val; struct mpp_dev *core = queue->cores[i]; struct rkvdec2_dev *dec = to_rkvdec2_dev(core); + struct rkvdec_link_dev *link_dec = dec->link_dec; if (mpp->disable) continue; work_mode |= dec->core_mask; rkvdec2_ccu_link_fix_rcb_regs(dec); /* control by ccu */ - val = readl(dec->link_dec->reg_base + RKVDEC_LINK_IRQ_BASE); + val = readl(link_dec->reg_base + link_dec->info->irq_base); val |= RKVDEC_LINK_BIT_CCU_WORK_MODE; - writel(val, dec->link_dec->reg_base + RKVDEC_LINK_IRQ_BASE); + writel(val, link_dec->reg_base + link_dec->info->irq_base); } writel(work_mode, ccu->reg_base + RKVDEC_CCU_CORE_WORK_BASE); ccu->ccu_core_work_mode = readl(ccu->reg_base + RKVDEC_CCU_CORE_WORK_BASE); diff --git a/drivers/video/rockchip/mpp/mpp_rkvdec2_link.h b/drivers/video/rockchip/mpp/mpp_rkvdec2_link.h index 09b3ff3877b2..335085119f24 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvdec2_link.h +++ b/drivers/video/rockchip/mpp/mpp_rkvdec2_link.h @@ -29,9 +29,6 @@ /* define for link hardware */ #define RKVDEC_LINK_ADD_CFG_NUM 1 -#define RKVDEC_LINK_IRQ_BASE 0x000 -#define RKVDEC_LINK_BIT_IRQ_DIS BIT(2) -#define RKVDEC_LINK_BIT_IRQ BIT(8) #define RKVDEC_LINK_BIT_IRQ_RAW BIT(9) #define RKVDEC_LINK_BIT_CORE_WORK_MODE BIT(16) #define RKVDEC_LINK_BIT_CCU_WORK_MODE BIT(17) @@ -51,12 +48,6 @@ #define RKVDEC_LINK_EN_BASE 0x018 #define RKVDEC_LINK_BIT_EN BIT(0) -#define RKVDEC_LINK_NEXT_ADDR_BASE 0x01c - -#define RKVDEC_LINK_STA_BASE 0x024 - -#define RKVDEC_LINK_REG_CYCLE_CNT 179 - /* define for ccu link hardware */ #define RKVDEC_CCU_CTRL_BASE 0x000 #define RKVDEC_CCU_BIT_AUTOGATE BIT(0) @@ -113,7 +104,11 @@ struct rkvdec_link_info { /* current read back addr in table buffer */ u32 tb_reg_r; /* secondary enable in table buffer */ - u32 tb_reg_second_en; + int tb_reg_debug; + int tb_reg_seg0; + int tb_reg_seg1; + int tb_reg_seg2; + int tb_reg_second_en; u32 part_w_num; u32 part_r_num; @@ -126,6 +121,9 @@ struct rkvdec_link_info { bool hack_setup; struct rkvdec_link_status reg_status; + /* for next link node addr */ + u32 next_addr_base; + /* register for vdpu383 later */ u32 ip_reset_base; u32 ip_reset_en; @@ -248,4 +246,7 @@ int rkvdec2_hard_ccu_iommu_fault_handle(struct iommu_domain *iommu, struct device *iommu_dev, unsigned long iova, int status, void *arg); +/* for special handle */ +int rkvdec_vdpu383_link_irq(struct mpp_dev *mpp); + #endif diff --git a/include/linux/pwm-rockchip.h b/include/linux/pwm-rockchip.h index 03320dbcf5ac..f3c550dcb2b0 100644 --- a/include/linux/pwm-rockchip.h +++ b/include/linux/pwm-rockchip.h @@ -92,6 +92,8 @@ enum rockchip_pwm_wave_update_mode { * @enable: enable or disable wave generator * @duty_en: to update duty by duty table or not * @period_en: to update period by period table or not + * @clk_rate: the dclk rate in wave generator mode + * @rpt: the number of repeated effective periods * @width_mode: the width mode of wave table * @update_mode: the update mode of wave generator * @duty_max: the maximum address of duty table