Commit | Line | Data |
---|---|---|
8369ae33 RM |
1 | /* |
2 | * Broadcom specific AMBA | |
3 | * ChipCommon Power Management Unit driver | |
4 | * | |
eb032b98 | 5 | * Copyright 2009, Michael Buesch <m@bues.ch> |
8369ae33 RM |
6 | * Copyright 2007, Broadcom Corporation |
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 | static void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc, | |
15 | u32 offset, u32 mask, u32 set) | |
16 | { | |
17 | u32 value; | |
18 | ||
19 | bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR); | |
20 | bcma_cc_write32(cc, BCMA_CC_CHIPCTL_ADDR, offset); | |
21 | bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR); | |
22 | value = bcma_cc_read32(cc, BCMA_CC_CHIPCTL_DATA); | |
23 | value &= mask; | |
24 | value |= set; | |
25 | bcma_cc_write32(cc, BCMA_CC_CHIPCTL_DATA, value); | |
26 | bcma_cc_read32(cc, BCMA_CC_CHIPCTL_DATA); | |
27 | } | |
28 | ||
29 | static void bcma_pmu_pll_init(struct bcma_drv_cc *cc) | |
30 | { | |
31 | struct bcma_bus *bus = cc->core->bus; | |
32 | ||
33 | switch (bus->chipinfo.id) { | |
34 | case 0x4313: | |
35 | case 0x4331: | |
36 | case 43224: | |
37 | case 43225: | |
38 | break; | |
39 | default: | |
40 | pr_err("PLL init unknown for device 0x%04X\n", | |
41 | bus->chipinfo.id); | |
42 | } | |
43 | } | |
44 | ||
45 | static void bcma_pmu_resources_init(struct bcma_drv_cc *cc) | |
46 | { | |
47 | struct bcma_bus *bus = cc->core->bus; | |
48 | u32 min_msk = 0, max_msk = 0; | |
49 | ||
50 | switch (bus->chipinfo.id) { | |
51 | case 0x4313: | |
52 | min_msk = 0x200D; | |
53 | max_msk = 0xFFFF; | |
54 | break; | |
55 | case 43224: | |
91fa4b0a | 56 | case 43225: |
8369ae33 RM |
57 | break; |
58 | default: | |
59 | pr_err("PMU resource config unknown for device 0x%04X\n", | |
60 | bus->chipinfo.id); | |
61 | } | |
62 | ||
63 | /* Set the resource masks. */ | |
64 | if (min_msk) | |
65 | bcma_cc_write32(cc, BCMA_CC_PMU_MINRES_MSK, min_msk); | |
66 | if (max_msk) | |
67 | bcma_cc_write32(cc, BCMA_CC_PMU_MAXRES_MSK, max_msk); | |
68 | } | |
69 | ||
70 | void bcma_pmu_swreg_init(struct bcma_drv_cc *cc) | |
71 | { | |
72 | struct bcma_bus *bus = cc->core->bus; | |
73 | ||
74 | switch (bus->chipinfo.id) { | |
75 | case 0x4313: | |
76 | case 0x4331: | |
77 | case 43224: | |
91fa4b0a | 78 | case 43225: |
8369ae33 RM |
79 | break; |
80 | default: | |
81 | pr_err("PMU switch/regulators init unknown for device " | |
82 | "0x%04X\n", bus->chipinfo.id); | |
83 | } | |
84 | } | |
85 | ||
86 | void bcma_pmu_workarounds(struct bcma_drv_cc *cc) | |
87 | { | |
88 | struct bcma_bus *bus = cc->core->bus; | |
89 | ||
90 | switch (bus->chipinfo.id) { | |
91 | case 0x4313: | |
92 | bcma_chipco_chipctl_maskset(cc, 0, ~0, 0x7); | |
93 | break; | |
94 | case 0x4331: | |
95 | pr_err("Enabling Ext PA lines not implemented\n"); | |
96 | break; | |
97 | case 43224: | |
98 | if (bus->chipinfo.rev == 0) { | |
99 | pr_err("Workarounds for 43224 rev 0 not fully " | |
100 | "implemented\n"); | |
898f699e | 101 | bcma_chipco_chipctl_maskset(cc, 0, ~0, 0x00F000F0); |
8369ae33 RM |
102 | } else { |
103 | bcma_chipco_chipctl_maskset(cc, 0, ~0, 0xF0); | |
104 | } | |
105 | break; | |
91fa4b0a RM |
106 | case 43225: |
107 | break; | |
8369ae33 RM |
108 | default: |
109 | pr_err("Workarounds unknown for device 0x%04X\n", | |
110 | bus->chipinfo.id); | |
111 | } | |
112 | } | |
113 | ||
114 | void bcma_pmu_init(struct bcma_drv_cc *cc) | |
115 | { | |
116 | u32 pmucap; | |
117 | ||
118 | pmucap = bcma_cc_read32(cc, BCMA_CC_PMU_CAP); | |
119 | cc->pmu.rev = (pmucap & BCMA_CC_PMU_CAP_REVISION); | |
120 | ||
121 | pr_debug("Found rev %u PMU (capabilities 0x%08X)\n", cc->pmu.rev, | |
122 | pmucap); | |
123 | ||
124 | if (cc->pmu.rev == 1) | |
125 | bcma_cc_mask32(cc, BCMA_CC_PMU_CTL, | |
126 | ~BCMA_CC_PMU_CTL_NOILPONW); | |
127 | else | |
128 | bcma_cc_set32(cc, BCMA_CC_PMU_CTL, | |
129 | BCMA_CC_PMU_CTL_NOILPONW); | |
130 | ||
131 | if (cc->core->id.id == 0x4329 && cc->core->id.rev == 2) | |
132 | pr_err("Fix for 4329b0 bad LPOM state not implemented!\n"); | |
133 | ||
134 | bcma_pmu_pll_init(cc); | |
135 | bcma_pmu_resources_init(cc); | |
136 | bcma_pmu_swreg_init(cc); | |
137 | bcma_pmu_workarounds(cc); | |
138 | } |