Browse Source

[ARM] S3C24XX: Split DCLK/CLKOUT definitions out of clock.c

Only certain boards need these clocks, and they are not
available on some CPUs (such as the S3C24A0) so remove
them from arch/arm/plat-s3c24xx/clock.c and into their
own file with appropriate Kconfig entries.

Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Ben Dooks 16 years ago
parent
commit
93bc6b6371

+ 2 - 0
arch/arm/mach-s3c2410/Kconfig

@@ -80,6 +80,7 @@ config ARCH_BAST
 	select PM_SIMTEC if PM
 	select PM_SIMTEC if PM
 	select SIMTEC_NOR
 	select SIMTEC_NOR
 	select MACH_BAST_IDE
 	select MACH_BAST_IDE
+	select S3C24XX_DCLK
 	select ISA
 	select ISA
 	help
 	help
 	  Say Y here if you are using the Simtec Electronics EB2410ITX
 	  Say Y here if you are using the Simtec Electronics EB2410ITX
@@ -117,6 +118,7 @@ config MACH_TCT_HAMMER
 config MACH_VR1000
 config MACH_VR1000
 	bool "Thorcom VR1000"
 	bool "Thorcom VR1000"
 	select PM_SIMTEC if PM
 	select PM_SIMTEC if PM
+	select S3C24XX_DCLK
 	select SIMTEC_NOR
 	select SIMTEC_NOR
 	select MACH_BAST_IDE
 	select MACH_BAST_IDE
 	select CPU_S3C2410
 	select CPU_S3C2410

+ 2 - 0
arch/arm/mach-s3c2440/Kconfig

@@ -29,6 +29,7 @@ menu "S3C2440 Machines"
 config MACH_ANUBIS
 config MACH_ANUBIS
 	bool "Simtec Electronics ANUBIS"
 	bool "Simtec Electronics ANUBIS"
 	select CPU_S3C2440
 	select CPU_S3C2440
+	select S3C24XX_DCLK
 	select PM_SIMTEC if PM
 	select PM_SIMTEC if PM
 	select HAVE_PATA_PLATFORM
 	select HAVE_PATA_PLATFORM
 	help
 	help
@@ -38,6 +39,7 @@ config MACH_ANUBIS
 config MACH_OSIRIS
 config MACH_OSIRIS
 	bool "Simtec IM2440D20 (OSIRIS) module"
 	bool "Simtec IM2440D20 (OSIRIS) module"
 	select CPU_S3C2440
 	select CPU_S3C2440
+	select S3C24XX_DCLK
 	select PM_SIMTEC if PM
 	select PM_SIMTEC if PM
 	help
 	help
 	  Say Y here if you are using the Simtec IM2440D20 module, also
 	  Say Y here if you are using the Simtec IM2440D20 module, also

+ 5 - 0
arch/arm/plat-s3c24xx/Kconfig

@@ -23,6 +23,11 @@ config S3C2410_CLOCK
 	  Clock code for the S3C2410, and similar processors which
 	  Clock code for the S3C2410, and similar processors which
 	  is currently includes the S3C2410, S3C2440, S3C2442.
 	  is currently includes the S3C2410, S3C2440, S3C2442.
 
 
+config S3C24XX_DCLK
+	bool
+	help
+	  Clock code for supporting DCLK/CLKOUT on S3C24XX architectures
+
 config CPU_S3C244X
 config CPU_S3C244X
 	bool
 	bool
 	depends on ARCH_S3C2410 && (CPU_S3C2440 || CPU_S3C2442)
 	depends on ARCH_S3C2410 && (CPU_S3C2440 || CPU_S3C2442)

+ 1 - 0
arch/arm/plat-s3c24xx/Makefile

@@ -20,6 +20,7 @@ obj-y				+= gpiolib.o
 obj-y				+= time.o
 obj-y				+= time.o
 obj-y				+= clock.o
 obj-y				+= clock.o
 obj-y				+= pwm-clock.o
 obj-y				+= pwm-clock.o
+obj-$(CONFIG_S3C24XX_DCLK)	+= clock-dclk.o
 
 
 # Architecture dependant builds
 # Architecture dependant builds
 
 

+ 194 - 0
arch/arm/plat-s3c24xx/clock-dclk.c

