brcm2708: update 4.1 patches
[openwrt.git] / target / linux / brcm2708 / patches-4.1 / 0136-cpufreq-bcm2835-Use-firmware-API.patch
1 From 020e1720dc926c944479da4ce0edd7508bc82d21 Mon Sep 17 00:00:00 2001
2 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
3 Date: Mon, 20 Jul 2015 12:18:36 +0200
4 Subject: [PATCH 136/171] cpufreq: bcm2835: Use firmware API
5 MIME-Version: 1.0
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
8
9 Use the new firmware API instead of the legacy mailbox API.
10
11 Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
12 ---
13  drivers/cpufreq/bcm2835-cpufreq.c | 117 +++++++++++++++++---------------------
14  1 file changed, 53 insertions(+), 64 deletions(-)
15
16 --- a/drivers/cpufreq/bcm2835-cpufreq.c
17 +++ b/drivers/cpufreq/bcm2835-cpufreq.c
18 @@ -26,7 +26,7 @@
19  #include <linux/init.h>
20  #include <linux/module.h>
21  #include <linux/cpufreq.h>
22 -#include <linux/platform_data/mailbox-bcm2708.h>
23 +#include <soc/bcm2835/raspberrypi-firmware.h>
24  
25  /* ---------- DEFINES ---------- */
26  /*#define CPUFREQ_DEBUG_ENABLE*/               /* enable debugging */
27 @@ -43,23 +43,6 @@
28  #define print_err(fmt,...) pr_err("%s:%s:%d: "fmt, MODULE_NAME, __func__,__LINE__, ##__VA_ARGS__)
29  #define print_info(fmt,...) pr_info("%s: "fmt, MODULE_NAME, ##__VA_ARGS__)
30  
31 -/* tag part of the message */
32 -struct vc_msg_tag {
33 -       uint32_t tag_id;                /* the message id */
34 -       uint32_t buffer_size;           /* size of the buffer (which in this case is always 8 bytes) */
35 -       uint32_t data_size;             /* amount of data being sent or received */
36 -       uint32_t dev_id;                /* the ID of the clock/voltage to get or set */
37 -       uint32_t val;                   /* the value (e.g. rate (in Hz)) to set */
38 -};
39 -
40 -/* message structure to be sent to videocore */
41 -struct vc_msg {
42 -       uint32_t msg_size;              /* simply, sizeof(struct vc_msg) */
43 -       uint32_t request_code;          /* holds various information like the success and number of bytes returned (refer to mailboxes wiki) */
44 -       struct vc_msg_tag tag;          /* the tag structure above to make */
45 -       uint32_t end_tag;               /* an end identifier, should be set to NULL */
46 -};
47 -
48  /* ---------- GLOBALS ---------- */
49  static struct cpufreq_driver bcm2835_cpufreq_driver;   /* the cpufreq driver global */
50  
51 @@ -74,62 +57,63 @@ static struct cpufreq_frequency_table bc
52    clk_rate either gets or sets the clock rates.
53   ===============================================
54  */
55 -static uint32_t bcm2835_cpufreq_set_clock(int cur_rate, int arm_rate)
56 +
57 +static int bcm2835_cpufreq_clock_property(u32 tag, u32 id, u32 *val)
58  {
59 -       int s, actual_rate=0;
60 -       struct vc_msg msg;
61 +       struct rpi_firmware *fw = rpi_firmware_get(NULL);
62 +       struct {
63 +               u32 id;
64 +               u32 val;
65 +       } packet;
66 +       int ret;
67 +
68 +       packet.id = id;
69 +       packet.val = *val;
70 +       ret = rpi_firmware_property(fw, tag, &packet, sizeof(packet));
71 +       if (ret)
72 +               return ret;
73  
74 -       /* wipe all previous message data */
75 -       memset(&msg, 0, sizeof msg);
76 +       *val = packet.val;
77  
78 -       msg.msg_size = sizeof msg;
79 +       return 0;
80 +}
81  
82 -       msg.tag.tag_id = VCMSG_SET_CLOCK_RATE;
83 -       msg.tag.buffer_size = 8;
84 -       msg.tag.data_size = 8;   /* we're sending the clock ID and the new rates which is a total of 2 words */
85 -       msg.tag.dev_id = VCMSG_ID_ARM_CLOCK;
86 -       msg.tag.val = arm_rate * 1000;
87 +static uint32_t bcm2835_cpufreq_set_clock(int cur_rate, int arm_rate)
88 +{
89 +       u32 rate = arm_rate * 1000;
90 +       int ret;
91  
92 -       /* send the message */
93 -       s = bcm_mailbox_property(&msg, sizeof msg);
94 +       ret = bcm2835_cpufreq_clock_property(RPI_FIRMWARE_SET_CLOCK_RATE, VCMSG_ID_ARM_CLOCK, &rate);
95 +       if (ret) {
96 +               print_err("Failed to set clock: %d (%d)\n", arm_rate, ret);
97 +               return 0;
98 +       }
99  
100 -       /* check if it was all ok and return the rate in KHz */
101 -       if (s == 0 && (msg.request_code & 0x80000000))
102 -               actual_rate = msg.tag.val/1000;
103 +       rate /= 1000;
104 +       print_debug("Setting new frequency = %d -> %d (actual %d)\n", cur_rate, arm_rate, rate);
105  
106 -       print_debug("Setting new frequency = %d -> %d (actual %d)\n", cur_rate, arm_rate, actual_rate);
107 -       return actual_rate;
108 +       return rate;
109  }
110  
111  static uint32_t bcm2835_cpufreq_get_clock(int tag)
112  {
113 -       int s;
114 -       int arm_rate = 0;
115 -       struct vc_msg msg;
116 -
117 -       /* wipe all previous message data */
118 -       memset(&msg, 0, sizeof msg);
119 -
120 -       msg.msg_size = sizeof msg;
121 -       msg.tag.tag_id = tag;
122 -       msg.tag.buffer_size = 8;
123 -       msg.tag.data_size = 4; /* we're just sending the clock ID which is one word long */
124 -       msg.tag.dev_id = VCMSG_ID_ARM_CLOCK;
125 -
126 -       /* send the message */
127 -       s = bcm_mailbox_property(&msg, sizeof msg);
128 -
129 -       /* check if it was all ok and return the rate in KHz */
130 -       if (s == 0 && (msg.request_code & 0x80000000))
131 -               arm_rate = msg.tag.val/1000;
132 -
133 -       print_debug("%s frequency = %d\n",
134 -               tag == VCMSG_GET_CLOCK_RATE ? "Current":
135 -               tag == VCMSG_GET_MIN_CLOCK ? "Min":
136 -               tag == VCMSG_GET_MAX_CLOCK ? "Max":
137 -               "Unexpected", arm_rate);
138 +       u32 rate;
139 +       int ret;
140 +
141 +       ret = bcm2835_cpufreq_clock_property(tag, VCMSG_ID_ARM_CLOCK, &rate);
142 +       if (ret) {
143 +               print_err("Failed to get clock (%d)\n", ret);
144 +               return 0;
145 +       }
146 +
147 +       rate /= 1000;
148 +       print_debug("%s frequency = %u\n",
149 +               tag == RPI_FIRMWARE_GET_CLOCK_RATE ? "Current":
150 +               tag == RPI_FIRMWARE_GET_MIN_CLOCK_RATE ? "Min":
151 +               tag == RPI_FIRMWARE_GET_MAX_CLOCK_RATE ? "Max":
152 +               "Unexpected", rate);
153  
154 -       return arm_rate;
155 +       return rate;
156  }
157  
158  /*
159 @@ -165,9 +149,14 @@ static int bcm2835_cpufreq_driver_init(s
160         /* measured value of how long it takes to change frequency */
161         const unsigned int transition_latency = 355000; /* ns */
162  
163 +       if (!rpi_firmware_get(NULL)) {
164 +               print_err("Firmware is not available\n");
165 +               return -ENODEV;
166 +       }
167 +
168         /* now find out what the maximum and minimum frequencies are */
169 -       bcm2835_freq_table[0].frequency = bcm2835_cpufreq_get_clock(VCMSG_GET_MIN_CLOCK);
170 -       bcm2835_freq_table[1].frequency = bcm2835_cpufreq_get_clock(VCMSG_GET_MAX_CLOCK);
171 +       bcm2835_freq_table[0].frequency = bcm2835_cpufreq_get_clock(RPI_FIRMWARE_GET_MIN_CLOCK_RATE);
172 +       bcm2835_freq_table[1].frequency = bcm2835_cpufreq_get_clock(RPI_FIRMWARE_GET_MAX_CLOCK_RATE);
173  
174         print_info("min=%d max=%d\n", bcm2835_freq_table[0].frequency, bcm2835_freq_table[1].frequency);
175         return cpufreq_generic_init(policy, bcm2835_freq_table, transition_latency);
176 @@ -201,8 +190,8 @@ static int bcm2835_cpufreq_driver_target
177  
178  static unsigned int bcm2835_cpufreq_driver_get(unsigned int cpu)
179  {
180 -       unsigned int actual_rate = bcm2835_cpufreq_get_clock(VCMSG_GET_CLOCK_RATE);
181 -       print_debug("%d: freq=%d\n", cpu, actual_rate);
182 +       unsigned int actual_rate = bcm2835_cpufreq_get_clock(RPI_FIRMWARE_GET_CLOCK_RATE);
183 +       print_debug("cpu%d: freq=%d\n", cpu, actual_rate);
184         return actual_rate <= bcm2835_freq_table[0].frequency ? bcm2835_freq_table[0].frequency : bcm2835_freq_table[1].frequency;
185  }
186