1 // SPDX-License-Identifier: GPL-2.0-only
3 * (C) COPYRIGHT 2012-2013 ARM Limited. All rights reserved.
5 * Parts of this file were based on sources as follows:
7 * Copyright (c) 2006-2008 Intel Corporation
8 * Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
9 * Copyright (C) 2011 Texas Instruments
13 * DOC: ARM PrimeCell PL111 CLCD Driver
15 * The PL111 is a simple LCD controller that can support TFT and STN
16 * displays. This driver exposes a standard KMS interface for them.
18 * This driver uses the same Device Tree binding as the fbdev CLCD
19 * driver. While the fbdev driver supports panels that may be
20 * connected to the CLCD internally to the CLCD driver, in DRM the
21 * panels get split out to drivers/gpu/drm/panels/. This means that,
22 * in converting from using fbdev to using DRM, you also need to write
23 * a panel driver (which may be as simple as an entry in
26 * The driver currently doesn't expose the cursor. The DRM API for
27 * cursors requires support for 64x64 ARGB8888 cursor images, while
28 * the hardware can only support 64x64 monochrome with masking
29 * cursors. While one could imagine trying to hack something together
30 * to look at the ARGB8888 and program reasonable in monochrome, we
31 * just don't expose the cursor at all instead, and leave cursor
32 * support to the X11 software cursor layer.
36 * - Fix race between setting plane base address and getting IRQ for
37 * vsync firing the pageflip completion.
39 * - Use the "max-memory-bandwidth" DT property to filter the
42 * - Read back hardware state at boot to skip reprogramming the
43 * hardware when doing a no-op modeset.
45 * - Use the CLKSEL bit to support switching between the two external
49 #include <linux/amba/bus.h>
50 #include <linux/amba/clcd-regs.h>
51 #include <linux/dma-buf.h>
52 #include <linux/module.h>
54 #include <linux/of_graph.h>
55 #include <linux/of_reserved_mem.h>
56 #include <linux/shmem_fs.h>
57 #include <linux/slab.h>
58 #include <linux/version.h>
60 #include <drm/drm_atomic_helper.h>
61 #include <drm/drm_bridge.h>
62 #include <drm/drm_drv.h>
63 #include <drm/drm_fb_cma_helper.h>
64 #include <drm/drm_fb_helper.h>
65 #include <drm/drm_gem_cma_helper.h>
66 #include <drm/drm_gem_framebuffer_helper.h>
67 #include <drm/drm_of.h>
68 #include <drm/drm_panel.h>
69 #include <drm/drm_probe_helper.h>
70 #include <drm/drm_vblank.h>
72 #include "pl111_drm.h"
73 #include "pl111_versatile.h"
74 #include "pl111_nomadik.h"
76 #define DRIVER_DESC "DRM module for PL111"
78 static const struct drm_mode_config_funcs mode_config_funcs
= {
79 .fb_create
= drm_gem_fb_create
,
80 .atomic_check
= drm_atomic_helper_check
,
81 .atomic_commit
= drm_atomic_helper_commit
,
84 static int pl111_modeset_init(struct drm_device
*dev
)
86 struct drm_mode_config
*mode_config
;
87 struct pl111_drm_dev_private
*priv
= dev
->dev_private
;
88 struct device_node
*np
= dev
->dev
->of_node
;
89 struct device_node
*remote
;
90 struct drm_panel
*panel
= NULL
;
91 struct drm_bridge
*bridge
= NULL
;
96 drm_mode_config_init(dev
);
97 mode_config
= &dev
->mode_config
;
98 mode_config
->funcs
= &mode_config_funcs
;
99 mode_config
->min_width
= 1;
100 mode_config
->max_width
= 1024;
101 mode_config
->min_height
= 1;
102 mode_config
->max_height
= 768;
105 for_each_endpoint_of_node(np
, remote
) {
106 struct drm_panel
*tmp_panel
;
107 struct drm_bridge
*tmp_bridge
;
109 dev_dbg(dev
->dev
, "checking endpoint %d\n", i
);
111 ret
= drm_of_find_panel_or_bridge(dev
->dev
->of_node
,
116 if (ret
== -EPROBE_DEFER
) {
118 * Something deferred, but that is often just
119 * another way of saying -ENODEV, but let's
120 * cast a vote for later deferral.
123 } else if (ret
!= -ENODEV
) {
124 /* Continue, maybe something else is working */
126 "endpoint %d returns %d\n", i
, ret
);
132 "found panel on endpoint %d\n", i
);
137 "found bridge on endpoint %d\n", i
);
145 * If we can't find neither panel nor bridge on any of the
146 * endpoints, and any of them retured -EPROBE_DEFER, then
147 * let's defer this driver too.
149 if ((!panel
&& !bridge
) && defer
)
150 return -EPROBE_DEFER
;
153 bridge
= drm_panel_bridge_add_typed(panel
,
154 DRM_MODE_CONNECTOR_Unknown
);
155 if (IS_ERR(bridge
)) {
156 ret
= PTR_ERR(bridge
);
160 dev_info(dev
->dev
, "Using non-panel bridge\n");
162 dev_err(dev
->dev
, "No bridge, exiting\n");
166 priv
->bridge
= bridge
;
169 priv
->connector
= drm_panel_bridge_connector(bridge
);
172 ret
= pl111_display_init(dev
);
174 dev_err(dev
->dev
, "Failed to init display\n");
178 ret
= drm_simple_display_pipe_attach_bridge(&priv
->pipe
,
183 if (!priv
->variant
->broken_vblank
) {
184 ret
= drm_vblank_init(dev
, 1);
186 dev_err(dev
->dev
, "Failed to init vblank\n");
191 drm_mode_config_reset(dev
);
193 drm_kms_helper_poll_init(dev
);
199 drm_panel_bridge_remove(bridge
);
201 drm_mode_config_cleanup(dev
);
206 static struct drm_gem_object
*
207 pl111_gem_import_sg_table(struct drm_device
*dev
,
208 struct dma_buf_attachment
*attach
,
209 struct sg_table
*sgt
)
211 struct pl111_drm_dev_private
*priv
= dev
->dev_private
;
214 * When using device-specific reserved memory we can't import
215 * DMA buffers: those are passed by reference in any global
216 * memory and we can only handle a specific range of memory.
218 if (priv
->use_device_memory
)
219 return ERR_PTR(-EINVAL
);
221 return drm_gem_cma_prime_import_sg_table(dev
, attach
, sgt
);
224 DEFINE_DRM_GEM_CMA_FOPS(drm_fops
);
226 static struct drm_driver pl111_drm_driver
= {
228 DRIVER_MODESET
| DRIVER_GEM
| DRIVER_ATOMIC
,
237 .dumb_create
= drm_gem_cma_dumb_create
,
238 .gem_free_object_unlocked
= drm_gem_cma_free_object
,
239 .gem_vm_ops
= &drm_gem_cma_vm_ops
,
240 .prime_handle_to_fd
= drm_gem_prime_handle_to_fd
,
241 .prime_fd_to_handle
= drm_gem_prime_fd_to_handle
,
242 .gem_prime_import_sg_table
= pl111_gem_import_sg_table
,
243 .gem_prime_get_sg_table
= drm_gem_cma_prime_get_sg_table
,
244 .gem_prime_mmap
= drm_gem_cma_prime_mmap
,
245 .gem_prime_vmap
= drm_gem_cma_prime_vmap
,
247 #if defined(CONFIG_DEBUG_FS)
248 .debugfs_init
= pl111_debugfs_init
,
252 static int pl111_amba_probe(struct amba_device
*amba_dev
,
253 const struct amba_id
*id
)
255 struct device
*dev
= &amba_dev
->dev
;
256 struct pl111_drm_dev_private
*priv
;
257 const struct pl111_variant_data
*variant
= id
->data
;
258 struct drm_device
*drm
;
261 priv
= devm_kzalloc(dev
, sizeof(*priv
), GFP_KERNEL
);
265 drm
= drm_dev_alloc(&pl111_drm_driver
, dev
);
268 amba_set_drvdata(amba_dev
, drm
);
270 drm
->dev_private
= priv
;
271 priv
->variant
= variant
;
273 ret
= of_reserved_mem_device_init(dev
);
275 dev_info(dev
, "using device-specific reserved memory\n");
276 priv
->use_device_memory
= true;
279 if (of_property_read_u32(dev
->of_node
, "max-memory-bandwidth",
281 dev_info(dev
, "no max memory bandwidth specified, assume unlimited\n");
285 /* The two main variants swap this register */
286 if (variant
->is_pl110
|| variant
->is_lcdc
) {
287 priv
->ienb
= CLCD_PL110_IENB
;
288 priv
->ctrl
= CLCD_PL110_CNTL
;
290 priv
->ienb
= CLCD_PL111_IENB
;
291 priv
->ctrl
= CLCD_PL111_CNTL
;
294 priv
->regs
= devm_ioremap_resource(dev
, &amba_dev
->res
);
295 if (IS_ERR(priv
->regs
)) {
296 dev_err(dev
, "%s failed mmio\n", __func__
);
297 ret
= PTR_ERR(priv
->regs
);
301 /* This may override some variant settings */
302 ret
= pl111_versatile_init(dev
, priv
);
306 pl111_nomadik_init(dev
);
308 /* turn off interrupts before requesting the irq */
309 writel(0, priv
->regs
+ priv
->ienb
);
311 ret
= devm_request_irq(dev
, amba_dev
->irq
[0], pl111_irq
, 0,
312 variant
->name
, priv
);
314 dev_err(dev
, "%s failed irq %d\n", __func__
, ret
);
318 ret
= pl111_modeset_init(drm
);
322 ret
= drm_dev_register(drm
, 0);
326 drm_fbdev_generic_setup(drm
, priv
->variant
->fb_bpp
);
332 of_reserved_mem_device_release(dev
);
337 static int pl111_amba_remove(struct amba_device
*amba_dev
)
339 struct device
*dev
= &amba_dev
->dev
;
340 struct drm_device
*drm
= amba_get_drvdata(amba_dev
);
341 struct pl111_drm_dev_private
*priv
= drm
->dev_private
;
343 drm_dev_unregister(drm
);
345 drm_panel_bridge_remove(priv
->bridge
);
346 drm_mode_config_cleanup(drm
);
348 of_reserved_mem_device_release(dev
);
354 * This early variant lacks the 565 and 444 pixel formats.
356 static const u32 pl110_pixel_formats
[] = {
367 static const struct pl111_variant_data pl110_variant
= {
370 .formats
= pl110_pixel_formats
,
371 .nformats
= ARRAY_SIZE(pl110_pixel_formats
),
375 /* RealView, Versatile Express etc use this modern variant */
376 static const u32 pl111_pixel_formats
[] = {
393 static const struct pl111_variant_data pl111_variant
= {
395 .formats
= pl111_pixel_formats
,
396 .nformats
= ARRAY_SIZE(pl111_pixel_formats
),
400 static const u32 pl110_nomadik_pixel_formats
[] = {
419 static const struct pl111_variant_data pl110_nomadik_variant
= {
420 .name
= "LCDC (PL110 Nomadik)",
421 .formats
= pl110_nomadik_pixel_formats
,
422 .nformats
= ARRAY_SIZE(pl110_nomadik_pixel_formats
),
424 .st_bitmux_control
= true,
425 .broken_vblank
= true,
429 static const struct amba_id pl111_id_table
[] = {
433 .data
= (void *)&pl110_variant
,
438 .data
= (void *)&pl110_nomadik_variant
,
443 .data
= (void *)&pl111_variant
,
448 static struct amba_driver pl111_amba_driver __maybe_unused
= {
450 .name
= "drm-clcd-pl111",
452 .probe
= pl111_amba_probe
,
453 .remove
= pl111_amba_remove
,
454 .id_table
= pl111_id_table
,
457 #ifdef CONFIG_ARM_AMBA
458 module_amba_driver(pl111_amba_driver
);
461 MODULE_DESCRIPTION(DRIVER_DESC
);
462 MODULE_AUTHOR("ARM Ltd.");
463 MODULE_LICENSE("GPL");