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