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