Tegra20 External Memory Controller driver
Subsystems (5)
v6 cover Tegra20 External Memory Controller driver
Changelog:
v6:
- Driver now handles "refresh request overflow" interrupt by reporting error message.
- EMC rate is set during driver initialization to ensure that clock divider is in a proper state.
v5:
- Fixed wrong EMC clock divider type in the "Turn EMC clock gate into divider" patch. It is a Tegra's fractional 7.1 divider and not a simple integer divider. Peter, please take a look at the change.
v4:
- Fixed "bad of_node_put()" error which was revealed by enabling some extra kernel debug config options.
- The "emc-table" DT nodes are now parsed starting from the "emc" node instead of the DT root.
- Adjusted code comment in the "Turn EMC clock gate into divider" patch as was suggested by Stephen Boyd to the v3.
v3:
- Handle "nvidia,use-ram-code" DT property, its handling was missed in the previous versions.
- Honor "emc-tables" DT node naming which is explicitly specified in the DT binding, also was missed in the previous versions.
- Two new DT binding patches: one adds the EMC clock property, other relocates the binding doc file to the appropriate directory. One new patch that adds EMC clock property to the DTS file.
- Addressed v2 review comments from Thierry Reding. Driver does not preserve backwards compatibility with older device tree binding.
- The PLL_M and PLL_P clocks are kept internal to the driver because after some more considering I couldn't find a really good reason why these clocks should be in the device tree.
- Some minor cleanups and fixes in the drivers code.
v2:
- Minor code cleanups like consistent use of writel_relaxed instead of non-relaxed version, reworded error messages, etc.
- Factored out use_pllm_ud bit checking into a standalone patch for consistency.
Dmitry Osipenko (8):
dt: bindings: tegra20-emc: Document interrupt property
dt: bindings: tegra20-emc: Document clock property
dt: bindings: Move tegra20-emc binding to memory-controllers directory
ARM: dts: tegra20: Add interrupt entry to External Memory Controller
ARM: dts: tegra20: Add clock entry to External Memory Controller
clk: tegra20: Turn EMC clock gate into divider
clk: tegra20: Check whether direct PLLM sourcing is turned off for EMC
memory: tegra: Introduce Tegra20 EMC driver
.../nvidia,tegra20-emc.txt | 4 +
arch/arm/boot/dts/tegra20.dtsi | 2 +
drivers/clk/tegra/clk-tegra20.c | 46 +-
drivers/memory/tegra/Kconfig | 10 +
drivers/memory/tegra/Makefile | 1 +
drivers/memory/tegra/tegra20-emc.c | 591 ++++++++++++++++++
6 files changed, 644 insertions(+), 10 deletions(-)
rename Documentation/devicetree/bindings/{arm/tegra => memory-controllers}/nvidia,tegra20-emc.txt (95%)
create mode 100644 drivers/memory/tegra/tegra20-emc.cSignature · 1 line
2.19.0
PATCH v6 1/8 dt: bindings: tegra20-emc: Document interrupt property
EMC has a dedicated interrupt that is used to notify about completion of HW operations. Document the interrupt property.
--- .../devicetree/bindings/arm/tegra/nvidia,tegra20-emc.txt | 2 ++ 1 file changed, 2 insertions(+)
Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-emc.txt +2 -0
@@ -10,6 +10,7 @@ Properties: and chosen using the ramcode board selector. If omitted, only one set of tables can be present and said tables will be used irrespective of ram-code configuration. +- interrupts : Should contain EMC General interrupt. Child device nodes describe the memory settings for different configurations and clock rates.
@@ -20,6 +21,7 @@ Example: #size-cells = < 0 >; compatible = "nvidia,tegra20-emc"; reg = <0x7000f4000 0x200>; + interrupts = <0 78 0x04>; }
Signature · 1 line
2.19.0
Thierry Reding
AppliedRe: [PATCH v6 1/8] dt: bindings: tegra20-emc: Document interrupt property
Quoted 9 lines · Dmitry Osipenko
EMC has a dedicated interrupt that is used to notify about completion of HW operations. Document the interrupt property.
Signed-off-by Dmitry Osipenko <[email protected]>Acked-by Rob Herring <[email protected]>--- .../devicetree/bindings/arm/tegra/nvidia,tegra20-emc.txt | 2 ++ 1 file changed, 2 insertions(+)
Applied to for-4.21/dt-bindings, thanks.
Thierry
PATCH v6 2/8 dt: bindings: tegra20-emc: Document clock property
In reply to Dmitry OsipenkoEmbedded memory controller has a corresponding clock, document the clock property.
--- .../devicetree/bindings/arm/tegra/nvidia,tegra20-emc.txt | 2 ++ 1 file changed, 2 insertions(+)
Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-emc.txt +2 -0
@@ -11,6 +11,7 @@ Properties: set of tables can be present and said tables will be used irrespective of ram-code configuration. - interrupts : Should contain EMC General interrupt. +- clocks : Should contain EMC clock. Child device nodes describe the memory settings for different configurations and clock rates.
@@ -22,6 +23,7 @@ Example: compatible = "nvidia,tegra20-emc"; reg = <0x7000f4000 0x200>; interrupts = <0 78 0x04>; + clocks = <&tegra_car TEGRA20_CLK_EMC>; }
Signature · 1 line
2.19.0
Thierry Reding
AppliedRe: [PATCH v6 2/8] dt: bindings: tegra20-emc: Document clock property
Quoted 8 lines · Dmitry Osipenko
Embedded memory controller has a corresponding clock, document the clock property.
Signed-off-by Dmitry Osipenko <[email protected]>Acked-by Rob Herring <[email protected]>--- .../devicetree/bindings/arm/tegra/nvidia,tegra20-emc.txt | 2 ++ 1 file changed, 2 insertions(+)
Applied to for-4.21/dt-bindings, thanks.
Thierry
PATCH v6 3/8 dt: bindings: Move tegra20-emc binding to memory-controllers directory
In reply to Dmitry OsipenkoMove tegra20-emc binding to the memory-controllers directory for consistency with the other Tegra memory bindings.
---
.../{arm/tegra => memory-controllers}/nvidia,tegra20-emc.txt | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename Documentation/devicetree/bindings/{arm/tegra => memory-controllers}/nvidia,tegra20-emc.txt (100%)Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt renamed from Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-emc.txt +0 -0
Signature · 1 line
2.19.0
Thierry Reding
AppliedRe: [PATCH v6 3/8] dt: bindings: Move tegra20-emc binding to memory-controllers directory
Quoted 9 lines · Dmitry Osipenko
Move tegra20-emc binding to the memory-controllers directory for consistency with the other Tegra memory bindings.
Signed-off-by Dmitry Osipenko <[email protected]>Acked-by Rob Herring <[email protected]>--- .../{arm/tegra => memory-controllers}/nvidia,tegra20-emc.txt | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Documentation/devicetree/bindings/{arm/tegra => memory-controllers}/nvidia,tegra20-emc.txt (100%)
Applied to for-4.21/dt-bindings, thanks.
Thierry
PATCH v6 4/8 ARM: dts: tegra20: Add interrupt entry to External Memory Controller
In reply to Dmitry OsipenkoAdd interrupt entry into the EMC DT node.
--- arch/arm/boot/dts/tegra20.dtsi | 1 + 1 file changed, 1 insertion(+)
arch/arm/boot/dts/tegra20.dtsi +1 -0
@@ -632,6 +632,7 @@ memory-controller@7000f400 { compatible = "nvidia,tegra20-emc"; reg = <0x7000f400 0x200>; + interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; };
Signature · 1 line
2.19.0
Thierry Reding
AppliedRe: [PATCH v6 4/8] ARM: dts: tegra20: Add interrupt entry to External Memory Controller
Quoted 7 lines · Dmitry Osipenko
Add interrupt entry into the EMC DT node.
Signed-off-by Dmitry Osipenko <[email protected]>--- arch/arm/boot/dts/tegra20.dtsi | 1 + 1 file changed, 1 insertion(+)
Applied to for-4.21/arm/dt, thanks.
Thierry
Thierry Reding
AppliedRe: [PATCH v6 4/8] ARM: dts: tegra20: Add interrupt entry to External Memory Controller
In reply to Dmitry OsipenkoQuoted 7 lines · Dmitry Osipenko
Add interrupt entry into the EMC DT node.
Signed-off-by Dmitry Osipenko <[email protected]>--- arch/arm/boot/dts/tegra20.dtsi | 1 + 1 file changed, 1 insertion(+)
Applied to for-4.21/arm/dt, thanks.
Thierry
PATCH v6 5/8 ARM: dts: tegra20: Add clock entry to External Memory Controller
In reply to Dmitry OsipenkoAdd clock entry into the EMC DT node.
--- arch/arm/boot/dts/tegra20.dtsi | 1 + 1 file changed, 1 insertion(+)
arch/arm/boot/dts/tegra20.dtsi +1 -0
@@ -633,6 +633,7 @@ compatible = "nvidia,tegra20-emc"; reg = <0x7000f400 0x200>; interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&tegra_car TEGRA20_CLK_EMC>; #address-cells = <1>; #size-cells = <0>; };
Signature · 1 line
2.19.0
Thierry Reding
AppliedRe: [PATCH v6 5/8] ARM: dts: tegra20: Add clock entry to External Memory Controller
Quoted 6 lines · Dmitry Osipenko
Add clock entry into the EMC DT node.
Signed-off-by Dmitry Osipenko <[email protected]>--- arch/arm/boot/dts/tegra20.dtsi | 1 + 1 file changed, 1 insertion(+)
Applied to for-4.21/arm/dt, thanks.
Thierry
PATCH v6 6/8 clk: tegra20: Turn EMC clock gate into divider
In reply to Dmitry OsipenkoKernel should never gate the EMC clock as it causes immediate lockup, so removing clk-gate functionality doesn't affect anything. Turning EMC clk gate into divider allows to implement glitch-less EMC scaling, avoiding reparenting to a backup clock.
--- drivers/clk/tegra/clk-tegra20.c | 36 ++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 10 deletions(-)
drivers/clk/tegra/clk-tegra20.c +26 -10
@@ -584,7 +584,6 @@ static struct tegra_clk tegra20_clks[tegra_clk_max] __initdata = { [tegra_clk_afi] = { .dt_id = TEGRA20_CLK_AFI, .present = true }, [tegra_clk_fuse] = { .dt_id = TEGRA20_CLK_FUSE, .present = true }, [tegra_clk_kfuse] = { .dt_id = TEGRA20_CLK_KFUSE, .present = true }, - [tegra_clk_emc] = { .dt_id = TEGRA20_CLK_EMC, .present = true }, };static unsigned long tegra20_clk_measure_input_freq (void )
@@ -805,6 +804,31 @@ static struct tegra_periph_init_data tegra_periph_nodiv_clk_list[] = { TEGRA_INIT_DATA_NODIV("disp2", mux_pllpdc_clkm, CLK_SOURCE_DISP2, 30, 2, 26, 0, TEGRA20_CLK_DISP2), }; +static void __init tegra20_emc_clk_init (void ) +{ +struct clk *clk; + + clk =clk_register_mux (NULL ,"emc_mux" , mux_pllmcp_clkm, +ARRAY_SIZE (mux_pllmcp_clkm), +CLK_SET_RATE_NO_REPARENT , + clk_base +CLK_SOURCE_EMC , +30 ,2 ,0 , &emc_lock); + + clk =tegra_clk_register_mc ("mc" ,"emc_mux" , clk_base +CLK_SOURCE_EMC , + &emc_lock); + clks[TEGRA20_CLK_MC ] = clk; + +/* +* Note that 'emc_mux' source and 'emc' rate shouldn't be changed at +* the same time due to a HW bug, this won't happen because we're +* defining 'emc_mux' and 'emc' as distinct clocks. +*/ + clk =tegra_clk_register_divider ("emc" ,"emc_mux" , + clk_base +CLK_SOURCE_EMC ,CLK_IS_CRITICAL , +TEGRA_DIVIDER_INT ,0 ,8 ,1 , &emc_lock); + clks[TEGRA20_CLK_EMC ] = clk; +} +static void __init tegra20_periph_clk_init (void ) {struct tegra_periph_init_data *data;
@@ -818,15 +842,7 @@ static void __init tegra20_periph_clk_init(void) clks[TEGRA20_CLK_AC97 ] = clk;/* emc */ - clk =clk_register_mux (NULL ,"emc_mux" , mux_pllmcp_clkm, -ARRAY_SIZE (mux_pllmcp_clkm), -CLK_SET_RATE_NO_REPARENT , - clk_base +CLK_SOURCE_EMC , -30 ,2 ,0 , &emc_lock); - - clk =tegra_clk_register_mc ("mc" ,"emc_mux" , clk_base +CLK_SOURCE_EMC , - &emc_lock); - clks[TEGRA20_CLK_MC ] = clk; +tegra20_emc_clk_init ();/* dsi */ clk = tegra_clk_register_periph_gate("dsi", "pll_d", 0, clk_base, 0,
Signature · 1 line
2.19.0
Thierry Reding
AppliedRe: [PATCH v6 6/8] clk: tegra20: Turn EMC clock gate into divider
Quoted 11 lines · Dmitry Osipenko
Kernel should never gate the EMC clock as it causes immediate lockup, so removing clk-gate functionality doesn't affect anything. Turning EMC clk gate into divider allows to implement glitch-less EMC scaling, avoiding reparenting to a backup clock.
Signed-off-by Dmitry Osipenko <[email protected]>Acked-by Stephen Boyd <[email protected]>--- drivers/clk/tegra/clk-tegra20.c | 36 ++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 10 deletions(-)
Applied to for-4.21/clk, thanks.
Thierry
PATCH v6 7/8 clk: tegra20: Check whether direct PLLM sourcing is turned off for EMC
In reply to Dmitry OsipenkoEnsure that direct PLLM sourcing is turned off for EMC as we don't support that configuration in the clk driver.
--- drivers/clk/tegra/clk-tegra20.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
drivers/clk/tegra/clk-tegra20.c +10 -0
@@ -806,7 +806,9 @@ static struct tegra_periph_init_data tegra_periph_nodiv_clk_list[] = {static void __init tegra20_emc_clk_init (void ) { +const u32 use_pllm_ud =BIT (29 );struct clk *clk; +u32 emc_reg; clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm, ARRAY_SIZE(mux_pllmcp_clkm),
@@ -818,6 +820,14 @@ static void __init tegra20_emc_clk_init(void) &emc_lock); clks[TEGRA20_CLK_MC ] = clk; +/* un-divided pll_m_out0 is currently unsupported */ + emc_reg =readl_relaxed (clk_base +CLK_SOURCE_EMC ); +if (emc_reg & use_pllm_ud) { +pr_err ("%s: un-divided PllM_out0 used as clock source\n" , + __func__); +return ; + } +/* * Note that 'emc_mux' source and 'emc' rate shouldn't be changed at * the same time due to a HW bug, this won't happen because we're
Signature · 1 line
2.19.0
Thierry Reding
AppliedRe: [PATCH v6 7/8] clk: tegra20: Check whether direct PLLM sourcing is turned off for EMC
Quoted 9 lines · Dmitry Osipenko
Ensure that direct PLLM sourcing is turned off for EMC as we don't support that configuration in the clk driver.
Signed-off-by Dmitry Osipenko <[email protected]>Acked-by Stephen Boyd <[email protected]>--- drivers/clk/tegra/clk-tegra20.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
Applied to for-4.21/clk, thanks.
Thierry
PATCH v6 8/8 memory: tegra: Introduce Tegra20 EMC driver
In reply to Dmitry OsipenkoIntroduce driver for the External Memory Controller (EMC) found on Tegra20 chips, which controls the external DRAM on the board. The purpose of this driver is to program memory timing for external memory on the EMC clock rate change.
--- drivers/memory/tegra/Kconfig | 10 + drivers/memory/tegra/Makefile | 1 + drivers/memory/tegra/tegra20-emc.c | 591 +++++++++++++++++++++++++++++ 3 files changed, 602 insertions(+) create mode 100644 drivers/memory/tegra/tegra20-emc.c
drivers/memory/tegra/Kconfig +10 -0
@@ -6,6 +6,16 @@ config TEGRA_MC This driver supports the Memory Controller (MC) hardware found on NVIDIA Tegra SoCs. +config TEGRA20_EMC + bool "NVIDIA Tegra20 External Memory Controller driver" + default y + depends on ARCH_TEGRA_2x_SOC + help + This driver is for the External Memory Controller (EMC) found on + Tegra20 chips. The EMC controls the external DRAM on the board. + This driver is required to change memory timings / clock rate for + external memory. + config TEGRA124_EMC bool "NVIDIA Tegra124 External Memory Controller driver" default y
drivers/memory/tegra/Makefile +1 -0
@@ -10,5 +10,6 @@ tegra-mc-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210.o obj-$(CONFIG_TEGRA_MC) += tegra-mc.o +obj-$(CONFIG_TEGRA20_EMC) += tegra20-emc.o obj-$(CONFIG_TEGRA124_EMC) += tegra124-emc.o obj-$(CONFIG_ARCH_TEGRA_186_SOC) += tegra186.o
drivers/memory/tegra/tegra20-emc.c new file +591 -0
591 lines not on this page · raw message
Signature · 1 line
2.19.0
Thierry Reding
AppliedRe: [PATCH v6 8/8] memory: tegra: Introduce Tegra20 EMC driver
Quoted 5 lines · Dmitry Osipenko
Introduce driver for the External Memory Controller (EMC) found on Tegra20 chips, which controls the external DRAM on the board. The purpose of this driver is to program memory timing for external memory on the EMC clock rate change.
Quoted 8 lines
Signed-off-by Dmitry Osipenko <[email protected]>--- drivers/memory/tegra/Kconfig | 10 + drivers/memory/tegra/Makefile | 1 + drivers/memory/tegra/tegra20-emc.c | 591 +++++++++++++++++++++++++++++ 3 files changed, 602 insertions(+) create mode 100644 drivers/memory/tegra/tegra20-emc.c
Applied to for-4.21/memory, thanks.
Though I did notice that there's quite a bit of code that's very similar between this and the existing Tegra124 driver, so I wonder if we can do a pass over them and refactor some of it as a follow-up.
Thierry
Re: [PATCH v6 8/8] memory: tegra: Introduce Tegra20 EMC driver
Quoted 15 lines · Thierry Reding
Quoted 5 lines · Dmitry Osipenko
Introduce driver for the External Memory Controller (EMC) found on Tegra20 chips, which controls the external DRAM on the board. The purpose of this driver is to program memory timing for external memory on the EMC clock rate change.
Quoted 8 lines
Signed-off-by Dmitry Osipenko <[email protected]>--- drivers/memory/tegra/Kconfig | 10 + drivers/memory/tegra/Makefile | 1 + drivers/memory/tegra/tegra20-emc.c | 591 +++++++++++++++++++++++++++++ 3 files changed, 602 insertions(+) create mode 100644 drivers/memory/tegra/tegra20-emc.c
Quoted 1 line
Applied to for-4.21/memory, thanks.
Thank you!
Quoted 3 lines
Though I did notice that there's quite a bit of code that's very similar between this and the existing Tegra124 driver, so I wonder if we can do a pass over them and refactor some of it as a follow-up.
I don't think this will really worth the effort.