17bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song/*
27bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song * Clock tree for CSR SiRFatlasVI
37bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song *
47736692993308dfedc1aabbeb8b401fc00098de5Barry Song * Copyright (c) 2011 - 2014 Cambridge Silicon Radio Limited, a CSR plc group
57736692993308dfedc1aabbeb8b401fc00098de5Barry Song * company.
67bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song *
77bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song * Licensed under GPLv2 or later.
87bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song */
97bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song
107bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song#include <linux/module.h>
117bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song#include <linux/bitops.h>
127bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song#include <linux/io.h>
137bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song#include <linux/clk.h>
147bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song#include <linux/clkdev.h>
157bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song#include <linux/clk-provider.h>
167bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song#include <linux/of_address.h>
177bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song#include <linux/syscore_ops.h>
187bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song
197bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song#include "atlas6.h"
207bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song#include "clk-common.c"
217bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song
227bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Songstatic struct clk_dmn clk_mmc01 = {
237bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	.regofs = SIRFSOC_CLKC_MMC01_CFG,
247bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	.enable_bit = 59,
257bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	.hw = {
267bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song		.init = &clk_mmc01_init,
277bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	},
287bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song};
297bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song
307bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Songstatic struct clk_dmn clk_mmc23 = {
317bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	.regofs = SIRFSOC_CLKC_MMC23_CFG,
327bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	.enable_bit = 60,
337bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	.hw = {
347bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song		.init = &clk_mmc23_init,
357bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	},
367bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song};
377bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song
387bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Songstatic struct clk_dmn clk_mmc45 = {
397bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	.regofs = SIRFSOC_CLKC_MMC45_CFG,
407bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	.enable_bit = 61,
417bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	.hw = {
427bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song		.init = &clk_mmc45_init,
437bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	},
447bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song};
457bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song
467bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Songstatic struct clk_init_data clk_nand_init = {
477bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	.name = "nand",
487bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	.ops = &dmn_ops,
497bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	.parent_names = dmn_clk_parents,
507bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	.num_parents = ARRAY_SIZE(dmn_clk_parents),
517bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song};
527bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song
537bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Songstatic struct clk_dmn clk_nand = {
547bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	.regofs = SIRFSOC_CLKC_NAND_CFG,
557bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	.enable_bit = 34,
567bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	.hw = {
577bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song		.init = &clk_nand_init,
587bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	},
597bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song};
607bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song
617bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Songenum atlas6_clk_index {
627bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	/* 0    1     2      3      4      5      6       7         8      9 */
637bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	rtc,    osc,   pll1,  pll2,  pll3,  mem,   sys,   security, dsp,   gps,
647bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	mf,     io,    cpu,   uart0, uart1, uart2, tsc,   i2c0,     i2c1,  spi0,
657bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	spi1,   pwmc,  efuse, pulse, dmac0, dmac1, nand,  audio,    usp0,  usp1,
667bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	usp2,   vip,   gfx,   gfx2d,    lcd,   vpp,   mmc01, mmc23,    mmc45, usbpll,
677bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	usb0,  usb1,   cphif, maxclk,
687bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song};
697bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song
707bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Songstatic __initdata struct clk_hw *atlas6_clk_hw_array[maxclk] = {
717bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	NULL, /* dummy */
727bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	NULL,
737bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	&clk_pll1.hw,
747bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	&clk_pll2.hw,
757bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	&clk_pll3.hw,
767bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	&clk_mem.hw,
777bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	&clk_sys.hw,
787bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	&clk_security.hw,
797bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	&clk_dsp.hw,
807bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	&clk_gps.hw,
817bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	&clk_mf.hw,
827bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	&clk_io.hw,
837bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	&clk_cpu.hw,
847bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	&clk_uart0.hw,
857bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	&clk_uart1.hw,
867bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	&clk_uart2.hw,
877bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	&clk_tsc.hw,
887bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	&clk_i2c0.hw,
897bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	&clk_i2c1.hw,
907bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	&clk_spi0.hw,
917bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	&clk_spi1.hw,
927bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	&clk_pwmc.hw,
937bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	&clk_efuse.hw,
947bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	&clk_pulse.hw,
957bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	&clk_dmac0.hw,
967bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	&clk_dmac1.hw,
977bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	&clk_nand.hw,
987bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	&clk_audio.hw,
997bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	&clk_usp0.hw,
1007bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	&clk_usp1.hw,
1017bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	&clk_usp2.hw,
1027bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	&clk_vip.hw,
1037bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	&clk_gfx.hw,
1047bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	&clk_gfx2d.hw,
1057bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	&clk_lcd.hw,
1067bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	&clk_vpp.hw,
1077bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	&clk_mmc01.hw,
1087bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	&clk_mmc23.hw,
1097bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	&clk_mmc45.hw,
1107bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	&usb_pll_clk_hw,
1117bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	&clk_usb0.hw,
1127bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	&clk_usb1.hw,
1137bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	&clk_cphif.hw,
1147bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song};
1157bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song
1167bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Songstatic struct clk *atlas6_clks[maxclk];
1177bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song
1187bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Songstatic void __init atlas6_clk_init(struct device_node *np)
1197bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song{
1207bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	struct device_node *rscnp;
1217bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	int i;
1227bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song
1237bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	rscnp = of_find_compatible_node(NULL, NULL, "sirf,prima2-rsc");
1247bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	sirfsoc_rsc_vbase = of_iomap(rscnp, 0);
1257bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	if (!sirfsoc_rsc_vbase)
1267bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song		panic("unable to map rsc registers\n");
1277bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	of_node_put(rscnp);
1287bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song
1297bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	sirfsoc_clk_vbase = of_iomap(np, 0);
1307bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	if (!sirfsoc_clk_vbase)
1317bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song		panic("unable to map clkc registers\n");
1327bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song
1337bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	/* These are always available (RTC and 26MHz OSC)*/
1347bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	atlas6_clks[rtc] = clk_register_fixed_rate(NULL, "rtc", NULL,
1357bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song		CLK_IS_ROOT, 32768);
1367bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	atlas6_clks[osc] = clk_register_fixed_rate(NULL, "osc", NULL,
1377bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song		CLK_IS_ROOT, 26000000);
1387bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song
1397bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	for (i = pll1; i < maxclk; i++) {
1407bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song		atlas6_clks[i] = clk_register(NULL, atlas6_clk_hw_array[i]);
1417bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song		BUG_ON(!atlas6_clks[i]);
1427bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	}
1437bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	clk_register_clkdev(atlas6_clks[cpu], NULL, "cpu");
1447bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	clk_register_clkdev(atlas6_clks[io],  NULL, "io");
1457bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	clk_register_clkdev(atlas6_clks[mem],  NULL, "mem");
1467bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	clk_register_clkdev(atlas6_clks[mem],  NULL, "osc");
1477bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song
1487bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	clk_data.clks = atlas6_clks;
1497bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	clk_data.clk_num = maxclk;
1507bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song
1517bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song	of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
1527bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry Song}
1537bf21bc81f28cefa61250cfd9de2c884bbe1f3dbBarry SongCLK_OF_DECLARE(atlas6_clk, "sirf,atlas6-clkc", atlas6_clk_init);
154