Merge git://git.denx.de/u-boot-dm

This commit is contained in:
Tom Rini
2014-10-22 13:51:45 -04:00
145 changed files with 7919 additions and 2273 deletions

View File

@@ -21,6 +21,17 @@
#define CONFIG_MACH_TYPE 4273
#define CONFIG_SYS_HZ 1000
#ifndef CONFIG_SPL_BUILD
#define CONFIG_DM
#define CONFIG_CMD_DM
#define CONFIG_DM_GPIO
#define CONFIG_CMD_GPIO
#define CONFIG_DM_SERIAL
#define CONFIG_SYS_MALLOC_F_LEN (1 << 10)
#endif
/* Display information on boot */
#define CONFIG_DISPLAY_CPUINFO
#define CONFIG_DISPLAY_BOARDINFO

View File

@@ -17,6 +17,13 @@
#include <linux/sizes.h>
#define CONFIG_SYS_GENERIC_BOARD
#define CONFIG_DM
#define CONFIG_CMD_DM
#define CONFIG_DM_GPIO
#define CONFIG_DM_SERIAL
#define CONFIG_DM_SPI
#define CONFIG_DM_SPI_FLASH
#define CONFIG_ARCH_CPU_INIT
#define CONFIG_DISPLAY_CPUINFO
#define CONFIG_DISPLAY_BOARDINFO

View File

@@ -38,6 +38,7 @@
#define CONFIG_POWER_TPS65090_EC
#define CONFIG_CROS_EC_SPI /* Support CROS_EC over SPI */
#define CONFIG_DM_CROS_EC
#define CONFIG_USB_XHCI
#define CONFIG_USB_XHCI_EXYNOS

View File

@@ -31,6 +31,11 @@
*/
#define CONFIG_MACH_TYPE MACH_TYPE_BCM2708
/* Enable driver model */
#define CONFIG_DM
#define CONFIG_CMD_DM
#define CONFIG_DM_GPIO
/* Memory layout */
#define CONFIG_NR_DRAM_BANKS 1
#define CONFIG_SYS_SDRAM_BASE 0x00000000

View File

@@ -276,6 +276,8 @@
#define CONFIG_SYS_I2C_SOFT_SPEED 50000
#define CONFIG_SYS_I2C_SOFT_SLAVE 0x7F
#define CONFIG_I2C_MULTI_BUS
#define CONFIG_SYS_I2C_INIT_BOARD
#define CONFIG_SYS_MAX_I2C_BUS 7
#define CONFIG_USB_GADGET
#define CONFIG_USB_GADGET_S3C_UDC_OTG
@@ -286,4 +288,10 @@
#define CONFIG_OF_LIBFDT
#define CONFIG_SYS_GENERIC_BOARD
#define CONFIG_DM
#define CONFIG_CMD_DM
#define CONFIG_DM_GPIO
#define CONFIG_DM_SERIAL
#endif /* __CONFIG_H */

View File

@@ -187,17 +187,7 @@
* SPI Settings
*/
#define CONFIG_SOFT_SPI
#define CONFIG_SOFT_SPI_MODE SPI_MODE_3
#define CONFIG_SOFT_SPI_GPIO_SCLK EXYNOS4_GPIO_Y31
#define CONFIG_SOFT_SPI_GPIO_MOSI EXYNOS4_GPIO_Y33
#define CONFIG_SOFT_SPI_GPIO_MISO EXYNOS4_GPIO_Y30
#define CONFIG_SOFT_SPI_GPIO_CS EXYNOS4_GPIO_Y43
#define SPI_DELAY udelay(1)
#undef SPI_INIT
#define SPI_SCL(bit) universal_spi_scl(bit)
#define SPI_SDA(bit) universal_spi_sda(bit)
#define SPI_READ universal_spi_read()
#ifndef __ASSEMBLY__
void universal_spi_scl(int bit);
void universal_spi_sda(int bit);

View File

@@ -259,7 +259,6 @@
#define I2C_MOSI 0x00004000 /* PD 17: Master Out, Slave In */
#define I2C_MISO 0x00008000 /* PD 16: Master In, Slave Out */
#undef SPI_INIT /* no port initialization needed */
#define SPI_READ ((immr->im_ioport.iop_pdatd & I2C_MISO) != 0)
#define SPI_SDA(bit) do { \
if(bit) immr->im_ioport.iop_pdatd |= I2C_MOSI; \

View File

