^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * arch/arm/mach-ep93xx/clock.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Clock control for Cirrus EP93xx chips.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #define pr_fmt(fmt) "ep93xx " KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/clkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/soc/cirrus/ep93xx.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "hardware.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <asm/div64.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "soc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) struct clk {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct clk *parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) unsigned long rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) int users;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) int sw_locked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) void __iomem *enable_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) u32 enable_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) unsigned long (*get_rate)(struct clk *clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) int (*set_rate)(struct clk *clk, unsigned long rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) static unsigned long get_uart_rate(struct clk *clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static int set_keytchclk_rate(struct clk *clk, unsigned long rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) static int set_div_rate(struct clk *clk, unsigned long rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static int set_i2s_sclk_rate(struct clk *clk, unsigned long rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static int set_i2s_lrclk_rate(struct clk *clk, unsigned long rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) static struct clk clk_xtali = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) .rate = EP93XX_EXT_CLK_RATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) static struct clk clk_uart1 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) .parent = &clk_xtali,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) .sw_locked = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) .enable_reg = EP93XX_SYSCON_DEVCFG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) .enable_mask = EP93XX_SYSCON_DEVCFG_U1EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) .get_rate = get_uart_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) static struct clk clk_uart2 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) .parent = &clk_xtali,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) .sw_locked = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) .enable_reg = EP93XX_SYSCON_DEVCFG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) .enable_mask = EP93XX_SYSCON_DEVCFG_U2EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) .get_rate = get_uart_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) static struct clk clk_uart3 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) .parent = &clk_xtali,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) .sw_locked = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) .enable_reg = EP93XX_SYSCON_DEVCFG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) .enable_mask = EP93XX_SYSCON_DEVCFG_U3EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) .get_rate = get_uart_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) static struct clk clk_pll1 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) .parent = &clk_xtali,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) static struct clk clk_f = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) .parent = &clk_pll1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static struct clk clk_h = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) .parent = &clk_pll1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) static struct clk clk_p = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) .parent = &clk_pll1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) static struct clk clk_pll2 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) .parent = &clk_xtali,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) static struct clk clk_usb_host = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) .parent = &clk_pll2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) .enable_reg = EP93XX_SYSCON_PWRCNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) .enable_mask = EP93XX_SYSCON_PWRCNT_USH_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) static struct clk clk_keypad = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) .parent = &clk_xtali,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) .sw_locked = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) .enable_reg = EP93XX_SYSCON_KEYTCHCLKDIV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) .enable_mask = EP93XX_SYSCON_KEYTCHCLKDIV_KEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) .set_rate = set_keytchclk_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) static struct clk clk_adc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) .parent = &clk_xtali,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) .sw_locked = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) .enable_reg = EP93XX_SYSCON_KEYTCHCLKDIV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) .enable_mask = EP93XX_SYSCON_KEYTCHCLKDIV_TSEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) .set_rate = set_keytchclk_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) static struct clk clk_spi = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) .parent = &clk_xtali,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) .rate = EP93XX_EXT_CLK_RATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) static struct clk clk_pwm = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) .parent = &clk_xtali,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) .rate = EP93XX_EXT_CLK_RATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) static struct clk clk_video = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) .sw_locked = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) .enable_reg = EP93XX_SYSCON_VIDCLKDIV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) .enable_mask = EP93XX_SYSCON_CLKDIV_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) .set_rate = set_div_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) static struct clk clk_i2s_mclk = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) .sw_locked = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) .enable_reg = EP93XX_SYSCON_I2SCLKDIV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) .enable_mask = EP93XX_SYSCON_CLKDIV_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) .set_rate = set_div_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static struct clk clk_i2s_sclk = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) .sw_locked = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) .parent = &clk_i2s_mclk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) .enable_reg = EP93XX_SYSCON_I2SCLKDIV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) .enable_mask = EP93XX_SYSCON_I2SCLKDIV_SENA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) .set_rate = set_i2s_sclk_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) static struct clk clk_i2s_lrclk = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) .sw_locked = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) .parent = &clk_i2s_sclk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) .enable_reg = EP93XX_SYSCON_I2SCLKDIV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) .enable_mask = EP93XX_SYSCON_I2SCLKDIV_SENA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) .set_rate = set_i2s_lrclk_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) /* DMA Clocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) static struct clk clk_m2p0 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) .parent = &clk_h,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) .enable_reg = EP93XX_SYSCON_PWRCNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) static struct clk clk_m2p1 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) .parent = &clk_h,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) .enable_reg = EP93XX_SYSCON_PWRCNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) static struct clk clk_m2p2 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) .parent = &clk_h,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) .enable_reg = EP93XX_SYSCON_PWRCNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) static struct clk clk_m2p3 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) .parent = &clk_h,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) .enable_reg = EP93XX_SYSCON_PWRCNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) static struct clk clk_m2p4 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) .parent = &clk_h,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) .enable_reg = EP93XX_SYSCON_PWRCNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) static struct clk clk_m2p5 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) .parent = &clk_h,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) .enable_reg = EP93XX_SYSCON_PWRCNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static struct clk clk_m2p6 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) .parent = &clk_h,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) .enable_reg = EP93XX_SYSCON_PWRCNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) static struct clk clk_m2p7 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) .parent = &clk_h,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) .enable_reg = EP93XX_SYSCON_PWRCNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) static struct clk clk_m2p8 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) .parent = &clk_h,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) .enable_reg = EP93XX_SYSCON_PWRCNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) static struct clk clk_m2p9 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) .parent = &clk_h,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) .enable_reg = EP93XX_SYSCON_PWRCNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) static struct clk clk_m2m0 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) .parent = &clk_h,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) .enable_reg = EP93XX_SYSCON_PWRCNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2M0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) static struct clk clk_m2m1 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) .parent = &clk_h,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) .enable_reg = EP93XX_SYSCON_PWRCNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2M1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) #define INIT_CK(dev,con,ck) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) { .dev_id = dev, .con_id = con, .clk = ck }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) static struct clk_lookup clocks[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) INIT_CK(NULL, "xtali", &clk_xtali),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) INIT_CK("apb:uart1", NULL, &clk_uart1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) INIT_CK("apb:uart2", NULL, &clk_uart2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) INIT_CK("apb:uart3", NULL, &clk_uart3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) INIT_CK(NULL, "pll1", &clk_pll1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) INIT_CK(NULL, "fclk", &clk_f),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) INIT_CK(NULL, "hclk", &clk_h),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) INIT_CK(NULL, "apb_pclk", &clk_p),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) INIT_CK(NULL, "pll2", &clk_pll2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) INIT_CK("ohci-platform", NULL, &clk_usb_host),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) INIT_CK("ep93xx-keypad", NULL, &clk_keypad),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) INIT_CK("ep93xx-adc", NULL, &clk_adc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) INIT_CK("ep93xx-fb", NULL, &clk_video),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) INIT_CK("ep93xx-spi.0", NULL, &clk_spi),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) INIT_CK("ep93xx-i2s", "mclk", &clk_i2s_mclk),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) INIT_CK("ep93xx-i2s", "sclk", &clk_i2s_sclk),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) INIT_CK("ep93xx-i2s", "lrclk", &clk_i2s_lrclk),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) INIT_CK(NULL, "pwm_clk", &clk_pwm),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) INIT_CK(NULL, "m2p0", &clk_m2p0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) INIT_CK(NULL, "m2p1", &clk_m2p1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) INIT_CK(NULL, "m2p2", &clk_m2p2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) INIT_CK(NULL, "m2p3", &clk_m2p3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) INIT_CK(NULL, "m2p4", &clk_m2p4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) INIT_CK(NULL, "m2p5", &clk_m2p5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) INIT_CK(NULL, "m2p6", &clk_m2p6),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) INIT_CK(NULL, "m2p7", &clk_m2p7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) INIT_CK(NULL, "m2p8", &clk_m2p8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) INIT_CK(NULL, "m2p9", &clk_m2p9),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) INIT_CK(NULL, "m2m0", &clk_m2m0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) INIT_CK(NULL, "m2m1", &clk_m2m1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) static DEFINE_SPINLOCK(clk_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) static void __clk_enable(struct clk *clk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) if (!clk->users++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) if (clk->parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) __clk_enable(clk->parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) if (clk->enable_reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) u32 v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) v = __raw_readl(clk->enable_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) v |= clk->enable_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) if (clk->sw_locked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) ep93xx_syscon_swlocked_write(v, clk->enable_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) __raw_writel(v, clk->enable_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) int clk_enable(struct clk *clk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (!clk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) spin_lock_irqsave(&clk_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) __clk_enable(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) spin_unlock_irqrestore(&clk_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) EXPORT_SYMBOL(clk_enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) static void __clk_disable(struct clk *clk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) if (!--clk->users) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) if (clk->enable_reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) u32 v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) v = __raw_readl(clk->enable_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) v &= ~clk->enable_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) if (clk->sw_locked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) ep93xx_syscon_swlocked_write(v, clk->enable_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) __raw_writel(v, clk->enable_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) if (clk->parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) __clk_disable(clk->parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) void clk_disable(struct clk *clk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) if (!clk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) spin_lock_irqsave(&clk_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) __clk_disable(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) spin_unlock_irqrestore(&clk_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) EXPORT_SYMBOL(clk_disable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) static unsigned long get_uart_rate(struct clk *clk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) unsigned long rate = clk_get_rate(clk->parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) value = __raw_readl(EP93XX_SYSCON_PWRCNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if (value & EP93XX_SYSCON_PWRCNT_UARTBAUD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) return rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) return rate / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) unsigned long clk_get_rate(struct clk *clk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) if (clk->get_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) return clk->get_rate(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) return clk->rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) EXPORT_SYMBOL(clk_get_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) static int set_keytchclk_rate(struct clk *clk, unsigned long rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) u32 div_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) val = __raw_readl(clk->enable_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) * The Key Matrix and ADC clocks are configured using the same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) * System Controller register. The clock used will be either
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) * 1/4 or 1/16 the external clock rate depending on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) * EP93XX_SYSCON_KEYTCHCLKDIV_KDIV/EP93XX_SYSCON_KEYTCHCLKDIV_ADIV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) * bit being set or cleared.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) div_bit = clk->enable_mask >> 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) if (rate == EP93XX_KEYTCHCLK_DIV4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) val |= div_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) else if (rate == EP93XX_KEYTCHCLK_DIV16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) val &= ~div_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) ep93xx_syscon_swlocked_write(val, clk->enable_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) clk->rate = rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) static int calc_clk_div(struct clk *clk, unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) int *psel, int *esel, int *pdiv, int *div)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) struct clk *mclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) unsigned long max_rate, actual_rate, mclk_rate, rate_err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) int i, found = 0, __div = 0, __pdiv = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) /* Don't exceed the maximum rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) max_rate = max3(clk_pll1.rate / 4, clk_pll2.rate / 4, clk_xtali.rate / 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) rate = min(rate, max_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) * Try the two pll's and the external clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) * Because the valid predividers are 2, 2.5 and 3, we multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) * all the clocks by 2 to avoid floating point math.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) * This is based on the algorithm in the ep93xx raster guide:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) * http://be-a-maverick.com/en/pubs/appNote/AN269REV1.pdf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) for (i = 0; i < 3; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if (i == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) mclk = &clk_xtali;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) else if (i == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) mclk = &clk_pll1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) mclk = &clk_pll2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) mclk_rate = mclk->rate * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) /* Try each predivider value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) for (__pdiv = 4; __pdiv <= 6; __pdiv++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) __div = mclk_rate / (rate * __pdiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) if (__div < 2 || __div > 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) actual_rate = mclk_rate / (__pdiv * __div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if (!found || abs(actual_rate - rate) < rate_err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) *pdiv = __pdiv - 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) *div = __div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) *psel = (i == 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) *esel = (i != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) clk->parent = mclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) clk->rate = actual_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) rate_err = abs(actual_rate - rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) found = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) if (!found)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) static int set_div_rate(struct clk *clk, unsigned long rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) int err, psel = 0, esel = 0, pdiv = 0, div = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) err = calc_clk_div(clk, rate, &psel, &esel, &pdiv, &div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) /* Clear the esel, psel, pdiv and div bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) val = __raw_readl(clk->enable_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) val &= ~0x7fff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) /* Set the new esel, psel, pdiv and div bits for the new clock rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) val |= (esel ? EP93XX_SYSCON_CLKDIV_ESEL : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) (psel ? EP93XX_SYSCON_CLKDIV_PSEL : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) (pdiv << EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) | div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) ep93xx_syscon_swlocked_write(val, clk->enable_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) static int set_i2s_sclk_rate(struct clk *clk, unsigned long rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) unsigned val = __raw_readl(clk->enable_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (rate == clk_i2s_mclk.rate / 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) ep93xx_syscon_swlocked_write(val & ~EP93XX_I2SCLKDIV_SDIV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) clk->enable_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) else if (rate == clk_i2s_mclk.rate / 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) ep93xx_syscon_swlocked_write(val | EP93XX_I2SCLKDIV_SDIV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) clk->enable_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) clk_i2s_sclk.rate = rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) static int set_i2s_lrclk_rate(struct clk *clk, unsigned long rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) unsigned val = __raw_readl(clk->enable_reg) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) ~EP93XX_I2SCLKDIV_LRDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) if (rate == clk_i2s_sclk.rate / 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) ep93xx_syscon_swlocked_write(val | EP93XX_I2SCLKDIV_LRDIV32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) clk->enable_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) else if (rate == clk_i2s_sclk.rate / 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) ep93xx_syscon_swlocked_write(val | EP93XX_I2SCLKDIV_LRDIV64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) clk->enable_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) else if (rate == clk_i2s_sclk.rate / 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) ep93xx_syscon_swlocked_write(val | EP93XX_I2SCLKDIV_LRDIV128,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) clk->enable_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) clk_i2s_lrclk.rate = rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) int clk_set_rate(struct clk *clk, unsigned long rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) if (clk->set_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) return clk->set_rate(clk, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) EXPORT_SYMBOL(clk_set_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) long clk_round_rate(struct clk *clk, unsigned long rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) WARN_ON(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) EXPORT_SYMBOL(clk_round_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) int clk_set_parent(struct clk *clk, struct clk *parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) WARN_ON(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) EXPORT_SYMBOL(clk_set_parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) struct clk *clk_get_parent(struct clk *clk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) return clk->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) EXPORT_SYMBOL(clk_get_parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) static char fclk_divisors[] = { 1, 2, 4, 8, 16, 1, 1, 1 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) static char hclk_divisors[] = { 1, 2, 4, 5, 6, 8, 16, 32 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) static char pclk_divisors[] = { 1, 2, 4, 8 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) * PLL rate = 14.7456 MHz * (X1FBD + 1) * (X2FBD + 1) / (X2IPD + 1) / 2^PS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) static unsigned long calc_pll_rate(u32 config_word)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) unsigned long long rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) rate = clk_xtali.rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) rate *= ((config_word >> 11) & 0x1f) + 1; /* X1FBD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) rate *= ((config_word >> 5) & 0x3f) + 1; /* X2FBD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) do_div(rate, (config_word & 0x1f) + 1); /* X2IPD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) for (i = 0; i < ((config_word >> 16) & 3); i++) /* PS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) rate >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) return (unsigned long)rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) static void __init ep93xx_dma_clock_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) clk_m2p0.rate = clk_h.rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) clk_m2p1.rate = clk_h.rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) clk_m2p2.rate = clk_h.rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) clk_m2p3.rate = clk_h.rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) clk_m2p4.rate = clk_h.rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) clk_m2p5.rate = clk_h.rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) clk_m2p6.rate = clk_h.rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) clk_m2p7.rate = clk_h.rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) clk_m2p8.rate = clk_h.rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) clk_m2p9.rate = clk_h.rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) clk_m2m0.rate = clk_h.rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) clk_m2m1.rate = clk_h.rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) static int __init ep93xx_clock_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) /* Determine the bootloader configured pll1 rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) value = __raw_readl(EP93XX_SYSCON_CLKSET1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) if (!(value & EP93XX_SYSCON_CLKSET1_NBYP1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) clk_pll1.rate = clk_xtali.rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) clk_pll1.rate = calc_pll_rate(value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) /* Initialize the pll1 derived clocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) clk_f.rate = clk_pll1.rate / fclk_divisors[(value >> 25) & 0x7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) clk_h.rate = clk_pll1.rate / hclk_divisors[(value >> 20) & 0x7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) clk_p.rate = clk_h.rate / pclk_divisors[(value >> 18) & 0x3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) ep93xx_dma_clock_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) /* Determine the bootloader configured pll2 rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) value = __raw_readl(EP93XX_SYSCON_CLKSET2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) if (!(value & EP93XX_SYSCON_CLKSET2_NBYP2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) clk_pll2.rate = clk_xtali.rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) else if (value & EP93XX_SYSCON_CLKSET2_PLL2_EN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) clk_pll2.rate = calc_pll_rate(value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) clk_pll2.rate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) /* Initialize the pll2 derived clocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) clk_usb_host.rate = clk_pll2.rate / (((value >> 28) & 0xf) + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) * EP93xx SSP clock rate was doubled in version E2. For more information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) * see:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) * http://www.cirrus.com/en/pubs/appNote/AN273REV4.pdf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) if (ep93xx_chip_revision() < EP93XX_CHIP_REV_E2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) clk_spi.rate /= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) pr_info("PLL1 running at %ld MHz, PLL2 at %ld MHz\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) clk_pll1.rate / 1000000, clk_pll2.rate / 1000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) pr_info("FCLK %ld MHz, HCLK %ld MHz, PCLK %ld MHz\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) clk_f.rate / 1000000, clk_h.rate / 1000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) clk_p.rate / 1000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) clkdev_add_table(clocks, ARRAY_SIZE(clocks));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) postcore_initcall(ep93xx_clock_init);