Commit 077bb25c authored by Arnd Bergmann's avatar Arnd Bergmann

Merge tag 'omap-for-v3.14/fixes-rc4' of...

Merge tag 'omap-for-v3.14/fixes-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into fixes

Omap fixes from Tony Lindgren:

Fixes for omaps mostly to fix the 3430 display regression,
and random crashes if booting n900 with device tree and
thumb mode. Also few other regressions and fixes.

* tag 'omap-for-v3.14/fixes-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap:
  ARM: OMAP3: Fix pinctrl interrupts for core2
  ARM: OMAP: Kill warning in CPUIDLE code with !CONFIG_SMP
  ARM: OMAP2+: Add support for thumb mode on DT booted N900
  ARM: OMAP2+: clock: fix clkoutx2 with CLK_SET_RATE_PARENT
  ARM: OMAP4: hwmod: Fix SOFTRESET logic for OMAP4
  ARM: DRA7: hwmod data: correct the sysc data for spinlock
  ARM: OMAP5: PRM: Fix reboot handling
Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parents a3db2bba 4b416368
...@@ -433,7 +433,9 @@ static const struct clk_ops dpll4_m5x2_ck_ops = { ...@@ -433,7 +433,9 @@ static const struct clk_ops dpll4_m5x2_ck_ops = {
.enable = &omap2_dflt_clk_enable, .enable = &omap2_dflt_clk_enable,
.disable = &omap2_dflt_clk_disable, .disable = &omap2_dflt_clk_disable,
.is_enabled = &omap2_dflt_clk_is_enabled, .is_enabled = &omap2_dflt_clk_is_enabled,
.set_rate = &omap3_clkoutx2_set_rate,
.recalc_rate = &omap3_clkoutx2_recalc, .recalc_rate = &omap3_clkoutx2_recalc,
.round_rate = &omap3_clkoutx2_round_rate,
}; };
static const struct clk_ops dpll4_m5x2_ck_3630_ops = { static const struct clk_ops dpll4_m5x2_ck_3630_ops = {
......
...@@ -23,6 +23,8 @@ ...@@ -23,6 +23,8 @@
#include "prm.h" #include "prm.h"
#include "clockdomain.h" #include "clockdomain.h"
#define MAX_CPUS 2
/* Machine specific information */ /* Machine specific information */
struct idle_statedata { struct idle_statedata {
u32 cpu_state; u32 cpu_state;
...@@ -48,11 +50,11 @@ static struct idle_statedata omap4_idle_data[] = { ...@@ -48,11 +50,11 @@ static struct idle_statedata omap4_idle_data[] = {
}, },
}; };
static struct powerdomain *mpu_pd, *cpu_pd[NR_CPUS]; static struct powerdomain *mpu_pd, *cpu_pd[MAX_CPUS];
static struct clockdomain *cpu_clkdm[NR_CPUS]; static struct clockdomain *cpu_clkdm[MAX_CPUS];
static atomic_t abort_barrier; static atomic_t abort_barrier;
static bool cpu_done[NR_CPUS]; static bool cpu_done[MAX_CPUS];
static struct idle_statedata *state_ptr = &omap4_idle_data[0]; static struct idle_statedata *state_ptr = &omap4_idle_data[0];
/* Private functions */ /* Private functions */
......
...@@ -623,6 +623,32 @@ void omap3_dpll_deny_idle(struct clk_hw_omap *clk) ...@@ -623,6 +623,32 @@ void omap3_dpll_deny_idle(struct clk_hw_omap *clk)
/* Clock control for DPLL outputs */ /* Clock control for DPLL outputs */
/* Find the parent DPLL for the given clkoutx2 clock */
static struct clk_hw_omap *omap3_find_clkoutx2_dpll(struct clk_hw *hw)
{
struct clk_hw_omap *pclk = NULL;
struct clk *parent;
/* Walk up the parents of clk, looking for a DPLL */
do {
do {
parent = __clk_get_parent(hw->clk);
hw = __clk_get_hw(parent);
} while (hw && (__clk_get_flags(hw->clk) & CLK_IS_BASIC));
if (!hw)
break;
pclk = to_clk_hw_omap(hw);
} while (pclk && !pclk->dpll_data);
/* clk does not have a DPLL as a parent? error in the clock data */
if (!pclk) {
WARN_ON(1);
return NULL;
}
return pclk;
}
/** /**
* omap3_clkoutx2_recalc - recalculate DPLL X2 output virtual clock rate * omap3_clkoutx2_recalc - recalculate DPLL X2 output virtual clock rate
* @clk: DPLL output struct clk * @clk: DPLL output struct clk
...@@ -637,27 +663,14 @@ unsigned long omap3_clkoutx2_recalc(struct clk_hw *hw, ...@@ -637,27 +663,14 @@ unsigned long omap3_clkoutx2_recalc(struct clk_hw *hw,
unsigned long rate; unsigned long rate;
u32 v; u32 v;
struct clk_hw_omap *pclk = NULL; struct clk_hw_omap *pclk = NULL;
struct clk *parent;
if (!parent_rate) if (!parent_rate)
return 0; return 0;
/* Walk up the parents of clk, looking for a DPLL */ pclk = omap3_find_clkoutx2_dpll(hw);
do {
do {
parent = __clk_get_parent(hw->clk);
hw = __clk_get_hw(parent);
} while (hw && (__clk_get_flags(hw->clk) & CLK_IS_BASIC));
if (!hw)
break;
pclk = to_clk_hw_omap(hw);
} while (pclk && !pclk->dpll_data);
/* clk does not have a DPLL as a parent? error in the clock data */ if (!pclk)
if (!pclk) {
WARN_ON(1);
return 0; return 0;
}
dd = pclk->dpll_data; dd = pclk->dpll_data;
...@@ -672,6 +685,55 @@ unsigned long omap3_clkoutx2_recalc(struct clk_hw *hw, ...@@ -672,6 +685,55 @@ unsigned long omap3_clkoutx2_recalc(struct clk_hw *hw,
return rate; return rate;
} }
int omap3_clkoutx2_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
return 0;
}
long omap3_clkoutx2_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *prate)
{
const struct dpll_data *dd;
u32 v;
struct clk_hw_omap *pclk = NULL;
if (!*prate)
return 0;
pclk = omap3_find_clkoutx2_dpll(hw);
if (!pclk)
return 0;
dd = pclk->dpll_data;
/* TYPE J does not have a clkoutx2 */
if (dd->flags & DPLL_J_TYPE) {
*prate = __clk_round_rate(__clk_get_parent(pclk->hw.clk), rate);
return *prate;
}
WARN_ON(!dd->enable_mask);
v = omap2_clk_readl(pclk, dd->control_reg) & dd->enable_mask;
v >>= __ffs(dd->enable_mask);
/* If in bypass, the rate is fixed to the bypass rate*/
if (v != OMAP3XXX_EN_DPLL_LOCKED)
return *prate;
if (__clk_get_flags(hw->clk) & CLK_SET_RATE_PARENT) {
unsigned long best_parent;
best_parent = (rate / 2);
*prate = __clk_round_rate(__clk_get_parent(hw->clk),
best_parent);
}
return *prate * 2;
}
/* OMAP3/4 non-CORE DPLL clkops */ /* OMAP3/4 non-CORE DPLL clkops */
const struct clk_hw_omap_ops clkhwops_omap3_dpll = { const struct clk_hw_omap_ops clkhwops_omap3_dpll = {
.allow_idle = omap3_dpll_allow_idle, .allow_idle = omap3_dpll_allow_idle,
......
...@@ -1946,30 +1946,32 @@ static int _ocp_softreset(struct omap_hwmod *oh) ...@@ -1946,30 +1946,32 @@ static int _ocp_softreset(struct omap_hwmod *oh)
if (ret) if (ret)
goto dis_opt_clks; goto dis_opt_clks;
_write_sysconfig(v, oh);
ret = _clear_softreset(oh, &v);
if (ret)
goto dis_opt_clks;
_write_sysconfig(v, oh); _write_sysconfig(v, oh);
if (oh->class->sysc->srst_udelay) if (oh->class->sysc->srst_udelay)
udelay(oh->class->sysc->srst_udelay); udelay(oh->class->sysc->srst_udelay);
c = _wait_softreset_complete(oh); c = _wait_softreset_complete(oh);
if (c == MAX_MODULE_SOFTRESET_WAIT) if (c == MAX_MODULE_SOFTRESET_WAIT) {
pr_warning("omap_hwmod: %s: softreset failed (waited %d usec)\n", pr_warning("omap_hwmod: %s: softreset failed (waited %d usec)\n",
oh->name, MAX_MODULE_SOFTRESET_WAIT); oh->name, MAX_MODULE_SOFTRESET_WAIT);
else ret = -ETIMEDOUT;
goto dis_opt_clks;
} else {
pr_debug("omap_hwmod: %s: softreset in %d usec\n", oh->name, c); pr_debug("omap_hwmod: %s: softreset in %d usec\n", oh->name, c);
}
ret = _clear_softreset(oh, &v);
if (ret)
goto dis_opt_clks;
_write_sysconfig(v, oh);
/* /*
* XXX add _HWMOD_STATE_WEDGED for modules that don't come back from * XXX add _HWMOD_STATE_WEDGED for modules that don't come back from
* _wait_target_ready() or _reset() * _wait_target_ready() or _reset()
*/ */
ret = (c == MAX_MODULE_SOFTRESET_WAIT) ? -ETIMEDOUT : 0;
dis_opt_clks: dis_opt_clks:
if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET) if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET)
_disable_optional_clocks(oh); _disable_optional_clocks(oh);
......
...@@ -1365,11 +1365,10 @@ static struct omap_hwmod_class_sysconfig dra7xx_spinlock_sysc = { ...@@ -1365,11 +1365,10 @@ static struct omap_hwmod_class_sysconfig dra7xx_spinlock_sysc = {
.rev_offs = 0x0000, .rev_offs = 0x0000,
.sysc_offs = 0x0010, .sysc_offs = 0x0010,
.syss_offs = 0x0014, .syss_offs = 0x0014,
.sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_ENAWAKEUP |
SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), SYSS_HAS_RESET_STATUS),
.idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
SIDLE_SMART_WKUP),
.sysc_fields = &omap_hwmod_sysc_type1, .sysc_fields = &omap_hwmod_sysc_type1,
}; };
......
...@@ -22,6 +22,8 @@ ...@@ -22,6 +22,8 @@
#include "common-board-devices.h" #include "common-board-devices.h"
#include "dss-common.h" #include "dss-common.h"
#include "control.h" #include "control.h"
#include "omap-secure.h"
#include "soc.h"
struct pdata_init { struct pdata_init {
const char *compatible; const char *compatible;
...@@ -169,6 +171,22 @@ static void __init am3517_evm_legacy_init(void) ...@@ -169,6 +171,22 @@ static void __init am3517_evm_legacy_init(void)
omap_ctrl_writel(v, AM35XX_CONTROL_IP_SW_RESET); omap_ctrl_writel(v, AM35XX_CONTROL_IP_SW_RESET);
omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET); /* OCP barrier */ omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET); /* OCP barrier */
} }
static void __init nokia_n900_legacy_init(void)
{
hsmmc2_internal_input_clk();
if (omap_type() == OMAP2_DEVICE_TYPE_SEC) {
if (IS_ENABLED(CONFIG_ARM_ERRATA_430973)) {
pr_info("RX-51: Enabling ARM errata 430973 workaround\n");
/* set IBE to 1 */
rx51_secure_update_aux_cr(BIT(6), 0);
} else {
pr_warning("RX-51: Not enabling ARM errata 430973 workaround\n");
pr_warning("Thumb binaries may crash randomly without this workaround\n");
}
}
}
#endif /* CONFIG_ARCH_OMAP3 */ #endif /* CONFIG_ARCH_OMAP3 */
#ifdef CONFIG_ARCH_OMAP4 #ifdef CONFIG_ARCH_OMAP4
...@@ -239,6 +257,7 @@ struct of_dev_auxdata omap_auxdata_lookup[] __initdata = { ...@@ -239,6 +257,7 @@ struct of_dev_auxdata omap_auxdata_lookup[] __initdata = {
#endif #endif
#ifdef CONFIG_ARCH_OMAP3 #ifdef CONFIG_ARCH_OMAP3
OF_DEV_AUXDATA("ti,omap3-padconf", 0x48002030, "48002030.pinmux", &pcs_pdata), OF_DEV_AUXDATA("ti,omap3-padconf", 0x48002030, "48002030.pinmux", &pcs_pdata),
OF_DEV_AUXDATA("ti,omap3-padconf", 0x480025a0, "480025a0.pinmux", &pcs_pdata),
OF_DEV_AUXDATA("ti,omap3-padconf", 0x48002a00, "48002a00.pinmux", &pcs_pdata), OF_DEV_AUXDATA("ti,omap3-padconf", 0x48002a00, "48002a00.pinmux", &pcs_pdata),
/* Only on am3517 */ /* Only on am3517 */
OF_DEV_AUXDATA("ti,davinci_mdio", 0x5c030000, "davinci_mdio.0", NULL), OF_DEV_AUXDATA("ti,davinci_mdio", 0x5c030000, "davinci_mdio.0", NULL),
...@@ -259,7 +278,7 @@ struct of_dev_auxdata omap_auxdata_lookup[] __initdata = { ...@@ -259,7 +278,7 @@ struct of_dev_auxdata omap_auxdata_lookup[] __initdata = {
static struct pdata_init pdata_quirks[] __initdata = { static struct pdata_init pdata_quirks[] __initdata = {
#ifdef CONFIG_ARCH_OMAP3 #ifdef CONFIG_ARCH_OMAP3
{ "compulab,omap3-sbc-t3730", omap3_sbc_t3730_legacy_init, }, { "compulab,omap3-sbc-t3730", omap3_sbc_t3730_legacy_init, },
{ "nokia,omap3-n900", hsmmc2_internal_input_clk, }, { "nokia,omap3-n900", nokia_n900_legacy_init, },
{ "nokia,omap3-n9", hsmmc2_internal_input_clk, }, { "nokia,omap3-n9", hsmmc2_internal_input_clk, },
{ "nokia,omap3-n950", hsmmc2_internal_input_clk, }, { "nokia,omap3-n950", hsmmc2_internal_input_clk, },
{ "isee,omap3-igep0020", omap3_igep0020_legacy_init, }, { "isee,omap3-igep0020", omap3_igep0020_legacy_init, },
......
...@@ -183,11 +183,11 @@ void omap4_prminst_global_warm_sw_reset(void) ...@@ -183,11 +183,11 @@ void omap4_prminst_global_warm_sw_reset(void)
OMAP4_PRM_RSTCTRL_OFFSET); OMAP4_PRM_RSTCTRL_OFFSET);
v |= OMAP4430_RST_GLOBAL_WARM_SW_MASK; v |= OMAP4430_RST_GLOBAL_WARM_SW_MASK;
omap4_prminst_write_inst_reg(v, OMAP4430_PRM_PARTITION, omap4_prminst_write_inst_reg(v, OMAP4430_PRM_PARTITION,
OMAP4430_PRM_DEVICE_INST, dev_inst,
OMAP4_PRM_RSTCTRL_OFFSET); OMAP4_PRM_RSTCTRL_OFFSET);
/* OCP barrier */ /* OCP barrier */
v = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, v = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
OMAP4430_PRM_DEVICE_INST, dev_inst,
OMAP4_PRM_RSTCTRL_OFFSET); OMAP4_PRM_RSTCTRL_OFFSET);
} }
...@@ -245,6 +245,10 @@ long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate, ...@@ -245,6 +245,10 @@ long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate,
void omap2_init_clk_clkdm(struct clk_hw *clk); void omap2_init_clk_clkdm(struct clk_hw *clk);
unsigned long omap3_clkoutx2_recalc(struct clk_hw *hw, unsigned long omap3_clkoutx2_recalc(struct clk_hw *hw,
unsigned long parent_rate); unsigned long parent_rate);
int omap3_clkoutx2_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate);
long omap3_clkoutx2_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *prate);
int omap2_clkops_enable_clkdm(struct clk_hw *hw); int omap2_clkops_enable_clkdm(struct clk_hw *hw);
void omap2_clkops_disable_clkdm(struct clk_hw *hw); void omap2_clkops_disable_clkdm(struct clk_hw *hw);
int omap2_clk_disable_autoidle_all(void); int omap2_clk_disable_autoidle_all(void);
......
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