Message ID | 20221105185911.1547847-9-j.neuschaefer@gmx.net |
---|---|
State | New |
Headers | show |
Series | Nuvoton WPCM450 FIU SPI flash controller | expand |
Hi Jonathan, I love your patch! Yet something to improve: [auto build test ERROR on next-20221104] [cannot apply to broonie-spi/for-next linusw-pinctrl/devel robh/for-next v6.1-rc3 v6.1-rc2 v6.1-rc1 linus/master v6.1-rc3] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Jonathan-Neusch-fer/Nuvoton-WPCM450-FIU-SPI-flash-controller/20221106-030021 patch link: https://lore.kernel.org/r/20221105185911.1547847-9-j.neuschaefer%40gmx.net patch subject: [PATCH 8/8] spi: wpcm-fiu: Add direct map support config: alpha-allyesconfig compiler: alpha-linux-gcc (GCC) 12.1.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/intel-lab-lkp/linux/commit/8f83cce55d2b39c9b8934c262a8d01eeebfc5ccc git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Jonathan-Neusch-fer/Nuvoton-WPCM450-FIU-SPI-flash-controller/20221106-030021 git checkout 8f83cce55d2b39c9b8934c262a8d01eeebfc5ccc # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=alpha SHELL=/bin/bash If you fix the issue, kindly add following tag where applicable | Reported-by: kernel test robot <lkp@intel.com> All errors (new ones prefixed by >>): >> drivers/spi/spi-wpcm-fiu.c:424:24: error: initialization of 'ssize_t (*)(struct spi_mem_dirmap_desc *, u64, size_t, void *)' {aka 'long int (*)(struct spi_mem_dirmap_desc *, long long unsigned int, long unsigned int, void *)'} from incompatible pointer type 'int (*)(struct spi_mem_dirmap_desc *, u64, size_t, void *)' {aka 'int (*)(struct spi_mem_dirmap_desc *, long long unsigned int, long unsigned int, void *)'} [-Werror=incompatible-pointer-types] 424 | .dirmap_read = wpcm_fiu_direct_read, | ^~~~~~~~~~~~~~~~~~~~ drivers/spi/spi-wpcm-fiu.c:424:24: note: (near initialization for 'wpcm_fiu_mem_ops.dirmap_read') cc1: some warnings being treated as errors vim +424 drivers/spi/spi-wpcm-fiu.c 418 419 static const struct spi_controller_mem_ops wpcm_fiu_mem_ops = { 420 .adjust_op_size = wpcm_fiu_adjust_op_size, 421 .supports_op = wpcm_fiu_supports_op, 422 .exec_op = wpcm_fiu_exec_op, 423 .dirmap_create = wpcm_fiu_dirmap_create, > 424 .dirmap_read = wpcm_fiu_direct_read, 425 }; 426
On Sun, Nov 06, 2022 at 05:35:24AM +0800, kernel test robot wrote: > >> drivers/spi/spi-wpcm-fiu.c:424:24: error: initialization of 'ssize_t (*)(struct spi_mem_dirmap_desc *, u64, size_t, void *)' {aka 'long int (*)(struct spi_mem_dirmap_desc *, long long unsigned int, long unsigned int, void *)'} from incompatible pointer type 'int (*)(struct spi_mem_dirmap_desc *, u64, size_t, void *)' {aka 'int (*)(struct spi_mem_dirmap_desc *, long long unsigned int, long unsigned int, void *)'} [-Werror=incompatible-pointer-types] > 424 | .dirmap_read = wpcm_fiu_direct_read, > | ^~~~~~~~~~~~~~~~~~~~ > drivers/spi/spi-wpcm-fiu.c:424:24: note: (near initialization for 'wpcm_fiu_mem_ops.dirmap_read') > cc1: some warnings being treated as errors Indeed. I'll fix it.
diff --git a/drivers/spi/spi-wpcm-fiu.c b/drivers/spi/spi-wpcm-fiu.c index d68693d4cd8bd..eda46c766ad9d 100644 --- a/drivers/spi/spi-wpcm-fiu.c +++ b/drivers/spi/spi-wpcm-fiu.c @@ -51,10 +51,16 @@ */ #define UMA_WAIT_ITERATIONS 100 +/* The memory-mapped view of flash is 16 MiB long */ +#define MAX_MEMORY_SIZE_PER_CS (16 << 20) +#define MAX_MEMORY_SIZE_TOTAL (4 * MAX_MEMORY_SIZE_PER_CS) + struct wpcm_fiu_spi { struct device *dev; struct clk *clk; void __iomem *regs; + void __iomem *memory; + size_t memory_size; struct regmap *shm_regmap; }; @@ -367,14 +373,64 @@ static int wpcm_fiu_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op) return 0; } +static int wpcm_fiu_dirmap_create(struct spi_mem_dirmap_desc *desc) +{ + struct wpcm_fiu_spi *fiu = spi_controller_get_devdata(desc->mem->spi->controller); + int cs = desc->mem->spi->chip_select; + + if (desc->info.op_tmpl.data.dir != SPI_MEM_DATA_IN) + return -ENOTSUPP; + + /* + * Unfortunately, FIU only supports a 16 MiB direct mapping window (per + * attached flash chip), but the SPI MEM core doesn't support partial + * direct mappings. This means that we can't support direct mapping on + * flashes that are bigger than 16 MiB. + */ + if (desc->info.offset + desc->info.length > MAX_MEMORY_SIZE_PER_CS) + return -ENOTSUPP; + + /* Don't read past the memory window */ + if (cs * MAX_MEMORY_SIZE_PER_CS + desc->info.offset + desc->info.length > fiu->memory_size) + return -ENOTSUPP; + + return 0; +} + +static int wpcm_fiu_direct_read(struct spi_mem_dirmap_desc *desc, u64 offs, size_t len, void *buf) +{ + struct wpcm_fiu_spi *fiu = spi_controller_get_devdata(desc->mem->spi->controller); + int cs = desc->mem->spi->chip_select; + + if (offs >= MAX_MEMORY_SIZE_PER_CS) + return -ENOTSUPP; + + offs += cs * MAX_MEMORY_SIZE_PER_CS; + + if (!fiu->memory || offs >= fiu->memory_size) + return -ENOTSUPP; + + len = min_t(size_t, len, fiu->memory_size - offs); + memcpy_fromio(buf, fiu->memory + offs, len); + + return len; +} + static const struct spi_controller_mem_ops wpcm_fiu_mem_ops = { .adjust_op_size = wpcm_fiu_adjust_op_size, .supports_op = wpcm_fiu_supports_op, .exec_op = wpcm_fiu_exec_op, + .dirmap_create = wpcm_fiu_dirmap_create, + .dirmap_read = wpcm_fiu_direct_read, }; static void wpcm_fiu_hw_init(struct wpcm_fiu_spi *fiu) { + /* Configure memory-mapped flash access */ + writeb(FIU_BURST_CFG_R16, fiu->regs + FIU_BURST_BFG); + writeb(MAX_MEMORY_SIZE_TOTAL / (512 << 10), fiu->regs + FIU_CFG); + writeb(MAX_MEMORY_SIZE_PER_CS / (512 << 10) | BIT(6), fiu->regs + FIU_SPI_FL_CFG); + /* Deassert all manually asserted chip selects */ writeb(0x0f, fiu->regs + FIU_UMA_ECTS); } @@ -404,6 +460,14 @@ static int wpcm_fiu_probe(struct platform_device *pdev) if (IS_ERR(fiu->clk)) return PTR_ERR(fiu->clk); + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "memory"); + fiu->memory = devm_ioremap_resource(dev, res); + fiu->memory_size = min_t(size_t, resource_size(res), MAX_MEMORY_SIZE_TOTAL); + if (IS_ERR(fiu->regs)) { + dev_err(dev, "Failed to map flash memory window\n"); + return PTR_ERR(fiu->memory); + } + fiu->shm_regmap = syscon_regmap_lookup_by_phandle_optional(dev->of_node, "nuvoton,shm"); wpcm_fiu_hw_init(fiu);
Besides software controlled SPI transfers (UMA, "user mode access"), FIU also supports a 16 MiB mapping window per attached flash chip. This patch implements direct mapped read access, to speed up flash reads. Without direct mapping: # time dd if=/dev/mtd0ro of=dump bs=1M 16+0 records in 16+0 records out real 1m 47.74s user 0m 0.00s sys 1m 47.75s With direct mapping: # time dd if=/dev/mtd0ro of=dump bs=1M 16+0 records in 16+0 records out real 0m 30.81s user 0m 0.00s sys 0m 30.81s Signed-off-by: Jonathan Neuschäfer <j.neuschaefer@gmx.net> --- drivers/spi/spi-wpcm-fiu.c | 64 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) -- 2.35.1