Fixed MTP to work with TWRP

This commit is contained in:
awab228 2018-06-19 23:16:04 +02:00
commit f6dfaef42e
50820 changed files with 20846062 additions and 0 deletions

View file

@ -0,0 +1,269 @@
if ARCH_DAVINCI
config AINTC
bool
config CP_INTC
bool
select IRQ_DOMAIN
config ARCH_DAVINCI_DMx
bool
select CPU_ARM926T
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 ARCH_DAVINCI_DA8XX
select CPU_DCACHE_WRITETHROUGH # needed on silicon revs 1.0, 1.1
select CP_INTC
config ARCH_DAVINCI_DA850
bool "DA850/OMAP-L138/AM18x based system"
select ARCH_DAVINCI_DA8XX
select CP_INTC
config ARCH_DAVINCI_DA8XX
bool
select CPU_ARM926T
config ARCH_DAVINCI_DM365
bool "DaVinci 365 based system"
select AINTC
select ARCH_DAVINCI_DMx
comment "DaVinci Board Type"
config MACH_DA8XX_DT
bool "Support DA8XX platforms using device tree"
default y
depends on ARCH_DAVINCI_DA8XX
select PINCTRL
help
Say y here to include support for TI DaVinci DA850 based using
Flattened Device Tree. More information at Documentation/devicetree
config MACH_DAVINCI_EVM
bool "TI DM644x EVM"
default ARCH_DAVINCI_DM644x
depends on ARCH_DAVINCI_DM644x
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 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 EEPROM_AT24
select I2C
select MACH_DAVINCI_DM6467TEVM
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 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 EEPROM_AT24
select GPIO_PCF857X
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.
config DA850_UI_SD_VIDEO_PORT
bool "Video Port Interface"
help
Say Y if you want to use Video Port Interface (VPIF) on the
DA850/OMAP-L138 EVM. The Video decoders/encoders are found on the
UI daughter card that is supplied with the EVM.
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 MACH_MITYOMAPL138
bool "Critical Link MityDSP-L138/MityARM-1808 SoM"
depends on ARCH_DAVINCI_DA850
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

View file

@ -0,0 +1,40 @@
#
# Makefile for the linux kernel.
#
#
# Common objects
obj-y := time.o clock.o serial.o psc.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_AINTC) += irq.o
obj-$(CONFIG_CP_INTC) += cp_intc.o
# Board specific
obj-$(CONFIG_MACH_DA8XX_DT) += da8xx-dt.o
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_MITYOMAPL138) += board-mityomapl138.o
obj-$(CONFIG_MACH_OMAPL138_HAWKBOARD) += board-omapl138-hawk.o
# Power Management
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
obj-$(CONFIG_SUSPEND) += pm.o sleep.o
obj-$(CONFIG_HAVE_CLK) += pm_domain.o

View file

@ -0,0 +1,7 @@
zreladdr-$(CONFIG_ARCH_DAVINCI_DA8XX) += 0xc0008000
params_phys-$(CONFIG_ARCH_DAVINCI_DA8XX) := 0xc0000100
initrd_phys-$(CONFIG_ARCH_DAVINCI_DA8XX) := 0xc0800000
zreladdr-$(CONFIG_ARCH_DAVINCI_DMx) += 0x80008000
params_phys-$(CONFIG_ARCH_DAVINCI_DMx) := 0x80000100
initrd_phys-$(CONFIG_ARCH_DAVINCI_DMx) := 0x80800000

View file

@ -0,0 +1,218 @@
/*
* 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 <linux/platform_data/mtd-davinci-aemif.h>
#include <linux/platform_data/mtd-davinci.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))
static inline unsigned int davinci_aemif_readl(void __iomem *base, int offset)
{
return readl_relaxed(base + offset);
}
static inline void davinci_aemif_writel(void __iomem *base,
int offset, unsigned long value)
{
writel_relaxed(value, base + offset);
}
/*
* 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
* @clkrate: the AEMIF clkrate
*
* 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.
*/
static int davinci_aemif_setup_timing(struct davinci_aemif_timing *t,
void __iomem *base, unsigned cs,
unsigned long clkrate)
{
unsigned set, val;
int ta, rhold, rstrobe, rsetup, whold, wstrobe, wsetup;
unsigned offset = A1CR_OFFSET + cs * 4;
if (!t)
return 0; /* Nothing to do */
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;
}
/**
* davinci_aemif_setup - setup AEMIF interface by davinci_nand_pdata
* @pdev - link to platform device to setup settings for
*
* 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(struct platform_device *pdev)
{
struct davinci_nand_pdata *pdata = dev_get_platdata(&pdev->dev);
uint32_t val;
unsigned long clkrate;
struct resource *res;
void __iomem *base;
struct clk *clk;
int ret = 0;
clk = clk_get(&pdev->dev, "aemif");
if (IS_ERR(clk)) {
ret = PTR_ERR(clk);
dev_dbg(&pdev->dev, "unable to get AEMIF clock, err %d\n", ret);
return ret;
}
ret = clk_prepare_enable(clk);
if (ret < 0) {
dev_dbg(&pdev->dev, "unable to enable AEMIF clock, err %d\n",
ret);
goto err_put;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
if (!res) {
dev_err(&pdev->dev, "cannot get IORESOURCE_MEM\n");
ret = -ENOMEM;
goto err;
}
base = ioremap(res->start, resource_size(res));
if (!base) {
dev_err(&pdev->dev, "ioremap failed for resource %pR\n", res);
ret = -ENOMEM;
goto err;
}
/*
* Setup Async configuration register in case we did not boot
* from NAND and so bootloader did not bother to set it up.
*/
val = davinci_aemif_readl(base, A1CR_OFFSET + pdev->id * 4);
/*
* Extended Wait is not valid and Select Strobe mode is not
* used
*/
val &= ~(ACR_ASIZE_MASK | ACR_EW_MASK | ACR_SS_MASK);
if (pdata->options & NAND_BUSWIDTH_16)
val |= 0x1;
davinci_aemif_writel(base, A1CR_OFFSET + pdev->id * 4, val);
clkrate = clk_get_rate(clk);
if (pdata->timing)
ret = davinci_aemif_setup_timing(pdata->timing, base, pdev->id,
clkrate);
if (ret < 0)
dev_dbg(&pdev->dev, "NAND timing values setup fail\n");
iounmap(base);
err:
clk_disable_unprepare(clk);
err_put:
clk_put(clk);
return ret;
}

View file

@ -0,0 +1,49 @@
/*
* TI DaVinci Audio definitions
*/
#ifndef __ASM_ARCH_DAVINCI_ASP_H
#define __ASM_ARCH_DAVINCI_ASP_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
#endif /* __ASM_ARCH_DAVINCI_ASP_H */

View file

