Commit 49e013b8 authored by Tony Lindgren's avatar Tony Lindgren Committed by Kamal Mostafa

ARM: OMAP2+: Fix onenand rate detection to avoid filesystem corruption

commit e7b11dc7 upstream.

Commit 63aa945b ("memory: omap-gpmc: Add Kconfig option for debug")
unified the GPMC debug for the SoCs with GPMC. The commit also left out
the option for HWMOD_INIT_NO_RESET as we now require proper timings for
GPMC to be able to remap GPMC devices out of address 0.

Unfortunately on Nokia N900, onenand now only partially works with the
device tree provided timings. It works enough to get detected but the
clock rate supported by the onenand chip gets misdetected. This in turn
causes the GPMC timings to be miscalculated and this leads into file
system corruption on N900.

Looks like onenand needs CS_CONFIG1 bit 27 WRITETYPE set for for sync
write. This is needed also for async timings when we write to onenand
with omap2_onenand_set_async_mode(). Without sync write bit set, the
async read for the onenand ONENAND_REG_VERSION_ID will return 0xfff.

Let's exit with an error if onenand rate is not detected. And let's
remove the extra call to omap2_onenand_set_async_mode() as we only need
to do this once at the end of omap2_onenand_setup_async().

Fixes: 63aa945b ("memory: omap-gpmc: Add Kconfig option for debug")
Reported-by: default avatarIvaylo Dimitrov <ivo.g.dimitrov.75@gmail.com>
Tested-by: default avatarIvaylo Dimitrov <ivo.g.dimitrov.75@gmail.com>
Tested-by: default avatarAaro Koskinen <aaro.koskinen@iki.fi>
Signed-off-by: default avatarTony Lindgren <tony@atomide.com>
Signed-off-by: default avatarKamal Mostafa <kamal@canonical.com>
parent aec8da63
......@@ -149,8 +149,8 @@ static int omap2_onenand_get_freq(struct omap_onenand_platform_data *cfg,
freq = 104;
break;
default:
freq = 54;
break;
pr_err("onenand rate not detected, bad GPMC async timings?\n");
freq = 0;
}
return freq;
......@@ -271,6 +271,11 @@ static int omap2_onenand_setup_async(void __iomem *onenand_base)
struct gpmc_timings t;
int ret;
/*
* Note that we need to keep sync_write set for the call to
* omap2_onenand_set_async_mode() to work to detect the onenand
* supported clock rate for the sync timings.
*/
if (gpmc_onenand_data->of_node) {
gpmc_read_settings_dt(gpmc_onenand_data->of_node,
&onenand_async);
......@@ -281,12 +286,9 @@ static int omap2_onenand_setup_async(void __iomem *onenand_base)
else
gpmc_onenand_data->flags |= ONENAND_SYNC_READ;
onenand_async.sync_read = false;
onenand_async.sync_write = false;
}
}
omap2_onenand_set_async_mode(onenand_base);
omap2_onenand_calc_async_timings(&t);
ret = gpmc_cs_program_settings(gpmc_onenand_data->cs, &onenand_async);
......@@ -310,6 +312,8 @@ static int omap2_onenand_setup_sync(void __iomem *onenand_base, int *freq_ptr)
if (!freq) {
/* Very first call freq is not known */
freq = omap2_onenand_get_freq(gpmc_onenand_data, onenand_base);
if (!freq)
return -ENODEV;
set_onenand_cfg(onenand_base);
}
......
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