@@ -32,6 +32,7 @@
#define CONFIG_DM_GPIO
#define CONFIG_DM_TEST
#define CONFIG_DM_SERIAL
#define CONFIG_DM_CROS_EC
#define CONFIG_SYS_STDIO_DEREGISTER
@@ -97,8 +98,8 @@
#define CONFIG_CMD_SF_TEST
#define CONFIG_CMD_SPI
#define CONFIG_SPI_FLASH
#define CONFIG_OF_SPI
#define CONFIG_OF_SPI_FLASH
#define CONFIG_DM_SPI
#define CONFIG_DM_SPI_FLASH
#define CONFIG_SPI_FLASH_ATMEL
#define CONFIG_SPI_FLASH_EON
#define CONFIG_SPI_FLASH_GIGADEVICE

View File

@@ -223,4 +223,10 @@
#define CONFIG_OF_LIBFDT
#define CONFIG_SYS_GENERIC_BOARD
#define CONFIG_DM
#define CONFIG_CMD_DM
#define CONFIG_DM_GPIO
#define CONFIG_DM_SERIAL
#endif /* __CONFIG_H */

View File

@@ -59,7 +59,7 @@
BOARD_EXTRA_ENV_SETTINGS
#if defined(CONFIG_TEGRA20_SFLASH) || defined(CONFIG_TEGRA20_SLINK) || defined(CONFIG_TEGRA114_SPI)
#define CONFIG_FDT_SPI
#define CONFIG_TEGRA_SPI
#endif
/* overrides for SPL build here */

View File

@@ -24,6 +24,8 @@
#ifndef CONFIG_SPL_BUILD
#define CONFIG_DM_SERIAL
#endif
#define CONFIG_DM_SPI
#define CONFIG_DM_SPI_FLASH
#define CONFIG_SYS_TIMER_RATE 1000000
#define CONFIG_SYS_TIMER_COUNTER NV_PA_TMRUS_BASE

View File

@@ -99,7 +99,6 @@
#define CONFIG_VIDEO_BMP_GZIP
#define CONFIG_VIDEO_BMP_RLE8
#define CONFIG_SYS_VIDEO_LOGO_MAX_SIZE (2 << 20)
#undef SPI_INIT
#define SPI_DELAY udelay(10)
#define SPI_SDA(val) zipitz2_spi_sda(val)

View File

