Skip to content

Commit

Permalink
clk: sirf: re-arch to make the codes support both prima2 and atlas6
Browse files Browse the repository at this point in the history
sirfprima2 and sirfatlas6 are two different SoCs in CSR SiRF series. for
prima2 and atlas6, there are many shared clocks but there are still
some different register layout and hardware clocks, then result in
different clock table.

here we re-arch the driver to
1. clk-common.c provides common clocks for prima2 and atlas6,
2. clk-prima2.h describles registers of prima2 and clk-prima2.c provides
prima2 specific clocks and clock table.
3. clk-atlas6.h describles registers of atlas6 and clk-atlas6.c provides
atlas6 specific clocks and clock table.
4. clk.h and clk.c expose external interfaces and provide uniform entry
for both prima2 and atlas6.

so both prima2 and atlas6 will get support by drivers/clk/sirf.

Signed-off-by: Barry Song <Baohua.Song@csr.com>
Signed-off-by: Rongjun Ying <Rongjun.Ying@csr.com>
Signed-off-by: Mike Turquette <mturquette@linaro.org>
  • Loading branch information
Barry Song authored and Mike Turquette committed Jan 16, 2014
1 parent 5d2043f commit 7bf21bc
Show file tree
Hide file tree
Showing 7 changed files with 458 additions and 172 deletions.
2 changes: 1 addition & 1 deletion drivers/clk/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ obj-$(CONFIG_ARCH_SOCFPGA) += socfpga/
obj-$(CONFIG_PLAT_SPEAR) += spear/
obj-$(CONFIG_ARCH_U300) += clk-u300.o
obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/
obj-$(CONFIG_ARCH_SIRF) += clk-prima2.o
obj-$(CONFIG_PLAT_ORION) += mvebu/
ifeq ($(CONFIG_COMMON_CLK), y)
obj-$(CONFIG_ARCH_MMP) += mmp/
Expand All @@ -31,6 +30,7 @@ obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
obj-$(CONFIG_ARCH_SUNXI) += sunxi/
obj-$(CONFIG_ARCH_U8500) += ux500/
obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o
obj-$(CONFIG_ARCH_SIRF) += sirf/
obj-$(CONFIG_ARCH_ZYNQ) += zynq/
obj-$(CONFIG_ARCH_TEGRA) += tegra/
obj-$(CONFIG_PLAT_SAMSUNG) += samsung/
Expand Down
5 changes: 5 additions & 0 deletions drivers/clk/sirf/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#
# Makefile for sirf specific clk
#

obj-$(CONFIG_ARCH_SIRF) += clk-prima2.o clk-atlas6.o
31 changes: 31 additions & 0 deletions drivers/clk/sirf/atlas6.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#define SIRFSOC_CLKC_CLK_EN0 0x0000
#define SIRFSOC_CLKC_CLK_EN1 0x0004
#define SIRFSOC_CLKC_REF_CFG 0x0020
#define SIRFSOC_CLKC_CPU_CFG 0x0024
#define SIRFSOC_CLKC_MEM_CFG 0x0028
#define SIRFSOC_CLKC_MEMDIV_CFG 0x002C
#define SIRFSOC_CLKC_SYS_CFG 0x0030
#define SIRFSOC_CLKC_IO_CFG 0x0034
#define SIRFSOC_CLKC_DSP_CFG 0x0038
#define SIRFSOC_CLKC_GFX_CFG 0x003c
#define SIRFSOC_CLKC_MM_CFG 0x0040
#define SIRFSOC_CLKC_GFX2D_CFG 0x0040
#define SIRFSOC_CLKC_LCD_CFG 0x0044
#define SIRFSOC_CLKC_MMC01_CFG 0x0048
#define SIRFSOC_CLKC_MMC23_CFG 0x004C
#define SIRFSOC_CLKC_MMC45_CFG 0x0050
#define SIRFSOC_CLKC_NAND_CFG 0x0054
#define SIRFSOC_CLKC_NANDDIV_CFG 0x0058
#define SIRFSOC_CLKC_PLL1_CFG0 0x0080
#define SIRFSOC_CLKC_PLL2_CFG0 0x0084
#define SIRFSOC_CLKC_PLL3_CFG0 0x0088
#define SIRFSOC_CLKC_PLL1_CFG1 0x008c
#define SIRFSOC_CLKC_PLL2_CFG1 0x0090
#define SIRFSOC_CLKC_PLL3_CFG1 0x0094
#define SIRFSOC_CLKC_PLL1_CFG2 0x0098
#define SIRFSOC_CLKC_PLL2_CFG2 0x009c
#define SIRFSOC_CLKC_PLL3_CFG2 0x00A0
#define SIRFSOC_USBPHY_PLL_CTRL 0x0008
#define SIRFSOC_USBPHY_PLL_POWERDOWN BIT(1)
#define SIRFSOC_USBPHY_PLL_BYPASS BIT(2)
#define SIRFSOC_USBPHY_PLL_LOCK BIT(3)
152 changes: 152 additions & 0 deletions drivers/clk/sirf/clk-atlas6.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
/*
* Clock tree for CSR SiRFatlasVI
*
* Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
*
* Licensed under GPLv2 or later.
*/

