mirror of
https://github.com/AetherDroid/android_kernel_samsung_on5xelte.git
synced 2025-10-28 14:58:52 +01:00
Fixed MTP to work with TWRP
This commit is contained in:
commit
f6dfaef42e
50820 changed files with 20846062 additions and 0 deletions
269
arch/arm/mach-davinci/Kconfig
Normal file
269
arch/arm/mach-davinci/Kconfig
Normal 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
|
||||
40
arch/arm/mach-davinci/Makefile
Normal file
40
arch/arm/mach-davinci/Makefile
Normal 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
|
||||
7
arch/arm/mach-davinci/Makefile.boot
Normal file
7
arch/arm/mach-davinci/Makefile.boot
Normal 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
|
||||
218
arch/arm/mach-davinci/aemif.c
Normal file
218
arch/arm/mach-davinci/aemif.c
Normal 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;
|
||||
}
|
||||
49
arch/arm/mach-davinci/asp.h
Normal file
49
arch/arm/mach-davinci/asp.h
Normal 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 */
|
||||
692
arch/arm/mach-davinci/board-da830-evm.c
Normal file
692
arch/arm/mach-davinci/board-da830-evm.c
Normal 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
|
||||
1625
arch/arm/mach-davinci/board-da850-evm.c
Normal file
1625
arch/arm/mach-davinci/board-da850-evm.c
Normal file
File diff suppressed because it is too large
Load diff
428
arch/arm/mach-davinci/board-dm355-evm.c
Normal file
428
arch/arm/mach-davinci/board-dm355-evm.c
Normal 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
|
||||
281
arch/arm/mach-davinci/board-dm355-leopard.c
Normal file
281
arch/arm/mach-davinci/board-dm355-leopard.c
Normal 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
|
||||
787
arch/arm/mach-davinci/board-dm365-evm.c
Normal file
787
arch/arm/mach-davinci/board-dm365-evm.c
Normal 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
|
||||
|
||||
825
arch/arm/mach-davinci/board-dm644x-evm.c
Normal file
825
arch/arm/mach-davinci/board-dm644x-evm.c
Normal 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
|
||||
840
arch/arm/mach-davinci/board-dm646x-evm.c
Normal file
840
arch/arm/mach-davinci/board-dm646x-evm.c
Normal 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
|
||||
|
||||
583
arch/arm/mach-davinci/board-mityomapl138.c
Normal file
583
arch/arm/mach-davinci/board-mityomapl138.c
Normal 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
|
||||
236
arch/arm/mach-davinci/board-neuros-osd2.c
Normal file
236
arch/arm/mach-davinci/board-neuros-osd2.c
Normal 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
|
||||
348
arch/arm/mach-davinci/board-omapl138-hawk.c
Normal file
348
arch/arm/mach-davinci/board-omapl138-hawk.c
Normal 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
|
||||
158
arch/arm/mach-davinci/board-sffsdr.c
Normal file
158
arch/arm/mach-davinci/board-sffsdr.c
Normal 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
|
||||
295
arch/arm/mach-davinci/cdce949.c
Normal file
295
arch/arm/mach-davinci/cdce949.c
Normal 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");
|
||||
713
arch/arm/mach-davinci/clock.c
Normal file
713
arch/arm/mach-davinci/clock.c
Normal 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 */
|
||||
140
arch/arm/mach-davinci/clock.h
Normal file
140
arch/arm/mach-davinci/clock.h
Normal 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
|
||||
124
arch/arm/mach-davinci/common.c
Normal file
124
arch/arm/mach-davinci/common.c
Normal 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();
|
||||
}
|
||||
222
arch/arm/mach-davinci/cp_intc.c
Normal file
222
arch/arm/mach-davinci/cp_intc.c
Normal 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);
|
||||
}
|
||||
105
arch/arm/mach-davinci/cpuidle.c
Normal file
105
arch/arm/mach-davinci/cpuidle.c
Normal 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);
|
||||
|
||||
1217
arch/arm/mach-davinci/da830.c
Normal file
1217
arch/arm/mach-davinci/da830.c
Normal file
File diff suppressed because it is too large
Load diff
1348
arch/arm/mach-davinci/da850.c
Normal file
1348
arch/arm/mach-davinci/da850.c
Normal file
File diff suppressed because it is too large
Load diff
79
arch/arm/mach-davinci/da8xx-dt.c
Normal file
79
arch/arm/mach-davinci/da8xx-dt.c
Normal 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
|
||||
123
arch/arm/mach-davinci/davinci.h
Normal file
123
arch/arm/mach-davinci/davinci.h
Normal 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 */
|
||||
1029
arch/arm/mach-davinci/devices-da8xx.c
Normal file
1029
arch/arm/mach-davinci/devices-da8xx.c
Normal file
File diff suppressed because it is too large
Load diff
350
arch/arm/mach-davinci/devices.c
Normal file
350
arch/arm/mach-davinci/devices.c
Normal 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,
|
||||
},
|
||||
};
|
||||
|
||||
1079
arch/arm/mach-davinci/dm355.c
Normal file
1079
arch/arm/mach-davinci/dm355.c
Normal file
File diff suppressed because it is too large
Load diff
1440
arch/arm/mach-davinci/dm365.c
Normal file
1440
arch/arm/mach-davinci/dm365.c
Normal file
File diff suppressed because it is too large
Load diff
969
arch/arm/mach-davinci/dm644x.c
Normal file
969
arch/arm/mach-davinci/dm644x.c
Normal 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);
|
||||
956
arch/arm/mach-davinci/dm646x.c
Normal file
956
arch/arm/mach-davinci/dm646x.c
Normal 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);
|
||||
19
arch/arm/mach-davinci/include/mach/cdce949.h
Normal file
19
arch/arm/mach-davinci/include/mach/cdce949.h
Normal 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
|
||||
24
arch/arm/mach-davinci/include/mach/clock.h
Normal file
24
arch/arm/mach-davinci/include/mach/clock.h
Normal 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
|
||||
107
arch/arm/mach-davinci/include/mach/common.h
Normal file
107
arch/arm/mach-davinci/include/mach/common.h
Normal 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 */
|
||||
57
arch/arm/mach-davinci/include/mach/cp_intc.h
Normal file
57
arch/arm/mach-davinci/include/mach/cp_intc.h
Normal 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 */
|
||||
26
arch/arm/mach-davinci/include/mach/cpufreq.h
Normal file
26
arch/arm/mach-davinci/include/mach/cpufreq.h
Normal 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
|
||||
18
arch/arm/mach-davinci/include/mach/cpuidle.h
Normal file
18
arch/arm/mach-davinci/include/mach/cpuidle.h
Normal 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
|
||||
86
arch/arm/mach-davinci/include/mach/cputype.h
Normal file
86
arch/arm/mach-davinci/include/mach/cputype.h
Normal 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
|
||||
154
arch/arm/mach-davinci/include/mach/da8xx.h
Normal file
154
arch/arm/mach-davinci/include/mach/da8xx.h
Normal 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 */
|
||||
4
arch/arm/mach-davinci/include/mach/ddr2.h
Normal file
4
arch/arm/mach-davinci/include/mach/ddr2.h
Normal 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)
|
||||
39
arch/arm/mach-davinci/include/mach/entry-macro.S
Normal file
39
arch/arm/mach-davinci/include/mach/entry-macro.S
Normal 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
|
||||
33
arch/arm/mach-davinci/include/mach/hardware.h
Normal file
33
arch/arm/mach-davinci/include/mach/hardware.h
Normal 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 */
|
||||
409
arch/arm/mach-davinci/include/mach/irqs.h
Normal file
409
arch/arm/mach-davinci/include/mach/irqs.h
Normal 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 */
|
||||
990
arch/arm/mach-davinci/include/mach/mux.h
Normal file
990
arch/arm/mach-davinci/include/mach/mux.h
Normal 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 */
|
||||
54
arch/arm/mach-davinci/include/mach/pm.h
Normal file
54
arch/arm/mach-davinci/include/mach/pm.h
Normal 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
|
||||
217
arch/arm/mach-davinci/include/mach/psc.h
Normal file
217
arch/arm/mach-davinci/include/mach/psc.h
Normal 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 */
|
||||
37
arch/arm/mach-davinci/include/mach/serial.h
Normal file
37
arch/arm/mach-davinci/include/mach/serial.h
Normal 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 */
|
||||
30
arch/arm/mach-davinci/include/mach/sram.h
Normal file
30
arch/arm/mach-davinci/include/mach/sram.h
Normal 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 */
|
||||
35
arch/arm/mach-davinci/include/mach/time.h
Normal file
35
arch/arm/mach-davinci/include/mach/time.h
Normal 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 */
|
||||
97
arch/arm/mach-davinci/include/mach/uncompress.h
Normal file
97
arch/arm/mach-davinci/include/mach/uncompress.h
Normal 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
117
arch/arm/mach-davinci/irq.c
Normal 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
113
arch/arm/mach-davinci/mux.c
Normal 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;
|
||||
}
|
||||
51
arch/arm/mach-davinci/mux.h
Normal file
51
arch/arm/mach-davinci/mux.h
Normal 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
159
arch/arm/mach-davinci/pm.c
Normal 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);
|
||||
}
|
||||
65
arch/arm/mach-davinci/pm_domain.c
Normal file
65
arch/arm/mach-davinci/pm_domain.c
Normal 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
137
arch/arm/mach-davinci/psc.c
Normal 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);
|
||||
}
|
||||
116
arch/arm/mach-davinci/serial.c
Normal file
116
arch/arm/mach-davinci/serial.c
Normal 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;
|
||||
}
|
||||
228
arch/arm/mach-davinci/sleep.S
Normal file
228
arch/arm/mach-davinci/sleep.S
Normal 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)
|
||||
81
arch/arm/mach-davinci/sram.c
Normal file
81
arch/arm/mach-davinci/sram.c
Normal 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);
|
||||
|
||||
456
arch/arm/mach-davinci/time.c
Normal file
456
arch/arm/mach-davinci/time.c
Normal 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
175
arch/arm/mach-davinci/usb.c
Normal 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 */
|
||||
Loading…
Add table
Add a link
Reference in a new issue