1 /* 2 * Broadcom specific AMBA 3 * PCIe Gen 2 Core 4 * 5 * Copyright 2014, Broadcom Corporation 6 * Copyright 2014, Rafał Miłecki <zajec5@gmail.com> 7 * 8 * Licensed under the GNU/GPL. See COPYING for details. 9 */ 10 11 #include "bcma_private.h" 12 #include <linux/bcma/bcma.h> 13 14 /************************************************** 15 * R/W ops. 16 **************************************************/ 17 18 #if 0 19 static u32 bcma_core_pcie2_cfg_read(struct bcma_drv_pcie2 *pcie2, u32 addr) 20 { 21 pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, addr); 22 pcie2_read32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR); 23 return pcie2_read32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA); 24 } 25 #endif 26 27 static void bcma_core_pcie2_cfg_write(struct bcma_drv_pcie2 *pcie2, u32 addr, 28 u32 val) 29 { 30 pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, addr); 31 pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, val); 32 } 33 34 /************************************************** 35 * Init. 36 **************************************************/ 37 38 static u32 bcma_core_pcie2_war_delay_perst_enab(struct bcma_drv_pcie2 *pcie2, 39 bool enable) 40 { 41 u32 val; 42 43 /* restore back to default */ 44 val = pcie2_read32(pcie2, BCMA_CORE_PCIE2_CLK_CONTROL); 45 val |= PCIE2_CLKC_DLYPERST; 46 val &= ~PCIE2_CLKC_DISSPROMLD; 47 if (enable) { 48 val &= ~PCIE2_CLKC_DLYPERST; 49 val |= PCIE2_CLKC_DISSPROMLD; 50 } 51 pcie2_write32(pcie2, (BCMA_CORE_PCIE2_CLK_CONTROL), val); 52 /* flush */ 53 return pcie2_read32(pcie2, BCMA_CORE_PCIE2_CLK_CONTROL); 54 } 55 56 static void bcma_core_pcie2_set_ltr_vals(struct bcma_drv_pcie2 *pcie2) 57 { 58 /* LTR0 */ 59 pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, 0x844); 60 pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, 0x883c883c); 61 /* LTR1 */ 62 pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, 0x848); 63 pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, 0x88648864); 64 /* LTR2 */ 65 pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, 0x84C); 66 pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, 0x90039003); 67 } 68 69 static void bcma_core_pcie2_hw_ltr_war(struct bcma_drv_pcie2 *pcie2) 70 { 71 u8 core_rev = pcie2->core->id.rev; 72 u32 devstsctr2; 73 74 if (core_rev < 2 || core_rev == 10 || core_rev > 13) 75 return; 76 77 pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, 78 PCIE2_CAP_DEVSTSCTRL2_OFFSET); 79 devstsctr2 = pcie2_read32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA); 80 if (devstsctr2 & PCIE2_CAP_DEVSTSCTRL2_LTRENAB) { 81 /* force the right LTR values */ 82 bcma_core_pcie2_set_ltr_vals(pcie2); 83 84 /* TODO: 85 si_core_wrapperreg(pcie2, 3, 0x60, 0x8080, 0); */ 86 87 /* enable the LTR */ 88 devstsctr2 |= PCIE2_CAP_DEVSTSCTRL2_LTRENAB; 89 pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, 90 PCIE2_CAP_DEVSTSCTRL2_OFFSET); 91 pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, devstsctr2); 92 93 /* set the LTR state to be active */ 94 pcie2_write32(pcie2, BCMA_CORE_PCIE2_LTR_STATE, 95 PCIE2_LTR_ACTIVE); 96 usleep_range(1000, 2000); 97 98 /* set the LTR state to be sleep */ 99 pcie2_write32(pcie2, BCMA_CORE_PCIE2_LTR_STATE, 100 PCIE2_LTR_SLEEP); 101 usleep_range(1000, 2000); 102 } 103 } 104 105 static void pciedev_crwlpciegen2(struct bcma_drv_pcie2 *pcie2) 106 { 107 u8 core_rev = pcie2->core->id.rev; 108 bool pciewar160, pciewar162; 109 110 pciewar160 = core_rev == 7 || core_rev == 9 || core_rev == 11; 111 pciewar162 = core_rev == 5 || core_rev == 7 || core_rev == 8 || 112 core_rev == 9 || core_rev == 11; 113 114 if (!pciewar160 && !pciewar162) 115 return; 116 117 /* TODO */ 118 #if 0 119 pcie2_set32(pcie2, BCMA_CORE_PCIE2_CLK_CONTROL, 120 PCIE_DISABLE_L1CLK_GATING); 121 #if 0 122 pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, 123 PCIEGEN2_COE_PVT_TL_CTRL_0); 124 pcie2_mask32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, 125 ~(1 << COE_PVT_TL_CTRL_0_PM_DIS_L1_REENTRY_BIT)); 126 #endif 127 #endif 128 } 129 130 static void pciedev_crwlpciegen2_180(struct bcma_drv_pcie2 *pcie2) 131 { 132 pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, PCIE2_PMCR_REFUP); 133 pcie2_set32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, 0x1f); 134 } 135 136 static void pciedev_crwlpciegen2_182(struct bcma_drv_pcie2 *pcie2) 137 { 138 pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, PCIE2_SBMBX); 139 pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, 1 << 0); 140 } 141 142 static void pciedev_reg_pm_clk_period(struct bcma_drv_pcie2 *pcie2) 143 { 144 struct bcma_drv_cc *drv_cc = &pcie2->core->bus->drv_cc; 145 u8 core_rev = pcie2->core->id.rev; 146 u32 alp_khz, pm_value; 147 148 if (core_rev <= 13) { 149 alp_khz = bcma_pmu_get_alp_clock(drv_cc) / 1000; 150 pm_value = (1000000 * 2) / alp_khz; 151 pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, 152 PCIE2_PVT_REG_PM_CLK_PERIOD); 153 pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, pm_value); 154 } 155 } 156 157 void bcma_core_pcie2_init(struct bcma_drv_pcie2 *pcie2) 158 { 159 struct bcma_chipinfo *ci = &pcie2->core->bus->chipinfo; 160 u32 tmp; 161 162 tmp = pcie2_read32(pcie2, BCMA_CORE_PCIE2_SPROM(54)); 163 if ((tmp & 0xe) >> 1 == 2) 164 bcma_core_pcie2_cfg_write(pcie2, 0x4e0, 0x17); 165 166 /* TODO: Do we need pcie_reqsize? */ 167 168 if (ci->id == BCMA_CHIP_ID_BCM4360 && ci->rev > 3) 169 bcma_core_pcie2_war_delay_perst_enab(pcie2, true); 170 bcma_core_pcie2_hw_ltr_war(pcie2); 171 pciedev_crwlpciegen2(pcie2); 172 pciedev_reg_pm_clk_period(pcie2); 173 pciedev_crwlpciegen2_180(pcie2); 174 pciedev_crwlpciegen2_182(pcie2); 175 } 176