Path: blob/master/arch/arm/mach-davinci/devices-tnetv107x.c
10699 views
/*1* Texas Instruments TNETV107X SoC devices2*3* Copyright (C) 2010 Texas Instruments4*5* This program is free software; you can redistribute it and/or6* modify it under the terms of the GNU General Public License as7* published by the Free Software Foundation version 2.8*9* This program is distributed "as is" WITHOUT ANY WARRANTY of any10* kind, whether express or implied; without even the implied warranty11* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12* GNU General Public License for more details.13*/14#include <linux/kernel.h>15#include <linux/init.h>16#include <linux/platform_device.h>17#include <linux/dma-mapping.h>18#include <linux/clk.h>19#include <linux/slab.h>2021#include <mach/common.h>22#include <mach/irqs.h>23#include <mach/edma.h>24#include <mach/tnetv107x.h>2526#include "clock.h"2728/* Base addresses for on-chip devices */29#define TNETV107X_TPCC_BASE 0x01c0000030#define TNETV107X_TPTC0_BASE 0x01c1000031#define TNETV107X_TPTC1_BASE 0x01c1040032#define TNETV107X_WDOG_BASE 0x0808670033#define TNETV107X_TSC_BASE 0x0808850034#define TNETV107X_SDIO0_BASE 0x0808870035#define TNETV107X_SDIO1_BASE 0x0808880036#define TNETV107X_KEYPAD_BASE 0x08088a0037#define TNETV107X_SSP_BASE 0x08088c0038#define TNETV107X_ASYNC_EMIF_CNTRL_BASE 0x0820000039#define TNETV107X_ASYNC_EMIF_DATA_CE0_BASE 0x3000000040#define TNETV107X_ASYNC_EMIF_DATA_CE1_BASE 0x4000000041#define TNETV107X_ASYNC_EMIF_DATA_CE2_BASE 0x4400000042#define TNETV107X_ASYNC_EMIF_DATA_CE3_BASE 0x480000004344/* TNETV107X specific EDMA3 information */45#define EDMA_TNETV107X_NUM_DMACH 6446#define EDMA_TNETV107X_NUM_TCC 6447#define EDMA_TNETV107X_NUM_PARAMENTRY 12848#define EDMA_TNETV107X_NUM_EVQUE 249#define EDMA_TNETV107X_NUM_TC 250#define EDMA_TNETV107X_CHMAP_EXIST 051#define EDMA_TNETV107X_NUM_REGIONS 452#define TNETV107X_DMACH2EVENT_MAP0 0x3C0CE000u53#define TNETV107X_DMACH2EVENT_MAP1 0x000FFFFFu5455#define TNETV107X_DMACH_SDIO0_RX 2656#define TNETV107X_DMACH_SDIO0_TX 2757#define TNETV107X_DMACH_SDIO1_RX 2858#define TNETV107X_DMACH_SDIO1_TX 295960static const s8 edma_tc_mapping[][2] = {61/* event queue no TC no */62{ 0, 0 },63{ 1, 1 },64{ -1, -1 }65};6667static const s8 edma_priority_mapping[][2] = {68/* event queue no Prio */69{ 0, 3 },70{ 1, 7 },71{ -1, -1 }72};7374static struct edma_soc_info edma_cc0_info = {75.n_channel = EDMA_TNETV107X_NUM_DMACH,76.n_region = EDMA_TNETV107X_NUM_REGIONS,77.n_slot = EDMA_TNETV107X_NUM_PARAMENTRY,78.n_tc = EDMA_TNETV107X_NUM_TC,79.n_cc = 1,80.queue_tc_mapping = edma_tc_mapping,81.queue_priority_mapping = edma_priority_mapping,82};8384static struct edma_soc_info *tnetv107x_edma_info[EDMA_MAX_CC] = {85&edma_cc0_info,86};8788static struct resource edma_resources[] = {89{90.name = "edma_cc0",91.start = TNETV107X_TPCC_BASE,92.end = TNETV107X_TPCC_BASE + SZ_32K - 1,93.flags = IORESOURCE_MEM,94},95{96.name = "edma_tc0",97.start = TNETV107X_TPTC0_BASE,98.end = TNETV107X_TPTC0_BASE + SZ_1K - 1,99.flags = IORESOURCE_MEM,100},101{102.name = "edma_tc1",103.start = TNETV107X_TPTC1_BASE,104.end = TNETV107X_TPTC1_BASE + SZ_1K - 1,105.flags = IORESOURCE_MEM,106},107{108.name = "edma0",109.start = IRQ_TNETV107X_TPCC,110.flags = IORESOURCE_IRQ,111},112{113.name = "edma0_err",114.start = IRQ_TNETV107X_TPCC_ERR,115.flags = IORESOURCE_IRQ,116},117};118119static struct platform_device edma_device = {120.name = "edma",121.id = -1,122.num_resources = ARRAY_SIZE(edma_resources),123.resource = edma_resources,124.dev.platform_data = tnetv107x_edma_info,125};126127static struct plat_serial8250_port serial_data[] = {128{129.mapbase = TNETV107X_UART0_BASE,130.irq = IRQ_TNETV107X_UART0,131.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |132UPF_FIXED_TYPE | UPF_IOREMAP,133.type = PORT_AR7,134.iotype = UPIO_MEM32,135.regshift = 2,136},137{138.mapbase = TNETV107X_UART1_BASE,139.irq = IRQ_TNETV107X_UART1,140.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |141UPF_FIXED_TYPE | UPF_IOREMAP,142.type = PORT_AR7,143.iotype = UPIO_MEM32,144.regshift = 2,145},146{147.mapbase = TNETV107X_UART2_BASE,148.irq = IRQ_TNETV107X_UART2,149.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |150UPF_FIXED_TYPE | UPF_IOREMAP,151.type = PORT_AR7,152.iotype = UPIO_MEM32,153.regshift = 2,154},155{156.flags = 0,157},158};159160struct platform_device tnetv107x_serial_device = {161.name = "serial8250",162.id = PLAT8250_DEV_PLATFORM,163.dev.platform_data = serial_data,164};165166static struct resource mmc0_resources[] = {167{ /* Memory mapped registers */168.start = TNETV107X_SDIO0_BASE,169.end = TNETV107X_SDIO0_BASE + 0x0ff,170.flags = IORESOURCE_MEM171},172{ /* MMC interrupt */173.start = IRQ_TNETV107X_MMC0,174.flags = IORESOURCE_IRQ175},176{ /* SDIO interrupt */177.start = IRQ_TNETV107X_SDIO0,178.flags = IORESOURCE_IRQ179},180{ /* DMA RX */181.start = EDMA_CTLR_CHAN(0, TNETV107X_DMACH_SDIO0_RX),182.flags = IORESOURCE_DMA183},184{ /* DMA TX */185.start = EDMA_CTLR_CHAN(0, TNETV107X_DMACH_SDIO0_TX),186.flags = IORESOURCE_DMA187},188};189190static struct resource mmc1_resources[] = {191{ /* Memory mapped registers */192.start = TNETV107X_SDIO1_BASE,193.end = TNETV107X_SDIO1_BASE + 0x0ff,194.flags = IORESOURCE_MEM195},196{ /* MMC interrupt */197.start = IRQ_TNETV107X_MMC1,198.flags = IORESOURCE_IRQ199},200{ /* SDIO interrupt */201.start = IRQ_TNETV107X_SDIO1,202.flags = IORESOURCE_IRQ203},204{ /* DMA RX */205.start = EDMA_CTLR_CHAN(0, TNETV107X_DMACH_SDIO1_RX),206.flags = IORESOURCE_DMA207},208{ /* DMA TX */209.start = EDMA_CTLR_CHAN(0, TNETV107X_DMACH_SDIO1_TX),210.flags = IORESOURCE_DMA211},212};213214static u64 mmc0_dma_mask = DMA_BIT_MASK(32);215static u64 mmc1_dma_mask = DMA_BIT_MASK(32);216217static struct platform_device mmc_devices[2] = {218{219.name = "davinci_mmc",220.id = 0,221.dev = {222.dma_mask = &mmc0_dma_mask,223.coherent_dma_mask = DMA_BIT_MASK(32),224},225.num_resources = ARRAY_SIZE(mmc0_resources),226.resource = mmc0_resources227},228{229.name = "davinci_mmc",230.id = 1,231.dev = {232.dma_mask = &mmc1_dma_mask,233.coherent_dma_mask = DMA_BIT_MASK(32),234},235.num_resources = ARRAY_SIZE(mmc1_resources),236.resource = mmc1_resources237},238};239240static const u32 emif_windows[] = {241TNETV107X_ASYNC_EMIF_DATA_CE0_BASE, TNETV107X_ASYNC_EMIF_DATA_CE1_BASE,242TNETV107X_ASYNC_EMIF_DATA_CE2_BASE, TNETV107X_ASYNC_EMIF_DATA_CE3_BASE,243};244245static const u32 emif_window_sizes[] = { SZ_256M, SZ_64M, SZ_64M, SZ_64M };246247static struct resource wdt_resources[] = {248{249.start = TNETV107X_WDOG_BASE,250.end = TNETV107X_WDOG_BASE + SZ_4K - 1,251.flags = IORESOURCE_MEM,252},253};254255struct platform_device tnetv107x_wdt_device = {256.name = "tnetv107x_wdt",257.id = 0,258.num_resources = ARRAY_SIZE(wdt_resources),259.resource = wdt_resources,260};261262static int __init nand_init(int chipsel, struct davinci_nand_pdata *data)263{264struct resource res[2];265struct platform_device *pdev;266u32 range;267int ret;268269/* Figure out the resource range from the ale/cle masks */270range = max(data->mask_cle, data->mask_ale);271range = PAGE_ALIGN(range + 4) - 1;272273if (range >= emif_window_sizes[chipsel])274return -EINVAL;275276pdev = kzalloc(sizeof(*pdev), GFP_KERNEL);277if (!pdev)278return -ENOMEM;279280pdev->name = "davinci_nand";281pdev->id = chipsel;282pdev->dev.platform_data = data;283284memset(res, 0, sizeof(res));285286res[0].start = emif_windows[chipsel];287res[0].end = res[0].start + range;288res[0].flags = IORESOURCE_MEM;289290res[1].start = TNETV107X_ASYNC_EMIF_CNTRL_BASE;291res[1].end = res[1].start + SZ_4K - 1;292res[1].flags = IORESOURCE_MEM;293294ret = platform_device_add_resources(pdev, res, ARRAY_SIZE(res));295if (ret < 0) {296kfree(pdev);297return ret;298}299300return platform_device_register(pdev);301}302303static struct resource keypad_resources[] = {304{305.start = TNETV107X_KEYPAD_BASE,306.end = TNETV107X_KEYPAD_BASE + 0xff,307.flags = IORESOURCE_MEM,308},309{310.start = IRQ_TNETV107X_KEYPAD,311.flags = IORESOURCE_IRQ,312.name = "press",313},314{315.start = IRQ_TNETV107X_KEYPAD_FREE,316.flags = IORESOURCE_IRQ,317.name = "release",318},319};320321static struct platform_device keypad_device = {322.name = "tnetv107x-keypad",323.num_resources = ARRAY_SIZE(keypad_resources),324.resource = keypad_resources,325};326327static struct resource tsc_resources[] = {328{329.start = TNETV107X_TSC_BASE,330.end = TNETV107X_TSC_BASE + 0xff,331.flags = IORESOURCE_MEM,332},333{334.start = IRQ_TNETV107X_TSC,335.flags = IORESOURCE_IRQ,336},337};338339static struct platform_device tsc_device = {340.name = "tnetv107x-ts",341.num_resources = ARRAY_SIZE(tsc_resources),342.resource = tsc_resources,343};344345static struct resource ssp_resources[] = {346{347.start = TNETV107X_SSP_BASE,348.end = TNETV107X_SSP_BASE + 0x1ff,349.flags = IORESOURCE_MEM,350},351{352.start = IRQ_TNETV107X_SSP,353.flags = IORESOURCE_IRQ,354},355};356357static struct platform_device ssp_device = {358.name = "ti-ssp",359.id = -1,360.num_resources = ARRAY_SIZE(ssp_resources),361.resource = ssp_resources,362};363364void __init tnetv107x_devices_init(struct tnetv107x_device_info *info)365{366int i, error;367struct clk *tsc_clk;368369/*370* The reset defaults for tnetv107x tsc clock divider is set too high.371* This forces the clock down to a range that allows the ADC to372* complete sample conversion in time.373*/374tsc_clk = clk_get(NULL, "sys_tsc_clk");375if (tsc_clk) {376error = clk_set_rate(tsc_clk, 5000000);377WARN_ON(error < 0);378clk_put(tsc_clk);379}380381platform_device_register(&edma_device);382platform_device_register(&tnetv107x_wdt_device);383platform_device_register(&tsc_device);384385if (info->serial_config)386davinci_serial_init(info->serial_config);387388for (i = 0; i < 2; i++)389if (info->mmc_config[i]) {390mmc_devices[i].dev.platform_data = info->mmc_config[i];391platform_device_register(&mmc_devices[i]);392}393394for (i = 0; i < 4; i++)395if (info->nand_config[i])396nand_init(i, info->nand_config[i]);397398if (info->keypad_config) {399keypad_device.dev.platform_data = info->keypad_config;400platform_device_register(&keypad_device);401}402403if (info->ssp_config) {404ssp_device.dev.platform_data = info->ssp_config;405platform_device_register(&ssp_device);406}407}408409410