diff options
Diffstat (limited to 'arch/arm/mach-davinci/board-dm646x-evm.c')
| -rw-r--r-- | arch/arm/mach-davinci/board-dm646x-evm.c | 335 |
1 files changed, 225 insertions, 110 deletions
diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c index 8d0b0e01c59..ae129bc4927 100644 --- a/arch/arm/mach-davinci/board-dm646x-evm.c +++ b/arch/arm/mach-davinci/board-dm646x-evm.c @@ -22,71 +22,36 @@ #include <linux/gpio.h> #include <linux/platform_device.h> #include <linux/i2c.h> -#include <linux/i2c/at24.h> +#include <linux/platform_data/at24.h> #include <linux/i2c/pcf857x.h> #include <media/tvp514x.h> +#include <media/adv7343.h> #include <linux/mtd/mtd.h> #include <linux/mtd/nand.h> #include <linux/mtd/partitions.h> +#include <linux/clk.h> +#include <linux/export.h> +#include <linux/platform_data/gpio-davinci.h> +#include <linux/platform_data/i2c-davinci.h> +#include <linux/platform_data/mtd-davinci.h> +#include <linux/platform_data/mtd-davinci-aemif.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> -#include <mach/dm646x.h> #include <mach/common.h> +#include <mach/irqs.h> #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 "davinci.h" +#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. @@ -111,23 +76,34 @@ static struct mtd_partition davinci_nand_partitions[] = { } }; +static struct davinci_aemif_timing dm6467tevm_nandflash_timing = { + .wsetup = 29, + .wstrobe = 24, + .whold = 14, + .rsetup = 19, + .rstrobe = 33, + .rhold = 0, + .ta = 29, +}; + static struct davinci_nand_pdata davinci_nand_data = { .mask_cle = 0x80000, .mask_ale = 0x40000, .parts = davinci_nand_partitions, .nr_parts = ARRAY_SIZE(davinci_nand_partitions), .ecc_mode = NAND_ECC_HW, + .ecc_bits = 1, .options = 0, }; static struct resource davinci_nand_resources[] = { { - .start = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE, - .end = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE + SZ_32M - 1, + .start = DM646X_ASYNC_EMIF_CS2_SPACE_BASE, + .end = DM646X_ASYNC_EMIF_CS2_SPACE_BASE + SZ_32M - 1, .flags = IORESOURCE_MEM, }, { - .start = DAVINCI_ASYNC_EMIF_CONTROL_BASE, - .end = DAVINCI_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1, + .start = DM646X_ASYNC_EMIF_CONTROL_BASE, + .end = DM646X_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1, .flags = IORESOURCE_MEM, }, }; @@ -144,6 +120,12 @@ static struct platform_device davinci_nand_device = { }, }; +#define HAS_ATA IS_ENABLED(CONFIG_BLK_DEV_PALMCHIP_BK3710) + +/* CPLD Register 0 bits to control ATA */ +#define DM646X_EVM_ATA_RST BIT(0) +#define DM646X_EVM_ATA_PWD BIT(1) + /* CPLD Register 0 Client: used for I/O Control */ static int cpld_reg0_probe(struct i2c_client *client, const struct i2c_device_id *id) @@ -210,7 +192,7 @@ static int evm_led_setup(struct i2c_client *client, int gpio, while (ngpio--) { leds->gpio = gpio++; leds++; - }; + } evm_led_dev = platform_device_alloc("leds-gpio", 0); platform_device_add_data(evm_led_dev, &evm_led_data, @@ -352,7 +334,7 @@ static struct snd_platform_data dm646x_evm_snd_data[] = { .num_serializer = ARRAY_SIZE(dm646x_iis_serializer_direction), .tdm_slots = 2, .serial_dir = dm646x_iis_serializer_direction, - .eventq_no = EVENTQ_0, + .asp_chan_q = EVENTQ_0, }, { .tx_dma_offset = 0x400, @@ -361,7 +343,7 @@ static struct snd_platform_data dm646x_evm_snd_data[] = { .num_serializer = ARRAY_SIZE(dm646x_dit_serializer_direction), .tdm_slots = 32, .serial_dir = dm646x_dit_serializer_direction, - .eventq_no = EVENTQ_0, + .asp_chan_q = EVENTQ_0, }, }; @@ -374,7 +356,7 @@ static int cpld_video_probe(struct i2c_client *client, return 0; } -static int __devexit cpld_video_remove(struct i2c_client *client) +static int cpld_video_remove(struct i2c_client *client) { cpld_client = NULL; return 0; @@ -417,6 +399,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 +409,26 @@ static struct davinci_i2c_platform_data i2c_pdata = { .bus_delay = 0 /* usec */, }; +#define VCH2CLK_MASK (BIT_MASK(10) | BIT_MASK(9) | BIT_MASK(8)) +#define VCH2CLK_SYSCLK8 (BIT(9)) +#define VCH2CLK_AUXCLK (BIT(9) | BIT(8)) +#define VCH3CLK_MASK (BIT_MASK(14) | BIT_MASK(13) | BIT_MASK(12)) +#define VCH3CLK_SYSCLK8 (BIT(13)) +#define VCH3CLK_AUXCLK (BIT(14) | BIT(13)) + +#define VIDCH2CLK (BIT(10)) +#define VIDCH3CLK (BIT(11)) +#define VIDCH1CLK (BIT(4)) +#define TVP7002_INPUT (BIT(4)) +#define TVP5147_INPUT (~BIT(4)) +#define VPIF_INPUT_ONE_CHANNEL (BIT(5)) +#define VPIF_INPUT_TWO_CHANNEL (~BIT(5)) +#define TVP5147_CH0 "tvp514x-0" +#define TVP5147_CH1 "tvp514x-1" + +/* spin lock for updating above registers */ +static spinlock_t vpif_reg_lock; + static int set_vpif_clock(int mux_mode, int hd) { unsigned long flags; @@ -431,14 +436,14 @@ static int set_vpif_clock(int mux_mode, int hd) int val = 0; int err = 0; - if (!vpif_vidclkctl_reg || !vpif_vsclkdis_reg || !cpld_client) + if (!cpld_client) return -ENXIO; /* disable the clock */ spin_lock_irqsave(&vpif_reg_lock, flags); - value = __raw_readl(vpif_vsclkdis_reg); + value = __raw_readl(DAVINCI_SYSMOD_VIRT(SYSMOD_VSCLKDIS)); value |= (VIDCH3CLK | VIDCH2CLK); - __raw_writel(value, vpif_vsclkdis_reg); + __raw_writel(value, DAVINCI_SYSMOD_VIRT(SYSMOD_VSCLKDIS)); spin_unlock_irqrestore(&vpif_reg_lock, flags); val = i2c_smbus_read_byte(cpld_client); @@ -454,7 +459,7 @@ static int set_vpif_clock(int mux_mode, int hd) if (err) return err; - value = __raw_readl(vpif_vidclkctl_reg); + value = __raw_readl(DAVINCI_SYSMOD_VIRT(SYSMOD_VIDCLKCTL)); value &= ~(VCH2CLK_MASK); value &= ~(VCH3CLK_MASK); @@ -463,13 +468,13 @@ static int set_vpif_clock(int mux_mode, int hd) else value |= (VCH2CLK_AUXCLK | VCH3CLK_AUXCLK); - __raw_writel(value, vpif_vidclkctl_reg); + __raw_writel(value, DAVINCI_SYSMOD_VIRT(SYSMOD_VIDCLKCTL)); spin_lock_irqsave(&vpif_reg_lock, flags); - value = __raw_readl(vpif_vsclkdis_reg); + value = __raw_readl(DAVINCI_SYSMOD_VIRT(SYSMOD_VSCLKDIS)); /* enable the clock */ value &= ~(VIDCH3CLK | VIDCH2CLK); - __raw_writel(value, vpif_vsclkdis_reg); + __raw_writel(value, DAVINCI_SYSMOD_VIRT(SYSMOD_VSCLKDIS)); spin_unlock_irqrestore(&vpif_reg_lock, flags); return 0; @@ -490,18 +495,49 @@ static struct vpif_subdev_info dm646x_vpif_subdev[] = { }, }; -static const char *output[] = { - "Composite", - "Component", - "S-Video", +static const struct vpif_output dm6467_ch0_outputs[] = { + { + .output = { + .index = 0, + .name = "Composite", + .type = V4L2_OUTPUT_TYPE_ANALOG, + .capabilities = V4L2_OUT_CAP_STD, + .std = V4L2_STD_ALL, + }, + .subdev_name = "adv7343", + .output_route = ADV7343_COMPOSITE_ID, + }, + { + .output = { + .index = 1, + .name = "Component", + .type = V4L2_OUTPUT_TYPE_ANALOG, + .capabilities = V4L2_OUT_CAP_DV_TIMINGS, + }, + .subdev_name = "adv7343", + .output_route = ADV7343_COMPONENT_ID, + }, + { + .output = { + .index = 2, + .name = "S-Video", + .type = V4L2_OUTPUT_TYPE_ANALOG, + .capabilities = V4L2_OUT_CAP_STD, + .std = V4L2_STD_ALL, + }, + .subdev_name = "adv7343", + .output_route = ADV7343_SVIDEO_ID, + }, }; static struct vpif_display_config dm646x_vpif_display_config = { .set_clock = set_vpif_clock, .subdevinfo = dm646x_vpif_subdev, .subdev_count = ARRAY_SIZE(dm646x_vpif_subdev), - .output = output, - .output_count = ARRAY_SIZE(output), + .chan_config[0] = { + .outputs = dm6467_ch0_outputs, + .output_count = ARRAY_SIZE(dm6467_ch0_outputs), + }, .card_name = "DM646x EVM", }; @@ -554,7 +590,7 @@ static int setup_vpif_input_channel_mode(int mux_mode) int val; u32 value; - if (!vpif_vsclkdis_reg || !cpld_client) + if (!cpld_client) return -ENXIO; val = i2c_smbus_read_byte(cpld_client); @@ -562,7 +598,7 @@ static int setup_vpif_input_channel_mode(int mux_mode) return val; spin_lock_irqsave(&vpif_reg_lock, flags); - value = __raw_readl(vpif_vsclkdis_reg); + value = __raw_readl(DAVINCI_SYSMOD_VIRT(SYSMOD_VIDCLKCTL)); if (mux_mode) { val &= VPIF_INPUT_TWO_CHANNEL; value |= VIDCH1CLK; @@ -570,7 +606,7 @@ static int setup_vpif_input_channel_mode(int mux_mode) val |= VPIF_INPUT_ONE_CHANNEL; value &= ~VIDCH1CLK; } - __raw_writel(value, vpif_vsclkdis_reg); + __raw_writel(value, DAVINCI_SYSMOD_VIRT(SYSMOD_VIDCLKCTL)); spin_unlock_irqrestore(&vpif_reg_lock, flags); err = i2c_smbus_write_byte(cpld_client, val); @@ -595,15 +631,6 @@ static struct vpif_subdev_info vpif_capture_sdev_info[] = { I2C_BOARD_INFO("tvp5146", 0x5d), .platform_data = &tvp5146_pdata, }, - .input = INPUT_CVBS_VI2B, - .output = OUTPUT_10BIT_422_EMBEDDED_SYNC, - .can_route = 1, - .vpif_if = { - .if_type = VPIF_IF_BT656, - .hd_pol = 1, - .vd_pol = 1, - .fid_pol = 0, - }, }, { .name = TVP5147_CH1, @@ -611,15 +638,6 @@ static struct vpif_subdev_info vpif_capture_sdev_info[] = { I2C_BOARD_INFO("tvp5146", 0x5c), .platform_data = &tvp5146_pdata, }, - .input = INPUT_SVIDEO_VI2C_VI1C, - .output = OUTPUT_10BIT_422_EMBEDDED_SYNC, - .can_route = 1, - .vpif_if = { - .if_type = VPIF_IF_BT656, - .hd_pol = 1, - .vd_pol = 1, - .fid_pol = 0, - }, }, }; @@ -629,9 +647,12 @@ static const struct vpif_input dm6467_ch0_inputs[] = { .index = 0, .name = "Composite", .type = V4L2_INPUT_TYPE_CAMERA, + .capabilities = V4L2_IN_CAP_STD, .std = TVP514X_STD_ALL, }, .subdev_name = TVP5147_CH0, + .input_route = INPUT_CVBS_VI2B, + .output_route = OUTPUT_10BIT_422_EMBEDDED_SYNC, }, }; @@ -641,9 +662,12 @@ static const struct vpif_input dm6467_ch1_inputs[] = { .index = 0, .name = "S-Video", .type = V4L2_INPUT_TYPE_CAMERA, + .capabilities = V4L2_IN_CAP_STD, .std = TVP514X_STD_ALL, }, .subdev_name = TVP5147_CH1, + .input_route = INPUT_SVIDEO_VI2C_VI1C, + .output_route = OUTPUT_10BIT_422_EMBEDDED_SYNC, }, }; @@ -655,21 +679,27 @@ static struct vpif_capture_config dm646x_vpif_capture_cfg = { .chan_config[0] = { .inputs = dm6467_ch0_inputs, .input_count = ARRAY_SIZE(dm6467_ch0_inputs), + .vpif_if = { + .if_type = VPIF_IF_BT656, + .hd_pol = 1, + .vd_pol = 1, + .fid_pol = 0, + }, }, .chan_config[1] = { .inputs = dm6467_ch1_inputs, .input_count = ARRAY_SIZE(dm6467_ch1_inputs), + .vpif_if = { + .if_type = VPIF_IF_BT656, + .hd_pol = 1, + .vd_pol = 1, + .fid_pol = 0, + }, }, }; static void __init evm_init_video(void) { - vpif_vidclkctl_reg = ioremap(VIDCLKCTL_OFFSET, 4); - vpif_vsclkdis_reg = ioremap(VSCLKDIS_OFFSET, 4); - if (!vpif_vidclkctl_reg || !vpif_vsclkdis_reg) { - pr_err("Can't map VPIF VIDCLKCTL or VSCLKDIS registers\n"); - return; - } spin_lock_init(&vpif_reg_lock); dm646x_setup_vpif(&dm646x_vpif_display_config, @@ -685,41 +715,126 @@ 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); + } +} + +#define DM6467T_EVM_REF_FREQ 33000000 + static void __init davinci_map_io(void) { dm646x_init(); + + if (machine_is_davinci_dm6467tevm()) + davinci_set_refclk_rate(DM6467T_EVM_REF_FREQ); + + cdce_clk_init(); } +#define DM646X_EVM_PHY_ID "davinci_mdio-0:01" +/* + * The following EDMA channels/slots are not being used by drivers (for + * example: Timer, GPIO, UART events etc) on dm646x, hence they are being + * reserved for codecs on the DSP side. + */ +static const s16 dm646x_dma_rsv_chans[][2] = { + /* (offset, number) */ + { 0, 4}, + {13, 3}, + {24, 4}, + {30, 2}, + {54, 3}, + {-1, -1} +}; + +static const s16 dm646x_dma_rsv_slots[][2] = { + /* (offset, number) */ + { 0, 4}, + {13, 3}, + {24, 4}, + {30, 2}, + {54, 3}, + {128, 384}, + {-1, -1} +}; + +static struct edma_rsv_info dm646x_edma_rsv[] = { + { + .rsv_chans = dm646x_dma_rsv_chans, + .rsv_slots = dm646x_dma_rsv_slots, + }, +}; + static __init void evm_init(void) { + int ret; struct davinci_soc_info *soc_info = &davinci_soc_info; + ret = dm646x_gpio_register(); + if (ret) + pr_warn("%s: GPIO init failed: %d\n", __func__, ret); + evm_init_i2c(); - davinci_serial_init(&uart_config); + davinci_serial_init(dm646x_serial_device); dm646x_init_mcasp0(&dm646x_evm_snd_data[0]); dm646x_init_mcasp1(&dm646x_evm_snd_data[1]); + if (machine_is_davinci_dm6467tevm()) + davinci_nand_data.timing = &dm6467tevm_nandflash_timing; + platform_device_register(&davinci_nand_device); - if (HAS_ATA) - dm646x_init_ide(); + if (davinci_aemif_setup(&davinci_nand_device)) + pr_warn("%s: Cannot configure AEMIF.\n", __func__); - soc_info->emac_pdata->phy_mask = DM646X_EVM_PHY_MASK; - soc_info->emac_pdata->mdio_max_freq = DM646X_EVM_MDIO_FREQUENCY; -} + dm646x_init_edma(dm646x_edma_rsv); -static __init void davinci_dm646x_evm_irq_init(void) -{ - davinci_irq_init(); + if (HAS_ATA) + davinci_init_ide(); + + soc_info->emac_pdata->phy_id = DM646X_EVM_PHY_ID; } MACHINE_START(DAVINCI_DM6467_EVM, "DaVinci DM646x EVM") - .phys_io = IO_PHYS, - .io_pg_offst = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc, - .boot_params = (0x80000100), + .atag_offset = 0x100, + .map_io = davinci_map_io, + .init_irq = davinci_irq_init, + .init_time = davinci_timer_init, + .init_machine = evm_init, + .init_late = davinci_init_late, + .dma_zone_size = SZ_128M, + .restart = davinci_restart, +MACHINE_END + +MACHINE_START(DAVINCI_DM6467TEVM, "DaVinci DM6467T EVM") + .atag_offset = 0x100, .map_io = davinci_map_io, - .init_irq = davinci_dm646x_evm_irq_init, - .timer = &davinci_timer, + .init_irq = davinci_irq_init, + .init_time = davinci_timer_init, .init_machine = evm_init, + .init_late = davinci_init_late, + .dma_zone_size = SZ_128M, + .restart = davinci_restart, MACHINE_END |