@@ -0,0 +1,194 @@
+/* linux/arch/arm/plat-s3c24xx/clock-dclk.c
+ *
+ * Copyright (c) 2004,2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C24XX - definitions for DCLK and CLKOUT registers
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <mach/regs-clock.h>
+#include <mach/regs-gpio.h>
+
+#include <plat/clock.h>
+#include <plat/cpu.h>
+
+/* clocks that could be registered by external code */
+
+static int s3c24xx_dclk_enable(struct clk *clk, int enable)
+{
+	unsigned long dclkcon = __raw_readl(S3C24XX_DCLKCON);
+
+	if (enable)
+		dclkcon |= clk->ctrlbit;
+	else
+		dclkcon &= ~clk->ctrlbit;
+
+	__raw_writel(dclkcon, S3C24XX_DCLKCON);
+
+	return 0;
+}
+
+static int s3c24xx_dclk_setparent(struct clk *clk, struct clk *parent)
+{
+	unsigned long dclkcon;
+	unsigned int uclk;
+
+	if (parent == &clk_upll)
+		uclk = 1;
+	else if (parent == &clk_p)
+		uclk = 0;
+	else
+		return -EINVAL;
+
+	clk->parent = parent;
+
+	dclkcon = __raw_readl(S3C24XX_DCLKCON);
+
+	if (clk->ctrlbit == S3C2410_DCLKCON_DCLK0EN) {
+		if (uclk)
+			dclkcon |= S3C2410_DCLKCON_DCLK0_UCLK;
+		else
+			dclkcon &= ~S3C2410_DCLKCON_DCLK0_UCLK;
+	} else {
+		if (uclk)
+			dclkcon |= S3C2410_DCLKCON_DCLK1_UCLK;
+		else
+			dclkcon &= ~S3C2410_DCLKCON_DCLK1_UCLK;
+	}
+
+	__raw_writel(dclkcon, S3C24XX_DCLKCON);
+
+	return 0;
+}
+static unsigned long s3c24xx_calc_div(struct clk *clk, unsigned long rate)
+{
+	unsigned long div;
+
+	if ((rate == 0) || !clk->parent)
+		return 0;
+
+	div = clk_get_rate(clk->parent) / rate;
+	if (div < 2)
+		div = 2;
+	else if (div > 16)
+		div = 16;
+
+	return div;
+}
+
+static unsigned long s3c24xx_round_dclk_rate(struct clk *clk,
+	unsigned long rate)
+{
+	unsigned long div = s3c24xx_calc_div(clk, rate);
+
+	if (div == 0)
+		return 0;
+
+	return clk_get_rate(clk->parent) / div;
+}
+
+static int s3c24xx_set_dclk_rate(struct clk *clk, unsigned long rate)
+{
+	unsigned long mask, data, div = s3c24xx_calc_div(clk, rate);
+
+	if (div == 0)
+		return -EINVAL;
+
+	if (clk == &s3c24xx_dclk0) {
+		mask = S3C2410_DCLKCON_DCLK0_DIV_MASK |
+			S3C2410_DCLKCON_DCLK0_CMP_MASK;
+		data = S3C2410_DCLKCON_DCLK0_DIV(div) |
+			S3C2410_DCLKCON_DCLK0_CMP((div + 1) / 2);
+	} else if (clk == &s3c24xx_dclk1) {
+		mask = S3C2410_DCLKCON_DCLK1_DIV_MASK |
+			S3C2410_DCLKCON_DCLK1_CMP_MASK;
+		data = S3C2410_DCLKCON_DCLK1_DIV(div) |
+			S3C2410_DCLKCON_DCLK1_CMP((div + 1) / 2);
+	} else
+		return -EINVAL;
+
+	clk->rate = clk_get_rate(clk->parent) / div;
+	__raw_writel(((__raw_readl(S3C24XX_DCLKCON) & ~mask) | data),
+		S3C24XX_DCLKCON);
+	return clk->rate;
+}
+static int s3c24xx_clkout_setparent(struct clk *clk, struct clk *parent)
+{
+	unsigned long mask;
+	unsigned long source;
+
+	/* calculate the MISCCR setting for the clock */
+
+	if (parent == &clk_xtal)
+		source = S3C2410_MISCCR_CLK0_MPLL;
+	else if (parent == &clk_upll)
+		source = S3C2410_MISCCR_CLK0_UPLL;
+	else if (parent == &clk_f)
+		source = S3C2410_MISCCR_CLK0_FCLK;
+	else if (parent == &clk_h)
+		source = S3C2410_MISCCR_CLK0_HCLK;
+	else if (parent == &clk_p)
+		source = S3C2410_MISCCR_CLK0_PCLK;
+	else if (clk == &s3c24xx_clkout0 && parent == &s3c24xx_dclk0)
+		source = S3C2410_MISCCR_CLK0_DCLK0;
+	else if (clk == &s3c24xx_clkout1 && parent == &s3c24xx_dclk1)
+		source = S3C2410_MISCCR_CLK0_DCLK0;
+	else
+		return -EINVAL;
+
+	clk->parent = parent;
+
+	if (clk == &s3c24xx_clkout0)
+		mask = S3C2410_MISCCR_CLK0_MASK;
+	else {
+		source <<= 4;
+		mask = S3C2410_MISCCR_CLK1_MASK;
+	}
+
+	s3c2410_modify_misccr(mask, source);
+	return 0;
+}
+
+/* external clock definitions */
+
+struct clk s3c24xx_dclk0 = {
+	.name		= "dclk0",
+	.id		= -1,
+	.ctrlbit	= S3C2410_DCLKCON_DCLK0EN,
+	.enable	        = s3c24xx_dclk_enable,
+	.set_parent	= s3c24xx_dclk_setparent,
+	.set_rate	= s3c24xx_set_dclk_rate,
+	.round_rate	= s3c24xx_round_dclk_rate,
+};
+
+struct clk s3c24xx_dclk1 = {
+	.name		= "dclk1",
+	.id		= -1,
+	.ctrlbit	= S3C2410_DCLKCON_DCLK1EN,
+	.enable		= s3c24xx_dclk_enable,
+	.set_parent	= s3c24xx_dclk_setparent,
+	.set_rate	= s3c24xx_set_dclk_rate,
+	.round_rate	= s3c24xx_round_dclk_rate,
+};
+
+struct clk s3c24xx_clkout0 = {
+	.name		= "clkout0",
+	.id		= -1,
+	.set_parent	= s3c24xx_clkout_setparent,
+};
+
+struct clk s3c24xx_clkout1 = {
+	.name		= "clkout1",
+	.id		= -1,
+	.set_parent	= s3c24xx_clkout_setparent,
+};

