1// SPDX-License-Identifier: GPL-2.0-only
2
3#include <linux/aperture.h>
4#include <linux/of_address.h>
5#include <linux/pci.h>
6#include <linux/platform_device.h>
7
8#include <drm/clients/drm_client_setup.h>
9#include <drm/drm_atomic.h>
10#include <drm/drm_atomic_state_helper.h>
11#include <drm/drm_connector.h>
12#include <drm/drm_damage_helper.h>
13#include <drm/drm_device.h>
14#include <drm/drm_drv.h>
15#include <drm/drm_edid.h>
16#include <drm/drm_fbdev_shmem.h>
17#include <drm/drm_format_helper.h>
18#include <drm/drm_framebuffer.h>
19#include <drm/drm_gem_atomic_helper.h>
20#include <drm/drm_gem_framebuffer_helper.h>
21#include <drm/drm_gem_shmem_helper.h>
22#include <drm/drm_managed.h>
23#include <drm/drm_modeset_helper_vtables.h>
24#include <drm/drm_probe_helper.h>
25
26#include "drm_sysfb_helper.h"
27
28#define DRIVER_NAME "ofdrm"
29#define DRIVER_DESC "DRM driver for OF platform devices"
30#define DRIVER_MAJOR 1
31#define DRIVER_MINOR 0
32
33#define PCI_VENDOR_ID_ATI_R520 0x7100
34#define PCI_VENDOR_ID_ATI_R600 0x9400
35
36#define OFDRM_GAMMA_LUT_SIZE 256
37
38/* Definitions used by the Avivo palette */
39#define AVIVO_DC_LUT_RW_SELECT 0x6480
40#define AVIVO_DC_LUT_RW_MODE 0x6484
41#define AVIVO_DC_LUT_RW_INDEX 0x6488
42#define AVIVO_DC_LUT_SEQ_COLOR 0x648c
43#define AVIVO_DC_LUT_PWL_DATA 0x6490
44#define AVIVO_DC_LUT_30_COLOR 0x6494
45#define AVIVO_DC_LUT_READ_PIPE_SELECT 0x6498
46#define AVIVO_DC_LUT_WRITE_EN_MASK 0x649c
47#define AVIVO_DC_LUT_AUTOFILL 0x64a0
48#define AVIVO_DC_LUTA_CONTROL 0x64c0
49#define AVIVO_DC_LUTA_BLACK_OFFSET_BLUE 0x64c4
50#define AVIVO_DC_LUTA_BLACK_OFFSET_GREEN 0x64c8
51#define AVIVO_DC_LUTA_BLACK_OFFSET_RED 0x64cc
52#define AVIVO_DC_LUTA_WHITE_OFFSET_BLUE 0x64d0
53#define AVIVO_DC_LUTA_WHITE_OFFSET_GREEN 0x64d4
54#define AVIVO_DC_LUTA_WHITE_OFFSET_RED 0x64d8
55#define AVIVO_DC_LUTB_CONTROL 0x6cc0
56#define AVIVO_DC_LUTB_BLACK_OFFSET_BLUE 0x6cc4
57#define AVIVO_DC_LUTB_BLACK_OFFSET_GREEN 0x6cc8
58#define AVIVO_DC_LUTB_BLACK_OFFSET_RED 0x6ccc
59#define AVIVO_DC_LUTB_WHITE_OFFSET_BLUE 0x6cd0
60#define AVIVO_DC_LUTB_WHITE_OFFSET_GREEN 0x6cd4
61#define AVIVO_DC_LUTB_WHITE_OFFSET_RED 0x6cd8
62
63enum ofdrm_model {
64 OFDRM_MODEL_UNKNOWN,
65 OFDRM_MODEL_MACH64, /* ATI Mach64 */
66 OFDRM_MODEL_RAGE128, /* ATI Rage128 */
67 OFDRM_MODEL_RAGE_M3A, /* ATI Rage Mobility M3 Head A */
68 OFDRM_MODEL_RAGE_M3B, /* ATI Rage Mobility M3 Head B */
69 OFDRM_MODEL_RADEON, /* ATI Radeon */
70 OFDRM_MODEL_GXT2000, /* IBM GXT2000 */
71 OFDRM_MODEL_AVIVO, /* ATI R5xx */
72 OFDRM_MODEL_QEMU, /* QEMU VGA */
73};
74
75/*
76 * Helpers for display nodes
77 */
78
79static int display_get_validated_int(struct drm_device *dev, const char *name, uint32_t value)
80{
81 return drm_sysfb_get_validated_int(dev, name, value, INT_MAX);
82}
83
84static int display_get_validated_int0(struct drm_device *dev, const char *name, uint32_t value)
85{
86 return drm_sysfb_get_validated_int0(dev, name, value, INT_MAX);
87}
88
89static const struct drm_format_info *display_get_validated_format(struct drm_device *dev,
90 u32 depth, bool big_endian)
91{
92 const struct drm_format_info *info;
93 u32 format;
94
95 switch (depth) {
96 case 8:
97 format = drm_mode_legacy_fb_format(bpp: 8, depth: 8);
98 break;
99 case 15:
100 case 16:
101 format = drm_mode_legacy_fb_format(bpp: 16, depth);
102 break;
103 case 32:
104 format = drm_mode_legacy_fb_format(bpp: 32, depth: 24);
105 break;
106 default:
107 drm_err(dev, "unsupported framebuffer depth %u\n", depth);
108 return ERR_PTR(error: -EINVAL);
109 }
110
111 /*
112 * DRM formats assume little-endian byte order. Update the format
113 * if the scanout buffer uses big-endian ordering.
114 */
115 if (big_endian) {
116 switch (format) {
117 case DRM_FORMAT_XRGB8888:
118 format = DRM_FORMAT_BGRX8888;
119 break;
120 case DRM_FORMAT_ARGB8888:
121 format = DRM_FORMAT_BGRA8888;
122 break;
123 case DRM_FORMAT_RGB565:
124 format = DRM_FORMAT_RGB565 | DRM_FORMAT_BIG_ENDIAN;
125 break;
126 case DRM_FORMAT_XRGB1555:
127 format = DRM_FORMAT_XRGB1555 | DRM_FORMAT_BIG_ENDIAN;
128 break;
129 default:
130 break;
131 }
132 }
133
134 info = drm_format_info(format);
135 if (!info) {
136 drm_err(dev, "cannot find framebuffer format for depth %u\n", depth);
137 return ERR_PTR(error: -EINVAL);
138 }
139
140 return info;
141}
142
143static int display_read_u32_of(struct drm_device *dev, struct device_node *of_node,
144 const char *name, u32 *value)
145{
146 int ret = of_property_read_u32(np: of_node, propname: name, out_value: value);
147
148 if (ret)
149 drm_err(dev, "cannot parse framebuffer %s: error %d\n", name, ret);
150 return ret;
151}
152
153static bool display_get_big_endian_of(struct drm_device *dev, struct device_node *of_node)
154{
155 bool big_endian;
156
157#ifdef __BIG_ENDIAN
158 big_endian = !of_property_read_bool(of_node, "little-endian");
159#else
160 big_endian = of_property_read_bool(np: of_node, propname: "big-endian");
161#endif
162
163 return big_endian;
164}
165
166static int display_get_width_of(struct drm_device *dev, struct device_node *of_node)
167{
168 u32 width;
169 int ret = display_read_u32_of(dev, of_node, name: "width", value: &width);
170
171 if (ret)
172 return ret;
173 return display_get_validated_int0(dev, name: "width", value: width);
174}
175
176static int display_get_height_of(struct drm_device *dev, struct device_node *of_node)
177{
178 u32 height;
179 int ret = display_read_u32_of(dev, of_node, name: "height", value: &height);
180
181 if (ret)
182 return ret;
183 return display_get_validated_int0(dev, name: "height", value: height);
184}
185
186static int display_get_depth_of(struct drm_device *dev, struct device_node *of_node)
187{
188 u32 depth;
189 int ret = display_read_u32_of(dev, of_node, name: "depth", value: &depth);
190
191 if (ret)
192 return ret;
193 return display_get_validated_int0(dev, name: "depth", value: depth);
194}
195
196static int display_get_linebytes_of(struct drm_device *dev, struct device_node *of_node)
197{
198 u32 linebytes;
199 int ret = display_read_u32_of(dev, of_node, name: "linebytes", value: &linebytes);
200
201 if (ret)
202 return ret;
203 return display_get_validated_int(dev, name: "linebytes", value: linebytes);
204}
205
206static u64 display_get_address_of(struct drm_device *dev, struct device_node *of_node)
207{
208 u32 address;
209 int ret;
210
211 /*
212 * Not all devices provide an address property, it's not
213 * a bug if this fails. The driver will try to find the
214 * framebuffer base address from the device's memory regions.
215 */
216 ret = of_property_read_u32(np: of_node, propname: "address", out_value: &address);
217 if (ret)
218 return OF_BAD_ADDR;
219
220 return address;
221}
222
223static const u8 *display_get_edid_of(struct drm_device *dev, struct device_node *of_node,
224 u8 buf[EDID_LENGTH])
225{
226 int ret = of_property_read_u8_array(np: of_node, propname: "EDID", out_values: buf, EDID_LENGTH);
227
228 if (ret)
229 return NULL;
230 return buf;
231}
232
233static bool is_avivo(u32 vendor, u32 device)
234{
235 /* This will match most R5xx */
236 return (vendor == PCI_VENDOR_ID_ATI) &&
237 ((device >= PCI_VENDOR_ID_ATI_R520 && device < 0x7800) ||
238 (PCI_VENDOR_ID_ATI_R600 >= 0x9400));
239}
240
241static enum ofdrm_model display_get_model_of(struct drm_device *dev, struct device_node *of_node)
242{
243 enum ofdrm_model model = OFDRM_MODEL_UNKNOWN;
244
245 if (of_node_name_prefix(np: of_node, prefix: "ATY,Rage128")) {
246 model = OFDRM_MODEL_RAGE128;
247 } else if (of_node_name_prefix(np: of_node, prefix: "ATY,RageM3pA") ||
248 of_node_name_prefix(np: of_node, prefix: "ATY,RageM3p12A")) {
249 model = OFDRM_MODEL_RAGE_M3A;
250 } else if (of_node_name_prefix(np: of_node, prefix: "ATY,RageM3pB")) {
251 model = OFDRM_MODEL_RAGE_M3B;
252 } else if (of_node_name_prefix(np: of_node, prefix: "ATY,Rage6")) {
253 model = OFDRM_MODEL_RADEON;
254 } else if (of_node_name_prefix(np: of_node, prefix: "ATY,")) {
255 return OFDRM_MODEL_MACH64;
256 } else if (of_device_is_compatible(device: of_node, "pci1014,b7") ||
257 of_device_is_compatible(device: of_node, "pci1014,21c")) {
258 model = OFDRM_MODEL_GXT2000;
259 } else if (of_node_name_prefix(np: of_node, prefix: "vga,Display-")) {
260 struct device_node *of_parent;
261 const __be32 *vendor_p, *device_p;
262
263 /* Look for AVIVO initialized by SLOF */
264 of_parent = of_get_parent(node: of_node);
265 vendor_p = of_get_property(node: of_parent, name: "vendor-id", NULL);
266 device_p = of_get_property(node: of_parent, name: "device-id", NULL);
267 if (vendor_p && device_p) {
268 u32 vendor = be32_to_cpup(p: vendor_p);
269 u32 device = be32_to_cpup(p: device_p);
270
271 if (is_avivo(vendor, device))
272 model = OFDRM_MODEL_AVIVO;
273 }
274 of_node_put(node: of_parent);
275 } else if (of_device_is_compatible(device: of_node, "qemu,std-vga")) {
276 model = OFDRM_MODEL_QEMU;
277 }
278
279 return model;
280}
281
282/*
283 * Open Firmware display device
284 */
285
286struct ofdrm_device;
287
288struct ofdrm_device_funcs {
289 void __iomem *(*cmap_ioremap)(struct ofdrm_device *odev,
290 struct device_node *of_node,
291 u64 fb_bas);
292 void (*cmap_write)(struct ofdrm_device *odev, unsigned char index,
293 unsigned char r, unsigned char g, unsigned char b);
294};
295
296struct ofdrm_device {
297 struct drm_sysfb_device sysfb;
298
299 const struct ofdrm_device_funcs *funcs;
300
301 /* colormap */
302 void __iomem *cmap_base;
303
304 u8 edid[EDID_LENGTH];
305
306 /* modesetting */
307 u32 formats[DRM_SYSFB_PLANE_NFORMATS(1)];
308 struct drm_plane primary_plane;
309 struct drm_crtc crtc;
310 struct drm_encoder encoder;
311 struct drm_connector connector;
312};
313
314static struct ofdrm_device *ofdrm_device_of_dev(struct drm_device *dev)
315{
316 return container_of(to_drm_sysfb_device(dev), struct ofdrm_device, sysfb);
317}
318
319/*
320 * Hardware
321 */
322
323#if defined(CONFIG_PCI)
324static struct pci_dev *display_get_pci_dev_of(struct drm_device *dev, struct device_node *of_node)
325{
326 const __be32 *vendor_p, *device_p;
327 u32 vendor, device;
328 struct pci_dev *pcidev;
329
330 vendor_p = of_get_property(node: of_node, name: "vendor-id", NULL);
331 if (!vendor_p)
332 return ERR_PTR(error: -ENODEV);
333 vendor = be32_to_cpup(p: vendor_p);
334
335 device_p = of_get_property(node: of_node, name: "device-id", NULL);
336 if (!device_p)
337 return ERR_PTR(error: -ENODEV);
338 device = be32_to_cpup(p: device_p);
339
340 pcidev = pci_get_device(vendor, device, NULL);
341 if (!pcidev)
342 return ERR_PTR(error: -ENODEV);
343
344 return pcidev;
345}
346
347static void ofdrm_pci_release(void *data)
348{
349 struct pci_dev *pcidev = data;
350
351 pci_disable_device(dev: pcidev);
352}
353
354static int ofdrm_device_init_pci(struct ofdrm_device *odev)
355{
356 struct drm_device *dev = &odev->sysfb.dev;
357 struct platform_device *pdev = to_platform_device(dev->dev);
358 struct device_node *of_node = pdev->dev.of_node;
359 struct pci_dev *pcidev;
360 int ret;
361
362 /*
363 * Never use pcim_ or other managed helpers on the returned PCI
364 * device. Otherwise, probing the native driver will fail for
365 * resource conflicts. PCI-device management has to be tied to
366 * the lifetime of the platform device until the native driver
367 * takes over.
368 */
369 pcidev = display_get_pci_dev_of(dev, of_node);
370 if (IS_ERR(ptr: pcidev))
371 return 0; /* no PCI device found; ignore the error */
372
373 ret = pci_enable_device(dev: pcidev);
374 if (ret) {
375 drm_err(dev, "pci_enable_device(%s) failed: %d\n",
376 dev_name(&pcidev->dev), ret);
377 return ret;
378 }
379 ret = devm_add_action_or_reset(&pdev->dev, ofdrm_pci_release, pcidev);
380 if (ret)
381 return ret;
382
383 return 0;
384}
385#else
386static int ofdrm_device_init_pci(struct ofdrm_device *odev)
387{
388 return 0;
389}
390#endif
391
392/*
393 * OF display settings
394 */
395
396static struct resource *ofdrm_find_fb_resource(struct ofdrm_device *odev,
397 struct resource *fb_res)
398{
399 struct platform_device *pdev = to_platform_device(odev->sysfb.dev.dev);
400 struct resource *res, *max_res = NULL;
401 u32 i;
402
403 for (i = 0; pdev->num_resources; ++i) {
404 res = platform_get_resource(pdev, IORESOURCE_MEM, i);
405 if (!res)
406 break; /* all resources processed */
407 if (resource_size(res) < resource_size(res: fb_res))
408 continue; /* resource too small */
409 if (fb_res->start && resource_contains(r1: res, r2: fb_res))
410 return res; /* resource contains framebuffer */
411 if (!max_res || resource_size(res) > resource_size(res: max_res))
412 max_res = res; /* store largest resource as fallback */
413 }
414
415 return max_res;
416}
417
418/*
419 * Colormap / Palette
420 */
421
422static void __iomem *get_cmap_address_of(struct ofdrm_device *odev, struct device_node *of_node,
423 int bar_no, unsigned long offset, unsigned long size)
424{
425 struct drm_device *dev = &odev->sysfb.dev;
426 const __be32 *addr_p;
427 u64 max_size, address;
428 unsigned int flags;
429 void __iomem *mem;
430
431 addr_p = of_get_pci_address(dev: of_node, bar_no, size: &max_size, flags: &flags);
432 if (!addr_p)
433 addr_p = of_get_address(dev: of_node, index: bar_no, size: &max_size, flags: &flags);
434 if (!addr_p)
435 return IOMEM_ERR_PTR(-ENODEV);
436
437 if ((flags & (IORESOURCE_IO | IORESOURCE_MEM)) == 0)
438 return IOMEM_ERR_PTR(-ENODEV);
439
440 if ((offset + size) >= max_size)
441 return IOMEM_ERR_PTR(-ENODEV);
442
443 address = of_translate_address(np: of_node, addr: addr_p);
444 if (address == OF_BAD_ADDR)
445 return IOMEM_ERR_PTR(-ENODEV);
446
447 mem = devm_ioremap(dev: dev->dev, offset: address + offset, size);
448 if (!mem)
449 return IOMEM_ERR_PTR(-ENOMEM);
450
451 return mem;
452}
453
454static void __iomem *ofdrm_mach64_cmap_ioremap(struct ofdrm_device *odev,
455 struct device_node *of_node,
456 u64 fb_base)
457{
458 struct drm_device *dev = &odev->sysfb.dev;
459 u64 address;
460 void __iomem *cmap_base;
461
462 address = fb_base & 0xff000000ul;
463 address += 0x7ff000;
464
465 cmap_base = devm_ioremap(dev: dev->dev, offset: address, size: 0x1000);
466 if (!cmap_base)
467 return IOMEM_ERR_PTR(-ENOMEM);
468
469 return cmap_base;
470}
471
472static void ofdrm_mach64_cmap_write(struct ofdrm_device *odev, unsigned char index,
473 unsigned char r, unsigned char g, unsigned char b)
474{
475 void __iomem *addr = odev->cmap_base + 0xcc0;
476 void __iomem *data = odev->cmap_base + 0xcc0 + 1;
477
478 writeb(val: index, addr);
479 writeb(val: r, addr: data);
480 writeb(val: g, addr: data);
481 writeb(val: b, addr: data);
482}
483
484static void __iomem *ofdrm_rage128_cmap_ioremap(struct ofdrm_device *odev,
485 struct device_node *of_node,
486 u64 fb_base)
487{
488 return get_cmap_address_of(odev, of_node, bar_no: 2, offset: 0, size: 0x1fff);
489}
490
491static void ofdrm_rage128_cmap_write(struct ofdrm_device *odev, unsigned char index,
492 unsigned char r, unsigned char g, unsigned char b)
493{
494 void __iomem *addr = odev->cmap_base + 0xb0;
495 void __iomem *data = odev->cmap_base + 0xb4;
496 u32 color = (r << 16) | (g << 8) | b;
497
498 writeb(val: index, addr);
499 writel(val: color, addr: data);
500}
501
502static void __iomem *ofdrm_rage_m3a_cmap_ioremap(struct ofdrm_device *odev,
503 struct device_node *of_node,
504 u64 fb_base)
505{
506 return get_cmap_address_of(odev, of_node, bar_no: 2, offset: 0, size: 0x1fff);
507}
508
509static void ofdrm_rage_m3a_cmap_write(struct ofdrm_device *odev, unsigned char index,
510 unsigned char r, unsigned char g, unsigned char b)
511{
512 void __iomem *dac_ctl = odev->cmap_base + 0x58;
513 void __iomem *addr = odev->cmap_base + 0xb0;
514 void __iomem *data = odev->cmap_base + 0xb4;
515 u32 color = (r << 16) | (g << 8) | b;
516 u32 val;
517
518 /* Clear PALETTE_ACCESS_CNTL in DAC_CNTL */
519 val = readl(addr: dac_ctl);
520 val &= ~0x20;
521 writel(val, addr: dac_ctl);
522
523 /* Set color at palette index */
524 writeb(val: index, addr);
525 writel(val: color, addr: data);
526}
527
528static void __iomem *ofdrm_rage_m3b_cmap_ioremap(struct ofdrm_device *odev,
529 struct device_node *of_node,
530 u64 fb_base)
531{
532 return get_cmap_address_of(odev, of_node, bar_no: 2, offset: 0, size: 0x1fff);
533}
534
535static void ofdrm_rage_m3b_cmap_write(struct ofdrm_device *odev, unsigned char index,
536 unsigned char r, unsigned char g, unsigned char b)
537{
538 void __iomem *dac_ctl = odev->cmap_base + 0x58;
539 void __iomem *addr = odev->cmap_base + 0xb0;
540 void __iomem *data = odev->cmap_base + 0xb4;
541 u32 color = (r << 16) | (g << 8) | b;
542 u32 val;
543
544 /* Set PALETTE_ACCESS_CNTL in DAC_CNTL */
545 val = readl(addr: dac_ctl);
546 val |= 0x20;
547 writel(val, addr: dac_ctl);
548
549 /* Set color at palette index */
550 writeb(val: index, addr);
551 writel(val: color, addr: data);
552}
553
554static void __iomem *ofdrm_radeon_cmap_ioremap(struct ofdrm_device *odev,
555 struct device_node *of_node,
556 u64 fb_base)
557{
558 return get_cmap_address_of(odev, of_node, bar_no: 1, offset: 0, size: 0x1fff);
559}
560
561static void __iomem *ofdrm_gxt2000_cmap_ioremap(struct ofdrm_device *odev,
562 struct device_node *of_node,
563 u64 fb_base)
564{
565 return get_cmap_address_of(odev, of_node, bar_no: 0, offset: 0x6000, size: 0x1000);
566}
567
568static void ofdrm_gxt2000_cmap_write(struct ofdrm_device *odev, unsigned char index,
569 unsigned char r, unsigned char g, unsigned char b)
570{
571 void __iomem *data = ((unsigned int __iomem *)odev->cmap_base) + index;
572 u32 color = (r << 16) | (g << 8) | b;
573
574 writel(val: color, addr: data);
575}
576
577static void __iomem *ofdrm_avivo_cmap_ioremap(struct ofdrm_device *odev,
578 struct device_node *of_node,
579 u64 fb_base)
580{
581 struct device_node *of_parent;
582 void __iomem *cmap_base;
583
584 of_parent = of_get_parent(node: of_node);
585 cmap_base = get_cmap_address_of(odev, of_node: of_parent, bar_no: 0, offset: 0, size: 0x10000);
586 of_node_put(node: of_parent);
587
588 return cmap_base;
589}
590
591static void ofdrm_avivo_cmap_write(struct ofdrm_device *odev, unsigned char index,
592 unsigned char r, unsigned char g, unsigned char b)
593{
594 void __iomem *lutsel = odev->cmap_base + AVIVO_DC_LUT_RW_SELECT;
595 void __iomem *addr = odev->cmap_base + AVIVO_DC_LUT_RW_INDEX;
596 void __iomem *data = odev->cmap_base + AVIVO_DC_LUT_30_COLOR;
597 u32 color = (r << 22) | (g << 12) | (b << 2);
598
599 /* Write to both LUTs for now */
600
601 writel(val: 1, addr: lutsel);
602 writeb(val: index, addr);
603 writel(val: color, addr: data);
604
605 writel(val: 0, addr: lutsel);
606 writeb(val: index, addr);
607 writel(val: color, addr: data);
608}
609
610static void __iomem *ofdrm_qemu_cmap_ioremap(struct ofdrm_device *odev,
611 struct device_node *of_node,
612 u64 fb_base)
613{
614 static const __be32 io_of_addr[3] = {
615 cpu_to_be32(0x01000000),
616 cpu_to_be32(0x00),
617 cpu_to_be32(0x00),
618 };
619
620 struct drm_device *dev = &odev->sysfb.dev;
621 u64 address;
622 void __iomem *cmap_base;
623
624 address = of_translate_address(np: of_node, addr: io_of_addr);
625 if (address == OF_BAD_ADDR)
626 return IOMEM_ERR_PTR(-ENODEV);
627
628 cmap_base = devm_ioremap(dev: dev->dev, offset: address + 0x3c8, size: 2);
629 if (!cmap_base)
630 return IOMEM_ERR_PTR(-ENOMEM);
631
632 return cmap_base;
633}
634
635static void ofdrm_qemu_cmap_write(struct ofdrm_device *odev, unsigned char index,
636 unsigned char r, unsigned char g, unsigned char b)
637{
638 void __iomem *addr = odev->cmap_base;
639 void __iomem *data = odev->cmap_base + 1;
640
641 writeb(val: index, addr);
642 writeb(val: r, addr: data);
643 writeb(val: g, addr: data);
644 writeb(val: b, addr: data);
645}
646
647static void ofdrm_device_set_gamma_linear(struct ofdrm_device *odev,
648 const struct drm_format_info *format)
649{
650 struct drm_device *dev = &odev->sysfb.dev;
651 int i;
652
653 switch (format->format) {
654 case DRM_FORMAT_RGB565:
655 case DRM_FORMAT_RGB565 | DRM_FORMAT_BIG_ENDIAN:
656 /* Use better interpolation, to take 32 values from 0 to 255 */
657 for (i = 0; i < OFDRM_GAMMA_LUT_SIZE / 8; i++) {
658 unsigned char r = i * 8 + i / 4;
659 unsigned char g = i * 4 + i / 16;
660 unsigned char b = i * 8 + i / 4;
661
662 odev->funcs->cmap_write(odev, i, r, g, b);
663 }
664 /* Green has one more bit, so add padding with 0 for red and blue. */
665 for (i = OFDRM_GAMMA_LUT_SIZE / 8; i < OFDRM_GAMMA_LUT_SIZE / 4; i++) {
666 unsigned char r = 0;
667 unsigned char g = i * 4 + i / 16;
668 unsigned char b = 0;
669
670 odev->funcs->cmap_write(odev, i, r, g, b);
671 }
672 break;
673 case DRM_FORMAT_XRGB8888:
674 case DRM_FORMAT_BGRX8888:
675 for (i = 0; i < OFDRM_GAMMA_LUT_SIZE; i++)
676 odev->funcs->cmap_write(odev, i, i, i, i);
677 break;
678 default:
679 drm_warn_once(dev, "Unsupported format %p4cc for gamma correction\n",
680 &format->format);
681 break;
682 }
683}
684
685static void ofdrm_device_set_gamma(struct ofdrm_device *odev,
686 const struct drm_format_info *format,
687 struct drm_color_lut *lut)
688{
689 struct drm_device *dev = &odev->sysfb.dev;
690 int i;
691
692 switch (format->format) {
693 case DRM_FORMAT_RGB565:
694 case DRM_FORMAT_RGB565 | DRM_FORMAT_BIG_ENDIAN:
695 /* Use better interpolation, to take 32 values from lut[0] to lut[255] */
696 for (i = 0; i < OFDRM_GAMMA_LUT_SIZE / 8; i++) {
697 unsigned char r = lut[i * 8 + i / 4].red >> 8;
698 unsigned char g = lut[i * 4 + i / 16].green >> 8;
699 unsigned char b = lut[i * 8 + i / 4].blue >> 8;
700
701 odev->funcs->cmap_write(odev, i, r, g, b);
702 }
703 /* Green has one more bit, so add padding with 0 for red and blue. */
704 for (i = OFDRM_GAMMA_LUT_SIZE / 8; i < OFDRM_GAMMA_LUT_SIZE / 4; i++) {
705 unsigned char r = 0;
706 unsigned char g = lut[i * 4 + i / 16].green >> 8;
707 unsigned char b = 0;
708
709 odev->funcs->cmap_write(odev, i, r, g, b);
710 }
711 break;
712 case DRM_FORMAT_XRGB8888:
713 case DRM_FORMAT_BGRX8888:
714 for (i = 0; i < OFDRM_GAMMA_LUT_SIZE; i++) {
715 unsigned char r = lut[i].red >> 8;
716 unsigned char g = lut[i].green >> 8;
717 unsigned char b = lut[i].blue >> 8;
718
719 odev->funcs->cmap_write(odev, i, r, g, b);
720 }
721 break;
722 default:
723 drm_warn_once(dev, "Unsupported format %p4cc for gamma correction\n",
724 &format->format);
725 break;
726 }
727}
728
729/*
730 * Modesetting
731 */
732
733static const u64 ofdrm_primary_plane_format_modifiers[] = {
734 DRM_SYSFB_PLANE_FORMAT_MODIFIERS,
735};
736
737static const struct drm_plane_helper_funcs ofdrm_primary_plane_helper_funcs = {
738 DRM_SYSFB_PLANE_HELPER_FUNCS,
739};
740
741static const struct drm_plane_funcs ofdrm_primary_plane_funcs = {
742 DRM_SYSFB_PLANE_FUNCS,
743 .destroy = drm_plane_cleanup,
744};
745
746static void ofdrm_crtc_helper_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_state *state)
747{
748 struct ofdrm_device *odev = ofdrm_device_of_dev(dev: crtc->dev);
749 struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
750 struct drm_sysfb_crtc_state *sysfb_crtc_state = to_drm_sysfb_crtc_state(base: crtc_state);
751
752 if (crtc_state->enable && crtc_state->color_mgmt_changed) {
753 const struct drm_format_info *format = sysfb_crtc_state->format;
754
755 if (crtc_state->gamma_lut)
756 ofdrm_device_set_gamma(odev, format, lut: crtc_state->gamma_lut->data);
757 else
758 ofdrm_device_set_gamma_linear(odev, format);
759 }
760}
761
762static const struct drm_crtc_helper_funcs ofdrm_crtc_helper_funcs = {
763 DRM_SYSFB_CRTC_HELPER_FUNCS,
764 .atomic_flush = ofdrm_crtc_helper_atomic_flush,
765};
766
767static const struct drm_crtc_funcs ofdrm_crtc_funcs = {
768 DRM_SYSFB_CRTC_FUNCS,
769 .destroy = drm_crtc_cleanup,
770};
771
772static const struct drm_encoder_funcs ofdrm_encoder_funcs = {
773 .destroy = drm_encoder_cleanup,
774};
775
776static const struct drm_connector_helper_funcs ofdrm_connector_helper_funcs = {
777 DRM_SYSFB_CONNECTOR_HELPER_FUNCS,
778};
779
780static const struct drm_connector_funcs ofdrm_connector_funcs = {
781 DRM_SYSFB_CONNECTOR_FUNCS,
782 .destroy = drm_connector_cleanup,
783};
784
785static const struct drm_mode_config_funcs ofdrm_mode_config_funcs = {
786 DRM_SYSFB_MODE_CONFIG_FUNCS,
787};
788
789/*
790 * Init / Cleanup
791 */
792
793static const struct ofdrm_device_funcs ofdrm_unknown_device_funcs = {
794};
795
796static const struct ofdrm_device_funcs ofdrm_mach64_device_funcs = {
797 .cmap_ioremap = ofdrm_mach64_cmap_ioremap,
798 .cmap_write = ofdrm_mach64_cmap_write,
799};
800
801static const struct ofdrm_device_funcs ofdrm_rage128_device_funcs = {
802 .cmap_ioremap = ofdrm_rage128_cmap_ioremap,
803 .cmap_write = ofdrm_rage128_cmap_write,
804};
805
806static const struct ofdrm_device_funcs ofdrm_rage_m3a_device_funcs = {
807 .cmap_ioremap = ofdrm_rage_m3a_cmap_ioremap,
808 .cmap_write = ofdrm_rage_m3a_cmap_write,
809};
810
811static const struct ofdrm_device_funcs ofdrm_rage_m3b_device_funcs = {
812 .cmap_ioremap = ofdrm_rage_m3b_cmap_ioremap,
813 .cmap_write = ofdrm_rage_m3b_cmap_write,
814};
815
816static const struct ofdrm_device_funcs ofdrm_radeon_device_funcs = {
817 .cmap_ioremap = ofdrm_radeon_cmap_ioremap,
818 .cmap_write = ofdrm_rage128_cmap_write, /* same as Rage128 */
819};
820
821static const struct ofdrm_device_funcs ofdrm_gxt2000_device_funcs = {
822 .cmap_ioremap = ofdrm_gxt2000_cmap_ioremap,
823 .cmap_write = ofdrm_gxt2000_cmap_write,
824};
825
826static const struct ofdrm_device_funcs ofdrm_avivo_device_funcs = {
827 .cmap_ioremap = ofdrm_avivo_cmap_ioremap,
828 .cmap_write = ofdrm_avivo_cmap_write,
829};
830
831static const struct ofdrm_device_funcs ofdrm_qemu_device_funcs = {
832 .cmap_ioremap = ofdrm_qemu_cmap_ioremap,
833 .cmap_write = ofdrm_qemu_cmap_write,
834};
835
836static struct ofdrm_device *ofdrm_device_create(struct drm_driver *drv,
837 struct platform_device *pdev)
838{
839 struct device_node *of_node = pdev->dev.of_node;
840 struct ofdrm_device *odev;
841 struct drm_sysfb_device *sysfb;
842 struct drm_device *dev;
843 enum ofdrm_model model;
844 bool big_endian;
845 int width, height, depth, linebytes;
846 const struct drm_format_info *format;
847 u64 address;
848 const u8 *edid;
849 resource_size_t fb_size, fb_base, fb_pgbase, fb_pgsize;
850 struct resource *res, *mem;
851 void __iomem *screen_base;
852 struct drm_plane *primary_plane;
853 struct drm_crtc *crtc;
854 struct drm_encoder *encoder;
855 struct drm_connector *connector;
856 unsigned long max_width, max_height;
857 size_t nformats;
858 int ret;
859
860 odev = devm_drm_dev_alloc(&pdev->dev, drv, struct ofdrm_device, sysfb.dev);
861 if (IS_ERR(ptr: odev))
862 return ERR_CAST(ptr: odev);
863 sysfb = &odev->sysfb;
864 dev = &sysfb->dev;
865 platform_set_drvdata(pdev, data: dev);
866
867 ret = ofdrm_device_init_pci(odev);
868 if (ret)
869 return ERR_PTR(error: ret);
870
871 /*
872 * OF display-node settings
873 */
874
875 model = display_get_model_of(dev, of_node);
876 drm_dbg(dev, "detected model %d\n", model);
877
878 switch (model) {
879 case OFDRM_MODEL_UNKNOWN:
880 odev->funcs = &ofdrm_unknown_device_funcs;
881 break;
882 case OFDRM_MODEL_MACH64:
883 odev->funcs = &ofdrm_mach64_device_funcs;
884 break;
885 case OFDRM_MODEL_RAGE128:
886 odev->funcs = &ofdrm_rage128_device_funcs;
887 break;
888 case OFDRM_MODEL_RAGE_M3A:
889 odev->funcs = &ofdrm_rage_m3a_device_funcs;
890 break;
891 case OFDRM_MODEL_RAGE_M3B:
892 odev->funcs = &ofdrm_rage_m3b_device_funcs;
893 break;
894 case OFDRM_MODEL_RADEON:
895 odev->funcs = &ofdrm_radeon_device_funcs;
896 break;
897 case OFDRM_MODEL_GXT2000:
898 odev->funcs = &ofdrm_gxt2000_device_funcs;
899 break;
900 case OFDRM_MODEL_AVIVO:
901 odev->funcs = &ofdrm_avivo_device_funcs;
902 break;
903 case OFDRM_MODEL_QEMU:
904 odev->funcs = &ofdrm_qemu_device_funcs;
905 break;
906 }
907
908 big_endian = display_get_big_endian_of(dev, of_node);
909
910 width = display_get_width_of(dev, of_node);
911 if (width < 0)
912 return ERR_PTR(error: width);
913 height = display_get_height_of(dev, of_node);
914 if (height < 0)
915 return ERR_PTR(error: height);
916 depth = display_get_depth_of(dev, of_node);
917 if (depth < 0)
918 return ERR_PTR(error: depth);
919 linebytes = display_get_linebytes_of(dev, of_node);
920 if (linebytes < 0)
921 return ERR_PTR(error: linebytes);
922
923 format = display_get_validated_format(dev, depth, big_endian);
924 if (IS_ERR(ptr: format))
925 return ERR_CAST(ptr: format);
926 if (!linebytes) {
927 linebytes = drm_format_info_min_pitch(info: format, plane: 0, buffer_width: width);
928 if (drm_WARN_ON(dev, !linebytes))
929 return ERR_PTR(error: -EINVAL);
930 }
931
932 fb_size = linebytes * height;
933
934 /*
935 * Try to figure out the address of the framebuffer. Unfortunately, Open
936 * Firmware doesn't provide a standard way to do so. All we can do is a
937 * dodgy heuristic that happens to work in practice.
938 *
939 * On most machines, the "address" property contains what we need, though
940 * not on Matrox cards found in IBM machines. What appears to give good
941 * results is to go through the PCI ranges and pick one that encloses the
942 * "address" property. If none match, we pick the largest.
943 */
944 address = display_get_address_of(dev, of_node);
945 if (address != OF_BAD_ADDR) {
946 struct resource fb_res = DEFINE_RES_MEM(address, fb_size);
947
948 res = ofdrm_find_fb_resource(odev, fb_res: &fb_res);
949 if (!res)
950 return ERR_PTR(error: -EINVAL);
951 if (resource_contains(r1: res, r2: &fb_res))
952 fb_base = address;
953 else
954 fb_base = res->start;
955 } else {
956 struct resource fb_res = DEFINE_RES_MEM(0u, fb_size);
957
958 res = ofdrm_find_fb_resource(odev, fb_res: &fb_res);
959 if (!res)
960 return ERR_PTR(error: -EINVAL);
961 fb_base = res->start;
962 }
963
964 /*
965 * I/O resources
966 */
967
968 fb_pgbase = round_down(fb_base, PAGE_SIZE);
969 fb_pgsize = fb_base - fb_pgbase + round_up(fb_size, PAGE_SIZE);
970
971 ret = devm_aperture_acquire_for_platform_device(pdev, base: fb_pgbase, size: fb_pgsize);
972 if (ret) {
973 drm_err(dev, "could not acquire memory range %pr: error %d\n", &res, ret);
974 return ERR_PTR(error: ret);
975 }
976
977 mem = devm_request_mem_region(&pdev->dev, fb_pgbase, fb_pgsize, drv->name);
978 if (!mem) {
979 drm_warn(dev, "could not acquire memory region %pr\n", &res);
980 return ERR_PTR(error: -ENOMEM);
981 }
982
983 screen_base = devm_ioremap(dev: &pdev->dev, offset: mem->start, size: resource_size(res: mem));
984 if (!screen_base)
985 return ERR_PTR(error: -ENOMEM);
986
987 if (odev->funcs->cmap_ioremap) {
988 void __iomem *cmap_base = odev->funcs->cmap_ioremap(odev, of_node, fb_base);
989
990 if (IS_ERR(ptr: cmap_base)) {
991 /* Don't fail; continue without colormap */
992 drm_warn(dev, "could not find colormap: error %ld\n", PTR_ERR(cmap_base));
993 } else {
994 odev->cmap_base = cmap_base;
995 }
996 }
997
998 /* EDID is optional */
999 edid = display_get_edid_of(dev, of_node, buf: odev->edid);
1000
1001 /*
1002 * Firmware framebuffer
1003 */
1004
1005 iosys_map_set_vaddr_iomem(map: &sysfb->fb_addr, vaddr_iomem: screen_base);
1006 sysfb->fb_mode = drm_sysfb_mode(width, height, width_mm: 0, height_mm: 0);
1007 sysfb->fb_format = format;
1008 sysfb->fb_pitch = linebytes;
1009 if (odev->cmap_base)
1010 sysfb->fb_gamma_lut_size = OFDRM_GAMMA_LUT_SIZE;
1011 sysfb->edid = edid;
1012
1013 drm_dbg(dev, "display mode={" DRM_MODE_FMT "}\n", DRM_MODE_ARG(&sysfb->fb_mode));
1014 drm_dbg(dev, "framebuffer format=%p4cc, size=%dx%d, linebytes=%d byte\n",
1015 &format->format, width, height, linebytes);
1016
1017 /*
1018 * Mode-setting pipeline
1019 */
1020
1021 ret = drmm_mode_config_init(dev);
1022 if (ret)
1023 return ERR_PTR(error: ret);
1024
1025 max_width = max_t(unsigned long, width, DRM_SHADOW_PLANE_MAX_WIDTH);
1026 max_height = max_t(unsigned long, height, DRM_SHADOW_PLANE_MAX_HEIGHT);
1027
1028 dev->mode_config.min_width = width;
1029 dev->mode_config.max_width = max_width;
1030 dev->mode_config.min_height = height;
1031 dev->mode_config.max_height = max_height;
1032 dev->mode_config.funcs = &ofdrm_mode_config_funcs;
1033 dev->mode_config.preferred_depth = format->depth;
1034 dev->mode_config.quirk_addfb_prefer_host_byte_order = true;
1035
1036 /* Primary plane */
1037
1038 nformats = drm_fb_build_fourcc_list(dev, native_fourccs: &format->format, native_nfourccs: 1,
1039 fourccs_out: odev->formats, ARRAY_SIZE(odev->formats));
1040
1041 primary_plane = &odev->primary_plane;
1042 ret = drm_universal_plane_init(dev, plane: primary_plane, possible_crtcs: 0, funcs: &ofdrm_primary_plane_funcs,
1043 formats: odev->formats, format_count: nformats,
1044 format_modifiers: ofdrm_primary_plane_format_modifiers,
1045 type: DRM_PLANE_TYPE_PRIMARY, NULL);
1046 if (ret)
1047 return ERR_PTR(error: ret);
1048 drm_plane_helper_add(plane: primary_plane, funcs: &ofdrm_primary_plane_helper_funcs);
1049 drm_plane_enable_fb_damage_clips(plane: primary_plane);
1050
1051 /* CRTC */
1052
1053 crtc = &odev->crtc;
1054 ret = drm_crtc_init_with_planes(dev, crtc, primary: primary_plane, NULL,
1055 funcs: &ofdrm_crtc_funcs, NULL);
1056 if (ret)
1057 return ERR_PTR(error: ret);
1058 drm_crtc_helper_add(crtc, funcs: &ofdrm_crtc_helper_funcs);
1059
1060 if (sysfb->fb_gamma_lut_size) {
1061 ret = drm_mode_crtc_set_gamma_size(crtc, gamma_size: sysfb->fb_gamma_lut_size);
1062 if (!ret)
1063 drm_crtc_enable_color_mgmt(crtc, degamma_lut_size: 0, has_ctm: false, gamma_lut_size: sysfb->fb_gamma_lut_size);
1064 }
1065
1066 /* Encoder */
1067
1068 encoder = &odev->encoder;
1069 ret = drm_encoder_init(dev, encoder, funcs: &ofdrm_encoder_funcs, DRM_MODE_ENCODER_NONE, NULL);
1070 if (ret)
1071 return ERR_PTR(error: ret);
1072 encoder->possible_crtcs = drm_crtc_mask(crtc);
1073
1074 /* Connector */
1075
1076 connector = &odev->connector;
1077 ret = drm_connector_init(dev, connector, funcs: &ofdrm_connector_funcs,
1078 DRM_MODE_CONNECTOR_Unknown);
1079 if (ret)
1080 return ERR_PTR(error: ret);
1081 drm_connector_helper_add(connector, funcs: &ofdrm_connector_helper_funcs);
1082 drm_connector_set_panel_orientation_with_quirk(connector,
1083 panel_orientation: DRM_MODE_PANEL_ORIENTATION_UNKNOWN,
1084 width, height);
1085 if (edid)
1086 drm_connector_attach_edid_property(connector);
1087
1088 ret = drm_connector_attach_encoder(connector, encoder);
1089 if (ret)
1090 return ERR_PTR(error: ret);
1091
1092 drm_mode_config_reset(dev);
1093
1094 return odev;
1095}
1096
1097/*
1098 * DRM driver
1099 */
1100
1101DEFINE_DRM_GEM_FOPS(ofdrm_fops);
1102
1103static struct drm_driver ofdrm_driver = {
1104 DRM_GEM_SHMEM_DRIVER_OPS,
1105 DRM_FBDEV_SHMEM_DRIVER_OPS,
1106 .name = DRIVER_NAME,
1107 .desc = DRIVER_DESC,
1108 .major = DRIVER_MAJOR,
1109 .minor = DRIVER_MINOR,
1110 .driver_features = DRIVER_ATOMIC | DRIVER_GEM | DRIVER_MODESET,
1111 .fops = &ofdrm_fops,
1112};
1113
1114/*
1115 * Platform driver
1116 */
1117
1118static int ofdrm_probe(struct platform_device *pdev)
1119{
1120 struct ofdrm_device *odev;
1121 struct drm_sysfb_device *sysfb;
1122 struct drm_device *dev;
1123 int ret;
1124
1125 odev = ofdrm_device_create(drv: &ofdrm_driver, pdev);
1126 if (IS_ERR(ptr: odev))
1127 return PTR_ERR(ptr: odev);
1128 sysfb = &odev->sysfb;
1129 dev = &sysfb->dev;
1130
1131 ret = drm_dev_register(dev, flags: 0);
1132 if (ret)
1133 return ret;
1134
1135 drm_client_setup(dev, format: sysfb->fb_format);
1136
1137 return 0;
1138}
1139
1140static void ofdrm_remove(struct platform_device *pdev)
1141{
1142 struct drm_device *dev = platform_get_drvdata(pdev);
1143
1144 drm_dev_unplug(dev);
1145}
1146
1147static const struct of_device_id ofdrm_of_match_display[] = {
1148 { .compatible = "display", },
1149 { },
1150};
1151MODULE_DEVICE_TABLE(of, ofdrm_of_match_display);
1152
1153static struct platform_driver ofdrm_platform_driver = {
1154 .driver = {
1155 .name = "of-display",
1156 .of_match_table = ofdrm_of_match_display,
1157 },
1158 .probe = ofdrm_probe,
1159 .remove = ofdrm_remove,
1160};
1161
1162module_platform_driver(ofdrm_platform_driver);
1163
1164MODULE_DESCRIPTION(DRIVER_DESC);
1165MODULE_LICENSE("GPL");
1166

source code of linux/drivers/gpu/drm/sysfb/ofdrm.c