@ -0,0 +1,692 @@
/*
* 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/platform_data/at24.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/spi/spi.h>
#include <linux/spi/flash.h>
#include <linux/platform_data/gpio-davinci.h>
#include <linux/platform_data/mtd-davinci.h>
#include <linux/platform_data/mtd-davinci-aemif.h>
#include <linux/platform_data/spi-davinci.h>
#include <linux/platform_data/usb-davinci.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <mach/common.h>
#include <mach/cp_intc.h>
#include <mach/mux.h>
#include <mach/da8xx.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_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 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,
};
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
};
#define HAS_MMC IS_ENABLED(CONFIG_MMC_DAVINCI)
#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");
if (davinci_aemif_setup(&da830_evm_nand_device))
pr_warn("%s: Cannot configure AEMIF.\n", __func__);
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_gpio();
if (ret)
pr_warn("da830_evm_init: GPIO init failed: %d\n", 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(da8xx_serial_device);
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 = spi_register_board_info(da830evm_spi_info,
ARRAY_SIZE(da830evm_spi_info));
if (ret)
pr_warn("%s: spi info registration failed: %d\n", __func__,
ret);
ret = da8xx_register_spi_bus(0, 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,
.init_time = davinci_timer_init,
.init_machine = da830_evm_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
.restart = da8xx_restart,
MACHINE_END

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,428 @@
/*
* 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 <linux/platform_data/gpio-davinci.h>
#include <linux/platform_data/i2c-davinci.h>
#include <linux/platform_data/mtd-davinci.h>
#include <linux/platform_data/mmc-davinci.h>
#include <linux/platform_data/usb-davinci.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <mach/serial.h>
#include <mach/common.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",
};
/* venc standards timings */
static struct vpbe_enc_mode_info dm355evm_enc_preset_timing[] = {
{
.name = "ntsc",
.timings_type = VPBE_ENC_STD,
.std_id = V4L2_STD_NTSC,
.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,
.std_id = V4L2_STD_PAL,
.interlaced = 1,
.xres = 720,
.yres = 576,
.aspect = {54, 59},
.fps = {25, 1},
.left_margin = 0x7E,
.upper_margin = 0x16
},
};
#define VENC_STD_ALL (V4L2_STD_NTSC | V4L2_STD_PAL)
/*
* The outputs available from VPBE + ecnoders. Keep the
* 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. Application uses index of the array to set an output.
*/
static struct vpbe_output dm355evm_vpbe_outputs[] = {
{
.output = {
.index = 0,
.name = "Composite",
.type = V4L2_OUTPUT_TYPE_ANALOG,
.std = VENC_STD_ALL,
.capabilities = V4L2_OUT_CAP_STD,
},
.subdev_name = DM355_VPBE_VENC_SUBDEV_NAME,
.default_mode = "ntsc",
.num_modes = ARRAY_SIZE(dm355evm_enc_preset_timing),
.modes = dm355evm_enc_preset_timing,
.if_params = V4L2_MBUS_FMT_FIXED,
},
};
static struct vpbe_config dm355evm_display_cfg = {
.module_name = "dm355-vpbe-display",
.i2c_adapter_id = 1,
.osd = {
.module_name = DM355_VPBE_OSD_SUBDEV_NAME,
},
.venc = {
.module_name = DM355_VPBE_VENC_SUBDEV_NAME,
},
.num_outputs = ARRAY_SIZE(dm355evm_vpbe_outputs),
.outputs = dm355evm_vpbe_outputs,
};
static struct platform_device *davinci_evm_devices[] __initdata = {
&dm355evm_dm9000,
&davinci_nand_device,
};
static void __init dm355_evm_map_io(void)
{
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,
};
/* 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.
*/
#define USB_ID_VALUE 1 /* ID pulled low */
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;
int ret;
ret = dm355_gpio_register();
if (ret)
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
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_prepare_enable(aemif);
platform_add_devices(davinci_evm_devices,
ARRAY_SIZE(davinci_evm_devices));
evm_init_i2c();
davinci_serial_init(dm355_serial_device);
/* 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_video(&vpfe_cfg, &dm355evm_display_cfg);
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,
.init_time = davinci_timer_init,
.init_machine = dm355_evm_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
.restart = davinci_restart,
MACHINE_END

View file

@ -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 <linux/platform_data/i2c-davinci.h>
#include <linux/platform_data/mmc-davinci.h>
#include <linux/platform_data/mtd-davinci.h>
#include <linux/platform_data/usb-davinci.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <mach/common.h>
#include <mach/serial.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,
.ecc_bits = 4,
.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 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.
*/
#define USB_ID_VALUE 1 /* ID pulled low */
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;
int ret;
ret = dm355_gpio_register();
if (ret)
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
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_prepare_enable(aemif);
platform_add_devices(davinci_leopard_devices,
ARRAY_SIZE(davinci_leopard_devices));
leopard_init_i2c();
davinci_serial_init(dm355_serial_device);
/* 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,
.init_time = davinci_timer_init,
.init_machine = dm355_leopard_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
.restart = davinci_restart,
MACHINE_END

View file

@ -0,0 +1,787 @@
/*
* 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/platform_data/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 <linux/v4l2-dv-timings.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <mach/mux.h>
#include <mach/common.h>
#include <linux/platform_data/i2c-davinci.h>
#include <mach/serial.h>
#include <linux/platform_data/mmc-davinci.h>
#include <linux/platform_data/mtd-davinci.h>
#include <linux/platform_data/keyscan-davinci.h>
#include <media/ths7303.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 __maybe_unused = {
.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,
};
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",
};
/* venc standards timings */
static struct vpbe_enc_mode_info dm365evm_enc_std_timing[] = {
{
.name = "ntsc",
.timings_type = VPBE_ENC_STD,
.std_id = V4L2_STD_NTSC,
.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,
.std_id = V4L2_STD_PAL,
.interlaced = 1,
.xres = 720,
.yres = 576,
.aspect = {54, 59},
.fps = {25, 1},
.left_margin = 0x7E,
.upper_margin = 0x16,
},
};
/* venc dv timings */
static struct vpbe_enc_mode_info dm365evm_enc_preset_timing[] = {
{
.name = "480p59_94",
.timings_type = VPBE_ENC_DV_TIMINGS,
.dv_timings = V4L2_DV_BT_CEA_720X480P59_94,
.interlaced = 0,
.xres = 720,
.yres = 480,
.aspect = {1, 1},
.fps = {5994, 100},
.left_margin = 0x8F,
.upper_margin = 0x2D,
},
{
.name = "576p50",
.timings_type = VPBE_ENC_DV_TIMINGS,
.dv_timings = V4L2_DV_BT_CEA_720X576P50,
.interlaced = 0,
.xres = 720,
.yres = 576,
.aspect = {1, 1},
.fps = {50, 1},
.left_margin = 0x8C,
.upper_margin = 0x36,
},
{
.name = "720p60",
.timings_type = VPBE_ENC_DV_TIMINGS,
.dv_timings = V4L2_DV_BT_CEA_1280X720P60,
.interlaced = 0,
.xres = 1280,
.yres = 720,
.aspect = {1, 1},
.fps = {60, 1},
.left_margin = 0x117,
.right_margin = 70,
.upper_margin = 38,
.lower_margin = 3,
.hsync_len = 80,
.vsync_len = 5,
},
{
.name = "1080i60",
.timings_type = VPBE_ENC_DV_TIMINGS,
.dv_timings = V4L2_DV_BT_CEA_1920X1080I60,
.interlaced = 1,
.xres = 1920,
.yres = 1080,
.aspect = {1, 1},
.fps = {30, 1},
.left_margin = 0xc9,
.right_margin = 80,
.upper_margin = 30,
.lower_margin = 3,
.hsync_len = 88,
.vsync_len = 5,
},
};
#define VENC_STD_ALL (V4L2_STD_NTSC | V4L2_STD_PAL)
/*
* The outputs available from VPBE + ecnoders. Keep the
* 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. Application uses index of the array to set an output.
*/
static struct vpbe_output dm365evm_vpbe_outputs[] = {
{
.output = {
.index = 0,
.name = "Composite",
.type = V4L2_OUTPUT_TYPE_ANALOG,
.std = VENC_STD_ALL,
.capabilities = V4L2_OUT_CAP_STD,
},
.subdev_name = DM365_VPBE_VENC_SUBDEV_NAME,
.default_mode = "ntsc",
.num_modes = ARRAY_SIZE(dm365evm_enc_std_timing),
.modes = dm365evm_enc_std_timing,
.if_params = V4L2_MBUS_FMT_FIXED,
},
{
.output = {
.index = 1,
.name = "Component",
.type = V4L2_OUTPUT_TYPE_ANALOG,
.capabilities = V4L2_OUT_CAP_DV_TIMINGS,
},
.subdev_name = DM365_VPBE_VENC_SUBDEV_NAME,
.default_mode = "480p59_94",
.num_modes = ARRAY_SIZE(dm365evm_enc_preset_timing),
.modes = dm365evm_enc_preset_timing,
.if_params = V4L2_MBUS_FMT_FIXED,
},
};
/*
* Amplifiers on the board
*/
static struct ths7303_platform_data ths7303_pdata = {
.ch_1 = 3,
.ch_2 = 3,
.ch_3 = 3,
};
static struct amp_config_info vpbe_amp = {
.module_name = "ths7303",
.is_i2c = 1,
.board_info = {
I2C_BOARD_INFO("ths7303", 0x2c),
.platform_data = &ths7303_pdata,
}
};
static struct vpbe_config dm365evm_display_cfg = {
.module_name = "dm365-vpbe-display",
.i2c_adapter_id = 1,
.amp = &vpbe_amp,
.osd = {
.module_name = DM365_VPBE_OSD_SUBDEV_NAME,
},
.venc = {
.module_name = DM365_VPBE_VENC_SUBDEV_NAME,
},
.num_outputs = ARRAY_SIZE(dm365evm_vpbe_outputs),
.outputs = dm365evm_vpbe_outputs,
};
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_prepare_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_unprepare(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 void __init dm365_evm_map_io(void)
{
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)
{
int ret;
ret = dm365_gpio_register();
if (ret)
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
evm_init_i2c();
davinci_serial_init(dm365_serial_device);
dm365evm_emac_configure();
dm365evm_mmc_configure();
davinci_setup_mmc(0, &dm365evm_mmc_config);
dm365_init_video(&vpfe_cfg, &dm365evm_display_cfg);
/* 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,
.init_time = davinci_timer_init,
.init_machine = dm365_evm_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
.restart = davinci_restart,
MACHINE_END

View file

@ -0,0 +1,825 @@
/*
* 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/platform_data/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/v4l2-dv-timings.h>
#include <linux/export.h>
#include <media/tvp514x.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <mach/common.h>
#include <linux/platform_data/i2c-davinci.h>
#include <mach/serial.h>
#include <mach/mux.h>
#include <linux/platform_data/mtd-davinci.h>
#include <linux/platform_data/mmc-davinci.h>
#include <linux/platform_data/usb-davinci.h>
#include <linux/platform_data/mtd-davinci-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,
.ecc_bits = 1,
.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] = {
{
.flags = 0,
.len = 2,
.buf = (void __force *)txbuf,
},
{
.flags = I2C_M_RD,
.len = 4,
.buf = buf,
},
};
int status;
if (!dm6446evm_msp)
return -ENXIO;
msg[0].addr = dm6446evm_msp->addr;
msg[1].addr = dm6446evm_msp->addr;
/* 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,
};
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,
.std_id = V4L2_STD_NTSC,
.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,
.std_id = V4L2_STD_PAL,
.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_TIMINGS,
.dv_timings = V4L2_DV_BT_CEA_720X480P59_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_TIMINGS,
.dv_timings = V4L2_DV_BT_CEA_720X576P50,
.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 = DM644X_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_DV_TIMINGS,
},
.subdev_name = DM644X_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 = DM644X_VPBE_OSD_SUBDEV_NAME,
},
.venc = {
.module_name = DM644X_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 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;
}
#define HAS_ATA IS_ENABLED(CONFIG_BLK_DEV_PALMCHIP_BK3710)
#define HAS_NOR IS_ENABLED(CONFIG_MTD_PHYSMAP)
#define HAS_NAND IS_ENABLED(CONFIG_MTD_NAND_DAVINCI)
static __init void davinci_evm_init(void)
{
int ret;
struct clk *aemif_clk;
struct davinci_soc_info *soc_info = &davinci_soc_info;
ret = dm644x_gpio_register();
if (ret)
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
aemif_clk = clk_get(NULL, "aemif");
clk_prepare_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);
if (davinci_aemif_setup(&davinci_evm_nandflash_device))
pr_warn("%s: Cannot configure AEMIF.\n",
__func__);
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(dm644x_serial_device);
dm644x_init_asp(&dm644x_evm_snd_data);
/* irlml6401 switches over 1A, in under 8 msec */
davinci_setup_usb(1000, 8);
if (IS_BUILTIN(CONFIG_PHYLIB)) {
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,
.init_time = davinci_timer_init,
.init_machine = davinci_evm_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
.restart = davinci_restart,
MACHINE_END

View file

@ -0,0 +1,840 @@
/*
* 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/platform_data/at24.h>
#include <linux/i2c/pcf857x.h>
#include <media/tvp514x.h>
#include <media/adv7343.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 <linux/platform_data/gpio-davinci.h>
#include <linux/platform_data/i2c-davinci.h>
#include <linux/platform_data/mtd-davinci.h>
#include <linux/platform_data/mtd-davinci-aemif.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <mach/common.h>
#include <mach/irqs.h>
#include <mach/serial.h>
#include <mach/clock.h>
#include <mach/cdce949.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,
.ecc_bits = 1,
.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,
},
};
#define HAS_ATA IS_ENABLED(CONFIG_BLK_DEV_PALMCHIP_BK3710)
/* 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 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 struct vpif_output dm6467_ch0_outputs[] = {
{
.output = {
.index = 0,
.name = "Composite",
.type = V4L2_OUTPUT_TYPE_ANALOG,
.capabilities = V4L2_OUT_CAP_STD,
.std = V4L2_STD_ALL,
},
.subdev_name = "adv7343",
.output_route = ADV7343_COMPOSITE_ID,
},
{
.output = {
.index = 1,
.name = "Component",
.type = V4L2_OUTPUT_TYPE_ANALOG,
.capabilities = V4L2_OUT_CAP_DV_TIMINGS,
},
.subdev_name = "adv7343",
.output_route = ADV7343_COMPONENT_ID,
},
{
.output = {
.index = 2,
.name = "S-Video",
.type = V4L2_OUTPUT_TYPE_ANALOG,
.capabilities = V4L2_OUT_CAP_STD,
.std = V4L2_STD_ALL,
},
.subdev_name = "adv7343",
.output_route = ADV7343_SVIDEO_ID,
},
};
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),
.chan_config[0] = {
.outputs = dm6467_ch0_outputs,
.output_count = ARRAY_SIZE(dm6467_ch0_outputs),
},
.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,
},
},
{
.name = TVP5147_CH1,
.board_info = {
I2C_BOARD_INFO("tvp5146", 0x5c),
.platform_data = &tvp5146_pdata,
},
},
};
static const struct vpif_input dm6467_ch0_inputs[] = {
{
.input = {
.index = 0,
.name = "Composite",
.type = V4L2_INPUT_TYPE_CAMERA,
.capabilities = V4L2_IN_CAP_STD,
.std = TVP514X_STD_ALL,
},
.subdev_name = TVP5147_CH0,
.input_route = INPUT_CVBS_VI2B,
.output_route = OUTPUT_10BIT_422_EMBEDDED_SYNC,
},
};
static const struct vpif_input dm6467_ch1_inputs[] = {
{
.input = {
.index = 0,
.name = "S-Video",
.type = V4L2_INPUT_TYPE_CAMERA,
.capabilities = V4L2_IN_CAP_STD,
.std = TVP514X_STD_ALL,
},
.subdev_name = TVP5147_CH1,
.input_route = INPUT_SVIDEO_VI2C_VI1C,
.output_route = OUTPUT_10BIT_422_EMBEDDED_SYNC,
},
};
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),
.vpif_if = {
.if_type = VPIF_IF_BT656,
.hd_pol = 1,
.vd_pol = 1,
.fid_pol = 0,
},
},
.chan_config[1] = {
.inputs = dm6467_ch1_inputs,
.input_count = ARRAY_SIZE(dm6467_ch1_inputs),
.vpif_if = {
.if_type = VPIF_IF_BT656,
.hd_pol = 1,
.vd_pol = 1,
.fid_pol = 0,
},
},
};
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();
}
#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)
{
int ret;
struct davinci_soc_info *soc_info = &davinci_soc_info;
ret = dm646x_gpio_register();
if (ret)
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
evm_init_i2c();
davinci_serial_init(dm646x_serial_device);
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);
if (davinci_aemif_setup(&davinci_nand_device))
pr_warn("%s: Cannot configure AEMIF.\n", __func__);
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,
.init_time = davinci_timer_init,
.init_machine = evm_init,
.init_late = davinci_init_late,
.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,
.init_time = davinci_timer_init,
.init_machine = evm_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
.restart = davinci_restart,
MACHINE_END

View file

@ -0,0 +1,583 @@
/*
* 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/platform_data/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 <linux/platform_data/mtd-davinci.h>
#include <linux/platform_data/mtd-davinci-aemif.h>
#include <mach/mux.h>
#include <linux/platform_data/spi-davinci.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));
if (davinci_aemif_setup(&mityomapl138_nandflash_device))
pr_warn("%s: Cannot configure AEMIF.\n", __func__);
}
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(da8xx_serial_device);
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 = spi_register_board_info(mityomapl138_spi_flash_info,
ARRAY_SIZE(mityomapl138_spi_flash_info));
if (ret)
pr_warn("spi info registration failed: %d\n", ret);
ret = da8xx_register_spi_bus(1,
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,
.init_time = davinci_timer_init,
.init_machine = mityomapl138_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
.restart = da8xx_restart,
MACHINE_END

View file

@ -0,0 +1,236 @@
/*
* 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 <linux/platform_data/gpio-davinci.h>
#include <linux/platform_data/i2c-davinci.h>
#include <linux/platform_data/mmc-davinci.h>
#include <linux/platform_data/mtd-davinci.h>
#include <linux/platform_data/usb-davinci.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <mach/common.h>
#include <mach/serial.h>
#include <mach/mux.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,
.ecc_bits = 1,
.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 void __init davinci_ntosd2_map_io(void)
{
dm644x_init();
}
static struct davinci_mmc_config davinci_ntosd2_mmc_config = {
.wires = 4,
};
#define HAS_ATA IS_ENABLED(CONFIG_BLK_DEV_PALMCHIP_BK3710)
#define HAS_NAND IS_ENABLED(CONFIG_MTD_NAND_DAVINCI)
static __init void davinci_ntosd2_init(void)
{
int ret;
struct clk *aemif_clk;
struct davinci_soc_info *soc_info = &davinci_soc_info;
ret = dm644x_gpio_register();
if (ret)
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
aemif_clk = clk_get(NULL, "aemif");
clk_prepare_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));
davinci_serial_init(dm644x_serial_device);
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,
.init_time = davinci_timer_init,
.init_machine = davinci_ntosd2_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
.restart = davinci_restart,
MACHINE_END

View file

@ -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 <linux/platform_data/gpio-davinci.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/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_warn("%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_warn("%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,
};
static __init void omapl138_hawk_mmc_init(void)
{
int ret;
ret = davinci_cfg_reg_list(hawk_mmcsd0_pins);
if (ret) {
pr_warn("%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_warn("%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_warn("%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_warn("%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_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_warn("%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_warn("%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 __init void omapl138_hawk_init(void)
{
int ret;
ret = da850_register_gpio();
if (ret)
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
davinci_serial_init(da8xx_serial_device);
omapl138_hawk_config_emac();
ret = da850_register_edma(da850_edma_rsv);
if (ret)
pr_warn("%s: EDMA registration failed: %d\n", __func__, ret);
omapl138_hawk_mmc_init();
omapl138_hawk_usb_init();
ret = da8xx_register_watchdog();
if (ret)
pr_warn("%s: watchdog registration failed: %d\n",
__func__, ret);
ret = da8xx_register_rproc();
if (ret)
pr_warn("%s: dsp/rproc registration failed: %d\n",
__func__, 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,
.init_time = davinci_timer_init,
.init_machine = omapl138_hawk_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
.restart = da8xx_restart,
.reserve = da8xx_rproc_reserve_cma,
MACHINE_END

View file

@ -0,0 +1,158 @@
/*
* 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/platform_data/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 <linux/platform_data/i2c-davinci.h>
#include <mach/serial.h>
#include <mach/mux.h>
#include <linux/platform_data/usb-davinci.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 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(dm644x_serial_device);
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")
.atag_offset = 0x100,
.map_io = davinci_sffsdr_map_io,
.init_irq = davinci_irq_init,
.init_time = davinci_timer_init,
.init_machine = davinci_sffsdr_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
.restart = davinci_restart,
MACHINE_END

View file

@ -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 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 = 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");

View file

@ -0,0 +1,713 @@
/*
* 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) {
if (clk->flags & CLK_PSC)
davinci_psc_config(clk->domain, clk->gpsc, clk->lpsc,
true, clk->flags);
else if (clk->clk_enable)
clk->clk_enable(clk);
}
}
static void __clk_disable(struct clk *clk)
{
if (WARN_ON(clk->usecount == 0))
return;
if (--clk->usecount == 0) {
if (!(clk->flags & CLK_PLL) && (clk->flags & CLK_PSC))
davinci_psc_config(clk->domain, clk->gpsc, clk->lpsc,
false, clk->flags);
else if (clk->clk_disable)
clk->clk_disable(clk);
}
if (clk->parent)
__clk_disable(clk->parent);
}
int davinci_clk_reset(struct clk *clk, bool reset)
{
unsigned long flags;
if (clk == NULL || IS_ERR(clk))
return -EINVAL;
spin_lock_irqsave(&clockfw_lock, flags);
if (clk->flags & CLK_PSC)
davinci_psc_reset(clk->gpsc, clk->lpsc, reset);
spin_unlock_irqrestore(&clockfw_lock, flags);
return 0;
}
EXPORT_SYMBOL(davinci_clk_reset);
int davinci_clk_reset_assert(struct clk *clk)
{
if (clk == NULL || IS_ERR(clk) || !clk->reset)
return -EINVAL;
return clk->reset(clk, true);
}
EXPORT_SYMBOL(davinci_clk_reset_assert);
int davinci_clk_reset_deassert(struct clk *clk)
{
if (clk == NULL || IS_ERR(clk) || !clk->reset)
return -EINVAL;
return clk->reset(clk, false);
}
EXPORT_SYMBOL(davinci_clk_reset_deassert);
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 0;
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
*/
int __init davinci_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;
}
#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;
if (clk->flags & PSC_LRST)
clk->reset = davinci_clk_reset;
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 */

View file

@ -0,0 +1,140 @@
/*
* 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);
int (*reset) (struct clk *clk, bool reset);
void (*clk_enable) (struct clk *clk);
void (*clk_disable) (struct clk *clk);
};
/* 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 PSC_LRST BIT(8) /* Use local reset on enable/disable */
#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);
int davinci_clk_reset(struct clk *clk, bool reset);
extern struct platform_device davinci_wdt_device;
extern void davinci_watchdog_reset(struct platform_device *);
#endif
#endif

View file

@ -0,0 +1,124 @@
/*
* 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);
/*
* 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");
}
void __init davinci_init_late(void)
{
davinci_cpufreq_init();
davinci_pm_init();
davinci_clk_disable_unused();
}

View file

@ -0,0 +1,222 @@
/*
* 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/export.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/irqdomain.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.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->hwirq, 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->hwirq, 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->hwirq, 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->hwirq);
unsigned mask = BIT_MASK(d->hwirq);
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,
};
static struct irq_domain *cp_intc_domain;
static int cp_intc_host_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw)
{
pr_debug("cp_intc_host_map(%d, 0x%lx)\n", virq, hw);
irq_set_chip(virq, &cp_intc_irq_chip);
set_irq_flags(virq, IRQF_VALID | IRQF_PROBE);
irq_set_handler(virq, handle_edge_irq);
return 0;
}
static const struct irq_domain_ops cp_intc_host_ops = {
.map = cp_intc_host_map,
.xlate = irq_domain_xlate_onetwocell,
};
int __init cp_intc_of_init(struct device_node *node, struct device_node *parent)
{
u32 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, irq_base;
davinci_intc_type = DAVINCI_INTC_TYPE_CP_INTC;
if (node) {
davinci_intc_base = of_iomap(node, 0);
if (of_property_read_u32(node, "ti,intc-size", &num_irq))
pr_warn("unable to get intc-size, default to %d\n",
num_irq);
} else {
davinci_intc_base = ioremap(davinci_soc_info.intc_base, SZ_8K);
}
if (WARN_ON(!davinci_intc_base))
return -EINVAL;
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));
irq_base = irq_alloc_descs(-1, 0, num_irq, 0);
if (irq_base < 0) {
pr_warn("Couldn't allocate IRQ numbers\n");
irq_base = 0;
}
/* create a legacy host */
cp_intc_domain = irq_domain_add_legacy(node, num_irq,
irq_base, 0, &cp_intc_host_ops, NULL);
if (!cp_intc_domain) {
pr_err("cp_intc: failed to allocate irq host!\n");
return -EINVAL;
}
/* Enable global interrupt */
cp_intc_write(1, CP_INTC_GLOBAL_ENABLE);
return 0;
}
void __init cp_intc_init(void)
{
cp_intc_of_init(NULL, NULL);
}

View file

@ -0,0 +1,105 @@
/*
* 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
static void __iomem *ddr2_reg_base;
static bool ddr2_pdown;
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);
}
/* 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)
{
davinci_save_ddr_power(1, ddr2_pdown);
cpu_do_idle();
davinci_save_ddr_power(0, ddr2_pdown);
return index;
}
static struct cpuidle_driver davinci_idle_driver = {
.name = "cpuidle-davinci",
.owner = THIS_MODULE,
.states[0] = ARM_CPUIDLE_WFI_STATE,
.states[1] = {
.enter = davinci_enter_idle,
.exit_latency = 10,
.target_residency = 10000,
.flags = CPUIDLE_FLAG_TIME_VALID,
.name = "DDR SR",
.desc = "WFI and DDR Self Refresh",
},
.state_count = DAVINCI_CPUIDLE_MAX_STATES,
};
static int __init davinci_cpuidle_probe(struct platform_device *pdev)
{
struct davinci_cpuidle_config *pdata = pdev->dev.platform_data;
if (!pdata) {
dev_err(&pdev->dev, "cannot get platform data\n");
return -ENOENT;
}
ddr2_reg_base = pdata->ddr2_ctlr_base;
ddr2_pdown = pdata->ddr2_pdown;
return cpuidle_register(&davinci_idle_driver, NULL);
}
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);

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,79 @@
/*
* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
*
* Modified from mach-omap/omap2/board-generic.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/io.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/irqdomain.h>
#include <asm/mach/arch.h>
#include <mach/common.h>
#include <mach/cp_intc.h>
#include <mach/da8xx.h>
#define DA8XX_NUM_UARTS 3
static struct of_device_id da8xx_irq_match[] __initdata = {
{ .compatible = "ti,cp-intc", .data = cp_intc_of_init, },
{ }
};
static void __init da8xx_init_irq(void)
{
of_irq_init(da8xx_irq_match);
}
static struct of_dev_auxdata da850_auxdata_lookup[] __initdata = {
OF_DEV_AUXDATA("ti,davinci-i2c", 0x01c22000, "i2c_davinci.1", NULL),
OF_DEV_AUXDATA("ti,davinci-wdt", 0x01c21000, "davinci-wdt", NULL),
OF_DEV_AUXDATA("ti,da830-mmc", 0x01c40000, "da830-mmc.0", NULL),
OF_DEV_AUXDATA("ti,da850-ehrpwm", 0x01f00000, "ehrpwm", NULL),
OF_DEV_AUXDATA("ti,da850-ehrpwm", 0x01f02000, "ehrpwm", NULL),
OF_DEV_AUXDATA("ti,da850-ecap", 0x01f06000, "ecap", NULL),
OF_DEV_AUXDATA("ti,da850-ecap", 0x01f07000, "ecap", NULL),
OF_DEV_AUXDATA("ti,da850-ecap", 0x01f08000, "ecap", NULL),
OF_DEV_AUXDATA("ti,da830-spi", 0x01f0e000, "spi_davinci.1", NULL),
OF_DEV_AUXDATA("ns16550a", 0x01c42000, "serial8250.0", NULL),
OF_DEV_AUXDATA("ns16550a", 0x01d0c000, "serial8250.1", NULL),
OF_DEV_AUXDATA("ns16550a", 0x01d0d000, "serial8250.2", NULL),
OF_DEV_AUXDATA("ti,davinci_mdio", 0x01e24000, "davinci_mdio.0", NULL),
OF_DEV_AUXDATA("ti,davinci-dm6467-emac", 0x01e20000, "davinci_emac.1",
NULL),
OF_DEV_AUXDATA("ti,da830-mcasp-audio", 0x01d00000, "davinci-mcasp.0", NULL),
{}
};
#ifdef CONFIG_ARCH_DAVINCI_DA850
static void __init da850_init_machine(void)
{
of_platform_populate(NULL, of_default_bus_match_table,
da850_auxdata_lookup, NULL);
}
static const char *da850_boards_compat[] __initdata = {
"enbw,cmc",
"ti,da850-evm",
"ti,da850",
NULL,
};
DT_MACHINE_START(DA850_DT, "Generic DA850/OMAP-L138/AM18x")
.map_io = da850_init,
.init_irq = da8xx_init_irq,
.init_time = davinci_timer_init,
.init_machine = da850_init_machine,
.dt_compat = da850_boards_compat,
.init_late = davinci_init_late,
.restart = da8xx_restart,
MACHINE_END
#endif

View file

@ -0,0 +1,123 @@
/*
* 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 <linux/platform_data/davinci_asp.h>
#include <linux/platform_data/edma.h>
#include <linux/platform_data/keyscan-davinci.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_VDAC_CONFIG 0x2c
#define SYSMOD_VIDCLKCTL 0x38
#define SYSMOD_VPSS_CLKCTL 0x44
#define SYSMOD_VDD3P3VPWDN 0x48
#define SYSMOD_VSCLKDIS 0x6c
#define SYSMOD_PUPDCTL1 0x7c
/* VPSS CLKCTL bit definitions */
#define VPSS_MUXSEL_EXTCLK_ENABLE BIT(1)
#define VPSS_VENCCLKEN_ENABLE BIT(3)
#define VPSS_DACCLKEN_ENABLE BIT(4)
#define VPSS_PLLC2SYSCLK5_ENABLE BIT(5)
extern void __iomem *davinci_sysmod_base;
#define DAVINCI_SYSMOD_VIRT(x) (davinci_sysmod_base + (x))
void davinci_map_sysmod(void);
#define DAVINCI_GPIO_BASE 0x01C67000
int davinci_gpio_register(struct resource *res, int size, void *pdata);
/* 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
int davinci_init_wdt(void);
/* DM355 function declarations */
void dm355_init(void);
void dm355_init_spi0(unsigned chipselect_mask,
const struct spi_board_info *info, unsigned len);
void dm355_init_asp1(u32 evt_enable, struct snd_platform_data *pdata);
int dm355_init_video(struct vpfe_config *, struct vpbe_config *);
int dm355_gpio_register(void);
/* DM365 function declarations */
void dm365_init(void);
void dm365_init_asp(struct snd_platform_data *pdata);
void dm365_init_vc(struct snd_platform_data *pdata);
void dm365_init_ks(struct davinci_ks_platform_data *pdata);
void dm365_init_rtc(void);
void dm365_init_spi0(unsigned chipselect_mask,
const struct spi_board_info *info, unsigned len);
int dm365_init_video(struct vpfe_config *, struct vpbe_config *);
int dm365_gpio_register(void);
/* DM644x function declarations */
void dm644x_init(void);
void dm644x_init_asp(struct snd_platform_data *pdata);
int dm644x_init_video(struct vpfe_config *, struct vpbe_config *);
int dm644x_gpio_register(void);
/* DM646x function declarations */
void dm646x_init(void);
void dm646x_init_mcasp0(struct snd_platform_data *pdata);
void dm646x_init_mcasp1(struct snd_platform_data *pdata);
int 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 *);
int dm646x_gpio_register(void);
extern struct platform_device dm365_serial_device[];
extern struct platform_device dm355_serial_device[];
extern struct platform_device dm644x_serial_device[];
extern struct platform_device dm646x_serial_device[];
#endif /*__DAVINCI_H */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,350 @@
/*
* 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 <linux/reboot.h>
#include <mach/hardware.h>
#include <linux/platform_data/i2c-davinci.h>
#include <mach/irqs.h>
#include <mach/cputype.h>
#include <mach/mux.h>
#include <linux/platform_data/mmc-davinci.h>
#include <mach/time.h>
#include <linux/platform_data/edma.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
#define DAVINCI_DMA_MMCRXEVT 26
#define DAVINCI_DMA_MMCTXEVT 27
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 IS_ENABLED(CONFIG_MMC_DAVINCI)
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 = "dm6441-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 = "dm6441-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;
davinci_mmcsd1_device.name = "da830-mmc";
} 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;
davinci_mmcsd0_device.name = "da830-mmc";
} 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 = "davinci-wdt",
.id = -1,
.num_resources = ARRAY_SIZE(wdt_resources),
.resource = wdt_resources,
};
void davinci_restart(enum reboot_mode mode, const char *cmd)
{
davinci_watchdog_reset(&davinci_wdt_device);
}
int davinci_init_wdt(void)
{
return platform_device_register(&davinci_wdt_device);
}
static struct platform_device davinci_gpio_device = {
.name = "davinci_gpio",
.id = -1,
};
int davinci_gpio_register(struct resource *res, int size, void *pdata)
{
davinci_gpio_device.resource = res;
davinci_gpio_device.num_resources = size;
davinci_gpio_device.dev.platform_data = pdata;
return platform_device_register(&davinci_gpio_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,
},
};

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,969 @@
/*
* 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 <linux/platform_data/edma.h>
#include <linux/platform_data/gpio-davinci.h>
#include <asm/mach/map.h>
#include <mach/cputype.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 "davinci.h"
#include "clock.h"
#include "mux.h"
#include "asp.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("vpss", "master", &vpss_master_clk),
CLK("vpss", "slave", &vpss_slave_clk),
CLK(NULL, "arm", &arm_clk),
CLK("serial8250.0", NULL, &uart0_clk),
CLK("serial8250.1", NULL, &uart1_clk),
CLK("serial8250.2", NULL, &uart2_clk),
CLK("davinci_emac.1", NULL, &emac_clk),
CLK("davinci_mdio.0", "fck", &emac_clk),
CLK("i2c_davinci.1", NULL, &i2c_clk),
CLK("palm_bk3710", NULL, &ide_clk),
CLK("davinci-mcbsp", NULL, &asp_clk),
CLK("dm6441-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("davinci-wdt", 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 s8
queue_priority_mapping[][2] = {
/* {event queue no, Priority} */
{0, 3},
{1, 7},
{-1, -1},
};
static struct edma_soc_info edma_cc0_info = {
.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[] = {
{
.name = "mpu",
.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 platform_device dm644x_osd_dev = {
.name = DM644X_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),
},
};
#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 pclock)
{
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_TIMINGS:
if (pclock <= 27000000) {
v |= DM644X_VPSS_DACCLKEN;
writel(v, DAVINCI_SYSMOD_VIRT(SYSMOD_VPSS_CLKCTL));
} else {
/*
* 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;
}
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 = {
.setup_clock = dm644x_venc_setup_clock,
};
static struct platform_device dm644x_venc_dev = {
.name = DM644X_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 resource dm644_gpio_resources[] = {
{ /* registers */
.start = DAVINCI_GPIO_BASE,
.end = DAVINCI_GPIO_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
{ /* interrupt */
.start = IRQ_GPIOBNK0,
.end = IRQ_GPIOBNK4,
.flags = IORESOURCE_IRQ,
},
};
static struct davinci_gpio_platform_data dm644_gpio_platform_data = {
.ngpio = 71,
};
int __init dm644x_gpio_register(void)
{
return davinci_gpio_register(dm644_gpio_resources,
ARRAY_SIZE(dm644_gpio_resources),
&dm644_gpio_platform_data);
}
/*----------------------------------------------------------------------*/
static struct map_desc dm644x_io_desc[] = {
{
.virtual = IO_VIRT,
.pfn = __phys_to_pfn(IO_PHYS),
.length = IO_SIZE,
.type = MT_DEVICE
},
};
/* 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_serial0_platform_data[] = {
{
.mapbase = DAVINCI_UART0_BASE,
.irq = IRQ_UARTINT0,
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
UPF_IOREMAP,
.iotype = UPIO_MEM,
.regshift = 2,
},
{
.flags = 0,
}
};
static struct plat_serial8250_port dm644x_serial1_platform_data[] = {
{
.mapbase = DAVINCI_UART1_BASE,
.irq = IRQ_UARTINT1,
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
UPF_IOREMAP,
.iotype = UPIO_MEM,
.regshift = 2,
},
{
.flags = 0,
}
};
static struct plat_serial8250_port dm644x_serial2_platform_data[] = {
{
.mapbase = DAVINCI_UART2_BASE,
.irq = IRQ_UARTINT2,
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
UPF_IOREMAP,
.iotype = UPIO_MEM,
.regshift = 2,
},
{
.flags = 0,
}
};
struct platform_device dm644x_serial_device[] = {
{
.name = "serial8250",
.id = PLAT8250_DEV_PLATFORM,
.dev = {
.platform_data = dm644x_serial0_platform_data,
}
},
{
.name = "serial8250",
.id = PLAT8250_DEV_PLATFORM1,
.dev = {
.platform_data = dm644x_serial1_platform_data,
}
},
{
.name = "serial8250",
.id = PLAT8250_DEV_PLATFORM2,
.dev = {
.platform_data = dm644x_serial2_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,
.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);
}
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)
{
int ret = 0;
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);
ret = davinci_init_wdt();
if (ret)
pr_warn("%s: watchdog init failed: %d\n", __func__, ret);
return ret;
}
postcore_initcall(dm644x_init_devices);

View file

@ -0,0 +1,956 @@
/*
* 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 <linux/platform_data/edma.h>
#include <linux/platform_data/gpio-davinci.h>
#include <asm/mach/map.h>
#include <mach/cputype.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 "davinci.h"
#include "clock.h"
#include "mux.h"
#include "asp.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("serial8250.0", NULL, &uart0_clk),
CLK("serial8250.1", NULL, &uart1_clk),
CLK("serial8250.2", NULL, &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("davinci_mdio.0", "fck", &emac_clk),
CLK(NULL, "pwm0", &pwm0_clk),
CLK(NULL, "pwm1", &pwm1_clk),
CLK(NULL, "timer0", &timer0_clk),
CLK(NULL, "timer1", &timer1_clk),
CLK("davinci-wdt", 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 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 = {
.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 = "mpu",
.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 = "mpu",
.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 resource dm646x_gpio_resources[] = {
{ /* registers */
.start = DAVINCI_GPIO_BASE,
.end = DAVINCI_GPIO_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
{ /* interrupt */
.start = IRQ_DM646X_GPIOBNK0,
.end = IRQ_DM646X_GPIOBNK2,
.flags = IORESOURCE_IRQ,
},
};
static struct davinci_gpio_platform_data dm646x_gpio_platform_data = {
.ngpio = 43,
};
int __init dm646x_gpio_register(void)
{
return davinci_gpio_register(dm646x_gpio_resources,
ARRAY_SIZE(dm646x_gpio_resources),
&dm646x_gpio_platform_data);
}
/*----------------------------------------------------------------------*/
static struct map_desc dm646x_io_desc[] = {
{
.virtual = IO_VIRT,
.pfn = __phys_to_pfn(IO_PHYS),
.length = IO_SIZE,
.type = MT_DEVICE
},
};
/* 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_serial0_platform_data[] = {
{
.mapbase = DAVINCI_UART0_BASE,
.irq = IRQ_UARTINT0,
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
UPF_IOREMAP,
.iotype = UPIO_MEM32,
.regshift = 2,
},
{
.flags = 0,
}
};
static struct plat_serial8250_port dm646x_serial1_platform_data[] = {
{
.mapbase = DAVINCI_UART1_BASE,
.irq = IRQ_UARTINT1,
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
UPF_IOREMAP,
.iotype = UPIO_MEM32,
.regshift = 2,
},
{
.flags = 0,
}
};
static struct plat_serial8250_port dm646x_serial2_platform_data[] = {
{
.mapbase = DAVINCI_UART2_BASE,
.irq = IRQ_DM646X_UARTINT2,
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
UPF_IOREMAP,
.iotype = UPIO_MEM32,
.regshift = 2,
},
{
.flags = 0,
}
};
struct platform_device dm646x_serial_device[] = {
{
.name = "serial8250",
.id = PLAT8250_DEV_PLATFORM,
.dev = {
.platform_data = dm646x_serial0_platform_data,
}
},
{
.name = "serial8250",
.id = PLAT8250_DEV_PLATFORM1,
.dev = {
.platform_data = dm646x_serial1_platform_data,
}
},
{
.name = "serial8250",
.id = PLAT8250_DEV_PLATFORM2,
.dev = {
.platform_data = dm646x_serial2_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,
.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)
{
int ret = 0;
if (!cpu_is_davinci_dm646x())
return 0;
platform_device_register(&dm646x_mdio_device);
platform_device_register(&dm646x_emac_device);
ret = davinci_init_wdt();
if (ret)
pr_warn("%s: watchdog init failed: %d\n", __func__, ret);
return ret;
}
postcore_initcall(dm646x_init_devices);

View file

@ -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

View file

@ -0,0 +1,24 @@
/*
* 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);
int davinci_clk_reset_assert(struct clk *c);
int davinci_clk_reset_deassert(struct clk *c);
#endif

View file

@ -0,0 +1,107 @@
/*
* 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>
#include <linux/reboot.h>
extern void davinci_timer_init(void);
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 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(enum reboot_mode mode, const char *cmd);
void davinci_init_late(void);
#ifdef CONFIG_DAVINCI_RESET_CLOCKS
int davinci_clk_disable_unused(void);
#else
static inline int davinci_clk_disable_unused(void) { return 0; }
#endif
#ifdef CONFIG_CPU_FREQ
int davinci_cpufreq_init(void);
#else
static inline int davinci_cpufreq_init(void) { return 0; }
#endif
#ifdef CONFIG_SUSPEND
int davinci_pm_init(void);
#else
static inline int davinci_pm_init(void) { return 0; }
#endif
#define SRAM_SIZE SZ_128K
#endif /* __ARCH_ARM_MACH_DAVINCI_COMMON_H */

View file

@ -0,0 +1,57 @@
/*
* 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 cp_intc_init(void);
int cp_intc_of_init(struct device_node *, struct device_node *);
#endif /* __ASM_HARDWARE_CP_INTC_H */

View file

@ -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

View file

@ -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

View file

@ -0,0 +1,86 @@
/*
* 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 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)
#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
#endif

View file

@ -0,0 +1,154 @@
/*
* 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 <linux/platform_data/davinci_asp.h>
#include <linux/reboot.h>
#include <linux/videodev2.h>
#include <mach/serial.h>
#include <mach/pm.h>
#include <linux/platform_data/edma.h>
#include <linux/platform_data/i2c-davinci.h>
#include <linux/platform_data/mmc-davinci.h>
#include <linux/platform_data/usb-davinci.h>
#include <linux/platform_data/spi-davinci.h>
#include <linux/platform_data/uio_pruss.h>
#include <media/davinci/vpif_types.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_HOST1CFG_REG 0x44
#define DA8XX_CHIPSIG_REG 0x174
#define DA8XX_CFGCHIP0_REG 0x17c
#define DA8XX_CFGCHIP1_REG 0x180
#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_VPIF_BASE 0x01e17000
#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_SHARED_RAM_BASE 0x80000000
#define DA8XX_ARM_RAM_BASE 0xffff0000
void da830_init(void);
void 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_bus(int instance, unsigned num_chipselect);
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_uio_pruss(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 da8xx_register_mcasp(int id, struct snd_platform_data *pdata);
int da8xx_register_rtc(void);
int da8xx_register_gpio(void *pdata);
int da850_register_cpufreq(char *async_clk);
int da8xx_register_cpuidle(void);
void __iomem *da8xx_get_mem_ctlr(void);
int da850_register_pm(struct platform_device *pdev);
int da850_register_sata(unsigned long refclkpn);
int da850_register_vpif(void);
int da850_register_vpif_display
(struct vpif_display_config *display_config);
int da850_register_vpif_capture
(struct vpif_capture_config *capture_config);
void da8xx_restart(enum reboot_mode mode, const char *cmd);
void da8xx_rproc_reserve_cma(void);
int da8xx_register_rproc(void);
int da850_register_gpio(void);
int da830_register_gpio(void);
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 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_vpif_capture_pins[];
extern const short da850_vpif_display_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 */

View file

@ -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)

