.. | .. |
---|
13 | 13 | #include <linux/gpio/consumer.h> |
---|
14 | 14 | #include <linux/mfd/rk630.h> |
---|
15 | 15 | |
---|
16 | | -static int rk630_macphy_enable(struct rk630 *rk630) |
---|
| 16 | +static int rk630_macphy_enable(struct rk630 *rk630, unsigned long rate) |
---|
17 | 17 | { |
---|
18 | 18 | u32 val; |
---|
19 | 19 | int ret; |
---|
.. | .. |
---|
68 | 68 | return ret; |
---|
69 | 69 | } |
---|
70 | 70 | |
---|
71 | | - /* mode sel: RMII && clock sel: 24M && BGS value: OTP && id */ |
---|
72 | | - val = (2 << 14) | (0 << 12) | (0x1 << 8) | (6 << 5) | 1; |
---|
| 71 | + /* mode sel: RMII && BGS value: OTP && id */ |
---|
| 72 | + val = (2 << 14) | (0 << 12) | (0x1 << 8) | 1; |
---|
| 73 | + switch (rate) { |
---|
| 74 | + case 24000000: |
---|
| 75 | + val |= 0x6 << 5; |
---|
| 76 | + break; |
---|
| 77 | + case 25000000: |
---|
| 78 | + val |= 0x4 << 5; |
---|
| 79 | + break; |
---|
| 80 | + case 27000000: |
---|
| 81 | + val |= 0x5 << 5; |
---|
| 82 | + break; |
---|
| 83 | + default: |
---|
| 84 | + dev_err(rk630->dev, "Unsupported clock rate: %ld\n", rate); |
---|
| 85 | + return -EINVAL; |
---|
| 86 | + } |
---|
| 87 | + |
---|
73 | 88 | ret = regmap_write(rk630->grf, GRF_REG(0x404), val | 0xffff0000); |
---|
74 | 89 | if (ret != 0) { |
---|
75 | 90 | dev_err(rk630->dev, "Could not write to GRF: %d\n", ret); |
---|
.. | .. |
---|
100 | 115 | { |
---|
101 | 116 | .name = "rk630-tve", |
---|
102 | 117 | .of_compatible = "rockchip,rk630-tve", |
---|
| 118 | + }, |
---|
| 119 | + { |
---|
| 120 | + .name = "rk630-rtc", |
---|
| 121 | + .of_compatible = "rockchip,rk630-rtc", |
---|
103 | 122 | }, |
---|
104 | 123 | { |
---|
105 | 124 | .name = "rk630-macphy", |
---|
.. | .. |
---|
164 | 183 | }; |
---|
165 | 184 | EXPORT_SYMBOL_GPL(rk630_cru_regmap_config); |
---|
166 | 185 | |
---|
| 186 | +static const struct regmap_range rk630_rtc_readable_ranges[] = { |
---|
| 187 | + regmap_reg_range(RTC_SET_SECONDS, RTC_CNT_3), |
---|
| 188 | +}; |
---|
| 189 | + |
---|
| 190 | +static const struct regmap_access_table rk630_rtc_readable_table = { |
---|
| 191 | + .yes_ranges = rk630_rtc_readable_ranges, |
---|
| 192 | + .n_yes_ranges = ARRAY_SIZE(rk630_rtc_readable_ranges), |
---|
| 193 | +}; |
---|
| 194 | + |
---|
| 195 | +const struct regmap_config rk630_rtc_regmap_config = { |
---|
| 196 | + .name = "rtc", |
---|
| 197 | + .reg_bits = 32, |
---|
| 198 | + .val_bits = 32, |
---|
| 199 | + .reg_stride = 4, |
---|
| 200 | + .max_register = RTC_MAX_REGISTER, |
---|
| 201 | + .reg_format_endian = REGMAP_ENDIAN_NATIVE, |
---|
| 202 | + .val_format_endian = REGMAP_ENDIAN_NATIVE, |
---|
| 203 | + .rd_table = &rk630_rtc_readable_table, |
---|
| 204 | +}; |
---|
| 205 | +EXPORT_SYMBOL_GPL(rk630_rtc_regmap_config); |
---|
| 206 | + |
---|
167 | 207 | int rk630_core_probe(struct rk630 *rk630) |
---|
168 | 208 | { |
---|
169 | 209 | bool macphy_enabled = false; |
---|
| 210 | + struct clk *ref_clk; |
---|
170 | 211 | struct device_node *np; |
---|
| 212 | + unsigned long rate; |
---|
171 | 213 | int ret; |
---|
| 214 | + |
---|
| 215 | + if (!rk630->irq) { |
---|
| 216 | + dev_err(rk630->dev, "No interrupt support, no core IRQ\n"); |
---|
| 217 | + return -EINVAL; |
---|
| 218 | + } |
---|
| 219 | + |
---|
| 220 | + ref_clk = devm_clk_get(rk630->dev, "ref"); |
---|
| 221 | + if (IS_ERR(ref_clk)) { |
---|
| 222 | + dev_err(rk630->dev, "failed to get ref clk source\n"); |
---|
| 223 | + return PTR_ERR(ref_clk); |
---|
| 224 | + } |
---|
| 225 | + |
---|
| 226 | + ret = clk_prepare_enable(ref_clk); |
---|
| 227 | + if (ret < 0) { |
---|
| 228 | + dev_err(rk630->dev, "failed to enable ref clk - %d\n", ret); |
---|
| 229 | + return ret; |
---|
| 230 | + } |
---|
| 231 | + rate = clk_get_rate(ref_clk); |
---|
| 232 | + |
---|
| 233 | + ret = devm_add_action_or_reset(rk630->dev, (void (*) (void *))clk_disable_unprepare, |
---|
| 234 | + ref_clk); |
---|
| 235 | + if (ret) |
---|
| 236 | + return ret; |
---|
172 | 237 | |
---|
173 | 238 | rk630->reset_gpio = devm_gpiod_get(rk630->dev, "reset", 0); |
---|
174 | 239 | if (IS_ERR(rk630->reset_gpio)) { |
---|
.. | .. |
---|
182 | 247 | gpiod_direction_output(rk630->reset_gpio, 1); |
---|
183 | 248 | usleep_range(50000, 60000); |
---|
184 | 249 | gpiod_direction_output(rk630->reset_gpio, 0); |
---|
| 250 | + |
---|
| 251 | + /** |
---|
| 252 | + * If rtc output clamp is enabled, rtc regs can't be accessed, |
---|
| 253 | + * RK630 irq add will failed. |
---|
| 254 | + */ |
---|
| 255 | + regmap_update_bits(rk630->grf, PLUMAGE_GRF_SOC_CON0, |
---|
| 256 | + RTC_CLAMP_EN_MASK, RTC_CLAMP_EN(1)); |
---|
| 257 | + |
---|
| 258 | + /* disable ext_off\vbat_det\msec\sys_int\periodic interrupt by default */ |
---|
| 259 | + regmap_write(rk630->rtc, RTC_INT1_EN, 0); |
---|
185 | 260 | |
---|
186 | 261 | ret = devm_mfd_add_devices(rk630->dev, PLATFORM_DEVID_NONE, |
---|
187 | 262 | rk630_devs, ARRAY_SIZE(rk630_devs), |
---|
.. | .. |
---|
204 | 279 | } |
---|
205 | 280 | |
---|
206 | 281 | if (macphy_enabled) |
---|
207 | | - rk630_macphy_enable(rk630); |
---|
| 282 | + rk630_macphy_enable(rk630, rate); |
---|
208 | 283 | else |
---|
209 | 284 | rk630_macphy_disable(rk630); |
---|
210 | 285 | |
---|