diff options
Diffstat (limited to 'ANDROID_3.4.5/arch/arm/mach-davinci')
80 files changed, 25051 insertions, 0 deletions
diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/Kconfig b/ANDROID_3.4.5/arch/arm/mach-davinci/Kconfig new file mode 100644 index 00000000..32d837d8 --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/Kconfig @@ -0,0 +1,276 @@ +if ARCH_DAVINCI + +config AINTC + bool + +config CP_INTC + bool + +config ARCH_DAVINCI_DMx + select CPU_ARM926T + bool + +menu "TI DaVinci Implementations" + +comment "DaVinci Core Type" + +config ARCH_DAVINCI_DM644x + bool "DaVinci 644x based system" + select AINTC + select ARCH_DAVINCI_DMx + +config ARCH_DAVINCI_DM355 + bool "DaVinci 355 based system" + select AINTC + select ARCH_DAVINCI_DMx + +config ARCH_DAVINCI_DM646x + bool "DaVinci 646x based system" + select AINTC + select ARCH_DAVINCI_DMx + +config ARCH_DAVINCI_DA830 + bool "DA830/OMAP-L137/AM17x based system" + select CP_INTC + select ARCH_DAVINCI_DA8XX + select CPU_DCACHE_WRITETHROUGH # needed on silicon revs 1.0, 1.1 + +config ARCH_DAVINCI_DA850 + bool "DA850/OMAP-L138/AM18x based system" + select CP_INTC + select ARCH_DAVINCI_DA8XX + select ARCH_HAS_CPUFREQ + +config ARCH_DAVINCI_DA8XX + select CPU_ARM926T + bool + +config ARCH_DAVINCI_DM365 + bool "DaVinci 365 based system" + select AINTC + select ARCH_DAVINCI_DMx + +config ARCH_DAVINCI_TNETV107X + select CPU_V6 + select CP_INTC + bool "TNETV107X based system" + +comment "DaVinci Board Type" + +config MACH_DAVINCI_EVM + bool "TI DM644x EVM" + default ARCH_DAVINCI_DM644x + depends on ARCH_DAVINCI_DM644x + select MISC_DEVICES + select EEPROM_AT24 + select I2C + help + Configure this option to specify the whether the board used + for development is a DM644x EVM + +config MACH_SFFSDR + bool "Lyrtech SFFSDR" + depends on ARCH_DAVINCI_DM644x + select MISC_DEVICES + select EEPROM_AT24 + select I2C + help + Say Y here to select the Lyrtech Small Form Factor + Software Defined Radio (SFFSDR) board. + +config MACH_NEUROS_OSD2 + bool "Neuros OSD2 Open Television Set Top Box" + depends on ARCH_DAVINCI_DM644x + help + Configure this option to specify the whether the board used + for development is a Neuros OSD2 Open Set Top Box. + +config MACH_DAVINCI_DM355_EVM + bool "TI DM355 EVM" + default ARCH_DAVINCI_DM355 + depends on ARCH_DAVINCI_DM355 + help + Configure this option to specify the whether the board used + for development is a DM355 EVM + +config MACH_DM355_LEOPARD + bool "DM355 Leopard board" + depends on ARCH_DAVINCI_DM355 + help + Configure this option to specify the whether the board used + for development is a DM355 Leopard board. + +config MACH_DAVINCI_DM6467_EVM + bool "TI DM6467 EVM" + default ARCH_DAVINCI_DM646x + depends on ARCH_DAVINCI_DM646x + select MACH_DAVINCI_DM6467TEVM + select MISC_DEVICES + select EEPROM_AT24 + select I2C + help + Configure this option to specify the whether the board used + for development is a DM6467 EVM + +config MACH_DAVINCI_DM6467TEVM + bool + +config MACH_DAVINCI_DM365_EVM + bool "TI DM365 EVM" + default ARCH_DAVINCI_DM365 + depends on ARCH_DAVINCI_DM365 + select MISC_DEVICES + select EEPROM_AT24 + select I2C + help + Configure this option to specify whether the board used + for development is a DM365 EVM + +config MACH_DAVINCI_DA830_EVM + bool "TI DA830/OMAP-L137/AM17x Reference Platform" + default ARCH_DAVINCI_DA830 + depends on ARCH_DAVINCI_DA830 + select GPIO_PCF857X + select MISC_DEVICES + select EEPROM_AT24 + select I2C + help + Say Y here to select the TI DA830/OMAP-L137/AM17x Evaluation Module. + +choice + prompt "Select DA830/OMAP-L137/AM17x UI board peripheral" + depends on MACH_DAVINCI_DA830_EVM + help + The presence of UI card on the DA830/OMAP-L137/AM17x EVM is + detected automatically based on successful probe of the I2C + based GPIO expander on that board. This option selected in this + menu has an effect only in case of a successful UI card detection. + +config DA830_UI_LCD + bool "LCD" + help + Say Y here to use the LCD as a framebuffer or simple character + display. + +config DA830_UI_NAND + bool "NAND flash" + help + Say Y here to use the NAND flash. Do not forget to setup + the switch correctly. +endchoice + +config MACH_DAVINCI_DA850_EVM + bool "TI DA850/OMAP-L138/AM18x Reference Platform" + default ARCH_DAVINCI_DA850 + depends on ARCH_DAVINCI_DA850 + help + Say Y here to select the TI DA850/OMAP-L138/AM18x Evaluation Module. + +choice + prompt "Select peripherals connected to expander on UI board" + depends on MACH_DAVINCI_DA850_EVM + help + The presence of User Interface (UI) card on the DA850/OMAP-L138/AM18x + EVM is detected automatically based on successful probe of the I2C + based GPIO expander on that card. This option selected in this + menu has an effect only in case of a successful UI card detection. + +config DA850_UI_NONE + bool "No peripheral is enabled" + help + Say Y if you do not want to enable any of the peripherals connected + to TCA6416 expander on DA850/OMAP-L138/AM18x EVM UI card + +config DA850_UI_RMII + bool "RMII Ethernet PHY" + help + Say Y if you want to use the RMII PHY on the DA850/OMAP-L138/AM18x + EVM. This PHY is found on the UI daughter card that is supplied with + the EVM. + NOTE: Please take care while choosing this option, MII PHY will + not be functional if RMII mode is selected. + +endchoice + +config DA850_WL12XX + bool "AM18x wl1271 daughter board" + depends on MACH_DAVINCI_DA850_EVM + help + The wl1271 daughter card for AM18x EVMs is a combo wireless + connectivity add-on card, based on the LS Research TiWi module with + Texas Instruments' wl1271 solution. + Say Y if you want to use a wl1271 expansion card connected to the + AM18x EVM. + +config GPIO_PCA953X + default MACH_DAVINCI_DA850_EVM + +config KEYBOARD_GPIO_POLLED + default MACH_DAVINCI_DA850_EVM + +config MACH_TNETV107X + bool "TI TNETV107X Reference Platform" + default ARCH_DAVINCI_TNETV107X + depends on ARCH_DAVINCI_TNETV107X + help + Say Y here to select the TI TNETV107X Evaluation Module. + +config MACH_MITYOMAPL138 + bool "Critical Link MityDSP-L138/MityARM-1808 SoM" + depends on ARCH_DAVINCI_DA850 + select MISC_DEVICES + select EEPROM_AT24 + select I2C + help + Say Y here to select the Critical Link MityDSP-L138/MityARM-1808 + System on Module. Information on this SoM may be found at + http://www.mitydsp.com + +config MACH_OMAPL138_HAWKBOARD + bool "TI AM1808 / OMAPL-138 Hawkboard platform" + depends on ARCH_DAVINCI_DA850 + help + Say Y here to select the TI AM1808 / OMAPL-138 Hawkboard platform . + Information of this board may be found at + http://www.hawkboard.org/ + +config DAVINCI_MUX + bool "DAVINCI multiplexing support" + depends on ARCH_DAVINCI + default y + help + Pin multiplexing support for DAVINCI boards. If your bootloader + sets the multiplexing correctly, say N. Otherwise, or if unsure, + say Y. + +config DAVINCI_MUX_DEBUG + bool "Multiplexing debug output" + depends on DAVINCI_MUX + help + Makes the multiplexing functions print out a lot of debug info. + This is useful if you want to find out the correct values of the + multiplexing registers. + +config DAVINCI_MUX_WARNINGS + bool "Warn about pins the bootloader didn't set up" + depends on DAVINCI_MUX + help + Choose Y here to warn whenever driver initialization logic needs + to change the pin multiplexing setup. When there are no warnings + printed, it's safe to deselect DAVINCI_MUX for your product. + +config DAVINCI_RESET_CLOCKS + bool "Reset unused clocks during boot" + depends on ARCH_DAVINCI + help + Say Y if you want to reset unused clocks during boot. + This option saves power, but assumes all drivers are + using the clock framework. Broken drivers that do not + yet use clock framework may not work with this option. + If you are booting from another operating system, you + probably do not want this option enabled until your + device drivers work properly. + +endmenu + +endif diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/Makefile b/ANDROID_3.4.5/arch/arm/mach-davinci/Makefile new file mode 100644 index 00000000..2db78bd5 --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/Makefile @@ -0,0 +1,41 @@ +# +# Makefile for the linux kernel. +# +# + +# Common objects +obj-y := time.o clock.o serial.o psc.o \ + dma.o usb.o common.o sram.o aemif.o + +obj-$(CONFIG_DAVINCI_MUX) += mux.o + +# Chip specific +obj-$(CONFIG_ARCH_DAVINCI_DM644x) += dm644x.o devices.o +obj-$(CONFIG_ARCH_DAVINCI_DM355) += dm355.o devices.o +obj-$(CONFIG_ARCH_DAVINCI_DM646x) += dm646x.o devices.o +obj-$(CONFIG_ARCH_DAVINCI_DM365) += dm365.o devices.o +obj-$(CONFIG_ARCH_DAVINCI_DA830) += da830.o devices-da8xx.o +obj-$(CONFIG_ARCH_DAVINCI_DA850) += da850.o devices-da8xx.o +obj-$(CONFIG_ARCH_DAVINCI_TNETV107X) += tnetv107x.o devices-tnetv107x.o + +obj-$(CONFIG_AINTC) += irq.o +obj-$(CONFIG_CP_INTC) += cp_intc.o + +# Board specific +obj-$(CONFIG_MACH_DAVINCI_EVM) += board-dm644x-evm.o +obj-$(CONFIG_MACH_SFFSDR) += board-sffsdr.o +obj-$(CONFIG_MACH_NEUROS_OSD2) += board-neuros-osd2.o +obj-$(CONFIG_MACH_DAVINCI_DM355_EVM) += board-dm355-evm.o +obj-$(CONFIG_MACH_DM355_LEOPARD) += board-dm355-leopard.o +obj-$(CONFIG_MACH_DAVINCI_DM6467_EVM) += board-dm646x-evm.o cdce949.o +obj-$(CONFIG_MACH_DAVINCI_DM365_EVM) += board-dm365-evm.o +obj-$(CONFIG_MACH_DAVINCI_DA830_EVM) += board-da830-evm.o +obj-$(CONFIG_MACH_DAVINCI_DA850_EVM) += board-da850-evm.o +obj-$(CONFIG_MACH_TNETV107X) += board-tnetv107x-evm.o +obj-$(CONFIG_MACH_MITYOMAPL138) += board-mityomapl138.o +obj-$(CONFIG_MACH_OMAPL138_HAWKBOARD) += board-omapl138-hawk.o + +# Power Management +obj-$(CONFIG_CPU_FREQ) += cpufreq.o +obj-$(CONFIG_CPU_IDLE) += cpuidle.o +obj-$(CONFIG_SUSPEND) += pm.o sleep.o diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/Makefile.boot b/ANDROID_3.4.5/arch/arm/mach-davinci/Makefile.boot new file mode 100644 index 00000000..04a6c4e6 --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/Makefile.boot @@ -0,0 +1,13 @@ +ifeq ($(CONFIG_ARCH_DAVINCI_DA8XX),y) +ifeq ($(CONFIG_ARCH_DAVINCI_DMx),y) +$(error Cannot enable DaVinci and DA8XX platforms concurrently) +else + zreladdr-y += 0xc0008000 +params_phys-y := 0xc0000100 +initrd_phys-y := 0xc0800000 +endif +else + zreladdr-y += 0x80008000 +params_phys-y := 0x80000100 +initrd_phys-y := 0x80800000 +endif diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/aemif.c b/ANDROID_3.4.5/arch/arm/mach-davinci/aemif.c new file mode 100644 index 00000000..1ce70a91 --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/aemif.c @@ -0,0 +1,133 @@ +/* + * AEMIF support for DaVinci SoCs + * + * Copyright (C) 2010 Texas Instruments Incorporated. http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/io.h> +#include <linux/err.h> +#include <linux/clk.h> +#include <linux/module.h> +#include <linux/time.h> + +#include <mach/aemif.h> + +/* Timing value configuration */ + +#define TA(x) ((x) << 2) +#define RHOLD(x) ((x) << 4) +#define RSTROBE(x) ((x) << 7) +#define RSETUP(x) ((x) << 13) +#define WHOLD(x) ((x) << 17) +#define WSTROBE(x) ((x) << 20) +#define WSETUP(x) ((x) << 26) + +#define TA_MAX 0x3 +#define RHOLD_MAX 0x7 +#define RSTROBE_MAX 0x3f +#define RSETUP_MAX 0xf +#define WHOLD_MAX 0x7 +#define WSTROBE_MAX 0x3f +#define WSETUP_MAX 0xf + +#define TIMING_MASK (TA(TA_MAX) | \ + RHOLD(RHOLD_MAX) | \ + RSTROBE(RSTROBE_MAX) | \ + RSETUP(RSETUP_MAX) | \ + WHOLD(WHOLD_MAX) | \ + WSTROBE(WSTROBE_MAX) | \ + WSETUP(WSETUP_MAX)) + +/* + * aemif_calc_rate - calculate timing data. + * @wanted: The cycle time needed in nanoseconds. + * @clk: The input clock rate in kHz. + * @max: The maximum divider value that can be programmed. + * + * On success, returns the calculated timing value minus 1 for easy + * programming into AEMIF timing registers, else negative errno. + */ +static int aemif_calc_rate(int wanted, unsigned long clk, int max) +{ + int result; + + result = DIV_ROUND_UP((wanted * clk), NSEC_PER_MSEC) - 1; + + pr_debug("%s: result %d from %ld, %d\n", __func__, result, clk, wanted); + + /* It is generally OK to have a more relaxed timing than requested... */ + if (result < 0) + result = 0; + + /* ... But configuring tighter timings is not an option. */ + else if (result > max) + result = -EINVAL; + + return result; +} + +/** + * davinci_aemif_setup_timing - setup timing values for a given AEMIF interface + * @t: timing values to be progammed + * @base: The virtual base address of the AEMIF interface + * @cs: chip-select to program the timing values for + * + * This function programs the given timing values (in real clock) into the + * AEMIF registers taking the AEMIF clock into account. + * + * This function does not use any locking while programming the AEMIF + * because it is expected that there is only one user of a given + * chip-select. + * + * Returns 0 on success, else negative errno. + */ +int davinci_aemif_setup_timing(struct davinci_aemif_timing *t, + void __iomem *base, unsigned cs) +{ + unsigned set, val; + int ta, rhold, rstrobe, rsetup, whold, wstrobe, wsetup; + unsigned offset = A1CR_OFFSET + cs * 4; + struct clk *aemif_clk; + unsigned long clkrate; + + if (!t) + return 0; /* Nothing to do */ + + aemif_clk = clk_get(NULL, "aemif"); + if (IS_ERR(aemif_clk)) + return PTR_ERR(aemif_clk); + + clkrate = clk_get_rate(aemif_clk); + + clkrate /= 1000; /* turn clock into kHz for ease of use */ + + ta = aemif_calc_rate(t->ta, clkrate, TA_MAX); + rhold = aemif_calc_rate(t->rhold, clkrate, RHOLD_MAX); + rstrobe = aemif_calc_rate(t->rstrobe, clkrate, RSTROBE_MAX); + rsetup = aemif_calc_rate(t->rsetup, clkrate, RSETUP_MAX); + whold = aemif_calc_rate(t->whold, clkrate, WHOLD_MAX); + wstrobe = aemif_calc_rate(t->wstrobe, clkrate, WSTROBE_MAX); + wsetup = aemif_calc_rate(t->wsetup, clkrate, WSETUP_MAX); + + if (ta < 0 || rhold < 0 || rstrobe < 0 || rsetup < 0 || + whold < 0 || wstrobe < 0 || wsetup < 0) { + pr_err("%s: cannot get suitable timings\n", __func__); + return -EINVAL; + } + + set = TA(ta) | RHOLD(rhold) | RSTROBE(rstrobe) | RSETUP(rsetup) | + WHOLD(whold) | WSTROBE(wstrobe) | WSETUP(wsetup); + + val = __raw_readl(base + offset); + val &= ~TIMING_MASK; + val |= set; + __raw_writel(val, base + offset); + + return 0; +} +EXPORT_SYMBOL(davinci_aemif_setup_timing); diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/board-da830-evm.c b/ANDROID_3.4.5/arch/arm/mach-davinci/board-da830-evm.c new file mode 100644 index 00000000..dc1afe5b --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/board-da830-evm.c @@ -0,0 +1,686 @@ +/* + * TI DA830/OMAP L137 EVM board + * + * Author: Mark A. Greer <mgreer@mvista.com> + * Derived from: arch/arm/mach-davinci/board-dm644x-evm.c + * + * 2007, 2009 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/console.h> +#include <linux/interrupt.h> +#include <linux/gpio.h> +#include <linux/platform_device.h> +#include <linux/i2c.h> +#include <linux/i2c/pcf857x.h> +#include <linux/i2c/at24.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> +#include <linux/spi/spi.h> +#include <linux/spi/flash.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> + +#include <mach/cp_intc.h> +#include <mach/mux.h> +#include <mach/nand.h> +#include <mach/da8xx.h> +#include <mach/usb.h> +#include <mach/aemif.h> +#include <mach/spi.h> + +#define DA830_EVM_PHY_ID "" +/* + * USB1 VBUS is controlled by GPIO1[15], over-current is reported on GPIO2[4]. + */ +#define ON_BD_USB_DRV GPIO_TO_PIN(1, 15) +#define ON_BD_USB_OVC GPIO_TO_PIN(2, 4) + +static const short da830_evm_usb11_pins[] = { + DA830_GPIO1_15, DA830_GPIO2_4, + -1 +}; + +static da8xx_ocic_handler_t da830_evm_usb_ocic_handler; + +static int da830_evm_usb_set_power(unsigned port, int on) +{ + gpio_set_value(ON_BD_USB_DRV, on); + return 0; +} + +static int da830_evm_usb_get_power(unsigned port) +{ + return gpio_get_value(ON_BD_USB_DRV); +} + +static int da830_evm_usb_get_oci(unsigned port) +{ + return !gpio_get_value(ON_BD_USB_OVC); +} + +static irqreturn_t da830_evm_usb_ocic_irq(int, void *); + +static int da830_evm_usb_ocic_notify(da8xx_ocic_handler_t handler) +{ + int irq = gpio_to_irq(ON_BD_USB_OVC); + int error = 0; + + if (handler != NULL) { + da830_evm_usb_ocic_handler = handler; + + error = request_irq(irq, da830_evm_usb_ocic_irq, IRQF_DISABLED | + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, + "OHCI over-current indicator", NULL); + if (error) + printk(KERN_ERR "%s: could not request IRQ to watch " + "over-current indicator changes\n", __func__); + } else + free_irq(irq, NULL); + + return error; +} + +static struct da8xx_ohci_root_hub da830_evm_usb11_pdata = { + .set_power = da830_evm_usb_set_power, + .get_power = da830_evm_usb_get_power, + .get_oci = da830_evm_usb_get_oci, + .ocic_notify = da830_evm_usb_ocic_notify, + + /* TPS2065 switch @ 5V */ + .potpgt = (3 + 1) / 2, /* 3 ms max */ +}; + +static irqreturn_t da830_evm_usb_ocic_irq(int irq, void *dev_id) +{ + da830_evm_usb_ocic_handler(&da830_evm_usb11_pdata, 1); + return IRQ_HANDLED; +} + +static __init void da830_evm_usb_init(void) +{ + u32 cfgchip2; + int ret; + + /* + * Set up USB clock/mode in the CFGCHIP2 register. + * FYI: CFGCHIP2 is 0x0000ef00 initially. + */ + cfgchip2 = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)); + + /* USB2.0 PHY reference clock is 24 MHz */ + cfgchip2 &= ~CFGCHIP2_REFFREQ; + cfgchip2 |= CFGCHIP2_REFFREQ_24MHZ; + + /* + * Select internal reference clock for USB 2.0 PHY + * and use it as a clock source for USB 1.1 PHY + * (this is the default setting anyway). + */ + cfgchip2 &= ~CFGCHIP2_USB1PHYCLKMUX; + cfgchip2 |= CFGCHIP2_USB2PHYCLKMUX; + + /* + * We have to override VBUS/ID signals when MUSB is configured into the + * host-only mode -- ID pin will float if no cable is connected, so the + * controller won't be able to drive VBUS thinking that it's a B-device. + * Otherwise, we want to use the OTG mode and enable VBUS comparators. + */ + cfgchip2 &= ~CFGCHIP2_OTGMODE; +#ifdef CONFIG_USB_MUSB_HOST + cfgchip2 |= CFGCHIP2_FORCE_HOST; +#else + cfgchip2 |= CFGCHIP2_SESENDEN | CFGCHIP2_VBDTCTEN; +#endif + + __raw_writel(cfgchip2, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)); + + /* USB_REFCLKIN is not used. */ + ret = davinci_cfg_reg(DA830_USB0_DRVVBUS); + if (ret) + pr_warning("%s: USB 2.0 PinMux setup failed: %d\n", + __func__, ret); + else { + /* + * TPS2065 switch @ 5V supplies 1 A (sustains 1.5 A), + * with the power on to power good time of 3 ms. + */ + ret = da8xx_register_usb20(1000, 3); + if (ret) + pr_warning("%s: USB 2.0 registration failed: %d\n", + __func__, ret); + } + + ret = davinci_cfg_reg_list(da830_evm_usb11_pins); + if (ret) { + pr_warning("%s: USB 1.1 PinMux setup failed: %d\n", + __func__, ret); + return; + } + + ret = gpio_request(ON_BD_USB_DRV, "ON_BD_USB_DRV"); + if (ret) { + printk(KERN_ERR "%s: failed to request GPIO for USB 1.1 port " + "power control: %d\n", __func__, ret); + return; + } + gpio_direction_output(ON_BD_USB_DRV, 0); + + ret = gpio_request(ON_BD_USB_OVC, "ON_BD_USB_OVC"); + if (ret) { + printk(KERN_ERR "%s: failed to request GPIO for USB 1.1 port " + "over-current indicator: %d\n", __func__, ret); + return; + } + gpio_direction_input(ON_BD_USB_OVC); + + ret = da8xx_register_usb11(&da830_evm_usb11_pdata); + if (ret) + pr_warning("%s: USB 1.1 registration failed: %d\n", + __func__, ret); +} + +static struct davinci_uart_config da830_evm_uart_config __initdata = { + .enabled_uarts = 0x7, +}; + +static const short da830_evm_mcasp1_pins[] = { + DA830_AHCLKX1, DA830_ACLKX1, DA830_AFSX1, DA830_AHCLKR1, DA830_AFSR1, + DA830_AMUTE1, DA830_AXR1_0, DA830_AXR1_1, DA830_AXR1_2, DA830_AXR1_5, + DA830_ACLKR1, DA830_AXR1_6, DA830_AXR1_7, DA830_AXR1_8, DA830_AXR1_10, + DA830_AXR1_11, + -1 +}; + +static u8 da830_iis_serializer_direction[] = { + RX_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, + INACTIVE_MODE, TX_MODE, INACTIVE_MODE, INACTIVE_MODE, + INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, +}; + +static struct snd_platform_data da830_evm_snd_data = { + .tx_dma_offset = 0x2000, + .rx_dma_offset = 0x2000, + .op_mode = DAVINCI_MCASP_IIS_MODE, + .num_serializer = ARRAY_SIZE(da830_iis_serializer_direction), + .tdm_slots = 2, + .serial_dir = da830_iis_serializer_direction, + .asp_chan_q = EVENTQ_0, + .version = MCASP_VERSION_2, + .txnumevt = 1, + .rxnumevt = 1, +}; + +/* + * GPIO2[1] is used as MMC_SD_WP and GPIO2[2] as MMC_SD_INS. + */ +static const short da830_evm_mmc_sd_pins[] = { + DA830_MMCSD_DAT_0, DA830_MMCSD_DAT_1, DA830_MMCSD_DAT_2, + DA830_MMCSD_DAT_3, DA830_MMCSD_DAT_4, DA830_MMCSD_DAT_5, + DA830_MMCSD_DAT_6, DA830_MMCSD_DAT_7, DA830_MMCSD_CLK, + DA830_MMCSD_CMD, DA830_GPIO2_1, DA830_GPIO2_2, + -1 +}; + +#define DA830_MMCSD_WP_PIN GPIO_TO_PIN(2, 1) +#define DA830_MMCSD_CD_PIN GPIO_TO_PIN(2, 2) + +static int da830_evm_mmc_get_ro(int index) +{ + return gpio_get_value(DA830_MMCSD_WP_PIN); +} + +static int da830_evm_mmc_get_cd(int index) +{ + return !gpio_get_value(DA830_MMCSD_CD_PIN); +} + +static struct davinci_mmc_config da830_evm_mmc_config = { + .get_ro = da830_evm_mmc_get_ro, + .get_cd = da830_evm_mmc_get_cd, + .wires = 8, + .max_freq = 50000000, + .caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED, + .version = MMC_CTLR_VERSION_2, +}; + +static inline void da830_evm_init_mmc(void) +{ + int ret; + + ret = davinci_cfg_reg_list(da830_evm_mmc_sd_pins); + if (ret) { + pr_warning("da830_evm_init: mmc/sd mux setup failed: %d\n", + ret); + return; + } + + ret = gpio_request(DA830_MMCSD_WP_PIN, "MMC WP"); + if (ret) { + pr_warning("da830_evm_init: can not open GPIO %d\n", + DA830_MMCSD_WP_PIN); + return; + } + gpio_direction_input(DA830_MMCSD_WP_PIN); + + ret = gpio_request(DA830_MMCSD_CD_PIN, "MMC CD\n"); + if (ret) { + pr_warning("da830_evm_init: can not open GPIO %d\n", + DA830_MMCSD_CD_PIN); + return; + } + gpio_direction_input(DA830_MMCSD_CD_PIN); + + ret = da8xx_register_mmcsd0(&da830_evm_mmc_config); + if (ret) { + pr_warning("da830_evm_init: mmc/sd registration failed: %d\n", + ret); + gpio_free(DA830_MMCSD_WP_PIN); + } +} + +/* + * UI board NAND/NOR flashes only use 8-bit data bus. + */ +static const short da830_evm_emif25_pins[] = { + DA830_EMA_D_0, DA830_EMA_D_1, DA830_EMA_D_2, DA830_EMA_D_3, + DA830_EMA_D_4, DA830_EMA_D_5, DA830_EMA_D_6, DA830_EMA_D_7, + DA830_EMA_A_0, DA830_EMA_A_1, DA830_EMA_A_2, DA830_EMA_A_3, + DA830_EMA_A_4, DA830_EMA_A_5, DA830_EMA_A_6, DA830_EMA_A_7, + DA830_EMA_A_8, DA830_EMA_A_9, DA830_EMA_A_10, DA830_EMA_A_11, + DA830_EMA_A_12, DA830_EMA_BA_0, DA830_EMA_BA_1, DA830_NEMA_WE, + DA830_NEMA_CS_2, DA830_NEMA_CS_3, DA830_NEMA_OE, DA830_EMA_WAIT_0, + -1 +}; + +#if defined(CONFIG_MMC_DAVINCI) || defined(CONFIG_MMC_DAVINCI_MODULE) +#define HAS_MMC 1 +#else +#define HAS_MMC 0 +#endif + +#ifdef CONFIG_DA830_UI_NAND +static struct mtd_partition da830_evm_nand_partitions[] = { + /* bootloader (U-Boot, etc) in first sector */ + [0] = { + .name = "bootloader", + .offset = 0, + .size = SZ_128K, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + /* bootloader params in the next sector */ + [1] = { + .name = "params", + .offset = MTDPART_OFS_APPEND, + .size = SZ_128K, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + /* kernel */ + [2] = { + .name = "kernel", + .offset = MTDPART_OFS_APPEND, + .size = SZ_2M, + .mask_flags = 0, + }, + /* file system */ + [3] = { + .name = "filesystem", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + .mask_flags = 0, + } +}; + +/* flash bbt decriptors */ +static uint8_t da830_evm_nand_bbt_pattern[] = { 'B', 'b', 't', '0' }; +static uint8_t da830_evm_nand_mirror_pattern[] = { '1', 't', 'b', 'B' }; + +static struct nand_bbt_descr da830_evm_nand_bbt_main_descr = { + .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | + NAND_BBT_WRITE | NAND_BBT_2BIT | + NAND_BBT_VERSION | NAND_BBT_PERCHIP, + .offs = 2, + .len = 4, + .veroffs = 16, + .maxblocks = 4, + .pattern = da830_evm_nand_bbt_pattern +}; + +static struct nand_bbt_descr da830_evm_nand_bbt_mirror_descr = { + .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | + NAND_BBT_WRITE | NAND_BBT_2BIT | + NAND_BBT_VERSION | NAND_BBT_PERCHIP, + .offs = 2, + .len = 4, + .veroffs = 16, + .maxblocks = 4, + .pattern = da830_evm_nand_mirror_pattern +}; + +static struct davinci_aemif_timing da830_evm_nandflash_timing = { + .wsetup = 24, + .wstrobe = 21, + .whold = 14, + .rsetup = 19, + .rstrobe = 50, + .rhold = 0, + .ta = 20, +}; + +static struct davinci_nand_pdata da830_evm_nand_pdata = { + .parts = da830_evm_nand_partitions, + .nr_parts = ARRAY_SIZE(da830_evm_nand_partitions), + .ecc_mode = NAND_ECC_HW, + .ecc_bits = 4, + .bbt_options = NAND_BBT_USE_FLASH, + .bbt_td = &da830_evm_nand_bbt_main_descr, + .bbt_md = &da830_evm_nand_bbt_mirror_descr, + .timing = &da830_evm_nandflash_timing, +}; + +static struct resource da830_evm_nand_resources[] = { + [0] = { /* First memory resource is NAND I/O window */ + .start = DA8XX_AEMIF_CS3_BASE, + .end = DA8XX_AEMIF_CS3_BASE + PAGE_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { /* Second memory resource is AEMIF control registers */ + .start = DA8XX_AEMIF_CTL_BASE, + .end = DA8XX_AEMIF_CTL_BASE + SZ_32K - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device da830_evm_nand_device = { + .name = "davinci_nand", + .id = 1, + .dev = { + .platform_data = &da830_evm_nand_pdata, + }, + .num_resources = ARRAY_SIZE(da830_evm_nand_resources), + .resource = da830_evm_nand_resources, +}; + +static inline void da830_evm_init_nand(int mux_mode) +{ + int ret; + + if (HAS_MMC) { + pr_warning("WARNING: both MMC/SD and NAND are " + "enabled, but they share AEMIF pins.\n" + "\tDisable MMC/SD for NAND support.\n"); + return; + } + + ret = davinci_cfg_reg_list(da830_evm_emif25_pins); + if (ret) + pr_warning("da830_evm_init: emif25 mux setup failed: %d\n", + ret); + + ret = platform_device_register(&da830_evm_nand_device); + if (ret) + pr_warning("da830_evm_init: NAND device not registered.\n"); + + gpio_direction_output(mux_mode, 1); +} +#else +static inline void da830_evm_init_nand(int mux_mode) { } +#endif + +#ifdef CONFIG_DA830_UI_LCD +static inline void da830_evm_init_lcdc(int mux_mode) +{ + int ret; + + ret = davinci_cfg_reg_list(da830_lcdcntl_pins); + if (ret) + pr_warning("da830_evm_init: lcdcntl mux setup failed: %d\n", + ret); + + ret = da8xx_register_lcdc(&sharp_lcd035q3dg01_pdata); + if (ret) + pr_warning("da830_evm_init: lcd setup failed: %d\n", ret); + + gpio_direction_output(mux_mode, 0); +} +#else +static inline void da830_evm_init_lcdc(int mux_mode) { } +#endif + +static struct at24_platform_data da830_evm_i2c_eeprom_info = { + .byte_len = SZ_256K / 8, + .page_size = 64, + .flags = AT24_FLAG_ADDR16, + .setup = davinci_get_mac_addr, + .context = (void *)0x7f00, +}; + +static int __init da830_evm_ui_expander_setup(struct i2c_client *client, + int gpio, unsigned ngpio, void *context) +{ + gpio_request(gpio + 6, "UI MUX_MODE"); + + /* Drive mux mode low to match the default without UI card */ + gpio_direction_output(gpio + 6, 0); + + da830_evm_init_lcdc(gpio + 6); + + da830_evm_init_nand(gpio + 6); + + return 0; +} + +static int da830_evm_ui_expander_teardown(struct i2c_client *client, int gpio, + unsigned ngpio, void *context) +{ + gpio_free(gpio + 6); + return 0; +} + +static struct pcf857x_platform_data __initdata da830_evm_ui_expander_info = { + .gpio_base = DAVINCI_N_GPIO, + .setup = da830_evm_ui_expander_setup, + .teardown = da830_evm_ui_expander_teardown, +}; + +static struct i2c_board_info __initdata da830_evm_i2c_devices[] = { + { + I2C_BOARD_INFO("24c256", 0x50), + .platform_data = &da830_evm_i2c_eeprom_info, + }, + { + I2C_BOARD_INFO("tlv320aic3x", 0x18), + }, + { + I2C_BOARD_INFO("pcf8574", 0x3f), + .platform_data = &da830_evm_ui_expander_info, + }, +}; + +static struct davinci_i2c_platform_data da830_evm_i2c_0_pdata = { + .bus_freq = 100, /* kHz */ + .bus_delay = 0, /* usec */ +}; + +/* + * The following EDMA channels/slots are not being used by drivers (for + * example: Timer, GPIO, UART events etc) on da830/omap-l137 EVM, hence + * they are being reserved for codecs on the DSP side. + */ +static const s16 da830_dma_rsv_chans[][2] = { + /* (offset, number) */ + { 8, 2}, + {12, 2}, + {24, 4}, + {30, 2}, + {-1, -1} +}; + +static const s16 da830_dma_rsv_slots[][2] = { + /* (offset, number) */ + { 8, 2}, + {12, 2}, + {24, 4}, + {30, 26}, + {-1, -1} +}; + +static struct edma_rsv_info da830_edma_rsv[] = { + { + .rsv_chans = da830_dma_rsv_chans, + .rsv_slots = da830_dma_rsv_slots, + }, +}; + +static struct mtd_partition da830evm_spiflash_part[] = { + [0] = { + .name = "DSP-UBL", + .offset = 0, + .size = SZ_8K, + .mask_flags = MTD_WRITEABLE, + }, + [1] = { + .name = "ARM-UBL", + .offset = MTDPART_OFS_APPEND, + .size = SZ_16K + SZ_8K, + .mask_flags = MTD_WRITEABLE, + }, + [2] = { + .name = "U-Boot", + .offset = MTDPART_OFS_APPEND, + .size = SZ_256K - SZ_32K, + .mask_flags = MTD_WRITEABLE, + }, + [3] = { + .name = "U-Boot-Environment", + .offset = MTDPART_OFS_APPEND, + .size = SZ_16K, + .mask_flags = 0, + }, + [4] = { + .name = "Kernel", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + .mask_flags = 0, + }, +}; + +static struct flash_platform_data da830evm_spiflash_data = { + .name = "m25p80", + .parts = da830evm_spiflash_part, + .nr_parts = ARRAY_SIZE(da830evm_spiflash_part), + .type = "w25x32", +}; + +static struct davinci_spi_config da830evm_spiflash_cfg = { + .io_type = SPI_IO_TYPE_DMA, + .c2tdelay = 8, + .t2cdelay = 8, +}; + +static struct spi_board_info da830evm_spi_info[] = { + { + .modalias = "m25p80", + .platform_data = &da830evm_spiflash_data, + .controller_data = &da830evm_spiflash_cfg, + .mode = SPI_MODE_0, + .max_speed_hz = 30000000, + .bus_num = 0, + .chip_select = 0, + }, +}; + +static __init void da830_evm_init(void) +{ + struct davinci_soc_info *soc_info = &davinci_soc_info; + int ret; + + ret = da830_register_edma(da830_edma_rsv); + if (ret) + pr_warning("da830_evm_init: edma registration failed: %d\n", + ret); + + ret = davinci_cfg_reg_list(da830_i2c0_pins); + if (ret) + pr_warning("da830_evm_init: i2c0 mux setup failed: %d\n", + ret); + + ret = da8xx_register_i2c(0, &da830_evm_i2c_0_pdata); + if (ret) + pr_warning("da830_evm_init: i2c0 registration failed: %d\n", + ret); + + da830_evm_usb_init(); + + soc_info->emac_pdata->rmii_en = 1; + soc_info->emac_pdata->phy_id = DA830_EVM_PHY_ID; + + ret = davinci_cfg_reg_list(da830_cpgmac_pins); + if (ret) + pr_warning("da830_evm_init: cpgmac mux setup failed: %d\n", + ret); + + ret = da8xx_register_emac(); + if (ret) + pr_warning("da830_evm_init: emac registration failed: %d\n", + ret); + + ret = da8xx_register_watchdog(); + if (ret) + pr_warning("da830_evm_init: watchdog registration failed: %d\n", + ret); + + davinci_serial_init(&da830_evm_uart_config); + i2c_register_board_info(1, da830_evm_i2c_devices, + ARRAY_SIZE(da830_evm_i2c_devices)); + + ret = davinci_cfg_reg_list(da830_evm_mcasp1_pins); + if (ret) + pr_warning("da830_evm_init: mcasp1 mux setup failed: %d\n", + ret); + + da8xx_register_mcasp(1, &da830_evm_snd_data); + + da830_evm_init_mmc(); + + ret = da8xx_register_rtc(); + if (ret) + pr_warning("da830_evm_init: rtc setup failed: %d\n", ret); + + ret = da8xx_register_spi(0, da830evm_spi_info, + ARRAY_SIZE(da830evm_spi_info)); + if (ret) + pr_warning("da830_evm_init: spi 0 registration failed: %d\n", + ret); +} + +#ifdef CONFIG_SERIAL_8250_CONSOLE +static int __init da830_evm_console_init(void) +{ + if (!machine_is_davinci_da830_evm()) + return 0; + + return add_preferred_console("ttyS", 2, "115200"); +} +console_initcall(da830_evm_console_init); +#endif + +static void __init da830_evm_map_io(void) +{ + da830_init(); +} + +MACHINE_START(DAVINCI_DA830_EVM, "DaVinci DA830/OMAP-L137/AM17x EVM") + .atag_offset = 0x100, + .map_io = da830_evm_map_io, + .init_irq = cp_intc_init, + .timer = &davinci_timer, + .init_machine = da830_evm_init, + .dma_zone_size = SZ_128M, + .restart = da8xx_restart, +MACHINE_END diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/board-da850-evm.c b/ANDROID_3.4.5/arch/arm/mach-davinci/board-da850-evm.c new file mode 100644 index 00000000..a70de24d --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/board-da850-evm.c @@ -0,0 +1,1416 @@ +/* + * TI DA850/OMAP-L138 EVM board + * + * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ + * + * Derived from: arch/arm/mach-davinci/board-da830-evm.c + * Original Copyrights follow: + * + * 2007, 2009 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/console.h> +#include <linux/i2c.h> +#include <linux/i2c/at24.h> +#include <linux/i2c/pca953x.h> +#include <linux/input.h> +#include <linux/mfd/tps6507x.h> +#include <linux/gpio.h> +#include <linux/gpio_keys.h> +#include <linux/platform_device.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/nand.h> +#include <linux/mtd/partitions.h> +#include <linux/mtd/physmap.h> +#include <linux/regulator/machine.h> +#include <linux/regulator/tps6507x.h> +#include <linux/input/tps6507x-ts.h> +#include <linux/spi/spi.h> +#include <linux/spi/flash.h> +#include <linux/delay.h> +#include <linux/wl12xx.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/system_info.h> + +#include <mach/cp_intc.h> +#include <mach/da8xx.h> +#include <mach/nand.h> +#include <mach/mux.h> +#include <mach/aemif.h> +#include <mach/spi.h> + +#define DA850_EVM_PHY_ID "davinci_mdio-0:00" +#define DA850_LCD_PWR_PIN GPIO_TO_PIN(2, 8) +#define DA850_LCD_BL_PIN GPIO_TO_PIN(2, 15) + +#define DA850_MMCSD_CD_PIN GPIO_TO_PIN(4, 0) +#define DA850_MMCSD_WP_PIN GPIO_TO_PIN(4, 1) + +#define DA850_WLAN_EN GPIO_TO_PIN(6, 9) +#define DA850_WLAN_IRQ GPIO_TO_PIN(6, 10) + +#define DA850_MII_MDIO_CLKEN_PIN GPIO_TO_PIN(2, 6) + +static struct mtd_partition da850evm_spiflash_part[] = { + [0] = { + .name = "UBL", + .offset = 0, + .size = SZ_64K, + .mask_flags = MTD_WRITEABLE, + }, + [1] = { + .name = "U-Boot", + .offset = MTDPART_OFS_APPEND, + .size = SZ_512K, + .mask_flags = MTD_WRITEABLE, + }, + [2] = { + .name = "U-Boot-Env", + .offset = MTDPART_OFS_APPEND, + .size = SZ_64K, + .mask_flags = MTD_WRITEABLE, + }, + [3] = { + .name = "Kernel", + .offset = MTDPART_OFS_APPEND, + .size = SZ_2M + SZ_512K, + .mask_flags = 0, + }, + [4] = { + .name = "Filesystem", + .offset = MTDPART_OFS_APPEND, + .size = SZ_4M, + .mask_flags = 0, + }, + [5] = { + .name = "MAC-Address", + .offset = SZ_8M - SZ_64K, + .size = SZ_64K, + .mask_flags = MTD_WRITEABLE, + }, +}; + +static struct flash_platform_data da850evm_spiflash_data = { + .name = "m25p80", + .parts = da850evm_spiflash_part, + .nr_parts = ARRAY_SIZE(da850evm_spiflash_part), + .type = "m25p64", +}; + +static struct davinci_spi_config da850evm_spiflash_cfg = { + .io_type = SPI_IO_TYPE_DMA, + .c2tdelay = 8, + .t2cdelay = 8, +}; + +static struct spi_board_info da850evm_spi_info[] = { + { + .modalias = "m25p80", + .platform_data = &da850evm_spiflash_data, + .controller_data = &da850evm_spiflash_cfg, + .mode = SPI_MODE_0, + .max_speed_hz = 30000000, + .bus_num = 1, + .chip_select = 0, + }, +}; + +#ifdef CONFIG_MTD +static void da850_evm_m25p80_notify_add(struct mtd_info *mtd) +{ + char *mac_addr = davinci_soc_info.emac_pdata->mac_addr; + size_t retlen; + + if (!strcmp(mtd->name, "MAC-Address")) { + mtd_read(mtd, 0, ETH_ALEN, &retlen, mac_addr); + if (retlen == ETH_ALEN) + pr_info("Read MAC addr from SPI Flash: %pM\n", + mac_addr); + } +} + +static struct mtd_notifier da850evm_spi_notifier = { + .add = da850_evm_m25p80_notify_add, +}; + +static void da850_evm_setup_mac_addr(void) +{ + register_mtd_user(&da850evm_spi_notifier); +} +#else +static void da850_evm_setup_mac_addr(void) { } +#endif + +static struct mtd_partition da850_evm_norflash_partition[] = { + { + .name = "bootloaders + env", + .offset = 0, + .size = SZ_512K, + .mask_flags = MTD_WRITEABLE, + }, + { + .name = "kernel", + .offset = MTDPART_OFS_APPEND, + .size = SZ_2M, + .mask_flags = 0, + }, + { + .name = "filesystem", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + .mask_flags = 0, + }, +}; + +static struct physmap_flash_data da850_evm_norflash_data = { + .width = 2, + .parts = da850_evm_norflash_partition, + .nr_parts = ARRAY_SIZE(da850_evm_norflash_partition), +}; + +static struct resource da850_evm_norflash_resource[] = { + { + .start = DA8XX_AEMIF_CS2_BASE, + .end = DA8XX_AEMIF_CS2_BASE + SZ_32M - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device da850_evm_norflash_device = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &da850_evm_norflash_data, + }, + .num_resources = 1, + .resource = da850_evm_norflash_resource, +}; + +static struct davinci_pm_config da850_pm_pdata = { + .sleepcount = 128, +}; + +static struct platform_device da850_pm_device = { + .name = "pm-davinci", + .dev = { + .platform_data = &da850_pm_pdata, + }, + .id = -1, +}; + +/* DA850/OMAP-L138 EVM includes a 512 MByte large-page NAND flash + * (128K blocks). It may be used instead of the (default) SPI flash + * to boot, using TI's tools to install the secondary boot loader + * (UBL) and U-Boot. + */ +static struct mtd_partition da850_evm_nandflash_partition[] = { + { + .name = "u-boot env", + .offset = 0, + .size = SZ_128K, + .mask_flags = MTD_WRITEABLE, + }, + { + .name = "UBL", + .offset = MTDPART_OFS_APPEND, + .size = SZ_128K, + .mask_flags = MTD_WRITEABLE, + }, + { + .name = "u-boot", + .offset = MTDPART_OFS_APPEND, + .size = 4 * SZ_128K, + .mask_flags = MTD_WRITEABLE, + }, + { + .name = "kernel", + .offset = 0x200000, + .size = SZ_2M, + .mask_flags = 0, + }, + { + .name = "filesystem", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + .mask_flags = 0, + }, +}; + +static struct davinci_aemif_timing da850_evm_nandflash_timing = { + .wsetup = 24, + .wstrobe = 21, + .whold = 14, + .rsetup = 19, + .rstrobe = 50, + .rhold = 0, + .ta = 20, +}; + +static struct davinci_nand_pdata da850_evm_nandflash_data = { + .parts = da850_evm_nandflash_partition, + .nr_parts = ARRAY_SIZE(da850_evm_nandflash_partition), + .ecc_mode = NAND_ECC_HW, + .ecc_bits = 4, + .bbt_options = NAND_BBT_USE_FLASH, + .timing = &da850_evm_nandflash_timing, +}; + +static struct resource da850_evm_nandflash_resource[] = { + { + .start = DA8XX_AEMIF_CS3_BASE, + .end = DA8XX_AEMIF_CS3_BASE + SZ_512K + 2 * SZ_1K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = DA8XX_AEMIF_CTL_BASE, + .end = DA8XX_AEMIF_CTL_BASE + SZ_32K - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device da850_evm_nandflash_device = { + .name = "davinci_nand", + .id = 1, + .dev = { + .platform_data = &da850_evm_nandflash_data, + }, + .num_resources = ARRAY_SIZE(da850_evm_nandflash_resource), + .resource = da850_evm_nandflash_resource, +}; + +static struct platform_device *da850_evm_devices[] __initdata = { + &da850_evm_nandflash_device, + &da850_evm_norflash_device, +}; + +#define DA8XX_AEMIF_CE2CFG_OFFSET 0x10 +#define DA8XX_AEMIF_ASIZE_16BIT 0x1 + +static void __init da850_evm_init_nor(void) +{ + void __iomem *aemif_addr; + + aemif_addr = ioremap(DA8XX_AEMIF_CTL_BASE, SZ_32K); + + /* Configure data bus width of CS2 to 16 bit */ + writel(readl(aemif_addr + DA8XX_AEMIF_CE2CFG_OFFSET) | + DA8XX_AEMIF_ASIZE_16BIT, + aemif_addr + DA8XX_AEMIF_CE2CFG_OFFSET); + + iounmap(aemif_addr); +} + +static const short da850_evm_nand_pins[] = { + DA850_EMA_D_0, DA850_EMA_D_1, DA850_EMA_D_2, DA850_EMA_D_3, + DA850_EMA_D_4, DA850_EMA_D_5, DA850_EMA_D_6, DA850_EMA_D_7, + DA850_EMA_A_1, DA850_EMA_A_2, DA850_NEMA_CS_3, DA850_NEMA_CS_4, + DA850_NEMA_WE, DA850_NEMA_OE, + -1 +}; + +static const short da850_evm_nor_pins[] = { + DA850_EMA_BA_1, DA850_EMA_CLK, DA850_EMA_WAIT_1, DA850_NEMA_CS_2, + DA850_NEMA_WE, DA850_NEMA_OE, DA850_EMA_D_0, DA850_EMA_D_1, + DA850_EMA_D_2, DA850_EMA_D_3, DA850_EMA_D_4, DA850_EMA_D_5, + DA850_EMA_D_6, DA850_EMA_D_7, DA850_EMA_D_8, DA850_EMA_D_9, + DA850_EMA_D_10, DA850_EMA_D_11, DA850_EMA_D_12, DA850_EMA_D_13, + DA850_EMA_D_14, DA850_EMA_D_15, DA850_EMA_A_0, DA850_EMA_A_1, + DA850_EMA_A_2, DA850_EMA_A_3, DA850_EMA_A_4, DA850_EMA_A_5, + DA850_EMA_A_6, DA850_EMA_A_7, DA850_EMA_A_8, DA850_EMA_A_9, + DA850_EMA_A_10, DA850_EMA_A_11, DA850_EMA_A_12, DA850_EMA_A_13, + DA850_EMA_A_14, DA850_EMA_A_15, DA850_EMA_A_16, DA850_EMA_A_17, + DA850_EMA_A_18, DA850_EMA_A_19, DA850_EMA_A_20, DA850_EMA_A_21, + DA850_EMA_A_22, DA850_EMA_A_23, + -1 +}; + +#if defined(CONFIG_MMC_DAVINCI) || \ + defined(CONFIG_MMC_DAVINCI_MODULE) +#define HAS_MMC 1 +#else +#define HAS_MMC 0 +#endif + +static inline void da850_evm_setup_nor_nand(void) +{ + int ret = 0; + + if (!HAS_MMC) { + ret = davinci_cfg_reg_list(da850_evm_nand_pins); + if (ret) + pr_warning("da850_evm_init: nand mux setup failed: " + "%d\n", ret); + + ret = davinci_cfg_reg_list(da850_evm_nor_pins); + if (ret) + pr_warning("da850_evm_init: nor mux setup failed: %d\n", + ret); + + da850_evm_init_nor(); + + platform_add_devices(da850_evm_devices, + ARRAY_SIZE(da850_evm_devices)); + } +} + +#ifdef CONFIG_DA850_UI_RMII +static inline void da850_evm_setup_emac_rmii(int rmii_sel) +{ + struct davinci_soc_info *soc_info = &davinci_soc_info; + + soc_info->emac_pdata->rmii_en = 1; + gpio_set_value_cansleep(rmii_sel, 0); +} +#else +static inline void da850_evm_setup_emac_rmii(int rmii_sel) { } +#endif + + +#define DA850_KEYS_DEBOUNCE_MS 10 +/* + * At 200ms polling interval it is possible to miss an + * event by tapping very lightly on the push button but most + * pushes do result in an event; longer intervals require the + * user to hold the button whereas shorter intervals require + * more CPU time for polling. + */ +#define DA850_GPIO_KEYS_POLL_MS 200 + +enum da850_evm_ui_exp_pins { + DA850_EVM_UI_EXP_SEL_C = 5, + DA850_EVM_UI_EXP_SEL_B, + DA850_EVM_UI_EXP_SEL_A, + DA850_EVM_UI_EXP_PB8, + DA850_EVM_UI_EXP_PB7, + DA850_EVM_UI_EXP_PB6, + DA850_EVM_UI_EXP_PB5, + DA850_EVM_UI_EXP_PB4, + DA850_EVM_UI_EXP_PB3, + DA850_EVM_UI_EXP_PB2, + DA850_EVM_UI_EXP_PB1, +}; + +static const char const *da850_evm_ui_exp[] = { + [DA850_EVM_UI_EXP_SEL_C] = "sel_c", + [DA850_EVM_UI_EXP_SEL_B] = "sel_b", + [DA850_EVM_UI_EXP_SEL_A] = "sel_a", + [DA850_EVM_UI_EXP_PB8] = "pb8", + [DA850_EVM_UI_EXP_PB7] = "pb7", + [DA850_EVM_UI_EXP_PB6] = "pb6", + [DA850_EVM_UI_EXP_PB5] = "pb5", + [DA850_EVM_UI_EXP_PB4] = "pb4", + [DA850_EVM_UI_EXP_PB3] = "pb3", + [DA850_EVM_UI_EXP_PB2] = "pb2", + [DA850_EVM_UI_EXP_PB1] = "pb1", +}; + +#define DA850_N_UI_PB 8 + +static struct gpio_keys_button da850_evm_ui_keys[] = { + [0 ... DA850_N_UI_PB - 1] = { + .type = EV_KEY, + .active_low = 1, + .wakeup = 0, + .debounce_interval = DA850_KEYS_DEBOUNCE_MS, + .code = -1, /* assigned at runtime */ + .gpio = -1, /* assigned at runtime */ + .desc = NULL, /* assigned at runtime */ + }, +}; + +static struct gpio_keys_platform_data da850_evm_ui_keys_pdata = { + .buttons = da850_evm_ui_keys, + .nbuttons = ARRAY_SIZE(da850_evm_ui_keys), + .poll_interval = DA850_GPIO_KEYS_POLL_MS, +}; + +static struct platform_device da850_evm_ui_keys_device = { + .name = "gpio-keys-polled", + .id = 0, + .dev = { + .platform_data = &da850_evm_ui_keys_pdata + }, +}; + +static void da850_evm_ui_keys_init(unsigned gpio) +{ + int i; + struct gpio_keys_button *button; + + for (i = 0; i < DA850_N_UI_PB; i++) { + button = &da850_evm_ui_keys[i]; + button->code = KEY_F8 - i; + button->desc = (char *) + da850_evm_ui_exp[DA850_EVM_UI_EXP_PB8 + i]; + button->gpio = gpio + DA850_EVM_UI_EXP_PB8 + i; + } +} + +static int da850_evm_ui_expander_setup(struct i2c_client *client, unsigned gpio, + unsigned ngpio, void *c) +{ + int sel_a, sel_b, sel_c, ret; + + sel_a = gpio + DA850_EVM_UI_EXP_SEL_A; + sel_b = gpio + DA850_EVM_UI_EXP_SEL_B; + sel_c = gpio + DA850_EVM_UI_EXP_SEL_C; + + ret = gpio_request(sel_a, da850_evm_ui_exp[DA850_EVM_UI_EXP_SEL_A]); + if (ret) { + pr_warning("Cannot open UI expander pin %d\n", sel_a); + goto exp_setup_sela_fail; + } + + ret = gpio_request(sel_b, da850_evm_ui_exp[DA850_EVM_UI_EXP_SEL_B]); + if (ret) { + pr_warning("Cannot open UI expander pin %d\n", sel_b); + goto exp_setup_selb_fail; + } + + ret = gpio_request(sel_c, da850_evm_ui_exp[DA850_EVM_UI_EXP_SEL_C]); + if (ret) { + pr_warning("Cannot open UI expander pin %d\n", sel_c); + goto exp_setup_selc_fail; + } + + /* deselect all functionalities */ + gpio_direction_output(sel_a, 1); + gpio_direction_output(sel_b, 1); + gpio_direction_output(sel_c, 1); + + da850_evm_ui_keys_init(gpio); + ret = platform_device_register(&da850_evm_ui_keys_device); + if (ret) { + pr_warning("Could not register UI GPIO expander push-buttons"); + goto exp_setup_keys_fail; + } + + pr_info("DA850/OMAP-L138 EVM UI card detected\n"); + + da850_evm_setup_nor_nand(); + + da850_evm_setup_emac_rmii(sel_a); + + return 0; + +exp_setup_keys_fail: + gpio_free(sel_c); +exp_setup_selc_fail: + gpio_free(sel_b); +exp_setup_selb_fail: + gpio_free(sel_a); +exp_setup_sela_fail: + return ret; +} + +static int da850_evm_ui_expander_teardown(struct i2c_client *client, + unsigned gpio, unsigned ngpio, void *c) +{ + platform_device_unregister(&da850_evm_ui_keys_device); + + /* deselect all functionalities */ + gpio_set_value_cansleep(gpio + DA850_EVM_UI_EXP_SEL_C, 1); + gpio_set_value_cansleep(gpio + DA850_EVM_UI_EXP_SEL_B, 1); + gpio_set_value_cansleep(gpio + DA850_EVM_UI_EXP_SEL_A, 1); + + gpio_free(gpio + DA850_EVM_UI_EXP_SEL_C); + gpio_free(gpio + DA850_EVM_UI_EXP_SEL_B); + gpio_free(gpio + DA850_EVM_UI_EXP_SEL_A); + + return 0; +} + +/* assign the baseboard expander's GPIOs after the UI board's */ +#define DA850_UI_EXPANDER_N_GPIOS ARRAY_SIZE(da850_evm_ui_exp) +#define DA850_BB_EXPANDER_GPIO_BASE (DAVINCI_N_GPIO + DA850_UI_EXPANDER_N_GPIOS) + +enum da850_evm_bb_exp_pins { + DA850_EVM_BB_EXP_DEEP_SLEEP_EN = 0, + DA850_EVM_BB_EXP_SW_RST, + DA850_EVM_BB_EXP_TP_23, + DA850_EVM_BB_EXP_TP_22, + DA850_EVM_BB_EXP_TP_21, + DA850_EVM_BB_EXP_USER_PB1, + DA850_EVM_BB_EXP_USER_LED2, + DA850_EVM_BB_EXP_USER_LED1, + DA850_EVM_BB_EXP_USER_SW1, + DA850_EVM_BB_EXP_USER_SW2, + DA850_EVM_BB_EXP_USER_SW3, + DA850_EVM_BB_EXP_USER_SW4, + DA850_EVM_BB_EXP_USER_SW5, + DA850_EVM_BB_EXP_USER_SW6, + DA850_EVM_BB_EXP_USER_SW7, + DA850_EVM_BB_EXP_USER_SW8 +}; + +static const char const *da850_evm_bb_exp[] = { + [DA850_EVM_BB_EXP_DEEP_SLEEP_EN] = "deep_sleep_en", + [DA850_EVM_BB_EXP_SW_RST] = "sw_rst", + [DA850_EVM_BB_EXP_TP_23] = "tp_23", + [DA850_EVM_BB_EXP_TP_22] = "tp_22", + [DA850_EVM_BB_EXP_TP_21] = "tp_21", + [DA850_EVM_BB_EXP_USER_PB1] = "user_pb1", + [DA850_EVM_BB_EXP_USER_LED2] = "user_led2", + [DA850_EVM_BB_EXP_USER_LED1] = "user_led1", + [DA850_EVM_BB_EXP_USER_SW1] = "user_sw1", + [DA850_EVM_BB_EXP_USER_SW2] = "user_sw2", + [DA850_EVM_BB_EXP_USER_SW3] = "user_sw3", + [DA850_EVM_BB_EXP_USER_SW4] = "user_sw4", + [DA850_EVM_BB_EXP_USER_SW5] = "user_sw5", + [DA850_EVM_BB_EXP_USER_SW6] = "user_sw6", + [DA850_EVM_BB_EXP_USER_SW7] = "user_sw7", + [DA850_EVM_BB_EXP_USER_SW8] = "user_sw8", +}; + +#define DA850_N_BB_USER_SW 8 + +static struct gpio_keys_button da850_evm_bb_keys[] = { + [0] = { + .type = EV_KEY, + .active_low = 1, + .wakeup = 0, + .debounce_interval = DA850_KEYS_DEBOUNCE_MS, + .code = KEY_PROG1, + .desc = NULL, /* assigned at runtime */ + .gpio = -1, /* assigned at runtime */ + }, + [1 ... DA850_N_BB_USER_SW] = { + .type = EV_SW, + .active_low = 1, + .wakeup = 0, + .debounce_interval = DA850_KEYS_DEBOUNCE_MS, + .code = -1, /* assigned at runtime */ + .desc = NULL, /* assigned at runtime */ + .gpio = -1, /* assigned at runtime */ + }, +}; + +static struct gpio_keys_platform_data da850_evm_bb_keys_pdata = { + .buttons = da850_evm_bb_keys, + .nbuttons = ARRAY_SIZE(da850_evm_bb_keys), + .poll_interval = DA850_GPIO_KEYS_POLL_MS, +}; + +static struct platform_device da850_evm_bb_keys_device = { + .name = "gpio-keys-polled", + .id = 1, + .dev = { + .platform_data = &da850_evm_bb_keys_pdata + }, +}; + +static void da850_evm_bb_keys_init(unsigned gpio) +{ + int i; + struct gpio_keys_button *button; + + button = &da850_evm_bb_keys[0]; + button->desc = (char *) + da850_evm_bb_exp[DA850_EVM_BB_EXP_USER_PB1]; + button->gpio = gpio + DA850_EVM_BB_EXP_USER_PB1; + + for (i = 0; i < DA850_N_BB_USER_SW; i++) { + button = &da850_evm_bb_keys[i + 1]; + button->code = SW_LID + i; + button->desc = (char *) + da850_evm_bb_exp[DA850_EVM_BB_EXP_USER_SW1 + i]; + button->gpio = gpio + DA850_EVM_BB_EXP_USER_SW1 + i; + } +} + +#define DA850_N_BB_USER_LED 2 + +static struct gpio_led da850_evm_bb_leds[] = { + [0 ... DA850_N_BB_USER_LED - 1] = { + .active_low = 1, + .gpio = -1, /* assigned at runtime */ + .name = NULL, /* assigned at runtime */ + }, +}; + +static struct gpio_led_platform_data da850_evm_bb_leds_pdata = { + .leds = da850_evm_bb_leds, + .num_leds = ARRAY_SIZE(da850_evm_bb_leds), +}; + +static struct platform_device da850_evm_bb_leds_device = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &da850_evm_bb_leds_pdata + } +}; + +static void da850_evm_bb_leds_init(unsigned gpio) +{ + int i; + struct gpio_led *led; + + for (i = 0; i < DA850_N_BB_USER_LED; i++) { + led = &da850_evm_bb_leds[i]; + + led->gpio = gpio + DA850_EVM_BB_EXP_USER_LED2 + i; + led->name = + da850_evm_bb_exp[DA850_EVM_BB_EXP_USER_LED2 + i]; + } +} + +static int da850_evm_bb_expander_setup(struct i2c_client *client, + unsigned gpio, unsigned ngpio, + void *c) +{ + int ret; + + /* + * Register the switches and pushbutton on the baseboard as a gpio-keys + * device. + */ + da850_evm_bb_keys_init(gpio); + ret = platform_device_register(&da850_evm_bb_keys_device); + if (ret) { + pr_warning("Could not register baseboard GPIO expander keys"); + goto io_exp_setup_sw_fail; + } + + da850_evm_bb_leds_init(gpio); + ret = platform_device_register(&da850_evm_bb_leds_device); + if (ret) { + pr_warning("Could not register baseboard GPIO expander LEDS"); + goto io_exp_setup_leds_fail; + } + + return 0; + +io_exp_setup_leds_fail: + platform_device_unregister(&da850_evm_bb_keys_device); +io_exp_setup_sw_fail: + return ret; +} + +static int da850_evm_bb_expander_teardown(struct i2c_client *client, + unsigned gpio, unsigned ngpio, void *c) +{ + platform_device_unregister(&da850_evm_bb_leds_device); + platform_device_unregister(&da850_evm_bb_keys_device); + + return 0; +} + +static struct pca953x_platform_data da850_evm_ui_expander_info = { + .gpio_base = DAVINCI_N_GPIO, + .setup = da850_evm_ui_expander_setup, + .teardown = da850_evm_ui_expander_teardown, + .names = da850_evm_ui_exp, +}; + +static struct pca953x_platform_data da850_evm_bb_expander_info = { + .gpio_base = DA850_BB_EXPANDER_GPIO_BASE, + .setup = da850_evm_bb_expander_setup, + .teardown = da850_evm_bb_expander_teardown, + .names = da850_evm_bb_exp, +}; + +static struct i2c_board_info __initdata da850_evm_i2c_devices[] = { + { + I2C_BOARD_INFO("tlv320aic3x", 0x18), + }, + { + I2C_BOARD_INFO("tca6416", 0x20), + .platform_data = &da850_evm_ui_expander_info, + }, + { + I2C_BOARD_INFO("tca6416", 0x21), + .platform_data = &da850_evm_bb_expander_info, + }, +}; + +static struct davinci_i2c_platform_data da850_evm_i2c_0_pdata = { + .bus_freq = 100, /* kHz */ + .bus_delay = 0, /* usec */ +}; + +static struct davinci_uart_config da850_evm_uart_config __initdata = { + .enabled_uarts = 0x7, +}; + +/* davinci da850 evm audio machine driver */ +static u8 da850_iis_serializer_direction[] = { + INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, + INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, + INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, TX_MODE, + RX_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, +}; + +static struct snd_platform_data da850_evm_snd_data = { + .tx_dma_offset = 0x2000, + .rx_dma_offset = 0x2000, + .op_mode = DAVINCI_MCASP_IIS_MODE, + .num_serializer = ARRAY_SIZE(da850_iis_serializer_direction), + .tdm_slots = 2, + .serial_dir = da850_iis_serializer_direction, + .asp_chan_q = EVENTQ_0, + .version = MCASP_VERSION_2, + .txnumevt = 1, + .rxnumevt = 1, +}; + +static const short da850_evm_mcasp_pins[] __initconst = { + DA850_AHCLKX, DA850_ACLKX, DA850_AFSX, + DA850_AHCLKR, DA850_ACLKR, DA850_AFSR, DA850_AMUTE, + DA850_AXR_11, DA850_AXR_12, + -1 +}; + +static int da850_evm_mmc_get_ro(int index) +{ + return gpio_get_value(DA850_MMCSD_WP_PIN); +} + +static int da850_evm_mmc_get_cd(int index) +{ + return !gpio_get_value(DA850_MMCSD_CD_PIN); +} + +static struct davinci_mmc_config da850_mmc_config = { + .get_ro = da850_evm_mmc_get_ro, + .get_cd = da850_evm_mmc_get_cd, + .wires = 4, + .max_freq = 50000000, + .caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED, + .version = MMC_CTLR_VERSION_2, +}; + +static const short da850_evm_mmcsd0_pins[] __initconst = { + DA850_MMCSD0_DAT_0, DA850_MMCSD0_DAT_1, DA850_MMCSD0_DAT_2, + DA850_MMCSD0_DAT_3, DA850_MMCSD0_CLK, DA850_MMCSD0_CMD, + DA850_GPIO4_0, DA850_GPIO4_1, + -1 +}; + +static void da850_panel_power_ctrl(int val) +{ + /* lcd backlight */ + gpio_set_value(DA850_LCD_BL_PIN, val); + + /* lcd power */ + gpio_set_value(DA850_LCD_PWR_PIN, val); +} + +static int da850_lcd_hw_init(void) +{ + int status; + + status = gpio_request(DA850_LCD_BL_PIN, "lcd bl\n"); + if (status < 0) + return status; + + status = gpio_request(DA850_LCD_PWR_PIN, "lcd pwr\n"); + if (status < 0) { + gpio_free(DA850_LCD_BL_PIN); + return status; + } + + gpio_direction_output(DA850_LCD_BL_PIN, 0); + gpio_direction_output(DA850_LCD_PWR_PIN, 0); + + /* Switch off panel power and backlight */ + da850_panel_power_ctrl(0); + + /* Switch on panel power and backlight */ + da850_panel_power_ctrl(1); + + return 0; +} + +/* TPS65070 voltage regulator support */ + +/* 3.3V */ +static struct regulator_consumer_supply tps65070_dcdc1_consumers[] = { + { + .supply = "usb0_vdda33", + }, + { + .supply = "usb1_vdda33", + }, +}; + +/* 3.3V or 1.8V */ +static struct regulator_consumer_supply tps65070_dcdc2_consumers[] = { + { + .supply = "dvdd3318_a", + }, + { + .supply = "dvdd3318_b", + }, + { + .supply = "dvdd3318_c", + }, +}; + +/* 1.2V */ +static struct regulator_consumer_supply tps65070_dcdc3_consumers[] = { + { + .supply = "cvdd", + }, +}; + +/* 1.8V LDO */ +static struct regulator_consumer_supply tps65070_ldo1_consumers[] = { + { + .supply = "sata_vddr", + }, + { + .supply = "usb0_vdda18", + }, + { + .supply = "usb1_vdda18", + }, + { + .supply = "ddr_dvdd18", + }, +}; + +/* 1.2V LDO */ +static struct regulator_consumer_supply tps65070_ldo2_consumers[] = { + { + .supply = "sata_vdd", + }, + { + .supply = "pll0_vdda", + }, + { + .supply = "pll1_vdda", + }, + { + .supply = "usbs_cvdd", + }, + { + .supply = "vddarnwa1", + }, +}; + +/* We take advantage of the fact that both defdcdc{2,3} are tied high */ +static struct tps6507x_reg_platform_data tps6507x_platform_data = { + .defdcdc_default = true, +}; + +static struct regulator_init_data tps65070_regulator_data[] = { + /* dcdc1 */ + { + .constraints = { + .min_uV = 3150000, + .max_uV = 3450000, + .valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS), + .boot_on = 1, + }, + .num_consumer_supplies = ARRAY_SIZE(tps65070_dcdc1_consumers), + .consumer_supplies = tps65070_dcdc1_consumers, + }, + + /* dcdc2 */ + { + .constraints = { + .min_uV = 1710000, + .max_uV = 3450000, + .valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS), + .boot_on = 1, + }, + .num_consumer_supplies = ARRAY_SIZE(tps65070_dcdc2_consumers), + .consumer_supplies = tps65070_dcdc2_consumers, + .driver_data = &tps6507x_platform_data, + }, + + /* dcdc3 */ + { + .constraints = { + .min_uV = 950000, + .max_uV = 1350000, + .valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS), + .boot_on = 1, + }, + .num_consumer_supplies = ARRAY_SIZE(tps65070_dcdc3_consumers), + .consumer_supplies = tps65070_dcdc3_consumers, + .driver_data = &tps6507x_platform_data, + }, + + /* ldo1 */ + { + .constraints = { + .min_uV = 1710000, + .max_uV = 1890000, + .valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS), + .boot_on = 1, + }, + .num_consumer_supplies = ARRAY_SIZE(tps65070_ldo1_consumers), + .consumer_supplies = tps65070_ldo1_consumers, + }, + + /* ldo2 */ + { + .constraints = { + .min_uV = 1140000, + .max_uV = 1320000, + .valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS), + .boot_on = 1, + }, + .num_consumer_supplies = ARRAY_SIZE(tps65070_ldo2_consumers), + .consumer_supplies = tps65070_ldo2_consumers, + }, +}; + +static struct touchscreen_init_data tps6507x_touchscreen_data = { + .poll_period = 30, /* ms between touch samples */ + .min_pressure = 0x30, /* minimum pressure to trigger touch */ + .vref = 0, /* turn off vref when not using A/D */ + .vendor = 0, /* /sys/class/input/input?/id/vendor */ + .product = 65070, /* /sys/class/input/input?/id/product */ + .version = 0x100, /* /sys/class/input/input?/id/version */ +}; + +static struct tps6507x_board tps_board = { + .tps6507x_pmic_init_data = &tps65070_regulator_data[0], + .tps6507x_ts_init_data = &tps6507x_touchscreen_data, +}; + +static struct i2c_board_info __initdata da850_evm_tps65070_info[] = { + { + I2C_BOARD_INFO("tps6507x", 0x48), + .platform_data = &tps_board, + }, +}; + +static int __init pmic_tps65070_init(void) +{ + return i2c_register_board_info(1, da850_evm_tps65070_info, + ARRAY_SIZE(da850_evm_tps65070_info)); +} + +static const short da850_evm_lcdc_pins[] = { + DA850_GPIO2_8, DA850_GPIO2_15, + -1 +}; + +static const short da850_evm_mii_pins[] = { + DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, + DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER, + DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3, + DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK, + DA850_MDIO_D, + -1 +}; + +static const short da850_evm_rmii_pins[] = { + DA850_RMII_TXD_0, DA850_RMII_TXD_1, DA850_RMII_TXEN, + DA850_RMII_CRS_DV, DA850_RMII_RXD_0, DA850_RMII_RXD_1, + DA850_RMII_RXER, DA850_RMII_MHZ_50_CLK, DA850_MDIO_CLK, + DA850_MDIO_D, + -1 +}; + +static int __init da850_evm_config_emac(void) +{ + void __iomem *cfg_chip3_base; + int ret; + u32 val; + struct davinci_soc_info *soc_info = &davinci_soc_info; + u8 rmii_en = soc_info->emac_pdata->rmii_en; + + if (!machine_is_davinci_da850_evm()) + return 0; + + cfg_chip3_base = DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG); + + val = __raw_readl(cfg_chip3_base); + + if (rmii_en) { + val |= BIT(8); + ret = davinci_cfg_reg_list(da850_evm_rmii_pins); + pr_info("EMAC: RMII PHY configured, MII PHY will not be" + " functional\n"); + } else { + val &= ~BIT(8); + ret = davinci_cfg_reg_list(da850_evm_mii_pins); + pr_info("EMAC: MII PHY configured, RMII PHY will not be" + " functional\n"); + } + + if (ret) + pr_warning("da850_evm_init: cpgmac/rmii mux setup failed: %d\n", + ret); + + /* configure the CFGCHIP3 register for RMII or MII */ + __raw_writel(val, cfg_chip3_base); + + ret = davinci_cfg_reg(DA850_GPIO2_6); + if (ret) + pr_warning("da850_evm_init:GPIO(2,6) mux setup " + "failed\n"); + + ret = gpio_request(DA850_MII_MDIO_CLKEN_PIN, "mdio_clk_en"); + if (ret) { + pr_warning("Cannot open GPIO %d\n", + DA850_MII_MDIO_CLKEN_PIN); + return ret; + } + + /* Enable/Disable MII MDIO clock */ + gpio_direction_output(DA850_MII_MDIO_CLKEN_PIN, rmii_en); + + soc_info->emac_pdata->phy_id = DA850_EVM_PHY_ID; + + ret = da8xx_register_emac(); + if (ret) + pr_warning("da850_evm_init: emac registration failed: %d\n", + ret); + + return 0; +} +device_initcall(da850_evm_config_emac); + +/* + * The following EDMA channels/slots are not being used by drivers (for + * example: Timer, GPIO, UART events etc) on da850/omap-l138 EVM, hence + * they are being reserved for codecs on the DSP side. + */ +static const s16 da850_dma0_rsv_chans[][2] = { + /* (offset, number) */ + { 8, 6}, + {24, 4}, + {30, 2}, + {-1, -1} +}; + +static const s16 da850_dma0_rsv_slots[][2] = { + /* (offset, number) */ + { 8, 6}, + {24, 4}, + {30, 50}, + {-1, -1} +}; + +static const s16 da850_dma1_rsv_chans[][2] = { + /* (offset, number) */ + { 0, 28}, + {30, 2}, + {-1, -1} +}; + +static const s16 da850_dma1_rsv_slots[][2] = { + /* (offset, number) */ + { 0, 28}, + {30, 90}, + {-1, -1} +}; + +static struct edma_rsv_info da850_edma_cc0_rsv = { + .rsv_chans = da850_dma0_rsv_chans, + .rsv_slots = da850_dma0_rsv_slots, +}; + +static struct edma_rsv_info da850_edma_cc1_rsv = { + .rsv_chans = da850_dma1_rsv_chans, + .rsv_slots = da850_dma1_rsv_slots, +}; + +static struct edma_rsv_info *da850_edma_rsv[2] = { + &da850_edma_cc0_rsv, + &da850_edma_cc1_rsv, +}; + +#ifdef CONFIG_CPU_FREQ +static __init int da850_evm_init_cpufreq(void) +{ + switch (system_rev & 0xF) { + case 3: + da850_max_speed = 456000; + break; + case 2: + da850_max_speed = 408000; + break; + case 1: + da850_max_speed = 372000; + break; + } + + return da850_register_cpufreq("pll0_sysclk3"); +} +#else +static __init int da850_evm_init_cpufreq(void) { return 0; } +#endif + +#ifdef CONFIG_DA850_WL12XX + +static void wl12xx_set_power(int index, bool power_on) +{ + static bool power_state; + + pr_debug("Powering %s wl12xx", power_on ? "on" : "off"); + + if (power_on == power_state) + return; + power_state = power_on; + + if (power_on) { + /* Power up sequence required for wl127x devices */ + gpio_set_value(DA850_WLAN_EN, 1); + usleep_range(15000, 15000); + gpio_set_value(DA850_WLAN_EN, 0); + usleep_range(1000, 1000); + gpio_set_value(DA850_WLAN_EN, 1); + msleep(70); + } else { + gpio_set_value(DA850_WLAN_EN, 0); + } +} + +static struct davinci_mmc_config da850_wl12xx_mmc_config = { + .set_power = wl12xx_set_power, + .wires = 4, + .max_freq = 25000000, + .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_NONREMOVABLE | + MMC_CAP_POWER_OFF_CARD, + .version = MMC_CTLR_VERSION_2, +}; + +static const short da850_wl12xx_pins[] __initconst = { + DA850_MMCSD1_DAT_0, DA850_MMCSD1_DAT_1, DA850_MMCSD1_DAT_2, + DA850_MMCSD1_DAT_3, DA850_MMCSD1_CLK, DA850_MMCSD1_CMD, + DA850_GPIO6_9, DA850_GPIO6_10, + -1 +}; + +static struct wl12xx_platform_data da850_wl12xx_wlan_data __initdata = { + .irq = -1, + .board_ref_clock = WL12XX_REFCLOCK_38, + .platform_quirks = WL12XX_PLATFORM_QUIRK_EDGE_IRQ, +}; + +static __init int da850_wl12xx_init(void) +{ + int ret; + + ret = davinci_cfg_reg_list(da850_wl12xx_pins); + if (ret) { + pr_err("wl12xx/mmc mux setup failed: %d\n", ret); + goto exit; + } + + ret = da850_register_mmcsd1(&da850_wl12xx_mmc_config); + if (ret) { + pr_err("wl12xx/mmc registration failed: %d\n", ret); + goto exit; + } + + ret = gpio_request_one(DA850_WLAN_EN, GPIOF_OUT_INIT_LOW, "wl12xx_en"); + if (ret) { + pr_err("Could not request wl12xx enable gpio: %d\n", ret); + goto exit; + } + + ret = gpio_request_one(DA850_WLAN_IRQ, GPIOF_IN, "wl12xx_irq"); + if (ret) { + pr_err("Could not request wl12xx irq gpio: %d\n", ret); + goto free_wlan_en; + } + + da850_wl12xx_wlan_data.irq = gpio_to_irq(DA850_WLAN_IRQ); + + ret = wl12xx_set_platform_data(&da850_wl12xx_wlan_data); + if (ret) { + pr_err("Could not set wl12xx data: %d\n", ret); + goto free_wlan_irq; + } + + return 0; + +free_wlan_irq: + gpio_free(DA850_WLAN_IRQ); + +free_wlan_en: + gpio_free(DA850_WLAN_EN); + +exit: + return ret; +} + +#else /* CONFIG_DA850_WL12XX */ + +static __init int da850_wl12xx_init(void) +{ + return 0; +} + +#endif /* CONFIG_DA850_WL12XX */ + +#define DA850EVM_SATA_REFCLKPN_RATE (100 * 1000 * 1000) + +static __init void da850_evm_init(void) +{ + int ret; + + ret = pmic_tps65070_init(); + if (ret) + pr_warning("da850_evm_init: TPS65070 PMIC init failed: %d\n", + ret); + + ret = da850_register_edma(da850_edma_rsv); + if (ret) + pr_warning("da850_evm_init: edma registration failed: %d\n", + ret); + + ret = davinci_cfg_reg_list(da850_i2c0_pins); + if (ret) + pr_warning("da850_evm_init: i2c0 mux setup failed: %d\n", + ret); + + ret = da8xx_register_i2c(0, &da850_evm_i2c_0_pdata); + if (ret) + pr_warning("da850_evm_init: i2c0 registration failed: %d\n", + ret); + + + ret = da8xx_register_watchdog(); + if (ret) + pr_warning("da830_evm_init: watchdog registration failed: %d\n", + ret); + + if (HAS_MMC) { + ret = davinci_cfg_reg_list(da850_evm_mmcsd0_pins); + if (ret) + pr_warning("da850_evm_init: mmcsd0 mux setup failed:" + " %d\n", ret); + + ret = gpio_request(DA850_MMCSD_CD_PIN, "MMC CD\n"); + if (ret) + pr_warning("da850_evm_init: can not open GPIO %d\n", + DA850_MMCSD_CD_PIN); + gpio_direction_input(DA850_MMCSD_CD_PIN); + + ret = gpio_request(DA850_MMCSD_WP_PIN, "MMC WP\n"); + if (ret) + pr_warning("da850_evm_init: can not open GPIO %d\n", + DA850_MMCSD_WP_PIN); + gpio_direction_input(DA850_MMCSD_WP_PIN); + + ret = da8xx_register_mmcsd0(&da850_mmc_config); + if (ret) + pr_warning("da850_evm_init: mmcsd0 registration failed:" + " %d\n", ret); + + ret = da850_wl12xx_init(); + if (ret) + pr_warning("da850_evm_init: wl12xx initialization" + " failed: %d\n", ret); + } + + davinci_serial_init(&da850_evm_uart_config); + + i2c_register_board_info(1, da850_evm_i2c_devices, + ARRAY_SIZE(da850_evm_i2c_devices)); + + /* + * shut down uart 0 and 1; they are not used on the board and + * accessing them causes endless "too much work in irq53" messages + * with arago fs + */ + __raw_writel(0, IO_ADDRESS(DA8XX_UART1_BASE) + 0x30); + __raw_writel(0, IO_ADDRESS(DA8XX_UART0_BASE) + 0x30); + + ret = davinci_cfg_reg_list(da850_evm_mcasp_pins); + if (ret) + pr_warning("da850_evm_init: mcasp mux setup failed: %d\n", + ret); + + da8xx_register_mcasp(0, &da850_evm_snd_data); + + ret = davinci_cfg_reg_list(da850_lcdcntl_pins); + if (ret) + pr_warning("da850_evm_init: lcdcntl mux setup failed: %d\n", + ret); + + /* Handle board specific muxing for LCD here */ + ret = davinci_cfg_reg_list(da850_evm_lcdc_pins); + if (ret) + pr_warning("da850_evm_init: evm specific lcd mux setup " + "failed: %d\n", ret); + + ret = da850_lcd_hw_init(); + if (ret) + pr_warning("da850_evm_init: lcd initialization failed: %d\n", + ret); + + sharp_lk043t1dg01_pdata.panel_power_ctrl = da850_panel_power_ctrl, + ret = da8xx_register_lcdc(&sharp_lk043t1dg01_pdata); + if (ret) + pr_warning("da850_evm_init: lcdc registration failed: %d\n", + ret); + + ret = da8xx_register_rtc(); + if (ret) + pr_warning("da850_evm_init: rtc setup failed: %d\n", ret); + + ret = da850_evm_init_cpufreq(); + if (ret) + pr_warning("da850_evm_init: cpufreq registration failed: %d\n", + ret); + + ret = da8xx_register_cpuidle(); + if (ret) + pr_warning("da850_evm_init: cpuidle registration failed: %d\n", + ret); + + ret = da850_register_pm(&da850_pm_device); + if (ret) + pr_warning("da850_evm_init: suspend registration failed: %d\n", + ret); + + ret = da8xx_register_spi(1, da850evm_spi_info, + ARRAY_SIZE(da850evm_spi_info)); + if (ret) + pr_warning("da850_evm_init: spi 1 registration failed: %d\n", + ret); + + ret = da850_register_sata(DA850EVM_SATA_REFCLKPN_RATE); + if (ret) + pr_warning("da850_evm_init: sata registration failed: %d\n", + ret); + + da850_evm_setup_mac_addr(); +} + +#ifdef CONFIG_SERIAL_8250_CONSOLE +static int __init da850_evm_console_init(void) +{ + if (!machine_is_davinci_da850_evm()) + return 0; + + return add_preferred_console("ttyS", 2, "115200"); +} +console_initcall(da850_evm_console_init); +#endif + +static void __init da850_evm_map_io(void) +{ + da850_init(); +} + +MACHINE_START(DAVINCI_DA850_EVM, "DaVinci DA850/OMAP-L138/AM18x EVM") + .atag_offset = 0x100, + .map_io = da850_evm_map_io, + .init_irq = cp_intc_init, + .timer = &davinci_timer, + .init_machine = da850_evm_init, + .dma_zone_size = SZ_128M, + .restart = da8xx_restart, +MACHINE_END diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/board-dm355-evm.c b/ANDROID_3.4.5/arch/arm/mach-davinci/board-dm355-evm.c new file mode 100644 index 00000000..82ed753f --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/board-dm355-evm.c @@ -0,0 +1,362 @@ +/* + * TI DaVinci EVM board support + * + * Author: Kevin Hilman, Deep Root Systems, LLC + * + * 2007 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/err.h> +#include <linux/platform_device.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> +#include <linux/mtd/nand.h> +#include <linux/i2c.h> +#include <linux/gpio.h> +#include <linux/clk.h> +#include <linux/videodev2.h> +#include <media/tvp514x.h> +#include <linux/spi/spi.h> +#include <linux/spi/eeprom.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> + +#include <mach/i2c.h> +#include <mach/serial.h> +#include <mach/nand.h> +#include <mach/mmc.h> +#include <mach/usb.h> + +#include "davinci.h" + +/* NOTE: this is geared for the standard config, with a socketed + * 2 GByte Micron NAND (MT29F16G08FAA) using 128KB sectors. If you + * swap chips, maybe with a different block size, partitioning may + * need to be changed. + */ +#define NAND_BLOCK_SIZE SZ_128K + +static struct mtd_partition davinci_nand_partitions[] = { + { + /* UBL (a few copies) plus U-Boot */ + .name = "bootloader", + .offset = 0, + .size = 15 * NAND_BLOCK_SIZE, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, { + /* U-Boot environment */ + .name = "params", + .offset = MTDPART_OFS_APPEND, + .size = 1 * NAND_BLOCK_SIZE, + .mask_flags = 0, + }, { + .name = "kernel", + .offset = MTDPART_OFS_APPEND, + .size = SZ_4M, + .mask_flags = 0, + }, { + .name = "filesystem1", + .offset = MTDPART_OFS_APPEND, + .size = SZ_512M, + .mask_flags = 0, + }, { + .name = "filesystem2", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + .mask_flags = 0, + } + /* two blocks with bad block table (and mirror) at the end */ +}; + +static struct davinci_nand_pdata davinci_nand_data = { + .mask_chipsel = BIT(14), + .parts = davinci_nand_partitions, + .nr_parts = ARRAY_SIZE(davinci_nand_partitions), + .ecc_mode = NAND_ECC_HW, + .bbt_options = NAND_BBT_USE_FLASH, + .ecc_bits = 4, +}; + +static struct resource davinci_nand_resources[] = { + { + .start = DM355_ASYNC_EMIF_DATA_CE0_BASE, + .end = DM355_ASYNC_EMIF_DATA_CE0_BASE + SZ_32M - 1, + .flags = IORESOURCE_MEM, + }, { + .start = DM355_ASYNC_EMIF_CONTROL_BASE, + .end = DM355_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device davinci_nand_device = { + .name = "davinci_nand", + .id = 0, + + .num_resources = ARRAY_SIZE(davinci_nand_resources), + .resource = davinci_nand_resources, + + .dev = { + .platform_data = &davinci_nand_data, + }, +}; + +static struct davinci_i2c_platform_data i2c_pdata = { + .bus_freq = 400 /* kHz */, + .bus_delay = 0 /* usec */, + .sda_pin = 15, + .scl_pin = 14, +}; + +static struct snd_platform_data dm355_evm_snd_data; + +static int dm355evm_mmc_gpios = -EINVAL; + +static void dm355evm_mmcsd_gpios(unsigned gpio) +{ + gpio_request(gpio + 0, "mmc0_ro"); + gpio_request(gpio + 1, "mmc0_cd"); + gpio_request(gpio + 2, "mmc1_ro"); + gpio_request(gpio + 3, "mmc1_cd"); + + /* we "know" these are input-only so we don't + * need to call gpio_direction_input() + */ + + dm355evm_mmc_gpios = gpio; +} + +static struct i2c_board_info dm355evm_i2c_info[] = { + { I2C_BOARD_INFO("dm355evm_msp", 0x25), + .platform_data = dm355evm_mmcsd_gpios, + }, + /* { plus irq }, */ + { I2C_BOARD_INFO("tlv320aic33", 0x1b), }, +}; + +static void __init evm_init_i2c(void) +{ + davinci_init_i2c(&i2c_pdata); + + gpio_request(5, "dm355evm_msp"); + gpio_direction_input(5); + dm355evm_i2c_info[0].irq = gpio_to_irq(5); + + i2c_register_board_info(1, dm355evm_i2c_info, + ARRAY_SIZE(dm355evm_i2c_info)); +} + +static struct resource dm355evm_dm9000_rsrc[] = { + { + /* addr */ + .start = 0x04014000, + .end = 0x04014001, + .flags = IORESOURCE_MEM, + }, { + /* data */ + .start = 0x04014002, + .end = 0x04014003, + .flags = IORESOURCE_MEM, + }, { + .flags = IORESOURCE_IRQ + | IORESOURCE_IRQ_HIGHEDGE /* rising (active high) */, + }, +}; + +static struct platform_device dm355evm_dm9000 = { + .name = "dm9000", + .id = -1, + .resource = dm355evm_dm9000_rsrc, + .num_resources = ARRAY_SIZE(dm355evm_dm9000_rsrc), +}; + +static struct tvp514x_platform_data tvp5146_pdata = { + .clk_polarity = 0, + .hs_polarity = 1, + .vs_polarity = 1 +}; + +#define TVP514X_STD_ALL (V4L2_STD_NTSC | V4L2_STD_PAL) +/* Inputs available at the TVP5146 */ +static struct v4l2_input tvp5146_inputs[] = { + { + .index = 0, + .name = "Composite", + .type = V4L2_INPUT_TYPE_CAMERA, + .std = TVP514X_STD_ALL, + }, + { + .index = 1, + .name = "S-Video", + .type = V4L2_INPUT_TYPE_CAMERA, + .std = TVP514X_STD_ALL, + }, +}; + +/* + * this is the route info for connecting each input to decoder + * ouput that goes to vpfe. There is a one to one correspondence + * with tvp5146_inputs + */ +static struct vpfe_route tvp5146_routes[] = { + { + .input = INPUT_CVBS_VI2B, + .output = OUTPUT_10BIT_422_EMBEDDED_SYNC, + }, + { + .input = INPUT_SVIDEO_VI2C_VI1C, + .output = OUTPUT_10BIT_422_EMBEDDED_SYNC, + }, +}; + +static struct vpfe_subdev_info vpfe_sub_devs[] = { + { + .name = "tvp5146", + .grp_id = 0, + .num_inputs = ARRAY_SIZE(tvp5146_inputs), + .inputs = tvp5146_inputs, + .routes = tvp5146_routes, + .can_route = 1, + .ccdc_if_params = { + .if_type = VPFE_BT656, + .hdpol = VPFE_PINPOL_POSITIVE, + .vdpol = VPFE_PINPOL_POSITIVE, + }, + .board_info = { + I2C_BOARD_INFO("tvp5146", 0x5d), + .platform_data = &tvp5146_pdata, + }, + } +}; + +static struct vpfe_config vpfe_cfg = { + .num_subdevs = ARRAY_SIZE(vpfe_sub_devs), + .i2c_adapter_id = 1, + .sub_devs = vpfe_sub_devs, + .card_name = "DM355 EVM", + .ccdc = "DM355 CCDC", +}; + +static struct platform_device *davinci_evm_devices[] __initdata = { + &dm355evm_dm9000, + &davinci_nand_device, +}; + +static struct davinci_uart_config uart_config __initdata = { + .enabled_uarts = (1 << 0), +}; + +static void __init dm355_evm_map_io(void) +{ + /* setup input configuration for VPFE input devices */ + dm355_set_vpfe_config(&vpfe_cfg); + dm355_init(); +} + +static int dm355evm_mmc_get_cd(int module) +{ + if (!gpio_is_valid(dm355evm_mmc_gpios)) + return -ENXIO; + /* low == card present */ + return !gpio_get_value_cansleep(dm355evm_mmc_gpios + 2 * module + 1); +} + +static int dm355evm_mmc_get_ro(int module) +{ + if (!gpio_is_valid(dm355evm_mmc_gpios)) + return -ENXIO; + /* high == card's write protect switch active */ + return gpio_get_value_cansleep(dm355evm_mmc_gpios + 2 * module + 0); +} + +static struct davinci_mmc_config dm355evm_mmc_config = { + .get_cd = dm355evm_mmc_get_cd, + .get_ro = dm355evm_mmc_get_ro, + .wires = 4, + .max_freq = 50000000, + .caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED, + .version = MMC_CTLR_VERSION_1, +}; + +/* Don't connect anything to J10 unless you're only using USB host + * mode *and* have to do so with some kind of gender-bender. If + * you have proper Mini-B or Mini-A cables (or Mini-A adapters) + * the ID pin won't need any help. + */ +#ifdef CONFIG_USB_MUSB_PERIPHERAL +#define USB_ID_VALUE 0 /* ID pulled high; *should* float */ +#else +#define USB_ID_VALUE 1 /* ID pulled low */ +#endif + +static struct spi_eeprom at25640a = { + .byte_len = SZ_64K / 8, + .name = "at25640a", + .page_size = 32, + .flags = EE_ADDR2, +}; + +static struct spi_board_info dm355_evm_spi_info[] __initconst = { + { + .modalias = "at25", + .platform_data = &at25640a, + .max_speed_hz = 10 * 1000 * 1000, /* at 3v3 */ + .bus_num = 0, + .chip_select = 0, + .mode = SPI_MODE_0, + }, +}; + +static __init void dm355_evm_init(void) +{ + struct clk *aemif; + + gpio_request(1, "dm9000"); + gpio_direction_input(1); + dm355evm_dm9000_rsrc[2].start = gpio_to_irq(1); + + aemif = clk_get(&dm355evm_dm9000.dev, "aemif"); + if (IS_ERR(aemif)) + WARN("%s: unable to get AEMIF clock\n", __func__); + else + clk_enable(aemif); + + platform_add_devices(davinci_evm_devices, + ARRAY_SIZE(davinci_evm_devices)); + evm_init_i2c(); + davinci_serial_init(&uart_config); + + /* NOTE: NAND flash timings set by the UBL are slower than + * needed by MT29F16G08FAA chips ... EMIF.A1CR is 0x40400204 + * but could be 0x0400008c for about 25% faster page reads. + */ + + gpio_request(2, "usb_id_toggle"); + gpio_direction_output(2, USB_ID_VALUE); + /* irlml6401 switches over 1A in under 8 msec */ + davinci_setup_usb(1000, 8); + + davinci_setup_mmc(0, &dm355evm_mmc_config); + davinci_setup_mmc(1, &dm355evm_mmc_config); + + dm355_init_spi0(BIT(0), dm355_evm_spi_info, + ARRAY_SIZE(dm355_evm_spi_info)); + + /* DM335 EVM uses ASP1; line-out is a stereo mini-jack */ + dm355_init_asp1(ASP1_TX_EVT_EN | ASP1_RX_EVT_EN, &dm355_evm_snd_data); +} + +MACHINE_START(DAVINCI_DM355_EVM, "DaVinci DM355 EVM") + .atag_offset = 0x100, + .map_io = dm355_evm_map_io, + .init_irq = davinci_irq_init, + .timer = &davinci_timer, + .init_machine = dm355_evm_init, + .dma_zone_size = SZ_128M, + .restart = davinci_restart, +MACHINE_END diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/board-dm355-leopard.c b/ANDROID_3.4.5/arch/arm/mach-davinci/board-dm355-leopard.c new file mode 100644 index 00000000..d74a8b34 --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/board-dm355-leopard.c @@ -0,0 +1,281 @@ +/* + * DM355 leopard board support + * + * Based on board-dm355-evm.c + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/err.h> +#include <linux/platform_device.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> +#include <linux/mtd/nand.h> +#include <linux/i2c.h> +#include <linux/gpio.h> +#include <linux/clk.h> +#include <linux/spi/spi.h> +#include <linux/spi/eeprom.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> + +#include <mach/i2c.h> +#include <mach/serial.h> +#include <mach/nand.h> +#include <mach/mmc.h> +#include <mach/usb.h> + +#include "davinci.h" + +/* NOTE: this is geared for the standard config, with a socketed + * 2 GByte Micron NAND (MT29F16G08FAA) using 128KB sectors. If you + * swap chips, maybe with a different block size, partitioning may + * need to be changed. + */ +#define NAND_BLOCK_SIZE SZ_128K + +static struct mtd_partition davinci_nand_partitions[] = { + { + /* UBL (a few copies) plus U-Boot */ + .name = "bootloader", + .offset = 0, + .size = 15 * NAND_BLOCK_SIZE, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, { + /* U-Boot environment */ + .name = "params", + .offset = MTDPART_OFS_APPEND, + .size = 1 * NAND_BLOCK_SIZE, + .mask_flags = 0, + }, { + .name = "kernel", + .offset = MTDPART_OFS_APPEND, + .size = SZ_4M, + .mask_flags = 0, + }, { + .name = "filesystem1", + .offset = MTDPART_OFS_APPEND, + .size = SZ_512M, + .mask_flags = 0, + }, { + .name = "filesystem2", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + .mask_flags = 0, + } + /* two blocks with bad block table (and mirror) at the end */ +}; + +static struct davinci_nand_pdata davinci_nand_data = { + .mask_chipsel = BIT(14), + .parts = davinci_nand_partitions, + .nr_parts = ARRAY_SIZE(davinci_nand_partitions), + .ecc_mode = NAND_ECC_HW_SYNDROME, + .bbt_options = NAND_BBT_USE_FLASH, +}; + +static struct resource davinci_nand_resources[] = { + { + .start = DM355_ASYNC_EMIF_DATA_CE0_BASE, + .end = DM355_ASYNC_EMIF_DATA_CE0_BASE + SZ_32M - 1, + .flags = IORESOURCE_MEM, + }, { + .start = DM355_ASYNC_EMIF_CONTROL_BASE, + .end = DM355_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device davinci_nand_device = { + .name = "davinci_nand", + .id = 0, + + .num_resources = ARRAY_SIZE(davinci_nand_resources), + .resource = davinci_nand_resources, + + .dev = { + .platform_data = &davinci_nand_data, + }, +}; + +static struct davinci_i2c_platform_data i2c_pdata = { + .bus_freq = 400 /* kHz */, + .bus_delay = 0 /* usec */, +}; + +static int leopard_mmc_gpio = -EINVAL; + +static void dm355leopard_mmcsd_gpios(unsigned gpio) +{ + gpio_request(gpio + 0, "mmc0_ro"); + gpio_request(gpio + 1, "mmc0_cd"); + gpio_request(gpio + 2, "mmc1_ro"); + gpio_request(gpio + 3, "mmc1_cd"); + + /* we "know" these are input-only so we don't + * need to call gpio_direction_input() + */ + + leopard_mmc_gpio = gpio; +} + +static struct i2c_board_info dm355leopard_i2c_info[] = { + { I2C_BOARD_INFO("dm355leopard_msp", 0x25), + .platform_data = dm355leopard_mmcsd_gpios, + /* plus irq */ }, + /* { I2C_BOARD_INFO("tlv320aic3x", 0x1b), }, */ + /* { I2C_BOARD_INFO("tvp5146", 0x5d), }, */ +}; + +static void __init leopard_init_i2c(void) +{ + davinci_init_i2c(&i2c_pdata); + + gpio_request(5, "dm355leopard_msp"); + gpio_direction_input(5); + dm355leopard_i2c_info[0].irq = gpio_to_irq(5); + + i2c_register_board_info(1, dm355leopard_i2c_info, + ARRAY_SIZE(dm355leopard_i2c_info)); +} + +static struct resource dm355leopard_dm9000_rsrc[] = { + { + /* addr */ + .start = 0x04000000, + .end = 0x04000001, + .flags = IORESOURCE_MEM, + }, { + /* data */ + .start = 0x04000016, + .end = 0x04000017, + .flags = IORESOURCE_MEM, + }, { + .flags = IORESOURCE_IRQ + | IORESOURCE_IRQ_HIGHEDGE /* rising (active high) */, + }, +}; + +static struct platform_device dm355leopard_dm9000 = { + .name = "dm9000", + .id = -1, + .resource = dm355leopard_dm9000_rsrc, + .num_resources = ARRAY_SIZE(dm355leopard_dm9000_rsrc), +}; + +static struct platform_device *davinci_leopard_devices[] __initdata = { + &dm355leopard_dm9000, + &davinci_nand_device, +}; + +static struct davinci_uart_config uart_config __initdata = { + .enabled_uarts = (1 << 0), +}; + +static void __init dm355_leopard_map_io(void) +{ + dm355_init(); +} + +static int dm355leopard_mmc_get_cd(int module) +{ + if (!gpio_is_valid(leopard_mmc_gpio)) + return -ENXIO; + /* low == card present */ + return !gpio_get_value_cansleep(leopard_mmc_gpio + 2 * module + 1); +} + +static int dm355leopard_mmc_get_ro(int module) +{ + if (!gpio_is_valid(leopard_mmc_gpio)) + return -ENXIO; + /* high == card's write protect switch active */ + return gpio_get_value_cansleep(leopard_mmc_gpio + 2 * module + 0); +} + +static struct davinci_mmc_config dm355leopard_mmc_config = { + .get_cd = dm355leopard_mmc_get_cd, + .get_ro = dm355leopard_mmc_get_ro, + .wires = 4, + .max_freq = 50000000, + .caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED, +}; + +/* Don't connect anything to J10 unless you're only using USB host + * mode *and* have to do so with some kind of gender-bender. If + * you have proper Mini-B or Mini-A cables (or Mini-A adapters) + * the ID pin won't need any help. + */ +#ifdef CONFIG_USB_MUSB_PERIPHERAL +#define USB_ID_VALUE 0 /* ID pulled high; *should* float */ +#else +#define USB_ID_VALUE 1 /* ID pulled low */ +#endif + +static struct spi_eeprom at25640a = { + .byte_len = SZ_64K / 8, + .name = "at25640a", + .page_size = 32, + .flags = EE_ADDR2, +}; + +static struct spi_board_info dm355_leopard_spi_info[] __initconst = { + { + .modalias = "at25", + .platform_data = &at25640a, + .max_speed_hz = 10 * 1000 * 1000, /* at 3v3 */ + .bus_num = 0, + .chip_select = 0, + .mode = SPI_MODE_0, + }, +}; + +static __init void dm355_leopard_init(void) +{ + struct clk *aemif; + + gpio_request(9, "dm9000"); + gpio_direction_input(9); + dm355leopard_dm9000_rsrc[2].start = gpio_to_irq(9); + + aemif = clk_get(&dm355leopard_dm9000.dev, "aemif"); + if (IS_ERR(aemif)) + WARN("%s: unable to get AEMIF clock\n", __func__); + else + clk_enable(aemif); + + platform_add_devices(davinci_leopard_devices, + ARRAY_SIZE(davinci_leopard_devices)); + leopard_init_i2c(); + davinci_serial_init(&uart_config); + + /* NOTE: NAND flash timings set by the UBL are slower than + * needed by MT29F16G08FAA chips ... EMIF.A1CR is 0x40400204 + * but could be 0x0400008c for about 25% faster page reads. + */ + + gpio_request(2, "usb_id_toggle"); + gpio_direction_output(2, USB_ID_VALUE); + /* irlml6401 switches over 1A in under 8 msec */ + davinci_setup_usb(1000, 8); + + davinci_setup_mmc(0, &dm355leopard_mmc_config); + davinci_setup_mmc(1, &dm355leopard_mmc_config); + + dm355_init_spi0(BIT(0), dm355_leopard_spi_info, + ARRAY_SIZE(dm355_leopard_spi_info)); +} + +MACHINE_START(DM355_LEOPARD, "DaVinci DM355 leopard") + .atag_offset = 0x100, + .map_io = dm355_leopard_map_io, + .init_irq = davinci_irq_init, + .timer = &davinci_timer, + .init_machine = dm355_leopard_init, + .dma_zone_size = SZ_128M, + .restart = davinci_restart, +MACHINE_END diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/board-dm365-evm.c b/ANDROID_3.4.5/arch/arm/mach-davinci/board-dm365-evm.c new file mode 100644 index 00000000..5bce2b83 --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/board-dm365-evm.c @@ -0,0 +1,624 @@ +/* + * TI DaVinci DM365 EVM board support + * + * Copyright (C) 2009 Texas Instruments Incorporated + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/err.h> +#include <linux/i2c.h> +#include <linux/io.h> +#include <linux/clk.h> +#include <linux/i2c/at24.h> +#include <linux/leds.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> +#include <linux/slab.h> +#include <linux/mtd/nand.h> +#include <linux/input.h> +#include <linux/spi/spi.h> +#include <linux/spi/eeprom.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> + +#include <mach/mux.h> +#include <mach/common.h> +#include <mach/i2c.h> +#include <mach/serial.h> +#include <mach/mmc.h> +#include <mach/nand.h> +#include <mach/keyscan.h> + +#include <media/tvp514x.h> + +#include "davinci.h" + +static inline int have_imager(void) +{ + /* REVISIT when it's supported, trigger via Kconfig */ + return 0; +} + +static inline int have_tvp7002(void) +{ + /* REVISIT when it's supported, trigger via Kconfig */ + return 0; +} + +#define DM365_EVM_PHY_ID "davinci_mdio-0:01" +/* + * A MAX-II CPLD is used for various board control functions. + */ +#define CPLD_OFFSET(a13a8,a2a1) (((a13a8) << 10) + ((a2a1) << 3)) + +#define CPLD_VERSION CPLD_OFFSET(0,0) /* r/o */ +#define CPLD_TEST CPLD_OFFSET(0,1) +#define CPLD_LEDS CPLD_OFFSET(0,2) +#define CPLD_MUX CPLD_OFFSET(0,3) +#define CPLD_SWITCH CPLD_OFFSET(1,0) /* r/o */ +#define CPLD_POWER CPLD_OFFSET(1,1) +#define CPLD_VIDEO CPLD_OFFSET(1,2) +#define CPLD_CARDSTAT CPLD_OFFSET(1,3) /* r/o */ + +#define CPLD_DILC_OUT CPLD_OFFSET(2,0) +#define CPLD_DILC_IN CPLD_OFFSET(2,1) /* r/o */ + +#define CPLD_IMG_DIR0 CPLD_OFFSET(2,2) +#define CPLD_IMG_MUX0 CPLD_OFFSET(2,3) +#define CPLD_IMG_MUX1 CPLD_OFFSET(3,0) +#define CPLD_IMG_DIR1 CPLD_OFFSET(3,1) +#define CPLD_IMG_MUX2 CPLD_OFFSET(3,2) +#define CPLD_IMG_MUX3 CPLD_OFFSET(3,3) +#define CPLD_IMG_DIR2 CPLD_OFFSET(4,0) +#define CPLD_IMG_MUX4 CPLD_OFFSET(4,1) +#define CPLD_IMG_MUX5 CPLD_OFFSET(4,2) + +#define CPLD_RESETS CPLD_OFFSET(4,3) + +#define CPLD_CCD_DIR1 CPLD_OFFSET(0x3e,0) +#define CPLD_CCD_IO1 CPLD_OFFSET(0x3e,1) +#define CPLD_CCD_DIR2 CPLD_OFFSET(0x3e,2) +#define CPLD_CCD_IO2 CPLD_OFFSET(0x3e,3) +#define CPLD_CCD_DIR3 CPLD_OFFSET(0x3f,0) +#define CPLD_CCD_IO3 CPLD_OFFSET(0x3f,1) + +static void __iomem *cpld; + + +/* NOTE: this is geared for the standard config, with a socketed + * 2 GByte Micron NAND (MT29F16G08FAA) using 128KB sectors. If you + * swap chips with a different block size, partitioning will + * need to be changed. This NAND chip MT29F16G08FAA is the default + * NAND shipped with the Spectrum Digital DM365 EVM + */ +#define NAND_BLOCK_SIZE SZ_128K + +static struct mtd_partition davinci_nand_partitions[] = { + { + /* UBL (a few copies) plus U-Boot */ + .name = "bootloader", + .offset = 0, + .size = 30 * NAND_BLOCK_SIZE, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, { + /* U-Boot environment */ + .name = "params", + .offset = MTDPART_OFS_APPEND, + .size = 2 * NAND_BLOCK_SIZE, + .mask_flags = 0, + }, { + .name = "kernel", + .offset = MTDPART_OFS_APPEND, + .size = SZ_4M, + .mask_flags = 0, + }, { + .name = "filesystem1", + .offset = MTDPART_OFS_APPEND, + .size = SZ_512M, + .mask_flags = 0, + }, { + .name = "filesystem2", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + .mask_flags = 0, + } + /* two blocks with bad block table (and mirror) at the end */ +}; + +static struct davinci_nand_pdata davinci_nand_data = { + .mask_chipsel = BIT(14), + .parts = davinci_nand_partitions, + .nr_parts = ARRAY_SIZE(davinci_nand_partitions), + .ecc_mode = NAND_ECC_HW, + .bbt_options = NAND_BBT_USE_FLASH, + .ecc_bits = 4, +}; + +static struct resource davinci_nand_resources[] = { + { + .start = DM365_ASYNC_EMIF_DATA_CE0_BASE, + .end = DM365_ASYNC_EMIF_DATA_CE0_BASE + SZ_32M - 1, + .flags = IORESOURCE_MEM, + }, { + .start = DM365_ASYNC_EMIF_CONTROL_BASE, + .end = DM365_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device davinci_nand_device = { + .name = "davinci_nand", + .id = 0, + .num_resources = ARRAY_SIZE(davinci_nand_resources), + .resource = davinci_nand_resources, + .dev = { + .platform_data = &davinci_nand_data, + }, +}; + +static struct at24_platform_data eeprom_info = { + .byte_len = (256*1024) / 8, + .page_size = 64, + .flags = AT24_FLAG_ADDR16, + .setup = davinci_get_mac_addr, + .context = (void *)0x7f00, +}; + +static struct snd_platform_data dm365_evm_snd_data = { + .asp_chan_q = EVENTQ_3, +}; + +static struct i2c_board_info i2c_info[] = { + { + I2C_BOARD_INFO("24c256", 0x50), + .platform_data = &eeprom_info, + }, + { + I2C_BOARD_INFO("tlv320aic3x", 0x18), + }, +}; + +static struct davinci_i2c_platform_data i2c_pdata = { + .bus_freq = 400 /* kHz */, + .bus_delay = 0 /* usec */, +}; + +static int dm365evm_keyscan_enable(struct device *dev) +{ + return davinci_cfg_reg(DM365_KEYSCAN); +} + +static unsigned short dm365evm_keymap[] = { + KEY_KP2, + KEY_LEFT, + KEY_EXIT, + KEY_DOWN, + KEY_ENTER, + KEY_UP, + KEY_KP1, + KEY_RIGHT, + KEY_MENU, + KEY_RECORD, + KEY_REWIND, + KEY_KPMINUS, + KEY_STOP, + KEY_FASTFORWARD, + KEY_KPPLUS, + KEY_PLAYPAUSE, + 0 +}; + +static struct davinci_ks_platform_data dm365evm_ks_data = { + .device_enable = dm365evm_keyscan_enable, + .keymap = dm365evm_keymap, + .keymapsize = ARRAY_SIZE(dm365evm_keymap), + .rep = 1, + /* Scan period = strobe + interval */ + .strobe = 0x5, + .interval = 0x2, + .matrix_type = DAVINCI_KEYSCAN_MATRIX_4X4, +}; + +static int cpld_mmc_get_cd(int module) +{ + if (!cpld) + return -ENXIO; + + /* low == card present */ + return !(__raw_readb(cpld + CPLD_CARDSTAT) & BIT(module ? 4 : 0)); +} + +static int cpld_mmc_get_ro(int module) +{ + if (!cpld) + return -ENXIO; + + /* high == card's write protect switch active */ + return !!(__raw_readb(cpld + CPLD_CARDSTAT) & BIT(module ? 5 : 1)); +} + +static struct davinci_mmc_config dm365evm_mmc_config = { + .get_cd = cpld_mmc_get_cd, + .get_ro = cpld_mmc_get_ro, + .wires = 4, + .max_freq = 50000000, + .caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED, + .version = MMC_CTLR_VERSION_2, +}; + +static void dm365evm_emac_configure(void) +{ + /* + * EMAC pins are multiplexed with GPIO and UART + * Further details are available at the DM365 ARM + * Subsystem Users Guide(sprufg5.pdf) pages 125 - 127 + */ + davinci_cfg_reg(DM365_EMAC_TX_EN); + davinci_cfg_reg(DM365_EMAC_TX_CLK); + davinci_cfg_reg(DM365_EMAC_COL); + davinci_cfg_reg(DM365_EMAC_TXD3); + davinci_cfg_reg(DM365_EMAC_TXD2); + davinci_cfg_reg(DM365_EMAC_TXD1); + davinci_cfg_reg(DM365_EMAC_TXD0); + davinci_cfg_reg(DM365_EMAC_RXD3); + davinci_cfg_reg(DM365_EMAC_RXD2); + davinci_cfg_reg(DM365_EMAC_RXD1); + davinci_cfg_reg(DM365_EMAC_RXD0); + davinci_cfg_reg(DM365_EMAC_RX_CLK); + davinci_cfg_reg(DM365_EMAC_RX_DV); + davinci_cfg_reg(DM365_EMAC_RX_ER); + davinci_cfg_reg(DM365_EMAC_CRS); + davinci_cfg_reg(DM365_EMAC_MDIO); + davinci_cfg_reg(DM365_EMAC_MDCLK); + + /* + * EMAC interrupts are multiplexed with GPIO interrupts + * Details are available at the DM365 ARM + * Subsystem Users Guide(sprufg5.pdf) pages 133 - 134 + */ + davinci_cfg_reg(DM365_INT_EMAC_RXTHRESH); + davinci_cfg_reg(DM365_INT_EMAC_RXPULSE); + davinci_cfg_reg(DM365_INT_EMAC_TXPULSE); + davinci_cfg_reg(DM365_INT_EMAC_MISCPULSE); +} + +static void dm365evm_mmc_configure(void) +{ + /* + * MMC/SD pins are multiplexed with GPIO and EMIF + * Further details are available at the DM365 ARM + * Subsystem Users Guide(sprufg5.pdf) pages 118, 128 - 131 + */ + davinci_cfg_reg(DM365_SD1_CLK); + davinci_cfg_reg(DM365_SD1_CMD); + davinci_cfg_reg(DM365_SD1_DATA3); + davinci_cfg_reg(DM365_SD1_DATA2); + davinci_cfg_reg(DM365_SD1_DATA1); + davinci_cfg_reg(DM365_SD1_DATA0); +} + +static struct tvp514x_platform_data tvp5146_pdata = { + .clk_polarity = 0, + .hs_polarity = 1, + .vs_polarity = 1 +}; + +#define TVP514X_STD_ALL (V4L2_STD_NTSC | V4L2_STD_PAL) +/* Inputs available at the TVP5146 */ +static struct v4l2_input tvp5146_inputs[] = { + { + .index = 0, + .name = "Composite", + .type = V4L2_INPUT_TYPE_CAMERA, + .std = TVP514X_STD_ALL, + }, + { + .index = 1, + .name = "S-Video", + .type = V4L2_INPUT_TYPE_CAMERA, + .std = TVP514X_STD_ALL, + }, +}; + +/* + * this is the route info for connecting each input to decoder + * ouput that goes to vpfe. There is a one to one correspondence + * with tvp5146_inputs + */ +static struct vpfe_route tvp5146_routes[] = { + { + .input = INPUT_CVBS_VI2B, + .output = OUTPUT_10BIT_422_EMBEDDED_SYNC, + }, +{ + .input = INPUT_SVIDEO_VI2C_VI1C, + .output = OUTPUT_10BIT_422_EMBEDDED_SYNC, + }, +}; + +static struct vpfe_subdev_info vpfe_sub_devs[] = { + { + .name = "tvp5146", + .grp_id = 0, + .num_inputs = ARRAY_SIZE(tvp5146_inputs), + .inputs = tvp5146_inputs, + .routes = tvp5146_routes, + .can_route = 1, + .ccdc_if_params = { + .if_type = VPFE_BT656, + .hdpol = VPFE_PINPOL_POSITIVE, + .vdpol = VPFE_PINPOL_POSITIVE, + }, + .board_info = { + I2C_BOARD_INFO("tvp5146", 0x5d), + .platform_data = &tvp5146_pdata, + }, + }, +}; + +static struct vpfe_config vpfe_cfg = { + .num_subdevs = ARRAY_SIZE(vpfe_sub_devs), + .sub_devs = vpfe_sub_devs, + .i2c_adapter_id = 1, + .card_name = "DM365 EVM", + .ccdc = "ISIF", +}; + +static void __init evm_init_i2c(void) +{ + davinci_init_i2c(&i2c_pdata); + i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info)); +} + +static struct platform_device *dm365_evm_nand_devices[] __initdata = { + &davinci_nand_device, +}; + +static inline int have_leds(void) +{ +#ifdef CONFIG_LEDS_CLASS + return 1; +#else + return 0; +#endif +} + +struct cpld_led { + struct led_classdev cdev; + u8 mask; +}; + +static const struct { + const char *name; + const char *trigger; +} cpld_leds[] = { + { "dm365evm::ds2", }, + { "dm365evm::ds3", }, + { "dm365evm::ds4", }, + { "dm365evm::ds5", }, + { "dm365evm::ds6", "nand-disk", }, + { "dm365evm::ds7", "mmc1", }, + { "dm365evm::ds8", "mmc0", }, + { "dm365evm::ds9", "heartbeat", }, +}; + +static void cpld_led_set(struct led_classdev *cdev, enum led_brightness b) +{ + struct cpld_led *led = container_of(cdev, struct cpld_led, cdev); + u8 reg = __raw_readb(cpld + CPLD_LEDS); + + if (b != LED_OFF) + reg &= ~led->mask; + else + reg |= led->mask; + __raw_writeb(reg, cpld + CPLD_LEDS); +} + +static enum led_brightness cpld_led_get(struct led_classdev *cdev) +{ + struct cpld_led *led = container_of(cdev, struct cpld_led, cdev); + u8 reg = __raw_readb(cpld + CPLD_LEDS); + + return (reg & led->mask) ? LED_OFF : LED_FULL; +} + +static int __init cpld_leds_init(void) +{ + int i; + + if (!have_leds() || !cpld) + return 0; + + /* setup LEDs */ + __raw_writeb(0xff, cpld + CPLD_LEDS); + for (i = 0; i < ARRAY_SIZE(cpld_leds); i++) { + struct cpld_led *led; + + led = kzalloc(sizeof(*led), GFP_KERNEL); + if (!led) + break; + + led->cdev.name = cpld_leds[i].name; + led->cdev.brightness_set = cpld_led_set; + led->cdev.brightness_get = cpld_led_get; + led->cdev.default_trigger = cpld_leds[i].trigger; + led->mask = BIT(i); + + if (led_classdev_register(NULL, &led->cdev) < 0) { + kfree(led); + break; + } + } + + return 0; +} +/* run after subsys_initcall() for LEDs */ +fs_initcall(cpld_leds_init); + + +static void __init evm_init_cpld(void) +{ + u8 mux, resets; + const char *label; + struct clk *aemif_clk; + + /* Make sure we can configure the CPLD through CS1. Then + * leave it on for later access to MMC and LED registers. + */ + aemif_clk = clk_get(NULL, "aemif"); + if (IS_ERR(aemif_clk)) + return; + clk_enable(aemif_clk); + + if (request_mem_region(DM365_ASYNC_EMIF_DATA_CE1_BASE, SECTION_SIZE, + "cpld") == NULL) + goto fail; + cpld = ioremap(DM365_ASYNC_EMIF_DATA_CE1_BASE, SECTION_SIZE); + if (!cpld) { + release_mem_region(DM365_ASYNC_EMIF_DATA_CE1_BASE, + SECTION_SIZE); +fail: + pr_err("ERROR: can't map CPLD\n"); + clk_disable(aemif_clk); + return; + } + + /* External muxing for some signals */ + mux = 0; + + /* Read SW5 to set up NAND + keypad _or_ OneNAND (sync read). + * NOTE: SW4 bus width setting must match! + */ + if ((__raw_readb(cpld + CPLD_SWITCH) & BIT(5)) == 0) { + /* external keypad mux */ + mux |= BIT(7); + + platform_add_devices(dm365_evm_nand_devices, + ARRAY_SIZE(dm365_evm_nand_devices)); + } else { + /* no OneNAND support yet */ + } + + /* Leave external chips in reset when unused. */ + resets = BIT(3) | BIT(2) | BIT(1) | BIT(0); + + /* Static video input config with SN74CBT16214 1-of-3 mux: + * - port b1 == tvp7002 (mux lowbits == 1 or 6) + * - port b2 == imager (mux lowbits == 2 or 7) + * - port b3 == tvp5146 (mux lowbits == 5) + * + * Runtime switching could work too, with limitations. + */ + if (have_imager()) { + label = "HD imager"; + mux |= 2; + + /* externally mux MMC1/ENET/AIC33 to imager */ + mux |= BIT(6) | BIT(5) | BIT(3); + } else { + struct davinci_soc_info *soc_info = &davinci_soc_info; + + /* we can use MMC1 ... */ + dm365evm_mmc_configure(); + davinci_setup_mmc(1, &dm365evm_mmc_config); + + /* ... and ENET ... */ + dm365evm_emac_configure(); + soc_info->emac_pdata->phy_id = DM365_EVM_PHY_ID; + resets &= ~BIT(3); + + /* ... and AIC33 */ + resets &= ~BIT(1); + + if (have_tvp7002()) { + mux |= 1; + resets &= ~BIT(2); + label = "tvp7002 HD"; + } else { + /* default to tvp5146 */ + mux |= 5; + resets &= ~BIT(0); + label = "tvp5146 SD"; + } + } + __raw_writeb(mux, cpld + CPLD_MUX); + __raw_writeb(resets, cpld + CPLD_RESETS); + pr_info("EVM: %s video input\n", label); + + /* REVISIT export switches: NTSC/PAL (SW5.6), EXTRA1 (SW5.2), etc */ +} + +static struct davinci_uart_config uart_config __initdata = { + .enabled_uarts = (1 << 0), +}; + +static void __init dm365_evm_map_io(void) +{ + /* setup input configuration for VPFE input devices */ + dm365_set_vpfe_config(&vpfe_cfg); + dm365_init(); +} + +static struct spi_eeprom at25640 = { + .byte_len = SZ_64K / 8, + .name = "at25640", + .page_size = 32, + .flags = EE_ADDR2, +}; + +static struct spi_board_info dm365_evm_spi_info[] __initconst = { + { + .modalias = "at25", + .platform_data = &at25640, + .max_speed_hz = 10 * 1000 * 1000, + .bus_num = 0, + .chip_select = 0, + .mode = SPI_MODE_0, + }, +}; + +static __init void dm365_evm_init(void) +{ + evm_init_i2c(); + davinci_serial_init(&uart_config); + + dm365evm_emac_configure(); + dm365evm_mmc_configure(); + + davinci_setup_mmc(0, &dm365evm_mmc_config); + + /* maybe setup mmc1/etc ... _after_ mmc0 */ + evm_init_cpld(); + +#ifdef CONFIG_SND_DM365_AIC3X_CODEC + dm365_init_asp(&dm365_evm_snd_data); +#elif defined(CONFIG_SND_DM365_VOICE_CODEC) + dm365_init_vc(&dm365_evm_snd_data); +#endif + dm365_init_rtc(); + dm365_init_ks(&dm365evm_ks_data); + + dm365_init_spi0(BIT(0), dm365_evm_spi_info, + ARRAY_SIZE(dm365_evm_spi_info)); +} + +MACHINE_START(DAVINCI_DM365_EVM, "DaVinci DM365 EVM") + .atag_offset = 0x100, + .map_io = dm365_evm_map_io, + .init_irq = davinci_irq_init, + .timer = &davinci_timer, + .init_machine = dm365_evm_init, + .dma_zone_size = SZ_128M, + .restart = davinci_restart, +MACHINE_END + diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/board-dm644x-evm.c b/ANDROID_3.4.5/arch/arm/mach-davinci/board-dm644x-evm.c new file mode 100644 index 00000000..3683306e --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/board-dm644x-evm.c @@ -0,0 +1,830 @@ +/* + * TI DaVinci EVM board support + * + * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com> + * + * 2007 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/dma-mapping.h> +#include <linux/platform_device.h> +#include <linux/gpio.h> +#include <linux/i2c.h> +#include <linux/i2c/pcf857x.h> +#include <linux/i2c/at24.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/nand.h> +#include <linux/mtd/partitions.h> +#include <linux/mtd/physmap.h> +#include <linux/phy.h> +#include <linux/clk.h> +#include <linux/videodev2.h> +#include <linux/export.h> + +#include <media/tvp514x.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> + +#include <mach/common.h> +#include <mach/i2c.h> +#include <mach/serial.h> +#include <mach/mux.h> +#include <mach/nand.h> +#include <mach/mmc.h> +#include <mach/usb.h> +#include <mach/aemif.h> + +#include "davinci.h" + +#define DM644X_EVM_PHY_ID "davinci_mdio-0:01" +#define LXT971_PHY_ID (0x001378e2) +#define LXT971_PHY_MASK (0xfffffff0) + +static struct mtd_partition davinci_evm_norflash_partitions[] = { + /* bootloader (UBL, U-Boot, etc) in first 5 sectors */ + { + .name = "bootloader", + .offset = 0, + .size = 5 * SZ_64K, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + /* bootloader params in the next 1 sectors */ + { + .name = "params", + .offset = MTDPART_OFS_APPEND, + .size = SZ_64K, + .mask_flags = 0, + }, + /* kernel */ + { + .name = "kernel", + .offset = MTDPART_OFS_APPEND, + .size = SZ_2M, + .mask_flags = 0 + }, + /* file system */ + { + .name = "filesystem", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + .mask_flags = 0 + } +}; + +static struct physmap_flash_data davinci_evm_norflash_data = { + .width = 2, + .parts = davinci_evm_norflash_partitions, + .nr_parts = ARRAY_SIZE(davinci_evm_norflash_partitions), +}; + +/* NOTE: CFI probe will correctly detect flash part as 32M, but EMIF + * limits addresses to 16M, so using addresses past 16M will wrap */ +static struct resource davinci_evm_norflash_resource = { + .start = DM644X_ASYNC_EMIF_DATA_CE0_BASE, + .end = DM644X_ASYNC_EMIF_DATA_CE0_BASE + SZ_16M - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device davinci_evm_norflash_device = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &davinci_evm_norflash_data, + }, + .num_resources = 1, + .resource = &davinci_evm_norflash_resource, +}; + +/* DM644x EVM includes a 64 MByte small-page NAND flash (16K blocks). + * It may used instead of the (default) NOR chip to boot, using TI's + * tools to install the secondary boot loader (UBL) and U-Boot. + */ +static struct mtd_partition davinci_evm_nandflash_partition[] = { + /* Bootloader layout depends on whose u-boot is installed, but we + * can hide all the details. + * - block 0 for u-boot environment ... in mainline u-boot + * - block 1 for UBL (plus up to four backup copies in blocks 2..5) + * - blocks 6...? for u-boot + * - blocks 16..23 for u-boot environment ... in TI's u-boot + */ + { + .name = "bootloader", + .offset = 0, + .size = SZ_256K + SZ_128K, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + /* Kernel */ + { + .name = "kernel", + .offset = MTDPART_OFS_APPEND, + .size = SZ_4M, + .mask_flags = 0, + }, + /* File system (older GIT kernels started this on the 5MB mark) */ + { + .name = "filesystem", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + .mask_flags = 0, + } + /* A few blocks at end hold a flash BBT ... created by TI's CCS + * using flashwriter_nand.out, but ignored by TI's versions of + * Linux and u-boot. We boot faster by using them. + */ +}; + +static struct davinci_aemif_timing davinci_evm_nandflash_timing = { + .wsetup = 20, + .wstrobe = 40, + .whold = 20, + .rsetup = 10, + .rstrobe = 40, + .rhold = 10, + .ta = 40, +}; + +static struct davinci_nand_pdata davinci_evm_nandflash_data = { + .parts = davinci_evm_nandflash_partition, + .nr_parts = ARRAY_SIZE(davinci_evm_nandflash_partition), + .ecc_mode = NAND_ECC_HW, + .bbt_options = NAND_BBT_USE_FLASH, + .timing = &davinci_evm_nandflash_timing, +}; + +static struct resource davinci_evm_nandflash_resource[] = { + { + .start = DM644X_ASYNC_EMIF_DATA_CE0_BASE, + .end = DM644X_ASYNC_EMIF_DATA_CE0_BASE + SZ_16M - 1, + .flags = IORESOURCE_MEM, + }, { + .start = DM644X_ASYNC_EMIF_CONTROL_BASE, + .end = DM644X_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device davinci_evm_nandflash_device = { + .name = "davinci_nand", + .id = 0, + .dev = { + .platform_data = &davinci_evm_nandflash_data, + }, + .num_resources = ARRAY_SIZE(davinci_evm_nandflash_resource), + .resource = davinci_evm_nandflash_resource, +}; + +static u64 davinci_fb_dma_mask = DMA_BIT_MASK(32); + +static struct platform_device davinci_fb_device = { + .name = "davincifb", + .id = -1, + .dev = { + .dma_mask = &davinci_fb_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .num_resources = 0, +}; + +static struct tvp514x_platform_data dm644xevm_tvp5146_pdata = { + .clk_polarity = 0, + .hs_polarity = 1, + .vs_polarity = 1 +}; + +#define TVP514X_STD_ALL (V4L2_STD_NTSC | V4L2_STD_PAL) +/* Inputs available at the TVP5146 */ +static struct v4l2_input dm644xevm_tvp5146_inputs[] = { + { + .index = 0, + .name = "Composite", + .type = V4L2_INPUT_TYPE_CAMERA, + .std = TVP514X_STD_ALL, + }, + { + .index = 1, + .name = "S-Video", + .type = V4L2_INPUT_TYPE_CAMERA, + .std = TVP514X_STD_ALL, + }, +}; + +/* + * this is the route info for connecting each input to decoder + * ouput that goes to vpfe. There is a one to one correspondence + * with tvp5146_inputs + */ +static struct vpfe_route dm644xevm_tvp5146_routes[] = { + { + .input = INPUT_CVBS_VI2B, + .output = OUTPUT_10BIT_422_EMBEDDED_SYNC, + }, + { + .input = INPUT_SVIDEO_VI2C_VI1C, + .output = OUTPUT_10BIT_422_EMBEDDED_SYNC, + }, +}; + +static struct vpfe_subdev_info dm644xevm_vpfe_sub_devs[] = { + { + .name = "tvp5146", + .grp_id = 0, + .num_inputs = ARRAY_SIZE(dm644xevm_tvp5146_inputs), + .inputs = dm644xevm_tvp5146_inputs, + .routes = dm644xevm_tvp5146_routes, + .can_route = 1, + .ccdc_if_params = { + .if_type = VPFE_BT656, + .hdpol = VPFE_PINPOL_POSITIVE, + .vdpol = VPFE_PINPOL_POSITIVE, + }, + .board_info = { + I2C_BOARD_INFO("tvp5146", 0x5d), + .platform_data = &dm644xevm_tvp5146_pdata, + }, + }, +}; + +static struct vpfe_config dm644xevm_capture_cfg = { + .num_subdevs = ARRAY_SIZE(dm644xevm_vpfe_sub_devs), + .i2c_adapter_id = 1, + .sub_devs = dm644xevm_vpfe_sub_devs, + .card_name = "DM6446 EVM", + .ccdc = "DM6446 CCDC", +}; + +static struct platform_device rtc_dev = { + .name = "rtc_davinci_evm", + .id = -1, +}; + +static struct snd_platform_data dm644x_evm_snd_data; + +/*----------------------------------------------------------------------*/ + +/* + * I2C GPIO expanders + */ + +#define PCF_Uxx_BASE(x) (DAVINCI_N_GPIO + ((x) * 8)) + + +/* U2 -- LEDs */ + +static struct gpio_led evm_leds[] = { + { .name = "DS8", .active_low = 1, + .default_trigger = "heartbeat", }, + { .name = "DS7", .active_low = 1, }, + { .name = "DS6", .active_low = 1, }, + { .name = "DS5", .active_low = 1, }, + { .name = "DS4", .active_low = 1, }, + { .name = "DS3", .active_low = 1, }, + { .name = "DS2", .active_low = 1, + .default_trigger = "mmc0", }, + { .name = "DS1", .active_low = 1, + .default_trigger = "ide-disk", }, +}; + +static const struct gpio_led_platform_data evm_led_data = { + .num_leds = ARRAY_SIZE(evm_leds), + .leds = evm_leds, +}; + +static struct platform_device *evm_led_dev; + +static int +evm_led_setup(struct i2c_client *client, int gpio, unsigned ngpio, void *c) +{ + struct gpio_led *leds = evm_leds; + int status; + + while (ngpio--) { + leds->gpio = gpio++; + leds++; + } + + /* what an extremely annoying way to be forced to handle + * device unregistration ... + */ + evm_led_dev = platform_device_alloc("leds-gpio", 0); + platform_device_add_data(evm_led_dev, + &evm_led_data, sizeof evm_led_data); + + evm_led_dev->dev.parent = &client->dev; + status = platform_device_add(evm_led_dev); + if (status < 0) { + platform_device_put(evm_led_dev); + evm_led_dev = NULL; + } + return status; +} + +static int +evm_led_teardown(struct i2c_client *client, int gpio, unsigned ngpio, void *c) +{ + if (evm_led_dev) { + platform_device_unregister(evm_led_dev); + evm_led_dev = NULL; + } + return 0; +} + +static struct pcf857x_platform_data pcf_data_u2 = { + .gpio_base = PCF_Uxx_BASE(0), + .setup = evm_led_setup, + .teardown = evm_led_teardown, +}; + + +/* U18 - A/V clock generator and user switch */ + +static int sw_gpio; + +static ssize_t +sw_show(struct device *d, struct device_attribute *a, char *buf) +{ + char *s = gpio_get_value_cansleep(sw_gpio) ? "on\n" : "off\n"; + + strcpy(buf, s); + return strlen(s); +} + +static DEVICE_ATTR(user_sw, S_IRUGO, sw_show, NULL); + +static int +evm_u18_setup(struct i2c_client *client, int gpio, unsigned ngpio, void *c) +{ + int status; + + /* export dip switch option */ + sw_gpio = gpio + 7; + status = gpio_request(sw_gpio, "user_sw"); + if (status == 0) + status = gpio_direction_input(sw_gpio); + if (status == 0) + status = device_create_file(&client->dev, &dev_attr_user_sw); + else + gpio_free(sw_gpio); + if (status != 0) + sw_gpio = -EINVAL; + + /* audio PLL: 48 kHz (vs 44.1 or 32), single rate (vs double) */ + gpio_request(gpio + 3, "pll_fs2"); + gpio_direction_output(gpio + 3, 0); + + gpio_request(gpio + 2, "pll_fs1"); + gpio_direction_output(gpio + 2, 0); + + gpio_request(gpio + 1, "pll_sr"); + gpio_direction_output(gpio + 1, 0); + + return 0; +} + +static int +evm_u18_teardown(struct i2c_client *client, int gpio, unsigned ngpio, void *c) +{ + gpio_free(gpio + 1); + gpio_free(gpio + 2); + gpio_free(gpio + 3); + + if (sw_gpio > 0) { + device_remove_file(&client->dev, &dev_attr_user_sw); + gpio_free(sw_gpio); + } + return 0; +} + +static struct pcf857x_platform_data pcf_data_u18 = { + .gpio_base = PCF_Uxx_BASE(1), + .n_latch = (1 << 3) | (1 << 2) | (1 << 1), + .setup = evm_u18_setup, + .teardown = evm_u18_teardown, +}; + + +/* U35 - various I/O signals used to manage USB, CF, ATA, etc */ + +static int +evm_u35_setup(struct i2c_client *client, int gpio, unsigned ngpio, void *c) +{ + /* p0 = nDRV_VBUS (initial: don't supply it) */ + gpio_request(gpio + 0, "nDRV_VBUS"); + gpio_direction_output(gpio + 0, 1); + + /* p1 = VDDIMX_EN */ + gpio_request(gpio + 1, "VDDIMX_EN"); + gpio_direction_output(gpio + 1, 1); + + /* p2 = VLYNQ_EN */ + gpio_request(gpio + 2, "VLYNQ_EN"); + gpio_direction_output(gpio + 2, 1); + + /* p3 = n3V3_CF_RESET (initial: stay in reset) */ + gpio_request(gpio + 3, "nCF_RESET"); + gpio_direction_output(gpio + 3, 0); + + /* (p4 unused) */ + + /* p5 = 1V8_WLAN_RESET (initial: stay in reset) */ + gpio_request(gpio + 5, "WLAN_RESET"); + gpio_direction_output(gpio + 5, 1); + + /* p6 = nATA_SEL (initial: select) */ + gpio_request(gpio + 6, "nATA_SEL"); + gpio_direction_output(gpio + 6, 0); + + /* p7 = nCF_SEL (initial: deselect) */ + gpio_request(gpio + 7, "nCF_SEL"); + gpio_direction_output(gpio + 7, 1); + + return 0; +} + +static int +evm_u35_teardown(struct i2c_client *client, int gpio, unsigned ngpio, void *c) +{ + gpio_free(gpio + 7); + gpio_free(gpio + 6); + gpio_free(gpio + 5); + gpio_free(gpio + 3); + gpio_free(gpio + 2); + gpio_free(gpio + 1); + gpio_free(gpio + 0); + return 0; +} + +static struct pcf857x_platform_data pcf_data_u35 = { + .gpio_base = PCF_Uxx_BASE(2), + .setup = evm_u35_setup, + .teardown = evm_u35_teardown, +}; + +/*----------------------------------------------------------------------*/ + +/* Most of this EEPROM is unused, but U-Boot uses some data: + * - 0x7f00, 6 bytes Ethernet Address + * - 0x0039, 1 byte NTSC vs PAL (bit 0x80 == PAL) + * - ... newer boards may have more + */ + +static struct at24_platform_data eeprom_info = { + .byte_len = (256*1024) / 8, + .page_size = 64, + .flags = AT24_FLAG_ADDR16, + .setup = davinci_get_mac_addr, + .context = (void *)0x7f00, +}; + +/* + * MSP430 supports RTC, card detection, input from IR remote, and + * a bit more. It triggers interrupts on GPIO(7) from pressing + * buttons on the IR remote, and for card detect switches. + */ +static struct i2c_client *dm6446evm_msp; + +static int dm6446evm_msp_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + dm6446evm_msp = client; + return 0; +} + +static int dm6446evm_msp_remove(struct i2c_client *client) +{ + dm6446evm_msp = NULL; + return 0; +} + +static const struct i2c_device_id dm6446evm_msp_ids[] = { + { "dm6446evm_msp", 0, }, + { /* end of list */ }, +}; + +static struct i2c_driver dm6446evm_msp_driver = { + .driver.name = "dm6446evm_msp", + .id_table = dm6446evm_msp_ids, + .probe = dm6446evm_msp_probe, + .remove = dm6446evm_msp_remove, +}; + +static int dm6444evm_msp430_get_pins(void) +{ + static const char txbuf[2] = { 2, 4, }; + char buf[4]; + struct i2c_msg msg[2] = { + { + .addr = dm6446evm_msp->addr, + .flags = 0, + .len = 2, + .buf = (void __force *)txbuf, + }, + { + .addr = dm6446evm_msp->addr, + .flags = I2C_M_RD, + .len = 4, + .buf = buf, + }, + }; + int status; + + if (!dm6446evm_msp) + return -ENXIO; + + /* Command 4 == get input state, returns port 2 and port3 data + * S Addr W [A] len=2 [A] cmd=4 [A] + * RS Addr R [A] [len=4] A [cmd=4] A [port2] A [port3] N P + */ + status = i2c_transfer(dm6446evm_msp->adapter, msg, 2); + if (status < 0) + return status; + + dev_dbg(&dm6446evm_msp->dev, + "PINS: %02x %02x %02x %02x\n", + buf[0], buf[1], buf[2], buf[3]); + + return (buf[3] << 8) | buf[2]; +} + +static int dm6444evm_mmc_get_cd(int module) +{ + int status = dm6444evm_msp430_get_pins(); + + return (status < 0) ? status : !(status & BIT(1)); +} + +static int dm6444evm_mmc_get_ro(int module) +{ + int status = dm6444evm_msp430_get_pins(); + + return (status < 0) ? status : status & BIT(6 + 8); +} + +static struct davinci_mmc_config dm6446evm_mmc_config = { + .get_cd = dm6444evm_mmc_get_cd, + .get_ro = dm6444evm_mmc_get_ro, + .wires = 4, + .version = MMC_CTLR_VERSION_1 +}; + +static struct i2c_board_info __initdata i2c_info[] = { + { + I2C_BOARD_INFO("dm6446evm_msp", 0x23), + }, + { + I2C_BOARD_INFO("pcf8574", 0x38), + .platform_data = &pcf_data_u2, + }, + { + I2C_BOARD_INFO("pcf8574", 0x39), + .platform_data = &pcf_data_u18, + }, + { + I2C_BOARD_INFO("pcf8574", 0x3a), + .platform_data = &pcf_data_u35, + }, + { + I2C_BOARD_INFO("24c256", 0x50), + .platform_data = &eeprom_info, + }, + { + I2C_BOARD_INFO("tlv320aic33", 0x1b), + }, +}; + +/* The msp430 uses a slow bitbanged I2C implementation (ergo 20 KHz), + * which requires 100 usec of idle bus after i2c writes sent to it. + */ +static struct davinci_i2c_platform_data i2c_pdata = { + .bus_freq = 20 /* kHz */, + .bus_delay = 100 /* usec */, + .sda_pin = 44, + .scl_pin = 43, +}; + +static void __init evm_init_i2c(void) +{ + davinci_init_i2c(&i2c_pdata); + i2c_add_driver(&dm6446evm_msp_driver); + i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info)); +} + +#define VENC_STD_ALL (V4L2_STD_NTSC | V4L2_STD_PAL) + +/* venc standard timings */ +static struct vpbe_enc_mode_info dm644xevm_enc_std_timing[] = { + { + .name = "ntsc", + .timings_type = VPBE_ENC_STD, + .timings = {V4L2_STD_525_60}, + .interlaced = 1, + .xres = 720, + .yres = 480, + .aspect = {11, 10}, + .fps = {30000, 1001}, + .left_margin = 0x79, + .upper_margin = 0x10, + }, + { + .name = "pal", + .timings_type = VPBE_ENC_STD, + .timings = {V4L2_STD_625_50}, + .interlaced = 1, + .xres = 720, + .yres = 576, + .aspect = {54, 59}, + .fps = {25, 1}, + .left_margin = 0x7e, + .upper_margin = 0x16, + }, +}; + +/* venc dv preset timings */ +static struct vpbe_enc_mode_info dm644xevm_enc_preset_timing[] = { + { + .name = "480p59_94", + .timings_type = VPBE_ENC_DV_PRESET, + .timings = {V4L2_DV_480P59_94}, + .interlaced = 0, + .xres = 720, + .yres = 480, + .aspect = {1, 1}, + .fps = {5994, 100}, + .left_margin = 0x80, + .upper_margin = 0x20, + }, + { + .name = "576p50", + .timings_type = VPBE_ENC_DV_PRESET, + .timings = {V4L2_DV_576P50}, + .interlaced = 0, + .xres = 720, + .yres = 576, + .aspect = {1, 1}, + .fps = {50, 1}, + .left_margin = 0x7e, + .upper_margin = 0x30, + }, +}; + +/* + * The outputs available from VPBE + encoders. Keep the order same + * as that of encoders. First those from venc followed by that from + * encoders. Index in the output refers to index on a particular encoder. + * Driver uses this index to pass it to encoder when it supports more + * than one output. Userspace applications use index of the array to + * set an output. + */ +static struct vpbe_output dm644xevm_vpbe_outputs[] = { + { + .output = { + .index = 0, + .name = "Composite", + .type = V4L2_OUTPUT_TYPE_ANALOG, + .std = VENC_STD_ALL, + .capabilities = V4L2_OUT_CAP_STD, + }, + .subdev_name = VPBE_VENC_SUBDEV_NAME, + .default_mode = "ntsc", + .num_modes = ARRAY_SIZE(dm644xevm_enc_std_timing), + .modes = dm644xevm_enc_std_timing, + }, + { + .output = { + .index = 1, + .name = "Component", + .type = V4L2_OUTPUT_TYPE_ANALOG, + .capabilities = V4L2_OUT_CAP_PRESETS, + }, + .subdev_name = VPBE_VENC_SUBDEV_NAME, + .default_mode = "480p59_94", + .num_modes = ARRAY_SIZE(dm644xevm_enc_preset_timing), + .modes = dm644xevm_enc_preset_timing, + }, +}; + +static struct vpbe_config dm644xevm_display_cfg = { + .module_name = "dm644x-vpbe-display", + .i2c_adapter_id = 1, + .osd = { + .module_name = VPBE_OSD_SUBDEV_NAME, + }, + .venc = { + .module_name = VPBE_VENC_SUBDEV_NAME, + }, + .num_outputs = ARRAY_SIZE(dm644xevm_vpbe_outputs), + .outputs = dm644xevm_vpbe_outputs, +}; + +static struct platform_device *davinci_evm_devices[] __initdata = { + &davinci_fb_device, + &rtc_dev, +}; + +static struct davinci_uart_config uart_config __initdata = { + .enabled_uarts = (1 << 0), +}; + +static void __init +davinci_evm_map_io(void) +{ + dm644x_init(); +} + +static int davinci_phy_fixup(struct phy_device *phydev) +{ + unsigned int control; + /* CRITICAL: Fix for increasing PHY signal drive strength for + * TX lockup issue. On DaVinci EVM, the Intel LXT971 PHY + * signal strength was low causing TX to fail randomly. The + * fix is to Set bit 11 (Increased MII drive strength) of PHY + * register 26 (Digital Config register) on this phy. */ + control = phy_read(phydev, 26); + phy_write(phydev, 26, (control | 0x800)); + return 0; +} + +#if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \ + defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE) +#define HAS_ATA 1 +#else +#define HAS_ATA 0 +#endif + +#if defined(CONFIG_MTD_PHYSMAP) || \ + defined(CONFIG_MTD_PHYSMAP_MODULE) +#define HAS_NOR 1 +#else +#define HAS_NOR 0 +#endif + +#if defined(CONFIG_MTD_NAND_DAVINCI) || \ + defined(CONFIG_MTD_NAND_DAVINCI_MODULE) +#define HAS_NAND 1 +#else +#define HAS_NAND 0 +#endif + +static __init void davinci_evm_init(void) +{ + struct clk *aemif_clk; + struct davinci_soc_info *soc_info = &davinci_soc_info; + + aemif_clk = clk_get(NULL, "aemif"); + clk_enable(aemif_clk); + + if (HAS_ATA) { + if (HAS_NAND || HAS_NOR) + pr_warning("WARNING: both IDE and Flash are " + "enabled, but they share AEMIF pins.\n" + "\tDisable IDE for NAND/NOR support.\n"); + davinci_init_ide(); + } else if (HAS_NAND || HAS_NOR) { + davinci_cfg_reg(DM644X_HPIEN_DISABLE); + davinci_cfg_reg(DM644X_ATAEN_DISABLE); + + /* only one device will be jumpered and detected */ + if (HAS_NAND) { + platform_device_register(&davinci_evm_nandflash_device); + evm_leds[7].default_trigger = "nand-disk"; + if (HAS_NOR) + pr_warning("WARNING: both NAND and NOR flash " + "are enabled; disable one of them.\n"); + } else if (HAS_NOR) + platform_device_register(&davinci_evm_norflash_device); + } + + platform_add_devices(davinci_evm_devices, + ARRAY_SIZE(davinci_evm_devices)); + evm_init_i2c(); + + davinci_setup_mmc(0, &dm6446evm_mmc_config); + dm644x_init_video(&dm644xevm_capture_cfg, &dm644xevm_display_cfg); + + davinci_serial_init(&uart_config); + dm644x_init_asp(&dm644x_evm_snd_data); + + /* irlml6401 switches over 1A, in under 8 msec */ + davinci_setup_usb(1000, 8); + + soc_info->emac_pdata->phy_id = DM644X_EVM_PHY_ID; + /* Register the fixup for PHY on DaVinci */ + phy_register_fixup_for_uid(LXT971_PHY_ID, LXT971_PHY_MASK, + davinci_phy_fixup); + +} + +MACHINE_START(DAVINCI_EVM, "DaVinci DM644x EVM") + /* Maintainer: MontaVista Software <source@mvista.com> */ + .atag_offset = 0x100, + .map_io = davinci_evm_map_io, + .init_irq = davinci_irq_init, + .timer = &davinci_timer, + .init_machine = davinci_evm_init, + .dma_zone_size = SZ_128M, + .restart = davinci_restart, +MACHINE_END diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/board-dm646x-evm.c b/ANDROID_3.4.5/arch/arm/mach-davinci/board-dm646x-evm.c new file mode 100644 index 00000000..d72ab948 --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/board-dm646x-evm.c @@ -0,0 +1,804 @@ +/* + * TI DaVinci DM646X EVM board + * + * Derived from: arch/arm/mach-davinci/board-evm.c + * Copyright (C) 2006 Texas Instruments. + * + * (C) 2007-2008, MontaVista Software, Inc. + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + * + */ + +/************************************************************************** + * Included Files + **************************************************************************/ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/leds.h> +#include <linux/gpio.h> +#include <linux/platform_device.h> +#include <linux/i2c.h> +#include <linux/i2c/at24.h> +#include <linux/i2c/pcf857x.h> + +#include <media/tvp514x.h> + +#include <linux/mtd/mtd.h> +#include <linux/mtd/nand.h> +#include <linux/mtd/partitions.h> +#include <linux/clk.h> +#include <linux/export.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> + +#include <mach/common.h> +#include <mach/serial.h> +#include <mach/i2c.h> +#include <mach/nand.h> +#include <mach/clock.h> +#include <mach/cdce949.h> +#include <mach/aemif.h> + +#include "davinci.h" +#include "clock.h" + +#define NAND_BLOCK_SIZE SZ_128K + +/* Note: We are setting first partition as 'bootloader' constituting UBL, U-Boot + * and U-Boot environment this avoids dependency on any particular combination + * of UBL, U-Boot or flashing tools etc. + */ +static struct mtd_partition davinci_nand_partitions[] = { + { + /* UBL, U-Boot with environment */ + .name = "bootloader", + .offset = MTDPART_OFS_APPEND, + .size = 16 * NAND_BLOCK_SIZE, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, { + .name = "kernel", + .offset = MTDPART_OFS_APPEND, + .size = SZ_4M, + .mask_flags = 0, + }, { + .name = "filesystem", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + .mask_flags = 0, + } +}; + +static struct davinci_aemif_timing dm6467tevm_nandflash_timing = { + .wsetup = 29, + .wstrobe = 24, + .whold = 14, + .rsetup = 19, + .rstrobe = 33, + .rhold = 0, + .ta = 29, +}; + +static struct davinci_nand_pdata davinci_nand_data = { + .mask_cle = 0x80000, + .mask_ale = 0x40000, + .parts = davinci_nand_partitions, + .nr_parts = ARRAY_SIZE(davinci_nand_partitions), + .ecc_mode = NAND_ECC_HW, + .options = 0, +}; + +static struct resource davinci_nand_resources[] = { + { + .start = DM646X_ASYNC_EMIF_CS2_SPACE_BASE, + .end = DM646X_ASYNC_EMIF_CS2_SPACE_BASE + SZ_32M - 1, + .flags = IORESOURCE_MEM, + }, { + .start = DM646X_ASYNC_EMIF_CONTROL_BASE, + .end = DM646X_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device davinci_nand_device = { + .name = "davinci_nand", + .id = 0, + + .num_resources = ARRAY_SIZE(davinci_nand_resources), + .resource = davinci_nand_resources, + + .dev = { + .platform_data = &davinci_nand_data, + }, +}; + +#if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \ + defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE) +#define HAS_ATA 1 +#else +#define HAS_ATA 0 +#endif + +/* CPLD Register 0 bits to control ATA */ +#define DM646X_EVM_ATA_RST BIT(0) +#define DM646X_EVM_ATA_PWD BIT(1) + +/* CPLD Register 0 Client: used for I/O Control */ +static int cpld_reg0_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + if (HAS_ATA) { + u8 data; + struct i2c_msg msg[2] = { + { + .addr = client->addr, + .flags = I2C_M_RD, + .len = 1, + .buf = &data, + }, + { + .addr = client->addr, + .flags = 0, + .len = 1, + .buf = &data, + }, + }; + + /* Clear ATA_RSTn and ATA_PWD bits to enable ATA operation. */ + i2c_transfer(client->adapter, msg, 1); + data &= ~(DM646X_EVM_ATA_RST | DM646X_EVM_ATA_PWD); + i2c_transfer(client->adapter, msg + 1, 1); + } + + return 0; +} + +static const struct i2c_device_id cpld_reg_ids[] = { + { "cpld_reg0", 0, }, + { }, +}; + +static struct i2c_driver dm6467evm_cpld_driver = { + .driver.name = "cpld_reg0", + .id_table = cpld_reg_ids, + .probe = cpld_reg0_probe, +}; + +/* LEDS */ + +static struct gpio_led evm_leds[] = { + { .name = "DS1", .active_low = 1, }, + { .name = "DS2", .active_low = 1, }, + { .name = "DS3", .active_low = 1, }, + { .name = "DS4", .active_low = 1, }, +}; + +static const struct gpio_led_platform_data evm_led_data = { + .num_leds = ARRAY_SIZE(evm_leds), + .leds = evm_leds, +}; + +static struct platform_device *evm_led_dev; + +static int evm_led_setup(struct i2c_client *client, int gpio, + unsigned int ngpio, void *c) +{ + struct gpio_led *leds = evm_leds; + int status; + + while (ngpio--) { + leds->gpio = gpio++; + leds++; + }; + + evm_led_dev = platform_device_alloc("leds-gpio", 0); + platform_device_add_data(evm_led_dev, &evm_led_data, + sizeof(evm_led_data)); + + evm_led_dev->dev.parent = &client->dev; + status = platform_device_add(evm_led_dev); + if (status < 0) { + platform_device_put(evm_led_dev); + evm_led_dev = NULL; + } + return status; +} + +static int evm_led_teardown(struct i2c_client *client, int gpio, + unsigned ngpio, void *c) +{ + if (evm_led_dev) { + platform_device_unregister(evm_led_dev); + evm_led_dev = NULL; + } + return 0; +} + +static int evm_sw_gpio[4] = { -EINVAL, -EINVAL, -EINVAL, -EINVAL }; + +static int evm_sw_setup(struct i2c_client *client, int gpio, + unsigned ngpio, void *c) +{ + int status; + int i; + char label[10]; + + for (i = 0; i < 4; ++i) { + snprintf(label, 10, "user_sw%d", i); + status = gpio_request(gpio, label); + if (status) + goto out_free; + evm_sw_gpio[i] = gpio++; + + status = gpio_direction_input(evm_sw_gpio[i]); + if (status) { + gpio_free(evm_sw_gpio[i]); + evm_sw_gpio[i] = -EINVAL; + goto out_free; + } + + status = gpio_export(evm_sw_gpio[i], 0); + if (status) { + gpio_free(evm_sw_gpio[i]); + evm_sw_gpio[i] = -EINVAL; + goto out_free; + } + } + return status; +out_free: + for (i = 0; i < 4; ++i) { + if (evm_sw_gpio[i] != -EINVAL) { + gpio_free(evm_sw_gpio[i]); + evm_sw_gpio[i] = -EINVAL; + } + } + return status; +} + +static int evm_sw_teardown(struct i2c_client *client, int gpio, + unsigned ngpio, void *c) +{ + int i; + + for (i = 0; i < 4; ++i) { + if (evm_sw_gpio[i] != -EINVAL) { + gpio_unexport(evm_sw_gpio[i]); + gpio_free(evm_sw_gpio[i]); + evm_sw_gpio[i] = -EINVAL; + } + } + return 0; +} + +static int evm_pcf_setup(struct i2c_client *client, int gpio, + unsigned int ngpio, void *c) +{ + int status; + + if (ngpio < 8) + return -EINVAL; + + status = evm_sw_setup(client, gpio, 4, c); + if (status) + return status; + + return evm_led_setup(client, gpio+4, 4, c); +} + +static int evm_pcf_teardown(struct i2c_client *client, int gpio, + unsigned int ngpio, void *c) +{ + BUG_ON(ngpio < 8); + + evm_sw_teardown(client, gpio, 4, c); + evm_led_teardown(client, gpio+4, 4, c); + + return 0; +} + +static struct pcf857x_platform_data pcf_data = { + .gpio_base = DAVINCI_N_GPIO+1, + .setup = evm_pcf_setup, + .teardown = evm_pcf_teardown, +}; + +/* Most of this EEPROM is unused, but U-Boot uses some data: + * - 0x7f00, 6 bytes Ethernet Address + * - ... newer boards may have more + */ + +static struct at24_platform_data eeprom_info = { + .byte_len = (256*1024) / 8, + .page_size = 64, + .flags = AT24_FLAG_ADDR16, + .setup = davinci_get_mac_addr, + .context = (void *)0x7f00, +}; + +static u8 dm646x_iis_serializer_direction[] = { + TX_MODE, RX_MODE, INACTIVE_MODE, INACTIVE_MODE, +}; + +static u8 dm646x_dit_serializer_direction[] = { + TX_MODE, +}; + +static struct snd_platform_data dm646x_evm_snd_data[] = { + { + .tx_dma_offset = 0x400, + .rx_dma_offset = 0x400, + .op_mode = DAVINCI_MCASP_IIS_MODE, + .num_serializer = ARRAY_SIZE(dm646x_iis_serializer_direction), + .tdm_slots = 2, + .serial_dir = dm646x_iis_serializer_direction, + .asp_chan_q = EVENTQ_0, + }, + { + .tx_dma_offset = 0x400, + .rx_dma_offset = 0, + .op_mode = DAVINCI_MCASP_DIT_MODE, + .num_serializer = ARRAY_SIZE(dm646x_dit_serializer_direction), + .tdm_slots = 32, + .serial_dir = dm646x_dit_serializer_direction, + .asp_chan_q = EVENTQ_0, + }, +}; + +static struct i2c_client *cpld_client; + +static int cpld_video_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + cpld_client = client; + return 0; +} + +static int __devexit cpld_video_remove(struct i2c_client *client) +{ + cpld_client = NULL; + return 0; +} + +static const struct i2c_device_id cpld_video_id[] = { + { "cpld_video", 0 }, + { } +}; + +static struct i2c_driver cpld_video_driver = { + .driver = { + .name = "cpld_video", + }, + .probe = cpld_video_probe, + .remove = cpld_video_remove, + .id_table = cpld_video_id, +}; + +static void evm_init_cpld(void) +{ + i2c_add_driver(&cpld_video_driver); +} + +static struct i2c_board_info __initdata i2c_info[] = { + { + I2C_BOARD_INFO("24c256", 0x50), + .platform_data = &eeprom_info, + }, + { + I2C_BOARD_INFO("pcf8574a", 0x38), + .platform_data = &pcf_data, + }, + { + I2C_BOARD_INFO("cpld_reg0", 0x3a), + }, + { + I2C_BOARD_INFO("tlv320aic33", 0x18), + }, + { + I2C_BOARD_INFO("cpld_video", 0x3b), + }, + { + I2C_BOARD_INFO("cdce949", 0x6c), + }, +}; + +static struct davinci_i2c_platform_data i2c_pdata = { + .bus_freq = 100 /* kHz */, + .bus_delay = 0 /* usec */, +}; + +#define VCH2CLK_MASK (BIT_MASK(10) | BIT_MASK(9) | BIT_MASK(8)) +#define VCH2CLK_SYSCLK8 (BIT(9)) +#define VCH2CLK_AUXCLK (BIT(9) | BIT(8)) +#define VCH3CLK_MASK (BIT_MASK(14) | BIT_MASK(13) | BIT_MASK(12)) +#define VCH3CLK_SYSCLK8 (BIT(13)) +#define VCH3CLK_AUXCLK (BIT(14) | BIT(13)) + +#define VIDCH2CLK (BIT(10)) +#define VIDCH3CLK (BIT(11)) +#define VIDCH1CLK (BIT(4)) +#define TVP7002_INPUT (BIT(4)) +#define TVP5147_INPUT (~BIT(4)) +#define VPIF_INPUT_ONE_CHANNEL (BIT(5)) +#define VPIF_INPUT_TWO_CHANNEL (~BIT(5)) +#define TVP5147_CH0 "tvp514x-0" +#define TVP5147_CH1 "tvp514x-1" + +/* spin lock for updating above registers */ +static spinlock_t vpif_reg_lock; + +static int set_vpif_clock(int mux_mode, int hd) +{ + unsigned long flags; + unsigned int value; + int val = 0; + int err = 0; + + if (!cpld_client) + return -ENXIO; + + /* disable the clock */ + spin_lock_irqsave(&vpif_reg_lock, flags); + value = __raw_readl(DAVINCI_SYSMOD_VIRT(SYSMOD_VSCLKDIS)); + value |= (VIDCH3CLK | VIDCH2CLK); + __raw_writel(value, DAVINCI_SYSMOD_VIRT(SYSMOD_VSCLKDIS)); + spin_unlock_irqrestore(&vpif_reg_lock, flags); + + val = i2c_smbus_read_byte(cpld_client); + if (val < 0) + return val; + + if (mux_mode == 1) + val &= ~0x40; + else + val |= 0x40; + + err = i2c_smbus_write_byte(cpld_client, val); + if (err) + return err; + + value = __raw_readl(DAVINCI_SYSMOD_VIRT(SYSMOD_VIDCLKCTL)); + value &= ~(VCH2CLK_MASK); + value &= ~(VCH3CLK_MASK); + + if (hd >= 1) + value |= (VCH2CLK_SYSCLK8 | VCH3CLK_SYSCLK8); + else + value |= (VCH2CLK_AUXCLK | VCH3CLK_AUXCLK); + + __raw_writel(value, DAVINCI_SYSMOD_VIRT(SYSMOD_VIDCLKCTL)); + + spin_lock_irqsave(&vpif_reg_lock, flags); + value = __raw_readl(DAVINCI_SYSMOD_VIRT(SYSMOD_VSCLKDIS)); + /* enable the clock */ + value &= ~(VIDCH3CLK | VIDCH2CLK); + __raw_writel(value, DAVINCI_SYSMOD_VIRT(SYSMOD_VSCLKDIS)); + spin_unlock_irqrestore(&vpif_reg_lock, flags); + + return 0; +} + +static struct vpif_subdev_info dm646x_vpif_subdev[] = { + { + .name = "adv7343", + .board_info = { + I2C_BOARD_INFO("adv7343", 0x2a), + }, + }, + { + .name = "ths7303", + .board_info = { + I2C_BOARD_INFO("ths7303", 0x2c), + }, + }, +}; + +static const char *output[] = { + "Composite", + "Component", + "S-Video", +}; + +static struct vpif_display_config dm646x_vpif_display_config = { + .set_clock = set_vpif_clock, + .subdevinfo = dm646x_vpif_subdev, + .subdev_count = ARRAY_SIZE(dm646x_vpif_subdev), + .output = output, + .output_count = ARRAY_SIZE(output), + .card_name = "DM646x EVM", +}; + +/** + * setup_vpif_input_path() + * @channel: channel id (0 - CH0, 1 - CH1) + * @sub_dev_name: ptr sub device name + * + * This will set vpif input to capture data from tvp514x or + * tvp7002. + */ +static int setup_vpif_input_path(int channel, const char *sub_dev_name) +{ + int err = 0; + int val; + + /* for channel 1, we don't do anything */ + if (channel != 0) + return 0; + + if (!cpld_client) + return -ENXIO; + + val = i2c_smbus_read_byte(cpld_client); + if (val < 0) + return val; + + if (!strcmp(sub_dev_name, TVP5147_CH0) || + !strcmp(sub_dev_name, TVP5147_CH1)) + val &= TVP5147_INPUT; + else + val |= TVP7002_INPUT; + + err = i2c_smbus_write_byte(cpld_client, val); + if (err) + return err; + return 0; +} + +/** + * setup_vpif_input_channel_mode() + * @mux_mode: mux mode. 0 - 1 channel or (1) - 2 channel + * + * This will setup input mode to one channel (TVP7002) or 2 channel (TVP5147) + */ +static int setup_vpif_input_channel_mode(int mux_mode) +{ + unsigned long flags; + int err = 0; + int val; + u32 value; + + if (!cpld_client) + return -ENXIO; + + val = i2c_smbus_read_byte(cpld_client); + if (val < 0) + return val; + + spin_lock_irqsave(&vpif_reg_lock, flags); + value = __raw_readl(DAVINCI_SYSMOD_VIRT(SYSMOD_VIDCLKCTL)); + if (mux_mode) { + val &= VPIF_INPUT_TWO_CHANNEL; + value |= VIDCH1CLK; + } else { + val |= VPIF_INPUT_ONE_CHANNEL; + value &= ~VIDCH1CLK; + } + __raw_writel(value, DAVINCI_SYSMOD_VIRT(SYSMOD_VIDCLKCTL)); + spin_unlock_irqrestore(&vpif_reg_lock, flags); + + err = i2c_smbus_write_byte(cpld_client, val); + if (err) + return err; + + return 0; +} + +static struct tvp514x_platform_data tvp5146_pdata = { + .clk_polarity = 0, + .hs_polarity = 1, + .vs_polarity = 1 +}; + +#define TVP514X_STD_ALL (V4L2_STD_NTSC | V4L2_STD_PAL) + +static struct vpif_subdev_info vpif_capture_sdev_info[] = { + { + .name = TVP5147_CH0, + .board_info = { + I2C_BOARD_INFO("tvp5146", 0x5d), + .platform_data = &tvp5146_pdata, + }, + .input = INPUT_CVBS_VI2B, + .output = OUTPUT_10BIT_422_EMBEDDED_SYNC, + .can_route = 1, + .vpif_if = { + .if_type = VPIF_IF_BT656, + .hd_pol = 1, + .vd_pol = 1, + .fid_pol = 0, + }, + }, + { + .name = TVP5147_CH1, + .board_info = { + I2C_BOARD_INFO("tvp5146", 0x5c), + .platform_data = &tvp5146_pdata, + }, + .input = INPUT_SVIDEO_VI2C_VI1C, + .output = OUTPUT_10BIT_422_EMBEDDED_SYNC, + .can_route = 1, + .vpif_if = { + .if_type = VPIF_IF_BT656, + .hd_pol = 1, + .vd_pol = 1, + .fid_pol = 0, + }, + }, +}; + +static const struct vpif_input dm6467_ch0_inputs[] = { + { + .input = { + .index = 0, + .name = "Composite", + .type = V4L2_INPUT_TYPE_CAMERA, + .std = TVP514X_STD_ALL, + }, + .subdev_name = TVP5147_CH0, + }, +}; + +static const struct vpif_input dm6467_ch1_inputs[] = { + { + .input = { + .index = 0, + .name = "S-Video", + .type = V4L2_INPUT_TYPE_CAMERA, + .std = TVP514X_STD_ALL, + }, + .subdev_name = TVP5147_CH1, + }, +}; + +static struct vpif_capture_config dm646x_vpif_capture_cfg = { + .setup_input_path = setup_vpif_input_path, + .setup_input_channel_mode = setup_vpif_input_channel_mode, + .subdev_info = vpif_capture_sdev_info, + .subdev_count = ARRAY_SIZE(vpif_capture_sdev_info), + .chan_config[0] = { + .inputs = dm6467_ch0_inputs, + .input_count = ARRAY_SIZE(dm6467_ch0_inputs), + }, + .chan_config[1] = { + .inputs = dm6467_ch1_inputs, + .input_count = ARRAY_SIZE(dm6467_ch1_inputs), + }, +}; + +static void __init evm_init_video(void) +{ + spin_lock_init(&vpif_reg_lock); + + dm646x_setup_vpif(&dm646x_vpif_display_config, + &dm646x_vpif_capture_cfg); +} + +static void __init evm_init_i2c(void) +{ + davinci_init_i2c(&i2c_pdata); + i2c_add_driver(&dm6467evm_cpld_driver); + i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info)); + evm_init_cpld(); + evm_init_video(); +} + +#define CDCE949_XIN_RATE 27000000 + +/* CDCE949 support - "lpsc" field is overridden to work as clock number */ +static struct clk cdce_clk_in = { + .name = "cdce_xin", + .rate = CDCE949_XIN_RATE, +}; + +static struct clk_lookup cdce_clks[] = { + CLK(NULL, "xin", &cdce_clk_in), + CLK(NULL, NULL, NULL), +}; + +static void __init cdce_clk_init(void) +{ + struct clk_lookup *c; + struct clk *clk; + + for (c = cdce_clks; c->clk; c++) { + clk = c->clk; + clkdev_add(c); + clk_register(clk); + } +} + +#define DM6467T_EVM_REF_FREQ 33000000 + +static void __init davinci_map_io(void) +{ + dm646x_init(); + + if (machine_is_davinci_dm6467tevm()) + davinci_set_refclk_rate(DM6467T_EVM_REF_FREQ); + + cdce_clk_init(); +} + +static struct davinci_uart_config uart_config __initdata = { + .enabled_uarts = (1 << 0), +}; + +#define DM646X_EVM_PHY_ID "davinci_mdio-0:01" +/* + * The following EDMA channels/slots are not being used by drivers (for + * example: Timer, GPIO, UART events etc) on dm646x, hence they are being + * reserved for codecs on the DSP side. + */ +static const s16 dm646x_dma_rsv_chans[][2] = { + /* (offset, number) */ + { 0, 4}, + {13, 3}, + {24, 4}, + {30, 2}, + {54, 3}, + {-1, -1} +}; + +static const s16 dm646x_dma_rsv_slots[][2] = { + /* (offset, number) */ + { 0, 4}, + {13, 3}, + {24, 4}, + {30, 2}, + {54, 3}, + {128, 384}, + {-1, -1} +}; + +static struct edma_rsv_info dm646x_edma_rsv[] = { + { + .rsv_chans = dm646x_dma_rsv_chans, + .rsv_slots = dm646x_dma_rsv_slots, + }, +}; + +static __init void evm_init(void) +{ + struct davinci_soc_info *soc_info = &davinci_soc_info; + + evm_init_i2c(); + davinci_serial_init(&uart_config); + dm646x_init_mcasp0(&dm646x_evm_snd_data[0]); + dm646x_init_mcasp1(&dm646x_evm_snd_data[1]); + + if (machine_is_davinci_dm6467tevm()) + davinci_nand_data.timing = &dm6467tevm_nandflash_timing; + + platform_device_register(&davinci_nand_device); + + dm646x_init_edma(dm646x_edma_rsv); + + if (HAS_ATA) + davinci_init_ide(); + + soc_info->emac_pdata->phy_id = DM646X_EVM_PHY_ID; +} + +MACHINE_START(DAVINCI_DM6467_EVM, "DaVinci DM646x EVM") + .atag_offset = 0x100, + .map_io = davinci_map_io, + .init_irq = davinci_irq_init, + .timer = &davinci_timer, + .init_machine = evm_init, + .dma_zone_size = SZ_128M, + .restart = davinci_restart, +MACHINE_END + +MACHINE_START(DAVINCI_DM6467TEVM, "DaVinci DM6467T EVM") + .atag_offset = 0x100, + .map_io = davinci_map_io, + .init_irq = davinci_irq_init, + .timer = &davinci_timer, + .init_machine = evm_init, + .dma_zone_size = SZ_128M, + .restart = davinci_restart, +MACHINE_END + diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/board-mityomapl138.c b/ANDROID_3.4.5/arch/arm/mach-davinci/board-mityomapl138.c new file mode 100644 index 00000000..672d820e --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/board-mityomapl138.c @@ -0,0 +1,577 @@ +/* + * Critical Link MityOMAP-L138 SoM + * + * Copyright (C) 2010 Critical Link LLC - http://www.criticallink.com + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of + * any kind, whether express or implied. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/console.h> +#include <linux/platform_device.h> +#include <linux/mtd/partitions.h> +#include <linux/regulator/machine.h> +#include <linux/i2c.h> +#include <linux/i2c/at24.h> +#include <linux/etherdevice.h> +#include <linux/spi/spi.h> +#include <linux/spi/flash.h> + +#include <asm/io.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <mach/common.h> +#include <mach/cp_intc.h> +#include <mach/da8xx.h> +#include <mach/nand.h> +#include <mach/mux.h> +#include <mach/spi.h> + +#define MITYOMAPL138_PHY_ID "" + +#define FACTORY_CONFIG_MAGIC 0x012C0138 +#define FACTORY_CONFIG_VERSION 0x00010001 + +/* Data Held in On-Board I2C device */ +struct factory_config { + u32 magic; + u32 version; + u8 mac[6]; + u32 fpga_type; + u32 spare; + u32 serialnumber; + char partnum[32]; +}; + +static struct factory_config factory_config; + +struct part_no_info { + const char *part_no; /* part number string of interest */ + int max_freq; /* khz */ +}; + +static struct part_no_info mityomapl138_pn_info[] = { + { + .part_no = "L138-C", + .max_freq = 300000, + }, + { + .part_no = "L138-D", + .max_freq = 375000, + }, + { + .part_no = "L138-F", + .max_freq = 456000, + }, + { + .part_no = "1808-C", + .max_freq = 300000, + }, + { + .part_no = "1808-D", + .max_freq = 375000, + }, + { + .part_no = "1808-F", + .max_freq = 456000, + }, + { + .part_no = "1810-D", + .max_freq = 375000, + }, +}; + +#ifdef CONFIG_CPU_FREQ +static void mityomapl138_cpufreq_init(const char *partnum) +{ + int i, ret; + + for (i = 0; partnum && i < ARRAY_SIZE(mityomapl138_pn_info); i++) { + /* + * the part number has additional characters beyond what is + * stored in the table. This information is not needed for + * determining the speed grade, and would require several + * more table entries. Only check the first N characters + * for a match. + */ + if (!strncmp(partnum, mityomapl138_pn_info[i].part_no, + strlen(mityomapl138_pn_info[i].part_no))) { + da850_max_speed = mityomapl138_pn_info[i].max_freq; + break; + } + } + + ret = da850_register_cpufreq("pll0_sysclk3"); + if (ret) + pr_warning("cpufreq registration failed: %d\n", ret); +} +#else +static void mityomapl138_cpufreq_init(const char *partnum) { } +#endif + +static void read_factory_config(struct memory_accessor *a, void *context) +{ + int ret; + const char *partnum = NULL; + struct davinci_soc_info *soc_info = &davinci_soc_info; + + ret = a->read(a, (char *)&factory_config, 0, sizeof(factory_config)); + if (ret != sizeof(struct factory_config)) { + pr_warning("MityOMAPL138: Read Factory Config Failed: %d\n", + ret); + goto bad_config; + } + + if (factory_config.magic != FACTORY_CONFIG_MAGIC) { + pr_warning("MityOMAPL138: Factory Config Magic Wrong (%X)\n", + factory_config.magic); + goto bad_config; + } + + if (factory_config.version != FACTORY_CONFIG_VERSION) { + pr_warning("MityOMAPL138: Factory Config Version Wrong (%X)\n", + factory_config.version); + goto bad_config; + } + + pr_info("MityOMAPL138: Found MAC = %pM\n", factory_config.mac); + if (is_valid_ether_addr(factory_config.mac)) + memcpy(soc_info->emac_pdata->mac_addr, + factory_config.mac, ETH_ALEN); + else + pr_warning("MityOMAPL138: Invalid MAC found " + "in factory config block\n"); + + partnum = factory_config.partnum; + pr_info("MityOMAPL138: Part Number = %s\n", partnum); + +bad_config: + /* default maximum speed is valid for all platforms */ + mityomapl138_cpufreq_init(partnum); +} + +static struct at24_platform_data mityomapl138_fd_chip = { + .byte_len = 256, + .page_size = 8, + .flags = AT24_FLAG_READONLY | AT24_FLAG_IRUGO, + .setup = read_factory_config, + .context = NULL, +}; + +static struct davinci_i2c_platform_data mityomap_i2c_0_pdata = { + .bus_freq = 100, /* kHz */ + .bus_delay = 0, /* usec */ +}; + +/* TPS65023 voltage regulator support */ +/* 1.2V Core */ +static struct regulator_consumer_supply tps65023_dcdc1_consumers[] = { + { + .supply = "cvdd", + }, +}; + +/* 1.8V */ +static struct regulator_consumer_supply tps65023_dcdc2_consumers[] = { + { + .supply = "usb0_vdda18", + }, + { + .supply = "usb1_vdda18", + }, + { + .supply = "ddr_dvdd18", + }, + { + .supply = "sata_vddr", + }, +}; + +/* 1.2V */ +static struct regulator_consumer_supply tps65023_dcdc3_consumers[] = { + { + .supply = "sata_vdd", + }, + { + .supply = "usb_cvdd", + }, + { + .supply = "pll0_vdda", + }, + { + .supply = "pll1_vdda", + }, +}; + +/* 1.8V Aux LDO, not used */ +static struct regulator_consumer_supply tps65023_ldo1_consumers[] = { + { + .supply = "1.8v_aux", + }, +}; + +/* FPGA VCC Aux (2.5 or 3.3) LDO */ +static struct regulator_consumer_supply tps65023_ldo2_consumers[] = { + { + .supply = "vccaux", + }, +}; + +static struct regulator_init_data tps65023_regulator_data[] = { + /* dcdc1 */ + { + .constraints = { + .min_uV = 1150000, + .max_uV = 1350000, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS, + .boot_on = 1, + }, + .num_consumer_supplies = ARRAY_SIZE(tps65023_dcdc1_consumers), + .consumer_supplies = tps65023_dcdc1_consumers, + }, + /* dcdc2 */ + { + .constraints = { + .min_uV = 1800000, + .max_uV = 1800000, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + .boot_on = 1, + }, + .num_consumer_supplies = ARRAY_SIZE(tps65023_dcdc2_consumers), + .consumer_supplies = tps65023_dcdc2_consumers, + }, + /* dcdc3 */ + { + .constraints = { + .min_uV = 1200000, + .max_uV = 1200000, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + .boot_on = 1, + }, + .num_consumer_supplies = ARRAY_SIZE(tps65023_dcdc3_consumers), + .consumer_supplies = tps65023_dcdc3_consumers, + }, + /* ldo1 */ + { + .constraints = { + .min_uV = 1800000, + .max_uV = 1800000, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + .boot_on = 1, + }, + .num_consumer_supplies = ARRAY_SIZE(tps65023_ldo1_consumers), + .consumer_supplies = tps65023_ldo1_consumers, + }, + /* ldo2 */ + { + .constraints = { + .min_uV = 2500000, + .max_uV = 3300000, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS, + .boot_on = 1, + }, + .num_consumer_supplies = ARRAY_SIZE(tps65023_ldo2_consumers), + .consumer_supplies = tps65023_ldo2_consumers, + }, +}; + +static struct i2c_board_info __initdata mityomap_tps65023_info[] = { + { + I2C_BOARD_INFO("tps65023", 0x48), + .platform_data = &tps65023_regulator_data[0], + }, + { + I2C_BOARD_INFO("24c02", 0x50), + .platform_data = &mityomapl138_fd_chip, + }, +}; + +static int __init pmic_tps65023_init(void) +{ + return i2c_register_board_info(1, mityomap_tps65023_info, + ARRAY_SIZE(mityomap_tps65023_info)); +} + +/* + * SPI Devices: + * SPI1_CS0: 8M Flash ST-M25P64-VME6G + */ +static struct mtd_partition spi_flash_partitions[] = { + [0] = { + .name = "ubl", + .offset = 0, + .size = SZ_64K, + .mask_flags = MTD_WRITEABLE, + }, + [1] = { + .name = "u-boot", + .offset = MTDPART_OFS_APPEND, + .size = SZ_512K, + .mask_flags = MTD_WRITEABLE, + }, + [2] = { + .name = "u-boot-env", + .offset = MTDPART_OFS_APPEND, + .size = SZ_64K, + .mask_flags = MTD_WRITEABLE, + }, + [3] = { + .name = "periph-config", + .offset = MTDPART_OFS_APPEND, + .size = SZ_64K, + .mask_flags = MTD_WRITEABLE, + }, + [4] = { + .name = "reserved", + .offset = MTDPART_OFS_APPEND, + .size = SZ_256K + SZ_64K, + }, + [5] = { + .name = "kernel", + .offset = MTDPART_OFS_APPEND, + .size = SZ_2M + SZ_1M, + }, + [6] = { + .name = "fpga", + .offset = MTDPART_OFS_APPEND, + .size = SZ_2M, + }, + [7] = { + .name = "spare", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct flash_platform_data mityomapl138_spi_flash_data = { + .name = "m25p80", + .parts = spi_flash_partitions, + .nr_parts = ARRAY_SIZE(spi_flash_partitions), + .type = "m24p64", +}; + +static struct davinci_spi_config spi_eprom_config = { + .io_type = SPI_IO_TYPE_DMA, + .c2tdelay = 8, + .t2cdelay = 8, +}; + +static struct spi_board_info mityomapl138_spi_flash_info[] = { + { + .modalias = "m25p80", + .platform_data = &mityomapl138_spi_flash_data, + .controller_data = &spi_eprom_config, + .mode = SPI_MODE_0, + .max_speed_hz = 30000000, + .bus_num = 1, + .chip_select = 0, + }, +}; + +/* + * MityDSP-L138 includes a 256 MByte large-page NAND flash + * (128K blocks). + */ +static struct mtd_partition mityomapl138_nandflash_partition[] = { + { + .name = "rootfs", + .offset = 0, + .size = SZ_128M, + .mask_flags = 0, /* MTD_WRITEABLE, */ + }, + { + .name = "homefs", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + .mask_flags = 0, + }, +}; + +static struct davinci_nand_pdata mityomapl138_nandflash_data = { + .parts = mityomapl138_nandflash_partition, + .nr_parts = ARRAY_SIZE(mityomapl138_nandflash_partition), + .ecc_mode = NAND_ECC_HW, + .bbt_options = NAND_BBT_USE_FLASH, + .options = NAND_BUSWIDTH_16, + .ecc_bits = 1, /* 4 bit mode is not supported with 16 bit NAND */ +}; + +static struct resource mityomapl138_nandflash_resource[] = { + { + .start = DA8XX_AEMIF_CS3_BASE, + .end = DA8XX_AEMIF_CS3_BASE + SZ_512K + 2 * SZ_1K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = DA8XX_AEMIF_CTL_BASE, + .end = DA8XX_AEMIF_CTL_BASE + SZ_32K - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device mityomapl138_nandflash_device = { + .name = "davinci_nand", + .id = 1, + .dev = { + .platform_data = &mityomapl138_nandflash_data, + }, + .num_resources = ARRAY_SIZE(mityomapl138_nandflash_resource), + .resource = mityomapl138_nandflash_resource, +}; + +static struct platform_device *mityomapl138_devices[] __initdata = { + &mityomapl138_nandflash_device, +}; + +static void __init mityomapl138_setup_nand(void) +{ + platform_add_devices(mityomapl138_devices, + ARRAY_SIZE(mityomapl138_devices)); +} + +static struct davinci_uart_config mityomapl138_uart_config __initdata = { + .enabled_uarts = 0x7, +}; + +static const short mityomap_mii_pins[] = { + DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, + DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER, + DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3, + DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK, + DA850_MDIO_D, + -1 +}; + +static const short mityomap_rmii_pins[] = { + DA850_RMII_TXD_0, DA850_RMII_TXD_1, DA850_RMII_TXEN, + DA850_RMII_CRS_DV, DA850_RMII_RXD_0, DA850_RMII_RXD_1, + DA850_RMII_RXER, DA850_RMII_MHZ_50_CLK, DA850_MDIO_CLK, + DA850_MDIO_D, + -1 +}; + +static void __init mityomapl138_config_emac(void) +{ + void __iomem *cfg_chip3_base; + int ret; + u32 val; + struct davinci_soc_info *soc_info = &davinci_soc_info; + + soc_info->emac_pdata->rmii_en = 0; /* hardcoded for now */ + + cfg_chip3_base = DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG); + val = __raw_readl(cfg_chip3_base); + + if (soc_info->emac_pdata->rmii_en) { + val |= BIT(8); + ret = davinci_cfg_reg_list(mityomap_rmii_pins); + pr_info("RMII PHY configured\n"); + } else { + val &= ~BIT(8); + ret = davinci_cfg_reg_list(mityomap_mii_pins); + pr_info("MII PHY configured\n"); + } + + if (ret) { + pr_warning("mii/rmii mux setup failed: %d\n", ret); + return; + } + + /* configure the CFGCHIP3 register for RMII or MII */ + __raw_writel(val, cfg_chip3_base); + + soc_info->emac_pdata->phy_id = MITYOMAPL138_PHY_ID; + + ret = da8xx_register_emac(); + if (ret) + pr_warning("emac registration failed: %d\n", ret); +} + +static struct davinci_pm_config da850_pm_pdata = { + .sleepcount = 128, +}; + +static struct platform_device da850_pm_device = { + .name = "pm-davinci", + .dev = { + .platform_data = &da850_pm_pdata, + }, + .id = -1, +}; + +static void __init mityomapl138_init(void) +{ + int ret; + + /* for now, no special EDMA channels are reserved */ + ret = da850_register_edma(NULL); + if (ret) + pr_warning("edma registration failed: %d\n", ret); + + ret = da8xx_register_watchdog(); + if (ret) + pr_warning("watchdog registration failed: %d\n", ret); + + davinci_serial_init(&mityomapl138_uart_config); + + ret = da8xx_register_i2c(0, &mityomap_i2c_0_pdata); + if (ret) + pr_warning("i2c0 registration failed: %d\n", ret); + + ret = pmic_tps65023_init(); + if (ret) + pr_warning("TPS65023 PMIC init failed: %d\n", ret); + + mityomapl138_setup_nand(); + + ret = da8xx_register_spi(1, mityomapl138_spi_flash_info, + ARRAY_SIZE(mityomapl138_spi_flash_info)); + if (ret) + pr_warning("spi 1 registration failed: %d\n", ret); + + mityomapl138_config_emac(); + + ret = da8xx_register_rtc(); + if (ret) + pr_warning("rtc setup failed: %d\n", ret); + + ret = da8xx_register_cpuidle(); + if (ret) + pr_warning("cpuidle registration failed: %d\n", ret); + + ret = da850_register_pm(&da850_pm_device); + if (ret) + pr_warning("da850_evm_init: suspend registration failed: %d\n", + ret); +} + +#ifdef CONFIG_SERIAL_8250_CONSOLE +static int __init mityomapl138_console_init(void) +{ + if (!machine_is_mityomapl138()) + return 0; + + return add_preferred_console("ttyS", 1, "115200"); +} +console_initcall(mityomapl138_console_init); +#endif + +static void __init mityomapl138_map_io(void) +{ + da850_init(); +} + +MACHINE_START(MITYOMAPL138, "MityDSP-L138/MityARM-1808") + .atag_offset = 0x100, + .map_io = mityomapl138_map_io, + .init_irq = cp_intc_init, + .timer = &davinci_timer, + .init_machine = mityomapl138_init, + .dma_zone_size = SZ_128M, + .restart = da8xx_restart, +MACHINE_END diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/board-neuros-osd2.c b/ANDROID_3.4.5/arch/arm/mach-davinci/board-neuros-osd2.c new file mode 100644 index 00000000..a772bb45 --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/board-neuros-osd2.c @@ -0,0 +1,283 @@ +/* + * Neuros Technologies OSD2 board support + * + * Modified from original 644X-EVM board support. + * 2008 (c) Neuros Technology, LLC. + * 2009 (c) Jorge Luis Zapata Muga <jorgeluis.zapata@gmail.com> + * 2009 (c) Andrey A. Porodko <Andrey.Porodko@gmail.com> + * + * The Neuros OSD 2.0 is the hardware component of the Neuros Open + * Internet Television Platform. Hardware is very close to TI + * DM644X-EVM board. It has: + * DM6446M02 module with 256MB NAND, 256MB RAM, TLV320AIC32 AIC, + * USB, Ethernet, SD/MMC, UART, THS8200, TVP7000 for video. + * Additionally realtime clock, IR remote control receiver, + * IR Blaster based on MSP430 (firmware although is different + * from used in DM644X-EVM), internal ATA-6 3.5” HDD drive + * with PATA interface, two muxed red-green leds. + * + * For more information please refer to + * http://wiki.neurostechnology.com/index.php/OSD_2.0_HD + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ +#include <linux/platform_device.h> +#include <linux/gpio.h> +#include <linux/mtd/partitions.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> + +#include <mach/common.h> +#include <mach/i2c.h> +#include <mach/serial.h> +#include <mach/mux.h> +#include <mach/nand.h> +#include <mach/mmc.h> +#include <mach/usb.h> + +#include "davinci.h" + +#define NEUROS_OSD2_PHY_ID "davinci_mdio-0:01" +#define LXT971_PHY_ID 0x001378e2 +#define LXT971_PHY_MASK 0xfffffff0 + +#define NTOSD2_AUDIOSOC_I2C_ADDR 0x18 +#define NTOSD2_MSP430_I2C_ADDR 0x59 +#define NTOSD2_MSP430_IRQ 2 + +/* Neuros OSD2 has a Samsung 256 MByte NAND flash (Dev ID of 0xAA, + * 2048 blocks in the device, 64 pages per block, 2048 bytes per + * page. + */ + +#define NAND_BLOCK_SIZE SZ_128K + +static struct mtd_partition davinci_ntosd2_nandflash_partition[] = { + { + /* UBL (a few copies) plus U-Boot */ + .name = "bootloader", + .offset = 0, + .size = 15 * NAND_BLOCK_SIZE, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, { + /* U-Boot environment */ + .name = "params", + .offset = MTDPART_OFS_APPEND, + .size = 1 * NAND_BLOCK_SIZE, + .mask_flags = 0, + }, { + /* Kernel */ + .name = "kernel", + .offset = MTDPART_OFS_APPEND, + .size = SZ_4M, + .mask_flags = 0, + }, { + /* File System */ + .name = "filesystem", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + .mask_flags = 0, + } + /* A few blocks at end hold a flash Bad Block Table. */ +}; + +static struct davinci_nand_pdata davinci_ntosd2_nandflash_data = { + .parts = davinci_ntosd2_nandflash_partition, + .nr_parts = ARRAY_SIZE(davinci_ntosd2_nandflash_partition), + .ecc_mode = NAND_ECC_HW, + .bbt_options = NAND_BBT_USE_FLASH, +}; + +static struct resource davinci_ntosd2_nandflash_resource[] = { + { + .start = DM644X_ASYNC_EMIF_DATA_CE0_BASE, + .end = DM644X_ASYNC_EMIF_DATA_CE0_BASE + SZ_16M - 1, + .flags = IORESOURCE_MEM, + }, { + .start = DM644X_ASYNC_EMIF_CONTROL_BASE, + .end = DM644X_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device davinci_ntosd2_nandflash_device = { + .name = "davinci_nand", + .id = 0, + .dev = { + .platform_data = &davinci_ntosd2_nandflash_data, + }, + .num_resources = ARRAY_SIZE(davinci_ntosd2_nandflash_resource), + .resource = davinci_ntosd2_nandflash_resource, +}; + +static u64 davinci_fb_dma_mask = DMA_BIT_MASK(32); + +static struct platform_device davinci_fb_device = { + .name = "davincifb", + .id = -1, + .dev = { + .dma_mask = &davinci_fb_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .num_resources = 0, +}; + +static struct snd_platform_data dm644x_ntosd2_snd_data; + +static struct gpio_led ntosd2_leds[] = { + { .name = "led1_green", .gpio = GPIO(10), }, + { .name = "led1_red", .gpio = GPIO(11), }, + { .name = "led2_green", .gpio = GPIO(12), }, + { .name = "led2_red", .gpio = GPIO(13), }, +}; + +static struct gpio_led_platform_data ntosd2_leds_data = { + .num_leds = ARRAY_SIZE(ntosd2_leds), + .leds = ntosd2_leds, +}; + +static struct platform_device ntosd2_leds_dev = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &ntosd2_leds_data, + }, +}; + + +static struct platform_device *davinci_ntosd2_devices[] __initdata = { + &davinci_fb_device, + &ntosd2_leds_dev, +}; + +static struct davinci_uart_config uart_config __initdata = { + .enabled_uarts = (1 << 0), +}; + +static void __init davinci_ntosd2_map_io(void) +{ + dm644x_init(); +} + +/* + I2C initialization +*/ +static struct davinci_i2c_platform_data ntosd2_i2c_pdata = { + .bus_freq = 20 /* kHz */, + .bus_delay = 100 /* usec */, +}; + +static struct i2c_board_info __initdata ntosd2_i2c_info[] = { +}; + +static int ntosd2_init_i2c(void) +{ + int status; + + davinci_init_i2c(&ntosd2_i2c_pdata); + status = gpio_request(NTOSD2_MSP430_IRQ, ntosd2_i2c_info[0].type); + if (status == 0) { + status = gpio_direction_input(NTOSD2_MSP430_IRQ); + if (status == 0) { + status = gpio_to_irq(NTOSD2_MSP430_IRQ); + if (status > 0) { + ntosd2_i2c_info[0].irq = status; + i2c_register_board_info(1, + ntosd2_i2c_info, + ARRAY_SIZE(ntosd2_i2c_info)); + } + } + } + return status; +} + +static struct davinci_mmc_config davinci_ntosd2_mmc_config = { + .wires = 4, + .version = MMC_CTLR_VERSION_1 +}; + + +#if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \ + defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE) +#define HAS_ATA 1 +#else +#define HAS_ATA 0 +#endif + +#if defined(CONFIG_MTD_NAND_DAVINCI) || \ + defined(CONFIG_MTD_NAND_DAVINCI_MODULE) +#define HAS_NAND 1 +#else +#define HAS_NAND 0 +#endif + +static __init void davinci_ntosd2_init(void) +{ + struct clk *aemif_clk; + struct davinci_soc_info *soc_info = &davinci_soc_info; + int status; + + aemif_clk = clk_get(NULL, "aemif"); + clk_enable(aemif_clk); + + if (HAS_ATA) { + if (HAS_NAND) + pr_warning("WARNING: both IDE and Flash are " + "enabled, but they share AEMIF pins.\n" + "\tDisable IDE for NAND/NOR support.\n"); + davinci_init_ide(); + } else if (HAS_NAND) { + davinci_cfg_reg(DM644X_HPIEN_DISABLE); + davinci_cfg_reg(DM644X_ATAEN_DISABLE); + + /* only one device will be jumpered and detected */ + if (HAS_NAND) + platform_device_register( + &davinci_ntosd2_nandflash_device); + } + + platform_add_devices(davinci_ntosd2_devices, + ARRAY_SIZE(davinci_ntosd2_devices)); + + /* Initialize I2C interface specific for this board */ + status = ntosd2_init_i2c(); + if (status < 0) + pr_warning("davinci_ntosd2_init: msp430 irq setup failed:" + " %d\n", status); + + davinci_serial_init(&uart_config); + dm644x_init_asp(&dm644x_ntosd2_snd_data); + + soc_info->emac_pdata->phy_id = NEUROS_OSD2_PHY_ID; + + davinci_setup_usb(1000, 8); + /* + * Mux the pins to be GPIOs, VLYNQEN is already done at startup. + * The AEAWx are five new AEAW pins that can be muxed by separately. + * They are a bitmask for GPIO management. According TI + * documentation (http://www.ti.com/lit/gpn/tms320dm6446) to employ + * gpio(10,11,12,13) for leds any combination of bits works except + * four last. So we are to reset all five. + */ + davinci_cfg_reg(DM644X_AEAW0); + davinci_cfg_reg(DM644X_AEAW1); + davinci_cfg_reg(DM644X_AEAW2); + davinci_cfg_reg(DM644X_AEAW3); + davinci_cfg_reg(DM644X_AEAW4); + + davinci_setup_mmc(0, &davinci_ntosd2_mmc_config); +} + +MACHINE_START(NEUROS_OSD2, "Neuros OSD2") + /* Maintainer: Neuros Technologies <neuros@groups.google.com> */ + .atag_offset = 0x100, + .map_io = davinci_ntosd2_map_io, + .init_irq = davinci_irq_init, + .timer = &davinci_timer, + .init_machine = davinci_ntosd2_init, + .dma_zone_size = SZ_128M, + .restart = davinci_restart, +MACHINE_END diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/board-omapl138-hawk.c b/ANDROID_3.4.5/arch/arm/mach-davinci/board-omapl138-hawk.c new file mode 100644 index 00000000..45e81576 --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -0,0 +1,348 @@ +/* + * Hawkboard.org based on TI's OMAP-L138 Platform + * + * Initial code: Syed Mohammed Khasim + * + * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of + * any kind, whether express or implied. + */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/console.h> +#include <linux/gpio.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> + +#include <mach/cp_intc.h> +#include <mach/da8xx.h> +#include <mach/mux.h> + +#define HAWKBOARD_PHY_ID "davinci_mdio-0:07" +#define DA850_HAWK_MMCSD_CD_PIN GPIO_TO_PIN(3, 12) +#define DA850_HAWK_MMCSD_WP_PIN GPIO_TO_PIN(3, 13) + +#define DA850_USB1_VBUS_PIN GPIO_TO_PIN(2, 4) +#define DA850_USB1_OC_PIN GPIO_TO_PIN(6, 13) + +static short omapl138_hawk_mii_pins[] __initdata = { + DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, + DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER, + DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3, + DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK, + DA850_MDIO_D, + -1 +}; + +static __init void omapl138_hawk_config_emac(void) +{ + void __iomem *cfgchip3 = DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG); + int ret; + u32 val; + struct davinci_soc_info *soc_info = &davinci_soc_info; + + val = __raw_readl(cfgchip3); + val &= ~BIT(8); + ret = davinci_cfg_reg_list(omapl138_hawk_mii_pins); + if (ret) { + pr_warning("%s: cpgmac/mii mux setup failed: %d\n", + __func__, ret); + return; + } + + /* configure the CFGCHIP3 register for MII */ + __raw_writel(val, cfgchip3); + pr_info("EMAC: MII PHY configured\n"); + + soc_info->emac_pdata->phy_id = HAWKBOARD_PHY_ID; + + ret = da8xx_register_emac(); + if (ret) + pr_warning("%s: emac registration failed: %d\n", + __func__, ret); +} + +/* + * The following EDMA channels/slots are not being used by drivers (for + * example: Timer, GPIO, UART events etc) on da850/omap-l138 EVM/Hawkboard, + * hence they are being reserved for codecs on the DSP side. + */ +static const s16 da850_dma0_rsv_chans[][2] = { + /* (offset, number) */ + { 8, 6}, + {24, 4}, + {30, 2}, + {-1, -1} +}; + +static const s16 da850_dma0_rsv_slots[][2] = { + /* (offset, number) */ + { 8, 6}, + {24, 4}, + {30, 50}, + {-1, -1} +}; + +static const s16 da850_dma1_rsv_chans[][2] = { + /* (offset, number) */ + { 0, 28}, + {30, 2}, + {-1, -1} +}; + +static const s16 da850_dma1_rsv_slots[][2] = { + /* (offset, number) */ + { 0, 28}, + {30, 90}, + {-1, -1} +}; + +static struct edma_rsv_info da850_edma_cc0_rsv = { + .rsv_chans = da850_dma0_rsv_chans, + .rsv_slots = da850_dma0_rsv_slots, +}; + +static struct edma_rsv_info da850_edma_cc1_rsv = { + .rsv_chans = da850_dma1_rsv_chans, + .rsv_slots = da850_dma1_rsv_slots, +}; + +static struct edma_rsv_info *da850_edma_rsv[2] = { + &da850_edma_cc0_rsv, + &da850_edma_cc1_rsv, +}; + +static const short hawk_mmcsd0_pins[] = { + DA850_MMCSD0_DAT_0, DA850_MMCSD0_DAT_1, DA850_MMCSD0_DAT_2, + DA850_MMCSD0_DAT_3, DA850_MMCSD0_CLK, DA850_MMCSD0_CMD, + DA850_GPIO3_12, DA850_GPIO3_13, + -1 +}; + +static int da850_hawk_mmc_get_ro(int index) +{ + return gpio_get_value(DA850_HAWK_MMCSD_WP_PIN); +} + +static int da850_hawk_mmc_get_cd(int index) +{ + return !gpio_get_value(DA850_HAWK_MMCSD_CD_PIN); +} + +static struct davinci_mmc_config da850_mmc_config = { + .get_ro = da850_hawk_mmc_get_ro, + .get_cd = da850_hawk_mmc_get_cd, + .wires = 4, + .max_freq = 50000000, + .caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED, + .version = MMC_CTLR_VERSION_2, +}; + +static __init void omapl138_hawk_mmc_init(void) +{ + int ret; + + ret = davinci_cfg_reg_list(hawk_mmcsd0_pins); + if (ret) { + pr_warning("%s: MMC/SD0 mux setup failed: %d\n", + __func__, ret); + return; + } + + ret = gpio_request_one(DA850_HAWK_MMCSD_CD_PIN, + GPIOF_DIR_IN, "MMC CD"); + if (ret < 0) { + pr_warning("%s: can not open GPIO %d\n", + __func__, DA850_HAWK_MMCSD_CD_PIN); + return; + } + + ret = gpio_request_one(DA850_HAWK_MMCSD_WP_PIN, + GPIOF_DIR_IN, "MMC WP"); + if (ret < 0) { + pr_warning("%s: can not open GPIO %d\n", + __func__, DA850_HAWK_MMCSD_WP_PIN); + goto mmc_setup_wp_fail; + } + + ret = da8xx_register_mmcsd0(&da850_mmc_config); + if (ret) { + pr_warning("%s: MMC/SD0 registration failed: %d\n", + __func__, ret); + goto mmc_setup_mmcsd_fail; + } + + return; + +mmc_setup_mmcsd_fail: + gpio_free(DA850_HAWK_MMCSD_WP_PIN); +mmc_setup_wp_fail: + gpio_free(DA850_HAWK_MMCSD_CD_PIN); +} + +static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id); +static da8xx_ocic_handler_t hawk_usb_ocic_handler; + +static const short da850_hawk_usb11_pins[] = { + DA850_GPIO2_4, DA850_GPIO6_13, + -1 +}; + +static int hawk_usb_set_power(unsigned port, int on) +{ + gpio_set_value(DA850_USB1_VBUS_PIN, on); + return 0; +} + +static int hawk_usb_get_power(unsigned port) +{ + return gpio_get_value(DA850_USB1_VBUS_PIN); +} + +static int hawk_usb_get_oci(unsigned port) +{ + return !gpio_get_value(DA850_USB1_OC_PIN); +} + +static int hawk_usb_ocic_notify(da8xx_ocic_handler_t handler) +{ + int irq = gpio_to_irq(DA850_USB1_OC_PIN); + int error = 0; + + if (handler != NULL) { + hawk_usb_ocic_handler = handler; + + error = request_irq(irq, omapl138_hawk_usb_ocic_irq, + IRQF_DISABLED | IRQF_TRIGGER_RISING | + IRQF_TRIGGER_FALLING, + "OHCI over-current indicator", NULL); + if (error) + pr_err("%s: could not request IRQ to watch " + "over-current indicator changes\n", __func__); + } else { + free_irq(irq, NULL); + } + return error; +} + +static struct da8xx_ohci_root_hub omapl138_hawk_usb11_pdata = { + .set_power = hawk_usb_set_power, + .get_power = hawk_usb_get_power, + .get_oci = hawk_usb_get_oci, + .ocic_notify = hawk_usb_ocic_notify, + /* TPS2087 switch @ 5V */ + .potpgt = (3 + 1) / 2, /* 3 ms max */ +}; + +static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id) +{ + hawk_usb_ocic_handler(&omapl138_hawk_usb11_pdata, 1); + return IRQ_HANDLED; +} + +static __init void omapl138_hawk_usb_init(void) +{ + int ret; + u32 cfgchip2; + + ret = davinci_cfg_reg_list(da850_hawk_usb11_pins); + if (ret) { + pr_warning("%s: USB 1.1 PinMux setup failed: %d\n", + __func__, ret); + return; + } + + /* Setup the Ref. clock frequency for the HAWK at 24 MHz. */ + + cfgchip2 = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)); + cfgchip2 &= ~CFGCHIP2_REFFREQ; + cfgchip2 |= CFGCHIP2_REFFREQ_24MHZ; + __raw_writel(cfgchip2, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)); + + ret = gpio_request_one(DA850_USB1_VBUS_PIN, + GPIOF_DIR_OUT, "USB1 VBUS"); + if (ret < 0) { + pr_err("%s: failed to request GPIO for USB 1.1 port " + "power control: %d\n", __func__, ret); + return; + } + + ret = gpio_request_one(DA850_USB1_OC_PIN, + GPIOF_DIR_IN, "USB1 OC"); + if (ret < 0) { + pr_err("%s: failed to request GPIO for USB 1.1 port " + "over-current indicator: %d\n", __func__, ret); + goto usb11_setup_oc_fail; + } + + ret = da8xx_register_usb11(&omapl138_hawk_usb11_pdata); + if (ret) { + pr_warning("%s: USB 1.1 registration failed: %d\n", + __func__, ret); + goto usb11_setup_fail; + } + + return; + +usb11_setup_fail: + gpio_free(DA850_USB1_OC_PIN); +usb11_setup_oc_fail: + gpio_free(DA850_USB1_VBUS_PIN); +} + +static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { + .enabled_uarts = 0x7, +}; + +static __init void omapl138_hawk_init(void) +{ + int ret; + + davinci_serial_init(&omapl138_hawk_uart_config); + + omapl138_hawk_config_emac(); + + ret = da850_register_edma(da850_edma_rsv); + if (ret) + pr_warning("%s: EDMA registration failed: %d\n", + __func__, ret); + + omapl138_hawk_mmc_init(); + + omapl138_hawk_usb_init(); + + ret = da8xx_register_watchdog(); + if (ret) + pr_warning("omapl138_hawk_init: " + "watchdog registration failed: %d\n", + ret); +} + +#ifdef CONFIG_SERIAL_8250_CONSOLE +static int __init omapl138_hawk_console_init(void) +{ + if (!machine_is_omapl138_hawkboard()) + return 0; + + return add_preferred_console("ttyS", 2, "115200"); +} +console_initcall(omapl138_hawk_console_init); +#endif + +static void __init omapl138_hawk_map_io(void) +{ + da850_init(); +} + +MACHINE_START(OMAPL138_HAWKBOARD, "AM18x/OMAP-L138 Hawkboard") + .atag_offset = 0x100, + .map_io = omapl138_hawk_map_io, + .init_irq = cp_intc_init, + .timer = &davinci_timer, + .init_machine = omapl138_hawk_init, + .dma_zone_size = SZ_128M, + .restart = da8xx_restart, +MACHINE_END diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/board-sffsdr.c b/ANDROID_3.4.5/arch/arm/mach-davinci/board-sffsdr.c new file mode 100644 index 00000000..76e67509 --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/board-sffsdr.c @@ -0,0 +1,162 @@ +/* + * Lyrtech SFFSDR board support. + * + * Copyright (C) 2008 Philip Balister, OpenSDR <philip@opensdr.com> + * Copyright (C) 2008 Lyrtech <www.lyrtech.com> + * + * Based on DV-EVM platform, original copyright follows: + * + * Copyright (C) 2007 MontaVista Software, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/i2c.h> +#include <linux/i2c/at24.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/nand.h> +#include <linux/mtd/partitions.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/flash.h> + +#include <mach/common.h> +#include <mach/i2c.h> +#include <mach/serial.h> +#include <mach/mux.h> +#include <mach/usb.h> + +#include "davinci.h" + +#define SFFSDR_PHY_ID "davinci_mdio-0:01" +static struct mtd_partition davinci_sffsdr_nandflash_partition[] = { + /* U-Boot Environment: Block 0 + * UBL: Block 1 + * U-Boot: Blocks 6-7 (256 kb) + * Integrity Kernel: Blocks 8-31 (3 Mb) + * Integrity Data: Blocks 100-END + */ + { + .name = "Linux Kernel", + .offset = 32 * SZ_128K, + .size = 16 * SZ_128K, /* 2 Mb */ + .mask_flags = MTD_WRITEABLE, /* Force read-only */ + }, + { + .name = "Linux ROOT", + .offset = MTDPART_OFS_APPEND, + .size = 256 * SZ_128K, /* 32 Mb */ + .mask_flags = 0, /* R/W */ + }, +}; + +static struct flash_platform_data davinci_sffsdr_nandflash_data = { + .parts = davinci_sffsdr_nandflash_partition, + .nr_parts = ARRAY_SIZE(davinci_sffsdr_nandflash_partition), +}; + +static struct resource davinci_sffsdr_nandflash_resource[] = { + { + .start = DM644X_ASYNC_EMIF_DATA_CE0_BASE, + .end = DM644X_ASYNC_EMIF_DATA_CE0_BASE + SZ_16M - 1, + .flags = IORESOURCE_MEM, + }, { + .start = DM644X_ASYNC_EMIF_CONTROL_BASE, + .end = DM644X_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device davinci_sffsdr_nandflash_device = { + .name = "davinci_nand", /* Name of driver */ + .id = 0, + .dev = { + .platform_data = &davinci_sffsdr_nandflash_data, + }, + .num_resources = ARRAY_SIZE(davinci_sffsdr_nandflash_resource), + .resource = davinci_sffsdr_nandflash_resource, +}; + +static struct at24_platform_data eeprom_info = { + .byte_len = (64*1024) / 8, + .page_size = 32, + .flags = AT24_FLAG_ADDR16, +}; + +static struct i2c_board_info __initdata i2c_info[] = { + { + I2C_BOARD_INFO("24lc64", 0x50), + .platform_data = &eeprom_info, + }, + /* Other I2C devices: + * MSP430, addr 0x23 (not used) + * PCA9543, addr 0x70 (setup done by U-Boot) + * ADS7828, addr 0x48 (ADC for voltage monitoring.) + */ +}; + +static struct davinci_i2c_platform_data i2c_pdata = { + .bus_freq = 20 /* kHz */, + .bus_delay = 100 /* usec */, +}; + +static void __init sffsdr_init_i2c(void) +{ + davinci_init_i2c(&i2c_pdata); + i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info)); +} + +static struct platform_device *davinci_sffsdr_devices[] __initdata = { + &davinci_sffsdr_nandflash_device, +}; + +static struct davinci_uart_config uart_config __initdata = { + .enabled_uarts = (1 << 0), +}; + +static void __init davinci_sffsdr_map_io(void) +{ + dm644x_init(); +} + +static __init void davinci_sffsdr_init(void) +{ + struct davinci_soc_info *soc_info = &davinci_soc_info; + + platform_add_devices(davinci_sffsdr_devices, + ARRAY_SIZE(davinci_sffsdr_devices)); + sffsdr_init_i2c(); + davinci_serial_init(&uart_config); + soc_info->emac_pdata->phy_id = SFFSDR_PHY_ID; + davinci_setup_usb(0, 0); /* We support only peripheral mode. */ + + /* mux VLYNQ pins */ + davinci_cfg_reg(DM644X_VLYNQEN); + davinci_cfg_reg(DM644X_VLYNQWD); +} + +MACHINE_START(SFFSDR, "Lyrtech SFFSDR") + /* Maintainer: Hugo Villeneuve hugo.villeneuve@lyrtech.com */ + .atag_offset = 0x100, + .map_io = davinci_sffsdr_map_io, + .init_irq = davinci_irq_init, + .timer = &davinci_timer, + .init_machine = davinci_sffsdr_init, + .dma_zone_size = SZ_128M, + .restart = davinci_restart, +MACHINE_END diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/board-tnetv107x-evm.c b/ANDROID_3.4.5/arch/arm/mach-davinci/board-tnetv107x-evm.c new file mode 100644 index 00000000..5f14e30b --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/board-tnetv107x-evm.c @@ -0,0 +1,287 @@ +/* + * Texas Instruments TNETV107X EVM Board Support + * + * Copyright (C) 2010 Texas Instruments + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/console.h> +#include <linux/dma-mapping.h> +#include <linux/interrupt.h> +#include <linux/gpio.h> +#include <linux/delay.h> +#include <linux/platform_device.h> +#include <linux/ratelimit.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> +#include <linux/input.h> +#include <linux/input/matrix_keypad.h> +#include <linux/spi/spi.h> + +#include <asm/mach/arch.h> +#include <asm/mach-types.h> + +#include <mach/irqs.h> +#include <mach/edma.h> +#include <mach/mux.h> +#include <mach/cp_intc.h> +#include <mach/tnetv107x.h> + +#define EVM_MMC_WP_GPIO 21 +#define EVM_MMC_CD_GPIO 24 +#define EVM_SPI_CS_GPIO 54 + +static int initialize_gpio(int gpio, char *desc) +{ + int ret; + + ret = gpio_request(gpio, desc); + if (ret < 0) { + pr_err_ratelimited("cannot open %s gpio\n", desc); + return -ENOSYS; + } + gpio_direction_input(gpio); + return gpio; +} + +static int mmc_get_cd(int index) +{ + static int gpio; + + if (!gpio) + gpio = initialize_gpio(EVM_MMC_CD_GPIO, "mmc card detect"); + + if (gpio < 0) + return gpio; + + return gpio_get_value(gpio) ? 0 : 1; +} + +static int mmc_get_ro(int index) +{ + static int gpio; + + if (!gpio) + gpio = initialize_gpio(EVM_MMC_WP_GPIO, "mmc write protect"); + + if (gpio < 0) + return gpio; + + return gpio_get_value(gpio) ? 1 : 0; +} + +static struct davinci_mmc_config mmc_config = { + .get_cd = mmc_get_cd, + .get_ro = mmc_get_ro, + .wires = 4, + .max_freq = 50000000, + .caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED, + .version = MMC_CTLR_VERSION_1, +}; + +static const short sdio1_pins[] __initdata = { + TNETV107X_SDIO1_CLK_1, TNETV107X_SDIO1_CMD_1, + TNETV107X_SDIO1_DATA0_1, TNETV107X_SDIO1_DATA1_1, + TNETV107X_SDIO1_DATA2_1, TNETV107X_SDIO1_DATA3_1, + TNETV107X_GPIO21, TNETV107X_GPIO24, + -1 +}; + +static const short uart1_pins[] __initdata = { + TNETV107X_UART1_RD, TNETV107X_UART1_TD, + -1 +}; + +static const short ssp_pins[] __initdata = { + TNETV107X_SSP0_0, TNETV107X_SSP0_1, TNETV107X_SSP0_2, + TNETV107X_SSP1_0, TNETV107X_SSP1_1, TNETV107X_SSP1_2, + TNETV107X_SSP1_3, -1 +}; + +static struct mtd_partition nand_partitions[] = { + /* bootloader (U-Boot, etc) in first 12 sectors */ + { + .name = "bootloader", + .offset = 0, + .size = (12*SZ_128K), + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + /* bootloader params in the next sector */ + { + .name = "params", + .offset = MTDPART_OFS_NXTBLK, + .size = SZ_128K, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + /* kernel */ + { + .name = "kernel", + .offset = MTDPART_OFS_NXTBLK, + .size = SZ_4M, + .mask_flags = 0, + }, + /* file system */ + { + .name = "filesystem", + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL, + .mask_flags = 0, + } +}; + +static struct davinci_nand_pdata nand_config = { + .mask_cle = 0x4000, + .mask_ale = 0x2000, + .parts = nand_partitions, + .nr_parts = ARRAY_SIZE(nand_partitions), + .ecc_mode = NAND_ECC_HW, + .bbt_options = NAND_BBT_USE_FLASH, + .ecc_bits = 1, +}; + +static struct davinci_uart_config serial_config __initconst = { + .enabled_uarts = BIT(1), +}; + +static const uint32_t keymap[] = { + KEY(0, 0, KEY_NUMERIC_1), + KEY(0, 1, KEY_NUMERIC_2), + KEY(0, 2, KEY_NUMERIC_3), + KEY(0, 3, KEY_FN_F1), + KEY(0, 4, KEY_MENU), + + KEY(1, 0, KEY_NUMERIC_4), + KEY(1, 1, KEY_NUMERIC_5), + KEY(1, 2, KEY_NUMERIC_6), + KEY(1, 3, KEY_UP), + KEY(1, 4, KEY_FN_F2), + + KEY(2, 0, KEY_NUMERIC_7), + KEY(2, 1, KEY_NUMERIC_8), + KEY(2, 2, KEY_NUMERIC_9), + KEY(2, 3, KEY_LEFT), + KEY(2, 4, KEY_ENTER), + + KEY(3, 0, KEY_NUMERIC_STAR), + KEY(3, 1, KEY_NUMERIC_0), + KEY(3, 2, KEY_NUMERIC_POUND), + KEY(3, 3, KEY_DOWN), + KEY(3, 4, KEY_RIGHT), + + KEY(4, 0, KEY_FN_F3), + KEY(4, 1, KEY_FN_F4), + KEY(4, 2, KEY_MUTE), + KEY(4, 3, KEY_HOME), + KEY(4, 4, KEY_BACK), + + KEY(5, 0, KEY_VOLUMEDOWN), + KEY(5, 1, KEY_VOLUMEUP), + KEY(5, 2, KEY_F1), + KEY(5, 3, KEY_F2), + KEY(5, 4, KEY_F3), +}; + +static const struct matrix_keymap_data keymap_data = { + .keymap = keymap, + .keymap_size = ARRAY_SIZE(keymap), +}; + +static struct matrix_keypad_platform_data keypad_config = { + .keymap_data = &keymap_data, + .num_row_gpios = 6, + .num_col_gpios = 5, + .debounce_ms = 0, /* minimum */ + .active_low = 0, /* pull up realization */ + .no_autorepeat = 0, +}; + +static void spi_select_device(int cs) +{ + static int gpio; + + if (!gpio) { + int ret; + ret = gpio_request(EVM_SPI_CS_GPIO, "spi chipsel"); + if (ret < 0) { + pr_err("cannot open spi chipsel gpio\n"); + gpio = -ENOSYS; + return; + } else { + gpio = EVM_SPI_CS_GPIO; + gpio_direction_output(gpio, 0); + } + } + + if (gpio < 0) + return; + + return gpio_set_value(gpio, cs ? 1 : 0); +} + +static struct ti_ssp_spi_data spi_master_data = { + .num_cs = 2, + .select = spi_select_device, + .iosel = SSP_PIN_SEL(0, SSP_CLOCK) | SSP_PIN_SEL(1, SSP_DATA) | + SSP_PIN_SEL(2, SSP_CHIPSEL) | SSP_PIN_SEL(3, SSP_IN) | + SSP_INPUT_SEL(3), +}; + +static struct ti_ssp_data ssp_config = { + .out_clock = 250 * 1000, + .dev_data = { + [1] = { + .dev_name = "ti-ssp-spi", + .pdata = &spi_master_data, + .pdata_size = sizeof(spi_master_data), + }, + }, +}; + +static struct tnetv107x_device_info evm_device_info __initconst = { + .serial_config = &serial_config, + .mmc_config[1] = &mmc_config, /* controller 1 */ + .nand_config[0] = &nand_config, /* chip select 0 */ + .keypad_config = &keypad_config, + .ssp_config = &ssp_config, +}; + +static struct spi_board_info spi_info[] __initconst = { +}; + +static __init void tnetv107x_evm_board_init(void) +{ + davinci_cfg_reg_list(sdio1_pins); + davinci_cfg_reg_list(uart1_pins); + davinci_cfg_reg_list(ssp_pins); + + tnetv107x_devices_init(&evm_device_info); + + spi_register_board_info(spi_info, ARRAY_SIZE(spi_info)); +} + +#ifdef CONFIG_SERIAL_8250_CONSOLE +static int __init tnetv107x_evm_console_init(void) +{ + return add_preferred_console("ttyS", 0, "115200"); +} +console_initcall(tnetv107x_evm_console_init); +#endif + +MACHINE_START(TNETV107X, "TNETV107X EVM") + .atag_offset = 0x100, + .map_io = tnetv107x_init, + .init_irq = cp_intc_init, + .timer = &davinci_timer, + .init_machine = tnetv107x_evm_board_init, + .dma_zone_size = SZ_128M, + .restart = tnetv107x_restart, +MACHINE_END diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/cdce949.c b/ANDROID_3.4.5/arch/arm/mach-davinci/cdce949.c new file mode 100644 index 00000000..f2232ca6 --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/cdce949.c @@ -0,0 +1,295 @@ +/* + * TI CDCE949 clock synthesizer driver + * + * Note: This implementation assumes an input of 27MHz to the CDCE. + * This is by no means constrained by CDCE hardware although the datasheet + * does use this as an example for all illustrations and more importantly: + * that is the crystal input on boards it is currently used on. + * + * Copyright (C) 2009 Texas Instruments Incorporated. http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ +#include <linux/kernel.h> +#include <linux/clk.h> +#include <linux/platform_device.h> +#include <linux/i2c.h> +#include <linux/module.h> + +#include <mach/clock.h> +#include <mach/cdce949.h> + +#include "clock.h" + +static struct i2c_client *cdce_i2c_client; +static DEFINE_MUTEX(cdce_mutex); + +/* CDCE register descriptor */ +struct cdce_reg { + u8 addr; + u8 val; +}; + +/* Per-Output (Y1, Y2 etc.) frequency descriptor */ +struct cdce_freq { + /* Frequency in KHz */ + unsigned long frequency; + /* + * List of registers to program to obtain a particular frequency. + * 0x0 in register address and value is the end of list marker. + */ + struct cdce_reg *reglist; +}; + +#define CDCE_FREQ_TABLE_ENTRY(line, out) \ +{ \ + .reglist = cdce_y ##line## _ ##out, \ + .frequency = out, \ +} + +/* List of CDCE outputs */ +struct cdce_output { + /* List of frequencies on this output */ + struct cdce_freq *freq_table; + /* Number of possible frequencies */ + int size; +}; + +/* + * Finding out the values to program into CDCE949 registers for a particular + * frequency output is not a simple calculation. Have a look at the datasheet + * for the details. There is desktop software available to help users with + * the calculations. Here, we just depend on the output of that software + * (or hand calculations) instead trying to runtime calculate the register + * values and inflicting misery on ourselves. + */ +static struct cdce_reg cdce_y1_148500[] = { + { 0x13, 0x00 }, + /* program PLL1_0 multiplier */ + { 0x18, 0xaf }, + { 0x19, 0x50 }, + { 0x1a, 0x02 }, + { 0x1b, 0xc9 }, + /* program PLL1_11 multiplier */ + { 0x1c, 0x00 }, + { 0x1d, 0x40 }, + { 0x1e, 0x02 }, + { 0x1f, 0xc9 }, + /* output state selection */ + { 0x15, 0x00 }, + { 0x14, 0xef }, + /* switch MUX to PLL1 output */ + { 0x14, 0x6f }, + { 0x16, 0x06 }, + /* set P2DIV divider, P3DIV and input crystal */ + { 0x17, 0x06 }, + { 0x01, 0x00 }, + { 0x05, 0x48 }, + { 0x02, 0x80 }, + /* enable and disable PLL */ + { 0x02, 0xbc }, + { 0x03, 0x01 }, + { }, +}; + +static struct cdce_reg cdce_y1_74250[] = { + { 0x13, 0x00 }, + { 0x18, 0xaf }, + { 0x19, 0x50 }, + { 0x1a, 0x02 }, + { 0x1b, 0xc9 }, + { 0x1c, 0x00 }, + { 0x1d, 0x40 }, + { 0x1e, 0x02 }, + { 0x1f, 0xc9 }, + /* output state selection */ + { 0x15, 0x00 }, + { 0x14, 0xef }, + /* switch MUX to PLL1 output */ + { 0x14, 0x6f }, + { 0x16, 0x06 }, + /* set P2DIV divider, P3DIV and input crystal */ + { 0x17, 0x06 }, + { 0x01, 0x00 }, + { 0x05, 0x48 }, + { 0x02, 0x80 }, + /* enable and disable PLL */ + { 0x02, 0xbc }, + { 0x03, 0x02 }, + { }, +}; + +static struct cdce_reg cdce_y1_27000[] = { + { 0x13, 0x00 }, + { 0x18, 0x00 }, + { 0x19, 0x40 }, + { 0x1a, 0x02 }, + { 0x1b, 0x08 }, + { 0x1c, 0x00 }, + { 0x1d, 0x40 }, + { 0x1e, 0x02 }, + { 0x1f, 0x08 }, + { 0x15, 0x02 }, + { 0x14, 0xed }, + { 0x16, 0x01 }, + { 0x17, 0x01 }, + { 0x01, 0x00 }, + { 0x05, 0x50 }, + { 0x02, 0xb4 }, + { 0x03, 0x01 }, + { }, +}; + +static struct cdce_freq cdce_y1_freqs[] = { + CDCE_FREQ_TABLE_ENTRY(1, 148500), + CDCE_FREQ_TABLE_ENTRY(1, 74250), + CDCE_FREQ_TABLE_ENTRY(1, 27000), +}; + +static struct cdce_reg cdce_y5_13500[] = { + { 0x27, 0x08 }, + { 0x28, 0x00 }, + { 0x29, 0x40 }, + { 0x2a, 0x02 }, + { 0x2b, 0x08 }, + { 0x24, 0x6f }, + { }, +}; + +static struct cdce_reg cdce_y5_16875[] = { + { 0x27, 0x08 }, + { 0x28, 0x9f }, + { 0x29, 0xb0 }, + { 0x2a, 0x02 }, + { 0x2b, 0x89 }, + { 0x24, 0x6f }, + { }, +}; + +static struct cdce_reg cdce_y5_27000[] = { + { 0x27, 0x04 }, + { 0x28, 0x00 }, + { 0x29, 0x40 }, + { 0x2a, 0x02 }, + { 0x2b, 0x08 }, + { 0x24, 0x6f }, + { }, +}; +static struct cdce_reg cdce_y5_54000[] = { + { 0x27, 0x04 }, + { 0x28, 0xff }, + { 0x29, 0x80 }, + { 0x2a, 0x02 }, + { 0x2b, 0x07 }, + { 0x24, 0x6f }, + { }, +}; + +static struct cdce_reg cdce_y5_81000[] = { + { 0x27, 0x02 }, + { 0x28, 0xbf }, + { 0x29, 0xa0 }, + { 0x2a, 0x03 }, + { 0x2b, 0x0a }, + { 0x24, 0x6f }, + { }, +}; + +static struct cdce_freq cdce_y5_freqs[] = { + CDCE_FREQ_TABLE_ENTRY(5, 13500), + CDCE_FREQ_TABLE_ENTRY(5, 16875), + CDCE_FREQ_TABLE_ENTRY(5, 27000), + CDCE_FREQ_TABLE_ENTRY(5, 54000), + CDCE_FREQ_TABLE_ENTRY(5, 81000), +}; + + +static struct cdce_output output_list[] = { + [1] = { cdce_y1_freqs, ARRAY_SIZE(cdce_y1_freqs) }, + [5] = { cdce_y5_freqs, ARRAY_SIZE(cdce_y5_freqs) }, +}; + +int cdce_set_rate(struct clk *clk, unsigned long rate) +{ + int i, ret = 0; + struct cdce_freq *freq_table = output_list[clk->lpsc].freq_table; + struct cdce_reg *regs = NULL; + + if (!cdce_i2c_client) + return -ENODEV; + + if (!freq_table) + return -EINVAL; + + for (i = 0; i < output_list[clk->lpsc].size; i++) { + if (freq_table[i].frequency == rate / 1000) { + regs = freq_table[i].reglist; + break; + } + } + + if (!regs) + return -EINVAL; + + mutex_lock(&cdce_mutex); + for (i = 0; regs[i].addr; i++) { + ret = i2c_smbus_write_byte_data(cdce_i2c_client, + regs[i].addr | 0x80, regs[i].val); + if (ret) + break; + } + mutex_unlock(&cdce_mutex); + + if (!ret) + clk->rate = rate; + + return ret; +} + +static int cdce_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + cdce_i2c_client = client; + return 0; +} + +static int __devexit cdce_remove(struct i2c_client *client) +{ + cdce_i2c_client = NULL; + return 0; +} + +static const struct i2c_device_id cdce_id[] = { + {"cdce949", 0}, + {}, +}; +MODULE_DEVICE_TABLE(i2c, cdce_id); + +static struct i2c_driver cdce_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "cdce949", + }, + .probe = cdce_probe, + .remove = __devexit_p(cdce_remove), + .id_table = cdce_id, +}; + +static int __init cdce_init(void) +{ + return i2c_add_driver(&cdce_driver); +} +subsys_initcall(cdce_init); + +static void __exit cdce_exit(void) +{ + i2c_del_driver(&cdce_driver); +} +module_exit(cdce_exit); + +MODULE_AUTHOR("Texas Instruments"); +MODULE_DESCRIPTION("CDCE949 clock synthesizer driver"); +MODULE_LICENSE("GPL v2"); diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/clock.c b/ANDROID_3.4.5/arch/arm/mach-davinci/clock.c new file mode 100644 index 00000000..008772e3 --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/clock.c @@ -0,0 +1,670 @@ +/* + * Clock and PLL control for DaVinci devices + * + * Copyright (C) 2006-2007 Texas Instruments. + * Copyright (C) 2008-2009 Deep Root Systems, LLC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/errno.h> +#include <linux/clk.h> +#include <linux/err.h> +#include <linux/mutex.h> +#include <linux/io.h> +#include <linux/delay.h> + +#include <mach/hardware.h> + +#include <mach/clock.h> +#include <mach/psc.h> +#include <mach/cputype.h> +#include "clock.h" + +static LIST_HEAD(clocks); +static DEFINE_MUTEX(clocks_mutex); +static DEFINE_SPINLOCK(clockfw_lock); + +static void __clk_enable(struct clk *clk) +{ + if (clk->parent) + __clk_enable(clk->parent); + if (clk->usecount++ == 0 && (clk->flags & CLK_PSC)) + davinci_psc_config(clk->domain, clk->gpsc, clk->lpsc, + true, clk->flags); +} + +static void __clk_disable(struct clk *clk) +{ + if (WARN_ON(clk->usecount == 0)) + return; + if (--clk->usecount == 0 && !(clk->flags & CLK_PLL) && + (clk->flags & CLK_PSC)) + davinci_psc_config(clk->domain, clk->gpsc, clk->lpsc, + false, clk->flags); + if (clk->parent) + __clk_disable(clk->parent); +} + +int clk_enable(struct clk *clk) +{ + unsigned long flags; + + if (clk == NULL || IS_ERR(clk)) + return -EINVAL; + + spin_lock_irqsave(&clockfw_lock, flags); + __clk_enable(clk); + spin_unlock_irqrestore(&clockfw_lock, flags); + + return 0; +} +EXPORT_SYMBOL(clk_enable); + +void clk_disable(struct clk *clk) +{ + unsigned long flags; + + if (clk == NULL || IS_ERR(clk)) + return; + + spin_lock_irqsave(&clockfw_lock, flags); + __clk_disable(clk); + spin_unlock_irqrestore(&clockfw_lock, flags); +} +EXPORT_SYMBOL(clk_disable); + +unsigned long clk_get_rate(struct clk *clk) +{ + if (clk == NULL || IS_ERR(clk)) + return -EINVAL; + + return clk->rate; +} +EXPORT_SYMBOL(clk_get_rate); + +long clk_round_rate(struct clk *clk, unsigned long rate) +{ + if (clk == NULL || IS_ERR(clk)) + return -EINVAL; + + if (clk->round_rate) + return clk->round_rate(clk, rate); + + return clk->rate; +} +EXPORT_SYMBOL(clk_round_rate); + +/* Propagate rate to children */ +static void propagate_rate(struct clk *root) +{ + struct clk *clk; + + list_for_each_entry(clk, &root->children, childnode) { + if (clk->recalc) + clk->rate = clk->recalc(clk); + propagate_rate(clk); + } +} + +int clk_set_rate(struct clk *clk, unsigned long rate) +{ + unsigned long flags; + int ret = -EINVAL; + + if (clk == NULL || IS_ERR(clk)) + return ret; + + if (clk->set_rate) + ret = clk->set_rate(clk, rate); + + spin_lock_irqsave(&clockfw_lock, flags); + if (ret == 0) { + if (clk->recalc) + clk->rate = clk->recalc(clk); + propagate_rate(clk); + } + spin_unlock_irqrestore(&clockfw_lock, flags); + + return ret; +} +EXPORT_SYMBOL(clk_set_rate); + +int clk_set_parent(struct clk *clk, struct clk *parent) +{ + unsigned long flags; + + if (clk == NULL || IS_ERR(clk)) + return -EINVAL; + + /* Cannot change parent on enabled clock */ + if (WARN_ON(clk->usecount)) + return -EINVAL; + + mutex_lock(&clocks_mutex); + clk->parent = parent; + list_del_init(&clk->childnode); + list_add(&clk->childnode, &clk->parent->children); + mutex_unlock(&clocks_mutex); + + spin_lock_irqsave(&clockfw_lock, flags); + if (clk->recalc) + clk->rate = clk->recalc(clk); + propagate_rate(clk); + spin_unlock_irqrestore(&clockfw_lock, flags); + + return 0; +} +EXPORT_SYMBOL(clk_set_parent); + +int clk_register(struct clk *clk) +{ + if (clk == NULL || IS_ERR(clk)) + return -EINVAL; + + if (WARN(clk->parent && !clk->parent->rate, + "CLK: %s parent %s has no rate!\n", + clk->name, clk->parent->name)) + return -EINVAL; + + INIT_LIST_HEAD(&clk->children); + + mutex_lock(&clocks_mutex); + list_add_tail(&clk->node, &clocks); + if (clk->parent) + list_add_tail(&clk->childnode, &clk->parent->children); + mutex_unlock(&clocks_mutex); + + /* If rate is already set, use it */ + if (clk->rate) + return 0; + + /* Else, see if there is a way to calculate it */ + if (clk->recalc) + clk->rate = clk->recalc(clk); + + /* Otherwise, default to parent rate */ + else if (clk->parent) + clk->rate = clk->parent->rate; + + return 0; +} +EXPORT_SYMBOL(clk_register); + +void clk_unregister(struct clk *clk) +{ + if (clk == NULL || IS_ERR(clk)) + return; + + mutex_lock(&clocks_mutex); + list_del(&clk->node); + list_del(&clk->childnode); + mutex_unlock(&clocks_mutex); +} +EXPORT_SYMBOL(clk_unregister); + +#ifdef CONFIG_DAVINCI_RESET_CLOCKS +/* + * Disable any unused clocks left on by the bootloader + */ +static int __init clk_disable_unused(void) +{ + struct clk *ck; + + spin_lock_irq(&clockfw_lock); + list_for_each_entry(ck, &clocks, node) { + if (ck->usecount > 0) + continue; + if (!(ck->flags & CLK_PSC)) + continue; + + /* ignore if in Disabled or SwRstDisable states */ + if (!davinci_psc_is_clk_active(ck->gpsc, ck->lpsc)) + continue; + + pr_debug("Clocks: disable unused %s\n", ck->name); + + davinci_psc_config(ck->domain, ck->gpsc, ck->lpsc, + false, ck->flags); + } + spin_unlock_irq(&clockfw_lock); + + return 0; +} +late_initcall(clk_disable_unused); +#endif + +static unsigned long clk_sysclk_recalc(struct clk *clk) +{ + u32 v, plldiv; + struct pll_data *pll; + unsigned long rate = clk->rate; + + /* If this is the PLL base clock, no more calculations needed */ + if (clk->pll_data) + return rate; + + if (WARN_ON(!clk->parent)) + return rate; + + rate = clk->parent->rate; + + /* Otherwise, the parent must be a PLL */ + if (WARN_ON(!clk->parent->pll_data)) + return rate; + + pll = clk->parent->pll_data; + + /* If pre-PLL, source clock is before the multiplier and divider(s) */ + if (clk->flags & PRE_PLL) + rate = pll->input_rate; + + if (!clk->div_reg) + return rate; + + v = __raw_readl(pll->base + clk->div_reg); + if (v & PLLDIV_EN) { + plldiv = (v & pll->div_ratio_mask) + 1; + if (plldiv) + rate /= plldiv; + } + + return rate; +} + +int davinci_set_sysclk_rate(struct clk *clk, unsigned long rate) +{ + unsigned v; + struct pll_data *pll; + unsigned long input; + unsigned ratio = 0; + + /* If this is the PLL base clock, wrong function to call */ + if (clk->pll_data) + return -EINVAL; + + /* There must be a parent... */ + if (WARN_ON(!clk->parent)) + return -EINVAL; + + /* ... the parent must be a PLL... */ + if (WARN_ON(!clk->parent->pll_data)) + return -EINVAL; + + /* ... and this clock must have a divider. */ + if (WARN_ON(!clk->div_reg)) + return -EINVAL; + + pll = clk->parent->pll_data; + + input = clk->parent->rate; + + /* If pre-PLL, source clock is before the multiplier and divider(s) */ + if (clk->flags & PRE_PLL) + input = pll->input_rate; + + if (input > rate) { + /* + * Can afford to provide an output little higher than requested + * only if maximum rate supported by hardware on this sysclk + * is known. + */ + if (clk->maxrate) { + ratio = DIV_ROUND_CLOSEST(input, rate); + if (input / ratio > clk->maxrate) + ratio = 0; + } + + if (ratio == 0) + ratio = DIV_ROUND_UP(input, rate); + + ratio--; + } + + if (ratio > pll->div_ratio_mask) + return -EINVAL; + + do { + v = __raw_readl(pll->base + PLLSTAT); + } while (v & PLLSTAT_GOSTAT); + + v = __raw_readl(pll->base + clk->div_reg); + v &= ~pll->div_ratio_mask; + v |= ratio | PLLDIV_EN; + __raw_writel(v, pll->base + clk->div_reg); + + v = __raw_readl(pll->base + PLLCMD); + v |= PLLCMD_GOSET; + __raw_writel(v, pll->base + PLLCMD); + + do { + v = __raw_readl(pll->base + PLLSTAT); + } while (v & PLLSTAT_GOSTAT); + + return 0; +} +EXPORT_SYMBOL(davinci_set_sysclk_rate); + +static unsigned long clk_leafclk_recalc(struct clk *clk) +{ + if (WARN_ON(!clk->parent)) + return clk->rate; + + return clk->parent->rate; +} + +int davinci_simple_set_rate(struct clk *clk, unsigned long rate) +{ + clk->rate = rate; + return 0; +} + +static unsigned long clk_pllclk_recalc(struct clk *clk) +{ + u32 ctrl, mult = 1, prediv = 1, postdiv = 1; + u8 bypass; + struct pll_data *pll = clk->pll_data; + unsigned long rate = clk->rate; + + ctrl = __raw_readl(pll->base + PLLCTL); + rate = pll->input_rate = clk->parent->rate; + + if (ctrl & PLLCTL_PLLEN) { + bypass = 0; + mult = __raw_readl(pll->base + PLLM); + if (cpu_is_davinci_dm365()) + mult = 2 * (mult & PLLM_PLLM_MASK); + else + mult = (mult & PLLM_PLLM_MASK) + 1; + } else + bypass = 1; + + if (pll->flags & PLL_HAS_PREDIV) { + prediv = __raw_readl(pll->base + PREDIV); + if (prediv & PLLDIV_EN) + prediv = (prediv & pll->div_ratio_mask) + 1; + else + prediv = 1; + } + + /* pre-divider is fixed, but (some?) chips won't report that */ + if (cpu_is_davinci_dm355() && pll->num == 1) + prediv = 8; + + if (pll->flags & PLL_HAS_POSTDIV) { + postdiv = __raw_readl(pll->base + POSTDIV); + if (postdiv & PLLDIV_EN) + postdiv = (postdiv & pll->div_ratio_mask) + 1; + else + postdiv = 1; + } + + if (!bypass) { + rate /= prediv; + rate *= mult; + rate /= postdiv; + } + + pr_debug("PLL%d: input = %lu MHz [ ", + pll->num, clk->parent->rate / 1000000); + if (bypass) + pr_debug("bypass "); + if (prediv > 1) + pr_debug("/ %d ", prediv); + if (mult > 1) + pr_debug("* %d ", mult); + if (postdiv > 1) + pr_debug("/ %d ", postdiv); + pr_debug("] --> %lu MHz output.\n", rate / 1000000); + + return rate; +} + +/** + * davinci_set_pllrate - set the output rate of a given PLL. + * + * Note: Currently tested to work with OMAP-L138 only. + * + * @pll: pll whose rate needs to be changed. + * @prediv: The pre divider value. Passing 0 disables the pre-divider. + * @pllm: The multiplier value. Passing 0 leads to multiply-by-one. + * @postdiv: The post divider value. Passing 0 disables the post-divider. + */ +int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv, + unsigned int mult, unsigned int postdiv) +{ + u32 ctrl; + unsigned int locktime; + unsigned long flags; + + if (pll->base == NULL) + return -EINVAL; + + /* + * PLL lock time required per OMAP-L138 datasheet is + * (2000 * prediv)/sqrt(pllm) OSCIN cycles. We approximate sqrt(pllm) + * as 4 and OSCIN cycle as 25 MHz. + */ + if (prediv) { + locktime = ((2000 * prediv) / 100); + prediv = (prediv - 1) | PLLDIV_EN; + } else { + locktime = PLL_LOCK_TIME; + } + if (postdiv) + postdiv = (postdiv - 1) | PLLDIV_EN; + if (mult) + mult = mult - 1; + + /* Protect against simultaneous calls to PLL setting seqeunce */ + spin_lock_irqsave(&clockfw_lock, flags); + + ctrl = __raw_readl(pll->base + PLLCTL); + + /* Switch the PLL to bypass mode */ + ctrl &= ~(PLLCTL_PLLENSRC | PLLCTL_PLLEN); + __raw_writel(ctrl, pll->base + PLLCTL); + + udelay(PLL_BYPASS_TIME); + + /* Reset and enable PLL */ + ctrl &= ~(PLLCTL_PLLRST | PLLCTL_PLLDIS); + __raw_writel(ctrl, pll->base + PLLCTL); + + if (pll->flags & PLL_HAS_PREDIV) + __raw_writel(prediv, pll->base + PREDIV); + + __raw_writel(mult, pll->base + PLLM); + + if (pll->flags & PLL_HAS_POSTDIV) + __raw_writel(postdiv, pll->base + POSTDIV); + + udelay(PLL_RESET_TIME); + + /* Bring PLL out of reset */ + ctrl |= PLLCTL_PLLRST; + __raw_writel(ctrl, pll->base + PLLCTL); + + udelay(locktime); + + /* Remove PLL from bypass mode */ + ctrl |= PLLCTL_PLLEN; + __raw_writel(ctrl, pll->base + PLLCTL); + + spin_unlock_irqrestore(&clockfw_lock, flags); + + return 0; +} +EXPORT_SYMBOL(davinci_set_pllrate); + +/** + * davinci_set_refclk_rate() - Set the reference clock rate + * @rate: The new rate. + * + * Sets the reference clock rate to a given value. This will most likely + * result in the entire clock tree getting updated. + * + * This is used to support boards which use a reference clock different + * than that used by default in <soc>.c file. The reference clock rate + * should be updated early in the boot process; ideally soon after the + * clock tree has been initialized once with the default reference clock + * rate (davinci_common_init()). + * + * Returns 0 on success, error otherwise. + */ +int davinci_set_refclk_rate(unsigned long rate) +{ + struct clk *refclk; + + refclk = clk_get(NULL, "ref"); + if (IS_ERR(refclk)) { + pr_err("%s: failed to get reference clock.\n", __func__); + return PTR_ERR(refclk); + } + + clk_set_rate(refclk, rate); + + clk_put(refclk); + + return 0; +} + +int __init davinci_clk_init(struct clk_lookup *clocks) + { + struct clk_lookup *c; + struct clk *clk; + size_t num_clocks = 0; + + for (c = clocks; c->clk; c++) { + clk = c->clk; + + if (!clk->recalc) { + + /* Check if clock is a PLL */ + if (clk->pll_data) + clk->recalc = clk_pllclk_recalc; + + /* Else, if it is a PLL-derived clock */ + else if (clk->flags & CLK_PLL) + clk->recalc = clk_sysclk_recalc; + + /* Otherwise, it is a leaf clock (PSC clock) */ + else if (clk->parent) + clk->recalc = clk_leafclk_recalc; + } + + if (clk->pll_data) { + struct pll_data *pll = clk->pll_data; + + if (!pll->div_ratio_mask) + pll->div_ratio_mask = PLLDIV_RATIO_MASK; + + if (pll->phys_base && !pll->base) { + pll->base = ioremap(pll->phys_base, SZ_4K); + WARN_ON(!pll->base); + } + } + + if (clk->recalc) + clk->rate = clk->recalc(clk); + + if (clk->lpsc) + clk->flags |= CLK_PSC; + + clk_register(clk); + num_clocks++; + + /* Turn on clocks that Linux doesn't otherwise manage */ + if (clk->flags & ALWAYS_ENABLED) + clk_enable(clk); + } + + clkdev_add_table(clocks, num_clocks); + + return 0; +} + +#ifdef CONFIG_DEBUG_FS + +#include <linux/debugfs.h> +#include <linux/seq_file.h> + +#define CLKNAME_MAX 10 /* longest clock name */ +#define NEST_DELTA 2 +#define NEST_MAX 4 + +static void +dump_clock(struct seq_file *s, unsigned nest, struct clk *parent) +{ + char *state; + char buf[CLKNAME_MAX + NEST_DELTA * NEST_MAX]; + struct clk *clk; + unsigned i; + + if (parent->flags & CLK_PLL) + state = "pll"; + else if (parent->flags & CLK_PSC) + state = "psc"; + else + state = ""; + + /* <nest spaces> name <pad to end> */ + memset(buf, ' ', sizeof(buf) - 1); + buf[sizeof(buf) - 1] = 0; + i = strlen(parent->name); + memcpy(buf + nest, parent->name, + min(i, (unsigned)(sizeof(buf) - 1 - nest))); + + seq_printf(s, "%s users=%2d %-3s %9ld Hz\n", + buf, parent->usecount, state, clk_get_rate(parent)); + /* REVISIT show device associations too */ + + /* cost is now small, but not linear... */ + list_for_each_entry(clk, &parent->children, childnode) { + dump_clock(s, nest + NEST_DELTA, clk); + } +} + +static int davinci_ck_show(struct seq_file *m, void *v) +{ + struct clk *clk; + + /* + * Show clock tree; We trust nonzero usecounts equate to PSC enables... + */ + mutex_lock(&clocks_mutex); + list_for_each_entry(clk, &clocks, node) + if (!clk->parent) + dump_clock(m, 0, clk); + mutex_unlock(&clocks_mutex); + + return 0; +} + +static int davinci_ck_open(struct inode *inode, struct file *file) +{ + return single_open(file, davinci_ck_show, NULL); +} + +static const struct file_operations davinci_ck_operations = { + .open = davinci_ck_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int __init davinci_clk_debugfs_init(void) +{ + debugfs_create_file("davinci_clocks", S_IFREG | S_IRUGO, NULL, NULL, + &davinci_ck_operations); + return 0; + +} +device_initcall(davinci_clk_debugfs_init); +#endif /* CONFIG_DEBUG_FS */ diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/clock.h b/ANDROID_3.4.5/arch/arm/mach-davinci/clock.h new file mode 100644 index 00000000..46f0f1bf --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/clock.h @@ -0,0 +1,135 @@ +/* + * TI DaVinci clock definitions + * + * Copyright (C) 2006-2007 Texas Instruments. + * Copyright (C) 2008-2009 Deep Root Systems, LLC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ARCH_ARM_DAVINCI_CLOCK_H +#define __ARCH_ARM_DAVINCI_CLOCK_H + +#define DAVINCI_PLL1_BASE 0x01c40800 +#define DAVINCI_PLL2_BASE 0x01c40c00 +#define MAX_PLL 2 + +/* PLL/Reset register offsets */ +#define PLLCTL 0x100 +#define PLLCTL_PLLEN BIT(0) +#define PLLCTL_PLLPWRDN BIT(1) +#define PLLCTL_PLLRST BIT(3) +#define PLLCTL_PLLDIS BIT(4) +#define PLLCTL_PLLENSRC BIT(5) +#define PLLCTL_CLKMODE BIT(8) + +#define PLLM 0x110 +#define PLLM_PLLM_MASK 0xff + +#define PREDIV 0x114 +#define PLLDIV1 0x118 +#define PLLDIV2 0x11c +#define PLLDIV3 0x120 +#define POSTDIV 0x128 +#define BPDIV 0x12c +#define PLLCMD 0x138 +#define PLLSTAT 0x13c +#define PLLALNCTL 0x140 +#define PLLDCHANGE 0x144 +#define PLLCKEN 0x148 +#define PLLCKSTAT 0x14c +#define PLLSYSTAT 0x150 +#define PLLDIV4 0x160 +#define PLLDIV5 0x164 +#define PLLDIV6 0x168 +#define PLLDIV7 0x16c +#define PLLDIV8 0x170 +#define PLLDIV9 0x174 +#define PLLDIV_EN BIT(15) +#define PLLDIV_RATIO_MASK 0x1f + +/* + * OMAP-L138 system reference guide recommends a wait for 4 OSCIN/CLKIN + * cycles to ensure that the PLLC has switched to bypass mode. Delay of 1us + * ensures we are good for all > 4MHz OSCIN/CLKIN inputs. Typically the input + * is ~25MHz. Units are micro seconds. + */ +#define PLL_BYPASS_TIME 1 +/* From OMAP-L138 datasheet table 6-4. Units are micro seconds */ +#define PLL_RESET_TIME 1 +/* + * From OMAP-L138 datasheet table 6-4; assuming prediv = 1, sqrt(pllm) = 4 + * Units are micro seconds. + */ +#define PLL_LOCK_TIME 20 + +#ifndef __ASSEMBLER__ + +#include <linux/list.h> +#include <linux/clkdev.h> + +#define PLLSTAT_GOSTAT BIT(0) +#define PLLCMD_GOSET BIT(0) + +struct pll_data { + u32 phys_base; + void __iomem *base; + u32 num; + u32 flags; + u32 input_rate; + u32 div_ratio_mask; +}; +#define PLL_HAS_PREDIV 0x01 +#define PLL_HAS_POSTDIV 0x02 + +struct clk { + struct list_head node; + struct module *owner; + const char *name; + unsigned long rate; + unsigned long maxrate; /* H/W supported max rate */ + u8 usecount; + u8 lpsc; + u8 gpsc; + u8 domain; + u32 flags; + struct clk *parent; + struct list_head children; /* list of children */ + struct list_head childnode; /* parent's child list node */ + struct pll_data *pll_data; + u32 div_reg; + unsigned long (*recalc) (struct clk *); + int (*set_rate) (struct clk *clk, unsigned long rate); + int (*round_rate) (struct clk *clk, unsigned long rate); +}; + +/* Clock flags: SoC-specific flags start at BIT(16) */ +#define ALWAYS_ENABLED BIT(1) +#define CLK_PSC BIT(2) +#define CLK_PLL BIT(3) /* PLL-derived clock */ +#define PRE_PLL BIT(4) /* source is before PLL mult/div */ +#define PSC_SWRSTDISABLE BIT(5) /* Disable state is SwRstDisable */ +#define PSC_FORCE BIT(6) /* Force module state transtition */ + +#define CLK(dev, con, ck) \ + { \ + .dev_id = dev, \ + .con_id = con, \ + .clk = ck, \ + } \ + +int davinci_clk_init(struct clk_lookup *clocks); +int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv, + unsigned int mult, unsigned int postdiv); +int davinci_set_sysclk_rate(struct clk *clk, unsigned long rate); +int davinci_set_refclk_rate(unsigned long rate); +int davinci_simple_set_rate(struct clk *clk, unsigned long rate); + +extern struct platform_device davinci_wdt_device; +extern void davinci_watchdog_reset(struct platform_device *); + +#endif + +#endif diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/common.c b/ANDROID_3.4.5/arch/arm/mach-davinci/common.c new file mode 100644 index 00000000..cb9b2e47 --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/common.c @@ -0,0 +1,119 @@ +/* + * Code commons to all DaVinci SoCs. + * + * Author: Mark A. Greer <mgreer@mvista.com> + * + * 2009 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ +#include <linux/module.h> +#include <linux/io.h> +#include <linux/etherdevice.h> +#include <linux/davinci_emac.h> +#include <linux/dma-mapping.h> + +#include <asm/tlb.h> +#include <asm/mach/map.h> + +#include <mach/common.h> +#include <mach/cputype.h> + +#include "clock.h" + +struct davinci_soc_info davinci_soc_info; +EXPORT_SYMBOL(davinci_soc_info); + +void __iomem *davinci_intc_base; +int davinci_intc_type; + +void davinci_get_mac_addr(struct memory_accessor *mem_acc, void *context) +{ + char *mac_addr = davinci_soc_info.emac_pdata->mac_addr; + off_t offset = (off_t)context; + + /* Read MAC addr from EEPROM */ + if (mem_acc->read(mem_acc, mac_addr, offset, ETH_ALEN) == ETH_ALEN) + pr_info("Read MAC addr from EEPROM: %pM\n", mac_addr); +} + +static int __init davinci_init_id(struct davinci_soc_info *soc_info) +{ + int i; + struct davinci_id *dip; + u8 variant; + u16 part_no; + void __iomem *base; + + base = ioremap(soc_info->jtag_id_reg, SZ_4K); + if (!base) { + pr_err("Unable to map JTAG ID register\n"); + return -ENOMEM; + } + + soc_info->jtag_id = __raw_readl(base); + iounmap(base); + + variant = (soc_info->jtag_id & 0xf0000000) >> 28; + part_no = (soc_info->jtag_id & 0x0ffff000) >> 12; + + for (i = 0, dip = soc_info->ids; i < soc_info->ids_num; + i++, dip++) + /* Don't care about the manufacturer right now */ + if ((dip->part_no == part_no) && (dip->variant == variant)) { + soc_info->cpu_id = dip->cpu_id; + pr_info("DaVinci %s variant 0x%x\n", dip->name, + dip->variant); + return 0; + } + + pr_err("Unknown DaVinci JTAG ID 0x%x\n", soc_info->jtag_id); + return -EINVAL; +} + +void __init davinci_common_init(struct davinci_soc_info *soc_info) +{ + int ret; + + if (!soc_info) { + ret = -EINVAL; + goto err; + } + + memcpy(&davinci_soc_info, soc_info, sizeof(struct davinci_soc_info)); + + if (davinci_soc_info.io_desc && (davinci_soc_info.io_desc_num > 0)) + iotable_init(davinci_soc_info.io_desc, + davinci_soc_info.io_desc_num); + + init_consistent_dma_size(14 << 20); + + /* + * Normally devicemaps_init() would flush caches and tlb after + * mdesc->map_io(), but we must also do it here because of the CPU + * revision check below. + */ + local_flush_tlb_all(); + flush_cache_all(); + + /* + * We want to check CPU revision early for cpu_is_xxxx() macros. + * IO space mapping must be initialized before we can do that. + */ + ret = davinci_init_id(&davinci_soc_info); + if (ret < 0) + goto err; + + if (davinci_soc_info.cpu_clks) { + ret = davinci_clk_init(davinci_soc_info.cpu_clks); + + if (ret != 0) + goto err; + } + + return; + +err: + panic("davinci_common_init: SoC Initialization failed\n"); +} diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/cp_intc.c b/ANDROID_3.4.5/arch/arm/mach-davinci/cp_intc.c new file mode 100644 index 00000000..f83152d6 --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/cp_intc.c @@ -0,0 +1,177 @@ +/* + * TI Common Platform Interrupt Controller (cp_intc) driver + * + * Author: Steve Chen <schen@mvista.com> + * Copyright (C) 2008-2009, MontaVista Software, Inc. <source@mvista.com> + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#include <linux/init.h> +#include <linux/irq.h> +#include <linux/io.h> + +#include <mach/common.h> +#include <mach/cp_intc.h> + +static inline unsigned int cp_intc_read(unsigned offset) +{ + return __raw_readl(davinci_intc_base + offset); +} + +static inline void cp_intc_write(unsigned long value, unsigned offset) +{ + __raw_writel(value, davinci_intc_base + offset); +} + +static void cp_intc_ack_irq(struct irq_data *d) +{ + cp_intc_write(d->irq, CP_INTC_SYS_STAT_IDX_CLR); +} + +/* Disable interrupt */ +static void cp_intc_mask_irq(struct irq_data *d) +{ + /* XXX don't know why we need to disable nIRQ here... */ + cp_intc_write(1, CP_INTC_HOST_ENABLE_IDX_CLR); + cp_intc_write(d->irq, CP_INTC_SYS_ENABLE_IDX_CLR); + cp_intc_write(1, CP_INTC_HOST_ENABLE_IDX_SET); +} + +/* Enable interrupt */ +static void cp_intc_unmask_irq(struct irq_data *d) +{ + cp_intc_write(d->irq, CP_INTC_SYS_ENABLE_IDX_SET); +} + +static int cp_intc_set_irq_type(struct irq_data *d, unsigned int flow_type) +{ + unsigned reg = BIT_WORD(d->irq); + unsigned mask = BIT_MASK(d->irq); + unsigned polarity = cp_intc_read(CP_INTC_SYS_POLARITY(reg)); + unsigned type = cp_intc_read(CP_INTC_SYS_TYPE(reg)); + + switch (flow_type) { + case IRQ_TYPE_EDGE_RISING: + polarity |= mask; + type |= mask; + break; + case IRQ_TYPE_EDGE_FALLING: + polarity &= ~mask; + type |= mask; + break; + case IRQ_TYPE_LEVEL_HIGH: + polarity |= mask; + type &= ~mask; + break; + case IRQ_TYPE_LEVEL_LOW: + polarity &= ~mask; + type &= ~mask; + break; + default: + return -EINVAL; + } + + cp_intc_write(polarity, CP_INTC_SYS_POLARITY(reg)); + cp_intc_write(type, CP_INTC_SYS_TYPE(reg)); + + return 0; +} + +/* + * Faking this allows us to to work with suspend functions of + * generic drivers which call {enable|disable}_irq_wake for + * wake up interrupt sources (eg RTC on DA850). + */ +static int cp_intc_set_wake(struct irq_data *d, unsigned int on) +{ + return 0; +} + +static struct irq_chip cp_intc_irq_chip = { + .name = "cp_intc", + .irq_ack = cp_intc_ack_irq, + .irq_mask = cp_intc_mask_irq, + .irq_unmask = cp_intc_unmask_irq, + .irq_set_type = cp_intc_set_irq_type, + .irq_set_wake = cp_intc_set_wake, +}; + +void __init cp_intc_init(void) +{ + unsigned long num_irq = davinci_soc_info.intc_irq_num; + u8 *irq_prio = davinci_soc_info.intc_irq_prios; + u32 *host_map = davinci_soc_info.intc_host_map; + unsigned num_reg = BITS_TO_LONGS(num_irq); + int i; + + davinci_intc_type = DAVINCI_INTC_TYPE_CP_INTC; + davinci_intc_base = ioremap(davinci_soc_info.intc_base, SZ_8K); + if (WARN_ON(!davinci_intc_base)) + return; + + cp_intc_write(0, CP_INTC_GLOBAL_ENABLE); + + /* Disable all host interrupts */ + cp_intc_write(0, CP_INTC_HOST_ENABLE(0)); + + /* Disable system interrupts */ + for (i = 0; i < num_reg; i++) + cp_intc_write(~0, CP_INTC_SYS_ENABLE_CLR(i)); + + /* Set to normal mode, no nesting, no priority hold */ + cp_intc_write(0, CP_INTC_CTRL); + cp_intc_write(0, CP_INTC_HOST_CTRL); + + /* Clear system interrupt status */ + for (i = 0; i < num_reg; i++) + cp_intc_write(~0, CP_INTC_SYS_STAT_CLR(i)); + + /* Enable nIRQ (what about nFIQ?) */ + cp_intc_write(1, CP_INTC_HOST_ENABLE_IDX_SET); + + /* + * Priority is determined by host channel: lower channel number has + * higher priority i.e. channel 0 has highest priority and channel 31 + * had the lowest priority. + */ + num_reg = (num_irq + 3) >> 2; /* 4 channels per register */ + if (irq_prio) { + unsigned j, k; + u32 val; + + for (k = i = 0; i < num_reg; i++) { + for (val = j = 0; j < 4; j++, k++) { + val >>= 8; + if (k < num_irq) + val |= irq_prio[k] << 24; + } + + cp_intc_write(val, CP_INTC_CHAN_MAP(i)); + } + } else { + /* + * Default everything to channel 15 if priority not specified. + * Note that channel 0-1 are mapped to nFIQ and channels 2-31 + * are mapped to nIRQ. + */ + for (i = 0; i < num_reg; i++) + cp_intc_write(0x0f0f0f0f, CP_INTC_CHAN_MAP(i)); + } + + if (host_map) + for (i = 0; host_map[i] != -1; i++) + cp_intc_write(host_map[i], CP_INTC_HOST_MAP(i)); + + /* Set up genirq dispatching for cp_intc */ + for (i = 0; i < num_irq; i++) { + irq_set_chip(i, &cp_intc_irq_chip); + set_irq_flags(i, IRQF_VALID | IRQF_PROBE); + irq_set_handler(i, handle_edge_irq); + } + + /* Enable global interrupt */ + cp_intc_write(1, CP_INTC_GLOBAL_ENABLE); +} diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/cpufreq.c b/ANDROID_3.4.5/arch/arm/mach-davinci/cpufreq.c new file mode 100644 index 00000000..031048fe --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/cpufreq.c @@ -0,0 +1,249 @@ +/* + * CPU frequency scaling for DaVinci + * + * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ + * + * Based on linux/arch/arm/plat-omap/cpu-omap.c. Original Copyright follows: + * + * Copyright (C) 2005 Nokia Corporation + * Written by Tony Lindgren <tony@atomide.com> + * + * Based on cpu-sa1110.c, Copyright (C) 2001 Russell King + * + * Copyright (C) 2007-2008 Texas Instruments, Inc. + * Updated to support OMAP3 + * Rajendra Nayak <rnayak@ti.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/types.h> +#include <linux/cpufreq.h> +#include <linux/init.h> +#include <linux/err.h> +#include <linux/clk.h> +#include <linux/platform_device.h> +#include <linux/export.h> + +#include <mach/hardware.h> +#include <mach/cpufreq.h> +#include <mach/common.h> + +#include "clock.h" + +struct davinci_cpufreq { + struct device *dev; + struct clk *armclk; + struct clk *asyncclk; + unsigned long asyncrate; +}; +static struct davinci_cpufreq cpufreq; + +static int davinci_verify_speed(struct cpufreq_policy *policy) +{ + struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data; + struct cpufreq_frequency_table *freq_table = pdata->freq_table; + struct clk *armclk = cpufreq.armclk; + + if (freq_table) + return cpufreq_frequency_table_verify(policy, freq_table); + + if (policy->cpu) + return -EINVAL; + + cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, + policy->cpuinfo.max_freq); + + policy->min = clk_round_rate(armclk, policy->min * 1000) / 1000; + policy->max = clk_round_rate(armclk, policy->max * 1000) / 1000; + cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, + policy->cpuinfo.max_freq); + return 0; +} + +static unsigned int davinci_getspeed(unsigned int cpu) +{ + if (cpu) + return 0; + + return clk_get_rate(cpufreq.armclk) / 1000; +} + +static int davinci_target(struct cpufreq_policy *policy, + unsigned int target_freq, unsigned int relation) +{ + int ret = 0; + unsigned int idx; + struct cpufreq_freqs freqs; + struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data; + struct clk *armclk = cpufreq.armclk; + + /* + * Ensure desired rate is within allowed range. Some govenors + * (ondemand) will just pass target_freq=0 to get the minimum. + */ + if (target_freq < policy->cpuinfo.min_freq) + target_freq = policy->cpuinfo.min_freq; + if (target_freq > policy->cpuinfo.max_freq) + target_freq = policy->cpuinfo.max_freq; + + freqs.old = davinci_getspeed(0); + freqs.new = clk_round_rate(armclk, target_freq * 1000) / 1000; + freqs.cpu = 0; + + if (freqs.old == freqs.new) + return ret; + + dev_dbg(cpufreq.dev, "transition: %u --> %u\n", freqs.old, freqs.new); + + ret = cpufreq_frequency_table_target(policy, pdata->freq_table, + freqs.new, relation, &idx); + if (ret) + return -EINVAL; + + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + + /* if moving to higher frequency, up the voltage beforehand */ + if (pdata->set_voltage && freqs.new > freqs.old) { + ret = pdata->set_voltage(idx); + if (ret) + goto out; + } + + ret = clk_set_rate(armclk, idx); + if (ret) + goto out; + + if (cpufreq.asyncclk) { + ret = clk_set_rate(cpufreq.asyncclk, cpufreq.asyncrate); + if (ret) + goto out; + } + + /* if moving to lower freq, lower the voltage after lowering freq */ + if (pdata->set_voltage && freqs.new < freqs.old) + pdata->set_voltage(idx); + +out: + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); + + return ret; +} + +static int davinci_cpu_init(struct cpufreq_policy *policy) +{ + int result = 0; + struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data; + struct cpufreq_frequency_table *freq_table = pdata->freq_table; + + if (policy->cpu != 0) + return -EINVAL; + + /* Finish platform specific initialization */ + if (pdata->init) { + result = pdata->init(); + if (result) + return result; + } + + policy->cur = policy->min = policy->max = davinci_getspeed(0); + + if (freq_table) { + result = cpufreq_frequency_table_cpuinfo(policy, freq_table); + if (!result) + cpufreq_frequency_table_get_attr(freq_table, + policy->cpu); + } else { + policy->cpuinfo.min_freq = policy->min; + policy->cpuinfo.max_freq = policy->max; + } + + policy->min = policy->cpuinfo.min_freq; + policy->max = policy->cpuinfo.max_freq; + policy->cur = davinci_getspeed(0); + + /* + * Time measurement across the target() function yields ~1500-1800us + * time taken with no drivers on notification list. + * Setting the latency to 2000 us to accommodate addition of drivers + * to pre/post change notification list. + */ + policy->cpuinfo.transition_latency = 2000 * 1000; + return 0; +} + +static int davinci_cpu_exit(struct cpufreq_policy *policy) +{ + cpufreq_frequency_table_put_attr(policy->cpu); + return 0; +} + +static struct freq_attr *davinci_cpufreq_attr[] = { + &cpufreq_freq_attr_scaling_available_freqs, + NULL, +}; + +static struct cpufreq_driver davinci_driver = { + .flags = CPUFREQ_STICKY, + .verify = davinci_verify_speed, + .target = davinci_target, + .get = davinci_getspeed, + .init = davinci_cpu_init, + .exit = davinci_cpu_exit, + .name = "davinci", + .attr = davinci_cpufreq_attr, +}; + +static int __init davinci_cpufreq_probe(struct platform_device *pdev) +{ + struct davinci_cpufreq_config *pdata = pdev->dev.platform_data; + struct clk *asyncclk; + + if (!pdata) + return -EINVAL; + if (!pdata->freq_table) + return -EINVAL; + + cpufreq.dev = &pdev->dev; + + cpufreq.armclk = clk_get(NULL, "arm"); + if (IS_ERR(cpufreq.armclk)) { + dev_err(cpufreq.dev, "Unable to get ARM clock\n"); + return PTR_ERR(cpufreq.armclk); + } + + asyncclk = clk_get(cpufreq.dev, "async"); + if (!IS_ERR(asyncclk)) { + cpufreq.asyncclk = asyncclk; + cpufreq.asyncrate = clk_get_rate(asyncclk); + } + + return cpufreq_register_driver(&davinci_driver); +} + +static int __exit davinci_cpufreq_remove(struct platform_device *pdev) +{ + clk_put(cpufreq.armclk); + + if (cpufreq.asyncclk) + clk_put(cpufreq.asyncclk); + + return cpufreq_unregister_driver(&davinci_driver); +} + +static struct platform_driver davinci_cpufreq_driver = { + .driver = { + .name = "cpufreq-davinci", + .owner = THIS_MODULE, + }, + .remove = __exit_p(davinci_cpufreq_remove), +}; + +static int __init davinci_cpufreq_init(void) +{ + return platform_driver_probe(&davinci_cpufreq_driver, + davinci_cpufreq_probe); +} +late_initcall(davinci_cpufreq_init); + diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/cpuidle.c b/ANDROID_3.4.5/arch/arm/mach-davinci/cpuidle.c new file mode 100644 index 00000000..9107691a --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/cpuidle.c @@ -0,0 +1,162 @@ +/* + * CPU idle for DaVinci SoCs + * + * Copyright (C) 2009 Texas Instruments Incorporated. http://www.ti.com/ + * + * Derived from Marvell Kirkwood CPU idle code + * (arch/arm/mach-kirkwood/cpuidle.c) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/cpuidle.h> +#include <linux/io.h> +#include <linux/export.h> +#include <asm/proc-fns.h> +#include <asm/cpuidle.h> + +#include <mach/cpuidle.h> +#include <mach/ddr2.h> + +#define DAVINCI_CPUIDLE_MAX_STATES 2 + +struct davinci_ops { + void (*enter) (u32 flags); + void (*exit) (u32 flags); + u32 flags; +}; + +/* Actual code that puts the SoC in different idle states */ +static int davinci_enter_idle(struct cpuidle_device *dev, + struct cpuidle_driver *drv, + int index) +{ + struct cpuidle_state_usage *state_usage = &dev->states_usage[index]; + struct davinci_ops *ops = cpuidle_get_statedata(state_usage); + + if (ops && ops->enter) + ops->enter(ops->flags); + + index = cpuidle_wrap_enter(dev, drv, index, + arm_cpuidle_simple_enter); + + if (ops && ops->exit) + ops->exit(ops->flags); + + return index; +} + +/* fields in davinci_ops.flags */ +#define DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN BIT(0) + +static struct cpuidle_driver davinci_idle_driver = { + .name = "cpuidle-davinci", + .owner = THIS_MODULE, + .en_core_tk_irqen = 1, + .states[0] = ARM_CPUIDLE_WFI_STATE, + .states[1] = { + .enter = davinci_enter_idle, + .exit_latency = 10, + .target_residency = 100000, + .flags = CPUIDLE_FLAG_TIME_VALID, + .name = "DDR SR", + .desc = "WFI and DDR Self Refresh", + }, + .state_count = DAVINCI_CPUIDLE_MAX_STATES, +}; + +static DEFINE_PER_CPU(struct cpuidle_device, davinci_cpuidle_device); +static void __iomem *ddr2_reg_base; + +static void davinci_save_ddr_power(int enter, bool pdown) +{ + u32 val; + + val = __raw_readl(ddr2_reg_base + DDR2_SDRCR_OFFSET); + + if (enter) { + if (pdown) + val |= DDR2_SRPD_BIT; + else + val &= ~DDR2_SRPD_BIT; + val |= DDR2_LPMODEN_BIT; + } else { + val &= ~(DDR2_SRPD_BIT | DDR2_LPMODEN_BIT); + } + + __raw_writel(val, ddr2_reg_base + DDR2_SDRCR_OFFSET); +} + +static void davinci_c2state_enter(u32 flags) +{ + davinci_save_ddr_power(1, !!(flags & DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN)); +} + +static void davinci_c2state_exit(u32 flags) +{ + davinci_save_ddr_power(0, !!(flags & DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN)); +} + +static struct davinci_ops davinci_states[DAVINCI_CPUIDLE_MAX_STATES] = { + [1] = { + .enter = davinci_c2state_enter, + .exit = davinci_c2state_exit, + }, +}; + +static int __init davinci_cpuidle_probe(struct platform_device *pdev) +{ + int ret; + struct cpuidle_device *device; + struct davinci_cpuidle_config *pdata = pdev->dev.platform_data; + + device = &per_cpu(davinci_cpuidle_device, smp_processor_id()); + + if (!pdata) { + dev_err(&pdev->dev, "cannot get platform data\n"); + return -ENOENT; + } + + ddr2_reg_base = pdata->ddr2_ctlr_base; + + if (pdata->ddr2_pdown) + davinci_states[1].flags |= DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN; + cpuidle_set_statedata(&device->states_usage[1], &davinci_states[1]); + + device->state_count = DAVINCI_CPUIDLE_MAX_STATES; + + ret = cpuidle_register_driver(&davinci_idle_driver); + if (ret) { + dev_err(&pdev->dev, "failed to register driver\n"); + return ret; + } + + ret = cpuidle_register_device(device); + if (ret) { + dev_err(&pdev->dev, "failed to register device\n"); + cpuidle_unregister_driver(&davinci_idle_driver); + return ret; + } + + return 0; +} + +static struct platform_driver davinci_cpuidle_driver = { + .driver = { + .name = "cpuidle-davinci", + .owner = THIS_MODULE, + }, +}; + +static int __init davinci_cpuidle_init(void) +{ + return platform_driver_probe(&davinci_cpuidle_driver, + davinci_cpuidle_probe); +} +device_initcall(davinci_cpuidle_init); + diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/da830.c b/ANDROID_3.4.5/arch/arm/mach-davinci/da830.c new file mode 100644 index 00000000..deee5c2d --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/da830.c @@ -0,0 +1,1212 @@ +/* + * TI DA830/OMAP L137 chip specific setup + * + * Author: Mark A. Greer <mgreer@mvista.com> + * + * 2009 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ +#include <linux/gpio.h> +#include <linux/init.h> +#include <linux/clk.h> + +#include <asm/mach/map.h> + +#include <mach/psc.h> +#include <mach/irqs.h> +#include <mach/cputype.h> +#include <mach/common.h> +#include <mach/time.h> +#include <mach/da8xx.h> +#include <mach/gpio-davinci.h> + +#include "clock.h" +#include "mux.h" + +/* Offsets of the 8 compare registers on the da830 */ +#define DA830_CMP12_0 0x60 +#define DA830_CMP12_1 0x64 +#define DA830_CMP12_2 0x68 +#define DA830_CMP12_3 0x6c +#define DA830_CMP12_4 0x70 +#define DA830_CMP12_5 0x74 +#define DA830_CMP12_6 0x78 +#define DA830_CMP12_7 0x7c + +#define DA830_REF_FREQ 24000000 + +static struct pll_data pll0_data = { + .num = 1, + .phys_base = DA8XX_PLL0_BASE, + .flags = PLL_HAS_PREDIV | PLL_HAS_POSTDIV, +}; + +static struct clk ref_clk = { + .name = "ref_clk", + .rate = DA830_REF_FREQ, +}; + +static struct clk pll0_clk = { + .name = "pll0", + .parent = &ref_clk, + .pll_data = &pll0_data, + .flags = CLK_PLL, +}; + +static struct clk pll0_aux_clk = { + .name = "pll0_aux_clk", + .parent = &pll0_clk, + .flags = CLK_PLL | PRE_PLL, +}; + +static struct clk pll0_sysclk2 = { + .name = "pll0_sysclk2", + .parent = &pll0_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV2, +}; + +static struct clk pll0_sysclk3 = { + .name = "pll0_sysclk3", + .parent = &pll0_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV3, +}; + +static struct clk pll0_sysclk4 = { + .name = "pll0_sysclk4", + .parent = &pll0_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV4, +}; + +static struct clk pll0_sysclk5 = { + .name = "pll0_sysclk5", + .parent = &pll0_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV5, +}; + +static struct clk pll0_sysclk6 = { + .name = "pll0_sysclk6", + .parent = &pll0_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV6, +}; + +static struct clk pll0_sysclk7 = { + .name = "pll0_sysclk7", + .parent = &pll0_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV7, +}; + +static struct clk i2c0_clk = { + .name = "i2c0", + .parent = &pll0_aux_clk, +}; + +static struct clk timerp64_0_clk = { + .name = "timer0", + .parent = &pll0_aux_clk, +}; + +static struct clk timerp64_1_clk = { + .name = "timer1", + .parent = &pll0_aux_clk, +}; + +static struct clk arm_rom_clk = { + .name = "arm_rom", + .parent = &pll0_sysclk2, + .lpsc = DA8XX_LPSC0_ARM_RAM_ROM, + .flags = ALWAYS_ENABLED, +}; + +static struct clk scr0_ss_clk = { + .name = "scr0_ss", + .parent = &pll0_sysclk2, + .lpsc = DA8XX_LPSC0_SCR0_SS, + .flags = ALWAYS_ENABLED, +}; + +static struct clk scr1_ss_clk = { + .name = "scr1_ss", + .parent = &pll0_sysclk2, + .lpsc = DA8XX_LPSC0_SCR1_SS, + .flags = ALWAYS_ENABLED, +}; + +static struct clk scr2_ss_clk = { + .name = "scr2_ss", + .parent = &pll0_sysclk2, + .lpsc = DA8XX_LPSC0_SCR2_SS, + .flags = ALWAYS_ENABLED, +}; + +static struct clk dmax_clk = { + .name = "dmax", + .parent = &pll0_sysclk2, + .lpsc = DA8XX_LPSC0_PRUSS, + .flags = ALWAYS_ENABLED, +}; + +static struct clk tpcc_clk = { + .name = "tpcc", + .parent = &pll0_sysclk2, + .lpsc = DA8XX_LPSC0_TPCC, + .flags = ALWAYS_ENABLED | CLK_PSC, +}; + +static struct clk tptc0_clk = { + .name = "tptc0", + .parent = &pll0_sysclk2, + .lpsc = DA8XX_LPSC0_TPTC0, + .flags = ALWAYS_ENABLED, +}; + +static struct clk tptc1_clk = { + .name = "tptc1", + .parent = &pll0_sysclk2, + .lpsc = DA8XX_LPSC0_TPTC1, + .flags = ALWAYS_ENABLED, +}; + +static struct clk mmcsd_clk = { + .name = "mmcsd", + .parent = &pll0_sysclk2, + .lpsc = DA8XX_LPSC0_MMC_SD, +}; + +static struct clk uart0_clk = { + .name = "uart0", + .parent = &pll0_sysclk2, + .lpsc = DA8XX_LPSC0_UART0, +}; + +static struct clk uart1_clk = { + .name = "uart1", + .parent = &pll0_sysclk2, + .lpsc = DA8XX_LPSC1_UART1, + .gpsc = 1, +}; + +static struct clk uart2_clk = { + .name = "uart2", + .parent = &pll0_sysclk2, + .lpsc = DA8XX_LPSC1_UART2, + .gpsc = 1, +}; + +static struct clk spi0_clk = { + .name = "spi0", + .parent = &pll0_sysclk2, + .lpsc = DA8XX_LPSC0_SPI0, +}; + +static struct clk spi1_clk = { + .name = "spi1", + .parent = &pll0_sysclk2, + .lpsc = DA8XX_LPSC1_SPI1, + .gpsc = 1, +}; + +static struct clk ecap0_clk = { + .name = "ecap0", + .parent = &pll0_sysclk2, + .lpsc = DA8XX_LPSC1_ECAP, + .gpsc = 1, +}; + +static struct clk ecap1_clk = { + .name = "ecap1", + .parent = &pll0_sysclk2, + .lpsc = DA8XX_LPSC1_ECAP, + .gpsc = 1, +}; + +static struct clk ecap2_clk = { + .name = "ecap2", + .parent = &pll0_sysclk2, + .lpsc = DA8XX_LPSC1_ECAP, + .gpsc = 1, +}; + +static struct clk pwm0_clk = { + .name = "pwm0", + .parent = &pll0_sysclk2, + .lpsc = DA8XX_LPSC1_PWM, + .gpsc = 1, +}; + +static struct clk pwm1_clk = { + .name = "pwm1", + .parent = &pll0_sysclk2, + .lpsc = DA8XX_LPSC1_PWM, + .gpsc = 1, +}; + +static struct clk pwm2_clk = { + .name = "pwm2", + .parent = &pll0_sysclk2, + .lpsc = DA8XX_LPSC1_PWM, + .gpsc = 1, +}; + +static struct clk eqep0_clk = { + .name = "eqep0", + .parent = &pll0_sysclk2, + .lpsc = DA830_LPSC1_EQEP, + .gpsc = 1, +}; + +static struct clk eqep1_clk = { + .name = "eqep1", + .parent = &pll0_sysclk2, + .lpsc = DA830_LPSC1_EQEP, + .gpsc = 1, +}; + +static struct clk lcdc_clk = { + .name = "lcdc", + .parent = &pll0_sysclk2, + .lpsc = DA8XX_LPSC1_LCDC, + .gpsc = 1, +}; + +static struct clk mcasp0_clk = { + .name = "mcasp0", + .parent = &pll0_sysclk2, + .lpsc = DA8XX_LPSC1_McASP0, + .gpsc = 1, +}; + +static struct clk mcasp1_clk = { + .name = "mcasp1", + .parent = &pll0_sysclk2, + .lpsc = DA830_LPSC1_McASP1, + .gpsc = 1, +}; + +static struct clk mcasp2_clk = { + .name = "mcasp2", + .parent = &pll0_sysclk2, + .lpsc = DA830_LPSC1_McASP2, + .gpsc = 1, +}; + +static struct clk usb20_clk = { + .name = "usb20", + .parent = &pll0_sysclk2, + .lpsc = DA8XX_LPSC1_USB20, + .gpsc = 1, +}; + +static struct clk aemif_clk = { + .name = "aemif", + .parent = &pll0_sysclk3, + .lpsc = DA8XX_LPSC0_EMIF25, + .flags = ALWAYS_ENABLED, +}; + +static struct clk aintc_clk = { + .name = "aintc", + .parent = &pll0_sysclk4, + .lpsc = DA8XX_LPSC0_AINTC, + .flags = ALWAYS_ENABLED, +}; + +static struct clk secu_mgr_clk = { + .name = "secu_mgr", + .parent = &pll0_sysclk4, + .lpsc = DA8XX_LPSC0_SECU_MGR, + .flags = ALWAYS_ENABLED, +}; + +static struct clk emac_clk = { + .name = "emac", + .parent = &pll0_sysclk4, + .lpsc = DA8XX_LPSC1_CPGMAC, + .gpsc = 1, +}; + +static struct clk gpio_clk = { + .name = "gpio", + .parent = &pll0_sysclk4, + .lpsc = DA8XX_LPSC1_GPIO, + .gpsc = 1, +}; + +static struct clk i2c1_clk = { + .name = "i2c1", + .parent = &pll0_sysclk4, + .lpsc = DA8XX_LPSC1_I2C, + .gpsc = 1, +}; + +static struct clk usb11_clk = { + .name = "usb11", + .parent = &pll0_sysclk4, + .lpsc = DA8XX_LPSC1_USB11, + .gpsc = 1, +}; + +static struct clk emif3_clk = { + .name = "emif3", + .parent = &pll0_sysclk5, + .lpsc = DA8XX_LPSC1_EMIF3C, + .gpsc = 1, + .flags = ALWAYS_ENABLED, +}; + +static struct clk arm_clk = { + .name = "arm", + .parent = &pll0_sysclk6, + .lpsc = DA8XX_LPSC0_ARM, + .flags = ALWAYS_ENABLED, +}; + +static struct clk rmii_clk = { + .name = "rmii", + .parent = &pll0_sysclk7, +}; + +static struct clk_lookup da830_clks[] = { + CLK(NULL, "ref", &ref_clk), + CLK(NULL, "pll0", &pll0_clk), + CLK(NULL, "pll0_aux", &pll0_aux_clk), + CLK(NULL, "pll0_sysclk2", &pll0_sysclk2), + CLK(NULL, "pll0_sysclk3", &pll0_sysclk3), + CLK(NULL, "pll0_sysclk4", &pll0_sysclk4), + CLK(NULL, "pll0_sysclk5", &pll0_sysclk5), + CLK(NULL, "pll0_sysclk6", &pll0_sysclk6), + CLK(NULL, "pll0_sysclk7", &pll0_sysclk7), + CLK("i2c_davinci.1", NULL, &i2c0_clk), + CLK(NULL, "timer0", &timerp64_0_clk), + CLK("watchdog", NULL, &timerp64_1_clk), + CLK(NULL, "arm_rom", &arm_rom_clk), + CLK(NULL, "scr0_ss", &scr0_ss_clk), + CLK(NULL, "scr1_ss", &scr1_ss_clk), + CLK(NULL, "scr2_ss", &scr2_ss_clk), + CLK(NULL, "dmax", &dmax_clk), + CLK(NULL, "tpcc", &tpcc_clk), + CLK(NULL, "tptc0", &tptc0_clk), + CLK(NULL, "tptc1", &tptc1_clk), + CLK("davinci_mmc.0", NULL, &mmcsd_clk), + CLK(NULL, "uart0", &uart0_clk), + CLK(NULL, "uart1", &uart1_clk), + CLK(NULL, "uart2", &uart2_clk), + CLK("spi_davinci.0", NULL, &spi0_clk), + CLK("spi_davinci.1", NULL, &spi1_clk), + CLK(NULL, "ecap0", &ecap0_clk), + CLK(NULL, "ecap1", &ecap1_clk), + CLK(NULL, "ecap2", &ecap2_clk), + CLK(NULL, "pwm0", &pwm0_clk), + CLK(NULL, "pwm1", &pwm1_clk), + CLK(NULL, "pwm2", &pwm2_clk), + CLK("eqep.0", NULL, &eqep0_clk), + CLK("eqep.1", NULL, &eqep1_clk), + CLK("da8xx_lcdc.0", NULL, &lcdc_clk), + CLK("davinci-mcasp.0", NULL, &mcasp0_clk), + CLK("davinci-mcasp.1", NULL, &mcasp1_clk), + CLK("davinci-mcasp.2", NULL, &mcasp2_clk), + CLK(NULL, "usb20", &usb20_clk), + CLK(NULL, "aemif", &aemif_clk), + CLK(NULL, "aintc", &aintc_clk), + CLK(NULL, "secu_mgr", &secu_mgr_clk), + CLK("davinci_emac.1", NULL, &emac_clk), + CLK(NULL, "gpio", &gpio_clk), + CLK("i2c_davinci.2", NULL, &i2c1_clk), + CLK(NULL, "usb11", &usb11_clk), + CLK(NULL, "emif3", &emif3_clk), + CLK(NULL, "arm", &arm_clk), + CLK(NULL, "rmii", &rmii_clk), + CLK(NULL, NULL, NULL), +}; + +/* + * Device specific mux setup + * + * soc description mux mode mode mux dbg + * reg offset mask mode + */ +static const struct mux_config da830_pins[] = { +#ifdef CONFIG_DAVINCI_MUX + MUX_CFG(DA830, GPIO7_14, 0, 0, 0xf, 1, false) + MUX_CFG(DA830, RTCK, 0, 0, 0xf, 8, false) + MUX_CFG(DA830, GPIO7_15, 0, 4, 0xf, 1, false) + MUX_CFG(DA830, EMU_0, 0, 4, 0xf, 8, false) + MUX_CFG(DA830, EMB_SDCKE, 0, 8, 0xf, 1, false) + MUX_CFG(DA830, EMB_CLK_GLUE, 0, 12, 0xf, 1, false) + MUX_CFG(DA830, EMB_CLK, 0, 12, 0xf, 2, false) + MUX_CFG(DA830, NEMB_CS_0, 0, 16, 0xf, 1, false) + MUX_CFG(DA830, NEMB_CAS, 0, 20, 0xf, 1, false) + MUX_CFG(DA830, NEMB_RAS, 0, 24, 0xf, 1, false) + MUX_CFG(DA830, NEMB_WE, 0, 28, 0xf, 1, false) + MUX_CFG(DA830, EMB_BA_1, 1, 0, 0xf, 1, false) + MUX_CFG(DA830, EMB_BA_0, 1, 4, 0xf, 1, false) + MUX_CFG(DA830, EMB_A_0, 1, 8, 0xf, 1, false) + MUX_CFG(DA830, EMB_A_1, 1, 12, 0xf, 1, false) + MUX_CFG(DA830, EMB_A_2, 1, 16, 0xf, 1, false) + MUX_CFG(DA830, EMB_A_3, 1, 20, 0xf, 1, false) + MUX_CFG(DA830, EMB_A_4, 1, 24, 0xf, 1, false) + MUX_CFG(DA830, EMB_A_5, 1, 28, 0xf, 1, false) + MUX_CFG(DA830, GPIO7_0, 1, 0, 0xf, 8, false) + MUX_CFG(DA830, GPIO7_1, 1, 4, 0xf, 8, false) + MUX_CFG(DA830, GPIO7_2, 1, 8, 0xf, 8, false) + MUX_CFG(DA830, GPIO7_3, 1, 12, 0xf, 8, false) + MUX_CFG(DA830, GPIO7_4, 1, 16, 0xf, 8, false) + MUX_CFG(DA830, GPIO7_5, 1, 20, 0xf, 8, false) + MUX_CFG(DA830, GPIO7_6, 1, 24, 0xf, 8, false) + MUX_CFG(DA830, GPIO7_7, 1, 28, 0xf, 8, false) + MUX_CFG(DA830, EMB_A_6, 2, 0, 0xf, 1, false) + MUX_CFG(DA830, EMB_A_7, 2, 4, 0xf, 1, false) + MUX_CFG(DA830, EMB_A_8, 2, 8, 0xf, 1, false) + MUX_CFG(DA830, EMB_A_9, 2, 12, 0xf, 1, false) + MUX_CFG(DA830, EMB_A_10, 2, 16, 0xf, 1, false) + MUX_CFG(DA830, EMB_A_11, 2, 20, 0xf, 1, false) + MUX_CFG(DA830, EMB_A_12, 2, 24, 0xf, 1, false) + MUX_CFG(DA830, EMB_D_31, 2, 28, 0xf, 1, false) + MUX_CFG(DA830, GPIO7_8, 2, 0, 0xf, 8, false) + MUX_CFG(DA830, GPIO7_9, 2, 4, 0xf, 8, false) + MUX_CFG(DA830, GPIO7_10, 2, 8, 0xf, 8, false) + MUX_CFG(DA830, GPIO7_11, 2, 12, 0xf, 8, false) + MUX_CFG(DA830, GPIO7_12, 2, 16, 0xf, 8, false) + MUX_CFG(DA830, GPIO7_13, 2, 20, 0xf, 8, false) + MUX_CFG(DA830, GPIO3_13, 2, 24, 0xf, 8, false) + MUX_CFG(DA830, EMB_D_30, 3, 0, 0xf, 1, false) + MUX_CFG(DA830, EMB_D_29, 3, 4, 0xf, 1, false) + MUX_CFG(DA830, EMB_D_28, 3, 8, 0xf, 1, false) + MUX_CFG(DA830, EMB_D_27, 3, 12, 0xf, 1, false) + MUX_CFG(DA830, EMB_D_26, 3, 16, 0xf, 1, false) + MUX_CFG(DA830, EMB_D_25, 3, 20, 0xf, 1, false) + MUX_CFG(DA830, EMB_D_24, 3, 24, 0xf, 1, false) + MUX_CFG(DA830, EMB_D_23, 3, 28, 0xf, 1, false) + MUX_CFG(DA830, EMB_D_22, 4, 0, 0xf, 1, false) + MUX_CFG(DA830, EMB_D_21, 4, 4, 0xf, 1, false) + MUX_CFG(DA830, EMB_D_20, 4, 8, 0xf, 1, false) + MUX_CFG(DA830, EMB_D_19, 4, 12, 0xf, 1, false) + MUX_CFG(DA830, EMB_D_18, 4, 16, 0xf, 1, false) + MUX_CFG(DA830, EMB_D_17, 4, 20, 0xf, 1, false) + MUX_CFG(DA830, EMB_D_16, 4, 24, 0xf, 1, false) + MUX_CFG(DA830, NEMB_WE_DQM_3, 4, 28, 0xf, 1, false) + MUX_CFG(DA830, NEMB_WE_DQM_2, 5, 0, 0xf, 1, false) + MUX_CFG(DA830, EMB_D_0, 5, 4, 0xf, 1, false) + MUX_CFG(DA830, EMB_D_1, 5, 8, 0xf, 1, false) + MUX_CFG(DA830, EMB_D_2, 5, 12, 0xf, 1, false) + MUX_CFG(DA830, EMB_D_3, 5, 16, 0xf, 1, false) + MUX_CFG(DA830, EMB_D_4, 5, 20, 0xf, 1, false) + MUX_CFG(DA830, EMB_D_5, 5, 24, 0xf, 1, false) + MUX_CFG(DA830, EMB_D_6, 5, 28, 0xf, 1, false) + MUX_CFG(DA830, GPIO6_0, 5, 4, 0xf, 8, false) + MUX_CFG(DA830, GPIO6_1, 5, 8, 0xf, 8, false) + MUX_CFG(DA830, GPIO6_2, 5, 12, 0xf, 8, false) + MUX_CFG(DA830, GPIO6_3, 5, 16, 0xf, 8, false) + MUX_CFG(DA830, GPIO6_4, 5, 20, 0xf, 8, false) + MUX_CFG(DA830, GPIO6_5, 5, 24, 0xf, 8, false) + MUX_CFG(DA830, GPIO6_6, 5, 28, 0xf, 8, false) + MUX_CFG(DA830, EMB_D_7, 6, 0, 0xf, 1, false) + MUX_CFG(DA830, EMB_D_8, 6, 4, 0xf, 1, false) + MUX_CFG(DA830, EMB_D_9, 6, 8, 0xf, 1, false) + MUX_CFG(DA830, EMB_D_10, 6, 12, 0xf, 1, false) + MUX_CFG(DA830, EMB_D_11, 6, 16, 0xf, 1, false) + MUX_CFG(DA830, EMB_D_12, 6, 20, 0xf, 1, false) + MUX_CFG(DA830, EMB_D_13, 6, 24, 0xf, 1, false) + MUX_CFG(DA830, EMB_D_14, 6, 28, 0xf, 1, false) + MUX_CFG(DA830, GPIO6_7, 6, 0, 0xf, 8, false) + MUX_CFG(DA830, GPIO6_8, 6, 4, 0xf, 8, false) + MUX_CFG(DA830, GPIO6_9, 6, 8, 0xf, 8, false) + MUX_CFG(DA830, GPIO6_10, 6, 12, 0xf, 8, false) + MUX_CFG(DA830, GPIO6_11, 6, 16, 0xf, 8, false) + MUX_CFG(DA830, GPIO6_12, 6, 20, 0xf, 8, false) + MUX_CFG(DA830, GPIO6_13, 6, 24, 0xf, 8, false) + MUX_CFG(DA830, GPIO6_14, 6, 28, 0xf, 8, false) + MUX_CFG(DA830, EMB_D_15, 7, 0, 0xf, 1, false) + MUX_CFG(DA830, NEMB_WE_DQM_1, 7, 4, 0xf, 1, false) + MUX_CFG(DA830, NEMB_WE_DQM_0, 7, 8, 0xf, 1, false) + MUX_CFG(DA830, SPI0_SOMI_0, 7, 12, 0xf, 1, false) + MUX_CFG(DA830, SPI0_SIMO_0, 7, 16, 0xf, 1, false) + MUX_CFG(DA830, SPI0_CLK, 7, 20, 0xf, 1, false) + MUX_CFG(DA830, NSPI0_ENA, 7, 24, 0xf, 1, false) + MUX_CFG(DA830, NSPI0_SCS_0, 7, 28, 0xf, 1, false) + MUX_CFG(DA830, EQEP0I, 7, 12, 0xf, 2, false) + MUX_CFG(DA830, EQEP0S, 7, 16, 0xf, 2, false) + MUX_CFG(DA830, EQEP1I, 7, 20, 0xf, 2, false) + MUX_CFG(DA830, NUART0_CTS, 7, 24, 0xf, 2, false) + MUX_CFG(DA830, NUART0_RTS, 7, 28, 0xf, 2, false) + MUX_CFG(DA830, EQEP0A, 7, 24, 0xf, 4, false) + MUX_CFG(DA830, EQEP0B, 7, 28, 0xf, 4, false) + MUX_CFG(DA830, GPIO6_15, 7, 0, 0xf, 8, false) + MUX_CFG(DA830, GPIO5_14, 7, 4, 0xf, 8, false) + MUX_CFG(DA830, GPIO5_15, 7, 8, 0xf, 8, false) + MUX_CFG(DA830, GPIO5_0, 7, 12, 0xf, 8, false) + MUX_CFG(DA830, GPIO5_1, 7, 16, 0xf, 8, false) + MUX_CFG(DA830, GPIO5_2, 7, 20, 0xf, 8, false) + MUX_CFG(DA830, GPIO5_3, 7, 24, 0xf, 8, false) + MUX_CFG(DA830, GPIO5_4, 7, 28, 0xf, 8, false) + MUX_CFG(DA830, SPI1_SOMI_0, 8, 0, 0xf, 1, false) + MUX_CFG(DA830, SPI1_SIMO_0, 8, 4, 0xf, 1, false) + MUX_CFG(DA830, SPI1_CLK, 8, 8, 0xf, 1, false) + MUX_CFG(DA830, UART0_RXD, 8, 12, 0xf, 1, false) + MUX_CFG(DA830, UART0_TXD, 8, 16, 0xf, 1, false) + MUX_CFG(DA830, AXR1_10, 8, 20, 0xf, 1, false) + MUX_CFG(DA830, AXR1_11, 8, 24, 0xf, 1, false) + MUX_CFG(DA830, NSPI1_ENA, 8, 28, 0xf, 1, false) + MUX_CFG(DA830, I2C1_SCL, 8, 0, 0xf, 2, false) + MUX_CFG(DA830, I2C1_SDA, 8, 4, 0xf, 2, false) + MUX_CFG(DA830, EQEP1S, 8, 8, 0xf, 2, false) + MUX_CFG(DA830, I2C0_SDA, 8, 12, 0xf, 2, false) + MUX_CFG(DA830, I2C0_SCL, 8, 16, 0xf, 2, false) + MUX_CFG(DA830, UART2_RXD, 8, 28, 0xf, 2, false) + MUX_CFG(DA830, TM64P0_IN12, 8, 12, 0xf, 4, false) + MUX_CFG(DA830, TM64P0_OUT12, 8, 16, 0xf, 4, false) + MUX_CFG(DA830, GPIO5_5, 8, 0, 0xf, 8, false) + MUX_CFG(DA830, GPIO5_6, 8, 4, 0xf, 8, false) + MUX_CFG(DA830, GPIO5_7, 8, 8, 0xf, 8, false) + MUX_CFG(DA830, GPIO5_8, 8, 12, 0xf, 8, false) + MUX_CFG(DA830, GPIO5_9, 8, 16, 0xf, 8, false) + MUX_CFG(DA830, GPIO5_10, 8, 20, 0xf, 8, false) + MUX_CFG(DA830, GPIO5_11, 8, 24, 0xf, 8, false) + MUX_CFG(DA830, GPIO5_12, 8, 28, 0xf, 8, false) + MUX_CFG(DA830, NSPI1_SCS_0, 9, 0, 0xf, 1, false) + MUX_CFG(DA830, USB0_DRVVBUS, 9, 4, 0xf, 1, false) + MUX_CFG(DA830, AHCLKX0, 9, 8, 0xf, 1, false) + MUX_CFG(DA830, ACLKX0, 9, 12, 0xf, 1, false) + MUX_CFG(DA830, AFSX0, 9, 16, 0xf, 1, false) + MUX_CFG(DA830, AHCLKR0, 9, 20, 0xf, 1, false) + MUX_CFG(DA830, ACLKR0, 9, 24, 0xf, 1, false) + MUX_CFG(DA830, AFSR0, 9, 28, 0xf, 1, false) + MUX_CFG(DA830, UART2_TXD, 9, 0, 0xf, 2, false) + MUX_CFG(DA830, AHCLKX2, 9, 8, 0xf, 2, false) + MUX_CFG(DA830, ECAP0_APWM0, 9, 12, 0xf, 2, false) + MUX_CFG(DA830, RMII_MHZ_50_CLK, 9, 20, 0xf, 2, false) + MUX_CFG(DA830, ECAP1_APWM1, 9, 24, 0xf, 2, false) + MUX_CFG(DA830, USB_REFCLKIN, 9, 8, 0xf, 4, false) + MUX_CFG(DA830, GPIO5_13, 9, 0, 0xf, 8, false) + MUX_CFG(DA830, GPIO4_15, 9, 4, 0xf, 8, false) + MUX_CFG(DA830, GPIO2_11, 9, 8, 0xf, 8, false) + MUX_CFG(DA830, GPIO2_12, 9, 12, 0xf, 8, false) + MUX_CFG(DA830, GPIO2_13, 9, 16, 0xf, 8, false) + MUX_CFG(DA830, GPIO2_14, 9, 20, 0xf, 8, false) + MUX_CFG(DA830, GPIO2_15, 9, 24, 0xf, 8, false) + MUX_CFG(DA830, GPIO3_12, 9, 28, 0xf, 8, false) + MUX_CFG(DA830, AMUTE0, 10, 0, 0xf, 1, false) + MUX_CFG(DA830, AXR0_0, 10, 4, 0xf, 1, false) + MUX_CFG(DA830, AXR0_1, 10, 8, 0xf, 1, false) + MUX_CFG(DA830, AXR0_2, 10, 12, 0xf, 1, false) + MUX_CFG(DA830, AXR0_3, 10, 16, 0xf, 1, false) + MUX_CFG(DA830, AXR0_4, 10, 20, 0xf, 1, false) + MUX_CFG(DA830, AXR0_5, 10, 24, 0xf, 1, false) + MUX_CFG(DA830, AXR0_6, 10, 28, 0xf, 1, false) + MUX_CFG(DA830, RMII_TXD_0, 10, 4, 0xf, 2, false) + MUX_CFG(DA830, RMII_TXD_1, 10, 8, 0xf, 2, false) + MUX_CFG(DA830, RMII_TXEN, 10, 12, 0xf, 2, false) + MUX_CFG(DA830, RMII_CRS_DV, 10, 16, 0xf, 2, false) + MUX_CFG(DA830, RMII_RXD_0, 10, 20, 0xf, 2, false) + MUX_CFG(DA830, RMII_RXD_1, 10, 24, 0xf, 2, false) + MUX_CFG(DA830, RMII_RXER, 10, 28, 0xf, 2, false) + MUX_CFG(DA830, AFSR2, 10, 4, 0xf, 4, false) + MUX_CFG(DA830, ACLKX2, 10, 8, 0xf, 4, false) + MUX_CFG(DA830, AXR2_3, 10, 12, 0xf, 4, false) + MUX_CFG(DA830, AXR2_2, 10, 16, 0xf, 4, false) + MUX_CFG(DA830, AXR2_1, 10, 20, 0xf, 4, false) + MUX_CFG(DA830, AFSX2, 10, 24, 0xf, 4, false) + MUX_CFG(DA830, ACLKR2, 10, 28, 0xf, 4, false) + MUX_CFG(DA830, NRESETOUT, 10, 0, 0xf, 8, false) + MUX_CFG(DA830, GPIO3_0, 10, 4, 0xf, 8, false) + MUX_CFG(DA830, GPIO3_1, 10, 8, 0xf, 8, false) + MUX_CFG(DA830, GPIO3_2, 10, 12, 0xf, 8, false) + MUX_CFG(DA830, GPIO3_3, 10, 16, 0xf, 8, false) + MUX_CFG(DA830, GPIO3_4, 10, 20, 0xf, 8, false) + MUX_CFG(DA830, GPIO3_5, 10, 24, 0xf, 8, false) + MUX_CFG(DA830, GPIO3_6, 10, 28, 0xf, 8, false) + MUX_CFG(DA830, AXR0_7, 11, 0, 0xf, 1, false) + MUX_CFG(DA830, AXR0_8, 11, 4, 0xf, 1, false) + MUX_CFG(DA830, UART1_RXD, 11, 8, 0xf, 1, false) + MUX_CFG(DA830, UART1_TXD, 11, 12, 0xf, 1, false) + MUX_CFG(DA830, AXR0_11, 11, 16, 0xf, 1, false) + MUX_CFG(DA830, AHCLKX1, 11, 20, 0xf, 1, false) + MUX_CFG(DA830, ACLKX1, 11, 24, 0xf, 1, false) + MUX_CFG(DA830, AFSX1, 11, 28, 0xf, 1, false) + MUX_CFG(DA830, MDIO_CLK, 11, 0, 0xf, 2, false) + MUX_CFG(DA830, MDIO_D, 11, 4, 0xf, 2, false) + MUX_CFG(DA830, AXR0_9, 11, 8, 0xf, 2, false) + MUX_CFG(DA830, AXR0_10, 11, 12, 0xf, 2, false) + MUX_CFG(DA830, EPWM0B, 11, 20, 0xf, 2, false) + MUX_CFG(DA830, EPWM0A, 11, 24, 0xf, 2, false) + MUX_CFG(DA830, EPWMSYNCI, 11, 28, 0xf, 2, false) + MUX_CFG(DA830, AXR2_0, 11, 16, 0xf, 4, false) + MUX_CFG(DA830, EPWMSYNC0, 11, 28, 0xf, 4, false) + MUX_CFG(DA830, GPIO3_7, 11, 0, 0xf, 8, false) + MUX_CFG(DA830, GPIO3_8, 11, 4, 0xf, 8, false) + MUX_CFG(DA830, GPIO3_9, 11, 8, 0xf, 8, false) + MUX_CFG(DA830, GPIO3_10, 11, 12, 0xf, 8, false) + MUX_CFG(DA830, GPIO3_11, 11, 16, 0xf, 8, false) + MUX_CFG(DA830, GPIO3_14, 11, 20, 0xf, 8, false) + MUX_CFG(DA830, GPIO3_15, 11, 24, 0xf, 8, false) + MUX_CFG(DA830, GPIO4_10, 11, 28, 0xf, 8, false) + MUX_CFG(DA830, AHCLKR1, 12, 0, 0xf, 1, false) + MUX_CFG(DA830, ACLKR1, 12, 4, 0xf, 1, false) + MUX_CFG(DA830, AFSR1, 12, 8, 0xf, 1, false) + MUX_CFG(DA830, AMUTE1, 12, 12, 0xf, 1, false) + MUX_CFG(DA830, AXR1_0, 12, 16, 0xf, 1, false) + MUX_CFG(DA830, AXR1_1, 12, 20, 0xf, 1, false) + MUX_CFG(DA830, AXR1_2, 12, 24, 0xf, 1, false) + MUX_CFG(DA830, AXR1_3, 12, 28, 0xf, 1, false) + MUX_CFG(DA830, ECAP2_APWM2, 12, 4, 0xf, 2, false) + MUX_CFG(DA830, EHRPWMGLUETZ, 12, 12, 0xf, 2, false) + MUX_CFG(DA830, EQEP1A, 12, 28, 0xf, 2, false) + MUX_CFG(DA830, GPIO4_11, 12, 0, 0xf, 8, false) + MUX_CFG(DA830, GPIO4_12, 12, 4, 0xf, 8, false) + MUX_CFG(DA830, GPIO4_13, 12, 8, 0xf, 8, false) + MUX_CFG(DA830, GPIO4_14, 12, 12, 0xf, 8, false) + MUX_CFG(DA830, GPIO4_0, 12, 16, 0xf, 8, false) + MUX_CFG(DA830, GPIO4_1, 12, 20, 0xf, 8, false) + MUX_CFG(DA830, GPIO4_2, 12, 24, 0xf, 8, false) + MUX_CFG(DA830, GPIO4_3, 12, 28, 0xf, 8, false) + MUX_CFG(DA830, AXR1_4, 13, 0, 0xf, 1, false) + MUX_CFG(DA830, AXR1_5, 13, 4, 0xf, 1, false) + MUX_CFG(DA830, AXR1_6, 13, 8, 0xf, 1, false) + MUX_CFG(DA830, AXR1_7, 13, 12, 0xf, 1, false) + MUX_CFG(DA830, AXR1_8, 13, 16, 0xf, 1, false) + MUX_CFG(DA830, AXR1_9, 13, 20, 0xf, 1, false) + MUX_CFG(DA830, EMA_D_0, 13, 24, 0xf, 1, false) + MUX_CFG(DA830, EMA_D_1, 13, 28, 0xf, 1, false) + MUX_CFG(DA830, EQEP1B, 13, 0, 0xf, 2, false) + MUX_CFG(DA830, EPWM2B, 13, 4, 0xf, 2, false) + MUX_CFG(DA830, EPWM2A, 13, 8, 0xf, 2, false) + MUX_CFG(DA830, EPWM1B, 13, 12, 0xf, 2, false) + MUX_CFG(DA830, EPWM1A, 13, 16, 0xf, 2, false) + MUX_CFG(DA830, MMCSD_DAT_0, 13, 24, 0xf, 2, false) + MUX_CFG(DA830, MMCSD_DAT_1, 13, 28, 0xf, 2, false) + MUX_CFG(DA830, UHPI_HD_0, 13, 24, 0xf, 4, false) + MUX_CFG(DA830, UHPI_HD_1, 13, 28, 0xf, 4, false) + MUX_CFG(DA830, GPIO4_4, 13, 0, 0xf, 8, false) + MUX_CFG(DA830, GPIO4_5, 13, 4, 0xf, 8, false) + MUX_CFG(DA830, GPIO4_6, 13, 8, 0xf, 8, false) + MUX_CFG(DA830, GPIO4_7, 13, 12, 0xf, 8, false) + MUX_CFG(DA830, GPIO4_8, 13, 16, 0xf, 8, false) + MUX_CFG(DA830, GPIO4_9, 13, 20, 0xf, 8, false) + MUX_CFG(DA830, GPIO0_0, 13, 24, 0xf, 8, false) + MUX_CFG(DA830, GPIO0_1, 13, 28, 0xf, 8, false) + MUX_CFG(DA830, EMA_D_2, 14, 0, 0xf, 1, false) + MUX_CFG(DA830, EMA_D_3, 14, 4, 0xf, 1, false) + MUX_CFG(DA830, EMA_D_4, 14, 8, 0xf, 1, false) + MUX_CFG(DA830, EMA_D_5, 14, 12, 0xf, 1, false) + MUX_CFG(DA830, EMA_D_6, 14, 16, 0xf, 1, false) + MUX_CFG(DA830, EMA_D_7, 14, 20, 0xf, 1, false) + MUX_CFG(DA830, EMA_D_8, 14, 24, 0xf, 1, false) + MUX_CFG(DA830, EMA_D_9, 14, 28, 0xf, 1, false) + MUX_CFG(DA830, MMCSD_DAT_2, 14, 0, 0xf, 2, false) + MUX_CFG(DA830, MMCSD_DAT_3, 14, 4, 0xf, 2, false) + MUX_CFG(DA830, MMCSD_DAT_4, 14, 8, 0xf, 2, false) + MUX_CFG(DA830, MMCSD_DAT_5, 14, 12, 0xf, 2, false) + MUX_CFG(DA830, MMCSD_DAT_6, 14, 16, 0xf, 2, false) + MUX_CFG(DA830, MMCSD_DAT_7, 14, 20, 0xf, 2, false) + MUX_CFG(DA830, UHPI_HD_8, 14, 24, 0xf, 2, false) + MUX_CFG(DA830, UHPI_HD_9, 14, 28, 0xf, 2, false) + MUX_CFG(DA830, UHPI_HD_2, 14, 0, 0xf, 4, false) + MUX_CFG(DA830, UHPI_HD_3, 14, 4, 0xf, 4, false) + MUX_CFG(DA830, UHPI_HD_4, 14, 8, 0xf, 4, false) + MUX_CFG(DA830, UHPI_HD_5, 14, 12, 0xf, 4, false) + MUX_CFG(DA830, UHPI_HD_6, 14, 16, 0xf, 4, false) + MUX_CFG(DA830, UHPI_HD_7, 14, 20, 0xf, 4, false) + MUX_CFG(DA830, LCD_D_8, 14, 24, 0xf, 4, false) + MUX_CFG(DA830, LCD_D_9, 14, 28, 0xf, 4, false) + MUX_CFG(DA830, GPIO0_2, 14, 0, 0xf, 8, false) + MUX_CFG(DA830, GPIO0_3, 14, 4, 0xf, 8, false) + MUX_CFG(DA830, GPIO0_4, 14, 8, 0xf, 8, false) + MUX_CFG(DA830, GPIO0_5, 14, 12, 0xf, 8, false) + MUX_CFG(DA830, GPIO0_6, 14, 16, 0xf, 8, false) + MUX_CFG(DA830, GPIO0_7, 14, 20, 0xf, 8, false) + MUX_CFG(DA830, GPIO0_8, 14, 24, 0xf, 8, false) + MUX_CFG(DA830, GPIO0_9, 14, 28, 0xf, 8, false) + MUX_CFG(DA830, EMA_D_10, 15, 0, 0xf, 1, false) + MUX_CFG(DA830, EMA_D_11, 15, 4, 0xf, 1, false) + MUX_CFG(DA830, EMA_D_12, 15, 8, 0xf, 1, false) + MUX_CFG(DA830, EMA_D_13, 15, 12, 0xf, 1, false) + MUX_CFG(DA830, EMA_D_14, 15, 16, 0xf, 1, false) + MUX_CFG(DA830, EMA_D_15, 15, 20, 0xf, 1, false) + MUX_CFG(DA830, EMA_A_0, 15, 24, 0xf, 1, false) + MUX_CFG(DA830, EMA_A_1, 15, 28, 0xf, 1, false) + MUX_CFG(DA830, UHPI_HD_10, 15, 0, 0xf, 2, false) + MUX_CFG(DA830, UHPI_HD_11, 15, 4, 0xf, 2, false) + MUX_CFG(DA830, UHPI_HD_12, 15, 8, 0xf, 2, false) + MUX_CFG(DA830, UHPI_HD_13, 15, 12, 0xf, 2, false) + MUX_CFG(DA830, UHPI_HD_14, 15, 16, 0xf, 2, false) + MUX_CFG(DA830, UHPI_HD_15, 15, 20, 0xf, 2, false) + MUX_CFG(DA830, LCD_D_7, 15, 24, 0xf, 2, false) + MUX_CFG(DA830, MMCSD_CLK, 15, 28, 0xf, 2, false) + MUX_CFG(DA830, LCD_D_10, 15, 0, 0xf, 4, false) + MUX_CFG(DA830, LCD_D_11, 15, 4, 0xf, 4, false) + MUX_CFG(DA830, LCD_D_12, 15, 8, 0xf, 4, false) + MUX_CFG(DA830, LCD_D_13, 15, 12, 0xf, 4, false) + MUX_CFG(DA830, LCD_D_14, 15, 16, 0xf, 4, false) + MUX_CFG(DA830, LCD_D_15, 15, 20, 0xf, 4, false) + MUX_CFG(DA830, UHPI_HCNTL0, 15, 28, 0xf, 4, false) + MUX_CFG(DA830, GPIO0_10, 15, 0, 0xf, 8, false) + MUX_CFG(DA830, GPIO0_11, 15, 4, 0xf, 8, false) + MUX_CFG(DA830, GPIO0_12, 15, 8, 0xf, 8, false) + MUX_CFG(DA830, GPIO0_13, 15, 12, 0xf, 8, false) + MUX_CFG(DA830, GPIO0_14, 15, 16, 0xf, 8, false) + MUX_CFG(DA830, GPIO0_15, 15, 20, 0xf, 8, false) + MUX_CFG(DA830, GPIO1_0, 15, 24, 0xf, 8, false) + MUX_CFG(DA830, GPIO1_1, 15, 28, 0xf, 8, false) + MUX_CFG(DA830, EMA_A_2, 16, 0, 0xf, 1, false) + MUX_CFG(DA830, EMA_A_3, 16, 4, 0xf, 1, false) + MUX_CFG(DA830, EMA_A_4, 16, 8, 0xf, 1, false) + MUX_CFG(DA830, EMA_A_5, 16, 12, 0xf, 1, false) + MUX_CFG(DA830, EMA_A_6, 16, 16, 0xf, 1, false) + MUX_CFG(DA830, EMA_A_7, 16, 20, 0xf, 1, false) + MUX_CFG(DA830, EMA_A_8, 16, 24, 0xf, 1, false) + MUX_CFG(DA830, EMA_A_9, 16, 28, 0xf, 1, false) + MUX_CFG(DA830, MMCSD_CMD, 16, 0, 0xf, 2, false) + MUX_CFG(DA830, LCD_D_6, 16, 4, 0xf, 2, false) + MUX_CFG(DA830, LCD_D_3, 16, 8, 0xf, 2, false) + MUX_CFG(DA830, LCD_D_2, 16, 12, 0xf, 2, false) + MUX_CFG(DA830, LCD_D_1, 16, 16, 0xf, 2, false) + MUX_CFG(DA830, LCD_D_0, 16, 20, 0xf, 2, false) + MUX_CFG(DA830, LCD_PCLK, 16, 24, 0xf, 2, false) + MUX_CFG(DA830, LCD_HSYNC, 16, 28, 0xf, 2, false) + MUX_CFG(DA830, UHPI_HCNTL1, 16, 0, 0xf, 4, false) + MUX_CFG(DA830, GPIO1_2, 16, 0, 0xf, 8, false) + MUX_CFG(DA830, GPIO1_3, 16, 4, 0xf, 8, false) + MUX_CFG(DA830, GPIO1_4, 16, 8, 0xf, 8, false) + MUX_CFG(DA830, GPIO1_5, 16, 12, 0xf, 8, false) + MUX_CFG(DA830, GPIO1_6, 16, 16, 0xf, 8, false) + MUX_CFG(DA830, GPIO1_7, 16, 20, 0xf, 8, false) + MUX_CFG(DA830, GPIO1_8, 16, 24, 0xf, 8, false) + MUX_CFG(DA830, GPIO1_9, 16, 28, 0xf, 8, false) + MUX_CFG(DA830, EMA_A_10, 17, 0, 0xf, 1, false) + MUX_CFG(DA830, EMA_A_11, 17, 4, 0xf, 1, false) + MUX_CFG(DA830, EMA_A_12, 17, 8, 0xf, 1, false) + MUX_CFG(DA830, EMA_BA_1, 17, 12, 0xf, 1, false) + MUX_CFG(DA830, EMA_BA_0, 17, 16, 0xf, 1, false) + MUX_CFG(DA830, EMA_CLK, 17, 20, 0xf, 1, false) + MUX_CFG(DA830, EMA_SDCKE, 17, 24, 0xf, 1, false) + MUX_CFG(DA830, NEMA_CAS, 17, 28, 0xf, 1, false) + MUX_CFG(DA830, LCD_VSYNC, 17, 0, 0xf, 2, false) + MUX_CFG(DA830, NLCD_AC_ENB_CS, 17, 4, 0xf, 2, false) + MUX_CFG(DA830, LCD_MCLK, 17, 8, 0xf, 2, false) + MUX_CFG(DA830, LCD_D_5, 17, 12, 0xf, 2, false) + MUX_CFG(DA830, LCD_D_4, 17, 16, 0xf, 2, false) + MUX_CFG(DA830, OBSCLK, 17, 20, 0xf, 2, false) + MUX_CFG(DA830, NEMA_CS_4, 17, 28, 0xf, 2, false) + MUX_CFG(DA830, UHPI_HHWIL, 17, 12, 0xf, 4, false) + MUX_CFG(DA830, AHCLKR2, 17, 20, 0xf, 4, false) + MUX_CFG(DA830, GPIO1_10, 17, 0, 0xf, 8, false) + MUX_CFG(DA830, GPIO1_11, 17, 4, 0xf, 8, false) + MUX_CFG(DA830, GPIO1_12, 17, 8, 0xf, 8, false) + MUX_CFG(DA830, GPIO1_13, 17, 12, 0xf, 8, false) + MUX_CFG(DA830, GPIO1_14, 17, 16, 0xf, 8, false) + MUX_CFG(DA830, GPIO1_15, 17, 20, 0xf, 8, false) + MUX_CFG(DA830, GPIO2_0, 17, 24, 0xf, 8, false) + MUX_CFG(DA830, GPIO2_1, 17, 28, 0xf, 8, false) + MUX_CFG(DA830, NEMA_RAS, 18, 0, 0xf, 1, false) + MUX_CFG(DA830, NEMA_WE, 18, 4, 0xf, 1, false) + MUX_CFG(DA830, NEMA_CS_0, 18, 8, 0xf, 1, false) + MUX_CFG(DA830, NEMA_CS_2, 18, 12, 0xf, 1, false) + MUX_CFG(DA830, NEMA_CS_3, 18, 16, 0xf, 1, false) + MUX_CFG(DA830, NEMA_OE, 18, 20, 0xf, 1, false) + MUX_CFG(DA830, NEMA_WE_DQM_1, 18, 24, 0xf, 1, false) + MUX_CFG(DA830, NEMA_WE_DQM_0, 18, 28, 0xf, 1, false) + MUX_CFG(DA830, NEMA_CS_5, 18, 0, 0xf, 2, false) + MUX_CFG(DA830, UHPI_HRNW, 18, 4, 0xf, 2, false) + MUX_CFG(DA830, NUHPI_HAS, 18, 8, 0xf, 2, false) + MUX_CFG(DA830, NUHPI_HCS, 18, 12, 0xf, 2, false) + MUX_CFG(DA830, NUHPI_HDS1, 18, 20, 0xf, 2, false) + MUX_CFG(DA830, NUHPI_HDS2, 18, 24, 0xf, 2, false) + MUX_CFG(DA830, NUHPI_HINT, 18, 28, 0xf, 2, false) + MUX_CFG(DA830, AXR0_12, 18, 4, 0xf, 4, false) + MUX_CFG(DA830, AMUTE2, 18, 16, 0xf, 4, false) + MUX_CFG(DA830, AXR0_13, 18, 20, 0xf, 4, false) + MUX_CFG(DA830, AXR0_14, 18, 24, 0xf, 4, false) + MUX_CFG(DA830, AXR0_15, 18, 28, 0xf, 4, false) + MUX_CFG(DA830, GPIO2_2, 18, 0, 0xf, 8, false) + MUX_CFG(DA830, GPIO2_3, 18, 4, 0xf, 8, false) + MUX_CFG(DA830, GPIO2_4, 18, 8, 0xf, 8, false) + MUX_CFG(DA830, GPIO2_5, 18, 12, 0xf, 8, false) + MUX_CFG(DA830, GPIO2_6, 18, 16, 0xf, 8, false) + MUX_CFG(DA830, GPIO2_7, 18, 20, 0xf, 8, false) + MUX_CFG(DA830, GPIO2_8, 18, 24, 0xf, 8, false) + MUX_CFG(DA830, GPIO2_9, 18, 28, 0xf, 8, false) + MUX_CFG(DA830, EMA_WAIT_0, 19, 0, 0xf, 1, false) + MUX_CFG(DA830, NUHPI_HRDY, 19, 0, 0xf, 2, false) + MUX_CFG(DA830, GPIO2_10, 19, 0, 0xf, 8, false) +#endif +}; + +const short da830_emif25_pins[] __initdata = { + DA830_EMA_D_0, DA830_EMA_D_1, DA830_EMA_D_2, DA830_EMA_D_3, + DA830_EMA_D_4, DA830_EMA_D_5, DA830_EMA_D_6, DA830_EMA_D_7, + DA830_EMA_D_8, DA830_EMA_D_9, DA830_EMA_D_10, DA830_EMA_D_11, + DA830_EMA_D_12, DA830_EMA_D_13, DA830_EMA_D_14, DA830_EMA_D_15, + DA830_EMA_A_0, DA830_EMA_A_1, DA830_EMA_A_2, DA830_EMA_A_3, + DA830_EMA_A_4, DA830_EMA_A_5, DA830_EMA_A_6, DA830_EMA_A_7, + DA830_EMA_A_8, DA830_EMA_A_9, DA830_EMA_A_10, DA830_EMA_A_11, + DA830_EMA_A_12, DA830_EMA_BA_0, DA830_EMA_BA_1, DA830_EMA_CLK, + DA830_EMA_SDCKE, DA830_NEMA_CS_4, DA830_NEMA_CS_5, DA830_NEMA_WE, + DA830_NEMA_CS_0, DA830_NEMA_CS_2, DA830_NEMA_CS_3, DA830_NEMA_OE, + DA830_NEMA_WE_DQM_1, DA830_NEMA_WE_DQM_0, DA830_EMA_WAIT_0, + -1 +}; + +const short da830_spi0_pins[] __initdata = { + DA830_SPI0_SOMI_0, DA830_SPI0_SIMO_0, DA830_SPI0_CLK, DA830_NSPI0_ENA, + DA830_NSPI0_SCS_0, + -1 +}; + +const short da830_spi1_pins[] __initdata = { + DA830_SPI1_SOMI_0, DA830_SPI1_SIMO_0, DA830_SPI1_CLK, DA830_NSPI1_ENA, + DA830_NSPI1_SCS_0, + -1 +}; + +const short da830_mmc_sd_pins[] __initdata = { + DA830_MMCSD_DAT_0, DA830_MMCSD_DAT_1, DA830_MMCSD_DAT_2, + DA830_MMCSD_DAT_3, DA830_MMCSD_DAT_4, DA830_MMCSD_DAT_5, + DA830_MMCSD_DAT_6, DA830_MMCSD_DAT_7, DA830_MMCSD_CLK, + DA830_MMCSD_CMD, + -1 +}; + +const short da830_uart0_pins[] __initdata = { + DA830_NUART0_CTS, DA830_NUART0_RTS, DA830_UART0_RXD, DA830_UART0_TXD, + -1 +}; + +const short da830_uart1_pins[] __initdata = { + DA830_UART1_RXD, DA830_UART1_TXD, + -1 +}; + +const short da830_uart2_pins[] __initdata = { + DA830_UART2_RXD, DA830_UART2_TXD, + -1 +}; + +const short da830_usb20_pins[] __initdata = { + DA830_USB0_DRVVBUS, DA830_USB_REFCLKIN, + -1 +}; + +const short da830_usb11_pins[] __initdata = { + DA830_USB_REFCLKIN, + -1 +}; + +const short da830_uhpi_pins[] __initdata = { + DA830_UHPI_HD_0, DA830_UHPI_HD_1, DA830_UHPI_HD_2, DA830_UHPI_HD_3, + DA830_UHPI_HD_4, DA830_UHPI_HD_5, DA830_UHPI_HD_6, DA830_UHPI_HD_7, + DA830_UHPI_HD_8, DA830_UHPI_HD_9, DA830_UHPI_HD_10, DA830_UHPI_HD_11, + DA830_UHPI_HD_12, DA830_UHPI_HD_13, DA830_UHPI_HD_14, DA830_UHPI_HD_15, + DA830_UHPI_HCNTL0, DA830_UHPI_HCNTL1, DA830_UHPI_HHWIL, DA830_UHPI_HRNW, + DA830_NUHPI_HAS, DA830_NUHPI_HCS, DA830_NUHPI_HDS1, DA830_NUHPI_HDS2, + DA830_NUHPI_HINT, DA830_NUHPI_HRDY, + -1 +}; + +const short da830_cpgmac_pins[] __initdata = { + DA830_RMII_TXD_0, DA830_RMII_TXD_1, DA830_RMII_TXEN, DA830_RMII_CRS_DV, + DA830_RMII_RXD_0, DA830_RMII_RXD_1, DA830_RMII_RXER, DA830_MDIO_CLK, + DA830_MDIO_D, + -1 +}; + +const short da830_emif3c_pins[] __initdata = { + DA830_EMB_SDCKE, DA830_EMB_CLK_GLUE, DA830_EMB_CLK, DA830_NEMB_CS_0, + DA830_NEMB_CAS, DA830_NEMB_RAS, DA830_NEMB_WE, DA830_EMB_BA_1, + DA830_EMB_BA_0, DA830_EMB_A_0, DA830_EMB_A_1, DA830_EMB_A_2, + DA830_EMB_A_3, DA830_EMB_A_4, DA830_EMB_A_5, DA830_EMB_A_6, + DA830_EMB_A_7, DA830_EMB_A_8, DA830_EMB_A_9, DA830_EMB_A_10, + DA830_EMB_A_11, DA830_EMB_A_12, DA830_NEMB_WE_DQM_3, + DA830_NEMB_WE_DQM_2, DA830_EMB_D_0, DA830_EMB_D_1, DA830_EMB_D_2, + DA830_EMB_D_3, DA830_EMB_D_4, DA830_EMB_D_5, DA830_EMB_D_6, + DA830_EMB_D_7, DA830_EMB_D_8, DA830_EMB_D_9, DA830_EMB_D_10, + DA830_EMB_D_11, DA830_EMB_D_12, DA830_EMB_D_13, DA830_EMB_D_14, + DA830_EMB_D_15, DA830_EMB_D_16, DA830_EMB_D_17, DA830_EMB_D_18, + DA830_EMB_D_19, DA830_EMB_D_20, DA830_EMB_D_21, DA830_EMB_D_22, + DA830_EMB_D_23, DA830_EMB_D_24, DA830_EMB_D_25, DA830_EMB_D_26, + DA830_EMB_D_27, DA830_EMB_D_28, DA830_EMB_D_29, DA830_EMB_D_30, + DA830_EMB_D_31, DA830_NEMB_WE_DQM_1, DA830_NEMB_WE_DQM_0, + -1 +}; + +const short da830_mcasp0_pins[] __initdata = { + DA830_AHCLKX0, DA830_ACLKX0, DA830_AFSX0, + DA830_AHCLKR0, DA830_ACLKR0, DA830_AFSR0, DA830_AMUTE0, + DA830_AXR0_0, DA830_AXR0_1, DA830_AXR0_2, DA830_AXR0_3, + DA830_AXR0_4, DA830_AXR0_5, DA830_AXR0_6, DA830_AXR0_7, + DA830_AXR0_8, DA830_AXR0_9, DA830_AXR0_10, DA830_AXR0_11, + DA830_AXR0_12, DA830_AXR0_13, DA830_AXR0_14, DA830_AXR0_15, + -1 +}; + +const short da830_mcasp1_pins[] __initdata = { + DA830_AHCLKX1, DA830_ACLKX1, DA830_AFSX1, + DA830_AHCLKR1, DA830_ACLKR1, DA830_AFSR1, DA830_AMUTE1, + DA830_AXR1_0, DA830_AXR1_1, DA830_AXR1_2, DA830_AXR1_3, + DA830_AXR1_4, DA830_AXR1_5, DA830_AXR1_6, DA830_AXR1_7, + DA830_AXR1_8, DA830_AXR1_9, DA830_AXR1_10, DA830_AXR1_11, + -1 +}; + +const short da830_mcasp2_pins[] __initdata = { + DA830_AHCLKX2, DA830_ACLKX2, DA830_AFSX2, + DA830_AHCLKR2, DA830_ACLKR2, DA830_AFSR2, DA830_AMUTE2, + DA830_AXR2_0, DA830_AXR2_1, DA830_AXR2_2, DA830_AXR2_3, + -1 +}; + +const short da830_i2c0_pins[] __initdata = { + DA830_I2C0_SDA, DA830_I2C0_SCL, + -1 +}; + +const short da830_i2c1_pins[] __initdata = { + DA830_I2C1_SCL, DA830_I2C1_SDA, + -1 +}; + +const short da830_lcdcntl_pins[] __initdata = { + DA830_LCD_D_0, DA830_LCD_D_1, DA830_LCD_D_2, DA830_LCD_D_3, + DA830_LCD_D_4, DA830_LCD_D_5, DA830_LCD_D_6, DA830_LCD_D_7, + DA830_LCD_D_8, DA830_LCD_D_9, DA830_LCD_D_10, DA830_LCD_D_11, + DA830_LCD_D_12, DA830_LCD_D_13, DA830_LCD_D_14, DA830_LCD_D_15, + DA830_LCD_PCLK, DA830_LCD_HSYNC, DA830_LCD_VSYNC, DA830_NLCD_AC_ENB_CS, + DA830_LCD_MCLK, + -1 +}; + +const short da830_pwm_pins[] __initdata = { + DA830_ECAP0_APWM0, DA830_ECAP1_APWM1, DA830_EPWM0B, DA830_EPWM0A, + DA830_EPWMSYNCI, DA830_EPWMSYNC0, DA830_ECAP2_APWM2, DA830_EHRPWMGLUETZ, + DA830_EPWM2B, DA830_EPWM2A, DA830_EPWM1B, DA830_EPWM1A, + -1 +}; + +const short da830_ecap0_pins[] __initdata = { + DA830_ECAP0_APWM0, + -1 +}; + +const short da830_ecap1_pins[] __initdata = { + DA830_ECAP1_APWM1, + -1 +}; + +const short da830_ecap2_pins[] __initdata = { + DA830_ECAP2_APWM2, + -1 +}; + +const short da830_eqep0_pins[] __initdata = { + DA830_EQEP0I, DA830_EQEP0S, DA830_EQEP0A, DA830_EQEP0B, + -1 +}; + +const short da830_eqep1_pins[] __initdata = { + DA830_EQEP1I, DA830_EQEP1S, DA830_EQEP1A, DA830_EQEP1B, + -1 +}; + +/* FIQ are pri 0-1; otherwise 2-7, with 7 lowest priority */ +static u8 da830_default_priorities[DA830_N_CP_INTC_IRQ] = { + [IRQ_DA8XX_COMMTX] = 7, + [IRQ_DA8XX_COMMRX] = 7, + [IRQ_DA8XX_NINT] = 7, + [IRQ_DA8XX_EVTOUT0] = 7, + [IRQ_DA8XX_EVTOUT1] = 7, + [IRQ_DA8XX_EVTOUT2] = 7, + [IRQ_DA8XX_EVTOUT3] = 7, + [IRQ_DA8XX_EVTOUT4] = 7, + [IRQ_DA8XX_EVTOUT5] = 7, + [IRQ_DA8XX_EVTOUT6] = 7, + [IRQ_DA8XX_EVTOUT7] = 7, + [IRQ_DA8XX_CCINT0] = 7, + [IRQ_DA8XX_CCERRINT] = 7, + [IRQ_DA8XX_TCERRINT0] = 7, + [IRQ_DA8XX_AEMIFINT] = 7, + [IRQ_DA8XX_I2CINT0] = 7, + [IRQ_DA8XX_MMCSDINT0] = 7, + [IRQ_DA8XX_MMCSDINT1] = 7, + [IRQ_DA8XX_ALLINT0] = 7, + [IRQ_DA8XX_RTC] = 7, + [IRQ_DA8XX_SPINT0] = 7, + [IRQ_DA8XX_TINT12_0] = 7, + [IRQ_DA8XX_TINT34_0] = 7, + [IRQ_DA8XX_TINT12_1] = 7, + [IRQ_DA8XX_TINT34_1] = 7, + [IRQ_DA8XX_UARTINT0] = 7, + [IRQ_DA8XX_KEYMGRINT] = 7, + [IRQ_DA830_MPUERR] = 7, + [IRQ_DA8XX_CHIPINT0] = 7, + [IRQ_DA8XX_CHIPINT1] = 7, + [IRQ_DA8XX_CHIPINT2] = 7, + [IRQ_DA8XX_CHIPINT3] = 7, + [IRQ_DA8XX_TCERRINT1] = 7, + [IRQ_DA8XX_C0_RX_THRESH_PULSE] = 7, + [IRQ_DA8XX_C0_RX_PULSE] = 7, + [IRQ_DA8XX_C0_TX_PULSE] = 7, + [IRQ_DA8XX_C0_MISC_PULSE] = 7, + [IRQ_DA8XX_C1_RX_THRESH_PULSE] = 7, + [IRQ_DA8XX_C1_RX_PULSE] = 7, + [IRQ_DA8XX_C1_TX_PULSE] = 7, + [IRQ_DA8XX_C1_MISC_PULSE] = 7, + [IRQ_DA8XX_MEMERR] = 7, + [IRQ_DA8XX_GPIO0] = 7, + [IRQ_DA8XX_GPIO1] = 7, + [IRQ_DA8XX_GPIO2] = 7, + [IRQ_DA8XX_GPIO3] = 7, + [IRQ_DA8XX_GPIO4] = 7, + [IRQ_DA8XX_GPIO5] = 7, + [IRQ_DA8XX_GPIO6] = 7, + [IRQ_DA8XX_GPIO7] = 7, + [IRQ_DA8XX_GPIO8] = 7, + [IRQ_DA8XX_I2CINT1] = 7, + [IRQ_DA8XX_LCDINT] = 7, + [IRQ_DA8XX_UARTINT1] = 7, + [IRQ_DA8XX_MCASPINT] = 7, + [IRQ_DA8XX_ALLINT1] = 7, + [IRQ_DA8XX_SPINT1] = 7, + [IRQ_DA8XX_UHPI_INT1] = 7, + [IRQ_DA8XX_USB_INT] = 7, + [IRQ_DA8XX_IRQN] = 7, + [IRQ_DA8XX_RWAKEUP] = 7, + [IRQ_DA8XX_UARTINT2] = 7, + [IRQ_DA8XX_DFTSSINT] = 7, + [IRQ_DA8XX_EHRPWM0] = 7, + [IRQ_DA8XX_EHRPWM0TZ] = 7, + [IRQ_DA8XX_EHRPWM1] = 7, + [IRQ_DA8XX_EHRPWM1TZ] = 7, + [IRQ_DA830_EHRPWM2] = 7, + [IRQ_DA830_EHRPWM2TZ] = 7, + [IRQ_DA8XX_ECAP0] = 7, + [IRQ_DA8XX_ECAP1] = 7, + [IRQ_DA8XX_ECAP2] = 7, + [IRQ_DA830_EQEP0] = 7, + [IRQ_DA830_EQEP1] = 7, + [IRQ_DA830_T12CMPINT0_0] = 7, + [IRQ_DA830_T12CMPINT1_0] = 7, + [IRQ_DA830_T12CMPINT2_0] = 7, + [IRQ_DA830_T12CMPINT3_0] = 7, + [IRQ_DA830_T12CMPINT4_0] = 7, + [IRQ_DA830_T12CMPINT5_0] = 7, + [IRQ_DA830_T12CMPINT6_0] = 7, + [IRQ_DA830_T12CMPINT7_0] = 7, + [IRQ_DA830_T12CMPINT0_1] = 7, + [IRQ_DA830_T12CMPINT1_1] = 7, + [IRQ_DA830_T12CMPINT2_1] = 7, + [IRQ_DA830_T12CMPINT3_1] = 7, + [IRQ_DA830_T12CMPINT4_1] = 7, + [IRQ_DA830_T12CMPINT5_1] = 7, + [IRQ_DA830_T12CMPINT6_1] = 7, + [IRQ_DA830_T12CMPINT7_1] = 7, + [IRQ_DA8XX_ARMCLKSTOPREQ] = 7, +}; + +static struct map_desc da830_io_desc[] = { + { + .virtual = IO_VIRT, + .pfn = __phys_to_pfn(IO_PHYS), + .length = IO_SIZE, + .type = MT_DEVICE + }, + { + .virtual = DA8XX_CP_INTC_VIRT, + .pfn = __phys_to_pfn(DA8XX_CP_INTC_BASE), + .length = DA8XX_CP_INTC_SIZE, + .type = MT_DEVICE + }, +}; + +static u32 da830_psc_bases[] = { DA8XX_PSC0_BASE, DA8XX_PSC1_BASE }; + +/* Contents of JTAG ID register used to identify exact cpu type */ +static struct davinci_id da830_ids[] = { + { + .variant = 0x0, + .part_no = 0xb7df, + .manufacturer = 0x017, /* 0x02f >> 1 */ + .cpu_id = DAVINCI_CPU_ID_DA830, + .name = "da830/omap-l137 rev1.0", + }, + { + .variant = 0x8, + .part_no = 0xb7df, + .manufacturer = 0x017, + .cpu_id = DAVINCI_CPU_ID_DA830, + .name = "da830/omap-l137 rev1.1", + }, + { + .variant = 0x9, + .part_no = 0xb7df, + .manufacturer = 0x017, + .cpu_id = DAVINCI_CPU_ID_DA830, + .name = "da830/omap-l137 rev2.0", + }, +}; + +static struct davinci_timer_instance da830_timer_instance[2] = { + { + .base = DA8XX_TIMER64P0_BASE, + .bottom_irq = IRQ_DA8XX_TINT12_0, + .top_irq = IRQ_DA8XX_TINT34_0, + .cmp_off = DA830_CMP12_0, + .cmp_irq = IRQ_DA830_T12CMPINT0_0, + }, + { + .base = DA8XX_TIMER64P1_BASE, + .bottom_irq = IRQ_DA8XX_TINT12_1, + .top_irq = IRQ_DA8XX_TINT34_1, + .cmp_off = DA830_CMP12_0, + .cmp_irq = IRQ_DA830_T12CMPINT0_1, + }, +}; + +/* + * T0_BOT: Timer 0, bottom : Used for clock_event & clocksource + * T0_TOP: Timer 0, top : Used by DSP + * T1_BOT, T1_TOP: Timer 1, bottom & top: Used for watchdog timer + */ +static struct davinci_timer_info da830_timer_info = { + .timers = da830_timer_instance, + .clockevent_id = T0_BOT, + .clocksource_id = T0_BOT, +}; + +static struct davinci_soc_info davinci_soc_info_da830 = { + .io_desc = da830_io_desc, + .io_desc_num = ARRAY_SIZE(da830_io_desc), + .jtag_id_reg = DA8XX_SYSCFG0_BASE + DA8XX_JTAG_ID_REG, + .ids = da830_ids, + .ids_num = ARRAY_SIZE(da830_ids), + .cpu_clks = da830_clks, + .psc_bases = da830_psc_bases, + .psc_bases_num = ARRAY_SIZE(da830_psc_bases), + .pinmux_base = DA8XX_SYSCFG0_BASE + 0x120, + .pinmux_pins = da830_pins, + .pinmux_pins_num = ARRAY_SIZE(da830_pins), + .intc_base = DA8XX_CP_INTC_BASE, + .intc_type = DAVINCI_INTC_TYPE_CP_INTC, + .intc_irq_prios = da830_default_priorities, + .intc_irq_num = DA830_N_CP_INTC_IRQ, + .timer_info = &da830_timer_info, + .gpio_type = GPIO_TYPE_DAVINCI, + .gpio_base = DA8XX_GPIO_BASE, + .gpio_num = 128, + .gpio_irq = IRQ_DA8XX_GPIO0, + .serial_dev = &da8xx_serial_device, + .emac_pdata = &da8xx_emac_pdata, +}; + +void __init da830_init(void) +{ + davinci_common_init(&davinci_soc_info_da830); + + da8xx_syscfg0_base = ioremap(DA8XX_SYSCFG0_BASE, SZ_4K); + WARN(!da8xx_syscfg0_base, "Unable to map syscfg0 module"); +} diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/da850.c b/ANDROID_3.4.5/arch/arm/mach-davinci/da850.c new file mode 100644 index 00000000..b44dc844 --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/da850.c @@ -0,0 +1,1126 @@ +/* + * TI DA850/OMAP-L138 chip specific setup + * + * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ + * + * Derived from: arch/arm/mach-davinci/da830.c + * Original Copyrights follow: + * + * 2009 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ +#include <linux/gpio.h> +#include <linux/init.h> +#include <linux/clk.h> +#include <linux/platform_device.h> +#include <linux/cpufreq.h> +#include <linux/regulator/consumer.h> + +#include <asm/mach/map.h> + +#include <mach/psc.h> +#include <mach/irqs.h> +#include <mach/cputype.h> +#include <mach/common.h> +#include <mach/time.h> +#include <mach/da8xx.h> +#include <mach/cpufreq.h> +#include <mach/pm.h> +#include <mach/gpio-davinci.h> + +#include "clock.h" +#include "mux.h" + +/* SoC specific clock flags */ +#define DA850_CLK_ASYNC3 BIT(16) + +#define DA850_PLL1_BASE 0x01e1a000 +#define DA850_TIMER64P2_BASE 0x01f0c000 +#define DA850_TIMER64P3_BASE 0x01f0d000 + +#define DA850_REF_FREQ 24000000 + +#define CFGCHIP3_ASYNC3_CLKSRC BIT(4) +#define CFGCHIP3_PLL1_MASTER_LOCK BIT(5) +#define CFGCHIP0_PLL_MASTER_LOCK BIT(4) + +static int da850_set_armrate(struct clk *clk, unsigned long rate); +static int da850_round_armrate(struct clk *clk, unsigned long rate); +static int da850_set_pll0rate(struct clk *clk, unsigned long armrate); + +static struct pll_data pll0_data = { + .num = 1, + .phys_base = DA8XX_PLL0_BASE, + .flags = PLL_HAS_PREDIV | PLL_HAS_POSTDIV, +}; + +static struct clk ref_clk = { + .name = "ref_clk", + .rate = DA850_REF_FREQ, + .set_rate = davinci_simple_set_rate, +}; + +static struct clk pll0_clk = { + .name = "pll0", + .parent = &ref_clk, + .pll_data = &pll0_data, + .flags = CLK_PLL, + .set_rate = da850_set_pll0rate, +}; + +static struct clk pll0_aux_clk = { + .name = "pll0_aux_clk", + .parent = &pll0_clk, + .flags = CLK_PLL | PRE_PLL, +}; + +static struct clk pll0_sysclk2 = { + .name = "pll0_sysclk2", + .parent = &pll0_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV2, +}; + +static struct clk pll0_sysclk3 = { + .name = "pll0_sysclk3", + .parent = &pll0_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV3, + .set_rate = davinci_set_sysclk_rate, + .maxrate = 100000000, +}; + +static struct clk pll0_sysclk4 = { + .name = "pll0_sysclk4", + .parent = &pll0_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV4, +}; + +static struct clk pll0_sysclk5 = { + .name = "pll0_sysclk5", + .parent = &pll0_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV5, +}; + +static struct clk pll0_sysclk6 = { + .name = "pll0_sysclk6", + .parent = &pll0_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV6, +}; + +static struct clk pll0_sysclk7 = { + .name = "pll0_sysclk7", + .parent = &pll0_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV7, +}; + +static struct pll_data pll1_data = { + .num = 2, + .phys_base = DA850_PLL1_BASE, + .flags = PLL_HAS_POSTDIV, +}; + +static struct clk pll1_clk = { + .name = "pll1", + .parent = &ref_clk, + .pll_data = &pll1_data, + .flags = CLK_PLL, +}; + +static struct clk pll1_aux_clk = { + .name = "pll1_aux_clk", + .parent = &pll1_clk, + .flags = CLK_PLL | PRE_PLL, +}; + +static struct clk pll1_sysclk2 = { + .name = "pll1_sysclk2", + .parent = &pll1_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV2, +}; + +static struct clk pll1_sysclk3 = { + .name = "pll1_sysclk3", + .parent = &pll1_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV3, +}; + +static struct clk i2c0_clk = { + .name = "i2c0", + .parent = &pll0_aux_clk, +}; + +static struct clk timerp64_0_clk = { + .name = "timer0", + .parent = &pll0_aux_clk, +}; + +static struct clk timerp64_1_clk = { + .name = "timer1", + .parent = &pll0_aux_clk, +}; + +static struct clk arm_rom_clk = { + .name = "arm_rom", + .parent = &pll0_sysclk2, + .lpsc = DA8XX_LPSC0_ARM_RAM_ROM, + .flags = ALWAYS_ENABLED, +}; + +static struct clk tpcc0_clk = { + .name = "tpcc0", + .parent = &pll0_sysclk2, + .lpsc = DA8XX_LPSC0_TPCC, + .flags = ALWAYS_ENABLED | CLK_PSC, +}; + +static struct clk tptc0_clk = { + .name = "tptc0", + .parent = &pll0_sysclk2, + .lpsc = DA8XX_LPSC0_TPTC0, + .flags = ALWAYS_ENABLED, +}; + +static struct clk tptc1_clk = { + .name = "tptc1", + .parent = &pll0_sysclk2, + .lpsc = DA8XX_LPSC0_TPTC1, + .flags = ALWAYS_ENABLED, +}; + +static struct clk tpcc1_clk = { + .name = "tpcc1", + .parent = &pll0_sysclk2, + .lpsc = DA850_LPSC1_TPCC1, + .gpsc = 1, + .flags = CLK_PSC | ALWAYS_ENABLED, +}; + +static struct clk tptc2_clk = { + .name = "tptc2", + .parent = &pll0_sysclk2, + .lpsc = DA850_LPSC1_TPTC2, + .gpsc = 1, + .flags = ALWAYS_ENABLED, +}; + +static struct clk uart0_clk = { + .name = "uart0", + .parent = &pll0_sysclk2, + .lpsc = DA8XX_LPSC0_UART0, +}; + +static struct clk uart1_clk = { + .name = "uart1", + .parent = &pll0_sysclk2, + .lpsc = DA8XX_LPSC1_UART1, + .gpsc = 1, + .flags = DA850_CLK_ASYNC3, +}; + +static struct clk uart2_clk = { + .name = "uart2", + .parent = &pll0_sysclk2, + .lpsc = DA8XX_LPSC1_UART2, + .gpsc = 1, + .flags = DA850_CLK_ASYNC3, +}; + +static struct clk aintc_clk = { + .name = "aintc", + .parent = &pll0_sysclk4, + .lpsc = DA8XX_LPSC0_AINTC, + .flags = ALWAYS_ENABLED, +}; + +static struct clk gpio_clk = { + .name = "gpio", + .parent = &pll0_sysclk4, + .lpsc = DA8XX_LPSC1_GPIO, + .gpsc = 1, +}; + +static struct clk i2c1_clk = { + .name = "i2c1", + .parent = &pll0_sysclk4, + .lpsc = DA8XX_LPSC1_I2C, + .gpsc = 1, +}; + +static struct clk emif3_clk = { + .name = "emif3", + .parent = &pll0_sysclk5, + .lpsc = DA8XX_LPSC1_EMIF3C, + .gpsc = 1, + .flags = ALWAYS_ENABLED, +}; + +static struct clk arm_clk = { + .name = "arm", + .parent = &pll0_sysclk6, + .lpsc = DA8XX_LPSC0_ARM, + .flags = ALWAYS_ENABLED, + .set_rate = da850_set_armrate, + .round_rate = da850_round_armrate, +}; + +static struct clk rmii_clk = { + .name = "rmii", + .parent = &pll0_sysclk7, +}; + +static struct clk emac_clk = { + .name = "emac", + .parent = &pll0_sysclk4, + .lpsc = DA8XX_LPSC1_CPGMAC, + .gpsc = 1, +}; + +static struct clk mcasp_clk = { + .name = "mcasp", + .parent = &pll0_sysclk2, + .lpsc = DA8XX_LPSC1_McASP0, + .gpsc = 1, + .flags = DA850_CLK_ASYNC3, +}; + +static struct clk lcdc_clk = { + .name = "lcdc", + .parent = &pll0_sysclk2, + .lpsc = DA8XX_LPSC1_LCDC, + .gpsc = 1, +}; + +static struct clk mmcsd0_clk = { + .name = "mmcsd0", + .parent = &pll0_sysclk2, + .lpsc = DA8XX_LPSC0_MMC_SD, +}; + +static struct clk mmcsd1_clk = { + .name = "mmcsd1", + .parent = &pll0_sysclk2, + .lpsc = DA850_LPSC1_MMC_SD1, + .gpsc = 1, +}; + +static struct clk aemif_clk = { + .name = "aemif", + .parent = &pll0_sysclk3, + .lpsc = DA8XX_LPSC0_EMIF25, + .flags = ALWAYS_ENABLED, +}; + +static struct clk usb11_clk = { + .name = "usb11", + .parent = &pll0_sysclk4, + .lpsc = DA8XX_LPSC1_USB11, + .gpsc = 1, +}; + +static struct clk usb20_clk = { + .name = "usb20", + .parent = &pll0_sysclk2, + .lpsc = DA8XX_LPSC1_USB20, + .gpsc = 1, +}; + +static struct clk spi0_clk = { + .name = "spi0", + .parent = &pll0_sysclk2, + .lpsc = DA8XX_LPSC0_SPI0, +}; + +static struct clk spi1_clk = { + .name = "spi1", + .parent = &pll0_sysclk2, + .lpsc = DA8XX_LPSC1_SPI1, + .gpsc = 1, + .flags = DA850_CLK_ASYNC3, +}; + +static struct clk sata_clk = { + .name = "sata", + .parent = &pll0_sysclk2, + .lpsc = DA850_LPSC1_SATA, + .gpsc = 1, + .flags = PSC_FORCE, +}; + +static struct clk_lookup da850_clks[] = { + CLK(NULL, "ref", &ref_clk), + CLK(NULL, "pll0", &pll0_clk), + CLK(NULL, "pll0_aux", &pll0_aux_clk), + CLK(NULL, "pll0_sysclk2", &pll0_sysclk2), + CLK(NULL, "pll0_sysclk3", &pll0_sysclk3), + CLK(NULL, "pll0_sysclk4", &pll0_sysclk4), + CLK(NULL, "pll0_sysclk5", &pll0_sysclk5), + CLK(NULL, "pll0_sysclk6", &pll0_sysclk6), + CLK(NULL, "pll0_sysclk7", &pll0_sysclk7), + CLK(NULL, "pll1", &pll1_clk), + CLK(NULL, "pll1_aux", &pll1_aux_clk), + CLK(NULL, "pll1_sysclk2", &pll1_sysclk2), + CLK(NULL, "pll1_sysclk3", &pll1_sysclk3), + CLK("i2c_davinci.1", NULL, &i2c0_clk), + CLK(NULL, "timer0", &timerp64_0_clk), + CLK("watchdog", NULL, &timerp64_1_clk), + CLK(NULL, "arm_rom", &arm_rom_clk), + CLK(NULL, "tpcc0", &tpcc0_clk), + CLK(NULL, "tptc0", &tptc0_clk), + CLK(NULL, "tptc1", &tptc1_clk), + CLK(NULL, "tpcc1", &tpcc1_clk), + CLK(NULL, "tptc2", &tptc2_clk), + CLK(NULL, "uart0", &uart0_clk), + CLK(NULL, "uart1", &uart1_clk), + CLK(NULL, "uart2", &uart2_clk), + CLK(NULL, "aintc", &aintc_clk), + CLK(NULL, "gpio", &gpio_clk), + CLK("i2c_davinci.2", NULL, &i2c1_clk), + CLK(NULL, "emif3", &emif3_clk), + CLK(NULL, "arm", &arm_clk), + CLK(NULL, "rmii", &rmii_clk), + CLK("davinci_emac.1", NULL, &emac_clk), + CLK("davinci-mcasp.0", NULL, &mcasp_clk), + CLK("da8xx_lcdc.0", NULL, &lcdc_clk), + CLK("davinci_mmc.0", NULL, &mmcsd0_clk), + CLK("davinci_mmc.1", NULL, &mmcsd1_clk), + CLK(NULL, "aemif", &aemif_clk), + CLK(NULL, "usb11", &usb11_clk), + CLK(NULL, "usb20", &usb20_clk), + CLK("spi_davinci.0", NULL, &spi0_clk), + CLK("spi_davinci.1", NULL, &spi1_clk), + CLK("ahci", NULL, &sata_clk), + CLK(NULL, NULL, NULL), +}; + +/* + * Device specific mux setup + * + * soc description mux mode mode mux dbg + * reg offset mask mode + */ +static const struct mux_config da850_pins[] = { +#ifdef CONFIG_DAVINCI_MUX + /* UART0 function */ + MUX_CFG(DA850, NUART0_CTS, 3, 24, 15, 2, false) + MUX_CFG(DA850, NUART0_RTS, 3, 28, 15, 2, false) + MUX_CFG(DA850, UART0_RXD, 3, 16, 15, 2, false) + MUX_CFG(DA850, UART0_TXD, 3, 20, 15, 2, false) + /* UART1 function */ + MUX_CFG(DA850, UART1_RXD, 4, 24, 15, 2, false) + MUX_CFG(DA850, UART1_TXD, 4, 28, 15, 2, false) + /* UART2 function */ + MUX_CFG(DA850, UART2_RXD, 4, 16, 15, 2, false) + MUX_CFG(DA850, UART2_TXD, 4, 20, 15, 2, false) + /* I2C1 function */ + MUX_CFG(DA850, I2C1_SCL, 4, 16, 15, 4, false) + MUX_CFG(DA850, I2C1_SDA, 4, 20, 15, 4, false) + /* I2C0 function */ + MUX_CFG(DA850, I2C0_SDA, 4, 12, 15, 2, false) + MUX_CFG(DA850, I2C0_SCL, 4, 8, 15, 2, false) + /* EMAC function */ + MUX_CFG(DA850, MII_TXEN, 2, 4, 15, 8, false) + MUX_CFG(DA850, MII_TXCLK, 2, 8, 15, 8, false) + MUX_CFG(DA850, MII_COL, 2, 12, 15, 8, false) + MUX_CFG(DA850, MII_TXD_3, 2, 16, 15, 8, false) + MUX_CFG(DA850, MII_TXD_2, 2, 20, 15, 8, false) + MUX_CFG(DA850, MII_TXD_1, 2, 24, 15, 8, false) + MUX_CFG(DA850, MII_TXD_0, 2, 28, 15, 8, false) + MUX_CFG(DA850, MII_RXCLK, 3, 0, 15, 8, false) + MUX_CFG(DA850, MII_RXDV, 3, 4, 15, 8, false) + MUX_CFG(DA850, MII_RXER, 3, 8, 15, 8, false) + MUX_CFG(DA850, MII_CRS, 3, 12, 15, 8, false) + MUX_CFG(DA850, MII_RXD_3, 3, 16, 15, 8, false) + MUX_CFG(DA850, MII_RXD_2, 3, 20, 15, 8, false) + MUX_CFG(DA850, MII_RXD_1, 3, 24, 15, 8, false) + MUX_CFG(DA850, MII_RXD_0, 3, 28, 15, 8, false) + MUX_CFG(DA850, MDIO_CLK, 4, 0, 15, 8, false) + MUX_CFG(DA850, MDIO_D, 4, 4, 15, 8, false) + MUX_CFG(DA850, RMII_TXD_0, 14, 12, 15, 8, false) + MUX_CFG(DA850, RMII_TXD_1, 14, 8, 15, 8, false) + MUX_CFG(DA850, RMII_TXEN, 14, 16, 15, 8, false) + MUX_CFG(DA850, RMII_CRS_DV, 15, 4, 15, 8, false) + MUX_CFG(DA850, RMII_RXD_0, 14, 24, 15, 8, false) + MUX_CFG(DA850, RMII_RXD_1, 14, 20, 15, 8, false) + MUX_CFG(DA850, RMII_RXER, 14, 28, 15, 8, false) + MUX_CFG(DA850, RMII_MHZ_50_CLK, 15, 0, 15, 0, false) + /* McASP function */ + MUX_CFG(DA850, ACLKR, 0, 0, 15, 1, false) + MUX_CFG(DA850, ACLKX, 0, 4, 15, 1, false) + MUX_CFG(DA850, AFSR, 0, 8, 15, 1, false) + MUX_CFG(DA850, AFSX, 0, 12, 15, 1, false) + MUX_CFG(DA850, AHCLKR, 0, 16, 15, 1, false) + MUX_CFG(DA850, AHCLKX, 0, 20, 15, 1, false) + MUX_CFG(DA850, AMUTE, 0, 24, 15, 1, false) + MUX_CFG(DA850, AXR_15, 1, 0, 15, 1, false) + MUX_CFG(DA850, AXR_14, 1, 4, 15, 1, false) + MUX_CFG(DA850, AXR_13, 1, 8, 15, 1, false) + MUX_CFG(DA850, AXR_12, 1, 12, 15, 1, false) + MUX_CFG(DA850, AXR_11, 1, 16, 15, 1, false) + MUX_CFG(DA850, AXR_10, 1, 20, 15, 1, false) + MUX_CFG(DA850, AXR_9, 1, 24, 15, 1, false) + MUX_CFG(DA850, AXR_8, 1, 28, 15, 1, false) + MUX_CFG(DA850, AXR_7, 2, 0, 15, 1, false) + MUX_CFG(DA850, AXR_6, 2, 4, 15, 1, false) + MUX_CFG(DA850, AXR_5, 2, 8, 15, 1, false) + MUX_CFG(DA850, AXR_4, 2, 12, 15, 1, false) + MUX_CFG(DA850, AXR_3, 2, 16, 15, 1, false) + MUX_CFG(DA850, AXR_2, 2, 20, 15, 1, false) + MUX_CFG(DA850, AXR_1, 2, 24, 15, 1, false) + MUX_CFG(DA850, AXR_0, 2, 28, 15, 1, false) + /* LCD function */ + MUX_CFG(DA850, LCD_D_7, 16, 8, 15, 2, false) + MUX_CFG(DA850, LCD_D_6, 16, 12, 15, 2, false) + MUX_CFG(DA850, LCD_D_5, 16, 16, 15, 2, false) + MUX_CFG(DA850, LCD_D_4, 16, 20, 15, 2, false) + MUX_CFG(DA850, LCD_D_3, 16, 24, 15, 2, false) + MUX_CFG(DA850, LCD_D_2, 16, 28, 15, 2, false) + MUX_CFG(DA850, LCD_D_1, 17, 0, 15, 2, false) + MUX_CFG(DA850, LCD_D_0, 17, 4, 15, 2, false) + MUX_CFG(DA850, LCD_D_15, 17, 8, 15, 2, false) + MUX_CFG(DA850, LCD_D_14, 17, 12, 15, 2, false) + MUX_CFG(DA850, LCD_D_13, 17, 16, 15, 2, false) + MUX_CFG(DA850, LCD_D_12, 17, 20, 15, 2, false) + MUX_CFG(DA850, LCD_D_11, 17, 24, 15, 2, false) + MUX_CFG(DA850, LCD_D_10, 17, 28, 15, 2, false) + MUX_CFG(DA850, LCD_D_9, 18, 0, 15, 2, false) + MUX_CFG(DA850, LCD_D_8, 18, 4, 15, 2, false) + MUX_CFG(DA850, LCD_PCLK, 18, 24, 15, 2, false) + MUX_CFG(DA850, LCD_HSYNC, 19, 0, 15, 2, false) + MUX_CFG(DA850, LCD_VSYNC, 19, 4, 15, 2, false) + MUX_CFG(DA850, NLCD_AC_ENB_CS, 19, 24, 15, 2, false) + /* MMC/SD0 function */ + MUX_CFG(DA850, MMCSD0_DAT_0, 10, 8, 15, 2, false) + MUX_CFG(DA850, MMCSD0_DAT_1, 10, 12, 15, 2, false) + MUX_CFG(DA850, MMCSD0_DAT_2, 10, 16, 15, 2, false) + MUX_CFG(DA850, MMCSD0_DAT_3, 10, 20, 15, 2, false) + MUX_CFG(DA850, MMCSD0_CLK, 10, 0, 15, 2, false) + MUX_CFG(DA850, MMCSD0_CMD, 10, 4, 15, 2, false) + /* MMC/SD1 function */ + MUX_CFG(DA850, MMCSD1_DAT_0, 18, 8, 15, 2, false) + MUX_CFG(DA850, MMCSD1_DAT_1, 19, 16, 15, 2, false) + MUX_CFG(DA850, MMCSD1_DAT_2, 19, 12, 15, 2, false) + MUX_CFG(DA850, MMCSD1_DAT_3, 19, 8, 15, 2, false) + MUX_CFG(DA850, MMCSD1_CLK, 18, 12, 15, 2, false) + MUX_CFG(DA850, MMCSD1_CMD, 18, 16, 15, 2, false) + /* EMIF2.5/EMIFA function */ + MUX_CFG(DA850, EMA_D_7, 9, 0, 15, 1, false) + MUX_CFG(DA850, EMA_D_6, 9, 4, 15, 1, false) + MUX_CFG(DA850, EMA_D_5, 9, 8, 15, 1, false) + MUX_CFG(DA850, EMA_D_4, 9, 12, 15, 1, false) + MUX_CFG(DA850, EMA_D_3, 9, 16, 15, 1, false) + MUX_CFG(DA850, EMA_D_2, 9, 20, 15, 1, false) + MUX_CFG(DA850, EMA_D_1, 9, 24, 15, 1, false) + MUX_CFG(DA850, EMA_D_0, 9, 28, 15, 1, false) + MUX_CFG(DA850, EMA_A_1, 12, 24, 15, 1, false) + MUX_CFG(DA850, EMA_A_2, 12, 20, 15, 1, false) + MUX_CFG(DA850, NEMA_CS_3, 7, 4, 15, 1, false) + MUX_CFG(DA850, NEMA_CS_4, 7, 8, 15, 1, false) + MUX_CFG(DA850, NEMA_WE, 7, 16, 15, 1, false) + MUX_CFG(DA850, NEMA_OE, 7, 20, 15, 1, false) + MUX_CFG(DA850, EMA_A_0, 12, 28, 15, 1, false) + MUX_CFG(DA850, EMA_A_3, 12, 16, 15, 1, false) + MUX_CFG(DA850, EMA_A_4, 12, 12, 15, 1, false) + MUX_CFG(DA850, EMA_A_5, 12, 8, 15, 1, false) + MUX_CFG(DA850, EMA_A_6, 12, 4, 15, 1, false) + MUX_CFG(DA850, EMA_A_7, 12, 0, 15, 1, false) + MUX_CFG(DA850, EMA_A_8, 11, 28, 15, 1, false) + MUX_CFG(DA850, EMA_A_9, 11, 24, 15, 1, false) + MUX_CFG(DA850, EMA_A_10, 11, 20, 15, 1, false) + MUX_CFG(DA850, EMA_A_11, 11, 16, 15, 1, false) + MUX_CFG(DA850, EMA_A_12, 11, 12, 15, 1, false) + MUX_CFG(DA850, EMA_A_13, 11, 8, 15, 1, false) + MUX_CFG(DA850, EMA_A_14, 11, 4, 15, 1, false) + MUX_CFG(DA850, EMA_A_15, 11, 0, 15, 1, false) + MUX_CFG(DA850, EMA_A_16, 10, 28, 15, 1, false) + MUX_CFG(DA850, EMA_A_17, 10, 24, 15, 1, false) + MUX_CFG(DA850, EMA_A_18, 10, 20, 15, 1, false) + MUX_CFG(DA850, EMA_A_19, 10, 16, 15, 1, false) + MUX_CFG(DA850, EMA_A_20, 10, 12, 15, 1, false) + MUX_CFG(DA850, EMA_A_21, 10, 8, 15, 1, false) + MUX_CFG(DA850, EMA_A_22, 10, 4, 15, 1, false) + MUX_CFG(DA850, EMA_A_23, 10, 0, 15, 1, false) + MUX_CFG(DA850, EMA_D_8, 8, 28, 15, 1, false) + MUX_CFG(DA850, EMA_D_9, 8, 24, 15, 1, false) + MUX_CFG(DA850, EMA_D_10, 8, 20, 15, 1, false) + MUX_CFG(DA850, EMA_D_11, 8, 16, 15, 1, false) + MUX_CFG(DA850, EMA_D_12, 8, 12, 15, 1, false) + MUX_CFG(DA850, EMA_D_13, 8, 8, 15, 1, false) + MUX_CFG(DA850, EMA_D_14, 8, 4, 15, 1, false) + MUX_CFG(DA850, EMA_D_15, 8, 0, 15, 1, false) + MUX_CFG(DA850, EMA_BA_1, 5, 24, 15, 1, false) + MUX_CFG(DA850, EMA_CLK, 6, 0, 15, 1, false) + MUX_CFG(DA850, EMA_WAIT_1, 6, 24, 15, 1, false) + MUX_CFG(DA850, NEMA_CS_2, 7, 0, 15, 1, false) + /* GPIO function */ + MUX_CFG(DA850, GPIO2_4, 6, 12, 15, 8, false) + MUX_CFG(DA850, GPIO2_6, 6, 4, 15, 8, false) + MUX_CFG(DA850, GPIO2_8, 5, 28, 15, 8, false) + MUX_CFG(DA850, GPIO2_15, 5, 0, 15, 8, false) + MUX_CFG(DA850, GPIO3_12, 7, 12, 15, 8, false) + MUX_CFG(DA850, GPIO3_13, 7, 8, 15, 8, false) + MUX_CFG(DA850, GPIO4_0, 10, 28, 15, 8, false) + MUX_CFG(DA850, GPIO4_1, 10, 24, 15, 8, false) + MUX_CFG(DA850, GPIO6_9, 13, 24, 15, 8, false) + MUX_CFG(DA850, GPIO6_10, 13, 20, 15, 8, false) + MUX_CFG(DA850, GPIO6_13, 13, 8, 15, 8, false) + MUX_CFG(DA850, RTC_ALARM, 0, 28, 15, 2, false) +#endif +}; + +const short da850_i2c0_pins[] __initdata = { + DA850_I2C0_SDA, DA850_I2C0_SCL, + -1 +}; + +const short da850_i2c1_pins[] __initdata = { + DA850_I2C1_SCL, DA850_I2C1_SDA, + -1 +}; + +const short da850_lcdcntl_pins[] __initdata = { + DA850_LCD_D_0, DA850_LCD_D_1, DA850_LCD_D_2, DA850_LCD_D_3, + DA850_LCD_D_4, DA850_LCD_D_5, DA850_LCD_D_6, DA850_LCD_D_7, + DA850_LCD_D_8, DA850_LCD_D_9, DA850_LCD_D_10, DA850_LCD_D_11, + DA850_LCD_D_12, DA850_LCD_D_13, DA850_LCD_D_14, DA850_LCD_D_15, + DA850_LCD_PCLK, DA850_LCD_HSYNC, DA850_LCD_VSYNC, DA850_NLCD_AC_ENB_CS, + -1 +}; + +/* FIQ are pri 0-1; otherwise 2-7, with 7 lowest priority */ +static u8 da850_default_priorities[DA850_N_CP_INTC_IRQ] = { + [IRQ_DA8XX_COMMTX] = 7, + [IRQ_DA8XX_COMMRX] = 7, + [IRQ_DA8XX_NINT] = 7, + [IRQ_DA8XX_EVTOUT0] = 7, + [IRQ_DA8XX_EVTOUT1] = 7, + [IRQ_DA8XX_EVTOUT2] = 7, + [IRQ_DA8XX_EVTOUT3] = 7, + [IRQ_DA8XX_EVTOUT4] = 7, + [IRQ_DA8XX_EVTOUT5] = 7, + [IRQ_DA8XX_EVTOUT6] = 7, + [IRQ_DA8XX_EVTOUT7] = 7, + [IRQ_DA8XX_CCINT0] = 7, + [IRQ_DA8XX_CCERRINT] = 7, + [IRQ_DA8XX_TCERRINT0] = 7, + [IRQ_DA8XX_AEMIFINT] = 7, + [IRQ_DA8XX_I2CINT0] = 7, + [IRQ_DA8XX_MMCSDINT0] = 7, + [IRQ_DA8XX_MMCSDINT1] = 7, + [IRQ_DA8XX_ALLINT0] = 7, + [IRQ_DA8XX_RTC] = 7, + [IRQ_DA8XX_SPINT0] = 7, + [IRQ_DA8XX_TINT12_0] = 7, + [IRQ_DA8XX_TINT34_0] = 7, + [IRQ_DA8XX_TINT12_1] = 7, + [IRQ_DA8XX_TINT34_1] = 7, + [IRQ_DA8XX_UARTINT0] = 7, + [IRQ_DA8XX_KEYMGRINT] = 7, + [IRQ_DA850_MPUADDRERR0] = 7, + [IRQ_DA8XX_CHIPINT0] = 7, + [IRQ_DA8XX_CHIPINT1] = 7, + [IRQ_DA8XX_CHIPINT2] = 7, + [IRQ_DA8XX_CHIPINT3] = 7, + [IRQ_DA8XX_TCERRINT1] = 7, + [IRQ_DA8XX_C0_RX_THRESH_PULSE] = 7, + [IRQ_DA8XX_C0_RX_PULSE] = 7, + [IRQ_DA8XX_C0_TX_PULSE] = 7, + [IRQ_DA8XX_C0_MISC_PULSE] = 7, + [IRQ_DA8XX_C1_RX_THRESH_PULSE] = 7, + [IRQ_DA8XX_C1_RX_PULSE] = 7, + [IRQ_DA8XX_C1_TX_PULSE] = 7, + [IRQ_DA8XX_C1_MISC_PULSE] = 7, + [IRQ_DA8XX_MEMERR] = 7, + [IRQ_DA8XX_GPIO0] = 7, + [IRQ_DA8XX_GPIO1] = 7, + [IRQ_DA8XX_GPIO2] = 7, + [IRQ_DA8XX_GPIO3] = 7, + [IRQ_DA8XX_GPIO4] = 7, + [IRQ_DA8XX_GPIO5] = 7, + [IRQ_DA8XX_GPIO6] = 7, + [IRQ_DA8XX_GPIO7] = 7, + [IRQ_DA8XX_GPIO8] = 7, + [IRQ_DA8XX_I2CINT1] = 7, + [IRQ_DA8XX_LCDINT] = 7, + [IRQ_DA8XX_UARTINT1] = 7, + [IRQ_DA8XX_MCASPINT] = 7, + [IRQ_DA8XX_ALLINT1] = 7, + [IRQ_DA8XX_SPINT1] = 7, + [IRQ_DA8XX_UHPI_INT1] = 7, + [IRQ_DA8XX_USB_INT] = 7, + [IRQ_DA8XX_IRQN] = 7, + [IRQ_DA8XX_RWAKEUP] = 7, + [IRQ_DA8XX_UARTINT2] = 7, + [IRQ_DA8XX_DFTSSINT] = 7, + [IRQ_DA8XX_EHRPWM0] = 7, + [IRQ_DA8XX_EHRPWM0TZ] = 7, + [IRQ_DA8XX_EHRPWM1] = 7, + [IRQ_DA8XX_EHRPWM1TZ] = 7, + [IRQ_DA850_SATAINT] = 7, + [IRQ_DA850_TINTALL_2] = 7, + [IRQ_DA8XX_ECAP0] = 7, + [IRQ_DA8XX_ECAP1] = 7, + [IRQ_DA8XX_ECAP2] = 7, + [IRQ_DA850_MMCSDINT0_1] = 7, + [IRQ_DA850_MMCSDINT1_1] = 7, + [IRQ_DA850_T12CMPINT0_2] = 7, + [IRQ_DA850_T12CMPINT1_2] = 7, + [IRQ_DA850_T12CMPINT2_2] = 7, + [IRQ_DA850_T12CMPINT3_2] = 7, + [IRQ_DA850_T12CMPINT4_2] = 7, + [IRQ_DA850_T12CMPINT5_2] = 7, + [IRQ_DA850_T12CMPINT6_2] = 7, + [IRQ_DA850_T12CMPINT7_2] = 7, + [IRQ_DA850_T12CMPINT0_3] = 7, + [IRQ_DA850_T12CMPINT1_3] = 7, + [IRQ_DA850_T12CMPINT2_3] = 7, + [IRQ_DA850_T12CMPINT3_3] = 7, + [IRQ_DA850_T12CMPINT4_3] = 7, + [IRQ_DA850_T12CMPINT5_3] = 7, + [IRQ_DA850_T12CMPINT6_3] = 7, + [IRQ_DA850_T12CMPINT7_3] = 7, + [IRQ_DA850_RPIINT] = 7, + [IRQ_DA850_VPIFINT] = 7, + [IRQ_DA850_CCINT1] = 7, + [IRQ_DA850_CCERRINT1] = 7, + [IRQ_DA850_TCERRINT2] = 7, + [IRQ_DA850_TINTALL_3] = 7, + [IRQ_DA850_MCBSP0RINT] = 7, + [IRQ_DA850_MCBSP0XINT] = 7, + [IRQ_DA850_MCBSP1RINT] = 7, + [IRQ_DA850_MCBSP1XINT] = 7, + [IRQ_DA8XX_ARMCLKSTOPREQ] = 7, +}; + +static struct map_desc da850_io_desc[] = { + { + .virtual = IO_VIRT, + .pfn = __phys_to_pfn(IO_PHYS), + .length = IO_SIZE, + .type = MT_DEVICE + }, + { + .virtual = DA8XX_CP_INTC_VIRT, + .pfn = __phys_to_pfn(DA8XX_CP_INTC_BASE), + .length = DA8XX_CP_INTC_SIZE, + .type = MT_DEVICE + }, + { + .virtual = SRAM_VIRT, + .pfn = __phys_to_pfn(DA8XX_ARM_RAM_BASE), + .length = SZ_8K, + .type = MT_DEVICE + }, +}; + +static u32 da850_psc_bases[] = { DA8XX_PSC0_BASE, DA8XX_PSC1_BASE }; + +/* Contents of JTAG ID register used to identify exact cpu type */ +static struct davinci_id da850_ids[] = { + { + .variant = 0x0, + .part_no = 0xb7d1, + .manufacturer = 0x017, /* 0x02f >> 1 */ + .cpu_id = DAVINCI_CPU_ID_DA850, + .name = "da850/omap-l138", + }, + { + .variant = 0x1, + .part_no = 0xb7d1, + .manufacturer = 0x017, /* 0x02f >> 1 */ + .cpu_id = DAVINCI_CPU_ID_DA850, + .name = "da850/omap-l138/am18x", + }, +}; + +static struct davinci_timer_instance da850_timer_instance[4] = { + { + .base = DA8XX_TIMER64P0_BASE, + .bottom_irq = IRQ_DA8XX_TINT12_0, + .top_irq = IRQ_DA8XX_TINT34_0, + }, + { + .base = DA8XX_TIMER64P1_BASE, + .bottom_irq = IRQ_DA8XX_TINT12_1, + .top_irq = IRQ_DA8XX_TINT34_1, + }, + { + .base = DA850_TIMER64P2_BASE, + .bottom_irq = IRQ_DA850_TINT12_2, + .top_irq = IRQ_DA850_TINT34_2, + }, + { + .base = DA850_TIMER64P3_BASE, + .bottom_irq = IRQ_DA850_TINT12_3, + .top_irq = IRQ_DA850_TINT34_3, + }, +}; + +/* + * T0_BOT: Timer 0, bottom : Used for clock_event + * T0_TOP: Timer 0, top : Used for clocksource + * T1_BOT, T1_TOP: Timer 1, bottom & top: Used for watchdog timer + */ +static struct davinci_timer_info da850_timer_info = { + .timers = da850_timer_instance, + .clockevent_id = T0_BOT, + .clocksource_id = T0_TOP, +}; + +static void da850_set_async3_src(int pllnum) +{ + struct clk *clk, *newparent = pllnum ? &pll1_sysclk2 : &pll0_sysclk2; + struct clk_lookup *c; + unsigned int v; + int ret; + + for (c = da850_clks; c->clk; c++) { + clk = c->clk; + if (clk->flags & DA850_CLK_ASYNC3) { + ret = clk_set_parent(clk, newparent); + WARN(ret, "DA850: unable to re-parent clock %s", + clk->name); + } + } + + v = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG)); + if (pllnum) + v |= CFGCHIP3_ASYNC3_CLKSRC; + else + v &= ~CFGCHIP3_ASYNC3_CLKSRC; + __raw_writel(v, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG)); +} + +#ifdef CONFIG_CPU_FREQ +/* + * Notes: + * According to the TRM, minimum PLLM results in maximum power savings. + * The OPP definitions below should keep the PLLM as low as possible. + * + * The output of the PLLM must be between 300 to 600 MHz. + */ +struct da850_opp { + unsigned int freq; /* in KHz */ + unsigned int prediv; + unsigned int mult; + unsigned int postdiv; + unsigned int cvdd_min; /* in uV */ + unsigned int cvdd_max; /* in uV */ +}; + +static const struct da850_opp da850_opp_456 = { + .freq = 456000, + .prediv = 1, + .mult = 19, + .postdiv = 1, + .cvdd_min = 1300000, + .cvdd_max = 1350000, +}; + +static const struct da850_opp da850_opp_408 = { + .freq = 408000, + .prediv = 1, + .mult = 17, + .postdiv = 1, + .cvdd_min = 1300000, + .cvdd_max = 1350000, +}; + +static const struct da850_opp da850_opp_372 = { + .freq = 372000, + .prediv = 2, + .mult = 31, + .postdiv = 1, + .cvdd_min = 1200000, + .cvdd_max = 1320000, +}; + +static const struct da850_opp da850_opp_300 = { + .freq = 300000, + .prediv = 1, + .mult = 25, + .postdiv = 2, + .cvdd_min = 1200000, + .cvdd_max = 1320000, +}; + +static const struct da850_opp da850_opp_200 = { + .freq = 200000, + .prediv = 1, + .mult = 25, + .postdiv = 3, + .cvdd_min = 1100000, + .cvdd_max = 1160000, +}; + +static const struct da850_opp da850_opp_96 = { + .freq = 96000, + .prediv = 1, + .mult = 20, + .postdiv = 5, + .cvdd_min = 1000000, + .cvdd_max = 1050000, +}; + +#define OPP(freq) \ + { \ + .index = (unsigned int) &da850_opp_##freq, \ + .frequency = freq * 1000, \ + } + +static struct cpufreq_frequency_table da850_freq_table[] = { + OPP(456), + OPP(408), + OPP(372), + OPP(300), + OPP(200), + OPP(96), + { + .index = 0, + .frequency = CPUFREQ_TABLE_END, + }, +}; + +#ifdef CONFIG_REGULATOR +static int da850_set_voltage(unsigned int index); +static int da850_regulator_init(void); +#endif + +static struct davinci_cpufreq_config cpufreq_info = { + .freq_table = da850_freq_table, +#ifdef CONFIG_REGULATOR + .init = da850_regulator_init, + .set_voltage = da850_set_voltage, +#endif +}; + +#ifdef CONFIG_REGULATOR +static struct regulator *cvdd; + +static int da850_set_voltage(unsigned int index) +{ + struct da850_opp *opp; + + if (!cvdd) + return -ENODEV; + + opp = (struct da850_opp *) cpufreq_info.freq_table[index].index; + + return regulator_set_voltage(cvdd, opp->cvdd_min, opp->cvdd_max); +} + +static int da850_regulator_init(void) +{ + cvdd = regulator_get(NULL, "cvdd"); + if (WARN(IS_ERR(cvdd), "Unable to obtain voltage regulator for CVDD;" + " voltage scaling unsupported\n")) { + return PTR_ERR(cvdd); + } + + return 0; +} +#endif + +static struct platform_device da850_cpufreq_device = { + .name = "cpufreq-davinci", + .dev = { + .platform_data = &cpufreq_info, + }, + .id = -1, +}; + +unsigned int da850_max_speed = 300000; + +int __init da850_register_cpufreq(char *async_clk) +{ + int i; + + /* cpufreq driver can help keep an "async" clock constant */ + if (async_clk) + clk_add_alias("async", da850_cpufreq_device.name, + async_clk, NULL); + for (i = 0; i < ARRAY_SIZE(da850_freq_table); i++) { + if (da850_freq_table[i].frequency <= da850_max_speed) { + cpufreq_info.freq_table = &da850_freq_table[i]; + break; + } + } + + return platform_device_register(&da850_cpufreq_device); +} + +static int da850_round_armrate(struct clk *clk, unsigned long rate) +{ + int i, ret = 0, diff; + unsigned int best = (unsigned int) -1; + struct cpufreq_frequency_table *table = cpufreq_info.freq_table; + + rate /= 1000; /* convert to kHz */ + + for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) { + diff = table[i].frequency - rate; + if (diff < 0) + diff = -diff; + + if (diff < best) { + best = diff; + ret = table[i].frequency; + } + } + + return ret * 1000; +} + +static int da850_set_armrate(struct clk *clk, unsigned long index) +{ + struct clk *pllclk = &pll0_clk; + + return clk_set_rate(pllclk, index); +} + +static int da850_set_pll0rate(struct clk *clk, unsigned long index) +{ + unsigned int prediv, mult, postdiv; + struct da850_opp *opp; + struct pll_data *pll = clk->pll_data; + int ret; + + opp = (struct da850_opp *) cpufreq_info.freq_table[index].index; + prediv = opp->prediv; + mult = opp->mult; + postdiv = opp->postdiv; + + ret = davinci_set_pllrate(pll, prediv, mult, postdiv); + if (WARN_ON(ret)) + return ret; + + return 0; +} +#else +int __init da850_register_cpufreq(char *async_clk) +{ + return 0; +} + +static int da850_set_armrate(struct clk *clk, unsigned long rate) +{ + return -EINVAL; +} + +static int da850_set_pll0rate(struct clk *clk, unsigned long armrate) +{ + return -EINVAL; +} + +static int da850_round_armrate(struct clk *clk, unsigned long rate) +{ + return clk->rate; +} +#endif + +int __init da850_register_pm(struct platform_device *pdev) +{ + int ret; + struct davinci_pm_config *pdata = pdev->dev.platform_data; + + ret = davinci_cfg_reg(DA850_RTC_ALARM); + if (ret) + return ret; + + pdata->ddr2_ctlr_base = da8xx_get_mem_ctlr(); + pdata->deepsleep_reg = DA8XX_SYSCFG1_VIRT(DA8XX_DEEPSLEEP_REG); + pdata->ddrpsc_num = DA8XX_LPSC1_EMIF3C; + + pdata->cpupll_reg_base = ioremap(DA8XX_PLL0_BASE, SZ_4K); + if (!pdata->cpupll_reg_base) + return -ENOMEM; + + pdata->ddrpll_reg_base = ioremap(DA850_PLL1_BASE, SZ_4K); + if (!pdata->ddrpll_reg_base) { + ret = -ENOMEM; + goto no_ddrpll_mem; + } + + pdata->ddrpsc_reg_base = ioremap(DA8XX_PSC1_BASE, SZ_4K); + if (!pdata->ddrpsc_reg_base) { + ret = -ENOMEM; + goto no_ddrpsc_mem; + } + + return platform_device_register(pdev); + +no_ddrpsc_mem: + iounmap(pdata->ddrpll_reg_base); +no_ddrpll_mem: + iounmap(pdata->cpupll_reg_base); + return ret; +} + +static struct davinci_soc_info davinci_soc_info_da850 = { + .io_desc = da850_io_desc, + .io_desc_num = ARRAY_SIZE(da850_io_desc), + .jtag_id_reg = DA8XX_SYSCFG0_BASE + DA8XX_JTAG_ID_REG, + .ids = da850_ids, + .ids_num = ARRAY_SIZE(da850_ids), + .cpu_clks = da850_clks, + .psc_bases = da850_psc_bases, + .psc_bases_num = ARRAY_SIZE(da850_psc_bases), + .pinmux_base = DA8XX_SYSCFG0_BASE + 0x120, + .pinmux_pins = da850_pins, + .pinmux_pins_num = ARRAY_SIZE(da850_pins), + .intc_base = DA8XX_CP_INTC_BASE, + .intc_type = DAVINCI_INTC_TYPE_CP_INTC, + .intc_irq_prios = da850_default_priorities, + .intc_irq_num = DA850_N_CP_INTC_IRQ, + .timer_info = &da850_timer_info, + .gpio_type = GPIO_TYPE_DAVINCI, + .gpio_base = DA8XX_GPIO_BASE, + .gpio_num = 144, + .gpio_irq = IRQ_DA8XX_GPIO0, + .serial_dev = &da8xx_serial_device, + .emac_pdata = &da8xx_emac_pdata, + .sram_dma = DA8XX_ARM_RAM_BASE, + .sram_len = SZ_8K, +}; + +void __init da850_init(void) +{ + unsigned int v; + + davinci_common_init(&davinci_soc_info_da850); + + da8xx_syscfg0_base = ioremap(DA8XX_SYSCFG0_BASE, SZ_4K); + if (WARN(!da8xx_syscfg0_base, "Unable to map syscfg0 module")) + return; + + da8xx_syscfg1_base = ioremap(DA8XX_SYSCFG1_BASE, SZ_4K); + if (WARN(!da8xx_syscfg1_base, "Unable to map syscfg1 module")) + return; + + /* + * Move the clock source of Async3 domain to PLL1 SYSCLK2. + * This helps keeping the peripherals on this domain insulated + * from CPU frequency changes caused by DVFS. The firmware sets + * both PLL0 and PLL1 to the same frequency so, there should not + * be any noticeable change even in non-DVFS use cases. + */ + da850_set_async3_src(1); + + /* Unlock writing to PLL0 registers */ + v = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP0_REG)); + v &= ~CFGCHIP0_PLL_MASTER_LOCK; + __raw_writel(v, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP0_REG)); + + /* Unlock writing to PLL1 registers */ + v = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG)); + v &= ~CFGCHIP3_PLL1_MASTER_LOCK; + __raw_writel(v, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG)); +} diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/davinci.h b/ANDROID_3.4.5/arch/arm/mach-davinci/davinci.h new file mode 100644 index 00000000..3e519dad --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/davinci.h @@ -0,0 +1,102 @@ +/* + * This file contains the processor specific definitions + * of the TI DM644x, DM355, DM365, and DM646x. + * + * Copyright (C) 2011 Texas Instruments Incorporated + * Copyright (c) 2007 Deep Root Systems, LLC + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __DAVINCI_H +#define __DAVINCI_H + +#include <linux/clk.h> +#include <linux/videodev2.h> +#include <linux/davinci_emac.h> +#include <linux/platform_device.h> +#include <linux/spi/spi.h> + +#include <mach/asp.h> +#include <mach/keyscan.h> +#include <mach/hardware.h> + +#include <media/davinci/vpfe_capture.h> +#include <media/davinci/vpif_types.h> +#include <media/davinci/vpss.h> +#include <media/davinci/vpbe_types.h> +#include <media/davinci/vpbe_venc.h> +#include <media/davinci/vpbe.h> +#include <media/davinci/vpbe_osd.h> + +#define DAVINCI_SYSTEM_MODULE_BASE 0x01c40000 +#define SYSMOD_VIDCLKCTL 0x38 +#define SYSMOD_VPSS_CLKCTL 0x44 +#define SYSMOD_VDD3P3VPWDN 0x48 +#define SYSMOD_VSCLKDIS 0x6c +#define SYSMOD_PUPDCTL1 0x7c + +extern void __iomem *davinci_sysmod_base; +#define DAVINCI_SYSMOD_VIRT(x) (davinci_sysmod_base + (x)) +void davinci_map_sysmod(void); + +/* DM355 base addresses */ +#define DM355_ASYNC_EMIF_CONTROL_BASE 0x01e10000 +#define DM355_ASYNC_EMIF_DATA_CE0_BASE 0x02000000 + +#define ASP1_TX_EVT_EN 1 +#define ASP1_RX_EVT_EN 2 + +/* DM365 base addresses */ +#define DM365_ASYNC_EMIF_CONTROL_BASE 0x01d10000 +#define DM365_ASYNC_EMIF_DATA_CE0_BASE 0x02000000 +#define DM365_ASYNC_EMIF_DATA_CE1_BASE 0x04000000 + +/* DM644x base addresses */ +#define DM644X_ASYNC_EMIF_CONTROL_BASE 0x01e00000 +#define DM644X_ASYNC_EMIF_DATA_CE0_BASE 0x02000000 +#define DM644X_ASYNC_EMIF_DATA_CE1_BASE 0x04000000 +#define DM644X_ASYNC_EMIF_DATA_CE2_BASE 0x06000000 +#define DM644X_ASYNC_EMIF_DATA_CE3_BASE 0x08000000 + +/* DM646x base addresses */ +#define DM646X_ASYNC_EMIF_CONTROL_BASE 0x20008000 +#define DM646X_ASYNC_EMIF_CS2_SPACE_BASE 0x42000000 + +/* DM355 function declarations */ +void __init dm355_init(void); +void dm355_init_spi0(unsigned chipselect_mask, + struct spi_board_info *info, unsigned len); +void __init dm355_init_asp1(u32 evt_enable, struct snd_platform_data *pdata); +void dm355_set_vpfe_config(struct vpfe_config *cfg); + +/* DM365 function declarations */ +void __init dm365_init(void); +void __init dm365_init_asp(struct snd_platform_data *pdata); +void __init dm365_init_vc(struct snd_platform_data *pdata); +void __init dm365_init_ks(struct davinci_ks_platform_data *pdata); +void __init dm365_init_rtc(void); +void dm365_init_spi0(unsigned chipselect_mask, + struct spi_board_info *info, unsigned len); +void dm365_set_vpfe_config(struct vpfe_config *cfg); + +/* DM644x function declarations */ +void __init dm644x_init(void); +void __init dm644x_init_asp(struct snd_platform_data *pdata); +int __init dm644x_init_video(struct vpfe_config *, struct vpbe_config *); + +/* DM646x function declarations */ +void __init dm646x_init(void); +void __init dm646x_init_mcasp0(struct snd_platform_data *pdata); +void __init dm646x_init_mcasp1(struct snd_platform_data *pdata); +int __init dm646x_init_edma(struct edma_rsv_info *rsv); +void dm646x_video_init(void); +void dm646x_setup_vpif(struct vpif_display_config *, + struct vpif_capture_config *); +#endif /*__DAVINCI_H */ diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/devices-da8xx.c b/ANDROID_3.4.5/arch/arm/mach-davinci/devices-da8xx.c new file mode 100644 index 00000000..42dbf3dc --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/devices-da8xx.c @@ -0,0 +1,978 @@ +/* + * DA8XX/OMAP L1XX platform device data + * + * Copyright (c) 2007-2009, MontaVista Software, Inc. <source@mvista.com> + * Derived from code that was: + * Copyright (C) 2006 Komal Shah <komal_shah802003@yahoo.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/dma-mapping.h> +#include <linux/serial_8250.h> +#include <linux/ahci_platform.h> +#include <linux/clk.h> + +#include <mach/cputype.h> +#include <mach/common.h> +#include <mach/time.h> +#include <mach/da8xx.h> +#include <mach/cpuidle.h> + +#include "clock.h" + +#define DA8XX_TPCC_BASE 0x01c00000 +#define DA8XX_TPTC0_BASE 0x01c08000 +#define DA8XX_TPTC1_BASE 0x01c08400 +#define DA8XX_WDOG_BASE 0x01c21000 /* DA8XX_TIMER64P1_BASE */ +#define DA8XX_I2C0_BASE 0x01c22000 +#define DA8XX_RTC_BASE 0x01c23000 +#define DA8XX_MMCSD0_BASE 0x01c40000 +#define DA8XX_SPI0_BASE 0x01c41000 +#define DA830_SPI1_BASE 0x01e12000 +#define DA8XX_LCD_CNTRL_BASE 0x01e13000 +#define DA850_SATA_BASE 0x01e18000 +#define DA850_MMCSD1_BASE 0x01e1b000 +#define DA8XX_EMAC_CPPI_PORT_BASE 0x01e20000 +#define DA8XX_EMAC_CPGMACSS_BASE 0x01e22000 +#define DA8XX_EMAC_CPGMAC_BASE 0x01e23000 +#define DA8XX_EMAC_MDIO_BASE 0x01e24000 +#define DA8XX_I2C1_BASE 0x01e28000 +#define DA850_TPCC1_BASE 0x01e30000 +#define DA850_TPTC2_BASE 0x01e38000 +#define DA850_SPI1_BASE 0x01f0e000 +#define DA8XX_DDR2_CTL_BASE 0xb0000000 + +#define DA8XX_EMAC_CTRL_REG_OFFSET 0x3000 +#define DA8XX_EMAC_MOD_REG_OFFSET 0x2000 +#define DA8XX_EMAC_RAM_OFFSET 0x0000 +#define DA8XX_EMAC_CTRL_RAM_SIZE SZ_8K + +#define DA8XX_DMA_SPI0_RX EDMA_CTLR_CHAN(0, 14) +#define DA8XX_DMA_SPI0_TX EDMA_CTLR_CHAN(0, 15) +#define DA8XX_DMA_MMCSD0_RX EDMA_CTLR_CHAN(0, 16) +#define DA8XX_DMA_MMCSD0_TX EDMA_CTLR_CHAN(0, 17) +#define DA8XX_DMA_SPI1_RX EDMA_CTLR_CHAN(0, 18) +#define DA8XX_DMA_SPI1_TX EDMA_CTLR_CHAN(0, 19) +#define DA850_DMA_MMCSD1_RX EDMA_CTLR_CHAN(1, 28) +#define DA850_DMA_MMCSD1_TX EDMA_CTLR_CHAN(1, 29) + +void __iomem *da8xx_syscfg0_base; +void __iomem *da8xx_syscfg1_base; + +static struct plat_serial8250_port da8xx_serial_pdata[] = { + { + .mapbase = DA8XX_UART0_BASE, + .irq = IRQ_DA8XX_UARTINT0, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | + UPF_IOREMAP, + .iotype = UPIO_MEM, + .regshift = 2, + }, + { + .mapbase = DA8XX_UART1_BASE, + .irq = IRQ_DA8XX_UARTINT1, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | + UPF_IOREMAP, + .iotype = UPIO_MEM, + .regshift = 2, + }, + { + .mapbase = DA8XX_UART2_BASE, + .irq = IRQ_DA8XX_UARTINT2, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | + UPF_IOREMAP, + .iotype = UPIO_MEM, + .regshift = 2, + }, + { + .flags = 0, + }, +}; + +struct platform_device da8xx_serial_device = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM, + .dev = { + .platform_data = da8xx_serial_pdata, + }, +}; + +static const s8 da8xx_queue_tc_mapping[][2] = { + /* {event queue no, TC no} */ + {0, 0}, + {1, 1}, + {-1, -1} +}; + +static const s8 da8xx_queue_priority_mapping[][2] = { + /* {event queue no, Priority} */ + {0, 3}, + {1, 7}, + {-1, -1} +}; + +static const s8 da850_queue_tc_mapping[][2] = { + /* {event queue no, TC no} */ + {0, 0}, + {-1, -1} +}; + +static const s8 da850_queue_priority_mapping[][2] = { + /* {event queue no, Priority} */ + {0, 3}, + {-1, -1} +}; + +static struct edma_soc_info da830_edma_cc0_info = { + .n_channel = 32, + .n_region = 4, + .n_slot = 128, + .n_tc = 2, + .n_cc = 1, + .queue_tc_mapping = da8xx_queue_tc_mapping, + .queue_priority_mapping = da8xx_queue_priority_mapping, + .default_queue = EVENTQ_1, +}; + +static struct edma_soc_info *da830_edma_info[EDMA_MAX_CC] = { + &da830_edma_cc0_info, +}; + +static struct edma_soc_info da850_edma_cc_info[] = { + { + .n_channel = 32, + .n_region = 4, + .n_slot = 128, + .n_tc = 2, + .n_cc = 1, + .queue_tc_mapping = da8xx_queue_tc_mapping, + .queue_priority_mapping = da8xx_queue_priority_mapping, + .default_queue = EVENTQ_1, + }, + { + .n_channel = 32, + .n_region = 4, + .n_slot = 128, + .n_tc = 1, + .n_cc = 1, + .queue_tc_mapping = da850_queue_tc_mapping, + .queue_priority_mapping = da850_queue_priority_mapping, + .default_queue = EVENTQ_0, + }, +}; + +static struct edma_soc_info *da850_edma_info[EDMA_MAX_CC] = { + &da850_edma_cc_info[0], + &da850_edma_cc_info[1], +}; + +static struct resource da830_edma_resources[] = { + { + .name = "edma_cc0", + .start = DA8XX_TPCC_BASE, + .end = DA8XX_TPCC_BASE + SZ_32K - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "edma_tc0", + .start = DA8XX_TPTC0_BASE, + .end = DA8XX_TPTC0_BASE + SZ_1K - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "edma_tc1", + .start = DA8XX_TPTC1_BASE, + .end = DA8XX_TPTC1_BASE + SZ_1K - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "edma0", + .start = IRQ_DA8XX_CCINT0, + .flags = IORESOURCE_IRQ, + }, + { + .name = "edma0_err", + .start = IRQ_DA8XX_CCERRINT, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct resource da850_edma_resources[] = { + { + .name = "edma_cc0", + .start = DA8XX_TPCC_BASE, + .end = DA8XX_TPCC_BASE + SZ_32K - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "edma_tc0", + .start = DA8XX_TPTC0_BASE, + .end = DA8XX_TPTC0_BASE + SZ_1K - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "edma_tc1", + .start = DA8XX_TPTC1_BASE, + .end = DA8XX_TPTC1_BASE + SZ_1K - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "edma_cc1", + .start = DA850_TPCC1_BASE, + .end = DA850_TPCC1_BASE + SZ_32K - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "edma_tc2", + .start = DA850_TPTC2_BASE, + .end = DA850_TPTC2_BASE + SZ_1K - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "edma0", + .start = IRQ_DA8XX_CCINT0, + .flags = IORESOURCE_IRQ, + }, + { + .name = "edma0_err", + .start = IRQ_DA8XX_CCERRINT, + .flags = IORESOURCE_IRQ, + }, + { + .name = "edma1", + .start = IRQ_DA850_CCINT1, + .flags = IORESOURCE_IRQ, + }, + { + .name = "edma1_err", + .start = IRQ_DA850_CCERRINT1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device da830_edma_device = { + .name = "edma", + .id = -1, + .dev = { + .platform_data = da830_edma_info, + }, + .num_resources = ARRAY_SIZE(da830_edma_resources), + .resource = da830_edma_resources, +}; + +static struct platform_device da850_edma_device = { + .name = "edma", + .id = -1, + .dev = { + .platform_data = da850_edma_info, + }, + .num_resources = ARRAY_SIZE(da850_edma_resources), + .resource = da850_edma_resources, +}; + +int __init da830_register_edma(struct edma_rsv_info *rsv) +{ + da830_edma_cc0_info.rsv = rsv; + + return platform_device_register(&da830_edma_device); +} + +int __init da850_register_edma(struct edma_rsv_info *rsv[2]) +{ + if (rsv) { + da850_edma_cc_info[0].rsv = rsv[0]; + da850_edma_cc_info[1].rsv = rsv[1]; + } + + return platform_device_register(&da850_edma_device); +} + +static struct resource da8xx_i2c_resources0[] = { + { + .start = DA8XX_I2C0_BASE, + .end = DA8XX_I2C0_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_DA8XX_I2CINT0, + .end = IRQ_DA8XX_I2CINT0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device da8xx_i2c_device0 = { + .name = "i2c_davinci", + .id = 1, + .num_resources = ARRAY_SIZE(da8xx_i2c_resources0), + .resource = da8xx_i2c_resources0, +}; + +static struct resource da8xx_i2c_resources1[] = { + { + .start = DA8XX_I2C1_BASE, + .end = DA8XX_I2C1_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_DA8XX_I2CINT1, + .end = IRQ_DA8XX_I2CINT1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device da8xx_i2c_device1 = { + .name = "i2c_davinci", + .id = 2, + .num_resources = ARRAY_SIZE(da8xx_i2c_resources1), + .resource = da8xx_i2c_resources1, +}; + +int __init da8xx_register_i2c(int instance, + struct davinci_i2c_platform_data *pdata) +{ + struct platform_device *pdev; + + if (instance == 0) + pdev = &da8xx_i2c_device0; + else if (instance == 1) + pdev = &da8xx_i2c_device1; + else + return -EINVAL; + + pdev->dev.platform_data = pdata; + return platform_device_register(pdev); +} + +static struct resource da8xx_watchdog_resources[] = { + { + .start = DA8XX_WDOG_BASE, + .end = DA8XX_WDOG_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, +}; + +struct platform_device da8xx_wdt_device = { + .name = "watchdog", + .id = -1, + .num_resources = ARRAY_SIZE(da8xx_watchdog_resources), + .resource = da8xx_watchdog_resources, +}; + +void da8xx_restart(char mode, const char *cmd) +{ + davinci_watchdog_reset(&da8xx_wdt_device); +} + +int __init da8xx_register_watchdog(void) +{ + return platform_device_register(&da8xx_wdt_device); +} + +static struct resource da8xx_emac_resources[] = { + { + .start = DA8XX_EMAC_CPPI_PORT_BASE, + .end = DA8XX_EMAC_CPPI_PORT_BASE + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_DA8XX_C0_RX_THRESH_PULSE, + .end = IRQ_DA8XX_C0_RX_THRESH_PULSE, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_DA8XX_C0_RX_PULSE, + .end = IRQ_DA8XX_C0_RX_PULSE, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_DA8XX_C0_TX_PULSE, + .end = IRQ_DA8XX_C0_TX_PULSE, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_DA8XX_C0_MISC_PULSE, + .end = IRQ_DA8XX_C0_MISC_PULSE, + .flags = IORESOURCE_IRQ, + }, +}; + +struct emac_platform_data da8xx_emac_pdata = { + .ctrl_reg_offset = DA8XX_EMAC_CTRL_REG_OFFSET, + .ctrl_mod_reg_offset = DA8XX_EMAC_MOD_REG_OFFSET, + .ctrl_ram_offset = DA8XX_EMAC_RAM_OFFSET, + .ctrl_ram_size = DA8XX_EMAC_CTRL_RAM_SIZE, + .version = EMAC_VERSION_2, +}; + +static struct platform_device da8xx_emac_device = { + .name = "davinci_emac", + .id = 1, + .dev = { + .platform_data = &da8xx_emac_pdata, + }, + .num_resources = ARRAY_SIZE(da8xx_emac_resources), + .resource = da8xx_emac_resources, +}; + +static struct resource da8xx_mdio_resources[] = { + { + .start = DA8XX_EMAC_MDIO_BASE, + .end = DA8XX_EMAC_MDIO_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device da8xx_mdio_device = { + .name = "davinci_mdio", + .id = 0, + .num_resources = ARRAY_SIZE(da8xx_mdio_resources), + .resource = da8xx_mdio_resources, +}; + +int __init da8xx_register_emac(void) +{ + int ret; + + ret = platform_device_register(&da8xx_mdio_device); + if (ret < 0) + return ret; + ret = platform_device_register(&da8xx_emac_device); + if (ret < 0) + return ret; + ret = clk_add_alias(NULL, dev_name(&da8xx_mdio_device.dev), + NULL, &da8xx_emac_device.dev); + return ret; +} + +static struct resource da830_mcasp1_resources[] = { + { + .name = "mcasp1", + .start = DAVINCI_DA830_MCASP1_REG_BASE, + .end = DAVINCI_DA830_MCASP1_REG_BASE + (SZ_1K * 12) - 1, + .flags = IORESOURCE_MEM, + }, + /* TX event */ + { + .start = DAVINCI_DA830_DMA_MCASP1_AXEVT, + .end = DAVINCI_DA830_DMA_MCASP1_AXEVT, + .flags = IORESOURCE_DMA, + }, + /* RX event */ + { + .start = DAVINCI_DA830_DMA_MCASP1_AREVT, + .end = DAVINCI_DA830_DMA_MCASP1_AREVT, + .flags = IORESOURCE_DMA, + }, +}; + +static struct platform_device da830_mcasp1_device = { + .name = "davinci-mcasp", + .id = 1, + .num_resources = ARRAY_SIZE(da830_mcasp1_resources), + .resource = da830_mcasp1_resources, +}; + +static struct resource da850_mcasp_resources[] = { + { + .name = "mcasp", + .start = DAVINCI_DA8XX_MCASP0_REG_BASE, + .end = DAVINCI_DA8XX_MCASP0_REG_BASE + (SZ_1K * 12) - 1, + .flags = IORESOURCE_MEM, + }, + /* TX event */ + { + .start = DAVINCI_DA8XX_DMA_MCASP0_AXEVT, + .end = DAVINCI_DA8XX_DMA_MCASP0_AXEVT, + .flags = IORESOURCE_DMA, + }, + /* RX event */ + { + .start = DAVINCI_DA8XX_DMA_MCASP0_AREVT, + .end = DAVINCI_DA8XX_DMA_MCASP0_AREVT, + .flags = IORESOURCE_DMA, + }, +}; + +static struct platform_device da850_mcasp_device = { + .name = "davinci-mcasp", + .id = 0, + .num_resources = ARRAY_SIZE(da850_mcasp_resources), + .resource = da850_mcasp_resources, +}; + +static struct platform_device davinci_pcm_device = { + .name = "davinci-pcm-audio", + .id = -1, +}; + +void __init da8xx_register_mcasp(int id, struct snd_platform_data *pdata) +{ + platform_device_register(&davinci_pcm_device); + + /* DA830/OMAP-L137 has 3 instances of McASP */ + if (cpu_is_davinci_da830() && id == 1) { + da830_mcasp1_device.dev.platform_data = pdata; + platform_device_register(&da830_mcasp1_device); + } else if (cpu_is_davinci_da850()) { + da850_mcasp_device.dev.platform_data = pdata; + platform_device_register(&da850_mcasp_device); + } +} + +static const struct display_panel disp_panel = { + QVGA, + 16, + 16, + COLOR_ACTIVE, +}; + +static struct lcd_ctrl_config lcd_cfg = { + &disp_panel, + .ac_bias = 255, + .ac_bias_intrpt = 0, + .dma_burst_sz = 16, + .bpp = 16, + .fdd = 255, + .tft_alt_mode = 0, + .stn_565_mode = 0, + .mono_8bit_mode = 0, + .invert_line_clock = 1, + .invert_frm_clock = 1, + .sync_edge = 0, + .sync_ctrl = 1, + .raster_order = 0, +}; + +struct da8xx_lcdc_platform_data sharp_lcd035q3dg01_pdata = { + .manu_name = "sharp", + .controller_data = &lcd_cfg, + .type = "Sharp_LCD035Q3DG01", +}; + +struct da8xx_lcdc_platform_data sharp_lk043t1dg01_pdata = { + .manu_name = "sharp", + .controller_data = &lcd_cfg, + .type = "Sharp_LK043T1DG01", +}; + +static struct resource da8xx_lcdc_resources[] = { + [0] = { /* registers */ + .start = DA8XX_LCD_CNTRL_BASE, + .end = DA8XX_LCD_CNTRL_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { /* interrupt */ + .start = IRQ_DA8XX_LCDINT, + .end = IRQ_DA8XX_LCDINT, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device da8xx_lcdc_device = { + .name = "da8xx_lcdc", + .id = 0, + .num_resources = ARRAY_SIZE(da8xx_lcdc_resources), + .resource = da8xx_lcdc_resources, +}; + +int __init da8xx_register_lcdc(struct da8xx_lcdc_platform_data *pdata) +{ + da8xx_lcdc_device.dev.platform_data = pdata; + return platform_device_register(&da8xx_lcdc_device); +} + +static struct resource da8xx_mmcsd0_resources[] = { + { /* registers */ + .start = DA8XX_MMCSD0_BASE, + .end = DA8XX_MMCSD0_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + { /* interrupt */ + .start = IRQ_DA8XX_MMCSDINT0, + .end = IRQ_DA8XX_MMCSDINT0, + .flags = IORESOURCE_IRQ, + }, + { /* DMA RX */ + .start = DA8XX_DMA_MMCSD0_RX, + .end = DA8XX_DMA_MMCSD0_RX, + .flags = IORESOURCE_DMA, + }, + { /* DMA TX */ + .start = DA8XX_DMA_MMCSD0_TX, + .end = DA8XX_DMA_MMCSD0_TX, + .flags = IORESOURCE_DMA, + }, +}; + +static struct platform_device da8xx_mmcsd0_device = { + .name = "davinci_mmc", + .id = 0, + .num_resources = ARRAY_SIZE(da8xx_mmcsd0_resources), + .resource = da8xx_mmcsd0_resources, +}; + +int __init da8xx_register_mmcsd0(struct davinci_mmc_config *config) +{ + da8xx_mmcsd0_device.dev.platform_data = config; + return platform_device_register(&da8xx_mmcsd0_device); +} + +#ifdef CONFIG_ARCH_DAVINCI_DA850 +static struct resource da850_mmcsd1_resources[] = { + { /* registers */ + .start = DA850_MMCSD1_BASE, + .end = DA850_MMCSD1_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + { /* interrupt */ + .start = IRQ_DA850_MMCSDINT0_1, + .end = IRQ_DA850_MMCSDINT0_1, + .flags = IORESOURCE_IRQ, + }, + { /* DMA RX */ + .start = DA850_DMA_MMCSD1_RX, + .end = DA850_DMA_MMCSD1_RX, + .flags = IORESOURCE_DMA, + }, + { /* DMA TX */ + .start = DA850_DMA_MMCSD1_TX, + .end = DA850_DMA_MMCSD1_TX, + .flags = IORESOURCE_DMA, + }, +}; + +static struct platform_device da850_mmcsd1_device = { + .name = "davinci_mmc", + .id = 1, + .num_resources = ARRAY_SIZE(da850_mmcsd1_resources), + .resource = da850_mmcsd1_resources, +}; + +int __init da850_register_mmcsd1(struct davinci_mmc_config *config) +{ + da850_mmcsd1_device.dev.platform_data = config; + return platform_device_register(&da850_mmcsd1_device); +} +#endif + +static struct resource da8xx_rtc_resources[] = { + { + .start = DA8XX_RTC_BASE, + .end = DA8XX_RTC_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + { /* timer irq */ + .start = IRQ_DA8XX_RTC, + .end = IRQ_DA8XX_RTC, + .flags = IORESOURCE_IRQ, + }, + { /* alarm irq */ + .start = IRQ_DA8XX_RTC, + .end = IRQ_DA8XX_RTC, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device da8xx_rtc_device = { + .name = "omap_rtc", + .id = -1, + .num_resources = ARRAY_SIZE(da8xx_rtc_resources), + .resource = da8xx_rtc_resources, +}; + +int da8xx_register_rtc(void) +{ + int ret; + void __iomem *base; + + base = ioremap(DA8XX_RTC_BASE, SZ_4K); + if (WARN_ON(!base)) + return -ENOMEM; + + /* Unlock the rtc's registers */ + __raw_writel(0x83e70b13, base + 0x6c); + __raw_writel(0x95a4f1e0, base + 0x70); + + iounmap(base); + + ret = platform_device_register(&da8xx_rtc_device); + if (!ret) + /* Atleast on DA850, RTC is a wakeup source */ + device_init_wakeup(&da8xx_rtc_device.dev, true); + + return ret; +} + +static void __iomem *da8xx_ddr2_ctlr_base; +void __iomem * __init da8xx_get_mem_ctlr(void) +{ + if (da8xx_ddr2_ctlr_base) + return da8xx_ddr2_ctlr_base; + + da8xx_ddr2_ctlr_base = ioremap(DA8XX_DDR2_CTL_BASE, SZ_32K); + if (!da8xx_ddr2_ctlr_base) + pr_warning("%s: Unable to map DDR2 controller", __func__); + + return da8xx_ddr2_ctlr_base; +} + +static struct resource da8xx_cpuidle_resources[] = { + { + .start = DA8XX_DDR2_CTL_BASE, + .end = DA8XX_DDR2_CTL_BASE + SZ_32K - 1, + .flags = IORESOURCE_MEM, + }, +}; + +/* DA8XX devices support DDR2 power down */ +static struct davinci_cpuidle_config da8xx_cpuidle_pdata = { + .ddr2_pdown = 1, +}; + + +static struct platform_device da8xx_cpuidle_device = { + .name = "cpuidle-davinci", + .num_resources = ARRAY_SIZE(da8xx_cpuidle_resources), + .resource = da8xx_cpuidle_resources, + .dev = { + .platform_data = &da8xx_cpuidle_pdata, + }, +}; + +int __init da8xx_register_cpuidle(void) +{ + da8xx_cpuidle_pdata.ddr2_ctlr_base = da8xx_get_mem_ctlr(); + + return platform_device_register(&da8xx_cpuidle_device); +} + +static struct resource da8xx_spi0_resources[] = { + [0] = { + .start = DA8XX_SPI0_BASE, + .end = DA8XX_SPI0_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_DA8XX_SPINT0, + .end = IRQ_DA8XX_SPINT0, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = DA8XX_DMA_SPI0_RX, + .end = DA8XX_DMA_SPI0_RX, + .flags = IORESOURCE_DMA, + }, + [3] = { + .start = DA8XX_DMA_SPI0_TX, + .end = DA8XX_DMA_SPI0_TX, + .flags = IORESOURCE_DMA, + }, +}; + +static struct resource da8xx_spi1_resources[] = { + [0] = { + .start = DA830_SPI1_BASE, + .end = DA830_SPI1_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_DA8XX_SPINT1, + .end = IRQ_DA8XX_SPINT1, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = DA8XX_DMA_SPI1_RX, + .end = DA8XX_DMA_SPI1_RX, + .flags = IORESOURCE_DMA, + }, + [3] = { + .start = DA8XX_DMA_SPI1_TX, + .end = DA8XX_DMA_SPI1_TX, + .flags = IORESOURCE_DMA, + }, +}; + +struct davinci_spi_platform_data da8xx_spi_pdata[] = { + [0] = { + .version = SPI_VERSION_2, + .intr_line = 1, + .dma_event_q = EVENTQ_0, + }, + [1] = { + .version = SPI_VERSION_2, + .intr_line = 1, + .dma_event_q = EVENTQ_0, + }, +}; + +static struct platform_device da8xx_spi_device[] = { + [0] = { + .name = "spi_davinci", + .id = 0, + .num_resources = ARRAY_SIZE(da8xx_spi0_resources), + .resource = da8xx_spi0_resources, + .dev = { + .platform_data = &da8xx_spi_pdata[0], + }, + }, + [1] = { + .name = "spi_davinci", + .id = 1, + .num_resources = ARRAY_SIZE(da8xx_spi1_resources), + .resource = da8xx_spi1_resources, + .dev = { + .platform_data = &da8xx_spi_pdata[1], + }, + }, +}; + +int __init da8xx_register_spi(int instance, struct spi_board_info *info, + unsigned len) +{ + int ret; + + if (instance < 0 || instance > 1) + return -EINVAL; + + ret = spi_register_board_info(info, len); + if (ret) + pr_warning("%s: failed to register board info for spi %d :" + " %d\n", __func__, instance, ret); + + da8xx_spi_pdata[instance].num_chipselect = len; + + if (instance == 1 && cpu_is_davinci_da850()) { + da8xx_spi1_resources[0].start = DA850_SPI1_BASE; + da8xx_spi1_resources[0].end = DA850_SPI1_BASE + SZ_4K - 1; + } + + return platform_device_register(&da8xx_spi_device[instance]); +} + +#ifdef CONFIG_ARCH_DAVINCI_DA850 + +static struct resource da850_sata_resources[] = { + { + .start = DA850_SATA_BASE, + .end = DA850_SATA_BASE + 0x1fff, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_DA850_SATAINT, + .flags = IORESOURCE_IRQ, + }, +}; + +/* SATA PHY Control Register offset from AHCI base */ +#define SATA_P0PHYCR_REG 0x178 + +#define SATA_PHY_MPY(x) ((x) << 0) +#define SATA_PHY_LOS(x) ((x) << 6) +#define SATA_PHY_RXCDR(x) ((x) << 10) +#define SATA_PHY_RXEQ(x) ((x) << 13) +#define SATA_PHY_TXSWING(x) ((x) << 19) +#define SATA_PHY_ENPLL(x) ((x) << 31) + +static struct clk *da850_sata_clk; +static unsigned long da850_sata_refclkpn; + +/* Supported DA850 SATA crystal frequencies */ +#define KHZ_TO_HZ(freq) ((freq) * 1000) +static unsigned long da850_sata_xtal[] = { + KHZ_TO_HZ(300000), + KHZ_TO_HZ(250000), + 0, /* Reserved */ + KHZ_TO_HZ(187500), + KHZ_TO_HZ(150000), + KHZ_TO_HZ(125000), + KHZ_TO_HZ(120000), + KHZ_TO_HZ(100000), + KHZ_TO_HZ(75000), + KHZ_TO_HZ(60000), +}; + +static int da850_sata_init(struct device *dev, void __iomem *addr) +{ + int i, ret; + unsigned int val; + + da850_sata_clk = clk_get(dev, NULL); + if (IS_ERR(da850_sata_clk)) + return PTR_ERR(da850_sata_clk); + + ret = clk_enable(da850_sata_clk); + if (ret) + goto err0; + + /* Enable SATA clock receiver */ + val = __raw_readl(DA8XX_SYSCFG1_VIRT(DA8XX_PWRDN_REG)); + val &= ~BIT(0); + __raw_writel(val, DA8XX_SYSCFG1_VIRT(DA8XX_PWRDN_REG)); + + /* Get the multiplier needed for 1.5GHz PLL output */ + for (i = 0; i < ARRAY_SIZE(da850_sata_xtal); i++) + if (da850_sata_xtal[i] == da850_sata_refclkpn) + break; + + if (i == ARRAY_SIZE(da850_sata_xtal)) { + ret = -EINVAL; + goto err1; + } + + val = SATA_PHY_MPY(i + 1) | + SATA_PHY_LOS(1) | + SATA_PHY_RXCDR(4) | + SATA_PHY_RXEQ(1) | + SATA_PHY_TXSWING(3) | + SATA_PHY_ENPLL(1); + + __raw_writel(val, addr + SATA_P0PHYCR_REG); + + return 0; + +err1: + clk_disable(da850_sata_clk); +err0: + clk_put(da850_sata_clk); + return ret; +} + +static void da850_sata_exit(struct device *dev) +{ + clk_disable(da850_sata_clk); + clk_put(da850_sata_clk); +} + +static struct ahci_platform_data da850_sata_pdata = { + .init = da850_sata_init, + .exit = da850_sata_exit, +}; + +static u64 da850_sata_dmamask = DMA_BIT_MASK(32); + +static struct platform_device da850_sata_device = { + .name = "ahci", + .id = -1, + .dev = { + .platform_data = &da850_sata_pdata, + .dma_mask = &da850_sata_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .num_resources = ARRAY_SIZE(da850_sata_resources), + .resource = da850_sata_resources, +}; + +int __init da850_register_sata(unsigned long refclkpn) +{ + da850_sata_refclkpn = refclkpn; + if (!da850_sata_refclkpn) + return -EINVAL; + + return platform_device_register(&da850_sata_device); +} +#endif diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/devices-tnetv107x.c b/ANDROID_3.4.5/arch/arm/mach-davinci/devices-tnetv107x.c new file mode 100644 index 00000000..29b17f7d --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/devices-tnetv107x.c @@ -0,0 +1,409 @@ +/* + * Texas Instruments TNETV107X SoC devices + * + * Copyright (C) 2010 Texas Instruments + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/dma-mapping.h> +#include <linux/clk.h> +#include <linux/slab.h> + +#include <mach/common.h> +#include <mach/irqs.h> +#include <mach/edma.h> +#include <mach/tnetv107x.h> + +#include "clock.h" + +/* Base addresses for on-chip devices */ +#define TNETV107X_TPCC_BASE 0x01c00000 +#define TNETV107X_TPTC0_BASE 0x01c10000 +#define TNETV107X_TPTC1_BASE 0x01c10400 +#define TNETV107X_WDOG_BASE 0x08086700 +#define TNETV107X_TSC_BASE 0x08088500 +#define TNETV107X_SDIO0_BASE 0x08088700 +#define TNETV107X_SDIO1_BASE 0x08088800 +#define TNETV107X_KEYPAD_BASE 0x08088a00 +#define TNETV107X_SSP_BASE 0x08088c00 +#define TNETV107X_ASYNC_EMIF_CNTRL_BASE 0x08200000 +#define TNETV107X_ASYNC_EMIF_DATA_CE0_BASE 0x30000000 +#define TNETV107X_ASYNC_EMIF_DATA_CE1_BASE 0x40000000 +#define TNETV107X_ASYNC_EMIF_DATA_CE2_BASE 0x44000000 +#define TNETV107X_ASYNC_EMIF_DATA_CE3_BASE 0x48000000 + +/* TNETV107X specific EDMA3 information */ +#define EDMA_TNETV107X_NUM_DMACH 64 +#define EDMA_TNETV107X_NUM_TCC 64 +#define EDMA_TNETV107X_NUM_PARAMENTRY 128 +#define EDMA_TNETV107X_NUM_EVQUE 2 +#define EDMA_TNETV107X_NUM_TC 2 +#define EDMA_TNETV107X_CHMAP_EXIST 0 +#define EDMA_TNETV107X_NUM_REGIONS 4 +#define TNETV107X_DMACH2EVENT_MAP0 0x3C0CE000u +#define TNETV107X_DMACH2EVENT_MAP1 0x000FFFFFu + +#define TNETV107X_DMACH_SDIO0_RX 26 +#define TNETV107X_DMACH_SDIO0_TX 27 +#define TNETV107X_DMACH_SDIO1_RX 28 +#define TNETV107X_DMACH_SDIO1_TX 29 + +static const s8 edma_tc_mapping[][2] = { + /* event queue no TC no */ + { 0, 0 }, + { 1, 1 }, + { -1, -1 } +}; + +static const s8 edma_priority_mapping[][2] = { + /* event queue no Prio */ + { 0, 3 }, + { 1, 7 }, + { -1, -1 } +}; + +static struct edma_soc_info edma_cc0_info = { + .n_channel = EDMA_TNETV107X_NUM_DMACH, + .n_region = EDMA_TNETV107X_NUM_REGIONS, + .n_slot = EDMA_TNETV107X_NUM_PARAMENTRY, + .n_tc = EDMA_TNETV107X_NUM_TC, + .n_cc = 1, + .queue_tc_mapping = edma_tc_mapping, + .queue_priority_mapping = edma_priority_mapping, + .default_queue = EVENTQ_1, +}; + +static struct edma_soc_info *tnetv107x_edma_info[EDMA_MAX_CC] = { + &edma_cc0_info, +}; + +static struct resource edma_resources[] = { + { + .name = "edma_cc0", + .start = TNETV107X_TPCC_BASE, + .end = TNETV107X_TPCC_BASE + SZ_32K - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "edma_tc0", + .start = TNETV107X_TPTC0_BASE, + .end = TNETV107X_TPTC0_BASE + SZ_1K - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "edma_tc1", + .start = TNETV107X_TPTC1_BASE, + .end = TNETV107X_TPTC1_BASE + SZ_1K - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "edma0", + .start = IRQ_TNETV107X_TPCC, + .flags = IORESOURCE_IRQ, + }, + { + .name = "edma0_err", + .start = IRQ_TNETV107X_TPCC_ERR, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device edma_device = { + .name = "edma", + .id = -1, + .num_resources = ARRAY_SIZE(edma_resources), + .resource = edma_resources, + .dev.platform_data = tnetv107x_edma_info, +}; + +static struct plat_serial8250_port serial_data[] = { + { + .mapbase = TNETV107X_UART0_BASE, + .irq = IRQ_TNETV107X_UART0, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | + UPF_FIXED_TYPE | UPF_IOREMAP, + .type = PORT_AR7, + .iotype = UPIO_MEM32, + .regshift = 2, + }, + { + .mapbase = TNETV107X_UART1_BASE, + .irq = IRQ_TNETV107X_UART1, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | + UPF_FIXED_TYPE | UPF_IOREMAP, + .type = PORT_AR7, + .iotype = UPIO_MEM32, + .regshift = 2, + }, + { + .mapbase = TNETV107X_UART2_BASE, + .irq = IRQ_TNETV107X_UART2, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | + UPF_FIXED_TYPE | UPF_IOREMAP, + .type = PORT_AR7, + .iotype = UPIO_MEM32, + .regshift = 2, + }, + { + .flags = 0, + }, +}; + +struct platform_device tnetv107x_serial_device = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM, + .dev.platform_data = serial_data, +}; + +static struct resource mmc0_resources[] = { + { /* Memory mapped registers */ + .start = TNETV107X_SDIO0_BASE, + .end = TNETV107X_SDIO0_BASE + 0x0ff, + .flags = IORESOURCE_MEM + }, + { /* MMC interrupt */ + .start = IRQ_TNETV107X_MMC0, + .flags = IORESOURCE_IRQ + }, + { /* SDIO interrupt */ + .start = IRQ_TNETV107X_SDIO0, + .flags = IORESOURCE_IRQ + }, + { /* DMA RX */ + .start = EDMA_CTLR_CHAN(0, TNETV107X_DMACH_SDIO0_RX), + .flags = IORESOURCE_DMA + }, + { /* DMA TX */ + .start = EDMA_CTLR_CHAN(0, TNETV107X_DMACH_SDIO0_TX), + .flags = IORESOURCE_DMA + }, +}; + +static struct resource mmc1_resources[] = { + { /* Memory mapped registers */ + .start = TNETV107X_SDIO1_BASE, + .end = TNETV107X_SDIO1_BASE + 0x0ff, + .flags = IORESOURCE_MEM + }, + { /* MMC interrupt */ + .start = IRQ_TNETV107X_MMC1, + .flags = IORESOURCE_IRQ + }, + { /* SDIO interrupt */ + .start = IRQ_TNETV107X_SDIO1, + .flags = IORESOURCE_IRQ + }, + { /* DMA RX */ + .start = EDMA_CTLR_CHAN(0, TNETV107X_DMACH_SDIO1_RX), + .flags = IORESOURCE_DMA + }, + { /* DMA TX */ + .start = EDMA_CTLR_CHAN(0, TNETV107X_DMACH_SDIO1_TX), + .flags = IORESOURCE_DMA + }, +}; + +static u64 mmc0_dma_mask = DMA_BIT_MASK(32); +static u64 mmc1_dma_mask = DMA_BIT_MASK(32); + +static struct platform_device mmc_devices[2] = { + { + .name = "davinci_mmc", + .id = 0, + .dev = { + .dma_mask = &mmc0_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .num_resources = ARRAY_SIZE(mmc0_resources), + .resource = mmc0_resources + }, + { + .name = "davinci_mmc", + .id = 1, + .dev = { + .dma_mask = &mmc1_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .num_resources = ARRAY_SIZE(mmc1_resources), + .resource = mmc1_resources + }, +}; + +static const u32 emif_windows[] = { + TNETV107X_ASYNC_EMIF_DATA_CE0_BASE, TNETV107X_ASYNC_EMIF_DATA_CE1_BASE, + TNETV107X_ASYNC_EMIF_DATA_CE2_BASE, TNETV107X_ASYNC_EMIF_DATA_CE3_BASE, +}; + +static const u32 emif_window_sizes[] = { SZ_256M, SZ_64M, SZ_64M, SZ_64M }; + +static struct resource wdt_resources[] = { + { + .start = TNETV107X_WDOG_BASE, + .end = TNETV107X_WDOG_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, +}; + +struct platform_device tnetv107x_wdt_device = { + .name = "tnetv107x_wdt", + .id = 0, + .num_resources = ARRAY_SIZE(wdt_resources), + .resource = wdt_resources, +}; + +static int __init nand_init(int chipsel, struct davinci_nand_pdata *data) +{ + struct resource res[2]; + struct platform_device *pdev; + u32 range; + int ret; + + /* Figure out the resource range from the ale/cle masks */ + range = max(data->mask_cle, data->mask_ale); + range = PAGE_ALIGN(range + 4) - 1; + + if (range >= emif_window_sizes[chipsel]) + return -EINVAL; + + pdev = kzalloc(sizeof(*pdev), GFP_KERNEL); + if (!pdev) + return -ENOMEM; + + pdev->name = "davinci_nand"; + pdev->id = chipsel; + pdev->dev.platform_data = data; + + memset(res, 0, sizeof(res)); + + res[0].start = emif_windows[chipsel]; + res[0].end = res[0].start + range; + res[0].flags = IORESOURCE_MEM; + + res[1].start = TNETV107X_ASYNC_EMIF_CNTRL_BASE; + res[1].end = res[1].start + SZ_4K - 1; + res[1].flags = IORESOURCE_MEM; + + ret = platform_device_add_resources(pdev, res, ARRAY_SIZE(res)); + if (ret < 0) { + kfree(pdev); + return ret; + } + + return platform_device_register(pdev); +} + +static struct resource keypad_resources[] = { + { + .start = TNETV107X_KEYPAD_BASE, + .end = TNETV107X_KEYPAD_BASE + 0xff, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_TNETV107X_KEYPAD, + .flags = IORESOURCE_IRQ, + .name = "press", + }, + { + .start = IRQ_TNETV107X_KEYPAD_FREE, + .flags = IORESOURCE_IRQ, + .name = "release", + }, +}; + +static struct platform_device keypad_device = { + .name = "tnetv107x-keypad", + .num_resources = ARRAY_SIZE(keypad_resources), + .resource = keypad_resources, +}; + +static struct resource tsc_resources[] = { + { + .start = TNETV107X_TSC_BASE, + .end = TNETV107X_TSC_BASE + 0xff, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_TNETV107X_TSC, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device tsc_device = { + .name = "tnetv107x-ts", + .num_resources = ARRAY_SIZE(tsc_resources), + .resource = tsc_resources, +}; + +static struct resource ssp_resources[] = { + { + .start = TNETV107X_SSP_BASE, + .end = TNETV107X_SSP_BASE + 0x1ff, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_TNETV107X_SSP, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device ssp_device = { + .name = "ti-ssp", + .id = -1, + .num_resources = ARRAY_SIZE(ssp_resources), + .resource = ssp_resources, +}; + +void __init tnetv107x_devices_init(struct tnetv107x_device_info *info) +{ + int i, error; + struct clk *tsc_clk; + + /* + * The reset defaults for tnetv107x tsc clock divider is set too high. + * This forces the clock down to a range that allows the ADC to + * complete sample conversion in time. + */ + tsc_clk = clk_get(NULL, "sys_tsc_clk"); + if (tsc_clk) { + error = clk_set_rate(tsc_clk, 5000000); + WARN_ON(error < 0); + clk_put(tsc_clk); + } + + platform_device_register(&edma_device); + platform_device_register(&tnetv107x_wdt_device); + platform_device_register(&tsc_device); + + if (info->serial_config) + davinci_serial_init(info->serial_config); + + for (i = 0; i < 2; i++) + if (info->mmc_config[i]) { + mmc_devices[i].dev.platform_data = info->mmc_config[i]; + platform_device_register(&mmc_devices[i]); + } + + for (i = 0; i < 4; i++) + if (info->nand_config[i]) + nand_init(i, info->nand_config[i]); + + if (info->keypad_config) { + keypad_device.dev.platform_data = info->keypad_config; + platform_device_register(&keypad_device); + } + + if (info->ssp_config) { + ssp_device.dev.platform_data = info->ssp_config; + platform_device_register(&ssp_device); + } +} diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/devices.c b/ANDROID_3.4.5/arch/arm/mach-davinci/devices.c new file mode 100644 index 00000000..d2f96662 --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/devices.c @@ -0,0 +1,354 @@ +/* + * mach-davinci/devices.c + * + * DaVinci platform device setup/initialization + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/dma-mapping.h> +#include <linux/io.h> + +#include <mach/hardware.h> +#include <mach/i2c.h> +#include <mach/irqs.h> +#include <mach/cputype.h> +#include <mach/mux.h> +#include <mach/edma.h> +#include <mach/mmc.h> +#include <mach/time.h> + +#include "davinci.h" +#include "clock.h" + +#define DAVINCI_I2C_BASE 0x01C21000 +#define DAVINCI_ATA_BASE 0x01C66000 +#define DAVINCI_MMCSD0_BASE 0x01E10000 +#define DM355_MMCSD0_BASE 0x01E11000 +#define DM355_MMCSD1_BASE 0x01E00000 +#define DM365_MMCSD0_BASE 0x01D11000 +#define DM365_MMCSD1_BASE 0x01D00000 + +void __iomem *davinci_sysmod_base; + +void davinci_map_sysmod(void) +{ + davinci_sysmod_base = ioremap_nocache(DAVINCI_SYSTEM_MODULE_BASE, + 0x800); + /* + * Throw a bug since a lot of board initialization code depends + * on system module availability. ioremap() failing this early + * need careful looking into anyway. + */ + BUG_ON(!davinci_sysmod_base); +} + +static struct resource i2c_resources[] = { + { + .start = DAVINCI_I2C_BASE, + .end = DAVINCI_I2C_BASE + 0x40, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_I2C, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device davinci_i2c_device = { + .name = "i2c_davinci", + .id = 1, + .num_resources = ARRAY_SIZE(i2c_resources), + .resource = i2c_resources, +}; + +void __init davinci_init_i2c(struct davinci_i2c_platform_data *pdata) +{ + if (cpu_is_davinci_dm644x()) + davinci_cfg_reg(DM644X_I2C); + + davinci_i2c_device.dev.platform_data = pdata; + (void) platform_device_register(&davinci_i2c_device); +} + +static struct resource ide_resources[] = { + { + .start = DAVINCI_ATA_BASE, + .end = DAVINCI_ATA_BASE + 0x7ff, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_IDE, + .end = IRQ_IDE, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 ide_dma_mask = DMA_BIT_MASK(32); + +static struct platform_device ide_device = { + .name = "palm_bk3710", + .id = -1, + .resource = ide_resources, + .num_resources = ARRAY_SIZE(ide_resources), + .dev = { + .dma_mask = &ide_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +void __init davinci_init_ide(void) +{ + if (cpu_is_davinci_dm644x()) { + davinci_cfg_reg(DM644X_HPIEN_DISABLE); + davinci_cfg_reg(DM644X_ATAEN); + davinci_cfg_reg(DM644X_HDIREN); + } else if (cpu_is_davinci_dm646x()) { + /* IRQ_DM646X_IDE is the same as IRQ_IDE */ + davinci_cfg_reg(DM646X_ATAEN); + } else { + WARN_ON(1); + return; + } + + platform_device_register(&ide_device); +} + +#if defined(CONFIG_MMC_DAVINCI) || defined(CONFIG_MMC_DAVINCI_MODULE) + +static u64 mmcsd0_dma_mask = DMA_BIT_MASK(32); + +static struct resource mmcsd0_resources[] = { + { + /* different on dm355 */ + .start = DAVINCI_MMCSD0_BASE, + .end = DAVINCI_MMCSD0_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + /* IRQs: MMC/SD, then SDIO */ + { + .start = IRQ_MMCINT, + .flags = IORESOURCE_IRQ, + }, { + /* different on dm355 */ + .start = IRQ_SDIOINT, + .flags = IORESOURCE_IRQ, + }, + /* DMA channels: RX, then TX */ + { + .start = EDMA_CTLR_CHAN(0, DAVINCI_DMA_MMCRXEVT), + .flags = IORESOURCE_DMA, + }, { + .start = EDMA_CTLR_CHAN(0, DAVINCI_DMA_MMCTXEVT), + .flags = IORESOURCE_DMA, + }, +}; + +static struct platform_device davinci_mmcsd0_device = { + .name = "davinci_mmc", + .id = 0, + .dev = { + .dma_mask = &mmcsd0_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .num_resources = ARRAY_SIZE(mmcsd0_resources), + .resource = mmcsd0_resources, +}; + +static u64 mmcsd1_dma_mask = DMA_BIT_MASK(32); + +static struct resource mmcsd1_resources[] = { + { + .start = DM355_MMCSD1_BASE, + .end = DM355_MMCSD1_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + /* IRQs: MMC/SD, then SDIO */ + { + .start = IRQ_DM355_MMCINT1, + .flags = IORESOURCE_IRQ, + }, { + .start = IRQ_DM355_SDIOINT1, + .flags = IORESOURCE_IRQ, + }, + /* DMA channels: RX, then TX */ + { + .start = EDMA_CTLR_CHAN(0, 30), /* rx */ + .flags = IORESOURCE_DMA, + }, { + .start = EDMA_CTLR_CHAN(0, 31), /* tx */ + .flags = IORESOURCE_DMA, + }, +}; + +static struct platform_device davinci_mmcsd1_device = { + .name = "davinci_mmc", + .id = 1, + .dev = { + .dma_mask = &mmcsd1_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .num_resources = ARRAY_SIZE(mmcsd1_resources), + .resource = mmcsd1_resources, +}; + + +void __init davinci_setup_mmc(int module, struct davinci_mmc_config *config) +{ + struct platform_device *pdev = NULL; + + if (WARN_ON(cpu_is_davinci_dm646x())) + return; + + /* REVISIT: update PINMUX, ARM_IRQMUX, and EDMA_EVTMUX here too; + * for example if MMCSD1 is used for SDIO, maybe DAT2 is unused. + * + * FIXME dm6441 (no MMC/SD), dm357 (one), and dm335 (two) are + * not handled right here ... + */ + switch (module) { + case 1: + if (cpu_is_davinci_dm355()) { + /* REVISIT we may not need all these pins if e.g. this + * is a hard-wired SDIO device... + */ + davinci_cfg_reg(DM355_SD1_CMD); + davinci_cfg_reg(DM355_SD1_CLK); + davinci_cfg_reg(DM355_SD1_DATA0); + davinci_cfg_reg(DM355_SD1_DATA1); + davinci_cfg_reg(DM355_SD1_DATA2); + davinci_cfg_reg(DM355_SD1_DATA3); + } else if (cpu_is_davinci_dm365()) { + /* Configure pull down control */ + unsigned v; + + v = __raw_readl(DAVINCI_SYSMOD_VIRT(SYSMOD_PUPDCTL1)); + __raw_writel(v & ~0xfc0, + DAVINCI_SYSMOD_VIRT(SYSMOD_PUPDCTL1)); + + mmcsd1_resources[0].start = DM365_MMCSD1_BASE; + mmcsd1_resources[0].end = DM365_MMCSD1_BASE + + SZ_4K - 1; + mmcsd1_resources[2].start = IRQ_DM365_SDIOINT1; + } else + break; + + pdev = &davinci_mmcsd1_device; + break; + case 0: + if (cpu_is_davinci_dm355()) { + mmcsd0_resources[0].start = DM355_MMCSD0_BASE; + mmcsd0_resources[0].end = DM355_MMCSD0_BASE + SZ_4K - 1; + mmcsd0_resources[2].start = IRQ_DM355_SDIOINT0; + + /* expose all 6 MMC0 signals: CLK, CMD, DATA[0..3] */ + davinci_cfg_reg(DM355_MMCSD0); + + /* enable RX EDMA */ + davinci_cfg_reg(DM355_EVT26_MMC0_RX); + } else if (cpu_is_davinci_dm365()) { + mmcsd0_resources[0].start = DM365_MMCSD0_BASE; + mmcsd0_resources[0].end = DM365_MMCSD0_BASE + + SZ_4K - 1; + mmcsd0_resources[2].start = IRQ_DM365_SDIOINT0; + } else if (cpu_is_davinci_dm644x()) { + /* REVISIT: should this be in board-init code? */ + /* Power-on 3.3V IO cells */ + __raw_writel(0, + DAVINCI_SYSMOD_VIRT(SYSMOD_VDD3P3VPWDN)); + /*Set up the pull regiter for MMC */ + davinci_cfg_reg(DM644X_MSTK); + } + + pdev = &davinci_mmcsd0_device; + break; + } + + if (WARN_ON(!pdev)) + return; + + pdev->dev.platform_data = config; + platform_device_register(pdev); +} + +#else + +void __init davinci_setup_mmc(int module, struct davinci_mmc_config *config) +{ +} + +#endif + +/*-------------------------------------------------------------------------*/ + +static struct resource wdt_resources[] = { + { + .start = DAVINCI_WDOG_BASE, + .end = DAVINCI_WDOG_BASE + SZ_1K - 1, + .flags = IORESOURCE_MEM, + }, +}; + +struct platform_device davinci_wdt_device = { + .name = "watchdog", + .id = -1, + .num_resources = ARRAY_SIZE(wdt_resources), + .resource = wdt_resources, +}; + +void davinci_restart(char mode, const char *cmd) +{ + davinci_watchdog_reset(&davinci_wdt_device); +} + +static void davinci_init_wdt(void) +{ + platform_device_register(&davinci_wdt_device); +} + +/*-------------------------------------------------------------------------*/ + +static struct platform_device davinci_pcm_device = { + .name = "davinci-pcm-audio", + .id = -1, +}; + +static void davinci_init_pcm(void) +{ + platform_device_register(&davinci_pcm_device); +} + +/*-------------------------------------------------------------------------*/ + +struct davinci_timer_instance davinci_timer_instance[2] = { + { + .base = DAVINCI_TIMER0_BASE, + .bottom_irq = IRQ_TINT0_TINT12, + .top_irq = IRQ_TINT0_TINT34, + }, + { + .base = DAVINCI_TIMER1_BASE, + .bottom_irq = IRQ_TINT1_TINT12, + .top_irq = IRQ_TINT1_TINT34, + }, +}; + +/*-------------------------------------------------------------------------*/ + +static int __init davinci_init_devices(void) +{ + /* please keep these calls, and their implementations above, + * in alphabetical order so they're easier to sort through. + */ + davinci_init_pcm(); + davinci_init_wdt(); + + return 0; +} +arch_initcall(davinci_init_devices); + diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/dm355.c b/ANDROID_3.4.5/arch/arm/mach-davinci/dm355.c new file mode 100644 index 00000000..fd3d09aa --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/dm355.c @@ -0,0 +1,893 @@ +/* + * TI DaVinci DM355 chip specific setup + * + * Author: Kevin Hilman, Deep Root Systems, LLC + * + * 2007 (c) Deep Root Systems, LLC. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ +#include <linux/init.h> +#include <linux/clk.h> +#include <linux/serial_8250.h> +#include <linux/platform_device.h> +#include <linux/dma-mapping.h> + +#include <linux/spi/spi.h> + +#include <asm/mach/map.h> + +#include <mach/cputype.h> +#include <mach/edma.h> +#include <mach/psc.h> +#include <mach/mux.h> +#include <mach/irqs.h> +#include <mach/time.h> +#include <mach/serial.h> +#include <mach/common.h> +#include <mach/asp.h> +#include <mach/spi.h> +#include <mach/gpio-davinci.h> + +#include "davinci.h" +#include "clock.h" +#include "mux.h" + +#define DM355_UART2_BASE (IO_PHYS + 0x206000) + +/* + * Device specific clocks + */ +#define DM355_REF_FREQ 24000000 /* 24 or 36 MHz */ + +static struct pll_data pll1_data = { + .num = 1, + .phys_base = DAVINCI_PLL1_BASE, + .flags = PLL_HAS_PREDIV | PLL_HAS_POSTDIV, +}; + +static struct pll_data pll2_data = { + .num = 2, + .phys_base = DAVINCI_PLL2_BASE, + .flags = PLL_HAS_PREDIV, +}; + +static struct clk ref_clk = { + .name = "ref_clk", + /* FIXME -- crystal rate is board-specific */ + .rate = DM355_REF_FREQ, +}; + +static struct clk pll1_clk = { + .name = "pll1", + .parent = &ref_clk, + .flags = CLK_PLL, + .pll_data = &pll1_data, +}; + +static struct clk pll1_aux_clk = { + .name = "pll1_aux_clk", + .parent = &pll1_clk, + .flags = CLK_PLL | PRE_PLL, +}; + +static struct clk pll1_sysclk1 = { + .name = "pll1_sysclk1", + .parent = &pll1_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV1, +}; + +static struct clk pll1_sysclk2 = { + .name = "pll1_sysclk2", + .parent = &pll1_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV2, +}; + +static struct clk pll1_sysclk3 = { + .name = "pll1_sysclk3", + .parent = &pll1_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV3, +}; + +static struct clk pll1_sysclk4 = { + .name = "pll1_sysclk4", + .parent = &pll1_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV4, +}; + +static struct clk pll1_sysclkbp = { + .name = "pll1_sysclkbp", + .parent = &pll1_clk, + .flags = CLK_PLL | PRE_PLL, + .div_reg = BPDIV +}; + +static struct clk vpss_dac_clk = { + .name = "vpss_dac", + .parent = &pll1_sysclk3, + .lpsc = DM355_LPSC_VPSS_DAC, +}; + +static struct clk vpss_master_clk = { + .name = "vpss_master", + .parent = &pll1_sysclk4, + .lpsc = DAVINCI_LPSC_VPSSMSTR, + .flags = CLK_PSC, +}; + +static struct clk vpss_slave_clk = { + .name = "vpss_slave", + .parent = &pll1_sysclk4, + .lpsc = DAVINCI_LPSC_VPSSSLV, +}; + +static struct clk clkout1_clk = { + .name = "clkout1", + .parent = &pll1_aux_clk, + /* NOTE: clkout1 can be externally gated by muxing GPIO-18 */ +}; + +static struct clk clkout2_clk = { + .name = "clkout2", + .parent = &pll1_sysclkbp, +}; + +static struct clk pll2_clk = { + .name = "pll2", + .parent = &ref_clk, + .flags = CLK_PLL, + .pll_data = &pll2_data, +}; + +static struct clk pll2_sysclk1 = { + .name = "pll2_sysclk1", + .parent = &pll2_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV1, +}; + +static struct clk pll2_sysclkbp = { + .name = "pll2_sysclkbp", + .parent = &pll2_clk, + .flags = CLK_PLL | PRE_PLL, + .div_reg = BPDIV +}; + +static struct clk clkout3_clk = { + .name = "clkout3", + .parent = &pll2_sysclkbp, + /* NOTE: clkout3 can be externally gated by muxing GPIO-16 */ +}; + +static struct clk arm_clk = { + .name = "arm_clk", + .parent = &pll1_sysclk1, + .lpsc = DAVINCI_LPSC_ARM, + .flags = ALWAYS_ENABLED, +}; + +/* + * NOT LISTED below, and not touched by Linux + * - in SyncReset state by default + * .lpsc = DAVINCI_LPSC_TPCC, + * .lpsc = DAVINCI_LPSC_TPTC0, + * .lpsc = DAVINCI_LPSC_TPTC1, + * .lpsc = DAVINCI_LPSC_DDR_EMIF, .parent = &sysclk2_clk, + * .lpsc = DAVINCI_LPSC_MEMSTICK, + * - in Enabled state by default + * .lpsc = DAVINCI_LPSC_SYSTEM_SUBSYS, + * .lpsc = DAVINCI_LPSC_SCR2, // "bus" + * .lpsc = DAVINCI_LPSC_SCR3, // "bus" + * .lpsc = DAVINCI_LPSC_SCR4, // "bus" + * .lpsc = DAVINCI_LPSC_CROSSBAR, // "emulation" + * .lpsc = DAVINCI_LPSC_CFG27, // "test" + * .lpsc = DAVINCI_LPSC_CFG3, // "test" + * .lpsc = DAVINCI_LPSC_CFG5, // "test" + */ + +static struct clk mjcp_clk = { + .name = "mjcp", + .parent = &pll1_sysclk1, + .lpsc = DAVINCI_LPSC_IMCOP, +}; + +static struct clk uart0_clk = { + .name = "uart0", + .parent = &pll1_aux_clk, + .lpsc = DAVINCI_LPSC_UART0, +}; + +static struct clk uart1_clk = { + .name = "uart1", + .parent = &pll1_aux_clk, + .lpsc = DAVINCI_LPSC_UART1, +}; + +static struct clk uart2_clk = { + .name = "uart2", + .parent = &pll1_sysclk2, + .lpsc = DAVINCI_LPSC_UART2, +}; + +static struct clk i2c_clk = { + .name = "i2c", + .parent = &pll1_aux_clk, + .lpsc = DAVINCI_LPSC_I2C, +}; + +static struct clk asp0_clk = { + .name = "asp0", + .parent = &pll1_sysclk2, + .lpsc = DAVINCI_LPSC_McBSP, +}; + +static struct clk asp1_clk = { + .name = "asp1", + .parent = &pll1_sysclk2, + .lpsc = DM355_LPSC_McBSP1, +}; + +static struct clk mmcsd0_clk = { + .name = "mmcsd0", + .parent = &pll1_sysclk2, + .lpsc = DAVINCI_LPSC_MMC_SD, +}; + +static struct clk mmcsd1_clk = { + .name = "mmcsd1", + .parent = &pll1_sysclk2, + .lpsc = DM355_LPSC_MMC_SD1, +}; + +static struct clk spi0_clk = { + .name = "spi0", + .parent = &pll1_sysclk2, + .lpsc = DAVINCI_LPSC_SPI, +}; + +static struct clk spi1_clk = { + .name = "spi1", + .parent = &pll1_sysclk2, + .lpsc = DM355_LPSC_SPI1, +}; + +static struct clk spi2_clk = { + .name = "spi2", + .parent = &pll1_sysclk2, + .lpsc = DM355_LPSC_SPI2, +}; + +static struct clk gpio_clk = { + .name = "gpio", + .parent = &pll1_sysclk2, + .lpsc = DAVINCI_LPSC_GPIO, +}; + +static struct clk aemif_clk = { + .name = "aemif", + .parent = &pll1_sysclk2, + .lpsc = DAVINCI_LPSC_AEMIF, +}; + +static struct clk pwm0_clk = { + .name = "pwm0", + .parent = &pll1_aux_clk, + .lpsc = DAVINCI_LPSC_PWM0, +}; + +static struct clk pwm1_clk = { + .name = "pwm1", + .parent = &pll1_aux_clk, + .lpsc = DAVINCI_LPSC_PWM1, +}; + +static struct clk pwm2_clk = { + .name = "pwm2", + .parent = &pll1_aux_clk, + .lpsc = DAVINCI_LPSC_PWM2, +}; + +static struct clk pwm3_clk = { + .name = "pwm3", + .parent = &pll1_aux_clk, + .lpsc = DM355_LPSC_PWM3, +}; + +static struct clk timer0_clk = { + .name = "timer0", + .parent = &pll1_aux_clk, + .lpsc = DAVINCI_LPSC_TIMER0, +}; + +static struct clk timer1_clk = { + .name = "timer1", + .parent = &pll1_aux_clk, + .lpsc = DAVINCI_LPSC_TIMER1, +}; + +static struct clk timer2_clk = { + .name = "timer2", + .parent = &pll1_aux_clk, + .lpsc = DAVINCI_LPSC_TIMER2, + .usecount = 1, /* REVISIT: why can't this be disabled? */ +}; + +static struct clk timer3_clk = { + .name = "timer3", + .parent = &pll1_aux_clk, + .lpsc = DM355_LPSC_TIMER3, +}; + +static struct clk rto_clk = { + .name = "rto", + .parent = &pll1_aux_clk, + .lpsc = DM355_LPSC_RTO, +}; + +static struct clk usb_clk = { + .name = "usb", + .parent = &pll1_sysclk2, + .lpsc = DAVINCI_LPSC_USB, +}; + +static struct clk_lookup dm355_clks[] = { + CLK(NULL, "ref", &ref_clk), + CLK(NULL, "pll1", &pll1_clk), + CLK(NULL, "pll1_sysclk1", &pll1_sysclk1), + CLK(NULL, "pll1_sysclk2", &pll1_sysclk2), + CLK(NULL, "pll1_sysclk3", &pll1_sysclk3), + CLK(NULL, "pll1_sysclk4", &pll1_sysclk4), + CLK(NULL, "pll1_aux", &pll1_aux_clk), + CLK(NULL, "pll1_sysclkbp", &pll1_sysclkbp), + CLK(NULL, "vpss_dac", &vpss_dac_clk), + CLK(NULL, "vpss_master", &vpss_master_clk), + CLK(NULL, "vpss_slave", &vpss_slave_clk), + CLK(NULL, "clkout1", &clkout1_clk), + CLK(NULL, "clkout2", &clkout2_clk), + CLK(NULL, "pll2", &pll2_clk), + CLK(NULL, "pll2_sysclk1", &pll2_sysclk1), + CLK(NULL, "pll2_sysclkbp", &pll2_sysclkbp), + CLK(NULL, "clkout3", &clkout3_clk), + CLK(NULL, "arm", &arm_clk), + CLK(NULL, "mjcp", &mjcp_clk), + CLK(NULL, "uart0", &uart0_clk), + CLK(NULL, "uart1", &uart1_clk), + CLK(NULL, "uart2", &uart2_clk), + CLK("i2c_davinci.1", NULL, &i2c_clk), + CLK("davinci-mcbsp.0", NULL, &asp0_clk), + CLK("davinci-mcbsp.1", NULL, &asp1_clk), + CLK("davinci_mmc.0", NULL, &mmcsd0_clk), + CLK("davinci_mmc.1", NULL, &mmcsd1_clk), + CLK("spi_davinci.0", NULL, &spi0_clk), + CLK("spi_davinci.1", NULL, &spi1_clk), + CLK("spi_davinci.2", NULL, &spi2_clk), + CLK(NULL, "gpio", &gpio_clk), + CLK(NULL, "aemif", &aemif_clk), + CLK(NULL, "pwm0", &pwm0_clk), + CLK(NULL, "pwm1", &pwm1_clk), + CLK(NULL, "pwm2", &pwm2_clk), + CLK(NULL, "pwm3", &pwm3_clk), + CLK(NULL, "timer0", &timer0_clk), + CLK(NULL, "timer1", &timer1_clk), + CLK("watchdog", NULL, &timer2_clk), + CLK(NULL, "timer3", &timer3_clk), + CLK(NULL, "rto", &rto_clk), + CLK(NULL, "usb", &usb_clk), + CLK(NULL, NULL, NULL), +}; + +/*----------------------------------------------------------------------*/ + +static u64 dm355_spi0_dma_mask = DMA_BIT_MASK(32); + +static struct resource dm355_spi0_resources[] = { + { + .start = 0x01c66000, + .end = 0x01c667ff, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_DM355_SPINT0_0, + .flags = IORESOURCE_IRQ, + }, + { + .start = 17, + .flags = IORESOURCE_DMA, + }, + { + .start = 16, + .flags = IORESOURCE_DMA, + }, +}; + +static struct davinci_spi_platform_data dm355_spi0_pdata = { + .version = SPI_VERSION_1, + .num_chipselect = 2, + .cshold_bug = true, + .dma_event_q = EVENTQ_1, +}; +static struct platform_device dm355_spi0_device = { + .name = "spi_davinci", + .id = 0, + .dev = { + .dma_mask = &dm355_spi0_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &dm355_spi0_pdata, + }, + .num_resources = ARRAY_SIZE(dm355_spi0_resources), + .resource = dm355_spi0_resources, +}; + +void __init dm355_init_spi0(unsigned chipselect_mask, + struct spi_board_info *info, unsigned len) +{ + /* for now, assume we need MISO */ + davinci_cfg_reg(DM355_SPI0_SDI); + + /* not all slaves will be wired up */ + if (chipselect_mask & BIT(0)) + davinci_cfg_reg(DM355_SPI0_SDENA0); + if (chipselect_mask & BIT(1)) + davinci_cfg_reg(DM355_SPI0_SDENA1); + + spi_register_board_info(info, len); + + platform_device_register(&dm355_spi0_device); +} + +/*----------------------------------------------------------------------*/ + +#define INTMUX 0x18 +#define EVTMUX 0x1c + +/* + * Device specific mux setup + * + * soc description mux mode mode mux dbg + * reg offset mask mode + */ +static const struct mux_config dm355_pins[] = { +#ifdef CONFIG_DAVINCI_MUX +MUX_CFG(DM355, MMCSD0, 4, 2, 1, 0, false) + +MUX_CFG(DM355, SD1_CLK, 3, 6, 1, 1, false) +MUX_CFG(DM355, SD1_CMD, 3, 7, 1, 1, false) +MUX_CFG(DM355, SD1_DATA3, 3, 8, 3, 1, false) +MUX_CFG(DM355, SD1_DATA2, 3, 10, 3, 1, false) +MUX_CFG(DM355, SD1_DATA1, 3, 12, 3, 1, false) +MUX_CFG(DM355, SD1_DATA0, 3, 14, 3, 1, false) + +MUX_CFG(DM355, I2C_SDA, 3, 19, 1, 1, false) +MUX_CFG(DM355, I2C_SCL, 3, 20, 1, 1, false) + +MUX_CFG(DM355, MCBSP0_BDX, 3, 0, 1, 1, false) +MUX_CFG(DM355, MCBSP0_X, 3, 1, 1, 1, false) +MUX_CFG(DM355, MCBSP0_BFSX, 3, 2, 1, 1, false) +MUX_CFG(DM355, MCBSP0_BDR, 3, 3, 1, 1, false) +MUX_CFG(DM355, MCBSP0_R, 3, 4, 1, 1, false) +MUX_CFG(DM355, MCBSP0_BFSR, 3, 5, 1, 1, false) + +MUX_CFG(DM355, SPI0_SDI, 4, 1, 1, 0, false) +MUX_CFG(DM355, SPI0_SDENA0, 4, 0, 1, 0, false) +MUX_CFG(DM355, SPI0_SDENA1, 3, 28, 1, 1, false) + +INT_CFG(DM355, INT_EDMA_CC, 2, 1, 1, false) +INT_CFG(DM355, INT_EDMA_TC0_ERR, 3, 1, 1, false) +INT_CFG(DM355, INT_EDMA_TC1_ERR, 4, 1, 1, false) + +EVT_CFG(DM355, EVT8_ASP1_TX, 0, 1, 0, false) +EVT_CFG(DM355, EVT9_ASP1_RX, 1, 1, 0, false) +EVT_CFG(DM355, EVT26_MMC0_RX, 2, 1, 0, false) + +MUX_CFG(DM355, VOUT_FIELD, 1, 18, 3, 1, false) +MUX_CFG(DM355, VOUT_FIELD_G70, 1, 18, 3, 0, false) +MUX_CFG(DM355, VOUT_HVSYNC, 1, 16, 1, 0, false) +MUX_CFG(DM355, VOUT_COUTL_EN, 1, 0, 0xff, 0x55, false) +MUX_CFG(DM355, VOUT_COUTH_EN, 1, 8, 0xff, 0x55, false) + +MUX_CFG(DM355, VIN_PCLK, 0, 14, 1, 1, false) +MUX_CFG(DM355, VIN_CAM_WEN, 0, 13, 1, 1, false) +MUX_CFG(DM355, VIN_CAM_VD, 0, 12, 1, 1, false) +MUX_CFG(DM355, VIN_CAM_HD, 0, 11, 1, 1, false) +MUX_CFG(DM355, VIN_YIN_EN, 0, 10, 1, 1, false) +MUX_CFG(DM355, VIN_CINL_EN, 0, 0, 0xff, 0x55, false) +MUX_CFG(DM355, VIN_CINH_EN, 0, 8, 3, 3, false) +#endif +}; + +static u8 dm355_default_priorities[DAVINCI_N_AINTC_IRQ] = { + [IRQ_DM355_CCDC_VDINT0] = 2, + [IRQ_DM355_CCDC_VDINT1] = 6, + [IRQ_DM355_CCDC_VDINT2] = 6, + [IRQ_DM355_IPIPE_HST] = 6, + [IRQ_DM355_H3AINT] = 6, + [IRQ_DM355_IPIPE_SDR] = 6, + [IRQ_DM355_IPIPEIFINT] = 6, + [IRQ_DM355_OSDINT] = 7, + [IRQ_DM355_VENCINT] = 6, + [IRQ_ASQINT] = 6, + [IRQ_IMXINT] = 6, + [IRQ_USBINT] = 4, + [IRQ_DM355_RTOINT] = 4, + [IRQ_DM355_UARTINT2] = 7, + [IRQ_DM355_TINT6] = 7, + [IRQ_CCINT0] = 5, /* dma */ + [IRQ_CCERRINT] = 5, /* dma */ + [IRQ_TCERRINT0] = 5, /* dma */ + [IRQ_TCERRINT] = 5, /* dma */ + [IRQ_DM355_SPINT2_1] = 7, + [IRQ_DM355_TINT7] = 4, + [IRQ_DM355_SDIOINT0] = 7, + [IRQ_MBXINT] = 7, + [IRQ_MBRINT] = 7, + [IRQ_MMCINT] = 7, + [IRQ_DM355_MMCINT1] = 7, + [IRQ_DM355_PWMINT3] = 7, + [IRQ_DDRINT] = 7, + [IRQ_AEMIFINT] = 7, + [IRQ_DM355_SDIOINT1] = 4, + [IRQ_TINT0_TINT12] = 2, /* clockevent */ + [IRQ_TINT0_TINT34] = 2, /* clocksource */ + [IRQ_TINT1_TINT12] = 7, /* DSP timer */ + [IRQ_TINT1_TINT34] = 7, /* system tick */ + [IRQ_PWMINT0] = 7, + [IRQ_PWMINT1] = 7, + [IRQ_PWMINT2] = 7, + [IRQ_I2C] = 3, + [IRQ_UARTINT0] = 3, + [IRQ_UARTINT1] = 3, + [IRQ_DM355_SPINT0_0] = 3, + [IRQ_DM355_SPINT0_1] = 3, + [IRQ_DM355_GPIO0] = 3, + [IRQ_DM355_GPIO1] = 7, + [IRQ_DM355_GPIO2] = 4, + [IRQ_DM355_GPIO3] = 4, + [IRQ_DM355_GPIO4] = 7, + [IRQ_DM355_GPIO5] = 7, + [IRQ_DM355_GPIO6] = 7, + [IRQ_DM355_GPIO7] = 7, + [IRQ_DM355_GPIO8] = 7, + [IRQ_DM355_GPIO9] = 7, + [IRQ_DM355_GPIOBNK0] = 7, + [IRQ_DM355_GPIOBNK1] = 7, + [IRQ_DM355_GPIOBNK2] = 7, + [IRQ_DM355_GPIOBNK3] = 7, + [IRQ_DM355_GPIOBNK4] = 7, + [IRQ_DM355_GPIOBNK5] = 7, + [IRQ_DM355_GPIOBNK6] = 7, + [IRQ_COMMTX] = 7, + [IRQ_COMMRX] = 7, + [IRQ_EMUINT] = 7, +}; + +/*----------------------------------------------------------------------*/ + +static const s8 +queue_tc_mapping[][2] = { + /* {event queue no, TC no} */ + {0, 0}, + {1, 1}, + {-1, -1}, +}; + +static const s8 +queue_priority_mapping[][2] = { + /* {event queue no, Priority} */ + {0, 3}, + {1, 7}, + {-1, -1}, +}; + +static struct edma_soc_info edma_cc0_info = { + .n_channel = 64, + .n_region = 4, + .n_slot = 128, + .n_tc = 2, + .n_cc = 1, + .queue_tc_mapping = queue_tc_mapping, + .queue_priority_mapping = queue_priority_mapping, + .default_queue = EVENTQ_1, +}; + +static struct edma_soc_info *dm355_edma_info[EDMA_MAX_CC] = { + &edma_cc0_info, +}; + +static struct resource edma_resources[] = { + { + .name = "edma_cc0", + .start = 0x01c00000, + .end = 0x01c00000 + SZ_64K - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "edma_tc0", + .start = 0x01c10000, + .end = 0x01c10000 + SZ_1K - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "edma_tc1", + .start = 0x01c10400, + .end = 0x01c10400 + SZ_1K - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "edma0", + .start = IRQ_CCINT0, + .flags = IORESOURCE_IRQ, + }, + { + .name = "edma0_err", + .start = IRQ_CCERRINT, + .flags = IORESOURCE_IRQ, + }, + /* not using (or muxing) TC*_ERR */ +}; + +static struct platform_device dm355_edma_device = { + .name = "edma", + .id = 0, + .dev.platform_data = dm355_edma_info, + .num_resources = ARRAY_SIZE(edma_resources), + .resource = edma_resources, +}; + +static struct resource dm355_asp1_resources[] = { + { + .start = DAVINCI_ASP1_BASE, + .end = DAVINCI_ASP1_BASE + SZ_8K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = DAVINCI_DMA_ASP1_TX, + .end = DAVINCI_DMA_ASP1_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = DAVINCI_DMA_ASP1_RX, + .end = DAVINCI_DMA_ASP1_RX, + .flags = IORESOURCE_DMA, + }, +}; + +static struct platform_device dm355_asp1_device = { + .name = "davinci-mcbsp", + .id = 1, + .num_resources = ARRAY_SIZE(dm355_asp1_resources), + .resource = dm355_asp1_resources, +}; + +static void dm355_ccdc_setup_pinmux(void) +{ + davinci_cfg_reg(DM355_VIN_PCLK); + davinci_cfg_reg(DM355_VIN_CAM_WEN); + davinci_cfg_reg(DM355_VIN_CAM_VD); + davinci_cfg_reg(DM355_VIN_CAM_HD); + davinci_cfg_reg(DM355_VIN_YIN_EN); + davinci_cfg_reg(DM355_VIN_CINL_EN); + davinci_cfg_reg(DM355_VIN_CINH_EN); +} + +static struct resource dm355_vpss_resources[] = { + { + /* VPSS BL Base address */ + .name = "vpss", + .start = 0x01c70800, + .end = 0x01c70800 + 0xff, + .flags = IORESOURCE_MEM, + }, + { + /* VPSS CLK Base address */ + .name = "vpss", + .start = 0x01c70000, + .end = 0x01c70000 + 0xf, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device dm355_vpss_device = { + .name = "vpss", + .id = -1, + .dev.platform_data = "dm355_vpss", + .num_resources = ARRAY_SIZE(dm355_vpss_resources), + .resource = dm355_vpss_resources, +}; + +static struct resource vpfe_resources[] = { + { + .start = IRQ_VDINT0, + .end = IRQ_VDINT0, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_VDINT1, + .end = IRQ_VDINT1, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 vpfe_capture_dma_mask = DMA_BIT_MASK(32); +static struct resource dm355_ccdc_resource[] = { + /* CCDC Base address */ + { + .flags = IORESOURCE_MEM, + .start = 0x01c70600, + .end = 0x01c70600 + 0x1ff, + }, +}; +static struct platform_device dm355_ccdc_dev = { + .name = "dm355_ccdc", + .id = -1, + .num_resources = ARRAY_SIZE(dm355_ccdc_resource), + .resource = dm355_ccdc_resource, + .dev = { + .dma_mask = &vpfe_capture_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = dm355_ccdc_setup_pinmux, + }, +}; + +static struct platform_device vpfe_capture_dev = { + .name = CAPTURE_DRV_NAME, + .id = -1, + .num_resources = ARRAY_SIZE(vpfe_resources), + .resource = vpfe_resources, + .dev = { + .dma_mask = &vpfe_capture_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +void dm355_set_vpfe_config(struct vpfe_config *cfg) +{ + vpfe_capture_dev.dev.platform_data = cfg; +} + +/*----------------------------------------------------------------------*/ + +static struct map_desc dm355_io_desc[] = { + { + .virtual = IO_VIRT, + .pfn = __phys_to_pfn(IO_PHYS), + .length = IO_SIZE, + .type = MT_DEVICE + }, + { + .virtual = SRAM_VIRT, + .pfn = __phys_to_pfn(0x00010000), + .length = SZ_32K, + .type = MT_MEMORY_NONCACHED, + }, +}; + +/* Contents of JTAG ID register used to identify exact cpu type */ +static struct davinci_id dm355_ids[] = { + { + .variant = 0x0, + .part_no = 0xb73b, + .manufacturer = 0x00f, + .cpu_id = DAVINCI_CPU_ID_DM355, + .name = "dm355", + }, +}; + +static u32 dm355_psc_bases[] = { DAVINCI_PWR_SLEEP_CNTRL_BASE }; + +/* + * T0_BOT: Timer 0, bottom: clockevent source for hrtimers + * T0_TOP: Timer 0, top : clocksource for generic timekeeping + * T1_BOT: Timer 1, bottom: (used by DSP in TI DSPLink code) + * T1_TOP: Timer 1, top : <unused> + */ +static struct davinci_timer_info dm355_timer_info = { + .timers = davinci_timer_instance, + .clockevent_id = T0_BOT, + .clocksource_id = T0_TOP, +}; + +static struct plat_serial8250_port dm355_serial_platform_data[] = { + { + .mapbase = DAVINCI_UART0_BASE, + .irq = IRQ_UARTINT0, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | + UPF_IOREMAP, + .iotype = UPIO_MEM, + .regshift = 2, + }, + { + .mapbase = DAVINCI_UART1_BASE, + .irq = IRQ_UARTINT1, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | + UPF_IOREMAP, + .iotype = UPIO_MEM, + .regshift = 2, + }, + { + .mapbase = DM355_UART2_BASE, + .irq = IRQ_DM355_UARTINT2, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | + UPF_IOREMAP, + .iotype = UPIO_MEM, + .regshift = 2, + }, + { + .flags = 0 + }, +}; + +static struct platform_device dm355_serial_device = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM, + .dev = { + .platform_data = dm355_serial_platform_data, + }, +}; + +static struct davinci_soc_info davinci_soc_info_dm355 = { + .io_desc = dm355_io_desc, + .io_desc_num = ARRAY_SIZE(dm355_io_desc), + .jtag_id_reg = 0x01c40028, + .ids = dm355_ids, + .ids_num = ARRAY_SIZE(dm355_ids), + .cpu_clks = dm355_clks, + .psc_bases = dm355_psc_bases, + .psc_bases_num = ARRAY_SIZE(dm355_psc_bases), + .pinmux_base = DAVINCI_SYSTEM_MODULE_BASE, + .pinmux_pins = dm355_pins, + .pinmux_pins_num = ARRAY_SIZE(dm355_pins), + .intc_base = DAVINCI_ARM_INTC_BASE, + .intc_type = DAVINCI_INTC_TYPE_AINTC, + .intc_irq_prios = dm355_default_priorities, + .intc_irq_num = DAVINCI_N_AINTC_IRQ, + .timer_info = &dm355_timer_info, + .gpio_type = GPIO_TYPE_DAVINCI, + .gpio_base = DAVINCI_GPIO_BASE, + .gpio_num = 104, + .gpio_irq = IRQ_DM355_GPIOBNK0, + .serial_dev = &dm355_serial_device, + .sram_dma = 0x00010000, + .sram_len = SZ_32K, +}; + +void __init dm355_init_asp1(u32 evt_enable, struct snd_platform_data *pdata) +{ + /* we don't use ASP1 IRQs, or we'd need to mux them ... */ + if (evt_enable & ASP1_TX_EVT_EN) + davinci_cfg_reg(DM355_EVT8_ASP1_TX); + + if (evt_enable & ASP1_RX_EVT_EN) + davinci_cfg_reg(DM355_EVT9_ASP1_RX); + + dm355_asp1_device.dev.platform_data = pdata; + platform_device_register(&dm355_asp1_device); +} + +void __init dm355_init(void) +{ + davinci_common_init(&davinci_soc_info_dm355); + davinci_map_sysmod(); +} + +static int __init dm355_init_devices(void) +{ + if (!cpu_is_davinci_dm355()) + return 0; + + /* Add ccdc clock aliases */ + clk_add_alias("master", dm355_ccdc_dev.name, "vpss_master", NULL); + clk_add_alias("slave", dm355_ccdc_dev.name, "vpss_master", NULL); + davinci_cfg_reg(DM355_INT_EDMA_CC); + platform_device_register(&dm355_edma_device); + platform_device_register(&dm355_vpss_device); + platform_device_register(&dm355_ccdc_dev); + platform_device_register(&vpfe_capture_dev); + + return 0; +} +postcore_initcall(dm355_init_devices); diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/dm365.c b/ANDROID_3.4.5/arch/arm/mach-davinci/dm365.c new file mode 100644 index 00000000..1a2e9530 --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/dm365.c @@ -0,0 +1,1260 @@ +/* + * TI DaVinci DM365 chip specific setup + * + * Copyright (C) 2009 Texas Instruments + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include <linux/init.h> +#include <linux/clk.h> +#include <linux/serial_8250.h> +#include <linux/platform_device.h> +#include <linux/dma-mapping.h> +#include <linux/spi/spi.h> + +#include <asm/mach/map.h> + +#include <mach/cputype.h> +#include <mach/edma.h> +#include <mach/psc.h> +#include <mach/mux.h> +#include <mach/irqs.h> +#include <mach/time.h> +#include <mach/serial.h> +#include <mach/common.h> +#include <mach/asp.h> +#include <mach/keyscan.h> +#include <mach/spi.h> +#include <mach/gpio-davinci.h> + +#include "davinci.h" +#include "clock.h" +#include "mux.h" + +#define DM365_REF_FREQ 24000000 /* 24 MHz on the DM365 EVM */ + +/* Base of key scan register bank */ +#define DM365_KEYSCAN_BASE 0x01c69400 + +#define DM365_RTC_BASE 0x01c69000 + +#define DAVINCI_DM365_VC_BASE 0x01d0c000 +#define DAVINCI_DMA_VC_TX 2 +#define DAVINCI_DMA_VC_RX 3 + +#define DM365_EMAC_BASE 0x01d07000 +#define DM365_EMAC_MDIO_BASE (DM365_EMAC_BASE + 0x4000) +#define DM365_EMAC_CNTRL_OFFSET 0x0000 +#define DM365_EMAC_CNTRL_MOD_OFFSET 0x3000 +#define DM365_EMAC_CNTRL_RAM_OFFSET 0x1000 +#define DM365_EMAC_CNTRL_RAM_SIZE 0x2000 + +static struct pll_data pll1_data = { + .num = 1, + .phys_base = DAVINCI_PLL1_BASE, + .flags = PLL_HAS_POSTDIV | PLL_HAS_PREDIV, +}; + +static struct pll_data pll2_data = { + .num = 2, + .phys_base = DAVINCI_PLL2_BASE, + .flags = PLL_HAS_POSTDIV | PLL_HAS_PREDIV, +}; + +static struct clk ref_clk = { + .name = "ref_clk", + .rate = DM365_REF_FREQ, +}; + +static struct clk pll1_clk = { + .name = "pll1", + .parent = &ref_clk, + .flags = CLK_PLL, + .pll_data = &pll1_data, +}; + +static struct clk pll1_aux_clk = { + .name = "pll1_aux_clk", + .parent = &pll1_clk, + .flags = CLK_PLL | PRE_PLL, +}; + +static struct clk pll1_sysclkbp = { + .name = "pll1_sysclkbp", + .parent = &pll1_clk, + .flags = CLK_PLL | PRE_PLL, + .div_reg = BPDIV +}; + +static struct clk clkout0_clk = { + .name = "clkout0", + .parent = &pll1_clk, + .flags = CLK_PLL | PRE_PLL, +}; + +static struct clk pll1_sysclk1 = { + .name = "pll1_sysclk1", + .parent = &pll1_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV1, +}; + +static struct clk pll1_sysclk2 = { + .name = "pll1_sysclk2", + .parent = &pll1_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV2, +}; + +static struct clk pll1_sysclk3 = { + .name = "pll1_sysclk3", + .parent = &pll1_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV3, +}; + +static struct clk pll1_sysclk4 = { + .name = "pll1_sysclk4", + .parent = &pll1_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV4, +}; + +static struct clk pll1_sysclk5 = { + .name = "pll1_sysclk5", + .parent = &pll1_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV5, +}; + +static struct clk pll1_sysclk6 = { + .name = "pll1_sysclk6", + .parent = &pll1_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV6, +}; + +static struct clk pll1_sysclk7 = { + .name = "pll1_sysclk7", + .parent = &pll1_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV7, +}; + +static struct clk pll1_sysclk8 = { + .name = "pll1_sysclk8", + .parent = &pll1_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV8, +}; + +static struct clk pll1_sysclk9 = { + .name = "pll1_sysclk9", + .parent = &pll1_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV9, +}; + +static struct clk pll2_clk = { + .name = "pll2", + .parent = &ref_clk, + .flags = CLK_PLL, + .pll_data = &pll2_data, +}; + +static struct clk pll2_aux_clk = { + .name = "pll2_aux_clk", + .parent = &pll2_clk, + .flags = CLK_PLL | PRE_PLL, +}; + +static struct clk clkout1_clk = { + .name = "clkout1", + .parent = &pll2_clk, + .flags = CLK_PLL | PRE_PLL, +}; + +static struct clk pll2_sysclk1 = { + .name = "pll2_sysclk1", + .parent = &pll2_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV1, +}; + +static struct clk pll2_sysclk2 = { + .name = "pll2_sysclk2", + .parent = &pll2_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV2, +}; + +static struct clk pll2_sysclk3 = { + .name = "pll2_sysclk3", + .parent = &pll2_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV3, +}; + +static struct clk pll2_sysclk4 = { + .name = "pll2_sysclk4", + .parent = &pll2_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV4, +}; + +static struct clk pll2_sysclk5 = { + .name = "pll2_sysclk5", + .parent = &pll2_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV5, +}; + +static struct clk pll2_sysclk6 = { + .name = "pll2_sysclk6", + .parent = &pll2_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV6, +}; + +static struct clk pll2_sysclk7 = { + .name = "pll2_sysclk7", + .parent = &pll2_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV7, +}; + +static struct clk pll2_sysclk8 = { + .name = "pll2_sysclk8", + .parent = &pll2_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV8, +}; + +static struct clk pll2_sysclk9 = { + .name = "pll2_sysclk9", + .parent = &pll2_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV9, +}; + +static struct clk vpss_dac_clk = { + .name = "vpss_dac", + .parent = &pll1_sysclk3, + .lpsc = DM365_LPSC_DAC_CLK, +}; + +static struct clk vpss_master_clk = { + .name = "vpss_master", + .parent = &pll1_sysclk5, + .lpsc = DM365_LPSC_VPSSMSTR, + .flags = CLK_PSC, +}; + +static struct clk arm_clk = { + .name = "arm_clk", + .parent = &pll2_sysclk2, + .lpsc = DAVINCI_LPSC_ARM, + .flags = ALWAYS_ENABLED, +}; + +static struct clk uart0_clk = { + .name = "uart0", + .parent = &pll1_aux_clk, + .lpsc = DAVINCI_LPSC_UART0, +}; + +static struct clk uart1_clk = { + .name = "uart1", + .parent = &pll1_sysclk4, + .lpsc = DAVINCI_LPSC_UART1, +}; + +static struct clk i2c_clk = { + .name = "i2c", + .parent = &pll1_aux_clk, + .lpsc = DAVINCI_LPSC_I2C, +}; + +static struct clk mmcsd0_clk = { + .name = "mmcsd0", + .parent = &pll1_sysclk8, + .lpsc = DAVINCI_LPSC_MMC_SD, +}; + +static struct clk mmcsd1_clk = { + .name = "mmcsd1", + .parent = &pll1_sysclk4, + .lpsc = DM365_LPSC_MMC_SD1, +}; + +static struct clk spi0_clk = { + .name = "spi0", + .parent = &pll1_sysclk4, + .lpsc = DAVINCI_LPSC_SPI, +}; + +static struct clk spi1_clk = { + .name = "spi1", + .parent = &pll1_sysclk4, + .lpsc = DM365_LPSC_SPI1, +}; + +static struct clk spi2_clk = { + .name = "spi2", + .parent = &pll1_sysclk4, + .lpsc = DM365_LPSC_SPI2, +}; + +static struct clk spi3_clk = { + .name = "spi3", + .parent = &pll1_sysclk4, + .lpsc = DM365_LPSC_SPI3, +}; + +static struct clk spi4_clk = { + .name = "spi4", + .parent = &pll1_aux_clk, + .lpsc = DM365_LPSC_SPI4, +}; + +static struct clk gpio_clk = { + .name = "gpio", + .parent = &pll1_sysclk4, + .lpsc = DAVINCI_LPSC_GPIO, +}; + +static struct clk aemif_clk = { + .name = "aemif", + .parent = &pll1_sysclk4, + .lpsc = DAVINCI_LPSC_AEMIF, +}; + +static struct clk pwm0_clk = { + .name = "pwm0", + .parent = &pll1_aux_clk, + .lpsc = DAVINCI_LPSC_PWM0, +}; + +static struct clk pwm1_clk = { + .name = "pwm1", + .parent = &pll1_aux_clk, + .lpsc = DAVINCI_LPSC_PWM1, +}; + +static struct clk pwm2_clk = { + .name = "pwm2", + .parent = &pll1_aux_clk, + .lpsc = DAVINCI_LPSC_PWM2, +}; + +static struct clk pwm3_clk = { + .name = "pwm3", + .parent = &ref_clk, + .lpsc = DM365_LPSC_PWM3, +}; + +static struct clk timer0_clk = { + .name = "timer0", + .parent = &pll1_aux_clk, + .lpsc = DAVINCI_LPSC_TIMER0, +}; + +static struct clk timer1_clk = { + .name = "timer1", + .parent = &pll1_aux_clk, + .lpsc = DAVINCI_LPSC_TIMER1, +}; + +static struct clk timer2_clk = { + .name = "timer2", + .parent = &pll1_aux_clk, + .lpsc = DAVINCI_LPSC_TIMER2, + .usecount = 1, +}; + +static struct clk timer3_clk = { + .name = "timer3", + .parent = &pll1_aux_clk, + .lpsc = DM365_LPSC_TIMER3, +}; + +static struct clk usb_clk = { + .name = "usb", + .parent = &pll1_aux_clk, + .lpsc = DAVINCI_LPSC_USB, +}; + +static struct clk emac_clk = { + .name = "emac", + .parent = &pll1_sysclk4, + .lpsc = DM365_LPSC_EMAC, +}; + +static struct clk voicecodec_clk = { + .name = "voice_codec", + .parent = &pll2_sysclk4, + .lpsc = DM365_LPSC_VOICE_CODEC, +}; + +static struct clk asp0_clk = { + .name = "asp0", + .parent = &pll1_sysclk4, + .lpsc = DM365_LPSC_McBSP1, +}; + +static struct clk rto_clk = { + .name = "rto", + .parent = &pll1_sysclk4, + .lpsc = DM365_LPSC_RTO, +}; + +static struct clk mjcp_clk = { + .name = "mjcp", + .parent = &pll1_sysclk3, + .lpsc = DM365_LPSC_MJCP, +}; + +static struct clk_lookup dm365_clks[] = { + CLK(NULL, "ref", &ref_clk), + CLK(NULL, "pll1", &pll1_clk), + CLK(NULL, "pll1_aux", &pll1_aux_clk), + CLK(NULL, "pll1_sysclkbp", &pll1_sysclkbp), + CLK(NULL, "clkout0", &clkout0_clk), + CLK(NULL, "pll1_sysclk1", &pll1_sysclk1), + CLK(NULL, "pll1_sysclk2", &pll1_sysclk2), + CLK(NULL, "pll1_sysclk3", &pll1_sysclk3), + CLK(NULL, "pll1_sysclk4", &pll1_sysclk4), + CLK(NULL, "pll1_sysclk5", &pll1_sysclk5), + CLK(NULL, "pll1_sysclk6", &pll1_sysclk6), + CLK(NULL, "pll1_sysclk7", &pll1_sysclk7), + CLK(NULL, "pll1_sysclk8", &pll1_sysclk8), + CLK(NULL, "pll1_sysclk9", &pll1_sysclk9), + CLK(NULL, "pll2", &pll2_clk), + CLK(NULL, "pll2_aux", &pll2_aux_clk), + CLK(NULL, "clkout1", &clkout1_clk), + CLK(NULL, "pll2_sysclk1", &pll2_sysclk1), + CLK(NULL, "pll2_sysclk2", &pll2_sysclk2), + CLK(NULL, "pll2_sysclk3", &pll2_sysclk3), + CLK(NULL, "pll2_sysclk4", &pll2_sysclk4), + CLK(NULL, "pll2_sysclk5", &pll2_sysclk5), + CLK(NULL, "pll2_sysclk6", &pll2_sysclk6), + CLK(NULL, "pll2_sysclk7", &pll2_sysclk7), + CLK(NULL, "pll2_sysclk8", &pll2_sysclk8), + CLK(NULL, "pll2_sysclk9", &pll2_sysclk9), + CLK(NULL, "vpss_dac", &vpss_dac_clk), + CLK(NULL, "vpss_master", &vpss_master_clk), + CLK(NULL, "arm", &arm_clk), + CLK(NULL, "uart0", &uart0_clk), + CLK(NULL, "uart1", &uart1_clk), + CLK("i2c_davinci.1", NULL, &i2c_clk), + CLK("davinci_mmc.0", NULL, &mmcsd0_clk), + CLK("davinci_mmc.1", NULL, &mmcsd1_clk), + CLK("spi_davinci.0", NULL, &spi0_clk), + CLK("spi_davinci.1", NULL, &spi1_clk), + CLK("spi_davinci.2", NULL, &spi2_clk), + CLK("spi_davinci.3", NULL, &spi3_clk), + CLK("spi_davinci.4", NULL, &spi4_clk), + CLK(NULL, "gpio", &gpio_clk), + CLK(NULL, "aemif", &aemif_clk), + CLK(NULL, "pwm0", &pwm0_clk), + CLK(NULL, "pwm1", &pwm1_clk), + CLK(NULL, "pwm2", &pwm2_clk), + CLK(NULL, "pwm3", &pwm3_clk), + CLK(NULL, "timer0", &timer0_clk), + CLK(NULL, "timer1", &timer1_clk), + CLK("watchdog", NULL, &timer2_clk), + CLK(NULL, "timer3", &timer3_clk), + CLK(NULL, "usb", &usb_clk), + CLK("davinci_emac.1", NULL, &emac_clk), + CLK("davinci_voicecodec", NULL, &voicecodec_clk), + CLK("davinci-mcbsp", NULL, &asp0_clk), + CLK(NULL, "rto", &rto_clk), + CLK(NULL, "mjcp", &mjcp_clk), + CLK(NULL, NULL, NULL), +}; + +/*----------------------------------------------------------------------*/ + +#define INTMUX 0x18 +#define EVTMUX 0x1c + + +static const struct mux_config dm365_pins[] = { +#ifdef CONFIG_DAVINCI_MUX +MUX_CFG(DM365, MMCSD0, 0, 24, 1, 0, false) + +MUX_CFG(DM365, SD1_CLK, 0, 16, 3, 1, false) +MUX_CFG(DM365, SD1_CMD, 4, 30, 3, 1, false) +MUX_CFG(DM365, SD1_DATA3, 4, 28, 3, 1, false) +MUX_CFG(DM365, SD1_DATA2, 4, 26, 3, 1, false) +MUX_CFG(DM365, SD1_DATA1, 4, 24, 3, 1, false) +MUX_CFG(DM365, SD1_DATA0, 4, 22, 3, 1, false) + +MUX_CFG(DM365, I2C_SDA, 3, 23, 3, 2, false) +MUX_CFG(DM365, I2C_SCL, 3, 21, 3, 2, false) + +MUX_CFG(DM365, AEMIF_AR_A14, 2, 0, 3, 1, false) +MUX_CFG(DM365, AEMIF_AR_BA0, 2, 0, 3, 2, false) +MUX_CFG(DM365, AEMIF_A3, 2, 2, 3, 1, false) +MUX_CFG(DM365, AEMIF_A7, 2, 4, 3, 1, false) +MUX_CFG(DM365, AEMIF_D15_8, 2, 6, 1, 1, false) +MUX_CFG(DM365, AEMIF_CE0, 2, 7, 1, 0, false) +MUX_CFG(DM365, AEMIF_CE1, 2, 8, 1, 0, false) +MUX_CFG(DM365, AEMIF_WE_OE, 2, 9, 1, 0, false) + +MUX_CFG(DM365, MCBSP0_BDX, 0, 23, 1, 1, false) +MUX_CFG(DM365, MCBSP0_X, 0, 22, 1, 1, false) +MUX_CFG(DM365, MCBSP0_BFSX, 0, 21, 1, 1, false) +MUX_CFG(DM365, MCBSP0_BDR, 0, 20, 1, 1, false) +MUX_CFG(DM365, MCBSP0_R, 0, 19, 1, 1, false) +MUX_CFG(DM365, MCBSP0_BFSR, 0, 18, 1, 1, false) + +MUX_CFG(DM365, SPI0_SCLK, 3, 28, 1, 1, false) +MUX_CFG(DM365, SPI0_SDI, 3, 26, 3, 1, false) +MUX_CFG(DM365, SPI0_SDO, 3, 25, 1, 1, false) +MUX_CFG(DM365, SPI0_SDENA0, 3, 29, 3, 1, false) +MUX_CFG(DM365, SPI0_SDENA1, 3, 26, 3, 2, false) + +MUX_CFG(DM365, UART0_RXD, 3, 20, 1, 1, false) +MUX_CFG(DM365, UART0_TXD, 3, 19, 1, 1, false) +MUX_CFG(DM365, UART1_RXD, 3, 17, 3, 2, false) +MUX_CFG(DM365, UART1_TXD, 3, 15, 3, 2, false) +MUX_CFG(DM365, UART1_RTS, 3, 23, 3, 1, false) +MUX_CFG(DM365, UART1_CTS, 3, 21, 3, 1, false) + +MUX_CFG(DM365, EMAC_TX_EN, 3, 17, 3, 1, false) +MUX_CFG(DM365, EMAC_TX_CLK, 3, 15, 3, 1, false) +MUX_CFG(DM365, EMAC_COL, 3, 14, 1, 1, false) +MUX_CFG(DM365, EMAC_TXD3, 3, 13, 1, 1, false) +MUX_CFG(DM365, EMAC_TXD2, 3, 12, 1, 1, false) +MUX_CFG(DM365, EMAC_TXD1, 3, 11, 1, 1, false) +MUX_CFG(DM365, EMAC_TXD0, 3, 10, 1, 1, false) +MUX_CFG(DM365, EMAC_RXD3, 3, 9, 1, 1, false) +MUX_CFG(DM365, EMAC_RXD2, 3, 8, 1, 1, false) +MUX_CFG(DM365, EMAC_RXD1, 3, 7, 1, 1, false) +MUX_CFG(DM365, EMAC_RXD0, 3, 6, 1, 1, false) +MUX_CFG(DM365, EMAC_RX_CLK, 3, 5, 1, 1, false) +MUX_CFG(DM365, EMAC_RX_DV, 3, 4, 1, 1, false) +MUX_CFG(DM365, EMAC_RX_ER, 3, 3, 1, 1, false) +MUX_CFG(DM365, EMAC_CRS, 3, 2, 1, 1, false) +MUX_CFG(DM365, EMAC_MDIO, 3, 1, 1, 1, false) +MUX_CFG(DM365, EMAC_MDCLK, 3, 0, 1, 1, false) + +MUX_CFG(DM365, KEYSCAN, 2, 0, 0x3f, 0x3f, false) + +MUX_CFG(DM365, PWM0, 1, 0, 3, 2, false) +MUX_CFG(DM365, PWM0_G23, 3, 26, 3, 3, false) +MUX_CFG(DM365, PWM1, 1, 2, 3, 2, false) +MUX_CFG(DM365, PWM1_G25, 3, 29, 3, 2, false) +MUX_CFG(DM365, PWM2_G87, 1, 10, 3, 2, false) +MUX_CFG(DM365, PWM2_G88, 1, 8, 3, 2, false) +MUX_CFG(DM365, PWM2_G89, 1, 6, 3, 2, false) +MUX_CFG(DM365, PWM2_G90, 1, 4, 3, 2, false) +MUX_CFG(DM365, PWM3_G80, 1, 20, 3, 3, false) +MUX_CFG(DM365, PWM3_G81, 1, 18, 3, 3, false) +MUX_CFG(DM365, PWM3_G85, 1, 14, 3, 2, false) +MUX_CFG(DM365, PWM3_G86, 1, 12, 3, 2, false) + +MUX_CFG(DM365, SPI1_SCLK, 4, 2, 3, 1, false) +MUX_CFG(DM365, SPI1_SDI, 3, 31, 1, 1, false) +MUX_CFG(DM365, SPI1_SDO, 4, 0, 3, 1, false) +MUX_CFG(DM365, SPI1_SDENA0, 4, 4, 3, 1, false) +MUX_CFG(DM365, SPI1_SDENA1, 4, 0, 3, 2, false) + +MUX_CFG(DM365, SPI2_SCLK, 4, 10, 3, 1, false) +MUX_CFG(DM365, SPI2_SDI, 4, 6, 3, 1, false) +MUX_CFG(DM365, SPI2_SDO, 4, 8, 3, 1, false) +MUX_CFG(DM365, SPI2_SDENA0, 4, 12, 3, 1, false) +MUX_CFG(DM365, SPI2_SDENA1, 4, 8, 3, 2, false) + +MUX_CFG(DM365, SPI3_SCLK, 0, 0, 3, 2, false) +MUX_CFG(DM365, SPI3_SDI, 0, 2, 3, 2, false) +MUX_CFG(DM365, SPI3_SDO, 0, 6, 3, 2, false) +MUX_CFG(DM365, SPI3_SDENA0, 0, 4, 3, 2, false) +MUX_CFG(DM365, SPI3_SDENA1, 0, 6, 3, 3, false) + +MUX_CFG(DM365, SPI4_SCLK, 4, 18, 3, 1, false) +MUX_CFG(DM365, SPI4_SDI, 4, 14, 3, 1, false) +MUX_CFG(DM365, SPI4_SDO, 4, 16, 3, 1, false) +MUX_CFG(DM365, SPI4_SDENA0, 4, 20, 3, 1, false) +MUX_CFG(DM365, SPI4_SDENA1, 4, 16, 3, 2, false) + +MUX_CFG(DM365, CLKOUT0, 4, 20, 3, 3, false) +MUX_CFG(DM365, CLKOUT1, 4, 16, 3, 3, false) +MUX_CFG(DM365, CLKOUT2, 4, 8, 3, 3, false) + +MUX_CFG(DM365, GPIO20, 3, 21, 3, 0, false) +MUX_CFG(DM365, GPIO30, 4, 6, 3, 0, false) +MUX_CFG(DM365, GPIO31, 4, 8, 3, 0, false) +MUX_CFG(DM365, GPIO32, 4, 10, 3, 0, false) +MUX_CFG(DM365, GPIO33, 4, 12, 3, 0, false) +MUX_CFG(DM365, GPIO40, 4, 26, 3, 0, false) +MUX_CFG(DM365, GPIO64_57, 2, 6, 1, 0, false) + +MUX_CFG(DM365, VOUT_FIELD, 1, 18, 3, 1, false) +MUX_CFG(DM365, VOUT_FIELD_G81, 1, 18, 3, 0, false) +MUX_CFG(DM365, VOUT_HVSYNC, 1, 16, 1, 0, false) +MUX_CFG(DM365, VOUT_COUTL_EN, 1, 0, 0xff, 0x55, false) +MUX_CFG(DM365, VOUT_COUTH_EN, 1, 8, 0xff, 0x55, false) +MUX_CFG(DM365, VIN_CAM_WEN, 0, 14, 3, 0, false) +MUX_CFG(DM365, VIN_CAM_VD, 0, 13, 1, 0, false) +MUX_CFG(DM365, VIN_CAM_HD, 0, 12, 1, 0, false) +MUX_CFG(DM365, VIN_YIN4_7_EN, 0, 0, 0xff, 0, false) +MUX_CFG(DM365, VIN_YIN0_3_EN, 0, 8, 0xf, 0, false) + +INT_CFG(DM365, INT_EDMA_CC, 2, 1, 1, false) +INT_CFG(DM365, INT_EDMA_TC0_ERR, 3, 1, 1, false) +INT_CFG(DM365, INT_EDMA_TC1_ERR, 4, 1, 1, false) +INT_CFG(DM365, INT_EDMA_TC2_ERR, 22, 1, 1, false) +INT_CFG(DM365, INT_EDMA_TC3_ERR, 23, 1, 1, false) +INT_CFG(DM365, INT_PRTCSS, 10, 1, 1, false) +INT_CFG(DM365, INT_EMAC_RXTHRESH, 14, 1, 1, false) +INT_CFG(DM365, INT_EMAC_RXPULSE, 15, 1, 1, false) +INT_CFG(DM365, INT_EMAC_TXPULSE, 16, 1, 1, false) +INT_CFG(DM365, INT_EMAC_MISCPULSE, 17, 1, 1, false) +INT_CFG(DM365, INT_IMX0_ENABLE, 0, 1, 0, false) +INT_CFG(DM365, INT_IMX0_DISABLE, 0, 1, 1, false) +INT_CFG(DM365, INT_HDVICP_ENABLE, 0, 1, 1, false) +INT_CFG(DM365, INT_HDVICP_DISABLE, 0, 1, 0, false) +INT_CFG(DM365, INT_IMX1_ENABLE, 24, 1, 1, false) +INT_CFG(DM365, INT_IMX1_DISABLE, 24, 1, 0, false) +INT_CFG(DM365, INT_NSF_ENABLE, 25, 1, 1, false) +INT_CFG(DM365, INT_NSF_DISABLE, 25, 1, 0, false) + +EVT_CFG(DM365, EVT2_ASP_TX, 0, 1, 0, false) +EVT_CFG(DM365, EVT3_ASP_RX, 1, 1, 0, false) +EVT_CFG(DM365, EVT2_VC_TX, 0, 1, 1, false) +EVT_CFG(DM365, EVT3_VC_RX, 1, 1, 1, false) +#endif +}; + +static u64 dm365_spi0_dma_mask = DMA_BIT_MASK(32); + +static struct davinci_spi_platform_data dm365_spi0_pdata = { + .version = SPI_VERSION_1, + .num_chipselect = 2, + .dma_event_q = EVENTQ_3, +}; + +static struct resource dm365_spi0_resources[] = { + { + .start = 0x01c66000, + .end = 0x01c667ff, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_DM365_SPIINT0_0, + .flags = IORESOURCE_IRQ, + }, + { + .start = 17, + .flags = IORESOURCE_DMA, + }, + { + .start = 16, + .flags = IORESOURCE_DMA, + }, +}; + +static struct platform_device dm365_spi0_device = { + .name = "spi_davinci", + .id = 0, + .dev = { + .dma_mask = &dm365_spi0_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &dm365_spi0_pdata, + }, + .num_resources = ARRAY_SIZE(dm365_spi0_resources), + .resource = dm365_spi0_resources, +}; + +void __init dm365_init_spi0(unsigned chipselect_mask, + struct spi_board_info *info, unsigned len) +{ + davinci_cfg_reg(DM365_SPI0_SCLK); + davinci_cfg_reg(DM365_SPI0_SDI); + davinci_cfg_reg(DM365_SPI0_SDO); + + /* not all slaves will be wired up */ + if (chipselect_mask & BIT(0)) + davinci_cfg_reg(DM365_SPI0_SDENA0); + if (chipselect_mask & BIT(1)) + davinci_cfg_reg(DM365_SPI0_SDENA1); + + spi_register_board_info(info, len); + + platform_device_register(&dm365_spi0_device); +} + +static struct emac_platform_data dm365_emac_pdata = { + .ctrl_reg_offset = DM365_EMAC_CNTRL_OFFSET, + .ctrl_mod_reg_offset = DM365_EMAC_CNTRL_MOD_OFFSET, + .ctrl_ram_offset = DM365_EMAC_CNTRL_RAM_OFFSET, + .ctrl_ram_size = DM365_EMAC_CNTRL_RAM_SIZE, + .version = EMAC_VERSION_2, +}; + +static struct resource dm365_emac_resources[] = { + { + .start = DM365_EMAC_BASE, + .end = DM365_EMAC_BASE + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_DM365_EMAC_RXTHRESH, + .end = IRQ_DM365_EMAC_RXTHRESH, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_DM365_EMAC_RXPULSE, + .end = IRQ_DM365_EMAC_RXPULSE, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_DM365_EMAC_TXPULSE, + .end = IRQ_DM365_EMAC_TXPULSE, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_DM365_EMAC_MISCPULSE, + .end = IRQ_DM365_EMAC_MISCPULSE, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device dm365_emac_device = { + .name = "davinci_emac", + .id = 1, + .dev = { + .platform_data = &dm365_emac_pdata, + }, + .num_resources = ARRAY_SIZE(dm365_emac_resources), + .resource = dm365_emac_resources, +}; + +static struct resource dm365_mdio_resources[] = { + { + .start = DM365_EMAC_MDIO_BASE, + .end = DM365_EMAC_MDIO_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device dm365_mdio_device = { + .name = "davinci_mdio", + .id = 0, + .num_resources = ARRAY_SIZE(dm365_mdio_resources), + .resource = dm365_mdio_resources, +}; + +static u8 dm365_default_priorities[DAVINCI_N_AINTC_IRQ] = { + [IRQ_VDINT0] = 2, + [IRQ_VDINT1] = 6, + [IRQ_VDINT2] = 6, + [IRQ_HISTINT] = 6, + [IRQ_H3AINT] = 6, + [IRQ_PRVUINT] = 6, + [IRQ_RSZINT] = 6, + [IRQ_DM365_INSFINT] = 7, + [IRQ_VENCINT] = 6, + [IRQ_ASQINT] = 6, + [IRQ_IMXINT] = 6, + [IRQ_DM365_IMCOPINT] = 4, + [IRQ_USBINT] = 4, + [IRQ_DM365_RTOINT] = 7, + [IRQ_DM365_TINT5] = 7, + [IRQ_DM365_TINT6] = 5, + [IRQ_CCINT0] = 5, + [IRQ_CCERRINT] = 5, + [IRQ_TCERRINT0] = 5, + [IRQ_TCERRINT] = 7, + [IRQ_PSCIN] = 4, + [IRQ_DM365_SPINT2_1] = 7, + [IRQ_DM365_TINT7] = 7, + [IRQ_DM365_SDIOINT0] = 7, + [IRQ_MBXINT] = 7, + [IRQ_MBRINT] = 7, + [IRQ_MMCINT] = 7, + [IRQ_DM365_MMCINT1] = 7, + [IRQ_DM365_PWMINT3] = 7, + [IRQ_AEMIFINT] = 2, + [IRQ_DM365_SDIOINT1] = 2, + [IRQ_TINT0_TINT12] = 7, + [IRQ_TINT0_TINT34] = 7, + [IRQ_TINT1_TINT12] = 7, + [IRQ_TINT1_TINT34] = 7, + [IRQ_PWMINT0] = 7, + [IRQ_PWMINT1] = 3, + [IRQ_PWMINT2] = 3, + [IRQ_I2C] = 3, + [IRQ_UARTINT0] = 3, + [IRQ_UARTINT1] = 3, + [IRQ_DM365_RTCINT] = 3, + [IRQ_DM365_SPIINT0_0] = 3, + [IRQ_DM365_SPIINT3_0] = 3, + [IRQ_DM365_GPIO0] = 3, + [IRQ_DM365_GPIO1] = 7, + [IRQ_DM365_GPIO2] = 4, + [IRQ_DM365_GPIO3] = 4, + [IRQ_DM365_GPIO4] = 7, + [IRQ_DM365_GPIO5] = 7, + [IRQ_DM365_GPIO6] = 7, + [IRQ_DM365_GPIO7] = 7, + [IRQ_DM365_EMAC_RXTHRESH] = 7, + [IRQ_DM365_EMAC_RXPULSE] = 7, + [IRQ_DM365_EMAC_TXPULSE] = 7, + [IRQ_DM365_EMAC_MISCPULSE] = 7, + [IRQ_DM365_GPIO12] = 7, + [IRQ_DM365_GPIO13] = 7, + [IRQ_DM365_GPIO14] = 7, + [IRQ_DM365_GPIO15] = 7, + [IRQ_DM365_KEYINT] = 7, + [IRQ_DM365_TCERRINT2] = 7, + [IRQ_DM365_TCERRINT3] = 7, + [IRQ_DM365_EMUINT] = 7, +}; + +/* Four Transfer Controllers on DM365 */ +static const s8 +dm365_queue_tc_mapping[][2] = { + /* {event queue no, TC no} */ + {0, 0}, + {1, 1}, + {2, 2}, + {3, 3}, + {-1, -1}, +}; + +static const s8 +dm365_queue_priority_mapping[][2] = { + /* {event queue no, Priority} */ + {0, 7}, + {1, 7}, + {2, 7}, + {3, 0}, + {-1, -1}, +}; + +static struct edma_soc_info edma_cc0_info = { + .n_channel = 64, + .n_region = 4, + .n_slot = 256, + .n_tc = 4, + .n_cc = 1, + .queue_tc_mapping = dm365_queue_tc_mapping, + .queue_priority_mapping = dm365_queue_priority_mapping, + .default_queue = EVENTQ_3, +}; + +static struct edma_soc_info *dm365_edma_info[EDMA_MAX_CC] = { + &edma_cc0_info, +}; + +static struct resource edma_resources[] = { + { + .name = "edma_cc0", + .start = 0x01c00000, + .end = 0x01c00000 + SZ_64K - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "edma_tc0", + .start = 0x01c10000, + .end = 0x01c10000 + SZ_1K - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "edma_tc1", + .start = 0x01c10400, + .end = 0x01c10400 + SZ_1K - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "edma_tc2", + .start = 0x01c10800, + .end = 0x01c10800 + SZ_1K - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "edma_tc3", + .start = 0x01c10c00, + .end = 0x01c10c00 + SZ_1K - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "edma0", + .start = IRQ_CCINT0, + .flags = IORESOURCE_IRQ, + }, + { + .name = "edma0_err", + .start = IRQ_CCERRINT, + .flags = IORESOURCE_IRQ, + }, + /* not using TC*_ERR */ +}; + +static struct platform_device dm365_edma_device = { + .name = "edma", + .id = 0, + .dev.platform_data = dm365_edma_info, + .num_resources = ARRAY_SIZE(edma_resources), + .resource = edma_resources, +}; + +static struct resource dm365_asp_resources[] = { + { + .start = DAVINCI_DM365_ASP0_BASE, + .end = DAVINCI_DM365_ASP0_BASE + SZ_8K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = DAVINCI_DMA_ASP0_TX, + .end = DAVINCI_DMA_ASP0_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = DAVINCI_DMA_ASP0_RX, + .end = DAVINCI_DMA_ASP0_RX, + .flags = IORESOURCE_DMA, + }, +}; + +static struct platform_device dm365_asp_device = { + .name = "davinci-mcbsp", + .id = -1, + .num_resources = ARRAY_SIZE(dm365_asp_resources), + .resource = dm365_asp_resources, +}; + +static struct resource dm365_vc_resources[] = { + { + .start = DAVINCI_DM365_VC_BASE, + .end = DAVINCI_DM365_VC_BASE + SZ_1K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = DAVINCI_DMA_VC_TX, + .end = DAVINCI_DMA_VC_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = DAVINCI_DMA_VC_RX, + .end = DAVINCI_DMA_VC_RX, + .flags = IORESOURCE_DMA, + }, +}; + +static struct platform_device dm365_vc_device = { + .name = "davinci_voicecodec", + .id = -1, + .num_resources = ARRAY_SIZE(dm365_vc_resources), + .resource = dm365_vc_resources, +}; + +static struct resource dm365_rtc_resources[] = { + { + .start = DM365_RTC_BASE, + .end = DM365_RTC_BASE + SZ_1K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_DM365_RTCINT, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device dm365_rtc_device = { + .name = "rtc_davinci", + .id = 0, + .num_resources = ARRAY_SIZE(dm365_rtc_resources), + .resource = dm365_rtc_resources, +}; + +static struct map_desc dm365_io_desc[] = { + { + .virtual = IO_VIRT, + .pfn = __phys_to_pfn(IO_PHYS), + .length = IO_SIZE, + .type = MT_DEVICE + }, + { + .virtual = SRAM_VIRT, + .pfn = __phys_to_pfn(0x00010000), + .length = SZ_32K, + .type = MT_MEMORY_NONCACHED, + }, +}; + +static struct resource dm365_ks_resources[] = { + { + /* registers */ + .start = DM365_KEYSCAN_BASE, + .end = DM365_KEYSCAN_BASE + SZ_1K - 1, + .flags = IORESOURCE_MEM, + }, + { + /* interrupt */ + .start = IRQ_DM365_KEYINT, + .end = IRQ_DM365_KEYINT, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device dm365_ks_device = { + .name = "davinci_keyscan", + .id = 0, + .num_resources = ARRAY_SIZE(dm365_ks_resources), + .resource = dm365_ks_resources, +}; + +/* Contents of JTAG ID register used to identify exact cpu type */ +static struct davinci_id dm365_ids[] = { + { + .variant = 0x0, + .part_no = 0xb83e, + .manufacturer = 0x017, + .cpu_id = DAVINCI_CPU_ID_DM365, + .name = "dm365_rev1.1", + }, + { + .variant = 0x8, + .part_no = 0xb83e, + .manufacturer = 0x017, + .cpu_id = DAVINCI_CPU_ID_DM365, + .name = "dm365_rev1.2", + }, +}; + +static u32 dm365_psc_bases[] = { DAVINCI_PWR_SLEEP_CNTRL_BASE }; + +static struct davinci_timer_info dm365_timer_info = { + .timers = davinci_timer_instance, + .clockevent_id = T0_BOT, + .clocksource_id = T0_TOP, +}; + +#define DM365_UART1_BASE (IO_PHYS + 0x106000) + +static struct plat_serial8250_port dm365_serial_platform_data[] = { + { + .mapbase = DAVINCI_UART0_BASE, + .irq = IRQ_UARTINT0, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | + UPF_IOREMAP, + .iotype = UPIO_MEM, + .regshift = 2, + }, + { + .mapbase = DM365_UART1_BASE, + .irq = IRQ_UARTINT1, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | + UPF_IOREMAP, + .iotype = UPIO_MEM, + .regshift = 2, + }, + { + .flags = 0 + }, +}; + +static struct platform_device dm365_serial_device = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM, + .dev = { + .platform_data = dm365_serial_platform_data, + }, +}; + +static struct davinci_soc_info davinci_soc_info_dm365 = { + .io_desc = dm365_io_desc, + .io_desc_num = ARRAY_SIZE(dm365_io_desc), + .jtag_id_reg = 0x01c40028, + .ids = dm365_ids, + .ids_num = ARRAY_SIZE(dm365_ids), + .cpu_clks = dm365_clks, + .psc_bases = dm365_psc_bases, + .psc_bases_num = ARRAY_SIZE(dm365_psc_bases), + .pinmux_base = DAVINCI_SYSTEM_MODULE_BASE, + .pinmux_pins = dm365_pins, + .pinmux_pins_num = ARRAY_SIZE(dm365_pins), + .intc_base = DAVINCI_ARM_INTC_BASE, + .intc_type = DAVINCI_INTC_TYPE_AINTC, + .intc_irq_prios = dm365_default_priorities, + .intc_irq_num = DAVINCI_N_AINTC_IRQ, + .timer_info = &dm365_timer_info, + .gpio_type = GPIO_TYPE_DAVINCI, + .gpio_base = DAVINCI_GPIO_BASE, + .gpio_num = 104, + .gpio_irq = IRQ_DM365_GPIO0, + .gpio_unbanked = 8, /* really 16 ... skip muxed GPIOs */ + .serial_dev = &dm365_serial_device, + .emac_pdata = &dm365_emac_pdata, + .sram_dma = 0x00010000, + .sram_len = SZ_32K, +}; + +void __init dm365_init_asp(struct snd_platform_data *pdata) +{ + davinci_cfg_reg(DM365_MCBSP0_BDX); + davinci_cfg_reg(DM365_MCBSP0_X); + davinci_cfg_reg(DM365_MCBSP0_BFSX); + davinci_cfg_reg(DM365_MCBSP0_BDR); + davinci_cfg_reg(DM365_MCBSP0_R); + davinci_cfg_reg(DM365_MCBSP0_BFSR); + davinci_cfg_reg(DM365_EVT2_ASP_TX); + davinci_cfg_reg(DM365_EVT3_ASP_RX); + dm365_asp_device.dev.platform_data = pdata; + platform_device_register(&dm365_asp_device); +} + +void __init dm365_init_vc(struct snd_platform_data *pdata) +{ + davinci_cfg_reg(DM365_EVT2_VC_TX); + davinci_cfg_reg(DM365_EVT3_VC_RX); + dm365_vc_device.dev.platform_data = pdata; + platform_device_register(&dm365_vc_device); +} + +void __init dm365_init_ks(struct davinci_ks_platform_data *pdata) +{ + dm365_ks_device.dev.platform_data = pdata; + platform_device_register(&dm365_ks_device); +} + +void __init dm365_init_rtc(void) +{ + davinci_cfg_reg(DM365_INT_PRTCSS); + platform_device_register(&dm365_rtc_device); +} + +void __init dm365_init(void) +{ + davinci_common_init(&davinci_soc_info_dm365); + davinci_map_sysmod(); +} + +static struct resource dm365_vpss_resources[] = { + { + /* VPSS ISP5 Base address */ + .name = "isp5", + .start = 0x01c70000, + .end = 0x01c70000 + 0xff, + .flags = IORESOURCE_MEM, + }, + { + /* VPSS CLK Base address */ + .name = "vpss", + .start = 0x01c70200, + .end = 0x01c70200 + 0xff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device dm365_vpss_device = { + .name = "vpss", + .id = -1, + .dev.platform_data = "dm365_vpss", + .num_resources = ARRAY_SIZE(dm365_vpss_resources), + .resource = dm365_vpss_resources, +}; + +static struct resource vpfe_resources[] = { + { + .start = IRQ_VDINT0, + .end = IRQ_VDINT0, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_VDINT1, + .end = IRQ_VDINT1, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 vpfe_capture_dma_mask = DMA_BIT_MASK(32); +static struct platform_device vpfe_capture_dev = { + .name = CAPTURE_DRV_NAME, + .id = -1, + .num_resources = ARRAY_SIZE(vpfe_resources), + .resource = vpfe_resources, + .dev = { + .dma_mask = &vpfe_capture_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +static void dm365_isif_setup_pinmux(void) +{ + davinci_cfg_reg(DM365_VIN_CAM_WEN); + davinci_cfg_reg(DM365_VIN_CAM_VD); + davinci_cfg_reg(DM365_VIN_CAM_HD); + davinci_cfg_reg(DM365_VIN_YIN4_7_EN); + davinci_cfg_reg(DM365_VIN_YIN0_3_EN); +} + +static struct resource isif_resource[] = { + /* ISIF Base address */ + { + .start = 0x01c71000, + .end = 0x01c71000 + 0x1ff, + .flags = IORESOURCE_MEM, + }, + /* ISIF Linearization table 0 */ + { + .start = 0x1C7C000, + .end = 0x1C7C000 + 0x2ff, + .flags = IORESOURCE_MEM, + }, + /* ISIF Linearization table 1 */ + { + .start = 0x1C7C400, + .end = 0x1C7C400 + 0x2ff, + .flags = IORESOURCE_MEM, + }, +}; +static struct platform_device dm365_isif_dev = { + .name = "isif", + .id = -1, + .num_resources = ARRAY_SIZE(isif_resource), + .resource = isif_resource, + .dev = { + .dma_mask = &vpfe_capture_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = dm365_isif_setup_pinmux, + }, +}; + +static int __init dm365_init_devices(void) +{ + if (!cpu_is_davinci_dm365()) + return 0; + + davinci_cfg_reg(DM365_INT_EDMA_CC); + platform_device_register(&dm365_edma_device); + + platform_device_register(&dm365_mdio_device); + platform_device_register(&dm365_emac_device); + clk_add_alias(NULL, dev_name(&dm365_mdio_device.dev), + NULL, &dm365_emac_device.dev); + + /* Add isif clock alias */ + clk_add_alias("master", dm365_isif_dev.name, "vpss_master", NULL); + platform_device_register(&dm365_vpss_device); + platform_device_register(&dm365_isif_dev); + platform_device_register(&vpfe_capture_dev); + return 0; +} +postcore_initcall(dm365_init_devices); + +void dm365_set_vpfe_config(struct vpfe_config *cfg) +{ + vpfe_capture_dev.dev.platform_data = cfg; +} diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/dm644x.c b/ANDROID_3.4.5/arch/arm/mach-davinci/dm644x.c new file mode 100644 index 00000000..c8b86665 --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/dm644x.c @@ -0,0 +1,958 @@ +/* + * TI DaVinci DM644x chip specific setup + * + * Author: Kevin Hilman, Deep Root Systems, LLC + * + * 2007 (c) Deep Root Systems, LLC. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ +#include <linux/init.h> +#include <linux/clk.h> +#include <linux/serial_8250.h> +#include <linux/platform_device.h> + +#include <asm/mach/map.h> + +#include <mach/cputype.h> +#include <mach/edma.h> +#include <mach/irqs.h> +#include <mach/psc.h> +#include <mach/mux.h> +#include <mach/time.h> +#include <mach/serial.h> +#include <mach/common.h> +#include <mach/asp.h> +#include <mach/gpio-davinci.h> + +#include "davinci.h" +#include "clock.h" +#include "mux.h" + +/* + * Device specific clocks + */ +#define DM644X_REF_FREQ 27000000 + +#define DM644X_EMAC_BASE 0x01c80000 +#define DM644X_EMAC_MDIO_BASE (DM644X_EMAC_BASE + 0x4000) +#define DM644X_EMAC_CNTRL_OFFSET 0x0000 +#define DM644X_EMAC_CNTRL_MOD_OFFSET 0x1000 +#define DM644X_EMAC_CNTRL_RAM_OFFSET 0x2000 +#define DM644X_EMAC_CNTRL_RAM_SIZE 0x2000 + +static struct pll_data pll1_data = { + .num = 1, + .phys_base = DAVINCI_PLL1_BASE, +}; + +static struct pll_data pll2_data = { + .num = 2, + .phys_base = DAVINCI_PLL2_BASE, +}; + +static struct clk ref_clk = { + .name = "ref_clk", + .rate = DM644X_REF_FREQ, +}; + +static struct clk pll1_clk = { + .name = "pll1", + .parent = &ref_clk, + .pll_data = &pll1_data, + .flags = CLK_PLL, +}; + +static struct clk pll1_sysclk1 = { + .name = "pll1_sysclk1", + .parent = &pll1_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV1, +}; + +static struct clk pll1_sysclk2 = { + .name = "pll1_sysclk2", + .parent = &pll1_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV2, +}; + +static struct clk pll1_sysclk3 = { + .name = "pll1_sysclk3", + .parent = &pll1_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV3, +}; + +static struct clk pll1_sysclk5 = { + .name = "pll1_sysclk5", + .parent = &pll1_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV5, +}; + +static struct clk pll1_aux_clk = { + .name = "pll1_aux_clk", + .parent = &pll1_clk, + .flags = CLK_PLL | PRE_PLL, +}; + +static struct clk pll1_sysclkbp = { + .name = "pll1_sysclkbp", + .parent = &pll1_clk, + .flags = CLK_PLL | PRE_PLL, + .div_reg = BPDIV +}; + +static struct clk pll2_clk = { + .name = "pll2", + .parent = &ref_clk, + .pll_data = &pll2_data, + .flags = CLK_PLL, +}; + +static struct clk pll2_sysclk1 = { + .name = "pll2_sysclk1", + .parent = &pll2_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV1, +}; + +static struct clk pll2_sysclk2 = { + .name = "pll2_sysclk2", + .parent = &pll2_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV2, +}; + +static struct clk pll2_sysclkbp = { + .name = "pll2_sysclkbp", + .parent = &pll2_clk, + .flags = CLK_PLL | PRE_PLL, + .div_reg = BPDIV +}; + +static struct clk dsp_clk = { + .name = "dsp", + .parent = &pll1_sysclk1, + .lpsc = DAVINCI_LPSC_GEM, + .domain = DAVINCI_GPSC_DSPDOMAIN, + .usecount = 1, /* REVISIT how to disable? */ +}; + +static struct clk arm_clk = { + .name = "arm", + .parent = &pll1_sysclk2, + .lpsc = DAVINCI_LPSC_ARM, + .flags = ALWAYS_ENABLED, +}; + +static struct clk vicp_clk = { + .name = "vicp", + .parent = &pll1_sysclk2, + .lpsc = DAVINCI_LPSC_IMCOP, + .domain = DAVINCI_GPSC_DSPDOMAIN, + .usecount = 1, /* REVISIT how to disable? */ +}; + +static struct clk vpss_master_clk = { + .name = "vpss_master", + .parent = &pll1_sysclk3, + .lpsc = DAVINCI_LPSC_VPSSMSTR, + .flags = CLK_PSC, +}; + +static struct clk vpss_slave_clk = { + .name = "vpss_slave", + .parent = &pll1_sysclk3, + .lpsc = DAVINCI_LPSC_VPSSSLV, +}; + +static struct clk uart0_clk = { + .name = "uart0", + .parent = &pll1_aux_clk, + .lpsc = DAVINCI_LPSC_UART0, +}; + +static struct clk uart1_clk = { + .name = "uart1", + .parent = &pll1_aux_clk, + .lpsc = DAVINCI_LPSC_UART1, +}; + +static struct clk uart2_clk = { + .name = "uart2", + .parent = &pll1_aux_clk, + .lpsc = DAVINCI_LPSC_UART2, +}; + +static struct clk emac_clk = { + .name = "emac", + .parent = &pll1_sysclk5, + .lpsc = DAVINCI_LPSC_EMAC_WRAPPER, +}; + +static struct clk i2c_clk = { + .name = "i2c", + .parent = &pll1_aux_clk, + .lpsc = DAVINCI_LPSC_I2C, +}; + +static struct clk ide_clk = { + .name = "ide", + .parent = &pll1_sysclk5, + .lpsc = DAVINCI_LPSC_ATA, +}; + +static struct clk asp_clk = { + .name = "asp0", + .parent = &pll1_sysclk5, + .lpsc = DAVINCI_LPSC_McBSP, +}; + +static struct clk mmcsd_clk = { + .name = "mmcsd", + .parent = &pll1_sysclk5, + .lpsc = DAVINCI_LPSC_MMC_SD, +}; + +static struct clk spi_clk = { + .name = "spi", + .parent = &pll1_sysclk5, + .lpsc = DAVINCI_LPSC_SPI, +}; + +static struct clk gpio_clk = { + .name = "gpio", + .parent = &pll1_sysclk5, + .lpsc = DAVINCI_LPSC_GPIO, +}; + +static struct clk usb_clk = { + .name = "usb", + .parent = &pll1_sysclk5, + .lpsc = DAVINCI_LPSC_USB, +}; + +static struct clk vlynq_clk = { + .name = "vlynq", + .parent = &pll1_sysclk5, + .lpsc = DAVINCI_LPSC_VLYNQ, +}; + +static struct clk aemif_clk = { + .name = "aemif", + .parent = &pll1_sysclk5, + .lpsc = DAVINCI_LPSC_AEMIF, +}; + +static struct clk pwm0_clk = { + .name = "pwm0", + .parent = &pll1_aux_clk, + .lpsc = DAVINCI_LPSC_PWM0, +}; + +static struct clk pwm1_clk = { + .name = "pwm1", + .parent = &pll1_aux_clk, + .lpsc = DAVINCI_LPSC_PWM1, +}; + +static struct clk pwm2_clk = { + .name = "pwm2", + .parent = &pll1_aux_clk, + .lpsc = DAVINCI_LPSC_PWM2, +}; + +static struct clk timer0_clk = { + .name = "timer0", + .parent = &pll1_aux_clk, + .lpsc = DAVINCI_LPSC_TIMER0, +}; + +static struct clk timer1_clk = { + .name = "timer1", + .parent = &pll1_aux_clk, + .lpsc = DAVINCI_LPSC_TIMER1, +}; + +static struct clk timer2_clk = { + .name = "timer2", + .parent = &pll1_aux_clk, + .lpsc = DAVINCI_LPSC_TIMER2, + .usecount = 1, /* REVISIT: why can't this be disabled? */ +}; + +static struct clk_lookup dm644x_clks[] = { + CLK(NULL, "ref", &ref_clk), + CLK(NULL, "pll1", &pll1_clk), + CLK(NULL, "pll1_sysclk1", &pll1_sysclk1), + CLK(NULL, "pll1_sysclk2", &pll1_sysclk2), + CLK(NULL, "pll1_sysclk3", &pll1_sysclk3), + CLK(NULL, "pll1_sysclk5", &pll1_sysclk5), + CLK(NULL, "pll1_aux", &pll1_aux_clk), + CLK(NULL, "pll1_sysclkbp", &pll1_sysclkbp), + CLK(NULL, "pll2", &pll2_clk), + CLK(NULL, "pll2_sysclk1", &pll2_sysclk1), + CLK(NULL, "pll2_sysclk2", &pll2_sysclk2), + CLK(NULL, "pll2_sysclkbp", &pll2_sysclkbp), + CLK(NULL, "dsp", &dsp_clk), + CLK(NULL, "arm", &arm_clk), + CLK(NULL, "vicp", &vicp_clk), + CLK(NULL, "vpss_master", &vpss_master_clk), + CLK(NULL, "vpss_slave", &vpss_slave_clk), + CLK(NULL, "arm", &arm_clk), + CLK(NULL, "uart0", &uart0_clk), + CLK(NULL, "uart1", &uart1_clk), + CLK(NULL, "uart2", &uart2_clk), + CLK("davinci_emac.1", NULL, &emac_clk), + CLK("i2c_davinci.1", NULL, &i2c_clk), + CLK("palm_bk3710", NULL, &ide_clk), + CLK("davinci-mcbsp", NULL, &asp_clk), + CLK("davinci_mmc.0", NULL, &mmcsd_clk), + CLK(NULL, "spi", &spi_clk), + CLK(NULL, "gpio", &gpio_clk), + CLK(NULL, "usb", &usb_clk), + CLK(NULL, "vlynq", &vlynq_clk), + CLK(NULL, "aemif", &aemif_clk), + CLK(NULL, "pwm0", &pwm0_clk), + CLK(NULL, "pwm1", &pwm1_clk), + CLK(NULL, "pwm2", &pwm2_clk), + CLK(NULL, "timer0", &timer0_clk), + CLK(NULL, "timer1", &timer1_clk), + CLK("watchdog", NULL, &timer2_clk), + CLK(NULL, NULL, NULL), +}; + +static struct emac_platform_data dm644x_emac_pdata = { + .ctrl_reg_offset = DM644X_EMAC_CNTRL_OFFSET, + .ctrl_mod_reg_offset = DM644X_EMAC_CNTRL_MOD_OFFSET, + .ctrl_ram_offset = DM644X_EMAC_CNTRL_RAM_OFFSET, + .ctrl_ram_size = DM644X_EMAC_CNTRL_RAM_SIZE, + .version = EMAC_VERSION_1, +}; + +static struct resource dm644x_emac_resources[] = { + { + .start = DM644X_EMAC_BASE, + .end = DM644X_EMAC_BASE + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_EMACINT, + .end = IRQ_EMACINT, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device dm644x_emac_device = { + .name = "davinci_emac", + .id = 1, + .dev = { + .platform_data = &dm644x_emac_pdata, + }, + .num_resources = ARRAY_SIZE(dm644x_emac_resources), + .resource = dm644x_emac_resources, +}; + +static struct resource dm644x_mdio_resources[] = { + { + .start = DM644X_EMAC_MDIO_BASE, + .end = DM644X_EMAC_MDIO_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device dm644x_mdio_device = { + .name = "davinci_mdio", + .id = 0, + .num_resources = ARRAY_SIZE(dm644x_mdio_resources), + .resource = dm644x_mdio_resources, +}; + +/* + * Device specific mux setup + * + * soc description mux mode mode mux dbg + * reg offset mask mode + */ +static const struct mux_config dm644x_pins[] = { +#ifdef CONFIG_DAVINCI_MUX +MUX_CFG(DM644X, HDIREN, 0, 16, 1, 1, true) +MUX_CFG(DM644X, ATAEN, 0, 17, 1, 1, true) +MUX_CFG(DM644X, ATAEN_DISABLE, 0, 17, 1, 0, true) + +MUX_CFG(DM644X, HPIEN_DISABLE, 0, 29, 1, 0, true) + +MUX_CFG(DM644X, AEAW, 0, 0, 31, 31, true) +MUX_CFG(DM644X, AEAW0, 0, 0, 1, 0, true) +MUX_CFG(DM644X, AEAW1, 0, 1, 1, 0, true) +MUX_CFG(DM644X, AEAW2, 0, 2, 1, 0, true) +MUX_CFG(DM644X, AEAW3, 0, 3, 1, 0, true) +MUX_CFG(DM644X, AEAW4, 0, 4, 1, 0, true) + +MUX_CFG(DM644X, MSTK, 1, 9, 1, 0, false) + +MUX_CFG(DM644X, I2C, 1, 7, 1, 1, false) + +MUX_CFG(DM644X, MCBSP, 1, 10, 1, 1, false) + +MUX_CFG(DM644X, UART1, 1, 1, 1, 1, true) +MUX_CFG(DM644X, UART2, 1, 2, 1, 1, true) + +MUX_CFG(DM644X, PWM0, 1, 4, 1, 1, false) + +MUX_CFG(DM644X, PWM1, 1, 5, 1, 1, false) + +MUX_CFG(DM644X, PWM2, 1, 6, 1, 1, false) + +MUX_CFG(DM644X, VLYNQEN, 0, 15, 1, 1, false) +MUX_CFG(DM644X, VLSCREN, 0, 14, 1, 1, false) +MUX_CFG(DM644X, VLYNQWD, 0, 12, 3, 3, false) + +MUX_CFG(DM644X, EMACEN, 0, 31, 1, 1, true) + +MUX_CFG(DM644X, GPIO3V, 0, 31, 1, 0, true) + +MUX_CFG(DM644X, GPIO0, 0, 24, 1, 0, true) +MUX_CFG(DM644X, GPIO3, 0, 25, 1, 0, false) +MUX_CFG(DM644X, GPIO43_44, 1, 7, 1, 0, false) +MUX_CFG(DM644X, GPIO46_47, 0, 22, 1, 0, true) + +MUX_CFG(DM644X, RGB666, 0, 22, 1, 1, true) + +MUX_CFG(DM644X, LOEEN, 0, 24, 1, 1, true) +MUX_CFG(DM644X, LFLDEN, 0, 25, 1, 1, false) +#endif +}; + +/* FIQ are pri 0-1; otherwise 2-7, with 7 lowest priority */ +static u8 dm644x_default_priorities[DAVINCI_N_AINTC_IRQ] = { + [IRQ_VDINT0] = 2, + [IRQ_VDINT1] = 6, + [IRQ_VDINT2] = 6, + [IRQ_HISTINT] = 6, + [IRQ_H3AINT] = 6, + [IRQ_PRVUINT] = 6, + [IRQ_RSZINT] = 6, + [7] = 7, + [IRQ_VENCINT] = 6, + [IRQ_ASQINT] = 6, + [IRQ_IMXINT] = 6, + [IRQ_VLCDINT] = 6, + [IRQ_USBINT] = 4, + [IRQ_EMACINT] = 4, + [14] = 7, + [15] = 7, + [IRQ_CCINT0] = 5, /* dma */ + [IRQ_CCERRINT] = 5, /* dma */ + [IRQ_TCERRINT0] = 5, /* dma */ + [IRQ_TCERRINT] = 5, /* dma */ + [IRQ_PSCIN] = 7, + [21] = 7, + [IRQ_IDE] = 4, + [23] = 7, + [IRQ_MBXINT] = 7, + [IRQ_MBRINT] = 7, + [IRQ_MMCINT] = 7, + [IRQ_SDIOINT] = 7, + [28] = 7, + [IRQ_DDRINT] = 7, + [IRQ_AEMIFINT] = 7, + [IRQ_VLQINT] = 4, + [IRQ_TINT0_TINT12] = 2, /* clockevent */ + [IRQ_TINT0_TINT34] = 2, /* clocksource */ + [IRQ_TINT1_TINT12] = 7, /* DSP timer */ + [IRQ_TINT1_TINT34] = 7, /* system tick */ + [IRQ_PWMINT0] = 7, + [IRQ_PWMINT1] = 7, + [IRQ_PWMINT2] = 7, + [IRQ_I2C] = 3, + [IRQ_UARTINT0] = 3, + [IRQ_UARTINT1] = 3, + [IRQ_UARTINT2] = 3, + [IRQ_SPINT0] = 3, + [IRQ_SPINT1] = 3, + [45] = 7, + [IRQ_DSP2ARM0] = 4, + [IRQ_DSP2ARM1] = 4, + [IRQ_GPIO0] = 7, + [IRQ_GPIO1] = 7, + [IRQ_GPIO2] = 7, + [IRQ_GPIO3] = 7, + [IRQ_GPIO4] = 7, + [IRQ_GPIO5] = 7, + [IRQ_GPIO6] = 7, + [IRQ_GPIO7] = 7, + [IRQ_GPIOBNK0] = 7, + [IRQ_GPIOBNK1] = 7, + [IRQ_GPIOBNK2] = 7, + [IRQ_GPIOBNK3] = 7, + [IRQ_GPIOBNK4] = 7, + [IRQ_COMMTX] = 7, + [IRQ_COMMRX] = 7, + [IRQ_EMUINT] = 7, +}; + +/*----------------------------------------------------------------------*/ + +static const s8 +queue_tc_mapping[][2] = { + /* {event queue no, TC no} */ + {0, 0}, + {1, 1}, + {-1, -1}, +}; + +static const s8 +queue_priority_mapping[][2] = { + /* {event queue no, Priority} */ + {0, 3}, + {1, 7}, + {-1, -1}, +}; + +static struct edma_soc_info edma_cc0_info = { + .n_channel = 64, + .n_region = 4, + .n_slot = 128, + .n_tc = 2, + .n_cc = 1, + .queue_tc_mapping = queue_tc_mapping, + .queue_priority_mapping = queue_priority_mapping, + .default_queue = EVENTQ_1, +}; + +static struct edma_soc_info *dm644x_edma_info[EDMA_MAX_CC] = { + &edma_cc0_info, +}; + +static struct resource edma_resources[] = { + { + .name = "edma_cc0", + .start = 0x01c00000, + .end = 0x01c00000 + SZ_64K - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "edma_tc0", + .start = 0x01c10000, + .end = 0x01c10000 + SZ_1K - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "edma_tc1", + .start = 0x01c10400, + .end = 0x01c10400 + SZ_1K - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "edma0", + .start = IRQ_CCINT0, + .flags = IORESOURCE_IRQ, + }, + { + .name = "edma0_err", + .start = IRQ_CCERRINT, + .flags = IORESOURCE_IRQ, + }, + /* not using TC*_ERR */ +}; + +static struct platform_device dm644x_edma_device = { + .name = "edma", + .id = 0, + .dev.platform_data = dm644x_edma_info, + .num_resources = ARRAY_SIZE(edma_resources), + .resource = edma_resources, +}; + +/* DM6446 EVM uses ASP0; line-out is a pair of RCA jacks */ +static struct resource dm644x_asp_resources[] = { + { + .start = DAVINCI_ASP0_BASE, + .end = DAVINCI_ASP0_BASE + SZ_8K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = DAVINCI_DMA_ASP0_TX, + .end = DAVINCI_DMA_ASP0_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = DAVINCI_DMA_ASP0_RX, + .end = DAVINCI_DMA_ASP0_RX, + .flags = IORESOURCE_DMA, + }, +}; + +static struct platform_device dm644x_asp_device = { + .name = "davinci-mcbsp", + .id = -1, + .num_resources = ARRAY_SIZE(dm644x_asp_resources), + .resource = dm644x_asp_resources, +}; + +#define DM644X_VPSS_BASE 0x01c73400 + +static struct resource dm644x_vpss_resources[] = { + { + /* VPSS Base address */ + .name = "vpss", + .start = DM644X_VPSS_BASE, + .end = DM644X_VPSS_BASE + 0xff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device dm644x_vpss_device = { + .name = "vpss", + .id = -1, + .dev.platform_data = "dm644x_vpss", + .num_resources = ARRAY_SIZE(dm644x_vpss_resources), + .resource = dm644x_vpss_resources, +}; + +static struct resource dm644x_vpfe_resources[] = { + { + .start = IRQ_VDINT0, + .end = IRQ_VDINT0, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_VDINT1, + .end = IRQ_VDINT1, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 dm644x_video_dma_mask = DMA_BIT_MASK(32); +static struct resource dm644x_ccdc_resource[] = { + /* CCDC Base address */ + { + .start = 0x01c70400, + .end = 0x01c70400 + 0xff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device dm644x_ccdc_dev = { + .name = "dm644x_ccdc", + .id = -1, + .num_resources = ARRAY_SIZE(dm644x_ccdc_resource), + .resource = dm644x_ccdc_resource, + .dev = { + .dma_mask = &dm644x_video_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +static struct platform_device dm644x_vpfe_dev = { + .name = CAPTURE_DRV_NAME, + .id = -1, + .num_resources = ARRAY_SIZE(dm644x_vpfe_resources), + .resource = dm644x_vpfe_resources, + .dev = { + .dma_mask = &dm644x_video_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +#define DM644X_OSD_BASE 0x01c72600 + +static struct resource dm644x_osd_resources[] = { + { + .start = DM644X_OSD_BASE, + .end = DM644X_OSD_BASE + 0x1ff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct osd_platform_data dm644x_osd_data = { + .vpbe_type = VPBE_VERSION_1, +}; + +static struct platform_device dm644x_osd_dev = { + .name = VPBE_OSD_SUBDEV_NAME, + .id = -1, + .num_resources = ARRAY_SIZE(dm644x_osd_resources), + .resource = dm644x_osd_resources, + .dev = { + .dma_mask = &dm644x_video_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &dm644x_osd_data, + }, +}; + +#define DM644X_VENC_BASE 0x01c72400 + +static struct resource dm644x_venc_resources[] = { + { + .start = DM644X_VENC_BASE, + .end = DM644X_VENC_BASE + 0x17f, + .flags = IORESOURCE_MEM, + }, +}; + +#define DM644X_VPSS_MUXSEL_PLL2_MODE BIT(0) +#define DM644X_VPSS_MUXSEL_VPBECLK_MODE BIT(1) +#define DM644X_VPSS_VENCLKEN BIT(3) +#define DM644X_VPSS_DACCLKEN BIT(4) + +static int dm644x_venc_setup_clock(enum vpbe_enc_timings_type type, + unsigned int mode) +{ + int ret = 0; + u32 v = DM644X_VPSS_VENCLKEN; + + switch (type) { + case VPBE_ENC_STD: + v |= DM644X_VPSS_DACCLKEN; + writel(v, DAVINCI_SYSMOD_VIRT(SYSMOD_VPSS_CLKCTL)); + break; + case VPBE_ENC_DV_PRESET: + switch (mode) { + case V4L2_DV_480P59_94: + case V4L2_DV_576P50: + v |= DM644X_VPSS_MUXSEL_PLL2_MODE | + DM644X_VPSS_DACCLKEN; + writel(v, DAVINCI_SYSMOD_VIRT(SYSMOD_VPSS_CLKCTL)); + break; + case V4L2_DV_720P60: + case V4L2_DV_1080I60: + case V4L2_DV_1080P30: + /* + * For HD, use external clock source since + * HD requires higher clock rate + */ + v |= DM644X_VPSS_MUXSEL_VPBECLK_MODE; + writel(v, DAVINCI_SYSMOD_VIRT(SYSMOD_VPSS_CLKCTL)); + break; + default: + ret = -EINVAL; + break; + } + break; + default: + ret = -EINVAL; + } + + return ret; +} + +static struct resource dm644x_v4l2_disp_resources[] = { + { + .start = IRQ_VENCINT, + .end = IRQ_VENCINT, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device dm644x_vpbe_display = { + .name = "vpbe-v4l2", + .id = -1, + .num_resources = ARRAY_SIZE(dm644x_v4l2_disp_resources), + .resource = dm644x_v4l2_disp_resources, + .dev = { + .dma_mask = &dm644x_video_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +static struct venc_platform_data dm644x_venc_pdata = { + .venc_type = VPBE_VERSION_1, + .setup_clock = dm644x_venc_setup_clock, +}; + +static struct platform_device dm644x_venc_dev = { + .name = VPBE_VENC_SUBDEV_NAME, + .id = -1, + .num_resources = ARRAY_SIZE(dm644x_venc_resources), + .resource = dm644x_venc_resources, + .dev = { + .dma_mask = &dm644x_video_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &dm644x_venc_pdata, + }, +}; + +static struct platform_device dm644x_vpbe_dev = { + .name = "vpbe_controller", + .id = -1, + .dev = { + .dma_mask = &dm644x_video_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +/*----------------------------------------------------------------------*/ + +static struct map_desc dm644x_io_desc[] = { + { + .virtual = IO_VIRT, + .pfn = __phys_to_pfn(IO_PHYS), + .length = IO_SIZE, + .type = MT_DEVICE + }, + { + .virtual = SRAM_VIRT, + .pfn = __phys_to_pfn(0x00008000), + .length = SZ_16K, + .type = MT_MEMORY_NONCACHED, + }, +}; + +/* Contents of JTAG ID register used to identify exact cpu type */ +static struct davinci_id dm644x_ids[] = { + { + .variant = 0x0, + .part_no = 0xb700, + .manufacturer = 0x017, + .cpu_id = DAVINCI_CPU_ID_DM6446, + .name = "dm6446", + }, + { + .variant = 0x1, + .part_no = 0xb700, + .manufacturer = 0x017, + .cpu_id = DAVINCI_CPU_ID_DM6446, + .name = "dm6446a", + }, +}; + +static u32 dm644x_psc_bases[] = { DAVINCI_PWR_SLEEP_CNTRL_BASE }; + +/* + * T0_BOT: Timer 0, bottom: clockevent source for hrtimers + * T0_TOP: Timer 0, top : clocksource for generic timekeeping + * T1_BOT: Timer 1, bottom: (used by DSP in TI DSPLink code) + * T1_TOP: Timer 1, top : <unused> + */ +static struct davinci_timer_info dm644x_timer_info = { + .timers = davinci_timer_instance, + .clockevent_id = T0_BOT, + .clocksource_id = T0_TOP, +}; + +static struct plat_serial8250_port dm644x_serial_platform_data[] = { + { + .mapbase = DAVINCI_UART0_BASE, + .irq = IRQ_UARTINT0, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | + UPF_IOREMAP, + .iotype = UPIO_MEM, + .regshift = 2, + }, + { + .mapbase = DAVINCI_UART1_BASE, + .irq = IRQ_UARTINT1, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | + UPF_IOREMAP, + .iotype = UPIO_MEM, + .regshift = 2, + }, + { + .mapbase = DAVINCI_UART2_BASE, + .irq = IRQ_UARTINT2, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | + UPF_IOREMAP, + .iotype = UPIO_MEM, + .regshift = 2, + }, + { + .flags = 0 + }, +}; + +static struct platform_device dm644x_serial_device = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM, + .dev = { + .platform_data = dm644x_serial_platform_data, + }, +}; + +static struct davinci_soc_info davinci_soc_info_dm644x = { + .io_desc = dm644x_io_desc, + .io_desc_num = ARRAY_SIZE(dm644x_io_desc), + .jtag_id_reg = 0x01c40028, + .ids = dm644x_ids, + .ids_num = ARRAY_SIZE(dm644x_ids), + .cpu_clks = dm644x_clks, + .psc_bases = dm644x_psc_bases, + .psc_bases_num = ARRAY_SIZE(dm644x_psc_bases), + .pinmux_base = DAVINCI_SYSTEM_MODULE_BASE, + .pinmux_pins = dm644x_pins, + .pinmux_pins_num = ARRAY_SIZE(dm644x_pins), + .intc_base = DAVINCI_ARM_INTC_BASE, + .intc_type = DAVINCI_INTC_TYPE_AINTC, + .intc_irq_prios = dm644x_default_priorities, + .intc_irq_num = DAVINCI_N_AINTC_IRQ, + .timer_info = &dm644x_timer_info, + .gpio_type = GPIO_TYPE_DAVINCI, + .gpio_base = DAVINCI_GPIO_BASE, + .gpio_num = 71, + .gpio_irq = IRQ_GPIOBNK0, + .serial_dev = &dm644x_serial_device, + .emac_pdata = &dm644x_emac_pdata, + .sram_dma = 0x00008000, + .sram_len = SZ_16K, +}; + +void __init dm644x_init_asp(struct snd_platform_data *pdata) +{ + davinci_cfg_reg(DM644X_MCBSP); + dm644x_asp_device.dev.platform_data = pdata; + platform_device_register(&dm644x_asp_device); +} + +void __init dm644x_init(void) +{ + davinci_common_init(&davinci_soc_info_dm644x); + davinci_map_sysmod(); +} + +int __init dm644x_init_video(struct vpfe_config *vpfe_cfg, + struct vpbe_config *vpbe_cfg) +{ + if (vpfe_cfg || vpbe_cfg) + platform_device_register(&dm644x_vpss_device); + + if (vpfe_cfg) { + dm644x_vpfe_dev.dev.platform_data = vpfe_cfg; + platform_device_register(&dm644x_ccdc_dev); + platform_device_register(&dm644x_vpfe_dev); + /* Add ccdc clock aliases */ + clk_add_alias("master", dm644x_ccdc_dev.name, + "vpss_master", NULL); + clk_add_alias("slave", dm644x_ccdc_dev.name, + "vpss_slave", NULL); + } + + if (vpbe_cfg) { + dm644x_vpbe_dev.dev.platform_data = vpbe_cfg; + platform_device_register(&dm644x_osd_dev); + platform_device_register(&dm644x_venc_dev); + platform_device_register(&dm644x_vpbe_dev); + platform_device_register(&dm644x_vpbe_display); + } + + return 0; +} + +static int __init dm644x_init_devices(void) +{ + if (!cpu_is_davinci_dm644x()) + return 0; + + platform_device_register(&dm644x_edma_device); + + platform_device_register(&dm644x_mdio_device); + platform_device_register(&dm644x_emac_device); + clk_add_alias(NULL, dev_name(&dm644x_mdio_device.dev), + NULL, &dm644x_emac_device.dev); + + return 0; +} +postcore_initcall(dm644x_init_devices); diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/dm646x.c b/ANDROID_3.4.5/arch/arm/mach-davinci/dm646x.c new file mode 100644 index 00000000..9eb87c1d --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/dm646x.c @@ -0,0 +1,927 @@ +/* + * TI DaVinci DM644x chip specific setup + * + * Author: Kevin Hilman, Deep Root Systems, LLC + * + * 2007 (c) Deep Root Systems, LLC. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ +#include <linux/dma-mapping.h> +#include <linux/init.h> +#include <linux/clk.h> +#include <linux/serial_8250.h> +#include <linux/platform_device.h> + +#include <asm/mach/map.h> + +#include <mach/cputype.h> +#include <mach/edma.h> +#include <mach/irqs.h> +#include <mach/psc.h> +#include <mach/mux.h> +#include <mach/time.h> +#include <mach/serial.h> +#include <mach/common.h> +#include <mach/asp.h> +#include <mach/gpio-davinci.h> + +#include "davinci.h" +#include "clock.h" +#include "mux.h" + +#define DAVINCI_VPIF_BASE (0x01C12000) + +#define VDD3P3V_VID_MASK (BIT_MASK(3) | BIT_MASK(2) | BIT_MASK(1) |\ + BIT_MASK(0)) +#define VSCLKDIS_MASK (BIT_MASK(11) | BIT_MASK(10) | BIT_MASK(9) |\ + BIT_MASK(8)) + +/* + * Device specific clocks + */ +#define DM646X_REF_FREQ 27000000 +#define DM646X_AUX_FREQ 24000000 + +#define DM646X_EMAC_BASE 0x01c80000 +#define DM646X_EMAC_MDIO_BASE (DM646X_EMAC_BASE + 0x4000) +#define DM646X_EMAC_CNTRL_OFFSET 0x0000 +#define DM646X_EMAC_CNTRL_MOD_OFFSET 0x1000 +#define DM646X_EMAC_CNTRL_RAM_OFFSET 0x2000 +#define DM646X_EMAC_CNTRL_RAM_SIZE 0x2000 + +static struct pll_data pll1_data = { + .num = 1, + .phys_base = DAVINCI_PLL1_BASE, +}; + +static struct pll_data pll2_data = { + .num = 2, + .phys_base = DAVINCI_PLL2_BASE, +}; + +static struct clk ref_clk = { + .name = "ref_clk", + .rate = DM646X_REF_FREQ, + .set_rate = davinci_simple_set_rate, +}; + +static struct clk aux_clkin = { + .name = "aux_clkin", + .rate = DM646X_AUX_FREQ, +}; + +static struct clk pll1_clk = { + .name = "pll1", + .parent = &ref_clk, + .pll_data = &pll1_data, + .flags = CLK_PLL, +}; + +static struct clk pll1_sysclk1 = { + .name = "pll1_sysclk1", + .parent = &pll1_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV1, +}; + +static struct clk pll1_sysclk2 = { + .name = "pll1_sysclk2", + .parent = &pll1_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV2, +}; + +static struct clk pll1_sysclk3 = { + .name = "pll1_sysclk3", + .parent = &pll1_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV3, +}; + +static struct clk pll1_sysclk4 = { + .name = "pll1_sysclk4", + .parent = &pll1_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV4, +}; + +static struct clk pll1_sysclk5 = { + .name = "pll1_sysclk5", + .parent = &pll1_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV5, +}; + +static struct clk pll1_sysclk6 = { + .name = "pll1_sysclk6", + .parent = &pll1_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV6, +}; + +static struct clk pll1_sysclk8 = { + .name = "pll1_sysclk8", + .parent = &pll1_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV8, +}; + +static struct clk pll1_sysclk9 = { + .name = "pll1_sysclk9", + .parent = &pll1_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV9, +}; + +static struct clk pll1_sysclkbp = { + .name = "pll1_sysclkbp", + .parent = &pll1_clk, + .flags = CLK_PLL | PRE_PLL, + .div_reg = BPDIV, +}; + +static struct clk pll1_aux_clk = { + .name = "pll1_aux_clk", + .parent = &pll1_clk, + .flags = CLK_PLL | PRE_PLL, +}; + +static struct clk pll2_clk = { + .name = "pll2_clk", + .parent = &ref_clk, + .pll_data = &pll2_data, + .flags = CLK_PLL, +}; + +static struct clk pll2_sysclk1 = { + .name = "pll2_sysclk1", + .parent = &pll2_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV1, +}; + +static struct clk dsp_clk = { + .name = "dsp", + .parent = &pll1_sysclk1, + .lpsc = DM646X_LPSC_C64X_CPU, + .usecount = 1, /* REVISIT how to disable? */ +}; + +static struct clk arm_clk = { + .name = "arm", + .parent = &pll1_sysclk2, + .lpsc = DM646X_LPSC_ARM, + .flags = ALWAYS_ENABLED, +}; + +static struct clk edma_cc_clk = { + .name = "edma_cc", + .parent = &pll1_sysclk2, + .lpsc = DM646X_LPSC_TPCC, + .flags = ALWAYS_ENABLED, +}; + +static struct clk edma_tc0_clk = { + .name = "edma_tc0", + .parent = &pll1_sysclk2, + .lpsc = DM646X_LPSC_TPTC0, + .flags = ALWAYS_ENABLED, +}; + +static struct clk edma_tc1_clk = { + .name = "edma_tc1", + .parent = &pll1_sysclk2, + .lpsc = DM646X_LPSC_TPTC1, + .flags = ALWAYS_ENABLED, +}; + +static struct clk edma_tc2_clk = { + .name = "edma_tc2", + .parent = &pll1_sysclk2, + .lpsc = DM646X_LPSC_TPTC2, + .flags = ALWAYS_ENABLED, +}; + +static struct clk edma_tc3_clk = { + .name = "edma_tc3", + .parent = &pll1_sysclk2, + .lpsc = DM646X_LPSC_TPTC3, + .flags = ALWAYS_ENABLED, +}; + +static struct clk uart0_clk = { + .name = "uart0", + .parent = &aux_clkin, + .lpsc = DM646X_LPSC_UART0, +}; + +static struct clk uart1_clk = { + .name = "uart1", + .parent = &aux_clkin, + .lpsc = DM646X_LPSC_UART1, +}; + +static struct clk uart2_clk = { + .name = "uart2", + .parent = &aux_clkin, + .lpsc = DM646X_LPSC_UART2, +}; + +static struct clk i2c_clk = { + .name = "I2CCLK", + .parent = &pll1_sysclk3, + .lpsc = DM646X_LPSC_I2C, +}; + +static struct clk gpio_clk = { + .name = "gpio", + .parent = &pll1_sysclk3, + .lpsc = DM646X_LPSC_GPIO, +}; + +static struct clk mcasp0_clk = { + .name = "mcasp0", + .parent = &pll1_sysclk3, + .lpsc = DM646X_LPSC_McASP0, +}; + +static struct clk mcasp1_clk = { + .name = "mcasp1", + .parent = &pll1_sysclk3, + .lpsc = DM646X_LPSC_McASP1, +}; + +static struct clk aemif_clk = { + .name = "aemif", + .parent = &pll1_sysclk3, + .lpsc = DM646X_LPSC_AEMIF, + .flags = ALWAYS_ENABLED, +}; + +static struct clk emac_clk = { + .name = "emac", + .parent = &pll1_sysclk3, + .lpsc = DM646X_LPSC_EMAC, +}; + +static struct clk pwm0_clk = { + .name = "pwm0", + .parent = &pll1_sysclk3, + .lpsc = DM646X_LPSC_PWM0, + .usecount = 1, /* REVIST: disabling hangs system */ +}; + +static struct clk pwm1_clk = { + .name = "pwm1", + .parent = &pll1_sysclk3, + .lpsc = DM646X_LPSC_PWM1, + .usecount = 1, /* REVIST: disabling hangs system */ +}; + +static struct clk timer0_clk = { + .name = "timer0", + .parent = &pll1_sysclk3, + .lpsc = DM646X_LPSC_TIMER0, +}; + +static struct clk timer1_clk = { + .name = "timer1", + .parent = &pll1_sysclk3, + .lpsc = DM646X_LPSC_TIMER1, +}; + +static struct clk timer2_clk = { + .name = "timer2", + .parent = &pll1_sysclk3, + .flags = ALWAYS_ENABLED, /* no LPSC, always enabled; c.f. spruep9a */ +}; + + +static struct clk ide_clk = { + .name = "ide", + .parent = &pll1_sysclk4, + .lpsc = DAVINCI_LPSC_ATA, +}; + +static struct clk vpif0_clk = { + .name = "vpif0", + .parent = &ref_clk, + .lpsc = DM646X_LPSC_VPSSMSTR, + .flags = ALWAYS_ENABLED, +}; + +static struct clk vpif1_clk = { + .name = "vpif1", + .parent = &ref_clk, + .lpsc = DM646X_LPSC_VPSSSLV, + .flags = ALWAYS_ENABLED, +}; + +static struct clk_lookup dm646x_clks[] = { + CLK(NULL, "ref", &ref_clk), + CLK(NULL, "aux", &aux_clkin), + CLK(NULL, "pll1", &pll1_clk), + CLK(NULL, "pll1_sysclk", &pll1_sysclk1), + CLK(NULL, "pll1_sysclk", &pll1_sysclk2), + CLK(NULL, "pll1_sysclk", &pll1_sysclk3), + CLK(NULL, "pll1_sysclk", &pll1_sysclk4), + CLK(NULL, "pll1_sysclk", &pll1_sysclk5), + CLK(NULL, "pll1_sysclk", &pll1_sysclk6), + CLK(NULL, "pll1_sysclk", &pll1_sysclk8), + CLK(NULL, "pll1_sysclk", &pll1_sysclk9), + CLK(NULL, "pll1_sysclk", &pll1_sysclkbp), + CLK(NULL, "pll1_aux", &pll1_aux_clk), + CLK(NULL, "pll2", &pll2_clk), + CLK(NULL, "pll2_sysclk1", &pll2_sysclk1), + CLK(NULL, "dsp", &dsp_clk), + CLK(NULL, "arm", &arm_clk), + CLK(NULL, "edma_cc", &edma_cc_clk), + CLK(NULL, "edma_tc0", &edma_tc0_clk), + CLK(NULL, "edma_tc1", &edma_tc1_clk), + CLK(NULL, "edma_tc2", &edma_tc2_clk), + CLK(NULL, "edma_tc3", &edma_tc3_clk), + CLK(NULL, "uart0", &uart0_clk), + CLK(NULL, "uart1", &uart1_clk), + CLK(NULL, "uart2", &uart2_clk), + CLK("i2c_davinci.1", NULL, &i2c_clk), + CLK(NULL, "gpio", &gpio_clk), + CLK("davinci-mcasp.0", NULL, &mcasp0_clk), + CLK("davinci-mcasp.1", NULL, &mcasp1_clk), + CLK(NULL, "aemif", &aemif_clk), + CLK("davinci_emac.1", NULL, &emac_clk), + CLK(NULL, "pwm0", &pwm0_clk), + CLK(NULL, "pwm1", &pwm1_clk), + CLK(NULL, "timer0", &timer0_clk), + CLK(NULL, "timer1", &timer1_clk), + CLK("watchdog", NULL, &timer2_clk), + CLK("palm_bk3710", NULL, &ide_clk), + CLK(NULL, "vpif0", &vpif0_clk), + CLK(NULL, "vpif1", &vpif1_clk), + CLK(NULL, NULL, NULL), +}; + +static struct emac_platform_data dm646x_emac_pdata = { + .ctrl_reg_offset = DM646X_EMAC_CNTRL_OFFSET, + .ctrl_mod_reg_offset = DM646X_EMAC_CNTRL_MOD_OFFSET, + .ctrl_ram_offset = DM646X_EMAC_CNTRL_RAM_OFFSET, + .ctrl_ram_size = DM646X_EMAC_CNTRL_RAM_SIZE, + .version = EMAC_VERSION_2, +}; + +static struct resource dm646x_emac_resources[] = { + { + .start = DM646X_EMAC_BASE, + .end = DM646X_EMAC_BASE + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_DM646X_EMACRXTHINT, + .end = IRQ_DM646X_EMACRXTHINT, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_DM646X_EMACRXINT, + .end = IRQ_DM646X_EMACRXINT, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_DM646X_EMACTXINT, + .end = IRQ_DM646X_EMACTXINT, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_DM646X_EMACMISCINT, + .end = IRQ_DM646X_EMACMISCINT, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device dm646x_emac_device = { + .name = "davinci_emac", + .id = 1, + .dev = { + .platform_data = &dm646x_emac_pdata, + }, + .num_resources = ARRAY_SIZE(dm646x_emac_resources), + .resource = dm646x_emac_resources, +}; + +static struct resource dm646x_mdio_resources[] = { + { + .start = DM646X_EMAC_MDIO_BASE, + .end = DM646X_EMAC_MDIO_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device dm646x_mdio_device = { + .name = "davinci_mdio", + .id = 0, + .num_resources = ARRAY_SIZE(dm646x_mdio_resources), + .resource = dm646x_mdio_resources, +}; + +/* + * Device specific mux setup + * + * soc description mux mode mode mux dbg + * reg offset mask mode + */ +static const struct mux_config dm646x_pins[] = { +#ifdef CONFIG_DAVINCI_MUX +MUX_CFG(DM646X, ATAEN, 0, 0, 5, 1, true) + +MUX_CFG(DM646X, AUDCK1, 0, 29, 1, 0, false) + +MUX_CFG(DM646X, AUDCK0, 0, 28, 1, 0, false) + +MUX_CFG(DM646X, CRGMUX, 0, 24, 7, 5, true) + +MUX_CFG(DM646X, STSOMUX_DISABLE, 0, 22, 3, 0, true) + +MUX_CFG(DM646X, STSIMUX_DISABLE, 0, 20, 3, 0, true) + +MUX_CFG(DM646X, PTSOMUX_DISABLE, 0, 18, 3, 0, true) + +MUX_CFG(DM646X, PTSIMUX_DISABLE, 0, 16, 3, 0, true) + +MUX_CFG(DM646X, STSOMUX, 0, 22, 3, 2, true) + +MUX_CFG(DM646X, STSIMUX, 0, 20, 3, 2, true) + +MUX_CFG(DM646X, PTSOMUX_PARALLEL, 0, 18, 3, 2, true) + +MUX_CFG(DM646X, PTSIMUX_PARALLEL, 0, 16, 3, 2, true) + +MUX_CFG(DM646X, PTSOMUX_SERIAL, 0, 18, 3, 3, true) + +MUX_CFG(DM646X, PTSIMUX_SERIAL, 0, 16, 3, 3, true) +#endif +}; + +static u8 dm646x_default_priorities[DAVINCI_N_AINTC_IRQ] = { + [IRQ_DM646X_VP_VERTINT0] = 7, + [IRQ_DM646X_VP_VERTINT1] = 7, + [IRQ_DM646X_VP_VERTINT2] = 7, + [IRQ_DM646X_VP_VERTINT3] = 7, + [IRQ_DM646X_VP_ERRINT] = 7, + [IRQ_DM646X_RESERVED_1] = 7, + [IRQ_DM646X_RESERVED_2] = 7, + [IRQ_DM646X_WDINT] = 7, + [IRQ_DM646X_CRGENINT0] = 7, + [IRQ_DM646X_CRGENINT1] = 7, + [IRQ_DM646X_TSIFINT0] = 7, + [IRQ_DM646X_TSIFINT1] = 7, + [IRQ_DM646X_VDCEINT] = 7, + [IRQ_DM646X_USBINT] = 7, + [IRQ_DM646X_USBDMAINT] = 7, + [IRQ_DM646X_PCIINT] = 7, + [IRQ_CCINT0] = 7, /* dma */ + [IRQ_CCERRINT] = 7, /* dma */ + [IRQ_TCERRINT0] = 7, /* dma */ + [IRQ_TCERRINT] = 7, /* dma */ + [IRQ_DM646X_TCERRINT2] = 7, + [IRQ_DM646X_TCERRINT3] = 7, + [IRQ_DM646X_IDE] = 7, + [IRQ_DM646X_HPIINT] = 7, + [IRQ_DM646X_EMACRXTHINT] = 7, + [IRQ_DM646X_EMACRXINT] = 7, + [IRQ_DM646X_EMACTXINT] = 7, + [IRQ_DM646X_EMACMISCINT] = 7, + [IRQ_DM646X_MCASP0TXINT] = 7, + [IRQ_DM646X_MCASP0RXINT] = 7, + [IRQ_AEMIFINT] = 7, + [IRQ_DM646X_RESERVED_3] = 7, + [IRQ_DM646X_MCASP1TXINT] = 7, /* clockevent */ + [IRQ_TINT0_TINT34] = 7, /* clocksource */ + [IRQ_TINT1_TINT12] = 7, /* DSP timer */ + [IRQ_TINT1_TINT34] = 7, /* system tick */ + [IRQ_PWMINT0] = 7, + [IRQ_PWMINT1] = 7, + [IRQ_DM646X_VLQINT] = 7, + [IRQ_I2C] = 7, + [IRQ_UARTINT0] = 7, + [IRQ_UARTINT1] = 7, + [IRQ_DM646X_UARTINT2] = 7, + [IRQ_DM646X_SPINT0] = 7, + [IRQ_DM646X_SPINT1] = 7, + [IRQ_DM646X_DSP2ARMINT] = 7, + [IRQ_DM646X_RESERVED_4] = 7, + [IRQ_DM646X_PSCINT] = 7, + [IRQ_DM646X_GPIO0] = 7, + [IRQ_DM646X_GPIO1] = 7, + [IRQ_DM646X_GPIO2] = 7, + [IRQ_DM646X_GPIO3] = 7, + [IRQ_DM646X_GPIO4] = 7, + [IRQ_DM646X_GPIO5] = 7, + [IRQ_DM646X_GPIO6] = 7, + [IRQ_DM646X_GPIO7] = 7, + [IRQ_DM646X_GPIOBNK0] = 7, + [IRQ_DM646X_GPIOBNK1] = 7, + [IRQ_DM646X_GPIOBNK2] = 7, + [IRQ_DM646X_DDRINT] = 7, + [IRQ_DM646X_AEMIFINT] = 7, + [IRQ_COMMTX] = 7, + [IRQ_COMMRX] = 7, + [IRQ_EMUINT] = 7, +}; + +/*----------------------------------------------------------------------*/ + +/* Four Transfer Controllers on DM646x */ +static const s8 +dm646x_queue_tc_mapping[][2] = { + /* {event queue no, TC no} */ + {0, 0}, + {1, 1}, + {2, 2}, + {3, 3}, + {-1, -1}, +}; + +static const s8 +dm646x_queue_priority_mapping[][2] = { + /* {event queue no, Priority} */ + {0, 4}, + {1, 0}, + {2, 5}, + {3, 1}, + {-1, -1}, +}; + +static struct edma_soc_info edma_cc0_info = { + .n_channel = 64, + .n_region = 6, /* 0-1, 4-7 */ + .n_slot = 512, + .n_tc = 4, + .n_cc = 1, + .queue_tc_mapping = dm646x_queue_tc_mapping, + .queue_priority_mapping = dm646x_queue_priority_mapping, + .default_queue = EVENTQ_1, +}; + +static struct edma_soc_info *dm646x_edma_info[EDMA_MAX_CC] = { + &edma_cc0_info, +}; + +static struct resource edma_resources[] = { + { + .name = "edma_cc0", + .start = 0x01c00000, + .end = 0x01c00000 + SZ_64K - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "edma_tc0", + .start = 0x01c10000, + .end = 0x01c10000 + SZ_1K - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "edma_tc1", + .start = 0x01c10400, + .end = 0x01c10400 + SZ_1K - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "edma_tc2", + .start = 0x01c10800, + .end = 0x01c10800 + SZ_1K - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "edma_tc3", + .start = 0x01c10c00, + .end = 0x01c10c00 + SZ_1K - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "edma0", + .start = IRQ_CCINT0, + .flags = IORESOURCE_IRQ, + }, + { + .name = "edma0_err", + .start = IRQ_CCERRINT, + .flags = IORESOURCE_IRQ, + }, + /* not using TC*_ERR */ +}; + +static struct platform_device dm646x_edma_device = { + .name = "edma", + .id = 0, + .dev.platform_data = dm646x_edma_info, + .num_resources = ARRAY_SIZE(edma_resources), + .resource = edma_resources, +}; + +static struct resource dm646x_mcasp0_resources[] = { + { + .name = "mcasp0", + .start = DAVINCI_DM646X_MCASP0_REG_BASE, + .end = DAVINCI_DM646X_MCASP0_REG_BASE + (SZ_1K << 1) - 1, + .flags = IORESOURCE_MEM, + }, + /* first TX, then RX */ + { + .start = DAVINCI_DM646X_DMA_MCASP0_AXEVT0, + .end = DAVINCI_DM646X_DMA_MCASP0_AXEVT0, + .flags = IORESOURCE_DMA, + }, + { + .start = DAVINCI_DM646X_DMA_MCASP0_AREVT0, + .end = DAVINCI_DM646X_DMA_MCASP0_AREVT0, + .flags = IORESOURCE_DMA, + }, +}; + +static struct resource dm646x_mcasp1_resources[] = { + { + .name = "mcasp1", + .start = DAVINCI_DM646X_MCASP1_REG_BASE, + .end = DAVINCI_DM646X_MCASP1_REG_BASE + (SZ_1K << 1) - 1, + .flags = IORESOURCE_MEM, + }, + /* DIT mode, only TX event */ + { + .start = DAVINCI_DM646X_DMA_MCASP1_AXEVT1, + .end = DAVINCI_DM646X_DMA_MCASP1_AXEVT1, + .flags = IORESOURCE_DMA, + }, + /* DIT mode, dummy entry */ + { + .start = -1, + .end = -1, + .flags = IORESOURCE_DMA, + }, +}; + +static struct platform_device dm646x_mcasp0_device = { + .name = "davinci-mcasp", + .id = 0, + .num_resources = ARRAY_SIZE(dm646x_mcasp0_resources), + .resource = dm646x_mcasp0_resources, +}; + +static struct platform_device dm646x_mcasp1_device = { + .name = "davinci-mcasp", + .id = 1, + .num_resources = ARRAY_SIZE(dm646x_mcasp1_resources), + .resource = dm646x_mcasp1_resources, +}; + +static struct platform_device dm646x_dit_device = { + .name = "spdif-dit", + .id = -1, +}; + +static u64 vpif_dma_mask = DMA_BIT_MASK(32); + +static struct resource vpif_resource[] = { + { + .start = DAVINCI_VPIF_BASE, + .end = DAVINCI_VPIF_BASE + 0x03ff, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device vpif_dev = { + .name = "vpif", + .id = -1, + .dev = { + .dma_mask = &vpif_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = vpif_resource, + .num_resources = ARRAY_SIZE(vpif_resource), +}; + +static struct resource vpif_display_resource[] = { + { + .start = IRQ_DM646X_VP_VERTINT2, + .end = IRQ_DM646X_VP_VERTINT2, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_DM646X_VP_VERTINT3, + .end = IRQ_DM646X_VP_VERTINT3, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device vpif_display_dev = { + .name = "vpif_display", + .id = -1, + .dev = { + .dma_mask = &vpif_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = vpif_display_resource, + .num_resources = ARRAY_SIZE(vpif_display_resource), +}; + +static struct resource vpif_capture_resource[] = { + { + .start = IRQ_DM646X_VP_VERTINT0, + .end = IRQ_DM646X_VP_VERTINT0, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_DM646X_VP_VERTINT1, + .end = IRQ_DM646X_VP_VERTINT1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device vpif_capture_dev = { + .name = "vpif_capture", + .id = -1, + .dev = { + .dma_mask = &vpif_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = vpif_capture_resource, + .num_resources = ARRAY_SIZE(vpif_capture_resource), +}; + +/*----------------------------------------------------------------------*/ + +static struct map_desc dm646x_io_desc[] = { + { + .virtual = IO_VIRT, + .pfn = __phys_to_pfn(IO_PHYS), + .length = IO_SIZE, + .type = MT_DEVICE + }, + { + .virtual = SRAM_VIRT, + .pfn = __phys_to_pfn(0x00010000), + .length = SZ_32K, + .type = MT_MEMORY_NONCACHED, + }, +}; + +/* Contents of JTAG ID register used to identify exact cpu type */ +static struct davinci_id dm646x_ids[] = { + { + .variant = 0x0, + .part_no = 0xb770, + .manufacturer = 0x017, + .cpu_id = DAVINCI_CPU_ID_DM6467, + .name = "dm6467_rev1.x", + }, + { + .variant = 0x1, + .part_no = 0xb770, + .manufacturer = 0x017, + .cpu_id = DAVINCI_CPU_ID_DM6467, + .name = "dm6467_rev3.x", + }, +}; + +static u32 dm646x_psc_bases[] = { DAVINCI_PWR_SLEEP_CNTRL_BASE }; + +/* + * T0_BOT: Timer 0, bottom: clockevent source for hrtimers + * T0_TOP: Timer 0, top : clocksource for generic timekeeping + * T1_BOT: Timer 1, bottom: (used by DSP in TI DSPLink code) + * T1_TOP: Timer 1, top : <unused> + */ +static struct davinci_timer_info dm646x_timer_info = { + .timers = davinci_timer_instance, + .clockevent_id = T0_BOT, + .clocksource_id = T0_TOP, +}; + +static struct plat_serial8250_port dm646x_serial_platform_data[] = { + { + .mapbase = DAVINCI_UART0_BASE, + .irq = IRQ_UARTINT0, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | + UPF_IOREMAP, + .iotype = UPIO_MEM32, + .regshift = 2, + }, + { + .mapbase = DAVINCI_UART1_BASE, + .irq = IRQ_UARTINT1, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | + UPF_IOREMAP, + .iotype = UPIO_MEM32, + .regshift = 2, + }, + { + .mapbase = DAVINCI_UART2_BASE, + .irq = IRQ_DM646X_UARTINT2, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | + UPF_IOREMAP, + .iotype = UPIO_MEM32, + .regshift = 2, + }, + { + .flags = 0 + }, +}; + +static struct platform_device dm646x_serial_device = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM, + .dev = { + .platform_data = dm646x_serial_platform_data, + }, +}; + +static struct davinci_soc_info davinci_soc_info_dm646x = { + .io_desc = dm646x_io_desc, + .io_desc_num = ARRAY_SIZE(dm646x_io_desc), + .jtag_id_reg = 0x01c40028, + .ids = dm646x_ids, + .ids_num = ARRAY_SIZE(dm646x_ids), + .cpu_clks = dm646x_clks, + .psc_bases = dm646x_psc_bases, + .psc_bases_num = ARRAY_SIZE(dm646x_psc_bases), + .pinmux_base = DAVINCI_SYSTEM_MODULE_BASE, + .pinmux_pins = dm646x_pins, + .pinmux_pins_num = ARRAY_SIZE(dm646x_pins), + .intc_base = DAVINCI_ARM_INTC_BASE, + .intc_type = DAVINCI_INTC_TYPE_AINTC, + .intc_irq_prios = dm646x_default_priorities, + .intc_irq_num = DAVINCI_N_AINTC_IRQ, + .timer_info = &dm646x_timer_info, + .gpio_type = GPIO_TYPE_DAVINCI, + .gpio_base = DAVINCI_GPIO_BASE, + .gpio_num = 43, /* Only 33 usable */ + .gpio_irq = IRQ_DM646X_GPIOBNK0, + .serial_dev = &dm646x_serial_device, + .emac_pdata = &dm646x_emac_pdata, + .sram_dma = 0x10010000, + .sram_len = SZ_32K, +}; + +void __init dm646x_init_mcasp0(struct snd_platform_data *pdata) +{ + dm646x_mcasp0_device.dev.platform_data = pdata; + platform_device_register(&dm646x_mcasp0_device); +} + +void __init dm646x_init_mcasp1(struct snd_platform_data *pdata) +{ + dm646x_mcasp1_device.dev.platform_data = pdata; + platform_device_register(&dm646x_mcasp1_device); + platform_device_register(&dm646x_dit_device); +} + +void dm646x_setup_vpif(struct vpif_display_config *display_config, + struct vpif_capture_config *capture_config) +{ + unsigned int value; + + value = __raw_readl(DAVINCI_SYSMOD_VIRT(SYSMOD_VSCLKDIS)); + value &= ~VSCLKDIS_MASK; + __raw_writel(value, DAVINCI_SYSMOD_VIRT(SYSMOD_VSCLKDIS)); + + value = __raw_readl(DAVINCI_SYSMOD_VIRT(SYSMOD_VDD3P3VPWDN)); + value &= ~VDD3P3V_VID_MASK; + __raw_writel(value, DAVINCI_SYSMOD_VIRT(SYSMOD_VDD3P3VPWDN)); + + davinci_cfg_reg(DM646X_STSOMUX_DISABLE); + davinci_cfg_reg(DM646X_STSIMUX_DISABLE); + davinci_cfg_reg(DM646X_PTSOMUX_DISABLE); + davinci_cfg_reg(DM646X_PTSIMUX_DISABLE); + + vpif_display_dev.dev.platform_data = display_config; + vpif_capture_dev.dev.platform_data = capture_config; + platform_device_register(&vpif_dev); + platform_device_register(&vpif_display_dev); + platform_device_register(&vpif_capture_dev); +} + +int __init dm646x_init_edma(struct edma_rsv_info *rsv) +{ + edma_cc0_info.rsv = rsv; + + return platform_device_register(&dm646x_edma_device); +} + +void __init dm646x_init(void) +{ + davinci_common_init(&davinci_soc_info_dm646x); + davinci_map_sysmod(); +} + +static int __init dm646x_init_devices(void) +{ + if (!cpu_is_davinci_dm646x()) + return 0; + + platform_device_register(&dm646x_mdio_device); + platform_device_register(&dm646x_emac_device); + clk_add_alias(NULL, dev_name(&dm646x_mdio_device.dev), + NULL, &dm646x_emac_device.dev); + + return 0; +} +postcore_initcall(dm646x_init_devices); diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/dma.c b/ANDROID_3.4.5/arch/arm/mach-davinci/dma.c new file mode 100644 index 00000000..fd33919c --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/dma.c @@ -0,0 +1,1589 @@ +/* + * EDMA3 support for DaVinci + * + * Copyright (C) 2006-2009 Texas Instruments. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/module.h> +#include <linux/interrupt.h> +#include <linux/platform_device.h> +#include <linux/io.h> +#include <linux/slab.h> + +#include <mach/edma.h> + +/* Offsets matching "struct edmacc_param" */ +#define PARM_OPT 0x00 +#define PARM_SRC 0x04 +#define PARM_A_B_CNT 0x08 +#define PARM_DST 0x0c +#define PARM_SRC_DST_BIDX 0x10 +#define PARM_LINK_BCNTRLD 0x14 +#define PARM_SRC_DST_CIDX 0x18 +#define PARM_CCNT 0x1c + +#define PARM_SIZE 0x20 + +/* Offsets for EDMA CC global channel registers and their shadows */ +#define SH_ER 0x00 /* 64 bits */ +#define SH_ECR 0x08 /* 64 bits */ +#define SH_ESR 0x10 /* 64 bits */ +#define SH_CER 0x18 /* 64 bits */ +#define SH_EER 0x20 /* 64 bits */ +#define SH_EECR 0x28 /* 64 bits */ +#define SH_EESR 0x30 /* 64 bits */ +#define SH_SER 0x38 /* 64 bits */ +#define SH_SECR 0x40 /* 64 bits */ +#define SH_IER 0x50 /* 64 bits */ +#define SH_IECR 0x58 /* 64 bits */ +#define SH_IESR 0x60 /* 64 bits */ +#define SH_IPR 0x68 /* 64 bits */ +#define SH_ICR 0x70 /* 64 bits */ +#define SH_IEVAL 0x78 +#define SH_QER 0x80 +#define SH_QEER 0x84 +#define SH_QEECR 0x88 +#define SH_QEESR 0x8c +#define SH_QSER 0x90 +#define SH_QSECR 0x94 +#define SH_SIZE 0x200 + +/* Offsets for EDMA CC global registers */ +#define EDMA_REV 0x0000 +#define EDMA_CCCFG 0x0004 +#define EDMA_QCHMAP 0x0200 /* 8 registers */ +#define EDMA_DMAQNUM 0x0240 /* 8 registers (4 on OMAP-L1xx) */ +#define EDMA_QDMAQNUM 0x0260 +#define EDMA_QUETCMAP 0x0280 +#define EDMA_QUEPRI 0x0284 +#define EDMA_EMR 0x0300 /* 64 bits */ +#define EDMA_EMCR 0x0308 /* 64 bits */ +#define EDMA_QEMR 0x0310 +#define EDMA_QEMCR 0x0314 +#define EDMA_CCERR 0x0318 +#define EDMA_CCERRCLR 0x031c +#define EDMA_EEVAL 0x0320 +#define EDMA_DRAE 0x0340 /* 4 x 64 bits*/ +#define EDMA_QRAE 0x0380 /* 4 registers */ +#define EDMA_QUEEVTENTRY 0x0400 /* 2 x 16 registers */ +#define EDMA_QSTAT 0x0600 /* 2 registers */ +#define EDMA_QWMTHRA 0x0620 +#define EDMA_QWMTHRB 0x0624 +#define EDMA_CCSTAT 0x0640 + +#define EDMA_M 0x1000 /* global channel registers */ +#define EDMA_ECR 0x1008 +#define EDMA_ECRH 0x100C +#define EDMA_SHADOW0 0x2000 /* 4 regions shadowing global channels */ +#define EDMA_PARM 0x4000 /* 128 param entries */ + +#define PARM_OFFSET(param_no) (EDMA_PARM + ((param_no) << 5)) + +#define EDMA_DCHMAP 0x0100 /* 64 registers */ +#define CHMAP_EXIST BIT(24) + +#define EDMA_MAX_DMACH 64 +#define EDMA_MAX_PARAMENTRY 512 + +/*****************************************************************************/ + +static void __iomem *edmacc_regs_base[EDMA_MAX_CC]; + +static inline unsigned int edma_read(unsigned ctlr, int offset) +{ + return (unsigned int)__raw_readl(edmacc_regs_base[ctlr] + offset); +} + +static inline void edma_write(unsigned ctlr, int offset, int val) +{ + __raw_writel(val, edmacc_regs_base[ctlr] + offset); +} +static inline void edma_modify(unsigned ctlr, int offset, unsigned and, + unsigned or) +{ + unsigned val = edma_read(ctlr, offset); + val &= and; + val |= or; + edma_write(ctlr, offset, val); +} +static inline void edma_and(unsigned ctlr, int offset, unsigned and) +{ + unsigned val = edma_read(ctlr, offset); + val &= and; + edma_write(ctlr, offset, val); +} +static inline void edma_or(unsigned ctlr, int offset, unsigned or) +{ + unsigned val = edma_read(ctlr, offset); + val |= or; + edma_write(ctlr, offset, val); +} +static inline unsigned int edma_read_array(unsigned ctlr, int offset, int i) +{ + return edma_read(ctlr, offset + (i << 2)); +} +static inline void edma_write_array(unsigned ctlr, int offset, int i, + unsigned val) +{ + edma_write(ctlr, offset + (i << 2), val); +} +static inline void edma_modify_array(unsigned ctlr, int offset, int i, + unsigned and, unsigned or) +{ + edma_modify(ctlr, offset + (i << 2), and, or); +} +static inline void edma_or_array(unsigned ctlr, int offset, int i, unsigned or) +{ + edma_or(ctlr, offset + (i << 2), or); +} +static inline void edma_or_array2(unsigned ctlr, int offset, int i, int j, + unsigned or) +{ + edma_or(ctlr, offset + ((i*2 + j) << 2), or); +} +static inline void edma_write_array2(unsigned ctlr, int offset, int i, int j, + unsigned val) +{ + edma_write(ctlr, offset + ((i*2 + j) << 2), val); +} +static inline unsigned int edma_shadow0_read(unsigned ctlr, int offset) +{ + return edma_read(ctlr, EDMA_SHADOW0 + offset); +} +static inline unsigned int edma_shadow0_read_array(unsigned ctlr, int offset, + int i) +{ + return edma_read(ctlr, EDMA_SHADOW0 + offset + (i << 2)); +} +static inline void edma_shadow0_write(unsigned ctlr, int offset, unsigned val) +{ + edma_write(ctlr, EDMA_SHADOW0 + offset, val); +} +static inline void edma_shadow0_write_array(unsigned ctlr, int offset, int i, + unsigned val) +{ + edma_write(ctlr, EDMA_SHADOW0 + offset + (i << 2), val); +} +static inline unsigned int edma_parm_read(unsigned ctlr, int offset, + int param_no) +{ + return edma_read(ctlr, EDMA_PARM + offset + (param_no << 5)); +} +static inline void edma_parm_write(unsigned ctlr, int offset, int param_no, + unsigned val) +{ + edma_write(ctlr, EDMA_PARM + offset + (param_no << 5), val); +} +static inline void edma_parm_modify(unsigned ctlr, int offset, int param_no, + unsigned and, unsigned or) +{ + edma_modify(ctlr, EDMA_PARM + offset + (param_no << 5), and, or); +} +static inline void edma_parm_and(unsigned ctlr, int offset, int param_no, + unsigned and) +{ + edma_and(ctlr, EDMA_PARM + offset + (param_no << 5), and); +} +static inline void edma_parm_or(unsigned ctlr, int offset, int param_no, + unsigned or) +{ + edma_or(ctlr, EDMA_PARM + offset + (param_no << 5), or); +} + +static inline void set_bits(int offset, int len, unsigned long *p) +{ + for (; len > 0; len--) + set_bit(offset + (len - 1), p); +} + +static inline void clear_bits(int offset, int len, unsigned long *p) +{ + for (; len > 0; len--) + clear_bit(offset + (len - 1), p); +} + +/*****************************************************************************/ + +/* actual number of DMA channels and slots on this silicon */ +struct edma { + /* how many dma resources of each type */ + unsigned num_channels; + unsigned num_region; + unsigned num_slots; + unsigned num_tc; + unsigned num_cc; + enum dma_event_q default_queue; + + /* list of channels with no even trigger; terminated by "-1" */ + const s8 *noevent; + + /* The edma_inuse bit for each PaRAM slot is clear unless the + * channel is in use ... by ARM or DSP, for QDMA, or whatever. + */ + DECLARE_BITMAP(edma_inuse, EDMA_MAX_PARAMENTRY); + + /* The edma_unused bit for each channel is clear unless + * it is not being used on this platform. It uses a bit + * of SOC-specific initialization code. + */ + DECLARE_BITMAP(edma_unused, EDMA_MAX_DMACH); + + unsigned irq_res_start; + unsigned irq_res_end; + + struct dma_interrupt_data { + void (*callback)(unsigned channel, unsigned short ch_status, + void *data); + void *data; + } intr_data[EDMA_MAX_DMACH]; +}; + +static struct edma *edma_cc[EDMA_MAX_CC]; +static int arch_num_cc; + +/* dummy param set used to (re)initialize parameter RAM slots */ +static const struct edmacc_param dummy_paramset = { + .link_bcntrld = 0xffff, + .ccnt = 1, +}; + +/*****************************************************************************/ + +static void map_dmach_queue(unsigned ctlr, unsigned ch_no, + enum dma_event_q queue_no) +{ + int bit = (ch_no & 0x7) * 4; + + /* default to low priority queue */ + if (queue_no == EVENTQ_DEFAULT) + queue_no = edma_cc[ctlr]->default_queue; + + queue_no &= 7; + edma_modify_array(ctlr, EDMA_DMAQNUM, (ch_no >> 3), + ~(0x7 << bit), queue_no << bit); +} + +static void __init map_queue_tc(unsigned ctlr, int queue_no, int tc_no) +{ + int bit = queue_no * 4; + edma_modify(ctlr, EDMA_QUETCMAP, ~(0x7 << bit), ((tc_no & 0x7) << bit)); +} + +static void __init assign_priority_to_queue(unsigned ctlr, int queue_no, + int priority) +{ + int bit = queue_no * 4; + edma_modify(ctlr, EDMA_QUEPRI, ~(0x7 << bit), + ((priority & 0x7) << bit)); +} + +/** + * map_dmach_param - Maps channel number to param entry number + * + * This maps the dma channel number to param entry numberter. In + * other words using the DMA channel mapping registers a param entry + * can be mapped to any channel + * + * Callers are responsible for ensuring the channel mapping logic is + * included in that particular EDMA variant (Eg : dm646x) + * + */ +static void __init map_dmach_param(unsigned ctlr) +{ + int i; + for (i = 0; i < EDMA_MAX_DMACH; i++) + edma_write_array(ctlr, EDMA_DCHMAP , i , (i << 5)); +} + +static inline void +setup_dma_interrupt(unsigned lch, + void (*callback)(unsigned channel, u16 ch_status, void *data), + void *data) +{ + unsigned ctlr; + + ctlr = EDMA_CTLR(lch); + lch = EDMA_CHAN_SLOT(lch); + + if (!callback) + edma_shadow0_write_array(ctlr, SH_IECR, lch >> 5, + BIT(lch & 0x1f)); + + edma_cc[ctlr]->intr_data[lch].callback = callback; + edma_cc[ctlr]->intr_data[lch].data = data; + + if (callback) { + edma_shadow0_write_array(ctlr, SH_ICR, lch >> 5, + BIT(lch & 0x1f)); + edma_shadow0_write_array(ctlr, SH_IESR, lch >> 5, + BIT(lch & 0x1f)); + } +} + +static int irq2ctlr(int irq) +{ + if (irq >= edma_cc[0]->irq_res_start && irq <= edma_cc[0]->irq_res_end) + return 0; + else if (irq >= edma_cc[1]->irq_res_start && + irq <= edma_cc[1]->irq_res_end) + return 1; + + return -1; +} + +/****************************************************************************** + * + * DMA interrupt handler + * + *****************************************************************************/ +static irqreturn_t dma_irq_handler(int irq, void *data) +{ + int i; + int ctlr; + unsigned int cnt = 0; + + ctlr = irq2ctlr(irq); + if (ctlr < 0) + return IRQ_NONE; + + dev_dbg(data, "dma_irq_handler\n"); + + if ((edma_shadow0_read_array(ctlr, SH_IPR, 0) == 0) && + (edma_shadow0_read_array(ctlr, SH_IPR, 1) == 0)) + return IRQ_NONE; + + while (1) { + int j; + if (edma_shadow0_read_array(ctlr, SH_IPR, 0) & + edma_shadow0_read_array(ctlr, SH_IER, 0)) + j = 0; + else if (edma_shadow0_read_array(ctlr, SH_IPR, 1) & + edma_shadow0_read_array(ctlr, SH_IER, 1)) + j = 1; + else + break; + dev_dbg(data, "IPR%d %08x\n", j, + edma_shadow0_read_array(ctlr, SH_IPR, j)); + for (i = 0; i < 32; i++) { + int k = (j << 5) + i; + if ((edma_shadow0_read_array(ctlr, SH_IPR, j) & BIT(i)) + && (edma_shadow0_read_array(ctlr, + SH_IER, j) & BIT(i))) { + /* Clear the corresponding IPR bits */ + edma_shadow0_write_array(ctlr, SH_ICR, j, + BIT(i)); + if (edma_cc[ctlr]->intr_data[k].callback) + edma_cc[ctlr]->intr_data[k].callback( + k, DMA_COMPLETE, + edma_cc[ctlr]->intr_data[k]. + data); + } + } + cnt++; + if (cnt > 10) + break; + } + edma_shadow0_write(ctlr, SH_IEVAL, 1); + return IRQ_HANDLED; +} + +/****************************************************************************** + * + * DMA error interrupt handler + * + *****************************************************************************/ +static irqreturn_t dma_ccerr_handler(int irq, void *data) +{ + int i; + int ctlr; + unsigned int cnt = 0; + + ctlr = irq2ctlr(irq); + if (ctlr < 0) + return IRQ_NONE; + + dev_dbg(data, "dma_ccerr_handler\n"); + + if ((edma_read_array(ctlr, EDMA_EMR, 0) == 0) && + (edma_read_array(ctlr, EDMA_EMR, 1) == 0) && + (edma_read(ctlr, EDMA_QEMR) == 0) && + (edma_read(ctlr, EDMA_CCERR) == 0)) + return IRQ_NONE; + + while (1) { + int j = -1; + if (edma_read_array(ctlr, EDMA_EMR, 0)) + j = 0; + else if (edma_read_array(ctlr, EDMA_EMR, 1)) + j = 1; + if (j >= 0) { + dev_dbg(data, "EMR%d %08x\n", j, + edma_read_array(ctlr, EDMA_EMR, j)); + for (i = 0; i < 32; i++) { + int k = (j << 5) + i; + if (edma_read_array(ctlr, EDMA_EMR, j) & + BIT(i)) { + /* Clear the corresponding EMR bits */ + edma_write_array(ctlr, EDMA_EMCR, j, + BIT(i)); + /* Clear any SER */ + edma_shadow0_write_array(ctlr, SH_SECR, + j, BIT(i)); + if (edma_cc[ctlr]->intr_data[k]. + callback) { + edma_cc[ctlr]->intr_data[k]. + callback(k, + DMA_CC_ERROR, + edma_cc[ctlr]->intr_data + [k].data); + } + } + } + } else if (edma_read(ctlr, EDMA_QEMR)) { + dev_dbg(data, "QEMR %02x\n", + edma_read(ctlr, EDMA_QEMR)); + for (i = 0; i < 8; i++) { + if (edma_read(ctlr, EDMA_QEMR) & BIT(i)) { + /* Clear the corresponding IPR bits */ + edma_write(ctlr, EDMA_QEMCR, BIT(i)); + edma_shadow0_write(ctlr, SH_QSECR, + BIT(i)); + + /* NOTE: not reported!! */ + } + } + } else if (edma_read(ctlr, EDMA_CCERR)) { + dev_dbg(data, "CCERR %08x\n", + edma_read(ctlr, EDMA_CCERR)); + /* FIXME: CCERR.BIT(16) ignored! much better + * to just write CCERRCLR with CCERR value... + */ + for (i = 0; i < 8; i++) { + if (edma_read(ctlr, EDMA_CCERR) & BIT(i)) { + /* Clear the corresponding IPR bits */ + edma_write(ctlr, EDMA_CCERRCLR, BIT(i)); + + /* NOTE: not reported!! */ + } + } + } + if ((edma_read_array(ctlr, EDMA_EMR, 0) == 0) && + (edma_read_array(ctlr, EDMA_EMR, 1) == 0) && + (edma_read(ctlr, EDMA_QEMR) == 0) && + (edma_read(ctlr, EDMA_CCERR) == 0)) + break; + cnt++; + if (cnt > 10) + break; + } + edma_write(ctlr, EDMA_EEVAL, 1); + return IRQ_HANDLED; +} + +/****************************************************************************** + * + * Transfer controller error interrupt handlers + * + *****************************************************************************/ + +#define tc_errs_handled false /* disabled as long as they're NOPs */ + +static irqreturn_t dma_tc0err_handler(int irq, void *data) +{ + dev_dbg(data, "dma_tc0err_handler\n"); + return IRQ_HANDLED; +} + +static irqreturn_t dma_tc1err_handler(int irq, void *data) +{ + dev_dbg(data, "dma_tc1err_handler\n"); + return IRQ_HANDLED; +} + +static int reserve_contiguous_slots(int ctlr, unsigned int id, + unsigned int num_slots, + unsigned int start_slot) +{ + int i, j; + unsigned int count = num_slots; + int stop_slot = start_slot; + DECLARE_BITMAP(tmp_inuse, EDMA_MAX_PARAMENTRY); + + for (i = start_slot; i < edma_cc[ctlr]->num_slots; ++i) { + j = EDMA_CHAN_SLOT(i); + if (!test_and_set_bit(j, edma_cc[ctlr]->edma_inuse)) { + /* Record our current beginning slot */ + if (count == num_slots) + stop_slot = i; + + count--; + set_bit(j, tmp_inuse); + + if (count == 0) + break; + } else { + clear_bit(j, tmp_inuse); + + if (id == EDMA_CONT_PARAMS_FIXED_EXACT) { + stop_slot = i; + break; + } else { + count = num_slots; + } + } + } + + /* + * We have to clear any bits that we set + * if we run out parameter RAM slots, i.e we do find a set + * of contiguous parameter RAM slots but do not find the exact number + * requested as we may reach the total number of parameter RAM slots + */ + if (i == edma_cc[ctlr]->num_slots) + stop_slot = i; + + for (j = start_slot; j < stop_slot; j++) + if (test_bit(j, tmp_inuse)) + clear_bit(j, edma_cc[ctlr]->edma_inuse); + + if (count) + return -EBUSY; + + for (j = i - num_slots + 1; j <= i; ++j) + memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(j), + &dummy_paramset, PARM_SIZE); + + return EDMA_CTLR_CHAN(ctlr, i - num_slots + 1); +} + +static int prepare_unused_channel_list(struct device *dev, void *data) +{ + struct platform_device *pdev = to_platform_device(dev); + int i, ctlr; + + for (i = 0; i < pdev->num_resources; i++) { + if ((pdev->resource[i].flags & IORESOURCE_DMA) && + (int)pdev->resource[i].start >= 0) { + ctlr = EDMA_CTLR(pdev->resource[i].start); + clear_bit(EDMA_CHAN_SLOT(pdev->resource[i].start), + edma_cc[ctlr]->edma_unused); + } + } + + return 0; +} + +/*-----------------------------------------------------------------------*/ + +static bool unused_chan_list_done; + +/* Resource alloc/free: dma channels, parameter RAM slots */ + +/** + * edma_alloc_channel - allocate DMA channel and paired parameter RAM + * @channel: specific channel to allocate; negative for "any unmapped channel" + * @callback: optional; to be issued on DMA completion or errors + * @data: passed to callback + * @eventq_no: an EVENTQ_* constant, used to choose which Transfer + * Controller (TC) executes requests using this channel. Use + * EVENTQ_DEFAULT unless you really need a high priority queue. + * + * This allocates a DMA channel and its associated parameter RAM slot. + * The parameter RAM is initialized to hold a dummy transfer. + * + * Normal use is to pass a specific channel number as @channel, to make + * use of hardware events mapped to that channel. When the channel will + * be used only for software triggering or event chaining, channels not + * mapped to hardware events (or mapped to unused events) are preferable. + * + * DMA transfers start from a channel using edma_start(), or by + * chaining. When the transfer described in that channel's parameter RAM + * slot completes, that slot's data may be reloaded through a link. + * + * DMA errors are only reported to the @callback associated with the + * channel driving that transfer, but transfer completion callbacks can + * be sent to another channel under control of the TCC field in + * the option word of the transfer's parameter RAM set. Drivers must not + * use DMA transfer completion callbacks for channels they did not allocate. + * (The same applies to TCC codes used in transfer chaining.) + * + * Returns the number of the channel, else negative errno. + */ +int edma_alloc_channel(int channel, + void (*callback)(unsigned channel, u16 ch_status, void *data), + void *data, + enum dma_event_q eventq_no) +{ + unsigned i, done = 0, ctlr = 0; + int ret = 0; + + if (!unused_chan_list_done) { + /* + * Scan all the platform devices to find out the EDMA channels + * used and clear them in the unused list, making the rest + * available for ARM usage. + */ + ret = bus_for_each_dev(&platform_bus_type, NULL, NULL, + prepare_unused_channel_list); + if (ret < 0) + return ret; + + unused_chan_list_done = true; + } + + if (channel >= 0) { + ctlr = EDMA_CTLR(channel); + channel = EDMA_CHAN_SLOT(channel); + } + + if (channel < 0) { + for (i = 0; i < arch_num_cc; i++) { + channel = 0; + for (;;) { + channel = find_next_bit(edma_cc[i]->edma_unused, + edma_cc[i]->num_channels, + channel); + if (channel == edma_cc[i]->num_channels) + break; + if (!test_and_set_bit(channel, + edma_cc[i]->edma_inuse)) { + done = 1; + ctlr = i; + break; + } + channel++; + } + if (done) + break; + } + if (!done) + return -ENOMEM; + } else if (channel >= edma_cc[ctlr]->num_channels) { + return -EINVAL; + } else if (test_and_set_bit(channel, edma_cc[ctlr]->edma_inuse)) { + return -EBUSY; + } + + /* ensure access through shadow region 0 */ + edma_or_array2(ctlr, EDMA_DRAE, 0, channel >> 5, BIT(channel & 0x1f)); + + /* ensure no events are pending */ + edma_stop(EDMA_CTLR_CHAN(ctlr, channel)); + memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(channel), + &dummy_paramset, PARM_SIZE); + + if (callback) + setup_dma_interrupt(EDMA_CTLR_CHAN(ctlr, channel), + callback, data); + + map_dmach_queue(ctlr, channel, eventq_no); + + return EDMA_CTLR_CHAN(ctlr, channel); +} +EXPORT_SYMBOL(edma_alloc_channel); + + +/** + * edma_free_channel - deallocate DMA channel + * @channel: dma channel returned from edma_alloc_channel() + * + * This deallocates the DMA channel and associated parameter RAM slot + * allocated by edma_alloc_channel(). + * + * Callers are responsible for ensuring the channel is inactive, and + * will not be reactivated by linking, chaining, or software calls to + * edma_start(). + */ +void edma_free_channel(unsigned channel) +{ + unsigned ctlr; + + ctlr = EDMA_CTLR(channel); + channel = EDMA_CHAN_SLOT(channel); + + if (channel >= edma_cc[ctlr]->num_channels) + return; + + setup_dma_interrupt(channel, NULL, NULL); + /* REVISIT should probably take out of shadow region 0 */ + + memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(channel), + &dummy_paramset, PARM_SIZE); + clear_bit(channel, edma_cc[ctlr]->edma_inuse); +} +EXPORT_SYMBOL(edma_free_channel); + +/** + * edma_alloc_slot - allocate DMA parameter RAM + * @slot: specific slot to allocate; negative for "any unused slot" + * + * This allocates a parameter RAM slot, initializing it to hold a + * dummy transfer. Slots allocated using this routine have not been + * mapped to a hardware DMA channel, and will normally be used by + * linking to them from a slot associated with a DMA channel. + * + * Normal use is to pass EDMA_SLOT_ANY as the @slot, but specific + * slots may be allocated on behalf of DSP firmware. + * + * Returns the number of the slot, else negative errno. + */ +int edma_alloc_slot(unsigned ctlr, int slot) +{ + if (slot >= 0) + slot = EDMA_CHAN_SLOT(slot); + + if (slot < 0) { + slot = edma_cc[ctlr]->num_channels; + for (;;) { + slot = find_next_zero_bit(edma_cc[ctlr]->edma_inuse, + edma_cc[ctlr]->num_slots, slot); + if (slot == edma_cc[ctlr]->num_slots) + return -ENOMEM; + if (!test_and_set_bit(slot, edma_cc[ctlr]->edma_inuse)) + break; + } + } else if (slot < edma_cc[ctlr]->num_channels || + slot >= edma_cc[ctlr]->num_slots) { + return -EINVAL; + } else if (test_and_set_bit(slot, edma_cc[ctlr]->edma_inuse)) { + return -EBUSY; + } + + memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot), + &dummy_paramset, PARM_SIZE); + + return EDMA_CTLR_CHAN(ctlr, slot); +} +EXPORT_SYMBOL(edma_alloc_slot); + +/** + * edma_free_slot - deallocate DMA parameter RAM + * @slot: parameter RAM slot returned from edma_alloc_slot() + * + * This deallocates the parameter RAM slot allocated by edma_alloc_slot(). + * Callers are responsible for ensuring the slot is inactive, and will + * not be activated. + */ +void edma_free_slot(unsigned slot) +{ + unsigned ctlr; + + ctlr = EDMA_CTLR(slot); + slot = EDMA_CHAN_SLOT(slot); + + if (slot < edma_cc[ctlr]->num_channels || + slot >= edma_cc[ctlr]->num_slots) + return; + + memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot), + &dummy_paramset, PARM_SIZE); + clear_bit(slot, edma_cc[ctlr]->edma_inuse); +} +EXPORT_SYMBOL(edma_free_slot); + + +/** + * edma_alloc_cont_slots- alloc contiguous parameter RAM slots + * The API will return the starting point of a set of + * contiguous parameter RAM slots that have been requested + * + * @id: can only be EDMA_CONT_PARAMS_ANY or EDMA_CONT_PARAMS_FIXED_EXACT + * or EDMA_CONT_PARAMS_FIXED_NOT_EXACT + * @count: number of contiguous Paramter RAM slots + * @slot - the start value of Parameter RAM slot that should be passed if id + * is EDMA_CONT_PARAMS_FIXED_EXACT or EDMA_CONT_PARAMS_FIXED_NOT_EXACT + * + * If id is EDMA_CONT_PARAMS_ANY then the API starts looking for a set of + * contiguous Parameter RAM slots from parameter RAM 64 in the case of + * DaVinci SOCs and 32 in the case of DA8xx SOCs. + * + * If id is EDMA_CONT_PARAMS_FIXED_EXACT then the API starts looking for a + * set of contiguous parameter RAM slots from the "slot" that is passed as an + * argument to the API. + * + * If id is EDMA_CONT_PARAMS_FIXED_NOT_EXACT then the API initially tries + * starts looking for a set of contiguous parameter RAMs from the "slot" + * that is passed as an argument to the API. On failure the API will try to + * find a set of contiguous Parameter RAM slots from the remaining Parameter + * RAM slots + */ +int edma_alloc_cont_slots(unsigned ctlr, unsigned int id, int slot, int count) +{ + /* + * The start slot requested should be greater than + * the number of channels and lesser than the total number + * of slots + */ + if ((id != EDMA_CONT_PARAMS_ANY) && + (slot < edma_cc[ctlr]->num_channels || + slot >= edma_cc[ctlr]->num_slots)) + return -EINVAL; + + /* + * The number of parameter RAM slots requested cannot be less than 1 + * and cannot be more than the number of slots minus the number of + * channels + */ + if (count < 1 || count > + (edma_cc[ctlr]->num_slots - edma_cc[ctlr]->num_channels)) + return -EINVAL; + + switch (id) { + case EDMA_CONT_PARAMS_ANY: + return reserve_contiguous_slots(ctlr, id, count, + edma_cc[ctlr]->num_channels); + case EDMA_CONT_PARAMS_FIXED_EXACT: + case EDMA_CONT_PARAMS_FIXED_NOT_EXACT: + return reserve_contiguous_slots(ctlr, id, count, slot); + default: + return -EINVAL; + } + +} +EXPORT_SYMBOL(edma_alloc_cont_slots); + +/** + * edma_free_cont_slots - deallocate DMA parameter RAM slots + * @slot: first parameter RAM of a set of parameter RAM slots to be freed + * @count: the number of contiguous parameter RAM slots to be freed + * + * This deallocates the parameter RAM slots allocated by + * edma_alloc_cont_slots. + * Callers/applications need to keep track of sets of contiguous + * parameter RAM slots that have been allocated using the edma_alloc_cont_slots + * API. + * Callers are responsible for ensuring the slots are inactive, and will + * not be activated. + */ +int edma_free_cont_slots(unsigned slot, int count) +{ + unsigned ctlr, slot_to_free; + int i; + + ctlr = EDMA_CTLR(slot); + slot = EDMA_CHAN_SLOT(slot); + + if (slot < edma_cc[ctlr]->num_channels || + slot >= edma_cc[ctlr]->num_slots || + count < 1) + return -EINVAL; + + for (i = slot; i < slot + count; ++i) { + ctlr = EDMA_CTLR(i); + slot_to_free = EDMA_CHAN_SLOT(i); + + memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot_to_free), + &dummy_paramset, PARM_SIZE); + clear_bit(slot_to_free, edma_cc[ctlr]->edma_inuse); + } + + return 0; +} +EXPORT_SYMBOL(edma_free_cont_slots); + +/*-----------------------------------------------------------------------*/ + +/* Parameter RAM operations (i) -- read/write partial slots */ + +/** + * edma_set_src - set initial DMA source address in parameter RAM slot + * @slot: parameter RAM slot being configured + * @src_port: physical address of source (memory, controller FIFO, etc) + * @addressMode: INCR, except in very rare cases + * @fifoWidth: ignored unless @addressMode is FIFO, else specifies the + * width to use when addressing the fifo (e.g. W8BIT, W32BIT) + * + * Note that the source address is modified during the DMA transfer + * according to edma_set_src_index(). + */ +void edma_set_src(unsigned slot, dma_addr_t src_port, + enum address_mode mode, enum fifo_width width) +{ + unsigned ctlr; + + ctlr = EDMA_CTLR(slot); + slot = EDMA_CHAN_SLOT(slot); + + if (slot < edma_cc[ctlr]->num_slots) { + unsigned int i = edma_parm_read(ctlr, PARM_OPT, slot); + + if (mode) { + /* set SAM and program FWID */ + i = (i & ~(EDMA_FWID)) | (SAM | ((width & 0x7) << 8)); + } else { + /* clear SAM */ + i &= ~SAM; + } + edma_parm_write(ctlr, PARM_OPT, slot, i); + + /* set the source port address + in source register of param structure */ + edma_parm_write(ctlr, PARM_SRC, slot, src_port); + } +} +EXPORT_SYMBOL(edma_set_src); + +/** + * edma_set_dest - set initial DMA destination address in parameter RAM slot + * @slot: parameter RAM slot being configured + * @dest_port: physical address of destination (memory, controller FIFO, etc) + * @addressMode: INCR, except in very rare cases + * @fifoWidth: ignored unless @addressMode is FIFO, else specifies the + * width to use when addressing the fifo (e.g. W8BIT, W32BIT) + * + * Note that the destination address is modified during the DMA transfer + * according to edma_set_dest_index(). + */ +void edma_set_dest(unsigned slot, dma_addr_t dest_port, + enum address_mode mode, enum fifo_width width) +{ + unsigned ctlr; + + ctlr = EDMA_CTLR(slot); + slot = EDMA_CHAN_SLOT(slot); + + if (slot < edma_cc[ctlr]->num_slots) { + unsigned int i = edma_parm_read(ctlr, PARM_OPT, slot); + + if (mode) { + /* set DAM and program FWID */ + i = (i & ~(EDMA_FWID)) | (DAM | ((width & 0x7) << 8)); + } else { + /* clear DAM */ + i &= ~DAM; + } + edma_parm_write(ctlr, PARM_OPT, slot, i); + /* set the destination port address + in dest register of param structure */ + edma_parm_write(ctlr, PARM_DST, slot, dest_port); + } +} +EXPORT_SYMBOL(edma_set_dest); + +/** + * edma_get_position - returns the current transfer points + * @slot: parameter RAM slot being examined + * @src: pointer to source port position + * @dst: pointer to destination port position + * + * Returns current source and destination addresses for a particular + * parameter RAM slot. Its channel should not be active when this is called. + */ +void edma_get_position(unsigned slot, dma_addr_t *src, dma_addr_t *dst) +{ + struct edmacc_param temp; + unsigned ctlr; + + ctlr = EDMA_CTLR(slot); + slot = EDMA_CHAN_SLOT(slot); + + edma_read_slot(EDMA_CTLR_CHAN(ctlr, slot), &temp); + if (src != NULL) + *src = temp.src; + if (dst != NULL) + *dst = temp.dst; +} +EXPORT_SYMBOL(edma_get_position); + +/** + * edma_set_src_index - configure DMA source address indexing + * @slot: parameter RAM slot being configured + * @src_bidx: byte offset between source arrays in a frame + * @src_cidx: byte offset between source frames in a block + * + * Offsets are specified to support either contiguous or discontiguous + * memory transfers, or repeated access to a hardware register, as needed. + * When accessing hardware registers, both offsets are normally zero. + */ +void edma_set_src_index(unsigned slot, s16 src_bidx, s16 src_cidx) +{ + unsigned ctlr; + + ctlr = EDMA_CTLR(slot); + slot = EDMA_CHAN_SLOT(slot); + + if (slot < edma_cc[ctlr]->num_slots) { + edma_parm_modify(ctlr, PARM_SRC_DST_BIDX, slot, + 0xffff0000, src_bidx); + edma_parm_modify(ctlr, PARM_SRC_DST_CIDX, slot, + 0xffff0000, src_cidx); + } +} +EXPORT_SYMBOL(edma_set_src_index); + +/** + * edma_set_dest_index - configure DMA destination address indexing + * @slot: parameter RAM slot being configured + * @dest_bidx: byte offset between destination arrays in a frame + * @dest_cidx: byte offset between destination frames in a block + * + * Offsets are specified to support either contiguous or discontiguous + * memory transfers, or repeated access to a hardware register, as needed. + * When accessing hardware registers, both offsets are normally zero. + */ +void edma_set_dest_index(unsigned slot, s16 dest_bidx, s16 dest_cidx) +{ + unsigned ctlr; + + ctlr = EDMA_CTLR(slot); + slot = EDMA_CHAN_SLOT(slot); + + if (slot < edma_cc[ctlr]->num_slots) { + edma_parm_modify(ctlr, PARM_SRC_DST_BIDX, slot, + 0x0000ffff, dest_bidx << 16); + edma_parm_modify(ctlr, PARM_SRC_DST_CIDX, slot, + 0x0000ffff, dest_cidx << 16); + } +} +EXPORT_SYMBOL(edma_set_dest_index); + +/** + * edma_set_transfer_params - configure DMA transfer parameters + * @slot: parameter RAM slot being configured + * @acnt: how many bytes per array (at least one) + * @bcnt: how many arrays per frame (at least one) + * @ccnt: how many frames per block (at least one) + * @bcnt_rld: used only for A-Synchronized transfers; this specifies + * the value to reload into bcnt when it decrements to zero + * @sync_mode: ASYNC or ABSYNC + * + * See the EDMA3 documentation to understand how to configure and link + * transfers using the fields in PaRAM slots. If you are not doing it + * all at once with edma_write_slot(), you will use this routine + * plus two calls each for source and destination, setting the initial + * address and saying how to index that address. + * + * An example of an A-Synchronized transfer is a serial link using a + * single word shift register. In that case, @acnt would be equal to + * that word size; the serial controller issues a DMA synchronization + * event to transfer each word, and memory access by the DMA transfer + * controller will be word-at-a-time. + * + * An example of an AB-Synchronized transfer is a device using a FIFO. + * In that case, @acnt equals the FIFO width and @bcnt equals its depth. + * The controller with the FIFO issues DMA synchronization events when + * the FIFO threshold is reached, and the DMA transfer controller will + * transfer one frame to (or from) the FIFO. It will probably use + * efficient burst modes to access memory. + */ +void edma_set_transfer_params(unsigned slot, + u16 acnt, u16 bcnt, u16 ccnt, + u16 bcnt_rld, enum sync_dimension sync_mode) +{ + unsigned ctlr; + + ctlr = EDMA_CTLR(slot); + slot = EDMA_CHAN_SLOT(slot); + + if (slot < edma_cc[ctlr]->num_slots) { + edma_parm_modify(ctlr, PARM_LINK_BCNTRLD, slot, + 0x0000ffff, bcnt_rld << 16); + if (sync_mode == ASYNC) + edma_parm_and(ctlr, PARM_OPT, slot, ~SYNCDIM); + else + edma_parm_or(ctlr, PARM_OPT, slot, SYNCDIM); + /* Set the acount, bcount, ccount registers */ + edma_parm_write(ctlr, PARM_A_B_CNT, slot, (bcnt << 16) | acnt); + edma_parm_write(ctlr, PARM_CCNT, slot, ccnt); + } +} +EXPORT_SYMBOL(edma_set_transfer_params); + +/** + * edma_link - link one parameter RAM slot to another + * @from: parameter RAM slot originating the link + * @to: parameter RAM slot which is the link target + * + * The originating slot should not be part of any active DMA transfer. + */ +void edma_link(unsigned from, unsigned to) +{ + unsigned ctlr_from, ctlr_to; + + ctlr_from = EDMA_CTLR(from); + from = EDMA_CHAN_SLOT(from); + ctlr_to = EDMA_CTLR(to); + to = EDMA_CHAN_SLOT(to); + + if (from >= edma_cc[ctlr_from]->num_slots) + return; + if (to >= edma_cc[ctlr_to]->num_slots) + return; + edma_parm_modify(ctlr_from, PARM_LINK_BCNTRLD, from, 0xffff0000, + PARM_OFFSET(to)); +} +EXPORT_SYMBOL(edma_link); + +/** + * edma_unlink - cut link from one parameter RAM slot + * @from: parameter RAM slot originating the link + * + * The originating slot should not be part of any active DMA transfer. + * Its link is set to 0xffff. + */ +void edma_unlink(unsigned from) +{ + unsigned ctlr; + + ctlr = EDMA_CTLR(from); + from = EDMA_CHAN_SLOT(from); + + if (from >= edma_cc[ctlr]->num_slots) + return; + edma_parm_or(ctlr, PARM_LINK_BCNTRLD, from, 0xffff); +} +EXPORT_SYMBOL(edma_unlink); + +/*-----------------------------------------------------------------------*/ + +/* Parameter RAM operations (ii) -- read/write whole parameter sets */ + +/** + * edma_write_slot - write parameter RAM data for slot + * @slot: number of parameter RAM slot being modified + * @param: data to be written into parameter RAM slot + * + * Use this to assign all parameters of a transfer at once. This + * allows more efficient setup of transfers than issuing multiple + * calls to set up those parameters in small pieces, and provides + * complete control over all transfer options. + */ +void edma_write_slot(unsigned slot, const struct edmacc_param *param) +{ + unsigned ctlr; + + ctlr = EDMA_CTLR(slot); + slot = EDMA_CHAN_SLOT(slot); + + if (slot >= edma_cc[ctlr]->num_slots) + return; + memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot), param, + PARM_SIZE); +} +EXPORT_SYMBOL(edma_write_slot); + +/** + * edma_read_slot - read parameter RAM data from slot + * @slot: number of parameter RAM slot being copied + * @param: where to store copy of parameter RAM data + * + * Use this to read data from a parameter RAM slot, perhaps to + * save them as a template for later reuse. + */ +void edma_read_slot(unsigned slot, struct edmacc_param *param) +{ + unsigned ctlr; + + ctlr = EDMA_CTLR(slot); + slot = EDMA_CHAN_SLOT(slot); + + if (slot >= edma_cc[ctlr]->num_slots) + return; + memcpy_fromio(param, edmacc_regs_base[ctlr] + PARM_OFFSET(slot), + PARM_SIZE); +} +EXPORT_SYMBOL(edma_read_slot); + +/*-----------------------------------------------------------------------*/ + +/* Various EDMA channel control operations */ + +/** + * edma_pause - pause dma on a channel + * @channel: on which edma_start() has been called + * + * This temporarily disables EDMA hardware events on the specified channel, + * preventing them from triggering new transfers on its behalf + */ +void edma_pause(unsigned channel) +{ + unsigned ctlr; + + ctlr = EDMA_CTLR(channel); + channel = EDMA_CHAN_SLOT(channel); + + if (channel < edma_cc[ctlr]->num_channels) { + unsigned int mask = BIT(channel & 0x1f); + + edma_shadow0_write_array(ctlr, SH_EECR, channel >> 5, mask); + } +} +EXPORT_SYMBOL(edma_pause); + +/** + * edma_resume - resumes dma on a paused channel + * @channel: on which edma_pause() has been called + * + * This re-enables EDMA hardware events on the specified channel. + */ +void edma_resume(unsigned channel) +{ + unsigned ctlr; + + ctlr = EDMA_CTLR(channel); + channel = EDMA_CHAN_SLOT(channel); + + if (channel < edma_cc[ctlr]->num_channels) { + unsigned int mask = BIT(channel & 0x1f); + + edma_shadow0_write_array(ctlr, SH_EESR, channel >> 5, mask); + } +} +EXPORT_SYMBOL(edma_resume); + +/** + * edma_start - start dma on a channel + * @channel: channel being activated + * + * Channels with event associations will be triggered by their hardware + * events, and channels without such associations will be triggered by + * software. (At this writing there is no interface for using software + * triggers except with channels that don't support hardware triggers.) + * + * Returns zero on success, else negative errno. + */ +int edma_start(unsigned channel) +{ + unsigned ctlr; + + ctlr = EDMA_CTLR(channel); + channel = EDMA_CHAN_SLOT(channel); + + if (channel < edma_cc[ctlr]->num_channels) { + int j = channel >> 5; + unsigned int mask = BIT(channel & 0x1f); + + /* EDMA channels without event association */ + if (test_bit(channel, edma_cc[ctlr]->edma_unused)) { + pr_debug("EDMA: ESR%d %08x\n", j, + edma_shadow0_read_array(ctlr, SH_ESR, j)); + edma_shadow0_write_array(ctlr, SH_ESR, j, mask); + return 0; + } + + /* EDMA channel with event association */ + pr_debug("EDMA: ER%d %08x\n", j, + edma_shadow0_read_array(ctlr, SH_ER, j)); + /* Clear any pending event or error */ + edma_write_array(ctlr, EDMA_ECR, j, mask); + edma_write_array(ctlr, EDMA_EMCR, j, mask); + /* Clear any SER */ + edma_shadow0_write_array(ctlr, SH_SECR, j, mask); + edma_shadow0_write_array(ctlr, SH_EESR, j, mask); + pr_debug("EDMA: EER%d %08x\n", j, + edma_shadow0_read_array(ctlr, SH_EER, j)); + return 0; + } + + return -EINVAL; +} +EXPORT_SYMBOL(edma_start); + +/** + * edma_stop - stops dma on the channel passed + * @channel: channel being deactivated + * + * When @lch is a channel, any active transfer is paused and + * all pending hardware events are cleared. The current transfer + * may not be resumed, and the channel's Parameter RAM should be + * reinitialized before being reused. + */ +void edma_stop(unsigned channel) +{ + unsigned ctlr; + + ctlr = EDMA_CTLR(channel); + channel = EDMA_CHAN_SLOT(channel); + + if (channel < edma_cc[ctlr]->num_channels) { + int j = channel >> 5; + unsigned int mask = BIT(channel & 0x1f); + + edma_shadow0_write_array(ctlr, SH_EECR, j, mask); + edma_shadow0_write_array(ctlr, SH_ECR, j, mask); + edma_shadow0_write_array(ctlr, SH_SECR, j, mask); + edma_write_array(ctlr, EDMA_EMCR, j, mask); + + pr_debug("EDMA: EER%d %08x\n", j, + edma_shadow0_read_array(ctlr, SH_EER, j)); + + /* REVISIT: consider guarding against inappropriate event + * chaining by overwriting with dummy_paramset. + */ + } +} +EXPORT_SYMBOL(edma_stop); + +/****************************************************************************** + * + * It cleans ParamEntry qand bring back EDMA to initial state if media has + * been removed before EDMA has finished.It is usedful for removable media. + * Arguments: + * ch_no - channel no + * + * Return: zero on success, or corresponding error no on failure + * + * FIXME this should not be needed ... edma_stop() should suffice. + * + *****************************************************************************/ + +void edma_clean_channel(unsigned channel) +{ + unsigned ctlr; + + ctlr = EDMA_CTLR(channel); + channel = EDMA_CHAN_SLOT(channel); + + if (channel < edma_cc[ctlr]->num_channels) { + int j = (channel >> 5); + unsigned int mask = BIT(channel & 0x1f); + + pr_debug("EDMA: EMR%d %08x\n", j, + edma_read_array(ctlr, EDMA_EMR, j)); + edma_shadow0_write_array(ctlr, SH_ECR, j, mask); + /* Clear the corresponding EMR bits */ + edma_write_array(ctlr, EDMA_EMCR, j, mask); + /* Clear any SER */ + edma_shadow0_write_array(ctlr, SH_SECR, j, mask); + edma_write(ctlr, EDMA_CCERRCLR, BIT(16) | BIT(1) | BIT(0)); + } +} +EXPORT_SYMBOL(edma_clean_channel); + +/* + * edma_clear_event - clear an outstanding event on the DMA channel + * Arguments: + * channel - channel number + */ +void edma_clear_event(unsigned channel) +{ + unsigned ctlr; + + ctlr = EDMA_CTLR(channel); + channel = EDMA_CHAN_SLOT(channel); + + if (channel >= edma_cc[ctlr]->num_channels) + return; + if (channel < 32) + edma_write(ctlr, EDMA_ECR, BIT(channel)); + else + edma_write(ctlr, EDMA_ECRH, BIT(channel - 32)); +} +EXPORT_SYMBOL(edma_clear_event); + +/*-----------------------------------------------------------------------*/ + +static int __init edma_probe(struct platform_device *pdev) +{ + struct edma_soc_info **info = pdev->dev.platform_data; + const s8 (*queue_priority_mapping)[2]; + const s8 (*queue_tc_mapping)[2]; + int i, j, off, ln, found = 0; + int status = -1; + const s16 (*rsv_chans)[2]; + const s16 (*rsv_slots)[2]; + int irq[EDMA_MAX_CC] = {0, 0}; + int err_irq[EDMA_MAX_CC] = {0, 0}; + struct resource *r[EDMA_MAX_CC] = {NULL}; + resource_size_t len[EDMA_MAX_CC]; + char res_name[10]; + char irq_name[10]; + + if (!info) + return -ENODEV; + + for (j = 0; j < EDMA_MAX_CC; j++) { + sprintf(res_name, "edma_cc%d", j); + r[j] = platform_get_resource_byname(pdev, IORESOURCE_MEM, + res_name); + if (!r[j] || !info[j]) { + if (found) + break; + else + return -ENODEV; + } else { + found = 1; + } + + len[j] = resource_size(r[j]); + + r[j] = request_mem_region(r[j]->start, len[j], + dev_name(&pdev->dev)); + if (!r[j]) { + status = -EBUSY; + goto fail1; + } + + edmacc_regs_base[j] = ioremap(r[j]->start, len[j]); + if (!edmacc_regs_base[j]) { + status = -EBUSY; + goto fail1; + } + + edma_cc[j] = kzalloc(sizeof(struct edma), GFP_KERNEL); + if (!edma_cc[j]) { + status = -ENOMEM; + goto fail1; + } + + edma_cc[j]->num_channels = min_t(unsigned, info[j]->n_channel, + EDMA_MAX_DMACH); + edma_cc[j]->num_slots = min_t(unsigned, info[j]->n_slot, + EDMA_MAX_PARAMENTRY); + edma_cc[j]->num_cc = min_t(unsigned, info[j]->n_cc, + EDMA_MAX_CC); + + edma_cc[j]->default_queue = info[j]->default_queue; + + dev_dbg(&pdev->dev, "DMA REG BASE ADDR=%p\n", + edmacc_regs_base[j]); + + for (i = 0; i < edma_cc[j]->num_slots; i++) + memcpy_toio(edmacc_regs_base[j] + PARM_OFFSET(i), + &dummy_paramset, PARM_SIZE); + + /* Mark all channels as unused */ + memset(edma_cc[j]->edma_unused, 0xff, + sizeof(edma_cc[j]->edma_unused)); + + if (info[j]->rsv) { + + /* Clear the reserved channels in unused list */ + rsv_chans = info[j]->rsv->rsv_chans; + if (rsv_chans) { + for (i = 0; rsv_chans[i][0] != -1; i++) { + off = rsv_chans[i][0]; + ln = rsv_chans[i][1]; + clear_bits(off, ln, + edma_cc[j]->edma_unused); + } + } + + /* Set the reserved slots in inuse list */ + rsv_slots = info[j]->rsv->rsv_slots; + if (rsv_slots) { + for (i = 0; rsv_slots[i][0] != -1; i++) { + off = rsv_slots[i][0]; + ln = rsv_slots[i][1]; + set_bits(off, ln, + edma_cc[j]->edma_inuse); + } + } + } + + sprintf(irq_name, "edma%d", j); + irq[j] = platform_get_irq_byname(pdev, irq_name); + edma_cc[j]->irq_res_start = irq[j]; + status = request_irq(irq[j], dma_irq_handler, 0, "edma", + &pdev->dev); + if (status < 0) { + dev_dbg(&pdev->dev, "request_irq %d failed --> %d\n", + irq[j], status); + goto fail; + } + + sprintf(irq_name, "edma%d_err", j); + err_irq[j] = platform_get_irq_byname(pdev, irq_name); + edma_cc[j]->irq_res_end = err_irq[j]; + status = request_irq(err_irq[j], dma_ccerr_handler, 0, + "edma_error", &pdev->dev); + if (status < 0) { + dev_dbg(&pdev->dev, "request_irq %d failed --> %d\n", + err_irq[j], status); + goto fail; + } + + for (i = 0; i < edma_cc[j]->num_channels; i++) + map_dmach_queue(j, i, info[j]->default_queue); + + queue_tc_mapping = info[j]->queue_tc_mapping; + queue_priority_mapping = info[j]->queue_priority_mapping; + + /* Event queue to TC mapping */ + for (i = 0; queue_tc_mapping[i][0] != -1; i++) + map_queue_tc(j, queue_tc_mapping[i][0], + queue_tc_mapping[i][1]); + + /* Event queue priority mapping */ + for (i = 0; queue_priority_mapping[i][0] != -1; i++) + assign_priority_to_queue(j, + queue_priority_mapping[i][0], + queue_priority_mapping[i][1]); + + /* Map the channel to param entry if channel mapping logic + * exist + */ + if (edma_read(j, EDMA_CCCFG) & CHMAP_EXIST) + map_dmach_param(j); + + for (i = 0; i < info[j]->n_region; i++) { + edma_write_array2(j, EDMA_DRAE, i, 0, 0x0); + edma_write_array2(j, EDMA_DRAE, i, 1, 0x0); + edma_write_array(j, EDMA_QRAE, i, 0x0); + } + arch_num_cc++; + } + + if (tc_errs_handled) { + status = request_irq(IRQ_TCERRINT0, dma_tc0err_handler, 0, + "edma_tc0", &pdev->dev); + if (status < 0) { + dev_dbg(&pdev->dev, "request_irq %d failed --> %d\n", + IRQ_TCERRINT0, status); + return status; + } + status = request_irq(IRQ_TCERRINT, dma_tc1err_handler, 0, + "edma_tc1", &pdev->dev); + if (status < 0) { + dev_dbg(&pdev->dev, "request_irq %d --> %d\n", + IRQ_TCERRINT, status); + return status; + } + } + + return 0; + +fail: + for (i = 0; i < EDMA_MAX_CC; i++) { + if (err_irq[i]) + free_irq(err_irq[i], &pdev->dev); + if (irq[i]) + free_irq(irq[i], &pdev->dev); + } +fail1: + for (i = 0; i < EDMA_MAX_CC; i++) { + if (r[i]) + release_mem_region(r[i]->start, len[i]); + if (edmacc_regs_base[i]) + iounmap(edmacc_regs_base[i]); + kfree(edma_cc[i]); + } + return status; +} + + +static struct platform_driver edma_driver = { + .driver.name = "edma", +}; + +static int __init edma_init(void) +{ + return platform_driver_probe(&edma_driver, edma_probe); +} +arch_initcall(edma_init); + diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/aemif.h b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/aemif.h new file mode 100644 index 00000000..05b29344 --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/aemif.h @@ -0,0 +1,36 @@ +/* + * TI DaVinci AEMIF support + * + * Copyright 2010 (C) Texas Instruments, Inc. http://www.ti.com/ + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ +#ifndef _MACH_DAVINCI_AEMIF_H +#define _MACH_DAVINCI_AEMIF_H + +#define NRCSR_OFFSET 0x00 +#define AWCCR_OFFSET 0x04 +#define A1CR_OFFSET 0x10 + +#define ACR_ASIZE_MASK 0x3 +#define ACR_EW_MASK BIT(30) +#define ACR_SS_MASK BIT(31) + +/* All timings in nanoseconds */ +struct davinci_aemif_timing { + u8 wsetup; + u8 wstrobe; + u8 whold; + + u8 rsetup; + u8 rstrobe; + u8 rhold; + + u8 ta; +}; + +int davinci_aemif_setup_timing(struct davinci_aemif_timing *t, + void __iomem *base, unsigned cs); +#endif diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/asp.h b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/asp.h new file mode 100644 index 00000000..9aa24090 --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/asp.h @@ -0,0 +1,137 @@ +/* + * <mach/asp.h> - DaVinci Audio Serial Port support + */ +#ifndef __ASM_ARCH_DAVINCI_ASP_H +#define __ASM_ARCH_DAVINCI_ASP_H + +#include <mach/irqs.h> +#include <mach/edma.h> + +/* Bases of dm644x and dm355 register banks */ +#define DAVINCI_ASP0_BASE 0x01E02000 +#define DAVINCI_ASP1_BASE 0x01E04000 + +/* Bases of dm365 register banks */ +#define DAVINCI_DM365_ASP0_BASE 0x01D02000 + +/* Bases of dm646x register banks */ +#define DAVINCI_DM646X_MCASP0_REG_BASE 0x01D01000 +#define DAVINCI_DM646X_MCASP1_REG_BASE 0x01D01800 + +/* Bases of da850/da830 McASP0 register banks */ +#define DAVINCI_DA8XX_MCASP0_REG_BASE 0x01D00000 + +/* Bases of da830 McASP1 register banks */ +#define DAVINCI_DA830_MCASP1_REG_BASE 0x01D04000 + +/* EDMA channels of dm644x and dm355 */ +#define DAVINCI_DMA_ASP0_TX 2 +#define DAVINCI_DMA_ASP0_RX 3 +#define DAVINCI_DMA_ASP1_TX 8 +#define DAVINCI_DMA_ASP1_RX 9 + +/* EDMA channels of dm646x */ +#define DAVINCI_DM646X_DMA_MCASP0_AXEVT0 6 +#define DAVINCI_DM646X_DMA_MCASP0_AREVT0 9 +#define DAVINCI_DM646X_DMA_MCASP1_AXEVT1 12 + +/* EDMA channels of da850/da830 McASP0 */ +#define DAVINCI_DA8XX_DMA_MCASP0_AREVT 0 +#define DAVINCI_DA8XX_DMA_MCASP0_AXEVT 1 + +/* EDMA channels of da830 McASP1 */ +#define DAVINCI_DA830_DMA_MCASP1_AREVT 2 +#define DAVINCI_DA830_DMA_MCASP1_AXEVT 3 + +/* Interrupts */ +#define DAVINCI_ASP0_RX_INT IRQ_MBRINT +#define DAVINCI_ASP0_TX_INT IRQ_MBXINT +#define DAVINCI_ASP1_RX_INT IRQ_MBRINT +#define DAVINCI_ASP1_TX_INT IRQ_MBXINT + +struct snd_platform_data { + u32 tx_dma_offset; + u32 rx_dma_offset; + enum dma_event_q asp_chan_q; /* event queue number for ASP channel */ + enum dma_event_q ram_chan_q; /* event queue number for RAM channel */ + unsigned int codec_fmt; + /* + * Allowing this is more efficient and eliminates left and right swaps + * caused by underruns, but will swap the left and right channels + * when compared to previous behavior. + */ + unsigned enable_channel_combine:1; + unsigned sram_size_playback; + unsigned sram_size_capture; + + /* + * If McBSP peripheral gets the clock from an external pin, + * there are three chooses, that are MCBSP_CLKX, MCBSP_CLKR + * and MCBSP_CLKS. + * Depending on different hardware connections it is possible + * to use this setting to change the behaviour of McBSP + * driver. The dm365_clk_input_pin enum is available for dm365 + */ + int clk_input_pin; + + /* + * This flag works when both clock and FS are outputs for the cpu + * and makes clock more accurate (FS is not symmetrical and the + * clock is very fast. + * The clock becoming faster is named + * i2s continuous serial clock (I2S_SCK) and it is an externally + * visible bit clock. + * + * first line : WordSelect + * second line : ContinuousSerialClock + * third line: SerialData + * + * SYMMETRICAL APPROACH: + * _______________________ LEFT + * _| RIGHT |______________________| + * _ _ _ _ _ _ _ _ + * _| |_| |_ x16 _| |_| |_| |_| |_ x16 _| |_| |_ + * _ _ _ _ _ _ _ _ + * _/ \_/ \_ ... _/ \_/ \_/ \_/ \_ ... _/ \_/ \_ + * \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ + * + * ACCURATE CLOCK APPROACH: + * ______________ LEFT + * _| RIGHT |_______________________________| + * _ _ _ _ _ _ _ _ _ + * _| |_ x16 _| |_| |_ x16 _| |_| |_| |_| |_| |_| | + * _ _ _ _ dummy cycles + * _/ \_ ... _/ \_/ \_ ... _/ \__________________ + * \_/ \_/ \_/ \_/ + * + */ + bool i2s_accurate_sck; + + /* McASP specific fields */ + int tdm_slots; + u8 op_mode; + u8 num_serializer; + u8 *serial_dir; + u8 version; + u8 txnumevt; + u8 rxnumevt; +}; + +enum { + MCASP_VERSION_1 = 0, /* DM646x */ + MCASP_VERSION_2, /* DA8xx/OMAPL1x */ +}; + +enum dm365_clk_input_pin { + MCBSP_CLKR = 0, /* DM365 */ + MCBSP_CLKS, +}; + +#define INACTIVE_MODE 0 +#define TX_MODE 1 +#define RX_MODE 2 + +#define DAVINCI_MCASP_IIS_MODE 0 +#define DAVINCI_MCASP_DIT_MODE 1 + +#endif /* __ASM_ARCH_DAVINCI_ASP_H */ diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/cdce949.h b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/cdce949.h new file mode 100644 index 00000000..c73331fa --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/cdce949.h @@ -0,0 +1,19 @@ +/* + * TI CDCE949 off-chip clock synthesizer support + * + * 2009 (C) Texas Instruments, Inc. http://www.ti.com/ + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ +#ifndef _MACH_DAVINCI_CDCE949_H +#define _MACH_DAVINCI_CDCE949_H + +#include <linux/clk.h> + +#include <mach/clock.h> + +int cdce_set_rate(struct clk *clk, unsigned long rate); + +#endif diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/clock.h b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/clock.h new file mode 100644 index 00000000..a3b04021 --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/clock.h @@ -0,0 +1,21 @@ +/* + * arch/arm/mach-davinci/include/mach/clock.h + * + * Clock control driver for DaVinci - header file + * + * Authors: Vladimir Barinov <source@mvista.com> + * + * 2007 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ +#ifndef __ASM_ARCH_DAVINCI_CLOCK_H +#define __ASM_ARCH_DAVINCI_CLOCK_H + +struct clk; + +extern int clk_register(struct clk *clk); +extern void clk_unregister(struct clk *clk); + +#endif diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/common.h b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/common.h new file mode 100644 index 00000000..5cd39a4e --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/common.h @@ -0,0 +1,92 @@ +/* + * Header for code common to all DaVinci machines. + * + * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com> + * + * 2007 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ + +#ifndef __ARCH_ARM_MACH_DAVINCI_COMMON_H +#define __ARCH_ARM_MACH_DAVINCI_COMMON_H + +#include <linux/compiler.h> +#include <linux/types.h> + +struct sys_timer; + +extern struct sys_timer davinci_timer; + +extern void davinci_irq_init(void); +extern void __iomem *davinci_intc_base; +extern int davinci_intc_type; + +struct davinci_timer_instance { + u32 base; + u32 bottom_irq; + u32 top_irq; + unsigned long cmp_off; + unsigned int cmp_irq; +}; + +struct davinci_timer_info { + struct davinci_timer_instance *timers; + unsigned int clockevent_id; + unsigned int clocksource_id; +}; + +struct davinci_gpio_controller; + +/* + * SoC info passed into common davinci modules. + * + * Base addresses in this structure should be physical and not virtual. + * Modules that take such base addresses, should internally ioremap() them to + * use. + */ +struct davinci_soc_info { + struct map_desc *io_desc; + unsigned long io_desc_num; + u32 cpu_id; + u32 jtag_id; + u32 jtag_id_reg; + struct davinci_id *ids; + unsigned long ids_num; + struct clk_lookup *cpu_clks; + u32 *psc_bases; + unsigned long psc_bases_num; + u32 pinmux_base; + const struct mux_config *pinmux_pins; + unsigned long pinmux_pins_num; + u32 intc_base; + int intc_type; + u8 *intc_irq_prios; + unsigned long intc_irq_num; + u32 *intc_host_map; + struct davinci_timer_info *timer_info; + int gpio_type; + u32 gpio_base; + unsigned gpio_num; + unsigned gpio_irq; + unsigned gpio_unbanked; + struct davinci_gpio_controller *gpio_ctlrs; + int gpio_ctlrs_num; + struct platform_device *serial_dev; + struct emac_platform_data *emac_pdata; + dma_addr_t sram_dma; + unsigned sram_len; +}; + +extern struct davinci_soc_info davinci_soc_info; + +extern void davinci_common_init(struct davinci_soc_info *soc_info); +extern void davinci_init_ide(void); +void davinci_restart(char mode, const char *cmd); + +/* standard place to map on-chip SRAMs; they *may* support DMA */ +#define SRAM_VIRT 0xfffe0000 +#define SRAM_SIZE SZ_128K + +#endif /* __ARCH_ARM_MACH_DAVINCI_COMMON_H */ diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/cp_intc.h b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/cp_intc.h new file mode 100644 index 00000000..4e8190ee --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/cp_intc.h @@ -0,0 +1,56 @@ +/* + * TI Common Platform Interrupt Controller (cp_intc) definitions + * + * Author: Steve Chen <schen@mvista.com> + * Copyright (C) 2008-2009, MontaVista Software, Inc. <source@mvista.com> + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ +#ifndef __ASM_HARDWARE_CP_INTC_H +#define __ASM_HARDWARE_CP_INTC_H + +#define CP_INTC_REV 0x00 +#define CP_INTC_CTRL 0x04 +#define CP_INTC_HOST_CTRL 0x0C +#define CP_INTC_GLOBAL_ENABLE 0x10 +#define CP_INTC_GLOBAL_NESTING_LEVEL 0x1C +#define CP_INTC_SYS_STAT_IDX_SET 0x20 +#define CP_INTC_SYS_STAT_IDX_CLR 0x24 +#define CP_INTC_SYS_ENABLE_IDX_SET 0x28 +#define CP_INTC_SYS_ENABLE_IDX_CLR 0x2C +#define CP_INTC_GLOBAL_WAKEUP_ENABLE 0x30 +#define CP_INTC_HOST_ENABLE_IDX_SET 0x34 +#define CP_INTC_HOST_ENABLE_IDX_CLR 0x38 +#define CP_INTC_PACING_PRESCALE 0x40 +#define CP_INTC_VECTOR_BASE 0x50 +#define CP_INTC_VECTOR_SIZE 0x54 +#define CP_INTC_VECTOR_NULL 0x58 +#define CP_INTC_PRIO_IDX 0x80 +#define CP_INTC_PRIO_VECTOR 0x84 +#define CP_INTC_SECURE_ENABLE 0x90 +#define CP_INTC_SECURE_PRIO_IDX 0x94 +#define CP_INTC_PACING_PARAM(n) (0x0100 + (n << 4)) +#define CP_INTC_PACING_DEC(n) (0x0104 + (n << 4)) +#define CP_INTC_PACING_MAP(n) (0x0108 + (n << 4)) +#define CP_INTC_SYS_RAW_STAT(n) (0x0200 + (n << 2)) +#define CP_INTC_SYS_STAT_CLR(n) (0x0280 + (n << 2)) +#define CP_INTC_SYS_ENABLE_SET(n) (0x0300 + (n << 2)) +#define CP_INTC_SYS_ENABLE_CLR(n) (0x0380 + (n << 2)) +#define CP_INTC_CHAN_MAP(n) (0x0400 + (n << 2)) +#define CP_INTC_HOST_MAP(n) (0x0800 + (n << 2)) +#define CP_INTC_HOST_PRIO_IDX(n) (0x0900 + (n << 2)) +#define CP_INTC_SYS_POLARITY(n) (0x0D00 + (n << 2)) +#define CP_INTC_SYS_TYPE(n) (0x0D80 + (n << 2)) +#define CP_INTC_WAKEUP_ENABLE(n) (0x0E00 + (n << 2)) +#define CP_INTC_DEBUG_SELECT(n) (0x0F00 + (n << 2)) +#define CP_INTC_SYS_SECURE_ENABLE(n) (0x1000 + (n << 2)) +#define CP_INTC_HOST_NESTING_LEVEL(n) (0x1100 + (n << 2)) +#define CP_INTC_HOST_ENABLE(n) (0x1500 + (n << 2)) +#define CP_INTC_HOST_PRIO_VECTOR(n) (0x1600 + (n << 2)) +#define CP_INTC_VECTOR_ADDR(n) (0x2000 + (n << 2)) + +void __init cp_intc_init(void); + +#endif /* __ASM_HARDWARE_CP_INTC_H */ diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/cpufreq.h b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/cpufreq.h new file mode 100644 index 00000000..3c089cfb --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/cpufreq.h @@ -0,0 +1,26 @@ +/* + * TI DaVinci CPUFreq platform support. + * + * Copyright (C) 2009 Texas Instruments, Inc. http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef _MACH_DAVINCI_CPUFREQ_H +#define _MACH_DAVINCI_CPUFREQ_H + +#include <linux/cpufreq.h> + +struct davinci_cpufreq_config { + struct cpufreq_frequency_table *freq_table; + int (*set_voltage) (unsigned int index); + int (*init) (void); +}; + +#endif diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/cpuidle.h b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/cpuidle.h new file mode 100644 index 00000000..74f088b0 --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/cpuidle.h @@ -0,0 +1,18 @@ +/* + * TI DaVinci cpuidle platform support + * + * 2009 (C) Texas Instruments, Inc. http://www.ti.com/ + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ +#ifndef _MACH_DAVINCI_CPUIDLE_H +#define _MACH_DAVINCI_CPUIDLE_H + +struct davinci_cpuidle_config { + u32 ddr2_pdown; + void __iomem *ddr2_ctlr_base; +}; + +#endif diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/cputype.h b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/cputype.h new file mode 100644 index 00000000..957fb87e --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/cputype.h @@ -0,0 +1,94 @@ +/* + * DaVinci CPU type detection + * + * Author: Kevin Hilman, Deep Root Systems, LLC + * + * Defines the cpu_is_*() macros for runtime detection of DaVinci + * device type. In addition, if support for a given device is not + * compiled in to the kernel, the macros return 0 so that + * resulting code can be optimized out. + * + * 2009 (c) Deep Root Systems, LLC. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ +#ifndef _ASM_ARCH_CPU_H +#define _ASM_ARCH_CPU_H + +#include <mach/common.h> + +struct davinci_id { + u8 variant; /* JTAG ID bits 31:28 */ + u16 part_no; /* JTAG ID bits 27:12 */ + u16 manufacturer; /* JTAG ID bits 11:1 */ + u32 cpu_id; + char *name; +}; + +/* Can use lower 16 bits of cpu id for a variant when required */ +#define DAVINCI_CPU_ID_DM6446 0x64460000 +#define DAVINCI_CPU_ID_DM6467 0x64670000 +#define DAVINCI_CPU_ID_DM355 0x03550000 +#define DAVINCI_CPU_ID_DM365 0x03650000 +#define DAVINCI_CPU_ID_DA830 0x08300000 +#define DAVINCI_CPU_ID_DA850 0x08500000 +#define DAVINCI_CPU_ID_TNETV107X 0x0b8a0000 + +#define IS_DAVINCI_CPU(type, id) \ +static inline int is_davinci_ ##type(void) \ +{ \ + return (davinci_soc_info.cpu_id == (id)); \ +} + +IS_DAVINCI_CPU(dm644x, DAVINCI_CPU_ID_DM6446) +IS_DAVINCI_CPU(dm646x, DAVINCI_CPU_ID_DM6467) +IS_DAVINCI_CPU(dm355, DAVINCI_CPU_ID_DM355) +IS_DAVINCI_CPU(dm365, DAVINCI_CPU_ID_DM365) +IS_DAVINCI_CPU(da830, DAVINCI_CPU_ID_DA830) +IS_DAVINCI_CPU(da850, DAVINCI_CPU_ID_DA850) +IS_DAVINCI_CPU(tnetv107x, DAVINCI_CPU_ID_TNETV107X) + +#ifdef CONFIG_ARCH_DAVINCI_DM644x +#define cpu_is_davinci_dm644x() is_davinci_dm644x() +#else +#define cpu_is_davinci_dm644x() 0 +#endif + +#ifdef CONFIG_ARCH_DAVINCI_DM646x +#define cpu_is_davinci_dm646x() is_davinci_dm646x() +#else +#define cpu_is_davinci_dm646x() 0 +#endif + +#ifdef CONFIG_ARCH_DAVINCI_DM355 +#define cpu_is_davinci_dm355() is_davinci_dm355() +#else +#define cpu_is_davinci_dm355() 0 +#endif + +#ifdef CONFIG_ARCH_DAVINCI_DM365 +#define cpu_is_davinci_dm365() is_davinci_dm365() +#else +#define cpu_is_davinci_dm365() 0 +#endif + +#ifdef CONFIG_ARCH_DAVINCI_DA830 +#define cpu_is_davinci_da830() is_davinci_da830() +#else +#define cpu_is_davinci_da830() 0 +#endif + +#ifdef CONFIG_ARCH_DAVINCI_DA850 +#define cpu_is_davinci_da850() is_davinci_da850() +#else +#define cpu_is_davinci_da850() 0 +#endif + +#ifdef CONFIG_ARCH_DAVINCI_TNETV107X +#define cpu_is_davinci_tnetv107x() is_davinci_tnetv107x() +#else +#define cpu_is_davinci_tnetv107x() 0 +#endif + +#endif diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/da8xx.h b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/da8xx.h new file mode 100644 index 00000000..ee3461d7 --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/da8xx.h @@ -0,0 +1,133 @@ +/* + * Chip specific defines for DA8XX/OMAP L1XX SoC + * + * Author: Mark A. Greer <mgreer@mvista.com> + * + * 2007, 2009-2010 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ +#ifndef __ASM_ARCH_DAVINCI_DA8XX_H +#define __ASM_ARCH_DAVINCI_DA8XX_H + +#include <video/da8xx-fb.h> + +#include <linux/platform_device.h> +#include <linux/davinci_emac.h> +#include <linux/spi/spi.h> + +#include <mach/serial.h> +#include <mach/edma.h> +#include <mach/i2c.h> +#include <mach/asp.h> +#include <mach/mmc.h> +#include <mach/usb.h> +#include <mach/pm.h> +#include <mach/spi.h> + +extern void __iomem *da8xx_syscfg0_base; +extern void __iomem *da8xx_syscfg1_base; + +/* + * If the DA850/OMAP-L138/AM18x SoC on board is of a higher speed grade + * (than the regular 300Mhz variant), the board code should set this up + * with the supported speed before calling da850_register_cpufreq(). + */ +extern unsigned int da850_max_speed; + +/* + * The cp_intc interrupt controller for the da8xx isn't in the same + * chunk of physical memory space as the other registers (like it is + * on the davincis) so it needs to be mapped separately. It will be + * mapped early on when the I/O space is mapped and we'll put it just + * before the I/O space in the processor's virtual memory space. + */ +#define DA8XX_CP_INTC_BASE 0xfffee000 +#define DA8XX_CP_INTC_SIZE SZ_8K +#define DA8XX_CP_INTC_VIRT (IO_VIRT - DA8XX_CP_INTC_SIZE - SZ_4K) + +#define DA8XX_SYSCFG0_BASE (IO_PHYS + 0x14000) +#define DA8XX_SYSCFG0_VIRT(x) (da8xx_syscfg0_base + (x)) +#define DA8XX_JTAG_ID_REG 0x18 +#define DA8XX_CFGCHIP0_REG 0x17c +#define DA8XX_CFGCHIP2_REG 0x184 +#define DA8XX_CFGCHIP3_REG 0x188 + +#define DA8XX_SYSCFG1_BASE (IO_PHYS + 0x22C000) +#define DA8XX_SYSCFG1_VIRT(x) (da8xx_syscfg1_base + (x)) +#define DA8XX_DEEPSLEEP_REG 0x8 +#define DA8XX_PWRDN_REG 0x18 + +#define DA8XX_PSC0_BASE 0x01c10000 +#define DA8XX_PLL0_BASE 0x01c11000 +#define DA8XX_TIMER64P0_BASE 0x01c20000 +#define DA8XX_TIMER64P1_BASE 0x01c21000 +#define DA8XX_GPIO_BASE 0x01e26000 +#define DA8XX_PSC1_BASE 0x01e27000 +#define DA8XX_AEMIF_CS2_BASE 0x60000000 +#define DA8XX_AEMIF_CS3_BASE 0x62000000 +#define DA8XX_AEMIF_CTL_BASE 0x68000000 +#define DA8XX_ARM_RAM_BASE 0xffff0000 + +void __init da830_init(void); +void __init da850_init(void); + +int da830_register_edma(struct edma_rsv_info *rsv); +int da850_register_edma(struct edma_rsv_info *rsv[2]); +int da8xx_register_i2c(int instance, struct davinci_i2c_platform_data *pdata); +int da8xx_register_spi(int instance, struct spi_board_info *info, unsigned len); +int da8xx_register_watchdog(void); +int da8xx_register_usb20(unsigned mA, unsigned potpgt); +int da8xx_register_usb11(struct da8xx_ohci_root_hub *pdata); +int da8xx_register_emac(void); +int da8xx_register_lcdc(struct da8xx_lcdc_platform_data *pdata); +int da8xx_register_mmcsd0(struct davinci_mmc_config *config); +int da850_register_mmcsd1(struct davinci_mmc_config *config); +void __init da8xx_register_mcasp(int id, struct snd_platform_data *pdata); +int da8xx_register_rtc(void); +int da850_register_cpufreq(char *async_clk); +int da8xx_register_cpuidle(void); +void __iomem * __init da8xx_get_mem_ctlr(void); +int da850_register_pm(struct platform_device *pdev); +int __init da850_register_sata(unsigned long refclkpn); +void da8xx_restart(char mode, const char *cmd); + +extern struct platform_device da8xx_serial_device; +extern struct emac_platform_data da8xx_emac_pdata; +extern struct da8xx_lcdc_platform_data sharp_lcd035q3dg01_pdata; +extern struct da8xx_lcdc_platform_data sharp_lk043t1dg01_pdata; +extern struct davinci_spi_platform_data da8xx_spi_pdata[]; + +extern struct platform_device da8xx_wdt_device; + +extern const short da830_emif25_pins[]; +extern const short da830_spi0_pins[]; +extern const short da830_spi1_pins[]; +extern const short da830_mmc_sd_pins[]; +extern const short da830_uart0_pins[]; +extern const short da830_uart1_pins[]; +extern const short da830_uart2_pins[]; +extern const short da830_usb20_pins[]; +extern const short da830_usb11_pins[]; +extern const short da830_uhpi_pins[]; +extern const short da830_cpgmac_pins[]; +extern const short da830_emif3c_pins[]; +extern const short da830_mcasp0_pins[]; +extern const short da830_mcasp1_pins[]; +extern const short da830_mcasp2_pins[]; +extern const short da830_i2c0_pins[]; +extern const short da830_i2c1_pins[]; +extern const short da830_lcdcntl_pins[]; +extern const short da830_pwm_pins[]; +extern const short da830_ecap0_pins[]; +extern const short da830_ecap1_pins[]; +extern const short da830_ecap2_pins[]; +extern const short da830_eqep0_pins[]; +extern const short da830_eqep1_pins[]; + +extern const short da850_i2c0_pins[]; +extern const short da850_i2c1_pins[]; +extern const short da850_lcdcntl_pins[]; + +#endif /* __ASM_ARCH_DAVINCI_DA8XX_H */ diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/ddr2.h b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/ddr2.h new file mode 100644 index 00000000..c19e047d --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/ddr2.h @@ -0,0 +1,4 @@ +#define DDR2_SDRCR_OFFSET 0xc +#define DDR2_SRPD_BIT (1 << 23) +#define DDR2_MCLKSTOPEN_BIT (1 << 30) +#define DDR2_LPMODEN_BIT (1 << 31) diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/debug-macro.S b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/debug-macro.S new file mode 100644 index 00000000..cf94552d --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/debug-macro.S @@ -0,0 +1,85 @@ +/* + * Debugging macro for DaVinci + * + * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com> + * + * 2007 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ + +/* Modifications + * Jan 2009 Chaithrika U S Added senduart, busyuart, waituart + * macros, based on debug-8250.S file + * but using 32-bit accesses required for + * some davinci devices. + */ + +#include <linux/serial_reg.h> + +#include <mach/serial.h> + +#define UART_SHIFT 2 + + .pushsection .data +davinci_uart_phys: .word 0 +davinci_uart_virt: .word 0 + .popsection + + .macro addruart, rp, rv, tmp + + /* Use davinci_uart_phys/virt if already configured */ +10: adr \rp, 99f @ get effective addr of 99f + ldr \rv, [\rp] @ get absolute addr of 99f + sub \rv, \rv, \rp @ offset between the two + ldr \rp, [\rp, #4] @ abs addr of omap_uart_phys + sub \tmp, \rp, \rv @ make it effective + ldr \rp, [\tmp, #0] @ davinci_uart_phys + ldr \rv, [\tmp, #4] @ davinci_uart_virt + cmp \rp, #0 @ is port configured? + cmpne \rv, #0 + bne 100f @ already configured + + /* Check the debug UART address set in uncompress.h */ + and \rp, pc, #0xff000000 + ldr \rv, =DAVINCI_UART_INFO_OFS + add \rp, \rp, \rv + + /* Copy uart phys address from decompressor uart info */ + ldr \rv, [\rp, #0] + str \rv, [\tmp, #0] + + /* Copy uart virt address from decompressor uart info */ + ldr \rv, [\rp, #4] + str \rv, [\tmp, #4] + + b 10b + + .align +99: .word . + .word davinci_uart_phys + .ltorg + +100: + .endm + + .macro senduart,rd,rx + str \rd, [\rx, #UART_TX << UART_SHIFT] + .endm + + .macro busyuart,rd,rx +1002: ldr \rd, [\rx, #UART_LSR << UART_SHIFT] + and \rd, \rd, #UART_LSR_TEMT | UART_LSR_THRE + teq \rd, #UART_LSR_TEMT | UART_LSR_THRE + bne 1002b + .endm + + .macro waituart,rd,rx +#ifdef FLOW_CONTROL +1001: ldr \rd, [\rx, #UART_MSR << UART_SHIFT] + tst \rd, #UART_MSR_CTS + beq 1001b +#endif + .endm + diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/dm365.h b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/dm365.h new file mode 100644 index 00000000..b9bf3d6a --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/dm365.h @@ -0,0 +1 @@ +/* empty, remove once unused */ diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/dm646x.h b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/dm646x.h new file mode 100644 index 00000000..b9bf3d6a --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/dm646x.h @@ -0,0 +1 @@ +/* empty, remove once unused */ diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/edma.h b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/edma.h new file mode 100644 index 00000000..7e84c906 --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/edma.h @@ -0,0 +1,267 @@ +/* + * TI DAVINCI dma definitions + * + * Copyright (C) 2006-2009 Texas Instruments. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +/* + * This EDMA3 programming framework exposes two basic kinds of resource: + * + * Channel Triggers transfers, usually from a hardware event but + * also manually or by "chaining" from DMA completions. + * Each channel is coupled to a Parameter RAM (PaRAM) slot. + * + * Slot Each PaRAM slot holds a DMA transfer descriptor (PaRAM + * "set"), source and destination addresses, a link to a + * next PaRAM slot (if any), options for the transfer, and + * instructions for updating those addresses. There are + * more than twice as many slots as event channels. + * + * Each PaRAM set describes a sequence of transfers, either for one large + * buffer or for several discontiguous smaller buffers. An EDMA transfer + * is driven only from a channel, which performs the transfers specified + * in its PaRAM slot until there are no more transfers. When that last + * transfer completes, the "link" field may be used to reload the channel's + * PaRAM slot with a new transfer descriptor. + * + * The EDMA Channel Controller (CC) maps requests from channels into physical + * Transfer Controller (TC) requests when the channel triggers (by hardware + * or software events, or by chaining). The two physical DMA channels provided + * by the TCs are thus shared by many logical channels. + * + * DaVinci hardware also has a "QDMA" mechanism which is not currently + * supported through this interface. (DSP firmware uses it though.) + */ + +#ifndef EDMA_H_ +#define EDMA_H_ + +/* PaRAM slots are laid out like this */ +struct edmacc_param { + unsigned int opt; + unsigned int src; + unsigned int a_b_cnt; + unsigned int dst; + unsigned int src_dst_bidx; + unsigned int link_bcntrld; + unsigned int src_dst_cidx; + unsigned int ccnt; +}; + +#define CCINT0_INTERRUPT 16 +#define CCERRINT_INTERRUPT 17 +#define TCERRINT0_INTERRUPT 18 +#define TCERRINT1_INTERRUPT 19 + +/* fields in edmacc_param.opt */ +#define SAM BIT(0) +#define DAM BIT(1) +#define SYNCDIM BIT(2) +#define STATIC BIT(3) +#define EDMA_FWID (0x07 << 8) +#define TCCMODE BIT(11) +#define EDMA_TCC(t) ((t) << 12) +#define TCINTEN BIT(20) +#define ITCINTEN BIT(21) +#define TCCHEN BIT(22) +#define ITCCHEN BIT(23) + +#define TRWORD (0x7<<2) +#define PAENTRY (0x1ff<<5) + +/* Drivers should avoid using these symbolic names for dm644x + * channels, and use platform_device IORESOURCE_DMA resources + * instead. (Other DaVinci chips have different peripherals + * and thus have different DMA channel mappings.) + */ +#define DAVINCI_DMA_MCBSP_TX 2 +#define DAVINCI_DMA_MCBSP_RX 3 +#define DAVINCI_DMA_VPSS_HIST 4 +#define DAVINCI_DMA_VPSS_H3A 5 +#define DAVINCI_DMA_VPSS_PRVU 6 +#define DAVINCI_DMA_VPSS_RSZ 7 +#define DAVINCI_DMA_IMCOP_IMXINT 8 +#define DAVINCI_DMA_IMCOP_VLCDINT 9 +#define DAVINCI_DMA_IMCO_PASQINT 10 +#define DAVINCI_DMA_IMCOP_DSQINT 11 +#define DAVINCI_DMA_SPI_SPIX 16 +#define DAVINCI_DMA_SPI_SPIR 17 +#define DAVINCI_DMA_UART0_URXEVT0 18 +#define DAVINCI_DMA_UART0_UTXEVT0 19 +#define DAVINCI_DMA_UART1_URXEVT1 20 +#define DAVINCI_DMA_UART1_UTXEVT1 21 +#define DAVINCI_DMA_UART2_URXEVT2 22 +#define DAVINCI_DMA_UART2_UTXEVT2 23 +#define DAVINCI_DMA_MEMSTK_MSEVT 24 +#define DAVINCI_DMA_MMCRXEVT 26 +#define DAVINCI_DMA_MMCTXEVT 27 +#define DAVINCI_DMA_I2C_ICREVT 28 +#define DAVINCI_DMA_I2C_ICXEVT 29 +#define DAVINCI_DMA_GPIO_GPINT0 32 +#define DAVINCI_DMA_GPIO_GPINT1 33 +#define DAVINCI_DMA_GPIO_GPINT2 34 +#define DAVINCI_DMA_GPIO_GPINT3 35 +#define DAVINCI_DMA_GPIO_GPINT4 36 +#define DAVINCI_DMA_GPIO_GPINT5 37 +#define DAVINCI_DMA_GPIO_GPINT6 38 +#define DAVINCI_DMA_GPIO_GPINT7 39 +#define DAVINCI_DMA_GPIO_GPBNKINT0 40 +#define DAVINCI_DMA_GPIO_GPBNKINT1 41 +#define DAVINCI_DMA_GPIO_GPBNKINT2 42 +#define DAVINCI_DMA_GPIO_GPBNKINT3 43 +#define DAVINCI_DMA_GPIO_GPBNKINT4 44 +#define DAVINCI_DMA_TIMER0_TINT0 48 +#define DAVINCI_DMA_TIMER1_TINT1 49 +#define DAVINCI_DMA_TIMER2_TINT2 50 +#define DAVINCI_DMA_TIMER3_TINT3 51 +#define DAVINCI_DMA_PWM0 52 +#define DAVINCI_DMA_PWM1 53 +#define DAVINCI_DMA_PWM2 54 + +/* DA830 specific EDMA3 information */ +#define EDMA_DA830_NUM_DMACH 32 +#define EDMA_DA830_NUM_TCC 32 +#define EDMA_DA830_NUM_PARAMENTRY 128 +#define EDMA_DA830_NUM_EVQUE 2 +#define EDMA_DA830_NUM_TC 2 +#define EDMA_DA830_CHMAP_EXIST 0 +#define EDMA_DA830_NUM_REGIONS 4 +#define DA830_DMACH2EVENT_MAP0 0x000FC03Fu +#define DA830_DMACH2EVENT_MAP1 0x00000000u +#define DA830_EDMA_ARM_OWN 0x30FFCCFFu + +/*ch_status paramater of callback function possible values*/ +#define DMA_COMPLETE 1 +#define DMA_CC_ERROR 2 +#define DMA_TC1_ERROR 3 +#define DMA_TC2_ERROR 4 + +enum address_mode { + INCR = 0, + FIFO = 1 +}; + +enum fifo_width { + W8BIT = 0, + W16BIT = 1, + W32BIT = 2, + W64BIT = 3, + W128BIT = 4, + W256BIT = 5 +}; + +enum dma_event_q { + EVENTQ_0 = 0, + EVENTQ_1 = 1, + EVENTQ_2 = 2, + EVENTQ_3 = 3, + EVENTQ_DEFAULT = -1 +}; + +enum sync_dimension { + ASYNC = 0, + ABSYNC = 1 +}; + +#define EDMA_CTLR_CHAN(ctlr, chan) (((ctlr) << 16) | (chan)) +#define EDMA_CTLR(i) ((i) >> 16) +#define EDMA_CHAN_SLOT(i) ((i) & 0xffff) + +#define EDMA_CHANNEL_ANY -1 /* for edma_alloc_channel() */ +#define EDMA_SLOT_ANY -1 /* for edma_alloc_slot() */ +#define EDMA_CONT_PARAMS_ANY 1001 +#define EDMA_CONT_PARAMS_FIXED_EXACT 1002 +#define EDMA_CONT_PARAMS_FIXED_NOT_EXACT 1003 + +#define EDMA_MAX_CC 2 + +/* alloc/free DMA channels and their dedicated parameter RAM slots */ +int edma_alloc_channel(int channel, + void (*callback)(unsigned channel, u16 ch_status, void *data), + void *data, enum dma_event_q); +void edma_free_channel(unsigned channel); + +/* alloc/free parameter RAM slots */ +int edma_alloc_slot(unsigned ctlr, int slot); +void edma_free_slot(unsigned slot); + +/* alloc/free a set of contiguous parameter RAM slots */ +int edma_alloc_cont_slots(unsigned ctlr, unsigned int id, int slot, int count); +int edma_free_cont_slots(unsigned slot, int count); + +/* calls that operate on part of a parameter RAM slot */ +void edma_set_src(unsigned slot, dma_addr_t src_port, + enum address_mode mode, enum fifo_width); +void edma_set_dest(unsigned slot, dma_addr_t dest_port, + enum address_mode mode, enum fifo_width); +void edma_get_position(unsigned slot, dma_addr_t *src, dma_addr_t *dst); +void edma_set_src_index(unsigned slot, s16 src_bidx, s16 src_cidx); +void edma_set_dest_index(unsigned slot, s16 dest_bidx, s16 dest_cidx); +void edma_set_transfer_params(unsigned slot, u16 acnt, u16 bcnt, u16 ccnt, + u16 bcnt_rld, enum sync_dimension sync_mode); +void edma_link(unsigned from, unsigned to); +void edma_unlink(unsigned from); + +/* calls that operate on an entire parameter RAM slot */ +void edma_write_slot(unsigned slot, const struct edmacc_param *params); +void edma_read_slot(unsigned slot, struct edmacc_param *params); + +/* channel control operations */ +int edma_start(unsigned channel); +void edma_stop(unsigned channel); +void edma_clean_channel(unsigned channel); +void edma_clear_event(unsigned channel); +void edma_pause(unsigned channel); +void edma_resume(unsigned channel); + +struct edma_rsv_info { + + const s16 (*rsv_chans)[2]; + const s16 (*rsv_slots)[2]; +}; + +/* platform_data for EDMA driver */ +struct edma_soc_info { + + /* how many dma resources of each type */ + unsigned n_channel; + unsigned n_region; + unsigned n_slot; + unsigned n_tc; + unsigned n_cc; + /* + * Default queue is expected to be a low-priority queue. + * This way, long transfers on the default queue started + * by the codec engine will not cause audio defects. + */ + enum dma_event_q default_queue; + + /* Resource reservation for other cores */ + struct edma_rsv_info *rsv; + + const s8 (*queue_tc_mapping)[2]; + const s8 (*queue_priority_mapping)[2]; +}; + +#endif diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/entry-macro.S b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/entry-macro.S new file mode 100644 index 00000000..768b3c06 --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/entry-macro.S @@ -0,0 +1,41 @@ +/* + * Low-level IRQ helper macros for TI DaVinci-based platforms + * + * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com> + * + * 2007 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ +#include <mach/irqs.h> + + .macro get_irqnr_preamble, base, tmp + ldr \base, =davinci_intc_base + ldr \base, [\base] + .endm + + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp +#if defined(CONFIG_AINTC) && defined(CONFIG_CP_INTC) + ldr \tmp, =davinci_intc_type + ldr \tmp, [\tmp] + cmp \tmp, #DAVINCI_INTC_TYPE_CP_INTC + beq 1001f +#endif +#if defined(CONFIG_AINTC) + ldr \tmp, [\base, #0x14] + movs \tmp, \tmp, lsr #2 + sub \irqnr, \tmp, #1 + b 1002f +#endif +#if defined(CONFIG_CP_INTC) +1001: ldr \irqnr, [\base, #0x80] /* get irq number */ + and \irqnr, \irqnr, #0xff /* irq is in bits 0-9 */ + mov \tmp, \irqnr, lsr #3 + and \tmp, \tmp, #0xfc + add \tmp, \tmp, #0x280 /* get the register offset */ + ldr \irqstat, [\base, \tmp] /* get the intc status */ + cmp \irqstat, #0x0 +#endif +1002: + .endm diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/gpio-davinci.h b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/gpio-davinci.h new file mode 100644 index 00000000..1fdd1fd3 --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/gpio-davinci.h @@ -0,0 +1,91 @@ +/* + * TI DaVinci GPIO Support + * + * Copyright (c) 2006 David Brownell + * Copyright (c) 2007, MontaVista Software, Inc. <source@mvista.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __DAVINCI_DAVINCI_GPIO_H +#define __DAVINCI_DAVINCI_GPIO_H + +#include <linux/io.h> +#include <linux/spinlock.h> + +#include <asm-generic/gpio.h> + +#include <mach/irqs.h> +#include <mach/common.h> + +#define DAVINCI_GPIO_BASE 0x01C67000 + +enum davinci_gpio_type { + GPIO_TYPE_DAVINCI = 0, + GPIO_TYPE_TNETV107X, +}; + +/* + * basic gpio routines + * + * board-specific init should be done by arch/.../.../board-XXX.c (maybe + * initializing banks together) rather than boot loaders; kexec() won't + * go through boot loaders. + * + * the gpio clock will be turned on when gpios are used, and you may also + * need to pay attention to PINMUX registers to be sure those pins are + * used as gpios, not with other peripherals. + * + * On-chip GPIOs are numbered 0..(DAVINCI_N_GPIO-1). For documentation, + * and maybe for later updates, code may write GPIO(N). These may be + * all 1.8V signals, all 3.3V ones, or a mix of the two. A given chip + * may not support all the GPIOs in that range. + * + * GPIOs can also be on external chips, numbered after the ones built-in + * to the DaVinci chip. For now, they won't be usable as IRQ sources. + */ +#define GPIO(X) (X) /* 0 <= X <= (DAVINCI_N_GPIO - 1) */ + +/* Convert GPIO signal to GPIO pin number */ +#define GPIO_TO_PIN(bank, gpio) (16 * (bank) + (gpio)) + +struct davinci_gpio_controller { + struct gpio_chip chip; + int irq_base; + spinlock_t lock; + void __iomem *regs; + void __iomem *set_data; + void __iomem *clr_data; + void __iomem *in_data; +}; + +/* The __gpio_to_controller() and __gpio_mask() functions inline to constants + * with constant parameters; or in outlined code they execute at runtime. + * + * You'd access the controller directly when reading or writing more than + * one gpio value at a time, and to support wired logic where the value + * being driven by the cpu need not match the value read back. + * + * These are NOT part of the cross-platform GPIO interface + */ +static inline struct davinci_gpio_controller * +__gpio_to_controller(unsigned gpio) +{ + struct davinci_gpio_controller *ctlrs = davinci_soc_info.gpio_ctlrs; + int index = gpio / 32; + + if (!ctlrs || index >= davinci_soc_info.gpio_ctlrs_num) + return NULL; + + return ctlrs + index; +} + +static inline u32 __gpio_mask(unsigned gpio) +{ + return 1 << (gpio % 32); +} + +#endif /* __DAVINCI_DAVINCI_GPIO_H */ diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/gpio.h b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/gpio.h new file mode 100644 index 00000000..960e9de4 --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/gpio.h @@ -0,0 +1,88 @@ +/* + * TI DaVinci GPIO Support + * + * Copyright (c) 2006 David Brownell + * Copyright (c) 2007, MontaVista Software, Inc. <source@mvista.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __DAVINCI_GPIO_H +#define __DAVINCI_GPIO_H + +#include <asm-generic/gpio.h> + +#define __ARM_GPIOLIB_COMPLEX + +/* The inline versions use the static inlines in the driver header */ +#include "gpio-davinci.h" + +/* + * The get/set/clear functions will inline when called with constant + * parameters referencing built-in GPIOs, for low-overhead bitbanging. + * + * gpio_set_value() will inline only on traditional Davinci style controllers + * with distinct set/clear registers. + * + * Otherwise, calls with variable parameters or referencing external + * GPIOs (e.g. on GPIO expander chips) use outlined functions. + */ +static inline void gpio_set_value(unsigned gpio, int value) +{ + if (__builtin_constant_p(value) && gpio < davinci_soc_info.gpio_num) { + struct davinci_gpio_controller *ctlr; + u32 mask; + + ctlr = __gpio_to_controller(gpio); + + if (ctlr->set_data != ctlr->clr_data) { + mask = __gpio_mask(gpio); + if (value) + __raw_writel(mask, ctlr->set_data); + else + __raw_writel(mask, ctlr->clr_data); + return; + } + } + + __gpio_set_value(gpio, value); +} + +/* Returns zero or nonzero; works for gpios configured as inputs OR + * as outputs, at least for built-in GPIOs. + * + * NOTE: for built-in GPIOs, changes in reported values are synchronized + * to the GPIO clock. This is easily seen after calling gpio_set_value() + * and then immediately gpio_get_value(), where the gpio_get_value() will + * return the old value until the GPIO clock ticks and the new value gets + * latched. + */ +static inline int gpio_get_value(unsigned gpio) +{ + struct davinci_gpio_controller *ctlr; + + if (!__builtin_constant_p(gpio) || gpio >= davinci_soc_info.gpio_num) + return __gpio_get_value(gpio); + + ctlr = __gpio_to_controller(gpio); + return __gpio_mask(gpio) & __raw_readl(ctlr->in_data); +} + +static inline int gpio_cansleep(unsigned gpio) +{ + if (__builtin_constant_p(gpio) && gpio < davinci_soc_info.gpio_num) + return 0; + else + return __gpio_cansleep(gpio); +} + +static inline int irq_to_gpio(unsigned irq) +{ + /* don't support the reverse mapping */ + return -ENOSYS; +} + +#endif /* __DAVINCI_GPIO_H */ diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/hardware.h b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/hardware.h new file mode 100644 index 00000000..2184691e --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/hardware.h @@ -0,0 +1,33 @@ +/* + * Hardware definitions common to all DaVinci family processors + * + * Author: Kevin Hilman, Deep Root Systems, LLC + * + * 2007 (c) Deep Root Systems, LLC. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ +#ifndef __ASM_ARCH_HARDWARE_H +#define __ASM_ARCH_HARDWARE_H + +/* + * Before you add anything to ths file: + * + * This header is for defines common to ALL DaVinci family chips. + * Anything that is chip specific should go in <chipname>.h, + * and the chip/board init code should then explicitly include + * <chipname>.h + */ +/* + * I/O mapping + */ +#define IO_PHYS 0x01c00000UL +#define IO_OFFSET 0xfd000000 /* Virtual IO = 0xfec00000 */ +#define IO_SIZE 0x00400000 +#define IO_VIRT (IO_PHYS + IO_OFFSET) +#define io_v2p(va) ((va) - IO_OFFSET) +#define __IO_ADDRESS(x) ((x) + IO_OFFSET) +#define IO_ADDRESS(pa) IOMEM(__IO_ADDRESS(pa)) + +#endif /* __ASM_ARCH_HARDWARE_H */ diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/i2c.h b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/i2c.h new file mode 100644 index 00000000..2312d197 --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/i2c.h @@ -0,0 +1,26 @@ +/* + * DaVinci I2C controller platform_device info + * + * Author: Vladimir Barinov, MontaVista Software, Inc. <source@mvista.com> + * + * 2007 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. +*/ + +#ifndef __ASM_ARCH_I2C_H +#define __ASM_ARCH_I2C_H + +/* All frequencies are expressed in kHz */ +struct davinci_i2c_platform_data { + unsigned int bus_freq; /* standard bus frequency (kHz) */ + unsigned int bus_delay; /* post-transaction delay (usec) */ + unsigned int sda_pin; /* GPIO pin ID to use for SDA */ + unsigned int scl_pin; /* GPIO pin ID to use for SCL */ +}; + +/* for board setup code */ +void davinci_init_i2c(struct davinci_i2c_platform_data *); + +#endif /* __ASM_ARCH_I2C_H */ diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/irqs.h b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/irqs.h new file mode 100644 index 00000000..ec76c777 --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/irqs.h @@ -0,0 +1,506 @@ +/* + * DaVinci interrupt controller definitions + * + * Copyright (C) 2006 Texas Instruments. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ +#ifndef __ASM_ARCH_IRQS_H +#define __ASM_ARCH_IRQS_H + +/* Base address */ +#define DAVINCI_ARM_INTC_BASE 0x01C48000 + +#define DAVINCI_INTC_TYPE_AINTC 0 +#define DAVINCI_INTC_TYPE_CP_INTC 1 + +/* Interrupt lines */ +#define IRQ_VDINT0 0 +#define IRQ_VDINT1 1 +#define IRQ_VDINT2 2 +#define IRQ_HISTINT 3 +#define IRQ_H3AINT 4 +#define IRQ_PRVUINT 5 +#define IRQ_RSZINT 6 +#define IRQ_VFOCINT 7 +#define IRQ_VENCINT 8 +#define IRQ_ASQINT 9 +#define IRQ_IMXINT 10 +#define IRQ_VLCDINT 11 +#define IRQ_USBINT 12 +#define IRQ_EMACINT 13 + +#define IRQ_CCINT0 16 +#define IRQ_CCERRINT 17 +#define IRQ_TCERRINT0 18 +#define IRQ_TCERRINT 19 +#define IRQ_PSCIN 20 + +#define IRQ_IDE 22 +#define IRQ_HPIINT 23 +#define IRQ_MBXINT 24 +#define IRQ_MBRINT 25 +#define IRQ_MMCINT 26 +#define IRQ_SDIOINT 27 +#define IRQ_MSINT 28 +#define IRQ_DDRINT 29 +#define IRQ_AEMIFINT 30 +#define IRQ_VLQINT 31 +#define IRQ_TINT0_TINT12 32 +#define IRQ_TINT0_TINT34 33 +#define IRQ_TINT1_TINT12 34 +#define IRQ_TINT1_TINT34 35 +#define IRQ_PWMINT0 36 +#define IRQ_PWMINT1 37 +#define IRQ_PWMINT2 38 +#define IRQ_I2C 39 +#define IRQ_UARTINT0 40 +#define IRQ_UARTINT1 41 +#define IRQ_UARTINT2 42 +#define IRQ_SPINT0 43 +#define IRQ_SPINT1 44 + +#define IRQ_DSP2ARM0 46 +#define IRQ_DSP2ARM1 47 +#define IRQ_GPIO0 48 +#define IRQ_GPIO1 49 +#define IRQ_GPIO2 50 +#define IRQ_GPIO3 51 +#define IRQ_GPIO4 52 +#define IRQ_GPIO5 53 +#define IRQ_GPIO6 54 +#define IRQ_GPIO7 55 +#define IRQ_GPIOBNK0 56 +#define IRQ_GPIOBNK1 57 +#define IRQ_GPIOBNK2 58 +#define IRQ_GPIOBNK3 59 +#define IRQ_GPIOBNK4 60 +#define IRQ_COMMTX 61 +#define IRQ_COMMRX 62 +#define IRQ_EMUINT 63 + +#define DAVINCI_N_AINTC_IRQ 64 + +#define ARCH_TIMER_IRQ IRQ_TINT1_TINT34 + +/* DaVinci DM6467-specific Interrupts */ +#define IRQ_DM646X_VP_VERTINT0 0 +#define IRQ_DM646X_VP_VERTINT1 1 +#define IRQ_DM646X_VP_VERTINT2 2 +#define IRQ_DM646X_VP_VERTINT3 3 +#define IRQ_DM646X_VP_ERRINT 4 +#define IRQ_DM646X_RESERVED_1 5 +#define IRQ_DM646X_RESERVED_2 6 +#define IRQ_DM646X_WDINT 7 +#define IRQ_DM646X_CRGENINT0 8 +#define IRQ_DM646X_CRGENINT1 9 +#define IRQ_DM646X_TSIFINT0 10 +#define IRQ_DM646X_TSIFINT1 11 +#define IRQ_DM646X_VDCEINT 12 +#define IRQ_DM646X_USBINT 13 +#define IRQ_DM646X_USBDMAINT 14 +#define IRQ_DM646X_PCIINT 15 +#define IRQ_DM646X_TCERRINT2 20 +#define IRQ_DM646X_TCERRINT3 21 +#define IRQ_DM646X_IDE 22 +#define IRQ_DM646X_HPIINT 23 +#define IRQ_DM646X_EMACRXTHINT 24 +#define IRQ_DM646X_EMACRXINT 25 +#define IRQ_DM646X_EMACTXINT 26 +#define IRQ_DM646X_EMACMISCINT 27 +#define IRQ_DM646X_MCASP0TXINT 28 +#define IRQ_DM646X_MCASP0RXINT 29 +#define IRQ_DM646X_RESERVED_3 31 +#define IRQ_DM646X_MCASP1TXINT 32 +#define IRQ_DM646X_VLQINT 38 +#define IRQ_DM646X_UARTINT2 42 +#define IRQ_DM646X_SPINT0 43 +#define IRQ_DM646X_SPINT1 44 +#define IRQ_DM646X_DSP2ARMINT 45 +#define IRQ_DM646X_RESERVED_4 46 +#define IRQ_DM646X_PSCINT 47 +#define IRQ_DM646X_GPIO0 48 +#define IRQ_DM646X_GPIO1 49 +#define IRQ_DM646X_GPIO2 50 +#define IRQ_DM646X_GPIO3 51 +#define IRQ_DM646X_GPIO4 52 +#define IRQ_DM646X_GPIO5 53 +#define IRQ_DM646X_GPIO6 54 +#define IRQ_DM646X_GPIO7 55 +#define IRQ_DM646X_GPIOBNK0 56 +#define IRQ_DM646X_GPIOBNK1 57 +#define IRQ_DM646X_GPIOBNK2 58 +#define IRQ_DM646X_DDRINT 59 +#define IRQ_DM646X_AEMIFINT 60 + +/* DaVinci DM355-specific Interrupts */ +#define IRQ_DM355_CCDC_VDINT0 0 +#define IRQ_DM355_CCDC_VDINT1 1 +#define IRQ_DM355_CCDC_VDINT2 2 +#define IRQ_DM355_IPIPE_HST 3 +#define IRQ_DM355_H3AINT 4 +#define IRQ_DM355_IPIPE_SDR 5 +#define IRQ_DM355_IPIPEIFINT 6 +#define IRQ_DM355_OSDINT 7 +#define IRQ_DM355_VENCINT 8 +#define IRQ_DM355_IMCOPINT 11 +#define IRQ_DM355_RTOINT 13 +#define IRQ_DM355_TINT4 13 +#define IRQ_DM355_TINT2_TINT12 13 +#define IRQ_DM355_UARTINT2 14 +#define IRQ_DM355_TINT5 14 +#define IRQ_DM355_TINT2_TINT34 14 +#define IRQ_DM355_TINT6 15 +#define IRQ_DM355_TINT3_TINT12 15 +#define IRQ_DM355_SPINT1_0 17 +#define IRQ_DM355_SPINT1_1 18 +#define IRQ_DM355_SPINT2_0 19 +#define IRQ_DM355_SPINT2_1 21 +#define IRQ_DM355_TINT7 22 +#define IRQ_DM355_TINT3_TINT34 22 +#define IRQ_DM355_SDIOINT0 23 +#define IRQ_DM355_MMCINT0 26 +#define IRQ_DM355_MSINT 26 +#define IRQ_DM355_MMCINT1 27 +#define IRQ_DM355_PWMINT3 28 +#define IRQ_DM355_SDIOINT1 31 +#define IRQ_DM355_SPINT0_0 42 +#define IRQ_DM355_SPINT0_1 43 +#define IRQ_DM355_GPIO0 44 +#define IRQ_DM355_GPIO1 45 +#define IRQ_DM355_GPIO2 46 +#define IRQ_DM355_GPIO3 47 +#define IRQ_DM355_GPIO4 48 +#define IRQ_DM355_GPIO5 49 +#define IRQ_DM355_GPIO6 50 +#define IRQ_DM355_GPIO7 51 +#define IRQ_DM355_GPIO8 52 +#define IRQ_DM355_GPIO9 53 +#define IRQ_DM355_GPIOBNK0 54 +#define IRQ_DM355_GPIOBNK1 55 +#define IRQ_DM355_GPIOBNK2 56 +#define IRQ_DM355_GPIOBNK3 57 +#define IRQ_DM355_GPIOBNK4 58 +#define IRQ_DM355_GPIOBNK5 59 +#define IRQ_DM355_GPIOBNK6 60 + +/* DaVinci DM365-specific Interrupts */ +#define IRQ_DM365_INSFINT 7 +#define IRQ_DM365_IMXINT1 8 +#define IRQ_DM365_IMXINT0 10 +#define IRQ_DM365_KLD_ARMINT 10 +#define IRQ_DM365_IMCOPINT 11 +#define IRQ_DM365_RTOINT 13 +#define IRQ_DM365_TINT5 14 +#define IRQ_DM365_TINT6 15 +#define IRQ_DM365_SPINT2_1 21 +#define IRQ_DM365_TINT7 22 +#define IRQ_DM365_SDIOINT0 23 +#define IRQ_DM365_MMCINT1 27 +#define IRQ_DM365_PWMINT3 28 +#define IRQ_DM365_RTCINT 29 +#define IRQ_DM365_SDIOINT1 31 +#define IRQ_DM365_SPIINT0_0 42 +#define IRQ_DM365_SPIINT3_0 43 +#define IRQ_DM365_GPIO0 44 +#define IRQ_DM365_GPIO1 45 +#define IRQ_DM365_GPIO2 46 +#define IRQ_DM365_GPIO3 47 +#define IRQ_DM365_GPIO4 48 +#define IRQ_DM365_GPIO5 49 +#define IRQ_DM365_GPIO6 50 +#define IRQ_DM365_GPIO7 51 +#define IRQ_DM365_EMAC_RXTHRESH 52 +#define IRQ_DM365_EMAC_RXPULSE 53 +#define IRQ_DM365_EMAC_TXPULSE 54 +#define IRQ_DM365_EMAC_MISCPULSE 55 +#define IRQ_DM365_GPIO12 56 +#define IRQ_DM365_GPIO13 57 +#define IRQ_DM365_GPIO14 58 +#define IRQ_DM365_GPIO15 59 +#define IRQ_DM365_ADCINT 59 +#define IRQ_DM365_KEYINT 60 +#define IRQ_DM365_TCERRINT2 61 +#define IRQ_DM365_TCERRINT3 62 +#define IRQ_DM365_EMUINT 63 + +/* DA8XX interrupts */ +#define IRQ_DA8XX_COMMTX 0 +#define IRQ_DA8XX_COMMRX 1 +#define IRQ_DA8XX_NINT 2 +#define IRQ_DA8XX_EVTOUT0 3 +#define IRQ_DA8XX_EVTOUT1 4 +#define IRQ_DA8XX_EVTOUT2 5 +#define IRQ_DA8XX_EVTOUT3 6 +#define IRQ_DA8XX_EVTOUT4 7 +#define IRQ_DA8XX_EVTOUT5 8 +#define IRQ_DA8XX_EVTOUT6 9 +#define IRQ_DA8XX_EVTOUT7 10 +#define IRQ_DA8XX_CCINT0 11 +#define IRQ_DA8XX_CCERRINT 12 +#define IRQ_DA8XX_TCERRINT0 13 +#define IRQ_DA8XX_AEMIFINT 14 +#define IRQ_DA8XX_I2CINT0 15 +#define IRQ_DA8XX_MMCSDINT0 16 +#define IRQ_DA8XX_MMCSDINT1 17 +#define IRQ_DA8XX_ALLINT0 18 +#define IRQ_DA8XX_RTC 19 +#define IRQ_DA8XX_SPINT0 20 +#define IRQ_DA8XX_TINT12_0 21 +#define IRQ_DA8XX_TINT34_0 22 +#define IRQ_DA8XX_TINT12_1 23 +#define IRQ_DA8XX_TINT34_1 24 +#define IRQ_DA8XX_UARTINT0 25 +#define IRQ_DA8XX_KEYMGRINT 26 +#define IRQ_DA8XX_SECINT 26 +#define IRQ_DA8XX_SECKEYERR 26 +#define IRQ_DA8XX_CHIPINT0 28 +#define IRQ_DA8XX_CHIPINT1 29 +#define IRQ_DA8XX_CHIPINT2 30 +#define IRQ_DA8XX_CHIPINT3 31 +#define IRQ_DA8XX_TCERRINT1 32 +#define IRQ_DA8XX_C0_RX_THRESH_PULSE 33 +#define IRQ_DA8XX_C0_RX_PULSE 34 +#define IRQ_DA8XX_C0_TX_PULSE 35 +#define IRQ_DA8XX_C0_MISC_PULSE 36 +#define IRQ_DA8XX_C1_RX_THRESH_PULSE 37 +#define IRQ_DA8XX_C1_RX_PULSE 38 +#define IRQ_DA8XX_C1_TX_PULSE 39 +#define IRQ_DA8XX_C1_MISC_PULSE 40 +#define IRQ_DA8XX_MEMERR 41 +#define IRQ_DA8XX_GPIO0 42 +#define IRQ_DA8XX_GPIO1 43 +#define IRQ_DA8XX_GPIO2 44 +#define IRQ_DA8XX_GPIO3 45 +#define IRQ_DA8XX_GPIO4 46 +#define IRQ_DA8XX_GPIO5 47 +#define IRQ_DA8XX_GPIO6 48 +#define IRQ_DA8XX_GPIO7 49 +#define IRQ_DA8XX_GPIO8 50 +#define IRQ_DA8XX_I2CINT1 51 +#define IRQ_DA8XX_LCDINT 52 +#define IRQ_DA8XX_UARTINT1 53 +#define IRQ_DA8XX_MCASPINT 54 +#define IRQ_DA8XX_ALLINT1 55 +#define IRQ_DA8XX_SPINT1 56 +#define IRQ_DA8XX_UHPI_INT1 57 +#define IRQ_DA8XX_USB_INT 58 +#define IRQ_DA8XX_IRQN 59 +#define IRQ_DA8XX_RWAKEUP 60 +#define IRQ_DA8XX_UARTINT2 61 +#define IRQ_DA8XX_DFTSSINT 62 +#define IRQ_DA8XX_EHRPWM0 63 +#define IRQ_DA8XX_EHRPWM0TZ 64 +#define IRQ_DA8XX_EHRPWM1 65 +#define IRQ_DA8XX_EHRPWM1TZ 66 +#define IRQ_DA8XX_ECAP0 69 +#define IRQ_DA8XX_ECAP1 70 +#define IRQ_DA8XX_ECAP2 71 +#define IRQ_DA8XX_ARMCLKSTOPREQ 90 + +/* DA830 specific interrupts */ +#define IRQ_DA830_MPUERR 27 +#define IRQ_DA830_IOPUERR 27 +#define IRQ_DA830_BOOTCFGERR 27 +#define IRQ_DA830_EHRPWM2 67 +#define IRQ_DA830_EHRPWM2TZ 68 +#define IRQ_DA830_EQEP0 72 +#define IRQ_DA830_EQEP1 73 +#define IRQ_DA830_T12CMPINT0_0 74 +#define IRQ_DA830_T12CMPINT1_0 75 +#define IRQ_DA830_T12CMPINT2_0 76 +#define IRQ_DA830_T12CMPINT3_0 77 +#define IRQ_DA830_T12CMPINT4_0 78 +#define IRQ_DA830_T12CMPINT5_0 79 +#define IRQ_DA830_T12CMPINT6_0 80 +#define IRQ_DA830_T12CMPINT7_0 81 +#define IRQ_DA830_T12CMPINT0_1 82 +#define IRQ_DA830_T12CMPINT1_1 83 +#define IRQ_DA830_T12CMPINT2_1 84 +#define IRQ_DA830_T12CMPINT3_1 85 +#define IRQ_DA830_T12CMPINT4_1 86 +#define IRQ_DA830_T12CMPINT5_1 87 +#define IRQ_DA830_T12CMPINT6_1 88 +#define IRQ_DA830_T12CMPINT7_1 89 + +#define DA830_N_CP_INTC_IRQ 96 + +/* DA850 speicific interrupts */ +#define IRQ_DA850_MPUADDRERR0 27 +#define IRQ_DA850_MPUPROTERR0 27 +#define IRQ_DA850_IOPUADDRERR0 27 +#define IRQ_DA850_IOPUPROTERR0 27 +#define IRQ_DA850_IOPUADDRERR1 27 +#define IRQ_DA850_IOPUPROTERR1 27 +#define IRQ_DA850_IOPUADDRERR2 27 +#define IRQ_DA850_IOPUPROTERR2 27 +#define IRQ_DA850_BOOTCFG_ADDR_ERR 27 +#define IRQ_DA850_BOOTCFG_PROT_ERR 27 +#define IRQ_DA850_MPUADDRERR1 27 +#define IRQ_DA850_MPUPROTERR1 27 +#define IRQ_DA850_IOPUADDRERR3 27 +#define IRQ_DA850_IOPUPROTERR3 27 +#define IRQ_DA850_IOPUADDRERR4 27 +#define IRQ_DA850_IOPUPROTERR4 27 +#define IRQ_DA850_IOPUADDRERR5 27 +#define IRQ_DA850_IOPUPROTERR5 27 +#define IRQ_DA850_MIOPU_BOOTCFG_ERR 27 +#define IRQ_DA850_SATAINT 67 +#define IRQ_DA850_TINT12_2 68 +#define IRQ_DA850_TINT34_2 68 +#define IRQ_DA850_TINTALL_2 68 +#define IRQ_DA850_MMCSDINT0_1 72 +#define IRQ_DA850_MMCSDINT1_1 73 +#define IRQ_DA850_T12CMPINT0_2 74 +#define IRQ_DA850_T12CMPINT1_2 75 +#define IRQ_DA850_T12CMPINT2_2 76 +#define IRQ_DA850_T12CMPINT3_2 77 +#define IRQ_DA850_T12CMPINT4_2 78 +#define IRQ_DA850_T12CMPINT5_2 79 +#define IRQ_DA850_T12CMPINT6_2 80 +#define IRQ_DA850_T12CMPINT7_2 81 +#define IRQ_DA850_T12CMPINT0_3 82 +#define IRQ_DA850_T12CMPINT1_3 83 +#define IRQ_DA850_T12CMPINT2_3 84 +#define IRQ_DA850_T12CMPINT3_3 85 +#define IRQ_DA850_T12CMPINT4_3 86 +#define IRQ_DA850_T12CMPINT5_3 87 +#define IRQ_DA850_T12CMPINT6_3 88 +#define IRQ_DA850_T12CMPINT7_3 89 +#define IRQ_DA850_RPIINT 91 +#define IRQ_DA850_VPIFINT 92 +#define IRQ_DA850_CCINT1 93 +#define IRQ_DA850_CCERRINT1 94 +#define IRQ_DA850_TCERRINT2 95 +#define IRQ_DA850_TINT12_3 96 +#define IRQ_DA850_TINT34_3 96 +#define IRQ_DA850_TINTALL_3 96 +#define IRQ_DA850_MCBSP0RINT 97 +#define IRQ_DA850_MCBSP0XINT 98 +#define IRQ_DA850_MCBSP1RINT 99 +#define IRQ_DA850_MCBSP1XINT 100 + +#define DA850_N_CP_INTC_IRQ 101 + + +/* TNETV107X specific interrupts */ +#define IRQ_TNETV107X_TDM1_TXDMA 0 +#define IRQ_TNETV107X_EXT_INT_0 1 +#define IRQ_TNETV107X_EXT_INT_1 2 +#define IRQ_TNETV107X_GPIO_INT12 3 +#define IRQ_TNETV107X_GPIO_INT13 4 +#define IRQ_TNETV107X_TIMER_0_TINT12 5 +#define IRQ_TNETV107X_TIMER_1_TINT12 6 +#define IRQ_TNETV107X_UART0 7 +#define IRQ_TNETV107X_TDM1_RXDMA 8 +#define IRQ_TNETV107X_MCDMA_INT0 9 +#define IRQ_TNETV107X_MCDMA_INT1 10 +#define IRQ_TNETV107X_TPCC 11 +#define IRQ_TNETV107X_TPCC_INT0 12 +#define IRQ_TNETV107X_TPCC_INT1 13 +#define IRQ_TNETV107X_TPCC_INT2 14 +#define IRQ_TNETV107X_TPCC_INT3 15 +#define IRQ_TNETV107X_TPTC0 16 +#define IRQ_TNETV107X_TPTC1 17 +#define IRQ_TNETV107X_TIMER_0_TINT34 18 +#define IRQ_TNETV107X_ETHSS 19 +#define IRQ_TNETV107X_TIMER_1_TINT34 20 +#define IRQ_TNETV107X_DSP2ARM_INT0 21 +#define IRQ_TNETV107X_DSP2ARM_INT1 22 +#define IRQ_TNETV107X_ARM_NPMUIRQ 23 +#define IRQ_TNETV107X_USB1 24 +#define IRQ_TNETV107X_VLYNQ 25 +#define IRQ_TNETV107X_UART0_DMATX 26 +#define IRQ_TNETV107X_UART0_DMARX 27 +#define IRQ_TNETV107X_TDM1_TXMCSP 28 +#define IRQ_TNETV107X_SSP 29 +#define IRQ_TNETV107X_MCDMA_INT2 30 +#define IRQ_TNETV107X_MCDMA_INT3 31 +#define IRQ_TNETV107X_TDM_CODECIF_EOT 32 +#define IRQ_TNETV107X_IMCOP_SQR_ARM 33 +#define IRQ_TNETV107X_USB0 34 +#define IRQ_TNETV107X_USB_CDMA 35 +#define IRQ_TNETV107X_LCD 36 +#define IRQ_TNETV107X_KEYPAD 37 +#define IRQ_TNETV107X_KEYPAD_FREE 38 +#define IRQ_TNETV107X_RNG 39 +#define IRQ_TNETV107X_PKA 40 +#define IRQ_TNETV107X_TDM0_TXDMA 41 +#define IRQ_TNETV107X_TDM0_RXDMA 42 +#define IRQ_TNETV107X_TDM0_TXMCSP 43 +#define IRQ_TNETV107X_TDM0_RXMCSP 44 +#define IRQ_TNETV107X_TDM1_RXMCSP 45 +#define IRQ_TNETV107X_SDIO1 46 +#define IRQ_TNETV107X_SDIO0 47 +#define IRQ_TNETV107X_TSC 48 +#define IRQ_TNETV107X_TS 49 +#define IRQ_TNETV107X_UART1 50 +#define IRQ_TNETV107X_MBX_LITE 51 +#define IRQ_TNETV107X_GPIO_INT00 52 +#define IRQ_TNETV107X_GPIO_INT01 53 +#define IRQ_TNETV107X_GPIO_INT02 54 +#define IRQ_TNETV107X_GPIO_INT03 55 +#define IRQ_TNETV107X_UART2 56 +#define IRQ_TNETV107X_UART2_DMATX 57 +#define IRQ_TNETV107X_UART2_DMARX 58 +#define IRQ_TNETV107X_IMCOP_IMX 59 +#define IRQ_TNETV107X_IMCOP_VLCD 60 +#define IRQ_TNETV107X_AES 61 +#define IRQ_TNETV107X_DES 62 +#define IRQ_TNETV107X_SHAMD5 63 +#define IRQ_TNETV107X_TPCC_ERR 68 +#define IRQ_TNETV107X_TPCC_PROT 69 +#define IRQ_TNETV107X_TPTC0_ERR 70 +#define IRQ_TNETV107X_TPTC1_ERR 71 +#define IRQ_TNETV107X_UART0_ERR 72 +#define IRQ_TNETV107X_UART1_ERR 73 +#define IRQ_TNETV107X_AEMIF_ERR 74 +#define IRQ_TNETV107X_DDR_ERR 75 +#define IRQ_TNETV107X_WDTARM_INT0 76 +#define IRQ_TNETV107X_MCDMA_ERR 77 +#define IRQ_TNETV107X_GPIO_ERR 78 +#define IRQ_TNETV107X_MPU_ADDR 79 +#define IRQ_TNETV107X_MPU_PROT 80 +#define IRQ_TNETV107X_IOPU_ADDR 81 +#define IRQ_TNETV107X_IOPU_PROT 82 +#define IRQ_TNETV107X_KEYPAD_ADDR_ERR 83 +#define IRQ_TNETV107X_WDT0_ADDR_ERR 84 +#define IRQ_TNETV107X_WDT1_ADDR_ERR 85 +#define IRQ_TNETV107X_CLKCTL_ADDR_ERR 86 +#define IRQ_TNETV107X_PLL_UNLOCK 87 +#define IRQ_TNETV107X_WDTDSP_INT0 88 +#define IRQ_TNETV107X_SEC_CTRL_VIOLATION 89 +#define IRQ_TNETV107X_KEY_MNG_VIOLATION 90 +#define IRQ_TNETV107X_PBIST_CPU 91 +#define IRQ_TNETV107X_WDTARM 92 +#define IRQ_TNETV107X_PSC 93 +#define IRQ_TNETV107X_MMC0 94 +#define IRQ_TNETV107X_MMC1 95 + +#define TNETV107X_N_CP_INTC_IRQ 96 + +/* da850 currently has the most gpio pins (144) */ +#define DAVINCI_N_GPIO 144 +/* da850 currently has the most irqs so use DA850_N_CP_INTC_IRQ */ +#define NR_IRQS (DA850_N_CP_INTC_IRQ + DAVINCI_N_GPIO) + +#endif /* __ASM_ARCH_IRQS_H */ diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/keyscan.h b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/keyscan.h new file mode 100644 index 00000000..7a560e05 --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/keyscan.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2009 Texas Instruments, Inc + * + * Author: Miguel Aguilar <miguel.aguilar@ridgerun.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef DAVINCI_KEYSCAN_H +#define DAVINCI_KEYSCAN_H + +#include <linux/io.h> + +enum davinci_matrix_types { + DAVINCI_KEYSCAN_MATRIX_4X4, + DAVINCI_KEYSCAN_MATRIX_5X3, +}; + +struct davinci_ks_platform_data { + int (*device_enable)(struct device *dev); + unsigned short *keymap; + u32 keymapsize; + u8 rep:1; + u8 strobe; + u8 interval; + u8 matrix_type; +}; + +#endif + diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/mmc.h b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/mmc.h new file mode 100644 index 00000000..5ba6b22c --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/mmc.h @@ -0,0 +1,39 @@ +/* + * Board-specific MMC configuration + */ + +#ifndef _DAVINCI_MMC_H +#define _DAVINCI_MMC_H + +#include <linux/types.h> +#include <linux/mmc/host.h> + +struct davinci_mmc_config { + /* get_cd()/get_wp() may sleep */ + int (*get_cd)(int module); + int (*get_ro)(int module); + + void (*set_power)(int module, bool on); + + /* wires == 0 is equivalent to wires == 4 (4-bit parallel) */ + u8 wires; + + u32 max_freq; + + /* any additional host capabilities: OR'd in to mmc->f_caps */ + u32 caps; + + /* Version of the MMC/SD controller */ + u8 version; + + /* Number of sg segments */ + u8 nr_sg; +}; +void davinci_setup_mmc(int module, struct davinci_mmc_config *config); + +enum { + MMC_CTLR_VERSION_1 = 0, /* DM644x and DM355 */ + MMC_CTLR_VERSION_2, /* DA830 */ +}; + +#endif diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/mux.h b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/mux.h new file mode 100644 index 00000000..a7e92fca --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/mux.h @@ -0,0 +1,1217 @@ +/* + * Table of the DAVINCI register configurations for the PINMUX combinations + * + * Author: Vladimir Barinov, MontaVista Software, Inc. <source@mvista.com> + * + * Based on linux/include/asm-arm/arch-omap/mux.h: + * Copyright (C) 2003 - 2005 Nokia Corporation + * + * Written by Tony Lindgren + * + * 2007 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + * + * Copyright (C) 2008 Texas Instruments. + */ + +#ifndef __INC_MACH_MUX_H +#define __INC_MACH_MUX_H + +struct mux_config { + const char *name; + const char *mux_reg_name; + const unsigned char mux_reg; + const unsigned char mask_offset; + const unsigned char mask; + const unsigned char mode; + bool debug; +}; + +enum davinci_dm644x_index { + /* ATA and HDDIR functions */ + DM644X_HDIREN, + DM644X_ATAEN, + DM644X_ATAEN_DISABLE, + + /* HPI functions */ + DM644X_HPIEN_DISABLE, + + /* AEAW functions */ + DM644X_AEAW, + DM644X_AEAW0, + DM644X_AEAW1, + DM644X_AEAW2, + DM644X_AEAW3, + DM644X_AEAW4, + + /* Memory Stick */ + DM644X_MSTK, + + /* I2C */ + DM644X_I2C, + + /* ASP function */ + DM644X_MCBSP, + + /* UART1 */ + DM644X_UART1, + + /* UART2 */ + DM644X_UART2, + + /* PWM0 */ + DM644X_PWM0, + + /* PWM1 */ + DM644X_PWM1, + + /* PWM2 */ + DM644X_PWM2, + + /* VLYNQ function */ + DM644X_VLYNQEN, + DM644X_VLSCREN, + DM644X_VLYNQWD, + + /* EMAC and MDIO function */ + DM644X_EMACEN, + + /* GPIO3V[0:16] pins */ + DM644X_GPIO3V, + + /* GPIO pins */ + DM644X_GPIO0, + DM644X_GPIO3, + DM644X_GPIO43_44, + DM644X_GPIO46_47, + + /* VPBE */ + DM644X_RGB666, + + /* LCD */ + DM644X_LOEEN, + DM644X_LFLDEN, +}; + +enum davinci_dm646x_index { + /* ATA function */ + DM646X_ATAEN, + + /* AUDIO Clock */ + DM646X_AUDCK1, + DM646X_AUDCK0, + + /* CRGEN Control */ + DM646X_CRGMUX, + + /* VPIF Control */ + DM646X_STSOMUX_DISABLE, + DM646X_STSIMUX_DISABLE, + DM646X_PTSOMUX_DISABLE, + DM646X_PTSIMUX_DISABLE, + + /* TSIF Control */ + DM646X_STSOMUX, + DM646X_STSIMUX, + DM646X_PTSOMUX_PARALLEL, + DM646X_PTSIMUX_PARALLEL, + DM646X_PTSOMUX_SERIAL, + DM646X_PTSIMUX_SERIAL, +}; + +enum davinci_dm355_index { + /* MMC/SD 0 */ + DM355_MMCSD0, + + /* MMC/SD 1 */ + DM355_SD1_CLK, + DM355_SD1_CMD, + DM355_SD1_DATA3, + DM355_SD1_DATA2, + DM355_SD1_DATA1, + DM355_SD1_DATA0, + + /* I2C */ + DM355_I2C_SDA, + DM355_I2C_SCL, + + /* ASP0 function */ + DM355_MCBSP0_BDX, + DM355_MCBSP0_X, + DM355_MCBSP0_BFSX, + DM355_MCBSP0_BDR, + DM355_MCBSP0_R, + DM355_MCBSP0_BFSR, + + /* SPI0 */ + DM355_SPI0_SDI, + DM355_SPI0_SDENA0, + DM355_SPI0_SDENA1, + + /* IRQ muxing */ + DM355_INT_EDMA_CC, + DM355_INT_EDMA_TC0_ERR, + DM355_INT_EDMA_TC1_ERR, + + /* EDMA event muxing */ + DM355_EVT8_ASP1_TX, + DM355_EVT9_ASP1_RX, + DM355_EVT26_MMC0_RX, + + /* Video Out */ + DM355_VOUT_FIELD, + DM355_VOUT_FIELD_G70, + DM355_VOUT_HVSYNC, + DM355_VOUT_COUTL_EN, + DM355_VOUT_COUTH_EN, + + /* Video In Pin Mux */ + DM355_VIN_PCLK, + DM355_VIN_CAM_WEN, + DM355_VIN_CAM_VD, + DM355_VIN_CAM_HD, + DM355_VIN_YIN_EN, + DM355_VIN_CINL_EN, + DM355_VIN_CINH_EN, +}; + +enum davinci_dm365_index { + /* MMC/SD 0 */ + DM365_MMCSD0, + + /* MMC/SD 1 */ + DM365_SD1_CLK, + DM365_SD1_CMD, + DM365_SD1_DATA3, + DM365_SD1_DATA2, + DM365_SD1_DATA1, + DM365_SD1_DATA0, + + /* I2C */ + DM365_I2C_SDA, + DM365_I2C_SCL, + + /* AEMIF */ + DM365_AEMIF_AR_A14, + DM365_AEMIF_AR_BA0, + DM365_AEMIF_A3, + DM365_AEMIF_A7, + DM365_AEMIF_D15_8, + DM365_AEMIF_CE0, + DM365_AEMIF_CE1, + DM365_AEMIF_WE_OE, + + /* ASP0 function */ + DM365_MCBSP0_BDX, + DM365_MCBSP0_X, + DM365_MCBSP0_BFSX, + DM365_MCBSP0_BDR, + DM365_MCBSP0_R, + DM365_MCBSP0_BFSR, + + /* SPI0 */ + DM365_SPI0_SCLK, + DM365_SPI0_SDI, + DM365_SPI0_SDO, + DM365_SPI0_SDENA0, + DM365_SPI0_SDENA1, + + /* UART */ + DM365_UART0_RXD, + DM365_UART0_TXD, + DM365_UART1_RXD, + DM365_UART1_TXD, + DM365_UART1_RTS, + DM365_UART1_CTS, + + /* EMAC */ + DM365_EMAC_TX_EN, + DM365_EMAC_TX_CLK, + DM365_EMAC_COL, + DM365_EMAC_TXD3, + DM365_EMAC_TXD2, + DM365_EMAC_TXD1, + DM365_EMAC_TXD0, + DM365_EMAC_RXD3, + DM365_EMAC_RXD2, + DM365_EMAC_RXD1, + DM365_EMAC_RXD0, + DM365_EMAC_RX_CLK, + DM365_EMAC_RX_DV, + DM365_EMAC_RX_ER, + DM365_EMAC_CRS, + DM365_EMAC_MDIO, + DM365_EMAC_MDCLK, + + /* Key Scan */ + DM365_KEYSCAN, + + /* PWM */ + DM365_PWM0, + DM365_PWM0_G23, + DM365_PWM1, + DM365_PWM1_G25, + DM365_PWM2_G87, + DM365_PWM2_G88, + DM365_PWM2_G89, + DM365_PWM2_G90, + DM365_PWM3_G80, + DM365_PWM3_G81, + DM365_PWM3_G85, + DM365_PWM3_G86, + + /* SPI1 */ + DM365_SPI1_SCLK, + DM365_SPI1_SDO, + DM365_SPI1_SDI, + DM365_SPI1_SDENA0, + DM365_SPI1_SDENA1, + + /* SPI2 */ + DM365_SPI2_SCLK, + DM365_SPI2_SDO, + DM365_SPI2_SDI, + DM365_SPI2_SDENA0, + DM365_SPI2_SDENA1, + + /* SPI3 */ + DM365_SPI3_SCLK, + DM365_SPI3_SDO, + DM365_SPI3_SDI, + DM365_SPI3_SDENA0, + DM365_SPI3_SDENA1, + + /* SPI4 */ + DM365_SPI4_SCLK, + DM365_SPI4_SDO, + DM365_SPI4_SDI, + DM365_SPI4_SDENA0, + DM365_SPI4_SDENA1, + + /* Clock */ + DM365_CLKOUT0, + DM365_CLKOUT1, + DM365_CLKOUT2, + + /* GPIO */ + DM365_GPIO20, + DM365_GPIO30, + DM365_GPIO31, + DM365_GPIO32, + DM365_GPIO33, + DM365_GPIO40, + DM365_GPIO64_57, + + /* Video */ + DM365_VOUT_FIELD, + DM365_VOUT_FIELD_G81, + DM365_VOUT_HVSYNC, + DM365_VOUT_COUTL_EN, + DM365_VOUT_COUTH_EN, + DM365_VIN_CAM_WEN, + DM365_VIN_CAM_VD, + DM365_VIN_CAM_HD, + DM365_VIN_YIN4_7_EN, + DM365_VIN_YIN0_3_EN, + + /* IRQ muxing */ + DM365_INT_EDMA_CC, + DM365_INT_EDMA_TC0_ERR, + DM365_INT_EDMA_TC1_ERR, + DM365_INT_EDMA_TC2_ERR, + DM365_INT_EDMA_TC3_ERR, + DM365_INT_PRTCSS, + DM365_INT_EMAC_RXTHRESH, + DM365_INT_EMAC_RXPULSE, + DM365_INT_EMAC_TXPULSE, + DM365_INT_EMAC_MISCPULSE, + DM365_INT_IMX0_ENABLE, + DM365_INT_IMX0_DISABLE, + DM365_INT_HDVICP_ENABLE, + DM365_INT_HDVICP_DISABLE, + DM365_INT_IMX1_ENABLE, + DM365_INT_IMX1_DISABLE, + DM365_INT_NSF_ENABLE, + DM365_INT_NSF_DISABLE, + + /* EDMA event muxing */ + DM365_EVT2_ASP_TX, + DM365_EVT3_ASP_RX, + DM365_EVT2_VC_TX, + DM365_EVT3_VC_RX, + DM365_EVT26_MMC0_RX, +}; + +enum da830_index { + DA830_GPIO7_14, + DA830_RTCK, + DA830_GPIO7_15, + DA830_EMU_0, + DA830_EMB_SDCKE, + DA830_EMB_CLK_GLUE, + DA830_EMB_CLK, + DA830_NEMB_CS_0, + DA830_NEMB_CAS, + DA830_NEMB_RAS, + DA830_NEMB_WE, + DA830_EMB_BA_1, + DA830_EMB_BA_0, + DA830_EMB_A_0, + DA830_EMB_A_1, + DA830_EMB_A_2, + DA830_EMB_A_3, + DA830_EMB_A_4, + DA830_EMB_A_5, + DA830_GPIO7_0, + DA830_GPIO7_1, + DA830_GPIO7_2, + DA830_GPIO7_3, + DA830_GPIO7_4, + DA830_GPIO7_5, + DA830_GPIO7_6, + DA830_GPIO7_7, + DA830_EMB_A_6, + DA830_EMB_A_7, + DA830_EMB_A_8, + DA830_EMB_A_9, + DA830_EMB_A_10, + DA830_EMB_A_11, + DA830_EMB_A_12, + DA830_EMB_D_31, + DA830_GPIO7_8, + DA830_GPIO7_9, + DA830_GPIO7_10, + DA830_GPIO7_11, + DA830_GPIO7_12, + DA830_GPIO7_13, + DA830_GPIO3_13, + DA830_EMB_D_30, + DA830_EMB_D_29, + DA830_EMB_D_28, + DA830_EMB_D_27, + DA830_EMB_D_26, + DA830_EMB_D_25, + DA830_EMB_D_24, + DA830_EMB_D_23, + DA830_EMB_D_22, + DA830_EMB_D_21, + DA830_EMB_D_20, + DA830_EMB_D_19, + DA830_EMB_D_18, + DA830_EMB_D_17, + DA830_EMB_D_16, + DA830_NEMB_WE_DQM_3, + DA830_NEMB_WE_DQM_2, + DA830_EMB_D_0, + DA830_EMB_D_1, + DA830_EMB_D_2, + DA830_EMB_D_3, + DA830_EMB_D_4, + DA830_EMB_D_5, + DA830_EMB_D_6, + DA830_GPIO6_0, + DA830_GPIO6_1, + DA830_GPIO6_2, + DA830_GPIO6_3, + DA830_GPIO6_4, + DA830_GPIO6_5, + DA830_GPIO6_6, + DA830_EMB_D_7, + DA830_EMB_D_8, + DA830_EMB_D_9, + DA830_EMB_D_10, + DA830_EMB_D_11, + DA830_EMB_D_12, + DA830_EMB_D_13, + DA830_EMB_D_14, + DA830_GPIO6_7, + DA830_GPIO6_8, + DA830_GPIO6_9, + DA830_GPIO6_10, + DA830_GPIO6_11, + DA830_GPIO6_12, + DA830_GPIO6_13, + DA830_GPIO6_14, + DA830_EMB_D_15, + DA830_NEMB_WE_DQM_1, + DA830_NEMB_WE_DQM_0, + DA830_SPI0_SOMI_0, + DA830_SPI0_SIMO_0, + DA830_SPI0_CLK, + DA830_NSPI0_ENA, + DA830_NSPI0_SCS_0, + DA830_EQEP0I, + DA830_EQEP0S, + DA830_EQEP1I, + DA830_NUART0_CTS, + DA830_NUART0_RTS, + DA830_EQEP0A, + DA830_EQEP0B, + DA830_GPIO6_15, + DA830_GPIO5_14, + DA830_GPIO5_15, + DA830_GPIO5_0, + DA830_GPIO5_1, + DA830_GPIO5_2, + DA830_GPIO5_3, + DA830_GPIO5_4, + DA830_SPI1_SOMI_0, + DA830_SPI1_SIMO_0, + DA830_SPI1_CLK, + DA830_UART0_RXD, + DA830_UART0_TXD, + DA830_AXR1_10, + DA830_AXR1_11, + DA830_NSPI1_ENA, + DA830_I2C1_SCL, + DA830_I2C1_SDA, + DA830_EQEP1S, + DA830_I2C0_SDA, + DA830_I2C0_SCL, + DA830_UART2_RXD, + DA830_TM64P0_IN12, + DA830_TM64P0_OUT12, + DA830_GPIO5_5, + DA830_GPIO5_6, + DA830_GPIO5_7, + DA830_GPIO5_8, + DA830_GPIO5_9, + DA830_GPIO5_10, + DA830_GPIO5_11, + DA830_GPIO5_12, + DA830_NSPI1_SCS_0, + DA830_USB0_DRVVBUS, + DA830_AHCLKX0, + DA830_ACLKX0, + DA830_AFSX0, + DA830_AHCLKR0, + DA830_ACLKR0, + DA830_AFSR0, + DA830_UART2_TXD, + DA830_AHCLKX2, + DA830_ECAP0_APWM0, + DA830_RMII_MHZ_50_CLK, + DA830_ECAP1_APWM1, + DA830_USB_REFCLKIN, + DA830_GPIO5_13, + DA830_GPIO4_15, + DA830_GPIO2_11, + DA830_GPIO2_12, + DA830_GPIO2_13, + DA830_GPIO2_14, + DA830_GPIO2_15, + DA830_GPIO3_12, + DA830_AMUTE0, + DA830_AXR0_0, + DA830_AXR0_1, + DA830_AXR0_2, + DA830_AXR0_3, + DA830_AXR0_4, + DA830_AXR0_5, + DA830_AXR0_6, + DA830_RMII_TXD_0, + DA830_RMII_TXD_1, + DA830_RMII_TXEN, + DA830_RMII_CRS_DV, + DA830_RMII_RXD_0, + DA830_RMII_RXD_1, + DA830_RMII_RXER, + DA830_AFSR2, + DA830_ACLKX2, + DA830_AXR2_3, + DA830_AXR2_2, + DA830_AXR2_1, + DA830_AFSX2, + DA830_ACLKR2, + DA830_NRESETOUT, + DA830_GPIO3_0, + DA830_GPIO3_1, + DA830_GPIO3_2, + DA830_GPIO3_3, + DA830_GPIO3_4, + DA830_GPIO3_5, + DA830_GPIO3_6, + DA830_AXR0_7, + DA830_AXR0_8, + DA830_UART1_RXD, + DA830_UART1_TXD, + DA830_AXR0_11, + DA830_AHCLKX1, + DA830_ACLKX1, + DA830_AFSX1, + DA830_MDIO_CLK, + DA830_MDIO_D, + DA830_AXR0_9, + DA830_AXR0_10, + DA830_EPWM0B, + DA830_EPWM0A, + DA830_EPWMSYNCI, + DA830_AXR2_0, + DA830_EPWMSYNC0, + DA830_GPIO3_7, + DA830_GPIO3_8, + DA830_GPIO3_9, + DA830_GPIO3_10, + DA830_GPIO3_11, + DA830_GPIO3_14, + DA830_GPIO3_15, + DA830_GPIO4_10, + DA830_AHCLKR1, + DA830_ACLKR1, + DA830_AFSR1, + DA830_AMUTE1, + DA830_AXR1_0, + DA830_AXR1_1, + DA830_AXR1_2, + DA830_AXR1_3, + DA830_ECAP2_APWM2, + DA830_EHRPWMGLUETZ, + DA830_EQEP1A, + DA830_GPIO4_11, + DA830_GPIO4_12, + DA830_GPIO4_13, + DA830_GPIO4_14, + DA830_GPIO4_0, + DA830_GPIO4_1, + DA830_GPIO4_2, + DA830_GPIO4_3, + DA830_AXR1_4, + DA830_AXR1_5, + DA830_AXR1_6, + DA830_AXR1_7, + DA830_AXR1_8, + DA830_AXR1_9, + DA830_EMA_D_0, + DA830_EMA_D_1, + DA830_EQEP1B, + DA830_EPWM2B, + DA830_EPWM2A, + DA830_EPWM1B, + DA830_EPWM1A, + DA830_MMCSD_DAT_0, + DA830_MMCSD_DAT_1, + DA830_UHPI_HD_0, + DA830_UHPI_HD_1, + DA830_GPIO4_4, + DA830_GPIO4_5, + DA830_GPIO4_6, + DA830_GPIO4_7, + DA830_GPIO4_8, + DA830_GPIO4_9, + DA830_GPIO0_0, + DA830_GPIO0_1, + DA830_EMA_D_2, + DA830_EMA_D_3, + DA830_EMA_D_4, + DA830_EMA_D_5, + DA830_EMA_D_6, + DA830_EMA_D_7, + DA830_EMA_D_8, + DA830_EMA_D_9, + DA830_MMCSD_DAT_2, + DA830_MMCSD_DAT_3, + DA830_MMCSD_DAT_4, + DA830_MMCSD_DAT_5, + DA830_MMCSD_DAT_6, + DA830_MMCSD_DAT_7, + DA830_UHPI_HD_8, + DA830_UHPI_HD_9, + DA830_UHPI_HD_2, + DA830_UHPI_HD_3, + DA830_UHPI_HD_4, + DA830_UHPI_HD_5, + DA830_UHPI_HD_6, + DA830_UHPI_HD_7, + DA830_LCD_D_8, + DA830_LCD_D_9, + DA830_GPIO0_2, + DA830_GPIO0_3, + DA830_GPIO0_4, + DA830_GPIO0_5, + DA830_GPIO0_6, + DA830_GPIO0_7, + DA830_GPIO0_8, + DA830_GPIO0_9, + DA830_EMA_D_10, + DA830_EMA_D_11, + DA830_EMA_D_12, + DA830_EMA_D_13, + DA830_EMA_D_14, + DA830_EMA_D_15, + DA830_EMA_A_0, + DA830_EMA_A_1, + DA830_UHPI_HD_10, + DA830_UHPI_HD_11, + DA830_UHPI_HD_12, + DA830_UHPI_HD_13, + DA830_UHPI_HD_14, + DA830_UHPI_HD_15, + DA830_LCD_D_7, + DA830_MMCSD_CLK, + DA830_LCD_D_10, + DA830_LCD_D_11, + DA830_LCD_D_12, + DA830_LCD_D_13, + DA830_LCD_D_14, + DA830_LCD_D_15, + DA830_UHPI_HCNTL0, + DA830_GPIO0_10, + DA830_GPIO0_11, + DA830_GPIO0_12, + DA830_GPIO0_13, + DA830_GPIO0_14, + DA830_GPIO0_15, + DA830_GPIO1_0, + DA830_GPIO1_1, + DA830_EMA_A_2, + DA830_EMA_A_3, + DA830_EMA_A_4, + DA830_EMA_A_5, + DA830_EMA_A_6, + DA830_EMA_A_7, + DA830_EMA_A_8, + DA830_EMA_A_9, + DA830_MMCSD_CMD, + DA830_LCD_D_6, + DA830_LCD_D_3, + DA830_LCD_D_2, + DA830_LCD_D_1, + DA830_LCD_D_0, + DA830_LCD_PCLK, + DA830_LCD_HSYNC, + DA830_UHPI_HCNTL1, + DA830_GPIO1_2, + DA830_GPIO1_3, + DA830_GPIO1_4, + DA830_GPIO1_5, + DA830_GPIO1_6, + DA830_GPIO1_7, + DA830_GPIO1_8, + DA830_GPIO1_9, + DA830_EMA_A_10, + DA830_EMA_A_11, + DA830_EMA_A_12, + DA830_EMA_BA_1, + DA830_EMA_BA_0, + DA830_EMA_CLK, + DA830_EMA_SDCKE, + DA830_NEMA_CAS, + DA830_LCD_VSYNC, + DA830_NLCD_AC_ENB_CS, + DA830_LCD_MCLK, + DA830_LCD_D_5, + DA830_LCD_D_4, + DA830_OBSCLK, + DA830_NEMA_CS_4, + DA830_UHPI_HHWIL, + DA830_AHCLKR2, + DA830_GPIO1_10, + DA830_GPIO1_11, + DA830_GPIO1_12, + DA830_GPIO1_13, + DA830_GPIO1_14, + DA830_GPIO1_15, + DA830_GPIO2_0, + DA830_GPIO2_1, + DA830_NEMA_RAS, + DA830_NEMA_WE, + DA830_NEMA_CS_0, + DA830_NEMA_CS_2, + DA830_NEMA_CS_3, + DA830_NEMA_OE, + DA830_NEMA_WE_DQM_1, + DA830_NEMA_WE_DQM_0, + DA830_NEMA_CS_5, + DA830_UHPI_HRNW, + DA830_NUHPI_HAS, + DA830_NUHPI_HCS, + DA830_NUHPI_HDS1, + DA830_NUHPI_HDS2, + DA830_NUHPI_HINT, + DA830_AXR0_12, + DA830_AMUTE2, + DA830_AXR0_13, + DA830_AXR0_14, + DA830_AXR0_15, + DA830_GPIO2_2, + DA830_GPIO2_3, + DA830_GPIO2_4, + DA830_GPIO2_5, + DA830_GPIO2_6, + DA830_GPIO2_7, + DA830_GPIO2_8, + DA830_GPIO2_9, + DA830_EMA_WAIT_0, + DA830_NUHPI_HRDY, + DA830_GPIO2_10, +}; + +enum davinci_da850_index { + /* UART0 function */ + DA850_NUART0_CTS, + DA850_NUART0_RTS, + DA850_UART0_RXD, + DA850_UART0_TXD, + + /* UART1 function */ + DA850_NUART1_CTS, + DA850_NUART1_RTS, + DA850_UART1_RXD, + DA850_UART1_TXD, + + /* UART2 function */ + DA850_NUART2_CTS, + DA850_NUART2_RTS, + DA850_UART2_RXD, + DA850_UART2_TXD, + + /* I2C1 function */ + DA850_I2C1_SCL, + DA850_I2C1_SDA, + + /* I2C0 function */ + DA850_I2C0_SDA, + DA850_I2C0_SCL, + + /* EMAC function */ + DA850_MII_TXEN, + DA850_MII_TXCLK, + DA850_MII_COL, + DA850_MII_TXD_3, + DA850_MII_TXD_2, + DA850_MII_TXD_1, + DA850_MII_TXD_0, + DA850_MII_RXER, + DA850_MII_CRS, + DA850_MII_RXCLK, + DA850_MII_RXDV, + DA850_MII_RXD_3, + DA850_MII_RXD_2, + DA850_MII_RXD_1, + DA850_MII_RXD_0, + DA850_MDIO_CLK, + DA850_MDIO_D, + DA850_RMII_TXD_0, + DA850_RMII_TXD_1, + DA850_RMII_TXEN, + DA850_RMII_CRS_DV, + DA850_RMII_RXD_0, + DA850_RMII_RXD_1, + DA850_RMII_RXER, + DA850_RMII_MHZ_50_CLK, + + /* McASP function */ + DA850_ACLKR, + DA850_ACLKX, + DA850_AFSR, + DA850_AFSX, + DA850_AHCLKR, + DA850_AHCLKX, + DA850_AMUTE, + DA850_AXR_15, + DA850_AXR_14, + DA850_AXR_13, + DA850_AXR_12, + DA850_AXR_11, + DA850_AXR_10, + DA850_AXR_9, + DA850_AXR_8, + DA850_AXR_7, + DA850_AXR_6, + DA850_AXR_5, + DA850_AXR_4, + DA850_AXR_3, + DA850_AXR_2, + DA850_AXR_1, + DA850_AXR_0, + + /* LCD function */ + DA850_LCD_D_7, + DA850_LCD_D_6, + DA850_LCD_D_5, + DA850_LCD_D_4, + DA850_LCD_D_3, + DA850_LCD_D_2, + DA850_LCD_D_1, + DA850_LCD_D_0, + DA850_LCD_D_15, + DA850_LCD_D_14, + DA850_LCD_D_13, + DA850_LCD_D_12, + DA850_LCD_D_11, + DA850_LCD_D_10, + DA850_LCD_D_9, + DA850_LCD_D_8, + DA850_LCD_PCLK, + DA850_LCD_HSYNC, + DA850_LCD_VSYNC, + DA850_NLCD_AC_ENB_CS, + + /* MMC/SD0 function */ + DA850_MMCSD0_DAT_0, + DA850_MMCSD0_DAT_1, + DA850_MMCSD0_DAT_2, + DA850_MMCSD0_DAT_3, + DA850_MMCSD0_CLK, + DA850_MMCSD0_CMD, + + /* MMC/SD1 function */ + DA850_MMCSD1_DAT_0, + DA850_MMCSD1_DAT_1, + DA850_MMCSD1_DAT_2, + DA850_MMCSD1_DAT_3, + DA850_MMCSD1_CLK, + DA850_MMCSD1_CMD, + + /* EMIF2.5/EMIFA function */ + DA850_EMA_D_7, + DA850_EMA_D_6, + DA850_EMA_D_5, + DA850_EMA_D_4, + DA850_EMA_D_3, + DA850_EMA_D_2, + DA850_EMA_D_1, + DA850_EMA_D_0, + DA850_EMA_A_1, + DA850_EMA_A_2, + DA850_NEMA_CS_3, + DA850_NEMA_CS_4, + DA850_NEMA_WE, + DA850_NEMA_OE, + DA850_EMA_D_15, + DA850_EMA_D_14, + DA850_EMA_D_13, + DA850_EMA_D_12, + DA850_EMA_D_11, + DA850_EMA_D_10, + DA850_EMA_D_9, + DA850_EMA_D_8, + DA850_EMA_A_0, + DA850_EMA_A_3, + DA850_EMA_A_4, + DA850_EMA_A_5, + DA850_EMA_A_6, + DA850_EMA_A_7, + DA850_EMA_A_8, + DA850_EMA_A_9, + DA850_EMA_A_10, + DA850_EMA_A_11, + DA850_EMA_A_12, + DA850_EMA_A_13, + DA850_EMA_A_14, + DA850_EMA_A_15, + DA850_EMA_A_16, + DA850_EMA_A_17, + DA850_EMA_A_18, + DA850_EMA_A_19, + DA850_EMA_A_20, + DA850_EMA_A_21, + DA850_EMA_A_22, + DA850_EMA_A_23, + DA850_EMA_BA_1, + DA850_EMA_CLK, + DA850_EMA_WAIT_1, + DA850_NEMA_CS_2, + + /* GPIO function */ + DA850_GPIO2_4, + DA850_GPIO2_6, + DA850_GPIO2_8, + DA850_GPIO2_15, + DA850_GPIO3_12, + DA850_GPIO3_13, + DA850_GPIO4_0, + DA850_GPIO4_1, + DA850_GPIO6_9, + DA850_GPIO6_10, + DA850_GPIO6_13, + DA850_RTC_ALARM, +}; + +enum davinci_tnetv107x_index { + TNETV107X_ASR_A00, + TNETV107X_GPIO32, + TNETV107X_ASR_A01, + TNETV107X_GPIO33, + TNETV107X_ASR_A02, + TNETV107X_GPIO34, + TNETV107X_ASR_A03, + TNETV107X_GPIO35, + TNETV107X_ASR_A04, + TNETV107X_GPIO36, + TNETV107X_ASR_A05, + TNETV107X_GPIO37, + TNETV107X_ASR_A06, + TNETV107X_GPIO38, + TNETV107X_ASR_A07, + TNETV107X_GPIO39, + TNETV107X_ASR_A08, + TNETV107X_GPIO40, + TNETV107X_ASR_A09, + TNETV107X_GPIO41, + TNETV107X_ASR_A10, + TNETV107X_GPIO42, + TNETV107X_ASR_A11, + TNETV107X_BOOT_STRP_0, + TNETV107X_ASR_A12, + TNETV107X_BOOT_STRP_1, + TNETV107X_ASR_A13, + TNETV107X_GPIO43, + TNETV107X_ASR_A14, + TNETV107X_GPIO44, + TNETV107X_ASR_A15, + TNETV107X_GPIO45, + TNETV107X_ASR_A16, + TNETV107X_GPIO46, + TNETV107X_ASR_A17, + TNETV107X_GPIO47, + TNETV107X_ASR_A18, + TNETV107X_GPIO48, + TNETV107X_SDIO1_DATA3_0, + TNETV107X_ASR_A19, + TNETV107X_GPIO49, + TNETV107X_SDIO1_DATA2_0, + TNETV107X_ASR_A20, + TNETV107X_GPIO50, + TNETV107X_SDIO1_DATA1_0, + TNETV107X_ASR_A21, + TNETV107X_GPIO51, + TNETV107X_SDIO1_DATA0_0, + TNETV107X_ASR_A22, + TNETV107X_GPIO52, + TNETV107X_SDIO1_CMD_0, + TNETV107X_ASR_A23, + TNETV107X_GPIO53, + TNETV107X_SDIO1_CLK_0, + TNETV107X_ASR_BA_1, + TNETV107X_GPIO54, + TNETV107X_SYS_PLL_CLK, + TNETV107X_ASR_CS0, + TNETV107X_ASR_CS1, + TNETV107X_ASR_CS2, + TNETV107X_TDM_PLL_CLK, + TNETV107X_ASR_CS3, + TNETV107X_ETH_PHY_CLK, + TNETV107X_ASR_D00, + TNETV107X_GPIO55, + TNETV107X_ASR_D01, + TNETV107X_GPIO56, + TNETV107X_ASR_D02, + TNETV107X_GPIO57, + TNETV107X_ASR_D03, + TNETV107X_GPIO58, + TNETV107X_ASR_D04, + TNETV107X_GPIO59_0, + TNETV107X_ASR_D05, + TNETV107X_GPIO60_0, + TNETV107X_ASR_D06, + TNETV107X_GPIO61_0, + TNETV107X_ASR_D07, + TNETV107X_GPIO62_0, + TNETV107X_ASR_D08, + TNETV107X_GPIO63_0, + TNETV107X_ASR_D09, + TNETV107X_GPIO64_0, + TNETV107X_ASR_D10, + TNETV107X_SDIO1_DATA3_1, + TNETV107X_ASR_D11, + TNETV107X_SDIO1_DATA2_1, + TNETV107X_ASR_D12, + TNETV107X_SDIO1_DATA1_1, + TNETV107X_ASR_D13, + TNETV107X_SDIO1_DATA0_1, + TNETV107X_ASR_D14, + TNETV107X_SDIO1_CMD_1, + TNETV107X_ASR_D15, + TNETV107X_SDIO1_CLK_1, + TNETV107X_ASR_OE, + TNETV107X_BOOT_STRP_2, + TNETV107X_ASR_RNW, + TNETV107X_GPIO29_0, + TNETV107X_ASR_WAIT, + TNETV107X_GPIO30_0, + TNETV107X_ASR_WE, + TNETV107X_BOOT_STRP_3, + TNETV107X_ASR_WE_DQM0, + TNETV107X_GPIO31, + TNETV107X_LCD_PD17_0, + TNETV107X_ASR_WE_DQM1, + TNETV107X_ASR_BA0_0, + TNETV107X_VLYNQ_CLK, + TNETV107X_GPIO14, + TNETV107X_LCD_PD19_0, + TNETV107X_VLYNQ_RXD0, + TNETV107X_GPIO15, + TNETV107X_LCD_PD20_0, + TNETV107X_VLYNQ_RXD1, + TNETV107X_GPIO16, + TNETV107X_LCD_PD21_0, + TNETV107X_VLYNQ_TXD0, + TNETV107X_GPIO17, + TNETV107X_LCD_PD22_0, + TNETV107X_VLYNQ_TXD1, + TNETV107X_GPIO18, + TNETV107X_LCD_PD23_0, + TNETV107X_SDIO0_CLK, + TNETV107X_GPIO19, + TNETV107X_SDIO0_CMD, + TNETV107X_GPIO20, + TNETV107X_SDIO0_DATA0, + TNETV107X_GPIO21, + TNETV107X_SDIO0_DATA1, + TNETV107X_GPIO22, + TNETV107X_SDIO0_DATA2, + TNETV107X_GPIO23, + TNETV107X_SDIO0_DATA3, + TNETV107X_GPIO24, + TNETV107X_EMU0, + TNETV107X_EMU1, + TNETV107X_RTCK, + TNETV107X_TRST_N, + TNETV107X_TCK, + TNETV107X_TDI, + TNETV107X_TDO, + TNETV107X_TMS, + TNETV107X_TDM1_CLK, + TNETV107X_TDM1_RX, + TNETV107X_TDM1_TX, + TNETV107X_TDM1_FS, + TNETV107X_KEYPAD_R0, + TNETV107X_KEYPAD_R1, + TNETV107X_KEYPAD_R2, + TNETV107X_KEYPAD_R3, + TNETV107X_KEYPAD_R4, + TNETV107X_KEYPAD_R5, + TNETV107X_KEYPAD_R6, + TNETV107X_GPIO12, + TNETV107X_KEYPAD_R7, + TNETV107X_GPIO10, + TNETV107X_KEYPAD_C0, + TNETV107X_KEYPAD_C1, + TNETV107X_KEYPAD_C2, + TNETV107X_KEYPAD_C3, + TNETV107X_KEYPAD_C4, + TNETV107X_KEYPAD_C5, + TNETV107X_KEYPAD_C6, + TNETV107X_GPIO13, + TNETV107X_TEST_CLK_IN, + TNETV107X_KEYPAD_C7, + TNETV107X_GPIO11, + TNETV107X_SSP0_0, + TNETV107X_SCC_DCLK, + TNETV107X_LCD_PD20_1, + TNETV107X_SSP0_1, + TNETV107X_SCC_CS_N, + TNETV107X_LCD_PD21_1, + TNETV107X_SSP0_2, + TNETV107X_SCC_D, + TNETV107X_LCD_PD22_1, + TNETV107X_SSP0_3, + TNETV107X_SCC_RESETN, + TNETV107X_LCD_PD23_1, + TNETV107X_SSP1_0, + TNETV107X_GPIO25, + TNETV107X_UART2_CTS, + TNETV107X_SSP1_1, + TNETV107X_GPIO26, + TNETV107X_UART2_RD, + TNETV107X_SSP1_2, + TNETV107X_GPIO27, + TNETV107X_UART2_RTS, + TNETV107X_SSP1_3, + TNETV107X_GPIO28, + TNETV107X_UART2_TD, + TNETV107X_UART0_CTS, + TNETV107X_UART0_RD, + TNETV107X_UART0_RTS, + TNETV107X_UART0_TD, + TNETV107X_UART1_RD, + TNETV107X_UART1_TD, + TNETV107X_LCD_AC_NCS, + TNETV107X_LCD_HSYNC_RNW, + TNETV107X_LCD_VSYNC_A0, + TNETV107X_LCD_MCLK, + TNETV107X_LCD_PD16_0, + TNETV107X_LCD_PCLK_E, + TNETV107X_LCD_PD00, + TNETV107X_LCD_PD01, + TNETV107X_LCD_PD02, + TNETV107X_LCD_PD03, + TNETV107X_LCD_PD04, + TNETV107X_LCD_PD05, + TNETV107X_LCD_PD06, + TNETV107X_LCD_PD07, + TNETV107X_LCD_PD08, + TNETV107X_GPIO59_1, + TNETV107X_LCD_PD09, + TNETV107X_GPIO60_1, + TNETV107X_LCD_PD10, + TNETV107X_ASR_BA0_1, + TNETV107X_GPIO61_1, + TNETV107X_LCD_PD11, + TNETV107X_GPIO62_1, + TNETV107X_LCD_PD12, + TNETV107X_GPIO63_1, + TNETV107X_LCD_PD13, + TNETV107X_GPIO64_1, + TNETV107X_LCD_PD14, + TNETV107X_GPIO29_1, + TNETV107X_LCD_PD15, + TNETV107X_GPIO30_1, + TNETV107X_EINT0, + TNETV107X_GPIO08, + TNETV107X_EINT1, + TNETV107X_GPIO09, + TNETV107X_GPIO00, + TNETV107X_LCD_PD20_2, + TNETV107X_TDM_CLK_IN_2, + TNETV107X_GPIO01, + TNETV107X_LCD_PD21_2, + TNETV107X_24M_CLK_OUT_1, + TNETV107X_GPIO02, + TNETV107X_LCD_PD22_2, + TNETV107X_GPIO03, + TNETV107X_LCD_PD23_2, + TNETV107X_GPIO04, + TNETV107X_LCD_PD16_1, + TNETV107X_USB0_RXERR, + TNETV107X_GPIO05, + TNETV107X_LCD_PD17_1, + TNETV107X_TDM_CLK_IN_1, + TNETV107X_GPIO06, + TNETV107X_LCD_PD18, + TNETV107X_24M_CLK_OUT_2, + TNETV107X_GPIO07, + TNETV107X_LCD_PD19_1, + TNETV107X_USB1_RXERR, + TNETV107X_ETH_PLL_CLK, + TNETV107X_MDIO, + TNETV107X_MDC, + TNETV107X_AIC_MUTE_STAT_N, + TNETV107X_TDM0_CLK, + TNETV107X_AIC_HNS_EN_N, + TNETV107X_TDM0_FS, + TNETV107X_AIC_HDS_EN_STAT_N, + TNETV107X_TDM0_TX, + TNETV107X_AIC_HNF_EN_STAT_N, + TNETV107X_TDM0_RX, +}; + +#define PINMUX(x) (4 * (x)) + +#ifdef CONFIG_DAVINCI_MUX +/* setup pin muxing */ +extern int davinci_cfg_reg(unsigned long reg_cfg); +extern int davinci_cfg_reg_list(const short pins[]); +#else +/* boot loader does it all (no warnings from CONFIG_DAVINCI_MUX_WARNINGS) */ +static inline int davinci_cfg_reg(unsigned long reg_cfg) { return 0; } +static inline int davinci_cfg_reg_list(const short pins[]) +{ + return 0; +} +#endif + +#endif /* __INC_MACH_MUX_H */ diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/nand.h b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/nand.h new file mode 100644 index 00000000..1cf555ae --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/nand.h @@ -0,0 +1,90 @@ +/* + * mach-davinci/nand.h + * + * Copyright © 2006 Texas Instruments. + * + * Ported to 2.6.23 Copyright © 2008 by + * Sander Huijsen <Shuijsen@optelecom-nkf.com> + * Troy Kisky <troy.kisky@boundarydevices.com> + * Dirk Behme <Dirk.Behme@gmail.com> + * + * -------------------------------------------------------------------------- + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __ARCH_ARM_DAVINCI_NAND_H +#define __ARCH_ARM_DAVINCI_NAND_H + +#include <linux/mtd/nand.h> + +#define NANDFCR_OFFSET 0x60 +#define NANDFSR_OFFSET 0x64 +#define NANDF1ECC_OFFSET 0x70 + +/* 4-bit ECC syndrome registers */ +#define NAND_4BIT_ECC_LOAD_OFFSET 0xbc +#define NAND_4BIT_ECC1_OFFSET 0xc0 +#define NAND_4BIT_ECC2_OFFSET 0xc4 +#define NAND_4BIT_ECC3_OFFSET 0xc8 +#define NAND_4BIT_ECC4_OFFSET 0xcc +#define NAND_ERR_ADD1_OFFSET 0xd0 +#define NAND_ERR_ADD2_OFFSET 0xd4 +#define NAND_ERR_ERRVAL1_OFFSET 0xd8 +#define NAND_ERR_ERRVAL2_OFFSET 0xdc + +/* NOTE: boards don't need to use these address bits + * for ALE/CLE unless they support booting from NAND. + * They're used unless platform data overrides them. + */ +#define MASK_ALE 0x08 +#define MASK_CLE 0x10 + +struct davinci_nand_pdata { /* platform_data */ + uint32_t mask_ale; + uint32_t mask_cle; + + /* for packages using two chipselects */ + uint32_t mask_chipsel; + + /* board's default static partition info */ + struct mtd_partition *parts; + unsigned nr_parts; + + /* none == NAND_ECC_NONE (strongly *not* advised!!) + * soft == NAND_ECC_SOFT + * else == NAND_ECC_HW, according to ecc_bits + * + * All DaVinci-family chips support 1-bit hardware ECC. + * Newer ones also support 4-bit ECC, but are awkward + * using it with large page chips. + */ + nand_ecc_modes_t ecc_mode; + u8 ecc_bits; + + /* e.g. NAND_BUSWIDTH_16 */ + unsigned options; + /* e.g. NAND_BBT_USE_FLASH */ + unsigned bbt_options; + + /* Main and mirror bbt descriptor overrides */ + struct nand_bbt_descr *bbt_td; + struct nand_bbt_descr *bbt_md; + + /* Access timings */ + struct davinci_aemif_timing *timing; +}; + +#endif /* __ARCH_ARM_DAVINCI_NAND_H */ diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/pm.h b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/pm.h new file mode 100644 index 00000000..37b19bf3 --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/pm.h @@ -0,0 +1,54 @@ +/* + * TI DaVinci platform support for power management. + * + * Copyright (C) 2009 Texas Instruments, Inc. http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef _MACH_DAVINCI_PM_H +#define _MACH_DAVINCI_PM_H + +/* + * Caution: Assembly code in sleep.S makes assumtion on the order + * of the members of this structure. + */ +struct davinci_pm_config { + void __iomem *ddr2_ctlr_base; + void __iomem *ddrpsc_reg_base; + int ddrpsc_num; + void __iomem *ddrpll_reg_base; + void __iomem *deepsleep_reg; + void __iomem *cpupll_reg_base; + /* + * Note on SLEEPCOUNT: + * The SLEEPCOUNT feature is mainly intended for cases in which + * the internal oscillator is used. The internal oscillator is + * fully disabled in deep sleep mode. When you exist deep sleep + * mode, the oscillator will be turned on and will generate very + * small oscillations which will not be detected by the deep sleep + * counter. Eventually those oscillations will grow to an amplitude + * large enough to start incrementing the deep sleep counter. + * In this case recommendation from hardware engineers is that the + * SLEEPCOUNT be set to 4096. This means that 4096 valid clock cycles + * must be detected before the clock is passed to the rest of the + * system. + * In the case that the internal oscillator is not used and the + * clock is generated externally, the SLEEPCOUNT value can be very + * small since the clock input is assumed to be stable before SoC + * is taken out of deepsleep mode. A value of 128 would be more than + * adequate. + */ + int sleepcount; +}; + +extern unsigned int davinci_cpu_suspend_sz; +extern void davinci_cpu_suspend(struct davinci_pm_config *); + +#endif diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/psc.h b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/psc.h new file mode 100644 index 00000000..8bc3fc25 --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/psc.h @@ -0,0 +1,260 @@ +/* + * DaVinci Power & Sleep Controller (PSC) defines + * + * Copyright (C) 2006 Texas Instruments. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ +#ifndef __ASM_ARCH_PSC_H +#define __ASM_ARCH_PSC_H + +#define DAVINCI_PWR_SLEEP_CNTRL_BASE 0x01C41000 + +/* Power and Sleep Controller (PSC) Domains */ +#define DAVINCI_GPSC_ARMDOMAIN 0 +#define DAVINCI_GPSC_DSPDOMAIN 1 + +#define DAVINCI_LPSC_VPSSMSTR 0 +#define DAVINCI_LPSC_VPSSSLV 1 +#define DAVINCI_LPSC_TPCC 2 +#define DAVINCI_LPSC_TPTC0 3 +#define DAVINCI_LPSC_TPTC1 4 +#define DAVINCI_LPSC_EMAC 5 +#define DAVINCI_LPSC_EMAC_WRAPPER 6 +#define DAVINCI_LPSC_USB 9 +#define DAVINCI_LPSC_ATA 10 +#define DAVINCI_LPSC_VLYNQ 11 +#define DAVINCI_LPSC_UHPI 12 +#define DAVINCI_LPSC_DDR_EMIF 13 +#define DAVINCI_LPSC_AEMIF 14 +#define DAVINCI_LPSC_MMC_SD 15 +#define DAVINCI_LPSC_McBSP 17 +#define DAVINCI_LPSC_I2C 18 +#define DAVINCI_LPSC_UART0 19 +#define DAVINCI_LPSC_UART1 20 +#define DAVINCI_LPSC_UART2 21 +#define DAVINCI_LPSC_SPI 22 +#define DAVINCI_LPSC_PWM0 23 +#define DAVINCI_LPSC_PWM1 24 +#define DAVINCI_LPSC_PWM2 25 +#define DAVINCI_LPSC_GPIO 26 +#define DAVINCI_LPSC_TIMER0 27 +#define DAVINCI_LPSC_TIMER1 28 +#define DAVINCI_LPSC_TIMER2 29 +#define DAVINCI_LPSC_SYSTEM_SUBSYS 30 +#define DAVINCI_LPSC_ARM 31 +#define DAVINCI_LPSC_SCR2 32 +#define DAVINCI_LPSC_SCR3 33 +#define DAVINCI_LPSC_SCR4 34 +#define DAVINCI_LPSC_CROSSBAR 35 +#define DAVINCI_LPSC_CFG27 36 +#define DAVINCI_LPSC_CFG3 37 +#define DAVINCI_LPSC_CFG5 38 +#define DAVINCI_LPSC_GEM 39 +#define DAVINCI_LPSC_IMCOP 40 + +#define DM355_LPSC_TIMER3 5 +#define DM355_LPSC_SPI1 6 +#define DM355_LPSC_MMC_SD1 7 +#define DM355_LPSC_McBSP1 8 +#define DM355_LPSC_PWM3 10 +#define DM355_LPSC_SPI2 11 +#define DM355_LPSC_RTO 12 +#define DM355_LPSC_VPSS_DAC 41 + +/* DM365 */ +#define DM365_LPSC_TIMER3 5 +#define DM365_LPSC_SPI1 6 +#define DM365_LPSC_MMC_SD1 7 +#define DM365_LPSC_McBSP1 8 +#define DM365_LPSC_PWM3 10 +#define DM365_LPSC_SPI2 11 +#define DM365_LPSC_RTO 12 +#define DM365_LPSC_TIMER4 17 +#define DM365_LPSC_SPI0 22 +#define DM365_LPSC_SPI3 38 +#define DM365_LPSC_SPI4 39 +#define DM365_LPSC_EMAC 40 +#define DM365_LPSC_VOICE_CODEC 44 +#define DM365_LPSC_DAC_CLK 46 +#define DM365_LPSC_VPSSMSTR 47 +#define DM365_LPSC_MJCP 50 + +/* + * LPSC Assignments + */ +#define DM646X_LPSC_ARM 0 +#define DM646X_LPSC_C64X_CPU 1 +#define DM646X_LPSC_HDVICP0 2 +#define DM646X_LPSC_HDVICP1 3 +#define DM646X_LPSC_TPCC 4 +#define DM646X_LPSC_TPTC0 5 +#define DM646X_LPSC_TPTC1 6 +#define DM646X_LPSC_TPTC2 7 +#define DM646X_LPSC_TPTC3 8 +#define DM646X_LPSC_PCI 13 +#define DM646X_LPSC_EMAC 14 +#define DM646X_LPSC_VDCE 15 +#define DM646X_LPSC_VPSSMSTR 16 +#define DM646X_LPSC_VPSSSLV 17 +#define DM646X_LPSC_TSIF0 18 +#define DM646X_LPSC_TSIF1 19 +#define DM646X_LPSC_DDR_EMIF 20 +#define DM646X_LPSC_AEMIF 21 +#define DM646X_LPSC_McASP0 22 +#define DM646X_LPSC_McASP1 23 +#define DM646X_LPSC_CRGEN0 24 +#define DM646X_LPSC_CRGEN1 25 +#define DM646X_LPSC_UART0 26 +#define DM646X_LPSC_UART1 27 +#define DM646X_LPSC_UART2 28 +#define DM646X_LPSC_PWM0 29 +#define DM646X_LPSC_PWM1 30 +#define DM646X_LPSC_I2C 31 +#define DM646X_LPSC_SPI 32 +#define DM646X_LPSC_GPIO 33 +#define DM646X_LPSC_TIMER0 34 +#define DM646X_LPSC_TIMER1 35 +#define DM646X_LPSC_ARM_INTC 45 + +/* PSC0 defines */ +#define DA8XX_LPSC0_TPCC 0 +#define DA8XX_LPSC0_TPTC0 1 +#define DA8XX_LPSC0_TPTC1 2 +#define DA8XX_LPSC0_EMIF25 3 +#define DA8XX_LPSC0_SPI0 4 +#define DA8XX_LPSC0_MMC_SD 5 +#define DA8XX_LPSC0_AINTC 6 +#define DA8XX_LPSC0_ARM_RAM_ROM 7 +#define DA8XX_LPSC0_SECU_MGR 8 +#define DA8XX_LPSC0_UART0 9 +#define DA8XX_LPSC0_SCR0_SS 10 +#define DA8XX_LPSC0_SCR1_SS 11 +#define DA8XX_LPSC0_SCR2_SS 12 +#define DA8XX_LPSC0_PRUSS 13 +#define DA8XX_LPSC0_ARM 14 +#define DA8XX_LPSC0_GEM 15 + +/* PSC1 defines */ +#define DA850_LPSC1_TPCC1 0 +#define DA8XX_LPSC1_USB20 1 +#define DA8XX_LPSC1_USB11 2 +#define DA8XX_LPSC1_GPIO 3 +#define DA8XX_LPSC1_UHPI 4 +#define DA8XX_LPSC1_CPGMAC 5 +#define DA8XX_LPSC1_EMIF3C 6 +#define DA8XX_LPSC1_McASP0 7 +#define DA830_LPSC1_McASP1 8 +#define DA850_LPSC1_SATA 8 +#define DA830_LPSC1_McASP2 9 +#define DA8XX_LPSC1_SPI1 10 +#define DA8XX_LPSC1_I2C 11 +#define DA8XX_LPSC1_UART1 12 +#define DA8XX_LPSC1_UART2 13 +#define DA8XX_LPSC1_LCDC 16 +#define DA8XX_LPSC1_PWM 17 +#define DA850_LPSC1_MMC_SD1 18 +#define DA8XX_LPSC1_ECAP 20 +#define DA830_LPSC1_EQEP 21 +#define DA850_LPSC1_TPTC2 21 +#define DA8XX_LPSC1_SCR_P0_SS 24 +#define DA8XX_LPSC1_SCR_P1_SS 25 +#define DA8XX_LPSC1_CR_P3_SS 26 +#define DA8XX_LPSC1_L3_CBA_RAM 31 + +/* TNETV107X LPSC Assignments */ +#define TNETV107X_LPSC_ARM 0 +#define TNETV107X_LPSC_GEM 1 +#define TNETV107X_LPSC_DDR2_PHY 2 +#define TNETV107X_LPSC_TPCC 3 +#define TNETV107X_LPSC_TPTC0 4 +#define TNETV107X_LPSC_TPTC1 5 +#define TNETV107X_LPSC_RAM 6 +#define TNETV107X_LPSC_MBX_LITE 7 +#define TNETV107X_LPSC_LCD 8 +#define TNETV107X_LPSC_ETHSS 9 +#define TNETV107X_LPSC_AEMIF 10 +#define TNETV107X_LPSC_CHIP_CFG 11 +#define TNETV107X_LPSC_TSC 12 +#define TNETV107X_LPSC_ROM 13 +#define TNETV107X_LPSC_UART2 14 +#define TNETV107X_LPSC_PKTSEC 15 +#define TNETV107X_LPSC_SECCTL 16 +#define TNETV107X_LPSC_KEYMGR 17 +#define TNETV107X_LPSC_KEYPAD 18 +#define TNETV107X_LPSC_GPIO 19 +#define TNETV107X_LPSC_MDIO 20 +#define TNETV107X_LPSC_SDIO0 21 +#define TNETV107X_LPSC_UART0 22 +#define TNETV107X_LPSC_UART1 23 +#define TNETV107X_LPSC_TIMER0 24 +#define TNETV107X_LPSC_TIMER1 25 +#define TNETV107X_LPSC_WDT_ARM 26 +#define TNETV107X_LPSC_WDT_DSP 27 +#define TNETV107X_LPSC_SSP 28 +#define TNETV107X_LPSC_TDM0 29 +#define TNETV107X_LPSC_VLYNQ 30 +#define TNETV107X_LPSC_MCDMA 31 +#define TNETV107X_LPSC_USB0 32 +#define TNETV107X_LPSC_TDM1 33 +#define TNETV107X_LPSC_DEBUGSS 34 +#define TNETV107X_LPSC_ETHSS_RGMII 35 +#define TNETV107X_LPSC_SYSTEM 36 +#define TNETV107X_LPSC_IMCOP 37 +#define TNETV107X_LPSC_SPARE 38 +#define TNETV107X_LPSC_SDIO1 39 +#define TNETV107X_LPSC_USB1 40 +#define TNETV107X_LPSC_USBSS 41 +#define TNETV107X_LPSC_DDR2_EMIF1_VRST 42 +#define TNETV107X_LPSC_DDR2_EMIF2_VCTL_RST 43 +#define TNETV107X_LPSC_MAX 44 + +/* PSC register offsets */ +#define EPCPR 0x070 +#define PTCMD 0x120 +#define PTSTAT 0x128 +#define PDSTAT 0x200 +#define PDCTL 0x300 +#define MDSTAT 0x800 +#define MDCTL 0xA00 + +/* PSC module states */ +#define PSC_STATE_SWRSTDISABLE 0 +#define PSC_STATE_SYNCRST 1 +#define PSC_STATE_DISABLE 2 +#define PSC_STATE_ENABLE 3 + +#define MDSTAT_STATE_MASK 0x3f +#define PDSTAT_STATE_MASK 0x1f +#define MDCTL_FORCE BIT(31) +#define PDCTL_NEXT BIT(1) +#define PDCTL_EPCGOOD BIT(8) + +#ifndef __ASSEMBLER__ + +extern int davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id); +extern void davinci_psc_config(unsigned int domain, unsigned int ctlr, + unsigned int id, bool enable, u32 flags); + +#endif + +#endif /* __ASM_ARCH_PSC_H */ diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/serial.h b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/serial.h new file mode 100644 index 00000000..e347d88f --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/serial.h @@ -0,0 +1,58 @@ +/* + * DaVinci serial device definitions + * + * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com> + * + * 2007 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ +#ifndef __ASM_ARCH_SERIAL_H +#define __ASM_ARCH_SERIAL_H + +#include <asm/memory.h> + +#include <mach/hardware.h> + +/* + * Stolen area that contains debug uart physical and virtual addresses. These + * addresses are filled in by the uncompress.h code, and are used by the debug + * macros in debug-macro.S. + * + * This area sits just below the page tables (see arch/arm/kernel/head.S). + * We define it as a relative offset from start of usable RAM. + */ +#define DAVINCI_UART_INFO_OFS 0x3ff8 + +#define DAVINCI_UART0_BASE (IO_PHYS + 0x20000) +#define DAVINCI_UART1_BASE (IO_PHYS + 0x20400) +#define DAVINCI_UART2_BASE (IO_PHYS + 0x20800) + +#define DA8XX_UART0_BASE (IO_PHYS + 0x042000) +#define DA8XX_UART1_BASE (IO_PHYS + 0x10c000) +#define DA8XX_UART2_BASE (IO_PHYS + 0x10d000) + +#define TNETV107X_UART0_BASE 0x08108100 +#define TNETV107X_UART1_BASE 0x08088400 +#define TNETV107X_UART2_BASE 0x08108300 + +#define TNETV107X_UART0_VIRT IOMEM(0xfee08100) +#define TNETV107X_UART1_VIRT IOMEM(0xfed88400) +#define TNETV107X_UART2_VIRT IOMEM(0xfee08300) + +/* DaVinci UART register offsets */ +#define UART_DAVINCI_PWREMU 0x0c +#define UART_DM646X_SCR 0x10 +#define UART_DM646X_SCR_TX_WATERMARK 0x08 + +#ifndef __ASSEMBLY__ +struct davinci_uart_config { + /* Bit field of UARTs present; bit 0 --> UART1 */ + unsigned int enabled_uarts; +}; + +extern int davinci_serial_init(struct davinci_uart_config *); +#endif + +#endif /* __ASM_ARCH_SERIAL_H */ diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/spi.h b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/spi.h new file mode 100644 index 00000000..7af305b3 --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/spi.h @@ -0,0 +1,89 @@ +/* + * Copyright 2009 Texas Instruments. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __ARCH_ARM_DAVINCI_SPI_H +#define __ARCH_ARM_DAVINCI_SPI_H + +#include <mach/edma.h> + +#define SPI_INTERN_CS 0xFF + +enum { + SPI_VERSION_1, /* For DM355/DM365/DM6467 */ + SPI_VERSION_2, /* For DA8xx */ +}; + +/** + * davinci_spi_platform_data - Platform data for SPI master device on DaVinci + * + * @version: version of the SPI IP. Different DaVinci devices have slightly + * varying versions of the same IP. + * @num_chipselect: number of chipselects supported by this SPI master + * @intr_line: interrupt line used to connect the SPI IP to the ARM interrupt + * controller withn the SoC. Possible values are 0 and 1. + * @chip_sel: list of GPIOs which can act as chip-selects for the SPI. + * SPI_INTERN_CS denotes internal SPI chip-select. Not necessary + * to populate if all chip-selects are internal. + * @cshold_bug: set this to true if the SPI controller on your chip requires + * a write to CSHOLD bit in between transfers (like in DM355). + * @dma_event_q: DMA event queue to use if SPI_IO_TYPE_DMA is used for any + * device on the bus. + */ +struct davinci_spi_platform_data { + u8 version; + u8 num_chipselect; + u8 intr_line; + u8 *chip_sel; + bool cshold_bug; + enum dma_event_q dma_event_q; +}; + +/** + * davinci_spi_config - Per-chip-select configuration for SPI slave devices + * + * @wdelay: amount of delay between transmissions. Measured in number of + * SPI module clocks. + * @odd_parity: polarity of parity flag at the end of transmit data stream. + * 0 - odd parity, 1 - even parity. + * @parity_enable: enable transmission of parity at end of each transmit + * data stream. + * @io_type: type of IO transfer. Choose between polled, interrupt and DMA. + * @timer_disable: disable chip-select timers (setup and hold) + * @c2tdelay: chip-select setup time. Measured in number of SPI module clocks. + * @t2cdelay: chip-select hold time. Measured in number of SPI module clocks. + * @t2edelay: transmit data finished to SPI ENAn pin inactive time. Measured + * in number of SPI clocks. + * @c2edelay: chip-select active to SPI ENAn signal active time. Measured in + * number of SPI clocks. + */ +struct davinci_spi_config { + u8 wdelay; + u8 odd_parity; + u8 parity_enable; +#define SPI_IO_TYPE_INTR 0 +#define SPI_IO_TYPE_POLL 1 +#define SPI_IO_TYPE_DMA 2 + u8 io_type; + u8 timer_disable; + u8 c2tdelay; + u8 t2cdelay; + u8 t2edelay; + u8 c2edelay; +}; + +#endif /* __ARCH_ARM_DAVINCI_SPI_H */ diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/sram.h b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/sram.h new file mode 100644 index 00000000..111f7cc7 --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/sram.h @@ -0,0 +1,27 @@ +/* + * mach/sram.h - DaVinci simple SRAM allocator + * + * Copyright (C) 2009 David Brownell + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __MACH_SRAM_H +#define __MACH_SRAM_H + +/* ARBITRARY: SRAM allocations are multiples of this 2^N size */ +#define SRAM_GRANULARITY 512 + +/* + * SRAM allocations return a CPU virtual address, or NULL on error. + * If a DMA address is requested and the SRAM supports DMA, its + * mapped address is also returned. + * + * Errors include SRAM memory not being available, and requesting + * DMA mapped SRAM on systems which don't allow that. + */ +extern void *sram_alloc(size_t len, dma_addr_t *dma); +extern void sram_free(void *addr, size_t len); + +#endif /* __MACH_SRAM_H */ diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/time.h b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/time.h new file mode 100644 index 00000000..1c971d8d --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/time.h @@ -0,0 +1,35 @@ +/* + * Local header file for DaVinci time code. + * + * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com> + * + * 2007 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ +#ifndef __ARCH_ARM_MACH_DAVINCI_TIME_H +#define __ARCH_ARM_MACH_DAVINCI_TIME_H + +#define DAVINCI_TIMER0_BASE (IO_PHYS + 0x21400) +#define DAVINCI_TIMER1_BASE (IO_PHYS + 0x21800) +#define DAVINCI_WDOG_BASE (IO_PHYS + 0x21C00) + +enum { + T0_BOT, + T0_TOP, + T1_BOT, + T1_TOP, + NUM_TIMERS +}; + +#define IS_TIMER1(id) (id & 0x2) +#define IS_TIMER0(id) (!IS_TIMER1(id)) +#define IS_TIMER_TOP(id) ((id & 0x1)) +#define IS_TIMER_BOT(id) (!IS_TIMER_TOP(id)) + +#define ID_TO_TIMER(id) (IS_TIMER1(id) != 0) + +extern struct davinci_timer_instance davinci_timer_instance[]; + +#endif /* __ARCH_ARM_MACH_DAVINCI_TIME_H */ diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/timex.h b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/timex.h new file mode 100644 index 00000000..9b885298 --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/timex.h @@ -0,0 +1,22 @@ +/* + * DaVinci timer defines + * + * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com> + * + * 2007 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ +#ifndef __ASM_ARCH_TIMEX_H +#define __ASM_ARCH_TIMEX_H + +/* + * Alert: Not all timers of the DaVinci family run at a frequency of 27MHz, + * but we should be fine as long as CLOCK_TICK_RATE or LATCH (see include/ + * linux/jiffies.h) are not used directly in code. Currently none of the + * code relevant to DaVinci platform depends on these values directly. + */ +#define CLOCK_TICK_RATE 27000000 + +#endif /* __ASM_ARCH_TIMEX_H__ */ diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/tnetv107x.h b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/tnetv107x.h new file mode 100644 index 00000000..83e5926f --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/tnetv107x.h @@ -0,0 +1,61 @@ +/* + * Texas Instruments TNETV107X SoC Specific Defines + * + * Copyright (C) 2010 Texas Instruments + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __ASM_ARCH_DAVINCI_TNETV107X_H +#define __ASM_ARCH_DAVINCI_TNETV107X_H + +#include <asm/sizes.h> + +#define TNETV107X_DDR_BASE 0x80000000 + +/* + * Fixed mapping for early init starts here. If low-level debug is enabled, + * this area also gets mapped via io_pg_offset and io_phys by the boot code. + * To fit in with the io_pg_offset calculation, the io base address selected + * here _must_ be a multiple of 2^20. + */ +#define TNETV107X_IO_BASE 0x08000000 +#define TNETV107X_IO_VIRT (IO_VIRT + SZ_1M) + +#define TNETV107X_N_GPIO 65 + +#ifndef __ASSEMBLY__ + +#include <linux/serial_8250.h> +#include <linux/input/matrix_keypad.h> +#include <linux/mfd/ti_ssp.h> + +#include <mach/mmc.h> +#include <mach/nand.h> +#include <mach/serial.h> + +struct tnetv107x_device_info { + struct davinci_uart_config *serial_config; + struct davinci_mmc_config *mmc_config[2]; /* 2 controllers */ + struct davinci_nand_pdata *nand_config[4]; /* 4 chipsels */ + struct matrix_keypad_platform_data *keypad_config; + struct ti_ssp_data *ssp_config; +}; + +extern struct platform_device tnetv107x_wdt_device; +extern struct platform_device tnetv107x_serial_device; + +extern void __init tnetv107x_init(void); +extern void __init tnetv107x_devices_init(struct tnetv107x_device_info *); +extern void __init tnetv107x_irq_init(void); +void tnetv107x_restart(char mode, const char *cmd); + +#endif + +#endif /* __ASM_ARCH_DAVINCI_TNETV107X_H */ diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/uncompress.h b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/uncompress.h new file mode 100644 index 00000000..da2fb2c2 --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/uncompress.h @@ -0,0 +1,108 @@ +/* + * Serial port stubs for kernel decompress status messages + * + * Initially based on: + * arch/arm/plat-omap/include/mach/uncompress.h + * + * Original copyrights follow. + * + * Copyright (C) 2000 RidgeRun, Inc. + * Author: Greg Lonnon <glonnon@ridgerun.com> + * + * Rewritten by: + * Author: <source@mvista.com> + * 2004 (c) MontaVista Software, Inc. + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#include <linux/types.h> +#include <linux/serial_reg.h> + +#include <asm/mach-types.h> + +#include <mach/serial.h> + +#define IOMEM(x) ((void __force __iomem *)(x)) + +u32 *uart; + +/* PORT_16C550A, in polled non-fifo mode */ +static void putc(char c) +{ + while (!(uart[UART_LSR] & UART_LSR_THRE)) + barrier(); + uart[UART_TX] = c; +} + +static inline void flush(void) +{ + while (!(uart[UART_LSR] & UART_LSR_THRE)) + barrier(); +} + +static inline void set_uart_info(u32 phys, void * __iomem virt) +{ + /* + * Get address of some.bss variable and round it down + * a la CONFIG_AUTO_ZRELADDR. + */ + u32 ram_start = (u32)&uart & 0xf8000000; + u32 *uart_info = (u32 *)(ram_start + DAVINCI_UART_INFO_OFS); + + uart = (u32 *)phys; + uart_info[0] = phys; + uart_info[1] = (u32)virt; +} + +#define _DEBUG_LL_ENTRY(machine, phys, virt) \ + if (machine_is_##machine()) { \ + set_uart_info(phys, virt); \ + break; \ + } + +#define DEBUG_LL_DAVINCI(machine, port) \ + _DEBUG_LL_ENTRY(machine, DAVINCI_UART##port##_BASE, \ + IO_ADDRESS(DAVINCI_UART##port##_BASE)) + +#define DEBUG_LL_DA8XX(machine, port) \ + _DEBUG_LL_ENTRY(machine, DA8XX_UART##port##_BASE, \ + IO_ADDRESS(DA8XX_UART##port##_BASE)) + +#define DEBUG_LL_TNETV107X(machine, port) \ + _DEBUG_LL_ENTRY(machine, TNETV107X_UART##port##_BASE, \ + TNETV107X_UART##port##_VIRT) + +static inline void __arch_decomp_setup(unsigned long arch_id) +{ + /* + * Initialize the port based on the machine ID from the bootloader. + * Note that we're using macros here instead of switch statement + * as machine_is functions are optimized out for the boards that + * are not selected. + */ + do { + /* Davinci boards */ + DEBUG_LL_DAVINCI(davinci_evm, 0); + DEBUG_LL_DAVINCI(sffsdr, 0); + DEBUG_LL_DAVINCI(neuros_osd2, 0); + DEBUG_LL_DAVINCI(davinci_dm355_evm, 0); + DEBUG_LL_DAVINCI(dm355_leopard, 0); + DEBUG_LL_DAVINCI(davinci_dm6467_evm, 0); + DEBUG_LL_DAVINCI(davinci_dm365_evm, 0); + + /* DA8xx boards */ + DEBUG_LL_DA8XX(davinci_da830_evm, 2); + DEBUG_LL_DA8XX(davinci_da850_evm, 2); + DEBUG_LL_DA8XX(mityomapl138, 1); + DEBUG_LL_DA8XX(omapl138_hawkboard, 2); + + /* TNETV107x boards */ + DEBUG_LL_TNETV107X(tnetv107x, 1); + } while (0); +} + +#define arch_decomp_setup() __arch_decomp_setup(arch_id) +#define arch_decomp_wdog() diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/usb.h b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/usb.h new file mode 100644 index 00000000..e0bc4abe --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/include/mach/usb.h @@ -0,0 +1,59 @@ +/* + * USB related definitions + * + * Copyright (C) 2009 MontaVista Software, Inc. <source@mvista.com> + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#ifndef __ASM_ARCH_USB_H +#define __ASM_ARCH_USB_H + +/* DA8xx CFGCHIP2 (USB 2.0 PHY Control) register bits */ +#define CFGCHIP2_PHYCLKGD (1 << 17) +#define CFGCHIP2_VBUSSENSE (1 << 16) +#define CFGCHIP2_RESET (1 << 15) +#define CFGCHIP2_OTGMODE (3 << 13) +#define CFGCHIP2_NO_OVERRIDE (0 << 13) +#define CFGCHIP2_FORCE_HOST (1 << 13) +#define CFGCHIP2_FORCE_DEVICE (2 << 13) +#define CFGCHIP2_FORCE_HOST_VBUS_LOW (3 << 13) +#define CFGCHIP2_USB1PHYCLKMUX (1 << 12) +#define CFGCHIP2_USB2PHYCLKMUX (1 << 11) +#define CFGCHIP2_PHYPWRDN (1 << 10) +#define CFGCHIP2_OTGPWRDN (1 << 9) +#define CFGCHIP2_DATPOL (1 << 8) +#define CFGCHIP2_USB1SUSPENDM (1 << 7) +#define CFGCHIP2_PHY_PLLON (1 << 6) /* override PLL suspend */ +#define CFGCHIP2_SESENDEN (1 << 5) /* Vsess_end comparator */ +#define CFGCHIP2_VBDTCTEN (1 << 4) /* Vbus comparator */ +#define CFGCHIP2_REFFREQ (0xf << 0) +#define CFGCHIP2_REFFREQ_12MHZ (1 << 0) +#define CFGCHIP2_REFFREQ_24MHZ (2 << 0) +#define CFGCHIP2_REFFREQ_48MHZ (3 << 0) + +struct da8xx_ohci_root_hub; + +typedef void (*da8xx_ocic_handler_t)(struct da8xx_ohci_root_hub *hub, + unsigned port); + +/* Passed as the platform data to the OHCI driver */ +struct da8xx_ohci_root_hub { + /* Switch the port power on/off */ + int (*set_power)(unsigned port, int on); + /* Read the port power status */ + int (*get_power)(unsigned port); + /* Read the port over-current indicator */ + int (*get_oci)(unsigned port); + /* Over-current indicator change notification (pass NULL to disable) */ + int (*ocic_notify)(da8xx_ocic_handler_t handler); + + /* Time from power on to power good (in 2 ms units) */ + u8 potpgt; +}; + +void davinci_setup_usb(unsigned mA, unsigned potpgt_ms); + +#endif /* ifndef __ASM_ARCH_USB_H */ diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/irq.c b/ANDROID_3.4.5/arch/arm/mach-davinci/irq.c new file mode 100644 index 00000000..952dc126 --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/irq.c @@ -0,0 +1,117 @@ +/* + * Interrupt handler for DaVinci boards. + * + * Copyright (C) 2006 Texas Instruments. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/io.h> + +#include <mach/hardware.h> +#include <mach/cputype.h> +#include <mach/common.h> +#include <asm/mach/irq.h> + +#define FIQ_REG0_OFFSET 0x0000 +#define FIQ_REG1_OFFSET 0x0004 +#define IRQ_REG0_OFFSET 0x0008 +#define IRQ_REG1_OFFSET 0x000C +#define IRQ_ENT_REG0_OFFSET 0x0018 +#define IRQ_ENT_REG1_OFFSET 0x001C +#define IRQ_INCTL_REG_OFFSET 0x0020 +#define IRQ_EABASE_REG_OFFSET 0x0024 +#define IRQ_INTPRI0_REG_OFFSET 0x0030 +#define IRQ_INTPRI7_REG_OFFSET 0x004C + +static inline void davinci_irq_writel(unsigned long value, int offset) +{ + __raw_writel(value, davinci_intc_base + offset); +} + +static __init void +davinci_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num) +{ + struct irq_chip_generic *gc; + struct irq_chip_type *ct; + + gc = irq_alloc_generic_chip("AINTC", 1, irq_start, base, handle_edge_irq); + if (!gc) { + pr_err("%s: irq_alloc_generic_chip for IRQ %u failed\n", + __func__, irq_start); + return; + } + + ct = gc->chip_types; + ct->chip.irq_ack = irq_gc_ack_set_bit; + ct->chip.irq_mask = irq_gc_mask_clr_bit; + ct->chip.irq_unmask = irq_gc_mask_set_bit; + + ct->regs.ack = IRQ_REG0_OFFSET; + ct->regs.mask = IRQ_ENT_REG0_OFFSET; + irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE, + IRQ_NOREQUEST | IRQ_NOPROBE, 0); +} + +/* ARM Interrupt Controller Initialization */ +void __init davinci_irq_init(void) +{ + unsigned i, j; + const u8 *davinci_def_priorities = davinci_soc_info.intc_irq_prios; + + davinci_intc_type = DAVINCI_INTC_TYPE_AINTC; + davinci_intc_base = ioremap(davinci_soc_info.intc_base, SZ_4K); + if (WARN_ON(!davinci_intc_base)) + return; + + /* Clear all interrupt requests */ + davinci_irq_writel(~0x0, FIQ_REG0_OFFSET); + davinci_irq_writel(~0x0, FIQ_REG1_OFFSET); + davinci_irq_writel(~0x0, IRQ_REG0_OFFSET); + davinci_irq_writel(~0x0, IRQ_REG1_OFFSET); + + /* Disable all interrupts */ + davinci_irq_writel(0x0, IRQ_ENT_REG0_OFFSET); + davinci_irq_writel(0x0, IRQ_ENT_REG1_OFFSET); + + /* Interrupts disabled immediately, IRQ entry reflects all */ + davinci_irq_writel(0x0, IRQ_INCTL_REG_OFFSET); + + /* we don't use the hardware vector table, just its entry addresses */ + davinci_irq_writel(0, IRQ_EABASE_REG_OFFSET); + + /* Clear all interrupt requests */ + davinci_irq_writel(~0x0, FIQ_REG0_OFFSET); + davinci_irq_writel(~0x0, FIQ_REG1_OFFSET); + davinci_irq_writel(~0x0, IRQ_REG0_OFFSET); + davinci_irq_writel(~0x0, IRQ_REG1_OFFSET); + + for (i = IRQ_INTPRI0_REG_OFFSET; i <= IRQ_INTPRI7_REG_OFFSET; i += 4) { + u32 pri; + + for (j = 0, pri = 0; j < 32; j += 4, davinci_def_priorities++) + pri |= (*davinci_def_priorities & 0x07) << j; + davinci_irq_writel(pri, i); + } + + for (i = 0, j = 0; i < davinci_soc_info.intc_irq_num; i += 32, j += 0x04) + davinci_alloc_gc(davinci_intc_base + j, i, 32); + + irq_set_handler(IRQ_TINT1_TINT34, handle_level_irq); +} diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/mux.c b/ANDROID_3.4.5/arch/arm/mach-davinci/mux.c new file mode 100644 index 00000000..f34a8dcd --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/mux.c @@ -0,0 +1,113 @@ +/* + * Utility to set the DAVINCI MUX register from a table in mux.h + * + * Author: Vladimir Barinov, MontaVista Software, Inc. <source@mvista.com> + * + * Based on linux/arch/arm/plat-omap/mux.c: + * Copyright (C) 2003 - 2005 Nokia Corporation + * + * Written by Tony Lindgren + * + * 2007 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + * + * Copyright (C) 2008 Texas Instruments. + */ +#include <linux/io.h> +#include <linux/module.h> +#include <linux/spinlock.h> + +#include <mach/mux.h> +#include <mach/common.h> + +static void __iomem *pinmux_base; + +/* + * Sets the DAVINCI MUX register based on the table + */ +int __init_or_module davinci_cfg_reg(const unsigned long index) +{ + static DEFINE_SPINLOCK(mux_spin_lock); + struct davinci_soc_info *soc_info = &davinci_soc_info; + unsigned long flags; + const struct mux_config *cfg; + unsigned int reg_orig = 0, reg = 0; + unsigned int mask, warn = 0; + + if (WARN_ON(!soc_info->pinmux_pins)) + return -ENODEV; + + if (!pinmux_base) { + pinmux_base = ioremap(soc_info->pinmux_base, SZ_4K); + if (WARN_ON(!pinmux_base)) + return -ENOMEM; + } + + if (index >= soc_info->pinmux_pins_num) { + printk(KERN_ERR "Invalid pin mux index: %lu (%lu)\n", + index, soc_info->pinmux_pins_num); + dump_stack(); + return -ENODEV; + } + + cfg = &soc_info->pinmux_pins[index]; + + if (cfg->name == NULL) { + printk(KERN_ERR "No entry for the specified index\n"); + return -ENODEV; + } + + /* Update the mux register in question */ + if (cfg->mask) { + unsigned tmp1, tmp2; + + spin_lock_irqsave(&mux_spin_lock, flags); + reg_orig = __raw_readl(pinmux_base + cfg->mux_reg); + + mask = (cfg->mask << cfg->mask_offset); + tmp1 = reg_orig & mask; + reg = reg_orig & ~mask; + + tmp2 = (cfg->mode << cfg->mask_offset); + reg |= tmp2; + + if (tmp1 != tmp2) + warn = 1; + + __raw_writel(reg, pinmux_base + cfg->mux_reg); + spin_unlock_irqrestore(&mux_spin_lock, flags); + } + + if (warn) { +#ifdef CONFIG_DAVINCI_MUX_WARNINGS + printk(KERN_WARNING "MUX: initialized %s\n", cfg->name); +#endif + } + +#ifdef CONFIG_DAVINCI_MUX_DEBUG + if (cfg->debug || warn) { + printk(KERN_WARNING "MUX: Setting register %s\n", cfg->name); + printk(KERN_WARNING " %s (0x%08x) = 0x%08x -> 0x%08x\n", + cfg->mux_reg_name, cfg->mux_reg, reg_orig, reg); + } +#endif + + return 0; +} +EXPORT_SYMBOL(davinci_cfg_reg); + +int __init_or_module davinci_cfg_reg_list(const short pins[]) +{ + int i, error = -EINVAL; + + if (pins) + for (i = 0; pins[i] >= 0; i++) { + error = davinci_cfg_reg(pins[i]); + if (error) + break; + } + + return error; +} diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/mux.h b/ANDROID_3.4.5/arch/arm/mach-davinci/mux.h new file mode 100644 index 00000000..5aad1e7d --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/mux.h @@ -0,0 +1,51 @@ +/* + * Pin-multiplex helper macros for TI DaVinci family devices + * + * Author: Vladimir Barinov, MontaVista Software, Inc. <source@mvista.com> + * + * 2007 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + * + * Copyright (C) 2008 Texas Instruments. + */ +#ifndef _MACH_DAVINCI_MUX_H_ +#define _MACH_DAVINCI_MUX_H_ + +#include <mach/mux.h> + +#define MUX_CFG(soc, desc, muxreg, mode_offset, mode_mask, mux_mode, dbg)\ +[soc##_##desc] = { \ + .name = #desc, \ + .debug = dbg, \ + .mux_reg_name = "PINMUX"#muxreg, \ + .mux_reg = PINMUX(muxreg), \ + .mask_offset = mode_offset, \ + .mask = mode_mask, \ + .mode = mux_mode, \ + }, + +#define INT_CFG(soc, desc, mode_offset, mode_mask, mux_mode, dbg) \ +[soc##_##desc] = { \ + .name = #desc, \ + .debug = dbg, \ + .mux_reg_name = "INTMUX", \ + .mux_reg = INTMUX, \ + .mask_offset = mode_offset, \ + .mask = mode_mask, \ + .mode = mux_mode, \ + }, + +#define EVT_CFG(soc, desc, mode_offset, mode_mask, mux_mode, dbg) \ +[soc##_##desc] = { \ + .name = #desc, \ + .debug = dbg, \ + .mux_reg_name = "EVTMUX", \ + .mux_reg = EVTMUX, \ + .mask_offset = mode_offset, \ + .mask = mode_mask, \ + .mode = mux_mode, \ + }, + +#endif /* _MACH_DAVINCI_MUX_H */ diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/pm.c b/ANDROID_3.4.5/arch/arm/mach-davinci/pm.c new file mode 100644 index 00000000..04c49f75 --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/pm.c @@ -0,0 +1,159 @@ +/* + * DaVinci Power Management Routines + * + * Copyright (C) 2009 Texas Instruments, Inc. http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/pm.h> +#include <linux/suspend.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/clk.h> +#include <linux/spinlock.h> + +#include <asm/cacheflush.h> +#include <asm/delay.h> +#include <asm/io.h> + +#include <mach/da8xx.h> +#include <mach/sram.h> +#include <mach/pm.h> + +#include "clock.h" + +#define DEEPSLEEP_SLEEPCOUNT_MASK 0xFFFF + +static void (*davinci_sram_suspend) (struct davinci_pm_config *); +static struct davinci_pm_config *pdata; + +static void davinci_sram_push(void *dest, void *src, unsigned int size) +{ + memcpy(dest, src, size); + flush_icache_range((unsigned long)dest, (unsigned long)(dest + size)); +} + +static void davinci_pm_suspend(void) +{ + unsigned val; + + if (pdata->cpupll_reg_base != pdata->ddrpll_reg_base) { + + /* Switch CPU PLL to bypass mode */ + val = __raw_readl(pdata->cpupll_reg_base + PLLCTL); + val &= ~(PLLCTL_PLLENSRC | PLLCTL_PLLEN); + __raw_writel(val, pdata->cpupll_reg_base + PLLCTL); + + udelay(PLL_BYPASS_TIME); + + /* Powerdown CPU PLL */ + val = __raw_readl(pdata->cpupll_reg_base + PLLCTL); + val |= PLLCTL_PLLPWRDN; + __raw_writel(val, pdata->cpupll_reg_base + PLLCTL); + } + + /* Configure sleep count in deep sleep register */ + val = __raw_readl(pdata->deepsleep_reg); + val &= ~DEEPSLEEP_SLEEPCOUNT_MASK, + val |= pdata->sleepcount; + __raw_writel(val, pdata->deepsleep_reg); + + /* System goes to sleep in this call */ + davinci_sram_suspend(pdata); + + if (pdata->cpupll_reg_base != pdata->ddrpll_reg_base) { + + /* put CPU PLL in reset */ + val = __raw_readl(pdata->cpupll_reg_base + PLLCTL); + val &= ~PLLCTL_PLLRST; + __raw_writel(val, pdata->cpupll_reg_base + PLLCTL); + + /* put CPU PLL in power down */ + val = __raw_readl(pdata->cpupll_reg_base + PLLCTL); + val &= ~PLLCTL_PLLPWRDN; + __raw_writel(val, pdata->cpupll_reg_base + PLLCTL); + + /* wait for CPU PLL reset */ + udelay(PLL_RESET_TIME); + + /* bring CPU PLL out of reset */ + val = __raw_readl(pdata->cpupll_reg_base + PLLCTL); + val |= PLLCTL_PLLRST; + __raw_writel(val, pdata->cpupll_reg_base + PLLCTL); + + /* Wait for CPU PLL to lock */ + udelay(PLL_LOCK_TIME); + + /* Remove CPU PLL from bypass mode */ + val = __raw_readl(pdata->cpupll_reg_base + PLLCTL); + val &= ~PLLCTL_PLLENSRC; + val |= PLLCTL_PLLEN; + __raw_writel(val, pdata->cpupll_reg_base + PLLCTL); + } +} + +static int davinci_pm_enter(suspend_state_t state) +{ + int ret = 0; + + switch (state) { + case PM_SUSPEND_STANDBY: + case PM_SUSPEND_MEM: + davinci_pm_suspend(); + break; + default: + ret = -EINVAL; + } + + return ret; +} + +static const struct platform_suspend_ops davinci_pm_ops = { + .enter = davinci_pm_enter, + .valid = suspend_valid_only_mem, +}; + +static int __init davinci_pm_probe(struct platform_device *pdev) +{ + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "cannot get platform data\n"); + return -ENOENT; + } + + davinci_sram_suspend = sram_alloc(davinci_cpu_suspend_sz, NULL); + if (!davinci_sram_suspend) { + dev_err(&pdev->dev, "cannot allocate SRAM memory\n"); + return -ENOMEM; + } + + davinci_sram_push(davinci_sram_suspend, davinci_cpu_suspend, + davinci_cpu_suspend_sz); + + suspend_set_ops(&davinci_pm_ops); + + return 0; +} + +static int __exit davinci_pm_remove(struct platform_device *pdev) +{ + sram_free(davinci_sram_suspend, davinci_cpu_suspend_sz); + return 0; +} + +static struct platform_driver davinci_pm_driver = { + .driver = { + .name = "pm-davinci", + .owner = THIS_MODULE, + }, + .remove = __exit_p(davinci_pm_remove), +}; + +static int __init davinci_pm_init(void) +{ + return platform_driver_probe(&davinci_pm_driver, davinci_pm_probe); +} +late_initcall(davinci_pm_init); diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/psc.c b/ANDROID_3.4.5/arch/arm/mach-davinci/psc.c new file mode 100644 index 00000000..d7e210f4 --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/psc.c @@ -0,0 +1,112 @@ +/* + * TI DaVinci Power and Sleep Controller (PSC) + * + * Copyright (C) 2006 Texas Instruments. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/io.h> + +#include <mach/cputype.h> +#include <mach/psc.h> + +#include "clock.h" + +/* Return nonzero iff the domain's clock is active */ +int __init davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id) +{ + void __iomem *psc_base; + u32 mdstat; + struct davinci_soc_info *soc_info = &davinci_soc_info; + + if (!soc_info->psc_bases || (ctlr >= soc_info->psc_bases_num)) { + pr_warning("PSC: Bad psc data: 0x%x[%d]\n", + (int)soc_info->psc_bases, ctlr); + return 0; + } + + psc_base = ioremap(soc_info->psc_bases[ctlr], SZ_4K); + mdstat = __raw_readl(psc_base + MDSTAT + 4 * id); + iounmap(psc_base); + + /* if clocked, state can be "Enable" or "SyncReset" */ + return mdstat & BIT(12); +} + +/* Enable or disable a PSC domain */ +void davinci_psc_config(unsigned int domain, unsigned int ctlr, + unsigned int id, bool enable, u32 flags) +{ + u32 epcpr, ptcmd, ptstat, pdstat, pdctl, mdstat, mdctl; + void __iomem *psc_base; + struct davinci_soc_info *soc_info = &davinci_soc_info; + u32 next_state = PSC_STATE_ENABLE; + + if (!soc_info->psc_bases || (ctlr >= soc_info->psc_bases_num)) { + pr_warning("PSC: Bad psc data: 0x%x[%d]\n", + (int)soc_info->psc_bases, ctlr); + return; + } + + psc_base = ioremap(soc_info->psc_bases[ctlr], SZ_4K); + + if (!enable) { + if (flags & PSC_SWRSTDISABLE) + next_state = PSC_STATE_SWRSTDISABLE; + else + next_state = PSC_STATE_DISABLE; + } + + mdctl = __raw_readl(psc_base + MDCTL + 4 * id); + mdctl &= ~MDSTAT_STATE_MASK; + mdctl |= next_state; + if (flags & PSC_FORCE) + mdctl |= MDCTL_FORCE; + __raw_writel(mdctl, psc_base + MDCTL + 4 * id); + + pdstat = __raw_readl(psc_base + PDSTAT + 4 * domain); + if ((pdstat & PDSTAT_STATE_MASK) == 0) { + pdctl = __raw_readl(psc_base + PDCTL + 4 * domain); + pdctl |= PDCTL_NEXT; + __raw_writel(pdctl, psc_base + PDCTL + 4 * domain); + + ptcmd = 1 << domain; + __raw_writel(ptcmd, psc_base + PTCMD); + + do { + epcpr = __raw_readl(psc_base + EPCPR); + } while ((((epcpr >> domain) & 1) == 0)); + + pdctl = __raw_readl(psc_base + PDCTL + 4 * domain); + pdctl |= PDCTL_EPCGOOD; + __raw_writel(pdctl, psc_base + PDCTL + 4 * domain); + } else { + ptcmd = 1 << domain; + __raw_writel(ptcmd, psc_base + PTCMD); + } + + do { + ptstat = __raw_readl(psc_base + PTSTAT); + } while (!(((ptstat >> domain) & 1) == 0)); + + do { + mdstat = __raw_readl(psc_base + MDSTAT + 4 * id); + } while (!((mdstat & MDSTAT_STATE_MASK) == next_state)); + + iounmap(psc_base); +} diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/serial.c b/ANDROID_3.4.5/arch/arm/mach-davinci/serial.c new file mode 100644 index 00000000..1875740f --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/serial.c @@ -0,0 +1,115 @@ +/* + * TI DaVinci serial driver + * + * Copyright (C) 2006 Texas Instruments. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/serial_8250.h> +#include <linux/serial_reg.h> +#include <linux/platform_device.h> +#include <linux/delay.h> +#include <linux/clk.h> +#include <linux/io.h> + +#include <mach/serial.h> +#include <mach/cputype.h> + +static inline unsigned int serial_read_reg(struct plat_serial8250_port *up, + int offset) +{ + offset <<= up->regshift; + + WARN_ONCE(!up->membase, "unmapped read: uart[%d]\n", offset); + + return (unsigned int)__raw_readl(up->membase + offset); +} + +static inline void serial_write_reg(struct plat_serial8250_port *p, int offset, + int value) +{ + offset <<= p->regshift; + + WARN_ONCE(!p->membase, "unmapped write: uart[%d]\n", offset); + + __raw_writel(value, p->membase + offset); +} + +static void __init davinci_serial_reset(struct plat_serial8250_port *p) +{ + unsigned int pwremu = 0; + + serial_write_reg(p, UART_IER, 0); /* disable all interrupts */ + + /* reset both transmitter and receiver: bits 14,13 = UTRST, URRST */ + serial_write_reg(p, UART_DAVINCI_PWREMU, pwremu); + mdelay(10); + + pwremu |= (0x3 << 13); + pwremu |= 0x1; + serial_write_reg(p, UART_DAVINCI_PWREMU, pwremu); + + if (cpu_is_davinci_dm646x()) + serial_write_reg(p, UART_DM646X_SCR, + UART_DM646X_SCR_TX_WATERMARK); +} + +int __init davinci_serial_init(struct davinci_uart_config *info) +{ + int i; + char name[16]; + struct clk *uart_clk; + struct davinci_soc_info *soc_info = &davinci_soc_info; + struct device *dev = &soc_info->serial_dev->dev; + struct plat_serial8250_port *p = dev->platform_data; + + /* + * Make sure the serial ports are muxed on at this point. + * You have to mux them off in device drivers later on if not needed. + */ + for (i = 0; p->flags; i++, p++) { + if (!(info->enabled_uarts & (1 << i))) + continue; + + sprintf(name, "uart%d", i); + uart_clk = clk_get(dev, name); + if (IS_ERR(uart_clk)) { + printk(KERN_ERR "%s:%d: failed to get UART%d clock\n", + __func__, __LINE__, i); + continue; + } + + clk_enable(uart_clk); + p->uartclk = clk_get_rate(uart_clk); + + if (!p->membase && p->mapbase) { + p->membase = ioremap(p->mapbase, SZ_4K); + + if (p->membase) + p->flags &= ~UPF_IOREMAP; + else + pr_err("uart regs ioremap failed\n"); + } + + if (p->membase && p->type != PORT_AR7) + davinci_serial_reset(p); + } + + return platform_device_register(soc_info->serial_dev); +} diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/sleep.S b/ANDROID_3.4.5/arch/arm/mach-davinci/sleep.S new file mode 100644 index 00000000..d4e9316e --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/sleep.S @@ -0,0 +1,228 @@ +/* + * (C) Copyright 2009, Texas Instruments, Inc. http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* replicated define because linux/bitops.h cannot be included in assembly */ +#define BIT(nr) (1 << (nr)) + +#include <linux/linkage.h> +#include <asm/assembler.h> +#include <mach/psc.h> +#include <mach/ddr2.h> + +#include "clock.h" + +/* Arbitrary, hardware currently does not update PHYRDY correctly */ +#define PHYRDY_CYCLES 0x1000 + +/* Assume 25 MHz speed for the cycle conversions since PLLs are bypassed */ +#define PLL_BYPASS_CYCLES (PLL_BYPASS_TIME * 25) +#define PLL_RESET_CYCLES (PLL_RESET_TIME * 25) +#define PLL_LOCK_CYCLES (PLL_LOCK_TIME * 25) + +#define DEEPSLEEP_SLEEPENABLE_BIT BIT(31) + + .text +/* + * Move DaVinci into deep sleep state + * + * Note: This code is copied to internal SRAM by PM code. When the DaVinci + * wakes up it continues execution at the point it went to sleep. + * Register Usage: + * r0: contains virtual base for DDR2 controller + * r1: contains virtual base for DDR2 Power and Sleep controller (PSC) + * r2: contains PSC number for DDR2 + * r3: contains virtual base DDR2 PLL controller + * r4: contains virtual address of the DEEPSLEEP register + */ +ENTRY(davinci_cpu_suspend) + stmfd sp!, {r0-r12, lr} @ save registers on stack + + ldr ip, CACHE_FLUSH + blx ip + + ldmia r0, {r0-r4} + + /* + * Switch DDR to self-refresh mode. + */ + + /* calculate SDRCR address */ + ldr ip, [r0, #DDR2_SDRCR_OFFSET] + bic ip, ip, #DDR2_SRPD_BIT + orr ip, ip, #DDR2_LPMODEN_BIT + str ip, [r0, #DDR2_SDRCR_OFFSET] + + ldr ip, [r0, #DDR2_SDRCR_OFFSET] + orr ip, ip, #DDR2_MCLKSTOPEN_BIT + str ip, [r0, #DDR2_SDRCR_OFFSET] + + mov ip, #PHYRDY_CYCLES +1: subs ip, ip, #0x1 + bne 1b + + /* Disable DDR2 LPSC */ + mov r7, r0 + mov r0, #0x2 + bl davinci_ddr_psc_config + mov r0, r7 + + /* Disable clock to DDR PHY */ + ldr ip, [r3, #PLLDIV1] + bic ip, ip, #PLLDIV_EN + str ip, [r3, #PLLDIV1] + + /* Put the DDR PLL in bypass and power down */ + ldr ip, [r3, #PLLCTL] + bic ip, ip, #PLLCTL_PLLENSRC + bic ip, ip, #PLLCTL_PLLEN + str ip, [r3, #PLLCTL] + + /* Wait for PLL to switch to bypass */ + mov ip, #PLL_BYPASS_CYCLES +2: subs ip, ip, #0x1 + bne 2b + + /* Power down the PLL */ + ldr ip, [r3, #PLLCTL] + orr ip, ip, #PLLCTL_PLLPWRDN + str ip, [r3, #PLLCTL] + + /* Go to deep sleep */ + ldr ip, [r4] + orr ip, ip, #DEEPSLEEP_SLEEPENABLE_BIT + /* System goes to sleep beyond after this instruction */ + str ip, [r4] + + /* Wake up from sleep */ + + /* Clear sleep enable */ + ldr ip, [r4] + bic ip, ip, #DEEPSLEEP_SLEEPENABLE_BIT + str ip, [r4] + + /* initialize the DDR PLL controller */ + + /* Put PLL in reset */ + ldr ip, [r3, #PLLCTL] + bic ip, ip, #PLLCTL_PLLRST + str ip, [r3, #PLLCTL] + + /* Clear PLL power down */ + ldr ip, [r3, #PLLCTL] + bic ip, ip, #PLLCTL_PLLPWRDN + str ip, [r3, #PLLCTL] + + mov ip, #PLL_RESET_CYCLES +3: subs ip, ip, #0x1 + bne 3b + + /* Bring PLL out of reset */ + ldr ip, [r3, #PLLCTL] + orr ip, ip, #PLLCTL_PLLRST + str ip, [r3, #PLLCTL] + + /* Wait for PLL to lock (assume prediv = 1, 25MHz OSCIN) */ + mov ip, #PLL_LOCK_CYCLES +4: subs ip, ip, #0x1 + bne 4b + + /* Remove PLL from bypass mode */ + ldr ip, [r3, #PLLCTL] + bic ip, ip, #PLLCTL_PLLENSRC + orr ip, ip, #PLLCTL_PLLEN + str ip, [r3, #PLLCTL] + + /* Start 2x clock to DDR2 */ + + ldr ip, [r3, #PLLDIV1] + orr ip, ip, #PLLDIV_EN + str ip, [r3, #PLLDIV1] + + /* Enable VCLK */ + + /* Enable DDR2 LPSC */ + mov r7, r0 + mov r0, #0x3 + bl davinci_ddr_psc_config + mov r0, r7 + + /* clear MCLKSTOPEN */ + + ldr ip, [r0, #DDR2_SDRCR_OFFSET] + bic ip, ip, #DDR2_MCLKSTOPEN_BIT + str ip, [r0, #DDR2_SDRCR_OFFSET] + + ldr ip, [r0, #DDR2_SDRCR_OFFSET] + bic ip, ip, #DDR2_LPMODEN_BIT + str ip, [r0, #DDR2_SDRCR_OFFSET] + + /* Restore registers and return */ + ldmfd sp!, {r0-r12, pc} + +ENDPROC(davinci_cpu_suspend) + +/* + * Disables or Enables DDR2 LPSC + * Register Usage: + * r0: Enable or Disable LPSC r0 = 0x3 => Enable, r0 = 0x2 => Disable LPSC + * r1: contains virtual base for DDR2 Power and Sleep controller (PSC) + * r2: contains PSC number for DDR2 + */ +ENTRY(davinci_ddr_psc_config) + /* Set next state in mdctl for DDR2 */ + mov r6, #MDCTL + add r6, r6, r2, lsl #2 + ldr ip, [r1, r6] + bic ip, ip, #MDSTAT_STATE_MASK + orr ip, ip, r0 + str ip, [r1, r6] + + /* Enable the Power Domain Transition Command */ + ldr ip, [r1, #PTCMD] + orr ip, ip, #0x1 + str ip, [r1, #PTCMD] + + /* Check for Transition Complete (PTSTAT) */ +ptstat_done: + ldr ip, [r1, #PTSTAT] + and ip, ip, #0x1 + cmp ip, #0x0 + bne ptstat_done + + /* Check for DDR2 clock disable completion; */ + mov r6, #MDSTAT + add r6, r6, r2, lsl #2 +ddr2clk_stop_done: + ldr ip, [r1, r6] + and ip, ip, #MDSTAT_STATE_MASK + cmp ip, r0 + bne ddr2clk_stop_done + + mov pc, lr +ENDPROC(davinci_ddr_psc_config) + +CACHE_FLUSH: +#ifdef CONFIG_CPU_V6 + .word v6_flush_kern_cache_all +#else + .word arm926_flush_kern_cache_all +#endif + +ENTRY(davinci_cpu_suspend_sz) + .word . - davinci_cpu_suspend +ENDPROC(davinci_cpu_suspend_sz) diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/sram.c b/ANDROID_3.4.5/arch/arm/mach-davinci/sram.c new file mode 100644 index 00000000..db0f7787 --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/sram.c @@ -0,0 +1,71 @@ +/* + * mach-davinci/sram.c - DaVinci simple SRAM allocator + * + * Copyright (C) 2009 David Brownell + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#include <linux/module.h> +#include <linux/init.h> +#include <linux/genalloc.h> + +#include <mach/common.h> +#include <mach/sram.h> + +static struct gen_pool *sram_pool; + +void *sram_alloc(size_t len, dma_addr_t *dma) +{ + unsigned long vaddr; + dma_addr_t dma_base = davinci_soc_info.sram_dma; + + if (dma) + *dma = 0; + if (!sram_pool || (dma && !dma_base)) + return NULL; + + vaddr = gen_pool_alloc(sram_pool, len); + if (!vaddr) + return NULL; + + if (dma) + *dma = dma_base + (vaddr - SRAM_VIRT); + return (void *)vaddr; + +} +EXPORT_SYMBOL(sram_alloc); + +void sram_free(void *addr, size_t len) +{ + gen_pool_free(sram_pool, (unsigned long) addr, len); +} +EXPORT_SYMBOL(sram_free); + + +/* + * REVISIT This supports CPU and DMA access to/from SRAM, but it + * doesn't (yet?) support some other notable uses of SRAM: as TCM + * for data and/or instructions; and holding code needed to enter + * and exit suspend states (while DRAM can't be used). + */ +static int __init sram_init(void) +{ + unsigned len = davinci_soc_info.sram_len; + int status = 0; + + if (len) { + len = min_t(unsigned, len, SRAM_SIZE); + sram_pool = gen_pool_create(ilog2(SRAM_GRANULARITY), -1); + if (!sram_pool) + status = -ENOMEM; + } + if (sram_pool) + status = gen_pool_add(sram_pool, SRAM_VIRT, len, -1); + WARN_ON(status < 0); + return status; +} +core_initcall(sram_init); + diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/time.c b/ANDROID_3.4.5/arch/arm/mach-davinci/time.c new file mode 100644 index 00000000..75da315b --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/time.c @@ -0,0 +1,466 @@ +/* + * DaVinci timer subsystem + * + * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com> + * + * 2007 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/clocksource.h> +#include <linux/clockchips.h> +#include <linux/io.h> +#include <linux/clk.h> +#include <linux/err.h> +#include <linux/platform_device.h> + +#include <asm/sched_clock.h> +#include <asm/mach/irq.h> +#include <asm/mach/time.h> + +#include <mach/cputype.h> +#include <mach/hardware.h> +#include <mach/time.h> + +#include "clock.h" + +static struct clock_event_device clockevent_davinci; +static unsigned int davinci_clock_tick_rate; + +/* + * This driver configures the 2 64-bit count-up timers as 4 independent + * 32-bit count-up timers used as follows: + */ + +enum { + TID_CLOCKEVENT, + TID_CLOCKSOURCE, +}; + +/* Timer register offsets */ +#define PID12 0x0 +#define TIM12 0x10 +#define TIM34 0x14 +#define PRD12 0x18 +#define PRD34 0x1c +#define TCR 0x20 +#define TGCR 0x24 +#define WDTCR 0x28 + +/* Offsets of the 8 compare registers */ +#define CMP12_0 0x60 +#define CMP12_1 0x64 +#define CMP12_2 0x68 +#define CMP12_3 0x6c +#define CMP12_4 0x70 +#define CMP12_5 0x74 +#define CMP12_6 0x78 +#define CMP12_7 0x7c + +/* Timer register bitfields */ +#define TCR_ENAMODE_DISABLE 0x0 +#define TCR_ENAMODE_ONESHOT 0x1 +#define TCR_ENAMODE_PERIODIC 0x2 +#define TCR_ENAMODE_MASK 0x3 + +#define TGCR_TIMMODE_SHIFT 2 +#define TGCR_TIMMODE_64BIT_GP 0x0 +#define TGCR_TIMMODE_32BIT_UNCHAINED 0x1 +#define TGCR_TIMMODE_64BIT_WDOG 0x2 +#define TGCR_TIMMODE_32BIT_CHAINED 0x3 + +#define TGCR_TIM12RS_SHIFT 0 +#define TGCR_TIM34RS_SHIFT 1 +#define TGCR_RESET 0x0 +#define TGCR_UNRESET 0x1 +#define TGCR_RESET_MASK 0x3 + +#define WDTCR_WDEN_SHIFT 14 +#define WDTCR_WDEN_DISABLE 0x0 +#define WDTCR_WDEN_ENABLE 0x1 +#define WDTCR_WDKEY_SHIFT 16 +#define WDTCR_WDKEY_SEQ0 0xa5c6 +#define WDTCR_WDKEY_SEQ1 0xda7e + +struct timer_s { + char *name; + unsigned int id; + unsigned long period; + unsigned long opts; + unsigned long flags; + void __iomem *base; + unsigned long tim_off; + unsigned long prd_off; + unsigned long enamode_shift; + struct irqaction irqaction; +}; +static struct timer_s timers[]; + +/* values for 'opts' field of struct timer_s */ +#define TIMER_OPTS_DISABLED 0x01 +#define TIMER_OPTS_ONESHOT 0x02 +#define TIMER_OPTS_PERIODIC 0x04 +#define TIMER_OPTS_STATE_MASK 0x07 + +#define TIMER_OPTS_USE_COMPARE 0x80000000 +#define USING_COMPARE(t) ((t)->opts & TIMER_OPTS_USE_COMPARE) + +static char *id_to_name[] = { + [T0_BOT] = "timer0_0", + [T0_TOP] = "timer0_1", + [T1_BOT] = "timer1_0", + [T1_TOP] = "timer1_1", +}; + +static int timer32_config(struct timer_s *t) +{ + u32 tcr; + struct davinci_soc_info *soc_info = &davinci_soc_info; + + if (USING_COMPARE(t)) { + struct davinci_timer_instance *dtip = + soc_info->timer_info->timers; + int event_timer = ID_TO_TIMER(timers[TID_CLOCKEVENT].id); + + /* + * Next interrupt should be the current time reg value plus + * the new period (using 32-bit unsigned addition/wrapping + * to 0 on overflow). This assumes that the clocksource + * is setup to count to 2^32-1 before wrapping around to 0. + */ + __raw_writel(__raw_readl(t->base + t->tim_off) + t->period, + t->base + dtip[event_timer].cmp_off); + } else { + tcr = __raw_readl(t->base + TCR); + + /* disable timer */ + tcr &= ~(TCR_ENAMODE_MASK << t->enamode_shift); + __raw_writel(tcr, t->base + TCR); + + /* reset counter to zero, set new period */ + __raw_writel(0, t->base + t->tim_off); + __raw_writel(t->period, t->base + t->prd_off); + + /* Set enable mode */ + if (t->opts & TIMER_OPTS_ONESHOT) + tcr |= TCR_ENAMODE_ONESHOT << t->enamode_shift; + else if (t->opts & TIMER_OPTS_PERIODIC) + tcr |= TCR_ENAMODE_PERIODIC << t->enamode_shift; + + __raw_writel(tcr, t->base + TCR); + } + return 0; +} + +static inline u32 timer32_read(struct timer_s *t) +{ + return __raw_readl(t->base + t->tim_off); +} + +static irqreturn_t timer_interrupt(int irq, void *dev_id) +{ + struct clock_event_device *evt = &clockevent_davinci; + + evt->event_handler(evt); + return IRQ_HANDLED; +} + +/* called when 32-bit counter wraps */ +static irqreturn_t freerun_interrupt(int irq, void *dev_id) +{ + return IRQ_HANDLED; +} + +static struct timer_s timers[] = { + [TID_CLOCKEVENT] = { + .name = "clockevent", + .opts = TIMER_OPTS_DISABLED, + .irqaction = { + .flags = IRQF_DISABLED | IRQF_TIMER, + .handler = timer_interrupt, + } + }, + [TID_CLOCKSOURCE] = { + .name = "free-run counter", + .period = ~0, + .opts = TIMER_OPTS_PERIODIC, + .irqaction = { + .flags = IRQF_DISABLED | IRQF_TIMER, + .handler = freerun_interrupt, + } + }, +}; + +static void __init timer_init(void) +{ + struct davinci_soc_info *soc_info = &davinci_soc_info; + struct davinci_timer_instance *dtip = soc_info->timer_info->timers; + void __iomem *base[2]; + int i; + + /* Global init of each 64-bit timer as a whole */ + for(i=0; i<2; i++) { + u32 tgcr; + + base[i] = ioremap(dtip[i].base, SZ_4K); + if (WARN_ON(!base[i])) + continue; + + /* Disabled, Internal clock source */ + __raw_writel(0, base[i] + TCR); + + /* reset both timers, no pre-scaler for timer34 */ + tgcr = 0; + __raw_writel(tgcr, base[i] + TGCR); + + /* Set both timers to unchained 32-bit */ + tgcr = TGCR_TIMMODE_32BIT_UNCHAINED << TGCR_TIMMODE_SHIFT; + __raw_writel(tgcr, base[i] + TGCR); + + /* Unreset timers */ + tgcr |= (TGCR_UNRESET << TGCR_TIM12RS_SHIFT) | + (TGCR_UNRESET << TGCR_TIM34RS_SHIFT); + __raw_writel(tgcr, base[i] + TGCR); + + /* Init both counters to zero */ + __raw_writel(0, base[i] + TIM12); + __raw_writel(0, base[i] + TIM34); + } + + /* Init of each timer as a 32-bit timer */ + for (i=0; i< ARRAY_SIZE(timers); i++) { + struct timer_s *t = &timers[i]; + int timer = ID_TO_TIMER(t->id); + u32 irq; + + t->base = base[timer]; + if (!t->base) + continue; + + if (IS_TIMER_BOT(t->id)) { + t->enamode_shift = 6; + t->tim_off = TIM12; + t->prd_off = PRD12; + irq = dtip[timer].bottom_irq; + } else { + t->enamode_shift = 22; + t->tim_off = TIM34; + t->prd_off = PRD34; + irq = dtip[timer].top_irq; + } + + /* Register interrupt */ + t->irqaction.name = t->name; + t->irqaction.dev_id = (void *)t; + + if (t->irqaction.handler != NULL) { + irq = USING_COMPARE(t) ? dtip[i].cmp_irq : irq; + setup_irq(irq, &t->irqaction); + } + } +} + +/* + * clocksource + */ +static cycle_t read_cycles(struct clocksource *cs) +{ + struct timer_s *t = &timers[TID_CLOCKSOURCE]; + + return (cycles_t)timer32_read(t); +} + +static struct clocksource clocksource_davinci = { + .rating = 300, + .read = read_cycles, + .mask = CLOCKSOURCE_MASK(32), + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + +/* + * Overwrite weak default sched_clock with something more precise + */ +static u32 notrace davinci_read_sched_clock(void) +{ + return timer32_read(&timers[TID_CLOCKSOURCE]); +} + +/* + * clockevent + */ +static int davinci_set_next_event(unsigned long cycles, + struct clock_event_device *evt) +{ + struct timer_s *t = &timers[TID_CLOCKEVENT]; + + t->period = cycles; + timer32_config(t); + return 0; +} + +static void davinci_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + struct timer_s *t = &timers[TID_CLOCKEVENT]; + + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + t->period = davinci_clock_tick_rate / (HZ); + t->opts &= ~TIMER_OPTS_STATE_MASK; + t->opts |= TIMER_OPTS_PERIODIC; + timer32_config(t); + break; + case CLOCK_EVT_MODE_ONESHOT: + t->opts &= ~TIMER_OPTS_STATE_MASK; + t->opts |= TIMER_OPTS_ONESHOT; + break; + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_SHUTDOWN: + t->opts &= ~TIMER_OPTS_STATE_MASK; + t->opts |= TIMER_OPTS_DISABLED; + break; + case CLOCK_EVT_MODE_RESUME: + break; + } +} + +static struct clock_event_device clockevent_davinci = { + .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, + .shift = 32, + .set_next_event = davinci_set_next_event, + .set_mode = davinci_set_mode, +}; + + +static void __init davinci_timer_init(void) +{ + struct clk *timer_clk; + struct davinci_soc_info *soc_info = &davinci_soc_info; + unsigned int clockevent_id; + unsigned int clocksource_id; + static char err[] __initdata = KERN_ERR + "%s: can't register clocksource!\n"; + int i; + + clockevent_id = soc_info->timer_info->clockevent_id; + clocksource_id = soc_info->timer_info->clocksource_id; + + timers[TID_CLOCKEVENT].id = clockevent_id; + timers[TID_CLOCKSOURCE].id = clocksource_id; + + /* + * If using same timer for both clock events & clocksource, + * a compare register must be used to generate an event interrupt. + * This is equivalent to a oneshot timer only (not periodic). + */ + if (clockevent_id == clocksource_id) { + struct davinci_timer_instance *dtip = + soc_info->timer_info->timers; + int event_timer = ID_TO_TIMER(clockevent_id); + + /* Only bottom timers can use compare regs */ + if (IS_TIMER_TOP(clockevent_id)) + pr_warning("davinci_timer_init: Invalid use" + " of system timers. Results unpredictable.\n"); + else if ((dtip[event_timer].cmp_off == 0) + || (dtip[event_timer].cmp_irq == 0)) + pr_warning("davinci_timer_init: Invalid timer instance" + " setup. Results unpredictable.\n"); + else { + timers[TID_CLOCKEVENT].opts |= TIMER_OPTS_USE_COMPARE; + clockevent_davinci.features = CLOCK_EVT_FEAT_ONESHOT; + } + } + + timer_clk = clk_get(NULL, "timer0"); + BUG_ON(IS_ERR(timer_clk)); + clk_enable(timer_clk); + + /* init timer hw */ + timer_init(); + + davinci_clock_tick_rate = clk_get_rate(timer_clk); + + /* setup clocksource */ + clocksource_davinci.name = id_to_name[clocksource_id]; + if (clocksource_register_hz(&clocksource_davinci, + davinci_clock_tick_rate)) + printk(err, clocksource_davinci.name); + + setup_sched_clock(davinci_read_sched_clock, 32, + davinci_clock_tick_rate); + + /* setup clockevent */ + clockevent_davinci.name = id_to_name[timers[TID_CLOCKEVENT].id]; + clockevent_davinci.mult = div_sc(davinci_clock_tick_rate, NSEC_PER_SEC, + clockevent_davinci.shift); + clockevent_davinci.max_delta_ns = + clockevent_delta2ns(0xfffffffe, &clockevent_davinci); + clockevent_davinci.min_delta_ns = 50000; /* 50 usec */ + + clockevent_davinci.cpumask = cpumask_of(0); + clockevents_register_device(&clockevent_davinci); + + for (i=0; i< ARRAY_SIZE(timers); i++) + timer32_config(&timers[i]); +} + +struct sys_timer davinci_timer = { + .init = davinci_timer_init, +}; + + +/* reset board using watchdog timer */ +void davinci_watchdog_reset(struct platform_device *pdev) +{ + u32 tgcr, wdtcr; + void __iomem *base; + struct clk *wd_clk; + + base = ioremap(pdev->resource[0].start, SZ_4K); + if (WARN_ON(!base)) + return; + + wd_clk = clk_get(&pdev->dev, NULL); + if (WARN_ON(IS_ERR(wd_clk))) + return; + clk_enable(wd_clk); + + /* disable, internal clock source */ + __raw_writel(0, base + TCR); + + /* reset timer, set mode to 64-bit watchdog, and unreset */ + tgcr = 0; + __raw_writel(tgcr, base + TGCR); + tgcr = TGCR_TIMMODE_64BIT_WDOG << TGCR_TIMMODE_SHIFT; + tgcr |= (TGCR_UNRESET << TGCR_TIM12RS_SHIFT) | + (TGCR_UNRESET << TGCR_TIM34RS_SHIFT); + __raw_writel(tgcr, base + TGCR); + + /* clear counter and period regs */ + __raw_writel(0, base + TIM12); + __raw_writel(0, base + TIM34); + __raw_writel(0, base + PRD12); + __raw_writel(0, base + PRD34); + + /* put watchdog in pre-active state */ + wdtcr = __raw_readl(base + WDTCR); + wdtcr = (WDTCR_WDKEY_SEQ0 << WDTCR_WDKEY_SHIFT) | + (WDTCR_WDEN_ENABLE << WDTCR_WDEN_SHIFT); + __raw_writel(wdtcr, base + WDTCR); + + /* put watchdog in active state */ + wdtcr = (WDTCR_WDKEY_SEQ1 << WDTCR_WDKEY_SHIFT) | + (WDTCR_WDEN_ENABLE << WDTCR_WDEN_SHIFT); + __raw_writel(wdtcr, base + WDTCR); + + /* write an invalid value to the WDKEY field to trigger + * a watchdog reset */ + wdtcr = 0x00004000; + __raw_writel(wdtcr, base + WDTCR); +} diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/tnetv107x.c b/ANDROID_3.4.5/arch/arm/mach-davinci/tnetv107x.c new file mode 100644 index 00000000..dc1a209b --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/tnetv107x.c @@ -0,0 +1,765 @@ +/* + * Texas Instruments TNETV107X SoC Support + * + * Copyright (C) 2010 Texas Instruments + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include <linux/gpio.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/clk.h> +#include <linux/io.h> +#include <linux/err.h> +#include <linux/platform_device.h> + +#include <asm/mach/map.h> + +#include <mach/common.h> +#include <mach/time.h> +#include <mach/cputype.h> +#include <mach/psc.h> +#include <mach/cp_intc.h> +#include <mach/irqs.h> +#include <mach/hardware.h> +#include <mach/tnetv107x.h> +#include <mach/gpio-davinci.h> + +#include "clock.h" +#include "mux.h" + +/* Base addresses for on-chip devices */ +#define TNETV107X_INTC_BASE 0x03000000 +#define TNETV107X_TIMER0_BASE 0x08086500 +#define TNETV107X_TIMER1_BASE 0x08086600 +#define TNETV107X_CHIP_CFG_BASE 0x08087000 +#define TNETV107X_GPIO_BASE 0x08088000 +#define TNETV107X_CLOCK_CONTROL_BASE 0x0808a000 +#define TNETV107X_PSC_BASE 0x0808b000 + +/* Reference clock frequencies */ +#define OSC_FREQ_ONCHIP (24000 * 1000) +#define OSC_FREQ_OFFCHIP_SYS (25000 * 1000) +#define OSC_FREQ_OFFCHIP_ETH (25000 * 1000) +#define OSC_FREQ_OFFCHIP_TDM (19200 * 1000) + +#define N_PLLS 3 + +/* Clock Control Registers */ +struct clk_ctrl_regs { + u32 pll_bypass; + u32 _reserved0; + u32 gem_lrst; + u32 _reserved1; + u32 pll_unlock_stat; + u32 sys_unlock; + u32 eth_unlock; + u32 tdm_unlock; +}; + +/* SSPLL Registers */ +struct sspll_regs { + u32 modes; + u32 post_div; + u32 pre_div; + u32 mult_factor; + u32 divider_range; + u32 bw_divider; + u32 spr_amount; + u32 spr_rate_div; + u32 diag; +}; + +/* Watchdog Timer Registers */ +struct wdt_regs { + u32 kick_lock; + u32 kick; + u32 change_lock; + u32 change ; + u32 disable_lock; + u32 disable; + u32 prescale_lock; + u32 prescale; +}; + +static struct clk_ctrl_regs __iomem *clk_ctrl_regs; + +static struct sspll_regs __iomem *sspll_regs[N_PLLS]; +static int sspll_regs_base[N_PLLS] = { 0x40, 0x80, 0xc0 }; + +/* PLL bypass bit shifts in clk_ctrl_regs->pll_bypass register */ +static u32 bypass_mask[N_PLLS] = { BIT(0), BIT(2), BIT(1) }; + +/* offchip (external) reference clock frequencies */ +static u32 pll_ext_freq[] = { + OSC_FREQ_OFFCHIP_SYS, + OSC_FREQ_OFFCHIP_TDM, + OSC_FREQ_OFFCHIP_ETH +}; + +/* PSC control registers */ +static u32 psc_regs[] = { TNETV107X_PSC_BASE }; + +/* Host map for interrupt controller */ +static u32 intc_host_map[] = { 0x01010000, 0x01010101, -1 }; + +static unsigned long clk_sspll_recalc(struct clk *clk); + +/* Level 1 - the PLLs */ +#define define_pll_clk(cname, pll, divmask, base) \ + static struct pll_data pll_##cname##_data = { \ + .num = pll, \ + .div_ratio_mask = divmask, \ + .phys_base = base + \ + TNETV107X_CLOCK_CONTROL_BASE, \ + }; \ + static struct clk pll_##cname##_clk = { \ + .name = "pll_" #cname "_clk", \ + .pll_data = &pll_##cname##_data, \ + .flags = CLK_PLL, \ + .recalc = clk_sspll_recalc, \ + } + +define_pll_clk(sys, 0, 0x1ff, 0x600); +define_pll_clk(tdm, 1, 0x0ff, 0x200); +define_pll_clk(eth, 2, 0x0ff, 0x400); + +/* Level 2 - divided outputs from the PLLs */ +#define define_pll_div_clk(pll, cname, div) \ + static struct clk pll##_##cname##_clk = { \ + .name = #pll "_" #cname "_clk", \ + .parent = &pll_##pll##_clk, \ + .flags = CLK_PLL, \ + .div_reg = PLLDIV##div, \ + .set_rate = davinci_set_sysclk_rate, \ + } + +define_pll_div_clk(sys, arm1176, 1); +define_pll_div_clk(sys, dsp, 2); +define_pll_div_clk(sys, ddr, 3); +define_pll_div_clk(sys, full, 4); +define_pll_div_clk(sys, lcd, 5); +define_pll_div_clk(sys, vlynq_ref, 6); +define_pll_div_clk(sys, tsc, 7); +define_pll_div_clk(sys, half, 8); + +define_pll_div_clk(eth, 5mhz, 1); +define_pll_div_clk(eth, 50mhz, 2); +define_pll_div_clk(eth, 125mhz, 3); +define_pll_div_clk(eth, 250mhz, 4); +define_pll_div_clk(eth, 25mhz, 5); + +define_pll_div_clk(tdm, 0, 1); +define_pll_div_clk(tdm, extra, 2); +define_pll_div_clk(tdm, 1, 3); + + +/* Level 3 - LPSC gated clocks */ +#define __lpsc_clk(cname, _parent, mod, flg) \ + static struct clk clk_##cname = { \ + .name = #cname, \ + .parent = &_parent, \ + .lpsc = TNETV107X_LPSC_##mod,\ + .flags = flg, \ + } + +#define lpsc_clk_enabled(cname, parent, mod) \ + __lpsc_clk(cname, parent, mod, ALWAYS_ENABLED) + +#define lpsc_clk(cname, parent, mod) \ + __lpsc_clk(cname, parent, mod, 0) + +lpsc_clk_enabled(arm, sys_arm1176_clk, ARM); +lpsc_clk_enabled(gem, sys_dsp_clk, GEM); +lpsc_clk_enabled(ddr2_phy, sys_ddr_clk, DDR2_PHY); +lpsc_clk_enabled(tpcc, sys_full_clk, TPCC); +lpsc_clk_enabled(tptc0, sys_full_clk, TPTC0); +lpsc_clk_enabled(tptc1, sys_full_clk, TPTC1); +lpsc_clk_enabled(ram, sys_full_clk, RAM); +lpsc_clk_enabled(aemif, sys_full_clk, AEMIF); +lpsc_clk_enabled(chipcfg, sys_half_clk, CHIP_CFG); +lpsc_clk_enabled(rom, sys_half_clk, ROM); +lpsc_clk_enabled(secctl, sys_half_clk, SECCTL); +lpsc_clk_enabled(keymgr, sys_half_clk, KEYMGR); +lpsc_clk_enabled(gpio, sys_half_clk, GPIO); +lpsc_clk_enabled(debugss, sys_half_clk, DEBUGSS); +lpsc_clk_enabled(system, sys_half_clk, SYSTEM); +lpsc_clk_enabled(ddr2_vrst, sys_ddr_clk, DDR2_EMIF1_VRST); +lpsc_clk_enabled(ddr2_vctl_rst, sys_ddr_clk, DDR2_EMIF2_VCTL_RST); +lpsc_clk_enabled(wdt_arm, sys_half_clk, WDT_ARM); +lpsc_clk_enabled(timer1, sys_half_clk, TIMER1); + +lpsc_clk(mbx_lite, sys_arm1176_clk, MBX_LITE); +lpsc_clk(ethss, eth_125mhz_clk, ETHSS); +lpsc_clk(tsc, sys_tsc_clk, TSC); +lpsc_clk(uart0, sys_half_clk, UART0); +lpsc_clk(uart1, sys_half_clk, UART1); +lpsc_clk(uart2, sys_half_clk, UART2); +lpsc_clk(pktsec, sys_half_clk, PKTSEC); +lpsc_clk(keypad, sys_half_clk, KEYPAD); +lpsc_clk(mdio, sys_half_clk, MDIO); +lpsc_clk(sdio0, sys_half_clk, SDIO0); +lpsc_clk(sdio1, sys_half_clk, SDIO1); +lpsc_clk(timer0, sys_half_clk, TIMER0); +lpsc_clk(wdt_dsp, sys_half_clk, WDT_DSP); +lpsc_clk(ssp, sys_half_clk, SSP); +lpsc_clk(tdm0, tdm_0_clk, TDM0); +lpsc_clk(tdm1, tdm_1_clk, TDM1); +lpsc_clk(vlynq, sys_vlynq_ref_clk, VLYNQ); +lpsc_clk(mcdma, sys_half_clk, MCDMA); +lpsc_clk(usbss, sys_half_clk, USBSS); +lpsc_clk(usb0, clk_usbss, USB0); +lpsc_clk(usb1, clk_usbss, USB1); +lpsc_clk(ethss_rgmii, eth_250mhz_clk, ETHSS_RGMII); +lpsc_clk(imcop, sys_dsp_clk, IMCOP); +lpsc_clk(spare, sys_half_clk, SPARE); + +/* LCD needs a full power down to clear controller state */ +__lpsc_clk(lcd, sys_lcd_clk, LCD, PSC_SWRSTDISABLE); + + +/* Level 4 - leaf clocks for LPSC modules shared across drivers */ +static struct clk clk_rng = { .name = "rng", .parent = &clk_pktsec }; +static struct clk clk_pka = { .name = "pka", .parent = &clk_pktsec }; + +static struct clk_lookup clks[] = { + CLK(NULL, "pll_sys_clk", &pll_sys_clk), + CLK(NULL, "pll_eth_clk", &pll_eth_clk), + CLK(NULL, "pll_tdm_clk", &pll_tdm_clk), + CLK(NULL, "sys_arm1176_clk", &sys_arm1176_clk), + CLK(NULL, "sys_dsp_clk", &sys_dsp_clk), + CLK(NULL, "sys_ddr_clk", &sys_ddr_clk), + CLK(NULL, "sys_full_clk", &sys_full_clk), + CLK(NULL, "sys_lcd_clk", &sys_lcd_clk), + CLK(NULL, "sys_vlynq_ref_clk", &sys_vlynq_ref_clk), + CLK(NULL, "sys_tsc_clk", &sys_tsc_clk), + CLK(NULL, "sys_half_clk", &sys_half_clk), + CLK(NULL, "eth_5mhz_clk", ð_5mhz_clk), + CLK(NULL, "eth_50mhz_clk", ð_50mhz_clk), + CLK(NULL, "eth_125mhz_clk", ð_125mhz_clk), + CLK(NULL, "eth_250mhz_clk", ð_250mhz_clk), + CLK(NULL, "eth_25mhz_clk", ð_25mhz_clk), + CLK(NULL, "tdm_0_clk", &tdm_0_clk), + CLK(NULL, "tdm_extra_clk", &tdm_extra_clk), + CLK(NULL, "tdm_1_clk", &tdm_1_clk), + CLK(NULL, "clk_arm", &clk_arm), + CLK(NULL, "clk_gem", &clk_gem), + CLK(NULL, "clk_ddr2_phy", &clk_ddr2_phy), + CLK(NULL, "clk_tpcc", &clk_tpcc), + CLK(NULL, "clk_tptc0", &clk_tptc0), + CLK(NULL, "clk_tptc1", &clk_tptc1), + CLK(NULL, "clk_ram", &clk_ram), + CLK(NULL, "clk_mbx_lite", &clk_mbx_lite), + CLK("tnetv107x-fb.0", NULL, &clk_lcd), + CLK(NULL, "clk_ethss", &clk_ethss), + CLK(NULL, "aemif", &clk_aemif), + CLK(NULL, "clk_chipcfg", &clk_chipcfg), + CLK("tnetv107x-ts.0", NULL, &clk_tsc), + CLK(NULL, "clk_rom", &clk_rom), + CLK(NULL, "uart2", &clk_uart2), + CLK(NULL, "clk_pktsec", &clk_pktsec), + CLK("tnetv107x-rng.0", NULL, &clk_rng), + CLK("tnetv107x-pka.0", NULL, &clk_pka), + CLK(NULL, "clk_secctl", &clk_secctl), + CLK(NULL, "clk_keymgr", &clk_keymgr), + CLK("tnetv107x-keypad.0", NULL, &clk_keypad), + CLK(NULL, "clk_gpio", &clk_gpio), + CLK(NULL, "clk_mdio", &clk_mdio), + CLK("davinci_mmc.0", NULL, &clk_sdio0), + CLK(NULL, "uart0", &clk_uart0), + CLK(NULL, "uart1", &clk_uart1), + CLK(NULL, "timer0", &clk_timer0), + CLK(NULL, "timer1", &clk_timer1), + CLK("tnetv107x_wdt.0", NULL, &clk_wdt_arm), + CLK(NULL, "clk_wdt_dsp", &clk_wdt_dsp), + CLK("ti-ssp", NULL, &clk_ssp), + CLK(NULL, "clk_tdm0", &clk_tdm0), + CLK(NULL, "clk_vlynq", &clk_vlynq), + CLK(NULL, "clk_mcdma", &clk_mcdma), + CLK(NULL, "clk_usbss", &clk_usbss), + CLK(NULL, "clk_usb0", &clk_usb0), + CLK(NULL, "clk_usb1", &clk_usb1), + CLK(NULL, "clk_tdm1", &clk_tdm1), + CLK(NULL, "clk_debugss", &clk_debugss), + CLK(NULL, "clk_ethss_rgmii", &clk_ethss_rgmii), + CLK(NULL, "clk_system", &clk_system), + CLK(NULL, "clk_imcop", &clk_imcop), + CLK(NULL, "clk_spare", &clk_spare), + CLK("davinci_mmc.1", NULL, &clk_sdio1), + CLK(NULL, "clk_ddr2_vrst", &clk_ddr2_vrst), + CLK(NULL, "clk_ddr2_vctl_rst", &clk_ddr2_vctl_rst), + CLK(NULL, NULL, NULL), +}; + +static const struct mux_config pins[] = { +#ifdef CONFIG_DAVINCI_MUX + MUX_CFG(TNETV107X, ASR_A00, 0, 0, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO32, 0, 0, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, ASR_A01, 0, 5, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO33, 0, 5, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, ASR_A02, 0, 10, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO34, 0, 10, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, ASR_A03, 0, 15, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO35, 0, 15, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, ASR_A04, 0, 20, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO36, 0, 20, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, ASR_A05, 0, 25, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO37, 0, 25, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, ASR_A06, 1, 0, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO38, 1, 0, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, ASR_A07, 1, 5, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO39, 1, 5, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, ASR_A08, 1, 10, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO40, 1, 10, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, ASR_A09, 1, 15, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO41, 1, 15, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, ASR_A10, 1, 20, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO42, 1, 20, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, ASR_A11, 1, 25, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, BOOT_STRP_0, 1, 25, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, ASR_A12, 2, 0, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, BOOT_STRP_1, 2, 0, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, ASR_A13, 2, 5, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO43, 2, 5, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, ASR_A14, 2, 10, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO44, 2, 10, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, ASR_A15, 2, 15, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO45, 2, 15, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, ASR_A16, 2, 20, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO46, 2, 20, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, ASR_A17, 2, 25, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO47, 2, 25, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, ASR_A18, 3, 0, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO48, 3, 0, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, SDIO1_DATA3_0, 3, 0, 0x1f, 0x1c, false) + MUX_CFG(TNETV107X, ASR_A19, 3, 5, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO49, 3, 5, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, SDIO1_DATA2_0, 3, 5, 0x1f, 0x1c, false) + MUX_CFG(TNETV107X, ASR_A20, 3, 10, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO50, 3, 10, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, SDIO1_DATA1_0, 3, 10, 0x1f, 0x1c, false) + MUX_CFG(TNETV107X, ASR_A21, 3, 15, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO51, 3, 15, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, SDIO1_DATA0_0, 3, 15, 0x1f, 0x1c, false) + MUX_CFG(TNETV107X, ASR_A22, 3, 20, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO52, 3, 20, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, SDIO1_CMD_0, 3, 20, 0x1f, 0x1c, false) + MUX_CFG(TNETV107X, ASR_A23, 3, 25, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO53, 3, 25, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, SDIO1_CLK_0, 3, 25, 0x1f, 0x1c, false) + MUX_CFG(TNETV107X, ASR_BA_1, 4, 0, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO54, 4, 0, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, SYS_PLL_CLK, 4, 0, 0x1f, 0x1c, false) + MUX_CFG(TNETV107X, ASR_CS0, 4, 5, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, ASR_CS1, 4, 10, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, ASR_CS2, 4, 15, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, TDM_PLL_CLK, 4, 15, 0x1f, 0x1c, false) + MUX_CFG(TNETV107X, ASR_CS3, 4, 20, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, ETH_PHY_CLK, 4, 20, 0x1f, 0x0c, false) + MUX_CFG(TNETV107X, ASR_D00, 4, 25, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO55, 4, 25, 0x1f, 0x1c, false) + MUX_CFG(TNETV107X, ASR_D01, 5, 0, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO56, 5, 0, 0x1f, 0x1c, false) + MUX_CFG(TNETV107X, ASR_D02, 5, 5, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO57, 5, 5, 0x1f, 0x1c, false) + MUX_CFG(TNETV107X, ASR_D03, 5, 10, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO58, 5, 10, 0x1f, 0x1c, false) + MUX_CFG(TNETV107X, ASR_D04, 5, 15, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO59_0, 5, 15, 0x1f, 0x1c, false) + MUX_CFG(TNETV107X, ASR_D05, 5, 20, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO60_0, 5, 20, 0x1f, 0x1c, false) + MUX_CFG(TNETV107X, ASR_D06, 5, 25, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO61_0, 5, 25, 0x1f, 0x1c, false) + MUX_CFG(TNETV107X, ASR_D07, 6, 0, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO62_0, 6, 0, 0x1f, 0x1c, false) + MUX_CFG(TNETV107X, ASR_D08, 6, 5, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO63_0, 6, 5, 0x1f, 0x1c, false) + MUX_CFG(TNETV107X, ASR_D09, 6, 10, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO64_0, 6, 10, 0x1f, 0x1c, false) + MUX_CFG(TNETV107X, ASR_D10, 6, 15, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, SDIO1_DATA3_1, 6, 15, 0x1f, 0x1c, false) + MUX_CFG(TNETV107X, ASR_D11, 6, 20, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, SDIO1_DATA2_1, 6, 20, 0x1f, 0x1c, false) + MUX_CFG(TNETV107X, ASR_D12, 6, 25, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, SDIO1_DATA1_1, 6, 25, 0x1f, 0x1c, false) + MUX_CFG(TNETV107X, ASR_D13, 7, 0, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, SDIO1_DATA0_1, 7, 0, 0x1f, 0x1c, false) + MUX_CFG(TNETV107X, ASR_D14, 7, 5, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, SDIO1_CMD_1, 7, 5, 0x1f, 0x1c, false) + MUX_CFG(TNETV107X, ASR_D15, 7, 10, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, SDIO1_CLK_1, 7, 10, 0x1f, 0x1c, false) + MUX_CFG(TNETV107X, ASR_OE, 7, 15, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, BOOT_STRP_2, 7, 15, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, ASR_RNW, 7, 20, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO29_0, 7, 20, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, ASR_WAIT, 7, 25, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO30_0, 7, 25, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, ASR_WE, 8, 0, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, BOOT_STRP_3, 8, 0, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, ASR_WE_DQM0, 8, 5, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO31, 8, 5, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, LCD_PD17_0, 8, 5, 0x1f, 0x1c, false) + MUX_CFG(TNETV107X, ASR_WE_DQM1, 8, 10, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, ASR_BA0_0, 8, 10, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, VLYNQ_CLK, 9, 0, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO14, 9, 0, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, LCD_PD19_0, 9, 0, 0x1f, 0x1c, false) + MUX_CFG(TNETV107X, VLYNQ_RXD0, 9, 5, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO15, 9, 5, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, LCD_PD20_0, 9, 5, 0x1f, 0x1c, false) + MUX_CFG(TNETV107X, VLYNQ_RXD1, 9, 10, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO16, 9, 10, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, LCD_PD21_0, 9, 10, 0x1f, 0x1c, false) + MUX_CFG(TNETV107X, VLYNQ_TXD0, 9, 15, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO17, 9, 15, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, LCD_PD22_0, 9, 15, 0x1f, 0x1c, false) + MUX_CFG(TNETV107X, VLYNQ_TXD1, 9, 20, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO18, 9, 20, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, LCD_PD23_0, 9, 20, 0x1f, 0x1c, false) + MUX_CFG(TNETV107X, SDIO0_CLK, 10, 0, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO19, 10, 0, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, SDIO0_CMD, 10, 5, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO20, 10, 5, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, SDIO0_DATA0, 10, 10, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO21, 10, 10, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, SDIO0_DATA1, 10, 15, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO22, 10, 15, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, SDIO0_DATA2, 10, 20, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO23, 10, 20, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, SDIO0_DATA3, 10, 25, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO24, 10, 25, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, EMU0, 11, 0, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, EMU1, 11, 5, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, RTCK, 12, 0, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, TRST_N, 12, 5, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, TCK, 12, 10, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, TDI, 12, 15, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, TDO, 12, 20, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, TMS, 12, 25, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, TDM1_CLK, 13, 0, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, TDM1_RX, 13, 5, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, TDM1_TX, 13, 10, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, TDM1_FS, 13, 15, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, KEYPAD_R0, 14, 0, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, KEYPAD_R1, 14, 5, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, KEYPAD_R2, 14, 10, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, KEYPAD_R3, 14, 15, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, KEYPAD_R4, 14, 20, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, KEYPAD_R5, 14, 25, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, KEYPAD_R6, 15, 0, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO12, 15, 0, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, KEYPAD_R7, 15, 5, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO10, 15, 5, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, KEYPAD_C0, 15, 10, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, KEYPAD_C1, 15, 15, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, KEYPAD_C2, 15, 20, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, KEYPAD_C3, 15, 25, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, KEYPAD_C4, 16, 0, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, KEYPAD_C5, 16, 5, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, KEYPAD_C6, 16, 10, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO13, 16, 10, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, TEST_CLK_IN, 16, 10, 0x1f, 0x0c, false) + MUX_CFG(TNETV107X, KEYPAD_C7, 16, 15, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO11, 16, 15, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, SSP0_0, 17, 0, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, SCC_DCLK, 17, 0, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, LCD_PD20_1, 17, 0, 0x1f, 0x0c, false) + MUX_CFG(TNETV107X, SSP0_1, 17, 5, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, SCC_CS_N, 17, 5, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, LCD_PD21_1, 17, 5, 0x1f, 0x0c, false) + MUX_CFG(TNETV107X, SSP0_2, 17, 10, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, SCC_D, 17, 10, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, LCD_PD22_1, 17, 10, 0x1f, 0x0c, false) + MUX_CFG(TNETV107X, SSP0_3, 17, 15, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, SCC_RESETN, 17, 15, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, LCD_PD23_1, 17, 15, 0x1f, 0x0c, false) + MUX_CFG(TNETV107X, SSP1_0, 18, 0, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO25, 18, 0, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, UART2_CTS, 18, 0, 0x1f, 0x0c, false) + MUX_CFG(TNETV107X, SSP1_1, 18, 5, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO26, 18, 5, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, UART2_RD, 18, 5, 0x1f, 0x0c, false) + MUX_CFG(TNETV107X, SSP1_2, 18, 10, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO27, 18, 10, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, UART2_RTS, 18, 10, 0x1f, 0x0c, false) + MUX_CFG(TNETV107X, SSP1_3, 18, 15, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO28, 18, 15, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, UART2_TD, 18, 15, 0x1f, 0x0c, false) + MUX_CFG(TNETV107X, UART0_CTS, 19, 0, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, UART0_RD, 19, 5, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, UART0_RTS, 19, 10, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, UART0_TD, 19, 15, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, UART1_RD, 19, 20, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, UART1_TD, 19, 25, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, LCD_AC_NCS, 20, 0, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, LCD_HSYNC_RNW, 20, 5, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, LCD_VSYNC_A0, 20, 10, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, LCD_MCLK, 20, 15, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, LCD_PD16_0, 20, 15, 0x1f, 0x0c, false) + MUX_CFG(TNETV107X, LCD_PCLK_E, 20, 20, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, LCD_PD00, 20, 25, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, LCD_PD01, 21, 0, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, LCD_PD02, 21, 5, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, LCD_PD03, 21, 10, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, LCD_PD04, 21, 15, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, LCD_PD05, 21, 20, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, LCD_PD06, 21, 25, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, LCD_PD07, 22, 0, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, LCD_PD08, 22, 5, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO59_1, 22, 5, 0x1f, 0x0c, false) + MUX_CFG(TNETV107X, LCD_PD09, 22, 10, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO60_1, 22, 10, 0x1f, 0x0c, false) + MUX_CFG(TNETV107X, LCD_PD10, 22, 15, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, ASR_BA0_1, 22, 15, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, GPIO61_1, 22, 15, 0x1f, 0x0c, false) + MUX_CFG(TNETV107X, LCD_PD11, 22, 20, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO62_1, 22, 20, 0x1f, 0x0c, false) + MUX_CFG(TNETV107X, LCD_PD12, 22, 25, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO63_1, 22, 25, 0x1f, 0x0c, false) + MUX_CFG(TNETV107X, LCD_PD13, 23, 0, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO64_1, 23, 0, 0x1f, 0x0c, false) + MUX_CFG(TNETV107X, LCD_PD14, 23, 5, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO29_1, 23, 5, 0x1f, 0x0c, false) + MUX_CFG(TNETV107X, LCD_PD15, 23, 10, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO30_1, 23, 10, 0x1f, 0x0c, false) + MUX_CFG(TNETV107X, EINT0, 24, 0, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO08, 24, 0, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, EINT1, 24, 5, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, GPIO09, 24, 5, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, GPIO00, 24, 10, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, LCD_PD20_2, 24, 10, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, TDM_CLK_IN_2, 24, 10, 0x1f, 0x0c, false) + MUX_CFG(TNETV107X, GPIO01, 24, 15, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, LCD_PD21_2, 24, 15, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, 24M_CLK_OUT_1, 24, 15, 0x1f, 0x0c, false) + MUX_CFG(TNETV107X, GPIO02, 24, 20, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, LCD_PD22_2, 24, 20, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, GPIO03, 24, 25, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, LCD_PD23_2, 24, 25, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, GPIO04, 25, 0, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, LCD_PD16_1, 25, 0, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, USB0_RXERR, 25, 0, 0x1f, 0x0c, false) + MUX_CFG(TNETV107X, GPIO05, 25, 5, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, LCD_PD17_1, 25, 5, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, TDM_CLK_IN_1, 25, 5, 0x1f, 0x0c, false) + MUX_CFG(TNETV107X, GPIO06, 25, 10, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, LCD_PD18, 25, 10, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, 24M_CLK_OUT_2, 25, 10, 0x1f, 0x0c, false) + MUX_CFG(TNETV107X, GPIO07, 25, 15, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, LCD_PD19_1, 25, 15, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, USB1_RXERR, 25, 15, 0x1f, 0x0c, false) + MUX_CFG(TNETV107X, ETH_PLL_CLK, 25, 15, 0x1f, 0x1c, false) + MUX_CFG(TNETV107X, MDIO, 26, 0, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, MDC, 26, 5, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, AIC_MUTE_STAT_N, 26, 10, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, TDM0_CLK, 26, 10, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, AIC_HNS_EN_N, 26, 15, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, TDM0_FS, 26, 15, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, AIC_HDS_EN_STAT_N, 26, 20, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, TDM0_TX, 26, 20, 0x1f, 0x04, false) + MUX_CFG(TNETV107X, AIC_HNF_EN_STAT_N, 26, 25, 0x1f, 0x00, false) + MUX_CFG(TNETV107X, TDM0_RX, 26, 25, 0x1f, 0x04, false) +#endif +}; + +/* FIQ are pri 0-1; otherwise 2-7, with 7 lowest priority */ +static u8 irq_prios[TNETV107X_N_CP_INTC_IRQ] = { + /* fill in default priority 7 */ + [0 ... (TNETV107X_N_CP_INTC_IRQ - 1)] = 7, + /* now override as needed, e.g. [xxx] = 5 */ +}; + +/* Contents of JTAG ID register used to identify exact cpu type */ +static struct davinci_id ids[] = { + { + .variant = 0x0, + .part_no = 0xb8a1, + .manufacturer = 0x017, + .cpu_id = DAVINCI_CPU_ID_TNETV107X, + .name = "tnetv107x rev 1.0", + }, + { + .variant = 0x1, + .part_no = 0xb8a1, + .manufacturer = 0x017, + .cpu_id = DAVINCI_CPU_ID_TNETV107X, + .name = "tnetv107x rev 1.1/1.2", + }, +}; + +static struct davinci_timer_instance timer_instance[2] = { + { + .base = TNETV107X_TIMER0_BASE, + .bottom_irq = IRQ_TNETV107X_TIMER_0_TINT12, + .top_irq = IRQ_TNETV107X_TIMER_0_TINT34, + }, + { + .base = TNETV107X_TIMER1_BASE, + .bottom_irq = IRQ_TNETV107X_TIMER_1_TINT12, + .top_irq = IRQ_TNETV107X_TIMER_1_TINT34, + }, +}; + +static struct davinci_timer_info timer_info = { + .timers = timer_instance, + .clockevent_id = T0_BOT, + .clocksource_id = T0_TOP, +}; + +/* + * TNETV107X platforms do not use the static mappings from Davinci + * IO_PHYS/IO_VIRT. This SOC's interesting MMRs are at different addresses, + * and changing IO_PHYS would break away from existing Davinci SOCs. + * + * The primary impact of the current model is that IO_ADDRESS() is not to be + * used to map registers on TNETV107X. + * + * 1. The first chunk is for INTC: This needs to be mapped in via iotable + * because ioremap() does not seem to be operational at the time when + * irqs are initialized. Without this, consistent dma init bombs. + * + * 2. The second chunk maps in register areas that need to be populated into + * davinci_soc_info. Note that alignment restrictions come into play if + * low-level debug is enabled (see note in <mach/tnetv107x.h>). + */ +static struct map_desc io_desc[] = { + { /* INTC */ + .virtual = IO_VIRT, + .pfn = __phys_to_pfn(TNETV107X_INTC_BASE), + .length = SZ_16K, + .type = MT_DEVICE + }, + { /* Most of the rest */ + .virtual = TNETV107X_IO_VIRT, + .pfn = __phys_to_pfn(TNETV107X_IO_BASE), + .length = IO_SIZE - SZ_1M, + .type = MT_DEVICE + }, +}; + +static unsigned long clk_sspll_recalc(struct clk *clk) +{ + int pll; + unsigned long mult = 0, prediv = 1, postdiv = 1; + unsigned long ref = OSC_FREQ_ONCHIP, ret; + u32 tmp; + + if (WARN_ON(!clk->pll_data)) + return clk->rate; + + if (!clk_ctrl_regs) { + void __iomem *tmp; + + tmp = ioremap(TNETV107X_CLOCK_CONTROL_BASE, SZ_4K); + + if (WARN(!tmp, "failed ioremap for clock control regs\n")) + return clk->parent ? clk->parent->rate : 0; + + for (pll = 0; pll < N_PLLS; pll++) + sspll_regs[pll] = tmp + sspll_regs_base[pll]; + + clk_ctrl_regs = tmp; + } + + pll = clk->pll_data->num; + + tmp = __raw_readl(&clk_ctrl_regs->pll_bypass); + if (!(tmp & bypass_mask[pll])) { + mult = __raw_readl(&sspll_regs[pll]->mult_factor); + prediv = __raw_readl(&sspll_regs[pll]->pre_div) + 1; + postdiv = __raw_readl(&sspll_regs[pll]->post_div) + 1; + } + + tmp = __raw_readl(clk->pll_data->base + PLLCTL); + if (tmp & PLLCTL_CLKMODE) + ref = pll_ext_freq[pll]; + + clk->pll_data->input_rate = ref; + + tmp = __raw_readl(clk->pll_data->base + PLLCTL); + if (!(tmp & PLLCTL_PLLEN)) + return ref; + + ret = ref; + if (mult) + ret += ((unsigned long long)ref * mult) / 256; + + ret /= (prediv * postdiv); + + return ret; +} + +static void tnetv107x_watchdog_reset(struct platform_device *pdev) +{ + struct wdt_regs __iomem *regs; + + regs = ioremap(pdev->resource[0].start, SZ_4K); + + /* disable watchdog */ + __raw_writel(0x7777, ®s->disable_lock); + __raw_writel(0xcccc, ®s->disable_lock); + __raw_writel(0xdddd, ®s->disable_lock); + __raw_writel(0, ®s->disable); + + /* program prescale */ + __raw_writel(0x5a5a, ®s->prescale_lock); + __raw_writel(0xa5a5, ®s->prescale_lock); + __raw_writel(0, ®s->prescale); + + /* program countdown */ + __raw_writel(0x6666, ®s->change_lock); + __raw_writel(0xbbbb, ®s->change_lock); + __raw_writel(1, ®s->change); + + /* enable watchdog */ + __raw_writel(0x7777, ®s->disable_lock); + __raw_writel(0xcccc, ®s->disable_lock); + __raw_writel(0xdddd, ®s->disable_lock); + __raw_writel(1, ®s->disable); + + /* kick */ + __raw_writel(0x5555, ®s->kick_lock); + __raw_writel(0xaaaa, ®s->kick_lock); + __raw_writel(1, ®s->kick); +} + +void tnetv107x_restart(char mode, const char *cmd) +{ + tnetv107x_watchdog_reset(&tnetv107x_wdt_device); +} + +static struct davinci_soc_info tnetv107x_soc_info = { + .io_desc = io_desc, + .io_desc_num = ARRAY_SIZE(io_desc), + .ids = ids, + .ids_num = ARRAY_SIZE(ids), + .jtag_id_reg = TNETV107X_CHIP_CFG_BASE + 0x018, + .cpu_clks = clks, + .psc_bases = psc_regs, + .psc_bases_num = ARRAY_SIZE(psc_regs), + .pinmux_base = TNETV107X_CHIP_CFG_BASE + 0x150, + .pinmux_pins = pins, + .pinmux_pins_num = ARRAY_SIZE(pins), + .intc_type = DAVINCI_INTC_TYPE_CP_INTC, + .intc_base = TNETV107X_INTC_BASE, + .intc_irq_prios = irq_prios, + .intc_irq_num = TNETV107X_N_CP_INTC_IRQ, + .intc_host_map = intc_host_map, + .gpio_base = TNETV107X_GPIO_BASE, + .gpio_type = GPIO_TYPE_TNETV107X, + .gpio_num = TNETV107X_N_GPIO, + .timer_info = &timer_info, + .serial_dev = &tnetv107x_serial_device, +}; + +void __init tnetv107x_init(void) +{ + davinci_common_init(&tnetv107x_soc_info); +} diff --git a/ANDROID_3.4.5/arch/arm/mach-davinci/usb.c b/ANDROID_3.4.5/arch/arm/mach-davinci/usb.c new file mode 100644 index 00000000..23d2b6d9 --- /dev/null +++ b/ANDROID_3.4.5/arch/arm/mach-davinci/usb.c @@ -0,0 +1,180 @@ +/* + * USB + */ +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/dma-mapping.h> + +#include <linux/usb/musb.h> + +#include <mach/common.h> +#include <mach/irqs.h> +#include <mach/cputype.h> +#include <mach/usb.h> + +#define DAVINCI_USB_OTG_BASE 0x01c64000 + +#define DA8XX_USB0_BASE 0x01e00000 +#define DA8XX_USB1_BASE 0x01e25000 + +#if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE) +static struct musb_hdrc_eps_bits musb_eps[] = { + { "ep1_tx", 8, }, + { "ep1_rx", 8, }, + { "ep2_tx", 8, }, + { "ep2_rx", 8, }, + { "ep3_tx", 5, }, + { "ep3_rx", 5, }, + { "ep4_tx", 5, }, + { "ep4_rx", 5, }, +}; + +static struct musb_hdrc_config musb_config = { + .multipoint = true, + .dyn_fifo = true, + .soft_con = true, + .dma = true, + + .num_eps = 5, + .dma_channels = 8, + .ram_bits = 10, + .eps_bits = musb_eps, +}; + +static struct musb_hdrc_platform_data usb_data = { +#if defined(CONFIG_USB_MUSB_OTG) + /* OTG requires a Mini-AB connector */ + .mode = MUSB_OTG, +#elif defined(CONFIG_USB_MUSB_PERIPHERAL) + .mode = MUSB_PERIPHERAL, +#elif defined(CONFIG_USB_MUSB_HOST) + .mode = MUSB_HOST, +#endif + .clock = "usb", + .config = &musb_config, +}; + +static struct resource usb_resources[] = { + { + /* physical address */ + .start = DAVINCI_USB_OTG_BASE, + .end = DAVINCI_USB_OTG_BASE + 0x5ff, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_USBINT, + .flags = IORESOURCE_IRQ, + .name = "mc" + }, + { + /* placeholder for the dedicated CPPI IRQ */ + .flags = IORESOURCE_IRQ, + .name = "dma" + }, +}; + +static u64 usb_dmamask = DMA_BIT_MASK(32); + +static struct platform_device usb_dev = { + .name = "musb-davinci", + .id = -1, + .dev = { + .platform_data = &usb_data, + .dma_mask = &usb_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = usb_resources, + .num_resources = ARRAY_SIZE(usb_resources), +}; + +void __init davinci_setup_usb(unsigned mA, unsigned potpgt_ms) +{ + usb_data.power = mA > 510 ? 255 : mA / 2; + usb_data.potpgt = (potpgt_ms + 1) / 2; + + if (cpu_is_davinci_dm646x()) { + /* Override the defaults as DM6467 uses different IRQs. */ + usb_dev.resource[1].start = IRQ_DM646X_USBINT; + usb_dev.resource[2].start = IRQ_DM646X_USBDMAINT; + } else /* other devices don't have dedicated CPPI IRQ */ + usb_dev.num_resources = 2; + + platform_device_register(&usb_dev); +} + +#ifdef CONFIG_ARCH_DAVINCI_DA8XX +static struct resource da8xx_usb20_resources[] = { + { + .start = DA8XX_USB0_BASE, + .end = DA8XX_USB0_BASE + SZ_64K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_DA8XX_USB_INT, + .flags = IORESOURCE_IRQ, + .name = "mc", + }, +}; + +int __init da8xx_register_usb20(unsigned mA, unsigned potpgt) +{ + usb_data.clock = "usb20"; + usb_data.power = mA > 510 ? 255 : mA / 2; + usb_data.potpgt = (potpgt + 1) / 2; + + usb_dev.resource = da8xx_usb20_resources; + usb_dev.num_resources = ARRAY_SIZE(da8xx_usb20_resources); + usb_dev.name = "musb-da8xx"; + + return platform_device_register(&usb_dev); +} +#endif /* CONFIG_DAVINCI_DA8XX */ + +#else + +void __init davinci_setup_usb(unsigned mA, unsigned potpgt_ms) +{ +} + +#ifdef CONFIG_ARCH_DAVINCI_DA8XX +int __init da8xx_register_usb20(unsigned mA, unsigned potpgt) +{ + return 0; +} +#endif + +#endif /* CONFIG_USB_MUSB_HDRC */ + +#ifdef CONFIG_ARCH_DAVINCI_DA8XX +static struct resource da8xx_usb11_resources[] = { + [0] = { + .start = DA8XX_USB1_BASE, + .end = DA8XX_USB1_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_DA8XX_IRQN, + .end = IRQ_DA8XX_IRQN, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 da8xx_usb11_dma_mask = DMA_BIT_MASK(32); + +static struct platform_device da8xx_usb11_device = { + .name = "ohci", + .id = 0, + .dev = { + .dma_mask = &da8xx_usb11_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .num_resources = ARRAY_SIZE(da8xx_usb11_resources), + .resource = da8xx_usb11_resources, +}; + +int __init da8xx_register_usb11(struct da8xx_ohci_root_hub *pdata) +{ + da8xx_usb11_device.dev.platform_data = pdata; + return platform_device_register(&da8xx_usb11_device); +} +#endif /* CONFIG_DAVINCI_DA8XX */ |