^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Raspberry Pi driver for firmware controlled clocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Even though clk-bcm2835 provides an interface to the hardware registers for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * the system clocks we've had to factor out 'pllb' as the firmware 'owns' it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * We're not allowed to change it directly as we might race with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * over-temperature and under-voltage protections provided by the firmware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Copyright (C) 2019 Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/clkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/clk-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <soc/bcm2835/raspberrypi-firmware.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) enum rpi_firmware_clk_id {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) RPI_FIRMWARE_EMMC_CLK_ID = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) RPI_FIRMWARE_UART_CLK_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) RPI_FIRMWARE_ARM_CLK_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) RPI_FIRMWARE_CORE_CLK_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) RPI_FIRMWARE_V3D_CLK_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) RPI_FIRMWARE_H264_CLK_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) RPI_FIRMWARE_ISP_CLK_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) RPI_FIRMWARE_SDRAM_CLK_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) RPI_FIRMWARE_PIXEL_CLK_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) RPI_FIRMWARE_PWM_CLK_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) RPI_FIRMWARE_HEVC_CLK_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) RPI_FIRMWARE_EMMC2_CLK_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) RPI_FIRMWARE_M2MC_CLK_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) RPI_FIRMWARE_PIXEL_BVB_CLK_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) RPI_FIRMWARE_NUM_CLK_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) static char *rpi_firmware_clk_names[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) [RPI_FIRMWARE_EMMC_CLK_ID] = "emmc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) [RPI_FIRMWARE_UART_CLK_ID] = "uart",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) [RPI_FIRMWARE_ARM_CLK_ID] = "arm",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) [RPI_FIRMWARE_CORE_CLK_ID] = "core",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) [RPI_FIRMWARE_V3D_CLK_ID] = "v3d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) [RPI_FIRMWARE_H264_CLK_ID] = "h264",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) [RPI_FIRMWARE_ISP_CLK_ID] = "isp",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) [RPI_FIRMWARE_SDRAM_CLK_ID] = "sdram",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) [RPI_FIRMWARE_PIXEL_CLK_ID] = "pixel",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) [RPI_FIRMWARE_PWM_CLK_ID] = "pwm",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) [RPI_FIRMWARE_HEVC_CLK_ID] = "hevc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) [RPI_FIRMWARE_EMMC2_CLK_ID] = "emmc2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) [RPI_FIRMWARE_M2MC_CLK_ID] = "m2mc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) [RPI_FIRMWARE_PIXEL_BVB_CLK_ID] = "pixel-bvb",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define RPI_FIRMWARE_STATE_ENABLE_BIT BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define RPI_FIRMWARE_STATE_WAIT_BIT BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct raspberrypi_clk {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct rpi_firmware *firmware;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct platform_device *cpufreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct raspberrypi_clk_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) struct clk_hw hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) unsigned int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) struct raspberrypi_clk *rpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * Structure of the message passed to Raspberry Pi's firmware in order to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * change clock rates. The 'disable_turbo' option is only available to the ARM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * clock (pllb) which we enable by default as turbo mode will alter multiple
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * clocks at once.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * Even though we're able to access the clock registers directly we're bound to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * use the firmware interface as the firmware ultimately takes care of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * mitigating overheating/undervoltage situations and we would be changing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * frequencies behind his back.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * For more information on the firmware interface check:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) struct raspberrypi_firmware_prop {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) __le32 id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) __le32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) __le32 disable_turbo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) static int raspberrypi_clock_property(struct rpi_firmware *firmware,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) const struct raspberrypi_clk_data *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) u32 tag, u32 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) struct raspberrypi_firmware_prop msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) .id = cpu_to_le32(data->id),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) .val = cpu_to_le32(*val),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) .disable_turbo = cpu_to_le32(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) ret = rpi_firmware_property(firmware, tag, &msg, sizeof(msg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) *val = le32_to_cpu(msg.val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) static int raspberrypi_fw_is_prepared(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) struct raspberrypi_clk_data *data =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) container_of(hw, struct raspberrypi_clk_data, hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct raspberrypi_clk *rpi = data->rpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) u32 val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) ret = raspberrypi_clock_property(rpi->firmware, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) RPI_FIRMWARE_GET_CLOCK_STATE, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) return !!(val & RPI_FIRMWARE_STATE_ENABLE_BIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) static unsigned long raspberrypi_fw_get_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) struct raspberrypi_clk_data *data =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) container_of(hw, struct raspberrypi_clk_data, hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) struct raspberrypi_clk *rpi = data->rpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) u32 val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) ret = raspberrypi_clock_property(rpi->firmware, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) RPI_FIRMWARE_GET_CLOCK_RATE, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) static int raspberrypi_fw_set_rate(struct clk_hw *hw, unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) struct raspberrypi_clk_data *data =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) container_of(hw, struct raspberrypi_clk_data, hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) struct raspberrypi_clk *rpi = data->rpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) u32 _rate = rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) ret = raspberrypi_clock_property(rpi->firmware, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) RPI_FIRMWARE_SET_CLOCK_RATE, &_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) dev_err_ratelimited(rpi->dev, "Failed to change %s frequency: %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) clk_hw_get_name(hw), ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) static int raspberrypi_fw_dumb_determine_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) struct clk_rate_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) * The firmware will do the rounding but that isn't part of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) * the interface with the firmware, so we just do our best
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) req->rate = clamp(req->rate, req->min_rate, req->max_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) static const struct clk_ops raspberrypi_firmware_clk_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) .is_prepared = raspberrypi_fw_is_prepared,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) .recalc_rate = raspberrypi_fw_get_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) .determine_rate = raspberrypi_fw_dumb_determine_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) .set_rate = raspberrypi_fw_set_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) static struct clk_hw *raspberrypi_clk_register(struct raspberrypi_clk *rpi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) unsigned int parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) unsigned int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) struct raspberrypi_clk_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) struct clk_init_data init = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) u32 min_rate, max_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) data = devm_kzalloc(rpi->dev, sizeof(*data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) data->rpi = rpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) data->id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) init.name = devm_kasprintf(rpi->dev, GFP_KERNEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) "fw-clk-%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) rpi_firmware_clk_names[id]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) init.ops = &raspberrypi_firmware_clk_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) init.flags = CLK_GET_RATE_NOCACHE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) data->hw.init = &init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) ret = raspberrypi_clock_property(rpi->firmware, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) RPI_FIRMWARE_GET_MIN_CLOCK_RATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) &min_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) dev_err(rpi->dev, "Failed to get clock %d min freq: %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) id, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) return ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) ret = raspberrypi_clock_property(rpi->firmware, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) RPI_FIRMWARE_GET_MAX_CLOCK_RATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) &max_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) dev_err(rpi->dev, "Failed to get clock %d max freq: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) id, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) ret = devm_clk_hw_register(rpi->dev, &data->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) return ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) clk_hw_set_rate_range(&data->hw, min_rate, max_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) if (id == RPI_FIRMWARE_ARM_CLK_ID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) ret = devm_clk_hw_register_clkdev(rpi->dev, &data->hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) NULL, "cpu0");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) dev_err(rpi->dev, "Failed to initialize clkdev\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) return ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) return &data->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) struct rpi_firmware_get_clocks_response {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) u32 parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) u32 id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static int raspberrypi_discover_clocks(struct raspberrypi_clk *rpi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) struct clk_hw_onecell_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) struct rpi_firmware_get_clocks_response *clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) clks = devm_kcalloc(rpi->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) sizeof(*clks), RPI_FIRMWARE_NUM_CLK_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if (!clks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) ret = rpi_firmware_property(rpi->firmware, RPI_FIRMWARE_GET_CLOCKS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) clks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) sizeof(*clks) * RPI_FIRMWARE_NUM_CLK_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) while (clks->id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) struct clk_hw *hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) switch (clks->id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) case RPI_FIRMWARE_ARM_CLK_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) case RPI_FIRMWARE_CORE_CLK_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) case RPI_FIRMWARE_M2MC_CLK_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) case RPI_FIRMWARE_V3D_CLK_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) case RPI_FIRMWARE_PIXEL_BVB_CLK_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) hw = raspberrypi_clk_register(rpi, clks->parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) clks->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) if (IS_ERR(hw))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) return PTR_ERR(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) data->hws[clks->id] = hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) data->num = clks->id + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) clks++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) static int raspberrypi_clk_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) struct clk_hw_onecell_data *clk_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) struct device_node *firmware_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) struct rpi_firmware *firmware;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) struct raspberrypi_clk *rpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) * We can be probed either through the an old-fashioned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) * platform device registration or through a DT node that is a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) * child of the firmware node. Handle both cases.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if (dev->of_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) firmware_node = of_get_parent(dev->of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) firmware_node = of_find_compatible_node(NULL, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) "raspberrypi,bcm2835-firmware");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) if (!firmware_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) dev_err(dev, "Missing firmware node\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) firmware = rpi_firmware_get(firmware_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) of_node_put(firmware_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) if (!firmware)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) return -EPROBE_DEFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) rpi = devm_kzalloc(dev, sizeof(*rpi), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) if (!rpi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) rpi->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) rpi->firmware = firmware;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) platform_set_drvdata(pdev, rpi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) clk_data = devm_kzalloc(dev, struct_size(clk_data, hws,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) RPI_FIRMWARE_NUM_CLK_ID),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) if (!clk_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) ret = raspberrypi_discover_clocks(rpi, clk_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) clk_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) rpi->cpufreq = platform_device_register_data(dev, "raspberrypi-cpufreq",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) -1, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) static int raspberrypi_clk_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) struct raspberrypi_clk *rpi = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) platform_device_unregister(rpi->cpufreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) static const struct of_device_id raspberrypi_clk_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) { .compatible = "raspberrypi,firmware-clocks" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) MODULE_DEVICE_TABLE(of, raspberrypi_clk_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) static struct platform_driver raspberrypi_clk_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) .name = "raspberrypi-clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) .of_match_table = raspberrypi_clk_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) .probe = raspberrypi_clk_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) .remove = raspberrypi_clk_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) module_platform_driver(raspberrypi_clk_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) MODULE_AUTHOR("Nicolas Saenz Julienne <nsaenzjulienne@suse.de>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) MODULE_DESCRIPTION("Raspberry Pi firmware clock driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) MODULE_ALIAS("platform:raspberrypi-clk");