#include <linux/module.h>
#include <linux/bitops.h>
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/clkdev.h>
#include <linux/clk-provider.h>
#include <linux/of_address.h>
#include <linux/syscore_ops.h>

#include "atlas6.h"
#include "clk-common.c"

static struct clk_dmn clk_mmc01 = {
.regofs = SIRFSOC_CLKC_MMC01_CFG,
.enable_bit = 59,
.hw = {
.init = &clk_mmc01_init,
},
};

static struct clk_dmn clk_mmc23 = {
.regofs = SIRFSOC_CLKC_MMC23_CFG,
.enable_bit = 60,
.hw = {
.init = &clk_mmc23_init,
},
};

static struct clk_dmn clk_mmc45 = {
.regofs = SIRFSOC_CLKC_MMC45_CFG,
.enable_bit = 61,
.hw = {
.init = &clk_mmc45_init,
},
};

static struct clk_init_data clk_nand_init = {
.name = "nand",
.ops = &dmn_ops,
.parent_names = dmn_clk_parents,
.num_parents = ARRAY_SIZE(dmn_clk_parents),
};

static struct clk_dmn clk_nand = {
.regofs = SIRFSOC_CLKC_NAND_CFG,
.enable_bit = 34,
.hw = {
.init = &clk_nand_init,
},
};

enum atlas6_clk_index {
/* 0 1 2 3 4 5 6 7 8 9 */
rtc, osc, pll1, pll2, pll3, mem, sys, security, dsp, gps,
mf, io, cpu, uart0, uart1, uart2, tsc, i2c0, i2c1, spi0,
spi1, pwmc, efuse, pulse, dmac0, dmac1, nand, audio, usp0, usp1,
usp2, vip, gfx, gfx2d, lcd, vpp, mmc01, mmc23, mmc45, usbpll,
usb0, usb1, cphif, maxclk,
};

static __initdata struct clk_hw *atlas6_clk_hw_array[maxclk] = {
NULL, /* dummy */
NULL,
&clk_pll1.hw,
&clk_pll2.hw,
&clk_pll3.hw,
&clk_mem.hw,
&clk_sys.hw,
&clk_security.hw,
&clk_dsp.hw,
&clk_gps.hw,
&clk_mf.hw,
&clk_io.hw,
&clk_cpu.hw,
&clk_uart0.hw,
&clk_uart1.hw,
&clk_uart2.hw,
&clk_tsc.hw,
&clk_i2c0.hw,
&clk_i2c1.hw,
&clk_spi0.hw,
&clk_spi1.hw,
&clk_pwmc.hw,
&clk_efuse.hw,
&clk_pulse.hw,
&clk_dmac0.hw,
&clk_dmac1.hw,
&clk_nand.hw,
&clk_audio.hw,
&clk_usp0.hw,
&clk_usp1.hw,
&clk_usp2.hw,
&clk_vip.hw,
&clk_gfx.hw,
&clk_gfx2d.hw,
&clk_lcd.hw,
&clk_vpp.hw,
&clk_mmc01.hw,
&clk_mmc23.hw,
&clk_mmc45.hw,
&usb_pll_clk_hw,
&clk_usb0.hw,
&clk_usb1.hw,
&clk_cphif.hw,
};

static struct clk *atlas6_clks[maxclk];

static void __init atlas6_clk_init(struct device_node *np)
{
struct device_node *rscnp;
int i;

rscnp = of_find_compatible_node(NULL, NULL, "sirf,prima2-rsc");
sirfsoc_rsc_vbase = of_iomap(rscnp, 0);
if (!sirfsoc_rsc_vbase)
panic("unable to map rsc registers\n");
of_node_put(rscnp);

sirfsoc_clk_vbase = of_iomap(np, 0);
if (!sirfsoc_clk_vbase)
panic("unable to map clkc registers\n");

/* These are always available (RTC and 26MHz OSC)*/
atlas6_clks[rtc] = clk_register_fixed_rate(NULL, "rtc", NULL,
CLK_IS_ROOT, 32768);
atlas6_clks[osc] = clk_register_fixed_rate(NULL, "osc", NULL,
CLK_IS_ROOT, 26000000);

for (i = pll1; i < maxclk; i++) {
atlas6_clks[i] = clk_register(NULL, atlas6_clk_hw_array[i]);
BUG_ON(!atlas6_clks[i]);
}
clk_register_clkdev(atlas6_clks[cpu], NULL, "cpu");
clk_register_clkdev(atlas6_clks[io], NULL, "io");
clk_register_clkdev(atlas6_clks[mem], NULL, "mem");
clk_register_clkdev(atlas6_clks[mem], NULL, "osc");

clk_data.clks = atlas6_clks;
clk_data.clk_num = maxclk;

of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
}
CLK_OF_DECLARE(atlas6_clk, "sirf,atlas6-clkc", atlas6_clk_init);
Loading

0 comments on commit 7bf21bc

Please sign in to comment.