xref: /kernel/linux/linux-6.6/drivers/gpu/drm/tiny/ofdrm.c (revision 62306a36)
1// SPDX-License-Identifier: GPL-2.0-only
2
3#include <linux/of_address.h>
4#include <linux/pci.h>
5#include <linux/platform_device.h>
6
7#include <drm/drm_aperture.h>
8#include <drm/drm_atomic.h>
9#include <drm/drm_atomic_state_helper.h>
10#include <drm/drm_connector.h>
11#include <drm/drm_damage_helper.h>
12#include <drm/drm_device.h>
13#include <drm/drm_drv.h>
14#include <drm/drm_fbdev_generic.h>
15#include <drm/drm_format_helper.h>
16#include <drm/drm_framebuffer.h>
17#include <drm/drm_gem_atomic_helper.h>
18#include <drm/drm_gem_framebuffer_helper.h>
19#include <drm/drm_gem_shmem_helper.h>
20#include <drm/drm_managed.h>
21#include <drm/drm_modeset_helper_vtables.h>
22#include <drm/drm_plane_helper.h>
23#include <drm/drm_probe_helper.h>
24#include <drm/drm_simple_kms_helper.h>
25
26#define DRIVER_NAME	"ofdrm"
27#define DRIVER_DESC	"DRM driver for OF platform devices"
28#define DRIVER_DATE	"20220501"
29#define DRIVER_MAJOR	1
30#define DRIVER_MINOR	0
31
32#define PCI_VENDOR_ID_ATI_R520	0x7100
33#define PCI_VENDOR_ID_ATI_R600	0x9400
34
35#define OFDRM_GAMMA_LUT_SIZE	256
36
37/* Definitions used by the Avivo palette  */
38#define AVIVO_DC_LUT_RW_SELECT                  0x6480
39#define AVIVO_DC_LUT_RW_MODE                    0x6484
40#define AVIVO_DC_LUT_RW_INDEX                   0x6488
41#define AVIVO_DC_LUT_SEQ_COLOR                  0x648c
42#define AVIVO_DC_LUT_PWL_DATA                   0x6490
43#define AVIVO_DC_LUT_30_COLOR                   0x6494
44#define AVIVO_DC_LUT_READ_PIPE_SELECT           0x6498
45#define AVIVO_DC_LUT_WRITE_EN_MASK              0x649c
46#define AVIVO_DC_LUT_AUTOFILL                   0x64a0
47#define AVIVO_DC_LUTA_CONTROL                   0x64c0
48#define AVIVO_DC_LUTA_BLACK_OFFSET_BLUE         0x64c4
49#define AVIVO_DC_LUTA_BLACK_OFFSET_GREEN        0x64c8
50#define AVIVO_DC_LUTA_BLACK_OFFSET_RED          0x64cc
51#define AVIVO_DC_LUTA_WHITE_OFFSET_BLUE         0x64d0
52#define AVIVO_DC_LUTA_WHITE_OFFSET_GREEN        0x64d4
53#define AVIVO_DC_LUTA_WHITE_OFFSET_RED          0x64d8
54#define AVIVO_DC_LUTB_CONTROL                   0x6cc0
55#define AVIVO_DC_LUTB_BLACK_OFFSET_BLUE         0x6cc4
56#define AVIVO_DC_LUTB_BLACK_OFFSET_GREEN        0x6cc8
57#define AVIVO_DC_LUTB_BLACK_OFFSET_RED          0x6ccc
58#define AVIVO_DC_LUTB_WHITE_OFFSET_BLUE         0x6cd0
59#define AVIVO_DC_LUTB_WHITE_OFFSET_GREEN        0x6cd4
60#define AVIVO_DC_LUTB_WHITE_OFFSET_RED          0x6cd8
61
62enum ofdrm_model {
63	OFDRM_MODEL_UNKNOWN,
64	OFDRM_MODEL_MACH64, /* ATI Mach64 */
65	OFDRM_MODEL_RAGE128, /* ATI Rage128 */
66	OFDRM_MODEL_RAGE_M3A, /* ATI Rage Mobility M3 Head A */
67	OFDRM_MODEL_RAGE_M3B, /* ATI Rage Mobility M3 Head B */
68	OFDRM_MODEL_RADEON, /* ATI Radeon */
69	OFDRM_MODEL_GXT2000, /* IBM GXT2000 */
70	OFDRM_MODEL_AVIVO, /* ATI R5xx */
71	OFDRM_MODEL_QEMU, /* QEMU VGA */
72};
73
74/*
75 * Helpers for display nodes
76 */
77
78static int display_get_validated_int(struct drm_device *dev, const char *name, uint32_t value)
79{
80	if (value > INT_MAX) {
81		drm_err(dev, "invalid framebuffer %s of %u\n", name, value);
82		return -EINVAL;
83	}
84	return (int)value;
85}
86
87static int display_get_validated_int0(struct drm_device *dev, const char *name, uint32_t value)
88{
89	if (!value) {
90		drm_err(dev, "invalid framebuffer %s of %u\n", name, value);
91		return -EINVAL;
92	}
93	return display_get_validated_int(dev, name, value);
94}
95
96static const struct drm_format_info *display_get_validated_format(struct drm_device *dev,
97								  u32 depth, bool big_endian)
98{
99	const struct drm_format_info *info;
100	u32 format;
101
102	switch (depth) {
103	case 8:
104		format = drm_mode_legacy_fb_format(8, 8);
105		break;
106	case 15:
107	case 16:
108		format = drm_mode_legacy_fb_format(16, depth);
109		break;
110	case 32:
111		format = drm_mode_legacy_fb_format(32, 24);
112		break;
113	default:
114		drm_err(dev, "unsupported framebuffer depth %u\n", depth);
115		return ERR_PTR(-EINVAL);
116	}
117
118	/*
119	 * DRM formats assume little-endian byte order. Update the format
120	 * if the scanout buffer uses big-endian ordering.
121	 */
122	if (big_endian) {
123		switch (format) {
124		case DRM_FORMAT_XRGB8888:
125			format = DRM_FORMAT_BGRX8888;
126			break;
127		case DRM_FORMAT_ARGB8888:
128			format = DRM_FORMAT_BGRA8888;
129			break;
130		case DRM_FORMAT_RGB565:
131			format = DRM_FORMAT_RGB565 | DRM_FORMAT_BIG_ENDIAN;
132			break;
133		case DRM_FORMAT_XRGB1555:
134			format = DRM_FORMAT_XRGB1555 | DRM_FORMAT_BIG_ENDIAN;
135			break;
136		default:
137			break;
138		}
139	}
140
141	info = drm_format_info(format);
142	if (!info) {
143		drm_err(dev, "cannot find framebuffer format for depth %u\n", depth);
144		return ERR_PTR(-EINVAL);
145	}
146
147	return info;
148}
149
150static int display_read_u32_of(struct drm_device *dev, struct device_node *of_node,
151			       const char *name, u32 *value)
152{
153	int ret = of_property_read_u32(of_node, name, value);
154
155	if (ret)
156		drm_err(dev, "cannot parse framebuffer %s: error %d\n", name, ret);
157	return ret;
158}
159
160static bool display_get_big_endian_of(struct drm_device *dev, struct device_node *of_node)
161{
162	bool big_endian;
163
164#ifdef __BIG_ENDIAN
165	big_endian = !of_property_read_bool(of_node, "little-endian");
166#else
167	big_endian = of_property_read_bool(of_node, "big-endian");
168#endif
169
170	return big_endian;
171}
172
173static int display_get_width_of(struct drm_device *dev, struct device_node *of_node)
174{
175	u32 width;
176	int ret = display_read_u32_of(dev, of_node, "width", &width);
177
178	if (ret)
179		return ret;
180	return display_get_validated_int0(dev, "width", width);
181}
182
183static int display_get_height_of(struct drm_device *dev, struct device_node *of_node)
184{
185	u32 height;
186	int ret = display_read_u32_of(dev, of_node, "height", &height);
187
188	if (ret)
189		return ret;
190	return display_get_validated_int0(dev, "height", height);
191}
192
193static int display_get_depth_of(struct drm_device *dev, struct device_node *of_node)
194{
195	u32 depth;
196	int ret = display_read_u32_of(dev, of_node, "depth", &depth);
197
198	if (ret)
199		return ret;
200	return display_get_validated_int0(dev, "depth", depth);
201}
202
203static int display_get_linebytes_of(struct drm_device *dev, struct device_node *of_node)
204{
205	u32 linebytes;
206	int ret = display_read_u32_of(dev, of_node, "linebytes", &linebytes);
207
208	if (ret)
209		return ret;
210	return display_get_validated_int(dev, "linebytes", linebytes);
211}
212
213static u64 display_get_address_of(struct drm_device *dev, struct device_node *of_node)
214{
215	u32 address;
216	int ret;
217
218	/*
219	 * Not all devices provide an address property, it's not
220	 * a bug if this fails. The driver will try to find the
221	 * framebuffer base address from the device's memory regions.
222	 */
223	ret = of_property_read_u32(of_node, "address", &address);
224	if (ret)
225		return OF_BAD_ADDR;
226
227	return address;
228}
229
230static bool is_avivo(u32 vendor, u32 device)
231{
232	/* This will match most R5xx */
233	return (vendor == PCI_VENDOR_ID_ATI) &&
234	       ((device >= PCI_VENDOR_ID_ATI_R520 && device < 0x7800) ||
235		(PCI_VENDOR_ID_ATI_R600 >= 0x9400));
236}
237
238static enum ofdrm_model display_get_model_of(struct drm_device *dev, struct device_node *of_node)
239{
240	enum ofdrm_model model = OFDRM_MODEL_UNKNOWN;
241
242	if (of_node_name_prefix(of_node, "ATY,Rage128")) {
243		model = OFDRM_MODEL_RAGE128;
244	} else if (of_node_name_prefix(of_node, "ATY,RageM3pA") ||
245		   of_node_name_prefix(of_node, "ATY,RageM3p12A")) {
246		model = OFDRM_MODEL_RAGE_M3A;
247	} else if (of_node_name_prefix(of_node, "ATY,RageM3pB")) {
248		model = OFDRM_MODEL_RAGE_M3B;
249	} else if (of_node_name_prefix(of_node, "ATY,Rage6")) {
250		model = OFDRM_MODEL_RADEON;
251	} else if (of_node_name_prefix(of_node, "ATY,")) {
252		return OFDRM_MODEL_MACH64;
253	} else if (of_device_is_compatible(of_node, "pci1014,b7") ||
254		   of_device_is_compatible(of_node, "pci1014,21c")) {
255		model = OFDRM_MODEL_GXT2000;
256	} else if (of_node_name_prefix(of_node, "vga,Display-")) {
257		struct device_node *of_parent;
258		const __be32 *vendor_p, *device_p;
259
260		/* Look for AVIVO initialized by SLOF */
261		of_parent = of_get_parent(of_node);
262		vendor_p = of_get_property(of_parent, "vendor-id", NULL);
263		device_p = of_get_property(of_parent, "device-id", NULL);
264		if (vendor_p && device_p) {
265			u32 vendor = be32_to_cpup(vendor_p);
266			u32 device = be32_to_cpup(device_p);
267
268			if (is_avivo(vendor, device))
269				model = OFDRM_MODEL_AVIVO;
270		}
271		of_node_put(of_parent);
272	} else if (of_device_is_compatible(of_node, "qemu,std-vga")) {
273		model = OFDRM_MODEL_QEMU;
274	}
275
276	return model;
277}
278
279/*
280 * Open Firmware display device
281 */
282
283struct ofdrm_device;
284
285struct ofdrm_device_funcs {
286	void __iomem *(*cmap_ioremap)(struct ofdrm_device *odev,
287				      struct device_node *of_node,
288				      u64 fb_bas);
289	void (*cmap_write)(struct ofdrm_device *odev, unsigned char index,
290			   unsigned char r, unsigned char g, unsigned char b);
291};
292
293struct ofdrm_device {
294	struct drm_device dev;
295	struct platform_device *pdev;
296
297	const struct ofdrm_device_funcs *funcs;
298
299	/* firmware-buffer settings */
300	struct iosys_map screen_base;
301	struct drm_display_mode mode;
302	const struct drm_format_info *format;
303	unsigned int pitch;
304
305	/* colormap */
306	void __iomem *cmap_base;
307
308	/* modesetting */
309	uint32_t formats[8];
310	struct drm_plane primary_plane;
311	struct drm_crtc crtc;
312	struct drm_encoder encoder;
313	struct drm_connector connector;
314};
315
316static struct ofdrm_device *ofdrm_device_of_dev(struct drm_device *dev)
317{
318	return container_of(dev, struct ofdrm_device, dev);
319}
320
321/*
322 * Hardware
323 */
324
325#if defined(CONFIG_PCI)
326static struct pci_dev *display_get_pci_dev_of(struct drm_device *dev, struct device_node *of_node)
327{
328	const __be32 *vendor_p, *device_p;
329	u32 vendor, device;
330	struct pci_dev *pcidev;
331
332	vendor_p = of_get_property(of_node, "vendor-id", NULL);
333	if (!vendor_p)
334		return ERR_PTR(-ENODEV);
335	vendor = be32_to_cpup(vendor_p);
336
337	device_p = of_get_property(of_node, "device-id", NULL);
338	if (!device_p)
339		return ERR_PTR(-ENODEV);
340	device = be32_to_cpup(device_p);
341
342	pcidev = pci_get_device(vendor, device, NULL);
343	if (!pcidev)
344		return ERR_PTR(-ENODEV);
345
346	return pcidev;
347}
348
349static void ofdrm_pci_release(void *data)
350{
351	struct pci_dev *pcidev = data;
352
353	pci_disable_device(pcidev);
354}
355
356static int ofdrm_device_init_pci(struct ofdrm_device *odev)
357{
358	struct drm_device *dev = &odev->dev;
359	struct platform_device *pdev = to_platform_device(dev->dev);
360	struct device_node *of_node = pdev->dev.of_node;
361	struct pci_dev *pcidev;
362	int ret;
363
364	/*
365	 * Never use pcim_ or other managed helpers on the returned PCI
366	 * device. Otherwise, probing the native driver will fail for
367	 * resource conflicts. PCI-device management has to be tied to
368	 * the lifetime of the platform device until the native driver
369	 * takes over.
370	 */
371	pcidev = display_get_pci_dev_of(dev, of_node);
372	if (IS_ERR(pcidev))
373		return 0; /* no PCI device found; ignore the error */
374
375	ret = pci_enable_device(pcidev);
376	if (ret) {
377		drm_err(dev, "pci_enable_device(%s) failed: %d\n",
378			dev_name(&pcidev->dev), ret);
379		return ret;
380	}
381	ret = devm_add_action_or_reset(&pdev->dev, ofdrm_pci_release, pcidev);
382	if (ret)
383		return ret;
384
385	return 0;
386}
387#else
388static int ofdrm_device_init_pci(struct ofdrm_device *odev)
389{
390	return 0;
391}
392#endif
393
394/*
395 *  OF display settings
396 */
397
398static struct resource *ofdrm_find_fb_resource(struct ofdrm_device *odev,
399					       struct resource *fb_res)
400{
401	struct platform_device *pdev = to_platform_device(odev->dev.dev);
402	struct resource *res, *max_res = NULL;
403	u32 i;
404
405	for (i = 0; pdev->num_resources; ++i) {
406		res = platform_get_resource(pdev, IORESOURCE_MEM, i);
407		if (!res)
408			break; /* all resources processed */
409		if (resource_size(res) < resource_size(fb_res))
410			continue; /* resource too small */
411		if (fb_res->start && resource_contains(res, fb_res))
412			return res; /* resource contains framebuffer */
413		if (!max_res || resource_size(res) > resource_size(max_res))
414			max_res = res; /* store largest resource as fallback */
415	}
416
417	return max_res;
418}
419
420/*
421 * Colormap / Palette
422 */
423
424static void __iomem *get_cmap_address_of(struct ofdrm_device *odev, struct device_node *of_node,
425					 int bar_no, unsigned long offset, unsigned long size)
426{
427	struct drm_device *dev = &odev->dev;
428	const __be32 *addr_p;
429	u64 max_size, address;
430	unsigned int flags;
431	void __iomem *mem;
432
433	addr_p = of_get_pci_address(of_node, bar_no, &max_size, &flags);
434	if (!addr_p)
435		addr_p = of_get_address(of_node, bar_no, &max_size, &flags);
436	if (!addr_p)
437		return IOMEM_ERR_PTR(-ENODEV);
438
439	if ((flags & (IORESOURCE_IO | IORESOURCE_MEM)) == 0)
440		return IOMEM_ERR_PTR(-ENODEV);
441
442	if ((offset + size) >= max_size)
443		return IOMEM_ERR_PTR(-ENODEV);
444
445	address = of_translate_address(of_node, addr_p);
446	if (address == OF_BAD_ADDR)
447		return IOMEM_ERR_PTR(-ENODEV);
448
449	mem = devm_ioremap(dev->dev, address + offset, size);
450	if (!mem)
451		return IOMEM_ERR_PTR(-ENOMEM);
452
453	return mem;
454}
455
456static void __iomem *ofdrm_mach64_cmap_ioremap(struct ofdrm_device *odev,
457					       struct device_node *of_node,
458					       u64 fb_base)
459{
460	struct drm_device *dev = &odev->dev;
461	u64 address;
462	void __iomem *cmap_base;
463
464	address = fb_base & 0xff000000ul;
465	address += 0x7ff000;
466
467	cmap_base = devm_ioremap(dev->dev, address, 0x1000);
468	if (!cmap_base)
469		return IOMEM_ERR_PTR(-ENOMEM);
470
471	return cmap_base;
472}
473
474static void ofdrm_mach64_cmap_write(struct ofdrm_device *odev, unsigned char index,
475				    unsigned char r, unsigned char g, unsigned char b)
476{
477	void __iomem *addr = odev->cmap_base + 0xcc0;
478	void __iomem *data = odev->cmap_base + 0xcc0 + 1;
479
480	writeb(index, addr);
481	writeb(r, data);
482	writeb(g, data);
483	writeb(b, data);
484}
485
486static void __iomem *ofdrm_rage128_cmap_ioremap(struct ofdrm_device *odev,
487						struct device_node *of_node,
488						u64 fb_base)
489{
490	return get_cmap_address_of(odev, of_node, 2, 0, 0x1fff);
491}
492
493static void ofdrm_rage128_cmap_write(struct ofdrm_device *odev, unsigned char index,
494				     unsigned char r, unsigned char g, unsigned char b)
495{
496	void __iomem *addr = odev->cmap_base + 0xb0;
497	void __iomem *data = odev->cmap_base + 0xb4;
498	u32 color = (r << 16) | (g << 8) | b;
499
500	writeb(index, addr);
501	writel(color, data);
502}
503
504static void __iomem *ofdrm_rage_m3a_cmap_ioremap(struct ofdrm_device *odev,
505						 struct device_node *of_node,
506						 u64 fb_base)
507{
508	return get_cmap_address_of(odev, of_node, 2, 0, 0x1fff);
509}
510
511static void ofdrm_rage_m3a_cmap_write(struct ofdrm_device *odev, unsigned char index,
512				      unsigned char r, unsigned char g, unsigned char b)
513{
514	void __iomem *dac_ctl = odev->cmap_base + 0x58;
515	void __iomem *addr = odev->cmap_base + 0xb0;
516	void __iomem *data = odev->cmap_base + 0xb4;
517	u32 color = (r << 16) | (g << 8) | b;
518	u32 val;
519
520	/* Clear PALETTE_ACCESS_CNTL in DAC_CNTL */
521	val = readl(dac_ctl);
522	val &= ~0x20;
523	writel(val, dac_ctl);
524
525	/* Set color at palette index */
526	writeb(index, addr);
527	writel(color, data);
528}
529
530static void __iomem *ofdrm_rage_m3b_cmap_ioremap(struct ofdrm_device *odev,
531						 struct device_node *of_node,
532						 u64 fb_base)
533{
534	return get_cmap_address_of(odev, of_node, 2, 0, 0x1fff);
535}
536
537static void ofdrm_rage_m3b_cmap_write(struct ofdrm_device *odev, unsigned char index,
538				      unsigned char r, unsigned char g, unsigned char b)
539{
540	void __iomem *dac_ctl = odev->cmap_base + 0x58;
541	void __iomem *addr = odev->cmap_base + 0xb0;
542	void __iomem *data = odev->cmap_base + 0xb4;
543	u32 color = (r << 16) | (g << 8) | b;
544	u32 val;
545
546	/* Set PALETTE_ACCESS_CNTL in DAC_CNTL */
547	val = readl(dac_ctl);
548	val |= 0x20;
549	writel(val, dac_ctl);
550
551	/* Set color at palette index */
552	writeb(index, addr);
553	writel(color, data);
554}
555
556static void __iomem *ofdrm_radeon_cmap_ioremap(struct ofdrm_device *odev,
557					       struct device_node *of_node,
558					       u64 fb_base)
559{
560	return get_cmap_address_of(odev, of_node, 1, 0, 0x1fff);
561}
562
563static void __iomem *ofdrm_gxt2000_cmap_ioremap(struct ofdrm_device *odev,
564						struct device_node *of_node,
565						u64 fb_base)
566{
567	return get_cmap_address_of(odev, of_node, 0, 0x6000, 0x1000);
568}
569
570static void ofdrm_gxt2000_cmap_write(struct ofdrm_device *odev, unsigned char index,
571				     unsigned char r, unsigned char g, unsigned char b)
572{
573	void __iomem *data = ((unsigned int __iomem *)odev->cmap_base) + index;
574	u32 color = (r << 16) | (g << 8) | b;
575
576	writel(color, data);
577}
578
579static void __iomem *ofdrm_avivo_cmap_ioremap(struct ofdrm_device *odev,
580					      struct device_node *of_node,
581					      u64 fb_base)
582{
583	struct device_node *of_parent;
584	void __iomem *cmap_base;
585
586	of_parent = of_get_parent(of_node);
587	cmap_base = get_cmap_address_of(odev, of_parent, 0, 0, 0x10000);
588	of_node_put(of_parent);
589
590	return cmap_base;
591}
592
593static void ofdrm_avivo_cmap_write(struct ofdrm_device *odev, unsigned char index,
594				   unsigned char r, unsigned char g, unsigned char b)
595{
596	void __iomem *lutsel = odev->cmap_base + AVIVO_DC_LUT_RW_SELECT;
597	void __iomem *addr = odev->cmap_base + AVIVO_DC_LUT_RW_INDEX;
598	void __iomem *data = odev->cmap_base + AVIVO_DC_LUT_30_COLOR;
599	u32 color = (r << 22) | (g << 12) | (b << 2);
600
601	/* Write to both LUTs for now */
602
603	writel(1, lutsel);
604	writeb(index, addr);
605	writel(color, data);
606
607	writel(0, lutsel);
608	writeb(index, addr);
609	writel(color, data);
610}
611
612static void __iomem *ofdrm_qemu_cmap_ioremap(struct ofdrm_device *odev,
613					     struct device_node *of_node,
614					     u64 fb_base)
615{
616	static const __be32 io_of_addr[3] = {
617		cpu_to_be32(0x01000000),
618		cpu_to_be32(0x00),
619		cpu_to_be32(0x00),
620	};
621
622	struct drm_device *dev = &odev->dev;
623	u64 address;
624	void __iomem *cmap_base;
625
626	address = of_translate_address(of_node, io_of_addr);
627	if (address == OF_BAD_ADDR)
628		return IOMEM_ERR_PTR(-ENODEV);
629
630	cmap_base = devm_ioremap(dev->dev, address + 0x3c8, 2);
631	if (!cmap_base)
632		return IOMEM_ERR_PTR(-ENOMEM);
633
634	return cmap_base;
635}
636
637static void ofdrm_qemu_cmap_write(struct ofdrm_device *odev, unsigned char index,
638				  unsigned char r, unsigned char g, unsigned char b)
639{
640	void __iomem *addr = odev->cmap_base;
641	void __iomem *data = odev->cmap_base + 1;
642
643	writeb(index, addr);
644	writeb(r, data);
645	writeb(g, data);
646	writeb(b, data);
647}
648
649static void ofdrm_device_set_gamma_linear(struct ofdrm_device *odev,
650					  const struct drm_format_info *format)
651{
652	struct drm_device *dev = &odev->dev;
653	int i;
654
655	switch (format->format) {
656	case DRM_FORMAT_RGB565:
657	case DRM_FORMAT_RGB565 | DRM_FORMAT_BIG_ENDIAN:
658		/* Use better interpolation, to take 32 values from 0 to 255 */
659		for (i = 0; i < OFDRM_GAMMA_LUT_SIZE / 8; i++) {
660			unsigned char r = i * 8 + i / 4;
661			unsigned char g = i * 4 + i / 16;
662			unsigned char b = i * 8 + i / 4;
663
664			odev->funcs->cmap_write(odev, i, r, g, b);
665		}
666		/* Green has one more bit, so add padding with 0 for red and blue. */
667		for (i = OFDRM_GAMMA_LUT_SIZE / 8; i < OFDRM_GAMMA_LUT_SIZE / 4; i++) {
668			unsigned char r = 0;
669			unsigned char g = i * 4 + i / 16;
670			unsigned char b = 0;
671
672			odev->funcs->cmap_write(odev, i, r, g, b);
673		}
674		break;
675	case DRM_FORMAT_XRGB8888:
676	case DRM_FORMAT_BGRX8888:
677		for (i = 0; i < OFDRM_GAMMA_LUT_SIZE; i++)
678			odev->funcs->cmap_write(odev, i, i, i, i);
679		break;
680	default:
681		drm_warn_once(dev, "Unsupported format %p4cc for gamma correction\n",
682			      &format->format);
683		break;
684	}
685}
686
687static void ofdrm_device_set_gamma(struct ofdrm_device *odev,
688				   const struct drm_format_info *format,
689				   struct drm_color_lut *lut)
690{
691	struct drm_device *dev = &odev->dev;
692	int i;
693
694	switch (format->format) {
695	case DRM_FORMAT_RGB565:
696	case DRM_FORMAT_RGB565 | DRM_FORMAT_BIG_ENDIAN:
697		/* Use better interpolation, to take 32 values from lut[0] to lut[255] */
698		for (i = 0; i < OFDRM_GAMMA_LUT_SIZE / 8; i++) {
699			unsigned char r = lut[i * 8 + i / 4].red >> 8;
700			unsigned char g = lut[i * 4 + i / 16].green >> 8;
701			unsigned char b = lut[i * 8 + i / 4].blue >> 8;
702
703			odev->funcs->cmap_write(odev, i, r, g, b);
704		}
705		/* Green has one more bit, so add padding with 0 for red and blue. */
706		for (i = OFDRM_GAMMA_LUT_SIZE / 8; i < OFDRM_GAMMA_LUT_SIZE / 4; i++) {
707			unsigned char r = 0;
708			unsigned char g = lut[i * 4 + i / 16].green >> 8;
709			unsigned char b = 0;
710
711			odev->funcs->cmap_write(odev, i, r, g, b);
712		}
713		break;
714	case DRM_FORMAT_XRGB8888:
715	case DRM_FORMAT_BGRX8888:
716		for (i = 0; i < OFDRM_GAMMA_LUT_SIZE; i++) {
717			unsigned char r = lut[i].red >> 8;
718			unsigned char g = lut[i].green >> 8;
719			unsigned char b = lut[i].blue >> 8;
720
721			odev->funcs->cmap_write(odev, i, r, g, b);
722		}
723		break;
724	default:
725		drm_warn_once(dev, "Unsupported format %p4cc for gamma correction\n",
726			      &format->format);
727		break;
728	}
729}
730
731/*
732 * Modesetting
733 */
734
735struct ofdrm_crtc_state {
736	struct drm_crtc_state base;
737
738	/* Primary-plane format; required for color mgmt. */
739	const struct drm_format_info *format;
740};
741
742static struct ofdrm_crtc_state *to_ofdrm_crtc_state(struct drm_crtc_state *base)
743{
744	return container_of(base, struct ofdrm_crtc_state, base);
745}
746
747static void ofdrm_crtc_state_destroy(struct ofdrm_crtc_state *ofdrm_crtc_state)
748{
749	__drm_atomic_helper_crtc_destroy_state(&ofdrm_crtc_state->base);
750	kfree(ofdrm_crtc_state);
751}
752
753static const uint64_t ofdrm_primary_plane_format_modifiers[] = {
754	DRM_FORMAT_MOD_LINEAR,
755	DRM_FORMAT_MOD_INVALID
756};
757
758static int ofdrm_primary_plane_helper_atomic_check(struct drm_plane *plane,
759						   struct drm_atomic_state *new_state)
760{
761	struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(new_state, plane);
762	struct drm_framebuffer *new_fb = new_plane_state->fb;
763	struct drm_crtc *new_crtc = new_plane_state->crtc;
764	struct drm_crtc_state *new_crtc_state = NULL;
765	struct ofdrm_crtc_state *new_ofdrm_crtc_state;
766	int ret;
767
768	if (new_crtc)
769		new_crtc_state = drm_atomic_get_new_crtc_state(new_state, new_plane_state->crtc);
770
771	ret = drm_atomic_helper_check_plane_state(new_plane_state, new_crtc_state,
772						  DRM_PLANE_NO_SCALING,
773						  DRM_PLANE_NO_SCALING,
774						  false, false);
775	if (ret)
776		return ret;
777	else if (!new_plane_state->visible)
778		return 0;
779
780	new_crtc_state = drm_atomic_get_new_crtc_state(new_state, new_plane_state->crtc);
781
782	new_ofdrm_crtc_state = to_ofdrm_crtc_state(new_crtc_state);
783	new_ofdrm_crtc_state->format = new_fb->format;
784
785	return 0;
786}
787
788static void ofdrm_primary_plane_helper_atomic_update(struct drm_plane *plane,
789						     struct drm_atomic_state *state)
790{
791	struct drm_device *dev = plane->dev;
792	struct ofdrm_device *odev = ofdrm_device_of_dev(dev);
793	struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
794	struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane);
795	struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
796	struct drm_framebuffer *fb = plane_state->fb;
797	unsigned int dst_pitch = odev->pitch;
798	const struct drm_format_info *dst_format = odev->format;
799	struct drm_atomic_helper_damage_iter iter;
800	struct drm_rect damage;
801	int ret, idx;
802
803	ret = drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE);
804	if (ret)
805		return;
806
807	if (!drm_dev_enter(dev, &idx))
808		goto out_drm_gem_fb_end_cpu_access;
809
810	drm_atomic_helper_damage_iter_init(&iter, old_plane_state, plane_state);
811	drm_atomic_for_each_plane_damage(&iter, &damage) {
812		struct iosys_map dst = odev->screen_base;
813		struct drm_rect dst_clip = plane_state->dst;
814
815		if (!drm_rect_intersect(&dst_clip, &damage))
816			continue;
817
818		iosys_map_incr(&dst, drm_fb_clip_offset(dst_pitch, dst_format, &dst_clip));
819		drm_fb_blit(&dst, &dst_pitch, dst_format->format, shadow_plane_state->data, fb,
820			    &damage);
821	}
822
823	drm_dev_exit(idx);
824out_drm_gem_fb_end_cpu_access:
825	drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE);
826}
827
828static void ofdrm_primary_plane_helper_atomic_disable(struct drm_plane *plane,
829						      struct drm_atomic_state *state)
830{
831	struct drm_device *dev = plane->dev;
832	struct ofdrm_device *odev = ofdrm_device_of_dev(dev);
833	struct iosys_map dst = odev->screen_base;
834	struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
835	void __iomem *dst_vmap = dst.vaddr_iomem; /* TODO: Use mapping abstraction */
836	unsigned int dst_pitch = odev->pitch;
837	const struct drm_format_info *dst_format = odev->format;
838	struct drm_rect dst_clip;
839	unsigned long lines, linepixels, i;
840	int idx;
841
842	drm_rect_init(&dst_clip,
843		      plane_state->src_x >> 16, plane_state->src_y >> 16,
844		      plane_state->src_w >> 16, plane_state->src_h >> 16);
845
846	lines = drm_rect_height(&dst_clip);
847	linepixels = drm_rect_width(&dst_clip);
848
849	if (!drm_dev_enter(dev, &idx))
850		return;
851
852	/* Clear buffer to black if disabled */
853	dst_vmap += drm_fb_clip_offset(dst_pitch, dst_format, &dst_clip);
854	for (i = 0; i < lines; ++i) {
855		memset_io(dst_vmap, 0, linepixels * dst_format->cpp[0]);
856		dst_vmap += dst_pitch;
857	}
858
859	drm_dev_exit(idx);
860}
861
862static const struct drm_plane_helper_funcs ofdrm_primary_plane_helper_funcs = {
863	DRM_GEM_SHADOW_PLANE_HELPER_FUNCS,
864	.atomic_check = ofdrm_primary_plane_helper_atomic_check,
865	.atomic_update = ofdrm_primary_plane_helper_atomic_update,
866	.atomic_disable = ofdrm_primary_plane_helper_atomic_disable,
867};
868
869static const struct drm_plane_funcs ofdrm_primary_plane_funcs = {
870	.update_plane = drm_atomic_helper_update_plane,
871	.disable_plane = drm_atomic_helper_disable_plane,
872	.destroy = drm_plane_cleanup,
873	DRM_GEM_SHADOW_PLANE_FUNCS,
874};
875
876static enum drm_mode_status ofdrm_crtc_helper_mode_valid(struct drm_crtc *crtc,
877							 const struct drm_display_mode *mode)
878{
879	struct ofdrm_device *odev = ofdrm_device_of_dev(crtc->dev);
880
881	return drm_crtc_helper_mode_valid_fixed(crtc, mode, &odev->mode);
882}
883
884static int ofdrm_crtc_helper_atomic_check(struct drm_crtc *crtc,
885					  struct drm_atomic_state *new_state)
886{
887	static const size_t gamma_lut_length = OFDRM_GAMMA_LUT_SIZE * sizeof(struct drm_color_lut);
888
889	struct drm_device *dev = crtc->dev;
890	struct drm_crtc_state *new_crtc_state = drm_atomic_get_new_crtc_state(new_state, crtc);
891	int ret;
892
893	if (!new_crtc_state->enable)
894		return 0;
895
896	ret = drm_atomic_helper_check_crtc_primary_plane(new_crtc_state);
897	if (ret)
898		return ret;
899
900	if (new_crtc_state->color_mgmt_changed) {
901		struct drm_property_blob *gamma_lut = new_crtc_state->gamma_lut;
902
903		if (gamma_lut && (gamma_lut->length != gamma_lut_length)) {
904			drm_dbg(dev, "Incorrect gamma_lut length %zu\n", gamma_lut->length);
905			return -EINVAL;
906		}
907	}
908
909	return 0;
910}
911
912static void ofdrm_crtc_helper_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_state *state)
913{
914	struct ofdrm_device *odev = ofdrm_device_of_dev(crtc->dev);
915	struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
916	struct ofdrm_crtc_state *ofdrm_crtc_state = to_ofdrm_crtc_state(crtc_state);
917
918	if (crtc_state->enable && crtc_state->color_mgmt_changed) {
919		const struct drm_format_info *format = ofdrm_crtc_state->format;
920
921		if (crtc_state->gamma_lut)
922			ofdrm_device_set_gamma(odev, format, crtc_state->gamma_lut->data);
923		else
924			ofdrm_device_set_gamma_linear(odev, format);
925	}
926}
927
928/*
929 * The CRTC is always enabled. Screen updates are performed by
930 * the primary plane's atomic_update function. Disabling clears
931 * the screen in the primary plane's atomic_disable function.
932 */
933static const struct drm_crtc_helper_funcs ofdrm_crtc_helper_funcs = {
934	.mode_valid = ofdrm_crtc_helper_mode_valid,
935	.atomic_check = ofdrm_crtc_helper_atomic_check,
936	.atomic_flush = ofdrm_crtc_helper_atomic_flush,
937};
938
939static void ofdrm_crtc_reset(struct drm_crtc *crtc)
940{
941	struct ofdrm_crtc_state *ofdrm_crtc_state =
942		kzalloc(sizeof(*ofdrm_crtc_state), GFP_KERNEL);
943
944	if (crtc->state)
945		ofdrm_crtc_state_destroy(to_ofdrm_crtc_state(crtc->state));
946
947	if (ofdrm_crtc_state)
948		__drm_atomic_helper_crtc_reset(crtc, &ofdrm_crtc_state->base);
949	else
950		__drm_atomic_helper_crtc_reset(crtc, NULL);
951}
952
953static struct drm_crtc_state *ofdrm_crtc_atomic_duplicate_state(struct drm_crtc *crtc)
954{
955	struct drm_device *dev = crtc->dev;
956	struct drm_crtc_state *crtc_state = crtc->state;
957	struct ofdrm_crtc_state *new_ofdrm_crtc_state;
958	struct ofdrm_crtc_state *ofdrm_crtc_state;
959
960	if (drm_WARN_ON(dev, !crtc_state))
961		return NULL;
962
963	new_ofdrm_crtc_state = kzalloc(sizeof(*new_ofdrm_crtc_state), GFP_KERNEL);
964	if (!new_ofdrm_crtc_state)
965		return NULL;
966
967	ofdrm_crtc_state = to_ofdrm_crtc_state(crtc_state);
968
969	__drm_atomic_helper_crtc_duplicate_state(crtc, &new_ofdrm_crtc_state->base);
970	new_ofdrm_crtc_state->format = ofdrm_crtc_state->format;
971
972	return &new_ofdrm_crtc_state->base;
973}
974
975static void ofdrm_crtc_atomic_destroy_state(struct drm_crtc *crtc,
976					    struct drm_crtc_state *crtc_state)
977{
978	ofdrm_crtc_state_destroy(to_ofdrm_crtc_state(crtc_state));
979}
980
981static const struct drm_crtc_funcs ofdrm_crtc_funcs = {
982	.reset = ofdrm_crtc_reset,
983	.destroy = drm_crtc_cleanup,
984	.set_config = drm_atomic_helper_set_config,
985	.page_flip = drm_atomic_helper_page_flip,
986	.atomic_duplicate_state = ofdrm_crtc_atomic_duplicate_state,
987	.atomic_destroy_state = ofdrm_crtc_atomic_destroy_state,
988};
989
990static int ofdrm_connector_helper_get_modes(struct drm_connector *connector)
991{
992	struct ofdrm_device *odev = ofdrm_device_of_dev(connector->dev);
993
994	return drm_connector_helper_get_modes_fixed(connector, &odev->mode);
995}
996
997static const struct drm_connector_helper_funcs ofdrm_connector_helper_funcs = {
998	.get_modes = ofdrm_connector_helper_get_modes,
999};
1000
1001static const struct drm_connector_funcs ofdrm_connector_funcs = {
1002	.reset = drm_atomic_helper_connector_reset,
1003	.fill_modes = drm_helper_probe_single_connector_modes,
1004	.destroy = drm_connector_cleanup,
1005	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
1006	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
1007};
1008
1009static const struct drm_mode_config_funcs ofdrm_mode_config_funcs = {
1010	.fb_create = drm_gem_fb_create_with_dirty,
1011	.atomic_check = drm_atomic_helper_check,
1012	.atomic_commit = drm_atomic_helper_commit,
1013};
1014
1015/*
1016 * Init / Cleanup
1017 */
1018
1019static const struct ofdrm_device_funcs ofdrm_unknown_device_funcs = {
1020};
1021
1022static const struct ofdrm_device_funcs ofdrm_mach64_device_funcs = {
1023	.cmap_ioremap = ofdrm_mach64_cmap_ioremap,
1024	.cmap_write = ofdrm_mach64_cmap_write,
1025};
1026
1027static const struct ofdrm_device_funcs ofdrm_rage128_device_funcs = {
1028	.cmap_ioremap = ofdrm_rage128_cmap_ioremap,
1029	.cmap_write = ofdrm_rage128_cmap_write,
1030};
1031
1032static const struct ofdrm_device_funcs ofdrm_rage_m3a_device_funcs = {
1033	.cmap_ioremap = ofdrm_rage_m3a_cmap_ioremap,
1034	.cmap_write = ofdrm_rage_m3a_cmap_write,
1035};
1036
1037static const struct ofdrm_device_funcs ofdrm_rage_m3b_device_funcs = {
1038	.cmap_ioremap = ofdrm_rage_m3b_cmap_ioremap,
1039	.cmap_write = ofdrm_rage_m3b_cmap_write,
1040};
1041
1042static const struct ofdrm_device_funcs ofdrm_radeon_device_funcs = {
1043	.cmap_ioremap = ofdrm_radeon_cmap_ioremap,
1044	.cmap_write = ofdrm_rage128_cmap_write, /* same as Rage128 */
1045};
1046
1047static const struct ofdrm_device_funcs ofdrm_gxt2000_device_funcs = {
1048	.cmap_ioremap = ofdrm_gxt2000_cmap_ioremap,
1049	.cmap_write = ofdrm_gxt2000_cmap_write,
1050};
1051
1052static const struct ofdrm_device_funcs ofdrm_avivo_device_funcs = {
1053	.cmap_ioremap = ofdrm_avivo_cmap_ioremap,
1054	.cmap_write = ofdrm_avivo_cmap_write,
1055};
1056
1057static const struct ofdrm_device_funcs ofdrm_qemu_device_funcs = {
1058	.cmap_ioremap = ofdrm_qemu_cmap_ioremap,
1059	.cmap_write = ofdrm_qemu_cmap_write,
1060};
1061
1062static struct drm_display_mode ofdrm_mode(unsigned int width, unsigned int height)
1063{
1064	/*
1065	 * Assume a monitor resolution of 96 dpi to
1066	 * get a somewhat reasonable screen size.
1067	 */
1068	const struct drm_display_mode mode = {
1069		DRM_MODE_INIT(60, width, height,
1070			      DRM_MODE_RES_MM(width, 96ul),
1071			      DRM_MODE_RES_MM(height, 96ul))
1072	};
1073
1074	return mode;
1075}
1076
1077static struct ofdrm_device *ofdrm_device_create(struct drm_driver *drv,
1078						struct platform_device *pdev)
1079{
1080	struct device_node *of_node = pdev->dev.of_node;
1081	struct ofdrm_device *odev;
1082	struct drm_device *dev;
1083	enum ofdrm_model model;
1084	bool big_endian;
1085	int width, height, depth, linebytes;
1086	const struct drm_format_info *format;
1087	u64 address;
1088	resource_size_t fb_size, fb_base, fb_pgbase, fb_pgsize;
1089	struct resource *res, *mem;
1090	void __iomem *screen_base;
1091	struct drm_plane *primary_plane;
1092	struct drm_crtc *crtc;
1093	struct drm_encoder *encoder;
1094	struct drm_connector *connector;
1095	unsigned long max_width, max_height;
1096	size_t nformats;
1097	int ret;
1098
1099	odev = devm_drm_dev_alloc(&pdev->dev, drv, struct ofdrm_device, dev);
1100	if (IS_ERR(odev))
1101		return ERR_CAST(odev);
1102	dev = &odev->dev;
1103	platform_set_drvdata(pdev, dev);
1104
1105	ret = ofdrm_device_init_pci(odev);
1106	if (ret)
1107		return ERR_PTR(ret);
1108
1109	/*
1110	 * OF display-node settings
1111	 */
1112
1113	model = display_get_model_of(dev, of_node);
1114	drm_dbg(dev, "detected model %d\n", model);
1115
1116	switch (model) {
1117	case OFDRM_MODEL_UNKNOWN:
1118		odev->funcs = &ofdrm_unknown_device_funcs;
1119		break;
1120	case OFDRM_MODEL_MACH64:
1121		odev->funcs = &ofdrm_mach64_device_funcs;
1122		break;
1123	case OFDRM_MODEL_RAGE128:
1124		odev->funcs = &ofdrm_rage128_device_funcs;
1125		break;
1126	case OFDRM_MODEL_RAGE_M3A:
1127		odev->funcs = &ofdrm_rage_m3a_device_funcs;
1128		break;
1129	case OFDRM_MODEL_RAGE_M3B:
1130		odev->funcs = &ofdrm_rage_m3b_device_funcs;
1131		break;
1132	case OFDRM_MODEL_RADEON:
1133		odev->funcs = &ofdrm_radeon_device_funcs;
1134		break;
1135	case OFDRM_MODEL_GXT2000:
1136		odev->funcs = &ofdrm_gxt2000_device_funcs;
1137		break;
1138	case OFDRM_MODEL_AVIVO:
1139		odev->funcs = &ofdrm_avivo_device_funcs;
1140		break;
1141	case OFDRM_MODEL_QEMU:
1142		odev->funcs = &ofdrm_qemu_device_funcs;
1143		break;
1144	}
1145
1146	big_endian = display_get_big_endian_of(dev, of_node);
1147
1148	width = display_get_width_of(dev, of_node);
1149	if (width < 0)
1150		return ERR_PTR(width);
1151	height = display_get_height_of(dev, of_node);
1152	if (height < 0)
1153		return ERR_PTR(height);
1154	depth = display_get_depth_of(dev, of_node);
1155	if (depth < 0)
1156		return ERR_PTR(depth);
1157	linebytes = display_get_linebytes_of(dev, of_node);
1158	if (linebytes < 0)
1159		return ERR_PTR(linebytes);
1160
1161	format = display_get_validated_format(dev, depth, big_endian);
1162	if (IS_ERR(format))
1163		return ERR_CAST(format);
1164	if (!linebytes) {
1165		linebytes = drm_format_info_min_pitch(format, 0, width);
1166		if (drm_WARN_ON(dev, !linebytes))
1167			return ERR_PTR(-EINVAL);
1168	}
1169
1170	fb_size = linebytes * height;
1171
1172	/*
1173	 * Try to figure out the address of the framebuffer. Unfortunately, Open
1174	 * Firmware doesn't provide a standard way to do so. All we can do is a
1175	 * dodgy heuristic that happens to work in practice.
1176	 *
1177	 * On most machines, the "address" property contains what we need, though
1178	 * not on Matrox cards found in IBM machines. What appears to give good
1179	 * results is to go through the PCI ranges and pick one that encloses the
1180	 * "address" property. If none match, we pick the largest.
1181	 */
1182	address = display_get_address_of(dev, of_node);
1183	if (address != OF_BAD_ADDR) {
1184		struct resource fb_res = DEFINE_RES_MEM(address, fb_size);
1185
1186		res = ofdrm_find_fb_resource(odev, &fb_res);
1187		if (!res)
1188			return ERR_PTR(-EINVAL);
1189		if (resource_contains(res, &fb_res))
1190			fb_base = address;
1191		else
1192			fb_base = res->start;
1193	} else {
1194		struct resource fb_res = DEFINE_RES_MEM(0u, fb_size);
1195
1196		res = ofdrm_find_fb_resource(odev, &fb_res);
1197		if (!res)
1198			return ERR_PTR(-EINVAL);
1199		fb_base = res->start;
1200	}
1201
1202	/*
1203	 * I/O resources
1204	 */
1205
1206	fb_pgbase = round_down(fb_base, PAGE_SIZE);
1207	fb_pgsize = fb_base - fb_pgbase + round_up(fb_size, PAGE_SIZE);
1208
1209	ret = devm_aperture_acquire_from_firmware(dev, fb_pgbase, fb_pgsize);
1210	if (ret) {
1211		drm_err(dev, "could not acquire memory range %pr: error %d\n", &res, ret);
1212		return ERR_PTR(ret);
1213	}
1214
1215	mem = devm_request_mem_region(&pdev->dev, fb_pgbase, fb_pgsize, drv->name);
1216	if (!mem) {
1217		drm_warn(dev, "could not acquire memory region %pr\n", &res);
1218		return ERR_PTR(-ENOMEM);
1219	}
1220
1221	screen_base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
1222	if (!screen_base)
1223		return ERR_PTR(-ENOMEM);
1224
1225	if (odev->funcs->cmap_ioremap) {
1226		void __iomem *cmap_base = odev->funcs->cmap_ioremap(odev, of_node, fb_base);
1227
1228		if (IS_ERR(cmap_base)) {
1229			/* Don't fail; continue without colormap */
1230			drm_warn(dev, "could not find colormap: error %ld\n", PTR_ERR(cmap_base));
1231		} else {
1232			odev->cmap_base = cmap_base;
1233		}
1234	}
1235
1236	/*
1237	 * Firmware framebuffer
1238	 */
1239
1240	iosys_map_set_vaddr_iomem(&odev->screen_base, screen_base);
1241	odev->mode = ofdrm_mode(width, height);
1242	odev->format = format;
1243	odev->pitch = linebytes;
1244
1245	drm_dbg(dev, "display mode={" DRM_MODE_FMT "}\n", DRM_MODE_ARG(&odev->mode));
1246	drm_dbg(dev, "framebuffer format=%p4cc, size=%dx%d, linebytes=%d byte\n",
1247		&format->format, width, height, linebytes);
1248
1249	/*
1250	 * Mode-setting pipeline
1251	 */
1252
1253	ret = drmm_mode_config_init(dev);
1254	if (ret)
1255		return ERR_PTR(ret);
1256
1257	max_width = max_t(unsigned long, width, DRM_SHADOW_PLANE_MAX_WIDTH);
1258	max_height = max_t(unsigned long, height, DRM_SHADOW_PLANE_MAX_HEIGHT);
1259
1260	dev->mode_config.min_width = width;
1261	dev->mode_config.max_width = max_width;
1262	dev->mode_config.min_height = height;
1263	dev->mode_config.max_height = max_height;
1264	dev->mode_config.funcs = &ofdrm_mode_config_funcs;
1265	dev->mode_config.preferred_depth = format->depth;
1266	dev->mode_config.quirk_addfb_prefer_host_byte_order = true;
1267
1268	/* Primary plane */
1269
1270	nformats = drm_fb_build_fourcc_list(dev, &format->format, 1,
1271					    odev->formats, ARRAY_SIZE(odev->formats));
1272
1273	primary_plane = &odev->primary_plane;
1274	ret = drm_universal_plane_init(dev, primary_plane, 0, &ofdrm_primary_plane_funcs,
1275				       odev->formats, nformats,
1276				       ofdrm_primary_plane_format_modifiers,
1277				       DRM_PLANE_TYPE_PRIMARY, NULL);
1278	if (ret)
1279		return ERR_PTR(ret);
1280	drm_plane_helper_add(primary_plane, &ofdrm_primary_plane_helper_funcs);
1281	drm_plane_enable_fb_damage_clips(primary_plane);
1282
1283	/* CRTC */
1284
1285	crtc = &odev->crtc;
1286	ret = drm_crtc_init_with_planes(dev, crtc, primary_plane, NULL,
1287					&ofdrm_crtc_funcs, NULL);
1288	if (ret)
1289		return ERR_PTR(ret);
1290	drm_crtc_helper_add(crtc, &ofdrm_crtc_helper_funcs);
1291
1292	if (odev->cmap_base) {
1293		drm_mode_crtc_set_gamma_size(crtc, OFDRM_GAMMA_LUT_SIZE);
1294		drm_crtc_enable_color_mgmt(crtc, 0, false, OFDRM_GAMMA_LUT_SIZE);
1295	}
1296
1297	/* Encoder */
1298
1299	encoder = &odev->encoder;
1300	ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_NONE);
1301	if (ret)
1302		return ERR_PTR(ret);
1303	encoder->possible_crtcs = drm_crtc_mask(crtc);
1304
1305	/* Connector */
1306
1307	connector = &odev->connector;
1308	ret = drm_connector_init(dev, connector, &ofdrm_connector_funcs,
1309				 DRM_MODE_CONNECTOR_Unknown);
1310	if (ret)
1311		return ERR_PTR(ret);
1312	drm_connector_helper_add(connector, &ofdrm_connector_helper_funcs);
1313	drm_connector_set_panel_orientation_with_quirk(connector,
1314						       DRM_MODE_PANEL_ORIENTATION_UNKNOWN,
1315						       width, height);
1316
1317	ret = drm_connector_attach_encoder(connector, encoder);
1318	if (ret)
1319		return ERR_PTR(ret);
1320
1321	drm_mode_config_reset(dev);
1322
1323	return odev;
1324}
1325
1326/*
1327 * DRM driver
1328 */
1329
1330DEFINE_DRM_GEM_FOPS(ofdrm_fops);
1331
1332static struct drm_driver ofdrm_driver = {
1333	DRM_GEM_SHMEM_DRIVER_OPS,
1334	.name			= DRIVER_NAME,
1335	.desc			= DRIVER_DESC,
1336	.date			= DRIVER_DATE,
1337	.major			= DRIVER_MAJOR,
1338	.minor			= DRIVER_MINOR,
1339	.driver_features	= DRIVER_ATOMIC | DRIVER_GEM | DRIVER_MODESET,
1340	.fops			= &ofdrm_fops,
1341};
1342
1343/*
1344 * Platform driver
1345 */
1346
1347static int ofdrm_probe(struct platform_device *pdev)
1348{
1349	struct ofdrm_device *odev;
1350	struct drm_device *dev;
1351	unsigned int color_mode;
1352	int ret;
1353
1354	odev = ofdrm_device_create(&ofdrm_driver, pdev);
1355	if (IS_ERR(odev))
1356		return PTR_ERR(odev);
1357	dev = &odev->dev;
1358
1359	ret = drm_dev_register(dev, 0);
1360	if (ret)
1361		return ret;
1362
1363	color_mode = drm_format_info_bpp(odev->format, 0);
1364	if (color_mode == 16)
1365		color_mode = odev->format->depth; // can be 15 or 16
1366
1367	drm_fbdev_generic_setup(dev, color_mode);
1368
1369	return 0;
1370}
1371
1372static void ofdrm_remove(struct platform_device *pdev)
1373{
1374	struct drm_device *dev = platform_get_drvdata(pdev);
1375
1376	drm_dev_unplug(dev);
1377}
1378
1379static const struct of_device_id ofdrm_of_match_display[] = {
1380	{ .compatible = "display", },
1381	{ },
1382};
1383MODULE_DEVICE_TABLE(of, ofdrm_of_match_display);
1384
1385static struct platform_driver ofdrm_platform_driver = {
1386	.driver = {
1387		.name = "of-display",
1388		.of_match_table = ofdrm_of_match_display,
1389	},
1390	.probe = ofdrm_probe,
1391	.remove_new = ofdrm_remove,
1392};
1393
1394module_platform_driver(ofdrm_platform_driver);
1395
1396MODULE_DESCRIPTION(DRIVER_DESC);
1397MODULE_LICENSE("GPL");
1398