View file

@ -0,0 +1,39 @@
/*
* 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 */
mov \tmp, \irqnr, lsr #31
and \irqnr, \irqnr, #0xff /* irq is in bits 0-9 */
and \tmp, \tmp, #0x1
cmp \tmp, #0x1
#endif
1002:
.endm

View file

@ -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 UL(0x01c00000)
#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 */

View file

@ -0,0 +1,409 @@
/*
* 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
/* 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 */

View file

@ -0,0 +1,990 @@
/*
* 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,
/* VPIF Capture */
DA850_VPIF_DIN0,
DA850_VPIF_DIN1,
DA850_VPIF_DIN2,
DA850_VPIF_DIN3,
DA850_VPIF_DIN4,
DA850_VPIF_DIN5,
DA850_VPIF_DIN6,
DA850_VPIF_DIN7,
DA850_VPIF_DIN8,
DA850_VPIF_DIN9,
DA850_VPIF_DIN10,
DA850_VPIF_DIN11,
DA850_VPIF_DIN12,
DA850_VPIF_DIN13,
DA850_VPIF_DIN14,
DA850_VPIF_DIN15,
DA850_VPIF_CLKIN0,
DA850_VPIF_CLKIN1,
DA850_VPIF_CLKIN2,
DA850_VPIF_CLKIN3,
/* VPIF Display */
DA850_VPIF_DOUT0,
DA850_VPIF_DOUT1,
DA850_VPIF_DOUT2,
DA850_VPIF_DOUT3,
DA850_VPIF_DOUT4,
DA850_VPIF_DOUT5,
DA850_VPIF_DOUT6,
DA850_VPIF_DOUT7,
DA850_VPIF_DOUT8,
DA850_VPIF_DOUT9,
DA850_VPIF_DOUT10,
DA850_VPIF_DOUT11,
DA850_VPIF_DOUT12,
DA850_VPIF_DOUT13,
DA850_VPIF_DOUT14,
DA850_VPIF_DOUT15,
DA850_VPIF_CLKO2,
DA850_VPIF_CLKO3,
};
#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 */

