diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mtd/nand/gpmi-nand/gpmi-lib.c | 34 | ||||
-rw-r--r-- | drivers/mtd/nand/gpmi-nand/gpmi-nand.h | 9 |
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; }; |