1/* 2 * Copyright (C) 2013 Pengutronix 3 * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> 4 * 5 * This program is free software; you can redistribute it and/or modify it under 6 * the terms of the GNU General Public License version 2 as published by the 7 * Free Software Foundation. 8 */ 9#include <linux/clk.h> 10#include <linux/io.h> 11#include <linux/clk-provider.h> 12#include <linux/of.h> 13#include <linux/of_address.h> 14 15#include <dt-bindings/clock/efm32-cmu.h> 16 17#define CMU_HFPERCLKEN0 0x44 18 19static struct clk *clk[37]; 20static struct clk_onecell_data clk_data = { 21 .clks = clk, 22 .clk_num = ARRAY_SIZE(clk), 23}; 24 25static void __init efm32gg_cmu_init(struct device_node *np) 26{ 27 int i; 28 void __iomem *base; 29 30 for (i = 0; i < ARRAY_SIZE(clk); ++i) 31 clk[i] = ERR_PTR(-ENOENT); 32 33 base = of_iomap(np, 0); 34 if (!base) { 35 pr_warn("Failed to map address range for efm32gg,cmu node\n"); 36 return; 37 } 38 39 clk[clk_HFXO] = clk_register_fixed_rate(NULL, "HFXO", NULL, 40 CLK_IS_ROOT, 48000000); 41 42 clk[clk_HFPERCLKUSART0] = clk_register_gate(NULL, "HFPERCLK.USART0", 43 "HFXO", 0, base + CMU_HFPERCLKEN0, 0, 0, NULL); 44 clk[clk_HFPERCLKUSART1] = clk_register_gate(NULL, "HFPERCLK.USART1", 45 "HFXO", 0, base + CMU_HFPERCLKEN0, 1, 0, NULL); 46 clk[clk_HFPERCLKUSART2] = clk_register_gate(NULL, "HFPERCLK.USART2", 47 "HFXO", 0, base + CMU_HFPERCLKEN0, 2, 0, NULL); 48 clk[clk_HFPERCLKUART0] = clk_register_gate(NULL, "HFPERCLK.UART0", 49 "HFXO", 0, base + CMU_HFPERCLKEN0, 3, 0, NULL); 50 clk[clk_HFPERCLKUART1] = clk_register_gate(NULL, "HFPERCLK.UART1", 51 "HFXO", 0, base + CMU_HFPERCLKEN0, 4, 0, NULL); 52 clk[clk_HFPERCLKTIMER0] = clk_register_gate(NULL, "HFPERCLK.TIMER0", 53 "HFXO", 0, base + CMU_HFPERCLKEN0, 5, 0, NULL); 54 clk[clk_HFPERCLKTIMER1] = clk_register_gate(NULL, "HFPERCLK.TIMER1", 55 "HFXO", 0, base + CMU_HFPERCLKEN0, 6, 0, NULL); 56 clk[clk_HFPERCLKTIMER2] = clk_register_gate(NULL, "HFPERCLK.TIMER2", 57 "HFXO", 0, base + CMU_HFPERCLKEN0, 7, 0, NULL); 58 clk[clk_HFPERCLKTIMER3] = clk_register_gate(NULL, "HFPERCLK.TIMER3", 59 "HFXO", 0, base + CMU_HFPERCLKEN0, 8, 0, NULL); 60 clk[clk_HFPERCLKACMP0] = clk_register_gate(NULL, "HFPERCLK.ACMP0", 61 "HFXO", 0, base + CMU_HFPERCLKEN0, 9, 0, NULL); 62 clk[clk_HFPERCLKACMP1] = clk_register_gate(NULL, "HFPERCLK.ACMP1", 63 "HFXO", 0, base + CMU_HFPERCLKEN0, 10, 0, NULL); 64 clk[clk_HFPERCLKI2C0] = clk_register_gate(NULL, "HFPERCLK.I2C0", 65 "HFXO", 0, base + CMU_HFPERCLKEN0, 11, 0, NULL); 66 clk[clk_HFPERCLKI2C1] = clk_register_gate(NULL, "HFPERCLK.I2C1", 67 "HFXO", 0, base + CMU_HFPERCLKEN0, 12, 0, NULL); 68 clk[clk_HFPERCLKGPIO] = clk_register_gate(NULL, "HFPERCLK.GPIO", 69 "HFXO", 0, base + CMU_HFPERCLKEN0, 13, 0, NULL); 70 clk[clk_HFPERCLKVCMP] = clk_register_gate(NULL, "HFPERCLK.VCMP", 71 "HFXO", 0, base + CMU_HFPERCLKEN0, 14, 0, NULL); 72 clk[clk_HFPERCLKPRS] = clk_register_gate(NULL, "HFPERCLK.PRS", 73 "HFXO", 0, base + CMU_HFPERCLKEN0, 15, 0, NULL); 74 clk[clk_HFPERCLKADC0] = clk_register_gate(NULL, "HFPERCLK.ADC0", 75 "HFXO", 0, base + CMU_HFPERCLKEN0, 16, 0, NULL); 76 clk[clk_HFPERCLKDAC0] = clk_register_gate(NULL, "HFPERCLK.DAC0", 77 "HFXO", 0, base + CMU_HFPERCLKEN0, 17, 0, NULL); 78 79 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); 80} 81CLK_OF_DECLARE(efm32ggcmu, "efm32gg,cmu", efm32gg_cmu_init); 82