mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-25 08:21:14 +00:00
7d7aa2fd92
This change makes the names of Broadcom targets consistent by using the common notation based on SoC/CPU ID (which is used internally anyway), bcmXXXX instead of brcmXXXX. This is even used for target TITLE in make menuconfig already, only the short target name used brcm so far. Despite, since subtargets range from bcm2708 to bcm2711, it seems appropriate to use bcm27xx instead of bcm2708 (again, as already done for BOARDNAME). This also renames the packages brcm2708-userland and brcm2708-gpu-fw. Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de> Acked-by: Álvaro Fernández Rojas <noltari@gmail.com>
116 lines
3.7 KiB
Diff
116 lines
3.7 KiB
Diff
From f8e7e4a65b3f99452db67cfb7e21afc80b8af7f2 Mon Sep 17 00:00:00 2001
|
|
From: Phil Elwell <phil@raspberrypi.org>
|
|
Date: Mon, 6 Mar 2017 09:06:18 +0000
|
|
Subject: [PATCH] clk-bcm2835: Read max core clock from firmware
|
|
|
|
The VPU is responsible for managing the core clock, usually under
|
|
direction from the bcm2835-cpufreq driver but not via the clk-bcm2835
|
|
driver. Since the core frequency can change without warning, it is
|
|
safer to report the maximum clock rate to users of the core clock -
|
|
I2C, SPI and the mini UART - to err on the safe side when calculating
|
|
clock divisors.
|
|
|
|
If the DT node for the clock driver includes a reference to the
|
|
firmware node, use the firmware API to query the maximum core clock
|
|
instead of reading the divider registers.
|
|
|
|
Prior to this patch, a "100KHz" I2C bus was sometimes clocked at about
|
|
160KHz. In particular, switching to the 4.9 kernel was likely to break
|
|
SenseHAT usage on a Pi3.
|
|
|
|
Signed-off-by: Phil Elwell <phil@raspberrypi.org>
|
|
---
|
|
drivers/clk/bcm/clk-bcm2835.c | 39 ++++++++++++++++++++++++++++++++++-
|
|
1 file changed, 38 insertions(+), 1 deletion(-)
|
|
|
|
--- a/drivers/clk/bcm/clk-bcm2835.c
|
|
+++ b/drivers/clk/bcm/clk-bcm2835.c
|
|
@@ -44,6 +44,7 @@
|
|
#include <linux/platform_device.h>
|
|
#include <linux/slab.h>
|
|
#include <dt-bindings/clock/bcm2835.h>
|
|
+#include <soc/bcm2835/raspberrypi-firmware.h>
|
|
|
|
#define CM_PASSWORD 0x5a000000
|
|
|
|
@@ -298,6 +299,8 @@
|
|
#define LOCK_TIMEOUT_NS 100000000
|
|
#define BCM2835_MAX_FB_RATE 1750000000u
|
|
|
|
+#define VCMSG_ID_CORE_CLOCK 4
|
|
+
|
|
/*
|
|
* Names of clocks used within the driver that need to be replaced
|
|
* with an external parent's name. This array is in the order that
|
|
@@ -316,6 +319,7 @@ static const char *const cprman_parent_n
|
|
struct bcm2835_cprman {
|
|
struct device *dev;
|
|
void __iomem *regs;
|
|
+ struct rpi_firmware *fw;
|
|
spinlock_t regs_lock; /* spinlock for all clocks */
|
|
|
|
/*
|
|
@@ -998,6 +1002,30 @@ static unsigned long bcm2835_clock_get_r
|
|
return bcm2835_clock_rate_from_divisor(clock, parent_rate, div);
|
|
}
|
|
|
|
+static unsigned long bcm2835_clock_get_rate_vpu(struct clk_hw *hw,
|
|
+ unsigned long parent_rate)
|
|
+{
|
|
+ struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
|
|
+ struct bcm2835_cprman *cprman = clock->cprman;
|
|
+
|
|
+ if (cprman->fw) {
|
|
+ struct {
|
|
+ u32 id;
|
|
+ u32 val;
|
|
+ } packet;
|
|
+
|
|
+ packet.id = VCMSG_ID_CORE_CLOCK;
|
|
+ packet.val = 0;
|
|
+
|
|
+ if (!rpi_firmware_property(cprman->fw,
|
|
+ RPI_FIRMWARE_GET_MAX_CLOCK_RATE,
|
|
+ &packet, sizeof(packet)))
|
|
+ return packet.val;
|
|
+ }
|
|
+
|
|
+ return bcm2835_clock_get_rate(hw, parent_rate);
|
|
+}
|
|
+
|
|
static void bcm2835_clock_wait_busy(struct bcm2835_clock *clock)
|
|
{
|
|
struct bcm2835_cprman *cprman = clock->cprman;
|
|
@@ -1286,7 +1314,7 @@ static int bcm2835_vpu_clock_is_on(struc
|
|
*/
|
|
static const struct clk_ops bcm2835_vpu_clock_clk_ops = {
|
|
.is_prepared = bcm2835_vpu_clock_is_on,
|
|
- .recalc_rate = bcm2835_clock_get_rate,
|
|
+ .recalc_rate = bcm2835_clock_get_rate_vpu,
|
|
.set_rate = bcm2835_clock_set_rate,
|
|
.determine_rate = bcm2835_clock_determine_rate,
|
|
.set_parent = bcm2835_clock_set_parent,
|
|
@@ -2165,6 +2193,7 @@ static int bcm2835_clk_probe(struct plat
|
|
struct resource *res;
|
|
const struct bcm2835_clk_desc *desc;
|
|
const size_t asize = ARRAY_SIZE(clk_desc_array);
|
|
+ struct device_node *fw_node;
|
|
size_t i;
|
|
u32 clk_id;
|
|
int ret;
|
|
@@ -2182,6 +2211,14 @@ static int bcm2835_clk_probe(struct plat
|
|
if (IS_ERR(cprman->regs))
|
|
return PTR_ERR(cprman->regs);
|
|
|
|
+ fw_node = of_parse_phandle(dev->of_node, "firmware", 0);
|
|
+ if (fw_node) {
|
|
+ struct rpi_firmware *fw = rpi_firmware_get(NULL);
|
|
+ if (!fw)
|
|
+ return -EPROBE_DEFER;
|
|
+ cprman->fw = fw;
|
|
+ }
|
|
+
|
|
memset(bcm2835_clk_claimed, 0, sizeof(bcm2835_clk_claimed));
|
|
for (i = 0;
|
|
!of_property_read_u32_index(pdev->dev.of_node, "claim-clocks",
|