diff options
author | Rafał Miłecki <zajec5@gmail.com> | 2013-06-26 04:02:11 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-06-27 13:42:16 -0400 |
commit | 88f9b65d444794bb607f71644362ba0642585206 (patch) | |
tree | 79b35a37ff7dbff438e572ce39b0aa8c43b2ff24 /drivers/bcma | |
parent | 8960400eeefa73e7fe32dc2b6b5ac529d43a9593 (diff) |
bcma: add support for BCM43142
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/bcma')
-rw-r--r-- | drivers/bcma/bcma_private.h | 2 | ||||
-rw-r--r-- | drivers/bcma/driver_chipcommon.c | 11 | ||||
-rw-r--r-- | drivers/bcma/driver_chipcommon_pmu.c | 123 | ||||
-rw-r--r-- | drivers/bcma/host_pci.c | 1 | ||||
-rw-r--r-- | drivers/bcma/main.c | 19 | ||||
-rw-r--r-- | drivers/bcma/sprom.c | 1 |
6 files changed, 155 insertions, 2 deletions
diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h index 79595a001204..0215f9ad755c 100644 --- a/drivers/bcma/bcma_private.h +++ b/drivers/bcma/bcma_private.h | |||
@@ -22,6 +22,8 @@ | |||
22 | struct bcma_bus; | 22 | struct bcma_bus; |
23 | 23 | ||
24 | /* main.c */ | 24 | /* main.c */ |
25 | bool bcma_wait_value(struct bcma_device *core, u16 reg, u32 mask, u32 value, | ||
26 | int timeout); | ||
25 | int bcma_bus_register(struct bcma_bus *bus); | 27 | int bcma_bus_register(struct bcma_bus *bus); |
26 | void bcma_bus_unregister(struct bcma_bus *bus); | 28 | void bcma_bus_unregister(struct bcma_bus *bus); |
27 | int __init bcma_bus_early_register(struct bcma_bus *bus, | 29 | int __init bcma_bus_early_register(struct bcma_bus *bus, |
diff --git a/drivers/bcma/driver_chipcommon.c b/drivers/bcma/driver_chipcommon.c index 036c6744b39b..b068f98920a8 100644 --- a/drivers/bcma/driver_chipcommon.c +++ b/drivers/bcma/driver_chipcommon.c | |||
@@ -140,8 +140,15 @@ void bcma_core_chipcommon_init(struct bcma_drv_cc *cc) | |||
140 | bcma_core_chipcommon_early_init(cc); | 140 | bcma_core_chipcommon_early_init(cc); |
141 | 141 | ||
142 | if (cc->core->id.rev >= 20) { | 142 | if (cc->core->id.rev >= 20) { |
143 | bcma_cc_write32(cc, BCMA_CC_GPIOPULLUP, 0); | 143 | u32 pullup = 0, pulldown = 0; |
144 | bcma_cc_write32(cc, BCMA_CC_GPIOPULLDOWN, 0); | 144 | |
145 | if (cc->core->bus->chipinfo.id == BCMA_CHIP_ID_BCM43142) { | ||
146 | pullup = 0x402e0; | ||
147 | pulldown = 0x20500; | ||
148 | } | ||
149 | |||
150 | bcma_cc_write32(cc, BCMA_CC_GPIOPULLUP, pullup); | ||
151 | bcma_cc_write32(cc, BCMA_CC_GPIOPULLDOWN, pulldown); | ||
145 | } | 152 | } |
146 | 153 | ||
147 | if (cc->capabilities & BCMA_CC_CAP_PMU) | 154 | if (cc->capabilities & BCMA_CC_CAP_PMU) |
diff --git a/drivers/bcma/driver_chipcommon_pmu.c b/drivers/bcma/driver_chipcommon_pmu.c index edca73af3cc0..5081a8c439cc 100644 --- a/drivers/bcma/driver_chipcommon_pmu.c +++ b/drivers/bcma/driver_chipcommon_pmu.c | |||
@@ -56,6 +56,109 @@ void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask, | |||
56 | } | 56 | } |
57 | EXPORT_SYMBOL_GPL(bcma_chipco_regctl_maskset); | 57 | EXPORT_SYMBOL_GPL(bcma_chipco_regctl_maskset); |
58 | 58 | ||
59 | static u32 bcma_pmu_xtalfreq(struct bcma_drv_cc *cc) | ||
60 | { | ||
61 | u32 ilp_ctl, alp_hz; | ||
62 | |||
63 | if (!(bcma_cc_read32(cc, BCMA_CC_PMU_STAT) & | ||
64 | BCMA_CC_PMU_STAT_EXT_LPO_AVAIL)) | ||
65 | return 0; | ||
66 | |||
67 | bcma_cc_write32(cc, BCMA_CC_PMU_XTAL_FREQ, | ||
68 | BIT(BCMA_CC_PMU_XTAL_FREQ_MEASURE_SHIFT)); | ||
69 | usleep_range(1000, 2000); | ||
70 | |||
71 | ilp_ctl = bcma_cc_read32(cc, BCMA_CC_PMU_XTAL_FREQ); | ||
72 | ilp_ctl &= BCMA_CC_PMU_XTAL_FREQ_ILPCTL_MASK; | ||
73 | |||
74 | bcma_cc_write32(cc, BCMA_CC_PMU_XTAL_FREQ, 0); | ||
75 | |||
76 | alp_hz = ilp_ctl * 32768 / 4; | ||
77 | return (alp_hz + 50000) / 100000 * 100; | ||
78 | } | ||
79 | |||
80 | static void bcma_pmu2_pll_init0(struct bcma_drv_cc *cc, u32 xtalfreq) | ||
81 | { | ||
82 | struct bcma_bus *bus = cc->core->bus; | ||
83 | u32 freq_tgt_target = 0, freq_tgt_current; | ||
84 | u32 pll0, mask; | ||
85 | |||
86 | switch (bus->chipinfo.id) { | ||
87 | case BCMA_CHIP_ID_BCM43142: | ||
88 | /* pmu2_xtaltab0_adfll_485 */ | ||
89 | switch (xtalfreq) { | ||
90 | case 12000: | ||
91 | freq_tgt_target = 0x50D52; | ||
92 | break; | ||
93 | case 20000: | ||
94 | freq_tgt_target = 0x307FE; | ||
95 | break; | ||
96 | case 26000: | ||
97 | freq_tgt_target = 0x254EA; | ||
98 | break; | ||
99 | case 37400: | ||
100 | freq_tgt_target = 0x19EF8; | ||
101 | break; | ||
102 | case 52000: | ||
103 | freq_tgt_target = 0x12A75; | ||
104 | break; | ||
105 | } | ||
106 | break; | ||
107 | } | ||
108 | |||
109 | if (!freq_tgt_target) { | ||
110 | bcma_err(bus, "Unknown TGT frequency for xtalfreq %d\n", | ||
111 | xtalfreq); | ||
112 | return; | ||
113 | } | ||
114 | |||
115 | pll0 = bcma_chipco_pll_read(cc, BCMA_CC_PMU15_PLL_PLLCTL0); | ||
116 | freq_tgt_current = (pll0 & BCMA_CC_PMU15_PLL_PC0_FREQTGT_MASK) >> | ||
117 | BCMA_CC_PMU15_PLL_PC0_FREQTGT_SHIFT; | ||
118 | |||
119 | if (freq_tgt_current == freq_tgt_target) { | ||
120 | bcma_debug(bus, "Target TGT frequency already set\n"); | ||
121 | return; | ||
122 | } | ||
123 | |||
124 | /* Turn off PLL */ | ||
125 | switch (bus->chipinfo.id) { | ||
126 | case BCMA_CHIP_ID_BCM43142: | ||
127 | mask = (u32)~(BCMA_RES_4314_HT_AVAIL | | ||
128 | BCMA_RES_4314_MACPHY_CLK_AVAIL); | ||
129 | |||
130 | bcma_cc_mask32(cc, BCMA_CC_PMU_MINRES_MSK, mask); | ||
131 | bcma_cc_mask32(cc, BCMA_CC_PMU_MAXRES_MSK, mask); | ||
132 | bcma_wait_value(cc->core, BCMA_CLKCTLST, | ||
133 | BCMA_CLKCTLST_HAVEHT, 0, 20000); | ||
134 | break; | ||
135 | } | ||
136 | |||
137 | pll0 &= ~BCMA_CC_PMU15_PLL_PC0_FREQTGT_MASK; | ||
138 | pll0 |= freq_tgt_target << BCMA_CC_PMU15_PLL_PC0_FREQTGT_SHIFT; | ||
139 | bcma_chipco_pll_write(cc, BCMA_CC_PMU15_PLL_PLLCTL0, pll0); | ||
140 | |||
141 | /* Flush */ | ||
142 | if (cc->pmu.rev >= 2) | ||
143 | bcma_cc_set32(cc, BCMA_CC_PMU_CTL, BCMA_CC_PMU_CTL_PLL_UPD); | ||
144 | |||
145 | /* TODO: Do we need to update OTP? */ | ||
146 | } | ||
147 | |||
148 | static void bcma_pmu_pll_init(struct bcma_drv_cc *cc) | ||
149 | { | ||
150 | struct bcma_bus *bus = cc->core->bus; | ||
151 | u32 xtalfreq = bcma_pmu_xtalfreq(cc); | ||
152 | |||
153 | switch (bus->chipinfo.id) { | ||
154 | case BCMA_CHIP_ID_BCM43142: | ||
155 | if (xtalfreq == 0) | ||
156 | xtalfreq = 20000; | ||
157 | bcma_pmu2_pll_init0(cc, xtalfreq); | ||
158 | break; | ||
159 | } | ||
160 | } | ||
161 | |||
59 | static void bcma_pmu_resources_init(struct bcma_drv_cc *cc) | 162 | static void bcma_pmu_resources_init(struct bcma_drv_cc *cc) |
60 | { | 163 | { |
61 | struct bcma_bus *bus = cc->core->bus; | 164 | struct bcma_bus *bus = cc->core->bus; |
@@ -66,6 +169,25 @@ static void bcma_pmu_resources_init(struct bcma_drv_cc *cc) | |||
66 | min_msk = 0x200D; | 169 | min_msk = 0x200D; |
67 | max_msk = 0xFFFF; | 170 | max_msk = 0xFFFF; |
68 | break; | 171 | break; |
172 | case BCMA_CHIP_ID_BCM43142: | ||
173 | min_msk = BCMA_RES_4314_LPLDO_PU | | ||
174 | BCMA_RES_4314_PMU_SLEEP_DIS | | ||
175 | BCMA_RES_4314_PMU_BG_PU | | ||
176 | BCMA_RES_4314_CBUCK_LPOM_PU | | ||
177 | BCMA_RES_4314_CBUCK_PFM_PU | | ||
178 | BCMA_RES_4314_CLDO_PU | | ||
179 | BCMA_RES_4314_LPLDO2_LVM | | ||
180 | BCMA_RES_4314_WL_PMU_PU | | ||
181 | BCMA_RES_4314_LDO3P3_PU | | ||
182 | BCMA_RES_4314_OTP_PU | | ||
183 | BCMA_RES_4314_WL_PWRSW_PU | | ||
184 | BCMA_RES_4314_LQ_AVAIL | | ||
185 | BCMA_RES_4314_LOGIC_RET | | ||
186 | BCMA_RES_4314_MEM_SLEEP | | ||
187 | BCMA_RES_4314_MACPHY_RET | | ||
188 | BCMA_RES_4314_WL_CORE_READY; | ||
189 | max_msk = 0x3FFFFFFF; | ||
190 | break; | ||
69 | default: | 191 | default: |
70 | bcma_debug(bus, "PMU resource config unknown or not needed for device 0x%04X\n", | 192 | bcma_debug(bus, "PMU resource config unknown or not needed for device 0x%04X\n", |
71 | bus->chipinfo.id); | 193 | bus->chipinfo.id); |
@@ -165,6 +287,7 @@ void bcma_pmu_init(struct bcma_drv_cc *cc) | |||
165 | bcma_cc_set32(cc, BCMA_CC_PMU_CTL, | 287 | bcma_cc_set32(cc, BCMA_CC_PMU_CTL, |
166 | BCMA_CC_PMU_CTL_NOILPONW); | 288 | BCMA_CC_PMU_CTL_NOILPONW); |
167 | 289 | ||
290 | bcma_pmu_pll_init(cc); | ||
168 | bcma_pmu_resources_init(cc); | 291 | bcma_pmu_resources_init(cc); |
169 | bcma_pmu_workarounds(cc); | 292 | bcma_pmu_workarounds(cc); |
170 | } | 293 | } |
diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c index fbf2759e7e4e..a355e63a3838 100644 --- a/drivers/bcma/host_pci.c +++ b/drivers/bcma/host_pci.c | |||
@@ -275,6 +275,7 @@ static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = { | |||
275 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4357) }, | 275 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4357) }, |
276 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4358) }, | 276 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4358) }, |
277 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4359) }, | 277 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4359) }, |
278 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4365) }, | ||
278 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) }, | 279 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) }, |
279 | { 0, }, | 280 | { 0, }, |
280 | }; | 281 | }; |
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c index f72f52b4b1dd..0067422ec17d 100644 --- a/drivers/bcma/main.c +++ b/drivers/bcma/main.c | |||
@@ -93,6 +93,25 @@ struct bcma_device *bcma_find_core_unit(struct bcma_bus *bus, u16 coreid, | |||
93 | return NULL; | 93 | return NULL; |
94 | } | 94 | } |
95 | 95 | ||
96 | bool bcma_wait_value(struct bcma_device *core, u16 reg, u32 mask, u32 value, | ||
97 | int timeout) | ||
98 | { | ||
99 | unsigned long deadline = jiffies + timeout; | ||
100 | u32 val; | ||
101 | |||
102 | do { | ||
103 | val = bcma_read32(core, reg); | ||
104 | if ((val & mask) == value) | ||
105 | return true; | ||
106 | cpu_relax(); | ||
107 | udelay(10); | ||
108 | } while (!time_after_eq(jiffies, deadline)); | ||
109 | |||
110 | bcma_warn(core->bus, "Timeout waiting for register 0x%04X!\n", reg); | ||
111 | |||
112 | return false; | ||
113 | } | ||
114 | |||
96 | static void bcma_release_core_dev(struct device *dev) | 115 | static void bcma_release_core_dev(struct device *dev) |
97 | { | 116 | { |
98 | struct bcma_device *core = container_of(dev, struct bcma_device, dev); | 117 | struct bcma_device *core = container_of(dev, struct bcma_device, dev); |
diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c index de15b4f4b237..72bf4540f565 100644 --- a/drivers/bcma/sprom.c +++ b/drivers/bcma/sprom.c | |||
@@ -503,6 +503,7 @@ static bool bcma_sprom_onchip_available(struct bcma_bus *bus) | |||
503 | case BCMA_CHIP_ID_BCM4331: | 503 | case BCMA_CHIP_ID_BCM4331: |
504 | present = chip_status & BCMA_CC_CHIPST_4331_OTP_PRESENT; | 504 | present = chip_status & BCMA_CC_CHIPST_4331_OTP_PRESENT; |
505 | break; | 505 | break; |
506 | case BCMA_CHIP_ID_BCM43142: | ||
506 | case BCMA_CHIP_ID_BCM43224: | 507 | case BCMA_CHIP_ID_BCM43224: |
507 | case BCMA_CHIP_ID_BCM43225: | 508 | case BCMA_CHIP_ID_BCM43225: |
508 | /* for these chips OTP is always available */ | 509 | /* for these chips OTP is always available */ |