summaryrefslogtreecommitdiff
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
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>
-rw-r--r--drivers/marvell/mochi/cp110_setup.c46
-rw-r--r--plat/marvell/a8k/common/include/a8k_plat_def.h19
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)