[RFC PATCH 0/2] video: ti: am335x: drop pre-driver-model code
The commit [1] also removed the code with driver model support, I preferred to start from a revert and apply the necessary changes in a second commit, rather than restore the removed modules. [1] 82f7b869f5d7a ("video: Drop CONFIG_AM335X_LCD") Dario Binacchi (2): Revert "video: Drop CONFIG_AM335X_LCD" video: ti: am335x: drop pre-driver-model code drivers/video/Kconfig | 2 + drivers/video/Makefile | 1 + drivers/video/ti/Kconfig| 8 + drivers/video/ti/Makefile | 6 + drivers/video/ti/tilcdc-panel.c | 172 + drivers/video/ti/tilcdc-panel.h | 14 ++ drivers/video/ti/tilcdc.c | 426 drivers/video/ti/tilcdc.h | 38 +++ 8 files changed, 667 insertions(+) create mode 100644 drivers/video/ti/Kconfig create mode 100644 drivers/video/ti/Makefile create mode 100644 drivers/video/ti/tilcdc-panel.c create mode 100644 drivers/video/ti/tilcdc-panel.h create mode 100644 drivers/video/ti/tilcdc.c create mode 100644 drivers/video/ti/tilcdc.h -- 2.32.0
[PATCH v4] cmd: mtd: check if a block has to be skipped or erased
As reported by patch [1], the `mtd erase' command should not erase bad blocks. To force bad block erasing you have to use the `mtd erase.dontskipbad' command. This patch tries to fix the same issue without modifying code taken from the linux kernel, in order to make further upgrades easier. [1] https://lore.kernel.org/all/20221006031501.110290-2-mikhail.kshevets...@iopsys.eu/ Suggested-by: Michael Trimarchi Co-developed-by: Michael Trimarchi Signed-off-by: Michael Trimarchi Co-developed-by: Mikhail Kshevetskiy Signed-off-by: Mikhail Kshevetskiy Tested-by: Mikhail Kshevetskiy Signed-off-by: Dario Binacchi --- Changes in v4: - Use the first version of the patch and fix the check of value returned by the mtd_erase(). - Change the commit author. Changes in v3: - Simplify the code. mtd_erase() can't return a bad block error. Print the messaged where the bad block is found. Changes in v2: - Change the commit author - Do not continue to erase if scrub option is enabled and a bad block was found but return from the function. - Update the patch tags. cmd/mtd.c | 28 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/cmd/mtd.c b/cmd/mtd.c index ad5cc9827d55..eb6e2d6892ff 100644 --- a/cmd/mtd.c +++ b/cmd/mtd.c @@ -434,19 +434,31 @@ static int do_mtd_erase(struct cmd_tbl *cmdtp, int flag, int argc, erase_op.mtd = mtd; erase_op.addr = off; erase_op.len = mtd->erasesize; - erase_op.scrub = scrub; while (len) { - ret = mtd_erase(mtd, &erase_op); + if (!scrub) { + ret = mtd_block_isbad(mtd, erase_op.addr); + if (ret < 0) { + printf("Failed to get bad block at 0x%08llx\n", + erase_op.addr); + ret = CMD_RET_FAILURE; + goto out_put_mtd; + } - if (ret) { - /* Abort if its not a bad block error */ - if (ret != -EIO) - break; - printf("Skipping bad block at 0x%08llx\n", - erase_op.addr); + if (ret > 0) { + printf("Skipping bad block at 0x%08llx\n", + erase_op.addr); + ret = 0; + len -= mtd->erasesize; + erase_op.addr += mtd->erasesize; + continue; + } } + ret = mtd_erase(mtd, &erase_op); + if (ret && ret != -EIO) + break; + len -= mtd->erasesize; erase_op.addr += mtd->erasesize; } -- 2.32.0
Re: [PATCH v2] cmd: mtd: check if a block has to be skipped or erased
Hi Simon, On Wed, Oct 26, 2022 at 1:35 AM Simon Glass wrote: > > Hi, > > On Mon, 24 Oct 2022 at 03:35, Dario Binacchi > wrote: > > > > From: Mikhail Kshevetskiy > > > > As reported by patch [1], the `mtd erase' command should not erase bad > > blocks. > > To force bad block erasing you have to use the `mtd erase.dontskipbad' > > command. > > > > This patch tries to fix the same issue without modifying code taken > > from the linux kernel, in order to make further upgrades easier. > > > > [1] > > https://lore.kernel.org/all/20221006031501.110290-2-mikhail.kshevets...@iopsys.eu/ > > Suggested-by: Michael Trimarchi > > Co-developed-by: Michael Trimarchi > > Signed-off-by: Michael Trimarchi > > Co-developed-by: Dario Binacchi > > Signed-off-by: Dario Binacchi > > Tested-by: Mikhail Kshevetskiy > > Signed-off-by: Mikhail Kshevetskiy > > > > --- > > > > Changes in v2: > > - Change the commit author > > - Do not continue to erase if scrub option is enabled and a bad block > > was found but return from the function. > > - Update the patch tags. > > > > cmd/mtd.c | 17 +++-- > > 1 file changed, 15 insertions(+), 2 deletions(-) > > Can we get some tests in test/dm/mtd.c? We are thinking about it. Probably not soon, but we are thinking about what and how to add them. Thanks and regards, Dario > > Regards, > Simon -- Dario Binacchi Embedded Linux Developer dario.binac...@amarulasolutions.com __ Amarula Solutions SRL Via Le Canevare 30, 31100 Treviso, Veneto, IT T. +39 042 243 5310 i...@amarulasolutions.com www.amarulasolutions.com
Re: [PATCH v3] cmd: mtd: check if a block has to be skipped or erased
Hi Mikhail, On Wed, Oct 26, 2022 at 2:56 PM Mikhail Kshevetskiy wrote: > > On 26.10.2022 09:29, Dario Binacchi wrote: > > > [External email] > > > > > > > > > > > > Hi Mikhail, > > > > On Mon, Oct 24, 2022 at 1:24 PM Mikhail Kshevetskiy > > wrote: > >> > >> On 24.10.2022 12:44, Dario Binacchi wrote: > >>> [External email] > >>> > >>> > >>> > >>> > >>> > >>> From: Mikhail Kshevetskiy > >>> > >>> As reported by patch [1], the `mtd erase' command should not erase bad > >>> blocks. > >>> To force bad block erasing you have to use the `mtd erase.dontskipbad' > >>> command. > >>> > >>> This patch tries to fix the same issue without modifying code taken > >>> from the linux kernel, in order to make further upgrades easier. > >>> > >>> [1] > >>> https://eur03.safelinks.protection.outlook.com/?url=https%3A%2F%2Flore.kernel.org%2Fall%2F20221006031501.110290-2-mikhail.kshevetskiy%40iopsys.eu%2F&data=05%7C01%7Cmikhail.kshevetskiy%40iopsys.eu%7C02dff372bf00435cd94208dab71b6aed%7C7ff78d652de440f586750569e5c7a65d%7C0%7C0%7C638023625630435867%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=YRmQ5XcWRw8gcy4Hy3nK29J%2FnttlD10lQvH%2B5YnBrxU%3D&reserved=0 > >>> Suggested-by: Michael Trimarchi > >>> Co-developed-by: Michael Trimarchi > >>> Signed-off-by: Michael Trimarchi > >>> Co-developed-by: Dario Binacchi > >>> Signed-off-by: Dario Binacchi > >>> Tested-by: Mikhail Kshevetskiy > >>> Signed-off-by: Mikhail Kshevetskiy > >>> > >>> --- > >>> > >>> Changes in v3: > >>> - Simplify the code. mtd_erase() can't return a bad block error. Print > >>> the messaged where the bad block is found. > >>> > >>> Changes in v2: > >>> - Change the commit author > >>> - Do not continue to erase if scrub option is enabled and a bad block > >>> was found but return from the function. > >>> - Update the patch tags. > >>> > >>> cmd/mtd.c | 24 > >>> 1 file changed, 16 insertions(+), 8 deletions(-) > >>> > >>> diff --git a/cmd/mtd.c b/cmd/mtd.c > >>> index ad5cc9827d55..29b2a9c04c0c 100644 > >>> --- a/cmd/mtd.c > >>> +++ b/cmd/mtd.c > >>> @@ -434,19 +434,27 @@ static int do_mtd_erase(struct cmd_tbl *cmdtp, int > >>> flag, int argc, > >>> erase_op.mtd = mtd; > >>> erase_op.addr = off; > >>> erase_op.len = mtd->erasesize; > >>> - erase_op.scrub = scrub; > >>> > >>> while (len) { > >>> - ret = mtd_erase(mtd, &erase_op); > >>> - > >>> - if (ret) { > >>> - /* Abort if its not a bad block error */ > >>> - if (ret != -EIO) > >>> + if (!scrub) { > >>> + ret = mtd_block_isbad(mtd, erase_op.addr); > >>> + if (ret < 0) { > >>> + printf("Failed to get bad block at > >>> 0x%08llx\n", > >>> + erase_op.addr); > >>> + ret = CMD_RET_FAILURE; > >>> + goto out_put_mtd; > >>> + } else if (ret > 0) { > >>> + printf("Skipping bad block at 0x%08llx\n", > >>> + erase_op.addr); > >>> + ret = -EIO; > >>> break; > >>> - printf("Skipping bad block at 0x%08llx\n", > >>> - erase_op.addr); > >>> + } > >>> } > >>> > >>> + ret = mtd_erase(mtd, &erase_op); > >>> + if (ret) > >>> + break; > >>> + > >> mtd_erase() can return -EIO, see drivers/mtd/nand/spi/core.c function > >> spinand_mtd_erase() > > If I compare my original patch [1] with yours [2], I see no difference > >
Re: [PATCH v3] cmd: mtd: check if a block has to be skipped or erased
Hi Mikhail, On Mon, Oct 24, 2022 at 1:24 PM Mikhail Kshevetskiy wrote: > > > On 24.10.2022 12:44, Dario Binacchi wrote: > > [External email] > > > > > > > > > > > > From: Mikhail Kshevetskiy > > > > As reported by patch [1], the `mtd erase' command should not erase bad > > blocks. > > To force bad block erasing you have to use the `mtd erase.dontskipbad' > > command. > > > > This patch tries to fix the same issue without modifying code taken > > from the linux kernel, in order to make further upgrades easier. > > > > [1] > > https://eur03.safelinks.protection.outlook.com/?url=https%3A%2F%2Flore.kernel.org%2Fall%2F20221006031501.110290-2-mikhail.kshevetskiy%40iopsys.eu%2F&data=05%7C01%7Cmikhail.kshevetskiy%40iopsys.eu%7C0ce3c4f03458440084dd08dab5a44a0e%7C7ff78d652de440f586750569e5c7a65d%7C0%7C0%7C638022014468655016%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=VMQov1%2FRUmymW2G452jlOveOu2tFCE5MtzssuP2Ri3Y%3D&reserved=0 > > Suggested-by: Michael Trimarchi > > Co-developed-by: Michael Trimarchi > > Signed-off-by: Michael Trimarchi > > Co-developed-by: Dario Binacchi > > Signed-off-by: Dario Binacchi > > Tested-by: Mikhail Kshevetskiy > > Signed-off-by: Mikhail Kshevetskiy > > > > --- > > > > Changes in v3: > > - Simplify the code. mtd_erase() can't return a bad block error. Print > > the messaged where the bad block is found. > > > > Changes in v2: > > - Change the commit author > > - Do not continue to erase if scrub option is enabled and a bad block > > was found but return from the function. > > - Update the patch tags. > > > > cmd/mtd.c | 24 > > 1 file changed, 16 insertions(+), 8 deletions(-) > > > > diff --git a/cmd/mtd.c b/cmd/mtd.c > > index ad5cc9827d55..29b2a9c04c0c 100644 > > --- a/cmd/mtd.c > > +++ b/cmd/mtd.c > > @@ -434,19 +434,27 @@ static int do_mtd_erase(struct cmd_tbl *cmdtp, int > > flag, int argc, > > erase_op.mtd = mtd; > > erase_op.addr = off; > > erase_op.len = mtd->erasesize; > > - erase_op.scrub = scrub; > > > > while (len) { > > - ret = mtd_erase(mtd, &erase_op); > > - > > - if (ret) { > > - /* Abort if its not a bad block error */ > > - if (ret != -EIO) > > + if (!scrub) { > > + ret = mtd_block_isbad(mtd, erase_op.addr); > > + if (ret < 0) { > > + printf("Failed to get bad block at > > 0x%08llx\n", > > + erase_op.addr); > > + ret = CMD_RET_FAILURE; > > + goto out_put_mtd; > > + } else if (ret > 0) { > > + printf("Skipping bad block at 0x%08llx\n", > > + erase_op.addr); > > + ret = -EIO; > > break; > > - printf("Skipping bad block at 0x%08llx\n", > > - erase_op.addr); > > + } > > } > > > > + ret = mtd_erase(mtd, &erase_op); > > + if (ret) > > + break; > > + > > mtd_erase() can return -EIO, see drivers/mtd/nand/spi/core.c function > spinand_mtd_erase() If I compare my original patch [1] with yours [2], I see no difference in behavior except for ret checking after calling mtd_erase() which, in my case, was wrong. Do you agree? Further, checking for a bad block inside the do_mtd_erase(), the mtd_erase() can return -EIO only in the case of a protected block. In case of the scrub option enabled the bad block is erased, otherwise the block is jumped in the do_mtd_erase() without calling the mtd_erase(). I think that now we can distinguish between a bad block and a protected block inside the do_mtd_erase(), always if it's true that the -EIO error is only returned for bad/protected block by low level operations. [1] https://patchwork.ozlabs.org/project/uboot/patch/20221021152929.3598415-1-dario.binac...@amarulasolutions.com/ [2] https://patchwork.amarulasolutions.com/patch/2458/ Thanks and regards, Dario > > > > > len -= mtd->erasesize; > > erase_op.addr += mtd->erasesize; > > } > > -- > > 2.32.0 > > -- Dario Binacchi Embedded Linux Developer dario.binac...@amarulasolutions.com __ Amarula Solutions SRL Via Le Canevare 30, 31100 Treviso, Veneto, IT T. +39 042 243 5310 i...@amarulasolutions.com www.amarulasolutions.com
[PATCH v3] cmd: mtd: check if a block has to be skipped or erased
From: Mikhail Kshevetskiy As reported by patch [1], the `mtd erase' command should not erase bad blocks. To force bad block erasing you have to use the `mtd erase.dontskipbad' command. This patch tries to fix the same issue without modifying code taken from the linux kernel, in order to make further upgrades easier. [1] https://lore.kernel.org/all/20221006031501.110290-2-mikhail.kshevets...@iopsys.eu/ Suggested-by: Michael Trimarchi Co-developed-by: Michael Trimarchi Signed-off-by: Michael Trimarchi Co-developed-by: Dario Binacchi Signed-off-by: Dario Binacchi Tested-by: Mikhail Kshevetskiy Signed-off-by: Mikhail Kshevetskiy --- Changes in v3: - Simplify the code. mtd_erase() can't return a bad block error. Print the messaged where the bad block is found. Changes in v2: - Change the commit author - Do not continue to erase if scrub option is enabled and a bad block was found but return from the function. - Update the patch tags. cmd/mtd.c | 24 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/cmd/mtd.c b/cmd/mtd.c index ad5cc9827d55..29b2a9c04c0c 100644 --- a/cmd/mtd.c +++ b/cmd/mtd.c @@ -434,19 +434,27 @@ static int do_mtd_erase(struct cmd_tbl *cmdtp, int flag, int argc, erase_op.mtd = mtd; erase_op.addr = off; erase_op.len = mtd->erasesize; - erase_op.scrub = scrub; while (len) { - ret = mtd_erase(mtd, &erase_op); - - if (ret) { - /* Abort if its not a bad block error */ - if (ret != -EIO) + if (!scrub) { + ret = mtd_block_isbad(mtd, erase_op.addr); + if (ret < 0) { + printf("Failed to get bad block at 0x%08llx\n", + erase_op.addr); + ret = CMD_RET_FAILURE; + goto out_put_mtd; + } else if (ret > 0) { + printf("Skipping bad block at 0x%08llx\n", + erase_op.addr); + ret = -EIO; break; - printf("Skipping bad block at 0x%08llx\n", - erase_op.addr); + } } + ret = mtd_erase(mtd, &erase_op); + if (ret) + break; + len -= mtd->erasesize; erase_op.addr += mtd->erasesize; } -- 2.32.0
[PATCH v2] cmd: mtd: check if a block has to be skipped or erased
From: Mikhail Kshevetskiy As reported by patch [1], the `mtd erase' command should not erase bad blocks. To force bad block erasing you have to use the `mtd erase.dontskipbad' command. This patch tries to fix the same issue without modifying code taken from the linux kernel, in order to make further upgrades easier. [1] https://lore.kernel.org/all/20221006031501.110290-2-mikhail.kshevets...@iopsys.eu/ Suggested-by: Michael Trimarchi Co-developed-by: Michael Trimarchi Signed-off-by: Michael Trimarchi Co-developed-by: Dario Binacchi Signed-off-by: Dario Binacchi Tested-by: Mikhail Kshevetskiy Signed-off-by: Mikhail Kshevetskiy --- Changes in v2: - Change the commit author - Do not continue to erase if scrub option is enabled and a bad block was found but return from the function. - Update the patch tags. cmd/mtd.c | 17 +++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/cmd/mtd.c b/cmd/mtd.c index ad5cc9827d55..a314745e95e1 100644 --- a/cmd/mtd.c +++ b/cmd/mtd.c @@ -434,11 +434,24 @@ static int do_mtd_erase(struct cmd_tbl *cmdtp, int flag, int argc, erase_op.mtd = mtd; erase_op.addr = off; erase_op.len = mtd->erasesize; - erase_op.scrub = scrub; while (len) { - ret = mtd_erase(mtd, &erase_op); + if (!scrub) { + ret = mtd_block_isbad(mtd, erase_op.addr); + if (ret < 0) { + printf("Failed to get bad block at 0x%08llx\n", + erase_op.addr); + ret = CMD_RET_FAILURE; + goto out_put_mtd; + } else if (ret > 0) { + /* simulate bad block behavior */ + ret = -EIO; + goto skip_block_erasing; + } + } + ret = mtd_erase(mtd, &erase_op); +skip_block_erasing: if (ret) { /* Abort if its not a bad block error */ if (ret != -EIO) -- 2.32.0
Re: [PATCH v2] cmd: mtd: try to erase bad blocks only if scrub flag is provided
Hi Mikhail, On Mon, Oct 24, 2022 at 10:27 AM Michael Nazzareno Trimarchi < mich...@amarulasolutions.com> wrote: > Hi > > On Mon, Oct 24, 2022 at 10:20 AM Mikhail Kshevetskiy > wrote: > > > > > > On 24.10.2022 10:49, Michael Nazzareno Trimarchi wrote: > > > [External email] > > > > > > > > > > > > > > > > > > Hi Mikhail > > > > > > On Mon, Oct 24, 2022 at 9:37 AM Mikhail Kshevetskiy > > > wrote: > > >> 'mtd erase' command should not erase bad blocks. To force bad block > erasing > > >> there is 'mtd erase.dontskipbad' command. Unfortunately nand layer > erases > > >> bad blocks unconditionally. This is wrong. > > >> > > >> Fix issue by adding bad block checks to do_mtd_erase() function in > the case > > >> srub flag is not provided. We can't simplify code by eliminating -EIO > result > > >> check of mtd_erase() as it will terminate erasing with > CMD_RET_SUCCESS. > > >> > > >> Thanks to Dario Binacchi for > his patch. > > >> > > >> Signed-off-by: Mikhail Kshevetskiy > > >> --- > > >> cmd/mtd.c | 17 +++-- > > >> 1 file changed, 15 insertions(+), 2 deletions(-) > > >> > > >> diff --git a/cmd/mtd.c b/cmd/mtd.c > > >> index ad5cc9827d..a314745e95 100644 > > >> --- a/cmd/mtd.c > > >> +++ b/cmd/mtd.c > > >> @@ -434,11 +434,24 @@ static int do_mtd_erase(struct cmd_tbl *cmdtp, > int flag, int argc, > > >> erase_op.mtd = mtd; > > >> erase_op.addr = off; > > >> erase_op.len = mtd->erasesize; > > >> - erase_op.scrub = scrub; > > >> > > >> while (len) { > > >> - ret = mtd_erase(mtd, &erase_op); > > >> + if (!scrub) { > > >> + ret = mtd_block_isbad(mtd, erase_op.addr); > > >> + if (ret < 0) { > > >> + printf("Failed to get bad block at > 0x%08llx\n", > > >> + erase_op.addr); > > >> + ret = CMD_RET_FAILURE; > > >> + goto out_put_mtd; > > >> + } else if (ret > 0) { > > >> + /* simulate bad block behavior */ > > >> + ret = -EIO; > > >> + goto skip_block_erasing; > > >> + } > > >> + } > > >> > > >> + ret = mtd_erase(mtd, &erase_op); > > >> +skip_block_erasing: > > >> if (ret) { > > >> /* Abort if its not a bad block error */ > > >> if (ret != -EIO) > > >> -- > > >> 2.35.1 > > >> > > > As I stated in a different email. Please re-post with the right > sign-off > > > > > > Michael > > > > There is an issue with Dario Binacchi patch. Please see my comments for > > his patch. > > > > I just suggest a fix. I am sorry if I do it wrong way. > > > > Mikhail > > There are two ways I can see: > Repost the v3 starting from Dario one and improve the commit message > for him. You can add your signed off and tested by And please add these tags: Suggested-by: Michael Trimarchi Co-developed-by: Michael Trimarchi Signed-off-by: Michael Trimarchi Co-developed-by: Dario Binacchi Signed-off-by: Dario Binacchi Thanks and regards, Dario > or > wait Dario to resend with all the suggestion you have made > > We think that you rise a correct problem and you help us to > understand. We just decided to fix on uboot level and not core level. > > Michael > > > > > > > -- > > > Michael Nazzareno Trimarchi > > > Co-Founder & Chief Executive Officer > > > M. +39 347 913 2170 > > > mich...@amarulasolutions.com > > > __ > > > > > > Amarula Solutions BV > > > Joop Geesinkweg 125, 1114 AB, Amsterdam, NL > > > T. +31 (0)85 111 9172 > > > i...@amarulasolutions.com > > > > https://eur03.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.amarulasolutions.com%2F&data=05%7C01%7Cmikhail.kshevetskiy%40iopsys.eu%7Ca0041129e25a4456725708dab594462c%7C7ff78d652de440f586750569e5c7a65d%7C0%7C0%7C638021945688614410%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=HASzL7T4QF8Kea8t6Dt7hQYnHGs1poC9gRPZ6N3SPEI%3D&reserved=0 > > > > -- > Michael Nazzareno Trimarchi > Co-Founder & Chief Executive Officer > M. +39 347 913 2170 > mich...@amarulasolutions.com > __ > > Amarula Solutions BV > Joop Geesinkweg 125, 1114 AB, Amsterdam, NL > T. +31 (0)85 111 9172 > i...@amarulasolutions.com > www.amarulasolutions.com > -- *Dario Binacchi* Embedded Linux Developer dario.binac...@amarulasolutions.com __ *Amarula Solutions SRL* Via Le Canevare 30, 31100 Treviso, Veneto, IT T. +39 042 243 5310 i...@amarulasolutions.com www.amarulasolutions.com
[PATCH] cmd: mtd: check if a block has to be skipped or erased
As reported by patch [1], the `mtd erase' command should not erase bad blocks. To force bad block erasing you have to use the `mtd erase.dontskipbad' command. This patch tries to fix the same issue without modifying code taken from the linux kernel, in order to make further upgrades easier. [1] https://lore.kernel.org/all/20221006031501.110290-2-mikhail.kshevets...@iopsys.eu/ Signed-off-by: Dario Binacchi Suggested-by: Michael Trimarchi Co-developed-by: Michael Trimarchi Signed-off-by: Michael Trimarchi Cc: Mikhail Kshevetskiy --- cmd/mtd.c | 28 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/cmd/mtd.c b/cmd/mtd.c index ad5cc9827d55..3330a428c018 100644 --- a/cmd/mtd.c +++ b/cmd/mtd.c @@ -434,19 +434,31 @@ static int do_mtd_erase(struct cmd_tbl *cmdtp, int flag, int argc, erase_op.mtd = mtd; erase_op.addr = off; erase_op.len = mtd->erasesize; - erase_op.scrub = scrub; while (len) { - ret = mtd_erase(mtd, &erase_op); + if (!scrub) { + ret = mtd_block_isbad(mtd, erase_op.addr); + if (ret < 0) { + printf("Failed to get bad block at 0x%08llx\n", + erase_op.addr); + ret = CMD_RET_FAILURE; + goto out_put_mtd; + } - if (ret) { - /* Abort if its not a bad block error */ - if (ret != -EIO) - break; - printf("Skipping bad block at 0x%08llx\n", - erase_op.addr); + if (ret > 0) { + printf("Skipping bad block at 0x%08llx\n", + erase_op.addr); + ret = 0; + len -= mtd->erasesize; + erase_op.addr += mtd->erasesize; + continue; + } } + ret = mtd_erase(mtd, &erase_op); + if (ret) + break; + len -= mtd->erasesize; erase_op.addr += mtd->erasesize; } -- 2.32.0
Pull request for u-boot-nand-20221009
Hi Tom, The following changes since commit f5717231abad983b4d8f87db612ae60dec86cb1b: Merge branch '2022-10-07-riscv-toolchain-update' (2022-10-07 11:25:05 -0400) are available in the Git repository at: https://source.denx.de/u-boot/custodians/u-boot-nand-flash.git tags/u-boot-nand-20221009 for you to fetch changes up to 7676811867b54d4cb7b3356505d41511614884f3: mtd: Update the function name to 'rfree' (2022-10-09 10:42:26 +0200) Gitlab CI showed no issues: https://source.denx.de/u-boot/custodians/u-boot-nand-flash/-/pipelines/13750 Merge tag 'u-boot-nand-20221009' of https://source.denx.de/u-boot/custodians/u-boot-nand-flash into next - mtd: Update the function name to 'rfree' - Support NAND ONFI EDO mode for imx8mn architecture - dm: clk: add missing stub when CONFIG_CLK is deactivated ---- Dario Binacchi (3): dm: clk: add missing stub when CONFIG_CLK is deactivated mtd: mxs_nand: don't get the gpmi_apbh_dma clock mtd: mxs_nand: get the clock with the right name Fabio Estevam (1): mtd: Update the function name to 'rfree' Michael Trimarchi (4): clk: imx: gate2 support shared counter and relative clock functions clk: imx: clk-imx8mn add gpmi nand clocks imx: gpmi: Add register needed to control nand bus timing mtd: mxs_nand: Support EDO mode for imx8mn architecture Roger Quadros (1): mtd: nand: Fix SPL build after migration of CONFIG_SYS_NAND_SELF_INIT to Kconfig arch/arm/include/asm/mach-imx/regs-gpmi.h | 9 + drivers/clk/imx/clk-gate2.c | 15 +++- drivers/clk/imx/clk-imx8mn.c | 14 +++ drivers/clk/imx/clk.h | 27 +++-- drivers/mtd/nand/raw/mxs_nand.c | 200 +++ drivers/mtd/nand/raw/mxs_nand_dt.c| 79 +++--- drivers/mtd/nand/raw/nand.c | 2 +- include/clk.h | 32 +++- include/linux/mtd/mtd.h | 2 +- include/mxs_nand.h| 3 ++ 10 files changed, 335 insertions(+), 48 deletions(-) -- *Dario Binacchi* Embedded Linux Developer dario.binac...@amarulasolutions.com __ *Amarula Solutions SRL* Via Le Canevare 30, 31100 Treviso, Veneto, IT T. +39 042 243 5310 i...@amarulasolutions.com www.amarulasolutions.com
Re: [PATCH 7/7] mtd: mxs_nand: Support EDO mode for imx8mn architecture
Hi Michael, On Wed, Sep 28, 2022 at 10:45 AM Dario Binacchi < dario.binac...@amarulasolutions.com> wrote: > From: Michael Trimarchi > > Add support for imx8mn architecture in order to run the NAND > in fast edo mode. > > Signed-off-by: Michael Trimarchi > Signed-off-by: Dario Binacchi > > --- > > drivers/mtd/nand/raw/mxs_nand.c| 200 + > drivers/mtd/nand/raw/mxs_nand_dt.c | 66 ++ > include/mxs_nand.h | 3 + > 3 files changed, 242 insertions(+), 27 deletions(-) > > diff --git a/drivers/mtd/nand/raw/mxs_nand.c > b/drivers/mtd/nand/raw/mxs_nand.c > index 7893e9d7e343..65eab4c8088a 100644 > --- a/drivers/mtd/nand/raw/mxs_nand.c > +++ b/drivers/mtd/nand/raw/mxs_nand.c > @@ -14,6 +14,7 @@ > */ > > #include > +#include > #include > #include > #include > @@ -26,10 +27,12 @@ > #include > #include > #include > +#include > #include > #include > #include > #include > +#include > > #defineMXS_NAND_DMA_DESCRIPTOR_COUNT 4 > > @@ -49,6 +52,10 @@ > #endif > > #defineMXS_NAND_BCH_TIMEOUT1 > +#defineUSEC_PER_SEC100 > +#defineNSEC_PER_SEC10L > + > +#define TO_CYCLES(duration, period) DIV_ROUND_UP_ULL(duration, period) > > struct nand_ecclayout fake_ecc_layout; > > @@ -1344,6 +1351,196 @@ err1: > return ret; > } > > +/* > + * <1> Firstly, we should know what's the GPMI-clock means. > + * The GPMI-clock is the internal clock in the gpmi nand controller. > + * If you set 100MHz to gpmi nand controller, the GPMI-clock's period > + * is 10ns. Mark the GPMI-clock's period as GPMI-clock-period. > + * > + * <2> Secondly, we should know what's the frequency on the nand chip > pins. > + * The frequency on the nand chip pins is derived from the GPMI-clock. > + * We can get it from the following equation: > + * > + * F = G / (DS + DH) > + * > + * F : the frequency on the nand chip pins. > + * G : the GPMI clock, such as 100MHz. > + * DS : GPMI_HW_GPMI_TIMING0:DATA_SETUP > + * DH : GPMI_HW_GPMI_TIMING0:DATA_HOLD > + * > + * <3> Thirdly, when the frequency on the nand chip pins is above 33MHz, > + * the nand EDO(extended Data Out) timing could be applied. > + * The GPMI implements a feedback read strobe to sample the read data. > + * The feedback read strobe can be delayed to support the nand EDO > timing > + * where the read strobe may deasserts before the read data is valid, > and > + * read data is valid for some time after read strobe. > + * > + * The following figure illustrates some aspects of a NAND Flash read: > + * > + * |<---tREA>| > + * | | > + * | | | > + * |<--tRP-->| | > + * | | | > + * __ ___|__ > + * RDN\/ | > + * | > + * /-\ > + * Read Data--< >- > + * \-/ > + *| | > + *|<-D->| > + * FeedbackRDN > + * \___/ > + * > + * D stands for delay, set in the HW_GPMI_CTRL1:RDN_DELAY. > + * > + * > + * <4> Now, we begin to describe how to compute the right RDN_DELAY. > + * > + * 4.1) From the aspect of the nand chip pins: > + *Delay = (tREA + C - tRP) {1} > + * > + *tREA : the maximum read access time. > + *C: a constant to adjust the delay. default is 4000ps. > + *tRP : the read pulse width, which is exactly: > + * tRP = (GPMI-clock-period) * DATA_SETUP > + * > + * 4.2) From the aspect of the GPMI nand controller: > + * Delay = RDN_DELAY * 0.125 * RP{2} > + * > + * RP : the DLL reference period. > + *if (GPMI-clock-period > DLL_THRETHOLD) > + * RP = GPMI-clock-period / 2; > + *else > + * RP = GPMI-clock-period; > + * > + *Set the HW_GPMI_CTRL1:HALF_PERIOD if GPMI-clock-period > + *is greater DLL_THRETHOLD. In other SOCs, the DLL_THRETHOLD > + *is 16000ps, but in mx6q, we use
Re: [u-boot][PATCH] mtd: nand: Fix SPL build after migration of CONFIG_SYS_NAND_SELF_INIT to Kconfig
Hi Roger, On Wed, Sep 28, 2022 at 1:42 PM Roger Quadros wrote: > This fixes the below build error if nand.c is included in > an SPL build. > > /work/u-boot/drivers/mtd/nand/raw/nand.c: In function ‘nand_init_chip’: > /work/u-boot/drivers/mtd/nand/raw/nand.c:82:28: error: ‘nand_chip’ > undeclared (first use in this function) >82 | struct nand_chip *nand = &nand_chip[i]; > |^ > /work/u-boot/drivers/mtd/nand/raw/nand.c:82:28: note: each undeclared > identifier is reported only once for each function it appears in > /work/u-boot/drivers/mtd/nand/raw/nand.c:84:20: error: ‘base_address’ > undeclared (first use in this function); did you mean ‘base_addr’? >84 | ulong base_addr = base_address[i]; > |^~~~ > |base_addr > > Fixes: 068c41f1cc77 ("Finish conversion CONFIG_SYS_NAND_SELF_INIT to > Kconfig") > Signed-off-by: Roger Quadros > --- > drivers/mtd/nand/raw/nand.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/mtd/nand/raw/nand.c b/drivers/mtd/nand/raw/nand.c > index 4b5560dd24..14bca12024 100644 > --- a/drivers/mtd/nand/raw/nand.c > +++ b/drivers/mtd/nand/raw/nand.c > @@ -19,7 +19,7 @@ int nand_curr_device = -1; > > static struct mtd_info *nand_info[CONFIG_SYS_MAX_NAND_DEVICE]; > > -#ifndef CONFIG_SYS_NAND_SELF_INIT > +#if !CONFIG_IS_ENABLED(SYS_NAND_SELF_INIT) > static struct nand_chip nand_chip[CONFIG_SYS_MAX_NAND_DEVICE]; > static ulong base_address[CONFIG_SYS_MAX_NAND_DEVICE] = > CONFIG_SYS_NAND_BASE_LIST; > #endif > -- > 2.17.1 > > Applied to nand-next, thanks! Dario -- *Dario Binacchi* Embedded Linux Developer dario.binac...@amarulasolutions.com __ *Amarula Solutions SRL* Via Le Canevare 30, 31100 Treviso, Veneto, IT T. +39 042 243 5310 i...@amarulasolutions.com www.amarulasolutions.com
[PATCH 7/7] mtd: mxs_nand: Support EDO mode for imx8mn architecture
From: Michael Trimarchi Add support for imx8mn architecture in order to run the NAND in fast edo mode. Signed-off-by: Michael Trimarchi Signed-off-by: Dario Binacchi --- drivers/mtd/nand/raw/mxs_nand.c| 200 + drivers/mtd/nand/raw/mxs_nand_dt.c | 66 ++ include/mxs_nand.h | 3 + 3 files changed, 242 insertions(+), 27 deletions(-) diff --git a/drivers/mtd/nand/raw/mxs_nand.c b/drivers/mtd/nand/raw/mxs_nand.c index 7893e9d7e343..65eab4c8088a 100644 --- a/drivers/mtd/nand/raw/mxs_nand.c +++ b/drivers/mtd/nand/raw/mxs_nand.c @@ -14,6 +14,7 @@ */ #include +#include #include #include #include @@ -26,10 +27,12 @@ #include #include #include +#include #include #include #include #include +#include #defineMXS_NAND_DMA_DESCRIPTOR_COUNT 4 @@ -49,6 +52,10 @@ #endif #defineMXS_NAND_BCH_TIMEOUT1 +#defineUSEC_PER_SEC100 +#defineNSEC_PER_SEC10L + +#define TO_CYCLES(duration, period) DIV_ROUND_UP_ULL(duration, period) struct nand_ecclayout fake_ecc_layout; @@ -1344,6 +1351,196 @@ err1: return ret; } +/* + * <1> Firstly, we should know what's the GPMI-clock means. + * The GPMI-clock is the internal clock in the gpmi nand controller. + * If you set 100MHz to gpmi nand controller, the GPMI-clock's period + * is 10ns. Mark the GPMI-clock's period as GPMI-clock-period. + * + * <2> Secondly, we should know what's the frequency on the nand chip pins. + * The frequency on the nand chip pins is derived from the GPMI-clock. + * We can get it from the following equation: + * + * F = G / (DS + DH) + * + * F : the frequency on the nand chip pins. + * G : the GPMI clock, such as 100MHz. + * DS : GPMI_HW_GPMI_TIMING0:DATA_SETUP + * DH : GPMI_HW_GPMI_TIMING0:DATA_HOLD + * + * <3> Thirdly, when the frequency on the nand chip pins is above 33MHz, + * the nand EDO(extended Data Out) timing could be applied. + * The GPMI implements a feedback read strobe to sample the read data. + * The feedback read strobe can be delayed to support the nand EDO timing + * where the read strobe may deasserts before the read data is valid, and + * read data is valid for some time after read strobe. + * + * The following figure illustrates some aspects of a NAND Flash read: + * + * |<---tREA>| + * | | + * | | | + * |<--tRP-->| | + * | | | + * __ ___|__ + * RDN\/ | + * | + * /-\ + * Read Data--< >- + * \-/ + *| | + *|<-D->| + * FeedbackRDN + * \___/ + * + * D stands for delay, set in the HW_GPMI_CTRL1:RDN_DELAY. + * + * + * <4> Now, we begin to describe how to compute the right RDN_DELAY. + * + * 4.1) From the aspect of the nand chip pins: + *Delay = (tREA + C - tRP) {1} + * + *tREA : the maximum read access time. + *C: a constant to adjust the delay. default is 4000ps. + *tRP : the read pulse width, which is exactly: + * tRP = (GPMI-clock-period) * DATA_SETUP + * + * 4.2) From the aspect of the GPMI nand controller: + * Delay = RDN_DELAY * 0.125 * RP{2} + * + * RP : the DLL reference period. + *if (GPMI-clock-period > DLL_THRETHOLD) + * RP = GPMI-clock-period / 2; + *else + * RP = GPMI-clock-period; + * + *Set the HW_GPMI_CTRL1:HALF_PERIOD if GPMI-clock-period + *is greater DLL_THRETHOLD. In other SOCs, the DLL_THRETHOLD + *is 16000ps, but in mx6q, we use 12000ps. + * + * 4.3) since {1} equals {2}, we get: + * + * (tREA + 4000 - tRP) * 8 + * RDN_DELAY = --- {3} + * RP + */ +static void mxs_compute_timings(struct nand_chip *chip, + const struct nand_sdr_timings *sdr) +{ + struct mxs_nand_info *nand_info = nand_get_controller_data(chip); + unsigned long clk_rate; + unsigned int dll_wait_time_us; + unsigned int dll_threshold_ps = nand_info->max_chain_delay; + unsigned int period_ps, reference_period_ps; + unsigned int data_setup_cycles, data_hold_cycles, addr_setup_cycles; + unsigned int tRP_ps; + bool use_
[PATCH 6/7] mtd: mxs_nand: get the clock with the right name
Rename the gpmi_apb_bch clock name to gpmi_bch_apb, as you can find in the device tree. Fixes: commit a59691280daca ("MXS_NAND: Add clock support for iMX8") Signed-off-by: Dario Binacchi --- drivers/mtd/nand/raw/mxs_nand_dt.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/nand/raw/mxs_nand_dt.c b/drivers/mtd/nand/raw/mxs_nand_dt.c index c1e784832f33..94ee7ed9ec83 100644 --- a/drivers/mtd/nand/raw/mxs_nand_dt.c +++ b/drivers/mtd/nand/raw/mxs_nand_dt.c @@ -132,15 +132,15 @@ static int mxs_nand_dt_probe(struct udevice *dev) return ret; } - ret = clk_get_by_name(dev, "gpmi_apb_bch", &gpmi_clk); + ret = clk_get_by_name(dev, "gpmi_bch_apb", &gpmi_clk); if (ret < 0) { - debug("Can't get gpmi_apb_bch clk: %d\n", ret); + debug("Can't get gpmi_bch_apb clk: %d\n", ret); return ret; } ret = clk_enable(&gpmi_clk); if (ret < 0) { - debug("Can't enable gpmi_apb_bch clk: %d\n", ret); + debug("Can't enable gpmi_bch_apb clk: %d\n", ret); return ret; } } -- 2.32.0
[PATCH 5/7] mtd: mxs_nand: don't get the gpmi_apbh_dma clock
This clock name is not present in any U-boot and Linux kernel device tree. Fixes: commit a59691280daca ("MXS_NAND: Add clock support for iMX8") Signed-off-by: Dario Binacchi --- drivers/mtd/nand/raw/mxs_nand_dt.c | 13 - 1 file changed, 13 deletions(-) diff --git a/drivers/mtd/nand/raw/mxs_nand_dt.c b/drivers/mtd/nand/raw/mxs_nand_dt.c index b9833a646f01..c1e784832f33 100644 --- a/drivers/mtd/nand/raw/mxs_nand_dt.c +++ b/drivers/mtd/nand/raw/mxs_nand_dt.c @@ -143,19 +143,6 @@ static int mxs_nand_dt_probe(struct udevice *dev) debug("Can't enable gpmi_apb_bch clk: %d\n", ret); return ret; } - - /* this clock is used for apbh_dma, since the apbh dma does not support DM, - * we optionally enable it here - */ - ret = clk_get_by_name(dev, "gpmi_apbh_dma", &gpmi_clk); - if (ret < 0) { - debug("Can't get gpmi_apbh_dma clk: %d\n", ret); - } else { - ret = clk_enable(&gpmi_clk); - if (ret < 0) { - debug("Can't enable gpmi_apbh_dma clk: %d\n", ret); - } - } } return mxs_nand_init_ctrl(info); -- 2.32.0
[PATCH 4/7] imx: gpmi: Add register needed to control nand bus timing
From: Michael Trimarchi It is used as delay for gpmi write strobe. Signed-off-by: Michael Trimarchi Signed-off-by: Dario Binacchi --- arch/arm/include/asm/mach-imx/regs-gpmi.h | 9 + 1 file changed, 9 insertions(+) diff --git a/arch/arm/include/asm/mach-imx/regs-gpmi.h b/arch/arm/include/asm/mach-imx/regs-gpmi.h index 33daa53c45df..7a1577863195 100644 --- a/arch/arm/include/asm/mach-imx/regs-gpmi.h +++ b/arch/arm/include/asm/mach-imx/regs-gpmi.h @@ -93,6 +93,11 @@ struct mxs_gpmi_regs { #defineGPMI_CTRL1_DECOUPLE_CS (1 << 24) #defineGPMI_CTRL1_WRN_DLY_SEL_MASK (0x3 << 22) #defineGPMI_CTRL1_WRN_DLY_SEL_OFFSET 22 +#defineGPMI_CTRL1_WRN_DLY_SEL_4_TO_8NS 0x0 +#defineGPMI_CTRL1_WRN_DLY_SEL_6_TO_10NS0x1 +#defineGPMI_CTRL1_WRN_DLY_SEL_7_TO_12NS0x2 +#defineGPMI_CTRL1_WRN_DLY_SEL_NO_DELAY 0x3 + #defineGPMI_CTRL1_TIMEOUT_IRQ_EN (1 << 20) #defineGPMI_CTRL1_GANGED_RDYBUSY (1 << 19) #defineGPMI_CTRL1_BCH_MODE (1 << 18) @@ -111,6 +116,10 @@ struct mxs_gpmi_regs { #defineGPMI_CTRL1_ATA_IRQRDY_POLARITY (1 << 2) #defineGPMI_CTRL1_CAMERA_MODE (1 << 1) #defineGPMI_CTRL1_GPMI_MODE(1 << 0) +#defineGPMI_CTRL1_CLEAR_MASK (GPMI_CTRL1_WRN_DLY_SEL_MASK | \ +GPMI_CTRL1_DLL_ENABLE | \ + GPMI_CTRL1_RDN_DELAY_MASK | \ +GPMI_CTRL1_HALF_PERIOD) #defineGPMI_TIMING0_ADDRESS_SETUP_MASK (0xff << 16) #defineGPMI_TIMING0_ADDRESS_SETUP_OFFSET 16 -- 2.32.0
[PATCH 2/7] clk: imx: gate2 support shared counter and relative clock functions
From: Michael Trimarchi Add shared counter in order to avoid to swich off clock that are already used. Signed-off-by: Michael Trimarchi Signed-off-by: Dario Binacchi --- drivers/clk/imx/clk-gate2.c | 15 ++- drivers/clk/imx/clk.h | 27 +++ 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/drivers/clk/imx/clk-gate2.c b/drivers/clk/imx/clk-gate2.c index 40b2d4caab49..da2723023778 100644 --- a/drivers/clk/imx/clk-gate2.c +++ b/drivers/clk/imx/clk-gate2.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include "clk.h" @@ -33,6 +34,7 @@ struct clk_gate2 { u8 bit_idx; u8 cgr_val; u8 flags; + unsigned int*share_count; }; #define to_clk_gate2(_clk) container_of(_clk, struct clk_gate2, clk) @@ -42,6 +44,9 @@ static int clk_gate2_enable(struct clk *clk) struct clk_gate2 *gate = to_clk_gate2(clk); u32 reg; + if (gate->share_count && (*gate->share_count)++ > 0) + return 0; + reg = readl(gate->reg); reg &= ~(3 << gate->bit_idx); reg |= gate->cgr_val << gate->bit_idx; @@ -55,6 +60,13 @@ static int clk_gate2_disable(struct clk *clk) struct clk_gate2 *gate = to_clk_gate2(clk); u32 reg; + if (gate->share_count) { + if (WARN_ON(*gate->share_count == 0)) + return 0; + else if (--(*gate->share_count) > 0) + return 0; + } + reg = readl(gate->reg); reg &= ~(3 << gate->bit_idx); writel(reg, gate->reg); @@ -82,7 +94,7 @@ static const struct clk_ops clk_gate2_ops = { struct clk *clk_register_gate2(struct device *dev, const char *name, const char *parent_name, unsigned long flags, void __iomem *reg, u8 bit_idx, u8 cgr_val, - u8 clk_gate2_flags) + u8 clk_gate2_flags, unsigned int *share_count) { struct clk_gate2 *gate; struct clk *clk; @@ -96,6 +108,7 @@ struct clk *clk_register_gate2(struct device *dev, const char *name, gate->bit_idx = bit_idx; gate->cgr_val = cgr_val; gate->flags = clk_gate2_flags; + gate->share_count = share_count; clk = &gate->clk; diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h index 46dee35a6735..11f5dca1175b 100644 --- a/drivers/clk/imx/clk.h +++ b/drivers/clk/imx/clk.h @@ -53,7 +53,7 @@ struct clk *imx_clk_pll14xx(const char *name, const char *parent_name, struct clk *clk_register_gate2(struct device *dev, const char *name, const char *parent_name, unsigned long flags, void __iomem *reg, u8 bit_idx, u8 cgr_val, - u8 clk_gate_flags); + u8 clk_gate_flags, unsigned int *share_count); struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name, const char *parent_name, void __iomem *base, @@ -63,7 +63,26 @@ static inline struct clk *imx_clk_gate2(const char *name, const char *parent, void __iomem *reg, u8 shift) { return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg, - shift, 0x3, 0); + shift, 0x3, 0, NULL); +} + +static inline struct clk *imx_clk_gate2_shared(const char *name, + const char *parent, + void __iomem *reg, u8 shift, + unsigned int *share_count) +{ + return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg, + shift, 0x3, 0, share_count); +} + +static inline struct clk *imx_clk_gate2_shared2(const char *name, + const char *parent, + void __iomem *reg, u8 shift, + unsigned int *share_count) +{ + return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT | + CLK_OPS_PARENT_ENABLE, reg, shift, 0x3, 0, + share_count); } static inline struct clk *imx_clk_gate4(const char *name, const char *parent, @@ -71,7 +90,7 @@ static inline struct clk *imx_clk_gate4(const char *name, const char *parent, { return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, - reg, shift, 0x3, 0); + reg, shift, 0x3, 0, NULL); } static inline struct clk *imx_clk_gate4_flags(const char *name, @@ -80,7 +99,7 @@ static inline struct clk *imx_clk_gate4_flags(const char *name, { return clk_regis
[PATCH 3/7] clk: imx: clk-imx8mn add gpmi nand clocks
From: Michael Trimarchi Add gpmi nand clock. Those clock can be used in mxs nand driver to run nand to EDO mode 5, 4, ... Signed-off-by: Michael Trimarchi Signed-off-by: Dario Binacchi --- drivers/clk/imx/clk-imx8mn.c | 14 ++ 1 file changed, 14 insertions(+) diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c index 15d7599cfb7d..35e0d935d390 100644 --- a/drivers/clk/imx/clk-imx8mn.c +++ b/drivers/clk/imx/clk-imx8mn.c @@ -15,6 +15,8 @@ #include "clk.h" +static u32 share_count_nand; + static const char *pll_ref_sels[] = { "clock-osc-24m", "dummy", "dummy", "dummy", }; static const char *dram_pll_bypass_sels[] = {"dram_pll", "dram_pll_ref_sel", }; static const char *arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", }; @@ -90,6 +92,10 @@ static const char *imx8mn_usdhc3_sels[] = {"clock-osc-24m", "sys_pll1_400m", "sy static const char *imx8mn_qspi_sels[] = {"clock-osc-24m", "sys_pll1_400m", "sys_pll2_333m", "sys_pll2_500m", "audio_pll2_out", "sys_pll1_266m", "sys_pll3_out", "sys_pll1_100m", }; +static const char * const imx8mn_nand_sels[] = {"osc_24m", "sys_pll2_500m", "audio_pll1_out", + "sys_pll1_400m", "audio_pll2_out", "sys_pll3_out", + "sys_pll2_250m", "video_pll1_out", }; + static const char * const imx8mn_usb_core_sels[] = {"clock-osc-24m", "sys_pll1_100m", "sys_pll1_40m", "sys_pll2_100m", "sys_pll2_200m", "clk_ext2", "clk_ext3", "audio_pll2_out", }; @@ -268,6 +274,8 @@ static int imx8mn_clk_probe(struct udevice *dev) clk_dm(IMX8MN_CLK_USDHC3, imx8m_clk_composite("usdhc3", imx8mn_usdhc3_sels, base + 0xbc80)); + clk_dm(IMX8MN_CLK_NAND, + imx8m_clk_composite("nand", imx8mn_nand_sels, base + 0xab00)); clk_dm(IMX8MN_CLK_QSPI, imx8m_clk_composite("qspi", imx8mn_qspi_sels, base + 0xab80)); clk_dm(IMX8MN_CLK_USB_CORE_REF, @@ -299,6 +307,12 @@ static int imx8mn_clk_probe(struct udevice *dev) imx_clk_gate4("usdhc3_root_clk", "usdhc3", base + 0x45e0, 0)); clk_dm(IMX8MN_CLK_QSPI_ROOT, imx_clk_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0)); + clk_dm(IMX8MN_CLK_NAND_ROOT, + imx_clk_gate2_shared2("nand_root_clk", "nand", base + 0x4300, 0, &share_count_nand)); + clk_dm(IMX8MN_CLK_NAND_USDHC_BUS_RAWNAND_CLK, + imx_clk_gate2_shared2("nand_usdhc_rawnand_clk", +"nand_usdhc_bus", base + 0x4300, 0, +&share_count_nand)); clk_dm(IMX8MN_CLK_USB1_CTRL_ROOT, imx_clk_gate4("usb1_ctrl_root_clk", "usb_bus", base + 0x44d0, 0)); -- 2.32.0
[PATCH 1/7] dm: clk: add missing stub when CONFIG_CLK is deactivated
Add missing stub for functions [devm_]clk_...() when CONFIG_CLK is deactivated. Signed-off-by: Dario Binacchi --- include/clk.h | 32 +++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/include/clk.h b/include/clk.h index 76bb64bb5ee0..407513e0fa29 100644 --- a/include/clk.h +++ b/include/clk.h @@ -88,8 +88,9 @@ struct clk_bulk { unsigned int count; }; -#if CONFIG_IS_ENABLED(OF_CONTROL) && CONFIG_IS_ENABLED(CLK) struct phandle_1_arg; + +#if CONFIG_IS_ENABLED(OF_CONTROL) && CONFIG_IS_ENABLED(CLK) /** * clk_get_by_phandle() - Get a clock by its phandle information (of-platadata) * @dev: Device containing the phandle @@ -258,12 +259,26 @@ int clk_release_all(struct clk *clk, int count); void devm_clk_put(struct udevice *dev, struct clk *clk); #else + +static inline int clk_get_by_phandle(struct udevice *dev, const +struct phandle_1_arg *cells, +struct clk *clk) +{ + return -ENOSYS; +} + static inline int clk_get_by_index(struct udevice *dev, int index, struct clk *clk) { return -ENOSYS; } +static inline int clk_get_by_index_nodev(ofnode node, int index, +struct clk *clk) +{ + return -ENOSYS; +} + static inline int clk_get_bulk(struct udevice *dev, struct clk_bulk *bulk) { return -ENOSYS; @@ -275,6 +290,17 @@ static inline int clk_get_by_name(struct udevice *dev, const char *name, return -ENOSYS; } +static inline struct clk *devm_clk_get(struct udevice *dev, const char *id) +{ + return ERR_PTR(-ENOSYS); +} + +static inline struct clk *devm_clk_get_optional(struct udevice *dev, + const char *id) +{ + return ERR_PTR(-ENOSYS); +} + static inline int clk_get_by_name_nodev(ofnode node, const char *name, struct clk *clk) { @@ -285,6 +311,10 @@ static inline int clk_release_all(struct clk *clk, int count) { return -ENOSYS; } + +static inline void devm_clk_put(struct udevice *dev, struct clk *clk) +{ +} #endif /** -- 2.32.0
[PATCH 0/7] Support NAND ONFI EDO mode for imx8mn architecture
Debugging and testing the series made it necessary to add some patches to fix correct clock access and compilation issues raised by buildman. Dario Binacchi (3): dm: clk: add missing stub when CONFIG_CLK is deactivated mtd: mxs_nand: don't get the gpmi_apbh_dma clock mtd: mxs_nand: get the clock with the right name Michael Trimarchi (4): clk: imx: gate2 support shared counter and relative clock functions clk: imx: clk-imx8mn add gpmi nand clocks imx: gpmi: Add register needed to control nand bus timing mtd: mxs_nand: Support EDO mode for imx8mn architecture arch/arm/include/asm/mach-imx/regs-gpmi.h | 9 + drivers/clk/imx/clk-gate2.c | 15 +- drivers/clk/imx/clk-imx8mn.c | 14 ++ drivers/clk/imx/clk.h | 27 ++- drivers/mtd/nand/raw/mxs_nand.c | 200 ++ drivers/mtd/nand/raw/mxs_nand_dt.c| 79 + include/clk.h | 32 +++- include/mxs_nand.h| 3 + 8 files changed, 333 insertions(+), 46 deletions(-) -- 2.32.0
Re: [PATCH] cmd: nand: Extend nand info to print ecc information
Hi Michael, On Thu, Sep 22, 2022 at 3:39 PM Michael Trimarchi wrote: > > Extract the information about ecc strength and ecc step size > from mtd controller. This information is usefull to check if > what we think as ecc is what we really configured. > > Signed-off-by: Michael Trimarchi > --- > cmd/nand.c | 14 -- > 1 file changed, 8 insertions(+), 6 deletions(-) > > diff --git a/cmd/nand.c b/cmd/nand.c > index e730484d0b..9a9794684b 100644 > --- a/cmd/nand.c > +++ b/cmd/nand.c > @@ -417,12 +417,14 @@ static void nand_print_and_set_info(int idx) > printf("%dx ", chip->numchips); > printf("%s, sector size %u KiB\n", >mtd->name, mtd->erasesize >> 10); > - printf(" Page size %8d b\n", mtd->writesize); > - printf(" OOB size%8d b\n", mtd->oobsize); > - printf(" Erase size %8d b\n", mtd->erasesize); > - printf(" subpagesize %8d b\n", chip->subpagesize); > - printf(" options 0x%08x\n", chip->options); > - printf(" bbt options 0x%08x\n", chip->bbt_options); > + printf(" Page size %8d b\n", mtd->writesize); > + printf(" OOB size %8d b\n", mtd->oobsize); > + printf(" Erase size%8d b\n", mtd->erasesize); > + printf(" ecc strength %8d bits\n", mtd->ecc_strength); > + printf(" ecc step size %8d b\n", mtd->ecc_step_size); > + printf(" subpagesize %8d b\n", chip->subpagesize); > + printf(" options 0x%08x\n", chip->options); > + printf(" bbt options 0x%08x\n", chip->bbt_options); > > /* Set geometry info */ > env_set_hex("nand_writesize", mtd->writesize); > -- > 2.34.1 > Reviewed-by: Dario Binacchi Thanks and regards, Dario -- Dario Binacchi Embedded Linux Developer dario.binac...@amarulasolutions.com __ Amarula Solutions SRL Via Le Canevare 30, 31100 Treviso, Veneto, IT T. +39 042 243 5310 i...@amarulasolutions.com www.amarulasolutions.com
Re: [PATCH] mtd: nand: pxa3xx: simplify ECC hardware parameters
gt; + info->ntotalchunks = (info->last_spare_size || > info->last_chunk_size) ? > + info->nfullchunks + 1 : > info->nfullchunks; > + info->ecc_size = nfc_layouts[i].ecc_size; > + break; > + } > + ++i; > + } > + > + /* for bch the ecc is calculated per chunk size and for Hamming it is > 512 */ > + ecc->size = (info->ecc_bch) ? info->chunk_size : 512; > + > + /* nand_scan_tail func perform validity tests for ECC strength, and > it > +* assumes that all chunks are with same size. in our case when ecc > is 12 > +* the chunk size is 704 but the last chunk is with different size so > +* we cheat it nand_scan_tail validity tests by set info->ecc_size > value to 512 > */ > - } else if (strength == 4 && ecc_stepsize == 512 && page_size == 2048) > { > - info->ecc_bch = 1; > - info->nfullchunks = 1; > - info->ntotalchunks = 1; > - info->chunk_size = 2048; > - info->spare_size = 32; > - info->ecc_size = 32; > - ecc->mode = NAND_ECC_HW; > - ecc->size = info->chunk_size; > - ecc->layout = &ecc_layout_2KB_bch4bit; > - ecc->strength = 16; > + if (strength == 12) > + ecc->size = 512; > > - } else if (strength == 4 && ecc_stepsize == 512 && page_size == 4096) > { > - info->ecc_bch = 1; > - info->nfullchunks = 2; > - info->ntotalchunks = 2; > - info->chunk_size = 2048; > - info->spare_size = 32; > - info->ecc_size = 32; > - ecc->mode = NAND_ECC_HW; > - ecc->size = info->chunk_size; > - ecc->layout = &ecc_layout_4KB_bch4bit; > - ecc->strength = 16; > - > - } else if (strength == 4 && ecc_stepsize == 512 && page_size == 8192) > { > - info->ecc_bch = 1; > - info->nfullchunks = 4; > - info->ntotalchunks = 4; > - info->chunk_size = 2048; > - info->spare_size = 32; > - info->ecc_size = 32; > - ecc->mode = NAND_ECC_HW; > - ecc->size = info->chunk_size; > - ecc->layout = &ecc_layout_8KB_bch4bit; > - ecc->strength = 16; > - > - /* > -* Required ECC: 8-bit correction per 512 bytes > -* Select: 16-bit correction per 1024 bytes > -*/ > - } else if (strength == 8 && ecc_stepsize == 512 && page_size == 2048) > { > - info->ecc_bch = 1; > - info->nfullchunks = 1; > - info->ntotalchunks = 2; > - info->chunk_size = 1024; > - info->spare_size = 0; > - info->last_chunk_size = 1024; > - info->last_spare_size = 32; > - info->ecc_size = 32; > - ecc->mode = NAND_ECC_HW; > - ecc->size = info->chunk_size; > - ecc->layout = &ecc_layout_2KB_bch8bit; > - ecc->strength = 16; > - > - } else if (strength == 8 && ecc_stepsize == 512 && page_size == 4096) > { > - info->ecc_bch = 1; > - info->nfullchunks = 4; > - info->ntotalchunks = 5; > - info->chunk_size = 1024; > - info->spare_size = 0; > - info->last_chunk_size = 0; > - info->last_spare_size = 64; > - info->ecc_size = 32; > - ecc->mode = NAND_ECC_HW; > - ecc->size = info->chunk_size; > - ecc->layout = &ecc_layout_4KB_bch8bit; > - ecc->strength = 16; > - > - } else if (strength == 8 && ecc_stepsize == 512 && page_size == 8192) > { > - info->ecc_bch = 1; > - info->nfullchunks = 8; > - info->ntotalchunks = 9; > - info->chunk_size = 1024; > - info->spare_size = 0; > - info->last_chunk_size = 0; > - info->last_spare_size = 160; > - info->ecc_size = 32; > - ecc->mode = NAND_ECC_HW; > - ecc->size = info->chunk_size; > - ecc->layout = &ecc_layout_8KB_bch8bit; > - ecc->strength = 16; > - > - } else { > + if (ecc_stepsize != 512 || !(nfc_layouts[i].strength)) { > dev_err(info->controller.active->mtd.dev, > "ECC strength %d at page size %d is not supported\n", > strength, page_size); > -- > 2.37.2 > -- Dario Binacchi Embedded Linux Developer dario.binac...@amarulasolutions.com __ Amarula Solutions SRL Via Le Canevare 30, 31100 Treviso, Veneto, IT T. +39 042 243 5310 i...@amarulasolutions.com www.amarulasolutions.com
Re: [PATCH v2 8/9] ARM: dts: at91: sam9x60ek: Enable NAND support
1>; > >>>> + #size-cells = <1>; > >>>> + > >>>> + at91bootstrap@0 { > >>>> + label = "at91bootstrap"; > >>>> + reg = <0x0 0x4>; > >>>> + }; > >>>> + > >>>> + uboot@4 { > >>>> + label = "u-boot"; > >>>> + reg = <0x4 0xc>; > >>>> + }; > >>>> + > >>>> + ubootenvred@10 { > >>>> + label = "U-Boot Env Redundant"; > >>>> + reg = <0x10 0x4>; > >>>> + }; > >>>> + > >>>> + ubootenv@14 { > >>>> + label = "U-Boot Env"; > >>>> + reg = <0x14 0x4>; > >>>> + }; > >>>> + > >>>> + dtb@18 { > >>>> + label = "device tree"; > >>>> + reg = <0x18 0x8>; > >>>> + }; > >>>> + > >>>> + kernel@20 { > >>>> + label = "kernel"; > >>>> + reg = <0x20 0x60>; > >>>> + }; > >>>> + > >>>> + rootfs@80 { > >>>> + label = "rootfs"; > >>>> + reg = <0x80 0x1f80>; > >>>> + }; > >>>> + }; > >>>> + }; > >>>> + }; > >>>> +}; > >>>> + > >>>>&macb0 { > >>>> phy-mode = "rmii"; > >>>> status = "okay"; > >>>> -- > >>>> 2.34.1 > >>>> > >>> > >>> > >>> -- > >>> Michael Nazzareno Trimarchi > >>> Co-Founder & Chief Executive Officer > >>> M. +39 347 913 2170 > >>> mich...@amarulasolutions.com > >>> __ > >>> > >>> Amarula Solutions BV > >>> Joop Geesinkweg 125, 1114 AB, Amsterdam, NL > >>> T. +31 (0)85 111 9172 > >>> i...@amarulasolutions.com > >>> www.amarulasolutions.com > >>> > >> > > > > > > -- > > Michael Nazzareno Trimarchi > > Co-Founder & Chief Executive Officer > > M. +39 347 913 2170 > > mich...@amarulasolutions.com > > __ > > > > Amarula Solutions BV > > Joop Geesinkweg 125, 1114 AB, Amsterdam, NL > > T. +31 (0)85 111 9172 > > i...@amarulasolutions.com > > www.amarulasolutions.com > > > -- Dario Binacchi Embedded Linux Developer dario.binac...@amarulasolutions.com __ Amarula Solutions SRL Via Le Canevare 30, 31100 Treviso, Veneto, IT T. +39 042 243 5310 i...@amarulasolutions.com www.amarulasolutions.com
[PATCH] ARM: dts: at91: sam9x60ek: fix indentation for pinctrl sub-nodes
The indentation went far on the right due to an extra tab for each pinctrl sub-nodes. Signed-off-by: Dario Binacchi --- arch/arm/dts/sam9x60ek.dts | 36 ++-- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/arch/arm/dts/sam9x60ek.dts b/arch/arm/dts/sam9x60ek.dts index 54c694bd7848..eb44868a3e3e 100644 --- a/arch/arm/dts/sam9x60ek.dts +++ b/arch/arm/dts/sam9x60ek.dts @@ -80,26 +80,26 @@ }; pinctrl { - pinctrl_qspi: qspi { - atmel,pins = - ; - }; + pinctrl_qspi: qspi { + atmel,pins = + ; + }; - pinctrl_flx0: flx0_default { - atmel,pins = - ; - }; + pinctrl_flx0: flx0_default { + atmel,pins = + ; + }; - pinctrl_onewire_tm_default: onewire_tm_default { - atmel,pins = - ; - }; + pinctrl_onewire_tm_default: onewire_tm_default { + atmel,pins = + ; + }; }; }; -- 2.32.0
[RFC PATCH] Rename disto_[pxe_]getfile to distro_[pxe_]getfile
Replace 'disto' with 'distro' since they are all functions about distro booting. Signed-off-by: Dario Binacchi --- boot/bootmeth_distro.c | 6 +++--- boot/bootmeth_pxe.c | 6 +++--- doc/develop/bootstd.rst | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/boot/bootmeth_distro.c b/boot/bootmeth_distro.c index fea09b2c2fbe..5c6c687f0a64 100644 --- a/boot/bootmeth_distro.c +++ b/boot/bootmeth_distro.c @@ -35,8 +35,8 @@ static int distro_get_state_desc(struct udevice *dev, char *buf, int maxsize) return 0; } -static int disto_getfile(struct pxe_context *ctx, const char *file_path, -char *file_addr, ulong *sizep) +static int distro_getfile(struct pxe_context *ctx, const char *file_path, + char *file_addr, ulong *sizep) { struct distro_info *info = ctx->userdata; ulong addr; @@ -113,7 +113,7 @@ static int distro_boot(struct udevice *dev, struct bootflow *bflow) addr = map_to_sysmem(bflow->buf); info.dev = dev; info.bflow = bflow; - ret = pxe_setup_ctx(&ctx, &cmdtp, disto_getfile, &info, true, + ret = pxe_setup_ctx(&ctx, &cmdtp, distro_getfile, &info, true, bflow->subdir); if (ret) return log_msg_ret("ctx", -EINVAL); diff --git a/boot/bootmeth_pxe.c b/boot/bootmeth_pxe.c index f1e2b4c77627..e6992168c067 100644 --- a/boot/bootmeth_pxe.c +++ b/boot/bootmeth_pxe.c @@ -23,8 +23,8 @@ #include #include -static int disto_pxe_getfile(struct pxe_context *ctx, const char *file_path, -char *file_addr, ulong *sizep) +static int distro_pxe_getfile(struct pxe_context *ctx, const char *file_path, + char *file_addr, ulong *sizep) { struct distro_info *info = ctx->userdata; ulong addr; @@ -142,7 +142,7 @@ static int distro_pxe_boot(struct udevice *dev, struct bootflow *bflow) info.dev = dev; info.bflow = bflow; info.cmdtp = &cmdtp; - ret = pxe_setup_ctx(ctx, &cmdtp, disto_pxe_getfile, &info, false, + ret = pxe_setup_ctx(ctx, &cmdtp, distro_pxe_getfile, &info, false, bflow->subdir); if (ret) return log_msg_ret("ctx", -EINVAL); diff --git a/doc/develop/bootstd.rst b/doc/develop/bootstd.rst index f7fc72570766..1ccc49424ebd 100644 --- a/doc/develop/bootstd.rst +++ b/doc/develop/bootstd.rst @@ -322,7 +322,7 @@ look like this:: The `sf-bootdev` driver can implement a way to read from the SPI flash, using the offset and size provided, and return that bootflow file back to the caller. -When distro boot wants to read the kernel it calls disto_getfile() which must +When distro boot wants to read the kernel it calls distro_getfile() which must provide a way to read from the SPI flash. See `distro_boot()` at distro_boot_ for more details. -- 2.32.0
Re: [PATCH] mtd: rawnand: fsl_elbc: Fix reading address pointer from DT
Hi Pali On Fri, Aug 19, 2022 at 11:20 AM Pali Rohár wrote: > > During compilation gcc throws warning: > > drivers/mtd/nand/raw/fsl_elbc_nand.c: In function ‘fsl_elbc_nand_probe’: > drivers/mtd/nand/raw/fsl_elbc_nand.c:841:31: warning: cast to pointer > from integer of different size [-Wint-to-pointer-cast] > return fsl_elbc_chip_init(0, (void *)dev_read_addr(dev), dev); >^ > > Fix it by using dev_read_addr_ptr() function which returns pointer instead > of dev_read_addr() which returns integer type. > > Signed-off-by: Pali Rohár > --- > drivers/mtd/nand/raw/fsl_elbc_nand.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/mtd/nand/raw/fsl_elbc_nand.c > b/drivers/mtd/nand/raw/fsl_elbc_nand.c > index 48a3687f2728..4a07cf854fff 100644 > --- a/drivers/mtd/nand/raw/fsl_elbc_nand.c > +++ b/drivers/mtd/nand/raw/fsl_elbc_nand.c > @@ -839,7 +839,7 @@ void board_nand_init(void) > > static int fsl_elbc_nand_probe(struct udevice *dev) > { > - return fsl_elbc_chip_init(0, (void *)dev_read_addr(dev), dev); > + return fsl_elbc_chip_init(0, dev_read_addr_ptr(dev), dev); > } > > static const struct udevice_id fsl_elbc_nand_dt_ids[] = { > -- > 2.20.1 > Reviewed-by: Dario Binacchi Thanks and regards, Dario -- Dario Binacchi Embedded Linux Developer dario.binac...@amarulasolutions.com __ Amarula Solutions SRL Via Le Canevare 30, 31100 Treviso, Veneto, IT T. +39 042 243 5310 i...@amarulasolutions.com www.amarulasolutions.com
[PATCH v4 12/14] mtd: nand: Move Macronix specific initialization in nand_macronix.c
From: Michael Trimarchi Upstream linux commit 3b5206f4be9b65. Move Macronix specific initialization logic into nand_macronix.c. This is part of the "separate vendor specific code from core" cleanup process. Signed-off-by: Michael Trimarchi Signed-off-by: Dario Binacchi --- (no changes since v3) Changes in v3: - Use commit sha1 with 13 digits. - Add the SPDX-License-Identifier tag. - Fix code style warnings raised by patman. Changes in v2: - Use short-commit form - Remove linux info. Uboot seems that backport without add this extra information. - Adjust the include file in nand_macronix. drivers/mtd/nand/raw/Makefile| 4 +++- drivers/mtd/nand/raw/nand_base.c | 11 -- drivers/mtd/nand/raw/nand_ids.c | 2 +- drivers/mtd/nand/raw/nand_macronix.c | 31 include/linux/mtd/rawnand.h | 1 + 5 files changed, 36 insertions(+), 13 deletions(-) create mode 100644 drivers/mtd/nand/raw/nand_macronix.c diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile index 9c2ced9925d8..a398aa9d8864 100644 --- a/drivers/mtd/nand/raw/Makefile +++ b/drivers/mtd/nand/raw/Makefile @@ -14,7 +14,8 @@ obj-$(CONFIG_SPL_NAND_DENALI) += denali_spl.o obj-$(CONFIG_SPL_NAND_SIMPLE) += nand_spl_simple.o obj-$(CONFIG_SPL_NAND_LOAD) += nand_spl_load.o obj-$(CONFIG_SPL_NAND_ECC) += nand_ecc.o -obj-$(CONFIG_SPL_NAND_BASE) += nand_base.o nand_amd.o nand_hynix.o nand_micron.o \ +obj-$(CONFIG_SPL_NAND_BASE) += nand_base.o nand_amd.o nand_hynix.o \ + nand_macronix.o nand_micron.o \ nand_samsung.o nand_toshiba.o obj-$(CONFIG_SPL_NAND_IDENT) += nand_ids.o nand_timings.o obj-$(CONFIG_TPL_NAND_INIT) += nand.o @@ -34,6 +35,7 @@ obj-y += nand_ecc.o obj-y += nand_base.o obj-y += nand_amd.o obj-y += nand_hynix.o +obj-y += nand_macronix.o obj-y += nand_micron.o obj-y += nand_samsung.o obj-y += nand_toshiba.o diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index 68e6f4f14347..4b09a1128827 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -4217,22 +4217,11 @@ static void nand_decode_id(struct nand_chip *chip, struct nand_flash_dev *type) static void nand_decode_bbm_options(struct mtd_info *mtd, struct nand_chip *chip) { - int maf_id = chip->id.data[0]; - /* Set the bad block position */ if (mtd->writesize > 512 || (chip->options & NAND_BUSWIDTH_16)) chip->badblockpos = NAND_LARGE_BADBLOCK_POS; else chip->badblockpos = NAND_SMALL_BADBLOCK_POS; - - /* -* Bad block marker is stored in the last page of each block on Samsung -* and Hynix MLC devices; stored in first two pages of each block on -* Micron devices with 2KiB pages and on SLC Samsung, Hynix, Toshiba, -* AMD/Spansion, and Macronix. All others scan only the first page. -*/ - if (nand_is_slc(chip) && maf_id == NAND_MFR_MACRONIX) - chip->bbt_options |= NAND_BBT_SCAN2NDPAGE; } static inline bool is_full_id_nand(struct nand_flash_dev *type) diff --git a/drivers/mtd/nand/raw/nand_ids.c b/drivers/mtd/nand/raw/nand_ids.c index c78f2e088040..7602dd30f169 100644 --- a/drivers/mtd/nand/raw/nand_ids.c +++ b/drivers/mtd/nand/raw/nand_ids.c @@ -197,7 +197,7 @@ struct nand_manufacturers nand_manuf_ids[] = { {NAND_MFR_HYNIX, "Hynix", &hynix_nand_manuf_ops}, {NAND_MFR_MICRON, "Micron", µn_nand_manuf_ops}, {NAND_MFR_AMD, "AMD/Spansion", &amd_nand_manuf_ops}, - {NAND_MFR_MACRONIX, "Macronix"}, + {NAND_MFR_MACRONIX, "Macronix", ¯onix_nand_manuf_ops}, {NAND_MFR_EON, "Eon"}, {NAND_MFR_SANDISK, "SanDisk"}, {NAND_MFR_INTEL, "Intel"}, diff --git a/drivers/mtd/nand/raw/nand_macronix.c b/drivers/mtd/nand/raw/nand_macronix.c new file mode 100644 index ..dc972e590922 --- /dev/null +++ b/drivers/mtd/nand/raw/nand_macronix.c @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2017 Free Electrons + * Copyright (C) 2017 NextThing Co + * + * Author: Boris Brezillon + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include + +static int macronix_nand_init(struct nand_chip *chip) +{ + if (nand_is_slc(chip)) + chip->bbt_o
[PATCH v4 11/14] mtd: nand: Move AMD/Spansion specific init/detection logic in nand_amd.c
From: Michael Trimarchi Upstream linux commit 229204da53b31d. Move AMD/Spansion specific initialization/detection logic into nand_amd.c. This is part of the "separate vendor specific code from core" cleanup process. Signed-off-by: Michael Trimarchi Signed-off-by: Dario Binacchi --- (no changes since v3) Changes in v3: - Use commit sha1 with 13 digits. - Add the SPDX-License-Identifier tag. - Fix code style warnings raised by patman. Changes in v2: - Use short-commit form - Remove linux info. Uboot seems that backport without add this extra information. - Adjust the include file in nand_amd. drivers/mtd/nand/raw/Makefile| 4 ++- drivers/mtd/nand/raw/nand_amd.c | 52 drivers/mtd/nand/raw/nand_base.c | 17 +-- drivers/mtd/nand/raw/nand_ids.c | 2 +- include/linux/mtd/rawnand.h | 1 + 5 files changed, 58 insertions(+), 18 deletions(-) create mode 100644 drivers/mtd/nand/raw/nand_amd.c diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile index 8ef30b45fd2d..9c2ced9925d8 100644 --- a/drivers/mtd/nand/raw/Makefile +++ b/drivers/mtd/nand/raw/Makefile @@ -14,7 +14,8 @@ obj-$(CONFIG_SPL_NAND_DENALI) += denali_spl.o obj-$(CONFIG_SPL_NAND_SIMPLE) += nand_spl_simple.o obj-$(CONFIG_SPL_NAND_LOAD) += nand_spl_load.o obj-$(CONFIG_SPL_NAND_ECC) += nand_ecc.o -obj-$(CONFIG_SPL_NAND_BASE) += nand_base.o nand_hynix.o nand_micron.o nand_samsung.o nand_toshiba.o +obj-$(CONFIG_SPL_NAND_BASE) += nand_base.o nand_amd.o nand_hynix.o nand_micron.o \ + nand_samsung.o nand_toshiba.o obj-$(CONFIG_SPL_NAND_IDENT) += nand_ids.o nand_timings.o obj-$(CONFIG_TPL_NAND_INIT) += nand.o ifeq ($(CONFIG_SPL_ENV_SUPPORT),y) @@ -31,6 +32,7 @@ obj-y += nand_ids.o obj-y += nand_util.o obj-y += nand_ecc.o obj-y += nand_base.o +obj-y += nand_amd.o obj-y += nand_hynix.o obj-y += nand_micron.o obj-y += nand_samsung.o diff --git a/drivers/mtd/nand/raw/nand_amd.c b/drivers/mtd/nand/raw/nand_amd.c new file mode 100644 index ..e02b8c79dba2 --- /dev/null +++ b/drivers/mtd/nand/raw/nand_amd.c @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2017 Free Electrons + * Copyright (C) 2017 NextThing Co + * + * Author: Boris Brezillon + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include + +static void amd_nand_decode_id(struct nand_chip *chip) +{ + struct mtd_info *mtd = nand_to_mtd(chip); + + nand_decode_ext_id(chip); + + /* +* Check for Spansion/AMD ID + repeating 5th, 6th byte since +* some Spansion chips have erasesize that conflicts with size +* listed in nand_ids table. +* Data sheet (5 byte ID): Spansion S30ML-P ORNAND (p.39) +*/ + if (chip->id.data[4] != 0x00 && chip->id.data[5] == 0x00 && + chip->id.data[6] == 0x00 && chip->id.data[7] == 0x00 && + mtd->writesize == 512) { + mtd->erasesize = 128 * 1024; + mtd->erasesize <<= ((chip->id.data[3] & 0x03) << 1); + } +} + +static int amd_nand_init(struct nand_chip *chip) +{ + if (nand_is_slc(chip)) + chip->bbt_options |= NAND_BBT_SCAN2NDPAGE; + + return 0; +} + +const struct nand_manufacturer_ops amd_nand_manuf_ops = { + .detect = amd_nand_decode_id, + .init = amd_nand_init, +}; diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index fe7e049d4064..68e6f4f14347 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -4200,7 +4200,6 @@ static int nand_manufacturer_init(struct nand_chip *chip) static void nand_decode_id(struct nand_chip *chip, struct nand_flash_dev *type) { struct mtd_info *mtd = &chip->mtd; - int maf_id = chip->id.data[0]; mtd->erasesize = type->erasesize; mtd->writesize = type->pagesize; @@ -4208,19 +4207,6 @@ static void nand_decode_id(struct nand_chip *chip, struct nand_flash_dev *type) /* All legacy ID NAND are small-page, SLC */ chip->bits_per_cell = 1; - - /* -* Check for Spansion/AMD ID + repeating 5th, 6th byte since -* some Spansion chips have erasesize that conflicts with size -* listed in nand_ids table. -* Data sheet (5 byte ID): Spansion S30ML-P ORNAND (p.39) -*/ - if (maf_id == NAND_MFR_AMD && chip->id.da
[PATCH v4 10/14] mtd: nand: Move Micron specific init logic in nand_micron.c
From: Michael Trimarchi Upstream linux commit 10d4e75c36f6c1. Move Micron specific initialization logic into nand_micron.c. This is part of the "separate vendor specific code from core" cleanup process. Signed-off-by: Michael Trimarchi Signed-off-by: Dario Binacchi --- (no changes since v3) Changes in v3: - Use commit sha1 with 13 digits. - Add the SPDX-License-Identifier tag. - Fix code style warnings raised by patman. Changes in v2: - Use short-commit form - Remove linux info. Uboot seems that backport without add this extra information. - Adjust the include file in nand_micron. drivers/mtd/nand/raw/Makefile | 3 +- drivers/mtd/nand/raw/nand_base.c | 33 +--- drivers/mtd/nand/raw/nand_ids.c| 2 +- drivers/mtd/nand/raw/nand_micron.c | 87 ++ include/linux/mtd/rawnand.h| 21 +--- 5 files changed, 93 insertions(+), 53 deletions(-) create mode 100644 drivers/mtd/nand/raw/nand_micron.c diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile index 16e0775395a2..8ef30b45fd2d 100644 --- a/drivers/mtd/nand/raw/Makefile +++ b/drivers/mtd/nand/raw/Makefile @@ -14,7 +14,7 @@ obj-$(CONFIG_SPL_NAND_DENALI) += denali_spl.o obj-$(CONFIG_SPL_NAND_SIMPLE) += nand_spl_simple.o obj-$(CONFIG_SPL_NAND_LOAD) += nand_spl_load.o obj-$(CONFIG_SPL_NAND_ECC) += nand_ecc.o -obj-$(CONFIG_SPL_NAND_BASE) += nand_base.o nand_hynix.o nand_samsung.o nand_toshiba.o +obj-$(CONFIG_SPL_NAND_BASE) += nand_base.o nand_hynix.o nand_micron.o nand_samsung.o nand_toshiba.o obj-$(CONFIG_SPL_NAND_IDENT) += nand_ids.o nand_timings.o obj-$(CONFIG_TPL_NAND_INIT) += nand.o ifeq ($(CONFIG_SPL_ENV_SUPPORT),y) @@ -32,6 +32,7 @@ obj-y += nand_util.o obj-y += nand_ecc.o obj-y += nand_base.o obj-y += nand_hynix.o +obj-y += nand_micron.o obj-y += nand_samsung.o obj-y += nand_toshiba.o obj-y += nand_timings.o diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index 4ea7f10a06fc..fe7e049d4064 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -3871,30 +3871,6 @@ ext_out: return ret; } -static int nand_setup_read_retry_micron(struct mtd_info *mtd, int retry_mode) -{ - struct nand_chip *chip = mtd_to_nand(mtd); - uint8_t feature[ONFI_SUBFEATURE_PARAM_LEN] = {retry_mode}; - - return chip->onfi_set_features(mtd, chip, ONFI_FEATURE_ADDR_READ_RETRY, - feature); -} - -/* - * Configure chip properties from Micron vendor-specific ONFI table - */ -static void nand_onfi_detect_micron(struct nand_chip *chip, - struct nand_onfi_params *p) -{ - struct nand_onfi_vendor_micron *micron = (void *)p->vendor; - - if (le16_to_cpu(p->vendor_revision) < 1) - return; - - chip->read_retries = micron->read_retry_options; - chip->setup_read_retry = nand_setup_read_retry_micron; -} - /* * Check if the NAND chip is ONFI compliant, returns 1 if it is, 0 otherwise. */ @@ -3994,9 +3970,6 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip) pr_warn("Could not retrieve ONFI ECC requirements\n"); } - if (p->jedec_id == NAND_MFR_MICRON) - nand_onfi_detect_micron(chip, p); - return 1; } #else @@ -4272,10 +4245,8 @@ static void nand_decode_bbm_options(struct mtd_info *mtd, * Micron devices with 2KiB pages and on SLC Samsung, Hynix, Toshiba, * AMD/Spansion, and Macronix. All others scan only the first page. */ - if ((nand_is_slc(chip) && -(maf_id == NAND_MFR_AMD || - maf_id == NAND_MFR_MACRONIX)) || - (mtd->writesize == 2048 && maf_id == NAND_MFR_MICRON)) + if (nand_is_slc(chip) && + (maf_id == NAND_MFR_AMD || maf_id == NAND_MFR_MACRONIX)) chip->bbt_options |= NAND_BBT_SCAN2NDPAGE; } diff --git a/drivers/mtd/nand/raw/nand_ids.c b/drivers/mtd/nand/raw/nand_ids.c index 509652c8e26c..bb5ac8337fde 100644 --- a/drivers/mtd/nand/raw/nand_ids.c +++ b/drivers/mtd/nand/raw/nand_ids.c @@ -195,7 +195,7 @@ struct nand_manufacturers nand_manuf_ids[] = { {NAND_MFR_RENESAS, "Renesas"}, {NAND_MFR_STMICRO, "ST Micro"}, {NAND_MFR_HYNIX, "Hynix", &hynix_nand_manuf_ops}, - {NAND_MFR_MICRON, "Micron"}, + {NAND_MFR_MICRON, "Micron", µn_nand_manuf_ops}, {NAND_MFR_AMD, "AMD/Spansion"}, {NAND_MFR_MACRONIX, "Macronix"}, {NAND_MFR_EON, "Eon"}, diff --git a/drivers/mtd/nand/raw/nand_micron.c b/drivers/mtd/nand/raw/nand_micron.c new file mode 100644 index ..8b31c6198134 --- /dev/null +++ b/drivers/mtd/nand/raw/nand_micron.c @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2017 Free Electrons + * Copyright (C)
[PATCH v4 09/14] mtd: nand: Move Toshiba specific init/detection logic in nand_toshiba.c
From: Michael Trimarchi Upstream linux commit 9b2d61f80b060c. Move Toshiba specific initialization and detection logic into nand_toshiba.c. This is part of the "separate vendor specific code from core" cleanup process. Signed-off-by: Michael Trimarchi Signed-off-by: Dario Binacchi --- (no changes since v3) Changes in v3: - Use commit sha1 with 13 digits. - Add the SPDX-License-Identifier tag. - Fix code style warnings raised by patman. Changes in v2: - Use short-commit form - Remove linux info. Uboot seems that backport without add this extra information. - Adjust the include file in nand_toshiba. drivers/mtd/nand/raw/Makefile | 3 +- drivers/mtd/nand/raw/nand_base.c| 21 ++-- drivers/mtd/nand/raw/nand_ids.c | 2 +- drivers/mtd/nand/raw/nand_toshiba.c | 53 + include/linux/mtd/rawnand.h | 1 + 5 files changed, 59 insertions(+), 21 deletions(-) create mode 100644 drivers/mtd/nand/raw/nand_toshiba.c diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile index 86d9b8e8beb8..16e0775395a2 100644 --- a/drivers/mtd/nand/raw/Makefile +++ b/drivers/mtd/nand/raw/Makefile @@ -14,7 +14,7 @@ obj-$(CONFIG_SPL_NAND_DENALI) += denali_spl.o obj-$(CONFIG_SPL_NAND_SIMPLE) += nand_spl_simple.o obj-$(CONFIG_SPL_NAND_LOAD) += nand_spl_load.o obj-$(CONFIG_SPL_NAND_ECC) += nand_ecc.o -obj-$(CONFIG_SPL_NAND_BASE) += nand_base.o nand_hynix.o nand_samsung.o +obj-$(CONFIG_SPL_NAND_BASE) += nand_base.o nand_hynix.o nand_samsung.o nand_toshiba.o obj-$(CONFIG_SPL_NAND_IDENT) += nand_ids.o nand_timings.o obj-$(CONFIG_TPL_NAND_INIT) += nand.o ifeq ($(CONFIG_SPL_ENV_SUPPORT),y) @@ -33,6 +33,7 @@ obj-y += nand_ecc.o obj-y += nand_base.o obj-y += nand_hynix.o obj-y += nand_samsung.o +obj-y += nand_toshiba.o obj-y += nand_timings.o endif # not spl diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index 5698c1e6a229..4ea7f10a06fc 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -4163,12 +4163,11 @@ static int nand_get_bits_per_cell(u8 cellinfo) void nand_decode_ext_id(struct nand_chip *chip) { struct mtd_info *mtd = &chip->mtd; - int extid, id_len; + int extid; /* The 3rd id byte holds MLC / multichip data */ chip->bits_per_cell = nand_get_bits_per_cell(chip->id.data[2]); /* The 4th id byte is the important one */ extid = chip->id.data[3]; - id_len = chip->id.len; /* Calc pagesize */ mtd->writesize = 1024 << (extid & 0x03); @@ -4184,21 +4183,6 @@ void nand_decode_ext_id(struct nand_chip *chip) /* Get buswidth information */ if (extid & 0x1) chip->options |= NAND_BUSWIDTH_16; - - /* -* Toshiba 24nm raw SLC (i.e., not BENAND) have 32B OOB per -* 512B page. For Toshiba SLC, we decode the 5th/6th byte as -* follows: -* - ID byte 6, bits[2:0]: 100b -> 43nm, 101b -> 32nm, -* 110b -> 24nm -* - ID byte 5, bit[7]:1 -> BENAND, 0 -> raw SLC -*/ - if (id_len >= 6 && chip->id.data[0] == NAND_MFR_TOSHIBA && - nand_is_slc(chip) && - (chip->id.data[5] & 0x7) == 0x6 /* 24nm */ && - !(chip->id.data[4] & 0x80) /* !BENAND */) { - mtd->oobsize = 32 * mtd->writesize >> 9; - } } EXPORT_SYMBOL_GPL(nand_decode_ext_id); @@ -4289,8 +4273,7 @@ static void nand_decode_bbm_options(struct mtd_info *mtd, * AMD/Spansion, and Macronix. All others scan only the first page. */ if ((nand_is_slc(chip) && -(maf_id == NAND_MFR_TOSHIBA || - maf_id == NAND_MFR_AMD || +(maf_id == NAND_MFR_AMD || maf_id == NAND_MFR_MACRONIX)) || (mtd->writesize == 2048 && maf_id == NAND_MFR_MICRON)) chip->bbt_options |= NAND_BBT_SCAN2NDPAGE; diff --git a/drivers/mtd/nand/raw/nand_ids.c b/drivers/mtd/nand/raw/nand_ids.c index ec263a43279a..509652c8e26c 100644 --- a/drivers/mtd/nand/raw/nand_ids.c +++ b/drivers/mtd/nand/raw/nand_ids.c @@ -188,7 +188,7 @@ struct nand_flash_dev nand_flash_ids[] = { /* Manufacturer IDs */ struct nand_manufacturers nand_manuf_ids[] = { - {NAND_MFR_TOSHIBA, "Toshiba"}, + {NAND_MFR_TOSHIBA, "Toshiba", &toshiba_nand_manuf_ops}, {NAND_MFR_SAMSUNG, "Samsung", &samsung_nand_manuf_ops}, {NAND_MFR_FUJITSU, "Fujitsu"}, {NAND_MFR_NATIONAL, "National"}, diff --git a/drivers/mtd/nand/raw/nand_toshiba.c b/drivers/mtd/nand/raw/nand_toshiba.c new file mode 100644 index ..f7426fa59f51 --- /dev/null +++ b/drivers/mtd/nand/raw/nand_toshiba.c @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* +
[PATCH v4 14/14] mtd: decommission the NAND museum
From: Michael Trimarchi Upstream linux commit f7025a43a9da26. The MTD subsystem has its own small museum of ancient NANDs in a form of the CONFIG_MTD_NAND_MUSEUM_IDS configuration option. The museum contains stone age NANDs with 256 bytes pages, as well as iron age NANDs with 512 bytes per page and up to 8MiB page size. It is with great sorrow that I inform you that the museum is being decommissioned. The MTD subsystem is out of budget for Kconfig options and already has too many of them, and there is a general kernel trend to simplify the configuration menu. We remove the stone age exhibits along with closing the museum REMARK Don't apply this part from upstream: Some of the iron age ones are transferred to the regular NAND depot. Namely, only those which have unique device IDs are transferred, and the ones which have conflicting device IDs are removed. Signed-off-by: Michael Trimarchi Signed-off-by: Dario Binacchi --- (no changes since v3) Changes in v3: - Use commit sha1 with 13 digits. - Wrap commit description to a maximum of 75 chars. Changes in v2: - Use short-commit form. - Remove linux info. Uboot seems that backport without add this extra information. drivers/mtd/nand/raw/nand_ids.c | 10 -- 1 file changed, 10 deletions(-) diff --git a/drivers/mtd/nand/raw/nand_ids.c b/drivers/mtd/nand/raw/nand_ids.c index 7602dd30f169..4dece1b20676 100644 --- a/drivers/mtd/nand/raw/nand_ids.c +++ b/drivers/mtd/nand/raw/nand_ids.c @@ -24,16 +24,6 @@ * extended chip ID. */ struct nand_flash_dev nand_flash_ids[] = { -#ifdef CONFIG_MTD_NAND_MUSEUM_IDS - LEGACY_ID_NAND("NAND 1MiB 5V 8-bit",0x6e, 1, SZ_4K, SP_OPTIONS), - LEGACY_ID_NAND("NAND 2MiB 5V 8-bit",0x64, 2, SZ_4K, SP_OPTIONS), - LEGACY_ID_NAND("NAND 1MiB 3,3V 8-bit", 0xe8, 1, SZ_4K, SP_OPTIONS), - LEGACY_ID_NAND("NAND 1MiB 3,3V 8-bit", 0xec, 1, SZ_4K, SP_OPTIONS), - LEGACY_ID_NAND("NAND 2MiB 3,3V 8-bit", 0xea, 2, SZ_4K, SP_OPTIONS), - LEGACY_ID_NAND("NAND 4MiB 3,3V 8-bit", 0xd5, 4, SZ_8K, SP_OPTIONS), - - LEGACY_ID_NAND("NAND 8MiB 3,3V 8-bit", 0xe6, 8, SZ_8K, SP_OPTIONS), -#endif /* * Some incompatible NAND chips share device ID's and so must be * listed by full ID. We list them first so that we can easily identify -- 2.32.0
[PATCH v4 13/14] mtd: nand: toshiba: Retrieve ECC requirements from extended ID
From: Michael Trimarchi Upstream linux commit fb3bff5b407e58. This patch enables support to read the ECC strength and size from the NAND flash using Toshiba Memory SLC NAND extended-ID. This patch is based on the information of the 6th ID byte of the Toshiba Memory SLC NAND. Signed-off-by: Michael Trimarchi Signed-off-by: Dario Binacchi --- (no changes since v3) Changes in v3: - Use commit sha1 with 13 digits. Changes in v2: - Use short-commit form - Remove linux info. Uboot seems that backport without add this extra information. drivers/mtd/nand/raw/nand_toshiba.c | 26 ++ 1 file changed, 26 insertions(+) diff --git a/drivers/mtd/nand/raw/nand_toshiba.c b/drivers/mtd/nand/raw/nand_toshiba.c index f7426fa59f51..99dc44df671a 100644 --- a/drivers/mtd/nand/raw/nand_toshiba.c +++ b/drivers/mtd/nand/raw/nand_toshiba.c @@ -37,6 +37,32 @@ static void toshiba_nand_decode_id(struct nand_chip *chip) (chip->id.data[5] & 0x7) == 0x6 /* 24nm */ && !(chip->id.data[4] & 0x80) /* !BENAND */) mtd->oobsize = 32 * mtd->writesize >> 9; + + /* +* Extract ECC requirements from 6th id byte. +* For Toshiba SLC, ecc requrements are as follows: +* - 43nm: 1 bit ECC for each 512Byte is required. +* - 32nm: 4 bit ECC for each 512Byte is required. +* - 24nm: 8 bit ECC for each 512Byte is required. +*/ + if (chip->id.len >= 6 && nand_is_slc(chip)) { + chip->ecc_step_ds = 512; + switch (chip->id.data[5] & 0x7) { + case 0x4: + chip->ecc_strength_ds = 1; + break; + case 0x5: + chip->ecc_strength_ds = 4; + break; + case 0x6: + chip->ecc_strength_ds = 8; + break; + default: + WARN(1, "Could not get ECC info"); + chip->ecc_step_ds = 0; + break; + } + } } static int toshiba_nand_init(struct nand_chip *chip) -- 2.32.0
[PATCH v4 08/14] mtd: nand: Move Hynix specific init/detection logic in nand_hynix.c
From: Michael Trimarchi Upstream linux commit 01389b6bd2f4f7. Move Hynix specific initialization and detection logic into nand_hynix.c. This is part of the "separate vendor specific code from core" cleanup process. Signed-off-by: Michael Trimarchi Signed-off-by: Dario Binacchi --- (no changes since v3) Changes in v3: - Use commit sha1 with 13 digits. - Add the SPDX-License-Identifier tag. - Fix code style warnings raised by patman. Changes in v2: - Use short-commit form - Remove linux info. Uboot seems that backport without add this extra information. - Adjust the include file in nand_hynix. drivers/mtd/nand/raw/Makefile | 3 +- drivers/mtd/nand/raw/nand_base.c | 117 -- drivers/mtd/nand/raw/nand_hynix.c | 85 ++ drivers/mtd/nand/raw/nand_ids.c | 2 +- include/linux/mtd/rawnand.h | 1 + 5 files changed, 120 insertions(+), 88 deletions(-) create mode 100644 drivers/mtd/nand/raw/nand_hynix.c diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile index 440290bed0fe..86d9b8e8beb8 100644 --- a/drivers/mtd/nand/raw/Makefile +++ b/drivers/mtd/nand/raw/Makefile @@ -14,7 +14,7 @@ obj-$(CONFIG_SPL_NAND_DENALI) += denali_spl.o obj-$(CONFIG_SPL_NAND_SIMPLE) += nand_spl_simple.o obj-$(CONFIG_SPL_NAND_LOAD) += nand_spl_load.o obj-$(CONFIG_SPL_NAND_ECC) += nand_ecc.o -obj-$(CONFIG_SPL_NAND_BASE) += nand_base.o nand_samsung.o +obj-$(CONFIG_SPL_NAND_BASE) += nand_base.o nand_hynix.o nand_samsung.o obj-$(CONFIG_SPL_NAND_IDENT) += nand_ids.o nand_timings.o obj-$(CONFIG_TPL_NAND_INIT) += nand.o ifeq ($(CONFIG_SPL_ENV_SUPPORT),y) @@ -31,6 +31,7 @@ obj-y += nand_ids.o obj-y += nand_util.o obj-y += nand_ecc.o obj-y += nand_base.o +obj-y += nand_hynix.o obj-y += nand_samsung.o obj-y += nand_timings.o diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index fe59157bc3c4..5698c1e6a229 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -4170,85 +4170,34 @@ void nand_decode_ext_id(struct nand_chip *chip) extid = chip->id.data[3]; id_len = chip->id.len; + /* Calc pagesize */ + mtd->writesize = 1024 << (extid & 0x03); + extid >>= 2; + /* Calc oobsize */ + mtd->oobsize = (8 << (extid & 0x01)) * + (mtd->writesize >> 9); + extid >>= 2; + /* Calc blocksize. Blocksize is multiples of 64KiB */ + mtd->erasesize = (64 * 1024) << (extid & 0x03); + extid >>= 2; + /* Get buswidth information */ + /* Get buswidth information */ + if (extid & 0x1) + chip->options |= NAND_BUSWIDTH_16; + /* -* Field definitions are in the following datasheets: -* Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32) -* Hynix MLC (6 byte ID): Hynix H27UBG8T2B (p.22) -* -* Check for ID length, non-zero 6th byte, cell type, and Hynix/Samsung -* ID to decide what to do. +* Toshiba 24nm raw SLC (i.e., not BENAND) have 32B OOB per +* 512B page. For Toshiba SLC, we decode the 5th/6th byte as +* follows: +* - ID byte 6, bits[2:0]: 100b -> 43nm, 101b -> 32nm, +* 110b -> 24nm +* - ID byte 5, bit[7]:1 -> BENAND, 0 -> raw SLC */ - if (id_len == 6 && chip->id.data[0] == NAND_MFR_HYNIX && - !nand_is_slc(chip)) { - unsigned int tmp; - - /* Calc pagesize */ - mtd->writesize = 2048 << (extid & 0x03); - extid >>= 2; - /* Calc oobsize */ - switch (((extid >> 2) & 0x04) | (extid & 0x03)) { - case 0: - mtd->oobsize = 128; - break; - case 1: - mtd->oobsize = 224; - break; - case 2: - mtd->oobsize = 448; - break; - case 3: - mtd->oobsize = 64; - break; - case 4: - mtd->oobsize = 32; - break; - case 5: - mtd->oobsize = 16; - break; - default: - mtd->oobsize = 640; - break; - } - extid >>= 2; - /* Calc blocksize */ - tmp = ((extid >> 1) & 0x04) | (extid & 0x03); - if (tmp < 0x03) - mtd->erasesize = (128 * 1024) << tmp; - else if (tmp == 0x03) - mtd->erasesize = 768 * 1024; - else -
[PATCH v4 07/14] mtd: nand: Move Samsung specific init/detection logic in nand_samsung.c
From: Michael Trimarchi Upstream linux commit c51d0ac59f2420. Move Samsung specific initialization and detection logic into nand_samsung.c. This is part of the "separate vendor specific code from core" cleanup process. Signed-off-by: Michael Trimarchi Signed-off-by: Dario Binacchi --- (no changes since v3) Changes in v3: - Use commit sha1 with 13 digits. - Fix code style warnings raised by patman. - Add the SPDX-License-Identifier tag. Changes in v2: - Use short-commit form. - Remove linux info. Uboot seems that backport without add this extra information. - Adjust the include file in nand_samsung. drivers/mtd/nand/raw/Makefile | 3 +- drivers/mtd/nand/raw/nand_base.c| 52 ++--- drivers/mtd/nand/raw/nand_ids.c | 4 +- drivers/mtd/nand/raw/nand_samsung.c | 90 + include/linux/mtd/rawnand.h | 2 + 5 files changed, 100 insertions(+), 51 deletions(-) create mode 100644 drivers/mtd/nand/raw/nand_samsung.c diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile index f278f31f5cd5..440290bed0fe 100644 --- a/drivers/mtd/nand/raw/Makefile +++ b/drivers/mtd/nand/raw/Makefile @@ -14,7 +14,7 @@ obj-$(CONFIG_SPL_NAND_DENALI) += denali_spl.o obj-$(CONFIG_SPL_NAND_SIMPLE) += nand_spl_simple.o obj-$(CONFIG_SPL_NAND_LOAD) += nand_spl_load.o obj-$(CONFIG_SPL_NAND_ECC) += nand_ecc.o -obj-$(CONFIG_SPL_NAND_BASE) += nand_base.o +obj-$(CONFIG_SPL_NAND_BASE) += nand_base.o nand_samsung.o obj-$(CONFIG_SPL_NAND_IDENT) += nand_ids.o nand_timings.o obj-$(CONFIG_TPL_NAND_INIT) += nand.o ifeq ($(CONFIG_SPL_ENV_SUPPORT),y) @@ -31,6 +31,7 @@ obj-y += nand_ids.o obj-y += nand_util.o obj-y += nand_ecc.o obj-y += nand_base.o +obj-y += nand_samsung.o obj-y += nand_timings.o endif # not spl diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index 174c760f3416..fe59157bc3c4 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -4173,48 +4173,13 @@ void nand_decode_ext_id(struct nand_chip *chip) /* * Field definitions are in the following datasheets: * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32) -* New Samsung (6 byte ID): Samsung K9GAG08U0F (p.44) * Hynix MLC (6 byte ID): Hynix H27UBG8T2B (p.22) * * Check for ID length, non-zero 6th byte, cell type, and Hynix/Samsung * ID to decide what to do. */ - if (id_len == 6 && chip->id.data[0] == NAND_MFR_SAMSUNG && - !nand_is_slc(chip) && chip->id.data[5] != 0x00) { - /* Calc pagesize */ - mtd->writesize = 2048 << (extid & 0x03); - extid >>= 2; - /* Calc oobsize */ - switch (((extid >> 2) & 0x04) | (extid & 0x03)) { - case 1: - mtd->oobsize = 128; - break; - case 2: - mtd->oobsize = 218; - break; - case 3: - mtd->oobsize = 400; - break; - case 4: - mtd->oobsize = 436; - break; - case 5: - mtd->oobsize = 512; - break; - case 6: - mtd->oobsize = 640; - break; - case 7: - default: /* Other cases are "reserved" (unknown) */ - mtd->oobsize = 1024; - break; - } - extid >>= 2; - /* Calc blocksize */ - mtd->erasesize = (128 * 1024) << - (((extid >> 1) & 0x04) | (extid & 0x03)); - } else if (id_len == 6 && chip->id.data[0] == NAND_MFR_HYNIX && - !nand_is_slc(chip)) { + if (id_len == 6 && chip->id.data[0] == NAND_MFR_HYNIX && + !nand_is_slc(chip)) { unsigned int tmp; /* Calc pagesize */ @@ -4374,13 +4339,10 @@ static void nand_decode_bbm_options(struct mtd_info *mtd, * Micron devices with 2KiB pages and on SLC Samsung, Hynix, Toshiba, * AMD/Spansion, and Macronix. All others scan only the first page. */ - if (!nand_is_slc(chip) && - (maf_id == NAND_MFR_SAMSUNG || -maf_id == NAND_MFR_HYNIX)) + if (!nand_is_slc(chip) && maf_id == NAND_MFR_HYNIX) chip->bbt_options |= NAND_BBT_SCANLASTPAGE; else if ((nand_is_slc(chip) && - (maf_id == NAND_MFR_SAMSUNG || -maf_id == NAND_MFR_HYNIX || + (maf_id == NA
[PATCH v4 02/14] mtd: nand: Store nand ID in struct nand_chip
From: Michael Trimarchi Upstream linux commit 7f501f0a72036d. Store the NAND ID in struct nand_chip to avoid passing id_data and id_len as function parameters. Signed-off-by: Michael Trimarchi Signed-off-by: Dario Binacchi --- (no changes since v3) Changes in v3: - Use commit sha1 with 13 digits. - Fix code style warnings raised by patman. Changes in v2: - Use short-commit form. - Remove linux info. Uboot seems that backport without add this extra information. drivers/mtd/nand/raw/nand_base.c | 58 include/linux/mtd/rawnand.h | 15 + 2 files changed, 44 insertions(+), 29 deletions(-) diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index 9a2194ebd3f8..220804c75c87 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -4160,16 +4160,14 @@ static int nand_get_bits_per_cell(u8 cellinfo) * chip. The rest of the parameters must be decoded according to generic or * manufacturer-specific "extended ID" decoding patterns. */ -static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip, - u8 id_data[8]) +static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip) { int extid, id_len; /* The 3rd id byte holds MLC / multichip data */ - chip->bits_per_cell = nand_get_bits_per_cell(id_data[2]); + chip->bits_per_cell = nand_get_bits_per_cell(chip->id.data[2]); /* The 4th id byte is the important one */ - extid = id_data[3]; - - id_len = nand_id_len(id_data, 8); + extid = chip->id.data[3]; + id_len = chip->id.len; /* * Field definitions are in the following datasheets: @@ -4180,8 +4178,8 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip, * Check for ID length, non-zero 6th byte, cell type, and Hynix/Samsung * ID to decide what to do. */ - if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG && - !nand_is_slc(chip) && id_data[5] != 0x00) { + if (id_len == 6 && chip->id.data[0] == NAND_MFR_SAMSUNG && + !nand_is_slc(chip) && chip->id.data[5] != 0x00) { /* Calc pagesize */ mtd->writesize = 2048 << (extid & 0x03); extid >>= 2; @@ -4214,7 +4212,7 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip, /* Calc blocksize */ mtd->erasesize = (128 * 1024) << (((extid >> 1) & 0x04) | (extid & 0x03)); - } else if (id_len == 6 && id_data[0] == NAND_MFR_HYNIX && + } else if (id_len == 6 && chip->id.data[0] == NAND_MFR_HYNIX && !nand_is_slc(chip)) { unsigned int tmp; @@ -4278,10 +4276,10 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip, * 110b -> 24nm * - ID byte 5, bit[7]:1 -> BENAND, 0 -> raw SLC */ - if (id_len >= 6 && id_data[0] == NAND_MFR_TOSHIBA && - nand_is_slc(chip) && - (id_data[5] & 0x7) == 0x6 /* 24nm */ && - !(id_data[4] & 0x80) /* !BENAND */) { + if (id_len >= 6 && chip->id.data[0] == NAND_MFR_TOSHIBA && + nand_is_slc(chip) && + (chip->id.data[5] & 0x7) == 0x6 /* 24nm */ && + !(chip->id.data[4] & 0x80) /* !BENAND */) { mtd->oobsize = 32 * mtd->writesize >> 9; } @@ -4294,9 +4292,9 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip, * the chip. */ static void nand_decode_id(struct mtd_info *mtd, struct nand_chip *chip, - struct nand_flash_dev *type, u8 id_data[8]) + struct nand_flash_dev *type) { - int maf_id = id_data[0]; + int maf_id = chip->id.data[0]; mtd->erasesize = type->erasesize; mtd->writesize = type->pagesize; @@ -4311,11 +4309,11 @@ static void nand_decode_id(struct mtd_info *mtd, struct nand_chip *chip, * listed in nand_ids table. * Data sheet (5 byte ID): Spansion S30ML-P ORNAND (p.39) */ - if (maf_id == NAND_MFR_AMD && id_data[4] != 0x00 && id_data[5] == 0x00 - && id_data[6] == 0x00 && id_data[7] == 0x00 - && mtd->writesize == 512) { + if (maf_id == NAND_MFR_AMD && chip->id.data[4] != 0x00 && +
[PATCH v4 06/14] mtd: nand: Export symbol nand_decode_ext_id
From: Michael Trimarchi In preparation of moving specific nand support that are not jedec or onfi Signed-off-by: Michael Trimarchi Signed-off-by: Dario Binacchi --- (no changes since v1) drivers/mtd/nand/raw/nand_base.c | 3 ++- include/linux/mtd/rawnand.h | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index 145de22be852..174c760f3416 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -4160,7 +4160,7 @@ static int nand_get_bits_per_cell(u8 cellinfo) * chip. The rest of the parameters must be decoded according to generic or * manufacturer-specific "extended ID" decoding patterns. */ -static void nand_decode_ext_id(struct nand_chip *chip) +void nand_decode_ext_id(struct nand_chip *chip) { struct mtd_info *mtd = &chip->mtd; int extid, id_len; @@ -4286,6 +4286,7 @@ static void nand_decode_ext_id(struct nand_chip *chip) } } +EXPORT_SYMBOL_GPL(nand_decode_ext_id); /* * Manufacturer detection. Only used when the NAND is not ONFI or JEDEC diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h index d8141cb4d114..8fb2a43296f5 100644 --- a/include/linux/mtd/rawnand.h +++ b/include/linux/mtd/rawnand.h @@ -1374,4 +1374,7 @@ int nand_read_data_op(struct nand_chip *chip, void *buf, unsigned int len, int nand_write_data_op(struct nand_chip *chip, const void *buf, unsigned int len, bool force_8bit); +/* Default extended ID decoding function */ +void nand_decode_ext_id(struct nand_chip *chip); + #endif /* __LINUX_MTD_RAWNAND_H */ -- 2.32.0
[PATCH v4 05/14] mtd: nand: Fix MediaTek MT7621 SoC build
From: Michael Trimarchi nand_get_flash_type was reworked in commit 1ca6f9483e9ab5. This change break the Mediatek MT721. Fix it adjust the function call parameters +include/linux/mtd/rawnand.h:32:62: note: expected 'struct nand_chip *' but argument is of type 'struct mtd_info *' + 32 | struct nand_flash_dev *nand_get_flash_type(struct nand_chip *chip, + |~~^~~~ +drivers/mtd/nand/raw/mt7621_nand.c:1189:48: error: passing argument 2 of 'nand_get_flash_type' from incompatible pointer type [-Werror=incompatible-pointer-types] + |^~~~ + || + |struct nand_chip * +include/linux/mtd/rawnand.h:33:49: note: expected 'int *' but argument is of type 'struct nand_chip *' + 33 |int *maf_id, int *dev_id, Signed-off-by: Michael Trimarchi Signed-off-by: Dario Binacchi --- Changes in v4: - Add the patch to the series. drivers/mtd/nand/raw/mt7621_nand.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/nand/raw/mt7621_nand.c b/drivers/mtd/nand/raw/mt7621_nand.c index 2fd89349392b..9763ae6dc51a 100644 --- a/drivers/mtd/nand/raw/mt7621_nand.c +++ b/drivers/mtd/nand/raw/mt7621_nand.c @@ -1186,7 +1186,7 @@ int mt7621_nfc_spl_post_init(struct mt7621_nfc *nfc) int nand_maf_id, nand_dev_id; struct nand_flash_dev *type; - type = nand_get_flash_type(&nand->mtd, nand, &nand_maf_id, + type = nand_get_flash_type(nand, &nand_maf_id, &nand_dev_id, NULL); if (IS_ERR(type)) -- 2.32.0
[PATCH v4 04/14] mtd: nand: Get rid of mtd variable in function calls
From: Michael Trimarchi chip points to mtd. Passing chip is enough to have a reference to mtd when is necessary Signed-off-by: Michael Trimarchi Signed-off-by: Dario Binacchi --- (no changes since v3) Changes in v3: - Fix code style warnings raised by patman. drivers/mtd/nand/raw/nand_base.c | 25 + include/linux/mtd/rawnand.h | 3 +-- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index 0900e6dbf9a6..145de22be852 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -4160,8 +4160,9 @@ static int nand_get_bits_per_cell(u8 cellinfo) * chip. The rest of the parameters must be decoded according to generic or * manufacturer-specific "extended ID" decoding patterns. */ -static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip) +static void nand_decode_ext_id(struct nand_chip *chip) { + struct mtd_info *mtd = &chip->mtd; int extid, id_len; /* The 3rd id byte holds MLC / multichip data */ chip->bits_per_cell = nand_get_bits_per_cell(chip->id.data[2]); @@ -4291,7 +4292,7 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip) * compliant and does not have a full-id or legacy-id entry in the nand_ids * table. */ -static void nand_manufacturer_detect(struct mtd_info *mtd, struct nand_chip *chip) +static void nand_manufacturer_detect(struct nand_chip *chip) { /* * Try manufacturer detection if available and use @@ -4301,7 +4302,7 @@ static void nand_manufacturer_detect(struct mtd_info *mtd, struct nand_chip *chi chip->manufacturer.desc->ops->detect) chip->manufacturer.desc->ops->detect(chip); else - nand_decode_ext_id(mtd, chip); + nand_decode_ext_id(chip); } /* @@ -4324,9 +4325,9 @@ static int nand_manufacturer_init(struct nand_chip *chip) * decodes a matching ID table entry and assigns the MTD size parameters for * the chip. */ -static void nand_decode_id(struct mtd_info *mtd, struct nand_chip *chip, - struct nand_flash_dev *type) +static void nand_decode_id(struct nand_chip *chip, struct nand_flash_dev *type) { + struct mtd_info *mtd = &chip->mtd; int maf_id = chip->id.data[0]; mtd->erasesize = type->erasesize; @@ -4439,11 +4440,11 @@ static const struct nand_manufacturers *nand_get_manufacturer_desc(u8 id) /* * Get the flash and manufacturer id and lookup if the type is supported. */ -struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, - struct nand_chip *chip, - int *maf_id, int *dev_id, - struct nand_flash_dev *type) +struct nand_flash_dev *nand_get_flash_type(struct nand_chip *chip, int *maf_id, + int *dev_id, + struct nand_flash_dev *type) { + struct mtd_info *mtd = &chip->mtd; const struct nand_manufacturers *manufacturer_desc; int busw, ret; u8 *id_data = chip->id.data; @@ -4539,9 +4540,9 @@ struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, chip->chipsize = (uint64_t)type->chipsize << 20; if (!type->pagesize) { - nand_manufacturer_detect(mtd, chip); + nand_manufacturer_detect(chip); } else { - nand_decode_id(mtd, chip, type); + nand_decode_id(chip, type); } /* Get chip options */ @@ -4729,7 +4730,7 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips, nand_set_defaults(chip, chip->options & NAND_BUSWIDTH_16); /* Read the flash type */ - type = nand_get_flash_type(mtd, chip, &nand_maf_id, + type = nand_get_flash_type(chip, &nand_maf_id, &nand_dev_id, table); if (IS_ERR(type)) { diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h index 57fe7fb47bd8..d8141cb4d114 100644 --- a/include/linux/mtd/rawnand.h +++ b/include/linux/mtd/rawnand.h @@ -29,8 +29,7 @@ struct nand_flash_dev; struct device_node; /* Get the flash and manufacturer id and lookup if the type is supported. */ -struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, - struct nand_chip *chip, +struct nand_flash_dev *nand_get_flash_type(struct nand_chip *chip, int *maf_id, int *dev_id, struct nand_flash_dev *type); -- 2.32.0
[PATCH v4 03/14] mtd: nand: Add manufacturer specific initialization/detection steps
From: Michael Trimarchi Upstream linux commit abbe26d144ec22. A lot of NANDs are implementing generic features in a non-generic way, or are providing advanced auto-detection logic where the NAND ID bytes meaning changes with the NAND generation. Providing this vendor specific initialization step will allow us to get rid of full-id entries in the nand_ids table or all the vendor specific cases added over the time in the generic NAND ID decoding logic. Signed-off-by: Michael Trimarchi Signed-off-by: Dario Binacchi --- (no changes since v3) Changes in v3: - Use commit sha1 with 13 digits. - Fix code style warnings raised by patman. Changes in v2: - Use short-commit form. - Remove linux info. Uboot seems that backport without add this extra information. drivers/mtd/nand/raw/nand_base.c | 98 include/linux/mtd/rawnand.h | 30 ++ 2 files changed, 105 insertions(+), 23 deletions(-) diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index 220804c75c87..0900e6dbf9a6 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -4286,6 +4286,39 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip) } } +/* + * Manufacturer detection. Only used when the NAND is not ONFI or JEDEC + * compliant and does not have a full-id or legacy-id entry in the nand_ids + * table. + */ +static void nand_manufacturer_detect(struct mtd_info *mtd, struct nand_chip *chip) +{ + /* +* Try manufacturer detection if available and use +* nand_decode_ext_id() otherwise. +*/ + if (chip->manufacturer.desc && chip->manufacturer.desc->ops && + chip->manufacturer.desc->ops->detect) + chip->manufacturer.desc->ops->detect(chip); + else + nand_decode_ext_id(mtd, chip); +} + +/* + * Manufacturer initialization. This function is called for all NANDs including + * ONFI and JEDEC compliant ones. + * Manufacturer drivers should put all their specific initialization code in + * their ->init() hook. + */ +static int nand_manufacturer_init(struct nand_chip *chip) +{ + if (!chip->manufacturer.desc || !chip->manufacturer.desc->ops || + !chip->manufacturer.desc->ops->init) + return 0; + + return chip->manufacturer.desc->ops->init(chip); +} + /* * Old devices have chip data hardcoded in the device ID table. nand_decode_id * decodes a matching ID table entry and assigns the MTD size parameters for @@ -4383,6 +4416,26 @@ static bool find_full_id_nand(struct mtd_info *mtd, struct nand_chip *chip, return false; } +/** + * nand_get_manufacturer_desc - Get manufacturer information from the + * manufacturer ID + * @id: manufacturer ID + * + * Returns a nand_manufacturer_desc object if the manufacturer is defined + * in the NAND manufacturers database, NULL otherwise. + */ +static const struct nand_manufacturers *nand_get_manufacturer_desc(u8 id) +{ + int i; + + for (i = 0; nand_manuf_ids[i].id != 0x0; i++) { + if (nand_manuf_ids[i].id == id) + return &nand_manuf_ids[i]; + } + + return NULL; +} + /* * Get the flash and manufacturer id and lookup if the type is supported. */ @@ -4391,8 +,8 @@ struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, int *maf_id, int *dev_id, struct nand_flash_dev *type) { + const struct nand_manufacturers *manufacturer_desc; int busw, ret; - int maf_idx; u8 *id_data = chip->id.data; /* @@ -4433,6 +4486,12 @@ struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, return ERR_PTR(-ENODEV); } + chip->id.len = nand_id_len(id_data, ARRAY_SIZE(chip->id.data)); + + /* Try to identify manufacturer */ + manufacturer_desc = nand_get_manufacturer_desc(*maf_id); + chip->manufacturer.desc = manufacturer_desc; + if (!type) type = nand_flash_ids; @@ -4451,8 +4510,6 @@ struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, */ chip->options &= ~NAND_BUSWIDTH_16; - chip->id.len = nand_id_len(id_data, ARRAY_SIZE(chip->id.data)); - for (; type->name != NULL; type++) { if (is_full_id_nand(type)) { if (find_full_id_nand(mtd, chip, type)) @@ -4482,8 +4539,7 @@ struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, chip->chipsize = (uint64_t)type->chipsize << 20; if (!type->pagesize) { - /* Decode parameters from extended ID */ - nand_decode_ext_id(mtd, chip); + nand_manufac
[PATCH v4 01/14] mtd: nand: Get rid of busw parameter
From: Michael Trimarchi Upstream linux commit 29a198a1592d83. Auto-detection functions are passed a busw parameter to retrieve the actual NAND bus width and eventually set the correct value in chip->options. Rework the nand_get_flash_type() function to get rid of this extra parameter and let detection code directly set the NAND_BUSWIDTH_16 flag in chip->options if needed. Signed-off-by: Michael Trimarchi Signed-off-by: Dario Binacchi --- (no changes since v3) Changes in v3: - Use commit sha1 with 13 digits. Changes in v2: - Use short-commit form. - Remove linux info. Uboot seems that backport without add this extra information. drivers/mtd/nand/raw/nand_base.c | 59 +--- 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index e8ece0a4a0dd..9a2194ebd3f8 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -3898,8 +3898,7 @@ static void nand_onfi_detect_micron(struct nand_chip *chip, /* * Check if the NAND chip is ONFI compliant, returns 1 if it is, 0 otherwise. */ -static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, - int *busw) +static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip) { struct nand_onfi_params *p = &chip->onfi_params; char id[4]; @@ -3971,9 +3970,7 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, chip->bits_per_cell = p->bits_per_cell; if (onfi_feature(chip) & ONFI_FEATURE_16_BIT_BUS) - *busw = NAND_BUSWIDTH_16; - else - *busw = 0; + chip->options |= NAND_BUSWIDTH_16; if (p->ecc_bits != 0xff) { chip->ecc_strength_ds = p->ecc_bits; @@ -4003,8 +4000,7 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, return 1; } #else -static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, - int *busw) +static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip) { return 0; } @@ -4013,8 +4009,7 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, /* * Check if the NAND chip is JEDEC compliant, returns 1 if it is, 0 otherwise. */ -static int nand_flash_detect_jedec(struct mtd_info *mtd, struct nand_chip *chip, - int *busw) +static int nand_flash_detect_jedec(struct mtd_info *mtd, struct nand_chip *chip) { struct nand_jedec_params *p = &chip->jedec_params; struct jedec_ecc_info *ecc; @@ -4076,9 +4071,7 @@ static int nand_flash_detect_jedec(struct mtd_info *mtd, struct nand_chip *chip, chip->bits_per_cell = p->bits_per_cell; if (jedec_feature(chip) & JEDEC_FEATURE_16_BIT_BUS) - *busw = NAND_BUSWIDTH_16; - else - *busw = 0; + chip->options |= NAND_BUSWIDTH_16; /* ECC info */ ecc = &p->ecc_info[0]; @@ -4168,7 +4161,7 @@ static int nand_get_bits_per_cell(u8 cellinfo) * manufacturer-specific "extended ID" decoding patterns. */ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip, - u8 id_data[8], int *busw) + u8 id_data[8]) { int extid, id_len; /* The 3rd id byte holds MLC / multichip data */ @@ -4221,7 +4214,6 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip, /* Calc blocksize */ mtd->erasesize = (128 * 1024) << (((extid >> 1) & 0x04) | (extid & 0x03)); - *busw = 0; } else if (id_len == 6 && id_data[0] == NAND_MFR_HYNIX && !nand_is_slc(chip)) { unsigned int tmp; @@ -4262,7 +4254,6 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip, mtd->erasesize = 768 * 1024; else mtd->erasesize = (64 * 1024) << tmp; - *busw = 0; } else { /* Calc pagesize */ mtd->writesize = 1024 << (extid & 0x03); @@ -4275,7 +4266,9 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip, mtd->erasesize = (64 * 1024) << (extid & 0x03); extid >>= 2; /* Get buswidth information */ - *busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0; + /* Get buswidth information */ + if (extid & 0x1) + chip->options |= NAND_BUSWIDTH_16; /* *
[PATCH v4 00/14] Port manufacturer specific initialization
In preparation of re-sync of mtd stack, we opt to move the current stack slowly in order to have a more easy sync and test. We would like to prepare uboot to support no-jedec and no-onfi compliant nand so we need to clean up a bit the code we have now and upstream some of the support. In this series we expect no functional change Tested on: - imx6ull Micron MT29F2G08ABAGAH4 - imx8mn Macronix MX30LF4G18AC Changes in v4: - Add the patch "mtd: nand: Fix MediaTek MT7621 SoC build" to the series. Changes in v3: - Use commit sha1 with 13 digits. - Use commit sha1 with 13 digits. - Fix code style warnings raised by patman. - Use commit sha1 with 13 digits. - Fix code style warnings raised by patman. - Fix code style warnings raised by patman. - Use commit sha1 with 13 digits. - Fix code style warnings raised by patman. - Add the SPDX-License-Identifier tag. - Use commit sha1 with 13 digits. - Add the SPDX-License-Identifier tag. - Fix code style warnings raised by patman. - Use commit sha1 with 13 digits. - Add the SPDX-License-Identifier tag. - Fix code style warnings raised by patman. - Use commit sha1 with 13 digits. - Add the SPDX-License-Identifier tag. - Fix code style warnings raised by patman. - Use commit sha1 with 13 digits. - Add the SPDX-License-Identifier tag. - Fix code style warnings raised by patman. - Use commit sha1 with 13 digits. - Add the SPDX-License-Identifier tag. - Fix code style warnings raised by patman. - Use commit sha1 with 13 digits. - Use commit sha1 with 13 digits. - Wrap commit description to a maximum of 75 chars. Changes in v2: - Use short-commit form. - Remove linux info. Uboot seems that backport without add this extra information. - Use short-commit form. - Remove linux info. Uboot seems that backport without add this extra information. - Use short-commit form. - Remove linux info. Uboot seems that backport without add this extra information. - Use short-commit form. - Remove linux info. Uboot seems that backport without add this extra information. - Adjust the include file in nand_samsung. - Use short-commit form - Remove linux info. Uboot seems that backport without add this extra information. - Adjust the include file in nand_hynix. - Use short-commit form - Remove linux info. Uboot seems that backport without add this extra information. - Adjust the include file in nand_toshiba. - Use short-commit form - Remove linux info. Uboot seems that backport without add this extra information. - Adjust the include file in nand_micron. - Use short-commit form - Remove linux info. Uboot seems that backport without add this extra information. - Adjust the include file in nand_amd. - Use short-commit form - Remove linux info. Uboot seems that backport without add this extra information. - Adjust the include file in nand_macronix. - Use short-commit form - Remove linux info. Uboot seems that backport without add this extra information. - Use short-commit form. - Remove linux info. Uboot seems that backport without add this extra information. Michael Trimarchi (14): mtd: nand: Get rid of busw parameter mtd: nand: Store nand ID in struct nand_chip mtd: nand: Add manufacturer specific initialization/detection steps mtd: nand: Get rid of mtd variable in function calls mtd: nand: Fix MediaTek MT7621 SoC build mtd: nand: Export symbol nand_decode_ext_id mtd: nand: Move Samsung specific init/detection logic in nand_samsung.c mtd: nand: Move Hynix specific init/detection logic in nand_hynix.c mtd: nand: Move Toshiba specific init/detection logic in nand_toshiba.c mtd: nand: Move Micron specific init logic in nand_micron.c mtd: nand: Move AMD/Spansion specific init/detection logic in nand_amd.c mtd: nand: Move Macronix specific initialization in nand_macronix.c mtd: nand: toshiba: Retrieve ECC requirements from extended ID mtd: decommission the NAND museum drivers/mtd/nand/raw/Makefile| 10 +- drivers/mtd/nand/raw/mt7621_nand.c | 2 +- drivers/mtd/nand/raw/nand_amd.c | 52 drivers/mtd/nand/raw/nand_base.c | 370 ++- drivers/mtd/nand/raw/nand_hynix.c| 85 ++ drivers/mtd/nand/raw/nand_ids.c | 24 +- drivers/mtd/nand/raw/nand_macronix.c | 31 +++ drivers/mtd/nand/raw/nand_micron.c | 87 +++ drivers/mtd/nand/raw/nand_samsung.c | 90 +++ drivers/mtd/nand/raw/nand_toshiba.c | 79 ++ include/linux/mtd/rawnand.h | 78 -- 11 files changed, 626 insertions(+), 282 deletions(-) create mode 100644 drivers/mtd/nand/raw/nand_amd.c create mode 100644 drivers/mtd/nand/raw/nand_hynix.c create mode 100644 drivers/mtd/nand/raw/nand_macronix.c create mode 100644 drivers/mtd/nand/raw/nand_micron.c create mode 100644 drivers/mtd/nand/raw/nand_samsung.c create mode 100644 drivers/mtd/nand/raw/nand_toshiba.c -- 2.32.0
[PATCH v3 13/13] mtd: decommission the NAND museum
From: Michael Trimarchi Upstream linux commit f7025a43a9da26. The MTD subsystem has its own small museum of ancient NANDs in a form of the CONFIG_MTD_NAND_MUSEUM_IDS configuration option. The museum contains stone age NANDs with 256 bytes pages, as well as iron age NANDs with 512 bytes per page and up to 8MiB page size. It is with great sorrow that I inform you that the museum is being decommissioned. The MTD subsystem is out of budget for Kconfig options and already has too many of them, and there is a general kernel trend to simplify the configuration menu. We remove the stone age exhibits along with closing the museum REMARK Don't apply this part from upstream: Some of the iron age ones are transferred to the regular NAND depot. Namely, only those which have unique device IDs are transferred, and the ones which have conflicting device IDs are removed. Signed-off-by: Michael Trimarchi Signed-off-by: Dario Binacchi --- Changes in v3: - Use commit sha1 with 13 digits. - Wrap commit description to a maximum of 75 chars. Changes in v2: - Use short-commit form. - Remove linux info. Uboot seems that backport without add this extra information. drivers/mtd/nand/raw/nand_ids.c | 10 -- 1 file changed, 10 deletions(-) diff --git a/drivers/mtd/nand/raw/nand_ids.c b/drivers/mtd/nand/raw/nand_ids.c index 7602dd30f169..4dece1b20676 100644 --- a/drivers/mtd/nand/raw/nand_ids.c +++ b/drivers/mtd/nand/raw/nand_ids.c @@ -24,16 +24,6 @@ * extended chip ID. */ struct nand_flash_dev nand_flash_ids[] = { -#ifdef CONFIG_MTD_NAND_MUSEUM_IDS - LEGACY_ID_NAND("NAND 1MiB 5V 8-bit",0x6e, 1, SZ_4K, SP_OPTIONS), - LEGACY_ID_NAND("NAND 2MiB 5V 8-bit",0x64, 2, SZ_4K, SP_OPTIONS), - LEGACY_ID_NAND("NAND 1MiB 3,3V 8-bit", 0xe8, 1, SZ_4K, SP_OPTIONS), - LEGACY_ID_NAND("NAND 1MiB 3,3V 8-bit", 0xec, 1, SZ_4K, SP_OPTIONS), - LEGACY_ID_NAND("NAND 2MiB 3,3V 8-bit", 0xea, 2, SZ_4K, SP_OPTIONS), - LEGACY_ID_NAND("NAND 4MiB 3,3V 8-bit", 0xd5, 4, SZ_8K, SP_OPTIONS), - - LEGACY_ID_NAND("NAND 8MiB 3,3V 8-bit", 0xe6, 8, SZ_8K, SP_OPTIONS), -#endif /* * Some incompatible NAND chips share device ID's and so must be * listed by full ID. We list them first so that we can easily identify -- 2.32.0
[PATCH v3 12/13] mtd: nand: toshiba: Retrieve ECC requirements from extended ID
From: Michael Trimarchi Upstream linux commit fb3bff5b407e58. This patch enables support to read the ECC strength and size from the NAND flash using Toshiba Memory SLC NAND extended-ID. This patch is based on the information of the 6th ID byte of the Toshiba Memory SLC NAND. Signed-off-by: Michael Trimarchi Signed-off-by: Dario Binacchi --- Changes in v3: - Use commit sha1 with 13 digits. Changes in v2: - Use short-commit form - Remove linux info. Uboot seems that backport without add this extra information. drivers/mtd/nand/raw/nand_toshiba.c | 26 ++ 1 file changed, 26 insertions(+) diff --git a/drivers/mtd/nand/raw/nand_toshiba.c b/drivers/mtd/nand/raw/nand_toshiba.c index f7426fa59f51..99dc44df671a 100644 --- a/drivers/mtd/nand/raw/nand_toshiba.c +++ b/drivers/mtd/nand/raw/nand_toshiba.c @@ -37,6 +37,32 @@ static void toshiba_nand_decode_id(struct nand_chip *chip) (chip->id.data[5] & 0x7) == 0x6 /* 24nm */ && !(chip->id.data[4] & 0x80) /* !BENAND */) mtd->oobsize = 32 * mtd->writesize >> 9; + + /* +* Extract ECC requirements from 6th id byte. +* For Toshiba SLC, ecc requrements are as follows: +* - 43nm: 1 bit ECC for each 512Byte is required. +* - 32nm: 4 bit ECC for each 512Byte is required. +* - 24nm: 8 bit ECC for each 512Byte is required. +*/ + if (chip->id.len >= 6 && nand_is_slc(chip)) { + chip->ecc_step_ds = 512; + switch (chip->id.data[5] & 0x7) { + case 0x4: + chip->ecc_strength_ds = 1; + break; + case 0x5: + chip->ecc_strength_ds = 4; + break; + case 0x6: + chip->ecc_strength_ds = 8; + break; + default: + WARN(1, "Could not get ECC info"); + chip->ecc_step_ds = 0; + break; + } + } } static int toshiba_nand_init(struct nand_chip *chip) -- 2.32.0
[PATCH v3 11/13] mtd: nand: Move Macronix specific initialization in nand_macronix.c
From: Michael Trimarchi Upstream linux commit 3b5206f4be9b65. Move Macronix specific initialization logic into nand_macronix.c. This is part of the "separate vendor specific code from core" cleanup process. Signed-off-by: Michael Trimarchi Signed-off-by: Dario Binacchi --- Changes in v3: - Use commit sha1 with 13 digits. - Add the SPDX-License-Identifier tag. - Fix code style warnings raised by patman. Changes in v2: - Use short-commit form - Remove linux info. Uboot seems that backport without add this extra information. - Adjust the include file in nand_macronix. drivers/mtd/nand/raw/Makefile| 4 +++- drivers/mtd/nand/raw/nand_base.c | 11 -- drivers/mtd/nand/raw/nand_ids.c | 2 +- drivers/mtd/nand/raw/nand_macronix.c | 31 include/linux/mtd/rawnand.h | 1 + 5 files changed, 36 insertions(+), 13 deletions(-) create mode 100644 drivers/mtd/nand/raw/nand_macronix.c diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile index 9c2ced9925d8..a398aa9d8864 100644 --- a/drivers/mtd/nand/raw/Makefile +++ b/drivers/mtd/nand/raw/Makefile @@ -14,7 +14,8 @@ obj-$(CONFIG_SPL_NAND_DENALI) += denali_spl.o obj-$(CONFIG_SPL_NAND_SIMPLE) += nand_spl_simple.o obj-$(CONFIG_SPL_NAND_LOAD) += nand_spl_load.o obj-$(CONFIG_SPL_NAND_ECC) += nand_ecc.o -obj-$(CONFIG_SPL_NAND_BASE) += nand_base.o nand_amd.o nand_hynix.o nand_micron.o \ +obj-$(CONFIG_SPL_NAND_BASE) += nand_base.o nand_amd.o nand_hynix.o \ + nand_macronix.o nand_micron.o \ nand_samsung.o nand_toshiba.o obj-$(CONFIG_SPL_NAND_IDENT) += nand_ids.o nand_timings.o obj-$(CONFIG_TPL_NAND_INIT) += nand.o @@ -34,6 +35,7 @@ obj-y += nand_ecc.o obj-y += nand_base.o obj-y += nand_amd.o obj-y += nand_hynix.o +obj-y += nand_macronix.o obj-y += nand_micron.o obj-y += nand_samsung.o obj-y += nand_toshiba.o diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index 68e6f4f14347..4b09a1128827 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -4217,22 +4217,11 @@ static void nand_decode_id(struct nand_chip *chip, struct nand_flash_dev *type) static void nand_decode_bbm_options(struct mtd_info *mtd, struct nand_chip *chip) { - int maf_id = chip->id.data[0]; - /* Set the bad block position */ if (mtd->writesize > 512 || (chip->options & NAND_BUSWIDTH_16)) chip->badblockpos = NAND_LARGE_BADBLOCK_POS; else chip->badblockpos = NAND_SMALL_BADBLOCK_POS; - - /* -* Bad block marker is stored in the last page of each block on Samsung -* and Hynix MLC devices; stored in first two pages of each block on -* Micron devices with 2KiB pages and on SLC Samsung, Hynix, Toshiba, -* AMD/Spansion, and Macronix. All others scan only the first page. -*/ - if (nand_is_slc(chip) && maf_id == NAND_MFR_MACRONIX) - chip->bbt_options |= NAND_BBT_SCAN2NDPAGE; } static inline bool is_full_id_nand(struct nand_flash_dev *type) diff --git a/drivers/mtd/nand/raw/nand_ids.c b/drivers/mtd/nand/raw/nand_ids.c index c78f2e088040..7602dd30f169 100644 --- a/drivers/mtd/nand/raw/nand_ids.c +++ b/drivers/mtd/nand/raw/nand_ids.c @@ -197,7 +197,7 @@ struct nand_manufacturers nand_manuf_ids[] = { {NAND_MFR_HYNIX, "Hynix", &hynix_nand_manuf_ops}, {NAND_MFR_MICRON, "Micron", µn_nand_manuf_ops}, {NAND_MFR_AMD, "AMD/Spansion", &amd_nand_manuf_ops}, - {NAND_MFR_MACRONIX, "Macronix"}, + {NAND_MFR_MACRONIX, "Macronix", ¯onix_nand_manuf_ops}, {NAND_MFR_EON, "Eon"}, {NAND_MFR_SANDISK, "SanDisk"}, {NAND_MFR_INTEL, "Intel"}, diff --git a/drivers/mtd/nand/raw/nand_macronix.c b/drivers/mtd/nand/raw/nand_macronix.c new file mode 100644 index ..dc972e590922 --- /dev/null +++ b/drivers/mtd/nand/raw/nand_macronix.c @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2017 Free Electrons + * Copyright (C) 2017 NextThing Co + * + * Author: Boris Brezillon + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include + +static int macronix_nand_init(struct nand_chip *chip) +{ + if (nand_is_slc(chip)) + chip->bbt_options |= NAND_BBT_SC
[PATCH v3 10/13] mtd: nand: Move AMD/Spansion specific init/detection logic in nand_amd.c
From: Michael Trimarchi Upstream linux commit 229204da53b31d. Move AMD/Spansion specific initialization/detection logic into nand_amd.c. This is part of the "separate vendor specific code from core" cleanup process. Signed-off-by: Michael Trimarchi Signed-off-by: Dario Binacchi --- Changes in v3: - Use commit sha1 with 13 digits. - Add the SPDX-License-Identifier tag. - Fix code style warnings raised by patman. Changes in v2: - Use short-commit form - Remove linux info. Uboot seems that backport without add this extra information. - Adjust the include file in nand_amd. drivers/mtd/nand/raw/Makefile| 4 ++- drivers/mtd/nand/raw/nand_amd.c | 52 drivers/mtd/nand/raw/nand_base.c | 17 +-- drivers/mtd/nand/raw/nand_ids.c | 2 +- include/linux/mtd/rawnand.h | 1 + 5 files changed, 58 insertions(+), 18 deletions(-) create mode 100644 drivers/mtd/nand/raw/nand_amd.c diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile index 8ef30b45fd2d..9c2ced9925d8 100644 --- a/drivers/mtd/nand/raw/Makefile +++ b/drivers/mtd/nand/raw/Makefile @@ -14,7 +14,8 @@ obj-$(CONFIG_SPL_NAND_DENALI) += denali_spl.o obj-$(CONFIG_SPL_NAND_SIMPLE) += nand_spl_simple.o obj-$(CONFIG_SPL_NAND_LOAD) += nand_spl_load.o obj-$(CONFIG_SPL_NAND_ECC) += nand_ecc.o -obj-$(CONFIG_SPL_NAND_BASE) += nand_base.o nand_hynix.o nand_micron.o nand_samsung.o nand_toshiba.o +obj-$(CONFIG_SPL_NAND_BASE) += nand_base.o nand_amd.o nand_hynix.o nand_micron.o \ + nand_samsung.o nand_toshiba.o obj-$(CONFIG_SPL_NAND_IDENT) += nand_ids.o nand_timings.o obj-$(CONFIG_TPL_NAND_INIT) += nand.o ifeq ($(CONFIG_SPL_ENV_SUPPORT),y) @@ -31,6 +32,7 @@ obj-y += nand_ids.o obj-y += nand_util.o obj-y += nand_ecc.o obj-y += nand_base.o +obj-y += nand_amd.o obj-y += nand_hynix.o obj-y += nand_micron.o obj-y += nand_samsung.o diff --git a/drivers/mtd/nand/raw/nand_amd.c b/drivers/mtd/nand/raw/nand_amd.c new file mode 100644 index ..e02b8c79dba2 --- /dev/null +++ b/drivers/mtd/nand/raw/nand_amd.c @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2017 Free Electrons + * Copyright (C) 2017 NextThing Co + * + * Author: Boris Brezillon + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include + +static void amd_nand_decode_id(struct nand_chip *chip) +{ + struct mtd_info *mtd = nand_to_mtd(chip); + + nand_decode_ext_id(chip); + + /* +* Check for Spansion/AMD ID + repeating 5th, 6th byte since +* some Spansion chips have erasesize that conflicts with size +* listed in nand_ids table. +* Data sheet (5 byte ID): Spansion S30ML-P ORNAND (p.39) +*/ + if (chip->id.data[4] != 0x00 && chip->id.data[5] == 0x00 && + chip->id.data[6] == 0x00 && chip->id.data[7] == 0x00 && + mtd->writesize == 512) { + mtd->erasesize = 128 * 1024; + mtd->erasesize <<= ((chip->id.data[3] & 0x03) << 1); + } +} + +static int amd_nand_init(struct nand_chip *chip) +{ + if (nand_is_slc(chip)) + chip->bbt_options |= NAND_BBT_SCAN2NDPAGE; + + return 0; +} + +const struct nand_manufacturer_ops amd_nand_manuf_ops = { + .detect = amd_nand_decode_id, + .init = amd_nand_init, +}; diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index fe7e049d4064..68e6f4f14347 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -4200,7 +4200,6 @@ static int nand_manufacturer_init(struct nand_chip *chip) static void nand_decode_id(struct nand_chip *chip, struct nand_flash_dev *type) { struct mtd_info *mtd = &chip->mtd; - int maf_id = chip->id.data[0]; mtd->erasesize = type->erasesize; mtd->writesize = type->pagesize; @@ -4208,19 +4207,6 @@ static void nand_decode_id(struct nand_chip *chip, struct nand_flash_dev *type) /* All legacy ID NAND are small-page, SLC */ chip->bits_per_cell = 1; - - /* -* Check for Spansion/AMD ID + repeating 5th, 6th byte since -* some Spansion chips have erasesize that conflicts with size -* listed in nand_ids table. -* Data sheet (5 byte ID): Spansion S30ML-P ORNAND (p.39) -*/ - if (maf_id == NAND_MFR_AMD && chip->id.data[4] != 0x00 &&
[PATCH v3 09/13] mtd: nand: Move Micron specific init logic in nand_micron.c
From: Michael Trimarchi Upstream linux commit 10d4e75c36f6c1. Move Micron specific initialization logic into nand_micron.c. This is part of the "separate vendor specific code from core" cleanup process. Signed-off-by: Michael Trimarchi Signed-off-by: Dario Binacchi --- Changes in v3: - Use commit sha1 with 13 digits. - Add the SPDX-License-Identifier tag. - Fix code style warnings raised by patman. Changes in v2: - Use short-commit form - Remove linux info. Uboot seems that backport without add this extra information. - Adjust the include file in nand_micron. drivers/mtd/nand/raw/Makefile | 3 +- drivers/mtd/nand/raw/nand_base.c | 33 +--- drivers/mtd/nand/raw/nand_ids.c| 2 +- drivers/mtd/nand/raw/nand_micron.c | 87 ++ include/linux/mtd/rawnand.h| 21 +--- 5 files changed, 93 insertions(+), 53 deletions(-) create mode 100644 drivers/mtd/nand/raw/nand_micron.c diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile index 16e0775395a2..8ef30b45fd2d 100644 --- a/drivers/mtd/nand/raw/Makefile +++ b/drivers/mtd/nand/raw/Makefile @@ -14,7 +14,7 @@ obj-$(CONFIG_SPL_NAND_DENALI) += denali_spl.o obj-$(CONFIG_SPL_NAND_SIMPLE) += nand_spl_simple.o obj-$(CONFIG_SPL_NAND_LOAD) += nand_spl_load.o obj-$(CONFIG_SPL_NAND_ECC) += nand_ecc.o -obj-$(CONFIG_SPL_NAND_BASE) += nand_base.o nand_hynix.o nand_samsung.o nand_toshiba.o +obj-$(CONFIG_SPL_NAND_BASE) += nand_base.o nand_hynix.o nand_micron.o nand_samsung.o nand_toshiba.o obj-$(CONFIG_SPL_NAND_IDENT) += nand_ids.o nand_timings.o obj-$(CONFIG_TPL_NAND_INIT) += nand.o ifeq ($(CONFIG_SPL_ENV_SUPPORT),y) @@ -32,6 +32,7 @@ obj-y += nand_util.o obj-y += nand_ecc.o obj-y += nand_base.o obj-y += nand_hynix.o +obj-y += nand_micron.o obj-y += nand_samsung.o obj-y += nand_toshiba.o obj-y += nand_timings.o diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index 4ea7f10a06fc..fe7e049d4064 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -3871,30 +3871,6 @@ ext_out: return ret; } -static int nand_setup_read_retry_micron(struct mtd_info *mtd, int retry_mode) -{ - struct nand_chip *chip = mtd_to_nand(mtd); - uint8_t feature[ONFI_SUBFEATURE_PARAM_LEN] = {retry_mode}; - - return chip->onfi_set_features(mtd, chip, ONFI_FEATURE_ADDR_READ_RETRY, - feature); -} - -/* - * Configure chip properties from Micron vendor-specific ONFI table - */ -static void nand_onfi_detect_micron(struct nand_chip *chip, - struct nand_onfi_params *p) -{ - struct nand_onfi_vendor_micron *micron = (void *)p->vendor; - - if (le16_to_cpu(p->vendor_revision) < 1) - return; - - chip->read_retries = micron->read_retry_options; - chip->setup_read_retry = nand_setup_read_retry_micron; -} - /* * Check if the NAND chip is ONFI compliant, returns 1 if it is, 0 otherwise. */ @@ -3994,9 +3970,6 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip) pr_warn("Could not retrieve ONFI ECC requirements\n"); } - if (p->jedec_id == NAND_MFR_MICRON) - nand_onfi_detect_micron(chip, p); - return 1; } #else @@ -4272,10 +4245,8 @@ static void nand_decode_bbm_options(struct mtd_info *mtd, * Micron devices with 2KiB pages and on SLC Samsung, Hynix, Toshiba, * AMD/Spansion, and Macronix. All others scan only the first page. */ - if ((nand_is_slc(chip) && -(maf_id == NAND_MFR_AMD || - maf_id == NAND_MFR_MACRONIX)) || - (mtd->writesize == 2048 && maf_id == NAND_MFR_MICRON)) + if (nand_is_slc(chip) && + (maf_id == NAND_MFR_AMD || maf_id == NAND_MFR_MACRONIX)) chip->bbt_options |= NAND_BBT_SCAN2NDPAGE; } diff --git a/drivers/mtd/nand/raw/nand_ids.c b/drivers/mtd/nand/raw/nand_ids.c index 509652c8e26c..bb5ac8337fde 100644 --- a/drivers/mtd/nand/raw/nand_ids.c +++ b/drivers/mtd/nand/raw/nand_ids.c @@ -195,7 +195,7 @@ struct nand_manufacturers nand_manuf_ids[] = { {NAND_MFR_RENESAS, "Renesas"}, {NAND_MFR_STMICRO, "ST Micro"}, {NAND_MFR_HYNIX, "Hynix", &hynix_nand_manuf_ops}, - {NAND_MFR_MICRON, "Micron"}, + {NAND_MFR_MICRON, "Micron", µn_nand_manuf_ops}, {NAND_MFR_AMD, "AMD/Spansion"}, {NAND_MFR_MACRONIX, "Macronix"}, {NAND_MFR_EON, "Eon"}, diff --git a/drivers/mtd/nand/raw/nand_micron.c b/drivers/mtd/nand/raw/nand_micron.c new file mode 100644 index ..8b31c6198134 --- /dev/null +++ b/drivers/mtd/nand/raw/nand_micron.c @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2017 Free Electrons + * Copyright (C) 2017 NextThing Co
[PATCH v3 08/13] mtd: nand: Move Toshiba specific init/detection logic in nand_toshiba.c
From: Michael Trimarchi Upstream linux commit 9b2d61f80b060c. Move Toshiba specific initialization and detection logic into nand_toshiba.c. This is part of the "separate vendor specific code from core" cleanup process. Signed-off-by: Michael Trimarchi Signed-off-by: Dario Binacchi --- Changes in v3: - Use commit sha1 with 13 digits. - Add the SPDX-License-Identifier tag. - Fix code style warnings raised by patman. Changes in v2: - Use short-commit form - Remove linux info. Uboot seems that backport without add this extra information. - Adjust the include file in nand_toshiba. drivers/mtd/nand/raw/Makefile | 3 +- drivers/mtd/nand/raw/nand_base.c| 21 ++-- drivers/mtd/nand/raw/nand_ids.c | 2 +- drivers/mtd/nand/raw/nand_toshiba.c | 53 + include/linux/mtd/rawnand.h | 1 + 5 files changed, 59 insertions(+), 21 deletions(-) create mode 100644 drivers/mtd/nand/raw/nand_toshiba.c diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile index 86d9b8e8beb8..16e0775395a2 100644 --- a/drivers/mtd/nand/raw/Makefile +++ b/drivers/mtd/nand/raw/Makefile @@ -14,7 +14,7 @@ obj-$(CONFIG_SPL_NAND_DENALI) += denali_spl.o obj-$(CONFIG_SPL_NAND_SIMPLE) += nand_spl_simple.o obj-$(CONFIG_SPL_NAND_LOAD) += nand_spl_load.o obj-$(CONFIG_SPL_NAND_ECC) += nand_ecc.o -obj-$(CONFIG_SPL_NAND_BASE) += nand_base.o nand_hynix.o nand_samsung.o +obj-$(CONFIG_SPL_NAND_BASE) += nand_base.o nand_hynix.o nand_samsung.o nand_toshiba.o obj-$(CONFIG_SPL_NAND_IDENT) += nand_ids.o nand_timings.o obj-$(CONFIG_TPL_NAND_INIT) += nand.o ifeq ($(CONFIG_SPL_ENV_SUPPORT),y) @@ -33,6 +33,7 @@ obj-y += nand_ecc.o obj-y += nand_base.o obj-y += nand_hynix.o obj-y += nand_samsung.o +obj-y += nand_toshiba.o obj-y += nand_timings.o endif # not spl diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index 5698c1e6a229..4ea7f10a06fc 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -4163,12 +4163,11 @@ static int nand_get_bits_per_cell(u8 cellinfo) void nand_decode_ext_id(struct nand_chip *chip) { struct mtd_info *mtd = &chip->mtd; - int extid, id_len; + int extid; /* The 3rd id byte holds MLC / multichip data */ chip->bits_per_cell = nand_get_bits_per_cell(chip->id.data[2]); /* The 4th id byte is the important one */ extid = chip->id.data[3]; - id_len = chip->id.len; /* Calc pagesize */ mtd->writesize = 1024 << (extid & 0x03); @@ -4184,21 +4183,6 @@ void nand_decode_ext_id(struct nand_chip *chip) /* Get buswidth information */ if (extid & 0x1) chip->options |= NAND_BUSWIDTH_16; - - /* -* Toshiba 24nm raw SLC (i.e., not BENAND) have 32B OOB per -* 512B page. For Toshiba SLC, we decode the 5th/6th byte as -* follows: -* - ID byte 6, bits[2:0]: 100b -> 43nm, 101b -> 32nm, -* 110b -> 24nm -* - ID byte 5, bit[7]:1 -> BENAND, 0 -> raw SLC -*/ - if (id_len >= 6 && chip->id.data[0] == NAND_MFR_TOSHIBA && - nand_is_slc(chip) && - (chip->id.data[5] & 0x7) == 0x6 /* 24nm */ && - !(chip->id.data[4] & 0x80) /* !BENAND */) { - mtd->oobsize = 32 * mtd->writesize >> 9; - } } EXPORT_SYMBOL_GPL(nand_decode_ext_id); @@ -4289,8 +4273,7 @@ static void nand_decode_bbm_options(struct mtd_info *mtd, * AMD/Spansion, and Macronix. All others scan only the first page. */ if ((nand_is_slc(chip) && -(maf_id == NAND_MFR_TOSHIBA || - maf_id == NAND_MFR_AMD || +(maf_id == NAND_MFR_AMD || maf_id == NAND_MFR_MACRONIX)) || (mtd->writesize == 2048 && maf_id == NAND_MFR_MICRON)) chip->bbt_options |= NAND_BBT_SCAN2NDPAGE; diff --git a/drivers/mtd/nand/raw/nand_ids.c b/drivers/mtd/nand/raw/nand_ids.c index ec263a43279a..509652c8e26c 100644 --- a/drivers/mtd/nand/raw/nand_ids.c +++ b/drivers/mtd/nand/raw/nand_ids.c @@ -188,7 +188,7 @@ struct nand_flash_dev nand_flash_ids[] = { /* Manufacturer IDs */ struct nand_manufacturers nand_manuf_ids[] = { - {NAND_MFR_TOSHIBA, "Toshiba"}, + {NAND_MFR_TOSHIBA, "Toshiba", &toshiba_nand_manuf_ops}, {NAND_MFR_SAMSUNG, "Samsung", &samsung_nand_manuf_ops}, {NAND_MFR_FUJITSU, "Fujitsu"}, {NAND_MFR_NATIONAL, "National"}, diff --git a/drivers/mtd/nand/raw/nand_toshiba.c b/drivers/mtd/nand/raw/nand_toshiba.c new file mode 100644 index ..f7426fa59f51 --- /dev/null +++ b/drivers/mtd/nand/raw/nand_toshiba.c @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2017 F
[PATCH v3 06/13] mtd: nand: Move Samsung specific init/detection logic in nand_samsung.c
From: Michael Trimarchi Upstream linux commit c51d0ac59f2420. Move Samsung specific initialization and detection logic into nand_samsung.c. This is part of the "separate vendor specific code from core" cleanup process. Signed-off-by: Michael Trimarchi Signed-off-by: Dario Binacchi --- Changes in v3: - Use commit sha1 with 13 digits. - Fix code style warnings raised by patman. - Add the SPDX-License-Identifier tag. Changes in v2: - Use short-commit form. - Remove linux info. Uboot seems that backport without add this extra information. - Adjust the include file in nand_samsung. drivers/mtd/nand/raw/Makefile | 3 +- drivers/mtd/nand/raw/nand_base.c| 52 ++--- drivers/mtd/nand/raw/nand_ids.c | 4 +- drivers/mtd/nand/raw/nand_samsung.c | 90 + include/linux/mtd/rawnand.h | 2 + 5 files changed, 100 insertions(+), 51 deletions(-) create mode 100644 drivers/mtd/nand/raw/nand_samsung.c diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile index f278f31f5cd5..440290bed0fe 100644 --- a/drivers/mtd/nand/raw/Makefile +++ b/drivers/mtd/nand/raw/Makefile @@ -14,7 +14,7 @@ obj-$(CONFIG_SPL_NAND_DENALI) += denali_spl.o obj-$(CONFIG_SPL_NAND_SIMPLE) += nand_spl_simple.o obj-$(CONFIG_SPL_NAND_LOAD) += nand_spl_load.o obj-$(CONFIG_SPL_NAND_ECC) += nand_ecc.o -obj-$(CONFIG_SPL_NAND_BASE) += nand_base.o +obj-$(CONFIG_SPL_NAND_BASE) += nand_base.o nand_samsung.o obj-$(CONFIG_SPL_NAND_IDENT) += nand_ids.o nand_timings.o obj-$(CONFIG_TPL_NAND_INIT) += nand.o ifeq ($(CONFIG_SPL_ENV_SUPPORT),y) @@ -31,6 +31,7 @@ obj-y += nand_ids.o obj-y += nand_util.o obj-y += nand_ecc.o obj-y += nand_base.o +obj-y += nand_samsung.o obj-y += nand_timings.o endif # not spl diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index 174c760f3416..fe59157bc3c4 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -4173,48 +4173,13 @@ void nand_decode_ext_id(struct nand_chip *chip) /* * Field definitions are in the following datasheets: * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32) -* New Samsung (6 byte ID): Samsung K9GAG08U0F (p.44) * Hynix MLC (6 byte ID): Hynix H27UBG8T2B (p.22) * * Check for ID length, non-zero 6th byte, cell type, and Hynix/Samsung * ID to decide what to do. */ - if (id_len == 6 && chip->id.data[0] == NAND_MFR_SAMSUNG && - !nand_is_slc(chip) && chip->id.data[5] != 0x00) { - /* Calc pagesize */ - mtd->writesize = 2048 << (extid & 0x03); - extid >>= 2; - /* Calc oobsize */ - switch (((extid >> 2) & 0x04) | (extid & 0x03)) { - case 1: - mtd->oobsize = 128; - break; - case 2: - mtd->oobsize = 218; - break; - case 3: - mtd->oobsize = 400; - break; - case 4: - mtd->oobsize = 436; - break; - case 5: - mtd->oobsize = 512; - break; - case 6: - mtd->oobsize = 640; - break; - case 7: - default: /* Other cases are "reserved" (unknown) */ - mtd->oobsize = 1024; - break; - } - extid >>= 2; - /* Calc blocksize */ - mtd->erasesize = (128 * 1024) << - (((extid >> 1) & 0x04) | (extid & 0x03)); - } else if (id_len == 6 && chip->id.data[0] == NAND_MFR_HYNIX && - !nand_is_slc(chip)) { + if (id_len == 6 && chip->id.data[0] == NAND_MFR_HYNIX && + !nand_is_slc(chip)) { unsigned int tmp; /* Calc pagesize */ @@ -4374,13 +4339,10 @@ static void nand_decode_bbm_options(struct mtd_info *mtd, * Micron devices with 2KiB pages and on SLC Samsung, Hynix, Toshiba, * AMD/Spansion, and Macronix. All others scan only the first page. */ - if (!nand_is_slc(chip) && - (maf_id == NAND_MFR_SAMSUNG || -maf_id == NAND_MFR_HYNIX)) + if (!nand_is_slc(chip) && maf_id == NAND_MFR_HYNIX) chip->bbt_options |= NAND_BBT_SCANLASTPAGE; else if ((nand_is_slc(chip) && - (maf_id == NAND_MFR_SAMSUNG || -maf_id == NAND_MFR_HYNIX || + (maf_id == NAND_MFR_HYNIX ||
[PATCH v3 07/13] mtd: nand: Move Hynix specific init/detection logic in nand_hynix.c
From: Michael Trimarchi Upstream linux commit 01389b6bd2f4f7. Move Hynix specific initialization and detection logic into nand_hynix.c. This is part of the "separate vendor specific code from core" cleanup process. Signed-off-by: Michael Trimarchi Signed-off-by: Dario Binacchi --- Changes in v3: - Use commit sha1 with 13 digits. - Add the SPDX-License-Identifier tag. - Fix code style warnings raised by patman. Changes in v2: - Use short-commit form - Remove linux info. Uboot seems that backport without add this extra information. - Adjust the include file in nand_hynix. drivers/mtd/nand/raw/Makefile | 3 +- drivers/mtd/nand/raw/nand_base.c | 117 -- drivers/mtd/nand/raw/nand_hynix.c | 85 ++ drivers/mtd/nand/raw/nand_ids.c | 2 +- include/linux/mtd/rawnand.h | 1 + 5 files changed, 120 insertions(+), 88 deletions(-) create mode 100644 drivers/mtd/nand/raw/nand_hynix.c diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile index 440290bed0fe..86d9b8e8beb8 100644 --- a/drivers/mtd/nand/raw/Makefile +++ b/drivers/mtd/nand/raw/Makefile @@ -14,7 +14,7 @@ obj-$(CONFIG_SPL_NAND_DENALI) += denali_spl.o obj-$(CONFIG_SPL_NAND_SIMPLE) += nand_spl_simple.o obj-$(CONFIG_SPL_NAND_LOAD) += nand_spl_load.o obj-$(CONFIG_SPL_NAND_ECC) += nand_ecc.o -obj-$(CONFIG_SPL_NAND_BASE) += nand_base.o nand_samsung.o +obj-$(CONFIG_SPL_NAND_BASE) += nand_base.o nand_hynix.o nand_samsung.o obj-$(CONFIG_SPL_NAND_IDENT) += nand_ids.o nand_timings.o obj-$(CONFIG_TPL_NAND_INIT) += nand.o ifeq ($(CONFIG_SPL_ENV_SUPPORT),y) @@ -31,6 +31,7 @@ obj-y += nand_ids.o obj-y += nand_util.o obj-y += nand_ecc.o obj-y += nand_base.o +obj-y += nand_hynix.o obj-y += nand_samsung.o obj-y += nand_timings.o diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index fe59157bc3c4..5698c1e6a229 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -4170,85 +4170,34 @@ void nand_decode_ext_id(struct nand_chip *chip) extid = chip->id.data[3]; id_len = chip->id.len; + /* Calc pagesize */ + mtd->writesize = 1024 << (extid & 0x03); + extid >>= 2; + /* Calc oobsize */ + mtd->oobsize = (8 << (extid & 0x01)) * + (mtd->writesize >> 9); + extid >>= 2; + /* Calc blocksize. Blocksize is multiples of 64KiB */ + mtd->erasesize = (64 * 1024) << (extid & 0x03); + extid >>= 2; + /* Get buswidth information */ + /* Get buswidth information */ + if (extid & 0x1) + chip->options |= NAND_BUSWIDTH_16; + /* -* Field definitions are in the following datasheets: -* Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32) -* Hynix MLC (6 byte ID): Hynix H27UBG8T2B (p.22) -* -* Check for ID length, non-zero 6th byte, cell type, and Hynix/Samsung -* ID to decide what to do. +* Toshiba 24nm raw SLC (i.e., not BENAND) have 32B OOB per +* 512B page. For Toshiba SLC, we decode the 5th/6th byte as +* follows: +* - ID byte 6, bits[2:0]: 100b -> 43nm, 101b -> 32nm, +* 110b -> 24nm +* - ID byte 5, bit[7]:1 -> BENAND, 0 -> raw SLC */ - if (id_len == 6 && chip->id.data[0] == NAND_MFR_HYNIX && - !nand_is_slc(chip)) { - unsigned int tmp; - - /* Calc pagesize */ - mtd->writesize = 2048 << (extid & 0x03); - extid >>= 2; - /* Calc oobsize */ - switch (((extid >> 2) & 0x04) | (extid & 0x03)) { - case 0: - mtd->oobsize = 128; - break; - case 1: - mtd->oobsize = 224; - break; - case 2: - mtd->oobsize = 448; - break; - case 3: - mtd->oobsize = 64; - break; - case 4: - mtd->oobsize = 32; - break; - case 5: - mtd->oobsize = 16; - break; - default: - mtd->oobsize = 640; - break; - } - extid >>= 2; - /* Calc blocksize */ - tmp = ((extid >> 1) & 0x04) | (extid & 0x03); - if (tmp < 0x03) - mtd->erasesize = (128 * 1024) << tmp; - else if (tmp == 0x03) - mtd->erasesize = 768 * 1024; - else - mtd->erasesize = (64 * 1024)
[PATCH v3 05/13] mtd: nand: Export symbol nand_decode_ext_id
From: Michael Trimarchi In preparation of moving specific nand support that are not jedec or onfi Signed-off-by: Michael Trimarchi Signed-off-by: Dario Binacchi --- (no changes since v1) drivers/mtd/nand/raw/nand_base.c | 3 ++- include/linux/mtd/rawnand.h | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index 145de22be852..174c760f3416 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -4160,7 +4160,7 @@ static int nand_get_bits_per_cell(u8 cellinfo) * chip. The rest of the parameters must be decoded according to generic or * manufacturer-specific "extended ID" decoding patterns. */ -static void nand_decode_ext_id(struct nand_chip *chip) +void nand_decode_ext_id(struct nand_chip *chip) { struct mtd_info *mtd = &chip->mtd; int extid, id_len; @@ -4286,6 +4286,7 @@ static void nand_decode_ext_id(struct nand_chip *chip) } } +EXPORT_SYMBOL_GPL(nand_decode_ext_id); /* * Manufacturer detection. Only used when the NAND is not ONFI or JEDEC diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h index d8141cb4d114..8fb2a43296f5 100644 --- a/include/linux/mtd/rawnand.h +++ b/include/linux/mtd/rawnand.h @@ -1374,4 +1374,7 @@ int nand_read_data_op(struct nand_chip *chip, void *buf, unsigned int len, int nand_write_data_op(struct nand_chip *chip, const void *buf, unsigned int len, bool force_8bit); +/* Default extended ID decoding function */ +void nand_decode_ext_id(struct nand_chip *chip); + #endif /* __LINUX_MTD_RAWNAND_H */ -- 2.32.0
[PATCH v3 04/13] mtd: nand: Get rid of mtd variable in function calls
From: Michael Trimarchi chip points to mtd. Passing chip is enough to have a reference to mtd when is necessary Signed-off-by: Michael Trimarchi Signed-off-by: Dario Binacchi --- Changes in v3: - Fix code style warnings raised by patman. drivers/mtd/nand/raw/nand_base.c | 25 + include/linux/mtd/rawnand.h | 3 +-- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index 0900e6dbf9a6..145de22be852 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -4160,8 +4160,9 @@ static int nand_get_bits_per_cell(u8 cellinfo) * chip. The rest of the parameters must be decoded according to generic or * manufacturer-specific "extended ID" decoding patterns. */ -static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip) +static void nand_decode_ext_id(struct nand_chip *chip) { + struct mtd_info *mtd = &chip->mtd; int extid, id_len; /* The 3rd id byte holds MLC / multichip data */ chip->bits_per_cell = nand_get_bits_per_cell(chip->id.data[2]); @@ -4291,7 +4292,7 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip) * compliant and does not have a full-id or legacy-id entry in the nand_ids * table. */ -static void nand_manufacturer_detect(struct mtd_info *mtd, struct nand_chip *chip) +static void nand_manufacturer_detect(struct nand_chip *chip) { /* * Try manufacturer detection if available and use @@ -4301,7 +4302,7 @@ static void nand_manufacturer_detect(struct mtd_info *mtd, struct nand_chip *chi chip->manufacturer.desc->ops->detect) chip->manufacturer.desc->ops->detect(chip); else - nand_decode_ext_id(mtd, chip); + nand_decode_ext_id(chip); } /* @@ -4324,9 +4325,9 @@ static int nand_manufacturer_init(struct nand_chip *chip) * decodes a matching ID table entry and assigns the MTD size parameters for * the chip. */ -static void nand_decode_id(struct mtd_info *mtd, struct nand_chip *chip, - struct nand_flash_dev *type) +static void nand_decode_id(struct nand_chip *chip, struct nand_flash_dev *type) { + struct mtd_info *mtd = &chip->mtd; int maf_id = chip->id.data[0]; mtd->erasesize = type->erasesize; @@ -4439,11 +4440,11 @@ static const struct nand_manufacturers *nand_get_manufacturer_desc(u8 id) /* * Get the flash and manufacturer id and lookup if the type is supported. */ -struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, - struct nand_chip *chip, - int *maf_id, int *dev_id, - struct nand_flash_dev *type) +struct nand_flash_dev *nand_get_flash_type(struct nand_chip *chip, int *maf_id, + int *dev_id, + struct nand_flash_dev *type) { + struct mtd_info *mtd = &chip->mtd; const struct nand_manufacturers *manufacturer_desc; int busw, ret; u8 *id_data = chip->id.data; @@ -4539,9 +4540,9 @@ struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, chip->chipsize = (uint64_t)type->chipsize << 20; if (!type->pagesize) { - nand_manufacturer_detect(mtd, chip); + nand_manufacturer_detect(chip); } else { - nand_decode_id(mtd, chip, type); + nand_decode_id(chip, type); } /* Get chip options */ @@ -4729,7 +4730,7 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips, nand_set_defaults(chip, chip->options & NAND_BUSWIDTH_16); /* Read the flash type */ - type = nand_get_flash_type(mtd, chip, &nand_maf_id, + type = nand_get_flash_type(chip, &nand_maf_id, &nand_dev_id, table); if (IS_ERR(type)) { diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h index 57fe7fb47bd8..d8141cb4d114 100644 --- a/include/linux/mtd/rawnand.h +++ b/include/linux/mtd/rawnand.h @@ -29,8 +29,7 @@ struct nand_flash_dev; struct device_node; /* Get the flash and manufacturer id and lookup if the type is supported. */ -struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, - struct nand_chip *chip, +struct nand_flash_dev *nand_get_flash_type(struct nand_chip *chip, int *maf_id, int *dev_id, struct nand_flash_dev *type); -- 2.32.0
[PATCH v3 02/13] mtd: nand: Store nand ID in struct nand_chip
From: Michael Trimarchi Upstream linux commit 7f501f0a72036d. Store the NAND ID in struct nand_chip to avoid passing id_data and id_len as function parameters. Signed-off-by: Michael Trimarchi Signed-off-by: Dario Binacchi --- Changes in v3: - Use commit sha1 with 13 digits. - Fix code style warnings raised by patman. Changes in v2: - Use short-commit form. - Remove linux info. Uboot seems that backport without add this extra information. drivers/mtd/nand/raw/nand_base.c | 58 include/linux/mtd/rawnand.h | 15 + 2 files changed, 44 insertions(+), 29 deletions(-) diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index 9a2194ebd3f8..220804c75c87 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -4160,16 +4160,14 @@ static int nand_get_bits_per_cell(u8 cellinfo) * chip. The rest of the parameters must be decoded according to generic or * manufacturer-specific "extended ID" decoding patterns. */ -static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip, - u8 id_data[8]) +static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip) { int extid, id_len; /* The 3rd id byte holds MLC / multichip data */ - chip->bits_per_cell = nand_get_bits_per_cell(id_data[2]); + chip->bits_per_cell = nand_get_bits_per_cell(chip->id.data[2]); /* The 4th id byte is the important one */ - extid = id_data[3]; - - id_len = nand_id_len(id_data, 8); + extid = chip->id.data[3]; + id_len = chip->id.len; /* * Field definitions are in the following datasheets: @@ -4180,8 +4178,8 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip, * Check for ID length, non-zero 6th byte, cell type, and Hynix/Samsung * ID to decide what to do. */ - if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG && - !nand_is_slc(chip) && id_data[5] != 0x00) { + if (id_len == 6 && chip->id.data[0] == NAND_MFR_SAMSUNG && + !nand_is_slc(chip) && chip->id.data[5] != 0x00) { /* Calc pagesize */ mtd->writesize = 2048 << (extid & 0x03); extid >>= 2; @@ -4214,7 +4212,7 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip, /* Calc blocksize */ mtd->erasesize = (128 * 1024) << (((extid >> 1) & 0x04) | (extid & 0x03)); - } else if (id_len == 6 && id_data[0] == NAND_MFR_HYNIX && + } else if (id_len == 6 && chip->id.data[0] == NAND_MFR_HYNIX && !nand_is_slc(chip)) { unsigned int tmp; @@ -4278,10 +4276,10 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip, * 110b -> 24nm * - ID byte 5, bit[7]:1 -> BENAND, 0 -> raw SLC */ - if (id_len >= 6 && id_data[0] == NAND_MFR_TOSHIBA && - nand_is_slc(chip) && - (id_data[5] & 0x7) == 0x6 /* 24nm */ && - !(id_data[4] & 0x80) /* !BENAND */) { + if (id_len >= 6 && chip->id.data[0] == NAND_MFR_TOSHIBA && + nand_is_slc(chip) && + (chip->id.data[5] & 0x7) == 0x6 /* 24nm */ && + !(chip->id.data[4] & 0x80) /* !BENAND */) { mtd->oobsize = 32 * mtd->writesize >> 9; } @@ -4294,9 +4292,9 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip, * the chip. */ static void nand_decode_id(struct mtd_info *mtd, struct nand_chip *chip, - struct nand_flash_dev *type, u8 id_data[8]) + struct nand_flash_dev *type) { - int maf_id = id_data[0]; + int maf_id = chip->id.data[0]; mtd->erasesize = type->erasesize; mtd->writesize = type->pagesize; @@ -4311,11 +4309,11 @@ static void nand_decode_id(struct mtd_info *mtd, struct nand_chip *chip, * listed in nand_ids table. * Data sheet (5 byte ID): Spansion S30ML-P ORNAND (p.39) */ - if (maf_id == NAND_MFR_AMD && id_data[4] != 0x00 && id_data[5] == 0x00 - && id_data[6] == 0x00 && id_data[7] == 0x00 - && mtd->writesize == 512) { + if (maf_id == NAND_MFR_AMD && chip->id.data[4] != 0x00 && + chip->id.
[PATCH v3 03/13] mtd: nand: Add manufacturer specific initialization/detection steps
From: Michael Trimarchi Upstream linux commit abbe26d144ec22. A lot of NANDs are implementing generic features in a non-generic way, or are providing advanced auto-detection logic where the NAND ID bytes meaning changes with the NAND generation. Providing this vendor specific initialization step will allow us to get rid of full-id entries in the nand_ids table or all the vendor specific cases added over the time in the generic NAND ID decoding logic. Signed-off-by: Michael Trimarchi Signed-off-by: Dario Binacchi --- Changes in v3: - Use commit sha1 with 13 digits. - Fix code style warnings raised by patman. Changes in v2: - Use short-commit form. - Remove linux info. Uboot seems that backport without add this extra information. drivers/mtd/nand/raw/nand_base.c | 98 include/linux/mtd/rawnand.h | 30 ++ 2 files changed, 105 insertions(+), 23 deletions(-) diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index 220804c75c87..0900e6dbf9a6 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -4286,6 +4286,39 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip) } } +/* + * Manufacturer detection. Only used when the NAND is not ONFI or JEDEC + * compliant and does not have a full-id or legacy-id entry in the nand_ids + * table. + */ +static void nand_manufacturer_detect(struct mtd_info *mtd, struct nand_chip *chip) +{ + /* +* Try manufacturer detection if available and use +* nand_decode_ext_id() otherwise. +*/ + if (chip->manufacturer.desc && chip->manufacturer.desc->ops && + chip->manufacturer.desc->ops->detect) + chip->manufacturer.desc->ops->detect(chip); + else + nand_decode_ext_id(mtd, chip); +} + +/* + * Manufacturer initialization. This function is called for all NANDs including + * ONFI and JEDEC compliant ones. + * Manufacturer drivers should put all their specific initialization code in + * their ->init() hook. + */ +static int nand_manufacturer_init(struct nand_chip *chip) +{ + if (!chip->manufacturer.desc || !chip->manufacturer.desc->ops || + !chip->manufacturer.desc->ops->init) + return 0; + + return chip->manufacturer.desc->ops->init(chip); +} + /* * Old devices have chip data hardcoded in the device ID table. nand_decode_id * decodes a matching ID table entry and assigns the MTD size parameters for @@ -4383,6 +4416,26 @@ static bool find_full_id_nand(struct mtd_info *mtd, struct nand_chip *chip, return false; } +/** + * nand_get_manufacturer_desc - Get manufacturer information from the + * manufacturer ID + * @id: manufacturer ID + * + * Returns a nand_manufacturer_desc object if the manufacturer is defined + * in the NAND manufacturers database, NULL otherwise. + */ +static const struct nand_manufacturers *nand_get_manufacturer_desc(u8 id) +{ + int i; + + for (i = 0; nand_manuf_ids[i].id != 0x0; i++) { + if (nand_manuf_ids[i].id == id) + return &nand_manuf_ids[i]; + } + + return NULL; +} + /* * Get the flash and manufacturer id and lookup if the type is supported. */ @@ -4391,8 +,8 @@ struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, int *maf_id, int *dev_id, struct nand_flash_dev *type) { + const struct nand_manufacturers *manufacturer_desc; int busw, ret; - int maf_idx; u8 *id_data = chip->id.data; /* @@ -4433,6 +4486,12 @@ struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, return ERR_PTR(-ENODEV); } + chip->id.len = nand_id_len(id_data, ARRAY_SIZE(chip->id.data)); + + /* Try to identify manufacturer */ + manufacturer_desc = nand_get_manufacturer_desc(*maf_id); + chip->manufacturer.desc = manufacturer_desc; + if (!type) type = nand_flash_ids; @@ -4451,8 +4510,6 @@ struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, */ chip->options &= ~NAND_BUSWIDTH_16; - chip->id.len = nand_id_len(id_data, ARRAY_SIZE(chip->id.data)); - for (; type->name != NULL; type++) { if (is_full_id_nand(type)) { if (find_full_id_nand(mtd, chip, type)) @@ -4482,8 +4539,7 @@ struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, chip->chipsize = (uint64_t)type->chipsize << 20; if (!type->pagesize) { - /* Decode parameters from extended ID */ - nand_decode_ext_id(mtd, chip); + nand_manufacturer_detect(mtd, chip);
[PATCH v3 01/13] mtd: nand: Get rid of busw parameter
From: Michael Trimarchi Upstream linux commit 29a198a1592d83. Auto-detection functions are passed a busw parameter to retrieve the actual NAND bus width and eventually set the correct value in chip->options. Rework the nand_get_flash_type() function to get rid of this extra parameter and let detection code directly set the NAND_BUSWIDTH_16 flag in chip->options if needed. Signed-off-by: Michael Trimarchi Signed-off-by: Dario Binacchi --- Changes in v3: - Use commit sha1 with 13 digits. Changes in v2: - Use short-commit form. - Remove linux info. Uboot seems that backport without add this extra information. drivers/mtd/nand/raw/nand_base.c | 59 +--- 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index e8ece0a4a0dd..9a2194ebd3f8 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -3898,8 +3898,7 @@ static void nand_onfi_detect_micron(struct nand_chip *chip, /* * Check if the NAND chip is ONFI compliant, returns 1 if it is, 0 otherwise. */ -static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, - int *busw) +static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip) { struct nand_onfi_params *p = &chip->onfi_params; char id[4]; @@ -3971,9 +3970,7 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, chip->bits_per_cell = p->bits_per_cell; if (onfi_feature(chip) & ONFI_FEATURE_16_BIT_BUS) - *busw = NAND_BUSWIDTH_16; - else - *busw = 0; + chip->options |= NAND_BUSWIDTH_16; if (p->ecc_bits != 0xff) { chip->ecc_strength_ds = p->ecc_bits; @@ -4003,8 +4000,7 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, return 1; } #else -static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, - int *busw) +static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip) { return 0; } @@ -4013,8 +4009,7 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, /* * Check if the NAND chip is JEDEC compliant, returns 1 if it is, 0 otherwise. */ -static int nand_flash_detect_jedec(struct mtd_info *mtd, struct nand_chip *chip, - int *busw) +static int nand_flash_detect_jedec(struct mtd_info *mtd, struct nand_chip *chip) { struct nand_jedec_params *p = &chip->jedec_params; struct jedec_ecc_info *ecc; @@ -4076,9 +4071,7 @@ static int nand_flash_detect_jedec(struct mtd_info *mtd, struct nand_chip *chip, chip->bits_per_cell = p->bits_per_cell; if (jedec_feature(chip) & JEDEC_FEATURE_16_BIT_BUS) - *busw = NAND_BUSWIDTH_16; - else - *busw = 0; + chip->options |= NAND_BUSWIDTH_16; /* ECC info */ ecc = &p->ecc_info[0]; @@ -4168,7 +4161,7 @@ static int nand_get_bits_per_cell(u8 cellinfo) * manufacturer-specific "extended ID" decoding patterns. */ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip, - u8 id_data[8], int *busw) + u8 id_data[8]) { int extid, id_len; /* The 3rd id byte holds MLC / multichip data */ @@ -4221,7 +4214,6 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip, /* Calc blocksize */ mtd->erasesize = (128 * 1024) << (((extid >> 1) & 0x04) | (extid & 0x03)); - *busw = 0; } else if (id_len == 6 && id_data[0] == NAND_MFR_HYNIX && !nand_is_slc(chip)) { unsigned int tmp; @@ -4262,7 +4254,6 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip, mtd->erasesize = 768 * 1024; else mtd->erasesize = (64 * 1024) << tmp; - *busw = 0; } else { /* Calc pagesize */ mtd->writesize = 1024 << (extid & 0x03); @@ -4275,7 +4266,9 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip, mtd->erasesize = (64 * 1024) << (extid & 0x03); extid >>= 2; /* Get buswidth information */ - *busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0; + /* Get buswidth information */ + if (extid & 0x1) + chip->options |= NAND_BUSWIDTH_16; /* * Toshiba 24nm raw SLC (i.
[PATCH v3 00/13] Port manufacturer specific initialization
In preparation of re-sync of mtd stack, we opt to move the current stack slowly in order to have a more easy sync and test. We would like to prepare uboot to support no-jedec and no-onfi compliant nand so we need to clean up a bit the code we have now and upstream some of the support. In this series we expect no functional change Tested on: - imx6ull Micron MT29F2G08ABAGAH4 - imx8mn Macronix MX30LF4G18AC Changes in v3: - Use commit sha1 with 13 digits. - Use commit sha1 with 13 digits. - Fix code style warnings raised by patman. - Use commit sha1 with 13 digits. - Fix code style warnings raised by patman. - Fix code style warnings raised by patman. - Use commit sha1 with 13 digits. - Fix code style warnings raised by patman. - Add the SPDX-License-Identifier tag. - Use commit sha1 with 13 digits. - Add the SPDX-License-Identifier tag. - Fix code style warnings raised by patman. - Use commit sha1 with 13 digits. - Add the SPDX-License-Identifier tag. - Fix code style warnings raised by patman. - Use commit sha1 with 13 digits. - Add the SPDX-License-Identifier tag. - Fix code style warnings raised by patman. - Use commit sha1 with 13 digits. - Add the SPDX-License-Identifier tag. - Fix code style warnings raised by patman. - Use commit sha1 with 13 digits. - Add the SPDX-License-Identifier tag. - Fix code style warnings raised by patman. - Use commit sha1 with 13 digits. - Use commit sha1 with 13 digits. - Wrap commit description to a maximum of 75 chars. Changes in v2: - Use short-commit form. - Remove linux info. Uboot seems that backport without add this extra information. - Use short-commit form. - Remove linux info. Uboot seems that backport without add this extra information. - Use short-commit form. - Remove linux info. Uboot seems that backport without add this extra information. - Use short-commit form. - Remove linux info. Uboot seems that backport without add this extra information. - Adjust the include file in nand_samsung. - Use short-commit form - Remove linux info. Uboot seems that backport without add this extra information. - Adjust the include file in nand_hynix. - Use short-commit form - Remove linux info. Uboot seems that backport without add this extra information. - Adjust the include file in nand_toshiba. - Use short-commit form - Remove linux info. Uboot seems that backport without add this extra information. - Adjust the include file in nand_micron. - Use short-commit form - Remove linux info. Uboot seems that backport without add this extra information. - Adjust the include file in nand_amd. - Use short-commit form - Remove linux info. Uboot seems that backport without add this extra information. - Adjust the include file in nand_macronix. - Use short-commit form - Remove linux info. Uboot seems that backport without add this extra information. - Use short-commit form. - Remove linux info. Uboot seems that backport without add this extra information. Michael Trimarchi (13): mtd: nand: Get rid of busw parameter mtd: nand: Store nand ID in struct nand_chip mtd: nand: Add manufacturer specific initialization/detection steps mtd: nand: Get rid of mtd variable in function calls mtd: nand: Export symbol nand_decode_ext_id mtd: nand: Move Samsung specific init/detection logic in nand_samsung.c mtd: nand: Move Hynix specific init/detection logic in nand_hynix.c mtd: nand: Move Toshiba specific init/detection logic in nand_toshiba.c mtd: nand: Move Micron specific init logic in nand_micron.c mtd: nand: Move AMD/Spansion specific init/detection logic in nand_amd.c mtd: nand: Move Macronix specific initialization in nand_macronix.c mtd: nand: toshiba: Retrieve ECC requirements from extended ID mtd: decommission the NAND museum drivers/mtd/nand/raw/Makefile| 10 +- drivers/mtd/nand/raw/nand_amd.c | 52 drivers/mtd/nand/raw/nand_base.c | 370 ++- drivers/mtd/nand/raw/nand_hynix.c| 85 ++ drivers/mtd/nand/raw/nand_ids.c | 24 +- drivers/mtd/nand/raw/nand_macronix.c | 31 +++ drivers/mtd/nand/raw/nand_micron.c | 87 +++ drivers/mtd/nand/raw/nand_samsung.c | 90 +++ drivers/mtd/nand/raw/nand_toshiba.c | 79 ++ include/linux/mtd/rawnand.h | 78 -- 10 files changed, 625 insertions(+), 281 deletions(-) create mode 100644 drivers/mtd/nand/raw/nand_amd.c create mode 100644 drivers/mtd/nand/raw/nand_hynix.c create mode 100644 drivers/mtd/nand/raw/nand_macronix.c create mode 100644 drivers/mtd/nand/raw/nand_micron.c create mode 100644 drivers/mtd/nand/raw/nand_samsung.c create mode 100644 drivers/mtd/nand/raw/nand_toshiba.c -- 2.32.0
[PATCH v3 01/13] mtd: nand: Get rid of busw parameter
From: Michael Trimarchi Upstream linux commit 29a198a1592d83. Auto-detection functions are passed a busw parameter to retrieve the actual NAND bus width and eventually set the correct value in chip->options. Rework the nand_get_flash_type() function to get rid of this extra parameter and let detection code directly set the NAND_BUSWIDTH_16 flag in chip->options if needed. Signed-off-by: Michael Trimarchi Signed-off-by: Dario Binacchi --- Changes in v3: - Use commit sha1 with 13 digits. Changes in v2: - Use short-commit form. - Remove linux info. Uboot seems that backport without add this extra information. drivers/mtd/nand/raw/nand_base.c | 59 +--- 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index e8ece0a4a0dd..9a2194ebd3f8 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -3898,8 +3898,7 @@ static void nand_onfi_detect_micron(struct nand_chip *chip, /* * Check if the NAND chip is ONFI compliant, returns 1 if it is, 0 otherwise. */ -static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, - int *busw) +static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip) { struct nand_onfi_params *p = &chip->onfi_params; char id[4]; @@ -3971,9 +3970,7 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, chip->bits_per_cell = p->bits_per_cell; if (onfi_feature(chip) & ONFI_FEATURE_16_BIT_BUS) - *busw = NAND_BUSWIDTH_16; - else - *busw = 0; + chip->options |= NAND_BUSWIDTH_16; if (p->ecc_bits != 0xff) { chip->ecc_strength_ds = p->ecc_bits; @@ -4003,8 +4000,7 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, return 1; } #else -static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, - int *busw) +static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip) { return 0; } @@ -4013,8 +4009,7 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, /* * Check if the NAND chip is JEDEC compliant, returns 1 if it is, 0 otherwise. */ -static int nand_flash_detect_jedec(struct mtd_info *mtd, struct nand_chip *chip, - int *busw) +static int nand_flash_detect_jedec(struct mtd_info *mtd, struct nand_chip *chip) { struct nand_jedec_params *p = &chip->jedec_params; struct jedec_ecc_info *ecc; @@ -4076,9 +4071,7 @@ static int nand_flash_detect_jedec(struct mtd_info *mtd, struct nand_chip *chip, chip->bits_per_cell = p->bits_per_cell; if (jedec_feature(chip) & JEDEC_FEATURE_16_BIT_BUS) - *busw = NAND_BUSWIDTH_16; - else - *busw = 0; + chip->options |= NAND_BUSWIDTH_16; /* ECC info */ ecc = &p->ecc_info[0]; @@ -4168,7 +4161,7 @@ static int nand_get_bits_per_cell(u8 cellinfo) * manufacturer-specific "extended ID" decoding patterns. */ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip, - u8 id_data[8], int *busw) + u8 id_data[8]) { int extid, id_len; /* The 3rd id byte holds MLC / multichip data */ @@ -4221,7 +4214,6 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip, /* Calc blocksize */ mtd->erasesize = (128 * 1024) << (((extid >> 1) & 0x04) | (extid & 0x03)); - *busw = 0; } else if (id_len == 6 && id_data[0] == NAND_MFR_HYNIX && !nand_is_slc(chip)) { unsigned int tmp; @@ -4262,7 +4254,6 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip, mtd->erasesize = 768 * 1024; else mtd->erasesize = (64 * 1024) << tmp; - *busw = 0; } else { /* Calc pagesize */ mtd->writesize = 1024 << (extid & 0x03); @@ -4275,7 +4266,9 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip, mtd->erasesize = (64 * 1024) << (extid & 0x03); extid >>= 2; /* Get buswidth information */ - *busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0; + /* Get buswidth information */ + if (extid & 0x1) + chip->options |= NAND_BUSWIDTH_16; /* * Toshiba 24nm raw SLC (i.
[RESEND PATCH 4/4] configs: imx8mn_bsh_smm_s2: add mtdparts to bootargs
Passing the mtdparts environment variable to the Linux kernel is required to properly mount the UBI rootfs. Co-developed-by: Michael Trimarchi Signed-off-by: Michael Trimarchi Signed-off-by: Dario Binacchi --- include/configs/imx8mn_bsh_smm_s2.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/configs/imx8mn_bsh_smm_s2.h b/include/configs/imx8mn_bsh_smm_s2.h index 1eff8c43701c..d09c2ab01610 100644 --- a/include/configs/imx8mn_bsh_smm_s2.h +++ b/include/configs/imx8mn_bsh_smm_s2.h @@ -18,6 +18,7 @@ "mtdparts=" CONFIG_MTDPARTS_DEFAULT "\0" \ "nandargs=setenv bootargs " \ "${optargs} " \ + "mtdparts=${mtdparts} " \ "root=${nandroot} " \ "rootfstype=${nandrootfstype}\0" \ "nandroot=ubi0:root rw ubi.mtd=nandrootfs\0" \ -- 2.32.0
[RESEND PATCH 3/4] configs: imx8mn_bsh_smm_s2: remove console from bootargs
The Linux kernel device tree already specifies the device to be used for boot console output with a stdout-path property under /chosen. Co-developed-by: Michael Trimarchi Signed-off-by: Michael Trimarchi Signed-off-by: Dario Binacchi --- include/configs/imx8mn_bsh_smm_s2.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/configs/imx8mn_bsh_smm_s2.h b/include/configs/imx8mn_bsh_smm_s2.h index 098f23b206d1..1eff8c43701c 100644 --- a/include/configs/imx8mn_bsh_smm_s2.h +++ b/include/configs/imx8mn_bsh_smm_s2.h @@ -16,7 +16,7 @@ #define NANDARGS \ "mtdids=" CONFIG_MTDIDS_DEFAULT "\0" \ "mtdparts=" CONFIG_MTDPARTS_DEFAULT "\0" \ - "nandargs=setenv bootargs console=${console} " \ + "nandargs=setenv bootargs " \ "${optargs} " \ "root=${nandroot} " \ "rootfstype=${nandrootfstype}\0" \ -- 2.32.0
[RESEND PATCH 2/4] configs: imx8mn_bsh_smm_s2: add UBI commands
imx8mn_bsh_smm_s2 uses ubifs rootfs, UBI commands are required to flash it. Co-developed-by: Michael Trimarchi Signed-off-by: Michael Trimarchi Signed-off-by: Dario Binacchi --- configs/imx8mn_bsh_smm_s2_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/imx8mn_bsh_smm_s2_defconfig b/configs/imx8mn_bsh_smm_s2_defconfig index 08f52e50609b..f8c75a2b237e 100644 --- a/configs/imx8mn_bsh_smm_s2_defconfig +++ b/configs/imx8mn_bsh_smm_s2_defconfig @@ -43,6 +43,7 @@ CONFIG_CMD_USB_MASS_STORAGE=y CONFIG_CMD_MTDPARTS=y CONFIG_MTDIDS_DEFAULT="nand0=gpmi-nand" CONFIG_MTDPARTS_DEFAULT="gpmi-nand:64m(nandboot),16m(nandfit),32m(nandkernel),1m(nanddtb),8m(nandtee),-(nandrootfs)" +CONFIG_CMD_UBI=y CONFIG_OF_CONTROL=y CONFIG_SPL_OF_CONTROL=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y -- 2.32.0
[RESEND PATCH 1/4] configs: imx8mn_bsh_smm_s2: add NAND driver
It allows to boot from NAND. Co-developed-by: Michael Trimarchi Signed-off-by: Michael Trimarchi Signed-off-by: Dario Binacchi --- configs/imx8mn_bsh_smm_s2_defconfig | 5 + 1 file changed, 5 insertions(+) diff --git a/configs/imx8mn_bsh_smm_s2_defconfig b/configs/imx8mn_bsh_smm_s2_defconfig index 49f425300151..08f52e50609b 100644 --- a/configs/imx8mn_bsh_smm_s2_defconfig +++ b/configs/imx8mn_bsh_smm_s2_defconfig @@ -30,8 +30,10 @@ CONFIG_SPL_BOARD_INIT=y CONFIG_SPL_BOOTROM_SUPPORT=y CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x300 +CONFIG_SPL_DMA=y CONFIG_SPL_I2C=y CONFIG_SPL_MTD_SUPPORT=y +CONFIG_SPL_NAND_SUPPORT=y CONFIG_SPL_POWER=y CONFIG_SPL_WATCHDOG=y CONFIG_SYS_PROMPT="> " @@ -65,6 +67,9 @@ CONFIG_SYS_NAND_USE_FLASH_BBT=y CONFIG_NAND_MXS=y CONFIG_NAND_MXS_DT=y CONFIG_SYS_NAND_ONFI_DETECTION=y +CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y +CONFIG_SYS_NAND_U_BOOT_OFFS=0xD8000 +CONFIG_SYS_NAND_U_BOOT_OFFS_REDUND=0x4058000 CONFIG_PHYLIB=y CONFIG_PHY_NXP_TJA11XX=y CONFIG_DM_ETH=y -- 2.32.0
[RESEND PATCH 0/4] imx8mn_bsh_smm_s2: fix NAND booting
The series contains all the patches required by the BSH smm s2 board for booting from NAND and properly mounting the UBI rootfs. Dario Binacchi (4): configs: imx8mn_bsh_smm_s2: add NAND driver configs: imx8mn_bsh_smm_s2: add UBI commands configs: imx8mn_bsh_smm_s2: remove console from bootargs configs: imx8mn_bsh_smm_s2: add mtdparts to bootargs configs/imx8mn_bsh_smm_s2_defconfig | 6 ++ include/configs/imx8mn_bsh_smm_s2.h | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) -- 2.32.0
[PATCH 4/4] configs: imx8mn_bsh_smm_s2: add mtdparts to bootargs
Passing the mtdparts environment variable to the Linux kernel is required to properly mount the UBI rootfs. Co-developed-by: Michael Trimarchi Signed-off-by: Michael Trimarchi Signed-off-by: Dario Binacchi --- include/configs/imx8mn_bsh_smm_s2.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/configs/imx8mn_bsh_smm_s2.h b/include/configs/imx8mn_bsh_smm_s2.h index 1eff8c43701c..d09c2ab01610 100644 --- a/include/configs/imx8mn_bsh_smm_s2.h +++ b/include/configs/imx8mn_bsh_smm_s2.h @@ -18,6 +18,7 @@ "mtdparts=" CONFIG_MTDPARTS_DEFAULT "\0" \ "nandargs=setenv bootargs " \ "${optargs} " \ + "mtdparts=${mtdparts} " \ "root=${nandroot} " \ "rootfstype=${nandrootfstype}\0" \ "nandroot=ubi0:root rw ubi.mtd=nandrootfs\0" \ -- 2.32.0
[PATCH 1/4] configs: imx8mn_bsh_smm_s2: add NAND driver
It allows to boot from NAND. Co-developed-by: Michael Trimarchi Signed-off-by: Michael Trimarchi Signed-off-by: Dario Binacchi --- configs/imx8mn_bsh_smm_s2_defconfig | 5 + 1 file changed, 5 insertions(+) diff --git a/configs/imx8mn_bsh_smm_s2_defconfig b/configs/imx8mn_bsh_smm_s2_defconfig index 49f425300151..08f52e50609b 100644 --- a/configs/imx8mn_bsh_smm_s2_defconfig +++ b/configs/imx8mn_bsh_smm_s2_defconfig @@ -30,8 +30,10 @@ CONFIG_SPL_BOARD_INIT=y CONFIG_SPL_BOOTROM_SUPPORT=y CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x300 +CONFIG_SPL_DMA=y CONFIG_SPL_I2C=y CONFIG_SPL_MTD_SUPPORT=y +CONFIG_SPL_NAND_SUPPORT=y CONFIG_SPL_POWER=y CONFIG_SPL_WATCHDOG=y CONFIG_SYS_PROMPT="> " @@ -65,6 +67,9 @@ CONFIG_SYS_NAND_USE_FLASH_BBT=y CONFIG_NAND_MXS=y CONFIG_NAND_MXS_DT=y CONFIG_SYS_NAND_ONFI_DETECTION=y +CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y +CONFIG_SYS_NAND_U_BOOT_OFFS=0xD8000 +CONFIG_SYS_NAND_U_BOOT_OFFS_REDUND=0x4058000 CONFIG_PHYLIB=y CONFIG_PHY_NXP_TJA11XX=y CONFIG_DM_ETH=y -- 2.32.0
[PATCH 3/4] configs: imx8mn_bsh_smm_s2: remove console from bootargs
The Linux kernel device tree already specifies the device to be used for boot console output with a stdout-path property under /chosen. Co-developed-by: Michael Trimarchi Signed-off-by: Michael Trimarchi Signed-off-by: Dario Binacchi --- include/configs/imx8mn_bsh_smm_s2.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/configs/imx8mn_bsh_smm_s2.h b/include/configs/imx8mn_bsh_smm_s2.h index 098f23b206d1..1eff8c43701c 100644 --- a/include/configs/imx8mn_bsh_smm_s2.h +++ b/include/configs/imx8mn_bsh_smm_s2.h @@ -16,7 +16,7 @@ #define NANDARGS \ "mtdids=" CONFIG_MTDIDS_DEFAULT "\0" \ "mtdparts=" CONFIG_MTDPARTS_DEFAULT "\0" \ - "nandargs=setenv bootargs console=${console} " \ + "nandargs=setenv bootargs " \ "${optargs} " \ "root=${nandroot} " \ "rootfstype=${nandrootfstype}\0" \ -- 2.32.0
[PATCH 2/4] configs: imx8mn_bsh_smm_s2: add UBI commands
imx8mn_bsh_smm_s2 uses ubifs rootfs, UBI commands are required to flash it. Co-developed-by: Michael Trimarchi Signed-off-by: Michael Trimarchi Signed-off-by: Dario Binacchi --- configs/imx8mn_bsh_smm_s2_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/imx8mn_bsh_smm_s2_defconfig b/configs/imx8mn_bsh_smm_s2_defconfig index 08f52e50609b..f8c75a2b237e 100644 --- a/configs/imx8mn_bsh_smm_s2_defconfig +++ b/configs/imx8mn_bsh_smm_s2_defconfig @@ -43,6 +43,7 @@ CONFIG_CMD_USB_MASS_STORAGE=y CONFIG_CMD_MTDPARTS=y CONFIG_MTDIDS_DEFAULT="nand0=gpmi-nand" CONFIG_MTDPARTS_DEFAULT="gpmi-nand:64m(nandboot),16m(nandfit),32m(nandkernel),1m(nanddtb),8m(nandtee),-(nandrootfs)" +CONFIG_CMD_UBI=y CONFIG_OF_CONTROL=y CONFIG_SPL_OF_CONTROL=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y -- 2.32.0
[PATCH 0/4] imx8mn_bsh_smm_s2: fix NAND booting
The series contains all the patches required by the BSH smm s2 board for booting from NAND and properly mounting the UBI rootfs. Dario Binacchi (4): configs: imx8mn_bsh_smm_s2: add NAND driver configs: imx8mn_bsh_smm_s2: add UBI commands configs: imx8mn_bsh_smm_s2: remove console from bootargs configs: imx8mn_bsh_smm_s2: add mtdparts to bootargs configs/imx8mn_bsh_smm_s2_defconfig | 6 ++ include/configs/imx8mn_bsh_smm_s2.h | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) -- 2.32.0
Re: The contradictory nature of spl_nand_fit_read
Hi Sean, > Il 01/04/2022 23:43 Michael Nazzareno Trimarchi > ha scritto: > > > Hi Sean > > On Fri, Apr 1, 2022 at 8:53 PM Sean Anderson wrote: > > > > > > > > On 4/1/22 2:46 PM, Sean Anderson wrote: > > > Hi all, > > > > > > I don't understand how spl_nand_fit_read is supposed to work. This > > > function has been seemingly hacked together by multiple people over the > > > years, and it (presumably) (somehow) works despite mass confusion of > > > units. I tried to do some refactoring, but the contradictions make it > > > very difficult to determine what is a bug and what is intentional. > > > > > > Lets start with the basics. spl_nand_fit_read is used to implement > > > spl_load_info.load. I've reproduced the documentation for this function > > > below: > > > > > >> read() - Read from device > > >> > > >> @load: Information about the load state > > >> @sector: Sector number to read from (each @load->bl_len bytes) > > >> @count: Number of sectors to read > > >> @buf: Buffer to read into > > >> @return number of sectors read, 0 on error > > > > > > In particular, both @sector and @count are in units of load.bl_len. In > > > addition, the return value should be @count on success. > > > > > >> static ulong spl_nand_fit_read(struct spl_load_info *load, ulong offs, > > >> ulong size, void *dst) > > >> { > > >> int err; > > >> #ifdef CONFIG_SYS_NAND_BLOCK_SIZE > > > > > > The following logic was introduced in commit 9f6a14c47f ("spl: fit: > > > nand: fix fit loading in case of bad blocks"). However, at the time it > > > was not guarded by the above ifdef. nand_spl_adjust_offset is not > > > defined for all nand drivers. It is defined for at least mxs, am335x, > > > atmel, and simple. Additionally, some drivers (such as rockchip) > > > implement bad block skipping in nand_spl_load_image. > > > > > > It's not at all clear to me that there is common config which determines > > > whether nand_spl_adjust_offset is implemented. Nevertheless, in commit > > > aa0032f672 ("spl: fit: nand: allow for non-page-aligned elements"), the > > > above directive selects different code if CONFIG_SYS_NAND_BLOCK_SIZE is > > > defined. > > > > > >> ulong sector; > > >> > > >> sector = *(int *)load->priv; > > > > > > This is the offset passed to nand_spl_load_image. This > > > offset is in units of bytes, and is aligned to the block size. However, > > > it is *not* set if CONFIG_SPL_LOAD_IMX_CONTAINER is enabled. Oops. > > > > > >> offs = sector + nand_spl_adjust_offset(sector, offs - sector); > > > > I forgot to mention this, but this also adds sector to offs, but offs > > already includes the sector: > > > > > return spl_load_simple_fit(spl_image, &load, offset / bl_len, header); > > The spl_nand_fit_read was called from info->read that was in units of sectors > count = info->read(info, sector, sectors, fit); > debug("fit read sector %lx, sectors=%d, dst=%p, count=%lu, size=0x%lx\n", > sector, sectors, fit, count, size); > > > load.dev = NULL; > load.priv = &offset; > load.filename = NULL; > load.bl_len = 1; > load.read = spl_nand_fit_read; > > static ulong spl_nand_fit_read(struct spl_load_info *load, ulong offs, >ulong size, void *dst) > { > ulong sector; > int ret; > > sector = *(int *)load->priv; > offs = sector + nand_spl_adjust_offset(sector, offs - sector); > ret = nand_spl_load_image(offs, size, dst); > if (!ret) > return size; > else > return 0; > } > > Sorry it's a bit of time and I think that we are discussing about this > commit at the time was introduced > > Michael > > > > > Which means that we add in sector twice (but with different units!) > > > > > The documentation for this this function is as follows > > > > > >> nand_spl_adjust_offset - Adjust offset from a starting sector > > >> @sector: Address of the sector > > >> @offs: Offset starting from @sector > > >> > > >> If one or more bad blocks are in the address space between @sector > > >> and @sector + @offs, @offs is increased by the NAND block size for > > >> each bad block found. > > > > > > In particular, note that offs is in units of bytes. However, we know > > > from above that at this point in the function, offs is in units of > > > bl_len. Oops. > > > > > >> #else > > >> offs *= load->bl_len; > > >> size *= load->bl_len; > > > > > > This code path adjusts both offs and size to be in units of > > > > *units of bytes > > > > >> #endif > > >> err = nand_spl_load_image(offs, size, dst); > > > > > > So by the time we get here, one code path is in units of bytes, and the > > > other is in units of bl_len. nand_spl_load_image seems to expect bytes > > > (though there is no documentation, so I can't be sure). Which of course > > > begs the question: how did the code introduced in 9f6a14c47f ever work? The commit 9f6a14c47f only added the
Re: [EXT] Re: [PATCH] imx: Revert "imx: mx6ull: fix REFTOP_VBGADJ setting" and fix comments
of REFTOP_VBGADJ from fuse. Your patch, re-introduces non-backward compatibility. Thanks and regards, Dario > Anyway, both NXP manufacturing and SW need to follow the fuse value > definition. > > Best regards, > Ye Li > > > > Michael > > > > > > > > } > > > -- > > > 2.7.4 > > > > > > > -- > > Michael Nazzareno Trimarchi > > Co-Founder & Chief Executive Officer > > M. +39 347 913 2170 > > mich...@amarulasolutions.com > > __ > > > > Amarula Solutions BV > > Joop Geesinkweg 125, 1114 AB, Amsterdam, NL > > T. +31 (0)85 111 9172 > > i...@amarulasolutions.com > > https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww. > > amarulasolutions.com%2F&data=04%7C01%7Cye.li%40nxp.com%7C18373707 > > 3bca4b167e1808da0334d5fc%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7 > > C637825822708088241%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQI > > joiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=jZ0z1fFhG9 > > %2BmQ7pB94C4RPEEwCg2IxMvhRluxs7HcQc%3D&reserved=0 -- Dario Binacchi Embedded Linux Developer dario.binac...@amarulasolutions.com __ Amarula Solutions SRL Via Le Canevare 30, 31100 Treviso, Veneto, IT T. +39 042 243 5310 i...@amarulasolutions.com www.amarulasolutions.com
[RESEND PATCH 2/2] mx6: crm_regs: drop BM_ANADIG_ANA_MISC0_REFTOP_VBGADJ
Commit 97c16dc8bf098 ("imx: mx6ull: update the REFTOP_VBGADJ setting") made this macro unused. Then remove it. Signed-off-by: Dario Binacchi --- arch/arm/include/asm/arch-mx6/crm_regs.h | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/include/asm/arch-mx6/crm_regs.h b/arch/arm/include/asm/arch-mx6/crm_regs.h index 4174f244afa1..2a2b8dd806b7 100644 --- a/arch/arm/include/asm/arch-mx6/crm_regs.h +++ b/arch/arm/include/asm/arch-mx6/crm_regs.h @@ -1291,7 +1291,6 @@ struct mxc_ccm_reg { (((v) << 0) & BM_ANADIG_PFD_528_PFD0_FRAC) #define BM_ANADIG_ANA_MISC0_REFTOP_SELBIASOFF 0x0008 -#define BM_ANADIG_ANA_MISC0_REFTOP_VBGADJ 0x60 #define BM_ANADIG_ANA_MISC0_REFTOP_VBGADJ_SHIFT 4 #define BM_PMU_MISC2_AUDIO_DIV_MSB (1 << 23) -- 2.32.0
[RESEND PATCH 1/2] imx: mx6ull: fix REFTOP_VBGADJ setting
The previous code wrote the contents of the fuse as is in the REFTOP_VBGADJ[2:0], but this was wrong if you consider the contents of the table in the code comment. This table is also different from the table in the commit description. But then, which of the two is correct? If it is assumed that an unprogrammed fuse has a value of 0 then for backward compatibility of the code REFTOP_VBGADJ[2:0] must be set to 6 (b'110). Therefore, the table in the code comment can be considered correct as well as this patch. Fixes: 97c16dc8bf098 ("imx: mx6ull: update the REFTOP_VBGADJ setting") Signed-off-by: Dario Binacchi --- arch/arm/mach-imx/mx6/soc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-imx/mx6/soc.c b/arch/arm/mach-imx/mx6/soc.c index aacfc854a2f8..099cb5b12d77 100644 --- a/arch/arm/mach-imx/mx6/soc.c +++ b/arch/arm/mach-imx/mx6/soc.c @@ -366,11 +366,13 @@ static void init_bandgap(void) * 111 - set REFTOP_VBGADJ[2:0] to 3b'111, */ if (is_mx6ull()) { + static const u32 map[] = {6, 1, 2, 3, 4, 5, 0, 7}; + val = readl(&fuse->mem0); val >>= OCOTP_MEM0_REFTOP_TRIM_SHIFT; val &= 0x7; - writel(val << BM_ANADIG_ANA_MISC0_REFTOP_VBGADJ_SHIFT, + writel(map[val] << BM_ANADIG_ANA_MISC0_REFTOP_VBGADJ_SHIFT, &anatop->ana_misc0_set); } } -- 2.32.0
[PATCH 2/2] mx6: crm_regs: drop BM_ANADIG_ANA_MISC0_REFTOP_VBGADJ
Commit 97c16dc8bf098 ("imx: mx6ull: update the REFTOP_VBGADJ setting") made this macro unused. Then remove it. Signed-off-by: Dario Binacchi --- arch/arm/include/asm/arch-mx6/crm_regs.h | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/include/asm/arch-mx6/crm_regs.h b/arch/arm/include/asm/arch-mx6/crm_regs.h index 4174f244afa1..2a2b8dd806b7 100644 --- a/arch/arm/include/asm/arch-mx6/crm_regs.h +++ b/arch/arm/include/asm/arch-mx6/crm_regs.h @@ -1291,7 +1291,6 @@ struct mxc_ccm_reg { (((v) << 0) & BM_ANADIG_PFD_528_PFD0_FRAC) #define BM_ANADIG_ANA_MISC0_REFTOP_SELBIASOFF 0x0008 -#define BM_ANADIG_ANA_MISC0_REFTOP_VBGADJ 0x60 #define BM_ANADIG_ANA_MISC0_REFTOP_VBGADJ_SHIFT 4 #define BM_PMU_MISC2_AUDIO_DIV_MSB (1 << 23) -- 2.32.0
[PATCH 1/2] imx: mx6ull: fix REFTOP_VBGADJ setting
The previous code wrote the contents of the fuse as is in the REFTOP_VBGADJ[2:0], but this was wrong if you consider the contents of the table in the code comment. This table is also different from the table in the commit description. But then, which of the two is correct? If it is assumed that an unprogrammed fuse has a value of 0 then for backward compatibility of the code REFTOP_VBGADJ[2:0] must be set to 6 (b'110). Therefore, the table in the code comment can be considered correct as well as this patch. Fixes: 97c16dc8bf098 ("imx: mx6ull: update the REFTOP_VBGADJ setting") Signed-off-by: Dario Binacchi --- arch/arm/mach-imx/mx6/soc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-imx/mx6/soc.c b/arch/arm/mach-imx/mx6/soc.c index aacfc854a2f8..099cb5b12d77 100644 --- a/arch/arm/mach-imx/mx6/soc.c +++ b/arch/arm/mach-imx/mx6/soc.c @@ -366,11 +366,13 @@ static void init_bandgap(void) * 111 - set REFTOP_VBGADJ[2:0] to 3b'111, */ if (is_mx6ull()) { + static const u32 map[] = {6, 1, 2, 3, 4, 5, 0, 7}; + val = readl(&fuse->mem0); val >>= OCOTP_MEM0_REFTOP_TRIM_SHIFT; val &= 0x7; - writel(val << BM_ANADIG_ANA_MISC0_REFTOP_VBGADJ_SHIFT, + writel(map[val] << BM_ANADIG_ANA_MISC0_REFTOP_VBGADJ_SHIFT, &anatop->ana_misc0_set); } } -- 2.32.0
Re: Re : Re: Commit 76c2ff3e broke backlight on Chromebook snow
Hi Guillaume, > Il 22/10/2021 14:34 Guillaume GARDET ha scritto: > > > Hi Dario, > > ----- Dario Binacchi a écrit : > > Hi Guillaume, > > > > > Il 21/10/2021 16:47 Guillaume GARDET ha > > > scritto: > > > > > > > > > Hi, > > > > > > Commit 76c2ff3e [0] broke backlight on Chromebook snow. > > > A revert on top of 2021.10 restores the backlight. > > > Not sure why it breaks on Chromebook snow yet. Dario, any idea how to fix > > > this? > > > > Is it possible that max_level is equal to min_level and therefore division > > by zero is done? > > I do not think so, because u-boot does not crash and the DTS file has > multiple levels: > https://source.denx.de/u-boot/u-boot/-/blob/master/arch/arm/dts/exynos5250-snow.dts#L243 > > I think the problem occurs when 'cur_level == max_level', which is also the > default value in the DTS. > If I change the default-brightness-level to 6 (instead of 7), then the > backlight works again, which would confirm the assumption above. I have set the default-brightness-level to max-level on my beaglebone board but the backlight works the same. I didn't see any difference. Thanks and regards Dario > pwm_backlight_set_brightness seems to set cur_level to max value by default. > Maybe the driver thinks there is nothing to do, since current level is also > the desired level? > > > Cheers, > Guillaume > > > > > > Thanks and regards, > > Dario > > > > > > Cheers, > > > Guillaume
Re: Commit 76c2ff3e broke backlight on Chromebook snow
Hi Guillaume, > Il 21/10/2021 16:47 Guillaume GARDET ha scritto: > > > Hi, > > Commit 76c2ff3e [0] broke backlight on Chromebook snow. > A revert on top of 2021.10 restores the backlight. > Not sure why it breaks on Chromebook snow yet. Dario, any idea how to fix > this? Is it possible that max_level is equal to min_level and therefore division by zero is done? Thanks and regards, Dario > > Cheers, > Guillaume
[PATCH 3/3] clk: ti: add am33xx/am43xx spread spectrum clock support
The patch enables spread spectrum clocking (SSC) for MPU and LCD PLLs. As reported by the TI spruh73x/spruhl7x RM, SSC is only supported for the DISP/LCD and MPU PLLs on am33xx/am43xx. SSC is not supported for DDR, PER, and CORE PLLs. Calculating the required values and setting the registers accordingly was taken from the set_mpu_spreadspectrum routine contained in the arch/arm/mach-omap2/am33xx/clock_am33xx.c file of the u-boot project. In locked condition, DPLL output clock = CLKINP *[M/N]. In case of SSC enabled, the reference manual explains that there is a restriction of range of M values. Since the clk_ti_am3_dpll_round_rate() attempts to select the minimum possible N, the value of M obtained is not guaranteed to be within the range required. With the new "ti,min-div" parameter it is possible to increase N and consequently M to satisfy the constraint imposed by SSC. Link: https://lore.kernel.org/r/20210606202253.31649-6-dario...@libero.it Signed-off-by: Dario Binacchi --- arch/arm/include/asm/arch-am33xx/clock.h | 12 +++ drivers/clk/ti/clk-am3-dpll.c| 131 ++- 2 files changed, 140 insertions(+), 3 deletions(-) diff --git a/arch/arm/include/asm/arch-am33xx/clock.h b/arch/arm/include/asm/arch-am33xx/clock.h index 5d775902bb..79e3b8c7d9 100644 --- a/arch/arm/include/asm/arch-am33xx/clock.h +++ b/arch/arm/include/asm/arch-am33xx/clock.h @@ -78,6 +78,18 @@ #define CM_CLKSEL_DPLL_N_SHIFT 0 #define CM_CLKSEL_DPLL_N_MASK 0x7F +/* CM_SSC_DELTAM_DPLL */ +#define CM_SSC_DELTAM_DPLL_FRAC_SHIFT 0 +#define CM_SSC_DELTAM_DPLL_FRAC_MASK GENMASK(17, 0) +#define CM_SSC_DELTAM_DPLL_INT_SHIFT 18 +#define CM_SSC_DELTAM_DPLL_INT_MASKGENMASK(19, 18) + +/* CM_SSC_MODFREQ_DPLL */ +#define CM_SSC_MODFREQ_DPLL_MANT_SHIFT 0 +#define CM_SSC_MODFREQ_DPLL_MANT_MASK GENMASK(6, 0) +#define CM_SSC_MODFREQ_DPLL_EXP_SHIFT 7 +#define CM_SSC_MODFREQ_DPLL_EXP_MASK GENMASK(10, 8) + struct dpll_params { u32 m; u32 n; diff --git a/drivers/clk/ti/clk-am3-dpll.c b/drivers/clk/ti/clk-am3-dpll.c index 916d308034..398a011a5c 100644 --- a/drivers/clk/ti/clk-am3-dpll.c +++ b/drivers/clk/ti/clk-am3-dpll.c @@ -27,11 +27,17 @@ struct clk_ti_am3_dpll_priv { struct clk_ti_reg clkmode_reg; struct clk_ti_reg idlest_reg; struct clk_ti_reg clksel_reg; + struct clk_ti_reg ssc_deltam_reg; + struct clk_ti_reg ssc_modfreq_reg; struct clk clk_bypass; struct clk clk_ref; u16 last_rounded_mult; u8 last_rounded_div; + u8 min_div; ulong max_rate; + u32 ssc_modfreq; + u32 ssc_deltam; + bool ssc_downspread; }; static ulong clk_ti_am3_dpll_round_rate(struct clk *clk, ulong rate) @@ -51,7 +57,7 @@ static ulong clk_ti_am3_dpll_round_rate(struct clk *clk, ulong rate) err = rate; err_min = rate; ref_rate = clk_get_rate(&priv->clk_ref); - for (d = 1; err_min && d <= 128; d++) { + for (d = priv->min_div; err_min && d <= 128; d++) { for (m = 2; m <= 2047; m++) { r = (ref_rate * m) / d; err = abs(r - rate); @@ -71,8 +77,8 @@ static ulong clk_ti_am3_dpll_round_rate(struct clk *clk, ulong rate) priv->last_rounded_mult = mult; priv->last_rounded_div = div; - dev_dbg(clk->dev, "rate=%ld, best_rate=%ld, mult=%d, div=%d\n", rate, - ret, mult, div); + dev_dbg(clk->dev, "rate=%ld, min-div: %d, best_rate=%ld, mult=%d, div=%d\n", + rate, priv->min_div, ret, mult, div); return ret; } @@ -107,6 +113,96 @@ static int clk_ti_am3_dpll_state(struct clk *clk, u8 state) return 0; } +/** + * clk_ti_am3_dpll_ssc_program - set spread-spectrum clocking registers + * @clk: struct clk * of DPLL to set + * + * Enable the DPLL spread spectrum clocking if frequency modulation and + * frequency spreading have been set, otherwise disable it. + */ +static void clk_ti_am3_dpll_ssc_program(struct clk *clk) +{ + struct clk_ti_am3_dpll_priv *priv = dev_get_priv(clk->dev); + unsigned long ref_rate; + u32 v, ctrl, mod_freq_divider, exponent, mantissa; + u32 deltam_step, deltam_ceil; + + ctrl = clk_ti_readl(&priv->clkmode_reg); + + if (priv->ssc_modfreq && priv->ssc_deltam) { + ctrl |= CM_CLKMODE_DPLL_SSC_EN_MASK; + + if (priv->ssc_downspread) + ctrl |= CM_CLKMODE_DPLL_SSC_DOWNSPREAD_MASK; + else + ctrl &= ~CM_CLKMODE_DPLL_SSC_DOWNSPREAD_MASK; + + ref_rate = clk_get_rate(&priv->clk_ref); + mod_freq_divider = + (ref_rate / priv->last_rounded_div) / (4
[PATCH 2/3] ARM: dts: am43xx-clocks: add spread spectrum support
Registers for adjusting the spread spectrum clocking (SSC) have been added. As reported by the TI spruhl7x RM, SSC is supported only for LCD and MPU PLLs, but the PRCM_CM_SSC_DELTAMSTEP_DPLL_XXX and PRCM_CM_SSC_MODFREQDIV_DPLL_XXX registers, as well as the enable field in the PRCM_CM_CLKMODE_DPLL_XXX registers are mapped for all PLLs (CORE, MPU, DDR, PER, DISP, EXTDEV). Link: https://lore.kernel.org/r/20210606202253.31649-5-dario...@libero.it Signed-off-by: Dario Binacchi --- arch/arm/dts/am43xx-clocks.dtsi | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm/dts/am43xx-clocks.dtsi b/arch/arm/dts/am43xx-clocks.dtsi index d0c0dfa4ec..b1127b5b91 100644 --- a/arch/arm/dts/am43xx-clocks.dtsi +++ b/arch/arm/dts/am43xx-clocks.dtsi @@ -199,7 +199,7 @@ #clock-cells = <0>; compatible = "ti,am3-dpll-core-clock"; clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; - reg = <0x2d20>, <0x2d24>, <0x2d2c>; + reg = <0x2d20>, <0x2d24>, <0x2d2c>, <0x2d48>, <0x2d4c>; }; dpll_core_x2_ck: dpll_core_x2_ck { @@ -245,7 +245,7 @@ #clock-cells = <0>; compatible = "ti,am3-dpll-clock"; clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; - reg = <0x2d60>, <0x2d64>, <0x2d6c>; + reg = <0x2d60>, <0x2d64>, <0x2d6c>, <0x2d88>, <0x2d8c>; }; dpll_mpu_m2_ck: dpll_mpu_m2_ck { @@ -263,7 +263,7 @@ #clock-cells = <0>; compatible = "ti,am3-dpll-clock"; clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; - reg = <0x2da0>, <0x2da4>, <0x2dac>; + reg = <0x2da0>, <0x2da4>, <0x2dac>, <0x2dc8>, <0x2dcc>; }; dpll_ddr_m2_ck: dpll_ddr_m2_ck { @@ -281,7 +281,7 @@ #clock-cells = <0>; compatible = "ti,am3-dpll-clock"; clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; - reg = <0x2e20>, <0x2e24>, <0x2e2c>; + reg = <0x2e20>, <0x2e24>, <0x2e2c>, <0x2e48>, <0x2e4c>; }; dpll_disp_m2_ck: dpll_disp_m2_ck { @@ -300,7 +300,7 @@ #clock-cells = <0>; compatible = "ti,am3-dpll-j-type-clock"; clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; - reg = <0x2de0>, <0x2de4>, <0x2dec>; + reg = <0x2de0>, <0x2de4>, <0x2dec>, <0x2e08>, <0x2e0c>; }; dpll_per_m2_ck: dpll_per_m2_ck { @@ -583,7 +583,7 @@ #clock-cells = <0>; compatible = "ti,am3-dpll-clock"; clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; - reg = <0x2e60>, <0x2e64>, <0x2e6c>; + reg = <0x2e60>, <0x2e64>, <0x2e6c>, <0x2e88>, <0x2e8c>; }; dpll_extdev_m2_ck: dpll_extdev_m2_ck { -- 2.17.1
[PATCH 1/3] ARM: dts: am33xx-clocks: add spread spectrum support
Registers for adjusting the spread spectrum clocking (SSC) have been added. As reported by the TI spruh73x RM, SSC is supported only for LCD and MPU PLLs, but the CM_SSC_DELTAMSTEP_DPLL_XXX and CM_SSC_MODFREQDIV_DPLL_XXX registers, as well as the enable field in the CM_CLKMODE_DPLL_XXX registers are mapped for all PLLs (CORE, MPU, DDR, PER, DISP). Link: https://lore.kernel.org/r/20210606202253.31649-4-dario...@libero.it Signed-off-by: Dario Binacchi --- arch/arm/dts/am33xx-clocks.dtsi | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/arm/dts/am33xx-clocks.dtsi b/arch/arm/dts/am33xx-clocks.dtsi index 9221824390..44b6268ae3 100644 --- a/arch/arm/dts/am33xx-clocks.dtsi +++ b/arch/arm/dts/am33xx-clocks.dtsi @@ -167,7 +167,7 @@ #clock-cells = <0>; compatible = "ti,am3-dpll-core-clock"; clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; - reg = <0x0490>, <0x045c>, <0x0468>; + reg = <0x0490>, <0x045c>, <0x0468>, <0x0460>, <0x0464>; }; dpll_core_x2_ck: dpll_core_x2_ck { @@ -207,7 +207,7 @@ #clock-cells = <0>; compatible = "ti,am3-dpll-clock"; clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; - reg = <0x0488>, <0x0420>, <0x042c>; + reg = <0x0488>, <0x0420>, <0x042c>, <0x0424>, <0x0428>; }; dpll_mpu_m2_ck: dpll_mpu_m2_ck@4a8 { @@ -223,7 +223,7 @@ #clock-cells = <0>; compatible = "ti,am3-dpll-no-gate-clock"; clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; - reg = <0x0494>, <0x0434>, <0x0440>; + reg = <0x0494>, <0x0434>, <0x0440>, <0x0438>, <0x043c>; }; dpll_ddr_m2_ck: dpll_ddr_m2_ck@4a0 { @@ -247,7 +247,7 @@ #clock-cells = <0>; compatible = "ti,am3-dpll-no-gate-clock"; clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; - reg = <0x0498>, <0x0448>, <0x0454>; + reg = <0x0498>, <0x0448>, <0x0454>, <0x044c>, <0x0450>; }; dpll_disp_m2_ck: dpll_disp_m2_ck@4a4 { @@ -264,7 +264,7 @@ #clock-cells = <0>; compatible = "ti,am3-dpll-no-gate-j-type-clock"; clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; - reg = <0x048c>, <0x0470>, <0x049c>; + reg = <0x048c>, <0x0470>, <0x049c>, <0x0474>, <0x0478>; }; dpll_per_m2_ck: dpll_per_m2_ck@4ac { -- 2.17.1
[PATCH 0/3] Add am33xx/am43xx spread spectrum clock support
The series is a porting to U-boot of a series previously merged in the Linux kernel: 0899431f95a7 ("clk: ti: add am33xx/am43xx spread spectrum clock support") 2fdf0b888eba ("ARM: dts: am43xx-clocks: add spread spectrum support") a543293391ad ("ARM: dts: am33xx-clocks: add spread spectrum support") Dario Binacchi (3): ARM: dts: am33xx-clocks: add spread spectrum support ARM: dts: am43xx-clocks: add spread spectrum support clk: ti: add am33xx/am43xx spread spectrum clock support arch/arm/dts/am33xx-clocks.dtsi | 10 +- arch/arm/dts/am43xx-clocks.dtsi | 12 +-- arch/arm/include/asm/arch-am33xx/clock.h | 12 +++ drivers/clk/ti/clk-am3-dpll.c| 131 ++- 4 files changed, 151 insertions(+), 14 deletions(-) -- 2.17.1
[PATCH v2 7/8] rtc: davinci: add driver model support
Update the driver to support the device tree and the driver model. The read / write helpers in rtc_ops allow access to scratch registers only. The offset parameter is added to the address of the scratch0 register. Support for non-DM has been removed as there were no users. Signed-off-by: Dario Binacchi --- Changes in v2: - Use consistent naming (omap_rtc_. - Remove non-DM support. It's no more used. drivers/rtc/davinci.c | 428 -- 1 file changed, 367 insertions(+), 61 deletions(-) diff --git a/drivers/rtc/davinci.c b/drivers/rtc/davinci.c index 82e5eb3b43..21e5234477 100644 --- a/drivers/rtc/davinci.c +++ b/drivers/rtc/davinci.c @@ -2,127 +2,433 @@ /* * (C) Copyright 2011 DENX Software Engineering GmbH * Heiko Schocher + * Copyright (C) 2021 Dario Binacchi */ #include #include +#include +#include #include #include #include -#include -#include +#include #include -#if !defined(RTC_BASE) && defined(DAVINCI_RTC_BASE) -#define RTC_BASE DAVINCI_RTC_BASE -#endif +/* RTC registers */ +#define OMAP_RTC_SECONDS_REG 0x00 +#define OMAP_RTC_MINUTES_REG 0x04 +#define OMAP_RTC_HOURS_REG 0x08 +#define OMAP_RTC_DAYS_REG 0x0C +#define OMAP_RTC_MONTHS_REG0x10 +#define OMAP_RTC_YEARS_REG 0x14 +#define OMAP_RTC_WEEKS_REG 0x18 -static void davinci_rtc_lock(struct davinci_rtc *rtc) +#define OMAP_RTC_CTRL_REG 0x40 +#define OMAP_RTC_STATUS_REG0x44 +#define OMAP_RTC_INTERRUPTS_REG0x48 + +#define OMAP_RTC_OSC_REG 0x54 + +#define OMAP_RTC_SCRATCH0_REG 0x60 +#define OMAP_RTC_SCRATCH1_REG 0x64 +#define OMAP_RTC_SCRATCH2_REG 0x68 + +#define OMAP_RTC_KICK0_REG 0x6c +#define OMAP_RTC_KICK1_REG 0x70 + +#define OMAP_RTC_PMIC_REG 0x98 + +/* OMAP_RTC_CTRL_REG bit fields: */ +#define OMAP_RTC_CTRL_SPLITBIT(7) +#define OMAP_RTC_CTRL_DISABLE BIT(6) +#define OMAP_RTC_CTRL_SET_32_COUNTER BIT(5) +#define OMAP_RTC_CTRL_TEST BIT(4) +#define OMAP_RTC_CTRL_MODE_12_24 BIT(3) +#define OMAP_RTC_CTRL_AUTO_COMPBIT(2) +#define OMAP_RTC_CTRL_ROUND_30SBIT(1) +#define OMAP_RTC_CTRL_STOP BIT(0) + +/* OMAP_RTC_STATUS_REG bit fields */ +#define OMAP_RTC_STATUS_POWER_UP BIT(7) +#define OMAP_RTC_STATUS_ALARM2 BIT(7) +#define OMAP_RTC_STATUS_ALARM BIT(6) +#define OMAP_RTC_STATUS_1D_EVENT BIT(5) +#define OMAP_RTC_STATUS_1H_EVENT BIT(4) +#define OMAP_RTC_STATUS_1M_EVENT BIT(3) +#define OMAP_RTC_STATUS_1S_EVENT BIT(2) +#define OMAP_RTC_STATUS_RUNBIT(1) +#define OMAP_RTC_STATUS_BUSY BIT(0) + +/* OMAP_RTC_OSC_REG bit fields */ +#define OMAP_RTC_OSC_32KCLK_EN BIT(6) +#define OMAP_RTC_OSC_SEL_32KCLK_SRCBIT(3) +#define OMAP_RTC_OSC_OSC32K_GZ_DISABLE BIT(4) + +/* OMAP_RTC_KICKER values */ +#defineOMAP_RTC_KICK0_VALUE0x83e70b13 +#defineOMAP_RTC_KICK1_VALUE0x95a4f1e0 + +struct omap_rtc_device_type { + bool has_32kclk_en; + bool has_irqwakeen; + bool has_pmic_mode; + bool has_power_up_reset; +}; + +struct omap_rtc_priv { + fdt_addr_t base; + u8 max_reg; + struct udevice *dev; + struct clk clk; + bool has_ext_clk; + const struct omap_rtc_device_type *type; +}; + +static inline u8 omap_rtc_readb(struct omap_rtc_priv *priv, unsigned int reg) +{ + return readb(priv->base + reg); +} + +static inline u32 omap_rtc_readl(struct omap_rtc_priv *priv, unsigned int reg) +{ + return readl(priv->base + reg); +} + +static inline void omap_rtc_writeb(struct omap_rtc_priv *priv, unsigned int reg, + u8 val) +{ + writeb(val, priv->base + reg); +} + +static inline void omap_rtc_writel(struct omap_rtc_priv *priv, unsigned int reg, + u32 val) +{ + writel(val, priv->base + reg); +} + +static inline void omap_rtc_unlock(struct omap_rtc_priv *priv) { - writel(0, &rtc->kick0r); - writel(0, &rtc->kick1r); + omap_rtc_writel(priv, OMAP_RTC_KICK0_REG, OMAP_RTC_KICK0_VALUE); + omap_rtc_writel(priv, OMAP_RTC_KICK1_REG, OMAP_RTC_KICK1_VALUE); } -static void davinci_rtc_unlock(struct davinci_rtc *rtc) +static inline void omap_rtc_lock(struct omap_rtc_priv *priv) { - writel(RTC_KICK0R_WE, &rtc->kick0r); - writel(RTC_KICK1R_WE, &rtc->kick1r); + omap_rtc_writel(priv, OMAP_RTC_KICK0_REG, 0); + omap_rtc_writel(priv, OMAP_RTC_KICK1_REG, 0); } -static int davinci_rtc_wait_not_busy(struct davinci_rtc *rtc) +static int omap_rtc_wait_not_busy(struct omap_rtc_priv *priv) { int count; u8 status; - status = readb(&rtc->status); - if ((status & RTC_STA
[PATCH v2 8/8] rtc: davinci: fix date loaded on reset
On reset, the RTC loads the 2000-01-01 date with a wrong day of the week (Sunday instead of Saturday). Signed-off-by: Dario Binacchi --- (no changes since v1) drivers/rtc/davinci.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/drivers/rtc/davinci.c b/drivers/rtc/davinci.c index 21e5234477..c7ce41bbf5 100644 --- a/drivers/rtc/davinci.c +++ b/drivers/rtc/davinci.c @@ -290,6 +290,7 @@ static int omap_rtc_remove(struct udevice *dev) static int omap_rtc_probe(struct udevice *dev) { struct omap_rtc_priv *priv = dev_get_priv(dev); + struct rtc_time tm; u8 reg, mask, new_ctrl; priv->dev = dev; @@ -380,6 +381,15 @@ static int omap_rtc_probe(struct udevice *dev) } omap_rtc_lock(priv); + + if (omap_rtc_get(dev, &tm)) { + dev_err(dev, "failed to get datetime\n"); + } else if (tm.tm_year == 2000 && tm.tm_mon == 1 && tm.tm_mday == 1 && + tm.tm_wday == 0) { + tm.tm_wday = 6; + omap_rtc_set(dev, &tm); + } + return 0; } -- 2.17.1
[PATCH v2 4/8] rtc: davinci: check BUSY bit before set TC registers
To write correct data to the TC registers, the STATUS register must be read until the BUSY bit is equal to zero. Once the BUSY flag is zero, there is a 15 μs access period in which the TC registers can be programmed. The rtc_wait_not_busy() has been inspired by the Kernel. Signed-off-by: Dario Binacchi --- (no changes since v1) drivers/rtc/davinci.c | 45 ++- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/drivers/rtc/davinci.c b/drivers/rtc/davinci.c index 99ae31e2a5..7b8c729f3b 100644 --- a/drivers/rtc/davinci.c +++ b/drivers/rtc/davinci.c @@ -16,19 +16,39 @@ #define RTC_BASE DAVINCI_RTC_BASE #endif -int rtc_get(struct rtc_time *tmp) +static int davinci_rtc_wait_not_busy(struct davinci_rtc *rtc) { - struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE; - unsigned long sec, min, hour, mday, wday, mon_cent, year; - unsigned long status; + int count; + u8 status; status = readb(&rtc->status); if ((status & RTC_STATE_RUN) != RTC_STATE_RUN) { printf("RTC doesn't run\n"); return -1; } - if ((status & RTC_STATE_BUSY) == RTC_STATE_BUSY) - udelay(20); + + /* BUSY may stay active for 1/32768 second (~30 usec) */ + for (count = 0; count < 50; count++) { + if (!(status & RTC_STATE_BUSY)) + break; + + udelay(1); + status = readb(&rtc->status); + } + + /* now we have ~15 usec to read/write various registers */ + return 0; +} + +int rtc_get(struct rtc_time *tmp) +{ + struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE; + unsigned long sec, min, hour, mday, wday, mon_cent, year; + int ret; + + ret = davinci_rtc_wait_not_busy(rtc); + if (ret) + return ret; sec = readb(&rtc->second); min = readb(&rtc->minutes); @@ -63,10 +83,12 @@ int rtc_get(struct rtc_time *tmp) int rtc_set(struct rtc_time *tmp) { struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE; + int ret; + + ret = davinci_rtc_wait_not_busy(rtc); + if (ret) + return ret; - debug("Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", - tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, - tmp->tm_hour, tmp->tm_min, tmp->tm_sec); writeb(bin2bcd(tmp->tm_year % 100), &rtc->year); writeb(bin2bcd(tmp->tm_mon), &rtc->month); @@ -75,6 +97,11 @@ int rtc_set(struct rtc_time *tmp) writeb(bin2bcd(tmp->tm_hour), &rtc->hours); writeb(bin2bcd(tmp->tm_min), &rtc->minutes); writeb(bin2bcd(tmp->tm_sec), &rtc->second); + + debug("Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", + tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, + tmp->tm_hour, tmp->tm_min, tmp->tm_sec); + return 0; } -- 2.17.1
[PATCH v2 5/8] rtc: davinci: use unlock/lock mechanism
The RTC module contains a kicker mechanism to prevent any spurious writes from changing the register values. To set the time, you must first unlock the TC registers, update them and then lock. Signed-off-by: Dario Binacchi --- (no changes since v1) drivers/rtc/davinci.c | 14 ++ 1 file changed, 14 insertions(+) diff --git a/drivers/rtc/davinci.c b/drivers/rtc/davinci.c index 7b8c729f3b..82e5eb3b43 100644 --- a/drivers/rtc/davinci.c +++ b/drivers/rtc/davinci.c @@ -16,6 +16,18 @@ #define RTC_BASE DAVINCI_RTC_BASE #endif +static void davinci_rtc_lock(struct davinci_rtc *rtc) +{ + writel(0, &rtc->kick0r); + writel(0, &rtc->kick1r); +} + +static void davinci_rtc_unlock(struct davinci_rtc *rtc) +{ + writel(RTC_KICK0R_WE, &rtc->kick0r); + writel(RTC_KICK1R_WE, &rtc->kick1r); +} + static int davinci_rtc_wait_not_busy(struct davinci_rtc *rtc) { int count; @@ -89,6 +101,7 @@ int rtc_set(struct rtc_time *tmp) if (ret) return ret; + davinci_rtc_unlock(rtc); writeb(bin2bcd(tmp->tm_year % 100), &rtc->year); writeb(bin2bcd(tmp->tm_mon), &rtc->month); @@ -97,6 +110,7 @@ int rtc_set(struct rtc_time *tmp) writeb(bin2bcd(tmp->tm_hour), &rtc->hours); writeb(bin2bcd(tmp->tm_min), &rtc->minutes); writeb(bin2bcd(tmp->tm_sec), &rtc->second); + davinci_rtc_lock(rtc); debug("Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, -- 2.17.1
[PATCH v2 3/8] rtc: davinci: replace 32bit access with 8bit access
Use 32-bit access only where it is needed. Most of the RTC registers contain useful information in the 8 least significant bits, the others are reserved. Signed-off-by: Dario Binacchi --- (no changes since v1) drivers/rtc/davinci.c | 32 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/rtc/davinci.c b/drivers/rtc/davinci.c index 8f5f76c9d6..99ae31e2a5 100644 --- a/drivers/rtc/davinci.c +++ b/drivers/rtc/davinci.c @@ -22,7 +22,7 @@ int rtc_get(struct rtc_time *tmp) unsigned long sec, min, hour, mday, wday, mon_cent, year; unsigned long status; - status = readl(&rtc->status); + status = readb(&rtc->status); if ((status & RTC_STATE_RUN) != RTC_STATE_RUN) { printf("RTC doesn't run\n"); return -1; @@ -30,13 +30,13 @@ int rtc_get(struct rtc_time *tmp) if ((status & RTC_STATE_BUSY) == RTC_STATE_BUSY) udelay(20); - sec = readl(&rtc->second); - min = readl(&rtc->minutes); - hour= readl(&rtc->hours); - mday= readl(&rtc->day); - wday= readl(&rtc->dotw); - mon_cent = readl(&rtc->month); - year= readl(&rtc->year); + sec = readb(&rtc->second); + min = readb(&rtc->minutes); + hour= readb(&rtc->hours); + mday= readb(&rtc->day); + wday= readb(&rtc->dotw); + mon_cent = readb(&rtc->month); + year= readb(&rtc->year); debug("Get RTC year: %02lx mon/cent: %02lx mday: %02lx wday: %02lx " "hr: %02lx min: %02lx sec: %02lx\n", @@ -67,14 +67,14 @@ int rtc_set(struct rtc_time *tmp) debug("Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec); - writel(bin2bcd(tmp->tm_year % 100), &rtc->year); - writel(bin2bcd(tmp->tm_mon), &rtc->month); + writeb(bin2bcd(tmp->tm_year % 100), &rtc->year); + writeb(bin2bcd(tmp->tm_mon), &rtc->month); - writel(bin2bcd(tmp->tm_wday), &rtc->dotw); - writel(bin2bcd(tmp->tm_mday), &rtc->day); - writel(bin2bcd(tmp->tm_hour), &rtc->hours); - writel(bin2bcd(tmp->tm_min), &rtc->minutes); - writel(bin2bcd(tmp->tm_sec), &rtc->second); + writeb(bin2bcd(tmp->tm_wday), &rtc->dotw); + writeb(bin2bcd(tmp->tm_mday), &rtc->day); + writeb(bin2bcd(tmp->tm_hour), &rtc->hours); + writeb(bin2bcd(tmp->tm_min), &rtc->minutes); + writeb(bin2bcd(tmp->tm_sec), &rtc->second); return 0; } @@ -83,5 +83,5 @@ void rtc_reset(void) struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE; /* run RTC counter */ - writel(0x01, &rtc->ctrl); + writeb(0x01, &rtc->ctrl); } -- 2.17.1
[PATCH v2 6/8] arm: dts: sync rtc node of am335x boards with Linux 5.9-rc7
There have been some changes to the am335x- DTs related to the rtc node, so let's re-syncs them with Linux. Signed-off-by: Dario Binacchi --- (no changes since v1) arch/arm/dts/am335x-bone-common.dtsi| 5 + arch/arm/dts/am335x-evm.dts | 5 + arch/arm/dts/am335x-evmsk.dts | 5 + arch/arm/dts/am335x-osd335x-common.dtsi | 6 ++ 4 files changed, 21 insertions(+) diff --git a/arch/arm/dts/am335x-bone-common.dtsi b/arch/arm/dts/am335x-bone-common.dtsi index 5b8230e281..8dcfac3a5b 100644 --- a/arch/arm/dts/am335x-bone-common.dtsi +++ b/arch/arm/dts/am335x-bone-common.dtsi @@ -398,3 +398,8 @@ &sham { status = "okay"; }; + +&rtc { + clocks = <&clk_32768_ck>, <&clk_24mhz_clkctrl AM3_CLK_24MHZ_CLKDIV32K_CLKCTRL 0>; + clock-names = "ext-clk", "int-clk"; +}; diff --git a/arch/arm/dts/am335x-evm.dts b/arch/arm/dts/am335x-evm.dts index c4bd1855f2..136f685bc5 100644 --- a/arch/arm/dts/am335x-evm.dts +++ b/arch/arm/dts/am335x-evm.dts @@ -783,3 +783,8 @@ pinctrl-names = "default"; pinctrl-0 = <&dcan1_pins_default>; }; + +&rtc { + clocks = <&clk_32768_ck>, <&clk_24mhz_clkctrl AM3_CLK_24MHZ_CLKDIV32K_CLKCTRL 0>; + clock-names = "ext-clk", "int-clk"; +}; diff --git a/arch/arm/dts/am335x-evmsk.dts b/arch/arm/dts/am335x-evmsk.dts index c94c33b595..b14bf2ff1b 100644 --- a/arch/arm/dts/am335x-evmsk.dts +++ b/arch/arm/dts/am335x-evmsk.dts @@ -724,3 +724,8 @@ &lcdc { status = "okay"; }; + +&rtc { + clocks = <&clk_32768_ck>, <&clk_24mhz_clkctrl AM3_CLK_24MHZ_CLKDIV32K_CLKCTRL 0>; + clock-names = "ext-clk", "int-clk"; +}; diff --git a/arch/arm/dts/am335x-osd335x-common.dtsi b/arch/arm/dts/am335x-osd335x-common.dtsi index f8ff473f94..2b55b7d0f9 100644 --- a/arch/arm/dts/am335x-osd335x-common.dtsi +++ b/arch/arm/dts/am335x-osd335x-common.dtsi @@ -122,3 +122,9 @@ &sham { status = "okay"; }; + +&rtc { + clocks = <&clk_32768_ck>, <&clk_24mhz_clkctrl AM3_CLK_24MHZ_CLKDIV32K_CLKCTRL 0>; + clock-names = "ext-clk", "int-clk"; + system-power-controller; +}; -- 2.17.1
[PATCH v2 0/8] rtc: davinci: add driver model support
The series adds driver model support for omap RTC plus some fixes. Changes in v2: - Separated from Kconfig patch - Use consistent naming (omap_rtc_. - Remove non-DM support. It's no more used. Dario Binacchi (8): rtc: davinci: enable compilation for omap architectures rtc: davinci: fix compiler errors rtc: davinci: replace 32bit access with 8bit access rtc: davinci: check BUSY bit before set TC registers rtc: davinci: use unlock/lock mechanism arm: dts: sync rtc node of am335x boards with Linux 5.9-rc7 rtc: davinci: add driver model support rtc: davinci: fix date loaded on reset arch/arm/dts/am335x-bone-common.dtsi| 5 + arch/arm/dts/am335x-evm.dts | 5 + arch/arm/dts/am335x-evmsk.dts | 5 + arch/arm/dts/am335x-osd335x-common.dtsi | 6 + drivers/rtc/Kconfig | 7 + drivers/rtc/davinci.c | 460 +--- 6 files changed, 439 insertions(+), 49 deletions(-) -- 2.17.1
[PATCH v2 1/8] rtc: davinci: enable compilation for omap architectures
The Davinci's onchip RTC is also present on TI OMAP1, AM33XX, AM43XX and DRA7XX SOCs. So, let's enable compilation for these architectures too. Signed-off-by: Dario Binacchi --- (no changes since v1) drivers/rtc/Kconfig | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index c84a9d2b27..cbdfddb80f 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -188,4 +188,11 @@ config RTC_ABX80X families of ultra-low-power battery- and capacitor-backed real-time clock chips. +config RTC_DAVINCI + bool "Enable TI OMAP RTC driver" + depends on ARCH_DAVINCI || ARCH_OMAP2PLUS + help + Say "yes" here to support the on chip real time clock + present on TI OMAP1, AM33xx, DA8xx/OMAP-L13x, AM43xx and DRA7xx. + endmenu -- 2.17.1
[PATCH v2 2/8] rtc: davinci: fix compiler errors
Fix errors raised by module compilation. Signed-off-by: Dario Binacchi --- Changes in v2: - Separated from Kconfig patch drivers/rtc/davinci.c | 11 --- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/rtc/davinci.c b/drivers/rtc/davinci.c index c446e7a735..8f5f76c9d6 100644 --- a/drivers/rtc/davinci.c +++ b/drivers/rtc/davinci.c @@ -9,11 +9,16 @@ #include #include #include +#include #include +#if !defined(RTC_BASE) && defined(DAVINCI_RTC_BASE) +#define RTC_BASE DAVINCI_RTC_BASE +#endif + int rtc_get(struct rtc_time *tmp) { - struct davinci_rtc *rtc = (struct davinci_rtc *)DAVINCI_RTC_BASE; + struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE; unsigned long sec, min, hour, mday, wday, mon_cent, year; unsigned long status; @@ -57,7 +62,7 @@ int rtc_get(struct rtc_time *tmp) int rtc_set(struct rtc_time *tmp) { - struct davinci_rtc *rtc = (struct davinci_rtc *)DAVINCI_RTC_BASE; + struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE; debug("Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, @@ -75,7 +80,7 @@ int rtc_set(struct rtc_time *tmp) void rtc_reset(void) { - struct davinci_rtc *rtc = (struct davinci_rtc *)DAVINCI_RTC_BASE; + struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE; /* run RTC counter */ writel(0x01, &rtc->ctrl); -- 2.17.1
Re: [PATCH 1/7] rtc: davinci: enable compilation for omap architectures
Hi Lokesh, > Il 27/05/2021 11:59 Lokesh Vutla ha scritto: > > > On 07/05/21 9:45 am, Dario Binacchi wrote: > > The Davinci's onchip RTC is also present on TI OMAP1, AM33XX, AM43XX and > > DRA7XX SOCs. So, let's enable compilation for these architectures too. > > > > Signed-off-by: Dario Binacchi > > --- > > > > drivers/rtc/Kconfig | 7 +++ > > drivers/rtc/davinci.c | 11 --- > > 2 files changed, 15 insertions(+), 3 deletions(-) > > > > diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig > > index c84a9d2b27..cbdfddb80f 100644 > > --- a/drivers/rtc/Kconfig > > +++ b/drivers/rtc/Kconfig > > @@ -188,4 +188,11 @@ config RTC_ABX80X > > families of ultra-low-power battery- and capacitor-backed real-time > > clock chips. > > > > +config RTC_DAVINCI > > + bool "Enable TI OMAP RTC driver" > > + depends on ARCH_DAVINCI || ARCH_OMAP2PLUS > > I assume you are converting to a Kconfig symbol? Can you keep this as a > separate > patch and use tools/moveconfig.py? The CONFIG_RTC_DAVINCI symbol was only in the Makefile. I ran moveconfig.py and in fact it didn't find it in any configuration header. I'll add the Kconfig symbol in a separate patch. Thanks and regards Dario Binacchi > > Thanks and regards, > Lokesh
Re: [PATCH] pinctrl: single: Fix probe failure getting register area size
Hi, > Il 17/05/2021 22:15 Tom Rini ha scritto: > > > On Fri, May 07, 2021 at 02:40:34PM +0530, Vignesh Raghavendra wrote: > > > If reg property of pinctrl-single node requires address translation then > > probe fails with following message: > > > > single-pinctrl pinctrl@4301c000: failed to get base register size > > > > This is because driver uses dev_read_addr_size() to get size which also > > tries to fetch untranslated addr and fails. > > Fix this by using dev_read_addr_size_index() which takes care of address > > translation and also makes following dev_read_addr() call redundant. > > > > This fixes Ethernet failures on TI's AM654 based EVMs due to lack of > > pinmux configuration. > > > > Fixes: 9fd8a430f3 ("pinctrl: single: get register area size by device API") > > Signed-off-by: Vignesh Raghavendra > > --- > > drivers/pinctrl/pinctrl-single.c | 10 ++ > > 1 file changed, 2 insertions(+), 8 deletions(-) > > > > diff --git a/drivers/pinctrl/pinctrl-single.c > > b/drivers/pinctrl/pinctrl-single.c > > index ebb7602dde..7af6c5f0b0 100644 > > --- a/drivers/pinctrl/pinctrl-single.c > > +++ b/drivers/pinctrl/pinctrl-single.c > > @@ -509,19 +509,13 @@ static int single_of_to_plat(struct udevice *dev) > > return -EINVAL; > > } > > > > - addr = dev_read_addr_size(dev, "reg", &size); > > + addr = dev_read_addr_size_index(dev, 0, &size); > > if (addr == FDT_ADDR_T_NONE) { > > - dev_err(dev, "failed to get base register size\n"); > > + dev_err(dev, "failed to get base register address\n"); > > return -EINVAL; > > } > > > > pdata->offset = size - pdata->width / BITS_PER_BYTE; > > - > > - addr = dev_read_addr(dev); > > - if (addr == FDT_ADDR_T_NONE) { > > - dev_dbg(dev, "no valid base register address\n"); > > - return -EINVAL; > > - } > > pdata->base = addr; > > > > ret = dev_read_u32(dev, "pinctrl-single,function-mask", &pdata->mask); > > Dario, since this has a fixes tag for a commit of yours, comments? > Thanks! > I applied the patch and tested it on my beaglebone black. It is OK. As well the tests I had developed in the sandbox configuration for pinmux passed. Thanks and regards, Dario > -- > Tom
Re: [PATCH 1/7] rtc: davinci: enable compilation for omap architectures
Hi Pali, > Il 07/05/2021 09:56 Pali Rohár ha scritto: > > > On Friday 07 May 2021 06:15:02 Dario Binacchi wrote: > > The Davinci's onchip RTC is also present on TI OMAP1, AM33XX, AM43XX and > > DRA7XX SOCs. So, let's enable compilation for these architectures too. > > Hello! If it is available on AM33XX, do you know if it is also on OMAP3? > I do not think so. I think am335x is omap2 and not omap3. In https://www.ti.com/lit/ug/spruf98y/spruf98y.pdf I don't see any reference to the RTC. Thanks and regards, Dario > > Signed-off-by: Dario Binacchi > > --- > > > > drivers/rtc/Kconfig | 7 +++ > > drivers/rtc/davinci.c | 11 --- > > 2 files changed, 15 insertions(+), 3 deletions(-) > > > > diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig > > index c84a9d2b27..cbdfddb80f 100644 > > --- a/drivers/rtc/Kconfig > > +++ b/drivers/rtc/Kconfig > > @@ -188,4 +188,11 @@ config RTC_ABX80X > > families of ultra-low-power battery- and capacitor-backed real-time > > clock chips. > > > > +config RTC_DAVINCI > > + bool "Enable TI OMAP RTC driver" > > + depends on ARCH_DAVINCI || ARCH_OMAP2PLUS > > + help > > + Say "yes" here to support the on chip real time clock > > + present on TI OMAP1, AM33xx, DA8xx/OMAP-L13x, AM43xx and DRA7xx. > > + > > endmenu > > diff --git a/drivers/rtc/davinci.c b/drivers/rtc/davinci.c > > index c446e7a735..8f5f76c9d6 100644 > > --- a/drivers/rtc/davinci.c > > +++ b/drivers/rtc/davinci.c > > @@ -9,11 +9,16 @@ > > #include > > #include > > #include > > +#include > > #include > > > > +#if !defined(RTC_BASE) && defined(DAVINCI_RTC_BASE) > > +#define RTC_BASE DAVINCI_RTC_BASE > > +#endif > > + > > int rtc_get(struct rtc_time *tmp) > > { > > - struct davinci_rtc *rtc = (struct davinci_rtc *)DAVINCI_RTC_BASE; > > + struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE; > > unsigned long sec, min, hour, mday, wday, mon_cent, year; > > unsigned long status; > > > > @@ -57,7 +62,7 @@ int rtc_get(struct rtc_time *tmp) > > > > int rtc_set(struct rtc_time *tmp) > > { > > - struct davinci_rtc *rtc = (struct davinci_rtc *)DAVINCI_RTC_BASE; > > + struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE; > > > > debug("Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", > > tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, > > @@ -75,7 +80,7 @@ int rtc_set(struct rtc_time *tmp) > > > > void rtc_reset(void) > > { > > - struct davinci_rtc *rtc = (struct davinci_rtc *)DAVINCI_RTC_BASE; > > + struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE; > > > > /* run RTC counter */ > > writel(0x01, &rtc->ctrl); > > -- > > 2.17.1 > >
[PATCH 6/7] rtc: davinci: add driver model support
Update the driver to support the device tree and the driver model. The read / write helpers in rtc_ops allow access to scratch registers only. The offset parameter is added to the address of the scratch0 register. Signed-off-by: Dario Binacchi --- drivers/rtc/davinci.c | 373 -- 1 file changed, 363 insertions(+), 10 deletions(-) diff --git a/drivers/rtc/davinci.c b/drivers/rtc/davinci.c index 82e5eb3b43..b0a077cba7 100644 --- a/drivers/rtc/davinci.c +++ b/drivers/rtc/davinci.c @@ -2,20 +2,20 @@ /* * (C) Copyright 2011 DENX Software Engineering GmbH * Heiko Schocher + * Copyright (C) 2021 Dario Binacchi */ #include #include +#include +#include #include #include #include #include #include +#include #include -#if !defined(RTC_BASE) && defined(DAVINCI_RTC_BASE) -#define RTC_BASE DAVINCI_RTC_BASE -#endif - static void davinci_rtc_lock(struct davinci_rtc *rtc) { writel(0, &rtc->kick0r); @@ -52,9 +52,8 @@ static int davinci_rtc_wait_not_busy(struct davinci_rtc *rtc) return 0; } -int rtc_get(struct rtc_time *tmp) +static int davinci_rtc_get(struct davinci_rtc *rtc, struct rtc_time *tmp) { - struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE; unsigned long sec, min, hour, mday, wday, mon_cent, year; int ret; @@ -92,9 +91,8 @@ int rtc_get(struct rtc_time *tmp) return 0; } -int rtc_set(struct rtc_time *tmp) +static int davinci_rtc_set(struct davinci_rtc *rtc, const struct rtc_time *tmp) { - struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE; int ret; ret = davinci_rtc_wait_not_busy(rtc); @@ -119,10 +117,365 @@ int rtc_set(struct rtc_time *tmp) return 0; } +static void davinci_rtc_reset(struct davinci_rtc *rtc) +{ + /* run RTC counter */ + writeb(0x01, &rtc->ctrl); +} + +#if !CONFIG_IS_ENABLED(DM_RTC) + +#if !defined(RTC_BASE) && defined(DAVINCI_RTC_BASE) +#define RTC_BASE DAVINCI_RTC_BASE +#endif + +int rtc_get(struct rtc_time *tmp) +{ + struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE; + + return davinci_rtc_get(rtc, tmp); +} + +int rtc_set(struct rtc_time *tmp) +{ + struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE; + + return davinci_rtc_set(rtc, tmp); +} + void rtc_reset(void) { struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE; - /* run RTC counter */ - writeb(0x01, &rtc->ctrl); + davinci_rtc_reset(rtc); +} + +#else /* CONFIG_DM_RTC */ + +#define OMAP_RTC_CTRL_REG 0x40 +#define OMAP_RTC_STATUS_REG0x44 +#define OMAP_RTC_INTERRUPTS_REG0x48 + +#define OMAP_RTC_OSC_REG 0x54 + +#define OMAP_RTC_SCRATCH0_REG 0x60 +#define OMAP_RTC_SCRATCH1_REG 0x64 +#define OMAP_RTC_SCRATCH2_REG 0x68 + +#define OMAP_RTC_KICK0_REG 0x6c +#define OMAP_RTC_KICK1_REG 0x70 + +#define OMAP_RTC_PMIC_REG 0x98 + +/* OMAP_RTC_CTRL_REG bit fields: */ +#define OMAP_RTC_CTRL_SPLITBIT(7) +#define OMAP_RTC_CTRL_DISABLE BIT(6) +#define OMAP_RTC_CTRL_SET_32_COUNTER BIT(5) +#define OMAP_RTC_CTRL_TEST BIT(4) +#define OMAP_RTC_CTRL_MODE_12_24 BIT(3) +#define OMAP_RTC_CTRL_AUTO_COMPBIT(2) +#define OMAP_RTC_CTRL_ROUND_30SBIT(1) +#define OMAP_RTC_CTRL_STOP BIT(0) + +/* OMAP_RTC_STATUS_REG bit fields */ +#define OMAP_RTC_STATUS_POWER_UP BIT(7) +#define OMAP_RTC_STATUS_ALARM2 BIT(7) +#define OMAP_RTC_STATUS_ALARM BIT(6) +#define OMAP_RTC_STATUS_1D_EVENT BIT(5) +#define OMAP_RTC_STATUS_1H_EVENT BIT(4) +#define OMAP_RTC_STATUS_1M_EVENT BIT(3) +#define OMAP_RTC_STATUS_1S_EVENT BIT(2) +#define OMAP_RTC_STATUS_RUNBIT(1) +#define OMAP_RTC_STATUS_BUSY BIT(0) + +/* OMAP_RTC_OSC_REG bit fields */ +#define OMAP_RTC_OSC_32KCLK_EN BIT(6) +#define OMAP_RTC_OSC_SEL_32KCLK_SRCBIT(3) +#define OMAP_RTC_OSC_OSC32K_GZ_DISABLE BIT(4) + +struct omap_rtc_device_type { + bool has_32kclk_en; + bool has_irqwakeen; + bool has_pmic_mode; + bool has_power_up_reset; +}; + +struct omap_rtc_priv { + fdt_addr_t base; + u8 max_reg; + struct udevice *dev; + struct clk clk; + bool has_ext_clk; + const struct omap_rtc_device_type *type; +}; + +static inline u8 omap_rtc_readb(struct omap_rtc_priv *priv, unsigned int reg) +{ + return readb(priv->base + reg); +} + +static inline u32 omap_rtc_readl(struct omap_rtc_priv *priv, unsigned int reg) +{ + return readl(priv->base + reg); +} + +static inline void omap_rtc_writeb(struct omap_rtc_priv *priv, unsigned int reg, + u8 val) +{ + writeb(val, priv->base + reg); +} + +static inline void omap_rtc_writel(struct omap_rtc_priv *priv, unsigned int r
[PATCH 5/7] arm: dts: sync rtc node of am335x boards with Linux 5.9-rc7
There have been some changes to the am335x- DTs related to the rtc node, so let's re-syncs them with Linux. Signed-off-by: Dario Binacchi --- arch/arm/dts/am335x-bone-common.dtsi| 5 + arch/arm/dts/am335x-evm.dts | 5 + arch/arm/dts/am335x-evmsk.dts | 5 + arch/arm/dts/am335x-osd335x-common.dtsi | 6 ++ 4 files changed, 21 insertions(+) diff --git a/arch/arm/dts/am335x-bone-common.dtsi b/arch/arm/dts/am335x-bone-common.dtsi index 5b8230e281..8dcfac3a5b 100644 --- a/arch/arm/dts/am335x-bone-common.dtsi +++ b/arch/arm/dts/am335x-bone-common.dtsi @@ -398,3 +398,8 @@ &sham { status = "okay"; }; + +&rtc { + clocks = <&clk_32768_ck>, <&clk_24mhz_clkctrl AM3_CLK_24MHZ_CLKDIV32K_CLKCTRL 0>; + clock-names = "ext-clk", "int-clk"; +}; diff --git a/arch/arm/dts/am335x-evm.dts b/arch/arm/dts/am335x-evm.dts index c4bd1855f2..136f685bc5 100644 --- a/arch/arm/dts/am335x-evm.dts +++ b/arch/arm/dts/am335x-evm.dts @@ -783,3 +783,8 @@ pinctrl-names = "default"; pinctrl-0 = <&dcan1_pins_default>; }; + +&rtc { + clocks = <&clk_32768_ck>, <&clk_24mhz_clkctrl AM3_CLK_24MHZ_CLKDIV32K_CLKCTRL 0>; + clock-names = "ext-clk", "int-clk"; +}; diff --git a/arch/arm/dts/am335x-evmsk.dts b/arch/arm/dts/am335x-evmsk.dts index c94c33b595..b14bf2ff1b 100644 --- a/arch/arm/dts/am335x-evmsk.dts +++ b/arch/arm/dts/am335x-evmsk.dts @@ -724,3 +724,8 @@ &lcdc { status = "okay"; }; + +&rtc { + clocks = <&clk_32768_ck>, <&clk_24mhz_clkctrl AM3_CLK_24MHZ_CLKDIV32K_CLKCTRL 0>; + clock-names = "ext-clk", "int-clk"; +}; diff --git a/arch/arm/dts/am335x-osd335x-common.dtsi b/arch/arm/dts/am335x-osd335x-common.dtsi index f8ff473f94..2b55b7d0f9 100644 --- a/arch/arm/dts/am335x-osd335x-common.dtsi +++ b/arch/arm/dts/am335x-osd335x-common.dtsi @@ -122,3 +122,9 @@ &sham { status = "okay"; }; + +&rtc { + clocks = <&clk_32768_ck>, <&clk_24mhz_clkctrl AM3_CLK_24MHZ_CLKDIV32K_CLKCTRL 0>; + clock-names = "ext-clk", "int-clk"; + system-power-controller; +}; -- 2.17.1
[PATCH 7/7] rtc: davinci: fix date loaded on reset
On reset, the RTC loads the 2000-01-01 date with a wrong day of the week (Sunday instead of Saturday). Signed-off-by: Dario Binacchi --- drivers/rtc/davinci.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/drivers/rtc/davinci.c b/drivers/rtc/davinci.c index b0a077cba7..88fd56b1ba 100644 --- a/drivers/rtc/davinci.c +++ b/drivers/rtc/davinci.c @@ -335,6 +335,7 @@ static int omap_rtc_remove(struct udevice *dev) static int omap_rtc_probe(struct udevice *dev) { struct omap_rtc_priv *priv = dev_get_priv(dev); + struct rtc_time tm; u8 reg, mask, new_ctrl; priv->dev = dev; @@ -425,6 +426,15 @@ static int omap_rtc_probe(struct udevice *dev) } omap_rtc_lock(priv); + + if (omap_rtc_get(dev, &tm)) { + dev_err(dev, "failed to get datetime\n"); + } else if (tm.tm_year == 2000 && tm.tm_mon == 1 && tm.tm_mday == 1 && + tm.tm_wday == 0) { + tm.tm_wday = 6; + omap_rtc_set(dev, &tm); + } + return 0; } -- 2.17.1
[PATCH 4/7] rtc: davinci: use unlock/lock mechanism
The RTC module contains a kicker mechanism to prevent any spurious writes from changing the register values. To set the time, you must first unlock the TC registers, update them and then lock. Signed-off-by: Dario Binacchi --- drivers/rtc/davinci.c | 14 ++ 1 file changed, 14 insertions(+) diff --git a/drivers/rtc/davinci.c b/drivers/rtc/davinci.c index 7b8c729f3b..82e5eb3b43 100644 --- a/drivers/rtc/davinci.c +++ b/drivers/rtc/davinci.c @@ -16,6 +16,18 @@ #define RTC_BASE DAVINCI_RTC_BASE #endif +static void davinci_rtc_lock(struct davinci_rtc *rtc) +{ + writel(0, &rtc->kick0r); + writel(0, &rtc->kick1r); +} + +static void davinci_rtc_unlock(struct davinci_rtc *rtc) +{ + writel(RTC_KICK0R_WE, &rtc->kick0r); + writel(RTC_KICK1R_WE, &rtc->kick1r); +} + static int davinci_rtc_wait_not_busy(struct davinci_rtc *rtc) { int count; @@ -89,6 +101,7 @@ int rtc_set(struct rtc_time *tmp) if (ret) return ret; + davinci_rtc_unlock(rtc); writeb(bin2bcd(tmp->tm_year % 100), &rtc->year); writeb(bin2bcd(tmp->tm_mon), &rtc->month); @@ -97,6 +110,7 @@ int rtc_set(struct rtc_time *tmp) writeb(bin2bcd(tmp->tm_hour), &rtc->hours); writeb(bin2bcd(tmp->tm_min), &rtc->minutes); writeb(bin2bcd(tmp->tm_sec), &rtc->second); + davinci_rtc_lock(rtc); debug("Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, -- 2.17.1
[PATCH 3/7] rtc: davinci: check BUSY bit before set TC registers
To write correct data to the TC registers, the STATUS register must be read until the BUSY bit is equal to zero. Once the BUSY flag is zero, there is a 15 μs access period in which the TC registers can be programmed. The rtc_wait_not_busy() has been inspired by the Kernel. Signed-off-by: Dario Binacchi --- drivers/rtc/davinci.c | 45 ++- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/drivers/rtc/davinci.c b/drivers/rtc/davinci.c index 99ae31e2a5..7b8c729f3b 100644 --- a/drivers/rtc/davinci.c +++ b/drivers/rtc/davinci.c @@ -16,19 +16,39 @@ #define RTC_BASE DAVINCI_RTC_BASE #endif -int rtc_get(struct rtc_time *tmp) +static int davinci_rtc_wait_not_busy(struct davinci_rtc *rtc) { - struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE; - unsigned long sec, min, hour, mday, wday, mon_cent, year; - unsigned long status; + int count; + u8 status; status = readb(&rtc->status); if ((status & RTC_STATE_RUN) != RTC_STATE_RUN) { printf("RTC doesn't run\n"); return -1; } - if ((status & RTC_STATE_BUSY) == RTC_STATE_BUSY) - udelay(20); + + /* BUSY may stay active for 1/32768 second (~30 usec) */ + for (count = 0; count < 50; count++) { + if (!(status & RTC_STATE_BUSY)) + break; + + udelay(1); + status = readb(&rtc->status); + } + + /* now we have ~15 usec to read/write various registers */ + return 0; +} + +int rtc_get(struct rtc_time *tmp) +{ + struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE; + unsigned long sec, min, hour, mday, wday, mon_cent, year; + int ret; + + ret = davinci_rtc_wait_not_busy(rtc); + if (ret) + return ret; sec = readb(&rtc->second); min = readb(&rtc->minutes); @@ -63,10 +83,12 @@ int rtc_get(struct rtc_time *tmp) int rtc_set(struct rtc_time *tmp) { struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE; + int ret; + + ret = davinci_rtc_wait_not_busy(rtc); + if (ret) + return ret; - debug("Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", - tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, - tmp->tm_hour, tmp->tm_min, tmp->tm_sec); writeb(bin2bcd(tmp->tm_year % 100), &rtc->year); writeb(bin2bcd(tmp->tm_mon), &rtc->month); @@ -75,6 +97,11 @@ int rtc_set(struct rtc_time *tmp) writeb(bin2bcd(tmp->tm_hour), &rtc->hours); writeb(bin2bcd(tmp->tm_min), &rtc->minutes); writeb(bin2bcd(tmp->tm_sec), &rtc->second); + + debug("Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", + tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, + tmp->tm_hour, tmp->tm_min, tmp->tm_sec); + return 0; } -- 2.17.1
[PATCH 2/7] rtc: davinci: replace 32bit access with 8bit access
Use 32-bit access only where it is needed. Most of the RTC registers contain useful information in the 8 least significant bits, the others are reserved. Signed-off-by: Dario Binacchi --- drivers/rtc/davinci.c | 32 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/rtc/davinci.c b/drivers/rtc/davinci.c index 8f5f76c9d6..99ae31e2a5 100644 --- a/drivers/rtc/davinci.c +++ b/drivers/rtc/davinci.c @@ -22,7 +22,7 @@ int rtc_get(struct rtc_time *tmp) unsigned long sec, min, hour, mday, wday, mon_cent, year; unsigned long status; - status = readl(&rtc->status); + status = readb(&rtc->status); if ((status & RTC_STATE_RUN) != RTC_STATE_RUN) { printf("RTC doesn't run\n"); return -1; @@ -30,13 +30,13 @@ int rtc_get(struct rtc_time *tmp) if ((status & RTC_STATE_BUSY) == RTC_STATE_BUSY) udelay(20); - sec = readl(&rtc->second); - min = readl(&rtc->minutes); - hour= readl(&rtc->hours); - mday= readl(&rtc->day); - wday= readl(&rtc->dotw); - mon_cent = readl(&rtc->month); - year= readl(&rtc->year); + sec = readb(&rtc->second); + min = readb(&rtc->minutes); + hour= readb(&rtc->hours); + mday= readb(&rtc->day); + wday= readb(&rtc->dotw); + mon_cent = readb(&rtc->month); + year= readb(&rtc->year); debug("Get RTC year: %02lx mon/cent: %02lx mday: %02lx wday: %02lx " "hr: %02lx min: %02lx sec: %02lx\n", @@ -67,14 +67,14 @@ int rtc_set(struct rtc_time *tmp) debug("Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec); - writel(bin2bcd(tmp->tm_year % 100), &rtc->year); - writel(bin2bcd(tmp->tm_mon), &rtc->month); + writeb(bin2bcd(tmp->tm_year % 100), &rtc->year); + writeb(bin2bcd(tmp->tm_mon), &rtc->month); - writel(bin2bcd(tmp->tm_wday), &rtc->dotw); - writel(bin2bcd(tmp->tm_mday), &rtc->day); - writel(bin2bcd(tmp->tm_hour), &rtc->hours); - writel(bin2bcd(tmp->tm_min), &rtc->minutes); - writel(bin2bcd(tmp->tm_sec), &rtc->second); + writeb(bin2bcd(tmp->tm_wday), &rtc->dotw); + writeb(bin2bcd(tmp->tm_mday), &rtc->day); + writeb(bin2bcd(tmp->tm_hour), &rtc->hours); + writeb(bin2bcd(tmp->tm_min), &rtc->minutes); + writeb(bin2bcd(tmp->tm_sec), &rtc->second); return 0; } @@ -83,5 +83,5 @@ void rtc_reset(void) struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE; /* run RTC counter */ - writel(0x01, &rtc->ctrl); + writeb(0x01, &rtc->ctrl); } -- 2.17.1
[PATCH 1/7] rtc: davinci: enable compilation for omap architectures
The Davinci's onchip RTC is also present on TI OMAP1, AM33XX, AM43XX and DRA7XX SOCs. So, let's enable compilation for these architectures too. Signed-off-by: Dario Binacchi --- drivers/rtc/Kconfig | 7 +++ drivers/rtc/davinci.c | 11 --- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index c84a9d2b27..cbdfddb80f 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -188,4 +188,11 @@ config RTC_ABX80X families of ultra-low-power battery- and capacitor-backed real-time clock chips. +config RTC_DAVINCI + bool "Enable TI OMAP RTC driver" + depends on ARCH_DAVINCI || ARCH_OMAP2PLUS + help + Say "yes" here to support the on chip real time clock + present on TI OMAP1, AM33xx, DA8xx/OMAP-L13x, AM43xx and DRA7xx. + endmenu diff --git a/drivers/rtc/davinci.c b/drivers/rtc/davinci.c index c446e7a735..8f5f76c9d6 100644 --- a/drivers/rtc/davinci.c +++ b/drivers/rtc/davinci.c @@ -9,11 +9,16 @@ #include #include #include +#include #include +#if !defined(RTC_BASE) && defined(DAVINCI_RTC_BASE) +#define RTC_BASE DAVINCI_RTC_BASE +#endif + int rtc_get(struct rtc_time *tmp) { - struct davinci_rtc *rtc = (struct davinci_rtc *)DAVINCI_RTC_BASE; + struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE; unsigned long sec, min, hour, mday, wday, mon_cent, year; unsigned long status; @@ -57,7 +62,7 @@ int rtc_get(struct rtc_time *tmp) int rtc_set(struct rtc_time *tmp) { - struct davinci_rtc *rtc = (struct davinci_rtc *)DAVINCI_RTC_BASE; + struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE; debug("Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, @@ -75,7 +80,7 @@ int rtc_set(struct rtc_time *tmp) void rtc_reset(void) { - struct davinci_rtc *rtc = (struct davinci_rtc *)DAVINCI_RTC_BASE; + struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE; /* run RTC counter */ writel(0x01, &rtc->ctrl); -- 2.17.1
[PATCH 0/7] rtc: davinci: add driver model support
The series adds driver model support for omap RTC plus some fixes. Dario Binacchi (7): rtc: davinci: enable compilation for omap architectures rtc: davinci: replace 32bit access with 8bit access rtc: davinci: check BUSY bit before set TC registers rtc: davinci: use unlock/lock mechanism arm: dts: sync rtc node of am335x boards with Linux 5.9-rc7 rtc: davinci: add driver model support rtc: davinci: fix date loaded on reset arch/arm/dts/am335x-bone-common.dtsi| 5 + arch/arm/dts/am335x-evm.dts | 5 + arch/arm/dts/am335x-evmsk.dts | 5 + arch/arm/dts/am335x-osd335x-common.dtsi | 6 + drivers/rtc/Kconfig | 7 + drivers/rtc/davinci.c | 467 ++-- 6 files changed, 466 insertions(+), 29 deletions(-) -- 2.17.1
Re: Weirdness of ofnode_get_addr_size()
Hi Jan, > Il 04/05/2021 17:26 Simon Glass ha scritto: > > > Hi Jan, > > On Sun, 2 May 2021 at 01:53, Jan Kiszka wrote: > > > > Hi, > > > > I'm trying to make some sense of ofnode_get_addr_size() in order to fix > > [1] properly. > > > > First, the documentation if this functions says "This does no address > > translation". But the node-pointer path happily calls > > of_translate_address(), as the result of a6a45cd32539. For not > > offset-bases path, it calls fdtdec_get_addr_size() which does no > > translation. > > > > Related to [1]: The node-pointer path cleanly calls > > of_n_addr/size_cells() in order to retrieve the configured number of > > cells. But the offset-based path simply calls fdtdec_get_addr_size() > > which assumes that the number of cells is derived from the physical > > address width of that platform. > > > > So, what is that functions actually supposed to do? > > +Dario Binacchi +Mario Six > > I suspect the code has got ahead of the docs. > > d64b9cdcd47 fdt: translate address if #size-cells = <0> I submitted a patch to revert the commit: https://patchwork.ozlabs.org/project/uboot/patch/20210501150527.10273-6-dario...@libero.it/ Thanks and regards, Dario > e8d5291824e core: ofnode: Fix translation for #size-cells == 0 > > Regards, > Simon > > > > > Jan > > > > [1] https://www.mail-archive.com/u-boot@lists.denx.de/msg405446.html
Re: [PATCH v4 05/12] pinctrl: single: get register area size by device API
Hi Jan, > Il 01/05/2021 14:29 Jan Kiszka ha scritto: > > > On 11.04.21 09:39, Dario Binacchi wrote: > > Use dev_read_addr_size to get size of the controller's register area. > > > > Signed-off-by: Dario Binacchi > > Reviewed-by: Pratyush Yadav > > > > --- > > > > (no changes since v3) > > > > Changes in v3: > > - Added Pratyush Yadav review tag. > > > > Changes in v2: > > - Check dev_read_addr_size return value. > > > > drivers/pinctrl/pinctrl-single.c | 14 -- > > 1 file changed, 8 insertions(+), 6 deletions(-) > > > > diff --git a/drivers/pinctrl/pinctrl-single.c > > b/drivers/pinctrl/pinctrl-single.c > > index cec00e289c..d5656de8e8 100644 > > --- a/drivers/pinctrl/pinctrl-single.c > > +++ b/drivers/pinctrl/pinctrl-single.c > > @@ -182,17 +182,19 @@ static int single_set_state(struct udevice *dev, > > static int single_of_to_plat(struct udevice *dev) > > { > > fdt_addr_t addr; > > - u32 of_reg[2]; > > - int res; > > + fdt_size_t size; > > struct single_pdata *pdata = dev_get_plat(dev); > > > > pdata->width = > > dev_read_u32_default(dev, "pinctrl-single,register-width", 0); > > > > - res = dev_read_u32_array(dev, "reg", of_reg, 2); > > - if (res) > > - return res; > > - pdata->offset = of_reg[1] - pdata->width / 8; > > + addr = dev_read_addr_size(dev, "reg", &size); > > Looks to me as if this has to be > > addr = dev_read_addr_size_index(dev, 0, &size); > > because dev_read_addr_size() assumes address and size width of > fdt_addr_t, ie. 2 cells, rather than what is actually configured in the DT. > > I don't understand the use cases of dev_read_addr_size() vs. > dev_read_addr_size_index(), if the former should also respect what the > parent node configured size-wise. However, this patch breaks e.g. > k3-am65 DTs, namely pinctrl@4301c000 which uses only one cell for > address and size (according to bus@4204). If dev_read_addr_size() breaks k3-am65 DTs, the use of dev_read_addr_size_index() doesn't break am335x DTs. Sandbox and beaglebone tests are ok. IMHO you can submit the patch. Why not, add a test too. Thanks and regards, Dario > > Jan > > > + if (addr == FDT_ADDR_T_NONE) { > > + dev_err(dev, "failed to get base register size\n"); > > + return -EINVAL; > > + } > > + > > + pdata->offset = size - pdata->width / BITS_PER_BYTE; > > > > addr = dev_read_addr(dev); > > if (addr == FDT_ADDR_T_NONE) { > >