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