Merge git://git.denx.de/u-boot-dm
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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; \
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#define _DM_UCLASS_H
|
||||
|
||||
#include <dm/uclass-id.h>
|
||||
#include <linker_lists.h>
|
||||
#include <linux/list.h>
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
#ifndef __DM_UTIL_H
|
||||
#define __DM_UTIL_H
|
||||
|
||||
void dm_warn(const char *fmt, ...);
|
||||
|
||||
|
||||
@@ -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
14
include/serial_mxc.h
Normal 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
27
include/serial_pl01x.h
Normal 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
|
||||
299
include/spi.h
299
include/spi.h
@@ -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_ */
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user