xref: /openbmc/linux/arch/sh/boards/board-sh7785lcr.c (revision c8b5d9dcbc94ae5e7d9ed647246df4454d25332e)
1*c8b5d9dcSPaul Mundt /*
2*c8b5d9dcSPaul Mundt  * Renesas Technology Corp. R0P7785LC0011RL Support.
3*c8b5d9dcSPaul Mundt  *
4*c8b5d9dcSPaul Mundt  * Copyright (C) 2008  Yoshihiro Shimoda
5*c8b5d9dcSPaul Mundt  *
6*c8b5d9dcSPaul Mundt  * This file is subject to the terms and conditions of the GNU General Public
7*c8b5d9dcSPaul Mundt  * License.  See the file "COPYING" in the main directory of this archive
8*c8b5d9dcSPaul Mundt  * for more details.
9*c8b5d9dcSPaul Mundt  */
10*c8b5d9dcSPaul Mundt 
11*c8b5d9dcSPaul Mundt #include <linux/init.h>
12*c8b5d9dcSPaul Mundt #include <linux/platform_device.h>
13*c8b5d9dcSPaul Mundt #include <linux/sm501.h>
14*c8b5d9dcSPaul Mundt #include <linux/sm501-regs.h>
15*c8b5d9dcSPaul Mundt #include <linux/fb.h>
16*c8b5d9dcSPaul Mundt #include <linux/mtd/physmap.h>
17*c8b5d9dcSPaul Mundt #include <linux/delay.h>
18*c8b5d9dcSPaul Mundt #include <linux/i2c.h>
19*c8b5d9dcSPaul Mundt #include <linux/i2c-pca-platform.h>
20*c8b5d9dcSPaul Mundt #include <linux/i2c-algo-pca.h>
21*c8b5d9dcSPaul Mundt #include <asm/heartbeat.h>
22*c8b5d9dcSPaul Mundt #include <asm/sh7785lcr.h>
23*c8b5d9dcSPaul Mundt 
24*c8b5d9dcSPaul Mundt /*
25*c8b5d9dcSPaul Mundt  * NOTE: This board has 2 physical memory maps.
26*c8b5d9dcSPaul Mundt  *	 Please look at include/asm-sh/sh7785lcr.h or hardware manual.
27*c8b5d9dcSPaul Mundt  */
28*c8b5d9dcSPaul Mundt static struct resource heartbeat_resources[] = {
29*c8b5d9dcSPaul Mundt 	[0] = {
30*c8b5d9dcSPaul Mundt 		.start	= PLD_LEDCR,
31*c8b5d9dcSPaul Mundt 		.end	= PLD_LEDCR,
32*c8b5d9dcSPaul Mundt 		.flags	= IORESOURCE_MEM,
33*c8b5d9dcSPaul Mundt 	},
34*c8b5d9dcSPaul Mundt };
35*c8b5d9dcSPaul Mundt 
36*c8b5d9dcSPaul Mundt static struct heartbeat_data heartbeat_data = {
37*c8b5d9dcSPaul Mundt 	.regsize = 8,
38*c8b5d9dcSPaul Mundt };
39*c8b5d9dcSPaul Mundt 
40*c8b5d9dcSPaul Mundt static struct platform_device heartbeat_device = {
41*c8b5d9dcSPaul Mundt 	.name		= "heartbeat",
42*c8b5d9dcSPaul Mundt 	.id		= -1,
43*c8b5d9dcSPaul Mundt 	.dev	= {
44*c8b5d9dcSPaul Mundt 		.platform_data	= &heartbeat_data,
45*c8b5d9dcSPaul Mundt 	},
46*c8b5d9dcSPaul Mundt 	.num_resources	= ARRAY_SIZE(heartbeat_resources),
47*c8b5d9dcSPaul Mundt 	.resource	= heartbeat_resources,
48*c8b5d9dcSPaul Mundt };
49*c8b5d9dcSPaul Mundt 
50*c8b5d9dcSPaul Mundt static struct mtd_partition nor_flash_partitions[] = {
51*c8b5d9dcSPaul Mundt 	{
52*c8b5d9dcSPaul Mundt 		.name		= "loader",
53*c8b5d9dcSPaul Mundt 		.offset		= 0x00000000,
54*c8b5d9dcSPaul Mundt 		.size		= 512 * 1024,
55*c8b5d9dcSPaul Mundt 	},
56*c8b5d9dcSPaul Mundt 	{
57*c8b5d9dcSPaul Mundt 		.name		= "bootenv",
58*c8b5d9dcSPaul Mundt 		.offset		= MTDPART_OFS_APPEND,
59*c8b5d9dcSPaul Mundt 		.size		= 512 * 1024,
60*c8b5d9dcSPaul Mundt 	},
61*c8b5d9dcSPaul Mundt 	{
62*c8b5d9dcSPaul Mundt 		.name		= "kernel",
63*c8b5d9dcSPaul Mundt 		.offset		= MTDPART_OFS_APPEND,
64*c8b5d9dcSPaul Mundt 		.size		= 4 * 1024 * 1024,
65*c8b5d9dcSPaul Mundt 	},
66*c8b5d9dcSPaul Mundt 	{
67*c8b5d9dcSPaul Mundt 		.name		= "data",
68*c8b5d9dcSPaul Mundt 		.offset		= MTDPART_OFS_APPEND,
69*c8b5d9dcSPaul Mundt 		.size		= MTDPART_SIZ_FULL,
70*c8b5d9dcSPaul Mundt 	},
71*c8b5d9dcSPaul Mundt };
72*c8b5d9dcSPaul Mundt 
73*c8b5d9dcSPaul Mundt static struct physmap_flash_data nor_flash_data = {
74*c8b5d9dcSPaul Mundt 	.width		= 4,
75*c8b5d9dcSPaul Mundt 	.parts		= nor_flash_partitions,
76*c8b5d9dcSPaul Mundt 	.nr_parts	= ARRAY_SIZE(nor_flash_partitions),
77*c8b5d9dcSPaul Mundt };
78*c8b5d9dcSPaul Mundt 
79*c8b5d9dcSPaul Mundt static struct resource nor_flash_resources[] = {
80*c8b5d9dcSPaul Mundt 	[0]	= {
81*c8b5d9dcSPaul Mundt 		.start	= NOR_FLASH_ADDR,
82*c8b5d9dcSPaul Mundt 		.end	= NOR_FLASH_ADDR + NOR_FLASH_SIZE - 1,
83*c8b5d9dcSPaul Mundt 		.flags	= IORESOURCE_MEM,
84*c8b5d9dcSPaul Mundt 	}
85*c8b5d9dcSPaul Mundt };
86*c8b5d9dcSPaul Mundt 
87*c8b5d9dcSPaul Mundt static struct platform_device nor_flash_device = {
88*c8b5d9dcSPaul Mundt 	.name		= "physmap-flash",
89*c8b5d9dcSPaul Mundt 	.dev		= {
90*c8b5d9dcSPaul Mundt 		.platform_data	= &nor_flash_data,
91*c8b5d9dcSPaul Mundt 	},
92*c8b5d9dcSPaul Mundt 	.num_resources	= ARRAY_SIZE(nor_flash_resources),
93*c8b5d9dcSPaul Mundt 	.resource	= nor_flash_resources,
94*c8b5d9dcSPaul Mundt };
95*c8b5d9dcSPaul Mundt 
96*c8b5d9dcSPaul Mundt static struct resource r8a66597_usb_host_resources[] = {
97*c8b5d9dcSPaul Mundt 	[0] = {
98*c8b5d9dcSPaul Mundt 		.name	= "r8a66597_hcd",
99*c8b5d9dcSPaul Mundt 		.start	= R8A66597_ADDR,
100*c8b5d9dcSPaul Mundt 		.end	= R8A66597_ADDR + R8A66597_SIZE - 1,
101*c8b5d9dcSPaul Mundt 		.flags	= IORESOURCE_MEM,
102*c8b5d9dcSPaul Mundt 	},
103*c8b5d9dcSPaul Mundt 	[1] = {
104*c8b5d9dcSPaul Mundt 		.name	= "r8a66597_hcd",
105*c8b5d9dcSPaul Mundt 		.start	= 2,
106*c8b5d9dcSPaul Mundt 		.end	= 2,
107*c8b5d9dcSPaul Mundt 		.flags	= IORESOURCE_IRQ,
108*c8b5d9dcSPaul Mundt 	},
109*c8b5d9dcSPaul Mundt };
110*c8b5d9dcSPaul Mundt 
111*c8b5d9dcSPaul Mundt static struct platform_device r8a66597_usb_host_device = {
112*c8b5d9dcSPaul Mundt 	.name		= "r8a66597_hcd",
113*c8b5d9dcSPaul Mundt 	.id		= -1,
114*c8b5d9dcSPaul Mundt 	.dev = {
115*c8b5d9dcSPaul Mundt 		.dma_mask		= NULL,
116*c8b5d9dcSPaul Mundt 		.coherent_dma_mask	= 0xffffffff,
117*c8b5d9dcSPaul Mundt 	},
118*c8b5d9dcSPaul Mundt 	.num_resources	= ARRAY_SIZE(r8a66597_usb_host_resources),
119*c8b5d9dcSPaul Mundt 	.resource	= r8a66597_usb_host_resources,
120*c8b5d9dcSPaul Mundt };
121*c8b5d9dcSPaul Mundt 
122*c8b5d9dcSPaul Mundt static struct resource sm501_resources[] = {
123*c8b5d9dcSPaul Mundt 	[0]	= {
124*c8b5d9dcSPaul Mundt 		.start	= SM107_MEM_ADDR,
125*c8b5d9dcSPaul Mundt 		.end	= SM107_MEM_ADDR + SM107_MEM_SIZE - 1,
126*c8b5d9dcSPaul Mundt 		.flags	= IORESOURCE_MEM,
127*c8b5d9dcSPaul Mundt 	},
128*c8b5d9dcSPaul Mundt 	[1]	= {
129*c8b5d9dcSPaul Mundt 		.start	= SM107_REG_ADDR,
130*c8b5d9dcSPaul Mundt 		.end	= SM107_REG_ADDR + SM107_REG_SIZE - 1,
131*c8b5d9dcSPaul Mundt 		.flags	= IORESOURCE_MEM,
132*c8b5d9dcSPaul Mundt 	},
133*c8b5d9dcSPaul Mundt 	[2]	= {
134*c8b5d9dcSPaul Mundt 		.start	= 10,
135*c8b5d9dcSPaul Mundt 		.flags	= IORESOURCE_IRQ,
136*c8b5d9dcSPaul Mundt 	},
137*c8b5d9dcSPaul Mundt };
138*c8b5d9dcSPaul Mundt 
139*c8b5d9dcSPaul Mundt static struct fb_videomode sm501_default_mode_crt = {
140*c8b5d9dcSPaul Mundt 	.pixclock	= 35714,	/* 28MHz */
141*c8b5d9dcSPaul Mundt 	.xres		= 640,
142*c8b5d9dcSPaul Mundt 	.yres		= 480,
143*c8b5d9dcSPaul Mundt 	.left_margin	= 105,
144*c8b5d9dcSPaul Mundt 	.right_margin	= 16,
145*c8b5d9dcSPaul Mundt 	.upper_margin	= 33,
146*c8b5d9dcSPaul Mundt 	.lower_margin	= 10,
147*c8b5d9dcSPaul Mundt 	.hsync_len	= 39,
148*c8b5d9dcSPaul Mundt 	.vsync_len	= 2,
149*c8b5d9dcSPaul Mundt 	.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
150*c8b5d9dcSPaul Mundt };
151*c8b5d9dcSPaul Mundt 
152*c8b5d9dcSPaul Mundt static struct fb_videomode sm501_default_mode_pnl = {
153*c8b5d9dcSPaul Mundt 	.pixclock	= 40000,	/* 25MHz */
154*c8b5d9dcSPaul Mundt 	.xres		= 640,
155*c8b5d9dcSPaul Mundt 	.yres		= 480,
156*c8b5d9dcSPaul Mundt 	.left_margin	= 2,
157*c8b5d9dcSPaul Mundt 	.right_margin	= 16,
158*c8b5d9dcSPaul Mundt 	.upper_margin	= 33,
159*c8b5d9dcSPaul Mundt 	.lower_margin	= 10,
160*c8b5d9dcSPaul Mundt 	.hsync_len	= 39,
161*c8b5d9dcSPaul Mundt 	.vsync_len	= 2,
162*c8b5d9dcSPaul Mundt 	.sync		= 0,
163*c8b5d9dcSPaul Mundt };
164*c8b5d9dcSPaul Mundt 
165*c8b5d9dcSPaul Mundt static struct sm501_platdata_fbsub sm501_pdata_fbsub_pnl = {
166*c8b5d9dcSPaul Mundt 	.def_bpp	= 16,
167*c8b5d9dcSPaul Mundt 	.def_mode	= &sm501_default_mode_pnl,
168*c8b5d9dcSPaul Mundt 	.flags		= SM501FB_FLAG_USE_INIT_MODE |
169*c8b5d9dcSPaul Mundt 			  SM501FB_FLAG_USE_HWCURSOR |
170*c8b5d9dcSPaul Mundt 			  SM501FB_FLAG_USE_HWACCEL |
171*c8b5d9dcSPaul Mundt 			  SM501FB_FLAG_DISABLE_AT_EXIT |
172*c8b5d9dcSPaul Mundt 			  SM501FB_FLAG_PANEL_NO_VBIASEN,
173*c8b5d9dcSPaul Mundt };
174*c8b5d9dcSPaul Mundt 
175*c8b5d9dcSPaul Mundt static struct sm501_platdata_fbsub sm501_pdata_fbsub_crt = {
176*c8b5d9dcSPaul Mundt 	.def_bpp	= 16,
177*c8b5d9dcSPaul Mundt 	.def_mode	= &sm501_default_mode_crt,
178*c8b5d9dcSPaul Mundt 	.flags		= SM501FB_FLAG_USE_INIT_MODE |
179*c8b5d9dcSPaul Mundt 			  SM501FB_FLAG_USE_HWCURSOR |
180*c8b5d9dcSPaul Mundt 			  SM501FB_FLAG_USE_HWACCEL |
181*c8b5d9dcSPaul Mundt 			  SM501FB_FLAG_DISABLE_AT_EXIT,
182*c8b5d9dcSPaul Mundt };
183*c8b5d9dcSPaul Mundt 
184*c8b5d9dcSPaul Mundt static struct sm501_platdata_fb sm501_fb_pdata = {
185*c8b5d9dcSPaul Mundt 	.fb_route	= SM501_FB_OWN,
186*c8b5d9dcSPaul Mundt 	.fb_crt		= &sm501_pdata_fbsub_crt,
187*c8b5d9dcSPaul Mundt 	.fb_pnl		= &sm501_pdata_fbsub_pnl,
188*c8b5d9dcSPaul Mundt };
189*c8b5d9dcSPaul Mundt 
190*c8b5d9dcSPaul Mundt static struct sm501_initdata sm501_initdata = {
191*c8b5d9dcSPaul Mundt 	.gpio_high	= {
192*c8b5d9dcSPaul Mundt 		.set	= 0x00001fe0,
193*c8b5d9dcSPaul Mundt 		.mask	= 0x0,
194*c8b5d9dcSPaul Mundt 	},
195*c8b5d9dcSPaul Mundt 	.devices	= 0,
196*c8b5d9dcSPaul Mundt 	.mclk		= 84 * 1000000,
197*c8b5d9dcSPaul Mundt 	.m1xclk		= 112 * 1000000,
198*c8b5d9dcSPaul Mundt };
199*c8b5d9dcSPaul Mundt 
200*c8b5d9dcSPaul Mundt static struct sm501_platdata sm501_platform_data = {
201*c8b5d9dcSPaul Mundt 	.init		= &sm501_initdata,
202*c8b5d9dcSPaul Mundt 	.fb		= &sm501_fb_pdata,
203*c8b5d9dcSPaul Mundt };
204*c8b5d9dcSPaul Mundt 
205*c8b5d9dcSPaul Mundt static struct platform_device sm501_device = {
206*c8b5d9dcSPaul Mundt 	.name		= "sm501",
207*c8b5d9dcSPaul Mundt 	.id		= -1,
208*c8b5d9dcSPaul Mundt 	.dev		= {
209*c8b5d9dcSPaul Mundt 		.platform_data	= &sm501_platform_data,
210*c8b5d9dcSPaul Mundt 	},
211*c8b5d9dcSPaul Mundt 	.num_resources	= ARRAY_SIZE(sm501_resources),
212*c8b5d9dcSPaul Mundt 	.resource	= sm501_resources,
213*c8b5d9dcSPaul Mundt };
214*c8b5d9dcSPaul Mundt 
215*c8b5d9dcSPaul Mundt static struct resource i2c_resources[] = {
216*c8b5d9dcSPaul Mundt 	[0] = {
217*c8b5d9dcSPaul Mundt 		.start	= PCA9564_ADDR,
218*c8b5d9dcSPaul Mundt 		.end	= PCA9564_ADDR + PCA9564_SIZE - 1,
219*c8b5d9dcSPaul Mundt 		.flags	= IORESOURCE_MEM | IORESOURCE_MEM_8BIT,
220*c8b5d9dcSPaul Mundt 	},
221*c8b5d9dcSPaul Mundt 	[1] = {
222*c8b5d9dcSPaul Mundt 		.start	= 12,
223*c8b5d9dcSPaul Mundt 		.end	= 12,
224*c8b5d9dcSPaul Mundt 		.flags	= IORESOURCE_IRQ,
225*c8b5d9dcSPaul Mundt 	},
226*c8b5d9dcSPaul Mundt };
227*c8b5d9dcSPaul Mundt 
228*c8b5d9dcSPaul Mundt static struct i2c_pca9564_pf_platform_data i2c_platform_data = {
229*c8b5d9dcSPaul Mundt 	.gpio			= 0,
230*c8b5d9dcSPaul Mundt 	.i2c_clock_speed	= I2C_PCA_CON_330kHz,
231*c8b5d9dcSPaul Mundt 	.timeout		= 100,
232*c8b5d9dcSPaul Mundt };
233*c8b5d9dcSPaul Mundt 
234*c8b5d9dcSPaul Mundt static struct platform_device i2c_device = {
235*c8b5d9dcSPaul Mundt 	.name		= "i2c-pca-platform",
236*c8b5d9dcSPaul Mundt 	.id		= -1,
237*c8b5d9dcSPaul Mundt 	.dev		= {
238*c8b5d9dcSPaul Mundt 		.platform_data	= &i2c_platform_data,
239*c8b5d9dcSPaul Mundt 	},
240*c8b5d9dcSPaul Mundt 	.num_resources	= ARRAY_SIZE(i2c_resources),
241*c8b5d9dcSPaul Mundt 	.resource	= i2c_resources,
242*c8b5d9dcSPaul Mundt };
243*c8b5d9dcSPaul Mundt 
244*c8b5d9dcSPaul Mundt static struct platform_device *sh7785lcr_devices[] __initdata = {
245*c8b5d9dcSPaul Mundt 	&heartbeat_device,
246*c8b5d9dcSPaul Mundt 	&nor_flash_device,
247*c8b5d9dcSPaul Mundt 	&r8a66597_usb_host_device,
248*c8b5d9dcSPaul Mundt 	&sm501_device,
249*c8b5d9dcSPaul Mundt 	&i2c_device,
250*c8b5d9dcSPaul Mundt };
251*c8b5d9dcSPaul Mundt 
252*c8b5d9dcSPaul Mundt static struct i2c_board_info __initdata sh7785lcr_i2c_devices[] = {
253*c8b5d9dcSPaul Mundt 	{
254*c8b5d9dcSPaul Mundt 		I2C_BOARD_INFO("r2025sd", 0x32),
255*c8b5d9dcSPaul Mundt 	},
256*c8b5d9dcSPaul Mundt };
257*c8b5d9dcSPaul Mundt 
258*c8b5d9dcSPaul Mundt static int __init sh7785lcr_devices_setup(void)
259*c8b5d9dcSPaul Mundt {
260*c8b5d9dcSPaul Mundt 	i2c_register_board_info(0, sh7785lcr_i2c_devices,
261*c8b5d9dcSPaul Mundt 				ARRAY_SIZE(sh7785lcr_i2c_devices));
262*c8b5d9dcSPaul Mundt 
263*c8b5d9dcSPaul Mundt 	return platform_add_devices(sh7785lcr_devices,
264*c8b5d9dcSPaul Mundt 				    ARRAY_SIZE(sh7785lcr_devices));
265*c8b5d9dcSPaul Mundt }
266*c8b5d9dcSPaul Mundt __initcall(sh7785lcr_devices_setup);
267*c8b5d9dcSPaul Mundt 
268*c8b5d9dcSPaul Mundt /* Initialize IRQ setting */
269*c8b5d9dcSPaul Mundt void __init init_sh7785lcr_IRQ(void)
270*c8b5d9dcSPaul Mundt {
271*c8b5d9dcSPaul Mundt 	plat_irq_setup_pins(IRQ_MODE_IRQ7654);
272*c8b5d9dcSPaul Mundt 	plat_irq_setup_pins(IRQ_MODE_IRQ3210);
273*c8b5d9dcSPaul Mundt }
274*c8b5d9dcSPaul Mundt 
275*c8b5d9dcSPaul Mundt static void sh7785lcr_power_off(void)
276*c8b5d9dcSPaul Mundt {
277*c8b5d9dcSPaul Mundt 	ctrl_outb(0x01, P2SEGADDR(PLD_POFCR));
278*c8b5d9dcSPaul Mundt }
279*c8b5d9dcSPaul Mundt 
280*c8b5d9dcSPaul Mundt /* Initialize the board */
281*c8b5d9dcSPaul Mundt static void __init sh7785lcr_setup(char **cmdline_p)
282*c8b5d9dcSPaul Mundt {
283*c8b5d9dcSPaul Mundt 	void __iomem *sm501_reg;
284*c8b5d9dcSPaul Mundt 
285*c8b5d9dcSPaul Mundt 	printk(KERN_INFO "Renesas Technology Corp. R0P7785LC0011RL support.\n");
286*c8b5d9dcSPaul Mundt 
287*c8b5d9dcSPaul Mundt 	pm_power_off = sh7785lcr_power_off;
288*c8b5d9dcSPaul Mundt 
289*c8b5d9dcSPaul Mundt 	/* sm501 DRAM configuration */
290*c8b5d9dcSPaul Mundt 	sm501_reg = (void __iomem *)0xb3e00000 + SM501_DRAM_CONTROL;
291*c8b5d9dcSPaul Mundt 	writel(0x000307c2, sm501_reg);
292*c8b5d9dcSPaul Mundt }
293*c8b5d9dcSPaul Mundt 
294*c8b5d9dcSPaul Mundt /*
295*c8b5d9dcSPaul Mundt  * The Machine Vector
296*c8b5d9dcSPaul Mundt  */
297*c8b5d9dcSPaul Mundt static struct sh_machine_vector mv_sh7785lcr __initmv = {
298*c8b5d9dcSPaul Mundt 	.mv_name		= "SH7785LCR",
299*c8b5d9dcSPaul Mundt 	.mv_setup		= sh7785lcr_setup,
300*c8b5d9dcSPaul Mundt 	.mv_init_irq		= init_sh7785lcr_IRQ,
301*c8b5d9dcSPaul Mundt };
302*c8b5d9dcSPaul Mundt 
303