Message ID | 20180426154134.8270-8-sam.lefebvre@essensium.com |
---|---|
State | Rejected |
Delegated to: | Miquel Raynal |
Headers | show |
Series | [01/13] mtd: nand: gpmi: drop dma_ops_type | expand |
Hello Han, Could we have your input on this patch, please? On Thu, 26 Apr 2018 17:41:28 +0200, Sam Lefebvre <sam.lefebvre@essensium.com> wrote: > The GPMI block by default decouples the ready/busy signal (which is > shared between all chip-selects) to separate internal signals per > chip-select. However, since the gpmi-nand driver uses DMA0 for all > chip-selects, DMA transfers will not be able to see the ready/busy > status for any chip-select other than 0. > > Currently, this happens to work because nand_command() ends with an > explicit nand_wait_ready() and the driver only sets up a single command > in a DMA chain. nand_wait_ready() polls for the chip-select specific > ready/busy status bit. Future patches, however, will set up a DMA chain > with several commands, so these will have to wait correctly in the DMA > chain itself. > > To fix this, set the GANGED_RDYBUSY bit in the control1 register. This > ties all internal ready/busy signals together, so DMA0 will also see > the ready/busy status of chip selects 1-2-3. It's a bit silly that this > isn't implied in hardware by the DECOUPLE_CS bit. > > Signed-off-by: Sam Lefebvre <sam.lefebvre@essensium.com> > Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be> > Cc: Han Xu <han.xu@nxp.com> > --- > Tested on an i.MX6Q with two identical chips on CS0 and CS1. > --- > drivers/mtd/nand/raw/gpmi-nand/gpmi-lib.c | 3 +++ > drivers/mtd/nand/raw/gpmi-nand/gpmi-regs.h | 1 + > 2 files changed, 4 insertions(+) > > diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/raw/gpmi-nand/gpmi-lib.c > index 83697b8df871..1858afdb400d 100644 > --- a/drivers/mtd/nand/raw/gpmi-nand/gpmi-lib.c > +++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-lib.c > @@ -193,6 +193,9 @@ int gpmi_init(struct gpmi_nand_data *this) > */ > writel(BM_GPMI_CTRL1_DECOUPLE_CS, r->gpmi_regs + HW_GPMI_CTRL1_SET); > > + /* Aggregate ready busy signalling. */ > + writel(BM_GPMI_CTRL1_GANGED_RDYBUSY, r->gpmi_regs + HW_GPMI_CTRL1_SET); > + > gpmi_disable_clk(this); > return 0; > err_out: > diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-regs.h b/drivers/mtd/nand/raw/gpmi-nand/gpmi-regs.h > index d92bf32221ca..e341802c90ac 100644 > --- a/drivers/mtd/nand/raw/gpmi-nand/gpmi-regs.h > +++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-regs.h > @@ -120,6 +120,7 @@ > #define BV_GPMI_CTRL1_WRN_DLY_SEL_7_TO_12NS 0x2 > #define BV_GPMI_CTRL1_WRN_DLY_SEL_NO_DELAY 0x3 > > +#define BM_GPMI_CTRL1_GANGED_RDYBUSY (1 << 19) > #define BM_GPMI_CTRL1_BCH_MODE (1 << 18) > > #define BP_GPMI_CTRL1_DLL_ENABLE 17 Thanks, Miquèl
diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/raw/gpmi-nand/gpmi-lib.c index 83697b8df871..1858afdb400d 100644 --- a/drivers/mtd/nand/raw/gpmi-nand/gpmi-lib.c +++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-lib.c @@ -193,6 +193,9 @@ int gpmi_init(struct gpmi_nand_data *this) */ writel(BM_GPMI_CTRL1_DECOUPLE_CS, r->gpmi_regs + HW_GPMI_CTRL1_SET); + /* Aggregate ready busy signalling. */ + writel(BM_GPMI_CTRL1_GANGED_RDYBUSY, r->gpmi_regs + HW_GPMI_CTRL1_SET); + gpmi_disable_clk(this); return 0; err_out: diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-regs.h b/drivers/mtd/nand/raw/gpmi-nand/gpmi-regs.h index d92bf32221ca..e341802c90ac 100644 --- a/drivers/mtd/nand/raw/gpmi-nand/gpmi-regs.h +++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-regs.h @@ -120,6 +120,7 @@ #define BV_GPMI_CTRL1_WRN_DLY_SEL_7_TO_12NS 0x2 #define BV_GPMI_CTRL1_WRN_DLY_SEL_NO_DELAY 0x3 +#define BM_GPMI_CTRL1_GANGED_RDYBUSY (1 << 19) #define BM_GPMI_CTRL1_BCH_MODE (1 << 18) #define BP_GPMI_CTRL1_DLL_ENABLE 17