Path: blob/master/arch/avr32/mach-at32ap/at32ap700x.c
10817 views
/*1* Copyright (C) 2005-2006 Atmel Corporation2*3* This program is free software; you can redistribute it and/or modify4* it under the terms of the GNU General Public License version 2 as5* published by the Free Software Foundation.6*/7#include <linux/clk.h>8#include <linux/delay.h>9#include <linux/dw_dmac.h>10#include <linux/fb.h>11#include <linux/init.h>12#include <linux/platform_device.h>13#include <linux/dma-mapping.h>14#include <linux/slab.h>15#include <linux/gpio.h>16#include <linux/spi/spi.h>17#include <linux/usb/atmel_usba_udc.h>1819#include <mach/atmel-mci.h>20#include <linux/atmel-mci.h>2122#include <asm/io.h>23#include <asm/irq.h>2425#include <mach/at32ap700x.h>26#include <mach/board.h>27#include <mach/hmatrix.h>28#include <mach/portmux.h>29#include <mach/sram.h>3031#include <sound/atmel-abdac.h>32#include <sound/atmel-ac97c.h>3334#include <video/atmel_lcdc.h>3536#include "clock.h"37#include "pio.h"38#include "pm.h"394041#define PBMEM(base) \42{ \43.start = base, \44.end = base + 0x3ff, \45.flags = IORESOURCE_MEM, \46}47#define IRQ(num) \48{ \49.start = num, \50.end = num, \51.flags = IORESOURCE_IRQ, \52}53#define NAMED_IRQ(num, _name) \54{ \55.start = num, \56.end = num, \57.name = _name, \58.flags = IORESOURCE_IRQ, \59}6061/* REVISIT these assume *every* device supports DMA, but several62* don't ... tc, smc, pio, rtc, watchdog, pwm, ps2, and more.63*/64#define DEFINE_DEV(_name, _id) \65static u64 _name##_id##_dma_mask = DMA_BIT_MASK(32); \66static struct platform_device _name##_id##_device = { \67.name = #_name, \68.id = _id, \69.dev = { \70.dma_mask = &_name##_id##_dma_mask, \71.coherent_dma_mask = DMA_BIT_MASK(32), \72}, \73.resource = _name##_id##_resource, \74.num_resources = ARRAY_SIZE(_name##_id##_resource), \75}76#define DEFINE_DEV_DATA(_name, _id) \77static u64 _name##_id##_dma_mask = DMA_BIT_MASK(32); \78static struct platform_device _name##_id##_device = { \79.name = #_name, \80.id = _id, \81.dev = { \82.dma_mask = &_name##_id##_dma_mask, \83.platform_data = &_name##_id##_data, \84.coherent_dma_mask = DMA_BIT_MASK(32), \85}, \86.resource = _name##_id##_resource, \87.num_resources = ARRAY_SIZE(_name##_id##_resource), \88}8990#define select_peripheral(port, pin_mask, periph, flags) \91at32_select_periph(GPIO_##port##_BASE, pin_mask, \92GPIO_##periph, flags)9394#define DEV_CLK(_name, devname, bus, _index) \95static struct clk devname##_##_name = { \96.name = #_name, \97.dev = &devname##_device.dev, \98.parent = &bus##_clk, \99.mode = bus##_clk_mode, \100.get_rate = bus##_clk_get_rate, \101.index = _index, \102}103104static DEFINE_SPINLOCK(pm_lock);105106static struct clk osc0;107static struct clk osc1;108109static unsigned long osc_get_rate(struct clk *clk)110{111return at32_board_osc_rates[clk->index];112}113114static unsigned long pll_get_rate(struct clk *clk, unsigned long control)115{116unsigned long div, mul, rate;117118div = PM_BFEXT(PLLDIV, control) + 1;119mul = PM_BFEXT(PLLMUL, control) + 1;120121rate = clk->parent->get_rate(clk->parent);122rate = (rate + div / 2) / div;123rate *= mul;124125return rate;126}127128static long pll_set_rate(struct clk *clk, unsigned long rate,129u32 *pll_ctrl)130{131unsigned long mul;132unsigned long mul_best_fit = 0;133unsigned long div;134unsigned long div_min;135unsigned long div_max;136unsigned long div_best_fit = 0;137unsigned long base;138unsigned long pll_in;139unsigned long actual = 0;140unsigned long rate_error;141unsigned long rate_error_prev = ~0UL;142u32 ctrl;143144/* Rate must be between 80 MHz and 200 Mhz. */145if (rate < 80000000UL || rate > 200000000UL)146return -EINVAL;147148ctrl = PM_BF(PLLOPT, 4);149base = clk->parent->get_rate(clk->parent);150151/* PLL input frequency must be between 6 MHz and 32 MHz. */152div_min = DIV_ROUND_UP(base, 32000000UL);153div_max = base / 6000000UL;154155if (div_max < div_min)156return -EINVAL;157158for (div = div_min; div <= div_max; div++) {159pll_in = (base + div / 2) / div;160mul = (rate + pll_in / 2) / pll_in;161162if (mul == 0)163continue;164165actual = pll_in * mul;166rate_error = abs(actual - rate);167168if (rate_error < rate_error_prev) {169mul_best_fit = mul;170div_best_fit = div;171rate_error_prev = rate_error;172}173174if (rate_error == 0)175break;176}177178if (div_best_fit == 0)179return -EINVAL;180181ctrl |= PM_BF(PLLMUL, mul_best_fit - 1);182ctrl |= PM_BF(PLLDIV, div_best_fit - 1);183ctrl |= PM_BF(PLLCOUNT, 16);184185if (clk->parent == &osc1)186ctrl |= PM_BIT(PLLOSC);187188*pll_ctrl = ctrl;189190return actual;191}192193static unsigned long pll0_get_rate(struct clk *clk)194{195u32 control;196197control = pm_readl(PLL0);198199return pll_get_rate(clk, control);200}201202static void pll1_mode(struct clk *clk, int enabled)203{204unsigned long timeout;205u32 status;206u32 ctrl;207208ctrl = pm_readl(PLL1);209210if (enabled) {211if (!PM_BFEXT(PLLMUL, ctrl) && !PM_BFEXT(PLLDIV, ctrl)) {212pr_debug("clk %s: failed to enable, rate not set\n",213clk->name);214return;215}216217ctrl |= PM_BIT(PLLEN);218pm_writel(PLL1, ctrl);219220/* Wait for PLL lock. */221for (timeout = 10000; timeout; timeout--) {222status = pm_readl(ISR);223if (status & PM_BIT(LOCK1))224break;225udelay(10);226}227228if (!(status & PM_BIT(LOCK1)))229printk(KERN_ERR "clk %s: timeout waiting for lock\n",230clk->name);231} else {232ctrl &= ~PM_BIT(PLLEN);233pm_writel(PLL1, ctrl);234}235}236237static unsigned long pll1_get_rate(struct clk *clk)238{239u32 control;240241control = pm_readl(PLL1);242243return pll_get_rate(clk, control);244}245246static long pll1_set_rate(struct clk *clk, unsigned long rate, int apply)247{248u32 ctrl = 0;249unsigned long actual_rate;250251actual_rate = pll_set_rate(clk, rate, &ctrl);252253if (apply) {254if (actual_rate != rate)255return -EINVAL;256if (clk->users > 0)257return -EBUSY;258pr_debug(KERN_INFO "clk %s: new rate %lu (actual rate %lu)\n",259clk->name, rate, actual_rate);260pm_writel(PLL1, ctrl);261}262263return actual_rate;264}265266static int pll1_set_parent(struct clk *clk, struct clk *parent)267{268u32 ctrl;269270if (clk->users > 0)271return -EBUSY;272273ctrl = pm_readl(PLL1);274WARN_ON(ctrl & PM_BIT(PLLEN));275276if (parent == &osc0)277ctrl &= ~PM_BIT(PLLOSC);278else if (parent == &osc1)279ctrl |= PM_BIT(PLLOSC);280else281return -EINVAL;282283pm_writel(PLL1, ctrl);284clk->parent = parent;285286return 0;287}288289/*290* The AT32AP7000 has five primary clock sources: One 32kHz291* oscillator, two crystal oscillators and two PLLs.292*/293static struct clk osc32k = {294.name = "osc32k",295.get_rate = osc_get_rate,296.users = 1,297.index = 0,298};299static struct clk osc0 = {300.name = "osc0",301.get_rate = osc_get_rate,302.users = 1,303.index = 1,304};305static struct clk osc1 = {306.name = "osc1",307.get_rate = osc_get_rate,308.index = 2,309};310static struct clk pll0 = {311.name = "pll0",312.get_rate = pll0_get_rate,313.parent = &osc0,314};315static struct clk pll1 = {316.name = "pll1",317.mode = pll1_mode,318.get_rate = pll1_get_rate,319.set_rate = pll1_set_rate,320.set_parent = pll1_set_parent,321.parent = &osc0,322};323324/*325* The main clock can be either osc0 or pll0. The boot loader may326* have chosen one for us, so we don't really know which one until we327* have a look at the SM.328*/329static struct clk *main_clock;330331/*332* Synchronous clocks are generated from the main clock. The clocks333* must satisfy the constraint334* fCPU >= fHSB >= fPB335* i.e. each clock must not be faster than its parent.336*/337static unsigned long bus_clk_get_rate(struct clk *clk, unsigned int shift)338{339return main_clock->get_rate(main_clock) >> shift;340};341342static void cpu_clk_mode(struct clk *clk, int enabled)343{344unsigned long flags;345u32 mask;346347spin_lock_irqsave(&pm_lock, flags);348mask = pm_readl(CPU_MASK);349if (enabled)350mask |= 1 << clk->index;351else352mask &= ~(1 << clk->index);353pm_writel(CPU_MASK, mask);354spin_unlock_irqrestore(&pm_lock, flags);355}356357static unsigned long cpu_clk_get_rate(struct clk *clk)358{359unsigned long cksel, shift = 0;360361cksel = pm_readl(CKSEL);362if (cksel & PM_BIT(CPUDIV))363shift = PM_BFEXT(CPUSEL, cksel) + 1;364365return bus_clk_get_rate(clk, shift);366}367368static long cpu_clk_set_rate(struct clk *clk, unsigned long rate, int apply)369{370u32 control;371unsigned long parent_rate, child_div, actual_rate, div;372373parent_rate = clk->parent->get_rate(clk->parent);374control = pm_readl(CKSEL);375376if (control & PM_BIT(HSBDIV))377child_div = 1 << (PM_BFEXT(HSBSEL, control) + 1);378else379child_div = 1;380381if (rate > 3 * (parent_rate / 4) || child_div == 1) {382actual_rate = parent_rate;383control &= ~PM_BIT(CPUDIV);384} else {385unsigned int cpusel;386div = (parent_rate + rate / 2) / rate;387if (div > child_div)388div = child_div;389cpusel = (div > 1) ? (fls(div) - 2) : 0;390control = PM_BIT(CPUDIV) | PM_BFINS(CPUSEL, cpusel, control);391actual_rate = parent_rate / (1 << (cpusel + 1));392}393394pr_debug("clk %s: new rate %lu (actual rate %lu)\n",395clk->name, rate, actual_rate);396397if (apply)398pm_writel(CKSEL, control);399400return actual_rate;401}402403static void hsb_clk_mode(struct clk *clk, int enabled)404{405unsigned long flags;406u32 mask;407408spin_lock_irqsave(&pm_lock, flags);409mask = pm_readl(HSB_MASK);410if (enabled)411mask |= 1 << clk->index;412else413mask &= ~(1 << clk->index);414pm_writel(HSB_MASK, mask);415spin_unlock_irqrestore(&pm_lock, flags);416}417418static unsigned long hsb_clk_get_rate(struct clk *clk)419{420unsigned long cksel, shift = 0;421422cksel = pm_readl(CKSEL);423if (cksel & PM_BIT(HSBDIV))424shift = PM_BFEXT(HSBSEL, cksel) + 1;425426return bus_clk_get_rate(clk, shift);427}428429void pba_clk_mode(struct clk *clk, int enabled)430{431unsigned long flags;432u32 mask;433434spin_lock_irqsave(&pm_lock, flags);435mask = pm_readl(PBA_MASK);436if (enabled)437mask |= 1 << clk->index;438else439mask &= ~(1 << clk->index);440pm_writel(PBA_MASK, mask);441spin_unlock_irqrestore(&pm_lock, flags);442}443444unsigned long pba_clk_get_rate(struct clk *clk)445{446unsigned long cksel, shift = 0;447448cksel = pm_readl(CKSEL);449if (cksel & PM_BIT(PBADIV))450shift = PM_BFEXT(PBASEL, cksel) + 1;451452return bus_clk_get_rate(clk, shift);453}454455static void pbb_clk_mode(struct clk *clk, int enabled)456{457unsigned long flags;458u32 mask;459460spin_lock_irqsave(&pm_lock, flags);461mask = pm_readl(PBB_MASK);462if (enabled)463mask |= 1 << clk->index;464else465mask &= ~(1 << clk->index);466pm_writel(PBB_MASK, mask);467spin_unlock_irqrestore(&pm_lock, flags);468}469470static unsigned long pbb_clk_get_rate(struct clk *clk)471{472unsigned long cksel, shift = 0;473474cksel = pm_readl(CKSEL);475if (cksel & PM_BIT(PBBDIV))476shift = PM_BFEXT(PBBSEL, cksel) + 1;477478return bus_clk_get_rate(clk, shift);479}480481static struct clk cpu_clk = {482.name = "cpu",483.get_rate = cpu_clk_get_rate,484.set_rate = cpu_clk_set_rate,485.users = 1,486};487static struct clk hsb_clk = {488.name = "hsb",489.parent = &cpu_clk,490.get_rate = hsb_clk_get_rate,491};492static struct clk pba_clk = {493.name = "pba",494.parent = &hsb_clk,495.mode = hsb_clk_mode,496.get_rate = pba_clk_get_rate,497.index = 1,498};499static struct clk pbb_clk = {500.name = "pbb",501.parent = &hsb_clk,502.mode = hsb_clk_mode,503.get_rate = pbb_clk_get_rate,504.users = 1,505.index = 2,506};507508/* --------------------------------------------------------------------509* Generic Clock operations510* -------------------------------------------------------------------- */511512static void genclk_mode(struct clk *clk, int enabled)513{514u32 control;515516control = pm_readl(GCCTRL(clk->index));517if (enabled)518control |= PM_BIT(CEN);519else520control &= ~PM_BIT(CEN);521pm_writel(GCCTRL(clk->index), control);522}523524static unsigned long genclk_get_rate(struct clk *clk)525{526u32 control;527unsigned long div = 1;528529control = pm_readl(GCCTRL(clk->index));530if (control & PM_BIT(DIVEN))531div = 2 * (PM_BFEXT(DIV, control) + 1);532533return clk->parent->get_rate(clk->parent) / div;534}535536static long genclk_set_rate(struct clk *clk, unsigned long rate, int apply)537{538u32 control;539unsigned long parent_rate, actual_rate, div;540541parent_rate = clk->parent->get_rate(clk->parent);542control = pm_readl(GCCTRL(clk->index));543544if (rate > 3 * parent_rate / 4) {545actual_rate = parent_rate;546control &= ~PM_BIT(DIVEN);547} else {548div = (parent_rate + rate) / (2 * rate) - 1;549control = PM_BFINS(DIV, div, control) | PM_BIT(DIVEN);550actual_rate = parent_rate / (2 * (div + 1));551}552553dev_dbg(clk->dev, "clk %s: new rate %lu (actual rate %lu)\n",554clk->name, rate, actual_rate);555556if (apply)557pm_writel(GCCTRL(clk->index), control);558559return actual_rate;560}561562int genclk_set_parent(struct clk *clk, struct clk *parent)563{564u32 control;565566dev_dbg(clk->dev, "clk %s: new parent %s (was %s)\n",567clk->name, parent->name, clk->parent->name);568569control = pm_readl(GCCTRL(clk->index));570571if (parent == &osc1 || parent == &pll1)572control |= PM_BIT(OSCSEL);573else if (parent == &osc0 || parent == &pll0)574control &= ~PM_BIT(OSCSEL);575else576return -EINVAL;577578if (parent == &pll0 || parent == &pll1)579control |= PM_BIT(PLLSEL);580else581control &= ~PM_BIT(PLLSEL);582583pm_writel(GCCTRL(clk->index), control);584clk->parent = parent;585586return 0;587}588589static void __init genclk_init_parent(struct clk *clk)590{591u32 control;592struct clk *parent;593594BUG_ON(clk->index > 7);595596control = pm_readl(GCCTRL(clk->index));597if (control & PM_BIT(OSCSEL))598parent = (control & PM_BIT(PLLSEL)) ? &pll1 : &osc1;599else600parent = (control & PM_BIT(PLLSEL)) ? &pll0 : &osc0;601602clk->parent = parent;603}604605static struct dw_dma_platform_data dw_dmac0_data = {606.nr_channels = 3,607};608609static struct resource dw_dmac0_resource[] = {610PBMEM(0xff200000),611IRQ(2),612};613DEFINE_DEV_DATA(dw_dmac, 0);614DEV_CLK(hclk, dw_dmac0, hsb, 10);615616/* --------------------------------------------------------------------617* System peripherals618* -------------------------------------------------------------------- */619static struct resource at32_pm0_resource[] = {620{621.start = 0xfff00000,622.end = 0xfff0007f,623.flags = IORESOURCE_MEM,624},625IRQ(20),626};627628static struct resource at32ap700x_rtc0_resource[] = {629{630.start = 0xfff00080,631.end = 0xfff000af,632.flags = IORESOURCE_MEM,633},634IRQ(21),635};636637static struct resource at32_wdt0_resource[] = {638{639.start = 0xfff000b0,640.end = 0xfff000cf,641.flags = IORESOURCE_MEM,642},643};644645static struct resource at32_eic0_resource[] = {646{647.start = 0xfff00100,648.end = 0xfff0013f,649.flags = IORESOURCE_MEM,650},651IRQ(19),652};653654DEFINE_DEV(at32_pm, 0);655DEFINE_DEV(at32ap700x_rtc, 0);656DEFINE_DEV(at32_wdt, 0);657DEFINE_DEV(at32_eic, 0);658659/*660* Peripheral clock for PM, RTC, WDT and EIC. PM will ensure that this661* is always running.662*/663static struct clk at32_pm_pclk = {664.name = "pclk",665.dev = &at32_pm0_device.dev,666.parent = &pbb_clk,667.mode = pbb_clk_mode,668.get_rate = pbb_clk_get_rate,669.users = 1,670.index = 0,671};672673static struct resource intc0_resource[] = {674PBMEM(0xfff00400),675};676struct platform_device at32_intc0_device = {677.name = "intc",678.id = 0,679.resource = intc0_resource,680.num_resources = ARRAY_SIZE(intc0_resource),681};682DEV_CLK(pclk, at32_intc0, pbb, 1);683684static struct clk ebi_clk = {685.name = "ebi",686.parent = &hsb_clk,687.mode = hsb_clk_mode,688.get_rate = hsb_clk_get_rate,689.users = 1,690};691static struct clk hramc_clk = {692.name = "hramc",693.parent = &hsb_clk,694.mode = hsb_clk_mode,695.get_rate = hsb_clk_get_rate,696.users = 1,697.index = 3,698};699static struct clk sdramc_clk = {700.name = "sdramc_clk",701.parent = &pbb_clk,702.mode = pbb_clk_mode,703.get_rate = pbb_clk_get_rate,704.users = 1,705.index = 14,706};707708static struct resource smc0_resource[] = {709PBMEM(0xfff03400),710};711DEFINE_DEV(smc, 0);712DEV_CLK(pclk, smc0, pbb, 13);713DEV_CLK(mck, smc0, hsb, 0);714715static struct platform_device pdc_device = {716.name = "pdc",717.id = 0,718};719DEV_CLK(hclk, pdc, hsb, 4);720DEV_CLK(pclk, pdc, pba, 16);721722static struct clk pico_clk = {723.name = "pico",724.parent = &cpu_clk,725.mode = cpu_clk_mode,726.get_rate = cpu_clk_get_rate,727.users = 1,728};729730/* --------------------------------------------------------------------731* HMATRIX732* -------------------------------------------------------------------- */733734struct clk at32_hmatrix_clk = {735.name = "hmatrix_clk",736.parent = &pbb_clk,737.mode = pbb_clk_mode,738.get_rate = pbb_clk_get_rate,739.index = 2,740.users = 1,741};742743/*744* Set bits in the HMATRIX Special Function Register (SFR) used by the745* External Bus Interface (EBI). This can be used to enable special746* features like CompactFlash support, NAND Flash support, etc. on747* certain chipselects.748*/749static inline void set_ebi_sfr_bits(u32 mask)750{751hmatrix_sfr_set_bits(HMATRIX_SLAVE_EBI, mask);752}753754/* --------------------------------------------------------------------755* Timer/Counter (TC)756* -------------------------------------------------------------------- */757758static struct resource at32_tcb0_resource[] = {759PBMEM(0xfff00c00),760IRQ(22),761};762static struct platform_device at32_tcb0_device = {763.name = "atmel_tcb",764.id = 0,765.resource = at32_tcb0_resource,766.num_resources = ARRAY_SIZE(at32_tcb0_resource),767};768DEV_CLK(t0_clk, at32_tcb0, pbb, 3);769770static struct resource at32_tcb1_resource[] = {771PBMEM(0xfff01000),772IRQ(23),773};774static struct platform_device at32_tcb1_device = {775.name = "atmel_tcb",776.id = 1,777.resource = at32_tcb1_resource,778.num_resources = ARRAY_SIZE(at32_tcb1_resource),779};780DEV_CLK(t0_clk, at32_tcb1, pbb, 4);781782/* --------------------------------------------------------------------783* PIO784* -------------------------------------------------------------------- */785786static struct resource pio0_resource[] = {787PBMEM(0xffe02800),788IRQ(13),789};790DEFINE_DEV(pio, 0);791DEV_CLK(mck, pio0, pba, 10);792793static struct resource pio1_resource[] = {794PBMEM(0xffe02c00),795IRQ(14),796};797DEFINE_DEV(pio, 1);798DEV_CLK(mck, pio1, pba, 11);799800static struct resource pio2_resource[] = {801PBMEM(0xffe03000),802IRQ(15),803};804DEFINE_DEV(pio, 2);805DEV_CLK(mck, pio2, pba, 12);806807static struct resource pio3_resource[] = {808PBMEM(0xffe03400),809IRQ(16),810};811DEFINE_DEV(pio, 3);812DEV_CLK(mck, pio3, pba, 13);813814static struct resource pio4_resource[] = {815PBMEM(0xffe03800),816IRQ(17),817};818DEFINE_DEV(pio, 4);819DEV_CLK(mck, pio4, pba, 14);820821static int __init system_device_init(void)822{823platform_device_register(&at32_pm0_device);824platform_device_register(&at32_intc0_device);825platform_device_register(&at32ap700x_rtc0_device);826platform_device_register(&at32_wdt0_device);827platform_device_register(&at32_eic0_device);828platform_device_register(&smc0_device);829platform_device_register(&pdc_device);830platform_device_register(&dw_dmac0_device);831832platform_device_register(&at32_tcb0_device);833platform_device_register(&at32_tcb1_device);834835platform_device_register(&pio0_device);836platform_device_register(&pio1_device);837platform_device_register(&pio2_device);838platform_device_register(&pio3_device);839platform_device_register(&pio4_device);840841return 0;842}843core_initcall(system_device_init);844845/* --------------------------------------------------------------------846* PSIF847* -------------------------------------------------------------------- */848static struct resource atmel_psif0_resource[] __initdata = {849{850.start = 0xffe03c00,851.end = 0xffe03cff,852.flags = IORESOURCE_MEM,853},854IRQ(18),855};856static struct clk atmel_psif0_pclk = {857.name = "pclk",858.parent = &pba_clk,859.mode = pba_clk_mode,860.get_rate = pba_clk_get_rate,861.index = 15,862};863864static struct resource atmel_psif1_resource[] __initdata = {865{866.start = 0xffe03d00,867.end = 0xffe03dff,868.flags = IORESOURCE_MEM,869},870IRQ(18),871};872static struct clk atmel_psif1_pclk = {873.name = "pclk",874.parent = &pba_clk,875.mode = pba_clk_mode,876.get_rate = pba_clk_get_rate,877.index = 15,878};879880struct platform_device *__init at32_add_device_psif(unsigned int id)881{882struct platform_device *pdev;883u32 pin_mask;884885if (!(id == 0 || id == 1))886return NULL;887888pdev = platform_device_alloc("atmel_psif", id);889if (!pdev)890return NULL;891892switch (id) {893case 0:894pin_mask = (1 << 8) | (1 << 9); /* CLOCK & DATA */895896if (platform_device_add_resources(pdev, atmel_psif0_resource,897ARRAY_SIZE(atmel_psif0_resource)))898goto err_add_resources;899atmel_psif0_pclk.dev = &pdev->dev;900select_peripheral(PIOA, pin_mask, PERIPH_A, 0);901break;902case 1:903pin_mask = (1 << 11) | (1 << 12); /* CLOCK & DATA */904905if (platform_device_add_resources(pdev, atmel_psif1_resource,906ARRAY_SIZE(atmel_psif1_resource)))907goto err_add_resources;908atmel_psif1_pclk.dev = &pdev->dev;909select_peripheral(PIOB, pin_mask, PERIPH_A, 0);910break;911default:912return NULL;913}914915platform_device_add(pdev);916return pdev;917918err_add_resources:919platform_device_put(pdev);920return NULL;921}922923/* --------------------------------------------------------------------924* USART925* -------------------------------------------------------------------- */926927static struct atmel_uart_data atmel_usart0_data = {928.use_dma_tx = 1,929.use_dma_rx = 1,930};931static struct resource atmel_usart0_resource[] = {932PBMEM(0xffe00c00),933IRQ(6),934};935DEFINE_DEV_DATA(atmel_usart, 0);936DEV_CLK(usart, atmel_usart0, pba, 3);937938static struct atmel_uart_data atmel_usart1_data = {939.use_dma_tx = 1,940.use_dma_rx = 1,941};942static struct resource atmel_usart1_resource[] = {943PBMEM(0xffe01000),944IRQ(7),945};946DEFINE_DEV_DATA(atmel_usart, 1);947DEV_CLK(usart, atmel_usart1, pba, 4);948949static struct atmel_uart_data atmel_usart2_data = {950.use_dma_tx = 1,951.use_dma_rx = 1,952};953static struct resource atmel_usart2_resource[] = {954PBMEM(0xffe01400),955IRQ(8),956};957DEFINE_DEV_DATA(atmel_usart, 2);958DEV_CLK(usart, atmel_usart2, pba, 5);959960static struct atmel_uart_data atmel_usart3_data = {961.use_dma_tx = 1,962.use_dma_rx = 1,963};964static struct resource atmel_usart3_resource[] = {965PBMEM(0xffe01800),966IRQ(9),967};968DEFINE_DEV_DATA(atmel_usart, 3);969DEV_CLK(usart, atmel_usart3, pba, 6);970971static inline void configure_usart0_pins(int flags)972{973u32 pin_mask = (1 << 8) | (1 << 9); /* RXD & TXD */974if (flags & ATMEL_USART_RTS) pin_mask |= (1 << 6);975if (flags & ATMEL_USART_CTS) pin_mask |= (1 << 7);976if (flags & ATMEL_USART_CLK) pin_mask |= (1 << 10);977978select_peripheral(PIOA, pin_mask, PERIPH_B, AT32_GPIOF_PULLUP);979}980981static inline void configure_usart1_pins(int flags)982{983u32 pin_mask = (1 << 17) | (1 << 18); /* RXD & TXD */984if (flags & ATMEL_USART_RTS) pin_mask |= (1 << 19);985if (flags & ATMEL_USART_CTS) pin_mask |= (1 << 20);986if (flags & ATMEL_USART_CLK) pin_mask |= (1 << 16);987988select_peripheral(PIOA, pin_mask, PERIPH_A, AT32_GPIOF_PULLUP);989}990991static inline void configure_usart2_pins(int flags)992{993u32 pin_mask = (1 << 26) | (1 << 27); /* RXD & TXD */994if (flags & ATMEL_USART_RTS) pin_mask |= (1 << 30);995if (flags & ATMEL_USART_CTS) pin_mask |= (1 << 29);996if (flags & ATMEL_USART_CLK) pin_mask |= (1 << 28);997998select_peripheral(PIOB, pin_mask, PERIPH_B, AT32_GPIOF_PULLUP);999}10001001static inline void configure_usart3_pins(int flags)1002{1003u32 pin_mask = (1 << 18) | (1 << 17); /* RXD & TXD */1004if (flags & ATMEL_USART_RTS) pin_mask |= (1 << 16);1005if (flags & ATMEL_USART_CTS) pin_mask |= (1 << 15);1006if (flags & ATMEL_USART_CLK) pin_mask |= (1 << 19);10071008select_peripheral(PIOB, pin_mask, PERIPH_B, AT32_GPIOF_PULLUP);1009}10101011static struct platform_device *__initdata at32_usarts[4];10121013void __init at32_map_usart(unsigned int hw_id, unsigned int line, int flags)1014{1015struct platform_device *pdev;1016struct atmel_uart_data *pdata;10171018switch (hw_id) {1019case 0:1020pdev = &atmel_usart0_device;1021configure_usart0_pins(flags);1022break;1023case 1:1024pdev = &atmel_usart1_device;1025configure_usart1_pins(flags);1026break;1027case 2:1028pdev = &atmel_usart2_device;1029configure_usart2_pins(flags);1030break;1031case 3:1032pdev = &atmel_usart3_device;1033configure_usart3_pins(flags);1034break;1035default:1036return;1037}10381039if (PXSEG(pdev->resource[0].start) == P4SEG) {1040/* Addresses in the P4 segment are permanently mapped 1:1 */1041struct atmel_uart_data *data = pdev->dev.platform_data;1042data->regs = (void __iomem *)pdev->resource[0].start;1043}10441045pdev->id = line;1046pdata = pdev->dev.platform_data;1047pdata->num = line;1048at32_usarts[line] = pdev;1049}10501051struct platform_device *__init at32_add_device_usart(unsigned int id)1052{1053platform_device_register(at32_usarts[id]);1054return at32_usarts[id];1055}10561057struct platform_device *atmel_default_console_device;10581059void __init at32_setup_serial_console(unsigned int usart_id)1060{1061atmel_default_console_device = at32_usarts[usart_id];1062}10631064/* --------------------------------------------------------------------1065* Ethernet1066* -------------------------------------------------------------------- */10671068#ifdef CONFIG_CPU_AT32AP70001069static struct eth_platform_data macb0_data;1070static struct resource macb0_resource[] = {1071PBMEM(0xfff01800),1072IRQ(25),1073};1074DEFINE_DEV_DATA(macb, 0);1075DEV_CLK(hclk, macb0, hsb, 8);1076DEV_CLK(pclk, macb0, pbb, 6);10771078static struct eth_platform_data macb1_data;1079static struct resource macb1_resource[] = {1080PBMEM(0xfff01c00),1081IRQ(26),1082};1083DEFINE_DEV_DATA(macb, 1);1084DEV_CLK(hclk, macb1, hsb, 9);1085DEV_CLK(pclk, macb1, pbb, 7);10861087struct platform_device *__init1088at32_add_device_eth(unsigned int id, struct eth_platform_data *data)1089{1090struct platform_device *pdev;1091u32 pin_mask;10921093switch (id) {1094case 0:1095pdev = &macb0_device;10961097pin_mask = (1 << 3); /* TXD0 */1098pin_mask |= (1 << 4); /* TXD1 */1099pin_mask |= (1 << 7); /* TXEN */1100pin_mask |= (1 << 8); /* TXCK */1101pin_mask |= (1 << 9); /* RXD0 */1102pin_mask |= (1 << 10); /* RXD1 */1103pin_mask |= (1 << 13); /* RXER */1104pin_mask |= (1 << 15); /* RXDV */1105pin_mask |= (1 << 16); /* MDC */1106pin_mask |= (1 << 17); /* MDIO */11071108if (!data->is_rmii) {1109pin_mask |= (1 << 0); /* COL */1110pin_mask |= (1 << 1); /* CRS */1111pin_mask |= (1 << 2); /* TXER */1112pin_mask |= (1 << 5); /* TXD2 */1113pin_mask |= (1 << 6); /* TXD3 */1114pin_mask |= (1 << 11); /* RXD2 */1115pin_mask |= (1 << 12); /* RXD3 */1116pin_mask |= (1 << 14); /* RXCK */1117#ifndef CONFIG_BOARD_MIMC2001118pin_mask |= (1 << 18); /* SPD */1119#endif1120}11211122select_peripheral(PIOC, pin_mask, PERIPH_A, 0);11231124break;11251126case 1:1127pdev = &macb1_device;11281129pin_mask = (1 << 13); /* TXD0 */1130pin_mask |= (1 << 14); /* TXD1 */1131pin_mask |= (1 << 11); /* TXEN */1132pin_mask |= (1 << 12); /* TXCK */1133pin_mask |= (1 << 10); /* RXD0 */1134pin_mask |= (1 << 6); /* RXD1 */1135pin_mask |= (1 << 5); /* RXER */1136pin_mask |= (1 << 4); /* RXDV */1137pin_mask |= (1 << 3); /* MDC */1138pin_mask |= (1 << 2); /* MDIO */11391140#ifndef CONFIG_BOARD_MIMC2001141if (!data->is_rmii)1142pin_mask |= (1 << 15); /* SPD */1143#endif11441145select_peripheral(PIOD, pin_mask, PERIPH_B, 0);11461147if (!data->is_rmii) {1148pin_mask = (1 << 19); /* COL */1149pin_mask |= (1 << 23); /* CRS */1150pin_mask |= (1 << 26); /* TXER */1151pin_mask |= (1 << 27); /* TXD2 */1152pin_mask |= (1 << 28); /* TXD3 */1153pin_mask |= (1 << 29); /* RXD2 */1154pin_mask |= (1 << 30); /* RXD3 */1155pin_mask |= (1 << 24); /* RXCK */11561157select_peripheral(PIOC, pin_mask, PERIPH_B, 0);1158}1159break;11601161default:1162return NULL;1163}11641165memcpy(pdev->dev.platform_data, data, sizeof(struct eth_platform_data));1166platform_device_register(pdev);11671168return pdev;1169}1170#endif11711172/* --------------------------------------------------------------------1173* SPI1174* -------------------------------------------------------------------- */1175static struct resource atmel_spi0_resource[] = {1176PBMEM(0xffe00000),1177IRQ(3),1178};1179DEFINE_DEV(atmel_spi, 0);1180DEV_CLK(spi_clk, atmel_spi0, pba, 0);11811182static struct resource atmel_spi1_resource[] = {1183PBMEM(0xffe00400),1184IRQ(4),1185};1186DEFINE_DEV(atmel_spi, 1);1187DEV_CLK(spi_clk, atmel_spi1, pba, 1);11881189void __init1190at32_spi_setup_slaves(unsigned int bus_num, struct spi_board_info *b, unsigned int n)1191{1192/*1193* Manage the chipselects as GPIOs, normally using the same pins1194* the SPI controller expects; but boards can use other pins.1195*/1196static u8 __initdata spi_pins[][4] = {1197{ GPIO_PIN_PA(3), GPIO_PIN_PA(4),1198GPIO_PIN_PA(5), GPIO_PIN_PA(20) },1199{ GPIO_PIN_PB(2), GPIO_PIN_PB(3),1200GPIO_PIN_PB(4), GPIO_PIN_PA(27) },1201};1202unsigned int pin, mode;12031204/* There are only 2 SPI controllers */1205if (bus_num > 1)1206return;12071208for (; n; n--, b++) {1209b->bus_num = bus_num;1210if (b->chip_select >= 4)1211continue;1212pin = (unsigned)b->controller_data;1213if (!pin) {1214pin = spi_pins[bus_num][b->chip_select];1215b->controller_data = (void *)pin;1216}1217mode = AT32_GPIOF_OUTPUT;1218if (!(b->mode & SPI_CS_HIGH))1219mode |= AT32_GPIOF_HIGH;1220at32_select_gpio(pin, mode);1221}1222}12231224struct platform_device *__init1225at32_add_device_spi(unsigned int id, struct spi_board_info *b, unsigned int n)1226{1227struct platform_device *pdev;1228u32 pin_mask;12291230switch (id) {1231case 0:1232pdev = &atmel_spi0_device;1233pin_mask = (1 << 1) | (1 << 2); /* MOSI & SCK */12341235/* pullup MISO so a level is always defined */1236select_peripheral(PIOA, (1 << 0), PERIPH_A, AT32_GPIOF_PULLUP);1237select_peripheral(PIOA, pin_mask, PERIPH_A, 0);12381239at32_spi_setup_slaves(0, b, n);1240break;12411242case 1:1243pdev = &atmel_spi1_device;1244pin_mask = (1 << 1) | (1 << 5); /* MOSI */12451246/* pullup MISO so a level is always defined */1247select_peripheral(PIOB, (1 << 0), PERIPH_B, AT32_GPIOF_PULLUP);1248select_peripheral(PIOB, pin_mask, PERIPH_B, 0);12491250at32_spi_setup_slaves(1, b, n);1251break;12521253default:1254return NULL;1255}12561257spi_register_board_info(b, n);1258platform_device_register(pdev);1259return pdev;1260}12611262/* --------------------------------------------------------------------1263* TWI1264* -------------------------------------------------------------------- */1265static struct resource atmel_twi0_resource[] __initdata = {1266PBMEM(0xffe00800),1267IRQ(5),1268};1269static struct clk atmel_twi0_pclk = {1270.name = "twi_pclk",1271.parent = &pba_clk,1272.mode = pba_clk_mode,1273.get_rate = pba_clk_get_rate,1274.index = 2,1275};12761277struct platform_device *__init at32_add_device_twi(unsigned int id,1278struct i2c_board_info *b,1279unsigned int n)1280{1281struct platform_device *pdev;1282u32 pin_mask;12831284if (id != 0)1285return NULL;12861287pdev = platform_device_alloc("atmel_twi", id);1288if (!pdev)1289return NULL;12901291if (platform_device_add_resources(pdev, atmel_twi0_resource,1292ARRAY_SIZE(atmel_twi0_resource)))1293goto err_add_resources;12941295pin_mask = (1 << 6) | (1 << 7); /* SDA & SDL */12961297select_peripheral(PIOA, pin_mask, PERIPH_A, 0);12981299atmel_twi0_pclk.dev = &pdev->dev;13001301if (b)1302i2c_register_board_info(id, b, n);13031304platform_device_add(pdev);1305return pdev;13061307err_add_resources:1308platform_device_put(pdev);1309return NULL;1310}13111312/* --------------------------------------------------------------------1313* MMC1314* -------------------------------------------------------------------- */1315static struct resource atmel_mci0_resource[] __initdata = {1316PBMEM(0xfff02400),1317IRQ(28),1318};1319static struct clk atmel_mci0_pclk = {1320.name = "mci_clk",1321.parent = &pbb_clk,1322.mode = pbb_clk_mode,1323.get_rate = pbb_clk_get_rate,1324.index = 9,1325};13261327struct platform_device *__init1328at32_add_device_mci(unsigned int id, struct mci_platform_data *data)1329{1330struct platform_device *pdev;1331struct mci_dma_data *slave;1332u32 pioa_mask;1333u32 piob_mask;13341335if (id != 0 || !data)1336return NULL;13371338/* Must have at least one usable slot */1339if (!data->slot[0].bus_width && !data->slot[1].bus_width)1340return NULL;13411342pdev = platform_device_alloc("atmel_mci", id);1343if (!pdev)1344goto fail;13451346if (platform_device_add_resources(pdev, atmel_mci0_resource,1347ARRAY_SIZE(atmel_mci0_resource)))1348goto fail;13491350slave = kzalloc(sizeof(struct mci_dma_data), GFP_KERNEL);1351if (!slave)1352goto fail;13531354slave->sdata.dma_dev = &dw_dmac0_device.dev;1355slave->sdata.reg_width = DW_DMA_SLAVE_WIDTH_32BIT;1356slave->sdata.cfg_hi = (DWC_CFGH_SRC_PER(0)1357| DWC_CFGH_DST_PER(1));1358slave->sdata.cfg_lo &= ~(DWC_CFGL_HS_DST_POL1359| DWC_CFGL_HS_SRC_POL);13601361data->dma_slave = slave;13621363if (platform_device_add_data(pdev, data,1364sizeof(struct mci_platform_data)))1365goto fail_free;13661367/* CLK line is common to both slots */1368pioa_mask = 1 << 10;13691370switch (data->slot[0].bus_width) {1371case 4:1372pioa_mask |= 1 << 13; /* DATA1 */1373pioa_mask |= 1 << 14; /* DATA2 */1374pioa_mask |= 1 << 15; /* DATA3 */1375/* fall through */1376case 1:1377pioa_mask |= 1 << 11; /* CMD */1378pioa_mask |= 1 << 12; /* DATA0 */13791380if (gpio_is_valid(data->slot[0].detect_pin))1381at32_select_gpio(data->slot[0].detect_pin, 0);1382if (gpio_is_valid(data->slot[0].wp_pin))1383at32_select_gpio(data->slot[0].wp_pin, 0);1384break;1385case 0:1386/* Slot is unused */1387break;1388default:1389goto fail_free;1390}13911392select_peripheral(PIOA, pioa_mask, PERIPH_A, 0);1393piob_mask = 0;13941395switch (data->slot[1].bus_width) {1396case 4:1397piob_mask |= 1 << 8; /* DATA1 */1398piob_mask |= 1 << 9; /* DATA2 */1399piob_mask |= 1 << 10; /* DATA3 */1400/* fall through */1401case 1:1402piob_mask |= 1 << 6; /* CMD */1403piob_mask |= 1 << 7; /* DATA0 */1404select_peripheral(PIOB, piob_mask, PERIPH_B, 0);14051406if (gpio_is_valid(data->slot[1].detect_pin))1407at32_select_gpio(data->slot[1].detect_pin, 0);1408if (gpio_is_valid(data->slot[1].wp_pin))1409at32_select_gpio(data->slot[1].wp_pin, 0);1410break;1411case 0:1412/* Slot is unused */1413break;1414default:1415if (!data->slot[0].bus_width)1416goto fail_free;14171418data->slot[1].bus_width = 0;1419break;1420}14211422atmel_mci0_pclk.dev = &pdev->dev;14231424platform_device_add(pdev);1425return pdev;14261427fail_free:1428kfree(slave);1429fail:1430data->dma_slave = NULL;1431platform_device_put(pdev);1432return NULL;1433}14341435/* --------------------------------------------------------------------1436* LCDC1437* -------------------------------------------------------------------- */1438#if defined(CONFIG_CPU_AT32AP7000) || defined(CONFIG_CPU_AT32AP7002)1439static struct atmel_lcdfb_info atmel_lcdfb0_data;1440static struct resource atmel_lcdfb0_resource[] = {1441{1442.start = 0xff000000,1443.end = 0xff000fff,1444.flags = IORESOURCE_MEM,1445},1446IRQ(1),1447{1448/* Placeholder for pre-allocated fb memory */1449.start = 0x00000000,1450.end = 0x00000000,1451.flags = 0,1452},1453};1454DEFINE_DEV_DATA(atmel_lcdfb, 0);1455DEV_CLK(hck1, atmel_lcdfb0, hsb, 7);1456static struct clk atmel_lcdfb0_pixclk = {1457.name = "lcdc_clk",1458.dev = &atmel_lcdfb0_device.dev,1459.mode = genclk_mode,1460.get_rate = genclk_get_rate,1461.set_rate = genclk_set_rate,1462.set_parent = genclk_set_parent,1463.index = 7,1464};14651466struct platform_device *__init1467at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_info *data,1468unsigned long fbmem_start, unsigned long fbmem_len,1469u64 pin_mask)1470{1471struct platform_device *pdev;1472struct atmel_lcdfb_info *info;1473struct fb_monspecs *monspecs;1474struct fb_videomode *modedb;1475unsigned int modedb_size;1476u32 portc_mask, portd_mask, porte_mask;14771478/*1479* Do a deep copy of the fb data, monspecs and modedb. Make1480* sure all allocations are done before setting up the1481* portmux.1482*/1483monspecs = kmemdup(data->default_monspecs,1484sizeof(struct fb_monspecs), GFP_KERNEL);1485if (!monspecs)1486return NULL;14871488modedb_size = sizeof(struct fb_videomode) * monspecs->modedb_len;1489modedb = kmemdup(monspecs->modedb, modedb_size, GFP_KERNEL);1490if (!modedb)1491goto err_dup_modedb;1492monspecs->modedb = modedb;14931494switch (id) {1495case 0:1496pdev = &atmel_lcdfb0_device;14971498if (pin_mask == 0ULL)1499/* Default to "full" lcdc control signals and 24bit */1500pin_mask = ATMEL_LCDC_PRI_24BIT | ATMEL_LCDC_PRI_CONTROL;15011502/* LCDC on port C */1503portc_mask = pin_mask & 0xfff80000;1504select_peripheral(PIOC, portc_mask, PERIPH_A, 0);15051506/* LCDC on port D */1507portd_mask = pin_mask & 0x0003ffff;1508select_peripheral(PIOD, portd_mask, PERIPH_A, 0);15091510/* LCDC on port E */1511porte_mask = (pin_mask >> 32) & 0x0007ffff;1512select_peripheral(PIOE, porte_mask, PERIPH_B, 0);15131514clk_set_parent(&atmel_lcdfb0_pixclk, &pll0);1515clk_set_rate(&atmel_lcdfb0_pixclk, clk_get_rate(&pll0));1516break;15171518default:1519goto err_invalid_id;1520}15211522if (fbmem_len) {1523pdev->resource[2].start = fbmem_start;1524pdev->resource[2].end = fbmem_start + fbmem_len - 1;1525pdev->resource[2].flags = IORESOURCE_MEM;1526}15271528info = pdev->dev.platform_data;1529memcpy(info, data, sizeof(struct atmel_lcdfb_info));1530info->default_monspecs = monspecs;15311532platform_device_register(pdev);1533return pdev;15341535err_invalid_id:1536kfree(modedb);1537err_dup_modedb:1538kfree(monspecs);1539return NULL;1540}1541#endif15421543/* --------------------------------------------------------------------1544* PWM1545* -------------------------------------------------------------------- */1546static struct resource atmel_pwm0_resource[] __initdata = {1547PBMEM(0xfff01400),1548IRQ(24),1549};1550static struct clk atmel_pwm0_mck = {1551.name = "pwm_clk",1552.parent = &pbb_clk,1553.mode = pbb_clk_mode,1554.get_rate = pbb_clk_get_rate,1555.index = 5,1556};15571558struct platform_device *__init at32_add_device_pwm(u32 mask)1559{1560struct platform_device *pdev;1561u32 pin_mask;15621563if (!mask)1564return NULL;15651566pdev = platform_device_alloc("atmel_pwm", 0);1567if (!pdev)1568return NULL;15691570if (platform_device_add_resources(pdev, atmel_pwm0_resource,1571ARRAY_SIZE(atmel_pwm0_resource)))1572goto out_free_pdev;15731574if (platform_device_add_data(pdev, &mask, sizeof(mask)))1575goto out_free_pdev;15761577pin_mask = 0;1578if (mask & (1 << 0))1579pin_mask |= (1 << 28);1580if (mask & (1 << 1))1581pin_mask |= (1 << 29);1582if (pin_mask > 0)1583select_peripheral(PIOA, pin_mask, PERIPH_A, 0);15841585pin_mask = 0;1586if (mask & (1 << 2))1587pin_mask |= (1 << 21);1588if (mask & (1 << 3))1589pin_mask |= (1 << 22);1590if (pin_mask > 0)1591select_peripheral(PIOA, pin_mask, PERIPH_B, 0);15921593atmel_pwm0_mck.dev = &pdev->dev;15941595platform_device_add(pdev);15961597return pdev;15981599out_free_pdev:1600platform_device_put(pdev);1601return NULL;1602}16031604/* --------------------------------------------------------------------1605* SSC1606* -------------------------------------------------------------------- */1607static struct resource ssc0_resource[] = {1608PBMEM(0xffe01c00),1609IRQ(10),1610};1611DEFINE_DEV(ssc, 0);1612DEV_CLK(pclk, ssc0, pba, 7);16131614static struct resource ssc1_resource[] = {1615PBMEM(0xffe02000),1616IRQ(11),1617};1618DEFINE_DEV(ssc, 1);1619DEV_CLK(pclk, ssc1, pba, 8);16201621static struct resource ssc2_resource[] = {1622PBMEM(0xffe02400),1623IRQ(12),1624};1625DEFINE_DEV(ssc, 2);1626DEV_CLK(pclk, ssc2, pba, 9);16271628struct platform_device *__init1629at32_add_device_ssc(unsigned int id, unsigned int flags)1630{1631struct platform_device *pdev;1632u32 pin_mask = 0;16331634switch (id) {1635case 0:1636pdev = &ssc0_device;1637if (flags & ATMEL_SSC_RF)1638pin_mask |= (1 << 21); /* RF */1639if (flags & ATMEL_SSC_RK)1640pin_mask |= (1 << 22); /* RK */1641if (flags & ATMEL_SSC_TK)1642pin_mask |= (1 << 23); /* TK */1643if (flags & ATMEL_SSC_TF)1644pin_mask |= (1 << 24); /* TF */1645if (flags & ATMEL_SSC_TD)1646pin_mask |= (1 << 25); /* TD */1647if (flags & ATMEL_SSC_RD)1648pin_mask |= (1 << 26); /* RD */16491650if (pin_mask > 0)1651select_peripheral(PIOA, pin_mask, PERIPH_A, 0);16521653break;1654case 1:1655pdev = &ssc1_device;1656if (flags & ATMEL_SSC_RF)1657pin_mask |= (1 << 0); /* RF */1658if (flags & ATMEL_SSC_RK)1659pin_mask |= (1 << 1); /* RK */1660if (flags & ATMEL_SSC_TK)1661pin_mask |= (1 << 2); /* TK */1662if (flags & ATMEL_SSC_TF)1663pin_mask |= (1 << 3); /* TF */1664if (flags & ATMEL_SSC_TD)1665pin_mask |= (1 << 4); /* TD */1666if (flags & ATMEL_SSC_RD)1667pin_mask |= (1 << 5); /* RD */16681669if (pin_mask > 0)1670select_peripheral(PIOA, pin_mask, PERIPH_B, 0);16711672break;1673case 2:1674pdev = &ssc2_device;1675if (flags & ATMEL_SSC_TD)1676pin_mask |= (1 << 13); /* TD */1677if (flags & ATMEL_SSC_RD)1678pin_mask |= (1 << 14); /* RD */1679if (flags & ATMEL_SSC_TK)1680pin_mask |= (1 << 15); /* TK */1681if (flags & ATMEL_SSC_TF)1682pin_mask |= (1 << 16); /* TF */1683if (flags & ATMEL_SSC_RF)1684pin_mask |= (1 << 17); /* RF */1685if (flags & ATMEL_SSC_RK)1686pin_mask |= (1 << 18); /* RK */16871688if (pin_mask > 0)1689select_peripheral(PIOB, pin_mask, PERIPH_A, 0);16901691break;1692default:1693return NULL;1694}16951696platform_device_register(pdev);1697return pdev;1698}16991700/* --------------------------------------------------------------------1701* USB Device Controller1702* -------------------------------------------------------------------- */1703static struct resource usba0_resource[] __initdata = {1704{1705.start = 0xff300000,1706.end = 0xff3fffff,1707.flags = IORESOURCE_MEM,1708}, {1709.start = 0xfff03000,1710.end = 0xfff033ff,1711.flags = IORESOURCE_MEM,1712},1713IRQ(31),1714};1715static struct clk usba0_pclk = {1716.name = "pclk",1717.parent = &pbb_clk,1718.mode = pbb_clk_mode,1719.get_rate = pbb_clk_get_rate,1720.index = 12,1721};1722static struct clk usba0_hclk = {1723.name = "hclk",1724.parent = &hsb_clk,1725.mode = hsb_clk_mode,1726.get_rate = hsb_clk_get_rate,1727.index = 6,1728};17291730#define EP(nam, idx, maxpkt, maxbk, dma, isoc) \1731[idx] = { \1732.name = nam, \1733.index = idx, \1734.fifo_size = maxpkt, \1735.nr_banks = maxbk, \1736.can_dma = dma, \1737.can_isoc = isoc, \1738}17391740static struct usba_ep_data at32_usba_ep[] __initdata = {1741EP("ep0", 0, 64, 1, 0, 0),1742EP("ep1", 1, 512, 2, 1, 1),1743EP("ep2", 2, 512, 2, 1, 1),1744EP("ep3-int", 3, 64, 3, 1, 0),1745EP("ep4-int", 4, 64, 3, 1, 0),1746EP("ep5", 5, 1024, 3, 1, 1),1747EP("ep6", 6, 1024, 3, 1, 1),1748};17491750#undef EP17511752struct platform_device *__init1753at32_add_device_usba(unsigned int id, struct usba_platform_data *data)1754{1755/*1756* pdata doesn't have room for any endpoints, so we need to1757* append room for the ones we need right after it.1758*/1759struct {1760struct usba_platform_data pdata;1761struct usba_ep_data ep[7];1762} usba_data;1763struct platform_device *pdev;17641765if (id != 0)1766return NULL;17671768pdev = platform_device_alloc("atmel_usba_udc", 0);1769if (!pdev)1770return NULL;17711772if (platform_device_add_resources(pdev, usba0_resource,1773ARRAY_SIZE(usba0_resource)))1774goto out_free_pdev;17751776if (data) {1777usba_data.pdata.vbus_pin = data->vbus_pin;1778usba_data.pdata.vbus_pin_inverted = data->vbus_pin_inverted;1779} else {1780usba_data.pdata.vbus_pin = -EINVAL;1781usba_data.pdata.vbus_pin_inverted = -EINVAL;1782}17831784data = &usba_data.pdata;1785data->num_ep = ARRAY_SIZE(at32_usba_ep);1786memcpy(data->ep, at32_usba_ep, sizeof(at32_usba_ep));17871788if (platform_device_add_data(pdev, data, sizeof(usba_data)))1789goto out_free_pdev;17901791if (gpio_is_valid(data->vbus_pin))1792at32_select_gpio(data->vbus_pin, 0);17931794usba0_pclk.dev = &pdev->dev;1795usba0_hclk.dev = &pdev->dev;17961797platform_device_add(pdev);17981799return pdev;18001801out_free_pdev:1802platform_device_put(pdev);1803return NULL;1804}18051806/* --------------------------------------------------------------------1807* IDE / CompactFlash1808* -------------------------------------------------------------------- */1809#if defined(CONFIG_CPU_AT32AP7000) || defined(CONFIG_CPU_AT32AP7001)1810static struct resource at32_smc_cs4_resource[] __initdata = {1811{1812.start = 0x04000000,1813.end = 0x07ffffff,1814.flags = IORESOURCE_MEM,1815},1816IRQ(~0UL), /* Magic IRQ will be overridden */1817};1818static struct resource at32_smc_cs5_resource[] __initdata = {1819{1820.start = 0x20000000,1821.end = 0x23ffffff,1822.flags = IORESOURCE_MEM,1823},1824IRQ(~0UL), /* Magic IRQ will be overridden */1825};18261827static int __init at32_init_ide_or_cf(struct platform_device *pdev,1828unsigned int cs, unsigned int extint)1829{1830static unsigned int extint_pin_map[4] __initdata = {1831(1 << 25),1832(1 << 26),1833(1 << 27),1834(1 << 28),1835};1836static bool common_pins_initialized __initdata = false;1837unsigned int extint_pin;1838int ret;1839u32 pin_mask;18401841if (extint >= ARRAY_SIZE(extint_pin_map))1842return -EINVAL;1843extint_pin = extint_pin_map[extint];18441845switch (cs) {1846case 4:1847ret = platform_device_add_resources(pdev,1848at32_smc_cs4_resource,1849ARRAY_SIZE(at32_smc_cs4_resource));1850if (ret)1851return ret;18521853/* NCS4 -> OE_N */1854select_peripheral(PIOE, (1 << 21), PERIPH_A, 0);1855hmatrix_sfr_set_bits(HMATRIX_SLAVE_EBI, HMATRIX_EBI_CF0_ENABLE);1856break;1857case 5:1858ret = platform_device_add_resources(pdev,1859at32_smc_cs5_resource,1860ARRAY_SIZE(at32_smc_cs5_resource));1861if (ret)1862return ret;18631864/* NCS5 -> OE_N */1865select_peripheral(PIOE, (1 << 22), PERIPH_A, 0);1866hmatrix_sfr_set_bits(HMATRIX_SLAVE_EBI, HMATRIX_EBI_CF1_ENABLE);1867break;1868default:1869return -EINVAL;1870}18711872if (!common_pins_initialized) {1873pin_mask = (1 << 19); /* CFCE1 -> CS0_N */1874pin_mask |= (1 << 20); /* CFCE2 -> CS1_N */1875pin_mask |= (1 << 23); /* CFRNW -> DIR */1876pin_mask |= (1 << 24); /* NWAIT <- IORDY */18771878select_peripheral(PIOE, pin_mask, PERIPH_A, 0);18791880common_pins_initialized = true;1881}18821883select_peripheral(PIOB, extint_pin, PERIPH_A, AT32_GPIOF_DEGLITCH);18841885pdev->resource[1].start = EIM_IRQ_BASE + extint;1886pdev->resource[1].end = pdev->resource[1].start;18871888return 0;1889}18901891struct platform_device *__init1892at32_add_device_ide(unsigned int id, unsigned int extint,1893struct ide_platform_data *data)1894{1895struct platform_device *pdev;18961897pdev = platform_device_alloc("at32_ide", id);1898if (!pdev)1899goto fail;19001901if (platform_device_add_data(pdev, data,1902sizeof(struct ide_platform_data)))1903goto fail;19041905if (at32_init_ide_or_cf(pdev, data->cs, extint))1906goto fail;19071908platform_device_add(pdev);1909return pdev;19101911fail:1912platform_device_put(pdev);1913return NULL;1914}19151916struct platform_device *__init1917at32_add_device_cf(unsigned int id, unsigned int extint,1918struct cf_platform_data *data)1919{1920struct platform_device *pdev;19211922pdev = platform_device_alloc("at32_cf", id);1923if (!pdev)1924goto fail;19251926if (platform_device_add_data(pdev, data,1927sizeof(struct cf_platform_data)))1928goto fail;19291930if (at32_init_ide_or_cf(pdev, data->cs, extint))1931goto fail;19321933if (gpio_is_valid(data->detect_pin))1934at32_select_gpio(data->detect_pin, AT32_GPIOF_DEGLITCH);1935if (gpio_is_valid(data->reset_pin))1936at32_select_gpio(data->reset_pin, 0);1937if (gpio_is_valid(data->vcc_pin))1938at32_select_gpio(data->vcc_pin, 0);1939/* READY is used as extint, so we can't select it as gpio */19401941platform_device_add(pdev);1942return pdev;19431944fail:1945platform_device_put(pdev);1946return NULL;1947}1948#endif19491950/* --------------------------------------------------------------------1951* NAND Flash / SmartMedia1952* -------------------------------------------------------------------- */1953static struct resource smc_cs3_resource[] __initdata = {1954{1955.start = 0x0c000000,1956.end = 0x0fffffff,1957.flags = IORESOURCE_MEM,1958}, {1959.start = 0xfff03c00,1960.end = 0xfff03fff,1961.flags = IORESOURCE_MEM,1962},1963};19641965struct platform_device *__init1966at32_add_device_nand(unsigned int id, struct atmel_nand_data *data)1967{1968struct platform_device *pdev;19691970if (id != 0 || !data)1971return NULL;19721973pdev = platform_device_alloc("atmel_nand", id);1974if (!pdev)1975goto fail;19761977if (platform_device_add_resources(pdev, smc_cs3_resource,1978ARRAY_SIZE(smc_cs3_resource)))1979goto fail;19801981if (platform_device_add_data(pdev, data,1982sizeof(struct atmel_nand_data)))1983goto fail;19841985hmatrix_sfr_set_bits(HMATRIX_SLAVE_EBI, HMATRIX_EBI_NAND_ENABLE);1986if (data->enable_pin)1987at32_select_gpio(data->enable_pin,1988AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);1989if (data->rdy_pin)1990at32_select_gpio(data->rdy_pin, 0);1991if (data->det_pin)1992at32_select_gpio(data->det_pin, 0);19931994platform_device_add(pdev);1995return pdev;19961997fail:1998platform_device_put(pdev);1999return NULL;2000}20012002/* --------------------------------------------------------------------2003* AC97C2004* -------------------------------------------------------------------- */2005static struct resource atmel_ac97c0_resource[] __initdata = {2006PBMEM(0xfff02800),2007IRQ(29),2008};2009static struct clk atmel_ac97c0_pclk = {2010.name = "pclk",2011.parent = &pbb_clk,2012.mode = pbb_clk_mode,2013.get_rate = pbb_clk_get_rate,2014.index = 10,2015};20162017struct platform_device *__init2018at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data,2019unsigned int flags)2020{2021struct platform_device *pdev;2022struct dw_dma_slave *rx_dws;2023struct dw_dma_slave *tx_dws;2024struct ac97c_platform_data _data;2025u32 pin_mask;20262027if (id != 0)2028return NULL;20292030pdev = platform_device_alloc("atmel_ac97c", id);2031if (!pdev)2032return NULL;20332034if (platform_device_add_resources(pdev, atmel_ac97c0_resource,2035ARRAY_SIZE(atmel_ac97c0_resource)))2036goto out_free_resources;20372038if (!data) {2039data = &_data;2040memset(data, 0, sizeof(struct ac97c_platform_data));2041data->reset_pin = -ENODEV;2042}20432044rx_dws = &data->rx_dws;2045tx_dws = &data->tx_dws;20462047/* Check if DMA slave interface for capture should be configured. */2048if (flags & AC97C_CAPTURE) {2049rx_dws->dma_dev = &dw_dmac0_device.dev;2050rx_dws->reg_width = DW_DMA_SLAVE_WIDTH_16BIT;2051rx_dws->cfg_hi = DWC_CFGH_SRC_PER(3);2052rx_dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL);2053rx_dws->src_master = 0;2054rx_dws->dst_master = 1;2055rx_dws->src_msize = DW_DMA_MSIZE_1;2056rx_dws->dst_msize = DW_DMA_MSIZE_1;2057rx_dws->fc = DW_DMA_FC_D_P2M;2058}20592060/* Check if DMA slave interface for playback should be configured. */2061if (flags & AC97C_PLAYBACK) {2062tx_dws->dma_dev = &dw_dmac0_device.dev;2063tx_dws->reg_width = DW_DMA_SLAVE_WIDTH_16BIT;2064tx_dws->cfg_hi = DWC_CFGH_DST_PER(4);2065tx_dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL);2066tx_dws->src_master = 0;2067tx_dws->dst_master = 1;2068tx_dws->src_msize = DW_DMA_MSIZE_1;2069tx_dws->dst_msize = DW_DMA_MSIZE_1;2070tx_dws->fc = DW_DMA_FC_D_M2P;2071}20722073if (platform_device_add_data(pdev, data,2074sizeof(struct ac97c_platform_data)))2075goto out_free_resources;20762077/* SDO | SYNC | SCLK | SDI */2078pin_mask = (1 << 20) | (1 << 21) | (1 << 22) | (1 << 23);20792080select_peripheral(PIOB, pin_mask, PERIPH_B, 0);20812082if (gpio_is_valid(data->reset_pin))2083at32_select_gpio(data->reset_pin, AT32_GPIOF_OUTPUT2084| AT32_GPIOF_HIGH);20852086atmel_ac97c0_pclk.dev = &pdev->dev;20872088platform_device_add(pdev);2089return pdev;20902091out_free_resources:2092platform_device_put(pdev);2093return NULL;2094}20952096/* --------------------------------------------------------------------2097* ABDAC2098* -------------------------------------------------------------------- */2099static struct resource abdac0_resource[] __initdata = {2100PBMEM(0xfff02000),2101IRQ(27),2102};2103static struct clk abdac0_pclk = {2104.name = "pclk",2105.parent = &pbb_clk,2106.mode = pbb_clk_mode,2107.get_rate = pbb_clk_get_rate,2108.index = 8,2109};2110static struct clk abdac0_sample_clk = {2111.name = "sample_clk",2112.mode = genclk_mode,2113.get_rate = genclk_get_rate,2114.set_rate = genclk_set_rate,2115.set_parent = genclk_set_parent,2116.index = 6,2117};21182119struct platform_device *__init2120at32_add_device_abdac(unsigned int id, struct atmel_abdac_pdata *data)2121{2122struct platform_device *pdev;2123struct dw_dma_slave *dws;2124u32 pin_mask;21252126if (id != 0 || !data)2127return NULL;21282129pdev = platform_device_alloc("atmel_abdac", id);2130if (!pdev)2131return NULL;21322133if (platform_device_add_resources(pdev, abdac0_resource,2134ARRAY_SIZE(abdac0_resource)))2135goto out_free_resources;21362137dws = &data->dws;21382139dws->dma_dev = &dw_dmac0_device.dev;2140dws->reg_width = DW_DMA_SLAVE_WIDTH_32BIT;2141dws->cfg_hi = DWC_CFGH_DST_PER(2);2142dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL);2143dws->src_master = 0;2144dws->dst_master = 1;2145dws->src_msize = DW_DMA_MSIZE_1;2146dws->dst_msize = DW_DMA_MSIZE_1;2147dws->fc = DW_DMA_FC_D_M2P;21482149if (platform_device_add_data(pdev, data,2150sizeof(struct atmel_abdac_pdata)))2151goto out_free_resources;21522153pin_mask = (1 << 20) | (1 << 22); /* DATA1 & DATAN1 */2154pin_mask |= (1 << 21) | (1 << 23); /* DATA0 & DATAN0 */21552156select_peripheral(PIOB, pin_mask, PERIPH_A, 0);21572158abdac0_pclk.dev = &pdev->dev;2159abdac0_sample_clk.dev = &pdev->dev;21602161platform_device_add(pdev);2162return pdev;21632164out_free_resources:2165platform_device_put(pdev);2166return NULL;2167}21682169/* --------------------------------------------------------------------2170* GCLK2171* -------------------------------------------------------------------- */2172static struct clk gclk0 = {2173.name = "gclk0",2174.mode = genclk_mode,2175.get_rate = genclk_get_rate,2176.set_rate = genclk_set_rate,2177.set_parent = genclk_set_parent,2178.index = 0,2179};2180static struct clk gclk1 = {2181.name = "gclk1",2182.mode = genclk_mode,2183.get_rate = genclk_get_rate,2184.set_rate = genclk_set_rate,2185.set_parent = genclk_set_parent,2186.index = 1,2187};2188static struct clk gclk2 = {2189.name = "gclk2",2190.mode = genclk_mode,2191.get_rate = genclk_get_rate,2192.set_rate = genclk_set_rate,2193.set_parent = genclk_set_parent,2194.index = 2,2195};2196static struct clk gclk3 = {2197.name = "gclk3",2198.mode = genclk_mode,2199.get_rate = genclk_get_rate,2200.set_rate = genclk_set_rate,2201.set_parent = genclk_set_parent,2202.index = 3,2203};2204static struct clk gclk4 = {2205.name = "gclk4",2206.mode = genclk_mode,2207.get_rate = genclk_get_rate,2208.set_rate = genclk_set_rate,2209.set_parent = genclk_set_parent,2210.index = 4,2211};22122213static __initdata struct clk *init_clocks[] = {2214&osc32k,2215&osc0,2216&osc1,2217&pll0,2218&pll1,2219&cpu_clk,2220&hsb_clk,2221&pba_clk,2222&pbb_clk,2223&at32_pm_pclk,2224&at32_intc0_pclk,2225&at32_hmatrix_clk,2226&ebi_clk,2227&hramc_clk,2228&sdramc_clk,2229&smc0_pclk,2230&smc0_mck,2231&pdc_hclk,2232&pdc_pclk,2233&dw_dmac0_hclk,2234&pico_clk,2235&pio0_mck,2236&pio1_mck,2237&pio2_mck,2238&pio3_mck,2239&pio4_mck,2240&at32_tcb0_t0_clk,2241&at32_tcb1_t0_clk,2242&atmel_psif0_pclk,2243&atmel_psif1_pclk,2244&atmel_usart0_usart,2245&atmel_usart1_usart,2246&atmel_usart2_usart,2247&atmel_usart3_usart,2248&atmel_pwm0_mck,2249#if defined(CONFIG_CPU_AT32AP7000)2250&macb0_hclk,2251&macb0_pclk,2252&macb1_hclk,2253&macb1_pclk,2254#endif2255&atmel_spi0_spi_clk,2256&atmel_spi1_spi_clk,2257&atmel_twi0_pclk,2258&atmel_mci0_pclk,2259#if defined(CONFIG_CPU_AT32AP7000) || defined(CONFIG_CPU_AT32AP7002)2260&atmel_lcdfb0_hck1,2261&atmel_lcdfb0_pixclk,2262#endif2263&ssc0_pclk,2264&ssc1_pclk,2265&ssc2_pclk,2266&usba0_hclk,2267&usba0_pclk,2268&atmel_ac97c0_pclk,2269&abdac0_pclk,2270&abdac0_sample_clk,2271&gclk0,2272&gclk1,2273&gclk2,2274&gclk3,2275&gclk4,2276};22772278void __init setup_platform(void)2279{2280u32 cpu_mask = 0, hsb_mask = 0, pba_mask = 0, pbb_mask = 0;2281int i;22822283if (pm_readl(MCCTRL) & PM_BIT(PLLSEL)) {2284main_clock = &pll0;2285cpu_clk.parent = &pll0;2286} else {2287main_clock = &osc0;2288cpu_clk.parent = &osc0;2289}22902291if (pm_readl(PLL0) & PM_BIT(PLLOSC))2292pll0.parent = &osc1;2293if (pm_readl(PLL1) & PM_BIT(PLLOSC))2294pll1.parent = &osc1;22952296genclk_init_parent(&gclk0);2297genclk_init_parent(&gclk1);2298genclk_init_parent(&gclk2);2299genclk_init_parent(&gclk3);2300genclk_init_parent(&gclk4);2301#if defined(CONFIG_CPU_AT32AP7000) || defined(CONFIG_CPU_AT32AP7002)2302genclk_init_parent(&atmel_lcdfb0_pixclk);2303#endif2304genclk_init_parent(&abdac0_sample_clk);23052306/*2307* Build initial dynamic clock list by registering all clocks2308* from the array.2309* At the same time, turn on all clocks that have at least one2310* user already, and turn off everything else. We only do this2311* for module clocks, and even though it isn't particularly2312* pretty to check the address of the mode function, it should2313* do the trick...2314*/2315for (i = 0; i < ARRAY_SIZE(init_clocks); i++) {2316struct clk *clk = init_clocks[i];23172318/* first, register clock */2319at32_clk_register(clk);23202321if (clk->users == 0)2322continue;23232324if (clk->mode == &cpu_clk_mode)2325cpu_mask |= 1 << clk->index;2326else if (clk->mode == &hsb_clk_mode)2327hsb_mask |= 1 << clk->index;2328else if (clk->mode == &pba_clk_mode)2329pba_mask |= 1 << clk->index;2330else if (clk->mode == &pbb_clk_mode)2331pbb_mask |= 1 << clk->index;2332}23332334pm_writel(CPU_MASK, cpu_mask);2335pm_writel(HSB_MASK, hsb_mask);2336pm_writel(PBA_MASK, pba_mask);2337pm_writel(PBB_MASK, pbb_mask);23382339/* Initialize the port muxes */2340at32_init_pio(&pio0_device);2341at32_init_pio(&pio1_device);2342at32_init_pio(&pio2_device);2343at32_init_pio(&pio3_device);2344at32_init_pio(&pio4_device);2345}23462347struct gen_pool *sram_pool;23482349static int __init sram_init(void)2350{2351struct gen_pool *pool;23522353/* 1KiB granularity */2354pool = gen_pool_create(10, -1);2355if (!pool)2356goto fail;23572358if (gen_pool_add(pool, 0x24000000, 0x8000, -1))2359goto err_pool_add;23602361sram_pool = pool;2362return 0;23632364err_pool_add:2365gen_pool_destroy(pool);2366fail:2367pr_err("Failed to create SRAM pool\n");2368return -ENOMEM;2369}2370core_initcall(sram_init);237123722373