View file

@ -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

View file

@ -0,0 +1,217 @@
/*
* 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 DA850_LPSC1_VPIF 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
/* 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_LRST BIT(8)
#define MDCTL_FORCE BIT(31)
#define PDCTL_NEXT BIT(0)
#define PDCTL_EPCGOOD BIT(8)
#ifndef __ASSEMBLER__
extern int davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id);
extern void davinci_psc_reset(unsigned int ctlr, unsigned int id,
bool reset);
extern void davinci_psc_config(unsigned int domain, unsigned int ctlr,
unsigned int id, bool enable, u32 flags);
#endif
#endif /* __ASM_ARCH_PSC_H */

View file

@ -0,0 +1,37 @@
/*
* 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>
#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)
/* DaVinci UART register offsets */
#define UART_DAVINCI_PWREMU 0x0c
#define UART_DM646X_SCR 0x10
#define UART_DM646X_SCR_TX_WATERMARK 0x08
#ifndef __ASSEMBLY__
#include <linux/platform_device.h>
extern int davinci_serial_init(struct platform_device *);
#endif
#endif /* __ASM_ARCH_SERIAL_H */

View file

@ -0,0 +1,30 @@
/*
* 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);
/* Get the struct gen_pool * for use in platform data */
extern struct gen_pool *sram_get_gen_pool(void);
#endif /* __MACH_SRAM_H */

