k210-sysctl.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Copyright (c) 2019 Christoph Hellwig.
  4. * Copyright (c) 2019 Western Digital Corporation or its affiliates.
  5. */
  6. #include <linux/io.h>
  7. #include <linux/platform_device.h>
  8. #include <linux/of_platform.h>
  9. #include <linux/clk.h>
  10. #include <asm/soc.h>
  11. #include <soc/canaan/k210-sysctl.h>
  12. static int k210_sysctl_probe(struct platform_device *pdev)
  13. {
  14. struct device *dev = &pdev->dev;
  15. struct clk *pclk;
  16. int ret;
  17. dev_info(dev, "K210 system controller\n");
  18. /* Get power bus clock */
  19. pclk = devm_clk_get(dev, NULL);
  20. if (IS_ERR(pclk))
  21. return dev_err_probe(dev, PTR_ERR(pclk),
  22. "Get bus clock failed\n");
  23. ret = clk_prepare_enable(pclk);
  24. if (ret) {
  25. dev_err(dev, "Enable bus clock failed\n");
  26. return ret;
  27. }
  28. /* Populate children */
  29. ret = devm_of_platform_populate(dev);
  30. if (ret)
  31. dev_err(dev, "Populate platform failed %d\n", ret);
  32. return ret;
  33. }
  34. static const struct of_device_id k210_sysctl_of_match[] = {
  35. { .compatible = "canaan,k210-sysctl", },
  36. { /* sentinel */ },
  37. };
  38. static struct platform_driver k210_sysctl_driver = {
  39. .driver = {
  40. .name = "k210-sysctl",
  41. .of_match_table = k210_sysctl_of_match,
  42. },
  43. .probe = k210_sysctl_probe,
  44. };
  45. builtin_platform_driver(k210_sysctl_driver);
  46. /*
  47. * System controller registers base address and size.
  48. */
  49. #define K210_SYSCTL_BASE_ADDR 0x50440000ULL
  50. #define K210_SYSCTL_BASE_SIZE 0x1000
  51. /*
  52. * This needs to be called very early during initialization, given that
  53. * PLL1 needs to be enabled to be able to use all SRAM.
  54. */
  55. static void __init k210_soc_early_init(const void *fdt)
  56. {
  57. void __iomem *sysctl_base;
  58. sysctl_base = ioremap(K210_SYSCTL_BASE_ADDR, K210_SYSCTL_BASE_SIZE);
  59. if (!sysctl_base)
  60. panic("k210-sysctl: ioremap failed");
  61. k210_clk_early_init(sysctl_base);
  62. iounmap(sysctl_base);
  63. }
  64. SOC_EARLY_INIT_DECLARE(k210_soc, "canaan,kendryte-k210", k210_soc_early_init);