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