clk-raspberrypi.c (12186B)
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 21enum rpi_firmware_clk_id { 22 RPI_FIRMWARE_EMMC_CLK_ID = 1, 23 RPI_FIRMWARE_UART_CLK_ID, 24 RPI_FIRMWARE_ARM_CLK_ID, 25 RPI_FIRMWARE_CORE_CLK_ID, 26 RPI_FIRMWARE_V3D_CLK_ID, 27 RPI_FIRMWARE_H264_CLK_ID, 28 RPI_FIRMWARE_ISP_CLK_ID, 29 RPI_FIRMWARE_SDRAM_CLK_ID, 30 RPI_FIRMWARE_PIXEL_CLK_ID, 31 RPI_FIRMWARE_PWM_CLK_ID, 32 RPI_FIRMWARE_HEVC_CLK_ID, 33 RPI_FIRMWARE_EMMC2_CLK_ID, 34 RPI_FIRMWARE_M2MC_CLK_ID, 35 RPI_FIRMWARE_PIXEL_BVB_CLK_ID, 36 RPI_FIRMWARE_NUM_CLK_ID, 37}; 38 39static char *rpi_firmware_clk_names[] = { 40 [RPI_FIRMWARE_EMMC_CLK_ID] = "emmc", 41 [RPI_FIRMWARE_UART_CLK_ID] = "uart", 42 [RPI_FIRMWARE_ARM_CLK_ID] = "arm", 43 [RPI_FIRMWARE_CORE_CLK_ID] = "core", 44 [RPI_FIRMWARE_V3D_CLK_ID] = "v3d", 45 [RPI_FIRMWARE_H264_CLK_ID] = "h264", 46 [RPI_FIRMWARE_ISP_CLK_ID] = "isp", 47 [RPI_FIRMWARE_SDRAM_CLK_ID] = "sdram", 48 [RPI_FIRMWARE_PIXEL_CLK_ID] = "pixel", 49 [RPI_FIRMWARE_PWM_CLK_ID] = "pwm", 50 [RPI_FIRMWARE_HEVC_CLK_ID] = "hevc", 51 [RPI_FIRMWARE_EMMC2_CLK_ID] = "emmc2", 52 [RPI_FIRMWARE_M2MC_CLK_ID] = "m2mc", 53 [RPI_FIRMWARE_PIXEL_BVB_CLK_ID] = "pixel-bvb", 54}; 55 56#define RPI_FIRMWARE_STATE_ENABLE_BIT BIT(0) 57#define RPI_FIRMWARE_STATE_WAIT_BIT BIT(1) 58 59struct raspberrypi_clk_variant; 60 61struct raspberrypi_clk { 62 struct device *dev; 63 struct rpi_firmware *firmware; 64 struct platform_device *cpufreq; 65}; 66 67struct raspberrypi_clk_data { 68 struct clk_hw hw; 69 70 unsigned int id; 71 struct raspberrypi_clk_variant *variant; 72 73 struct raspberrypi_clk *rpi; 74}; 75 76struct raspberrypi_clk_variant { 77 bool export; 78 char *clkdev; 79 unsigned long min_rate; 80 bool minimize; 81}; 82 83static struct raspberrypi_clk_variant 84raspberrypi_clk_variants[RPI_FIRMWARE_NUM_CLK_ID] = { 85 [RPI_FIRMWARE_ARM_CLK_ID] = { 86 .export = true, 87 .clkdev = "cpu0", 88 }, 89 [RPI_FIRMWARE_CORE_CLK_ID] = { 90 .export = true, 91 92 /* 93 * The clock is shared between the HVS and the CSI 94 * controllers, on the BCM2711 and will change depending 95 * on the pixels composited on the HVS and the capture 96 * resolution on Unicam. 97 * 98 * Since the rate can get quite large, and we need to 99 * coordinate between both driver instances, let's 100 * always use the minimum the drivers will let us. 101 */ 102 .minimize = true, 103 }, 104 [RPI_FIRMWARE_M2MC_CLK_ID] = { 105 .export = true, 106 107 /* 108 * If we boot without any cable connected to any of the 109 * HDMI connector, the firmware will skip the HSM 110 * initialization and leave it with a rate of 0, 111 * resulting in a bus lockup when we're accessing the 112 * registers even if it's enabled. 113 * 114 * Let's put a sensible default so that we don't end up 115 * in this situation. 116 */ 117 .min_rate = 120000000, 118 119 /* 120 * The clock is shared between the two HDMI controllers 121 * on the BCM2711 and will change depending on the 122 * resolution output on each. Since the rate can get 123 * quite large, and we need to coordinate between both 124 * driver instances, let's always use the minimum the 125 * drivers will let us. 126 */ 127 .minimize = true, 128 }, 129 [RPI_FIRMWARE_V3D_CLK_ID] = { 130 .export = true, 131 }, 132 [RPI_FIRMWARE_PIXEL_BVB_CLK_ID] = { 133 .export = true, 134 }, 135}; 136 137/* 138 * Structure of the message passed to Raspberry Pi's firmware in order to 139 * change clock rates. The 'disable_turbo' option is only available to the ARM 140 * clock (pllb) which we enable by default as turbo mode will alter multiple 141 * clocks at once. 142 * 143 * Even though we're able to access the clock registers directly we're bound to 144 * use the firmware interface as the firmware ultimately takes care of 145 * mitigating overheating/undervoltage situations and we would be changing 146 * frequencies behind his back. 147 * 148 * For more information on the firmware interface check: 149 * https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface 150 */ 151struct raspberrypi_firmware_prop { 152 __le32 id; 153 __le32 val; 154 __le32 disable_turbo; 155} __packed; 156 157static int raspberrypi_clock_property(struct rpi_firmware *firmware, 158 const struct raspberrypi_clk_data *data, 159 u32 tag, u32 *val) 160{ 161 struct raspberrypi_firmware_prop msg = { 162 .id = cpu_to_le32(data->id), 163 .val = cpu_to_le32(*val), 164 .disable_turbo = cpu_to_le32(1), 165 }; 166 int ret; 167 168 ret = rpi_firmware_property(firmware, tag, &msg, sizeof(msg)); 169 if (ret) 170 return ret; 171 172 *val = le32_to_cpu(msg.val); 173 174 return 0; 175} 176 177static int raspberrypi_fw_is_prepared(struct clk_hw *hw) 178{ 179 struct raspberrypi_clk_data *data = 180 container_of(hw, struct raspberrypi_clk_data, hw); 181 struct raspberrypi_clk *rpi = data->rpi; 182 u32 val = 0; 183 int ret; 184 185 ret = raspberrypi_clock_property(rpi->firmware, data, 186 RPI_FIRMWARE_GET_CLOCK_STATE, &val); 187 if (ret) 188 return 0; 189 190 return !!(val & RPI_FIRMWARE_STATE_ENABLE_BIT); 191} 192 193 194static unsigned long raspberrypi_fw_get_rate(struct clk_hw *hw, 195 unsigned long parent_rate) 196{ 197 struct raspberrypi_clk_data *data = 198 container_of(hw, struct raspberrypi_clk_data, hw); 199 struct raspberrypi_clk *rpi = data->rpi; 200 u32 val = 0; 201 int ret; 202 203 ret = raspberrypi_clock_property(rpi->firmware, data, 204 RPI_FIRMWARE_GET_CLOCK_RATE, &val); 205 if (ret) 206 return ret; 207 208 return val; 209} 210 211static int raspberrypi_fw_set_rate(struct clk_hw *hw, unsigned long rate, 212 unsigned long parent_rate) 213{ 214 struct raspberrypi_clk_data *data = 215 container_of(hw, struct raspberrypi_clk_data, hw); 216 struct raspberrypi_clk *rpi = data->rpi; 217 u32 _rate = rate; 218 int ret; 219 220 ret = raspberrypi_clock_property(rpi->firmware, data, 221 RPI_FIRMWARE_SET_CLOCK_RATE, &_rate); 222 if (ret) 223 dev_err_ratelimited(rpi->dev, "Failed to change %s frequency: %d", 224 clk_hw_get_name(hw), ret); 225 226 return ret; 227} 228 229static int raspberrypi_fw_dumb_determine_rate(struct clk_hw *hw, 230 struct clk_rate_request *req) 231{ 232 struct raspberrypi_clk_data *data = 233 container_of(hw, struct raspberrypi_clk_data, hw); 234 struct raspberrypi_clk_variant *variant = data->variant; 235 236 /* 237 * The firmware will do the rounding but that isn't part of 238 * the interface with the firmware, so we just do our best 239 * here. 240 */ 241 242 req->rate = clamp(req->rate, req->min_rate, req->max_rate); 243 244 /* 245 * We want to aggressively reduce the clock rate here, so let's 246 * just ignore the requested rate and return the bare minimum 247 * rate we can get away with. 248 */ 249 if (variant->minimize && req->min_rate > 0) 250 req->rate = req->min_rate; 251 252 return 0; 253} 254 255static const struct clk_ops raspberrypi_firmware_clk_ops = { 256 .is_prepared = raspberrypi_fw_is_prepared, 257 .recalc_rate = raspberrypi_fw_get_rate, 258 .determine_rate = raspberrypi_fw_dumb_determine_rate, 259 .set_rate = raspberrypi_fw_set_rate, 260}; 261 262static struct clk_hw *raspberrypi_clk_register(struct raspberrypi_clk *rpi, 263 unsigned int parent, 264 unsigned int id, 265 struct raspberrypi_clk_variant *variant) 266{ 267 struct raspberrypi_clk_data *data; 268 struct clk_init_data init = {}; 269 u32 min_rate, max_rate; 270 int ret; 271 272 data = devm_kzalloc(rpi->dev, sizeof(*data), GFP_KERNEL); 273 if (!data) 274 return ERR_PTR(-ENOMEM); 275 data->rpi = rpi; 276 data->id = id; 277 data->variant = variant; 278 279 init.name = devm_kasprintf(rpi->dev, GFP_KERNEL, 280 "fw-clk-%s", 281 rpi_firmware_clk_names[id]); 282 init.ops = &raspberrypi_firmware_clk_ops; 283 init.flags = CLK_GET_RATE_NOCACHE; 284 285 data->hw.init = &init; 286 287 ret = raspberrypi_clock_property(rpi->firmware, data, 288 RPI_FIRMWARE_GET_MIN_CLOCK_RATE, 289 &min_rate); 290 if (ret) { 291 dev_err(rpi->dev, "Failed to get clock %d min freq: %d", 292 id, ret); 293 return ERR_PTR(ret); 294 } 295 296 ret = raspberrypi_clock_property(rpi->firmware, data, 297 RPI_FIRMWARE_GET_MAX_CLOCK_RATE, 298 &max_rate); 299 if (ret) { 300 dev_err(rpi->dev, "Failed to get clock %d max freq: %d\n", 301 id, ret); 302 return ERR_PTR(ret); 303 } 304 305 ret = devm_clk_hw_register(rpi->dev, &data->hw); 306 if (ret) 307 return ERR_PTR(ret); 308 309 clk_hw_set_rate_range(&data->hw, min_rate, max_rate); 310 311 if (variant->clkdev) { 312 ret = devm_clk_hw_register_clkdev(rpi->dev, &data->hw, 313 NULL, variant->clkdev); 314 if (ret) { 315 dev_err(rpi->dev, "Failed to initialize clkdev\n"); 316 return ERR_PTR(ret); 317 } 318 } 319 320 if (variant->min_rate) { 321 unsigned long rate; 322 323 clk_hw_set_rate_range(&data->hw, variant->min_rate, max_rate); 324 325 rate = raspberrypi_fw_get_rate(&data->hw, 0); 326 if (rate < variant->min_rate) { 327 ret = raspberrypi_fw_set_rate(&data->hw, variant->min_rate, 0); 328 if (ret) 329 return ERR_PTR(ret); 330 } 331 } 332 333 return &data->hw; 334} 335 336struct rpi_firmware_get_clocks_response { 337 u32 parent; 338 u32 id; 339}; 340 341static int raspberrypi_discover_clocks(struct raspberrypi_clk *rpi, 342 struct clk_hw_onecell_data *data) 343{ 344 struct rpi_firmware_get_clocks_response *clks; 345 int ret; 346 347 clks = devm_kcalloc(rpi->dev, 348 RPI_FIRMWARE_NUM_CLK_ID, sizeof(*clks), 349 GFP_KERNEL); 350 if (!clks) 351 return -ENOMEM; 352 353 ret = rpi_firmware_property(rpi->firmware, RPI_FIRMWARE_GET_CLOCKS, 354 clks, 355 sizeof(*clks) * RPI_FIRMWARE_NUM_CLK_ID); 356 if (ret) 357 return ret; 358 359 while (clks->id) { 360 struct raspberrypi_clk_variant *variant; 361 362 if (clks->id > RPI_FIRMWARE_NUM_CLK_ID) { 363 dev_err(rpi->dev, "Unknown clock id: %u", clks->id); 364 return -EINVAL; 365 } 366 367 variant = &raspberrypi_clk_variants[clks->id]; 368 if (variant->export) { 369 struct clk_hw *hw; 370 371 hw = raspberrypi_clk_register(rpi, clks->parent, 372 clks->id, variant); 373 if (IS_ERR(hw)) 374 return PTR_ERR(hw); 375 376 data->hws[clks->id] = hw; 377 data->num = clks->id + 1; 378 } 379 380 clks++; 381 } 382 383 return 0; 384} 385 386static int raspberrypi_clk_probe(struct platform_device *pdev) 387{ 388 struct clk_hw_onecell_data *clk_data; 389 struct device_node *firmware_node; 390 struct device *dev = &pdev->dev; 391 struct rpi_firmware *firmware; 392 struct raspberrypi_clk *rpi; 393 int ret; 394 395 /* 396 * We can be probed either through the an old-fashioned 397 * platform device registration or through a DT node that is a 398 * child of the firmware node. Handle both cases. 399 */ 400 if (dev->of_node) 401 firmware_node = of_get_parent(dev->of_node); 402 else 403 firmware_node = of_find_compatible_node(NULL, NULL, 404 "raspberrypi,bcm2835-firmware"); 405 if (!firmware_node) { 406 dev_err(dev, "Missing firmware node\n"); 407 return -ENOENT; 408 } 409 410 firmware = devm_rpi_firmware_get(&pdev->dev, firmware_node); 411 of_node_put(firmware_node); 412 if (!firmware) 413 return -EPROBE_DEFER; 414 415 rpi = devm_kzalloc(dev, sizeof(*rpi), GFP_KERNEL); 416 if (!rpi) 417 return -ENOMEM; 418 419 rpi->dev = dev; 420 rpi->firmware = firmware; 421 platform_set_drvdata(pdev, rpi); 422 423 clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, 424 RPI_FIRMWARE_NUM_CLK_ID), 425 GFP_KERNEL); 426 if (!clk_data) 427 return -ENOMEM; 428 429 ret = raspberrypi_discover_clocks(rpi, clk_data); 430 if (ret) 431 return ret; 432 433 ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, 434 clk_data); 435 if (ret) 436 return ret; 437 438 rpi->cpufreq = platform_device_register_data(dev, "raspberrypi-cpufreq", 439 -1, NULL, 0); 440 441 return 0; 442} 443 444static int raspberrypi_clk_remove(struct platform_device *pdev) 445{ 446 struct raspberrypi_clk *rpi = platform_get_drvdata(pdev); 447 448 platform_device_unregister(rpi->cpufreq); 449 450 return 0; 451} 452 453static const struct of_device_id raspberrypi_clk_match[] = { 454 { .compatible = "raspberrypi,firmware-clocks" }, 455 { }, 456}; 457MODULE_DEVICE_TABLE(of, raspberrypi_clk_match); 458 459static struct platform_driver raspberrypi_clk_driver = { 460 .driver = { 461 .name = "raspberrypi-clk", 462 .of_match_table = raspberrypi_clk_match, 463 }, 464 .probe = raspberrypi_clk_probe, 465 .remove = raspberrypi_clk_remove, 466}; 467module_platform_driver(raspberrypi_clk_driver); 468 469MODULE_AUTHOR("Nicolas Saenz Julienne <nsaenzjulienne@suse.de>"); 470MODULE_DESCRIPTION("Raspberry Pi firmware clock driver"); 471MODULE_LICENSE("GPL"); 472MODULE_ALIAS("platform:raspberrypi-clk");