1
2
3
4
5
6
7
8
9
10
11
12
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
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
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
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
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
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
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
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
79struct am335x_lcdhw {
80 unsigned int pid;
81 unsigned int ctrl;
82 unsigned int gap0;
83 unsigned int lidd_ctrl;
84 unsigned int lidd_cs0_conf;
85 unsigned int lidd_cs0_addr;
86 unsigned int lidd_cs0_data;
87 unsigned int lidd_cs1_conf;
88 unsigned int lidd_cs1_addr;
89 unsigned int lidd_cs1_data;
90 unsigned int raster_ctrl;
91 unsigned int raster_timing0;
92 unsigned int raster_timing1;
93 unsigned int raster_timing2;
94 unsigned int raster_subpanel;
95 unsigned int raster_subpanel2;
96 unsigned int lcddma_ctrl;
97 unsigned int lcddma_fb0_base;
98 unsigned int lcddma_fb0_ceiling;
99 unsigned int lcddma_fb1_base;
100 unsigned int lcddma_fb1_ceiling;
101 unsigned int sysconfig;
102 unsigned int irqstatus_raw;
103 unsigned int irqstatus;
104 unsigned int irqenable_set;
105 unsigned int irqenable_clear;
106 unsigned int gap1;
107 unsigned int clkc_enable;
108 unsigned int clkc_reset;
109};
110
111DECLARE_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
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
122static struct am335x_lcdhw *lcdhw = (void *)LCD_CNTL_BASE;
123
124int 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
130struct dpll_data {
131 unsigned long rounded_rate;
132 u16 rounded_m;
133 u8 rounded_n;
134 u8 rounded_div;
135};
136
137
138
139
140
141
142
143
144
145static 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
189
190
191
192
193
194static 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(®s->ctrl) & ~LCDC_CTRL_CLK_DIVISOR_MASK;
210 reg |= LCDC_CTRL_CLK_DIVISOR(dd.rounded_div);
211 writel(reg, ®s->ctrl);
212 return round_rate;
213}
214
215int 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
232 switch (panel->bpp) {
233 case 16:
234 break;
235 case 32:
236 raster_ctrl |= LCDC_RASTER_CTRL_TFT_24BPP_UNPACK;
237
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
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
266 writel(0x0, &cmdpll->clklcdcpixelclk);
267
268
269 memset((void *)gd->fb_base, 0, 0x20);
270 *(unsigned int *)gd->fb_base = 0x4000;
271
272 gd->fb_base += 0x20;
273
274
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;
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