1 /*
2  * Copyright (C) 2013 Red Hat
3  * Author: Rob Clark <robdclark@gmail.com>
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 as published by
7  * the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 
19 #include "msm_drv.h"
20 #include "msm_mmu.h"
21 #include "mdp4_kms.h"
22 
23 static struct mdp4_platform_config *mdp4_get_config(struct platform_device *dev);
24 
mdp4_hw_init(struct msm_kms * kms)25 static int mdp4_hw_init(struct msm_kms *kms)
26 {
27 	struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
28 	struct drm_device *dev = mdp4_kms->dev;
29 	uint32_t version, major, minor, dmap_cfg, vg_cfg;
30 	unsigned long clk;
31 	int ret = 0;
32 
33 	pm_runtime_get_sync(dev->dev);
34 
35 	mdp4_enable(mdp4_kms);
36 	version = mdp4_read(mdp4_kms, REG_MDP4_VERSION);
37 	mdp4_disable(mdp4_kms);
38 
39 	major = FIELD(version, MDP4_VERSION_MAJOR);
40 	minor = FIELD(version, MDP4_VERSION_MINOR);
41 
42 	DBG("found MDP4 version v%d.%d", major, minor);
43 
44 	if (major != 4) {
45 		dev_err(dev->dev, "unexpected MDP version: v%d.%d\n",
46 				major, minor);
47 		ret = -ENXIO;
48 		goto out;
49 	}
50 
51 	mdp4_kms->rev = minor;
52 
53 	if (mdp4_kms->dsi_pll_vdda) {
54 		if ((mdp4_kms->rev == 2) || (mdp4_kms->rev == 4)) {
55 			ret = regulator_set_voltage(mdp4_kms->dsi_pll_vdda,
56 					1200000, 1200000);
57 			if (ret) {
58 				dev_err(dev->dev,
59 					"failed to set dsi_pll_vdda voltage: %d\n", ret);
60 				goto out;
61 			}
62 		}
63 	}
64 
65 	if (mdp4_kms->dsi_pll_vddio) {
66 		if (mdp4_kms->rev == 2) {
67 			ret = regulator_set_voltage(mdp4_kms->dsi_pll_vddio,
68 					1800000, 1800000);
69 			if (ret) {
70 				dev_err(dev->dev,
71 					"failed to set dsi_pll_vddio voltage: %d\n", ret);
72 				goto out;
73 			}
74 		}
75 	}
76 
77 	if (mdp4_kms->rev > 1) {
78 		mdp4_write(mdp4_kms, REG_MDP4_CS_CONTROLLER0, 0x0707ffff);
79 		mdp4_write(mdp4_kms, REG_MDP4_CS_CONTROLLER1, 0x03073f3f);
80 	}
81 
82 	mdp4_write(mdp4_kms, REG_MDP4_PORTMAP_MODE, 0x3);
83 
84 	/* max read pending cmd config, 3 pending requests: */
85 	mdp4_write(mdp4_kms, REG_MDP4_READ_CNFG, 0x02222);
86 
87 	clk = clk_get_rate(mdp4_kms->clk);
88 
89 	if ((mdp4_kms->rev >= 1) || (clk >= 90000000)) {
90 		dmap_cfg = 0x47;     /* 16 bytes-burst x 8 req */
91 		vg_cfg = 0x47;       /* 16 bytes-burs x 8 req */
92 	} else {
93 		dmap_cfg = 0x27;     /* 8 bytes-burst x 8 req */
94 		vg_cfg = 0x43;       /* 16 bytes-burst x 4 req */
95 	}
96 
97 	DBG("fetch config: dmap=%02x, vg=%02x", dmap_cfg, vg_cfg);
98 
99 	mdp4_write(mdp4_kms, REG_MDP4_DMA_FETCH_CONFIG(DMA_P), dmap_cfg);
100 	mdp4_write(mdp4_kms, REG_MDP4_DMA_FETCH_CONFIG(DMA_E), dmap_cfg);
101 
102 	mdp4_write(mdp4_kms, REG_MDP4_PIPE_FETCH_CONFIG(VG1), vg_cfg);
103 	mdp4_write(mdp4_kms, REG_MDP4_PIPE_FETCH_CONFIG(VG2), vg_cfg);
104 	mdp4_write(mdp4_kms, REG_MDP4_PIPE_FETCH_CONFIG(RGB1), vg_cfg);
105 	mdp4_write(mdp4_kms, REG_MDP4_PIPE_FETCH_CONFIG(RGB2), vg_cfg);
106 
107 	if (mdp4_kms->rev >= 2)
108 		mdp4_write(mdp4_kms, REG_MDP4_LAYERMIXER_IN_CFG_UPDATE_METHOD, 1);
109 	mdp4_write(mdp4_kms, REG_MDP4_LAYERMIXER_IN_CFG, 0);
110 
111 	/* disable CSC matrix / YUV by default: */
112 	mdp4_write(mdp4_kms, REG_MDP4_PIPE_OP_MODE(VG1), 0);
113 	mdp4_write(mdp4_kms, REG_MDP4_PIPE_OP_MODE(VG2), 0);
114 	mdp4_write(mdp4_kms, REG_MDP4_DMA_P_OP_MODE, 0);
115 	mdp4_write(mdp4_kms, REG_MDP4_DMA_S_OP_MODE, 0);
116 	mdp4_write(mdp4_kms, REG_MDP4_OVLP_CSC_CONFIG(1), 0);
117 	mdp4_write(mdp4_kms, REG_MDP4_OVLP_CSC_CONFIG(2), 0);
118 
119 	if (mdp4_kms->rev > 1)
120 		mdp4_write(mdp4_kms, REG_MDP4_RESET_STATUS, 1);
121 
122 	dev->mode_config.allow_fb_modifiers = true;
123 
124 out:
125 	pm_runtime_put_sync(dev->dev);
126 
127 	return ret;
128 }
129 
mdp4_prepare_commit(struct msm_kms * kms,struct drm_atomic_state * state)130 static void mdp4_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *state)
131 {
132 	struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
133 	int i, ncrtcs = state->dev->mode_config.num_crtc;
134 
135 	mdp4_enable(mdp4_kms);
136 
137 	/* see 119ecb7fd */
138 	for (i = 0; i < ncrtcs; i++) {
139 		struct drm_crtc *crtc = state->crtcs[i];
140 		if (!crtc)
141 			continue;
142 		drm_crtc_vblank_get(crtc);
143 	}
144 }
145 
mdp4_complete_commit(struct msm_kms * kms,struct drm_atomic_state * state)146 static void mdp4_complete_commit(struct msm_kms *kms, struct drm_atomic_state *state)
147 {
148 	struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
149 	int i, ncrtcs = state->dev->mode_config.num_crtc;
150 
151 	/* see 119ecb7fd */
152 	for (i = 0; i < ncrtcs; i++) {
153 		struct drm_crtc *crtc = state->crtcs[i];
154 		if (!crtc)
155 			continue;
156 		drm_crtc_vblank_put(crtc);
157 	}
158 
159 	mdp4_disable(mdp4_kms);
160 }
161 
mdp4_wait_for_crtc_commit_done(struct msm_kms * kms,struct drm_crtc * crtc)162 static void mdp4_wait_for_crtc_commit_done(struct msm_kms *kms,
163 						struct drm_crtc *crtc)
164 {
165 	mdp4_crtc_wait_for_commit_done(crtc);
166 }
167 
mdp4_round_pixclk(struct msm_kms * kms,unsigned long rate,struct drm_encoder * encoder)168 static long mdp4_round_pixclk(struct msm_kms *kms, unsigned long rate,
169 		struct drm_encoder *encoder)
170 {
171 	/* if we had >1 encoder, we'd need something more clever: */
172 	return mdp4_dtv_round_pixclk(encoder, rate);
173 }
174 
mdp4_preclose(struct msm_kms * kms,struct drm_file * file)175 static void mdp4_preclose(struct msm_kms *kms, struct drm_file *file)
176 {
177 	struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
178 	struct msm_drm_private *priv = mdp4_kms->dev->dev_private;
179 	unsigned i;
180 
181 	for (i = 0; i < priv->num_crtcs; i++)
182 		mdp4_crtc_cancel_pending_flip(priv->crtcs[i], file);
183 }
184 
mdp4_destroy(struct msm_kms * kms)185 static void mdp4_destroy(struct msm_kms *kms)
186 {
187 	struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
188 	if (mdp4_kms->blank_cursor_iova)
189 		msm_gem_put_iova(mdp4_kms->blank_cursor_bo, mdp4_kms->id);
190 	if (mdp4_kms->blank_cursor_bo)
191 		drm_gem_object_unreference_unlocked(mdp4_kms->blank_cursor_bo);
192 	kfree(mdp4_kms);
193 }
194 
195 static const struct mdp_kms_funcs kms_funcs = {
196 	.base = {
197 		.hw_init         = mdp4_hw_init,
198 		.irq_preinstall  = mdp4_irq_preinstall,
199 		.irq_postinstall = mdp4_irq_postinstall,
200 		.irq_uninstall   = mdp4_irq_uninstall,
201 		.irq             = mdp4_irq,
202 		.enable_vblank   = mdp4_enable_vblank,
203 		.disable_vblank  = mdp4_disable_vblank,
204 		.prepare_commit  = mdp4_prepare_commit,
205 		.complete_commit = mdp4_complete_commit,
206 		.wait_for_crtc_commit_done = mdp4_wait_for_crtc_commit_done,
207 		.get_format      = mdp_get_format,
208 		.round_pixclk    = mdp4_round_pixclk,
209 		.preclose        = mdp4_preclose,
210 		.destroy         = mdp4_destroy,
211 	},
212 	.set_irqmask         = mdp4_set_irqmask,
213 };
214 
mdp4_disable(struct mdp4_kms * mdp4_kms)215 int mdp4_disable(struct mdp4_kms *mdp4_kms)
216 {
217 	DBG("");
218 
219 	clk_disable_unprepare(mdp4_kms->clk);
220 	if (mdp4_kms->pclk)
221 		clk_disable_unprepare(mdp4_kms->pclk);
222 	clk_disable_unprepare(mdp4_kms->lut_clk);
223 	if (mdp4_kms->axi_clk)
224 		clk_disable_unprepare(mdp4_kms->axi_clk);
225 
226 	return 0;
227 }
228 
mdp4_enable(struct mdp4_kms * mdp4_kms)229 int mdp4_enable(struct mdp4_kms *mdp4_kms)
230 {
231 	DBG("");
232 
233 	clk_prepare_enable(mdp4_kms->clk);
234 	if (mdp4_kms->pclk)
235 		clk_prepare_enable(mdp4_kms->pclk);
236 	clk_prepare_enable(mdp4_kms->lut_clk);
237 	if (mdp4_kms->axi_clk)
238 		clk_prepare_enable(mdp4_kms->axi_clk);
239 
240 	return 0;
241 }
242 
243 #ifdef CONFIG_OF
detect_panel(struct drm_device * dev)244 static struct drm_panel *detect_panel(struct drm_device *dev)
245 {
246 	struct device_node *endpoint, *panel_node;
247 	struct device_node *np = dev->dev->of_node;
248 	struct drm_panel *panel = NULL;
249 
250 	endpoint = of_graph_get_next_endpoint(np, NULL);
251 	if (!endpoint) {
252 		dev_err(dev->dev, "no valid endpoint\n");
253 		return ERR_PTR(-ENODEV);
254 	}
255 
256 	panel_node = of_graph_get_remote_port_parent(endpoint);
257 	if (!panel_node) {
258 		dev_err(dev->dev, "no valid panel node\n");
259 		of_node_put(endpoint);
260 		return ERR_PTR(-ENODEV);
261 	}
262 
263 	of_node_put(endpoint);
264 
265 	panel = of_drm_find_panel(panel_node);
266 	if (!panel) {
267 		of_node_put(panel_node);
268 		return ERR_PTR(-EPROBE_DEFER);
269 	}
270 
271 	return panel;
272 }
273 #else
detect_panel(struct drm_device * dev)274 static struct drm_panel *detect_panel(struct drm_device *dev)
275 {
276 	// ??? maybe use a module param to specify which panel is attached?
277 }
278 #endif
279 
modeset_init(struct mdp4_kms * mdp4_kms)280 static int modeset_init(struct mdp4_kms *mdp4_kms)
281 {
282 	struct drm_device *dev = mdp4_kms->dev;
283 	struct msm_drm_private *priv = dev->dev_private;
284 	struct drm_plane *plane;
285 	struct drm_crtc *crtc;
286 	struct drm_encoder *encoder;
287 	struct drm_connector *connector;
288 	struct drm_panel *panel;
289 	int ret;
290 
291 	/* construct non-private planes: */
292 	plane = mdp4_plane_init(dev, VG1, false);
293 	if (IS_ERR(plane)) {
294 		dev_err(dev->dev, "failed to construct plane for VG1\n");
295 		ret = PTR_ERR(plane);
296 		goto fail;
297 	}
298 	priv->planes[priv->num_planes++] = plane;
299 
300 	plane = mdp4_plane_init(dev, VG2, false);
301 	if (IS_ERR(plane)) {
302 		dev_err(dev->dev, "failed to construct plane for VG2\n");
303 		ret = PTR_ERR(plane);
304 		goto fail;
305 	}
306 	priv->planes[priv->num_planes++] = plane;
307 
308 	/*
309 	 * Setup the LCDC/LVDS path: RGB2 -> DMA_P -> LCDC -> LVDS:
310 	 */
311 
312 	panel = detect_panel(dev);
313 	if (IS_ERR(panel)) {
314 		ret = PTR_ERR(panel);
315 		dev_err(dev->dev, "failed to detect LVDS panel: %d\n", ret);
316 		goto fail;
317 	}
318 
319 	plane = mdp4_plane_init(dev, RGB2, true);
320 	if (IS_ERR(plane)) {
321 		dev_err(dev->dev, "failed to construct plane for RGB2\n");
322 		ret = PTR_ERR(plane);
323 		goto fail;
324 	}
325 
326 	crtc  = mdp4_crtc_init(dev, plane, priv->num_crtcs, 0, DMA_P);
327 	if (IS_ERR(crtc)) {
328 		dev_err(dev->dev, "failed to construct crtc for DMA_P\n");
329 		ret = PTR_ERR(crtc);
330 		goto fail;
331 	}
332 
333 	encoder = mdp4_lcdc_encoder_init(dev, panel);
334 	if (IS_ERR(encoder)) {
335 		dev_err(dev->dev, "failed to construct LCDC encoder\n");
336 		ret = PTR_ERR(encoder);
337 		goto fail;
338 	}
339 
340 	/* LCDC can be hooked to DMA_P: */
341 	encoder->possible_crtcs = 1 << priv->num_crtcs;
342 
343 	priv->crtcs[priv->num_crtcs++] = crtc;
344 	priv->encoders[priv->num_encoders++] = encoder;
345 
346 	connector = mdp4_lvds_connector_init(dev, panel, encoder);
347 	if (IS_ERR(connector)) {
348 		ret = PTR_ERR(connector);
349 		dev_err(dev->dev, "failed to initialize LVDS connector: %d\n", ret);
350 		goto fail;
351 	}
352 
353 	priv->connectors[priv->num_connectors++] = connector;
354 
355 	/*
356 	 * Setup DTV/HDMI path: RGB1 -> DMA_E -> DTV -> HDMI:
357 	 */
358 
359 	plane = mdp4_plane_init(dev, RGB1, true);
360 	if (IS_ERR(plane)) {
361 		dev_err(dev->dev, "failed to construct plane for RGB1\n");
362 		ret = PTR_ERR(plane);
363 		goto fail;
364 	}
365 
366 	crtc  = mdp4_crtc_init(dev, plane, priv->num_crtcs, 1, DMA_E);
367 	if (IS_ERR(crtc)) {
368 		dev_err(dev->dev, "failed to construct crtc for DMA_E\n");
369 		ret = PTR_ERR(crtc);
370 		goto fail;
371 	}
372 
373 	encoder = mdp4_dtv_encoder_init(dev);
374 	if (IS_ERR(encoder)) {
375 		dev_err(dev->dev, "failed to construct DTV encoder\n");
376 		ret = PTR_ERR(encoder);
377 		goto fail;
378 	}
379 
380 	/* DTV can be hooked to DMA_E: */
381 	encoder->possible_crtcs = 1 << priv->num_crtcs;
382 
383 	priv->crtcs[priv->num_crtcs++] = crtc;
384 	priv->encoders[priv->num_encoders++] = encoder;
385 
386 	if (priv->hdmi) {
387 		/* Construct bridge/connector for HDMI: */
388 		ret = hdmi_modeset_init(priv->hdmi, dev, encoder);
389 		if (ret) {
390 			dev_err(dev->dev, "failed to initialize HDMI: %d\n", ret);
391 			goto fail;
392 		}
393 	}
394 
395 	return 0;
396 
397 fail:
398 	return ret;
399 }
400 
401 static const char *iommu_ports[] = {
402 		"mdp_port0_cb0", "mdp_port1_cb0",
403 };
404 
mdp4_kms_init(struct drm_device * dev)405 struct msm_kms *mdp4_kms_init(struct drm_device *dev)
406 {
407 	struct platform_device *pdev = dev->platformdev;
408 	struct mdp4_platform_config *config = mdp4_get_config(pdev);
409 	struct mdp4_kms *mdp4_kms;
410 	struct msm_kms *kms = NULL;
411 	struct msm_mmu *mmu;
412 	int ret;
413 
414 	mdp4_kms = kzalloc(sizeof(*mdp4_kms), GFP_KERNEL);
415 	if (!mdp4_kms) {
416 		dev_err(dev->dev, "failed to allocate kms\n");
417 		ret = -ENOMEM;
418 		goto fail;
419 	}
420 
421 	mdp_kms_init(&mdp4_kms->base, &kms_funcs);
422 
423 	kms = &mdp4_kms->base.base;
424 
425 	mdp4_kms->dev = dev;
426 
427 	mdp4_kms->mmio = msm_ioremap(pdev, NULL, "MDP4");
428 	if (IS_ERR(mdp4_kms->mmio)) {
429 		ret = PTR_ERR(mdp4_kms->mmio);
430 		goto fail;
431 	}
432 
433 	mdp4_kms->dsi_pll_vdda =
434 			devm_regulator_get_optional(&pdev->dev, "dsi_pll_vdda");
435 	if (IS_ERR(mdp4_kms->dsi_pll_vdda))
436 		mdp4_kms->dsi_pll_vdda = NULL;
437 
438 	mdp4_kms->dsi_pll_vddio =
439 			devm_regulator_get_optional(&pdev->dev, "dsi_pll_vddio");
440 	if (IS_ERR(mdp4_kms->dsi_pll_vddio))
441 		mdp4_kms->dsi_pll_vddio = NULL;
442 
443 	/* NOTE: driver for this regulator still missing upstream.. use
444 	 * _get_exclusive() and ignore the error if it does not exist
445 	 * (and hope that the bootloader left it on for us)
446 	 */
447 	mdp4_kms->vdd = devm_regulator_get_exclusive(&pdev->dev, "vdd");
448 	if (IS_ERR(mdp4_kms->vdd))
449 		mdp4_kms->vdd = NULL;
450 
451 	if (mdp4_kms->vdd) {
452 		ret = regulator_enable(mdp4_kms->vdd);
453 		if (ret) {
454 			dev_err(dev->dev, "failed to enable regulator vdd: %d\n", ret);
455 			goto fail;
456 		}
457 	}
458 
459 	mdp4_kms->clk = devm_clk_get(&pdev->dev, "core_clk");
460 	if (IS_ERR(mdp4_kms->clk)) {
461 		dev_err(dev->dev, "failed to get core_clk\n");
462 		ret = PTR_ERR(mdp4_kms->clk);
463 		goto fail;
464 	}
465 
466 	mdp4_kms->pclk = devm_clk_get(&pdev->dev, "iface_clk");
467 	if (IS_ERR(mdp4_kms->pclk))
468 		mdp4_kms->pclk = NULL;
469 
470 	// XXX if (rev >= MDP_REV_42) { ???
471 	mdp4_kms->lut_clk = devm_clk_get(&pdev->dev, "lut_clk");
472 	if (IS_ERR(mdp4_kms->lut_clk)) {
473 		dev_err(dev->dev, "failed to get lut_clk\n");
474 		ret = PTR_ERR(mdp4_kms->lut_clk);
475 		goto fail;
476 	}
477 
478 	mdp4_kms->axi_clk = devm_clk_get(&pdev->dev, "mdp_axi_clk");
479 	if (IS_ERR(mdp4_kms->axi_clk)) {
480 		dev_err(dev->dev, "failed to get axi_clk\n");
481 		ret = PTR_ERR(mdp4_kms->axi_clk);
482 		goto fail;
483 	}
484 
485 	clk_set_rate(mdp4_kms->clk, config->max_clk);
486 	clk_set_rate(mdp4_kms->lut_clk, config->max_clk);
487 
488 	/* make sure things are off before attaching iommu (bootloader could
489 	 * have left things on, in which case we'll start getting faults if
490 	 * we don't disable):
491 	 */
492 	mdp4_enable(mdp4_kms);
493 	mdp4_write(mdp4_kms, REG_MDP4_DTV_ENABLE, 0);
494 	mdp4_write(mdp4_kms, REG_MDP4_LCDC_ENABLE, 0);
495 	mdp4_write(mdp4_kms, REG_MDP4_DSI_ENABLE, 0);
496 	mdp4_disable(mdp4_kms);
497 	mdelay(16);
498 
499 	if (config->iommu) {
500 		mmu = msm_iommu_new(&pdev->dev, config->iommu);
501 		if (IS_ERR(mmu)) {
502 			ret = PTR_ERR(mmu);
503 			goto fail;
504 		}
505 		ret = mmu->funcs->attach(mmu, iommu_ports,
506 				ARRAY_SIZE(iommu_ports));
507 		if (ret)
508 			goto fail;
509 	} else {
510 		dev_info(dev->dev, "no iommu, fallback to phys "
511 				"contig buffers for scanout\n");
512 		mmu = NULL;
513 	}
514 
515 	mdp4_kms->id = msm_register_mmu(dev, mmu);
516 	if (mdp4_kms->id < 0) {
517 		ret = mdp4_kms->id;
518 		dev_err(dev->dev, "failed to register mdp4 iommu: %d\n", ret);
519 		goto fail;
520 	}
521 
522 	ret = modeset_init(mdp4_kms);
523 	if (ret) {
524 		dev_err(dev->dev, "modeset_init failed: %d\n", ret);
525 		goto fail;
526 	}
527 
528 	mutex_lock(&dev->struct_mutex);
529 	mdp4_kms->blank_cursor_bo = msm_gem_new(dev, SZ_16K, MSM_BO_WC);
530 	mutex_unlock(&dev->struct_mutex);
531 	if (IS_ERR(mdp4_kms->blank_cursor_bo)) {
532 		ret = PTR_ERR(mdp4_kms->blank_cursor_bo);
533 		dev_err(dev->dev, "could not allocate blank-cursor bo: %d\n", ret);
534 		mdp4_kms->blank_cursor_bo = NULL;
535 		goto fail;
536 	}
537 
538 	ret = msm_gem_get_iova(mdp4_kms->blank_cursor_bo, mdp4_kms->id,
539 			&mdp4_kms->blank_cursor_iova);
540 	if (ret) {
541 		dev_err(dev->dev, "could not pin blank-cursor bo: %d\n", ret);
542 		goto fail;
543 	}
544 
545 	dev->mode_config.min_width = 0;
546 	dev->mode_config.min_height = 0;
547 	dev->mode_config.max_width = 2048;
548 	dev->mode_config.max_height = 2048;
549 
550 	return kms;
551 
552 fail:
553 	if (kms)
554 		mdp4_destroy(kms);
555 	return ERR_PTR(ret);
556 }
557 
mdp4_get_config(struct platform_device * dev)558 static struct mdp4_platform_config *mdp4_get_config(struct platform_device *dev)
559 {
560 	static struct mdp4_platform_config config = {};
561 #ifdef CONFIG_OF
562 	/* TODO */
563 	config.max_clk = 266667000;
564 	config.iommu = iommu_domain_alloc(&platform_bus_type);
565 #else
566 	if (cpu_is_apq8064())
567 		config.max_clk = 266667000;
568 	else
569 		config.max_clk = 200000000;
570 
571 	config.iommu = msm_get_iommu_domain(DISPLAY_READ_DOMAIN);
572 #endif
573 	return &config;
574 }
575