1/*
2 * G4EVM board support
3 *
4 * Copyright (C) 2010  Magnus Damm
5 * Copyright (C) 2008  Yoshihiro Shimoda
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19 */
20#include <linux/kernel.h>
21#include <linux/init.h>
22#include <linux/interrupt.h>
23#include <linux/irq.h>
24#include <linux/platform_device.h>
25#include <linux/delay.h>
26#include <linux/mtd/mtd.h>
27#include <linux/mtd/partitions.h>
28#include <linux/mtd/physmap.h>
29#include <linux/usb/r8a66597.h>
30#include <linux/io.h>
31#include <linux/input.h>
32#include <linux/input/sh_keysc.h>
33#include <linux/mmc/host.h>
34#include <linux/mmc/sh_mobile_sdhi.h>
35#include <linux/gpio.h>
36#include <linux/dma-mapping.h>
37#include <mach/irqs.h>
38#include <mach/sh7377.h>
39#include <mach/common.h>
40#include <asm/mach-types.h>
41#include <asm/mach/arch.h>
42
43/*
44 * SDHI
45 *
46 * SDHI0 : card detection is possible
47 * SDHI1 : card detection is impossible
48 *
49 * [G4-MAIN-BOARD]
50 * JP74 : short		# DBG_2V8A    for SDHI0
51 * JP75 : NC		# DBG_3V3A    for SDHI0
52 * JP76 : NC		# DBG_3V3A_SD for SDHI0
53 * JP77 : NC		# 3V3A_SDIO   for SDHI1
54 * JP78 : short		# DBG_2V8A    for SDHI1
55 * JP79 : NC		# DBG_3V3A    for SDHI1
56 * JP80 : NC		# DBG_3V3A_SD for SDHI1
57 *
58 * [G4-CORE-BOARD]
59 * S32 : all off	# to dissever from G3-CORE_DBG board
60 * S33 : all off	# to dissever from G3-CORE_DBG board
61 *
62 * [G3-CORE_DBG-BOARD]
63 * S1  : all off	# to dissever from G3-CORE_DBG board
64 * S3  : all off	# to dissever from G3-CORE_DBG board
65 * S4  : all off	# to dissever from G3-CORE_DBG board
66 */
67
68static struct mtd_partition nor_flash_partitions[] = {
69	{
70		.name		= "loader",
71		.offset		= 0x00000000,
72		.size		= 512 * 1024,
73	},
74	{
75		.name		= "bootenv",
76		.offset		= MTDPART_OFS_APPEND,
77		.size		= 512 * 1024,
78	},
79	{
80		.name		= "kernel_ro",
81		.offset		= MTDPART_OFS_APPEND,
82		.size		= 8 * 1024 * 1024,
83		.mask_flags	= MTD_WRITEABLE,
84	},
85	{
86		.name		= "kernel",
87		.offset		= MTDPART_OFS_APPEND,
88		.size		= 8 * 1024 * 1024,
89	},
90	{
91		.name		= "data",
92		.offset		= MTDPART_OFS_APPEND,
93		.size		= MTDPART_SIZ_FULL,
94	},
95};
96
97static struct physmap_flash_data nor_flash_data = {
98	.width		= 2,
99	.parts		= nor_flash_partitions,
100	.nr_parts	= ARRAY_SIZE(nor_flash_partitions),
101};
102
103static struct resource nor_flash_resources[] = {
104	[0]	= {
105		.start	= 0x00000000,
106		.end	= 0x08000000 - 1,
107		.flags	= IORESOURCE_MEM,
108	}
109};
110
111static struct platform_device nor_flash_device = {
112	.name		= "physmap-flash",
113	.dev		= {
114		.platform_data	= &nor_flash_data,
115	},
116	.num_resources	= ARRAY_SIZE(nor_flash_resources),
117	.resource	= nor_flash_resources,
118};
119
120/* USBHS */
121static void usb_host_port_power(int port, int power)
122{
123	if (!power) /* only power-on supported for now */
124		return;
125
126	/* set VBOUT/PWEN and EXTLP0 in DVSTCTR */
127	__raw_writew(__raw_readw(0xe6890008) | 0x600, 0xe6890008);
128}
129
130static struct r8a66597_platdata usb_host_data = {
131	.on_chip = 1,
132	.port_power = usb_host_port_power,
133};
134
135static struct resource usb_host_resources[] = {
136	[0] = {
137		.name	= "USBHS",
138		.start	= 0xe6890000,
139		.end	= 0xe68900e5,
140		.flags	= IORESOURCE_MEM,
141	},
142	[1] = {
143		.start	= evt2irq(0x0a20), /* USBHS_USHI0 */
144		.flags	= IORESOURCE_IRQ,
145	},
146};
147
148static struct platform_device usb_host_device = {
149	.name		= "r8a66597_hcd",
150	.id		= 0,
151	.dev = {
152		.platform_data		= &usb_host_data,
153		.dma_mask		= NULL,
154		.coherent_dma_mask	= 0xffffffff,
155	},
156	.num_resources	= ARRAY_SIZE(usb_host_resources),
157	.resource	= usb_host_resources,
158};
159
160/* KEYSC */
161static struct sh_keysc_info keysc_info = {
162	.mode		= SH_KEYSC_MODE_5,
163	.scan_timing	= 3,
164	.delay		= 100,
165	.keycodes = {
166		KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F,
167		KEY_G, KEY_H, KEY_I, KEY_J, KEY_K, KEY_L,
168		KEY_M, KEY_N, KEY_U, KEY_P, KEY_Q, KEY_R,
169		KEY_S, KEY_T, KEY_U, KEY_V, KEY_W, KEY_X,
170		KEY_Y, KEY_Z, KEY_HOME, KEY_SLEEP, KEY_WAKEUP, KEY_COFFEE,
171		KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5,
172		KEY_6, KEY_7, KEY_8, KEY_9, KEY_STOP, KEY_COMPUTER,
173	},
174};
175
176static struct resource keysc_resources[] = {
177	[0] = {
178		.name	= "KEYSC",
179		.start  = 0xe61b0000,
180		.end    = 0xe61b000f,
181		.flags  = IORESOURCE_MEM,
182	},
183	[1] = {
184		.start  = evt2irq(0x0be0), /* KEYSC_KEY */
185		.flags  = IORESOURCE_IRQ,
186	},
187};
188
189static struct platform_device keysc_device = {
190	.name           = "sh_keysc",
191	.id             = 0, /* keysc0 clock */
192	.num_resources  = ARRAY_SIZE(keysc_resources),
193	.resource       = keysc_resources,
194	.dev	= {
195		.platform_data	= &keysc_info,
196	},
197};
198
199/* SDHI */
200static struct sh_mobile_sdhi_info sdhi0_info = {
201	.tmio_caps	= MMC_CAP_SDIO_IRQ,
202};
203
204static struct resource sdhi0_resources[] = {
205	[0] = {
206		.name	= "SDHI0",
207		.start  = 0xe6d50000,
208		.end    = 0xe6d500ff,
209		.flags  = IORESOURCE_MEM,
210	},
211	[1] = {
212		.start  = evt2irq(0x0e00), /* SDHI0 */
213		.flags  = IORESOURCE_IRQ,
214	},
215};
216
217static struct platform_device sdhi0_device = {
218	.name           = "sh_mobile_sdhi",
219	.num_resources  = ARRAY_SIZE(sdhi0_resources),
220	.resource       = sdhi0_resources,
221	.id             = 0,
222	.dev	= {
223		.platform_data	= &sdhi0_info,
224	},
225};
226
227static struct sh_mobile_sdhi_info sdhi1_info = {
228	.tmio_caps	= MMC_CAP_NONREMOVABLE | MMC_CAP_SDIO_IRQ,
229};
230
231static struct resource sdhi1_resources[] = {
232	[0] = {
233		.name	= "SDHI1",
234		.start  = 0xe6d60000,
235		.end    = 0xe6d600ff,
236		.flags  = IORESOURCE_MEM,
237	},
238	[1] = {
239		.start  = evt2irq(0x0e80), /* SDHI1 */
240		.flags  = IORESOURCE_IRQ,
241	},
242};
243
244static struct platform_device sdhi1_device = {
245	.name           = "sh_mobile_sdhi",
246	.num_resources  = ARRAY_SIZE(sdhi1_resources),
247	.resource       = sdhi1_resources,
248	.id             = 1,
249	.dev	= {
250		.platform_data	= &sdhi1_info,
251	},
252};
253
254static struct platform_device *g4evm_devices[] __initdata = {
255	&nor_flash_device,
256	&usb_host_device,
257	&keysc_device,
258	&sdhi0_device,
259	&sdhi1_device,
260};
261
262#define GPIO_SDHID0_D0	0xe60520fc
263#define GPIO_SDHID0_D1	0xe60520fd
264#define GPIO_SDHID0_D2	0xe60520fe
265#define GPIO_SDHID0_D3	0xe60520ff
266#define GPIO_SDHICMD0	0xe6052100
267
268#define GPIO_SDHID1_D0	0xe6052103
269#define GPIO_SDHID1_D1	0xe6052104
270#define GPIO_SDHID1_D2	0xe6052105
271#define GPIO_SDHID1_D3	0xe6052106
272#define GPIO_SDHICMD1	0xe6052107
273
274/*
275 * FIXME !!
276 *
277 * gpio_pull_up is quick_hack.
278 *
279 * current gpio frame work doesn't have
280 * the method to control only pull up/down/free.
281 * this function should be replaced by correct gpio function
282 */
283static void __init gpio_pull_up(u32 addr)
284{
285	u8 data = __raw_readb(addr);
286
287	data &= 0x0F;
288	data |= 0xC0;
289	__raw_writeb(data, addr);
290}
291
292static void __init g4evm_init(void)
293{
294	sh7377_pinmux_init();
295
296	/* Lit DS14 LED */
297	gpio_request(GPIO_PORT109, NULL);
298	gpio_direction_output(GPIO_PORT109, 1);
299	gpio_export(GPIO_PORT109, 1);
300
301	/* Lit DS15 LED */
302	gpio_request(GPIO_PORT110, NULL);
303	gpio_direction_output(GPIO_PORT110, 1);
304	gpio_export(GPIO_PORT110, 1);
305
306	/* Lit DS16 LED */
307	gpio_request(GPIO_PORT112, NULL);
308	gpio_direction_output(GPIO_PORT112, 1);
309	gpio_export(GPIO_PORT112, 1);
310
311	/* Lit DS17 LED */
312	gpio_request(GPIO_PORT113, NULL);
313	gpio_direction_output(GPIO_PORT113, 1);
314	gpio_export(GPIO_PORT113, 1);
315
316	/* USBHS */
317	gpio_request(GPIO_FN_VBUS_0, NULL);
318	gpio_request(GPIO_FN_PWEN, NULL);
319	gpio_request(GPIO_FN_OVCN, NULL);
320	gpio_request(GPIO_FN_OVCN2, NULL);
321	gpio_request(GPIO_FN_EXTLP, NULL);
322	gpio_request(GPIO_FN_IDIN, NULL);
323
324	/* setup USB phy */
325	__raw_writew(0x0200, 0xe605810a);       /* USBCR1 */
326	__raw_writew(0x00e0, 0xe60581c0);       /* CPFCH */
327	__raw_writew(0x6010, 0xe60581c6);       /* CGPOSR */
328	__raw_writew(0x8a0a, 0xe605810c);       /* USBCR2 */
329
330	/* KEYSC @ CN31 */
331	gpio_request(GPIO_FN_PORT60_KEYOUT5, NULL);
332	gpio_request(GPIO_FN_PORT61_KEYOUT4, NULL);
333	gpio_request(GPIO_FN_PORT62_KEYOUT3, NULL);
334	gpio_request(GPIO_FN_PORT63_KEYOUT2, NULL);
335	gpio_request(GPIO_FN_PORT64_KEYOUT1, NULL);
336	gpio_request(GPIO_FN_PORT65_KEYOUT0, NULL);
337	gpio_request(GPIO_FN_PORT66_KEYIN0_PU, NULL);
338	gpio_request(GPIO_FN_PORT67_KEYIN1_PU, NULL);
339	gpio_request(GPIO_FN_PORT68_KEYIN2_PU, NULL);
340	gpio_request(GPIO_FN_PORT69_KEYIN3_PU, NULL);
341	gpio_request(GPIO_FN_PORT70_KEYIN4_PU, NULL);
342	gpio_request(GPIO_FN_PORT71_KEYIN5_PU, NULL);
343	gpio_request(GPIO_FN_PORT72_KEYIN6_PU, NULL);
344
345	/* SDHI0 */
346	gpio_request(GPIO_FN_SDHICLK0, NULL);
347	gpio_request(GPIO_FN_SDHICD0, NULL);
348	gpio_request(GPIO_FN_SDHID0_0, NULL);
349	gpio_request(GPIO_FN_SDHID0_1, NULL);
350	gpio_request(GPIO_FN_SDHID0_2, NULL);
351	gpio_request(GPIO_FN_SDHID0_3, NULL);
352	gpio_request(GPIO_FN_SDHICMD0, NULL);
353	gpio_request(GPIO_FN_SDHIWP0, NULL);
354	gpio_pull_up(GPIO_SDHID0_D0);
355	gpio_pull_up(GPIO_SDHID0_D1);
356	gpio_pull_up(GPIO_SDHID0_D2);
357	gpio_pull_up(GPIO_SDHID0_D3);
358	gpio_pull_up(GPIO_SDHICMD0);
359
360	/* SDHI1 */
361	gpio_request(GPIO_FN_SDHICLK1, NULL);
362	gpio_request(GPIO_FN_SDHID1_0, NULL);
363	gpio_request(GPIO_FN_SDHID1_1, NULL);
364	gpio_request(GPIO_FN_SDHID1_2, NULL);
365	gpio_request(GPIO_FN_SDHID1_3, NULL);
366	gpio_request(GPIO_FN_SDHICMD1, NULL);
367	gpio_pull_up(GPIO_SDHID1_D0);
368	gpio_pull_up(GPIO_SDHID1_D1);
369	gpio_pull_up(GPIO_SDHID1_D2);
370	gpio_pull_up(GPIO_SDHID1_D3);
371	gpio_pull_up(GPIO_SDHICMD1);
372
373	sh7377_add_standard_devices();
374
375	platform_add_devices(g4evm_devices, ARRAY_SIZE(g4evm_devices));
376}
377
378MACHINE_START(G4EVM, "g4evm")
379	.map_io		= sh7377_map_io,
380	.init_early	= sh7377_add_early_devices,
381	.init_irq	= sh7377_init_irq,
382	.handle_irq	= shmobile_handle_irq_intc,
383	.init_machine	= g4evm_init,
384	.timer		= &shmobile_timer,
385MACHINE_END
386