clk-st.c 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. // SPDX-License-Identifier: MIT
  2. /*
  3. * clock framework for AMD Stoney based clocks
  4. *
  5. * Copyright 2018 Advanced Micro Devices, Inc.
  6. */
  7. #include <linux/clk.h>
  8. #include <linux/clkdev.h>
  9. #include <linux/clk-provider.h>
  10. #include <linux/platform_data/clk-st.h>
  11. #include <linux/platform_device.h>
  12. /* Clock Driving Strength 2 register */
  13. #define CLKDRVSTR2 0x28
  14. /* Clock Control 1 register */
  15. #define MISCCLKCNTL1 0x40
  16. /* Auxiliary clock1 enable bit */
  17. #define OSCCLKENB 2
  18. /* 25Mhz auxiliary output clock freq bit */
  19. #define OSCOUT1CLK25MHZ 16
  20. #define ST_CLK_48M 0
  21. #define ST_CLK_25M 1
  22. #define ST_CLK_MUX 2
  23. #define ST_CLK_GATE 3
  24. #define ST_MAX_CLKS 4
  25. static const char * const clk_oscout1_parents[] = { "clk48MHz", "clk25MHz" };
  26. static struct clk_hw *hws[ST_MAX_CLKS];
  27. static int st_clk_probe(struct platform_device *pdev)
  28. {
  29. struct st_clk_data *st_data;
  30. st_data = dev_get_platdata(&pdev->dev);
  31. if (!st_data || !st_data->base)
  32. return -EINVAL;
  33. hws[ST_CLK_48M] = clk_hw_register_fixed_rate(NULL, "clk48MHz", NULL, 0,
  34. 48000000);
  35. hws[ST_CLK_25M] = clk_hw_register_fixed_rate(NULL, "clk25MHz", NULL, 0,
  36. 25000000);
  37. hws[ST_CLK_MUX] = clk_hw_register_mux(NULL, "oscout1_mux",
  38. clk_oscout1_parents, ARRAY_SIZE(clk_oscout1_parents),
  39. 0, st_data->base + CLKDRVSTR2, OSCOUT1CLK25MHZ, 3, 0, NULL);
  40. clk_set_parent(hws[ST_CLK_MUX]->clk, hws[ST_CLK_48M]->clk);
  41. hws[ST_CLK_GATE] = clk_hw_register_gate(NULL, "oscout1", "oscout1_mux",
  42. 0, st_data->base + MISCCLKCNTL1, OSCCLKENB,
  43. CLK_GATE_SET_TO_DISABLE, NULL);
  44. clk_hw_register_clkdev(hws[ST_CLK_GATE], "oscout1", NULL);
  45. return 0;
  46. }
  47. static int st_clk_remove(struct platform_device *pdev)
  48. {
  49. int i;
  50. for (i = 0; i < ST_MAX_CLKS; i++)
  51. clk_hw_unregister(hws[i]);
  52. return 0;
  53. }
  54. static struct platform_driver st_clk_driver = {
  55. .driver = {
  56. .name = "clk-st",
  57. .suppress_bind_attrs = true,
  58. },
  59. .probe = st_clk_probe,
  60. .remove = st_clk_remove,
  61. };
  62. builtin_platform_driver(st_clk_driver);