summaryrefslogtreecommitdiff
path: root/drivers/marvell/mochi/cp110_setup.c
diff options
context:
space:
mode:
authorIgal Liberman <igall@marvell.com>2017-05-10 16:22:17 +0300
committerKostya Porotchkin <kostap@marvell.com>2017-05-11 11:05:54 +0300
commitf82b49eea6be0a3169c58cce0a1cf1041583d948 (patch)
tree887259dc7d3f16a2fa7e9afda517866632fd0bc3 /drivers/marvell/mochi/cp110_setup.c
parent816e294f4ad2144c010b6c495f86d06293c83849 (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.c46
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