^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) 2015 Altera Corporation. All rights reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/clk-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include "clk.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #define CLK_MGR_FREE_SHIFT 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #define CLK_MGR_FREE_MASK 0x7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #define SOCFPGA_MPU_FREE_CLK "mpu_free_clk"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define SOCFPGA_NOC_FREE_CLK "noc_free_clk"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define SOCFPGA_SDMMC_FREE_CLK "sdmmc_free_clk"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define to_socfpga_periph_clk(p) container_of(p, struct socfpga_periph_clk, hw.hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) static unsigned long clk_periclk_recalc_rate(struct clk_hw *hwclk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) struct socfpga_periph_clk *socfpgaclk = to_socfpga_periph_clk(hwclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) u32 div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) if (socfpgaclk->fixed_div) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) div = socfpgaclk->fixed_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) } else if (socfpgaclk->div_reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) div = readl(socfpgaclk->div_reg) >> socfpgaclk->shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) div &= GENMASK(socfpgaclk->width - 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) div += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) div = ((readl(socfpgaclk->hw.reg) & 0x7ff) + 1);
^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) return parent_rate / div;
^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) static u8 clk_periclk_get_parent(struct clk_hw *hwclk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) struct socfpga_periph_clk *socfpgaclk = to_socfpga_periph_clk(hwclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) u32 clk_src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) const char *name = clk_hw_get_name(hwclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) clk_src = readl(socfpgaclk->hw.reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) if (streq(name, SOCFPGA_MPU_FREE_CLK) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) streq(name, SOCFPGA_NOC_FREE_CLK) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) streq(name, SOCFPGA_SDMMC_FREE_CLK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) return (clk_src >> CLK_MGR_FREE_SHIFT) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) CLK_MGR_FREE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) static const struct clk_ops periclk_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) .recalc_rate = clk_periclk_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) .get_parent = clk_periclk_get_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) static __init void __socfpga_periph_init(struct device_node *node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) const struct clk_ops *ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct socfpga_periph_clk *periph_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) const char *clk_name = node->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) const char *parent_name[SOCFPGA_MAX_PARENTS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) struct clk_init_data init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) u32 fixed_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) u32 div_reg[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) of_property_read_u32(node, "reg", ®);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) periph_clk = kzalloc(sizeof(*periph_clk), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) if (WARN_ON(!periph_clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) periph_clk->hw.reg = clk_mgr_a10_base_addr + reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) rc = of_property_read_u32_array(node, "div-reg", div_reg, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) if (!rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) periph_clk->div_reg = clk_mgr_a10_base_addr + div_reg[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) periph_clk->shift = div_reg[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) periph_clk->width = div_reg[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) periph_clk->div_reg = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) rc = of_property_read_u32(node, "fixed-divider", &fixed_div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) periph_clk->fixed_div = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) periph_clk->fixed_div = fixed_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) of_property_read_string(node, "clock-output-names", &clk_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) init.name = clk_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) init.ops = ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) init.flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) init.num_parents = of_clk_parent_fill(node, parent_name, SOCFPGA_MAX_PARENTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) init.parent_names = parent_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) periph_clk->hw.hw.init = &init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) clk = clk_register(NULL, &periph_clk->hw.hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (WARN_ON(IS_ERR(clk))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) kfree(periph_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) rc = of_clk_add_provider(node, of_clk_src_simple_get, clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) pr_err("Could not register clock provider for node:%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) clk_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) goto err_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) err_clk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) clk_unregister(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) void __init socfpga_a10_periph_init(struct device_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) __socfpga_periph_init(node, &periclk_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }