^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) * Clock tree for CSR SiRFprimaII
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2011 - 2014 Cambridge Silicon Radio Limited, a CSR plc group
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * company.
^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) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/clkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/clk-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/syscore_ops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "prima2.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "clk-common.c"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) static struct clk_dmn clk_mmc01 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) .regofs = SIRFSOC_CLKC_MMC_CFG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) .enable_bit = 59,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) .hw = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) .init = &clk_mmc01_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) static struct clk_dmn clk_mmc23 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) .regofs = SIRFSOC_CLKC_MMC_CFG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) .enable_bit = 60,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) .hw = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) .init = &clk_mmc23_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static struct clk_dmn clk_mmc45 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) .regofs = SIRFSOC_CLKC_MMC_CFG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) .enable_bit = 61,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) .hw = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) .init = &clk_mmc45_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static const struct clk_init_data clk_nand_init = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) .name = "nand",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) .ops = &ios_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) .parent_names = std_clk_io_parents,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) .num_parents = ARRAY_SIZE(std_clk_io_parents),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) static struct clk_std clk_nand = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) .enable_bit = 34,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) .hw = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) .init = &clk_nand_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) enum prima2_clk_index {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /* 0 1 2 3 4 5 6 7 8 9 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) rtc, osc, pll1, pll2, pll3, mem, sys, security, dsp, gps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) mf, io, cpu, uart0, uart1, uart2, tsc, i2c0, i2c1, spi0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) spi1, pwmc, efuse, pulse, dmac0, dmac1, nand, audio, usp0, usp1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) usp2, vip, gfx, mm, lcd, vpp, mmc01, mmc23, mmc45, usbpll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) usb0, usb1, cphif, maxclk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) static __initdata struct clk_hw *prima2_clk_hw_array[maxclk] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) NULL, /* dummy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) &clk_pll1.hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) &clk_pll2.hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) &clk_pll3.hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) &clk_mem.hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) &clk_sys.hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) &clk_security.hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) &clk_dsp.hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) &clk_gps.hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) &clk_mf.hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) &clk_io.hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) &clk_cpu.hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) &clk_uart0.hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) &clk_uart1.hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) &clk_uart2.hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) &clk_tsc.hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) &clk_i2c0.hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) &clk_i2c1.hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) &clk_spi0.hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) &clk_spi1.hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) &clk_pwmc.hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) &clk_efuse.hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) &clk_pulse.hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) &clk_dmac0.hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) &clk_dmac1.hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) &clk_nand.hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) &clk_audio.hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) &clk_usp0.hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) &clk_usp1.hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) &clk_usp2.hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) &clk_vip.hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) &clk_gfx.hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) &clk_mm.hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) &clk_lcd.hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) &clk_vpp.hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) &clk_mmc01.hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) &clk_mmc23.hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) &clk_mmc45.hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) &usb_pll_clk_hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) &clk_usb0.hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) &clk_usb1.hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) &clk_cphif.hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) static struct clk *prima2_clks[maxclk];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static void __init prima2_clk_init(struct device_node *np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct device_node *rscnp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) rscnp = of_find_compatible_node(NULL, NULL, "sirf,prima2-rsc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) sirfsoc_rsc_vbase = of_iomap(rscnp, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) if (!sirfsoc_rsc_vbase)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) panic("unable to map rsc registers\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) of_node_put(rscnp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) sirfsoc_clk_vbase = of_iomap(np, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (!sirfsoc_clk_vbase)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) panic("unable to map clkc registers\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /* These are always available (RTC and 26MHz OSC)*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) prima2_clks[rtc] = clk_register_fixed_rate(NULL, "rtc", NULL, 0, 32768);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) prima2_clks[osc] = clk_register_fixed_rate(NULL, "osc", NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 26000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) for (i = pll1; i < maxclk; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) prima2_clks[i] = clk_register(NULL, prima2_clk_hw_array[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) BUG_ON(IS_ERR(prima2_clks[i]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) clk_register_clkdev(prima2_clks[cpu], NULL, "cpu");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) clk_register_clkdev(prima2_clks[io], NULL, "io");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) clk_register_clkdev(prima2_clks[mem], NULL, "mem");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) clk_register_clkdev(prima2_clks[mem], NULL, "osc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) clk_data.clks = prima2_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) clk_data.clk_num = maxclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) CLK_OF_DECLARE(prima2_clk, "sirf,prima2-clkc", prima2_clk_init);