1682e09ffSMasahiro Yamada /* 2682e09ffSMasahiro Yamada * Copyright (C) 2016 Socionext Inc. 3682e09ffSMasahiro Yamada * Author: Masahiro Yamada <yamada.masahiro@socionext.com> 4682e09ffSMasahiro Yamada * 5682e09ffSMasahiro Yamada * SPDX-License-Identifier: GPL-2.0+ 6682e09ffSMasahiro Yamada */ 7682e09ffSMasahiro Yamada 8682e09ffSMasahiro Yamada #include <linux/bitops.h> 9d9a70368SMasahiro Yamada #include <linux/delay.h> 10d9a70368SMasahiro Yamada #include <linux/errno.h> 11682e09ffSMasahiro Yamada #include <linux/io.h> 12682e09ffSMasahiro Yamada #include <linux/sizes.h> 13682e09ffSMasahiro Yamada 14682e09ffSMasahiro Yamada #include "pll.h" 15682e09ffSMasahiro Yamada 16682e09ffSMasahiro Yamada /* PLL type: SSC */ 17682e09ffSMasahiro Yamada #define SC_PLLCTRL_SSC_DK_MASK GENMASK(14, 0) 18682e09ffSMasahiro Yamada #define SC_PLLCTRL_SSC_EN BIT(31) 19682e09ffSMasahiro Yamada #define SC_PLLCTRL2_NRSTDS BIT(28) 20682e09ffSMasahiro Yamada #define SC_PLLCTRL2_SSC_JK_MASK GENMASK(26, 0) 21bc647958SMasahiro Yamada #define SC_PLLCTRL3_REGI_SHIFT 16 22bc647958SMasahiro Yamada #define SC_PLLCTRL3_REGI_MASK GENMASK(19, 16) 23682e09ffSMasahiro Yamada 24682e09ffSMasahiro Yamada /* PLL type: VPLL27 */ 25682e09ffSMasahiro Yamada #define SC_VPLL27CTRL_WP BIT(0) 26682e09ffSMasahiro Yamada #define SC_VPLL27CTRL3_K_LD BIT(28) 27682e09ffSMasahiro Yamada 28682e09ffSMasahiro Yamada /* PLL type: DSPLL */ 29682e09ffSMasahiro Yamada #define SC_DSPLLCTRL2_K_LD BIT(28) 30682e09ffSMasahiro Yamada 31682e09ffSMasahiro Yamada int uniphier_ld20_sscpll_init(unsigned long reg_base, unsigned int freq, 32682e09ffSMasahiro Yamada unsigned int ssc_rate, unsigned int divn) 33682e09ffSMasahiro Yamada { 34682e09ffSMasahiro Yamada void __iomem *base; 35682e09ffSMasahiro Yamada u32 tmp; 36682e09ffSMasahiro Yamada 37682e09ffSMasahiro Yamada base = ioremap(reg_base, SZ_16); 38682e09ffSMasahiro Yamada if (!base) 39682e09ffSMasahiro Yamada return -ENOMEM; 40682e09ffSMasahiro Yamada 41682e09ffSMasahiro Yamada if (freq != UNIPHIER_PLL_FREQ_DEFAULT) { 42682e09ffSMasahiro Yamada tmp = readl(base); /* SSCPLLCTRL */ 43682e09ffSMasahiro Yamada tmp &= ~SC_PLLCTRL_SSC_DK_MASK; 44682e09ffSMasahiro Yamada tmp |= (487 * freq * ssc_rate / divn / 512) & 45682e09ffSMasahiro Yamada SC_PLLCTRL_SSC_DK_MASK; 46682e09ffSMasahiro Yamada writel(tmp, base); 47682e09ffSMasahiro Yamada 48682e09ffSMasahiro Yamada tmp = readl(base + 4); 49682e09ffSMasahiro Yamada tmp &= ~SC_PLLCTRL2_SSC_JK_MASK; 50682e09ffSMasahiro Yamada tmp |= (41859 * freq / divn) & SC_PLLCTRL2_SSC_JK_MASK; 51682e09ffSMasahiro Yamada 52682e09ffSMasahiro Yamada udelay(50); 53682e09ffSMasahiro Yamada } 54682e09ffSMasahiro Yamada 55682e09ffSMasahiro Yamada tmp = readl(base + 4); /* SSCPLLCTRL2 */ 56682e09ffSMasahiro Yamada tmp |= SC_PLLCTRL2_NRSTDS; 57682e09ffSMasahiro Yamada writel(tmp, base + 4); 58682e09ffSMasahiro Yamada 59682e09ffSMasahiro Yamada iounmap(base); 60682e09ffSMasahiro Yamada 61682e09ffSMasahiro Yamada return 0; 62682e09ffSMasahiro Yamada } 63682e09ffSMasahiro Yamada 64682e09ffSMasahiro Yamada int uniphier_ld20_sscpll_ssc_en(unsigned long reg_base) 65682e09ffSMasahiro Yamada { 66682e09ffSMasahiro Yamada void __iomem *base; 67682e09ffSMasahiro Yamada u32 tmp; 68682e09ffSMasahiro Yamada 69682e09ffSMasahiro Yamada base = ioremap(reg_base, SZ_16); 70682e09ffSMasahiro Yamada if (!base) 71682e09ffSMasahiro Yamada return -ENOMEM; 72682e09ffSMasahiro Yamada 73682e09ffSMasahiro Yamada tmp = readl(base); /* SSCPLLCTRL */ 74682e09ffSMasahiro Yamada tmp |= SC_PLLCTRL_SSC_EN; 75682e09ffSMasahiro Yamada writel(tmp, base); 76682e09ffSMasahiro Yamada 77682e09ffSMasahiro Yamada iounmap(base); 78682e09ffSMasahiro Yamada 79682e09ffSMasahiro Yamada return 0; 80682e09ffSMasahiro Yamada } 81682e09ffSMasahiro Yamada 82bc647958SMasahiro Yamada int uniphier_ld20_sscpll_set_regi(unsigned long reg_base, unsigned regi) 83bc647958SMasahiro Yamada { 84bc647958SMasahiro Yamada void __iomem *base; 85bc647958SMasahiro Yamada u32 tmp; 86bc647958SMasahiro Yamada 87bc647958SMasahiro Yamada base = ioremap(reg_base, SZ_16); 88bc647958SMasahiro Yamada if (!base) 89bc647958SMasahiro Yamada return -ENOMEM; 90bc647958SMasahiro Yamada 91*4013bbb1SDai Okamura tmp = readl(base + 8); /* SSCPLLCTRL3 */ 92bc647958SMasahiro Yamada tmp &= ~SC_PLLCTRL3_REGI_MASK; 93bc647958SMasahiro Yamada tmp |= regi << SC_PLLCTRL3_REGI_SHIFT; 94bc647958SMasahiro Yamada writel(tmp, base + 8); 95bc647958SMasahiro Yamada 96bc647958SMasahiro Yamada iounmap(base); 97bc647958SMasahiro Yamada 98bc647958SMasahiro Yamada return 0; 99bc647958SMasahiro Yamada } 100bc647958SMasahiro Yamada 101682e09ffSMasahiro Yamada int uniphier_ld20_vpll27_init(unsigned long reg_base) 102682e09ffSMasahiro Yamada { 103682e09ffSMasahiro Yamada void __iomem *base; 104682e09ffSMasahiro Yamada u32 tmp; 105682e09ffSMasahiro Yamada 106682e09ffSMasahiro Yamada base = ioremap(reg_base, SZ_16); 107682e09ffSMasahiro Yamada if (!base) 108682e09ffSMasahiro Yamada return -ENOMEM; 109682e09ffSMasahiro Yamada 110682e09ffSMasahiro Yamada tmp = readl(base); /* VPLL27CTRL */ 111682e09ffSMasahiro Yamada tmp |= SC_VPLL27CTRL_WP; /* write protect off */ 112682e09ffSMasahiro Yamada writel(tmp, base); 113682e09ffSMasahiro Yamada 114682e09ffSMasahiro Yamada tmp = readl(base + 8); /* VPLL27CTRL3 */ 115682e09ffSMasahiro Yamada tmp |= SC_VPLL27CTRL3_K_LD; 116682e09ffSMasahiro Yamada writel(tmp, base + 8); 117682e09ffSMasahiro Yamada 118682e09ffSMasahiro Yamada tmp = readl(base); /* VPLL27CTRL */ 119682e09ffSMasahiro Yamada tmp &= ~SC_VPLL27CTRL_WP; /* write protect on */ 120682e09ffSMasahiro Yamada writel(tmp, base); 121682e09ffSMasahiro Yamada 122682e09ffSMasahiro Yamada iounmap(base); 123682e09ffSMasahiro Yamada 124682e09ffSMasahiro Yamada return 0; 125682e09ffSMasahiro Yamada } 126682e09ffSMasahiro Yamada 127682e09ffSMasahiro Yamada int uniphier_ld20_dspll_init(unsigned long reg_base) 128682e09ffSMasahiro Yamada { 129682e09ffSMasahiro Yamada void __iomem *base; 130682e09ffSMasahiro Yamada u32 tmp; 131682e09ffSMasahiro Yamada 132682e09ffSMasahiro Yamada base = ioremap(reg_base, SZ_16); 133682e09ffSMasahiro Yamada if (!base) 134682e09ffSMasahiro Yamada return -ENOMEM; 135682e09ffSMasahiro Yamada 136*4013bbb1SDai Okamura tmp = readl(base + 4); /* DSPLLCTRL2 */ 137682e09ffSMasahiro Yamada tmp |= SC_DSPLLCTRL2_K_LD; 138*4013bbb1SDai Okamura writel(tmp, base + 4); 139682e09ffSMasahiro Yamada 140682e09ffSMasahiro Yamada iounmap(base); 141682e09ffSMasahiro Yamada 142682e09ffSMasahiro Yamada return 0; 143682e09ffSMasahiro Yamada } 144