diff options
author | Miquel Raynal <miquel.raynal@bootlin.com> | 2018-03-02 15:38:39 +0100 |
---|---|---|
committer | Boris Brezillon <boris.brezillon@bootlin.com> | 2018-03-20 12:00:00 +0100 |
commit | 76e1a0086a0c3276b384f77905345e0fcc886fdd (patch) | |
tree | 0a6539d85c1012c5e42a2fad14399bb184404a31 /drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.h | |
parent | bd0b64340c2d66c0fe1aa99b0b23159d7e0c21f2 (diff) | |
download | lwn-76e1a0086a0c3276b384f77905345e0fcc886fdd.tar.gz lwn-76e1a0086a0c3276b384f77905345e0fcc886fdd.zip |
mtd: rawnand: gpmi: support ->setup_data_interface()
Until now the GPMI driver had its own timings logic while the core
already handles that and request the NAND controller drivers to support
the ->setup_data_interface() hook. Implement that hook by reusing the
already existing function. No real glue is necessary between core timing
delays and GPMI registers because the driver already translates the
ONFI timing modes into register values.
Make use of the core's tREA, tRLOH and tRHOH values that allow computing
more precise timings for mode [0-3] and get significantly better values
(+20% with an i.MX6 Sabre Auto board). Otherwise use the existing logic.
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Tested-by: Han Xu <han.xu@nxp.com>
Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
Diffstat (limited to 'drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.h')
-rw-r--r-- | drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.h | 82 |
1 files changed, 46 insertions, 36 deletions
diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.h b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.h index 06c1f993912c..23f9030cf6d2 100644 --- a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.h +++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.h @@ -135,11 +135,47 @@ struct gpmi_devdata { const int clks_count; }; +/** + * struct gpmi_nfc_hardware_timing - GPMI hardware timing parameters. + * @timing_mode: The timing mode to comply with. + * @must_apply_timings: Whether controller timings have already been + * applied or not (useful only while there is + * support for only one chip select) + * @clk_rate: The clock rate that must be used to derive the + * following parameters. + * @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. + * @wrn_dly_sel: The delay on the GPMI write strobe. + */ +struct gpmi_nfc_hardware_timing { + unsigned int timing_mode; + bool must_apply_timings; + unsigned long int clk_rate; + + /* for HW_GPMI_TIMING0 */ + u8 data_setup_in_cycles; + u8 data_hold_in_cycles; + u8 address_setup_in_cycles; + + /* for HW_GPMI_TIMING1 */ + u16 device_busy_timeout; +#define GPMI_DEFAULT_BUSY_TIMEOUT 0x500 /* default busy timeout value.*/ + + /* for HW_GPMI_CTRL1 */ + bool use_half_periods; + u8 sample_delay_factor; + u8 wrn_dly_sel; +}; + struct gpmi_nand_data { - /* flags */ -#define GPMI_ASYNC_EDO_ENABLED (1 << 0) -#define GPMI_TIMING_INIT_OK (1 << 1) - int flags; + /* Devdata */ const struct gpmi_devdata *devdata; /* System Interface */ @@ -152,6 +188,7 @@ struct gpmi_nand_data { /* Flash Hardware */ struct nand_timing timing; int timing_mode; + struct gpmi_nfc_hardware_timing hw; /* BCH */ struct bch_geometry bch_geometry; @@ -205,35 +242,6 @@ struct gpmi_nand_data { }; /** - * struct gpmi_nfc_hardware_timing - GPMI hardware timing parameters. - * @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. - * @wrn_dly_sel: The delay on the GPMI write strobe. - */ -struct gpmi_nfc_hardware_timing { - /* for HW_GPMI_TIMING0 */ - uint8_t data_setup_in_cycles; - uint8_t data_hold_in_cycles; - uint8_t address_setup_in_cycles; - - /* for HW_GPMI_TIMING1 */ - uint16_t device_busy_timeout; -#define GPMI_DEFAULT_BUSY_TIMEOUT 0x500 /* default busy timeout value.*/ - - /* for HW_GPMI_CTRL1 */ - bool use_half_periods; - uint8_t sample_delay_factor; - uint8_t wrn_dly_sel; -}; - -/** * struct timing_threshold - Timing threshold * @max_data_setup_cycles: The maximum number of data setup cycles that * can be expressed in the hardware. @@ -279,14 +287,16 @@ int start_dma_with_bch_irq(struct gpmi_nand_data *, /* GPMI-NAND helper function library */ int gpmi_init(struct gpmi_nand_data *); -int gpmi_extra_init(struct gpmi_nand_data *); void gpmi_clear_bch(struct gpmi_nand_data *); void gpmi_dump_info(struct gpmi_nand_data *); int bch_set_geometry(struct gpmi_nand_data *); int gpmi_is_ready(struct gpmi_nand_data *, unsigned chip); int gpmi_send_command(struct gpmi_nand_data *); -void gpmi_begin(struct gpmi_nand_data *); -void gpmi_end(struct gpmi_nand_data *); +int gpmi_enable_clk(struct gpmi_nand_data *this); +int gpmi_disable_clk(struct gpmi_nand_data *this); +int gpmi_setup_data_interface(struct mtd_info *mtd, int chipnr, + const struct nand_data_interface *conf); +void gpmi_nfc_apply_timings(struct gpmi_nand_data *this); int gpmi_read_data(struct gpmi_nand_data *); int gpmi_send_data(struct gpmi_nand_data *); int gpmi_send_page(struct gpmi_nand_data *, |