View file

@ -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 */

View file

@ -0,0 +1,97 @@
/*
* 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)
{
if (!uart)
return;
while (!(uart[UART_LSR] & UART_LSR_THRE))
barrier();
uart[UART_TX] = c;
}
static inline void flush(void)
{
if (!uart)
return;
while (!(uart[UART_LSR] & UART_LSR_THRE))
barrier();
}
static inline void set_uart_info(u32 phys)
{
uart = (u32 *)phys;
}
#define _DEBUG_LL_ENTRY(machine, phys) \
{ \
if (machine_is_##machine()) { \
set_uart_info(phys); \
break; \
} \
}
#define DEBUG_LL_DAVINCI(machine, port) \
_DEBUG_LL_ENTRY(machine, DAVINCI_UART##port##_BASE)
#define DEBUG_LL_DA8XX(machine, port) \
_DEBUG_LL_ENTRY(machine, DA8XX_UART##port##_BASE)
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);
} while (0);
}
#define arch_decomp_setup() __arch_decomp_setup(arch_id)

117
arch/arm/mach-davinci/irq.c Normal file
View file

@ -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);
}

113
arch/arm/mach-davinci/mux.c Normal file
View file

@ -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;
}

View file

@ -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 */

159
arch/arm/mach-davinci/pm.c Normal file
View file

