1/* 2 * Texas Instruments TNETV107X SoC devices 3 * 4 * Copyright (C) 2010 Texas Instruments 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation version 2. 9 * 10 * This program is distributed "as is" WITHOUT ANY WARRANTY of any 11 * kind, whether express or implied; without even the implied warranty 12 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 */ 15#include <linux/kernel.h> 16#include <linux/init.h> 17#include <linux/platform_device.h> 18#include <linux/dma-mapping.h> 19#include <linux/clk.h> 20#include <linux/slab.h> 21 22#include <mach/common.h> 23#include <mach/irqs.h> 24#include <mach/edma.h> 25#include <mach/tnetv107x.h> 26 27#include "clock.h" 28 29/* Base addresses for on-chip devices */ 30#define TNETV107X_TPCC_BASE 0x01c00000 31#define TNETV107X_TPTC0_BASE 0x01c10000 32#define TNETV107X_TPTC1_BASE 0x01c10400 33#define TNETV107X_WDOG_BASE 0x08086700 34#define TNETV107X_SDIO0_BASE 0x08088700 35#define TNETV107X_SDIO1_BASE 0x08088800 36#define TNETV107X_ASYNC_EMIF_CNTRL_BASE 0x08200000 37#define TNETV107X_ASYNC_EMIF_DATA_CE0_BASE 0x30000000 38#define TNETV107X_ASYNC_EMIF_DATA_CE1_BASE 0x40000000 39#define TNETV107X_ASYNC_EMIF_DATA_CE2_BASE 0x44000000 40#define TNETV107X_ASYNC_EMIF_DATA_CE3_BASE 0x48000000 41 42/* TNETV107X specific EDMA3 information */ 43#define EDMA_TNETV107X_NUM_DMACH 64 44#define EDMA_TNETV107X_NUM_TCC 64 45#define EDMA_TNETV107X_NUM_PARAMENTRY 128 46#define EDMA_TNETV107X_NUM_EVQUE 2 47#define EDMA_TNETV107X_NUM_TC 2 48#define EDMA_TNETV107X_CHMAP_EXIST 0 49#define EDMA_TNETV107X_NUM_REGIONS 4 50#define TNETV107X_DMACH2EVENT_MAP0 0x3C0CE000u 51#define TNETV107X_DMACH2EVENT_MAP1 0x000FFFFFu 52 53#define TNETV107X_DMACH_SDIO0_RX 26 54#define TNETV107X_DMACH_SDIO0_TX 27 55#define TNETV107X_DMACH_SDIO1_RX 28 56#define TNETV107X_DMACH_SDIO1_TX 29 57 58static const s8 edma_tc_mapping[][2] = { 59 /* event queue no TC no */ 60 { 0, 0 }, 61 { 1, 1 }, 62 { -1, -1 } 63}; 64 65static const s8 edma_priority_mapping[][2] = { 66 /* event queue no Prio */ 67 { 0, 3 }, 68 { 1, 7 }, 69 { -1, -1 } 70}; 71 72static struct edma_soc_info edma_cc0_info = { 73 .n_channel = EDMA_TNETV107X_NUM_DMACH, 74 .n_region = EDMA_TNETV107X_NUM_REGIONS, 75 .n_slot = EDMA_TNETV107X_NUM_PARAMENTRY, 76 .n_tc = EDMA_TNETV107X_NUM_TC, 77 .n_cc = 1, 78 .queue_tc_mapping = edma_tc_mapping, 79 .queue_priority_mapping = edma_priority_mapping, 80}; 81 82static struct edma_soc_info *tnetv107x_edma_info[EDMA_MAX_CC] = { 83 &edma_cc0_info, 84}; 85 86static struct resource edma_resources[] = { 87 { 88 .name = "edma_cc0", 89 .start = TNETV107X_TPCC_BASE, 90 .end = TNETV107X_TPCC_BASE + SZ_32K - 1, 91 .flags = IORESOURCE_MEM, 92 }, 93 { 94 .name = "edma_tc0", 95 .start = TNETV107X_TPTC0_BASE, 96 .end = TNETV107X_TPTC0_BASE + SZ_1K - 1, 97 .flags = IORESOURCE_MEM, 98 }, 99 { 100 .name = "edma_tc1", 101 .start = TNETV107X_TPTC1_BASE, 102 .end = TNETV107X_TPTC1_BASE + SZ_1K - 1, 103 .flags = IORESOURCE_MEM, 104 }, 105 { 106 .name = "edma0", 107 .start = IRQ_TNETV107X_TPCC, 108 .flags = IORESOURCE_IRQ, 109 }, 110 { 111 .name = "edma0_err", 112 .start = IRQ_TNETV107X_TPCC_ERR, 113 .flags = IORESOURCE_IRQ, 114 }, 115}; 116 117static struct platform_device edma_device = { 118 .name = "edma", 119 .id = -1, 120 .num_resources = ARRAY_SIZE(edma_resources), 121 .resource = edma_resources, 122 .dev.platform_data = tnetv107x_edma_info, 123}; 124 125static struct plat_serial8250_port serial_data[] = { 126 { 127 .mapbase = TNETV107X_UART0_BASE, 128 .irq = IRQ_TNETV107X_UART0, 129 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | 130 UPF_FIXED_TYPE | UPF_IOREMAP, 131 .type = PORT_AR7, 132 .iotype = UPIO_MEM32, 133 .regshift = 2, 134 }, 135 { 136 .mapbase = TNETV107X_UART1_BASE, 137 .irq = IRQ_TNETV107X_UART1, 138 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | 139 UPF_FIXED_TYPE | UPF_IOREMAP, 140 .type = PORT_AR7, 141 .iotype = UPIO_MEM32, 142 .regshift = 2, 143 }, 144 { 145 .mapbase = TNETV107X_UART2_BASE, 146 .irq = IRQ_TNETV107X_UART2, 147 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | 148 UPF_FIXED_TYPE | UPF_IOREMAP, 149 .type = PORT_AR7, 150 .iotype = UPIO_MEM32, 151 .regshift = 2, 152 }, 153 { 154 .flags = 0, 155 }, 156}; 157 158struct platform_device tnetv107x_serial_device = { 159 .name = "serial8250", 160 .id = PLAT8250_DEV_PLATFORM, 161 .dev.platform_data = serial_data, 162}; 163 164static struct resource mmc0_resources[] = { 165 { /* Memory mapped registers */ 166 .start = TNETV107X_SDIO0_BASE, 167 .end = TNETV107X_SDIO0_BASE + 0x0ff, 168 .flags = IORESOURCE_MEM 169 }, 170 { /* MMC interrupt */ 171 .start = IRQ_TNETV107X_MMC0, 172 .flags = IORESOURCE_IRQ 173 }, 174 { /* SDIO interrupt */ 175 .start = IRQ_TNETV107X_SDIO0, 176 .flags = IORESOURCE_IRQ 177 }, 178 { /* DMA RX */ 179 .start = EDMA_CTLR_CHAN(0, TNETV107X_DMACH_SDIO0_RX), 180 .flags = IORESOURCE_DMA 181 }, 182 { /* DMA TX */ 183 .start = EDMA_CTLR_CHAN(0, TNETV107X_DMACH_SDIO0_TX), 184 .flags = IORESOURCE_DMA 185 }, 186}; 187 188static struct resource mmc1_resources[] = { 189 { /* Memory mapped registers */ 190 .start = TNETV107X_SDIO1_BASE, 191 .end = TNETV107X_SDIO1_BASE + 0x0ff, 192 .flags = IORESOURCE_MEM 193 }, 194 { /* MMC interrupt */ 195 .start = IRQ_TNETV107X_MMC1, 196 .flags = IORESOURCE_IRQ 197 }, 198 { /* SDIO interrupt */ 199 .start = IRQ_TNETV107X_SDIO1, 200 .flags = IORESOURCE_IRQ 201 }, 202 { /* DMA RX */ 203 .start = EDMA_CTLR_CHAN(0, TNETV107X_DMACH_SDIO1_RX), 204 .flags = IORESOURCE_DMA 205 }, 206 { /* DMA TX */ 207 .start = EDMA_CTLR_CHAN(0, TNETV107X_DMACH_SDIO1_TX), 208 .flags = IORESOURCE_DMA 209 }, 210}; 211 212static u64 mmc0_dma_mask = DMA_BIT_MASK(32); 213static u64 mmc1_dma_mask = DMA_BIT_MASK(32); 214 215static struct platform_device mmc_devices[2] = { 216 { 217 .name = "davinci_mmc", 218 .id = 0, 219 .dev = { 220 .dma_mask = &mmc0_dma_mask, 221 .coherent_dma_mask = DMA_BIT_MASK(32), 222 }, 223 .num_resources = ARRAY_SIZE(mmc0_resources), 224 .resource = mmc0_resources 225 }, 226 { 227 .name = "davinci_mmc", 228 .id = 1, 229 .dev = { 230 .dma_mask = &mmc1_dma_mask, 231 .coherent_dma_mask = DMA_BIT_MASK(32), 232 }, 233 .num_resources = ARRAY_SIZE(mmc1_resources), 234 .resource = mmc1_resources 235 }, 236}; 237 238static const u32 emif_windows[] = { 239 TNETV107X_ASYNC_EMIF_DATA_CE0_BASE, TNETV107X_ASYNC_EMIF_DATA_CE1_BASE, 240 TNETV107X_ASYNC_EMIF_DATA_CE2_BASE, TNETV107X_ASYNC_EMIF_DATA_CE3_BASE, 241}; 242 243static const u32 emif_window_sizes[] = { SZ_256M, SZ_64M, SZ_64M, SZ_64M }; 244 245static struct resource wdt_resources[] = { 246 { 247 .start = TNETV107X_WDOG_BASE, 248 .end = TNETV107X_WDOG_BASE + SZ_4K - 1, 249 .flags = IORESOURCE_MEM, 250 }, 251}; 252 253struct platform_device tnetv107x_wdt_device = { 254 .name = "tnetv107x_wdt", 255 .id = 0, 256 .num_resources = ARRAY_SIZE(wdt_resources), 257 .resource = wdt_resources, 258}; 259 260static int __init nand_init(int chipsel, struct davinci_nand_pdata *data) 261{ 262 struct resource res[2]; 263 struct platform_device *pdev; 264 u32 range; 265 int ret; 266 267 /* Figure out the resource range from the ale/cle masks */ 268 range = max(data->mask_cle, data->mask_ale); 269 range = PAGE_ALIGN(range + 4) - 1; 270 271 if (range >= emif_window_sizes[chipsel]) 272 return -EINVAL; 273 274 pdev = kzalloc(sizeof(*pdev), GFP_KERNEL); 275 if (!pdev) 276 return -ENOMEM; 277 278 pdev->name = "davinci_nand"; 279 pdev->id = chipsel; 280 pdev->dev.platform_data = data; 281 282 memset(res, 0, sizeof(res)); 283 284 res[0].start = emif_windows[chipsel]; 285 res[0].end = res[0].start + range; 286 res[0].flags = IORESOURCE_MEM; 287 288 res[1].start = TNETV107X_ASYNC_EMIF_CNTRL_BASE; 289 res[1].end = res[1].start + SZ_4K - 1; 290 res[1].flags = IORESOURCE_MEM; 291 292 ret = platform_device_add_resources(pdev, res, ARRAY_SIZE(res)); 293 if (ret < 0) { 294 kfree(pdev); 295 return ret; 296 } 297 298 return platform_device_register(pdev); 299} 300 301void __init tnetv107x_devices_init(struct tnetv107x_device_info *info) 302{ 303 int i; 304 305 platform_device_register(&edma_device); 306 platform_device_register(&tnetv107x_wdt_device); 307 308 if (info->serial_config) 309 davinci_serial_init(info->serial_config); 310 311 for (i = 0; i < 2; i++) 312 if (info->mmc_config[i]) { 313 mmc_devices[i].dev.platform_data = info->mmc_config[i]; 314 platform_device_register(&mmc_devices[i]); 315 } 316 317 for (i = 0; i < 4; i++) 318 if (info->nand_config[i]) 319 nand_init(i, info->nand_config[i]); 320} 321