Re: [PATCH v10 3/4] mtd: rawnand: Add support for secure regions in NAND memory

2021-04-02 Thread Boris Brezillon
On Thu, 1 Apr 2021 21:46:22 +0530
Manivannan Sadhasivam  wrote:

> On Thu, Apr 01, 2021 at 05:54:21PM +0200, Boris Brezillon wrote:
> > On Thu,  1 Apr 2021 20:49:54 +0530
> > Manivannan Sadhasivam  wrote:
> >   
> > > @@ -565,6 +608,11 @@ static int nand_block_isreserved(struct mtd_info 
> > > *mtd, loff_t ofs)
> > >  
> > >   if (!chip->bbt)
> > >   return 0;
> > > +
> > > + /* Check if the region is secured */
> > > + if (nand_region_is_secured(chip, ofs, 0))
> > > + return -EIO;  
> > 
> > That would is still wrong, you should never pass a 0 size to
> > nand_region_is_secured().
> >   
> 
> Size doesn't matter here, that's why I passed 0. Maybe 1 would be
> appropriate?

You're checking if a block is reserved, so I think passing the
eraseblock size would make more sense, but I actually don't understand
why you need to check if the region is secure here (looks like
nand_block_isreserved() does not access the flash).



Re: [PATCH v8 3/3] mtd: rawnand: Add support for secure regions in NAND memory

2021-04-01 Thread Boris Brezillon
On Thu, 1 Apr 2021 15:48:12 +0530
Manivannan Sadhasivam  wrote:

