Commit 331d919a authored by Tony Lindgren's avatar Tony Lindgren

Merge branch 'for_2.6.36' of git://git.pwsan.com/linux-2.6 into omap-for-linus

parents 047b51fb fb8ce14c
...@@ -228,6 +228,12 @@ config OMAP_ARM_120MHZ ...@@ -228,6 +228,12 @@ config OMAP_ARM_120MHZ
help help
Enable 120MHz clock for OMAP CPU. If unsure, say N. 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 config OMAP_ARM_60MHZ
bool "OMAP ARM 60 MHz CPU" bool "OMAP ARM 60 MHz CPU"
depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_OMAP850) depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_OMAP850)
......
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
#include <linux/module.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/errno.h> #include <linux/errno.h>
...@@ -34,9 +33,9 @@ ...@@ -34,9 +33,9 @@
__u32 arm_idlect1_mask; __u32 arm_idlect1_mask;
struct clk *api_ck_p, *ck_dpll1_p, *ck_ref_p; struct clk *api_ck_p, *ck_dpll1_p, *ck_ref_p;
/*------------------------------------------------------------------------- /*
* Omap1 specific clock functions * Omap1 specific clock functions
*-------------------------------------------------------------------------*/ */
unsigned long omap1_uart_recalc(struct clk *clk) unsigned long omap1_uart_recalc(struct clk *clk)
{ {
...@@ -523,7 +522,8 @@ const struct clkops clkops_dspck = { ...@@ -523,7 +522,8 @@ const struct clkops clkops_dspck = {
.disable = omap1_clk_disable_dsp_domain, .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; int ret;
struct uart_clk *uclk; struct uart_clk *uclk;
...@@ -539,7 +539,8 @@ static int omap1_clk_enable_uart_functional(struct clk *clk) ...@@ -539,7 +539,8 @@ static int omap1_clk_enable_uart_functional(struct clk *clk)
return ret; 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; struct uart_clk *uclk;
...@@ -550,9 +551,10 @@ static void omap1_clk_disable_uart_functional(struct clk *clk) ...@@ -550,9 +551,10 @@ static void omap1_clk_disable_uart_functional(struct clk *clk)
omap1_clk_disable_generic(clk); omap1_clk_disable_generic(clk);
} }
const struct clkops clkops_uart = { /* XXX SYSC register handling does not belong in the clock framework */
.enable = omap1_clk_enable_uart_functional, const struct clkops clkops_uart_16xx = {
.disable = omap1_clk_disable_uart_functional, .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) 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) ...@@ -572,9 +574,9 @@ int omap1_clk_set_rate(struct clk *clk, unsigned long rate)
return ret; return ret;
} }
/*------------------------------------------------------------------------- /*
* Omap1 clock reset and init functions * Omap1 clock reset and init functions
*-------------------------------------------------------------------------*/ */
#ifdef CONFIG_OMAP_RESET_CLOCKS #ifdef CONFIG_OMAP_RESET_CLOCKS
......
...@@ -107,7 +107,7 @@ extern struct clk *api_ck_p, *ck_dpll1_p, *ck_ref_p; ...@@ -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_dspck;
extern const struct clkops clkops_dummy; 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; extern const struct clkops clkops_generic;
#endif #endif
...@@ -8,6 +8,10 @@ ...@@ -8,6 +8,10 @@
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. * 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> #include <linux/kernel.h>
...@@ -23,9 +27,49 @@ ...@@ -23,9 +27,49 @@
#include "clock.h" #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 * Omap1 clocks
*-------------------------------------------------------------------------*/ */
static struct clk ck_ref = { static struct clk ck_ref = {
.name = "ck_ref", .name = "ck_ref",
...@@ -54,7 +98,7 @@ static struct arm_idlect1_clk ck_dpll1out = { ...@@ -54,7 +98,7 @@ static struct arm_idlect1_clk ck_dpll1out = {
.enable_bit = EN_CKOUT_ARM, .enable_bit = EN_CKOUT_ARM,
.recalc = &followparent_recalc, .recalc = &followparent_recalc,
}, },
.idlect_shift = 12, .idlect_shift = IDL_CLKOUT_ARM_SHIFT,
}; };
static struct clk sossi_ck = { static struct clk sossi_ck = {
...@@ -63,7 +107,7 @@ static struct clk sossi_ck = { ...@@ -63,7 +107,7 @@ static struct clk sossi_ck = {
.parent = &ck_dpll1out.clk, .parent = &ck_dpll1out.clk,
.flags = CLOCK_NO_IDLE_PARENT | ENABLE_REG_32BIT, .flags = CLOCK_NO_IDLE_PARENT | ENABLE_REG_32BIT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_1), .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_1),
.enable_bit = 16, .enable_bit = CONF_MOD_SOSSI_CLK_EN_R,
.recalc = &omap1_sossi_recalc, .recalc = &omap1_sossi_recalc,
.set_rate = &omap1_set_sossi_rate, .set_rate = &omap1_set_sossi_rate,
}; };
...@@ -91,7 +135,7 @@ static struct arm_idlect1_clk armper_ck = { ...@@ -91,7 +135,7 @@ static struct arm_idlect1_clk armper_ck = {
.round_rate = omap1_clk_round_rate_ckctl_arm, .round_rate = omap1_clk_round_rate_ckctl_arm,
.set_rate = omap1_clk_set_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 = { ...@@ -118,7 +162,7 @@ static struct arm_idlect1_clk armxor_ck = {
.enable_bit = EN_XORPCK, .enable_bit = EN_XORPCK,
.recalc = &followparent_recalc, .recalc = &followparent_recalc,
}, },
.idlect_shift = 1, .idlect_shift = IDLXORP_ARM_SHIFT,
}; };
static struct arm_idlect1_clk armtim_ck = { static struct arm_idlect1_clk armtim_ck = {
...@@ -131,7 +175,7 @@ static struct arm_idlect1_clk armtim_ck = { ...@@ -131,7 +175,7 @@ static struct arm_idlect1_clk armtim_ck = {
.enable_bit = EN_TIMCK, .enable_bit = EN_TIMCK,
.recalc = &followparent_recalc, .recalc = &followparent_recalc,
}, },
.idlect_shift = 9, .idlect_shift = IDLTIM_ARM_SHIFT,
}; };
static struct arm_idlect1_clk armwdt_ck = { static struct arm_idlect1_clk armwdt_ck = {
...@@ -145,7 +189,7 @@ static struct arm_idlect1_clk armwdt_ck = { ...@@ -145,7 +189,7 @@ static struct arm_idlect1_clk armwdt_ck = {
.fixed_div = 14, .fixed_div = 14,
.recalc = &omap_fixed_divisor_recalc, .recalc = &omap_fixed_divisor_recalc,
}, },
.idlect_shift = 0, .idlect_shift = IDLWDT_ARM_SHIFT,
}; };
static struct clk arminth_ck16xx = { static struct clk arminth_ck16xx = {
...@@ -212,7 +256,6 @@ static struct clk dsptim_ck = { ...@@ -212,7 +256,6 @@ static struct clk dsptim_ck = {
.recalc = &followparent_recalc, .recalc = &followparent_recalc,
}; };
/* Tie ARM_IDLECT1:IDLIF_ARM to this logical clock structure */
static struct arm_idlect1_clk tc_ck = { static struct arm_idlect1_clk tc_ck = {
.clk = { .clk = {
.name = "tc_ck", .name = "tc_ck",
...@@ -224,7 +267,7 @@ static struct arm_idlect1_clk tc_ck = { ...@@ -224,7 +267,7 @@ static struct arm_idlect1_clk tc_ck = {
.round_rate = omap1_clk_round_rate_ckctl_arm, .round_rate = omap1_clk_round_rate_ckctl_arm,
.set_rate = omap1_clk_set_rate_ckctl_arm, .set_rate = omap1_clk_set_rate_ckctl_arm,
}, },
.idlect_shift = 6, .idlect_shift = IDLIF_ARM_SHIFT,
}; };
static struct clk arminth_ck1510 = { static struct clk arminth_ck1510 = {
...@@ -304,7 +347,7 @@ static struct arm_idlect1_clk api_ck = { ...@@ -304,7 +347,7 @@ static struct arm_idlect1_clk api_ck = {
.enable_bit = EN_APICK, .enable_bit = EN_APICK,
.recalc = &followparent_recalc, .recalc = &followparent_recalc,
}, },
.idlect_shift = 8, .idlect_shift = IDLAPI_ARM_SHIFT,
}; };
static struct arm_idlect1_clk lb_ck = { static struct arm_idlect1_clk lb_ck = {
...@@ -317,7 +360,7 @@ static struct arm_idlect1_clk lb_ck = { ...@@ -317,7 +360,7 @@ static struct arm_idlect1_clk lb_ck = {
.enable_bit = EN_LBCK, .enable_bit = EN_LBCK,
.recalc = &followparent_recalc, .recalc = &followparent_recalc,
}, },
.idlect_shift = 4, .idlect_shift = IDLLB_ARM_SHIFT,
}; };
static struct clk rhea1_ck = { static struct clk rhea1_ck = {
...@@ -359,9 +402,15 @@ static struct arm_idlect1_clk lcd_ck_1510 = { ...@@ -359,9 +402,15 @@ static struct arm_idlect1_clk lcd_ck_1510 = {
.round_rate = omap1_clk_round_rate_ckctl_arm, .round_rate = omap1_clk_round_rate_ckctl_arm,
.set_rate = omap1_clk_set_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 = { static struct clk uart1_1510 = {
.name = "uart1_ck", .name = "uart1_ck",
.ops = &clkops_null, .ops = &clkops_null,
...@@ -370,25 +419,37 @@ static struct clk uart1_1510 = { ...@@ -370,25 +419,37 @@ static struct clk uart1_1510 = {
.rate = 12000000, .rate = 12000000,
.flags = 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_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, .set_rate = &omap1_set_uart_rate,
.recalc = &omap1_uart_recalc, .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 = { static struct uart_clk uart1_16xx = {
.clk = { .clk = {
.name = "uart1_ck", .name = "uart1_ck",
.ops = &clkops_uart, .ops = &clkops_uart_16xx,
/* Direct from ULPD, no real parent */ /* Direct from ULPD, no real parent */
.parent = &armper_ck.clk, .parent = &armper_ck.clk,
.rate = 48000000, .rate = 48000000,
.flags = 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_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
.enable_bit = 29, .enable_bit = CONF_MOD_UART1_CLK_MODE_R,
}, },
.sysc_addr = 0xfffb0054, .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 = { static struct clk uart2_ck = {
.name = "uart2_ck", .name = "uart2_ck",
.ops = &clkops_null, .ops = &clkops_null,
...@@ -397,11 +458,17 @@ static struct clk uart2_ck = { ...@@ -397,11 +458,17 @@ static struct clk uart2_ck = {
.rate = 12000000, .rate = 12000000,
.flags = 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_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, .set_rate = &omap1_set_uart_rate,
.recalc = &omap1_uart_recalc, .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 = { static struct clk uart3_1510 = {
.name = "uart3_ck", .name = "uart3_ck",
.ops = &clkops_null, .ops = &clkops_null,
...@@ -410,21 +477,27 @@ static struct clk uart3_1510 = { ...@@ -410,21 +477,27 @@ static struct clk uart3_1510 = {
.rate = 12000000, .rate = 12000000,
.flags = 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_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, .set_rate = &omap1_set_uart_rate,
.recalc = &omap1_uart_recalc, .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 = { static struct uart_clk uart3_16xx = {
.clk = { .clk = {
.name = "uart3_ck", .name = "uart3_ck",
.ops = &clkops_uart, .ops = &clkops_uart_16xx,
/* Direct from ULPD, no real parent */ /* Direct from ULPD, no real parent */
.parent = &armper_ck.clk, .parent = &armper_ck.clk,
.rate = 48000000, .rate = 48000000,
.flags = 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_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
.enable_bit = 31, .enable_bit = CONF_MOD_UART3_CLK_MODE_R,
}, },
.sysc_addr = 0xfffb9854, .sysc_addr = 0xfffb9854,
}; };
...@@ -457,7 +530,7 @@ static struct clk usb_hhc_ck16xx = { ...@@ -457,7 +530,7 @@ static struct clk usb_hhc_ck16xx = {
/* OTG_SYSCON_2.OTG_PADEN == 0 (not 1510-compatible) */ /* OTG_SYSCON_2.OTG_PADEN == 0 (not 1510-compatible) */
.flags = ENABLE_REG_32BIT, .flags = ENABLE_REG_32BIT,
.enable_reg = OMAP1_IO_ADDRESS(OTG_BASE + 0x08), /* OTG_SYSCON_2 */ .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 = { static struct clk usb_dc_ck = {
...@@ -466,7 +539,7 @@ static struct clk usb_dc_ck = { ...@@ -466,7 +539,7 @@ static struct clk usb_dc_ck = {
/* Direct from ULPD, no parent */ /* Direct from ULPD, no parent */
.rate = 48000000, .rate = 48000000,
.enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG), .enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
.enable_bit = 4, .enable_bit = USB_REQ_EN_SHIFT,
}; };
static struct clk usb_dc_ck7xx = { static struct clk usb_dc_ck7xx = {
...@@ -475,7 +548,7 @@ static struct clk usb_dc_ck7xx = { ...@@ -475,7 +548,7 @@ static struct clk usb_dc_ck7xx = {
/* Direct from ULPD, no parent */ /* Direct from ULPD, no parent */
.rate = 48000000, .rate = 48000000,
.enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG), .enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
.enable_bit = 8, .enable_bit = SOFT_USB_OTG_DPLL_REQ_SHIFT,
}; };
static struct clk uart1_7xx = { static struct clk uart1_7xx = {
...@@ -502,7 +575,7 @@ static struct clk mclk_1510 = { ...@@ -502,7 +575,7 @@ static struct clk mclk_1510 = {
/* Direct from ULPD, no parent. May be enabled by ext hardware. */ /* Direct from ULPD, no parent. May be enabled by ext hardware. */
.rate = 12000000, .rate = 12000000,
.enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG), .enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
.enable_bit = 6, .enable_bit = SOFT_COM_MCKO_REQ_SHIFT,
}; };
static struct clk mclk_16xx = { static struct clk mclk_16xx = {
...@@ -542,9 +615,13 @@ static struct clk mmc1_ck = { ...@@ -542,9 +615,13 @@ static struct clk mmc1_ck = {
.rate = 48000000, .rate = 48000000,
.flags = 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_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 = { static struct clk mmc2_ck = {
.name = "mmc2_ck", .name = "mmc2_ck",
.ops = &clkops_generic, .ops = &clkops_generic,
...@@ -564,7 +641,7 @@ static struct clk mmc3_ck = { ...@@ -564,7 +641,7 @@ static struct clk mmc3_ck = {
.rate = 48000000, .rate = 48000000,
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT, .flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG), .enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
.enable_bit = 12, .enable_bit = SOFT_MMC_DPLL_REQ_SHIFT,
}; };
static struct clk virtual_ck_mpu = { static struct clk virtual_ck_mpu = {
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
# #
# Common support # 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 omap-2-3-common = irq.o sdrc.o
hwmod-common = omap_hwmod.o \ hwmod-common = omap_hwmod.o \
...@@ -15,7 +15,7 @@ clock-common = clock.o clock_common_data.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_OMAP2) += $(omap-2-3-common) $(prcm-common) $(hwmod-common)
obj-$(CONFIG_ARCH_OMAP3) += $(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 obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
......
...@@ -1408,7 +1408,7 @@ static struct clk ts_fck = { ...@@ -1408,7 +1408,7 @@ static struct clk ts_fck = {
static struct clk usbtll_fck = { static struct clk usbtll_fck = {
.name = "usbtll_fck", .name = "usbtll_fck",
.ops = &clkops_omap2_dflt, .ops = &clkops_omap2_dflt_wait,
.parent = &dpll5_m2_ck, .parent = &dpll5_m2_ck,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3), .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3),
.enable_bit = OMAP3430ES2_EN_USBTLL_SHIFT, .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) ...@@ -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]; cm_idlest_reg = cm_idlest_offs[idlest_id - 1];
mask = 1 << idlest_shift;
if (cpu_is_omap24xx()) if (cpu_is_omap24xx())
ena = idlest_shift; ena = mask;
else if (cpu_is_omap34xx()) else if (cpu_is_omap34xx())
ena = 0; ena = 0;
else else
BUG(); BUG();
mask = 1 << idlest_shift;
/* XXX should be OMAP2 CM */ /* XXX should be OMAP2 CM */
omap_test_timeout(((cm_read_mod_reg(prcm_mod, cm_idlest_reg) & mask) == ena), omap_test_timeout(((cm_read_mod_reg(prcm_mod, cm_idlest_reg) & mask) == ena),
MAX_MODULE_READY_TIME, i); MAX_MODULE_READY_TIME, i);
......
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#include <plat/clockdomain.h> #include <plat/clockdomain.h>
#include "clockdomains.h" #include "clockdomains.h"
#include <plat/omap_hwmod.h> #include <plat/omap_hwmod.h>
/* /*
...@@ -315,6 +316,8 @@ static int __init _omap2_init_reprogram_sdrc(void) ...@@ -315,6 +316,8 @@ static int __init _omap2_init_reprogram_sdrc(void)
void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0, void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
struct omap_sdrc_params *sdrc_cs1) struct omap_sdrc_params *sdrc_cs1)
{ {
u8 skip_setup_idle = 0;
pwrdm_init(powerdomains_omap); pwrdm_init(powerdomains_omap);
clkdm_init(clockdomains_omap, clkdm_autodeps); clkdm_init(clockdomains_omap, clkdm_autodeps);
if (cpu_is_omap242x()) if (cpu_is_omap242x())
...@@ -338,9 +341,13 @@ void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0, ...@@ -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"); pr_err("Could not init clock framework - unknown CPU\n");
omap_serial_early_init(); omap_serial_early_init();
#ifndef CONFIG_PM_RUNTIME
skip_setup_idle = 1;
#endif
if (cpu_is_omap24xx() || cpu_is_omap34xx()) /* FIXME: OMAP4 */ if (cpu_is_omap24xx() || cpu_is_omap34xx()) /* FIXME: OMAP4 */
omap_hwmod_late_init(); omap_hwmod_late_init(skip_setup_idle);
omap_pm_if_init();
if (cpu_is_omap24xx() || cpu_is_omap34xx()) { if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
omap2_sdrc_init(sdrc_cs0, sdrc_cs1); omap2_sdrc_init(sdrc_cs0, sdrc_cs1);
_omap2_init_reprogram_sdrc(); _omap2_init_reprogram_sdrc();
......
/* /*
* omap_hwmod implementation for OMAP2/3/4 * 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 * Paul Walmsley, Benoît Cousson, Kevin Hilman
* *
...@@ -423,7 +423,7 @@ static int _init_main_clk(struct omap_hwmod *oh) ...@@ -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 * * @oh: struct omap_hwmod *
* *
* Called from _init_clocks(). Populates the @oh OCP slave interface * Called from _init_clocks(). Populates the @oh OCP slave interface
...@@ -764,6 +764,7 @@ static struct omap_hwmod *_lookup(const char *name) ...@@ -764,6 +764,7 @@ static struct omap_hwmod *_lookup(const char *name)
/** /**
* _init_clocks - clk_get() all clocks associated with this hwmod * _init_clocks - clk_get() all clocks associated with this hwmod
* @oh: struct omap_hwmod * * @oh: struct omap_hwmod *
* @data: not used; pass NULL
* *
* Called by omap_hwmod_late_init() (after omap2_clk_init()). * Called by omap_hwmod_late_init() (after omap2_clk_init()).
* Resolves all clock names embedded in the hwmod. Must be called * Resolves all clock names embedded in the hwmod. Must be called
...@@ -771,7 +772,7 @@ static struct omap_hwmod *_lookup(const char *name) ...@@ -771,7 +772,7 @@ static struct omap_hwmod *_lookup(const char *name)
* has not yet been registered or if the clocks have already been * has not yet been registered or if the clocks have already been
* initialized, 0 on success, or a non-zero error on failure. * 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; int ret = 0;
...@@ -886,7 +887,7 @@ static int _reset(struct omap_hwmod *oh) ...@@ -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 * * @oh: struct omap_hwmod *
* *
* Enables an omap_hwmod @oh such that the MPU can access the hwmod's * 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) ...@@ -894,7 +895,7 @@ static int _reset(struct omap_hwmod *oh)
* Returns -EINVAL if the hwmod is in the wrong state or passes along * Returns -EINVAL if the hwmod is in the wrong state or passes along
* the return value of _wait_target_ready(). * the return value of _wait_target_ready().
*/ */
static int _enable(struct omap_hwmod *oh) int _omap_hwmod_enable(struct omap_hwmod *oh)
{ {
int r; int r;
...@@ -939,7 +940,7 @@ static int _enable(struct omap_hwmod *oh) ...@@ -939,7 +940,7 @@ static int _enable(struct omap_hwmod *oh)
* no further work. Returns -EINVAL if the hwmod is in the wrong * no further work. Returns -EINVAL if the hwmod is in the wrong
* state or returns 0. * 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) { if (oh->_state != _HWMOD_STATE_ENABLED) {
WARN(1, "omap_hwmod: %s: idle state can only be entered from " WARN(1, "omap_hwmod: %s: idle state can only be entered from "
...@@ -996,19 +997,25 @@ static int _shutdown(struct omap_hwmod *oh) ...@@ -996,19 +997,25 @@ static int _shutdown(struct omap_hwmod *oh)
/** /**
* _setup - do initial configuration of omap_hwmod * _setup - do initial configuration of omap_hwmod
* @oh: struct 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 * Writes the CLOCKACTIVITY bits @clockact to the hwmod @oh
* OCP_SYSCONFIG register. Must be called with omap_hwmod_mutex * OCP_SYSCONFIG register. Must be called with omap_hwmod_mutex held.
* held. Returns -EINVAL if the hwmod is in the wrong state or returns * @skip_setup_idle is intended to be used on a system that will not
* 0. * 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; int i, r;
u8 skip_setup_idle;
if (!oh) if (!oh || !data)
return -EINVAL; return -EINVAL;
skip_setup_idle = *(u8 *)data;
/* Set iclk autoidle mode */ /* Set iclk autoidle mode */
if (oh->slaves_cnt > 0) { if (oh->slaves_cnt > 0) {
for (i = 0; i < oh->slaves_cnt; i++) { for (i = 0; i < oh->slaves_cnt; i++) {
...@@ -1029,7 +1036,7 @@ static int _setup(struct omap_hwmod *oh) ...@@ -1029,7 +1036,7 @@ static int _setup(struct omap_hwmod *oh)
oh->_state = _HWMOD_STATE_INITIALIZED; oh->_state = _HWMOD_STATE_INITIALIZED;
r = _enable(oh); r = _omap_hwmod_enable(oh);
if (r) { if (r) {
pr_warning("omap_hwmod: %s: cannot be enabled (%d)\n", pr_warning("omap_hwmod: %s: cannot be enabled (%d)\n",
oh->name, oh->_state); oh->name, oh->_state);
...@@ -1041,7 +1048,7 @@ static int _setup(struct omap_hwmod *oh) ...@@ -1041,7 +1048,7 @@ static int _setup(struct omap_hwmod *oh)
* XXX Do the OCP_SYSCONFIG bits need to be * XXX Do the OCP_SYSCONFIG bits need to be
* reprogrammed after a reset? If not, then this can * reprogrammed after a reset? If not, then this can
* be removed. If they do, then probably the * 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. * rewrite of the OCP_SYSCONFIG register.
*/ */
if (oh->class->sysc) { if (oh->class->sysc) {
...@@ -1050,8 +1057,8 @@ static int _setup(struct omap_hwmod *oh) ...@@ -1050,8 +1057,8 @@ static int _setup(struct omap_hwmod *oh)
} }
} }
if (!(oh->flags & HWMOD_INIT_NO_IDLE)) if (!(oh->flags & HWMOD_INIT_NO_IDLE) && !skip_setup_idle)
_idle(oh); _omap_hwmod_idle(oh);
return 0; return 0;
} }
...@@ -1062,14 +1069,29 @@ static int _setup(struct omap_hwmod *oh) ...@@ -1062,14 +1069,29 @@ static int _setup(struct omap_hwmod *oh)
u32 omap_hwmod_readl(struct omap_hwmod *oh, u16 reg_offs) 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) 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) int omap_hwmod_set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode)
{ {
u32 v; u32 v;
...@@ -1124,7 +1146,7 @@ int omap_hwmod_register(struct omap_hwmod *oh) ...@@ -1124,7 +1146,7 @@ int omap_hwmod_register(struct omap_hwmod *oh)
ms_id = _find_mpu_port_index(oh); ms_id = _find_mpu_port_index(oh);
if (!IS_ERR_VALUE(ms_id)) { if (!IS_ERR_VALUE(ms_id)) {
oh->_mpu_port_index = 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 { } else {
oh->_int_flags |= _HWMOD_NO_MPU_PORT; oh->_int_flags |= _HWMOD_NO_MPU_PORT;
} }
...@@ -1164,6 +1186,7 @@ struct omap_hwmod *omap_hwmod_lookup(const char *name) ...@@ -1164,6 +1186,7 @@ struct omap_hwmod *omap_hwmod_lookup(const char *name)
/** /**
* omap_hwmod_for_each - call function for each registered omap_hwmod * omap_hwmod_for_each - call function for each registered omap_hwmod
* @fn: pointer to a callback function * @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 * Call @fn for each registered omap_hwmod, passing @data to each
* function. @fn must return 0 for success or any other value for * 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) ...@@ -1172,7 +1195,8 @@ struct omap_hwmod *omap_hwmod_lookup(const char *name)
* caller of omap_hwmod_for_each(). @fn is called with * caller of omap_hwmod_for_each(). @fn is called with
* omap_hwmod_for_each() held. * 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; struct omap_hwmod *temp_oh;
int ret; int ret;
...@@ -1182,7 +1206,7 @@ int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh)) ...@@ -1182,7 +1206,7 @@ int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh))
mutex_lock(&omap_hwmod_mutex); mutex_lock(&omap_hwmod_mutex);
list_for_each_entry(temp_oh, &omap_hwmod_list, node) { list_for_each_entry(temp_oh, &omap_hwmod_list, node) {
ret = (*fn)(temp_oh); ret = (*fn)(temp_oh, data);
if (ret) if (ret)
break; break;
} }
...@@ -1229,24 +1253,28 @@ int omap_hwmod_init(struct omap_hwmod **ohs) ...@@ -1229,24 +1253,28 @@ int omap_hwmod_init(struct omap_hwmod **ohs)
/** /**
* omap_hwmod_late_init - do some post-clock framework initialization * 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 * Must be called after omap2_clk_init(). Resolves the struct clk names
* to struct clk pointers for each registered omap_hwmod. Also calls * to struct clk pointers for each registered omap_hwmod. Also calls
* _setup() on each hwmod. Returns 0. * _setup() on each hwmod. Returns 0.
*/ */
int omap_hwmod_late_init(void) int omap_hwmod_late_init(u8 skip_setup_idle)
{ {
int r; int r;
/* XXX check return value */ /* 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"); WARN(r, "omap_hwmod: omap_hwmod_late_init(): _init_clocks failed\n");
mpu_oh = omap_hwmod_lookup(MPU_INITIATOR_NAME); mpu_oh = omap_hwmod_lookup(MPU_INITIATOR_NAME);
WARN(!mpu_oh, "omap_hwmod: could not find MPU initiator hwmod %s\n", WARN(!mpu_oh, "omap_hwmod: could not find MPU initiator hwmod %s\n",
MPU_INITIATOR_NAME); 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; return 0;
} }
...@@ -1270,7 +1298,7 @@ int omap_hwmod_unregister(struct omap_hwmod *oh) ...@@ -1270,7 +1298,7 @@ int omap_hwmod_unregister(struct omap_hwmod *oh)
pr_debug("omap_hwmod: %s: unregistering\n", oh->name); pr_debug("omap_hwmod: %s: unregistering\n", oh->name);
mutex_lock(&omap_hwmod_mutex); mutex_lock(&omap_hwmod_mutex);
iounmap(oh->_rt_va); iounmap(oh->_mpu_rt_va);
list_del(&oh->node); list_del(&oh->node);
mutex_unlock(&omap_hwmod_mutex); mutex_unlock(&omap_hwmod_mutex);
...@@ -1292,12 +1320,13 @@ int omap_hwmod_enable(struct omap_hwmod *oh) ...@@ -1292,12 +1320,13 @@ int omap_hwmod_enable(struct omap_hwmod *oh)
return -EINVAL; return -EINVAL;
mutex_lock(&omap_hwmod_mutex); mutex_lock(&omap_hwmod_mutex);
r = _enable(oh); r = _omap_hwmod_enable(oh);
mutex_unlock(&omap_hwmod_mutex); mutex_unlock(&omap_hwmod_mutex);
return r; return r;
} }
/** /**
* omap_hwmod_idle - idle an omap_hwmod * omap_hwmod_idle - idle an omap_hwmod
* @oh: struct omap_hwmod * * @oh: struct omap_hwmod *
...@@ -1311,7 +1340,7 @@ int omap_hwmod_idle(struct omap_hwmod *oh) ...@@ -1311,7 +1340,7 @@ int omap_hwmod_idle(struct omap_hwmod *oh)
return -EINVAL; return -EINVAL;
mutex_lock(&omap_hwmod_mutex); mutex_lock(&omap_hwmod_mutex);
_idle(oh); _omap_hwmod_idle(oh);
mutex_unlock(&omap_hwmod_mutex); mutex_unlock(&omap_hwmod_mutex);
return 0; return 0;
...@@ -1413,7 +1442,7 @@ int omap_hwmod_reset(struct omap_hwmod *oh) ...@@ -1413,7 +1442,7 @@ int omap_hwmod_reset(struct omap_hwmod *oh)
mutex_lock(&omap_hwmod_mutex); mutex_lock(&omap_hwmod_mutex);
r = _reset(oh); r = _reset(oh);
if (!r) if (!r)
r = _enable(oh); r = _omap_hwmod_enable(oh);
mutex_unlock(&omap_hwmod_mutex); mutex_unlock(&omap_hwmod_mutex);
return r; return r;
...@@ -1529,6 +1558,29 @@ struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh) ...@@ -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 * omap_hwmod_add_initiator_dep - add sleepdep from @init_oh to @oh
* @oh: struct omap_hwmod * * @oh: struct omap_hwmod *
......
...@@ -30,42 +30,44 @@ ...@@ -30,42 +30,44 @@
*/ */
static struct omap_hwmod omap2420_mpu_hwmod; 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; static struct omap_hwmod omap2420_l4_core_hwmod;
/* L3 -> L4_CORE interface */ /* L3 -> L4_CORE interface */
static struct omap_hwmod_ocp_if omap2420_l3__l4_core = { static struct omap_hwmod_ocp_if omap2420_l3_main__l4_core = {
.master = &omap2420_l3_hwmod, .master = &omap2420_l3_main_hwmod,
.slave = &omap2420_l4_core_hwmod, .slave = &omap2420_l4_core_hwmod,
.user = OCP_USER_MPU | OCP_USER_SDMA, .user = OCP_USER_MPU | OCP_USER_SDMA,
}; };
/* MPU -> L3 interface */ /* 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, .master = &omap2420_mpu_hwmod,
.slave = &omap2420_l3_hwmod, .slave = &omap2420_l3_main_hwmod,
.user = OCP_USER_MPU, .user = OCP_USER_MPU,
}; };
/* Slave interfaces on the L3 interconnect */ /* Slave interfaces on the L3 interconnect */
static struct omap_hwmod_ocp_if *omap2420_l3_slaves[] = { static struct omap_hwmod_ocp_if *omap2420_l3_main_slaves[] = {
&omap2420_mpu__l3, &omap2420_mpu__l3_main,
}; };
/* Master interfaces on the L3 interconnect */ /* Master interfaces on the L3 interconnect */
static struct omap_hwmod_ocp_if *omap2420_l3_masters[] = { static struct omap_hwmod_ocp_if *omap2420_l3_main_masters[] = {
&omap2420_l3__l4_core, &omap2420_l3_main__l4_core,
}; };
/* L3 */ /* L3 */
static struct omap_hwmod omap2420_l3_hwmod = { static struct omap_hwmod omap2420_l3_main_hwmod = {
.name = "l3_hwmod", .name = "l3_main",
.class = &l3_hwmod_class, .class = &l3_hwmod_class,
.masters = omap2420_l3_masters, .masters = omap2420_l3_main_masters,
.masters_cnt = ARRAY_SIZE(omap2420_l3_masters), .masters_cnt = ARRAY_SIZE(omap2420_l3_main_masters),
.slaves = omap2420_l3_slaves, .slaves = omap2420_l3_main_slaves,
.slaves_cnt = ARRAY_SIZE(omap2420_l3_slaves), .slaves_cnt = ARRAY_SIZE(omap2420_l3_main_slaves),
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420) .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
.flags = HWMOD_NO_IDLEST,
}; };
static struct omap_hwmod omap2420_l4_wkup_hwmod; static struct omap_hwmod omap2420_l4_wkup_hwmod;
...@@ -79,7 +81,7 @@ static struct omap_hwmod_ocp_if omap2420_l4_core__l4_wkup = { ...@@ -79,7 +81,7 @@ static struct omap_hwmod_ocp_if omap2420_l4_core__l4_wkup = {
/* Slave interfaces on the L4_CORE interconnect */ /* Slave interfaces on the L4_CORE interconnect */
static struct omap_hwmod_ocp_if *omap2420_l4_core_slaves[] = { 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 */ /* Master interfaces on the L4_CORE interconnect */
...@@ -89,13 +91,14 @@ static struct omap_hwmod_ocp_if *omap2420_l4_core_masters[] = { ...@@ -89,13 +91,14 @@ static struct omap_hwmod_ocp_if *omap2420_l4_core_masters[] = {
/* L4 CORE */ /* L4 CORE */
static struct omap_hwmod omap2420_l4_core_hwmod = { static struct omap_hwmod omap2420_l4_core_hwmod = {
.name = "l4_core_hwmod", .name = "l4_core",
.class = &l4_hwmod_class, .class = &l4_hwmod_class,
.masters = omap2420_l4_core_masters, .masters = omap2420_l4_core_masters,
.masters_cnt = ARRAY_SIZE(omap2420_l4_core_masters), .masters_cnt = ARRAY_SIZE(omap2420_l4_core_masters),
.slaves = omap2420_l4_core_slaves, .slaves = omap2420_l4_core_slaves,
.slaves_cnt = ARRAY_SIZE(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 */ /* Slave interfaces on the L4_WKUP interconnect */
...@@ -109,18 +112,19 @@ static struct omap_hwmod_ocp_if *omap2420_l4_wkup_masters[] = { ...@@ -109,18 +112,19 @@ static struct omap_hwmod_ocp_if *omap2420_l4_wkup_masters[] = {
/* L4 WKUP */ /* L4 WKUP */
static struct omap_hwmod omap2420_l4_wkup_hwmod = { static struct omap_hwmod omap2420_l4_wkup_hwmod = {
.name = "l4_wkup_hwmod", .name = "l4_wkup",
.class = &l4_hwmod_class, .class = &l4_hwmod_class,
.masters = omap2420_l4_wkup_masters, .masters = omap2420_l4_wkup_masters,
.masters_cnt = ARRAY_SIZE(omap2420_l4_wkup_masters), .masters_cnt = ARRAY_SIZE(omap2420_l4_wkup_masters),
.slaves = omap2420_l4_wkup_slaves, .slaves = omap2420_l4_wkup_slaves,
.slaves_cnt = ARRAY_SIZE(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 */ /* Master interfaces on the MPU device */
static struct omap_hwmod_ocp_if *omap2420_mpu_masters[] = { static struct omap_hwmod_ocp_if *omap2420_mpu_masters[] = {
&omap2420_mpu__l3, &omap2420_mpu__l3_main,
}; };
/* MPU */ /* MPU */
...@@ -133,11 +137,40 @@ static struct omap_hwmod omap2420_mpu_hwmod = { ...@@ -133,11 +137,40 @@ static struct omap_hwmod omap2420_mpu_hwmod = {
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420), .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[] = { static __initdata struct omap_hwmod *omap2420_hwmods[] = {
&omap2420_l3_hwmod, &omap2420_l3_main_hwmod,
&omap2420_l4_core_hwmod, &omap2420_l4_core_hwmod,
&omap2420_l4_wkup_hwmod, &omap2420_l4_wkup_hwmod,
&omap2420_mpu_hwmod, &omap2420_mpu_hwmod,
&omap2420_iva_hwmod,
NULL, NULL,
}; };
......
...@@ -30,47 +30,47 @@ ...@@ -30,47 +30,47 @@
*/ */
static struct omap_hwmod omap2430_mpu_hwmod; 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; static struct omap_hwmod omap2430_l4_core_hwmod;
/* L3 -> L4_CORE interface */ /* L3 -> L4_CORE interface */
static struct omap_hwmod_ocp_if omap2430_l3__l4_core = { static struct omap_hwmod_ocp_if omap2430_l3_main__l4_core = {
.master = &omap2430_l3_hwmod, .master = &omap2430_l3_main_hwmod,
.slave = &omap2430_l4_core_hwmod, .slave = &omap2430_l4_core_hwmod,
.user = OCP_USER_MPU | OCP_USER_SDMA, .user = OCP_USER_MPU | OCP_USER_SDMA,
}; };
/* MPU -> L3 interface */ /* 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, .master = &omap2430_mpu_hwmod,
.slave = &omap2430_l3_hwmod, .slave = &omap2430_l3_main_hwmod,
.user = OCP_USER_MPU, .user = OCP_USER_MPU,
}; };
/* Slave interfaces on the L3 interconnect */ /* Slave interfaces on the L3 interconnect */
static struct omap_hwmod_ocp_if *omap2430_l3_slaves[] = { static struct omap_hwmod_ocp_if *omap2430_l3_main_slaves[] = {
&omap2430_mpu__l3, &omap2430_mpu__l3_main,
}; };
/* Master interfaces on the L3 interconnect */ /* Master interfaces on the L3 interconnect */
static struct omap_hwmod_ocp_if *omap2430_l3_masters[] = { static struct omap_hwmod_ocp_if *omap2430_l3_main_masters[] = {
&omap2430_l3__l4_core, &omap2430_l3_main__l4_core,
}; };
/* L3 */ /* L3 */
static struct omap_hwmod omap2430_l3_hwmod = { static struct omap_hwmod omap2430_l3_main_hwmod = {
.name = "l3_hwmod", .name = "l3_main",
.class = &l3_hwmod_class, .class = &l3_hwmod_class,
.masters = omap2430_l3_masters, .masters = omap2430_l3_main_masters,
.masters_cnt = ARRAY_SIZE(omap2430_l3_masters), .masters_cnt = ARRAY_SIZE(omap2430_l3_main_masters),
.slaves = omap2430_l3_slaves, .slaves = omap2430_l3_main_slaves,
.slaves_cnt = ARRAY_SIZE(omap2430_l3_slaves), .slaves_cnt = ARRAY_SIZE(omap2430_l3_main_slaves),
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430) .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_l4_wkup_hwmod;
static struct omap_hwmod omap2430_mmc1_hwmod;
static struct omap_hwmod omap2430_mmc2_hwmod;
/* L4_CORE -> L4_WKUP interface */ /* L4_CORE -> L4_WKUP interface */
static struct omap_hwmod_ocp_if omap2430_l4_core__l4_wkup = { 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 = { ...@@ -81,7 +81,7 @@ static struct omap_hwmod_ocp_if omap2430_l4_core__l4_wkup = {
/* Slave interfaces on the L4_CORE interconnect */ /* Slave interfaces on the L4_CORE interconnect */
static struct omap_hwmod_ocp_if *omap2430_l4_core_slaves[] = { 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 */ /* Master interfaces on the L4_CORE interconnect */
...@@ -91,13 +91,14 @@ static struct omap_hwmod_ocp_if *omap2430_l4_core_masters[] = { ...@@ -91,13 +91,14 @@ static struct omap_hwmod_ocp_if *omap2430_l4_core_masters[] = {
/* L4 CORE */ /* L4 CORE */
static struct omap_hwmod omap2430_l4_core_hwmod = { static struct omap_hwmod omap2430_l4_core_hwmod = {
.name = "l4_core_hwmod", .name = "l4_core",
.class = &l4_hwmod_class, .class = &l4_hwmod_class,
.masters = omap2430_l4_core_masters, .masters = omap2430_l4_core_masters,
.masters_cnt = ARRAY_SIZE(omap2430_l4_core_masters), .masters_cnt = ARRAY_SIZE(omap2430_l4_core_masters),
.slaves = omap2430_l4_core_slaves, .slaves = omap2430_l4_core_slaves,
.slaves_cnt = ARRAY_SIZE(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 */ /* Slave interfaces on the L4_WKUP interconnect */
...@@ -111,18 +112,19 @@ static struct omap_hwmod_ocp_if *omap2430_l4_wkup_masters[] = { ...@@ -111,18 +112,19 @@ static struct omap_hwmod_ocp_if *omap2430_l4_wkup_masters[] = {
/* L4 WKUP */ /* L4 WKUP */
static struct omap_hwmod omap2430_l4_wkup_hwmod = { static struct omap_hwmod omap2430_l4_wkup_hwmod = {
.name = "l4_wkup_hwmod", .name = "l4_wkup",
.class = &l4_hwmod_class, .class = &l4_hwmod_class,
.masters = omap2430_l4_wkup_masters, .masters = omap2430_l4_wkup_masters,
.masters_cnt = ARRAY_SIZE(omap2430_l4_wkup_masters), .masters_cnt = ARRAY_SIZE(omap2430_l4_wkup_masters),
.slaves = omap2430_l4_wkup_slaves, .slaves = omap2430_l4_wkup_slaves,
.slaves_cnt = ARRAY_SIZE(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 */ /* Master interfaces on the MPU device */
static struct omap_hwmod_ocp_if *omap2430_mpu_masters[] = { static struct omap_hwmod_ocp_if *omap2430_mpu_masters[] = {
&omap2430_mpu__l3, &omap2430_mpu__l3_main,
}; };
/* MPU */ /* MPU */
...@@ -135,11 +137,40 @@ static struct omap_hwmod omap2430_mpu_hwmod = { ...@@ -135,11 +137,40 @@ static struct omap_hwmod omap2430_mpu_hwmod = {
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), .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[] = { static __initdata struct omap_hwmod *omap2430_hwmods[] = {
&omap2430_l3_hwmod, &omap2430_l3_main_hwmod,
&omap2430_l4_core_hwmod, &omap2430_l4_core_hwmod,
&omap2430_l4_wkup_hwmod, &omap2430_l4_wkup_hwmod,
&omap2430_mpu_hwmod, &omap2430_mpu_hwmod,
&omap2430_iva_hwmod,
NULL, NULL,
}; };
......
...@@ -32,51 +32,53 @@ ...@@ -32,51 +32,53 @@
*/ */
static struct omap_hwmod omap3xxx_mpu_hwmod; 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_core_hwmod;
static struct omap_hwmod omap3xxx_l4_per_hwmod; static struct omap_hwmod omap3xxx_l4_per_hwmod;
/* L3 -> L4_CORE interface */ /* L3 -> L4_CORE interface */
static struct omap_hwmod_ocp_if omap3xxx_l3__l4_core = { static struct omap_hwmod_ocp_if omap3xxx_l3_main__l4_core = {
.master = &omap3xxx_l3_hwmod, .master = &omap3xxx_l3_main_hwmod,
.slave = &omap3xxx_l4_core_hwmod, .slave = &omap3xxx_l4_core_hwmod,
.user = OCP_USER_MPU | OCP_USER_SDMA, .user = OCP_USER_MPU | OCP_USER_SDMA,
}; };
/* L3 -> L4_PER interface */ /* L3 -> L4_PER interface */
static struct omap_hwmod_ocp_if omap3xxx_l3__l4_per = { static struct omap_hwmod_ocp_if omap3xxx_l3_main__l4_per = {
.master = &omap3xxx_l3_hwmod, .master = &omap3xxx_l3_main_hwmod,
.slave = &omap3xxx_l4_per_hwmod, .slave = &omap3xxx_l4_per_hwmod,
.user = OCP_USER_MPU | OCP_USER_SDMA, .user = OCP_USER_MPU | OCP_USER_SDMA,
}; };
/* MPU -> L3 interface */ /* 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, .master = &omap3xxx_mpu_hwmod,
.slave = &omap3xxx_l3_hwmod, .slave = &omap3xxx_l3_main_hwmod,
.user = OCP_USER_MPU, .user = OCP_USER_MPU,
}; };
/* Slave interfaces on the L3 interconnect */ /* Slave interfaces on the L3 interconnect */
static struct omap_hwmod_ocp_if *omap3xxx_l3_slaves[] = { static struct omap_hwmod_ocp_if *omap3xxx_l3_main_slaves[] = {
&omap3xxx_mpu__l3, &omap3xxx_mpu__l3_main,
}; };
/* Master interfaces on the L3 interconnect */ /* Master interfaces on the L3 interconnect */
static struct omap_hwmod_ocp_if *omap3xxx_l3_masters[] = { static struct omap_hwmod_ocp_if *omap3xxx_l3_main_masters[] = {
&omap3xxx_l3__l4_core, &omap3xxx_l3_main__l4_core,
&omap3xxx_l3__l4_per, &omap3xxx_l3_main__l4_per,
}; };
/* L3 */ /* L3 */
static struct omap_hwmod omap3xxx_l3_hwmod = { static struct omap_hwmod omap3xxx_l3_main_hwmod = {
.name = "l3_hwmod", .name = "l3_main",
.class = &l3_hwmod_class, .class = &l3_hwmod_class,
.masters = omap3xxx_l3_masters, .masters = omap3xxx_l3_main_masters,
.masters_cnt = ARRAY_SIZE(omap3xxx_l3_masters), .masters_cnt = ARRAY_SIZE(omap3xxx_l3_main_masters),
.slaves = omap3xxx_l3_slaves, .slaves = omap3xxx_l3_main_slaves,
.slaves_cnt = ARRAY_SIZE(omap3xxx_l3_slaves), .slaves_cnt = ARRAY_SIZE(omap3xxx_l3_main_slaves),
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
.flags = HWMOD_NO_IDLEST,
}; };
static struct omap_hwmod omap3xxx_l4_wkup_hwmod; static struct omap_hwmod omap3xxx_l4_wkup_hwmod;
...@@ -90,7 +92,7 @@ static struct omap_hwmod_ocp_if omap3xxx_l4_core__l4_wkup = { ...@@ -90,7 +92,7 @@ static struct omap_hwmod_ocp_if omap3xxx_l4_core__l4_wkup = {
/* Slave interfaces on the L4_CORE interconnect */ /* Slave interfaces on the L4_CORE interconnect */
static struct omap_hwmod_ocp_if *omap3xxx_l4_core_slaves[] = { 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 */ /* Master interfaces on the L4_CORE interconnect */
...@@ -100,18 +102,19 @@ static struct omap_hwmod_ocp_if *omap3xxx_l4_core_masters[] = { ...@@ -100,18 +102,19 @@ static struct omap_hwmod_ocp_if *omap3xxx_l4_core_masters[] = {
/* L4 CORE */ /* L4 CORE */
static struct omap_hwmod omap3xxx_l4_core_hwmod = { static struct omap_hwmod omap3xxx_l4_core_hwmod = {
.name = "l4_core_hwmod", .name = "l4_core",
.class = &l4_hwmod_class, .class = &l4_hwmod_class,
.masters = omap3xxx_l4_core_masters, .masters = omap3xxx_l4_core_masters,
.masters_cnt = ARRAY_SIZE(omap3xxx_l4_core_masters), .masters_cnt = ARRAY_SIZE(omap3xxx_l4_core_masters),
.slaves = omap3xxx_l4_core_slaves, .slaves = omap3xxx_l4_core_slaves,
.slaves_cnt = ARRAY_SIZE(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 */ /* Slave interfaces on the L4_PER interconnect */
static struct omap_hwmod_ocp_if *omap3xxx_l4_per_slaves[] = { 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 */ /* Master interfaces on the L4_PER interconnect */
...@@ -120,13 +123,14 @@ static struct omap_hwmod_ocp_if *omap3xxx_l4_per_masters[] = { ...@@ -120,13 +123,14 @@ static struct omap_hwmod_ocp_if *omap3xxx_l4_per_masters[] = {
/* L4 PER */ /* L4 PER */
static struct omap_hwmod omap3xxx_l4_per_hwmod = { static struct omap_hwmod omap3xxx_l4_per_hwmod = {
.name = "l4_per_hwmod", .name = "l4_per",
.class = &l4_hwmod_class, .class = &l4_hwmod_class,
.masters = omap3xxx_l4_per_masters, .masters = omap3xxx_l4_per_masters,
.masters_cnt = ARRAY_SIZE(omap3xxx_l4_per_masters), .masters_cnt = ARRAY_SIZE(omap3xxx_l4_per_masters),
.slaves = omap3xxx_l4_per_slaves, .slaves = omap3xxx_l4_per_slaves,
.slaves_cnt = ARRAY_SIZE(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 */ /* Slave interfaces on the L4_WKUP interconnect */
...@@ -140,18 +144,19 @@ static struct omap_hwmod_ocp_if *omap3xxx_l4_wkup_masters[] = { ...@@ -140,18 +144,19 @@ static struct omap_hwmod_ocp_if *omap3xxx_l4_wkup_masters[] = {
/* L4 WKUP */ /* L4 WKUP */
static struct omap_hwmod omap3xxx_l4_wkup_hwmod = { static struct omap_hwmod omap3xxx_l4_wkup_hwmod = {
.name = "l4_wkup_hwmod", .name = "l4_wkup",
.class = &l4_hwmod_class, .class = &l4_hwmod_class,
.masters = omap3xxx_l4_wkup_masters, .masters = omap3xxx_l4_wkup_masters,
.masters_cnt = ARRAY_SIZE(omap3xxx_l4_wkup_masters), .masters_cnt = ARRAY_SIZE(omap3xxx_l4_wkup_masters),
.slaves = omap3xxx_l4_wkup_slaves, .slaves = omap3xxx_l4_wkup_slaves,
.slaves_cnt = ARRAY_SIZE(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 */ /* Master interfaces on the MPU device */
static struct omap_hwmod_ocp_if *omap3xxx_mpu_masters[] = { static struct omap_hwmod_ocp_if *omap3xxx_mpu_masters[] = {
&omap3xxx_mpu__l3, &omap3xxx_mpu__l3_main,
}; };
/* MPU */ /* MPU */
...@@ -164,12 +169,41 @@ static struct omap_hwmod omap3xxx_mpu_hwmod = { ...@@ -164,12 +169,41 @@ static struct omap_hwmod omap3xxx_mpu_hwmod = {
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), .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[] = { static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
&omap3xxx_l3_hwmod, &omap3xxx_l3_main_hwmod,
&omap3xxx_l4_core_hwmod, &omap3xxx_l4_core_hwmod,
&omap3xxx_l4_per_hwmod, &omap3xxx_l4_per_hwmod,
&omap3xxx_l4_wkup_hwmod, &omap3xxx_l4_wkup_hwmod,
&omap3xxx_mpu_hwmod, &omap3xxx_mpu_hwmod,
&omap3xxx_iva_hwmod,
NULL, NULL,
}; };
......
...@@ -66,3 +66,6 @@ struct omap_hwmod_class mpu_hwmod_class = { ...@@ -66,3 +66,6 @@ struct omap_hwmod_class mpu_hwmod_class = {
.name = "mpu" .name = "mpu"
}; };
struct omap_hwmod_class iva_hwmod_class = {
.name = "iva"
};
...@@ -20,5 +20,6 @@ ...@@ -20,5 +20,6 @@
extern struct omap_hwmod_class l3_hwmod_class; extern struct omap_hwmod_class l3_hwmod_class;
extern struct omap_hwmod_class l4_hwmod_class; extern struct omap_hwmod_class l4_hwmod_class;
extern struct omap_hwmod_class mpu_hwmod_class; extern struct omap_hwmod_class mpu_hwmod_class;
extern struct omap_hwmod_class iva_hwmod_class;
#endif #endif
/*
* 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 ...@@ -15,6 +15,7 @@ obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o
# omap_device support (OMAP2+ only at the moment) # omap_device support (OMAP2+ only at the moment)
obj-$(CONFIG_ARCH_OMAP2) += omap_device.o obj-$(CONFIG_ARCH_OMAP2) += omap_device.o
obj-$(CONFIG_ARCH_OMAP3) += 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_MCBSP) += mcbsp.o
obj-$(CONFIG_OMAP_IOMMU) += iommu.o iovmm.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) ...@@ -138,6 +138,16 @@ static inline int omap1_i2c_add_bus(struct platform_device *pdev, int bus_id)
return platform_device_register(pdev); 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) static inline int omap2_i2c_add_bus(struct platform_device *pdev, int bus_id)
{ {
struct resource *res; struct resource *res;
...@@ -168,7 +178,7 @@ static inline int omap2_i2c_add_bus(struct platform_device *pdev, int bus_id) ...@@ -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; struct omap_i2c_bus_platform_data *pd;
pd = pdev->dev.platform_data; 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); return platform_device_register(pdev);
......
...@@ -19,6 +19,22 @@ struct module; ...@@ -19,6 +19,22 @@ struct module;
struct clk; struct clk;
struct clockdomain; 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 { struct clkops {
int (*enable)(struct clk *); int (*enable)(struct clk *);
void (*disable)(struct clk *); void (*disable)(struct clk *);
...@@ -30,12 +46,45 @@ struct clkops { ...@@ -30,12 +46,45 @@ struct clkops {
#ifdef CONFIG_ARCH_OMAP2PLUS #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 { struct clksel_rate {
u32 val; u32 val;
u8 div; u8 div;
u8 flags; 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 clksel {
struct clk *parent; struct clk *parent;
const struct clksel_rate *rates; const struct clksel_rate *rates;
...@@ -116,6 +165,60 @@ struct dpll_data { ...@@ -116,6 +165,60 @@ struct dpll_data {
#endif #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 clk {
struct list_head node; struct list_head node;
const struct clkops *ops; const struct clkops *ops;
...@@ -129,8 +232,8 @@ struct clk { ...@@ -129,8 +232,8 @@ struct clk {
int (*set_rate)(struct clk *, unsigned long); int (*set_rate)(struct clk *, unsigned long);
long (*round_rate)(struct clk *, unsigned long); long (*round_rate)(struct clk *, unsigned long);
void (*init)(struct clk *); void (*init)(struct clk *);
__u8 enable_bit; u8 enable_bit;
__s8 usecount; s8 usecount;
u8 fixed_div; u8 fixed_div;
u8 flags; u8 flags;
#ifdef CONFIG_ARCH_OMAP2PLUS #ifdef CONFIG_ARCH_OMAP2PLUS
...@@ -141,8 +244,8 @@ struct clk { ...@@ -141,8 +244,8 @@ struct clk {
const char *clkdm_name; const char *clkdm_name;
struct clockdomain *clkdm; struct clockdomain *clkdm;
#else #else
__u8 rate_offset; u8 rate_offset;
__u8 src_offset; u8 src_offset;
#endif #endif
#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS) #if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
struct dentry *dent; /* For visible tree hierarchy */ struct dentry *dent; /* For visible tree hierarchy */
...@@ -188,23 +291,4 @@ extern const struct clkops clkops_null; ...@@ -188,23 +291,4 @@ extern const struct clkops clkops_null;
extern struct clk dummy_ck; 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 #endif
...@@ -87,4 +87,8 @@ void omap2_set_globals_uart(struct omap_globals *); ...@@ -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 */ #endif /* __ARCH_ARM_MACH_OMAP_COMMON_H */
/* /*
* omap-pm.h - OMAP power management interface * omap-pm.h - OMAP power management interface
* *
* Copyright (C) 2008-2009 Texas Instruments, Inc. * Copyright (C) 2008-2010 Texas Instruments, Inc.
* Copyright (C) 2008-2009 Nokia Corporation * Copyright (C) 2008-2010 Nokia Corporation
* Paul Walmsley * Paul Walmsley
* *
* Interface developed by (in alphabetical order): Karthik Dasu, Jouni * Interface developed by (in alphabetical order): Karthik Dasu, Jouni
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <linux/device.h> #include <linux/device.h>
#include <linux/cpufreq.h> #include <linux/cpufreq.h>
#include <linux/clk.h>
#include "powerdomain.h" #include "powerdomain.h"
...@@ -89,7 +90,7 @@ void omap_pm_if_exit(void); ...@@ -89,7 +90,7 @@ void omap_pm_if_exit(void);
* @t: maximum MPU wakeup latency in microseconds * @t: maximum MPU wakeup latency in microseconds
* *
* Request that the maximum interrupt latency for the MPU to be no * 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 * defined as the elapsed time from the occurrence of a hardware or
* timer interrupt to the time when the device driver's interrupt * timer interrupt to the time when the device driver's interrupt
* service routine has been entered by the MPU. * service routine has been entered by the MPU.
...@@ -105,15 +106,19 @@ void omap_pm_if_exit(void); ...@@ -105,15 +106,19 @@ void omap_pm_if_exit(void);
* elapsed from when a device driver enables a hardware device with * elapsed from when a device driver enables a hardware device with
* clk_enable(), to when the device is ready for register access or * clk_enable(), to when the device is ready for register access or
* other use. To control this device wakeup latency, use * 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 * previous t value. To remove the latency target for the MPU, call
* with t = -1. * 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); ...@@ -123,8 +128,8 @@ void omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t);
* @r: minimum throughput (in KiB/s) * @r: minimum throughput (in KiB/s)
* *
* Request that the minimum data throughput on the OCP interconnect * Request that the minimum data throughput on the OCP interconnect
* attached to device 'dev' interconnect agent 'tbus_id' be no less * attached to device @dev interconnect agent @tbus_id be no less
* than 'r' KiB/s. * than @r KiB/s.
* *
* It is expected that the OMAP PM or bus code will use this * It is expected that the OMAP PM or bus code will use this
* information to set the interconnect clock to run at the lowest * 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); ...@@ -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 * code will also need to add an minimum L3 interconnect speed
* constraint, * constraint,
* *
* Multiple calls to set_min_bus_tput() will replace the previous rate * Multiple calls to omap_pm_set_min_bus_tput() will replace the
* value for this device. To remove the interconnect throughput * previous rate value for this device. To remove the interconnect
* restriction for this device, call with r = 0. * 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 * 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 * @t: maximum device wakeup latency in microseconds
* *
* Request that the maximum amount of time necessary for a device to * Request that the maximum amount of time necessary for a device @dev
* become accessible after its clocks are enabled should be no greater * to become accessible after its clocks are enabled should be no
* than 't' microseconds. Specifically, this represents the time from * greater than @t microseconds. Specifically, this represents the
* when a device driver enables device clocks with clk_enable(), to * time from when a device driver enables device clocks with
* when the register reads and writes on the device will succeed. * clk_enable(), to when the register reads and writes on the device
* This function should be called before clk_disable() is called, * will succeed. This function should be called before clk_disable()
* since the power state transition decision may be made during * is called, since the power state transition decision may be made
* clk_disable(). * during clk_disable().
* *
* It is intended that underlying PM code will use this information to * It is intended that underlying PM code will use this information to
* determine what power state to put the powerdomain enclosing this * determine what power state to put the powerdomain enclosing this
* device into. * device into.
* *
* Multiple calls to set_max_dev_wakeup_lat() will replace the * Multiple calls to omap_pm_set_max_dev_wakeup_lat() will replace the
* previous wakeup latency values for this device. To remove the wakeup * previous wakeup latency values for this device. To remove the
* latency restriction for this device, call with t = -1. * 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,10 +207,71 @@ void omap_pm_set_max_dev_wakeup_lat(struct device *dev, long t); ...@@ -198,10 +207,71 @@ 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 * value for this device. To remove the maximum DMA latency for this
* device, call with t = -1. * 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 * DSP Bridge-specific constraints
......
...@@ -101,6 +101,8 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id, ...@@ -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_device_register(struct omap_device *od);
int omap_early_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 */ /* OMAP PM interface */
int omap_device_align_pm_lat(struct platform_device *pdev, int omap_device_align_pm_lat(struct platform_device *pdev,
u32 new_wakeup_lat_limit); u32 new_wakeup_lat_limit);
......
/* /*
* omap_hwmod macros, structures * omap_hwmod macros, structures
* *
* Copyright (C) 2009 Nokia Corporation * Copyright (C) 2009-2010 Nokia Corporation
* Paul Walmsley * Paul Walmsley
* *
* Created in collaboration with (alphabetical order): Benoît Cousson, * Created in collaboration with (alphabetical order): Benoît Cousson,
...@@ -419,7 +419,7 @@ struct omap_hwmod_class { ...@@ -419,7 +419,7 @@ struct omap_hwmod_class {
* @slaves: ptr to array of OCP ifs that this hwmod can respond on * @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 * @dev_attr: arbitrary device attributes that can be passed to the driver
* @_sysc_cache: internal-use hwmod flags * @_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) * @_mpu_port_index: cached MPU register target slave ID (internal use)
* @msuspendmux_reg_id: CONTROL_MSUSPENDMUX register ID (1-6) * @msuspendmux_reg_id: CONTROL_MSUSPENDMUX register ID (1-6)
* @msuspendmux_shift: CONTROL_MSUSPENDMUX register bit shift * @msuspendmux_shift: CONTROL_MSUSPENDMUX register bit shift
...@@ -460,7 +460,7 @@ struct omap_hwmod { ...@@ -460,7 +460,7 @@ struct omap_hwmod {
struct omap_hwmod_ocp_if **slaves; /* connect to *_TA */ struct omap_hwmod_ocp_if **slaves; /* connect to *_TA */
void *dev_attr; void *dev_attr;
u32 _sysc_cache; u32 _sysc_cache;
void __iomem *_rt_va; void __iomem *_mpu_rt_va;
struct list_head node; struct list_head node;
u16 flags; u16 flags;
u8 _mpu_port_index; u8 _mpu_port_index;
...@@ -482,11 +482,14 @@ int omap_hwmod_init(struct omap_hwmod **ohs); ...@@ -482,11 +482,14 @@ int omap_hwmod_init(struct omap_hwmod **ohs);
int omap_hwmod_register(struct omap_hwmod *oh); int omap_hwmod_register(struct omap_hwmod *oh);
int omap_hwmod_unregister(struct omap_hwmod *oh); int omap_hwmod_unregister(struct omap_hwmod *oh);
struct omap_hwmod *omap_hwmod_lookup(const char *name); struct omap_hwmod *omap_hwmod_lookup(const char *name);
int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh)); int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh, void *data),
int omap_hwmod_late_init(void); 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_enable(struct omap_hwmod *oh);
int omap_hwmod_idle(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_shutdown(struct omap_hwmod *oh);
int omap_hwmod_enable_clocks(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); ...@@ -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); int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res);
struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh); 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, int omap_hwmod_add_initiator_dep(struct omap_hwmod *oh,
struct omap_hwmod *init_oh); struct omap_hwmod *init_oh);
......
...@@ -34,11 +34,11 @@ struct omap_opp *l3_opps; ...@@ -34,11 +34,11 @@ struct omap_opp *l3_opps;
* Device-driver-originated constraints (via board-*.c files) * 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) { if (!dev || t < -1) {
WARN_ON(1); WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
return; return -EINVAL;
}; };
if (t == -1) if (t == -1)
...@@ -58,14 +58,16 @@ void omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t) ...@@ -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. * 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 && if (!dev || (agent_id != OCP_INITIATOR_AGENT &&
agent_id != OCP_TARGET_AGENT)) { agent_id != OCP_TARGET_AGENT)) {
WARN_ON(1); WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
return; return -EINVAL;
}; };
if (r == 0) if (r == 0)
...@@ -83,13 +85,16 @@ void omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r) ...@@ -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. * 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) { if (!req_dev || !dev || t < -1) {
WARN_ON(1); WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
return; return -EINVAL;
}; };
if (t == -1) if (t == -1)
...@@ -111,13 +116,15 @@ void omap_pm_set_max_dev_wakeup_lat(struct device *dev, long t) ...@@ -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. * 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) { if (!dev || t < -1) {
WARN_ON(1); WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
return; return -EINVAL;
}; };
if (t == -1) if (t == -1)
...@@ -139,8 +146,36 @@ void omap_pm_set_max_sdma_lat(struct device *dev, long t) ...@@ -139,8 +146,36 @@ void omap_pm_set_max_sdma_lat(struct device *dev, long t)
* TI CDP code can call constraint_set here. * 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 * DSP Bridge-specific constraints
......
/* /*
* omap_device implementation * omap_device implementation
* *
* Copyright (C) 2009 Nokia Corporation * Copyright (C) 2009-2010 Nokia Corporation
* Paul Walmsley, Kevin Hilman * Paul Walmsley, Kevin Hilman
* *
* Developed in collaboration with (alphabetical order): Benoit * Developed in collaboration with (alphabetical order): Benoit
...@@ -90,7 +90,10 @@ ...@@ -90,7 +90,10 @@
#define USE_WAKEUP_LAT 0 #define USE_WAKEUP_LAT 0
#define IGNORE_WAKEUP_LAT 1 #define IGNORE_WAKEUP_LAT 1
/*
* 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 #define OMAP_DEVICE_MAGIC 0xf00dcafe
/* Private functions */ /* Private functions */
...@@ -359,7 +362,7 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id, ...@@ -359,7 +362,7 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
struct omap_device *od; struct omap_device *od;
char *pdev_name2; char *pdev_name2;
struct resource *res = NULL; struct resource *res = NULL;
int res_count; int i, res_count;
struct omap_hwmod **hwmods; struct omap_hwmod **hwmods;
if (!ohs || oh_cnt == 0 || !pdev_name) 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, ...@@ -416,6 +419,9 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
else else
ret = omap_device_register(od); ret = omap_device_register(od);
for (i = 0; i < oh_cnt; i++)
hwmods[i]->od = od;
if (ret) if (ret)
goto odbs_exit4; goto odbs_exit4;
...@@ -652,6 +658,25 @@ struct powerdomain *omap_device_get_pwrdm(struct omap_device *od) ...@@ -652,6 +658,25 @@ struct powerdomain *omap_device_get_pwrdm(struct omap_device *od)
return omap_hwmod_get_pwrdm(od->hwmods[0]); 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 * Public functions intended for use in omap_device_pm_latency
* .activate_func and .deactivate_func function pointers * .activate_func and .deactivate_func function pointers
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment