summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mtd/nand/gpmi-nand/gpmi-lib.c34
-rw-r--r--drivers/mtd/nand/gpmi-nand/gpmi-nand.h9
2 files changed, 22 insertions, 21 deletions
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
index 75c2e618b28a..8e28df497635 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
@@ -989,6 +989,7 @@ return_results:
hw->address_setup_in_cycles = address_setup_in_cycles;
hw->use_half_periods = dll_use_half_periods;
hw->sample_delay_factor = sample_delay_factor;
+ hw->device_busy_timeout = 0x500; /* default busy timeout value. */
/* Return success. */
return 0;
@@ -1020,26 +1021,26 @@ void gpmi_begin(struct gpmi_nand_data *this)
}
}
- /* set ready/busy timeout */
- writel(0x500 << BP_GPMI_TIMING1_BUSY_TIMEOUT,
- gpmi_regs + HW_GPMI_TIMING1);
-
/* Get the timing information we need. */
nfc->clock_frequency_in_hz = clk_get_rate(r->clock);
clock_period_in_ns = 1000000000 / nfc->clock_frequency_in_hz;
gpmi_nfc_compute_hardware_timing(this, &hw);
- /* Set up all the simple timing parameters. */
+ /* [1] Set HW_GPMI_TIMING0 */
reg = BF_GPMI_TIMING0_ADDRESS_SETUP(hw.address_setup_in_cycles) |
BF_GPMI_TIMING0_DATA_HOLD(hw.data_hold_in_cycles) |
BF_GPMI_TIMING0_DATA_SETUP(hw.data_setup_in_cycles) ;
writel(reg, gpmi_regs + HW_GPMI_TIMING0);
- /*
- * DLL_ENABLE must be set to 0 when setting RDN_DELAY or HALF_PERIOD.
- */
+ /* [2] Set HW_GPMI_TIMING1 */
+ writel(BF_GPMI_TIMING1_DEVICE_BUSY_TIMEOUT(hw.device_busy_timeout),
+ gpmi_regs + HW_GPMI_TIMING1);
+
+ /* [3] The following code is to set the HW_GPMI_CTRL1. */
+
+ /* DLL_ENABLE must be set to 0 when setting RDN_DELAY or HALF_PERIOD. */
writel(BM_GPMI_CTRL1_DLL_ENABLE, gpmi_regs + HW_GPMI_CTRL1_CLR);
/* Clear out the DLL control fields. */
@@ -1050,30 +1051,21 @@ void gpmi_begin(struct gpmi_nand_data *this)
if (!hw.sample_delay_factor)
return;
- /* Configure the HALF_PERIOD flag. */
if (hw.use_half_periods)
writel(BM_GPMI_CTRL1_HALF_PERIOD,
- gpmi_regs + HW_GPMI_CTRL1_SET);
-
- /* Set the delay factor. */
+ gpmi_regs + HW_GPMI_CTRL1_SET);
writel(BF_GPMI_CTRL1_RDN_DELAY(hw.sample_delay_factor),
- gpmi_regs + HW_GPMI_CTRL1_SET);
-
- /* Enable the DLL. */
+ gpmi_regs + HW_GPMI_CTRL1_SET);
writel(BM_GPMI_CTRL1_DLL_ENABLE, gpmi_regs + HW_GPMI_CTRL1_SET);
/*
* After we enable the GPMI DLL, we have to wait 64 clock cycles before
- * we can use the GPMI.
- *
- * Calculate the amount of time we need to wait, in microseconds.
+ * we can use the GPMI. Calculate the amount of time we need to wait,
+ * in microseconds.
*/
dll_wait_time_in_us = (clock_period_in_ns * 64) / 1000;
-
if (!dll_wait_time_in_us)
dll_wait_time_in_us = 1;
-
- /* Wait for the DLL to settle. */
udelay(dll_wait_time_in_us);
err_out:
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
index 229b2c5e1b12..cf50a6055511 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
@@ -188,14 +188,23 @@ struct gpmi_nand_data {
* @data_setup_in_cycles: The data setup time, in cycles.
* @data_hold_in_cycles: The data hold time, in cycles.
* @address_setup_in_cycles: The address setup time, in cycles.
+ * @device_busy_timeout: The timeout waiting for NAND Ready/Busy,
+ * this value is the number of cycles multiplied
+ * by 4096.
* @use_half_periods: Indicates the clock is running slowly, so the
* NFC DLL should use half-periods.
* @sample_delay_factor: The sample delay factor.
*/
struct gpmi_nfc_hardware_timing {
+ /* for GPMI_HW_GPMI_TIMING0 */
uint8_t data_setup_in_cycles;
uint8_t data_hold_in_cycles;
uint8_t address_setup_in_cycles;
+
+ /* for GPMI_HW_GPMI_TIMING1 */
+ uint16_t device_busy_timeout;
+
+ /* for GPMI_HW_GPMI_CTRL1 */
bool use_half_periods;
uint8_t sample_delay_factor;
};