@ -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/common.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),
};
int __init davinci_pm_init(void)
{
return platform_driver_probe(&davinci_pm_driver, davinci_pm_probe);
}

View file

@ -0,0 +1,65 @@
/*
* Runtime PM support code for DaVinci
*
* Author: Kevin Hilman
*
* Copyright (C) 2012 Texas Instruments, 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/init.h>
#include <linux/pm_runtime.h>
#include <linux/pm_clock.h>
#include <linux/platform_device.h>
#ifdef CONFIG_PM_RUNTIME
static int davinci_pm_runtime_suspend(struct device *dev)
{
int ret;
dev_dbg(dev, "%s\n", __func__);
ret = pm_generic_runtime_suspend(dev);
if (ret)
return ret;
ret = pm_clk_suspend(dev);
if (ret) {
pm_generic_runtime_resume(dev);
return ret;
}
return 0;
}
static int davinci_pm_runtime_resume(struct device *dev)
{
dev_dbg(dev, "%s\n", __func__);
pm_clk_resume(dev);
return pm_generic_runtime_resume(dev);
}
#endif
static struct dev_pm_domain davinci_pm_domain = {
.ops = {
SET_RUNTIME_PM_OPS(davinci_pm_runtime_suspend,
davinci_pm_runtime_resume, NULL)
USE_PLATFORM_PM_SLEEP_OPS
},
};
static struct pm_clk_notifier_block platform_bus_notifier = {
.pm_domain = &davinci_pm_domain,
.con_ids = { "fck", "master", "slave", NULL },
};
static int __init davinci_pm_runtime_init(void)
{
pm_clk_add_notifier(&platform_bus_type, &platform_bus_notifier);
return 0;
}
core_initcall(davinci_pm_runtime_init);

137
arch/arm/mach-davinci/psc.c Normal file
View file

@ -0,0 +1,137 @@
/*
* 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_warn("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);
}
/* Control "reset" line associated with PSC domain */
void davinci_psc_reset(unsigned int ctlr, unsigned int id, bool reset)
{
u32 mdctl;
void __iomem *psc_base;
struct davinci_soc_info *soc_info = &davinci_soc_info;
if (!soc_info->psc_bases || (ctlr >= soc_info->psc_bases_num)) {
pr_warn("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);
mdctl = readl(psc_base + MDCTL + 4 * id);
if (reset)
mdctl &= ~MDCTL_LRST;
else
mdctl |= MDCTL_LRST;
writel(mdctl, psc_base + MDCTL + 4 * id);
iounmap(psc_base);
}
/* 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_warn("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);
}

View file

@ -0,0 +1,116 @@
/*
* 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 platform_device *serial_dev)
{
int i, ret = 0;
struct device *dev;
struct plat_serial8250_port *p;
struct clk *clk;
/*
* 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; serial_dev[i].dev.platform_data != NULL; i++) {
dev = &serial_dev[i].dev;
p = dev->platform_data;
ret = platform_device_register(&serial_dev[i]);
if (ret)
continue;
clk = clk_get(dev, NULL);
if (IS_ERR(clk)) {
pr_err("%s:%d: failed to get UART%d clock\n",
__func__, __LINE__, i);
continue;
}
clk_prepare_enable(clk);
p->uartclk = clk_get_rate(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 ret;
}

View file

@ -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
ret 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)

View file

@ -0,0 +1,81 @@
/*
* 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/io.h>
#include <linux/genalloc.h>
#include <mach/common.h>
#include <mach/sram.h>
static struct gen_pool *sram_pool;
struct gen_pool *sram_get_gen_pool(void)
{
return sram_pool;
}
void *sram_alloc(size_t len, dma_addr_t *dma)
{
dma_addr_t dma_base = davinci_soc_info.sram_dma;
if (dma)
*dma = 0;
if (!sram_pool || (dma && !dma_base))
return NULL;
return gen_pool_dma_alloc(sram_pool, len, dma);
}
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)
{
phys_addr_t phys = davinci_soc_info.sram_dma;
unsigned len = davinci_soc_info.sram_len;
int status = 0;
void __iomem *addr;
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) {
addr = ioremap(phys, len);
if (!addr)
return -ENOMEM;
status = gen_pool_add_virt(sram_pool, (unsigned long) addr,
phys, len, -1);
if (status < 0)
iounmap(addr);
}
WARN_ON(status < 0);
return status;
}
core_initcall(sram_init);

View file

@ -0,0 +1,456 @@
/*
* 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 <linux/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_TIMER,
.handler = timer_interrupt,
}
},
[TID_CLOCKSOURCE] = {
.name = "free-run counter",
.period = ~0,
.opts = TIMER_OPTS_PERIODIC,
.irqaction = {
.flags = 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 u64 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,
.set_next_event = davinci_set_next_event,
.set_mode = davinci_set_mode,
};
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_prepare_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);
sched_clock_register(davinci_read_sched_clock, 32,
davinci_clock_tick_rate);
/* setup clockevent */
clockevent_davinci.name = id_to_name[timers[TID_CLOCKEVENT].id];
clockevent_davinci.cpumask = cpumask_of(0);
clockevents_config_and_register(&clockevent_davinci,
davinci_clock_tick_rate, 1, 0xfffffffe);
for (i=0; i< ARRAY_SIZE(timers); i++)
timer32_config(&timers[i]);
}
/* 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_prepare_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);
}

175
arch/arm/mach-davinci/usb.c Normal file
View file

@ -0,0 +1,175 @@
/*
* 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/da8xx.h>
#include <linux/platform_data/usb-davinci.h>
#define DAVINCI_USB_OTG_BASE 0x01c64000
#define DA8XX_USB0_BASE 0x01e00000
#define DA8XX_USB1_BASE 0x01e25000
#if IS_ENABLED(CONFIG_USB_MUSB_HDRC)
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 = {
/* OTG requires a Mini-AB connector */
.mode = MUSB_OTG,
.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 */