xref: /openbmc/u-boot/drivers/clk/owl/clk_s900.c (revision ae485b54)
1*ae485b54SManivannan Sadhasivam // SPDX-License-Identifier: GPL-2.0+
2*ae485b54SManivannan Sadhasivam /*
3*ae485b54SManivannan Sadhasivam  * Actions Semi S900 clock driver
4*ae485b54SManivannan Sadhasivam  *
5*ae485b54SManivannan Sadhasivam  * Copyright (C) 2015 Actions Semi Co., Ltd.
6*ae485b54SManivannan Sadhasivam  * Copyright (C) 2018 Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
7*ae485b54SManivannan Sadhasivam  */
8*ae485b54SManivannan Sadhasivam 
9*ae485b54SManivannan Sadhasivam #include <common.h>
10*ae485b54SManivannan Sadhasivam #include <dm.h>
11*ae485b54SManivannan Sadhasivam #include <asm/arch-owl/clk_s900.h>
12*ae485b54SManivannan Sadhasivam #include <asm/arch-owl/regs_s900.h>
13*ae485b54SManivannan Sadhasivam #include <asm/io.h>
14*ae485b54SManivannan Sadhasivam 
15*ae485b54SManivannan Sadhasivam #include <dt-bindings/clock/s900_cmu.h>
16*ae485b54SManivannan Sadhasivam 
17*ae485b54SManivannan Sadhasivam void owl_clk_init(struct owl_clk_priv *priv)
18*ae485b54SManivannan Sadhasivam {
19*ae485b54SManivannan Sadhasivam 	u32 bus_clk = 0, core_pll, dev_pll;
20*ae485b54SManivannan Sadhasivam 
21*ae485b54SManivannan Sadhasivam 	/* Enable ASSIST_PLL */
22*ae485b54SManivannan Sadhasivam 	setbits_le32(priv->base + CMU_ASSISTPLL, BIT(0));
23*ae485b54SManivannan Sadhasivam 
24*ae485b54SManivannan Sadhasivam 	udelay(PLL_STABILITY_WAIT_US);
25*ae485b54SManivannan Sadhasivam 
26*ae485b54SManivannan Sadhasivam 	/* Source HOSC to DEV_CLK */
27*ae485b54SManivannan Sadhasivam 	clrbits_le32(priv->base + CMU_DEVPLL, CMU_DEVPLL_CLK);
28*ae485b54SManivannan Sadhasivam 
29*ae485b54SManivannan Sadhasivam 	/* Configure BUS_CLK */
30*ae485b54SManivannan Sadhasivam 	bus_clk |= (CMU_PDBGDIV_DIV | CMU_PERDIV_DIV | CMU_NOCDIV_DIV |
31*ae485b54SManivannan Sadhasivam 			CMU_DMMCLK_SRC | CMU_APBCLK_DIV | CMU_AHBCLK_DIV |
32*ae485b54SManivannan Sadhasivam 			CMU_NOCCLK_SRC | CMU_CORECLK_HOSC);
33*ae485b54SManivannan Sadhasivam 	writel(bus_clk, priv->base + CMU_BUSCLK);
34*ae485b54SManivannan Sadhasivam 
35*ae485b54SManivannan Sadhasivam 	udelay(PLL_STABILITY_WAIT_US);
36*ae485b54SManivannan Sadhasivam 
37*ae485b54SManivannan Sadhasivam 	/* Configure CORE_PLL */
38*ae485b54SManivannan Sadhasivam 	core_pll = readl(priv->base + CMU_COREPLL);
39*ae485b54SManivannan Sadhasivam 	core_pll |= (CMU_COREPLL_EN | CMU_COREPLL_HOSC_EN | CMU_COREPLL_OUT);
40*ae485b54SManivannan Sadhasivam 	writel(core_pll, priv->base + CMU_COREPLL);
41*ae485b54SManivannan Sadhasivam 
42*ae485b54SManivannan Sadhasivam 	udelay(PLL_STABILITY_WAIT_US);
43*ae485b54SManivannan Sadhasivam 
44*ae485b54SManivannan Sadhasivam 	/* Configure DEV_PLL */
45*ae485b54SManivannan Sadhasivam 	dev_pll = readl(priv->base + CMU_DEVPLL);
46*ae485b54SManivannan Sadhasivam 	dev_pll |= (CMU_DEVPLL_EN | CMU_DEVPLL_OUT);
47*ae485b54SManivannan Sadhasivam 	writel(dev_pll, priv->base + CMU_DEVPLL);
48*ae485b54SManivannan Sadhasivam 
49*ae485b54SManivannan Sadhasivam 	udelay(PLL_STABILITY_WAIT_US);
50*ae485b54SManivannan Sadhasivam 
51*ae485b54SManivannan Sadhasivam 	/* Source CORE_PLL for CORE_CLK */
52*ae485b54SManivannan Sadhasivam 	clrsetbits_le32(priv->base + CMU_BUSCLK, CMU_CORECLK_MASK,
53*ae485b54SManivannan Sadhasivam 			CMU_CORECLK_CPLL);
54*ae485b54SManivannan Sadhasivam 
55*ae485b54SManivannan Sadhasivam 	/* Source DEV_PLL for DEV_CLK */
56*ae485b54SManivannan Sadhasivam 	setbits_le32(priv->base + CMU_DEVPLL, CMU_DEVPLL_CLK);
57*ae485b54SManivannan Sadhasivam 
58*ae485b54SManivannan Sadhasivam 	udelay(PLL_STABILITY_WAIT_US);
59*ae485b54SManivannan Sadhasivam }
60*ae485b54SManivannan Sadhasivam 
61*ae485b54SManivannan Sadhasivam void owl_uart_clk_enable(struct owl_clk_priv *priv)
62*ae485b54SManivannan Sadhasivam {
63*ae485b54SManivannan Sadhasivam 	/* Source HOSC for UART5 interface */
64*ae485b54SManivannan Sadhasivam 	clrbits_le32(priv->base + CMU_UART5CLK, CMU_UARTCLK_SRC_DEVPLL);
65*ae485b54SManivannan Sadhasivam 
66*ae485b54SManivannan Sadhasivam 	/* Enable UART5 interface clock */
67*ae485b54SManivannan Sadhasivam 	setbits_le32(priv->base + CMU_DEVCLKEN1, CMU_DEVCLKEN1_UART5);
68*ae485b54SManivannan Sadhasivam }
69*ae485b54SManivannan Sadhasivam 
70*ae485b54SManivannan Sadhasivam void owl_uart_clk_disable(struct owl_clk_priv *priv)
71*ae485b54SManivannan Sadhasivam {
72*ae485b54SManivannan Sadhasivam 	/* Disable UART5 interface clock */
73*ae485b54SManivannan Sadhasivam 	clrbits_le32(priv->base + CMU_DEVCLKEN1, CMU_DEVCLKEN1_UART5);
74*ae485b54SManivannan Sadhasivam }
75*ae485b54SManivannan Sadhasivam 
76*ae485b54SManivannan Sadhasivam int owl_clk_enable(struct clk *clk)
77*ae485b54SManivannan Sadhasivam {
78*ae485b54SManivannan Sadhasivam 	struct owl_clk_priv *priv = dev_get_priv(clk->dev);
79*ae485b54SManivannan Sadhasivam 
80*ae485b54SManivannan Sadhasivam 	switch (clk->id) {
81*ae485b54SManivannan Sadhasivam 	case CLOCK_UART5:
82*ae485b54SManivannan Sadhasivam 		owl_uart_clk_enable(priv);
83*ae485b54SManivannan Sadhasivam 		break;
84*ae485b54SManivannan Sadhasivam 	default:
85*ae485b54SManivannan Sadhasivam 		return 0;
86*ae485b54SManivannan Sadhasivam 	}
87*ae485b54SManivannan Sadhasivam 
88*ae485b54SManivannan Sadhasivam 	return 0;
89*ae485b54SManivannan Sadhasivam }
90*ae485b54SManivannan Sadhasivam 
91*ae485b54SManivannan Sadhasivam int owl_clk_disable(struct clk *clk)
92*ae485b54SManivannan Sadhasivam {
93*ae485b54SManivannan Sadhasivam 	struct owl_clk_priv *priv = dev_get_priv(clk->dev);
94*ae485b54SManivannan Sadhasivam 
95*ae485b54SManivannan Sadhasivam 	switch (clk->id) {
96*ae485b54SManivannan Sadhasivam 	case CLOCK_UART5:
97*ae485b54SManivannan Sadhasivam 		owl_uart_clk_disable(priv);
98*ae485b54SManivannan Sadhasivam 		break;
99*ae485b54SManivannan Sadhasivam 	default:
100*ae485b54SManivannan Sadhasivam 		return 0;
101*ae485b54SManivannan Sadhasivam 	}
102*ae485b54SManivannan Sadhasivam 
103*ae485b54SManivannan Sadhasivam 	return 0;
104*ae485b54SManivannan Sadhasivam }
105*ae485b54SManivannan Sadhasivam 
106*ae485b54SManivannan Sadhasivam static int owl_clk_probe(struct udevice *dev)
107*ae485b54SManivannan Sadhasivam {
108*ae485b54SManivannan Sadhasivam 	struct owl_clk_priv *priv = dev_get_priv(dev);
109*ae485b54SManivannan Sadhasivam 
110*ae485b54SManivannan Sadhasivam 	priv->base = dev_read_addr(dev);
111*ae485b54SManivannan Sadhasivam 	if (priv->base == FDT_ADDR_T_NONE)
112*ae485b54SManivannan Sadhasivam 		return -EINVAL;
113*ae485b54SManivannan Sadhasivam 
114*ae485b54SManivannan Sadhasivam 	/* setup necessary clocks */
115*ae485b54SManivannan Sadhasivam 	owl_clk_init(priv);
116*ae485b54SManivannan Sadhasivam 
117*ae485b54SManivannan Sadhasivam 	return 0;
118*ae485b54SManivannan Sadhasivam }
119*ae485b54SManivannan Sadhasivam 
120*ae485b54SManivannan Sadhasivam static struct clk_ops owl_clk_ops = {
121*ae485b54SManivannan Sadhasivam 	.enable = owl_clk_enable,
122*ae485b54SManivannan Sadhasivam 	.disable = owl_clk_disable,
123*ae485b54SManivannan Sadhasivam };
124*ae485b54SManivannan Sadhasivam 
125*ae485b54SManivannan Sadhasivam static const struct udevice_id owl_clk_ids[] = {
126*ae485b54SManivannan Sadhasivam 	{ .compatible = "actions,s900-cmu" },
127*ae485b54SManivannan Sadhasivam 	{ }
128*ae485b54SManivannan Sadhasivam };
129*ae485b54SManivannan Sadhasivam 
130*ae485b54SManivannan Sadhasivam U_BOOT_DRIVER(clk_owl) = {
131*ae485b54SManivannan Sadhasivam 	.name		= "clk_s900",
132*ae485b54SManivannan Sadhasivam 	.id		= UCLASS_CLK,
133*ae485b54SManivannan Sadhasivam 	.of_match	= owl_clk_ids,
134*ae485b54SManivannan Sadhasivam 	.ops		= &owl_clk_ops,
135*ae485b54SManivannan Sadhasivam 	.priv_auto_alloc_size = sizeof(struct owl_clk_priv),
136*ae485b54SManivannan Sadhasivam 	.probe		= owl_clk_probe,
137*ae485b54SManivannan Sadhasivam 	.flags		= DM_FLAG_PRE_RELOC,
138*ae485b54SManivannan Sadhasivam };
139