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