2 * (C) COPYRIGHT 2012-2013 ARM Limited. All rights reserved.
4 * Parts of this file were based on sources as follows:
6 * Copyright (c) 2006-2008 Intel Corporation
7 * Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
8 * Copyright (C) 2011 Texas Instruments
10 * This program is free software and is provided to you under the terms of the
11 * GNU General Public License version 2 as published by the Free Software
12 * Foundation, and any use by you of this program is subject to the terms of
18 * DOC: ARM PrimeCell PL111 CLCD Driver
20 * The PL111 is a simple LCD controller that can support TFT and STN
21 * displays. This driver exposes a standard KMS interface for them.
23 * This driver uses the same Device Tree binding as the fbdev CLCD
24 * driver. While the fbdev driver supports panels that may be
25 * connected to the CLCD internally to the CLCD driver, in DRM the
26 * panels get split out to drivers/gpu/drm/panels/. This means that,
27 * in converting from using fbdev to using DRM, you also need to write
28 * a panel driver (which may be as simple as an entry in
31 * The driver currently doesn't expose the cursor. The DRM API for
32 * cursors requires support for 64x64 ARGB8888 cursor images, while
33 * the hardware can only support 64x64 monochrome with masking
34 * cursors. While one could imagine trying to hack something together
35 * to look at the ARGB8888 and program reasonable in monochrome, we
36 * just don't expose the cursor at all instead, and leave cursor
37 * support to the X11 software cursor layer.
41 * - Fix race between setting plane base address and getting IRQ for
42 * vsync firing the pageflip completion.
44 * - Use the "max-memory-bandwidth" DT property to filter the
47 * - Read back hardware state at boot to skip reprogramming the
48 * hardware when doing a no-op modeset.
50 * - Use the CLKSEL bit to support switching between the two external
54 #include <linux/amba/bus.h>
55 #include <linux/amba/clcd-regs.h>
56 #include <linux/version.h>
57 #include <linux/shmem_fs.h>
58 #include <linux/dma-buf.h>
59 #include <linux/module.h>
60 #include <linux/slab.h>
62 #include <linux/of_graph.h>
63 #include <linux/of_reserved_mem.h>
66 #include <drm/drm_atomic_helper.h>
67 #include <drm/drm_bridge.h>
68 #include <drm/drm_fb_cma_helper.h>
69 #include <drm/drm_fb_helper.h>
70 #include <drm/drm_gem_cma_helper.h>
71 #include <drm/drm_gem_framebuffer_helper.h>
72 #include <drm/drm_of.h>
73 #include <drm/drm_panel.h>
74 #include <drm/drm_probe_helper.h>
76 #include "pl111_drm.h"
77 #include "pl111_versatile.h"
78 #include "pl111_nomadik.h"
80 #define DRIVER_DESC "DRM module for PL111"
82 static const struct drm_mode_config_funcs mode_config_funcs
= {
83 .fb_create
= drm_gem_fb_create
,
84 .atomic_check
= drm_atomic_helper_check
,
85 .atomic_commit
= drm_atomic_helper_commit
,
88 static int pl111_modeset_init(struct drm_device
*dev
)
90 struct drm_mode_config
*mode_config
;
91 struct pl111_drm_dev_private
*priv
= dev
->dev_private
;
92 struct device_node
*np
= dev
->dev
->of_node
;
93 struct device_node
*remote
;
94 struct drm_panel
*panel
= NULL
;
95 struct drm_bridge
*bridge
= NULL
;
100 drm_mode_config_init(dev
);
101 mode_config
= &dev
->mode_config
;
102 mode_config
->funcs
= &mode_config_funcs
;
103 mode_config
->min_width
= 1;
104 mode_config
->max_width
= 1024;
105 mode_config
->min_height
= 1;
106 mode_config
->max_height
= 768;
109 for_each_endpoint_of_node(np
, remote
) {
110 struct drm_panel
*tmp_panel
;
111 struct drm_bridge
*tmp_bridge
;
113 dev_dbg(dev
->dev
, "checking endpoint %d\n", i
);
115 ret
= drm_of_find_panel_or_bridge(dev
->dev
->of_node
,
120 if (ret
== -EPROBE_DEFER
) {
122 * Something deferred, but that is often just
123 * another way of saying -ENODEV, but let's
124 * cast a vote for later deferral.
127 } else if (ret
!= -ENODEV
) {
128 /* Continue, maybe something else is working */
130 "endpoint %d returns %d\n", i
, ret
);
136 "found panel on endpoint %d\n", i
);
141 "found bridge on endpoint %d\n", i
);
149 * If we can't find neither panel nor bridge on any of the
150 * endpoints, and any of them retured -EPROBE_DEFER, then
151 * let's defer this driver too.
153 if ((!panel
&& !bridge
) && defer
)
154 return -EPROBE_DEFER
;
157 bridge
= drm_panel_bridge_add(panel
,
158 DRM_MODE_CONNECTOR_Unknown
);
159 if (IS_ERR(bridge
)) {
160 ret
= PTR_ERR(bridge
);
164 dev_info(dev
->dev
, "Using non-panel bridge\n");
166 dev_err(dev
->dev
, "No bridge, exiting\n");
170 priv
->bridge
= bridge
;
173 priv
->connector
= panel
->connector
;
176 ret
= pl111_display_init(dev
);
178 dev_err(dev
->dev
, "Failed to init display\n");
182 ret
= drm_simple_display_pipe_attach_bridge(&priv
->pipe
,
187 if (!priv
->variant
->broken_vblank
) {
188 ret
= drm_vblank_init(dev
, 1);
190 dev_err(dev
->dev
, "Failed to init vblank\n");
195 drm_mode_config_reset(dev
);
197 drm_kms_helper_poll_init(dev
);
203 drm_panel_bridge_remove(bridge
);
205 drm_mode_config_cleanup(dev
);
210 static struct drm_gem_object
*
211 pl111_gem_import_sg_table(struct drm_device
*dev
,
212 struct dma_buf_attachment
*attach
,
213 struct sg_table
*sgt
)
215 struct pl111_drm_dev_private
*priv
= dev
->dev_private
;
218 * When using device-specific reserved memory we can't import
219 * DMA buffers: those are passed by reference in any global
220 * memory and we can only handle a specific range of memory.
222 if (priv
->use_device_memory
)
223 return ERR_PTR(-EINVAL
);
225 return drm_gem_cma_prime_import_sg_table(dev
, attach
, sgt
);
228 DEFINE_DRM_GEM_CMA_FOPS(drm_fops
);
230 static struct drm_driver pl111_drm_driver
= {
232 DRIVER_MODESET
| DRIVER_GEM
| DRIVER_PRIME
| DRIVER_ATOMIC
,
241 .dumb_create
= drm_gem_cma_dumb_create
,
242 .gem_free_object_unlocked
= drm_gem_cma_free_object
,
243 .gem_vm_ops
= &drm_gem_cma_vm_ops
,
244 .prime_handle_to_fd
= drm_gem_prime_handle_to_fd
,
245 .prime_fd_to_handle
= drm_gem_prime_fd_to_handle
,
246 .gem_prime_import
= drm_gem_prime_import
,
247 .gem_prime_import_sg_table
= pl111_gem_import_sg_table
,
248 .gem_prime_export
= drm_gem_prime_export
,
249 .gem_prime_get_sg_table
= drm_gem_cma_prime_get_sg_table
,
250 .gem_prime_mmap
= drm_gem_cma_prime_mmap
,
251 .gem_prime_vmap
= drm_gem_cma_prime_vmap
,
253 #if defined(CONFIG_DEBUG_FS)
254 .debugfs_init
= pl111_debugfs_init
,
258 static int pl111_amba_probe(struct amba_device
*amba_dev
,
259 const struct amba_id
*id
)
261 struct device
*dev
= &amba_dev
->dev
;
262 struct pl111_drm_dev_private
*priv
;
263 const struct pl111_variant_data
*variant
= id
->data
;
264 struct drm_device
*drm
;
267 priv
= devm_kzalloc(dev
, sizeof(*priv
), GFP_KERNEL
);
271 drm
= drm_dev_alloc(&pl111_drm_driver
, dev
);
274 amba_set_drvdata(amba_dev
, drm
);
276 drm
->dev_private
= priv
;
277 priv
->variant
= variant
;
279 ret
= of_reserved_mem_device_init(dev
);
281 dev_info(dev
, "using device-specific reserved memory\n");
282 priv
->use_device_memory
= true;
285 if (of_property_read_u32(dev
->of_node
, "max-memory-bandwidth",
287 dev_info(dev
, "no max memory bandwidth specified, assume unlimited\n");
291 /* The two main variants swap this register */
292 if (variant
->is_pl110
|| variant
->is_lcdc
) {
293 priv
->ienb
= CLCD_PL110_IENB
;
294 priv
->ctrl
= CLCD_PL110_CNTL
;
296 priv
->ienb
= CLCD_PL111_IENB
;
297 priv
->ctrl
= CLCD_PL111_CNTL
;
300 priv
->regs
= devm_ioremap_resource(dev
, &amba_dev
->res
);
301 if (IS_ERR(priv
->regs
)) {
302 dev_err(dev
, "%s failed mmio\n", __func__
);
303 ret
= PTR_ERR(priv
->regs
);
307 /* This may override some variant settings */
308 ret
= pl111_versatile_init(dev
, priv
);
312 pl111_nomadik_init(dev
);
314 /* turn off interrupts before requesting the irq */
315 writel(0, priv
->regs
+ priv
->ienb
);
317 ret
= devm_request_irq(dev
, amba_dev
->irq
[0], pl111_irq
, 0,
318 variant
->name
, priv
);
320 dev_err(dev
, "%s failed irq %d\n", __func__
, ret
);
324 ret
= pl111_modeset_init(drm
);
328 ret
= drm_dev_register(drm
, 0);
332 drm_fbdev_generic_setup(drm
, priv
->variant
->fb_bpp
);
338 of_reserved_mem_device_release(dev
);
343 static int pl111_amba_remove(struct amba_device
*amba_dev
)
345 struct device
*dev
= &amba_dev
->dev
;
346 struct drm_device
*drm
= amba_get_drvdata(amba_dev
);
347 struct pl111_drm_dev_private
*priv
= drm
->dev_private
;
349 drm_dev_unregister(drm
);
351 drm_panel_bridge_remove(priv
->bridge
);
352 drm_mode_config_cleanup(drm
);
354 of_reserved_mem_device_release(dev
);
360 * This early variant lacks the 565 and 444 pixel formats.
362 static const u32 pl110_pixel_formats
[] = {
373 static const struct pl111_variant_data pl110_variant
= {
376 .formats
= pl110_pixel_formats
,
377 .nformats
= ARRAY_SIZE(pl110_pixel_formats
),
381 /* RealView, Versatile Express etc use this modern variant */
382 static const u32 pl111_pixel_formats
[] = {
399 static const struct pl111_variant_data pl111_variant
= {
401 .formats
= pl111_pixel_formats
,
402 .nformats
= ARRAY_SIZE(pl111_pixel_formats
),
406 static const u32 pl110_nomadik_pixel_formats
[] = {
425 static const struct pl111_variant_data pl110_nomadik_variant
= {
426 .name
= "LCDC (PL110 Nomadik)",
427 .formats
= pl110_nomadik_pixel_formats
,
428 .nformats
= ARRAY_SIZE(pl110_nomadik_pixel_formats
),
430 .st_bitmux_control
= true,
431 .broken_vblank
= true,
435 static const struct amba_id pl111_id_table
[] = {
439 .data
= (void *)&pl110_variant
,
444 .data
= (void *)&pl110_nomadik_variant
,
449 .data
= (void *)&pl111_variant
,
454 static struct amba_driver pl111_amba_driver __maybe_unused
= {
456 .name
= "drm-clcd-pl111",
458 .probe
= pl111_amba_probe
,
459 .remove
= pl111_amba_remove
,
460 .id_table
= pl111_id_table
,
463 #ifdef CONFIG_ARM_AMBA
464 module_amba_driver(pl111_amba_driver
);
467 MODULE_DESCRIPTION(DRIVER_DESC
);
468 MODULE_AUTHOR("ARM Ltd.");
469 MODULE_LICENSE("GPL");