@@ -14,6 +14,7 @@
#include <fdtdec.h>
#include <cros_ec_message.h>
#ifndef CONFIG_DM_CROS_EC
/* Which interface is the device on? */
enum cros_ec_interface_t {
CROS_EC_IF_NONE,
@@ -22,9 +23,13 @@ enum cros_ec_interface_t {
CROS_EC_IF_LPC, /* Intel Low Pin Count interface */
CROS_EC_IF_SANDBOX,
};
#endif
/* Our configuration information */
struct cros_ec_dev {
#ifdef CONFIG_DM_CROS_EC
struct udevice *dev; /* Transport device */
#else
enum cros_ec_interface_t interface;
struct spi_slave *spi; /* Our SPI slave, if using SPI */
int node; /* Our node */
@@ -33,6 +38,7 @@ struct cros_ec_dev {
unsigned int addr; /* Device address (for I2C) */
unsigned int bus_num; /* Bus number (for I2C) */
unsigned int max_frequency; /* Maximum interface frequency */
#endif
struct fdt_gpio_state ec_int; /* GPIO used as EC interrupt line */
int protocol_version; /* Protocol version to use */
int optimise_flash_write; /* Don't write erased flash blocks */
@@ -233,6 +239,22 @@ int cros_ec_flash_update_rw(struct cros_ec_dev *dev,
*/
struct cros_ec_dev *board_get_cros_ec_dev(void);
#ifdef CONFIG_DM_CROS_EC
struct dm_cros_ec_ops {
int (*check_version)(struct udevice *dev);
int (*command)(struct udevice *dev, uint8_t cmd, int cmd_version,
const uint8_t *dout, int dout_len,
uint8_t **dinp, int din_len);
int (*packet)(struct udevice *dev, int out_bytes, int in_bytes);
};
#define dm_cros_ec_get_ops(dev) \
((struct dm_cros_ec_ops *)(dev)->driver->ops)
int cros_ec_register(struct udevice *dev);
#else /* !CONFIG_DM_CROS_EC */
/* Internal interfaces */
int cros_ec_i2c_init(struct cros_ec_dev *dev, const void *blob);
@@ -336,6 +358,7 @@ int cros_ec_spi_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version,
int cros_ec_spi_packet(struct cros_ec_dev *dev, int out_bytes, int in_bytes);
int cros_ec_sandbox_packet(struct cros_ec_dev *dev, int out_bytes,
int in_bytes);
#endif
/**
* Dump a block of data for a command.
@@ -489,9 +512,11 @@ int cros_ec_get_error(void);
* Returns information from the FDT about the Chrome EC flash
*
* @param blob FDT blob to use
* @param node Node offset to read from
* @param config Structure to use to return information
*/
int cros_ec_decode_ec_flash(const void *blob, struct fdt_cros_ec *config);
int cros_ec_decode_ec_flash(const void *blob, int node,
struct fdt_cros_ec *config);
/**
* Check the current keyboard state, in case recovery mode is requested.

View File

@@ -65,6 +65,19 @@ int device_bind_by_name(struct udevice *parent, bool pre_reloc_only,
*/
int device_probe(struct udevice *dev);
/**
* device_probe() - Probe a child device, activating it
*
* Activate a device so that it is ready for use. All its parents are probed
* first. The child is provided with parent data if parent_priv is not NULL.
*
* @dev: Pointer to device to probe
* @parent_priv: Pointer to parent data. If non-NULL then this is provided to
* the child.
* @return 0 if OK, -ve on error
*/
int device_probe_child(struct udevice *dev, void *parent_priv);
/**
* device_remove() - Remove a device, de-activating it
*

View File

@@ -57,7 +57,8 @@ struct driver_info;
* @sibling_node: Next device in list of all devices
* @flags: Flags for this device DM_FLAG_...
* @req_seq: Requested sequence number for this device (-1 = any)
* @seq: Allocated sequence number for this device (-1 = none)
* @seq: Allocated sequence number for this device (-1 = none). This is set up
* when the device is probed and will be unique within the device's uclass.
*/
struct udevice {
struct driver *driver;
@@ -96,6 +97,12 @@ struct udevice_id {
ulong data;
};
#ifdef CONFIG_OF_CONTROL
#define of_match_ptr(_ptr) (_ptr)
#else
#define of_match_ptr(_ptr) NULL
#endif /* CONFIG_OF_CONTROL */
/**
* struct driver - A driver for a feature or peripheral
*
@@ -133,6 +140,10 @@ struct udevice_id {
* @per_child_auto_alloc_size: Each device can hold private data owned by
* its parent. If required this will be automatically allocated if this
* value is non-zero.
* TODO(sjg@chromium.org): I'm considering dropping this, and just having
* device_probe_child() pass it in. So far the use case for allocating it
* is SPI, but I found that unsatisfactory. Since it is here I will leave it
* until things are clearer.
* @ops: Driver-specific operations. This is typically a list of function
* pointers defined by the driver, to implement driver functions required by
* the uclass.
@@ -274,4 +285,22 @@ int device_find_child_by_of_offset(struct udevice *parent, int of_offset,
int device_get_child_by_of_offset(struct udevice *parent, int seq,
struct udevice **devp);
/**
* device_find_first_child() - Find the first child of a device
*
* @parent: Parent device to search
* @devp: Returns first child device, or NULL if none
* @return 0
*/
int device_find_first_child(struct udevice *parent, struct udevice **devp);
/**
* device_find_first_child() - Find the first child of a device
*
* @devp: Pointer to previous child device on entry. Returns pointer to next
* child device, or NULL if none
* @return 0
*/
int device_find_next_child(struct udevice **devp);
#endif

View File

@@ -38,7 +38,7 @@ struct uclass_driver *lists_uclass_lookup(enum uclass_id id);
* This searches the U_BOOT_DEVICE() structures and creates new devices for
* each one. The devices will have @parent as their parent.
*
* @parent: parent driver (root)
* @parent: parent device (root)
* @early_only: If true, bind only drivers with the DM_INIT_F flag. If false
* bind all drivers.
*/
@@ -50,7 +50,7 @@ int lists_bind_drivers(struct udevice *parent, bool pre_reloc_only);
* This creates a new device bound to the given device tree node, with
* @parent as its parent.
*
* @parent: parent driver (root)
* @parent: parent device (root)
* @blob: device tree blob
* @offset: offset of this device tree node
* @devp: if non-NULL, returns a pointer to the bound device

View File

@@ -11,10 +11,12 @@
#ifndef _DM_PLATDATA_H
#define _DM_PLATDATA_H
#include <linker_lists.h>
/**
* struct driver_info - Information required to instantiate a device
*
* @name: Device name
* @name: Driver name
* @platdata: Driver-specific platform data
*/
struct driver_info {
@@ -25,4 +27,8 @@ struct driver_info {
#define U_BOOT_DEVICE(__name) \
ll_entry_declare(struct driver_info, __name, driver_info)
/* Declare a list of devices. The argument is a driver_info[] array */
#define U_BOOT_DEVICES(__name) \
ll_entry_declare_list(struct driver_info, __name, driver_info)
#endif

View File

@@ -18,10 +18,16 @@ enum uclass_id {
UCLASS_TEST,
UCLASS_TEST_FDT,
UCLASS_TEST_BUS,
UCLASS_SPI_EMUL, /* sandbox SPI device emulator */
UCLASS_SIMPLE_BUS,
/* U-Boot uclasses start here */
UCLASS_GPIO, /* Bank of general-purpose I/O pins */
UCLASS_SERIAL, /* Serial UART */
UCLASS_SPI, /* SPI bus */
UCLASS_SPI_GENERIC, /* Generic SPI flash target */
UCLASS_SPI_FLASH, /* SPI flash */
UCLASS_CROS_EC, /* Chrome OS EC */
UCLASS_COUNT,
UCLASS_INVALID = -1,

View File

@@ -11,6 +11,7 @@
#define _DM_UCLASS_H
#include <dm/uclass-id.h>
#include <linker_lists.h>
#include <linux/list.h>
/**

View File

@@ -5,6 +5,7 @@
*/
#ifndef __DM_UTIL_H
#define __DM_UTIL_H
void dm_warn(const char *fmt, ...);

View File

@@ -11,6 +11,8 @@
#ifndef __LINKER_LISTS_H__
#define __LINKER_LISTS_H__
#include <linux/compiler.h>
/*
* There is no use in including this from ASM files, but that happens
* anyway, e.g. PPC kgdb.S includes command.h which incluse us.
@@ -140,6 +142,27 @@
__attribute__((unused, \
section(".u_boot_list_2_"#_list"_2_"#_name)))
/**
* ll_entry_declare_list() - Declare a list of link-generated array entries
* @_type: Data type of each entry
* @_name: Name of the entry
* @_list: name of the list. Should contain only characters allowed
* in a C variable name!
*
* This is like ll_entry_declare() but creates multiple entries. It should
* be assigned to an array.
*
* ll_entry_declare_list(struct my_sub_cmd, my_sub_cmd, cmd_sub, cmd.sub) = {
* { .x = 3, .y = 4 },
* { .x = 8, .y = 2 },
* { .x = 1, .y = 7 }
* };
*/
#define ll_entry_declare_list(_type, _name, _list) \
_type _u_boot_list_2_##_list##_2_##_name[] __aligned(4) \
__attribute__((unused, \
section(".u_boot_list_2_"#_list"_2_"#_name)))
/**
* We need a 0-byte-size type for iterator symbols, and the compiler
* does not allow defining objects of C type 'void'. Using an empty

14
include/serial_mxc.h Normal file
View File

@@ -0,0 +1,14 @@
/*
* Copyright (c) 2014 Google, Inc
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef __serial_mxc_h
#define __serial_mxc_h
/* Information about a serial port */
struct mxc_serial_platdata {
struct mxc_uart *reg; /* address of registers in physical memory */
};
#endif

27
include/serial_pl01x.h Normal file
View File

@@ -0,0 +1,27 @@
/*
* Copyright (c) 2014 Google, Inc
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef __serial_pl01x_h
#define __serial_pl01x_h
enum pl01x_type {
TYPE_PL010,
TYPE_PL011,
};
/*
*Information about a serial port
*
* @base: Register base address
* @type: Port type
* @clock: Input clock rate, used for calculating the baud rate divisor
*/
struct pl01x_serial_platdata {
unsigned long base;
enum pl01x_type type;
unsigned int clock;
};
#endif

View File

@@ -54,12 +54,31 @@
#define SPI_DEFAULT_WORDLEN 8
#ifdef CONFIG_DM_SPI
struct dm_spi_bus {
uint max_hz;
};
#endif /* CONFIG_DM_SPI */
/**
* struct spi_slave - Representation of a SPI slave
*
* Drivers are expected to extend this with controller-specific data.
* For driver model this is the per-child data used by the SPI bus. It can
* be accessed using dev_get_parentdata() on the slave device. Each SPI
* driver should define this child data in its U_BOOT_DRIVER() definition:
*
* @bus: ID of the bus that the slave is attached to.
* .per_child_auto_alloc_size = sizeof(struct spi_slave),
*
* If not using driver model, drivers are expected to extend this with
* controller-specific data.
*
* @dev: SPI slave device
* @max_hz: Maximum speed for this slave
* @mode: SPI mode to use for this slave (see SPI mode flags)
* @bus: ID of the bus that the slave is attached to. For
* driver model this is the sequence number of the SPI
* bus (bus->seq) so does not need to be stored
* @cs: ID of the chip select connected to the slave.
* @op_mode_rx: SPI RX operation mode.
* @op_mode_tx: SPI TX operation mode.
@@ -71,7 +90,13 @@
* @flags: Indication of SPI flags.
*/
struct spi_slave {
#ifdef CONFIG_DM_SPI
struct udevice *dev; /* struct spi_slave is dev->parentdata */
uint max_hz;
uint mode;
#else
unsigned int bus;
#endif
unsigned int cs;
u8 op_mode_rx;
u8 op_mode_tx;
@@ -228,8 +253,9 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
* Returns: 1 if bus:cs identifies a valid chip on this board, 0
* otherwise.
*/
int spi_cs_is_valid(unsigned int bus, unsigned int cs);
int spi_cs_is_valid(unsigned int bus, unsigned int cs);
#ifndef CONFIG_DM_SPI
/**
* Activate a SPI chipselect.
* This function is provided by the board code when using a driver
@@ -255,6 +281,7 @@ void spi_cs_deactivate(struct spi_slave *slave);
* @hz: The transfer speed
*/
void spi_set_speed(struct spi_slave *slave, uint hz);
#endif
/**
* Write 8 bits, then read 8 bits.
@@ -305,4 +332,270 @@ struct spi_slave *spi_setup_slave_fdt(const void *blob, int slave_node,
struct spi_slave *spi_base_setup_slave_fdt(const void *blob, int busnum,
int node);
#ifdef CONFIG_DM_SPI
/**
* struct spi_cs_info - Information about a bus chip select
*
* @dev: Connected device, or NULL if none
*/
struct spi_cs_info {
struct udevice *dev;
};
/**
* struct struct dm_spi_ops - Driver model SPI operations
*
* The uclass interface is implemented by all SPI devices which use
* driver model.
*/
struct dm_spi_ops {
/**
* Claim the bus and prepare it for communication.
*
* The device provided is the slave device. It's parent controller
* will be used to provide the communication.
*
* This must be called before doing any transfers with a SPI slave. It
* will enable and initialize any SPI hardware as necessary, and make
* sure that the SCK line is in the correct idle state. It is not
* allowed to claim the same bus for several slaves without releasing
* the bus in between.
*
* @bus: The SPI slave
*
* Returns: 0 if the bus was claimed successfully, or a negative value
* if it wasn't.
*/
int (*claim_bus)(struct udevice *bus);
/**
* Release the SPI bus
*
* This must be called once for every call to spi_claim_bus() after
* all transfers have finished. It may disable any SPI hardware as
* appropriate.
*
* @bus: The SPI slave
*/
int (*release_bus)(struct udevice *bus);
/**
* Set the word length for SPI transactions
*
* Set the word length (number of bits per word) for SPI transactions.
*
* @bus: The SPI slave
* @wordlen: The number of bits in a word
*
* Returns: 0 on success, -ve on failure.
*/
int (*set_wordlen)(struct udevice *bus, unsigned int wordlen);
/**
* SPI transfer
*
* This writes "bitlen" bits out the SPI MOSI port and simultaneously
* clocks "bitlen" bits in the SPI MISO port. That's just the way SPI
* works.
*
* The source of the outgoing bits is the "dout" parameter and the
* destination of the input bits is the "din" parameter. Note that
* "dout" and "din" can point to the same memory location, in which
* case the input data overwrites the output data (since both are
* buffered by temporary variables, this is OK).
*
* spi_xfer() interface:
* @dev: The slave device to communicate with
* @bitlen: How many bits to write and read.
* @dout: Pointer to a string of bits to send out. The bits are
* held in a byte array and are sent MSB first.
* @din: Pointer to a string of bits that will be filled in.
* @flags: A bitwise combination of SPI_XFER_* flags.
*
* Returns: 0 on success, not -1 on failure
*/
int (*xfer)(struct udevice *dev, unsigned int bitlen, const void *dout,
void *din, unsigned long flags);
/**
* Set transfer speed.
* This sets a new speed to be applied for next spi_xfer().
* @bus: The SPI bus
* @hz: The transfer speed
* @return 0 if OK, -ve on error
*/
int (*set_speed)(struct udevice *bus, uint hz);
/**
* Set the SPI mode/flags
*
* It is unclear if we want to set speed and mode together instead
* of separately.
*
* @bus: The SPI bus
* @mode: Requested SPI mode (SPI_... flags)
* @return 0 if OK, -ve on error
*/
int (*set_mode)(struct udevice *bus, uint mode);
/**
* Get information on a chip select
*
* This is only called when the SPI uclass does not know about a
* chip select, i.e. it has no attached device. It gives the driver
* a chance to allow activity on that chip select even so.
*
* @bus: The SPI bus
* @cs: The chip select (0..n-1)
* @info: Returns information about the chip select, if valid.
* On entry info->dev is NULL
* @return 0 if OK (and @info is set up), -ENODEV if the chip select
* is invalid, other -ve value on error
*/
int (*cs_info)(struct udevice *bus, uint cs, struct spi_cs_info *info);
};
struct dm_spi_emul_ops {
/**
* SPI transfer
*
* This writes "bitlen" bits out the SPI MOSI port and simultaneously
* clocks "bitlen" bits in the SPI MISO port. That's just the way SPI
* works. Here the device is a slave.
*
* The source of the outgoing bits is the "dout" parameter and the
* destination of the input bits is the "din" parameter. Note that
* "dout" and "din" can point to the same memory location, in which
* case the input data overwrites the output data (since both are
* buffered by temporary variables, this is OK).
*
* spi_xfer() interface:
* @slave: The SPI slave which will be sending/receiving the data.
* @bitlen: How many bits to write and read.
* @dout: Pointer to a string of bits sent to the device. The
* bits are held in a byte array and are sent MSB first.
* @din: Pointer to a string of bits that will be sent back to
* the master.
* @flags: A bitwise combination of SPI_XFER_* flags.
*
* Returns: 0 on success, not -1 on failure
*/
int (*xfer)(struct udevice *slave, unsigned int bitlen,
const void *dout, void *din, unsigned long flags);
};
/**
* spi_find_bus_and_cs() - Find bus and slave devices by number
*
* Given a bus number and chip select, this finds the corresponding bus
* device and slave device. Neither device is activated by this function,
* although they may have been activated previously.
*
* @busnum: SPI bus number
* @cs: Chip select to look for
* @busp: Returns bus device
* @devp: Return slave device
* @return 0 if found, -ENODEV on error
*/
int spi_find_bus_and_cs(int busnum, int cs, struct udevice **busp,
struct udevice **devp);
/**
* spi_get_bus_and_cs() - Find and activate bus and slave devices by number
*
* Given a bus number and chip select, this finds the corresponding bus
* device and slave device.
*
* If no such slave exists, and drv_name is not NULL, then a new slave device
* is automatically bound on this chip select.
*
* Ths new slave device is probed ready for use with the given speed and mode.
*
* @busnum: SPI bus number
* @cs: Chip select to look for
* @speed: SPI speed to use for this slave
* @mode: SPI mode to use for this slave
* @drv_name: Name of driver to attach to this chip select
* @dev_name: Name of the new device thus created
* @busp: Returns bus device
* @devp: Return slave device
* @return 0 if found, -ve on error
*/
int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode,
const char *drv_name, const char *dev_name,
struct udevice **busp, struct spi_slave **devp);
/**
* spi_chip_select() - Get the chip select for a slave
*
* @return the chip select this slave is attached to
*/
int spi_chip_select(struct udevice *slave);
/**
* spi_bind_device() - bind a device to a bus's chip select
*
* This binds a new device to an given chip select (which must be unused).
*
* @bus: SPI bus to search
* @cs: Chip select to attach to
* @drv_name: Name of driver to attach to this chip select
* @dev_name: Name of the new device thus created
* @devp: Returns the newly bound device
*/
int spi_bind_device(struct udevice *bus, int cs, const char *drv_name,
const char *dev_name, struct udevice **devp);
/**
* spi_ofdata_to_platdata() - decode standard SPI platform data
*
* This decodes the speed and mode from a device tree node and puts it into
* the spi_slave structure.
*
* @blob: Device tree blob
* @node: Node offset to read from
* @spi: Place to put the decoded information
*/
int spi_ofdata_to_platdata(const void *blob, int node, struct spi_slave *spi);
/**
* spi_cs_info() - Check information on a chip select
*
* This checks a particular chip select on a bus to see if it has a device
* attached, or is even valid.
*
* @bus: The SPI bus
* @cs: The chip select (0..n-1)
* @info: Returns information about the chip select, if valid
* @return 0 if OK (and @info is set up), -ENODEV if the chip select
* is invalid, other -ve value on error
*/
int spi_cs_info(struct udevice *bus, uint cs, struct spi_cs_info *info);
struct sandbox_state;
/**
* sandbox_spi_get_emul() - get an emulator for a SPI slave
*
* This provides a way to attach an emulated SPI device to a particular SPI
* slave, so that xfer() operations on the slave will be handled by the
* emulator. If a emulator already exists on that chip select it is returned.
* Otherwise one is created.
*
* @state: Sandbox state
* @bus: SPI bus requesting the emulator
* @slave: SPI slave device requesting the emulator
* @emuip: Returns pointer to emulator
* @return 0 if OK, -ve on error
*/
int sandbox_spi_get_emul(struct sandbox_state *state,
struct udevice *bus, struct udevice *slave,
struct udevice **emulp);
/* Access the serial operations for a device */
#define spi_get_ops(dev) ((struct dm_spi_ops *)(dev)->driver->ops)
#define spi_emul_get_ops(dev) ((struct dm_spi_emul_ops *)(dev)->driver->ops)
#endif /* CONFIG_DM_SPI */
#endif /* _SPI_H_ */

View File

@@ -15,9 +15,8 @@
#ifndef _SPI_FLASH_H_
#define _SPI_FLASH_H_
#include <spi.h>
#include <dm.h> /* Because we dereference struct udevice here */
#include <linux/types.h>
#include <linux/compiler.h>
#ifndef CONFIG_SF_DEFAULT_SPEED
# define CONFIG_SF_DEFAULT_SPEED 1000000
@@ -32,64 +31,19 @@
# define CONFIG_SF_DEFAULT_BUS 0
#endif
/* sf param flags */
#define SECT_4K 1 << 1
#define SECT_32K 1 << 2
#define E_FSR 1 << 3
#define WR_QPP 1 << 4
/* Enum list - Full read commands */
enum spi_read_cmds {
ARRAY_SLOW = 1 << 0,
DUAL_OUTPUT_FAST = 1 << 1,
DUAL_IO_FAST = 1 << 2,
QUAD_OUTPUT_FAST = 1 << 3,
QUAD_IO_FAST = 1 << 4,
};
#define RD_EXTN ARRAY_SLOW | DUAL_OUTPUT_FAST | DUAL_IO_FAST
#define RD_FULL RD_EXTN | QUAD_OUTPUT_FAST | QUAD_IO_FAST
/* Dual SPI flash memories */
enum spi_dual_flash {
SF_SINGLE_FLASH = 0,
SF_DUAL_STACKED_FLASH = 1 << 0,
SF_DUAL_PARALLEL_FLASH = 1 << 1,
};
/**
* struct spi_flash_params - SPI/QSPI flash device params structure
*
* @name: Device name ([MANUFLETTER][DEVTYPE][DENSITY][EXTRAINFO])
* @jedec: Device jedec ID (0x[1byte_manuf_id][2byte_dev_id])
* @ext_jedec: Device ext_jedec ID
* @sector_size: Sector size of this device
* @nr_sectors: No.of sectors on this device
* @e_rd_cmd: Enum list for read commands
* @flags: Important param, for flash specific behaviour
*/
struct spi_flash_params {
const char *name;
u32 jedec;
u16 ext_jedec;
u32 sector_size;
u32 nr_sectors;
u8 e_rd_cmd;
u16 flags;
};
extern const struct spi_flash_params spi_flash_params_table[];
struct spi_slave;
/**
* struct spi_flash - SPI flash structure
*
* @spi: SPI slave
* @name: Name of SPI flash
* @dual_flash: Indicates dual flash memories - dual stacked, parallel
* @dual_flash: Indicates dual flash memories - dual stacked, parallel
* @shift: Flash shift useful in dual parallel
* @size: Total flash size
* @page_size: Write (page) size
* @sector_size: Sector size
* @erase_size: Erase size
* @erase_size: Erase size
* @bank_read_cmd: Bank read cmd
* @bank_write_cmd: Bank write cmd
* @bank_curr: Current flash bank
@@ -97,8 +51,8 @@ extern const struct spi_flash_params spi_flash_params_table[];
* @erase_cmd: Erase cmd 4K, 32K, 64K
* @read_cmd: Read cmd - Array Fast, Extn read and quad read.
* @write_cmd: Write cmd - page and quad program.
* @dummy_byte: Dummy cycles for read operation.
* @memory_map: Address of read-only SPI flash access
* @dummy_byte: Dummy cycles for read operation.
* @memory_map: Address of read-only SPI flash access
* @read: Flash read ops: Read len bytes at offset into buf
* Supported cmds: Fast Array Read
* @write: Flash write ops: Write len bytes from buf into offset
@@ -108,7 +62,12 @@ extern const struct spi_flash_params spi_flash_params_table[];
* return 0 - Success, 1 - Failure
*/
struct spi_flash {
#ifdef CONFIG_DM_SPI_FLASH
struct spi_slave *spi;
struct udevice *dev;
#else
struct spi_slave *spi;
#endif
const char *name;
u8 dual_flash;
u8 shift;
@@ -129,12 +88,75 @@ struct spi_flash {
u8 dummy_byte;
void *memory_map;
#ifndef CONFIG_DM_SPI_FLASH
/*
* These are not strictly needed for driver model, but keep them here
* whilt the transition is in progress.
*
* Normally each driver would provide its own operations, but for
* SPI flash most chips use the same algorithms. One approach is
* to create a 'common' SPI flash device which knows how to talk
* to most devices, and then allow other drivers to be used instead
* if requird, perhaps with a way of scanning through the list to
* find the driver that matches the device.
*/
int (*read)(struct spi_flash *flash, u32 offset, size_t len, void *buf);
int (*write)(struct spi_flash *flash, u32 offset, size_t len,
const void *buf);
int (*erase)(struct spi_flash *flash, u32 offset, size_t len);
#endif
};
struct dm_spi_flash_ops {
int (*read)(struct udevice *dev, u32 offset, size_t len, void *buf);
int (*write)(struct udevice *dev, u32 offset, size_t len,
const void *buf);
int (*erase)(struct udevice *dev, u32 offset, size_t len);
};
/* Access the serial operations for a device */
#define sf_get_ops(dev) ((struct dm_spi_flash_ops *)(dev)->driver->ops)
#ifdef CONFIG_DM_SPI_FLASH
int spi_flash_probe_bus_cs(unsigned int busnum, unsigned int cs,
unsigned int max_hz, unsigned int spi_mode,
struct udevice **devp);
/* Compatibility function - this is the old U-Boot API */
struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
unsigned int max_hz, unsigned int spi_mode);
/* Compatibility function - this is the old U-Boot API */
void spi_flash_free(struct spi_flash *flash);
int spi_flash_remove(struct udevice *flash);
static inline int spi_flash_read(struct spi_flash *flash, u32 offset,
size_t len, void *buf)
{
return sf_get_ops(flash->dev)->read(flash->dev, offset, len, buf);
}
static inline int spi_flash_write(struct spi_flash *flash, u32 offset,
size_t len, const void *buf)
{
return sf_get_ops(flash->dev)->write(flash->dev, offset, len, buf);
}
static inline int spi_flash_erase(struct spi_flash *flash, u32 offset,
size_t len)
{
return sf_get_ops(flash->dev)->erase(flash->dev, offset, len);
}
struct sandbox_state;
int sandbox_sf_bind_emul(struct sandbox_state *state, int busnum, int cs,
struct udevice *bus, int of_offset, const char *spec);
void sandbox_sf_unbind_emul(struct sandbox_state *state, int busnum, int cs);
#else
struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
unsigned int max_hz, unsigned int spi_mode);
@@ -169,6 +191,7 @@ static inline int spi_flash_erase(struct spi_flash *flash, u32 offset,
{
return flash->erase(flash, offset, len);
}
#endif
void spi_boot(void) __noreturn;
void spi_spl_load_image(uint32_t offs, unsigned int size, void *vdst);