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; 51*c30c44e7SDai Okamura writel(tmp, base + 4); 52682e09ffSMasahiro Yamada 53682e09ffSMasahiro Yamada udelay(50); 54682e09ffSMasahiro Yamada } 55682e09ffSMasahiro Yamada 56682e09ffSMasahiro Yamada tmp = readl(base + 4); /* SSCPLLCTRL2 */ 57682e09ffSMasahiro Yamada tmp |= SC_PLLCTRL2_NRSTDS; 58682e09ffSMasahiro Yamada writel(tmp, base + 4); 59682e09ffSMasahiro Yamada 60682e09ffSMasahiro Yamada iounmap(base); 61682e09ffSMasahiro Yamada 62682e09ffSMasahiro Yamada return 0; 63682e09ffSMasahiro Yamada } 64682e09ffSMasahiro Yamada 65682e09ffSMasahiro Yamada int uniphier_ld20_sscpll_ssc_en(unsigned long reg_base) 66682e09ffSMasahiro Yamada { 67682e09ffSMasahiro Yamada void __iomem *base; 68682e09ffSMasahiro Yamada u32 tmp; 69682e09ffSMasahiro Yamada 70682e09ffSMasahiro Yamada base = ioremap(reg_base, SZ_16); 71682e09ffSMasahiro Yamada if (!base) 72682e09ffSMasahiro Yamada return -ENOMEM; 73682e09ffSMasahiro Yamada 74682e09ffSMasahiro Yamada tmp = readl(base); /* SSCPLLCTRL */ 75682e09ffSMasahiro Yamada tmp |= SC_PLLCTRL_SSC_EN; 76682e09ffSMasahiro Yamada writel(tmp, base); 77682e09ffSMasahiro Yamada 78682e09ffSMasahiro Yamada iounmap(base); 79682e09ffSMasahiro Yamada 80682e09ffSMasahiro Yamada return 0; 81682e09ffSMasahiro Yamada } 82682e09ffSMasahiro Yamada 83bc647958SMasahiro Yamada int uniphier_ld20_sscpll_set_regi(unsigned long reg_base, unsigned regi) 84bc647958SMasahiro Yamada { 85bc647958SMasahiro Yamada void __iomem *base; 86bc647958SMasahiro Yamada u32 tmp; 87bc647958SMasahiro Yamada 88bc647958SMasahiro Yamada base = ioremap(reg_base, SZ_16); 89bc647958SMasahiro Yamada if (!base) 90bc647958SMasahiro Yamada return -ENOMEM; 91bc647958SMasahiro Yamada 924013bbb1SDai Okamura tmp = readl(base + 8); /* SSCPLLCTRL3 */ 93bc647958SMasahiro Yamada tmp &= ~SC_PLLCTRL3_REGI_MASK; 94bc647958SMasahiro Yamada tmp |= regi << SC_PLLCTRL3_REGI_SHIFT; 95bc647958SMasahiro Yamada writel(tmp, base + 8); 96bc647958SMasahiro Yamada 97bc647958SMasahiro Yamada iounmap(base); 98bc647958SMasahiro Yamada 99bc647958SMasahiro Yamada return 0; 100bc647958SMasahiro Yamada } 101bc647958SMasahiro Yamada 102682e09ffSMasahiro Yamada int uniphier_ld20_vpll27_init(unsigned long reg_base) 103682e09ffSMasahiro Yamada { 104682e09ffSMasahiro Yamada void __iomem *base; 105682e09ffSMasahiro Yamada u32 tmp; 106682e09ffSMasahiro Yamada 107682e09ffSMasahiro Yamada base = ioremap(reg_base, SZ_16); 108682e09ffSMasahiro Yamada if (!base) 109682e09ffSMasahiro Yamada return -ENOMEM; 110682e09ffSMasahiro Yamada 111682e09ffSMasahiro Yamada tmp = readl(base); /* VPLL27CTRL */ 112682e09ffSMasahiro Yamada tmp |= SC_VPLL27CTRL_WP; /* write protect off */ 113682e09ffSMasahiro Yamada writel(tmp, base); 114682e09ffSMasahiro Yamada 115682e09ffSMasahiro Yamada tmp = readl(base + 8); /* VPLL27CTRL3 */ 116682e09ffSMasahiro Yamada tmp |= SC_VPLL27CTRL3_K_LD; 117682e09ffSMasahiro Yamada writel(tmp, base + 8); 118682e09ffSMasahiro Yamada 119682e09ffSMasahiro Yamada tmp = readl(base); /* VPLL27CTRL */ 120682e09ffSMasahiro Yamada tmp &= ~SC_VPLL27CTRL_WP; /* write protect on */ 121682e09ffSMasahiro Yamada writel(tmp, base); 122682e09ffSMasahiro Yamada 123682e09ffSMasahiro Yamada iounmap(base); 124682e09ffSMasahiro Yamada 125682e09ffSMasahiro Yamada return 0; 126682e09ffSMasahiro Yamada } 127682e09ffSMasahiro Yamada 128682e09ffSMasahiro Yamada int uniphier_ld20_dspll_init(unsigned long reg_base) 129682e09ffSMasahiro Yamada { 130682e09ffSMasahiro Yamada void __iomem *base; 131682e09ffSMasahiro Yamada u32 tmp; 132682e09ffSMasahiro Yamada 133682e09ffSMasahiro Yamada base = ioremap(reg_base, SZ_16); 134682e09ffSMasahiro Yamada if (!base) 135682e09ffSMasahiro Yamada return -ENOMEM; 136682e09ffSMasahiro Yamada 1374013bbb1SDai Okamura tmp = readl(base + 4); /* DSPLLCTRL2 */ 138682e09ffSMasahiro Yamada tmp |= SC_DSPLLCTRL2_K_LD; 1394013bbb1SDai Okamura writel(tmp, base + 4); 140682e09ffSMasahiro Yamada 141682e09ffSMasahiro Yamada iounmap(base); 142682e09ffSMasahiro Yamada 143682e09ffSMasahiro Yamada return 0; 144682e09ffSMasahiro Yamada } 145