mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-10 23:24:38 +00:00
First set of u-boot-atmel features for 2020.04 cycle
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABAgAGBQJeFDfVAAoJEB6zHgIOrC/IKfsH/2cUfXuc9IgA7L90L3g7htlS zLAQSC8Xk0WbgbmBJh/lq6zFWj2Mu2yfkZqRzwN8bHkmOPq40F+pEAszVtjH77HM FpSjMSDVWfNXuhmoiS571dehA0TGi1b2kknrAXqpOwVuMRncMCwaPi8yZYZSGlSV VzMtguQxD0sZg4oMZVde3tCd41smPTPNDjzLZnXdLa0b09+EtW6enGuk3vzXlS/8 QUT68wUzkeoptJhf3pQ3BXNvkFwdNdYJ74uevDmkAYtvxyl10WNykcwYmH50Q9qq 9plF11EizmTHlj16rWpZLx66RP0s4pziKaeGMr6S8uln33Cr9N496wPqtuDBnvA= =FYPj -----END PGP SIGNATURE----- Merge tag 'u-boot-atmel-2020.04-a' of https://gitlab.denx.de/u-boot/custodians/u-boot-atmel First set of u-boot-atmel features for 2020.04 cycle This feature set is a patch series from Tudor Ambarus which includes parsing of the spi flash SFDP parser for SST flashes, and using those tables to retrieve unique saved per device MAC address. This is then used as base mac address on the SAMA5D2 Wireless SOM EK board.
This commit is contained in:
commit
ac0f978afd
8 changed files with 184 additions and 2 deletions
|
@ -40,6 +40,7 @@ void configure_ddrcfg_input_buffers(bool open);
|
|||
#endif
|
||||
|
||||
int at91_set_ethaddr(int offset);
|
||||
void at91_spi_nor_set_ethaddr(void);
|
||||
int at91_video_show_board_info(void);
|
||||
|
||||
#endif /* AT91_COMMON_H */
|
||||
|
|
|
@ -5,4 +5,5 @@
|
|||
|
||||
obj-y += board.o
|
||||
obj-$(CONFIG_I2C_EEPROM) += mac_eeprom.o
|
||||
obj-$(CONFIG_SPI_FLASH_SFDP_SUPPORT) += mac-spi-nor.o
|
||||
obj-$(CONFIG_DM_VIDEO) += video_display.o
|
||||
|
|
127
board/atmel/common/mac-spi-nor.c
Normal file
127
board/atmel/common/mac-spi-nor.c
Normal file
|
@ -0,0 +1,127 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2019 Microchip Technology Inc. and its subsidiaries
|
||||
*
|
||||
* Author: Tudor Ambarus <tudor.ambarus@microchip.com>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <env.h>
|
||||
#include <linux/mtd/spi-nor.h>
|
||||
#include <netdev.h>
|
||||
|
||||
#define ETH_ADDR_SIZE 6
|
||||
|
||||
#ifdef CONFIG_SPI_FLASH_SST
|
||||
#define SFDP_MICROCHIP_MANUF_ID 0xbf
|
||||
#define SFDP_MICROCHIP_MEM_TYPE 0x26
|
||||
#define SFDP_MICROCHIP_DEV_ID 0x43
|
||||
|
||||
#define SFDP_MICROCHIP_EUI_OFFSET 0x60
|
||||
#define SFDP_MICROCHIP_EUI48 0x30
|
||||
|
||||
struct sst26vf064beui {
|
||||
u8 manufacturer_id;
|
||||
u8 memory_type;
|
||||
u8 device_id;
|
||||
u8 reserved;
|
||||
};
|
||||
|
||||
/**
|
||||
* sst26vf064beui_check() - Check the validity of the EUI-48 information from
|
||||
* the sst26vf064beui SPI NOR Microchip SFDP table.
|
||||
* @manufacturer_sfdp: pointer to the Microchip manufacturer specific SFDP
|
||||
* table.
|
||||
*
|
||||
* Return: 0 on success, -errno otherwise.
|
||||
*/
|
||||
static int sst26vf064beui_check(const u8 *manufacturer_sfdp)
|
||||
{
|
||||
struct sst26vf064beui *sst26vf064beui =
|
||||
(struct sst26vf064beui *)manufacturer_sfdp;
|
||||
|
||||
if (sst26vf064beui->manufacturer_id != SFDP_MICROCHIP_MANUF_ID)
|
||||
return -EINVAL;
|
||||
|
||||
if (sst26vf064beui->memory_type != SFDP_MICROCHIP_MEM_TYPE)
|
||||
return -EINVAL;
|
||||
|
||||
if (sst26vf064beui->device_id != SFDP_MICROCHIP_DEV_ID)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* Check if the EUI-48 MAC address is programmed in the next six address
|
||||
* locations.
|
||||
*/
|
||||
if (manufacturer_sfdp[SFDP_MICROCHIP_EUI_OFFSET] !=
|
||||
SFDP_MICROCHIP_EUI48)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* sst26vf064beui_get_ethaddr() - Get the ethernet address from the
|
||||
* sst26vf064beui SPI NOR Microchip SFDP table.
|
||||
* @manufacturer_sfdp: pointer to the Microchip manufacturer specific SFDP
|
||||
* table.
|
||||
* @ethaddr: pointer where to fill the ethernet address
|
||||
* @size: size of the ethernet address.
|
||||
*
|
||||
* Return: 0 on success, -errno otherwise.
|
||||
*/
|
||||
static int sst26vf064beui_get_ethaddr(const u8 *manufacturer_sfdp,
|
||||
u8 *ethaddr, size_t size)
|
||||
{
|
||||
u64 eui_table[2];
|
||||
u64 *p = (u64 *)&manufacturer_sfdp[SFDP_MICROCHIP_EUI_OFFSET];
|
||||
int i, ret;
|
||||
|
||||
ret = sst26vf064beui_check(manufacturer_sfdp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
eui_table[i] = le64_to_cpu(p[i]);
|
||||
|
||||
/* Ethaddr starts at offset one. */
|
||||
memcpy(ethaddr, &((u8 *)eui_table)[1], size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* at91_spi_nor_set_ethaddr() - Retrieve and set the ethernet address from the
|
||||
* SPI NOR manufacturer specific SFDP table.
|
||||
*/
|
||||
void at91_spi_nor_set_ethaddr(void)
|
||||
{
|
||||
struct udevice *dev;
|
||||
struct spi_nor *nor;
|
||||
const char *ethaddr_name = "ethaddr";
|
||||
u8 ethaddr[ETH_ADDR_SIZE] = {0};
|
||||
|
||||
if (env_get(ethaddr_name))
|
||||
return;
|
||||
|
||||
if (uclass_first_device_err(UCLASS_SPI_FLASH, &dev))
|
||||
return;
|
||||
|
||||
nor = dev_get_uclass_priv(dev);
|
||||
if (!nor)
|
||||
return;
|
||||
|
||||
if (!nor->manufacturer_sfdp)
|
||||
return;
|
||||
|
||||
#ifdef CONFIG_SPI_FLASH_SST
|
||||
if (sst26vf064beui_get_ethaddr(nor->manufacturer_sfdp, ethaddr,
|
||||
ETH_ADDR_SIZE))
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (is_valid_ethaddr(ethaddr))
|
||||
eth_env_set_enetaddr(ethaddr_name, ethaddr);
|
||||
}
|
|
@ -68,6 +68,9 @@ int board_init(void)
|
|||
#ifdef CONFIG_MISC_INIT_R
|
||||
int misc_init_r(void)
|
||||
{
|
||||
#ifdef CONFIG_SPI_FLASH_SFDP_SUPPORT
|
||||
at91_spi_nor_set_ethaddr();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -67,8 +67,12 @@ CONFIG_MMC_SDHCI=y
|
|||
CONFIG_MMC_SDHCI_ATMEL=y
|
||||
CONFIG_MTD=y
|
||||
CONFIG_DM_SPI_FLASH=y
|
||||
CONFIG_SF_DEFAULT_BUS=2
|
||||
CONFIG_SF_DEFAULT_SPEED=50000000
|
||||
CONFIG_SPI_FLASH_SFDP_SUPPORT=y
|
||||
CONFIG_SPI_FLASH_ATMEL=y
|
||||
CONFIG_SPI_FLASH_MACRONIX=y
|
||||
CONFIG_SPI_FLASH_SPANSION=y
|
||||
CONFIG_SPI_FLASH_STMICRO=y
|
||||
CONFIG_SPI_FLASH_SST=y
|
||||
CONFIG_PHY_MICREL=y
|
||||
|
@ -83,6 +87,7 @@ CONFIG_DEBUG_UART_ANNOUNCE=y
|
|||
CONFIG_ATMEL_USART=y
|
||||
CONFIG_SPI=y
|
||||
CONFIG_DM_SPI=y
|
||||
CONFIG_ATMEL_QSPI=y
|
||||
CONFIG_TIMER=y
|
||||
CONFIG_SPL_TIMER=y
|
||||
CONFIG_ATMEL_PIT_TIMER=y
|
||||
|
|
|
@ -80,6 +80,7 @@ CONFIG_MTD=y
|
|||
CONFIG_DM_SPI_FLASH=y
|
||||
CONFIG_SF_DEFAULT_BUS=2
|
||||
CONFIG_SF_DEFAULT_SPEED=50000000
|
||||
CONFIG_SPI_FLASH_SFDP_SUPPORT=y
|
||||
CONFIG_SPI_FLASH_ATMEL=y
|
||||
CONFIG_SPI_FLASH_MACRONIX=y
|
||||
CONFIG_SPI_FLASH_SPANSION=y
|
||||
|
|
|
@ -1594,6 +1594,7 @@ struct sfdp_parameter_header {
|
|||
|
||||
#define SFDP_BFPT_ID 0xff00 /* Basic Flash Parameter Table */
|
||||
#define SFDP_SECTOR_MAP_ID 0xff81 /* Sector Map Table */
|
||||
#define SFDP_SST_ID 0x01bf /* Manufacturer specific Table */
|
||||
|
||||
#define SFDP_SIGNATURE 0x50444653U
|
||||
#define SFDP_JESD216_MAJOR 1
|
||||
|
@ -1973,6 +1974,34 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* spi_nor_parse_microchip_sfdp() - parse the Microchip manufacturer specific
|
||||
* SFDP table.
|
||||
* @nor: pointer to a 'struct spi_nor'.
|
||||
* @param_header: pointer to the SFDP parameter header.
|
||||
*
|
||||
* Return: 0 on success, -errno otherwise.
|
||||
*/
|
||||
static int
|
||||
spi_nor_parse_microchip_sfdp(struct spi_nor *nor,
|
||||
const struct sfdp_parameter_header *param_header)
|
||||
{
|
||||
size_t size;
|
||||
u32 addr;
|
||||
int ret;
|
||||
|
||||
size = param_header->length * sizeof(u32);
|
||||
addr = SFDP_PARAM_HEADER_PTP(param_header);
|
||||
|
||||
nor->manufacturer_sfdp = devm_kmalloc(nor->dev, size, GFP_KERNEL);
|
||||
if (!nor->manufacturer_sfdp)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = spi_nor_read_sfdp(nor, addr, size, nor->manufacturer_sfdp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* spi_nor_parse_sfdp() - parse the Serial Flash Discoverable Parameters.
|
||||
* @nor: pointer to a 'struct spi_nor'
|
||||
|
@ -2069,12 +2098,25 @@ static int spi_nor_parse_sfdp(struct spi_nor *nor,
|
|||
dev_info(dev, "non-uniform erase sector maps are not supported yet.\n");
|
||||
break;
|
||||
|
||||
case SFDP_SST_ID:
|
||||
err = spi_nor_parse_microchip_sfdp(nor, param_header);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (err)
|
||||
goto exit;
|
||||
if (err) {
|
||||
dev_warn(dev, "Failed to parse optional parameter table: %04x\n",
|
||||
SFDP_PARAM_HEADER_ID(param_header));
|
||||
/*
|
||||
* Let's not drop all information we extracted so far
|
||||
* if optional table parsers fail. In case of failing,
|
||||
* each optional parser is responsible to roll back to
|
||||
* the previously known spi_nor data.
|
||||
*/
|
||||
err = 0;
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
|
|
|
@ -261,6 +261,7 @@ struct flash_info;
|
|||
* @lock: the lock for the read/write/erase/lock/unlock operations
|
||||
* @dev: point to a spi device, or a spi nor controller device.
|
||||
* @info: spi-nor part JDEC MFR id and other info
|
||||
* @manufacturer_sfdp: manufacturer specific SFDP table
|
||||
* @page_size: the page size of the SPI NOR
|
||||
* @addr_width: number of address bytes
|
||||
* @erase_opcode: the opcode for erasing a sector
|
||||
|
@ -299,6 +300,7 @@ struct spi_nor {
|
|||
struct udevice *dev;
|
||||
struct spi_slave *spi;
|
||||
const struct flash_info *info;
|
||||
u8 *manufacturer_sfdp;
|
||||
u32 page_size;
|
||||
u8 addr_width;
|
||||
u8 erase_opcode;
|
||||
|
|
Loading…
Reference in a new issue