1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2013-2018 Hannes Schmelzer <oe5hpm@oevsv.at>
4  * B&R Industrial Automation GmbH - http://www.br-automation.com
5  * Copyright (C) 2020 Dario Binacchi <dariobin@libero.it>
6  *
7  * minimal framebuffer driver for TI's AM335x SoC to be compatible with
8  * Wolfgang Denk's LCD-Framework (CONFIG_LCD, common/lcd.c)
9  *
10  * - supporting 16/24/32bit RGB/TFT raster Mode (not using palette)
11  * - sets up LCD controller as in 'am335x_lcdpanel' struct given
12  * - starts output DMA from gd->fb_base buffer
13  */
14 #include <common.h>
15 #include <lcd.h>
16 #include <log.h>
17 #include <asm/arch/clock.h>
18 #include <asm/arch/hardware.h>
19 #include <asm/arch/omap.h>
20 #include <asm/arch/sys_proto.h>
21 #include <asm/global_data.h>
22 #include <asm/io.h>
23 #include <linux/delay.h>
24 #include <linux/err.h>
25 #include "am335x-fb.h"
26 
27 #define LCDC_FMAX				200000000
28 
29 /* LCD Control Register */
30 #define LCDC_CTRL_CLK_DIVISOR_MASK		GENMASK(15, 8)
31 #define LCDC_CTRL_RASTER_MODE			BIT(0)
32 #define LCDC_CTRL_CLK_DIVISOR(x)		(((x) & GENMASK(7, 0)) << 8)
33 /* LCD Clock Enable Register */
34 #define LCDC_CLKC_ENABLE_CORECLKEN		BIT(0)
35 #define LCDC_CLKC_ENABLE_LIDDCLKEN		BIT(1)
36 #define LCDC_CLKC_ENABLE_DMACLKEN		BIT(2)
37 /* LCD DMA Control Register */
38 #define LCDC_DMA_CTRL_BURST_SIZE(x)		(((x) & GENMASK(2, 0)) << 4)
39 #define LCDC_DMA_CTRL_BURST_1			0x0
40 #define LCDC_DMA_CTRL_BURST_2			0x1
41 #define LCDC_DMA_CTRL_BURST_4			0x2
42 #define LCDC_DMA_CTRL_BURST_8			0x3
43 #define LCDC_DMA_CTRL_BURST_16			0x4
44 #define LCDC_DMA_CTRL_FIFO_TH(x)		(((x) & GENMASK(2, 0)) << 8)
45 /* LCD Timing_0 Register */
46 #define LCDC_RASTER_TIMING_0_HORMSB(x)	((((x) - 1) & BIT(10)) >> 7)
47 #define LCDC_RASTER_TIMING_0_HORLSB(x) (((((x) >> 4) - 1) & GENMASK(5, 0)) << 4)
48 #define LCDC_RASTER_TIMING_0_HSWLSB(x)	((((x) - 1) & GENMASK(5, 0)) << 10)
49 #define LCDC_RASTER_TIMING_0_HFPLSB(x)	((((x) - 1) & GENMASK(7, 0)) << 16)
50 #define LCDC_RASTER_TIMING_0_HBPLSB(x)	((((x) - 1) & GENMASK(7, 0)) << 24)
51 /* LCD Timing_1 Register */
52 #define LCDC_RASTER_TIMING_1_VERLSB(x)		(((x) - 1) & GENMASK(9, 0))
53 #define LCDC_RASTER_TIMING_1_VSW(x)	((((x) - 1) & GENMASK(5, 0)) << 10)
54 #define LCDC_RASTER_TIMING_1_VFP(x)		(((x) & GENMASK(7, 0)) << 16)
55 #define LCDC_RASTER_TIMING_1_VBP(x)		(((x) & GENMASK(7, 0)) << 24)
56 /* LCD Timing_2 Register */
57 #define LCDC_RASTER_TIMING_2_HFPMSB(x)	((((x) - 1) & GENMASK(9, 8)) >> 8)
58 #define LCDC_RASTER_TIMING_2_HBPMSB(x)	((((x) - 1) & GENMASK(9, 8)) >> 4)
59 #define LCDC_RASTER_TIMING_2_ACB(x)		(((x) & GENMASK(7, 0)) << 8)
60 #define LCDC_RASTER_TIMING_2_ACBI(x)		(((x) & GENMASK(3, 0)) << 16)
61 #define LCDC_RASTER_TIMING_2_VSYNC_INVERT	BIT(20)
62 #define LCDC_RASTER_TIMING_2_HSYNC_INVERT	BIT(21)
63 #define LCDC_RASTER_TIMING_2_PXCLK_INVERT	BIT(22)
64 #define LCDC_RASTER_TIMING_2_DE_INVERT		BIT(23)
65 #define LCDC_RASTER_TIMING_2_HSVS_RISEFALL	BIT(24)
66 #define LCDC_RASTER_TIMING_2_HSVS_CONTROL	BIT(25)
67 #define LCDC_RASTER_TIMING_2_VERMSB(x)		((((x) - 1) & BIT(10)) << 16)
68 #define LCDC_RASTER_TIMING_2_HSWMSB(x)	((((x) - 1) & GENMASK(9, 6)) << 21)
69 /* LCD Raster Ctrl Register */
70 #define LCDC_RASTER_CTRL_ENABLE			BIT(0)
71 #define LCDC_RASTER_CTRL_TFT_MODE		BIT(7)
72 #define LCDC_RASTER_CTRL_DATA_ORDER		BIT(8)
73 #define LCDC_RASTER_CTRL_REQDLY(x)		(((x) & GENMASK(7, 0)) << 12)
74 #define LCDC_RASTER_CTRL_PALMODE_RAWDATA	(0x02 << 20)
75 #define LCDC_RASTER_CTRL_TFT_ALT_ENABLE		BIT(23)
76 #define LCDC_RASTER_CTRL_TFT_24BPP_MODE		BIT(25)
77 #define LCDC_RASTER_CTRL_TFT_24BPP_UNPACK	BIT(26)
78 
79 struct am335x_lcdhw {
80 	unsigned int		pid;			/* 0x00 */
81 	unsigned int		ctrl;			/* 0x04 */
82 	unsigned int		gap0;			/* 0x08 */
83 	unsigned int		lidd_ctrl;		/* 0x0C */
84 	unsigned int		lidd_cs0_conf;		/* 0x10 */
85 	unsigned int		lidd_cs0_addr;		/* 0x14 */
86 	unsigned int		lidd_cs0_data;		/* 0x18 */
87 	unsigned int		lidd_cs1_conf;		/* 0x1C */
88 	unsigned int		lidd_cs1_addr;		/* 0x20 */
89 	unsigned int		lidd_cs1_data;		/* 0x24 */
90 	unsigned int		raster_ctrl;		/* 0x28 */
91 	unsigned int		raster_timing0;		/* 0x2C */
92 	unsigned int		raster_timing1;		/* 0x30 */
93 	unsigned int		raster_timing2;		/* 0x34 */
94 	unsigned int		raster_subpanel;	/* 0x38 */
95 	unsigned int		raster_subpanel2;	/* 0x3C */
96 	unsigned int		lcddma_ctrl;		/* 0x40 */
97 	unsigned int		lcddma_fb0_base;	/* 0x44 */
98 	unsigned int		lcddma_fb0_ceiling;	/* 0x48 */
99 	unsigned int		lcddma_fb1_base;	/* 0x4C */
100 	unsigned int		lcddma_fb1_ceiling;	/* 0x50 */
101 	unsigned int		sysconfig;		/* 0x54 */
102 	unsigned int		irqstatus_raw;		/* 0x58 */
103 	unsigned int		irqstatus;		/* 0x5C */
104 	unsigned int		irqenable_set;		/* 0x60 */
105 	unsigned int		irqenable_clear;	/* 0x64 */
106 	unsigned int		gap1;			/* 0x68 */
107 	unsigned int		clkc_enable;		/* 0x6C */
108 	unsigned int		clkc_reset;		/* 0x70 */
109 };
110 
111 DECLARE_GLOBAL_DATA_PTR;
112 
113 #if !defined(LCD_CNTL_BASE)
114 #error "hw-base address of LCD-Controller (LCD_CNTL_BASE) not defined!"
115 #endif
116 
117 /* Macro definitions */
118 #define FBSIZE(x)	(((x)->hactive * (x)->vactive * (x)->bpp) >> 3)
119 
120 #define LCDC_RASTER_TIMING_2_INVMASK(x)		((x) & GENMASK(25, 20))
121 
122 static struct am335x_lcdhw *lcdhw = (void *)LCD_CNTL_BASE;
123 
lcd_get_size(int * line_length)124 int lcd_get_size(int *line_length)
125 {
126 	*line_length = (panel_info.vl_col * NBITS(panel_info.vl_bpix)) / 8;
127 	return *line_length * panel_info.vl_row + 0x20;
128 }
129 
130 struct dpll_data {
131 	unsigned long rounded_rate;
132 	u16 rounded_m;
133 	u8 rounded_n;
134 	u8 rounded_div;
135 };
136 
137 /**
138  * am335x_dpll_round_rate() - Round a target rate for an OMAP DPLL
139  *
140  * @dpll_data: struct dpll_data pointer for the DPLL
141  * @rate:      New DPLL clock rate
142  * @return rounded rate and the computed m, n and div values in the dpll_data
143  *         structure, or -ve error code.
144  */
am335x_dpll_round_rate(struct dpll_data * dd,ulong rate)145 static ulong am335x_dpll_round_rate(struct dpll_data *dd, ulong rate)
146 {
147 	unsigned int m, n, d;
148 	unsigned long rounded_rate;
149 	int err, err_r;
150 
151 	dd->rounded_rate = -EFAULT;
152 	err = rate;
153 	err_r = err;
154 
155 	for (d = 2; err && d < 255; d++) {
156 		for (m = 2; m < 2047; m++) {
157 			if ((V_OSCK * m) < (rate * d))
158 				continue;
159 
160 			n = (V_OSCK * m) / (rate * d);
161 			if (n > 127)
162 				break;
163 
164 			if (((V_OSCK * m) / n) > LCDC_FMAX)
165 				break;
166 
167 			rounded_rate = (V_OSCK * m) / n / d;
168 			err = abs(rounded_rate - rate);
169 			if (err < err_r) {
170 				err_r = err;
171 				dd->rounded_rate = rounded_rate;
172 				dd->rounded_m = m;
173 				dd->rounded_n = n;
174 				dd->rounded_div = d;
175 				if (err == 0)
176 					break;
177 			}
178 		}
179 	}
180 
181 	debug("DPLL display: best error %d Hz (M %d, N %d, DIV %d)\n",
182 	      err_r, dd->rounded_m, dd->rounded_n, dd->rounded_div);
183 
184 	return dd->rounded_rate;
185 }
186 
187 /**
188  * am335x_fb_set_pixel_clk_rate() - Set pixel clock rate.
189  *
190  * @am335x_lcdhw: Base address of the LCD controller registers.
191  * @rate:         New clock rate in Hz.
192  * @return new rate, or -ve error code.
193  */
am335x_fb_set_pixel_clk_rate(struct am335x_lcdhw * regs,ulong rate)194 static ulong am335x_fb_set_pixel_clk_rate(struct am335x_lcdhw *regs, ulong rate)
195 {
196 	struct dpll_params dpll_disp = { 1, 0, 1, -1, -1, -1, -1 };
197 	struct dpll_data dd;
198 	ulong round_rate;
199 	u32 reg;
200 
201 	round_rate = am335x_dpll_round_rate(&dd, rate);
202 	if (IS_ERR_VALUE(round_rate))
203 		return round_rate;
204 
205 	dpll_disp.m = dd.rounded_m;
206 	dpll_disp.n = dd.rounded_n;
207 	do_setup_dpll(&dpll_disp_regs, &dpll_disp);
208 
209 	reg = readl(&regs->ctrl) & ~LCDC_CTRL_CLK_DIVISOR_MASK;
210 	reg |= LCDC_CTRL_CLK_DIVISOR(dd.rounded_div);
211 	writel(reg, &regs->ctrl);
212 	return round_rate;
213 }
214 
am335xfb_init(struct am335x_lcdpanel * panel)215 int am335xfb_init(struct am335x_lcdpanel *panel)
216 {
217 	u32 raster_ctrl = 0;
218 	struct cm_dpll *const cmdpll = (struct cm_dpll *)CM_DPLL;
219 	ulong rate;
220 	u32 reg;
221 
222 	if (gd->fb_base == 0) {
223 		printf("ERROR: no valid fb_base stored in GLOBAL_DATA_PTR!\n");
224 		return -1;
225 	}
226 	if (panel == NULL) {
227 		printf("ERROR: missing ptr to am335x_lcdpanel!\n");
228 		return -1;
229 	}
230 
231 	/* We can already set the bits for the raster_ctrl in this check */
232 	switch (panel->bpp) {
233 	case 16:
234 		break;
235 	case 32:
236 		raster_ctrl |= LCDC_RASTER_CTRL_TFT_24BPP_UNPACK;
237 		/* fallthrough */
238 	case 24:
239 		raster_ctrl |= LCDC_RASTER_CTRL_TFT_24BPP_MODE;
240 		break;
241 	default:
242 		pr_err("am335x-fb: invalid bpp value: %d\n", panel->bpp);
243 		return -1;
244 	}
245 
246 	/* check given clock-frequency */
247 	if (panel->pxl_clk > (LCDC_FMAX / 2)) {
248 		pr_err("am335x-fb: requested pxl-clk: %d not supported!\n",
249 		       panel->pxl_clk);
250 		return -1;
251 	}
252 
253 	debug("setting up LCD-Controller for %dx%dx%d (hfp=%d,hbp=%d,hsw=%d / ",
254 	      panel->hactive, panel->vactive, panel->bpp,
255 	      panel->hfp, panel->hbp, panel->hsw);
256 	debug("vfp=%d,vbp=%d,vsw=%d / clk=%d)\n",
257 	      panel->vfp, panel->vfp, panel->vsw, panel->pxl_clk);
258 	debug("using frambuffer at 0x%08x with size %d.\n",
259 	      (unsigned int)gd->fb_base, FBSIZE(panel));
260 
261 	rate = am335x_fb_set_pixel_clk_rate(lcdhw, panel->pxl_clk);
262 	if (IS_ERR_VALUE(rate))
263 		return rate;
264 
265 	/* clock source for LCDC from dispPLL M2 */
266 	writel(0x0, &cmdpll->clklcdcpixelclk);
267 
268 	/* palette default entry */
269 	memset((void *)gd->fb_base, 0, 0x20);
270 	*(unsigned int *)gd->fb_base = 0x4000;
271 	/* point fb behind palette */
272 	gd->fb_base += 0x20;
273 
274 	/* turn ON display through powercontrol function if accessible */
275 	if (panel->panel_power_ctrl != NULL)
276 		panel->panel_power_ctrl(1);
277 
278 	debug("am335x-fb: wait for stable power ...\n");
279 	mdelay(panel->pup_delay);
280 	lcdhw->clkc_enable = LCDC_CLKC_ENABLE_CORECLKEN |
281 		LCDC_CLKC_ENABLE_LIDDCLKEN | LCDC_CLKC_ENABLE_DMACLKEN;
282 	lcdhw->raster_ctrl = 0;
283 
284 	reg = lcdhw->ctrl & LCDC_CTRL_CLK_DIVISOR_MASK;
285 	reg |= LCDC_CTRL_RASTER_MODE;
286 	lcdhw->ctrl = reg;
287 
288 	lcdhw->lcddma_fb0_base = gd->fb_base;
289 	lcdhw->lcddma_fb0_ceiling = gd->fb_base + FBSIZE(panel);
290 	lcdhw->lcddma_fb1_base = gd->fb_base;
291 	lcdhw->lcddma_fb1_ceiling = gd->fb_base + FBSIZE(panel);
292 	lcdhw->lcddma_ctrl = LCDC_DMA_CTRL_BURST_SIZE(LCDC_DMA_CTRL_BURST_16);
293 
294 	lcdhw->raster_timing0 = LCDC_RASTER_TIMING_0_HORLSB(panel->hactive) |
295 				LCDC_RASTER_TIMING_0_HORMSB(panel->hactive) |
296 				LCDC_RASTER_TIMING_0_HFPLSB(panel->hfp) |
297 				LCDC_RASTER_TIMING_0_HBPLSB(panel->hbp) |
298 				LCDC_RASTER_TIMING_0_HSWLSB(panel->hsw);
299 	lcdhw->raster_timing1 = LCDC_RASTER_TIMING_1_VBP(panel->vbp) |
300 				LCDC_RASTER_TIMING_1_VFP(panel->vfp) |
301 				LCDC_RASTER_TIMING_1_VSW(panel->vsw) |
302 				LCDC_RASTER_TIMING_1_VERLSB(panel->vactive);
303 	lcdhw->raster_timing2 = LCDC_RASTER_TIMING_2_HSWMSB(panel->hsw) |
304 				LCDC_RASTER_TIMING_2_VERMSB(panel->vactive) |
305 				LCDC_RASTER_TIMING_2_INVMASK(panel->pol) |
306 				LCDC_RASTER_TIMING_2_HBPMSB(panel->hbp) |
307 				LCDC_RASTER_TIMING_2_HFPMSB(panel->hfp) |
308 				0x0000FF00;	/* clk cycles for ac-bias */
309 	lcdhw->raster_ctrl =	raster_ctrl |
310 				LCDC_RASTER_CTRL_PALMODE_RAWDATA |
311 				LCDC_RASTER_CTRL_TFT_MODE |
312 				LCDC_RASTER_CTRL_ENABLE;
313 
314 	debug("am335x-fb: waiting picture to be stable.\n.");
315 	mdelay(panel->pon_delay);
316 
317 	return 0;
318 }
319