clk-en7523.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. #include <linux/delay.h>
  3. #include <linux/clk-provider.h>
  4. #include <linux/of.h>
  5. #include <linux/of_address.h>
  6. #include <linux/of_device.h>
  7. #include <linux/platform_device.h>
  8. #include <dt-bindings/clock/en7523-clk.h>
  9. #define REG_PCI_CONTROL 0x88
  10. #define REG_PCI_CONTROL_PERSTOUT BIT(29)
  11. #define REG_PCI_CONTROL_PERSTOUT1 BIT(26)
  12. #define REG_PCI_CONTROL_REFCLK_EN1 BIT(22)
  13. #define REG_GSW_CLK_DIV_SEL 0x1b4
  14. #define REG_EMI_CLK_DIV_SEL 0x1b8
  15. #define REG_BUS_CLK_DIV_SEL 0x1bc
  16. #define REG_SPI_CLK_DIV_SEL 0x1c4
  17. #define REG_SPI_CLK_FREQ_SEL 0x1c8
  18. #define REG_NPU_CLK_DIV_SEL 0x1fc
  19. #define REG_CRYPTO_CLKSRC 0x200
  20. #define REG_RESET_CONTROL 0x834
  21. #define REG_RESET_CONTROL_PCIEHB BIT(29)
  22. #define REG_RESET_CONTROL_PCIE1 BIT(27)
  23. #define REG_RESET_CONTROL_PCIE2 BIT(26)
  24. struct en_clk_desc {
  25. int id;
  26. const char *name;
  27. u32 base_reg;
  28. u8 base_bits;
  29. u8 base_shift;
  30. union {
  31. const unsigned int *base_values;
  32. unsigned int base_value;
  33. };
  34. size_t n_base_values;
  35. u16 div_reg;
  36. u8 div_bits;
  37. u8 div_shift;
  38. u16 div_val0;
  39. u8 div_step;
  40. };
  41. struct en_clk_gate {
  42. void __iomem *base;
  43. struct clk_hw hw;
  44. };
  45. static const u32 gsw_base[] = { 400000000, 500000000 };
  46. static const u32 emi_base[] = { 333000000, 400000000 };
  47. static const u32 bus_base[] = { 500000000, 540000000 };
  48. static const u32 slic_base[] = { 100000000, 3125000 };
  49. static const u32 npu_base[] = { 333000000, 400000000, 500000000 };
  50. static const struct en_clk_desc en7523_base_clks[] = {
  51. {
  52. .id = EN7523_CLK_GSW,
  53. .name = "gsw",
  54. .base_reg = REG_GSW_CLK_DIV_SEL,
  55. .base_bits = 1,
  56. .base_shift = 8,
  57. .base_values = gsw_base,
  58. .n_base_values = ARRAY_SIZE(gsw_base),
  59. .div_bits = 3,
  60. .div_shift = 0,
  61. .div_step = 1,
  62. }, {
  63. .id = EN7523_CLK_EMI,
  64. .name = "emi",
  65. .base_reg = REG_EMI_CLK_DIV_SEL,
  66. .base_bits = 1,
  67. .base_shift = 8,
  68. .base_values = emi_base,
  69. .n_base_values = ARRAY_SIZE(emi_base),
  70. .div_bits = 3,
  71. .div_shift = 0,
  72. .div_step = 1,
  73. }, {
  74. .id = EN7523_CLK_BUS,
  75. .name = "bus",
  76. .base_reg = REG_BUS_CLK_DIV_SEL,
  77. .base_bits = 1,
  78. .base_shift = 8,
  79. .base_values = bus_base,
  80. .n_base_values = ARRAY_SIZE(bus_base),
  81. .div_bits = 3,
  82. .div_shift = 0,
  83. .div_step = 1,
  84. }, {
  85. .id = EN7523_CLK_SLIC,
  86. .name = "slic",
  87. .base_reg = REG_SPI_CLK_FREQ_SEL,
  88. .base_bits = 1,
  89. .base_shift = 0,
  90. .base_values = slic_base,
  91. .n_base_values = ARRAY_SIZE(slic_base),
  92. .div_reg = REG_SPI_CLK_DIV_SEL,
  93. .div_bits = 5,
  94. .div_shift = 24,
  95. .div_val0 = 20,
  96. .div_step = 2,
  97. }, {
  98. .id = EN7523_CLK_SPI,
  99. .name = "spi",
  100. .base_reg = REG_SPI_CLK_DIV_SEL,
  101. .base_value = 400000000,
  102. .div_bits = 5,
  103. .div_shift = 8,
  104. .div_val0 = 40,
  105. .div_step = 2,
  106. }, {
  107. .id = EN7523_CLK_NPU,
  108. .name = "npu",
  109. .base_reg = REG_NPU_CLK_DIV_SEL,
  110. .base_bits = 2,
  111. .base_shift = 8,
  112. .base_values = npu_base,
  113. .n_base_values = ARRAY_SIZE(npu_base),
  114. .div_bits = 3,
  115. .div_shift = 0,
  116. .div_step = 1,
  117. }, {
  118. .id = EN7523_CLK_CRYPTO,
  119. .name = "crypto",
  120. .base_reg = REG_CRYPTO_CLKSRC,
  121. .base_bits = 1,
  122. .base_shift = 8,
  123. .base_values = emi_base,
  124. .n_base_values = ARRAY_SIZE(emi_base),
  125. }
  126. };
  127. static const struct of_device_id of_match_clk_en7523[] = {
  128. { .compatible = "airoha,en7523-scu", },
  129. { /* sentinel */ }
  130. };
  131. static unsigned int en7523_get_base_rate(void __iomem *base, unsigned int i)
  132. {
  133. const struct en_clk_desc *desc = &en7523_base_clks[i];
  134. u32 val;
  135. if (!desc->base_bits)
  136. return desc->base_value;
  137. val = readl(base + desc->base_reg);
  138. val >>= desc->base_shift;
  139. val &= (1 << desc->base_bits) - 1;
  140. if (val >= desc->n_base_values)
  141. return 0;
  142. return desc->base_values[val];
  143. }
  144. static u32 en7523_get_div(void __iomem *base, int i)
  145. {
  146. const struct en_clk_desc *desc = &en7523_base_clks[i];
  147. u32 reg, val;
  148. if (!desc->div_bits)
  149. return 1;
  150. reg = desc->div_reg ? desc->div_reg : desc->base_reg;
  151. val = readl(base + reg);
  152. val >>= desc->div_shift;
  153. val &= (1 << desc->div_bits) - 1;
  154. if (!val && desc->div_val0)
  155. return desc->div_val0;
  156. return (val + 1) * desc->div_step;
  157. }
  158. static int en7523_pci_is_enabled(struct clk_hw *hw)
  159. {
  160. struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw);
  161. return !!(readl(cg->base + REG_PCI_CONTROL) & REG_PCI_CONTROL_REFCLK_EN1);
  162. }
  163. static int en7523_pci_prepare(struct clk_hw *hw)
  164. {
  165. struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw);
  166. void __iomem *np_base = cg->base;
  167. u32 val, mask;
  168. /* Need to pull device low before reset */
  169. val = readl(np_base + REG_PCI_CONTROL);
  170. val &= ~(REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT);
  171. writel(val, np_base + REG_PCI_CONTROL);
  172. usleep_range(1000, 2000);
  173. /* Enable PCIe port 1 */
  174. val |= REG_PCI_CONTROL_REFCLK_EN1;
  175. writel(val, np_base + REG_PCI_CONTROL);
  176. usleep_range(1000, 2000);
  177. /* Reset to default */
  178. val = readl(np_base + REG_RESET_CONTROL);
  179. mask = REG_RESET_CONTROL_PCIE1 | REG_RESET_CONTROL_PCIE2 |
  180. REG_RESET_CONTROL_PCIEHB;
  181. writel(val & ~mask, np_base + REG_RESET_CONTROL);
  182. usleep_range(1000, 2000);
  183. writel(val | mask, np_base + REG_RESET_CONTROL);
  184. msleep(100);
  185. writel(val & ~mask, np_base + REG_RESET_CONTROL);
  186. usleep_range(5000, 10000);
  187. /* Release device */
  188. mask = REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT;
  189. val = readl(np_base + REG_PCI_CONTROL);
  190. writel(val & ~mask, np_base + REG_PCI_CONTROL);
  191. usleep_range(1000, 2000);
  192. writel(val | mask, np_base + REG_PCI_CONTROL);
  193. msleep(250);
  194. return 0;
  195. }
  196. static void en7523_pci_unprepare(struct clk_hw *hw)
  197. {
  198. struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw);
  199. void __iomem *np_base = cg->base;
  200. u32 val;
  201. val = readl(np_base + REG_PCI_CONTROL);
  202. val &= ~REG_PCI_CONTROL_REFCLK_EN1;
  203. writel(val, np_base + REG_PCI_CONTROL);
  204. }
  205. static struct clk_hw *en7523_register_pcie_clk(struct device *dev,
  206. void __iomem *np_base)
  207. {
  208. static const struct clk_ops pcie_gate_ops = {
  209. .is_enabled = en7523_pci_is_enabled,
  210. .prepare = en7523_pci_prepare,
  211. .unprepare = en7523_pci_unprepare,
  212. };
  213. struct clk_init_data init = {
  214. .name = "pcie",
  215. .ops = &pcie_gate_ops,
  216. };
  217. struct en_clk_gate *cg;
  218. cg = devm_kzalloc(dev, sizeof(*cg), GFP_KERNEL);
  219. if (!cg)
  220. return NULL;
  221. cg->base = np_base;
  222. cg->hw.init = &init;
  223. en7523_pci_unprepare(&cg->hw);
  224. if (clk_hw_register(dev, &cg->hw))
  225. return NULL;
  226. return &cg->hw;
  227. }
  228. static void en7523_register_clocks(struct device *dev, struct clk_hw_onecell_data *clk_data,
  229. void __iomem *base, void __iomem *np_base)
  230. {
  231. struct clk_hw *hw;
  232. u32 rate;
  233. int i;
  234. for (i = 0; i < ARRAY_SIZE(en7523_base_clks); i++) {
  235. const struct en_clk_desc *desc = &en7523_base_clks[i];
  236. rate = en7523_get_base_rate(base, i);
  237. rate /= en7523_get_div(base, i);
  238. hw = clk_hw_register_fixed_rate(dev, desc->name, NULL, 0, rate);
  239. if (IS_ERR(hw)) {
  240. pr_err("Failed to register clk %s: %ld\n",
  241. desc->name, PTR_ERR(hw));
  242. continue;
  243. }
  244. clk_data->hws[desc->id] = hw;
  245. }
  246. hw = en7523_register_pcie_clk(dev, np_base);
  247. clk_data->hws[EN7523_CLK_PCIE] = hw;
  248. clk_data->num = EN7523_NUM_CLOCKS;
  249. }
  250. static int en7523_clk_probe(struct platform_device *pdev)
  251. {
  252. struct device_node *node = pdev->dev.of_node;
  253. struct clk_hw_onecell_data *clk_data;
  254. void __iomem *base, *np_base;
  255. int r;
  256. base = devm_platform_ioremap_resource(pdev, 0);
  257. if (IS_ERR(base))
  258. return PTR_ERR(base);
  259. np_base = devm_platform_ioremap_resource(pdev, 1);
  260. if (IS_ERR(np_base))
  261. return PTR_ERR(np_base);
  262. clk_data = devm_kzalloc(&pdev->dev,
  263. struct_size(clk_data, hws, EN7523_NUM_CLOCKS),
  264. GFP_KERNEL);
  265. if (!clk_data)
  266. return -ENOMEM;
  267. en7523_register_clocks(&pdev->dev, clk_data, base, np_base);
  268. r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
  269. if (r)
  270. dev_err(&pdev->dev,
  271. "could not register clock provider: %s: %d\n",
  272. pdev->name, r);
  273. return r;
  274. }
  275. static struct platform_driver clk_en7523_drv = {
  276. .probe = en7523_clk_probe,
  277. .driver = {
  278. .name = "clk-en7523",
  279. .of_match_table = of_match_clk_en7523,
  280. .suppress_bind_attrs = true,
  281. },
  282. };
  283. static int __init clk_en7523_init(void)
  284. {
  285. return platform_driver_register(&clk_en7523_drv);
  286. }
  287. arch_initcall(clk_en7523_init);