ti-j721e-ufs.c 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
  4. */
  5. #include <asm/io.h>
  6. #include <clk.h>
  7. #include <common.h>
  8. #include <dm.h>
  9. #include <dm/device_compat.h>
  10. #include <linux/bitops.h>
  11. #include <linux/err.h>
  12. #define UFS_SS_CTRL 0x4
  13. #define UFS_SS_RST_N_PCS BIT(0)
  14. #define UFS_SS_CLK_26MHZ BIT(4)
  15. static int ti_j721e_ufs_probe(struct udevice *dev)
  16. {
  17. void __iomem *base;
  18. unsigned int clock;
  19. struct clk clk;
  20. u32 reg = 0;
  21. int ret;
  22. ret = clk_get_by_index(dev, 0, &clk);
  23. if (ret) {
  24. dev_err(dev, "failed to get M-PHY clock\n");
  25. return ret;
  26. }
  27. clock = clk_get_rate(&clk);
  28. if (IS_ERR_VALUE(clock)) {
  29. dev_err(dev, "failed to get rate\n");
  30. return ret;
  31. }
  32. base = dev_remap_addr_index(dev, 0);
  33. if (clock == 26000000)
  34. reg |= UFS_SS_CLK_26MHZ;
  35. /* Take UFS slave device out of reset */
  36. reg |= UFS_SS_RST_N_PCS;
  37. writel(reg, base + UFS_SS_CTRL);
  38. return 0;
  39. }
  40. static int ti_j721e_ufs_remove(struct udevice *dev)
  41. {
  42. void __iomem *base = dev_remap_addr_index(dev, 0);
  43. u32 reg = readl(base + UFS_SS_CTRL);
  44. reg &= ~UFS_SS_RST_N_PCS;
  45. writel(reg, base + UFS_SS_CTRL);
  46. return 0;
  47. }
  48. static const struct udevice_id ti_j721e_ufs_ids[] = {
  49. {
  50. .compatible = "ti,j721e-ufs",
  51. },
  52. {},
  53. };
  54. U_BOOT_DRIVER(ti_j721e_ufs) = {
  55. .name = "ti-j721e-ufs",
  56. .id = UCLASS_MISC,
  57. .of_match = ti_j721e_ufs_ids,
  58. .probe = ti_j721e_ufs_probe,
  59. .remove = ti_j721e_ufs_remove,
  60. .flags = DM_FLAG_OS_PREPARE,
  61. };