diff --git a/drivers/devfreq/rockchip_dmc.c b/drivers/devfreq/rockchip_dmc.c index 12d40d8e9223..8b3529e1ab64 100644 --- a/drivers/devfreq/rockchip_dmc.c +++ b/drivers/devfreq/rockchip_dmc.c @@ -643,8 +643,6 @@ struct rockchip_dmcfreq { int (*set_auto_self_refresh)(u32 en); }; -static struct rockchip_dmcfreq *rk_dmcfreq; - /* * function: packaging de-skew setting to rk3328_ddr_dts_config_timing, * rk3328_ddr_dts_config_timing will pass to trust firmware, and @@ -2052,12 +2050,19 @@ static ssize_t rockchip_dmcfreq_status_store(struct device *dev, static DEVICE_ATTR(system_status, 0644, rockchip_dmcfreq_status_show, rockchip_dmcfreq_status_store); -void rockchip_dmcfreq_vop_bandwidth_update(unsigned int bw_mbyte) +void rockchip_dmcfreq_vop_bandwidth_update(struct devfreq *devfreq, + unsigned int bw_mbyte) { - struct rockchip_dmcfreq *dmcfreq = rk_dmcfreq; + struct device *dev; + struct rockchip_dmcfreq *dmcfreq; unsigned long vop_last_rate, target = 0; int i; + if (!devfreq) + return; + + dev = devfreq->dev.parent; + dmcfreq = dev_get_drvdata(dev); if (!dmcfreq || !dmcfreq->auto_freq_en || !dmcfreq->vop_bw_tbl) return; @@ -2078,12 +2083,20 @@ void rockchip_dmcfreq_vop_bandwidth_update(unsigned int bw_mbyte) rockchip_dmcfreq_update_target(dmcfreq); } -int rockchip_dmcfreq_vop_bandwidth_request(unsigned int bw_mbyte) +int rockchip_dmcfreq_vop_bandwidth_request(struct devfreq *devfreq, + unsigned int bw_mbyte) { - struct rockchip_dmcfreq *dmcfreq = rk_dmcfreq; + struct device *dev; + struct rockchip_dmcfreq *dmcfreq; unsigned long target = 0; int i; + if (!devfreq) + return 0; + + dev = devfreq->dev.parent; + dmcfreq = dev_get_drvdata(dev); + if (!dmcfreq || !dmcfreq->auto_freq_en || !dmcfreq->vop_bw_tbl) return 0; @@ -2481,8 +2494,6 @@ static int rockchip_dmcfreq_probe(struct platform_device *pdev) rockchip_set_system_status(SYS_STATUS_NORMAL); - rk_dmcfreq = data; - ret = ddr_power_model_simple_init(data); if (!ret) { diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c index f60ade8ab100..da9b8ae9d3e6 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -1264,6 +1265,8 @@ static int rockchip_drm_bind(struct device *dev) struct drm_device *drm_dev; struct rockchip_drm_private *private; int ret; + struct device_node *np = dev->of_node; + struct device_node *parent_np; drm_dev = drm_dev_alloc(&rockchip_drm_driver, dev); if (!drm_dev) @@ -1286,6 +1289,27 @@ static int rockchip_drm_bind(struct device *dev) drm_dev->dev_private = private; + private->dmc_support = false; + private->devfreq = devfreq_get_devfreq_by_phandle(dev, 0); + if (IS_ERR(private->devfreq)) { + if (PTR_ERR(private->devfreq) == -EPROBE_DEFER) { + parent_np = of_parse_phandle(np, "devfreq", 0); + if (parent_np && + of_device_is_available(parent_np)) { + private->dmc_support = true; + dev_warn(dev, "defer getting devfreq\n"); + } else { + dev_info(dev, "dmc is disabled\n"); + } + } else { + dev_info(dev, "devfreq is not set\n"); + } + private->devfreq = NULL; + } else { + private->dmc_support = true; + dev_info(dev, "devfreq is ready\n"); + } + private->hdmi_pll.pll = devm_clk_get(dev, "hdmi-tmds-pll"); if (PTR_ERR(private->hdmi_pll.pll) == -ENOENT) { private->hdmi_pll.pll = NULL; diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h index a9120d81abe8..239c08c342ca 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h @@ -197,6 +197,8 @@ struct rockchip_drm_private { struct drm_mm mm; struct rockchip_dclk_pll default_pll; struct rockchip_dclk_pll hdmi_pll; + struct devfreq *devfreq; + bool dmc_support; }; #ifndef MODULE diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c index 390a19d3b17c..b8a011977e71 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c @@ -234,7 +234,15 @@ static int rockchip_drm_bandwidth_atomic_check(struct drm_device *dev, /* * Check ddr frequency support here here. */ - ret = rockchip_dmcfreq_vop_bandwidth_request(*bandwidth); + if (priv->dmc_support && !priv->devfreq) { + priv->devfreq = devfreq_get_devfreq_by_phandle(dev->dev, 0); + if (IS_ERR(priv->devfreq)) + priv->devfreq = NULL; + } + + if (priv->devfreq) + ret = rockchip_dmcfreq_vop_bandwidth_request(priv->devfreq, + *bandwidth); return ret; } @@ -244,6 +252,7 @@ rockchip_atomic_commit_complete(struct rockchip_atomic_commit *commit) { struct drm_atomic_state *state = commit->state; struct drm_device *dev = commit->dev; + struct rockchip_drm_private *prv = dev->dev_private; size_t bandwidth = commit->bandwidth; /* @@ -273,7 +282,13 @@ rockchip_atomic_commit_complete(struct rockchip_atomic_commit *commit) rockchip_drm_backlight_update(dev); - rockchip_dmcfreq_vop_bandwidth_update(bandwidth); + if (prv->dmc_support && !prv->devfreq) { + prv->devfreq = devfreq_get_devfreq_by_phandle(dev->dev, 0); + if (IS_ERR(prv->devfreq)) + prv->devfreq = NULL; + } + if (prv->devfreq) + rockchip_dmcfreq_vop_bandwidth_update(prv->devfreq, bandwidth); drm_atomic_helper_commit_planes(dev, state, true); diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.h b/drivers/gpu/drm/rockchip/rockchip_drm_fb.h index eae46e205b9b..addd06c70393 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.h @@ -33,15 +33,21 @@ dma_addr_t rockchip_fb_get_dma_addr(struct drm_framebuffer *fb, unsigned int plane); #ifdef CONFIG_ARM_ROCKCHIP_DMC_DEVFREQ -int rockchip_dmcfreq_vop_bandwidth_request(unsigned int bw_mbyte); -void rockchip_dmcfreq_vop_bandwidth_update(unsigned int bw_mbyte); +int rockchip_dmcfreq_vop_bandwidth_request(struct devfreq *devfreq, + unsigned int bw_mbyte); +void rockchip_dmcfreq_vop_bandwidth_update(struct devfreq *devfreq, + unsigned int bw_mbyte); #else -static inline int rockchip_dmcfreq_vop_bandwidth_request(unsigned int bw_mbyte) +static inline int +rockchip_dmcfreq_vop_bandwidth_request(struct devfreq *devfreq, + unsigned int bw_mbyte) { return 0; } -static inline void rockchip_dmcfreq_vop_bandwidth_update(unsigned int bw_mbyte) +static inline void +rockchip_dmcfreq_vop_bandwidth_update(struct devfreq *devfreq, + unsigned int bw_mbyte) { } #endif