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 mdelay(1); 71 72 tmp = readl(base); /* SSCPLLCTRL */ 73 tmp |= SC_PLLCTRL_SSC_EN; 74 writel(tmp, base); 75 76 iounmap(base); 77 78 return 0; 79 } 80 81 int uniphier_ld20_vpll27_init(unsigned long reg_base) 82 { 83 void __iomem *base; 84 u32 tmp; 85 86 base = ioremap(reg_base, SZ_16); 87 if (!base) 88 return -ENOMEM; 89 90 tmp = readl(base); /* VPLL27CTRL */ 91 tmp |= SC_VPLL27CTRL_WP; /* write protect off */ 92 writel(tmp, base); 93 94 tmp = readl(base + 8); /* VPLL27CTRL3 */ 95 tmp |= SC_VPLL27CTRL3_K_LD; 96 writel(tmp, base + 8); 97 98 tmp = readl(base); /* VPLL27CTRL */ 99 tmp &= ~SC_VPLL27CTRL_WP; /* write protect on */ 100 writel(tmp, base); 101 102 iounmap(base); 103 104 return 0; 105 } 106 107 int uniphier_ld20_dspll_init(unsigned long reg_base) 108 { 109 void __iomem *base; 110 u32 tmp; 111 112 base = ioremap(reg_base, SZ_16); 113 if (!base) 114 return -ENOMEM; 115 116 tmp = readl(base + 8); /* DSPLLCTRL2 */ 117 tmp |= SC_DSPLLCTRL2_K_LD; 118 writel(tmp, base + 8); 119 120 iounmap(base); 121 122 return 0; 123 } 124