1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2020 Dario Binacchi <dariobin@libero.it>
4 */
5
6#include <common.h>
7#include <clk.h>
8#include <dm.h>
9#include <dm/device_compat.h>
10#include <log.h>
11#include <panel.h>
12#include <video.h>
13#include <asm/global_data.h>
14#include <asm/io.h>
15#include <asm/utils.h>
16#include "tilcdc.h"
17#include "tilcdc-panel.h"
18
19#define LCDC_FMAX				200000000
20
21/* LCD Control Register */
22#define LCDC_CTRL_CLK_DIVISOR_MASK		GENMASK(15, 8)
23#define LCDC_CTRL_RASTER_MODE			BIT(0)
24#define LCDC_CTRL_CLK_DIVISOR(x)		(((x) & GENMASK(7, 0)) << 8)
25/* LCD Clock Enable Register */
26#define LCDC_CLKC_ENABLE_CORECLKEN		BIT(0)
27#define LCDC_CLKC_ENABLE_LIDDCLKEN		BIT(1)
28#define LCDC_CLKC_ENABLE_DMACLKEN		BIT(2)
29/* LCD DMA Control Register */
30#define LCDC_DMA_CTRL_BURST_SIZE(x)		(((x) & GENMASK(2, 0)) << 4)
31#define LCDC_DMA_CTRL_BURST_1			0x0
32#define LCDC_DMA_CTRL_BURST_2			0x1
33#define LCDC_DMA_CTRL_BURST_4			0x2
34#define LCDC_DMA_CTRL_BURST_8			0x3
35#define LCDC_DMA_CTRL_BURST_16			0x4
36#define LCDC_DMA_CTRL_FIFO_TH(x)		(((x) & GENMASK(2, 0)) << 8)
37/* LCD Timing_0 Register */
38#define LCDC_RASTER_TIMING_0_HORMSB(x)	((((x) - 1) & BIT(10)) >> 7)
39#define LCDC_RASTER_TIMING_0_HORLSB(x) (((((x) >> 4) - 1) & GENMASK(5, 0)) << 4)
40#define LCDC_RASTER_TIMING_0_HSWLSB(x)	((((x) - 1) & GENMASK(5, 0)) << 10)
41#define LCDC_RASTER_TIMING_0_HFPLSB(x)	((((x) - 1) & GENMASK(7, 0)) << 16)
42#define LCDC_RASTER_TIMING_0_HBPLSB(x)	((((x) - 1) & GENMASK(7, 0)) << 24)
43/* LCD Timing_1 Register */
44#define LCDC_RASTER_TIMING_1_VERLSB(x)		(((x) - 1) & GENMASK(9, 0))
45#define LCDC_RASTER_TIMING_1_VSW(x)	((((x) - 1) & GENMASK(5, 0)) << 10)
46#define LCDC_RASTER_TIMING_1_VFP(x)		(((x) & GENMASK(7, 0)) << 16)
47#define LCDC_RASTER_TIMING_1_VBP(x)		(((x) & GENMASK(7, 0)) << 24)
48/* LCD Timing_2 Register */
49#define LCDC_RASTER_TIMING_2_HFPMSB(x)	((((x) - 1) & GENMASK(9, 8)) >> 8)
50#define LCDC_RASTER_TIMING_2_HBPMSB(x)	((((x) - 1) & GENMASK(9, 8)) >> 4)
51#define LCDC_RASTER_TIMING_2_ACB(x)		(((x) & GENMASK(7, 0)) << 8)
52#define LCDC_RASTER_TIMING_2_ACBI(x)		(((x) & GENMASK(3, 0)) << 16)
53#define LCDC_RASTER_TIMING_2_VSYNC_INVERT	BIT(20)
54#define LCDC_RASTER_TIMING_2_HSYNC_INVERT	BIT(21)
55#define LCDC_RASTER_TIMING_2_PXCLK_INVERT	BIT(22)
56#define LCDC_RASTER_TIMING_2_DE_INVERT		BIT(23)
57#define LCDC_RASTER_TIMING_2_HSVS_RISEFALL	BIT(24)
58#define LCDC_RASTER_TIMING_2_HSVS_CONTROL	BIT(25)
59#define LCDC_RASTER_TIMING_2_VERMSB(x)		((((x) - 1) & BIT(10)) << 16)
60#define LCDC_RASTER_TIMING_2_HSWMSB(x)	((((x) - 1) & GENMASK(9, 6)) << 21)
61/* LCD Raster Ctrl Register */
62#define LCDC_RASTER_CTRL_ENABLE			BIT(0)
63#define LCDC_RASTER_CTRL_TFT_MODE		BIT(7)
64#define LCDC_RASTER_CTRL_DATA_ORDER		BIT(8)
65#define LCDC_RASTER_CTRL_REQDLY(x)		(((x) & GENMASK(7, 0)) << 12)
66#define LCDC_RASTER_CTRL_PALMODE_RAWDATA	(0x02 << 20)
67#define LCDC_RASTER_CTRL_TFT_ALT_ENABLE		BIT(23)
68#define LCDC_RASTER_CTRL_TFT_24BPP_MODE		BIT(25)
69#define LCDC_RASTER_CTRL_TFT_24BPP_UNPACK	BIT(26)
70
71enum {
72	LCDC_MAX_WIDTH = 2048,
73	LCDC_MAX_HEIGHT = 2048,
74	LCDC_MAX_LOG2_BPP = VIDEO_BPP32,
75};
76
77struct tilcdc_regs {
78	u32 pid;
79	u32 ctrl;
80	u32 gap0;
81	u32 lidd_ctrl;
82	u32 lidd_cs0_conf;
83	u32 lidd_cs0_addr;
84	u32 lidd_cs0_data;
85	u32 lidd_cs1_conf;
86	u32 lidd_cs1_addr;
87	u32 lidd_cs1_data;
88	u32 raster_ctrl;
89	u32 raster_timing0;
90	u32 raster_timing1;
91	u32 raster_timing2;
92	u32 raster_subpanel;
93	u32 raster_subpanel2;
94	u32 lcddma_ctrl;
95	u32 lcddma_fb0_base;
96	u32 lcddma_fb0_ceiling;
97	u32 lcddma_fb1_base;
98	u32 lcddma_fb1_ceiling;
99	u32 sysconfig;
100	u32 irqstatus_raw;
101	u32 irqstatus;
102	u32 irqenable_set;
103	u32 irqenable_clear;
104	u32 gap1;
105	u32 clkc_enable;
106	u32 clkc_reset;
107};
108
109struct tilcdc_priv {
110	struct tilcdc_regs *regs;
111	struct clk gclk;
112	struct clk dpll_m2_clk;
113};
114
115DECLARE_GLOBAL_DATA_PTR;
116
117static ulong tilcdc_set_pixel_clk_rate(struct udevice *dev, ulong rate)
118{
119	struct tilcdc_priv *priv = dev_get_priv(dev);
120	struct tilcdc_regs *regs = priv->regs;
121	ulong mult_rate, mult_round_rate, best_err, err;
122	u32 v;
123	int div, i;
124
125	best_err = rate;
126	div = 0;
127	for (i = 2; i <= 255; i++) {
128		mult_rate = rate * i;
129		mult_round_rate = clk_round_rate(&priv->gclk, mult_rate);
130		if (IS_ERR_VALUE(mult_round_rate))
131			return mult_round_rate;
132
133		err = mult_rate - mult_round_rate;
134		if (err < best_err) {
135			best_err = err;
136			div = i;
137			if (err == 0)
138				break;
139		}
140	}
141
142	if (div == 0) {
143		dev_err(dev, "failed to find a divisor\n");
144		return -EFAULT;
145	}
146
147	mult_rate = clk_set_rate(&priv->gclk, rate * div);
148	v = readl(&regs->ctrl) & ~LCDC_CTRL_CLK_DIVISOR_MASK;
149	v |= LCDC_CTRL_CLK_DIVISOR(div);
150	writel(v, &regs->ctrl);
151	rate = mult_rate / div;
152	dev_dbg(dev, "rate=%ld, div=%d, err=%ld\n", rate, div, err);
153	return rate;
154}
155
156static int tilcdc_remove(struct udevice *dev)
157{
158	struct video_uc_plat *uc_plat = dev_get_uclass_plat(dev);
159	struct tilcdc_priv *priv = dev_get_priv(dev);
160
161	uc_plat->base -= 0x20;
162	uc_plat->size += 0x20;
163	clk_release_all(&priv->gclk, 1);
164	clk_release_all(&priv->dpll_m2_clk, 1);
165	return 0;
166}
167
168static int tilcdc_probe(struct udevice *dev)
169{
170	struct video_uc_plat *uc_plat = dev_get_uclass_plat(dev);
171	struct video_priv *uc_priv = dev_get_uclass_priv(dev);
172	struct tilcdc_priv *priv = dev_get_priv(dev);
173	struct tilcdc_regs *regs = priv->regs;
174	struct udevice *panel, *clk_dev;
175	struct tilcdc_panel_info info;
176	struct display_timing timing;
177	ulong rate;
178	u32 reg;
179	int err;
180
181	/* Before relocation we don't need to do anything */
182	if (!(gd->flags & GD_FLG_RELOC))
183		return 0;
184
185	err = uclass_get_device(UCLASS_PANEL, 0, &panel);
186	if (err) {
187		dev_err(dev, "failed to get panel\n");
188		return err;
189	}
190
191	err = panel_get_display_timing(panel, &timing);
192	if (err) {
193		dev_err(dev, "failed to get display timing\n");
194		return err;
195	}
196
197	if (timing.pixelclock.typ > (LCDC_FMAX / 2)) {
198		dev_err(dev, "invalid display clock-frequency: %d Hz\n",
199			timing.pixelclock.typ);
200		return -EINVAL;
201	}
202
203	if (timing.hactive.typ > LCDC_MAX_WIDTH)
204		timing.hactive.typ = LCDC_MAX_WIDTH;
205
206	if (timing.vactive.typ > LCDC_MAX_HEIGHT)
207		timing.vactive.typ = LCDC_MAX_HEIGHT;
208
209	err = tilcdc_panel_get_display_info(panel, &info);
210	if (err) {
211		dev_err(dev, "failed to get panel info\n");
212		return err;
213	}
214
215	switch (info.bpp) {
216	case 16:
217	case 24:
218	case 32:
219		break;
220	default:
221		dev_err(dev, "invalid seting, bpp: %d\n", info.bpp);
222		return -EINVAL;
223	}
224
225	switch (info.dma_burst_sz) {
226	case 1:
227	case 2:
228	case 4:
229	case 8:
230	case 16:
231		break;
232	default:
233		dev_err(dev, "invalid setting, dma-burst-sz: %d\n",
234			info.dma_burst_sz);
235		return -EINVAL;
236	}
237
238	err = uclass_get_device_by_name(UCLASS_CLK, "lcd_gclk@534", &clk_dev);
239	if (err) {
240		dev_err(dev, "failed to get lcd_gclk device\n");
241		return err;
242	}
243
244	err = clk_request(clk_dev, &priv->gclk);
245	if (err) {
246		dev_err(dev, "failed to get %s clock\n", clk_dev->name);
247		return err;
248	}
249
250	rate = tilcdc_set_pixel_clk_rate(dev, timing.pixelclock.typ);
251	if (IS_ERR_VALUE(rate)) {
252		dev_err(dev, "failed to set pixel clock rate\n");
253		return rate;
254	}
255
256	err = uclass_get_device_by_name(UCLASS_CLK, "dpll_disp_m2_ck@4a4",
257					&clk_dev);
258	if (err) {
259		dev_err(dev, "failed to get dpll_disp_m2 clock device\n");
260		return err;
261	}
262
263	err = clk_request(clk_dev, &priv->dpll_m2_clk);
264	if (err) {
265		dev_err(dev, "failed to get %s clock\n", clk_dev->name);
266		return err;
267	}
268
269	err = clk_set_parent(&priv->gclk, &priv->dpll_m2_clk);
270	if (err) {
271		dev_err(dev, "failed to set %s clock as %s's parent\n",
272			priv->dpll_m2_clk.dev->name, priv->gclk.dev->name);
273		return err;
274	}
275
276	/* palette default entry */
277	memset((void *)uc_plat->base, 0, 0x20);
278	*(unsigned int *)uc_plat->base = 0x4000;
279	/* point fb behind palette */
280	uc_plat->base += 0x20;
281	uc_plat->size -= 0x20;
282
283	writel(LCDC_CLKC_ENABLE_CORECLKEN | LCDC_CLKC_ENABLE_LIDDCLKEN |
284	       LCDC_CLKC_ENABLE_DMACLKEN, &regs->clkc_enable);
285	writel(0, &regs->raster_ctrl);
286
287	reg = readl(&regs->ctrl) & LCDC_CTRL_CLK_DIVISOR_MASK;
288	reg |= LCDC_CTRL_RASTER_MODE;
289	writel(reg, &regs->ctrl);
290
291	reg = (timing.hactive.typ * timing.vactive.typ * info.bpp) >> 3;
292	reg += uc_plat->base;
293	writel(uc_plat->base, &regs->lcddma_fb0_base);
294	writel(reg, &regs->lcddma_fb0_ceiling);
295	writel(uc_plat->base, &regs->lcddma_fb1_base);
296	writel(reg, &regs->lcddma_fb1_ceiling);
297
298	reg = LCDC_DMA_CTRL_FIFO_TH(info.fifo_th);
299	switch (info.dma_burst_sz) {
300	case 1:
301		reg |= LCDC_DMA_CTRL_BURST_SIZE(LCDC_DMA_CTRL_BURST_1);
302		break;
303	case 2:
304		reg |= LCDC_DMA_CTRL_BURST_SIZE(LCDC_DMA_CTRL_BURST_2);
305		break;
306	case 4:
307		reg |= LCDC_DMA_CTRL_BURST_SIZE(LCDC_DMA_CTRL_BURST_4);
308		break;
309	case 8:
310		reg |= LCDC_DMA_CTRL_BURST_SIZE(LCDC_DMA_CTRL_BURST_8);
311		break;
312	case 16:
313		reg |= LCDC_DMA_CTRL_BURST_SIZE(LCDC_DMA_CTRL_BURST_16);
314		break;
315	}
316
317	writel(reg, &regs->lcddma_ctrl);
318
319	writel(LCDC_RASTER_TIMING_0_HORLSB(timing.hactive.typ) |
320	       LCDC_RASTER_TIMING_0_HORMSB(timing.hactive.typ) |
321	       LCDC_RASTER_TIMING_0_HFPLSB(timing.hfront_porch.typ) |
322	       LCDC_RASTER_TIMING_0_HBPLSB(timing.hback_porch.typ) |
323	       LCDC_RASTER_TIMING_0_HSWLSB(timing.hsync_len.typ),
324	       &regs->raster_timing0);
325
326	writel(LCDC_RASTER_TIMING_1_VBP(timing.vback_porch.typ) |
327	       LCDC_RASTER_TIMING_1_VFP(timing.vfront_porch.typ) |
328	       LCDC_RASTER_TIMING_1_VSW(timing.vsync_len.typ) |
329	       LCDC_RASTER_TIMING_1_VERLSB(timing.vactive.typ),
330	       &regs->raster_timing1);
331
332	reg = LCDC_RASTER_TIMING_2_ACB(info.ac_bias) |
333		LCDC_RASTER_TIMING_2_ACBI(info.ac_bias_intrpt) |
334		LCDC_RASTER_TIMING_2_HSWMSB(timing.hsync_len.typ) |
335		LCDC_RASTER_TIMING_2_VERMSB(timing.vactive.typ) |
336		LCDC_RASTER_TIMING_2_HBPMSB(timing.hback_porch.typ) |
337		LCDC_RASTER_TIMING_2_HFPMSB(timing.hfront_porch.typ);
338
339	if (timing.flags & DISPLAY_FLAGS_VSYNC_LOW)
340		reg |= LCDC_RASTER_TIMING_2_VSYNC_INVERT;
341
342	if (timing.flags & DISPLAY_FLAGS_HSYNC_LOW)
343		reg |= LCDC_RASTER_TIMING_2_HSYNC_INVERT;
344
345	if (info.invert_pxl_clk)
346		reg |= LCDC_RASTER_TIMING_2_PXCLK_INVERT;
347
348	if (info.sync_edge)
349		reg |= LCDC_RASTER_TIMING_2_HSVS_RISEFALL;
350
351	if (info.sync_ctrl)
352		reg |= LCDC_RASTER_TIMING_2_HSVS_CONTROL;
353
354	writel(reg, &regs->raster_timing2);
355
356	reg = LCDC_RASTER_CTRL_PALMODE_RAWDATA | LCDC_RASTER_CTRL_TFT_MODE |
357		LCDC_RASTER_CTRL_ENABLE | LCDC_RASTER_CTRL_REQDLY(info.fdd);
358
359	if (info.tft_alt_mode)
360		reg |= LCDC_RASTER_CTRL_TFT_ALT_ENABLE;
361
362	if (info.bpp == 24)
363		reg |= LCDC_RASTER_CTRL_TFT_24BPP_MODE;
364	else if (info.bpp == 32)
365		reg |= LCDC_RASTER_CTRL_TFT_24BPP_MODE |
366			LCDC_RASTER_CTRL_TFT_24BPP_UNPACK;
367
368	if (info.raster_order)
369		reg |= LCDC_RASTER_CTRL_DATA_ORDER;
370
371	writel(reg, &regs->raster_ctrl);
372
373	uc_priv->xsize = timing.hactive.typ;
374	uc_priv->ysize = timing.vactive.typ;
375	uc_priv->bpix = log_2_n_round_up(info.bpp);
376
377	err = panel_enable_backlight(panel);
378	if (err) {
379		dev_err(dev, "failed to enable panel backlight\n");
380		return err;
381	}
382
383	return 0;
384}
385
386static int tilcdc_of_to_plat(struct udevice *dev)
387{
388	struct tilcdc_priv *priv = dev_get_priv(dev);
389
390	priv->regs = dev_read_addr_ptr(dev);
391	if (!priv->regs) {
392		dev_err(dev, "failed to get base address\n");
393		return -EINVAL;
394	}
395
396	dev_dbg(dev, "LCD: base address=0x%x\n", (unsigned int)priv->regs);
397	return 0;
398}
399
400static int tilcdc_bind(struct udevice *dev)
401{
402	struct video_uc_plat *uc_plat = dev_get_uclass_plat(dev);
403
404	uc_plat->size = ((LCDC_MAX_WIDTH * LCDC_MAX_HEIGHT *
405			  (1 << LCDC_MAX_LOG2_BPP)) >> 3) + 0x20;
406
407	dev_dbg(dev, "frame buffer size 0x%x\n", uc_plat->size);
408	return 0;
409}
410
411static const struct udevice_id tilcdc_ids[] = {
412	{.compatible = "ti,am33xx-tilcdc"},
413	{}
414};
415
416U_BOOT_DRIVER(tilcdc) = {
417	.name = "tilcdc",
418	.id = UCLASS_VIDEO,
419	.of_match = tilcdc_ids,
420	.bind = tilcdc_bind,
421	.of_to_plat = tilcdc_of_to_plat,
422	.probe = tilcdc_probe,
423	.remove = tilcdc_remove,
424	.priv_auto = sizeof(struct tilcdc_priv)
425};
426