2
0

200-mips-bmips-automatically-detect-CPU-frequency.patch 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. From 0377ad93031d3e51c2afe44231241185f684b6af Mon Sep 17 00:00:00 2001
  2. From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <[email protected]>
  3. Date: Fri, 5 Mar 2021 15:14:32 +0100
  4. Subject: [PATCH] mips: bmips: automatically detect CPU frequency
  5. MIME-Version: 1.0
  6. Content-Type: text/plain; charset=UTF-8
  7. Content-Transfer-Encoding: 8bit
  8. Some BCM63xx SoCs support multiple CPU frequencies depending on HW config.
  9. Signed-off-by: Álvaro Fernández Rojas <[email protected]>
  10. ---
  11. arch/mips/bmips/setup.c | 197 ++++++++++++++++++++++++++++++++++++++--
  12. 1 file changed, 190 insertions(+), 7 deletions(-)
  13. --- a/arch/mips/bmips/setup.c
  14. +++ b/arch/mips/bmips/setup.c
  15. @@ -31,13 +31,52 @@
  16. #define RELO_NORMAL_VEC BIT(18)
  17. +#define REG_BCM6318_SOB ((void __iomem *)CKSEG1ADDR(0x10000900))
  18. +#define BCM6318_FREQ_SHIFT 23
  19. +#define BCM6318_FREQ_MASK (0x3 << BCM6318_FREQ_SHIFT)
  20. +
  21. #define REG_BCM6328_OTP ((void __iomem *)CKSEG1ADDR(0x1000062c))
  22. #define BCM6328_TP1_DISABLED BIT(9)
  23. +#define REG_BCM6328_MISC_SB ((void __iomem *)CKSEG1ADDR(0x10001a40))
  24. +#define BCM6328_FCVO_SHIFT 7
  25. +#define BCM6328_FCVO_MASK (0x1f << BCM6328_FCVO_SHIFT)
  26. +
  27. +#define REG_BCM6358_DDR_PLLC ((void __iomem *)0xfffe12b8)
  28. +#define BCM6358_PLLC_M1_SHIFT 0
  29. +#define BCM6358_PLLC_M1_MASK (0xff << BCM6358_PLLC_M1_SHIFT)
  30. +#define BCM6358_PLLC_N1_SHIFT 23
  31. +#define BCM6358_PLLC_N1_MASK (0x3f << BCM6358_PLLC_N1_SHIFT)
  32. +#define BCM6358_PLLC_N2_SHIFT 29
  33. +#define BCM6358_PLLC_N2_MASK (0x7 << BCM6358_PLLC_N2_SHIFT)
  34. +
  35. +#define REG_BCM6362_MISC_SB ((void __iomem *)CKSEG1ADDR(0x10001814))
  36. +#define BCM6362_FCVO_SHIFT 1
  37. +#define BCM6362_FCVO_MASK (0x1f << BCM6362_FCVO_SHIFT)
  38. +
  39. +#define REG_BCM6368_DDR_PLLC ((void __iomem *)CKSEG1ADDR(0x100012a0))
  40. +#define BCM6368_PLLC_P1_SHIFT 0
  41. +#define BCM6368_PLLC_P1_MASK (0xf << BCM6368_PLLC_P1_SHIFT)
  42. +#define BCM6368_PLLC_P2_SHIFT 4
  43. +#define BCM6368_PLLC_P2_MASK (0xf << BCM6368_PLLC_P2_SHIFT)
  44. +#define BCM6368_PLLC_NDIV_SHIFT 16
  45. +#define BCM6368_PLLC_NDIV_MASK (0x1ff << BCM6368_PLLC_NDIV_SHIFT)
  46. +#define REG_BCM6368_DDR_PLLD ((void __iomem *)CKSEG1ADDR(0x100012a4))
  47. +#define BCM6368_PLLD_MDIV_SHIFT 0
  48. +#define BCM6368_PLLD_MDIV_MASK (0xff << BCM6368_PLLD_MDIV_SHIFT)
  49. +
  50. +#define REG_BCM63268_MISC_SB ((void __iomem *)CKSEG1ADDR(0x10001814))
  51. +#define BCM63268_FCVO_SHIFT 21
  52. +#define BCM63268_FCVO_MASK (0xf << BCM63268_FCVO_SHIFT)
  53. extern bool bmips_rac_flush_disable;
  54. static const unsigned long kbase = VMLINUX_LOAD_ADDRESS & 0xfff00000;
  55. +struct bmips_cpufreq {
  56. + const char *compatible;
  57. + u32 (*cpu_freq)(void);
  58. +};
  59. +
  60. struct bmips_quirk {
  61. const char *compatible;
  62. void (*quirk_fn)(void);
  63. @@ -142,17 +181,161 @@ const char *get_system_type(void)
  64. return "Generic BMIPS kernel";
  65. }
  66. +static u32 bcm6318_cpufreq(void)
  67. +{
  68. + u32 val = __raw_readl(REG_BCM6318_SOB);
  69. +
  70. + switch ((val & BCM6318_FREQ_MASK) >> BCM6318_FREQ_SHIFT) {
  71. + case 0:
  72. + return 166000000;
  73. + case 2:
  74. + return 250000000;
  75. + case 3:
  76. + return 333000000;
  77. + case 1:
  78. + return 400000000;
  79. + default:
  80. + return 0;
  81. + }
  82. +}
  83. +
  84. +static u32 bcm6328_cpufreq(void)
  85. +{
  86. + u32 val = __raw_readl(REG_BCM6328_MISC_SB);
  87. +
  88. + switch ((val & BCM6328_FCVO_MASK) >> BCM6328_FCVO_SHIFT) {
  89. + case 0x12:
  90. + case 0x14:
  91. + case 0x19:
  92. + return 160000000;
  93. + case 0x1c:
  94. + return 192000000;
  95. + case 0x13:
  96. + case 0x15:
  97. + return 200000000;
  98. + case 0x1a:
  99. + return 384000000;
  100. + case 0x16:
  101. + return 400000000;
  102. + default:
  103. + return 320000000;
  104. + }
  105. +}
  106. +
  107. +static u32 bcm6358_cpufreq(void)
  108. +{
  109. + u32 val, n1, n2, m1;
  110. +
  111. + val = __raw_readl(REG_BCM6358_DDR_PLLC);
  112. + n1 = (val & BCM6358_PLLC_N1_MASK) >> BCM6358_PLLC_N1_SHIFT;
  113. + n2 = (val & BCM6358_PLLC_N2_MASK) >> BCM6358_PLLC_N2_SHIFT;
  114. + m1 = (val & BCM6358_PLLC_M1_MASK) >> BCM6358_PLLC_M1_SHIFT;
  115. +
  116. + return (16 * 1000000 * n1 * n2) / m1;
  117. +}
  118. +
  119. +static u32 bcm6362_cpufreq(void)
  120. +{
  121. + u32 val = __raw_readl(REG_BCM6362_MISC_SB);
  122. +
  123. + switch ((val & BCM6362_FCVO_MASK) >> BCM6362_FCVO_SHIFT) {
  124. + case 0x04:
  125. + case 0x0c:
  126. + case 0x14:
  127. + case 0x1c:
  128. + return 160000000;
  129. + case 0x15:
  130. + case 0x1d:
  131. + return 200000000;
  132. + case 0x03:
  133. + case 0x0b:
  134. + case 0x13:
  135. + case 0x1b:
  136. + return 240000000;
  137. + case 0x07:
  138. + case 0x17:
  139. + return 384000000;
  140. + case 0x05:
  141. + case 0x0e:
  142. + case 0x16:
  143. + case 0x1e:
  144. + case 0x1f:
  145. + return 400000000;
  146. + case 0x06:
  147. + return 440000000;
  148. + default:
  149. + return 320000000;
  150. + }
  151. +}
  152. +
  153. +static u32 bcm6368_cpufreq(void)
  154. +{
  155. + u32 val, p1, p2, ndiv, m1;
  156. +
  157. + val = __raw_readl(REG_BCM6368_DDR_PLLC);
  158. + p1 = (val & BCM6368_PLLC_P1_MASK) >> BCM6368_PLLC_P1_SHIFT;
  159. + p2 = (val & BCM6368_PLLC_P2_MASK) >> BCM6368_PLLC_P2_SHIFT;
  160. + ndiv = (val & BCM6368_PLLC_NDIV_MASK) >>
  161. + BCM6368_PLLC_NDIV_SHIFT;
  162. +
  163. + val = __raw_readl(REG_BCM6368_DDR_PLLD);
  164. + m1 = (val & BCM6368_PLLD_MDIV_MASK) >> BCM6368_PLLD_MDIV_SHIFT;
  165. +
  166. + return (((64 * 1000000) / p1) * p2 * ndiv) / m1;
  167. +}
  168. +
  169. +static u32 bcm63268_cpufreq(void)
  170. +{
  171. + u32 val = __raw_readl(REG_BCM63268_MISC_SB);
  172. +
  173. + switch ((val & BCM63268_FCVO_MASK) >> BCM63268_FCVO_SHIFT) {
  174. + case 0x3:
  175. + case 0xe:
  176. + return 320000000;
  177. + case 0xa:
  178. + return 333000000;
  179. + case 0x2:
  180. + case 0xb:
  181. + case 0xf:
  182. + return 400000000;
  183. + default:
  184. + return 0;
  185. + }
  186. +}
  187. +
  188. +static const struct bmips_cpufreq bmips_cpufreq_list[] = {
  189. + { "brcm,bcm6318", &bcm6318_cpufreq },
  190. + { "brcm,bcm6328", &bcm6328_cpufreq },
  191. + { "brcm,bcm6358", &bcm6358_cpufreq },
  192. + { "brcm,bcm6362", &bcm6362_cpufreq },
  193. + { "brcm,bcm6368", &bcm6368_cpufreq },
  194. + { "brcm,bcm63268", &bcm63268_cpufreq },
  195. + { /* sentinel */ }
  196. +};
  197. +
  198. void __init plat_time_init(void)
  199. {
  200. + const struct bmips_cpufreq *cf;
  201. struct device_node *np;
  202. - u32 freq;
  203. + u32 freq = 0;
  204. - np = of_find_node_by_name(NULL, "cpus");
  205. - if (!np)
  206. - panic("missing 'cpus' DT node");
  207. - if (of_property_read_u32(np, "mips-hpt-frequency", &freq) < 0)
  208. - panic("missing 'mips-hpt-frequency' property");
  209. - of_node_put(np);
  210. + for (cf = bmips_cpufreq_list; cf->cpu_freq; cf++) {
  211. + if (of_flat_dt_is_compatible(of_get_flat_dt_root(),
  212. + cf->compatible)) {
  213. + freq = cf->cpu_freq() / 2;
  214. + printk("%s detected @ %u MHz\n", cf->compatible, freq / 500000);
  215. + break;
  216. + }
  217. + }
  218. +
  219. + if (!freq) {
  220. + np = of_find_node_by_name(NULL, "cpus");
  221. + if (!np)
  222. + panic("missing 'cpus' DT node");
  223. + if (of_property_read_u32(np, "mips-hpt-frequency", &freq) < 0)
  224. + panic("missing 'mips-hpt-frequency' property");
  225. + of_node_put(np);
  226. + }
  227. mips_hpt_frequency = freq;
  228. }