1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Raspberry Pi driver for firmware controlled clocks 4 * 5 * Even though clk-bcm2835 provides an interface to the hardware registers for 6 * the system clocks we've had to factor out 'pllb' as the firmware 'owns' it. 7 * We're not allowed to change it directly as we might race with the 8 * over-temperature and under-voltage protections provided by the firmware. 9 * 10 * Copyright (C) 2019 Nicolas Saenz Julienne <nsaenzjulienne@suse.de> 11 */ 12 13 #include <linux/clkdev.h> 14 #include <linux/clk-provider.h> 15 #include <linux/io.h> 16 #include <linux/module.h> 17 #include <linux/platform_device.h> 18 19 #include <soc/bcm2835/raspberrypi-firmware.h> 20 21 #define RPI_FIRMWARE_ARM_CLK_ID 0x00000003 22 23 #define RPI_FIRMWARE_STATE_ENABLE_BIT BIT(0) 24 #define RPI_FIRMWARE_STATE_WAIT_BIT BIT(1) 25 26 /* 27 * Even though the firmware interface alters 'pllb' the frequencies are 28 * provided as per 'pllb_arm'. We need to scale before passing them trough. 29 */ 30 #define RPI_FIRMWARE_PLLB_ARM_DIV_RATE 2 31 32 #define A2W_PLL_FRAC_BITS 20 33 34 struct raspberrypi_clk { 35 struct device *dev; 36 struct rpi_firmware *firmware; 37 struct platform_device *cpufreq; 38 39 unsigned long min_rate; 40 unsigned long max_rate; 41 42 struct clk_hw pllb; 43 struct clk_hw *pllb_arm; 44 struct clk_lookup *pllb_arm_lookup; 45 }; 46 47 /* 48 * Structure of the message passed to Raspberry Pi's firmware in order to 49 * change clock rates. The 'disable_turbo' option is only available to the ARM 50 * clock (pllb) which we enable by default as turbo mode will alter multiple 51 * clocks at once. 52 * 53 * Even though we're able to access the clock registers directly we're bound to 54 * use the firmware interface as the firmware ultimately takes care of 55 * mitigating overheating/undervoltage situations and we would be changing 56 * frequencies behind his back. 57 * 58 * For more information on the firmware interface check: 59 * https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface 60 */ 61 struct raspberrypi_firmware_prop { 62 __le32 id; 63 __le32 val; 64 __le32 disable_turbo; 65 } __packed; 66 67 static int raspberrypi_clock_property(struct rpi_firmware *firmware, u32 tag, 68 u32 clk, u32 *val) 69 { 70 struct raspberrypi_firmware_prop msg = { 71 .id = cpu_to_le32(clk), 72 .val = cpu_to_le32(*val), 73 .disable_turbo = cpu_to_le32(1), 74 }; 75 int ret; 76 77 ret = rpi_firmware_property(firmware, tag, &msg, sizeof(msg)); 78 if (ret) 79 return ret; 80 81 *val = le32_to_cpu(msg.val); 82 83 return 0; 84 } 85 86 static int raspberrypi_fw_pll_is_on(struct clk_hw *hw) 87 { 88 struct raspberrypi_clk *rpi = container_of(hw, struct raspberrypi_clk, 89 pllb); 90 u32 val = 0; 91 int ret; 92 93 ret = raspberrypi_clock_property(rpi->firmware, 94 RPI_FIRMWARE_GET_CLOCK_STATE, 95 RPI_FIRMWARE_ARM_CLK_ID, &val); 96 if (ret) 97 return 0; 98 99 return !!(val & RPI_FIRMWARE_STATE_ENABLE_BIT); 100 } 101 102 103 static unsigned long raspberrypi_fw_pll_get_rate(struct clk_hw *hw, 104 unsigned long parent_rate) 105 { 106 struct raspberrypi_clk *rpi = container_of(hw, struct raspberrypi_clk, 107 pllb); 108 u32 val = 0; 109 int ret; 110 111 ret = raspberrypi_clock_property(rpi->firmware, 112 RPI_FIRMWARE_GET_CLOCK_RATE, 113 RPI_FIRMWARE_ARM_CLK_ID, 114 &val); 115 if (ret) 116 return ret; 117 118 return val * RPI_FIRMWARE_PLLB_ARM_DIV_RATE; 119 } 120 121 static int raspberrypi_fw_pll_set_rate(struct clk_hw *hw, unsigned long rate, 122 unsigned long parent_rate) 123 { 124 struct raspberrypi_clk *rpi = container_of(hw, struct raspberrypi_clk, 125 pllb); 126 u32 new_rate = rate / RPI_FIRMWARE_PLLB_ARM_DIV_RATE; 127 int ret; 128 129 ret = raspberrypi_clock_property(rpi->firmware, 130 RPI_FIRMWARE_SET_CLOCK_RATE, 131 RPI_FIRMWARE_ARM_CLK_ID, 132 &new_rate); 133 if (ret) 134 dev_err_ratelimited(rpi->dev, "Failed to change %s frequency: %d", 135 clk_hw_get_name(hw), ret); 136 137 return ret; 138 } 139 140 /* 141 * Sadly there is no firmware rate rounding interface. We borrowed it from 142 * clk-bcm2835. 143 */ 144 static int raspberrypi_pll_determine_rate(struct clk_hw *hw, 145 struct clk_rate_request *req) 146 { 147 struct raspberrypi_clk *rpi = container_of(hw, struct raspberrypi_clk, 148 pllb); 149 u64 div, final_rate; 150 u32 ndiv, fdiv; 151 152 /* We can't use req->rate directly as it would overflow */ 153 final_rate = clamp(req->rate, rpi->min_rate, rpi->max_rate); 154 155 div = (u64)final_rate << A2W_PLL_FRAC_BITS; 156 do_div(div, req->best_parent_rate); 157 158 ndiv = div >> A2W_PLL_FRAC_BITS; 159 fdiv = div & ((1 << A2W_PLL_FRAC_BITS) - 1); 160 161 final_rate = ((u64)req->best_parent_rate * 162 ((ndiv << A2W_PLL_FRAC_BITS) + fdiv)); 163 164 req->rate = final_rate >> A2W_PLL_FRAC_BITS; 165 166 return 0; 167 } 168 169 static const struct clk_ops raspberrypi_firmware_pll_clk_ops = { 170 .is_prepared = raspberrypi_fw_pll_is_on, 171 .recalc_rate = raspberrypi_fw_pll_get_rate, 172 .set_rate = raspberrypi_fw_pll_set_rate, 173 .determine_rate = raspberrypi_pll_determine_rate, 174 }; 175 176 static int raspberrypi_register_pllb(struct raspberrypi_clk *rpi) 177 { 178 u32 min_rate = 0, max_rate = 0; 179 struct clk_init_data init; 180 int ret; 181 182 memset(&init, 0, sizeof(init)); 183 184 /* All of the PLLs derive from the external oscillator. */ 185 init.parent_names = (const char *[]){ "osc" }; 186 init.num_parents = 1; 187 init.name = "pllb"; 188 init.ops = &raspberrypi_firmware_pll_clk_ops; 189 init.flags = CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED; 190 191 /* Get min & max rates set by the firmware */ 192 ret = raspberrypi_clock_property(rpi->firmware, 193 RPI_FIRMWARE_GET_MIN_CLOCK_RATE, 194 RPI_FIRMWARE_ARM_CLK_ID, 195 &min_rate); 196 if (ret) { 197 dev_err(rpi->dev, "Failed to get %s min freq: %d\n", 198 init.name, ret); 199 return ret; 200 } 201 202 ret = raspberrypi_clock_property(rpi->firmware, 203 RPI_FIRMWARE_GET_MAX_CLOCK_RATE, 204 RPI_FIRMWARE_ARM_CLK_ID, 205 &max_rate); 206 if (ret) { 207 dev_err(rpi->dev, "Failed to get %s max freq: %d\n", 208 init.name, ret); 209 return ret; 210 } 211 212 if (!min_rate || !max_rate) { 213 dev_err(rpi->dev, "Unexpected frequency range: min %u, max %u\n", 214 min_rate, max_rate); 215 return -EINVAL; 216 } 217 218 dev_info(rpi->dev, "CPU frequency range: min %u, max %u\n", 219 min_rate, max_rate); 220 221 rpi->min_rate = min_rate * RPI_FIRMWARE_PLLB_ARM_DIV_RATE; 222 rpi->max_rate = max_rate * RPI_FIRMWARE_PLLB_ARM_DIV_RATE; 223 224 rpi->pllb.init = &init; 225 226 return devm_clk_hw_register(rpi->dev, &rpi->pllb); 227 } 228 229 static int raspberrypi_register_pllb_arm(struct raspberrypi_clk *rpi) 230 { 231 rpi->pllb_arm = clk_hw_register_fixed_factor(rpi->dev, 232 "pllb_arm", "pllb", 233 CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, 234 1, 2); 235 if (IS_ERR(rpi->pllb_arm)) { 236 dev_err(rpi->dev, "Failed to initialize pllb_arm\n"); 237 return PTR_ERR(rpi->pllb_arm); 238 } 239 240 rpi->pllb_arm_lookup = clkdev_hw_create(rpi->pllb_arm, NULL, "cpu0"); 241 if (!rpi->pllb_arm_lookup) { 242 dev_err(rpi->dev, "Failed to initialize pllb_arm_lookup\n"); 243 clk_hw_unregister_fixed_factor(rpi->pllb_arm); 244 return -ENOMEM; 245 } 246 247 return 0; 248 } 249 250 static int raspberrypi_clk_probe(struct platform_device *pdev) 251 { 252 struct device_node *firmware_node; 253 struct device *dev = &pdev->dev; 254 struct rpi_firmware *firmware; 255 struct raspberrypi_clk *rpi; 256 int ret; 257 258 firmware_node = of_find_compatible_node(NULL, NULL, 259 "raspberrypi,bcm2835-firmware"); 260 if (!firmware_node) { 261 dev_err(dev, "Missing firmware node\n"); 262 return -ENOENT; 263 } 264 265 firmware = rpi_firmware_get(firmware_node); 266 of_node_put(firmware_node); 267 if (!firmware) 268 return -EPROBE_DEFER; 269 270 rpi = devm_kzalloc(dev, sizeof(*rpi), GFP_KERNEL); 271 if (!rpi) 272 return -ENOMEM; 273 274 rpi->dev = dev; 275 rpi->firmware = firmware; 276 platform_set_drvdata(pdev, rpi); 277 278 ret = raspberrypi_register_pllb(rpi); 279 if (ret) { 280 dev_err(dev, "Failed to initialize pllb, %d\n", ret); 281 return ret; 282 } 283 284 ret = raspberrypi_register_pllb_arm(rpi); 285 if (ret) 286 return ret; 287 288 rpi->cpufreq = platform_device_register_data(dev, "raspberrypi-cpufreq", 289 -1, NULL, 0); 290 291 return 0; 292 } 293 294 static int raspberrypi_clk_remove(struct platform_device *pdev) 295 { 296 struct raspberrypi_clk *rpi = platform_get_drvdata(pdev); 297 298 platform_device_unregister(rpi->cpufreq); 299 300 return 0; 301 } 302 303 static struct platform_driver raspberrypi_clk_driver = { 304 .driver = { 305 .name = "raspberrypi-clk", 306 }, 307 .probe = raspberrypi_clk_probe, 308 .remove = raspberrypi_clk_remove, 309 }; 310 module_platform_driver(raspberrypi_clk_driver); 311 312 MODULE_AUTHOR("Nicolas Saenz Julienne <nsaenzjulienne@suse.de>"); 313 MODULE_DESCRIPTION("Raspberry Pi firmware clock driver"); 314 MODULE_LICENSE("GPL"); 315 MODULE_ALIAS("platform:raspberrypi-clk"); 316