mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-23 17:30:02 +00:00
Merge branch 'for_2.6.34_b' of git://git.pwsan.com/linux-2.6 into omap-for-linus
This commit is contained in:
commit
b610ec5023
54 changed files with 4622 additions and 1741 deletions
|
@ -199,7 +199,7 @@ CONFIG_ARCH_OMAP4=y
|
|||
#
|
||||
# CONFIG_OMAP_RESET_CLOCKS is not set
|
||||
# CONFIG_OMAP_MUX is not set
|
||||
# CONFIG_OMAP_MCBSP is not set
|
||||
CONFIG_OMAP_MCBSP=y
|
||||
# CONFIG_OMAP_MBOX_FWK is not set
|
||||
# CONFIG_OMAP_MPU_TIMER is not set
|
||||
CONFIG_OMAP_32K_TIMER=y
|
||||
|
@ -304,7 +304,7 @@ CONFIG_ALIGNMENT_TRAP=y
|
|||
#
|
||||
CONFIG_ZBOOT_ROM_TEXT=0x0
|
||||
CONFIG_ZBOOT_ROM_BSS=0x0
|
||||
CONFIG_CMDLINE="root=/dev/ram0 rw mem=128M console=ttyS0,115200n8 initrd=0x81600000,20M ramdisk_size=20480"
|
||||
CONFIG_CMDLINE="root=/dev/ram0 rw mem=128M console=ttyS2,115200n8 initrd=0x81600000,20M ramdisk_size=20480"
|
||||
# CONFIG_XIP_KERNEL is not set
|
||||
# CONFIG_KEXEC is not set
|
||||
|
||||
|
@ -488,7 +488,8 @@ CONFIG_GPIOLIB=y
|
|||
# CONFIG_POWER_SUPPLY is not set
|
||||
# CONFIG_HWMON is not set
|
||||
# CONFIG_THERMAL is not set
|
||||
# CONFIG_WATCHDOG is not set
|
||||
CONFIG_WATCHDOG=y
|
||||
CONFIG_OMAP_WATCHDOG=y
|
||||
CONFIG_SSB_POSSIBLE=y
|
||||
|
||||
#
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* linux/arch/arm/mach-omap1/clock.c
|
||||
*
|
||||
* Copyright (C) 2004 - 2005, 2009 Nokia corporation
|
||||
* Copyright (C) 2004 - 2005, 2009-2010 Nokia Corporation
|
||||
* Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
|
||||
*
|
||||
* Modified to use omap shared clock framework by
|
||||
|
@ -38,20 +38,6 @@ struct clk *api_ck_p, *ck_dpll1_p, *ck_ref_p;
|
|||
* Omap1 specific clock functions
|
||||
*-------------------------------------------------------------------------*/
|
||||
|
||||
static int clk_omap1_dummy_enable(struct clk *clk)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void clk_omap1_dummy_disable(struct clk *clk)
|
||||
{
|
||||
}
|
||||
|
||||
const struct clkops clkops_dummy = {
|
||||
.enable = clk_omap1_dummy_enable,
|
||||
.disable = clk_omap1_dummy_disable,
|
||||
};
|
||||
|
||||
unsigned long omap1_uart_recalc(struct clk *clk)
|
||||
{
|
||||
unsigned int val = __raw_readl(clk->enable_reg);
|
||||
|
@ -571,9 +557,6 @@ const struct clkops clkops_uart = {
|
|||
|
||||
long omap1_clk_round_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
if (clk->flags & RATE_FIXED)
|
||||
return clk->rate;
|
||||
|
||||
if (clk->round_rate != NULL)
|
||||
return clk->round_rate(clk, rate);
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* linux/arch/arm/mach-omap1/clock_data.c
|
||||
*
|
||||
* Copyright (C) 2004 - 2005, 2009 Nokia corporation
|
||||
* Copyright (C) 2004 - 2005, 2009-2010 Nokia Corporation
|
||||
* Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
|
||||
* Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, Inc
|
||||
*
|
||||
|
@ -27,13 +27,6 @@
|
|||
* Omap1 clocks
|
||||
*-------------------------------------------------------------------------*/
|
||||
|
||||
/* XXX is this necessary? */
|
||||
static struct clk dummy_ck = {
|
||||
.name = "dummy",
|
||||
.ops = &clkops_dummy,
|
||||
.flags = RATE_FIXED,
|
||||
};
|
||||
|
||||
static struct clk ck_ref = {
|
||||
.name = "ck_ref",
|
||||
.ops = &clkops_null,
|
||||
|
@ -389,8 +382,7 @@ static struct uart_clk uart1_16xx = {
|
|||
/* Direct from ULPD, no real parent */
|
||||
.parent = &armper_ck.clk,
|
||||
.rate = 48000000,
|
||||
.flags = RATE_FIXED | ENABLE_REG_32BIT |
|
||||
CLOCK_NO_IDLE_PARENT,
|
||||
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
|
||||
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
|
||||
.enable_bit = 29,
|
||||
},
|
||||
|
@ -430,8 +422,7 @@ static struct uart_clk uart3_16xx = {
|
|||
/* Direct from ULPD, no real parent */
|
||||
.parent = &armper_ck.clk,
|
||||
.rate = 48000000,
|
||||
.flags = RATE_FIXED | ENABLE_REG_32BIT |
|
||||
CLOCK_NO_IDLE_PARENT,
|
||||
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
|
||||
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
|
||||
.enable_bit = 31,
|
||||
},
|
||||
|
@ -443,7 +434,7 @@ static struct clk usb_clko = { /* 6 MHz output on W4_USB_CLKO */
|
|||
.ops = &clkops_generic,
|
||||
/* Direct from ULPD, no parent */
|
||||
.rate = 6000000,
|
||||
.flags = RATE_FIXED | ENABLE_REG_32BIT,
|
||||
.flags = ENABLE_REG_32BIT,
|
||||
.enable_reg = OMAP1_IO_ADDRESS(ULPD_CLOCK_CTRL),
|
||||
.enable_bit = USB_MCLK_EN_BIT,
|
||||
};
|
||||
|
@ -453,7 +444,7 @@ static struct clk usb_hhc_ck1510 = {
|
|||
.ops = &clkops_generic,
|
||||
/* Direct from ULPD, no parent */
|
||||
.rate = 48000000, /* Actually 2 clocks, 12MHz and 48MHz */
|
||||
.flags = RATE_FIXED | ENABLE_REG_32BIT,
|
||||
.flags = ENABLE_REG_32BIT,
|
||||
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
|
||||
.enable_bit = USB_HOST_HHC_UHOST_EN,
|
||||
};
|
||||
|
@ -464,7 +455,7 @@ static struct clk usb_hhc_ck16xx = {
|
|||
/* Direct from ULPD, no parent */
|
||||
.rate = 48000000,
|
||||
/* OTG_SYSCON_2.OTG_PADEN == 0 (not 1510-compatible) */
|
||||
.flags = RATE_FIXED | ENABLE_REG_32BIT,
|
||||
.flags = ENABLE_REG_32BIT,
|
||||
.enable_reg = OMAP1_IO_ADDRESS(OTG_BASE + 0x08), /* OTG_SYSCON_2 */
|
||||
.enable_bit = 8 /* UHOST_EN */,
|
||||
};
|
||||
|
@ -474,7 +465,6 @@ static struct clk usb_dc_ck = {
|
|||
.ops = &clkops_generic,
|
||||
/* Direct from ULPD, no parent */
|
||||
.rate = 48000000,
|
||||
.flags = RATE_FIXED,
|
||||
.enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
|
||||
.enable_bit = 4,
|
||||
};
|
||||
|
@ -484,7 +474,6 @@ static struct clk usb_dc_ck7xx = {
|
|||
.ops = &clkops_generic,
|
||||
/* Direct from ULPD, no parent */
|
||||
.rate = 48000000,
|
||||
.flags = RATE_FIXED,
|
||||
.enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
|
||||
.enable_bit = 8,
|
||||
};
|
||||
|
@ -494,7 +483,6 @@ static struct clk mclk_1510 = {
|
|||
.ops = &clkops_generic,
|
||||
/* Direct from ULPD, no parent. May be enabled by ext hardware. */
|
||||
.rate = 12000000,
|
||||
.flags = RATE_FIXED,
|
||||
.enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
|
||||
.enable_bit = 6,
|
||||
};
|
||||
|
@ -515,7 +503,6 @@ static struct clk bclk_1510 = {
|
|||
.ops = &clkops_generic,
|
||||
/* Direct from ULPD, no parent. May be enabled by ext hardware. */
|
||||
.rate = 12000000,
|
||||
.flags = RATE_FIXED,
|
||||
};
|
||||
|
||||
static struct clk bclk_16xx = {
|
||||
|
@ -530,36 +517,34 @@ static struct clk bclk_16xx = {
|
|||
};
|
||||
|
||||
static struct clk mmc1_ck = {
|
||||
.name = "mmc_ck",
|
||||
.name = "mmc1_ck",
|
||||
.ops = &clkops_generic,
|
||||
/* Functional clock is direct from ULPD, interface clock is ARMPER */
|
||||
.parent = &armper_ck.clk,
|
||||
.rate = 48000000,
|
||||
.flags = RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
|
||||
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
|
||||
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
|
||||
.enable_bit = 23,
|
||||
};
|
||||
|
||||
static struct clk mmc2_ck = {
|
||||
.name = "mmc_ck",
|
||||
.id = 1,
|
||||
.name = "mmc2_ck",
|
||||
.ops = &clkops_generic,
|
||||
/* Functional clock is direct from ULPD, interface clock is ARMPER */
|
||||
.parent = &armper_ck.clk,
|
||||
.rate = 48000000,
|
||||
.flags = RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
|
||||
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
|
||||
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
|
||||
.enable_bit = 20,
|
||||
};
|
||||
|
||||
static struct clk mmc3_ck = {
|
||||
.name = "mmc_ck",
|
||||
.id = 2,
|
||||
.name = "mmc3_ck",
|
||||
.ops = &clkops_generic,
|
||||
/* Functional clock is direct from ULPD, interface clock is ARMPER */
|
||||
.parent = &armper_ck.clk,
|
||||
.rate = 48000000,
|
||||
.flags = RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
|
||||
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
|
||||
.enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
|
||||
.enable_bit = 12,
|
||||
};
|
||||
|
@ -577,7 +562,6 @@ static struct clk virtual_ck_mpu = {
|
|||
remains active during MPU idle whenever this is enabled */
|
||||
static struct clk i2c_fck = {
|
||||
.name = "i2c_fck",
|
||||
.id = 1,
|
||||
.ops = &clkops_null,
|
||||
.flags = CLOCK_NO_IDLE_PARENT,
|
||||
.parent = &armxor_ck.clk,
|
||||
|
@ -586,7 +570,6 @@ static struct clk i2c_fck = {
|
|||
|
||||
static struct clk i2c_ick = {
|
||||
.name = "i2c_ick",
|
||||
.id = 1,
|
||||
.ops = &clkops_null,
|
||||
.flags = CLOCK_NO_IDLE_PARENT,
|
||||
.parent = &armper_ck.clk,
|
||||
|
|
|
@ -5,23 +5,17 @@
|
|||
# Common support
|
||||
obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer-gp.o
|
||||
|
||||
omap-2-3-common = irq.o sdrc.o omap_hwmod.o
|
||||
omap-3-4-common = dpll3xxx.o
|
||||
omap-2-3-common = irq.o sdrc.o
|
||||
hwmod-common = omap_hwmod.o \
|
||||
omap_hwmod_common_data.o
|
||||
prcm-common = prcm.o powerdomain.o
|
||||
clock-common = clock.o clock_common_data.o \
|
||||
clockdomain.o clkt_dpll.o \
|
||||
clkt_clksel.o
|
||||
clock-omap2xxx = clkt2xxx_dpllcore.o \
|
||||
clkt2xxx_virt_prcm_set.o \
|
||||
clkt2xxx_apll.o clkt2xxx_osc.o \
|
||||
clkt2xxx_sys.o
|
||||
clock-omap3xxx = clkt34xx_dpll3m2.o
|
||||
|
||||
obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(prcm-common) $(clock-common) \
|
||||
$(clock-omap2xxx)
|
||||
obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(prcm-common) $(clock-common) \
|
||||
$(omap-3-4-common) $(clock-omap3xxx)
|
||||
obj-$(CONFIG_ARCH_OMAP4) += $(omap-3-4-common) $(prcm-common) $(clock-common)
|
||||
obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(prcm-common) $(hwmod-common)
|
||||
obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(prcm-common) $(hwmod-common)
|
||||
obj-$(CONFIG_ARCH_OMAP4) += $(prcm-common)
|
||||
|
||||
obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
|
||||
|
||||
|
@ -63,11 +57,28 @@ obj-$(CONFIG_ARCH_OMAP3) += cm.o
|
|||
obj-$(CONFIG_ARCH_OMAP4) += cm4xxx.o
|
||||
|
||||
# Clock framework
|
||||
obj-$(CONFIG_ARCH_OMAP2) += clock2xxx.o clock2xxx_data.o
|
||||
obj-$(CONFIG_ARCH_OMAP2) += $(clock-common) clock2xxx.o \
|
||||
clkt2xxx_sys.o \
|
||||
clkt2xxx_dpllcore.o \
|
||||
clkt2xxx_virt_prcm_set.o \
|
||||
clkt2xxx_apll.o clkt2xxx_osc.o
|
||||
obj-$(CONFIG_ARCH_OMAP2420) += clock2420_data.o
|
||||
obj-$(CONFIG_ARCH_OMAP2430) += clock2430.o clock2430_data.o
|
||||
obj-$(CONFIG_ARCH_OMAP3) += $(clock-common) clock3xxx.o \
|
||||
clock34xx.o clkt34xx_dpll3m2.o \
|
||||
clock3517.o clock36xx.o \
|
||||
dpll3xxx.o clock3xxx_data.o
|
||||
obj-$(CONFIG_ARCH_OMAP4) += $(clock-common) clock44xx_data.o \
|
||||
dpll3xxx.o
|
||||
|
||||
# OMAP2 clock rate set data (old "OPP" data)
|
||||
obj-$(CONFIG_ARCH_OMAP2420) += opp2420_data.o
|
||||
obj-$(CONFIG_ARCH_OMAP3) += clock34xx.o clock34xx_data.o
|
||||
obj-$(CONFIG_ARCH_OMAP2430) += opp2430_data.o
|
||||
obj-$(CONFIG_ARCH_OMAP4) += clock44xx.o clock44xx_data.o
|
||||
|
||||
# hwmod data
|
||||
obj-$(CONFIG_ARCH_OMAP2420) += omap_hwmod_2420_data.o
|
||||
obj-$(CONFIG_ARCH_OMAP2430) += omap_hwmod_2430_data.o
|
||||
obj-$(CONFIG_ARCH_OMAP3) += omap_hwmod_3xxx_data.o
|
||||
|
||||
# EMU peripherals
|
||||
obj-$(CONFIG_OMAP3_EMU) += emu.o
|
||||
|
|
|
@ -38,6 +38,8 @@
|
|||
#define APLLS_CLKIN_13MHZ 2
|
||||
#define APLLS_CLKIN_12MHZ 3
|
||||
|
||||
void __iomem *cm_idlest_pll;
|
||||
|
||||
/* Private functions */
|
||||
|
||||
/* Enable an APLL if off */
|
||||
|
@ -56,8 +58,8 @@ static int omap2_clk_apll_enable(struct clk *clk, u32 status_mask)
|
|||
cval |= apll_mask;
|
||||
cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN);
|
||||
|
||||
omap2_cm_wait_idlest(OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), status_mask,
|
||||
clk->name);
|
||||
omap2_cm_wait_idlest(cm_idlest_pll, status_mask,
|
||||
OMAP24XX_CM_IDLEST_VAL, clk->name);
|
||||
|
||||
/*
|
||||
* REVISIT: Should we return an error code if omap2_wait_clock_ready()
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <plat/sdrc.h>
|
||||
|
||||
#include "clock.h"
|
||||
#include "clock3xxx.h"
|
||||
#include "clock34xx.h"
|
||||
#include "sdrc.h"
|
||||
|
||||
|
|
|
@ -258,10 +258,6 @@ long omap2_clk_round_rate(struct clk *clk, unsigned long rate)
|
|||
if (clk->round_rate)
|
||||
return clk->round_rate(clk, rate);
|
||||
|
||||
if (clk->flags & RATE_FIXED)
|
||||
printk(KERN_ERR "clock: generic omap2_clk_round_rate called "
|
||||
"on fixed-rate clock %s\n", clk->name);
|
||||
|
||||
return clk->rate;
|
||||
}
|
||||
|
||||
|
@ -377,8 +373,6 @@ int omap2_clksel_set_rate(struct clk *clk, unsigned long rate)
|
|||
|
||||
clk->rate = clk->parent->rate / new_div;
|
||||
|
||||
omap2xxx_clk_commit(clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -400,8 +394,6 @@ int omap2_clksel_set_parent(struct clk *clk, struct clk *new_parent)
|
|||
__raw_writel(v, clk->clksel_reg);
|
||||
v = __raw_readl(clk->clksel_reg); /* OCP barrier */
|
||||
|
||||
omap2xxx_clk_commit(clk);
|
||||
|
||||
clk_reparent(clk, new_parent);
|
||||
|
||||
/* CLKSEL clocks follow their parents' rates, divided by a divisor */
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
#include "cm-regbits-34xx.h"
|
||||
|
||||
/* DPLL rate rounding: minimum DPLL multiplier, divider values */
|
||||
#define DPLL_MIN_MULTIPLIER 1
|
||||
#define DPLL_MIN_MULTIPLIER 2
|
||||
#define DPLL_MIN_DIVIDER 1
|
||||
|
||||
/* Possible error results from _dpll_test_mult */
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* linux/arch/arm/mach-omap2/clock.c
|
||||
*
|
||||
* Copyright (C) 2005-2008 Texas Instruments, Inc.
|
||||
* Copyright (C) 2004-2008 Nokia Corporation
|
||||
* Copyright (C) 2004-2010 Nokia Corporation
|
||||
*
|
||||
* Contacts:
|
||||
* Richard Woodruff <r-woodruff2@ti.com>
|
||||
|
@ -14,11 +14,10 @@
|
|||
*/
|
||||
#undef DEBUG
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
|
@ -38,9 +37,9 @@
|
|||
|
||||
u8 cpu_mask;
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* OMAP2/3/4 specific clock functions
|
||||
*-------------------------------------------------------------------------*/
|
||||
/*
|
||||
* OMAP2+ specific clock functions
|
||||
*/
|
||||
|
||||
/* Private functions */
|
||||
|
||||
|
@ -57,7 +56,7 @@ u8 cpu_mask;
|
|||
static void _omap2_module_wait_ready(struct clk *clk)
|
||||
{
|
||||
void __iomem *companion_reg, *idlest_reg;
|
||||
u8 other_bit, idlest_bit;
|
||||
u8 other_bit, idlest_bit, idlest_val;
|
||||
|
||||
/* Not all modules have multiple clocks that their IDLEST depends on */
|
||||
if (clk->ops->find_companion) {
|
||||
|
@ -66,49 +65,14 @@ static void _omap2_module_wait_ready(struct clk *clk)
|
|||
return;
|
||||
}
|
||||
|
||||
clk->ops->find_idlest(clk, &idlest_reg, &idlest_bit);
|
||||
clk->ops->find_idlest(clk, &idlest_reg, &idlest_bit, &idlest_val);
|
||||
|
||||
omap2_cm_wait_idlest(idlest_reg, (1 << idlest_bit), clk->name);
|
||||
}
|
||||
|
||||
/* Enables clock without considering parent dependencies or use count
|
||||
* REVISIT: Maybe change this to use clk->enable like on omap1?
|
||||
*/
|
||||
static int _omap2_clk_enable(struct clk *clk)
|
||||
{
|
||||
return clk->ops->enable(clk);
|
||||
}
|
||||
|
||||
/* Disables clock without considering parent dependencies or use count */
|
||||
static void _omap2_clk_disable(struct clk *clk)
|
||||
{
|
||||
clk->ops->disable(clk);
|
||||
omap2_cm_wait_idlest(idlest_reg, (1 << idlest_bit), idlest_val,
|
||||
clk->name);
|
||||
}
|
||||
|
||||
/* Public functions */
|
||||
|
||||
/**
|
||||
* omap2xxx_clk_commit - commit clock parent/rate changes in hardware
|
||||
* @clk: struct clk *
|
||||
*
|
||||
* If @clk has the DELAYED_APP flag set, meaning that parent/rate changes
|
||||
* don't take effect until the VALID_CONFIG bit is written, write the
|
||||
* VALID_CONFIG bit and wait for the write to complete. No return value.
|
||||
*/
|
||||
void omap2xxx_clk_commit(struct clk *clk)
|
||||
{
|
||||
if (!cpu_is_omap24xx())
|
||||
return;
|
||||
|
||||
if (!(clk->flags & DELAYED_APP))
|
||||
return;
|
||||
|
||||
prm_write_mod_reg(OMAP24XX_VALID_CONFIG, OMAP24XX_GR_MOD,
|
||||
OMAP2_PRCM_CLKCFG_CTRL_OFFSET);
|
||||
/* OCP barrier */
|
||||
prm_read_mod_reg(OMAP24XX_GR_MOD, OMAP2_PRCM_CLKCFG_CTRL_OFFSET);
|
||||
}
|
||||
|
||||
/**
|
||||
* omap2_init_clk_clkdm - look up a clockdomain name, store pointer in clk
|
||||
* @clk: OMAP clock struct ptr to use
|
||||
|
@ -175,7 +139,8 @@ void omap2_clk_dflt_find_companion(struct clk *clk, void __iomem **other_reg,
|
|||
* omap2_clk_dflt_find_idlest - find CM_IDLEST reg va, bit shift for @clk
|
||||
* @clk: struct clk * to find IDLEST info for
|
||||
* @idlest_reg: void __iomem ** to return the CM_IDLEST va in
|
||||
* @idlest_bit: u8 ** to return the CM_IDLEST bit shift in
|
||||
* @idlest_bit: u8 * to return the CM_IDLEST bit shift in
|
||||
* @idlest_val: u8 * to return the idle status indicator
|
||||
*
|
||||
* Return the CM_IDLEST register address and bit shift corresponding
|
||||
* to the module that "owns" this clock. This default code assumes
|
||||
|
@ -185,13 +150,26 @@ void omap2_clk_dflt_find_companion(struct clk *clk, void __iomem **other_reg,
|
|||
* CM_IDLEST2). This is not true for all modules. No return value.
|
||||
*/
|
||||
void omap2_clk_dflt_find_idlest(struct clk *clk, void __iomem **idlest_reg,
|
||||
u8 *idlest_bit)
|
||||
u8 *idlest_bit, u8 *idlest_val)
|
||||
{
|
||||
u32 r;
|
||||
|
||||
r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20);
|
||||
*idlest_reg = (__force void __iomem *)r;
|
||||
*idlest_bit = clk->enable_bit;
|
||||
|
||||
/*
|
||||
* 24xx uses 0 to indicate not ready, and 1 to indicate ready.
|
||||
* 34xx reverses this, just to keep us on our toes
|
||||
* AM35xx uses both, depending on the module.
|
||||
*/
|
||||
if (cpu_is_omap24xx())
|
||||
*idlest_val = OMAP24XX_CM_IDLEST_VAL;
|
||||
else if (cpu_is_omap34xx())
|
||||
*idlest_val = OMAP34XX_CM_IDLEST_VAL;
|
||||
else
|
||||
BUG();
|
||||
|
||||
}
|
||||
|
||||
int omap2_dflt_clk_enable(struct clk *clk)
|
||||
|
@ -253,46 +231,106 @@ const struct clkops clkops_omap2_dflt = {
|
|||
.disable = omap2_dflt_clk_disable,
|
||||
};
|
||||
|
||||
/**
|
||||
* omap2_clk_disable - disable a clock, if the system is not using it
|
||||
* @clk: struct clk * to disable
|
||||
*
|
||||
* Decrements the usecount on struct clk @clk. If there are no users
|
||||
* left, call the clkops-specific clock disable function to disable it
|
||||
* in hardware. If the clock is part of a clockdomain (which they all
|
||||
* should be), request that the clockdomain be disabled. (It too has
|
||||
* a usecount, and so will not be disabled in the hardware until it no
|
||||
* longer has any users.) If the clock has a parent clock (most of
|
||||
* them do), then call ourselves, recursing on the parent clock. This
|
||||
* can cause an entire branch of the clock tree to be powered off by
|
||||
* simply disabling one clock. Intended to be called with the clockfw_lock
|
||||
* spinlock held. No return value.
|
||||
*/
|
||||
void omap2_clk_disable(struct clk *clk)
|
||||
{
|
||||
if (clk->usecount > 0 && !(--clk->usecount)) {
|
||||
_omap2_clk_disable(clk);
|
||||
if (clk->parent)
|
||||
omap2_clk_disable(clk->parent);
|
||||
if (clk->usecount == 0) {
|
||||
WARN(1, "clock: %s: omap2_clk_disable() called, but usecount "
|
||||
"already 0?", clk->name);
|
||||
return;
|
||||
}
|
||||
|
||||
pr_debug("clock: %s: decrementing usecount\n", clk->name);
|
||||
|
||||
clk->usecount--;
|
||||
|
||||
if (clk->usecount > 0)
|
||||
return;
|
||||
|
||||
pr_debug("clock: %s: disabling in hardware\n", clk->name);
|
||||
|
||||
clk->ops->disable(clk);
|
||||
|
||||
if (clk->clkdm)
|
||||
omap2_clkdm_clk_disable(clk->clkdm, clk);
|
||||
|
||||
}
|
||||
if (clk->parent)
|
||||
omap2_clk_disable(clk->parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* omap2_clk_enable - request that the system enable a clock
|
||||
* @clk: struct clk * to enable
|
||||
*
|
||||
* Increments the usecount on struct clk @clk. If there were no users
|
||||
* previously, then recurse up the clock tree, enabling all of the
|
||||
* clock's parents and all of the parent clockdomains, and finally,
|
||||
* enabling @clk's clockdomain, and @clk itself. Intended to be
|
||||
* called with the clockfw_lock spinlock held. Returns 0 upon success
|
||||
* or a negative error code upon failure.
|
||||
*/
|
||||
int omap2_clk_enable(struct clk *clk)
|
||||
{
|
||||
int ret = 0;
|
||||
int ret;
|
||||
|
||||
if (clk->usecount++ == 0) {
|
||||
if (clk->clkdm)
|
||||
omap2_clkdm_clk_enable(clk->clkdm, clk);
|
||||
pr_debug("clock: %s: incrementing usecount\n", clk->name);
|
||||
|
||||
clk->usecount++;
|
||||
|
||||
if (clk->usecount > 1)
|
||||
return 0;
|
||||
|
||||
pr_debug("clock: %s: enabling in hardware\n", clk->name);
|
||||
|
||||
if (clk->parent) {
|
||||
ret = omap2_clk_enable(clk->parent);
|
||||
if (ret)
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = _omap2_clk_enable(clk);
|
||||
if (ret) {
|
||||
if (clk->parent)
|
||||
omap2_clk_disable(clk->parent);
|
||||
|
||||
goto err;
|
||||
WARN(1, "clock: %s: could not enable parent %s: %d\n",
|
||||
clk->name, clk->parent->name, ret);
|
||||
goto oce_err1;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
||||
err:
|
||||
if (clk->clkdm) {
|
||||
ret = omap2_clkdm_clk_enable(clk->clkdm, clk);
|
||||
if (ret) {
|
||||
WARN(1, "clock: %s: could not enable clockdomain %s: "
|
||||
"%d\n", clk->name, clk->clkdm->name, ret);
|
||||
goto oce_err2;
|
||||
}
|
||||
}
|
||||
|
||||
ret = clk->ops->enable(clk);
|
||||
if (ret) {
|
||||
WARN(1, "clock: %s: could not enable: %d\n", clk->name, ret);
|
||||
goto oce_err3;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
oce_err3:
|
||||
if (clk->clkdm)
|
||||
omap2_clkdm_clk_disable(clk->clkdm, clk);
|
||||
oce_err2:
|
||||
if (clk->parent)
|
||||
omap2_clk_disable(clk->parent);
|
||||
oce_err1:
|
||||
clk->usecount--;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -303,11 +341,6 @@ int omap2_clk_set_rate(struct clk *clk, unsigned long rate)
|
|||
|
||||
pr_debug("clock: set_rate for clock %s to rate %ld\n", clk->name, rate);
|
||||
|
||||
/* CONFIG_PARTICIPANT clocks are changed only in sets via the
|
||||
rate table mechanism, driven by mpu_speed */
|
||||
if (clk->flags & CONFIG_PARTICIPANT)
|
||||
return -EINVAL;
|
||||
|
||||
/* dpll_ck, core_ck, virt_prcm_set; plus all clksel clocks */
|
||||
if (clk->set_rate)
|
||||
ret = clk->set_rate(clk, rate);
|
||||
|
@ -317,18 +350,30 @@ int omap2_clk_set_rate(struct clk *clk, unsigned long rate)
|
|||
|
||||
int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
|
||||
{
|
||||
if (clk->flags & CONFIG_PARTICIPANT)
|
||||
return -EINVAL;
|
||||
|
||||
if (!clk->clksel)
|
||||
return -EINVAL;
|
||||
|
||||
if (clk->parent == new_parent)
|
||||
return 0;
|
||||
|
||||
return omap2_clksel_set_parent(clk, new_parent);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Omap2 clock reset and init functions
|
||||
*-------------------------------------------------------------------------*/
|
||||
/* OMAP3/4 non-CORE DPLL clkops */
|
||||
|
||||
#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
|
||||
|
||||
const struct clkops clkops_omap3_noncore_dpll_ops = {
|
||||
.enable = omap3_noncore_dpll_enable,
|
||||
.disable = omap3_noncore_dpll_disable,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* OMAP2+ clock reset and init functions
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_OMAP_RESET_CLOCKS
|
||||
void omap2_clk_disable_unused(struct clk *clk)
|
||||
|
@ -345,13 +390,97 @@ void omap2_clk_disable_unused(struct clk *clk)
|
|||
if (cpu_is_omap34xx()) {
|
||||
omap2_clk_enable(clk);
|
||||
omap2_clk_disable(clk);
|
||||
} else
|
||||
_omap2_clk_disable(clk);
|
||||
} else {
|
||||
clk->ops->disable(clk);
|
||||
}
|
||||
if (clk->clkdm != NULL)
|
||||
pwrdm_clkdm_state_switch(clk->clkdm);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* omap2_clk_switch_mpurate_at_boot - switch ARM MPU rate by boot-time argument
|
||||
* @mpurate_ck_name: clk name of the clock to change rate
|
||||
*
|
||||
* Change the ARM MPU clock rate to the rate specified on the command
|
||||
* line, if one was specified. @mpurate_ck_name should be
|
||||
* "virt_prcm_set" on OMAP2xxx and "dpll1_ck" on OMAP34xx/OMAP36xx.
|
||||
* XXX Does not handle voltage scaling - on OMAP2xxx this is currently
|
||||
* handled by the virt_prcm_set clock, but this should be handled by
|
||||
* the OPP layer. XXX This is intended to be handled by the OPP layer
|
||||
* code in the near future and should be removed from the clock code.
|
||||
* Returns -EINVAL if 'mpurate' is zero or if clk_set_rate() rejects
|
||||
* the rate, -ENOENT if the struct clk referred to by @mpurate_ck_name
|
||||
* cannot be found, or 0 upon success.
|
||||
*/
|
||||
int __init omap2_clk_switch_mpurate_at_boot(const char *mpurate_ck_name)
|
||||
{
|
||||
struct clk *mpurate_ck;
|
||||
int r;
|
||||
|
||||
if (!mpurate)
|
||||
return -EINVAL;
|
||||
|
||||
mpurate_ck = clk_get(NULL, mpurate_ck_name);
|
||||
if (WARN(IS_ERR(mpurate_ck), "Failed to get %s.\n", mpurate_ck_name))
|
||||
return -ENOENT;
|
||||
|
||||
r = clk_set_rate(mpurate_ck, mpurate);
|
||||
if (IS_ERR_VALUE(r)) {
|
||||
WARN(1, "clock: %s: unable to set MPU rate to %d: %d\n",
|
||||
mpurate_ck->name, mpurate, r);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
calibrate_delay();
|
||||
recalculate_root_clocks();
|
||||
|
||||
clk_put(mpurate_ck);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* omap2_clk_print_new_rates - print summary of current clock tree rates
|
||||
* @hfclkin_ck_name: clk name for the off-chip HF oscillator
|
||||
* @core_ck_name: clk name for the on-chip CORE_CLK
|
||||
* @mpu_ck_name: clk name for the ARM MPU clock
|
||||
*
|
||||
* Prints a short message to the console with the HFCLKIN oscillator
|
||||
* rate, the rate of the CORE clock, and the rate of the ARM MPU clock.
|
||||
* Called by the boot-time MPU rate switching code. XXX This is intended
|
||||
* to be handled by the OPP layer code in the near future and should be
|
||||
* removed from the clock code. No return value.
|
||||
*/
|
||||
void __init omap2_clk_print_new_rates(const char *hfclkin_ck_name,
|
||||
const char *core_ck_name,
|
||||
const char *mpu_ck_name)
|
||||
{
|
||||
struct clk *hfclkin_ck, *core_ck, *mpu_ck;
|
||||
unsigned long hfclkin_rate;
|
||||
|
||||
mpu_ck = clk_get(NULL, mpu_ck_name);
|
||||
if (WARN(IS_ERR(mpu_ck), "clock: failed to get %s.\n", mpu_ck_name))
|
||||
return;
|
||||
|
||||
core_ck = clk_get(NULL, core_ck_name);
|
||||
if (WARN(IS_ERR(core_ck), "clock: failed to get %s.\n", core_ck_name))
|
||||
return;
|
||||
|
||||
hfclkin_ck = clk_get(NULL, hfclkin_ck_name);
|
||||
if (WARN(IS_ERR(hfclkin_ck), "Failed to get %s.\n", hfclkin_ck_name))
|
||||
return;
|
||||
|
||||
hfclkin_rate = clk_get_rate(hfclkin_ck);
|
||||
|
||||
pr_info("Switched to new clocking rate (Crystal/Core/MPU): "
|
||||
"%ld.%01ld/%ld/%ld MHz\n",
|
||||
(hfclkin_rate / 1000000),
|
||||
((hfclkin_rate / 100000) % 10),
|
||||
(clk_get_rate(core_ck) / 1000000),
|
||||
(clk_get_rate(mpu_ck) / 1000000));
|
||||
}
|
||||
|
||||
/* Common data */
|
||||
|
||||
struct clk_functions omap2_clk_functions = {
|
||||
|
|
|
@ -47,6 +47,10 @@
|
|||
#define DPLL_LOW_POWER_BYPASS 0x5
|
||||
#define DPLL_LOCKED 0x7
|
||||
|
||||
/* DPLL Type and DCO Selection Flags */
|
||||
#define DPLL_J_TYPE 0x1
|
||||
#define DPLL_NO_DCO_SEL 0x2
|
||||
|
||||
int omap2_clk_enable(struct clk *clk);
|
||||
void omap2_clk_disable(struct clk *clk);
|
||||
long omap2_clk_round_rate(struct clk *clk, unsigned long rate);
|
||||
|
@ -114,12 +118,16 @@ void omap2_dflt_clk_disable(struct clk *clk);
|
|||
void omap2_clk_dflt_find_companion(struct clk *clk, void __iomem **other_reg,
|
||||
u8 *other_bit);
|
||||
void omap2_clk_dflt_find_idlest(struct clk *clk, void __iomem **idlest_reg,
|
||||
u8 *idlest_bit);
|
||||
void omap2xxx_clk_commit(struct clk *clk);
|
||||
u8 *idlest_bit, u8 *idlest_val);
|
||||
int omap2_clk_switch_mpurate_at_boot(const char *mpurate_ck_name);
|
||||
void omap2_clk_print_new_rates(const char *hfclkin_ck_name,
|
||||
const char *core_ck_name,
|
||||
const char *mpu_ck_name);
|
||||
|
||||
extern u8 cpu_mask;
|
||||
|
||||
extern const struct clkops clkops_omap2_dflt_wait;
|
||||
extern const struct clkops clkops_dummy;
|
||||
extern const struct clkops clkops_omap2_dflt;
|
||||
|
||||
extern struct clk_functions omap2_clk_functions;
|
||||
|
@ -137,4 +145,6 @@ extern void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table)
|
|||
#define omap2_clk_exit_cpufreq_table 0
|
||||
#endif
|
||||
|
||||
extern const struct clkops clkops_omap3_noncore_dpll_ops;
|
||||
|
||||
#endif
|
||||
|
|
1910
arch/arm/mach-omap2/clock2420_data.c
Normal file
1910
arch/arm/mach-omap2/clock2420_data.c
Normal file
File diff suppressed because it is too large
Load diff
59
arch/arm/mach-omap2/clock2430.c
Normal file
59
arch/arm/mach-omap2/clock2430.c
Normal file
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* clock2430.c - OMAP2430-specific clock integration code
|
||||
*
|
||||
* Copyright (C) 2005-2008 Texas Instruments, Inc.
|
||||
* Copyright (C) 2004-2010 Nokia Corporation
|
||||
*
|
||||
* Contacts:
|
||||
* Richard Woodruff <r-woodruff2@ti.com>
|
||||
* Paul Walmsley
|
||||
*
|
||||
* Based on earlier work by Tuukka Tikkanen, Tony Lindgren,
|
||||
* Gordon McNutt and RidgeRun, Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#undef DEBUG
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <plat/clock.h>
|
||||
|
||||
#include "clock.h"
|
||||
#include "clock2xxx.h"
|
||||
#include "cm.h"
|
||||
#include "cm-regbits-24xx.h"
|
||||
|
||||
/**
|
||||
* omap2430_clk_i2chs_find_idlest - return CM_IDLEST info for 2430 I2CHS
|
||||
* @clk: struct clk * being enabled
|
||||
* @idlest_reg: void __iomem ** to store CM_IDLEST reg address into
|
||||
* @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into
|
||||
* @idlest_val: pointer to a u8 to store the CM_IDLEST indicator
|
||||
*
|
||||
* OMAP2430 I2CHS CM_IDLEST bits are in CM_IDLEST1_CORE, but the
|
||||
* CM_*CLKEN bits are in CM_{I,F}CLKEN2_CORE. This custom function
|
||||
* passes back the correct CM_IDLEST register address for I2CHS
|
||||
* modules. No return value.
|
||||
*/
|
||||
static void omap2430_clk_i2chs_find_idlest(struct clk *clk,
|
||||
void __iomem **idlest_reg,
|
||||
u8 *idlest_bit,
|
||||
u8 *idlest_val)
|
||||
{
|
||||
*idlest_reg = OMAP2430_CM_REGADDR(CORE_MOD, CM_IDLEST);
|
||||
*idlest_bit = clk->enable_bit;
|
||||
*idlest_val = OMAP24XX_CM_IDLEST_VAL;
|
||||
}
|
||||
|
||||
/* 2430 I2CHS has non-standard IDLEST register */
|
||||
const struct clkops clkops_omap2430_i2chs_wait = {
|
||||
.enable = omap2_dflt_clk_enable,
|
||||
.disable = omap2_dflt_clk_disable,
|
||||
.find_idlest = omap2430_clk_i2chs_find_idlest,
|
||||
.find_companion = omap2_clk_dflt_find_companion,
|
||||
};
|
File diff suppressed because it is too large
Load diff
|
@ -35,39 +35,6 @@ struct clk *vclk, *sclk, *dclk;
|
|||
* Omap24xx specific clock functions
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP2430
|
||||
|
||||
/**
|
||||
* omap2430_clk_i2chs_find_idlest - return CM_IDLEST info for 2430 I2CHS
|
||||
* @clk: struct clk * being enabled
|
||||
* @idlest_reg: void __iomem ** to store CM_IDLEST reg address into
|
||||
* @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into
|
||||
*
|
||||
* OMAP2430 I2CHS CM_IDLEST bits are in CM_IDLEST1_CORE, but the
|
||||
* CM_*CLKEN bits are in CM_{I,F}CLKEN2_CORE. This custom function
|
||||
* passes back the correct CM_IDLEST register address for I2CHS
|
||||
* modules. No return value.
|
||||
*/
|
||||
static void omap2430_clk_i2chs_find_idlest(struct clk *clk,
|
||||
void __iomem **idlest_reg,
|
||||
u8 *idlest_bit)
|
||||
{
|
||||
*idlest_reg = OMAP_CM_REGADDR(CORE_MOD, CM_IDLEST);
|
||||
*idlest_bit = clk->enable_bit;
|
||||
}
|
||||
|
||||
#else
|
||||
#define omap2430_clk_i2chs_find_idlest NULL
|
||||
#endif
|
||||
|
||||
/* 2430 I2CHS has non-standard IDLEST register */
|
||||
const struct clkops clkops_omap2430_i2chs_wait = {
|
||||
.enable = omap2_dflt_clk_enable,
|
||||
.disable = omap2_dflt_clk_disable,
|
||||
.find_idlest = omap2430_clk_i2chs_find_idlest,
|
||||
.find_companion = omap2_clk_dflt_find_companion,
|
||||
};
|
||||
|
||||
/*
|
||||
* Set clocks for bypass mode for reboot to work.
|
||||
*/
|
||||
|
@ -83,40 +50,24 @@ void omap2xxx_clk_prepare_for_reboot(void)
|
|||
}
|
||||
|
||||
/*
|
||||
* Switch the MPU rate if specified on cmdline.
|
||||
* We cannot do this early until cmdline is parsed.
|
||||
* Switch the MPU rate if specified on cmdline. We cannot do this
|
||||
* early until cmdline is parsed. XXX This should be removed from the
|
||||
* clock code and handled by the OPP layer code in the near future.
|
||||
*/
|
||||
static int __init omap2xxx_clk_arch_init(void)
|
||||
{
|
||||
struct clk *virt_prcm_set, *sys_ck, *dpll_ck, *mpu_ck;
|
||||
unsigned long sys_ck_rate;
|
||||
int ret;
|
||||
|
||||
if (!cpu_is_omap24xx())
|
||||
return 0;
|
||||
|
||||
if (!mpurate)
|
||||
return -EINVAL;
|
||||
ret = omap2_clk_switch_mpurate_at_boot("virt_prcm_set");
|
||||
if (!ret)
|
||||
omap2_clk_print_new_rates("sys_ck", "dpll_ck", "mpu_ck");
|
||||
|
||||
virt_prcm_set = clk_get(NULL, "virt_prcm_set");
|
||||
sys_ck = clk_get(NULL, "sys_ck");
|
||||
dpll_ck = clk_get(NULL, "dpll_ck");
|
||||
mpu_ck = clk_get(NULL, "mpu_ck");
|
||||
|
||||
if (clk_set_rate(virt_prcm_set, mpurate))
|
||||
printk(KERN_ERR "Could not find matching MPU rate\n");
|
||||
|
||||
recalculate_root_clocks();
|
||||
|
||||
sys_ck_rate = clk_get_rate(sys_ck);
|
||||
|
||||
pr_info("Switched to new clocking rate (Crystal/DPLL/MPU): "
|
||||
"%ld.%01ld/%ld/%ld MHz\n",
|
||||
(sys_ck_rate / 1000000), (sys_ck_rate / 100000) % 10,
|
||||
(clk_get_rate(dpll_ck) / 1000000),
|
||||
(clk_get_rate(mpu_ck) / 1000000));
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
arch_initcall(omap2xxx_clk_arch_init);
|
||||
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
/*
|
||||
* OMAP2 clock function prototypes and macros
|
||||
*
|
||||
* Copyright (C) 2005-2009 Texas Instruments, Inc.
|
||||
* Copyright (C) 2004-2009 Nokia Corporation
|
||||
* Copyright (C) 2005-2010 Texas Instruments, Inc.
|
||||
* Copyright (C) 2004-2010 Nokia Corporation
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK_24XX_H
|
||||
#define __ARCH_ARM_MACH_OMAP2_CLOCK_24XX_H
|
||||
#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK2XXX_H
|
||||
#define __ARCH_ARM_MACH_OMAP2_CLOCK2XXX_H
|
||||
|
||||
unsigned long omap2_table_mpu_recalc(struct clk *clk);
|
||||
int omap2_select_table_rate(struct clk *clk, unsigned long rate);
|
||||
|
@ -19,20 +19,20 @@ unsigned long omap2xxx_clk_get_core_rate(struct clk *clk);
|
|||
u32 omap2xxx_get_apll_clkin(void);
|
||||
u32 omap2xxx_get_sysclkdiv(void);
|
||||
void omap2xxx_clk_prepare_for_reboot(void);
|
||||
int omap2xxx_clk_init(void);
|
||||
|
||||
/* REVISIT: These should be set dynamically for CONFIG_MULTI_OMAP2 */
|
||||
#ifdef CONFIG_ARCH_OMAP2420
|
||||
#define OMAP_CM_REGADDR OMAP2420_CM_REGADDR
|
||||
#define OMAP24XX_PRCM_CLKOUT_CTRL OMAP2420_PRCM_CLKOUT_CTRL
|
||||
#define OMAP24XX_PRCM_CLKEMUL_CTRL OMAP2420_PRCM_CLKEMUL_CTRL
|
||||
int omap2420_clk_init(void);
|
||||
#else
|
||||
#define OMAP_CM_REGADDR OMAP2430_CM_REGADDR
|
||||
#define OMAP24XX_PRCM_CLKOUT_CTRL OMAP2430_PRCM_CLKOUT_CTRL
|
||||
#define OMAP24XX_PRCM_CLKEMUL_CTRL OMAP2430_PRCM_CLKEMUL_CTRL
|
||||
#define omap2420_clk_init() 0
|
||||
#endif
|
||||
|
||||
extern void __iomem *prcm_clksrc_ctrl;
|
||||
#ifdef CONFIG_ARCH_OMAP2430
|
||||
int omap2430_clk_init(void);
|
||||
#else
|
||||
#define omap2430_clk_init() 0
|
||||
#endif
|
||||
|
||||
extern void __iomem *prcm_clksrc_ctrl, *cm_idlest_pll;
|
||||
|
||||
extern struct clk *dclk;
|
||||
|
||||
|
|
|
@ -8,7 +8,8 @@
|
|||
* Jouni Högander
|
||||
*
|
||||
* Parts of this code are based on code written by
|
||||
* Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu
|
||||
* Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu,
|
||||
* Russell King
|
||||
*
|
||||
* 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
|
||||
|
@ -17,36 +18,22 @@
|
|||
#undef DEBUG
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <plat/cpu.h>
|
||||
#include <plat/clock.h>
|
||||
|
||||
#include "clock.h"
|
||||
#include "clock34xx.h"
|
||||
#include "prm.h"
|
||||
#include "prm-regbits-34xx.h"
|
||||
#include "cm.h"
|
||||
#include "cm-regbits-34xx.h"
|
||||
|
||||
/*
|
||||
* DPLL5_FREQ_FOR_USBHOST: USBHOST and USBTLL are the only clocks
|
||||
* that are sourced by DPLL5, and both of these require this clock
|
||||
* to be at 120 MHz for proper operation.
|
||||
*/
|
||||
#define DPLL5_FREQ_FOR_USBHOST 120000000
|
||||
|
||||
/* needed by omap3_core_dpll_m2_set_rate() */
|
||||
struct clk *sdrc_ick_p, *arm_fck_p;
|
||||
|
||||
/**
|
||||
* omap3430es2_clk_ssi_find_idlest - return CM_IDLEST info for SSI
|
||||
* @clk: struct clk * being enabled
|
||||
* @idlest_reg: void __iomem ** to store CM_IDLEST reg address into
|
||||
* @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into
|
||||
* @idlest_val: pointer to a u8 to store the CM_IDLEST indicator
|
||||
*
|
||||
* The OMAP3430ES2 SSI target CM_IDLEST bit is at a different shift
|
||||
* from the CM_{I,F}CLKEN bit. Pass back the correct info via
|
||||
|
@ -54,13 +41,15 @@ struct clk *sdrc_ick_p, *arm_fck_p;
|
|||
*/
|
||||
static void omap3430es2_clk_ssi_find_idlest(struct clk *clk,
|
||||
void __iomem **idlest_reg,
|
||||
u8 *idlest_bit)
|
||||
u8 *idlest_bit,
|
||||
u8 *idlest_val)
|
||||
{
|
||||
u32 r;
|
||||
|
||||
r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20);
|
||||
*idlest_reg = (__force void __iomem *)r;
|
||||
*idlest_bit = OMAP3430ES2_ST_SSI_IDLE_SHIFT;
|
||||
*idlest_val = OMAP34XX_CM_IDLEST_VAL;
|
||||
}
|
||||
|
||||
const struct clkops clkops_omap3430es2_ssi_wait = {
|
||||
|
@ -75,6 +64,7 @@ const struct clkops clkops_omap3430es2_ssi_wait = {
|
|||
* @clk: struct clk * being enabled
|
||||
* @idlest_reg: void __iomem ** to store CM_IDLEST reg address into
|
||||
* @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into
|
||||
* @idlest_val: pointer to a u8 to store the CM_IDLEST indicator
|
||||
*
|
||||
* Some OMAP modules on OMAP3 ES2+ chips have both initiator and
|
||||
* target IDLEST bits. For our purposes, we are concerned with the
|
||||
|
@ -85,7 +75,8 @@ const struct clkops clkops_omap3430es2_ssi_wait = {
|
|||
*/
|
||||
static void omap3430es2_clk_dss_usbhost_find_idlest(struct clk *clk,
|
||||
void __iomem **idlest_reg,
|
||||
u8 *idlest_bit)
|
||||
u8 *idlest_bit,
|
||||
u8 *idlest_val)
|
||||
{
|
||||
u32 r;
|
||||
|
||||
|
@ -93,6 +84,7 @@ static void omap3430es2_clk_dss_usbhost_find_idlest(struct clk *clk,
|
|||
*idlest_reg = (__force void __iomem *)r;
|
||||
/* USBHOST_IDLE has same shift */
|
||||
*idlest_bit = OMAP3430ES2_ST_DSS_IDLE_SHIFT;
|
||||
*idlest_val = OMAP34XX_CM_IDLEST_VAL;
|
||||
}
|
||||
|
||||
const struct clkops clkops_omap3430es2_dss_usbhost_wait = {
|
||||
|
@ -107,6 +99,7 @@ const struct clkops clkops_omap3430es2_dss_usbhost_wait = {
|
|||
* @clk: struct clk * being enabled
|
||||
* @idlest_reg: void __iomem ** to store CM_IDLEST reg address into
|
||||
* @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into
|
||||
* @idlest_val: pointer to a u8 to store the CM_IDLEST indicator
|
||||
*
|
||||
* The OMAP3430ES2 HSOTGUSB target CM_IDLEST bit is at a different
|
||||
* shift from the CM_{I,F}CLKEN bit. Pass back the correct info via
|
||||
|
@ -114,13 +107,15 @@ const struct clkops clkops_omap3430es2_dss_usbhost_wait = {
|
|||
*/
|
||||
static void omap3430es2_clk_hsotgusb_find_idlest(struct clk *clk,
|
||||
void __iomem **idlest_reg,
|
||||
u8 *idlest_bit)
|
||||
u8 *idlest_bit,
|
||||
u8 *idlest_val)
|
||||
{
|
||||
u32 r;
|
||||
|
||||
r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20);
|
||||
*idlest_reg = (__force void __iomem *)r;
|
||||
*idlest_bit = OMAP3430ES2_ST_HSOTGUSB_IDLE_SHIFT;
|
||||
*idlest_val = OMAP34XX_CM_IDLEST_VAL;
|
||||
}
|
||||
|
||||
const struct clkops clkops_omap3430es2_hsotgusb_wait = {
|
||||
|
@ -129,93 +124,3 @@ const struct clkops clkops_omap3430es2_hsotgusb_wait = {
|
|||
.find_idlest = omap3430es2_clk_hsotgusb_find_idlest,
|
||||
.find_companion = omap2_clk_dflt_find_companion,
|
||||
};
|
||||
|
||||
const struct clkops omap3_clkops_noncore_dpll_ops = {
|
||||
.enable = omap3_noncore_dpll_enable,
|
||||
.disable = omap3_noncore_dpll_disable,
|
||||
};
|
||||
|
||||
int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
/*
|
||||
* According to the 12-5 CDP code from TI, "Limitation 2.5"
|
||||
* on 3430ES1 prevents us from changing DPLL multipliers or dividers
|
||||
* on DPLL4.
|
||||
*/
|
||||
if (omap_rev() == OMAP3430_REV_ES1_0) {
|
||||
printk(KERN_ERR "clock: DPLL4 cannot change rate due to "
|
||||
"silicon 'Limitation 2.5' on 3430ES1.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
return omap3_noncore_dpll_set_rate(clk, rate);
|
||||
}
|
||||
|
||||
void __init omap3_clk_lock_dpll5(void)
|
||||
{
|
||||
struct clk *dpll5_clk;
|
||||
struct clk *dpll5_m2_clk;
|
||||
|
||||
dpll5_clk = clk_get(NULL, "dpll5_ck");
|
||||
clk_set_rate(dpll5_clk, DPLL5_FREQ_FOR_USBHOST);
|
||||
clk_enable(dpll5_clk);
|
||||
|
||||
/* Enable autoidle to allow it to enter low power bypass */
|
||||
omap3_dpll_allow_idle(dpll5_clk);
|
||||
|
||||
/* Program dpll5_m2_clk divider for no division */
|
||||
dpll5_m2_clk = clk_get(NULL, "dpll5_m2_ck");
|
||||
clk_enable(dpll5_m2_clk);
|
||||
clk_set_rate(dpll5_m2_clk, DPLL5_FREQ_FOR_USBHOST);
|
||||
|
||||
clk_disable(dpll5_m2_clk);
|
||||
clk_disable(dpll5_clk);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Common clock code */
|
||||
|
||||
/* REVISIT: Move this init stuff out into clock.c */
|
||||
|
||||
/*
|
||||
* Switch the MPU rate if specified on cmdline.
|
||||
* We cannot do this early until cmdline is parsed.
|
||||
*/
|
||||
static int __init omap3xxx_clk_arch_init(void)
|
||||
{
|
||||
struct clk *osc_sys_ck, *dpll1_ck, *arm_fck, *core_ck;
|
||||
unsigned long osc_sys_rate;
|
||||
|
||||
if (!cpu_is_omap34xx())
|
||||
return 0;
|
||||
|
||||
if (!mpurate)
|
||||
return -EINVAL;
|
||||
|
||||
/* XXX test these for success */
|
||||
dpll1_ck = clk_get(NULL, "dpll1_ck");
|
||||
arm_fck = clk_get(NULL, "arm_fck");
|
||||
core_ck = clk_get(NULL, "core_ck");
|
||||
osc_sys_ck = clk_get(NULL, "osc_sys_ck");
|
||||
|
||||
/* REVISIT: not yet ready for 343x */
|
||||
if (clk_set_rate(dpll1_ck, mpurate))
|
||||
printk(KERN_ERR "*** Unable to set MPU rate\n");
|
||||
|
||||
recalculate_root_clocks();
|
||||
|
||||
osc_sys_rate = clk_get_rate(osc_sys_ck);
|
||||
|
||||
pr_info("Switched to new clocking rate (Crystal/Core/MPU): "
|
||||
"%ld.%01ld/%ld/%ld MHz\n",
|
||||
(osc_sys_rate / 1000000),
|
||||
((osc_sys_rate / 100000) % 10),
|
||||
(clk_get_rate(core_ck) / 1000000),
|
||||
(clk_get_rate(arm_fck) / 1000000));
|
||||
|
||||
calibrate_delay();
|
||||
|
||||
return 0;
|
||||
}
|
||||
arch_initcall(omap3xxx_clk_arch_init);
|
||||
|
||||
|
||||
|
|
|
@ -1,25 +1,15 @@
|
|||
/*
|
||||
* OMAP3 clock function prototypes and macros
|
||||
* OMAP34xx clock function prototypes and macros
|
||||
*
|
||||
* Copyright (C) 2007-2009 Texas Instruments, Inc.
|
||||
* Copyright (C) 2007-2009 Nokia Corporation
|
||||
* Copyright (C) 2007-2010 Texas Instruments, Inc.
|
||||
* Copyright (C) 2007-2010 Nokia Corporation
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK_34XX_H
|
||||
#define __ARCH_ARM_MACH_OMAP2_CLOCK_34XX_H
|
||||
#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK34XX_H
|
||||
#define __ARCH_ARM_MACH_OMAP2_CLOCK34XX_H
|
||||
|
||||
int omap3xxx_clk_init(void);
|
||||
int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate);
|
||||
int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate);
|
||||
void omap3_clk_lock_dpll5(void);
|
||||
|
||||
extern struct clk *sdrc_ick_p;
|
||||
extern struct clk *arm_fck_p;
|
||||
|
||||
/* OMAP34xx-specific clkops */
|
||||
extern const struct clkops clkops_omap3430es2_ssi_wait;
|
||||
extern const struct clkops clkops_omap3430es2_hsotgusb_wait;
|
||||
extern const struct clkops clkops_omap3430es2_dss_usbhost_wait;
|
||||
extern const struct clkops omap3_clkops_noncore_dpll_ops;
|
||||
|
||||
#endif
|
||||
|
|
124
arch/arm/mach-omap2/clock3517.c
Normal file
124
arch/arm/mach-omap2/clock3517.c
Normal file
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* OMAP3517/3505-specific clock framework functions
|
||||
*
|
||||
* Copyright (C) 2010 Texas Instruments, Inc.
|
||||
* Copyright (C) 2010 Nokia Corporation
|
||||
*
|
||||
* Ranjith Lohithakshan
|
||||
* Paul Walmsley
|
||||
*
|
||||
* Parts of this code are based on code written by
|
||||
* Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu,
|
||||
* Russell King
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#undef DEBUG
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <plat/clock.h>
|
||||
|
||||
#include "clock.h"
|
||||
#include "clock3517.h"
|
||||
#include "cm.h"
|
||||
#include "cm-regbits-34xx.h"
|
||||
|
||||
/*
|
||||
* In AM35xx IPSS, the {ICK,FCK} enable bits for modules are exported
|
||||
* in the same register at a bit offset of 0x8. The EN_ACK for ICK is
|
||||
* at an offset of 4 from ICK enable bit.
|
||||
*/
|
||||
#define AM35XX_IPSS_ICK_MASK 0xF
|
||||
#define AM35XX_IPSS_ICK_EN_ACK_OFFSET 0x4
|
||||
#define AM35XX_IPSS_ICK_FCK_OFFSET 0x8
|
||||
#define AM35XX_IPSS_CLK_IDLEST_VAL 0
|
||||
|
||||
/**
|
||||
* am35xx_clk_find_idlest - return clock ACK info for AM35XX IPSS
|
||||
* @clk: struct clk * being enabled
|
||||
* @idlest_reg: void __iomem ** to store CM_IDLEST reg address into
|
||||
* @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into
|
||||
* @idlest_val: pointer to a u8 to store the CM_IDLEST indicator
|
||||
*
|
||||
* The interface clocks on AM35xx IPSS reflects the clock idle status
|
||||
* in the enable register itsel at a bit offset of 4 from the enable
|
||||
* bit. A value of 1 indicates that clock is enabled.
|
||||
*/
|
||||
static void am35xx_clk_find_idlest(struct clk *clk,
|
||||
void __iomem **idlest_reg,
|
||||
u8 *idlest_bit,
|
||||
u8 *idlest_val)
|
||||
{
|
||||
*idlest_reg = (__force void __iomem *)(clk->enable_reg);
|
||||
*idlest_bit = clk->enable_bit + AM35XX_IPSS_ICK_EN_ACK_OFFSET;
|
||||
*idlest_val = AM35XX_IPSS_CLK_IDLEST_VAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* am35xx_clk_find_companion - find companion clock to @clk
|
||||
* @clk: struct clk * to find the companion clock of
|
||||
* @other_reg: void __iomem ** to return the companion clock CM_*CLKEN va in
|
||||
* @other_bit: u8 ** to return the companion clock bit shift in
|
||||
*
|
||||
* Some clocks don't have companion clocks. For example, modules with
|
||||
* only an interface clock (such as HECC) don't have a companion
|
||||
* clock. Right now, this code relies on the hardware exporting a bit
|
||||
* in the correct companion register that indicates that the
|
||||
* nonexistent 'companion clock' is active. Future patches will
|
||||
* associate this type of code with per-module data structures to
|
||||
* avoid this issue, and remove the casts. No return value.
|
||||
*/
|
||||
static void am35xx_clk_find_companion(struct clk *clk, void __iomem **other_reg,
|
||||
u8 *other_bit)
|
||||
{
|
||||
*other_reg = (__force void __iomem *)(clk->enable_reg);
|
||||
if (clk->enable_bit & AM35XX_IPSS_ICK_MASK)
|
||||
*other_bit = clk->enable_bit + AM35XX_IPSS_ICK_FCK_OFFSET;
|
||||
else
|
||||
*other_bit = clk->enable_bit - AM35XX_IPSS_ICK_FCK_OFFSET;
|
||||
}
|
||||
|
||||
const struct clkops clkops_am35xx_ipss_module_wait = {
|
||||
.enable = omap2_dflt_clk_enable,
|
||||
.disable = omap2_dflt_clk_disable,
|
||||
.find_idlest = am35xx_clk_find_idlest,
|
||||
.find_companion = am35xx_clk_find_companion,
|
||||
};
|
||||
|
||||
/**
|
||||
* am35xx_clk_ipss_find_idlest - return CM_IDLEST info for IPSS
|
||||
* @clk: struct clk * being enabled
|
||||
* @idlest_reg: void __iomem ** to store CM_IDLEST reg address into
|
||||
* @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into
|
||||
* @idlest_val: pointer to a u8 to store the CM_IDLEST indicator
|
||||
*
|
||||
* The IPSS target CM_IDLEST bit is at a different shift from the
|
||||
* CM_{I,F}CLKEN bit. Pass back the correct info via @idlest_reg
|
||||
* and @idlest_bit. No return value.
|
||||
*/
|
||||
static void am35xx_clk_ipss_find_idlest(struct clk *clk,
|
||||
void __iomem **idlest_reg,
|
||||
u8 *idlest_bit,
|
||||
u8 *idlest_val)
|
||||
{
|
||||
u32 r;
|
||||
|
||||
r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20);
|
||||
*idlest_reg = (__force void __iomem *)r;
|
||||
*idlest_bit = AM35XX_ST_IPSS_SHIFT;
|
||||
*idlest_val = OMAP34XX_CM_IDLEST_VAL;
|
||||
}
|
||||
|
||||
const struct clkops clkops_am35xx_ipss_wait = {
|
||||
.enable = omap2_dflt_clk_enable,
|
||||
.disable = omap2_dflt_clk_disable,
|
||||
.find_idlest = am35xx_clk_ipss_find_idlest,
|
||||
.find_companion = omap2_clk_dflt_find_companion,
|
||||
};
|
||||
|
||||
|
14
arch/arm/mach-omap2/clock3517.h
Normal file
14
arch/arm/mach-omap2/clock3517.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* OMAP3517/3505 clock function prototypes and macros
|
||||
*
|
||||
* Copyright (C) 2010 Texas Instruments, Inc.
|
||||
* Copyright (C) 2010 Nokia Corporation
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK3517_H
|
||||
#define __ARCH_ARM_MACH_OMAP2_CLOCK3517_H
|
||||
|
||||
extern const struct clkops clkops_am35xx_ipss_module_wait;
|
||||
extern const struct clkops clkops_am35xx_ipss_wait;
|
||||
|
||||
#endif
|
72
arch/arm/mach-omap2/clock36xx.c
Normal file
72
arch/arm/mach-omap2/clock36xx.c
Normal file
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* OMAP36xx-specific clkops
|
||||
*
|
||||
* Copyright (C) 2010 Texas Instruments, Inc.
|
||||
* Copyright (C) 2010 Nokia Corporation
|
||||
*
|
||||
* Mike Turquette
|
||||
* Vijaykumar GN
|
||||
* Paul Walmsley
|
||||
*
|
||||
* Parts of this code are based on code written by
|
||||
* Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu,
|
||||
* Russell King
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#undef DEBUG
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <plat/clock.h>
|
||||
|
||||
#include "clock.h"
|
||||
#include "clock36xx.h"
|
||||
|
||||
|
||||
/**
|
||||
* omap36xx_pwrdn_clk_enable_with_hsdiv_restore - enable clocks suffering
|
||||
* from HSDivider PWRDN problem Implements Errata ID: i556.
|
||||
* @clk: DPLL output struct clk
|
||||
*
|
||||
* 3630 only: dpll3_m3_ck, dpll4_m2_ck, dpll4_m3_ck, dpll4_m4_ck,
|
||||
* dpll4_m5_ck & dpll4_m6_ck dividers gets loaded with reset
|
||||
* valueafter their respective PWRDN bits are set. Any dummy write
|
||||
* (Any other value different from the Read value) to the
|
||||
* corresponding CM_CLKSEL register will refresh the dividers.
|
||||
*/
|
||||
static int omap36xx_pwrdn_clk_enable_with_hsdiv_restore(struct clk *clk)
|
||||
{
|
||||
u32 dummy_v, orig_v, clksel_shift;
|
||||
int ret;
|
||||
|
||||
/* Clear PWRDN bit of HSDIVIDER */
|
||||
ret = omap2_dflt_clk_enable(clk);
|
||||
|
||||
/* Restore the dividers */
|
||||
if (!ret) {
|
||||
clksel_shift = __ffs(clk->parent->clksel_mask);
|
||||
orig_v = __raw_readl(clk->parent->clksel_reg);
|
||||
dummy_v = orig_v;
|
||||
|
||||
/* Write any other value different from the Read value */
|
||||
dummy_v ^= (1 << clksel_shift);
|
||||
__raw_writel(dummy_v, clk->parent->clksel_reg);
|
||||
|
||||
/* Write the original divider */
|
||||
__raw_writel(orig_v, clk->parent->clksel_reg);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
const struct clkops clkops_omap36xx_pwrdn_with_hsdiv_wait_restore = {
|
||||
.enable = omap36xx_pwrdn_clk_enable_with_hsdiv_restore,
|
||||
.disable = omap2_dflt_clk_disable,
|
||||
.find_companion = omap2_clk_dflt_find_companion,
|
||||
.find_idlest = omap2_clk_dflt_find_idlest,
|
||||
};
|
13
arch/arm/mach-omap2/clock36xx.h
Normal file
13
arch/arm/mach-omap2/clock36xx.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* OMAP36xx clock function prototypes and macros
|
||||
*
|
||||
* Copyright (C) 2010 Texas Instruments, Inc.
|
||||
* Copyright (C) 2010 Nokia Corporation
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK36XX_H
|
||||
#define __ARCH_ARM_MACH_OMAP2_CLOCK36XX_H
|
||||
|
||||
extern const struct clkops clkops_omap36xx_pwrdn_with_hsdiv_wait_restore;
|
||||
|
||||
#endif
|
104
arch/arm/mach-omap2/clock3xxx.c
Normal file
104
arch/arm/mach-omap2/clock3xxx.c
Normal file
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* OMAP3-specific clock framework functions
|
||||
*
|
||||
* Copyright (C) 2007-2008 Texas Instruments, Inc.
|
||||
* Copyright (C) 2007-2010 Nokia Corporation
|
||||
*
|
||||
* Paul Walmsley
|
||||
* Jouni Högander
|
||||
*
|
||||
* Parts of this code are based on code written by
|
||||
* Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#undef DEBUG
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <plat/clock.h>
|
||||
|
||||
#include "clock.h"
|
||||
#include "clock3xxx.h"
|
||||
#include "prm.h"
|
||||
#include "prm-regbits-34xx.h"
|
||||
#include "cm.h"
|
||||
#include "cm-regbits-34xx.h"
|
||||
|
||||
/*
|
||||
* DPLL5_FREQ_FOR_USBHOST: USBHOST and USBTLL are the only clocks
|
||||
* that are sourced by DPLL5, and both of these require this clock
|
||||
* to be at 120 MHz for proper operation.
|
||||
*/
|
||||
#define DPLL5_FREQ_FOR_USBHOST 120000000
|
||||
|
||||
/* needed by omap3_core_dpll_m2_set_rate() */
|
||||
struct clk *sdrc_ick_p, *arm_fck_p;
|
||||
|
||||
int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
/*
|
||||
* According to the 12-5 CDP code from TI, "Limitation 2.5"
|
||||
* on 3430ES1 prevents us from changing DPLL multipliers or dividers
|
||||
* on DPLL4.
|
||||
*/
|
||||
if (omap_rev() == OMAP3430_REV_ES1_0) {
|
||||
pr_err("clock: DPLL4 cannot change rate due to "
|
||||
"silicon 'Limitation 2.5' on 3430ES1.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return omap3_noncore_dpll_set_rate(clk, rate);
|
||||
}
|
||||
|
||||
void __init omap3_clk_lock_dpll5(void)
|
||||
{
|
||||
struct clk *dpll5_clk;
|
||||
struct clk *dpll5_m2_clk;
|
||||
|
||||
dpll5_clk = clk_get(NULL, "dpll5_ck");
|
||||
clk_set_rate(dpll5_clk, DPLL5_FREQ_FOR_USBHOST);
|
||||
clk_enable(dpll5_clk);
|
||||
|
||||
/* Enable autoidle to allow it to enter low power bypass */
|
||||
omap3_dpll_allow_idle(dpll5_clk);
|
||||
|
||||
/* Program dpll5_m2_clk divider for no division */
|
||||
dpll5_m2_clk = clk_get(NULL, "dpll5_m2_ck");
|
||||
clk_enable(dpll5_m2_clk);
|
||||
clk_set_rate(dpll5_m2_clk, DPLL5_FREQ_FOR_USBHOST);
|
||||
|
||||
clk_disable(dpll5_m2_clk);
|
||||
clk_disable(dpll5_clk);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Common clock code */
|
||||
|
||||
/*
|
||||
* Switch the MPU rate if specified on cmdline. We cannot do this
|
||||
* early until cmdline is parsed. XXX This should be removed from the
|
||||
* clock code and handled by the OPP layer code in the near future.
|
||||
*/
|
||||
static int __init omap3xxx_clk_arch_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!cpu_is_omap34xx())
|
||||
return 0;
|
||||
|
||||
ret = omap2_clk_switch_mpurate_at_boot("dpll1_ck");
|
||||
if (!ret)
|
||||
omap2_clk_print_new_rates("osc_sys_ck", "arm_fck", "core_ck");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
arch_initcall(omap3xxx_clk_arch_init);
|
||||
|
||||
|
21
arch/arm/mach-omap2/clock3xxx.h
Normal file
21
arch/arm/mach-omap2/clock3xxx.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* OMAP3-common clock function prototypes and macros
|
||||
*
|
||||
* Copyright (C) 2007-2010 Texas Instruments, Inc.
|
||||
* Copyright (C) 2007-2010 Nokia Corporation
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK3XXX_H
|
||||
#define __ARCH_ARM_MACH_OMAP2_CLOCK3XXX_H
|
||||
|
||||
int omap3xxx_clk_init(void);
|
||||
int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate);
|
||||
int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate);
|
||||
void omap3_clk_lock_dpll5(void);
|
||||
|
||||
extern struct clk *sdrc_ick_p;
|
||||
extern struct clk *arm_fck_p;
|
||||
|
||||
extern const struct clkops clkops_noncore_dpll_ops;
|
||||
|
||||
#endif
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* OMAP3 clock data
|
||||
*
|
||||
* Copyright (C) 2007-2009 Texas Instruments, Inc.
|
||||
* Copyright (C) 2007-2009 Nokia Corporation
|
||||
* Copyright (C) 2007-2010 Texas Instruments, Inc.
|
||||
* Copyright (C) 2007-2010 Nokia Corporation
|
||||
*
|
||||
* Written by Paul Walmsley
|
||||
* With many device clock fixes by Kevin Hilman and Jouni Högander
|
||||
|
@ -16,15 +16,19 @@
|
|||
* to be requested from drivers directly.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/list.h>
|
||||
|
||||
#include <plat/control.h>
|
||||
#include <plat/clkdev_omap.h>
|
||||
|
||||
#include "clock.h"
|
||||
#include "clock3xxx.h"
|
||||
#include "clock34xx.h"
|
||||
#include "clock36xx.h"
|
||||
#include "clock3517.h"
|
||||
|
||||
#include "cm.h"
|
||||
#include "cm-regbits-34xx.h"
|
||||
#include "prm.h"
|
||||
|
@ -37,7 +41,8 @@
|
|||
#define OMAP_CM_REGADDR OMAP34XX_CM_REGADDR
|
||||
|
||||
/* Maximum DPLL multiplier, divider values for OMAP3 */
|
||||
#define OMAP3_MAX_DPLL_MULT 2048
|
||||
#define OMAP3_MAX_DPLL_MULT 2047
|
||||
#define OMAP3630_MAX_JTYPE_DPLL_MULT 4095
|
||||
#define OMAP3_MAX_DPLL_DIV 128
|
||||
|
||||
/*
|
||||
|
@ -59,14 +64,12 @@ static struct clk omap_32k_fck = {
|
|||
.name = "omap_32k_fck",
|
||||
.ops = &clkops_null,
|
||||
.rate = 32768,
|
||||
.flags = RATE_FIXED,
|
||||
};
|
||||
|
||||
static struct clk secure_32k_fck = {
|
||||
.name = "secure_32k_fck",
|
||||
.ops = &clkops_null,
|
||||
.rate = 32768,
|
||||
.flags = RATE_FIXED,
|
||||
};
|
||||
|
||||
/* Virtual source clocks for osc_sys_ck */
|
||||
|
@ -74,42 +77,36 @@ static struct clk virt_12m_ck = {
|
|||
.name = "virt_12m_ck",
|
||||
.ops = &clkops_null,
|
||||
.rate = 12000000,
|
||||
.flags = RATE_FIXED,
|
||||
};
|
||||
|
||||
static struct clk virt_13m_ck = {
|
||||
.name = "virt_13m_ck",
|
||||
.ops = &clkops_null,
|
||||
.rate = 13000000,
|
||||
.flags = RATE_FIXED,
|
||||
};
|
||||
|
||||
static struct clk virt_16_8m_ck = {
|
||||
.name = "virt_16_8m_ck",
|
||||
.ops = &clkops_null,
|
||||
.rate = 16800000,
|
||||
.flags = RATE_FIXED,
|
||||
};
|
||||
|
||||
static struct clk virt_19_2m_ck = {
|
||||
.name = "virt_19_2m_ck",
|
||||
.ops = &clkops_null,
|
||||
.rate = 19200000,
|
||||
.flags = RATE_FIXED,
|
||||
};
|
||||
|
||||
static struct clk virt_26m_ck = {
|
||||
.name = "virt_26m_ck",
|
||||
.ops = &clkops_null,
|
||||
.rate = 26000000,
|
||||
.flags = RATE_FIXED,
|
||||
};
|
||||
|
||||
static struct clk virt_38_4m_ck = {
|
||||
.name = "virt_38_4m_ck",
|
||||
.ops = &clkops_null,
|
||||
.rate = 38400000,
|
||||
.flags = RATE_FIXED,
|
||||
};
|
||||
|
||||
static const struct clksel_rate osc_sys_12m_rates[] = {
|
||||
|
@ -162,7 +159,6 @@ static struct clk osc_sys_ck = {
|
|||
.clksel_mask = OMAP3430_SYS_CLKIN_SEL_MASK,
|
||||
.clksel = osc_sys_clksel,
|
||||
/* REVISIT: deal with autoextclkmode? */
|
||||
.flags = RATE_FIXED,
|
||||
.recalc = &omap2_clksel_recalc,
|
||||
};
|
||||
|
||||
|
@ -236,6 +232,42 @@ static const struct clksel_rate div16_dpll_rates[] = {
|
|||
{ .div = 0 }
|
||||
};
|
||||
|
||||
static const struct clksel_rate div32_dpll4_rates_3630[] = {
|
||||
{ .div = 1, .val = 1, .flags = RATE_IN_36XX | DEFAULT_RATE },
|
||||
{ .div = 2, .val = 2, .flags = RATE_IN_36XX },
|
||||
{ .div = 3, .val = 3, .flags = RATE_IN_36XX },
|
||||
{ .div = 4, .val = 4, .flags = RATE_IN_36XX },
|
||||
{ .div = 5, .val = 5, .flags = RATE_IN_36XX },
|
||||
{ .div = 6, .val = 6, .flags = RATE_IN_36XX },
|
||||
{ .div = 7, .val = 7, .flags = RATE_IN_36XX },
|
||||
{ .div = 8, .val = 8, .flags = RATE_IN_36XX },
|
||||
{ .div = 9, .val = 9, .flags = RATE_IN_36XX },
|
||||
{ .div = 10, .val = 10, .flags = RATE_IN_36XX },
|
||||
{ .div = 11, .val = 11, .flags = RATE_IN_36XX },
|
||||
{ .div = 12, .val = 12, .flags = RATE_IN_36XX },
|
||||
{ .div = 13, .val = 13, .flags = RATE_IN_36XX },
|
||||
{ .div = 14, .val = 14, .flags = RATE_IN_36XX },
|
||||
{ .div = 15, .val = 15, .flags = RATE_IN_36XX },
|
||||
{ .div = 16, .val = 16, .flags = RATE_IN_36XX },
|
||||
{ .div = 17, .val = 17, .flags = RATE_IN_36XX },
|
||||
{ .div = 18, .val = 18, .flags = RATE_IN_36XX },
|
||||
{ .div = 19, .val = 19, .flags = RATE_IN_36XX },
|
||||
{ .div = 20, .val = 20, .flags = RATE_IN_36XX },
|
||||
{ .div = 21, .val = 21, .flags = RATE_IN_36XX },
|
||||
{ .div = 22, .val = 22, .flags = RATE_IN_36XX },
|
||||
{ .div = 23, .val = 23, .flags = RATE_IN_36XX },
|
||||
{ .div = 24, .val = 24, .flags = RATE_IN_36XX },
|
||||
{ .div = 25, .val = 25, .flags = RATE_IN_36XX },
|
||||
{ .div = 26, .val = 26, .flags = RATE_IN_36XX },
|
||||
{ .div = 27, .val = 27, .flags = RATE_IN_36XX },
|
||||
{ .div = 28, .val = 28, .flags = RATE_IN_36XX },
|
||||
{ .div = 29, .val = 29, .flags = RATE_IN_36XX },
|
||||
{ .div = 30, .val = 30, .flags = RATE_IN_36XX },
|
||||
{ .div = 31, .val = 31, .flags = RATE_IN_36XX },
|
||||
{ .div = 32, .val = 32, .flags = RATE_IN_36XX },
|
||||
{ .div = 0 }
|
||||
};
|
||||
|
||||
/* DPLL1 */
|
||||
/* MPU clock source */
|
||||
/* Type: DPLL */
|
||||
|
@ -337,7 +369,7 @@ static struct dpll_data dpll2_dd = {
|
|||
|
||||
static struct clk dpll2_ck = {
|
||||
.name = "dpll2_ck",
|
||||
.ops = &omap3_clkops_noncore_dpll_ops,
|
||||
.ops = &clkops_omap3_noncore_dpll_ops,
|
||||
.parent = &sys_ck,
|
||||
.dpll_data = &dpll2_dd,
|
||||
.round_rate = &omap2_dpll_round_rate,
|
||||
|
@ -529,7 +561,8 @@ static struct clk emu_core_alwon_ck = {
|
|||
/* DPLL4 */
|
||||
/* Supplies 96MHz, 54Mhz TV DAC, DSS fclk, CAM sensor clock, emul trace clk */
|
||||
/* Type: DPLL */
|
||||
static struct dpll_data dpll4_dd = {
|
||||
static struct dpll_data dpll4_dd;
|
||||
static struct dpll_data dpll4_dd_34xx __initdata = {
|
||||
.mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL2),
|
||||
.mult_mask = OMAP3430_PERIPH_DPLL_MULT_MASK,
|
||||
.div1_mask = OMAP3430_PERIPH_DPLL_DIV_MASK,
|
||||
|
@ -552,9 +585,32 @@ static struct dpll_data dpll4_dd = {
|
|||
.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
|
||||
};
|
||||
|
||||
static struct dpll_data dpll4_dd_3630 __initdata = {
|
||||
.mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL2),
|
||||
.mult_mask = OMAP3630_PERIPH_DPLL_MULT_MASK,
|
||||
.div1_mask = OMAP3430_PERIPH_DPLL_DIV_MASK,
|
||||
.clk_bypass = &sys_ck,
|
||||
.clk_ref = &sys_ck,
|
||||
.control_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
|
||||
.enable_mask = OMAP3430_EN_PERIPH_DPLL_MASK,
|
||||
.modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
|
||||
.auto_recal_bit = OMAP3430_EN_PERIPH_DPLL_DRIFTGUARD_SHIFT,
|
||||
.recal_en_bit = OMAP3430_PERIPH_DPLL_RECAL_EN_SHIFT,
|
||||
.recal_st_bit = OMAP3430_PERIPH_DPLL_ST_SHIFT,
|
||||
.autoidle_reg = OMAP_CM_REGADDR(PLL_MOD, CM_AUTOIDLE),
|
||||
.autoidle_mask = OMAP3430_AUTO_PERIPH_DPLL_MASK,
|
||||
.idlest_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
|
||||
.idlest_mask = OMAP3430_ST_PERIPH_CLK_MASK,
|
||||
.max_multiplier = OMAP3630_MAX_JTYPE_DPLL_MULT,
|
||||
.min_divider = 1,
|
||||
.max_divider = OMAP3_MAX_DPLL_DIV,
|
||||
.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE,
|
||||
.flags = DPLL_J_TYPE
|
||||
};
|
||||
|
||||
static struct clk dpll4_ck = {
|
||||
.name = "dpll4_ck",
|
||||
.ops = &omap3_clkops_noncore_dpll_ops,
|
||||
.ops = &clkops_omap3_noncore_dpll_ops,
|
||||
.parent = &sys_ck,
|
||||
.dpll_data = &dpll4_dd,
|
||||
.round_rate = &omap2_dpll_round_rate,
|
||||
|
@ -581,8 +637,15 @@ static const struct clksel div16_dpll4_clksel[] = {
|
|||
{ .parent = NULL }
|
||||
};
|
||||
|
||||
static const struct clksel div32_dpll4_clksel[] = {
|
||||
{ .parent = &dpll4_ck, .rates = div32_dpll4_rates_3630 },
|
||||
{ .parent = NULL }
|
||||
};
|
||||
|
||||
/* This virtual clock is the source for dpll4_m2x2_ck */
|
||||
static struct clk dpll4_m2_ck = {
|
||||
static struct clk dpll4_m2_ck;
|
||||
|
||||
static struct clk dpll4_m2_ck_34xx __initdata = {
|
||||
.name = "dpll4_m2_ck",
|
||||
.ops = &clkops_null,
|
||||
.parent = &dpll4_ck,
|
||||
|
@ -594,6 +657,18 @@ static struct clk dpll4_m2_ck = {
|
|||
.recalc = &omap2_clksel_recalc,
|
||||
};
|
||||
|
||||
static struct clk dpll4_m2_ck_3630 __initdata = {
|
||||
.name = "dpll4_m2_ck",
|
||||
.ops = &clkops_null,
|
||||
.parent = &dpll4_ck,
|
||||
.init = &omap2_init_clksel_parent,
|
||||
.clksel_reg = OMAP_CM_REGADDR(PLL_MOD, OMAP3430_CM_CLKSEL3),
|
||||
.clksel_mask = OMAP3630_DIV_96M_MASK,
|
||||
.clksel = div32_dpll4_clksel,
|
||||
.clkdm_name = "dpll4_clkdm",
|
||||
.recalc = &omap2_clksel_recalc,
|
||||
};
|
||||
|
||||
/* The PWRDN bit is apparently only available on 3430ES2 and above */
|
||||
static struct clk dpll4_m2x2_ck = {
|
||||
.name = "dpll4_m2x2_ck",
|
||||
|
@ -612,18 +687,24 @@ static struct clk dpll4_m2x2_ck = {
|
|||
* 96M_ALWON_FCLK (called "omap_96m_alwon_fck" below) and
|
||||
* CM_96K_(F)CLK.
|
||||
*/
|
||||
static struct clk omap_96m_alwon_fck = {
|
||||
.name = "omap_96m_alwon_fck",
|
||||
|
||||
/* Adding 192MHz Clock node needed by SGX */
|
||||
static struct clk omap_192m_alwon_fck = {
|
||||
.name = "omap_192m_alwon_fck",
|
||||
.ops = &clkops_null,
|
||||
.parent = &dpll4_m2x2_ck,
|
||||
.recalc = &followparent_recalc,
|
||||
};
|
||||
|
||||
static struct clk cm_96m_fck = {
|
||||
.name = "cm_96m_fck",
|
||||
.ops = &clkops_null,
|
||||
.parent = &omap_96m_alwon_fck,
|
||||
.recalc = &followparent_recalc,
|
||||
static const struct clksel_rate omap_96m_alwon_fck_rates[] = {
|
||||
{ .div = 1, .val = 1, .flags = RATE_IN_36XX },
|
||||
{ .div = 2, .val = 2, .flags = RATE_IN_36XX | DEFAULT_RATE },
|
||||
{ .div = 0 }
|
||||
};
|
||||
|
||||
static const struct clksel omap_96m_alwon_fck_clksel[] = {
|
||||
{ .parent = &omap_192m_alwon_fck, .rates = omap_96m_alwon_fck_rates },
|
||||
{ .parent = NULL }
|
||||
};
|
||||
|
||||
static const struct clksel_rate omap_96m_dpll_rates[] = {
|
||||
|
@ -636,6 +717,31 @@ static const struct clksel_rate omap_96m_sys_rates[] = {
|
|||
{ .div = 0 }
|
||||
};
|
||||
|
||||
static struct clk omap_96m_alwon_fck = {
|
||||
.name = "omap_96m_alwon_fck",
|
||||
.ops = &clkops_null,
|
||||
.parent = &dpll4_m2x2_ck,
|
||||
.recalc = &followparent_recalc,
|
||||
};
|
||||
|
||||
static struct clk omap_96m_alwon_fck_3630 = {
|
||||
.name = "omap_96m_alwon_fck",
|
||||
.parent = &omap_192m_alwon_fck,
|
||||
.init = &omap2_init_clksel_parent,
|
||||
.ops = &clkops_null,
|
||||
.recalc = &omap2_clksel_recalc,
|
||||
.clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
|
||||
.clksel_mask = OMAP3630_CLKSEL_96M_MASK,
|
||||
.clksel = omap_96m_alwon_fck_clksel
|
||||
};
|
||||
|
||||
static struct clk cm_96m_fck = {
|
||||
.name = "cm_96m_fck",
|
||||
.ops = &clkops_null,
|
||||
.parent = &omap_96m_alwon_fck,
|
||||
.recalc = &followparent_recalc,
|
||||
};
|
||||
|
||||
static const struct clksel omap_96m_fck_clksel[] = {
|
||||
{ .parent = &cm_96m_fck, .rates = omap_96m_dpll_rates },
|
||||
{ .parent = &sys_ck, .rates = omap_96m_sys_rates },
|
||||
|
@ -654,7 +760,9 @@ static struct clk omap_96m_fck = {
|
|||
};
|
||||
|
||||
/* This virtual clock is the source for dpll4_m3x2_ck */
|
||||
static struct clk dpll4_m3_ck = {
|
||||
static struct clk dpll4_m3_ck;
|
||||
|
||||
static struct clk dpll4_m3_ck_34xx __initdata = {
|
||||
.name = "dpll4_m3_ck",
|
||||
.ops = &clkops_null,
|
||||
.parent = &dpll4_ck,
|
||||
|
@ -666,6 +774,18 @@ static struct clk dpll4_m3_ck = {
|
|||
.recalc = &omap2_clksel_recalc,
|
||||
};
|
||||
|
||||
static struct clk dpll4_m3_ck_3630 __initdata = {
|
||||
.name = "dpll4_m3_ck",
|
||||
.ops = &clkops_null,
|
||||
.parent = &dpll4_ck,
|
||||
.init = &omap2_init_clksel_parent,
|
||||
.clksel_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_CLKSEL),
|
||||
.clksel_mask = OMAP3630_CLKSEL_TV_MASK,
|
||||
.clksel = div32_dpll4_clksel,
|
||||
.clkdm_name = "dpll4_clkdm",
|
||||
.recalc = &omap2_clksel_recalc,
|
||||
};
|
||||
|
||||
/* The PWRDN bit is apparently only available on 3430ES2 and above */
|
||||
static struct clk dpll4_m3x2_ck = {
|
||||
.name = "dpll4_m3x2_ck",
|
||||
|
@ -739,7 +859,9 @@ static struct clk omap_12m_fck = {
|
|||
};
|
||||
|
||||
/* This virstual clock is the source for dpll4_m4x2_ck */
|
||||
static struct clk dpll4_m4_ck = {
|
||||
static struct clk dpll4_m4_ck;
|
||||
|
||||
static struct clk dpll4_m4_ck_34xx __initdata = {
|
||||
.name = "dpll4_m4_ck",
|
||||
.ops = &clkops_null,
|
||||
.parent = &dpll4_ck,
|
||||
|
@ -753,6 +875,20 @@ static struct clk dpll4_m4_ck = {
|
|||
.round_rate = &omap2_clksel_round_rate,
|
||||
};
|
||||
|
||||
static struct clk dpll4_m4_ck_3630 __initdata = {
|
||||
.name = "dpll4_m4_ck",
|
||||
.ops = &clkops_null,
|
||||
.parent = &dpll4_ck,
|
||||
.init = &omap2_init_clksel_parent,
|
||||
.clksel_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_CLKSEL),
|
||||
.clksel_mask = OMAP3630_CLKSEL_DSS1_MASK,
|
||||
.clksel = div32_dpll4_clksel,
|
||||
.clkdm_name = "dpll4_clkdm",
|
||||
.recalc = &omap2_clksel_recalc,
|
||||
.set_rate = &omap2_clksel_set_rate,
|
||||
.round_rate = &omap2_clksel_round_rate,
|
||||
};
|
||||
|
||||
/* The PWRDN bit is apparently only available on 3430ES2 and above */
|
||||
static struct clk dpll4_m4x2_ck = {
|
||||
.name = "dpll4_m4x2_ck",
|
||||
|
@ -766,7 +902,9 @@ static struct clk dpll4_m4x2_ck = {
|
|||
};
|
||||
|
||||
/* This virtual clock is the source for dpll4_m5x2_ck */
|
||||
static struct clk dpll4_m5_ck = {
|
||||
static struct clk dpll4_m5_ck;
|
||||
|
||||
static struct clk dpll4_m5_ck_34xx __initdata = {
|
||||
.name = "dpll4_m5_ck",
|
||||
.ops = &clkops_null,
|
||||
.parent = &dpll4_ck,
|
||||
|
@ -780,6 +918,20 @@ static struct clk dpll4_m5_ck = {
|
|||
.recalc = &omap2_clksel_recalc,
|
||||
};
|
||||
|
||||
static struct clk dpll4_m5_ck_3630 __initdata = {
|
||||
.name = "dpll4_m5_ck",
|
||||
.ops = &clkops_null,
|
||||
.parent = &dpll4_ck,
|
||||
.init = &omap2_init_clksel_parent,
|
||||
.clksel_reg = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_CLKSEL),
|
||||
.clksel_mask = OMAP3630_CLKSEL_CAM_MASK,
|
||||
.clksel = div32_dpll4_clksel,
|
||||
.clkdm_name = "dpll4_clkdm",
|
||||
.set_rate = &omap2_clksel_set_rate,
|
||||
.round_rate = &omap2_clksel_round_rate,
|
||||
.recalc = &omap2_clksel_recalc,
|
||||
};
|
||||
|
||||
/* The PWRDN bit is apparently only available on 3430ES2 and above */
|
||||
static struct clk dpll4_m5x2_ck = {
|
||||
.name = "dpll4_m5x2_ck",
|
||||
|
@ -793,7 +945,9 @@ static struct clk dpll4_m5x2_ck = {
|
|||
};
|
||||
|
||||
/* This virtual clock is the source for dpll4_m6x2_ck */
|
||||
static struct clk dpll4_m6_ck = {
|
||||
static struct clk dpll4_m6_ck;
|
||||
|
||||
static struct clk dpll4_m6_ck_34xx __initdata = {
|
||||
.name = "dpll4_m6_ck",
|
||||
.ops = &clkops_null,
|
||||
.parent = &dpll4_ck,
|
||||
|
@ -805,6 +959,18 @@ static struct clk dpll4_m6_ck = {
|
|||
.recalc = &omap2_clksel_recalc,
|
||||
};
|
||||
|
||||
static struct clk dpll4_m6_ck_3630 __initdata = {
|
||||
.name = "dpll4_m6_ck",
|
||||
.ops = &clkops_null,
|
||||
.parent = &dpll4_ck,
|
||||
.init = &omap2_init_clksel_parent,
|
||||
.clksel_reg = OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
|
||||
.clksel_mask = OMAP3630_DIV_DPLL4_MASK,
|
||||
.clksel = div32_dpll4_clksel,
|
||||
.clkdm_name = "dpll4_clkdm",
|
||||
.recalc = &omap2_clksel_recalc,
|
||||
};
|
||||
|
||||
/* The PWRDN bit is apparently only available on 3430ES2 and above */
|
||||
static struct clk dpll4_m6x2_ck = {
|
||||
.name = "dpll4_m6x2_ck",
|
||||
|
@ -854,7 +1020,7 @@ static struct dpll_data dpll5_dd = {
|
|||
|
||||
static struct clk dpll5_ck = {
|
||||
.name = "dpll5_ck",
|
||||
.ops = &omap3_clkops_noncore_dpll_ops,
|
||||
.ops = &clkops_omap3_noncore_dpll_ops,
|
||||
.parent = &sys_ck,
|
||||
.dpll_data = &dpll5_dd,
|
||||
.round_rate = &omap2_dpll_round_rate,
|
||||
|
@ -1166,12 +1332,24 @@ static struct clk gfx_cg2_ck = {
|
|||
/* SGX power domain - 3430ES2 only */
|
||||
|
||||
static const struct clksel_rate sgx_core_rates[] = {
|
||||
{ .div = 2, .val = 5, .flags = RATE_IN_36XX },
|
||||
{ .div = 3, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
|
||||
{ .div = 4, .val = 1, .flags = RATE_IN_343X },
|
||||
{ .div = 6, .val = 2, .flags = RATE_IN_343X },
|
||||
{ .div = 0 },
|
||||
};
|
||||
|
||||
static const struct clksel_rate sgx_192m_rates[] = {
|
||||
{ .div = 1, .val = 4, .flags = RATE_IN_36XX | DEFAULT_RATE },
|
||||
{ .div = 0 },
|
||||
};
|
||||
|
||||
static const struct clksel_rate sgx_corex2_rates[] = {
|
||||
{ .div = 3, .val = 6, .flags = RATE_IN_36XX | DEFAULT_RATE },
|
||||
{ .div = 5, .val = 7, .flags = RATE_IN_36XX },
|
||||
{ .div = 0 },
|
||||
};
|
||||
|
||||
static const struct clksel_rate sgx_96m_rates[] = {
|
||||
{ .div = 1, .val = 3, .flags = RATE_IN_343X | DEFAULT_RATE },
|
||||
{ .div = 0 },
|
||||
|
@ -1180,7 +1358,9 @@ static const struct clksel_rate sgx_96m_rates[] = {
|
|||
static const struct clksel sgx_clksel[] = {
|
||||
{ .parent = &core_ck, .rates = sgx_core_rates },
|
||||
{ .parent = &cm_96m_fck, .rates = sgx_96m_rates },
|
||||
{ .parent = NULL },
|
||||
{ .parent = &omap_192m_alwon_fck, .rates = sgx_192m_rates },
|
||||
{ .parent = &corex2_fck, .rates = sgx_corex2_rates },
|
||||
{ .parent = NULL }
|
||||
};
|
||||
|
||||
static struct clk sgx_fck = {
|
||||
|
@ -1194,6 +1374,8 @@ static struct clk sgx_fck = {
|
|||
.clksel = sgx_clksel,
|
||||
.clkdm_name = "sgx_clkdm",
|
||||
.recalc = &omap2_clksel_recalc,
|
||||
.set_rate = &omap2_clksel_set_rate,
|
||||
.round_rate = &omap2_clksel_round_rate
|
||||
};
|
||||
|
||||
static struct clk sgx_ick = {
|
||||
|
@ -1320,9 +1502,8 @@ static struct clk core_96m_fck = {
|
|||
};
|
||||
|
||||
static struct clk mmchs3_fck = {
|
||||
.name = "mmchs_fck",
|
||||
.name = "mmchs3_fck",
|
||||
.ops = &clkops_omap2_dflt_wait,
|
||||
.id = 2,
|
||||
.parent = &core_96m_fck,
|
||||
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
|
||||
.enable_bit = OMAP3430ES2_EN_MMC3_SHIFT,
|
||||
|
@ -1331,9 +1512,8 @@ static struct clk mmchs3_fck = {
|
|||
};
|
||||
|
||||
static struct clk mmchs2_fck = {
|
||||
.name = "mmchs_fck",
|
||||
.name = "mmchs2_fck",
|
||||
.ops = &clkops_omap2_dflt_wait,
|
||||
.id = 1,
|
||||
.parent = &core_96m_fck,
|
||||
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
|
||||
.enable_bit = OMAP3430_EN_MMC2_SHIFT,
|
||||
|
@ -1352,7 +1532,7 @@ static struct clk mspro_fck = {
|
|||
};
|
||||
|
||||
static struct clk mmchs1_fck = {
|
||||
.name = "mmchs_fck",
|
||||
.name = "mmchs1_fck",
|
||||
.ops = &clkops_omap2_dflt_wait,
|
||||
.parent = &core_96m_fck,
|
||||
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
|
||||
|
@ -1362,9 +1542,8 @@ static struct clk mmchs1_fck = {
|
|||
};
|
||||
|
||||
static struct clk i2c3_fck = {
|
||||
.name = "i2c_fck",
|
||||
.name = "i2c3_fck",
|
||||
.ops = &clkops_omap2_dflt_wait,
|
||||
.id = 3,
|
||||
.parent = &core_96m_fck,
|
||||
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
|
||||
.enable_bit = OMAP3430_EN_I2C3_SHIFT,
|
||||
|
@ -1373,9 +1552,8 @@ static struct clk i2c3_fck = {
|
|||
};
|
||||
|
||||
static struct clk i2c2_fck = {
|
||||
.name = "i2c_fck",
|
||||
.name = "i2c2_fck",
|
||||
.ops = &clkops_omap2_dflt_wait,
|
||||
.id = 2,
|
||||
.parent = &core_96m_fck,
|
||||
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
|
||||
.enable_bit = OMAP3430_EN_I2C2_SHIFT,
|
||||
|
@ -1384,9 +1562,8 @@ static struct clk i2c2_fck = {
|
|||
};
|
||||
|
||||
static struct clk i2c1_fck = {
|
||||
.name = "i2c_fck",
|
||||
.name = "i2c1_fck",
|
||||
.ops = &clkops_omap2_dflt_wait,
|
||||
.id = 1,
|
||||
.parent = &core_96m_fck,
|
||||
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
|
||||
.enable_bit = OMAP3430_EN_I2C1_SHIFT,
|
||||
|
@ -1415,9 +1592,8 @@ static const struct clksel mcbsp_15_clksel[] = {
|
|||
};
|
||||
|
||||
static struct clk mcbsp5_fck = {
|
||||
.name = "mcbsp_fck",
|
||||
.name = "mcbsp5_fck",
|
||||
.ops = &clkops_omap2_dflt_wait,
|
||||
.id = 5,
|
||||
.init = &omap2_init_clksel_parent,
|
||||
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
|
||||
.enable_bit = OMAP3430_EN_MCBSP5_SHIFT,
|
||||
|
@ -1429,9 +1605,8 @@ static struct clk mcbsp5_fck = {
|
|||
};
|
||||
|
||||
static struct clk mcbsp1_fck = {
|
||||
.name = "mcbsp_fck",
|
||||
.name = "mcbsp1_fck",
|
||||
.ops = &clkops_omap2_dflt_wait,
|
||||
.id = 1,
|
||||
.init = &omap2_init_clksel_parent,
|
||||
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
|
||||
.enable_bit = OMAP3430_EN_MCBSP1_SHIFT,
|
||||
|
@ -1453,9 +1628,8 @@ static struct clk core_48m_fck = {
|
|||
};
|
||||
|
||||
static struct clk mcspi4_fck = {
|
||||
.name = "mcspi_fck",
|
||||
.name = "mcspi4_fck",
|
||||
.ops = &clkops_omap2_dflt_wait,
|
||||
.id = 4,
|
||||
.parent = &core_48m_fck,
|
||||
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
|
||||
.enable_bit = OMAP3430_EN_MCSPI4_SHIFT,
|
||||
|
@ -1463,9 +1637,8 @@ static struct clk mcspi4_fck = {
|
|||
};
|
||||
|
||||
static struct clk mcspi3_fck = {
|
||||
.name = "mcspi_fck",
|
||||
.name = "mcspi3_fck",
|
||||
.ops = &clkops_omap2_dflt_wait,
|
||||
.id = 3,
|
||||
.parent = &core_48m_fck,
|
||||
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
|
||||
.enable_bit = OMAP3430_EN_MCSPI3_SHIFT,
|
||||
|
@ -1473,9 +1646,8 @@ static struct clk mcspi3_fck = {
|
|||
};
|
||||
|
||||
static struct clk mcspi2_fck = {
|
||||
.name = "mcspi_fck",
|
||||
.name = "mcspi2_fck",
|
||||
.ops = &clkops_omap2_dflt_wait,
|
||||
.id = 2,
|
||||
.parent = &core_48m_fck,
|
||||
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
|
||||
.enable_bit = OMAP3430_EN_MCSPI2_SHIFT,
|
||||
|
@ -1483,9 +1655,8 @@ static struct clk mcspi2_fck = {
|
|||
};
|
||||
|
||||
static struct clk mcspi1_fck = {
|
||||
.name = "mcspi_fck",
|
||||
.name = "mcspi1_fck",
|
||||
.ops = &clkops_omap2_dflt_wait,
|
||||
.id = 1,
|
||||
.parent = &core_48m_fck,
|
||||
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
|
||||
.enable_bit = OMAP3430_EN_MCSPI1_SHIFT,
|
||||
|
@ -1694,9 +1865,8 @@ static struct clk usbtll_ick = {
|
|||
};
|
||||
|
||||
static struct clk mmchs3_ick = {
|
||||
.name = "mmchs_ick",
|
||||
.name = "mmchs3_ick",
|
||||
.ops = &clkops_omap2_dflt_wait,
|
||||
.id = 2,
|
||||
.parent = &core_l4_ick,
|
||||
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
|
||||
.enable_bit = OMAP3430ES2_EN_MMC3_SHIFT,
|
||||
|
@ -1746,9 +1916,8 @@ static struct clk des2_ick = {
|
|||
};
|
||||
|
||||
static struct clk mmchs2_ick = {
|
||||
.name = "mmchs_ick",
|
||||
.name = "mmchs2_ick",
|
||||
.ops = &clkops_omap2_dflt_wait,
|
||||
.id = 1,
|
||||
.parent = &core_l4_ick,
|
||||
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
|
||||
.enable_bit = OMAP3430_EN_MMC2_SHIFT,
|
||||
|
@ -1757,7 +1926,7 @@ static struct clk mmchs2_ick = {
|
|||
};
|
||||
|
||||
static struct clk mmchs1_ick = {
|
||||
.name = "mmchs_ick",
|
||||
.name = "mmchs1_ick",
|
||||
.ops = &clkops_omap2_dflt_wait,
|
||||
.parent = &core_l4_ick,
|
||||
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
|
||||
|
@ -1787,9 +1956,8 @@ static struct clk hdq_ick = {
|
|||
};
|
||||
|
||||
static struct clk mcspi4_ick = {
|
||||
.name = "mcspi_ick",
|
||||
.name = "mcspi4_ick",
|
||||
.ops = &clkops_omap2_dflt_wait,
|
||||
.id = 4,
|
||||
.parent = &core_l4_ick,
|
||||
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
|
||||
.enable_bit = OMAP3430_EN_MCSPI4_SHIFT,
|
||||
|
@ -1798,9 +1966,8 @@ static struct clk mcspi4_ick = {
|
|||
};
|
||||
|
||||
static struct clk mcspi3_ick = {
|
||||
.name = "mcspi_ick",
|
||||
.name = "mcspi3_ick",
|
||||
.ops = &clkops_omap2_dflt_wait,
|
||||
.id = 3,
|
||||
.parent = &core_l4_ick,
|
||||
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
|
||||
.enable_bit = OMAP3430_EN_MCSPI3_SHIFT,
|
||||
|
@ -1809,9 +1976,8 @@ static struct clk mcspi3_ick = {
|
|||
};
|
||||
|
||||
static struct clk mcspi2_ick = {
|
||||
.name = "mcspi_ick",
|
||||
.name = "mcspi2_ick",
|
||||
.ops = &clkops_omap2_dflt_wait,
|
||||
.id = 2,
|
||||
.parent = &core_l4_ick,
|
||||
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
|
||||
.enable_bit = OMAP3430_EN_MCSPI2_SHIFT,
|
||||
|
@ -1820,9 +1986,8 @@ static struct clk mcspi2_ick = {
|
|||
};
|
||||
|
||||
static struct clk mcspi1_ick = {
|
||||
.name = "mcspi_ick",
|
||||
.name = "mcspi1_ick",
|
||||
.ops = &clkops_omap2_dflt_wait,
|
||||
.id = 1,
|
||||
.parent = &core_l4_ick,
|
||||
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
|
||||
.enable_bit = OMAP3430_EN_MCSPI1_SHIFT,
|
||||
|
@ -1831,9 +1996,8 @@ static struct clk mcspi1_ick = {
|
|||
};
|
||||
|
||||
static struct clk i2c3_ick = {
|
||||
.name = "i2c_ick",
|
||||
.name = "i2c3_ick",
|
||||
.ops = &clkops_omap2_dflt_wait,
|
||||
.id = 3,
|
||||
.parent = &core_l4_ick,
|
||||
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
|
||||
.enable_bit = OMAP3430_EN_I2C3_SHIFT,
|
||||
|
@ -1842,9 +2006,8 @@ static struct clk i2c3_ick = {
|
|||
};
|
||||
|
||||
static struct clk i2c2_ick = {
|
||||
.name = "i2c_ick",
|
||||
.name = "i2c2_ick",
|
||||
.ops = &clkops_omap2_dflt_wait,
|
||||
.id = 2,
|
||||
.parent = &core_l4_ick,
|
||||
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
|
||||
.enable_bit = OMAP3430_EN_I2C2_SHIFT,
|
||||
|
@ -1853,9 +2016,8 @@ static struct clk i2c2_ick = {
|
|||
};
|
||||
|
||||
static struct clk i2c1_ick = {
|
||||
.name = "i2c_ick",
|
||||
.name = "i2c1_ick",
|
||||
.ops = &clkops_omap2_dflt_wait,
|
||||
.id = 1,
|
||||
.parent = &core_l4_ick,
|
||||
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
|
||||
.enable_bit = OMAP3430_EN_I2C1_SHIFT,
|
||||
|
@ -1904,9 +2066,8 @@ static struct clk gpt10_ick = {
|
|||
};
|
||||
|
||||
static struct clk mcbsp5_ick = {
|
||||
.name = "mcbsp_ick",
|
||||
.name = "mcbsp5_ick",
|
||||
.ops = &clkops_omap2_dflt_wait,
|
||||
.id = 5,
|
||||
.parent = &core_l4_ick,
|
||||
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
|
||||
.enable_bit = OMAP3430_EN_MCBSP5_SHIFT,
|
||||
|
@ -1915,9 +2076,8 @@ static struct clk mcbsp5_ick = {
|
|||
};
|
||||
|
||||
static struct clk mcbsp1_ick = {
|
||||
.name = "mcbsp_ick",
|
||||
.name = "mcbsp1_ick",
|
||||
.ops = &clkops_omap2_dflt_wait,
|
||||
.id = 1,
|
||||
.parent = &core_l4_ick,
|
||||
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
|
||||
.enable_bit = OMAP3430_EN_MCBSP1_SHIFT,
|
||||
|
@ -2712,9 +2872,8 @@ static struct clk gpt2_ick = {
|
|||
};
|
||||
|
||||
static struct clk mcbsp2_ick = {
|
||||
.name = "mcbsp_ick",
|
||||
.name = "mcbsp2_ick",
|
||||
.ops = &clkops_omap2_dflt_wait,
|
||||
.id = 2,
|
||||
.parent = &per_l4_ick,
|
||||
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
|
||||
.enable_bit = OMAP3430_EN_MCBSP2_SHIFT,
|
||||
|
@ -2723,9 +2882,8 @@ static struct clk mcbsp2_ick = {
|
|||
};
|
||||
|
||||
static struct clk mcbsp3_ick = {
|
||||
.name = "mcbsp_ick",
|
||||
.name = "mcbsp3_ick",
|
||||
.ops = &clkops_omap2_dflt_wait,
|
||||
.id = 3,
|
||||
.parent = &per_l4_ick,
|
||||
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
|
||||
.enable_bit = OMAP3430_EN_MCBSP3_SHIFT,
|
||||
|
@ -2734,9 +2892,8 @@ static struct clk mcbsp3_ick = {
|
|||
};
|
||||
|
||||
static struct clk mcbsp4_ick = {
|
||||
.name = "mcbsp_ick",
|
||||
.name = "mcbsp4_ick",
|
||||
.ops = &clkops_omap2_dflt_wait,
|
||||
.id = 4,
|
||||
.parent = &per_l4_ick,
|
||||
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
|
||||
.enable_bit = OMAP3430_EN_MCBSP4_SHIFT,
|
||||
|
@ -2751,9 +2908,8 @@ static const struct clksel mcbsp_234_clksel[] = {
|
|||
};
|
||||
|
||||
static struct clk mcbsp2_fck = {
|
||||
.name = "mcbsp_fck",
|
||||
.name = "mcbsp2_fck",
|
||||
.ops = &clkops_omap2_dflt_wait,
|
||||
.id = 2,
|
||||
.init = &omap2_init_clksel_parent,
|
||||
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
|
||||
.enable_bit = OMAP3430_EN_MCBSP2_SHIFT,
|
||||
|
@ -2765,9 +2921,8 @@ static struct clk mcbsp2_fck = {
|
|||
};
|
||||
|
||||
static struct clk mcbsp3_fck = {
|
||||
.name = "mcbsp_fck",
|
||||
.name = "mcbsp3_fck",
|
||||
.ops = &clkops_omap2_dflt_wait,
|
||||
.id = 3,
|
||||
.init = &omap2_init_clksel_parent,
|
||||
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
|
||||
.enable_bit = OMAP3430_EN_MCBSP3_SHIFT,
|
||||
|
@ -2779,9 +2934,8 @@ static struct clk mcbsp3_fck = {
|
|||
};
|
||||
|
||||
static struct clk mcbsp4_fck = {
|
||||
.name = "mcbsp_fck",
|
||||
.name = "mcbsp4_fck",
|
||||
.ops = &clkops_omap2_dflt_wait,
|
||||
.id = 4,
|
||||
.init = &omap2_init_clksel_parent,
|
||||
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
|
||||
.enable_bit = OMAP3430_EN_MCBSP4_SHIFT,
|
||||
|
@ -2983,6 +3137,111 @@ static struct clk wdt1_fck = {
|
|||
.recalc = &followparent_recalc,
|
||||
};
|
||||
|
||||
/* Clocks for AM35XX */
|
||||
static struct clk ipss_ick = {
|
||||
.name = "ipss_ick",
|
||||
.ops = &clkops_am35xx_ipss_wait,
|
||||
.parent = &core_l3_ick,
|
||||
.clkdm_name = "core_l3_clkdm",
|
||||
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
|
||||
.enable_bit = AM35XX_EN_IPSS_SHIFT,
|
||||
.recalc = &followparent_recalc,
|
||||
};
|
||||
|
||||
static struct clk emac_ick = {
|
||||
.name = "emac_ick",
|
||||
.ops = &clkops_am35xx_ipss_module_wait,
|
||||
.parent = &ipss_ick,
|
||||
.clkdm_name = "core_l3_clkdm",
|
||||
.enable_reg = OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
|
||||
.enable_bit = AM35XX_CPGMAC_VBUSP_CLK_SHIFT,
|
||||
.recalc = &followparent_recalc,
|
||||
};
|
||||
|
||||
static struct clk rmii_ck = {
|
||||
.name = "rmii_ck",
|
||||
.ops = &clkops_null,
|
||||
.rate = 50000000,
|
||||
};
|
||||
|
||||
static struct clk emac_fck = {
|
||||
.name = "emac_fck",
|
||||
.ops = &clkops_omap2_dflt,
|
||||
.parent = &rmii_ck,
|
||||
.enable_reg = OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
|
||||
.enable_bit = AM35XX_CPGMAC_FCLK_SHIFT,
|
||||
.recalc = &followparent_recalc,
|
||||
};
|
||||
|
||||
static struct clk hsotgusb_ick_am35xx = {
|
||||
.name = "hsotgusb_ick",
|
||||
.ops = &clkops_am35xx_ipss_module_wait,
|
||||
.parent = &ipss_ick,
|
||||
.clkdm_name = "core_l3_clkdm",
|
||||
.enable_reg = OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
|
||||
.enable_bit = AM35XX_USBOTG_VBUSP_CLK_SHIFT,
|
||||
.recalc = &followparent_recalc,
|
||||
};
|
||||
|
||||
static struct clk hsotgusb_fck_am35xx = {
|
||||
.name = "hsotgusb_fck",
|
||||
.ops = &clkops_omap2_dflt,
|
||||
.parent = &sys_ck,
|
||||
.clkdm_name = "core_l3_clkdm",
|
||||
.enable_reg = OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
|
||||
.enable_bit = AM35XX_USBOTG_FCLK_SHIFT,
|
||||
.recalc = &followparent_recalc,
|
||||
};
|
||||
|
||||
static struct clk hecc_ck = {
|
||||
.name = "hecc_ck",
|
||||
.ops = &clkops_am35xx_ipss_module_wait,
|
||||
.parent = &sys_ck,
|
||||
.clkdm_name = "core_l3_clkdm",
|
||||
.enable_reg = OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
|
||||
.enable_bit = AM35XX_HECC_VBUSP_CLK_SHIFT,
|
||||
.recalc = &followparent_recalc,
|
||||
};
|
||||
|
||||
static struct clk vpfe_ick = {
|
||||
.name = "vpfe_ick",
|
||||
.ops = &clkops_am35xx_ipss_module_wait,
|
||||
.parent = &ipss_ick,
|
||||
.clkdm_name = "core_l3_clkdm",
|
||||
.enable_reg = OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
|
||||
.enable_bit = AM35XX_VPFE_VBUSP_CLK_SHIFT,
|
||||
.recalc = &followparent_recalc,
|
||||
};
|
||||
|
||||
static struct clk pclk_ck = {
|
||||
.name = "pclk_ck",
|
||||
.ops = &clkops_null,
|
||||
.rate = 27000000,
|
||||
};
|
||||
|
||||
static struct clk vpfe_fck = {
|
||||
.name = "vpfe_fck",
|
||||
.ops = &clkops_omap2_dflt,
|
||||
.parent = &pclk_ck,
|
||||
.enable_reg = OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
|
||||
.enable_bit = AM35XX_VPFE_FCLK_SHIFT,
|
||||
.recalc = &followparent_recalc,
|
||||
};
|
||||
|
||||
/*
|
||||
* The UART1/2 functional clock acts as the functional
|
||||
* clock for UART4. No separate fclk control available.
|
||||
*/
|
||||
static struct clk uart4_ick_am35xx = {
|
||||
.name = "uart4_ick",
|
||||
.ops = &clkops_omap2_dflt_wait,
|
||||
.parent = &core_l4_ick,
|
||||
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
|
||||
.enable_bit = AM35XX_EN_UART4_SHIFT,
|
||||
.clkdm_name = "core_l4_clkdm",
|
||||
.recalc = &followparent_recalc,
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* clkdev
|
||||
|
@ -3017,6 +3276,7 @@ static struct omap_clk omap3xxx_clks[] = {
|
|||
CLK("etb", "emu_core_alwon_ck", &emu_core_alwon_ck, CK_3XXX),
|
||||
CLK(NULL, "dpll4_ck", &dpll4_ck, CK_3XXX),
|
||||
CLK(NULL, "dpll4_x2_ck", &dpll4_x2_ck, CK_3XXX),
|
||||
CLK(NULL, "omap_192m_alwon_fck", &omap_192m_alwon_fck, CK_36XX),
|
||||
CLK(NULL, "omap_96m_alwon_fck", &omap_96m_alwon_fck, CK_3XXX),
|
||||
CLK(NULL, "omap_96m_fck", &omap_96m_fck, CK_3XXX),
|
||||
CLK(NULL, "cm_96m_fck", &cm_96m_fck, CK_3XXX),
|
||||
|
@ -3209,6 +3469,17 @@ static struct omap_clk omap3xxx_clks[] = {
|
|||
CLK(NULL, "secure_32k_fck", &secure_32k_fck, CK_3XXX),
|
||||
CLK(NULL, "gpt12_fck", &gpt12_fck, CK_3XXX),
|
||||
CLK(NULL, "wdt1_fck", &wdt1_fck, CK_3XXX),
|
||||
CLK(NULL, "ipss_ick", &ipss_ick, CK_AM35XX),
|
||||
CLK(NULL, "rmii_ck", &rmii_ck, CK_AM35XX),
|
||||
CLK(NULL, "pclk_ck", &pclk_ck, CK_AM35XX),
|
||||
CLK("davinci_emac", "ick", &emac_ick, CK_AM35XX),
|
||||
CLK("davinci_emac", "fck", &emac_fck, CK_AM35XX),
|
||||
CLK("vpfe-capture", "master", &vpfe_ick, CK_AM35XX),
|
||||
CLK("vpfe-capture", "slave", &vpfe_fck, CK_AM35XX),
|
||||
CLK("musb_hdrc", "ick", &hsotgusb_ick_am35xx, CK_AM35XX),
|
||||
CLK("musb_hdrc", "fck", &hsotgusb_fck_am35xx, CK_AM35XX),
|
||||
CLK(NULL, "hecc_ck", &hecc_ck, CK_AM35XX),
|
||||
CLK(NULL, "uart4_ick", &uart4_ick_am35xx, CK_AM35XX),
|
||||
};
|
||||
|
||||
|
||||
|
@ -3239,13 +3510,64 @@ int __init omap3xxx_clk_init(void)
|
|||
cpu_clkflg |= CK_3430ES2;
|
||||
}
|
||||
}
|
||||
if (omap3_has_192mhz_clk())
|
||||
omap_96m_alwon_fck = omap_96m_alwon_fck_3630;
|
||||
|
||||
if (cpu_is_omap3630()) {
|
||||
cpu_mask |= RATE_IN_36XX;
|
||||
cpu_clkflg |= CK_36XX;
|
||||
|
||||
/*
|
||||
* XXX This type of dynamic rewriting of the clock tree is
|
||||
* deprecated and should be revised soon.
|
||||
*/
|
||||
dpll4_m2_ck = dpll4_m2_ck_3630;
|
||||
dpll4_m3_ck = dpll4_m3_ck_3630;
|
||||
dpll4_m4_ck = dpll4_m4_ck_3630;
|
||||
dpll4_m5_ck = dpll4_m5_ck_3630;
|
||||
dpll4_m6_ck = dpll4_m6_ck_3630;
|
||||
|
||||
/*
|
||||
* For 3630: override clkops_omap2_dflt_wait for the
|
||||
* clocks affected from PWRDN reset Limitation
|
||||
*/
|
||||
dpll3_m3x2_ck.ops =
|
||||
&clkops_omap36xx_pwrdn_with_hsdiv_wait_restore;
|
||||
dpll4_m2x2_ck.ops =
|
||||
&clkops_omap36xx_pwrdn_with_hsdiv_wait_restore;
|
||||
dpll4_m3x2_ck.ops =
|
||||
&clkops_omap36xx_pwrdn_with_hsdiv_wait_restore;
|
||||
dpll4_m4x2_ck.ops =
|
||||
&clkops_omap36xx_pwrdn_with_hsdiv_wait_restore;
|
||||
dpll4_m5x2_ck.ops =
|
||||
&clkops_omap36xx_pwrdn_with_hsdiv_wait_restore;
|
||||
dpll4_m6x2_ck.ops =
|
||||
&clkops_omap36xx_pwrdn_with_hsdiv_wait_restore;
|
||||
} else {
|
||||
/*
|
||||
* XXX This type of dynamic rewriting of the clock tree is
|
||||
* deprecated and should be revised soon.
|
||||
*/
|
||||
dpll4_m2_ck = dpll4_m2_ck_34xx;
|
||||
dpll4_m3_ck = dpll4_m3_ck_34xx;
|
||||
dpll4_m4_ck = dpll4_m4_ck_34xx;
|
||||
dpll4_m5_ck = dpll4_m5_ck_34xx;
|
||||
dpll4_m6_ck = dpll4_m6_ck_34xx;
|
||||
}
|
||||
|
||||
if (cpu_is_omap3630())
|
||||
dpll4_dd = dpll4_dd_3630;
|
||||
else
|
||||
dpll4_dd = dpll4_dd_34xx;
|
||||
|
||||
clk_init(&omap2_clk_functions);
|
||||
|
||||
for (c = omap3xxx_clks; c < omap3xxx_clks + ARRAY_SIZE(omap3xxx_clks); c++)
|
||||
for (c = omap3xxx_clks; c < omap3xxx_clks + ARRAY_SIZE(omap3xxx_clks);
|
||||
c++)
|
||||
clk_preinit(c->lk.clk);
|
||||
|
||||
for (c = omap3xxx_clks; c < omap3xxx_clks + ARRAY_SIZE(omap3xxx_clks); c++)
|
||||
for (c = omap3xxx_clks; c < omap3xxx_clks + ARRAY_SIZE(omap3xxx_clks);
|
||||
c++)
|
||||
if (c->cpu & cpu_clkflg) {
|
||||
clkdev_add(&c->lk);
|
||||
clk_register(c->lk.clk);
|
|
@ -1,19 +0,0 @@
|
|||
/*
|
||||
* OMAP4-specific clock framework functions
|
||||
*
|
||||
* Copyright (C) 2009 Texas Instruments, Inc.
|
||||
*
|
||||
* Rajendra Nayak (rnayak@ti.com)
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <linux/errno.h>
|
||||
#include "clock.h"
|
||||
|
||||
const struct clkops omap4_clkops_noncore_dpll_ops = {
|
||||
.enable = &omap3_noncore_dpll_enable,
|
||||
.disable = &omap3_noncore_dpll_disable,
|
||||
};
|
|
@ -2,16 +2,19 @@
|
|||
* OMAP4 clock function prototypes and macros
|
||||
*
|
||||
* Copyright (C) 2009 Texas Instruments, Inc.
|
||||
* Copyright (C) 2010 Nokia Corporation
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK_44XX_H
|
||||
#define __ARCH_ARM_MACH_OMAP2_CLOCK_44XX_H
|
||||
#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK44XX_H
|
||||
#define __ARCH_ARM_MACH_OMAP2_CLOCK44XX_H
|
||||
|
||||
#define OMAP4430_MAX_DPLL_MULT 2048
|
||||
/*
|
||||
* XXX Missing values for the OMAP4 DPLL_USB
|
||||
* XXX Missing min_multiplier values for all OMAP4 DPLLs
|
||||
*/
|
||||
#define OMAP4430_MAX_DPLL_MULT 2047
|
||||
#define OMAP4430_MAX_DPLL_DIV 128
|
||||
|
||||
int omap4xxx_clk_init(void);
|
||||
|
||||
extern const struct clkops omap4_clkops_noncore_dpll_ops;
|
||||
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* OMAP2/3/4 clockdomain framework functions
|
||||
*
|
||||
* Copyright (C) 2008-2009 Texas Instruments, Inc.
|
||||
* Copyright (C) 2008-2009 Nokia Corporation
|
||||
* Copyright (C) 2008-2010 Texas Instruments, Inc.
|
||||
* Copyright (C) 2008-2010 Nokia Corporation
|
||||
*
|
||||
* Written by Paul Walmsley and Jouni Högander
|
||||
* Added OMAP4 specific support by Abhijit Pagare <abhijitpagare@ti.com>
|
||||
|
@ -173,6 +173,9 @@ static void _clkdm_add_autodeps(struct clockdomain *clkdm)
|
|||
{
|
||||
struct clkdm_autodep *autodep;
|
||||
|
||||
if (!autodeps)
|
||||
return;
|
||||
|
||||
for (autodep = autodeps; autodep->clkdm.ptr; autodep++) {
|
||||
if (IS_ERR(autodep->clkdm.ptr))
|
||||
continue;
|
||||
|
@ -201,6 +204,9 @@ static void _clkdm_del_autodeps(struct clockdomain *clkdm)
|
|||
{
|
||||
struct clkdm_autodep *autodep;
|
||||
|
||||
if (!autodeps)
|
||||
return;
|
||||
|
||||
for (autodep = autodeps; autodep->clkdm.ptr; autodep++) {
|
||||
if (IS_ERR(autodep->clkdm.ptr))
|
||||
continue;
|
||||
|
@ -891,8 +897,17 @@ void omap2_clkdm_allow_idle(struct clockdomain *clkdm)
|
|||
pr_debug("clockdomain: enabling automatic idle transitions for %s\n",
|
||||
clkdm->name);
|
||||
|
||||
/*
|
||||
* XXX This should be removed once TI adds wakeup/sleep
|
||||
* dependency code and data for OMAP4.
|
||||
*/
|
||||
if (cpu_is_omap44xx()) {
|
||||
WARN_ONCE(1, "clockdomain: OMAP4 wakeup/sleep dependency "
|
||||
"support is not yet implemented\n");
|
||||
} else {
|
||||
if (atomic_read(&clkdm->usecount) > 0)
|
||||
_clkdm_add_autodeps(clkdm);
|
||||
}
|
||||
|
||||
_omap2_clkdm_set_hwsup(clkdm, 1);
|
||||
|
||||
|
@ -924,8 +939,17 @@ void omap2_clkdm_deny_idle(struct clockdomain *clkdm)
|
|||
|
||||
_omap2_clkdm_set_hwsup(clkdm, 0);
|
||||
|
||||
/*
|
||||
* XXX This should be removed once TI adds wakeup/sleep
|
||||
* dependency code and data for OMAP4.
|
||||
*/
|
||||
if (cpu_is_omap44xx()) {
|
||||
WARN_ONCE(1, "clockdomain: OMAP4 wakeup/sleep dependency "
|
||||
"support is not yet implemented\n");
|
||||
} else {
|
||||
if (atomic_read(&clkdm->usecount) > 0)
|
||||
_clkdm_del_autodeps(clkdm);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -954,7 +978,7 @@ int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)
|
|||
* downstream clocks for debugging purposes?
|
||||
*/
|
||||
|
||||
if (!clkdm || !clk || !clkdm->clkstctrl_reg)
|
||||
if (!clkdm || !clk)
|
||||
return -EINVAL;
|
||||
|
||||
if (atomic_inc_return(&clkdm->usecount) > 1)
|
||||
|
@ -965,6 +989,9 @@ int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)
|
|||
pr_debug("clockdomain: clkdm %s: clk %s now enabled\n", clkdm->name,
|
||||
clk->name);
|
||||
|
||||
if (!clkdm->clkstctrl_reg)
|
||||
return 0;
|
||||
|
||||
v = omap2_clkdm_clktrctrl_read(clkdm);
|
||||
|
||||
if ((cpu_is_omap34xx() && v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) ||
|
||||
|
@ -1006,7 +1033,7 @@ int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk)
|
|||
* downstream clocks for debugging purposes?
|
||||
*/
|
||||
|
||||
if (!clkdm || !clk || !clkdm->clkstctrl_reg)
|
||||
if (!clkdm || !clk)
|
||||
return -EINVAL;
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -1024,6 +1051,9 @@ int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk)
|
|||
pr_debug("clockdomain: clkdm %s: clk %s now disabled\n", clkdm->name,
|
||||
clk->name);
|
||||
|
||||
if (!clkdm->clkstctrl_reg)
|
||||
return 0;
|
||||
|
||||
v = omap2_clkdm_clktrctrl_read(clkdm);
|
||||
|
||||
if ((cpu_is_omap34xx() && v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) ||
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
/* Bits specific to each register */
|
||||
|
||||
/* CM_FCLKEN_IVA2 */
|
||||
#define OMAP3430_CM_FCLKEN_IVA2_EN_IVA2 (1 << 0)
|
||||
#define OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_MASK (1 << 0)
|
||||
#define OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_SHIFT 0
|
||||
|
||||
/* CM_CLKEN_PLL_IVA2 */
|
||||
|
@ -168,6 +168,12 @@
|
|||
#define OMAP3430_EN_SDRC (1 << 1)
|
||||
#define OMAP3430_EN_SDRC_SHIFT 1
|
||||
|
||||
/* AM35XX specific CM_ICLKEN1_CORE bits */
|
||||
#define AM35XX_EN_IPSS_MASK (1 << 4)
|
||||
#define AM35XX_EN_IPSS_SHIFT 4
|
||||
#define AM35XX_EN_UART4_MASK (1 << 23)
|
||||
#define AM35XX_EN_UART4_SHIFT 23
|
||||
|
||||
/* CM_ICLKEN2_CORE */
|
||||
#define OMAP3430_EN_PKA (1 << 4)
|
||||
#define OMAP3430_EN_PKA_SHIFT 4
|
||||
|
@ -220,6 +226,10 @@
|
|||
#define OMAP3430_ST_SSI_STDBY_SHIFT 0
|
||||
#define OMAP3430_ST_SSI_STDBY_MASK (1 << 0)
|
||||
|
||||
/* AM35xx specific CM_IDLEST1_CORE bits */
|
||||
#define AM35XX_ST_IPSS_SHIFT 5
|
||||
#define AM35XX_ST_IPSS_MASK (1 << 5)
|
||||
|
||||
/* CM_IDLEST2_CORE */
|
||||
#define OMAP3430_ST_PKA_SHIFT 4
|
||||
#define OMAP3430_ST_PKA_MASK (1 << 4)
|
||||
|
@ -336,6 +346,8 @@
|
|||
#define OMAP3430_CLKSEL_L4_MASK (0x3 << 2)
|
||||
#define OMAP3430_CLKSEL_L3_SHIFT 0
|
||||
#define OMAP3430_CLKSEL_L3_MASK (0x3 << 0)
|
||||
#define OMAP3630_CLKSEL_96M_SHIFT 12
|
||||
#define OMAP3630_CLKSEL_96M_MASK (0x3 << 12)
|
||||
|
||||
/* CM_CLKSTCTRL_CORE */
|
||||
#define OMAP3430ES1_CLKTRCTRL_D2D_SHIFT 4
|
||||
|
@ -379,6 +391,10 @@
|
|||
#define OMAP3430ES2_CM_FCLKEN_SGX_EN_SGX_SHIFT 1
|
||||
#define OMAP3430ES2_CM_FCLKEN_SGX_EN_SGX_MASK (1 << 1)
|
||||
|
||||
/* CM_IDLEST_SGX */
|
||||
#define OMAP3430ES2_ST_SGX_SHIFT 1
|
||||
#define OMAP3430ES2_ST_SGX_MASK (1 << 1)
|
||||
|
||||
/* CM_ICLKEN_SGX */
|
||||
#define OMAP3430ES2_CM_ICLKEN_SGX_EN_SGX_SHIFT 0
|
||||
#define OMAP3430ES2_CM_ICLKEN_SGX_EN_SGX_MASK (1 << 0)
|
||||
|
@ -517,12 +533,18 @@
|
|||
/* CM_CLKSEL2_PLL */
|
||||
#define OMAP3430_PERIPH_DPLL_MULT_SHIFT 8
|
||||
#define OMAP3430_PERIPH_DPLL_MULT_MASK (0x7ff << 8)
|
||||
#define OMAP3630_PERIPH_DPLL_MULT_MASK (0xfff << 8)
|
||||
#define OMAP3430_PERIPH_DPLL_DIV_SHIFT 0
|
||||
#define OMAP3430_PERIPH_DPLL_DIV_MASK (0x7f << 0)
|
||||
#define OMAP3630_PERIPH_DPLL_DCO_SEL_SHIFT 21
|
||||
#define OMAP3630_PERIPH_DPLL_DCO_SEL_MASK (0x7 << 21)
|
||||
#define OMAP3630_PERIPH_DPLL_SD_DIV_SHIFT 24
|
||||
#define OMAP3630_PERIPH_DPLL_SD_DIV_MASK (0xff << 24)
|
||||
|
||||
/* CM_CLKSEL3_PLL */
|
||||
#define OMAP3430_DIV_96M_SHIFT 0
|
||||
#define OMAP3430_DIV_96M_MASK (0x1f << 0)
|
||||
#define OMAP3630_DIV_96M_MASK (0x3f << 0)
|
||||
|
||||
/* CM_CLKSEL4_PLL */
|
||||
#define OMAP3430ES2_PERIPH2_DPLL_MULT_SHIFT 8
|
||||
|
@ -569,8 +591,10 @@
|
|||
/* CM_CLKSEL_DSS */
|
||||
#define OMAP3430_CLKSEL_TV_SHIFT 8
|
||||
#define OMAP3430_CLKSEL_TV_MASK (0x1f << 8)
|
||||
#define OMAP3630_CLKSEL_TV_MASK (0x3f << 8)
|
||||
#define OMAP3430_CLKSEL_DSS1_SHIFT 0
|
||||
#define OMAP3430_CLKSEL_DSS1_MASK (0x1f << 0)
|
||||
#define OMAP3630_CLKSEL_DSS1_MASK (0x3f << 0)
|
||||
|
||||
/* CM_SLEEPDEP_DSS specific bits */
|
||||
|
||||
|
@ -598,6 +622,7 @@
|
|||
/* CM_CLKSEL_CAM */
|
||||
#define OMAP3430_CLKSEL_CAM_SHIFT 0
|
||||
#define OMAP3430_CLKSEL_CAM_MASK (0x1f << 0)
|
||||
#define OMAP3630_CLKSEL_CAM_MASK (0x3f << 0)
|
||||
|
||||
/* CM_SLEEPDEP_CAM specific bits */
|
||||
|
||||
|
@ -693,6 +718,7 @@
|
|||
/* CM_CLKSEL1_EMU */
|
||||
#define OMAP3430_DIV_DPLL4_SHIFT 24
|
||||
#define OMAP3430_DIV_DPLL4_MASK (0x1f << 24)
|
||||
#define OMAP3630_DIV_DPLL4_MASK (0x3f << 24)
|
||||
#define OMAP3430_DIV_DPLL3_SHIFT 16
|
||||
#define OMAP3430_DIV_DPLL3_MASK (0x1f << 16)
|
||||
#define OMAP3430_CLKSEL_TRACECLK_SHIFT 11
|
||||
|
|
|
@ -139,5 +139,8 @@ static inline u32 cm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx)
|
|||
/* CM_IDLEST_GFX */
|
||||
#define OMAP_ST_GFX (1 << 0)
|
||||
|
||||
/* CM_IDLEST indicator */
|
||||
#define OMAP24XX_CM_IDLEST_VAL 0
|
||||
#define OMAP34XX_CM_IDLEST_VAL 1
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
/*
|
||||
* OMAP3/4 - specific DPLL control functions
|
||||
*
|
||||
* Copyright (C) 2009 Texas Instruments, Inc.
|
||||
* Copyright (C) 2009 Nokia Corporation
|
||||
* Copyright (C) 2009-2010 Texas Instruments, Inc.
|
||||
* Copyright (C) 2009-2010 Nokia Corporation
|
||||
*
|
||||
* Written by Paul Walmsley
|
||||
* Testing and integration fixes by Jouni Högander
|
||||
* Testing and integration fixes by Jouni Högander
|
||||
*
|
||||
* 36xx support added by Vishwanath BS, Richard Woodruff, and Nishanth
|
||||
* Menon
|
||||
*
|
||||
* Parts of this code are based on code written by
|
||||
* Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu
|
||||
|
@ -15,7 +18,6 @@
|
|||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/list.h>
|
||||
|
@ -23,13 +25,10 @@
|
|||
#include <linux/delay.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/limits.h>
|
||||
#include <linux/bitops.h>
|
||||
|
||||
#include <plat/cpu.h>
|
||||
#include <plat/clock.h>
|
||||
#include <plat/sram.h>
|
||||
#include <asm/div64.h>
|
||||
#include <asm/clkdev.h>
|
||||
|
||||
#include "clock.h"
|
||||
|
@ -225,6 +224,47 @@ static int _omap3_noncore_dpll_stop(struct clk *clk)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* lookup_dco_sddiv - Set j-type DPLL4 compensation variables
|
||||
* @clk: pointer to a DPLL struct clk
|
||||
* @dco: digital control oscillator selector
|
||||
* @sd_div: target sigma-delta divider
|
||||
* @m: DPLL multiplier to set
|
||||
* @n: DPLL divider to set
|
||||
*
|
||||
* See 36xx TRM section 3.5.3.3.3.2 "Type B DPLL (Low-Jitter)"
|
||||
*
|
||||
* XXX This code is not needed for 3430/AM35xx; can it be optimized
|
||||
* out in non-multi-OMAP builds for those chips?
|
||||
*/
|
||||
static void lookup_dco_sddiv(struct clk *clk, u8 *dco, u8 *sd_div, u16 m,
|
||||
u8 n)
|
||||
{
|
||||
unsigned long fint, clkinp, sd; /* watch out for overflow */
|
||||
int mod1, mod2;
|
||||
|
||||
clkinp = clk->parent->rate;
|
||||
fint = (clkinp / n) * m;
|
||||
|
||||
if (fint < 1000000000)
|
||||
*dco = 2;
|
||||
else
|
||||
*dco = 4;
|
||||
/*
|
||||
* target sigma-delta to near 250MHz
|
||||
* sd = ceil[(m/(n+1)) * (clkinp_MHz / 250)]
|
||||
*/
|
||||
clkinp /= 100000; /* shift from MHz to 10*Hz for 38.4 and 19.2 */
|
||||
mod1 = (clkinp * m) % (250 * n);
|
||||
sd = (clkinp * m) / (250 * n);
|
||||
mod2 = sd % 10;
|
||||
sd /= 10;
|
||||
|
||||
if (mod1 || mod2)
|
||||
sd++;
|
||||
*sd_div = sd;
|
||||
}
|
||||
|
||||
/*
|
||||
* _omap3_noncore_dpll_program - set non-core DPLL M,N values directly
|
||||
* @clk: struct clk * of DPLL to set
|
||||
|
@ -243,8 +283,11 @@ static int omap3_noncore_dpll_program(struct clk *clk, u16 m, u8 n, u16 freqsel)
|
|||
/* 3430 ES2 TRM: 4.7.6.9 DPLL Programming Sequence */
|
||||
_omap3_noncore_dpll_bypass(clk);
|
||||
|
||||
/* Set jitter correction */
|
||||
if (!cpu_is_omap44xx()) {
|
||||
/*
|
||||
* Set jitter correction. No jitter correction for OMAP4 and 3630
|
||||
* since freqsel field is no longer present
|
||||
*/
|
||||
if (!cpu_is_omap44xx() && !cpu_is_omap3630()) {
|
||||
v = __raw_readl(dd->control_reg);
|
||||
v &= ~dd->freqsel_mask;
|
||||
v |= freqsel << __ffs(dd->freqsel_mask);
|
||||
|
@ -256,6 +299,21 @@ static int omap3_noncore_dpll_program(struct clk *clk, u16 m, u8 n, u16 freqsel)
|
|||
v &= ~(dd->mult_mask | dd->div1_mask);
|
||||
v |= m << __ffs(dd->mult_mask);
|
||||
v |= (n - 1) << __ffs(dd->div1_mask);
|
||||
|
||||
/*
|
||||
* XXX This code is not needed for 3430/AM35XX; can it be optimized
|
||||
* out in non-multi-OMAP builds for those chips?
|
||||
*/
|
||||
if ((dd->flags & DPLL_J_TYPE) && !(dd->flags & DPLL_NO_DCO_SEL)) {
|
||||
u8 dco, sd_div;
|
||||
lookup_dco_sddiv(clk, &dco, &sd_div, m, n);
|
||||
/* XXX This probably will need revision for OMAP4 */
|
||||
v &= ~(OMAP3630_PERIPH_DPLL_DCO_SEL_MASK
|
||||
| OMAP3630_PERIPH_DPLL_SD_DIV_MASK);
|
||||
v |= dco << __ffs(OMAP3630_PERIPH_DPLL_DCO_SEL_MASK);
|
||||
v |= sd_div << __ffs(OMAP3630_PERIPH_DPLL_SD_DIV_MASK);
|
||||
}
|
||||
|
||||
__raw_writel(v, dd->mult_div1_reg);
|
||||
|
||||
/* We let the clock framework set the other output dividers later */
|
||||
|
@ -387,8 +445,8 @@ int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate)
|
|||
if (dd->last_rounded_rate == 0)
|
||||
return -EINVAL;
|
||||
|
||||
/* No freqsel on OMAP4 */
|
||||
if (!cpu_is_omap44xx()) {
|
||||
/* No freqsel on OMAP4 and OMAP3630 */
|
||||
if (!cpu_is_omap44xx() && !cpu_is_omap3630()) {
|
||||
freqsel = _omap3_dpll_compute_freqsel(clk,
|
||||
dd->last_rounded_n);
|
||||
if (!freqsel)
|
||||
|
@ -533,7 +591,7 @@ unsigned long omap3_clkoutx2_recalc(struct clk *clk)
|
|||
|
||||
v = __raw_readl(dd->control_reg) & dd->enable_mask;
|
||||
v >>= __ffs(dd->enable_mask);
|
||||
if (v != OMAP3XXX_EN_DPLL_LOCKED)
|
||||
if ((v != OMAP3XXX_EN_DPLL_LOCKED) || (dd->flags & DPLL_J_TYPE))
|
||||
rate = clk->parent->rate;
|
||||
else
|
||||
rate = clk->parent->rate * 2;
|
||||
|
|
|
@ -177,6 +177,8 @@ void __init omap3_check_features(void)
|
|||
OMAP3_CHECK_FEATURE(status, SGX);
|
||||
OMAP3_CHECK_FEATURE(status, NEON);
|
||||
OMAP3_CHECK_FEATURE(status, ISP);
|
||||
if (cpu_is_omap3630())
|
||||
omap3_features |= OMAP3_HAS_192MHZ_CLK;
|
||||
|
||||
/*
|
||||
* TODO: Get additional info (where applicable)
|
||||
|
@ -361,6 +363,7 @@ void __init omap3_cpuinfo(void)
|
|||
OMAP3_SHOW_FEATURE(sgx);
|
||||
OMAP3_SHOW_FEATURE(neon);
|
||||
OMAP3_SHOW_FEATURE(isp);
|
||||
OMAP3_SHOW_FEATURE(192mhz_clk);
|
||||
|
||||
printk(")\n");
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
#include <plat/vram.h>
|
||||
|
||||
#include "clock2xxx.h"
|
||||
#include "clock34xx.h"
|
||||
#include "clock3xxx.h"
|
||||
#include "clock44xx.h"
|
||||
|
||||
#include <plat/omap-pm.h>
|
||||
|
@ -46,9 +46,6 @@
|
|||
#include <plat/clockdomain.h>
|
||||
#include "clockdomains.h"
|
||||
#include <plat/omap_hwmod.h>
|
||||
#include "omap_hwmod_2420.h"
|
||||
#include "omap_hwmod_2430.h"
|
||||
#include "omap_hwmod_34xx.h"
|
||||
|
||||
/*
|
||||
* The machine specific code may provide the extra mapping besides the
|
||||
|
@ -310,26 +307,24 @@ static int __init _omap2_init_reprogram_sdrc(void)
|
|||
void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
|
||||
struct omap_sdrc_params *sdrc_cs1)
|
||||
{
|
||||
struct omap_hwmod **hwmods = NULL;
|
||||
|
||||
if (cpu_is_omap2420())
|
||||
hwmods = omap2420_hwmods;
|
||||
else if (cpu_is_omap2430())
|
||||
hwmods = omap2430_hwmods;
|
||||
else if (cpu_is_omap34xx())
|
||||
hwmods = omap34xx_hwmods;
|
||||
|
||||
pwrdm_init(powerdomains_omap);
|
||||
clkdm_init(clockdomains_omap, clkdm_autodeps);
|
||||
#ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once the clkdev is ready */
|
||||
/* The OPP tables have to be registered before a clk init */
|
||||
omap_hwmod_init(hwmods);
|
||||
if (cpu_is_omap242x())
|
||||
omap2420_hwmod_init();
|
||||
else if (cpu_is_omap243x())
|
||||
omap2430_hwmod_init();
|
||||
else if (cpu_is_omap34xx())
|
||||
omap3xxx_hwmod_init();
|
||||
omap2_mux_init();
|
||||
/* The OPP tables have to be registered before a clk init */
|
||||
omap_pm_if_early_init(mpu_opps, dsp_opps, l3_opps);
|
||||
#endif
|
||||
|
||||
if (cpu_is_omap24xx())
|
||||
omap2xxx_clk_init();
|
||||
if (cpu_is_omap2420())
|
||||
omap2420_clk_init();
|
||||
else if (cpu_is_omap2430())
|
||||
omap2430_clk_init();
|
||||
else if (cpu_is_omap34xx())
|
||||
omap3xxx_clk_init();
|
||||
else if (cpu_is_omap44xx())
|
||||
|
|
|
@ -84,17 +84,16 @@ static u8 inited;
|
|||
*/
|
||||
static int _update_sysc_cache(struct omap_hwmod *oh)
|
||||
{
|
||||
if (!oh->sysconfig) {
|
||||
WARN(!oh->sysconfig, "omap_hwmod: %s: cannot read "
|
||||
"OCP_SYSCONFIG: not defined on hwmod\n", oh->name);
|
||||
if (!oh->class->sysc) {
|
||||
WARN(1, "omap_hwmod: %s: cannot read OCP_SYSCONFIG: not defined on hwmod's class\n", oh->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* XXX ensure module interface clock is up */
|
||||
|
||||
oh->_sysc_cache = omap_hwmod_readl(oh, oh->sysconfig->sysc_offs);
|
||||
oh->_sysc_cache = omap_hwmod_readl(oh, oh->class->sysc->sysc_offs);
|
||||
|
||||
if (!(oh->sysconfig->sysc_flags & SYSC_NO_CACHE))
|
||||
if (!(oh->class->sysc->sysc_flags & SYSC_NO_CACHE))
|
||||
oh->_int_flags |= _HWMOD_SYSCONFIG_LOADED;
|
||||
|
||||
return 0;
|
||||
|
@ -105,14 +104,13 @@ static int _update_sysc_cache(struct omap_hwmod *oh)
|
|||
* @v: OCP_SYSCONFIG value to write
|
||||
* @oh: struct omap_hwmod *
|
||||
*
|
||||
* Write @v into the module OCP_SYSCONFIG register, if it has one. No
|
||||
* return value.
|
||||
* Write @v into the module class' OCP_SYSCONFIG register, if it has
|
||||
* one. No return value.
|
||||
*/
|
||||
static void _write_sysconfig(u32 v, struct omap_hwmod *oh)
|
||||
{
|
||||
if (!oh->sysconfig) {
|
||||
WARN(!oh->sysconfig, "omap_hwmod: %s: cannot write "
|
||||
"OCP_SYSCONFIG: not defined on hwmod\n", oh->name);
|
||||
if (!oh->class->sysc) {
|
||||
WARN(1, "omap_hwmod: %s: cannot write OCP_SYSCONFIG: not defined on hwmod's class\n", oh->name);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -120,7 +118,7 @@ static void _write_sysconfig(u32 v, struct omap_hwmod *oh)
|
|||
|
||||
if (oh->_sysc_cache != v) {
|
||||
oh->_sysc_cache = v;
|
||||
omap_hwmod_writel(v, oh, oh->sysconfig->sysc_offs);
|
||||
omap_hwmod_writel(v, oh, oh->class->sysc->sysc_offs);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -137,12 +135,23 @@ static void _write_sysconfig(u32 v, struct omap_hwmod *oh)
|
|||
static int _set_master_standbymode(struct omap_hwmod *oh, u8 standbymode,
|
||||
u32 *v)
|
||||
{
|
||||
if (!oh->sysconfig ||
|
||||
!(oh->sysconfig->sysc_flags & SYSC_HAS_MIDLEMODE))
|
||||
u32 mstandby_mask;
|
||||
u8 mstandby_shift;
|
||||
|
||||
if (!oh->class->sysc ||
|
||||
!(oh->class->sysc->sysc_flags & SYSC_HAS_MIDLEMODE))
|
||||
return -EINVAL;
|
||||
|
||||
*v &= ~SYSC_MIDLEMODE_MASK;
|
||||
*v |= __ffs(standbymode) << SYSC_MIDLEMODE_SHIFT;
|
||||
if (!oh->class->sysc->sysc_fields) {
|
||||
WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mstandby_shift = oh->class->sysc->sysc_fields->midle_shift;
|
||||
mstandby_mask = (0x3 << mstandby_shift);
|
||||
|
||||
*v &= ~mstandby_mask;
|
||||
*v |= __ffs(standbymode) << mstandby_shift;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -159,12 +168,23 @@ static int _set_master_standbymode(struct omap_hwmod *oh, u8 standbymode,
|
|||
*/
|
||||
static int _set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode, u32 *v)
|
||||
{
|
||||
if (!oh->sysconfig ||
|
||||
!(oh->sysconfig->sysc_flags & SYSC_HAS_SIDLEMODE))
|
||||
u32 sidle_mask;
|
||||
u8 sidle_shift;
|
||||
|
||||
if (!oh->class->sysc ||
|
||||
!(oh->class->sysc->sysc_flags & SYSC_HAS_SIDLEMODE))
|
||||
return -EINVAL;
|
||||
|
||||
*v &= ~SYSC_SIDLEMODE_MASK;
|
||||
*v |= __ffs(idlemode) << SYSC_SIDLEMODE_SHIFT;
|
||||
if (!oh->class->sysc->sysc_fields) {
|
||||
WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sidle_shift = oh->class->sysc->sysc_fields->sidle_shift;
|
||||
sidle_mask = (0x3 << sidle_shift);
|
||||
|
||||
*v &= ~sidle_mask;
|
||||
*v |= __ffs(idlemode) << sidle_shift;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -182,12 +202,23 @@ static int _set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode, u32 *v)
|
|||
*/
|
||||
static int _set_clockactivity(struct omap_hwmod *oh, u8 clockact, u32 *v)
|
||||
{
|
||||
if (!oh->sysconfig ||
|
||||
!(oh->sysconfig->sysc_flags & SYSC_HAS_CLOCKACTIVITY))
|
||||
u32 clkact_mask;
|
||||
u8 clkact_shift;
|
||||
|
||||
if (!oh->class->sysc ||
|
||||
!(oh->class->sysc->sysc_flags & SYSC_HAS_CLOCKACTIVITY))
|
||||
return -EINVAL;
|
||||
|
||||
*v &= ~SYSC_CLOCKACTIVITY_MASK;
|
||||
*v |= clockact << SYSC_CLOCKACTIVITY_SHIFT;
|
||||
if (!oh->class->sysc->sysc_fields) {
|
||||
WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
clkact_shift = oh->class->sysc->sysc_fields->clkact_shift;
|
||||
clkact_mask = (0x3 << clkact_shift);
|
||||
|
||||
*v &= ~clkact_mask;
|
||||
*v |= clockact << clkact_shift;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -202,11 +233,20 @@ static int _set_clockactivity(struct omap_hwmod *oh, u8 clockact, u32 *v)
|
|||
*/
|
||||
static int _set_softreset(struct omap_hwmod *oh, u32 *v)
|
||||
{
|
||||
if (!oh->sysconfig ||
|
||||
!(oh->sysconfig->sysc_flags & SYSC_HAS_SOFTRESET))
|
||||
u32 softrst_mask;
|
||||
|
||||
if (!oh->class->sysc ||
|
||||
!(oh->class->sysc->sysc_flags & SYSC_HAS_SOFTRESET))
|
||||
return -EINVAL;
|
||||
|
||||
*v |= SYSC_SOFTRESET_MASK;
|
||||
if (!oh->class->sysc->sysc_fields) {
|
||||
WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
softrst_mask = (0x1 << oh->class->sysc->sysc_fields->srst_shift);
|
||||
|
||||
*v |= softrst_mask;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -227,12 +267,23 @@ static int _set_softreset(struct omap_hwmod *oh, u32 *v)
|
|||
static int _set_module_autoidle(struct omap_hwmod *oh, u8 autoidle,
|
||||
u32 *v)
|
||||
{
|
||||
if (!oh->sysconfig ||
|
||||
!(oh->sysconfig->sysc_flags & SYSC_HAS_AUTOIDLE))
|
||||
u32 autoidle_mask;
|
||||
u8 autoidle_shift;
|
||||
|
||||
if (!oh->class->sysc ||
|
||||
!(oh->class->sysc->sysc_flags & SYSC_HAS_AUTOIDLE))
|
||||
return -EINVAL;
|
||||
|
||||
*v &= ~SYSC_AUTOIDLE_MASK;
|
||||
*v |= autoidle << SYSC_AUTOIDLE_SHIFT;
|
||||
if (!oh->class->sysc->sysc_fields) {
|
||||
WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
autoidle_shift = oh->class->sysc->sysc_fields->autoidle_shift;
|
||||
autoidle_mask = (0x3 << autoidle_shift);
|
||||
|
||||
*v &= ~autoidle_mask;
|
||||
*v |= autoidle << autoidle_shift;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -246,14 +297,21 @@ static int _set_module_autoidle(struct omap_hwmod *oh, u8 autoidle,
|
|||
*/
|
||||
static int _enable_wakeup(struct omap_hwmod *oh)
|
||||
{
|
||||
u32 v;
|
||||
u32 v, wakeup_mask;
|
||||
|
||||
if (!oh->sysconfig ||
|
||||
!(oh->sysconfig->sysc_flags & SYSC_HAS_ENAWAKEUP))
|
||||
if (!oh->class->sysc ||
|
||||
!(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP))
|
||||
return -EINVAL;
|
||||
|
||||
if (!oh->class->sysc->sysc_fields) {
|
||||
WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
wakeup_mask = (0x1 << oh->class->sysc->sysc_fields->enwkup_shift);
|
||||
|
||||
v = oh->_sysc_cache;
|
||||
v |= SYSC_ENAWAKEUP_MASK;
|
||||
v |= wakeup_mask;
|
||||
_write_sysconfig(v, oh);
|
||||
|
||||
/* XXX test pwrdm_get_wken for this hwmod's subsystem */
|
||||
|
@ -272,14 +330,21 @@ static int _enable_wakeup(struct omap_hwmod *oh)
|
|||
*/
|
||||
static int _disable_wakeup(struct omap_hwmod *oh)
|
||||
{
|
||||
u32 v;
|
||||
u32 v, wakeup_mask;
|
||||
|
||||
if (!oh->sysconfig ||
|
||||
!(oh->sysconfig->sysc_flags & SYSC_HAS_ENAWAKEUP))
|
||||
if (!oh->class->sysc ||
|
||||
!(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP))
|
||||
return -EINVAL;
|
||||
|
||||
if (!oh->class->sysc->sysc_fields) {
|
||||
WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
wakeup_mask = (0x1 << oh->class->sysc->sysc_fields->enwkup_shift);
|
||||
|
||||
v = oh->_sysc_cache;
|
||||
v &= ~SYSC_ENAWAKEUP_MASK;
|
||||
v &= ~wakeup_mask;
|
||||
_write_sysconfig(v, oh);
|
||||
|
||||
/* XXX test pwrdm_get_wken for this hwmod's subsystem */
|
||||
|
@ -342,18 +407,18 @@ static int _init_main_clk(struct omap_hwmod *oh)
|
|||
struct clk *c;
|
||||
int ret = 0;
|
||||
|
||||
if (!oh->clkdev_con_id)
|
||||
if (!oh->main_clk)
|
||||
return 0;
|
||||
|
||||
c = clk_get_sys(oh->clkdev_dev_id, oh->clkdev_con_id);
|
||||
WARN(IS_ERR(c), "omap_hwmod: %s: cannot clk_get main_clk %s.%s\n",
|
||||
oh->name, oh->clkdev_dev_id, oh->clkdev_con_id);
|
||||
c = omap_clk_get_by_name(oh->main_clk);
|
||||
WARN(IS_ERR(c), "omap_hwmod: %s: cannot clk_get main_clk %s\n",
|
||||
oh->name, oh->main_clk);
|
||||
if (IS_ERR(c))
|
||||
ret = -EINVAL;
|
||||
oh->_clk = c;
|
||||
|
||||
WARN(!c->clkdm, "omap_hwmod: %s: missing clockdomain for %s.\n",
|
||||
oh->clkdev_con_id, c->name);
|
||||
oh->main_clk, c->name);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -376,13 +441,12 @@ static int _init_interface_clks(struct omap_hwmod *oh)
|
|||
return 0;
|
||||
|
||||
for (i = 0, os = *oh->slaves; i < oh->slaves_cnt; i++, os++) {
|
||||
if (!os->clkdev_con_id)
|
||||
if (!os->clk)
|
||||
continue;
|
||||
|
||||
c = clk_get_sys(os->clkdev_dev_id, os->clkdev_con_id);
|
||||
c = omap_clk_get_by_name(os->clk);
|
||||
WARN(IS_ERR(c), "omap_hwmod: %s: cannot clk_get "
|
||||
"interface_clk %s.%s\n", oh->name,
|
||||
os->clkdev_dev_id, os->clkdev_con_id);
|
||||
"interface_clk %s\n", oh->name, os->clk);
|
||||
if (IS_ERR(c))
|
||||
ret = -EINVAL;
|
||||
os->_clk = c;
|
||||
|
@ -406,10 +470,9 @@ static int _init_opt_clks(struct omap_hwmod *oh)
|
|||
int ret = 0;
|
||||
|
||||
for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++) {
|
||||
c = clk_get_sys(oc->clkdev_dev_id, oc->clkdev_con_id);
|
||||
c = omap_clk_get_by_name(oc->clk);
|
||||
WARN(IS_ERR(c), "omap_hwmod: %s: cannot clk_get opt_clk "
|
||||
"%s.%s\n", oh->name, oc->clkdev_dev_id,
|
||||
oc->clkdev_con_id);
|
||||
"%s\n", oh->name, oc->clk);
|
||||
if (IS_ERR(c))
|
||||
ret = -EINVAL;
|
||||
oc->_clk = c;
|
||||
|
@ -566,27 +629,28 @@ static void __iomem *_find_mpu_rt_base(struct omap_hwmod *oh, u8 index)
|
|||
*/
|
||||
static void _sysc_enable(struct omap_hwmod *oh)
|
||||
{
|
||||
u8 idlemode;
|
||||
u8 idlemode, sf;
|
||||
u32 v;
|
||||
|
||||
if (!oh->sysconfig)
|
||||
if (!oh->class->sysc)
|
||||
return;
|
||||
|
||||
v = oh->_sysc_cache;
|
||||
sf = oh->class->sysc->sysc_flags;
|
||||
|
||||
if (oh->sysconfig->sysc_flags & SYSC_HAS_SIDLEMODE) {
|
||||
if (sf & SYSC_HAS_SIDLEMODE) {
|
||||
idlemode = (oh->flags & HWMOD_SWSUP_SIDLE) ?
|
||||
HWMOD_IDLEMODE_NO : HWMOD_IDLEMODE_SMART;
|
||||
_set_slave_idlemode(oh, idlemode, &v);
|
||||
}
|
||||
|
||||
if (oh->sysconfig->sysc_flags & SYSC_HAS_MIDLEMODE) {
|
||||
if (sf & SYSC_HAS_MIDLEMODE) {
|
||||
idlemode = (oh->flags & HWMOD_SWSUP_MSTANDBY) ?
|
||||
HWMOD_IDLEMODE_NO : HWMOD_IDLEMODE_SMART;
|
||||
_set_master_standbymode(oh, idlemode, &v);
|
||||
}
|
||||
|
||||
if (oh->sysconfig->sysc_flags & SYSC_HAS_AUTOIDLE) {
|
||||
if (sf & SYSC_HAS_AUTOIDLE) {
|
||||
idlemode = (oh->flags & HWMOD_NO_OCP_AUTOIDLE) ?
|
||||
0 : 1;
|
||||
_set_module_autoidle(oh, idlemode, &v);
|
||||
|
@ -599,9 +663,9 @@ static void _sysc_enable(struct omap_hwmod *oh)
|
|||
* calling into this code. But this must wait until the
|
||||
* clock structures are tagged with omap_hwmod entries
|
||||
*/
|
||||
if (oh->flags & HWMOD_SET_DEFAULT_CLOCKACT &&
|
||||
oh->sysconfig->sysc_flags & SYSC_HAS_CLOCKACTIVITY)
|
||||
_set_clockactivity(oh, oh->sysconfig->clockact, &v);
|
||||
if ((oh->flags & HWMOD_SET_DEFAULT_CLOCKACT) &&
|
||||
(sf & SYSC_HAS_CLOCKACTIVITY))
|
||||
_set_clockactivity(oh, oh->class->sysc->clockact, &v);
|
||||
|
||||
_write_sysconfig(v, oh);
|
||||
}
|
||||
|
@ -617,21 +681,22 @@ static void _sysc_enable(struct omap_hwmod *oh)
|
|||
*/
|
||||
static void _sysc_idle(struct omap_hwmod *oh)
|
||||
{
|
||||
u8 idlemode;
|
||||
u8 idlemode, sf;
|
||||
u32 v;
|
||||
|
||||
if (!oh->sysconfig)
|
||||
if (!oh->class->sysc)
|
||||
return;
|
||||
|
||||
v = oh->_sysc_cache;
|
||||
sf = oh->class->sysc->sysc_flags;
|
||||
|
||||
if (oh->sysconfig->sysc_flags & SYSC_HAS_SIDLEMODE) {
|
||||
if (sf & SYSC_HAS_SIDLEMODE) {
|
||||
idlemode = (oh->flags & HWMOD_SWSUP_SIDLE) ?
|
||||
HWMOD_IDLEMODE_FORCE : HWMOD_IDLEMODE_SMART;
|
||||
_set_slave_idlemode(oh, idlemode, &v);
|
||||
}
|
||||
|
||||
if (oh->sysconfig->sysc_flags & SYSC_HAS_MIDLEMODE) {
|
||||
if (sf & SYSC_HAS_MIDLEMODE) {
|
||||
idlemode = (oh->flags & HWMOD_SWSUP_MSTANDBY) ?
|
||||
HWMOD_IDLEMODE_FORCE : HWMOD_IDLEMODE_SMART;
|
||||
_set_master_standbymode(oh, idlemode, &v);
|
||||
|
@ -650,19 +715,21 @@ static void _sysc_idle(struct omap_hwmod *oh)
|
|||
static void _sysc_shutdown(struct omap_hwmod *oh)
|
||||
{
|
||||
u32 v;
|
||||
u8 sf;
|
||||
|
||||
if (!oh->sysconfig)
|
||||
if (!oh->class->sysc)
|
||||
return;
|
||||
|
||||
v = oh->_sysc_cache;
|
||||
sf = oh->class->sysc->sysc_flags;
|
||||
|
||||
if (oh->sysconfig->sysc_flags & SYSC_HAS_SIDLEMODE)
|
||||
if (sf & SYSC_HAS_SIDLEMODE)
|
||||
_set_slave_idlemode(oh, HWMOD_IDLEMODE_FORCE, &v);
|
||||
|
||||
if (oh->sysconfig->sysc_flags & SYSC_HAS_MIDLEMODE)
|
||||
if (sf & SYSC_HAS_MIDLEMODE)
|
||||
_set_master_standbymode(oh, HWMOD_IDLEMODE_FORCE, &v);
|
||||
|
||||
if (oh->sysconfig->sysc_flags & SYSC_HAS_AUTOIDLE)
|
||||
if (sf & SYSC_HAS_AUTOIDLE)
|
||||
_set_module_autoidle(oh, 1, &v);
|
||||
|
||||
_write_sysconfig(v, oh);
|
||||
|
@ -779,9 +846,9 @@ static int _reset(struct omap_hwmod *oh)
|
|||
u32 r, v;
|
||||
int c = 0;
|
||||
|
||||
if (!oh->sysconfig ||
|
||||
!(oh->sysconfig->sysc_flags & SYSC_HAS_SOFTRESET) ||
|
||||
(oh->sysconfig->sysc_flags & SYSS_MISSING))
|
||||
if (!oh->class->sysc ||
|
||||
!(oh->class->sysc->sysc_flags & SYSC_HAS_SOFTRESET) ||
|
||||
(oh->class->sysc->sysc_flags & SYSS_MISSING))
|
||||
return -EINVAL;
|
||||
|
||||
/* clocks must be on for this operation */
|
||||
|
@ -799,7 +866,7 @@ static int _reset(struct omap_hwmod *oh)
|
|||
return r;
|
||||
_write_sysconfig(v, oh);
|
||||
|
||||
omap_test_timeout((omap_hwmod_readl(oh, oh->sysconfig->syss_offs) &
|
||||
omap_test_timeout((omap_hwmod_readl(oh, oh->class->sysc->syss_offs) &
|
||||
SYSS_RESETDONE_MASK),
|
||||
MAX_MODULE_RESET_WAIT, c);
|
||||
|
||||
|
@ -845,7 +912,7 @@ static int _enable(struct omap_hwmod *oh)
|
|||
_add_initiator_dep(oh, mpu_oh);
|
||||
_enable_clocks(oh);
|
||||
|
||||
if (oh->sysconfig) {
|
||||
if (oh->class->sysc) {
|
||||
if (!(oh->_int_flags & _HWMOD_SYSCONFIG_LOADED))
|
||||
_update_sysc_cache(oh);
|
||||
_sysc_enable(oh);
|
||||
|
@ -876,7 +943,7 @@ static int _idle(struct omap_hwmod *oh)
|
|||
|
||||
pr_debug("omap_hwmod: %s: idling\n", oh->name);
|
||||
|
||||
if (oh->sysconfig)
|
||||
if (oh->class->sysc)
|
||||
_sysc_idle(oh);
|
||||
_del_initiator_dep(oh, mpu_oh);
|
||||
_disable_clocks(oh);
|
||||
|
@ -906,7 +973,7 @@ static int _shutdown(struct omap_hwmod *oh)
|
|||
|
||||
pr_debug("omap_hwmod: %s: disabling\n", oh->name);
|
||||
|
||||
if (oh->sysconfig)
|
||||
if (oh->class->sysc)
|
||||
_sysc_shutdown(oh);
|
||||
_del_initiator_dep(oh, mpu_oh);
|
||||
/* XXX what about the other system initiators here? DMA, tesla, d2d */
|
||||
|
@ -966,7 +1033,7 @@ static int _setup(struct omap_hwmod *oh)
|
|||
* _enable() function should be split to avoid the
|
||||
* rewrite of the OCP_SYSCONFIG register.
|
||||
*/
|
||||
if (oh->sysconfig) {
|
||||
if (oh->class->sysc) {
|
||||
_update_sysc_cache(oh);
|
||||
_sysc_enable(oh);
|
||||
}
|
||||
|
@ -1013,9 +1080,12 @@ int omap_hwmod_set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode)
|
|||
* omap_hwmod_register - register a struct omap_hwmod
|
||||
* @oh: struct omap_hwmod *
|
||||
*
|
||||
* Registers the omap_hwmod @oh. Returns -EEXIST if an omap_hwmod already
|
||||
* has been registered by the same name; -EINVAL if the omap_hwmod is in the
|
||||
* wrong state, or 0 on success.
|
||||
* Registers the omap_hwmod @oh. Returns -EEXIST if an omap_hwmod
|
||||
* already has been registered by the same name; -EINVAL if the
|
||||
* omap_hwmod is in the wrong state, if @oh is NULL, if the
|
||||
* omap_hwmod's class field is NULL; if the omap_hwmod is missing a
|
||||
* name, or if the omap_hwmod's class is missing a name; or 0 upon
|
||||
* success.
|
||||
*
|
||||
* XXX The data should be copied into bootmem, so the original data
|
||||
* should be marked __initdata and freed after init. This would allow
|
||||
|
@ -1027,7 +1097,8 @@ int omap_hwmod_register(struct omap_hwmod *oh)
|
|||
{
|
||||
int ret, ms_id;
|
||||
|
||||
if (!oh || (oh->_state != _HWMOD_STATE_UNKNOWN))
|
||||
if (!oh || !oh->name || !oh->class || !oh->class->name ||
|
||||
(oh->_state != _HWMOD_STATE_UNKNOWN))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&omap_hwmod_mutex);
|
||||
|
@ -1300,7 +1371,7 @@ void omap_hwmod_ocp_barrier(struct omap_hwmod *oh)
|
|||
{
|
||||
BUG_ON(!oh);
|
||||
|
||||
if (!oh->sysconfig || !oh->sysconfig->sysc_flags) {
|
||||
if (!oh->class->sysc || !oh->class->sysc->sysc_flags) {
|
||||
WARN(1, "omap_device: %s: OCP barrier impossible due to "
|
||||
"device configuration\n", oh->name);
|
||||
return;
|
||||
|
@ -1310,7 +1381,7 @@ void omap_hwmod_ocp_barrier(struct omap_hwmod *oh)
|
|||
* Forces posted writes to complete on the OCP thread handling
|
||||
* register writes
|
||||
*/
|
||||
omap_hwmod_readl(oh, oh->sysconfig->sysc_offs);
|
||||
omap_hwmod_readl(oh, oh->class->sysc->sysc_offs);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1503,8 +1574,8 @@ int omap_hwmod_del_initiator_dep(struct omap_hwmod *oh,
|
|||
*/
|
||||
int omap_hwmod_enable_wakeup(struct omap_hwmod *oh)
|
||||
{
|
||||
if (!oh->sysconfig ||
|
||||
!(oh->sysconfig->sysc_flags & SYSC_HAS_ENAWAKEUP))
|
||||
if (!oh->class->sysc ||
|
||||
!(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&omap_hwmod_mutex);
|
||||
|
@ -1528,8 +1599,8 @@ int omap_hwmod_enable_wakeup(struct omap_hwmod *oh)
|
|||
*/
|
||||
int omap_hwmod_disable_wakeup(struct omap_hwmod *oh)
|
||||
{
|
||||
if (!oh->sysconfig ||
|
||||
!(oh->sysconfig->sysc_flags & SYSC_HAS_ENAWAKEUP))
|
||||
if (!oh->class->sysc ||
|
||||
!(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&omap_hwmod_mutex);
|
||||
|
@ -1538,3 +1609,52 @@ int omap_hwmod_disable_wakeup(struct omap_hwmod *oh)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* omap_hwmod_for_each_by_class - call @fn for each hwmod of class @classname
|
||||
* @classname: struct omap_hwmod_class name to search for
|
||||
* @fn: callback function pointer to call for each hwmod in class @classname
|
||||
* @user: arbitrary context data to pass to the callback function
|
||||
*
|
||||
* For each omap_hwmod of class @classname, call @fn. Takes
|
||||
* omap_hwmod_mutex to prevent the hwmod list from changing during the
|
||||
* iteration. If the callback function returns something other than
|
||||
* zero, the iterator is terminated, and the callback function's return
|
||||
* value is passed back to the caller. Returns 0 upon success, -EINVAL
|
||||
* if @classname or @fn are NULL, or passes back the error code from @fn.
|
||||
*/
|
||||
int omap_hwmod_for_each_by_class(const char *classname,
|
||||
int (*fn)(struct omap_hwmod *oh,
|
||||
void *user),
|
||||
void *user)
|
||||
{
|
||||
struct omap_hwmod *temp_oh;
|
||||
int ret = 0;
|
||||
|
||||
if (!classname || !fn)
|
||||
return -EINVAL;
|
||||
|
||||
pr_debug("omap_hwmod: %s: looking for modules of class %s\n",
|
||||
__func__, classname);
|
||||
|
||||
mutex_lock(&omap_hwmod_mutex);
|
||||
|
||||
list_for_each_entry(temp_oh, &omap_hwmod_list, node) {
|
||||
if (!strcmp(temp_oh->class->name, classname)) {
|
||||
pr_debug("omap_hwmod: %s: %s: calling callback fn\n",
|
||||
__func__, temp_oh->name);
|
||||
ret = (*fn)(temp_oh, user);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&omap_hwmod_mutex);
|
||||
|
||||
if (ret)
|
||||
pr_debug("omap_hwmod: %s: iterator terminated early: %d\n",
|
||||
__func__, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* omap_hwmod_2420.h - hardware modules present on the OMAP2420 chips
|
||||
* omap_hwmod_2420_data.c - hardware modules present on the OMAP2420 chips
|
||||
*
|
||||
* Copyright (C) 2009 Nokia Corporation
|
||||
* Copyright (C) 2009-2010 Nokia Corporation
|
||||
* Paul Walmsley
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
@ -9,20 +9,26 @@
|
|||
* published by the Free Software Foundation.
|
||||
*
|
||||
* XXX handle crossbar/shared link difference for L3?
|
||||
*
|
||||
* XXX these should be marked initdata for multi-OMAP kernels
|
||||
*/
|
||||
#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD2420_H
|
||||
#define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD2420_H
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP2420
|
||||
|
||||
#include <plat/omap_hwmod.h>
|
||||
#include <mach/irqs.h>
|
||||
#include <plat/cpu.h>
|
||||
#include <plat/dma.h>
|
||||
|
||||
#include "omap_hwmod_common_data.h"
|
||||
|
||||
#include "prm-regbits-24xx.h"
|
||||
|
||||
/*
|
||||
* OMAP2420 hardware module integration data
|
||||
*
|
||||
* ALl of the data in this section should be autogeneratable from the
|
||||
* TI hardware database or other technical documentation. Data that
|
||||
* is driver-specific or driver-kernel integration-specific belongs
|
||||
* elsewhere.
|
||||
*/
|
||||
|
||||
static struct omap_hwmod omap2420_mpu_hwmod;
|
||||
static struct omap_hwmod omap2420_l3_hwmod;
|
||||
static struct omap_hwmod omap2420_l4_core_hwmod;
|
||||
|
@ -54,6 +60,7 @@ static struct omap_hwmod_ocp_if *omap2420_l3_masters[] = {
|
|||
/* L3 */
|
||||
static struct omap_hwmod omap2420_l3_hwmod = {
|
||||
.name = "l3_hwmod",
|
||||
.class = &l3_hwmod_class,
|
||||
.masters = omap2420_l3_masters,
|
||||
.masters_cnt = ARRAY_SIZE(omap2420_l3_masters),
|
||||
.slaves = omap2420_l3_slaves,
|
||||
|
@ -83,6 +90,7 @@ static struct omap_hwmod_ocp_if *omap2420_l4_core_masters[] = {
|
|||
/* L4 CORE */
|
||||
static struct omap_hwmod omap2420_l4_core_hwmod = {
|
||||
.name = "l4_core_hwmod",
|
||||
.class = &l4_hwmod_class,
|
||||
.masters = omap2420_l4_core_masters,
|
||||
.masters_cnt = ARRAY_SIZE(omap2420_l4_core_masters),
|
||||
.slaves = omap2420_l4_core_slaves,
|
||||
|
@ -102,6 +110,7 @@ static struct omap_hwmod_ocp_if *omap2420_l4_wkup_masters[] = {
|
|||
/* L4 WKUP */
|
||||
static struct omap_hwmod omap2420_l4_wkup_hwmod = {
|
||||
.name = "l4_wkup_hwmod",
|
||||
.class = &l4_hwmod_class,
|
||||
.masters = omap2420_l4_wkup_masters,
|
||||
.masters_cnt = ARRAY_SIZE(omap2420_l4_wkup_masters),
|
||||
.slaves = omap2420_l4_wkup_slaves,
|
||||
|
@ -117,8 +126,8 @@ static struct omap_hwmod_ocp_if *omap2420_mpu_masters[] = {
|
|||
/* MPU */
|
||||
static struct omap_hwmod omap2420_mpu_hwmod = {
|
||||
.name = "mpu_hwmod",
|
||||
.clkdev_dev_id = NULL,
|
||||
.clkdev_con_id = "mpu_ck",
|
||||
.class = &mpu_hwmod_class,
|
||||
.main_clk = "mpu_ck",
|
||||
.masters = omap2420_mpu_masters,
|
||||
.masters_cnt = ARRAY_SIZE(omap2420_mpu_masters),
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
|
||||
|
@ -132,10 +141,9 @@ static __initdata struct omap_hwmod *omap2420_hwmods[] = {
|
|||
NULL,
|
||||
};
|
||||
|
||||
#else
|
||||
# define omap2420_hwmods 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
int __init omap2420_hwmod_init(void)
|
||||
{
|
||||
return omap_hwmod_init(omap2420_hwmods);
|
||||
}
|
||||
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* omap_hwmod_2430.h - hardware modules present on the OMAP2430 chips
|
||||
* omap_hwmod_2430_data.c - hardware modules present on the OMAP2430 chips
|
||||
*
|
||||
* Copyright (C) 2009 Nokia Corporation
|
||||
* Copyright (C) 2009-2010 Nokia Corporation
|
||||
* Paul Walmsley
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
@ -9,20 +9,26 @@
|
|||
* published by the Free Software Foundation.
|
||||
*
|
||||
* XXX handle crossbar/shared link difference for L3?
|
||||
*
|
||||
* XXX these should be marked initdata for multi-OMAP kernels
|
||||
*/
|
||||
#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD2430_H
|
||||
#define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD2430_H
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP2430
|
||||
|
||||
#include <plat/omap_hwmod.h>
|
||||
#include <mach/irqs.h>
|
||||
#include <plat/cpu.h>
|
||||
#include <plat/dma.h>
|
||||
|
||||
#include "omap_hwmod_common_data.h"
|
||||
|
||||
#include "prm-regbits-24xx.h"
|
||||
|
||||
/*
|
||||
* OMAP2430 hardware module integration data
|
||||
*
|
||||
* ALl of the data in this section should be autogeneratable from the
|
||||
* TI hardware database or other technical documentation. Data that
|
||||
* is driver-specific or driver-kernel integration-specific belongs
|
||||
* elsewhere.
|
||||
*/
|
||||
|
||||
static struct omap_hwmod omap2430_mpu_hwmod;
|
||||
static struct omap_hwmod omap2430_l3_hwmod;
|
||||
static struct omap_hwmod omap2430_l4_core_hwmod;
|
||||
|
@ -54,6 +60,7 @@ static struct omap_hwmod_ocp_if *omap2430_l3_masters[] = {
|
|||
/* L3 */
|
||||
static struct omap_hwmod omap2430_l3_hwmod = {
|
||||
.name = "l3_hwmod",
|
||||
.class = &l3_hwmod_class,
|
||||
.masters = omap2430_l3_masters,
|
||||
.masters_cnt = ARRAY_SIZE(omap2430_l3_masters),
|
||||
.slaves = omap2430_l3_slaves,
|
||||
|
@ -85,6 +92,7 @@ static struct omap_hwmod_ocp_if *omap2430_l4_core_masters[] = {
|
|||
/* L4 CORE */
|
||||
static struct omap_hwmod omap2430_l4_core_hwmod = {
|
||||
.name = "l4_core_hwmod",
|
||||
.class = &l4_hwmod_class,
|
||||
.masters = omap2430_l4_core_masters,
|
||||
.masters_cnt = ARRAY_SIZE(omap2430_l4_core_masters),
|
||||
.slaves = omap2430_l4_core_slaves,
|
||||
|
@ -104,6 +112,7 @@ static struct omap_hwmod_ocp_if *omap2430_l4_wkup_masters[] = {
|
|||
/* L4 WKUP */
|
||||
static struct omap_hwmod omap2430_l4_wkup_hwmod = {
|
||||
.name = "l4_wkup_hwmod",
|
||||
.class = &l4_hwmod_class,
|
||||
.masters = omap2430_l4_wkup_masters,
|
||||
.masters_cnt = ARRAY_SIZE(omap2430_l4_wkup_masters),
|
||||
.slaves = omap2430_l4_wkup_slaves,
|
||||
|
@ -119,8 +128,8 @@ static struct omap_hwmod_ocp_if *omap2430_mpu_masters[] = {
|
|||
/* MPU */
|
||||
static struct omap_hwmod omap2430_mpu_hwmod = {
|
||||
.name = "mpu_hwmod",
|
||||
.clkdev_dev_id = NULL,
|
||||
.clkdev_con_id = "mpu_ck",
|
||||
.class = &mpu_hwmod_class,
|
||||
.main_clk = "mpu_ck",
|
||||
.masters = omap2430_mpu_masters,
|
||||
.masters_cnt = ARRAY_SIZE(omap2430_mpu_masters),
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
|
||||
|
@ -134,10 +143,9 @@ static __initdata struct omap_hwmod *omap2430_hwmods[] = {
|
|||
NULL,
|
||||
};
|
||||
|
||||
#else
|
||||
# define omap2430_hwmods 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
int __init omap2430_hwmod_init(void)
|
||||
{
|
||||
return omap_hwmod_init(omap2430_hwmods);
|
||||
}
|
||||
|
||||
|
|
@ -1,168 +0,0 @@
|
|||
/*
|
||||
* omap_hwmod_34xx.h - hardware modules present on the OMAP34xx chips
|
||||
*
|
||||
* Copyright (C) 2009 Nokia Corporation
|
||||
* Paul Walmsley
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD34XX_H
|
||||
#define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD34XX_H
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP3
|
||||
|
||||
#include <plat/omap_hwmod.h>
|
||||
#include <mach/irqs.h>
|
||||
#include <plat/cpu.h>
|
||||
#include <plat/dma.h>
|
||||
|
||||
#include "prm-regbits-34xx.h"
|
||||
|
||||
static struct omap_hwmod omap34xx_mpu_hwmod;
|
||||
static struct omap_hwmod omap34xx_l3_hwmod;
|
||||
static struct omap_hwmod omap34xx_l4_core_hwmod;
|
||||
static struct omap_hwmod omap34xx_l4_per_hwmod;
|
||||
|
||||
/* L3 -> L4_CORE interface */
|
||||
static struct omap_hwmod_ocp_if omap34xx_l3__l4_core = {
|
||||
.master = &omap34xx_l3_hwmod,
|
||||
.slave = &omap34xx_l4_core_hwmod,
|
||||
.user = OCP_USER_MPU | OCP_USER_SDMA,
|
||||
};
|
||||
|
||||
/* L3 -> L4_PER interface */
|
||||
static struct omap_hwmod_ocp_if omap34xx_l3__l4_per = {
|
||||
.master = &omap34xx_l3_hwmod,
|
||||
.slave = &omap34xx_l4_per_hwmod,
|
||||
.user = OCP_USER_MPU | OCP_USER_SDMA,
|
||||
};
|
||||
|
||||
/* MPU -> L3 interface */
|
||||
static struct omap_hwmod_ocp_if omap34xx_mpu__l3 = {
|
||||
.master = &omap34xx_mpu_hwmod,
|
||||
.slave = &omap34xx_l3_hwmod,
|
||||
.user = OCP_USER_MPU,
|
||||
};
|
||||
|
||||
/* Slave interfaces on the L3 interconnect */
|
||||
static struct omap_hwmod_ocp_if *omap34xx_l3_slaves[] = {
|
||||
&omap34xx_mpu__l3,
|
||||
};
|
||||
|
||||
/* Master interfaces on the L3 interconnect */
|
||||
static struct omap_hwmod_ocp_if *omap34xx_l3_masters[] = {
|
||||
&omap34xx_l3__l4_core,
|
||||
&omap34xx_l3__l4_per,
|
||||
};
|
||||
|
||||
/* L3 */
|
||||
static struct omap_hwmod omap34xx_l3_hwmod = {
|
||||
.name = "l3_hwmod",
|
||||
.masters = omap34xx_l3_masters,
|
||||
.masters_cnt = ARRAY_SIZE(omap34xx_l3_masters),
|
||||
.slaves = omap34xx_l3_slaves,
|
||||
.slaves_cnt = ARRAY_SIZE(omap34xx_l3_slaves),
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
};
|
||||
|
||||
static struct omap_hwmod omap34xx_l4_wkup_hwmod;
|
||||
|
||||
/* L4_CORE -> L4_WKUP interface */
|
||||
static struct omap_hwmod_ocp_if omap34xx_l4_core__l4_wkup = {
|
||||
.master = &omap34xx_l4_core_hwmod,
|
||||
.slave = &omap34xx_l4_wkup_hwmod,
|
||||
.user = OCP_USER_MPU | OCP_USER_SDMA,
|
||||
};
|
||||
|
||||
/* Slave interfaces on the L4_CORE interconnect */
|
||||
static struct omap_hwmod_ocp_if *omap34xx_l4_core_slaves[] = {
|
||||
&omap34xx_l3__l4_core,
|
||||
};
|
||||
|
||||
/* Master interfaces on the L4_CORE interconnect */
|
||||
static struct omap_hwmod_ocp_if *omap34xx_l4_core_masters[] = {
|
||||
&omap34xx_l4_core__l4_wkup,
|
||||
};
|
||||
|
||||
/* L4 CORE */
|
||||
static struct omap_hwmod omap34xx_l4_core_hwmod = {
|
||||
.name = "l4_core_hwmod",
|
||||
.masters = omap34xx_l4_core_masters,
|
||||
.masters_cnt = ARRAY_SIZE(omap34xx_l4_core_masters),
|
||||
.slaves = omap34xx_l4_core_slaves,
|
||||
.slaves_cnt = ARRAY_SIZE(omap34xx_l4_core_slaves),
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
};
|
||||
|
||||
/* Slave interfaces on the L4_PER interconnect */
|
||||
static struct omap_hwmod_ocp_if *omap34xx_l4_per_slaves[] = {
|
||||
&omap34xx_l3__l4_per,
|
||||
};
|
||||
|
||||
/* Master interfaces on the L4_PER interconnect */
|
||||
static struct omap_hwmod_ocp_if *omap34xx_l4_per_masters[] = {
|
||||
};
|
||||
|
||||
/* L4 PER */
|
||||
static struct omap_hwmod omap34xx_l4_per_hwmod = {
|
||||
.name = "l4_per_hwmod",
|
||||
.masters = omap34xx_l4_per_masters,
|
||||
.masters_cnt = ARRAY_SIZE(omap34xx_l4_per_masters),
|
||||
.slaves = omap34xx_l4_per_slaves,
|
||||
.slaves_cnt = ARRAY_SIZE(omap34xx_l4_per_slaves),
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
};
|
||||
|
||||
/* Slave interfaces on the L4_WKUP interconnect */
|
||||
static struct omap_hwmod_ocp_if *omap34xx_l4_wkup_slaves[] = {
|
||||
&omap34xx_l4_core__l4_wkup,
|
||||
};
|
||||
|
||||
/* Master interfaces on the L4_WKUP interconnect */
|
||||
static struct omap_hwmod_ocp_if *omap34xx_l4_wkup_masters[] = {
|
||||
};
|
||||
|
||||
/* L4 WKUP */
|
||||
static struct omap_hwmod omap34xx_l4_wkup_hwmod = {
|
||||
.name = "l4_wkup_hwmod",
|
||||
.masters = omap34xx_l4_wkup_masters,
|
||||
.masters_cnt = ARRAY_SIZE(omap34xx_l4_wkup_masters),
|
||||
.slaves = omap34xx_l4_wkup_slaves,
|
||||
.slaves_cnt = ARRAY_SIZE(omap34xx_l4_wkup_slaves),
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
};
|
||||
|
||||
/* Master interfaces on the MPU device */
|
||||
static struct omap_hwmod_ocp_if *omap34xx_mpu_masters[] = {
|
||||
&omap34xx_mpu__l3,
|
||||
};
|
||||
|
||||
/* MPU */
|
||||
static struct omap_hwmod omap34xx_mpu_hwmod = {
|
||||
.name = "mpu_hwmod",
|
||||
.clkdev_dev_id = NULL,
|
||||
.clkdev_con_id = "arm_fck",
|
||||
.masters = omap34xx_mpu_masters,
|
||||
.masters_cnt = ARRAY_SIZE(omap34xx_mpu_masters),
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
|
||||
};
|
||||
|
||||
static __initdata struct omap_hwmod *omap34xx_hwmods[] = {
|
||||
&omap34xx_l3_hwmod,
|
||||
&omap34xx_l4_core_hwmod,
|
||||
&omap34xx_l4_per_hwmod,
|
||||
&omap34xx_l4_wkup_hwmod,
|
||||
&omap34xx_mpu_hwmod,
|
||||
NULL,
|
||||
};
|
||||
|
||||
#else
|
||||
# define omap34xx_hwmods 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
181
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
Normal file
181
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
Normal file
|
@ -0,0 +1,181 @@
|
|||
/*
|
||||
* omap_hwmod_3xxx_data.c - hardware modules present on the OMAP3xxx chips
|
||||
*
|
||||
* Copyright (C) 2009-2010 Nokia Corporation
|
||||
* Paul Walmsley
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* The data in this file should be completely autogeneratable from
|
||||
* the TI hardware database or other technical documentation.
|
||||
*
|
||||
* XXX these should be marked initdata for multi-OMAP kernels
|
||||
*/
|
||||
#include <plat/omap_hwmod.h>
|
||||
#include <mach/irqs.h>
|
||||
#include <plat/cpu.h>
|
||||
#include <plat/dma.h>
|
||||
|
||||
#include "omap_hwmod_common_data.h"
|
||||
|
||||
#include "prm-regbits-34xx.h"
|
||||
|
||||
/*
|
||||
* OMAP3xxx hardware module integration data
|
||||
*
|
||||
* ALl of the data in this section should be autogeneratable from the
|
||||
* TI hardware database or other technical documentation. Data that
|
||||
* is driver-specific or driver-kernel integration-specific belongs
|
||||
* elsewhere.
|
||||
*/
|
||||
|
||||
static struct omap_hwmod omap3xxx_mpu_hwmod;
|
||||
static struct omap_hwmod omap3xxx_l3_hwmod;
|
||||
static struct omap_hwmod omap3xxx_l4_core_hwmod;
|
||||
static struct omap_hwmod omap3xxx_l4_per_hwmod;
|
||||
|
||||
/* L3 -> L4_CORE interface */
|
||||
static struct omap_hwmod_ocp_if omap3xxx_l3__l4_core = {
|
||||
.master = &omap3xxx_l3_hwmod,
|
||||
.slave = &omap3xxx_l4_core_hwmod,
|
||||
.user = OCP_USER_MPU | OCP_USER_SDMA,
|
||||
};
|
||||
|
||||
/* L3 -> L4_PER interface */
|
||||
static struct omap_hwmod_ocp_if omap3xxx_l3__l4_per = {
|
||||
.master = &omap3xxx_l3_hwmod,
|
||||
.slave = &omap3xxx_l4_per_hwmod,
|
||||
.user = OCP_USER_MPU | OCP_USER_SDMA,
|
||||
};
|
||||
|
||||
/* MPU -> L3 interface */
|
||||
static struct omap_hwmod_ocp_if omap3xxx_mpu__l3 = {
|
||||
.master = &omap3xxx_mpu_hwmod,
|
||||
.slave = &omap3xxx_l3_hwmod,
|
||||
.user = OCP_USER_MPU,
|
||||
};
|
||||
|
||||
/* Slave interfaces on the L3 interconnect */
|
||||
static struct omap_hwmod_ocp_if *omap3xxx_l3_slaves[] = {
|
||||
&omap3xxx_mpu__l3,
|
||||
};
|
||||
|
||||
/* Master interfaces on the L3 interconnect */
|
||||
static struct omap_hwmod_ocp_if *omap3xxx_l3_masters[] = {
|
||||
&omap3xxx_l3__l4_core,
|
||||
&omap3xxx_l3__l4_per,
|
||||
};
|
||||
|
||||
/* L3 */
|
||||
static struct omap_hwmod omap3xxx_l3_hwmod = {
|
||||
.name = "l3_hwmod",
|
||||
.class = &l3_hwmod_class,
|
||||
.masters = omap3xxx_l3_masters,
|
||||
.masters_cnt = ARRAY_SIZE(omap3xxx_l3_masters),
|
||||
.slaves = omap3xxx_l3_slaves,
|
||||
.slaves_cnt = ARRAY_SIZE(omap3xxx_l3_slaves),
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
};
|
||||
|
||||
static struct omap_hwmod omap3xxx_l4_wkup_hwmod;
|
||||
|
||||
/* L4_CORE -> L4_WKUP interface */
|
||||
static struct omap_hwmod_ocp_if omap3xxx_l4_core__l4_wkup = {
|
||||
.master = &omap3xxx_l4_core_hwmod,
|
||||
.slave = &omap3xxx_l4_wkup_hwmod,
|
||||
.user = OCP_USER_MPU | OCP_USER_SDMA,
|
||||
};
|
||||
|
||||
/* Slave interfaces on the L4_CORE interconnect */
|
||||
static struct omap_hwmod_ocp_if *omap3xxx_l4_core_slaves[] = {
|
||||
&omap3xxx_l3__l4_core,
|
||||
};
|
||||
|
||||
/* Master interfaces on the L4_CORE interconnect */
|
||||
static struct omap_hwmod_ocp_if *omap3xxx_l4_core_masters[] = {
|
||||
&omap3xxx_l4_core__l4_wkup,
|
||||
};
|
||||
|
||||
/* L4 CORE */
|
||||
static struct omap_hwmod omap3xxx_l4_core_hwmod = {
|
||||
.name = "l4_core_hwmod",
|
||||
.class = &l4_hwmod_class,
|
||||
.masters = omap3xxx_l4_core_masters,
|
||||
.masters_cnt = ARRAY_SIZE(omap3xxx_l4_core_masters),
|
||||
.slaves = omap3xxx_l4_core_slaves,
|
||||
.slaves_cnt = ARRAY_SIZE(omap3xxx_l4_core_slaves),
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
};
|
||||
|
||||
/* Slave interfaces on the L4_PER interconnect */
|
||||
static struct omap_hwmod_ocp_if *omap3xxx_l4_per_slaves[] = {
|
||||
&omap3xxx_l3__l4_per,
|
||||
};
|
||||
|
||||
/* Master interfaces on the L4_PER interconnect */
|
||||
static struct omap_hwmod_ocp_if *omap3xxx_l4_per_masters[] = {
|
||||
};
|
||||
|
||||
/* L4 PER */
|
||||
static struct omap_hwmod omap3xxx_l4_per_hwmod = {
|
||||
.name = "l4_per_hwmod",
|
||||
.class = &l4_hwmod_class,
|
||||
.masters = omap3xxx_l4_per_masters,
|
||||
.masters_cnt = ARRAY_SIZE(omap3xxx_l4_per_masters),
|
||||
.slaves = omap3xxx_l4_per_slaves,
|
||||
.slaves_cnt = ARRAY_SIZE(omap3xxx_l4_per_slaves),
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
};
|
||||
|
||||
/* Slave interfaces on the L4_WKUP interconnect */
|
||||
static struct omap_hwmod_ocp_if *omap3xxx_l4_wkup_slaves[] = {
|
||||
&omap3xxx_l4_core__l4_wkup,
|
||||
};
|
||||
|
||||
/* Master interfaces on the L4_WKUP interconnect */
|
||||
static struct omap_hwmod_ocp_if *omap3xxx_l4_wkup_masters[] = {
|
||||
};
|
||||
|
||||
/* L4 WKUP */
|
||||
static struct omap_hwmod omap3xxx_l4_wkup_hwmod = {
|
||||
.name = "l4_wkup_hwmod",
|
||||
.class = &l4_hwmod_class,
|
||||
.masters = omap3xxx_l4_wkup_masters,
|
||||
.masters_cnt = ARRAY_SIZE(omap3xxx_l4_wkup_masters),
|
||||
.slaves = omap3xxx_l4_wkup_slaves,
|
||||
.slaves_cnt = ARRAY_SIZE(omap3xxx_l4_wkup_slaves),
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
};
|
||||
|
||||
/* Master interfaces on the MPU device */
|
||||
static struct omap_hwmod_ocp_if *omap3xxx_mpu_masters[] = {
|
||||
&omap3xxx_mpu__l3,
|
||||
};
|
||||
|
||||
/* MPU */
|
||||
static struct omap_hwmod omap3xxx_mpu_hwmod = {
|
||||
.name = "mpu_hwmod",
|
||||
.class = &mpu_hwmod_class,
|
||||
.main_clk = "arm_fck",
|
||||
.masters = omap3xxx_mpu_masters,
|
||||
.masters_cnt = ARRAY_SIZE(omap3xxx_mpu_masters),
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
|
||||
};
|
||||
|
||||
static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
|
||||
&omap3xxx_l3_hwmod,
|
||||
&omap3xxx_l4_core_hwmod,
|
||||
&omap3xxx_l4_per_hwmod,
|
||||
&omap3xxx_l4_wkup_hwmod,
|
||||
&omap3xxx_mpu_hwmod,
|
||||
NULL,
|
||||
};
|
||||
|
||||
int __init omap3xxx_hwmod_init(void)
|
||||
{
|
||||
return omap_hwmod_init(omap3xxx_hwmods);
|
||||
}
|
||||
|
||||
|
68
arch/arm/mach-omap2/omap_hwmod_common_data.c
Normal file
68
arch/arm/mach-omap2/omap_hwmod_common_data.c
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* omap_hwmod common data structures
|
||||
*
|
||||
* Copyright (C) 2010 Texas Instruments, Inc.
|
||||
* Thara Gopinath <thara@ti.com>
|
||||
* Benoît Cousson
|
||||
*
|
||||
* Copyright (C) 2010 Nokia Corporation
|
||||
* Paul Walmsley
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* This data/structures are to be used while defining OMAP on-chip module
|
||||
* data and their integration with other OMAP modules and Linux.
|
||||
*/
|
||||
|
||||
#include <plat/omap_hwmod.h>
|
||||
|
||||
#include "omap_hwmod_common_data.h"
|
||||
|
||||
/**
|
||||
* struct omap_hwmod_sysc_type1 - TYPE1 sysconfig scheme.
|
||||
*
|
||||
* To be used by hwmod structure to specify the sysconfig offsets
|
||||
* if the device ip is compliant with the original PRCM protocol
|
||||
* defined for OMAP2420.
|
||||
*/
|
||||
struct omap_hwmod_sysc_fields omap_hwmod_sysc_type1 = {
|
||||
.midle_shift = SYSC_TYPE1_MIDLEMODE_SHIFT,
|
||||
.clkact_shift = SYSC_TYPE1_CLOCKACTIVITY_SHIFT,
|
||||
.sidle_shift = SYSC_TYPE1_SIDLEMODE_SHIFT,
|
||||
.enwkup_shift = SYSC_TYPE1_ENAWAKEUP_SHIFT,
|
||||
.srst_shift = SYSC_TYPE1_SOFTRESET_SHIFT,
|
||||
.autoidle_shift = SYSC_TYPE1_AUTOIDLE_SHIFT,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct omap_hwmod_sysc_type2 - TYPE2 sysconfig scheme.
|
||||
*
|
||||
* To be used by hwmod structure to specify the sysconfig offsets if the
|
||||
* device ip is compliant with the new PRCM protocol defined for new
|
||||
* OMAP4 IPs.
|
||||
*/
|
||||
struct omap_hwmod_sysc_fields omap_hwmod_sysc_type2 = {
|
||||
.midle_shift = SYSC_TYPE2_MIDLEMODE_SHIFT,
|
||||
.sidle_shift = SYSC_TYPE2_SIDLEMODE_SHIFT,
|
||||
.srst_shift = SYSC_TYPE2_SOFTRESET_SHIFT,
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* omap_hwmod class data
|
||||
*/
|
||||
|
||||
struct omap_hwmod_class l3_hwmod_class = {
|
||||
.name = "l3"
|
||||
};
|
||||
|
||||
struct omap_hwmod_class l4_hwmod_class = {
|
||||
.name = "l4"
|
||||
};
|
||||
|
||||
struct omap_hwmod_class mpu_hwmod_class = {
|
||||
.name = "mpu"
|
||||
};
|
||||
|
24
arch/arm/mach-omap2/omap_hwmod_common_data.h
Normal file
24
arch/arm/mach-omap2/omap_hwmod_common_data.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* omap_hwmod_common_data.h - OMAP hwmod common macros and declarations
|
||||
*
|
||||
* Copyright (C) 2010 Nokia Corporation
|
||||
* Paul Walmsley
|
||||
*
|
||||
* Copyright (C) 2010 Texas Instruments, Inc.
|
||||
* Benoît Cousson
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef __ARCH_ARM_MACH_OMAP2_OMAP_HWMOD_COMMON_DATA_H
|
||||
#define __ARCH_ARM_MACH_OMAP2_OMAP_HWMOD_COMMON_DATA_H
|
||||
|
||||
#include <plat/omap_hwmod.h>
|
||||
|
||||
/* OMAP hwmod classes - forward declarations */
|
||||
extern struct omap_hwmod_class l3_hwmod_class;
|
||||
extern struct omap_hwmod_class l4_hwmod_class;
|
||||
extern struct omap_hwmod_class mpu_hwmod_class;
|
||||
|
||||
#endif
|
|
@ -385,6 +385,11 @@ static int pwrdm_dbg_show_counter(struct powerdomain *pwrdm, void *user)
|
|||
seq_printf(s, ",%s:%d", pwrdm_state_names[i],
|
||||
pwrdm->state_counter[i]);
|
||||
|
||||
seq_printf(s, ",RET-LOGIC-OFF:%d", pwrdm->ret_logic_off_counter);
|
||||
for (i = 0; i < pwrdm->banks; i++)
|
||||
seq_printf(s, ",RET-MEMBANK%d-OFF:%d", i + 1,
|
||||
pwrdm->ret_mem_off_counter[i]);
|
||||
|
||||
seq_printf(s, "\n");
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -688,7 +688,7 @@ static void __init omap3_iva_idle(void)
|
|||
OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
|
||||
|
||||
/* Enable IVA2 clock */
|
||||
cm_write_mod_reg(OMAP3430_CM_FCLKEN_IVA2_EN_IVA2,
|
||||
cm_write_mod_reg(OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_MASK,
|
||||
OMAP3430_IVA2_MOD, CM_FCLKEN);
|
||||
|
||||
/* Set IVA2 boot mode to 'idle' */
|
||||
|
|
|
@ -125,6 +125,10 @@ static int _pwrdm_register(struct powerdomain *pwrdm)
|
|||
for (i = 0; i < PWRDM_MAX_PWRSTS; i++)
|
||||
pwrdm->state_counter[i] = 0;
|
||||
|
||||
pwrdm->ret_logic_off_counter = 0;
|
||||
for (i = 0; i < pwrdm->banks; i++)
|
||||
pwrdm->ret_mem_off_counter[i] = 0;
|
||||
|
||||
pwrdm_wait_transition(pwrdm);
|
||||
pwrdm->state = pwrdm_read_pwrst(pwrdm);
|
||||
pwrdm->state_counter[pwrdm->state] = 1;
|
||||
|
@ -134,6 +138,25 @@ static int _pwrdm_register(struct powerdomain *pwrdm)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void _update_logic_membank_counters(struct powerdomain *pwrdm)
|
||||
{
|
||||
int i;
|
||||
u8 prev_logic_pwrst, prev_mem_pwrst;
|
||||
|
||||
prev_logic_pwrst = pwrdm_read_prev_logic_pwrst(pwrdm);
|
||||
if ((pwrdm->pwrsts_logic_ret == PWRSTS_OFF_RET) &&
|
||||
(prev_logic_pwrst == PWRDM_POWER_OFF))
|
||||
pwrdm->ret_logic_off_counter++;
|
||||
|
||||
for (i = 0; i < pwrdm->banks; i++) {
|
||||
prev_mem_pwrst = pwrdm_read_prev_mem_pwrst(pwrdm, i);
|
||||
|
||||
if ((pwrdm->pwrsts_mem_ret[i] == PWRSTS_OFF_RET) &&
|
||||
(prev_mem_pwrst == PWRDM_POWER_OFF))
|
||||
pwrdm->ret_mem_off_counter[i]++;
|
||||
}
|
||||
}
|
||||
|
||||
static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag)
|
||||
{
|
||||
|
||||
|
@ -153,6 +176,8 @@ static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag)
|
|||
prev = pwrdm_read_prev_pwrst(pwrdm);
|
||||
if (pwrdm->state != prev)
|
||||
pwrdm->state_counter[prev]++;
|
||||
if (prev == PWRDM_POWER_RET)
|
||||
_update_logic_membank_counters(pwrdm);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
|
@ -678,6 +703,29 @@ int pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm)
|
|||
OMAP3430_LASTLOGICSTATEENTERED);
|
||||
}
|
||||
|
||||
/**
|
||||
* pwrdm_read_logic_retst - get next powerdomain logic power state
|
||||
* @pwrdm: struct powerdomain * to get next logic power state
|
||||
*
|
||||
* Return the powerdomain pwrdm's logic power state. Returns -EINVAL
|
||||
* if the powerdomain pointer is null or returns the next logic
|
||||
* power state upon success.
|
||||
*/
|
||||
int pwrdm_read_logic_retst(struct powerdomain *pwrdm)
|
||||
{
|
||||
if (!pwrdm)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* The register bit names below may not correspond to the
|
||||
* actual names of the bits in each powerdomain's register,
|
||||
* but the type of value returned is the same for each
|
||||
* powerdomain.
|
||||
*/
|
||||
return prm_read_mod_bits_shift(pwrdm->prcm_offs, pwrstctrl_reg_offs,
|
||||
OMAP3430_LOGICSTATEST);
|
||||
}
|
||||
|
||||
/**
|
||||
* pwrdm_read_mem_pwrst - get current memory bank power state
|
||||
* @pwrdm: struct powerdomain * to get current memory bank power state
|
||||
|
@ -784,6 +832,56 @@ int pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
|
|||
OMAP3430_PM_PREPWSTST, m);
|
||||
}
|
||||
|
||||
/**
|
||||
* pwrdm_read_mem_retst - get next memory bank power state
|
||||
* @pwrdm: struct powerdomain * to get mext memory bank power state
|
||||
* @bank: memory bank number (0-3)
|
||||
*
|
||||
* Return the powerdomain pwrdm's next memory power state for bank
|
||||
* x. Returns -EINVAL if the powerdomain pointer is null, -EEXIST if
|
||||
* the target memory bank does not exist or is not controllable, or
|
||||
* returns the next memory power state upon success.
|
||||
*/
|
||||
int pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank)
|
||||
{
|
||||
u32 m;
|
||||
|
||||
if (!pwrdm)
|
||||
return -EINVAL;
|
||||
|
||||
if (pwrdm->banks < (bank + 1))
|
||||
return -EEXIST;
|
||||
|
||||
/*
|
||||
* The register bit names below may not correspond to the
|
||||
* actual names of the bits in each powerdomain's register,
|
||||
* but the type of value returned is the same for each
|
||||
* powerdomain.
|
||||
*/
|
||||
switch (bank) {
|
||||
case 0:
|
||||
m = OMAP_MEM0_RETSTATE_MASK;
|
||||
break;
|
||||
case 1:
|
||||
m = OMAP_MEM1_RETSTATE_MASK;
|
||||
break;
|
||||
case 2:
|
||||
m = OMAP_MEM2_RETSTATE_MASK;
|
||||
break;
|
||||
case 3:
|
||||
m = OMAP_MEM3_RETSTATE_MASK;
|
||||
break;
|
||||
case 4:
|
||||
m = OMAP_MEM4_RETSTATE_MASK;
|
||||
default:
|
||||
WARN_ON(1); /* should never happen */
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
return prm_read_mod_bits_shift(pwrdm->prcm_offs,
|
||||
pwrstctrl_reg_offs, m);
|
||||
}
|
||||
|
||||
/**
|
||||
* pwrdm_clear_all_prev_pwrst - clear previous powerstate register for a pwrdm
|
||||
* @pwrdm: struct powerdomain * to clear
|
||||
|
|
|
@ -82,6 +82,7 @@ static struct powerdomain core_3xxx_pre_es3_1_pwrdm = {
|
|||
CHIP_IS_OMAP3430ES2 |
|
||||
CHIP_IS_OMAP3430ES3_0),
|
||||
.pwrsts = PWRSTS_OFF_RET_ON,
|
||||
.pwrsts_logic_ret = PWRSTS_OFF_RET,
|
||||
.banks = 2,
|
||||
.pwrsts_mem_ret = {
|
||||
[0] = PWRSTS_OFF_RET, /* MEM1RETSTATE */
|
||||
|
@ -98,6 +99,7 @@ static struct powerdomain core_3xxx_es3_1_pwrdm = {
|
|||
.prcm_offs = CORE_MOD,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES3_1),
|
||||
.pwrsts = PWRSTS_OFF_RET_ON,
|
||||
.pwrsts_logic_ret = PWRSTS_OFF_RET,
|
||||
.flags = PWRDM_HAS_HDWR_SAR, /* for USBTLL only */
|
||||
.banks = 2,
|
||||
.pwrsts_mem_ret = {
|
||||
|
|
|
@ -127,13 +127,15 @@ u32 omap_prcm_get_reset_sources(void)
|
|||
return prm_read_mod_reg(WKUP_MOD, OMAP2_RM_RSTST) & 0x7f;
|
||||
if (cpu_is_omap44xx())
|
||||
return prm_read_mod_reg(WKUP_MOD, OMAP4_RM_RSTST) & 0x7f;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(omap_prcm_get_reset_sources);
|
||||
|
||||
/* Resets clock rates and reboots the system. Only called from system.h */
|
||||
void omap_prcm_arch_reset(char mode)
|
||||
{
|
||||
s16 prcm_offs;
|
||||
s16 prcm_offs = 0;
|
||||
|
||||
if (cpu_is_omap24xx()) {
|
||||
omap2xxx_clk_prepare_for_reboot();
|
||||
|
@ -242,26 +244,22 @@ u32 cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx)
|
|||
* omap2_cm_wait_idlest - wait for IDLEST bit to indicate module readiness
|
||||
* @reg: physical address of module IDLEST register
|
||||
* @mask: value to mask against to determine if the module is active
|
||||
* @idlest: idle state indicator (0 or 1) for the clock
|
||||
* @name: name of the clock (for printk)
|
||||
*
|
||||
* Returns 1 if the module indicated readiness in time, or 0 if it
|
||||
* failed to enable in roughly MAX_MODULE_ENABLE_WAIT microseconds.
|
||||
*/
|
||||
int omap2_cm_wait_idlest(void __iomem *reg, u32 mask, const char *name)
|
||||
int omap2_cm_wait_idlest(void __iomem *reg, u32 mask, u8 idlest,
|
||||
const char *name)
|
||||
{
|
||||
int i = 0;
|
||||
int ena = 0;
|
||||
|
||||
/*
|
||||
* 24xx uses 0 to indicate not ready, and 1 to indicate ready.
|
||||
* 34xx reverses this, just to keep us on our toes
|
||||
*/
|
||||
if (cpu_is_omap24xx())
|
||||
ena = mask;
|
||||
else if (cpu_is_omap34xx())
|
||||
if (idlest)
|
||||
ena = 0;
|
||||
else
|
||||
BUG();
|
||||
ena = mask;
|
||||
|
||||
/* Wait for lock */
|
||||
omap_test_timeout(((__raw_readl(reg) & mask) == ena),
|
||||
|
|
|
@ -85,8 +85,6 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode mode,
|
|||
case CLOCK_EVT_MODE_PERIODIC:
|
||||
period = clk_get_rate(omap_dm_timer_get_fclk(gptimer)) / HZ;
|
||||
period -= 1;
|
||||
if (cpu_is_omap44xx())
|
||||
period = 0xff; /* FIXME: */
|
||||
omap_dm_timer_set_load_start(gptimer, 1, 0xffffffff - period);
|
||||
break;
|
||||
case CLOCK_EVT_MODE_ONESHOT:
|
||||
|
@ -150,9 +148,6 @@ static void __init omap2_gp_clockevent_init(void)
|
|||
"timer-gp: omap_dm_timer_set_source() failed\n");
|
||||
|
||||
tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer));
|
||||
if (cpu_is_omap44xx())
|
||||
/* Assuming 32kHz clk is driving GPT1 */
|
||||
tick_rate = 32768; /* FIXME: */
|
||||
|
||||
pr_info("OMAP clockevent source: GPTIMER%d at %u Hz\n",
|
||||
gptimer_id, tick_rate);
|
||||
|
|
|
@ -313,6 +313,33 @@ void clk_enable_init_clocks(void)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* omap_clk_get_by_name - locate OMAP struct clk by its name
|
||||
* @name: name of the struct clk to locate
|
||||
*
|
||||
* Locate an OMAP struct clk by its name. Assumes that struct clk
|
||||
* names are unique. Returns NULL if not found or a pointer to the
|
||||
* struct clk if found.
|
||||
*/
|
||||
struct clk *omap_clk_get_by_name(const char *name)
|
||||
{
|
||||
struct clk *c;
|
||||
struct clk *ret = NULL;
|
||||
|
||||
mutex_lock(&clocks_mutex);
|
||||
|
||||
list_for_each_entry(c, &clocks, node) {
|
||||
if (!strcmp(c->name, name)) {
|
||||
ret = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&clocks_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Low level helpers
|
||||
*/
|
||||
|
@ -330,6 +357,16 @@ const struct clkops clkops_null = {
|
|||
.disable = clkll_disable_null,
|
||||
};
|
||||
|
||||
/*
|
||||
* Dummy clock
|
||||
*
|
||||
* Used for clock aliases that are needed on some OMAPs, but not others
|
||||
*/
|
||||
struct clk dummy_ck = {
|
||||
.name = "dummy",
|
||||
.ops = &clkops_null,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_CPU_FREQ
|
||||
void clk_init_cpufreq_table(struct cpufreq_frequency_table **table)
|
||||
{
|
||||
|
@ -408,8 +445,6 @@ static int clk_debugfs_register_one(struct clk *c)
|
|||
char *p = s;
|
||||
|
||||
p += sprintf(p, "%s", c->name);
|
||||
if (c->id != 0)
|
||||
sprintf(p, ":%d", c->id);
|
||||
d = debugfs_create_dir(s, pa ? pa->dent : clk_debugfs_root);
|
||||
if (!d)
|
||||
return -ENOMEM;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* arch/arm/plat-omap/include/mach/clock.h
|
||||
* OMAP clock: data structure definitions, function prototypes, shared macros
|
||||
*
|
||||
* Copyright (C) 2004 - 2005 Nokia corporation
|
||||
* Copyright (C) 2004-2005, 2008-2010 Nokia Corporation
|
||||
* Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
|
||||
* Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, Inc
|
||||
*
|
||||
|
@ -22,8 +22,10 @@ struct clockdomain;
|
|||
struct clkops {
|
||||
int (*enable)(struct clk *);
|
||||
void (*disable)(struct clk *);
|
||||
void (*find_idlest)(struct clk *, void __iomem **, u8 *);
|
||||
void (*find_companion)(struct clk *, void __iomem **, u8 *);
|
||||
void (*find_idlest)(struct clk *, void __iomem **,
|
||||
u8 *, u8 *);
|
||||
void (*find_companion)(struct clk *, void __iomem **,
|
||||
u8 *);
|
||||
};
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP2PLUS
|
||||
|
@ -39,6 +41,50 @@ struct clksel {
|
|||
const struct clksel_rate *rates;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct dpll_data - DPLL registers and integration data
|
||||
* @mult_div1_reg: register containing the DPLL M and N bitfields
|
||||
* @mult_mask: mask of the DPLL M bitfield in @mult_div1_reg
|
||||
* @div1_mask: mask of the DPLL N bitfield in @mult_div1_reg
|
||||
* @clk_bypass: struct clk pointer to the clock's bypass clock input
|
||||
* @clk_ref: struct clk pointer to the clock's reference clock input
|
||||
* @control_reg: register containing the DPLL mode bitfield
|
||||
* @enable_mask: mask of the DPLL mode bitfield in @control_reg
|
||||
* @rate_tolerance: maximum variance allowed from target rate (in Hz)
|
||||
* @last_rounded_rate: cache of the last rate result of omap2_dpll_round_rate()
|
||||
* @last_rounded_m: cache of the last M result of omap2_dpll_round_rate()
|
||||
* @max_multiplier: maximum valid non-bypass multiplier value (actual)
|
||||
* @last_rounded_n: cache of the last N result of omap2_dpll_round_rate()
|
||||
* @min_divider: minimum valid non-bypass divider value (actual)
|
||||
* @max_divider: maximum valid non-bypass divider value (actual)
|
||||
* @modes: possible values of @enable_mask
|
||||
* @autoidle_reg: register containing the DPLL autoidle mode bitfield
|
||||
* @idlest_reg: register containing the DPLL idle status bitfield
|
||||
* @autoidle_mask: mask of the DPLL autoidle mode bitfield in @autoidle_reg
|
||||
* @freqsel_mask: mask of the DPLL jitter correction bitfield in @control_reg
|
||||
* @idlest_mask: mask of the DPLL idle status bitfield in @idlest_reg
|
||||
* @auto_recal_bit: bitshift of the driftguard enable bit in @control_reg
|
||||
* @recal_en_bit: bitshift of the PRM_IRQENABLE_* bit for recalibration IRQs
|
||||
* @recal_st_bit: bitshift of the PRM_IRQSTATUS_* bit for recalibration IRQs
|
||||
* @flags: DPLL type/features (see below)
|
||||
*
|
||||
* Possible values for @flags:
|
||||
* DPLL_J_TYPE: "J-type DPLL" (only some 36xx, 4xxx DPLLs)
|
||||
* NO_DCO_SEL: don't program DCO (only for some J-type DPLLs)
|
||||
|
||||
* @freqsel_mask is only used on the OMAP34xx family and AM35xx.
|
||||
*
|
||||
* XXX Some DPLLs have multiple bypass inputs, so it's not technically
|
||||
* correct to only have one @clk_bypass pointer.
|
||||
*
|
||||
* XXX @rate_tolerance should probably be deprecated - currently there
|
||||
* don't seem to be any usecases for DPLL rounding that is not exact.
|
||||
*
|
||||
* XXX The runtime-variable fields (@last_rounded_rate, @last_rounded_m,
|
||||
* @last_rounded_n) should be separated from the runtime-fixed fields
|
||||
* and placed into a differenct structure, so that the runtime-fixed data
|
||||
* can be placed into read-only space.
|
||||
*/
|
||||
struct dpll_data {
|
||||
void __iomem *mult_div1_reg;
|
||||
u32 mult_mask;
|
||||
|
@ -50,13 +96,12 @@ struct dpll_data {
|
|||
unsigned int rate_tolerance;
|
||||
unsigned long last_rounded_rate;
|
||||
u16 last_rounded_m;
|
||||
u16 max_multiplier;
|
||||
u8 last_rounded_n;
|
||||
u8 min_divider;
|
||||
u8 max_divider;
|
||||
u32 max_tolerance;
|
||||
u16 max_multiplier;
|
||||
#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
|
||||
u8 modes;
|
||||
#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
|
||||
void __iomem *autoidle_reg;
|
||||
void __iomem *idlest_reg;
|
||||
u32 autoidle_mask;
|
||||
|
@ -65,6 +110,7 @@ struct dpll_data {
|
|||
u8 auto_recal_bit;
|
||||
u8 recal_en_bit;
|
||||
u8 recal_st_bit;
|
||||
u8 flags;
|
||||
# endif
|
||||
};
|
||||
|
||||
|
@ -74,12 +120,10 @@ struct clk {
|
|||
struct list_head node;
|
||||
const struct clkops *ops;
|
||||
const char *name;
|
||||
int id;
|
||||
struct clk *parent;
|
||||
struct list_head children;
|
||||
struct list_head sibling; /* node for children */
|
||||
unsigned long rate;
|
||||
__u32 flags;
|
||||
void __iomem *enable_reg;
|
||||
unsigned long (*recalc)(struct clk *);
|
||||
int (*set_rate)(struct clk *, unsigned long);
|
||||
|
@ -88,6 +132,7 @@ struct clk {
|
|||
__u8 enable_bit;
|
||||
__s8 usecount;
|
||||
u8 fixed_div;
|
||||
u8 flags;
|
||||
#ifdef CONFIG_ARCH_OMAP2PLUS
|
||||
void __iomem *clksel_reg;
|
||||
u32 clksel_mask;
|
||||
|
@ -137,23 +182,18 @@ unsigned long omap_fixed_divisor_recalc(struct clk *clk);
|
|||
extern void clk_init_cpufreq_table(struct cpufreq_frequency_table **table);
|
||||
extern void clk_exit_cpufreq_table(struct cpufreq_frequency_table **table);
|
||||
#endif
|
||||
extern struct clk *omap_clk_get_by_name(const char *name);
|
||||
|
||||
extern const struct clkops clkops_null;
|
||||
|
||||
extern struct clk dummy_ck;
|
||||
|
||||
/* Clock flags */
|
||||
/* bit 0 is free */
|
||||
#define RATE_FIXED (1 << 1) /* Fixed clock rate */
|
||||
/* bits 2-4 are free */
|
||||
#define ENABLE_REG_32BIT (1 << 5) /* Use 32-bit access */
|
||||
#define CLOCK_IDLE_CONTROL (1 << 7)
|
||||
#define CLOCK_NO_IDLE_PARENT (1 << 8)
|
||||
#define DELAYED_APP (1 << 9) /* Delay application of clock */
|
||||
#define CONFIG_PARTICIPANT (1 << 10) /* Fundamental clock */
|
||||
#define ENABLE_ON_INIT (1 << 11) /* Enable upon framework init */
|
||||
#define INVERT_ENABLE (1 << 12) /* 0 enables, 1 disables */
|
||||
#define CLOCK_IN_OMAP4430 (1 << 13)
|
||||
#define ALWAYS_ENABLED (1 << 14)
|
||||
/* bits 13-31 are currently free */
|
||||
#define ENABLE_REG_32BIT (1 << 0) /* Use 32-bit access */
|
||||
#define CLOCK_IDLE_CONTROL (1 << 1)
|
||||
#define CLOCK_NO_IDLE_PARENT (1 << 2)
|
||||
#define ENABLE_ON_INIT (1 << 3) /* Enable upon framework init */
|
||||
#define INVERT_ENABLE (1 << 4) /* 0 enables, 1 disables */
|
||||
|
||||
/* Clksel_rate flags */
|
||||
#define DEFAULT_RATE (1 << 0)
|
||||
|
@ -161,7 +201,8 @@ extern const struct clkops clkops_null;
|
|||
#define RATE_IN_243X (1 << 2)
|
||||
#define RATE_IN_343X (1 << 3) /* rates common to all 343X */
|
||||
#define RATE_IN_3430ES2 (1 << 4) /* 3430ES2 rates only */
|
||||
#define RATE_IN_4430 (1 << 5)
|
||||
#define RATE_IN_36XX (1 << 5)
|
||||
#define RATE_IN_4430 (1 << 6)
|
||||
|
||||
#define RATE_IN_24XX (RATE_IN_242X | RATE_IN_243X)
|
||||
|
||||
|
|
|
@ -439,6 +439,7 @@ extern u32 omap3_features;
|
|||
#define OMAP3_HAS_SGX BIT(2)
|
||||
#define OMAP3_HAS_NEON BIT(3)
|
||||
#define OMAP3_HAS_ISP BIT(4)
|
||||
#define OMAP3_HAS_192MHZ_CLK BIT(5)
|
||||
|
||||
#define OMAP3_HAS_FEATURE(feat,flag) \
|
||||
static inline unsigned int omap3_has_ ##feat(void) \
|
||||
|
@ -451,5 +452,6 @@ OMAP3_HAS_FEATURE(sgx, SGX)
|
|||
OMAP3_HAS_FEATURE(iva, IVA)
|
||||
OMAP3_HAS_FEATURE(neon, NEON)
|
||||
OMAP3_HAS_FEATURE(isp, ISP)
|
||||
OMAP3_HAS_FEATURE(192mhz_clk, 192MHZ_CLK)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -62,6 +62,7 @@
|
|||
*
|
||||
*/
|
||||
struct omap_device {
|
||||
u32 magic;
|
||||
struct platform_device pdev;
|
||||
struct omap_hwmod **hwmods;
|
||||
struct omap_device_pm_latency *pm_lats;
|
||||
|
@ -81,6 +82,7 @@ int omap_device_shutdown(struct platform_device *pdev);
|
|||
|
||||
/* Core code interface */
|
||||
|
||||
bool omap_device_is_valid(struct omap_device *od);
|
||||
int omap_device_count_resources(struct omap_device *od);
|
||||
int omap_device_fill_resources(struct omap_device *od, struct resource *res);
|
||||
|
||||
|
@ -88,15 +90,16 @@ struct omap_device *omap_device_build(const char *pdev_name, int pdev_id,
|
|||
struct omap_hwmod *oh, void *pdata,
|
||||
int pdata_len,
|
||||
struct omap_device_pm_latency *pm_lats,
|
||||
int pm_lats_cnt);
|
||||
int pm_lats_cnt, int is_early_device);
|
||||
|
||||
struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
|
||||
struct omap_hwmod **oh, int oh_cnt,
|
||||
void *pdata, int pdata_len,
|
||||
struct omap_device_pm_latency *pm_lats,
|
||||
int pm_lats_cnt);
|
||||
int pm_lats_cnt, int is_early_device);
|
||||
|
||||
int omap_device_register(struct omap_device *od);
|
||||
int omap_early_device_register(struct omap_device *od);
|
||||
|
||||
/* OMAP PM interface */
|
||||
int omap_device_align_pm_lat(struct platform_device *pdev,
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* Copyright (C) 2009 Nokia Corporation
|
||||
* Paul Walmsley
|
||||
*
|
||||
* Created in collaboration with (alphabetical order): Benoit Cousson,
|
||||
* Created in collaboration with (alphabetical order): Benoît Cousson,
|
||||
* Kevin Hilman, Tony Lindgren, Rajendra Nayak, Vikram Pandita, Sakari
|
||||
* Poussa, Anand Sawant, Santosh Shilimkar, Richard Woodruff
|
||||
*
|
||||
|
@ -33,25 +33,42 @@
|
|||
#define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD_H
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/ioport.h>
|
||||
|
||||
#include <plat/cpu.h>
|
||||
|
||||
struct omap_device;
|
||||
|
||||
/* OCP SYSCONFIG bit shifts/masks */
|
||||
#define SYSC_MIDLEMODE_SHIFT 12
|
||||
#define SYSC_MIDLEMODE_MASK (0x3 << SYSC_MIDLEMODE_SHIFT)
|
||||
#define SYSC_CLOCKACTIVITY_SHIFT 8
|
||||
#define SYSC_CLOCKACTIVITY_MASK (0x3 << SYSC_CLOCKACTIVITY_SHIFT)
|
||||
#define SYSC_SIDLEMODE_SHIFT 3
|
||||
#define SYSC_SIDLEMODE_MASK (0x3 << SYSC_SIDLEMODE_SHIFT)
|
||||
#define SYSC_ENAWAKEUP_SHIFT 2
|
||||
#define SYSC_ENAWAKEUP_MASK (1 << SYSC_ENAWAKEUP_SHIFT)
|
||||
#define SYSC_SOFTRESET_SHIFT 1
|
||||
#define SYSC_SOFTRESET_MASK (1 << SYSC_SOFTRESET_SHIFT)
|
||||
#define SYSC_AUTOIDLE_SHIFT 0
|
||||
#define SYSC_AUTOIDLE_MASK (1 << SYSC_AUTOIDLE_SHIFT)
|
||||
extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type1;
|
||||
extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type2;
|
||||
|
||||
/*
|
||||
* OCP SYSCONFIG bit shifts/masks TYPE1. These are for IPs compliant
|
||||
* with the original PRCM protocol defined for OMAP2420
|
||||
*/
|
||||
#define SYSC_TYPE1_MIDLEMODE_SHIFT 12
|
||||
#define SYSC_TYPE1_MIDLEMODE_MASK (0x3 << SYSC_MIDLEMODE_SHIFT)
|
||||
#define SYSC_TYPE1_CLOCKACTIVITY_SHIFT 8
|
||||
#define SYSC_TYPE1_CLOCKACTIVITY_MASK (0x3 << SYSC_CLOCKACTIVITY_SHIFT)
|
||||
#define SYSC_TYPE1_SIDLEMODE_SHIFT 3
|
||||
#define SYSC_TYPE1_SIDLEMODE_MASK (0x3 << SYSC_SIDLEMODE_SHIFT)
|
||||
#define SYSC_TYPE1_ENAWAKEUP_SHIFT 2
|
||||
#define SYSC_TYPE1_ENAWAKEUP_MASK (1 << SYSC_ENAWAKEUP_SHIFT)
|
||||
#define SYSC_TYPE1_SOFTRESET_SHIFT 1
|
||||
#define SYSC_TYPE1_SOFTRESET_MASK (1 << SYSC_SOFTRESET_SHIFT)
|
||||
#define SYSC_TYPE1_AUTOIDLE_SHIFT 0
|
||||
#define SYSC_TYPE1_AUTOIDLE_MASK (1 << SYSC_AUTOIDLE_SHIFT)
|
||||
|
||||
/*
|
||||
* OCP SYSCONFIG bit shifts/masks TYPE2. These are for IPs compliant
|
||||
* with the new PRCM protocol defined for new OMAP4 IPs.
|
||||
*/
|
||||
#define SYSC_TYPE2_SOFTRESET_SHIFT 0
|
||||
#define SYSC_TYPE2_SOFTRESET_MASK (1 << SYSC_TYPE2_SOFTRESET_SHIFT)
|
||||
#define SYSC_TYPE2_SIDLEMODE_SHIFT 2
|
||||
#define SYSC_TYPE2_SIDLEMODE_MASK (0x3 << SYSC_TYPE2_SIDLEMODE_SHIFT)
|
||||
#define SYSC_TYPE2_MIDLEMODE_SHIFT 4
|
||||
#define SYSC_TYPE2_MIDLEMODE_MASK (0x3 << SYSC_TYPE2_MIDLEMODE_SHIFT)
|
||||
|
||||
/* OCP SYSSTATUS bit shifts/masks */
|
||||
#define SYSS_RESETDONE_SHIFT 0
|
||||
|
@ -62,7 +79,6 @@ struct omap_device;
|
|||
#define HWMOD_IDLEMODE_NO (1 << 1)
|
||||
#define HWMOD_IDLEMODE_SMART (1 << 2)
|
||||
|
||||
|
||||
/**
|
||||
* struct omap_hwmod_irq_info - MPU IRQs used by the hwmod
|
||||
* @name: name of the IRQ channel (module local name)
|
||||
|
@ -94,8 +110,7 @@ struct omap_hwmod_dma_info {
|
|||
/**
|
||||
* struct omap_hwmod_opt_clk - optional clocks used by this hwmod
|
||||
* @role: "sys", "32k", "tv", etc -- for use in clk_get()
|
||||
* @clkdev_dev_id: opt clock: clkdev dev_id string
|
||||
* @clkdev_con_id: opt clock: clkdev con_id string
|
||||
* @clk: opt clock: OMAP clock name
|
||||
* @_clk: pointer to the struct clk (filled in at runtime)
|
||||
*
|
||||
* The module's interface clock and main functional clock should not
|
||||
|
@ -103,8 +118,7 @@ struct omap_hwmod_dma_info {
|
|||
*/
|
||||
struct omap_hwmod_opt_clk {
|
||||
const char *role;
|
||||
const char *clkdev_dev_id;
|
||||
const char *clkdev_con_id;
|
||||
const char *clk;
|
||||
struct clk *_clk;
|
||||
};
|
||||
|
||||
|
@ -171,8 +185,7 @@ struct omap_hwmod_addr_space {
|
|||
* @master: struct omap_hwmod that initiates OCP transactions on this link
|
||||
* @slave: struct omap_hwmod that responds to OCP transactions on this link
|
||||
* @addr: address space associated with this link
|
||||
* @clkdev_dev_id: interface clock: clkdev dev_id string
|
||||
* @clkdev_con_id: interface clock: clkdev con_id string
|
||||
* @clk: interface clock: OMAP clock name
|
||||
* @_clk: pointer to the interface struct clk (filled in at runtime)
|
||||
* @fw: interface firewall data
|
||||
* @addr_cnt: ARRAY_SIZE(@addr)
|
||||
|
@ -191,8 +204,7 @@ struct omap_hwmod_ocp_if {
|
|||
struct omap_hwmod *master;
|
||||
struct omap_hwmod *slave;
|
||||
struct omap_hwmod_addr_space *addr;
|
||||
const char *clkdev_dev_id;
|
||||
const char *clkdev_con_id;
|
||||
const char *clk;
|
||||
struct clk *_clk;
|
||||
union {
|
||||
struct omap_hwmod_omap2_firewall omap2;
|
||||
|
@ -236,7 +248,25 @@ struct omap_hwmod_ocp_if {
|
|||
#define CLOCKACT_TEST_NONE 0x3
|
||||
|
||||
/**
|
||||
* struct omap_hwmod_sysconfig - hwmod OCP_SYSCONFIG/OCP_SYSSTATUS data
|
||||
* struct omap_hwmod_sysc_fields - hwmod OCP_SYSCONFIG register field offsets.
|
||||
* @midle_shift: Offset of the midle bit
|
||||
* @clkact_shift: Offset of the clockactivity bit
|
||||
* @sidle_shift: Offset of the sidle bit
|
||||
* @enwkup_shift: Offset of the enawakeup bit
|
||||
* @srst_shift: Offset of the softreset bit
|
||||
* @autoidle_shift: Offset of the autoidle bit
|
||||
*/
|
||||
struct omap_hwmod_sysc_fields {
|
||||
u8 midle_shift;
|
||||
u8 clkact_shift;
|
||||
u8 sidle_shift;
|
||||
u8 enwkup_shift;
|
||||
u8 srst_shift;
|
||||
u8 autoidle_shift;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct omap_hwmod_class_sysconfig - hwmod class OCP_SYS* data
|
||||
* @rev_offs: IP block revision register offset (from module base addr)
|
||||
* @sysc_offs: OCP_SYSCONFIG register offset (from module base addr)
|
||||
* @syss_offs: OCP_SYSSTATUS register offset (from module base addr)
|
||||
|
@ -252,14 +282,22 @@ struct omap_hwmod_ocp_if {
|
|||
* been associated with the clocks marked in @clockact. This field is
|
||||
* only used if HWMOD_SET_DEFAULT_CLOCKACT is set (see below)
|
||||
*
|
||||
* @sysc_fields: structure containing the offset positions of various bits in
|
||||
* SYSCONFIG register. This can be populated using omap_hwmod_sysc_type1 or
|
||||
* omap_hwmod_sysc_type2 defined in omap_hwmod_common_data.c depending on
|
||||
* whether the device ip is compliant with the original PRCM protocol
|
||||
* defined for OMAP2420 or the new PRCM protocol for new OMAP4 IPs.
|
||||
* If the device follows a different scheme for the sysconfig register ,
|
||||
* then this field has to be populated with the correct offset structure.
|
||||
*/
|
||||
struct omap_hwmod_sysconfig {
|
||||
struct omap_hwmod_class_sysconfig {
|
||||
u16 rev_offs;
|
||||
u16 sysc_offs;
|
||||
u16 syss_offs;
|
||||
u8 idlemodes;
|
||||
u8 sysc_flags;
|
||||
u8 clockact;
|
||||
struct omap_hwmod_sysc_fields *sysc_fields;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -351,20 +389,34 @@ struct omap_hwmod_omap4_prcm {
|
|||
#define _HWMOD_STATE_IDLE 5
|
||||
#define _HWMOD_STATE_DISABLED 6
|
||||
|
||||
/**
|
||||
* struct omap_hwmod_class - the type of an IP block
|
||||
* @name: name of the hwmod_class
|
||||
* @sysc: device SYSCONFIG/SYSSTATUS register data
|
||||
* @rev: revision of the IP class
|
||||
*
|
||||
* Represent the class of a OMAP hardware "modules" (e.g. timer,
|
||||
* smartreflex, gpio, uart...)
|
||||
*/
|
||||
struct omap_hwmod_class {
|
||||
const char *name;
|
||||
struct omap_hwmod_class_sysconfig *sysc;
|
||||
u32 rev;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct omap_hwmod - integration data for OMAP hardware "modules" (IP blocks)
|
||||
* @name: name of the hwmod
|
||||
* @class: struct omap_hwmod_class * to the class of this hwmod
|
||||
* @od: struct omap_device currently associated with this hwmod (internal use)
|
||||
* @mpu_irqs: ptr to an array of MPU IRQs (see also mpu_irqs_cnt)
|
||||
* @sdma_chs: ptr to an array of SDMA channel IDs (see also sdma_chs_cnt)
|
||||
* @prcm: PRCM data pertaining to this hwmod
|
||||
* @clkdev_dev_id: main clock: clkdev dev_id string
|
||||
* @clkdev_con_id: main clock: clkdev con_id string
|
||||
* @main_clk: main clock: OMAP clock name
|
||||
* @_clk: pointer to the main struct clk (filled in at runtime)
|
||||
* @opt_clks: other device clocks that drivers can request (0..*)
|
||||
* @masters: ptr to array of OCP ifs that this hwmod can initiate on
|
||||
* @slaves: ptr to array of OCP ifs that this hwmod can respond on
|
||||
* @sysconfig: device SYSCONFIG/SYSSTATUS register data
|
||||
* @dev_attr: arbitrary device attributes that can be passed to the driver
|
||||
* @_sysc_cache: internal-use hwmod flags
|
||||
* @_rt_va: cached register target start address (internal use)
|
||||
|
@ -383,16 +435,17 @@ struct omap_hwmod_omap4_prcm {
|
|||
* @omap_chip: OMAP chips this hwmod is present on
|
||||
* @node: list node for hwmod list (internal use)
|
||||
*
|
||||
* @clkdev_dev_id, @clkdev_con_id, and @clk all refer to this module's "main
|
||||
* clock," which for our purposes is defined as "the functional clock needed
|
||||
* for register accesses to complete." Modules may not have a main clock if
|
||||
* the interface clock also serves as a main clock.
|
||||
* @main_clk refers to this module's "main clock," which for our
|
||||
* purposes is defined as "the functional clock needed for register
|
||||
* accesses to complete." Modules may not have a main clock if the
|
||||
* interface clock also serves as a main clock.
|
||||
*
|
||||
* Parameter names beginning with an underscore are managed internally by
|
||||
* the omap_hwmod code and should not be set during initialization.
|
||||
*/
|
||||
struct omap_hwmod {
|
||||
const char *name;
|
||||
struct omap_hwmod_class *class;
|
||||
struct omap_device *od;
|
||||
struct omap_hwmod_irq_info *mpu_irqs;
|
||||
struct omap_hwmod_dma_info *sdma_chs;
|
||||
|
@ -400,13 +453,11 @@ struct omap_hwmod {
|
|||
struct omap_hwmod_omap2_prcm omap2;
|
||||
struct omap_hwmod_omap4_prcm omap4;
|
||||
} prcm;
|
||||
const char *clkdev_dev_id;
|
||||
const char *clkdev_con_id;
|
||||
const char *main_clk;
|
||||
struct clk *_clk;
|
||||
struct omap_hwmod_opt_clk *opt_clks;
|
||||
struct omap_hwmod_ocp_if **masters; /* connect to *_IA */
|
||||
struct omap_hwmod_ocp_if **slaves; /* connect to *_TA */
|
||||
struct omap_hwmod_sysconfig *sysconfig;
|
||||
void *dev_attr;
|
||||
u32 _sysc_cache;
|
||||
void __iomem *_rt_va;
|
||||
|
@ -467,4 +518,17 @@ int omap_hwmod_set_clockact_none(struct omap_hwmod *oh);
|
|||
int omap_hwmod_enable_wakeup(struct omap_hwmod *oh);
|
||||
int omap_hwmod_disable_wakeup(struct omap_hwmod *oh);
|
||||
|
||||
int omap_hwmod_for_each_by_class(const char *classname,
|
||||
int (*fn)(struct omap_hwmod *oh,
|
||||
void *user),
|
||||
void *user);
|
||||
|
||||
/*
|
||||
* Chip variant-specific hwmod init routines - XXX should be converted
|
||||
* to use initcalls once the initial boot ordering is straightened out
|
||||
*/
|
||||
extern int omap2420_hwmod_init(void);
|
||||
extern int omap2430_hwmod_init(void);
|
||||
extern int omap3xxx_hwmod_init(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -100,6 +100,8 @@ struct powerdomain {
|
|||
struct list_head node;
|
||||
int state;
|
||||
unsigned state_counter[PWRDM_MAX_PWRSTS];
|
||||
unsigned ret_logic_off_counter;
|
||||
unsigned ret_mem_off_counter[PWRDM_MAX_MEM_BANKS];
|
||||
|
||||
#ifdef CONFIG_PM_DEBUG
|
||||
s64 timer;
|
||||
|
@ -137,8 +139,10 @@ int pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst);
|
|||
|
||||
int pwrdm_read_logic_pwrst(struct powerdomain *pwrdm);
|
||||
int pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm);
|
||||
int pwrdm_read_logic_retst(struct powerdomain *pwrdm);
|
||||
int pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank);
|
||||
int pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank);
|
||||
int pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank);
|
||||
|
||||
int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm);
|
||||
int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm);
|
||||
|
|
|
@ -25,7 +25,8 @@
|
|||
|
||||
u32 omap_prcm_get_reset_sources(void);
|
||||
void omap_prcm_arch_reset(char mode);
|
||||
int omap2_cm_wait_idlest(void __iomem *reg, u32 mask, const char *name);
|
||||
int omap2_cm_wait_idlest(void __iomem *reg, u32 mask, u8 idlest,
|
||||
const char *name);
|
||||
|
||||
#define START_PADCONF_SAVE 0x2
|
||||
#define PADCONF_SAVE_DONE 0x1
|
||||
|
|
|
@ -90,6 +90,8 @@
|
|||
#define IGNORE_WAKEUP_LAT 1
|
||||
|
||||
|
||||
#define OMAP_DEVICE_MAGIC 0xf00dcafe
|
||||
|
||||
/* Private functions */
|
||||
|
||||
/**
|
||||
|
@ -305,6 +307,7 @@ int omap_device_fill_resources(struct omap_device *od, struct resource *res)
|
|||
* @pdata_len: amount of memory pointed to by @pdata
|
||||
* @pm_lats: pointer to a omap_device_pm_latency array for this device
|
||||
* @pm_lats_cnt: ARRAY_SIZE() of @pm_lats
|
||||
* @is_early_device: should the device be registered as an early device or not
|
||||
*
|
||||
* Convenience function for building and registering a single
|
||||
* omap_device record, which in turn builds and registers a
|
||||
|
@ -316,7 +319,7 @@ struct omap_device *omap_device_build(const char *pdev_name, int pdev_id,
|
|||
struct omap_hwmod *oh, void *pdata,
|
||||
int pdata_len,
|
||||
struct omap_device_pm_latency *pm_lats,
|
||||
int pm_lats_cnt)
|
||||
int pm_lats_cnt, int is_early_device)
|
||||
{
|
||||
struct omap_hwmod *ohs[] = { oh };
|
||||
|
||||
|
@ -324,7 +327,8 @@ struct omap_device *omap_device_build(const char *pdev_name, int pdev_id,
|
|||
return ERR_PTR(-EINVAL);
|
||||
|
||||
return omap_device_build_ss(pdev_name, pdev_id, ohs, 1, pdata,
|
||||
pdata_len, pm_lats, pm_lats_cnt);
|
||||
pdata_len, pm_lats, pm_lats_cnt,
|
||||
is_early_device);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -336,6 +340,7 @@ struct omap_device *omap_device_build(const char *pdev_name, int pdev_id,
|
|||
* @pdata_len: amount of memory pointed to by @pdata
|
||||
* @pm_lats: pointer to a omap_device_pm_latency array for this device
|
||||
* @pm_lats_cnt: ARRAY_SIZE() of @pm_lats
|
||||
* @is_early_device: should the device be registered as an early device or not
|
||||
*
|
||||
* Convenience function for building and registering an omap_device
|
||||
* subsystem record. Subsystem records consist of multiple
|
||||
|
@ -347,7 +352,7 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
|
|||
struct omap_hwmod **ohs, int oh_cnt,
|
||||
void *pdata, int pdata_len,
|
||||
struct omap_device_pm_latency *pm_lats,
|
||||
int pm_lats_cnt)
|
||||
int pm_lats_cnt, int is_early_device)
|
||||
{
|
||||
int ret = -ENOMEM;
|
||||
struct omap_device *od;
|
||||
|
@ -403,7 +408,13 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
|
|||
od->pm_lats = pm_lats;
|
||||
od->pm_lats_cnt = pm_lats_cnt;
|
||||
|
||||
od->magic = OMAP_DEVICE_MAGIC;
|
||||
|
||||
if (is_early_device)
|
||||
ret = omap_early_device_register(od);
|
||||
else
|
||||
ret = omap_device_register(od);
|
||||
|
||||
if (ret)
|
||||
goto odbs_exit4;
|
||||
|
||||
|
@ -423,6 +434,24 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
|
|||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* omap_early_device_register - register an omap_device as an early platform
|
||||
* device.
|
||||
* @od: struct omap_device * to register
|
||||
*
|
||||
* Register the omap_device structure. This currently just calls
|
||||
* platform_early_add_device() on the underlying platform_device.
|
||||
* Returns 0 by default.
|
||||
*/
|
||||
int omap_early_device_register(struct omap_device *od)
|
||||
{
|
||||
struct platform_device *devices[1];
|
||||
|
||||
devices[0] = &(od->pdev);
|
||||
early_platform_add_devices(devices, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* omap_device_register - register an omap_device with one omap_hwmod
|
||||
* @od: struct omap_device * to register
|
||||
|
@ -462,8 +491,8 @@ int omap_device_enable(struct platform_device *pdev)
|
|||
od = _find_by_pdev(pdev);
|
||||
|
||||
if (od->_state == OMAP_DEVICE_STATE_ENABLED) {
|
||||
WARN(1, "omap_device: %s.%d: omap_device_enable() called from "
|
||||
"invalid state\n", od->pdev.name, od->pdev.id);
|
||||
WARN(1, "omap_device: %s.%d: %s() called from invalid state %d\n",
|
||||
od->pdev.name, od->pdev.id, __func__, od->_state);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -501,8 +530,8 @@ int omap_device_idle(struct platform_device *pdev)
|
|||
od = _find_by_pdev(pdev);
|
||||
|
||||
if (od->_state != OMAP_DEVICE_STATE_ENABLED) {
|
||||
WARN(1, "omap_device: %s.%d: omap_device_idle() called from "
|
||||
"invalid state\n", od->pdev.name, od->pdev.id);
|
||||
WARN(1, "omap_device: %s.%d: %s() called from invalid state %d\n",
|
||||
od->pdev.name, od->pdev.id, __func__, od->_state);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -534,8 +563,8 @@ int omap_device_shutdown(struct platform_device *pdev)
|
|||
|
||||
if (od->_state != OMAP_DEVICE_STATE_ENABLED &&
|
||||
od->_state != OMAP_DEVICE_STATE_IDLE) {
|
||||
WARN(1, "omap_device: %s.%d: omap_device_shutdown() called "
|
||||
"from invalid state\n", od->pdev.name, od->pdev.id);
|
||||
WARN(1, "omap_device: %s.%d: %s() called from invalid state %d\n",
|
||||
od->pdev.name, od->pdev.id, __func__, od->_state);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -588,6 +617,18 @@ int omap_device_align_pm_lat(struct platform_device *pdev,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* omap_device_is_valid - Check if pointer is a valid omap_device
|
||||
* @od: struct omap_device *
|
||||
*
|
||||
* Return whether struct omap_device pointer @od points to a valid
|
||||
* omap_device.
|
||||
*/
|
||||
bool omap_device_is_valid(struct omap_device *od)
|
||||
{
|
||||
return (od && od->magic == OMAP_DEVICE_MAGIC);
|
||||
}
|
||||
|
||||
/**
|
||||
* omap_device_get_pwrdm - return the powerdomain * associated with @od
|
||||
* @od: struct omap_device *
|
||||
|
|
Loading…
Reference in a new issue