From 80881dae52d05d3d6c920624157d68006390f01e Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Mon, 26 Mar 2012 12:49:57 -0600 Subject: ARM: tegra: uncompress.h: Implement TEGRA_DEBUG_UART_AUTO_ODMDATA Tegra has 5 UARTS which could be used for low-level debug output. Commit fe26398 "ARM: tegra: uncompress.h: Choose a UART at runtime" implemented one method for the kernel to automatically determine which of these to use at run-time, so that the same DEBUG_LL-enabled kernel image could be used across multiple Tegra boards. The required bootloader-side setup for that option is implemented in NVIDIA's various downstream U-Boot branches, but the U-Boot maintainers have refused to accept it upstream. This change implements an alternative automatic UART selection option using ODMDATA. This is a 32-bit value programmed into Tegra's boot memory which provides a few pieces of basic board-specific information, including a field that indicates the console UART. Setting up this value is part of the standard Tegra boot architecture, and so requires no Tegra-specific hacks in the bootloader's UART driver. Note that in theory, the format of ODMDATA is board-specific. However, in practice all boards use the same location/size/values for the UART field. ODMDATA[19:18] (which drive the type of debug console) is more problematic, since some boards use value 2 for UART and others use 3. This patch just accepts either value; if this doesn't work well for a given board, I'd suggest simply not enabling this debug option when building for that board. Note that the kernel assumes the bootloader has already set up any required pinmux settings for the UART; there is no way the kernel can do this for itself prior to knowing which board it's running on. In practice, people using this feature are highly likely to be using bootloaders that have indeed configured the pinmux. This assumption existed prior to this patch. Signed-off-by: Stephen Warren --- arch/arm/mach-tegra/Kconfig | 29 ++++- arch/arm/mach-tegra/include/mach/uncompress.h | 176 ++++++++++++++++++-------- 2 files changed, 153 insertions(+), 52 deletions(-) (limited to 'arch/arm/mach-tegra') diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index d0f2546706ca..204d3d4d7388 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig @@ -111,7 +111,7 @@ config MACH_VENTANA Support for the nVidia Ventana development platform choice - prompt "Low-level debug console UART" + prompt "Default low-level debug console UART" default TEGRA_DEBUG_UART_NONE config TEGRA_DEBUG_UART_NONE @@ -134,6 +134,33 @@ config TEGRA_DEBUG_UARTE endchoice +choice + prompt "Automatic low-level debug console UART" + default TEGRA_DEBUG_UART_AUTO_NONE + +config TEGRA_DEBUG_UART_AUTO_NONE + bool "None" + +config TEGRA_DEBUG_UART_AUTO_ODMDATA + bool "Via ODMDATA" + help + Automatically determines which UART to use for low-level debug based + on the ODMDATA value. This value is part of the BCT, and is written + to the boot memory device using nvflash, or other flashing tool. + When bits 19:18 are 3, then bits 17:15 indicate which UART to use; + 0/1/2/3/4 are UART A/B/C/D/E. + +config TEGRA_DEBUG_UART_AUTO_SCRATCH + bool "Via UART scratch register" + help + Automatically determines which UART to use for low-level debug based + on the UART scratch register value. Some bootloaders put ASCII 'D' + in this register when they initialize their own console UART output. + Using this option allows the kernel to automatically pick the same + UART. + +endchoice + config TEGRA_SYSTEM_DMA bool "Enable system DMA driver for NVIDIA Tegra SoCs" default y diff --git a/arch/arm/mach-tegra/include/mach/uncompress.h b/arch/arm/mach-tegra/include/mach/uncompress.h index 5a440f315e57..937c4c50219e 100644 --- a/arch/arm/mach-tegra/include/mach/uncompress.h +++ b/arch/arm/mach-tegra/include/mach/uncompress.h @@ -63,52 +63,86 @@ static inline void save_uart_address(void) buf[0] = 0; } -/* - * Setup before decompression. This is where we do UART selection for - * earlyprintk and init the uart_base register. - */ -static inline void arch_decomp_setup(void) +static const struct { + u32 base; + u32 reset_reg; + u32 clock_reg; + u32 bit; +} uarts[] = { + { + TEGRA_UARTA_BASE, + TEGRA_CLK_RESET_BASE + 0x04, + TEGRA_CLK_RESET_BASE + 0x10, + 6, + }, + { + TEGRA_UARTB_BASE, + TEGRA_CLK_RESET_BASE + 0x04, + TEGRA_CLK_RESET_BASE + 0x10, + 7, + }, + { + TEGRA_UARTC_BASE, + TEGRA_CLK_RESET_BASE + 0x08, + TEGRA_CLK_RESET_BASE + 0x14, + 23, + }, + { + TEGRA_UARTD_BASE, + TEGRA_CLK_RESET_BASE + 0x0c, + TEGRA_CLK_RESET_BASE + 0x18, + 1, + }, + { + TEGRA_UARTE_BASE, + TEGRA_CLK_RESET_BASE + 0x0c, + TEGRA_CLK_RESET_BASE + 0x18, + 2, + }, +}; + +static inline bool uart_clocked(int i) +{ + if (*(u8 *)uarts[i].reset_reg & BIT(uarts[i].bit)) + return false; + + if (!(*(u8 *)uarts[i].clock_reg & BIT(uarts[i].bit))) + return false; + + return true; +} + +#ifdef CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA +int auto_odmdata(void) +{ + volatile u32 *pmc = (volatile u32 *)TEGRA_PMC_BASE; + u32 odmdata = pmc[0xa0 / 4]; + + /* + * Bits 19:18 are the console type: 0=default, 1=none, 2==DCC, 3==UART + * Some boards apparently swap the last two values, but we don't have + * any way of catering for that here, so we just accept either. If this + * doesn't make sense for your board, just don't enable this feature. + * + * Bits 17:15 indicate the UART to use, 0/1/2/3/4 are UART A/B/C/D/E. + */ + + switch ((odmdata >> 18) & 3) { + case 2: + case 3: + break; + default: + return -1; + } + + return (odmdata >> 15) & 7; +} +#endif + +#ifdef CONFIG_TEGRA_DEBUG_UART_AUTO_SCRATCH +int auto_scratch(void) { - static const struct { - u32 base; - u32 reset_reg; - u32 clock_reg; - u32 bit; - } uarts[] = { - { - TEGRA_UARTA_BASE, - TEGRA_CLK_RESET_BASE + 0x04, - TEGRA_CLK_RESET_BASE + 0x10, - 6, - }, - { - TEGRA_UARTB_BASE, - TEGRA_CLK_RESET_BASE + 0x04, - TEGRA_CLK_RESET_BASE + 0x10, - 7, - }, - { - TEGRA_UARTC_BASE, - TEGRA_CLK_RESET_BASE + 0x08, - TEGRA_CLK_RESET_BASE + 0x14, - 23, - }, - { - TEGRA_UARTD_BASE, - TEGRA_CLK_RESET_BASE + 0x0c, - TEGRA_CLK_RESET_BASE + 0x18, - 1, - }, - { - TEGRA_UARTE_BASE, - TEGRA_CLK_RESET_BASE + 0x0c, - TEGRA_CLK_RESET_BASE + 0x18, - 2, - }, - }; int i; - volatile u32 *apb_misc = (volatile u32 *)TEGRA_APB_MISC_BASE; - u32 chip, div; /* * Look for the first UART that: @@ -125,20 +159,60 @@ static inline void arch_decomp_setup(void) * back to what's specified in TEGRA_DEBUG_UART_BASE. */ for (i = 0; i < ARRAY_SIZE(uarts); i++) { - if (*(u8 *)uarts[i].reset_reg & BIT(uarts[i].bit)) - continue; - - if (!(*(u8 *)uarts[i].clock_reg & BIT(uarts[i].bit))) + if (!uart_clocked(i)) continue; uart = (volatile u8 *)uarts[i].base; if (uart[UART_SCR << DEBUG_UART_SHIFT] != 'D') continue; - break; + return i; } - if (i == ARRAY_SIZE(uarts)) - uart = (volatile u8 *)TEGRA_DEBUG_UART_BASE; + + return -1; +} +#endif + +/* + * Setup before decompression. This is where we do UART selection for + * earlyprintk and init the uart_base register. + */ +static inline void arch_decomp_setup(void) +{ + int uart_id, auto_uart_id; + volatile u32 *apb_misc = (volatile u32 *)TEGRA_APB_MISC_BASE; + u32 chip, div; + +#if defined(CONFIG_TEGRA_DEBUG_UARTA) + uart_id = 0; +#elif defined(CONFIG_TEGRA_DEBUG_UARTB) + uart_id = 1; +#elif defined(CONFIG_TEGRA_DEBUG_UARTC) + uart_id = 2; +#elif defined(CONFIG_TEGRA_DEBUG_UARTD) + uart_id = 3; +#elif defined(CONFIG_TEGRA_DEBUG_UARTE) + uart_id = 4; +#else + uart_id = -1; +#endif + +#if defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA) + auto_uart_id = auto_odmdata(); +#elif defined(CONFIG_TEGRA_DEBUG_UART_AUTO_SCRATCH) + auto_uart_id = auto_scratch(); +#else + auto_uart_id = -1; +#endif + if (auto_uart_id != -1) + uart_id = auto_uart_id; + + if (uart_id < 0 || uart_id >= ARRAY_SIZE(uarts) || + !uart_clocked(uart_id)) + uart = NULL; + else + uart = (volatile u8 *)uarts[uart_id].base; + save_uart_address(); if (uart == NULL) return; -- cgit v1.2.1 From 8703612b0abb33e6daacc0f6b709a006ac85b285 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Fri, 30 Mar 2012 15:50:44 -0600 Subject: ARM: tegra: provide clock aliases for AHUB configlink The Tegra30 AHUB driver must call tegra_periph_reset_deassert() for all devices on the AHUB's configlink bus. The AHUB driver must be able to call clk_get_sys() to retrieve the clock parameter for this function. Add the necessary clock aliases to allow this. Signed-off-by: Stephen Warren Acked-by: Olof Johansson --- arch/arm/mach-tegra/tegra30_clocks.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'arch/arm/mach-tegra') diff --git a/arch/arm/mach-tegra/tegra30_clocks.c b/arch/arm/mach-tegra/tegra30_clocks.c index 6d08b53f92d2..e33fe4b14a2a 100644 --- a/arch/arm/mach-tegra/tegra30_clocks.c +++ b/arch/arm/mach-tegra/tegra30_clocks.c @@ -3015,6 +3015,15 @@ struct clk_duplicate tegra_clk_duplicates[] = { CLK_DUPLICATE("sbc6", "spi_slave_tegra.5", NULL), CLK_DUPLICATE("twd", "smp_twd", NULL), CLK_DUPLICATE("vcp", "nvavp", "vcp"), + CLK_DUPLICATE("i2s0", NULL, "i2s0"), + CLK_DUPLICATE("i2s1", NULL, "i2s1"), + CLK_DUPLICATE("i2s2", NULL, "i2s2"), + CLK_DUPLICATE("i2s3", NULL, "i2s3"), + CLK_DUPLICATE("i2s4", NULL, "i2s4"), + CLK_DUPLICATE("dam0", NULL, "dam0"), + CLK_DUPLICATE("dam1", NULL, "dam1"), + CLK_DUPLICATE("dam2", NULL, "dam2"), + CLK_DUPLICATE("spdif_in", NULL, "spdif_in"), }; struct clk *tegra_ptr_clks[] = { -- cgit v1.2.1 From 6437626928467e81aa4a3087d88cd3f443b3e9ec Mon Sep 17 00:00:00 2001 From: Peter De Schrijver Date: Mon, 23 Apr 2012 01:31:49 -0700 Subject: ARM: tegra: Initialize pll_p_out1 pll_a uses pll_p_out1 as its parent. Therefore this clock needs to be initialized to make sure pll_a has a known input clock. Failure to do so will cause the system to crash early in the bootup. Signed-off-by: Peter De Schrijver Signed-off-by: Stephen Warren --- arch/arm/mach-tegra/common.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'arch/arm/mach-tegra') diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c index 22df10fb9972..1f762333937e 100644 --- a/arch/arm/mach-tegra/common.c +++ b/arch/arm/mach-tegra/common.c @@ -93,6 +93,17 @@ static __initdata struct tegra_clk_init_table tegra20_clk_init_table[] = { }; #endif +#ifdef CONFIG_ARCH_TEGRA_3x_SOC +static __initdata struct tegra_clk_init_table tegra30_clk_init_table[] = { + /* name parent rate enabled */ + { "clk_m", NULL, 0, true }, + { "pll_p", "clk_m", 408000000, true }, + { "pll_p_out1", "pll_p", 9600000, true }, + { NULL, NULL, 0, 0}, +}; +#endif + + static void __init tegra_init_cache(u32 tag_latency, u32 data_latency) { #ifdef CONFIG_CACHE_L2X0 @@ -127,6 +138,7 @@ void __init tegra30_init_early(void) { tegra_init_fuse(); tegra30_init_clocks(); + tegra_clk_init_from_table(tegra30_clk_init_table); tegra_init_cache(0x441, 0x551); tegra_pmc_init(); tegra_powergate_init(); -- cgit v1.2.1 From 18b81fb733356025a6ad48b85092a0456e348ff0 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Mon, 26 Mar 2012 16:49:39 -0600 Subject: ARM: tegra: set up audio clocks for tegra30 dt Set up the audio clock tree for Tegra30 in an equivalent fashion to the existing setup for Tegra20. Signed-off-by: Stephen Warren Acked-by: Olof Johansson --- arch/arm/mach-tegra/board-dt-tegra30.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'arch/arm/mach-tegra') diff --git a/arch/arm/mach-tegra/board-dt-tegra30.c b/arch/arm/mach-tegra/board-dt-tegra30.c index 5f7c03e972f3..3de21c0b5461 100644 --- a/arch/arm/mach-tegra/board-dt-tegra30.c +++ b/arch/arm/mach-tegra/board-dt-tegra30.c @@ -57,6 +57,15 @@ struct of_dev_auxdata tegra30_auxdata_lookup[] __initdata = { static __initdata struct tegra_clk_init_table tegra_dt_clk_init_table[] = { /* name parent rate enabled */ { "uarta", "pll_p", 408000000, true }, + { "pll_a", "pll_p_out1", 564480000, true }, + { "pll_a_out0", "pll_a", 11289600, true }, + { "extern1", "pll_a_out0", 0, true }, + { "clk_out_1", "extern1", 0, true }, + { "i2s0", "pll_a_out0", 11289600, false}, + { "i2s1", "pll_a_out0", 11289600, false}, + { "i2s2", "pll_a_out0", 11289600, false}, + { "i2s3", "pll_a_out0", 11289600, false}, + { "i2s4", "pll_a_out0", 11289600, false}, { NULL, NULL, 0, 0}, }; -- cgit v1.2.1 From 5657d98deadb5e245bf5608cfb06e86898032125 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Tue, 27 Mar 2012 11:37:47 -0600 Subject: ARM: tegra: add AUXDATA required for audio Both the Tegra30 I2S and AHUB modules used clocks, and hence currently require AUXDATA in order to get specific device names so that clock lookups work. Signed-off-by: Stephen Warren Acked-by: Olof Johansson --- arch/arm/mach-tegra/board-dt-tegra30.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/arm/mach-tegra') diff --git a/arch/arm/mach-tegra/board-dt-tegra30.c b/arch/arm/mach-tegra/board-dt-tegra30.c index 3de21c0b5461..d96dae0b4aa7 100644 --- a/arch/arm/mach-tegra/board-dt-tegra30.c +++ b/arch/arm/mach-tegra/board-dt-tegra30.c @@ -51,6 +51,7 @@ struct of_dev_auxdata tegra30_auxdata_lookup[] __initdata = { OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000C500, "tegra-i2c.2", NULL), OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000C700, "tegra-i2c.3", NULL), OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000D000, "tegra-i2c.4", NULL), + OF_DEV_AUXDATA("nvidia,tegra30-ahub", 0x70080000, "tegra30-ahub", NULL), {} }; -- cgit v1.2.1 From c8b62ab41f76218efca5e4baa5c22ef52a9fe3a5 Mon Sep 17 00:00:00 2001 From: Allen Martin Date: Fri, 10 Sep 2010 09:17:33 -0500 Subject: ARM: tegra: Add pllc clock init table pll_c will be used as a clock source. Fill in tegra_pll_c_freq_table[] so that it's possible to explicitly initialize the PLL. NVIDIA's downstream nv-3.1 kernel and the ChromeOS kernel have different pll_c tables. nv-3.1 contains entries for 522MHz and 598MHz output, whereas the ChromeOS kernel contains entries for 600MHz output. I chose to upstream the ChromeOS values for now, since the 600MHz rate appears to match the default rate of this PLL when the HW boots, and it's not clear to me why 522 or 598MHz are more useful. Signed-off-by: Allen Martin Signed-off-by: Olof Johansson Signed-off-by: Stephen Warren [swarren: wrote commit description] --- arch/arm/mach-tegra/tegra2_clocks.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch/arm/mach-tegra') diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c index 592a4eeb5328..a357ad2a8cf7 100644 --- a/arch/arm/mach-tegra/tegra2_clocks.c +++ b/arch/arm/mach-tegra/tegra2_clocks.c @@ -1486,6 +1486,10 @@ static struct clk tegra_clk_m = { }; static struct clk_pll_freq_table tegra_pll_c_freq_table[] = { + { 12000000, 600000000, 600, 12, 1, 8 }, + { 13000000, 600000000, 600, 13, 1, 8 }, + { 19200000, 600000000, 500, 16, 1, 6 }, + { 26000000, 600000000, 600, 26, 1, 8 }, { 0, 0, 0, 0, 0, 0 }, }; -- cgit v1.2.1 From 60f975b98cf41476ba0e156f7523b197b046cf2b Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Thu, 12 Apr 2012 14:09:39 -0600 Subject: ARM: tegra: reparent sclk to pll_c_out1 pll_p_out4 needs to be used for other purposes. Reparent sclk so that it runs from pll_c. Change sclk's rate to 120MHz from 108MHz since this is the lowest precise rate that can be achieved by dividing the pll_c rate without reducing the sclk rate. (600/5=120, 600/5.5=109.0909..., 600/6=100). Signed-off-by: Stephen Warren --- arch/arm/mach-tegra/common.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'arch/arm/mach-tegra') diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c index 22df10fb9972..e96900418682 100644 --- a/arch/arm/mach-tegra/common.c +++ b/arch/arm/mach-tegra/common.c @@ -83,8 +83,10 @@ static __initdata struct tegra_clk_init_table tegra20_clk_init_table[] = { { "pll_p_out2", "pll_p", 48000000, true }, { "pll_p_out3", "pll_p", 72000000, true }, { "pll_p_out4", "pll_p", 108000000, true }, - { "sclk", "pll_p_out4", 108000000, true }, - { "hclk", "sclk", 108000000, true }, + { "pll_c", "clk_m", 600000000, true }, + { "pll_c_out1", "pll_c", 120000000, true }, + { "sclk", "pll_c_out1", 120000000, true }, + { "hclk", "sclk", 120000000, true }, { "pclk", "hclk", 54000000, true }, { "csite", NULL, 0, true }, { "emc", NULL, 0, true }, -- cgit v1.2.1 From 7ff4db0967bd7d617c77dc5a66c0d95166277817 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Fri, 20 Apr 2012 16:58:18 -0600 Subject: ARM: tegra: fix pclk rate Commit 40f9cf0 "ARM: tegra: reparent sclk to pll_c_out1" changed the rate of hclk. Since pclk is derived from that, and only has integer dividers, the pclk rate needs to change in the same fashion, from 54MHz to 60MHz. Signed-off-by: Stephen Warren --- arch/arm/mach-tegra/common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/arm/mach-tegra') diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c index e96900418682..a4fba8835136 100644 --- a/arch/arm/mach-tegra/common.c +++ b/arch/arm/mach-tegra/common.c @@ -87,7 +87,7 @@ static __initdata struct tegra_clk_init_table tegra20_clk_init_table[] = { { "pll_c_out1", "pll_c", 120000000, true }, { "sclk", "pll_c_out1", 120000000, true }, { "hclk", "sclk", 120000000, true }, - { "pclk", "hclk", 54000000, true }, + { "pclk", "hclk", 60000000, true }, { "csite", NULL, 0, true }, { "emc", NULL, 0, true }, { "cpu", NULL, 0, true }, -- cgit v1.2.1 From 9abafa021e223f04d6589ee2b977bbaf2e1f1367 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Thu, 12 Apr 2012 14:13:05 -0600 Subject: ARM: tegra: change pll_p_out4's rate to 24MHz pll_p_out4 is used on all/most Tegra boards to drive the cdev2 output pin to provide a reference clock to a ULPI USB PHY. This reference clock must run at 24MHz, and the cdev2 output has no additional dividers. Remove board-paz00.c's now-duplicate initialization of this clock. Reported-by: Marc Dietrich Signed-off-by: Stephen Warren --- arch/arm/mach-tegra/board-paz00.c | 1 - arch/arm/mach-tegra/common.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'arch/arm/mach-tegra') diff --git a/arch/arm/mach-tegra/board-paz00.c b/arch/arm/mach-tegra/board-paz00.c index 330afdfa2475..aebfa4003813 100644 --- a/arch/arm/mach-tegra/board-paz00.c +++ b/arch/arm/mach-tegra/board-paz00.c @@ -176,7 +176,6 @@ static __initdata struct tegra_clk_init_table paz00_clk_init_table[] = { { "uarta", "pll_p", 216000000, true }, { "uartc", "pll_p", 216000000, true }, - { "pll_p_out4", "pll_p", 24000000, true }, { "usbd", "clk_m", 12000000, false }, { "usb2", "clk_m", 12000000, false }, { "usb3", "clk_m", 12000000, false }, diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c index a4fba8835136..f18f615aa93a 100644 --- a/arch/arm/mach-tegra/common.c +++ b/arch/arm/mach-tegra/common.c @@ -82,7 +82,7 @@ static __initdata struct tegra_clk_init_table tegra20_clk_init_table[] = { { "pll_p_out1", "pll_p", 28800000, true }, { "pll_p_out2", "pll_p", 48000000, true }, { "pll_p_out3", "pll_p", 72000000, true }, - { "pll_p_out4", "pll_p", 108000000, true }, + { "pll_p_out4", "pll_p", 24000000, true }, { "pll_c", "clk_m", 600000000, true }, { "pll_c_out1", "pll_c", 120000000, true }, { "sclk", "pll_c_out1", 120000000, true }, -- cgit v1.2.1 From 60d148b9f838b718e4808061ee6d5833de77fd9c Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Thu, 12 Apr 2012 15:03:52 -0600 Subject: ARM: tegra: don't hard-code USB ULPI PHY reset_gpio Not all boards use GPIO_PV0 as the ULPI PHY reset signal. Instead of hard-coding this GPIO into devices.c, make the board files set it explicitly. This will allow the PHY code to differentiate between set and unset values, and hence know when to read the value from device tree. Signed-off-by: Stephen Warren --- arch/arm/mach-tegra/board-paz00.c | 2 ++ arch/arm/mach-tegra/board-trimslice.c | 2 ++ arch/arm/mach-tegra/devices.c | 5 ++--- arch/arm/mach-tegra/devices.h | 4 ++++ 4 files changed, 10 insertions(+), 3 deletions(-) (limited to 'arch/arm/mach-tegra') diff --git a/arch/arm/mach-tegra/board-paz00.c b/arch/arm/mach-tegra/board-paz00.c index aebfa4003813..e31317deec21 100644 --- a/arch/arm/mach-tegra/board-paz00.c +++ b/arch/arm/mach-tegra/board-paz00.c @@ -159,6 +159,8 @@ static void paz00_i2c_init(void) static void paz00_usb_init(void) { + tegra_ehci2_ulpi_phy_config.reset_gpio = TEGRA_ULPI_RST; + platform_device_register(&tegra_ehci2_device); platform_device_register(&tegra_ehci3_device); } diff --git a/arch/arm/mach-tegra/board-trimslice.c b/arch/arm/mach-tegra/board-trimslice.c index f6f5b6a11325..24f1678098dd 100644 --- a/arch/arm/mach-tegra/board-trimslice.c +++ b/arch/arm/mach-tegra/board-trimslice.c @@ -117,6 +117,8 @@ static void trimslice_usb_init(void) pdata = tegra_ehci1_device.dev.platform_data; pdata->vbus_gpio = TRIMSLICE_GPIO_USB1_MODE; + tegra_ehci2_ulpi_phy_config.reset_gpio = TEGRA_GPIO_PV0; + platform_device_register(&tegra_ehci3_device); platform_device_register(&tegra_ehci2_device); platform_device_register(&tegra_ehci1_device); diff --git a/arch/arm/mach-tegra/devices.c b/arch/arm/mach-tegra/devices.c index bd3035e0cea1..9fcb9a522276 100644 --- a/arch/arm/mach-tegra/devices.c +++ b/arch/arm/mach-tegra/devices.c @@ -439,9 +439,8 @@ static struct resource tegra_usb3_resources[] = { }, }; -static struct tegra_ulpi_config tegra_ehci2_ulpi_phy_config = { - /* All existing boards use GPIO PV0 for phy reset */ - .reset_gpio = TEGRA_GPIO_PV0, +struct tegra_ulpi_config tegra_ehci2_ulpi_phy_config = { + .reset_gpio = -1, .clk = "cdev2", }; diff --git a/arch/arm/mach-tegra/devices.h b/arch/arm/mach-tegra/devices.h index ec455679b219..4290ea0063ac 100644 --- a/arch/arm/mach-tegra/devices.h +++ b/arch/arm/mach-tegra/devices.h @@ -22,6 +22,10 @@ #include #include +#include + +extern struct tegra_ulpi_config tegra_ehci2_ulpi_phy_config; + extern struct tegra_ehci_platform_data tegra_ehci1_pdata; extern struct tegra_ehci_platform_data tegra_ehci2_pdata; extern struct tegra_ehci_platform_data tegra_ehci3_pdata; -- cgit v1.2.1 From aa607ebf93a5fc26275a575781399df971dd1b91 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Thu, 12 Apr 2012 15:46:49 -0600 Subject: ARM: tegra: add USB ULPI PHY reset GPIO to device tree ULPI PHYs have a reset signal, and different boards use a different GPIO for this task. Add a property to device tree to represent this. I'm not sure if adding this property to the EHCI controller node is entirely correct; perhaps eventually we should have explicit separate nodes for the various PHYs. However, we don't have that right now, so this binding seems like a reasonable choice. Cc: Cc: Greg Kroah-Hartman Cc: Signed-off-by: Stephen Warren --- arch/arm/mach-tegra/include/mach/usb_phy.h | 4 ++-- arch/arm/mach-tegra/usb_phy.c | 15 +++++++++++++-- 2 files changed, 15 insertions(+), 4 deletions(-) (limited to 'arch/arm/mach-tegra') diff --git a/arch/arm/mach-tegra/include/mach/usb_phy.h b/arch/arm/mach-tegra/include/mach/usb_phy.h index de1a0f602b28..935ce9f65590 100644 --- a/arch/arm/mach-tegra/include/mach/usb_phy.h +++ b/arch/arm/mach-tegra/include/mach/usb_phy.h @@ -61,8 +61,8 @@ struct tegra_usb_phy { struct usb_phy *ulpi; }; -struct tegra_usb_phy *tegra_usb_phy_open(int instance, void __iomem *regs, - void *config, enum tegra_usb_phy_mode phy_mode); +struct tegra_usb_phy *tegra_usb_phy_open(struct device *dev, int instance, + void __iomem *regs, void *config, enum tegra_usb_phy_mode phy_mode); int tegra_usb_phy_power_on(struct tegra_usb_phy *phy); diff --git a/arch/arm/mach-tegra/usb_phy.c b/arch/arm/mach-tegra/usb_phy.c index d71d2fed6721..54e353c8e304 100644 --- a/arch/arm/mach-tegra/usb_phy.c +++ b/arch/arm/mach-tegra/usb_phy.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -654,8 +655,8 @@ static void ulpi_phy_power_off(struct tegra_usb_phy *phy) clk_disable(phy->clk); } -struct tegra_usb_phy *tegra_usb_phy_open(int instance, void __iomem *regs, - void *config, enum tegra_usb_phy_mode phy_mode) +struct tegra_usb_phy *tegra_usb_phy_open(struct device *dev, int instance, + void __iomem *regs, void *config, enum tegra_usb_phy_mode phy_mode) { struct tegra_usb_phy *phy; struct tegra_ulpi_config *ulpi_config; @@ -711,6 +712,16 @@ struct tegra_usb_phy *tegra_usb_phy_open(int instance, void __iomem *regs, err = -ENXIO; goto err1; } + if (!gpio_is_valid(ulpi_config->reset_gpio)) + ulpi_config->reset_gpio = + of_get_named_gpio(dev->of_node, + "nvidia,phy-reset-gpio", 0); + if (!gpio_is_valid(ulpi_config->reset_gpio)) { + pr_err("%s: invalid reset gpio: %d\n", __func__, + ulpi_config->reset_gpio); + err = -EINVAL; + goto err1; + } gpio_request(ulpi_config->reset_gpio, "ulpi_phy_reset_b"); gpio_direction_output(ulpi_config->reset_gpio, 0); phy->ulpi = otg_ulpi_create(&ulpi_viewport_access_ops, 0); -- cgit v1.2.1 From 87d0bab2cba3c31624b80cc68bcf5e29ef969458 Mon Sep 17 00:00:00 2001 From: Hiroshi DOYU Date: Mon, 7 May 2012 12:24:48 +0200 Subject: ARM: tegra: Add Tegra AHB driver Tegra AHB Bus conforms to the AMBA Specification (Rev 2.0) Advanced High-performance Bus (AHB) architecture. The AHB Arbiter controls AHB bus master arbitration. This effectively forms a second level of arbitration for access to the memory controller through the AHB Slave Memory device. The AHB pre-fetch logic can be configured to enhance performance for devices doing sequential access. Each AHB master is assigned to either the high or low priority bin. Both Tegra20/30 have this AHB bus. Some of configuration params could be passed from DT too if needed. Signed-off-by: Hiroshi DOYU Acked-by: Arnd Bergmann Cc: Felipe Balbi Signed-off-by: Stephen Warren --- arch/arm/mach-tegra/Kconfig | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'arch/arm/mach-tegra') diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index d0f2546706ca..8bf27b54288e 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig @@ -50,6 +50,14 @@ config TEGRA_PCI depends on ARCH_TEGRA_2x_SOC select PCI +config TEGRA_AHB + bool "Enable AHB driver for NVIDIA Tegra SoCs" + default y + help + Adds AHB configuration functionality for NVIDIA Tegra SoCs, + which controls AHB bus master arbitration and some + perfomance parameters(priority, prefech size). + comment "Tegra board type" config MACH_HARMONY -- cgit v1.2.1 From 89c788bab1f0374ae05aef7560066442ceb55384 Mon Sep 17 00:00:00 2001 From: Hiroshi DOYU Date: Mon, 7 May 2012 09:43:46 +0300 Subject: ARM: tegra: Add SMMU enabler in AHB Add extern func, "tegra_ahb_enable_smmu()" to inform AHB that SMMU is ready. Signed-off-by: Hiroshi DOYU Cc: Felipe Balbi Signed-off-by: Stephen Warren --- arch/arm/mach-tegra/include/mach/tegra-ahb.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 arch/arm/mach-tegra/include/mach/tegra-ahb.h (limited to 'arch/arm/mach-tegra') diff --git a/arch/arm/mach-tegra/include/mach/tegra-ahb.h b/arch/arm/mach-tegra/include/mach/tegra-ahb.h new file mode 100644 index 000000000000..e0f8c84b1d8c --- /dev/null +++ b/arch/arm/mach-tegra/include/mach/tegra-ahb.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + */ + +#ifndef __MACH_TEGRA_AHB_H__ +#define __MACH_TEGRA_AHB_H__ + +extern int tegra_ahb_enable_smmu(struct device_node *ahb); + +#endif /* __MACH_TEGRA_AHB_H__ */ -- cgit v1.2.1