[PATCH openbmc 3/6] linux-obmc: apply the aspeed-spi-nor controller patchset

Milton Miller II miltonm at us.ibm.com
Fri Jan 22 03:06:49 AEDT 2016


-----Jeremy Kerr <jk at ozlabs.org> wrote: -----
> On  01/20/2016 11:41PM, Milton Miller  wrote:
> 
> Hi Milton,
> 
>> Thie applies the apseed-spi-nor driver and patches the dts for
>> palmetto and barreleye when building the linux image.  It also
>> enables the config options for the driver and some file systems to
>> support the overlay filesystem stack used by obmc-phosphor-initfs.
>> 
>> It also applies the rtc month fix patch.
> 
> OK, these should be separate.
> 
> However, I'd prefer we apply the patches directly to our kernel repo.
> Can you post a patch for that, then this change should just be an
> updated kernel reference.

Actually both patches were submitted as separate pull requests to the
openbmc/linux repository.  I submitted them as patching via openbmc 
bitbake recipe to make it easier for others to test; it avoids 
having bitbake transfer a tarball for each new repository and me keeping
a merged branch with all the fixes.  Someday we can teach the git fetcher 
about reference repositories.

> 
> Some minor comments on the kernel patch though:
> 
>> +diff --git a/drivers/mtd/spi-nor/aspeed-smc.c b/drivers/mtd/spi-nor/aspeed-smc.c
>> +new file mode 100644
>> +index 0000000..2497648
>> +--- /dev/null
>> ++++ b/drivers/mtd/spi-nor/aspeed-smc.c
>> +@@ -0,0 +1,539 @@
>> ++/* ASPEED Static Memory Controller driver
>> >++ * Copyright 2015
>> ++ * Milton Miller
>> ++ *
>> ++ */
>
> Make sure you have the right copyright headers on this one.
 
This is a literal post of what I had submitted in 2015.  However I 
admit I am a noob at copyright headers and detailed advice will 
be gladly accepted.

>
>> ++#define DEBUG
> 
> Remove on the final version; we have dynamic debug enabled in the
> OpenBMC kernels.

Sure.

> 
>> ++
>> ++#include <linux/device.h>
>> ++#include <linux/io.h>
>> ++#include <linux/module.h>
>> ++#include <linux/mutex.h>
>> ++#include <linux/mtd/mtd.h>
>> ++#include <linux/mtd/partitions.h>
>> ++#include <linux/mtd/spi-nor.h>
>> ++#include <linux/of.h>
>> ++#include <linux/of_platform.h>
>> ++#include <linux/sysfs.h>
>> ++
>> ++enum smc_controller_type {
>> ++	smc_type_leg,		/* legacy register mode and map */
>> ++	smc_type_fmc,		/* new FMC 5 CEs multiple flash types */
>> ++	smc_type_smc,		/* SPI memory controller for BIOS / host */
>> ++};
>> ++
>> ++enum smc_flash_type {
>> ++	smc_type_nor = 0,	/* controller connected to nor flash */
>> ++	smc_type_nand = 1,	/* controller connected to nand flash */
>> ++	smc_type_spi = 2,	/* controller connected to spi flash */
>> ++};
>> ++
>> ++struct aspeed_smc_info {
>> ++	unsigned long nce : 3;		/* number of chip enables */
>> ++	unsigned long hasdma : 1;	/* has dma engine */
>> ++	unsigned long maxwidth : 3;	/* max width of spi bus */
>> ++	unsigned long we0 : 5;		/* we shift for ce 0 in cfg reg */
>> ++	unsigned long hastype : 1;	/* type shift for ce 0 in cfg reg */
>> ++	u8 ctl0;			/* offset in regs of ctl for ce 0 */
>> ++	u8 cfg;				/* offset in regs of cfg */
>> ++	u8 time;			/* offset in regs of timing */
>> ++};
>
> I wouldn't worry about bitfields here.

I can adapt.

