1/* 2 * Versatile Express V2M Motherboard Support 3 */ 4#include <linux/device.h> 5#include <linux/amba/bus.h> 6#include <linux/amba/mmci.h> 7#include <linux/io.h> 8#include <linux/init.h> 9#include <linux/platform_device.h> 10#include <linux/smsc911x.h> 11#include <linux/spinlock.h> 12#include <linux/sysdev.h> 13#include <linux/usb/isp1760.h> 14 15#include <asm/clkdev.h> 16#include <asm/sizes.h> 17#include <asm/mach/flash.h> 18#include <asm/mach/map.h> 19#include <asm/mach/time.h> 20#include <asm/hardware/arm_timer.h> 21 22#include <mach/clkdev.h> 23#include <mach/motherboard.h> 24 25#include <plat/timer-sp.h> 26 27#include "core.h" 28 29#define V2M_PA_CS0 0x40000000 30#define V2M_PA_CS1 0x44000000 31#define V2M_PA_CS2 0x48000000 32#define V2M_PA_CS3 0x4c000000 33#define V2M_PA_CS7 0x10000000 34 35static struct map_desc v2m_io_desc[] __initdata = { 36 { 37 .virtual = __MMIO_P2V(V2M_PA_CS7), 38 .pfn = __phys_to_pfn(V2M_PA_CS7), 39 .length = SZ_128K, 40 .type = MT_DEVICE, 41 }, 42}; 43 44void __init v2m_map_io(struct map_desc *tile, size_t num) 45{ 46 iotable_init(v2m_io_desc, ARRAY_SIZE(v2m_io_desc)); 47 iotable_init(tile, num); 48} 49 50 51static void __init v2m_timer_init(void) 52{ 53 writel(0, MMIO_P2V(V2M_TIMER0) + TIMER_CTRL); 54 writel(0, MMIO_P2V(V2M_TIMER1) + TIMER_CTRL); 55 56 sp804_clocksource_init(MMIO_P2V(V2M_TIMER1)); 57 sp804_clockevents_init(MMIO_P2V(V2M_TIMER0), IRQ_V2M_TIMER0); 58} 59 60struct sys_timer v2m_timer = { 61 .init = v2m_timer_init, 62}; 63 64 65static DEFINE_SPINLOCK(v2m_cfg_lock); 66 67int v2m_cfg_write(u32 devfn, u32 data) 68{ 69 /* Configuration interface broken? */ 70 u32 val; 71 72 printk("%s: writing %08x to %08x\n", __func__, data, devfn); 73 74 devfn |= SYS_CFG_START | SYS_CFG_WRITE; 75 76 spin_lock(&v2m_cfg_lock); 77 val = readl(MMIO_P2V(V2M_SYS_CFGSTAT)); 78 writel(val & ~SYS_CFG_COMPLETE, MMIO_P2V(V2M_SYS_CFGSTAT)); 79 80 writel(data, MMIO_P2V(V2M_SYS_CFGDATA)); 81 writel(devfn, MMIO_P2V(V2M_SYS_CFGCTRL)); 82 83 do { 84 val = readl(MMIO_P2V(V2M_SYS_CFGSTAT)); 85 } while (val == 0); 86 spin_unlock(&v2m_cfg_lock); 87 88 return !!(val & SYS_CFG_ERR); 89} 90 91int v2m_cfg_read(u32 devfn, u32 *data) 92{ 93 u32 val; 94 95 devfn |= SYS_CFG_START; 96 97 spin_lock(&v2m_cfg_lock); 98 writel(0, MMIO_P2V(V2M_SYS_CFGSTAT)); 99 writel(devfn, MMIO_P2V(V2M_SYS_CFGCTRL)); 100 101 mb(); 102 103 do { 104 cpu_relax(); 105 val = readl(MMIO_P2V(V2M_SYS_CFGSTAT)); 106 } while (val == 0); 107 108 *data = readl(MMIO_P2V(V2M_SYS_CFGDATA)); 109 spin_unlock(&v2m_cfg_lock); 110 111 return !!(val & SYS_CFG_ERR); 112} 113 114 115static struct resource v2m_pcie_i2c_resource = { 116 .start = V2M_SERIAL_BUS_PCI, 117 .end = V2M_SERIAL_BUS_PCI + SZ_4K - 1, 118 .flags = IORESOURCE_MEM, 119}; 120 121static struct platform_device v2m_pcie_i2c_device = { 122 .name = "versatile-i2c", 123 .id = 0, 124 .num_resources = 1, 125 .resource = &v2m_pcie_i2c_resource, 126}; 127 128static struct resource v2m_ddc_i2c_resource = { 129 .start = V2M_SERIAL_BUS_DVI, 130 .end = V2M_SERIAL_BUS_DVI + SZ_4K - 1, 131 .flags = IORESOURCE_MEM, 132}; 133 134static struct platform_device v2m_ddc_i2c_device = { 135 .name = "versatile-i2c", 136 .id = 1, 137 .num_resources = 1, 138 .resource = &v2m_ddc_i2c_resource, 139}; 140 141static struct resource v2m_eth_resources[] = { 142 { 143 .start = V2M_LAN9118, 144 .end = V2M_LAN9118 + SZ_64K - 1, 145 .flags = IORESOURCE_MEM, 146 }, { 147 .start = IRQ_V2M_LAN9118, 148 .end = IRQ_V2M_LAN9118, 149 .flags = IORESOURCE_IRQ, 150 }, 151}; 152 153static struct smsc911x_platform_config v2m_eth_config = { 154 .flags = SMSC911X_USE_32BIT, 155 .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH, 156 .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL, 157 .phy_interface = PHY_INTERFACE_MODE_MII, 158}; 159 160static struct platform_device v2m_eth_device = { 161 .name = "smsc911x", 162 .id = -1, 163 .resource = v2m_eth_resources, 164 .num_resources = ARRAY_SIZE(v2m_eth_resources), 165 .dev.platform_data = &v2m_eth_config, 166}; 167 168static struct resource v2m_usb_resources[] = { 169 { 170 .start = V2M_ISP1761, 171 .end = V2M_ISP1761 + SZ_128K - 1, 172 .flags = IORESOURCE_MEM, 173 }, { 174 .start = IRQ_V2M_ISP1761, 175 .end = IRQ_V2M_ISP1761, 176 .flags = IORESOURCE_IRQ, 177 }, 178}; 179 180static struct isp1760_platform_data v2m_usb_config = { 181 .is_isp1761 = true, 182 .bus_width_16 = false, 183 .port1_otg = true, 184 .analog_oc = false, 185 .dack_polarity_high = false, 186 .dreq_polarity_high = false, 187}; 188 189static struct platform_device v2m_usb_device = { 190 .name = "isp1760", 191 .id = -1, 192 .resource = v2m_usb_resources, 193 .num_resources = ARRAY_SIZE(v2m_usb_resources), 194 .dev.platform_data = &v2m_usb_config, 195}; 196 197static int v2m_flash_init(void) 198{ 199 writel(0, MMIO_P2V(V2M_SYS_FLASH)); 200 return 0; 201} 202 203static void v2m_flash_exit(void) 204{ 205 writel(0, MMIO_P2V(V2M_SYS_FLASH)); 206} 207 208static void v2m_flash_set_vpp(int on) 209{ 210 writel(on != 0, MMIO_P2V(V2M_SYS_FLASH)); 211} 212 213static struct flash_platform_data v2m_flash_data = { 214 .map_name = "cfi_probe", 215 .width = 4, 216 .init = v2m_flash_init, 217 .exit = v2m_flash_exit, 218 .set_vpp = v2m_flash_set_vpp, 219}; 220 221static struct resource v2m_flash_resources[] = { 222 { 223 .start = V2M_NOR0, 224 .end = V2M_NOR0 + SZ_64M - 1, 225 .flags = IORESOURCE_MEM, 226 }, { 227 .start = V2M_NOR1, 228 .end = V2M_NOR1 + SZ_64M - 1, 229 .flags = IORESOURCE_MEM, 230 }, 231}; 232 233static struct platform_device v2m_flash_device = { 234 .name = "armflash", 235 .id = -1, 236 .resource = v2m_flash_resources, 237 .num_resources = ARRAY_SIZE(v2m_flash_resources), 238 .dev.platform_data = &v2m_flash_data, 239}; 240 241 242static unsigned int v2m_mmci_status(struct device *dev) 243{ 244 return readl(MMIO_P2V(V2M_SYS_MCI)) & (1 << 0); 245} 246 247static struct mmci_platform_data v2m_mmci_data = { 248 .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, 249 .status = v2m_mmci_status, 250}; 251 252static AMBA_DEVICE(aaci, "mb:aaci", V2M_AACI, NULL); 253static AMBA_DEVICE(mmci, "mb:mmci", V2M_MMCI, &v2m_mmci_data); 254static AMBA_DEVICE(kmi0, "mb:kmi0", V2M_KMI0, NULL); 255static AMBA_DEVICE(kmi1, "mb:kmi1", V2M_KMI1, NULL); 256static AMBA_DEVICE(uart0, "mb:uart0", V2M_UART0, NULL); 257static AMBA_DEVICE(uart1, "mb:uart1", V2M_UART1, NULL); 258static AMBA_DEVICE(uart2, "mb:uart2", V2M_UART2, NULL); 259static AMBA_DEVICE(uart3, "mb:uart3", V2M_UART3, NULL); 260static AMBA_DEVICE(wdt, "mb:wdt", V2M_WDT, NULL); 261static AMBA_DEVICE(rtc, "mb:rtc", V2M_RTC, NULL); 262 263static struct amba_device *v2m_amba_devs[] __initdata = { 264 &aaci_device, 265 &mmci_device, 266 &kmi0_device, 267 &kmi1_device, 268 &uart0_device, 269 &uart1_device, 270 &uart2_device, 271 &uart3_device, 272 &wdt_device, 273 &rtc_device, 274}; 275 276 277static long v2m_osc_round(struct clk *clk, unsigned long rate) 278{ 279 return rate; 280} 281 282static int v2m_osc1_set(struct clk *clk, unsigned long rate) 283{ 284 return v2m_cfg_write(SYS_CFG_OSC | SYS_CFG_SITE_MB | 1, rate); 285} 286 287static const struct clk_ops osc1_clk_ops = { 288 .round = v2m_osc_round, 289 .set = v2m_osc1_set, 290}; 291 292static struct clk osc1_clk = { 293 .ops = &osc1_clk_ops, 294 .rate = 24000000, 295}; 296 297static struct clk osc2_clk = { 298 .rate = 24000000, 299}; 300 301static struct clk dummy_apb_pclk; 302 303static struct clk_lookup v2m_lookups[] = { 304 { /* AMBA bus clock */ 305 .con_id = "apb_pclk", 306 .clk = &dummy_apb_pclk, 307 }, { /* UART0 */ 308 .dev_id = "mb:uart0", 309 .clk = &osc2_clk, 310 }, { /* UART1 */ 311 .dev_id = "mb:uart1", 312 .clk = &osc2_clk, 313 }, { /* UART2 */ 314 .dev_id = "mb:uart2", 315 .clk = &osc2_clk, 316 }, { /* UART3 */ 317 .dev_id = "mb:uart3", 318 .clk = &osc2_clk, 319 }, { /* KMI0 */ 320 .dev_id = "mb:kmi0", 321 .clk = &osc2_clk, 322 }, { /* KMI1 */ 323 .dev_id = "mb:kmi1", 324 .clk = &osc2_clk, 325 }, { /* MMC0 */ 326 .dev_id = "mb:mmci", 327 .clk = &osc2_clk, 328 }, { /* CLCD */ 329 .dev_id = "mb:clcd", 330 .clk = &osc1_clk, 331 }, 332}; 333 334static void v2m_power_off(void) 335{ 336 if (v2m_cfg_write(SYS_CFG_SHUTDOWN | SYS_CFG_SITE_MB, 0)) 337 printk(KERN_EMERG "Unable to shutdown\n"); 338} 339 340static void v2m_restart(char str, const char *cmd) 341{ 342 if (v2m_cfg_write(SYS_CFG_REBOOT | SYS_CFG_SITE_MB, 0)) 343 printk(KERN_EMERG "Unable to reboot\n"); 344} 345 346static int __init v2m_init(void) 347{ 348 int i; 349 350 clkdev_add_table(v2m_lookups, ARRAY_SIZE(v2m_lookups)); 351 352 platform_device_register(&v2m_pcie_i2c_device); 353 platform_device_register(&v2m_ddc_i2c_device); 354 platform_device_register(&v2m_flash_device); 355 platform_device_register(&v2m_eth_device); 356 platform_device_register(&v2m_usb_device); 357 358 for (i = 0; i < ARRAY_SIZE(v2m_amba_devs); i++) 359 amba_device_register(v2m_amba_devs[i], &iomem_resource); 360 361 pm_power_off = v2m_power_off; 362 arm_pm_restart = v2m_restart; 363 364 return 0; 365} 366arch_initcall(v2m_init); 367