Message ID | 20220815-rpi-fix-4k-60-v2-3-983276b83f62@cerno.tech (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | drm/vc4: Fix the core clock behaviour | expand |
Quoting Maxime Ripard (2022-09-20 05:50:22) > The firmware allows to query for its clocks the operating range of a > given clock. We'll need this for some drivers (KMS, in particular) to > infer the state of some configuration options, so let's create a > function to do so. > > Signed-off-by: Maxime Ripard <maxime@cerno.tech> > Acked-by: Stephen Boyd <sboyd@kernel.org>
Hi Maxime, Am 20.09.22 um 14:50 schrieb Maxime Ripard: > The firmware allows to query for its clocks the operating range of a > given clock. We'll need this for some drivers (KMS, in particular) to > infer the state of some configuration options, so let's create a > function to do so. > > Signed-off-by: Maxime Ripard <maxime@cerno.tech> > > diff --git a/drivers/firmware/raspberrypi.c b/drivers/firmware/raspberrypi.c > index b916e1e171f8..c4b9ea70f5a7 100644 > --- a/drivers/firmware/raspberrypi.c > +++ b/drivers/firmware/raspberrypi.c > @@ -228,6 +228,21 @@ static void rpi_register_clk_driver(struct device *dev) > -1, NULL, 0); > } > > +unsigned int rpi_firmware_clk_get_max_rate(struct rpi_firmware *fw, unsigned int id) > +{ > + struct rpi_firmware_clk_rate_request msg = > + RPI_FIRMWARE_CLK_RATE_REQUEST(id); > + int ret; > + > + ret = rpi_firmware_property(fw, RPI_FIRMWARE_GET_MAX_CLOCK_RATE, > + &msg, sizeof(msg)); > + if (ret) > + return 0; > + > + return le32_to_cpu(msg.rate); > +} > +EXPORT_SYMBOL_GPL(rpi_firmware_clk_get_max_rate); > + > static void rpi_firmware_delete(struct kref *kref) > { > struct rpi_firmware *fw = container_of(kref, struct rpi_firmware, > diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h > index 74c7bcc1ac2a..10248c370229 100644 > --- a/include/soc/bcm2835/raspberrypi-firmware.h > +++ b/include/soc/bcm2835/raspberrypi-firmware.h > @@ -154,12 +154,32 @@ enum rpi_firmware_clk_id { > RPI_FIRMWARE_NUM_CLK_ID, > }; > > +/** > + * struct rpi_firmware_clk_rate_request - Firmware Request for a rate > + * @id: ID of the clock being queried > + * @rate: Rate in Hertz. Set by the firmware. > + * > + * Used by @RPI_FIRMWARE_GET_CLOCK_RATE, @RPI_FIRMWARE_GET_CLOCK_MEASURED, > + * @RPI_FIRMWARE_GET_MAX_CLOCK_RATE and @RPI_FIRMWARE_GET_MIN_CLOCK_RATE. > + */ > +struct rpi_firmware_clk_rate_request { > + __le32 id; > + __le32 rate; > +} __packed; > + > +#define RPI_FIRMWARE_CLK_RATE_REQUEST(_id) \ > + { \ > + .id = _id, \ > + } > + > #if IS_ENABLED(CONFIG_RASPBERRYPI_FIRMWARE) > int rpi_firmware_property(struct rpi_firmware *fw, > u32 tag, void *data, size_t len); > int rpi_firmware_property_list(struct rpi_firmware *fw, > void *data, size_t tag_size); > void rpi_firmware_put(struct rpi_firmware *fw); > +unsigned int rpi_firmware_clk_get_max_rate(struct rpi_firmware *fw, > + unsigned int id); > struct device_node *rpi_firmware_find_node(void); > struct rpi_firmware *rpi_firmware_get(struct device_node *firmware_node); > struct rpi_firmware *devm_rpi_firmware_get(struct device *dev, > @@ -179,6 +199,12 @@ static inline int rpi_firmware_property_list(struct rpi_firmware *fw, > > static inline void rpi_firmware_put(struct rpi_firmware *fw) { } > > +static inline unsigned int rpi_firmware_clk_get_max_rate(struct rpi_firmware *fw, > + unsigned int id) > +{ > + return UINT_MAX; In case the driver is disabled the function return UINT_MAX, but in case the firmware doesn't support RPI_FIRMWARE_GET_MAX_CLOCK_RATE it returns 0. This looks a little bit inconsistent to me. > +} > + > static inline struct device_node *rpi_firmware_find_node(void) > { > return NULL; >
diff --git a/drivers/firmware/raspberrypi.c b/drivers/firmware/raspberrypi.c index b916e1e171f8..c4b9ea70f5a7 100644 --- a/drivers/firmware/raspberrypi.c +++ b/drivers/firmware/raspberrypi.c @@ -228,6 +228,21 @@ static void rpi_register_clk_driver(struct device *dev) -1, NULL, 0); } +unsigned int rpi_firmware_clk_get_max_rate(struct rpi_firmware *fw, unsigned int id) +{ + struct rpi_firmware_clk_rate_request msg = + RPI_FIRMWARE_CLK_RATE_REQUEST(id); + int ret; + + ret = rpi_firmware_property(fw, RPI_FIRMWARE_GET_MAX_CLOCK_RATE, + &msg, sizeof(msg)); + if (ret) + return 0; + + return le32_to_cpu(msg.rate); +} +EXPORT_SYMBOL_GPL(rpi_firmware_clk_get_max_rate); + static void rpi_firmware_delete(struct kref *kref) { struct rpi_firmware *fw = container_of(kref, struct rpi_firmware, diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h index 74c7bcc1ac2a..10248c370229 100644 --- a/include/soc/bcm2835/raspberrypi-firmware.h +++ b/include/soc/bcm2835/raspberrypi-firmware.h @@ -154,12 +154,32 @@ enum rpi_firmware_clk_id { RPI_FIRMWARE_NUM_CLK_ID, }; +/** + * struct rpi_firmware_clk_rate_request - Firmware Request for a rate + * @id: ID of the clock being queried + * @rate: Rate in Hertz. Set by the firmware. + * + * Used by @RPI_FIRMWARE_GET_CLOCK_RATE, @RPI_FIRMWARE_GET_CLOCK_MEASURED, + * @RPI_FIRMWARE_GET_MAX_CLOCK_RATE and @RPI_FIRMWARE_GET_MIN_CLOCK_RATE. + */ +struct rpi_firmware_clk_rate_request { + __le32 id; + __le32 rate; +} __packed; + +#define RPI_FIRMWARE_CLK_RATE_REQUEST(_id) \ + { \ + .id = _id, \ + } + #if IS_ENABLED(CONFIG_RASPBERRYPI_FIRMWARE) int rpi_firmware_property(struct rpi_firmware *fw, u32 tag, void *data, size_t len); int rpi_firmware_property_list(struct rpi_firmware *fw, void *data, size_t tag_size); void rpi_firmware_put(struct rpi_firmware *fw); +unsigned int rpi_firmware_clk_get_max_rate(struct rpi_firmware *fw, + unsigned int id); struct device_node *rpi_firmware_find_node(void); struct rpi_firmware *rpi_firmware_get(struct device_node *firmware_node); struct rpi_firmware *devm_rpi_firmware_get(struct device *dev, @@ -179,6 +199,12 @@ static inline int rpi_firmware_property_list(struct rpi_firmware *fw, static inline void rpi_firmware_put(struct rpi_firmware *fw) { } +static inline unsigned int rpi_firmware_clk_get_max_rate(struct rpi_firmware *fw, + unsigned int id) +{ + return UINT_MAX; +} + static inline struct device_node *rpi_firmware_find_node(void) { return NULL;
The firmware allows to query for its clocks the operating range of a given clock. We'll need this for some drivers (KMS, in particular) to infer the state of some configuration options, so let's create a function to do so. Signed-off-by: Maxime Ripard <maxime@cerno.tech>