^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (c) 2014 Oleksij Rempel <linux@rempel-privat.de>.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/clkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/clk-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <dt-bindings/clock/alphascale,asm9260.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define HW_AHBCLKCTRL0 0x0020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define HW_AHBCLKCTRL1 0x0030
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define HW_SYSPLLCTRL 0x0100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define HW_MAINCLKSEL 0x0120
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define HW_MAINCLKUEN 0x0124
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define HW_UARTCLKSEL 0x0128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define HW_UARTCLKUEN 0x012c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define HW_I2S0CLKSEL 0x0130
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define HW_I2S0CLKUEN 0x0134
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define HW_I2S1CLKSEL 0x0138
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define HW_I2S1CLKUEN 0x013c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define HW_WDTCLKSEL 0x0160
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define HW_WDTCLKUEN 0x0164
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define HW_CLKOUTCLKSEL 0x0170
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define HW_CLKOUTCLKUEN 0x0174
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define HW_CPUCLKDIV 0x017c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define HW_SYSAHBCLKDIV 0x0180
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define HW_I2S0MCLKDIV 0x0190
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define HW_I2S0SCLKDIV 0x0194
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define HW_I2S1MCLKDIV 0x0188
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define HW_I2S1SCLKDIV 0x018c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define HW_UART0CLKDIV 0x0198
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define HW_UART1CLKDIV 0x019c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define HW_UART2CLKDIV 0x01a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define HW_UART3CLKDIV 0x01a4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define HW_UART4CLKDIV 0x01a8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define HW_UART5CLKDIV 0x01ac
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define HW_UART6CLKDIV 0x01b0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define HW_UART7CLKDIV 0x01b4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define HW_UART8CLKDIV 0x01b8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define HW_UART9CLKDIV 0x01bc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define HW_SPI0CLKDIV 0x01c0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define HW_SPI1CLKDIV 0x01c4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define HW_QUADSPICLKDIV 0x01c8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define HW_SSP0CLKDIV 0x01d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define HW_NANDCLKDIV 0x01d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define HW_TRACECLKDIV 0x01e0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define HW_CAMMCLKDIV 0x01e8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define HW_WDTCLKDIV 0x01ec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define HW_CLKOUTCLKDIV 0x01f4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define HW_MACCLKDIV 0x01f8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define HW_LCDCLKDIV 0x01fc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define HW_ADCANACLKDIV 0x0200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) static struct clk_hw_onecell_data *clk_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static DEFINE_SPINLOCK(asm9260_clk_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct asm9260_div_clk {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) unsigned int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) const char *parent_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) struct asm9260_gate_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) unsigned int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) const char *parent_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) u8 bit_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) struct asm9260_mux_clock {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) u8 mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) u32 *table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) const char **parent_names;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) u8 num_parents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) unsigned long offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) static void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) static const struct asm9260_div_clk asm9260_div_clks[] __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) { CLKID_SYS_CPU, "cpu_div", "main_gate", HW_CPUCLKDIV },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) { CLKID_SYS_AHB, "ahb_div", "cpu_div", HW_SYSAHBCLKDIV },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) /* i2s has two deviders: one for only external mclk and internal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * devider for all clks. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) { CLKID_SYS_I2S0M, "i2s0m_div", "i2s0_mclk", HW_I2S0MCLKDIV },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) { CLKID_SYS_I2S1M, "i2s1m_div", "i2s1_mclk", HW_I2S1MCLKDIV },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) { CLKID_SYS_I2S0S, "i2s0s_div", "i2s0_gate", HW_I2S0SCLKDIV },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) { CLKID_SYS_I2S1S, "i2s1s_div", "i2s0_gate", HW_I2S1SCLKDIV },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) { CLKID_SYS_UART0, "uart0_div", "uart_gate", HW_UART0CLKDIV },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) { CLKID_SYS_UART1, "uart1_div", "uart_gate", HW_UART1CLKDIV },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) { CLKID_SYS_UART2, "uart2_div", "uart_gate", HW_UART2CLKDIV },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) { CLKID_SYS_UART3, "uart3_div", "uart_gate", HW_UART3CLKDIV },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) { CLKID_SYS_UART4, "uart4_div", "uart_gate", HW_UART4CLKDIV },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) { CLKID_SYS_UART5, "uart5_div", "uart_gate", HW_UART5CLKDIV },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) { CLKID_SYS_UART6, "uart6_div", "uart_gate", HW_UART6CLKDIV },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) { CLKID_SYS_UART7, "uart7_div", "uart_gate", HW_UART7CLKDIV },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) { CLKID_SYS_UART8, "uart8_div", "uart_gate", HW_UART8CLKDIV },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) { CLKID_SYS_UART9, "uart9_div", "uart_gate", HW_UART9CLKDIV },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) { CLKID_SYS_SPI0, "spi0_div", "main_gate", HW_SPI0CLKDIV },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) { CLKID_SYS_SPI1, "spi1_div", "main_gate", HW_SPI1CLKDIV },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) { CLKID_SYS_QUADSPI, "quadspi_div", "main_gate", HW_QUADSPICLKDIV },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) { CLKID_SYS_SSP0, "ssp0_div", "main_gate", HW_SSP0CLKDIV },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) { CLKID_SYS_NAND, "nand_div", "main_gate", HW_NANDCLKDIV },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) { CLKID_SYS_TRACE, "trace_div", "main_gate", HW_TRACECLKDIV },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) { CLKID_SYS_CAMM, "camm_div", "main_gate", HW_CAMMCLKDIV },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) { CLKID_SYS_MAC, "mac_div", "main_gate", HW_MACCLKDIV },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) { CLKID_SYS_LCD, "lcd_div", "main_gate", HW_LCDCLKDIV },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) { CLKID_SYS_ADCANA, "adcana_div", "main_gate", HW_ADCANACLKDIV },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) { CLKID_SYS_WDT, "wdt_div", "wdt_gate", HW_WDTCLKDIV },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) { CLKID_SYS_CLKOUT, "clkout_div", "clkout_gate", HW_CLKOUTCLKDIV },
^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 const struct asm9260_gate_data asm9260_mux_gates[] __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) { 0, "main_gate", "main_mux", HW_MAINCLKUEN, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) { 0, "uart_gate", "uart_mux", HW_UARTCLKUEN, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) { 0, "i2s0_gate", "i2s0_mux", HW_I2S0CLKUEN, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) { 0, "i2s1_gate", "i2s1_mux", HW_I2S1CLKUEN, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) { 0, "wdt_gate", "wdt_mux", HW_WDTCLKUEN, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) { 0, "clkout_gate", "clkout_mux", HW_CLKOUTCLKUEN, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) static const struct asm9260_gate_data asm9260_ahb_gates[] __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) /* ahb gates */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) { CLKID_AHB_ROM, "rom", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) HW_AHBCLKCTRL0, 1, CLK_IGNORE_UNUSED},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) { CLKID_AHB_RAM, "ram", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) HW_AHBCLKCTRL0, 2, CLK_IGNORE_UNUSED},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) { CLKID_AHB_GPIO, "gpio", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) HW_AHBCLKCTRL0, 4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) { CLKID_AHB_MAC, "mac", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) HW_AHBCLKCTRL0, 5 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) { CLKID_AHB_EMI, "emi", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) HW_AHBCLKCTRL0, 6, CLK_IGNORE_UNUSED},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) { CLKID_AHB_USB0, "usb0", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) HW_AHBCLKCTRL0, 7 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) { CLKID_AHB_USB1, "usb1", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) HW_AHBCLKCTRL0, 8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) { CLKID_AHB_DMA0, "dma0", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) HW_AHBCLKCTRL0, 9 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) { CLKID_AHB_DMA1, "dma1", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) HW_AHBCLKCTRL0, 10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) { CLKID_AHB_UART0, "uart0", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) HW_AHBCLKCTRL0, 11 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) { CLKID_AHB_UART1, "uart1", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) HW_AHBCLKCTRL0, 12 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) { CLKID_AHB_UART2, "uart2", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) HW_AHBCLKCTRL0, 13 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) { CLKID_AHB_UART3, "uart3", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) HW_AHBCLKCTRL0, 14 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) { CLKID_AHB_UART4, "uart4", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) HW_AHBCLKCTRL0, 15 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) { CLKID_AHB_UART5, "uart5", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) HW_AHBCLKCTRL0, 16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) { CLKID_AHB_UART6, "uart6", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) HW_AHBCLKCTRL0, 17 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) { CLKID_AHB_UART7, "uart7", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) HW_AHBCLKCTRL0, 18 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) { CLKID_AHB_UART8, "uart8", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) HW_AHBCLKCTRL0, 19 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) { CLKID_AHB_UART9, "uart9", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) HW_AHBCLKCTRL0, 20 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) { CLKID_AHB_I2S0, "i2s0", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) HW_AHBCLKCTRL0, 21 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) { CLKID_AHB_I2C0, "i2c0", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) HW_AHBCLKCTRL0, 22 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) { CLKID_AHB_I2C1, "i2c1", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) HW_AHBCLKCTRL0, 23 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) { CLKID_AHB_SSP0, "ssp0", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) HW_AHBCLKCTRL0, 24 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) { CLKID_AHB_IOCONFIG, "ioconf", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) HW_AHBCLKCTRL0, 25 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) { CLKID_AHB_WDT, "wdt", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) HW_AHBCLKCTRL0, 26 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) { CLKID_AHB_CAN0, "can0", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) HW_AHBCLKCTRL0, 27 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) { CLKID_AHB_CAN1, "can1", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) HW_AHBCLKCTRL0, 28 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) { CLKID_AHB_MPWM, "mpwm", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) HW_AHBCLKCTRL0, 29 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) { CLKID_AHB_SPI0, "spi0", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) HW_AHBCLKCTRL0, 30 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) { CLKID_AHB_SPI1, "spi1", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) HW_AHBCLKCTRL0, 31 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) { CLKID_AHB_QEI, "qei", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) HW_AHBCLKCTRL1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) { CLKID_AHB_QUADSPI0, "quadspi0", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) HW_AHBCLKCTRL1, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) { CLKID_AHB_CAMIF, "capmif", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) HW_AHBCLKCTRL1, 2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) { CLKID_AHB_LCDIF, "lcdif", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) HW_AHBCLKCTRL1, 3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) { CLKID_AHB_TIMER0, "timer0", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) HW_AHBCLKCTRL1, 4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) { CLKID_AHB_TIMER1, "timer1", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) HW_AHBCLKCTRL1, 5 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) { CLKID_AHB_TIMER2, "timer2", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) HW_AHBCLKCTRL1, 6 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) { CLKID_AHB_TIMER3, "timer3", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) HW_AHBCLKCTRL1, 7 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) { CLKID_AHB_IRQ, "irq", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) HW_AHBCLKCTRL1, 8, CLK_IGNORE_UNUSED},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) { CLKID_AHB_RTC, "rtc", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) HW_AHBCLKCTRL1, 9 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) { CLKID_AHB_NAND, "nand", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) HW_AHBCLKCTRL1, 10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) { CLKID_AHB_ADC0, "adc0", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) HW_AHBCLKCTRL1, 11 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) { CLKID_AHB_LED, "led", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) HW_AHBCLKCTRL1, 12 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) { CLKID_AHB_DAC0, "dac0", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) HW_AHBCLKCTRL1, 13 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) { CLKID_AHB_LCD, "lcd", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) HW_AHBCLKCTRL1, 14 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) { CLKID_AHB_I2S1, "i2s1", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) HW_AHBCLKCTRL1, 15 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) { CLKID_AHB_MAC1, "mac1", "ahb_div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) HW_AHBCLKCTRL1, 16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) static const char __initdata *main_mux_p[] = { NULL, NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) static const char __initdata *i2s0_mux_p[] = { NULL, NULL, "i2s0m_div"};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) static const char __initdata *i2s1_mux_p[] = { NULL, NULL, "i2s1m_div"};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) static const char __initdata *clkout_mux_p[] = { NULL, NULL, "rtc"};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) static u32 three_mux_table[] = {0, 1, 3};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) static struct asm9260_mux_clock asm9260_mux_clks[] __initdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) { 1, three_mux_table, "main_mux", main_mux_p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) ARRAY_SIZE(main_mux_p), HW_MAINCLKSEL, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) { 1, three_mux_table, "uart_mux", main_mux_p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) ARRAY_SIZE(main_mux_p), HW_UARTCLKSEL, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) { 1, three_mux_table, "wdt_mux", main_mux_p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) ARRAY_SIZE(main_mux_p), HW_WDTCLKSEL, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) { 3, three_mux_table, "i2s0_mux", i2s0_mux_p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) ARRAY_SIZE(i2s0_mux_p), HW_I2S0CLKSEL, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) { 3, three_mux_table, "i2s1_mux", i2s1_mux_p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) ARRAY_SIZE(i2s1_mux_p), HW_I2S1CLKSEL, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) { 3, three_mux_table, "clkout_mux", clkout_mux_p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) ARRAY_SIZE(clkout_mux_p), HW_CLKOUTCLKSEL, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) static void __init asm9260_acc_init(struct device_node *np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) struct clk_hw *hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) struct clk_hw **hws;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) const char *ref_clk, *pll_clk = "pll";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) u32 rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) int n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) clk_data = kzalloc(struct_size(clk_data, hws, MAX_CLKS), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (!clk_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) clk_data->num = MAX_CLKS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) hws = clk_data->hws;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) base = of_io_request_and_map(np, 0, np->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) if (IS_ERR(base))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) panic("%pOFn: unable to map resource", np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) /* register pll */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) rate = (ioread32(base + HW_SYSPLLCTRL) & 0xffff) * 1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) /* TODO: Convert to DT parent scheme */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) ref_clk = of_clk_get_parent_name(np, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) hw = __clk_hw_register_fixed_rate(NULL, NULL, pll_clk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) ref_clk, NULL, NULL, 0, rate, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) CLK_FIXED_RATE_PARENT_ACCURACY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) if (IS_ERR(hw))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) panic("%pOFn: can't register REFCLK. Check DT!", np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) for (n = 0; n < ARRAY_SIZE(asm9260_mux_clks); n++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) const struct asm9260_mux_clock *mc = &asm9260_mux_clks[n];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) mc->parent_names[0] = ref_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) mc->parent_names[1] = pll_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) hw = clk_hw_register_mux_table(NULL, mc->name, mc->parent_names,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) mc->num_parents, mc->flags, base + mc->offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 0, mc->mask, 0, mc->table, &asm9260_clk_lock);
^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) /* clock mux gate cells */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) for (n = 0; n < ARRAY_SIZE(asm9260_mux_gates); n++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) const struct asm9260_gate_data *gd = &asm9260_mux_gates[n];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) hw = clk_hw_register_gate(NULL, gd->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) gd->parent_name, gd->flags | CLK_SET_RATE_PARENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) base + gd->reg, gd->bit_idx, 0, &asm9260_clk_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) /* clock div cells */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) for (n = 0; n < ARRAY_SIZE(asm9260_div_clks); n++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) const struct asm9260_div_clk *dc = &asm9260_div_clks[n];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) hws[dc->idx] = clk_hw_register_divider(NULL, dc->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) dc->parent_name, CLK_SET_RATE_PARENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) base + dc->reg, 0, 8, CLK_DIVIDER_ONE_BASED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) &asm9260_clk_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) /* clock ahb gate cells */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) for (n = 0; n < ARRAY_SIZE(asm9260_ahb_gates); n++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) const struct asm9260_gate_data *gd = &asm9260_ahb_gates[n];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) hws[gd->idx] = clk_hw_register_gate(NULL, gd->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) gd->parent_name, gd->flags, base + gd->reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) gd->bit_idx, 0, &asm9260_clk_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) /* check for errors on leaf clocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) for (n = 0; n < MAX_CLKS; n++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) if (!IS_ERR(hws[n]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) pr_err("%pOF: Unable to register leaf clock %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) np, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) /* register clk-provider */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) iounmap(base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) CLK_OF_DECLARE(asm9260_acc, "alphascale,asm9260-clock-controller",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) asm9260_acc_init);