xref: /openbmc/linux/drivers/ufs/host/ti-j721e-ufs.c (revision dd11376b)
1*dd11376bSBart Van Assche // SPDX-License-Identifier: GPL-2.0
2*dd11376bSBart Van Assche //
3*dd11376bSBart Van Assche // Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
4*dd11376bSBart Van Assche //
5*dd11376bSBart Van Assche 
6*dd11376bSBart Van Assche #include <linux/clk.h>
7*dd11376bSBart Van Assche #include <linux/io.h>
8*dd11376bSBart Van Assche #include <linux/kernel.h>
9*dd11376bSBart Van Assche #include <linux/module.h>
10*dd11376bSBart Van Assche #include <linux/of_platform.h>
11*dd11376bSBart Van Assche #include <linux/platform_device.h>
12*dd11376bSBart Van Assche #include <linux/pm_runtime.h>
13*dd11376bSBart Van Assche 
14*dd11376bSBart Van Assche #define TI_UFS_SS_CTRL		0x4
15*dd11376bSBart Van Assche #define TI_UFS_SS_RST_N_PCS	BIT(0)
16*dd11376bSBart Van Assche #define TI_UFS_SS_CLK_26MHZ	BIT(4)
17*dd11376bSBart Van Assche 
18*dd11376bSBart Van Assche static int ti_j721e_ufs_probe(struct platform_device *pdev)
19*dd11376bSBart Van Assche {
20*dd11376bSBart Van Assche 	struct device *dev = &pdev->dev;
21*dd11376bSBart Van Assche 	unsigned long clk_rate;
22*dd11376bSBart Van Assche 	void __iomem *regbase;
23*dd11376bSBart Van Assche 	struct clk *clk;
24*dd11376bSBart Van Assche 	u32 reg = 0;
25*dd11376bSBart Van Assche 	int ret;
26*dd11376bSBart Van Assche 
27*dd11376bSBart Van Assche 	regbase = devm_platform_ioremap_resource(pdev, 0);
28*dd11376bSBart Van Assche 	if (IS_ERR(regbase))
29*dd11376bSBart Van Assche 		return PTR_ERR(regbase);
30*dd11376bSBart Van Assche 
31*dd11376bSBart Van Assche 	pm_runtime_enable(dev);
32*dd11376bSBart Van Assche 	ret = pm_runtime_resume_and_get(dev);
33*dd11376bSBart Van Assche 	if (ret < 0)
34*dd11376bSBart Van Assche 		goto disable_pm;
35*dd11376bSBart Van Assche 
36*dd11376bSBart Van Assche 	/* Select MPHY refclk frequency */
37*dd11376bSBart Van Assche 	clk = devm_clk_get(dev, NULL);
38*dd11376bSBart Van Assche 	if (IS_ERR(clk)) {
39*dd11376bSBart Van Assche 		ret = PTR_ERR(clk);
40*dd11376bSBart Van Assche 		dev_err(dev, "Cannot claim MPHY clock.\n");
41*dd11376bSBart Van Assche 		goto clk_err;
42*dd11376bSBart Van Assche 	}
43*dd11376bSBart Van Assche 	clk_rate = clk_get_rate(clk);
44*dd11376bSBart Van Assche 	if (clk_rate == 26000000)
45*dd11376bSBart Van Assche 		reg |= TI_UFS_SS_CLK_26MHZ;
46*dd11376bSBart Van Assche 	devm_clk_put(dev, clk);
47*dd11376bSBart Van Assche 
48*dd11376bSBart Van Assche 	/*  Take UFS slave device out of reset */
49*dd11376bSBart Van Assche 	reg |= TI_UFS_SS_RST_N_PCS;
50*dd11376bSBart Van Assche 	writel(reg, regbase + TI_UFS_SS_CTRL);
51*dd11376bSBart Van Assche 
52*dd11376bSBart Van Assche 	ret = of_platform_populate(pdev->dev.of_node, NULL, NULL,
53*dd11376bSBart Van Assche 				   dev);
54*dd11376bSBart Van Assche 	if (ret) {
55*dd11376bSBart Van Assche 		dev_err(dev, "failed to populate child nodes %d\n", ret);
56*dd11376bSBart Van Assche 		goto clk_err;
57*dd11376bSBart Van Assche 	}
58*dd11376bSBart Van Assche 
59*dd11376bSBart Van Assche 	return ret;
60*dd11376bSBart Van Assche 
61*dd11376bSBart Van Assche clk_err:
62*dd11376bSBart Van Assche 	pm_runtime_put_sync(dev);
63*dd11376bSBart Van Assche disable_pm:
64*dd11376bSBart Van Assche 	pm_runtime_disable(dev);
65*dd11376bSBart Van Assche 	return ret;
66*dd11376bSBart Van Assche }
67*dd11376bSBart Van Assche 
68*dd11376bSBart Van Assche static int ti_j721e_ufs_remove(struct platform_device *pdev)
69*dd11376bSBart Van Assche {
70*dd11376bSBart Van Assche 	of_platform_depopulate(&pdev->dev);
71*dd11376bSBart Van Assche 	pm_runtime_put_sync(&pdev->dev);
72*dd11376bSBart Van Assche 	pm_runtime_disable(&pdev->dev);
73*dd11376bSBart Van Assche 
74*dd11376bSBart Van Assche 	return 0;
75*dd11376bSBart Van Assche }
76*dd11376bSBart Van Assche 
77*dd11376bSBart Van Assche static const struct of_device_id ti_j721e_ufs_of_match[] = {
78*dd11376bSBart Van Assche 	{
79*dd11376bSBart Van Assche 		.compatible = "ti,j721e-ufs",
80*dd11376bSBart Van Assche 	},
81*dd11376bSBart Van Assche 	{ },
82*dd11376bSBart Van Assche };
83*dd11376bSBart Van Assche 
84*dd11376bSBart Van Assche static struct platform_driver ti_j721e_ufs_driver = {
85*dd11376bSBart Van Assche 	.probe	= ti_j721e_ufs_probe,
86*dd11376bSBart Van Assche 	.remove	= ti_j721e_ufs_remove,
87*dd11376bSBart Van Assche 	.driver	= {
88*dd11376bSBart Van Assche 		.name   = "ti-j721e-ufs",
89*dd11376bSBart Van Assche 		.of_match_table = ti_j721e_ufs_of_match,
90*dd11376bSBart Van Assche 	},
91*dd11376bSBart Van Assche };
92*dd11376bSBart Van Assche module_platform_driver(ti_j721e_ufs_driver);
93*dd11376bSBart Van Assche 
94*dd11376bSBart Van Assche MODULE_AUTHOR("Vignesh Raghavendra <vigneshr@ti.com>");
95*dd11376bSBart Van Assche MODULE_DESCRIPTION("TI UFS host controller glue driver");
96*dd11376bSBart Van Assche MODULE_LICENSE("GPL v2");
97