• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * (C) COPYRIGHT 2016 ARM Limited. All rights reserved.
3  * Author: Liviu Dudau <Liviu.Dudau@arm.com>
4  *
5  * This program is free software and is provided to you under the terms of the
6  * GNU General Public License version 2 as published by the Free Software
7  * Foundation, and any use by you of this program is subject to the terms
8  * of such GNU licence.
9  *
10  * ARM Mali DP500/DP550/DP650 KMS/DRM driver
11  */
12 
13 #include <linux/module.h>
14 #include <linux/clk.h>
15 #include <linux/component.h>
16 #include <linux/of_device.h>
17 #include <linux/of_graph.h>
18 #include <linux/of_reserved_mem.h>
19 #include <linux/pm_runtime.h>
20 #include <linux/debugfs.h>
21 
22 #include <drm/drmP.h>
23 #include <drm/drm_atomic.h>
24 #include <drm/drm_atomic_helper.h>
25 #include <drm/drm_crtc.h>
26 #include <drm/drm_crtc_helper.h>
27 #include <drm/drm_fb_helper.h>
28 #include <drm/drm_fb_cma_helper.h>
29 #include <drm/drm_gem_cma_helper.h>
30 #include <drm/drm_gem_framebuffer_helper.h>
31 #include <drm/drm_modeset_helper.h>
32 #include <drm/drm_of.h>
33 
34 #include "malidp_drv.h"
35 #include "malidp_mw.h"
36 #include "malidp_regs.h"
37 #include "malidp_hw.h"
38 
39 #define MALIDP_CONF_VALID_TIMEOUT	250
40 
malidp_write_gamma_table(struct malidp_hw_device * hwdev,u32 data[MALIDP_COEFFTAB_NUM_COEFFS])41 static void malidp_write_gamma_table(struct malidp_hw_device *hwdev,
42 				     u32 data[MALIDP_COEFFTAB_NUM_COEFFS])
43 {
44 	int i;
45 	/* Update all channels with a single gamma curve. */
46 	const u32 gamma_write_mask = GENMASK(18, 16);
47 	/*
48 	 * Always write an entire table, so the address field in
49 	 * DE_COEFFTAB_ADDR is 0 and we can use the gamma_write_mask bitmask
50 	 * directly.
51 	 */
52 	malidp_hw_write(hwdev, gamma_write_mask,
53 			hwdev->hw->map.coeffs_base + MALIDP_COEF_TABLE_ADDR);
54 	for (i = 0; i < MALIDP_COEFFTAB_NUM_COEFFS; ++i)
55 		malidp_hw_write(hwdev, data[i],
56 				hwdev->hw->map.coeffs_base +
57 				MALIDP_COEF_TABLE_DATA);
58 }
59 
malidp_atomic_commit_update_gamma(struct drm_crtc * crtc,struct drm_crtc_state * old_state)60 static void malidp_atomic_commit_update_gamma(struct drm_crtc *crtc,
61 					      struct drm_crtc_state *old_state)
62 {
63 	struct malidp_drm *malidp = crtc_to_malidp_device(crtc);
64 	struct malidp_hw_device *hwdev = malidp->dev;
65 
66 	if (!crtc->state->color_mgmt_changed)
67 		return;
68 
69 	if (!crtc->state->gamma_lut) {
70 		malidp_hw_clearbits(hwdev,
71 				    MALIDP_DISP_FUNC_GAMMA,
72 				    MALIDP_DE_DISPLAY_FUNC);
73 	} else {
74 		struct malidp_crtc_state *mc =
75 			to_malidp_crtc_state(crtc->state);
76 
77 		if (!old_state->gamma_lut || (crtc->state->gamma_lut->base.id !=
78 					      old_state->gamma_lut->base.id))
79 			malidp_write_gamma_table(hwdev, mc->gamma_coeffs);
80 
81 		malidp_hw_setbits(hwdev, MALIDP_DISP_FUNC_GAMMA,
82 				  MALIDP_DE_DISPLAY_FUNC);
83 	}
84 }
85 
86 static
malidp_atomic_commit_update_coloradj(struct drm_crtc * crtc,struct drm_crtc_state * old_state)87 void malidp_atomic_commit_update_coloradj(struct drm_crtc *crtc,
88 					  struct drm_crtc_state *old_state)
89 {
90 	struct malidp_drm *malidp = crtc_to_malidp_device(crtc);
91 	struct malidp_hw_device *hwdev = malidp->dev;
92 	int i;
93 
94 	if (!crtc->state->color_mgmt_changed)
95 		return;
96 
97 	if (!crtc->state->ctm) {
98 		malidp_hw_clearbits(hwdev, MALIDP_DISP_FUNC_CADJ,
99 				    MALIDP_DE_DISPLAY_FUNC);
100 	} else {
101 		struct malidp_crtc_state *mc =
102 			to_malidp_crtc_state(crtc->state);
103 
104 		if (!old_state->ctm || (crtc->state->ctm->base.id !=
105 					old_state->ctm->base.id))
106 			for (i = 0; i < MALIDP_COLORADJ_NUM_COEFFS; ++i)
107 				malidp_hw_write(hwdev,
108 						mc->coloradj_coeffs[i],
109 						hwdev->hw->map.coeffs_base +
110 						MALIDP_COLOR_ADJ_COEF + 4 * i);
111 
112 		malidp_hw_setbits(hwdev, MALIDP_DISP_FUNC_CADJ,
113 				  MALIDP_DE_DISPLAY_FUNC);
114 	}
115 }
116 
malidp_atomic_commit_se_config(struct drm_crtc * crtc,struct drm_crtc_state * old_state)117 static void malidp_atomic_commit_se_config(struct drm_crtc *crtc,
118 					   struct drm_crtc_state *old_state)
119 {
120 	struct malidp_crtc_state *cs = to_malidp_crtc_state(crtc->state);
121 	struct malidp_crtc_state *old_cs = to_malidp_crtc_state(old_state);
122 	struct malidp_drm *malidp = crtc_to_malidp_device(crtc);
123 	struct malidp_hw_device *hwdev = malidp->dev;
124 	struct malidp_se_config *s = &cs->scaler_config;
125 	struct malidp_se_config *old_s = &old_cs->scaler_config;
126 	u32 se_control = hwdev->hw->map.se_base +
127 			 ((hwdev->hw->map.features & MALIDP_REGMAP_HAS_CLEARIRQ) ?
128 			 0x10 : 0xC);
129 	u32 layer_control = se_control + MALIDP_SE_LAYER_CONTROL;
130 	u32 scr = se_control + MALIDP_SE_SCALING_CONTROL;
131 	u32 val;
132 
133 	/* Set SE_CONTROL */
134 	if (!s->scale_enable) {
135 		val = malidp_hw_read(hwdev, se_control);
136 		val &= ~MALIDP_SE_SCALING_EN;
137 		malidp_hw_write(hwdev, val, se_control);
138 		return;
139 	}
140 
141 	hwdev->hw->se_set_scaling_coeffs(hwdev, s, old_s);
142 	val = malidp_hw_read(hwdev, se_control);
143 	val |= MALIDP_SE_SCALING_EN | MALIDP_SE_ALPHA_EN;
144 
145 	val &= ~MALIDP_SE_ENH(MALIDP_SE_ENH_MASK);
146 	val |= s->enhancer_enable ? MALIDP_SE_ENH(3) : 0;
147 
148 	val |= MALIDP_SE_RGBO_IF_EN;
149 	malidp_hw_write(hwdev, val, se_control);
150 
151 	/* Set IN_SIZE & OUT_SIZE. */
152 	val = MALIDP_SE_SET_V_SIZE(s->input_h) |
153 	      MALIDP_SE_SET_H_SIZE(s->input_w);
154 	malidp_hw_write(hwdev, val, layer_control + MALIDP_SE_L0_IN_SIZE);
155 	val = MALIDP_SE_SET_V_SIZE(s->output_h) |
156 	      MALIDP_SE_SET_H_SIZE(s->output_w);
157 	malidp_hw_write(hwdev, val, layer_control + MALIDP_SE_L0_OUT_SIZE);
158 
159 	/* Set phase regs. */
160 	malidp_hw_write(hwdev, s->h_init_phase, scr + MALIDP_SE_H_INIT_PH);
161 	malidp_hw_write(hwdev, s->h_delta_phase, scr + MALIDP_SE_H_DELTA_PH);
162 	malidp_hw_write(hwdev, s->v_init_phase, scr + MALIDP_SE_V_INIT_PH);
163 	malidp_hw_write(hwdev, s->v_delta_phase, scr + MALIDP_SE_V_DELTA_PH);
164 }
165 
166 /*
167  * set the "config valid" bit and wait until the hardware acts on it
168  */
malidp_set_and_wait_config_valid(struct drm_device * drm)169 static int malidp_set_and_wait_config_valid(struct drm_device *drm)
170 {
171 	struct malidp_drm *malidp = drm->dev_private;
172 	struct malidp_hw_device *hwdev = malidp->dev;
173 	int ret;
174 
175 	hwdev->hw->set_config_valid(hwdev, 1);
176 	/* don't wait for config_valid flag if we are in config mode */
177 	if (hwdev->hw->in_config_mode(hwdev)) {
178 		atomic_set(&malidp->config_valid, MALIDP_CONFIG_VALID_DONE);
179 		return 0;
180 	}
181 
182 	ret = wait_event_interruptible_timeout(malidp->wq,
183 			atomic_read(&malidp->config_valid) == MALIDP_CONFIG_VALID_DONE,
184 			msecs_to_jiffies(MALIDP_CONF_VALID_TIMEOUT));
185 
186 	return (ret > 0) ? 0 : -ETIMEDOUT;
187 }
188 
malidp_atomic_commit_hw_done(struct drm_atomic_state * state)189 static void malidp_atomic_commit_hw_done(struct drm_atomic_state *state)
190 {
191 	struct drm_device *drm = state->dev;
192 	struct malidp_drm *malidp = drm->dev_private;
193 	int loop = 5;
194 
195 	malidp->event = malidp->crtc.state->event;
196 	malidp->crtc.state->event = NULL;
197 
198 	if (malidp->crtc.state->active) {
199 		/*
200 		 * if we have an event to deliver to userspace, make sure
201 		 * the vblank is enabled as we are sending it from the IRQ
202 		 * handler.
203 		 */
204 		if (malidp->event)
205 			drm_crtc_vblank_get(&malidp->crtc);
206 
207 		/* only set config_valid if the CRTC is enabled */
208 		if (malidp_set_and_wait_config_valid(drm) < 0) {
209 			/*
210 			 * make a loop around the second CVAL setting and
211 			 * try 5 times before giving up.
212 			 */
213 			while (loop--) {
214 				if (!malidp_set_and_wait_config_valid(drm))
215 					break;
216 			}
217 			DRM_DEBUG_DRIVER("timed out waiting for updated configuration\n");
218 		}
219 
220 	} else if (malidp->event) {
221 		/* CRTC inactive means vblank IRQ is disabled, send event directly */
222 		spin_lock_irq(&drm->event_lock);
223 		drm_crtc_send_vblank_event(&malidp->crtc, malidp->event);
224 		malidp->event = NULL;
225 		spin_unlock_irq(&drm->event_lock);
226 	}
227 	drm_atomic_helper_commit_hw_done(state);
228 }
229 
malidp_atomic_commit_tail(struct drm_atomic_state * state)230 static void malidp_atomic_commit_tail(struct drm_atomic_state *state)
231 {
232 	struct drm_device *drm = state->dev;
233 	struct malidp_drm *malidp = drm->dev_private;
234 	struct drm_crtc *crtc;
235 	struct drm_crtc_state *old_crtc_state;
236 	int i;
237 
238 	pm_runtime_get_sync(drm->dev);
239 
240 	/*
241 	 * set config_valid to a special value to let IRQ handlers
242 	 * know that we are updating registers
243 	 */
244 	atomic_set(&malidp->config_valid, MALIDP_CONFIG_START);
245 	malidp->dev->hw->set_config_valid(malidp->dev, 0);
246 
247 	drm_atomic_helper_commit_modeset_disables(drm, state);
248 
249 	for_each_old_crtc_in_state(state, crtc, old_crtc_state, i) {
250 		malidp_atomic_commit_update_gamma(crtc, old_crtc_state);
251 		malidp_atomic_commit_update_coloradj(crtc, old_crtc_state);
252 		malidp_atomic_commit_se_config(crtc, old_crtc_state);
253 	}
254 
255 	drm_atomic_helper_commit_planes(drm, state, DRM_PLANE_COMMIT_ACTIVE_ONLY);
256 
257 	malidp_mw_atomic_commit(drm, state);
258 
259 	drm_atomic_helper_commit_modeset_enables(drm, state);
260 
261 	malidp_atomic_commit_hw_done(state);
262 
263 	pm_runtime_put(drm->dev);
264 
265 	drm_atomic_helper_cleanup_planes(drm, state);
266 }
267 
268 static const struct drm_mode_config_helper_funcs malidp_mode_config_helpers = {
269 	.atomic_commit_tail = malidp_atomic_commit_tail,
270 };
271 
272 static const struct drm_mode_config_funcs malidp_mode_config_funcs = {
273 	.fb_create = drm_gem_fb_create,
274 	.output_poll_changed = drm_fb_helper_output_poll_changed,
275 	.atomic_check = drm_atomic_helper_check,
276 	.atomic_commit = drm_atomic_helper_commit,
277 };
278 
malidp_init(struct drm_device * drm)279 static int malidp_init(struct drm_device *drm)
280 {
281 	int ret;
282 	struct malidp_drm *malidp = drm->dev_private;
283 	struct malidp_hw_device *hwdev = malidp->dev;
284 
285 	drm_mode_config_init(drm);
286 
287 	drm->mode_config.min_width = hwdev->min_line_size;
288 	drm->mode_config.min_height = hwdev->min_line_size;
289 	drm->mode_config.max_width = hwdev->max_line_size;
290 	drm->mode_config.max_height = hwdev->max_line_size;
291 	drm->mode_config.funcs = &malidp_mode_config_funcs;
292 	drm->mode_config.helper_private = &malidp_mode_config_helpers;
293 
294 	ret = malidp_crtc_init(drm);
295 	if (ret)
296 		goto crtc_fail;
297 
298 	ret = malidp_mw_connector_init(drm);
299 	if (ret)
300 		goto crtc_fail;
301 
302 	return 0;
303 
304 crtc_fail:
305 	drm_mode_config_cleanup(drm);
306 	return ret;
307 }
308 
malidp_fini(struct drm_device * drm)309 static void malidp_fini(struct drm_device *drm)
310 {
311 	drm_mode_config_cleanup(drm);
312 }
313 
malidp_irq_init(struct platform_device * pdev)314 static int malidp_irq_init(struct platform_device *pdev)
315 {
316 	int irq_de, irq_se, ret = 0;
317 	struct drm_device *drm = dev_get_drvdata(&pdev->dev);
318 	struct malidp_drm *malidp = drm->dev_private;
319 	struct malidp_hw_device *hwdev = malidp->dev;
320 
321 	/* fetch the interrupts from DT */
322 	irq_de = platform_get_irq_byname(pdev, "DE");
323 	if (irq_de < 0) {
324 		DRM_ERROR("no 'DE' IRQ specified!\n");
325 		return irq_de;
326 	}
327 	irq_se = platform_get_irq_byname(pdev, "SE");
328 	if (irq_se < 0) {
329 		DRM_ERROR("no 'SE' IRQ specified!\n");
330 		return irq_se;
331 	}
332 
333 	ret = malidp_de_irq_init(drm, irq_de);
334 	if (ret)
335 		return ret;
336 
337 	ret = malidp_se_irq_init(drm, irq_se);
338 	if (ret) {
339 		malidp_de_irq_fini(hwdev);
340 		return ret;
341 	}
342 
343 	return 0;
344 }
345 
346 DEFINE_DRM_GEM_CMA_FOPS(fops);
347 
malidp_dumb_create(struct drm_file * file_priv,struct drm_device * drm,struct drm_mode_create_dumb * args)348 static int malidp_dumb_create(struct drm_file *file_priv,
349 			      struct drm_device *drm,
350 			      struct drm_mode_create_dumb *args)
351 {
352 	struct malidp_drm *malidp = drm->dev_private;
353 	/* allocate for the worst case scenario, i.e. rotated buffers */
354 	u8 alignment = malidp_hw_get_pitch_align(malidp->dev, 1);
355 
356 	args->pitch = ALIGN(DIV_ROUND_UP(args->width * args->bpp, 8), alignment);
357 
358 	return drm_gem_cma_dumb_create_internal(file_priv, drm, args);
359 }
360 
361 #ifdef CONFIG_DEBUG_FS
362 
malidp_error_stats_init(struct malidp_error_stats * error_stats)363 static void malidp_error_stats_init(struct malidp_error_stats *error_stats)
364 {
365 	error_stats->num_errors = 0;
366 	error_stats->last_error_status = 0;
367 	error_stats->last_error_vblank = -1;
368 }
369 
malidp_error(struct malidp_drm * malidp,struct malidp_error_stats * error_stats,u32 status,u64 vblank)370 void malidp_error(struct malidp_drm *malidp,
371 		  struct malidp_error_stats *error_stats, u32 status,
372 		  u64 vblank)
373 {
374 	unsigned long irqflags;
375 
376 	spin_lock_irqsave(&malidp->errors_lock, irqflags);
377 	error_stats->last_error_status = status;
378 	error_stats->last_error_vblank = vblank;
379 	error_stats->num_errors++;
380 	spin_unlock_irqrestore(&malidp->errors_lock, irqflags);
381 }
382 
malidp_error_stats_dump(const char * prefix,struct malidp_error_stats error_stats,struct seq_file * m)383 void malidp_error_stats_dump(const char *prefix,
384 			     struct malidp_error_stats error_stats,
385 			     struct seq_file *m)
386 {
387 	seq_printf(m, "[%s] num_errors : %d\n", prefix,
388 		   error_stats.num_errors);
389 	seq_printf(m, "[%s] last_error_status  : 0x%08x\n", prefix,
390 		   error_stats.last_error_status);
391 	seq_printf(m, "[%s] last_error_vblank : %lld\n", prefix,
392 		   error_stats.last_error_vblank);
393 }
394 
malidp_show_stats(struct seq_file * m,void * arg)395 static int malidp_show_stats(struct seq_file *m, void *arg)
396 {
397 	struct drm_device *drm = m->private;
398 	struct malidp_drm *malidp = drm->dev_private;
399 	unsigned long irqflags;
400 	struct malidp_error_stats de_errors, se_errors;
401 
402 	spin_lock_irqsave(&malidp->errors_lock, irqflags);
403 	de_errors = malidp->de_errors;
404 	se_errors = malidp->se_errors;
405 	spin_unlock_irqrestore(&malidp->errors_lock, irqflags);
406 	malidp_error_stats_dump("DE", de_errors, m);
407 	malidp_error_stats_dump("SE", se_errors, m);
408 	return 0;
409 }
410 
malidp_debugfs_open(struct inode * inode,struct file * file)411 static int malidp_debugfs_open(struct inode *inode, struct file *file)
412 {
413 	return single_open(file, malidp_show_stats, inode->i_private);
414 }
415 
malidp_debugfs_write(struct file * file,const char __user * ubuf,size_t len,loff_t * offp)416 static ssize_t malidp_debugfs_write(struct file *file, const char __user *ubuf,
417 				    size_t len, loff_t *offp)
418 {
419 	struct seq_file *m = file->private_data;
420 	struct drm_device *drm = m->private;
421 	struct malidp_drm *malidp = drm->dev_private;
422 	unsigned long irqflags;
423 
424 	spin_lock_irqsave(&malidp->errors_lock, irqflags);
425 	malidp_error_stats_init(&malidp->de_errors);
426 	malidp_error_stats_init(&malidp->se_errors);
427 	spin_unlock_irqrestore(&malidp->errors_lock, irqflags);
428 	return len;
429 }
430 
431 static const struct file_operations malidp_debugfs_fops = {
432 	.owner = THIS_MODULE,
433 	.open = malidp_debugfs_open,
434 	.read = seq_read,
435 	.write = malidp_debugfs_write,
436 	.llseek = seq_lseek,
437 	.release = single_release,
438 };
439 
malidp_debugfs_init(struct drm_minor * minor)440 static int malidp_debugfs_init(struct drm_minor *minor)
441 {
442 	struct malidp_drm *malidp = minor->dev->dev_private;
443 	struct dentry *dentry = NULL;
444 
445 	malidp_error_stats_init(&malidp->de_errors);
446 	malidp_error_stats_init(&malidp->se_errors);
447 	spin_lock_init(&malidp->errors_lock);
448 	dentry = debugfs_create_file("debug",
449 				     S_IRUGO | S_IWUSR,
450 				     minor->debugfs_root, minor->dev,
451 				     &malidp_debugfs_fops);
452 	if (!dentry) {
453 		DRM_ERROR("Cannot create debug file\n");
454 		return -ENOMEM;
455 	}
456 	return 0;
457 }
458 
459 #endif //CONFIG_DEBUG_FS
460 
461 static struct drm_driver malidp_driver = {
462 	.driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC |
463 			   DRIVER_PRIME,
464 	.lastclose = drm_fb_helper_lastclose,
465 	.gem_free_object_unlocked = drm_gem_cma_free_object,
466 	.gem_vm_ops = &drm_gem_cma_vm_ops,
467 	.dumb_create = malidp_dumb_create,
468 	.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
469 	.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
470 	.gem_prime_export = drm_gem_prime_export,
471 	.gem_prime_import = drm_gem_prime_import,
472 	.gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table,
473 	.gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table,
474 	.gem_prime_vmap = drm_gem_cma_prime_vmap,
475 	.gem_prime_vunmap = drm_gem_cma_prime_vunmap,
476 	.gem_prime_mmap = drm_gem_cma_prime_mmap,
477 #ifdef CONFIG_DEBUG_FS
478 	.debugfs_init = malidp_debugfs_init,
479 #endif
480 	.fops = &fops,
481 	.name = "mali-dp",
482 	.desc = "ARM Mali Display Processor driver",
483 	.date = "20160106",
484 	.major = 1,
485 	.minor = 0,
486 };
487 
488 static const struct of_device_id  malidp_drm_of_match[] = {
489 	{
490 		.compatible = "arm,mali-dp500",
491 		.data = &malidp_device[MALIDP_500]
492 	},
493 	{
494 		.compatible = "arm,mali-dp550",
495 		.data = &malidp_device[MALIDP_550]
496 	},
497 	{
498 		.compatible = "arm,mali-dp650",
499 		.data = &malidp_device[MALIDP_650]
500 	},
501 	{},
502 };
503 MODULE_DEVICE_TABLE(of, malidp_drm_of_match);
504 
malidp_is_compatible_hw_id(struct malidp_hw_device * hwdev,const struct of_device_id * dev_id)505 static bool malidp_is_compatible_hw_id(struct malidp_hw_device *hwdev,
506 				       const struct of_device_id *dev_id)
507 {
508 	u32 core_id;
509 	const char *compatstr_dp500 = "arm,mali-dp500";
510 	bool is_dp500;
511 	bool dt_is_dp500;
512 
513 	/*
514 	 * The DP500 CORE_ID register is in a different location, so check it
515 	 * first. If the product id field matches, then this is DP500, otherwise
516 	 * check the DP550/650 CORE_ID register.
517 	 */
518 	core_id = malidp_hw_read(hwdev, MALIDP500_DC_BASE + MALIDP_DE_CORE_ID);
519 	/* Offset 0x18 will never read 0x500 on products other than DP500. */
520 	is_dp500 = (MALIDP_PRODUCT_ID(core_id) == 0x500);
521 	dt_is_dp500 = strnstr(dev_id->compatible, compatstr_dp500,
522 			      sizeof(dev_id->compatible)) != NULL;
523 	if (is_dp500 != dt_is_dp500) {
524 		DRM_ERROR("Device-tree expects %s, but hardware %s DP500.\n",
525 			  dev_id->compatible, is_dp500 ? "is" : "is not");
526 		return false;
527 	} else if (!dt_is_dp500) {
528 		u16 product_id;
529 		char buf[32];
530 
531 		core_id = malidp_hw_read(hwdev,
532 					 MALIDP550_DC_BASE + MALIDP_DE_CORE_ID);
533 		product_id = MALIDP_PRODUCT_ID(core_id);
534 		snprintf(buf, sizeof(buf), "arm,mali-dp%X", product_id);
535 		if (!strnstr(dev_id->compatible, buf,
536 			     sizeof(dev_id->compatible))) {
537 			DRM_ERROR("Device-tree expects %s, but hardware is DP%03X.\n",
538 				  dev_id->compatible, product_id);
539 			return false;
540 		}
541 	}
542 	return true;
543 }
544 
malidp_has_sufficient_address_space(const struct resource * res,const struct of_device_id * dev_id)545 static bool malidp_has_sufficient_address_space(const struct resource *res,
546 						const struct of_device_id *dev_id)
547 {
548 	resource_size_t res_size = resource_size(res);
549 	const char *compatstr_dp500 = "arm,mali-dp500";
550 
551 	if (!strnstr(dev_id->compatible, compatstr_dp500,
552 		     sizeof(dev_id->compatible)))
553 		return res_size >= MALIDP550_ADDR_SPACE_SIZE;
554 	else if (res_size < MALIDP500_ADDR_SPACE_SIZE)
555 		return false;
556 	return true;
557 }
558 
core_id_show(struct device * dev,struct device_attribute * attr,char * buf)559 static ssize_t core_id_show(struct device *dev, struct device_attribute *attr,
560 			    char *buf)
561 {
562 	struct drm_device *drm = dev_get_drvdata(dev);
563 	struct malidp_drm *malidp = drm->dev_private;
564 
565 	return snprintf(buf, PAGE_SIZE, "%08x\n", malidp->core_id);
566 }
567 
568 DEVICE_ATTR_RO(core_id);
569 
malidp_init_sysfs(struct device * dev)570 static int malidp_init_sysfs(struct device *dev)
571 {
572 	int ret = device_create_file(dev, &dev_attr_core_id);
573 
574 	if (ret)
575 		DRM_ERROR("failed to create device file for core_id\n");
576 
577 	return ret;
578 }
579 
malidp_fini_sysfs(struct device * dev)580 static void malidp_fini_sysfs(struct device *dev)
581 {
582 	device_remove_file(dev, &dev_attr_core_id);
583 }
584 
585 #define MAX_OUTPUT_CHANNELS	3
586 
malidp_runtime_pm_suspend(struct device * dev)587 static int malidp_runtime_pm_suspend(struct device *dev)
588 {
589 	struct drm_device *drm = dev_get_drvdata(dev);
590 	struct malidp_drm *malidp = drm->dev_private;
591 	struct malidp_hw_device *hwdev = malidp->dev;
592 
593 	/* we can only suspend if the hardware is in config mode */
594 	WARN_ON(!hwdev->hw->in_config_mode(hwdev));
595 
596 	malidp_se_irq_fini(hwdev);
597 	malidp_de_irq_fini(hwdev);
598 	hwdev->pm_suspended = true;
599 	clk_disable_unprepare(hwdev->mclk);
600 	clk_disable_unprepare(hwdev->aclk);
601 	clk_disable_unprepare(hwdev->pclk);
602 
603 	return 0;
604 }
605 
malidp_runtime_pm_resume(struct device * dev)606 static int malidp_runtime_pm_resume(struct device *dev)
607 {
608 	struct drm_device *drm = dev_get_drvdata(dev);
609 	struct malidp_drm *malidp = drm->dev_private;
610 	struct malidp_hw_device *hwdev = malidp->dev;
611 
612 	clk_prepare_enable(hwdev->pclk);
613 	clk_prepare_enable(hwdev->aclk);
614 	clk_prepare_enable(hwdev->mclk);
615 	hwdev->pm_suspended = false;
616 	malidp_de_irq_hw_init(hwdev);
617 	malidp_se_irq_hw_init(hwdev);
618 
619 	return 0;
620 }
621 
malidp_bind(struct device * dev)622 static int malidp_bind(struct device *dev)
623 {
624 	struct resource *res;
625 	struct drm_device *drm;
626 	struct malidp_drm *malidp;
627 	struct malidp_hw_device *hwdev;
628 	struct platform_device *pdev = to_platform_device(dev);
629 	struct of_device_id const *dev_id;
630 	struct drm_encoder *encoder;
631 	/* number of lines for the R, G and B output */
632 	u8 output_width[MAX_OUTPUT_CHANNELS];
633 	int ret = 0, i;
634 	u32 version, out_depth = 0;
635 
636 	malidp = devm_kzalloc(dev, sizeof(*malidp), GFP_KERNEL);
637 	if (!malidp)
638 		return -ENOMEM;
639 
640 	hwdev = devm_kzalloc(dev, sizeof(*hwdev), GFP_KERNEL);
641 	if (!hwdev)
642 		return -ENOMEM;
643 
644 	hwdev->hw = (struct malidp_hw *)of_device_get_match_data(dev);
645 	malidp->dev = hwdev;
646 
647 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
648 	hwdev->regs = devm_ioremap_resource(dev, res);
649 	if (IS_ERR(hwdev->regs))
650 		return PTR_ERR(hwdev->regs);
651 
652 	hwdev->pclk = devm_clk_get(dev, "pclk");
653 	if (IS_ERR(hwdev->pclk))
654 		return PTR_ERR(hwdev->pclk);
655 
656 	hwdev->aclk = devm_clk_get(dev, "aclk");
657 	if (IS_ERR(hwdev->aclk))
658 		return PTR_ERR(hwdev->aclk);
659 
660 	hwdev->mclk = devm_clk_get(dev, "mclk");
661 	if (IS_ERR(hwdev->mclk))
662 		return PTR_ERR(hwdev->mclk);
663 
664 	hwdev->pxlclk = devm_clk_get(dev, "pxlclk");
665 	if (IS_ERR(hwdev->pxlclk))
666 		return PTR_ERR(hwdev->pxlclk);
667 
668 	/* Get the optional framebuffer memory resource */
669 	ret = of_reserved_mem_device_init(dev);
670 	if (ret && ret != -ENODEV)
671 		return ret;
672 
673 	drm = drm_dev_alloc(&malidp_driver, dev);
674 	if (IS_ERR(drm)) {
675 		ret = PTR_ERR(drm);
676 		goto alloc_fail;
677 	}
678 
679 	drm->dev_private = malidp;
680 	dev_set_drvdata(dev, drm);
681 
682 	/* Enable power management */
683 	pm_runtime_enable(dev);
684 
685 	/* Resume device to enable the clocks */
686 	if (pm_runtime_enabled(dev))
687 		pm_runtime_get_sync(dev);
688 	else
689 		malidp_runtime_pm_resume(dev);
690 
691 	dev_id = of_match_device(malidp_drm_of_match, dev);
692 	if (!dev_id) {
693 		ret = -EINVAL;
694 		goto query_hw_fail;
695 	}
696 
697 	if (!malidp_has_sufficient_address_space(res, dev_id)) {
698 		DRM_ERROR("Insufficient address space in device-tree.\n");
699 		ret = -EINVAL;
700 		goto query_hw_fail;
701 	}
702 
703 	if (!malidp_is_compatible_hw_id(hwdev, dev_id)) {
704 		ret = -EINVAL;
705 		goto query_hw_fail;
706 	}
707 
708 	ret = hwdev->hw->query_hw(hwdev);
709 	if (ret) {
710 		DRM_ERROR("Invalid HW configuration\n");
711 		goto query_hw_fail;
712 	}
713 
714 	version = malidp_hw_read(hwdev, hwdev->hw->map.dc_base + MALIDP_DE_CORE_ID);
715 	DRM_INFO("found ARM Mali-DP%3x version r%dp%d\n", version >> 16,
716 		 (version >> 12) & 0xf, (version >> 8) & 0xf);
717 
718 	malidp->core_id = version;
719 
720 	/* set the number of lines used for output of RGB data */
721 	ret = of_property_read_u8_array(dev->of_node,
722 					"arm,malidp-output-port-lines",
723 					output_width, MAX_OUTPUT_CHANNELS);
724 	if (ret)
725 		goto query_hw_fail;
726 
727 	for (i = 0; i < MAX_OUTPUT_CHANNELS; i++)
728 		out_depth = (out_depth << 8) | (output_width[i] & 0xf);
729 	malidp_hw_write(hwdev, out_depth, hwdev->hw->map.out_depth_base);
730 	hwdev->output_color_depth = out_depth;
731 
732 	atomic_set(&malidp->config_valid, MALIDP_CONFIG_VALID_INIT);
733 	init_waitqueue_head(&malidp->wq);
734 
735 	ret = malidp_init(drm);
736 	if (ret < 0)
737 		goto query_hw_fail;
738 
739 	ret = malidp_init_sysfs(dev);
740 	if (ret)
741 		goto init_fail;
742 
743 	/* Set the CRTC's port so that the encoder component can find it */
744 	malidp->crtc.port = of_graph_get_port_by_id(dev->of_node, 0);
745 
746 	ret = component_bind_all(dev, drm);
747 	if (ret) {
748 		DRM_ERROR("Failed to bind all components\n");
749 		goto bind_fail;
750 	}
751 
752 	/* We expect to have a maximum of two encoders one for the actual
753 	 * display and a virtual one for the writeback connector
754 	 */
755 	WARN_ON(drm->mode_config.num_encoder > 2);
756 	list_for_each_entry(encoder, &drm->mode_config.encoder_list, head) {
757 		encoder->possible_clones =
758 				(1 << drm->mode_config.num_encoder) -  1;
759 	}
760 
761 	ret = malidp_irq_init(pdev);
762 	if (ret < 0)
763 		goto irq_init_fail;
764 
765 	drm->irq_enabled = true;
766 
767 	ret = drm_vblank_init(drm, drm->mode_config.num_crtc);
768 	drm_crtc_vblank_reset(&malidp->crtc);
769 	if (ret < 0) {
770 		DRM_ERROR("failed to initialise vblank\n");
771 		goto vblank_fail;
772 	}
773 	pm_runtime_put(dev);
774 
775 	drm_mode_config_reset(drm);
776 
777 	ret = drm_fb_cma_fbdev_init(drm, 32, 0);
778 	if (ret)
779 		goto fbdev_fail;
780 
781 	drm_kms_helper_poll_init(drm);
782 
783 	ret = drm_dev_register(drm, 0);
784 	if (ret)
785 		goto register_fail;
786 
787 	return 0;
788 
789 register_fail:
790 	drm_fb_cma_fbdev_fini(drm);
791 	drm_kms_helper_poll_fini(drm);
792 fbdev_fail:
793 	pm_runtime_get_sync(dev);
794 vblank_fail:
795 	malidp_se_irq_fini(hwdev);
796 	malidp_de_irq_fini(hwdev);
797 	drm->irq_enabled = false;
798 irq_init_fail:
799 	drm_atomic_helper_shutdown(drm);
800 	component_unbind_all(dev, drm);
801 bind_fail:
802 	of_node_put(malidp->crtc.port);
803 	malidp->crtc.port = NULL;
804 init_fail:
805 	malidp_fini_sysfs(dev);
806 	malidp_fini(drm);
807 query_hw_fail:
808 	pm_runtime_put(dev);
809 	if (pm_runtime_enabled(dev))
810 		pm_runtime_disable(dev);
811 	else
812 		malidp_runtime_pm_suspend(dev);
813 	drm->dev_private = NULL;
814 	dev_set_drvdata(dev, NULL);
815 	drm_dev_put(drm);
816 alloc_fail:
817 	of_reserved_mem_device_release(dev);
818 
819 	return ret;
820 }
821 
malidp_unbind(struct device * dev)822 static void malidp_unbind(struct device *dev)
823 {
824 	struct drm_device *drm = dev_get_drvdata(dev);
825 	struct malidp_drm *malidp = drm->dev_private;
826 	struct malidp_hw_device *hwdev = malidp->dev;
827 
828 	drm_dev_unregister(drm);
829 	drm_fb_cma_fbdev_fini(drm);
830 	drm_kms_helper_poll_fini(drm);
831 	pm_runtime_get_sync(dev);
832 	drm_crtc_vblank_off(&malidp->crtc);
833 	malidp_se_irq_fini(hwdev);
834 	malidp_de_irq_fini(hwdev);
835 	drm->irq_enabled = false;
836 	drm_atomic_helper_shutdown(drm);
837 	component_unbind_all(dev, drm);
838 	of_node_put(malidp->crtc.port);
839 	malidp->crtc.port = NULL;
840 	malidp_fini_sysfs(dev);
841 	malidp_fini(drm);
842 	pm_runtime_put(dev);
843 	if (pm_runtime_enabled(dev))
844 		pm_runtime_disable(dev);
845 	else
846 		malidp_runtime_pm_suspend(dev);
847 	drm->dev_private = NULL;
848 	dev_set_drvdata(dev, NULL);
849 	drm_dev_put(drm);
850 	of_reserved_mem_device_release(dev);
851 }
852 
853 static const struct component_master_ops malidp_master_ops = {
854 	.bind = malidp_bind,
855 	.unbind = malidp_unbind,
856 };
857 
malidp_compare_dev(struct device * dev,void * data)858 static int malidp_compare_dev(struct device *dev, void *data)
859 {
860 	struct device_node *np = data;
861 
862 	return dev->of_node == np;
863 }
864 
malidp_platform_probe(struct platform_device * pdev)865 static int malidp_platform_probe(struct platform_device *pdev)
866 {
867 	struct device_node *port;
868 	struct component_match *match = NULL;
869 
870 	if (!pdev->dev.of_node)
871 		return -ENODEV;
872 
873 	/* there is only one output port inside each device, find it */
874 	port = of_graph_get_remote_node(pdev->dev.of_node, 0, 0);
875 	if (!port)
876 		return -ENODEV;
877 
878 	drm_of_component_match_add(&pdev->dev, &match, malidp_compare_dev,
879 				   port);
880 	of_node_put(port);
881 	return component_master_add_with_match(&pdev->dev, &malidp_master_ops,
882 					       match);
883 }
884 
malidp_platform_remove(struct platform_device * pdev)885 static int malidp_platform_remove(struct platform_device *pdev)
886 {
887 	component_master_del(&pdev->dev, &malidp_master_ops);
888 	return 0;
889 }
890 
malidp_pm_suspend(struct device * dev)891 static int __maybe_unused malidp_pm_suspend(struct device *dev)
892 {
893 	struct drm_device *drm = dev_get_drvdata(dev);
894 
895 	return drm_mode_config_helper_suspend(drm);
896 }
897 
malidp_pm_resume(struct device * dev)898 static int __maybe_unused malidp_pm_resume(struct device *dev)
899 {
900 	struct drm_device *drm = dev_get_drvdata(dev);
901 
902 	drm_mode_config_helper_resume(drm);
903 
904 	return 0;
905 }
906 
malidp_pm_suspend_late(struct device * dev)907 static int __maybe_unused malidp_pm_suspend_late(struct device *dev)
908 {
909 	if (!pm_runtime_status_suspended(dev)) {
910 		malidp_runtime_pm_suspend(dev);
911 		pm_runtime_set_suspended(dev);
912 	}
913 	return 0;
914 }
915 
malidp_pm_resume_early(struct device * dev)916 static int __maybe_unused malidp_pm_resume_early(struct device *dev)
917 {
918 	malidp_runtime_pm_resume(dev);
919 	pm_runtime_set_active(dev);
920 	return 0;
921 }
922 
923 static const struct dev_pm_ops malidp_pm_ops = {
924 	SET_SYSTEM_SLEEP_PM_OPS(malidp_pm_suspend, malidp_pm_resume) \
925 	SET_LATE_SYSTEM_SLEEP_PM_OPS(malidp_pm_suspend_late, malidp_pm_resume_early) \
926 	SET_RUNTIME_PM_OPS(malidp_runtime_pm_suspend, malidp_runtime_pm_resume, NULL)
927 };
928 
929 static struct platform_driver malidp_platform_driver = {
930 	.probe		= malidp_platform_probe,
931 	.remove		= malidp_platform_remove,
932 	.driver	= {
933 		.name = "mali-dp",
934 		.pm = &malidp_pm_ops,
935 		.of_match_table	= malidp_drm_of_match,
936 	},
937 };
938 
939 module_platform_driver(malidp_platform_driver);
940 
941 MODULE_AUTHOR("Liviu Dudau <Liviu.Dudau@arm.com>");
942 MODULE_DESCRIPTION("ARM Mali DP DRM driver");
943 MODULE_LICENSE("GPL v2");
944