Commit 1322188f authored by Kevin Hilman's avatar Kevin Hilman

clock: rework PLL/clock handling, with goal of DVFS capable clock tree

Here's a another pass at better modeling of clocks and PLLs.  The
longer term goal being the ability model the clock tree well enough to
do DVFS on devices that support it.

  - generalize PLL control and clock distribution
  - model PLLs, their dividers and the resulting PLL-derived clocks
  - add clock parent/child relationships
  - drop 'div_by_*' in favor of using PLL dividers
  - misc. other minor cleanups
  - move clock definitions into chip-specific code
  - start using clk_get_rate() to get rates (UART, timers)
  - drop DM*_CLOCK_TICK_RATE

Updates from last version

  - multiple updates and fixes from David Brownell (Thanks!)
  - use of divider registers instead of 'fixed_divisor' field
    to better model PLL-derived clocks based on divider regs.
  - drop some hard-coded LPSC init in favor of enabling with
    relevant clock.

TODO:
- seek-and-destroy hardcoded clock rates
Signed-off-by: default avatarKevin Hilman <khilman@deeprootsystems.com>
parent 5d0acbd9
......@@ -9,6 +9,11 @@ obj-y := time.o irq.o clock.o serial.o io.o id.o psc.o \
obj-$(CONFIG_DAVINCI_MUX) += mux.o mux_cfg.o
# Chip specific
obj-$(CONFIG_ARCH_DAVINCI_DM644x) += dm644x.o
obj-$(CONFIG_ARCH_DAVINCI_DM646x) += dm646x.o
obj-$(CONFIG_ARCH_DAVINCI_DM355) += dm355.o
# Board specific
obj-$(CONFIG_MACH_DAVINCI_EVM) += board-dm644x-evm.o
obj-$(CONFIG_MACH_DAVINCI_DM646X_EVM) += board-dm646x-evm.o
......
......@@ -28,6 +28,7 @@
#include <asm/mach/flash.h>
#include <mach/hardware.h>
#include <mach/dm355.h>
#include <mach/psc.h>
#include <mach/common.h>
#include <mach/emac.h>
......@@ -173,6 +174,7 @@ static struct davinci_uart_config uart_config __initdata = {
static void __init dm355_evm_map_io(void)
{
davinci_map_common_io();
dm355_init();
}
static int dm355evm_mmc_get_cd(int module)
......@@ -210,8 +212,6 @@ static struct davinci_mmc_config dm355evm_mmc_config = {
static __init void dm355_evm_init(void)
{
davinci_psc_init();
gpio_request(1, "dm9000");
gpio_direction_input(1);
dm355evm_dm9000_rsrc[2].start = gpio_to_irq(1);
......@@ -232,7 +232,6 @@ static __init void dm355_evm_init(void)
static __init void dm355_evm_irq_init(void)
{
davinci_init_common_hw();
davinci_irq_init();
}
......
......@@ -590,6 +590,7 @@ static void __init
davinci_evm_map_io(void)
{
davinci_map_common_io();
dm644x_init();
}
static int davinci_phy_fixup(struct phy_device *phydev)
......@@ -607,8 +608,6 @@ static int davinci_phy_fixup(struct phy_device *phydev)
static __init void davinci_evm_init(void)
{
davinci_psc_init();
#if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \
defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE)
#if defined(CONFIG_MTD_PHYSMAP) || \
......@@ -634,7 +633,6 @@ static __init void davinci_evm_init(void)
static __init void davinci_evm_irq_init(void)
{
davinci_init_common_hw();
davinci_irq_init();
}
......
......@@ -33,8 +33,8 @@
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/flash.h>
#include <mach/dm646x.h>
#include <mach/common.h>
#include <mach/hardware.h>
#include <mach/psc.h>
#include <mach/serial.h>
#include <mach/i2c.h>
......@@ -116,18 +116,17 @@ static void __init evm_init_i2c(void)
static void __init davinci_map_io(void)
{
davinci_map_common_io();
dm646x_init();
}
static __init void evm_init(void)
{
davinci_psc_init();
evm_init_i2c();
davinci_serial_init(&uart_config);
}
static __init void davinci_dm646x_evm_irq_init(void)
{
davinci_init_common_hw();
davinci_irq_init();
}
......
......@@ -147,6 +147,7 @@ static struct davinci_uart_config uart_config __initdata = {
static void __init davinci_sffsdr_map_io(void)
{
davinci_map_common_io();
dm644x_init();
}
static __init void davinci_sffsdr_init(void)
......@@ -180,7 +181,6 @@ __setup("eth=", davinci_cpmac_eth_setup);
static __init void davinci_sffsdr_irq_init(void)
{
davinci_init_common_hw();
davinci_irq_init();
}
......
This diff is collapsed.
......@@ -11,32 +11,69 @@
#ifndef __ARCH_ARM_DAVINCI_CLOCK_H
#define __ARCH_ARM_DAVINCI_CLOCK_H
#include <linux/list.h>
#define DAVINCI_PLL1_BASE 0x01c40800
#define DAVINCI_PLL2_BASE 0x01c40c00
#define MAX_PLL 2
/* PLL/Reset register offsets */
#define PLLCTL 0x100
#define PLLCTL_PLLEN BIT(0)
#define PLLCTL_CLKMODE BIT(8)
#define PLLM 0x110
#define PLLM_PLLM_MASK 0xff
#define PREDIV 0x114
#define PLLDIV1 0x118
#define PLLDIV2 0x11c
#define PLLDIV3 0x120
#define POSTDIV 0x128
#define BPDIV 0x12c
#define PLLCMD 0x138
#define PLLSTAT 0x13c
#define PLLALNCTL 0x140
#define PLLDCHANGE 0x144
#define PLLCKEN 0x148
#define PLLCKSTAT 0x14c
#define PLLSYSTAT 0x150
#define PLLDIV4 0x160
#define PLLDIV5 0x164
#define PLLDIV6 0x168
#define PLLDIV8 0x170
#define PLLDIV9 0x174
#define PLLDIV_EN BIT(15)
#define PLLDIV_RATIO_MASK 0x1f
struct pll_data {
u32 phys_base;
void __iomem *base;
u32 num;
u32 flags;
u32 input_rate;
};
#define PLL_HAS_PREDIV 0x01
#define PLL_HAS_POSTDIV 0x02
struct clk {
struct list_head node;
struct module *owner;
const char *name;
unsigned int *rate;
int id;
__s8 usecount;
__u8 flags;
__u8 lpsc;
unsigned long rate;
u8 usecount;
u8 flags;
u8 lpsc;
struct clk *parent;
struct pll_data *pll_data;
u32 div_reg;
};
/* Clock flags */
#define RATE_CKCTL 1
#define RATE_FIXED 2
#define RATE_PROPAGATES 4
#define VIRTUAL_CLOCK 8
#define ALWAYS_ENABLED 16
#define ENABLE_REG_32BIT 32
/* various clock frequencies */
#define DM646X_OSC_FREQ 27000000
#define DM646X_AUX_OSC_FREQ 24000000
#define DM646X_CLOCK_TICK_RATE 148500000
#define DM355_CLOCK_TICK_RATE 24000000
#define ALWAYS_ENABLED BIT(1)
#define CLK_PLL BIT(2)
int davinci_clk_associate(struct device *dev, const char *logical_clockname,
const char *physical_clockname);
const char *physical_clockname);
#endif
/*
* TI DaVinci DM355 chip specific setup
*
* Author: Kevin Hilman, Deep Root Systems, LLC
*
* 2007 (c) Deep Root Systems, LLC. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/clk.h>
#include <mach/dm355.h>
#include <mach/clock.h>
#include <mach/psc.h>
#include <mach/mux.h>
#include "clock.h"
#define DM355_REF_FREQ 24000000 /* 24 or 36 MHz */
static struct pll_data pll1_data = {
.num = 1,
.phys_base = DAVINCI_PLL1_BASE,
.flags = PLL_HAS_PREDIV | PLL_HAS_POSTDIV,
};
static struct pll_data pll2_data = {
.num = 2,
.phys_base = DAVINCI_PLL2_BASE,
.flags = PLL_HAS_PREDIV,
};
static struct clk ref_clk = {
.name = "ref_clk",
/* FIXME -- crystal rate is board-specific */
.rate = DM355_REF_FREQ,
.flags = CLK_PLL,
};
static struct clk pll1_clk = {
.name = "pll1",
.parent = &ref_clk,
.flags = CLK_PLL,
.pll_data = &pll1_data,
};
static struct clk pll2_clk = {
.name = "pll2",
.parent = &ref_clk,
.flags = CLK_PLL,
.pll_data = &pll2_data,
};
static struct clk aux_clk = {
.name = "aux_clk",
.parent = &ref_clk,
.flags = CLK_PLL,
};
static struct clk sysclk1_clk = {
.name = "SYSCLK1",
.parent = &pll1_clk,
.flags = CLK_PLL,
.div_reg = PLLDIV1,
};
static struct clk sysclk2_clk = {
.name = "SYSCLK2",
.parent = &pll1_clk,
.flags = CLK_PLL,
.div_reg = PLLDIV2,
};
static struct clk vpbe_clk = { /* a.k.a. PLL1.SYSCLK3 */
.name = "vpbe",
.parent = &pll1_clk,
.flags = CLK_PLL,
.div_reg = PLLDIV3,
};
static struct clk vpss_clk = { /* a.k.a. PLL1.SYCLK4 */
.name = "vpss",
.parent = &pll1_clk,
.flags = CLK_PLL,
.div_reg = PLLDIV4,
};
static struct clk clkout1_clk = {
.name = "clkout1",
.parent = &aux_clk,
.flags = CLK_PLL,
/* NOTE: clkout1 can be externally gated by muxing GPIO-18 */
};
static struct clk clkout2_clk = { /* a.k.a. PLL1.SYSCLKBP */
.name = "clkout2",
.parent = &pll1_clk,
.flags = CLK_PLL,
.div_reg = BPDIV,
};
static struct clk clkout3_clk = {
.name = "clkout3",
.parent = &pll2_clk,
.flags = CLK_PLL,
.div_reg = BPDIV,
/* NOTE: clkout3 can be externally gated by muxing GPIO-16 */
};
static struct clk arm_clk = {
.name = "ARMCLK",
.parent = &sysclk1_clk,
.flags = ALWAYS_ENABLED | CLK_PLL,
};
/*
* NOT LISTED below, but turned on by PSC init:
* - in SyncReset state by default
* .lpsc = DAVINCI_LPSC_VPSSMSTR, .parent = &vpss_clk,
* .lpsc = DAVINCI_LPSC_VPSSSLV, .parent = &vpss_clk,
* .lpsc = DAVINCI_LPSC_TPCC,
* .lpsc = DAVINCI_LPSC_TPTC0,
* .lpsc = DAVINCI_LPSC_TPTC1,
*
* NOT LISTED below, and not touched by Linux
* - in SyncReset state by default
* .lpsc = DAVINCI_LPSC_DDR_EMIF, .parent = &sysclk2_clk,
* .lpsc = DM355_LPSC_RT0, .parent = &aux_clk,
* .lpsc = DAVINCI_LPSC_MEMSTICK,
* .lpsc = 41, .parent = &vpss_clk, // VPSS DAC
* - in Enabled state by default
* .lpsc = DAVINCI_LPSC_SYSTEM_SUBSYS,
* .lpsc = DAVINCI_LPSC_SCR2, // "bus"
* .lpsc = DAVINCI_LPSC_SCR3, // "bus"
* .lpsc = DAVINCI_LPSC_SCR4, // "bus"
* .lpsc = DAVINCI_LPSC_CROSSBAR, // "emulation"
* .lpsc = DAVINCI_LPSC_CFG27, // "test"
* .lpsc = DAVINCI_LPSC_CFG3, // "test"
* .lpsc = DAVINCI_LPSC_CFG5, // "test"
*/
static struct clk mjcp_clk = {
.name = "mjcp",
.parent = &sysclk1_clk,
.lpsc = DAVINCI_LPSC_IMCOP,
};
static struct clk uart0_clk = {
.name = "uart0",
.parent = &aux_clk,
.lpsc = DAVINCI_LPSC_UART0,
};
static struct clk uart1_clk = {
.name = "uart1",
.parent = &aux_clk,
.lpsc = DAVINCI_LPSC_UART1,
};
static struct clk uart2_clk = {
.name = "uart2",
.parent = &sysclk2_clk,
.lpsc = DAVINCI_LPSC_UART2,
};
static struct clk i2c_clk = {
.name = "I2CCLK",
.parent = &aux_clk,
.lpsc = DAVINCI_LPSC_I2C,
};
static struct clk asp0_clk = {
.name = "asp0_clk",
.parent = &sysclk2_clk,
.lpsc = DAVINCI_LPSC_McBSP,
};
static struct clk asp1_clk = {
.name = "asp1_clk",
.parent = &sysclk2_clk,
.lpsc = DM355_LPSC_McBSP1,
};
static struct clk mmcsd0_clk = {
.name = "MMCSDCLK0",
.parent = &sysclk2_clk,
.lpsc = DAVINCI_LPSC_MMC_SD,
};
static struct clk mmcsd1_clk = {
.name = "MMCSDCLK1",
.parent = &sysclk2_clk,
.lpsc = DM355_LPSC_MMC_SD1,
};
static struct clk spi0_clk = {
.name = "SPICLK",
.parent = &sysclk2_clk,
.lpsc = DAVINCI_LPSC_SPI,
};
static struct clk spi1_clk = {
.name = "SPICLK1",
.parent = &sysclk2_clk,
.lpsc = DM355_LPSC_SPI1,
};
static struct clk spi2_clk = {
.name = "SPICLK2",
.parent = &sysclk2_clk,
.lpsc = DM355_LPSC_SPI2,
};
static struct clk gpio_clk = {
.name = "gpio",
.parent = &sysclk2_clk,
.lpsc = DAVINCI_LPSC_GPIO,
};
static struct clk aemif_clk = {
.name = "AEMIFCLK",
.parent = &sysclk2_clk,
.lpsc = DAVINCI_LPSC_AEMIF,
.usecount = 1,
};
static struct clk pwm0_clk = {
.name = "PWM0_CLK",
.parent = &aux_clk,
.lpsc = DAVINCI_LPSC_PWM0,
};
static struct clk pwm1_clk = {
.name = "PWM1_CLK",
.parent = &aux_clk,
.lpsc = DAVINCI_LPSC_PWM1,
};
static struct clk pwm2_clk = {
.name = "PWM2_CLK",
.parent = &aux_clk,
.lpsc = DAVINCI_LPSC_PWM2,
};
static struct clk pwm3_clk = {
.name = "PWM3_CLK",
.parent = &aux_clk,
.lpsc = DM355_LPSC_PWM3,
};
static struct clk timer0_clk = {
.name = "timer0",
.parent = &aux_clk,
.lpsc = DAVINCI_LPSC_TIMER0,
};
static struct clk timer1_clk = {
.name = "timer1",
.parent = &aux_clk,
.lpsc = DAVINCI_LPSC_TIMER1,
};
static struct clk timer2_clk = {
.name = "timer2",
.parent = &aux_clk,
.lpsc = DAVINCI_LPSC_TIMER2,
};
static struct clk timer3_clk = {
.name = "timer3",
.parent = &aux_clk,
.lpsc = DM355_LPSC_TIMER3,
};
static struct clk usb_clk = {
.name = "USBCLK",
.parent = &sysclk2_clk,
.lpsc = DAVINCI_LPSC_USB,
};
static struct clk *dm355_clks[] __initdata = {
&ref_clk,
&pll1_clk,
&aux_clk,
&sysclk1_clk,
&sysclk2_clk,
&vpbe_clk,
&vpss_clk,
&clkout1_clk,
&clkout2_clk,
&pll2_clk,
&clkout3_clk,
&arm_clk,
&mjcp_clk,
&uart0_clk,
&uart1_clk,
&uart2_clk,
&i2c_clk,
&asp0_clk,
&asp1_clk,
&mmcsd0_clk,
&mmcsd1_clk,
&spi0_clk,
&spi1_clk,
&spi2_clk,
&gpio_clk,
&aemif_clk,
&pwm0_clk,
&pwm1_clk,
&pwm2_clk,
&pwm3_clk,
&timer0_clk,
&timer1_clk,
&timer2_clk,
&timer3_clk,
&usb_clk,
NULL,
};
void __init dm355_init(void)
{
davinci_clk_init(dm355_clks);
davinci_mux_init();
}
/*
* TI DaVinci DM644x chip specific setup
*
* Author: Kevin Hilman, Deep Root Systems, LLC
*
* 2007 (c) Deep Root Systems, LLC. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/clk.h>
#include <mach/dm644x.h>
#include <mach/clock.h>
#include <mach/psc.h>
#include <mach/mux.h>
#include "clock.h"
#define DM644X_REF_FREQ 27000000
static struct pll_data pll1_data = {
.num = 1,
.phys_base = DAVINCI_PLL1_BASE,
};
static struct pll_data pll2_data = {
.num = 2,
.phys_base = DAVINCI_PLL2_BASE,
};
static struct clk ref_clk = {
.name = "ref_clk",
.rate = DM644X_REF_FREQ,
.flags = CLK_PLL,
};
static struct clk pll1_clk = {
.name = "pll1",
.parent = &ref_clk,
.pll_data = &pll1_data,
.flags = CLK_PLL,
};
static struct clk pll2_clk = {
.name = "pll2",
.parent = &ref_clk,
.pll_data = &pll2_data,
.flags = CLK_PLL,
};
static struct clk sysclk1_clk = {
.name = "SYSCLK1",
.parent = &pll1_clk,
.flags = CLK_PLL,
.div_reg = PLLDIV1,
};
static struct clk sysclk2_clk = {
.name = "SYSCLK2",
.parent = &pll1_clk,
.flags = CLK_PLL,
.div_reg = PLLDIV2,
};
static struct clk sysclk3_clk = {
.name = "SYSCLK3",
.parent = &pll1_clk,
.flags = CLK_PLL,
.div_reg = PLLDIV3,
};
static struct clk sysclk5_clk = {
.name = "SYSCLK5",
.parent = &pll1_clk,
.flags = CLK_PLL,
.div_reg = PLLDIV5,
};
static struct clk arm_clk = {
.name = "ARMCLK",
.parent = &sysclk2_clk,
.lpsc = DAVINCI_LPSC_NONE,
.flags = ALWAYS_ENABLED,
};
static struct clk uart0_clk = {
.name = "uart0",
.parent = &ref_clk,
.lpsc = DAVINCI_LPSC_UART0,
};
static struct clk uart1_clk = {
.name = "uart1",
.parent = &ref_clk,
.lpsc = DAVINCI_LPSC_UART1,
};
static struct clk uart2_clk = {
.name = "uart2",
.parent = &ref_clk,
.lpsc = DAVINCI_LPSC_UART2,
};
static struct clk emac_clk = {
.name = "EMACCLK",
.parent = &sysclk5_clk,
.lpsc = DAVINCI_LPSC_EMAC_WRAPPER,
};
static struct clk i2c_clk = {
.name = "I2CCLK",
.parent = &ref_clk,
.lpsc = DAVINCI_LPSC_I2C,
};
static struct clk ide_clk = {
.name = "IDECLK",
.parent = &sysclk5_clk,
.lpsc = DAVINCI_LPSC_ATA,
};
static struct clk asp_clk = {
.name = "asp0_clk",
.parent = &sysclk5_clk,
.lpsc = DAVINCI_LPSC_McBSP,
};
static struct clk mmcsd_clk = {
.name = "MMCSDCLK",
.parent = &sysclk5_clk,
.lpsc = DAVINCI_LPSC_MMC_SD,
};
static struct clk spi_clk = {
.name = "SPICLK",
.parent = &sysclk5_clk,
.lpsc = DAVINCI_LPSC_SPI,
};
static struct clk gpio_clk = {
.name = "gpio",
.parent = &sysclk5_clk,
.lpsc = DAVINCI_LPSC_GPIO,
};
static struct clk usb_clk = {
.name = "USBCLK",
.parent = &sysclk5_clk,
.lpsc = DAVINCI_LPSC_USB,
};
static struct clk vlynq_clk = {
.name = "VLYNQCLK",
.parent = &sysclk5_clk,
.lpsc = DAVINCI_LPSC_VLYNQ,
};
static struct clk aemif_clk = {
.name = "AEMIFCLK",
.parent = &sysclk5_clk,
.lpsc = DAVINCI_LPSC_AEMIF,
.flags = ALWAYS_ENABLED,
};
static struct clk timer0_clk = {
.name = "timer0",
.parent = &ref_clk,
.lpsc = DAVINCI_LPSC_TIMER0,
};
static struct clk timer1_clk = {
.name = "timer1",
.parent = &ref_clk,
.lpsc = DAVINCI_LPSC_TIMER1,
};
static struct clk timer2_clk = {
.name = "timer2",
.parent = &ref_clk,
.lpsc = DAVINCI_LPSC_TIMER2,
};
static struct clk *dm644x_clks[] __initdata = {
&ref_clk,
&pll1_clk,
&pll2_clk,
&sysclk1_clk,
&sysclk2_clk,
&sysclk3_clk,
&sysclk5_clk,
&arm_clk,
&uart0_clk,
&uart1_clk,
&uart2_clk,
&emac_clk,
&i2c_clk,
&ide_clk,
&asp_clk,
&mmcsd_clk,
&spi_clk,
&gpio_clk,
&usb_clk,
&vlynq_clk,
&aemif_clk,
&timer0_clk,
&timer1_clk,
&timer2_clk,
NULL,
};
void __init dm644x_init(void)
{
davinci_clk_init(dm644x_clks);
davinci_mux_init();
}
/*
* TI DaVinci DM644x chip specific setup
*
* Author: Kevin Hilman, Deep Root Systems, LLC
*
* 2007 (c) Deep Root Systems, LLC. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/clk.h>
#include <mach/dm644x.h>
#include <mach/clock.h>
#include <mach/psc.h>
#include <mach/mux.h>
#include "clock.h"
/* various clock frequencies */
#define DM646X_REF_FREQ 27000000
#define DM646X_AUX_FREQ 24000000
static struct pll_data pll1_data = {
.num = 1,
.phys_base = DAVINCI_PLL1_BASE,
};
static struct pll_data pll2_data = {
.num = 2,
.phys_base = DAVINCI_PLL2_BASE,
};
static struct clk ref_clk = {
.name = "ref_clk",
.rate = DM646X_REF_FREQ,
.flags = CLK_PLL,
};
static struct clk aux_clk = {
.name = "aux_clk",
.rate = DM646X_AUX_FREQ,
.flags = CLK_PLL,
};
static struct clk pll1_clk = {
.name = "pll1",
.parent = &ref_clk,
.pll_data = &pll1_data,
.flags = CLK_PLL,
};
static struct clk pll2_clk = {
.name = "pll2",
.parent = &ref_clk,
.pll_data = &pll2_data,
.flags = CLK_PLL,
};
static struct clk sysclk1_clk = {
.name = "SYSCLK1",
.parent = &pll1_clk,
.flags = CLK_PLL,
.div_reg = PLLDIV1,
};
static struct clk sysclk2_clk = {
.name = "SYSCLK2",
.parent = &pll1_clk,
.flags = CLK_PLL,
.div_reg = PLLDIV2,
};
static struct clk sysclk3_clk = {
.name = "SYSCLK3",
.parent = &pll1_clk,
.flags = CLK_PLL,
.div_reg = PLLDIV3,
};
static struct clk sysclk4_clk = {
.name = "SYSCLK4",
.parent = &pll1_clk,
.flags = CLK_PLL,
.div_reg = PLLDIV4,
};
static struct clk sysclk5_clk = {
.name = "SYSCLK5",
.parent = &pll1_clk,
.flags = CLK_PLL,
.div_reg = PLLDIV5,
};
static struct clk sysclk6_clk = {
.name = "SYSCLK6",
.parent = &pll1_clk,
.flags = CLK_PLL,
.div_reg = PLLDIV6,
};
static struct clk sysclk8_clk = {
.name = "SYSCLK8",
.parent = &pll1_clk,
.flags = CLK_PLL,
.div_reg = PLLDIV8,
};
static struct clk sysclk9_clk = {
.name = "SYSCLK9",
.parent = &pll1_clk,
.flags = CLK_PLL,
.div_reg = PLLDIV9,
};
static struct clk sysclkbp_clk = {
.name = "SYSCLKBP",
.parent = &pll1_clk,
.flags = CLK_PLL,
.div_reg = BPDIV,
};
static struct clk arm_clk = {
.name = "ARMCLK",
.parent = &sysclk2_clk,
.lpsc = DAVINCI_LPSC_NONE,
.flags = ALWAYS_ENABLED,
};
static struct clk uart0_clk = {
.name = "uart0",
.parent = &aux_clk,
.lpsc = DM646X_LPSC_UART0,
};
static struct clk uart1_clk = {
.name = "uart1",
.parent = &aux_clk,
.lpsc = DM646X_LPSC_UART1,
};
static struct clk uart2_clk = {
.name = "uart2",
.parent = &aux_clk,
.lpsc = DM646X_LPSC_UART2,
};
static struct clk i2c_clk = {
.name = "I2CCLK",
.parent = &sysclk3_clk,
.lpsc = DM646X_LPSC_I2C,
};
static struct clk gpio_clk = {
.name = "gpio",
.parent = &sysclk3_clk,
.lpsc = DM646X_LPSC_GPIO,
};
static struct clk aemif_clk = {
.name = "AEMIFCLK",
.parent = &sysclk3_clk,
.lpsc = DM646X_LPSC_AEMIF,
.flags = ALWAYS_ENABLED,
};
static struct clk emac_clk = {
.name = "EMACCLK",
.parent = &sysclk3_clk,
.lpsc = DM646X_LPSC_EMAC,
};
static struct clk timer0_clk = {
.name = "timer0",
.parent = &sysclk3_clk,
.lpsc = DM646X_LPSC_TIMER0,
};
static struct clk timer1_clk = {
.name = "timer1",
.parent = &sysclk3_clk,
.lpsc = DM646X_LPSC_TIMER1,
};
static struct clk *dm646x_clks[] __initdata = {
&ref_clk,
&pll1_clk,
&sysclk1_clk,
&sysclk2_clk,
&sysclk3_clk,
&sysclk4_clk,
&sysclk5_clk,
&sysclk6_clk,
&sysclk8_clk,
&sysclk9_clk,
&sysclkbp_clk,
&pll2_clk,
&arm_clk,
&uart0_clk,
&uart1_clk,
&uart2_clk,
&i2c_clk,
&gpio_clk,
&aemif_clk,
&emac_clk,
&timer0_clk,
&timer1_clk,
NULL,
};
void __init dm646x_init(void)
{
davinci_clk_init(dm646x_clks);
davinci_mux_init();
}
......@@ -17,6 +17,6 @@ struct clk;
extern int clk_register(struct clk *clk);
extern void clk_unregister(struct clk *clk);
extern int davinci_clk_init(void);
extern int davinci_clk_init(struct clk *clocks[]);
#endif
......@@ -17,7 +17,6 @@ struct sys_timer;
extern struct sys_timer davinci_timer;
extern void davinci_irq_init(void);
extern void davinci_init_common_hw(void);
extern void davinci_map_common_io(void);
/* parameters describe VBUS sourcing for host mode */
......
/*
* Chip specific defines for DM355 SoC
*
* Author: Kevin Hilman, Deep Root Systems, LLC
*
* 2007 (c) Deep Root Systems, LLC. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#ifndef __ASM_ARCH_DM355_H
#define __ASM_ARCH_DM355_H
#include <mach/hardware.h>
void __init dm355_init(void);
#endif /* __ASM_ARCH_DM355_H */
......@@ -24,4 +24,6 @@
#include <mach/hardware.h>
void __init dm644x_init(void);
#endif /* __ASM_ARCH_DM644X_H */
/*
* Chip specific defines for DM646x SoC
*
* Author: Kevin Hilman, Deep Root Systems, LLC
*
* 2007 (c) Deep Root Systems, LLC. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#ifndef __ASM_ARCH_DM646X_H
#define __ASM_ARCH_DM646X_H
#include <mach/hardware.h>
void __init dm646x_init(void);
#endif /* __ASM_ARCH_DM646X_H */
......@@ -31,6 +31,8 @@
#define DAVINCI_GPSC_ARMDOMAIN 0
#define DAVINCI_GPSC_DSPDOMAIN 1
#define DAVINCI_LPSC_NONE 0xff
#define DAVINCI_LPSC_VPSSMSTR 0
#define DAVINCI_LPSC_VPSSSLV 1
#define DAVINCI_LPSC_TPCC 2
......
......@@ -51,9 +51,3 @@ void __init davinci_map_common_io(void)
*/
davinci_check_revision();
}
void __init davinci_init_common_hw(void)
{
davinci_mux_init();
davinci_clk_init();
}
......@@ -124,6 +124,9 @@ void davinci_psc_config(unsigned int domain, unsigned int id, char enable)
{
u32 epcpr, ptcmd, ptstat, pdstat, pdctl1, mdstat, mdctl, mdstat_mask;
if (id == DAVINCI_LPSC_NONE)
return;
mdctl = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + MDCTL + 4 * id);
if (enable)
mdctl |= 0x00000003; /* Enable Module */
......@@ -199,12 +202,5 @@ void __init davinci_psc_init(void)
DAVINCI_LPSC_TPTC0, 1);
davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN,
DAVINCI_LPSC_TPTC1, 1);
/* Turn on WatchDog timer LPSC. Needed for RESET to work */
davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN,
DAVINCI_LPSC_TIMER2, 1);
} else if (cpu_is_davinci_dm646x()) {
davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN,
DM646X_LPSC_AEMIF, 1);
}
}
......@@ -57,7 +57,6 @@ static struct plat_serial8250_port serial_platform_data[] = {
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
.iotype = UPIO_MEM,
.regshift = 2,
.uartclk = 27000000,
},
{
.membase = (char *)IO_ADDRESS(DAVINCI_UART1_BASE),
......@@ -66,7 +65,6 @@ static struct plat_serial8250_port serial_platform_data[] = {
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
.iotype = UPIO_MEM,
.regshift = 2,
.uartclk = 27000000,
},
{
.membase = (char *)IO_ADDRESS(DAVINCI_UART2_BASE),
......@@ -75,7 +73,6 @@ static struct plat_serial8250_port serial_platform_data[] = {
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
.iotype = UPIO_MEM,
.regshift = 2,
.uartclk = 27000000,
},
{
.flags = 0
......@@ -125,12 +122,10 @@ void __init davinci_serial_init(struct davinci_uart_config *info)
struct plat_serial8250_port *p = serial_platform_data + i;
if (cpu_is_davinci_dm646x()) {
p->uartclk = DM646X_AUX_OSC_FREQ;
p->iotype = UPIO_MEM32;
}
if (cpu_is_davinci_dm355()) {
p->uartclk = 24000000;
if (i == 2) {
p->membase = (char *)
IO_ADDRESS(DM355_UART2_BASE);
......@@ -144,8 +139,9 @@ void __init davinci_serial_init(struct davinci_uart_config *info)
continue;
}
sprintf(name, "UART%d", i);
sprintf(name, "uart%d", i);
uart_clk = clk_get(dev, name);
p->uartclk = clk_get_rate(uart_clk);
if (IS_ERR(uart_clk))
printk(KERN_ERR "%s:%d: failed to get UART%d clock\n",
__func__, __LINE__, i);
......
......@@ -16,6 +16,8 @@
#include <linux/clockchips.h>
#include <linux/spinlock.h>
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <mach/hardware.h>
#include <asm/system.h>
......@@ -304,18 +306,26 @@ static struct clock_event_device clockevent_davinci = {
static void __init davinci_timer_init(void)
{
struct clk *timer_clk, *wd_clk;
static char err[] __initdata = KERN_ERR
"%s: can't register clocksource!\n";
/* init timer hw */
timer_init();
if (cpu_is_davinci_dm644x())
davinci_clock_tick_rate = DM646X_OSC_FREQ;
else if (cpu_is_davinci_dm646x())
davinci_clock_tick_rate = DM646X_CLOCK_TICK_RATE;
else if (cpu_is_davinci_dm355())
davinci_clock_tick_rate = DM355_CLOCK_TICK_RATE;
timer_clk = clk_get(NULL, "timer0");
BUG_ON(IS_ERR(timer_clk));
clk_enable(timer_clk);
if (cpu_is_davinci_dm644x() || cpu_is_davinci_dm355()) {
wd_clk = clk_get(NULL, "timer2");
BUG_ON(IS_ERR(wd_clk));
clk_enable(wd_clk);
}
davinci_clock_tick_rate = clk_get_rate(timer_clk);
clk_put(timer_clk);
/* setup clocksource */
clocksource_davinci.mult =
......
......@@ -401,7 +401,7 @@ static int davinci_i2s_probe(struct platform_device *pdev,
struct resource *mem, *ioarea;
struct evm_snd_platform_data *pdata;
int ret;
static const char *clocks[] = { "McBSPCLK", "McBSPCLK1", };
static const char *clocks[] = { "asp0_clk", "asp1_clk", };
if (pdev->id < 0 || pdev->id > ARRAY_SIZE(clocks))
return -EINVAL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment