1 /*
2  * Copyright (C) 2012 Russell King
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  */
8 #include <linux/clk.h>
9 #include <linux/module.h>
10 #include <drm/drmP.h>
11 #include <drm/drm_crtc_helper.h>
12 #include "armada_crtc.h"
13 #include "armada_drm.h"
14 #include "armada_gem.h"
15 #include "armada_hw.h"
16 #include <drm/armada_drm.h>
17 #include "armada_ioctlP.h"
18 
19 #ifdef CONFIG_DRM_ARMADA_TDA1998X
20 #include <drm/i2c/tda998x.h>
21 #include "armada_slave.h"
22 
23 static struct tda998x_encoder_params params = {
24 	/* With 0x24, there is no translation between vp_out and int_vp
25 	FB	LCD out	Pins	VIP	Int Vp
26 	R:23:16	R:7:0	VPC7:0	7:0	7:0[R]
27 	G:15:8	G:15:8	VPB7:0	23:16	23:16[G]
28 	B:7:0	B:23:16	VPA7:0	15:8	15:8[B]
29 	*/
30 	.swap_a = 2,
31 	.swap_b = 3,
32 	.swap_c = 4,
33 	.swap_d = 5,
34 	.swap_e = 0,
35 	.swap_f = 1,
36 	.audio_cfg = BIT(2),
37 	.audio_frame[1] = 1,
38 	.audio_format = AFMT_SPDIF,
39 	.audio_sample_rate = 44100,
40 };
41 
42 static const struct armada_drm_slave_config tda19988_config = {
43 	.i2c_adapter_id = 0,
44 	.crtcs = 1 << 0, /* Only LCD0 at the moment */
45 	.polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT,
46 	.interlace_allowed = true,
47 	.info = {
48 		.type = "tda998x",
49 		.addr = 0x70,
50 		.platform_data = &params,
51 	},
52 };
53 #endif
54 
55 static void armada_drm_unref_work(struct work_struct *work)
56 {
57 	struct armada_private *priv =
58 		container_of(work, struct armada_private, fb_unref_work);
59 	struct drm_framebuffer *fb;
60 
61 	while (kfifo_get(&priv->fb_unref, &fb))
62 		drm_framebuffer_unreference(fb);
63 }
64 
65 /* Must be called with dev->event_lock held */
66 void __armada_drm_queue_unref_work(struct drm_device *dev,
67 	struct drm_framebuffer *fb)
68 {
69 	struct armada_private *priv = dev->dev_private;
70 
71 	WARN_ON(!kfifo_put(&priv->fb_unref, fb));
72 	schedule_work(&priv->fb_unref_work);
73 }
74 
75 void armada_drm_queue_unref_work(struct drm_device *dev,
76 	struct drm_framebuffer *fb)
77 {
78 	unsigned long flags;
79 
80 	spin_lock_irqsave(&dev->event_lock, flags);
81 	__armada_drm_queue_unref_work(dev, fb);
82 	spin_unlock_irqrestore(&dev->event_lock, flags);
83 }
84 
85 static int armada_drm_load(struct drm_device *dev, unsigned long flags)
86 {
87 	const struct platform_device_id *id;
88 	struct armada_private *priv;
89 	struct resource *res[ARRAY_SIZE(priv->dcrtc)];
90 	struct resource *mem = NULL;
91 	int ret, n, i;
92 
93 	memset(res, 0, sizeof(res));
94 
95 	for (n = i = 0; ; n++) {
96 		struct resource *r = platform_get_resource(dev->platformdev,
97 							   IORESOURCE_MEM, n);
98 		if (!r)
99 			break;
100 
101 		/* Resources above 64K are graphics memory */
102 		if (resource_size(r) > SZ_64K)
103 			mem = r;
104 		else if (i < ARRAY_SIZE(priv->dcrtc))
105 			res[i++] = r;
106 		else
107 			return -EINVAL;
108 	}
109 
110 	if (!res[0] || !mem)
111 		return -ENXIO;
112 
113 	if (!devm_request_mem_region(dev->dev, mem->start,
114 			resource_size(mem), "armada-drm"))
115 		return -EBUSY;
116 
117 	priv = devm_kzalloc(dev->dev, sizeof(*priv), GFP_KERNEL);
118 	if (!priv) {
119 		DRM_ERROR("failed to allocate private\n");
120 		return -ENOMEM;
121 	}
122 
123 	platform_set_drvdata(dev->platformdev, dev);
124 	dev->dev_private = priv;
125 
126 	/* Get the implementation specific driver data. */
127 	id = platform_get_device_id(dev->platformdev);
128 	if (!id)
129 		return -ENXIO;
130 
131 	priv->variant = (struct armada_variant *)id->driver_data;
132 
133 	ret = priv->variant->init(priv, dev->dev);
134 	if (ret)
135 		return ret;
136 
137 	INIT_WORK(&priv->fb_unref_work, armada_drm_unref_work);
138 	INIT_KFIFO(priv->fb_unref);
139 
140 	/* Mode setting support */
141 	drm_mode_config_init(dev);
142 	dev->mode_config.min_width = 320;
143 	dev->mode_config.min_height = 200;
144 
145 	/*
146 	 * With vscale enabled, the maximum width is 1920 due to the
147 	 * 1920 by 3 lines RAM
148 	 */
149 	dev->mode_config.max_width = 1920;
150 	dev->mode_config.max_height = 2048;
151 
152 	dev->mode_config.preferred_depth = 24;
153 	dev->mode_config.funcs = &armada_drm_mode_config_funcs;
154 	drm_mm_init(&priv->linear, mem->start, resource_size(mem));
155 
156 	/* Create all LCD controllers */
157 	for (n = 0; n < ARRAY_SIZE(priv->dcrtc); n++) {
158 		if (!res[n])
159 			break;
160 
161 		ret = armada_drm_crtc_create(dev, n, res[n]);
162 		if (ret)
163 			goto err_kms;
164 	}
165 
166 #ifdef CONFIG_DRM_ARMADA_TDA1998X
167 	ret = armada_drm_connector_slave_create(dev, &tda19988_config);
168 	if (ret)
169 		goto err_kms;
170 #endif
171 
172 	ret = drm_vblank_init(dev, n);
173 	if (ret)
174 		goto err_kms;
175 
176 	ret = drm_irq_install(dev, platform_get_irq(dev->platformdev, 0));
177 	if (ret)
178 		goto err_kms;
179 
180 	dev->vblank_disable_allowed = 1;
181 
182 	ret = armada_fbdev_init(dev);
183 	if (ret)
184 		goto err_irq;
185 
186 	drm_kms_helper_poll_init(dev);
187 
188 	return 0;
189 
190  err_irq:
191 	drm_irq_uninstall(dev);
192  err_kms:
193 	drm_mode_config_cleanup(dev);
194 	drm_mm_takedown(&priv->linear);
195 	flush_work(&priv->fb_unref_work);
196 
197 	return ret;
198 }
199 
200 static int armada_drm_unload(struct drm_device *dev)
201 {
202 	struct armada_private *priv = dev->dev_private;
203 
204 	drm_kms_helper_poll_fini(dev);
205 	armada_fbdev_fini(dev);
206 	drm_irq_uninstall(dev);
207 	drm_mode_config_cleanup(dev);
208 	drm_mm_takedown(&priv->linear);
209 	flush_work(&priv->fb_unref_work);
210 	dev->dev_private = NULL;
211 
212 	return 0;
213 }
214 
215 void armada_drm_vbl_event_add(struct armada_crtc *dcrtc,
216 	struct armada_vbl_event *evt)
217 {
218 	unsigned long flags;
219 
220 	spin_lock_irqsave(&dcrtc->irq_lock, flags);
221 	if (list_empty(&evt->node)) {
222 		list_add_tail(&evt->node, &dcrtc->vbl_list);
223 
224 		drm_vblank_get(dcrtc->crtc.dev, dcrtc->num);
225 	}
226 	spin_unlock_irqrestore(&dcrtc->irq_lock, flags);
227 }
228 
229 void armada_drm_vbl_event_remove(struct armada_crtc *dcrtc,
230 	struct armada_vbl_event *evt)
231 {
232 	if (!list_empty(&evt->node)) {
233 		list_del_init(&evt->node);
234 		drm_vblank_put(dcrtc->crtc.dev, dcrtc->num);
235 	}
236 }
237 
238 void armada_drm_vbl_event_remove_unlocked(struct armada_crtc *dcrtc,
239 	struct armada_vbl_event *evt)
240 {
241 	unsigned long flags;
242 
243 	spin_lock_irqsave(&dcrtc->irq_lock, flags);
244 	armada_drm_vbl_event_remove(dcrtc, evt);
245 	spin_unlock_irqrestore(&dcrtc->irq_lock, flags);
246 }
247 
248 /* These are called under the vbl_lock. */
249 static int armada_drm_enable_vblank(struct drm_device *dev, int crtc)
250 {
251 	struct armada_private *priv = dev->dev_private;
252 	armada_drm_crtc_enable_irq(priv->dcrtc[crtc], VSYNC_IRQ_ENA);
253 	return 0;
254 }
255 
256 static void armada_drm_disable_vblank(struct drm_device *dev, int crtc)
257 {
258 	struct armada_private *priv = dev->dev_private;
259 	armada_drm_crtc_disable_irq(priv->dcrtc[crtc], VSYNC_IRQ_ENA);
260 }
261 
262 static irqreturn_t armada_drm_irq_handler(int irq, void *arg)
263 {
264 	struct drm_device *dev = arg;
265 	struct armada_private *priv = dev->dev_private;
266 	struct armada_crtc *dcrtc = priv->dcrtc[0];
267 	uint32_t v, stat = readl_relaxed(dcrtc->base + LCD_SPU_IRQ_ISR);
268 	irqreturn_t handled = IRQ_NONE;
269 
270 	/*
271 	 * This is rediculous - rather than writing bits to clear, we
272 	 * have to set the actual status register value.  This is racy.
273 	 */
274 	writel_relaxed(0, dcrtc->base + LCD_SPU_IRQ_ISR);
275 
276 	/* Mask out those interrupts we haven't enabled */
277 	v = stat & dcrtc->irq_ena;
278 
279 	if (v & (VSYNC_IRQ|GRA_FRAME_IRQ|DUMB_FRAMEDONE)) {
280 		armada_drm_crtc_irq(dcrtc, stat);
281 		handled = IRQ_HANDLED;
282 	}
283 
284 	return handled;
285 }
286 
287 static int armada_drm_irq_postinstall(struct drm_device *dev)
288 {
289 	struct armada_private *priv = dev->dev_private;
290 	struct armada_crtc *dcrtc = priv->dcrtc[0];
291 
292 	spin_lock_irq(&dev->vbl_lock);
293 	writel_relaxed(dcrtc->irq_ena, dcrtc->base + LCD_SPU_IRQ_ENA);
294 	writel(0, dcrtc->base + LCD_SPU_IRQ_ISR);
295 	spin_unlock_irq(&dev->vbl_lock);
296 
297 	return 0;
298 }
299 
300 static void armada_drm_irq_uninstall(struct drm_device *dev)
301 {
302 	struct armada_private *priv = dev->dev_private;
303 	struct armada_crtc *dcrtc = priv->dcrtc[0];
304 
305 	writel(0, dcrtc->base + LCD_SPU_IRQ_ENA);
306 }
307 
308 static struct drm_ioctl_desc armada_ioctls[] = {
309 	DRM_IOCTL_DEF_DRV(ARMADA_GEM_CREATE, armada_gem_create_ioctl,
310 		DRM_UNLOCKED),
311 	DRM_IOCTL_DEF_DRV(ARMADA_GEM_MMAP, armada_gem_mmap_ioctl,
312 		DRM_UNLOCKED),
313 	DRM_IOCTL_DEF_DRV(ARMADA_GEM_PWRITE, armada_gem_pwrite_ioctl,
314 		DRM_UNLOCKED),
315 };
316 
317 static void armada_drm_lastclose(struct drm_device *dev)
318 {
319 	armada_fbdev_lastclose(dev);
320 }
321 
322 static const struct file_operations armada_drm_fops = {
323 	.owner			= THIS_MODULE,
324 	.llseek			= no_llseek,
325 	.read			= drm_read,
326 	.poll			= drm_poll,
327 	.unlocked_ioctl		= drm_ioctl,
328 	.mmap			= drm_gem_mmap,
329 	.open			= drm_open,
330 	.release		= drm_release,
331 };
332 
333 static struct drm_driver armada_drm_driver = {
334 	.load			= armada_drm_load,
335 	.open			= NULL,
336 	.preclose		= NULL,
337 	.postclose		= NULL,
338 	.lastclose		= armada_drm_lastclose,
339 	.unload			= armada_drm_unload,
340 	.get_vblank_counter	= drm_vblank_count,
341 	.enable_vblank		= armada_drm_enable_vblank,
342 	.disable_vblank		= armada_drm_disable_vblank,
343 	.irq_handler		= armada_drm_irq_handler,
344 	.irq_postinstall	= armada_drm_irq_postinstall,
345 	.irq_uninstall		= armada_drm_irq_uninstall,
346 #ifdef CONFIG_DEBUG_FS
347 	.debugfs_init		= armada_drm_debugfs_init,
348 	.debugfs_cleanup	= armada_drm_debugfs_cleanup,
349 #endif
350 	.gem_free_object	= armada_gem_free_object,
351 	.prime_handle_to_fd	= drm_gem_prime_handle_to_fd,
352 	.prime_fd_to_handle	= drm_gem_prime_fd_to_handle,
353 	.gem_prime_export	= armada_gem_prime_export,
354 	.gem_prime_import	= armada_gem_prime_import,
355 	.dumb_create		= armada_gem_dumb_create,
356 	.dumb_map_offset	= armada_gem_dumb_map_offset,
357 	.dumb_destroy		= armada_gem_dumb_destroy,
358 	.gem_vm_ops		= &armada_gem_vm_ops,
359 	.major			= 1,
360 	.minor			= 0,
361 	.name			= "armada-drm",
362 	.desc			= "Armada SoC DRM",
363 	.date			= "20120730",
364 	.driver_features	= DRIVER_GEM | DRIVER_MODESET |
365 				  DRIVER_HAVE_IRQ | DRIVER_PRIME,
366 	.ioctls			= armada_ioctls,
367 	.fops			= &armada_drm_fops,
368 };
369 
370 static int armada_drm_probe(struct platform_device *pdev)
371 {
372 	return drm_platform_init(&armada_drm_driver, pdev);
373 }
374 
375 static int armada_drm_remove(struct platform_device *pdev)
376 {
377 	drm_put_dev(platform_get_drvdata(pdev));
378 	return 0;
379 }
380 
381 static const struct platform_device_id armada_drm_platform_ids[] = {
382 	{
383 		.name		= "armada-drm",
384 		.driver_data	= (unsigned long)&armada510_ops,
385 	}, {
386 		.name		= "armada-510-drm",
387 		.driver_data	= (unsigned long)&armada510_ops,
388 	},
389 	{ },
390 };
391 MODULE_DEVICE_TABLE(platform, armada_drm_platform_ids);
392 
393 static struct platform_driver armada_drm_platform_driver = {
394 	.probe	= armada_drm_probe,
395 	.remove	= armada_drm_remove,
396 	.driver	= {
397 		.name	= "armada-drm",
398 		.owner	= THIS_MODULE,
399 	},
400 	.id_table = armada_drm_platform_ids,
401 };
402 
403 static int __init armada_drm_init(void)
404 {
405 	armada_drm_driver.num_ioctls = ARRAY_SIZE(armada_ioctls);
406 	return platform_driver_register(&armada_drm_platform_driver);
407 }
408 module_init(armada_drm_init);
409 
410 static void __exit armada_drm_exit(void)
411 {
412 	platform_driver_unregister(&armada_drm_platform_driver);
413 }
414 module_exit(armada_drm_exit);
415 
416 MODULE_AUTHOR("Russell King <rmk+kernel@arm.linux.org.uk>");
417 MODULE_DESCRIPTION("Armada DRM Driver");
418 MODULE_LICENSE("GPL");
419 MODULE_ALIAS("platform:armada-drm");
420