+ 0 - 171
arch/arm/plat-s3c24xx/clock.c

@@ -283,178 +283,7 @@ struct clk clk_usb_bus = {
 	.parent		= &clk_upll,
 	.parent		= &clk_upll,
 };
 };
 
 
-/* clocks that could be registered by external code */
 
 
-static int s3c24xx_dclk_enable(struct clk *clk, int enable)
-{
-	unsigned long dclkcon = __raw_readl(S3C24XX_DCLKCON);
-
-	if (enable)
-		dclkcon |= clk->ctrlbit;
-	else
-		dclkcon &= ~clk->ctrlbit;
-
-	__raw_writel(dclkcon, S3C24XX_DCLKCON);
-
-	return 0;
-}
-
-static int s3c24xx_dclk_setparent(struct clk *clk, struct clk *parent)
-{
-	unsigned long dclkcon;
-	unsigned int uclk;
-
-	if (parent == &clk_upll)
-		uclk = 1;
-	else if (parent == &clk_p)
-		uclk = 0;
-	else
-		return -EINVAL;
-
-	clk->parent = parent;
-
-	dclkcon = __raw_readl(S3C24XX_DCLKCON);
-
-	if (clk->ctrlbit == S3C2410_DCLKCON_DCLK0EN) {
-		if (uclk)
-			dclkcon |= S3C2410_DCLKCON_DCLK0_UCLK;
-		else
-			dclkcon &= ~S3C2410_DCLKCON_DCLK0_UCLK;
-	} else {
-		if (uclk)
-			dclkcon |= S3C2410_DCLKCON_DCLK1_UCLK;
-		else
-			dclkcon &= ~S3C2410_DCLKCON_DCLK1_UCLK;
-	}
-
-	__raw_writel(dclkcon, S3C24XX_DCLKCON);
-
-	return 0;
-}
-
-static unsigned long s3c24xx_calc_div(struct clk *clk, unsigned long rate)
-{
-	unsigned long div;
-
-	if ((rate == 0) || !clk->parent)
-		return 0;
-
-	div = clk_get_rate(clk->parent) / rate;
-	if (div < 2)
-		div = 2;
-	else if (div > 16)
-		div = 16;
-
-	return div;
-}
-
-static unsigned long s3c24xx_round_dclk_rate(struct clk *clk,
-	unsigned long rate)
-{
-	unsigned long div = s3c24xx_calc_div(clk, rate);
-
-	if (div == 0)
-		return 0;
-
-	return clk_get_rate(clk->parent) / div;
-}
-
-static int s3c24xx_set_dclk_rate(struct clk *clk, unsigned long rate)
-{
-	unsigned long mask, data, div = s3c24xx_calc_div(clk, rate);
-
-	if (div == 0)
-		return -EINVAL;
-
-	if (clk == &s3c24xx_dclk0) {
-		mask = S3C2410_DCLKCON_DCLK0_DIV_MASK |
-			S3C2410_DCLKCON_DCLK0_CMP_MASK;
-		data = S3C2410_DCLKCON_DCLK0_DIV(div) |
-			S3C2410_DCLKCON_DCLK0_CMP((div + 1) / 2);
-	} else if (clk == &s3c24xx_dclk1) {
-		mask = S3C2410_DCLKCON_DCLK1_DIV_MASK |
-			S3C2410_DCLKCON_DCLK1_CMP_MASK;
-		data = S3C2410_DCLKCON_DCLK1_DIV(div) |
-			S3C2410_DCLKCON_DCLK1_CMP((div + 1) / 2);
-	} else
-		return -EINVAL;
-
-	clk->rate = clk_get_rate(clk->parent) / div;
-	__raw_writel(((__raw_readl(S3C24XX_DCLKCON) & ~mask) | data),
-		S3C24XX_DCLKCON);
-	return clk->rate;
-}
-
-static int s3c24xx_clkout_setparent(struct clk *clk, struct clk *parent)
-{
-	unsigned long mask;
-	unsigned long source;
-
-	/* calculate the MISCCR setting for the clock */
-
-	if (parent == &clk_xtal)
-		source = S3C2410_MISCCR_CLK0_MPLL;
-	else if (parent == &clk_upll)
-		source = S3C2410_MISCCR_CLK0_UPLL;
-	else if (parent == &clk_f)
-		source = S3C2410_MISCCR_CLK0_FCLK;
-	else if (parent == &clk_h)
-		source = S3C2410_MISCCR_CLK0_HCLK;
-	else if (parent == &clk_p)
-		source = S3C2410_MISCCR_CLK0_PCLK;
-	else if (clk == &s3c24xx_clkout0 && parent == &s3c24xx_dclk0)
-		source = S3C2410_MISCCR_CLK0_DCLK0;
-	else if (clk == &s3c24xx_clkout1 && parent == &s3c24xx_dclk1)
-		source = S3C2410_MISCCR_CLK0_DCLK0;
-	else
-		return -EINVAL;
-
-	clk->parent = parent;
-
-	if (clk == &s3c24xx_clkout0)
-		mask = S3C2410_MISCCR_CLK0_MASK;
-	else {
-		source <<= 4;
-		mask = S3C2410_MISCCR_CLK1_MASK;
-	}
-
-	s3c2410_modify_misccr(mask, source);
-	return 0;
-}
-
-/* external clock definitions */
-
-struct clk s3c24xx_dclk0 = {
-	.name		= "dclk0",
-	.id		= -1,
-	.ctrlbit	= S3C2410_DCLKCON_DCLK0EN,
-	.enable	        = s3c24xx_dclk_enable,
-	.set_parent	= s3c24xx_dclk_setparent,
-	.set_rate	= s3c24xx_set_dclk_rate,
-	.round_rate	= s3c24xx_round_dclk_rate,
-};
-
-struct clk s3c24xx_dclk1 = {
-	.name		= "dclk1",
-	.id		= -1,
-	.ctrlbit	= S3C2410_DCLKCON_DCLK1EN,
-	.enable		= s3c24xx_dclk_enable,
-	.set_parent	= s3c24xx_dclk_setparent,
-	.set_rate	= s3c24xx_set_dclk_rate,
-	.round_rate	= s3c24xx_round_dclk_rate,
-};
-
-struct clk s3c24xx_clkout0 = {
-	.name		= "clkout0",
-	.id		= -1,
-	.set_parent	= s3c24xx_clkout_setparent,
-};
-
-struct clk s3c24xx_clkout1 = {
-	.name		= "clkout1",
-	.id		= -1,
-	.set_parent	= s3c24xx_clkout_setparent,
-};
 
 
 struct clk s3c24xx_uclk = {
 struct clk s3c24xx_uclk = {
 	.name		= "uclk",
 	.name		= "uclk",