Skip to content

Clock Framework Improvements, and removal of clock requests API #4940

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 46 commits into from
Apr 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
60641c0
clk: Introduce Kunit Tests for the framework
mripard Jan 19, 2022
f720731
clk: Always clamp the rounded rate
mripard May 5, 2021
93f15f0
clk: Use clamp instead of open-coding our own
mripard Jan 17, 2022
3c8b635
clk: Always set the rate on clk_set_range_rate
mripard Jan 17, 2022
709fce3
clk: Add clk_drop_range
mripard Jan 17, 2022
954a948
clk: test: Test clk_set_rate_range on orphan mux
mripard Mar 25, 2022
beb900a
clk: Drop the rate range on clk_put()
mripard Mar 25, 2022
cc7cc16
clk: tests: Add test suites description
mripard Apr 1, 2022
0e8f5ca
clk: tests: Add reference to the orphan mux bug report
mripard Apr 1, 2022
bc2b933
clk: tests: Add tests for uncached clock
mripard Apr 8, 2022
4504a04
clk: tests: Add tests for single parent mux
mripard Apr 7, 2022
c91d62f
clk: tests: Add tests for mux with multiple parents
mripard Apr 7, 2022
12f881d
clk: tests: Add some tests for orphan with multiple parents
mripard Apr 2, 2022
5e57e76
clk: Take into account uncached clocks in clk_set_rate_range()
mripard Apr 8, 2022
f69b8e6
clk: Fix clk_get_parent() documentation
mripard Apr 1, 2022
b8a5a2a
clk: Set req_rate on reparenting
mripard Apr 1, 2022
2a52a4b
clk: Skip set_rate_range if our clock is orphan
mripard Apr 1, 2022
8b71589
clk: Add our request boundaries in clk_core_init_rate_req
mripard Apr 2, 2022
1c38104
clk: Change clk_core_init_rate_req prototype
mripard Apr 2, 2022
956b17a
clk: Introduce clk_hw_init_rate_request()
mripard Apr 2, 2022
1019a97
clk: Add missing clk_core_init_rate_req calls
mripard Apr 2, 2022
b11bd77
clk: Remove redundant clk_core_init_rate_req() call
mripard Apr 2, 2022
f9516cb
clk: Switch from __clk_determine_rate to clk_core_round_rate_nolock
mripard Apr 2, 2022
0b1ef8e
clk: Introduce clk_core_has_parent()
mripard Apr 7, 2022
088d950
clk: Stop forwarding clk_rate_requests to the parent
mripard Apr 2, 2022
9316b49
clk: Zero the clk_rate_request structure
mripard Apr 2, 2022
a46aa62
clk: Test the clock pointer in clk_hw_get_name()
mripard Apr 5, 2022
293abcc
clk: bcm: rpi: Add variant structure
mripard Jan 17, 2022
a96fb8e
clk: bcm: rpi: Set a default minimum rate
mripard Jan 17, 2022
1638e88
clk: bcm: rpi: Run some clocks at the minimum rate allowed
mripard Jan 17, 2022
b80133e
Revert "drm/vc4: kms: Move clock request to our HVS state"
mripard Mar 16, 2022
d1c1658
Revert "drm/vc4: Increase the core clock based on HVS load"
mripard Mar 16, 2022
5d6dd9c
Revert "drm/vc4: hdmi: Convert to the new clock request API"
mripard Mar 16, 2022
cb2ecc4
Revert "bcm2835-unicam: Switch to new clock api"
mripard Mar 16, 2022
0741f5d
Revert "rpivid: Switch to new clock api"
mripard Mar 16, 2022
8e54e1b
Revert "clk: requests: Dereference the request pointer after the check"
mripard Mar 16, 2022
5a72231
Revert "clk: requests: Ignore if the pointer is null"
mripard Mar 16, 2022
078f56c
Revert "clk: Introduce a clock request API"
mripard Mar 16, 2022
926cace
clk: Add clk_get_rate_range
mripard Apr 15, 2022
f17e3ee
clk: tests: Add some tests for clk_get_rate_range()
mripard Apr 15, 2022
c3c5f15
clk: tests: Add missing test case for ranges
mripard Apr 15, 2022
dcff89c
drm/vc4: hdmi: Rework hdmi_enable_4kp60 detection
mripard Mar 24, 2022
3836e29
drm/vc4: kms: Warn if clk_set_min_rate fails
mripard Mar 25, 2022
d3db8e7
drm/vc4: Make sure we don't end up with a core clock too high
mripard Mar 25, 2022
3f984da
drm/vc4: kms: Use maximum FIFO load for the HVS clock rate
mripard Apr 13, 2022
ec18e22
rpivid: Use clk_get_max_rate()
mripard Apr 15, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions drivers/clk/.kunitconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
CONFIG_KUNIT=y
CONFIG_COMMON_CLK=y
CONFIG_CLK_KUNIT_TEST=y
8 changes: 8 additions & 0 deletions drivers/clk/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -427,4 +427,12 @@ source "drivers/clk/x86/Kconfig"
source "drivers/clk/xilinx/Kconfig"
source "drivers/clk/zynqmp/Kconfig"

