| Srinidhi Kasagar | aa44ef4 | 2009-11-28 08:17:18 +0100 | [diff] [blame] | 1 | /* | 
|  | 2 | * Copyright (C) 2008-2009 ST-Ericsson | 
|  | 3 | * | 
|  | 4 | * Author: Srinidhi KASAGAR <srinidhi.kasagar@stericsson.com> | 
|  | 5 | * | 
|  | 6 | * This program is free software; you can redistribute it and/or modify | 
|  | 7 | * it under the terms of the GNU General Public License version 2, as | 
|  | 8 | * published by the Free Software Foundation. | 
|  | 9 | * | 
|  | 10 | */ | 
|  | 11 | #include <linux/kernel.h> | 
|  | 12 | #include <linux/init.h> | 
|  | 13 | #include <linux/interrupt.h> | 
|  | 14 | #include <linux/platform_device.h> | 
|  | 15 | #include <linux/io.h> | 
|  | 16 | #include <linux/amba/bus.h> | 
|  | 17 | #include <linux/amba/pl022.h> | 
|  | 18 | #include <linux/spi/spi.h> | 
|  | 19 |  | 
|  | 20 | #include <asm/localtimer.h> | 
|  | 21 | #include <asm/mach-types.h> | 
|  | 22 | #include <asm/mach/arch.h> | 
|  | 23 |  | 
|  | 24 | #include <plat/mtu.h> | 
| Srinidhi Kasagar | d48a41c | 2010-02-03 13:02:48 +0100 | [diff] [blame] | 25 | #include <plat/i2c.h> | 
| Srinidhi Kasagar | aa44ef4 | 2009-11-28 08:17:18 +0100 | [diff] [blame] | 26 |  | 
|  | 27 | #include <mach/hardware.h> | 
|  | 28 | #include <mach/setup.h> | 
|  | 29 |  | 
|  | 30 | #define __MEM_4K_RESOURCE(x) \ | 
|  | 31 | .res = {.start = (x), .end = (x) + SZ_4K - 1, .flags = IORESOURCE_MEM} | 
|  | 32 |  | 
|  | 33 | /* These are active devices on this board */ | 
|  | 34 | static struct amba_device uart0_device = { | 
|  | 35 | .dev = { .init_name = "uart0" }, | 
|  | 36 | __MEM_4K_RESOURCE(U8500_UART0_BASE), | 
|  | 37 | .irq = {IRQ_UART0, NO_IRQ}, | 
|  | 38 | }; | 
|  | 39 |  | 
|  | 40 | static struct amba_device uart1_device = { | 
|  | 41 | .dev = { .init_name = "uart1" }, | 
|  | 42 | __MEM_4K_RESOURCE(U8500_UART1_BASE), | 
|  | 43 | .irq = {IRQ_UART1, NO_IRQ}, | 
|  | 44 | }; | 
|  | 45 |  | 
|  | 46 | static struct amba_device uart2_device = { | 
|  | 47 | .dev = { .init_name = "uart2" }, | 
|  | 48 | __MEM_4K_RESOURCE(U8500_UART2_BASE), | 
|  | 49 | .irq = {IRQ_UART2, NO_IRQ}, | 
|  | 50 | }; | 
|  | 51 |  | 
|  | 52 | static void ab4500_spi_cs_control(u32 command) | 
|  | 53 | { | 
|  | 54 | /* set the FRM signal, which is CS  - TODO */ | 
|  | 55 | } | 
|  | 56 |  | 
|  | 57 | struct pl022_config_chip ab4500_chip_info = { | 
|  | 58 | .lbm = LOOPBACK_DISABLED, | 
|  | 59 | .com_mode = INTERRUPT_TRANSFER, | 
|  | 60 | .iface = SSP_INTERFACE_MOTOROLA_SPI, | 
|  | 61 | /* we can act as master only */ | 
|  | 62 | .hierarchy = SSP_MASTER, | 
|  | 63 | .slave_tx_disable = 0, | 
|  | 64 | .endian_rx = SSP_RX_MSB, | 
|  | 65 | .endian_tx = SSP_TX_MSB, | 
|  | 66 | .data_size = SSP_DATA_BITS_24, | 
|  | 67 | .rx_lev_trig = SSP_RX_1_OR_MORE_ELEM, | 
|  | 68 | .tx_lev_trig = SSP_TX_1_OR_MORE_EMPTY_LOC, | 
|  | 69 | .clk_phase = SSP_CLK_SECOND_EDGE, | 
|  | 70 | .clk_pol = SSP_CLK_POL_IDLE_HIGH, | 
|  | 71 | .cs_control = ab4500_spi_cs_control, | 
|  | 72 | }; | 
|  | 73 |  | 
|  | 74 | static struct spi_board_info u8500_spi_devices[] = { | 
|  | 75 | { | 
|  | 76 | .modalias = "ab4500", | 
|  | 77 | .controller_data = &ab4500_chip_info, | 
|  | 78 | .max_speed_hz = 12000000, | 
|  | 79 | .bus_num = 0, | 
|  | 80 | .chip_select = 0, | 
|  | 81 | .mode = SPI_MODE_0, | 
|  | 82 | .irq = IRQ_AB4500, | 
|  | 83 | }, | 
|  | 84 | }; | 
|  | 85 |  | 
|  | 86 | static struct pl022_ssp_controller ssp0_platform_data = { | 
|  | 87 | .bus_id = 0, | 
|  | 88 | /* pl022 not yet supports dma */ | 
|  | 89 | .enable_dma = 0, | 
|  | 90 | /* on this platform, gpio 31,142,144,214 & | 
|  | 91 | * 224 are connected as chip selects | 
|  | 92 | */ | 
|  | 93 | .num_chipselect = 5, | 
|  | 94 | }; | 
|  | 95 |  | 
|  | 96 | static struct amba_device pl022_device = { | 
|  | 97 | .dev = { | 
|  | 98 | .coherent_dma_mask = ~0, | 
|  | 99 | .init_name = "pl022", | 
|  | 100 | .platform_data = &ssp0_platform_data, | 
|  | 101 | }, | 
|  | 102 | .res = { | 
|  | 103 | .start = U8500_SSP0_BASE, | 
|  | 104 | .end   = U8500_SSP0_BASE + SZ_4K - 1, | 
|  | 105 | .flags = IORESOURCE_MEM, | 
|  | 106 | }, | 
|  | 107 | .irq = {IRQ_SSP0, NO_IRQ }, | 
|  | 108 | /* ST-Ericsson modified id */ | 
|  | 109 | .periphid = SSP_PER_ID, | 
|  | 110 | }; | 
|  | 111 |  | 
| Linus Walleij | 8e58ed3 | 2010-02-04 12:50:58 +0100 | [diff] [blame] | 112 | static struct amba_device pl031_device = { | 
|  | 113 | .dev = { | 
|  | 114 | .init_name = "pl031", | 
|  | 115 | }, | 
|  | 116 | .res = { | 
|  | 117 | .start = U8500_RTC_BASE, | 
|  | 118 | .end = U8500_RTC_BASE + SZ_4K - 1, | 
|  | 119 | .flags = IORESOURCE_MEM, | 
|  | 120 | }, | 
|  | 121 | .irq = {IRQ_RTC_RTT, NO_IRQ}, | 
|  | 122 | }; | 
|  | 123 |  | 
| Srinidhi Kasagar | d48a41c | 2010-02-03 13:02:48 +0100 | [diff] [blame] | 124 | #define U8500_I2C_RESOURCES(id, size)		\ | 
|  | 125 | static struct resource u8500_i2c_resources_##id[] = {	\ | 
|  | 126 | [0] = {					\ | 
|  | 127 | .start	= U8500_I2C##id##_BASE,	\ | 
|  | 128 | .end	= U8500_I2C##id##_BASE + size - 1, \ | 
|  | 129 | .flags	= IORESOURCE_MEM,	\ | 
|  | 130 | },					\ | 
|  | 131 | [1] = {					\ | 
|  | 132 | .start	= IRQ_I2C##id,		\ | 
|  | 133 | .end	= IRQ_I2C##id,		\ | 
|  | 134 | .flags	= IORESOURCE_IRQ	\ | 
|  | 135 | }					\ | 
|  | 136 | } | 
|  | 137 |  | 
|  | 138 | U8500_I2C_RESOURCES(0, SZ_4K); | 
|  | 139 | U8500_I2C_RESOURCES(1, SZ_4K); | 
|  | 140 | U8500_I2C_RESOURCES(2, SZ_4K); | 
|  | 141 | U8500_I2C_RESOURCES(3, SZ_4K); | 
|  | 142 |  | 
|  | 143 | #define U8500_I2C_CONTROLLER(id, _slsu, _tft, _rft, clk, _sm) \ | 
|  | 144 | static struct nmk_i2c_controller u8500_i2c_##id = { \ | 
|  | 145 | /*				\ | 
|  | 146 | * slave data setup time, which is	\ | 
|  | 147 | * 250 ns,100ns,10ns which is 14,6,2	\ | 
|  | 148 | * respectively for a 48 Mhz	\ | 
|  | 149 | * i2c clock			\ | 
|  | 150 | */				\ | 
|  | 151 | .slsu		= _slsu,	\ | 
|  | 152 | /* Tx FIFO threshold */		\ | 
|  | 153 | .tft		= _tft,		\ | 
|  | 154 | /* Rx FIFO threshold */		\ | 
|  | 155 | .rft		= _rft,		\ | 
|  | 156 | /* std. mode operation */	\ | 
|  | 157 | .clk_freq	= clk,		\ | 
|  | 158 | .sm		= _sm,		\ | 
|  | 159 | } | 
|  | 160 |  | 
|  | 161 | /* | 
|  | 162 | * The board uses 4 i2c controllers, initialize all of | 
|  | 163 | * them with slave data setup time of 250 ns, | 
|  | 164 | * Tx & Rx FIFO threshold values as 1 and standard | 
|  | 165 | * mode of operation | 
|  | 166 | */ | 
|  | 167 | U8500_I2C_CONTROLLER(0, 0xe, 1, 1, 100000, I2C_FREQ_MODE_STANDARD); | 
|  | 168 | U8500_I2C_CONTROLLER(1, 0xe, 1, 1, 100000, I2C_FREQ_MODE_STANDARD); | 
|  | 169 | U8500_I2C_CONTROLLER(2,	0xe, 1, 1, 100000, I2C_FREQ_MODE_STANDARD); | 
|  | 170 | U8500_I2C_CONTROLLER(3,	0xe, 1, 1, 100000, I2C_FREQ_MODE_STANDARD); | 
|  | 171 |  | 
|  | 172 | #define U8500_I2C_PDEVICE(cid)		\ | 
|  | 173 | static struct platform_device i2c_controller##cid = { \ | 
|  | 174 | .name = "nmk-i2c",		\ | 
|  | 175 | .id	 = cid,			\ | 
|  | 176 | .num_resources = 2,		\ | 
|  | 177 | .resource = u8500_i2c_resources_##cid,	\ | 
|  | 178 | .dev = {			\ | 
|  | 179 | .platform_data = &u8500_i2c_##cid \ | 
|  | 180 | }				\ | 
|  | 181 | } | 
|  | 182 |  | 
|  | 183 | U8500_I2C_PDEVICE(0); | 
|  | 184 | U8500_I2C_PDEVICE(1); | 
|  | 185 | U8500_I2C_PDEVICE(2); | 
|  | 186 | U8500_I2C_PDEVICE(3); | 
|  | 187 |  | 
| Srinidhi Kasagar | aa44ef4 | 2009-11-28 08:17:18 +0100 | [diff] [blame] | 188 | static struct amba_device *amba_devs[] __initdata = { | 
|  | 189 | &uart0_device, | 
|  | 190 | &uart1_device, | 
|  | 191 | &uart2_device, | 
|  | 192 | &pl022_device, | 
| Linus Walleij | 8e58ed3 | 2010-02-04 12:50:58 +0100 | [diff] [blame] | 193 | &pl031_device, | 
| Srinidhi Kasagar | aa44ef4 | 2009-11-28 08:17:18 +0100 | [diff] [blame] | 194 | }; | 
|  | 195 |  | 
| Srinidhi Kasagar | d48a41c | 2010-02-03 13:02:48 +0100 | [diff] [blame] | 196 | /* add any platform devices here - TODO */ | 
|  | 197 | static struct platform_device *platform_devs[] __initdata = { | 
|  | 198 | &i2c_controller0, | 
|  | 199 | &i2c_controller1, | 
|  | 200 | &i2c_controller2, | 
|  | 201 | &i2c_controller3, | 
|  | 202 | }; | 
|  | 203 |  | 
| Srinidhi Kasagar | aa44ef4 | 2009-11-28 08:17:18 +0100 | [diff] [blame] | 204 | static void __init u8500_timer_init(void) | 
|  | 205 | { | 
|  | 206 | #ifdef CONFIG_LOCAL_TIMERS | 
|  | 207 | /* Setup the local timer base */ | 
|  | 208 | twd_base = __io_address(U8500_TWD_BASE); | 
|  | 209 | #endif | 
|  | 210 | /* Setup the MTU base */ | 
|  | 211 | mtu_base = __io_address(U8500_MTU0_BASE); | 
|  | 212 |  | 
|  | 213 | nmdk_timer_init(); | 
|  | 214 | } | 
|  | 215 |  | 
|  | 216 | static struct sys_timer u8500_timer = { | 
|  | 217 | .init	= u8500_timer_init, | 
|  | 218 | }; | 
|  | 219 |  | 
|  | 220 | static void __init u8500_init_machine(void) | 
|  | 221 | { | 
|  | 222 | int i; | 
|  | 223 |  | 
|  | 224 | /* Register the active AMBA devices on this board */ | 
|  | 225 | for (i = 0; i < ARRAY_SIZE(amba_devs); i++) | 
|  | 226 | amba_device_register(amba_devs[i], &iomem_resource); | 
|  | 227 |  | 
| Srinidhi Kasagar | d48a41c | 2010-02-03 13:02:48 +0100 | [diff] [blame] | 228 | platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); | 
|  | 229 |  | 
| Srinidhi Kasagar | aa44ef4 | 2009-11-28 08:17:18 +0100 | [diff] [blame] | 230 | spi_register_board_info(u8500_spi_devices, | 
|  | 231 | ARRAY_SIZE(u8500_spi_devices)); | 
|  | 232 |  | 
|  | 233 | u8500_init_devices(); | 
|  | 234 | } | 
|  | 235 |  | 
|  | 236 | MACHINE_START(U8500, "ST-Ericsson MOP500 platform") | 
|  | 237 | /* Maintainer: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com> */ | 
|  | 238 | .phys_io	= U8500_UART2_BASE, | 
|  | 239 | .io_pg_offst	= (IO_ADDRESS(U8500_UART2_BASE) >> 18) & 0xfffc, | 
|  | 240 | .boot_params	= 0x100, | 
|  | 241 | .map_io		= u8500_map_io, | 
|  | 242 | .init_irq	= u8500_init_irq, | 
|  | 243 | /* we re-use nomadik timer here */ | 
|  | 244 | .timer		= &u8500_timer, | 
|  | 245 | .init_machine	= u8500_init_machine, | 
|  | 246 | MACHINE_END |