950-0157-clk-bcm2835-Add-leaf-clock-measurement-support-disab.patch 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. From 546bac0479e51024027f8c8820f912573643b101 Mon Sep 17 00:00:00 2001
  2. From: Eric Anholt <[email protected]>
  3. Date: Wed, 18 Jan 2017 07:31:57 +1100
  4. Subject: [PATCH] clk: bcm2835: Add leaf clock measurement support, disabled by
  5. default
  6. This proved incredibly useful during debugging of the DSI driver, to
  7. see if our clocks were running at rate we requested. Let's leave it
  8. here for the next person interacting with clocks on the platform (and
  9. so that hopefully we can just hook it up to debugfs some day).
  10. Signed-off-by: Eric Anholt <[email protected]>
  11. Signed-off-by: Stephen Boyd <[email protected]>
  12. (cherry picked from commit 3f9195811d8d829556c4cd88d3f9e56a80d5ba60)
  13. ---
  14. drivers/clk/bcm/clk-bcm2835.c | 144 ++++++++++++++++++++++++++++++++++--------
  15. 1 file changed, 119 insertions(+), 25 deletions(-)
  16. --- a/drivers/clk/bcm/clk-bcm2835.c
  17. +++ b/drivers/clk/bcm/clk-bcm2835.c
  18. @@ -39,6 +39,7 @@
  19. #include <linux/clk.h>
  20. #include <linux/clk/bcm2835.h>
  21. #include <linux/debugfs.h>
  22. +#include <linux/delay.h>
  23. #include <linux/module.h>
  24. #include <linux/of.h>
  25. #include <linux/platform_device.h>
  26. @@ -98,7 +99,8 @@
  27. #define CM_SMIDIV 0x0b4
  28. /* no definition for 0x0b8 and 0x0bc */
  29. #define CM_TCNTCTL 0x0c0
  30. -#define CM_TCNTDIV 0x0c4
  31. +# define CM_TCNT_SRC1_SHIFT 12
  32. +#define CM_TCNTCNT 0x0c4
  33. #define CM_TECCTL 0x0c8
  34. #define CM_TECDIV 0x0cc
  35. #define CM_TD0CTL 0x0d0
  36. @@ -338,6 +340,61 @@ static inline u32 cprman_read(struct bcm
  37. return readl(cprman->regs + reg);
  38. }
  39. +/* Does a cycle of measuring a clock through the TCNT clock, which may
  40. + * source from many other clocks in the system.
  41. + */
  42. +static unsigned long bcm2835_measure_tcnt_mux(struct bcm2835_cprman *cprman,
  43. + u32 tcnt_mux)
  44. +{
  45. + u32 osccount = 19200; /* 1ms */
  46. + u32 count;
  47. + ktime_t timeout;
  48. +
  49. + spin_lock(&cprman->regs_lock);
  50. +
  51. + cprman_write(cprman, CM_TCNTCTL, CM_KILL);
  52. +
  53. + cprman_write(cprman, CM_TCNTCTL,
  54. + (tcnt_mux & CM_SRC_MASK) |
  55. + (tcnt_mux >> CM_SRC_BITS) << CM_TCNT_SRC1_SHIFT);
  56. +
  57. + cprman_write(cprman, CM_OSCCOUNT, osccount);
  58. +
  59. + /* do a kind delay at the start */
  60. + mdelay(1);
  61. +
  62. + /* Finish off whatever is left of OSCCOUNT */
  63. + timeout = ktime_add_ns(ktime_get(), LOCK_TIMEOUT_NS);
  64. + while (cprman_read(cprman, CM_OSCCOUNT)) {
  65. + if (ktime_after(ktime_get(), timeout)) {
  66. + dev_err(cprman->dev, "timeout waiting for OSCCOUNT\n");
  67. + count = 0;
  68. + goto out;
  69. + }
  70. + cpu_relax();
  71. + }
  72. +
  73. + /* Wait for BUSY to clear. */
  74. + timeout = ktime_add_ns(ktime_get(), LOCK_TIMEOUT_NS);
  75. + while (cprman_read(cprman, CM_TCNTCTL) & CM_BUSY) {
  76. + if (ktime_after(ktime_get(), timeout)) {
  77. + dev_err(cprman->dev, "timeout waiting for !BUSY\n");
  78. + count = 0;
  79. + goto out;
  80. + }
  81. + cpu_relax();
  82. + }
  83. +
  84. + count = cprman_read(cprman, CM_TCNTCNT);
  85. +
  86. + cprman_write(cprman, CM_TCNTCTL, 0);
  87. +
  88. +out:
  89. + spin_unlock(&cprman->regs_lock);
  90. +
  91. + return count * 1000;
  92. +}
  93. +
  94. static int bcm2835_debugfs_regset(struct bcm2835_cprman *cprman, u32 base,
  95. struct debugfs_reg32 *regs, size_t nregs,
  96. struct dentry *dentry)
  97. @@ -473,6 +530,8 @@ struct bcm2835_clock_data {
  98. bool is_vpu_clock;
  99. bool is_mash_clock;
  100. +
  101. + u32 tcnt_mux;
  102. };
  103. struct bcm2835_gate_data {
  104. @@ -1014,6 +1073,17 @@ static int bcm2835_clock_on(struct clk_h
  105. CM_GATE);
  106. spin_unlock(&cprman->regs_lock);
  107. + /* Debug code to measure the clock once it's turned on to see
  108. + * if it's ticking at the rate we expect.
  109. + */
  110. + if (data->tcnt_mux && false) {
  111. + dev_info(cprman->dev,
  112. + "clk %s: rate %ld, measure %ld\n",
  113. + data->name,
  114. + clk_hw_get_rate(hw),
  115. + bcm2835_measure_tcnt_mux(cprman, data->tcnt_mux));
  116. + }
  117. +
  118. return 0;
  119. }
  120. @@ -1780,7 +1850,8 @@ static const struct bcm2835_clk_desc clk
  121. .ctl_reg = CM_OTPCTL,
  122. .div_reg = CM_OTPDIV,
  123. .int_bits = 4,
  124. - .frac_bits = 0),
  125. + .frac_bits = 0,
  126. + .tcnt_mux = 6),
  127. /*
  128. * Used for a 1Mhz clock for the system clocksource, and also used
  129. * bythe watchdog timer and the camera pulse generator.
  130. @@ -1814,13 +1885,15 @@ static const struct bcm2835_clk_desc clk
  131. .ctl_reg = CM_H264CTL,
  132. .div_reg = CM_H264DIV,
  133. .int_bits = 4,
  134. - .frac_bits = 8),
  135. + .frac_bits = 8,
  136. + .tcnt_mux = 1),
  137. [BCM2835_CLOCK_ISP] = REGISTER_VPU_CLK(
  138. .name = "isp",
  139. .ctl_reg = CM_ISPCTL,
  140. .div_reg = CM_ISPDIV,
  141. .int_bits = 4,
  142. - .frac_bits = 8),
  143. + .frac_bits = 8,
  144. + .tcnt_mux = 2),
  145. /*
  146. * Secondary SDRAM clock. Used for low-voltage modes when the PLL
  147. @@ -1831,13 +1904,15 @@ static const struct bcm2835_clk_desc clk
  148. .ctl_reg = CM_SDCCTL,
  149. .div_reg = CM_SDCDIV,
  150. .int_bits = 6,
  151. - .frac_bits = 0),
  152. + .frac_bits = 0,
  153. + .tcnt_mux = 3),
  154. [BCM2835_CLOCK_V3D] = REGISTER_VPU_CLK(
  155. .name = "v3d",
  156. .ctl_reg = CM_V3DCTL,
  157. .div_reg = CM_V3DDIV,
  158. .int_bits = 4,
  159. - .frac_bits = 8),
  160. + .frac_bits = 8,
  161. + .tcnt_mux = 4),
  162. /*
  163. * VPU clock. This doesn't have an enable bit, since it drives
  164. * the bus for everything else, and is special so it doesn't need
  165. @@ -1851,7 +1926,8 @@ static const struct bcm2835_clk_desc clk
  166. .int_bits = 12,
  167. .frac_bits = 8,
  168. .flags = CLK_IS_CRITICAL,
  169. - .is_vpu_clock = true),
  170. + .is_vpu_clock = true,
  171. + .tcnt_mux = 5),
  172. /* clocks with per parent mux */
  173. [BCM2835_CLOCK_AVEO] = REGISTER_PER_CLK(
  174. @@ -1859,19 +1935,22 @@ static const struct bcm2835_clk_desc clk
  175. .ctl_reg = CM_AVEOCTL,
  176. .div_reg = CM_AVEODIV,
  177. .int_bits = 4,
  178. - .frac_bits = 0),
  179. + .frac_bits = 0,
  180. + .tcnt_mux = 38),
  181. [BCM2835_CLOCK_CAM0] = REGISTER_PER_CLK(
  182. .name = "cam0",
  183. .ctl_reg = CM_CAM0CTL,
  184. .div_reg = CM_CAM0DIV,
  185. .int_bits = 4,
  186. - .frac_bits = 8),
  187. + .frac_bits = 8,
  188. + .tcnt_mux = 14),
  189. [BCM2835_CLOCK_CAM1] = REGISTER_PER_CLK(
  190. .name = "cam1",
  191. .ctl_reg = CM_CAM1CTL,
  192. .div_reg = CM_CAM1DIV,
  193. .int_bits = 4,
  194. - .frac_bits = 8),
  195. + .frac_bits = 8,
  196. + .tcnt_mux = 15),
  197. [BCM2835_CLOCK_DFT] = REGISTER_PER_CLK(
  198. .name = "dft",
  199. .ctl_reg = CM_DFTCTL,
  200. @@ -1883,7 +1962,8 @@ static const struct bcm2835_clk_desc clk
  201. .ctl_reg = CM_DPICTL,
  202. .div_reg = CM_DPIDIV,
  203. .int_bits = 4,
  204. - .frac_bits = 8),
  205. + .frac_bits = 8,
  206. + .tcnt_mux = 17),
  207. /* Arasan EMMC clock */
  208. [BCM2835_CLOCK_EMMC] = REGISTER_PER_CLK(
  209. @@ -1891,7 +1971,8 @@ static const struct bcm2835_clk_desc clk
  210. .ctl_reg = CM_EMMCCTL,
  211. .div_reg = CM_EMMCDIV,
  212. .int_bits = 4,
  213. - .frac_bits = 8),
  214. + .frac_bits = 8,
  215. + .tcnt_mux = 39),
  216. /* General purpose (GPIO) clocks */
  217. [BCM2835_CLOCK_GP0] = REGISTER_PER_CLK(
  218. @@ -1900,7 +1981,8 @@ static const struct bcm2835_clk_desc clk
  219. .div_reg = CM_GP0DIV,
  220. .int_bits = 12,
  221. .frac_bits = 12,
  222. - .is_mash_clock = true),
  223. + .is_mash_clock = true,
  224. + .tcnt_mux = 20),
  225. [BCM2835_CLOCK_GP1] = REGISTER_PER_CLK(
  226. .name = "gp1",
  227. .ctl_reg = CM_GP1CTL,
  228. @@ -1908,7 +1990,8 @@ static const struct bcm2835_clk_desc clk
  229. .int_bits = 12,
  230. .frac_bits = 12,
  231. .flags = CLK_IS_CRITICAL,
  232. - .is_mash_clock = true),
  233. + .is_mash_clock = true,
  234. + .tcnt_mux = 21),
  235. [BCM2835_CLOCK_GP2] = REGISTER_PER_CLK(
  236. .name = "gp2",
  237. .ctl_reg = CM_GP2CTL,
  238. @@ -1923,40 +2006,46 @@ static const struct bcm2835_clk_desc clk
  239. .ctl_reg = CM_HSMCTL,
  240. .div_reg = CM_HSMDIV,
  241. .int_bits = 4,
  242. - .frac_bits = 8),
  243. + .frac_bits = 8,
  244. + .tcnt_mux = 22),
  245. [BCM2835_CLOCK_PCM] = REGISTER_PER_CLK(
  246. .name = "pcm",
  247. .ctl_reg = CM_PCMCTL,
  248. .div_reg = CM_PCMDIV,
  249. .int_bits = 12,
  250. .frac_bits = 12,
  251. - .is_mash_clock = true),
  252. + .is_mash_clock = true,
  253. + .tcnt_mux = 23),
  254. [BCM2835_CLOCK_PWM] = REGISTER_PER_CLK(
  255. .name = "pwm",
  256. .ctl_reg = CM_PWMCTL,
  257. .div_reg = CM_PWMDIV,
  258. .int_bits = 12,
  259. .frac_bits = 12,
  260. - .is_mash_clock = true),
  261. + .is_mash_clock = true,
  262. + .tcnt_mux = 24),
  263. [BCM2835_CLOCK_SLIM] = REGISTER_PER_CLK(
  264. .name = "slim",
  265. .ctl_reg = CM_SLIMCTL,
  266. .div_reg = CM_SLIMDIV,
  267. .int_bits = 12,
  268. .frac_bits = 12,
  269. - .is_mash_clock = true),
  270. + .is_mash_clock = true,
  271. + .tcnt_mux = 25),
  272. [BCM2835_CLOCK_SMI] = REGISTER_PER_CLK(
  273. .name = "smi",
  274. .ctl_reg = CM_SMICTL,
  275. .div_reg = CM_SMIDIV,
  276. .int_bits = 4,
  277. - .frac_bits = 8),
  278. + .frac_bits = 8,
  279. + .tcnt_mux = 27),
  280. [BCM2835_CLOCK_UART] = REGISTER_PER_CLK(
  281. .name = "uart",
  282. .ctl_reg = CM_UARTCTL,
  283. .div_reg = CM_UARTDIV,
  284. .int_bits = 10,
  285. - .frac_bits = 12),
  286. + .frac_bits = 12,
  287. + .tcnt_mux = 28),
  288. /* TV encoder clock. Only operating frequency is 108Mhz. */
  289. [BCM2835_CLOCK_VEC] = REGISTER_PER_CLK(
  290. @@ -1969,7 +2058,8 @@ static const struct bcm2835_clk_desc clk
  291. * Allow rate change propagation only on PLLH_AUX which is
  292. * assigned index 7 in the parent array.
  293. */
  294. - .set_rate_parent = BIT(7)),
  295. + .set_rate_parent = BIT(7),
  296. + .tcnt_mux = 29),
  297. /* dsi clocks */
  298. [BCM2835_CLOCK_DSI0E] = REGISTER_PER_CLK(
  299. @@ -1977,25 +2067,29 @@ static const struct bcm2835_clk_desc clk
  300. .ctl_reg = CM_DSI0ECTL,
  301. .div_reg = CM_DSI0EDIV,
  302. .int_bits = 4,
  303. - .frac_bits = 8),
  304. + .frac_bits = 8,
  305. + .tcnt_mux = 18),
  306. [BCM2835_CLOCK_DSI1E] = REGISTER_PER_CLK(
  307. .name = "dsi1e",
  308. .ctl_reg = CM_DSI1ECTL,
  309. .div_reg = CM_DSI1EDIV,
  310. .int_bits = 4,
  311. - .frac_bits = 8),
  312. + .frac_bits = 8,
  313. + .tcnt_mux = 19),
  314. [BCM2835_CLOCK_DSI0P] = REGISTER_DSI0_CLK(
  315. .name = "dsi0p",
  316. .ctl_reg = CM_DSI0PCTL,
  317. .div_reg = CM_DSI0PDIV,
  318. .int_bits = 0,
  319. - .frac_bits = 0),
  320. + .frac_bits = 0,
  321. + .tcnt_mux = 12),
  322. [BCM2835_CLOCK_DSI1P] = REGISTER_DSI1_CLK(
  323. .name = "dsi1p",
  324. .ctl_reg = CM_DSI1PCTL,
  325. .div_reg = CM_DSI1PDIV,
  326. .int_bits = 0,
  327. - .frac_bits = 0),
  328. + .frac_bits = 0,
  329. + .tcnt_mux = 13),
  330. /* the gates */