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