From 81b4e751c2bb9d9c769c2b55273944f70f9abc95 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 28 Sep 2014 22:52:24 +0900 Subject: dm: fix comments The struct udevice stands for a device, not a driver. The driver_info.name is a driver's name, which is referenced to bind devices. Signed-off-by: Masahiro Yamada Acked-by: Simon Glass --- include/dm/lists.h | 4 ++-- include/dm/platdata.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/dm/lists.h b/include/dm/lists.h index 2356895246..704e33e37f 100644 --- a/include/dm/lists.h +++ b/include/dm/lists.h @@ -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 diff --git a/include/dm/platdata.h b/include/dm/platdata.h index 2bc8b147ed..7716f1940e 100644 --- a/include/dm/platdata.h +++ b/include/dm/platdata.h @@ -14,7 +14,7 @@ /** * struct driver_info - Information required to instantiate a device * - * @name: Device name + * @name: Driver name * @platdata: Driver-specific platform data */ struct driver_info { -- cgit v1.2.1 From dc7cb46f9707d27c9a9d66684c391062ccf8773f Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 7 Oct 2014 14:48:22 +0900 Subject: linker_lists: include The header file include/linker_lists.h uses __aligned(); therefore it depends on include/linux/compiler.h Signed-off-by: Masahiro Yamada Acked-by: Simon Glass --- include/linker_lists.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linker_lists.h b/include/linker_lists.h index 507d61ba9a..046ac907d2 100644 --- a/include/linker_lists.h +++ b/include/linker_lists.h @@ -11,6 +11,8 @@ #ifndef __LINKER_LISTS_H__ #define __LINKER_LISTS_H__ +#include + /* * 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. -- cgit v1.2.1 From 42c23dd2aafea0a1de7b8acbe1d2515eb25fee73 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 7 Oct 2014 14:49:13 +0900 Subject: dm: include from platdata.h and uclass.h The header files include/dm/platdata.h and include/dm/uclass.h use ll_entry_declare(); therefore they depend on include/linker_lists.h. Signed-off-by: Masahiro Yamada Acked-by: Simon Glass --- include/dm/platdata.h | 2 ++ include/dm/uclass.h | 1 + 2 files changed, 3 insertions(+) (limited to 'include') diff --git a/include/dm/platdata.h b/include/dm/platdata.h index 7716f1940e..0d4d561089 100644 --- a/include/dm/platdata.h +++ b/include/dm/platdata.h @@ -11,6 +11,8 @@ #ifndef _DM_PLATDATA_H #define _DM_PLATDATA_H +#include + /** * struct driver_info - Information required to instantiate a device * diff --git a/include/dm/uclass.h b/include/dm/uclass.h index 8d09ecff7b..f6ec6d7e9f 100644 --- a/include/dm/uclass.h +++ b/include/dm/uclass.h @@ -11,6 +11,7 @@ #define _DM_UCLASS_H #include +#include #include /** -- cgit v1.2.1 From b1799fcbdc9d5bd7c7eb85f70f256d81b3af0bfe Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 7 Oct 2014 14:49:38 +0900 Subject: dm: fix include guard Signed-off-by: Masahiro Yamada Acked-by: Simon Glass --- include/dm/util.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/dm/util.h b/include/dm/util.h index 8be64a921d..6ac3a38ef0 100644 --- a/include/dm/util.h +++ b/include/dm/util.h @@ -5,6 +5,7 @@ */ #ifndef __DM_UTIL_H +#define __DM_UTIL_H void dm_warn(const char *fmt, ...); -- cgit v1.2.1 From f887cb6d86012a79147cc67d512782644426dd9a Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 7 Oct 2014 14:51:31 +0900 Subject: dm: add of_match_ptr() macro The driver model supports two ways for passing device parameters; Device Tree and platform_data (board file). Each driver should generally support both of them because some popular IPs are used on various platforms. Assume the following scenario: - The driver Foo is used on SoC Bar and SoC Baz - The SoC Bar uses Device Tree control (CONFIG_OF_CONTROL=y) - The SoC Baz does not support Device Tree; uses a board file In this situation, the device driver Foo should work with/without the device tree control. The driver should have .of_match and .ofdata_to_platdata members for SoC Bar, while they are meaningless for SoC Baz; therefore those device-tree control code should go inside #ifdef CONFIG_OF_CONTROL. The driver code will be like this: #ifdef CONFIG_OF_CONTROL static const struct udevice_id foo_of_match = { { .compatible = "foo_driver" }, {}, } static int foo_ofdata_to_platdata(struct udevice *dev) { ... } #endif U_BOOT_DRIVER(foo_driver) = { ... .of_match = of_match_ptr(foo_of_match), .ofdata_to_platdata = of_match_ptr(foo_ofdata_to_platdata), ... } This idea has been borrowed from Linux. (In Linux, this macro is defined in include/linux/of.h) Signed-off-by: Masahiro Yamada Acked-by: Simon Glass --- include/dm/device.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include') diff --git a/include/dm/device.h b/include/dm/device.h index c8a4072bcf..e08d496e6a 100644 --- a/include/dm/device.h +++ b/include/dm/device.h @@ -96,6 +96,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 * -- cgit v1.2.1 From 4d38395c1585e54f23b9fd53f9694beb1931ba64 Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Mon, 6 Oct 2014 14:33:11 +0200 Subject: arm: goni: add i2c_init_board() Add proper initialization of GPIO pins used by software i2c. Signed-off-by: Robert Baldyga Acked-by: Simon Glass --- include/configs/s5p_goni.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/configs/s5p_goni.h b/include/configs/s5p_goni.h index 0c6e9c7878..fc2497a332 100644 --- a/include/configs/s5p_goni.h +++ b/include/configs/s5p_goni.h @@ -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 -- cgit v1.2.1 From d010facb4e315a3a4b78fc52c843720aeafd0bab Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 20 Oct 2014 19:48:35 -0600 Subject: dm: exynos: Move smdkc100 to generic board The generic board deadline is approaching, and we need this feature to enable driver model. Enable CONFIG_SYS_GENERIC_BOARD for smdkc100. Signed-off-by: Simon Glass --- include/configs/smdkc100.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/configs/smdkc100.h b/include/configs/smdkc100.h index 22835ffd64..a7eb33ed43 100644 --- a/include/configs/smdkc100.h +++ b/include/configs/smdkc100.h @@ -223,4 +223,6 @@ #define CONFIG_OF_LIBFDT +#define CONFIG_SYS_GENERIC_BOARD + #endif /* __CONFIG_H */ -- cgit v1.2.1 From 084067ce13b5665c8ee8eb1277447d67bc5210c8 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 20 Oct 2014 19:48:36 -0600 Subject: dm: exynos: Move s5p_goni to generic board The generic board deadline is approaching, and we need this feature to enable driver model. Enable CONFIG_SYS_GENERIC_BOARD for s5p_goni. Signed-off-by: Simon Glass --- include/configs/s5p_goni.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/configs/s5p_goni.h b/include/configs/s5p_goni.h index fc2497a332..781d8474db 100644 --- a/include/configs/s5p_goni.h +++ b/include/configs/s5p_goni.h @@ -288,4 +288,6 @@ #define CONFIG_OF_LIBFDT +#define CONFIG_SYS_GENERIC_BOARD + #endif /* __CONFIG_H */ -- cgit v1.2.1 From b8809e60cdb5ab09fb28a0903f25b2878483ec04 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 20 Oct 2014 19:48:40 -0600 Subject: dm: exynos: gpio: Convert to driver model Convert the exynos GPIO driver to driver model. This implements the generic GPIO interface but not the extra Exynos-specific functions. Signed-off-by: Simon Glass --- include/configs/exynos-common.h | 4 ++++ include/configs/s5p_goni.h | 3 +++ include/configs/smdkc100.h | 3 +++ 3 files changed, 10 insertions(+) (limited to 'include') diff --git a/include/configs/exynos-common.h b/include/configs/exynos-common.h index 371f32d840..4a4b22b74b 100644 --- a/include/configs/exynos-common.h +++ b/include/configs/exynos-common.h @@ -17,6 +17,10 @@ #include #define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_DM +#define CONFIG_CMD_DM +#define CONFIG_DM_GPIO + #define CONFIG_ARCH_CPU_INIT #define CONFIG_DISPLAY_CPUINFO #define CONFIG_DISPLAY_BOARDINFO diff --git a/include/configs/s5p_goni.h b/include/configs/s5p_goni.h index 781d8474db..76b0503026 100644 --- a/include/configs/s5p_goni.h +++ b/include/configs/s5p_goni.h @@ -289,5 +289,8 @@ #define CONFIG_OF_LIBFDT #define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_DM +#define CONFIG_CMD_DM +#define CONFIG_DM_GPIO #endif /* __CONFIG_H */ diff --git a/include/configs/smdkc100.h b/include/configs/smdkc100.h index a7eb33ed43..424e130ec2 100644 --- a/include/configs/smdkc100.h +++ b/include/configs/smdkc100.h @@ -224,5 +224,8 @@ #define CONFIG_OF_LIBFDT #define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_DM +#define CONFIG_CMD_DM +#define CONFIG_DM_GPIO #endif /* __CONFIG_H */ -- cgit v1.2.1 From 73e256c2ac7a67b00be69a397997d80d04ec994d Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 14 Sep 2014 16:36:17 -0600 Subject: dm: exynos: Move serial to driver model Change the Exynos serial driver to work with driver model and switch over all relevant boards to use it. Signed-off-by: Simon Glass --- include/configs/exynos-common.h | 1 + include/configs/s5p_goni.h | 1 + include/configs/smdkc100.h | 1 + 3 files changed, 3 insertions(+) (limited to 'include') diff --git a/include/configs/exynos-common.h b/include/configs/exynos-common.h index 4a4b22b74b..34a162d660 100644 --- a/include/configs/exynos-common.h +++ b/include/configs/exynos-common.h @@ -20,6 +20,7 @@ #define CONFIG_DM #define CONFIG_CMD_DM #define CONFIG_DM_GPIO +#define CONFIG_DM_SERIAL #define CONFIG_ARCH_CPU_INIT #define CONFIG_DISPLAY_CPUINFO diff --git a/include/configs/s5p_goni.h b/include/configs/s5p_goni.h index 76b0503026..3633a355bd 100644 --- a/include/configs/s5p_goni.h +++ b/include/configs/s5p_goni.h @@ -292,5 +292,6 @@ #define CONFIG_DM #define CONFIG_CMD_DM #define CONFIG_DM_GPIO +#define CONFIG_DM_SERIAL #endif /* __CONFIG_H */ diff --git a/include/configs/smdkc100.h b/include/configs/smdkc100.h index 424e130ec2..982d0dcea3 100644 --- a/include/configs/smdkc100.h +++ b/include/configs/smdkc100.h @@ -227,5 +227,6 @@ #define CONFIG_DM #define CONFIG_CMD_DM #define CONFIG_DM_GPIO +#define CONFIG_DM_SERIAL #endif /* __CONFIG_H */ -- cgit v1.2.1 From a8981d4f80b010666ad754d20a4f389f94d6726d Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 13 Oct 2014 23:41:49 -0600 Subject: dm: core: Add functions for iterating through device children Buses need to iterate through their children in some situations. Add a few functions to make this easy. Signed-off-by: Simon Glass Acked-by: Jagannadha Sutradharudu Teki --- include/dm/device.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'include') diff --git a/include/dm/device.h b/include/dm/device.h index e08d496e6a..160cd5883a 100644 --- a/include/dm/device.h +++ b/include/dm/device.h @@ -280,4 +280,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 -- cgit v1.2.1 From accd4b19b39bde7398aa8d1a8eeb66f3a14dde5b Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 13 Oct 2014 23:41:50 -0600 Subject: dm: core: Allow parents to pass data to children during probe Buses sometimes want to pass data to their children when they are probed. For example, a SPI bus may want to tell the slave device about the chip select it is connected to. Add a new function to permit the parent data to be supplied to the child. Signed-off-by: Simon Glass Acked-by: Jagannadha Sutradharudu Teki --- include/dm/device-internal.h | 13 +++++++++++++ include/dm/device.h | 4 ++++ 2 files changed, 17 insertions(+) (limited to 'include') diff --git a/include/dm/device-internal.h b/include/dm/device-internal.h index 7005d03d08..44cb7ef93b 100644 --- a/include/dm/device-internal.h +++ b/include/dm/device-internal.h @@ -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 * diff --git a/include/dm/device.h b/include/dm/device.h index 160cd5883a..56862d32ef 100644 --- a/include/dm/device.h +++ b/include/dm/device.h @@ -139,6 +139,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. -- cgit v1.2.1 From 547cea19b875ce83cc7c14ae750eca4973dab555 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 13 Oct 2014 23:41:51 -0600 Subject: dm: core: Add a clarifying comment on struct udevice's seq member The sequence number is unique within the uclass, so state this clearly. Signed-off-by: Simon Glass Acked-by: Jagannadha Sutradharudu Teki --- include/dm/device.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/dm/device.h b/include/dm/device.h index 56862d32ef..9ce95a834e 100644 --- a/include/dm/device.h +++ b/include/dm/device.h @@ -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; -- cgit v1.2.1 From d7af6a485126a0d08a0a9a56721e42a3e78b5b53 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 13 Oct 2014 23:41:52 -0600 Subject: dm: spi: Add a uclass for SPI Add a uclass which provides access to SPI buses and includes operations required by SPI. For a time driver model will need to co-exist with the legacy SPI interface so some parts of the header file are changed depending on which is in use. The exports are adjusted also since some functions are not available with driver model. Boards must define CONFIG_DM_SPI to use driver model for SPI. Signed-off-by: Simon Glass Reviewed-by: Jagannadha Sutradharudu Teki (Discussed some follow-up comments which will address in future add-ons) --- include/dm/uclass-id.h | 2 + include/spi.h | 254 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 253 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index 7f0e37b7b7..0afdc75386 100644 --- a/include/dm/uclass-id.h +++ b/include/dm/uclass-id.h @@ -22,6 +22,8 @@ enum uclass_id { /* 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_COUNT, UCLASS_INVALID = -1, diff --git a/include/spi.h b/include/spi.h index b673be270c..89949b11b7 100644 --- a/include/spi.h +++ b/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: + * + * .per_child_auto_alloc_size = sizeof(struct spi_slave), * - * @bus: ID of the bus that the slave is attached to. + * 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,225 @@ 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); +}; + +/** + * 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; +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) +#endif /* CONFIG_DM_SPI */ + #endif /* _SPI_H_ */ -- cgit v1.2.1 From c60e1f254747ac650f8290e5debcf8ad1567584b Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 13 Oct 2014 23:41:53 -0600 Subject: dm: sandbox: Add a SPI emulation uclass U-Boot includes a SPI emulation driver already but it is not explicit, and is hidden in the SPI flash code. Conceptually with sandbox's SPI implementation we have a layer which creates SPI bus transitions and a layer which interprets them, currently only for SPI flash. The latter is actually an emulation, and it should be possible to add more than one emulation - not just SPI flash. Add a SPI emulation uclass so that other emulations can be plugged in to support different types of emulated devices on difference buses/chip selects. Signed-off-by: Simon Glass Reviewed-by: Jagannadha Sutradharudu Teki --- include/dm/uclass-id.h | 1 + include/spi.h | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) (limited to 'include') diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index 0afdc75386..6e5638208b 100644 --- a/include/dm/uclass-id.h +++ b/include/dm/uclass-id.h @@ -18,6 +18,7 @@ enum uclass_id { UCLASS_TEST, UCLASS_TEST_FDT, UCLASS_TEST_BUS, + UCLASS_SPI_EMUL, /* sandbox SPI device emulator */ /* U-Boot uclasses start here */ UCLASS_GPIO, /* Bank of general-purpose I/O pins */ diff --git a/include/spi.h b/include/spi.h index 89949b11b7..aa0a48ea62 100644 --- a/include/spi.h +++ b/include/spi.h @@ -456,6 +456,35 @@ struct dm_spi_ops { 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 * @@ -545,12 +574,28 @@ int spi_ofdata_to_platdata(const void *blob, int node, struct spi_slave *spi); 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_ */ -- cgit v1.2.1 From 49b5d6e6e2efab092b18ed53a850b71a59d3eb78 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 13 Oct 2014 23:41:57 -0600 Subject: dm: sandbox: spi: Move to driver model Adjust the sandbox SPI driver to support driver model and move sandbox over to driver model for SPI. Signed-off-by: Simon Glass Reviewed-by: Jagannadha Sutradharudu Teki --- include/configs/sandbox.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'include') diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h index 022629f522..8b74f49250 100644 --- a/include/configs/sandbox.h +++ b/include/configs/sandbox.h @@ -97,8 +97,7 @@ #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_SPI_FLASH_ATMEL #define CONFIG_SPI_FLASH_EON #define CONFIG_SPI_FLASH_GIGADEVICE -- cgit v1.2.1 From 44ba6b0eccb37dd98becece22632bcc5e5cd2fbe Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 13 Oct 2014 23:41:59 -0600 Subject: dm: spi: Remove SPI_INIT feature This feature provides for init of a single SPI port for the soft SPI feature. It is not really compatible with driver model since it assumes a single SPI port. Also, inserting SPI init into the driver by means of a #define is not very nice. This feature is not used by any active boards, so let's remove it. Signed-off-by: Simon Glass Reviewed-by: Jagannadha Sutradharudu Teki --- include/configs/s5pc210_universal.h | 1 - include/configs/sacsng.h | 1 - include/configs/zipitz2.h | 1 - 3 files changed, 3 deletions(-) (limited to 'include') diff --git a/include/configs/s5pc210_universal.h b/include/configs/s5pc210_universal.h index 27f3d0af47..4fa8d66a25 100644 --- a/include/configs/s5pc210_universal.h +++ b/include/configs/s5pc210_universal.h @@ -194,7 +194,6 @@ #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() diff --git a/include/configs/sacsng.h b/include/configs/sacsng.h index b5064ab37c..2dee315f91 100644 --- a/include/configs/sacsng.h +++ b/include/configs/sacsng.h @@ -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; \ diff --git a/include/configs/zipitz2.h b/include/configs/zipitz2.h index 41a7c99edc..fe331bc082 100644 --- a/include/configs/zipitz2.h +++ b/include/configs/zipitz2.h @@ -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) -- cgit v1.2.1 From 73186c9460761315a5a5dfd352c631ab2a022f28 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 13 Oct 2014 23:42:01 -0600 Subject: dm: exynos: Convert SPI to driver model Move the exynos SPI driver over to driver model. This removes quite a bit of boilerplate from the driver, although it adds some for driver model. A few device tree additions are needed to make the SPI flash available. Signed-off-by: Simon Glass Reviewed-by: Jagannadha Sutradharudu Teki --- include/configs/exynos-common.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/configs/exynos-common.h b/include/configs/exynos-common.h index 34a162d660..eb6745e5a6 100644 --- a/include/configs/exynos-common.h +++ b/include/configs/exynos-common.h @@ -21,6 +21,7 @@ #define CONFIG_CMD_DM #define CONFIG_DM_GPIO #define CONFIG_DM_SERIAL +#define CONFIG_DM_SPI #define CONFIG_ARCH_CPU_INIT #define CONFIG_DISPLAY_CPUINFO -- cgit v1.2.1 From 0043b1faa7f8a6b9a38ac949335cf3a5c3074459 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 13 Oct 2014 23:42:03 -0600 Subject: exynos: universal_c210: Move to driver model soft_spi Adjust this board to use the driver model soft_spi implementation. Signed-off-by: Simon Glass Reviewed-by: Jagannadha Sutradharudu Teki --- include/configs/s5pc210_universal.h | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'include') diff --git a/include/configs/s5pc210_universal.h b/include/configs/s5pc210_universal.h index 4fa8d66a25..4b30d148c3 100644 --- a/include/configs/s5pc210_universal.h +++ b/include/configs/s5pc210_universal.h @@ -187,16 +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) -#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); -- cgit v1.2.1 From ff0960f9a018952cbaab59c0d87b6e0338c8f04c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 13 Oct 2014 23:42:04 -0600 Subject: sf: Tidy up public and private header files Since spi_flash.h is supposed to be the public API for SPI flash, move private things to sf_internal.h. Also tidy up a few comment nits. Signed-off-by: Simon Glass Reviewed-by: Jagannadha Sutradharudu Teki --- include/spi_flash.h | 57 +++++------------------------------------------------ 1 file changed, 5 insertions(+), 52 deletions(-) (limited to 'include') diff --git a/include/spi_flash.h b/include/spi_flash.h index 408a5b401c..223e4420a5 100644 --- a/include/spi_flash.h +++ b/include/spi_flash.h @@ -15,9 +15,7 @@ #ifndef _SPI_FLASH_H_ #define _SPI_FLASH_H_ -#include #include -#include #ifndef CONFIG_SF_DEFAULT_SPEED # define CONFIG_SF_DEFAULT_SPEED 1000000 @@ -32,64 +30,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 +50,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 -- cgit v1.2.1 From 4c2dbefde58917205af51a2c20b3069e01e55cf4 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 13 Oct 2014 23:42:06 -0600 Subject: dm: sf: Add a uclass for SPI flash Add a driver model uclass for SPI flash which supports the common operations (read, write, erase). Since we must keep support for the non-dm interface, some modification of the spi_flash header is required. CONFIG_DM_SPI_FLASH is used to enable driver model for SPI flash. Signed-off-by: Simon Glass Reviewed-by: Jagannadha Sutradharudu Teki --- include/dm/uclass-id.h | 1 + include/spi_flash.h | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) (limited to 'include') diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index 6e5638208b..c92adb4df9 100644 --- a/include/dm/uclass-id.h +++ b/include/dm/uclass-id.h @@ -25,6 +25,7 @@ enum uclass_id { UCLASS_SERIAL, /* Serial UART */ UCLASS_SPI, /* SPI bus */ UCLASS_SPI_GENERIC, /* Generic SPI flash target */ + UCLASS_SPI_FLASH, /* SPI flash */ UCLASS_COUNT, UCLASS_INVALID = -1, diff --git a/include/spi_flash.h b/include/spi_flash.h index 223e4420a5..5913b39e26 100644 --- a/include/spi_flash.h +++ b/include/spi_flash.h @@ -15,6 +15,7 @@ #ifndef _SPI_FLASH_H_ #define _SPI_FLASH_H_ +#include /* Because we dereference struct udevice here */ #include #ifndef CONFIG_SF_DEFAULT_SPEED @@ -61,7 +62,12 @@ struct spi_slave; * 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; @@ -82,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); @@ -122,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); -- cgit v1.2.1 From b6c2956defb42ce7fe1763f628b81e95f485eb2d Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 13 Oct 2014 23:42:08 -0600 Subject: dm: sf: sandbox: Convert SPI flash driver to driver model Convert sandbox's spi flash emulation driver to use driver model. Signed-off-by: Simon Glass Reviewed-by: Jagannadha Sutradharudu Teki --- include/configs/sandbox.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h index 8b74f49250..46f67be980 100644 --- a/include/configs/sandbox.h +++ b/include/configs/sandbox.h @@ -98,6 +98,7 @@ #define CONFIG_CMD_SPI #define CONFIG_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 -- cgit v1.2.1 From 465bc03b0c5861864fa082c0f79fc9295a9e2cb9 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 13 Oct 2014 23:42:09 -0600 Subject: dm: exynos: config: Use driver model for SPI flash Use driver model for exynos5 board SPI flash. Signed-off-by: Simon Glass Reviewed-by: Jagannadha Sutradharudu Teki --- include/configs/exynos-common.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/configs/exynos-common.h b/include/configs/exynos-common.h index eb6745e5a6..6ba9bb7a1b 100644 --- a/include/configs/exynos-common.h +++ b/include/configs/exynos-common.h @@ -22,6 +22,7 @@ #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 -- cgit v1.2.1 From fda6fac39bb915fdb0ff31b998336d3a5f5c71a9 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 13 Oct 2014 23:42:13 -0600 Subject: dm: tegra: spi: Convert to driver model This converts the Tegra SPI drivers to use driver model. This is tested on: - Tegra20 - trimslice - Tegra30 - beaver - Tegra124 - dalmore (not tested on Tegra124) Reviewed-by: Jagannadha Sutradharudu Teki Signed-off-by: Simon Glass --- include/configs/tegra-common-post.h | 2 +- include/configs/tegra-common.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/configs/tegra-common-post.h b/include/configs/tegra-common-post.h index 23e3c8af31..a258699af7 100644 --- a/include/configs/tegra-common-post.h +++ b/include/configs/tegra-common-post.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 */ diff --git a/include/configs/tegra-common.h b/include/configs/tegra-common.h index 834b3d5686..4719ee10ae 100644 --- a/include/configs/tegra-common.h +++ b/include/configs/tegra-common.h @@ -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 -- cgit v1.2.1 From 84d6cbd3029e8b16e201f1129c300fae258c0f9c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 13 Oct 2014 23:42:14 -0600 Subject: dm: cros_ec: Add support for driver model Add support for driver model if enabled. This involves minimal changes to the code, mostly just plumbing around the edges. Signed-off-by: Simon Glass Acked-by: Jagannadha Sutradharudu Teki --- include/cros_ec.h | 27 ++++++++++++++++++++++++++- include/dm/uclass-id.h | 1 + 2 files changed, 27 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/cros_ec.h b/include/cros_ec.h index 1e4d8db96b..9e13146ecb 100644 --- a/include/cros_ec.h +++ b/include/cros_ec.h @@ -14,6 +14,7 @@ #include #include +#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. diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index c92adb4df9..0ea7a6f09e 100644 --- a/include/dm/uclass-id.h +++ b/include/dm/uclass-id.h @@ -26,6 +26,7 @@ enum uclass_id { 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, -- cgit v1.2.1 From be995a85455343f99c84ceacf0bf771eb2e85752 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 13 Oct 2014 23:42:15 -0600 Subject: dm: sandbox: cros_ec: Move sandbox cros_ec to driver module Adjust the sandbox cros_ec emulation driver to work with driver model, and switch over to driver model for sandbox cros_ec. Signed-off-by: Simon Glass Acked-by: Jagannadha Sutradharudu Teki --- include/configs/sandbox.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h index 46f67be980..ee4b24473c 100644 --- a/include/configs/sandbox.h +++ b/include/configs/sandbox.h @@ -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 -- cgit v1.2.1 From ea0ebc8662357f8f5c7f568ec5e1eb8d773ae4ee Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 13 Oct 2014 23:42:16 -0600 Subject: dm: exynos: cros_ec: Move cros_ec_spi to driver model Adjust this driver to use driver model and move smdk5420 boards over to use it. Acked-by: Jagannadha Sutradharudu Teki Signed-off-by: Simon Glass --- include/configs/peach-pit.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/configs/peach-pit.h b/include/configs/peach-pit.h index ab8ac60df2..91bd37d6bc 100644 --- a/include/configs/peach-pit.h +++ b/include/configs/peach-pit.h @@ -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 -- cgit v1.2.1 From 3fcc3af4d270dac159fc0c8b2a28ae4f9198befe Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 1 Oct 2014 19:57:20 -0600 Subject: dm: linker_lists: Add a way to declare multiple objects The existing ll_entry_declare() permits a single element of the list to be added to a linker list. Sometimes we want to add several objects at once. To avoid lots of messy declarations, add a macro to support this. Signed-off-by: Simon Glass --- include/linker_lists.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'include') diff --git a/include/linker_lists.h b/include/linker_lists.h index 046ac907d2..d37fba44dc 100644 --- a/include/linker_lists.h +++ b/include/linker_lists.h @@ -142,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 -- cgit v1.2.1 From 10778398b3a0a05a4d00ee4a5b1d6a6f215eb37b Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 1 Oct 2014 19:57:21 -0600 Subject: dm: core: Allow a list of devices to be declared in one step The U_BOOT_DEVICE macro allows the declaration of a single U-Boot device. Add an equivalent macro to declare an array of devices, for convenience. Signed-off-by: Simon Glass --- include/dm/platdata.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/dm/platdata.h b/include/dm/platdata.h index 0d4d561089..fbc8a6b3ad 100644 --- a/include/dm/platdata.h +++ b/include/dm/platdata.h @@ -27,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 -- cgit v1.2.1 From a8ba569cba1e79f97438c1643ddc08f3ca7bffef Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 1 Oct 2014 19:57:27 -0600 Subject: dm: imx: serial: Support driver model in the MXC serial driver Add driver model support with this driver. Boards which use this driver should define platform data in their board files. Signed-off-by: Simon Glass --- include/serial_mxc.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 include/serial_mxc.h (limited to 'include') diff --git a/include/serial_mxc.h b/include/serial_mxc.h new file mode 100644 index 0000000000..7d3ace2f9e --- /dev/null +++ b/include/serial_mxc.h @@ -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 -- cgit v1.2.1 From 3f0e935f2250110990875159552e1ff7eb7da39d Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 1 Oct 2014 19:57:28 -0600 Subject: dm: imx: Move cm_fx6 to use driver model for serial and GPIO Now that serial and GPIO are available for iMX.6, move cm_fx6 over as an example. Acked-by: Igor Grinberg Signed-off-by: Simon Glass Acked-by: Nikita Kiryanov --- include/configs/cm_fx6.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'include') diff --git a/include/configs/cm_fx6.h b/include/configs/cm_fx6.h index 7cf241e31d..a20c373321 100644 --- a/include/configs/cm_fx6.h +++ b/include/configs/cm_fx6.h @@ -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 -- cgit v1.2.1 From da802b9e2726c7467e0b402efeb6ad3d975f1282 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 4 Oct 2014 11:29:37 -0600 Subject: dm: core: Add support for simple-bus Add a driver for the simple-bus nodes, which allows devices within these nodes to be bound. Signed-off-by: Simon Glass --- include/dm/uclass-id.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index 0ea7a6f09e..a8944c97d0 100644 --- a/include/dm/uclass-id.h +++ b/include/dm/uclass-id.h @@ -19,6 +19,7 @@ enum uclass_id { 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 */ -- cgit v1.2.1 From 41e98e011da9a3a4461e8cb1479ce343898264fe Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 22 Sep 2014 17:30:56 -0600 Subject: dm: rpi: Convert GPIO driver to driver model Convert the BCM2835 GPIO driver to use driver model, and switch over Raspberry Pi to use this, since it is the only board. Signed-off-by: Simon Glass Tested-by: Stephen Warren Acked-by: Stephen Warren --- include/configs/rpi_b.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include') diff --git a/include/configs/rpi_b.h b/include/configs/rpi_b.h index 2d69809480..d9475e950b 100644 --- a/include/configs/rpi_b.h +++ b/include/configs/rpi_b.h @@ -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 -- cgit v1.2.1 From aed2fbef5e9a0ab5a7cd01e742039a962f0b24ef Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 22 Sep 2014 17:30:57 -0600 Subject: dm: serial: Tidy up the pl01x driver Adjust the driver so that leaf functions take a pointer to the serial port register base. Put all the global configuration in the init function, and use the same settings from then on. This makes it much easier to move to driver model without duplicating the code, since with driver model we use platform data rather than global settings. The driver is compiled with either the CONFIG_PL010_SERIAL or CONFIG_PL011_SERIAL option and this determines the uart type. With driver model this needs to come in from platform data, so create a new CONFIG_PL01X_SERIAL config which brings in the driver, and adjust the driver to support both peripheral variants. Signed-off-by: Simon Glass Tested-by: Stephen Warren --- include/serial_pl01x.h | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 include/serial_pl01x.h (limited to 'include') diff --git a/include/serial_pl01x.h b/include/serial_pl01x.h new file mode 100644 index 0000000000..5e068f390b --- /dev/null +++ b/include/serial_pl01x.h @@ -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 -- cgit v1.2.1