xref: /openbmc/u-boot/board/siemens/rut/board.c (revision c0dcece7d9925506a950e45028cbd25614aad791)
1*c0dcece7SHeiko Schocher /*
2*c0dcece7SHeiko Schocher  * Board functions for TI AM335X based rut board
3*c0dcece7SHeiko Schocher  * (C) Copyright 2013 Siemens Schweiz AG
4*c0dcece7SHeiko Schocher  * (C) Heiko Schocher, DENX Software Engineering, hs@denx.de.
5*c0dcece7SHeiko Schocher  *
6*c0dcece7SHeiko Schocher  * Based on:
7*c0dcece7SHeiko Schocher  * u-boot:/board/ti/am335x/board.c
8*c0dcece7SHeiko Schocher  *
9*c0dcece7SHeiko Schocher  * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
10*c0dcece7SHeiko Schocher  *
11*c0dcece7SHeiko Schocher  * SPDX-License-Identifier:	GPL-2.0+
12*c0dcece7SHeiko Schocher  */
13*c0dcece7SHeiko Schocher 
14*c0dcece7SHeiko Schocher #include <common.h>
15*c0dcece7SHeiko Schocher #include <errno.h>
16*c0dcece7SHeiko Schocher #include <spi.h>
17*c0dcece7SHeiko Schocher #include <spl.h>
18*c0dcece7SHeiko Schocher #include <asm/arch/cpu.h>
19*c0dcece7SHeiko Schocher #include <asm/arch/hardware.h>
20*c0dcece7SHeiko Schocher #include <asm/arch/omap.h>
21*c0dcece7SHeiko Schocher #include <asm/arch/ddr_defs.h>
22*c0dcece7SHeiko Schocher #include <asm/arch/clock.h>
23*c0dcece7SHeiko Schocher #include <asm/arch/gpio.h>
24*c0dcece7SHeiko Schocher #include <asm/arch/mmc_host_def.h>
25*c0dcece7SHeiko Schocher #include <asm/arch/sys_proto.h>
26*c0dcece7SHeiko Schocher #include <asm/io.h>
27*c0dcece7SHeiko Schocher #include <asm/emif.h>
28*c0dcece7SHeiko Schocher #include <asm/gpio.h>
29*c0dcece7SHeiko Schocher #include <i2c.h>
30*c0dcece7SHeiko Schocher #include <miiphy.h>
31*c0dcece7SHeiko Schocher #include <cpsw.h>
32*c0dcece7SHeiko Schocher #include <video.h>
33*c0dcece7SHeiko Schocher #include <watchdog.h>
34*c0dcece7SHeiko Schocher #include "board.h"
35*c0dcece7SHeiko Schocher #include "../common/factoryset.h"
36*c0dcece7SHeiko Schocher #include "../../../drivers/video/da8xx-fb.h"
37*c0dcece7SHeiko Schocher 
38*c0dcece7SHeiko Schocher DECLARE_GLOBAL_DATA_PTR;
39*c0dcece7SHeiko Schocher 
40*c0dcece7SHeiko Schocher /*
41*c0dcece7SHeiko Schocher  * Read header information from EEPROM into global structure.
42*c0dcece7SHeiko Schocher  */
43*c0dcece7SHeiko Schocher static int read_eeprom(void)
44*c0dcece7SHeiko Schocher {
45*c0dcece7SHeiko Schocher 	return 0;
46*c0dcece7SHeiko Schocher }
47*c0dcece7SHeiko Schocher 
48*c0dcece7SHeiko Schocher #ifdef CONFIG_SPL_BUILD
49*c0dcece7SHeiko Schocher static void board_init_ddr(void)
50*c0dcece7SHeiko Schocher {
51*c0dcece7SHeiko Schocher struct emif_regs rut_ddr3_emif_reg_data = {
52*c0dcece7SHeiko Schocher 	.sdram_config = 0x61C04AB2,
53*c0dcece7SHeiko Schocher 	.sdram_tim1 = 0x0888A39B,
54*c0dcece7SHeiko Schocher 	.sdram_tim2 = 0x26337FDA,
55*c0dcece7SHeiko Schocher 	.sdram_tim3 = 0x501F830F,
56*c0dcece7SHeiko Schocher 	.emif_ddr_phy_ctlr_1 = 0x6,
57*c0dcece7SHeiko Schocher 	.zq_config = 0x50074BE4,
58*c0dcece7SHeiko Schocher 	.ref_ctrl = 0x93B,
59*c0dcece7SHeiko Schocher };
60*c0dcece7SHeiko Schocher 
61*c0dcece7SHeiko Schocher struct ddr_data rut_ddr3_data = {
62*c0dcece7SHeiko Schocher 	.datardsratio0 = 0x3b,
63*c0dcece7SHeiko Schocher 	.datawdsratio0 = 0x85,
64*c0dcece7SHeiko Schocher 	.datafwsratio0 = 0x100,
65*c0dcece7SHeiko Schocher 	.datawrsratio0 = 0xc1,
66*c0dcece7SHeiko Schocher 	.datauserank0delay = 1,
67*c0dcece7SHeiko Schocher 	.datadldiff0 = PHY_DLL_LOCK_DIFF,
68*c0dcece7SHeiko Schocher };
69*c0dcece7SHeiko Schocher 
70*c0dcece7SHeiko Schocher struct cmd_control rut_ddr3_cmd_ctrl_data = {
71*c0dcece7SHeiko Schocher 	.cmd0csratio = 0x40,
72*c0dcece7SHeiko Schocher 	.cmd0dldiff = 0,
73*c0dcece7SHeiko Schocher 	.cmd0iclkout = 1,
74*c0dcece7SHeiko Schocher 	.cmd1csratio = 0x40,
75*c0dcece7SHeiko Schocher 	.cmd1dldiff = 0,
76*c0dcece7SHeiko Schocher 	.cmd1iclkout = 1,
77*c0dcece7SHeiko Schocher 	.cmd2csratio = 0x40,
78*c0dcece7SHeiko Schocher 	.cmd2dldiff = 0,
79*c0dcece7SHeiko Schocher 	.cmd2iclkout = 1,
80*c0dcece7SHeiko Schocher };
81*c0dcece7SHeiko Schocher 
82*c0dcece7SHeiko Schocher 	config_ddr(DDR_PLL_FREQ, RUT_IOCTRL_VAL, &rut_ddr3_data,
83*c0dcece7SHeiko Schocher 		   &rut_ddr3_cmd_ctrl_data, &rut_ddr3_emif_reg_data, 0);
84*c0dcece7SHeiko Schocher }
85*c0dcece7SHeiko Schocher 
86*c0dcece7SHeiko Schocher static void spl_siemens_board_init(void)
87*c0dcece7SHeiko Schocher {
88*c0dcece7SHeiko Schocher 	return;
89*c0dcece7SHeiko Schocher }
90*c0dcece7SHeiko Schocher #endif /* if def CONFIG_SPL_BUILD */
91*c0dcece7SHeiko Schocher 
92*c0dcece7SHeiko Schocher #if defined(CONFIG_DRIVER_TI_CPSW)
93*c0dcece7SHeiko Schocher static void cpsw_control(int enabled)
94*c0dcece7SHeiko Schocher {
95*c0dcece7SHeiko Schocher 	/* VTP can be added here */
96*c0dcece7SHeiko Schocher 
97*c0dcece7SHeiko Schocher 	return;
98*c0dcece7SHeiko Schocher }
99*c0dcece7SHeiko Schocher 
100*c0dcece7SHeiko Schocher static struct cpsw_slave_data cpsw_slaves[] = {
101*c0dcece7SHeiko Schocher 	{
102*c0dcece7SHeiko Schocher 		.slave_reg_ofs	= 0x208,
103*c0dcece7SHeiko Schocher 		.sliver_reg_ofs	= 0xd80,
104*c0dcece7SHeiko Schocher 		.phy_id		= 1,
105*c0dcece7SHeiko Schocher 		.phy_if		= PHY_INTERFACE_MODE_RMII,
106*c0dcece7SHeiko Schocher 	},
107*c0dcece7SHeiko Schocher 	{
108*c0dcece7SHeiko Schocher 		.slave_reg_ofs	= 0x308,
109*c0dcece7SHeiko Schocher 		.sliver_reg_ofs	= 0xdc0,
110*c0dcece7SHeiko Schocher 		.phy_id		= 0,
111*c0dcece7SHeiko Schocher 		.phy_if		= PHY_INTERFACE_MODE_RMII,
112*c0dcece7SHeiko Schocher 	},
113*c0dcece7SHeiko Schocher };
114*c0dcece7SHeiko Schocher 
115*c0dcece7SHeiko Schocher static struct cpsw_platform_data cpsw_data = {
116*c0dcece7SHeiko Schocher 	.mdio_base		= CPSW_MDIO_BASE,
117*c0dcece7SHeiko Schocher 	.cpsw_base		= CPSW_BASE,
118*c0dcece7SHeiko Schocher 	.mdio_div		= 0xff,
119*c0dcece7SHeiko Schocher 	.channels		= 8,
120*c0dcece7SHeiko Schocher 	.cpdma_reg_ofs		= 0x800,
121*c0dcece7SHeiko Schocher 	.slaves			= 1,
122*c0dcece7SHeiko Schocher 	.slave_data		= cpsw_slaves,
123*c0dcece7SHeiko Schocher 	.ale_reg_ofs		= 0xd00,
124*c0dcece7SHeiko Schocher 	.ale_entries		= 1024,
125*c0dcece7SHeiko Schocher 	.host_port_reg_ofs	= 0x108,
126*c0dcece7SHeiko Schocher 	.hw_stats_reg_ofs	= 0x900,
127*c0dcece7SHeiko Schocher 	.bd_ram_ofs		= 0x2000,
128*c0dcece7SHeiko Schocher 	.mac_control		= (1 << 5),
129*c0dcece7SHeiko Schocher 	.control		= cpsw_control,
130*c0dcece7SHeiko Schocher 	.host_port_num		= 0,
131*c0dcece7SHeiko Schocher 	.version		= CPSW_CTRL_VERSION_2,
132*c0dcece7SHeiko Schocher };
133*c0dcece7SHeiko Schocher 
134*c0dcece7SHeiko Schocher #if defined(CONFIG_DRIVER_TI_CPSW) || \
135*c0dcece7SHeiko Schocher 	(defined(CONFIG_USB_ETHER) && defined(CONFIG_MUSB_GADGET))
136*c0dcece7SHeiko Schocher int board_eth_init(bd_t *bis)
137*c0dcece7SHeiko Schocher {
138*c0dcece7SHeiko Schocher 	struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
139*c0dcece7SHeiko Schocher 	int n = 0;
140*c0dcece7SHeiko Schocher 	int rv;
141*c0dcece7SHeiko Schocher 
142*c0dcece7SHeiko Schocher #ifndef CONFIG_SPL_BUILD
143*c0dcece7SHeiko Schocher 	factoryset_setenv();
144*c0dcece7SHeiko Schocher #endif
145*c0dcece7SHeiko Schocher 
146*c0dcece7SHeiko Schocher 	/* Set rgmii mode and enable rmii clock to be sourced from chip */
147*c0dcece7SHeiko Schocher 	writel((RMII_MODE_ENABLE | RMII_CHIPCKL_ENABLE), &cdev->miisel);
148*c0dcece7SHeiko Schocher 
149*c0dcece7SHeiko Schocher 	rv = cpsw_register(&cpsw_data);
150*c0dcece7SHeiko Schocher 	if (rv < 0)
151*c0dcece7SHeiko Schocher 		printf("Error %d registering CPSW switch\n", rv);
152*c0dcece7SHeiko Schocher 	else
153*c0dcece7SHeiko Schocher 		n += rv;
154*c0dcece7SHeiko Schocher 	return n;
155*c0dcece7SHeiko Schocher }
156*c0dcece7SHeiko Schocher #endif /* #if defined(CONFIG_DRIVER_TI_CPSW) */
157*c0dcece7SHeiko Schocher #endif /* #if (defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_SPL_BUILD)) */
158*c0dcece7SHeiko Schocher 
159*c0dcece7SHeiko Schocher #if defined(CONFIG_HW_WATCHDOG)
160*c0dcece7SHeiko Schocher static bool hw_watchdog_init_done;
161*c0dcece7SHeiko Schocher static int  hw_watchdog_trigger_level;
162*c0dcece7SHeiko Schocher 
163*c0dcece7SHeiko Schocher void hw_watchdog_reset(void)
164*c0dcece7SHeiko Schocher {
165*c0dcece7SHeiko Schocher 	if (!hw_watchdog_init_done)
166*c0dcece7SHeiko Schocher 		return;
167*c0dcece7SHeiko Schocher 
168*c0dcece7SHeiko Schocher 	hw_watchdog_trigger_level = hw_watchdog_trigger_level ? 0 : 1;
169*c0dcece7SHeiko Schocher 	gpio_set_value(WATCHDOG_TRIGGER_GPIO, hw_watchdog_trigger_level);
170*c0dcece7SHeiko Schocher }
171*c0dcece7SHeiko Schocher 
172*c0dcece7SHeiko Schocher void hw_watchdog_init(void)
173*c0dcece7SHeiko Schocher {
174*c0dcece7SHeiko Schocher 	gpio_request(WATCHDOG_TRIGGER_GPIO, "watchdog_trigger");
175*c0dcece7SHeiko Schocher 	gpio_direction_output(WATCHDOG_TRIGGER_GPIO, hw_watchdog_trigger_level);
176*c0dcece7SHeiko Schocher 
177*c0dcece7SHeiko Schocher 	hw_watchdog_reset();
178*c0dcece7SHeiko Schocher 
179*c0dcece7SHeiko Schocher 	hw_watchdog_init_done = 1;
180*c0dcece7SHeiko Schocher }
181*c0dcece7SHeiko Schocher #endif /* defined(CONFIG_HW_WATCHDOG) */
182*c0dcece7SHeiko Schocher 
183*c0dcece7SHeiko Schocher #if defined(CONFIG_VIDEO) && !defined(CONFIG_SPL_BUILD)
184*c0dcece7SHeiko Schocher static struct da8xx_panel lcd_panels[] = {
185*c0dcece7SHeiko Schocher 	/* FORMIKE, 4.3", 480x800, KWH043MC17-F01 */
186*c0dcece7SHeiko Schocher 	[0] = {
187*c0dcece7SHeiko Schocher 		.name   = "KWH043MC17-F01",
188*c0dcece7SHeiko Schocher 		.width  = 480,
189*c0dcece7SHeiko Schocher 		.height = 800,
190*c0dcece7SHeiko Schocher 		.hfp = 50,              /* no spec, "don't care" values */
191*c0dcece7SHeiko Schocher 		.hbp = 50,
192*c0dcece7SHeiko Schocher 		.hsw = 50,
193*c0dcece7SHeiko Schocher 		.vfp = 50,
194*c0dcece7SHeiko Schocher 		.vbp = 50,
195*c0dcece7SHeiko Schocher 		.vsw = 50,
196*c0dcece7SHeiko Schocher 		.pxl_clk = 35910000,    /* tCYCD=20ns, max 50MHz, 60fps */
197*c0dcece7SHeiko Schocher 		.invert_pxl_clk = 1,
198*c0dcece7SHeiko Schocher 	},
199*c0dcece7SHeiko Schocher 	/* FORMIKE, 4.3", 480x800, KWH043ST20-F01 */
200*c0dcece7SHeiko Schocher 	[1] = {
201*c0dcece7SHeiko Schocher 		.name   = "KWH043ST20-F01",
202*c0dcece7SHeiko Schocher 		.width  = 480,
203*c0dcece7SHeiko Schocher 		.height = 800,
204*c0dcece7SHeiko Schocher 		.hfp = 50,              /* no spec, "don't care" values */
205*c0dcece7SHeiko Schocher 		.hbp = 50,
206*c0dcece7SHeiko Schocher 		.hsw = 50,
207*c0dcece7SHeiko Schocher 		.vfp = 50,
208*c0dcece7SHeiko Schocher 		.vbp = 50,
209*c0dcece7SHeiko Schocher 		.vsw = 50,
210*c0dcece7SHeiko Schocher 		.pxl_clk = 35910000,    /* tCYCD=20ns, max 50MHz, 60fps */
211*c0dcece7SHeiko Schocher 		.invert_pxl_clk = 1,
212*c0dcece7SHeiko Schocher 	},
213*c0dcece7SHeiko Schocher 	/* Multi-Inno, 4.3", 480x800, MI0430VT-1 */
214*c0dcece7SHeiko Schocher 	[2] = {
215*c0dcece7SHeiko Schocher 		.name   = "MI0430VT-1",
216*c0dcece7SHeiko Schocher 		.width  = 480,
217*c0dcece7SHeiko Schocher 		.height = 800,
218*c0dcece7SHeiko Schocher 		.hfp = 50,              /* no spec, "don't care" values */
219*c0dcece7SHeiko Schocher 		.hbp = 50,
220*c0dcece7SHeiko Schocher 		.hsw = 50,
221*c0dcece7SHeiko Schocher 		.vfp = 50,
222*c0dcece7SHeiko Schocher 		.vbp = 50,
223*c0dcece7SHeiko Schocher 		.vsw = 50,
224*c0dcece7SHeiko Schocher 		.pxl_clk = 35910000,    /* tCYCD=20ns, max 50MHz, 60fps */
225*c0dcece7SHeiko Schocher 		.invert_pxl_clk = 1,
226*c0dcece7SHeiko Schocher 	},
227*c0dcece7SHeiko Schocher };
228*c0dcece7SHeiko Schocher 
229*c0dcece7SHeiko Schocher static const struct display_panel disp_panels[] = {
230*c0dcece7SHeiko Schocher 	[0] = {
231*c0dcece7SHeiko Schocher 		WVGA,
232*c0dcece7SHeiko Schocher 		16,	/* RGB 888 */
233*c0dcece7SHeiko Schocher 		16,
234*c0dcece7SHeiko Schocher 		COLOR_ACTIVE,
235*c0dcece7SHeiko Schocher 	},
236*c0dcece7SHeiko Schocher 	[1] = {
237*c0dcece7SHeiko Schocher 		WVGA,
238*c0dcece7SHeiko Schocher 		16,	/* RGB 888 */
239*c0dcece7SHeiko Schocher 		16,
240*c0dcece7SHeiko Schocher 		COLOR_ACTIVE,
241*c0dcece7SHeiko Schocher 	},
242*c0dcece7SHeiko Schocher 	[2] = {
243*c0dcece7SHeiko Schocher 		WVGA,
244*c0dcece7SHeiko Schocher 		24,	/* RGB 888 */
245*c0dcece7SHeiko Schocher 		16,
246*c0dcece7SHeiko Schocher 		COLOR_ACTIVE,
247*c0dcece7SHeiko Schocher 	},
248*c0dcece7SHeiko Schocher };
249*c0dcece7SHeiko Schocher 
250*c0dcece7SHeiko Schocher static const struct lcd_ctrl_config lcd_cfgs[] = {
251*c0dcece7SHeiko Schocher 	[0] = {
252*c0dcece7SHeiko Schocher 		&disp_panels[0],
253*c0dcece7SHeiko Schocher 		.ac_bias		= 255,
254*c0dcece7SHeiko Schocher 		.ac_bias_intrpt		= 0,
255*c0dcece7SHeiko Schocher 		.dma_burst_sz		= 16,
256*c0dcece7SHeiko Schocher 		.bpp			= 16,
257*c0dcece7SHeiko Schocher 		.fdd			= 0x80,
258*c0dcece7SHeiko Schocher 		.tft_alt_mode		= 0,
259*c0dcece7SHeiko Schocher 		.stn_565_mode		= 0,
260*c0dcece7SHeiko Schocher 		.mono_8bit_mode		= 0,
261*c0dcece7SHeiko Schocher 		.invert_line_clock	= 1,
262*c0dcece7SHeiko Schocher 		.invert_frm_clock	= 1,
263*c0dcece7SHeiko Schocher 		.sync_edge		= 0,
264*c0dcece7SHeiko Schocher 		.sync_ctrl		= 1,
265*c0dcece7SHeiko Schocher 		.raster_order		= 0,
266*c0dcece7SHeiko Schocher 	},
267*c0dcece7SHeiko Schocher 	[1] = {
268*c0dcece7SHeiko Schocher 		&disp_panels[1],
269*c0dcece7SHeiko Schocher 		.ac_bias		= 255,
270*c0dcece7SHeiko Schocher 		.ac_bias_intrpt		= 0,
271*c0dcece7SHeiko Schocher 		.dma_burst_sz		= 16,
272*c0dcece7SHeiko Schocher 		.bpp			= 16,
273*c0dcece7SHeiko Schocher 		.fdd			= 0x80,
274*c0dcece7SHeiko Schocher 		.tft_alt_mode		= 0,
275*c0dcece7SHeiko Schocher 		.stn_565_mode		= 0,
276*c0dcece7SHeiko Schocher 		.mono_8bit_mode		= 0,
277*c0dcece7SHeiko Schocher 		.invert_line_clock	= 1,
278*c0dcece7SHeiko Schocher 		.invert_frm_clock	= 1,
279*c0dcece7SHeiko Schocher 		.sync_edge		= 0,
280*c0dcece7SHeiko Schocher 		.sync_ctrl		= 1,
281*c0dcece7SHeiko Schocher 		.raster_order		= 0,
282*c0dcece7SHeiko Schocher 	},
283*c0dcece7SHeiko Schocher 	[2] = {
284*c0dcece7SHeiko Schocher 		&disp_panels[2],
285*c0dcece7SHeiko Schocher 		.ac_bias		= 255,
286*c0dcece7SHeiko Schocher 		.ac_bias_intrpt		= 0,
287*c0dcece7SHeiko Schocher 		.dma_burst_sz		= 16,
288*c0dcece7SHeiko Schocher 		.bpp			= 24,
289*c0dcece7SHeiko Schocher 		.fdd			= 0x80,
290*c0dcece7SHeiko Schocher 		.tft_alt_mode		= 0,
291*c0dcece7SHeiko Schocher 		.stn_565_mode		= 0,
292*c0dcece7SHeiko Schocher 		.mono_8bit_mode		= 0,
293*c0dcece7SHeiko Schocher 		.invert_line_clock	= 1,
294*c0dcece7SHeiko Schocher 		.invert_frm_clock	= 1,
295*c0dcece7SHeiko Schocher 		.sync_edge		= 0,
296*c0dcece7SHeiko Schocher 		.sync_ctrl		= 1,
297*c0dcece7SHeiko Schocher 		.raster_order		= 0,
298*c0dcece7SHeiko Schocher 	},
299*c0dcece7SHeiko Schocher 
300*c0dcece7SHeiko Schocher };
301*c0dcece7SHeiko Schocher 
302*c0dcece7SHeiko Schocher /* no console on this board */
303*c0dcece7SHeiko Schocher int board_cfb_skip(void)
304*c0dcece7SHeiko Schocher {
305*c0dcece7SHeiko Schocher 	return 1;
306*c0dcece7SHeiko Schocher }
307*c0dcece7SHeiko Schocher 
308*c0dcece7SHeiko Schocher #define PLL_GET_M(v) ((v >> 8) & 0x7ff)
309*c0dcece7SHeiko Schocher #define PLL_GET_N(v) (v & 0x7f)
310*c0dcece7SHeiko Schocher 
311*c0dcece7SHeiko Schocher static struct dpll_regs dpll_lcd_regs = {
312*c0dcece7SHeiko Schocher 	.cm_clkmode_dpll = CM_WKUP + 0x98,
313*c0dcece7SHeiko Schocher 	.cm_idlest_dpll = CM_WKUP + 0x48,
314*c0dcece7SHeiko Schocher 	.cm_clksel_dpll = CM_WKUP + 0x54,
315*c0dcece7SHeiko Schocher };
316*c0dcece7SHeiko Schocher 
317*c0dcece7SHeiko Schocher static int get_clk(struct dpll_regs *dpll_regs)
318*c0dcece7SHeiko Schocher {
319*c0dcece7SHeiko Schocher 	unsigned int val;
320*c0dcece7SHeiko Schocher 	unsigned int m, n;
321*c0dcece7SHeiko Schocher 	int f = 0;
322*c0dcece7SHeiko Schocher 
323*c0dcece7SHeiko Schocher 	val = readl(dpll_regs->cm_clksel_dpll);
324*c0dcece7SHeiko Schocher 	m = PLL_GET_M(val);
325*c0dcece7SHeiko Schocher 	n = PLL_GET_N(val);
326*c0dcece7SHeiko Schocher 	f = (m * V_OSCK) / n;
327*c0dcece7SHeiko Schocher 
328*c0dcece7SHeiko Schocher 	return f;
329*c0dcece7SHeiko Schocher };
330*c0dcece7SHeiko Schocher 
331*c0dcece7SHeiko Schocher 
332*c0dcece7SHeiko Schocher 
333*c0dcece7SHeiko Schocher int clk_get(int clk)
334*c0dcece7SHeiko Schocher {
335*c0dcece7SHeiko Schocher 	return get_clk(&dpll_lcd_regs);
336*c0dcece7SHeiko Schocher };
337*c0dcece7SHeiko Schocher 
338*c0dcece7SHeiko Schocher static int conf_disp_pll(int m, int n)
339*c0dcece7SHeiko Schocher {
340*c0dcece7SHeiko Schocher 	struct cm_perpll *cmper = (struct cm_perpll *)CM_PER;
341*c0dcece7SHeiko Schocher 	struct cm_dpll *cmdpll = (struct cm_dpll *)CM_DPLL;
342*c0dcece7SHeiko Schocher 	struct dpll_params dpll_lcd = {m, n, -1, -1, -1, -1, -1};
343*c0dcece7SHeiko Schocher #if defined(DISPL_PLL_SPREAD_SPECTRUM)
344*c0dcece7SHeiko Schocher 	struct cm_wkuppll *cmwkup = (struct cm_wkuppll *)CM_WKUP;
345*c0dcece7SHeiko Schocher #endif
346*c0dcece7SHeiko Schocher 
347*c0dcece7SHeiko Schocher 	u32 *const clk_domains[] = {
348*c0dcece7SHeiko Schocher 		&cmper->lcdclkctrl,
349*c0dcece7SHeiko Schocher 		0
350*c0dcece7SHeiko Schocher 	};
351*c0dcece7SHeiko Schocher 	u32 *const clk_modules_explicit_en[] = {
352*c0dcece7SHeiko Schocher 		&cmper->lcdclkctrl,
353*c0dcece7SHeiko Schocher 		&cmper->lcdcclkstctrl,
354*c0dcece7SHeiko Schocher 		&cmper->spi1clkctrl,
355*c0dcece7SHeiko Schocher 		0
356*c0dcece7SHeiko Schocher 	};
357*c0dcece7SHeiko Schocher 	do_enable_clocks(clk_domains, clk_modules_explicit_en, 1);
358*c0dcece7SHeiko Schocher 	/* 0x44e0_0500 write lcdc pixel clock mux Linux hat hier 0 */
359*c0dcece7SHeiko Schocher 	writel(0x0, &cmdpll->clklcdcpixelclk);
360*c0dcece7SHeiko Schocher 
361*c0dcece7SHeiko Schocher 	do_setup_dpll(&dpll_lcd_regs, &dpll_lcd);
362*c0dcece7SHeiko Schocher 
363*c0dcece7SHeiko Schocher #if defined(DISPL_PLL_SPREAD_SPECTRUM)
364*c0dcece7SHeiko Schocher 	writel(0x64, &cmwkup->resv6[3]); /* 0x50 */
365*c0dcece7SHeiko Schocher 	writel(0x800, &cmwkup->resv6[2]); /* 0x4c */
366*c0dcece7SHeiko Schocher 	writel(readl(&cmwkup->clkmoddplldisp) | (1 << 12),
367*c0dcece7SHeiko Schocher 	       &cmwkup->clkmoddplldisp); /* 0x98 */
368*c0dcece7SHeiko Schocher #endif
369*c0dcece7SHeiko Schocher 	return 0;
370*c0dcece7SHeiko Schocher }
371*c0dcece7SHeiko Schocher 
372*c0dcece7SHeiko Schocher static int set_gpio(int gpio, int state)
373*c0dcece7SHeiko Schocher {
374*c0dcece7SHeiko Schocher 	gpio_request(gpio, "temp");
375*c0dcece7SHeiko Schocher 	gpio_direction_output(gpio, state);
376*c0dcece7SHeiko Schocher 	gpio_set_value(gpio, state);
377*c0dcece7SHeiko Schocher 	gpio_free(gpio);
378*c0dcece7SHeiko Schocher 	return 0;
379*c0dcece7SHeiko Schocher }
380*c0dcece7SHeiko Schocher 
381*c0dcece7SHeiko Schocher static int enable_lcd(void)
382*c0dcece7SHeiko Schocher {
383*c0dcece7SHeiko Schocher 	unsigned char buf[1];
384*c0dcece7SHeiko Schocher 
385*c0dcece7SHeiko Schocher 	set_gpio(BOARD_LCD_RESET, 1);
386*c0dcece7SHeiko Schocher 
387*c0dcece7SHeiko Schocher 	/* spi lcd init */
388*c0dcece7SHeiko Schocher 	kwh043st20_f01_spi_startup(1, 0, 5000000, SPI_MODE_3);
389*c0dcece7SHeiko Schocher 
390*c0dcece7SHeiko Schocher 	/* backlight on */
391*c0dcece7SHeiko Schocher 	buf[0] = 0xf;
392*c0dcece7SHeiko Schocher 	i2c_write(0x24, 0x7, 1, buf, 1);
393*c0dcece7SHeiko Schocher 	buf[0] = 0x3f;
394*c0dcece7SHeiko Schocher 	i2c_write(0x24, 0x8, 1, buf, 1);
395*c0dcece7SHeiko Schocher 	return 0;
396*c0dcece7SHeiko Schocher }
397*c0dcece7SHeiko Schocher 
398*c0dcece7SHeiko Schocher int arch_early_init_r(void)
399*c0dcece7SHeiko Schocher {
400*c0dcece7SHeiko Schocher 	enable_lcd();
401*c0dcece7SHeiko Schocher 	return 0;
402*c0dcece7SHeiko Schocher }
403*c0dcece7SHeiko Schocher 
404*c0dcece7SHeiko Schocher static int board_video_init(void)
405*c0dcece7SHeiko Schocher {
406*c0dcece7SHeiko Schocher 	int i;
407*c0dcece7SHeiko Schocher 	int anzdisp = ARRAY_SIZE(lcd_panels);
408*c0dcece7SHeiko Schocher 	int display = 1;
409*c0dcece7SHeiko Schocher 
410*c0dcece7SHeiko Schocher 	for (i = 0; i < anzdisp; i++) {
411*c0dcece7SHeiko Schocher 		if (strncmp((const char *)factory_dat.disp_name,
412*c0dcece7SHeiko Schocher 			    lcd_panels[i].name,
413*c0dcece7SHeiko Schocher 		    strlen((const char *)factory_dat.disp_name)) == 0) {
414*c0dcece7SHeiko Schocher 			printf("DISPLAY: %s\n", factory_dat.disp_name);
415*c0dcece7SHeiko Schocher 			break;
416*c0dcece7SHeiko Schocher 		}
417*c0dcece7SHeiko Schocher 	}
418*c0dcece7SHeiko Schocher 	if (i == anzdisp) {
419*c0dcece7SHeiko Schocher 		i = 1;
420*c0dcece7SHeiko Schocher 		printf("%s: %s not found, using default %s\n", __func__,
421*c0dcece7SHeiko Schocher 		       factory_dat.disp_name, lcd_panels[i].name);
422*c0dcece7SHeiko Schocher 	}
423*c0dcece7SHeiko Schocher 	conf_disp_pll(25, 2);
424*c0dcece7SHeiko Schocher 	da8xx_video_init(&lcd_panels[display], &lcd_cfgs[display],
425*c0dcece7SHeiko Schocher 			 lcd_cfgs[display].bpp);
426*c0dcece7SHeiko Schocher 
427*c0dcece7SHeiko Schocher 	return 0;
428*c0dcece7SHeiko Schocher }
429*c0dcece7SHeiko Schocher 
430*c0dcece7SHeiko Schocher 
431*c0dcece7SHeiko Schocher #endif /* ifdef CONFIG_VIDEO */
432*c0dcece7SHeiko Schocher #include "../common/board.c"
433