Commit | Line | Data |
---|---|---|
f3590dc3 | 1 | // SPDX-License-Identifier: GPL-2.0 |
e7d16514 MD |
2 | /* |
3 | * KFR2R09 board support code | |
4 | * | |
5 | * Copyright (C) 2009 Magnus Damm | |
e7d16514 | 6 | */ |
f3590dc3 JM |
7 | |
8 | #include <asm/clock.h> | |
9 | #include <asm/io.h> | |
10 | #include <asm/machvec.h> | |
11 | #include <asm/suspend.h> | |
12 | ||
13 | #include <cpu/sh7724.h> | |
14 | ||
15 | #include <linux/clkdev.h> | |
e7d16514 | 16 | #include <linux/delay.h> |
f3590dc3 | 17 | #include <linux/dma-mapping.h> |
e7d16514 | 18 | #include <linux/gpio.h> |
f3590dc3 JM |
19 | #include <linux/gpio/machine.h> |
20 | #include <linux/i2c.h> | |
21 | #include <linux/init.h> | |
39a6bf14 | 22 | #include <linux/input.h> |
fc1d003d | 23 | #include <linux/input/sh_keysc.h> |
f3590dc3 JM |
24 | #include <linux/interrupt.h> |
25 | #include <linux/memblock.h> | |
26 | #include <linux/mfd/tmio.h> | |
27 | #include <linux/mmc/host.h> | |
f3590dc3 | 28 | #include <linux/mtd/physmap.h> |
3f3bee2e | 29 | #include <linux/platform_data/lv5207lp.h> |
f3590dc3 | 30 | #include <linux/platform_device.h> |
da5f2ddc GL |
31 | #include <linux/regulator/fixed.h> |
32 | #include <linux/regulator/machine.h> | |
f3590dc3 | 33 | #include <linux/sh_intc.h> |
5a1c4cb5 | 34 | #include <linux/usb/r8a66597.h> |
a1ad8033 | 35 | #include <linux/videodev2.h> |
f3590dc3 JM |
36 | |
37 | #include <mach/kfr2r09.h> | |
38 | ||
39 | #include <media/drv-intf/renesas-ceu.h> | |
b5dcee22 | 40 | #include <media/i2c/rj54n1cb0c.h> |
f3590dc3 | 41 | |
9f26e659 | 42 | #include <video/sh_mobile_lcdc.h> |
f3590dc3 JM |
43 | |
44 | #define CEU_BUFFER_MEMORY_SIZE (4 << 20) | |
45 | static phys_addr_t ceu_dma_membase; | |
46 | ||
47 | /* set VIO_CKO clock to 25MHz */ | |
48 | #define CEU_MCLK_FREQ 25000000 | |
49 | #define DRVCRB 0xA405018C | |
e7d16514 | 50 | |
a366aa64 MD |
51 | static struct mtd_partition kfr2r09_nor_flash_partitions[] = |
52 | { | |
53 | { | |
54 | .name = "boot", | |
55 | .offset = 0, | |
56 | .size = (4 * 1024 * 1024), | |
57 | .mask_flags = MTD_WRITEABLE, /* Read-only */ | |
58 | }, | |
59 | { | |
60 | .name = "other", | |
61 | .offset = MTDPART_OFS_APPEND, | |
62 | .size = MTDPART_SIZ_FULL, | |
63 | }, | |
64 | }; | |
65 | ||
66 | static struct physmap_flash_data kfr2r09_nor_flash_data = { | |
67 | .width = 2, | |
68 | .parts = kfr2r09_nor_flash_partitions, | |
69 | .nr_parts = ARRAY_SIZE(kfr2r09_nor_flash_partitions), | |
70 | }; | |
71 | ||
72 | static struct resource kfr2r09_nor_flash_resources[] = { | |
73 | [0] = { | |
74 | .name = "NOR Flash", | |
75 | .start = 0x00000000, | |
76 | .end = 0x03ffffff, | |
77 | .flags = IORESOURCE_MEM, | |
78 | } | |
79 | }; | |
80 | ||
81 | static struct platform_device kfr2r09_nor_flash_device = { | |
82 | .name = "physmap-flash", | |
83 | .resource = kfr2r09_nor_flash_resources, | |
84 | .num_resources = ARRAY_SIZE(kfr2r09_nor_flash_resources), | |
85 | .dev = { | |
86 | .platform_data = &kfr2r09_nor_flash_data, | |
87 | }, | |
88 | }; | |
89 | ||
33893d7a MD |
90 | static struct resource kfr2r09_nand_flash_resources[] = { |
91 | [0] = { | |
92 | .name = "NAND Flash", | |
93 | .start = 0x10000000, | |
94 | .end = 0x1001ffff, | |
95 | .flags = IORESOURCE_MEM, | |
96 | } | |
97 | }; | |
98 | ||
99 | static struct platform_device kfr2r09_nand_flash_device = { | |
100 | .name = "onenand-flash", | |
101 | .resource = kfr2r09_nand_flash_resources, | |
102 | .num_resources = ARRAY_SIZE(kfr2r09_nand_flash_resources), | |
103 | }; | |
104 | ||
39a6bf14 MD |
105 | static struct sh_keysc_info kfr2r09_sh_keysc_info = { |
106 | .mode = SH_KEYSC_MODE_1, /* KEYOUT0->4, KEYIN0->4 */ | |
107 | .scan_timing = 3, | |
108 | .delay = 10, | |
109 | .keycodes = { | |
110 | KEY_PHONE, KEY_CLEAR, KEY_MAIL, KEY_WWW, KEY_ENTER, | |
111 | KEY_1, KEY_2, KEY_3, 0, KEY_UP, | |
112 | KEY_4, KEY_5, KEY_6, 0, KEY_LEFT, | |
113 | KEY_7, KEY_8, KEY_9, KEY_PROG1, KEY_RIGHT, | |
114 | KEY_S, KEY_0, KEY_P, KEY_PROG2, KEY_DOWN, | |
115 | 0, 0, 0, 0, 0 | |
116 | }, | |
117 | }; | |
118 | ||
119 | static struct resource kfr2r09_sh_keysc_resources[] = { | |
120 | [0] = { | |
121 | .name = "KEYSC", | |
122 | .start = 0x044b0000, | |
123 | .end = 0x044b000f, | |
124 | .flags = IORESOURCE_MEM, | |
125 | }, | |
126 | [1] = { | |
aa82f9fc | 127 | .start = evt2irq(0xbe0), |
39a6bf14 MD |
128 | .flags = IORESOURCE_IRQ, |
129 | }, | |
130 | }; | |
131 | ||
132 | static struct platform_device kfr2r09_sh_keysc_device = { | |
133 | .name = "sh_keysc", | |
134 | .id = 0, /* "keysc0" clock */ | |
135 | .num_resources = ARRAY_SIZE(kfr2r09_sh_keysc_resources), | |
136 | .resource = kfr2r09_sh_keysc_resources, | |
137 | .dev = { | |
138 | .platform_data = &kfr2r09_sh_keysc_info, | |
139 | }, | |
140 | }; | |
141 | ||
e04008eb | 142 | static const struct fb_videomode kfr2r09_lcdc_modes[] = { |
44432407 GL |
143 | { |
144 | .name = "TX07D34VM0AAA", | |
145 | .xres = 240, | |
146 | .yres = 400, | |
147 | .left_margin = 0, | |
148 | .right_margin = 16, | |
149 | .hsync_len = 8, | |
150 | .upper_margin = 0, | |
151 | .lower_margin = 1, | |
152 | .vsync_len = 1, | |
153 | .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | |
154 | }, | |
155 | }; | |
156 | ||
9f26e659 MD |
157 | static struct sh_mobile_lcdc_info kfr2r09_sh_lcdc_info = { |
158 | .clock_source = LCDC_CLK_BUS, | |
159 | .ch[0] = { | |
160 | .chan = LCDC_CHAN_MAINLCD, | |
edd153a3 | 161 | .fourcc = V4L2_PIX_FMT_RGB565, |
9f26e659 MD |
162 | .interface_type = SYS18, |
163 | .clock_divider = 6, | |
164 | .flags = LCDC_FLAGS_DWPOL, | |
93ff2598 LP |
165 | .lcd_modes = kfr2r09_lcdc_modes, |
166 | .num_modes = ARRAY_SIZE(kfr2r09_lcdc_modes), | |
afaad83b | 167 | .panel_cfg = { |
9f26e659 MD |
168 | .width = 35, |
169 | .height = 58, | |
9f26e659 | 170 | .setup_sys = kfr2r09_lcd_setup, |
657bf0bd | 171 | .start_transfer = kfr2r09_lcd_start, |
d072c35e | 172 | }, |
9f26e659 MD |
173 | .sys_bus_cfg = { |
174 | .ldmt2r = 0x07010904, | |
175 | .ldmt3r = 0x14012914, | |
176 | /* set 1s delay to encourage fsync() */ | |
177 | .deferred_io_msec = 1000, | |
178 | }, | |
179 | } | |
180 | }; | |
181 | ||
182 | static struct resource kfr2r09_sh_lcdc_resources[] = { | |
183 | [0] = { | |
184 | .name = "LCDC", | |
185 | .start = 0xfe940000, /* P4-only space */ | |
a6f15ade | 186 | .end = 0xfe942fff, |
9f26e659 MD |
187 | .flags = IORESOURCE_MEM, |
188 | }, | |
189 | [1] = { | |
aa82f9fc | 190 | .start = evt2irq(0xf40), |
9f26e659 MD |
191 | .flags = IORESOURCE_IRQ, |
192 | }, | |
193 | }; | |
194 | ||
195 | static struct platform_device kfr2r09_sh_lcdc_device = { | |
196 | .name = "sh_mobile_lcdc_fb", | |
197 | .num_resources = ARRAY_SIZE(kfr2r09_sh_lcdc_resources), | |
198 | .resource = kfr2r09_sh_lcdc_resources, | |
199 | .dev = { | |
200 | .platform_data = &kfr2r09_sh_lcdc_info, | |
201 | }, | |
202 | }; | |
203 | ||
3f3bee2e LP |
204 | static struct lv5207lp_platform_data kfr2r09_backlight_data = { |
205 | .fbdev = &kfr2r09_sh_lcdc_device.dev, | |
206 | .def_value = 13, | |
207 | .max_value = 13, | |
208 | }; | |
209 | ||
210 | static struct i2c_board_info kfr2r09_backlight_board_info = { | |
211 | I2C_BOARD_INFO("lv5207lp", 0x75), | |
212 | .platform_data = &kfr2r09_backlight_data, | |
213 | }; | |
214 | ||
5a1c4cb5 MD |
215 | static struct r8a66597_platdata kfr2r09_usb0_gadget_data = { |
216 | .on_chip = 1, | |
217 | }; | |
218 | ||
219 | static struct resource kfr2r09_usb0_gadget_resources[] = { | |
220 | [0] = { | |
221 | .start = 0x04d80000, | |
222 | .end = 0x04d80123, | |
223 | .flags = IORESOURCE_MEM, | |
224 | }, | |
225 | [1] = { | |
bc404e91 GL |
226 | .start = evt2irq(0xa20), |
227 | .end = evt2irq(0xa20), | |
5a1c4cb5 MD |
228 | .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW, |
229 | }, | |
230 | }; | |
231 | ||
232 | static struct platform_device kfr2r09_usb0_gadget_device = { | |
233 | .name = "r8a66597_udc", | |
234 | .id = 0, | |
235 | .dev = { | |
236 | .dma_mask = NULL, /* not use dma */ | |
237 | .coherent_dma_mask = 0xffffffff, | |
238 | .platform_data = &kfr2r09_usb0_gadget_data, | |
239 | }, | |
240 | .num_resources = ARRAY_SIZE(kfr2r09_usb0_gadget_resources), | |
241 | .resource = kfr2r09_usb0_gadget_resources, | |
242 | }; | |
243 | ||
f3590dc3 JM |
244 | static struct ceu_platform_data ceu_pdata = { |
245 | .num_subdevs = 1, | |
246 | .subdevs = { | |
247 | { /* [0] = rj54n1cb0c */ | |
248 | .flags = 0, | |
249 | .bus_width = 8, | |
250 | .bus_shift = 0, | |
251 | .i2c_adapter_id = 1, | |
252 | .i2c_address = 0x50, | |
253 | }, | |
254 | }, | |
a469f627 GL |
255 | }; |
256 | ||
257 | static struct resource kfr2r09_ceu_resources[] = { | |
258 | [0] = { | |
259 | .name = "CEU", | |
260 | .start = 0xfe910000, | |
261 | .end = 0xfe91009f, | |
262 | .flags = IORESOURCE_MEM, | |
263 | }, | |
264 | [1] = { | |
aa82f9fc PM |
265 | .start = evt2irq(0x880), |
266 | .end = evt2irq(0x880), | |
a469f627 GL |
267 | .flags = IORESOURCE_IRQ, |
268 | }, | |
a469f627 GL |
269 | }; |
270 | ||
271 | static struct platform_device kfr2r09_ceu_device = { | |
f3590dc3 | 272 | .name = "renesas-ceu", |
a469f627 GL |
273 | .id = 0, /* "ceu0" clock */ |
274 | .num_resources = ARRAY_SIZE(kfr2r09_ceu_resources), | |
275 | .resource = kfr2r09_ceu_resources, | |
276 | .dev = { | |
f3590dc3 | 277 | .platform_data = &ceu_pdata, |
a469f627 | 278 | }, |
a469f627 GL |
279 | }; |
280 | ||
a6b5f200 GL |
281 | static struct rj54n1_pdata rj54n1_priv = { |
282 | .mclk_freq = CEU_MCLK_FREQ, | |
283 | .ioctl_high = false, | |
284 | }; | |
285 | ||
f3590dc3 JM |
286 | static struct i2c_board_info kfr2r09_i2c_camera = { |
287 | I2C_BOARD_INFO("rj54n1cb0c", 0x50), | |
288 | .platform_data = &rj54n1_priv, | |
a469f627 GL |
289 | }; |
290 | ||
f3590dc3 JM |
291 | static struct gpiod_lookup_table rj54n1_gpios = { |
292 | .dev_id = "1-0050", | |
293 | .table = { | |
294 | GPIO_LOOKUP("sh7724_pfc", GPIO_PTB4, "poweron", | |
295 | GPIO_ACTIVE_HIGH), | |
296 | GPIO_LOOKUP("sh7724_pfc", GPIO_PTB7, "enable", | |
297 | GPIO_ACTIVE_HIGH), | |
a469f627 GL |
298 | }, |
299 | }; | |
300 | ||
da5f2ddc GL |
301 | /* Fixed 3.3V regulator to be used by SDHI0 */ |
302 | static struct regulator_consumer_supply fixed3v3_power_consumers[] = | |
303 | { | |
304 | REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"), | |
305 | REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"), | |
306 | }; | |
307 | ||
d2a2fb97 MD |
308 | static struct resource kfr2r09_sh_sdhi0_resources[] = { |
309 | [0] = { | |
310 | .name = "SDHI0", | |
311 | .start = 0x04ce0000, | |
d80e9221 | 312 | .end = 0x04ce00ff, |
d2a2fb97 MD |
313 | .flags = IORESOURCE_MEM, |
314 | }, | |
315 | [1] = { | |
aa82f9fc | 316 | .start = evt2irq(0xe80), |
d2a2fb97 MD |
317 | .flags = IORESOURCE_IRQ, |
318 | }, | |
319 | }; | |
320 | ||
84f11d5b KM |
321 | static struct tmio_mmc_data sh7724_sdhi0_data = { |
322 | .chan_priv_tx = (void *)SHDMA_SLAVE_SDHI0_TX, | |
323 | .chan_priv_rx = (void *)SHDMA_SLAVE_SDHI0_RX, | |
84f11d5b | 324 | .capabilities = MMC_CAP_SDIO_IRQ, |
3ca1507b | 325 | .capabilities2 = MMC_CAP2_NO_WRITE_PROTECT, |
9e526bc7 GL |
326 | }; |
327 | ||
d2a2fb97 MD |
328 | static struct platform_device kfr2r09_sh_sdhi0_device = { |
329 | .name = "sh_mobile_sdhi", | |
330 | .num_resources = ARRAY_SIZE(kfr2r09_sh_sdhi0_resources), | |
331 | .resource = kfr2r09_sh_sdhi0_resources, | |
9e526bc7 GL |
332 | .dev = { |
333 | .platform_data = &sh7724_sdhi0_data, | |
334 | }, | |
d2a2fb97 MD |
335 | }; |
336 | ||
a366aa64 MD |
337 | static struct platform_device *kfr2r09_devices[] __initdata = { |
338 | &kfr2r09_nor_flash_device, | |
33893d7a | 339 | &kfr2r09_nand_flash_device, |
39a6bf14 | 340 | &kfr2r09_sh_keysc_device, |
9f26e659 | 341 | &kfr2r09_sh_lcdc_device, |
d2a2fb97 | 342 | &kfr2r09_sh_sdhi0_device, |
a366aa64 MD |
343 | }; |
344 | ||
345 | #define BSC_CS0BCR 0xfec10004 | |
346 | #define BSC_CS0WCR 0xfec10024 | |
33893d7a MD |
347 | #define BSC_CS4BCR 0xfec10010 |
348 | #define BSC_CS4WCR 0xfec10030 | |
5a1c4cb5 MD |
349 | #define PORT_MSELCRB 0xa4050182 |
350 | ||
045a4b7e | 351 | #ifdef CONFIG_I2C |
5a1c4cb5 MD |
352 | static int kfr2r09_usb0_gadget_i2c_setup(void) |
353 | { | |
354 | struct i2c_adapter *a; | |
355 | struct i2c_msg msg; | |
356 | unsigned char buf[2]; | |
357 | int ret; | |
358 | ||
359 | a = i2c_get_adapter(0); | |
360 | if (!a) | |
361 | return -ENODEV; | |
362 | ||
363 | /* set bit 1 (the second bit) of chip at 0x09, register 0x13 */ | |
364 | buf[0] = 0x13; | |
365 | msg.addr = 0x09; | |
366 | msg.buf = buf; | |
367 | msg.len = 1; | |
368 | msg.flags = 0; | |
369 | ret = i2c_transfer(a, &msg, 1); | |
370 | if (ret != 1) | |
371 | return -ENODEV; | |
372 | ||
373 | buf[0] = 0; | |
374 | msg.addr = 0x09; | |
375 | msg.buf = buf; | |
376 | msg.len = 1; | |
377 | msg.flags = I2C_M_RD; | |
378 | ret = i2c_transfer(a, &msg, 1); | |
379 | if (ret != 1) | |
380 | return -ENODEV; | |
381 | ||
382 | buf[1] = buf[0] | (1 << 1); | |
383 | buf[0] = 0x13; | |
384 | msg.addr = 0x09; | |
385 | msg.buf = buf; | |
386 | msg.len = 2; | |
387 | msg.flags = 0; | |
388 | ret = i2c_transfer(a, &msg, 1); | |
389 | if (ret != 1) | |
390 | return -ENODEV; | |
391 | ||
392 | return 0; | |
393 | } | |
e6d8460a MD |
394 | |
395 | static int kfr2r09_serial_i2c_setup(void) | |
396 | { | |
397 | struct i2c_adapter *a; | |
398 | struct i2c_msg msg; | |
399 | unsigned char buf[2]; | |
400 | int ret; | |
401 | ||
402 | a = i2c_get_adapter(0); | |
403 | if (!a) | |
404 | return -ENODEV; | |
405 | ||
406 | /* set bit 6 (the 7th bit) of chip at 0x09, register 0x13 */ | |
407 | buf[0] = 0x13; | |
408 | msg.addr = 0x09; | |
409 | msg.buf = buf; | |
410 | msg.len = 1; | |
411 | msg.flags = 0; | |
412 | ret = i2c_transfer(a, &msg, 1); | |
413 | if (ret != 1) | |
414 | return -ENODEV; | |
415 | ||
416 | buf[0] = 0; | |
417 | msg.addr = 0x09; | |
418 | msg.buf = buf; | |
419 | msg.len = 1; | |
420 | msg.flags = I2C_M_RD; | |
421 | ret = i2c_transfer(a, &msg, 1); | |
422 | if (ret != 1) | |
423 | return -ENODEV; | |
424 | ||
425 | buf[1] = buf[0] | (1 << 6); | |
426 | buf[0] = 0x13; | |
427 | msg.addr = 0x09; | |
428 | msg.buf = buf; | |
429 | msg.len = 2; | |
430 | msg.flags = 0; | |
431 | ret = i2c_transfer(a, &msg, 1); | |
432 | if (ret != 1) | |
433 | return -ENODEV; | |
434 | ||
435 | return 0; | |
436 | } | |
045a4b7e MD |
437 | #else |
438 | static int kfr2r09_usb0_gadget_i2c_setup(void) | |
439 | { | |
440 | return -ENODEV; | |
441 | } | |
e6d8460a MD |
442 | |
443 | static int kfr2r09_serial_i2c_setup(void) | |
444 | { | |
445 | return -ENODEV; | |
446 | } | |
045a4b7e | 447 | #endif |
5a1c4cb5 MD |
448 | |
449 | static int kfr2r09_usb0_gadget_setup(void) | |
450 | { | |
451 | int plugged_in; | |
452 | ||
453 | gpio_request(GPIO_PTN4, NULL); /* USB_DET */ | |
454 | gpio_direction_input(GPIO_PTN4); | |
455 | plugged_in = gpio_get_value(GPIO_PTN4); | |
456 | if (!plugged_in) | |
457 | return -ENODEV; /* no cable plugged in */ | |
458 | ||
459 | if (kfr2r09_usb0_gadget_i2c_setup() != 0) | |
460 | return -ENODEV; /* unable to configure using i2c */ | |
461 | ||
9d56dd3b | 462 | __raw_writew((__raw_readw(PORT_MSELCRB) & ~0xc000) | 0x8000, PORT_MSELCRB); |
5a1c4cb5 MD |
463 | gpio_request(GPIO_FN_PDSTATUS, NULL); /* R-standby disables USB clock */ |
464 | gpio_request(GPIO_PTV6, NULL); /* USBCLK_ON */ | |
465 | gpio_direction_output(GPIO_PTV6, 1); /* USBCLK_ON = H */ | |
466 | msleep(20); /* wait 20ms to let the clock settle */ | |
467 | clk_enable(clk_get(NULL, "usb0")); | |
9d56dd3b | 468 | __raw_writew(0x0600, 0xa40501d4); |
5a1c4cb5 MD |
469 | |
470 | return 0; | |
471 | } | |
a366aa64 | 472 | |
67e522d0 MD |
473 | extern char kfr2r09_sdram_enter_start; |
474 | extern char kfr2r09_sdram_enter_end; | |
475 | extern char kfr2r09_sdram_leave_start; | |
476 | extern char kfr2r09_sdram_leave_end; | |
477 | ||
e7d16514 MD |
478 | static int __init kfr2r09_devices_setup(void) |
479 | { | |
ffa6daa9 | 480 | struct clk *camera_clk; |
f3590dc3 | 481 | |
67e522d0 | 482 | /* register board specific self-refresh code */ |
58ee987e MD |
483 | sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF | |
484 | SUSP_SH_RSTANDBY, | |
67e522d0 MD |
485 | &kfr2r09_sdram_enter_start, |
486 | &kfr2r09_sdram_enter_end, | |
487 | &kfr2r09_sdram_leave_start, | |
488 | &kfr2r09_sdram_leave_end); | |
489 | ||
da5f2ddc GL |
490 | regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers, |
491 | ARRAY_SIZE(fixed3v3_power_consumers), 3300000); | |
492 | ||
e7d16514 MD |
493 | /* enable SCIF1 serial port for YC401 console support */ |
494 | gpio_request(GPIO_FN_SCIF1_RXD, NULL); | |
495 | gpio_request(GPIO_FN_SCIF1_TXD, NULL); | |
e6d8460a MD |
496 | kfr2r09_serial_i2c_setup(); /* ECONTMSK(bit6=L10ONEN) set 1 */ |
497 | gpio_request(GPIO_PTG3, NULL); /* HPON_ON */ | |
498 | gpio_direction_output(GPIO_PTG3, 1); /* HPON_ON = H */ | |
e7d16514 | 499 | |
a366aa64 | 500 | /* setup NOR flash at CS0 */ |
9d56dd3b PM |
501 | __raw_writel(0x36db0400, BSC_CS0BCR); |
502 | __raw_writel(0x00000500, BSC_CS0WCR); | |
a366aa64 | 503 | |
33893d7a | 504 | /* setup NAND flash at CS4 */ |
9d56dd3b PM |
505 | __raw_writel(0x36db0400, BSC_CS4BCR); |
506 | __raw_writel(0x00000500, BSC_CS4WCR); | |
33893d7a | 507 | |
39a6bf14 MD |
508 | /* setup KEYSC pins */ |
509 | gpio_request(GPIO_FN_KEYOUT0, NULL); | |
510 | gpio_request(GPIO_FN_KEYOUT1, NULL); | |
511 | gpio_request(GPIO_FN_KEYOUT2, NULL); | |
512 | gpio_request(GPIO_FN_KEYOUT3, NULL); | |
513 | gpio_request(GPIO_FN_KEYOUT4_IN6, NULL); | |
514 | gpio_request(GPIO_FN_KEYIN0, NULL); | |
515 | gpio_request(GPIO_FN_KEYIN1, NULL); | |
516 | gpio_request(GPIO_FN_KEYIN2, NULL); | |
517 | gpio_request(GPIO_FN_KEYIN3, NULL); | |
518 | gpio_request(GPIO_FN_KEYIN4, NULL); | |
519 | gpio_request(GPIO_FN_KEYOUT5_IN5, NULL); | |
520 | ||
9f26e659 MD |
521 | /* setup LCDC pins for SYS panel */ |
522 | gpio_request(GPIO_FN_LCDD17, NULL); | |
523 | gpio_request(GPIO_FN_LCDD16, NULL); | |
524 | gpio_request(GPIO_FN_LCDD15, NULL); | |
525 | gpio_request(GPIO_FN_LCDD14, NULL); | |
526 | gpio_request(GPIO_FN_LCDD13, NULL); | |
527 | gpio_request(GPIO_FN_LCDD12, NULL); | |
528 | gpio_request(GPIO_FN_LCDD11, NULL); | |
529 | gpio_request(GPIO_FN_LCDD10, NULL); | |
530 | gpio_request(GPIO_FN_LCDD9, NULL); | |
531 | gpio_request(GPIO_FN_LCDD8, NULL); | |
532 | gpio_request(GPIO_FN_LCDD7, NULL); | |
533 | gpio_request(GPIO_FN_LCDD6, NULL); | |
534 | gpio_request(GPIO_FN_LCDD5, NULL); | |
535 | gpio_request(GPIO_FN_LCDD4, NULL); | |
536 | gpio_request(GPIO_FN_LCDD3, NULL); | |
537 | gpio_request(GPIO_FN_LCDD2, NULL); | |
538 | gpio_request(GPIO_FN_LCDD1, NULL); | |
539 | gpio_request(GPIO_FN_LCDD0, NULL); | |
540 | gpio_request(GPIO_FN_LCDRS, NULL); /* LCD_RS */ | |
541 | gpio_request(GPIO_FN_LCDCS, NULL); /* LCD_CS/ */ | |
542 | gpio_request(GPIO_FN_LCDRD, NULL); /* LCD_RD/ */ | |
543 | gpio_request(GPIO_FN_LCDWR, NULL); /* LCD_WR/ */ | |
544 | gpio_request(GPIO_FN_LCDVSYN, NULL); /* LCD_VSYNC */ | |
545 | gpio_request(GPIO_PTE4, NULL); /* LCD_RST/ */ | |
546 | gpio_direction_output(GPIO_PTE4, 1); | |
547 | gpio_request(GPIO_PTF4, NULL); /* PROTECT/ */ | |
548 | gpio_direction_output(GPIO_PTF4, 1); | |
549 | gpio_request(GPIO_PTU0, NULL); /* LEDSTDBY/ */ | |
550 | gpio_direction_output(GPIO_PTU0, 1); | |
551 | ||
5a1c4cb5 MD |
552 | /* setup USB function */ |
553 | if (kfr2r09_usb0_gadget_setup() == 0) | |
554 | platform_device_register(&kfr2r09_usb0_gadget_device); | |
555 | ||
a469f627 GL |
556 | /* CEU */ |
557 | gpio_request(GPIO_FN_VIO_CKO, NULL); | |
558 | gpio_request(GPIO_FN_VIO0_CLK, NULL); | |
559 | gpio_request(GPIO_FN_VIO0_VD, NULL); | |
560 | gpio_request(GPIO_FN_VIO0_HD, NULL); | |
561 | gpio_request(GPIO_FN_VIO0_FLD, NULL); | |
562 | gpio_request(GPIO_FN_VIO0_D7, NULL); | |
563 | gpio_request(GPIO_FN_VIO0_D6, NULL); | |
564 | gpio_request(GPIO_FN_VIO0_D5, NULL); | |
565 | gpio_request(GPIO_FN_VIO0_D4, NULL); | |
566 | gpio_request(GPIO_FN_VIO0_D3, NULL); | |
567 | gpio_request(GPIO_FN_VIO0_D2, NULL); | |
568 | gpio_request(GPIO_FN_VIO0_D1, NULL); | |
569 | gpio_request(GPIO_FN_VIO0_D0, NULL); | |
570 | ||
d2a2fb97 MD |
571 | /* SDHI0 connected to yc304 */ |
572 | gpio_request(GPIO_FN_SDHI0CD, NULL); | |
d2a2fb97 MD |
573 | gpio_request(GPIO_FN_SDHI0D3, NULL); |
574 | gpio_request(GPIO_FN_SDHI0D2, NULL); | |
575 | gpio_request(GPIO_FN_SDHI0D1, NULL); | |
576 | gpio_request(GPIO_FN_SDHI0D0, NULL); | |
577 | gpio_request(GPIO_FN_SDHI0CMD, NULL); | |
578 | gpio_request(GPIO_FN_SDHI0CLK, NULL); | |
579 | ||
3f3bee2e LP |
580 | i2c_register_board_info(0, &kfr2r09_backlight_board_info, 1); |
581 | ||
f3590dc3 JM |
582 | /* Set camera clock frequency and register and alias for rj54n1. */ |
583 | camera_clk = clk_get(NULL, "video_clk"); | |
584 | if (!IS_ERR(camera_clk)) { | |
585 | clk_set_rate(camera_clk, | |
586 | clk_round_rate(camera_clk, CEU_MCLK_FREQ)); | |
587 | clk_put(camera_clk); | |
588 | } | |
589 | clk_add_alias(NULL, "1-0050", "video_clk", NULL); | |
590 | ||
591 | /* set DRVCRB | |
592 | * | |
593 | * use 1.8 V for VccQ_VIO | |
594 | * use 2.85V for VccQ_SR | |
595 | */ | |
596 | __raw_writew((__raw_readw(DRVCRB) & ~0x0003) | 0x0001, DRVCRB); | |
597 | ||
598 | gpiod_add_lookup_table(&rj54n1_gpios); | |
599 | ||
600 | i2c_register_board_info(1, &kfr2r09_i2c_camera, 1); | |
601 | ||
602 | /* Initialize CEU platform device separately to map memory first */ | |
603 | device_initialize(&kfr2r09_ceu_device.dev); | |
604 | arch_setup_pdev_archdata(&kfr2r09_ceu_device); | |
605 | dma_declare_coherent_memory(&kfr2r09_ceu_device.dev, | |
82c5de0a CH |
606 | ceu_dma_membase, ceu_dma_membase, |
607 | ceu_dma_membase + CEU_BUFFER_MEMORY_SIZE - 1); | |
f3590dc3 JM |
608 | |
609 | platform_device_add(&kfr2r09_ceu_device); | |
610 | ||
a366aa64 MD |
611 | return platform_add_devices(kfr2r09_devices, |
612 | ARRAY_SIZE(kfr2r09_devices)); | |
e7d16514 MD |
613 | } |
614 | device_initcall(kfr2r09_devices_setup); | |
615 | ||
616 | /* Return the board specific boot mode pin configuration */ | |
617 | static int kfr2r09_mode_pins(void) | |
618 | { | |
619 | /* MD0=1, MD1=1, MD2=0: Clock Mode 3 | |
620 | * MD3=0: 16-bit Area0 Bus Width | |
621 | * MD5=1: Little Endian | |
622 | * MD8=1: Test Mode Disabled | |
623 | */ | |
624 | return MODE_PIN0 | MODE_PIN1 | MODE_PIN5 | MODE_PIN8; | |
625 | } | |
626 | ||
f3590dc3 JM |
627 | /* Reserve a portion of memory for CEU buffers */ |
628 | static void __init kfr2r09_mv_mem_reserve(void) | |
629 | { | |
630 | phys_addr_t phys; | |
631 | phys_addr_t size = CEU_BUFFER_MEMORY_SIZE; | |
632 | ||
f240ec09 | 633 | phys = memblock_phys_alloc(size, PAGE_SIZE); |
ecc3e771 MR |
634 | if (!phys) |
635 | panic("Failed to allocate CEU memory\n"); | |
636 | ||
f3590dc3 JM |
637 | memblock_free(phys, size); |
638 | memblock_remove(phys, size); | |
639 | ||
640 | ceu_dma_membase = phys; | |
641 | } | |
642 | ||
e7d16514 MD |
643 | /* |
644 | * The Machine Vector | |
645 | */ | |
646 | static struct sh_machine_vector mv_kfr2r09 __initmv = { | |
647 | .mv_name = "kfr2r09", | |
648 | .mv_mode_pins = kfr2r09_mode_pins, | |
f3590dc3 | 649 | .mv_mem_reserve = kfr2r09_mv_mem_reserve, |
e7d16514 | 650 | }; |