[PATCH 1/3] firmware: add lpc18xx boot rom driver
Vladimir Zapolskiy
vz at mleia.com
Thu Oct 6 18:42:23 PDT 2016
Hi Joachim,
On 13.09.2016 22:51, Joachim Eastwood wrote:
> Firmware driver for the boot ROM found on all NXP LPC18xx/43xx
> devices. This driver makes it possible to retrieve device specific
> information from either the ROM via API calls or from OTP memory.
>
> The boot ROM contains several APIs for on-chip devices. Note that not
> all APIs are available on all devices. The API to retrieve device
> information and internal Flash programming (IAP) is only available on
> devices with Flash. Flashless devices retrieve device information from
> OTP memory. The CHIPID register in CREG (syscon) is used to check if
> IAP is available.
>
> For now this driver is only used to expose device information via a
> 'SoC device'. Linux API for the IAP and OTP will be added later. These
> two APIs will be used by a Flash MTD driver and a OTP NVMEM driver to
> program the memory.
>
> Signed-off-by: Joachim Eastwood <manabian at gmail.com>
please feel free to add to the series my
Tested-by: Vladimir Zapolskiy <vz at mleia.com>
Reviewed-by: Vladimir Zapolskiy <vz at mleia.com>
I tested the change on a board powered by LPC4357.
Nevertheless I have some nitpicks for your consideration.
And the first one is that I'm not totally convinced that drivers/firmware
is the proper place for the driver, I tend to think that it might be
a good time to create drivers/soc/nxp/
> ---
> drivers/firmware/Kconfig | 12 ++
> drivers/firmware/Makefile | 1 +
> drivers/firmware/nxp_lpc_boot_rom.c | 411 ++++++++++++++++++++++++++++++++++++
> 3 files changed, 424 insertions(+)
> create mode 100644 drivers/firmware/nxp_lpc_boot_rom.c
>
[snip]
> +/* LPC18xx/43xx CREG (syscon) defines */
> +#define LPC18XX_CREG_CHIPID 0x200
> +#define LPC18XX_FLASH_CHIPID0 0x4284e02b
> +#define LPC18XX_FLASH_CHIPID1 0x7284e02b
> +#define LPC18XX_FLASHLESS_CHIPID0 0x5284e02b
> +#define LPC18XX_FLASHLESS_CHIPID1 0x6284e02b
> +#define LPC43XX_FLASH_CHIPID0 0x4906002b
> +#define LPC43XX_FLASH_CHIPID1 0x7906002b
> +#define LPC43XX_FLASHLESS_CHIPID0 0x5906002b
> +#define LPC43XX_FLASHLESS_CHIPID1 0x6906002b
> +
> +#define NXP_PART_LPC(_num, _id0, _id1, _sz0, _sz1) \
> + { \
> + .name = "LPC"#_num, \
> + .id[0] = _id0, .id[1] = _id1, \
> + .flash_size[0] = _sz0 * 1024, \
> + .flash_size[1] = _sz1 * 1024, \
> + }
> +
> +
checkpatch complains:
CHECK: Please don't use multiple blank lines
#145: FILE: drivers/firmware/nxp_lpc_boot_rom.c:75:
+
+
> +struct nxp_lpc_part {
> + const char *name;
> + u16 flash_size[2];
flash_size[2] is set by NXP_PART_LPC() macro but unused, however
in my build environment (W=1 and sparse checks) I get tons of
legitimate compile time warnings:
drivers/firmware/nxp_lpc_boot_rom.c:93:9: warning: cast truncates bits from constant value (80000 becomes 0)
drivers/firmware/nxp_lpc_boot_rom.c:93:9: warning: cast truncates bits from constant value (80000 becomes 0)
drivers/firmware/nxp_lpc_boot_rom.c:94:9: warning: cast truncates bits from constant value (80000 becomes 0)
drivers/firmware/nxp_lpc_boot_rom.c:94:9: warning: cast truncates bits from constant value (80000 becomes 0)
....
drivers/firmware/nxp_lpc_boot_rom.c:93:2: warning: large integer implicitly truncated to unsigned type [-Woverflow]
NXP_PART_LPC(1857, 0xf001d830, 0x00, 512, 512),
^
drivers/firmware/nxp_lpc_boot_rom.c:93:2: warning: large integer implicitly truncated to unsigned type [-Woverflow]
drivers/firmware/nxp_lpc_boot_rom.c:94:2: warning: large integer implicitly truncated to unsigned type [-Woverflow]
NXP_PART_LPC(18S57, 0xf001d860, 0x00, 512, 512),
^
....
and so on.
Please consider either to store flash size in kB or change storage type to u32.
> + u32 id[2];
> +};
> +
> +static const struct nxp_lpc_part nxp_lpc_parts[] = {
> + /* LPC18xx Flashless parts */
> + NXP_PART_LPC(1850, 0xf000d830, 0x00, 0, 0),
> + NXP_PART_LPC(18S50, 0xf000d860, 0x00, 0, 0),
> + NXP_PART_LPC(1830, 0xf000da30, 0x00, 0, 0),
> + NXP_PART_LPC(18S30, 0xf000da60, 0x00, 0, 0),
> + NXP_PART_LPC(1820, 0xf00adb3c, 0x00, 0, 0),
> + NXP_PART_LPC(18S20, 0xf00adb6c, 0x00, 0, 0),
> + NXP_PART_LPC(1810, 0xf00b5b3f, 0x00, 0, 0),
> + NXP_PART_LPC(18S10, 0xf00b5b6f, 0x00, 0, 0),
> + /* LPC18xx Flash parts */
> + NXP_PART_LPC(1857, 0xf001d830, 0x00, 512, 512),
> + NXP_PART_LPC(18S57, 0xf001d860, 0x00, 512, 512),
> + NXP_PART_LPC(1853, 0xf001d830, 0x44, 256, 256),
> + NXP_PART_LPC(1837, 0xf001da30, 0x00, 512, 512),
> + NXP_PART_LPC(18S37, 0xf001d860, 0x00, 512, 512),
> + NXP_PART_LPC(1833, 0xf001da30, 0x44, 256, 256),
> + NXP_PART_LPC(1827, 0xf001db3c, 0x00, 512, 512),
> + NXP_PART_LPC(1825, 0xf001db3c, 0x22, 384, 384),
> + NXP_PART_LPC(1823, 0xf00bdb3c, 0x44, 256, 256),
> + NXP_PART_LPC(1822, 0xf00bdb3c, 0x80, 512, 0),
> + NXP_PART_LPC(1817, 0xf001db3f, 0x00, 512, 512),
> + NXP_PART_LPC(1815, 0xf001db3f, 0x22, 384, 384),
> + NXP_PART_LPC(1813, 0xf00bdb3f, 0x44, 256, 256),
> + NXP_PART_LPC(1812, 0xf00bdb3f, 0x80, 512, 0),
> + /* LPC43xx Flashless parts */
> + NXP_PART_LPC(4370, 0x00000030, 0x00, 0, 0), /* LBGA256 */
> + NXP_PART_LPC(4370, 0x00000230, 0x00, 0, 0), /* TFBGA100 */
> + NXP_PART_LPC(43S70, 0x00000060, 0x00, 0, 0),
> + NXP_PART_LPC(4350, 0xa0000830, 0x00, 0, 0),
> + NXP_PART_LPC(43S50, 0xa0000860, 0x00, 0, 0),
> + NXP_PART_LPC(4330, 0xa0000a30, 0x00, 0, 0),
> + NXP_PART_LPC(43S30, 0xa0000a60, 0x00, 0, 0),
> + NXP_PART_LPC(4320, 0xa000cb3c, 0x00, 0, 0),
> + NXP_PART_LPC(43S20, 0xa000cb6c, 0x00, 0, 0),
> + NXP_PART_LPC(4310, 0xa00acb3f, 0x00, 0, 0),
> + /* LPC43xx parts with Flash */
> + NXP_PART_LPC(4367, 0x8001c030, 0x00, 512, 512),
> + NXP_PART_LPC(43S67, 0x8001c060, 0x00, 512, 512),
> + NXP_PART_LPC(4357, 0xa001c830, 0x00, 512, 512),
> + NXP_PART_LPC(43S57, 0xa001c860, 0x00, 512, 512), /* LBGA256 */
> + NXP_PART_LPC(43S57, 0xa001ca60, 0x00, 512, 512), /* LQFP208 */
> + NXP_PART_LPC(4353, 0xa001c830, 0x44, 256, 256),
> + NXP_PART_LPC(4337, 0xa001ca30, 0x00, 512, 512),
> + NXP_PART_LPC(43S37, 0xa001ca60, 0x00, 512, 512),
> + NXP_PART_LPC(4333, 0xa001ca30, 0x44, 256, 256),
> + NXP_PART_LPC(4327, 0xa001cb3c, 0x00, 512, 512),
> + NXP_PART_LPC(4325, 0xa001cb3c, 0x22, 384, 384),
> + NXP_PART_LPC(4323, 0xa00bcb3c, 0x44, 256, 256),
> + NXP_PART_LPC(4322, 0xa00bcb3c, 0x80, 512, 0),
> + NXP_PART_LPC(4317, 0xa001cb3f, 0x00, 512, 512),
> + NXP_PART_LPC(4315, 0xa001cb3f, 0x22, 384, 384),
> + NXP_PART_LPC(4313, 0xa00bcb3f, 0x44, 256, 256),
> + NXP_PART_LPC(4312, 0xa00bcb3f, 0x80, 512, 0),
> +};
> +
> +struct iap_rom {
> + void (*entry)(u32 *, u32 *);
> +};
Here it might be simpler to declare a typedef instead of a struct.
> +struct nxp_rom_api {
> + struct device *dev;
> + void __iomem *rom;
> +
> + bool has_iap;
> + struct iap_rom iap;
> + spinlock_t lock;
> +
> + const struct nxp_lpc_part *part;
> + const char *partname;
> + u32 boot_version;
> +
> + struct soc_device *soc_dev;
> + struct soc_device_attribute soc_dev_attr;
> +};
> +
--
With best wishes,
Vladimir
More information about the linux-arm-kernel
mailing list