Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/msm/dpu: Integrate interconnect API in MDSS

The interconnect framework is designed to provide a
standard kernel interface to control the settings of
the interconnects on a SoC.

The interconnect API uses a consumer/provider-based model,
where the providers are the interconnect buses and the
consumers could be various drivers.

MDSS is one of the interconnect consumers which uses the
interconnect APIs to get the path between endpoints and
set its bandwidth requirement for the given interconnected
path.

Changes in v2:
- Remove error log and unnecessary check (Jordan Crouse)

Changes in v3:
- Code clean involving variable name change, removal
of extra paranthesis and variables (Matthias Kaehlcke)

Changes in v4:
- Add comments, spacings, tabs, proper port name
and icc macro (Georgi Djakov)

Changes in v5:
- Commit text and parenthesis alignment (Georgi Djakov)

Changes in v6:
- Change to new icc_set API's (Doug Anderson)

Changes in v7:
- Fixed a typo

Changes in v8:
- Handle the of_icc_get() returning NULL case. In practice
icc_set_bw() will gracefully handle the case of a NULL path,
but it's probably best for clarity to keep num_paths=0 in
this case.

Signed-off-by: Sravanthi Kollukuduru <skolluku@codeaurora.org>
Signed-off-by: Jayant Shekhar <jshekhar@codeaurora.org>
Signed-off-by: Rob Clark <robdclark@chromium.org>
Acked-by: Georgi Djakov <georgi.djakov@linaro.org>
Reviewed-by: Sean Paul <sean@poorly.run>

authored by

Jayant Shekhar and committed by
Rob Clark
20cad6cd cb88482e

+45 -4
+45 -4
drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c
··· 4 4 */ 5 5 6 6 #include "dpu_kms.h" 7 + #include <linux/interconnect.h> 7 8 8 9 #define to_dpu_mdss(x) container_of(x, struct dpu_mdss, base) 9 10 10 11 #define HW_INTR_STATUS 0x0010 12 + 13 + /* Max BW defined in KBps */ 14 + #define MAX_BW 6800000 11 15 12 16 struct dpu_irq_controller { 13 17 unsigned long enabled_mask; ··· 25 21 u32 hwversion; 26 22 struct dss_module_power mp; 27 23 struct dpu_irq_controller irq_controller; 24 + struct icc_path *path[2]; 25 + u32 num_paths; 28 26 }; 27 + 28 + static int dpu_mdss_parse_data_bus_icc_path(struct drm_device *dev, 29 + struct dpu_mdss *dpu_mdss) 30 + { 31 + struct icc_path *path0 = of_icc_get(dev->dev, "mdp0-mem"); 32 + struct icc_path *path1 = of_icc_get(dev->dev, "mdp1-mem"); 33 + 34 + if (IS_ERR_OR_NULL(path0)) 35 + return PTR_ERR_OR_ZERO(path0); 36 + 37 + dpu_mdss->path[0] = path0; 38 + dpu_mdss->num_paths = 1; 39 + 40 + if (!IS_ERR_OR_NULL(path1)) { 41 + dpu_mdss->path[1] = path1; 42 + dpu_mdss->num_paths++; 43 + } 44 + 45 + return 0; 46 + } 29 47 30 48 static void dpu_mdss_irq(struct irq_desc *desc) 31 49 { ··· 160 134 { 161 135 struct dpu_mdss *dpu_mdss = to_dpu_mdss(mdss); 162 136 struct dss_module_power *mp = &dpu_mdss->mp; 163 - int ret; 137 + int ret, i; 138 + u64 avg_bw = dpu_mdss->num_paths ? MAX_BW / dpu_mdss->num_paths : 0; 139 + 140 + for (i = 0; i < dpu_mdss->num_paths; i++) 141 + icc_set_bw(dpu_mdss->path[i], avg_bw, kBps_to_icc(MAX_BW)); 164 142 165 143 ret = msm_dss_enable_clk(mp->clk_config, mp->num_clk, true); 166 144 if (ret) ··· 177 147 { 178 148 struct dpu_mdss *dpu_mdss = to_dpu_mdss(mdss); 179 149 struct dss_module_power *mp = &dpu_mdss->mp; 180 - int ret; 150 + int ret, i; 181 151 182 152 ret = msm_dss_enable_clk(mp->clk_config, mp->num_clk, false); 183 153 if (ret) 184 154 DPU_ERROR("clock disable failed, ret:%d\n", ret); 155 + 156 + for (i = 0; i < dpu_mdss->num_paths; i++) 157 + icc_set_bw(dpu_mdss->path[i], 0, 0); 185 158 186 159 return ret; 187 160 } ··· 196 163 struct dpu_mdss *dpu_mdss = to_dpu_mdss(priv->mdss); 197 164 struct dss_module_power *mp = &dpu_mdss->mp; 198 165 int irq; 166 + int i; 199 167 200 168 pm_runtime_suspend(dev->dev); 201 169 pm_runtime_disable(dev->dev); ··· 205 171 irq_set_chained_handler_and_data(irq, NULL, NULL); 206 172 msm_dss_put_clk(mp->clk_config, mp->num_clk); 207 173 devm_kfree(&pdev->dev, mp->clk_config); 174 + 175 + for (i = 0; i < dpu_mdss->num_paths; i++) 176 + icc_put(dpu_mdss->path[i]); 208 177 209 178 if (dpu_mdss->mmio) 210 179 devm_iounmap(&pdev->dev, dpu_mdss->mmio); ··· 248 211 } 249 212 dpu_mdss->mmio_len = resource_size(res); 250 213 214 + ret = dpu_mdss_parse_data_bus_icc_path(dev, dpu_mdss); 215 + if (ret) 216 + return ret; 217 + 251 218 mp = &dpu_mdss->mp; 252 219 ret = msm_dss_parse_clock(pdev, mp); 253 220 if (ret) { ··· 273 232 irq_set_chained_handler_and_data(irq, dpu_mdss_irq, 274 233 dpu_mdss); 275 234 235 + priv->mdss = &dpu_mdss->base; 236 + 276 237 pm_runtime_enable(dev->dev); 277 238 278 239 pm_runtime_get_sync(dev->dev); 279 240 dpu_mdss->hwversion = readl_relaxed(dpu_mdss->mmio); 280 241 pm_runtime_put_sync(dev->dev); 281 - 282 - priv->mdss = &dpu_mdss->base; 283 242 284 243 return ret; 285 244