^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 Google, Inc.
^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/clk-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "clk.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) struct pistachio_clk_provider *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) pistachio_clk_alloc_provider(struct device_node *node, unsigned int num_clks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) struct pistachio_clk_provider *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) p = kzalloc(sizeof(*p), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) return p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) p->clk_data.clks = kcalloc(num_clks, sizeof(struct clk *), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) if (!p->clk_data.clks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) goto free_provider;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) p->clk_data.clk_num = num_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) p->node = node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) p->base = of_iomap(node, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) if (!p->base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) pr_err("Failed to map clock provider registers\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) goto free_clks;
^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) return p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) free_clks:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) kfree(p->clk_data.clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) free_provider:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) kfree(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) return NULL;
^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) void pistachio_clk_register_provider(struct pistachio_clk_provider *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) for (i = 0; i < p->clk_data.clk_num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) if (IS_ERR(p->clk_data.clks[i]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) pr_warn("Failed to register clock %d: %ld\n", i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) PTR_ERR(p->clk_data.clks[i]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) of_clk_add_provider(p->node, of_clk_src_onecell_get, &p->clk_data);
^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) void pistachio_clk_register_gate(struct pistachio_clk_provider *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) struct pistachio_gate *gate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) unsigned int num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) for (i = 0; i < num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) clk = clk_register_gate(NULL, gate[i].name, gate[i].parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) CLK_SET_RATE_PARENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) p->base + gate[i].reg, gate[i].shift,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) p->clk_data.clks[gate[i].id] = clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) void pistachio_clk_register_mux(struct pistachio_clk_provider *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) struct pistachio_mux *mux,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) unsigned int num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) for (i = 0; i < num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) clk = clk_register_mux(NULL, mux[i].name, mux[i].parents,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) mux[i].num_parents,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) CLK_SET_RATE_NO_REPARENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) p->base + mux[i].reg, mux[i].shift,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) get_count_order(mux[i].num_parents),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) p->clk_data.clks[mux[i].id] = clk;
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) void pistachio_clk_register_div(struct pistachio_clk_provider *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct pistachio_div *div,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) unsigned int num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) for (i = 0; i < num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) clk = clk_register_divider(NULL, div[i].name, div[i].parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 0, p->base + div[i].reg, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) div[i].width, div[i].div_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) p->clk_data.clks[div[i].id] = clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) void pistachio_clk_register_fixed_factor(struct pistachio_clk_provider *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) struct pistachio_fixed_factor *ff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) unsigned int num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) for (i = 0; i < num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) clk = clk_register_fixed_factor(NULL, ff[i].name, ff[i].parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 0, 1, ff[i].div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) p->clk_data.clks[ff[i].id] = clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^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) void pistachio_clk_force_enable(struct pistachio_clk_provider *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) unsigned int *clk_ids, unsigned int num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) for (i = 0; i < num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) struct clk *clk = p->clk_data.clks[clk_ids[i]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) if (IS_ERR(clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) err = clk_prepare_enable(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) pr_err("Failed to enable clock %s: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) __clk_get_name(clk), err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }