Merge branch 'davinci-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-davinci
* 'davinci-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-davinci: (40 commits) DaVinci DM365: Adding support for SPI EEPROM DaVinci DM365: Adding DM365 SPI support DaVinci DM355: Modifications to DM355 SPI support DaVinci: SPI: Adding header file for SPI support. davinci: dm646x: CDCE clocks: davinci_clk converted to clk_lookup davinci: clkdev cleanup: remove clk_lookup wrapper, use clkdev_add_table() DaVinci: DM365: Voice codec support for the DM365 SoC davinci: clock: let clk->set_rate function sleep Add SDA and SCL pin numbers to i2c platform data davinci: da8xx/omap-l1xx: Add EDMA platform data for da850/omap-l138 davinci: build list of unused EDMA events dynamically davinci: Fix edma_alloc_channel api for EDMA_CHANNEL_ANY case davinci: Keep count of channel controllers on a platform davinci: Correct return value of edma_alloc_channel api davinci: add CDCE949 support on DM6467 EVM davinci: add support for CDCE949 clock synthesizer davinci: da850/omap-l138 EVM: register for suspend support davinci: da850/omap-l138: add support for SoC suspend davinci: add power management support DaVinci: DM365: Changing default queue for DM365. ...
This commit is contained in:
commit
13dda80e48
@ -91,10 +91,14 @@ config MACH_DAVINCI_DM6467_EVM
|
||||
bool "TI DM6467 EVM"
|
||||
default ARCH_DAVINCI_DM646x
|
||||
depends on ARCH_DAVINCI_DM646x
|
||||
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
|
||||
|
@ -26,7 +26,7 @@ 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
|
||||
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
|
||||
@ -34,3 +34,4 @@ obj-$(CONFIG_MACH_DAVINCI_DA850_EVM) += board-da850-evm.o
|
||||
# Power Management
|
||||
obj-$(CONFIG_CPU_FREQ) += cpufreq.o
|
||||
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
|
||||
obj-$(CONFIG_SUSPEND) += pm.o sleep.o
|
||||
|
@ -112,7 +112,7 @@ static __init void da830_evm_usb_init(void)
|
||||
* Set up USB clock/mode in the CFGCHIP2 register.
|
||||
* FYI: CFGCHIP2 is 0x0000ef00 initially.
|
||||
*/
|
||||
cfgchip2 = __raw_readl(DA8XX_SYSCFG_VIRT(DA8XX_CFGCHIP2_REG));
|
||||
cfgchip2 = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
|
||||
|
||||
/* USB2.0 PHY reference clock is 24 MHz */
|
||||
cfgchip2 &= ~CFGCHIP2_REFFREQ;
|
||||
@ -139,7 +139,7 @@ static __init void da830_evm_usb_init(void)
|
||||
cfgchip2 |= CFGCHIP2_SESENDEN | CFGCHIP2_VBDTCTEN;
|
||||
#endif
|
||||
|
||||
__raw_writel(cfgchip2, DA8XX_SYSCFG_VIRT(DA8XX_CFGCHIP2_REG));
|
||||
__raw_writel(cfgchip2, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
|
||||
|
||||
/* USB_REFCLKIN is not used. */
|
||||
ret = davinci_cfg_reg(DA830_USB0_DRVVBUS);
|
||||
|
@ -46,8 +46,20 @@
|
||||
|
||||
static struct mtd_partition da850_evm_norflash_partition[] = {
|
||||
{
|
||||
.name = "NOR filesystem",
|
||||
.name = "bootloaders + env",
|
||||
.offset = 0,
|
||||
.size = SZ_512K,
|
||||
.mask_flags = MTD_WRITEABLE,
|
||||
},
|
||||
{
|
||||
.name = "kernel",
|
||||
.offset = MTDPART_OFS_APPEND,
|
||||
.size = SZ_2M,
|
||||
.mask_flags = 0,
|
||||
},
|
||||
{
|
||||
.name = "filesystem",
|
||||
.offset = MTDPART_OFS_APPEND,
|
||||
.size = MTDPART_SIZ_FULL,
|
||||
.mask_flags = 0,
|
||||
},
|
||||
@ -77,6 +89,18 @@ static struct platform_device da850_evm_norflash_device = {
|
||||
.resource = da850_evm_norflash_resource,
|
||||
};
|
||||
|
||||
static struct davinci_pm_config da850_pm_pdata = {
|
||||
.sleepcount = 128,
|
||||
};
|
||||
|
||||
static struct platform_device da850_pm_device = {
|
||||
.name = "pm-davinci",
|
||||
.dev = {
|
||||
.platform_data = &da850_pm_pdata,
|
||||
},
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
/* DA850/OMAP-L138 EVM includes a 512 MByte large-page NAND flash
|
||||
* (128K blocks). It may be used instead of the (default) SPI flash
|
||||
* to boot, using TI's tools to install the secondary boot loader
|
||||
@ -119,6 +143,7 @@ static struct davinci_nand_pdata da850_evm_nandflash_data = {
|
||||
.parts = da850_evm_nandflash_partition,
|
||||
.nr_parts = ARRAY_SIZE(da850_evm_nandflash_partition),
|
||||
.ecc_mode = NAND_ECC_HW,
|
||||
.ecc_bits = 4,
|
||||
.options = NAND_USE_FLASH_BBT,
|
||||
};
|
||||
|
||||
@ -537,7 +562,7 @@ static int __init da850_evm_config_emac(void)
|
||||
if (!machine_is_davinci_da850_evm())
|
||||
return 0;
|
||||
|
||||
cfg_chip3_base = DA8XX_SYSCFG_VIRT(DA8XX_CFGCHIP3_REG);
|
||||
cfg_chip3_base = DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG);
|
||||
|
||||
val = __raw_readl(cfg_chip3_base);
|
||||
|
||||
@ -696,6 +721,11 @@ static __init void da850_evm_init(void)
|
||||
if (ret)
|
||||
pr_warning("da850_evm_init: cpuidle registration failed: %d\n",
|
||||
ret);
|
||||
|
||||
ret = da850_register_pm(&da850_pm_device);
|
||||
if (ret)
|
||||
pr_warning("da850_evm_init: suspend registration failed: %d\n",
|
||||
ret);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SERIAL_8250_CONSOLE
|
||||
|
@ -111,6 +111,8 @@ static struct platform_device davinci_nand_device = {
|
||||
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;
|
||||
|
@ -24,6 +24,8 @@
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/mtd/nand.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/spi/eeprom.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
@ -571,6 +573,24 @@ 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)
|
||||
{
|
||||
evm_init_i2c();
|
||||
@ -587,6 +607,9 @@ static __init void dm365_evm_init(void)
|
||||
dm365_init_asp(&dm365_evm_snd_data);
|
||||
dm365_init_rtc();
|
||||
dm365_init_ks(&dm365evm_ks_data);
|
||||
|
||||
dm365_init_spi0(BIT(0), dm365_evm_spi_info,
|
||||
ARRAY_SIZE(dm365_evm_spi_info));
|
||||
}
|
||||
|
||||
static __init void dm365_evm_irq_init(void)
|
||||
|
@ -629,6 +629,8 @@ static struct i2c_board_info __initdata i2c_info[] = {
|
||||
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)
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/nand.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/clk.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
@ -39,54 +40,13 @@
|
||||
#include <mach/serial.h>
|
||||
#include <mach/i2c.h>
|
||||
#include <mach/nand.h>
|
||||
#include <mach/clock.h>
|
||||
#include <mach/cdce949.h>
|
||||
|
||||
#if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \
|
||||
defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE)
|
||||
#define HAS_ATA 1
|
||||
#else
|
||||
#define HAS_ATA 0
|
||||
#endif
|
||||
|
||||
#define DAVINCI_ASYNC_EMIF_CONTROL_BASE 0x20008000
|
||||
#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE 0x42000000
|
||||
#include "clock.h"
|
||||
|
||||
#define NAND_BLOCK_SIZE SZ_128K
|
||||
|
||||
/* CPLD Register 0 bits to control ATA */
|
||||
#define DM646X_EVM_ATA_RST BIT(0)
|
||||
#define DM646X_EVM_ATA_PWD BIT(1)
|
||||
|
||||
#define DM646X_EVM_PHY_MASK (0x2)
|
||||
#define DM646X_EVM_MDIO_FREQUENCY (2200000) /* PHY bus frequency */
|
||||
|
||||
#define VIDCLKCTL_OFFSET (DAVINCI_SYSTEM_MODULE_BASE + 0x38)
|
||||
#define VSCLKDIS_OFFSET (DAVINCI_SYSTEM_MODULE_BASE + 0x6c)
|
||||
#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"
|
||||
|
||||
static void __iomem *vpif_vidclkctl_reg;
|
||||
static void __iomem *vpif_vsclkdis_reg;
|
||||
/* spin lock for updating above registers */
|
||||
static spinlock_t vpif_reg_lock;
|
||||
|
||||
static struct davinci_uart_config uart_config __initdata = {
|
||||
.enabled_uarts = (1 << 0),
|
||||
};
|
||||
|
||||
/* 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.
|
||||
@ -120,6 +80,9 @@ static struct davinci_nand_pdata davinci_nand_data = {
|
||||
.options = 0,
|
||||
};
|
||||
|
||||
#define DAVINCI_ASYNC_EMIF_CONTROL_BASE 0x20008000
|
||||
#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE 0x42000000
|
||||
|
||||
static struct resource davinci_nand_resources[] = {
|
||||
{
|
||||
.start = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE,
|
||||
@ -144,6 +107,17 @@ static struct platform_device davinci_nand_device = {
|
||||
},
|
||||
};
|
||||
|
||||
#if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \
|
||||
defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE)
|
||||
#define HAS_ATA 1
|
||||
#else
|
||||
#define HAS_ATA 0
|
||||
#endif
|
||||
|
||||
/* CPLD Register 0 bits to control ATA */
|
||||
#define DM646X_EVM_ATA_RST BIT(0)
|
||||
#define DM646X_EVM_ATA_PWD BIT(1)
|
||||
|
||||
/* CPLD Register 0 Client: used for I/O Control */
|
||||
static int cpld_reg0_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
@ -417,6 +391,9 @@ static struct i2c_board_info __initdata i2c_info[] = {
|
||||
{
|
||||
I2C_BOARD_INFO("cpld_video", 0x3b),
|
||||
},
|
||||
{
|
||||
I2C_BOARD_INFO("cdce949", 0x6c),
|
||||
},
|
||||
};
|
||||
|
||||
static struct davinci_i2c_platform_data i2c_pdata = {
|
||||
@ -424,6 +401,30 @@ static struct davinci_i2c_platform_data i2c_pdata = {
|
||||
.bus_delay = 0 /* usec */,
|
||||
};
|
||||
|
||||
#define VIDCLKCTL_OFFSET (DAVINCI_SYSTEM_MODULE_BASE + 0x38)
|
||||
#define VSCLKDIS_OFFSET (DAVINCI_SYSTEM_MODULE_BASE + 0x6c)
|
||||
#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"
|
||||
|
||||
static void __iomem *vpif_vidclkctl_reg;
|
||||
static void __iomem *vpif_vsclkdis_reg;
|
||||
/* 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;
|
||||
@ -685,11 +686,44 @@ static void __init evm_init_i2c(void)
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
static void __init davinci_map_io(void)
|
||||
{
|
||||
dm646x_init();
|
||||
cdce_clk_init();
|
||||
}
|
||||
|
||||
static struct davinci_uart_config uart_config __initdata = {
|
||||
.enabled_uarts = (1 << 0),
|
||||
};
|
||||
|
||||
#define DM646X_EVM_PHY_MASK (0x2)
|
||||
#define DM646X_EVM_MDIO_FREQUENCY (2200000) /* PHY bus frequency */
|
||||
|
||||
static __init void evm_init(void)
|
||||
{
|
||||
struct davinci_soc_info *soc_info = &davinci_soc_info;
|
||||
@ -713,6 +747,17 @@ static __init void davinci_dm646x_evm_irq_init(void)
|
||||
davinci_irq_init();
|
||||
}
|
||||
|
||||
#define DM646X_EVM_REF_FREQ 27000000
|
||||
#define DM6467T_EVM_REF_FREQ 33000000
|
||||
|
||||
void __init dm646x_board_setup_refclk(struct clk *clk)
|
||||
{
|
||||
if (machine_is_davinci_dm6467tevm())
|
||||
clk->rate = DM6467T_EVM_REF_FREQ;
|
||||
else
|
||||
clk->rate = DM646X_EVM_REF_FREQ;
|
||||
}
|
||||
|
||||
MACHINE_START(DAVINCI_DM6467_EVM, "DaVinci DM646x EVM")
|
||||
.phys_io = IO_PHYS,
|
||||
.io_pg_offst = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
|
||||
@ -723,3 +768,13 @@ MACHINE_START(DAVINCI_DM6467_EVM, "DaVinci DM646x EVM")
|
||||
.init_machine = evm_init,
|
||||
MACHINE_END
|
||||
|
||||
MACHINE_START(DAVINCI_DM6467TEVM, "DaVinci DM6467T EVM")
|
||||
.phys_io = IO_PHYS,
|
||||
.io_pg_offst = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
|
||||
.boot_params = (0x80000100),
|
||||
.map_io = davinci_map_io,
|
||||
.init_irq = davinci_dm646x_evm_irq_init,
|
||||
.timer = &davinci_timer,
|
||||
.init_machine = evm_init,
|
||||
MACHINE_END
|
||||
|
||||
|
293
arch/arm/mach-davinci/cdce949.c
Normal file
293
arch/arm/mach-davinci/cdce949.c
Normal file
@ -0,0 +1,293 @@
|
||||
/*
|
||||
* 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 <mach/clock.h>
|
||||
|
||||
#include "clock.h"
|
||||
|
||||
static struct i2c_client *cdce_i2c_client;
|
||||
static DEFINE_MUTEX(cdce_mutex);
|
||||
|
||||
/* CDCE register descriptor */
|
||||
struct cdce_reg {
|
||||
u8 addr;
|
||||
u8 val;
|
||||
};
|
||||
|
||||
/* Per-Output (Y1, Y2 etc.) frequency descriptor */
|
||||
struct cdce_freq {
|
||||
/* Frequency in KHz */
|
||||
unsigned long frequency;
|
||||
/*
|
||||
* List of registers to program to obtain a particular frequency.
|
||||
* 0x0 in register address and value is the end of list marker.
|
||||
*/
|
||||
struct cdce_reg *reglist;
|
||||
};
|
||||
|
||||
#define CDCE_FREQ_TABLE_ENTRY(line, out) \
|
||||
{ \
|
||||
.reglist = cdce_y ##line## _ ##out, \
|
||||
.frequency = out, \
|
||||
}
|
||||
|
||||
/* List of CDCE outputs */
|
||||
struct cdce_output {
|
||||
/* List of frequencies on this output */
|
||||
struct cdce_freq *freq_table;
|
||||
/* Number of possible frequencies */
|
||||
int size;
|
||||
};
|
||||
|
||||
/*
|
||||
* Finding out the values to program into CDCE949 registers for a particular
|
||||
* frequency output is not a simple calculation. Have a look at the datasheet
|
||||
* for the details. There is desktop software available to help users with
|
||||
* the calculations. Here, we just depend on the output of that software
|
||||
* (or hand calculations) instead trying to runtime calculate the register
|
||||
* values and inflicting misery on ourselves.
|
||||
*/
|
||||
static struct cdce_reg cdce_y1_148500[] = {
|
||||
{ 0x13, 0x00 },
|
||||
/* program PLL1_0 multiplier */
|
||||
{ 0x18, 0xaf },
|
||||
{ 0x19, 0x50 },
|
||||
{ 0x1a, 0x02 },
|
||||
{ 0x1b, 0xc9 },
|
||||
/* program PLL1_11 multiplier */
|
||||
{ 0x1c, 0x00 },
|
||||
{ 0x1d, 0x40 },
|
||||
{ 0x1e, 0x02 },
|
||||
{ 0x1f, 0xc9 },
|
||||
/* output state selection */
|
||||
{ 0x15, 0x00 },
|
||||
{ 0x14, 0xef },
|
||||
/* switch MUX to PLL1 output */
|
||||
{ 0x14, 0x6f },
|
||||
{ 0x16, 0x06 },
|
||||
/* set P2DIV divider, P3DIV and input crystal */
|
||||
{ 0x17, 0x06 },
|
||||
{ 0x01, 0x00 },
|
||||
{ 0x05, 0x48 },
|
||||
{ 0x02, 0x80 },
|
||||
/* enable and disable PLL */
|
||||
{ 0x02, 0xbc },
|
||||
{ 0x03, 0x01 },
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct cdce_reg cdce_y1_74250[] = {
|
||||
{ 0x13, 0x00 },
|
||||
{ 0x18, 0xaf },
|
||||
{ 0x19, 0x50 },
|
||||
{ 0x1a, 0x02 },
|
||||
{ 0x1b, 0xc9 },
|
||||
{ 0x1c, 0x00 },
|
||||
{ 0x1d, 0x40 },
|
||||
{ 0x1e, 0x02 },
|
||||
{ 0x1f, 0xc9 },
|
||||
/* output state selection */
|
||||
{ 0x15, 0x00 },
|
||||
{ 0x14, 0xef },
|
||||
/* switch MUX to PLL1 output */
|
||||
{ 0x14, 0x6f },
|
||||
{ 0x16, 0x06 },
|
||||
/* set P2DIV divider, P3DIV and input crystal */
|
||||
{ 0x17, 0x06 },
|
||||
{ 0x01, 0x00 },
|
||||
{ 0x05, 0x48 },
|
||||
{ 0x02, 0x80 },
|
||||
/* enable and disable PLL */
|
||||
{ 0x02, 0xbc },
|
||||
{ 0x03, 0x02 },
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct cdce_reg cdce_y1_27000[] = {
|
||||
{ 0x13, 0x00 },
|
||||
{ 0x18, 0x00 },
|
||||
{ 0x19, 0x40 },
|
||||
{ 0x1a, 0x02 },
|
||||
{ 0x1b, 0x08 },
|
||||
{ 0x1c, 0x00 },
|
||||
{ 0x1d, 0x40 },
|
||||
{ 0x1e, 0x02 },
|
||||
{ 0x1f, 0x08 },
|
||||
{ 0x15, 0x02 },
|
||||
{ 0x14, 0xed },
|
||||
{ 0x16, 0x01 },
|
||||
{ 0x17, 0x01 },
|
||||
{ 0x01, 0x00 },
|
||||
{ 0x05, 0x50 },
|
||||
{ 0x02, 0xb4 },
|
||||
{ 0x03, 0x01 },
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct cdce_freq cdce_y1_freqs[] = {
|
||||
CDCE_FREQ_TABLE_ENTRY(1, 148500),
|
||||
CDCE_FREQ_TABLE_ENTRY(1, 74250),
|
||||
CDCE_FREQ_TABLE_ENTRY(1, 27000),
|
||||
};
|
||||
|
||||
static struct cdce_reg cdce_y5_13500[] = {
|
||||
{ 0x27, 0x08 },
|
||||
{ 0x28, 0x00 },
|
||||
{ 0x29, 0x40 },
|
||||
{ 0x2a, 0x02 },
|
||||
{ 0x2b, 0x08 },
|
||||
{ 0x24, 0x6f },
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct cdce_reg cdce_y5_16875[] = {
|
||||
{ 0x27, 0x08 },
|
||||
{ 0x28, 0x9f },
|
||||
{ 0x29, 0xb0 },
|
||||
{ 0x2a, 0x02 },
|
||||
{ 0x2b, 0x89 },
|
||||
{ 0x24, 0x6f },
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct cdce_reg cdce_y5_27000[] = {
|
||||
{ 0x27, 0x04 },
|
||||
{ 0x28, 0x00 },
|
||||
{ 0x29, 0x40 },
|
||||
{ 0x2a, 0x02 },
|
||||
{ 0x2b, 0x08 },
|
||||
{ 0x24, 0x6f },
|
||||
{ },
|
||||
};
|
||||
static struct cdce_reg cdce_y5_54000[] = {
|
||||
{ 0x27, 0x04 },
|
||||
{ 0x28, 0xff },
|
||||
{ 0x29, 0x80 },
|
||||
{ 0x2a, 0x02 },
|
||||
{ 0x2b, 0x07 },
|
||||
{ 0x24, 0x6f },
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct cdce_reg cdce_y5_81000[] = {
|
||||
{ 0x27, 0x02 },
|
||||
{ 0x28, 0xbf },
|
||||
{ 0x29, 0xa0 },
|
||||
{ 0x2a, 0x03 },
|
||||
{ 0x2b, 0x0a },
|
||||
{ 0x24, 0x6f },
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct cdce_freq cdce_y5_freqs[] = {
|
||||
CDCE_FREQ_TABLE_ENTRY(5, 13500),
|
||||
CDCE_FREQ_TABLE_ENTRY(5, 16875),
|
||||
CDCE_FREQ_TABLE_ENTRY(5, 27000),
|
||||
CDCE_FREQ_TABLE_ENTRY(5, 54000),
|
||||
CDCE_FREQ_TABLE_ENTRY(5, 81000),
|
||||
};
|
||||
|
||||
|
||||
static struct cdce_output output_list[] = {
|
||||
[1] = { cdce_y1_freqs, ARRAY_SIZE(cdce_y1_freqs) },
|
||||
[5] = { cdce_y5_freqs, ARRAY_SIZE(cdce_y5_freqs) },
|
||||
};
|
||||
|
||||
int cdce_set_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
int i, ret = 0;
|
||||
struct cdce_freq *freq_table = output_list[clk->lpsc].freq_table;
|
||||
struct cdce_reg *regs = NULL;
|
||||
|
||||
if (!cdce_i2c_client)
|
||||
return -ENODEV;
|
||||
|
||||
if (!freq_table)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < output_list[clk->lpsc].size; i++) {
|
||||
if (freq_table[i].frequency == rate / 1000) {
|
||||
regs = freq_table[i].reglist;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!regs)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&cdce_mutex);
|
||||
for (i = 0; regs[i].addr; i++) {
|
||||
ret = i2c_smbus_write_byte_data(cdce_i2c_client,
|
||||
regs[i].addr | 0x80, regs[i].val);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
mutex_unlock(&cdce_mutex);
|
||||
|
||||
if (!ret)
|
||||
clk->rate = rate;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cdce_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
cdce_i2c_client = client;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devexit cdce_remove(struct i2c_client *client)
|
||||
{
|
||||
cdce_i2c_client = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id cdce_id[] = {
|
||||
{"cdce949", 0},
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, cdce_id);
|
||||
|
||||
static struct i2c_driver cdce_driver = {
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "cdce949",
|
||||
},
|
||||
.probe = cdce_probe,
|
||||
.remove = __devexit_p(cdce_remove),
|
||||
.id_table = cdce_id,
|
||||
};
|
||||
|
||||
static int __init cdce_init(void)
|
||||
{
|
||||
return i2c_add_driver(&cdce_driver);
|
||||
}
|
||||
subsys_initcall(cdce_init);
|
||||
|
||||
static void __exit cdce_exit(void)
|
||||
{
|
||||
i2c_del_driver(&cdce_driver);
|
||||
}
|
||||
module_exit(cdce_exit);
|
||||
|
||||
MODULE_AUTHOR("Texas Instruments");
|
||||
MODULE_DESCRIPTION("CDCE949 clock synthesizer driver");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -49,7 +49,8 @@ static void __clk_disable(struct clk *clk)
|
||||
{
|
||||
if (WARN_ON(clk->usecount == 0))
|
||||
return;
|
||||
if (--clk->usecount == 0 && !(clk->flags & CLK_PLL))
|
||||
if (--clk->usecount == 0 && !(clk->flags & CLK_PLL) &&
|
||||
(clk->flags & CLK_PSC))
|
||||
davinci_psc_config(psc_domain(clk), clk->gpsc, clk->lpsc, 0);
|
||||
if (clk->parent)
|
||||
__clk_disable(clk->parent);
|
||||
@ -124,9 +125,10 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
|
||||
if (clk == NULL || IS_ERR(clk))
|
||||
return ret;
|
||||
|
||||
spin_lock_irqsave(&clockfw_lock, flags);
|
||||
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);
|
||||
@ -363,6 +365,7 @@ int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
|
||||
{
|
||||
u32 ctrl;
|
||||
unsigned int locktime;
|
||||
unsigned long flags;
|
||||
|
||||
if (pll->base == NULL)
|
||||
return -EINVAL;
|
||||
@ -376,25 +379,23 @@ int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
|
||||
locktime = ((2000 * prediv) / 100);
|
||||
prediv = (prediv - 1) | PLLDIV_EN;
|
||||
} else {
|
||||
locktime = 20;
|
||||
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);
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
udelay(1);
|
||||
udelay(PLL_BYPASS_TIME);
|
||||
|
||||
/* Reset and enable PLL */
|
||||
ctrl &= ~(PLLCTL_PLLRST | PLLCTL_PLLDIS);
|
||||
@ -408,11 +409,7 @@ int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
|
||||
if (pll->flags & PLL_HAS_POSTDIV)
|
||||
__raw_writel(postdiv, pll->base + POSTDIV);
|
||||
|
||||
/*
|
||||
* Wait for PLL to reset properly, OMAP-L138 datasheet says
|
||||
* 'min' time = 125ns
|
||||
*/
|
||||
udelay(1);
|
||||
udelay(PLL_RESET_TIME);
|
||||
|
||||
/* Bring PLL out of reset */
|
||||
ctrl |= PLLCTL_PLLRST;
|
||||
@ -424,17 +421,20 @@ int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
|
||||
ctrl |= PLLCTL_PLLEN;
|
||||
__raw_writel(ctrl, pll->base + PLLCTL);
|
||||
|
||||
spin_unlock_irqrestore(&clockfw_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(davinci_set_pllrate);
|
||||
|
||||
int __init davinci_clk_init(struct davinci_clk *clocks)
|
||||
int __init davinci_clk_init(struct clk_lookup *clocks)
|
||||
{
|
||||
struct davinci_clk *c;
|
||||
struct clk_lookup *c;
|
||||
struct clk *clk;
|
||||
size_t num_clocks = 0;
|
||||
|
||||
for (c = clocks; c->lk.clk; c++) {
|
||||
clk = c->lk.clk;
|
||||
for (c = clocks; c->clk; c++) {
|
||||
clk = c->clk;
|
||||
|
||||
if (!clk->recalc) {
|
||||
|
||||
@ -457,36 +457,24 @@ int __init davinci_clk_init(struct davinci_clk *clocks)
|
||||
if (clk->lpsc)
|
||||
clk->flags |= CLK_PSC;
|
||||
|
||||
clkdev_add(&c->lk);
|
||||
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_PROC_FS
|
||||
#include <linux/proc_fs.h>
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/seq_file.h>
|
||||
|
||||
static void *davinci_ck_start(struct seq_file *m, loff_t *pos)
|
||||
{
|
||||
return *pos < 1 ? (void *)1 : NULL;
|
||||
}
|
||||
|
||||
static void *davinci_ck_next(struct seq_file *m, void *v, loff_t *pos)
|
||||
{
|
||||
++*pos;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void davinci_ck_stop(struct seq_file *m, void *v)
|
||||
{
|
||||
}
|
||||
|
||||
#define CLKNAME_MAX 10 /* longest clock name */
|
||||
#define NEST_DELTA 2
|
||||
#define NEST_MAX 4
|
||||
@ -525,41 +513,38 @@ dump_clock(struct seq_file *s, unsigned nest, struct clk *parent)
|
||||
|
||||
static int davinci_ck_show(struct seq_file *m, void *v)
|
||||
{
|
||||
/* Show clock tree; we know the main oscillator is first.
|
||||
* We trust nonzero usecounts equate to PSC enables...
|
||||
struct clk *clk;
|
||||
|
||||
/*
|
||||
* Show clock tree; We trust nonzero usecounts equate to PSC enables...
|
||||
*/
|
||||
mutex_lock(&clocks_mutex);
|
||||
if (!list_empty(&clocks))
|
||||
dump_clock(m, 0, list_first_entry(&clocks, struct clk, node));
|
||||
list_for_each_entry(clk, &clocks, node)
|
||||
if (!clk->parent)
|
||||
dump_clock(m, 0, clk);
|
||||
mutex_unlock(&clocks_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct seq_operations davinci_ck_op = {
|
||||
.start = davinci_ck_start,
|
||||
.next = davinci_ck_next,
|
||||
.stop = davinci_ck_stop,
|
||||
.show = davinci_ck_show
|
||||
};
|
||||
|
||||
static int davinci_ck_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return seq_open(file, &davinci_ck_op);
|
||||
return single_open(file, davinci_ck_show, NULL);
|
||||
}
|
||||
|
||||
static const struct file_operations proc_davinci_ck_operations = {
|
||||
static const struct file_operations davinci_ck_operations = {
|
||||
.open = davinci_ck_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = seq_release,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static int __init davinci_ck_proc_init(void)
|
||||
static int __init davinci_clk_debugfs_init(void)
|
||||
{
|
||||
proc_create("davinci_clocks", 0, NULL, &proc_davinci_ck_operations);
|
||||
debugfs_create_file("davinci_clocks", S_IFREG | S_IRUGO, NULL, NULL,
|
||||
&davinci_ck_operations);
|
||||
return 0;
|
||||
|
||||
}
|
||||
__initcall(davinci_ck_proc_init);
|
||||
#endif /* CONFIG_DEBUG_PROC_FS */
|
||||
device_initcall(davinci_clk_debugfs_init);
|
||||
#endif /* CONFIG_DEBUG_FS */
|
||||
|
@ -12,9 +12,6 @@
|
||||
#ifndef __ARCH_ARM_DAVINCI_CLOCK_H
|
||||
#define __ARCH_ARM_DAVINCI_CLOCK_H
|
||||
|
||||
#include <linux/list.h>
|
||||
#include <asm/clkdev.h>
|
||||
|
||||
#define DAVINCI_PLL1_BASE 0x01c40800
|
||||
#define DAVINCI_PLL2_BASE 0x01c40c00
|
||||
#define MAX_PLL 2
|
||||
@ -53,6 +50,26 @@
|
||||
#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 <asm/clkdev.h>
|
||||
|
||||
struct pll_data {
|
||||
u32 phys_base;
|
||||
void __iomem *base;
|
||||
@ -89,23 +106,19 @@ struct clk {
|
||||
#define CLK_PLL BIT(4) /* PLL-derived clock */
|
||||
#define PRE_PLL BIT(5) /* source is before PLL mult/div */
|
||||
|
||||
struct davinci_clk {
|
||||
struct clk_lookup lk;
|
||||
};
|
||||
#define CLK(dev, con, ck) \
|
||||
{ \
|
||||
.dev_id = dev, \
|
||||
.con_id = con, \
|
||||
.clk = ck, \
|
||||
} \
|
||||
|
||||
#define CLK(dev, con, ck) \
|
||||
{ \
|
||||
.lk = { \
|
||||
.dev_id = dev, \
|
||||
.con_id = con, \
|
||||
.clk = ck, \
|
||||
}, \
|
||||
}
|
||||
|
||||
int davinci_clk_init(struct davinci_clk *clocks);
|
||||
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);
|
||||
|
||||
extern struct platform_device davinci_wdt_device;
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -11,13 +11,13 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/davinci_emac.h>
|
||||
|
||||
#include <asm/tlb.h>
|
||||
#include <asm/mach/map.h>
|
||||
|
||||
#include <mach/common.h>
|
||||
#include <mach/cputype.h>
|
||||
#include <mach/emac.h>
|
||||
|
||||
#include "clock.h"
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <asm/proc-fns.h>
|
||||
|
||||
#include <mach/cpuidle.h>
|
||||
#include <mach/memory.h>
|
||||
|
||||
#define DAVINCI_CPUIDLE_MAX_STATES 2
|
||||
|
||||
@ -39,10 +40,6 @@ static struct cpuidle_driver davinci_idle_driver = {
|
||||
static DEFINE_PER_CPU(struct cpuidle_device, davinci_cpuidle_device);
|
||||
static void __iomem *ddr2_reg_base;
|
||||
|
||||
#define DDR2_SDRCR_OFFSET 0xc
|
||||
#define DDR2_SRPD_BIT BIT(23)
|
||||
#define DDR2_LPMODEN_BIT BIT(31)
|
||||
|
||||
static void davinci_save_ddr_power(int enter, bool pdown)
|
||||
{
|
||||
u32 val;
|
||||
@ -109,8 +106,6 @@ static int __init davinci_cpuidle_probe(struct platform_device *pdev)
|
||||
int ret;
|
||||
struct cpuidle_device *device;
|
||||
struct davinci_cpuidle_config *pdata = pdev->dev.platform_data;
|
||||
struct resource *ddr2_regs;
|
||||
resource_size_t len;
|
||||
|
||||
device = &per_cpu(davinci_cpuidle_device, smp_processor_id());
|
||||
|
||||
@ -119,28 +114,12 @@ static int __init davinci_cpuidle_probe(struct platform_device *pdev)
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
ddr2_regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!ddr2_regs) {
|
||||
dev_err(&pdev->dev, "cannot get DDR2 controller register base");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
len = resource_size(ddr2_regs);
|
||||
|
||||
ddr2_regs = request_mem_region(ddr2_regs->start, len, ddr2_regs->name);
|
||||
if (!ddr2_regs)
|
||||
return -EBUSY;
|
||||
|
||||
ddr2_reg_base = ioremap(ddr2_regs->start, len);
|
||||
if (!ddr2_reg_base) {
|
||||
ret = -ENOMEM;
|
||||
goto ioremap_fail;
|
||||
}
|
||||
ddr2_reg_base = pdata->ddr2_ctlr_base;
|
||||
|
||||
ret = cpuidle_register_driver(&davinci_idle_driver);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to register driver\n");
|
||||
goto driver_register_fail;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Wait for interrupt state */
|
||||
@ -167,18 +146,11 @@ static int __init davinci_cpuidle_probe(struct platform_device *pdev)
|
||||
ret = cpuidle_register_device(device);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to register device\n");
|
||||
goto device_register_fail;
|
||||
cpuidle_unregister_driver(&davinci_idle_driver);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
device_register_fail:
|
||||
cpuidle_unregister_driver(&davinci_idle_driver);
|
||||
driver_register_fail:
|
||||
iounmap(ddr2_reg_base);
|
||||
ioremap_fail:
|
||||
release_mem_region(ddr2_regs->start, len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct platform_driver davinci_cpuidle_driver = {
|
||||
|
@ -371,7 +371,7 @@ static struct clk rmii_clk = {
|
||||
.parent = &pll0_sysclk7,
|
||||
};
|
||||
|
||||
static struct davinci_clk da830_clks[] = {
|
||||
static struct clk_lookup da830_clks[] = {
|
||||
CLK(NULL, "ref", &ref_clk),
|
||||
CLK(NULL, "pll0", &pll0_clk),
|
||||
CLK(NULL, "pll0_aux", &pll0_aux_clk),
|
||||
@ -1208,13 +1208,13 @@ static struct davinci_soc_info davinci_soc_info_da830 = {
|
||||
|
||||
void __init da830_init(void)
|
||||
{
|
||||
da8xx_syscfg_base = ioremap(DA8XX_SYSCFG_BASE, SZ_4K);
|
||||
if (WARN(!da8xx_syscfg_base, "Unable to map syscfg module"))
|
||||
da8xx_syscfg0_base = ioremap(DA8XX_SYSCFG0_BASE, SZ_4K);
|
||||
if (WARN(!da8xx_syscfg0_base, "Unable to map syscfg0 module"))
|
||||
return;
|
||||
|
||||
davinci_soc_info_da830.jtag_id_base =
|
||||
DA8XX_SYSCFG_VIRT(DA8XX_JTAG_ID_REG);
|
||||
davinci_soc_info_da830.pinmux_base = DA8XX_SYSCFG_VIRT(0x120);
|
||||
DA8XX_SYSCFG0_VIRT(DA8XX_JTAG_ID_REG);
|
||||
davinci_soc_info_da830.pinmux_base = DA8XX_SYSCFG0_VIRT(0x120);
|
||||
|
||||
davinci_common_init(&davinci_soc_info_da830);
|
||||
}
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <mach/time.h>
|
||||
#include <mach/da8xx.h>
|
||||
#include <mach/cpufreq.h>
|
||||
#include <mach/pm.h>
|
||||
|
||||
#include "clock.h"
|
||||
#include "mux.h"
|
||||
@ -40,6 +41,7 @@
|
||||
#define DA850_REF_FREQ 24000000
|
||||
|
||||
#define CFGCHIP3_ASYNC3_CLKSRC BIT(4)
|
||||
#define CFGCHIP3_PLL1_MASTER_LOCK BIT(5)
|
||||
#define CFGCHIP0_PLL_MASTER_LOCK BIT(4)
|
||||
|
||||
static int da850_set_armrate(struct clk *clk, unsigned long rate);
|
||||
@ -333,7 +335,7 @@ static struct clk aemif_clk = {
|
||||
.flags = ALWAYS_ENABLED,
|
||||
};
|
||||
|
||||
static struct davinci_clk da850_clks[] = {
|
||||
static struct clk_lookup da850_clks[] = {
|
||||
CLK(NULL, "ref", &ref_clk),
|
||||
CLK(NULL, "pll0", &pll0_clk),
|
||||
CLK(NULL, "pll0_aux", &pll0_aux_clk),
|
||||
@ -535,6 +537,7 @@ static const struct mux_config da850_pins[] = {
|
||||
MUX_CFG(DA850, GPIO2_15, 5, 0, 15, 8, false)
|
||||
MUX_CFG(DA850, GPIO4_0, 10, 28, 15, 8, false)
|
||||
MUX_CFG(DA850, GPIO4_1, 10, 24, 15, 8, false)
|
||||
MUX_CFG(DA850, RTC_ALARM, 0, 28, 15, 2, false)
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -770,6 +773,12 @@ static struct map_desc da850_io_desc[] = {
|
||||
.length = DA8XX_CP_INTC_SIZE,
|
||||
.type = MT_DEVICE
|
||||
},
|
||||
{
|
||||
.virtual = SRAM_VIRT,
|
||||
.pfn = __phys_to_pfn(DA8XX_ARM_RAM_BASE),
|
||||
.length = SZ_8K,
|
||||
.type = MT_DEVICE
|
||||
},
|
||||
};
|
||||
|
||||
static void __iomem *da850_psc_bases[] = {
|
||||
@ -825,12 +834,12 @@ static struct davinci_timer_info da850_timer_info = {
|
||||
static void da850_set_async3_src(int pllnum)
|
||||
{
|
||||
struct clk *clk, *newparent = pllnum ? &pll1_sysclk2 : &pll0_sysclk2;
|
||||
struct davinci_clk *c;
|
||||
struct clk_lookup *c;
|
||||
unsigned int v;
|
||||
int ret;
|
||||
|
||||
for (c = da850_clks; c->lk.clk; c++) {
|
||||
clk = c->lk.clk;
|
||||
for (c = da850_clks; c->clk; c++) {
|
||||
clk = c->clk;
|
||||
if (clk->flags & DA850_CLK_ASYNC3) {
|
||||
ret = clk_set_parent(clk, newparent);
|
||||
WARN(ret, "DA850: unable to re-parent clock %s",
|
||||
@ -838,12 +847,12 @@ static void da850_set_async3_src(int pllnum)
|
||||
}
|
||||
}
|
||||
|
||||
v = __raw_readl(DA8XX_SYSCFG_VIRT(DA8XX_CFGCHIP3_REG));
|
||||
v = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
|
||||
if (pllnum)
|
||||
v |= CFGCHIP3_ASYNC3_CLKSRC;
|
||||
else
|
||||
v &= ~CFGCHIP3_ASYNC3_CLKSRC;
|
||||
__raw_writel(v, DA8XX_SYSCFG_VIRT(DA8XX_CFGCHIP3_REG));
|
||||
__raw_writel(v, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CPU_FREQ
|
||||
@ -987,7 +996,6 @@ static int da850_set_pll0rate(struct clk *clk, unsigned long index)
|
||||
unsigned int prediv, mult, postdiv;
|
||||
struct da850_opp *opp;
|
||||
struct pll_data *pll = clk->pll_data;
|
||||
unsigned int v;
|
||||
int ret;
|
||||
|
||||
opp = (struct da850_opp *) da850_freq_table[index].index;
|
||||
@ -995,11 +1003,6 @@ static int da850_set_pll0rate(struct clk *clk, unsigned long index)
|
||||
mult = opp->mult;
|
||||
postdiv = opp->postdiv;
|
||||
|
||||
/* Unlock writing to PLL registers */
|
||||
v = __raw_readl(DA8XX_SYSCFG_VIRT(DA8XX_CFGCHIP0_REG));
|
||||
v &= ~CFGCHIP0_PLL_MASTER_LOCK;
|
||||
__raw_writel(v, DA8XX_SYSCFG_VIRT(DA8XX_CFGCHIP0_REG));
|
||||
|
||||
ret = davinci_set_pllrate(pll, prediv, mult, postdiv);
|
||||
if (WARN_ON(ret))
|
||||
return ret;
|
||||
@ -1028,6 +1031,43 @@ static int da850_round_armrate(struct clk *clk, unsigned long rate)
|
||||
}
|
||||
#endif
|
||||
|
||||
int da850_register_pm(struct platform_device *pdev)
|
||||
{
|
||||
int ret;
|
||||
struct davinci_pm_config *pdata = pdev->dev.platform_data;
|
||||
|
||||
ret = davinci_cfg_reg(DA850_RTC_ALARM);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pdata->ddr2_ctlr_base = da8xx_get_mem_ctlr();
|
||||
pdata->deepsleep_reg = DA8XX_SYSCFG1_VIRT(DA8XX_DEEPSLEEP_REG);
|
||||
pdata->ddrpsc_num = DA8XX_LPSC1_EMIF3C;
|
||||
|
||||
pdata->cpupll_reg_base = ioremap(DA8XX_PLL0_BASE, SZ_4K);
|
||||
if (!pdata->cpupll_reg_base)
|
||||
return -ENOMEM;
|
||||
|
||||
pdata->ddrpll_reg_base = ioremap(DA8XX_PLL1_BASE, SZ_4K);
|
||||
if (!pdata->ddrpll_reg_base) {
|
||||
ret = -ENOMEM;
|
||||
goto no_ddrpll_mem;
|
||||
}
|
||||
|
||||
pdata->ddrpsc_reg_base = ioremap(DA8XX_PSC1_BASE, SZ_4K);
|
||||
if (!pdata->ddrpsc_reg_base) {
|
||||
ret = -ENOMEM;
|
||||
goto no_ddrpsc_mem;
|
||||
}
|
||||
|
||||
return platform_device_register(pdev);
|
||||
|
||||
no_ddrpsc_mem:
|
||||
iounmap(pdata->ddrpll_reg_base);
|
||||
no_ddrpll_mem:
|
||||
iounmap(pdata->cpupll_reg_base);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct davinci_soc_info davinci_soc_info_da850 = {
|
||||
.io_desc = da850_io_desc,
|
||||
@ -1049,17 +1089,25 @@ static struct davinci_soc_info davinci_soc_info_da850 = {
|
||||
.gpio_irq = IRQ_DA8XX_GPIO0,
|
||||
.serial_dev = &da8xx_serial_device,
|
||||
.emac_pdata = &da8xx_emac_pdata,
|
||||
.sram_dma = DA8XX_ARM_RAM_BASE,
|
||||
.sram_len = SZ_8K,
|
||||
};
|
||||
|
||||
void __init da850_init(void)
|
||||
{
|
||||
da8xx_syscfg_base = ioremap(DA8XX_SYSCFG_BASE, SZ_4K);
|
||||
if (WARN(!da8xx_syscfg_base, "Unable to map syscfg module"))
|
||||
unsigned int v;
|
||||
|
||||
da8xx_syscfg0_base = ioremap(DA8XX_SYSCFG0_BASE, SZ_4K);
|
||||
if (WARN(!da8xx_syscfg0_base, "Unable to map syscfg0 module"))
|
||||
return;
|
||||
|
||||
da8xx_syscfg1_base = ioremap(DA8XX_SYSCFG1_BASE, SZ_4K);
|
||||
if (WARN(!da8xx_syscfg1_base, "Unable to map syscfg1 module"))
|
||||
return;
|
||||
|
||||
davinci_soc_info_da850.jtag_id_base =
|
||||
DA8XX_SYSCFG_VIRT(DA8XX_JTAG_ID_REG);
|
||||
davinci_soc_info_da850.pinmux_base = DA8XX_SYSCFG_VIRT(0x120);
|
||||
DA8XX_SYSCFG0_VIRT(DA8XX_JTAG_ID_REG);
|
||||
davinci_soc_info_da850.pinmux_base = DA8XX_SYSCFG0_VIRT(0x120);
|
||||
|
||||
davinci_common_init(&davinci_soc_info_da850);
|
||||
|
||||
@ -1071,4 +1119,14 @@ void __init da850_init(void)
|
||||
* be any noticible change even in non-DVFS use cases.
|
||||
*/
|
||||
da850_set_async3_src(1);
|
||||
|
||||
/* Unlock writing to PLL0 registers */
|
||||
v = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP0_REG));
|
||||
v &= ~CFGCHIP0_PLL_MASTER_LOCK;
|
||||
__raw_writel(v, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP0_REG));
|
||||
|
||||
/* Unlock writing to PLL1 registers */
|
||||
v = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
|
||||
v &= ~CFGCHIP3_PLL1_MASTER_LOCK;
|
||||
__raw_writel(v, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
|
||||
}
|
||||
|
@ -24,8 +24,10 @@
|
||||
#include "clock.h"
|
||||
|
||||
#define DA8XX_TPCC_BASE 0x01c00000
|
||||
#define DA850_TPCC1_BASE 0x01e30000
|
||||
#define DA8XX_TPTC0_BASE 0x01c08000
|
||||
#define DA8XX_TPTC1_BASE 0x01c08400
|
||||
#define DA850_TPTC2_BASE 0x01e38000
|
||||
#define DA8XX_WDOG_BASE 0x01c21000 /* DA8XX_TIMER64P1_BASE */
|
||||
#define DA8XX_I2C0_BASE 0x01c22000
|
||||
#define DA8XX_RTC_BASE 0x01C23000
|
||||
@ -42,7 +44,8 @@
|
||||
#define DA8XX_MDIO_REG_OFFSET 0x4000
|
||||
#define DA8XX_EMAC_CTRL_RAM_SIZE SZ_8K
|
||||
|
||||
void __iomem *da8xx_syscfg_base;
|
||||
void __iomem *da8xx_syscfg0_base;
|
||||
void __iomem *da8xx_syscfg1_base;
|
||||
|
||||
static struct plat_serial8250_port da8xx_serial_pdata[] = {
|
||||
{
|
||||
@ -82,11 +85,6 @@ struct platform_device da8xx_serial_device = {
|
||||
},
|
||||
};
|
||||
|
||||
static const s8 da8xx_dma_chan_no_event[] = {
|
||||
20, 21,
|
||||
-1
|
||||
};
|
||||
|
||||
static const s8 da8xx_queue_tc_mapping[][2] = {
|
||||
/* {event queue no, TC no} */
|
||||
{0, 0},
|
||||
@ -101,20 +99,52 @@ static const s8 da8xx_queue_priority_mapping[][2] = {
|
||||
{-1, -1}
|
||||
};
|
||||
|
||||
static struct edma_soc_info da8xx_edma_info[] = {
|
||||
static const s8 da850_queue_tc_mapping[][2] = {
|
||||
/* {event queue no, TC no} */
|
||||
{0, 0},
|
||||
{-1, -1}
|
||||
};
|
||||
|
||||
static const s8 da850_queue_priority_mapping[][2] = {
|
||||
/* {event queue no, Priority} */
|
||||
{0, 3},
|
||||
{-1, -1}
|
||||
};
|
||||
|
||||
static struct edma_soc_info da830_edma_info[] = {
|
||||
{
|
||||
.n_channel = 32,
|
||||
.n_region = 4,
|
||||
.n_slot = 128,
|
||||
.n_tc = 2,
|
||||
.n_cc = 1,
|
||||
.noevent = da8xx_dma_chan_no_event,
|
||||
.queue_tc_mapping = da8xx_queue_tc_mapping,
|
||||
.queue_priority_mapping = da8xx_queue_priority_mapping,
|
||||
},
|
||||
};
|
||||
|
||||
static struct resource da8xx_edma_resources[] = {
|
||||
static struct edma_soc_info da850_edma_info[] = {
|
||||
{
|
||||
.n_channel = 32,
|
||||
.n_region = 4,
|
||||
.n_slot = 128,
|
||||
.n_tc = 2,
|
||||
.n_cc = 1,
|
||||
.queue_tc_mapping = da8xx_queue_tc_mapping,
|
||||
.queue_priority_mapping = da8xx_queue_priority_mapping,
|
||||
},
|
||||
{
|
||||
.n_channel = 32,
|
||||
.n_region = 4,
|
||||
.n_slot = 128,
|
||||
.n_tc = 1,
|
||||
.n_cc = 1,
|
||||
.queue_tc_mapping = da850_queue_tc_mapping,
|
||||
.queue_priority_mapping = da850_queue_priority_mapping,
|
||||
},
|
||||
};
|
||||
|
||||
static struct resource da830_edma_resources[] = {
|
||||
{
|
||||
.name = "edma_cc0",
|
||||
.start = DA8XX_TPCC_BASE,
|
||||
@ -145,19 +175,91 @@ static struct resource da8xx_edma_resources[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device da8xx_edma_device = {
|
||||
static struct resource da850_edma_resources[] = {
|
||||
{
|
||||
.name = "edma_cc0",
|
||||
.start = DA8XX_TPCC_BASE,
|
||||
.end = DA8XX_TPCC_BASE + SZ_32K - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.name = "edma_tc0",
|
||||
.start = DA8XX_TPTC0_BASE,
|
||||
.end = DA8XX_TPTC0_BASE + SZ_1K - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.name = "edma_tc1",
|
||||
.start = DA8XX_TPTC1_BASE,
|
||||
.end = DA8XX_TPTC1_BASE + SZ_1K - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.name = "edma_cc1",
|
||||
.start = DA850_TPCC1_BASE,
|
||||
.end = DA850_TPCC1_BASE + SZ_32K - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.name = "edma_tc2",
|
||||
.start = DA850_TPTC2_BASE,
|
||||
.end = DA850_TPTC2_BASE + SZ_1K - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.name = "edma0",
|
||||
.start = IRQ_DA8XX_CCINT0,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.name = "edma0_err",
|
||||
.start = IRQ_DA8XX_CCERRINT,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.name = "edma1",
|
||||
.start = IRQ_DA850_CCINT1,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.name = "edma1_err",
|
||||
.start = IRQ_DA850_CCERRINT1,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device da830_edma_device = {
|
||||
.name = "edma",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = da8xx_edma_info,
|
||||
.platform_data = da830_edma_info,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(da8xx_edma_resources),
|
||||
.resource = da8xx_edma_resources,
|
||||
.num_resources = ARRAY_SIZE(da830_edma_resources),
|
||||
.resource = da830_edma_resources,
|
||||
};
|
||||
|
||||
static struct platform_device da850_edma_device = {
|
||||
.name = "edma",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = da850_edma_info,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(da850_edma_resources),
|
||||
.resource = da850_edma_resources,
|
||||
};
|
||||
|
||||
int __init da8xx_register_edma(void)
|
||||
{
|
||||
return platform_device_register(&da8xx_edma_device);
|
||||
struct platform_device *pdev;
|
||||
|
||||
if (cpu_is_davinci_da830())
|
||||
pdev = &da830_edma_device;
|
||||
else if (cpu_is_davinci_da850())
|
||||
pdev = &da850_edma_device;
|
||||
else
|
||||
return -ENODEV;
|
||||
|
||||
return platform_device_register(pdev);
|
||||
}
|
||||
|
||||
static struct resource da8xx_i2c_resources0[] = {
|
||||
@ -495,6 +597,19 @@ int da8xx_register_rtc(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __iomem *da8xx_ddr2_ctlr_base;
|
||||
void __iomem * __init da8xx_get_mem_ctlr(void)
|
||||
{
|
||||
if (da8xx_ddr2_ctlr_base)
|
||||
return da8xx_ddr2_ctlr_base;
|
||||
|
||||
da8xx_ddr2_ctlr_base = ioremap(DA8XX_DDR2_CTL_BASE, SZ_32K);
|
||||
if (!da8xx_ddr2_ctlr_base)
|
||||
pr_warning("%s: Unable to map DDR2 controller", __func__);
|
||||
|
||||
return da8xx_ddr2_ctlr_base;
|
||||
}
|
||||
|
||||
static struct resource da8xx_cpuidle_resources[] = {
|
||||
{
|
||||
.start = DA8XX_DDR2_CTL_BASE,
|
||||
@ -520,6 +635,7 @@ static struct platform_device da8xx_cpuidle_device = {
|
||||
|
||||
int __init da8xx_register_cpuidle(void)
|
||||
{
|
||||
da8xx_cpuidle_pdata.ddr2_ctlr_base = da8xx_get_mem_ctlr();
|
||||
|
||||
return platform_device_register(&da8xx_cpuidle_device);
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include <mach/serial.h>
|
||||
#include <mach/common.h>
|
||||
#include <mach/asp.h>
|
||||
#include <mach/spi.h>
|
||||
|
||||
#include "clock.h"
|
||||
#include "mux.h"
|
||||
@ -334,7 +335,7 @@ static struct clk usb_clk = {
|
||||
.lpsc = DAVINCI_LPSC_USB,
|
||||
};
|
||||
|
||||
static struct davinci_clk dm355_clks[] = {
|
||||
static struct clk_lookup dm355_clks[] = {
|
||||
CLK(NULL, "ref", &ref_clk),
|
||||
CLK(NULL, "pll1", &pll1_clk),
|
||||
CLK(NULL, "pll1_sysclk1", &pll1_sysclk1),
|
||||
@ -362,9 +363,9 @@ static struct davinci_clk dm355_clks[] = {
|
||||
CLK("davinci-asp.1", NULL, &asp1_clk),
|
||||
CLK("davinci_mmc.0", NULL, &mmcsd0_clk),
|
||||
CLK("davinci_mmc.1", NULL, &mmcsd1_clk),
|
||||
CLK(NULL, "spi0", &spi0_clk),
|
||||
CLK(NULL, "spi1", &spi1_clk),
|
||||
CLK(NULL, "spi2", &spi2_clk),
|
||||
CLK("spi_davinci.0", NULL, &spi0_clk),
|
||||
CLK("spi_davinci.1", NULL, &spi1_clk),
|
||||
CLK("spi_davinci.2", NULL, &spi2_clk),
|
||||
CLK(NULL, "gpio", &gpio_clk),
|
||||
CLK(NULL, "aemif", &aemif_clk),
|
||||
CLK(NULL, "pwm0", &pwm0_clk),
|
||||
@ -391,24 +392,40 @@ static struct resource dm355_spi0_resources[] = {
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = IRQ_DM355_SPINT0_1,
|
||||
.start = IRQ_DM355_SPINT0_0,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
/* Not yet used, so not included:
|
||||
* IORESOURCE_IRQ:
|
||||
* - IRQ_DM355_SPINT0_0
|
||||
* IORESOURCE_DMA:
|
||||
* - DAVINCI_DMA_SPI_SPIX
|
||||
* - DAVINCI_DMA_SPI_SPIR
|
||||
*/
|
||||
{
|
||||
.start = 17,
|
||||
.flags = IORESOURCE_DMA,
|
||||
},
|
||||
{
|
||||
.start = 16,
|
||||
.flags = IORESOURCE_DMA,
|
||||
},
|
||||
{
|
||||
.start = EVENTQ_1,
|
||||
.flags = IORESOURCE_DMA,
|
||||
},
|
||||
};
|
||||
|
||||
static struct davinci_spi_platform_data dm355_spi0_pdata = {
|
||||
.version = SPI_VERSION_1,
|
||||
.num_chipselect = 2,
|
||||
.clk_internal = 1,
|
||||
.cs_hold = 1,
|
||||
.intr_level = 0,
|
||||
.poll_mode = 1, /* 0 -> interrupt mode 1-> polling mode */
|
||||
.c2tdelay = 0,
|
||||
.t2cdelay = 0,
|
||||
};
|
||||
static struct platform_device dm355_spi0_device = {
|
||||
.name = "spi_davinci",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.dma_mask = &dm355_spi0_dma_mask,
|
||||
.coherent_dma_mask = DMA_BIT_MASK(32),
|
||||
.platform_data = &dm355_spi0_pdata,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(dm355_spi0_resources),
|
||||
.resource = dm355_spi0_resources,
|
||||
@ -563,13 +580,6 @@ static u8 dm355_default_priorities[DAVINCI_N_AINTC_IRQ] = {
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
static const s8 dma_chan_dm355_no_event[] = {
|
||||
12, 13, 24, 56, 57,
|
||||
58, 59, 60, 61, 62,
|
||||
63,
|
||||
-1
|
||||
};
|
||||
|
||||
static const s8
|
||||
queue_tc_mapping[][2] = {
|
||||
/* {event queue no, TC no} */
|
||||
@ -593,7 +603,6 @@ static struct edma_soc_info dm355_edma_info[] = {
|
||||
.n_slot = 128,
|
||||
.n_tc = 2,
|
||||
.n_cc = 1,
|
||||
.noevent = dma_chan_dm355_no_event,
|
||||
.queue_tc_mapping = queue_tc_mapping,
|
||||
.queue_priority_mapping = queue_priority_mapping,
|
||||
},
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/spi/spi.h>
|
||||
|
||||
#include <asm/mach/map.h>
|
||||
|
||||
@ -32,6 +33,8 @@
|
||||
#include <mach/common.h>
|
||||
#include <mach/asp.h>
|
||||
#include <mach/keyscan.h>
|
||||
#include <mach/spi.h>
|
||||
|
||||
|
||||
#include "clock.h"
|
||||
#include "mux.h"
|
||||
@ -403,7 +406,7 @@ static struct clk mjcp_clk = {
|
||||
.lpsc = DM365_LPSC_MJCP,
|
||||
};
|
||||
|
||||
static struct davinci_clk dm365_clks[] = {
|
||||
static struct clk_lookup dm365_clks[] = {
|
||||
CLK(NULL, "ref", &ref_clk),
|
||||
CLK(NULL, "pll1", &pll1_clk),
|
||||
CLK(NULL, "pll1_aux", &pll1_aux_clk),
|
||||
@ -455,7 +458,7 @@ static struct davinci_clk dm365_clks[] = {
|
||||
CLK(NULL, "timer3", &timer3_clk),
|
||||
CLK(NULL, "usb", &usb_clk),
|
||||
CLK("davinci_emac.1", NULL, &emac_clk),
|
||||
CLK("voice_codec", NULL, &voicecodec_clk),
|
||||
CLK("davinci_voicecodec", NULL, &voicecodec_clk),
|
||||
CLK("davinci-asp.0", NULL, &asp0_clk),
|
||||
CLK(NULL, "rto", &rto_clk),
|
||||
CLK(NULL, "mjcp", &mjcp_clk),
|
||||
@ -606,9 +609,78 @@ INT_CFG(DM365, INT_NSF_DISABLE, 25, 1, 0, false)
|
||||
|
||||
EVT_CFG(DM365, EVT2_ASP_TX, 0, 1, 0, false)
|
||||
EVT_CFG(DM365, EVT3_ASP_RX, 1, 1, 0, false)
|
||||
EVT_CFG(DM365, EVT2_VC_TX, 0, 1, 1, false)
|
||||
EVT_CFG(DM365, EVT3_VC_RX, 1, 1, 1, false)
|
||||
#endif
|
||||
};
|
||||
|
||||
static u64 dm365_spi0_dma_mask = DMA_BIT_MASK(32);
|
||||
|
||||
static struct davinci_spi_platform_data dm365_spi0_pdata = {
|
||||
.version = SPI_VERSION_1,
|
||||
.num_chipselect = 2,
|
||||
.clk_internal = 1,
|
||||
.cs_hold = 1,
|
||||
.intr_level = 0,
|
||||
.poll_mode = 1, /* 0 -> interrupt mode 1-> polling mode */
|
||||
.c2tdelay = 0,
|
||||
.t2cdelay = 0,
|
||||
};
|
||||
|
||||
static struct resource dm365_spi0_resources[] = {
|
||||
{
|
||||
.start = 0x01c66000,
|
||||
.end = 0x01c667ff,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = IRQ_DM365_SPIINT0_0,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.start = 17,
|
||||
.flags = IORESOURCE_DMA,
|
||||
},
|
||||
{
|
||||
.start = 16,
|
||||
.flags = IORESOURCE_DMA,
|
||||
},
|
||||
{
|
||||
.start = EVENTQ_3,
|
||||
.flags = IORESOURCE_DMA,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device dm365_spi0_device = {
|
||||
.name = "spi_davinci",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.dma_mask = &dm365_spi0_dma_mask,
|
||||
.coherent_dma_mask = DMA_BIT_MASK(32),
|
||||
.platform_data = &dm365_spi0_pdata,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(dm365_spi0_resources),
|
||||
.resource = dm365_spi0_resources,
|
||||
};
|
||||
|
||||
void __init dm365_init_spi0(unsigned chipselect_mask,
|
||||
struct spi_board_info *info, unsigned len)
|
||||
{
|
||||
davinci_cfg_reg(DM365_SPI0_SCLK);
|
||||
davinci_cfg_reg(DM365_SPI0_SDI);
|
||||
davinci_cfg_reg(DM365_SPI0_SDO);
|
||||
|
||||
/* not all slaves will be wired up */
|
||||
if (chipselect_mask & BIT(0))
|
||||
davinci_cfg_reg(DM365_SPI0_SDENA0);
|
||||
if (chipselect_mask & BIT(1))
|
||||
davinci_cfg_reg(DM365_SPI0_SDENA1);
|
||||
|
||||
spi_register_board_info(info, len);
|
||||
|
||||
platform_device_register(&dm365_spi0_device);
|
||||
}
|
||||
|
||||
static struct emac_platform_data dm365_emac_pdata = {
|
||||
.ctrl_reg_offset = DM365_EMAC_CNTRL_OFFSET,
|
||||
.ctrl_mod_reg_offset = DM365_EMAC_CNTRL_MOD_OFFSET,
|
||||
@ -754,7 +826,7 @@ static struct edma_soc_info dm365_edma_info[] = {
|
||||
.n_cc = 1,
|
||||
.queue_tc_mapping = dm365_queue_tc_mapping,
|
||||
.queue_priority_mapping = dm365_queue_priority_mapping,
|
||||
.default_queue = EVENTQ_2,
|
||||
.default_queue = EVENTQ_3,
|
||||
},
|
||||
};
|
||||
|
||||
@ -835,6 +907,31 @@ static struct platform_device dm365_asp_device = {
|
||||
.resource = dm365_asp_resources,
|
||||
};
|
||||
|
||||
static struct resource dm365_vc_resources[] = {
|
||||
{
|
||||
.start = DAVINCI_DM365_VC_BASE,
|
||||
.end = DAVINCI_DM365_VC_BASE + SZ_1K - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = DAVINCI_DMA_VC_TX,
|
||||
.end = DAVINCI_DMA_VC_TX,
|
||||
.flags = IORESOURCE_DMA,
|
||||
},
|
||||
{
|
||||
.start = DAVINCI_DMA_VC_RX,
|
||||
.end = DAVINCI_DMA_VC_RX,
|
||||
.flags = IORESOURCE_DMA,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device dm365_vc_device = {
|
||||
.name = "davinci_voicecodec",
|
||||
.id = -1,
|
||||
.num_resources = ARRAY_SIZE(dm365_vc_resources),
|
||||
.resource = dm365_vc_resources,
|
||||
};
|
||||
|
||||
static struct resource dm365_rtc_resources[] = {
|
||||
{
|
||||
.start = DM365_RTC_BASE,
|
||||
@ -991,6 +1088,14 @@ void __init dm365_init_asp(struct snd_platform_data *pdata)
|
||||
platform_device_register(&dm365_asp_device);
|
||||
}
|
||||
|
||||
void __init dm365_init_vc(struct snd_platform_data *pdata)
|
||||
{
|
||||
davinci_cfg_reg(DM365_EVT2_VC_TX);
|
||||
davinci_cfg_reg(DM365_EVT3_VC_RX);
|
||||
dm365_vc_device.dev.platform_data = pdata;
|
||||
platform_device_register(&dm365_vc_device);
|
||||
}
|
||||
|
||||
void __init dm365_init_ks(struct davinci_ks_platform_data *pdata)
|
||||
{
|
||||
dm365_ks_device.dev.platform_data = pdata;
|
||||
|
@ -277,7 +277,7 @@ static struct clk timer2_clk = {
|
||||
.usecount = 1, /* REVISIT: why cant' this be disabled? */
|
||||
};
|
||||
|
||||
struct davinci_clk dm644x_clks[] = {
|
||||
struct clk_lookup dm644x_clks[] = {
|
||||
CLK(NULL, "ref", &ref_clk),
|
||||
CLK(NULL, "pll1", &pll1_clk),
|
||||
CLK(NULL, "pll1_sysclk1", &pll1_sysclk1),
|
||||
@ -479,15 +479,6 @@ static u8 dm644x_default_priorities[DAVINCI_N_AINTC_IRQ] = {
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
static const s8 dma_chan_dm644x_no_event[] = {
|
||||
0, 1, 12, 13, 14,
|
||||
15, 25, 30, 31, 45,
|
||||
46, 47, 55, 56, 57,
|
||||
58, 59, 60, 61, 62,
|
||||
63,
|
||||
-1
|
||||
};
|
||||
|
||||
static const s8
|
||||
queue_tc_mapping[][2] = {
|
||||
/* {event queue no, TC no} */
|
||||
@ -511,7 +502,6 @@ static struct edma_soc_info dm644x_edma_info[] = {
|
||||
.n_slot = 128,
|
||||
.n_tc = 2,
|
||||
.n_cc = 1,
|
||||
.noevent = dma_chan_dm644x_no_event,
|
||||
.queue_tc_mapping = queue_tc_mapping,
|
||||
.queue_priority_mapping = queue_priority_mapping,
|
||||
},
|
||||
|
@ -42,7 +42,6 @@
|
||||
/*
|
||||
* Device specific clocks
|
||||
*/
|
||||
#define DM646X_REF_FREQ 27000000
|
||||
#define DM646X_AUX_FREQ 24000000
|
||||
|
||||
static struct pll_data pll1_data = {
|
||||
@ -57,7 +56,6 @@ static struct pll_data pll2_data = {
|
||||
|
||||
static struct clk ref_clk = {
|
||||
.name = "ref_clk",
|
||||
.rate = DM646X_REF_FREQ,
|
||||
};
|
||||
|
||||
static struct clk aux_clkin = {
|
||||
@ -313,7 +311,7 @@ static struct clk vpif1_clk = {
|
||||
.flags = ALWAYS_ENABLED,
|
||||
};
|
||||
|
||||
struct davinci_clk dm646x_clks[] = {
|
||||
struct clk_lookup dm646x_clks[] = {
|
||||
CLK(NULL, "ref", &ref_clk),
|
||||
CLK(NULL, "aux", &aux_clkin),
|
||||
CLK(NULL, "pll1", &pll1_clk),
|
||||
@ -513,14 +511,6 @@ static u8 dm646x_default_priorities[DAVINCI_N_AINTC_IRQ] = {
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
static const s8 dma_chan_dm646x_no_event[] = {
|
||||
0, 1, 2, 3, 13,
|
||||
14, 15, 24, 25, 26,
|
||||
27, 30, 31, 54, 55,
|
||||
56,
|
||||
-1
|
||||
};
|
||||
|
||||
/* Four Transfer Controllers on DM646x */
|
||||
static const s8
|
||||
dm646x_queue_tc_mapping[][2] = {
|
||||
@ -549,7 +539,6 @@ static struct edma_soc_info dm646x_edma_info[] = {
|
||||
.n_slot = 512,
|
||||
.n_tc = 4,
|
||||
.n_cc = 1,
|
||||
.noevent = dma_chan_dm646x_no_event,
|
||||
.queue_tc_mapping = dm646x_queue_tc_mapping,
|
||||
.queue_priority_mapping = dm646x_queue_priority_mapping,
|
||||
},
|
||||
@ -925,6 +914,7 @@ void dm646x_setup_vpif(struct vpif_display_config *display_config,
|
||||
|
||||
void __init dm646x_init(void)
|
||||
{
|
||||
dm646x_board_setup_refclk(&ref_clk);
|
||||
davinci_common_init(&davinci_soc_info_dm646x);
|
||||
}
|
||||
|
||||
|
@ -226,11 +226,11 @@ struct edma {
|
||||
*/
|
||||
DECLARE_BITMAP(edma_inuse, EDMA_MAX_PARAMENTRY);
|
||||
|
||||
/* The edma_noevent bit for each channel is clear unless
|
||||
* it doesn't trigger DMA events on this platform. It uses a
|
||||
* bit of SOC-specific initialization code.
|
||||
/* The edma_unused bit for each channel is clear unless
|
||||
* it is not being used on this platform. It uses a bit
|
||||
* of SOC-specific initialization code.
|
||||
*/
|
||||
DECLARE_BITMAP(edma_noevent, EDMA_MAX_DMACH);
|
||||
DECLARE_BITMAP(edma_unused, EDMA_MAX_DMACH);
|
||||
|
||||
unsigned irq_res_start;
|
||||
unsigned irq_res_end;
|
||||
@ -243,6 +243,7 @@ struct edma {
|
||||
};
|
||||
|
||||
static struct edma *edma_info[EDMA_MAX_CC];
|
||||
static int arch_num_cc;
|
||||
|
||||
/* dummy param set used to (re)initialize parameter RAM slots */
|
||||
static const struct edmacc_param dummy_paramset = {
|
||||
@ -555,8 +556,27 @@ static int reserve_contiguous_slots(int ctlr, unsigned int id,
|
||||
return EDMA_CTLR_CHAN(ctlr, i - num_slots + 1);
|
||||
}
|
||||
|
||||
static int prepare_unused_channel_list(struct device *dev, void *data)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
int i, ctlr;
|
||||
|
||||
for (i = 0; i < pdev->num_resources; i++) {
|
||||
if ((pdev->resource[i].flags & IORESOURCE_DMA) &&
|
||||
(int)pdev->resource[i].start >= 0) {
|
||||
ctlr = EDMA_CTLR(pdev->resource[i].start);
|
||||
clear_bit(EDMA_CHAN_SLOT(pdev->resource[i].start),
|
||||
edma_info[ctlr]->edma_unused);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
static bool unused_chan_list_done;
|
||||
|
||||
/* Resource alloc/free: dma channels, parameter RAM slots */
|
||||
|
||||
/**
|
||||
@ -594,7 +614,22 @@ int edma_alloc_channel(int channel,
|
||||
void *data,
|
||||
enum dma_event_q eventq_no)
|
||||
{
|
||||
unsigned i, done, ctlr = 0;
|
||||
unsigned i, done = 0, ctlr = 0;
|
||||
int ret = 0;
|
||||
|
||||
if (!unused_chan_list_done) {
|
||||
/*
|
||||
* Scan all the platform devices to find out the EDMA channels
|
||||
* used and clear them in the unused list, making the rest
|
||||
* available for ARM usage.
|
||||
*/
|
||||
ret = bus_for_each_dev(&platform_bus_type, NULL, NULL,
|
||||
prepare_unused_channel_list);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
unused_chan_list_done = true;
|
||||
}
|
||||
|
||||
if (channel >= 0) {
|
||||
ctlr = EDMA_CTLR(channel);
|
||||
@ -602,15 +637,15 @@ int edma_alloc_channel(int channel,
|
||||
}
|
||||
|
||||
if (channel < 0) {
|
||||
for (i = 0; i < EDMA_MAX_CC; i++) {
|
||||
for (i = 0; i < arch_num_cc; i++) {
|
||||
channel = 0;
|
||||
for (;;) {
|
||||
channel = find_next_bit(edma_info[i]->
|
||||
edma_noevent,
|
||||
edma_unused,
|
||||
edma_info[i]->num_channels,
|
||||
channel);
|
||||
if (channel == edma_info[i]->num_channels)
|
||||
return -ENOMEM;
|
||||
break;
|
||||
if (!test_and_set_bit(channel,
|
||||
edma_info[i]->edma_inuse)) {
|
||||
done = 1;
|
||||
@ -622,6 +657,8 @@ int edma_alloc_channel(int channel,
|
||||
if (done)
|
||||
break;
|
||||
}
|
||||
if (!done)
|
||||
return -ENOMEM;
|
||||
} else if (channel >= edma_info[ctlr]->num_channels) {
|
||||
return -EINVAL;
|
||||
} else if (test_and_set_bit(channel, edma_info[ctlr]->edma_inuse)) {
|
||||
@ -642,7 +679,7 @@ int edma_alloc_channel(int channel,
|
||||
|
||||
map_dmach_queue(ctlr, channel, eventq_no);
|
||||
|
||||
return channel;
|
||||
return EDMA_CTLR_CHAN(ctlr, channel);
|
||||
}
|
||||
EXPORT_SYMBOL(edma_alloc_channel);
|
||||
|
||||
@ -1219,7 +1256,7 @@ int edma_start(unsigned channel)
|
||||
unsigned int mask = (1 << (channel & 0x1f));
|
||||
|
||||
/* EDMA channels without event association */
|
||||
if (test_bit(channel, edma_info[ctlr]->edma_noevent)) {
|
||||
if (test_bit(channel, edma_info[ctlr]->edma_unused)) {
|
||||
pr_debug("EDMA: ESR%d %08x\n", j,
|
||||
edma_shadow0_read_array(ctlr, SH_ESR, j));
|
||||
edma_shadow0_write_array(ctlr, SH_ESR, j, mask);
|
||||
@ -1344,7 +1381,6 @@ static int __init edma_probe(struct platform_device *pdev)
|
||||
const s8 (*queue_tc_mapping)[2];
|
||||
int i, j, found = 0;
|
||||
int status = -1;
|
||||
const s8 *noevent;
|
||||
int irq[EDMA_MAX_CC] = {0, 0};
|
||||
int err_irq[EDMA_MAX_CC] = {0, 0};
|
||||
struct resource *r[EDMA_MAX_CC] = {NULL};
|
||||
@ -1407,11 +1443,9 @@ static int __init edma_probe(struct platform_device *pdev)
|
||||
memcpy_toio(edmacc_regs_base[j] + PARM_OFFSET(i),
|
||||
&dummy_paramset, PARM_SIZE);
|
||||
|
||||
noevent = info[j].noevent;
|
||||
if (noevent) {
|
||||
while (*noevent != -1)
|
||||
set_bit(*noevent++, edma_info[j]->edma_noevent);
|
||||
}
|
||||
/* Mark all channels as unused */
|
||||
memset(edma_info[j]->edma_unused, 0xff,
|
||||
sizeof(edma_info[j]->edma_unused));
|
||||
|
||||
sprintf(irq_name, "edma%d", j);
|
||||
irq[j] = platform_get_irq_byname(pdev, irq_name);
|
||||
@ -1467,6 +1501,7 @@ static int __init edma_probe(struct platform_device *pdev)
|
||||
edma_write_array2(j, EDMA_DRAE, i, 1, 0x0);
|
||||
edma_write_array(j, EDMA_QRAE, i, 0x0);
|
||||
}
|
||||
arch_num_cc++;
|
||||
}
|
||||
|
||||
if (tc_errs_handled) {
|
||||
|
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
|
@ -43,7 +43,7 @@ struct davinci_soc_info {
|
||||
void __iomem *jtag_id_base;
|
||||
struct davinci_id *ids;
|
||||
unsigned long ids_num;
|
||||
struct davinci_clk *cpu_clks;
|
||||
struct clk_lookup *cpu_clks;
|
||||
void __iomem **psc_bases;
|
||||
unsigned long psc_bases_num;
|
||||
void __iomem *pinmux_base;
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
struct davinci_cpuidle_config {
|
||||
u32 ddr2_pdown;
|
||||
void __iomem *ddr2_ctlr_base;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -13,15 +13,17 @@
|
||||
|
||||
#include <video/da8xx-fb.h>
|
||||
|
||||
#include <linux/davinci_emac.h>
|
||||
#include <mach/serial.h>
|
||||
#include <mach/edma.h>
|
||||
#include <mach/i2c.h>
|
||||
#include <mach/emac.h>
|
||||
#include <mach/asp.h>
|
||||
#include <mach/mmc.h>
|
||||
#include <mach/usb.h>
|
||||
#include <mach/pm.h>
|
||||
|
||||
extern void __iomem *da8xx_syscfg_base;
|
||||
extern void __iomem *da8xx_syscfg0_base;
|
||||
extern void __iomem *da8xx_syscfg1_base;
|
||||
|
||||
/*
|
||||
* The cp_intc interrupt controller for the da8xx isn't in the same
|
||||
@ -34,13 +36,17 @@ extern void __iomem *da8xx_syscfg_base;
|
||||
#define DA8XX_CP_INTC_SIZE SZ_8K
|
||||
#define DA8XX_CP_INTC_VIRT (IO_VIRT - DA8XX_CP_INTC_SIZE - SZ_4K)
|
||||
|
||||
#define DA8XX_SYSCFG_BASE (IO_PHYS + 0x14000)
|
||||
#define DA8XX_SYSCFG_VIRT(x) (da8xx_syscfg_base + (x))
|
||||
#define DA8XX_SYSCFG0_BASE (IO_PHYS + 0x14000)
|
||||
#define DA8XX_SYSCFG0_VIRT(x) (da8xx_syscfg0_base + (x))
|
||||
#define DA8XX_JTAG_ID_REG 0x18
|
||||
#define DA8XX_CFGCHIP0_REG 0x17c
|
||||
#define DA8XX_CFGCHIP2_REG 0x184
|
||||
#define DA8XX_CFGCHIP3_REG 0x188
|
||||
|
||||
#define DA8XX_SYSCFG1_BASE (IO_PHYS + 0x22C000)
|
||||
#define DA8XX_SYSCFG1_VIRT(x) (da8xx_syscfg1_base + (x))
|
||||
#define DA8XX_DEEPSLEEP_REG 0x8
|
||||
|
||||
#define DA8XX_PSC0_BASE 0x01c10000
|
||||
#define DA8XX_PLL0_BASE 0x01c11000
|
||||
#define DA8XX_TIMER64P0_BASE 0x01c20000
|
||||
@ -48,11 +54,13 @@ extern void __iomem *da8xx_syscfg_base;
|
||||
#define DA8XX_GPIO_BASE 0x01e26000
|
||||
#define DA8XX_PSC1_BASE 0x01e27000
|
||||
#define DA8XX_LCD_CNTRL_BASE 0x01e13000
|
||||
#define DA8XX_PLL1_BASE 0x01e1a000
|
||||
#define DA8XX_MMCSD0_BASE 0x01c40000
|
||||
#define DA8XX_AEMIF_CS2_BASE 0x60000000
|
||||
#define DA8XX_AEMIF_CS3_BASE 0x62000000
|
||||
#define DA8XX_AEMIF_CTL_BASE 0x68000000
|
||||
#define DA8XX_DDR2_CTL_BASE 0xb0000000
|
||||
#define DA8XX_ARM_RAM_BASE 0xffff0000
|
||||
|
||||
#define PINMUX0 0x00
|
||||
#define PINMUX1 0x04
|
||||
@ -90,6 +98,8 @@ void __init da8xx_register_mcasp(int id, struct snd_platform_data *pdata);
|
||||
int da8xx_register_rtc(void);
|
||||
int da850_register_cpufreq(void);
|
||||
int da8xx_register_cpuidle(void);
|
||||
void __iomem * __init da8xx_get_mem_ctlr(void);
|
||||
int da850_register_pm(struct platform_device *pdev);
|
||||
|
||||
extern struct platform_device da8xx_serial_device;
|
||||
extern struct emac_platform_data da8xx_emac_pdata;
|
||||
|
@ -14,8 +14,8 @@
|
||||
#define __ASM_ARCH_DM665_H
|
||||
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/davinci_emac.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/emac.h>
|
||||
#include <mach/asp.h>
|
||||
#include <mach/keyscan.h>
|
||||
#include <media/davinci/vpfe_capture.h>
|
||||
@ -32,10 +32,17 @@
|
||||
|
||||
#define DM365_RTC_BASE (0x01C69000)
|
||||
|
||||
#define DAVINCI_DM365_VC_BASE (0x01D0C000)
|
||||
#define DAVINCI_DMA_VC_TX 2
|
||||
#define DAVINCI_DMA_VC_RX 3
|
||||
|
||||
void __init dm365_init(void);
|
||||
void __init dm365_init_asp(struct snd_platform_data *pdata);
|
||||
void __init dm365_init_vc(struct snd_platform_data *pdata);
|
||||
void __init dm365_init_ks(struct davinci_ks_platform_data *pdata);
|
||||
void __init dm365_init_rtc(void);
|
||||
void dm365_init_spi0(unsigned chipselect_mask,
|
||||
struct spi_board_info *info, unsigned len);
|
||||
|
||||
void dm365_set_vpfe_config(struct vpfe_config *cfg);
|
||||
#endif /* __ASM_ARCH_DM365_H */
|
||||
|
@ -22,8 +22,8 @@
|
||||
#ifndef __ASM_ARCH_DM644X_H
|
||||
#define __ASM_ARCH_DM644X_H
|
||||
|
||||
#include <linux/davinci_emac.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/emac.h>
|
||||
#include <mach/asp.h>
|
||||
#include <media/davinci/vpfe_capture.h>
|
||||
|
||||
|
@ -12,10 +12,11 @@
|
||||
#define __ASM_ARCH_DM646X_H
|
||||
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/emac.h>
|
||||
#include <mach/asp.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/videodev2.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/davinci_emac.h>
|
||||
|
||||
#define DM646X_EMAC_BASE (0x01C80000)
|
||||
#define DM646X_EMAC_CNTRL_OFFSET (0x0000)
|
||||
@ -30,6 +31,7 @@ void __init dm646x_init(void);
|
||||
void __init dm646x_init_ide(void);
|
||||
void __init dm646x_init_mcasp0(struct snd_platform_data *pdata);
|
||||
void __init dm646x_init_mcasp1(struct snd_platform_data *pdata);
|
||||
void __init dm646x_board_setup_refclk(struct clk *clk);
|
||||
|
||||
void dm646x_video_init(void);
|
||||
|
||||
|
@ -280,8 +280,6 @@ struct edma_soc_info {
|
||||
unsigned n_cc;
|
||||
enum dma_event_q default_queue;
|
||||
|
||||
/* list of channels with no even trigger; terminated by "-1" */
|
||||
const s8 *noevent;
|
||||
const s8 (*queue_tc_mapping)[2];
|
||||
const s8 (*queue_priority_mapping)[2];
|
||||
};
|
||||
|
@ -16,6 +16,8 @@
|
||||
struct davinci_i2c_platform_data {
|
||||
unsigned int bus_freq; /* standard bus frequency (kHz) */
|
||||
unsigned int bus_delay; /* post-transaction delay (usec) */
|
||||
unsigned int sda_pin; /* GPIO pin ID to use for SDA */
|
||||
unsigned int scl_pin; /* GPIO pin ID to use for SCL */
|
||||
};
|
||||
|
||||
/* for board setup code */
|
||||
|
@ -31,6 +31,11 @@
|
||||
#define PHYS_OFFSET DAVINCI_DDR_BASE
|
||||
#endif
|
||||
|
||||
#define DDR2_SDRCR_OFFSET 0xc
|
||||
#define DDR2_SRPD_BIT BIT(23)
|
||||
#define DDR2_MCLKSTOPEN_BIT BIT(30)
|
||||
#define DDR2_LPMODEN_BIT BIT(31)
|
||||
|
||||
/*
|
||||
* Increase size of DMA-consistent memory region
|
||||
*/
|
||||
|
@ -327,6 +327,8 @@ enum davinci_dm365_index {
|
||||
/* EDMA event muxing */
|
||||
DM365_EVT2_ASP_TX,
|
||||
DM365_EVT3_ASP_RX,
|
||||
DM365_EVT2_VC_TX,
|
||||
DM365_EVT3_VC_RX,
|
||||
DM365_EVT26_MMC0_RX,
|
||||
};
|
||||
|
||||
@ -899,6 +901,7 @@ enum davinci_da850_index {
|
||||
DA850_GPIO2_15,
|
||||
DA850_GPIO4_0,
|
||||
DA850_GPIO4_1,
|
||||
DA850_RTC_ALARM,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_DAVINCI_MUX
|
||||
|
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
|
@ -180,8 +180,23 @@
|
||||
#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 PDCTL1 0x304
|
||||
#define MDSTAT 0x800
|
||||
#define MDCTL 0xA00
|
||||
|
||||
#define MDSTAT_STATE_MASK 0x1f
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
extern int davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id);
|
||||
extern void davinci_psc_config(unsigned int domain, unsigned int ctlr,
|
||||
unsigned int id, char enable);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __ASM_ARCH_PSC_H */
|
||||
|
44
arch/arm/mach-davinci/include/mach/spi.h
Normal file
44
arch/arm/mach-davinci/include/mach/spi.h
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2009 Texas Instruments.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_ARM_DAVINCI_SPI_H
|
||||
#define __ARCH_ARM_DAVINCI_SPI_H
|
||||
|
||||
enum {
|
||||
SPI_VERSION_1, /* For DM355/DM365/DM6467 */
|
||||
SPI_VERSION_2, /* For DA8xx */
|
||||
};
|
||||
|
||||
struct davinci_spi_platform_data {
|
||||
u8 version;
|
||||
u8 num_chipselect;
|
||||
u8 wdelay;
|
||||
u8 odd_parity;
|
||||
u8 parity_enable;
|
||||
u8 wait_enable;
|
||||
u8 timer_disable;
|
||||
u8 clk_internal;
|
||||
u8 cs_hold;
|
||||
u8 intr_level;
|
||||
u8 poll_mode;
|
||||
u8 use_dma;
|
||||
u8 c2tdelay;
|
||||
u8 t2cdelay;
|
||||
};
|
||||
|
||||
#endif /* __ARCH_ARM_DAVINCI_SPI_H */
|
@ -11,7 +11,12 @@
|
||||
#ifndef __ASM_ARCH_TIMEX_H
|
||||
#define __ASM_ARCH_TIMEX_H
|
||||
|
||||
/* The source frequency for the timers is the 27MHz clock */
|
||||
/*
|
||||
* Alert: Not all timers of the DaVinci family run at a frequency of 27MHz,
|
||||
* but we should be fine as long as CLOCK_TICK_RATE or LATCH (see include/
|
||||
* linux/jiffies.h) are not used directly in code. Currently none of the
|
||||
* code relevant to DaVinci platform depends on these values directly.
|
||||
*/
|
||||
#define CLOCK_TICK_RATE 27000000
|
||||
|
||||
#endif /* __ASM_ARCH_TIMEX_H__ */
|
||||
|
158
arch/arm/mach-davinci/pm.c
Normal file
158
arch/arm/mach-davinci/pm.c
Normal file
@ -0,0 +1,158 @@
|
||||
/*
|
||||
* 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 <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 struct platform_suspend_ops davinci_pm_ops = {
|
||||
.enter = davinci_pm_enter,
|
||||
.valid = suspend_valid_only_mem,
|
||||
};
|
||||
|
||||
static int __init davinci_pm_probe(struct platform_device *pdev)
|
||||
{
|
||||
pdata = pdev->dev.platform_data;
|
||||
if (!pdata) {
|
||||
dev_err(&pdev->dev, "cannot get platform data\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
davinci_sram_suspend = sram_alloc(davinci_cpu_suspend_sz, NULL);
|
||||
if (!davinci_sram_suspend) {
|
||||
dev_err(&pdev->dev, "cannot allocate SRAM memory\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
davinci_sram_push(davinci_sram_suspend, davinci_cpu_suspend,
|
||||
davinci_cpu_suspend_sz);
|
||||
|
||||
suspend_set_ops(&davinci_pm_ops);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __exit davinci_pm_remove(struct platform_device *pdev)
|
||||
{
|
||||
sram_free(davinci_sram_suspend, davinci_cpu_suspend_sz);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver davinci_pm_driver = {
|
||||
.driver = {
|
||||
.name = "pm-davinci",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.remove = __exit_p(davinci_pm_remove),
|
||||
};
|
||||
|
||||
static int __init davinci_pm_init(void)
|
||||
{
|
||||
return platform_driver_probe(&davinci_pm_driver, davinci_pm_probe);
|
||||
}
|
||||
late_initcall(davinci_pm_init);
|
@ -25,17 +25,6 @@
|
||||
#include <mach/cputype.h>
|
||||
#include <mach/psc.h>
|
||||
|
||||
/* PSC register offsets */
|
||||
#define EPCPR 0x070
|
||||
#define PTCMD 0x120
|
||||
#define PTSTAT 0x128
|
||||
#define PDSTAT 0x200
|
||||
#define PDCTL1 0x304
|
||||
#define MDSTAT 0x800
|
||||
#define MDCTL 0xA00
|
||||
|
||||
#define MDSTAT_STATE_MASK 0x1f
|
||||
|
||||
/* Return nonzero iff the domain's clock is active */
|
||||
int __init davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id)
|
||||
{
|
||||
|
224
arch/arm/mach-davinci/sleep.S
Normal file
224
arch/arm/mach-davinci/sleep.S
Normal file
@ -0,0 +1,224 @@
|
||||
/*
|
||||
* (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/memory.h>
|
||||
|
||||
#include "clock.h"
|
||||
|
||||
/* Arbitrary, hardware currently does not update PHYRDY correctly */
|
||||
#define PHYRDY_CYCLES 0x1000
|
||||
|
||||
/* Assume 25 MHz speed for the cycle conversions since PLLs are bypassed */
|
||||
#define PLL_BYPASS_CYCLES (PLL_BYPASS_TIME * 25)
|
||||
#define PLL_RESET_CYCLES (PLL_RESET_TIME * 25)
|
||||
#define PLL_LOCK_CYCLES (PLL_LOCK_TIME * 25)
|
||||
|
||||
#define DEEPSLEEP_SLEEPENABLE_BIT BIT(31)
|
||||
|
||||
.text
|
||||
/*
|
||||
* Move DaVinci into deep sleep state
|
||||
*
|
||||
* Note: This code is copied to internal SRAM by PM code. When the DaVinci
|
||||
* wakes up it continues execution at the point it went to sleep.
|
||||
* Register Usage:
|
||||
* r0: contains virtual base for DDR2 controller
|
||||
* r1: contains virtual base for DDR2 Power and Sleep controller (PSC)
|
||||
* r2: contains PSC number for DDR2
|
||||
* r3: contains virtual base DDR2 PLL controller
|
||||
* r4: contains virtual address of the DEEPSLEEP register
|
||||
*/
|
||||
ENTRY(davinci_cpu_suspend)
|
||||
stmfd sp!, {r0-r12, lr} @ save registers on stack
|
||||
|
||||
ldr ip, CACHE_FLUSH
|
||||
blx ip
|
||||
|
||||
ldmia r0, {r0-r4}
|
||||
|
||||
/*
|
||||
* Switch DDR to self-refresh mode.
|
||||
*/
|
||||
|
||||
/* calculate SDRCR address */
|
||||
ldr ip, [r0, #DDR2_SDRCR_OFFSET]
|
||||
bic ip, ip, #DDR2_SRPD_BIT
|
||||
orr ip, ip, #DDR2_LPMODEN_BIT
|
||||
str ip, [r0, #DDR2_SDRCR_OFFSET]
|
||||
|
||||
ldr ip, [r0, #DDR2_SDRCR_OFFSET]
|
||||
orr ip, ip, #DDR2_MCLKSTOPEN_BIT
|
||||
str ip, [r0, #DDR2_SDRCR_OFFSET]
|
||||
|
||||
mov ip, #PHYRDY_CYCLES
|
||||
1: subs ip, ip, #0x1
|
||||
bne 1b
|
||||
|
||||
/* Disable DDR2 LPSC */
|
||||
mov r7, r0
|
||||
mov r0, #0x2
|
||||
bl davinci_ddr_psc_config
|
||||
mov r0, r7
|
||||
|
||||
/* Disable clock to DDR PHY */
|
||||
ldr ip, [r3, #PLLDIV1]
|
||||
bic ip, ip, #PLLDIV_EN
|
||||
str ip, [r3, #PLLDIV1]
|
||||
|
||||
/* Put the DDR PLL in bypass and power down */
|
||||
ldr ip, [r3, #PLLCTL]
|
||||
bic ip, ip, #PLLCTL_PLLENSRC
|
||||
bic ip, ip, #PLLCTL_PLLEN
|
||||
str ip, [r3, #PLLCTL]
|
||||
|
||||
/* Wait for PLL to switch to bypass */
|
||||
mov ip, #PLL_BYPASS_CYCLES
|
||||
2: subs ip, ip, #0x1
|
||||
bne 2b
|
||||
|
||||
/* Power down the PLL */
|
||||
ldr ip, [r3, #PLLCTL]
|
||||
orr ip, ip, #PLLCTL_PLLPWRDN
|
||||
str ip, [r3, #PLLCTL]
|
||||
|
||||
/* Go to deep sleep */
|
||||
ldr ip, [r4]
|
||||
orr ip, ip, #DEEPSLEEP_SLEEPENABLE_BIT
|
||||
/* System goes to sleep beyond after this instruction */
|
||||
str ip, [r4]
|
||||
|
||||
/* Wake up from sleep */
|
||||
|
||||
/* Clear sleep enable */
|
||||
ldr ip, [r4]
|
||||
bic ip, ip, #DEEPSLEEP_SLEEPENABLE_BIT
|
||||
str ip, [r4]
|
||||
|
||||
/* initialize the DDR PLL controller */
|
||||
|
||||
/* Put PLL in reset */
|
||||
ldr ip, [r3, #PLLCTL]
|
||||
bic ip, ip, #PLLCTL_PLLRST
|
||||
str ip, [r3, #PLLCTL]
|
||||
|
||||
/* Clear PLL power down */
|
||||
ldr ip, [r3, #PLLCTL]
|
||||
bic ip, ip, #PLLCTL_PLLPWRDN
|
||||
str ip, [r3, #PLLCTL]
|
||||
|
||||
mov ip, #PLL_RESET_CYCLES
|
||||
3: subs ip, ip, #0x1
|
||||
bne 3b
|
||||
|
||||
/* Bring PLL out of reset */
|
||||
ldr ip, [r3, #PLLCTL]
|
||||
orr ip, ip, #PLLCTL_PLLRST
|
||||
str ip, [r3, #PLLCTL]
|
||||
|
||||
/* Wait for PLL to lock (assume prediv = 1, 25MHz OSCIN) */
|
||||
mov ip, #PLL_LOCK_CYCLES
|
||||
4: subs ip, ip, #0x1
|
||||
bne 4b
|
||||
|
||||
/* Remove PLL from bypass mode */
|
||||
ldr ip, [r3, #PLLCTL]
|
||||
bic ip, ip, #PLLCTL_PLLENSRC
|
||||
orr ip, ip, #PLLCTL_PLLEN
|
||||
str ip, [r3, #PLLCTL]
|
||||
|
||||
/* Start 2x clock to DDR2 */
|
||||
|
||||
ldr ip, [r3, #PLLDIV1]
|
||||
orr ip, ip, #PLLDIV_EN
|
||||
str ip, [r3, #PLLDIV1]
|
||||
|
||||
/* Enable VCLK */
|
||||
|
||||
/* Enable DDR2 LPSC */
|
||||
mov r7, r0
|
||||
mov r0, #0x3
|
||||
bl davinci_ddr_psc_config
|
||||
mov r0, r7
|
||||
|
||||
/* clear MCLKSTOPEN */
|
||||
|
||||
ldr ip, [r0, #DDR2_SDRCR_OFFSET]
|
||||
bic ip, ip, #DDR2_MCLKSTOPEN_BIT
|
||||
str ip, [r0, #DDR2_SDRCR_OFFSET]
|
||||
|
||||
ldr ip, [r0, #DDR2_SDRCR_OFFSET]
|
||||
bic ip, ip, #DDR2_LPMODEN_BIT
|
||||
str ip, [r0, #DDR2_SDRCR_OFFSET]
|
||||
|
||||
/* Restore registers and return */
|
||||
ldmfd sp!, {r0-r12, pc}
|
||||
|
||||
ENDPROC(davinci_cpu_suspend)
|
||||
|
||||
/*
|
||||
* Disables or Enables DDR2 LPSC
|
||||
* Register Usage:
|
||||
* r0: Enable or Disable LPSC r0 = 0x3 => Enable, r0 = 0x2 => Disable LPSC
|
||||
* r1: contains virtual base for DDR2 Power and Sleep controller (PSC)
|
||||
* r2: contains PSC number for DDR2
|
||||
*/
|
||||
ENTRY(davinci_ddr_psc_config)
|
||||
/* Set next state in mdctl for DDR2 */
|
||||
mov r6, #MDCTL
|
||||
add r6, r6, r2, lsl #2
|
||||
ldr ip, [r1, r6]
|
||||
bic ip, ip, #MDSTAT_STATE_MASK
|
||||
orr ip, ip, r0
|
||||
str ip, [r1, r6]
|
||||
|
||||
/* Enable the Power Domain Transition Command */
|
||||
ldr ip, [r1, #PTCMD]
|
||||
orr ip, ip, #0x1
|
||||
str ip, [r1, #PTCMD]
|
||||
|
||||
/* Check for Transition Complete (PTSTAT) */
|
||||
ptstat_done:
|
||||
ldr ip, [r1, #PTSTAT]
|
||||
and ip, ip, #0x1
|
||||
cmp ip, #0x0
|
||||
bne ptstat_done
|
||||
|
||||
/* Check for DDR2 clock disable completion; */
|
||||
mov r6, #MDSTAT
|
||||
add r6, r6, r2, lsl #2
|
||||
ddr2clk_stop_done:
|
||||
ldr ip, [r1, r6]
|
||||
and ip, ip, #MDSTAT_STATE_MASK
|
||||
cmp ip, r0
|
||||
bne ddr2clk_stop_done
|
||||
|
||||
mov pc, lr
|
||||
ENDPROC(davinci_ddr_psc_config)
|
||||
|
||||
CACHE_FLUSH:
|
||||
.word arm926_flush_kern_cache_all
|
||||
|
||||
ENTRY(davinci_cpu_suspend_sz)
|
||||
.word . - davinci_cpu_suspend
|
||||
ENDPROC(davinci_cpu_suspend_sz)
|
@ -920,7 +920,7 @@ config NET_NETX
|
||||
|
||||
config TI_DAVINCI_EMAC
|
||||
tristate "TI DaVinci EMAC Support"
|
||||
depends on ARM && ARCH_DAVINCI
|
||||
depends on ARM && ( ARCH_DAVINCI || ARCH_OMAP3 )
|
||||
select PHYLIB
|
||||
help
|
||||
This driver supports TI's DaVinci Ethernet .
|
||||
|
@ -62,12 +62,11 @@
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/davinci_emac.h>
|
||||
|
||||
#include <asm/irq.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
#include <mach/emac.h>
|
||||
|
||||
static int debug_level;
|
||||
module_param(debug_level, int, 0);
|
||||
MODULE_PARM_DESC(debug_level, "DaVinci EMAC debug level (NETIF_MSG bits)");
|
||||
@ -465,6 +464,7 @@ struct emac_priv {
|
||||
void __iomem *ctrl_base;
|
||||
void __iomem *emac_ctrl_ram;
|
||||
u32 ctrl_ram_size;
|
||||
u32 hw_ram_addr;
|
||||
struct emac_txch *txch[EMAC_DEF_MAX_TX_CH];
|
||||
struct emac_rxch *rxch[EMAC_DEF_MAX_RX_CH];
|
||||
u32 link; /* 1=link on, 0=link off */
|
||||
@ -488,6 +488,9 @@ struct emac_priv {
|
||||
struct mii_bus *mii_bus;
|
||||
struct phy_device *phydev;
|
||||
spinlock_t lock;
|
||||
/*platform specific members*/
|
||||
void (*int_enable) (void);
|
||||
void (*int_disable) (void);
|
||||
};
|
||||
|
||||
/* clock frequency for EMAC */
|
||||
@ -495,11 +498,9 @@ static struct clk *emac_clk;
|
||||
static unsigned long emac_bus_frequency;
|
||||
static unsigned long mdio_max_freq;
|
||||
|
||||
/* EMAC internal utility function */
|
||||
static inline u32 emac_virt_to_phys(void __iomem *addr)
|
||||
{
|
||||
return (u32 __force) io_v2p(addr);
|
||||
}
|
||||
#define emac_virt_to_phys(addr, priv) \
|
||||
(((u32 __force)(addr) - (u32 __force)(priv->emac_ctrl_ram)) \
|
||||
+ priv->hw_ram_addr)
|
||||
|
||||
/* Cache macros - Packet buffers would be from skb pool which is cached */
|
||||
#define EMAC_VIRT_NOCACHE(addr) (addr)
|
||||
@ -1002,6 +1003,8 @@ static void emac_int_disable(struct emac_priv *priv)
|
||||
emac_ctrl_write(EMAC_DM646X_CMRXINTEN, 0x0);
|
||||
emac_ctrl_write(EMAC_DM646X_CMTXINTEN, 0x0);
|
||||
/* NOTE: Rx Threshold and Misc interrupts are not disabled */
|
||||
if (priv->int_disable)
|
||||
priv->int_disable();
|
||||
|
||||
local_irq_restore(flags);
|
||||
|
||||
@ -1021,6 +1024,9 @@ static void emac_int_disable(struct emac_priv *priv)
|
||||
static void emac_int_enable(struct emac_priv *priv)
|
||||
{
|
||||
if (priv->version == EMAC_VERSION_2) {
|
||||
if (priv->int_enable)
|
||||
priv->int_enable();
|
||||
|
||||
emac_ctrl_write(EMAC_DM646X_CMRXINTEN, 0xff);
|
||||
emac_ctrl_write(EMAC_DM646X_CMTXINTEN, 0xff);
|
||||
|
||||
@ -1302,7 +1308,7 @@ static int emac_tx_bdproc(struct emac_priv *priv, u32 ch, u32 budget)
|
||||
curr_bd = txch->active_queue_head;
|
||||
if (NULL == curr_bd) {
|
||||
emac_write(EMAC_TXCP(ch),
|
||||
emac_virt_to_phys(txch->last_hw_bdprocessed));
|
||||
emac_virt_to_phys(txch->last_hw_bdprocessed, priv));
|
||||
txch->no_active_pkts++;
|
||||
spin_unlock_irqrestore(&priv->tx_lock, flags);
|
||||
return 0;
|
||||
@ -1312,7 +1318,7 @@ static int emac_tx_bdproc(struct emac_priv *priv, u32 ch, u32 budget)
|
||||
while ((curr_bd) &&
|
||||
((frame_status & EMAC_CPPI_OWNERSHIP_BIT) == 0) &&
|
||||
(pkts_processed < budget)) {
|
||||
emac_write(EMAC_TXCP(ch), emac_virt_to_phys(curr_bd));
|
||||
emac_write(EMAC_TXCP(ch), emac_virt_to_phys(curr_bd, priv));
|
||||
txch->active_queue_head = curr_bd->next;
|
||||
if (frame_status & EMAC_CPPI_EOQ_BIT) {
|
||||
if (curr_bd->next) { /* misqueued packet */
|
||||
@ -1399,7 +1405,7 @@ static int emac_send(struct emac_priv *priv, struct emac_netpktobj *pkt, u32 ch)
|
||||
txch->active_queue_tail = curr_bd;
|
||||
if (1 != txch->queue_active) {
|
||||
emac_write(EMAC_TXHDP(ch),
|
||||
emac_virt_to_phys(curr_bd));
|
||||
emac_virt_to_phys(curr_bd, priv));
|
||||
txch->queue_active = 1;
|
||||
}
|
||||
++txch->queue_reinit;
|
||||
@ -1411,10 +1417,11 @@ static int emac_send(struct emac_priv *priv, struct emac_netpktobj *pkt, u32 ch)
|
||||
tail_bd->next = curr_bd;
|
||||
txch->active_queue_tail = curr_bd;
|
||||
tail_bd = EMAC_VIRT_NOCACHE(tail_bd);
|
||||
tail_bd->h_next = (int)emac_virt_to_phys(curr_bd);
|
||||
tail_bd->h_next = (int)emac_virt_to_phys(curr_bd, priv);
|
||||
frame_status = tail_bd->mode;
|
||||
if (frame_status & EMAC_CPPI_EOQ_BIT) {
|
||||
emac_write(EMAC_TXHDP(ch), emac_virt_to_phys(curr_bd));
|
||||
emac_write(EMAC_TXHDP(ch),
|
||||
emac_virt_to_phys(curr_bd, priv));
|
||||
frame_status &= ~(EMAC_CPPI_EOQ_BIT);
|
||||
tail_bd->mode = frame_status;
|
||||
++txch->end_of_queue_add;
|
||||
@ -1604,7 +1611,8 @@ static int emac_init_rxch(struct emac_priv *priv, u32 ch, char *param)
|
||||
}
|
||||
|
||||
/* populate the hardware descriptor */
|
||||
curr_bd->h_next = emac_virt_to_phys(rxch->active_queue_head);
|
||||
curr_bd->h_next = emac_virt_to_phys(rxch->active_queue_head,
|
||||
priv);
|
||||
/* FIXME buff_ptr = dma_map_single(... data_ptr ...) */
|
||||
curr_bd->buff_ptr = virt_to_phys(curr_bd->data_ptr);
|
||||
curr_bd->off_b_len = rxch->buf_size;
|
||||
@ -1879,7 +1887,7 @@ static void emac_addbd_to_rx_queue(struct emac_priv *priv, u32 ch,
|
||||
rxch->active_queue_tail = curr_bd;
|
||||
if (0 != rxch->queue_active) {
|
||||
emac_write(EMAC_RXHDP(ch),
|
||||
emac_virt_to_phys(rxch->active_queue_head));
|
||||
emac_virt_to_phys(rxch->active_queue_head, priv));
|
||||
rxch->queue_active = 1;
|
||||
}
|
||||
} else {
|
||||
@ -1890,11 +1898,11 @@ static void emac_addbd_to_rx_queue(struct emac_priv *priv, u32 ch,
|
||||
rxch->active_queue_tail = curr_bd;
|
||||
tail_bd->next = curr_bd;
|
||||
tail_bd = EMAC_VIRT_NOCACHE(tail_bd);
|
||||
tail_bd->h_next = emac_virt_to_phys(curr_bd);
|
||||
tail_bd->h_next = emac_virt_to_phys(curr_bd, priv);
|
||||
frame_status = tail_bd->mode;
|
||||
if (frame_status & EMAC_CPPI_EOQ_BIT) {
|
||||
emac_write(EMAC_RXHDP(ch),
|
||||
emac_virt_to_phys(curr_bd));
|
||||
emac_virt_to_phys(curr_bd, priv));
|
||||
frame_status &= ~(EMAC_CPPI_EOQ_BIT);
|
||||
tail_bd->mode = frame_status;
|
||||
++rxch->end_of_queue_add;
|
||||
@ -1987,7 +1995,7 @@ static int emac_rx_bdproc(struct emac_priv *priv, u32 ch, u32 budget)
|
||||
curr_pkt->num_bufs = 1;
|
||||
curr_pkt->pkt_length =
|
||||
(frame_status & EMAC_RX_BD_PKT_LENGTH_MASK);
|
||||
emac_write(EMAC_RXCP(ch), emac_virt_to_phys(curr_bd));
|
||||
emac_write(EMAC_RXCP(ch), emac_virt_to_phys(curr_bd, priv));
|
||||
++rxch->processed_bd;
|
||||
last_bd = curr_bd;
|
||||
curr_bd = last_bd->next;
|
||||
@ -1998,7 +2006,7 @@ static int emac_rx_bdproc(struct emac_priv *priv, u32 ch, u32 budget)
|
||||
if (curr_bd) {
|
||||
++rxch->mis_queued_packets;
|
||||
emac_write(EMAC_RXHDP(ch),
|
||||
emac_virt_to_phys(curr_bd));
|
||||
emac_virt_to_phys(curr_bd, priv));
|
||||
} else {
|
||||
++rxch->end_of_queue;
|
||||
rxch->queue_active = 0;
|
||||
@ -2099,7 +2107,7 @@ static int emac_hw_enable(struct emac_priv *priv)
|
||||
emac_write(EMAC_RXINTMASKSET, BIT(ch));
|
||||
rxch->queue_active = 1;
|
||||
emac_write(EMAC_RXHDP(ch),
|
||||
emac_virt_to_phys(rxch->active_queue_head));
|
||||
emac_virt_to_phys(rxch->active_queue_head, priv));
|
||||
}
|
||||
|
||||
/* Enable MII */
|
||||
@ -2660,6 +2668,9 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev)
|
||||
priv->phy_mask = pdata->phy_mask;
|
||||
priv->rmii_en = pdata->rmii_en;
|
||||
priv->version = pdata->version;
|
||||
priv->int_enable = pdata->interrupt_enable;
|
||||
priv->int_disable = pdata->interrupt_disable;
|
||||
|
||||
emac_dev = &ndev->dev;
|
||||
/* Get EMAC platform data */
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
@ -2692,6 +2703,12 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev)
|
||||
priv->ctrl_ram_size = pdata->ctrl_ram_size;
|
||||
priv->emac_ctrl_ram = priv->remap_addr + pdata->ctrl_ram_offset;
|
||||
|
||||
if (pdata->hw_ram_addr)
|
||||
priv->hw_ram_addr = pdata->hw_ram_addr;
|
||||
else
|
||||
priv->hw_ram_addr = (u32 __force)res->start +
|
||||
pdata->ctrl_ram_offset;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||
if (!res) {
|
||||
dev_err(emac_dev, "DaVinci EMAC: Error getting irq res\n");
|
||||
|
@ -8,8 +8,8 @@
|
||||
* is licensed "as is" without any warranty of any kind, whether express
|
||||
* or implied.
|
||||
*/
|
||||
#ifndef _MACH_DAVINCI_EMAC_H
|
||||
#define _MACH_DAVINCI_EMAC_H
|
||||
#ifndef _LINUX_DAVINCI_EMAC_H
|
||||
#define _LINUX_DAVINCI_EMAC_H
|
||||
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/memory.h>
|
||||
@ -19,12 +19,15 @@ struct emac_platform_data {
|
||||
u32 ctrl_reg_offset;
|
||||
u32 ctrl_mod_reg_offset;
|
||||
u32 ctrl_ram_offset;
|
||||
u32 hw_ram_addr;
|
||||
u32 mdio_reg_offset;
|
||||
u32 ctrl_ram_size;
|
||||
u32 phy_mask;
|
||||
u32 mdio_max_freq;
|
||||
u8 rmii_en;
|
||||
u8 version;
|
||||
void (*interrupt_enable) (void);
|
||||
void (*interrupt_disable) (void);
|
||||
};
|
||||
|
||||
enum {
|
Loading…
Reference in New Issue
Block a user