> 
>> ++
>> ++#define E(_ce, _dma, _w, _ctl, _cfg, _we0, _hastype, _time, _misc) \
>> ++	.nce = _ce, .ctl0 = _ctl, .cfg = 0, .we0 = _we0, .hastype = _hastype, \
>> ++	.hasdma = _dma, .maxwidth = _w, .time = _time
>> ++
>> ++struct aspeed_smc_info aspeed_table[] = {
>> ++	[smc_type_fmc] = { E(5, 1, 4, 0x10, 0x00, 16, 1, 0x54, 0x50) },
>> ++	[smc_type_smc] = { E(1, 0, 2, 0x04, 0x00, 0,  0, 0x14, 0x10) },
>> ++};
> 
> And it'll be a little more readable to expand this:
> 
> struct aspeed_smc_info aspeed_table[] = {
> 	[smc_type_fmc] = {
> 		.nce = 5,
> 		.hasdma = 1,
> 		.maxwidth = 0x10,
> 		/* ... etc */
> 	},
> };

I think I'll go a step further, and make them separate structs, there
is not much in keeping them in an array.

> 
>> ++#if 0 /* ATTR */
>> ++static u32 spi_control_to_freq_div(u32 control)
>> ++{
>> ++	u32 sel;
>> ++
>> ++	sel = control & CONTROL_SPI_CLOCK_FREQ_SEL_MASK;
>> ++	sel >>= CONTROL_SPI_CLOCK_FREQ_SEL_SHIFT;
>> ++
>> ++	/* 16, 14, 12, 10, 8, 6, 4, 2, 15, 13, 11, 9, 7, 5, 3, 1 */
>> ++	return 16 - (((sel & 7) << 1) + ((sel & 8) >> 1));
>> ++}
>> ++
>> ++static u32 spi_control_to_dummy_bytes(u32 control)
>> ++{
>> ++
>> ++	return ((control & CONTROL_SPI_IO_DUMMY_CYCLES_LO) >>
>> ++			CONTROL_SPI_IO_DUMMY_CYCLES_LO_SHIFT) |
>> ++		((control & CONTROL_SPI_IO_DUMMY_CYCLES_HI_SHIFT) >>
>> ++			CONTROL_SPI_IO_DUMMY_CYCLES_HI_SHIFT);
>> ++}
>> ++
>> ++static size_t show_ctl_div(u32 control, char *buf)
>> ++{
>> ++	return sprintf(buf, "%u\n", spi_control_to_freq_div(control));
>> ++}
>> ++
>> ++static size_t show_ctl_dummy_bytes(u32 control, char *buf)
>> ++{
>> ++	return sprintf(buf, "%u\n", spi_control_to_dummy_bytes(control));
>> ++}
>> ++#endif /* ATTR */
> 
> There are a couple of `#if 0`-ed blocks in this patch. Was this just for
> development, or something we want to keep?

Actually I wrote them and made them compile except for the unused static 
function warning.  I intended to hook them up at least to debugfs but 
have not yet written that code.  I think they will be useful when developing 
the code to tune the transfer speeds.

So with that background, should I remove it or wait until we have done the 
next phase of tuning?


There are also a couple of functions that use more of the hardware to handle
sending the address, which should reduce the overhead.  I chose to wait to
test those until the base access was known to work.

[snip]

>> ++
>> ++const struct of_device_id aspeed_smc_matches[] = {
>> ++	{ .compatible = "aspeed,fmc", .data = &aspeed_table[smc_type_fmc] },
>> ++	{ .compatible = "aspeed,smc", .data = &aspeed_table[smc_type_smc] },
>> ++	{ }
>> ++};
>> ++MODULE_DEVICE_TABLE(of, aspeed_smc_matches);
> 
> I'd suggest grouping this with the platform_device definition below.

I put it before probe() to allow the  table to be matched to retrieve
the data pointer.  Moving it next to the the platform_driver struct 
would require a forward declaration of either the match table or the 
probe function.

> 
> But in general, all looks good to me. Ben - any thoughts about the
> smc controller implementation?
> 
> Cheers,
> Jeremy

milton



More information about the openbmc mailing list