]>
Commit | Line | Data |
---|---|---|
c0dcece7 HS |
1 | /* |
2 | * Board functions for TI AM335X based pxm2 board | |
3 | * (C) Copyright 2013 Siemens Schweiz AG | |
4 | * (C) Heiko Schocher, DENX Software Engineering, hs@denx.de. | |
5 | * | |
6 | * Based on: | |
7 | * u-boot:/board/ti/am335x/board.c | |
8 | * | |
9 | * Board functions for TI AM335X based boards | |
10 | * | |
11 | * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/ | |
12 | * | |
13 | * SPDX-License-Identifier: GPL-2.0+ | |
14 | */ | |
15 | ||
16 | #include <common.h> | |
17 | #include <errno.h> | |
18 | #include <spl.h> | |
19 | #include <asm/arch/cpu.h> | |
20 | #include <asm/arch/hardware.h> | |
21 | #include <asm/arch/omap.h> | |
22 | #include <asm/arch/ddr_defs.h> | |
23 | #include <asm/arch/clock.h> | |
24 | #include <asm/arch/gpio.h> | |
25 | #include <asm/arch/mmc_host_def.h> | |
26 | #include <asm/arch/sys_proto.h> | |
27 | #include "../../../drivers/video/da8xx-fb.h" | |
28 | #include <asm/io.h> | |
29 | #include <asm/emif.h> | |
30 | #include <asm/gpio.h> | |
31 | #include <i2c.h> | |
32 | #include <miiphy.h> | |
33 | #include <cpsw.h> | |
34 | #include <watchdog.h> | |
35 | #include "board.h" | |
36 | #include "../common/factoryset.h" | |
37 | #include "pmic.h" | |
38 | #include <nand.h> | |
39 | #include <bmp_layout.h> | |
40 | ||
41 | DECLARE_GLOBAL_DATA_PTR; | |
42 | ||
43 | #ifdef CONFIG_SPL_BUILD | |
44 | static void board_init_ddr(void) | |
45 | { | |
46 | struct emif_regs pxm2_ddr3_emif_reg_data = { | |
47 | .sdram_config = 0x41805332, | |
48 | .sdram_tim1 = 0x666b3c9, | |
49 | .sdram_tim2 = 0x243631ca, | |
50 | .sdram_tim3 = 0x33f, | |
51 | .emif_ddr_phy_ctlr_1 = 0x100005, | |
52 | .zq_config = 0, | |
53 | .ref_ctrl = 0x81a, | |
54 | }; | |
55 | ||
56 | struct ddr_data pxm2_ddr3_data = { | |
57 | .datardsratio0 = 0x81204812, | |
58 | .datawdsratio0 = 0, | |
59 | .datafwsratio0 = 0x8020080, | |
60 | .datawrsratio0 = 0x4010040, | |
c0dcece7 HS |
61 | }; |
62 | ||
63 | struct cmd_control pxm2_ddr3_cmd_ctrl_data = { | |
64 | .cmd0csratio = 0x80, | |
c0dcece7 HS |
65 | .cmd0iclkout = 0, |
66 | .cmd1csratio = 0x80, | |
c0dcece7 HS |
67 | .cmd1iclkout = 0, |
68 | .cmd2csratio = 0x80, | |
c0dcece7 HS |
69 | .cmd2iclkout = 0, |
70 | }; | |
71 | ||
965de8b9 | 72 | const struct ctrl_ioregs ioregs = { |
9fc2ed40 ES |
73 | .cm0ioctl = DDR_IOCTRL_VAL, |
74 | .cm1ioctl = DDR_IOCTRL_VAL, | |
75 | .cm2ioctl = DDR_IOCTRL_VAL, | |
76 | .dt0ioctl = DDR_IOCTRL_VAL, | |
77 | .dt1ioctl = DDR_IOCTRL_VAL, | |
965de8b9 LV |
78 | }; |
79 | ||
80 | config_ddr(DDR_PLL_FREQ, &ioregs, &pxm2_ddr3_data, | |
c0dcece7 HS |
81 | &pxm2_ddr3_cmd_ctrl_data, &pxm2_ddr3_emif_reg_data, 0); |
82 | } | |
83 | ||
84 | /* | |
85 | * voltage switching for MPU frequency switching. | |
86 | * @module = mpu - 0, core - 1 | |
87 | * @vddx_op_vol_sel = vdd voltage to set | |
88 | */ | |
89 | ||
90 | #define MPU 0 | |
91 | #define CORE 1 | |
92 | ||
93 | int voltage_update(unsigned int module, unsigned char vddx_op_vol_sel) | |
94 | { | |
95 | uchar buf[4]; | |
96 | unsigned int reg_offset; | |
97 | ||
98 | if (module == MPU) | |
99 | reg_offset = PMIC_VDD1_OP_REG; | |
100 | else | |
101 | reg_offset = PMIC_VDD2_OP_REG; | |
102 | ||
103 | /* Select VDDx OP */ | |
104 | if (i2c_read(PMIC_CTRL_I2C_ADDR, reg_offset, 1, buf, 1)) | |
105 | return 1; | |
106 | ||
107 | buf[0] &= ~PMIC_OP_REG_CMD_MASK; | |
108 | ||
109 | if (i2c_write(PMIC_CTRL_I2C_ADDR, reg_offset, 1, buf, 1)) | |
110 | return 1; | |
111 | ||
112 | /* Configure VDDx OP Voltage */ | |
113 | if (i2c_read(PMIC_CTRL_I2C_ADDR, reg_offset, 1, buf, 1)) | |
114 | return 1; | |
115 | ||
116 | buf[0] &= ~PMIC_OP_REG_SEL_MASK; | |
117 | buf[0] |= vddx_op_vol_sel; | |
118 | ||
119 | if (i2c_write(PMIC_CTRL_I2C_ADDR, reg_offset, 1, buf, 1)) | |
120 | return 1; | |
121 | ||
122 | if (i2c_read(PMIC_CTRL_I2C_ADDR, reg_offset, 1, buf, 1)) | |
123 | return 1; | |
124 | ||
125 | if ((buf[0] & PMIC_OP_REG_SEL_MASK) != vddx_op_vol_sel) | |
126 | return 1; | |
127 | ||
128 | return 0; | |
129 | } | |
130 | ||
131 | #define OSC (V_OSCK/1000000) | |
132 | ||
133 | const struct dpll_params dpll_mpu_pxm2 = { | |
134 | 720, OSC-1, 1, -1, -1, -1, -1}; | |
135 | ||
136 | void spl_siemens_board_init(void) | |
137 | { | |
138 | uchar buf[4]; | |
139 | /* | |
140 | * pxm2 PMIC code. All boards currently want an MPU voltage | |
141 | * of 1.2625V and CORE voltage of 1.1375V to operate at | |
142 | * 720MHz. | |
143 | */ | |
144 | if (i2c_probe(PMIC_CTRL_I2C_ADDR)) | |
145 | return; | |
146 | ||
147 | /* VDD1/2 voltage selection register access by control i/f */ | |
148 | if (i2c_read(PMIC_CTRL_I2C_ADDR, PMIC_DEVCTRL_REG, 1, buf, 1)) | |
149 | return; | |
150 | ||
151 | buf[0] |= PMIC_DEVCTRL_REG_SR_CTL_I2C_SEL_CTL_I2C; | |
152 | ||
153 | if (i2c_write(PMIC_CTRL_I2C_ADDR, PMIC_DEVCTRL_REG, 1, buf, 1)) | |
154 | return; | |
155 | ||
156 | /* Frequency switching for OPP 120 */ | |
157 | if (voltage_update(MPU, PMIC_OP_REG_SEL_1_2_6) || | |
158 | voltage_update(CORE, PMIC_OP_REG_SEL_1_1_3)) { | |
159 | printf("voltage update failed\n"); | |
160 | } | |
161 | } | |
162 | #endif /* if def CONFIG_SPL_BUILD */ | |
163 | ||
164 | int read_eeprom(void) | |
165 | { | |
166 | /* nothing ToDo here for this board */ | |
167 | ||
168 | return 0; | |
169 | } | |
170 | ||
171 | #if (defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_SPL_BUILD)) || \ | |
172 | (defined(CONFIG_SPL_ETH_SUPPORT) && defined(CONFIG_SPL_BUILD)) | |
173 | static void cpsw_control(int enabled) | |
174 | { | |
175 | /* VTP can be added here */ | |
176 | ||
177 | return; | |
178 | } | |
179 | ||
180 | static struct cpsw_slave_data cpsw_slaves[] = { | |
181 | { | |
182 | .slave_reg_ofs = 0x208, | |
183 | .sliver_reg_ofs = 0xd80, | |
9c653aad | 184 | .phy_addr = 0, |
c0dcece7 HS |
185 | .phy_if = PHY_INTERFACE_MODE_RMII, |
186 | }, | |
187 | { | |
188 | .slave_reg_ofs = 0x308, | |
189 | .sliver_reg_ofs = 0xdc0, | |
9c653aad | 190 | .phy_addr = 1, |
c0dcece7 HS |
191 | .phy_if = PHY_INTERFACE_MODE_RMII, |
192 | }, | |
193 | }; | |
194 | ||
195 | static struct cpsw_platform_data cpsw_data = { | |
196 | .mdio_base = CPSW_MDIO_BASE, | |
197 | .cpsw_base = CPSW_BASE, | |
198 | .mdio_div = 0xff, | |
199 | .channels = 4, | |
200 | .cpdma_reg_ofs = 0x800, | |
201 | .slaves = 1, | |
202 | .slave_data = cpsw_slaves, | |
203 | .ale_reg_ofs = 0xd00, | |
204 | .ale_entries = 1024, | |
205 | .host_port_reg_ofs = 0x108, | |
206 | .hw_stats_reg_ofs = 0x900, | |
207 | .bd_ram_ofs = 0x2000, | |
208 | .mac_control = (1 << 5), | |
209 | .control = cpsw_control, | |
210 | .host_port_num = 0, | |
211 | .version = CPSW_CTRL_VERSION_2, | |
212 | }; | |
213 | #endif /* #if (defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_SPL_BUILD)) */ | |
214 | ||
215 | #if defined(CONFIG_DRIVER_TI_CPSW) || \ | |
216 | (defined(CONFIG_USB_ETHER) && defined(CONFIG_MUSB_GADGET)) | |
217 | int board_eth_init(bd_t *bis) | |
218 | { | |
219 | int n = 0; | |
220 | #if (defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_SPL_BUILD)) || \ | |
221 | (defined(CONFIG_SPL_ETH_SUPPORT) && defined(CONFIG_SPL_BUILD)) | |
222 | struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE; | |
223 | #ifdef CONFIG_FACTORYSET | |
224 | int rv; | |
225 | if (!is_valid_ether_addr(factory_dat.mac)) | |
226 | printf("Error: no valid mac address\n"); | |
227 | else | |
228 | eth_setenv_enetaddr("ethaddr", factory_dat.mac); | |
229 | #endif /* #ifdef CONFIG_FACTORYSET */ | |
230 | ||
231 | /* Set rgmii mode and enable rmii clock to be sourced from chip */ | |
232 | writel(RGMII_MODE_ENABLE , &cdev->miisel); | |
233 | ||
234 | rv = cpsw_register(&cpsw_data); | |
235 | if (rv < 0) | |
236 | printf("Error %d registering CPSW switch\n", rv); | |
237 | else | |
238 | n += rv; | |
239 | #endif | |
240 | return n; | |
241 | } | |
242 | #endif /* #if defined(CONFIG_DRIVER_TI_CPSW) */ | |
243 | ||
244 | #if defined(CONFIG_VIDEO) && !defined(CONFIG_SPL_BUILD) | |
245 | static struct da8xx_panel lcd_panels[] = { | |
246 | /* AUO G156XW01 V1 */ | |
247 | [0] = { | |
248 | .name = "AUO_G156XW01_V1", | |
249 | .width = 1376, | |
250 | .height = 768, | |
251 | .hfp = 14, | |
252 | .hbp = 64, | |
253 | .hsw = 56, | |
254 | .vfp = 1, | |
255 | .vbp = 28, | |
256 | .vsw = 3, | |
257 | .pxl_clk = 60000000, | |
258 | .invert_pxl_clk = 0, | |
259 | }, | |
260 | /* AUO B101EVN06 V0 */ | |
261 | [1] = { | |
262 | .name = "AUO_B101EVN06_V0", | |
263 | .width = 1280, | |
264 | .height = 800, | |
265 | .hfp = 52, | |
266 | .hbp = 84, | |
267 | .hsw = 36, | |
268 | .vfp = 3, | |
269 | .vbp = 14, | |
270 | .vsw = 6, | |
271 | .pxl_clk = 60000000, | |
272 | .invert_pxl_clk = 0, | |
273 | }, | |
274 | /* | |
275 | * Settings from factoryset | |
276 | * stored in EEPROM | |
277 | */ | |
278 | [2] = { | |
279 | .name = "factoryset", | |
280 | .width = 0, | |
281 | .height = 0, | |
282 | .hfp = 0, | |
283 | .hbp = 0, | |
284 | .hsw = 0, | |
285 | .vfp = 0, | |
286 | .vbp = 0, | |
287 | .vsw = 0, | |
288 | .pxl_clk = 60000000, | |
289 | .invert_pxl_clk = 0, | |
290 | }, | |
291 | }; | |
292 | ||
293 | static const struct display_panel disp_panel = { | |
294 | WVGA, | |
295 | 32, | |
296 | 16, | |
297 | COLOR_ACTIVE, | |
298 | }; | |
299 | ||
300 | static const struct lcd_ctrl_config lcd_cfg = { | |
301 | &disp_panel, | |
302 | .ac_bias = 255, | |
303 | .ac_bias_intrpt = 0, | |
304 | .dma_burst_sz = 16, | |
305 | .bpp = 32, | |
306 | .fdd = 0x80, | |
307 | .tft_alt_mode = 0, | |
308 | .stn_565_mode = 0, | |
309 | .mono_8bit_mode = 0, | |
310 | .invert_line_clock = 1, | |
311 | .invert_frm_clock = 1, | |
312 | .sync_edge = 0, | |
313 | .sync_ctrl = 1, | |
314 | .raster_order = 0, | |
315 | }; | |
316 | ||
317 | static int set_gpio(int gpio, int state) | |
318 | { | |
319 | gpio_request(gpio, "temp"); | |
320 | gpio_direction_output(gpio, state); | |
321 | gpio_set_value(gpio, state); | |
322 | gpio_free(gpio); | |
323 | return 0; | |
324 | } | |
325 | ||
326 | static int enable_backlight(void) | |
327 | { | |
328 | set_gpio(BOARD_LCD_POWER, 1); | |
329 | set_gpio(BOARD_BACK_LIGHT, 1); | |
330 | set_gpio(BOARD_TOUCH_POWER, 1); | |
331 | return 0; | |
332 | } | |
333 | ||
334 | static int enable_pwm(void) | |
335 | { | |
336 | struct pwmss_regs *pwmss = (struct pwmss_regs *)PWMSS0_BASE; | |
337 | struct pwmss_ecap_regs *ecap; | |
338 | int ticks = PWM_TICKS; | |
339 | int duty = PWM_DUTY; | |
340 | ||
341 | ecap = (struct pwmss_ecap_regs *)AM33XX_ECAP0_BASE; | |
342 | /* enable clock */ | |
343 | setbits_le32(&pwmss->clkconfig, ECAP_CLK_EN); | |
344 | /* TimeStam Counter register */ | |
345 | writel(0xdb9, &ecap->tsctr); | |
346 | /* config period */ | |
347 | writel(ticks - 1, &ecap->cap3); | |
348 | writel(ticks - 1, &ecap->cap1); | |
349 | setbits_le16(&ecap->ecctl2, | |
350 | (ECTRL2_MDSL_ECAP | ECTRL2_SYNCOSEL_MASK | 0xd0)); | |
351 | /* config duty */ | |
352 | writel(duty, &ecap->cap2); | |
353 | writel(duty, &ecap->cap4); | |
354 | /* start */ | |
355 | setbits_le16(&ecap->ecctl2, ECTRL2_CTRSTP_FREERUN); | |
356 | return 0; | |
357 | } | |
358 | ||
359 | static struct dpll_regs dpll_lcd_regs = { | |
360 | .cm_clkmode_dpll = CM_WKUP + 0x98, | |
361 | .cm_idlest_dpll = CM_WKUP + 0x48, | |
362 | .cm_clksel_dpll = CM_WKUP + 0x54, | |
363 | }; | |
364 | ||
365 | /* no console on this board */ | |
366 | int board_cfb_skip(void) | |
367 | { | |
368 | return 1; | |
369 | } | |
370 | ||
371 | #define PLL_GET_M(v) ((v >> 8) & 0x7ff) | |
372 | #define PLL_GET_N(v) (v & 0x7f) | |
373 | ||
374 | static int get_clk(struct dpll_regs *dpll_regs) | |
375 | { | |
376 | unsigned int val; | |
377 | unsigned int m, n; | |
378 | int f = 0; | |
379 | ||
380 | val = readl(dpll_regs->cm_clksel_dpll); | |
381 | m = PLL_GET_M(val); | |
382 | n = PLL_GET_N(val); | |
383 | f = (m * V_OSCK) / n; | |
384 | ||
385 | return f; | |
386 | }; | |
387 | ||
388 | int clk_get(int clk) | |
389 | { | |
390 | return get_clk(&dpll_lcd_regs); | |
391 | }; | |
392 | ||
393 | static int conf_disp_pll(int m, int n) | |
394 | { | |
395 | struct cm_perpll *cmper = (struct cm_perpll *)CM_PER; | |
396 | struct cm_dpll *cmdpll = (struct cm_dpll *)CM_DPLL; | |
397 | struct dpll_params dpll_lcd = {m, n, -1, -1, -1, -1, -1}; | |
398 | ||
399 | u32 *const clk_domains[] = { | |
400 | &cmper->lcdclkctrl, | |
401 | 0 | |
402 | }; | |
403 | u32 *const clk_modules_explicit_en[] = { | |
404 | &cmper->lcdclkctrl, | |
405 | &cmper->lcdcclkstctrl, | |
406 | &cmper->epwmss0clkctrl, | |
407 | 0 | |
408 | }; | |
409 | do_enable_clocks(clk_domains, clk_modules_explicit_en, 1); | |
410 | writel(0x0, &cmdpll->clklcdcpixelclk); | |
411 | ||
412 | do_setup_dpll(&dpll_lcd_regs, &dpll_lcd); | |
413 | ||
414 | return 0; | |
415 | } | |
416 | ||
417 | static int board_video_init(void) | |
418 | { | |
56eb3da4 | 419 | conf_disp_pll(24, 1); |
c0dcece7 HS |
420 | if (factory_dat.pxm50) |
421 | da8xx_video_init(&lcd_panels[0], &lcd_cfg, lcd_cfg.bpp); | |
422 | else | |
423 | da8xx_video_init(&lcd_panels[1], &lcd_cfg, lcd_cfg.bpp); | |
424 | ||
425 | enable_pwm(); | |
426 | enable_backlight(); | |
427 | ||
428 | return 0; | |
429 | } | |
430 | #endif | |
431 | #include "../common/board.c" |