1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (C) 2013 Pengutronix 4 * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> 5 */ 6#include <linux/io.h> 7#include <linux/clk-provider.h> 8#include <linux/of.h> 9#include <linux/of_address.h> 10#include <linux/slab.h> 11 12#include <dt-bindings/clock/efm32-cmu.h> 13 14#define CMU_HFPERCLKEN0 0x44 15#define CMU_MAX_CLKS 37 16 17static struct clk_hw_onecell_data *clk_data; 18 19static void __init efm32gg_cmu_init(struct device_node *np) 20{ 21 int i; 22 void __iomem *base; 23 struct clk_hw **hws; 24 25 clk_data = kzalloc(struct_size(clk_data, hws, CMU_MAX_CLKS), 26 GFP_KERNEL); 27 28 if (!clk_data) 29 return; 30 31 hws = clk_data->hws; 32 33 for (i = 0; i < CMU_MAX_CLKS; ++i) 34 hws[i] = ERR_PTR(-ENOENT); 35 36 base = of_iomap(np, 0); 37 if (!base) { 38 pr_warn("Failed to map address range for efm32gg,cmu node\n"); 39 return; 40 } 41 42 hws[clk_HFXO] = clk_hw_register_fixed_rate(NULL, "HFXO", NULL, 0, 43 48000000); 44 45 hws[clk_HFPERCLKUSART0] = clk_hw_register_gate(NULL, "HFPERCLK.USART0", 46 "HFXO", 0, base + CMU_HFPERCLKEN0, 0, 0, NULL); 47 hws[clk_HFPERCLKUSART1] = clk_hw_register_gate(NULL, "HFPERCLK.USART1", 48 "HFXO", 0, base + CMU_HFPERCLKEN0, 1, 0, NULL); 49 hws[clk_HFPERCLKUSART2] = clk_hw_register_gate(NULL, "HFPERCLK.USART2", 50 "HFXO", 0, base + CMU_HFPERCLKEN0, 2, 0, NULL); 51 hws[clk_HFPERCLKUART0] = clk_hw_register_gate(NULL, "HFPERCLK.UART0", 52 "HFXO", 0, base + CMU_HFPERCLKEN0, 3, 0, NULL); 53 hws[clk_HFPERCLKUART1] = clk_hw_register_gate(NULL, "HFPERCLK.UART1", 54 "HFXO", 0, base + CMU_HFPERCLKEN0, 4, 0, NULL); 55 hws[clk_HFPERCLKTIMER0] = clk_hw_register_gate(NULL, "HFPERCLK.TIMER0", 56 "HFXO", 0, base + CMU_HFPERCLKEN0, 5, 0, NULL); 57 hws[clk_HFPERCLKTIMER1] = clk_hw_register_gate(NULL, "HFPERCLK.TIMER1", 58 "HFXO", 0, base + CMU_HFPERCLKEN0, 6, 0, NULL); 59 hws[clk_HFPERCLKTIMER2] = clk_hw_register_gate(NULL, "HFPERCLK.TIMER2", 60 "HFXO", 0, base + CMU_HFPERCLKEN0, 7, 0, NULL); 61 hws[clk_HFPERCLKTIMER3] = clk_hw_register_gate(NULL, "HFPERCLK.TIMER3", 62 "HFXO", 0, base + CMU_HFPERCLKEN0, 8, 0, NULL); 63 hws[clk_HFPERCLKACMP0] = clk_hw_register_gate(NULL, "HFPERCLK.ACMP0", 64 "HFXO", 0, base + CMU_HFPERCLKEN0, 9, 0, NULL); 65 hws[clk_HFPERCLKACMP1] = clk_hw_register_gate(NULL, "HFPERCLK.ACMP1", 66 "HFXO", 0, base + CMU_HFPERCLKEN0, 10, 0, NULL); 67 hws[clk_HFPERCLKI2C0] = clk_hw_register_gate(NULL, "HFPERCLK.I2C0", 68 "HFXO", 0, base + CMU_HFPERCLKEN0, 11, 0, NULL); 69 hws[clk_HFPERCLKI2C1] = clk_hw_register_gate(NULL, "HFPERCLK.I2C1", 70 "HFXO", 0, base + CMU_HFPERCLKEN0, 12, 0, NULL); 71 hws[clk_HFPERCLKGPIO] = clk_hw_register_gate(NULL, "HFPERCLK.GPIO", 72 "HFXO", 0, base + CMU_HFPERCLKEN0, 13, 0, NULL); 73 hws[clk_HFPERCLKVCMP] = clk_hw_register_gate(NULL, "HFPERCLK.VCMP", 74 "HFXO", 0, base + CMU_HFPERCLKEN0, 14, 0, NULL); 75 hws[clk_HFPERCLKPRS] = clk_hw_register_gate(NULL, "HFPERCLK.PRS", 76 "HFXO", 0, base + CMU_HFPERCLKEN0, 15, 0, NULL); 77 hws[clk_HFPERCLKADC0] = clk_hw_register_gate(NULL, "HFPERCLK.ADC0", 78 "HFXO", 0, base + CMU_HFPERCLKEN0, 16, 0, NULL); 79 hws[clk_HFPERCLKDAC0] = clk_hw_register_gate(NULL, "HFPERCLK.DAC0", 80 "HFXO", 0, base + CMU_HFPERCLKEN0, 17, 0, NULL); 81 82 of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data); 83} 84CLK_OF_DECLARE(efm32ggcmu, "efm32gg,cmu", efm32gg_cmu_init); 85