From e38d92fdcd04c79d28679682f63a83487c4c4c05 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Wed, 29 Apr 2009 17:44:58 -0700 Subject: davinci: DM646x: add base SoC and board support Add support for DM646x SoC (a.k.a DaVinci HD) and its Evalution Module (EVM.) Original support done by Sudhakar Rajashekhara. Signed-off-by: Sudhakar Rajashekhara Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/dm646x.c | 402 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 402 insertions(+) create mode 100644 arch/arm/mach-davinci/dm646x.c (limited to 'arch/arm/mach-davinci/dm646x.c') diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c new file mode 100644 index 00000000000..93443a6637e --- /dev/null +++ b/arch/arm/mach-davinci/dm646x.c @@ -0,0 +1,402 @@ +/* + * 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 +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "clock.h" +#include "mux.h" + +/* + * Device specific clocks + */ +#define DM646X_REF_FREQ 27000000 +#define DM646X_AUX_FREQ 24000000 + +static struct pll_data pll1_data = { + .num = 1, + .phys_base = DAVINCI_PLL1_BASE, +}; + +static struct pll_data pll2_data = { + .num = 2, + .phys_base = DAVINCI_PLL2_BASE, +}; + +static struct clk ref_clk = { + .name = "ref_clk", + .rate = DM646X_REF_FREQ, +}; + +static struct clk aux_clkin = { + .name = "aux_clkin", + .rate = DM646X_AUX_FREQ, +}; + +static struct clk pll1_clk = { + .name = "pll1", + .parent = &ref_clk, + .pll_data = &pll1_data, + .flags = CLK_PLL, +}; + +static struct clk pll1_sysclk1 = { + .name = "pll1_sysclk1", + .parent = &pll1_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV1, +}; + +static struct clk pll1_sysclk2 = { + .name = "pll1_sysclk2", + .parent = &pll1_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV2, +}; + +static struct clk pll1_sysclk3 = { + .name = "pll1_sysclk3", + .parent = &pll1_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV3, +}; + +static struct clk pll1_sysclk4 = { + .name = "pll1_sysclk4", + .parent = &pll1_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV4, +}; + +static struct clk pll1_sysclk5 = { + .name = "pll1_sysclk5", + .parent = &pll1_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV5, +}; + +static struct clk pll1_sysclk6 = { + .name = "pll1_sysclk6", + .parent = &pll1_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV6, +}; + +static struct clk pll1_sysclk8 = { + .name = "pll1_sysclk8", + .parent = &pll1_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV8, +}; + +static struct clk pll1_sysclk9 = { + .name = "pll1_sysclk9", + .parent = &pll1_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV9, +}; + +static struct clk pll1_sysclkbp = { + .name = "pll1_sysclkbp", + .parent = &pll1_clk, + .flags = CLK_PLL | PRE_PLL, + .div_reg = BPDIV, +}; + +static struct clk pll1_aux_clk = { + .name = "pll1_aux_clk", + .parent = &pll1_clk, + .flags = CLK_PLL | PRE_PLL, +}; + +static struct clk pll2_clk = { + .name = "pll2_clk", + .parent = &ref_clk, + .pll_data = &pll2_data, + .flags = CLK_PLL, +}; + +static struct clk pll2_sysclk1 = { + .name = "pll2_sysclk1", + .parent = &pll2_clk, + .flags = CLK_PLL, + .div_reg = PLLDIV1, +}; + +static struct clk dsp_clk = { + .name = "dsp", + .parent = &pll1_sysclk1, + .lpsc = DM646X_LPSC_C64X_CPU, + .flags = PSC_DSP, + .usecount = 1, /* REVISIT how to disable? */ +}; + +static struct clk arm_clk = { + .name = "arm", + .parent = &pll1_sysclk2, + .lpsc = DM646X_LPSC_ARM, + .flags = ALWAYS_ENABLED, +}; + +static struct clk uart0_clk = { + .name = "uart0", + .parent = &aux_clkin, + .lpsc = DM646X_LPSC_UART0, +}; + +static struct clk uart1_clk = { + .name = "uart1", + .parent = &aux_clkin, + .lpsc = DM646X_LPSC_UART1, +}; + +static struct clk uart2_clk = { + .name = "uart2", + .parent = &aux_clkin, + .lpsc = DM646X_LPSC_UART2, +}; + +static struct clk i2c_clk = { + .name = "I2CCLK", + .parent = &pll1_sysclk3, + .lpsc = DM646X_LPSC_I2C, +}; + +static struct clk gpio_clk = { + .name = "gpio", + .parent = &pll1_sysclk3, + .lpsc = DM646X_LPSC_GPIO, +}; + +static struct clk aemif_clk = { + .name = "aemif", + .parent = &pll1_sysclk3, + .lpsc = DM646X_LPSC_AEMIF, + .flags = ALWAYS_ENABLED, +}; + +static struct clk emac_clk = { + .name = "emac", + .parent = &pll1_sysclk3, + .lpsc = DM646X_LPSC_EMAC, +}; + +static struct clk pwm0_clk = { + .name = "pwm0", + .parent = &pll1_sysclk3, + .lpsc = DM646X_LPSC_PWM0, + .usecount = 1, /* REVIST: disabling hangs system */ +}; + +static struct clk pwm1_clk = { + .name = "pwm1", + .parent = &pll1_sysclk3, + .lpsc = DM646X_LPSC_PWM1, + .usecount = 1, /* REVIST: disabling hangs system */ +}; + +static struct clk timer0_clk = { + .name = "timer0", + .parent = &pll1_sysclk3, + .lpsc = DM646X_LPSC_TIMER0, +}; + +static struct clk timer1_clk = { + .name = "timer1", + .parent = &pll1_sysclk3, + .lpsc = DM646X_LPSC_TIMER1, +}; + +static struct clk timer2_clk = { + .name = "timer2", + .parent = &pll1_sysclk3, + .flags = ALWAYS_ENABLED, /* no LPSC, always enabled; c.f. spruep9a */ +}; + +static struct clk vpif0_clk = { + .name = "vpif0", + .parent = &ref_clk, + .lpsc = DM646X_LPSC_VPSSMSTR, + .flags = ALWAYS_ENABLED, +}; + +static struct clk vpif1_clk = { + .name = "vpif1", + .parent = &ref_clk, + .lpsc = DM646X_LPSC_VPSSSLV, + .flags = ALWAYS_ENABLED, +}; + +struct davinci_clk dm646x_clks[] = { + CLK(NULL, "ref", &ref_clk), + CLK(NULL, "aux", &aux_clkin), + CLK(NULL, "pll1", &pll1_clk), + CLK(NULL, "pll1_sysclk", &pll1_sysclk1), + CLK(NULL, "pll1_sysclk", &pll1_sysclk2), + CLK(NULL, "pll1_sysclk", &pll1_sysclk3), + CLK(NULL, "pll1_sysclk", &pll1_sysclk4), + CLK(NULL, "pll1_sysclk", &pll1_sysclk5), + CLK(NULL, "pll1_sysclk", &pll1_sysclk6), + CLK(NULL, "pll1_sysclk", &pll1_sysclk8), + CLK(NULL, "pll1_sysclk", &pll1_sysclk9), + CLK(NULL, "pll1_sysclk", &pll1_sysclkbp), + CLK(NULL, "pll1_aux", &pll1_aux_clk), + CLK(NULL, "pll2", &pll2_clk), + CLK(NULL, "pll2_sysclk1", &pll2_sysclk1), + CLK(NULL, "dsp", &dsp_clk), + CLK(NULL, "arm", &arm_clk), + CLK(NULL, "uart0", &uart0_clk), + CLK(NULL, "uart1", &uart1_clk), + CLK(NULL, "uart2", &uart2_clk), + CLK("i2c_davinci.1", NULL, &i2c_clk), + CLK(NULL, "gpio", &gpio_clk), + CLK(NULL, "aemif", &aemif_clk), + CLK("davinci_emac.1", NULL, &emac_clk), + CLK(NULL, "pwm0", &pwm0_clk), + CLK(NULL, "pwm1", &pwm1_clk), + CLK(NULL, "timer0", &timer0_clk), + CLK(NULL, "timer1", &timer1_clk), + CLK("watchdog", NULL, &timer2_clk), + CLK(NULL, "vpif0", &vpif0_clk), + CLK(NULL, "vpif1", &vpif1_clk), + CLK(NULL, NULL, NULL), +}; + +/* + * Device specific mux setup + * + * soc description mux mode mode mux dbg + * reg offset mask mode + */ +static const struct mux_config dm646x_pins[] = { +MUX_CFG(DM646X, ATAEN, 0, 0, 1, 1, true) + +MUX_CFG(DM646X, AUDCK1, 0, 29, 1, 0, false) + +MUX_CFG(DM646X, AUDCK0, 0, 28, 1, 0, false) + +MUX_CFG(DM646X, CRGMUX, 0, 24, 7, 5, true) + +MUX_CFG(DM646X, STSOMUX_DISABLE, 0, 22, 3, 0, true) + +MUX_CFG(DM646X, STSIMUX_DISABLE, 0, 20, 3, 0, true) + +MUX_CFG(DM646X, PTSOMUX_DISABLE, 0, 18, 3, 0, true) + +MUX_CFG(DM646X, PTSIMUX_DISABLE, 0, 16, 3, 0, true) + +MUX_CFG(DM646X, STSOMUX, 0, 22, 3, 2, true) + +MUX_CFG(DM646X, STSIMUX, 0, 20, 3, 2, true) + +MUX_CFG(DM646X, PTSOMUX_PARALLEL, 0, 18, 3, 2, true) + +MUX_CFG(DM646X, PTSIMUX_PARALLEL, 0, 16, 3, 2, true) + +MUX_CFG(DM646X, PTSOMUX_SERIAL, 0, 18, 3, 3, true) + +MUX_CFG(DM646X, PTSIMUX_SERIAL, 0, 16, 3, 3, true) +}; + +/*----------------------------------------------------------------------*/ + +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 +}; + +static struct edma_soc_info dm646x_edma_info = { + .n_channel = 64, + .n_region = 6, /* 0-1, 4-7 */ + .n_slot = 512, + .n_tc = 4, + .noevent = dma_chan_dm646x_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, + }, + { + .name = "edma_tc2", + .start = 0x01c10800, + .end = 0x01c10800 + SZ_1K - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "edma_tc3", + .start = 0x01c10c00, + .end = 0x01c10c00 + SZ_1K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_CCINT0, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_CCERRINT, + .flags = IORESOURCE_IRQ, + }, + /* not using TC*_ERR */ +}; + +static struct platform_device dm646x_edma_device = { + .name = "edma", + .id = -1, + .dev.platform_data = &dm646x_edma_info, + .num_resources = ARRAY_SIZE(edma_resources), + .resource = edma_resources, +}; + +/*----------------------------------------------------------------------*/ + +void __init dm646x_init(void) +{ + davinci_clk_init(dm646x_clks); + davinci_mux_register(dm646x_pins, ARRAY_SIZE(dm646x_pins)); +} + +static int __init dm646x_init_devices(void) +{ + if (!cpu_is_davinci_dm646x()) + return 0; + + platform_device_register(&dm646x_edma_device); + return 0; +} +postcore_initcall(dm646x_init_devices); -- cgit v1.2.3 From ac7b75b5bbbfd60b752869a22daa3be99b5b4f99 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Thu, 7 May 2009 06:19:40 -0700 Subject: davinci: EMAC platform support Add SoC and platform-specific data and init for DaVinci EMAC network driver. Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/dm646x.c | 57 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) (limited to 'arch/arm/mach-davinci/dm646x.c') diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index 93443a6637e..975ed062ce2 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -279,6 +279,44 @@ struct davinci_clk dm646x_clks[] = { CLK(NULL, NULL, NULL), }; +#if defined(CONFIG_TI_DAVINCI_EMAC) || defined(CONFIG_TI_DAVINCI_EMAC_MODULE) +static struct resource dm646x_emac_resources[] = { + { + .start = DM646X_EMAC_BASE, + .end = DM646X_EMAC_BASE + 0x47ff, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_DM646X_EMACRXTHINT, + .end = IRQ_DM646X_EMACRXTHINT, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_DM646X_EMACRXINT, + .end = IRQ_DM646X_EMACRXINT, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_DM646X_EMACTXINT, + .end = IRQ_DM646X_EMACTXINT, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_DM646X_EMACMISCINT, + .end = IRQ_DM646X_EMACMISCINT, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device dm646x_emac_device = { + .name = "davinci_emac", + .id = 1, + .num_resources = ARRAY_SIZE(dm646x_emac_resources), + .resource = dm646x_emac_resources, +}; + +#endif + /* * Device specific mux setup * @@ -385,6 +423,25 @@ static struct platform_device dm646x_edma_device = { /*----------------------------------------------------------------------*/ +#if defined(CONFIG_TI_DAVINCI_EMAC) || defined(CONFIG_TI_DAVINCI_EMAC_MODULE) + +void dm646x_init_emac(struct emac_platform_data *pdata) +{ + pdata->ctrl_reg_offset = DM646X_EMAC_CNTRL_OFFSET; + pdata->ctrl_mod_reg_offset = DM646X_EMAC_CNTRL_MOD_OFFSET; + pdata->ctrl_ram_offset = DM646X_EMAC_CNTRL_RAM_OFFSET; + pdata->mdio_reg_offset = DM646X_EMAC_MDIO_OFFSET; + pdata->ctrl_ram_size = DM646X_EMAC_CNTRL_RAM_SIZE; + pdata->version = EMAC_VERSION_2; + dm646x_emac_device.dev.platform_data = pdata; + platform_device_register(&dm646x_emac_device); +} +#else + +void dm646x_init_emac(struct emac_platform_data *unused) {} + +#endif + void __init dm646x_init(void) { davinci_clk_init(dm646x_clks); -- cgit v1.2.3 From 79c3c0b729647a6246c120408f36e6804dab244e Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Wed, 15 Apr 2009 12:38:58 -0700 Subject: davinci: Encapsulate SoC-specific data in a structure Create a structure to encapsulate SoC-specific information. This will assist in generalizing code so it can be used by different SoCs that have similar hardware but with minor differences such as having a different base address. The idea is that the code for each SoC fills out a structure with the correct information. The board-specific code then calls the SoC init routine which in turn will call a common init routine that makes a copy of the structure, maps in I/O regions, etc. After initialization, code can get a pointer to the structure by calling davinci_get_soc_info(). Eventually, the common init routine will make a copy of all of the data pointed to by the structure so the original data can be made __init_data. That way the data for SoC's that aren't being used won't consume memory for the entire life of the kernel. The structure will be extended in subsequent patches but initially, it holds the map_desc structure for any I/O regions the SoC/board wants statically mapped. Signed-off-by: Mark A. Greer Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/dm646x.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'arch/arm/mach-davinci/dm646x.c') diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index 975ed062ce2..8547ec02c9e 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -13,6 +13,8 @@ #include #include +#include + #include #include #include @@ -20,6 +22,7 @@ #include #include #include +#include #include "clock.h" #include "mux.h" @@ -442,8 +445,23 @@ void dm646x_init_emac(struct emac_platform_data *unused) {} #endif +static struct map_desc dm646x_io_desc[] = { + { + .virtual = IO_VIRT, + .pfn = __phys_to_pfn(IO_PHYS), + .length = IO_SIZE, + .type = MT_DEVICE + }, +}; + +static struct davinci_soc_info davinci_soc_info_dm646x = { + .io_desc = dm646x_io_desc, + .io_desc_num = ARRAY_SIZE(dm646x_io_desc), +}; + void __init dm646x_init(void) { + davinci_common_init(&davinci_soc_info_dm646x); davinci_clk_init(dm646x_clks); davinci_mux_register(dm646x_pins, ARRAY_SIZE(dm646x_pins)); } -- cgit v1.2.3 From b9ab12797e74d93a3656ea0bf5591f8b3e094fd5 Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Wed, 15 Apr 2009 12:39:09 -0700 Subject: davinci: Support JTAG ID register at any address The Davinci cpu_is_davinci_*() macros use the SoC part number and variant retrieved from the JTAG ID register to determine the type of cpu that the kernel is running on. Currently, the code to read the JTAG ID register assumes that the register is always at the same base address. This isn't true on some newer SoCs. To solve this, have the SoC-specific code set the JTAG ID register base address in soc_info structure and add a 'cpu_id' member to it. 'cpu_id' will be used by the cpu_is_davinci_*() macros to match the cpu id. Also move the info used to identify the cpu type into the SoC-specific code to keep all SoC-specific code together. The common code will read the JTAG ID register, search through an array of davinci_id structures to identify the cpu type. Once identified, it will set the 'cpu_id' member of the soc_info structure to the proper value and the cpu_is_davinci_*() macros will now work. Signed-off-by: Mark A. Greer Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/dm646x.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'arch/arm/mach-davinci/dm646x.c') diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index 8547ec02c9e..cd86bb78e0c 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -454,9 +454,23 @@ static struct map_desc dm646x_io_desc[] = { }, }; +/* Contents of JTAG ID register used to identify exact cpu type */ +static struct davinci_id dm646x_ids[] = { + { + .variant = 0x0, + .part_no = 0xb770, + .manufacturer = 0x017, + .cpu_id = DAVINCI_CPU_ID_DM6467, + .name = "dm6467", + }, +}; + static struct davinci_soc_info davinci_soc_info_dm646x = { .io_desc = dm646x_io_desc, .io_desc_num = ARRAY_SIZE(dm646x_io_desc), + .jtag_id_base = IO_ADDRESS(0x01c40028), + .ids = dm646x_ids, + .ids_num = ARRAY_SIZE(dm646x_ids), }; void __init dm646x_init(void) -- cgit v1.2.3 From 66e0c3991c5a1735dd8add77ab8aff5005f57681 Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Wed, 15 Apr 2009 12:39:23 -0700 Subject: davinci: Add clock init call to common init routine All of the davinci SoCs need to call davinci_clk_init() so put the call in the common init routine. Signed-off-by: Mark A. Greer Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/dm646x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/arm/mach-davinci/dm646x.c') diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index cd86bb78e0c..7cf9705be9c 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -471,12 +471,12 @@ static struct davinci_soc_info davinci_soc_info_dm646x = { .jtag_id_base = IO_ADDRESS(0x01c40028), .ids = dm646x_ids, .ids_num = ARRAY_SIZE(dm646x_ids), + .cpu_clks = dm646x_clks, }; void __init dm646x_init(void) { davinci_common_init(&davinci_soc_info_dm646x); - davinci_clk_init(dm646x_clks); davinci_mux_register(dm646x_pins, ARRAY_SIZE(dm646x_pins)); } -- cgit v1.2.3 From d81d188cafecbc9e01df51527ac4c84a5b19e033 Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Wed, 15 Apr 2009 12:39:33 -0700 Subject: davinci: Add support for multiple PSCs The current code to support the DaVinci Power and Sleep Controller (PSC) assumes that there is only one controller. This assumption is no longer valid so expand the support to allow greater than one PSC. To accomplish this, put the base addresses for the PSCs in the SoC infrastructure so it can be referenced by the PSC code. This also requires adding an extra parameter to davinci_psc_config() to specify the PSC that is to be enabled/disabled. Signed-off-by: Mark A. Greer Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/dm646x.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch/arm/mach-davinci/dm646x.c') diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index 7cf9705be9c..3c61543c7cf 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -465,6 +465,10 @@ static struct davinci_id dm646x_ids[] = { }, }; +static void __iomem *dm646x_psc_bases[] = { + IO_ADDRESS(DAVINCI_PWR_SLEEP_CNTRL_BASE), +}; + static struct davinci_soc_info davinci_soc_info_dm646x = { .io_desc = dm646x_io_desc, .io_desc_num = ARRAY_SIZE(dm646x_io_desc), @@ -472,6 +476,8 @@ static struct davinci_soc_info davinci_soc_info_dm646x = { .ids = dm646x_ids, .ids_num = ARRAY_SIZE(dm646x_ids), .cpu_clks = dm646x_clks, + .psc_bases = dm646x_psc_bases, + .psc_bases_num = ARRAY_SIZE(dm646x_psc_bases), }; void __init dm646x_init(void) -- cgit v1.2.3 From 0e585952ac6a06b3c77d6b8eadb9c359766a700d Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Wed, 15 Apr 2009 12:39:48 -0700 Subject: davinci: Move pinmux setup info to SoC infrastructure The pinmux register base and setup can be different for different SoCs so move the pinmux reg base, pinmux table (and its size) to the SoC infrastructure. Signed-off-by: Mark A. Greer Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/dm646x.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'arch/arm/mach-davinci/dm646x.c') diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index 3c61543c7cf..299d8d9d26e 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -327,6 +327,7 @@ static struct platform_device dm646x_emac_device = { * reg offset mask mode */ static const struct mux_config dm646x_pins[] = { +#ifdef CONFIG_DAVINCI_MUX MUX_CFG(DM646X, ATAEN, 0, 0, 1, 1, true) MUX_CFG(DM646X, AUDCK1, 0, 29, 1, 0, false) @@ -354,6 +355,7 @@ MUX_CFG(DM646X, PTSIMUX_PARALLEL, 0, 16, 3, 2, true) MUX_CFG(DM646X, PTSOMUX_SERIAL, 0, 18, 3, 3, true) MUX_CFG(DM646X, PTSIMUX_SERIAL, 0, 16, 3, 3, true) +#endif }; /*----------------------------------------------------------------------*/ @@ -478,12 +480,14 @@ static struct davinci_soc_info davinci_soc_info_dm646x = { .cpu_clks = dm646x_clks, .psc_bases = dm646x_psc_bases, .psc_bases_num = ARRAY_SIZE(dm646x_psc_bases), + .pinmux_base = IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE), + .pinmux_pins = dm646x_pins, + .pinmux_pins_num = ARRAY_SIZE(dm646x_pins), }; void __init dm646x_init(void) { davinci_common_init(&davinci_soc_info_dm646x); - davinci_mux_register(dm646x_pins, ARRAY_SIZE(dm646x_pins)); } static int __init dm646x_init_devices(void) -- cgit v1.2.3 From 673dd36f0d0cf8893d6b46d524ad80e81076b885 Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Wed, 15 Apr 2009 12:40:00 -0700 Subject: davinci: Move interrupt ctlr info to SoC infrastructure Use the SoC infrastructure to hold the interrupt controller information (i.e., base address, default priorities, interrupt controller type, and the number of IRQs). The interrupt controller base, although initially put in the soc_info structure's intc_base field, is eventually put in the global 'davinci_intc_base' so the low-level interrupt code can access it without a dereference. These changes enable the SoC default irq priorities to be put in the SoC-specific files, and the interrupt controller to be at any base address. Signed-off-by: Mark A. Greer Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/dm646x.c | 71 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) (limited to 'arch/arm/mach-davinci/dm646x.c') diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index 299d8d9d26e..beb522e8a1a 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -358,6 +358,73 @@ MUX_CFG(DM646X, PTSIMUX_SERIAL, 0, 16, 3, 3, true) #endif }; +static u8 dm646x_default_priorities[DAVINCI_N_AINTC_IRQ] = { + [IRQ_DM646X_VP_VERTINT0] = 7, + [IRQ_DM646X_VP_VERTINT1] = 7, + [IRQ_DM646X_VP_VERTINT2] = 7, + [IRQ_DM646X_VP_VERTINT3] = 7, + [IRQ_DM646X_VP_ERRINT] = 7, + [IRQ_DM646X_RESERVED_1] = 7, + [IRQ_DM646X_RESERVED_2] = 7, + [IRQ_DM646X_WDINT] = 7, + [IRQ_DM646X_CRGENINT0] = 7, + [IRQ_DM646X_CRGENINT1] = 7, + [IRQ_DM646X_TSIFINT0] = 7, + [IRQ_DM646X_TSIFINT1] = 7, + [IRQ_DM646X_VDCEINT] = 7, + [IRQ_DM646X_USBINT] = 7, + [IRQ_DM646X_USBDMAINT] = 7, + [IRQ_DM646X_PCIINT] = 7, + [IRQ_CCINT0] = 7, /* dma */ + [IRQ_CCERRINT] = 7, /* dma */ + [IRQ_TCERRINT0] = 7, /* dma */ + [IRQ_TCERRINT] = 7, /* dma */ + [IRQ_DM646X_TCERRINT2] = 7, + [IRQ_DM646X_TCERRINT3] = 7, + [IRQ_DM646X_IDE] = 7, + [IRQ_DM646X_HPIINT] = 7, + [IRQ_DM646X_EMACRXTHINT] = 7, + [IRQ_DM646X_EMACRXINT] = 7, + [IRQ_DM646X_EMACTXINT] = 7, + [IRQ_DM646X_EMACMISCINT] = 7, + [IRQ_DM646X_MCASP0TXINT] = 7, + [IRQ_DM646X_MCASP0RXINT] = 7, + [IRQ_AEMIFINT] = 7, + [IRQ_DM646X_RESERVED_3] = 7, + [IRQ_DM646X_MCASP1TXINT] = 7, /* clockevent */ + [IRQ_TINT0_TINT34] = 7, /* clocksource */ + [IRQ_TINT1_TINT12] = 7, /* DSP timer */ + [IRQ_TINT1_TINT34] = 7, /* system tick */ + [IRQ_PWMINT0] = 7, + [IRQ_PWMINT1] = 7, + [IRQ_DM646X_VLQINT] = 7, + [IRQ_I2C] = 7, + [IRQ_UARTINT0] = 7, + [IRQ_UARTINT1] = 7, + [IRQ_DM646X_UARTINT2] = 7, + [IRQ_DM646X_SPINT0] = 7, + [IRQ_DM646X_SPINT1] = 7, + [IRQ_DM646X_DSP2ARMINT] = 7, + [IRQ_DM646X_RESERVED_4] = 7, + [IRQ_DM646X_PSCINT] = 7, + [IRQ_DM646X_GPIO0] = 7, + [IRQ_DM646X_GPIO1] = 7, + [IRQ_DM646X_GPIO2] = 7, + [IRQ_DM646X_GPIO3] = 7, + [IRQ_DM646X_GPIO4] = 7, + [IRQ_DM646X_GPIO5] = 7, + [IRQ_DM646X_GPIO6] = 7, + [IRQ_DM646X_GPIO7] = 7, + [IRQ_DM646X_GPIOBNK0] = 7, + [IRQ_DM646X_GPIOBNK1] = 7, + [IRQ_DM646X_GPIOBNK2] = 7, + [IRQ_DM646X_DDRINT] = 7, + [IRQ_DM646X_AEMIFINT] = 7, + [IRQ_COMMTX] = 7, + [IRQ_COMMRX] = 7, + [IRQ_EMUINT] = 7, +}; + /*----------------------------------------------------------------------*/ static const s8 dma_chan_dm646x_no_event[] = { @@ -483,6 +550,10 @@ static struct davinci_soc_info davinci_soc_info_dm646x = { .pinmux_base = IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE), .pinmux_pins = dm646x_pins, .pinmux_pins_num = ARRAY_SIZE(dm646x_pins), + .intc_base = IO_ADDRESS(DAVINCI_ARM_INTC_BASE), + .intc_type = DAVINCI_INTC_TYPE_AINTC, + .intc_irq_prios = dm646x_default_priorities, + .intc_irq_num = DAVINCI_N_AINTC_IRQ, }; void __init dm646x_init(void) -- cgit v1.2.3 From f64691b3ab795268072e76ddb89290b6277cdf33 Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Wed, 15 Apr 2009 12:40:11 -0700 Subject: davinci: Add base address and timer flexibility The davinci timer code currently hardcodes the timer register base addresses, the timer irq numbers, and the timers to use for clock events and clocksource. This won't work for some a new SoC so put those values into the soc_info structure and set them up in the SoC-specific files. Signed-off-by: Mark A. Greer Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/dm646x.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'arch/arm/mach-davinci/dm646x.c') diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index beb522e8a1a..219063f4d00 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include "clock.h" @@ -538,6 +539,18 @@ static void __iomem *dm646x_psc_bases[] = { IO_ADDRESS(DAVINCI_PWR_SLEEP_CNTRL_BASE), }; +/* + * T0_BOT: Timer 0, bottom: clockevent source for hrtimers + * T0_TOP: Timer 0, top : clocksource for generic timekeeping + * T1_BOT: Timer 1, bottom: (used by DSP in TI DSPLink code) + * T1_TOP: Timer 1, top : + */ +struct davinci_timer_info dm646x_timer_info = { + .timers = davinci_timer_instance, + .clockevent_id = T0_BOT, + .clocksource_id = T0_TOP, +}; + static struct davinci_soc_info davinci_soc_info_dm646x = { .io_desc = dm646x_io_desc, .io_desc_num = ARRAY_SIZE(dm646x_io_desc), @@ -554,6 +567,7 @@ static struct davinci_soc_info davinci_soc_info_dm646x = { .intc_type = DAVINCI_INTC_TYPE_AINTC, .intc_irq_prios = dm646x_default_priorities, .intc_irq_num = DAVINCI_N_AINTC_IRQ, + .timer_info = &dm646x_timer_info, }; void __init dm646x_init(void) -- cgit v1.2.3 From 951d6f6d703110790256abfce03ced117d2dcc6b Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Wed, 15 Apr 2009 12:40:21 -0700 Subject: davinci: Add watchdog base address flexibility The watchdog code currently hardcodes the base address of the timer its using. To support new SoCs, make it support timers at any address. Use the soc_info structure to do this. Signed-off-by: Mark A. Greer Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/dm646x.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/arm/mach-davinci/dm646x.c') diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index 219063f4d00..83d67cf6935 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -568,6 +568,7 @@ static struct davinci_soc_info davinci_soc_info_dm646x = { .intc_irq_prios = dm646x_default_priorities, .intc_irq_num = DAVINCI_N_AINTC_IRQ, .timer_info = &dm646x_timer_info, + .wdt_base = IO_ADDRESS(DAVINCI_WDOG_BASE), }; void __init dm646x_init(void) -- cgit v1.2.3 From a994955cc091a8a51b7d7412174d9cf6de04d26b Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Wed, 15 Apr 2009 12:40:35 -0700 Subject: davinci: Make GPIO code more generic The current gpio code needs to know the number of gpio irqs there are and what the bank irq number is. To determine those values, it checks the SoC type. It also assumes that the base address and the number of irqs the interrupt controller uses is fixed. To clean up the SoC checks and make it support different base addresses and interrupt controllers, have the SoC-specific code set those values in the soc_info structure and have the gpio code reference them there. Signed-off-by: Mark A. Greer Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/dm646x.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch/arm/mach-davinci/dm646x.c') diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index 83d67cf6935..f980c2f95de 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -12,6 +12,7 @@ #include #include #include +#include #include @@ -569,6 +570,9 @@ static struct davinci_soc_info davinci_soc_info_dm646x = { .intc_irq_num = DAVINCI_N_AINTC_IRQ, .timer_info = &dm646x_timer_info, .wdt_base = IO_ADDRESS(DAVINCI_WDOG_BASE), + .gpio_base = IO_ADDRESS(DAVINCI_GPIO_BASE), + .gpio_num = 43, /* Only 33 usable */ + .gpio_irq = IRQ_DM646X_GPIOBNK0, }; void __init dm646x_init(void) -- cgit v1.2.3 From 65e866a9741126c678e6dcd5d4fa8c9eca18e945 Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Wed, 18 Mar 2009 12:36:08 -0500 Subject: davinci: Move serial platform_device into SoC-specific files Currently, there is one set of platform_device and platform_data structures for all DaVinci SoCs. The differences in the data between the various SoCs is handled by davinci_serial_init() by checking the SoC type. However, as new SoCs appear, this routine will become more & more cluttered. To clean up the routine and make it easier to add support for new SoCs, move the platform_device and platform_data structures into the SoC-specific code and use the SoC infrastructure to provide access to the data. In the process, fix a bug where the wrong irq is used for uart2 of the dm646x. Signed-off-by: Mark A. Greer Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/dm646x.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'arch/arm/mach-davinci/dm646x.c') diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index f980c2f95de..544658e5885 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -24,6 +25,7 @@ #include #include #include +#include #include #include "clock.h" @@ -552,6 +554,44 @@ struct davinci_timer_info dm646x_timer_info = { .clocksource_id = T0_TOP, }; +static struct plat_serial8250_port dm646x_serial_platform_data[] = { + { + .mapbase = DAVINCI_UART0_BASE, + .irq = IRQ_UARTINT0, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | + UPF_IOREMAP, + .iotype = UPIO_MEM32, + .regshift = 2, + }, + { + .mapbase = DAVINCI_UART1_BASE, + .irq = IRQ_UARTINT1, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | + UPF_IOREMAP, + .iotype = UPIO_MEM32, + .regshift = 2, + }, + { + .mapbase = DAVINCI_UART2_BASE, + .irq = IRQ_DM646X_UARTINT2, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | + UPF_IOREMAP, + .iotype = UPIO_MEM32, + .regshift = 2, + }, + { + .flags = 0 + }, +}; + +static struct platform_device dm646x_serial_device = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM, + .dev = { + .platform_data = dm646x_serial_platform_data, + }, +}; + static struct davinci_soc_info davinci_soc_info_dm646x = { .io_desc = dm646x_io_desc, .io_desc_num = ARRAY_SIZE(dm646x_io_desc), @@ -573,6 +613,7 @@ static struct davinci_soc_info davinci_soc_info_dm646x = { .gpio_base = IO_ADDRESS(DAVINCI_GPIO_BASE), .gpio_num = 43, /* Only 33 usable */ .gpio_irq = IRQ_DM646X_GPIOBNK0, + .serial_dev = &dm646x_serial_device, }; void __init dm646x_init(void) -- cgit v1.2.3 From 972412b648dcf0c4303dca7e515d5c24ce3cd1d5 Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Wed, 15 Apr 2009 12:40:56 -0700 Subject: davinci: Move emac platform_data to SoC-specific files Since most of the emac platform_data is really SoC specific and not board specific, move it to the SoC-specific files. Put a pointer to the platform_data in the soc_info structure so the board-specific code can set some of the platform_data if it needs to. Signed-off-by: Mark A. Greer Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/dm646x.c | 36 ++++++++++++++---------------------- 1 file changed, 14 insertions(+), 22 deletions(-) (limited to 'arch/arm/mach-davinci/dm646x.c') diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index 544658e5885..5185ad55fc5 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -286,7 +286,15 @@ struct davinci_clk dm646x_clks[] = { CLK(NULL, NULL, NULL), }; -#if defined(CONFIG_TI_DAVINCI_EMAC) || defined(CONFIG_TI_DAVINCI_EMAC_MODULE) +static struct emac_platform_data dm646x_emac_pdata = { + .ctrl_reg_offset = DM646X_EMAC_CNTRL_OFFSET, + .ctrl_mod_reg_offset = DM646X_EMAC_CNTRL_MOD_OFFSET, + .ctrl_ram_offset = DM646X_EMAC_CNTRL_RAM_OFFSET, + .mdio_reg_offset = DM646X_EMAC_MDIO_OFFSET, + .ctrl_ram_size = DM646X_EMAC_CNTRL_RAM_SIZE, + .version = EMAC_VERSION_2, +}; + static struct resource dm646x_emac_resources[] = { { .start = DM646X_EMAC_BASE, @@ -318,12 +326,13 @@ static struct resource dm646x_emac_resources[] = { static struct platform_device dm646x_emac_device = { .name = "davinci_emac", .id = 1, + .dev = { + .platform_data = &dm646x_emac_pdata, + }, .num_resources = ARRAY_SIZE(dm646x_emac_resources), .resource = dm646x_emac_resources, }; -#endif - /* * Device specific mux setup * @@ -499,25 +508,6 @@ static struct platform_device dm646x_edma_device = { /*----------------------------------------------------------------------*/ -#if defined(CONFIG_TI_DAVINCI_EMAC) || defined(CONFIG_TI_DAVINCI_EMAC_MODULE) - -void dm646x_init_emac(struct emac_platform_data *pdata) -{ - pdata->ctrl_reg_offset = DM646X_EMAC_CNTRL_OFFSET; - pdata->ctrl_mod_reg_offset = DM646X_EMAC_CNTRL_MOD_OFFSET; - pdata->ctrl_ram_offset = DM646X_EMAC_CNTRL_RAM_OFFSET; - pdata->mdio_reg_offset = DM646X_EMAC_MDIO_OFFSET; - pdata->ctrl_ram_size = DM646X_EMAC_CNTRL_RAM_SIZE; - pdata->version = EMAC_VERSION_2; - dm646x_emac_device.dev.platform_data = pdata; - platform_device_register(&dm646x_emac_device); -} -#else - -void dm646x_init_emac(struct emac_platform_data *unused) {} - -#endif - static struct map_desc dm646x_io_desc[] = { { .virtual = IO_VIRT, @@ -614,6 +604,7 @@ static struct davinci_soc_info davinci_soc_info_dm646x = { .gpio_num = 43, /* Only 33 usable */ .gpio_irq = IRQ_DM646X_GPIOBNK0, .serial_dev = &dm646x_serial_device, + .emac_pdata = &dm646x_emac_pdata, }; void __init dm646x_init(void) @@ -627,6 +618,7 @@ static int __init dm646x_init_devices(void) return 0; platform_device_register(&dm646x_edma_device); + platform_device_register(&dm646x_emac_device); return 0; } postcore_initcall(dm646x_init_devices); -- cgit v1.2.3 From 5570078c0ec5ecc5df0bbd7d06f43549b7127ae7 Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Wed, 15 Apr 2009 12:42:06 -0700 Subject: davinci: Move PINMUX defines to SoC files Different SoC have different numbers of pinmux registers and other resources that overlap with each other. To clean up the code and eliminate defines that overlap with each other, move the PINMUX defines to the SoC specific files. Signed-off-by: Mark A. Greer Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/dm646x.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch/arm/mach-davinci/dm646x.c') diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index 5185ad55fc5..12189c737a3 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -333,6 +333,9 @@ static struct platform_device dm646x_emac_device = { .resource = dm646x_emac_resources, }; +#define PINMUX0 0x00 +#define PINMUX1 0x04 + /* * Device specific mux setup * -- cgit v1.2.3 From 0d04eb47054f685b23033ed6ceadfb20db77c5b3 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Thu, 30 Apr 2009 17:35:48 -0700 Subject: davinci: soc-specific SRAM setup Package on-chip SRAM. It's always accessible from the ARM, so set up a standardized virtual address mapping into a 128 KiB area that's reserved for platform use. In some cases (dm6467) the physical addresses used for EDMA are not the same as the ones used by the ARM ... so record that info separately in the SOC data, for chips (unlike the OMAP-L137) where SRAM may be used with EDMA. Other blocks of SRAM, such as the ETB buffer or DSP L1/L2 RAM, may be unused/available on some system. They are ignored here. Signed-off-by: David Brownell Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/dm646x.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'arch/arm/mach-davinci/dm646x.c') diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index 12189c737a3..334f0711e0f 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -518,6 +518,13 @@ static struct map_desc dm646x_io_desc[] = { .length = IO_SIZE, .type = MT_DEVICE }, + { + .virtual = SRAM_VIRT, + .pfn = __phys_to_pfn(0x00010000), + .length = SZ_32K, + /* MT_MEMORY_NONCACHED requires supersection alignment */ + .type = MT_DEVICE, + }, }; /* Contents of JTAG ID register used to identify exact cpu type */ @@ -608,6 +615,8 @@ static struct davinci_soc_info davinci_soc_info_dm646x = { .gpio_irq = IRQ_DM646X_GPIOBNK0, .serial_dev = &dm646x_serial_device, .emac_pdata = &dm646x_emac_pdata, + .sram_dma = 0x10010000, + .sram_len = SZ_32K, }; void __init dm646x_init(void) -- cgit v1.2.3