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 /drivers/marvell/mochi/cp110_setup.c | |
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>
Diffstat (limited to 'drivers/marvell/mochi/cp110_setup.c')
-rw-r--r-- | drivers/marvell/mochi/cp110_setup.c | 46 |
1 files changed, 46 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 |