Commit 436bbc12 authored by Tony Lindgren's avatar Tony Lindgren

Merge tag 'for-v4.2/omap-hwmod-a' of...

Merge tag 'for-v4.2/omap-hwmod-a' of git://git.kernel.org/pub/scm/linux/kernel/git/pjw/omap-pending into omap-for-v4.2/soc

ARM: OMAP2+: hwmod code and data changes for v4.2

Several OMAP2+ hwmod changes for v4.2.  One patch cleans up a nasty
interaction between the OMAP GPMC and the hwmod code when debugging is
enabled.  IP block integration data has been added for the AM43xx EMIF
RAM controller.  There's also a fix for the omap-aes driver when used in
QEMU.  And finally, some changes to the OMAP3 hwmod code to support the
use of the security IP blocks (AES and SHA) on GP devices, or when they've
specifically been enabled in the DT data.

Basic build, boot, and power management test results are here:

http://www.pwsan.com/omap/testlogs/omap-hwmod-a-for-v4.2/20150601192349/
parents e2608180 a55a7445
...@@ -224,13 +224,13 @@ static int _omap_device_notifier_call(struct notifier_block *nb, ...@@ -224,13 +224,13 @@ static int _omap_device_notifier_call(struct notifier_block *nb,
*/ */
static int _omap_device_enable_hwmods(struct omap_device *od) static int _omap_device_enable_hwmods(struct omap_device *od)
{ {
int ret = 0;
int i; int i;
for (i = 0; i < od->hwmods_cnt; i++) for (i = 0; i < od->hwmods_cnt; i++)
omap_hwmod_enable(od->hwmods[i]); ret |= omap_hwmod_enable(od->hwmods[i]);
/* XXX pass along return value here? */ return ret;
return 0;
} }
/** /**
...@@ -241,13 +241,13 @@ static int _omap_device_enable_hwmods(struct omap_device *od) ...@@ -241,13 +241,13 @@ static int _omap_device_enable_hwmods(struct omap_device *od)
*/ */
static int _omap_device_idle_hwmods(struct omap_device *od) static int _omap_device_idle_hwmods(struct omap_device *od)
{ {
int ret = 0;
int i; int i;
for (i = 0; i < od->hwmods_cnt; i++) for (i = 0; i < od->hwmods_cnt; i++)
omap_hwmod_idle(od->hwmods[i]); ret |= omap_hwmod_idle(od->hwmods[i]);
/* XXX pass along return value here? */ return ret;
return 0;
} }
/* Public functions for use by core code */ /* Public functions for use by core code */
...@@ -595,18 +595,20 @@ static int _od_runtime_suspend(struct device *dev) ...@@ -595,18 +595,20 @@ static int _od_runtime_suspend(struct device *dev)
int ret; int ret;
ret = pm_generic_runtime_suspend(dev); ret = pm_generic_runtime_suspend(dev);
if (ret)
return ret;
if (!ret) return omap_device_idle(pdev);
omap_device_idle(pdev);
return ret;
} }
static int _od_runtime_resume(struct device *dev) static int _od_runtime_resume(struct device *dev)
{ {
struct platform_device *pdev = to_platform_device(dev); struct platform_device *pdev = to_platform_device(dev);
int ret;
omap_device_enable(pdev); ret = omap_device_enable(pdev);
if (ret)
return ret;
return pm_generic_runtime_resume(dev); return pm_generic_runtime_resume(dev);
} }
...@@ -743,7 +745,8 @@ int omap_device_enable(struct platform_device *pdev) ...@@ -743,7 +745,8 @@ int omap_device_enable(struct platform_device *pdev)
ret = _omap_device_enable_hwmods(od); ret = _omap_device_enable_hwmods(od);
od->_state = OMAP_DEVICE_STATE_ENABLED; if (ret == 0)
od->_state = OMAP_DEVICE_STATE_ENABLED;
return ret; return ret;
} }
...@@ -773,7 +776,8 @@ int omap_device_idle(struct platform_device *pdev) ...@@ -773,7 +776,8 @@ int omap_device_idle(struct platform_device *pdev)
ret = _omap_device_idle_hwmods(od); ret = _omap_device_idle_hwmods(od);
od->_state = OMAP_DEVICE_STATE_IDLE; if (ret == 0)
od->_state = OMAP_DEVICE_STATE_IDLE;
return ret; return ret;
} }
......
...@@ -3318,16 +3318,17 @@ int omap_hwmod_enable(struct omap_hwmod *oh) ...@@ -3318,16 +3318,17 @@ 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 r;
unsigned long flags; unsigned long flags;
if (!oh) if (!oh)
return -EINVAL; return -EINVAL;
spin_lock_irqsave(&oh->_lock, flags); spin_lock_irqsave(&oh->_lock, flags);
_idle(oh); r = _idle(oh);
spin_unlock_irqrestore(&oh->_lock, flags); spin_unlock_irqrestore(&oh->_lock, flags);
return 0; return r;
} }
/** /**
...@@ -3340,16 +3341,17 @@ int omap_hwmod_idle(struct omap_hwmod *oh) ...@@ -3340,16 +3341,17 @@ 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 r;
unsigned long flags; unsigned long flags;
if (!oh) if (!oh)
return -EINVAL; return -EINVAL;
spin_lock_irqsave(&oh->_lock, flags); spin_lock_irqsave(&oh->_lock, flags);
_shutdown(oh); r = _shutdown(oh);
spin_unlock_irqrestore(&oh->_lock, flags); spin_unlock_irqrestore(&oh->_lock, flags);
return 0; return r;
} }
/* /*
......
...@@ -109,6 +109,12 @@ extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type3; ...@@ -109,6 +109,12 @@ extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type3;
#define DEBUG_OMAPUART_FLAGS (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET) #define DEBUG_OMAPUART_FLAGS (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET)
#ifdef CONFIG_OMAP_GPMC_DEBUG
#define DEBUG_OMAP_GPMC_HWMOD_FLAGS HWMOD_INIT_NO_RESET
#else
#define DEBUG_OMAP_GPMC_HWMOD_FLAGS 0
#endif
#if defined(CONFIG_DEBUG_OMAP2UART1) #if defined(CONFIG_DEBUG_OMAP2UART1)
#undef DEBUG_OMAP2UART1_FLAGS #undef DEBUG_OMAP2UART1_FLAGS
#define DEBUG_OMAP2UART1_FLAGS DEBUG_OMAPUART_FLAGS #define DEBUG_OMAP2UART1_FLAGS DEBUG_OMAPUART_FLAGS
......
...@@ -762,16 +762,8 @@ struct omap_hwmod omap2xxx_gpmc_hwmod = { ...@@ -762,16 +762,8 @@ struct omap_hwmod omap2xxx_gpmc_hwmod = {
.name = "gpmc", .name = "gpmc",
.class = &omap2xxx_gpmc_hwmod_class, .class = &omap2xxx_gpmc_hwmod_class,
.main_clk = "gpmc_fck", .main_clk = "gpmc_fck",
/* /* Skip reset for CONFIG_OMAP_GPMC_DEBUG for bootloader timings */
* XXX HWMOD_INIT_NO_RESET should not be needed for this IP .flags = HWMOD_NO_IDLEST | DEBUG_OMAP_GPMC_HWMOD_FLAGS,
* block. It is not being added due to any known bugs with
* resetting the GPMC IP block, but rather because any timings
* set by the bootloader are not being correctly programmed by
* the kernel from the board file or DT data.
* HWMOD_INIT_NO_RESET should be removed ASAP.
*/
.flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET |
HWMOD_NO_IDLEST),
.prcm = { .prcm = {
.omap2 = { .omap2 = {
.prcm_reg_id = 3, .prcm_reg_id = 3,
......
...@@ -145,6 +145,7 @@ extern struct omap_hwmod am33xx_uart5_hwmod; ...@@ -145,6 +145,7 @@ extern struct omap_hwmod am33xx_uart5_hwmod;
extern struct omap_hwmod am33xx_uart6_hwmod; extern struct omap_hwmod am33xx_uart6_hwmod;
extern struct omap_hwmod am33xx_wd_timer1_hwmod; extern struct omap_hwmod am33xx_wd_timer1_hwmod;
extern struct omap_hwmod_class am33xx_emif_hwmod_class;
extern struct omap_hwmod_class am33xx_l4_hwmod_class; extern struct omap_hwmod_class am33xx_l4_hwmod_class;
extern struct omap_hwmod_class am33xx_wkup_m3_hwmod_class; extern struct omap_hwmod_class am33xx_wkup_m3_hwmod_class;
extern struct omap_hwmod_class am33xx_control_hwmod_class; extern struct omap_hwmod_class am33xx_control_hwmod_class;
......
...@@ -202,6 +202,19 @@ struct omap_hwmod am33xx_prcm_hwmod = { ...@@ -202,6 +202,19 @@ struct omap_hwmod am33xx_prcm_hwmod = {
.clkdm_name = "l4_wkup_clkdm", .clkdm_name = "l4_wkup_clkdm",
}; };
/*
* 'emif' class
* instance(s): emif
*/
static struct omap_hwmod_class_sysconfig am33xx_emif_sysc = {
.rev_offs = 0x0000,
};
struct omap_hwmod_class am33xx_emif_hwmod_class = {
.name = "emif",
.sysc = &am33xx_emif_sysc,
};
/* /*
* 'aes0' class * 'aes0' class
*/ */
...@@ -668,7 +681,8 @@ struct omap_hwmod am33xx_gpmc_hwmod = { ...@@ -668,7 +681,8 @@ struct omap_hwmod am33xx_gpmc_hwmod = {
.name = "gpmc", .name = "gpmc",
.class = &am33xx_gpmc_hwmod_class, .class = &am33xx_gpmc_hwmod_class,
.clkdm_name = "l3s_clkdm", .clkdm_name = "l3s_clkdm",
.flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), /* Skip reset for CONFIG_OMAP_GPMC_DEBUG for bootloader timings */
.flags = DEBUG_OMAP_GPMC_HWMOD_FLAGS,
.main_clk = "l3s_gclk", .main_clk = "l3s_gclk",
.prcm = { .prcm = {
.omap4 = { .omap4 = {
......
...@@ -34,19 +34,6 @@ ...@@ -34,19 +34,6 @@
* IP blocks * IP blocks
*/ */
/*
* 'emif' class
* instance(s): emif
*/
static struct omap_hwmod_class_sysconfig am33xx_emif_sysc = {
.rev_offs = 0x0000,
};
static struct omap_hwmod_class am33xx_emif_hwmod_class = {
.name = "emif",
.sysc = &am33xx_emif_sysc,
};
/* emif */ /* emif */
static struct omap_hwmod am33xx_emif_hwmod = { static struct omap_hwmod am33xx_emif_hwmod = {
.name = "emif", .name = "emif",
......
...@@ -2169,16 +2169,8 @@ static struct omap_hwmod omap3xxx_gpmc_hwmod = { ...@@ -2169,16 +2169,8 @@ static struct omap_hwmod omap3xxx_gpmc_hwmod = {
.clkdm_name = "core_l3_clkdm", .clkdm_name = "core_l3_clkdm",
.mpu_irqs = omap3xxx_gpmc_irqs, .mpu_irqs = omap3xxx_gpmc_irqs,
.main_clk = "gpmc_fck", .main_clk = "gpmc_fck",
/* /* Skip reset for CONFIG_OMAP_GPMC_DEBUG for bootloader timings */
* XXX HWMOD_INIT_NO_RESET should not be needed for this IP .flags = HWMOD_NO_IDLEST | DEBUG_OMAP_GPMC_HWMOD_FLAGS,
* block. It is not being added due to any known bugs with
* resetting the GPMC IP block, but rather because any timings
* set by the bootloader are not being correctly programmed by
* the kernel from the board file or DT data.
* HWMOD_INIT_NO_RESET should be removed ASAP.
*/
.flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET |
HWMOD_NO_IDLEST),
}; };
/* /*
...@@ -3744,29 +3736,54 @@ static struct omap_hwmod_ocp_if *omap3xxx_hwmod_ocp_ifs[] __initdata = { ...@@ -3744,29 +3736,54 @@ static struct omap_hwmod_ocp_if *omap3xxx_hwmod_ocp_ifs[] __initdata = {
/* GP-only hwmod links */ /* GP-only hwmod links */
static struct omap_hwmod_ocp_if *omap34xx_gp_hwmod_ocp_ifs[] __initdata = { static struct omap_hwmod_ocp_if *omap34xx_gp_hwmod_ocp_ifs[] __initdata = {
&omap3xxx_l4_sec__timer12, &omap3xxx_l4_sec__timer12,
&omap3xxx_l4_core__sham,
&omap3xxx_l4_core__aes,
NULL NULL
}; };
static struct omap_hwmod_ocp_if *omap36xx_gp_hwmod_ocp_ifs[] __initdata = { static struct omap_hwmod_ocp_if *omap36xx_gp_hwmod_ocp_ifs[] __initdata = {
&omap3xxx_l4_sec__timer12, &omap3xxx_l4_sec__timer12,
&omap3xxx_l4_core__sham,
&omap3xxx_l4_core__aes,
NULL NULL
}; };
static struct omap_hwmod_ocp_if *am35xx_gp_hwmod_ocp_ifs[] __initdata = { static struct omap_hwmod_ocp_if *am35xx_gp_hwmod_ocp_ifs[] __initdata = {
&omap3xxx_l4_sec__timer12, &omap3xxx_l4_sec__timer12,
/* NULL
* Apparently the SHA/MD5 and AES accelerator IP blocks are };
* only present on some AM35xx chips, and no one knows which
* ones. See /* crypto hwmod links */
* http://www.spinics.net/lists/arm-kernel/msg215466.html So static struct omap_hwmod_ocp_if *omap34xx_sham_hwmod_ocp_ifs[] __initdata = {
* if you need these IP blocks on an AM35xx, try uncommenting &omap3xxx_l4_core__sham,
* the following lines. NULL
*/ };
static struct omap_hwmod_ocp_if *omap34xx_aes_hwmod_ocp_ifs[] __initdata = {
&omap3xxx_l4_core__aes,
NULL
};
static struct omap_hwmod_ocp_if *omap36xx_sham_hwmod_ocp_ifs[] __initdata = {
&omap3xxx_l4_core__sham,
NULL
};
static struct omap_hwmod_ocp_if *omap36xx_aes_hwmod_ocp_ifs[] __initdata = {
&omap3xxx_l4_core__aes,
NULL
};
/*
* Apparently the SHA/MD5 and AES accelerator IP blocks are
* only present on some AM35xx chips, and no one knows which
* ones. See
* http://www.spinics.net/lists/arm-kernel/msg215466.html So
* if you need these IP blocks on an AM35xx, try uncommenting
* the following lines.
*/
static struct omap_hwmod_ocp_if *am35xx_sham_hwmod_ocp_ifs[] __initdata = {
/* &omap3xxx_l4_core__sham, */ /* &omap3xxx_l4_core__sham, */
NULL
};
static struct omap_hwmod_ocp_if *am35xx_aes_hwmod_ocp_ifs[] __initdata = {
/* &omap3xxx_l4_core__aes, */ /* &omap3xxx_l4_core__aes, */
NULL NULL
}; };
...@@ -3868,10 +3885,41 @@ static struct omap_hwmod_ocp_if *omap3xxx_dss_hwmod_ocp_ifs[] __initdata = { ...@@ -3868,10 +3885,41 @@ static struct omap_hwmod_ocp_if *omap3xxx_dss_hwmod_ocp_ifs[] __initdata = {
NULL NULL
}; };
/**
* omap3xxx_hwmod_is_hs_ip_block_usable - is a security IP block accessible?
* @bus: struct device_node * for the top-level OMAP DT data
* @dev_name: device name used in the DT file
*
* Determine whether a "secure" IP block @dev_name is usable by Linux.
* There doesn't appear to be a 100% reliable way to determine this,
* so we rely on heuristics. If @bus is null, meaning there's no DT
* data, then we only assume the IP block is accessible if the OMAP is
* fused as a 'general-purpose' SoC. If however DT data is present,
* test to see if the IP block is described in the DT data and set to
* 'status = "okay"'. If so then we assume the ODM has configured the
* OMAP firewalls to allow access to the IP block.
*
* Return: 0 if device named @dev_name is not likely to be accessible,
* or 1 if it is likely to be accessible.
*/
static int __init omap3xxx_hwmod_is_hs_ip_block_usable(struct device_node *bus,
const char *dev_name)
{
if (!bus)
return (omap_type() == OMAP2_DEVICE_TYPE_GP) ? 1 : 0;
if (of_device_is_available(of_find_node_by_name(bus, dev_name)))
return 1;
return 0;
}
int __init omap3xxx_hwmod_init(void) int __init omap3xxx_hwmod_init(void)
{ {
int r; int r;
struct omap_hwmod_ocp_if **h = NULL, **h_gp = NULL; struct omap_hwmod_ocp_if **h = NULL, **h_gp = NULL, **h_sham = NULL;
struct omap_hwmod_ocp_if **h_aes = NULL;
struct device_node *bus = NULL;
unsigned int rev; unsigned int rev;
omap_hwmod_init(); omap_hwmod_init();
...@@ -3893,13 +3941,19 @@ int __init omap3xxx_hwmod_init(void) ...@@ -3893,13 +3941,19 @@ int __init omap3xxx_hwmod_init(void)
rev == OMAP3430_REV_ES3_1 || rev == OMAP3430_REV_ES3_1_2) { rev == OMAP3430_REV_ES3_1 || rev == OMAP3430_REV_ES3_1_2) {
h = omap34xx_hwmod_ocp_ifs; h = omap34xx_hwmod_ocp_ifs;
h_gp = omap34xx_gp_hwmod_ocp_ifs; h_gp = omap34xx_gp_hwmod_ocp_ifs;
h_sham = omap34xx_sham_hwmod_ocp_ifs;
h_aes = omap34xx_aes_hwmod_ocp_ifs;
} else if (rev == AM35XX_REV_ES1_0 || rev == AM35XX_REV_ES1_1) { } else if (rev == AM35XX_REV_ES1_0 || rev == AM35XX_REV_ES1_1) {
h = am35xx_hwmod_ocp_ifs; h = am35xx_hwmod_ocp_ifs;
h_gp = am35xx_gp_hwmod_ocp_ifs; h_gp = am35xx_gp_hwmod_ocp_ifs;
h_sham = am35xx_sham_hwmod_ocp_ifs;
h_aes = am35xx_aes_hwmod_ocp_ifs;
} else if (rev == OMAP3630_REV_ES1_0 || rev == OMAP3630_REV_ES1_1 || } else if (rev == OMAP3630_REV_ES1_0 || rev == OMAP3630_REV_ES1_1 ||
rev == OMAP3630_REV_ES1_2) { rev == OMAP3630_REV_ES1_2) {
h = omap36xx_hwmod_ocp_ifs; h = omap36xx_hwmod_ocp_ifs;
h_gp = omap36xx_gp_hwmod_ocp_ifs; h_gp = omap36xx_gp_hwmod_ocp_ifs;
h_sham = omap36xx_sham_hwmod_ocp_ifs;
h_aes = omap36xx_aes_hwmod_ocp_ifs;
} else { } else {
WARN(1, "OMAP3 hwmod family init: unknown chip type\n"); WARN(1, "OMAP3 hwmod family init: unknown chip type\n");
return -EINVAL; return -EINVAL;
...@@ -3916,6 +3970,25 @@ int __init omap3xxx_hwmod_init(void) ...@@ -3916,6 +3970,25 @@ int __init omap3xxx_hwmod_init(void)
return r; return r;
} }
/*
* Register crypto hwmod links only if they are not disabled in DT.
* If DT information is missing, enable them only for GP devices.
*/
if (of_have_populated_dt())
bus = of_find_node_by_name(NULL, "ocp");
if (h_sham && omap3xxx_hwmod_is_hs_ip_block_usable(bus, "sham")) {
r = omap_hwmod_register_links(h_sham);
if (r < 0)
return r;
}
if (h_aes && omap3xxx_hwmod_is_hs_ip_block_usable(bus, "aes")) {
r = omap_hwmod_register_links(h_aes);
if (r < 0)
return r;
}
/* /*
* Register hwmod links specific to certain ES levels of a * Register hwmod links specific to certain ES levels of a
......
...@@ -24,6 +24,20 @@ ...@@ -24,6 +24,20 @@
/* IP blocks */ /* IP blocks */
static struct omap_hwmod am43xx_emif_hwmod = {
.name = "emif",
.class = &am33xx_emif_hwmod_class,
.clkdm_name = "emif_clkdm",
.flags = HWMOD_INIT_NO_IDLE,
.main_clk = "dpll_ddr_m2_ck",
.prcm = {
.omap4 = {
.clkctrl_offs = AM43XX_CM_PER_EMIF_CLKCTRL_OFFSET,
.modulemode = MODULEMODE_SWCTRL,
},
},
};
static struct omap_hwmod am43xx_l4_hs_hwmod = { static struct omap_hwmod am43xx_l4_hs_hwmod = {
.name = "l4_hs", .name = "l4_hs",
.class = &am33xx_l4_hwmod_class, .class = &am33xx_l4_hwmod_class,
...@@ -583,6 +597,13 @@ static struct omap_hwmod am43xx_vpfe1_hwmod = { ...@@ -583,6 +597,13 @@ static struct omap_hwmod am43xx_vpfe1_hwmod = {
}; };
/* Interfaces */ /* Interfaces */
static struct omap_hwmod_ocp_if am43xx_l3_main__emif = {
.master = &am33xx_l3_main_hwmod,
.slave = &am43xx_emif_hwmod,
.clk = "dpll_core_m4_ck",
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
static struct omap_hwmod_ocp_if am43xx_l3_main__l4_hs = { static struct omap_hwmod_ocp_if am43xx_l3_main__l4_hs = {
.master = &am33xx_l3_main_hwmod, .master = &am33xx_l3_main_hwmod,
.slave = &am43xx_l4_hs_hwmod, .slave = &am43xx_l4_hs_hwmod,
...@@ -918,6 +939,7 @@ static struct omap_hwmod_ocp_if *am43xx_hwmod_ocp_ifs[] __initdata = { ...@@ -918,6 +939,7 @@ static struct omap_hwmod_ocp_if *am43xx_hwmod_ocp_ifs[] __initdata = {
&am33xx_l3_main__l3_instr, &am33xx_l3_main__l3_instr,
&am33xx_l3_main__gfx, &am33xx_l3_main__gfx,
&am33xx_l3_s__l3_main, &am33xx_l3_s__l3_main,
&am43xx_l3_main__emif,
&am33xx_pruss__l3_main, &am33xx_pruss__l3_main,
&am43xx_wkup_m3__l4_wkup, &am43xx_wkup_m3__l4_wkup,
&am33xx_gfx__l3_main, &am33xx_gfx__l3_main,
......
...@@ -1188,15 +1188,8 @@ static struct omap_hwmod omap44xx_gpmc_hwmod = { ...@@ -1188,15 +1188,8 @@ static struct omap_hwmod omap44xx_gpmc_hwmod = {
.name = "gpmc", .name = "gpmc",
.class = &omap44xx_gpmc_hwmod_class, .class = &omap44xx_gpmc_hwmod_class,
.clkdm_name = "l3_2_clkdm", .clkdm_name = "l3_2_clkdm",
/* /* Skip reset for CONFIG_OMAP_GPMC_DEBUG for bootloader timings */
* XXX HWMOD_INIT_NO_RESET should not be needed for this IP .flags = DEBUG_OMAP_GPMC_HWMOD_FLAGS,
* block. It is not being added due to any known bugs with
* resetting the GPMC IP block, but rather because any timings
* set by the bootloader are not being correctly programmed by
* the kernel from the board file or DT data.
* HWMOD_INIT_NO_RESET should be removed ASAP.
*/
.flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET,
.prcm = { .prcm = {
.omap4 = { .omap4 = {
.clkctrl_offs = OMAP4_CM_L3_2_GPMC_CLKCTRL_OFFSET, .clkctrl_offs = OMAP4_CM_L3_2_GPMC_CLKCTRL_OFFSET,
......
...@@ -819,8 +819,8 @@ static struct omap_hwmod dra7xx_gpmc_hwmod = { ...@@ -819,8 +819,8 @@ static struct omap_hwmod dra7xx_gpmc_hwmod = {
.name = "gpmc", .name = "gpmc",
.class = &dra7xx_gpmc_hwmod_class, .class = &dra7xx_gpmc_hwmod_class,
.clkdm_name = "l3main1_clkdm", .clkdm_name = "l3main1_clkdm",
.flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET | /* Skip reset for CONFIG_OMAP_GPMC_DEBUG for bootloader timings */
HWMOD_SWSUP_SIDLE), .flags = HWMOD_SWSUP_SIDLE | DEBUG_OMAP_GPMC_HWMOD_FLAGS,
.main_clk = "l3_iclk_div", .main_clk = "l3_iclk_div",
.prcm = { .prcm = {
.omap4 = { .omap4 = {
......
...@@ -478,6 +478,8 @@ static struct omap_hwmod dm81xx_gpmc_hwmod = { ...@@ -478,6 +478,8 @@ static struct omap_hwmod dm81xx_gpmc_hwmod = {
.clkdm_name = "alwon_l3s_clkdm", .clkdm_name = "alwon_l3s_clkdm",
.class = &dm81xx_gpmc_hwmod_class, .class = &dm81xx_gpmc_hwmod_class,
.main_clk = "sysclk6_ck", .main_clk = "sysclk6_ck",
/* Skip reset for CONFIG_OMAP_GPMC_DEBUG for bootloader timings */
.flags = DEBUG_OMAP_GPMC_HWMOD_FLAGS,
.prcm = { .prcm = {
.omap4 = { .omap4 = {
.clkctrl_offs = DM816X_CM_ALWON_GPMC_CLKCTRL, .clkctrl_offs = DM816X_CM_ALWON_GPMC_CLKCTRL,
......
...@@ -146,4 +146,6 @@ ...@@ -146,4 +146,6 @@
#define AM43XX_CM_PER_HDQ1W_CLKCTRL_OFFSET 0x04a0 #define AM43XX_CM_PER_HDQ1W_CLKCTRL_OFFSET 0x04a0
#define AM43XX_CM_PER_VPFE0_CLKCTRL_OFFSET 0x0068 #define AM43XX_CM_PER_VPFE0_CLKCTRL_OFFSET 0x0068
#define AM43XX_CM_PER_VPFE1_CLKCTRL_OFFSET 0x0070 #define AM43XX_CM_PER_VPFE1_CLKCTRL_OFFSET 0x0070
#define AM43XX_CM_PER_EMIF_CLKCTRL_OFFSET 0x0720
#endif #endif
...@@ -49,6 +49,14 @@ config OMAP_GPMC ...@@ -49,6 +49,14 @@ config OMAP_GPMC
interfacing to a variety of asynchronous as well as synchronous interfacing to a variety of asynchronous as well as synchronous
memory drives like NOR, NAND, OneNAND, SRAM. memory drives like NOR, NAND, OneNAND, SRAM.
config OMAP_GPMC_DEBUG
bool
depends on OMAP_GPMC
help
Enables verbose debugging mostly to decode the bootloader provided
timings. Enable this during development to configure devices
connected to the GPMC bus.
config MVEBU_DEVBUS config MVEBU_DEVBUS
bool "Marvell EBU Device Bus Controller" bool "Marvell EBU Device Bus Controller"
default y default y
......
...@@ -403,7 +403,7 @@ static void gpmc_cs_bool_timings(int cs, const struct gpmc_bool_timings *p) ...@@ -403,7 +403,7 @@ static void gpmc_cs_bool_timings(int cs, const struct gpmc_bool_timings *p)
p->cycle2cyclediffcsen); p->cycle2cyclediffcsen);
} }
#ifdef DEBUG #ifdef CONFIG_OMAP_GPMC_DEBUG
/** /**
* get_gpmc_timing_reg - read a timing parameter and print DTS settings for it. * get_gpmc_timing_reg - read a timing parameter and print DTS settings for it.
* @cs: Chip Select Region * @cs: Chip Select Region
...@@ -612,7 +612,7 @@ static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit, int max ...@@ -612,7 +612,7 @@ static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit, int max
} }
l = gpmc_cs_read_reg(cs, reg); l = gpmc_cs_read_reg(cs, reg);
#ifdef DEBUG #ifdef CONFIG_OMAP_GPMC_DEBUG
pr_info( pr_info(
"GPMC CS%d: %-17s: %3d ticks, %3lu ns (was %3i ticks) %3d ns\n", "GPMC CS%d: %-17s: %3d ticks, %3lu ns (was %3i ticks) %3d ns\n",
cs, name, ticks, gpmc_get_clk_period(cs, cd) * ticks / 1000, cs, name, ticks, gpmc_get_clk_period(cs, cd) * ticks / 1000,
...@@ -767,7 +767,7 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t, ...@@ -767,7 +767,7 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t,
GPMC_CONFIG1_CLKACTIVATIONTIME_MAX, GPMC_CONFIG1_CLKACTIVATIONTIME_MAX,
clk_activation, GPMC_CD_FCLK); clk_activation, GPMC_CD_FCLK);
#ifdef DEBUG #ifdef CONFIG_OMAP_GPMC_DEBUG
pr_info("GPMC CS%d CLK period is %lu ns (div %d)\n", pr_info("GPMC CS%d CLK period is %lu ns (div %d)\n",
cs, (div * gpmc_get_fclk_period()) / 1000, div); cs, (div * gpmc_get_fclk_period()) / 1000, div);
#endif #endif
......
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