# Kunit test cases
config CLK_KUNIT_TEST
tristate "Basic Clock Framework Kunit Tests" if !KUNIT_ALL_TESTS
depends on KUNIT
default KUNIT_ALL_TESTS
help
Kunit tests for the common clock framework.

endif
1 change: 1 addition & 0 deletions drivers/clk/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# common clock types
obj-$(CONFIG_HAVE_CLK) += clk-devres.o clk-bulk.o clkdev.o
obj-$(CONFIG_COMMON_CLK) += clk.o
obj-$(CONFIG_CLK_KUNIT_TEST) += clk_test.o
obj-$(CONFIG_COMMON_CLK) += clk-divider.o
obj-$(CONFIG_COMMON_CLK) += clk-fixed-factor.o
obj-$(CONFIG_COMMON_CLK) += clk-fixed-rate.o
Expand Down
139 changes: 119 additions & 20 deletions drivers/clk/bcm/clk-raspberrypi.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ static char *rpi_firmware_clk_names[] = {
#define RPI_FIRMWARE_STATE_ENABLE_BIT BIT(0)
#define RPI_FIRMWARE_STATE_WAIT_BIT BIT(1)

struct raspberrypi_clk_variant;

struct raspberrypi_clk {
struct device *dev;
struct rpi_firmware *firmware;
Expand All @@ -68,10 +70,81 @@ struct raspberrypi_clk_data {
struct clk_hw hw;

unsigned int id;
struct raspberrypi_clk_variant *variant;

struct raspberrypi_clk *rpi;
};

struct raspberrypi_clk_variant {
bool export;
char *clkdev;
unsigned long min_rate;
bool minimize;
};

static struct raspberrypi_clk_variant
raspberrypi_clk_variants[RPI_FIRMWARE_NUM_CLK_ID] = {
[RPI_FIRMWARE_ARM_CLK_ID] = {
.export = true,
.clkdev = "cpu0",
},
[RPI_FIRMWARE_CORE_CLK_ID] = {
.export = true,

/*
* The clock is shared between the HVS and the CSI
* controllers, on the BCM2711 and will change depending
* on the pixels composited on the HVS and the capture
* resolution on Unicam.
*
* Since the rate can get quite large, and we need to
* coordinate between both driver instances, let's
* always use the minimum the drivers will let us.
*/
.minimize = true,
},
[RPI_FIRMWARE_M2MC_CLK_ID] = {
.export = true,

/*
* If we boot without any cable connected to any of the
* HDMI connector, the firmware will skip the HSM
* initialization and leave it with a rate of 0,
* resulting in a bus lockup when we're accessing the
* registers even if it's enabled.
*
* Let's put a sensible default so that we don't end up
* in this situation.
*/
.min_rate = 120000000,

/*
* The clock is shared between the two HDMI controllers
* on the BCM2711 and will change depending on the
* resolution output on each. Since the rate can get
* quite large, and we need to coordinate between both
* driver instances, let's always use the minimum the
* drivers will let us.
*/
.minimize = true,
},
[RPI_FIRMWARE_V3D_CLK_ID] = {
.export = true,
},
[RPI_FIRMWARE_HEVC_CLK_ID] = {
.export = true,
},
[RPI_FIRMWARE_PIXEL_BVB_CLK_ID] = {
.export = true,
},
[RPI_FIRMWARE_VEC_CLK_ID] = {
.export = true,
},
[RPI_FIRMWARE_PIXEL_CLK_ID] = {
.export = true,
},
};

/*
* Structure of the message passed to Raspberry Pi's firmware in order to
* change clock rates. The 'disable_turbo' option is only available to the ARM
Expand Down Expand Up @@ -167,12 +240,26 @@ static int raspberrypi_fw_set_rate(struct clk_hw *hw, unsigned long rate,
static int raspberrypi_fw_dumb_determine_rate(struct clk_hw *hw,
struct clk_rate_request *req)
{
struct raspberrypi_clk_data *data =
container_of(hw, struct raspberrypi_clk_data, hw);
struct raspberrypi_clk_variant *variant = data->variant;

/*
* The firmware will do the rounding but that isn't part of
* the interface with the firmware, so we just do our best
* here.
*/

req->rate = clamp(req->rate, req->min_rate, req->max_rate);

/*
* We want to aggressively reduce the clock rate here, so let's
* just ignore the requested rate and return the bare minimum
* rate we can get away with.
*/
if (variant->minimize && req->min_rate > 0)
req->rate = req->min_rate;

return 0;
}

Expand All @@ -185,7 +272,8 @@ static const struct clk_ops raspberrypi_firmware_clk_ops = {

static struct clk_hw *raspberrypi_clk_register(struct raspberrypi_clk *rpi,
unsigned int parent,
unsigned int id)
unsigned int id,
struct raspberrypi_clk_variant *variant)
{
struct raspberrypi_clk_data *data;
struct clk_init_data init = {};
Expand All @@ -197,6 +285,7 @@ static struct clk_hw *raspberrypi_clk_register(struct raspberrypi_clk *rpi,
return ERR_PTR(-ENOMEM);
data->rpi = rpi;
data->id = id;
data->variant = variant;

init.name = devm_kasprintf(rpi->dev, GFP_KERNEL,
"fw-clk-%s",
Expand Down Expand Up @@ -230,15 +319,28 @@ static struct clk_hw *raspberrypi_clk_register(struct raspberrypi_clk *rpi,

clk_hw_set_rate_range(&data->hw, min_rate, max_rate);

if (id == RPI_FIRMWARE_ARM_CLK_ID) {
if (variant->clkdev) {
ret = devm_clk_hw_register_clkdev(rpi->dev, &data->hw,
NULL, "cpu0");
NULL, variant->clkdev);
if (ret) {
dev_err(rpi->dev, "Failed to initialize clkdev\n");
return ERR_PTR(ret);
}
}

if (variant->min_rate) {
unsigned long rate;

clk_hw_set_rate_range(&data->hw, variant->min_rate, max_rate);

rate = raspberrypi_fw_get_rate(&data->hw, 0);
if (rate < variant->min_rate) {
ret = raspberrypi_fw_set_rate(&data->hw, variant->min_rate, 0);
if (ret)
return ERR_PTR(ret);
}
}

return &data->hw;
}

Expand Down Expand Up @@ -266,30 +368,27 @@ static int raspberrypi_discover_clocks(struct raspberrypi_clk *rpi,
return ret;

while (clks->id) {
struct clk_hw *hw;

switch (clks->id) {
case RPI_FIRMWARE_ARM_CLK_ID:
case RPI_FIRMWARE_CORE_CLK_ID:
case RPI_FIRMWARE_M2MC_CLK_ID:
case RPI_FIRMWARE_V3D_CLK_ID:
case RPI_FIRMWARE_HEVC_CLK_ID:
case RPI_FIRMWARE_PIXEL_BVB_CLK_ID:
case RPI_FIRMWARE_VEC_CLK_ID:
case RPI_FIRMWARE_PIXEL_CLK_ID:
struct raspberrypi_clk_variant *variant;

if (clks->id > RPI_FIRMWARE_NUM_CLK_ID) {
dev_err(rpi->dev, "Unknown clock id: %u", clks->id);
return -EINVAL;
}

variant = &raspberrypi_clk_variants[clks->id];
if (variant->export) {
struct clk_hw *hw;

hw = raspberrypi_clk_register(rpi, clks->parent,
clks->id);
clks->id, variant);
if (IS_ERR(hw))
return PTR_ERR(hw);

data->hws[clks->id] = hw;
data->num = clks->id + 1;
fallthrough;

default:
clks++;
break;
}

clks++;
}

return 0;
Expand Down
Loading