diff options
author | Igal Liberman <igall@marvell.com> | 2017-05-10 16:22:17 +0300 |
---|---|---|
committer | Kostya Porotchkin <kostap@marvell.com> | 2017-05-11 11:05:54 +0300 |
commit | f82b49eea6be0a3169c58cce0a1cf1041583d948 (patch) | |
tree | 887259dc7d3f16a2fa7e9afda517866632fd0bc3 | |
parent | 816e294f4ad2144c010b6c495f86d06293c83849 (diff) |
fix: pcie: cp110: fix pcie clock selection
There's a difference between PCIe clock configuration.
in CP110 revision A1 and CP110 revision A2
CP110 revision A1:
The SatR that decides if the PCIE uses internal refclock or external
refclock does not work properly.
When the clock is set to input we need to do extra configuration
in order to make the input clock functional.
(Iboth PCIe clocks must be aligned, so if one set to input, we must
Performe the configuration).
CP110 revision A2:
PCIe Reference Clock Buffer Control register must be set according to
the clock direction (input/output), there's a field for each refclock
(pcie0 and pcie1) which are set accordingly to the clock configuration.
Change-Id: I6b0150293bfd2d7595d19016c1fd82c4d4ed326a
Signed-off-by: Igal Liberman <igall@marvell.com>
Reviewed-on: http://vgitil04.il.marvell.com:8080/39297
Tested-by: iSoC Platform CI <ykjenk@marvell.com>
Reviewed-by: Kostya Porotchkin <kostap@marvell.com>
-rw-r--r-- | drivers/marvell/mochi/cp110_setup.c | 46 | ||||
-rw-r--r-- | plat/marvell/a8k/common/include/a8k_plat_def.h | 19 |
2 files changed, 65 insertions, 0 deletions
diff --git a/drivers/marvell/mochi/cp110_setup.c b/drivers/marvell/mochi/cp110_setup.c index ad76bf1f..dc6f0ed7 100644 --- a/drivers/marvell/mochi/cp110_setup.c +++ b/drivers/marvell/mochi/cp110_setup.c @@ -281,6 +281,49 @@ void cp110_errata_wa_init(int cp_index) mmio_write_32(MVEBU_SOC_CFG_REG(cp_index, MVEBU_SOC_CFG_REG_NUM), data); } +void cp110_pcie_clk_cfg(int cp_index) +{ + uint32_t pcie0_clk, pcie1_clk, reg; + + /* + * Determine the pcie0/1 clock direction (input/output) from the + * sample at reset. + */ + reg = mmio_read_32(MVEBU_SAMPLE_AT_RESET_REG(cp_index)); + pcie0_clk = (reg & SAR_PCIE0_CLK_CFG_MASK) >> SAR_PCIE0_CLK_CFG_OFFSET; + pcie1_clk = (reg & SAR_PCIE1_CLK_CFG_MASK) >> SAR_PCIE1_CLK_CFG_OFFSET; + + /* CP110 revision A2 */ + if (cp110_rev_id_get() == MVEBU_CP110_REF_ID_A2) { + /* + * PCIe Reference Clock Buffer Control register must be + * set according to the clock direction (input/output) + */ + reg = mmio_read_32(MVEBU_PCIE_REF_CLK_BUF_CTRL(cp_index)); + reg &= ~(PCIE0_REFCLK_BUFF_SOURCE | PCIE0_REFCLK_BUFF_SOURCE); + if (pcie0_clk) + reg |= PCIE0_REFCLK_BUFF_SOURCE; + if (pcie1_clk) + reg |= PCIE1_REFCLK_BUFF_SOURCE; + + mmio_write_32(MVEBU_PCIE_REF_CLK_BUF_CTRL(cp_index), reg); + } + + /* CP110 revision A1 */ + if (cp110_rev_id_get() == MVEBU_CP110_REF_ID_A1) { + if (!pcie0_clk || !pcie1_clk) { + /* + * if one of the pcie clocks is set to input, + * we need to set mss_push[131] field, otherwise, + * the pcie clock might not work. + */ + reg = mmio_read_32(MVEBU_CP_MSS_DPSHSR_REG(cp_index)); + reg |= MSS_DPSHSR_REG_PCIE_CLK_SEL; + mmio_write_32(MVEBU_CP_MSS_DPSHSR_REG(cp_index), reg); + } + } +} + /* Set a unique stream id for all DMA capable devices */ void cp110_stream_id_init(uintptr_t cp110_base) { @@ -439,6 +482,9 @@ void cp110_init(int cp_index) /* Execute SW WA for erratas */ cp110_errata_wa_init(cp_index); + /* Confiure pcie clock according to clock direction */ + cp110_pcie_clk_cfg(cp_index); + /* configure icu for CP0 */ /* ICU - Interrupt Consolidation unit * CP0: interrupt 0..63 mapped to ID 64..127 in AP diff --git a/plat/marvell/a8k/common/include/a8k_plat_def.h b/plat/marvell/a8k/common/include/a8k_plat_def.h index de218444..3ff5bd28 100644 --- a/plat/marvell/a8k/common/include/a8k_plat_def.h +++ b/plat/marvell/a8k/common/include/a8k_plat_def.h @@ -82,6 +82,12 @@ /******************************************************************************* * MVEBU memory map related constants ******************************************************************************/ +#define MVEBU_SAMPLE_AT_RESET_REG(x) (MVEBU_CP_REGS_BASE(x) + 0x440600) +#define SAR_PCIE1_CLK_CFG_OFFSET 31 +#define SAR_PCIE1_CLK_CFG_MASK (0x1 << SAR_PCIE1_CLK_CFG_OFFSET) +#define SAR_PCIE0_CLK_CFG_OFFSET 30 +#define SAR_PCIE0_CLK_CFG_MASK (0x1 << SAR_PCIE0_CLK_CFG_OFFSET) + /* Aggregate of all devices in the first GB */ #define DEVICE0_BASE MVEBU_REGS_BASE @@ -130,6 +136,19 @@ #define DOMAIN_OUTER_SHAREABLE 0x2 #define DOMAIN_SYSTEM_SHAREABLE 0x3 +/******************************************************************************* + * MSS Device Push Set Register + ******************************************************************************/ +#define MVEBU_CP_MSS_DPSHSR_REG(x) (MVEBU_CP_REGS_BASE(x) + 0x280040) +#define MSS_DPSHSR_REG_PCIE_CLK_SEL 0x8 + +/******************************************************************************* + * PCIE clock buffer control + ******************************************************************************/ +#define MVEBU_PCIE_REF_CLK_BUF_CTRL(x) (MVEBU_CP_REGS_BASE(x) + 0x4404F0) +#define PCIE1_REFCLK_BUFF_SOURCE 0x800 +#define PCIE0_REFCLK_BUFF_SOURCE 0x400 + /************************************************************************* * Required platform porting definitions common to all * Mangement Compute SubSystems (MSS) |