diff options
Diffstat (limited to 'target/linux/brcm2708/patches-4.1/0136-cpufreq-bcm2835-Use-firmware-API.patch')
-rw-r--r-- | target/linux/brcm2708/patches-4.1/0136-cpufreq-bcm2835-Use-firmware-API.patch | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/target/linux/brcm2708/patches-4.1/0136-cpufreq-bcm2835-Use-firmware-API.patch b/target/linux/brcm2708/patches-4.1/0136-cpufreq-bcm2835-Use-firmware-API.patch new file mode 100644 index 0000000..0dc3d38 --- /dev/null +++ b/target/linux/brcm2708/patches-4.1/0136-cpufreq-bcm2835-Use-firmware-API.patch @@ -0,0 +1,186 @@ +From 65ae931012f463feeb8cece70dfc829f2cd2b6b4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org> +Date: Mon, 20 Jul 2015 12:18:36 +0200 +Subject: [PATCH 136/203] cpufreq: bcm2835: Use firmware API +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Use the new firmware API instead of the legacy mailbox API. + +Signed-off-by: Noralf Trønnes <noralf@tronnes.org> +--- + drivers/cpufreq/bcm2835-cpufreq.c | 117 +++++++++++++++++--------------------- + 1 file changed, 53 insertions(+), 64 deletions(-) + +--- a/drivers/cpufreq/bcm2835-cpufreq.c ++++ b/drivers/cpufreq/bcm2835-cpufreq.c +@@ -26,7 +26,7 @@ + #include <linux/init.h> + #include <linux/module.h> + #include <linux/cpufreq.h> +-#include <linux/platform_data/mailbox-bcm2708.h> ++#include <soc/bcm2835/raspberrypi-firmware.h> + + /* ---------- DEFINES ---------- */ + /*#define CPUFREQ_DEBUG_ENABLE*/ /* enable debugging */ +@@ -43,23 +43,6 @@ + #define print_err(fmt,...) pr_err("%s:%s:%d: "fmt, MODULE_NAME, __func__,__LINE__, ##__VA_ARGS__) + #define print_info(fmt,...) pr_info("%s: "fmt, MODULE_NAME, ##__VA_ARGS__) + +-/* tag part of the message */ +-struct vc_msg_tag { +- uint32_t tag_id; /* the message id */ +- uint32_t buffer_size; /* size of the buffer (which in this case is always 8 bytes) */ +- uint32_t data_size; /* amount of data being sent or received */ +- uint32_t dev_id; /* the ID of the clock/voltage to get or set */ +- uint32_t val; /* the value (e.g. rate (in Hz)) to set */ +-}; +- +-/* message structure to be sent to videocore */ +-struct vc_msg { +- uint32_t msg_size; /* simply, sizeof(struct vc_msg) */ +- uint32_t request_code; /* holds various information like the success and number of bytes returned (refer to mailboxes wiki) */ +- struct vc_msg_tag tag; /* the tag structure above to make */ +- uint32_t end_tag; /* an end identifier, should be set to NULL */ +-}; +- + /* ---------- GLOBALS ---------- */ + static struct cpufreq_driver bcm2835_cpufreq_driver; /* the cpufreq driver global */ + +@@ -74,62 +57,63 @@ static struct cpufreq_frequency_table bc + clk_rate either gets or sets the clock rates. + =============================================== + */ +-static uint32_t bcm2835_cpufreq_set_clock(int cur_rate, int arm_rate) ++ ++static int bcm2835_cpufreq_clock_property(u32 tag, u32 id, u32 *val) + { +- int s, actual_rate=0; +- struct vc_msg msg; ++ struct rpi_firmware *fw = rpi_firmware_get(NULL); ++ struct { ++ u32 id; ++ u32 val; ++ } packet; ++ int ret; ++ ++ packet.id = id; ++ packet.val = *val; ++ ret = rpi_firmware_property(fw, tag, &packet, sizeof(packet)); ++ if (ret) ++ return ret; + +- /* wipe all previous message data */ +- memset(&msg, 0, sizeof msg); ++ *val = packet.val; + +- msg.msg_size = sizeof msg; ++ return 0; ++} + +- msg.tag.tag_id = VCMSG_SET_CLOCK_RATE; +- msg.tag.buffer_size = 8; +- msg.tag.data_size = 8; /* we're sending the clock ID and the new rates which is a total of 2 words */ +- msg.tag.dev_id = VCMSG_ID_ARM_CLOCK; +- msg.tag.val = arm_rate * 1000; ++static uint32_t bcm2835_cpufreq_set_clock(int cur_rate, int arm_rate) ++{ ++ u32 rate = arm_rate * 1000; ++ int ret; + +- /* send the message */ +- s = bcm_mailbox_property(&msg, sizeof msg); ++ ret = bcm2835_cpufreq_clock_property(RPI_FIRMWARE_SET_CLOCK_RATE, VCMSG_ID_ARM_CLOCK, &rate); ++ if (ret) { ++ print_err("Failed to set clock: %d (%d)\n", arm_rate, ret); ++ return 0; ++ } + +- /* check if it was all ok and return the rate in KHz */ +- if (s == 0 && (msg.request_code & 0x80000000)) +- actual_rate = msg.tag.val/1000; ++ rate /= 1000; ++ print_debug("Setting new frequency = %d -> %d (actual %d)\n", cur_rate, arm_rate, rate); + +- print_debug("Setting new frequency = %d -> %d (actual %d)\n", cur_rate, arm_rate, actual_rate); +- return actual_rate; ++ return rate; + } + + static uint32_t bcm2835_cpufreq_get_clock(int tag) + { +- int s; +- int arm_rate = 0; +- struct vc_msg msg; +- +- /* wipe all previous message data */ +- memset(&msg, 0, sizeof msg); +- +- msg.msg_size = sizeof msg; +- msg.tag.tag_id = tag; +- msg.tag.buffer_size = 8; +- msg.tag.data_size = 4; /* we're just sending the clock ID which is one word long */ +- msg.tag.dev_id = VCMSG_ID_ARM_CLOCK; +- +- /* send the message */ +- s = bcm_mailbox_property(&msg, sizeof msg); +- +- /* check if it was all ok and return the rate in KHz */ +- if (s == 0 && (msg.request_code & 0x80000000)) +- arm_rate = msg.tag.val/1000; +- +- print_debug("%s frequency = %d\n", +- tag == VCMSG_GET_CLOCK_RATE ? "Current": +- tag == VCMSG_GET_MIN_CLOCK ? "Min": +- tag == VCMSG_GET_MAX_CLOCK ? "Max": +- "Unexpected", arm_rate); ++ u32 rate; ++ int ret; ++ ++ ret = bcm2835_cpufreq_clock_property(tag, VCMSG_ID_ARM_CLOCK, &rate); ++ if (ret) { ++ print_err("Failed to get clock (%d)\n", ret); ++ return 0; ++ } ++ ++ rate /= 1000; ++ print_debug("%s frequency = %u\n", ++ tag == RPI_FIRMWARE_GET_CLOCK_RATE ? "Current": ++ tag == RPI_FIRMWARE_GET_MIN_CLOCK_RATE ? "Min": ++ tag == RPI_FIRMWARE_GET_MAX_CLOCK_RATE ? "Max": ++ "Unexpected", rate); + +- return arm_rate; ++ return rate; + } + + /* +@@ -165,9 +149,14 @@ static int bcm2835_cpufreq_driver_init(s + /* measured value of how long it takes to change frequency */ + const unsigned int transition_latency = 355000; /* ns */ + ++ if (!rpi_firmware_get(NULL)) { ++ print_err("Firmware is not available\n"); ++ return -ENODEV; ++ } ++ + /* now find out what the maximum and minimum frequencies are */ +- bcm2835_freq_table[0].frequency = bcm2835_cpufreq_get_clock(VCMSG_GET_MIN_CLOCK); +- bcm2835_freq_table[1].frequency = bcm2835_cpufreq_get_clock(VCMSG_GET_MAX_CLOCK); ++ bcm2835_freq_table[0].frequency = bcm2835_cpufreq_get_clock(RPI_FIRMWARE_GET_MIN_CLOCK_RATE); ++ bcm2835_freq_table[1].frequency = bcm2835_cpufreq_get_clock(RPI_FIRMWARE_GET_MAX_CLOCK_RATE); + + print_info("min=%d max=%d\n", bcm2835_freq_table[0].frequency, bcm2835_freq_table[1].frequency); + return cpufreq_generic_init(policy, bcm2835_freq_table, transition_latency); +@@ -201,8 +190,8 @@ static int bcm2835_cpufreq_driver_target + + static unsigned int bcm2835_cpufreq_driver_get(unsigned int cpu) + { +- unsigned int actual_rate = bcm2835_cpufreq_get_clock(VCMSG_GET_CLOCK_RATE); +- print_debug("%d: freq=%d\n", cpu, actual_rate); ++ unsigned int actual_rate = bcm2835_cpufreq_get_clock(RPI_FIRMWARE_GET_CLOCK_RATE); ++ print_debug("cpu%d: freq=%d\n", cpu, actual_rate); + return actual_rate <= bcm2835_freq_table[0].frequency ? bcm2835_freq_table[0].frequency : bcm2835_freq_table[1].frequency; + } + |