1*682e09ffSMasahiro Yamada /* 2*682e09ffSMasahiro Yamada * Copyright (C) 2016 Socionext Inc. 3*682e09ffSMasahiro Yamada * Author: Masahiro Yamada <yamada.masahiro@socionext.com> 4*682e09ffSMasahiro Yamada * 5*682e09ffSMasahiro Yamada * SPDX-License-Identifier: GPL-2.0+ 6*682e09ffSMasahiro Yamada */ 7*682e09ffSMasahiro Yamada 8*682e09ffSMasahiro Yamada #include <common.h> 9*682e09ffSMasahiro Yamada #include <linux/bitops.h> 10*682e09ffSMasahiro Yamada #include <linux/io.h> 11*682e09ffSMasahiro Yamada #include <linux/sizes.h> 12*682e09ffSMasahiro Yamada 13*682e09ffSMasahiro Yamada #include "pll.h" 14*682e09ffSMasahiro Yamada 15*682e09ffSMasahiro Yamada /* PLL type: SSC */ 16*682e09ffSMasahiro Yamada #define SC_PLLCTRL_SSC_DK_MASK GENMASK(14, 0) 17*682e09ffSMasahiro Yamada #define SC_PLLCTRL_SSC_EN BIT(31) 18*682e09ffSMasahiro Yamada #define SC_PLLCTRL2_NRSTDS BIT(28) 19*682e09ffSMasahiro Yamada #define SC_PLLCTRL2_SSC_JK_MASK GENMASK(26, 0) 20*682e09ffSMasahiro Yamada 21*682e09ffSMasahiro Yamada /* PLL type: VPLL27 */ 22*682e09ffSMasahiro Yamada #define SC_VPLL27CTRL_WP BIT(0) 23*682e09ffSMasahiro Yamada #define SC_VPLL27CTRL3_K_LD BIT(28) 24*682e09ffSMasahiro Yamada 25*682e09ffSMasahiro Yamada /* PLL type: DSPLL */ 26*682e09ffSMasahiro Yamada #define SC_DSPLLCTRL2_K_LD BIT(28) 27*682e09ffSMasahiro Yamada 28*682e09ffSMasahiro Yamada int uniphier_ld20_sscpll_init(unsigned long reg_base, unsigned int freq, 29*682e09ffSMasahiro Yamada unsigned int ssc_rate, unsigned int divn) 30*682e09ffSMasahiro Yamada { 31*682e09ffSMasahiro Yamada void __iomem *base; 32*682e09ffSMasahiro Yamada u32 tmp; 33*682e09ffSMasahiro Yamada 34*682e09ffSMasahiro Yamada base = ioremap(reg_base, SZ_16); 35*682e09ffSMasahiro Yamada if (!base) 36*682e09ffSMasahiro Yamada return -ENOMEM; 37*682e09ffSMasahiro Yamada 38*682e09ffSMasahiro Yamada if (freq != UNIPHIER_PLL_FREQ_DEFAULT) { 39*682e09ffSMasahiro Yamada tmp = readl(base); /* SSCPLLCTRL */ 40*682e09ffSMasahiro Yamada tmp &= ~SC_PLLCTRL_SSC_DK_MASK; 41*682e09ffSMasahiro Yamada tmp |= (487 * freq * ssc_rate / divn / 512) & 42*682e09ffSMasahiro Yamada SC_PLLCTRL_SSC_DK_MASK; 43*682e09ffSMasahiro Yamada writel(tmp, base); 44*682e09ffSMasahiro Yamada 45*682e09ffSMasahiro Yamada tmp = readl(base + 4); 46*682e09ffSMasahiro Yamada tmp &= ~SC_PLLCTRL2_SSC_JK_MASK; 47*682e09ffSMasahiro Yamada tmp |= (41859 * freq / divn) & SC_PLLCTRL2_SSC_JK_MASK; 48*682e09ffSMasahiro Yamada 49*682e09ffSMasahiro Yamada udelay(50); 50*682e09ffSMasahiro Yamada } 51*682e09ffSMasahiro Yamada 52*682e09ffSMasahiro Yamada tmp = readl(base + 4); /* SSCPLLCTRL2 */ 53*682e09ffSMasahiro Yamada tmp |= SC_PLLCTRL2_NRSTDS; 54*682e09ffSMasahiro Yamada writel(tmp, base + 4); 55*682e09ffSMasahiro Yamada 56*682e09ffSMasahiro Yamada iounmap(base); 57*682e09ffSMasahiro Yamada 58*682e09ffSMasahiro Yamada return 0; 59*682e09ffSMasahiro Yamada } 60*682e09ffSMasahiro Yamada 61*682e09ffSMasahiro Yamada int uniphier_ld20_sscpll_ssc_en(unsigned long reg_base) 62*682e09ffSMasahiro Yamada { 63*682e09ffSMasahiro Yamada void __iomem *base; 64*682e09ffSMasahiro Yamada u32 tmp; 65*682e09ffSMasahiro Yamada 66*682e09ffSMasahiro Yamada base = ioremap(reg_base, SZ_16); 67*682e09ffSMasahiro Yamada if (!base) 68*682e09ffSMasahiro Yamada return -ENOMEM; 69*682e09ffSMasahiro Yamada 70*682e09ffSMasahiro Yamada mdelay(1); 71*682e09ffSMasahiro Yamada 72*682e09ffSMasahiro Yamada tmp = readl(base); /* SSCPLLCTRL */ 73*682e09ffSMasahiro Yamada tmp |= SC_PLLCTRL_SSC_EN; 74*682e09ffSMasahiro Yamada writel(tmp, base); 75*682e09ffSMasahiro Yamada 76*682e09ffSMasahiro Yamada iounmap(base); 77*682e09ffSMasahiro Yamada 78*682e09ffSMasahiro Yamada return 0; 79*682e09ffSMasahiro Yamada } 80*682e09ffSMasahiro Yamada 81*682e09ffSMasahiro Yamada int uniphier_ld20_vpll27_init(unsigned long reg_base) 82*682e09ffSMasahiro Yamada { 83*682e09ffSMasahiro Yamada void __iomem *base; 84*682e09ffSMasahiro Yamada u32 tmp; 85*682e09ffSMasahiro Yamada 86*682e09ffSMasahiro Yamada base = ioremap(reg_base, SZ_16); 87*682e09ffSMasahiro Yamada if (!base) 88*682e09ffSMasahiro Yamada return -ENOMEM; 89*682e09ffSMasahiro Yamada 90*682e09ffSMasahiro Yamada tmp = readl(base); /* VPLL27CTRL */ 91*682e09ffSMasahiro Yamada tmp |= SC_VPLL27CTRL_WP; /* write protect off */ 92*682e09ffSMasahiro Yamada writel(tmp, base); 93*682e09ffSMasahiro Yamada 94*682e09ffSMasahiro Yamada tmp = readl(base + 8); /* VPLL27CTRL3 */ 95*682e09ffSMasahiro Yamada tmp |= SC_VPLL27CTRL3_K_LD; 96*682e09ffSMasahiro Yamada writel(tmp, base + 8); 97*682e09ffSMasahiro Yamada 98*682e09ffSMasahiro Yamada tmp = readl(base); /* VPLL27CTRL */ 99*682e09ffSMasahiro Yamada tmp &= ~SC_VPLL27CTRL_WP; /* write protect on */ 100*682e09ffSMasahiro Yamada writel(tmp, base); 101*682e09ffSMasahiro Yamada 102*682e09ffSMasahiro Yamada iounmap(base); 103*682e09ffSMasahiro Yamada 104*682e09ffSMasahiro Yamada return 0; 105*682e09ffSMasahiro Yamada } 106*682e09ffSMasahiro Yamada 107*682e09ffSMasahiro Yamada int uniphier_ld20_dspll_init(unsigned long reg_base) 108*682e09ffSMasahiro Yamada { 109*682e09ffSMasahiro Yamada void __iomem *base; 110*682e09ffSMasahiro Yamada u32 tmp; 111*682e09ffSMasahiro Yamada 112*682e09ffSMasahiro Yamada base = ioremap(reg_base, SZ_16); 113*682e09ffSMasahiro Yamada if (!base) 114*682e09ffSMasahiro Yamada return -ENOMEM; 115*682e09ffSMasahiro Yamada 116*682e09ffSMasahiro Yamada tmp = readl(base + 8); /* DSPLLCTRL2 */ 117*682e09ffSMasahiro Yamada tmp |= SC_DSPLLCTRL2_K_LD; 118*682e09ffSMasahiro Yamada writel(tmp, base + 8); 119*682e09ffSMasahiro Yamada 120*682e09ffSMasahiro Yamada iounmap(base); 121*682e09ffSMasahiro Yamada 122*682e09ffSMasahiro Yamada return 0; 123*682e09ffSMasahiro Yamada } 124