>  static int nand_isbad_bbm(struct nand_chip *chip, loff_t ofs)
>  {
> +   struct mtd_info *mtd = nand_to_mtd(chip);
> +   int last_page = ((mtd->erasesize - mtd->writesize) >>
> +chip->page_shift) & chip->pagemask;
> int ret;
>  
> if (chip->options & NAND_NO_BBM_QUIRK)
> return 0;
>  
> /* Check if the region is secured */
> -   ret = nand_check_secure_region(chip, ofs, 0);
> +   ret = nand_check_secure_region(chip, ofs, last_page);

or just:

ret = nand_check_secure_region(chip, ofs, mtd->erasesize);


> if (ret)
> return ret;
> 
> > */
> > 


Re: [PATCH v10 3/4] mtd: rawnand: Add support for secure regions in NAND memory

2021-04-01 Thread Boris Brezillon
On Thu,  1 Apr 2021 20:49:54 +0530
Manivannan Sadhasivam  wrote:

> @@ -565,6 +608,11 @@ static int nand_block_isreserved(struct mtd_info *mtd, 
> loff_t ofs)
>  
>   if (!chip->bbt)
>   return 0;
> +
> + /* Check if the region is secured */
> + if (nand_region_is_secured(chip, ofs, 0))
> + return -EIO;

That would is still wrong, you should never pass a 0 size to
nand_region_is_secured().



Re: [PATCH v7 3/3] mtd: rawnand: Add support for secure regions in NAND memory

2021-03-19 Thread Boris Brezillon
On Fri, 19 Mar 2021 20:30:10 +0530
Manivannan Sadhasivam  wrote:

> @@ -2737,6 +2783,11 @@ static int nand_read_page_swecc(struct nand_chip 
> *chip, uint8_t *buf,
>   uint8_t *ecc_code = chip->ecc.code_buf;
>   unsigned int max_bitflips = 0;
>  
> + /* Check if the region is secured */
> + ret = nand_check_secure_region(chip, ((loff_t)page << 
> chip->page_shift), 0);
> + if (ret)
> + return ret;
> +

I'm lost. Why do you need to do that here if it's already done in
nand_do_read_{ops,oob}()?

>   chip->ecc.read_page_raw(chip, buf, 1, page);
>  
>   for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)


Re: [PATCH v7 3/3] mtd: rawnand: Add support for secure regions in NAND memory

2021-03-19 Thread Boris Brezillon
On Fri, 19 Mar 2021 20:30:10 +0530
Manivannan Sadhasivam  wrote:

> On a typical end product, a vendor may choose to secure some regions in
> the NAND memory which are supposed to stay intact between FW upgrades.
> The access to those regions will be blocked by a secure element like
> Trustzone. So the normal world software like Linux kernel should not
> touch these regions (including reading).
> 
> The regions are declared using a NAND chip DT property,
> "secure-regions". So let's make use of this property in the raw NAND
> core and skip access to the secure regions present in a system.
> 
> Signed-off-by: Manivannan Sadhasivam 
> ---
>  drivers/mtd/nand/raw/nand_base.c | 111 +++
>  include/linux/mtd/rawnand.h  |   4 ++
>  2 files changed, 115 insertions(+)
> 
> diff --git a/drivers/mtd/nand/raw/nand_base.c 
> b/drivers/mtd/nand/raw/nand_base.c
> index c33fa1b1847f..479a79e682cd 100644
> --- a/drivers/mtd/nand/raw/nand_base.c
> +++ b/drivers/mtd/nand/raw/nand_base.c
> @@ -278,11 +278,47 @@ static int nand_block_bad(struct nand_chip *chip, 
> loff_t ofs)
>   return 0;
>  }
>  
> +/**
> + * nand_check_secure_region() - Check if the region is secured
> + * @chip: NAND chip object
> + * @offset: Offset of the region to check
> + * @size: Size of the region to check
> + *
> + * Checks if the region is secured by comparing the offset and size with the
> + * list of secure regions obtained from DT. Returns -EIO if the region is
> + * secured else 0.
> + */
> +static int nand_check_secure_region(struct nand_chip *chip, loff_t offset, 
> u64 size)
> +{
> + int i, j;
> +
> + /* Skip touching the secure regions if present */
> + for (i = 0, j = 0; i < chip->nr_secure_regions; i++, j += 2) {
> + /* First compare the start offset */
> + if (offset >= chip->secure_regions[j] &&
> + (offset < chip->secure_regions[j] + chip->secure_regions[j 
> + 1]))
> + return -EIO;
> + /* ...then offset + size */
> + else if (offset < chip->secure_regions[i] &&
> +  (offset + size) >= chip->secure_regions[i])
> + return -EIO;

How about:

const struct nand_secure_region *region = 
>secure_regions[i];

if (offset + size <= region->offset ||
offset >= region->offset +  region->size)
continue;

return -EIO;

> + }
> +
> + return 0;
> +}
> +
>  static int nand_isbad_bbm(struct nand_chip *chip, loff_t ofs)
>  {
> + int ret;
> +
>   if (chip->options & NAND_NO_BBM_QUIRK)
>   return 0;
>  
> + /* Check if the region is secured */
> + ret = nand_check_secure_region(chip, ofs, 0);
> + if (ret)
> + return ret;
> +
>   if (chip->legacy.block_bad)
>   return chip->legacy.block_bad(chip, ofs);
>  
> @@ -397,6 +433,11 @@ static int nand_do_write_oob(struct nand_chip *chip, 
> loff_t to,
>   return -EINVAL;
>   }
>  
> + /* Check if the region is secured */
> + ret = nand_check_secure_region(chip, to, ops->ooblen);
> + if (ret)
> + return ret;
> +
>   chipnr = (int)(to >> chip->chip_shift);
>  
>   /*
> @@ -565,6 +606,11 @@ static int nand_block_isreserved(struct mtd_info *mtd, 
> loff_t ofs)
>  
>   if (!chip->bbt)
>   return 0;
> +
> + /* Check if the region is secured */
> + if (nand_check_secure_region(chip, ofs, 0))
> + return -EIO;
> +
>   /* Return info from the table */
>   return nand_isreserved_bbt(chip, ofs);
>  }
> @@ -2737,6 +2783,11 @@ static int nand_read_page_swecc(struct nand_chip 
> *chip, uint8_t *buf,
>   uint8_t *ecc_code = chip->ecc.code_buf;
>   unsigned int max_bitflips = 0;
>  
> + /* Check if the region is secured */
> + ret = nand_check_secure_region(chip, ((loff_t)page << 
> chip->page_shift), 0);
> + if (ret)
> + return ret;
> +
>   chip->ecc.read_page_raw(chip, buf, 1, page);
>  
>   for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
> @@ -3127,6 +3178,11 @@ static int nand_do_read_ops(struct nand_chip *chip, 
> loff_t from,
>   int retry_mode = 0;
>   bool ecc_fail = false;
>  
> + /* Check if the region is secured */
> + ret = nand_check_secure_region(chip, from, readlen);
> + if (ret)
> + return ret;
> +
>   chipnr = (int)(from >> chip->chip_shift);
>   nand_select_target(chip, chipnr);
>  
> @@ -3458,6 +3514,11 @@ static int nand_do_read_oob(struct nand_chip *chip, 
> loff_t from,
>   pr_debug("%s: from = 0x%08Lx, len = %i\n",
>   __func__, (unsigned long long)from, readlen);
>  
> + /* Check if the region is secured */
> + ret = nand_check_secure_region(chip, from, readlen);
> + if (ret)
> + return ret;
> +
>   stats = mtd->ecc_stats;
>  
>   len = 

Re: [PATCH v5 3/3] mtd: rawnand: Add support for secure regions in NAND memory

2021-03-17 Thread Boris Brezillon
On Wed, 17 Mar 2021 19:22:49 +0530
Manivannan Sadhasivam  wrote:

> On Wed, Mar 17, 2021 at 02:14:49PM +0100, Boris Brezillon wrote:
> > On Wed, 17 Mar 2021 17:55:13 +0530
> > Manivannan Sadhasivam  wrote:
> >   
> > > On a typical end product, a vendor may choose to secure some regions in
> > > the NAND memory which are supposed to stay intact between FW upgrades.
> > > The access to those regions will be blocked by a secure element like
> > > Trustzone. So the normal world software like Linux kernel should not
> > > touch these regions (including reading).
> > > 
> > > The regions are declared using a NAND chip DT property,
> > > "secure-regions". So let's make use of this property in the nand core
> > > and skip access to the secure regions present in a system.
> > > 
> > > Signed-off-by: Manivannan Sadhasivam 
> > > ---
> > >  drivers/mtd/nand/raw/nand_base.c | 105 +++
> > >  include/linux/mtd/rawnand.h  |   4 ++
> > >  2 files changed, 109 insertions(+)
> > > 
> > > diff --git a/drivers/mtd/nand/raw/nand_base.c 
> > > b/drivers/mtd/nand/raw/nand_base.c
> > > index c33fa1b1847f..c85cbd491f05 100644
> > > --- a/drivers/mtd/nand/raw/nand_base.c
> > > +++ b/drivers/mtd/nand/raw/nand_base.c
> > > @@ -278,11 +278,41 @@ static int nand_block_bad(struct nand_chip *chip, 
> > > loff_t ofs)
> > >   return 0;
> > >  }
> > >  
> > > +/**
> > > + * nand_check_sec_region() - Check if the region is secured
> > > + * @chip: NAND chip object
> > > + * @offset: Offset of the region to check
> > > + *
> > > + * Checks if the region is secured by comparing the offset with the list 
> > > of
> > > + * secure regions obtained from DT. Returns -EIO if the region is secured
> > > + * else 0.
> > > + */
> > > +static int nand_check_sec_region(struct nand_chip *chip, loff_t offset)  
> > 
> > You're only passing an offset, looks like the size is missing, which
> > will be problematic for nand_do_{read,write}_ops() which might
> > read/write more than one page.
> >   
> 
> Hmm, so the intention is to skip reading the secure pages instead of bailing
> out inside while loop in nand_do_{read,write}_ops()?

No, the goal is to return -EIO before even trying to read/write those
pages if the range being read/written is covering a secure section. The
idea is to do this check outside the while() loop, so you only do it
once for the read/write request instead of once per page.

> I think that will violate
> the ABI since we skipped few pages but the application intended to read all.
> 
> Thanks,
> Mani
> 
> > > +{
> > > + int i, j;
> > > +
> > > + /* Skip touching the secure regions if present */
> > > + for (i = 0, j = 0; i < chip->nr_sec_regions; i++, j += 2) {
> > > + if (offset >= chip->sec_regions[j] &&
> > > + (offset <= chip->sec_regions[j] + chip->sec_regions[j + 1]))
> > > + return -EIO;
> > > + }
> > > +
> > > + return 0;
> > > +}
> > > +
> > >  static int nand_isbad_bbm(struct nand_chip *chip, loff_t ofs)
> > >  {
> > > + int ret;
> > > +
> > >   if (chip->options & NAND_NO_BBM_QUIRK)
> > >   return 0;
> > >  
> > > + /* Check if the region is secured */
> > > + ret = nand_check_sec_region(chip, ofs);
> > > + if (ret)
> > > + return ret;
> > > +
> > >   if (chip->legacy.block_bad)
> > >   return chip->legacy.block_bad(chip, ofs);
> > >  
> > > @@ -397,6 +427,11 @@ static int nand_do_write_oob(struct nand_chip *chip, 
> > > loff_t to,
> > >   return -EINVAL;
> > >   }
> > >  
> > > + /* Check if the region is secured */
> > > + ret = nand_check_sec_region(chip, to);
> > > + if (ret)
> > > + return ret;
> > > +
> > >   chipnr = (int)(to >> chip->chip_shift);
> > >  
> > >   /*
> > > @@ -565,6 +600,11 @@ static int nand_block_isreserved(struct mtd_info 
> > > *mtd, loff_t ofs)
> > >  
> > >   if (!chip->bbt)
> > >   return 0;
> > > +
> > > + /* Check if the region is secured */
> > > + if (nand_check_sec_region(chip, ofs))
> > > + return -EIO;
> > > +
> > >   /* Return info fro

Re: [PATCH v5 3/3] mtd: rawnand: Add support for secure regions in NAND memory

2021-03-17 Thread Boris Brezillon
On Wed, 17 Mar 2021 17:55:13 +0530
Manivannan Sadhasivam  wrote:

> On a typical end product, a vendor may choose to secure some regions in
> the NAND memory which are supposed to stay intact between FW upgrades.
> The access to those regions will be blocked by a secure element like
> Trustzone. So the normal world software like Linux kernel should not
> touch these regions (including reading).
> 
> The regions are declared using a NAND chip DT property,
> "secure-regions". So let's make use of this property in the nand core
> and skip access to the secure regions present in a system.
> 
> Signed-off-by: Manivannan Sadhasivam 
> ---
>  drivers/mtd/nand/raw/nand_base.c | 105 +++
>  include/linux/mtd/rawnand.h  |   4 ++
>  2 files changed, 109 insertions(+)
> 
> diff --git a/drivers/mtd/nand/raw/nand_base.c 
> b/drivers/mtd/nand/raw/nand_base.c
> index c33fa1b1847f..c85cbd491f05 100644
> --- a/drivers/mtd/nand/raw/nand_base.c
> +++ b/drivers/mtd/nand/raw/nand_base.c
> @@ -278,11 +278,41 @@ static int nand_block_bad(struct nand_chip *chip, 
> loff_t ofs)
>   return 0;
>  }
>  
> +/**
> + * nand_check_sec_region() - Check if the region is secured
> + * @chip: NAND chip object
> + * @offset: Offset of the region to check
> + *
> + * Checks if the region is secured by comparing the offset with the list of
> + * secure regions obtained from DT. Returns -EIO if the region is secured
> + * else 0.
> + */
> +static int nand_check_sec_region(struct nand_chip *chip, loff_t offset)

You're only passing an offset, looks like the size is missing, which
will be problematic for nand_do_{read,write}_ops() which might
read/write more than one page.

> +{
> + int i, j;
> +
> + /* Skip touching the secure regions if present */
> + for (i = 0, j = 0; i < chip->nr_sec_regions; i++, j += 2) {
> + if (offset >= chip->sec_regions[j] &&
> + (offset <= chip->sec_regions[j] + chip->sec_regions[j + 1]))
> + return -EIO;
> + }
> +
> + return 0;
> +}
> +
>  static int nand_isbad_bbm(struct nand_chip *chip, loff_t ofs)
>  {
> + int ret;
> +
>   if (chip->options & NAND_NO_BBM_QUIRK)
>   return 0;
>  
> + /* Check if the region is secured */
> + ret = nand_check_sec_region(chip, ofs);
> + if (ret)
> + return ret;
> +
>   if (chip->legacy.block_bad)
>   return chip->legacy.block_bad(chip, ofs);
>  
> @@ -397,6 +427,11 @@ static int nand_do_write_oob(struct nand_chip *chip, 
> loff_t to,
>   return -EINVAL;
>   }
>  
> + /* Check if the region is secured */
> + ret = nand_check_sec_region(chip, to);
> + if (ret)
> + return ret;
> +
>   chipnr = (int)(to >> chip->chip_shift);
>  
>   /*
> @@ -565,6 +600,11 @@ static int nand_block_isreserved(struct mtd_info *mtd, 
> loff_t ofs)
>  
>   if (!chip->bbt)
>   return 0;
> +
> + /* Check if the region is secured */
> + if (nand_check_sec_region(chip, ofs))
> + return -EIO;
> +
>   /* Return info from the table */
>   return nand_isreserved_bbt(chip, ofs);
>  }
> @@ -2737,6 +2777,11 @@ static int nand_read_page_swecc(struct nand_chip 
> *chip, uint8_t *buf,
>   uint8_t *ecc_code = chip->ecc.code_buf;
>   unsigned int max_bitflips = 0;
>  
> + /* Check if the region is secured */
> + ret = nand_check_sec_region(chip, ((loff_t)page << chip->page_shift));
> + if (ret)
> + return ret;
> +
>   chip->ecc.read_page_raw(chip, buf, 1, page);
>  
>   for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
> @@ -3127,6 +3172,11 @@ static int nand_do_read_ops(struct nand_chip *chip, 
> loff_t from,
>   int retry_mode = 0;
>   bool ecc_fail = false;
>  
> + /* Check if the region is secured */
> + ret = nand_check_sec_region(chip, from);
> + if (ret)
> + return ret;
> +
>   chipnr = (int)(from >> chip->chip_shift);
>   nand_select_target(chip, chipnr);
>  
> @@ -3458,6 +3508,11 @@ static int nand_do_read_oob(struct nand_chip *chip, 
> loff_t from,
>   pr_debug("%s: from = 0x%08Lx, len = %i\n",
>   __func__, (unsigned long long)from, readlen);
>  
> + /* Check if the region is secured */
> + ret = nand_check_sec_region(chip, from);
> + if (ret)
> + return ret;
> +
>   stats = mtd->ecc_stats;
>  
>   len = mtd_oobavail(mtd, ops);
> @@ -3709,6 +3764,11 @@ static int nand_write_page_swecc(struct nand_chip 
> *chip, const uint8_t *buf,
>   uint8_t *ecc_calc = chip->ecc.calc_buf;
>   const uint8_t *p = buf;
>  
> + /* Check if the region is secured */
> + ret = nand_check_sec_region(chip, ((loff_t)page << chip->page_shift));
> + if (ret)
> + return ret;
> +
>   /* Software ECC calculation */
>   for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
>   

Re: [PATCH v4 2/3] dt-bindings: mtd: Add a property to declare secure regions in NAND chips

2021-03-08 Thread Boris Brezillon
On Mon, 8 Mar 2021 19:01:34 +0530
Manivannan Sadhasivam  wrote:

> On Mon, Mar 08, 2021 at 10:10:59AM +0100, Boris Brezillon wrote:
> > On Mon,  8 Mar 2021 11:14:46 +0530
> > Manivannan Sadhasivam  wrote:
> >   
> > > On a typical end product, a vendor may choose to secure some regions in
> > > the NAND memory which are supposed to stay intact between FW upgrades.
> > > The access to those regions will be blocked by a secure element like
> > > Trustzone. So the normal world software like Linux kernel should not
> > > touch these regions (including reading).
> > > 
> > > So let's add a property for declaring such secure regions so that the
> > > drivers can skip touching them.
> > > 
> > > Signed-off-by: Manivannan Sadhasivam 
> > > ---
> > >  Documentation/devicetree/bindings/mtd/nand-controller.yaml | 7 +++
> > >  1 file changed, 7 insertions(+)
> > > 
> > > diff --git a/Documentation/devicetree/bindings/mtd/nand-controller.yaml 
> > > b/Documentation/devicetree/bindings/mtd/nand-controller.yaml
> > > index d0e422f4b3e0..15a674bedca3 100644
> > > --- a/Documentation/devicetree/bindings/mtd/nand-controller.yaml
> > > +++ b/Documentation/devicetree/bindings/mtd/nand-controller.yaml
> > > @@ -143,6 +143,13 @@ patternProperties:
> > >Ready/Busy pins. Active state refers to the NAND ready state 
> > > and
> > >should be set to GPIOD_ACTIVE_HIGH unless the signal is 
> > > inverted.
> > >  
> > > +  secure-regions:
> > > +$ref: /schemas/types.yaml#/definitions/uint32-matrix
> > > +description:
> > > +  Regions in the NAND chip which are protected using a secure 
> > > element
> > > +  like Trustzone. This property contains the start address and 
> > > size of
> > > +  the secure regions present.
> > > +  
> > 
> > Since you declare this as a generic property, I think it'd be simpler
> > to do the check at the core level.
> >   
> 
> Hmm, so have the parsing logic in qcom driver and check in core or both 
> parsing
> and check in core?

Both in the core.


Re: [PATCH v4 2/3] dt-bindings: mtd: Add a property to declare secure regions in NAND chips

2021-03-08 Thread Boris Brezillon
On Mon,  8 Mar 2021 11:14:46 +0530
Manivannan Sadhasivam  wrote:

> On a typical end product, a vendor may choose to secure some regions in
> the NAND memory which are supposed to stay intact between FW upgrades.
> The access to those regions will be blocked by a secure element like
> Trustzone. So the normal world software like Linux kernel should not
> touch these regions (including reading).
> 
> So let's add a property for declaring such secure regions so that the
> drivers can skip touching them.
> 
> Signed-off-by: Manivannan Sadhasivam 
> ---
>  Documentation/devicetree/bindings/mtd/nand-controller.yaml | 7 +++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/mtd/nand-controller.yaml 
> b/Documentation/devicetree/bindings/mtd/nand-controller.yaml
> index d0e422f4b3e0..15a674bedca3 100644
> --- a/Documentation/devicetree/bindings/mtd/nand-controller.yaml
> +++ b/Documentation/devicetree/bindings/mtd/nand-controller.yaml
> @@ -143,6 +143,13 @@ patternProperties:
>Ready/Busy pins. Active state refers to the NAND ready state and
>should be set to GPIOD_ACTIVE_HIGH unless the signal is inverted.
>  
> +  secure-regions:
> +$ref: /schemas/types.yaml#/definitions/uint32-matrix
> +description:
> +  Regions in the NAND chip which are protected using a secure element
> +  like Trustzone. This property contains the start address and size 
> of
> +  the secure regions present.
> +

Since you declare this as a generic property, I think it'd be simpler
to do the check at the core level.

>  required:
>- reg
>  



Re: [PATCH v4 3/3] mtd: rawnand: qcom: Add support for secure regions in NAND memory

2021-03-08 Thread Boris Brezillon
On Mon,  8 Mar 2021 11:14:47 +0530
Manivannan Sadhasivam  wrote:

> On a typical end product, a vendor may choose to secure some regions in
> the NAND memory which are supposed to stay intact between FW upgrades.
> The access to those regions will be blocked by a secure element like
> Trustzone. So the normal world software like Linux kernel should not
> touch these regions (including reading).
> 
> The regions are declared using a NAND chip DT property,
> "secure-regions". So let's make use of this property and skip
> access to the secure regions present in a system.
> 
> Signed-off-by: Manivannan Sadhasivam 
> ---
>  drivers/mtd/nand/raw/qcom_nandc.c | 72 +++
>  1 file changed, 63 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/mtd/nand/raw/qcom_nandc.c 
> b/drivers/mtd/nand/raw/qcom_nandc.c
> index 87c23bb320bf..8027f7cb32be 100644
> --- a/drivers/mtd/nand/raw/qcom_nandc.c
> +++ b/drivers/mtd/nand/raw/qcom_nandc.c
> @@ -431,6 +431,11 @@ struct qcom_nand_controller {
>   * @cfg0, cfg1, cfg0_raw..:  NANDc register configurations needed for
>   *   ecc/non-ecc mode for the current nand flash
>   *   device
> + *
> + * @sec_regions: Array representing the secure regions in the
> + *   NAND chip
> + *
> + * @nr_sec_regions:  Number of secure regions in the NAND chip
>   */
>  struct qcom_nand_host {
>   struct nand_chip chip;
> @@ -453,6 +458,9 @@ struct qcom_nand_host {
>   u32 ecc_bch_cfg;
>   u32 clrflashstatus;
>   u32 clrreadstatus;
> +
> + u32 *sec_regions;
> + u8 nr_sec_regions;
>  };
>  
>  /*
> @@ -662,16 +670,27 @@ static void nandc_set_reg(struct qcom_nand_controller 
> *nandc, int offset,
>  }
>  
>  /* helper to configure address register values */
> -static void set_address(struct qcom_nand_host *host, u16 column, int page)
> +static int set_address(struct qcom_nand_host *host, u16 column, int page)
>  {
>   struct nand_chip *chip = >chip;
>   struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip);
> + u32 offs = page << chip->page_shift;
> + int i, j;
> +
> + /* Skip touching the secure regions if present */
> + for (i = 0, j = 0; i < host->nr_sec_regions; i++, j += 2) {
> + if (offs >= host->sec_regions[j] &&
> + (offs <= host->sec_regions[j] + host->sec_regions[j + 1]))
> + return -EIO;
> + }

Hm, not sure that's a good idea to make this check part of
set_address(). Looks like set_address() can be used for ONFI page
access too, and you definitely don't want to block those
requests. I'd recommend having a separate helper that you can call from
qcom_nandc_{read,write}_{oob,page,page_raw}().

>  
>   if (chip->options & NAND_BUSWIDTH_16)
>   column >>= 1;
>  
>   nandc_set_reg(nandc, NAND_ADDR0, page << 16 | column);
>   nandc_set_reg(nandc, NAND_ADDR1, page >> 16 & 0xff);
> +
> + return 0;
>  }
>  
>  /*
> @@ -1491,13 +1510,13 @@ static void qcom_nandc_command(struct nand_chip 
> *chip, unsigned int command,
>   WARN_ON(column != 0);
>  
>   host->use_ecc = true;
> - set_address(host, 0, page_addr);
> + ret = set_address(host, 0, page_addr);
>   update_rw_regs(host, ecc->steps, true);
>   break;
>  
>   case NAND_CMD_SEQIN:
>   WARN_ON(column != 0);
> - set_address(host, 0, page_addr);
> + ret = set_address(host, 0, page_addr);
>   break;
>  
>   case NAND_CMD_PAGEPROG:
> @@ -1615,7 +1634,10 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, struct 
> nand_chip *chip,
>   host->use_ecc = false;
>  
>   clear_bam_transaction(nandc);
> - set_address(host, host->cw_size * cw, page);
> + ret = set_address(host, host->cw_size * cw, page);
> + if (ret)
> + return ret;
> +
>   update_rw_regs(host, 1, true);
>   config_nand_page_read(nandc);
>  
> @@ -1943,7 +1965,10 @@ static int copy_last_cw(struct qcom_nand_host *host, 
> int page)
>   /* prepare a clean read buffer */
>   memset(nandc->data_buffer, 0xff, size);
>  
> - set_address(host, host->cw_size * (ecc->steps - 1), page);
> + ret = set_address(host, host->cw_size * (ecc->steps - 1), page);
> + if (ret)
> + return ret;
> +
>   update_rw_regs(host, 1, true);
>  
>   config_nand_single_cw_page_read(nandc, host->use_ecc);
> @@ -2005,12 +2030,16 @@ static int qcom_nandc_read_oob(struct nand_chip 
> *chip, int page)
>   struct qcom_nand_host *host = to_qcom_nand_host(chip);
>   struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip);
>   struct nand_ecc_ctrl *ecc = >ecc;
> + int ret;
>  
>   clear_read_regs(nandc);
>   clear_bam_transaction(nandc);
>  
>   host->use_ecc = true;
> - set_address(host, 0, page);
> + ret = 

Re: [PATCH] mtd: rawnand: Do not check for bad block if bbt is unavailable

2021-02-04 Thread Boris Brezillon
On Thu, 4 Feb 2021 10:04:08 +0100
Miquel Raynal  wrote:

> Hi Boris,
> 
> Boris Brezillon  wrote on Thu, 4 Feb
> 2021 09:59:45 +0100:
> 
> > On Thu, 4 Feb 2021 14:22:21 +0530
> > Manivannan Sadhasivam  wrote:
> >   
> > > On Thu, Feb 04, 2021 at 09:13:36AM +0100, Miquel Raynal wrote:
> > > > Hi Manivannan,
> > > > 
> > > > Manivannan Sadhasivam  wrote on Wed,
> > > > 03 Feb 2021 17:11:31 +0530:
> > > >   
> > > > > On 3 February 2021 4:54:22 PM IST, Boris Brezillon 
> > > > >  wrote:  
> > > > > >On Wed, 03 Feb 2021 16:22:42 +0530
> > > > > >Manivannan Sadhasivam  wrote:
> > > > > >
> > > > > >> On 3 February 2021 3:49:14 PM IST, Boris Brezillon
> > > > > > wrote:
> > > > > >> >On Wed, 03 Feb 2021 15:42:02 +0530
> > > > > >> >Manivannan Sadhasivam  wrote:
> > > > > >> >  
> > > > > >> >> >> 
> > > > > >> >> >> I got more information from the vendor, Telit. The access to 
> > > > > >> >> >>
> > > > > >the  
> > > > > >> >3rd
> > > > > >> >> >partition is protected by Trustzone and any access in non  
> > > > > >> >> >  
> > > > > >privileged
> > > > > >> >> >mode (where Linux kernel runs) causes kernel panic and the 
> > > > > >> >> >device
> > > > > >> >> >reboots.   
> > > > > >> >
> > > > > >> >Out of curiosity, is it a per-CS-line thing or is this section
> > > > > >> >protected on all CS?
> > > > > >> >  
> > > > > >> 
> > > > > >> Sorry, I didn't get your question. 
> > > > > >
> > > > > >The qcom controller can handle several chips, each connected through 
> > > > > >a
> > > > > >different CS (chip-select) line, right? I'm wondering if the firmware
> > > > > >running in secure mode has the ability to block access for a specific
> > > > > >CS line or if all CS lines have the same constraint. That will impact
> > > > > >the way you describe it in your DT (in one case the secure-region
> > > > > >property should be under the controller node, in the other case it
> > > > > >should be under the NAND chip node).
> > > > > 
> > > > > Right. I believe the implementation is common to all NAND chips so 
> > > > > the property should be in the controller node.   
> > > > 
> > > > Looks weird: do you mean that each of the chips will have a secure 
> > > > area?  
> > > 
> > > I way I said is, the "secure-region" property will be present in the 
> > > controller
> > > node and not in the NAND chip node since this is not related to the device
> > > functionality.
> > > 
> > > But for referencing the NAND device, the property can have the phandle as 
> > > below:
> > > 
> > > secure-region = < 0x>;
> > 
> > My question was really what happens from a functional PoV. If you have
> > per-chip protection at the FW level, this property should be under the
> > NAND node. OTH, if the FW doesn't look at the selected chip before
> > blocking the access, it should be at the controller level. So, you
> > really have to understand what the secure FW does.  
> 
> I'm not so sure actually, that's why I like the phandle to nand0 -> in
> any case it's not a property of the NAND chip itself, it's kind of a
> host constraint, so I don't get why the property should be at the
> NAND node level?

I would argue that we already have plenty of NAND properties that
encode things controlled by the host (ECC, partitions, HW randomizer,
boot device, and all kind of controller specific stuff) :P. Having
the props under the NAND node makes it clear what those things are
applied to, and it's also easier to parse for the driver (you already
have to parse each node to get the reg property anyway).

> 
> Also, we should probably support several secure regions (which could be
> a way to express the fact that the FW does not look at the CS)?

Sure, the secure-region should probably be renamed secure-regions, even
if it's defined at the NAND chip level.


Re: [PATCH] mtd: rawnand: Do not check for bad block if bbt is unavailable

2021-02-04 Thread Boris Brezillon
On Thu, 4 Feb 2021 14:22:21 +0530
Manivannan Sadhasivam  wrote:

> On Thu, Feb 04, 2021 at 09:13:36AM +0100, Miquel Raynal wrote:
> > Hi Manivannan,
> > 
> > Manivannan Sadhasivam  wrote on Wed,
> > 03 Feb 2021 17:11:31 +0530:
> >   
> > > On 3 February 2021 4:54:22 PM IST, Boris Brezillon 
> > >  wrote:  
> > > >On Wed, 03 Feb 2021 16:22:42 +0530
> > > >Manivannan Sadhasivam  wrote:
> > > >
> > > >> On 3 February 2021 3:49:14 PM IST, Boris Brezillon
> > > > wrote:
> > > >> >On Wed, 03 Feb 2021 15:42:02 +0530
> > > >> >Manivannan Sadhasivam  wrote:
> > > >> >  
> > > >> >> >> 
> > > >> >> >> I got more information from the vendor, Telit. The access to
> > > >the  
> > > >> >3rd
> > > >> >> >partition is protected by Trustzone and any access in non
> > > >privileged
> > > >> >> >mode (where Linux kernel runs) causes kernel panic and the device
> > > >> >> >reboots.   
> > > >> >
> > > >> >Out of curiosity, is it a per-CS-line thing or is this section
> > > >> >protected on all CS?
> > > >> >  
> > > >> 
> > > >> Sorry, I didn't get your question. 
> > > >
> > > >The qcom controller can handle several chips, each connected through a
> > > >different CS (chip-select) line, right? I'm wondering if the firmware
> > > >running in secure mode has the ability to block access for a specific
> > > >CS line or if all CS lines have the same constraint. That will impact
> > > >the way you describe it in your DT (in one case the secure-region
> > > >property should be under the controller node, in the other case it
> > > >should be under the NAND chip node).
> > > 
> > > Right. I believe the implementation is common to all NAND chips so the 
> > > property should be in the controller node.   
> > 
> > Looks weird: do you mean that each of the chips will have a secure area?  
> 
> I way I said is, the "secure-region" property will be present in the 
> controller
> node and not in the NAND chip node since this is not related to the device
> functionality.
> 
> But for referencing the NAND device, the property can have the phandle as 
> below:
> 
> secure-region = < 0x>;

My question was really what happens from a functional PoV. If you have
per-chip protection at the FW level, this property should be under the
NAND node. OTH, if the FW doesn't look at the selected chip before
blocking the access, it should be at the controller level. So, you
really have to understand what the secure FW does.


Re: [PATCH] mtd: rawnand: Do not check for bad block if bbt is unavailable

2021-02-03 Thread Boris Brezillon
On Wed, 03 Feb 2021 16:22:42 +0530
Manivannan Sadhasivam  wrote:

> On 3 February 2021 3:49:14 PM IST, Boris Brezillon 
>  wrote:
> >On Wed, 03 Feb 2021 15:42:02 +0530
> >Manivannan Sadhasivam  wrote:
> >  
> >> >> 
> >> >> I got more information from the vendor, Telit. The access to the  
> >3rd
> >> >partition is protected by Trustzone and any access in non privileged
> >> >mode (where Linux kernel runs) causes kernel panic and the device
> >> >reboots.   
> >
> >Out of curiosity, is it a per-CS-line thing or is this section
> >protected on all CS?
> >  
> 
> Sorry, I didn't get your question. 

The qcom controller can handle several chips, each connected through a
different CS (chip-select) line, right? I'm wondering if the firmware
running in secure mode has the ability to block access for a specific
CS line or if all CS lines have the same constraint. That will impact
the way you describe it in your DT (in one case the secure-region
property should be under the controller node, in the other case it
should be under the NAND chip node).


Re: [PATCH] mtd: rawnand: Do not check for bad block if bbt is unavailable

2021-02-03 Thread Boris Brezillon
On Wed, 03 Feb 2021 15:42:02 +0530
Manivannan Sadhasivam  wrote:

> >> 
> >> I got more information from the vendor, Telit. The access to the 3rd  
> >partition is protected by Trustzone and any access in non privileged
> >mode (where Linux kernel runs) causes kernel panic and the device
> >reboots. 

Out of curiosity, is it a per-CS-line thing or is this section
protected on all CS?

> >
> >Ok, so this is not a chip feature but more a host constraint.
> >
> >In this case it would be a good idea to add a host DT property which
> >describes the zone to avoid accessing it. Something like:
> >
> > secure-area/secure-section = ;
> >
> >From the core perspective, we should parse this property early enough
> >and return -EIO when trying to access this area.

FWIW, I'm not sure making it part of the core is a good idea, at least
not until we have a different platform with a same needs. The
controller driver can parse it and return -EACCESS (or -EIO) when this
section is accessed.


Re: [PATCH] media: rkvdec: silence ktest bot build warning

2021-01-07 Thread Boris Brezillon
On Thu, 7 Jan 2021 10:13:43 +0100
Hans Verkuil  wrote:

> On 08/12/2020 16:55, Adrian Ratiu wrote:
> > Some configurations built by the ktest bot produce the following
> > warn, so mark the struct as __maybe_unused to avoid unnecessary
> > ML spam.
> >   
> >>> drivers/staging/media/rkvdec/rkvdec.c:967:34: warning: unused variable 
> >>> 'of_rkvdec_match' [-Wunused-const-variable]  
> >static const struct of_device_id of_rkvdec_match[] = {
> > ^
> >1 warning generated.  
> 
> I suspect that this is because there is no 'depends on OF' in the Kconfig.
> 
> '__maybe_unused' isn't used for this anywhere else, so this does not seem 
> like the
> right approach.

It's not uncommon to do that, especially when you want the driver to be
compile-tested (`git grep -C2 __maybe_unused|grep of_device_id` even
reports 2 drivers in the media tree :P). A `depends on OF` or an
`#ifdef CONFIG_OF` section surrounding the of_rkvdec_match declaration
would also do the trick.

> 
> Regards,
> 
>   Hans
> 
> > 
> > vim +/of_rkvdec_match +967 drivers/staging/media/rkvdec/rkvdec.c
> > 
> >966  
> >  > 967  static const struct of_device_id of_rkvdec_match[] = {  
> >968  { .compatible = "rockchip,rk3399-vdec" },
> >969  { /* sentinel */ }
> >970  };
> >971  MODULE_DEVICE_TABLE(of, of_rkvdec_match);
> >972
> > 
> > Cc: Boris Brezillon 
> > Cc: Ezequiel Garcia 
> > Cc: Mauro Carvalho Chehab 
> > Reported-by: kernel test robot 
> > Signed-off-by: Adrian Ratiu 
> > ---
> >  drivers/staging/media/rkvdec/rkvdec.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/drivers/staging/media/rkvdec/rkvdec.c 
> > b/drivers/staging/media/rkvdec/rkvdec.c
> > index aa4f8c287618..3af0f02ec59b 100644
> > --- a/drivers/staging/media/rkvdec/rkvdec.c
> > +++ b/drivers/staging/media/rkvdec/rkvdec.c
> > @@ -992,7 +992,7 @@ static void rkvdec_watchdog_func(struct work_struct 
> > *work)
> > }
> >  }
> >  
> > -static const struct of_device_id of_rkvdec_match[] = {
> > +static const struct of_device_id __maybe_unused of_rkvdec_match[] = {
> > { .compatible = "rockchip,rk3399-vdec" },
> > { /* sentinel */ }
> >  };
> >   
> 



Re: linux-next: error while fetching the i3c-fixes tree

2021-01-03 Thread Boris Brezillon
+Alexandre, the new I3C maintainer. You should probably flag him as the
person to contact if you have problem with the I3C tree in the future.

Hi Stephen,

On Sun, 3 Jan 2021 22:32:17 +1100
Stephen Rothwell  wrote:

> Hi all,
> 
> Fetching the i3c-fixes tree
> (git://git.kernel.org/pub/scm/linux/kernel/git/i3c/linux.git#master)
> produces this error:
> 
> fatal: couldn't find remote ref refs/heads/master
> 
> Should I maybe use the i3c/fixes branch instead?

Oops, I thought you were using that branch already. I guess I never
noticed because I didn't use the fixes branch much and kept the master
one around.

Sorry for the inconvenience.

Regards,

Boris



[GIT PULL] i3c: Changes for 5.11

2020-12-18 Thread Boris Brezillon
Hello Linus,

Here the I3C PR for 5.11. This should be my last PR (I resigned from
my maintainer position). Alexandre Belloni (maintainer of the RTC
subsystem) kindly proposed to take over, so he should send the I3C PRs
from now on.

Regards,

Boris 

The following changes since commit 3650b228f83adda7e5ee532e2b90429c03f7b9ec:

  Linux 5.10-rc1 (2020-10-25 15:14:11 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/i3c/linux.git tags/i3c/for-5.11

for you to fetch changes up to 95393f3e07ab53855b91881692a4a5b52dcdc03c:

  i3c/master/mipi-i3c-hci: quiet maybe-unused variable warning (2020-12-17 
10:31:30 +0100)


* Add the HCI driver
* Add a missing destroy_workqueue() in an error path
* Flag Alexandre Belloni as the new maintainer


Boris Brezillon (1):
  i3c: Resign from my maintainer role

Colin Ian King (1):
  i3c/master: Fix uninitialized variable next_addr

Nicolas Pitre (3):
  dt-bindings: i3c: MIPI I3C Host Controller Interface
  i3c/master: introduce the mipi-i3c-hci driver
  i3c/master/mipi-i3c-hci: quiet maybe-unused variable warning

Qinglang Miao (1):
  i3c master: fix missing destroy_workqueue() on error in 
i3c_master_register

 Documentation/devicetree/bindings/i3c/mipi-i3c-hci.yaml |   47 +++
 MAINTAINERS |2 +-
 drivers/i3c/master.c|5 +-
 drivers/i3c/master/Kconfig  |   13 +
 drivers/i3c/master/Makefile |1 +
 drivers/i3c/master/mipi-i3c-hci/Makefile|6 +
 drivers/i3c/master/mipi-i3c-hci/cmd.h   |   67 
 drivers/i3c/master/mipi-i3c-hci/cmd_v1.c|  378 
+++
 drivers/i3c/master/mipi-i3c-hci/cmd_v2.c|  316 
 drivers/i3c/master/mipi-i3c-hci/core.c  |  798 

 drivers/i3c/master/mipi-i3c-hci/dat.h   |   32 ++
 drivers/i3c/master/mipi-i3c-hci/dat_v1.c|  184 ++
 drivers/i3c/master/mipi-i3c-hci/dct.h   |   16 +
 drivers/i3c/master/mipi-i3c-hci/dct_v1.c|   36 ++
 drivers/i3c/master/mipi-i3c-hci/dma.c   |  784 
+++
 drivers/i3c/master/mipi-i3c-hci/ext_caps.c  |  308 
 drivers/i3c/master/mipi-i3c-hci/ext_caps.h  |   19 +
 drivers/i3c/master/mipi-i3c-hci/hci.h   |  144 
 drivers/i3c/master/mipi-i3c-hci/ibi.h   |   42 +++
 drivers/i3c/master/mipi-i3c-hci/pio.c   | 1041 

 drivers/i3c/master/mipi-i3c-hci/xfer_mode_rate.h|   79 
 21 files changed, 4316 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/i3c/mipi-i3c-hci.yaml
 create mode 100644 drivers/i3c/master/mipi-i3c-hci/Makefile
 create mode 100644 drivers/i3c/master/mipi-i3c-hci/cmd.h
 create mode 100644 drivers/i3c/master/mipi-i3c-hci/cmd_v1.c
 create mode 100644 drivers/i3c/master/mipi-i3c-hci/cmd_v2.c
 create mode 100644 drivers/i3c/master/mipi-i3c-hci/core.c
 create mode 100644 drivers/i3c/master/mipi-i3c-hci/dat.h
 create mode 100644 drivers/i3c/master/mipi-i3c-hci/dat_v1.c
 create mode 100644 drivers/i3c/master/mipi-i3c-hci/dct.h
 create mode 100644 drivers/i3c/master/mipi-i3c-hci/dct_v1.c
 create mode 100644 drivers/i3c/master/mipi-i3c-hci/dma.c
 create mode 100644 drivers/i3c/master/mipi-i3c-hci/ext_caps.c
 create mode 100644 drivers/i3c/master/mipi-i3c-hci/ext_caps.h
 create mode 100644 drivers/i3c/master/mipi-i3c-hci/hci.h
 create mode 100644 drivers/i3c/master/mipi-i3c-hci/ibi.h
 create mode 100644 drivers/i3c/master/mipi-i3c-hci/pio.c
 create mode 100644 drivers/i3c/master/mipi-i3c-hci/xfer_mode_rate.h


Re: [PATCH v4 6/9] spi: tegra210-quad: Add support for hardware dummy cycles transfer

2020-12-18 Thread Boris Brezillon
On Thu, 17 Dec 2020 12:28:44 -0800
Sowjanya Komatineni  wrote:

> Tegra Quad SPI controller hardware supports sending dummy bytes based
> on programmed dummy clock cycles after the actual transfer bytes.
> 
> This patch adds this support of hardware dummy bytes transfer and
> skips transfer of dummy bytes from the software.
> 
> For dummy cycles more than Tegra Quad SPI hardware maximum dummy
> cycles limit, driver transfers dummy bytes from the software.
> 
> Signed-off-by: Sowjanya Komatineni 
> ---
>  drivers/spi/spi-tegra210-quad.c | 41 
> -
>  1 file changed, 40 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c
> index e7bee8d..695a296 100644
> --- a/drivers/spi/spi-tegra210-quad.c
> +++ b/drivers/spi/spi-tegra210-quad.c
> @@ -117,6 +117,7 @@
>  
>  #define QSPI_MISC_REG   0x194
>  #define QSPI_NUM_DUMMY_CYCLE(x)  (((x) & 0xff) << 0)
> +#define QSPI_DUMMY_CYCLES_MAX0xff
>  
>  #define DATA_DIR_TX  BIT(0)
>  #define DATA_DIR_RX  BIT(1)
> @@ -170,6 +171,7 @@ struct tegra_qspi {
>   u32 def_command2_reg;
>   u32 spi_cs_timing1;
>   u32 spi_cs_timing2;
> + u8  dummy_cycles;
>  
>   struct completion   xfer_completion;
>   struct spi_transfer *curr_xfer;
> @@ -856,6 +858,8 @@ static int tegra_qspi_start_transfer_one(struct 
> spi_device *spi,
>  
>   tqspi->command1_reg = command1;
>  
> + tegra_qspi_writel(tqspi, QSPI_NUM_DUMMY_CYCLE(tqspi->dummy_cycles), 
> QSPI_MISC_REG);
> +
>   ret = tegra_qspi_flush_fifos(tqspi, false);
>   if (ret < 0)
>   return ret;
> @@ -974,7 +978,8 @@ static int tegra_qspi_transfer_one_message(struct 
> spi_master *master, struct spi
>  {
>   struct tegra_qspi *tqspi = spi_master_get_devdata(master);
>   struct spi_device *spi = msg->spi;
> - struct spi_transfer *xfer;
> + struct spi_transfer *xfer, *next_xfer;

next_after should be declared where it's actually used.

> + bool use_hw_dummy_cycles = false;

I don't think you need this variable (see below).

>   bool is_first_msg = true;
>   int ret;
>  
> @@ -984,8 +989,42 @@ static int tegra_qspi_transfer_one_message(struct 
> spi_master *master, struct spi
>   tqspi->rx_status = 0;
>  
>   list_for_each_entry(xfer, >transfers, transfer_list) {
> + u8 dummy_cycles = 0;

Should be declared where it's actually used, and you don't want it to be a u8
since you're checking that the result does not exceed 255 which will always
be true with a u8.

>   u32 cmd1;
>  
> + /*
> +  * Skip dummy bytes transfer if they are transferred by the 
> hardware along
> +  * with previous transfer.
> +  */
> + if (xfer->dummy_data && use_hw_dummy_cycles) {
> + msg->actual_length += xfer->len;
> + continue;
> + }
> +
> + /*
> +  * Tegra QSPI hardware supports dummy bytes transfer after 
> actual transfer
> +  * bytes based on programmed dummy clock cycles in the 
> QSPI_MISC register.
> +  * So, check if the next transfer is dummy data transfer and 
> program dummy
> +  * clock cycles along with the current transfer.
> +  */
> + if (!list_is_last(>transfer_list, >transfers)) {
> + next_xfer = list_next_entry(xfer, transfer_list);
> + if (next_xfer && next_xfer->dummy_data) {
> + dummy_cycles = next_xfer->len * 8 / 
> next_xfer->tx_nbits;
> + use_hw_dummy_cycles = true;
> + /*
> +  * Use software dummy bytes transfer if dummy 
> cycles exceeds
> +  * Tegra QSPI hardware maximum dummy cycles 
> limit.
> +  */
> + if (dummy_cycles > QSPI_DUMMY_CYCLES_MAX) {
> + use_hw_dummy_cycles = false;
> + dummy_cycles = 0;
> + }
> + }
> + }
> +
> + tqspi->dummy_cycles = dummy_cycles;
> +

This can be simplified:

/*
 * Skip dummy bytes transfer if they were issued with the
 * previous transfer.
 */
if (tqspi->dummy_cycles) {
WARN_ON(!xfer->dummy_data);
tqspi->dummy_cycles = 0;
}

/*
 * Tegra QSPI hardware supports dummy 

Re: [PATCH v4 5/9] spi: spi-mem: Mark dummy transfers by setting dummy_data bit

2020-12-18 Thread Boris Brezillon
On Fri, 18 Dec 2020 14:51:08 +0530
Pratyush Yadav  wrote:

> Hi Sowjanya,
> 
> On 17/12/20 12:28PM, Sowjanya Komatineni wrote:
> > This patch marks dummy transfer by setting dummy_data bit to 1.
> > 
> > Controllers supporting dummy transfer by hardware use this bit field
> > to skip software transfer of dummy bytes and use hardware dummy bytes
> > transfer.  
> 
> What is the benefit you get from this change? You add complexity in 
> spi-mem and the controller driver, so that must come with some benefits. 
> Here I don't see any. The transfer will certainly take the same amount 
> of time because the number or period of the dummy cycles has not 
> changed. So why is this needed?

Well, you don't have to queue TX bytes if you use HW-based dummy
cycles, but I agree, I'd expect the overhead to be negligible,
especially since we're talking about emitting a few bytes, not hundreds.
This being said, the complexity added to the core is reasonable IMHO,
so if it really helps reducing the CPU overhead (we might need some
numbers to prove that), I guess it's okay.

>  
> > Signed-off-by: Sowjanya Komatineni 
> > ---
> >  drivers/spi/spi-mem.c   | 1 +
> >  include/linux/spi/spi.h | 2 ++
> >  2 files changed, 3 insertions(+)
> > 
> > diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
> > index f3a3f19..c64371c 100644
> > --- a/drivers/spi/spi-mem.c
> > +++ b/drivers/spi/spi-mem.c
> > @@ -354,6 +354,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct 
> > spi_mem_op *op)
> > xfers[xferpos].tx_buf = tmpbuf + op->addr.nbytes + 1;
> > xfers[xferpos].len = op->dummy.nbytes;
> > xfers[xferpos].tx_nbits = op->dummy.buswidth;
> > +   xfers[xferpos].dummy_data = 1;
> > spi_message_add_tail([xferpos], );
> > xferpos++;
> > totalxferlen += op->dummy.nbytes;
> > diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
> > index aa09fdc..708f2f5 100644
> > --- a/include/linux/spi/spi.h
> > +++ b/include/linux/spi/spi.h
> > @@ -827,6 +827,7 @@ extern void spi_res_release(struct spi_controller *ctlr,
> >   *  transfer. If 0 the default (from @spi_device) is used.
> >   * @bits_per_word: select a bits_per_word other than the device default
> >   *  for this transfer. If 0 the default (from @spi_device) is used.
> > + * @dummy_data: indicates transfer is dummy bytes transfer.
> >   * @cs_change: affects chipselect after this transfer completes
> >   * @cs_change_delay: delay between cs deassert and assert when
> >   *  @cs_change is set and @spi_transfer is not the last in @spi_message
> > @@ -939,6 +940,7 @@ struct spi_transfer {
> > struct sg_table tx_sg;
> > struct sg_table rx_sg;
> >  
> > +   unsigneddummy_data:1;
> > unsignedcs_change:1;
> > unsignedtx_nbits:3;
> > unsignedrx_nbits:3;
> > -- 
> > 2.7.4
> >   
> 



Re: [PATCH v3 5/9] spi: spi-mem: Allow masters to transfer dummy cycles directly by hardware

2020-12-13 Thread Boris Brezillon
On Sun, 13 Dec 2020 10:54:26 +0100
Boris Brezillon  wrote:

> On Sat, 12 Dec 2020 09:28:50 -0800
> Sowjanya Komatineni  wrote:
> 
> > On 12/12/20 2:57 AM, Boris Brezillon wrote:  
> > > On Fri, 11 Dec 2020 13:15:59 -0800
> > > Sowjanya Komatineni  wrote:
> > >
> > >> This patch adds a flag SPI_MASTER_USES_HW_DUMMY_CYCLES for the 
> > >> controllers
> > >> that support transfer of dummy cycles by the hardware directly.
> > > Hm, not sure this is a good idea. I mean, if we expect regular SPI
> > > devices to use this feature, then why not, but if it's just for
> > > spi-mem, I'd recommend implementing a driver-specific exec_op() instead
> > > of using the default one.
> > 
> > dummy cycles programming is SPI device specific.
> > 
> > Transfer of dummy bytes by SW or HW controller can be depending on 
> > features supported by controller.
> > 
> > Adding controller driver specific exec_op() Just for skipping dummy 
> > bytes transfer will have so much of redundant code pretty much what all 
> > spi_mem_exec_op does.
> > 
> > So in v1, I handled this in controller driver by skipping SW transfer of 
> > dummy bytes during dummy phase and programming dummy cycles in 
> > controller register to allow HW to transfer.
> > 
> > Based on v1 feedback discussion, added this flag 
> > SPI_MASTER_USES_HW_DUMMY_CYCLES which can be used by controllers 
> > supporting HW dummy bytes transfer and updated spi_mem_exec_op to skip 
> > SW dummy bytes.
> > 
> > This helps other controllers supporting HW transfer of dummy bytes as 
> > well just to set the flag and use dummy cycles directly.  
> 
> Except saying a spi_message has X dummy cycle is not precise enough.
> Where are those dummy cycles in the transfer sequence? spi-mem has well
> defined sequencing (cmd[+addr][+dummy][+data]) so we know exacly where
> dummy cycles are, but trying to retro-fit the dummy-cycle concept in
> the generic spi_message is confusing IMHO. If want to avoid code
> duplication, I'm pretty sure the driver can be reworked so the
> spi_transfer/exec_op() path can share most of the logic (that probably
> implies declaring a tegra_qspi_op).

Something like that might also do the trick:

--->8---

diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
index ef53290b7d24..8b0476f37fbb 100644
--- a/drivers/spi/spi-mem.c
+++ b/drivers/spi/spi-mem.c
@@ -353,6 +353,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct 
spi_mem_op *op)
xfers[xferpos].tx_buf = tmpbuf + op->addr.nbytes + 1;
xfers[xferpos].len = op->dummy.nbytes;
xfers[xferpos].tx_nbits = op->dummy.buswidth;
+   xfers[xferpos].dummy_data = 1;
spi_message_add_tail([xferpos], );
xferpos++;
totalxferlen += op->dummy.nbytes;
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index 99380c0825db..ecf7989318c5 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -807,6 +807,10 @@ extern void spi_res_release(struct spi_controller *ctlr,
  *  transfer. If 0 the default (from @spi_device) is used.
  * @bits_per_word: select a bits_per_word other than the device default
  *  for this transfer. If 0 the default (from @spi_device) is used.
+ * @dummy_data: set to 1 for a dummy transfer (a transfer whose data is
+ *  ignored). Controllers that are able to issue dummy cycles can ignore
+ *  tx_buf, for those that can't tx_buf will contain dummy bytes. The
+ *  number of  dummy cycles to issue is (len * tx_bits) / 8.
  * @cs_change: affects chipselect after this transfer completes
  * @cs_change_delay: delay between cs deassert and assert when
  *  @cs_change is set and @spi_transfer is not the last in @spi_message
@@ -919,6 +923,7 @@ struct spi_transfer {
struct sg_table tx_sg;
struct sg_table rx_sg;
 
+   unsigneddummy_data:1;
unsignedcs_change:1;
unsignedtx_nbits:3;
unsignedrx_nbits:3;


Re: [PATCH v3 6/9] spi: tegra210-quad: Add support for hardware dummy cycles

2020-12-13 Thread Boris Brezillon
On Fri, 11 Dec 2020 13:16:00 -0800
Sowjanya Komatineni  wrote:

> Tegra Quad SPI controller hardware supports sending dummy cycles
> after address bytes.
> 
> This patch adds this support.
> 
> Signed-off-by: Sowjanya Komatineni 
> ---
>  drivers/spi/spi-tegra210-quad.c | 22 +-
>  1 file changed, 21 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c
> index 624f395..1d1b125 100644
> --- a/drivers/spi/spi-tegra210-quad.c
> +++ b/drivers/spi/spi-tegra210-quad.c
> @@ -124,6 +124,13 @@
>  #define QSPI_DMA_TIMEOUT (msecs_to_jiffies(1000))
>  #define DEFAULT_QSPI_DMA_BUF_LEN (64 * 1024)
>  
> +enum transfer_phase {
> + CMD_BYTE_XFER = 0,
> + ADDR_BYTES_XFER,
> + DATA_BYTES_XFER,
> + MAX_XFERS,
> +};
> +
>  struct tegra_qspi_client_data {
>   int tx_clk_tap_delay;
>   int rx_clk_tap_delay;
> @@ -857,6 +864,8 @@ static int tegra_qspi_start_transfer_one(struct 
> spi_device *spi,
>  
>   tqspi->command1_reg = command1;
>  
> + tegra_qspi_writel(tqspi, QSPI_NUM_DUMMY_CYCLE(tqspi->dummy_cycles), 
> QSPI_MISC_REG);
> +
>   ret = tegra_qspi_flush_fifos(tqspi, false);
>   if (ret < 0)
>   return ret;
> @@ -977,7 +986,7 @@ static int tegra_qspi_transfer_one_message(struct 
> spi_master *master, struct spi
>   struct spi_device *spi = msg->spi;
>   struct spi_transfer *xfer;
>   bool is_first_msg = true;
> - int ret;
> + int ret, xfer_phase = 0;
>  
>   msg->status = 0;
>   msg->actual_length = 0;
> @@ -987,6 +996,15 @@ static int tegra_qspi_transfer_one_message(struct 
> spi_master *master, struct spi
>   list_for_each_entry(xfer, >transfers, transfer_list) {
>   u32 cmd1;
>  
> + /*
> +  * Program dummy clock cycles in Tegra QSPI register only
> +  * during address transfer phase.
> +  */
> + if (xfer_phase == ADDR_BYTES_XFER)
> + tqspi->dummy_cycles = msg->dummy_cycles;
> + else
> + tqspi->dummy_cycles = 0;

That's fragile. You're trying to guess the phase (which is clearly a
spi-mem concept) from the position of the transfer in the list. What
happens if a spi-mem operation has no address bytes but requires dummy
cycles after the command? What happens if we patch spi_mem_exec_op() to
merge the cmd and address bytes in a single transfer (that's an option
I considered at some point when designing the framework before deciding
it was not worth the extra complexity)?

Besides, I keep thinking the regular transfer path should not assume
it's being passed spi-mem operations, if it is, that means you should
overload the default exec_op(). The more I look at it the less I like
this idea of adding a dummy_cycles field to spi_message. I'm pretty
sure we can find other ways to avoid code duplication if that's your
main concern.

> +
>   reinit_completion(>xfer_completion);
>  
>   cmd1 = tegra_qspi_setup_transfer_one(spi, xfer, is_first_msg);
> @@ -1018,6 +1036,7 @@ static int tegra_qspi_transfer_one_message(struct 
> spi_master *master, struct spi
>   }
>  
>   msg->actual_length += xfer->len;
> + xfer_phase++;
>  
>  complete_xfer:
>   if (ret < 0) {
> @@ -1203,6 +1222,7 @@ static int tegra_qspi_probe(struct platform_device 
> *pdev)
>   master->mode_bits = SPI_MODE_0 | SPI_MODE_3 | SPI_CS_HIGH |
>   SPI_TX_DUAL | SPI_RX_DUAL | SPI_TX_QUAD | 
> SPI_RX_QUAD;
>   master->bits_per_word_mask = SPI_BPW_MASK(32) | SPI_BPW_MASK(16) | 
> SPI_BPW_MASK(8);
> + master->flags = SPI_MASTER_USES_HW_DUMMY_CYCLES;
>   master->setup = tegra_qspi_setup;
>   master->cleanup = tegra_qspi_cleanup;
>   master->transfer_one_message = tegra_qspi_transfer_one_message;



Re: [PATCH v3 5/9] spi: spi-mem: Allow masters to transfer dummy cycles directly by hardware

2020-12-13 Thread Boris Brezillon
On Sat, 12 Dec 2020 09:28:50 -0800
Sowjanya Komatineni  wrote:

> On 12/12/20 2:57 AM, Boris Brezillon wrote:
> > On Fri, 11 Dec 2020 13:15:59 -0800
> > Sowjanya Komatineni  wrote:
> >  
> >> This patch adds a flag SPI_MASTER_USES_HW_DUMMY_CYCLES for the controllers
> >> that support transfer of dummy cycles by the hardware directly.  
> > Hm, not sure this is a good idea. I mean, if we expect regular SPI
> > devices to use this feature, then why not, but if it's just for
> > spi-mem, I'd recommend implementing a driver-specific exec_op() instead
> > of using the default one.  
> 
> dummy cycles programming is SPI device specific.
> 
> Transfer of dummy bytes by SW or HW controller can be depending on 
> features supported by controller.
> 
> Adding controller driver specific exec_op() Just for skipping dummy 
> bytes transfer will have so much of redundant code pretty much what all 
> spi_mem_exec_op does.
> 
> So in v1, I handled this in controller driver by skipping SW transfer of 
> dummy bytes during dummy phase and programming dummy cycles in 
> controller register to allow HW to transfer.
> 
> Based on v1 feedback discussion, added this flag 
> SPI_MASTER_USES_HW_DUMMY_CYCLES which can be used by controllers 
> supporting HW dummy bytes transfer and updated spi_mem_exec_op to skip 
> SW dummy bytes.
> 
> This helps other controllers supporting HW transfer of dummy bytes as 
> well just to set the flag and use dummy cycles directly.

Except saying a spi_message has X dummy cycle is not precise enough.
Where are those dummy cycles in the transfer sequence? spi-mem has well
defined sequencing (cmd[+addr][+dummy][+data]) so we know exacly where
dummy cycles are, but trying to retro-fit the dummy-cycle concept in
the generic spi_message is confusing IMHO. If want to avoid code
duplication, I'm pretty sure the driver can be reworked so the
spi_transfer/exec_op() path can share most of the logic (that probably
implies declaring a tegra_qspi_op).

> 
> > If we go for those core changes, we should at least add a
> > ctrl->max_dummy_cycles field so the core can fallback to regular writes
> > when the number of dummy cycles in the spi_mem_op exceeds what the
> > controller can do.  
> Yes makes sense. Will add this once we decide on keeping this flag to 
> identify controllers supporting HW transfer of dummy bytes Vs SW transfer.
> >> For controller with this flag set, spi-mem driver will skip dummy bytes
> >> transfer in the spi message.
> >>
> >> Controller drivers can get the number of dummy cycles from spi_message.
> >>
> >> Signed-off-by: Sowjanya Komatineni 
> >> ---
> >>   drivers/spi/spi-mem.c   | 18 +++---
> >>   include/linux/spi/spi.h |  8 
> >>   2 files changed, 19 insertions(+), 7 deletions(-)
> >>
> >> diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
> >> index f3a3f19..38a523b 100644
> >> --- a/drivers/spi/spi-mem.c
> >> +++ b/drivers/spi/spi-mem.c
> >> @@ -350,13 +350,17 @@ int spi_mem_exec_op(struct spi_mem *mem, const 
> >> struct spi_mem_op *op)
> >>}
> >>   
> >>if (op->dummy.nbytes) {
> >> -  memset(tmpbuf + op->addr.nbytes + 1, 0xff, op->dummy.nbytes);
> >> -  xfers[xferpos].tx_buf = tmpbuf + op->addr.nbytes + 1;
> >> -  xfers[xferpos].len = op->dummy.nbytes;
> >> -  xfers[xferpos].tx_nbits = op->dummy.buswidth;
> >> -  spi_message_add_tail([xferpos], );
> >> -  xferpos++;
> >> -  totalxferlen += op->dummy.nbytes;
> >> +  if (ctlr->flags & SPI_MASTER_USES_HW_DUMMY_CYCLES) {
> >> +  msg.dummy_cycles = (op->dummy.nbytes * 8) / 
> >> op->dummy.buswidth;
> >> +  } else {
> >> +  memset(tmpbuf + op->addr.nbytes + 1, 0xff, 
> >> op->dummy.nbytes);
> >> +  xfers[xferpos].tx_buf = tmpbuf + op->addr.nbytes + 1;
> >> +  xfers[xferpos].len = op->dummy.nbytes;
> >> +  xfers[xferpos].tx_nbits = op->dummy.buswidth;
> >> +  spi_message_add_tail([xferpos], );
> >> +  xferpos++;
> >> +  totalxferlen += op->dummy.nbytes;
> >> +  }
> >>}
> >>   
> >>if (op->data.nbytes) {
> >> diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
> >> index aa09fdc..2024149 100644
> >> --- a/include/linux/spi/spi.h
> >> +++ b/incl

Re: [PATCH v3 5/9] spi: spi-mem: Allow masters to transfer dummy cycles directly by hardware

2020-12-12 Thread Boris Brezillon
On Fri, 11 Dec 2020 13:15:59 -0800
Sowjanya Komatineni  wrote:

> This patch adds a flag SPI_MASTER_USES_HW_DUMMY_CYCLES for the controllers
> that support transfer of dummy cycles by the hardware directly.

Hm, not sure this is a good idea. I mean, if we expect regular SPI
devices to use this feature, then why not, but if it's just for
spi-mem, I'd recommend implementing a driver-specific exec_op() instead
of using the default one.

If we go for those core changes, we should at least add a
ctrl->max_dummy_cycles field so the core can fallback to regular writes
when the number of dummy cycles in the spi_mem_op exceeds what the
controller can do.

> 
> For controller with this flag set, spi-mem driver will skip dummy bytes
> transfer in the spi message.
> 
> Controller drivers can get the number of dummy cycles from spi_message.
> 
> Signed-off-by: Sowjanya Komatineni 
> ---
>  drivers/spi/spi-mem.c   | 18 +++---
>  include/linux/spi/spi.h |  8 
>  2 files changed, 19 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
> index f3a3f19..38a523b 100644
> --- a/drivers/spi/spi-mem.c
> +++ b/drivers/spi/spi-mem.c
> @@ -350,13 +350,17 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct 
> spi_mem_op *op)
>   }
>  
>   if (op->dummy.nbytes) {
> - memset(tmpbuf + op->addr.nbytes + 1, 0xff, op->dummy.nbytes);
> - xfers[xferpos].tx_buf = tmpbuf + op->addr.nbytes + 1;
> - xfers[xferpos].len = op->dummy.nbytes;
> - xfers[xferpos].tx_nbits = op->dummy.buswidth;
> - spi_message_add_tail([xferpos], );
> - xferpos++;
> - totalxferlen += op->dummy.nbytes;
> + if (ctlr->flags & SPI_MASTER_USES_HW_DUMMY_CYCLES) {
> + msg.dummy_cycles = (op->dummy.nbytes * 8) / 
> op->dummy.buswidth;
> + } else {
> + memset(tmpbuf + op->addr.nbytes + 1, 0xff, 
> op->dummy.nbytes);
> + xfers[xferpos].tx_buf = tmpbuf + op->addr.nbytes + 1;
> + xfers[xferpos].len = op->dummy.nbytes;
> + xfers[xferpos].tx_nbits = op->dummy.buswidth;
> + spi_message_add_tail([xferpos], );
> + xferpos++;
> + totalxferlen += op->dummy.nbytes;
> + }
>   }
>  
>   if (op->data.nbytes) {
> diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
> index aa09fdc..2024149 100644
> --- a/include/linux/spi/spi.h
> +++ b/include/linux/spi/spi.h
> @@ -512,6 +512,8 @@ struct spi_controller {
>  
>  #define SPI_MASTER_GPIO_SS   BIT(5)  /* GPIO CS must select slave */
>  
> +#define SPI_MASTER_USES_HW_DUMMY_CYCLES  BIT(6)  /* HW dummy bytes 
> transfer */
> +
>   /* flag indicating this is an SPI slave controller */
>   boolslave;
>  
> @@ -1022,6 +1024,12 @@ struct spi_message {
>   unsignedactual_length;
>   int status;
>  
> + /*
> +  * dummy cycles in the message transfer. This is used by the controller
> +  * drivers supports transfer of dummy cycles directly by the hardware.
> +  */
> + u8  dummy_cycles;
> +
>   /* for optional use by whatever driver currently owns the
>* spi_message ...  between calls to spi_async and then later
>* complete(), that's the spi_controller controller driver.



Re: linux-next: build warning after merge of the nand tree

2020-11-20 Thread Boris Brezillon
On Fri, 20 Nov 2020 12:23:59 +0100
Miquel Raynal  wrote:

> Hi Serge,
> 
> Stephen Rothwell  wrote on Fri, 20 Nov 2020
> 11:39:29 +1100:
> 
> > Hi all,
> > 
> > After merging the nand tree, today's linux-next build (x86_64
> > allmodconfig) produced this warning:
> > 
> > drivers/mtd/maps/physmap-bt1-rom.c: In function 'bt1_rom_map_read':
> > drivers/mtd/maps/physmap-bt1-rom.c:39:10: warning: cast from pointer to 
> > integer of different size [-Wpointer-to-int-cast]
> >39 |  shift = (unsigned int)src & 0x3;
> >   |  ^
> > drivers/mtd/maps/physmap-bt1-rom.c: In function 'bt1_rom_map_copy_from':
> > drivers/mtd/maps/physmap-bt1-rom.c:78:10: warning: cast from pointer to 
> > integer of different size [-Wpointer-to-int-cast]
> >78 |  shift = (unsigned int)src & 0x3;
> >   |  ^
> > 
> > Introduced by commit
> > 
> >   69a75a1a47d8 ("mtd: physmap: physmap-bt1-rom: Fix __iomem addrspace 
> > removal warning")
> >   
> 
> Too bad :/ I'll drop this patch for now, let's look for another
> solution...

uintptr_t cast?


Re: [PATCH v6] mtd: spinand: micron: add support for MT29F2G01AAAED

2020-11-06 Thread Boris Brezillon
On Fri,  6 Nov 2020 22:28:38 +0800
Thirumalesha Narasimhappa  wrote:

> The MT29F2G01AAAED is a single die, 2Gb Micron SPI NAND Flash with 4-bit
> ECC
> 
> Signed-off-by: Thirumalesha Narasimhappa 
> ---
> 
> v6: Reverted the SPINAND_OP_VARIANTS() as they were in v4 for
> MT29F2G01AAAED device
> 
> v5: As per the review comments, the changes were reverted to the v2,
> except the MT29F2G01AAAED device related (including the review comments)
> 
> v4: Split patch into two parts,
> 1. Generalise the oob structure name & function names as show in v3
> 2. Add support for MT29F2G01AAAED device
>a. Add oob section check in micron_ooblayout_free function
>b. Rename mt29f2g01aaaed_* to generic name micron_4_*
> 
> v3: As per the review comments,
>  1. Renamed read_cache_variants as quadio_read_cache_variants,
> write_cache_variants as
>   x4_write_cache_variants/x1_write_cache_variants,
> update_cache_variants as
>   x4_update_cache_variants/x1_update_cache_variants,
> read_cache_variants as x4_read_cache_variants

We want those renames in a separate patch (ideally happening before
this one).


Re: [v3 4/4] spi: aspeed: Add ASPEED FMC/SPI memory controller driver

2020-11-06 Thread Boris Brezillon
+Tudor and Vignesh

On Fri, 6 Nov 2020 10:21:06 +
Chin-Ting Kuo  wrote:

> Hi Boris,
> 
> Thanks for your comments and suggestions.
> 
> > -Original Message-----
> > From: Boris Brezillon 
> > Sent: Friday, November 6, 2020 5:06 PM
> > To: Chin-Ting Kuo 
> > Subject: Re: [v3 4/4] spi: aspeed: Add ASPEED FMC/SPI memory controller
> > driver
> > 
> > On Fri, 6 Nov 2020 08:58:23 +
> > Chin-Ting Kuo  wrote:
> >   
> > > Hi Boris,
> > >
> > > Thanks for your quick reply.
> > >  
> > > > -Original Message-
> > > > From: Boris Brezillon 
> > > > Sent: Thursday, November 5, 2020 11:12 PM
> > > > To: Cédric Le Goater ; robh...@kernel.org
> > > > Cc: Chin-Ting Kuo ;
> > > > broo...@kernel.org; j...@jms.id.au; and...@aj.id.au;
> > > > bbrezil...@kernel.org; devicet...@vger.kernel.org;
> > > > linux-kernel@vger.kernel.org; linux-asp...@lists.ozlabs.org;
> > > > linux-...@vger.kernel.org; BMC-SW 
> > > > Subject: Re: [v3 4/4] spi: aspeed: Add ASPEED FMC/SPI memory
> > > > controller driver
> > > >
> > > > Hi,
> > > >
> > > > On Thu, 5 Nov 2020 15:09:11 +0100
> > > > Cédric Le Goater  wrote:
> > > >  
> > > > > Hello Chin-Ting,
> > > > >
> > > > > Thanks for this driver. It's much cleaner than the previous and we
> > > > > should try adding support for the AST2500 SoC also. I guess we can
> > > > > keep the old driver for the AST2400 which has a different register 
> > > > > layout.
> > > > >
> > > > > On the patchset, I think we should split this patch in three :
> > > > >
> > > > >  - basic support
> > > > >  - AHB window calculation depending on the flash size
> > > > >  - read training support  
> > > >
> > > > I didn't look closely at the implementation, but if the read
> > > > training tries to read a section of the NOR, I'd recommend exposing
> > > > that feature through spi-mem and letting the SPI-NOR framework
> > > > trigger the training instead of doing that at dirmap creation time
> > > > (remember that spi-mem is also used for SPI NANDs which use the dirmap  
> > API too, and this training is unlikely to work there).  
> > > >
> > > > The SPI-NOR framework could pass a read op template and a reference
> > > > pattern such that all the spi-mem driver has to do is execute the
> > > > template op and compare the output to the reference buffer.
> > > >  
> > >
> > > I agree it. Before, I were not able to find a suitable location to 
> > > implement  
> > read training feature.  
> > > I think that I can add a SPI timing training function in
> > > "spi_controller_mem_ops" struct and call it by a wrapper function called 
> > > at  
> > the bottom of spi_nor_probe() in spi-nor.c.  
> > > Maybe, SPI-NOR framework does not need to pass reference buffer since
> > > calibration method depends on each SoC itself and buffer size may be  
> > variant.  
> > > The detail calibration method may be implemented in each SoC SPI driver.  
> > 
> > That's a real problem IMO. What makes this pattern SoC specific? I can see
> > why the location in flash could be *board* specific, but the pattern should 
> > be
> > pretty common, right? As for the spi-mem operation to be executed, it's
> > definitely memory specific (I can imagine some flash vendors providing a
> > specific command returning a fixed pattern that's not actually stored on a
> > visible portion of the flash).  
> 
> You are right, the pattern should be pretty common. The thing I was worried 
> about is the size of
> that buffer since, maybe, some controllers need to read more data than others 
> in order to get good
> training result.

It would be good to see how other controllers implement that. I know
that the Cadence controller had something similar. Vignesh might be
able to share his thoughts on this.

> 
> > >
> > > Besides, I am thinking about the possibility for adding a
> > > "spi_mem_post_init" function in spi-mem framework sine for some SoCs,
> > > SPI controller needs to adjust some settings after getting SPI flash  
> > information.
> > 
> > I don't think that's a good idea. The spi-mem interface should stay
> > memory-type agnostic and doing that means we somehow pass N

Re: [v3 4/4] spi: aspeed: Add ASPEED FMC/SPI memory controller driver

2020-11-06 Thread Boris Brezillon
On Fri, 6 Nov 2020 08:58:23 +
Chin-Ting Kuo  wrote:

> Hi Boris,
> 
> Thanks for your quick reply.
> 
> > -Original Message-----
> > From: Boris Brezillon 
> > Sent: Thursday, November 5, 2020 11:12 PM
> > To: Cédric Le Goater ; robh...@kernel.org
> > Cc: Chin-Ting Kuo ; broo...@kernel.org;
> > j...@jms.id.au; and...@aj.id.au; bbrezil...@kernel.org;
> > devicet...@vger.kernel.org; linux-kernel@vger.kernel.org;
> > linux-asp...@lists.ozlabs.org; linux-...@vger.kernel.org; BMC-SW
> > 
> > Subject: Re: [v3 4/4] spi: aspeed: Add ASPEED FMC/SPI memory controller
> > driver
> > 
> > Hi,
> > 
> > On Thu, 5 Nov 2020 15:09:11 +0100
> > Cédric Le Goater  wrote:
> >   
> > > Hello Chin-Ting,
> > >
> > > Thanks for this driver. It's much cleaner than the previous and we
> > > should try adding support for the AST2500 SoC also. I guess we can
> > > keep the old driver for the AST2400 which has a different register layout.
> > >
> > > On the patchset, I think we should split this patch in three :
> > >
> > >  - basic support
> > >  - AHB window calculation depending on the flash size
> > >  - read training support  
> > 
> > I didn't look closely at the implementation, but if the read training tries 
> > to read
> > a section of the NOR, I'd recommend exposing that feature through spi-mem
> > and letting the SPI-NOR framework trigger the training instead of doing 
> > that at
> > dirmap creation time (remember that spi-mem is also used for SPI NANDs
> > which use the dirmap API too, and this training is unlikely to work there).
> > 
> > The SPI-NOR framework could pass a read op template and a reference pattern
> > such that all the spi-mem driver has to do is execute the template op and
> > compare the output to the reference buffer.
> >   
> 
> I agree it. Before, I were not able to find a suitable location to implement 
> read training feature.
> I think that I can add a SPI timing training function in 
> "spi_controller_mem_ops" struct and
> call it by a wrapper function called at the bottom of spi_nor_probe() in 
> spi-nor.c.
> Maybe, SPI-NOR framework does not need to pass reference buffer since 
> calibration
> method depends on each SoC itself and buffer size may be variant.
> The detail calibration method may be implemented in each SoC SPI driver.

That's a real problem IMO. What makes this pattern SoC specific? I can
see why the location in flash could be *board* specific, but the
pattern should be pretty common, right? As for the spi-mem operation to
be executed, it's definitely memory specific (I can imagine some flash
vendors providing a specific command returning a fixed pattern that's
not actually stored on a visible portion of the flash).

> 
> Besides, I am thinking about the possibility for adding a "spi_mem_post_init" 
> function in
> spi-mem framework sine for some SoCs, SPI controller needs to adjust some 
> settings
> after getting SPI flash information.

I don't think that's a good idea. The spi-mem interface should stay
memory-type agnostic and doing that means we somehow pass NOR specific
info. What is it that you need exactly, and why?


Re: [v3 4/4] spi: aspeed: Add ASPEED FMC/SPI memory controller driver

2020-11-05 Thread Boris Brezillon
Hi,

On Thu, 5 Nov 2020 15:09:11 +0100
Cédric Le Goater  wrote:

> Hello Chin-Ting,
> 
> Thanks for this driver. It's much cleaner than the previous and we should 
> try adding support for the AST2500 SoC also. I guess we can keep the old 
> driver for the AST2400 which has a different register layout.
> 
> On the patchset, I think we should split this patch in three : 
> 
>  - basic support
>  - AHB window calculation depending on the flash size
>  - read training support  

I didn't look closely at the implementation, but if the read training
tries to read a section of the NOR, I'd recommend exposing that feature
through spi-mem and letting the SPI-NOR framework trigger the training
instead of doing that at dirmap creation time (remember that spi-mem is
also used for SPI NANDs which use the dirmap API too, and this training
is unlikely to work there).

The SPI-NOR framework could pass a read op template and a reference
pattern such that all the spi-mem driver has to do is execute the
template op and compare the output to the reference buffer.


> 
> We should avoid magic values when setting registers. This is confusing 
> and defines are much better.
>  
> AST2500 support will be a bit challenging because HW does not allow
> to configure a 128MB AHB window, max is 120MB This is a bug and the work 
> around is to use user mode for the remaining 8MB. Something to keep in
> mind.

Most SPI-MEM controllers don't have such a big dirmap window anyway, and
that shouldn't be a problem, because we don't expose the direct mapping
directly (as would be done if we were trying to support something like
XIP). That means that, assuming your controller allows controlling the
base spi-mem address the direct mapping points to, you should be able
to adjust the window at runtime and make it point where you requested.

Note that dirmap_{read,write}() are allowed to return less data than
requested thus simplifying the case where a specific access requires a
window adjustment in the middle of an read/write operation.

Regards,

Boris


Re: [PATCH v5] mtd: spinand: micron: add support for MT29F2G01AAAED

2020-11-05 Thread Boris Brezillon
On Tue, 3 Nov 2020 23:18:54 +0800
Thirumalesha N  wrote:

> Hi Boris,
> 
> On Tue, Nov 3, 2020 at 11:03 PM Boris Brezillon <
> boris.brezil...@collabora.com> wrote:  
> 
> > On Tue,  3 Nov 2020 22:59:01 +0800
> > Thirumalesha Narasimhappa  wrote:
> >  
> > > The MT29F2G01AAAED is a single die, 2Gb Micron SPI NAND Flash with 4-bit
> > > ECC
> > >
> > > Signed-off-by: Thirumalesha Narasimhappa 
> > > ---
> > >
> > > v5: As per the review comments, the changes were reverted to the v2,
> > > except the MT29F2G01AAAED device related (including the review comments)  
> >
> > I don't think that's what Miquel suggested, especially not for the
> > {write,update,write}_cache_variants helpers.
> >  
> 
> 
> I was a bit confused with the multiple levels of comments with the previous
> patch and I renamed *{write,update,write}_cache_var**iants* to *micron_4_**
> to avoid function redefinition.
> Please can you direct me with this patch, what needs to be modified/renamed
> ?

Keep the SPINAND_OP_VARIANTS() as they were in v4 and use the micron_4_
prefix for ECC related stuff.


Re: [PATCH v5] mtd: spinand: micron: add support for MT29F2G01AAAED

2020-11-03 Thread Boris Brezillon
On Tue,  3 Nov 2020 22:59:01 +0800
Thirumalesha Narasimhappa  wrote:

> The MT29F2G01AAAED is a single die, 2Gb Micron SPI NAND Flash with 4-bit
> ECC
> 
> Signed-off-by: Thirumalesha Narasimhappa 
> ---
> 
> v5: As per the review comments, the changes were reverted to the v2,
> except the MT29F2G01AAAED device related (including the review comments)

I don't think that's what Miquel suggested, especially not for the
{write,update,write}_cache_variants helpers.

> 
> v4: Split patch into two parts,
> 1. Generalise the oob structure name & function names as show in v3
> 2. Add support for MT29F2G01AAAED device
>a. Add oob section check in micron_ooblayout_free function
>b. Rename mt29f2g01aaaed_* to generic name micron_4_*
> 
> v3: As per the review comments,
>  1. Renamed read_cache_variants as quadio_read_cache_variants,
> write_cache_variants as
>   x4_write_cache_variants/x1_write_cache_variants,
> update_cache_variants as
>   x4_update_cache_variants/x1_update_cache_variants,
> read_cache_variants as x4_read_cache_variants
>  2. Renamed micron_8_ooblayout as micron_grouped_ooblayout &
> mt29f2g01aaaed_ooblayout as
>   micron_interleaved_ooblayout
>  3. Generalized page size based oob section check in
> mt29f2g01aaaed_ooblayout_ecc function
>   and separate case check for two bytes BBM reserved in
> mt29f2g01aaaed_ooblayout_free function
>  4. Removed mt29f2g01aaaed_ecc_get_status function &
> MICRON_STATUS_ECC_1TO4_BITFLIPS
> 
> v2: Removed SPINAND_SELECT_TARGET as per the comments & fixed typo
> errors
> 
> v1: Add support for Micron SPI Nand device MT29F2G01AAAED
> 
>  drivers/mtd/nand/spi/micron.c | 64 +++
>  1 file changed, 64 insertions(+)
> 
> diff --git a/drivers/mtd/nand/spi/micron.c b/drivers/mtd/nand/spi/micron.c
> index 5d370cfcdaaa..0b1e48d5c9d4 100644
> --- a/drivers/mtd/nand/spi/micron.c
> +++ b/drivers/mtd/nand/spi/micron.c
> @@ -44,6 +44,19 @@ static SPINAND_OP_VARIANTS(update_cache_variants,
>   SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
>   SPINAND_PROG_LOAD(false, 0, NULL, 0));
>  
> +/* Micron  MT29F2G01AAAED Device */
> +static SPINAND_OP_VARIANTS(micron_4_read_cache_variants,
> +SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
> +SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
> +SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
> +SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 
> 0));
> +
> +static SPINAND_OP_VARIANTS(micron_4_write_cache_variants,
> +SPINAND_PROG_LOAD(true, 0, NULL, 0));
> +
> +static SPINAND_OP_VARIANTS(micron_4_update_cache_variants,
> +SPINAND_PROG_LOAD(false, 0, NULL, 0));
> +
>  static int micron_8_ooblayout_ecc(struct mtd_info *mtd, int section,
> struct mtd_oob_region *region)
>  {
> @@ -74,6 +87,47 @@ static const struct mtd_ooblayout_ops micron_8_ooblayout = 
> {
>   .free = micron_8_ooblayout_free,
>  };
>  
> +static int micron_4_ooblayout_ecc(struct mtd_info *mtd, int section,
> +   struct mtd_oob_region *region)
> +{
> + struct spinand_device *spinand = mtd_to_spinand(mtd);
> +
> + if (section >= spinand->base.memorg.pagesize /
> + mtd->ecc_step_size)
> + return -ERANGE;
> +
> + region->offset = (section * 16) + 8;
> + region->length = 8;
> +
> + return 0;
> +}
> +
> +static int micron_4_ooblayout_free(struct mtd_info *mtd, int section,
> +struct mtd_oob_region *region)
> +{
> + struct spinand_device *spinand = mtd_to_spinand(mtd);
> +
> + if (section >= spinand->base.memorg.pagesize /
> + mtd->ecc_step_size)
> + return -ERANGE;
> +
> + if (section) {
> + region->offset = 16 * section;
> + region->length = 8;
> + } else {
> + /* section 0 has two bytes reserved for the BBM */
> + region->offset = 2;
> + region->length = 6;
> + }
> +
> + return 0;
> +}
> +
> +static const struct mtd_ooblayout_ops micron_4_ooblayout = {
> + .ecc = micron_4_ooblayout_ecc,
> + .free = micron_4_ooblayout_free,
> +};
> +
>  static int micron_select_target(struct spinand_device *spinand,
>   unsigned int target)
>  {
> @@ -217,6 +271,16 @@ static const struct spinand_info micron_spinand_table[] 
> = {
>SPINAND_ECCINFO(_8_ooblayout,
>micron_8_ecc_get_status),
>SPINAND_SELECT_TARGET(micron_select_target)),
> + /* M69A 2Gb 3.3V */
> + SPINAND_INFO("MT29F2G01AAAED",
> +  SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x9F),
> +  NAND_MEMORG(1, 2048, 64, 64, 2048, 80, 2, 1, 1),
> +  

Re: [PATCH] drm/panfrost: Fix module unload

2020-11-03 Thread Boris Brezillon
On Fri, 30 Oct 2020 14:58:33 +
Steven Price  wrote:

> When unloading the call to pm_runtime_put_sync_suspend() will attempt to
> turn the GPU cores off, however panfrost_device_fini() will have turned
> the clocks off. This leads to the hardware locking up.
> 
> Instead don't call pm_runtime_put_sync_suspend() and instead simply mark
> the device as suspended using pm_runtime_set_suspended(). And also
> include this on the error path in panfrost_probe().
> 
> Fixes: aebe8c22a912 ("drm/panfrost: Fix possible suspend in panfrost_remove")
> Signed-off-by: Steven Price 

Queued to drm-misc-fixes.

Thanks,

Boris

> ---
>  drivers/gpu/drm/panfrost/panfrost_drv.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c 
> b/drivers/gpu/drm/panfrost/panfrost_drv.c
> index 23513869500c..0ac8ad18fdc6 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_drv.c
> +++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
> @@ -627,6 +627,7 @@ static int panfrost_probe(struct platform_device *pdev)
>  err_out1:
>   pm_runtime_disable(pfdev->dev);
>   panfrost_device_fini(pfdev);
> + pm_runtime_set_suspended(pfdev->dev);
>  err_out0:
>   drm_dev_put(ddev);
>   return err;
> @@ -641,9 +642,9 @@ static int panfrost_remove(struct platform_device *pdev)
>   panfrost_gem_shrinker_cleanup(ddev);
>  
>   pm_runtime_get_sync(pfdev->dev);
> - panfrost_device_fini(pfdev);
> - pm_runtime_put_sync_suspend(pfdev->dev);
>   pm_runtime_disable(pfdev->dev);
> + panfrost_device_fini(pfdev);
> + pm_runtime_set_suspended(pfdev->dev);
>  
>   drm_dev_put(ddev);
>   return 0;



Re: linux-next: build warning after merge of the drm-misc tree

2020-11-02 Thread Boris Brezillon
Hi Stephen,

On Mon, 2 Nov 2020 12:46:37 +1100
Stephen Rothwell  wrote:

> Hi all,
> 
> After merging the imx-drm tree, today's linux-next build (arm
> multi_v7_defconfig) produced this warning:
> 
> drivers/gpu/drm/panfrost/panfrost_job.c: In function 'panfrost_job_close':
> drivers/gpu/drm/panfrost/panfrost_job.c:617:28: warning: unused variable 'js' 
> [-Wunused-variable]
>   617 |  struct panfrost_job_slot *js = pfdev->js;
>   |^~
> 
> Introduced by commit
> 
>   a17d609e3e21 ("drm/panfrost: Don't corrupt the queue mutex on open/close")
> 

Thanks for this report. I posted a patch [1] to fix that yesterday, and
I plan to apply it soon.

Regards,

Boris

[1]https://patchwork.kernel.org/project/dri-devel/patch/20201101173817.831769-1-boris.brezil...@collabora.com/


Re: [PATCH] drm/panfrost: Don't corrupt the queue mutex on open/close

2020-10-30 Thread Boris Brezillon
On Thu, 29 Oct 2020 17:00:47 +
Steven Price  wrote:

> The mutex within the panfrost_queue_state should have the lifetime of
> the queue, however it was erroneously initialised/destroyed during
> panfrost_job_{open,close} which is called every time a client
> opens/closes the drm node.
> 
> Move the initialisation/destruction to panfrost_job_{init,fini} where it
> belongs.
> 

Queued to drm-misc-next.

Thanks,

Boris

> Fixes: 1a11a88cfd9a ("drm/panfrost: Fix job timeout handling")
> Signed-off-by: Steven Price 
> Reviewed-by: Boris Brezillon 
> ---
>  drivers/gpu/drm/panfrost/panfrost_job.c | 8 +---
>  1 file changed, 5 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/panfrost/panfrost_job.c 
> b/drivers/gpu/drm/panfrost/panfrost_job.c
> index cfb431624eea..145ad37eda6a 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_job.c
> +++ b/drivers/gpu/drm/panfrost/panfrost_job.c
> @@ -595,6 +595,8 @@ int panfrost_job_init(struct panfrost_device *pfdev)
>   }
>  
>   for (j = 0; j < NUM_JOB_SLOTS; j++) {
> + mutex_init(>queue[j].lock);
> +
>   js->queue[j].fence_context = dma_fence_context_alloc(1);
>  
>   ret = drm_sched_init(>queue[j].sched,
> @@ -625,8 +627,10 @@ void panfrost_job_fini(struct panfrost_device *pfdev)
>  
>   job_write(pfdev, JOB_INT_MASK, 0);
>  
> - for (j = 0; j < NUM_JOB_SLOTS; j++)
> + for (j = 0; j < NUM_JOB_SLOTS; j++) {
>   drm_sched_fini(>queue[j].sched);
> + mutex_destroy(>queue[j].lock);
> + }
>  
>  }
>  
> @@ -638,7 +642,6 @@ int panfrost_job_open(struct panfrost_file_priv 
> *panfrost_priv)
>   int ret, i;
>  
>   for (i = 0; i < NUM_JOB_SLOTS; i++) {
> - mutex_init(>queue[i].lock);
>   sched = >queue[i].sched;
>   ret = drm_sched_entity_init(_priv->sched_entity[i],
>   DRM_SCHED_PRIORITY_NORMAL, ,
> @@ -657,7 +660,6 @@ void panfrost_job_close(struct panfrost_file_priv 
> *panfrost_priv)
>  
>   for (i = 0; i < NUM_JOB_SLOTS; i++) {
>   drm_sched_entity_destroy(_priv->sched_entity[i]);
> - mutex_destroy(>queue[i].lock);
>   /* Ensure any timeouts relating to this client have completed */
>   flush_delayed_work(>queue[i].sched.work_tdr);
>   }



Re: [PATCH 2/5] mtd: rawnand: qcom: Add initial support for qspi nand

2020-10-29 Thread Boris Brezillon
Hello,

On Sat, 10 Oct 2020 11:01:39 +0530
Md Sadre Alam  wrote:

> This change will add initial support for qspi (serial nand).
> 
> QPIC Version v.2.0 onwards supports serial nand as well so this
> change will initialize all required register to enable qspi (serial
> nand).
> 
> This change is supporting very basic functionality of qspi nand flash.
> 
> 1. Reset device (Reset QSPI NAND device).
> 
> 2. Device detection (Read id QSPI NAND device).

Unfortunately, that's not going to work in the long term. You're
basically hacking the raw NAND framework to make SPI NANDs fit. I do
understand the rationale behind this decision (re-using the code for
ECC and probably other things), but that's not going to work. So I'd
recommend doing the following instead:

1/ implement a SPI-mem controller driver
2/ implement an ECC engine driver so the ECC logic can be shared
   between the SPI controller and raw NAND controller drivers
3/ convert the raw NAND driver to the exec_op() interface (none of
   this hack would have been possible if the driver was using the new
   API)

Regards,

Boris


Re: [PATCH 0/5] mtd: rawnand: qcom: Add support for QSPI nand

2020-10-29 Thread Boris Brezillon
On Thu, 29 Oct 2020 08:53:44 +0100
Miquel Raynal  wrote:

> Hello,
> 
> mda...@codeaurora.org wrote on Wed, 28 Oct 2020 23:54:23 +0530:
> 
> > On 2020-10-28 15:18, Miquel Raynal wrote:  
> > > Hello,
> > > 
> > > Md Sadre Alam  wrote on Sat, 10 Oct 2020
> > > 11:01:37 +0530:
> > > 
> > >> QPIC 2.0 supports Serial NAND support in addition to all features and
> > >> commands in QPIC 1.0 for parallel NAND. Parallel and Serial NAND >> 
> > >> cannot
> > >> operate simultaneously. QSPI nand devices will connect to QPIC >> 
> > >> IO_MACRO
> > >> block of QPIC controller. There is a separate IO_MACRO clock for >> 
> > >> IO_MACRO
> > >> block. Default IO_MACRO block divide the input clock by 4. so if >> 
> > >> IO_MACRO
> > >> input clock is 320MHz then on bus it will be 80MHz, so QSPI nand >> 
> > >> device
> > >> should also support this frequency.
> > >> >> QPIC provides 4 data pins to QSPI nand. In standard SPI mode (x1 
> > >> >> mode) >> data
> > >> transfer will occur on only 2 pins one pin for Serial data in and one >> 
> > >> for
> > >> serial data out. In QUAD SPI mode (x4 mode) data transfer will occur >> 
> > >> at all
> > >> the four data lines. QPIC controller supports command for x1 mode and >> 
> > >> x4 mode.
> > >> >> Md Sadre Alam (5):
> > >>   dt-bindings: qcom_nandc: IPQ5018 QPIC NAND documentation
> > >>   mtd: rawnand: qcom: Add initial support for qspi nand
> > >>   mtd: rawnand: qcom: Read QPIC version
> > >>   mtd: rawnand: qcom: Enable support for erase,read & write for serial
> > >> nand.
> > >>   mtd: rawnand: qcom: Add support for serial training.
> > >> >>  .../devicetree/bindings/mtd/qcom_nandc.txt |   3 +
> > >>  drivers/mtd/nand/raw/nand_ids.c|  13 +
> > >>  drivers/mtd/nand/raw/qcom_nandc.c  | 502 >> 
> > >> -
> > >>  3 files changed, 494 insertions(+), 24 deletions(-)
> > >> > > I'm sorry but this series clearly breaks the current layering. I 
> > >> > > cannot
> > > authorize SPI-NAND code to fall into the raw NAND subsystem.
> > > 
> > 
> > I am agree with you, we should not add SPI-NAND changes inside
> > raw NAND subsystem.
> >   
> > > As both typologies cannot be used at the same time, I guess you should
> > > have another driver handling this feature under the spi/ subsystem +
> > > a few declarations in the SPI-NAND devices list.
> > > 
> > 
> > Initially I was started writing separate driver under SPI-NAND subsystem 
> > then I
> > realized that more than 85% of raw/qcom_nand.c code getting duplicated.
> > 
> > That's why I have added this SPI-NAND change in raw/qcom_nand.c since
> > more than 85% of code will be reused.
> > 
> > If I will add this change inside SPI-NAND subsystem then much of
> > raw/qcom_nand.c code will get duplicated. Would it be ok ?  
> 
> What about moving the generic code to drivers/mtd/nand/common/ and

Yeah, I don't think drivers/mtd/nand/common/ is the right place to put
this common code TBH, and I don't really see what's to be shared between
the NAND controller and SPI controller drivers. If it's just helpers to
access the registers, those can probably live in
drivers/soc/qcom/qcom_qpic2.c.

> referring to it from drivers/mtd/nand/raw/qcom_nand.c and
> drivers/spi/spi-qcom.c (or such)?
> 
> Thanks,
> Miquèl
> 
> __
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/



[GIT PULL] i3c: Changes for 5.10

2020-10-17 Thread Boris Brezillon
Hello Linus,

I'm a bit late, but here is the I3C PR for 5.10.

Regards,

Boris

The following changes since commit 9123e3a74ec7b934a4a099e98af6a61c2f80bbf5:

  Linux 5.9-rc1 (2020-08-16 13:04:57 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/i3c/linux.git tags/i3c/for-5.10

for you to fetch changes up to abea14bfdebbe9bd02f2ad24a1f3a878ed21c8f0:

  i3c: master: Fix error return in cdns_i3c_master_probe() (2020-10-07 15:14:07 
+0200)


* Fix DAA for the pre-reserved address case
* Fix an error path in the cadence driver


Jing Xiangfeng (1):
  i3c: master: Fix error return in cdns_i3c_master_probe()

Parshuram Thombare (2):
  i3c: master add i3c_master_attach_boardinfo to preserve boardinfo
  i3c: master: fix for SETDASA and DAA process

 drivers/i3c/master.c | 144 
+++--
 drivers/i3c/master/i3c-master-cdns.c |   4 +++-
 2 files changed, 94 insertions(+), 54 deletions(-)


Re: [PATCH] i3c: master: Fix error return in cdns_i3c_master_probe()

2020-10-07 Thread Boris Brezillon
On Fri, 11 Sep 2020 11:33:50 +0800
Jing Xiangfeng  wrote:

> Fix to return negative error code -ENOMEM from the error handling
> case instead of 0.
> 
> Signed-off-by: Jing Xiangfeng 

Queued to i3c/next.

Thanks,

Boris

> ---
>  drivers/i3c/master/i3c-master-cdns.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/i3c/master/i3c-master-cdns.c 
> b/drivers/i3c/master/i3c-master-cdns.c
> index 3fee8bd7fe20..3f2226928fe0 100644
> --- a/drivers/i3c/master/i3c-master-cdns.c
> +++ b/drivers/i3c/master/i3c-master-cdns.c
> @@ -1635,8 +1635,10 @@ static int cdns_i3c_master_probe(struct 
> platform_device *pdev)
>   master->ibi.slots = devm_kcalloc(>dev, master->ibi.num_slots,
>sizeof(*master->ibi.slots),
>GFP_KERNEL);
> - if (!master->ibi.slots)
> + if (!master->ibi.slots) {
> + ret = -ENOMEM;
>   goto err_disable_sysclk;
> + }
>  
>   writel(IBIR_THR(1), master->regs + CMD_IBI_THR_CTRL);
>   writel(MST_INT_IBIR_THR, master->regs + MST_IER);



Re: [PATCH v4 1/2] mtd: spinand: micron: Generalize the function and structure names

2020-09-28 Thread Boris Brezillon
On Mon, 28 Sep 2020 18:21:59 +0200
Miquel Raynal  wrote:

> Hi Boris,
> 
> Boris Brezillon  wrote on Mon, 28 Sep
> 2020 18:03:43 +0200:
> 
> > On Mon, 28 Sep 2020 17:50:05 +0200
> > Miquel Raynal  wrote:
> >   
> > > > > The way OOB
> > > > > bytes are organized do not seem relevant to me, I think i prefer the
> > > > > "_4_/_8_" naming,even if it's not very explicit.
> > > > 
> > > > The ECC strength doesn't say anything about the scheme used for ECC
> > > > bytes placement, and you might end up with 2 different schemes
> > > > providing the same strength, or the same scheme used for 2 different
> > > > strengths.  
> > > 
> > > So perhaps both should be present in the name?
> > 
> > No, the point was to re-use the same functions for various strengths if
> > they use the same ECC placement scheme.  
> 
> I get the point, but is the current implementation generic enough? I
> see hardcoded numbers, I have no idea if these numbers are common to
> all strength given a specific layout, or if they only match for a given
> strength?
> 
> +static int micron_4_ooblayout_ecc(struct mtd_info *mtd, int section,
> +   struct mtd_oob_region *region)
> +{
> + struct spinand_device *spinand = mtd_to_spinand(mtd);
> +
> + if (section >= spinand->base.memorg.pagesize /
> + mtd->ecc_step_size)
> + return -ERANGE;
> +
> + region->offset = (section * 16) + 8;
> + region->length = 8;
> +
> + return 0;
> +}
> 
> If possible, I would like to avoid several successive renaming.

Right, I thought those functions were patched to be generic, but that
doesn't seem to be the case, so I guess sticking to __ makes
sense for now.


Re: [PATCH v4 1/2] mtd: spinand: micron: Generalize the function and structure names

2020-09-28 Thread Boris Brezillon
On Mon, 28 Sep 2020 17:50:05 +0200
Miquel Raynal  wrote:

> > > The way OOB
> > > bytes are organized do not seem relevant to me, I think i prefer the
> > > "_4_/_8_" naming,even if it's not very explicit.
> > 
> > The ECC strength doesn't say anything about the scheme used for ECC
> > bytes placement, and you might end up with 2 different schemes
> > providing the same strength, or the same scheme used for 2 different
> > strengths.  
> 
> So perhaps both should be present in the name?

No, the point was to re-use the same functions for various strengths if
they use the same ECC placement scheme.


Re: [PATCH v4 1/2] mtd: spinand: micron: Generalize the function and structure names

2020-09-28 Thread Boris Brezillon
On Mon, 28 Sep 2020 16:55:28 +0200
Miquel Raynal  wrote:

> > IMHO, grouped means, ecc bytes are at continuous address, where as
> > interleaved means ecc bytes splitted into multiple addresses  
> 
> I don't like the name. Interleaved means that there are OOB bytes
> stored in the data section, which is not the case here.

Well, I would argue that the term interleaved alone doesn't say
anything about the things that are interleaved. But I guess
split/grouped would be fine too if you want to avoid re-using
interleaved here.

> The way OOB
> bytes are organized do not seem relevant to me, I think i prefer the
> "_4_/_8_" naming,even if it's not very explicit.

The ECC strength doesn't say anything about the scheme used for ECC
bytes placement, and you might end up with 2 different schemes
providing the same strength, or the same scheme used for 2 different
strengths.


Re: [PATCH v5] i3c: master: fix for SETDASA and DAA process

2020-09-14 Thread Boris Brezillon
On Tue, 25 Aug 2020 08:31:49 +0200
Parshuram Thombare  wrote:

> This patch fix following issue.
> Controller slots blocked for devices with static_addr
> but no init_dyn_addr may limit the number of I3C devices
> on the bus which gets dynamic address in DAA. So
> instead of attaching all the devices with static_addr,
> now we only attach the devices which successfully
> complete SETDASA. For remaining devices with init_dyn_addr,
> i3c_master_add_i3c_dev_locked() will try to set requested
> dynamic address after DAA.

Queued to i3c/next.

Thanks,

Boris


Re: [RESEND PATCH v3 7/8] mtd: spi-nor: Convert cadence-quadspi to use spi-mem framework

2020-08-24 Thread Boris Brezillon
On Mon, 24 Aug 2020 17:14:56 +0530
Vignesh Raghavendra  wrote:

> Hi Jan,
> 
> On 8/24/20 11:25 AM, Jan Kiszka wrote:
> [...]
> 
> >> +MODULE_AUTHOR("Vignesh Raghavendra ");
> >>  
> > On the AM65x, this changes mtd->name (thus mtd-id for
> > parser/cmdlinepart) from 4704.spi.0 to spi7.0. The besides having to
> > deal with both names now, "spi7" sounds like it could easily change
> > again if someone plugs or unplugs some other SPI device. Is this intended?
> >   
> 
> You could use DT aliases to make sure OSPI0 is always at given bus num
> (say spi7):
> 
> aliases {
> spi7 = 
> };

FWIW, we've added the ->get_name() method [1][2] to avoid such
regressions.

[1]https://elixir.bootlin.com/linux/latest/source/include/linux/spi/spi-mem.h#L218
[2]https://elixir.bootlin.com/linux/latest/source/drivers/spi/spi-fsl-qspi.c#L810


Re: [PATCH v2] mtd: spinand: micron: add support for MT29F2G01AAAED

2020-08-23 Thread Boris Brezillon
On Sun, 23 Aug 2020 19:14:10 +0800
Thirumalesha Narasimhappa  wrote:

> The MT29F2G01AAAED is a single die, 2Gb Micron SPI NAND Flash with 4-bit
> ECC
> 
> Signed-off-by: Thirumalesha Narasimhappa 
> ---
>  v2: removed SPINAND_SELECT_TARGET as per the comments & fixed typo errors
> 
>  drivers/mtd/nand/spi/micron.c | 78 +++
>  1 file changed, 78 insertions(+)
> 
> diff --git a/drivers/mtd/nand/spi/micron.c b/drivers/mtd/nand/spi/micron.c
> index 5d370cfcdaaa..c21ca395d657 100644
> --- a/drivers/mtd/nand/spi/micron.c
> +++ b/drivers/mtd/nand/spi/micron.c
> @@ -18,6 +18,9 @@
>  #define MICRON_STATUS_ECC_4TO6_BITFLIPS  (3 << 4)
>  #define MICRON_STATUS_ECC_7TO8_BITFLIPS  (5 << 4)
>  
> +/* For Micron MT29F2G01AAAED Device */
> +#define MICRON_STATUS_ECC_1TO4_BITFLIPS  (1 << 4)
> +

You shouldn't need that new definition (see below).

>  #define MICRON_CFG_CRBIT(0)
>  
>  /*
> @@ -44,6 +47,19 @@ static SPINAND_OP_VARIANTS(update_cache_variants,
>   SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
>   SPINAND_PROG_LOAD(false, 0, NULL, 0));
>  
> +/* Micron  MT29F2G01AAAED Device */
> +static SPINAND_OP_VARIANTS(read_cache_variants_mt29f2g01aaaed,
> + SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
> + SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
> + SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
> + SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
> +
> +static SPINAND_OP_VARIANTS(write_cache_variants_mt29f2g01aaaed,
> + SPINAND_PROG_LOAD(true, 0, NULL, 0));
> +
> +static SPINAND_OP_VARIANTS(update_cache_variants_mt29f2g01aaaed,
> + SPINAND_PROG_LOAD(false, 0, NULL, 0));
> +

Okay, I'd suggest picking more generic names. How about renaming the
existing variants into quadio_read_cache_variants,
x4_write_cache_variants and x4_update_cache_variants and naming the new
ones x4_read_cache_variants, x1_write_cache_variants and
x1_update_cache_variants.

>  static int micron_8_ooblayout_ecc(struct mtd_info *mtd, int section,
> struct mtd_oob_region *region)
>  {
> @@ -69,11 +85,41 @@ static int micron_8_ooblayout_free(struct mtd_info *mtd, 
> int section,
>   return 0;
>  }
>  
> +static int mt29f2g01aaaed_ooblayout_ecc(struct mtd_info *mtd, int section,
> + struct mtd_oob_region *region)
> +{
> + if (section >= 4)
> + return -ERANGE;

Hm, I'd try to deduce the max section based on the
pagesize/ecc-step-size so we can re-use the same ooblayout def for different
pagesize/ecc-step-size combinations.

> +
> + region->offset = (section * 16) + 8;
> + region->length = 8;
> +
> + return 0;
> +}
> +
> +static int mt29f2g01aaaed_ooblayout_free(struct mtd_info *mtd, int section,
> +  struct mtd_oob_region *region)
> +{
> + if (section >= 4)
> + return -ERANGE;
> +
> + /* Reserve 2 bytes for the BBM. */
> + region->offset = (section * 16) + 2;

You should probably only reserve those 2 bytes in section 0 (where the
BBM is).

> + region->length = 6;
> +
> + return 0;
> +}
> +
>  static const struct mtd_ooblayout_ops micron_8_ooblayout = {
>   .ecc = micron_8_ooblayout_ecc,
>   .free = micron_8_ooblayout_free,
>  };
>  
> +static const struct mtd_ooblayout_ops mt29f2g01aaaed_ooblayout = {

Maybe name that one micron_interleaved_ooblayout, and rename
micron_8_ooblayout into micron_grouped_ooblayout.

> + .ecc = mt29f2g01aaaed_ooblayout_ecc,
> + .free = mt29f2g01aaaed_ooblayout_free,
> +};
> +
>  static int micron_select_target(struct spinand_device *spinand,
>   unsigned int target)
>  {
> @@ -114,6 +160,27 @@ static int micron_8_ecc_get_status(struct spinand_device 
> *spinand,
>   return -EINVAL;
>  }
>  
> +static int mt29f2g01aaaed_ecc_get_status(struct spinand_device *spinand,
> +  u8 status)
> +{
> + switch (status & MICRON_STATUS_ECC_MASK) {
> + case STATUS_ECC_NO_BITFLIPS:
> + return 0;
> +
> + case STATUS_ECC_UNCOR_ERROR:
> + return -EBADMSG;
> +
> + /* 1 to 4-bit error detected and corrected */
> + case MICRON_STATUS_ECC_1TO4_BITFLIPS:
> + return 4;
> +
> + default:
> + break;
> + }
> +
> + return -EINVAL;
> +}

Looks like you're duplicating spinand_check_ecc_status(). Just leave the
get_status hook to NULL, that should do trick.


Re: [PATCH v4] i3c: master: fix for SETDASA and DAA process

2020-08-23 Thread Boris Brezillon
On Sun, 23 Aug 2020 11:59:18 +0200
Boris Brezillon  wrote:


> > -static void i3c_master_pre_assign_dyn_addr(struct i3c_dev_desc *dev)
> > +static int i3c_master_early_i3c_dev_add(struct i3c_master_controller 
> > *master,
> > + struct i3c_dev_boardinfo *boardinfo)
> >  {
> > -   struct i3c_master_controller *master = i3c_dev_get_master(dev);
> > +   struct i3c_device_info info = {
> > +   .static_addr = boardinfo->static_addr,
> > +   };
> > +   struct i3c_dev_desc *i3cdev;
> > int ret;
> >  
> > -   if (!dev->boardinfo || !dev->boardinfo->init_dyn_addr ||
> > -   !dev->boardinfo->static_addr)
> > -   return;
> > +   i3cdev = i3c_master_alloc_i3c_dev(master, );
> > +   if (IS_ERR(i3cdev))
> > +   return -ENOMEM;
> >  
> > -   ret = i3c_master_setdasa_locked(master, dev->info.static_addr,
> > -   dev->boardinfo->init_dyn_addr);
> > +   i3cdev->boardinfo = boardinfo;
> > +
> > +   ret = i3c_master_attach_i3c_dev(master, i3cdev);
> > if (ret)
> > -   return;
> > +   goto err_attach;
> > +
> > +   ret = i3c_master_setdasa_locked(master, i3cdev->info.static_addr,
> > +   i3cdev->boardinfo->init_dyn_addr);
> > +   if (ret)
> > +   goto err_setdasa;
> >  
> > -   dev->info.dyn_addr = dev->boardinfo->init_dyn_addr;
> > -   ret = i3c_master_reattach_i3c_dev(dev, 0);
> > +   i3cdev->info.dyn_addr = i3cdev->boardinfo->init_dyn_addr;
> > +   ret = i3c_master_reattach_i3c_dev(i3cdev, 0);
> > if (ret)
> > goto err_rstdaa;
> >  
> > -   ret = i3c_master_retrieve_dev_info(dev);
> > +   ret = i3c_master_retrieve_dev_info(i3cdev);
> > if (ret)
> > goto err_rstdaa;
> >  
> > -   return;
> > +   return 0;
> >  
> >  err_rstdaa:
> > -   i3c_master_rstdaa_locked(master, dev->boardinfo->init_dyn_addr);
> > +   i3c_master_rstdaa_locked(master, i3cdev->boardinfo->init_dyn_addr);
> > +err_setdasa:

Let's be consistent with the rest of the framework. Labels don't encode
what the error is but what's expected to be undone. IOW, this one
should be err_detach_dev

> > +   i3c_master_detach_i3c_dev(i3cdev);
> > +err_attach:

and this one err_free_dev.

> > +   i3c_master_free_i3c_dev(i3cdev);
> > +
> > +   return ret;
> >  }
> >  
> >  static void
> > @@ -1619,8 +1637,8 @@ static void i3c_master_detach_free_devs(struct 
> > i3c_master_controller *master)
> >   * This function is following all initialisation steps described in the I3C
> >   * specification:
> >   *
> > - * 1. Attach I2C and statically defined I3C devs to the master so that the
> > - *master can fill its internal device table appropriately
> > + * 1. Attach I2C devs to the master so that the master can fill its 
> > internal
> > + *device table appropriately
> >   *
> >   * 2. Call _master_controller_ops->bus_init() method to initialize
> >   *the master controller. That's usually where the bus mode is selected
> > @@ -1633,10 +1651,14 @@ static void i3c_master_detach_free_devs(struct 
> > i3c_master_controller *master)
> >   * 4. Disable all slave events.
> >   *
> >   * 5. Pre-assign dynamic addresses requested by the FW with SETDASA for I3C
> > - *devices that have a static address
> > + *devices that have a static address and attach corresponding 
> > statically
> > + *defined I3C devices to the master. If only init_dyn_addr is available
> > + *or if SETDASA fails, reserve those init_dyn_addr to be used later to 
> > set
> > + *address using SETNEWDA after DAA.

I'd re-order this to match what really happens: first reserve slots for
devices that have an init_dyn_addr defined, then try to create+attach
devices that also have a static address defined.

> >   *
> >   * 6. Do a DAA (Dynamic Address Assignment) to assign dynamic addresses to 
> > all
> > - *remaining I3C devices
> > + *remaining I3C devices and attach them to the master if the dynamic 
> > address
> > + *assignment succeeds

Can we move that change to a separate patch?

> >   *
> >   * Once this is done, all I3C and I2C devices should be usable.
> >   *
> > @@ -1647,7 +1669,6 @@ static int i3c_master_bus_init(struct 
> > i3c_master_controller *master)
> > enum i3c_addr_slot_status status;
> > struct i2c_dev_b

Re: [PATCH v4] i3c: master: fix for SETDASA and DAA process

2020-08-23 Thread Boris Brezillon
On Fri, 21 Aug 2020 11:13:15 +0200
Parshuram Thombare  wrote:

> This patch fix following issue.
> Controller slots blocked for devices with static_addr
> but no init_dyn_addr may limit the number of I3C devices
> on the bus which gets dynamic address in DAA. So
> instead of attaching all the devices with static_addr,
> now we only attach the devices which successfully
> complete SETDASA. For remaining devices with init_dyn_addr,
> i3c_master_add_i3c_dev_locked() will try to set requested
> dynamic address after DAA.
> 
> Signed-off-by: Parshuram Thombare 
> ---
> Changes between v3 and v4 are:
> 1. Code rectoring and removed Fixes tag
> 
> Changes between v2 and v3 are:
> 1. Keeping init_dyn_addr reserved.
> 2. Code refactoring and changes in comments.
> 
> Changes between v1 and v2 are:
> 1. Added boardinfo attach fix.
> 2. Removed reattach issue related fix.
> 3. Reserve init_dyn_addr initially, so that it will not
>be used in DAA and  attempt can be made to set those
>firmware requested dynamic address after DAA.
> ---
>  drivers/i3c/master.c |  116 -
>  1 files changed, 66 insertions(+), 50 deletions(-)
> 
> diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
> index 3d995f2..3ff95e4 100644
> --- a/drivers/i3c/master.c
> +++ b/drivers/i3c/master.c
> @@ -1367,7 +1367,9 @@ static int i3c_master_reattach_i3c_dev(struct 
> i3c_dev_desc *dev,
>   enum i3c_addr_slot_status status;
>   int ret;
>  
> - if (dev->info.dyn_addr != old_dyn_addr) {
> + if (dev->info.dyn_addr != old_dyn_addr &&
> + (!dev->boardinfo ||
> +  dev->info.dyn_addr != dev->boardinfo->init_dyn_addr)) {
>   status = i3c_bus_get_addr_slot_status(>bus,
> dev->info.dyn_addr);
>   if (status != I3C_ADDR_SLOT_FREE)
> @@ -1426,33 +1428,49 @@ static void i3c_master_detach_i2c_dev(struct 
> i2c_dev_desc *dev)
>   master->ops->detach_i2c_dev(dev);
>  }
>  
> -static void i3c_master_pre_assign_dyn_addr(struct i3c_dev_desc *dev)
> +static int i3c_master_early_i3c_dev_add(struct i3c_master_controller *master,
> +   struct i3c_dev_boardinfo *boardinfo)
>  {
> - struct i3c_master_controller *master = i3c_dev_get_master(dev);
> + struct i3c_device_info info = {
> + .static_addr = boardinfo->static_addr,
> + };
> + struct i3c_dev_desc *i3cdev;
>   int ret;
>  
> - if (!dev->boardinfo || !dev->boardinfo->init_dyn_addr ||
> - !dev->boardinfo->static_addr)
> - return;
> + i3cdev = i3c_master_alloc_i3c_dev(master, );
> + if (IS_ERR(i3cdev))
> + return -ENOMEM;
>  
> - ret = i3c_master_setdasa_locked(master, dev->info.static_addr,
> - dev->boardinfo->init_dyn_addr);
> + i3cdev->boardinfo = boardinfo;
> +
> + ret = i3c_master_attach_i3c_dev(master, i3cdev);
>   if (ret)
> - return;
> + goto err_attach;
> +
> + ret = i3c_master_setdasa_locked(master, i3cdev->info.static_addr,
> + i3cdev->boardinfo->init_dyn_addr);
> + if (ret)
> + goto err_setdasa;
>  
> - dev->info.dyn_addr = dev->boardinfo->init_dyn_addr;
> - ret = i3c_master_reattach_i3c_dev(dev, 0);
> + i3cdev->info.dyn_addr = i3cdev->boardinfo->init_dyn_addr;
> + ret = i3c_master_reattach_i3c_dev(i3cdev, 0);
>   if (ret)
>   goto err_rstdaa;
>  
> - ret = i3c_master_retrieve_dev_info(dev);
> + ret = i3c_master_retrieve_dev_info(i3cdev);
>   if (ret)
>   goto err_rstdaa;
>  
> - return;
> + return 0;
>  
>  err_rstdaa:
> - i3c_master_rstdaa_locked(master, dev->boardinfo->init_dyn_addr);
> + i3c_master_rstdaa_locked(master, i3cdev->boardinfo->init_dyn_addr);
> +err_setdasa:
> + i3c_master_detach_i3c_dev(i3cdev);
> +err_attach:
> + i3c_master_free_i3c_dev(i3cdev);
> +
> + return ret;
>  }
>  
>  static void
> @@ -1619,8 +1637,8 @@ static void i3c_master_detach_free_devs(struct 
> i3c_master_controller *master)
>   * This function is following all initialisation steps described in the I3C
>   * specification:
>   *
> - * 1. Attach I2C and statically defined I3C devs to the master so that the
> - *master can fill its internal device table appropriately
> + * 1. Attach I2C devs to the master so that the master can fill its internal
> + *device table appropriately
>   *
>   * 2. Call _master_controller_ops->bus_init() method to initialize
>   *the master controller. That's usually where the bus mode is selected
> @@ -1633,10 +1651,14 @@ static void i3c_master_detach_free_devs(struct 
> i3c_master_controller *master)
>   * 4. Disable all slave events.
>   *
>   * 5. Pre-assign dynamic addresses requested by the FW with SETDASA for I3C
> - *devices that have a static address
> + *devices that 

Re: [PATCH v3] i3c: master: fix for SETDASA and DAA process

2020-08-20 Thread Boris Brezillon
On Thu, 20 Aug 2020 21:03:11 +0200
Boris Brezillon  wrote:

> On Thu, 20 Aug 2020 18:16:14 +
> Parshuram Raju Thombare  wrote:
> 
> > >Hm, not sure that qualifies as a fix. The current implementation was
> > >correct, it was just reserving a slot in the device table for devices
> > >that didn't have an init address or on which SETDASA failed.
> > If I3C controllers like ours use hardware slots to store slave devices 
> > info, 
> > due to limited available slots this can cause issue. 
> >  If some slots are lost due to
> > 1. only init_dyn_addr and no static_addr in DT 
> > OR
> > 2. SETDASA failed  
> 
> Well, having a slot with a static address is valid, though I agree
> it's not really useful.
> 
> > at the end of DAA some devices may be left without dyn_addr allocated from 
> > master
> > and hence can't work properly.  
> 
> My point is, there's no address or device slot leak, it's just that
> reserving a slot for I3C devices that only have a static address is
> kind of useless. But let's be honest, given the number of I3C devices
> available out there, I don't think it will hurt us before quite some
> time :P. That's not to say we shouldn't address that, I just don't
> think it deserves a Fixes tag.
> 
> > I think during our discussion we recognized this change as a bug.  
> 
> IIRC, I was talking about the first patch in the series.
> 
> > That is the reason I added fixes tag, but if you think otherwise I can 
> > remove this tag.
> >
> > >> -static void i3c_master_pre_assign_dyn_addr(struct i3c_dev_desc *dev)
> > >> +static int i3c_master_pre_assign_dyn_addr(struct i3c_master_controller  
> > >>   
> > >That function now does more than just assigning a dynamic address: it
> > >also creates the i3c_dev_desc. It should be renamed accordingly
> > >(i3c_master_early_i3c_dev_add() maybe).
> > Ok
> >   
> > >You should reserve the address before calling
> > >i3c_master_pre_assign_dyn_addr():
> > >
> > >   /*
> > >* We don't attach devices which are not addressable
> > >* (no static_addr and dyn_addr) and devices with
> > >* static_addr but no init_dyn_addr will participate in DAA.
> > >*/
> > >   if (!i3cboardinfo->init_dyn_addr ||
> > >   !i3cboardinfo->static_addr)
> > >   continue;
> > Don't we want to cover the case when only init_dyn_addr is present ?  
> 
> Uh, yes, my bad.
> 
> > I am not sure if we can't have init_dyn_addr without static_addr.  
> 
> You can, when you want to assign a specific dynamic address to a device
> that doesn't have a static address (see the 'try to assign init_addr
> dance' in i3c_dev_add()).
> 
> > May be what we need is 
> > if (!i3cboardinfo->init_dyn_addr)
> > continue;
> > 
> > ret = i3c_bus_get_addr_slot_status(>bus,
> >i3cboardinfo->init_dyn_addr);
> > if (ret != I3C_ADDR_SLOT_FREE) {
> > ret = -EBUSY;
> > goto err_rstdaa;
> > }
> > 
> > i3c_bus_set_addr_slot_status(>bus,
> >  i3cboardinfo->init_dyn_addr,
> >  I3C_ADDR_SLOT_I3C_DEV);
> > 
> > if (i3cboardinfo->static_addr)
> > i3c_master_pre_assign_dyn_addr(master, i3cboardinfo);  
> 
> Yep, that's correct.
> 
> > IMHO this is functionally same to what I sent. Just that init_dyn_addr is 
> > reserved before,
> > and we leverage the change in reattach to bypass failure due to second 
> > attempt
> > to get init_dyn_addr in reattach called from 
> > i3c_master_pre_assign_dyn_addr().  
> 
> Unless I'm missing something, your solution didn't reserve the
> init address when there's no static address, and we definitely want
> that to happen, otherwise another device might steal it during DAA.

My bad, it did. This being said, I find it much easier to follow when
the reservation happens in one place, so I'm still in favor of the new
version.


Re: [PATCH v3] i3c: master: fix for SETDASA and DAA process

2020-08-20 Thread Boris Brezillon
On Thu, 20 Aug 2020 18:16:14 +
Parshuram Raju Thombare  wrote:

> >Hm, not sure that qualifies as a fix. The current implementation was
> >correct, it was just reserving a slot in the device table for devices
> >that didn't have an init address or on which SETDASA failed.  
> If I3C controllers like ours use hardware slots to store slave devices info, 
> due to limited available slots this can cause issue. 
>  If some slots are lost due to
> 1. only init_dyn_addr and no static_addr in DT 
> OR
> 2. SETDASA failed

Well, having a slot with a static address is valid, though I agree
it's not really useful.

> at the end of DAA some devices may be left without dyn_addr allocated from 
> master
> and hence can't work properly.

My point is, there's no address or device slot leak, it's just that
reserving a slot for I3C devices that only have a static address is
kind of useless. But let's be honest, given the number of I3C devices
available out there, I don't think it will hurt us before quite some
time :P. That's not to say we shouldn't address that, I just don't
think it deserves a Fixes tag.

> I think during our discussion we recognized this change as a bug.

IIRC, I was talking about the first patch in the series.

> That is the reason I added fixes tag, but if you think otherwise I can remove 
> this tag.
>  
> >> -static void i3c_master_pre_assign_dyn_addr(struct i3c_dev_desc *dev)
> >> +static int i3c_master_pre_assign_dyn_addr(struct i3c_master_controller  
> >That function now does more than just assigning a dynamic address: it
> >also creates the i3c_dev_desc. It should be renamed accordingly
> >(i3c_master_early_i3c_dev_add() maybe).  
> Ok
> 
> >You should reserve the address before calling
> >i3c_master_pre_assign_dyn_addr():
> >
> > /*
> >  * We don't attach devices which are not addressable
> >  * (no static_addr and dyn_addr) and devices with
> >  * static_addr but no init_dyn_addr will participate in DAA.
> >  */
> > if (!i3cboardinfo->init_dyn_addr ||
> > !i3cboardinfo->static_addr)
> > continue;  
> Don't we want to cover the case when only init_dyn_addr is present ?

Uh, yes, my bad.

> I am not sure if we can't have init_dyn_addr without static_addr.

You can, when you want to assign a specific dynamic address to a device
that doesn't have a static address (see the 'try to assign init_addr
dance' in i3c_dev_add()).

> May be what we need is 
>   if (!i3cboardinfo->init_dyn_addr)
>   continue;
> 
>   ret = i3c_bus_get_addr_slot_status(>bus,
>  i3cboardinfo->init_dyn_addr);
>   if (ret != I3C_ADDR_SLOT_FREE) {
>   ret = -EBUSY;
>   goto err_rstdaa;
>   }
> 
>   i3c_bus_set_addr_slot_status(>bus,
>i3cboardinfo->init_dyn_addr,
>I3C_ADDR_SLOT_I3C_DEV);
> 
>   if (i3cboardinfo->static_addr)
>   i3c_master_pre_assign_dyn_addr(master, i3cboardinfo);

Yep, that's correct.

> IMHO this is functionally same to what I sent. Just that init_dyn_addr is 
> reserved before,
> and we leverage the change in reattach to bypass failure due to second attempt
> to get init_dyn_addr in reattach called from i3c_master_pre_assign_dyn_addr().

Unless I'm missing something, your solution didn't reserve the
init address when there's no static address, and we definitely want
that to happen, otherwise another device might steal it during DAA.


Re: [PATCH v3] i3c: master: fix for SETDASA and DAA process

2020-08-20 Thread Boris Brezillon
On Thu, 20 Aug 2020 15:38:26 +0200
Parshuram Thombare  wrote:

> This patch fix following issue.
> Controller slots blocked for devices with static_addr
> but no init_dyn_addr may limit the number of I3C devices
> on the bus which gets dynamic address in DAA. So
> instead of attaching all the devices with static_addr,
> now we only attach the devices which successfully
> complete SETDASA. For remaining devices with init_dyn_addr,
> i3c_master_add_i3c_dev_locked() will try to set requested
> dynamic address after DAA.
> 
> Fixes: 3a379bbcea0a ("i3c: Add core I3C infrastructure")

Hm, not sure that qualifies as a fix. The current implementation was
correct, it was just reserving a slot in the device table for devices
that didn't have an init address or on which SETDASA failed.

> Signed-off-by: Parshuram Thombare 
> ---
> Changes between v2 and v3 are:
> 1. Keeping init_dyn_addr reserved.
> 2. Code refactoring and changes in comments.
> 
> Changes between v1 and v2 are:
> 1. Added boardinfo attach fix.
> 2. Removed reattach issue related fix.
> 3. Reserve init_dyn_addr initially, so that it will not
>be used in DAA and  attempt can be made to set those
>firmware requested dynamic address after DAA.
> ---
>  drivers/i3c/master.c |  115 
> --
>  1 files changed, 65 insertions(+), 50 deletions(-)
> 
> diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
> index 3d995f2..24543d8 100644
> --- a/drivers/i3c/master.c
> +++ b/drivers/i3c/master.c
> @@ -1367,7 +1367,9 @@ static int i3c_master_reattach_i3c_dev(struct 
> i3c_dev_desc *dev,
>   enum i3c_addr_slot_status status;
>   int ret;
>  
> - if (dev->info.dyn_addr != old_dyn_addr) {
> + if (dev->info.dyn_addr != old_dyn_addr &&
> + (!dev->boardinfo ||
> +  dev->info.dyn_addr != dev->boardinfo->init_dyn_addr)) {
>   status = i3c_bus_get_addr_slot_status(>bus,
> dev->info.dyn_addr);
>   if (status != I3C_ADDR_SLOT_FREE)
> @@ -1426,33 +1428,49 @@ static void i3c_master_detach_i2c_dev(struct 
> i2c_dev_desc *dev)
>   master->ops->detach_i2c_dev(dev);
>  }
>  
> -static void i3c_master_pre_assign_dyn_addr(struct i3c_dev_desc *dev)
> +static int i3c_master_pre_assign_dyn_addr(struct i3c_master_controller 
> *master,
> +   struct i3c_dev_boardinfo *boardinfo)

That function now does more than just assigning a dynamic address: it
also creates the i3c_dev_desc. It should be renamed accordingly
(i3c_master_early_i3c_dev_add() maybe).

>  {
> - struct i3c_master_controller *master = i3c_dev_get_master(dev);
> + struct i3c_device_info info = {
> + .static_addr = boardinfo->static_addr,
> + };
> + struct i3c_dev_desc *i3cdev;
>   int ret;
>  
> - if (!dev->boardinfo || !dev->boardinfo->init_dyn_addr ||
> - !dev->boardinfo->static_addr)
> - return;
> + i3cdev = i3c_master_alloc_i3c_dev(master, );
> + if (IS_ERR(i3cdev))
> + return -ENOMEM;
> +
> + i3cdev->boardinfo = boardinfo;
>  
> - ret = i3c_master_setdasa_locked(master, dev->info.static_addr,
> - dev->boardinfo->init_dyn_addr);
> + ret = i3c_master_attach_i3c_dev(master, i3cdev);
>   if (ret)
> - return;
> + goto err_attach;
> +
> + ret = i3c_master_setdasa_locked(master, i3cdev->info.static_addr,
> + i3cdev->boardinfo->init_dyn_addr);
> + if (ret)
> + goto err_setdasa;
>  
> - dev->info.dyn_addr = dev->boardinfo->init_dyn_addr;
> - ret = i3c_master_reattach_i3c_dev(dev, 0);
> + i3cdev->info.dyn_addr = i3cdev->boardinfo->init_dyn_addr;
> + ret = i3c_master_reattach_i3c_dev(i3cdev, 0);
>   if (ret)
>   goto err_rstdaa;
>  
> - ret = i3c_master_retrieve_dev_info(dev);
> + ret = i3c_master_retrieve_dev_info(i3cdev);
>   if (ret)
>   goto err_rstdaa;
>  
> - return;
> + return 0;
>  
>  err_rstdaa:
> - i3c_master_rstdaa_locked(master, dev->boardinfo->init_dyn_addr);
> + i3c_master_rstdaa_locked(master, i3cdev->boardinfo->init_dyn_addr);
> +err_setdasa:
> + i3c_master_detach_i3c_dev(i3cdev);
> +err_attach:
> + i3c_master_free_i3c_dev(i3cdev);
> +
> + return ret;
>  }
>  
>  static void
> @@ -1619,8 +1637,8 @@ static void i3c_master_detach_free_devs(struct 
> i3c_master_controller *master)
>   * This function is following all initialisation steps described in the I3C
>   * specification:
>   *
> - * 1. Attach I2C and statically defined I3C devs to the master so that the
> - *master can fill its internal device table appropriately
> + * 1. Attach I2C devs to the master so that the master can fill its internal
> + *device table appropriately
>   *
>   * 2. Call _master_controller_ops->bus_init() method to initialize
>   *  

Re: [PATCH v2 2/2] i3c: master: fix for SETDASA and DAA process

2020-08-20 Thread Boris Brezillon
On Thu, 20 Aug 2020 09:23:25 +
Parshuram Raju Thombare  wrote:

> Hi Boris,
> 
> Thanks for your comments.
> 
> >> +   * We anyway don't attach devices which are not addressable  
> >
> >You can drop the anyway.  
> Sure, I will make above mentioned change in the comment.
> 
> >> +   * (no static_addr and dyn_addr) and devices with static_addr
> >> +   * but no init_dyn_addr will participate in DAA.
> >> +   */
> >> +  if (!boardinfo->static_addr || !boardinfo->init_dyn_addr)
> >> +  return -EINVAL;  
> >
> >If we consider this as an error, we should probably check that before
> >calling i3c_master_pre_assign_dyn_addr() in i3c_master_bus_init().  
> Ok, I will move this check to i3c_master_bus_init(), before calling
> i3c_master_pre_assign_dyn_addr. It will probably add extra if condition,
> but will save one function call.
> 
> >>   * 5. Pre-assign dynamic addresses requested by the FW with SETDASA for 
> >> I3C
> >> - *devices that have a static address
> >> + *devices that have a static address and attach corresponding 
> >> statically
> >> + *defined I3C devices to the master.  
> >
> >  and attach them to the
> >  master if
> >   the dynamic address assignment succeeds  
> Sure, I will append above mentioned change to the comment.
> 
> >> +  /*
> >> +   * Free reserved init_dyn_addr so that attach can
> >> +   * get it before trying setnewda.
> >> +   */
> >> +  if (i3cboardinfo->init_dyn_addr)
> >> +  i3c_bus_set_addr_slot_status(>bus,
> >> +   init_dyn_addr,
> >> +   I3C_ADDR_SLOT_FREE);  
> >
> >Hm, it's a bit more complicated. I don't think we can unconditionally
> >release the init_dyn_addr here. Say you have a device that's been
> >assigned its init_dyn_addr, and userspace decided to re-assign a new
> >one (the feature is not available yet, but I thought about letting
> >userspace write to the dyn_addr sysfs entry and wire that to a SETDA).
> >The init_dyn_addr can now be re-assigned to a different device. After
> >some time the device ends up resetting and thus lose its DA. A new DAA
> >is issued to re-discover it, but you want this device to be assigned its
> >last known address not the init address. And when
> >i3c_master_attach_boardinfo() is called on this new device, you release
> >a slot that's no longer yours.
> >
> >That was the rational behind the "address slots are attached to i3cdevs
> >not boardinfo". Maybe we should have another list where we keep i3c
> >devs that have not been discovered yet but have boardinfo attached to
> >them. This way we can reserve dynamic addresses without blocking a
> >slot in the master device table.  
> 
> I think the sequence of events you are discussing here is
> 1. User assign address to device A with init_dyn_addr in boardinfo.
> 2. That particular init_dyn_addr is assigned to device B, which may be 
> hotplugged ?
> and don't have boardinfo or init_dyn_addr in boardinfo ? 
> 3. Device A resets and trigger DAA due to hot plug ?
>A. Here now init_dyn_addr is already assigned to device B so device A 
> shouldn't be freeing it.
>B. Now preferable dyn_addr is the one received from user in step 1.

No, that's not what I'm talking about. I meant:

1. Device A is assigned a default init address X in the DT.
2. Device B has no init address
3. The framework reserves address X for and assigns it to device A
   when it appears on the bus (DAA, SETDASA or HJ+DDA)
4. Device B is assigned address Y
5. User decides to explicitly assign a different address to device A by
   issuing "echo Z > /sys/bus/i3c///dyn_addr" (not yet
   supported, but I think we should allow that at some point), such
   that device A gets a lower/higher priority
6. User manually assigns address X to device B (that should be allowed
   since device A no longer uses X)
7. Device A is reset for some reason and loses its dynamic address,
   thus requiring a new DAA (or HJ+DAA). During this new discovery,
   device A is re-assigned its last known address (Z), but in the
   meantime you've marked address X as free (when attaching boardinfo
   to the newdev object).

> 
> If we are to prefer init_dyn_addr always, that will rule out possibility of 
> making init_dyn_addr 
> available to any other device when original device is assigned with user or 
> master
> provided address owing to SETDATA or SETNEWDA failures. And we can be sure of 
> not freeing
> init_dyn_addr inadvertently while it is being used by any other device.
> 
> Else if we want to prefer user provided address even across resets, since we 
> don't need init_dyn_addr
> anymore, it can be used to store user provided address. This will serve both 
> the purposes A and B stated above.
>  
> And in my opinion this can be handled when we add code to allow user to 
> change 

Re: [PATCH v2 3/4] i3c: master: svc: Add Silvaco I3C master driver

2020-08-19 Thread Boris Brezillon
On Wed, 12 Aug 2020 16:13:11 +0200
Miquel Raynal  wrote:


> +
> +#define SVC_I3C_MAX_DEVS 32
> +
> +struct svc_i3c_cmd {
> + u8 addr;
> + bool rnw;
> + u8 *in;
> + const void *out;
> + unsigned int len;
> + unsigned int read_len;
> + bool continued;
> +};
> +
> +struct svc_i3c_xfer {
> + struct list_head node;
> + struct completion comp;
> + int ret;
> + unsigned int type;
> + unsigned int ncmds;
> + struct svc_i3c_cmd cmds[];
> +};
> +
> +/**
> + * struct svc_i3c_master - Silvaco I3C Master structure
> + * @base: I3C master controller
> + * @dev: Corresponding device
> + * @regs: Memory mapping
> + * @free_slots: Bit array of available slots
> + * @addrs: Array containing the dynamic addresses of each attached device
> + * @descs: Array of descriptors, one per attached device
> + * @hj_work: Hot-join work
> + * @irq: Main interrupt
> + * @pclk: System clock
> + * @fclk: Fast clock (bus)
> + * @sclk: Slow clock (other events)
> + * @xferqueue: Transfer queue structure
> + * @xferqueue.list: List member
> + * @xferqueue.cur: Current ongoing transfer
> + * @xferqueue.lock: Queue lock
> + * @ibi: IBI structure
> + * @ibi.num_slots: Number of slots available in @ibi.slots
> + * @ibi.slots: Available IBI slots
> + * @ibi.lock: IBI lock
> + * @bus_lock: Bus lock
> + */
> +struct svc_i3c_master {
> + struct i3c_master_controller base;
> + struct device *dev;
> + void __iomem *regs;
> + u32 free_slots;
> + u8 addrs[SVC_I3C_MAX_DEVS];
> + struct i3c_dev_desc *descs[SVC_I3C_MAX_DEVS];
> + struct work_struct hj_work;
> + int irq;
> + struct clk *pclk;
> + struct clk *fclk;
> + struct clk *sclk;
> + struct {
> + struct list_head list;
> + struct svc_i3c_xfer *cur;
> + /* Prevent races between transfers */
> + spinlock_t lock;
> + } xferqueue;
> + struct {
> + unsigned int num_slots;
> + struct i3c_dev_desc **slots;
> + /* Prevent races within IBI handlers */
> + spinlock_t lock;
> + } ibi;
> +};
> +
> +/**
> + * struct svc_i3c_i3c_dev_data - Device specific data
> + * @index: Index in the master tables corresponding to this device
> + * @ibi: IBI slot index in the master structure
> + * @ibi_pool: IBI pool associated to this device
> + */
> +struct svc_i3c_i2c_dev_data {
> + u8 index;
> + int ibi;
> + struct i3c_generic_ibi_pool *ibi_pool;
> +};
> +
> +static void svc_i3c_master_enable_interrupts(struct svc_i3c_master *master, 
> u32 mask)
> +{
> + writel(mask, master->regs + SVC_I3C_MINTSET);
> +}
> +
> +static void svc_i3c_master_disable_interrupts(struct svc_i3c_master *master)
> +{
> + u32 mask = readl(master->regs + SVC_I3C_MINTSET);
> +
> + writel(mask, master->regs + SVC_I3C_MINTCLR);
> +}
> +
> +static inline struct svc_i3c_master *
> +to_svc_i3c_master(struct i3c_master_controller *master)
> +{
> + return container_of(master, struct svc_i3c_master, base);
> +}
> +
> +static void svc_i3c_master_hj(struct work_struct *work)
> +{
> + struct svc_i3c_master *master;
> +
> + master = container_of(work, struct svc_i3c_master, hj_work);
> + i3c_master_do_daa(>base);
> +}
> +
> +static void svc_i3c_master_flush_fifo(struct svc_i3c_master *master)
> +{
> + writel(SVC_I3C_MDATACTRL_FLUSHTB | SVC_I3C_MDATACTRL_FLUSHRB,
> +master->regs + SVC_I3C_MDATACTRL);
> +}
> +
> +static struct i3c_dev_desc *
> +svc_i3c_master_dev_from_addr(struct svc_i3c_master *master,
> +  unsigned int ibiaddr)
> +{
> + int i;
> +
> + for (i = 0; i < SVC_I3C_MAX_DEVS; i++)
> + if (master->addrs[i] == ibiaddr)
> + break;
> +
> + if (i == SVC_I3C_MAX_DEVS)
> + return NULL;
> +
> + return master->descs[i];
> +}
> +
> +static void svc_i3c_master_emit_stop(struct svc_i3c_master *master)
> +{
> + writel(SVC_I3C_MCTRL_REQUEST_STOP, master->regs + SVC_I3C_MCTRL);
> +}
> +
> +static int svc_i3c_master_handle_ibi(struct svc_i3c_master *master,
> +  struct i3c_dev_desc *dev)
> +{
> + struct svc_i3c_i2c_dev_data *data = i3c_dev_get_master_data(dev);
> + struct i3c_ibi_slot *slot;
> + unsigned int count;
> + u32 mdatactrl;
> + int ret = 0;
> + u8 *buf;
> +
> + spin_lock(>ibi.lock);
> +
> + slot = i3c_generic_ibi_get_free_slot(data->ibi_pool);
> + if (!slot) {
> + ret = -ENOSPC;
> + goto unlock;
> + }
> +
> + slot->len = 0;
> + buf = slot->data;
> + while (readl(master->regs + SVC_I3C_MSTATUS) & SVC_I3C_MINT_RXPEND) {
> + mdatactrl = readl(master->regs + SVC_I3C_MDATACTRL);
> + count = SVC_I3C_MDATACTRL_RXCOUNT(mdatactrl);
> + readsl(master->regs + SVC_I3C_MRDATAB, buf, count);
> + slot->len += count;
> + buf += count;
> + }

I don't think the 

Re: [PATCH v2 2/2] i3c: master: fix for SETDASA and DAA process

2020-08-19 Thread Boris Brezillon
Hello Parshuram,

Sorry for the late reply :-/.

On Thu, 21 May 2020 11:33:01 +0200
Parshuram Thombare  wrote:

> This patch fix following issue.
> Controller slots blocked for devices with static_addr
> but no init_dyn_addr may limit the number of I3C devices
> on the bus which gets dynamic address in DAA. So
> instead of attaching all the devices with static_addr,
> now we only attach the devices which successfully
> complete SETDASA. For remaining devices with init_dyn_addr,
> i3c_master_add_i3c_dev_locked() will try to set requested
> dynamic address after DAA.
> 
> Fixes: 3a379bbcea0a ("i3c: Add core I3C infrastructure")
> Signed-off-by: Parshuram Thombare 
> ---
>  drivers/i3c/master.c | 119 ++-
>  1 file changed, 71 insertions(+), 48 deletions(-)
> 
> diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
> index 3d995f247cb7..5e0438ecf95c 100644
> --- a/drivers/i3c/master.c
> +++ b/drivers/i3c/master.c
> @@ -1426,33 +1426,57 @@ static void i3c_master_detach_i2c_dev(struct 
> i2c_dev_desc *dev)
>   master->ops->detach_i2c_dev(dev);
>  }
>  
> -static void i3c_master_pre_assign_dyn_addr(struct i3c_dev_desc *dev)
> +static int i3c_master_pre_assign_dyn_addr(struct i3c_master_controller 
> *master,
> +   struct i3c_dev_boardinfo *boardinfo)
>  {
> - struct i3c_master_controller *master = i3c_dev_get_master(dev);
> + struct i3c_device_info info = {
> + .static_addr = boardinfo->static_addr,
> + };
> + struct i3c_dev_desc *i3cdev;
>   int ret;
>  
> - if (!dev->boardinfo || !dev->boardinfo->init_dyn_addr ||
> - !dev->boardinfo->static_addr)
> - return;
> + /*
> +  * We anyway don't attach devices which are not addressable

You can drop the anyway.

> +  * (no static_addr and dyn_addr) and devices with static_addr
> +  * but no init_dyn_addr will participate in DAA.
> +  */
> + if (!boardinfo->static_addr || !boardinfo->init_dyn_addr)
> + return -EINVAL;

If we consider this as an error, we should probably check that before
calling i3c_master_pre_assign_dyn_addr() in i3c_master_bus_init().

>  
> - ret = i3c_master_setdasa_locked(master, dev->info.static_addr,
> - dev->boardinfo->init_dyn_addr);
> + i3cdev = i3c_master_alloc_i3c_dev(master, );
> + if (IS_ERR(i3cdev))
> + return -ENOMEM;
> +
> + i3cdev->boardinfo = boardinfo;
> +
> + ret = i3c_master_attach_i3c_dev(master, i3cdev);
>   if (ret)
> - return;
> + goto err_attach;
>  
> - dev->info.dyn_addr = dev->boardinfo->init_dyn_addr;
> - ret = i3c_master_reattach_i3c_dev(dev, 0);
> + ret = i3c_master_setdasa_locked(master, i3cdev->info.static_addr,
> + i3cdev->boardinfo->init_dyn_addr);
> + if (ret)
> + goto err_setdasa;
> +
> + i3cdev->info.dyn_addr = i3cdev->boardinfo->init_dyn_addr;
> + ret = i3c_master_reattach_i3c_dev(i3cdev, 0);
>   if (ret)
>   goto err_rstdaa;
>  
> - ret = i3c_master_retrieve_dev_info(dev);
> + ret = i3c_master_retrieve_dev_info(i3cdev);
>   if (ret)
>   goto err_rstdaa;
>  
> - return;
> + return 0;
>  
>  err_rstdaa:
> - i3c_master_rstdaa_locked(master, dev->boardinfo->init_dyn_addr);
> + i3c_master_rstdaa_locked(master, i3cdev->boardinfo->init_dyn_addr);
> +err_setdasa:
> + i3c_master_detach_i3c_dev(i3cdev);
> +err_attach:
> + i3c_master_free_i3c_dev(i3cdev);
> +
> + return ret;
>  }
>  
>  static void
> @@ -1619,8 +1643,8 @@ static void i3c_master_detach_free_devs(struct 
> i3c_master_controller *master)
>   * This function is following all initialisation steps described in the I3C
>   * specification:
>   *
> - * 1. Attach I2C and statically defined I3C devs to the master so that the
> - *master can fill its internal device table appropriately
> + * 1. Attach I2C devs to the master so that the master can fill its internal
> + *device table appropriately
>   *
>   * 2. Call _master_controller_ops->bus_init() method to initialize
>   *the master controller. That's usually where the bus mode is selected
> @@ -1633,7 +1657,8 @@ static void i3c_master_detach_free_devs(struct 
> i3c_master_controller *master)
>   * 4. Disable all slave events.
>   *
>   * 5. Pre-assign dynamic addresses requested by the FW with SETDASA for I3C
> - *devices that have a static address
> + *devices that have a static address and attach corresponding statically
> + *defined I3C devices to the master.

 and attach them to the
 master if
  the dynamic address assignment succeeds

>   *
>   * 6. Do a DAA (Dynamic Address Assignment) to assign dynamic addresses to 
> all
>   *remaining I3C devices
> @@ -1647,7 +1672,6 @@ 

Re: [PATCH v4 0/6] media: v4l2: Add extended fmt and buffer ioctls

2020-07-21 Thread Boris Brezillon
Hello Helen,

Just a few drive-by comments.

On Fri, 17 Jul 2020 08:54:29 -0300
Helen Koike  wrote:

> Hi,
> 
> I'm sorry for taking too long to submit v4.
> 
> It is not perfect, not all v4l2-compliance tests passes, but I'd like a 
> review,
> specially on the API and potential problems, so I can focus on improving 
> implementation
> and maybe drop the RFC tag for next version.
> 
> Follow below what changed in v4 and some items I'd like to discuss:
> 
> 
> * Ioctl to replace v4l2_pix_format
> -
> During last media summit, we agreed to create ioctls that replace the 
> v4l2_pix_format
> struct and leave the other structs in the v4l2_format union alone.
> Thus I refactored the code to receive struct v4l2_ext_pix_format, and I 
> renamed the
> ioctls, so now we have:
> 
> int ioctl(int fd, VIDIOC_G_EXT_FMT, struct v4l2_ext_pix_format *argp);

Maybe use the EXT_PIX_FMT suffix here since the struct is really only
about pixel formats.

> int ioctl(int fd, VIDIOC_S_EXT_FMT, struct v4l2_ext_pix_format *argp);
> int ioctl(int fd, VIDIOC_TRY_EXT_FMT, struct v4l2_ext_pix_format *argp);
> 
> The only valid types are V4L2_BUF_TYPE_VIDEO_CAPTURE and 
> V4L2_BUF_TYPE_VIDEO_OUTPUT,
> all the other types are invalid with this API.
> 

[...]

> 
> 
> Boris Brezillon (5):
>   media: v4l2: Extend pixel formats to unify single/multi-planar
> handling (and more)
>   media: videobuf2: Expose helpers to implement the _ext_fmt and
> _ext_buf hooks
>   media: mediabus: Add helpers to convert a ext_pix format to/from a
> mbus_fmt
>   media: vivid: Convert the capture and output drivers to
> EXT_FMT/EXT_BUF
>   media: vimc: Implement the ext_fmt and ext_buf hooks

I think you should take ownership of these patches. The end result is
likely to be completely different from what I initially posted, and
you're the one doing the hard work here.

> 
> Hans Verkuil (1):
>   media: v4l2: Add extended buffer operations
> 
>  .../media/common/videobuf2/videobuf2-core.c   |   2 +
>  .../media/common/videobuf2/videobuf2-v4l2.c   | 549 +-
>  .../media/test-drivers/vimc/vimc-capture.c|  61 +-
>  drivers/media/test-drivers/vimc/vimc-common.c |   6 +-
>  drivers/media/test-drivers/vimc/vimc-common.h |   2 +-
>  drivers/media/test-drivers/vivid/vivid-core.c |  70 +-
>  .../test-drivers/vivid/vivid-touch-cap.c  |  26 +-
>  .../test-drivers/vivid/vivid-touch-cap.h  |   3 +-
>  .../media/test-drivers/vivid/vivid-vid-cap.c  | 169 +---
>  .../media/test-drivers/vivid/vivid-vid-cap.h  |  15 +-
>  .../media/test-drivers/vivid/vivid-vid-out.c  | 193 ++--
>  .../media/test-drivers/vivid/vivid-vid-out.h  |  15 +-
>  drivers/media/v4l2-core/v4l2-dev.c|  50 +-
>  drivers/media/v4l2-core/v4l2-ioctl.c  | 934 --
>  include/media/v4l2-ioctl.h|  60 ++
>  include/media/v4l2-mediabus.h |  42 +
>  include/media/videobuf2-core.h|   6 +-
>  include/media/videobuf2-v4l2.h|  21 +-
>  include/uapi/linux/videodev2.h| 144 +++
>  19 files changed, 1650 insertions(+), 718 deletions(-)
> 



Re: [RFC 07/12] media: uapi: h264: Add DPB entry field reference flags

2020-07-10 Thread Boris Brezillon
On Fri, 10 Jul 2020 08:50:28 -0300
Ezequiel Garcia  wrote:

> On Fri, 2020-07-10 at 10:13 +0200, Boris Brezillon wrote:
> > On Fri, 10 Jul 2020 01:21:07 -0300
> > Ezequiel Garcia  wrote:
> >   
> > > Hello Jonas,
> > > 
> > > In the context of the uAPI cleanup,
> > > I'm revisiting this patch.
> > > 
> > > On Sun, 2019-09-01 at 12:45 +, Jonas Karlman wrote:  
> > > > Add DPB entry flags to help indicate when a reference frame is a field 
> > > > picture
> > > > and how the DPB entry is referenced, top or bottom field or full frame.
> > > > 
> > > > Signed-off-by: Jonas Karlman 
> > > > ---
> > > >  Documentation/media/uapi/v4l/ext-ctrls-codec.rst | 12 
> > > >  include/media/h264-ctrls.h   |  4 
> > > >  2 files changed, 16 insertions(+)
> > > > 
> > > > diff --git a/Documentation/media/uapi/v4l/ext-ctrls-codec.rst 
> > > > b/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
> > > > index bc5dd8e76567..eb6c32668ad7 100644
> > > > --- a/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
> > > > +++ b/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
> > > > @@ -2022,6 +2022,18 @@ enum 
> > > > v4l2_mpeg_video_h264_hierarchical_coding_type -
> > > >  * - ``V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM``
> > > >- 0x0004
> > > >- The DPB entry is a long term reference frame
> > > > +* - ``V4L2_H264_DPB_ENTRY_FLAG_FIELD_PICTURE``
> > > > +  - 0x0008
> > > > +  - The DPB entry is a field picture
> > > > +* - ``V4L2_H264_DPB_ENTRY_FLAG_REF_TOP``
> > > > +  - 0x0010
> > > > +  - The DPB entry is a top field reference
> > > > +* - ``V4L2_H264_DPB_ENTRY_FLAG_REF_BOTTOM``
> > > > +  - 0x0020
> > > > +  - The DPB entry is a bottom field reference
> > > > +* - ``V4L2_H264_DPB_ENTRY_FLAG_REF_FRAME``
> > > > +  - 0x0030
> > > > +  - The DPB entry is a reference frame
> > > >  
> > > >  ``V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE (enum)``
> > > >  Specifies the decoding mode to use. Currently exposes slice-based 
> > > > and
> > > > diff --git a/include/media/h264-ctrls.h b/include/media/h264-ctrls.h
> > > > index e877bf1d537c..76020ebd1e6c 100644
> > > > --- a/include/media/h264-ctrls.h
> > > > +++ b/include/media/h264-ctrls.h
> > > > @@ -185,6 +185,10 @@ struct v4l2_ctrl_h264_slice_params {
> > > >  #define V4L2_H264_DPB_ENTRY_FLAG_VALID 0x01
> > > >  #define V4L2_H264_DPB_ENTRY_FLAG_ACTIVE0x02
> > > >  #define V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM 0x04
> > > > +#define V4L2_H264_DPB_ENTRY_FLAG_FIELD_PICTURE 0x08
> > > > +#define V4L2_H264_DPB_ENTRY_FLAG_REF_TOP   0x10
> > > > +#define V4L2_H264_DPB_ENTRY_FLAG_REF_BOTTOM0x20
> > > > +#define V4L2_H264_DPB_ENTRY_FLAG_REF_FRAME 0x30
> > > >  
> > > 
> > > I've been going thru the H264 spec and I'm unsure,
> > > are all these flags semantically needed?
> > > 
> > > For instance, if one of REF_BOTTOM or REF_TOP (or both)
> > > are set, doesn't that indicate it's a field picture?
> > > 
> > > Or conversely, if neither REF_BOTTOM or REF_TOP are set,
> > > then it's a frame picture?  
> > 
> > I think that's what I was trying to do here [1]
> > 
> > [1]https://patchwork.kernel.org/patch/11392095/  
> 
> Right. Aren't we missing a DPB_ENTRY_FLAG_TOP_FIELD?
> 
> If I understand correctly, the DPB can contain:
> 
> * frames (FLAG_FIELD not set)
> * a field pair, with a single field (FLAG_FIELD and either TOP or BOTTOM).
> * a field pair, with boths fields (FLAG_FIELD and both TOP or BOTTOM).

Well, my understand is that, if the buffer contains both a TOP and
BOTTOM field, it actually becomes a full frame, so you actually have
those cases:

* FLAG_FIELD not set: this a frame (note that a TOP/BOTTOM field
  decoded buffer can become of frame if it's complemented with the
  missing field later during the decoding)
* FLAG_FIELD set + BOTTOM_FIELD not set: this is a TOP field
* FLAG_FIELD set + BOTTOM_FIELD set: this is a BOTTOM field
* FLAG_FIELD not set + BOTTOM_FIELD set: invalid combination

but I might be wrong.


Re: [RFC 07/12] media: uapi: h264: Add DPB entry field reference flags

2020-07-10 Thread Boris Brezillon
On Fri, 10 Jul 2020 01:21:07 -0300
Ezequiel Garcia  wrote:

> Hello Jonas,
> 
> In the context of the uAPI cleanup,
> I'm revisiting this patch.
> 
> On Sun, 2019-09-01 at 12:45 +, Jonas Karlman wrote:
> > Add DPB entry flags to help indicate when a reference frame is a field 
> > picture
> > and how the DPB entry is referenced, top or bottom field or full frame.
> > 
> > Signed-off-by: Jonas Karlman 
> > ---
> >  Documentation/media/uapi/v4l/ext-ctrls-codec.rst | 12 
> >  include/media/h264-ctrls.h   |  4 
> >  2 files changed, 16 insertions(+)
> > 
> > diff --git a/Documentation/media/uapi/v4l/ext-ctrls-codec.rst 
> > b/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
> > index bc5dd8e76567..eb6c32668ad7 100644
> > --- a/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
> > +++ b/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
> > @@ -2022,6 +2022,18 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
> >  * - ``V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM``
> >- 0x0004
> >- The DPB entry is a long term reference frame
> > +* - ``V4L2_H264_DPB_ENTRY_FLAG_FIELD_PICTURE``
> > +  - 0x0008
> > +  - The DPB entry is a field picture
> > +* - ``V4L2_H264_DPB_ENTRY_FLAG_REF_TOP``
> > +  - 0x0010
> > +  - The DPB entry is a top field reference
> > +* - ``V4L2_H264_DPB_ENTRY_FLAG_REF_BOTTOM``
> > +  - 0x0020
> > +  - The DPB entry is a bottom field reference
> > +* - ``V4L2_H264_DPB_ENTRY_FLAG_REF_FRAME``
> > +  - 0x0030
> > +  - The DPB entry is a reference frame
> >  
> >  ``V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE (enum)``
> >  Specifies the decoding mode to use. Currently exposes slice-based and
> > diff --git a/include/media/h264-ctrls.h b/include/media/h264-ctrls.h
> > index e877bf1d537c..76020ebd1e6c 100644
> > --- a/include/media/h264-ctrls.h
> > +++ b/include/media/h264-ctrls.h
> > @@ -185,6 +185,10 @@ struct v4l2_ctrl_h264_slice_params {
> >  #define V4L2_H264_DPB_ENTRY_FLAG_VALID 0x01
> >  #define V4L2_H264_DPB_ENTRY_FLAG_ACTIVE0x02
> >  #define V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM 0x04
> > +#define V4L2_H264_DPB_ENTRY_FLAG_FIELD_PICTURE 0x08
> > +#define V4L2_H264_DPB_ENTRY_FLAG_REF_TOP   0x10
> > +#define V4L2_H264_DPB_ENTRY_FLAG_REF_BOTTOM0x20
> > +#define V4L2_H264_DPB_ENTRY_FLAG_REF_FRAME 0x30
> >
> 
> I've been going thru the H264 spec and I'm unsure,
> are all these flags semantically needed?
> 
> For instance, if one of REF_BOTTOM or REF_TOP (or both)
> are set, doesn't that indicate it's a field picture?
> 
> Or conversely, if neither REF_BOTTOM or REF_TOP are set,
> then it's a frame picture?

I think that's what I was trying to do here [1]

[1]https://patchwork.kernel.org/patch/11392095/


Re: [RESEND PATCH 2/3] drm/mediatek: mtk_dpi: Convert to bridge driver

2020-07-01 Thread Boris Brezillon
On Mon, 18 May 2020 19:39:08 +0200
Enric Balletbo i Serra  wrote:

> Convert mtk_dpi to a bridge driver with built-in encoder support for
> compatibility with existing component drivers.
> 
> Signed-off-by: Enric Balletbo i Serra 
> Reviewed-by: Chun-Kuang Hu 
> ---
> 
>  drivers/gpu/drm/mediatek/mtk_dpi.c | 66 +++---
>  1 file changed, 34 insertions(+), 32 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c 
> b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index 7112125dc3d1..baad198c69eb 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -61,6 +61,7 @@ enum mtk_dpi_out_color_format {
>  struct mtk_dpi {
>   struct mtk_ddp_comp ddp_comp;
>   struct drm_encoder encoder;
> + struct drm_bridge bridge;
>   struct drm_bridge *next_bridge;
>   void __iomem *regs;
>   struct device *dev;
> @@ -77,9 +78,9 @@ struct mtk_dpi {
>   int refcount;
>  };
>  
> -static inline struct mtk_dpi *mtk_dpi_from_encoder(struct drm_encoder *e)
> +static inline struct mtk_dpi *bridge_to_dpi(struct drm_bridge *b)
>  {
> - return container_of(e, struct mtk_dpi, encoder);
> + return container_of(b, struct mtk_dpi, bridge);
>  }
>  
>  enum mtk_dpi_polarity {
> @@ -518,50 +519,44 @@ static const struct drm_encoder_funcs 
> mtk_dpi_encoder_funcs = {
>   .destroy = mtk_dpi_encoder_destroy,
>  };
>  
> -static bool mtk_dpi_encoder_mode_fixup(struct drm_encoder *encoder,
> -const struct drm_display_mode *mode,
> -struct drm_display_mode *adjusted_mode)
> +static int mtk_dpi_bridge_attach(struct drm_bridge *bridge,
> +  enum drm_bridge_attach_flags flags)
>  {
> - return true;
> + struct mtk_dpi *dpi = bridge_to_dpi(bridge);
> +
> + return drm_bridge_attach(bridge->encoder, dpi->next_bridge,
> +  >bridge, flags);
>  }
>  
> -static void mtk_dpi_encoder_mode_set(struct drm_encoder *encoder,
> -  struct drm_display_mode *mode,
> -  struct drm_display_mode *adjusted_mode)
> +static void mtk_dpi_bridge_mode_set(struct drm_bridge *bridge,
> + const struct drm_display_mode *mode,
> + const struct drm_display_mode *adjusted_mode)
>  {
> - struct mtk_dpi *dpi = mtk_dpi_from_encoder(encoder);
> + struct mtk_dpi *dpi = bridge_to_dpi(bridge);
>  
>   drm_mode_copy(>mode, adjusted_mode);
>  }
>  
> -static void mtk_dpi_encoder_disable(struct drm_encoder *encoder)
> +static void mtk_dpi_bridge_disable(struct drm_bridge *bridge)
>  {
> - struct mtk_dpi *dpi = mtk_dpi_from_encoder(encoder);
> + struct mtk_dpi *dpi = bridge_to_dpi(bridge);
>  
>   mtk_dpi_power_off(dpi);
>  }
>  
> -static void mtk_dpi_encoder_enable(struct drm_encoder *encoder)
> +static void mtk_dpi_bridge_enable(struct drm_bridge *bridge)
>  {
> - struct mtk_dpi *dpi = mtk_dpi_from_encoder(encoder);
> + struct mtk_dpi *dpi = bridge_to_dpi(bridge);
>  
>   mtk_dpi_power_on(dpi);
>   mtk_dpi_set_display_mode(dpi, >mode);
>  }
>  
> -static int mtk_dpi_atomic_check(struct drm_encoder *encoder,
> - struct drm_crtc_state *crtc_state,
> - struct drm_connector_state *conn_state)
> -{
> - return 0;
> -}
> -
> -static const struct drm_encoder_helper_funcs mtk_dpi_encoder_helper_funcs = {
> - .mode_fixup = mtk_dpi_encoder_mode_fixup,
> - .mode_set = mtk_dpi_encoder_mode_set,
> - .disable = mtk_dpi_encoder_disable,
> - .enable = mtk_dpi_encoder_enable,
> - .atomic_check = mtk_dpi_atomic_check,
> +static const struct drm_bridge_funcs mtk_dpi_bridge_funcs = {
> + .attach = mtk_dpi_bridge_attach,
> + .mode_set = mtk_dpi_bridge_mode_set,
> + .disable = mtk_dpi_bridge_disable,
> + .enable = mtk_dpi_bridge_enable,
>  };
>  
>  static void mtk_dpi_start(struct mtk_ddp_comp *comp)
> @@ -602,16 +597,13 @@ static int mtk_dpi_bind(struct device *dev, struct 
> device *master, void *data)
>   dev_err(dev, "Failed to initialize decoder: %d\n", ret);
>   goto err_unregister;
>   }
> - drm_encoder_helper_add(>encoder, _dpi_encoder_helper_funcs);
>  
>   /* Currently DPI0 is fixed to be driven by OVL1 */
>   dpi->encoder.possible_crtcs = BIT(1);
>  
> - ret = drm_bridge_attach(>encoder, dpi->next_bridge, NULL, 0);
> - if (ret) {
> - dev_err(dev, "Failed to attach bridge: %d\n", ret);

Any reason your decided to drop this error message? If there's one,
this should probably happen in a separate patch.

> + ret = drm_bridge_attach(>encoder, >bridge, NULL, 0);
> + if (ret)
>   goto err_cleanup;
> - }
>  
>   dpi->bit_num = MTK_DPI_OUT_BIT_NUM_8BITS;
>   dpi->channel_swap = MTK_DPI_OUT_CHANNEL_SWAP_RGB;
> @@ -768,8 

Re: [RESEND PATCH 3/3] drm/mediatek: mtk_dpi: Use simple encoder

2020-07-01 Thread Boris Brezillon
On Mon, 18 May 2020 19:39:09 +0200
Enric Balletbo i Serra  wrote:

> The mtk_dpi driver uses an empty implementation for its encoder. Replace
> the code with the generic simple encoder.
> 
> Signed-off-by: Enric Balletbo i Serra 
> Reviewed-by: Chun-Kuang Hu 
> ---
> 
>  drivers/gpu/drm/mediatek/mtk_dpi.c | 14 +++---
>  1 file changed, 3 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c 
> b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index baad198c69eb..80778b2aac2a 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -20,6 +20,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #include "mtk_dpi_regs.h"
>  #include "mtk_drm_ddp_comp.h"
> @@ -510,15 +511,6 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
>   return 0;
>  }
>  
> -static void mtk_dpi_encoder_destroy(struct drm_encoder *encoder)
> -{
> - drm_encoder_cleanup(encoder);
> -}
> -
> -static const struct drm_encoder_funcs mtk_dpi_encoder_funcs = {
> - .destroy = mtk_dpi_encoder_destroy,
> -};
> -
>  static int mtk_dpi_bridge_attach(struct drm_bridge *bridge,
>enum drm_bridge_attach_flags flags)
>  {
> @@ -591,8 +583,8 @@ static int mtk_dpi_bind(struct device *dev, struct device 
> *master, void *data)
>   return ret;
>   }
>  
> - ret = drm_encoder_init(drm_dev, >encoder, _dpi_encoder_funcs,
> -DRM_MODE_ENCODER_TMDS, NULL);
> + ret = drm_simple_encoder_init(drm_dev, >encoder,
> +   DRM_MODE_ENCODER_TMDS);

Not related to this change, but shouldn't we have DRM_MODE_ENCODER_DPI
here?

>   if (ret) {
>   dev_err(dev, "Failed to initialize decoder: %d\n", ret);
>   goto err_unregister;



Re: [RESEND PATCH 1/3] drm/mediatek: mtk_dpi: Rename bridge to next_bridge

2020-07-01 Thread Boris Brezillon
On Wed, 1 Jul 2020 13:23:03 +0200
Boris Brezillon  wrote:

> On Mon, 18 May 2020 19:39:07 +0200
> Enric Balletbo i Serra  wrote:
> 
> > This is really a cosmetic change just to make a bit more readable the
> > code after convert the driver to drm_bridge. The bridge variable name
> > will be used by the encoder drm_bridge, and the chained bridge will be
> > named next_bridge.
> > 
> > Signed-off-by: Enric Balletbo i Serra 
> > Reviewed-by: Chun-Kuang Hu 
> > ---
> > 
> >  drivers/gpu/drm/mediatek/mtk_dpi.c | 8 
> >  1 file changed, 4 insertions(+), 4 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c 
> > b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > index 7fbfa95bab09..7112125dc3d1 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > @@ -61,7 +61,7 @@ enum mtk_dpi_out_color_format {
> >  struct mtk_dpi {
> > struct mtk_ddp_comp ddp_comp;
> > struct drm_encoder encoder;
> > -   struct drm_bridge *bridge;
> > +   struct drm_bridge *next_bridge;  
> 
> Did you consider moving the drm_of_find_panel_or_bridge() call to
> mtk_dpi_bind() so you can get rid of this field?

Nevermind, you need it in patch 2 for the recursive call to
drm_bridge_attach().

> 
> This makes we realize there's no refcounting on bridges, which means
> the bridge can vanish between the drm_of_find_panel_or_bridge() and
> drm_bridge_attach() calls :-/.
> 
> > void __iomem *regs;
> > struct device *dev;
> > struct clk *engine_clk;
> > @@ -607,7 +607,7 @@ static int mtk_dpi_bind(struct device *dev, struct 
> > device *master, void *data)
> > /* Currently DPI0 is fixed to be driven by OVL1 */
> > dpi->encoder.possible_crtcs = BIT(1);
> >  
> > -   ret = drm_bridge_attach(>encoder, dpi->bridge, NULL, 0);
> > +   ret = drm_bridge_attach(>encoder, dpi->next_bridge, NULL, 0);
> > if (ret) {
> > dev_err(dev, "Failed to attach bridge: %d\n", ret);
> > goto err_cleanup;
> > @@ -747,11 +747,11 @@ static int mtk_dpi_probe(struct platform_device *pdev)
> > }
> >  
> > ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0,
> > - NULL, >bridge);
> > + NULL, >next_bridge);
> > if (ret)
> > return ret;
> >  
> > -   dev_info(dev, "Found bridge node: %pOF\n", dpi->bridge->of_node);
> > +   dev_info(dev, "Found bridge node: %pOF\n", dpi->next_bridge->of_node);
> >  
> > comp_id = mtk_ddp_comp_get_id(dev->of_node, MTK_DPI);
> > if (comp_id < 0) {  
> 



Re: [RESEND PATCH 1/3] drm/mediatek: mtk_dpi: Rename bridge to next_bridge

2020-07-01 Thread Boris Brezillon
On Mon, 18 May 2020 19:39:07 +0200
Enric Balletbo i Serra  wrote:

> This is really a cosmetic change just to make a bit more readable the
> code after convert the driver to drm_bridge. The bridge variable name
> will be used by the encoder drm_bridge, and the chained bridge will be
> named next_bridge.
> 
> Signed-off-by: Enric Balletbo i Serra 
> Reviewed-by: Chun-Kuang Hu 
> ---
> 
>  drivers/gpu/drm/mediatek/mtk_dpi.c | 8 
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c 
> b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index 7fbfa95bab09..7112125dc3d1 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -61,7 +61,7 @@ enum mtk_dpi_out_color_format {
>  struct mtk_dpi {
>   struct mtk_ddp_comp ddp_comp;
>   struct drm_encoder encoder;
> - struct drm_bridge *bridge;
> + struct drm_bridge *next_bridge;

Did you consider moving the drm_of_find_panel_or_bridge() call to
mtk_dpi_bind() so you can get rid of this field?

This makes we realize there's no refcounting on bridges, which means
the bridge can vanish between the drm_of_find_panel_or_bridge() and
drm_bridge_attach() calls :-/.

>   void __iomem *regs;
>   struct device *dev;
>   struct clk *engine_clk;
> @@ -607,7 +607,7 @@ static int mtk_dpi_bind(struct device *dev, struct device 
> *master, void *data)
>   /* Currently DPI0 is fixed to be driven by OVL1 */
>   dpi->encoder.possible_crtcs = BIT(1);
>  
> - ret = drm_bridge_attach(>encoder, dpi->bridge, NULL, 0);
> + ret = drm_bridge_attach(>encoder, dpi->next_bridge, NULL, 0);
>   if (ret) {
>   dev_err(dev, "Failed to attach bridge: %d\n", ret);
>   goto err_cleanup;
> @@ -747,11 +747,11 @@ static int mtk_dpi_probe(struct platform_device *pdev)
>   }
>  
>   ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0,
> -   NULL, >bridge);
> +   NULL, >next_bridge);
>   if (ret)
>   return ret;
>  
> - dev_info(dev, "Found bridge node: %pOF\n", dpi->bridge->of_node);
> + dev_info(dev, "Found bridge node: %pOF\n", dpi->next_bridge->of_node);
>  
>   comp_id = mtk_ddp_comp_get_id(dev->of_node, MTK_DPI);
>   if (comp_id < 0) {



Re: next/master bisection: baseline.login on ox820-cloudengines-pogoplug-series-3

2020-06-18 Thread Boris Brezillon
On Thu, 18 Jun 2020 15:23:45 +0100
Guillaume Tucker  wrote:

> On 18/06/2020 15:09, Miquel Raynal wrote:
> > Hi Guillaume,
> > 
> > Miquel Raynal  wrote on Thu, 18 Jun 2020
> > 15:23:24 +0200:
> >   
> >> Hi Guillaume,
> >>
> >> Guillaume Tucker  wrote on Thu, 18 Jun
> >> 2020 13:28:05 +0100:
> >>  
> >>> Please see the bisection report below about a kernel panic.
> >>>
> >>> Reports aren't automatically sent to the public while we're
> >>> trialing new bisection features on kernelci.org but this one
> >>> looks valid.
> >>>
> >>> See the kernel Oops due to a NULL pointer followed by a panic:
> >>>
> >>>   
> >>> https://storage.kernelci.org/next/master/next-20200618/arm/oxnas_v6_defconfig/gcc-8/lab-baylibre/baseline-ox820-cloudengines-pogoplug-series-3.html#L504
> >>>   
> >>
> >> Thanks for the report, I will not be able to manage it before Monday,
> >> but I'll try to take care of it early next week.  
> > 
> > Actually Boris saw the issue, I just updated nand/next, it should be
> > part of tomorrow's linux-next. Could you please report if it fixes your
> > boot?  
> 
> Sure, will check tomorrow.  Thanks for the update.
> 
> We may also consider adding the nand/next branch to kernelci.org
> and catch issues earlier.  We can discuss that separately.

If you're testing linux-next that shouldn't help us much (nand/next is
pulled in linux-next already), but maybe it's just about making the
bisection easier for kernelci (less commits to inspect), in which case
that's probably a good idea. You might also want to add mtd/next,
spi-nor/next and cfi/next so the entire MTD subsystem gets tested.


Re: [PATCH v6 0/5] Micron SLC NAND filling block

2020-06-02 Thread Boris Brezillon
On Tue, 02 Jun 2020 10:59:46 +0200
Bean Huo  wrote:

> On Tue, 2020-06-02 at 09:48 +0200, Boris Brezillon wrote:
> > Hi Bean,
> > 
> > On Mon, 01 Jun 2020 23:10:43 +0200
> > Bean Huo  wrote:
> >   
> > > Hi Richard 
> > > would you please help us confirm below question??  
> > 
> > Miquel suggested an approach that would allow us to deal with both
> > JFFS2
> > and UBI/UBIFS without having any FS/wear-leveling specific code at
> > the
> > NAND level, but you decided to ignore his comments. Sorry but there's
> > nothing we can do to help you if you don't listen to our
> > recommendations.  
> 
> Expose this issue to FS layer, it is not good idea. that will impact
> more code, and involve duplicated code.

Sorry but as far as I'm concerned, you've lost the right to have your
word in such design choices a long time ago. You can't deliberately lie
to us for several weeks/months and expect us to trust you (your
judgment) after that.

Back to the actual proposal, it's something that came from a discussion
we had with Miquel and Richard. It's certainly not perfect, but neither
is the option of hardcoding a quirk for JFFS2/UBI/UBIFS in the Micron
NAND driver.

BTW, I think you completely occluded Miquel's suggestion to have a
generic implementation at the MTD level for users who don't care about
the pattern that's written to those 'soon-to-be-erased' blocks. See,
that's one of the things I'm complaining about. You seem to ignore
(don't know if it's deliberate or not) some of the suggestions we do.

> > 
> > I've been quite disappointed by your behavior in the past, and it  
> 
> > continues. Recently you've taken Miquel's patches and claimed
> > ownership  
> did you seem my recent patch? you can ignore that see this.

I don't understand what you mean here, sorry.

> 
> 
> > on them (probably not intentionally, but still) while you were
> > clearly
> > unable to rework your original series the way I suggested (which
> > Miquel
> > did after seeing you would never send new versions).   
> 
> seriously?

Yes, seriously!

> 
> > And when Miquel
> > suggested a change to the implementation he had done based on the
> > discussion we had with Richard, you decided to ignore it and pursue
> > in
> > the original direction. So, quite frankly, I'm really not convinced
> > you
> > can conduct such a change.
> >   
> 
> As Miquel mentioned, we need richard's final comfirmation,
> If he agrees with this proposal, I give up my current patch.
> 

Actually, you need more than Richard's blessing. Miquel has to agree on
the NAND changes, and even if I can't block the solution, I think I can
at least give my opinion: anything that involves FS/wear-leveling
specific code at the NAND level should be avoided. Given the discussion
we had regarding JFFS2 and the cleanmarkers, I don't think we can come
up with a solution that's safe for every users, hence the proposal to
empower users with this responsibility.


Re: [PATCH v6 0/5] Micron SLC NAND filling block

2020-06-02 Thread Boris Brezillon
Hi Bean,

On Mon, 01 Jun 2020 23:10:43 +0200
Bean Huo  wrote:

> Hi Richard 
> would you please help us confirm below question??

Miquel suggested an approach that would allow us to deal with both JFFS2
and UBI/UBIFS without having any FS/wear-leveling specific code at the
NAND level, but you decided to ignore his comments. Sorry but there's
nothing we can do to help you if you don't listen to our
recommendations.

I've been quite disappointed by your behavior in the past, and it
continues. Recently you've taken Miquel's patches and claimed ownership
on them (probably not intentionally, but still) while you were clearly
unable to rework your original series the way I suggested (which Miquel
did after seeing you would never send new versions). And when Miquel
suggested a change to the implementation he had done based on the
discussion we had with Richard, you decided to ignore it and pursue in
the original direction. So, quite frankly, I'm really not convinced you
can conduct such a change.

Regards,

Boris


Re: [GIT PULL] i3c: Changes for 5.8

2020-06-01 Thread Boris Brezillon
Hello Linus,

On Mon, 1 Jun 2020 11:39:05 -0700
Linus Torvalds  wrote:

> On Mon, Jun 1, 2020 at 12:54 AM Boris Brezillon
>  wrote:
> >
> >   git://git.kernel.org/pub/scm/linux/kernel/git/i3c/linux.git i3c/for-5.8  
> 
> Hmm. No such ref..
> 
> I see the "i3c/next" branch that has that top commit, but I don't see
> the signed tag.

Oops, should be here now.

> 
> Forgot to push?

I pushed it, but maybe not to the right repo.

> "git request-pull" _should_ have warned about the
> remote side missing..

Yes, it warned me about that but there used to be a slight delay
between the time I push at tag to the repo and the time it actually
appears there in the past (maybe it's no longer the case), so I didn't
pay attention to that one. I'll try to be more careful next time. Sorry
for the inconvenience.

Regards,

Boris


[GIT PULL] i3c: Changes for 5.8

2020-06-01 Thread Boris Brezillon
Hello Linus,

Here is the I3C PR for 5.8.

Regards,

Boris

The following changes since commit 8f3d9f354286745c751374f5f1fcafee6b3f3136:

  Linux 5.7-rc1 (2020-04-12 12:35:55 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/i3c/linux.git i3c/for-5.8

for you to fetch changes up to b4203ce0556348dcfe29f897d1dbe65102874d89:

  i3c master: GETMRL's 3rd byte is optional even with BCR_IBI_PAYLOAD 
(2020-04-16 14:27:46 +0200)


Fix GETMRL's logic


Nicolas Pitre (1):
  i3c master: GETMRL's 3rd byte is optional even with BCR_IBI_PAYLOAD

 drivers/i3c/master.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)


Re: [PATCH v2 1/2] i3c: master add i3c_master_attach_boardinfo to preserve boardinfo

2020-05-29 Thread Boris Brezillon
On Thu, 21 May 2020 11:32:22 +0200
Parshuram Thombare  wrote:

> Boardinfo was lost if I3C object for devices with boardinfo
> available are not created or not added to the I3C device list
> because of some failure e.g. SETDASA failed, retrieve info failed etc
> This patch adds i3c_master_attach_boardinfo which scan boardinfo list
> in the master object and 'attach' it to the I3C device object.
> 
> Fixes: 3a379bbcea0a ("i3c: Add core I3C infrastructure")
> Signed-off-by: Parshuram Thombare 

This patch looks good to me. I'll apply it just after the merge window.

> ---
>  drivers/i3c/master.c | 19 +--
>  1 file changed, 17 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
> index 5f4bd52121fe..3d995f247cb7 100644
> --- a/drivers/i3c/master.c
> +++ b/drivers/i3c/master.c
> @@ -1776,6 +1776,21 @@ static void i3c_master_bus_cleanup(struct 
> i3c_master_controller *master)
>   i3c_master_detach_free_devs(master);
>  }
>  
> +static void i3c_master_attach_boardinfo(struct i3c_dev_desc *i3cdev)
> +{
> + struct i3c_master_controller *master = i3cdev->common.master;
> + struct i3c_dev_boardinfo *i3cboardinfo;
> +
> + list_for_each_entry(i3cboardinfo, >boardinfo.i3c, node) {
> + if (i3cdev->info.pid != i3cboardinfo->pid)
> + continue;
> +
> + i3cdev->boardinfo = i3cboardinfo;
> + i3cdev->info.static_addr = i3cboardinfo->static_addr;
> + return;
> + }
> +}
> +
>  static struct i3c_dev_desc *
>  i3c_master_search_i3c_dev_duplicate(struct i3c_dev_desc *refdev)
>  {
> @@ -1831,10 +1846,10 @@ int i3c_master_add_i3c_dev_locked(struct 
> i3c_master_controller *master,
>   if (ret)
>   goto err_detach_dev;
>  
> + i3c_master_attach_boardinfo(newdev);
> +
>   olddev = i3c_master_search_i3c_dev_duplicate(newdev);
>   if (olddev) {
> - newdev->boardinfo = olddev->boardinfo;
> - newdev->info.static_addr = olddev->info.static_addr;
>   newdev->dev = olddev->dev;
>   if (newdev->dev)
>   newdev->dev->desc = newdev;



Re: [PATCH v3 00/14] mtd: spi-nor: add xSPI Octal DTR support

2020-05-28 Thread Boris Brezillon
On Thu, 28 May 2020 15:58:02 +0800
Mason Yang  wrote:

> Hello,
> 
> JESD216C has defined specification for Octal 8S-8S-8S and 8D-8D-8D.
> Based on JEDEC216C Basic Flash Parameter Table (BFPT) driver extract
> DWORD-18: command and command extension type.
> DWORD-20: Maximum operation speed of device in Octal mode.
> 
> xSPI profile 1.0 table:
> DWORD-1: Read Fast command, the number of dummy cycles and address nbytes
>for Read Status Register command.
> DWORD-2: Read/Write volatile Register command for CFG Reg2.
> DWORD-4 and DWORD-5: dummy cycles used for various frequencies based on
> maximum speed of device from BFPT 20th DWORD.
> 
> Ccommand sequences to change to octal DTR mode:
> The length of each command sequence is 8 per byte for single SPI mode and
> patching driver to parse and execute these sequences for octal DTR mode.
> 
> By Vignesh's comments to patch these drivers based on Pratyush's patches
> set [1].
> 
> This series adds support for Macronix mx25uw51245g works in octal DTR mode.
> 
> Tested on Macronix's Zynq PicoZed board with Macronix's SPI controller
> (spi-mxic.c) driver patched on mx25uw51245g Octal flash.
> 
> 
> [1] 
> https://patchwork.ozlabs.org/project/linux-mtd/cover/20200525091544.17270-1-p.ya...@ti.com/
> 
> 
> Summary of change log
> v3:
> Add support command sequences to change octal DTR mode and based on
> part of Pratyush's patches set.
> 
> v2: 
> Parse BFPT & xSPI table for Octal 8D-8D-8D mode parameters and enable Octal
> mode in spi_nor_late_init_params().
> Using Macros in spi_nor_spimem_read_data, spi_nor_spimem_write_data and
> so on by Vignesh comments.
> 
> v1:
> Without parsing BFPT & xSPI profile 1.0 table and enter Octal 8D-8D-8D
> mode directly in spi_nor_fixups hooks.
> 
> 
> thnaks for your time and review.
> best regards,
> Mason
> 
> --
> Mason Yang (7):
>   mtd: spi-nor: sfdp: get octal mode maximum speed from BFPT
>   mtd: spi-nor: sfdp: parse xSPI Profile 1.0 table
>   mtd: spi-nor: sfdp: parse command sequences to change octal DTR mode
>   mtd: spi-nor: core: add configuration register 2 read & write support
>   spi: mxic: patch for octal DTR mode support
>   mtd: spi-nor: core: execute command sequences to change octal DTR mode
>   mtd: spi-nor: macronix: Add Octal 8D-8D-8D supports for Macronix
> mx25uw51245g
> 
> Pratyush Yadav (7):
>   spi: spi-mem: allow specifying whether an op is DTR or not
>   spi: spi-mem: allow specifying a command's extension
>   mtd: spi-nor: add support for DTR protocol
>   mtd: spi-nor: sfdp: prepare BFPT parsing for JESD216 rev D
>   mtd: spi-nor: sfdp: get command opcode extension type from BFPT
>   mtd: spi-nor: core: use dummy cycle and address width info from SFDP
>   mtd: spi-nor: core: enable octal DTR mode when possible

Why are you doing that?! This series is being actively worked on by
Pratyush, and all you gain by sending it on your own is more
confusion. If you have patches on top of a series that's not been
merged yet, mention the dependency in the cover letter, but don't
resend patches that have already been sent and are being reviewed.

I think it's time you spend a bit of time learning about the submission
process, because that's not the first mistake you do, and I'm pretty
sure I already mentioned that in my previous reviews.


Re: [PATCH v8 02/19] spi: spi-mem: allow specifying a command's extension

2020-05-24 Thread Boris Brezillon
On Sat, 23 May 2020 04:10:25 +0530
Pratyush Yadav  wrote:

> diff --git a/drivers/spi/spi-mxic.c b/drivers/spi/spi-mxic.c
> index 69491f3a515d..4e4292f0ee1d 100644
> --- a/drivers/spi/spi-mxic.c
> +++ b/drivers/spi/spi-mxic.c
> @@ -356,6 +356,7 @@ static int mxic_spi_mem_exec_op(struct spi_mem *mem,
>   int nio = 1, i, ret;
>   u32 ss_ctrl;
>   u8 addr[8];
> + u8 opcode = op->cmd.opcode & 0xff;

You don't need the '& 0xff' here, the cast to an u8 will truncate the
value anyway.

>  
>   ret = mxic_spi_set_freq(mxic, mem->spi->max_speed_hz);
>   if (ret)
> @@ -393,7 +394,7 @@ static int mxic_spi_mem_exec_op(struct spi_mem *mem,
>   writel(readl(mxic->regs + HC_CFG) | HC_CFG_MAN_CS_ASSERT,
>  mxic->regs + HC_CFG);
>  
> - ret = mxic_spi_data_xfer(mxic, >cmd.opcode, NULL, 1);
> + ret = mxic_spi_data_xfer(mxic, , NULL, 1);
>   if (ret)
>   goto out;
>  
> diff --git a/drivers/spi/spi-zynq-qspi.c b/drivers/spi/spi-zynq-qspi.c
> index 17641157354d..41389856e14a 100644
> --- a/drivers/spi/spi-zynq-qspi.c
> +++ b/drivers/spi/spi-zynq-qspi.c
> @@ -527,20 +527,21 @@ static int zynq_qspi_exec_mem_op(struct spi_mem *mem,
>   struct zynq_qspi *xqspi = spi_controller_get_devdata(mem->spi->master);
>   int err = 0, i;
>   u8 *tmpbuf;
> + u8 opcode = op->cmd.opcode & 0xff;
>  

Ditto.

>   dev_dbg(xqspi->dev, "cmd:%#x mode:%d.%d.%d.%d\n",
> - op->cmd.opcode, op->cmd.buswidth, op->addr.buswidth,
> + opcode, op->cmd.buswidth, op->addr.buswidth,
>   op->dummy.buswidth, op->data.buswidth);
>  
>   zynq_qspi_chipselect(mem->spi, true);
>   zynq_qspi_config_op(xqspi, mem->spi);
>  
> - if (op->cmd.opcode) {
> + if (opcode) {

Unrelated to this patch, but this test is wrong. I don't see why we
couldn't have a '0' opcode. The test should be dropped or done on the
new op->cmd.nbytes field.

>   reinit_completion(>data_completion);
> - xqspi->txbuf = (u8 *)>cmd.opcode;
> + xqspi->txbuf = 
>   xqspi->rxbuf = NULL;
> - xqspi->tx_bytes = sizeof(op->cmd.opcode);
> - xqspi->rx_bytes = sizeof(op->cmd.opcode);
> + xqspi->tx_bytes = op->cmd.nbytes;
> + xqspi->rx_bytes = op->cmd.nbytes;
>   zynq_qspi_write_op(xqspi, ZYNQ_QSPI_FIFO_DEPTH, true);
>   zynq_qspi_write(xqspi, ZYNQ_QSPI_IEN_OFFSET,
>   ZYNQ_QSPI_IXR_RXTX_MASK);


Re: [PATCH v7 02/20] spi: spi-mem: allow specifying a command's extension

2020-05-22 Thread Boris Brezillon
On Fri, 22 May 2020 15:42:43 +0530
Pratyush Yadav  wrote:

> In xSPI mode, flashes expect 2-byte opcodes. The second byte is called
> the "command extension". There can be 3 types of extensions in xSPI:
> repeat, invert, and hex. When the extension type is "repeat", the same
> opcode is sent twice. When it is "invert", the second byte is the
> inverse of the opcode. When it is "hex" an additional opcode byte based
> is sent with the command whose value can be anything.
> 
> So, make opcode a 16-bit value and add a 'nbytes', similar to how
> multiple address widths are handled.

A slightly different version of patch 5 should go before this patch,
otherwise your series is not bisectable. By slightly different, I mean
that you should only write one byte, but put this byte in a temporary
var. Or maybe you can squash patch 5 in this one and mention why you do
so in your commit message.

> 
> Signed-off-by: Pratyush Yadav 
> ---
>  drivers/spi/spi-mem.c   | 5 -
>  include/linux/spi/spi-mem.h | 6 +-
>  2 files changed, 9 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
> index 93e255287ab9..29dcd1d62710 100644
> --- a/drivers/spi/spi-mem.c
> +++ b/drivers/spi/spi-mem.c
> @@ -159,6 +159,9 @@ bool spi_mem_default_supports_op(struct spi_mem *mem,
>   if (op->cmd.dtr || op->addr.dtr || op->dummy.dtr || op->data.dtr)
>   return false;
>  
> + if (op->cmd.nbytes != 1)
> + return false;
> +
>   return true;
>  }
>  EXPORT_SYMBOL_GPL(spi_mem_default_supports_op);
> @@ -173,7 +176,7 @@ static bool spi_mem_buswidth_is_valid(u8 buswidth)
>  
>  static int spi_mem_check_op(const struct spi_mem_op *op)
>  {
> - if (!op->cmd.buswidth)
> + if (!op->cmd.buswidth || !op->cmd.nbytes)
>   return -EINVAL;
>  
>   if ((op->addr.nbytes && !op->addr.buswidth) ||
> diff --git a/include/linux/spi/spi-mem.h b/include/linux/spi/spi-mem.h
> index e3dcb956bf61..159463cc659c 100644
> --- a/include/linux/spi/spi-mem.h
> +++ b/include/linux/spi/spi-mem.h
> @@ -17,6 +17,7 @@
>   {   \
>   .buswidth = __buswidth, \
>   .opcode = __opcode, \
> + .nbytes = 1,\
>   }
>  
>  #define SPI_MEM_OP_ADDR(__nbytes, __val, __buswidth) \
> @@ -69,6 +70,8 @@ enum spi_mem_data_dir {
>  
>  /**
>   * struct spi_mem_op - describes a SPI memory operation
> + * @cmd.nbytes: number of opcode bytes (only 1 or 2 are valid). The opcode is
> + *   sent MSB-first.
>   * @cmd.buswidth: number of IO lines used to transmit the command
>   * @cmd.opcode: operation opcode
>   * @cmd.dtr: whether the command opcode should be sent in DTR mode or not
> @@ -94,9 +97,10 @@ enum spi_mem_data_dir {
>   */
>  struct spi_mem_op {
>   struct {
> + u8 nbytes;
>   u8 buswidth;
>   u8 dtr : 1;
> - u8 opcode;
> + u16 opcode;
>   } cmd;
>  
>   struct {



Re: [PATCH v6 04/19] spi: spi-mem: allow specifying a command's extension

2020-05-21 Thread Boris Brezillon
On Fri, 22 May 2020 01:33:15 +0530
Pratyush Yadav  wrote:

> On 22/05/20 01:11AM, Pratyush Yadav wrote:
> > On 21/05/20 08:22PM, Boris Brezillon wrote:  
> > > On Wed, 20 May 2020 22:00:38 +0530
> > > Pratyush Yadav  wrote:
> > >   
> > > > In xSPI mode, flashes expect 2-byte opcodes. The second byte is called
> > > > the "command extension". There can be 3 types of extensions in xSPI:
> > > > repeat, invert, and hex. When the extension type is "repeat", the same
> > > > opcode is sent twice. When it is "invert", the second byte is the
> > > > inverse of the opcode. When it is "hex" an additional opcode byte based
> > > > is sent with the command whose value can be anything.
> > > > 
> > > > So, make opcode a 16-bit value and add a 'nbytes', similar to how
> > > > multiple address widths are handled.
> > > > 
> > > > Signed-off-by: Pratyush Yadav 
> > > > ---
> > > >  include/linux/spi/spi-mem.h | 5 -
> > > >  1 file changed, 4 insertions(+), 1 deletion(-)
> > > > 
> > > > diff --git a/include/linux/spi/spi-mem.h b/include/linux/spi/spi-mem.h
> > > > index e3dcb956bf61..731bb64c6ba6 100644
> > > > --- a/include/linux/spi/spi-mem.h
> > > > +++ b/include/linux/spi/spi-mem.h
> > > > @@ -69,6 +69,8 @@ enum spi_mem_data_dir {
> > > >  
> > > >  /**
> > > >   * struct spi_mem_op - describes a SPI memory operation
> > > > + * @cmd.nbytes: number of opcode bytes (only 1 or 2 are valid). The 
> > > > opcode is
> > > > + * sent MSB-first.
> > > >   * @cmd.buswidth: number of IO lines used to transmit the command
> > > >   * @cmd.opcode: operation opcode
> > > >   * @cmd.dtr: whether the command opcode should be sent in DTR mode or 
> > > > not
> > > > @@ -94,9 +96,10 @@ enum spi_mem_data_dir {
> > > >   */
> > > >  struct spi_mem_op {
> > > > struct {
> > > > +   u8 nbytes;
> > > > u8 buswidth;
> > > > u8 dtr : 1;
> > > > -   u8 opcode;
> > > > +   u16 opcode;
> > > > } cmd;
> > > >  
> > > > struct {  
> > > 
> > > As mentioned in one of my previous review, you should patch the mxic
> > > driver before extending the opcode field:  
> > 
> > IIUC, this patchset doesn't break original functionality of the driver. 
> > It will work like before with 1-byte opcodes. So I don't think it is the 
> > responsibility of this patchset to enhance the driver. It didn't work 
> > before with 2-byte opcodes, it won't work now. IMO this should be a 
> > separate, independent change.  
> 
> Scratch that. Big/little endian issue. If you'd drop your Signed-off-by, 
> I'll write the commit message and patch it in.

Just add a Suggested-by, that should be fine.

>   
> > > --->8---  
> > > diff --git a/drivers/spi/spi-mxic.c b/drivers/spi/spi-mxic.c
> > > index 69491f3a515d..c3f4136a7c1d 100644
> > > --- a/drivers/spi/spi-mxic.c
> > > +++ b/drivers/spi/spi-mxic.c
> > > @@ -356,6 +356,7 @@ static int mxic_spi_mem_exec_op(struct spi_mem *mem,
> > > int nio = 1, i, ret;
> > > u32 ss_ctrl;
> > > u8 addr[8];
> > > +   u8 cmd[2];
> > >  
> > > ret = mxic_spi_set_freq(mxic, mem->spi->max_speed_hz);
> > > if (ret)
> > > @@ -393,7 +394,10 @@ static int mxic_spi_mem_exec_op(struct spi_mem *mem,
> > > writel(readl(mxic->regs + HC_CFG) | HC_CFG_MAN_CS_ASSERT,
> > >mxic->regs + HC_CFG);
> > >  
> > > -   ret = mxic_spi_data_xfer(mxic, >cmd.opcode, NULL, 1);
> > > +   for (i = 0; i < op->cmd.nbytes; i++)
> > > +   cmd[i] = op->cmd.opcode >> (8 * (op->cmd.nbytes - i - 1));
> > > +
> > > +   ret = mxic_spi_data_xfer(mxic, cmd, NULL, op->cmd.nbytes);
> > > if (ret)
> > > goto out;
> > >
> 



Re: [PATCH v6 04/19] spi: spi-mem: allow specifying a command's extension

2020-05-21 Thread Boris Brezillon
On Wed, 20 May 2020 22:00:38 +0530
Pratyush Yadav  wrote:

> In xSPI mode, flashes expect 2-byte opcodes. The second byte is called
> the "command extension". There can be 3 types of extensions in xSPI:
> repeat, invert, and hex. When the extension type is "repeat", the same
> opcode is sent twice. When it is "invert", the second byte is the
> inverse of the opcode. When it is "hex" an additional opcode byte based
> is sent with the command whose value can be anything.
> 
> So, make opcode a 16-bit value and add a 'nbytes', similar to how
> multiple address widths are handled.
> 
> Signed-off-by: Pratyush Yadav 
> ---
>  include/linux/spi/spi-mem.h | 5 -
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/include/linux/spi/spi-mem.h b/include/linux/spi/spi-mem.h
> index e3dcb956bf61..731bb64c6ba6 100644
> --- a/include/linux/spi/spi-mem.h
> +++ b/include/linux/spi/spi-mem.h
> @@ -69,6 +69,8 @@ enum spi_mem_data_dir {
>  
>  /**
>   * struct spi_mem_op - describes a SPI memory operation
> + * @cmd.nbytes: number of opcode bytes (only 1 or 2 are valid). The opcode is
> + *   sent MSB-first.
>   * @cmd.buswidth: number of IO lines used to transmit the command
>   * @cmd.opcode: operation opcode
>   * @cmd.dtr: whether the command opcode should be sent in DTR mode or not
> @@ -94,9 +96,10 @@ enum spi_mem_data_dir {
>   */
>  struct spi_mem_op {
>   struct {
> + u8 nbytes;
>   u8 buswidth;
>   u8 dtr : 1;
> - u8 opcode;
> + u16 opcode;
>   } cmd;
>  
>   struct {

As mentioned in one of my previous review, you should patch the mxic
driver before extending the opcode field:

--->8---
diff --git a/drivers/spi/spi-mxic.c b/drivers/spi/spi-mxic.c
index 69491f3a515d..c3f4136a7c1d 100644
--- a/drivers/spi/spi-mxic.c
+++ b/drivers/spi/spi-mxic.c
@@ -356,6 +356,7 @@ static int mxic_spi_mem_exec_op(struct spi_mem *mem,
int nio = 1, i, ret;
u32 ss_ctrl;
u8 addr[8];
+   u8 cmd[2];
 
ret = mxic_spi_set_freq(mxic, mem->spi->max_speed_hz);
if (ret)
@@ -393,7 +394,10 @@ static int mxic_spi_mem_exec_op(struct spi_mem *mem,
writel(readl(mxic->regs + HC_CFG) | HC_CFG_MAN_CS_ASSERT,
   mxic->regs + HC_CFG);
 
-   ret = mxic_spi_data_xfer(mxic, >cmd.opcode, NULL, 1);
+   for (i = 0; i < op->cmd.nbytes; i++)
+   cmd[i] = op->cmd.opcode >> (8 * (op->cmd.nbytes - i - 1));
+
+   ret = mxic_spi_data_xfer(mxic, cmd, NULL, op->cmd.nbytes);
if (ret)
goto out;
 


Re: [PATCH] i3c: master: fix for SETDASA and DAA process

2020-05-20 Thread Boris Brezillon
On Thu, 14 May 2020 18:30:09 +0200
Parshuram Thombare  wrote:

> This patch fix following issues.
> 1. Controller slots blocked for devices with static_addr
>but no init_dyn_addr may limit the number of I3C devices
>on the bus which gets dynamic address in DAA. So
>instead of attaching all the devices with static_addr,
>now we only attach the devices which successfully
>complete SETDASA. Remaining devices are handled in DAA.
> 2. Since we alreay handled devices with init_dyn_addr, removed
>it's handling from i3c_master_add_i3c_dev_locked().
>Now only case handled is devices already with dyn_addr
>participated in DAA, and again got new dyn_addr with an
>extra slot in the master controller.

I don't get that one.

> 3. Removed unnecessary i3c_master_reattach_i3c_dev() from
>i3c_master_add_i3c_dev_locked(), right away after finding
>if duplicate device exists in the I3C list.
>In case of different new and old dyn_addr
>i3c_master_reattach_i3c_dev() will fail which is wrong,
>and in case of same dyn_addr it doesn't add anything new.

I think we should fix re-attach instead, which is what we discussed
with Przemek if I remember correctly.

> 

Can you please split the patch accordingly (one fix per commit)?

> Fixes: 3a379bbcea0a ("i3c: Add core I3C infrastructure")
> Signed-off-by: Parshuram Thombare 
> ---
>  drivers/i3c/master.c | 111 ++-
>  1 file changed, 46 insertions(+), 65 deletions(-)
> 
> diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
> index 5f4bd52121fe..f1d929b58549 100644
> --- a/drivers/i3c/master.c
> +++ b/drivers/i3c/master.c
> @@ -1375,6 +1375,11 @@ static int i3c_master_reattach_i3c_dev(struct 
> i3c_dev_desc *dev,
>   i3c_bus_set_addr_slot_status(>bus,
>dev->info.dyn_addr,
>I3C_ADDR_SLOT_I3C_DEV);
> +
> + if (old_dyn_addr)
> + i3c_bus_set_addr_slot_status(>bus,
> +  old_dyn_addr,
> +  I3C_ADDR_SLOT_FREE);
>   }
>  
>   if (master->ops->reattach_i3c_dev) {
> @@ -1426,33 +1431,52 @@ static void i3c_master_detach_i2c_dev(struct 
> i2c_dev_desc *dev)
>   master->ops->detach_i2c_dev(dev);
>  }
>  
> -static void i3c_master_pre_assign_dyn_addr(struct i3c_dev_desc *dev)
> +static void i3c_master_pre_assign_dyn_addr(struct i3c_master_controller 
> *master,
> +struct i3c_dev_boardinfo *boardinfo)
>  {
> - struct i3c_master_controller *master = i3c_dev_get_master(dev);
> + struct i3c_device_info info = {
> + .static_addr = boardinfo->static_addr,
> + };
> + struct i3c_dev_desc *i3cdev;
>   int ret;
>  
> - if (!dev->boardinfo || !dev->boardinfo->init_dyn_addr ||
> - !dev->boardinfo->static_addr)
> + /*
> +  * We anyway don't attach devices which are not addressable
> +  * (no static_addr and dyn_addr) and devices with static_addr
> +  * but no init_dyn_addr will participate in DAA.
> +  */
> + if (!boardinfo->static_addr || !boardinfo->init_dyn_addr)
> + return;
> +
> + i3cdev = i3c_master_alloc_i3c_dev(master, );
> + if (IS_ERR(i3cdev))
>   return;
>  
> - ret = i3c_master_setdasa_locked(master, dev->info.static_addr,
> - dev->boardinfo->init_dyn_addr);
> + i3cdev->boardinfo = boardinfo;
> +
> + ret = i3c_master_attach_i3c_dev(master, i3cdev);
>   if (ret)
>   return;
>  
> - dev->info.dyn_addr = dev->boardinfo->init_dyn_addr;
> - ret = i3c_master_reattach_i3c_dev(dev, 0);
> + ret = i3c_master_setdasa_locked(master, i3cdev->info.static_addr,
> + i3cdev->boardinfo->init_dyn_addr);
>   if (ret)
> - goto err_rstdaa;
> + goto err_setdasa;
>  
> - ret = i3c_master_retrieve_dev_info(dev);
> + i3cdev->info.dyn_addr = i3cdev->boardinfo->init_dyn_addr;
> + ret = i3c_master_reattach_i3c_dev(i3cdev, 0);
>   if (ret)
>   goto err_rstdaa;
>  
> - return;
> + ret = i3c_master_retrieve_dev_info(i3cdev);
> + if (ret)
> + goto err_rstdaa;
>  
>  err_rstdaa:
> - i3c_master_rstdaa_locked(master, dev->boardinfo->init_dyn_addr);
> + i3c_master_rstdaa_locked(master, i3cdev->boardinfo->init_dyn_addr);
> +err_setdasa:
> + i3c_master_detach_i3c_dev(i3cdev);
> + i3c_master_free_i3c_dev(i3cdev);
>  }
>  
>  static void
> @@ -1619,8 +1643,8 @@ static void i3c_master_detach_free_devs(struct 
> i3c_master_controller *master)
>   * This function is following all initialisation steps described in the I3C
>   * specification:
>   *
> - * 1. Attach I2C and statically defined I3C devs to the master so that the
> - *master can fill its 

Re: [PATCH] nand: raw: use write_oob_raw for MTD_OPS_AUTO_OOB mode

2020-05-12 Thread Boris Brezillon
On Tue, 12 May 2020 10:44:22 +0200
Miquel Raynal  wrote:

> Hello,
> 
> Richard, maybe you'll have an idea to fix the situation here?
> 
> Álvaro Fernández Rojas  wrote on Tue, 12 May 2020
> 10:36:25 +0200:
> 
> > Hi,
> >   
> > > El 11 may 2020, a las 18:29, Miquel Raynal  
> > > escribió:
> > > 
> > > Hello,
> > > 
> > > Boris Brezillon  wrote on Mon, 4 May
> > > 2020 12:32:37 +0200:
> > > 
> > >> On Mon,  4 May 2020 11:42:53 +0200
> > >> Álvaro Fernández Rojas  wrote:
> > >> 
> > >>> Some NAND controllers change the ECC bytes when OOB is written with ECC
> > >>> enabled.
> > >>> This is a problem in brcmnand, since adding JFFS2 cleanmarkers after 
> > >>> the page
> > >>> has been erased will change the ECC bytes to 0 and the controller will 
> > >>> think
> > >>> the block is bad.
> > >>> It can be fixed by using write_oob_raw, which ensures ECC is disabled.
> > >>> 
> > >>> Signed-off-by: Álvaro Fernández Rojas 
> > >>> ---
> > >>> drivers/mtd/nand/raw/nand_base.c | 2 +-
> > >>> 1 file changed, 1 insertion(+), 1 deletion(-)
> > >>> 
> > >>> diff --git a/drivers/mtd/nand/raw/nand_base.c 
> > >>> b/drivers/mtd/nand/raw/nand_base.c
> > >>> index c24e5e2ba130..755d25200520 100644
> > >>> --- a/drivers/mtd/nand/raw/nand_base.c
> > >>> +++ b/drivers/mtd/nand/raw/nand_base.c
> > >>> @@ -488,7 +488,7 @@ static int nand_do_write_oob(struct nand_chip 
> > >>> *chip, loff_t to,
> > >>> 
> > >>> nand_fill_oob(chip, ops->oobbuf, ops->ooblen, ops);
> > >>> 
> > >>> -   if (ops->mode == MTD_OPS_RAW)
> > >>> +   if (ops->mode == MTD_OPS_AUTO_OOB || ops->mode == MTD_OPS_RAW)
> > >>> status = chip->ecc.write_oob_raw(chip, page & 
> > >>> chip->pagemask);  
> > >> 
> > >> The doc says:
> > >> 
> > >> @MTD_OPS_PLACE_OOB:  OOB data are placed at the given offset (default)
> > >> @MTD_OPS_AUTO_OOB:   OOB data are automatically placed at the free areas
> > >> which are defined by the internal ecclayout
> > >> @MTD_OPS_RAW:data are transferred as-is, with no error
> > >>   correction; this mode implies %MTD_OPS_PLACE_OOB
> > >> 
> > >> To me, that means MTD_OPS_PLACE_OOB and MTD_OPS_AUTO_OOB do not imply
> > >> MTD_OPS_RAW. Anyway those modes are just too vague. We really should
> > >> separate the ECC-disabled/ECC-enabled concept (AKA raw vs non-raw mode)
> > >> from the OOB placement scheme. IIRC, Miquel had a patchset doing that.
> > >> 
> > >> We also should have the concept of protected OOB-region vs
> > >> unprotected-OOB-region if we want JFFS2 to work with controllers that
> > >> protect part of the OOB region. Once we have that we can patch JFFS2
> > >> to write things with "ECC-disabled"+"auto-OOB-placement-on-unprotected
> > >> area".
> > > 
> > > I see the problem but as Boris said the fix is not valid as-is.
> > > Problem is: I don't have a better proposal yet.
> > > 
> > > Is forcing JFFS2 to write cleanmarkers in raw mode only an option?
> > 
> > The doc says that for MTD_OPS_AUTO_OOB "the data is automatically placed at 
> > the free areas which are defined by the internal ecclayout”.
> > So, if we’re placing this data in the free OOB area left by the ECC bytes 
> > it means that this automatically placed data won’t be error correctable, 
> > since it’s in the OOB, and the OOB data isn’t error corrected, right?  
> 
> No, free bytes sometimes are and sometimes are not covered by the ECC
> engine. It depends on the controller.
> 
> > The problem is that "flash_erase -j” uses MTD_OPS_AUTO_OOB to write the OOB 
> > JFFS2 clean markers and if this is written with ECC enabled the NAND 
> > controller will change the ECC bytes to an invalid value (or at least 
> > brcmnand controller).
> > 
> > Another option could be adding another mode, something like 
> > MTD_OPS_AUTO_OOB_RAW and using it in mtd-utils and JFFS2.  
> 
> No, these modes already are completely wrong, I must resend my series
> fixing them.
> 

Totally agree with Miquel on that one: let's fix the
write/read/ecc-layout semantics instead of adding more obscure modes.


Re: [PATCH v7 1/7] i3c: master: secondary master initialization document

2020-05-12 Thread Boris Brezillon
On Tue, 12 May 2020 05:03:32 +
Parshuram Raju Thombare  wrote:

> >> Document describing secondary master initialization,
> >> mastership handover and DEFSLVS handling processes.  
> >
> >Thanks for doing that, but you probably didn't try to compile the doc
> >(the formatting is all messed up).
> >
> ># make htmldocs  
> 
> Yes, it looks messed in email but I built html format of doc and formatting 
> was ok.

I did build the html doc and it's not ok here.

> May be because some tab/space issue it is looking  messed up in email.

No, it's really the html output I'm complaining about.


Re: [PATCH v7 4/7] i3c: master: add mastership handover support

2020-05-11 Thread Boris Brezillon
On Mon, 11 May 2020 15:14:49 +0200
Parshuram Thombare  wrote:

> Added mastership acquire and yield functions.
> 
> Signed-off-by: Parshuram Thombare 
> ---
>  drivers/i3c/master.c   | 187 +++--
>  include/linux/i3c/master.h |  23 +
>  2 files changed, 201 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
> index 669bd7e45810..9c8250a6a2b0 100644
> --- a/drivers/i3c/master.c
> +++ b/drivers/i3c/master.c
> @@ -16,6 +16,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #include "internals.h"
>  
> @@ -467,6 +468,79 @@ static const char * const i3c_bus_mode_strings[] = {
>   [I3C_BUS_MODE_MIXED_SLOW] = "mixed-slow",
>  };
>  
> +static int i3c_master_enable_mr_events(struct i3c_master_controller *master)
> +{
> + int ret;
> +
> + master->ops->enable_mr_events(master);
> + i3c_bus_maintenance_lock(>bus);
> + ret = i3c_master_enec_locked(master, I3C_BROADCAST_ADDR,
> +  I3C_CCC_EVENT_MR | I3C_CCC_EVENT_HJ);
> + i3c_bus_maintenance_unlock(>bus);
> +
> + return ret;
> +}
> +
> +static int check_event_da_update(struct i3c_master_controller *m)
> +{
> + return m->ops->check_event_set(m, I3C_SLV_DA_UPDATE);
> +}
> +
> +static int check_event_mr_done(struct i3c_master_controller *m)
> +{
> + return m->ops->check_event_set(m, I3C_SLV_MR_DONE);
> +}
> +
> +/**
> + * i3c_master_acquire_bus() - acquire I3C bus mastership
> + * @m: I3C master object
> + *
> + * This function may sleep.
> + * It is expected to be called with normaluse_lock.
> + */
> +static int i3c_master_acquire_bus(struct i3c_master_controller *m)
> +{
> + int ret = 0;
> + u32 val;
> +
> + /*
> +  * Request mastership needs maintenance(write) lock. So, to avoid
> +  * deadlock, release normaluse(read) lock, which is expected to be
> +  * held before calling this function.
> +  * normaluse(read) lock is expected to be held before calling
> +  * this function to avoid race with maintenance activities
> +  * like DEFSLVS processing etc
> +  */
> + i3c_bus_normaluse_unlock(>bus);
> + i3c_bus_maintenance_lock(>bus);
> +
> + if (m->this && m->this == m->bus.cur_master) {
> + i3c_master_disec_locked(m, I3C_BROADCAST_ADDR,
> + I3C_CCC_EVENT_MR |
> + I3C_CCC_EVENT_HJ);
> + goto mr_req_done;
> + }
> +
> + ret = readx_poll_timeout(check_event_da_update, m, val,
> +  val, 100, 100);
> + if (ret)
> + goto mr_req_done;
> +
> + ret = m->ops->request_mastership(m);
> + if (ret)
> + goto mr_req_done;
> +
> + ret = readx_poll_timeout(check_event_mr_done, m, val,
> +  val, 100, 100);

Those waits should be done in the master driver. Pass a timeout to
->request_master() or make it a property of the i3c_master_controller
if you like, but don't poll the status from the core.

> + if (!ret)
> + m->bus.cur_master = m->this;
> +
> +mr_req_done:
> + i3c_bus_maintenance_unlock(>bus);
> + i3c_bus_normaluse_lock(>bus);

You should downgrade the lock instead of releasing it. I really need to
get my head around this locking scheme because I'm pretty sure we had
good reasons for the locking/unlocking dance Przemek had in his series.

> + return ret;
> +}
> +
>  static ssize_t mode_show(struct device *dev,
>struct device_attribute *da,
>char *buf)
> @@ -685,6 +759,33 @@ static int i3c_master_send_ccc_cmd_locked(struct 
> i3c_master_controller *master,
>   return 0;
>  }
>  
> +static int i3c_master_get_accmst_locked(struct i3c_master_controller *master,
> + u8 addr)
> +{
> + struct i3c_ccc_getaccmst *accmst;
> + struct i3c_ccc_cmd_dest dest;
> + struct i3c_ccc_cmd cmd;
> + int ret;
> +
> + accmst = i3c_ccc_cmd_dest_init(, addr, sizeof(*accmst));
> + if (!accmst)
> + return -ENOMEM;
> +
> + i3c_ccc_cmd_init(, true, I3C_CCC_GETACCMST, , 1);
> +
> + ret = i3c_master_send_ccc_cmd_locked(master, );
> + if (ret)
> + goto out;
> +
> + if (dest.payload.len != sizeof(*accmst))
> + ret = -EIO;
> +
> +out:
> + i3c_ccc_cmd_dest_cleanup();
> +
> + return ret;
> +}
> +
>  static struct i2c_dev_desc *
>  i3c_master_find_i2c_dev_by_addr(const struct i3c_master_controller *master,
>   u16 addr)
> @@ -1558,10 +1659,6 @@ int i3c_master_set_info(struct i3c_master_controller 
> *master,
>   if (!i3c_bus_dev_addr_is_avail(>bus, info->dyn_addr))
>   return -EINVAL;
>  
> - if (I3C_BCR_DEVICE_ROLE(info->bcr) == I3C_BCR_I3C_MASTER &&
> - master->secondary)
> - return -EINVAL;
> -
>   if (master->this)
>   return 

Re: [PATCH v7 3/7] i3c: master: add i3c_secondary_master_register

2020-05-11 Thread Boris Brezillon
On Mon, 11 May 2020 15:13:53 +0200
Parshuram Thombare  wrote:

> add i3c_secondary_master_register which is used
> to register secondary masters.
> 
> Signed-off-by: Parshuram Thombare 
> ---
>  drivers/i3c/master.c   | 154 -
>  include/linux/i3c/master.h |   3 +
>  2 files changed, 156 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
> index ba07a7d49633..669bd7e45810 100644
> --- a/drivers/i3c/master.c
> +++ b/drivers/i3c/master.c
> @@ -1768,6 +1768,90 @@ static int i3c_master_bus_init(struct 
> i3c_master_controller *master)
>   return ret;
>  }
>  
> +/**
> + * i3c_secondary_master_bus_init() - initialize an I3C bus for secondary
> + * master
> + * @master: secondary master initializing the bus
> + *
> + * This function does
> + *
> + * 1. Attach I2C devs to the master
> + *
> + * 2. Call _master_controller_ops->bus_init() method to initialize
> + *the master controller. That's usually where the bus mode is selected
> + *(pure bus or mixed fast/slow bus)

Can you really select the bus mode without knowing the I3C devices you
have on the bus? Or maybe that's a preliminary initialization which is
then updated when you receive DEFSLVS events.

> + *
> + * Once this is done, I2C devices should be usable.

I suspect you'll have to request bus ownership first, which means
they're not really usable, just registered to the I2C subsystem. This
might lead to a whole bunch of problems when drivers will try to send
messages to the I2C devices and receive ETIMEDOUT/EBUSY errors. We'll
probably need some updates to the I2C framework if we want I2C to play
nicely with bus handover, but I think we can keep that for later. I'd
suggest to forget about I2C for now and mark that as a limitation (no
I2C devs on secondary masters).

> + *
> + * Return: a 0 in case of success, an negative error code otherwise.
> + */
> +static int i3c_secondary_master_bus_init(struct i3c_master_controller 
> *master)
> +{
> + enum i3c_addr_slot_status status;
> + struct i2c_dev_boardinfo *i2cboardinfo;
> + struct i2c_dev_desc *i2cdev;
> + int ret;
> +
> + /*
> +  * First attach all devices with static definitions provided by the
> +  * FW.
> +  */
> + list_for_each_entry(i2cboardinfo, >boardinfo.i2c, node) {
> + status = i3c_bus_get_addr_slot_status(>bus,
> +   i2cboardinfo->base.addr);
> + if (status != I3C_ADDR_SLOT_FREE) {
> + ret = -EBUSY;
> + goto err_detach_devs;
> + }
> +
> + i3c_bus_set_addr_slot_status(>bus,
> +  i2cboardinfo->base.addr,
> +  I3C_ADDR_SLOT_I2C_DEV);
> +
> + i2cdev = i3c_master_alloc_i2c_dev(master, i2cboardinfo);
> + if (IS_ERR(i2cdev)) {
> + ret = PTR_ERR(i2cdev);
> + goto err_detach_devs;
> + }
> +
> + ret = i3c_master_attach_i2c_dev(master, i2cdev);
> + if (ret) {
> + i3c_master_free_i2c_dev(i2cdev);
> + goto err_detach_devs;
> + }
> + }
> +
> + /*
> +  * Now execute the controller specific ->bus_init() routine, which
> +  * might configure its internal logic to match the bus limitations.
> +  */
> + ret = master->ops->bus_init(master);
> + if (ret)
> + goto err_detach_devs;
> +
> + /*
> +  * The master device should have been instantiated in ->bus_init(),
> +  * complain if this was not the case.
> +  */
> + if (!master->this) {
> + dev_err(>dev,
> + "master_set_info() was not called in ->bus_init()\n");
> + ret = -EINVAL;
> + goto err_bus_cleanup;
> + }
> +
> + return 0;
> +
> +err_bus_cleanup:
> + if (master->ops->bus_cleanup)
> + master->ops->bus_cleanup(master);
> +
> +err_detach_devs:
> + i3c_master_detach_free_devs(master);
> +
> + return ret;
> +}
> +
>  static void i3c_master_bus_cleanup(struct i3c_master_controller *master)
>  {
>   if (master->ops->bus_cleanup)
> @@ -2457,7 +2541,10 @@ static int i3c_master_init(struct 
> i3c_master_controller *master,
>   goto err_put_dev;
>   }
>  
> - ret = i3c_master_bus_init(master);
> + if (secondary)
> + ret = i3c_secondary_master_bus_init(master);
> + else
> + ret = i3c_master_bus_init(master);
>   if (ret)
>   goto err_put_dev;
>  
> @@ -2535,6 +2622,71 @@ int i3c_master_register(struct i3c_master_controller 
> *master,
>  }
>  EXPORT_SYMBOL_GPL(i3c_master_register);
>  
> +/**
> + * i3c_secondary_master_register() - register an I3C secondary master
> + * @master: master used to send frames on the bus
> + * @parent: the parent device (the one that 

Re: [PATCH v7 1/7] i3c: master: secondary master initialization document

2020-05-11 Thread Boris Brezillon
On Mon, 11 May 2020 15:12:39 +0200
Parshuram Thombare  wrote:

> Document describing secondary master initialization,
> mastership handover and DEFSLVS handling processes.

Thanks for doing that, but you probably didn't try to compile the doc
(the formatting is all messed up).

# make htmldocs

and then check the output in Documentation/output/ (open index.html
with a web-browser and go to the i3c section).

> 
> Signed-off-by: Parshuram Thombare 
> ---
>  Documentation/driver-api/i3c/index.rst|   1 +
>  .../i3c/secondary-master-initialization.rst   | 118 ++
>  2 files changed, 119 insertions(+)
>  create mode 100644 
> Documentation/driver-api/i3c/secondary-master-initialization.rst
> 
> diff --git a/Documentation/driver-api/i3c/index.rst 
> b/Documentation/driver-api/i3c/index.rst
> index 783d6dad054b..af2a0aa68f5b 100644
> --- a/Documentation/driver-api/i3c/index.rst
> +++ b/Documentation/driver-api/i3c/index.rst
> @@ -9,3 +9,4 @@ I3C subsystem
> protocol
> device-driver-api
> master-driver-api
> +   secondary-master-initialization
> diff --git a/Documentation/driver-api/i3c/secondary-master-initialization.rst 
> b/Documentation/driver-api/i3c/secondary-master-initialization.rst
> new file mode 100644
> index ..9d1869550807
> --- /dev/null
> +++ b/Documentation/driver-api/i3c/secondary-master-initialization.rst
> @@ -0,0 +1,118 @@
> +.. SPDX-License-Identifier: GPL-2.0
> +
> +===
> +I3C Secondary Master Initialization
> +===
> +
> ++-+---+
> +| **Main master** | **Secondary master** 
>  |
> ++=+===+
> +| |  
>  |
> +| | Do I3C master controller specific | | Do I3C master controller 
> specefic   |
> +|   initialization.   |   initialization, except 
> enabling |
> +| |   the DEFSLVS interrupt. 
>  |
> +| | Call i3c_master_register  | | Call 
> i3c_secondary_master_register  |
> +| |  
>  |
> +|   *i3c_master_register* |   
> *i3c_secondary_master_register* |
> +|| Initialize I3C master controller   || Initialize I3C master 
> controller |
> +|  object.|  object. 
>  |
> +|| Scan I3C and I2C devices from DTS. || Scan I2C devices from DTS.  
>  |
> +|| Set appropriate bus mode based on  || Set appropriate bus mode 
> based on|
> +|  I2C devices information.   |  I3C and I2C devices 
> information. |
> +|| Create a work queue.   || Create a work queue.
>  |
> +|| Call i3c_master_bus_init   || Call 
> i3c_secondary_master_bus_init   |
> +| |  
>  |
> +|  *i3c_master_bus_init*  |  
> *i3c_secondary_master_bus_init*  |
> +|   | Call bus_init to do controller  |   | Call bus_init to do 
> controller|
> +| specific bus initialization and | specific bus 
> initialization and   |
> +| enabling the controller.| enabling the controller. 
>  |
> +|   | Create I3C device representing a|   | Create I3C device 
> representing a  |
> +| master and add it to the I3C| master and add it to the 
> I3C  |
> +| device list.| device list. 
>  |
> +|   | Set current master to the device|  
>  |
> +| created to represent I3C master || Allocate memory for 
> 'defslvs_data',  |
> +| device. |  that will be used to pass 
> I3C|
> +|   | Reset all dynamic address that  |  device list received in 
> DEFSLVS  |
> +| may have been assigned before.  |  to I3C core DEFSLVS 
> processing   |
> +|   | Disable all slave events before || Add I3C device representing 
> this |
> +| starting DAA.   |  master to the system.   
>  |
> +|   | Pre-assign dynamic address and  || Expose our I3C bus as an 
> I2C adapter |
> +| retrieve device information if  |  so that I2C devices are 
> exposed  |
> +| needed. |  through the I2C subsystem.  
>  |
> +|   | Do dynamic address assignment to|  
>  |
> +| all I3C devices currenly present| | 

Re: [PATCH v7 2/7] i3c: master: use i3c_master_register only for main master

2020-05-11 Thread Boris Brezillon
On Mon, 11 May 2020 15:13:05 +0200
Parshuram Thombare  wrote:

> Removed last argument 'secondary' and refactored
> i3c_master_register to move code that can be common
> to i3c_secondary_master_register to separate function
> i3c_master_init.
> 
> Signed-off-by: Parshuram Thombare 
> ---
>  drivers/i3c/master.c | 69 +---
>  drivers/i3c/master/dw-i3c-master.c   |  2 +-
>  drivers/i3c/master/i3c-master-cdns.c |  2 +-
>  include/linux/i3c/master.h   |  3 +-
>  4 files changed, 46 insertions(+), 30 deletions(-)
> 
> diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
> index 5f4bd52121fe..ba07a7d49633 100644
> --- a/drivers/i3c/master.c
> +++ b/drivers/i3c/master.c
> @@ -2391,31 +2391,10 @@ static int i3c_master_check_ops(const struct 
> i3c_master_controller_ops *ops)
>   return 0;
>  }
>  
> -/**
> - * i3c_master_register() - register an I3C master
> - * @master: master used to send frames on the bus
> - * @parent: the parent device (the one that provides this I3C master
> - *   controller)
> - * @ops: the master controller operations
> - * @secondary: true if you are registering a secondary master. Will return
> - *  -ENOTSUPP if set to true since secondary masters are not yet
> - *  supported
> - *
> - * This function takes care of everything for you:
> - *
> - * - creates and initializes the I3C bus
> - * - populates the bus with static I2C devs if @parent->of_node is not
> - *   NULL
> - * - registers all I3C devices added by the controller during bus
> - *   initialization
> - * - registers the I2C adapter and all I2C devices
> - *
> - * Return: 0 in case of success, a negative error code otherwise.
> - */
> -int i3c_master_register(struct i3c_master_controller *master,
> - struct device *parent,
> - const struct i3c_master_controller_ops *ops,
> - bool secondary)
> +static int i3c_master_init(struct i3c_master_controller *master,
> +struct device *parent,
> +const struct i3c_master_controller_ops *ops,
> +bool secondary)
>  {
>   struct i3c_bus *i3cbus = i3c_master_get_bus(master);
>   enum i3c_bus_mode mode = I3C_BUS_MODE_PURE;
> @@ -2482,6 +2461,45 @@ int i3c_master_register(struct i3c_master_controller 
> *master,
>   if (ret)
>   goto err_put_dev;
>  
> + return 0;
> +
> +err_put_dev:
> + put_device(>dev);
> +
> + return ret;
> +}
> +
> +/**
> + * i3c_master_register() - register an I3C master

The function should be renamed and the doc updated to reflect the fact
that it only works for primary masters:

i3c_primary_master_register() - register a primary I3C master

> + * @master: master used to send frames on the bus
> + * @parent: the parent device (the one that provides this I3C master
> + *   controller)
> + * @ops: the master controller operations
> + * @secondary: true if you are registering a secondary master. Will return
> + *  -ENOTSUPP if set to true since secondary masters are not yet
> + *  supported

This argument no longer exists.

> + *
> + * This function takes care of everything for you:
> + *
> + * - creates and initializes the I3C bus
> + * - populates the bus with static I2C devs if @parent->of_node is not
> + *   NULL
> + * - registers all I3C devices added by the controller during bus
> + *   initialization
> + * - registers the I2C adapter and all I2C devices
> + *
> + * Return: 0 in case of success, a negative error code otherwise.
> + */
> +int i3c_master_register(struct i3c_master_controller *master,
> + struct device *parent,
> + const struct i3c_master_controller_ops *ops)
> +{
> + int ret;
> +
> + ret = i3c_master_init(master, parent, ops, false);
> + if (ret)
> + return ret;
> +
>   ret = device_add(>dev);
>   if (ret)
>   goto err_cleanup_bus;
> @@ -2511,7 +2529,6 @@ int i3c_master_register(struct i3c_master_controller 
> *master,
>  err_cleanup_bus:
>   i3c_master_bus_cleanup(master);
>  
> -err_put_dev:
>   put_device(>dev);
>  
>   return ret;
> diff --git a/drivers/i3c/master/dw-i3c-master.c 
> b/drivers/i3c/master/dw-i3c-master.c
> index 1d83c97431c7..5d5a8a90ec06 100644
> --- a/drivers/i3c/master/dw-i3c-master.c
> +++ b/drivers/i3c/master/dw-i3c-master.c
> @@ -1158,7 +1158,7 @@ static int dw_i3c_probe(struct platform_device *pdev)
>   master->free_pos = GENMASK(master->maxdevs - 1, 0);
>  
>   ret = i3c_master_register(>base, >dev,
> -   _mipi_i3c_ops, false);
> +   _mipi_i3c_ops);
>   if (ret)
>   goto err_assert_rst;
>  
> diff --git a/drivers/i3c/master/i3c-master-cdns.c 
> b/drivers/i3c/master/i3c-master-cdns.c
> index 8889a4fdb454..ed4f43807f9e 100644
> --- a/drivers/i3c/master/i3c-master-cdns.c
> +++ 

Re: [PATCH v4 00/16] mtd: spi-nor: add xSPI Octal DTR support

2020-05-11 Thread Boris Brezillon
On Mon, 11 May 2020 09:00:35 +
 wrote:

> Hi, Pratyush, Boris,
> 
> On Friday, April 24, 2020 9:43:54 PM EEST Pratyush Yadav wrote:
> > This series adds support for octal DTR flashes in the spi-nor framework,  
> 
> I'm still learning about this, but I can give you my 2 cents as of now, to 
> open the discussion. Enabling 2-2-2, 4-4-4, and 8-8-8 modes is dangerous 
> because the flash may not recover from unexpected resets. Entering one of 
> these modes can be:
> 1/ volatile selectable, the device return to the 1-1-1 protocol after the 
> next 
> power-on. I guess this is conditioned by the optional RESET pin, but I'll 
> have 
> to check. Also the flash can return to the 1-1-1 mode using the software 
> reset 
> or through writing to its Configuration Register, without power-on or power-
> off.

My understanding is that there's no standard software reset procedure
that guarantees no conflict with existing 1S commands, so even the
software reset approach doesn't work here.

> 2/ non-volatile selectable in which RESET# and software reset are useless, 
> the 
> flash defaults to the mode selected in the non volatile Configuration 
> Register 
> bits. The only way to get back to 1-1-1 is to write to the Configuration 
> Register.

I'm less worried about this case though, since I'd expect the ROM
code and bootloaders to be able to deal with xD-xD-xD modes when the
flash is set in this mode by default. That implies letting Linux know
about this default mode of course, maybe through an extra DT
property/cmdline param.

> 
> Not recovering from unexpected resets is unacceptable. One should always 
> prefer option 1/ and condition the entering in 2-2-2, 4-4-4 and 8-8-8 with 
> the 
> presence of the optional RESET pin.

Totally agree with you on that one, but we know what happens in
practice...

> 
> For the unfortunate flashes that support just option 2/, we should not enter 
> these modes on our own, just by discovering the capabilities from the SFDP 
> tables or by the flags in the flash_info struct. The best we can do for them 
> is to move the responsibility to the user. Maybe to add a Kconfig option that 
> is disabled by default with which we condition the entering in 2-2-2, 4-4-4 
> or 
> 8-8-8 modes.

Hm, a Kconfig option doesn't sound like the right solution to the
problem, since it should be a per-flash decision, not something you set
system-wise.

> Once entered in one of these modes, if an unexpected reset comes, 
> you most likely are doomed, because early stage bootloaders may not work in 
> these modes and you'll not be able to boot the board. Assuming that one uses 
> other environment to boot the board, we should at least make sure that the 
> flash works in linux after an unexpected reset. We should try to determine in 
> which mode we are at init, so maybe an extension of the default_init hook is 
> needed. But all this looks like a BIG compromise, I'm not yet sure if we 
> should adress 2/. Thoughts?

We should definitely not write non-volatile regs on our own, but
instead use the mode that's been chosen there. I doubt anyone
setting the non-volative conf to 8D-8D-8D will ever want to go back to
1S-1S-1S anyway, so 8D -> 1S transitions are not really an issue, right?

Of course, that still leaves us with the 'mode detection' issue, and I
have no solution other than flagging it through the DT/cmdline for that
one...


Re: [PATCH v5 2/2] mtd: rawnand: Add NAND controller support on Intel LGM SoC

2020-05-07 Thread Boris Brezillon
On Thu, 7 May 2020 14:38:52 +0800
"Ramuthevar, Vadivel MuruganX"
 wrote:

> Hi Boris,
> 
>Thank you very much for the review comments and your time...
> 
> On 7/5/2020 2:27 pm, Boris Brezillon wrote:
> > On Thu, 7 May 2020 14:13:42 +0800
> > "Ramuthevar, Vadivel MuruganX"
> >  wrote:
> >   
> >> Hi Boris,
> >>
> >>  Thank you very much for the review comments and your time...
> >>
> >> On 7/5/2020 1:28 pm, Boris Brezillon wrote:  
> >>> On Thu,  7 May 2020 08:15:37 +0800
> >>> "Ramuthevar,Vadivel MuruganX"
> >>>  wrote:
> >>>  
> >>>> +reg = readl(ebu_host->ebu + EBU_ADDR_SEL(ebu_host->cs_num));
> >>>> +writel(reg | EBU_ADDR_MASK(5) | EBU_ADDR_SEL_REGEN,
> >>>> +   ebu_host->ebu + EBU_ADDR_SEL(ebu_host->cs_num));  
> >>>
> >>> Seriously, did you really think I would not notice what you're doing
> >>> here?  
> >> Yes , I know that you have very good understanding about this.
> >>You're reading the previous value which either contains a default  
> >>> mapping or has the mapping set by the bootloader, and write it back to
> >>> the register along with a new mask and the REGEN bit set (which
> >>> BTW is wrong since you don't mask out other fields before updating
> >>> them).  
> >> There is no other field get overwritten
> >>This confirms that this Core -> FPI address translation exists  
> >>> and has to be set properly, so please stop lying about that.  
> >>
> >> Sorry, there is no SW translation, as I have mentioned that it's
> >> optional only, for safer side , reading and writing the default values.  
> > 
> > Then write EBU_ADDR_SEL_REGEN and we'll if see that works. I suspect it
> > won't.  
> 
> You mean, without reading just writing EBU_ADDR_SEL_REGEN bit alone in 
> EBU_ADDR_SELx , as you said it won't work because it overwrites 0x174 
> with 0x0 values so BASE is lost.

Which confirms that this mapping has to be defined.

> either we can leave it or read & write with ORed | EBU_ADDR_SEL_REGEN

None of this is acceptable IMO. You have to build the value based on the
address translation described in the DT. Why are you so reluctant to
this approach?

> 
> Please correct me if anything is wrong, Thanks!
> >   
> >> The memory region to enabled that's my concern so written the same
> >> register values.  
> > 
> > I don't buy that, sorry.
> >   
> >>
> >> This will not be impact other fields, so please see below for reference
> >>
> >> The EBU Address Select Registers EBU_ADDR_SEL_0 to EBU_ADDSEL3 establish
> >> and control memory regions for external accesses.
> >>
> >> Reset Value: 1741H  
> > 
> > See, as suspected the reset value is exactly what you expect.  
> 
> Yes , that's the reason said being optional.

Then it's not optional. It just works because you use the default
value.


Re: [PATCH v5 2/2] mtd: rawnand: Add NAND controller support on Intel LGM SoC

2020-05-07 Thread Boris Brezillon
On Thu, 7 May 2020 14:13:42 +0800
"Ramuthevar, Vadivel MuruganX"
 wrote:

> Hi Boris,
> 
> Thank you very much for the review comments and your time...
> 
> On 7/5/2020 1:28 pm, Boris Brezillon wrote:
> > On Thu,  7 May 2020 08:15:37 +0800
> > "Ramuthevar,Vadivel MuruganX"
> >  wrote:
> >   
> >> +  reg = readl(ebu_host->ebu + EBU_ADDR_SEL(ebu_host->cs_num));
> >> +  writel(reg | EBU_ADDR_MASK(5) | EBU_ADDR_SEL_REGEN,
> >> + ebu_host->ebu + EBU_ADDR_SEL(ebu_host->cs_num));  
> > 
> > Seriously, did you really think I would not notice what you're doing
> > here?  
> Yes , I know that you have very good understanding about this.
>   You're reading the previous value which either contains a default
> > mapping or has the mapping set by the bootloader, and write it back to
> > the register along with a new mask and the REGEN bit set (which
> > BTW is wrong since you don't mask out other fields before updating
> > them).  
> There is no other field get overwritten
>   This confirms that this Core -> FPI address translation exists
> > and has to be set properly, so please stop lying about that.  
> 
> Sorry, there is no SW translation, as I have mentioned that it's 
> optional only, for safer side , reading and writing the default values.

Then write EBU_ADDR_SEL_REGEN and we'll if see that works. I suspect it
won't.

> The memory region to enabled that's my concern so written the same 
> register values.

I don't buy that, sorry.

> 
> This will not be impact other fields, so please see below for reference
> 
> The EBU Address Select Registers EBU_ADDR_SEL_0 to EBU_ADDSEL3 establish 
> and control memory regions for external accesses.
> 
> Reset Value: 1741H

See, as suspected the reset value is exactly what you expect.



Re: [PATCH v5 2/2] mtd: rawnand: Add NAND controller support on Intel LGM SoC

2020-05-06 Thread Boris Brezillon
On Thu,  7 May 2020 08:15:37 +0800
"Ramuthevar,Vadivel MuruganX"
 wrote:

> + reg = readl(ebu_host->ebu + EBU_ADDR_SEL(ebu_host->cs_num));
> + writel(reg | EBU_ADDR_MASK(5) | EBU_ADDR_SEL_REGEN,
> +ebu_host->ebu + EBU_ADDR_SEL(ebu_host->cs_num));

Seriously, did you really think I would not notice what you're doing
here? You're reading the previous value which either contains a default
mapping or has the mapping set by the bootloader, and write it back to
the register along with a new mask and the REGEN bit set (which
BTW is wrong since you don't mask out other fields before updating
them). This confirms that this Core -> FPI address translation exists
and has to be set properly, so please stop lying about that.


Re: [PATCH v2 0/5] mtd: spi-nor: Add support for Octal 8D-8D-8D mode

2020-05-05 Thread Boris Brezillon
On Tue, 5 May 2020 11:44:43 +0200
Boris Brezillon  wrote:

> On Tue, 5 May 2020 17:31:45 +0800
> masonccy...@mxic.com.tw wrote:
> 
> 
> > > > > > I quickly went through your patches but can't reply them in each
> > > > > >  
> > your   
> > > > > > patches.
> > > > > > 
> > > > > > i.e,.
> > > > > > 1) [v4,03/16] spi: spi-mem: allow specifying a command's extension
> > > > > > 
> > > > > > -u8 opcode;
> > > > > > +u16 opcode;
> > > > > > 
> > > > > > big/little Endian issue, right? 
> > > > > > why not just u8 ext_opcode;
> > > > > > No any impact for exist code and actually only xSPI device use 
> > > > extension 
> > > > > > command.
> > > > > 
> > > > > Boris already explained the reasoning behind it.
> > > > 
> > > > yup, I got his point and please make sure CPU data access.
> > > > 
> > > > i.e,.
> > > > Fix endianness of the BFPT DWORDs and xSPI in sfdp.c
> > > > 
> > > > and your patch,
> > > > +ext = spi_nor_get_cmd_ext(nor, op);
> > > > +op->cmd.opcode = (op->cmd.opcode <<
> > > >  
> > 8) |   
> > > > ext;
> > > > +op->cmd.nbytes = 2;
> > > > 
> > > > I think maybe using u8 opcode[2] could avoid endianness.
> > > 
> > > Again, thanks Boris for answering this. FWIW, I don't see anything wrong  
> > >
> >   
> > > with his suggestion.
> > > 
> > > To clarify a bit more, the idea is that we transmit the opcode MSB 
> > > first, just we do for the address. Assume we want to issue the command 
> > > 0x05. In 1S mode, we set cmd.opcode to 0x05. Here cmd.nbytes == 1. Treat  
> > >
> >   
> > > is as a 1-byte value, so the MSB is the same as the LSB. We directly 
> > > send 0x5 on the bus.
> > 
> > There are many SPI controllers driver use "op->cmd.opcode" directly,
> > so is spi-mxic.c.
> > 
> > i.e,.
> > ret = mxic_spi_data_xfer(mxic, >cmd.opcode, NULL, op->cmd.nbytes);  
> 
> Just because you do it doesn't mean it's right. And most controllers use
> the opcode value, they don't dereference the pointer as you do here.
> 
> >   
> > > 
> > > If cmd.nbytes == 2, then the opcode would be 0x05FA (assuming extension 
> > > is invert of command). So we send the MSB (0x05) first, and LSB (0xFA) 
> > > next.
> > 
> > My platform is Xilinx Zynq platform which CPU is ARMv7 processor.
> > 
> > In 1-1-1 mode, it's OK to send 1 byte command by u16 opcode but
> > in 8D-8D-8D mode, I need to patch
> > 
> > i.e.,
> > op->cmd.opcode = op->cmd.opcode | (ext << 8);
> > 
> > rather than your patch.  
> 
> Seriously, how hard is it to extract each byte from the u16 if your
> controller needs to pass things in a different order? I mean, that's
> already how it's done for the address cycle, so why is it a problem
> here? This sounds like bikeshedding to me. If the order is properly
> documented in the kernel doc, I see no problem having it grouped in one
> u16, with the first cmd cycle placed in the MSB and the second one in
> the LSB.

So, I gave it a try, and we're talking about something as simple as the
below diff. And yes, the mxic controller needs to be patched before
extending the cmd.opcode field, but we're talking about one driver here
(all other drivers should be fine). Oh, and if you look a few lines below
the changed lines, you'll notice that we do exactly the same for the
address.

--->8---
diff --git a/drivers/spi/spi-mxic.c b/drivers/spi/spi-mxic.c
index 69491f3a515d..c3f4136a7c1d 100644
--- a/drivers/spi/spi-mxic.c
+++ b/drivers/spi/spi-mxic.c
@@ -356,6 +356,7 @@ static int mxic_spi_mem_exec_op(struct spi_mem *mem,
int nio = 1, i, ret;
u32 ss_ctrl;
u8 addr[8];
+   u8 cmd[2];
 
ret = mxic_spi_set_freq(mxic, mem->spi->max_speed_hz);
if (ret)
@@ -393,7 +394,10 @@ static int mxic_spi_mem_exec_op(struct spi_mem *mem,
writel(readl(mxic->regs + HC_CFG) | HC_CFG_MAN_CS_ASSERT,
   mxic->regs + HC_CFG);
 
-   ret = mxic_spi_data_xfer(mxic, >cmd.opcode, NULL, 1);
+   for (i = 0; i < op->cmd.nbytes; i++)
+   cmd[i] = op->cmd.opcode >> (8 * (op->cmd.nbytes - i - 1));
+
+   ret = mxic_spi_data_xfer(mxic, cmd, NULL, op->cmd.nbytes);
if (ret)
goto out;
 


Re: [PATCH v2 0/5] mtd: spi-nor: Add support for Octal 8D-8D-8D mode

2020-05-05 Thread Boris Brezillon
On Tue, 5 May 2020 17:31:45 +0800
masonccy...@mxic.com.tw wrote:


> > > > > I quickly went through your patches but can't reply them in each   
> your 
> > > > > patches.
> > > > > 
> > > > > i.e,.
> > > > > 1) [v4,03/16] spi: spi-mem: allow specifying a command's extension
> > > > > 
> > > > > -u8 opcode;
> > > > > +u16 opcode;
> > > > > 
> > > > > big/little Endian issue, right? 
> > > > > why not just u8 ext_opcode;
> > > > > No any impact for exist code and actually only xSPI device use   
> > > extension   
> > > > > command.  
> > > > 
> > > > Boris already explained the reasoning behind it.  
> > > 
> > > yup, I got his point and please make sure CPU data access.
> > > 
> > > i.e,.
> > > Fix endianness of the BFPT DWORDs and xSPI in sfdp.c
> > > 
> > > and your patch,
> > > +ext = spi_nor_get_cmd_ext(nor, op);
> > > +op->cmd.opcode = (op->cmd.opcode <<   
> 8) | 
> > > ext;
> > > +op->cmd.nbytes = 2;
> > > 
> > > I think maybe using u8 opcode[2] could avoid endianness.  
> > 
> > Again, thanks Boris for answering this. FWIW, I don't see anything wrong   
> 
> > with his suggestion.
> > 
> > To clarify a bit more, the idea is that we transmit the opcode MSB 
> > first, just we do for the address. Assume we want to issue the command 
> > 0x05. In 1S mode, we set cmd.opcode to 0x05. Here cmd.nbytes == 1. Treat   
> 
> > is as a 1-byte value, so the MSB is the same as the LSB. We directly 
> > send 0x5 on the bus.  
> 
> There are many SPI controllers driver use "op->cmd.opcode" directly,
> so is spi-mxic.c.
> 
> i.e,.
> ret = mxic_spi_data_xfer(mxic, >cmd.opcode, NULL, op->cmd.nbytes);

Just because you do it doesn't mean it's right. And most controllers use
the opcode value, they don't dereference the pointer as you do here.

> 
> > 
> > If cmd.nbytes == 2, then the opcode would be 0x05FA (assuming extension 
> > is invert of command). So we send the MSB (0x05) first, and LSB (0xFA) 
> > next.  
> 
> My platform is Xilinx Zynq platform which CPU is ARMv7 processor.
> 
> In 1-1-1 mode, it's OK to send 1 byte command by u16 opcode but
> in 8D-8D-8D mode, I need to patch
> 
> i.e.,
> op->cmd.opcode = op->cmd.opcode | (ext << 8);
> 
> rather than your patch.

Seriously, how hard is it to extract each byte from the u16 if your
controller needs to pass things in a different order? I mean, that's
already how it's done for the address cycle, so why is it a problem
here? This sounds like bikeshedding to me. If the order is properly
documented in the kernel doc, I see no problem having it grouped in one
u16, with the first cmd cycle placed in the MSB and the second one in
the LSB.


Re: [PATCH v4 2/2] mtd: rawnand: Add NAND controller support on Intel LGM SoC

2020-05-05 Thread Boris Brezillon
Hello Vadivel,

On Tue, 5 May 2020 13:28:58 +0800
"Ramuthevar, Vadivel MuruganX"
 wrote:
 
> >>
> >>  ebu_nand: ebu_nand@e0f0 {
> >>  compatible = "intel,lgm-ebu-nand";
> >>  reg = <0xe0f0 0x100
> >>  0xe100 0x300
> >>  0xe140 0x8
> >>  0xe1c0 0x1>;
> >>  reg-names = "ebunand", "hsnand", "nand_cs0", 
> >> nand_cs1";
> >>  dmas = < 8>, < 9>;
> >>  dma-names = "ebu_rx", "ebu_tx";
> >>  clocks =  < LGM_GCLK_EBU>;
> >>  };
> >>
> >>
> >> _nand {
> >> status = "disabled";
> >>nand,cs = <1>;
> >>nand-ecc-mode = "hw";
> >>pinctrl-names = "default";
> >>pinctrl-0 = <_nand_base _cs1>;
> >>};
> >>
> >>>
> > Ok. If I understand the SoC topology correctly it should actually be
> > something like that:
> >
> > {
> > ...
> > fpi@x {
> > compatible = "intel,lgm-fpi", "simple-bus";
> >
> > /* You might have other ranges to define here */
> > ranges = <0x1600 0xe000 0x100>;
> >
> > ...  
> 
>  Sorry, we do not have fpi tree node in our dts/dtsi file instead we have
>  the below one.. , that also not included the major peripherals
>  controllers node.
> /* Special part from CPU core */
> core: core {
> compatible = "intel,core", "simple-bus";
> #address-cells = <1>;
> #size-cells = <1>;
> ranges;
> 
> ioapic1: interrupt-controller@fec0 {
> #interrupt-cells = <2>;
> #address-cells = <0>;
> compatible = "intel,ce4100-ioapic";
> interrupt-controller;
> reg = <0xfec0 0x1000>;
> nr_entries = <256>;
> };
> 
> hpet: timer@fed0 {
> compatible = "intel,ce4100-hpet";
> reg = <0xfed0 0x400>;
> };
> 
> lapic0: interrupt-controller@fee0 {
> compatible = "intel,ce4100-lapic";
> reg = <0xfee0 0x1000>;
> no_pic_mode;
> };
> };
> 
>  other than this, rest all in independent node .  
> >>>
> >>> But you do have an FPI bus, right? If this is the case it should be
> >>> represented.  
> >>
> >> Yes, FPI bus is slave to core which connects all the peripherals.
> >>
> >>Or is the "intel,core" bus actually the FPI bus that you  
> >>> named differently?  
> >>
> >> FPI slave bus connects to core bus by OCP bridge, so here it is named
> >> FPI bus, but SW perspective didn't have root tree which has all
> >> sub-nodes, as of now each peripheral has its own node.  
> > 
> > Duh, not sure that's a good idea to hide that, especially since you
> > have to describe the address translation that happens when crossing the
> > FPI bus (the ranges thing I mentioned previously).  
> 
> Thanks! for the keep reviewing.
> 
> SW Address translation is not required, after discussion with HW team , 
> came to know that 0x17400 and 0x17C00 internal to the SoC.
> 
> NOC will translate 0xE1XX... to FPI address 0x17X... internally.
> There is an address translation in the NOC.
> 0x17X... is not visible to user.
> 
> so far added hard-coded values to CS0 and CS1 is not at required.
> I will change the code accordingly and sent to you.

Hm, you told me last week that writing wrong values to this register
caused the NAND controller to not work properly (you even had code that
was overwriting the dynamically calculated values by hardcoded ones, so
I suspect it indeed didn't work) and now you say this write to
EBU_ADDR_SEL() is optional?! Sorry but it's hard to believe, and I've
received so many contradictory information from you on that matter that
I can't really tell which one is correct. Not sure I want to keep
reviewing new versions of this driver in this context.

Regards,

Boris


Re: [PATCH v2 2/3] media: uapi: Add VP9 stateless decoder controls

2020-05-04 Thread Boris Brezillon
On Mon, 04 May 2020 14:38:23 -0400
Nicolas Dufresne  wrote:

> Le lundi 04 mai 2020 à 14:01 -0400, Nicolas Dufresne a écrit :
> > Le samedi 02 mai 2020 à 19:55 -0300, Ezequiel Garcia a écrit :  
> > > +Nicolas
> > > 
> > > On Sat, 2020-05-02 at 20:37 +0200, Boris Brezillon wrote:  
> > > > On Fri, 01 May 2020 13:57:49 -0300
> > > > Ezequiel Garcia  wrote:
> > > >   
> > > > > > > +
> > > > > > > +.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
> > > > > > > +
> > > > > > > +.. flat-table:: enum v4l2_vp9_reset_frame_context
> > > > > > > +:header-rows:  0
> > > > > > > +:stub-columns: 0
> > > > > > > +:widths:   1 2
> > > > > > > +
> > > > > > > +* - ``V4L2_VP9_RESET_FRAME_CTX_NONE``
> > > > > > > +  - Do not reset any frame context.
> > > > > > > +* - ``V4L2_VP9_RESET_FRAME_CTX_NONE_ALT``
> > > > > > > +  - Do not reset any frame context. This is an alternative 
> > > > > > > value for
> > > > > > > +V4L2_VP9_RESET_FRAME_CTX_NONE.
> > > > > > 
> > > > > > Add `` around V4L2_VP9_RESET_FRAME_CTX_NONE.
> > > > > > 
> > > > > 
> > > > > Hm, now that I look closer, what's the point
> > > > > of having the NONE_ALT in our uAPI if it
> > > > > has same meaning as NONE?
> > > > > 
> > > > > I think it can be removed.  
> > > > 
> > > > The intent was to match the spec so that one can pass the value
> > > > extracted from the bitstream directly.  
> > 
> > reset_frame_contextspecifies whether the frame context should be reset
> > to default values:
> >   − 0 or 1 means do not reset any frame context
> >   − 2 resets just the context specified in the frame header
> >   − 3 resets all cont
> > 
> > But aren't we going too far by making this an emum ? In Microsfot DXVA,
> > we pass that value without interpreting it in userspace. For the
> > following RKVDEC, it is (suspiciously ?) ignored. Maybe just passing
> > over the value would make more sense, less work ?  
> 
> I have looked deeper. So basically when 2 and 3, that needs to be done
> by userspace is set back the associated probs arrays to their default
> values (see section 10.5 or the spec).
> 
> https://github.com/rockchip-linux/mpp/blob/develop/mpp/codec/dec/vp9/vp9d_parser.c#L1021
> 
> It seems that for both VAAPI And DXVA, the drivers takes care of that
> reset. So I'd like to ask, shall we code these defaults inside the
> driver ? I think we do similar things in JPEG side. But if we keep it
> the way it is, this should be strictly documented, otherwise anyone
> porting from DXVA or VAAPI will be tricked by this.

IIRC, some book keeping had to be done in userspace anyway, so I didn't
feel the need for resetting probe context in kernel space (tt's always
hard to draw a clear line of what should be done in userspace and what
should be automated by kernel drivers for those stateless decoders).
I suspect some engines have hardware probs contexts, and in that case,
you'd have to reset those when this field is set to 2 or 3, but that's
not the case here.


Re: [PATCH v2 2/3] media: uapi: Add VP9 stateless decoder controls

2020-05-04 Thread Boris Brezillon
On Mon, 04 May 2020 14:01:32 -0400
Nicolas Dufresne  wrote:

> Le samedi 02 mai 2020 à 19:55 -0300, Ezequiel Garcia a écrit :
> > +Nicolas
> > 
> > On Sat, 2020-05-02 at 20:37 +0200, Boris Brezillon wrote:  
> > > On Fri, 01 May 2020 13:57:49 -0300
> > > Ezequiel Garcia  wrote:
> > >   
> > > > > > +
> > > > > > +.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
> > > > > > +
> > > > > > +.. flat-table:: enum v4l2_vp9_reset_frame_context
> > > > > > +:header-rows:  0
> > > > > > +:stub-columns: 0
> > > > > > +:widths:   1 2
> > > > > > +
> > > > > > +* - ``V4L2_VP9_RESET_FRAME_CTX_NONE``
> > > > > > +  - Do not reset any frame context.
> > > > > > +* - ``V4L2_VP9_RESET_FRAME_CTX_NONE_ALT``
> > > > > > +  - Do not reset any frame context. This is an alternative 
> > > > > > value for
> > > > > > +V4L2_VP9_RESET_FRAME_CTX_NONE.
> > > > > 
> > > > > Add `` around V4L2_VP9_RESET_FRAME_CTX_NONE.
> > > > > 
> > > > 
> > > > Hm, now that I look closer, what's the point
> > > > of having the NONE_ALT in our uAPI if it
> > > > has same meaning as NONE?
> > > > 
> > > > I think it can be removed.  
> > > 
> > > The intent was to match the spec so that one can pass the value
> > > extracted from the bitstream directly.  
> 
> reset_frame_contextspecifies whether the frame context should be reset
> to default values:
>   − 0 or 1 means do not reset any frame context
>   − 2 resets just the context specified in the frame header
>   − 3 resets all cont
> 
> But aren't we going too far by making this an emum ?

I like to not have to constantly go back to the spec when I read code,
and having constant values defined through enums definitely helps in
this regard, but maybe it's just me.

> In Microsfot DXVA,
> we pass that value without interpreting it in userspace. For the
> following RKVDEC, it is (suspiciously ?) ignored.

IIRC, the prob context has to be kept in userspace anyway (and reset
when needed), and the rkvdec engine does not have any hardware context.
That's probably why this value is ignored here.

> Maybe just passing
> over the value would make more sense, less work ?

I don't see how adding an enum adds more work, given the enum values
match the ones defined VP 9 spec, but maybe I'm missing something.


Re: [PATCH] nand: raw: use write_oob_raw for MTD_OPS_AUTO_OOB mode

2020-05-04 Thread Boris Brezillon
On Mon,  4 May 2020 11:42:53 +0200
Álvaro Fernández Rojas  wrote:

> Some NAND controllers change the ECC bytes when OOB is written with ECC
> enabled.
> This is a problem in brcmnand, since adding JFFS2 cleanmarkers after the page
> has been erased will change the ECC bytes to 0 and the controller will think
> the block is bad.
> It can be fixed by using write_oob_raw, which ensures ECC is disabled.
> 
> Signed-off-by: Álvaro Fernández Rojas 
> ---
>  drivers/mtd/nand/raw/nand_base.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/mtd/nand/raw/nand_base.c 
> b/drivers/mtd/nand/raw/nand_base.c
> index c24e5e2ba130..755d25200520 100644
> --- a/drivers/mtd/nand/raw/nand_base.c
> +++ b/drivers/mtd/nand/raw/nand_base.c
> @@ -488,7 +488,7 @@ static int nand_do_write_oob(struct nand_chip *chip, 
> loff_t to,
>  
>   nand_fill_oob(chip, ops->oobbuf, ops->ooblen, ops);
>  
> - if (ops->mode == MTD_OPS_RAW)
> + if (ops->mode == MTD_OPS_AUTO_OOB || ops->mode == MTD_OPS_RAW)
>   status = chip->ecc.write_oob_raw(chip, page & chip->pagemask);

The doc says:

@MTD_OPS_PLACE_OOB:  OOB data are placed at the given offset (default)
@MTD_OPS_AUTO_OOB:   OOB data are automatically placed at the free areas
 which are defined by the internal ecclayout
@MTD_OPS_RAW:data are transferred as-is, with no error
 correction; this mode implies %MTD_OPS_PLACE_OOB

To me, that means MTD_OPS_PLACE_OOB and MTD_OPS_AUTO_OOB do not imply
MTD_OPS_RAW. Anyway those modes are just too vague. We really should
separate the ECC-disabled/ECC-enabled concept (AKA raw vs non-raw mode)
from the OOB placement scheme. IIRC, Miquel had a patchset doing that.

We also should have the concept of protected OOB-region vs
unprotected-OOB-region if we want JFFS2 to work with controllers that
protect part of the OOB region. Once we have that we can patch JFFS2
to write things with "ECC-disabled"+"auto-OOB-placement-on-unprotected
area".

>   else
>   status = chip->ecc.write_oob(chip, page & chip->pagemask);



Re: [PATCH v4 2/2] mtd: rawnand: Add NAND controller support on Intel LGM SoC

2020-05-04 Thread Boris Brezillon
On Mon, 4 May 2020 16:50:08 +0800
"Ramuthevar, Vadivel MuruganX"
 wrote:

> Hi Boris,
> 
> On 4/5/2020 3:17 pm, Boris Brezillon wrote:
> > On Mon, 4 May 2020 15:15:08 +0800
> > "Ramuthevar, Vadivel MuruganX"
> >  wrote:
> >   
> >> Hi Boris,
> >>
> >> Thank you very much for the prompt review and suggestions...
> >>
> >> On 4/5/2020 3:08 pm, Boris Brezillon wrote:  
> >>> On Mon, 4 May 2020 10:02:35 +0800
> >>> "Ramuthevar, Vadivel MuruganX"
> >>>   wrote:
> >>>  
> >>>> Hi Boris,
> >>>>
> >>>> On 30/4/2020 9:01 pm, Boris Brezillon wrote:  
> >>>>> On Thu, 30 Apr 2020 14:36:00 +0200
> >>>>> Boris Brezillon  wrote:
> >>>>> 
> >>>>>> On Thu, 30 Apr 2020 17:07:03 +0800
> >>>>>> "Ramuthevar, Vadivel MuruganX"
> >>>>>>   wrote:
> >>>>>>
> >>>>>>>>>> The question is, is it the same value we have in nand_pa or it is
> >>>>>>>>>> different?
> >>>>>>>>>> 
> >>>>>>>>> Different address which is 0xE140 NAND_BASE_PHY address.  
> >>>>>>>> Then why didn't you tell me they didn't match when I suggested to 
> >>>>>>>> pass  
> >>>>>>> sorry, because you keep asking nand_pa after that only I realized 
> >>>>>>> that.
> >>>>>>>
> >>>>>>>> nand_pa? So now the question is, what does this address represent?  
> >>>>>>>EBU-MODULE
> >>>>>>>  _ ___
> >>>>>>> | |   ||NAND CTRL  |
> >>>>>>> | FPI BUS |==>| CS0(0x174) | 0xE100( 0xE14/0xE1C) NAND_PHY_BASE
> >>>>>>> |_|   |_CS1(0x17C)_|__ |
> >>>>>>>
> >>>>>>> EBU_CONRTROLLER_BASE : 0xE0F0_
> >>>>>>> HSNAND_BASE: 0xE100_
> >>>>>>> NAND_CS0: 0xE140_
> >>>>>>> NAND_CS1: 0xE1C0_
> >>>>>>>
> >>>>>>> MEM_REGION_BASE_CS0: 0x17400 (internal to ebu controller )
> >>>>>>> MEM_REGION_BASE_CS1: 0x17C00
> >>>>>>>
> >>>>>> Hm, I wonder if we shouldn't use a 'ranges' property to describe this
> >>>>>> address translation. Something like
> >>>>>>
> >>>>>>ebu@xxx {
> >>>>>>ranges = <0x1740 0xe140 0x1000>,
> >>>>>> <0x17c0 0xe1c0 0x1000>;
> >>>>>>reg = <0x1740>, <0x17c0>;
> >>>>>>reg-names = "cs-0", "cs-1";
> >>>>>>}
> >>>>>>
> >>>>>> The translated address (0xE1X0) will be available in res->start,
> >>>>>> and the non-translated one (0x17X0) can be retrieved with
> >>>>>> of_get_address(). All you'd have to do then would be calculate the
> >>>>>> mask:
> >>>>>>
> >>>>>>mask = (translated_address & original_address) >> 22;
> >>>>>>num_comp_bits = fls(mask);
> >>>>>>WARN_ON(mask != GENMASK(num_comp_bits - 1, 0));
> >>>>>>
> >>>>>> Which allows you to properly set the ADDR_SEL() register without
> >>>>>> relying on some hardcoded values:
> >>>>>>
> >>>>>>writel(original_address | EBU_ADDR_SEL_REGEN |
> >>>>>>   EBU_ADDR_COMP_BITS(num_comp_bits),
> >>>>>>   ebu_host->ebu + EBU_ADDR_SEL(csid));
> >>>>>>
> >>>>>> That's quite important if we want to merge the xway NAND driver with
> >>>>>> this one.  
> >>>>> Looks like the translation is done at the FPI bus declaration level (see
> >>>>> [1]). We really need to see the big picture to take a wise decision
> >>>>> about the bin

Re: [PATCH v4 2/2] mtd: rawnand: Add NAND controller support on Intel LGM SoC

2020-05-04 Thread Boris Brezillon
On Mon, 4 May 2020 15:15:08 +0800
"Ramuthevar, Vadivel MuruganX"
 wrote:

> Hi Boris,
> 
>Thank you very much for the prompt review and suggestions...
> 
> On 4/5/2020 3:08 pm, Boris Brezillon wrote:
> > On Mon, 4 May 2020 10:02:35 +0800
> > "Ramuthevar, Vadivel MuruganX"
> >   wrote:
> >   
> >> Hi Boris,
> >>
> >> On 30/4/2020 9:01 pm, Boris Brezillon wrote:  
> >>> On Thu, 30 Apr 2020 14:36:00 +0200
> >>> Boris Brezillon  wrote:
> >>>  
> >>>> On Thu, 30 Apr 2020 17:07:03 +0800
> >>>> "Ramuthevar, Vadivel MuruganX"
> >>>>   wrote:
> >>>> 
> >>>>>>>> The question is, is it the same value we have in nand_pa or it is
> >>>>>>>> different?
> >>>>>>>>  
> >>>>>>> Different address which is 0xE140 NAND_BASE_PHY address.  
> >>>>>> Then why didn't you tell me they didn't match when I suggested to pass 
> >>>>>>  
> >>>>> sorry, because you keep asking nand_pa after that only I realized that.
> >>>>> 
> >>>>>> nand_pa? So now the question is, what does this address represent?  
> >>>>>   EBU-MODULE
> >>>>> _ ___
> >>>>> | |   ||NAND CTRL  |
> >>>>> | FPI BUS |==>| CS0(0x174) | 0xE100( 0xE14/0xE1C) NAND_PHY_BASE
> >>>>> |_|   |_CS1(0x17C)_|__ |
> >>>>>
> >>>>> EBU_CONRTROLLER_BASE : 0xE0F0_
> >>>>> HSNAND_BASE: 0xE100_
> >>>>> NAND_CS0: 0xE140_
> >>>>> NAND_CS1: 0xE1C0_
> >>>>>
> >>>>> MEM_REGION_BASE_CS0: 0x17400 (internal to ebu controller )
> >>>>> MEM_REGION_BASE_CS1: 0x17C00
> >>>>> 
> >>>> Hm, I wonder if we shouldn't use a 'ranges' property to describe this
> >>>> address translation. Something like
> >>>>
> >>>>  ebu@xxx {
> >>>>  ranges = <0x1740 0xe140 0x1000>,
> >>>>   <0x17c0 0xe1c0 0x1000>;
> >>>>  reg = <0x1740>, <0x17c0>;
> >>>>  reg-names = "cs-0", "cs-1";
> >>>>  }
> >>>>
> >>>> The translated address (0xE1X0) will be available in res->start,
> >>>> and the non-translated one (0x17X0) can be retrieved with
> >>>> of_get_address(). All you'd have to do then would be calculate the
> >>>> mask:
> >>>>
> >>>>  mask = (translated_address & original_address) >> 22;
> >>>>  num_comp_bits = fls(mask);
> >>>>  WARN_ON(mask != GENMASK(num_comp_bits - 1, 0));
> >>>>
> >>>> Which allows you to properly set the ADDR_SEL() register without
> >>>> relying on some hardcoded values:
> >>>>
> >>>>  writel(original_address | EBU_ADDR_SEL_REGEN |
> >>>> EBU_ADDR_COMP_BITS(num_comp_bits),
> >>>> ebu_host->ebu + EBU_ADDR_SEL(csid));
> >>>>
> >>>> That's quite important if we want to merge the xway NAND driver with
> >>>> this one.  
> >>> Looks like the translation is done at the FPI bus declaration level (see
> >>> [1]). We really need to see the big picture to take a wise decision
> >>> about the bindings. Would you mind pasting your dsti/dts files
> >>> somewhere? It feels like the NAND controller is a sub-part of a more
> >>> generic 'memory' controller, in which case the NAND controller should be
> >>> declared as a child of this generic memory bus (called localbus in [1],
> >>> but maybe EBU is more accurate).
> >>>
> >>> [1]https://github.com/xieyaxiongfly/Atheros_CSI_tool_OpenWRT_src/blob/master/target/linux/lantiq/files-4.14/arch/mips/boot/dts/vr9.dtsi#L162
> >>>  
> >>
> >>ebu_nand: ebu_nand@e0f0 {
> >>compatible = "intel,lgm-ebu-nand";
> >>reg = <0xe0f0 0x100
> >>0xe100 0x300
> >>0xe140 0x8
> >>0xe1c0 0x1

Re: [PATCH v4 2/2] mtd: rawnand: Add NAND controller support on Intel LGM SoC

2020-05-04 Thread Boris Brezillon
On Mon, 4 May 2020 10:02:35 +0800
"Ramuthevar, Vadivel MuruganX"
 wrote:

> Hi Boris,
> 
> On 30/4/2020 9:01 pm, Boris Brezillon wrote:
> > On Thu, 30 Apr 2020 14:36:00 +0200
> > Boris Brezillon  wrote:
> >   
> >> On Thu, 30 Apr 2020 17:07:03 +0800
> >> "Ramuthevar, Vadivel MuruganX"
> >>  wrote:
> >>  
> >>>>>> The question is, is it the same value we have in nand_pa or it is
> >>>>>> different?
> >>>>>>   
> >>>>> Different address which is 0xE140 NAND_BASE_PHY address.  
> >>>>
> >>>> Then why didn't you tell me they didn't match when I suggested to pass  
> >>>
> >>> sorry, because you keep asking nand_pa after that only I realized that.
> >>>  
> >>>> nand_pa? So now the question is, what does this address represent?  
> >>>
> >>>  EBU-MODULE
> >>>_ ___
> >>> | |   ||NAND CTRL  |
> >>> | FPI BUS |==>| CS0(0x174) | 0xE100( 0xE14/0xE1C) NAND_PHY_BASE
> >>> |_|   |_CS1(0x17C)_|__ |
> >>>
> >>> EBU_CONRTROLLER_BASE : 0xE0F0_
> >>> HSNAND_BASE: 0xE100_
> >>> NAND_CS0: 0xE140_
> >>> NAND_CS1: 0xE1C0_
> >>>
> >>> MEM_REGION_BASE_CS0: 0x17400 (internal to ebu controller )
> >>> MEM_REGION_BASE_CS1: 0x17C00
> >>>  
> >>
> >> Hm, I wonder if we shouldn't use a 'ranges' property to describe this
> >> address translation. Something like
> >>
> >>ebu@xxx {
> >>ranges = <0x1740 0xe140 0x1000>,
> >> <0x17c0 0xe1c0 0x1000>;
> >>reg = <0x1740>, <0x17c0>;
> >>reg-names = "cs-0", "cs-1";
> >>}
> >>
> >> The translated address (0xE1X0) will be available in res->start,
> >> and the non-translated one (0x17X0) can be retrieved with
> >> of_get_address(). All you'd have to do then would be calculate the
> >> mask:
> >>
> >>mask = (translated_address & original_address) >> 22;
> >>num_comp_bits = fls(mask);
> >>WARN_ON(mask != GENMASK(num_comp_bits - 1, 0));
> >>
> >> Which allows you to properly set the ADDR_SEL() register without
> >> relying on some hardcoded values:
> >>
> >>writel(original_address | EBU_ADDR_SEL_REGEN |
> >>   EBU_ADDR_COMP_BITS(num_comp_bits),
> >>   ebu_host->ebu + EBU_ADDR_SEL(csid));
> >>
> >> That's quite important if we want to merge the xway NAND driver with
> >> this one.  
> > 
> > Looks like the translation is done at the FPI bus declaration level (see
> > [1]). We really need to see the big picture to take a wise decision
> > about the bindings. Would you mind pasting your dsti/dts files
> > somewhere? It feels like the NAND controller is a sub-part of a more
> > generic 'memory' controller, in which case the NAND controller should be
> > declared as a child of this generic memory bus (called localbus in [1],
> > but maybe EBU is more accurate).
> > 
> > [1]https://github.com/xieyaxiongfly/Atheros_CSI_tool_OpenWRT_src/blob/master/target/linux/lantiq/files-4.14/arch/mips/boot/dts/vr9.dtsi#L162
> >   
> 
> 
>   ebu_nand: ebu_nand@e0f0 {
>   compatible = "intel,lgm-ebu-nand";
>   reg = <0xe0f0 0x100
>   0xe100 0x300
>   0xe140 0x8
>   0xe1c0 0x1>;
>   reg-names = "ebunand", "hsnand", "nand_cs0", nand_cs1";
>   dmas = < 8>, < 9>;
>   dma-names = "ebu_rx", "ebu_tx";
>   clocks =  < LGM_GCLK_EBU>;
>   };
> 
> 
>_nand {
>status = "disabled";
>   nand,cs = <1>;
>   nand-ecc-mode = "hw";
>   pinctrl-names = "default";
>   pinctrl-0 = <_nand_base _cs1>;
>   };
> 
> >   

Ok. If I understand the SoC topology correctly it should actually be
something like that:

{
...
fpi@x {
compatible = "intel,lgm-fpi", &quo

Re: [PATCH v2 2/3] media: uapi: Add VP9 stateless decoder controls

2020-05-02 Thread Boris Brezillon
On Fri, 01 May 2020 13:57:49 -0300
Ezequiel Garcia  wrote:

> > > +
> > > +.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
> > > +
> > > +.. flat-table:: enum v4l2_vp9_reset_frame_context
> > > +:header-rows:  0
> > > +:stub-columns: 0
> > > +:widths:   1 2
> > > +
> > > +* - ``V4L2_VP9_RESET_FRAME_CTX_NONE``
> > > +  - Do not reset any frame context.
> > > +* - ``V4L2_VP9_RESET_FRAME_CTX_NONE_ALT``
> > > +  - Do not reset any frame context. This is an alternative value for
> > > +V4L2_VP9_RESET_FRAME_CTX_NONE.  
> > 
> > Add `` around V4L2_VP9_RESET_FRAME_CTX_NONE.
> >   
> 
> Hm, now that I look closer, what's the point
> of having the NONE_ALT in our uAPI if it
> has same meaning as NONE?
> 
> I think it can be removed.

The intent was to match the spec so that one can pass the value
extracted from the bitstream directly.

> > 
> > I got several smatch warnings:
> > 
> > smatch: ERRORS
> > drivers/media/v4l2-core/v4l2-ctrls.c:1880 
> > validate_vp9_frame_decode_params() warn: was && intended here instead of ||?
> > 
> > (Commented on this ^^^ one above)
> > 
> > drivers/staging/media/rkvdec/rkvdec-vp9.c:426 init_intra_only_probs() 
> > error: buffer overflow 'ptr' 9 <= 69
> > drivers/staging/media/rkvdec/rkvdec-vp9.c:1478 rkvdec_vp9_done() error: 
> > potentially dereferencing uninitialized 'ctrl'.
> > drivers/staging/media/rkvdec/rkvdec-vp9.c:1483 rkvdec_vp9_done() error: 
> > uninitialized symbol 'dec_dst_buf'.
> > drivers/staging/media/rkvdec/rkvdec-vp9.c:941:6: warning: variable 'ret' 
> > set but not used [-Wunused-but-set-variable]
> > drivers/staging/media/rkvdec/rkvdec-vp9.c:1466:40: warning: variable 'fctx' 
> > set but not used [-Wunused-but-set-variable]
> >   
> 
> Oh, I'll run smatch and fix them all.

Oops!


Re: [PATCH v4 2/2] mtd: rawnand: Add NAND controller support on Intel LGM SoC

2020-04-30 Thread Boris Brezillon
On Thu, 30 Apr 2020 14:36:00 +0200
Boris Brezillon  wrote:

> On Thu, 30 Apr 2020 17:07:03 +0800
> "Ramuthevar, Vadivel MuruganX"
>  wrote:
> 
> > >>> The question is, is it the same value we have in nand_pa or it is
> > >>> different?
> > >>>
> > >> Different address which is 0xE140 NAND_BASE_PHY address.
> > > 
> > > Then why didn't you tell me they didn't match when I suggested to pass
> > 
> > sorry, because you keep asking nand_pa after that only I realized that.
> >   
> > > nand_pa? So now the question is, what does this address represent?
> > 
> > EBU-MODULE
> >   _ ___
> > | |   ||NAND CTRL  |
> > | FPI BUS |==>| CS0(0x174) | 0xE100( 0xE14/0xE1C) NAND_PHY_BASE
> > |_|   |_CS1(0x17C)_|__ |
> > 
> > EBU_CONRTROLLER_BASE : 0xE0F0_
> > HSNAND_BASE: 0xE100_
> > NAND_CS0: 0xE140_
> > NAND_CS1: 0xE1C0_
> > 
> > MEM_REGION_BASE_CS0: 0x17400 (internal to ebu controller )
> > MEM_REGION_BASE_CS1: 0x17C00
> >   
> 
> Hm, I wonder if we shouldn't use a 'ranges' property to describe this
> address translation. Something like
> 
>   ebu@xxx {
>   ranges = <0x1740 0xe140 0x1000>,
><0x17c0 0xe1c0 0x1000>;
>   reg = <0x1740>, <0x17c0>;
>   reg-names = "cs-0", "cs-1";
>   }
> 
> The translated address (0xE1X0) will be available in res->start,
> and the non-translated one (0x17X0) can be retrieved with
> of_get_address(). All you'd have to do then would be calculate the
> mask:
> 
>   mask = (translated_address & original_address) >> 22;
>   num_comp_bits = fls(mask);
>   WARN_ON(mask != GENMASK(num_comp_bits - 1, 0));
> 
> Which allows you to properly set the ADDR_SEL() register without
> relying on some hardcoded values:
> 
>   writel(original_address | EBU_ADDR_SEL_REGEN |
>  EBU_ADDR_COMP_BITS(num_comp_bits),
>  ebu_host->ebu + EBU_ADDR_SEL(csid));
> 
> That's quite important if we want to merge the xway NAND driver with
> this one.

Looks like the translation is done at the FPI bus declaration level (see
[1]). We really need to see the big picture to take a wise decision
about the bindings. Would you mind pasting your dsti/dts files
somewhere? It feels like the NAND controller is a sub-part of a more
generic 'memory' controller, in which case the NAND controller should be
declared as a child of this generic memory bus (called localbus in [1],
but maybe EBU is more accurate).

[1]https://github.com/xieyaxiongfly/Atheros_CSI_tool_OpenWRT_src/blob/master/target/linux/lantiq/files-4.14/arch/mips/boot/dts/vr9.dtsi#L162


Re: [PATCH v2] mtd: Fix mtd not the same name not registered if nvmem

2020-04-30 Thread Boris Brezillon
On Thu, 30 Apr 2020 14:26:51 +0200
Ricardo Ribalda Delgado  wrote:

> Hi
> 
> On Mon, Apr 27, 2020 at 9:10 PM Boris Brezillon
>  wrote:
> >
> > On Mon, 27 Apr 2020 16:49:22 +0200
> > Miquel Raynal  wrote:
> >  
> > > Hi Boris,
> > >
> > > Boris Brezillon  wrote on Mon, 27 Apr
> > > 2020 16:37:11 +0200:
> > >  
> > > > On Mon, 27 Apr 2020 16:22:22 +0200
> > > > Miquel Raynal  wrote:
> > > >  
> > > > > Hi Ricardo,
> > > > >
> > > > > Ricardo Ribalda Delgado  wrote on Tue, 14 Apr 2020
> > > > > 15:47:23 +0200:
> > > > >  
> > > > > > Ping?
> > > > > >
> > > > > > On Thu, Apr 2, 2020 at 8:59 AM Ricardo Ribalda Delgado
> > > > > >  wrote:  
> > > > > > >
> > > > > > > When the nvmem framework is enabled, a nvmem device is created 
> > > > > > > per mtd
> > > > > > > device/partition.
> > > > > > >
> > > > > > > It is not uncommon that a device can have multiple mtd devices 
> > > > > > > with
> > > > > > > partitions that have the same name. Eg, when there DT overlay is 
> > > > > > > allowed
> > > > > > > and the same device with mtd is attached twice.
> > > > > > >
> > > > > > > Under that circumstances, the mtd fails to register due to a name
> > > > > > > duplication on the nvmem framework.
> > > > > > >
> > > > > > > With this patch we add a _1, _2, _X to the subsequent names if 
> > > > > > > there is
> > > > > > > a collition, and throw a warning, instead of not starting the mtd
> > > > > > > device.
> > > > > > >
> > > > > > > [8.948991] sysfs: cannot create duplicate filename 
> > > > > > > '/bus/nvmem/devices/Production Data'
> > > > > > > [8.948992] CPU: 7 PID: 246 Comm: systemd-udevd Not tainted 
> > > > > > > 5.5.0-qtec-standard #13
> > > > > > > [8.948993] Hardware name: AMD Dibbler/Dibbler, BIOS 
> > > > > > > 05.22.04.0019 10/26/2019
> > > > > > > [8.948994] Call Trace:
> > > > > > > [8.948996]  dump_stack+0x50/0x70
> > > > > > > [8.948998]  sysfs_warn_dup.cold+0x17/0x2d
> > > > > > > [8.949000]  sysfs_do_create_link_sd.isra.0+0xc2/0xd0
> > > > > > > [8.949002]  bus_add_device+0x74/0x140
> > > > > > > [8.949004]  device_add+0x34b/0x850
> > > > > > > [8.949006]  nvmem_register.part.0+0x1bf/0x640
> > > > > > > ...
> > > > > > > [8.948926] mtd mtd8: Failed to register NVMEM device
> > > > > > >
> > > > > > > Signed-off-by: Ricardo Ribalda Delgado   
> > > > >
> > > > > Thanks for proposing this change. Indeed we are aware of the problem
> > > > > and the best solution that we could come up with was to create an
> > > > > additional "unique_name" field to the mtd_info structure. This new
> > > > > field would have the form:
> > > > >
> > > > > []
> > > > >
> > > > > The separator might be '~' (but I am completely open on that), and 
> > > > > that
> > > > > would give for instance:
> > > > >
> > > > > my-controller~my-device~my-part~mysub-part  
> > > >
> > > > I'd prefer something slightly more standard for the separator, like '/',
> > > > which is what we usually use when we want to represent a path in a tree.
> > > > I do agree on the general approach though.  
> > >
> > > I am not sure / is a valid separator here we would use this
> > > name to create a sysfs entry. Would it work?  
> >
> > Hm, you're probably right, I didn't check how the name was used by
> > nvmem. I also see that partition names can contain spaces, which is
> > not that great. So, if we want to use mtd->unique_name we should
> > probably sanitize it before passing it to nvmem. All this makes me
> > reconsider your initial proposal: use 'mtdX' as the nvmem name. It's
> > unique and it's simple enough to not require this extra sanitization
> > pass, on the other hand, guessing the nvmem partition based on such an
> > opaque name is not simple, not to mention that the mtd device name can
> > change depending on the probe order.
> >
> > I also wonder if creating nvmem devs unconditionally for all mtd
> > devices is a good idea. Sounds like we should only do that if there's an
> > explicit request to have one partition exposed as an nvmem.
> >
> > Note that, no matter what we decide about nvmem, I think having unique
> > names at the MTD level is a good thing.  
> 
> I have no preference one way or another.
> 
> The issue is that our current master leads to mtds not working fine
> and making the system unusable. Whatever we decide it must be fast and
> the patch backported.
> 
> My original patch follows the same logic as led does where there is a
> duplicated name. I can send a separate patch that uses mtdX and then
> you decide what to pick. Or we can go with a third way, but it needs
> to be soon ;).

Please send a patch using dev_name(>dev), and let's hope it
doesn't break someone else use case.


Re: [PATCH v4 2/2] mtd: rawnand: Add NAND controller support on Intel LGM SoC

2020-04-30 Thread Boris Brezillon
On Thu, 30 Apr 2020 17:07:03 +0800
"Ramuthevar, Vadivel MuruganX"
 wrote:

> >>> The question is, is it the same value we have in nand_pa or it is
> >>> different?
> >>>  
> >> Different address which is 0xE140 NAND_BASE_PHY address.  
> > 
> > Then why didn't you tell me they didn't match when I suggested to pass  
> 
> sorry, because you keep asking nand_pa after that only I realized that.
> 
> > nand_pa? So now the question is, what does this address represent?  
> 
> EBU-MODULE
>   _ ___
> | |   ||NAND CTRL  |
> | FPI BUS |==>| CS0(0x174) | 0xE100( 0xE14/0xE1C) NAND_PHY_BASE
> |_|   |_CS1(0x17C)_|__ |
> 
> EBU_CONRTROLLER_BASE : 0xE0F0_
> HSNAND_BASE: 0xE100_
> NAND_CS0: 0xE140_
> NAND_CS1: 0xE1C0_
> 
> MEM_REGION_BASE_CS0: 0x17400 (internal to ebu controller )
> MEM_REGION_BASE_CS1: 0x17C00
> 

Hm, I wonder if we shouldn't use a 'ranges' property to describe this
address translation. Something like

ebu@xxx {
ranges = <0x1740 0xe140 0x1000>,
 <0x17c0 0xe1c0 0x1000>;
reg = <0x1740>, <0x17c0>;
reg-names = "cs-0", "cs-1";
}

The translated address (0xE1X0) will be available in res->start,
and the non-translated one (0x17X0) can be retrieved with
of_get_address(). All you'd have to do then would be calculate the
mask:

mask = (translated_address & original_address) >> 22;
num_comp_bits = fls(mask);
WARN_ON(mask != GENMASK(num_comp_bits - 1, 0));

Which allows you to properly set the ADDR_SEL() register without
relying on some hardcoded values:

writel(original_address | EBU_ADDR_SEL_REGEN |
   EBU_ADDR_COMP_BITS(num_comp_bits),
   ebu_host->ebu + EBU_ADDR_SEL(csid));

That's quite important if we want to merge the xway NAND driver with
this one.


Re: [PATCH v4 2/2] mtd: rawnand: Add NAND controller support on Intel LGM SoC

2020-04-30 Thread Boris Brezillon
On Thu, 30 Apr 2020 16:30:15 +0800
"Ramuthevar, Vadivel MuruganX"
 wrote:

> >>>
> >>> And now I'd like you to explain why 5 is the right value for that field
> >>> (I guess that has to do with the position of the CS/ALE/CLE pins).  
> >>
> >> 5 : bit 26, 25, 24, 23, 22 to be included for comparison in the  
> > 
> > That's 6 bits to me, not 5.  
> 
> No , 5 bits only the above case.

Oops, right, sorry for the brain fart.

> > 
> > The question is, is it the same value we have in nand_pa or it is
> > different?
> >   
> Different address which is 0xE140 NAND_BASE_PHY address.

Then why didn't you tell me they didn't match when I suggested to pass
nand_pa? So now the question is, what does this address represent? Do
you have a reference manual I can look at to understand what this is?


Re: [PATCH v4 2/2] mtd: rawnand: Add NAND controller support on Intel LGM SoC

2020-04-30 Thread Boris Brezillon
On Thu, 30 Apr 2020 15:50:30 +0800
"Ramuthevar, Vadivel MuruganX"
 wrote:

> Hi Boris,
> 
>Thank you very much for keep reviewing the patches and more queries...
> 
> On 29/4/2020 11:31 pm, Boris Brezillon wrote:
> > On Wed, 29 Apr 2020 23:18:31 +0800
> > "Ramuthevar, Vadivel MuruganX"
> >  wrote:
> >   
> >> Hi Boris,
> >>
> >> On 29/4/2020 10:48 pm, Boris Brezillon wrote:  
> >>> On Wed, 29 Apr 2020 22:33:37 +0800
> >>> "Ramuthevar, Vadivel MuruganX"
> >>>  wrote:
> >>>  
> >>>> Hi Boris,
> >>>>
> >>>> On 29/4/2020 10:22 pm, Boris Brezillon wrote:  
> >>>>> On Wed, 29 Apr 2020 18:42:05 +0800
> >>>>> "Ramuthevar, Vadivel MuruganX"
> >>>>>  wrote:
> >>>>> 
> >>>>>> +
> >>>>>> +#define EBU_ADDR_SEL(n)   (0x20 + (n) * 4)
> >>>>>> +#define EBU_ADDR_MASK (5 << 4)  
> >>>>>
> >>>>> It's still unclear what ADDR_MASK is for. Can you add a comment
> >>>>> explaining what it does?  
> >>>>
> >>>> Thank you Boris, keep review and giving inputs, will update.  
> >>>
> >>> Can you please explain it here before sending a new version?  
> >>
> >> Memory Region Address Mask:
> >> Specifies the number of right-most bits in the base address that should
> >> be included in the address comparison. bits positions(7:4).  
> > 
> > Okay, then the macro should be
> > 
> > #define EBU_ADDR_MASK(x)((x) << 4)
> > 
> > And now I'd like you to explain why 5 is the right value for that field
> > (I guess that has to do with the position of the CS/ALE/CLE pins).  
> 
> 5 : bit 26, 25, 24, 23, 22 to be included for comparison in the 

That's 6 bits to me, not 5.

> ADDR_SELx , it compares only 5 bits.

Definitely not what I would qualify as right-most bits. So, you say the
comparison always starts at bit 22, and ends at 22+?

> >>>> Yes , we are setting both CS0 and CS1 memory access region, if you have
> >>>> any concern to optimize, please suggest me, Thanks!  
> >>>
> >>> If you want to setup both CS, and the address written in EBU_ADDR_SEL(x)
> >>> is really related to the nand_pa address, then retrieve resources for
> >>> all CS ranges.  
> >> If it's not related, please explain what those  
> >>> EBU_MEM_BASE_CS_X values encode.  
> >>
> >> Memory Region Base Address
> >> FPI Bus addresses are compared to this base address in conjunction with
> >> the mask control(EBU_ADDR_MASK). Driver need to program this field!  
> > 
> > That's not explaining what the base address should be. Is 'nand_pa' the
> > value we should have there?  
> 
> The one prorgrammed in the addr_sel register is used by the HW 
> controller, it remaps to  0x174XX-> CS0 and 0x17CXX->CS1.
> The hardware itself, decodes only for 1740xx/17c0xx, other random values 
> cannot be programmed

The question is, is it the same value we have in nand_pa or it is
different?


Re: [PATCH v6 3/8] i3c: master: i3c mastership request and handover

2020-04-30 Thread Boris Brezillon
On Fri, 17 Apr 2020 18:21:02 +0200
Parshuram Thombare  wrote:

> +
> +/* This function is expected to be called with normaluse_lock */
> +int i3c_master_acquire_bus(struct i3c_master_controller *master)
> +{
> + int ret = 0;
> +
> + if (!master->this || master->this != master->bus.cur_master) {

Let's limit the number of indentations by doing

if (master->this == master->bus.cur_master)
return 0;


> + if (master->mr_state == I3C_MR_IDLE) {
> + master->mr_state = I3C_MR_WAIT_DA;
> + init_completion(>mr_comp);
> + queue_work(master->wq, >sec_mst_work);
> + /*
> +  * Bus acquire procedure may need write lock
> +  * so release read lock before yielding
> +  * to bus acquire state machine
> +  */
> + i3c_bus_normaluse_unlock(>bus);
> + wait_for_completion(>mr_comp);
> + i3c_bus_normaluse_lock(>bus);

Is that really enough? I remember we had something a bit more complex
to handle the case where bus is acquired to send a message to a device,
and another master on the bus re-acquires it before we have a chance to
send this message message. i3c_master_acquire_bus_ownership() was
dealing with that in Przemek series. It seems you've rewritten a lot of
these things. Would you mind explaining why, and how that works?

> + if (master->mr_state != I3C_MR_DONE)
> + ret = -EAGAIN;
> + master->mr_state = I3C_MR_IDLE;
> + } else {
> + /*
> +  * MR request is already in process for
> +  * this master
> +  */
> + ret = -EAGAIN;
> + }
> + }
> +
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(i3c_master_acquire_bus);




Re: [PATCH v6 2/8] i3c: master: split bus_init callback into bus_init and master_set_info

2020-04-30 Thread Boris Brezillon
On Fri, 17 Apr 2020 18:20:52 +0200
Parshuram Thombare  wrote:

> To support mastership handover procedure, this patch splits the
> bus_init callback into bus_init and master_set_info callbacks

Missing period at the end of this sentence.

IIRC, we discussed passing master info directly at controller
registration time for primary master registration, thus avoiding this
->master_set_info() step. Any good reason for doing that? I mean, I'd
expect the PID, BCR, DCR to be fixed, the only one that can be assigned
automatically is the address, and we can have a magic value for
'auto-assign the first available address', like '0'. The
write to DEV_ID_RR0() can be done conditionally in master_bus_init()
when '!secondary_master'.

> 
> Signed-off-by: Parshuram Thombare 
> ---
>  drivers/i3c/master.c | 10 +++--
>  drivers/i3c/master/dw-i3c-master.c   | 29 -
>  drivers/i3c/master/i3c-master-cdns.c | 63 ++--
>  include/linux/i3c/master.h   |  7 +++-
>  4 files changed, 71 insertions(+), 38 deletions(-)
> 
> diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
> index 5f4bd52121fe..0ec332e45737 100644
> --- a/drivers/i3c/master.c
> +++ b/drivers/i3c/master.c
> @@ -1716,6 +1716,10 @@ static int i3c_master_bus_init(struct 
> i3c_master_controller *master)
>   if (ret)
>   goto err_detach_devs;
>  
> + ret = master->ops->master_set_info(master);
> + if (ret)
> + goto err_detach_devs;
> +
>   /*
>* The master device should have been instantiated in ->bus_init(),
>* complain if this was not the case.
> @@ -2378,9 +2382,9 @@ EXPORT_SYMBOL_GPL(i3c_generic_ibi_recycle_slot);
>  
>  static int i3c_master_check_ops(const struct i3c_master_controller_ops *ops)
>  {
> - if (!ops || !ops->bus_init || !ops->priv_xfers ||
> - !ops->send_ccc_cmd || !ops->do_daa || !ops->i2c_xfers ||
> - !ops->i2c_funcs)
> + if (!ops || !ops->bus_init || !ops->master_set_info ||
> + !ops->priv_xfers || !ops->send_ccc_cmd || !ops->do_daa ||
> + !ops->i2c_xfers || !ops->i2c_funcs)
>   return -EINVAL;
>  
>   if (ops->request_ibi &&
> diff --git a/drivers/i3c/master/dw-i3c-master.c 
> b/drivers/i3c/master/dw-i3c-master.c
> index 1d83c97431c7..5c9a72d68fb8 100644
> --- a/drivers/i3c/master/dw-i3c-master.c
> +++ b/drivers/i3c/master/dw-i3c-master.c
> @@ -593,7 +593,6 @@ static int dw_i3c_master_bus_init(struct 
> i3c_master_controller *m)
>  {
>   struct dw_i3c_master *master = to_dw_i3c_master(m);
>   struct i3c_bus *bus = i3c_master_get_bus(m);
> - struct i3c_device_info info = { };
>   u32 thld_ctrl;
>   int ret;
>  
> @@ -624,6 +623,24 @@ static int dw_i3c_master_bus_init(struct 
> i3c_master_controller *m)
>   writel(INTR_MASTER_MASK, master->regs + INTR_STATUS_EN);
>   writel(INTR_MASTER_MASK, master->regs + INTR_SIGNAL_EN);
>  
> + writel(IBI_REQ_REJECT_ALL, master->regs + IBI_SIR_REQ_REJECT);
> + writel(IBI_REQ_REJECT_ALL, master->regs + IBI_MR_REQ_REJECT);
> +
> + /* For now don't support Hot-Join */
> + writel(readl(master->regs + DEVICE_CTRL) | DEV_CTRL_HOT_JOIN_NACK,
> +master->regs + DEVICE_CTRL);
> +
> + dw_i3c_master_enable(master);
> +
> + return 0;
> +}
> +
> +static int dw_i3c_master_set_info(struct i3c_master_controller *m)
> +{
> + struct dw_i3c_master *master = to_dw_i3c_master(m);
> + struct i3c_device_info info = { };
> + int ret;
> +
>   ret = i3c_master_get_free_addr(m, 0);
>   if (ret < 0)
>   return ret;
> @@ -638,15 +655,6 @@ static int dw_i3c_master_bus_init(struct 
> i3c_master_controller *m)
>   if (ret)
>   return ret;
>  
> - writel(IBI_REQ_REJECT_ALL, master->regs + IBI_SIR_REQ_REJECT);
> - writel(IBI_REQ_REJECT_ALL, master->regs + IBI_MR_REQ_REJECT);
> -
> - /* For now don't support Hot-Join */
> - writel(readl(master->regs + DEVICE_CTRL) | DEV_CTRL_HOT_JOIN_NACK,
> -master->regs + DEVICE_CTRL);
> -
> - dw_i3c_master_enable(master);
> -
>   return 0;
>  }
>  
> @@ -1088,6 +1096,7 @@ static irqreturn_t dw_i3c_master_irq_handler(int irq, 
> void *dev_id)
>  
>  static const struct i3c_master_controller_ops dw_mipi_i3c_ops = {
>   .bus_init = dw_i3c_master_bus_init,
> + .master_set_info = dw_i3c_master_set_info,
>   .bus_cleanup = dw_i3c_master_bus_cleanup,
>   .attach_i3c_dev = dw_i3c_master_attach_i3c_dev,
>   .reattach_i3c_dev = dw_i3c_master_reattach_i3c_dev,
> diff --git a/drivers/i3c/master/i3c-master-cdns.c 
> b/drivers/i3c/master/i3c-master-cdns.c
> index 8889a4fdb454..c2d1631a9e38 100644
> --- a/drivers/i3c/master/i3c-master-cdns.c
> +++ b/drivers/i3c/master/i3c-master-cdns.c
> @@ -1199,21 +1199,20 @@ static int cdns_i3c_master_bus_init(struct 
> i3c_master_controller *m)
>   struct cdns_i3c_master *master = to_cdns_i3c_master(m);
>   unsigned long pres_step, sysclk_rate, 

Re: [PATCH v6 1/8] i3c: master: mastership handover document

2020-04-30 Thread Boris Brezillon
On Fri, 17 Apr 2020 18:20:42 +0200
Parshuram Thombare  wrote:

> Flow diagram for I3C mastership handover, DEFSLVS
> processing and secondary master initialization.
> 

Thanks for doing that, that's really appreciated, but the document
doesn't seem to be formatted properly. Would you mind fixing that (you
can build the docs with 'make htmldocs').

> Signed-off-by: Parshuram Thombare 
> ---
>  Documentation/driver-api/i3c/index.rst|   1 +
>  .../i3c/mastership-handover-flow-diagram.rst  | 209 ++
>  2 files changed, 210 insertions(+)
>  create mode 100644 
> Documentation/driver-api/i3c/mastership-handover-flow-diagram.rst
> 
> diff --git a/Documentation/driver-api/i3c/index.rst 
> b/Documentation/driver-api/i3c/index.rst
> index 783d6dad054b..9a38c5ba87cb 100644
> --- a/Documentation/driver-api/i3c/index.rst
> +++ b/Documentation/driver-api/i3c/index.rst
> @@ -9,3 +9,4 @@ I3C subsystem
> protocol
> device-driver-api
> master-driver-api
> +   mastership-handover-flow-diagram
> diff --git 
> a/Documentation/driver-api/i3c/mastership-handover-flow-diagram.rst 
> b/Documentation/driver-api/i3c/mastership-handover-flow-diagram.rst
> new file mode 100644
> index ..04cd9f1283e0
> --- /dev/null
> +++ b/Documentation/driver-api/i3c/mastership-handover-flow-diagram.rst
> @@ -0,0 +1,209 @@
> +.. SPDX-License-Identifier: GPL-2.0
> +
> +
> +I3C mastership handover flow
> +
> +
> +Main master  Sec Master1 Sec Master 2
> +
> +1. Initialize I3C1. Initialize I3C   1. Initialize I3C
> +   bus in Pure mode bus in Pure modebus in Pure mode
> +
> +defslvs_done flagdefslvs_done flag   defslvs_done flag
> += true   = false = false
> +
> +2. Do DAA + SETDASA  2. Spawn init. thread   2. Spawn init. thread
> + Initialization thread   Initialization thread
> + Wait for DEFSLVSWait for DEFSLVS
> + processing  processing
> + Wait forWait for
> + defslvs_done flag   defslvs_done flag
> + = true  = true
> +
> +3. Send DEFSLVS  DEFSLVS ISR DEFSLVS ISR
> + Set flag to indicateSet flag to indicate
> + DEFSLVS processing is   DEFSLVS processing is
> + pending pending
> + defslvs_done flag   defslvs_done flag
> + = false = false
> +
> + Defer DEFSLVS   Defer DEFSLVS
> + processing to bottomprocessing to bottom
> + halfhalf
> +
> +
> + DEFSLVS bottom half DEFSLVS bottom half
> + Try to acquire bus  Try to acquire bus
> + i3c_master_acquire_bus  i3c_master_acquire_bus
> +
> +
> + i3c_sec_mst_acquire_bus i3c_sec_mst_acquire_bus
> + state machine
> + 1. Wait until DA is
> +assigned
> +
> +4. Register all
> +   slaves and
> +   master devive
> +
> +5. Program bus mode
> +   as per board
> +   info (DTS)
> +
> +6. Send ENEC MR,
> +   HJ, SIR CCC
> +   Initialization
> +   complete
> +
> + 2. Check if DISEC MR2. Check if DISEC MR
> +is received is received
> +If not, initiateIf not, initiate
> +MR request  MR request
> +
> +
> + Sec master with highest priority (lowest address) get
> + mastership. Some controllers may not have way of knowing
> + if mastership is granted and can keep waiting for
> + GETACCMST.To avoid this, on reception of MR request
> + from highest priority secondary master, current master
> + send DISEC MR, HJ events to remaining master devices.
> +
> +MR request ISR
> +1. Disable IBI
> +   in controller
> +
> +MR request
> +bottom half
> +1. Send DISEC
> +   MR, HJ
> +   to all but
> +   master device
> +   to which MR
> +   is granted
> + 3. Received DISEC MR
> +Go back to WAIT
> +DA state
> +
> + 1. Wait until DA
> +is assigned
> + 2. Check if DISEC MR
> +is received
> +Wait until ENEC MR
> +is received before
> +

Re: [PATCH v4 1/2] dt-bindings: mtd: Add YAML for Nand Flash Controller support

2020-04-29 Thread Boris Brezillon
On Wed, 29 Apr 2020 18:42:04 +0800
"Ramuthevar,Vadivel MuruganX"
 wrote:

> From: Ramuthevar Vadivel Murugan 
> 
> Add YAML file for dt-bindings to support NAND Flash Controller
> on Intel's Lightning Mountain SoC.
> 
> Signed-off-by: Ramuthevar Vadivel Murugan 
> 
> ---
>  .../devicetree/bindings/mtd/intel,lgm-nand.yaml| 61 
> ++
>  1 file changed, 61 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mtd/intel,lgm-nand.yaml
> 
> diff --git a/Documentation/devicetree/bindings/mtd/intel,lgm-nand.yaml 
> b/Documentation/devicetree/bindings/mtd/intel,lgm-nand.yaml
> new file mode 100644
> index ..6dd899d367b4
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mtd/intel,lgm-nand.yaml
> @@ -0,0 +1,61 @@
> +# SPDX-License-Identifier: GPL-2.0
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/mtd/intel,lgm-nand.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Intel LGM SoC NAND Controller Device Tree Bindings
> +
> +allOf:
> +  - $ref: "nand-controller.yaml"
> +
> +maintainers:
> +  - Ramuthevar Vadivel Murugan 
> +
> +properties:
> +  compatible:
> +const: intel,lgm-nand-controller
> +
> +  reg:
> +maxItems: 1
> +
> +  clocks:
> +maxItems: 1
> +
> +  dmas:
> +maxItems: 2
> +
> +  dma-names:
> +enum:
> +  - rx
> +  - tx
> +
> +  pinctrl-names: true
> +
> +patternProperties:
> +  "^pinctrl-[0-9]+$": true
> +
> +  "^nand@[a-f0-9]+$":
> +type: object
> +properties:
> +  reg:
> +minimum: 0
> +maximum: 7
> +
> +  nand-ecc-mode: true
> +
> +  nand-ecc-algo:
> +const: hw
> +
> +additionalProperties: false
> +
> +required:
> +  - compatible
> +  - reg
> +  - clocks
> +  - clock-names
> +  - dmas
> +
> +additionalProperties: false
> +
> +...

Can you provide an example? I'd like to make sure the binding looks
good.


Re: [PATCH v4 2/2] mtd: rawnand: Add NAND controller support on Intel LGM SoC

2020-04-29 Thread Boris Brezillon
On Wed, 29 Apr 2020 23:18:31 +0800
"Ramuthevar, Vadivel MuruganX"
 wrote:

> Hi Boris,
> 
> On 29/4/2020 10:48 pm, Boris Brezillon wrote:
> > On Wed, 29 Apr 2020 22:33:37 +0800
> > "Ramuthevar, Vadivel MuruganX"
> >  wrote:
> >   
> >> Hi Boris,
> >>
> >> On 29/4/2020 10:22 pm, Boris Brezillon wrote:  
> >>> On Wed, 29 Apr 2020 18:42:05 +0800
> >>> "Ramuthevar, Vadivel MuruganX"
> >>>  wrote:
> >>>  
> >>>> +
> >>>> +#define EBU_ADDR_SEL(n) (0x20 + (n) * 4)
> >>>> +#define EBU_ADDR_MASK   (5 << 4)  
> >>>
> >>> It's still unclear what ADDR_MASK is for. Can you add a comment
> >>> explaining what it does?  
> >>
> >> Thank you Boris, keep review and giving inputs, will update.  
> > 
> > Can you please explain it here before sending a new version?  
> 
> Memory Region Address Mask:
> Specifies the number of right-most bits in the base address that should 
> be included in the address comparison. bits positions(7:4).

Okay, then the macro should be 

#define EBU_ADDR_MASK(x)((x) << 4)

And now I'd like you to explain why 5 is the right value for that field
(I guess that has to do with the position of the CS/ALE/CLE pins).

> 
> >>>  
> >>>> +#define EBU_ADDR_SEL_REGEN  0x1  
> >>>
> >>>  
> >>>> +
> >>>> +writel(lower_32_bits(ebu_host->cs[ebu_host->cs_num].nand_pa) |
> >>>> +   EBU_ADDR_SEL_REGEN | EBU_ADDR_MASK,
> >>>> +   ebu_host->ebu + EBU_ADDR_SEL(reg));

You set EBU_ADDR_SEL(reg) once here...

> >>>> +
> >>>> +writel(EBU_MEM_BASE_CS_0 | EBU_ADDR_MASK | EBU_ADDR_SEL_REGEN,
> >>>> +   ebu_host->ebu + EBU_ADDR_SEL(0));
> >>>> +writel(EBU_MEM_BASE_CS_1 | EBU_ADDR_MASK | EBU_ADDR_SEL_REGEN,
> >>>> +   ebu_host->ebu + EBU_ADDR_SEL(reg));  

... and a second time here. That sounds like overwriting the
EBU_ADDR_SEL(reg) register to me.

> >>>
> >>> That's super weird. You seem to set EBU_ADDR_SEL(reg) twice. Are you
> >>> sure that's needed, and are we setting EBU_ADDR_SEL(0) here?  
> >>
> >> You are right, its weird only, but we need it, since different chip
> >> select has different memory region access address.  
> > 
> > Well, that doesn't make any sense, the second write to
> > EBU_ADDR_SEL(reg) overrides the first one, meaning that nand_pa is
> > actually never written to ADDR_SEL(reg).  
> 
> it will not overwrite the first one, since two different registers
> EBU_ADDR_SEL_0 EBU_ADDR_SEL  20H
> EBU_ADDR_SEL_1 EBU_ADDR_SEL  24H

See my above.

> 
> it is an internal address selection w.r.t chip select for nand physical 
> address update.
> 
> 
> >   
> >>
> >> Yes , we are setting both CS0 and CS1 memory access region, if you have
> >> any concern to optimize, please suggest me, Thanks!  
> > 
> > If you want to setup both CS, and the address written in EBU_ADDR_SEL(x)
> > is really related to the nand_pa address, then retrieve resources for
> > all CS ranges.   
> If it's not related, please explain what those
> > EBU_MEM_BASE_CS_X values encode.  
> 
> Memory Region Base Address
> FPI Bus addresses are compared to this base address in conjunction with 
> the mask control(EBU_ADDR_MASK). Driver need to program this field!

That's not explaining what the base address should be. Is 'nand_pa' the
value we should have there?


  1   2   3   4   5   6   7   8   9   10   >