提交 a133e775 编写于 作者: R Russell King 提交者: Russell King
......@@ -585,6 +585,8 @@ config ARCH_DAVINCI
select ARCH_REQUIRE_GPIOLIB
select HAVE_CLK
select ZONE_DMA
select HAVE_IDE
select COMMON_CLKDEV
help
Support for TI's DaVinci platform.
......
此差异已折叠。
......@@ -4,19 +4,56 @@ menu "TI DaVinci Implementations"
comment "DaVinci Core Type"
config ARCH_DAVINCI644x
default y
config ARCH_DAVINCI_DM644x
bool "DaVinci 644x based system"
comment "DaVinci Board Type"
config MACH_DAVINCI_EVM
bool "TI DaVinci EVM"
bool "TI DM644x EVM"
default y
depends on ARCH_DAVINCI644x
depends on ARCH_DAVINCI_DM644x
help
Configure this option to specify the whether the board used
for development is a DaVinci EVM
for development is a DM644x EVM
config DAVINCI_MUX
bool "DAVINCI multiplexing support"
depends on ARCH_DAVINCI
default y
help
Pin multiplexing support for DAVINCI boards. If your bootloader
sets the multiplexing correctly, say N. Otherwise, or if unsure,
say Y.
config DAVINCI_MUX_DEBUG
bool "Multiplexing debug output"
depends on DAVINCI_MUX
help
Makes the multiplexing functions print out a lot of debug info.
This is useful if you want to find out the correct values of the
multiplexing registers.
config DAVINCI_MUX_WARNINGS
bool "Warn about pins the bootloader didn't set up"
depends on DAVINCI_MUX
help
Choose Y here to warn whenever driver initialization logic needs
to change the pin multiplexing setup. When there are no warnings
printed, it's safe to deselect DAVINCI_MUX for your product.
config DAVINCI_RESET_CLOCKS
bool "Reset unused clocks during boot"
depends on ARCH_DAVINCI
help
Say Y if you want to reset unused clocks during boot.
This option saves power, but assumes all drivers are
using the clock framework. Broken drivers that do not
yet use clock framework may not work with this option.
If you are booting from another operating system, you
probably do not want this option enabled until your
device drivers work properly.
endmenu
......
......@@ -5,7 +5,12 @@
# Common objects
obj-y := time.o irq.o clock.o serial.o io.o id.o psc.o \
gpio.o mux.o devices.o usb.o
gpio.o devices.o dma.o usb.o
obj-$(CONFIG_DAVINCI_MUX) += mux.o
# Chip specific
obj-$(CONFIG_ARCH_DAVINCI_DM644x) += dm644x.o
# Board specific
obj-$(CONFIG_MACH_DAVINCI_EVM) += board-evm.o
obj-$(CONFIG_MACH_DAVINCI_EVM) += board-dm644x-evm.o
......@@ -15,15 +15,20 @@
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/leds.h>
#include <linux/memory.h>
#include <linux/etherdevice.h>
#include <linux/i2c.h>
#include <linux/i2c/pcf857x.h>
#include <linux/i2c/at24.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
#include <linux/io.h>
#include <linux/phy.h>
#include <linux/clk.h>
#include <asm/setup.h>
#include <asm/mach-types.h>
......@@ -32,25 +37,34 @@
#include <asm/mach/map.h>
#include <asm/mach/flash.h>
#include <mach/hardware.h>
#include <mach/dm644x.h>
#include <mach/common.h>
#include <mach/i2c.h>
#include <mach/serial.h>
#include <mach/mux.h>
#include <mach/psc.h>
#include <mach/nand.h>
/* other misc. init functions */
void __init davinci_psc_init(void);
void __init davinci_irq_init(void);
void __init davinci_map_common_io(void);
void __init davinci_init_common_hw(void);
#define DM644X_EVM_PHY_MASK (0x2)
#define DM644X_EVM_MDIO_FREQUENCY (2200000) /* PHY bus frequency */
#if defined(CONFIG_MTD_PHYSMAP) || \
defined(CONFIG_MTD_PHYSMAP_MODULE)
#define DAVINCI_CFC_ATA_BASE 0x01C66000
#define DAVINCI_ASYNC_EMIF_CONTROL_BASE 0x01e00000
#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE 0x02000000
#define DAVINCI_ASYNC_EMIF_DATA_CE1_BASE 0x04000000
#define DAVINCI_ASYNC_EMIF_DATA_CE2_BASE 0x06000000
#define DAVINCI_ASYNC_EMIF_DATA_CE3_BASE 0x08000000
#define LXT971_PHY_ID (0x001378e2)
#define LXT971_PHY_MASK (0xfffffff0)
static struct mtd_partition davinci_evm_norflash_partitions[] = {
/* bootloader (U-Boot, etc) in first 4 sectors */
/* bootloader (UBL, U-Boot, etc) in first 5 sectors */
{
.name = "bootloader",
.offset = 0,
.size = 4 * SZ_64K,
.size = 5 * SZ_64K,
.mask_flags = MTD_WRITEABLE, /* force read-only */
},
/* bootloader params in the next 1 sectors */
......@@ -100,10 +114,89 @@ static struct platform_device davinci_evm_norflash_device = {
.resource = &davinci_evm_norflash_resource,
};
#endif
/* DM644x EVM includes a 64 MByte small-page NAND flash (16K blocks).
* It may used instead of the (default) NOR chip to boot, using TI's
* tools to install the secondary boot loader (UBL) and U-Boot.
*/
struct mtd_partition davinci_evm_nandflash_partition[] = {
/* Bootloader layout depends on whose u-boot is installed, but we
* can hide all the details.
* - block 0 for u-boot environment ... in mainline u-boot
* - block 1 for UBL (plus up to four backup copies in blocks 2..5)
* - blocks 6...? for u-boot
* - blocks 16..23 for u-boot environment ... in TI's u-boot
*/
{
.name = "bootloader",
.offset = 0,
.size = SZ_256K + SZ_128K,
.mask_flags = MTD_WRITEABLE, /* force read-only */
},
/* Kernel */
{
.name = "kernel",
.offset = MTDPART_OFS_APPEND,
.size = SZ_4M,
.mask_flags = 0,
},
/* File system (older GIT kernels started this on the 5MB mark) */
{
.name = "filesystem",
.offset = MTDPART_OFS_APPEND,
.size = MTDPART_SIZ_FULL,
.mask_flags = 0,
}
/* A few blocks at end hold a flash BBT ... created by TI's CCS
* using flashwriter_nand.out, but ignored by TI's versions of
* Linux and u-boot. We boot faster by using them.
*/
};
#if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \
defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE)
static struct davinci_nand_pdata davinci_evm_nandflash_data = {
.parts = davinci_evm_nandflash_partition,
.nr_parts = ARRAY_SIZE(davinci_evm_nandflash_partition),
.ecc_mode = NAND_ECC_HW,
.options = NAND_USE_FLASH_BBT,
};
static struct resource davinci_evm_nandflash_resource[] = {
{
.start = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE,
.end = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE + SZ_16M - 1,
.flags = IORESOURCE_MEM,
}, {
.start = DAVINCI_ASYNC_EMIF_CONTROL_BASE,
.end = DAVINCI_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device davinci_evm_nandflash_device = {
.name = "davinci_nand",
.id = 0,
.dev = {
.platform_data = &davinci_evm_nandflash_data,
},
.num_resources = ARRAY_SIZE(davinci_evm_nandflash_resource),
.resource = davinci_evm_nandflash_resource,
};
static u64 davinci_fb_dma_mask = DMA_BIT_MASK(32);
static struct platform_device davinci_fb_device = {
.name = "davincifb",
.id = -1,
.dev = {
.dma_mask = &davinci_fb_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
.num_resources = 0,
};
static struct platform_device rtc_dev = {
.name = "rtc_davinci_evm",
.id = -1,
};
static struct resource ide_resources[] = {
{
......@@ -118,7 +211,7 @@ static struct resource ide_resources[] = {
},
};
static u64 ide_dma_mask = DMA_BIT_MASK(32);
static u64 ide_dma_mask = DMA_32BIT_MASK;
static struct platform_device ide_dev = {
.name = "palm_bk3710",
......@@ -127,12 +220,10 @@ static struct platform_device ide_dev = {
.num_resources = ARRAY_SIZE(ide_resources),
.dev = {
.dma_mask = &ide_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
.coherent_dma_mask = DMA_32BIT_MASK,
},
};
#endif
/*----------------------------------------------------------------------*/
/*
......@@ -311,7 +402,9 @@ evm_u35_setup(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
gpio_request(gpio + 7, "nCF_SEL");
gpio_direction_output(gpio + 7, 1);
/* irlml6401 sustains over 3A, switches 5V in under 8 msec */
/* irlml6401 switches over 1A, in under 8 msec;
* now it can be managed by nDRV_VBUS ...
*/
setup_usb(500, 8);
return 0;
......@@ -343,13 +436,119 @@ static struct pcf857x_platform_data pcf_data_u35 = {
* - 0x0039, 1 byte NTSC vs PAL (bit 0x80 == PAL)
* - ... newer boards may have more
*/
static struct memory_accessor *at24_mem_acc;
static void at24_setup(struct memory_accessor *mem_acc, void *context)
{
DECLARE_MAC_BUF(mac_str);
char mac_addr[6];
at24_mem_acc = mem_acc;
/* Read MAC addr from EEPROM */
if (at24_mem_acc->read(at24_mem_acc, mac_addr, 0x7f00, 6) == 6) {
printk(KERN_INFO "Read MAC addr from EEPROM: %s\n",
print_mac(mac_str, mac_addr));
}
}
static struct at24_platform_data eeprom_info = {
.byte_len = (256*1024) / 8,
.page_size = 64,
.flags = AT24_FLAG_ADDR16,
.setup = at24_setup,
};
int dm6446evm_eeprom_read(void *buf, off_t off, size_t count)
{
if (at24_mem_acc)
return at24_mem_acc->read(at24_mem_acc, buf, off, count);
return -ENODEV;
}
EXPORT_SYMBOL(dm6446evm_eeprom_read);
int dm6446evm_eeprom_write(void *buf, off_t off, size_t count)
{
if (at24_mem_acc)
return at24_mem_acc->write(at24_mem_acc, buf, off, count);
return -ENODEV;
}
EXPORT_SYMBOL(dm6446evm_eeprom_write);
/*
* MSP430 supports RTC, card detection, input from IR remote, and
* a bit more. It triggers interrupts on GPIO(7) from pressing
* buttons on the IR remote, and for card detect switches.
*/
static struct i2c_client *dm6446evm_msp;
static int dm6446evm_msp_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
dm6446evm_msp = client;
return 0;
}
static int dm6446evm_msp_remove(struct i2c_client *client)
{
dm6446evm_msp = NULL;
return 0;
}
static const struct i2c_device_id dm6446evm_msp_ids[] = {
{ "dm6446evm_msp", 0, },
{ /* end of list */ },
};
static struct i2c_driver dm6446evm_msp_driver = {
.driver.name = "dm6446evm_msp",
.id_table = dm6446evm_msp_ids,
.probe = dm6446evm_msp_probe,
.remove = dm6446evm_msp_remove,
};
static int dm6444evm_msp430_get_pins(void)
{
static const char txbuf[2] = { 2, 4, };
char buf[4];
struct i2c_msg msg[2] = {
{
.addr = dm6446evm_msp->addr,
.flags = 0,
.len = 2,
.buf = (void __force *)txbuf,
},
{
.addr = dm6446evm_msp->addr,
.flags = I2C_M_RD,
.len = 4,
.buf = buf,
},
};
int status;
if (!dm6446evm_msp)
return -ENXIO;
/* Command 4 == get input state, returns port 2 and port3 data
* S Addr W [A] len=2 [A] cmd=4 [A]
* RS Addr R [A] [len=4] A [cmd=4] A [port2] A [port3] N P
*/
status = i2c_transfer(dm6446evm_msp->adapter, msg, 2);
if (status < 0)
return status;
dev_dbg(&dm6446evm_msp->dev,
"PINS: %02x %02x %02x %02x\n",
buf[0], buf[1], buf[2], buf[3]);
return (buf[3] << 8) | buf[2];
}
static struct i2c_board_info __initdata i2c_info[] = {
{
I2C_BOARD_INFO("dm6446evm_msp", 0x23),
},
{
I2C_BOARD_INFO("pcf8574", 0x38),
.platform_data = &pcf_data_u2,
......@@ -368,7 +567,6 @@ static struct i2c_board_info __initdata i2c_info[] = {
},
/* ALSO:
* - tvl320aic33 audio codec (0x1b)
* - msp430 microcontroller (0x23)
* - tvp5146 video decoder (0x5d)
*/
};
......@@ -384,51 +582,109 @@ static struct davinci_i2c_platform_data i2c_pdata = {
static void __init evm_init_i2c(void)
{
davinci_init_i2c(&i2c_pdata);
i2c_add_driver(&dm6446evm_msp_driver);
i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info));
}
static struct platform_device *davinci_evm_devices[] __initdata = {
#if defined(CONFIG_MTD_PHYSMAP) || \
defined(CONFIG_MTD_PHYSMAP_MODULE)
&davinci_evm_norflash_device,
#endif
#if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \
defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE)
&ide_dev,
#endif
&davinci_fb_device,
&rtc_dev,
};
static struct davinci_uart_config uart_config __initdata = {
.enabled_uarts = (1 << 0),
};
static void __init
davinci_evm_map_io(void)
{
davinci_map_common_io();
dm644x_init();
}
static __init void davinci_evm_init(void)
static int davinci_phy_fixup(struct phy_device *phydev)
{
davinci_psc_init();
unsigned int control;
/* CRITICAL: Fix for increasing PHY signal drive strength for
* TX lockup issue. On DaVinci EVM, the Intel LXT971 PHY
* signal strength was low causing TX to fail randomly. The
* fix is to Set bit 11 (Increased MII drive strength) of PHY
* register 26 (Digital Config register) on this phy. */
control = phy_read(phydev, 26);
phy_write(phydev, 26, (control | 0x800));
return 0;
}
#if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \
defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE)
#define HAS_ATA 1
#else
#define HAS_ATA 0
#endif
#if defined(CONFIG_MTD_PHYSMAP) || \
defined(CONFIG_MTD_PHYSMAP_MODULE)
printk(KERN_WARNING "WARNING: both IDE and NOR flash are enabled, "
"but share pins.\n\t Disable IDE for NOR support.\n");
#define HAS_NOR 1
#else
#define HAS_NOR 0
#endif
#if defined(CONFIG_MTD_NAND_DAVINCI) || \
defined(CONFIG_MTD_NAND_DAVINCI_MODULE)
#define HAS_NAND 1
#else
#define HAS_NAND 0
#endif
static __init void davinci_evm_init(void)
{
struct clk *aemif_clk;
aemif_clk = clk_get(NULL, "aemif");
clk_enable(aemif_clk);
if (HAS_ATA) {
if (HAS_NAND || HAS_NOR)
pr_warning("WARNING: both IDE and Flash are "
"enabled, but they share AEMIF pins.\n"
"\tDisable IDE for NAND/NOR support.\n");
davinci_cfg_reg(DM644X_HPIEN_DISABLE);
davinci_cfg_reg(DM644X_ATAEN);
davinci_cfg_reg(DM644X_HDIREN);
platform_device_register(&ide_dev);
} else if (HAS_NAND || HAS_NOR) {
davinci_cfg_reg(DM644X_HPIEN_DISABLE);
davinci_cfg_reg(DM644X_ATAEN_DISABLE);
/* only one device will be jumpered and detected */
if (HAS_NAND) {
platform_device_register(&davinci_evm_nandflash_device);
evm_leds[7].default_trigger = "nand-disk";
if (HAS_NOR)
pr_warning("WARNING: both NAND and NOR flash "
"are enabled; disable one of them.\n");
} else if (HAS_NOR)
platform_device_register(&davinci_evm_norflash_device);
}
platform_add_devices(davinci_evm_devices,
ARRAY_SIZE(davinci_evm_devices));
evm_init_i2c();
davinci_serial_init(&uart_config);
/* Register the fixup for PHY on DaVinci */
phy_register_fixup_for_uid(LXT971_PHY_ID, LXT971_PHY_MASK,
davinci_phy_fixup);
}
static __init void davinci_evm_irq_init(void)
{
davinci_init_common_hw();
davinci_irq_init();
}
MACHINE_START(DAVINCI_EVM, "DaVinci EVM")
MACHINE_START(DAVINCI_EVM, "DaVinci DM644x EVM")
/* Maintainer: MontaVista Software <source@mvista.com> */
.phys_io = IO_PHYS,
.io_pg_offst = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
......
/*
* TI DaVinci clock config file
* Clock and PLL control for DaVinci devices
*
* Copyright (C) 2006 Texas Instruments.
* Copyright (C) 2006-2007 Texas Instruments.
* Copyright (C) 2008-2009 Deep Root Systems, LLC
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -13,6 +14,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/platform_device.h>
......@@ -21,98 +23,50 @@
#include <mach/hardware.h>
#include <mach/psc.h>
#include <mach/cputype.h>
#include "clock.h"
/* PLL/Reset register offsets */
#define PLLM 0x110
static LIST_HEAD(clocks);
static DEFINE_MUTEX(clocks_mutex);
static DEFINE_SPINLOCK(clockfw_lock);
static unsigned int commonrate;
static unsigned int armrate;
static unsigned int fixedrate = 27000000; /* 27 MHZ */
extern void davinci_psc_config(unsigned int domain, unsigned int id, char enable);
/*
* Returns a clock. Note that we first try to use device id on the bus
* and clock name. If this fails, we try to use clock name only.
*/
struct clk *clk_get(struct device *dev, const char *id)
static unsigned psc_domain(struct clk *clk)
{
struct clk *p, *clk = ERR_PTR(-ENOENT);
int idno;
if (dev == NULL || dev->bus != &platform_bus_type)
idno = -1;
else
idno = to_platform_device(dev)->id;
mutex_lock(&clocks_mutex);
list_for_each_entry(p, &clocks, node) {
if (p->id == idno &&
strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
clk = p;
goto found;
}
}
list_for_each_entry(p, &clocks, node) {
if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
clk = p;
break;
}
}
found:
mutex_unlock(&clocks_mutex);
return clk;
return (clk->flags & PSC_DSP)
? DAVINCI_GPSC_DSPDOMAIN
: DAVINCI_GPSC_ARMDOMAIN;
}
EXPORT_SYMBOL(clk_get);
void clk_put(struct clk *clk)
static void __clk_enable(struct clk *clk)
{
if (clk && !IS_ERR(clk))
module_put(clk->owner);
}
EXPORT_SYMBOL(clk_put);
static int __clk_enable(struct clk *clk)
{
if (clk->flags & ALWAYS_ENABLED)
return 0;
davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, clk->lpsc, 1);
return 0;
if (clk->parent)
__clk_enable(clk->parent);
if (clk->usecount++ == 0 && (clk->flags & CLK_PSC))
davinci_psc_config(psc_domain(clk), clk->lpsc, 1);
}
static void __clk_disable(struct clk *clk)
{
if (clk->usecount)
if (WARN_ON(clk->usecount == 0))
return;
davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, clk->lpsc, 0);
if (--clk->usecount == 0 && !(clk->flags & CLK_PLL))
davinci_psc_config(psc_domain(clk), clk->lpsc, 0);
if (clk->parent)
__clk_disable(clk->parent);
}
int clk_enable(struct clk *clk)
{
unsigned long flags;
int ret = 0;
if (clk == NULL || IS_ERR(clk))
return -EINVAL;
if (clk->usecount++ == 0) {
spin_lock_irqsave(&clockfw_lock, flags);
ret = __clk_enable(clk);
spin_unlock_irqrestore(&clockfw_lock, flags);
}
spin_lock_irqsave(&clockfw_lock, flags);
__clk_enable(clk);
spin_unlock_irqrestore(&clockfw_lock, flags);
return ret;
return 0;
}
EXPORT_SYMBOL(clk_enable);
......@@ -123,11 +77,9 @@ void clk_disable(struct clk *clk)
if (clk == NULL || IS_ERR(clk))
return;
if (clk->usecount > 0 && !(--clk->usecount)) {
spin_lock_irqsave(&clockfw_lock, flags);
__clk_disable(clk);
spin_unlock_irqrestore(&clockfw_lock, flags);
}
spin_lock_irqsave(&clockfw_lock, flags);
__clk_disable(clk);
spin_unlock_irqrestore(&clockfw_lock, flags);
}
EXPORT_SYMBOL(clk_disable);
......@@ -136,7 +88,7 @@ unsigned long clk_get_rate(struct clk *clk)
if (clk == NULL || IS_ERR(clk))
return -EINVAL;
return *(clk->rate);
return clk->rate;
}
EXPORT_SYMBOL(clk_get_rate);
......@@ -145,7 +97,7 @@ long clk_round_rate(struct clk *clk, unsigned long rate)
if (clk == NULL || IS_ERR(clk))
return -EINVAL;
return *(clk->rate);
return clk->rate;
}
EXPORT_SYMBOL(clk_round_rate);
......@@ -164,10 +116,23 @@ int clk_register(struct clk *clk)
if (clk == NULL || IS_ERR(clk))
return -EINVAL;
if (WARN(clk->parent && !clk->parent->rate,
"CLK: %s parent %s has no rate!\n",
clk->name, clk->parent->name))
return -EINVAL;
mutex_lock(&clocks_mutex);
list_add(&clk->node, &clocks);
list_add_tail(&clk->node, &clocks);
mutex_unlock(&clocks_mutex);
/* If rate is already set, use it */
if (clk->rate)
return 0;
/* Otherwise, default to parent rate */
if (clk->parent)
clk->rate = clk->parent->rate;
return 0;
}
EXPORT_SYMBOL(clk_register);
......@@ -183,84 +148,150 @@ void clk_unregister(struct clk *clk)
}
EXPORT_SYMBOL(clk_unregister);
static struct clk davinci_clks[] = {
{
.name = "ARMCLK",
.rate = &armrate,
.lpsc = -1,
.flags = ALWAYS_ENABLED,
},
{
.name = "UART",
.rate = &fixedrate,
.lpsc = DAVINCI_LPSC_UART0,
},
{
.name = "EMACCLK",
.rate = &commonrate,
.lpsc = DAVINCI_LPSC_EMAC_WRAPPER,
},
{
.name = "I2CCLK",
.rate = &fixedrate,
.lpsc = DAVINCI_LPSC_I2C,
},
{
.name = "IDECLK",
.rate = &commonrate,
.lpsc = DAVINCI_LPSC_ATA,
},
{
.name = "McBSPCLK",
.rate = &commonrate,
.lpsc = DAVINCI_LPSC_McBSP,
},
{
.name = "MMCSDCLK",
.rate = &commonrate,
.lpsc = DAVINCI_LPSC_MMC_SD,
},
{
.name = "SPICLK",
.rate = &commonrate,
.lpsc = DAVINCI_LPSC_SPI,
},
{
.name = "gpio",
.rate = &commonrate,
.lpsc = DAVINCI_LPSC_GPIO,
},
{
.name = "usb",
.rate = &commonrate,
.lpsc = DAVINCI_LPSC_USB,
},
{
.name = "AEMIFCLK",
.rate = &commonrate,
.lpsc = DAVINCI_LPSC_AEMIF,
.usecount = 1,
#ifdef CONFIG_DAVINCI_RESET_CLOCKS
/*
* Disable any unused clocks left on by the bootloader
*/
static int __init clk_disable_unused(void)
{
struct clk *ck;
spin_lock_irq(&clockfw_lock);
list_for_each_entry(ck, &clocks, node) {
if (ck->usecount > 0)
continue;
if (!(ck->flags & CLK_PSC))
continue;
/* ignore if in Disabled or SwRstDisable states */
if (!davinci_psc_is_clk_active(ck->lpsc))
continue;
pr_info("Clocks: disable unused %s\n", ck->name);
davinci_psc_config(psc_domain(ck), ck->lpsc, 0);
}
};
spin_unlock_irq(&clockfw_lock);
return 0;
}
late_initcall(clk_disable_unused);
#endif
int __init davinci_clk_init(void)
static void clk_sysclk_recalc(struct clk *clk)
{
struct clk *clkp;
int count = 0;
u32 pll_mult;
pll_mult = davinci_readl(DAVINCI_PLL_CNTRL0_BASE + PLLM);
commonrate = ((pll_mult + 1) * 27000000) / 6;
armrate = ((pll_mult + 1) * 27000000) / 2;
for (clkp = davinci_clks; count < ARRAY_SIZE(davinci_clks);
count++, clkp++) {
clk_register(clkp);
/* Turn on clocks that have been enabled in the
* table above */
if (clkp->usecount)
clk_enable(clkp);
u32 v, plldiv;
struct pll_data *pll;
/* If this is the PLL base clock, no more calculations needed */
if (clk->pll_data)
return;
if (WARN_ON(!clk->parent))
return;
clk->rate = clk->parent->rate;
/* Otherwise, the parent must be a PLL */
if (WARN_ON(!clk->parent->pll_data))
return;
pll = clk->parent->pll_data;
/* If pre-PLL, source clock is before the multiplier and divider(s) */
if (clk->flags & PRE_PLL)
clk->rate = pll->input_rate;
if (!clk->div_reg)
return;
v = __raw_readl(pll->base + clk->div_reg);
if (v & PLLDIV_EN) {
plldiv = (v & PLLDIV_RATIO_MASK) + 1;
if (plldiv)
clk->rate /= plldiv;
}
}
static void __init clk_pll_init(struct clk *clk)
{
u32 ctrl, mult = 1, prediv = 1, postdiv = 1;
u8 bypass;
struct pll_data *pll = clk->pll_data;
pll->base = IO_ADDRESS(pll->phys_base);
ctrl = __raw_readl(pll->base + PLLCTL);
clk->rate = pll->input_rate = clk->parent->rate;
if (ctrl & PLLCTL_PLLEN) {
bypass = 0;
mult = __raw_readl(pll->base + PLLM);
mult = (mult & PLLM_PLLM_MASK) + 1;
} else
bypass = 1;
if (pll->flags & PLL_HAS_PREDIV) {
prediv = __raw_readl(pll->base + PREDIV);
if (prediv & PLLDIV_EN)
prediv = (prediv & PLLDIV_RATIO_MASK) + 1;
else
prediv = 1;
}
/* pre-divider is fixed, but (some?) chips won't report that */
if (cpu_is_davinci_dm355() && pll->num == 1)
prediv = 8;
if (pll->flags & PLL_HAS_POSTDIV) {
postdiv = __raw_readl(pll->base + POSTDIV);
if (postdiv & PLLDIV_EN)
postdiv = (postdiv & PLLDIV_RATIO_MASK) + 1;
else
postdiv = 1;
}
if (!bypass) {
clk->rate /= prediv;
clk->rate *= mult;
clk->rate /= postdiv;
}
pr_debug("PLL%d: input = %lu MHz [ ",
pll->num, clk->parent->rate / 1000000);
if (bypass)
pr_debug("bypass ");
if (prediv > 1)
pr_debug("/ %d ", prediv);
if (mult > 1)
pr_debug("* %d ", mult);
if (postdiv > 1)
pr_debug("/ %d ", postdiv);
pr_debug("] --> %lu MHz output.\n", clk->rate / 1000000);
}
int __init davinci_clk_init(struct davinci_clk *clocks)
{
struct davinci_clk *c;
struct clk *clk;
for (c = clocks; c->lk.clk; c++) {
clk = c->lk.clk;
if (clk->pll_data)
clk_pll_init(clk);
/* Calculate rates for PLL-derived clocks */
else if (clk->flags & CLK_PLL)
clk_sysclk_recalc(clk);
if (clk->lpsc)
clk->flags |= CLK_PSC;
clkdev_add(&c->lk);
clk_register(clk);
/* Turn on clocks that Linux doesn't otherwise manage */
if (clk->flags & ALWAYS_ENABLED)
clk_enable(clk);
}
return 0;
......@@ -285,12 +316,52 @@ static void davinci_ck_stop(struct seq_file *m, void *v)
{
}
static int davinci_ck_show(struct seq_file *m, void *v)
#define CLKNAME_MAX 10 /* longest clock name */
#define NEST_DELTA 2
#define NEST_MAX 4
static void
dump_clock(struct seq_file *s, unsigned nest, struct clk *parent)
{
struct clk *cp;
char *state;
char buf[CLKNAME_MAX + NEST_DELTA * NEST_MAX];
struct clk *clk;
unsigned i;
if (parent->flags & CLK_PLL)
state = "pll";
else if (parent->flags & CLK_PSC)
state = "psc";
else
state = "";
/* <nest spaces> name <pad to end> */
memset(buf, ' ', sizeof(buf) - 1);
buf[sizeof(buf) - 1] = 0;
i = strlen(parent->name);
memcpy(buf + nest, parent->name,
min(i, (unsigned)(sizeof(buf) - 1 - nest)));
seq_printf(s, "%s users=%2d %-3s %9ld Hz\n",
buf, parent->usecount, state, clk_get_rate(parent));
/* REVISIT show device associations too */
/* cost is now small, but not linear... */
list_for_each_entry(clk, &clocks, node) {
if (clk->parent == parent)
dump_clock(s, nest + NEST_DELTA, clk);
}
}
list_for_each_entry(cp, &clocks, node)
seq_printf(m,"%s %d %d\n", cp->name, *(cp->rate), cp->usecount);
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...
*/
mutex_lock(&clocks_mutex);
if (!list_empty(&clocks))
dump_clock(m, 0, list_first_entry(&clocks, struct clk, node));
mutex_unlock(&clocks_mutex);
return 0;
}
......@@ -321,4 +392,4 @@ static int __init davinci_ck_proc_init(void)
}
__initcall(davinci_ck_proc_init);
#endif /* CONFIG_DEBUG_PROC_FS */
#endif /* CONFIG_DEBUG_PROC_FS */
/*
* TI DaVinci clock definitions
*
* Copyright (C) 2006 Texas Instruments.
* Copyright (C) 2006-2007 Texas Instruments.
* Copyright (C) 2008-2009 Deep Root Systems, LLC
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
......@@ -11,23 +12,85 @@
#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
/* PLL/Reset register offsets */
#define PLLCTL 0x100
#define PLLCTL_PLLEN BIT(0)
#define PLLCTL_CLKMODE BIT(8)
#define PLLM 0x110
#define PLLM_PLLM_MASK 0xff
#define PREDIV 0x114
#define PLLDIV1 0x118
#define PLLDIV2 0x11c
#define PLLDIV3 0x120
#define POSTDIV 0x128
#define BPDIV 0x12c
#define PLLCMD 0x138
#define PLLSTAT 0x13c
#define PLLALNCTL 0x140
#define PLLDCHANGE 0x144
#define PLLCKEN 0x148
#define PLLCKSTAT 0x14c
#define PLLSYSTAT 0x150
#define PLLDIV4 0x160
#define PLLDIV5 0x164
#define PLLDIV6 0x168
#define PLLDIV7 0x16c
#define PLLDIV8 0x170
#define PLLDIV9 0x174
#define PLLDIV_EN BIT(15)
#define PLLDIV_RATIO_MASK 0x1f
struct pll_data {
u32 phys_base;
void __iomem *base;
u32 num;
u32 flags;
u32 input_rate;
};
#define PLL_HAS_PREDIV 0x01
#define PLL_HAS_POSTDIV 0x02
struct clk {
struct list_head node;
struct module *owner;
const char *name;
unsigned int *rate;
int id;
__s8 usecount;
__u8 flags;
__u8 lpsc;
unsigned long rate;
u8 usecount;
u8 flags;
u8 lpsc;
struct clk *parent;
struct pll_data *pll_data;
u32 div_reg;
};
/* Clock flags */
#define RATE_CKCTL 1
#define RATE_FIXED 2
#define RATE_PROPAGATES 4
#define VIRTUAL_CLOCK 8
#define ALWAYS_ENABLED 16
#define ENABLE_REG_32BIT 32
#define ALWAYS_ENABLED BIT(1)
#define CLK_PSC BIT(2)
#define PSC_DSP BIT(3) /* PSC uses DSP domain, not ARM */
#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) \
{ \
.lk = { \
.dev_id = dev, \
.con_id = con, \
.clk = ck, \
}, \
}
int davinci_clk_init(struct davinci_clk *clocks);
#endif
......@@ -21,6 +21,10 @@
#include <mach/hardware.h>
#include <mach/i2c.h>
#include <mach/irqs.h>
#include <mach/cputype.h>
#include <mach/mux.h>
#define DAVINCI_I2C_BASE 0x01C21000
static struct resource i2c_resources[] = {
{
......@@ -43,6 +47,9 @@ static struct platform_device davinci_i2c_device = {
void __init davinci_init_i2c(struct davinci_i2c_platform_data *pdata)
{
if (cpu_is_davinci_dm644x())
davinci_cfg_reg(DM644X_I2C);
davinci_i2c_device.dev.platform_data = pdata;
(void) platform_device_register(&davinci_i2c_device);
}
......
/*
* TI DaVinci DM644x chip specific setup
*
* Author: Kevin Hilman, Deep Root Systems, LLC
*
* 2007 (c) Deep Root Systems, LLC. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <mach/dm644x.h>
#include <mach/clock.h>
#include <mach/cputype.h>
#include <mach/edma.h>
#include <mach/irqs.h>
#include <mach/psc.h>
#include <mach/mux.h>
#include "clock.h"
#include "mux.h"
/*
* Device specific clocks
*/
#define DM644X_REF_FREQ 27000000
static struct pll_data pll1_data = {
.num = 1,
.phys_base = DAVINCI_PLL1_BASE,
};
static struct pll_data pll2_data = {
.num = 2,
.phys_base = DAVINCI_PLL2_BASE,
};
static struct clk ref_clk = {
.name = "ref_clk",
.rate = DM644X_REF_FREQ,
};
static struct clk pll1_clk = {
.name = "pll1",
.parent = &ref_clk,
.pll_data = &pll1_data,
.flags = CLK_PLL,
};
static struct clk pll1_sysclk1 = {
.name = "pll1_sysclk1",
.parent = &pll1_clk,
.flags = CLK_PLL,
.div_reg = PLLDIV1,
};
static struct clk pll1_sysclk2 = {
.name = "pll1_sysclk2",
.parent = &pll1_clk,
.flags = CLK_PLL,
.div_reg = PLLDIV2,
};
static struct clk pll1_sysclk3 = {
.name = "pll1_sysclk3",
.parent = &pll1_clk,
.flags = CLK_PLL,
.div_reg = PLLDIV3,
};
static struct clk pll1_sysclk5 = {
.name = "pll1_sysclk5",
.parent = &pll1_clk,
.flags = CLK_PLL,
.div_reg = PLLDIV5,
};
static struct clk pll1_aux_clk = {
.name = "pll1_aux_clk",
.parent = &pll1_clk,
.flags = CLK_PLL | PRE_PLL,
};
static struct clk pll1_sysclkbp = {
.name = "pll1_sysclkbp",
.parent = &pll1_clk,
.flags = CLK_PLL | PRE_PLL,
.div_reg = BPDIV
};
static struct clk pll2_clk = {
.name = "pll2",
.parent = &ref_clk,
.pll_data = &pll2_data,
.flags = CLK_PLL,
};
static struct clk pll2_sysclk1 = {
.name = "pll2_sysclk1",
.parent = &pll2_clk,
.flags = CLK_PLL,
.div_reg = PLLDIV1,
};
static struct clk pll2_sysclk2 = {
.name = "pll2_sysclk2",
.parent = &pll2_clk,
.flags = CLK_PLL,
.div_reg = PLLDIV2,
};
static struct clk pll2_sysclkbp = {
.name = "pll2_sysclkbp",
.parent = &pll2_clk,
.flags = CLK_PLL | PRE_PLL,
.div_reg = BPDIV
};
static struct clk dsp_clk = {
.name = "dsp",
.parent = &pll1_sysclk1,
.lpsc = DAVINCI_LPSC_GEM,
.flags = PSC_DSP,
.usecount = 1, /* REVISIT how to disable? */
};
static struct clk arm_clk = {
.name = "arm",
.parent = &pll1_sysclk2,
.lpsc = DAVINCI_LPSC_ARM,
.flags = ALWAYS_ENABLED,
};
static struct clk vicp_clk = {
.name = "vicp",
.parent = &pll1_sysclk2,
.lpsc = DAVINCI_LPSC_IMCOP,
.flags = PSC_DSP,
.usecount = 1, /* REVISIT how to disable? */
};
static struct clk vpss_master_clk = {
.name = "vpss_master",
.parent = &pll1_sysclk3,
.lpsc = DAVINCI_LPSC_VPSSMSTR,
.flags = CLK_PSC,
};
static struct clk vpss_slave_clk = {
.name = "vpss_slave",
.parent = &pll1_sysclk3,
.lpsc = DAVINCI_LPSC_VPSSSLV,
};
static struct clk uart0_clk = {
.name = "uart0",
.parent = &pll1_aux_clk,
.lpsc = DAVINCI_LPSC_UART0,
};
static struct clk uart1_clk = {
.name = "uart1",
.parent = &pll1_aux_clk,
.lpsc = DAVINCI_LPSC_UART1,
};
static struct clk uart2_clk = {
.name = "uart2",
.parent = &pll1_aux_clk,
.lpsc = DAVINCI_LPSC_UART2,
};
static struct clk emac_clk = {
.name = "emac",
.parent = &pll1_sysclk5,
.lpsc = DAVINCI_LPSC_EMAC_WRAPPER,
};
static struct clk i2c_clk = {
.name = "i2c",
.parent = &pll1_aux_clk,
.lpsc = DAVINCI_LPSC_I2C,
};
static struct clk ide_clk = {
.name = "ide",
.parent = &pll1_sysclk5,
.lpsc = DAVINCI_LPSC_ATA,
};
static struct clk asp_clk = {
.name = "asp0",
.parent = &pll1_sysclk5,
.lpsc = DAVINCI_LPSC_McBSP,
};
static struct clk mmcsd_clk = {
.name = "mmcsd",
.parent = &pll1_sysclk5,
.lpsc = DAVINCI_LPSC_MMC_SD,
};
static struct clk spi_clk = {
.name = "spi",
.parent = &pll1_sysclk5,
.lpsc = DAVINCI_LPSC_SPI,
};
static struct clk gpio_clk = {
.name = "gpio",
.parent = &pll1_sysclk5,
.lpsc = DAVINCI_LPSC_GPIO,
};
static struct clk usb_clk = {
.name = "usb",
.parent = &pll1_sysclk5,
.lpsc = DAVINCI_LPSC_USB,
};
static struct clk vlynq_clk = {
.name = "vlynq",
.parent = &pll1_sysclk5,
.lpsc = DAVINCI_LPSC_VLYNQ,
};
static struct clk aemif_clk = {
.name = "aemif",
.parent = &pll1_sysclk5,
.lpsc = DAVINCI_LPSC_AEMIF,
};
static struct clk pwm0_clk = {
.name = "pwm0",
.parent = &pll1_aux_clk,
.lpsc = DAVINCI_LPSC_PWM0,
};
static struct clk pwm1_clk = {
.name = "pwm1",
.parent = &pll1_aux_clk,
.lpsc = DAVINCI_LPSC_PWM1,
};
static struct clk pwm2_clk = {
.name = "pwm2",
.parent = &pll1_aux_clk,
.lpsc = DAVINCI_LPSC_PWM2,
};
static struct clk timer0_clk = {
.name = "timer0",
.parent = &pll1_aux_clk,
.lpsc = DAVINCI_LPSC_TIMER0,
};
static struct clk timer1_clk = {
.name = "timer1",
.parent = &pll1_aux_clk,
.lpsc = DAVINCI_LPSC_TIMER1,
};
static struct clk timer2_clk = {
.name = "timer2",
.parent = &pll1_aux_clk,
.lpsc = DAVINCI_LPSC_TIMER2,
.usecount = 1, /* REVISIT: why cant' this be disabled? */
};
struct davinci_clk dm644x_clks[] = {
CLK(NULL, "ref", &ref_clk),
CLK(NULL, "pll1", &pll1_clk),
CLK(NULL, "pll1_sysclk1", &pll1_sysclk1),
CLK(NULL, "pll1_sysclk2", &pll1_sysclk2),
CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
CLK(NULL, "pll1_sysclk5", &pll1_sysclk5),
CLK(NULL, "pll1_aux", &pll1_aux_clk),
CLK(NULL, "pll1_sysclkbp", &pll1_sysclkbp),
CLK(NULL, "pll2", &pll2_clk),
CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
CLK(NULL, "pll2_sysclk2", &pll2_sysclk2),
CLK(NULL, "pll2_sysclkbp", &pll2_sysclkbp),
CLK(NULL, "dsp", &dsp_clk),
CLK(NULL, "arm", &arm_clk),
CLK(NULL, "vicp", &vicp_clk),
CLK(NULL, "vpss_master", &vpss_master_clk),
CLK(NULL, "vpss_slave", &vpss_slave_clk),
CLK(NULL, "arm", &arm_clk),
CLK(NULL, "uart0", &uart0_clk),
CLK(NULL, "uart1", &uart1_clk),
CLK(NULL, "uart2", &uart2_clk),
CLK("davinci_emac.1", NULL, &emac_clk),
CLK("i2c_davinci.1", NULL, &i2c_clk),
CLK("palm_bk3710", NULL, &ide_clk),
CLK("soc-audio.0", NULL, &asp_clk),
CLK("davinci_mmc.0", NULL, &mmcsd_clk),
CLK(NULL, "spi", &spi_clk),
CLK(NULL, "gpio", &gpio_clk),
CLK(NULL, "usb", &usb_clk),
CLK(NULL, "vlynq", &vlynq_clk),
CLK(NULL, "aemif", &aemif_clk),
CLK(NULL, "pwm0", &pwm0_clk),
CLK(NULL, "pwm1", &pwm1_clk),
CLK(NULL, "pwm2", &pwm2_clk),
CLK(NULL, "timer0", &timer0_clk),
CLK(NULL, "timer1", &timer1_clk),
CLK("watchdog", NULL, &timer2_clk),
CLK(NULL, NULL, NULL),
};
#if defined(CONFIG_TI_DAVINCI_EMAC) || defined(CONFIG_TI_DAVINCI_EMAC_MODULE)
static struct resource dm644x_emac_resources[] = {
{
.start = DM644X_EMAC_BASE,
.end = DM644X_EMAC_BASE + 0x47ff,
.flags = IORESOURCE_MEM,
},
{
.start = IRQ_EMACINT,
.end = IRQ_EMACINT,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device dm644x_emac_device = {
.name = "davinci_emac",
.id = 1,
.num_resources = ARRAY_SIZE(dm644x_emac_resources),
.resource = dm644x_emac_resources,
};
#endif
/*
* Device specific mux setup
*
* soc description mux mode mode mux dbg
* reg offset mask mode
*/
static const struct mux_config dm644x_pins[] = {
MUX_CFG(DM644X, HDIREN, 0, 16, 1, 1, true)
MUX_CFG(DM644X, ATAEN, 0, 17, 1, 1, true)
MUX_CFG(DM644X, ATAEN_DISABLE, 0, 17, 1, 0, true)
MUX_CFG(DM644X, HPIEN_DISABLE, 0, 29, 1, 0, true)
MUX_CFG(DM644X, AEAW, 0, 0, 31, 31, true)
MUX_CFG(DM644X, MSTK, 1, 9, 1, 0, false)
MUX_CFG(DM644X, I2C, 1, 7, 1, 1, false)
MUX_CFG(DM644X, MCBSP, 1, 10, 1, 1, false)
MUX_CFG(DM644X, UART1, 1, 1, 1, 1, true)
MUX_CFG(DM644X, UART2, 1, 2, 1, 1, true)
MUX_CFG(DM644X, PWM0, 1, 4, 1, 1, false)
MUX_CFG(DM644X, PWM1, 1, 5, 1, 1, false)
MUX_CFG(DM644X, PWM2, 1, 6, 1, 1, false)
MUX_CFG(DM644X, VLYNQEN, 0, 15, 1, 1, false)
MUX_CFG(DM644X, VLSCREN, 0, 14, 1, 1, false)
MUX_CFG(DM644X, VLYNQWD, 0, 12, 3, 3, false)
MUX_CFG(DM644X, EMACEN, 0, 31, 1, 1, true)
MUX_CFG(DM644X, GPIO3V, 0, 31, 1, 0, true)
MUX_CFG(DM644X, GPIO0, 0, 24, 1, 0, true)
MUX_CFG(DM644X, GPIO3, 0, 25, 1, 0, false)
MUX_CFG(DM644X, GPIO43_44, 1, 7, 1, 0, false)
MUX_CFG(DM644X, GPIO46_47, 0, 22, 1, 0, true)
MUX_CFG(DM644X, RGB666, 0, 22, 1, 1, true)
MUX_CFG(DM644X, LOEEN, 0, 24, 1, 1, true)
MUX_CFG(DM644X, LFLDEN, 0, 25, 1, 1, false)
};
/*----------------------------------------------------------------------*/
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 struct edma_soc_info dm644x_edma_info = {
.n_channel = 64,
.n_region = 4,
.n_slot = 128,
.n_tc = 2,
.noevent = dma_chan_dm644x_no_event,
};
static struct resource edma_resources[] = {
{
.name = "edma_cc",
.start = 0x01c00000,
.end = 0x01c00000 + SZ_64K - 1,
.flags = IORESOURCE_MEM,
},
{
.name = "edma_tc0",
.start = 0x01c10000,
.end = 0x01c10000 + SZ_1K - 1,
.flags = IORESOURCE_MEM,
},
{
.name = "edma_tc1",
.start = 0x01c10400,
.end = 0x01c10400 + SZ_1K - 1,
.flags = IORESOURCE_MEM,
},
{
.start = IRQ_CCINT0,
.flags = IORESOURCE_IRQ,
},
{
.start = IRQ_CCERRINT,
.flags = IORESOURCE_IRQ,
},
/* not using TC*_ERR */
};
static struct platform_device dm644x_edma_device = {
.name = "edma",
.id = -1,
.dev.platform_data = &dm644x_edma_info,
.num_resources = ARRAY_SIZE(edma_resources),
.resource = edma_resources,
};
/*----------------------------------------------------------------------*/
void __init dm644x_init(void)
{
davinci_clk_init(dm644x_clks);
davinci_mux_register(dm644x_pins, ARRAY_SIZE(dm644x_pins));
}
static int __init dm644x_init_devices(void)
{
if (!cpu_is_davinci_dm644x())
return 0;
platform_device_register(&dm644x_edma_device);
return 0;
}
postcore_initcall(dm644x_init_devices);
此差异已折叠。
......@@ -20,6 +20,7 @@
#include <linux/irq.h>
#include <linux/bitops.h>
#include <mach/cputype.h>
#include <mach/irqs.h>
#include <mach/hardware.h>
#include <mach/gpio.h>
......@@ -36,9 +37,10 @@ struct davinci_gpio {
static struct davinci_gpio chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)];
static unsigned __initdata ngpio;
/* create a non-inlined version */
static struct gpio_controller *__iomem __init gpio2controller(unsigned gpio)
static struct gpio_controller __iomem * __init gpio2controller(unsigned gpio)
{
return __gpio_to_controller(gpio);
}
......@@ -114,9 +116,30 @@ static int __init davinci_gpio_setup(void)
{
int i, base;
for (i = 0, base = 0;
i < ARRAY_SIZE(chips);
i++, base += 32) {
/* The gpio banks conceptually expose a segmented bitmap,
* and "ngpio" is one more than the largest zero-based
* bit index that's valid.
*/
if (cpu_is_davinci_dm355()) { /* or dm335() */
ngpio = 104;
} else if (cpu_is_davinci_dm644x()) { /* or dm337() */
ngpio = 71;
} else if (cpu_is_davinci_dm646x()) {
/* NOTE: each bank has several "reserved" bits,
* unusable as GPIOs. Only 33 of the GPIO numbers
* are usable, and we're not rejecting the others.
*/
ngpio = 43;
} else {
/* if cpu_is_davinci_dm643x() ngpio = 111 */
pr_err("GPIO setup: how many GPIOs?\n");
return -EINVAL;
}
if (WARN_ON(DAVINCI_N_GPIO < ngpio))
ngpio = DAVINCI_N_GPIO;
for (i = 0, base = 0; base < ngpio; i++, base += 32) {
chips[i].chip.label = "DaVinci";
chips[i].chip.direction_input = davinci_direction_in;
......@@ -125,7 +148,7 @@ static int __init davinci_gpio_setup(void)
chips[i].chip.set = davinci_gpio_set;
chips[i].chip.base = base;
chips[i].chip.ngpio = DAVINCI_N_GPIO - base;
chips[i].chip.ngpio = ngpio - base;
if (chips[i].chip.ngpio > 32)
chips[i].chip.ngpio = 32;
......@@ -143,11 +166,11 @@ pure_initcall(davinci_gpio_setup);
* We expect irqs will normally be set up as input pins, but they can also be
* used as output pins ... which is convenient for testing.
*
* NOTE: GPIO0..GPIO7 also have direct INTC hookups, which work in addition
* to their GPIOBNK0 irq (but with a bit less overhead). But we don't have
* a good way to hook those up ...
* NOTE: The first few GPIOs also have direct INTC hookups in addition
* to their GPIOBNK0 irq, with a bit less overhead but less flexibility
* on triggering (e.g. no edge options). We don't try to use those.
*
* All those INTC hookups (GPIO0..GPIO7 plus five IRQ banks) can also
* All those INTC hookups (direct, plus several IRQ banks) can also
* serve as EDMA event triggers.
*/
......@@ -235,29 +258,42 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc)
}
/*
* NOTE: for suspend/resume, probably best to make a sysdev (and class)
* with its suspend/resume calls hooking into the results of the set_wake()
* NOTE: for suspend/resume, probably best to make a platform_device with
* suspend_late/resume_resume calls hooking into results of the set_wake()
* calls ... so if no gpios are wakeup events the clock can be disabled,
* with outputs left at previously set levels, and so that VDD3P3V.IOPWDN0
* can be set appropriately for GPIOV33 pins.
* (dm6446) can be set appropriately for GPIOV33 pins.
*/
static int __init davinci_gpio_irq_setup(void)
{
unsigned gpio, irq, bank;
unsigned bank_irq;
struct clk *clk;
u32 binten = 0;
if (cpu_is_davinci_dm355()) { /* or dm335() */
bank_irq = IRQ_DM355_GPIOBNK0;
} else if (cpu_is_davinci_dm644x()) {
bank_irq = IRQ_GPIOBNK0;
} else if (cpu_is_davinci_dm646x()) {
bank_irq = IRQ_DM646X_GPIOBNK0;
} else {
printk(KERN_ERR "Don't know first GPIO bank IRQ.\n");
return -EINVAL;
}
clk = clk_get(NULL, "gpio");
if (IS_ERR(clk)) {
printk(KERN_ERR "Error %ld getting gpio clock?\n",
PTR_ERR(clk));
return 0;
return PTR_ERR(clk);
}
clk_enable(clk);
for (gpio = 0, irq = gpio_to_irq(0), bank = IRQ_GPIOBNK0;
gpio < DAVINCI_N_GPIO; bank++) {
for (gpio = 0, irq = gpio_to_irq(0), bank = 0;
gpio < ngpio;
bank++, bank_irq++) {
struct gpio_controller *__iomem g = gpio2controller(gpio);
unsigned i;
......@@ -265,28 +301,28 @@ static int __init davinci_gpio_irq_setup(void)
__raw_writel(~0, &g->clr_rising);
/* set up all irqs in this bank */
set_irq_chained_handler(bank, gpio_irq_handler);
set_irq_chip_data(bank, g);
set_irq_data(bank, (void *)irq);
set_irq_chained_handler(bank_irq, gpio_irq_handler);
set_irq_chip_data(bank_irq, g);
set_irq_data(bank_irq, (void *)irq);
for (i = 0; i < 16 && gpio < DAVINCI_N_GPIO;
i++, irq++, gpio++) {
for (i = 0; i < 16 && gpio < ngpio; i++, irq++, gpio++) {
set_irq_chip(irq, &gpio_irqchip);
set_irq_chip_data(irq, g);
set_irq_handler(irq, handle_simple_irq);
set_irq_flags(irq, IRQF_VALID);
}
binten |= BIT(bank);
}
/* BINTEN -- per-bank interrupt enable. genirq would also let these
* bits be set/cleared dynamically.
*/
__raw_writel(0x1f, (void *__iomem)
__raw_writel(binten, (void *__iomem)
IO_ADDRESS(DAVINCI_GPIO_BASE + 0x08));
printk(KERN_INFO "DaVinci: %d gpio irqs\n", irq - gpio_to_irq(0));
return 0;
}
arch_initcall(davinci_gpio_irq_setup);
......@@ -15,7 +15,9 @@
#include <linux/init.h>
#include <linux/io.h>
#define JTAG_ID_BASE 0x01c40028
#define JTAG_ID_BASE IO_ADDRESS(0x01c40028)
static unsigned int davinci_revision;
struct davinci_id {
u8 variant; /* JTAG ID bits 31:28 */
......@@ -33,6 +35,20 @@ static struct davinci_id davinci_ids[] __initdata = {
.manufacturer = 0x017,
.type = 0x64460000,
},
{
/* DM646X */
.part_no = 0xb770,
.variant = 0x0,
.manufacturer = 0x017,
.type = 0x64670000,
},
{
/* DM355 */
.part_no = 0xb73b,
.variant = 0x0,
.manufacturer = 0x00f,
.type = 0x03550000,
},
};
/*
......@@ -42,7 +58,7 @@ static u16 __init davinci_get_part_no(void)
{
u32 dev_id, part_no;
dev_id = davinci_readl(JTAG_ID_BASE);
dev_id = __raw_readl(JTAG_ID_BASE);
part_no = ((dev_id >> 12) & 0xffff);
......@@ -56,13 +72,19 @@ static u8 __init davinci_get_variant(void)
{
u32 variant;
variant = davinci_readl(JTAG_ID_BASE);
variant = __raw_readl(JTAG_ID_BASE);
variant = (variant >> 28) & 0xf;
return variant;
}
unsigned int davinci_rev(void)
{
return davinci_revision >> 16;
}
EXPORT_SYMBOL(davinci_rev);
void __init davinci_check_revision(void)
{
int i;
......@@ -75,7 +97,7 @@ void __init davinci_check_revision(void)
/* First check only the major version in a safe way */
for (i = 0; i < ARRAY_SIZE(davinci_ids); i++) {
if (part_no == (davinci_ids[i].part_no)) {
system_rev = davinci_ids[i].type;
davinci_revision = davinci_ids[i].type;
break;
}
}
......@@ -84,10 +106,11 @@ void __init davinci_check_revision(void)
for (i = 0; i < ARRAY_SIZE(davinci_ids); i++) {
if (part_no == davinci_ids[i].part_no &&
variant == davinci_ids[i].variant) {
system_rev = davinci_ids[i].type;
davinci_revision = davinci_ids[i].type;
break;
}
}
printk("DaVinci DM%04x variant 0x%x\n", system_rev >> 16, variant);
printk(KERN_INFO "DaVinci DM%04x variant 0x%x\n",
davinci_rev(), variant);
}
/*
* DaVinci DM6446 EVM board specific headers
*
* Author: Kevin Hilman, Deep Root Systems, LLC
*
* 2007 (c) Deep Root Systems, LLC. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or ifndef.
*/
#ifndef _MACH_DAVINCI_DM6446EVM_H
#define _MACH_DAVINCI_DM6446EVM_H
#include <linux/types.h>
int dm6446evm_eeprom_read(char *buf, off_t off, size_t count);
int dm6446evm_eeprom_write(char *buf, off_t off, size_t count);
#endif
#ifndef __MACH_CLKDEV_H
#define __MACH_CLKDEV_H
static inline int __clk_get(struct clk *clk)
{
return 1;
}
static inline void __clk_put(struct clk *clk)
{
}
#endif
......@@ -17,6 +17,5 @@ struct clk;
extern int clk_register(struct clk *clk);
extern void clk_unregister(struct clk *clk);
extern int davinci_clk_init(void);
#endif
......@@ -16,6 +16,12 @@ struct sys_timer;
extern struct sys_timer davinci_timer;
extern void davinci_irq_init(void);
extern void davinci_map_common_io(void);
/* parameters describe VBUS sourcing for host mode */
extern void setup_usb(unsigned mA, unsigned potpgt_msec);
/* parameters describe VBUS sourcing for host mode */
extern void setup_usb(unsigned mA, unsigned potpgt_msec);
......
/*
* DaVinci CPU type detection
*
* Author: Kevin Hilman, Deep Root Systems, LLC
*
* Defines the cpu_is_*() macros for runtime detection of DaVinci
* device type. In addtion, if support for a given device is not
* compiled in to the kernel, the macros return 0 so that
* resulting code can be optimized out.
*
* 2009 (c) Deep Root Systems, LLC. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#ifndef _ASM_ARCH_CPU_H
#define _ASM_ARCH_CPU_H
extern unsigned int davinci_rev(void);
#define IS_DAVINCI_CPU(type, id) \
static inline int is_davinci_dm ##type(void) \
{ \
return (davinci_rev() == (id)) ? 1 : 0; \
}
IS_DAVINCI_CPU(644x, 0x6446)
IS_DAVINCI_CPU(646x, 0x6467)
IS_DAVINCI_CPU(355, 0x355)
#ifdef CONFIG_ARCH_DAVINCI_DM644x
#define cpu_is_davinci_dm644x() is_davinci_dm644x()
#else
#define cpu_is_davinci_dm644x() 0
#endif
#ifdef CONFIG_ARCH_DAVINCI_DM646x
#define cpu_is_davinci_dm646x() is_davinci_dm646x()
#else
#define cpu_is_davinci_dm646x() 0
#endif
#ifdef CONFIG_ARCH_DAVINCI_DM355
#define cpu_is_davinci_dm355() is_davinci_dm355()
#else
#define cpu_is_davinci_dm355() 0
#endif
#endif
/*
* This file contains the processor specific definitions
* of the TI DM644x.
*
* Copyright (C) 2008 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef __ASM_ARCH_DM644X_H
#define __ASM_ARCH_DM644X_H
#include <linux/platform_device.h>
#include <mach/hardware.h>
#define DM644X_EMAC_BASE (0x01C80000)
#define DM644X_EMAC_CNTRL_OFFSET (0x0000)
#define DM644X_EMAC_CNTRL_MOD_OFFSET (0x1000)
#define DM644X_EMAC_CNTRL_RAM_OFFSET (0x2000)
#define DM644X_EMAC_MDIO_OFFSET (0x4000)
#define DM644X_EMAC_CNTRL_RAM_SIZE (0x2000)
void __init dm644x_init(void);
#endif /* __ASM_ARCH_DM644X_H */
此差异已折叠。
......@@ -15,9 +15,11 @@
#include <linux/io.h>
#include <asm-generic/gpio.h>
#include <mach/hardware.h>
#include <mach/irqs.h>
#define DAVINCI_GPIO_BASE 0x01C67000
/*
* basic gpio routines
*
......@@ -26,23 +28,18 @@
* go through boot loaders.
*
* the gpio clock will be turned on when gpios are used, and you may also
* need to pay attention to PINMUX0 and PINMUX1 to be sure those pins are
* need to pay attention to PINMUX registers to be sure those pins are
* used as gpios, not with other peripherals.
*
* On-chip GPIOs are numbered 0..(DAVINCI_N_GPIO-1). For documentation,
* and maybe for later updates, code should write GPIO(N) or:
* - GPIOV18(N) for 1.8V pins, N in 0..53; same as GPIO(0)..GPIO(53)
* - GPIOV33(N) for 3.3V pins, N in 0..17; same as GPIO(54)..GPIO(70)
*
* For GPIO IRQs use gpio_to_irq(GPIO(N)) or gpio_to_irq(GPIOV33(N)) etc
* for now, that's != GPIO(N)
* and maybe for later updates, code may write GPIO(N). These may be
* all 1.8V signals, all 3.3V ones, or a mix of the two. A given chip
* may not support all the GPIOs in that range.
*
* GPIOs can also be on external chips, numbered after the ones built-in
* to the DaVinci chip. For now, they won't be usable as IRQ sources.
*/
#define GPIO(X) (X) /* 0 <= X <= 70 */
#define GPIOV18(X) (X) /* 1.8V i/o; 0 <= X <= 53 */
#define GPIOV33(X) ((X)+54) /* 3.3V i/o; 0 <= X <= 17 */
#define GPIO(X) (X) /* 0 <= X <= (DAVINCI_N_GPIO - 1) */
struct gpio_controller {
u32 dir;
......@@ -71,12 +68,14 @@ __gpio_to_controller(unsigned gpio)
{
void *__iomem ptr;
if (gpio < 32)
if (gpio < 32 * 1)
ptr = IO_ADDRESS(DAVINCI_GPIO_BASE + 0x10);
else if (gpio < 64)
else if (gpio < 32 * 2)
ptr = IO_ADDRESS(DAVINCI_GPIO_BASE + 0x38);
else if (gpio < DAVINCI_N_GPIO)
else if (gpio < 32 * 3)
ptr = IO_ADDRESS(DAVINCI_GPIO_BASE + 0x60);
else if (gpio < 32 * 4)
ptr = IO_ADDRESS(DAVINCI_GPIO_BASE + 0x88);
else
ptr = NULL;
return ptr;
......
/*
* Common hardware definitions
* Hardware definitions common to all DaVinci family processors
*
* Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com>
* Author: Kevin Hilman, Deep Root Systems, LLC
*
* 2007 (c) MontaVista Software, Inc. This file is licensed under
* 2007 (c) Deep Root Systems, LLC. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
......@@ -12,41 +12,16 @@
#define __ASM_ARCH_HARDWARE_H
/*
* Base register addresses
* Before you add anything to ths file:
*
* This header is for defines common to ALL DaVinci family chips.
* Anything that is chip specific should go in <chipname>.h,
* and the chip/board init code should then explicitly include
* <chipname>.h
*/
#define DAVINCI_DMA_3PCC_BASE (0x01C00000)
#define DAVINCI_DMA_3PTC0_BASE (0x01C10000)
#define DAVINCI_DMA_3PTC1_BASE (0x01C10400)
#define DAVINCI_I2C_BASE (0x01C21000)
#define DAVINCI_PWM0_BASE (0x01C22000)
#define DAVINCI_PWM1_BASE (0x01C22400)
#define DAVINCI_PWM2_BASE (0x01C22800)
#define DAVINCI_SYSTEM_MODULE_BASE (0x01C40000)
#define DAVINCI_PLL_CNTRL0_BASE (0x01C40800)
#define DAVINCI_PLL_CNTRL1_BASE (0x01C40C00)
#define DAVINCI_PWR_SLEEP_CNTRL_BASE (0x01C41000)
#define DAVINCI_SYSTEM_DFT_BASE (0x01C42000)
#define DAVINCI_IEEE1394_BASE (0x01C60000)
#define DAVINCI_USB_OTG_BASE (0x01C64000)
#define DAVINCI_CFC_ATA_BASE (0x01C66000)
#define DAVINCI_SPI_BASE (0x01C66800)
#define DAVINCI_GPIO_BASE (0x01C67000)
#define DAVINCI_UHPI_BASE (0x01C67800)
#define DAVINCI_VPSS_REGS_BASE (0x01C70000)
#define DAVINCI_EMAC_CNTRL_REGS_BASE (0x01C80000)
#define DAVINCI_EMAC_WRAPPER_CNTRL_REGS_BASE (0x01C81000)
#define DAVINCI_EMAC_WRAPPER_RAM_BASE (0x01C82000)
#define DAVINCI_MDIO_CNTRL_REGS_BASE (0x01C84000)
#define DAVINCI_IMCOP_BASE (0x01CC0000)
#define DAVINCI_ASYNC_EMIF_CNTRL_BASE (0x01E00000)
#define DAVINCI_VLYNQ_BASE (0x01E01000)
#define DAVINCI_MCBSP_BASE (0x01E02000)
#define DAVINCI_MMC_SD_BASE (0x01E10000)
#define DAVINCI_MS_BASE (0x01E20000)
#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE (0x02000000)
#define DAVINCI_ASYNC_EMIF_DATA_CE1_BASE (0x04000000)
#define DAVINCI_ASYNC_EMIF_DATA_CE2_BASE (0x06000000)
#define DAVINCI_ASYNC_EMIF_DATA_CE3_BASE (0x08000000)
#define DAVINCI_VLYNQ_REMOTE_BASE (0x0C000000)
#define DAVINCI_SYSTEM_MODULE_BASE 0x01C40000
/* System control register offsets */
#define DM64XX_VDD3P3V_PWDN 0x48
#endif /* __ASM_ARCH_HARDWARE_H */
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -14,6 +14,8 @@
#include <mach/hardware.h>
#include <mach/irqs.h>
#define DAVINCI_USB_OTG_BASE 0x01C64000
#if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE)
static struct musb_hdrc_eps_bits musb_eps[] = {
{ "ep1_tx", 8, },
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册