mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-12 13:55:32 +00:00
Merge branch 'for_2.6.36' of git://git.pwsan.com/linux-2.6 into omap-for-linus
This commit is contained in:
commit
331d919af4
24 changed files with 790 additions and 225 deletions
|
@ -228,6 +228,12 @@ config OMAP_ARM_120MHZ
|
|||
help
|
||||
Enable 120MHz clock for OMAP CPU. If unsure, say N.
|
||||
|
||||
config OMAP_ARM_96MHZ
|
||||
bool "OMAP ARM 96 MHz CPU"
|
||||
depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_OMAP850)
|
||||
help
|
||||
Enable 96MHz clock for OMAP CPU. If unsure, say N.
|
||||
|
||||
config OMAP_ARM_60MHZ
|
||||
bool "OMAP ARM 60 MHz CPU"
|
||||
depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_OMAP850)
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/errno.h>
|
||||
|
@ -34,9 +33,9 @@
|
|||
__u32 arm_idlect1_mask;
|
||||
struct clk *api_ck_p, *ck_dpll1_p, *ck_ref_p;
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
/*
|
||||
* Omap1 specific clock functions
|
||||
*-------------------------------------------------------------------------*/
|
||||
*/
|
||||
|
||||
unsigned long omap1_uart_recalc(struct clk *clk)
|
||||
{
|
||||
|
@ -523,7 +522,8 @@ const struct clkops clkops_dspck = {
|
|||
.disable = omap1_clk_disable_dsp_domain,
|
||||
};
|
||||
|
||||
static int omap1_clk_enable_uart_functional(struct clk *clk)
|
||||
/* XXX SYSC register handling does not belong in the clock framework */
|
||||
static int omap1_clk_enable_uart_functional_16xx(struct clk *clk)
|
||||
{
|
||||
int ret;
|
||||
struct uart_clk *uclk;
|
||||
|
@ -539,7 +539,8 @@ static int omap1_clk_enable_uart_functional(struct clk *clk)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void omap1_clk_disable_uart_functional(struct clk *clk)
|
||||
/* XXX SYSC register handling does not belong in the clock framework */
|
||||
static void omap1_clk_disable_uart_functional_16xx(struct clk *clk)
|
||||
{
|
||||
struct uart_clk *uclk;
|
||||
|
||||
|
@ -550,9 +551,10 @@ static void omap1_clk_disable_uart_functional(struct clk *clk)
|
|||
omap1_clk_disable_generic(clk);
|
||||
}
|
||||
|
||||
const struct clkops clkops_uart = {
|
||||
.enable = omap1_clk_enable_uart_functional,
|
||||
.disable = omap1_clk_disable_uart_functional,
|
||||
/* XXX SYSC register handling does not belong in the clock framework */
|
||||
const struct clkops clkops_uart_16xx = {
|
||||
.enable = omap1_clk_enable_uart_functional_16xx,
|
||||
.disable = omap1_clk_disable_uart_functional_16xx,
|
||||
};
|
||||
|
||||
long omap1_clk_round_rate(struct clk *clk, unsigned long rate)
|
||||
|
@ -572,9 +574,9 @@ int omap1_clk_set_rate(struct clk *clk, unsigned long rate)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
/*
|
||||
* Omap1 clock reset and init functions
|
||||
*-------------------------------------------------------------------------*/
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_OMAP_RESET_CLOCKS
|
||||
|
||||
|
|
|
@ -107,7 +107,7 @@ extern struct clk *api_ck_p, *ck_dpll1_p, *ck_ref_p;
|
|||
|
||||
extern const struct clkops clkops_dspck;
|
||||
extern const struct clkops clkops_dummy;
|
||||
extern const struct clkops clkops_uart;
|
||||
extern const struct clkops clkops_uart_16xx;
|
||||
extern const struct clkops clkops_generic;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -8,6 +8,10 @@
|
|||
* 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.
|
||||
*
|
||||
* To do:
|
||||
* - Clocks that are only available on some chips should be marked with the
|
||||
* chips that they are present on.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
|
@ -23,9 +27,49 @@
|
|||
|
||||
#include "clock.h"
|
||||
|
||||
/*------------------------------------------------------------------------
|
||||
/* Some ARM_IDLECT1 bit shifts - used in struct arm_idlect1_clk */
|
||||
#define IDL_CLKOUT_ARM_SHIFT 12
|
||||
#define IDLTIM_ARM_SHIFT 9
|
||||
#define IDLAPI_ARM_SHIFT 8
|
||||
#define IDLIF_ARM_SHIFT 6
|
||||
#define IDLLB_ARM_SHIFT 4 /* undocumented? */
|
||||
#define OMAP1510_IDLLCD_ARM_SHIFT 3 /* undocumented? */
|
||||
#define IDLPER_ARM_SHIFT 2
|
||||
#define IDLXORP_ARM_SHIFT 1
|
||||
#define IDLWDT_ARM_SHIFT 0
|
||||
|
||||
/* Some MOD_CONF_CTRL_0 bit shifts - used in struct clk.enable_bit */
|
||||
#define CONF_MOD_UART3_CLK_MODE_R 31
|
||||
#define CONF_MOD_UART2_CLK_MODE_R 30
|
||||
#define CONF_MOD_UART1_CLK_MODE_R 29
|
||||
#define CONF_MOD_MMC_SD_CLK_REQ_R 23
|
||||
#define CONF_MOD_MCBSP3_AUXON 20
|
||||
|
||||
/* Some MOD_CONF_CTRL_1 bit shifts - used in struct clk.enable_bit */
|
||||
#define CONF_MOD_SOSSI_CLK_EN_R 16
|
||||
|
||||
/* Some OTG_SYSCON_2-specific bit fields */
|
||||
#define OTG_SYSCON_2_UHOST_EN_SHIFT 8
|
||||
|
||||
/* Some SOFT_REQ_REG bit fields - used in struct clk.enable_bit */
|
||||
#define SOFT_MMC2_DPLL_REQ_SHIFT 13
|
||||
#define SOFT_MMC_DPLL_REQ_SHIFT 12
|
||||
#define SOFT_UART3_DPLL_REQ_SHIFT 11
|
||||
#define SOFT_UART2_DPLL_REQ_SHIFT 10
|
||||
#define SOFT_UART1_DPLL_REQ_SHIFT 9
|
||||
#define SOFT_USB_OTG_DPLL_REQ_SHIFT 8
|
||||
#define SOFT_CAM_DPLL_REQ_SHIFT 7
|
||||
#define SOFT_COM_MCKO_REQ_SHIFT 6
|
||||
#define SOFT_PERIPH_REQ_SHIFT 5 /* sys_ck gate for UART2 ? */
|
||||
#define USB_REQ_EN_SHIFT 4
|
||||
#define SOFT_USB_REQ_SHIFT 3 /* sys_ck gate for USB host? */
|
||||
#define SOFT_SDW_REQ_SHIFT 2 /* sys_ck gate for Bluetooth? */
|
||||
#define SOFT_COM_REQ_SHIFT 1 /* sys_ck gate for com proc? */
|
||||
#define SOFT_DPLL_REQ_SHIFT 0
|
||||
|
||||
/*
|
||||
* Omap1 clocks
|
||||
*-------------------------------------------------------------------------*/
|
||||
*/
|
||||
|
||||
static struct clk ck_ref = {
|
||||
.name = "ck_ref",
|
||||
|
@ -54,7 +98,7 @@ static struct arm_idlect1_clk ck_dpll1out = {
|
|||
.enable_bit = EN_CKOUT_ARM,
|
||||
.recalc = &followparent_recalc,
|
||||
},
|
||||
.idlect_shift = 12,
|
||||
.idlect_shift = IDL_CLKOUT_ARM_SHIFT,
|
||||
};
|
||||
|
||||
static struct clk sossi_ck = {
|
||||
|
@ -63,7 +107,7 @@ static struct clk sossi_ck = {
|
|||
.parent = &ck_dpll1out.clk,
|
||||
.flags = CLOCK_NO_IDLE_PARENT | ENABLE_REG_32BIT,
|
||||
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_1),
|
||||
.enable_bit = 16,
|
||||
.enable_bit = CONF_MOD_SOSSI_CLK_EN_R,
|
||||
.recalc = &omap1_sossi_recalc,
|
||||
.set_rate = &omap1_set_sossi_rate,
|
||||
};
|
||||
|
@ -91,7 +135,7 @@ static struct arm_idlect1_clk armper_ck = {
|
|||
.round_rate = omap1_clk_round_rate_ckctl_arm,
|
||||
.set_rate = omap1_clk_set_rate_ckctl_arm,
|
||||
},
|
||||
.idlect_shift = 2,
|
||||
.idlect_shift = IDLPER_ARM_SHIFT,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -118,7 +162,7 @@ static struct arm_idlect1_clk armxor_ck = {
|
|||
.enable_bit = EN_XORPCK,
|
||||
.recalc = &followparent_recalc,
|
||||
},
|
||||
.idlect_shift = 1,
|
||||
.idlect_shift = IDLXORP_ARM_SHIFT,
|
||||
};
|
||||
|
||||
static struct arm_idlect1_clk armtim_ck = {
|
||||
|
@ -131,7 +175,7 @@ static struct arm_idlect1_clk armtim_ck = {
|
|||
.enable_bit = EN_TIMCK,
|
||||
.recalc = &followparent_recalc,
|
||||
},
|
||||
.idlect_shift = 9,
|
||||
.idlect_shift = IDLTIM_ARM_SHIFT,
|
||||
};
|
||||
|
||||
static struct arm_idlect1_clk armwdt_ck = {
|
||||
|
@ -145,7 +189,7 @@ static struct arm_idlect1_clk armwdt_ck = {
|
|||
.fixed_div = 14,
|
||||
.recalc = &omap_fixed_divisor_recalc,
|
||||
},
|
||||
.idlect_shift = 0,
|
||||
.idlect_shift = IDLWDT_ARM_SHIFT,
|
||||
};
|
||||
|
||||
static struct clk arminth_ck16xx = {
|
||||
|
@ -212,7 +256,6 @@ static struct clk dsptim_ck = {
|
|||
.recalc = &followparent_recalc,
|
||||
};
|
||||
|
||||
/* Tie ARM_IDLECT1:IDLIF_ARM to this logical clock structure */
|
||||
static struct arm_idlect1_clk tc_ck = {
|
||||
.clk = {
|
||||
.name = "tc_ck",
|
||||
|
@ -224,7 +267,7 @@ static struct arm_idlect1_clk tc_ck = {
|
|||
.round_rate = omap1_clk_round_rate_ckctl_arm,
|
||||
.set_rate = omap1_clk_set_rate_ckctl_arm,
|
||||
},
|
||||
.idlect_shift = 6,
|
||||
.idlect_shift = IDLIF_ARM_SHIFT,
|
||||
};
|
||||
|
||||
static struct clk arminth_ck1510 = {
|
||||
|
@ -304,7 +347,7 @@ static struct arm_idlect1_clk api_ck = {
|
|||
.enable_bit = EN_APICK,
|
||||
.recalc = &followparent_recalc,
|
||||
},
|
||||
.idlect_shift = 8,
|
||||
.idlect_shift = IDLAPI_ARM_SHIFT,
|
||||
};
|
||||
|
||||
static struct arm_idlect1_clk lb_ck = {
|
||||
|
@ -317,7 +360,7 @@ static struct arm_idlect1_clk lb_ck = {
|
|||
.enable_bit = EN_LBCK,
|
||||
.recalc = &followparent_recalc,
|
||||
},
|
||||
.idlect_shift = 4,
|
||||
.idlect_shift = IDLLB_ARM_SHIFT,
|
||||
};
|
||||
|
||||
static struct clk rhea1_ck = {
|
||||
|
@ -359,9 +402,15 @@ static struct arm_idlect1_clk lcd_ck_1510 = {
|
|||
.round_rate = omap1_clk_round_rate_ckctl_arm,
|
||||
.set_rate = omap1_clk_set_rate_ckctl_arm,
|
||||
},
|
||||
.idlect_shift = 3,
|
||||
.idlect_shift = OMAP1510_IDLLCD_ARM_SHIFT,
|
||||
};
|
||||
|
||||
/*
|
||||
* XXX The enable_bit here is misused - it simply switches between 12MHz
|
||||
* and 48MHz. Reimplement with clksel.
|
||||
*
|
||||
* XXX does this need SYSC register handling?
|
||||
*/
|
||||
static struct clk uart1_1510 = {
|
||||
.name = "uart1_ck",
|
||||
.ops = &clkops_null,
|
||||
|
@ -370,25 +419,37 @@ static struct clk uart1_1510 = {
|
|||
.rate = 12000000,
|
||||
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
|
||||
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
|
||||
.enable_bit = 29, /* Chooses between 12MHz and 48MHz */
|
||||
.enable_bit = CONF_MOD_UART1_CLK_MODE_R,
|
||||
.set_rate = &omap1_set_uart_rate,
|
||||
.recalc = &omap1_uart_recalc,
|
||||
};
|
||||
|
||||
/*
|
||||
* XXX The enable_bit here is misused - it simply switches between 12MHz
|
||||
* and 48MHz. Reimplement with clksel.
|
||||
*
|
||||
* XXX SYSC register handling does not belong in the clock framework
|
||||
*/
|
||||
static struct uart_clk uart1_16xx = {
|
||||
.clk = {
|
||||
.name = "uart1_ck",
|
||||
.ops = &clkops_uart,
|
||||
.ops = &clkops_uart_16xx,
|
||||
/* Direct from ULPD, no real parent */
|
||||
.parent = &armper_ck.clk,
|
||||
.rate = 48000000,
|
||||
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
|
||||
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
|
||||
.enable_bit = 29,
|
||||
.enable_bit = CONF_MOD_UART1_CLK_MODE_R,
|
||||
},
|
||||
.sysc_addr = 0xfffb0054,
|
||||
};
|
||||
|
||||
/*
|
||||
* XXX The enable_bit here is misused - it simply switches between 12MHz
|
||||
* and 48MHz. Reimplement with clksel.
|
||||
*
|
||||
* XXX does this need SYSC register handling?
|
||||
*/
|
||||
static struct clk uart2_ck = {
|
||||
.name = "uart2_ck",
|
||||
.ops = &clkops_null,
|
||||
|
@ -397,11 +458,17 @@ static struct clk uart2_ck = {
|
|||
.rate = 12000000,
|
||||
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
|
||||
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
|
||||
.enable_bit = 30, /* Chooses between 12MHz and 48MHz */
|
||||
.enable_bit = CONF_MOD_UART2_CLK_MODE_R,
|
||||
.set_rate = &omap1_set_uart_rate,
|
||||
.recalc = &omap1_uart_recalc,
|
||||
};
|
||||
|
||||
/*
|
||||
* XXX The enable_bit here is misused - it simply switches between 12MHz
|
||||
* and 48MHz. Reimplement with clksel.
|
||||
*
|
||||
* XXX does this need SYSC register handling?
|
||||
*/
|
||||
static struct clk uart3_1510 = {
|
||||
.name = "uart3_ck",
|
||||
.ops = &clkops_null,
|
||||
|
@ -410,21 +477,27 @@ static struct clk uart3_1510 = {
|
|||
.rate = 12000000,
|
||||
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
|
||||
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
|
||||
.enable_bit = 31, /* Chooses between 12MHz and 48MHz */
|
||||
.enable_bit = CONF_MOD_UART3_CLK_MODE_R,
|
||||
.set_rate = &omap1_set_uart_rate,
|
||||
.recalc = &omap1_uart_recalc,
|
||||
};
|
||||
|
||||
/*
|
||||
* XXX The enable_bit here is misused - it simply switches between 12MHz
|
||||
* and 48MHz. Reimplement with clksel.
|
||||
*
|
||||
* XXX SYSC register handling does not belong in the clock framework
|
||||
*/
|
||||
static struct uart_clk uart3_16xx = {
|
||||
.clk = {
|
||||
.name = "uart3_ck",
|
||||
.ops = &clkops_uart,
|
||||
.ops = &clkops_uart_16xx,
|
||||
/* Direct from ULPD, no real parent */
|
||||
.parent = &armper_ck.clk,
|
||||
.rate = 48000000,
|
||||
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
|
||||
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
|
||||
.enable_bit = 31,
|
||||
.enable_bit = CONF_MOD_UART3_CLK_MODE_R,
|
||||
},
|
||||
.sysc_addr = 0xfffb9854,
|
||||
};
|
||||
|
@ -457,7 +530,7 @@ static struct clk usb_hhc_ck16xx = {
|
|||
/* OTG_SYSCON_2.OTG_PADEN == 0 (not 1510-compatible) */
|
||||
.flags = ENABLE_REG_32BIT,
|
||||
.enable_reg = OMAP1_IO_ADDRESS(OTG_BASE + 0x08), /* OTG_SYSCON_2 */
|
||||
.enable_bit = 8 /* UHOST_EN */,
|
||||
.enable_bit = OTG_SYSCON_2_UHOST_EN_SHIFT
|
||||
};
|
||||
|
||||
static struct clk usb_dc_ck = {
|
||||
|
@ -466,7 +539,7 @@ static struct clk usb_dc_ck = {
|
|||
/* Direct from ULPD, no parent */
|
||||
.rate = 48000000,
|
||||
.enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
|
||||
.enable_bit = 4,
|
||||
.enable_bit = USB_REQ_EN_SHIFT,
|
||||
};
|
||||
|
||||
static struct clk usb_dc_ck7xx = {
|
||||
|
@ -475,7 +548,7 @@ static struct clk usb_dc_ck7xx = {
|
|||
/* Direct from ULPD, no parent */
|
||||
.rate = 48000000,
|
||||
.enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
|
||||
.enable_bit = 8,
|
||||
.enable_bit = SOFT_USB_OTG_DPLL_REQ_SHIFT,
|
||||
};
|
||||
|
||||
static struct clk uart1_7xx = {
|
||||
|
@ -502,7 +575,7 @@ static struct clk mclk_1510 = {
|
|||
/* Direct from ULPD, no parent. May be enabled by ext hardware. */
|
||||
.rate = 12000000,
|
||||
.enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
|
||||
.enable_bit = 6,
|
||||
.enable_bit = SOFT_COM_MCKO_REQ_SHIFT,
|
||||
};
|
||||
|
||||
static struct clk mclk_16xx = {
|
||||
|
@ -542,9 +615,13 @@ static struct clk mmc1_ck = {
|
|||
.rate = 48000000,
|
||||
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
|
||||
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
|
||||
.enable_bit = 23,
|
||||
.enable_bit = CONF_MOD_MMC_SD_CLK_REQ_R,
|
||||
};
|
||||
|
||||
/*
|
||||
* XXX MOD_CONF_CTRL_0 bit 20 is defined in the 1510 TRM as
|
||||
* CONF_MOD_MCBSP3_AUXON ??
|
||||
*/
|
||||
static struct clk mmc2_ck = {
|
||||
.name = "mmc2_ck",
|
||||
.ops = &clkops_generic,
|
||||
|
@ -564,7 +641,7 @@ static struct clk mmc3_ck = {
|
|||
.rate = 48000000,
|
||||
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
|
||||
.enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
|
||||
.enable_bit = 12,
|
||||
.enable_bit = SOFT_MMC_DPLL_REQ_SHIFT,
|
||||
};
|
||||
|
||||
static struct clk virtual_ck_mpu = {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#
|
||||
|
||||
# Common support
|
||||
obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer-gp.o
|
||||
obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer-gp.o pm.o
|
||||
|
||||
omap-2-3-common = irq.o sdrc.o
|
||||
hwmod-common = omap_hwmod.o \
|
||||
|
@ -15,7 +15,7 @@ clock-common = clock.o clock_common_data.o \
|
|||
|
||||
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_ARCH_OMAP4) += $(prcm-common) $(hwmod-common)
|
||||
|
||||
obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
|
||||
|
||||
|
|
|
@ -1408,7 +1408,7 @@ static struct clk ts_fck = {
|
|||
|
||||
static struct clk usbtll_fck = {
|
||||
.name = "usbtll_fck",
|
||||
.ops = &clkops_omap2_dflt,
|
||||
.ops = &clkops_omap2_dflt_wait,
|
||||
.parent = &dpll5_m2_ck,
|
||||
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3),
|
||||
.enable_bit = OMAP3430ES2_EN_USBTLL_SHIFT,
|
||||
|
|
|
@ -50,15 +50,15 @@ int omap2_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift)
|
|||
|
||||
cm_idlest_reg = cm_idlest_offs[idlest_id - 1];
|
||||
|
||||
mask = 1 << idlest_shift;
|
||||
|
||||
if (cpu_is_omap24xx())
|
||||
ena = idlest_shift;
|
||||
ena = mask;
|
||||
else if (cpu_is_omap34xx())
|
||||
ena = 0;
|
||||
else
|
||||
BUG();
|
||||
|
||||
mask = 1 << idlest_shift;
|
||||
|
||||
/* XXX should be OMAP2 CM */
|
||||
omap_test_timeout(((cm_read_mod_reg(prcm_mod, cm_idlest_reg) & mask) == ena),
|
||||
MAX_MODULE_READY_TIME, i);
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
|
||||
#include <plat/clockdomain.h>
|
||||
#include "clockdomains.h"
|
||||
|
||||
#include <plat/omap_hwmod.h>
|
||||
|
||||
/*
|
||||
|
@ -315,6 +316,8 @@ 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)
|
||||
{
|
||||
u8 skip_setup_idle = 0;
|
||||
|
||||
pwrdm_init(powerdomains_omap);
|
||||
clkdm_init(clockdomains_omap, clkdm_autodeps);
|
||||
if (cpu_is_omap242x())
|
||||
|
@ -338,9 +341,13 @@ void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
|
|||
pr_err("Could not init clock framework - unknown CPU\n");
|
||||
|
||||
omap_serial_early_init();
|
||||
|
||||
#ifndef CONFIG_PM_RUNTIME
|
||||
skip_setup_idle = 1;
|
||||
#endif
|
||||
if (cpu_is_omap24xx() || cpu_is_omap34xx()) /* FIXME: OMAP4 */
|
||||
omap_hwmod_late_init();
|
||||
omap_pm_if_init();
|
||||
omap_hwmod_late_init(skip_setup_idle);
|
||||
|
||||
if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
|
||||
omap2_sdrc_init(sdrc_cs0, sdrc_cs1);
|
||||
_omap2_init_reprogram_sdrc();
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* omap_hwmod implementation for OMAP2/3/4
|
||||
*
|
||||
* Copyright (C) 2009 Nokia Corporation
|
||||
* Copyright (C) 2009-2010 Nokia Corporation
|
||||
*
|
||||
* Paul Walmsley, Benoît Cousson, Kevin Hilman
|
||||
*
|
||||
|
@ -423,7 +423,7 @@ static int _init_main_clk(struct omap_hwmod *oh)
|
|||
}
|
||||
|
||||
/**
|
||||
* _init_interface_clk - get a struct clk * for the the hwmod's interface clks
|
||||
* _init_interface_clks - get a struct clk * for the the hwmod's interface clks
|
||||
* @oh: struct omap_hwmod *
|
||||
*
|
||||
* Called from _init_clocks(). Populates the @oh OCP slave interface
|
||||
|
@ -764,6 +764,7 @@ static struct omap_hwmod *_lookup(const char *name)
|
|||
/**
|
||||
* _init_clocks - clk_get() all clocks associated with this hwmod
|
||||
* @oh: struct omap_hwmod *
|
||||
* @data: not used; pass NULL
|
||||
*
|
||||
* Called by omap_hwmod_late_init() (after omap2_clk_init()).
|
||||
* Resolves all clock names embedded in the hwmod. Must be called
|
||||
|
@ -771,7 +772,7 @@ static struct omap_hwmod *_lookup(const char *name)
|
|||
* has not yet been registered or if the clocks have already been
|
||||
* initialized, 0 on success, or a non-zero error on failure.
|
||||
*/
|
||||
static int _init_clocks(struct omap_hwmod *oh)
|
||||
static int _init_clocks(struct omap_hwmod *oh, void *data)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
|
@ -886,7 +887,7 @@ static int _reset(struct omap_hwmod *oh)
|
|||
}
|
||||
|
||||
/**
|
||||
* _enable - enable an omap_hwmod
|
||||
* _omap_hwmod_enable - enable an omap_hwmod
|
||||
* @oh: struct omap_hwmod *
|
||||
*
|
||||
* Enables an omap_hwmod @oh such that the MPU can access the hwmod's
|
||||
|
@ -894,7 +895,7 @@ static int _reset(struct omap_hwmod *oh)
|
|||
* Returns -EINVAL if the hwmod is in the wrong state or passes along
|
||||
* the return value of _wait_target_ready().
|
||||
*/
|
||||
static int _enable(struct omap_hwmod *oh)
|
||||
int _omap_hwmod_enable(struct omap_hwmod *oh)
|
||||
{
|
||||
int r;
|
||||
|
||||
|
@ -939,7 +940,7 @@ static int _enable(struct omap_hwmod *oh)
|
|||
* no further work. Returns -EINVAL if the hwmod is in the wrong
|
||||
* state or returns 0.
|
||||
*/
|
||||
static int _idle(struct omap_hwmod *oh)
|
||||
int _omap_hwmod_idle(struct omap_hwmod *oh)
|
||||
{
|
||||
if (oh->_state != _HWMOD_STATE_ENABLED) {
|
||||
WARN(1, "omap_hwmod: %s: idle state can only be entered from "
|
||||
|
@ -996,19 +997,25 @@ static int _shutdown(struct omap_hwmod *oh)
|
|||
/**
|
||||
* _setup - do initial configuration of omap_hwmod
|
||||
* @oh: struct omap_hwmod *
|
||||
* @skip_setup_idle_p: do not idle hwmods at the end of the fn if 1
|
||||
*
|
||||
* Writes the CLOCKACTIVITY bits @clockact to the hwmod @oh
|
||||
* OCP_SYSCONFIG register. Must be called with omap_hwmod_mutex
|
||||
* held. Returns -EINVAL if the hwmod is in the wrong state or returns
|
||||
* 0.
|
||||
* OCP_SYSCONFIG register. Must be called with omap_hwmod_mutex held.
|
||||
* @skip_setup_idle is intended to be used on a system that will not
|
||||
* call omap_hwmod_enable() to enable devices (e.g., a system without
|
||||
* PM runtime). Returns -EINVAL if the hwmod is in the wrong state or
|
||||
* returns 0.
|
||||
*/
|
||||
static int _setup(struct omap_hwmod *oh)
|
||||
static int _setup(struct omap_hwmod *oh, void *data)
|
||||
{
|
||||
int i, r;
|
||||
u8 skip_setup_idle;
|
||||
|
||||
if (!oh)
|
||||
if (!oh || !data)
|
||||
return -EINVAL;
|
||||
|
||||
skip_setup_idle = *(u8 *)data;
|
||||
|
||||
/* Set iclk autoidle mode */
|
||||
if (oh->slaves_cnt > 0) {
|
||||
for (i = 0; i < oh->slaves_cnt; i++) {
|
||||
|
@ -1029,7 +1036,7 @@ static int _setup(struct omap_hwmod *oh)
|
|||
|
||||
oh->_state = _HWMOD_STATE_INITIALIZED;
|
||||
|
||||
r = _enable(oh);
|
||||
r = _omap_hwmod_enable(oh);
|
||||
if (r) {
|
||||
pr_warning("omap_hwmod: %s: cannot be enabled (%d)\n",
|
||||
oh->name, oh->_state);
|
||||
|
@ -1041,7 +1048,7 @@ static int _setup(struct omap_hwmod *oh)
|
|||
* XXX Do the OCP_SYSCONFIG bits need to be
|
||||
* reprogrammed after a reset? If not, then this can
|
||||
* be removed. If they do, then probably the
|
||||
* _enable() function should be split to avoid the
|
||||
* _omap_hwmod_enable() function should be split to avoid the
|
||||
* rewrite of the OCP_SYSCONFIG register.
|
||||
*/
|
||||
if (oh->class->sysc) {
|
||||
|
@ -1050,8 +1057,8 @@ static int _setup(struct omap_hwmod *oh)
|
|||
}
|
||||
}
|
||||
|
||||
if (!(oh->flags & HWMOD_INIT_NO_IDLE))
|
||||
_idle(oh);
|
||||
if (!(oh->flags & HWMOD_INIT_NO_IDLE) && !skip_setup_idle)
|
||||
_omap_hwmod_idle(oh);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1062,14 +1069,29 @@ static int _setup(struct omap_hwmod *oh)
|
|||
|
||||
u32 omap_hwmod_readl(struct omap_hwmod *oh, u16 reg_offs)
|
||||
{
|
||||
return __raw_readl(oh->_rt_va + reg_offs);
|
||||
return __raw_readl(oh->_mpu_rt_va + reg_offs);
|
||||
}
|
||||
|
||||
void omap_hwmod_writel(u32 v, struct omap_hwmod *oh, u16 reg_offs)
|
||||
{
|
||||
__raw_writel(v, oh->_rt_va + reg_offs);
|
||||
__raw_writel(v, oh->_mpu_rt_va + reg_offs);
|
||||
}
|
||||
|
||||
/**
|
||||
* omap_hwmod_set_slave_idlemode - set the hwmod's OCP slave idlemode
|
||||
* @oh: struct omap_hwmod *
|
||||
* @idlemode: SIDLEMODE field bits (shifted to bit 0)
|
||||
*
|
||||
* Sets the IP block's OCP slave idlemode in hardware, and updates our
|
||||
* local copy. Intended to be used by drivers that have some erratum
|
||||
* that requires direct manipulation of the SIDLEMODE bits. Returns
|
||||
* -EINVAL if @oh is null, or passes along the return value from
|
||||
* _set_slave_idlemode().
|
||||
*
|
||||
* XXX Does this function have any current users? If not, we should
|
||||
* remove it; it is better to let the rest of the hwmod code handle this.
|
||||
* Any users of this function should be scrutinized carefully.
|
||||
*/
|
||||
int omap_hwmod_set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode)
|
||||
{
|
||||
u32 v;
|
||||
|
@ -1124,7 +1146,7 @@ int omap_hwmod_register(struct omap_hwmod *oh)
|
|||
ms_id = _find_mpu_port_index(oh);
|
||||
if (!IS_ERR_VALUE(ms_id)) {
|
||||
oh->_mpu_port_index = ms_id;
|
||||
oh->_rt_va = _find_mpu_rt_base(oh, oh->_mpu_port_index);
|
||||
oh->_mpu_rt_va = _find_mpu_rt_base(oh, oh->_mpu_port_index);
|
||||
} else {
|
||||
oh->_int_flags |= _HWMOD_NO_MPU_PORT;
|
||||
}
|
||||
|
@ -1164,6 +1186,7 @@ struct omap_hwmod *omap_hwmod_lookup(const char *name)
|
|||
/**
|
||||
* omap_hwmod_for_each - call function for each registered omap_hwmod
|
||||
* @fn: pointer to a callback function
|
||||
* @data: void * data to pass to callback function
|
||||
*
|
||||
* Call @fn for each registered omap_hwmod, passing @data to each
|
||||
* function. @fn must return 0 for success or any other value for
|
||||
|
@ -1172,7 +1195,8 @@ struct omap_hwmod *omap_hwmod_lookup(const char *name)
|
|||
* caller of omap_hwmod_for_each(). @fn is called with
|
||||
* omap_hwmod_for_each() held.
|
||||
*/
|
||||
int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh))
|
||||
int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh, void *data),
|
||||
void *data)
|
||||
{
|
||||
struct omap_hwmod *temp_oh;
|
||||
int ret;
|
||||
|
@ -1182,7 +1206,7 @@ int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh))
|
|||
|
||||
mutex_lock(&omap_hwmod_mutex);
|
||||
list_for_each_entry(temp_oh, &omap_hwmod_list, node) {
|
||||
ret = (*fn)(temp_oh);
|
||||
ret = (*fn)(temp_oh, data);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
|
@ -1229,24 +1253,28 @@ int omap_hwmod_init(struct omap_hwmod **ohs)
|
|||
|
||||
/**
|
||||
* omap_hwmod_late_init - do some post-clock framework initialization
|
||||
* @skip_setup_idle: if 1, do not idle hwmods in _setup()
|
||||
*
|
||||
* Must be called after omap2_clk_init(). Resolves the struct clk names
|
||||
* to struct clk pointers for each registered omap_hwmod. Also calls
|
||||
* _setup() on each hwmod. Returns 0.
|
||||
*/
|
||||
int omap_hwmod_late_init(void)
|
||||
int omap_hwmod_late_init(u8 skip_setup_idle)
|
||||
{
|
||||
int r;
|
||||
|
||||
/* XXX check return value */
|
||||
r = omap_hwmod_for_each(_init_clocks);
|
||||
r = omap_hwmod_for_each(_init_clocks, NULL);
|
||||
WARN(r, "omap_hwmod: omap_hwmod_late_init(): _init_clocks failed\n");
|
||||
|
||||
mpu_oh = omap_hwmod_lookup(MPU_INITIATOR_NAME);
|
||||
WARN(!mpu_oh, "omap_hwmod: could not find MPU initiator hwmod %s\n",
|
||||
MPU_INITIATOR_NAME);
|
||||
|
||||
omap_hwmod_for_each(_setup);
|
||||
if (skip_setup_idle)
|
||||
pr_debug("omap_hwmod: will leave hwmods enabled during setup\n");
|
||||
|
||||
omap_hwmod_for_each(_setup, &skip_setup_idle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1270,7 +1298,7 @@ int omap_hwmod_unregister(struct omap_hwmod *oh)
|
|||
pr_debug("omap_hwmod: %s: unregistering\n", oh->name);
|
||||
|
||||
mutex_lock(&omap_hwmod_mutex);
|
||||
iounmap(oh->_rt_va);
|
||||
iounmap(oh->_mpu_rt_va);
|
||||
list_del(&oh->node);
|
||||
mutex_unlock(&omap_hwmod_mutex);
|
||||
|
||||
|
@ -1292,12 +1320,13 @@ int omap_hwmod_enable(struct omap_hwmod *oh)
|
|||
return -EINVAL;
|
||||
|
||||
mutex_lock(&omap_hwmod_mutex);
|
||||
r = _enable(oh);
|
||||
r = _omap_hwmod_enable(oh);
|
||||
mutex_unlock(&omap_hwmod_mutex);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* omap_hwmod_idle - idle an omap_hwmod
|
||||
* @oh: struct omap_hwmod *
|
||||
|
@ -1311,7 +1340,7 @@ int omap_hwmod_idle(struct omap_hwmod *oh)
|
|||
return -EINVAL;
|
||||
|
||||
mutex_lock(&omap_hwmod_mutex);
|
||||
_idle(oh);
|
||||
_omap_hwmod_idle(oh);
|
||||
mutex_unlock(&omap_hwmod_mutex);
|
||||
|
||||
return 0;
|
||||
|
@ -1413,7 +1442,7 @@ int omap_hwmod_reset(struct omap_hwmod *oh)
|
|||
mutex_lock(&omap_hwmod_mutex);
|
||||
r = _reset(oh);
|
||||
if (!r)
|
||||
r = _enable(oh);
|
||||
r = _omap_hwmod_enable(oh);
|
||||
mutex_unlock(&omap_hwmod_mutex);
|
||||
|
||||
return r;
|
||||
|
@ -1529,6 +1558,29 @@ struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh)
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* omap_hwmod_get_mpu_rt_va - return the module's base address (for the MPU)
|
||||
* @oh: struct omap_hwmod *
|
||||
*
|
||||
* Returns the virtual address corresponding to the beginning of the
|
||||
* module's register target, in the address range that is intended to
|
||||
* be used by the MPU. Returns the virtual address upon success or NULL
|
||||
* upon error.
|
||||
*/
|
||||
void __iomem *omap_hwmod_get_mpu_rt_va(struct omap_hwmod *oh)
|
||||
{
|
||||
if (!oh)
|
||||
return NULL;
|
||||
|
||||
if (oh->_int_flags & _HWMOD_NO_MPU_PORT)
|
||||
return NULL;
|
||||
|
||||
if (oh->_state == _HWMOD_STATE_UNKNOWN)
|
||||
return NULL;
|
||||
|
||||
return oh->_mpu_rt_va;
|
||||
}
|
||||
|
||||
/**
|
||||
* omap_hwmod_add_initiator_dep - add sleepdep from @init_oh to @oh
|
||||
* @oh: struct omap_hwmod *
|
||||
|
|
|
@ -30,42 +30,44 @@
|
|||
*/
|
||||
|
||||
static struct omap_hwmod omap2420_mpu_hwmod;
|
||||
static struct omap_hwmod omap2420_l3_hwmod;
|
||||
static struct omap_hwmod omap2420_iva_hwmod;
|
||||
static struct omap_hwmod omap2420_l3_main_hwmod;
|
||||
static struct omap_hwmod omap2420_l4_core_hwmod;
|
||||
|
||||
/* L3 -> L4_CORE interface */
|
||||
static struct omap_hwmod_ocp_if omap2420_l3__l4_core = {
|
||||
.master = &omap2420_l3_hwmod,
|
||||
static struct omap_hwmod_ocp_if omap2420_l3_main__l4_core = {
|
||||
.master = &omap2420_l3_main_hwmod,
|
||||
.slave = &omap2420_l4_core_hwmod,
|
||||
.user = OCP_USER_MPU | OCP_USER_SDMA,
|
||||
};
|
||||
|
||||
/* MPU -> L3 interface */
|
||||
static struct omap_hwmod_ocp_if omap2420_mpu__l3 = {
|
||||
static struct omap_hwmod_ocp_if omap2420_mpu__l3_main = {
|
||||
.master = &omap2420_mpu_hwmod,
|
||||
.slave = &omap2420_l3_hwmod,
|
||||
.slave = &omap2420_l3_main_hwmod,
|
||||
.user = OCP_USER_MPU,
|
||||
};
|
||||
|
||||
/* Slave interfaces on the L3 interconnect */
|
||||
static struct omap_hwmod_ocp_if *omap2420_l3_slaves[] = {
|
||||
&omap2420_mpu__l3,
|
||||
static struct omap_hwmod_ocp_if *omap2420_l3_main_slaves[] = {
|
||||
&omap2420_mpu__l3_main,
|
||||
};
|
||||
|
||||
/* Master interfaces on the L3 interconnect */
|
||||
static struct omap_hwmod_ocp_if *omap2420_l3_masters[] = {
|
||||
&omap2420_l3__l4_core,
|
||||
static struct omap_hwmod_ocp_if *omap2420_l3_main_masters[] = {
|
||||
&omap2420_l3_main__l4_core,
|
||||
};
|
||||
|
||||
/* L3 */
|
||||
static struct omap_hwmod omap2420_l3_hwmod = {
|
||||
.name = "l3_hwmod",
|
||||
static struct omap_hwmod omap2420_l3_main_hwmod = {
|
||||
.name = "l3_main",
|
||||
.class = &l3_hwmod_class,
|
||||
.masters = omap2420_l3_masters,
|
||||
.masters_cnt = ARRAY_SIZE(omap2420_l3_masters),
|
||||
.slaves = omap2420_l3_slaves,
|
||||
.slaves_cnt = ARRAY_SIZE(omap2420_l3_slaves),
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
|
||||
.masters = omap2420_l3_main_masters,
|
||||
.masters_cnt = ARRAY_SIZE(omap2420_l3_main_masters),
|
||||
.slaves = omap2420_l3_main_slaves,
|
||||
.slaves_cnt = ARRAY_SIZE(omap2420_l3_main_slaves),
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
|
||||
.flags = HWMOD_NO_IDLEST,
|
||||
};
|
||||
|
||||
static struct omap_hwmod omap2420_l4_wkup_hwmod;
|
||||
|
@ -79,7 +81,7 @@ static struct omap_hwmod_ocp_if omap2420_l4_core__l4_wkup = {
|
|||
|
||||
/* Slave interfaces on the L4_CORE interconnect */
|
||||
static struct omap_hwmod_ocp_if *omap2420_l4_core_slaves[] = {
|
||||
&omap2420_l3__l4_core,
|
||||
&omap2420_l3_main__l4_core,
|
||||
};
|
||||
|
||||
/* Master interfaces on the L4_CORE interconnect */
|
||||
|
@ -89,13 +91,14 @@ static struct omap_hwmod_ocp_if *omap2420_l4_core_masters[] = {
|
|||
|
||||
/* L4 CORE */
|
||||
static struct omap_hwmod omap2420_l4_core_hwmod = {
|
||||
.name = "l4_core_hwmod",
|
||||
.name = "l4_core",
|
||||
.class = &l4_hwmod_class,
|
||||
.masters = omap2420_l4_core_masters,
|
||||
.masters_cnt = ARRAY_SIZE(omap2420_l4_core_masters),
|
||||
.slaves = omap2420_l4_core_slaves,
|
||||
.slaves_cnt = ARRAY_SIZE(omap2420_l4_core_slaves),
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
|
||||
.flags = HWMOD_NO_IDLEST,
|
||||
};
|
||||
|
||||
/* Slave interfaces on the L4_WKUP interconnect */
|
||||
|
@ -109,18 +112,19 @@ static struct omap_hwmod_ocp_if *omap2420_l4_wkup_masters[] = {
|
|||
|
||||
/* L4 WKUP */
|
||||
static struct omap_hwmod omap2420_l4_wkup_hwmod = {
|
||||
.name = "l4_wkup_hwmod",
|
||||
.name = "l4_wkup",
|
||||
.class = &l4_hwmod_class,
|
||||
.masters = omap2420_l4_wkup_masters,
|
||||
.masters_cnt = ARRAY_SIZE(omap2420_l4_wkup_masters),
|
||||
.slaves = omap2420_l4_wkup_slaves,
|
||||
.slaves_cnt = ARRAY_SIZE(omap2420_l4_wkup_slaves),
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
|
||||
.flags = HWMOD_NO_IDLEST,
|
||||
};
|
||||
|
||||
/* Master interfaces on the MPU device */
|
||||
static struct omap_hwmod_ocp_if *omap2420_mpu_masters[] = {
|
||||
&omap2420_mpu__l3,
|
||||
&omap2420_mpu__l3_main,
|
||||
};
|
||||
|
||||
/* MPU */
|
||||
|
@ -133,11 +137,40 @@ static struct omap_hwmod omap2420_mpu_hwmod = {
|
|||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
|
||||
};
|
||||
|
||||
/*
|
||||
* IVA1 interface data
|
||||
*/
|
||||
|
||||
/* IVA <- L3 interface */
|
||||
static struct omap_hwmod_ocp_if omap2420_l3__iva = {
|
||||
.master = &omap2420_l3_main_hwmod,
|
||||
.slave = &omap2420_iva_hwmod,
|
||||
.clk = "iva1_ifck",
|
||||
.user = OCP_USER_MPU | OCP_USER_SDMA,
|
||||
};
|
||||
|
||||
static struct omap_hwmod_ocp_if *omap2420_iva_masters[] = {
|
||||
&omap2420_l3__iva,
|
||||
};
|
||||
|
||||
/*
|
||||
* IVA2 (IVA2)
|
||||
*/
|
||||
|
||||
static struct omap_hwmod omap2420_iva_hwmod = {
|
||||
.name = "iva",
|
||||
.class = &iva_hwmod_class,
|
||||
.masters = omap2420_iva_masters,
|
||||
.masters_cnt = ARRAY_SIZE(omap2420_iva_masters),
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
|
||||
};
|
||||
|
||||
static __initdata struct omap_hwmod *omap2420_hwmods[] = {
|
||||
&omap2420_l3_hwmod,
|
||||
&omap2420_l3_main_hwmod,
|
||||
&omap2420_l4_core_hwmod,
|
||||
&omap2420_l4_wkup_hwmod,
|
||||
&omap2420_mpu_hwmod,
|
||||
&omap2420_iva_hwmod,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
|
|
@ -30,47 +30,47 @@
|
|||
*/
|
||||
|
||||
static struct omap_hwmod omap2430_mpu_hwmod;
|
||||
static struct omap_hwmod omap2430_l3_hwmod;
|
||||
static struct omap_hwmod omap2430_iva_hwmod;
|
||||
static struct omap_hwmod omap2430_l3_main_hwmod;
|
||||
static struct omap_hwmod omap2430_l4_core_hwmod;
|
||||
|
||||
/* L3 -> L4_CORE interface */
|
||||
static struct omap_hwmod_ocp_if omap2430_l3__l4_core = {
|
||||
.master = &omap2430_l3_hwmod,
|
||||
static struct omap_hwmod_ocp_if omap2430_l3_main__l4_core = {
|
||||
.master = &omap2430_l3_main_hwmod,
|
||||
.slave = &omap2430_l4_core_hwmod,
|
||||
.user = OCP_USER_MPU | OCP_USER_SDMA,
|
||||
};
|
||||
|
||||
/* MPU -> L3 interface */
|
||||
static struct omap_hwmod_ocp_if omap2430_mpu__l3 = {
|
||||
static struct omap_hwmod_ocp_if omap2430_mpu__l3_main = {
|
||||
.master = &omap2430_mpu_hwmod,
|
||||
.slave = &omap2430_l3_hwmod,
|
||||
.slave = &omap2430_l3_main_hwmod,
|
||||
.user = OCP_USER_MPU,
|
||||
};
|
||||
|
||||
/* Slave interfaces on the L3 interconnect */
|
||||
static struct omap_hwmod_ocp_if *omap2430_l3_slaves[] = {
|
||||
&omap2430_mpu__l3,
|
||||
static struct omap_hwmod_ocp_if *omap2430_l3_main_slaves[] = {
|
||||
&omap2430_mpu__l3_main,
|
||||
};
|
||||
|
||||
/* Master interfaces on the L3 interconnect */
|
||||
static struct omap_hwmod_ocp_if *omap2430_l3_masters[] = {
|
||||
&omap2430_l3__l4_core,
|
||||
static struct omap_hwmod_ocp_if *omap2430_l3_main_masters[] = {
|
||||
&omap2430_l3_main__l4_core,
|
||||
};
|
||||
|
||||
/* L3 */
|
||||
static struct omap_hwmod omap2430_l3_hwmod = {
|
||||
.name = "l3_hwmod",
|
||||
static struct omap_hwmod omap2430_l3_main_hwmod = {
|
||||
.name = "l3_main",
|
||||
.class = &l3_hwmod_class,
|
||||
.masters = omap2430_l3_masters,
|
||||
.masters_cnt = ARRAY_SIZE(omap2430_l3_masters),
|
||||
.slaves = omap2430_l3_slaves,
|
||||
.slaves_cnt = ARRAY_SIZE(omap2430_l3_slaves),
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
|
||||
.masters = omap2430_l3_main_masters,
|
||||
.masters_cnt = ARRAY_SIZE(omap2430_l3_main_masters),
|
||||
.slaves = omap2430_l3_main_slaves,
|
||||
.slaves_cnt = ARRAY_SIZE(omap2430_l3_main_slaves),
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
|
||||
.flags = HWMOD_NO_IDLEST,
|
||||
};
|
||||
|
||||
static struct omap_hwmod omap2430_l4_wkup_hwmod;
|
||||
static struct omap_hwmod omap2430_mmc1_hwmod;
|
||||
static struct omap_hwmod omap2430_mmc2_hwmod;
|
||||
|
||||
/* L4_CORE -> L4_WKUP interface */
|
||||
static struct omap_hwmod_ocp_if omap2430_l4_core__l4_wkup = {
|
||||
|
@ -81,7 +81,7 @@ static struct omap_hwmod_ocp_if omap2430_l4_core__l4_wkup = {
|
|||
|
||||
/* Slave interfaces on the L4_CORE interconnect */
|
||||
static struct omap_hwmod_ocp_if *omap2430_l4_core_slaves[] = {
|
||||
&omap2430_l3__l4_core,
|
||||
&omap2430_l3_main__l4_core,
|
||||
};
|
||||
|
||||
/* Master interfaces on the L4_CORE interconnect */
|
||||
|
@ -91,13 +91,14 @@ static struct omap_hwmod_ocp_if *omap2430_l4_core_masters[] = {
|
|||
|
||||
/* L4 CORE */
|
||||
static struct omap_hwmod omap2430_l4_core_hwmod = {
|
||||
.name = "l4_core_hwmod",
|
||||
.name = "l4_core",
|
||||
.class = &l4_hwmod_class,
|
||||
.masters = omap2430_l4_core_masters,
|
||||
.masters_cnt = ARRAY_SIZE(omap2430_l4_core_masters),
|
||||
.slaves = omap2430_l4_core_slaves,
|
||||
.slaves_cnt = ARRAY_SIZE(omap2430_l4_core_slaves),
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
|
||||
.flags = HWMOD_NO_IDLEST,
|
||||
};
|
||||
|
||||
/* Slave interfaces on the L4_WKUP interconnect */
|
||||
|
@ -111,18 +112,19 @@ static struct omap_hwmod_ocp_if *omap2430_l4_wkup_masters[] = {
|
|||
|
||||
/* L4 WKUP */
|
||||
static struct omap_hwmod omap2430_l4_wkup_hwmod = {
|
||||
.name = "l4_wkup_hwmod",
|
||||
.name = "l4_wkup",
|
||||
.class = &l4_hwmod_class,
|
||||
.masters = omap2430_l4_wkup_masters,
|
||||
.masters_cnt = ARRAY_SIZE(omap2430_l4_wkup_masters),
|
||||
.slaves = omap2430_l4_wkup_slaves,
|
||||
.slaves_cnt = ARRAY_SIZE(omap2430_l4_wkup_slaves),
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
|
||||
.flags = HWMOD_NO_IDLEST,
|
||||
};
|
||||
|
||||
/* Master interfaces on the MPU device */
|
||||
static struct omap_hwmod_ocp_if *omap2430_mpu_masters[] = {
|
||||
&omap2430_mpu__l3,
|
||||
&omap2430_mpu__l3_main,
|
||||
};
|
||||
|
||||
/* MPU */
|
||||
|
@ -135,11 +137,40 @@ static struct omap_hwmod omap2430_mpu_hwmod = {
|
|||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
|
||||
};
|
||||
|
||||
/*
|
||||
* IVA2_1 interface data
|
||||
*/
|
||||
|
||||
/* IVA2 <- L3 interface */
|
||||
static struct omap_hwmod_ocp_if omap2430_l3__iva = {
|
||||
.master = &omap2430_l3_main_hwmod,
|
||||
.slave = &omap2430_iva_hwmod,
|
||||
.clk = "dsp_fck",
|
||||
.user = OCP_USER_MPU | OCP_USER_SDMA,
|
||||
};
|
||||
|
||||
static struct omap_hwmod_ocp_if *omap2430_iva_masters[] = {
|
||||
&omap2430_l3__iva,
|
||||
};
|
||||
|
||||
/*
|
||||
* IVA2 (IVA2)
|
||||
*/
|
||||
|
||||
static struct omap_hwmod omap2430_iva_hwmod = {
|
||||
.name = "iva",
|
||||
.class = &iva_hwmod_class,
|
||||
.masters = omap2430_iva_masters,
|
||||
.masters_cnt = ARRAY_SIZE(omap2430_iva_masters),
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
|
||||
};
|
||||
|
||||
static __initdata struct omap_hwmod *omap2430_hwmods[] = {
|
||||
&omap2430_l3_hwmod,
|
||||
&omap2430_l3_main_hwmod,
|
||||
&omap2430_l4_core_hwmod,
|
||||
&omap2430_l4_wkup_hwmod,
|
||||
&omap2430_mpu_hwmod,
|
||||
&omap2430_iva_hwmod,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
|
|
@ -32,51 +32,53 @@
|
|||
*/
|
||||
|
||||
static struct omap_hwmod omap3xxx_mpu_hwmod;
|
||||
static struct omap_hwmod omap3xxx_l3_hwmod;
|
||||
static struct omap_hwmod omap3xxx_iva_hwmod;
|
||||
static struct omap_hwmod omap3xxx_l3_main_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,
|
||||
static struct omap_hwmod_ocp_if omap3xxx_l3_main__l4_core = {
|
||||
.master = &omap3xxx_l3_main_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,
|
||||
static struct omap_hwmod_ocp_if omap3xxx_l3_main__l4_per = {
|
||||
.master = &omap3xxx_l3_main_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 = {
|
||||
static struct omap_hwmod_ocp_if omap3xxx_mpu__l3_main = {
|
||||
.master = &omap3xxx_mpu_hwmod,
|
||||
.slave = &omap3xxx_l3_hwmod,
|
||||
.slave = &omap3xxx_l3_main_hwmod,
|
||||
.user = OCP_USER_MPU,
|
||||
};
|
||||
|
||||
/* Slave interfaces on the L3 interconnect */
|
||||
static struct omap_hwmod_ocp_if *omap3xxx_l3_slaves[] = {
|
||||
&omap3xxx_mpu__l3,
|
||||
static struct omap_hwmod_ocp_if *omap3xxx_l3_main_slaves[] = {
|
||||
&omap3xxx_mpu__l3_main,
|
||||
};
|
||||
|
||||
/* Master interfaces on the L3 interconnect */
|
||||
static struct omap_hwmod_ocp_if *omap3xxx_l3_masters[] = {
|
||||
&omap3xxx_l3__l4_core,
|
||||
&omap3xxx_l3__l4_per,
|
||||
static struct omap_hwmod_ocp_if *omap3xxx_l3_main_masters[] = {
|
||||
&omap3xxx_l3_main__l4_core,
|
||||
&omap3xxx_l3_main__l4_per,
|
||||
};
|
||||
|
||||
/* L3 */
|
||||
static struct omap_hwmod omap3xxx_l3_hwmod = {
|
||||
.name = "l3_hwmod",
|
||||
static struct omap_hwmod omap3xxx_l3_main_hwmod = {
|
||||
.name = "l3_main",
|
||||
.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)
|
||||
.masters = omap3xxx_l3_main_masters,
|
||||
.masters_cnt = ARRAY_SIZE(omap3xxx_l3_main_masters),
|
||||
.slaves = omap3xxx_l3_main_slaves,
|
||||
.slaves_cnt = ARRAY_SIZE(omap3xxx_l3_main_slaves),
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
|
||||
.flags = HWMOD_NO_IDLEST,
|
||||
};
|
||||
|
||||
static struct omap_hwmod omap3xxx_l4_wkup_hwmod;
|
||||
|
@ -90,7 +92,7 @@ static struct omap_hwmod_ocp_if omap3xxx_l4_core__l4_wkup = {
|
|||
|
||||
/* Slave interfaces on the L4_CORE interconnect */
|
||||
static struct omap_hwmod_ocp_if *omap3xxx_l4_core_slaves[] = {
|
||||
&omap3xxx_l3__l4_core,
|
||||
&omap3xxx_l3_main__l4_core,
|
||||
};
|
||||
|
||||
/* Master interfaces on the L4_CORE interconnect */
|
||||
|
@ -100,18 +102,19 @@ static struct omap_hwmod_ocp_if *omap3xxx_l4_core_masters[] = {
|
|||
|
||||
/* L4 CORE */
|
||||
static struct omap_hwmod omap3xxx_l4_core_hwmod = {
|
||||
.name = "l4_core_hwmod",
|
||||
.name = "l4_core",
|
||||
.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)
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
|
||||
.flags = HWMOD_NO_IDLEST,
|
||||
};
|
||||
|
||||
/* Slave interfaces on the L4_PER interconnect */
|
||||
static struct omap_hwmod_ocp_if *omap3xxx_l4_per_slaves[] = {
|
||||
&omap3xxx_l3__l4_per,
|
||||
&omap3xxx_l3_main__l4_per,
|
||||
};
|
||||
|
||||
/* Master interfaces on the L4_PER interconnect */
|
||||
|
@ -120,13 +123,14 @@ static struct omap_hwmod_ocp_if *omap3xxx_l4_per_masters[] = {
|
|||
|
||||
/* L4 PER */
|
||||
static struct omap_hwmod omap3xxx_l4_per_hwmod = {
|
||||
.name = "l4_per_hwmod",
|
||||
.name = "l4_per",
|
||||
.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)
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
|
||||
.flags = HWMOD_NO_IDLEST,
|
||||
};
|
||||
|
||||
/* Slave interfaces on the L4_WKUP interconnect */
|
||||
|
@ -140,18 +144,19 @@ static struct omap_hwmod_ocp_if *omap3xxx_l4_wkup_masters[] = {
|
|||
|
||||
/* L4 WKUP */
|
||||
static struct omap_hwmod omap3xxx_l4_wkup_hwmod = {
|
||||
.name = "l4_wkup_hwmod",
|
||||
.name = "l4_wkup",
|
||||
.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)
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
|
||||
.flags = HWMOD_NO_IDLEST,
|
||||
};
|
||||
|
||||
/* Master interfaces on the MPU device */
|
||||
static struct omap_hwmod_ocp_if *omap3xxx_mpu_masters[] = {
|
||||
&omap3xxx_mpu__l3,
|
||||
&omap3xxx_mpu__l3_main,
|
||||
};
|
||||
|
||||
/* MPU */
|
||||
|
@ -164,12 +169,41 @@ static struct omap_hwmod omap3xxx_mpu_hwmod = {
|
|||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
|
||||
};
|
||||
|
||||
/*
|
||||
* IVA2_2 interface data
|
||||
*/
|
||||
|
||||
/* IVA2 <- L3 interface */
|
||||
static struct omap_hwmod_ocp_if omap3xxx_l3__iva = {
|
||||
.master = &omap3xxx_l3_main_hwmod,
|
||||
.slave = &omap3xxx_iva_hwmod,
|
||||
.clk = "iva2_ck",
|
||||
.user = OCP_USER_MPU | OCP_USER_SDMA,
|
||||
};
|
||||
|
||||
static struct omap_hwmod_ocp_if *omap3xxx_iva_masters[] = {
|
||||
&omap3xxx_l3__iva,
|
||||
};
|
||||
|
||||
/*
|
||||
* IVA2 (IVA2)
|
||||
*/
|
||||
|
||||
static struct omap_hwmod omap3xxx_iva_hwmod = {
|
||||
.name = "iva",
|
||||
.class = &iva_hwmod_class,
|
||||
.masters = omap3xxx_iva_masters,
|
||||
.masters_cnt = ARRAY_SIZE(omap3xxx_iva_masters),
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
};
|
||||
|
||||
static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
|
||||
&omap3xxx_l3_hwmod,
|
||||
&omap3xxx_l3_main_hwmod,
|
||||
&omap3xxx_l4_core_hwmod,
|
||||
&omap3xxx_l4_per_hwmod,
|
||||
&omap3xxx_l4_wkup_hwmod,
|
||||
&omap3xxx_mpu_hwmod,
|
||||
&omap3xxx_iva_hwmod,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
|
|
@ -66,3 +66,6 @@ struct omap_hwmod_class mpu_hwmod_class = {
|
|||
.name = "mpu"
|
||||
};
|
||||
|
||||
struct omap_hwmod_class iva_hwmod_class = {
|
||||
.name = "iva"
|
||||
};
|
||||
|
|
|
@ -20,5 +20,6 @@
|
|||
extern struct omap_hwmod_class l3_hwmod_class;
|
||||
extern struct omap_hwmod_class l4_hwmod_class;
|
||||
extern struct omap_hwmod_class mpu_hwmod_class;
|
||||
extern struct omap_hwmod_class iva_hwmod_class;
|
||||
|
||||
#endif
|
||||
|
|
84
arch/arm/mach-omap2/pm.c
Normal file
84
arch/arm/mach-omap2/pm.c
Normal file
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* pm.c - Common OMAP2+ power management-related code
|
||||
*
|
||||
* Copyright (C) 2010 Texas Instruments, Inc.
|
||||
* Copyright (C) 2010 Nokia Corporation
|
||||
*
|
||||
* 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/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
#include <plat/omap-pm.h>
|
||||
#include <plat/omap_device.h>
|
||||
#include <plat/common.h>
|
||||
|
||||
static struct omap_device_pm_latency *pm_lats;
|
||||
|
||||
static struct device *mpu_dev;
|
||||
static struct device *dsp_dev;
|
||||
static struct device *l3_dev;
|
||||
|
||||
struct device *omap2_get_mpuss_device(void)
|
||||
{
|
||||
WARN_ON_ONCE(!mpu_dev);
|
||||
return mpu_dev;
|
||||
}
|
||||
|
||||
struct device *omap2_get_dsp_device(void)
|
||||
{
|
||||
WARN_ON_ONCE(!dsp_dev);
|
||||
return dsp_dev;
|
||||
}
|
||||
|
||||
struct device *omap2_get_l3_device(void)
|
||||
{
|
||||
WARN_ON_ONCE(!l3_dev);
|
||||
return l3_dev;
|
||||
}
|
||||
|
||||
/* static int _init_omap_device(struct omap_hwmod *oh, void *user) */
|
||||
static int _init_omap_device(char *name, struct device **new_dev)
|
||||
{
|
||||
struct omap_hwmod *oh;
|
||||
struct omap_device *od;
|
||||
|
||||
oh = omap_hwmod_lookup(name);
|
||||
if (WARN(!oh, "%s: could not find omap_hwmod for %s\n",
|
||||
__func__, name))
|
||||
return -ENODEV;
|
||||
|
||||
od = omap_device_build(oh->name, 0, oh, NULL, 0, pm_lats, 0, false);
|
||||
if (WARN(IS_ERR(od), "%s: could not build omap_device for %s\n",
|
||||
__func__, name))
|
||||
return -ENODEV;
|
||||
|
||||
*new_dev = &od->pdev.dev;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Build omap_devices for processors and bus.
|
||||
*/
|
||||
static void omap2_init_processor_devices(void)
|
||||
{
|
||||
_init_omap_device("mpu", &mpu_dev);
|
||||
_init_omap_device("iva", &dsp_dev);
|
||||
_init_omap_device("l3_main", &l3_dev);
|
||||
}
|
||||
|
||||
static int __init omap2_common_pm_init(void)
|
||||
{
|
||||
omap2_init_processor_devices();
|
||||
omap_pm_if_init();
|
||||
|
||||
return 0;
|
||||
}
|
||||
device_initcall(omap2_common_pm_init);
|
||||
|
|
@ -15,6 +15,7 @@ obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o
|
|||
# omap_device support (OMAP2+ only at the moment)
|
||||
obj-$(CONFIG_ARCH_OMAP2) += omap_device.o
|
||||
obj-$(CONFIG_ARCH_OMAP3) += omap_device.o
|
||||
obj-$(CONFIG_ARCH_OMAP4) += omap_device.o
|
||||
|
||||
obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
|
||||
obj-$(CONFIG_OMAP_IOMMU) += iommu.o iovmm.o
|
||||
|
|
|
@ -138,6 +138,16 @@ static inline int omap1_i2c_add_bus(struct platform_device *pdev, int bus_id)
|
|||
return platform_device_register(pdev);
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX This function is a temporary compatibility wrapper - only
|
||||
* needed until the I2C driver can be converted to call
|
||||
* omap_pm_set_max_dev_wakeup_lat() and handle a return code.
|
||||
*/
|
||||
static void omap_pm_set_max_mpu_wakeup_lat_compat(struct device *dev, long t)
|
||||
{
|
||||
omap_pm_set_max_mpu_wakeup_lat(dev, t);
|
||||
}
|
||||
|
||||
static inline int omap2_i2c_add_bus(struct platform_device *pdev, int bus_id)
|
||||
{
|
||||
struct resource *res;
|
||||
|
@ -168,7 +178,7 @@ static inline int omap2_i2c_add_bus(struct platform_device *pdev, int bus_id)
|
|||
struct omap_i2c_bus_platform_data *pd;
|
||||
|
||||
pd = pdev->dev.platform_data;
|
||||
pd->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat;
|
||||
pd->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat;
|
||||
}
|
||||
|
||||
return platform_device_register(pdev);
|
||||
|
|
|
@ -19,6 +19,22 @@ struct module;
|
|||
struct clk;
|
||||
struct clockdomain;
|
||||
|
||||
/**
|
||||
* struct clkops - some clock function pointers
|
||||
* @enable: fn ptr that enables the current clock in hardware
|
||||
* @disable: fn ptr that enables the current clock in hardware
|
||||
* @find_idlest: function returning the IDLEST register for the clock's IP blk
|
||||
* @find_companion: function returning the "companion" clk reg for the clock
|
||||
*
|
||||
* A "companion" clk is an accompanying clock to the one being queried
|
||||
* that must be enabled for the IP module connected to the clock to
|
||||
* become accessible by the hardware. Neither @find_idlest nor
|
||||
* @find_companion should be needed; that information is IP
|
||||
* block-specific; the hwmod code has been created to handle this, but
|
||||
* until hwmod data is ready and drivers have been converted to use PM
|
||||
* runtime calls in place of clk_enable()/clk_disable(), @find_idlest and
|
||||
* @find_companion must, unfortunately, remain.
|
||||
*/
|
||||
struct clkops {
|
||||
int (*enable)(struct clk *);
|
||||
void (*disable)(struct clk *);
|
||||
|
@ -30,12 +46,45 @@ struct clkops {
|
|||
|
||||
#ifdef CONFIG_ARCH_OMAP2PLUS
|
||||
|
||||
/* struct clksel_rate.flags possibilities */
|
||||
#define RATE_IN_242X (1 << 0)
|
||||
#define RATE_IN_243X (1 << 1)
|
||||
#define RATE_IN_3XXX (1 << 2) /* rates common to all OMAP3 */
|
||||
#define RATE_IN_3430ES2 (1 << 3) /* 3430ES2 rates only */
|
||||
#define RATE_IN_36XX (1 << 4)
|
||||
#define RATE_IN_4430 (1 << 5)
|
||||
|
||||
#define RATE_IN_24XX (RATE_IN_242X | RATE_IN_243X)
|
||||
#define RATE_IN_3430ES2PLUS (RATE_IN_3430ES2 | RATE_IN_36XX)
|
||||
|
||||
/**
|
||||
* struct clksel_rate - register bitfield values corresponding to clk divisors
|
||||
* @val: register bitfield value (shifted to bit 0)
|
||||
* @div: clock divisor corresponding to @val
|
||||
* @flags: (see "struct clksel_rate.flags possibilities" above)
|
||||
*
|
||||
* @val should match the value of a read from struct clk.clksel_reg
|
||||
* AND'ed with struct clk.clksel_mask, shifted right to bit 0.
|
||||
*
|
||||
* @div is the divisor that should be applied to the parent clock's rate
|
||||
* to produce the current clock's rate.
|
||||
*
|
||||
* XXX @flags probably should be replaced with an struct omap_chip.
|
||||
*/
|
||||
struct clksel_rate {
|
||||
u32 val;
|
||||
u8 div;
|
||||
u8 flags;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct clksel - available parent clocks, and a pointer to their divisors
|
||||
* @parent: struct clk * to a possible parent clock
|
||||
* @rates: available divisors for this parent clock
|
||||
*
|
||||
* A struct clksel is always associated with one or more struct clks
|
||||
* and one or more struct clksel_rates.
|
||||
*/
|
||||
struct clksel {
|
||||
struct clk *parent;
|
||||
const struct clksel_rate *rates;
|
||||
|
@ -116,6 +165,60 @@ struct dpll_data {
|
|||
|
||||
#endif
|
||||
|
||||
/* struct clk.flags possibilities */
|
||||
#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 */
|
||||
|
||||
/**
|
||||
* struct clk - OMAP struct clk
|
||||
* @node: list_head connecting this clock into the full clock list
|
||||
* @ops: struct clkops * for this clock
|
||||
* @name: the name of the clock in the hardware (used in hwmod data and debug)
|
||||
* @parent: pointer to this clock's parent struct clk
|
||||
* @children: list_head connecting to the child clks' @sibling list_heads
|
||||
* @sibling: list_head connecting this clk to its parent clk's @children
|
||||
* @rate: current clock rate
|
||||
* @enable_reg: register to write to enable the clock (see @enable_bit)
|
||||
* @recalc: fn ptr that returns the clock's current rate
|
||||
* @set_rate: fn ptr that can change the clock's current rate
|
||||
* @round_rate: fn ptr that can round the clock's current rate
|
||||
* @init: fn ptr to do clock-specific initialization
|
||||
* @enable_bit: bitshift to write to enable/disable the clock (see @enable_reg)
|
||||
* @usecount: number of users that have requested this clock to be enabled
|
||||
* @fixed_div: when > 0, this clock's rate is its parent's rate / @fixed_div
|
||||
* @flags: see "struct clk.flags possibilities" above
|
||||
* @clksel_reg: for clksel clks, register va containing src/divisor select
|
||||
* @clksel_mask: bitmask in @clksel_reg for the src/divisor selector
|
||||
* @clksel: for clksel clks, pointer to struct clksel for this clock
|
||||
* @dpll_data: for DPLLs, pointer to struct dpll_data for this clock
|
||||
* @clkdm_name: clockdomain name that this clock is contained in
|
||||
* @clkdm: pointer to struct clockdomain, resolved from @clkdm_name at runtime
|
||||
* @rate_offset: bitshift for rate selection bitfield (OMAP1 only)
|
||||
* @src_offset: bitshift for source selection bitfield (OMAP1 only)
|
||||
*
|
||||
* XXX @rate_offset, @src_offset should probably be removed and OMAP1
|
||||
* clock code converted to use clksel.
|
||||
*
|
||||
* XXX @usecount is poorly named. It should be "enable_count" or
|
||||
* something similar. "users" in the description refers to kernel
|
||||
* code (core code or drivers) that have called clk_enable() and not
|
||||
* yet called clk_disable(); the usecount of parent clocks is also
|
||||
* incremented by the clock code when clk_enable() is called on child
|
||||
* clocks and decremented by the clock code when clk_disable() is
|
||||
* called on child clocks.
|
||||
*
|
||||
* XXX @clkdm, @usecount, @children, @sibling should be marked for
|
||||
* internal use only.
|
||||
*
|
||||
* @children and @sibling are used to optimize parent-to-child clock
|
||||
* tree traversals. (child-to-parent traversals use @parent.)
|
||||
*
|
||||
* XXX The notion of the clock's current rate probably needs to be
|
||||
* separated from the clock's target rate.
|
||||
*/
|
||||
struct clk {
|
||||
struct list_head node;
|
||||
const struct clkops *ops;
|
||||
|
@ -129,8 +232,8 @@ struct clk {
|
|||
int (*set_rate)(struct clk *, unsigned long);
|
||||
long (*round_rate)(struct clk *, unsigned long);
|
||||
void (*init)(struct clk *);
|
||||
__u8 enable_bit;
|
||||
__s8 usecount;
|
||||
u8 enable_bit;
|
||||
s8 usecount;
|
||||
u8 fixed_div;
|
||||
u8 flags;
|
||||
#ifdef CONFIG_ARCH_OMAP2PLUS
|
||||
|
@ -141,8 +244,8 @@ struct clk {
|
|||
const char *clkdm_name;
|
||||
struct clockdomain *clkdm;
|
||||
#else
|
||||
__u8 rate_offset;
|
||||
__u8 src_offset;
|
||||
u8 rate_offset;
|
||||
u8 src_offset;
|
||||
#endif
|
||||
#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
|
||||
struct dentry *dent; /* For visible tree hierarchy */
|
||||
|
@ -188,23 +291,4 @@ extern const struct clkops clkops_null;
|
|||
|
||||
extern struct clk dummy_ck;
|
||||
|
||||
/* Clock flags */
|
||||
#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 RATE_IN_242X (1 << 0)
|
||||
#define RATE_IN_243X (1 << 1)
|
||||
#define RATE_IN_3XXX (1 << 2) /* rates common to all OMAP3 */
|
||||
#define RATE_IN_3430ES2 (1 << 3) /* 3430ES2 rates only */
|
||||
#define RATE_IN_36XX (1 << 4)
|
||||
#define RATE_IN_4430 (1 << 5)
|
||||
|
||||
#define RATE_IN_24XX (RATE_IN_242X | RATE_IN_243X)
|
||||
|
||||
#define RATE_IN_3430ES2PLUS (RATE_IN_3430ES2 | RATE_IN_36XX)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -87,4 +87,8 @@ void omap2_set_globals_uart(struct omap_globals *);
|
|||
} \
|
||||
})
|
||||
|
||||
extern struct device *omap2_get_mpuss_device(void);
|
||||
extern struct device *omap2_get_dsp_device(void);
|
||||
extern struct device *omap2_get_l3_device(void);
|
||||
|
||||
#endif /* __ARCH_ARM_MACH_OMAP_COMMON_H */
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* omap-pm.h - OMAP power management interface
|
||||
*
|
||||
* 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
|
||||
* Paul Walmsley
|
||||
*
|
||||
* Interface developed by (in alphabetical order): Karthik Dasu, Jouni
|
||||
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include <linux/device.h>
|
||||
#include <linux/cpufreq.h>
|
||||
#include <linux/clk.h>
|
||||
|
||||
#include "powerdomain.h"
|
||||
|
||||
|
@ -89,7 +90,7 @@ void omap_pm_if_exit(void);
|
|||
* @t: maximum MPU wakeup latency in microseconds
|
||||
*
|
||||
* Request that the maximum interrupt latency for the MPU to be no
|
||||
* greater than 't' microseconds. "Interrupt latency" in this case is
|
||||
* greater than @t microseconds. "Interrupt latency" in this case is
|
||||
* defined as the elapsed time from the occurrence of a hardware or
|
||||
* timer interrupt to the time when the device driver's interrupt
|
||||
* service routine has been entered by the MPU.
|
||||
|
@ -105,15 +106,19 @@ void omap_pm_if_exit(void);
|
|||
* elapsed from when a device driver enables a hardware device with
|
||||
* clk_enable(), to when the device is ready for register access or
|
||||
* other use. To control this device wakeup latency, use
|
||||
* set_max_dev_wakeup_lat()
|
||||
* omap_pm_set_max_dev_wakeup_lat()
|
||||
*
|
||||
* Multiple calls to set_max_mpu_wakeup_lat() will replace the
|
||||
* Multiple calls to omap_pm_set_max_mpu_wakeup_lat() will replace the
|
||||
* previous t value. To remove the latency target for the MPU, call
|
||||
* with t = -1.
|
||||
*
|
||||
* No return value.
|
||||
* XXX This constraint will be deprecated soon in favor of the more
|
||||
* general omap_pm_set_max_dev_wakeup_lat()
|
||||
*
|
||||
* Returns -EINVAL for an invalid argument, -ERANGE if the constraint
|
||||
* is not satisfiable, or 0 upon success.
|
||||
*/
|
||||
void omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t);
|
||||
int omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -123,8 +128,8 @@ void omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t);
|
|||
* @r: minimum throughput (in KiB/s)
|
||||
*
|
||||
* Request that the minimum data throughput on the OCP interconnect
|
||||
* attached to device 'dev' interconnect agent 'tbus_id' be no less
|
||||
* than 'r' KiB/s.
|
||||
* attached to device @dev interconnect agent @tbus_id be no less
|
||||
* than @r KiB/s.
|
||||
*
|
||||
* It is expected that the OMAP PM or bus code will use this
|
||||
* information to set the interconnect clock to run at the lowest
|
||||
|
@ -138,40 +143,44 @@ void omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t);
|
|||
* code will also need to add an minimum L3 interconnect speed
|
||||
* constraint,
|
||||
*
|
||||
* Multiple calls to set_min_bus_tput() will replace the previous rate
|
||||
* value for this device. To remove the interconnect throughput
|
||||
* restriction for this device, call with r = 0.
|
||||
* Multiple calls to omap_pm_set_min_bus_tput() will replace the
|
||||
* previous rate value for this device. To remove the interconnect
|
||||
* throughput restriction for this device, call with r = 0.
|
||||
*
|
||||
* No return value.
|
||||
* Returns -EINVAL for an invalid argument, -ERANGE if the constraint
|
||||
* is not satisfiable, or 0 upon success.
|
||||
*/
|
||||
void omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r);
|
||||
int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r);
|
||||
|
||||
|
||||
/**
|
||||
* omap_pm_set_max_dev_wakeup_lat - set the maximum device enable latency
|
||||
* @dev: struct device *
|
||||
* @req_dev: struct device * requesting the constraint, or NULL if none
|
||||
* @dev: struct device * to set the constraint one
|
||||
* @t: maximum device wakeup latency in microseconds
|
||||
*
|
||||
* Request that the maximum amount of time necessary for a device to
|
||||
* become accessible after its clocks are enabled should be no greater
|
||||
* than 't' microseconds. Specifically, this represents the time from
|
||||
* when a device driver enables device clocks with clk_enable(), to
|
||||
* when the register reads and writes on the device will succeed.
|
||||
* This function should be called before clk_disable() is called,
|
||||
* since the power state transition decision may be made during
|
||||
* clk_disable().
|
||||
* Request that the maximum amount of time necessary for a device @dev
|
||||
* to become accessible after its clocks are enabled should be no
|
||||
* greater than @t microseconds. Specifically, this represents the
|
||||
* time from when a device driver enables device clocks with
|
||||
* clk_enable(), to when the register reads and writes on the device
|
||||
* will succeed. This function should be called before clk_disable()
|
||||
* is called, since the power state transition decision may be made
|
||||
* during clk_disable().
|
||||
*
|
||||
* It is intended that underlying PM code will use this information to
|
||||
* determine what power state to put the powerdomain enclosing this
|
||||
* device into.
|
||||
*
|
||||
* Multiple calls to set_max_dev_wakeup_lat() will replace the
|
||||
* previous wakeup latency values for this device. To remove the wakeup
|
||||
* latency restriction for this device, call with t = -1.
|
||||
* Multiple calls to omap_pm_set_max_dev_wakeup_lat() will replace the
|
||||
* previous wakeup latency values for this device. To remove the
|
||||
* wakeup latency restriction for this device, call with t = -1.
|
||||
*
|
||||
* No return value.
|
||||
* Returns -EINVAL for an invalid argument, -ERANGE if the constraint
|
||||
* is not satisfiable, or 0 upon success.
|
||||
*/
|
||||
void omap_pm_set_max_dev_wakeup_lat(struct device *dev, long t);
|
||||
int omap_pm_set_max_dev_wakeup_lat(struct device *req_dev, struct device *dev,
|
||||
long t);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -198,11 +207,72 @@ void omap_pm_set_max_dev_wakeup_lat(struct device *dev, long t);
|
|||
* value for this device. To remove the maximum DMA latency for this
|
||||
* device, call with t = -1.
|
||||
*
|
||||
* No return value.
|
||||
* Returns -EINVAL for an invalid argument, -ERANGE if the constraint
|
||||
* is not satisfiable, or 0 upon success.
|
||||
*/
|
||||
void omap_pm_set_max_sdma_lat(struct device *dev, long t);
|
||||
int omap_pm_set_max_sdma_lat(struct device *dev, long t);
|
||||
|
||||
|
||||
/**
|
||||
* omap_pm_set_min_clk_rate - set minimum clock rate requested by @dev
|
||||
* @dev: struct device * requesting the constraint
|
||||
* @clk: struct clk * to set the minimum rate constraint on
|
||||
* @r: minimum rate in Hz
|
||||
*
|
||||
* Request that the minimum clock rate on the device @dev's clk @clk
|
||||
* be no less than @r Hz.
|
||||
*
|
||||
* It is expected that the OMAP PM code will use this information to
|
||||
* find an OPP or clock setting that will satisfy this clock rate
|
||||
* constraint, along with any other applicable system constraints on
|
||||
* the clock rate or corresponding voltage, etc.
|
||||
*
|
||||
* omap_pm_set_min_clk_rate() differs from the clock code's
|
||||
* clk_set_rate() in that it considers other constraints before taking
|
||||
* any hardware action, and may change a system OPP rather than just a
|
||||
* clock rate. clk_set_rate() is intended to be a low-level
|
||||
* interface.
|
||||
*
|
||||
* omap_pm_set_min_clk_rate() is easily open to abuse. A better API
|
||||
* would be something like "omap_pm_set_min_dev_performance()";
|
||||
* however, there is no easily-generalizable concept of performance
|
||||
* that applies to all devices. Only a device (and possibly the
|
||||
* device subsystem) has both the subsystem-specific knowledge, and
|
||||
* the hardware IP block-specific knowledge, to translate a constraint
|
||||
* on "touchscreen sampling accuracy" or "number of pixels or polygons
|
||||
* rendered per second" to a clock rate. This translation can be
|
||||
* dependent on the hardware IP block's revision, or firmware version,
|
||||
* and the driver is the only code on the system that has this
|
||||
* information and can know how to translate that into a clock rate.
|
||||
*
|
||||
* The intended use-case for this function is for userspace or other
|
||||
* kernel code to communicate a particular performance requirement to
|
||||
* a subsystem; then for the subsystem to communicate that requirement
|
||||
* to something that is meaningful to the device driver; then for the
|
||||
* device driver to convert that requirement to a clock rate, and to
|
||||
* then call omap_pm_set_min_clk_rate().
|
||||
*
|
||||
* Users of this function (such as device drivers) should not simply
|
||||
* call this function with some high clock rate to ensure "high
|
||||
* performance." Rather, the device driver should take a performance
|
||||
* constraint from its subsystem, such as "render at least X polygons
|
||||
* per second," and use some formula or table to convert that into a
|
||||
* clock rate constraint given the hardware type and hardware
|
||||
* revision. Device drivers or subsystems should not assume that they
|
||||
* know how to make a power/performance tradeoff - some device use
|
||||
* cases may tolerate a lower-fidelity device function for lower power
|
||||
* consumption; others may demand a higher-fidelity device function,
|
||||
* no matter what the power consumption.
|
||||
*
|
||||
* Multiple calls to omap_pm_set_min_clk_rate() will replace the
|
||||
* previous rate value for the device @dev. To remove the minimum clock
|
||||
* rate constraint for the device, call with r = 0.
|
||||
*
|
||||
* Returns -EINVAL for an invalid argument, -ERANGE if the constraint
|
||||
* is not satisfiable, or 0 upon success.
|
||||
*/
|
||||
int omap_pm_set_min_clk_rate(struct device *dev, struct clk *c, long r);
|
||||
|
||||
/*
|
||||
* DSP Bridge-specific constraints
|
||||
*/
|
||||
|
|
|
@ -101,6 +101,8 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
|
|||
int omap_device_register(struct omap_device *od);
|
||||
int omap_early_device_register(struct omap_device *od);
|
||||
|
||||
void __iomem *omap_device_get_rt_va(struct omap_device *od);
|
||||
|
||||
/* OMAP PM interface */
|
||||
int omap_device_align_pm_lat(struct platform_device *pdev,
|
||||
u32 new_wakeup_lat_limit);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* omap_hwmod macros, structures
|
||||
*
|
||||
* Copyright (C) 2009 Nokia Corporation
|
||||
* Copyright (C) 2009-2010 Nokia Corporation
|
||||
* Paul Walmsley
|
||||
*
|
||||
* Created in collaboration with (alphabetical order): Benoît Cousson,
|
||||
|
@ -419,7 +419,7 @@ struct omap_hwmod_class {
|
|||
* @slaves: ptr to array of OCP ifs that this hwmod can respond on
|
||||
* @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)
|
||||
* @_mpu_rt_va: cached register target start address (internal use)
|
||||
* @_mpu_port_index: cached MPU register target slave ID (internal use)
|
||||
* @msuspendmux_reg_id: CONTROL_MSUSPENDMUX register ID (1-6)
|
||||
* @msuspendmux_shift: CONTROL_MSUSPENDMUX register bit shift
|
||||
|
@ -460,7 +460,7 @@ struct omap_hwmod {
|
|||
struct omap_hwmod_ocp_if **slaves; /* connect to *_TA */
|
||||
void *dev_attr;
|
||||
u32 _sysc_cache;
|
||||
void __iomem *_rt_va;
|
||||
void __iomem *_mpu_rt_va;
|
||||
struct list_head node;
|
||||
u16 flags;
|
||||
u8 _mpu_port_index;
|
||||
|
@ -482,11 +482,14 @@ int omap_hwmod_init(struct omap_hwmod **ohs);
|
|||
int omap_hwmod_register(struct omap_hwmod *oh);
|
||||
int omap_hwmod_unregister(struct omap_hwmod *oh);
|
||||
struct omap_hwmod *omap_hwmod_lookup(const char *name);
|
||||
int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh));
|
||||
int omap_hwmod_late_init(void);
|
||||
int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh, void *data),
|
||||
void *data);
|
||||
int omap_hwmod_late_init(u8 skip_setup_idle);
|
||||
|
||||
int omap_hwmod_enable(struct omap_hwmod *oh);
|
||||
int _omap_hwmod_enable(struct omap_hwmod *oh);
|
||||
int omap_hwmod_idle(struct omap_hwmod *oh);
|
||||
int _omap_hwmod_idle(struct omap_hwmod *oh);
|
||||
int omap_hwmod_shutdown(struct omap_hwmod *oh);
|
||||
|
||||
int omap_hwmod_enable_clocks(struct omap_hwmod *oh);
|
||||
|
@ -504,6 +507,7 @@ int omap_hwmod_count_resources(struct omap_hwmod *oh);
|
|||
int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res);
|
||||
|
||||
struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh);
|
||||
void __iomem *omap_hwmod_get_mpu_rt_va(struct omap_hwmod *oh);
|
||||
|
||||
int omap_hwmod_add_initiator_dep(struct omap_hwmod *oh,
|
||||
struct omap_hwmod *init_oh);
|
||||
|
|
|
@ -34,11 +34,11 @@ struct omap_opp *l3_opps;
|
|||
* Device-driver-originated constraints (via board-*.c files)
|
||||
*/
|
||||
|
||||
void omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t)
|
||||
int omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t)
|
||||
{
|
||||
if (!dev || t < -1) {
|
||||
WARN_ON(1);
|
||||
return;
|
||||
WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
|
||||
return -EINVAL;
|
||||
};
|
||||
|
||||
if (t == -1)
|
||||
|
@ -58,14 +58,16 @@ void omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t)
|
|||
*
|
||||
* TI CDP code can call constraint_set here.
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r)
|
||||
int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r)
|
||||
{
|
||||
if (!dev || (agent_id != OCP_INITIATOR_AGENT &&
|
||||
agent_id != OCP_TARGET_AGENT)) {
|
||||
WARN_ON(1);
|
||||
return;
|
||||
WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
|
||||
return -EINVAL;
|
||||
};
|
||||
|
||||
if (r == 0)
|
||||
|
@ -83,13 +85,16 @@ void omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r)
|
|||
*
|
||||
* TI CDP code can call constraint_set here on the VDD2 OPP.
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void omap_pm_set_max_dev_wakeup_lat(struct device *dev, long t)
|
||||
int omap_pm_set_max_dev_wakeup_lat(struct device *req_dev, struct device *dev,
|
||||
long t)
|
||||
{
|
||||
if (!dev || t < -1) {
|
||||
WARN_ON(1);
|
||||
return;
|
||||
if (!req_dev || !dev || t < -1) {
|
||||
WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
|
||||
return -EINVAL;
|
||||
};
|
||||
|
||||
if (t == -1)
|
||||
|
@ -111,13 +116,15 @@ void omap_pm_set_max_dev_wakeup_lat(struct device *dev, long t)
|
|||
*
|
||||
* TI CDP code can call constraint_set here.
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void omap_pm_set_max_sdma_lat(struct device *dev, long t)
|
||||
int omap_pm_set_max_sdma_lat(struct device *dev, long t)
|
||||
{
|
||||
if (!dev || t < -1) {
|
||||
WARN_ON(1);
|
||||
return;
|
||||
WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
|
||||
return -EINVAL;
|
||||
};
|
||||
|
||||
if (t == -1)
|
||||
|
@ -139,8 +146,36 @@ void omap_pm_set_max_sdma_lat(struct device *dev, long t)
|
|||
* TI CDP code can call constraint_set here.
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int omap_pm_set_min_clk_rate(struct device *dev, struct clk *c, long r)
|
||||
{
|
||||
if (!dev || !c || r < 0) {
|
||||
WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (r == 0)
|
||||
pr_debug("OMAP PM: remove min clk rate constraint: "
|
||||
"dev %s\n", dev_name(dev));
|
||||
else
|
||||
pr_debug("OMAP PM: add min clk rate constraint: "
|
||||
"dev %s, rate = %ld Hz\n", dev_name(dev), r);
|
||||
|
||||
/*
|
||||
* Code in a real implementation should keep track of these
|
||||
* constraints on the clock, and determine the highest minimum
|
||||
* clock rate. It should iterate over each OPP and determine
|
||||
* whether the OPP will result in a clock rate that would
|
||||
* satisfy this constraint (and any other PM constraint in effect
|
||||
* at that time). Once it finds the lowest-voltage OPP that
|
||||
* meets those conditions, it should switch to it, or return
|
||||
* an error if the code is not capable of doing so.
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* DSP Bridge-specific constraints
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* omap_device implementation
|
||||
*
|
||||
* Copyright (C) 2009 Nokia Corporation
|
||||
* Copyright (C) 2009-2010 Nokia Corporation
|
||||
* Paul Walmsley, Kevin Hilman
|
||||
*
|
||||
* Developed in collaboration with (alphabetical order): Benoit
|
||||
|
@ -90,8 +90,11 @@
|
|||
#define USE_WAKEUP_LAT 0
|
||||
#define IGNORE_WAKEUP_LAT 1
|
||||
|
||||
|
||||
#define OMAP_DEVICE_MAGIC 0xf00dcafe
|
||||
/*
|
||||
* OMAP_DEVICE_MAGIC: used to determine whether a struct omap_device
|
||||
* obtained via container_of() is in fact a struct omap_device
|
||||
*/
|
||||
#define OMAP_DEVICE_MAGIC 0xf00dcafe
|
||||
|
||||
/* Private functions */
|
||||
|
||||
|
@ -359,7 +362,7 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
|
|||
struct omap_device *od;
|
||||
char *pdev_name2;
|
||||
struct resource *res = NULL;
|
||||
int res_count;
|
||||
int i, res_count;
|
||||
struct omap_hwmod **hwmods;
|
||||
|
||||
if (!ohs || oh_cnt == 0 || !pdev_name)
|
||||
|
@ -416,6 +419,9 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
|
|||
else
|
||||
ret = omap_device_register(od);
|
||||
|
||||
for (i = 0; i < oh_cnt; i++)
|
||||
hwmods[i]->od = od;
|
||||
|
||||
if (ret)
|
||||
goto odbs_exit4;
|
||||
|
||||
|
@ -652,6 +658,25 @@ struct powerdomain *omap_device_get_pwrdm(struct omap_device *od)
|
|||
return omap_hwmod_get_pwrdm(od->hwmods[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* omap_device_get_mpu_rt_va - return the MPU's virtual addr for the hwmod base
|
||||
* @od: struct omap_device *
|
||||
*
|
||||
* Return the MPU's virtual address for the base of the hwmod, from
|
||||
* the ioremap() that the hwmod code does. Only valid if there is one
|
||||
* hwmod associated with this device. Returns NULL if there are zero
|
||||
* or more than one hwmods associated with this omap_device;
|
||||
* otherwise, passes along the return value from
|
||||
* omap_hwmod_get_mpu_rt_va().
|
||||
*/
|
||||
void __iomem *omap_device_get_rt_va(struct omap_device *od)
|
||||
{
|
||||
if (od->hwmods_cnt != 1)
|
||||
return NULL;
|
||||
|
||||
return omap_hwmod_get_mpu_rt_va(od->hwmods[0]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Public functions intended for use in omap_device_pm_latency
|
||||
* .activate_func and .deactivate_func function pointers
|
||||
|
|
Loading…
Reference in a new issue