From: Jagan Teki <jteki@openedev.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] dm: Introduce SPI-NOR framework
Date: Thu, 03 Dec 2015 15:40:56 +0530 [thread overview]
Message-ID: <56601530.5030306@openedev.com> (raw)
Hi Simon,
I re-phrase all the question from previous thread and continue in this
for more discussion on spi-nor development.
> Is it intended that SPI flash should be a driver for the MTD uclass?
> Others would be NAND and CFI. From what I can tell MTD has the same
> operations as SPI flash (erase, read, write) and adds a lot more.
>
> Or is SPI flash really a separate uclass from MTD, with SPI flash
> being at a higher level?
Based on my "sf: MTD support" series SPI flash is a separate uclass from
MTD and it uses mtd_info operations.
>> cmd_sf
>> =======
>> MTD
>> =======
>> spi-nor or spi-flash
>> ===============
>> "spi-nor to spi drivers" and spi-nor controller driver
>> =======================================
> Your diagram above suggests that MTD calls into SPI NOR or SPI flash,
> but when I look at (for exampe) spi_flash_erase(), it is calling
> mtd_erase(), suggesting that it is above MTD in the software stack,
> the opposite of your diagram above.
>
Will explain this clearly in below description.
> Conceptually this seems problematic.
>
> SPI flash is a uclass and supports driver model. It has operations,
> etc. Your patches remove the operations in favour of calling MTD. But
> MTD does not support driver model. This is getting really messy.
>
Will explain this clearly in below description.
Introducing SPI-NOR:
********************
Some of the spi drivers or spi controllers at drivers/spi/*
not a real spi controllers, unlike normal spi controllers
those operates varienty of spi devices among spi-nor flash is
one of them but instead these were specially designed for
to operate spi-nor flash devices - these are spi-nor controllers.
example: drivers/spi/fsl_qspi.c
The problem with these were sitting at drivers/spi is entire
spi layer becomes spi-nor flash oriented which is absolutely
wrong indication where spi layer gets effected more with
flash operations - So this SPI-NOR will resolve this issue
by separating all spi-nor flash operations from spi layer
and by creating a generic layer called SPI-NOR core where it
deals with all SPI-NOR flash activities. The basic idea is
taken from Linux spi-nor framework.
SPI-NOR Block diagram:
*********************
=========
cmd_sf.c
===========
spi_flash.h
===========
mtdcore.c
===========
spi-nor.c
========================
m25p80.c fsl_qspi.c
========== ===========
spi-uclass spi-nor hw
========== ===========
spi_drivers
===========
spi-bus hw
==========
Note:
- spi-nor.c is a common core for m25p80.c which is a spi-nor to spi
driver interface layer and for fsl_qspi.c which is a typical spi-nor
controller driver.
- Challenging task is about probe.
SPI-NOR Development plan:
*************************
a) Adding MTD core support:
From command point of view the spi-flash is like a mtd device
having erase/write/read ops with offset, addr and size, but from lower
layers the spi-flash becomes either spi-nor or spi-nand so they have
their own specific features like struct spi_nor {}.
This is the reason for calling MTD from command layer and the lower
layer as SPI_NOR uclass.
b) Drop spi_flash uclass:
Since spi_flash is a generic term for serial flash devices among
these spi-nor and spi-nand are the real device categories so add
driver model to these categories.
I sent the series [1] for above a) and b)
c) Add spi-nor support (mean Adding SPI-NOR dm drivers) the next step.
Detailed SPI-NOR with examples:
******************************
include/spi_flash.h
-------------------
struct spi_flash {
struct spi_nor *nor;
};
include/linux/mtd/spi-nor.h
---------------------------
struct spi_nor {
struct udevice *dev;
struct mtd_info *info;
// spi-nor hooks
int (*read_reg)(struct udevice *dev, u8 cmd, u8 *val, int len);
int (*write_reg)(struct udevice *dev, u8 cmd, u8 *data, int len);
int (*read_mmap)(struct udevice *dev, void *data, void *offset,
size_t len);
int (*read)(struct udevice *dev, const u8 *opcode, size_t cmd_len,
void *data, size_t data_len);
int (*write)(struct udevice *dev, const u8 *cmd, size_t cmd_len,
const void *data, size_t data_len);
};
drivers/mtd/spi-nor/spi-nor.c
-----------------------------
static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
{
// call to spi-nor erase nor->erase()
}
static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char *buf)
{
// call to spi-nor erase nor->read()
}
static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len,
size_t *retlen, const u_char *buf)
{
// call to spi-nor erase nor->erase()
}
int spi_nor_scan(struct spi_nor *nor)
{
struct mtd_info *mtd = nor->mtd;
// read_jedec
// assign mtd hooks
// other spi-nor stuff
}
drivers/mtd/spi-nor/m25p80.c
----------------------------
struct m25p80 {
struct spi_slave *spi;
struct mtd_info mtd;
};
static int m25p80_probe(struct udevice *dev)
{
struct spi_slave *spi = dev_get_parentdata(dev);
struct spi_nor *nor = dev_get_uclass_priv(dev);
struct m25p80 *flash = dev_get_priv(dev);
struct spi_flash *sflash;
spi_nor_scan(nor);
add_mtd_device(&flash->mtd);
}
// spi-nor hooks
static const struct dm_spi_flash_ops m25p80_ops = {
.read = m25p80_read,
.write = m25p80_write,
.erase = m25p80_erase,
};
static const struct udevice_id m25p80_ids[] = {
{ .compatible = "jedec,spi-nor" },
{ }
};
U_BOOT_DRIVER(m25p80) = {
.name = "m25p80",
.id = UCLASS_SPI_NOR,
.of_match = m25p80_ids,
.probe = m25p80_probe,
.priv_auto_alloc_size = sizeof(struct m25p80),
.ops = &m25p80_ops,
};
drivers/mtd/spi-nor/fsl-qspi.c
------------------------------
struct fsl_qspi {
struct mtd_info mtd;
};
static int fsl_probe(struct udevice *dev)
{
struct spi_nor *nor = dev_get_uclass_priv(dev);
struct fsl_qspi *q = dev_get_priv(dev);
struct spi_flash *sflash;
spi_nor_scan(nor);
add_mtd_device(&q->mtd);
}
// spi-nor hooks
static const struct dm_spi_nor_ops fsl_qspi_ops = {
.read = fsl_qspi_read,
.write = fsl_qspi_write,
.erase = fsl_qspi_erase,
};
static const struct udevice_id fsl_qspi_ids[] = {
{ .compatible = "fsl,vf610-qspi" },
{ }
};
U_BOOT_DRIVER(fsl_qspi) = {
.name = "fsl_qspi",
.id = UCLASS_SPI_NOR,
.of_match = fsl_qspi_ids,
.probe = fsl_qspi_probe,
.priv_auto_alloc_size = sizeof(struct fsl_qspi),
ops = &fsl_qspi_ops,
};
About non-dm handling
*********************
We still maintain the driver similar to m25p80.c for non-dm interface
till all spi-drivers converted into dm.
[1] https://www.mail-archive.com/u-boot at lists.denx.de/msg193802.html
next reply other threads:[~2015-12-03 10:10 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-12-03 10:10 Jagan Teki [this message]
2015-12-06 15:01 ` [U-Boot] dm: Introduce SPI-NOR framework Jagan Teki
2015-12-08 2:52 ` Simon Glass
2015-12-08 15:36 ` Jagan Teki
2015-12-11 2:05 ` Simon Glass
2015-12-11 16:57 ` Jagan Teki
2015-12-14 22:14 ` Simon Glass
2015-12-17 17:06 ` Jagan Teki
2016-01-06 0:24 ` Simon Glass
2016-01-06 14:32 ` Jagan Teki
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=56601530.5030306@openedev.com \
--to=jteki@openedev.com \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.