PCI: mobiveil: Clear the control fields before updating it
authorHou Zhiqiang <Zhiqiang.Hou@nxp.com>
Fri, 5 Jul 2019 09:56:49 +0000 (17:56 +0800)
committerLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Mon, 8 Jul 2019 11:39:09 +0000 (12:39 +0100)
While programming the inbound and outbound windows in

program_{ib/ob}_windows()

we shoud clear the control fields in the registers before programming
it with a new value to prevent stale bits from older configuration.

Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Reviewed-by: Minghuan Lian <Minghuan.Lian@nxp.com>
Reviewed-by: Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>
drivers/pci/controller/pcie-mobiveil.c

index 0560344dc58816ded88d5bb6941c56a7a99c064a..7d18e5976fc16d1704f5e4b59f372d9122c5a8c1 100644 (file)
@@ -65,6 +65,8 @@
 #define PAB_AXI_AMAP_CTRL(win)         PAB_REG_ADDR(0x0ba0, win)
 #define  WIN_ENABLE_SHIFT              0
 #define  WIN_TYPE_SHIFT                        1
+#define  WIN_TYPE_MASK                 0x3
+#define  WIN_SIZE_MASK                 0xfffffc00
 
 #define PAB_EXT_AXI_AMAP_SIZE(win)     PAB_EXT_REG_ADDR(0xbaf0, win)
 
@@ -82,6 +84,7 @@
 #define PAB_PEX_AMAP_CTRL(win)         PAB_REG_ADDR(0x4ba0, win)
 #define  AMAP_CTRL_EN_SHIFT            0
 #define  AMAP_CTRL_TYPE_SHIFT          1
+#define  AMAP_CTRL_TYPE_MASK           3
 
 #define PAB_EXT_PEX_AMAP_SIZEN(win)    PAB_EXT_REG_ADDR(0xbef0, win)
 #define PAB_PEX_AMAP_AXI_WIN(win)      PAB_REG_ADDR(0x4ba4, win)
@@ -469,9 +472,9 @@ static void program_ib_windows(struct mobiveil_pcie *pcie, int win_num,
        csr_writel(pcie, value, PAB_PEX_PIO_CTRL);
 
        value = csr_readl(pcie, PAB_PEX_AMAP_CTRL(win_num));
-       value |= (type << AMAP_CTRL_TYPE_SHIFT) |
-                       (1 << AMAP_CTRL_EN_SHIFT) |
-                       lower_32_bits(size64);
+       value &= ~(AMAP_CTRL_TYPE_MASK << AMAP_CTRL_TYPE_SHIFT | WIN_SIZE_MASK);
+       value |= type << AMAP_CTRL_TYPE_SHIFT | 1 << AMAP_CTRL_EN_SHIFT |
+                lower_32_bits(size64);
        csr_writel(pcie, value, PAB_PEX_AMAP_CTRL(win_num));
 
        csr_writel(pcie, upper_32_bits(size64),
@@ -490,6 +493,7 @@ static void program_ib_windows(struct mobiveil_pcie *pcie, int win_num,
 static void program_ob_windows(struct mobiveil_pcie *pcie, int win_num,
                               u64 cpu_addr, u64 pci_addr, u32 type, u64 size)
 {
+       u32 value;
        u64 size64 = ~(size - 1);
 
        if (win_num >= pcie->apio_wins) {
@@ -502,8 +506,11 @@ static void program_ob_windows(struct mobiveil_pcie *pcie, int win_num,
         * program Enable Bit to 1, Type Bit to (00) base 2, AXI Window Size Bit
         * to 4 KB in PAB_AXI_AMAP_CTRL register
         */
-       csr_writel(pcie, 1 << WIN_ENABLE_SHIFT | type << WIN_TYPE_SHIFT |
-                  lower_32_bits(size64), PAB_AXI_AMAP_CTRL(win_num));
+       value = csr_readl(pcie, PAB_AXI_AMAP_CTRL(win_num));
+       value &= ~(WIN_TYPE_MASK << WIN_TYPE_SHIFT | WIN_SIZE_MASK);
+       value |= 1 << WIN_ENABLE_SHIFT | type << WIN_TYPE_SHIFT |
+                lower_32_bits(size64);
+       csr_writel(pcie, value, PAB_AXI_AMAP_CTRL(win_num));
 
        csr_writel(pcie, upper_32_bits(size64), PAB_EXT_AXI_AMAP_SIZE(win_num));