diff options
Diffstat (limited to 'doc/driver-model')
-rw-r--r-- | doc/driver-model/README.txt | 368 | ||||
-rw-r--r-- | doc/driver-model/UDM-block.txt | 278 | ||||
-rw-r--r-- | doc/driver-model/UDM-cores.txt | 126 | ||||
-rw-r--r-- | doc/driver-model/UDM-design.txt | 315 | ||||
-rw-r--r-- | doc/driver-model/UDM-fpga.txt | 115 | ||||
-rw-r--r-- | doc/driver-model/UDM-gpio.txt | 106 | ||||
-rw-r--r-- | doc/driver-model/UDM-hwmon.txt | 118 | ||||
-rw-r--r-- | doc/driver-model/UDM-keyboard.txt | 47 | ||||
-rw-r--r-- | doc/driver-model/UDM-mmc.txt | 319 | ||||
-rw-r--r-- | doc/driver-model/UDM-net.txt | 428 | ||||
-rw-r--r-- | doc/driver-model/UDM-pci.txt | 253 | ||||
-rw-r--r-- | doc/driver-model/UDM-pcmcia.txt | 78 | ||||
-rw-r--r-- | doc/driver-model/UDM-power.txt | 88 | ||||
-rw-r--r-- | doc/driver-model/UDM-rtc.txt | 253 | ||||
-rw-r--r-- | doc/driver-model/UDM-serial.txt | 155 | ||||
-rw-r--r-- | doc/driver-model/UDM-spi.txt | 200 | ||||
-rw-r--r-- | doc/driver-model/UDM-stdio.txt | 191 | ||||
-rw-r--r-- | doc/driver-model/UDM-tpm.txt | 48 | ||||
-rw-r--r-- | doc/driver-model/UDM-twserial.txt | 47 | ||||
-rw-r--r-- | doc/driver-model/UDM-usb.txt | 94 | ||||
-rw-r--r-- | doc/driver-model/UDM-video.txt | 74 | ||||
-rw-r--r-- | doc/driver-model/UDM-watchdog.txt | 329 |
22 files changed, 368 insertions, 3662 deletions
diff --git a/doc/driver-model/README.txt b/doc/driver-model/README.txt new file mode 100644 index 0000000..e0b395a --- /dev/null +++ b/doc/driver-model/README.txt @@ -0,0 +1,368 @@ +Driver Model +============ + +This README contains high-level information about driver model, a unified +way of declaring and accessing drivers in U-Boot. The original work was done +by: + + Marek Vasut <marex@denx.de> + Pavel Herrmann <morpheus.ibis@gmail.com> + Viktor Křivák <viktor.krivak@gmail.com> + Tomas Hlavacek <tmshlvck@gmail.com> + +This has been both simplified and extended into the current implementation +by: + + Simon Glass <sjg@chromium.org> + + +Terminology +----------- + +Uclass - a group of devices which operate in the same way. A uclass provides + a way of accessing invidual devices within the group, but always + using the same interface. For example a GPIO uclass provides + operations for get/set value. An I2C uclass may have 10 I2C ports, + 4 with one driver, and 6 with another. + +Driver - some code which talks to a peripheral and presents a higher-level + interface to it. + +Device - an instance of a driver, tied to a particular port or peripheral. + + +How to try it +------------- + +Build U-Boot sandbox and run it: + + make sandbox_config + make + ./u-boot + + (type 'reset' to exit U-Boot) + + +There is a uclass called 'demo'. This uclass handles +saying hello, and reporting its status. There are two drivers in this +uclass: + + - simple: Just prints a message for hello, doesn't implement status + - shape: Prints shapes and reports number of characters printed as status + +The demo class is pretty simple, but not trivial. The intention is that it +can be used for testing, so it will implement all driver model features and +provide good code coverage of them. It does have multiple drivers, it +handles parameter data and platdata (data which tells the driver how +to operate on a particular platform) and it uses private driver data. + +To try it, see the example session below: + +=>demo hello 1 +Hello '@' from 07981110: red 4 +=>demo status 2 +Status: 0 +=>demo hello 2 +g +r@ +e@@ +e@@@ +n@@@@ +g@@@@@ +=>demo status 2 +Status: 21 +=>demo hello 4 ^ + y^^^ + e^^^^^ +l^^^^^^^ +l^^^^^^^ + o^^^^^ + w^^^ +=>demo status 4 +Status: 36 +=> + + +Running the tests +----------------- + +The intent with driver model is that the core portion has 100% test coverage +in sandbox, and every uclass has its own test. As a move towards this, tests +are provided in test/dm. To run them, try: + + ./test/dm/test-dm.sh + +You should see something like this: + + <...U-Boot banner...> + Running 12 driver model tests + Test: dm_test_autobind + Test: dm_test_autoprobe + Test: dm_test_children + Test: dm_test_fdt + Test: dm_test_gpio + sandbox_gpio: sb_gpio_get_value: error: offset 4 not reserved + Test: dm_test_leak + Warning: Please add '#define DEBUG' to the top of common/dlmalloc.c + Warning: Please add '#define DEBUG' to the top of common/dlmalloc.c + Test: dm_test_lifecycle + Test: dm_test_operations + Test: dm_test_ordering + Test: dm_test_platdata + Test: dm_test_remove + Test: dm_test_uclass + Failures: 0 + +(You can add '#define DEBUG' as suggested to check for memory leaks) + + +What is going on? +----------------- + +Let's start at the top. The demo command is in common/cmd_demo.c. It does +the usual command procesing and then: + + struct device *demo_dev; + + ret = uclass_get_device(UCLASS_DEMO, devnum, &demo_dev); + +UCLASS_DEMO means the class of devices which implement 'demo'. Other +classes might be MMC, or GPIO, hashing or serial. The idea is that the +devices in the class all share a particular way of working. The class +presents a unified view of all these devices to U-Boot. + +This function looks up a device for the demo uclass. Given a device +number we can find the device because all devices have registered with +the UCLASS_DEMO uclass. + +The device is automatically activated ready for use by uclass_get_device(). + +Now that we have the device we can do things like: + + return demo_hello(demo_dev, ch); + +This function is in the demo uclass. It takes care of calling the 'hello' +method of the relevant driver. Bearing in mind that there are two drivers, +this particular device may use one or other of them. + +The code for demo_hello() is in drivers/demo/demo-uclass.c: + +int demo_hello(struct device *dev, int ch) +{ + const struct demo_ops *ops = device_get_ops(dev); + + if (!ops->hello) + return -ENOSYS; + + return ops->hello(dev, ch); +} + +As you can see it just calls the relevant driver method. One of these is +in drivers/demo/demo-simple.c: + +static int simple_hello(struct device *dev, int ch) +{ + const struct dm_demo_pdata *pdata = dev_get_platdata(dev); + + printf("Hello from %08x: %s %d\n", map_to_sysmem(dev), + pdata->colour, pdata->sides); + + return 0; +} + + +So that is a trip from top (command execution) to bottom (driver action) +but it leaves a lot of topics to address. + + +Declaring Drivers +----------------- + +A driver declaration looks something like this (see +drivers/demo/demo-shape.c): + +static const struct demo_ops shape_ops = { + .hello = shape_hello, + .status = shape_status, +}; + +U_BOOT_DRIVER(demo_shape_drv) = { + .name = "demo_shape_drv", + .id = UCLASS_DEMO, + .ops = &shape_ops, + .priv_data_size = sizeof(struct shape_data), +}; + + +This driver has two methods (hello and status) and requires a bit of +private data (accessible through dev_get_priv(dev) once the driver has +been probed). It is a member of UCLASS_DEMO so will register itself +there. + +In U_BOOT_DRIVER it is also possible to specify special methods for bind +and unbind, and these are called at appropriate times. For many drivers +it is hoped that only 'probe' and 'remove' will be needed. + +The U_BOOT_DRIVER macro creates a data structure accessible from C, +so driver model can find the drivers that are available. + +The methods a device can provide are documented in the device.h header. +Briefly, they are: + + bind - make the driver model aware of a device (bind it to its driver) + unbind - make the driver model forget the device + ofdata_to_platdata - convert device tree data to platdata - see later + probe - make a device ready for use + remove - remove a device so it cannot be used until probed again + +The sequence to get a device to work is bind, ofdata_to_platdata (if using +device tree) and probe. + + +Platform Data +------------- + +Where does the platform data come from? See demo-pdata.c which +sets up a table of driver names and their associated platform data. +The data can be interpreted by the drivers however they like - it is +basically a communication scheme between the board-specific code and +the generic drivers, which are intended to work on any board. + +Drivers can acceess their data via dev->info->platdata. Here is +the declaration for the platform data, which would normally appear +in the board file. + + static const struct dm_demo_cdata red_square = { + .colour = "red", + .sides = 4. + }; + static const struct driver_info info[] = { + { + .name = "demo_shape_drv", + .platdata = &red_square, + }, + }; + + demo1 = driver_bind(root, &info[0]); + + +Device Tree +----------- + +While platdata is useful, a more flexible way of providing device data is +by using device tree. With device tree we replace the above code with the +following device tree fragment: + + red-square { + compatible = "demo-shape"; + colour = "red"; + sides = <4>; + }; + + +The easiest way to make this work it to add a few members to the driver: + + .platdata_auto_alloc_size = sizeof(struct dm_test_pdata), + .ofdata_to_platdata = testfdt_ofdata_to_platdata, + .probe = testfdt_drv_probe, + +The 'auto_alloc' feature allowed space for the platdata to be allocated +and zeroed before the driver's ofdata_to_platdata method is called. This +method reads the information out of the device tree and puts it in +dev->platdata. Then the probe method is called to set up the device. + +Note that both methods are optional. If you provide an ofdata_to_platdata +method then it wlil be called first (after bind). If you provide a probe +method it will be called next. + +If you don't want to have the platdata automatically allocated then you +can leave out platdata_auto_alloc_size. In this case you can use malloc +in your ofdata_to_platdata (or probe) method to allocate the required memory, +and you should free it in the remove method. + + +Declaring Uclasses +------------------ + +The demo uclass is declared like this: + +U_BOOT_CLASS(demo) = { + .id = UCLASS_DEMO, +}; + +It is also possible to specify special methods for probe, etc. The uclass +numbering comes from include/dm/uclass.h. To add a new uclass, add to the +end of the enum there, then declare your uclass as above. + + +Data Structures +--------------- + +Driver model uses a doubly-linked list as the basic data structure. Some +nodes have several lists running through them. Creating a more efficient +data structure might be worthwhile in some rare cases, once we understand +what the bottlenecks are. + + +Changes since v1 +---------------- + +For the record, this implementation uses a very similar approach to the +original patches, but makes at least the following changes: + +- Tried to agressively remove boilerplate, so that for most drivers there +is little or no 'driver model' code to write. +- Moved some data from code into data structure - e.g. store a pointer to +the driver operations structure in the driver, rather than passing it +to the driver bind function. +- Rename some structures to make them more similar to Linux (struct device +instead of struct instance, struct platdata, etc.) +- Change the name 'core' to 'uclass', meaning U-Boot class. It seems that +this concept relates to a class of drivers (or a subsystem). We shouldn't +use 'class' since it is a C++ reserved word, so U-Boot class (uclass) seems +better than 'core'. +- Remove 'struct driver_instance' and just use a single 'struct device'. +This removes a level of indirection that doesn't seem necessary. +- Built in device tree support, to avoid the need for platdata +- Removed the concept of driver relocation, and just make it possible for +the new driver (created after relocation) to access the old driver data. +I feel that relocation is a very special case and will only apply to a few +drivers, many of which can/will just re-init anyway. So the overhead of +dealing with this might not be worth it. +- Implemented a GPIO system, trying to keep it simple + + +Things to punt for later +------------------------ + +- SPL support - this will have to be present before many drivers can be +converted, but it seems like we can add it once we are happy with the +core implementation. +- Pre-relocation support - similar story + +That is not to say that no thinking has gone into these - in fact there +is quite a lot there. However, getting these right is non-trivial and +there is a high cost associated with going down the wrong path. + +For SPL, it may be possible to fit in a simplified driver model with only +bind and probe methods, to reduce size. + +For pre-relocation we can simply call the driver model init function. Then +post relocation we throw that away and re-init driver model again. For drivers +which require some sort of continuity between pre- and post-relocation +devices, we can provide access to the pre-relocation device pointers. + +Uclasses are statically numbered at compile time. It would be possible to +change this to dynamic numbering, but then we would require some sort of +lookup service, perhaps searching by name. This is slightly less efficient +so has been left out for now. One small advantage of dynamic numbering might +be fewer merge conflicts in uclass-id.h. + + +Simon Glass +sjg@chromium.org +April 2013 +Updated 7-May-13 +Updated 14-Jun-13 +Updated 18-Oct-13 +Updated 5-Nov-13 diff --git a/doc/driver-model/UDM-block.txt b/doc/driver-model/UDM-block.txt deleted file mode 100644 index 0437d9b..0000000 --- a/doc/driver-model/UDM-block.txt +++ /dev/null @@ -1,278 +0,0 @@ -The U-Boot Driver Model Project -=============================== -Block device subsystem analysis -=============================== - -Pavel Herrmann <morpheus.ibis@gmail.com> -2012-03-08 - -I) Overview ------------ - - U-Boot currently implements several distinct APIs for block devices - some - drivers use the SATA API, some drivers use the IDE API, sym53c8xx and - AHCI use the SCSI API, mg_disk has a separate API, and systemace also has a - separate API. There are also MMC and USB APIs used outside of drivers/block, - those will be detailed in their specific documents. - - Block devices are described by block_dev_desc structure, that holds, among - other things, the read/write/erase callbacks. Block device structures are - stored in any way depending on the API, but can be accessed by - - block_dev_desc_t * $api_get_dev(int dev) - - function, as seen in disk/part.c. - - 1) SATA interface - ----------------- - - The SATA interface drivers implement the following functions: - - int init_sata(int dev) - int scan_sata(int dev) - ulong sata_read(int dev, ulong blknr, ulong blkcnt, void *buffer) - ulong sata_write(int dev, ulong blknr, ulong blkcnt, const void *buffer) - - Block devices are kept in sata_dev_desc[], which is prefilled with values - common to all SATA devices in cmd_sata.c, and then modified in init_sata - function in the drivers. Callbacks of the block device use SATA API - directly. The sata_get_dev function is defined in cmd_sata.c. - - 2) SCSI interface - ----------------- - - The SCSI interface drivers implement the following functions: - - void scsi_print_error(ccb *pccb) - int scsi_exec(ccb *pccb) - void scsi_bus_reset(void) - void scsi_low_level_init(int busdevfunc) - - The SCSI API works through the scsi_exec function, the actual operation - requested is found in the ccb structure. - - Block devices are kept in scsi_dev_desc[], which lives only in cmd_scsi.c. - Callbacks of the block device use functions from cmd_scsi.c, which in turn - call scsi_exec of the controller. The scsi_get_dev function is also defined - in cmd_scsi.c. - - 3) mg_disk interface - -------------------- - - The mg_disk interface drivers implement the following functions: - - struct mg_drv_data* mg_get_drv_data (void) - uint mg_disk_init (void) - uint mg_disk_read (u32 addr, u8 *buff, u32 len) - uint mg_disk_write(u32 addr, u8 *buff, u32 len) - uint mg_disk_write_sects(void *buff, u32 sect_num, u32 sect_cnt) - uint mg_disk_read_sects(void *buff, u32 sect_num, u32 sect_cnt) - - The mg_get_drv_data function is to be overridden per-board, but there are no - board in-tree that do this. - - Only one driver for this API exists, and it only supports one block device. - Callbacks for this device are implemented in mg_disk.c and call the mg_disk - API. The mg_disk_get_dev function is defined in mg_disk.c and ignores the - device number, always returning the same device. - - 4) systemace interface - ---------------------- - - The systemace interface does not define any driver API, and has no command - itself. The single defined function is systemace_get_devs() from - systemace.c, which returns a single static structure for the only supported - block device. Callbacks for this device are also implemented in systemace.c. - - 5) IDE interface - ---------------- - - The IDE interface drivers implement the following functions, but only if - CONFIG_IDE_AHB is set: - - uchar ide_read_register(int dev, unsigned int port); - void ide_write_register(int dev, unsigned int port, unsigned char val); - void ide_read_data(int dev, ulong *sect_buf, int words); - void ide_write_data(int dev, const ulong *sect_buf, int words); - - The first two functions are called from ide_inb()/ide_outb(), and will - default to direct memory access if CONFIG_IDE_AHB is not set, or - ide_inb()/ide_outb() functions will get overridden by the board altogether. - - The second two functions are called from input_data()/output_data() - functions, and also default to direct memory access, but cannot be - overridden by the board. - - One function shared by IDE drivers (but not defined in ide.h) is - int ide_preinit(void) - This function gets called from ide_init in cmd_ide.c if CONFIG_IDE_PREINIT - is defined, and will do the driver-specific initialization of the device. - - Block devices are kept in ide_dev_desc[], which is filled in cmd_ide.c. - Callbacks of the block device are defined in cmd_ide.c, and use the - ide_inb()/ide_outb()/input_data()/output_data() functions mentioned above. - The ide_get_dev function is defined in cmd_ide.c. - -II) Approach ------------- - - A new block controller core and an associated API will be created to mimic the - current SATA API, its drivers will have the following ops: - - struct block_ctrl_ops { - int scan(instance *i); - int reset(instance *i, int port); - lbaint_t read(instance *i, int port, lbaint_t start, lbatin_t length, - void *buffer); - lbaint_t write(instance *i, int port, lbaint_t start, lbatin_t length, - void*buffer); - } - - The current sata_init() function will be changed into the driver probe() - function. The read() and write() functions should never be called directly, - instead they should be called by block device driver for disks. - - Other block APIs would either be transformed into this API, or be kept as - legacy for old drivers, or be dropped altogether. - - Legacy driver APIs will each have its own driver core that will contain the - shared logic, which is currently located mostly in cmd_* files. Callbacks for - block device drivers will then probably be implemented as a part of the core - logic, and will use the driver ops (which will copy current state of - respective APIs) to do the work. - - All drivers will be cleaned up, most ifdefs should be converted into - platform_data, to enable support for multiple devices with different settings. - - A new block device core will also be created, and will keep track of all - block devices on all interfaces. - - Current block_dev_desc structure will be changed to fit the driver model, all - identification and configuration will be placed in private data, and - a single accessor and modifier will be defined, to accommodate the need for - different sets of options for different interfaces, while keeping the - structure small. The new block device drivers will have the following ops - structure (lbaint_t is either 32bit or 64bit unsigned, depending on - CONFIG_LBA48): - - struct blockdev_ops { - lbaint_t (*block_read)(struct instance *i, lbaint_t start, lbaint_t blkcnt, - void *buffer); - lbaint_t (*block_write)(struct instance *i, lbaint_t start, lbaint_t blkcnt, - void *buffer); - lbaint_t (*block_erase)(struct instance *i, lbaint_t start, lbaint_t blkcnt - ); - int (*get_option)(struct instance *i, enum blockdev_option_code op, - struct option *res); - int (*set_option)(struct instance *i, enum blockdev_option_code op, - struct option *val); - } - - struct option { - uint32_t flags - union data { - uint64_t data_u; - char* data_s; - void* data_p; - } - } - - enum blockdev_option_code { - BLKD_OPT_IFTYPE=0, - BLKD_OPT_TYPE, - BLKD_OPT_BLOCKSIZE, - BLKD_OPT_BLOCKCOUNT, - BLKD_OPT_REMOVABLE, - BLKD_OPT_LBA48, - BLKD_OPT_VENDOR, - BLKD_OPT_PRODICT, - BLKD_OPT_REVISION, - BLKD_OPT_SCSILUN, - BLKD_OPT_SCSITARGET, - BLKD_OPT_OFFSET - } - - Flags in option above will contain the type of returned data (which should be - checked against what is expected, even though the option requested should - specify it), and a flag to indicate whether the returned pointer needs to be - free()'d. - - The block device core will contain the logic now located in disk/part.c and - related files, and will be used to forward requests to block devices. The API - for the block device core will copy the ops of a block device (with a string - identifier instead of instance pointer). This means that partitions will also - be handled by the block device core, and exported as block devices, making - them transparent to the rest of the code. - - Sadly, this will change how file systems can access the devices, and thus will - affect a lot of places. However, these changes should be localized and easy to - implement. - - AHCI driver will be rewritten to fit the new unified block controller API, - making SCSI API easy to merge with sym53c8xx, or remove it once the device - driver has died. - - Optionally, IDE core may be changed into one driver with unified block - controller API, as most of it is already in one place and device drivers are - just sets of hooks. Additionally, mg_disk driver is unused and may be removed - in near future. - - -III) Analysis of in-tree drivers --------------------------------- - - ahci.c - ------ - SCSI API, will be rewritten for a different API. - - ata_piix.c - ---------- - SATA API, easy to port. - - fsl_sata.c - ---------- - SATA API, few CONFIG macros, easy to port. - - ftide020.c - ---------- - IDE API, defines CONFIG_IDE_AHB and ide_preinit hook functions. - - mg_disk.c - --------- - Single driver with mg_disk API, not much to change, easy to port. - - mvsata_ide.c - ------------ - IDE API, only defines ide_preinit hook function. - - mxc_ata.c - --------- - IDE API, only defines ide_preinit hook function. - - pata_bfin.c - ----------- - SATA API, easy to port. - - sata_dwc.c - ---------- - SATA API, easy to port. - - sata_sil3114.c - -------------- - SATA API, easy to port. - - sata_sil.c - ---------- - SATA API, easy to port. - - sil680.c - -------- - IDE API, only defines ide_preinit hook function. - - sym53c8xx.c - ----------- - SCSI API, may be merged with code from cmd_scsi. - - systemace.c - ----------- - Single driver with systemace API, not much to change, easy to port. diff --git a/doc/driver-model/UDM-cores.txt b/doc/driver-model/UDM-cores.txt deleted file mode 100644 index 6032333..0000000 --- a/doc/driver-model/UDM-cores.txt +++ /dev/null @@ -1,126 +0,0 @@ -The U-Boot Driver Model Project -=============================== -Driver cores API document -========================= - -Pavel Herrmann <morpheus.ibis@gmail.com> - -1) Overview ------------ - Driver cores will be used as a wrapper for devices of the same type, and as - an abstraction for device driver APIs. For each driver API (which roughly - correspond to device types), there will be one driver core. Each driver core - will implement three APIs - a driver API (which will be the same as API of - drivers the core wraps around), a core API (which will be implemented by all - cores) and a command API (core-specific API which will be exposed to - commands). - - A) Command API - The command API will provide access to shared functionality for a specific - device, which is currently located mostly in commands. Commands will be - rewritten to be more lightweight by using this API. As this API will be - different for each core, it is out of scope of this document. - - B) Driver API - The driver API will act as a wrapper around actual device drivers, - providing a single entrypoint for device access. All functions in this API - have an instance* argument (probably called "this" or "i"), which will be - examined by the core, and a correct function for the specified driver will - get called. - - If the core gets called with a group instance pointer (as discussed in - design), it will automatically select the instance that is associated - with this core, and use it as target of the call. if the group contains - multiple instances of a single type, the caller must explicitly use an - accessor to select the correct instance. - - This accessor will look like: - struct instance *get_instance_from_group(struct instance *group, int i) - - When called with a non-group instance, it will simply return the instance. - - C) Core API - The core API will be implemented by all cores, and will provide - functionality for getting driver instances from non-driver code. This API - will consist of following functions: - - int get_count(struct instance *core); - struct instance* get_instance(struct instance *core, int index); - int init(struct instance *core); - int bind(struct instance *core, struct instance *dev, void *ops, - void *hint); - int unbind(struct instance *core, instance *dev); - int replace(struct instance *core, struct_instance *new_dev, - struct instance *old_dev); - int destroy(struct instance *core); - int reloc(struct instance *new_core, struct instance *old_core); - - The 'hint' parameter of bind() serves for additional data a driver can - pass to the core, to help it create the correct internal state for this - instance. the replace() function will get called during instance - relocation, and will replace the old instance with the new one, keeping - the internal state untouched. - - -2) Lifetime of a driver core ----------------------------- - Driver cores will be initialized at runtime, to limit memory footprint in - early-init stage, when we have to fit into ~1KB of memory. All active cores - will be stored in a tree structure (referenced as "Core tree") in global data, - which provides good tradeoff between size and access time. - Every core will have a number constant associated with it, which will be used - to find the instance in Core tree, and to refer to the core in all calls - working with the Core tree. - The Core Tree should be implemented using B-tree (or a similar structure) - to guarantee acceptable time overhead in all cases. - - Code for working with the core (i2c in this example) follows: - - core_init(CORE_I2C); - This will check whether we already have a i2c core, and if not it creates - a new instance and adds it into the Core tree. This will not be exported, - all code should depend on get_core_instance to init the core when - necessary. - - get_core_instance(CORE_I2C); - This is an accessor into the Core tree, which will return the instance - of i2c core, creating it if necessary - - core_bind(CORE_I2C, instance, driver_ops); - This will get called in bind() function of a driver, and will add the - instance into cores internal list of devices. If the core is not found, it - will get created. - - driver_activate(instance *inst); - This call will recursively activate all devices necessary for using the - specified device. the code could be simplified as: - { - if (is_activated(inst)) - return; - driver_activate(inst->bus); - get_driver(inst)->probe(inst); - } - - The case with multiple parents will need to be handled here as well. - get_driver is an accessor to available drivers, which will get struct - driver based on a name in the instance. - - i2c_write(instance *inst, ...); - An actual call to some method of the driver. This code will look like: - { - driver_activate(inst); - struct instance *core = get_core_instance(CORE_I2C); - device_ops = get_ops(inst); - device_ops->write(...); - } - - get_ops will not be an exported function, it will be internal and specific - to the core, as it needs to know how are the ops stored, and what type - they are. - - Please note that above examples represent the algorithm, not the actual code, - as they are missing checks for validity of return values. - - core_init() function will get called the first time the core is requested, - either by core_link() or core_get_instance(). This way, the cores will get - created only when they are necessary, which will reduce our memory footprint. diff --git a/doc/driver-model/UDM-design.txt b/doc/driver-model/UDM-design.txt deleted file mode 100644 index 9f03bba..0000000 --- a/doc/driver-model/UDM-design.txt +++ /dev/null @@ -1,315 +0,0 @@ -The U-Boot Driver Model Project -=============================== -Design document -=============== -Marek Vasut <marek.vasut@gmail.com> -Pavel Herrmann <morpheus.ibis@gmail.com> -2012-05-17 - -I) The modular concept ----------------------- - -The driver core design is done with modularity in mind. The long-term plan is to -extend this modularity to allow loading not only drivers, but various other -objects into U-Boot at runtime -- like commands, support for other boards etc. - -II) Driver core initialization stages -------------------------------------- - -The drivers have to be initialized in two stages, since the U-Boot bootloader -runs in two stages itself. The first stage is the one which is executed before -the bootloader itself is relocated. The second stage then happens after -relocation. - - 1) First stage - -------------- - - The first stage runs after the bootloader did very basic hardware init. This - means the stack pointer was configured, caches disabled and that's about it. - The problem with this part is the memory management isn't running at all. To - make things even worse, at this point, the RAM is still likely uninitialized - and therefore unavailable. - - 2) Second stage - --------------- - - At this stage, the bootloader has initialized RAM and is running from it's - final location. Dynamic memory allocations are working at this point. Most of - the driver initialization is executed here. - -III) The drivers ----------------- - - 1) The structure of a driver - ---------------------------- - - The driver will contain a structure located in a separate section, which - will allow linker to create a list of compiled-in drivers at compile time. - Let's call this list "driver_list". - - struct driver __attribute__((section(driver_list))) { - /* The name of the driver */ - char name[STATIC_CONFIG_DRIVER_NAME_LENGTH]; - - /* - * This function should connect this driver with cores it depends on and - * with other drivers, likely bus drivers - */ - int (*bind)(struct instance *i); - - /* This function actually initializes the hardware. */ - int (*probe)(struct instance *i); - - /* - * The function of the driver called when U-Boot finished relocation. - * This is particularly important to eg. move pointers to DMA buffers - * and such from the location before relocation to their final location. - */ - int (*reloc)(struct instance *i); - - /* - * This is called when the driver is shuting down, to deinitialize the - * hardware. - */ - int (*remove)(struct instance *i); - - /* This is called to remove the driver from the driver tree */ - int (*unbind)(struct instance *i); - - /* This is a list of cores this driver depends on */ - struct driver *cores[]; - }; - - The cores[] array in here is very important. It allows u-boot to figure out, - in compile-time, which possible cores can be activated at runtime. Therefore - if there are cores that won't be ever activated, GCC LTO might remove them - from the final binary. Actually, this information might be used to drive build - of the cores. - - FIXME: Should *cores[] be really struct driver, pointing to drivers that - represent the cores? Shouldn't it be core instance pointer? - - 2) Instantiation of a driver - ---------------------------- - - The driver is instantiated by calling: - - driver_bind(struct instance *bus, const struct driver_info *di) - - The "struct instance *bus" is a pointer to a bus with which this driver should - be registered with. The "root" bus pointer is supplied to the board init - functions. - - FIXME: We need some functions that will return list of busses of certain type - registered with the system so the user can find proper instance even if - he has no bus pointer (this will come handy if the user isn't - registering the driver from board init function, but somewhere else). - - The "const struct driver_info *di" pointer points to a structure defining the - driver to be registered. The structure is defined as follows: - - struct driver_info { - char name[STATIC_CONFIG_DRIVER_NAME_LENGTH]; - void *platform_data; - } - - The instantiation of a driver by calling driver_bind() creates an instance - of the driver by allocating "struct driver_instance". Note that only struct - instance is passed to the driver. The wrapping struct driver_instance is there - for purposes of the driver core: - - struct driver_instance { - uint32_t flags; - struct instance i; - }; - - struct instance { - /* Pointer to a driver information passed by driver_register() */ - const struct driver_info *info; - /* Pointer to a bus this driver is bound with */ - struct instance *bus; - /* Pointer to this driver's own private data */ - void *private_data; - /* Pointer to the first block of successor nodes (optional) */ - struct successor_block *succ; - } - - The instantiation of a driver does not mean the hardware is initialized. The - driver_bind() call only creates the instance of the driver, fills in the "bus" - pointer and calls the drivers' .bind() function. The .bind() function of the - driver should hook the driver with the remaining cores and/or drivers it - depends on. - - It's important to note here, that in case the driver instance has multiple - parents, such parent can be connected with this instance by calling: - - driver_link(struct instance *parent, struct instance *dev); - - This will connect the other parent driver with the newly instantiated driver. - Note that this must be called after driver_bind() and before driver_acticate() - (driver_activate() will be explained below). To allow struct instance to have - multiple parent pointer, the struct instance *bus will utilize it's last bit - to indicate if this is a pointer to struct instance or to an array if - instances, struct successor block. The approach is similar as the approach to - *succ in struct instance, described in the following paragraph. - - The last pointer of the struct instance, the pointer to successor nodes, is - used only in case of a bus driver. Otherwise the pointer contains NULL value. - The last bit of this field indicates if this is a bus having a single child - node (so the last bit is 0) or if this bus has multiple child nodes (the last - bit is 1). In the former case, the driver core should clear the last bit and - this pointer points directly to the child node. In the later case of a bus - driver, the pointer points to an instance of structure: - - struct successor_block { - /* Array of pointers to instances of devices attached to this bus */ - struct instance *dev[BLOCKING_FACTOR]; - /* Pointer to next block of successors */ - struct successor_block *next; - } - - Some of the *dev[] array members might be NULL in case there are no more - devices attached. The *next is NULL in case the list of attached devices - doesn't continue anymore. The BLOCKING_FACTOR is used to allocate multiple - slots for successor devices at once to avoid fragmentation of memory. - - 3) The bind() function of a driver - ---------------------------------- - - The bind function of a driver connects the driver with various cores the - driver provides functions for. The driver model related part will look like - the following example for a bus driver: - - int driver_bind(struct instance *in) - { - ... - core_bind(&core_i2c_static_instance, in, i2c_bus_funcs); - ... - } - - FIXME: What if we need to run-time determine, depending on some hardware - register, what kind of i2c_bus_funcs to pass? - - This makes the i2c core aware of a new bus. The i2c_bus_funcs is a constant - structure of functions any i2c bus driver must provide to work. This will - allow the i2c command operate with the bus. The core_i2c_static_instance is - the pointer to the instance of a core this driver provides function to. - - FIXME: Maybe replace "core-i2c" with CORE_I2C global pointer to an instance of - the core? - - 4) The instantiation of a core driver - ------------------------------------- - - The core driver is special in the way that it's single-instance driver. It is - always present in the system, though it might not be activated. The fact that - it's single instance allows it to be instantiated at compile time. - - Therefore, all possible structures of this driver can be in read-only memory, - especially struct driver and struct driver_instance. But the successor list, - which needs special treatment. - - To solve the problem with a successor list and the core driver flags, a new - entry in struct gd (global data) will be introduced. This entry will point to - runtime allocated array of struct driver_instance. It will be possible to - allocate the exact amount of struct driver_instance necessary, as the number - of cores that might be activated will be known at compile time. The cores will - then behave like any usual driver. - - Pointers to the struct instance of cores can be computed at compile time, - therefore allowing the resulting u-boot binary to save some overhead. - - 5) The probe() function of a driver - ----------------------------------- - - The probe function of a driver allocates necessary resources and does required - initialization of the hardware itself. This is usually called only when the - driver is needed, as a part of the defered probe mechanism. - - The driver core should implement a function called - - int driver_activate(struct instance *in); - - which should call the .probe() function of the driver and then configure the - state of the driver instance to "ACTIVATED". This state of a driver instance - should be stored in a wrap-around structure for the structure instance, the - struct driver_instance. - - 6) The command side interface to a driver - ----------------------------------------- - - The U-Boot command shall communicate only with the specific driver core. The - driver core in turn exports necessary API towards the command. - - 7) Demonstration imaginary board - -------------------------------- - - Consider the following computer: - - * - | - +-- System power management logic - | - +-- CPU clock controlling logc - | - +-- NAND controller - | | - | +-- NAND flash chip - | - +-- 128MB of DDR DRAM - | - +-- I2C bus #0 - | | - | +-- RTC - | | - | +-- EEPROM #0 - | | - | +-- EEPROM #1 - | - +-- USB host-only IP core - | | - | +-- USB storage device - | - +-- USB OTG-capable IP core - | | - | +-- connection to the host PC - | - +-- GPIO - | | - | +-- User LED #0 - | | - | +-- User LED #1 - | - +-- UART0 - | - +-- UART1 - | - +-- Ethernet controller #0 - | - +-- Ethernet controller #1 - | - +-- Audio codec - | - +-- PCI bridge - | | - | +-- Ethernet controller #2 - | | - | +-- SPI host card - | | | - | | +-- Audio amplifier (must be operational before codec) - | | - | +-- GPIO host card - | | - | +-- User LED #2 - | - +-- LCD controller - | - +-- PWM controller (must be enabled after LCD controller) - | - +-- SPI host controller - | | - | +-- SD/MMC connected via SPI - | | - | +-- SPI flash - | - +-- CPLD/FPGA with stored configuration of the board diff --git a/doc/driver-model/UDM-fpga.txt b/doc/driver-model/UDM-fpga.txt deleted file mode 100644 index 4f9df94..0000000 --- a/doc/driver-model/UDM-fpga.txt +++ /dev/null @@ -1,115 +0,0 @@ -The U-Boot Driver Model Project -=============================== -I/O system analysis -=================== -Marek Vasut <marek.vasut@gmail.com> -2012-02-21 - -I) Overview ------------ - -The current FPGA implementation is handled by command "fpga". This command in -turn calls the following functions: - -fpga_info() -fpga_load() -fpga_dump() - -These functions are implemented by what appears to be FPGA multiplexer, located -in drivers/fpga/fpga.c . This code determines which device to operate with -depending on the device ID. - -The fpga_info() function is multiplexer of the functions providing information -about the particular FPGA device. These functions are implemented in the drivers -for the particular FPGA device: - -xilinx_info() -altera_info() -lattice_info() - -Similar approach is used for fpga_load(), which multiplexes "xilinx_load()", -"altera_load()" and "lattice_load()" and is used to load firmware into the FPGA -device. - -The fpga_dump() function, which prints the contents of the FPGA device, is no -different either, by multiplexing "xilinx_dump()", "altera_dump()" and -"lattice_dump()" functions. - -Finally, each new FPGA device is registered by calling "fpga_add()" function. -This function takes two arguments, the second one being particularly important, -because it's basically what will become platform_data. Currently, it's data that -are passed to the driver from the board/platform code. - -II) Approach ------------- - -The path to conversion of the FPGA subsystem will be very straightforward, since -the FPGA subsystem is already quite dynamic. Multiple things will need to be -modified though. - -First is the registration of the new FPGA device towards the FPGA core. This -will be achieved by calling: - - fpga_device_register(struct instance *i, const struct fpga_ops *ops); - -The particularly interesting part is the struct fpga_ops, which contains -operations supported by the FPGA device. These are basically the already used -calls in the current implementation: - -struct fpga_ops { - int info(struct instance *i); - int load(struct instance *i, const char *buf, size_t size); - int dump(struct instance *i, const char *buf, size_t size); -} - -The other piece that'll have to be modified is how the devices are tracked. -It'll be necessary to introduce a linked list of devices within the FPGA core -instead of tracking them by ID number. - -Next, the "Xilinx_desc", "Lattice_desc" and "Altera_desc" structures will have -to be moved to driver's private_data. Finally, structures passed from the board -and/or platform files, like "Xilinx_Virtex2_Slave_SelectMap_fns" would be passed -via platform_data to the driver. - -III) Analysis of in-tree drivers --------------------------------- - - 1) Altera driver - ---------------- - The driver is realized using the following files: - - drivers/fpga/altera.c - drivers/fpga/ACEX1K.c - drivers/fpga/cyclon2.c - drivers/fpga/stratixII.c - - All of the sub-drivers implement basically the same info-load-dump interface - and there's no expected problem during the conversion. The driver itself will - be realised by altera.c and all the sub-drivers will be linked in. The - distinction will be done by passing different platform data. - - 2) Lattice driver - ----------------- - The driver is realized using the following files: - - drivers/fpga/lattice.c - drivers/fpga/ivm_core.c - - This driver also implements the standard interface, but to realise the - operations with the FPGA device, uses functions from "ivm_core.c" file. This - file implements the main communications logic and has to be linked in together - with "lattice.c". No problem converting is expected here. - - 3) Xilinx driver - ---------------- - The driver is realized using the following files: - - drivers/fpga/xilinx.c - drivers/fpga/spartan2.c - drivers/fpga/spartan3.c - drivers/fpga/virtex2.c - - This set of sub-drivers is special by defining a big set of macros in - "include/spartan3.h" and similar files. These macros would need to be either - rewritten or replaced. Otherwise, there are no problems expected during the - conversion process. diff --git a/doc/driver-model/UDM-gpio.txt b/doc/driver-model/UDM-gpio.txt deleted file mode 100644 index 585d458..0000000 --- a/doc/driver-model/UDM-gpio.txt +++ /dev/null @@ -1,106 +0,0 @@ -The U-Boot Driver Model Project -=============================== -GPIO analysis -============= -Viktor Krivak <viktor.krivak@gmail.com> -2012-02-24 - -I) Overview ------------ - - At this moment U-Boot provides standard API that consists of 7 functions. - - int gpio_request(unsigned gpio, const char *label) - int gpio_free(unsigned gpio) - int gpio_direction_input(unsigned gpio) - int gpio_direction_output(unsigned gpio, int value) - int gpio_get_value(unsigned gpio) - void gpio_set_value(unsigned gpio, int value) - - Methods "gpio_request()" and "gpio_free()" are used for claiming and releasing - GPIOs. First one should check if the desired pin exists and if the pin wasn't - requested already elsewhere. The method also has a label argument that can be - used for debug purposes. The label argument should be copied into the internal - memory, but only if the DEBUG macro is set. The "gpio_free()" is the exact - opposite. It releases the particular pin. Other methods are used for setting - input or output direction and obtaining or setting values of the pins. - -II) Approach ------------- - - 1) Request and free GPIO - ------------------------ - - The "gpio_request()" implementation is basically the same for all boards. - The function checks if the particular GPIO is correct and checks if the - GPIO pin is still free. If the conditions are met, the method marks the - GPIO claimed in it's internal structure. If macro DEBUG is defined, the - function also copies the label argument to the structure. If the pin is - already locked, the function returns -1 and if DEBUG is defined, certain - debug output is generated, including the contents of the label argument. - The "gpio_free()" function releases the lock and eventually deallocates - data used by the copied label argument. - - 2) Internal data - ---------------- - - Internal data are driver specific. They have to contain some mechanism to - realise the locking though. This can be done for example using a bit field. - - 3) Operations provided by the driver - ------------------------------------ - - The driver operations basically meet API that is already defined and used. - Except for "gpio_request()" and "gpio_free()", all methods can be converted in - a simple manner. The driver provides the following structure: - - struct gpio_driver_ops { - int (*gpio_request)(struct instance *i, unsigned gpio, - const char *label); - int (*gpio_free)(struct instance *i, unsigned gpio); - int (*gpio_direction_input)(struct instance *i, unsigned gpio); - int (*gpio_direction_output)(struct instance *i, unsigned gpio, - int value); - int (*gpio_get_value)(struct instance *i, unsigned gpio); - void (*gpio_set_value)(struct instance *i, unsigned gpio, int value); - } - -III) Analysis of in-tree drivers --------------------------------- - - altera_pio.c - ------------ - Meets standard API. Implements gpio_request() properly. Simple conversion - possible. - - at91_gpio.c - ----------- - Don't meet standard API. Need some other methods to implement. - - da8xx_gpio.c - ------------ - Meets standard API. Implements gpio_request() properly. Simple conversion - possible. - - kw_gpio.c - --------- - Doesn't meet standard API. Needs some other methods to implement and move some - methods to another file. - - mpc83xx_gpio.c - -------------- - Meets standard API. Doesn't implement gpio_request() properly (only checks - if the pin is valid). Simple conversion possible. - - mvgpio.c - -------- - Meets standard API. Doesn't implement gpio_request() properly (only checks - if the pin is valid). Simple conversion possible. - - mvgpio.h - -------- - Wrong placement. Will be moved to another location. - - mvmfp.c - ------- - Wrong placement. Will be moved to another location. diff --git a/doc/driver-model/UDM-hwmon.txt b/doc/driver-model/UDM-hwmon.txt deleted file mode 100644 index 03a96a0..0000000 --- a/doc/driver-model/UDM-hwmon.txt +++ /dev/null @@ -1,118 +0,0 @@ -The U-Boot Driver Model Project -=============================== -Hwmon device subsystem analysis -=============================== - -Tomas Hlavacek <tmshlvck@gmail.com> -2012-03-02 - -I) Overview ------------ - -U-Boot currently implements one API for HW monitoring devices. The -interface is defined in include/dtt.h and comprises of functions: - - void dtt_init(void); - int dtt_init_one(int); - int dtt_read(int sensor, int reg); - int dtt_write(int sensor, int reg, int val); - int dtt_get_temp(int sensor); - -The functions are implemented by a proper device driver in drivers/hwmon -directory and the driver to be compiled in is selected in a Makefile. -Drivers are mutually exclusive. - -Drivers depends on I2O code and naturally on board specific data. There are -few ad-hoc constants put in dtt.h file and driver headers and code. This -has to be consolidated into board specific data or driver headers if those -constants makes sense globally. - - -II) Approach ------------- - - 1) New API - ---------- - In the UDM each hwmon driver would register itself by a function - - int hwmon_device_register(struct instance *i, - struct hwmon_device_ops *o); - - The structure being defined as follows: - - struct hwmon_device_ops { - int (*read)(struct instance *i, int sensor, int reg); - int (*write)(struct instance *i, int sensor, int reg, - int val); - int (*get_temp)(struct instance *i, int sensor); - }; - - - 2) Conversion thougths - ---------------------- - U-Boot hwmon drivers exports virtually the same functions (with exceptions) - and we are considering low number of drivers and code anyway. The interface - is already similar and unified by the interface defined in dtt.h. - Current initialization functions dtt_init() and dtt_init_one() will be - converted into probe() and hwmon_device_register(), so the funcionality will - be kept in more proper places. Besides implementing core registration and - initialization we need to do code cleanup, especially separate - driver-specific and HW specific constants. - - 3) Special consideration due to early initialization - ---------------------------------------------------- - The dtt_init() function call is used during early initialization in - board/gdsys/405ex/io64.c for starting up fans. The dtt code is perfectly - usable in the early stage because it uses only local variables and no heap - memory is required at this level. However the underlying code of I2C has to - keep the same properties with regard to possibility of running in early - initialization stage. - -III) Analysis of in-tree drivers --------------------------------- - - drivers/hwmon/lm81.c - -------------------- - The driver is standard dtt. Simple conversion is possible. - - - drivers/hwmon/ds1722.c - ---------------------- - The driver is not standard dtt, but interface is similar to dtt. - The interface has to be changed in order to comply to above mentioned - specification. - - - drivers/hwmon/ds1775.c - ---------------------- - The driver is standard dtt. Simple conversion is possible. - - - drivers/hwmon/lm73.c - -------------------- - The driver is standard dtt. Simple conversion is possible. - - - drivers/hwmon/lm63.c - -------------------- - The driver is standard dtt. Simple conversion is possible. - - - drivers/hwmon/adt7460.c - ----------------------- - The driver is standard dtt. Simple conversion is possible. - - - drivers/hwmon/lm75.c - -------------------- - The driver is standard dtt. Simple conversion is possible. - - - drivers/hwmon/ds1621.c - ---------------------- - The driver is standard dtt. Simple conversion is possible. - - - drivers/hwmon/adm1021.c - ----------------------- - The driver is standard dtt. Simple conversion is possible. diff --git a/doc/driver-model/UDM-keyboard.txt b/doc/driver-model/UDM-keyboard.txt deleted file mode 100644 index 5babfc5..0000000 --- a/doc/driver-model/UDM-keyboard.txt +++ /dev/null @@ -1,47 +0,0 @@ -The U-Boot Driver Model Project -=============================== -Keyboard input analysis -======================= -Marek Vasut <marek.vasut@gmail.com> -2012-02-20 - -I) Overview ------------ - -The keyboard drivers are most often registered with STDIO subsystem. There are -components of the keyboard drivers though, which operate in severe ad-hoc -manner, often being related to interrupt-driven keypress reception. This -components will require the most sanitization of all parts of keyboard input -subsystem. - -Otherwise, the keyboard is no different from other standard input but with the -necessity to decode scancodes. These are decoded using tables provided by -keyboard drivers. These tables are often driver specific. - -II) Approach ------------- - -The most problematic part is the interrupt driven keypress reception. For this, -the buffers that are currently shared throughout the whole U-Boot would need to -be converted into driver's private data. - -III) Analysis of in-tree drivers --------------------------------- - - board/mpl/common/kbd.c - ---------------------- - This driver is a classic STDIO driver, no problem with conversion is expected. - Only necessary change will be to move this driver to a proper location. - - board/rbc823/kbd.c - ------------------ - This driver is a classic STDIO driver, no problem with conversion is expected. - Only necessary change will be to move this driver to a proper location. - - drivers/input/keyboard.c - ------------------------ - This driver is special in many ways. Firstly because this is a universal stub - driver for converting scancodes from i8042 and the likes. Secondly because the - buffer is filled by various other ad-hoc implementations of keyboard input by - using this buffer as an extern. This will need to be fixed by allowing drivers - to pass certain routines to this driver via platform data. diff --git a/doc/driver-model/UDM-mmc.txt b/doc/driver-model/UDM-mmc.txt deleted file mode 100644 index 97f83a7..0000000 --- a/doc/driver-model/UDM-mmc.txt +++ /dev/null @@ -1,319 +0,0 @@ -The U-Boot Driver Model Project -=============================== -MMC system analysis -=================== -Marek Vasut <marek.vasut@gmail.com> -2012-02-25 - -I) Overview ------------ - -The MMC subsystem is already quite dynamic in it's nature. It's only necessary -to flip the subsystem to properly defined API. - -The probing process of MMC drivers start by calling "mmc_initialize()", -implemented by MMC framework, from the architecture initialization file. The -"mmc_initialize()" function in turn calls "board_mmc_init()" function and if -this doesn't succeed, "cpu_mmc_init()" function is called. It is important to -note that both of the "*_mmc_init()" functions have weak aliases to functions -which automatically fail. - -Both of the "*_mmc_init()" functions though serve only one purpose. To call -driver specific probe function, which in turn actually registers the driver with -MMC subsystem. Each of the driver specific probe functions is currently done in -very ad-hoc manner. - -The registration with the MMC subsystem is done by calling "mmc_register()", -whose argument is a runtime configured structure of information about the MMC -driver. Currently, the information structure is intermixed with driver's internal -data. The description of the structure follows: - -struct mmc { - /* - * API: Allows this driver to be a member of the linked list of all MMC drivers - * registered with MMC subsystem - */ - struct list_head link; - - /* DRIVER: Name of the registered driver */ - char name[32]; - - /* DRIVER: Driver's private data */ - void *priv; - - /* DRIVER: Voltages the host bus can provide */ - uint voltages; - - /* API: Version of the card */ - uint version; - - /* API: Test if the driver was already initialized */ - uint has_init; - - /* DRIVER: Minimum frequency the host bus can provide */ - uint f_min; - - /* DRIVER: Maximum frequency the host bus can provide */ - uint f_max; - - /* API: Is the card SDHC */ - int high_capacity; - - /* API: Actual width of the bus used by the current card */ - uint bus_width; - - /* - * DRIVER: Clock frequency to be configured on the host bus, this is read-only - * for the driver. - */ - uint clock; - - /* API: Capabilities of the card */ - uint card_caps; - - /* DRIVER: MMC bus capabilities */ - uint host_caps; - - /* API: Configuration and ID data retrieved from the card */ - uint ocr; - uint scr[2]; - uint csd[4]; - uint cid[4]; - ushort rca; - - /* API: Partition configuration */ - char part_config; - - /* API: Number of partitions */ - char part_num; - - /* API: Transmission speed */ - uint tran_speed; - - /* API: Read block length */ - uint read_bl_len; - - /* API: Write block length */ - uint write_bl_len; - - /* API: Erase group size */ - uint erase_grp_size; - - /* API: Capacity of the card */ - u64 capacity; - - /* API: Descriptor of this block device */ - block_dev_desc_t block_dev; - - /* DRIVER: Function used to submit command to the card */ - int (*send_cmd)(struct mmc *mmc, - struct mmc_cmd *cmd, struct mmc_data *data); - - /* DRIVER: Function used to configure the host */ - void (*set_ios)(struct mmc *mmc); - - /* DRIVER: Function used to initialize the host */ - int (*init)(struct mmc *mmc); - - /* DRIVER: Function used to report the status of Card Detect pin */ - int (*getcd)(struct mmc *mmc); - - /* - * DRIVER: Maximum amount of blocks sent during multiblock xfer, - * set to 0 to autodetect. - */ - uint b_max; -}; - -The API above is the new API used by most of the drivers. There're still drivers -in the tree that use old, legacy API though. - -2) Approach ------------ - -To convert the MMC subsystem to a proper driver model, the "struct mmc" -structure will have to be properly split in the first place. The result will -consist of multiple parts, first will be the structure defining operations -provided by the MMC driver: - -struct mmc_driver_ops { - /* Function used to submit command to the card */ - int (*send_cmd)(struct mmc *mmc, - struct mmc_cmd *cmd, struct mmc_data *data); - /* DRIVER: Function used to configure the host */ - void (*set_ios)(struct mmc *mmc); - /* Function used to initialize the host */ - int (*init)(struct mmc *mmc); - /* Function used to report the status of Card Detect pin */ - int (*getcd)(struct mmc *mmc); -} - -The second part will define the parameters of the MMC driver: - -struct mmc_driver_params { - /* Voltages the host bus can provide */ - uint32_t voltages; - /* Minimum frequency the host bus can provide */ - uint32_t f_min; - /* Maximum frequency the host bus can provide */ - uint32_t f_max; - /* MMC bus capabilities */ - uint32_t host_caps; - /* - * Maximum amount of blocks sent during multiblock xfer, - * set to 0 to autodetect. - */ - uint32_t b_max; -} - -And finally, the internal per-card data of the MMC subsystem core: - -struct mmc_card_props { - /* Version of the card */ - uint32_t version; - /* Test if the driver was already initializes */ - bool has_init; - /* Is the card SDHC */ - bool high_capacity; - /* Actual width of the bus used by the current card */ - uint8_t bus_width; - /* Capabilities of the card */ - uint32_t card_caps; - /* Configuration and ID data retrieved from the card */ - uint32_t ocr; - uint32_t scr[2]; - uint32_t csd[4]; - uint32_t cid[4]; - uint16_t rca; - /* Partition configuration */ - uint8_t part_config; - /* Number of partitions */ - uint8_t part_num; - /* Transmission speed */ - uint32_t tran_speed; - /* Read block length */ - uint32_t read_bl_len; - /* Write block length */ - uint32_t write_bl_len; - /* Erase group size */ - uint32_t erase_grp_size; - /* Capacity of the card */ - uint64_t capacity; - /* Descriptor of this block device */ - block_dev_desc_t block_dev; -} - -The probe() function will then register the MMC driver by calling: - - mmc_device_register(struct instance *i, struct mmc_driver_ops *o, - struct mmc_driver_params *p); - -The struct mmc_driver_params will have to be dynamic in some cases, but the -driver shouldn't modify it's contents elsewhere than in probe() call. - -Next, since the MMC drivers will now be consistently registered into the driver -tree from board file, the functions "board_mmc_init()" and "cpu_mmc_init()" will -disappear altogether. - -As for the legacy drivers, these will either be converted or removed altogether. - -III) Analysis of in-tree drivers --------------------------------- - - arm_pl180_mmci.c - ---------------- - Follows the new API and also has a good encapsulation of the whole driver. The - conversion here will be simple. - - atmel_mci.c - ----------- - This driver uses the legacy API and should be removed unless converted. It is - probably possbible to replace this driver with gen_atmel_mci.c . No conversion - will be done on this driver. - - bfin_sdh.c - ---------- - Follows the new API and also has a good encapsulation of the whole driver. The - conversion here will be simple. - - davinci_mmc.c - ------------- - Follows the new API and also has a good encapsulation of the whole driver. The - conversion here will be simple. - - fsl_esdhc.c - ----------- - Follows the new API and also has a good encapsulation of the whole driver. The - conversion here will be simple, unless some problem appears due to the FDT - component of the driver. - - ftsdc010_esdhc.c - ---------------- - Follows the new API and also has a good encapsulation of the whole driver. The - conversion here will be simple. - - gen_atmel_mci.c - --------------- - Follows the new API and also has a good encapsulation of the whole driver. The - conversion here will be simple. - - mmc_spi.c - --------- - Follows the new API and also has a good encapsulation of the whole driver. The - conversion here will be simple. - - mv_sdhci.c - ---------- - This is a component of the SDHCI support, allowing it to run on Marvell - Kirkwood chip. It is probable the SDHCI support will have to be modified to - allow calling functions from this file based on information passed via - platform_data. - - mxcmmc.c - -------- - Follows the new API and also has a good encapsulation of the whole driver. The - conversion here will be simple. - - mxsmmc.c - -------- - Follows the new API and also has a good encapsulation of the whole driver. The - conversion here will be simple. - - omap_hsmmc.c - ------------ - Follows the new API and also has a good encapsulation of the whole driver. The - conversion here will be simple. - - pxa_mmc.c - --------- - This driver uses the legacy API and is written in a severely ad-hoc manner. - This driver will be removed in favor of pxa_mmc_gen.c, which is proved to work - better and is already well tested. No conversion will be done on this driver - anymore. - - pxa_mmc_gen.c - ------------- - Follows the new API and also has a good encapsulation of the whole driver. The - conversion here will be simple. - - s5p_mmc.c - --------- - Follows the new API and also has a good encapsulation of the whole driver. The - conversion here will be simple. - - sdhci.c - ------- - Follows the new API and also has a good encapsulation of the whole driver. The - conversion here will be simple, though it'd be necessary to modify this driver - to also support the Kirkwood series and probably also Tegra series of CPUs. - See the respective parts of this section for details. - - sh_mmcif.c - ---------- - Follows the new API and also has a good encapsulation of the whole driver. The - conversion here will be simple. - - tegra2_mmc.c - ------------ - Follows the new API and also has a good encapsulation of the whole driver. The - conversion here will be simple. diff --git a/doc/driver-model/UDM-net.txt b/doc/driver-model/UDM-net.txt deleted file mode 100644 index 097ed69..0000000 --- a/doc/driver-model/UDM-net.txt +++ /dev/null @@ -1,428 +0,0 @@ -The U-Boot Driver Model Project -=============================== -Net system analysis -=================== -Marek Vasut <marek.vasut@gmail.com> -2012-03-03 - -I) Overview ------------ - -The networking subsystem already supports multiple devices. Therefore the -conversion shall not be very hard. - -The network subsystem is operated from net/eth.c, which tracks all registered -ethernet interfaces and calls their particular functions registered via -eth_register(). - -The eth_register() is called from the network driver initialization function, -which in turn is called most often either from "board_net_init()" or -"cpu_net_init()". This function has one important argument, which is the -"struct eth_device", defined at include/net.h: - -struct eth_device { - /* DRIVER: Name of the device */ - char name[NAMESIZE]; - /* DRIVER: MAC address */ - unsigned char enetaddr[6]; - /* DRIVER: Register base address */ - int iobase; - /* CORE: state of the device */ - int state; - - /* DRIVER: Device initialization function */ - int (*init) (struct eth_device*, bd_t*); - /* DRIVER: Function for sending packets */ - int (*send) (struct eth_device*, volatile void* packet, int length); - /* DRIVER: Function for receiving packets */ - int (*recv) (struct eth_device*); - /* DRIVER: Function to cease operation of the device */ - void (*halt) (struct eth_device*); - /* DRIVER: Function to send multicast packet (OPTIONAL) */ - int (*mcast) (struct eth_device*, u32 ip, u8 set); - /* DRIVER: Function to change ethernet MAC address */ - int (*write_hwaddr) (struct eth_device*); - /* CORE: Next device in the linked list of devices managed by net core */ - struct eth_device *next; - /* CORE: Device index */ - int index; - /* DRIVER: Driver's private data */ - void *priv; -}; - -This structure defines the particular driver, though also contains elements that -should not be exposed to the driver, like core state. - -Small, but important part of the networking subsystem is the PHY management -layer, whose drivers are contained in drivers/net/phy. These drivers register in -a very similar manner to network drivers, by calling "phy_register()" with the -argument of "struct phy_driver": - -struct phy_driver { - /* DRIVER: Name of the PHY driver */ - char *name; - /* DRIVER: UID of the PHY driver */ - unsigned int uid; - /* DRIVER: Mask for UID of the PHY driver */ - unsigned int mask; - /* DRIVER: MMDS of the PHY driver */ - unsigned int mmds; - /* DRIVER: Features the PHY driver supports */ - u32 features; - /* DRIVER: Initialize the PHY hardware */ - int (*probe)(struct phy_device *phydev); - /* DRIVER: Reconfigure the PHY hardware */ - int (*config)(struct phy_device *phydev); - /* DRIVER: Turn on the PHY hardware, allow it to send/receive */ - int (*startup)(struct phy_device *phydev); - /* DRIVER: Turn off the PHY hardware */ - int (*shutdown)(struct phy_device *phydev); - /* CORE: Allows this driver to be part of list of drivers */ - struct list_head list; -}; - -II) Approach ------------- - -To convert the elements of network subsystem to proper driver model method, the -"struct eth_device" will have to be split into multiple components. The first -will be a structure defining the driver operations: - -struct eth_driver_ops { - int (*init)(struct instance*, bd_t*); - int (*send)(struct instance*, void *packet, int length); - int (*recv)(struct instance*); - void (*halt)(struct instance*); - int (*mcast)(struct instance*, u32 ip, u8 set); - int (*write_hwaddr)(struct instance*); -}; - -Next, there'll be platform data which will be per-driver and will replace the -"priv" part of "struct eth_device". Last part will be the per-device core state. - -With regards to the PHY part of the API, the "struct phy_driver" is almost ready -to be used with the new driver model approach. The only change will be the -replacement of per-driver initialization functions and removal of -"phy_register()" function in favor or driver model approach. - -III) Analysis of in-tree drivers --------------------------------- - - drivers/net/4xx_enet.c - ---------------------- - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. - - drivers/net/altera_tse.c - ------------------------ - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. - - drivers/net/armada100_fec.c - --------------------------- - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. - - drivers/net/at91_emac.c - ----------------------- - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. - - drivers/net/ax88180.c - --------------------- - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. - - drivers/net/ax88796.c - --------------------- - - This file contains a components of the NE2000 driver, implementing only - different parts on the NE2000 clone AX88796. This being no standalone driver, - no conversion will be done here. - - drivers/net/bfin_mac.c - ---------------------- - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. - - drivers/net/calxedaxgmac.c - -------------------------- - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. - - drivers/net/cs8900.c - -------------------- - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. - - drivers/net/davinci_emac.c - -------------------------- - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. - - drivers/net/dc2114x.c - --------------------- - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. - - drivers/net/designware.c - ------------------------ - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. - - drivers/net/dm9000x.c - --------------------- - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. - - drivers/net/dnet.c - ------------------ - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. - - drivers/net/e1000.c - ------------------- - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. - - drivers/net/e1000_spi.c - ----------------------- - - Driver for the SPI bus integrated on the Intel E1000. This is not part of the - network stack. - - drivers/net/eepro100.c - ---------------------- - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. - - drivers/net/enc28j60.c - ---------------------- - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. - - drivers/net/ep93xx_eth.c - ------------------------ - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. - - drivers/net/ethoc.c - ------------------- - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. - - drivers/net/fec_mxc.c - --------------------- - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. - - drivers/net/fsl_mcdmafec.c - -------------------------- - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. - - drivers/net/fsl_mdio.c - ---------------------- - - This file contains driver for FSL MDIO interface, which is not part of the - networking stack. - - drivers/net/ftgmac100.c - ----------------------- - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. - - drivers/net/ftmac100.c - ---------------------- - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. - - drivers/net/greth.c - ------------------- - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. - - drivers/net/inca-ip_sw.c - ------------------------ - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. - - drivers/net/ks8695eth.c - ----------------------- - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. - - drivers/net/lan91c96.c - ---------------------- - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. - - drivers/net/macb.c - ------------------ - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. - - drivers/net/mcffec.c - -------------------- - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. - - drivers/net/mcfmii.c - -------------------- - - This file contains MII interface driver for MCF FEC. - - drivers/net/mpc512x_fec.c - ------------------------- - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. - - drivers/net/mpc5xxx_fec.c - ------------------------- - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. - - drivers/net/mvgbe.c - ------------------- - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. - - drivers/net/natsemi.c - --------------------- - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. - - drivers/net/ne2000_base.c - ------------------------- - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. This driver contains the core - implementation of NE2000, which needs a few external functions, implemented by - AX88796, NE2000 etc. - - drivers/net/ne2000.c - -------------------- - - This file implements external functions necessary for native NE2000 compatible - networking card to work. - - drivers/net/netconsole.c - ------------------------ - - This is actually an STDIO driver. - - drivers/net/ns8382x.c - --------------------- - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. - - drivers/net/pcnet.c - ------------------- - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. - - drivers/net/plb2800_eth.c - ------------------------- - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. - - drivers/net/rtl8139.c - --------------------- - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. - - drivers/net/rtl8169.c - --------------------- - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. - - drivers/net/sh_eth.c - -------------------- - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. - - drivers/net/smc91111.c - ---------------------- - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. - - drivers/net/smc911x.c - --------------------- - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. - - drivers/net/tsec.c - ------------------ - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. - - drivers/net/tsi108_eth.c - ------------------------ - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. - - drivers/net/uli526x.c - --------------------- - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. - - drivers/net/vsc7385.c - --------------------- - - This is a driver that only uploads firmware to a switch. This is not subject - of conversion. - - drivers/net/xilinx_axi_emac.c - ----------------------------- - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. - - drivers/net/xilinx_emaclite.c - ----------------------------- - - This driver uses the standard new networking API, therefore there should be no - obstacles throughout the conversion process. diff --git a/doc/driver-model/UDM-pci.txt b/doc/driver-model/UDM-pci.txt deleted file mode 100644 index 1dce99d..0000000 --- a/doc/driver-model/UDM-pci.txt +++ /dev/null @@ -1,253 +0,0 @@ -The U-Boot Driver Model Project -=============================== -PCI subsystem analysis -====================== - -Pavel Herrmann <morpheus.ibis@gmail.com> -2012-03-17 - -I) Overview ------------ - - U-Boot already supports multiple PCI busses, stored in a linked-list of - pci_controller structures. This structure contains generic driver data, bus - interface operations and private data for the driver. - - Bus interface operations for PCI are (names are self-explanatory): - - read_byte() - read_word() - read_dword() - write_byte() - write_word() - write_dword() - - Each driver has to implement dword operations, and either implement word and - byte operations, or use shared $operation_config_$type_via_dword (eg. - read_config_byte_via_dword and similar) function. These functions are used - for config space I/O (read_config_dword and similar functions of the PCI - subsystem), which is used to configure the connected devices for standard MMIO - operations. All data transfers by respective device drivers are then done by - MMIO - - Each driver also defines a separate init function, which has unique symbol - name, and thus more drivers can be compiled in without colliding. This init - function is typically called from pci_init_board(), different for each - particular board. - - Some boards also define a function called fixup_irq, which gets called after - scanning the PCI bus for devices, and should dismiss any interrupts. - - Several drivers are also located in arch/ and should be moved to drivers/pci. - -II) Approach ------------- - - The pci_controller structure needs to be broken down to fit the new driver - model. Due to a large number of members, this will be done through three - distinct accessors, one for memory regions, one for config table and one for - everything else. That will make the pci_ops structure look like this: - - struct pci_ops { - int (*read_byte)(struct instance *bus, pci_dev_t *dev, int addr, - u8 *buf); - int (*read_word)(struct instance *bus, pci_dev_t *dev, int addr, - u16 *buf); - int (*read_dword)(struct instance *bus, pci_dev_t *dev, int addr, - u32 *buf); - int (*write_byte)(struct instance *bus, pci_dev_t *dev, int addr, - u8 val); - int (*write_byte)(struct instance *bus, pci_dev_t *dev, int addr, - u8 val); - int (*write_dword)(struct instance *bus, pci_dev_t *dev, int addr, - u32 val); - void (*fixup_irq)(struct instance *bus, pci_dev_t *dev); - struct pci_region* (*get_region)(struct instance *, uint num); - struct pci_config_table* (*get_cfg_table)(struct instance *bus); - uint (*get_option)(struct instance * bus, enum pci_option_code op); - } - - enum pci_option_code { - PCI_OPT_BUS_NUMBER=0, - PCI_OPT_REGION_COUNT, - PCI_OPT_INDIRECT_TYPE, - PCI_OPT_AUTO_MEM, - PCI_OPT_AUTO_IO, - PCI_OPT_AUTO_PREFETCH, - PCI_OPT_AUTO_FB, - PCI_OPT_CURRENT_BUS, - PCI_OPT_CFG_ADDR, - } - - The return value for get_option will be an unsigned integer value for any - option code. If the option currently is a pointer to pci_region, it will - return an index for get_region function. Special case has to be made for - PCI_OPT_CFG_ADDR, which should be interpreted as a pointer, but it is only - used for equality in find_hose_by_cfg_addr, and thus can be returned as an - uint. Other function using cfg_addr value are read/write functions for - specific drivers (especially ops for indirect bridges), and thus have access - to private_data of the driver instance. - - The config table accessor will return a pointer to a NULL-terminated array of - pci_config_table, which is supplied by the board in platform_data, or NULL if - the board didn't specify one. This table is used to override PnP - auto-initialization, or to specific initialization functions for non-PNP - devices. - - Transparent PCI-PCI bridges will get their own driver, and will forward all - operations to operations of their parent bus. This however makes it - impossible to use instances to identify devices, as not all devices will be - directly visible to the respective bus driver. - - Init functions of controller drivers will be moved to their respective - probe() functions, in accordance to the driver model. - - The PCI core will handle all mapping functions currently found in pci.c, as - well as proxy functions for read/write operations of the drivers. The PCI - core will also handle bus scanning and device configuration. - - The PnP helper functions currently in pci_auto.c will also be a part of PCI - core, but they will be exposed only to PCI controller drivers, not to other - device drivers. - - The PCI API for device drivers will remain largely unchanged, most drivers - will require no changes at all, and all modifications will be limited to - changing the pci_controlle into instance*. - -III) Analysis of in-tree drivers --------------------------------- - - A) drivers in drivers/pci/ - -------------------------- - - pci_indirect.c - -------------- - Shared driver for indirect PCI bridges, several CONFIG macros - will - require significant cleanup. - - pci_sh4.c - --------- - Shared init function for SH4 drivers, uses dword for read/write ops. - - pci_sh7751.c - ------------ - Standard driver, uses SH4 shared init. - - pci_sh7780.c - ------------ - Standard driver, uses SH4 shared init. - - tsi108_pci.c - ------------ - Standard driver, uses dword for read/write ops. - - fsl_pci_init.c - -------------- - Driver for PCI and PCI-e, uses indirect functions. - - pci_ftpci100.c - -------------- - Standard driver, uses indirect functions, has separate scan/setup - functions. - - B) driver in arch/ - ------------------ - - x86/lib/pci_type1.c - ------------------- - Standard driver, specifies all read/write functions separately. - - m68k/cpu/mcf5445x/pci.c - ----------------------- - Standard driver, specifies all read/write functions separately. - - m68k/cpu/mcf547x_8x/pci.c - ------------------------- - Standard driver, specifies all read/write functions separately. - - powerpc/cpu/mpc824x/pci.c - ------------------------- - Standard driver, uses indirect functions, does not setup HW. - - powerpc/cpu/mpc8260/pci.c - ------------------------- - Standard driver, uses indirect functions. - - powerpc/cpu/ppc4xx/4xx_pci.c - ---------------------------- - Standard driver, uses indirect functions. - - powerpc/cpu/ppc4xx/4xx_pcie.c - ----------------------------- - PCI-e driver, specifies all read/write functions separately. - - powerpc/cpu/mpc83xx/pci.c - ------------------------- - Standard driver, uses indirect functions. - - powerpc/cpu/mpc83xx/pcie.c - -------------------------- - PCI-e driver, specifies all read/write functions separately. - - powerpc/cpu/mpc5xxx/pci_mpc5200.c - --------------------------------- - Standard driver, uses dword for read/write ops. - - powerpc/cpu/mpc512x/pci.c - ------------------------- - Standard driver, uses indirect functions. - - powerpc/cpu/mpc85xx/pci.c - ------------------------- - Standard driver, uses indirect functions, has two busses. - - C) drivers in board/ - -------------------- - - eltec/elppc/pci.c - ----------------- - Standard driver, uses indirect functions. - - amirix/ap1000/pci.c - ------------------- - Standard driver, specifies all read/write functions separately. - - prodrive/p3mx/pci.c - ------------------- - Standard driver, uses dword for read/write ops, has two busses. - - esd/cpci750/pci.c - ----------------- - Standard driver, uses dword for read/write ops, has two busses. - - esd/common/pci.c - ---------------- - Standard driver, uses dword for read/write ops. - - dave/common/pci.c - ----------------- - Standard driver, uses dword for read/write ops. - - ppmc7xx/pci.c - ------------- - Standard driver, uses indirect functions. - - Marvell/db64360/pci.c - --------------------- - Standard driver, uses dword for read/write ops, has two busses. - - Marvell/db64460/pci.c - --------------------- - Standard driver, uses dword for read/write ops, has two busses. - - evb64260/pci.c - -------------- - Standard driver, uses dword for read/write ops, has two busses. - - armltd/integrator/pci.c - ----------------------- - Standard driver, specifies all read/write functions separately. - - All drivers will be moved to drivers/pci. Several drivers seem - similar/identical, especially those located under board, and may be merged - into one. diff --git a/doc/driver-model/UDM-pcmcia.txt b/doc/driver-model/UDM-pcmcia.txt deleted file mode 100644 index d55e89d..0000000 --- a/doc/driver-model/UDM-pcmcia.txt +++ /dev/null @@ -1,78 +0,0 @@ -The U-Boot Driver Model Project -=============================== -PCMCIA analysis -=============== -Viktor Krivak <viktor.krivak@gmail.com> -2012-03-17 - -I) Overview ------------ - - U-boot implements only 2 methods to interoperate with pcmcia. One to turn - device on and other to turn device off. Names of these methods are usually - pcmcia_on() and pcmcia_off() without any parameters. Some files in driver - directory implements only internal API. These methods aren't used outside - driver directory and they are not converted to new driver model. - -II) Approach ------------ - - 1) New API - ---------- - - Current API is preserved and all internal methods are hiden. - - struct ops { - void (*pcmcia_on)(struct instance *i); - void (*pcmcia_off)(struct instance *i); - } - - 2) Conversion - ------------- - - In header file pcmcia.h are some other variables which are used for - additional configuration. But all have to be moved to platform data or to - specific driver implementation. - - 3) Platform data - ---------------- - - Many boards have custom implementation of internal API. Pointers to these - methods are stored in platform_data. But the most implementations for Intel - 82365 and compatible PC Card controllers and Yenta-compatible - PCI-to-CardBus controllers implement whole API per board. In these cases - pcmcia_on() and pcmcia_off() behave only as wrappers and call specific - board methods. - -III) Analysis of in-tree drivers --------------------------------- - - i82365.c - -------- - Driver methods have different name i82365_init() and i82365_exit but - all functionality is the same. Board files board/atc/ti113x.c and - board/cpc45/pd67290.c use their own implementation of these method. - In this case all methods in driver behave only as wrappers. - - marubun_pcmcia.c - ---------------- - Meets standard API behaviour. Simple conversion. - - mpc8xx_pcmcia.c - --------------- - Meets standard API behaviour. Simple conversion. - - rpx_pcmcia.c - ------------ - Implements only internal API used in other drivers. Non of methods - implemented here are used outside driver model. - - ti_pci1410a.c - ------------- - Has different API but methods in this file are never called. Probably - dead code. - - tqm8xx_pcmcia.c - --------------- - Implements only internal API used in other drivers. Non of methods - implemented here are used outside driver model. diff --git a/doc/driver-model/UDM-power.txt b/doc/driver-model/UDM-power.txt deleted file mode 100644 index 666d553..0000000 --- a/doc/driver-model/UDM-power.txt +++ /dev/null @@ -1,88 +0,0 @@ -The U-Boot Driver Model Project -=============================== -POWER analysis -============== -Viktor Krivak <viktor.krivak@gmail.com> -2012-03-09 - -I) Overview ------------ - - 1) Actual state - --------------- - - At this moment power doesn't contain API. There are many methods for - initialization of some board specific functions but only few does what is - expected. Basically only one file contains something meaningful for this - driver. - - 2) Current implementation - ------------------------- - - In file twl6030.c are methods twl6030_stop_usb_charging() and - twl6030_start_usb_charging() for start and stop charging from USB. There are - also methods to get information about battery state and initialization of - battery charging. Only these methods are used in converted API. - - -II) Approach ------------- - - 1) New API - ---------- - - New API implements only functions specific for managing power. All board - specific init methods are moved to other files. Name of methods are - self-explanatory. - - struct ops { - void (*start_usb_charging)(struct instance *i); - void (*stop_usb_charging)(struct instance *i); - int (*get_battery_current)(struct instance *i); - int (*get_battery_voltage)(struct instance *i); - void (*init_battery_charging)(struct instance *i); - } - - 2) Conversions of other methods - ------------------------------- - - Methods that can't be converted to new API are moved to board file or to - special file for board hacks. - -III) Analysis of in-tree drivers --------------------------------- - - ftpmu010.c - ---------- - All methods of this file are moved to another location. - void ftpmu010_32768osc_enable(void): Move to boards hacks - void ftpmu010_mfpsr_select_dev(unsigned int dev): Move to board file - arch/nds32/lib/board.c - void ftpmu010_mfpsr_diselect_dev(unsigned int dev): Dead code - void ftpmu010_dlldis_disable(void): Dead code - void ftpmu010_sdram_clk_disable(unsigned int cr0): Move to board file - arch/nds32/lib/board.c - void ftpmu010_sdramhtc_set(unsigned int val): Move to board file - arch/nds32/lib/board.c - - twl4030.c - --------- - All methods of this file are moved to another location. - void twl4030_power_reset_init(void): Move to board hacks - void twl4030_pmrecv_vsel_cfg(u8 vsel_reg, u8 vsel_val, u8 dev_grp, - u8 dev_grp_sel): Move to board hacks - void twl4030_power_init(void): Move to board hacks - void twl4030_power_mmc_init(void): Move to board hacks - - twl6030.c - --------- - Some methods are converted to new API and rest are moved to another location. - void twl6030_stop_usb_charging(void): Convert to new API - void twl6030_start_usb_charging(void): Convert to new API - int twl6030_get_battery_current(void): Convert to new API - int twl6030_get_battery_voltage(void): Convert to new API - void twl6030_init_battery_charging(void): Convert to new API - void twl6030_power_mmc_init(): Move to board file - drivers/mmc/omap_hsmmc.c - void twl6030_usb_device_settings(): Move to board file - drivers/usb/musb/omap3.c diff --git a/doc/driver-model/UDM-rtc.txt b/doc/driver-model/UDM-rtc.txt deleted file mode 100644 index 3640d24..0000000 --- a/doc/driver-model/UDM-rtc.txt +++ /dev/null @@ -1,253 +0,0 @@ -============================= -RTC device subsystem analysis -============================= - -Tomas Hlavacek <tmshlvck@gmail.com> -2012-03-10 - -I) Overview ------------ - -U-Boot currently implements one common API for RTC devices. The interface -is defined in include/rtc.h and comprises of functions and structures: - - struct rtc_time { - int tm_sec; - int tm_min; - int tm_hour; - int tm_mday; - int tm_mon; - int tm_year; - int tm_wday; - int tm_yday; - int tm_isdst; - }; - - int rtc_get (struct rtc_time *); - int rtc_set (struct rtc_time *); - void rtc_reset (void); - -The functions are implemented by a proper device driver in drivers/rtc -directory and the driver to be compiled in is selected in a Makefile. -Drivers are mutually exclusive. - -Drivers depends on date code in drivers/rtc/date.c and naturally on board -specific data. - -II) Approach ------------- - - 1) New API - ---------- - In the UDM each rtc driver would register itself by a function - - int rtc_device_register(struct instance *i, - struct rtc_device_ops *o); - - The structure being defined as follows: - - struct rtc_device_ops { - int (*get_time)(struct instance *i, struct rtc_time *t); - int (*set_time)(struct instance *i, struct rtc_time *t); - int (*reset)(struct instance *i); - }; - - - 2) Conversion thougths - ---------------------- - U-Boot RTC drivers exports the same functions and therefore the conversion - of the drivers is straight-forward. There is no initialization needed. - - -III) Analysis of in-tree drivers --------------------------------- - - drivers/rtc/rv3029.c - -------------------- - The driver is standard rtc. Simple conversion is possible. - - - drivers/rtc/s3c24x0_rtc.c - ------------------------- - The driver is standard rtc. Simple conversion is possible. - - - drivers/rtc/pt7c4338.c - ---------------------- - The driver is standard rtc. Simple conversion is possible. - - - drivers/rtc/mvrtc.c - ------------------- - The driver is standard rtc. Simple conversion is possible. - - - drivers/rtc/ftrtc010.c - ---------------------- - The driver is standard rtc. Simple conversion is possible. - - - drivers/rtc/mpc5xxx.c - --------------------- - The driver is standard rtc. Simple conversion is possible. - - - drivers/rtc/ds164x.c - -------------------- - The driver is standard rtc. Simple conversion is possible. - - - drivers/rtc/rs5c372.c - --------------------- - The driver is standard rtc. Simple conversion is possible. - - - drivers/rtc/m41t94.c - -------------------- - The driver is standard rtc. Simple conversion is possible. - - - drivers/rtc/mc13xxx-rtc.c - ------------------------- - The driver is standard rtc. Simple conversion is possible. - - - drivers/rtc/mcfrtc.c - -------------------- - The driver is standard rtc. Simple conversion is possible. - - - drivers/rtc/davinci.c - --------------------- - The driver is standard rtc. Simple conversion is possible. - - - drivers/rtc/rx8025.c - -------------------- - The driver is standard rtc. Simple conversion is possible. - - - drivers/rtc/bfin_rtc.c - ---------------------- - The driver is standard rtc. Simple conversion is possible. - - - drivers/rtc/m41t62.c - -------------------- - The driver is standard rtc. Simple conversion is possible. - - - drivers/rtc/ds1306.c - -------------------- - The driver is standard rtc. Simple conversion is possible. - - - drivers/rtc/mpc8xx.c - -------------------- - The driver is standard rtc. Simple conversion is possible. - - - drivers/rtc/ds3231.c - -------------------- - The driver is standard rtc. Simple conversion is possible. - - - drivers/rtc/ds12887.c - --------------------- - The driver is standard rtc. Simple conversion is possible. - - - drivers/rtc/ds1302.c - -------------------- - The driver is standard rtc. Simple conversion is possible. - - - drivers/rtc/ds1374.c - -------------------- - The driver is standard rtc. Simple conversion is possible. - - - drivers/rtc/ds174x.c - -------------------- - The driver is standard rtc. Simple conversion is possible. - - - drivers/rtc/m41t60.c - -------------------- - The driver is standard rtc. Simple conversion is possible. - - - drivers/rtc/m48t35ax.c - ---------------------- - The driver is standard rtc. Simple conversion is possible. - - - drivers/rtc/pl031.c - ------------------- - The driver is standard rtc. Simple conversion is possible. - - - drivers/rtc/x1205.c - ------------------- - The driver is standard rtc. Simple conversion is possible. - - - drivers/rtc/m41t11.c - -------------------- - The driver is standard rtc. Simple conversion is possible. - - - drivers/rtc/pcf8563.c - --------------------- - The driver is standard rtc. Simple conversion is possible. - - - drivers/rtc/mk48t59.c - --------------------- - Macros needs cleanup. Besides that the driver is standard rtc. - Simple conversion is possible. - - - drivers/rtc/mxsrtc.c - -------------------- - The driver is standard rtc. Simple conversion is possible. - - - drivers/rtc/ds1307.c - -------------------- - The driver is standard rtc. Simple conversion is possible. - - - drivers/rtc/ds1556.c - -------------------- - The driver is standard rtc. Simple conversion is possible. - - - drivers/rtc/rtc4543.c - --------------------- - The driver is standard rtc. Simple conversion is possible. - - - drivers/rtc/ds1337.c - -------------------- - The driver is standard rtc. Simple conversion is possible. - - - drivers/rtc/isl1208.c - --------------------- - The driver is standard rtc. Simple conversion is possible. - - - drivers/rtc/max6900.c - --------------------- - The driver is standard rtc. Simple conversion is possible. - - - drivers/rtc/mc146818.c - ---------------------- - The driver is standard rtc. Simple conversion is possible. - - - drivers/rtc/at91sam9_rtt.c - -------------------------- - The driver is standard rtc. Simple conversion is possible. diff --git a/doc/driver-model/UDM-serial.txt b/doc/driver-model/UDM-serial.txt deleted file mode 100644 index ed804a8..0000000 --- a/doc/driver-model/UDM-serial.txt +++ /dev/null @@ -1,155 +0,0 @@ -The U-Boot Driver Model Project -=============================== -Serial I/O analysis -=================== -Marek Vasut <marek.vasut@gmail.com> -2012-02-20 - -I) Overview ------------ - -The serial port support currently requires the driver to export the following -functions: - - serial_putc() ...... Output a character - serial_puts() ...... Output string, often done using serial_putc() - serial_tstc() ...... Test if incoming character is in a buffer - serial_getc() ...... Retrieve incoming character - serial_setbrg() .... Configure port options - serial_init() ...... Initialize the hardware - -The simpliest implementation, supporting only one port, simply defines these six -functions and calls them. Such calls are scattered all around U-Boot, especiall -serial_putc(), serial_puts(), serial_tstc() and serial_getc(). The serial_init() -and serial_setbrg() are often called from platform-dependent places. - -It's important to consider current implementation of CONFIG_SERIAL_MULTI though. -This resides in common/serial.c and behaves as a multiplexer for serial ports. -This, by calling serial_assign(), allows user to switch I/O from one serial port -to another. Though the environmental variables "stdin", "stdout", "stderr" -remain set to "serial". - -These variables are managed by the IOMUX. This resides in common/iomux.c and -manages all console input/output from U-Boot. For serial port, only one IOMUX is -always registered, called "serial" and the switching of different serial ports -is done by code in common/serial.c. - -On a final note, it's important to mention function default_serial_console(), -which is platform specific and reports the default serial console for the -platform, unless proper environment variable overrides this. - -II) Approach ------------- - -Drivers not using CONFIG_SERIAL_MULTI already will have to be converted to -similar approach. The probe() function of a driver will call a function -registering the driver with a STDIO subsystem core, stdio_device_register(). - -The serial_init() function will now be replaced by probe() function of the -driver, the rest of the components of the driver will be converted to standard -STDIO driver calls. See [ UDM-stdio.txt ] for details. - -The serial_setbrg() function depends on global data pointer. This is wrong, -since there is likely to be user willing to configure different baudrate on two -different serial ports. The function will be replaced with STDIO's "conf()" -call, with STDIO_CONFIG_SERIAL_BAUDRATE argument. - -III) Analysis of in-tree drivers --------------------------------- - - altera_jtag_uart.c - ------------------ - No support for CONFIG_SERIAL_MULTI. Simple conversion possible. - - altera_uart.c - ------------- - No support for CONFIG_SERIAL_MULTI. Simple conversion possible. - - arm_dcc.c - --------- - No support for CONFIG_SERIAL_MULTI. Simple conversion possible, unless used - with CONFIG_ARM_DCC_MULTI. Then it registers another separate IOMUX. - - atmel_usart.c - ------------- - No support for CONFIG_SERIAL_MULTI. Simple conversion possible. - - mcfuart.c - --------- - No support for CONFIG_SERIAL_MULTI. Simple conversion possible. - - ns16550.c - --------- - This driver seems complicated and certain consideration will need to be made - during conversion. This driver is implemented in very universal manner, - therefore it'll be necessary to properly design it's platform_data. - - opencores_yanu.c - ---------------- - No support for CONFIG_SERIAL_MULTI. Simple conversion possible. - - sandbox.c - --------- - No support for CONFIG_SERIAL_MULTI. Simple conversion possible. - - serial.c - -------- - This is a complementary part of NS16550 UART driver, see above. - - serial_imx.c - ------------ - No support for CONFIG_SERIAL_MULTI. Simple conversion possible. This driver - might be removed in favor of serial_mxc.c . - - serial_ks8695.c - --------------- - No support for CONFIG_SERIAL_MULTI. Simple conversion possible. - - serial_max3100.c - ---------------- - No support for CONFIG_SERIAL_MULTI. Simple conversion possible. - - serial_mxc.c - ------------ - No support for CONFIG_SERIAL_MULTI. Simple conversion possible. - - serial_pl01x.c - -------------- - No support for CONFIG_SERIAL_MULTI. Simple conversion possible, though this - driver in fact contains two drivers in total. - - serial_pxa.c - ------------ - This driver is a bit complicated, but due to clean support for - CONFIG_SERIAL_MULTI, there are no expected obstructions throughout the - conversion process. - - serial_s3c24x0.c - ---------------- - This driver, being quite ad-hoc might need some work to bring back to shape. - - serial_s5p.c - ------------ - No support for CONFIG_SERIAL_MULTI. Simple conversion possible. - - serial_sa1100.c - --------------- - No support for CONFIG_SERIAL_MULTI. Simple conversion possible. - - serial_sh.c - ----------- - No support for CONFIG_SERIAL_MULTI. Simple conversion possible. - - serial_xuartlite.c - ------------------ - No support for CONFIG_SERIAL_MULTI. Simple conversion possible. - - usbtty.c - -------- - This driver seems very complicated and entangled with USB framework. The - conversion might be complicated here. - - arch/powerpc/cpu/mpc512x/serial.c - --------------------------------- - This driver supports CONFIG_SERIAL_MULTI. This driver will need to be moved to - proper place. diff --git a/doc/driver-model/UDM-spi.txt b/doc/driver-model/UDM-spi.txt deleted file mode 100644 index 9ba0f84..0000000 --- a/doc/driver-model/UDM-spi.txt +++ /dev/null @@ -1,200 +0,0 @@ -The U-Boot Driver Model Project -=============================== -SPI analysis -============ -Viktor Krivak <viktor.krivak@gmail.com> -2012-03-03 - -I) Overview ------------ - - 1) The SPI driver - ----------------- - - At this moment U-Boot provides standard API that consist of 7 functions: - - void spi_init(void); - struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, - unsigned int max_hz, unsigned int mode); - void spi_free_slave(struct spi_slave *slave); - int spi_claim_bus(struct spi_slave *slave); - void spi_release_bus(struct spi_slave *slave); - int spi_xfer(struct spi_slave *slave, unsigned int bitlen, - const void *dout, void *din, unsigned long flags); - int spi_cs_is_valid(unsigned int bus, unsigned int cs); - void spi_cs_activate(struct spi_slave *slave); - void spi_cs_deactivate(struct spi_slave *slave); - void spi_set_speed(struct spi_slave *slave, uint hz); - - Method spi_init() is usually empty. All necessary configuration are sets by - spi_setup_slave(). But this configuration is usually stored only in memory. - No real hardware sets are made. All hardware settings are provided by method - spi_claim_bus(). This method claims the bus and it can't be claimed again - until it's release. That's mean all calls of method spi_claim_bus() will - fail. But lots of cpu implementation don't meet this behaviour. - Method spi_release_bus() does exact opposite. It release bus directly by - some hardware sets. spi_free_slave() only free memory allocated by - spi_setup_slave(). Method spi_xfer() do actually read and write operation - throw specified bus and cs. Other methods are self explanatory. - - 2) Current limitations - ---------------------- - - Theoretically at this moment api allows use more then one bus per device at - the time. But in real this can be achieved only when all buses have their - own base addresses in memory. - - -II) Approach ------------- - - 1) Claiming bus - --------------- - - The current api cannot be used because struct spi_slave have to be in - private data. In that case user are prohibited to use different bus on one - device at same time. But when base memory address for bus are different. - It's possible make more instance of this driver. Otherwise it can't can be - done because of hardware limitation. - - 2) API change - ------------- - - Method spi_init() is moved to probe. Methods spi_setup_slave() and - spi_claim_bus() are joined to one method. This method checks if desired bus - exists and is available then configure necessary hardware and claims bus. - Method spi_release_bus() and spi_free_slave() are also joined to meet this - new approach. Other function remain same. Only struct spi_slave was change - to instance. - - struct ops { - int (*spi_request_bus)(struct instance *i, unsigned int bus, - unsigned int cs, unsigned int max_hz, - unsigned int mode); - void (*spi_release_bus)(struct instance *i); - int (*spi_xfer) (struct instance *i, unsigned int bitlen, - const void *dout, void *din, unsigned long flags); - int (*spi_cs_is_valid)(struct instance *i, unsigned int bus, - unsigned int cs); - void (*spi_cs_activate)(struct instance *i); - void (*spi_cs_deactivate)(struct instance *i); - void (*spi_set_speed)(struct instance *i, uint hz); - } - - 3) Legacy API - ------------- - - To easy conversion of the whole driver. Original and new api can exist next - to each other. New API is designed to be only a wrapper that extracts - necessary information from private_data and use old api. When driver can - use more than one bus at the time. New API require multiple instance. One - for each bus. In this case spi_slave have to be copied in each instance. - - 4) Conversion TIME-LINE - ----------------------- - - To prevent build corruption api conversion have to be processed in several - independent steps. In first step all old API methods are renamed. After that - new API and core function are implemented. Next step is conversion of all - board init methods to set platform data. After all these steps it is possible - to start conversion of all remaining calls. This procedure guarantees that - build procedure and binaries are never broken. - -III) Analysis of in-tree drivers --------------------------------- - - altera_spi.c - ------------ - All methods have designated structure. Simple conversion possible. - - andes_spi.c - ----------- - All methods have designated structure. Simple conversion possible. - - andes_spi.h - ----------- - Support file for andes_spi.c. No conversion is needed. - - armada100_spi.c - --------------- - All methods have designated structure. Simple conversion possible. - - atmel_dataflash_spi.c - --------------------- - Wrong placement. Will be moved to another location. - - atmel_spi.c - ----------- - Supports more than one bus. Need some minor change. - - atmel_spi.h - ----------- - Support file for andes_spi.c. No conversion is needed. - - bfin_spi.c - ---------- - Supports more than one bus. Need some minor change. - - cf_spi.c - -------- - Cooperate with some cpu specific methods from other files. Hard conversion. - - davinci_spi.c - ------------- - All methods have designated structure. Simple conversion possible. - - davinci_spi.h - ------------- - Support file for davinci_spi.h. No conversion is needed. - - fsl_espi.c - ---------- - All methods have designated structure. Simple conversion possible. - - kirkwood_spi.c - -------------- - All methods have designated structure. Simple conversion possible. - - mpc8xxx_spi.c - ------------- - All methods have designated structure. Simple conversion possible. - - mpc52xx_spi.c - ------------- - All methods have designated structure. Simple conversion possible. - - mxc_spi.c - --------- - All methods have designated structure. Simple conversion possible. - - mxs_spi.c - --------- - All methods have designated structure. Simple conversion possible. - - oc_tiny_spi.c - ------------- - Supports more than one bus. Need some minor change. - - omap3_spi.c - ----------- - Supports more than one bus. Need some minor change. - - omap3_spi.h - ----------- - Support file for omap3_spi.c. No conversion is needed. - - sh_spi.c - -------- - All methods have designated structure. Simple conversion possible. - - sh_spi.h - -------- - Support file for sh_spi.h. No conversion is needed. - - soft_spi.c - ---------- - Use many board specific method linked from other files. Need careful debugging. - - tegra2_spi.c - ------------ - Some hardware specific problem when releasing bus. diff --git a/doc/driver-model/UDM-stdio.txt b/doc/driver-model/UDM-stdio.txt deleted file mode 100644 index 156627b..0000000 --- a/doc/driver-model/UDM-stdio.txt +++ /dev/null @@ -1,191 +0,0 @@ -The U-Boot Driver Model Project -=============================== -I/O system analysis -=================== -Marek Vasut <marek.vasut@gmail.com> -2012-02-20 - -I) Overview ------------ - -The console input and output is currently done using the STDIO subsystem in -U-Boot. The design of this subsystem is already flexible enough to be easily -converted to new driver model approach. Minor changes will need to be done -though. - -Each device that wants to register with STDIO subsystem has to define struct -stdio_dev, defined in include/stdio_dev.h and containing the following fields: - -struct stdio_dev { - int flags; /* Device flags: input/output/system */ - int ext; /* Supported extensions */ - char name[16]; /* Device name */ - -/* GENERAL functions */ - - int (*start) (void); /* To start the device */ - int (*stop) (void); /* To stop the device */ - -/* OUTPUT functions */ - - void (*putc) (const char c); /* To put a char */ - void (*puts) (const char *s); /* To put a string (accelerator) */ - -/* INPUT functions */ - - int (*tstc) (void); /* To test if a char is ready... */ - int (*getc) (void); /* To get that char */ - -/* Other functions */ - - void *priv; /* Private extensions */ - struct list_head list; -}; - -Currently used flags are DEV_FLAGS_INPUT, DEV_FLAGS_OUTPUT and DEV_FLAGS_SYSTEM, -extensions being only one, the DEV_EXT_VIDEO. - -The private extensions are now used as a per-device carrier of private data and -finally list allows this structure to be a member of linked list of STDIO -devices. - -The STDIN, STDOUT and STDERR routing is handled by environment variables -"stdin", "stdout" and "stderr". By configuring the variable to the name of a -driver, functions of such driver are called to execute that particular -operation. - -II) Approach ------------- - - 1) Similarity of serial, video and keyboard drivers - --------------------------------------------------- - - All of these drivers can be unified under the STDIO subsystem if modified - slightly. The serial drivers basically define both input and output functions - and need function to configure baudrate. The keyboard drivers provide only - input. On the other hand, video drivers provide output, but need to be - configured in certain way. This configuration might be dynamic, therefore the - STDIO has to be modified to provide such flexibility. - - 2) Unification of serial, video and keyboard drivers - ---------------------------------------------------- - - Every STDIO device would register a structure containing operation it supports - with the STDIO core by calling: - - int stdio_device_register(struct instance *i, struct stdio_device_ops *o); - - The structure being defined as follows: - - struct stdio_device_ops { - void (*putc)(struct instance *i, const char c); - void (*puts)(struct instance *i, const char *s); /* OPTIONAL */ - - int (*tstc)(struct instance *i); - int (*getc)(struct instance *i); - - int (*init)(struct instance *i); - int (*exit)(struct instance *i); - int (*conf)(struct instance *i, enum stdio_config c, const void *data); - }; - - The "putc()" function will emit a character, the "puts()" function will emit a - string. If both of these are set to NULL, the device is considered STDIN only, - aka input only device. - - The "getc()" retrieves a character from a STDIN device, while "tstc()" tests - if there is a character in the buffer of STDIN device. In case these two are - set to NULL, this device is STDOUT / STDERR device. - - Setting all "putc()", "puts()", "getc()" and "tstc()" calls to NULL isn't an - error condition, though such device does nothing. By instroducing tests for - these functions being NULL, the "flags" and "ext" fields from original struct - stdio_dev can be eliminated. - - The "init()" and "exit()" calls are replacement for "start()" and "exit()" - calls in the old approach. The "priv" part of the old struct stdio_dev will be - replaced by common private data in the driver model and the struct list_head - list will be eliminated by introducing common STDIO core, that tracks all the - STDIO devices. - - Lastly, the "conf()" call will allow the user to configure various options of - the driver. The enum stdio_config contains all possible configuration options - available to the STDIO devices, const void *data being the argument to be - configured. Currently, the enum stdio_config will contain at least the - following options: - - enum stdio_config { - STDIO_CONFIG_SERIAL_BAUDRATE, - }; - - 3) Transformation of stdio routing - ---------------------------------- - - By allowing multiple instances of drivers, the environment variables "stdin", - "stdout" and "stderr" can no longer be set to the name of the driver. - Therefore the STDIO core, tracking all of the STDIO devices in the system will - need to have a small amount of internal data for each device: - - struct stdio_device_node { - struct instance *i; - struct stdio_device_ops *ops; - uint8_t id; - uint8_t flags; - struct list_head list; - } - - The "id" is the order of the instance of the same driver. The "flags" variable - allows multiple drivers to be used at the same time and even for different - purpose. The following flags will be defined: - - STDIO_FLG_STDIN ..... This device will be used as an input device. All input - from all devices with this flag set will be received - and passed to the upper layers. - STDIO_FLG_STDOUT .... This device will be used as an output device. All - output sent to stdout will be routed to all devices - with this flag set. - STDIO_FLG_STDERR .... This device will be used as an standard error output - device. All output sent to stderr will be routed to - all devices with this flag set. - - The "list" member of this structure allows to have a linked list of all - registered STDIO devices. - -III) Analysis of in-tree drivers --------------------------------- - -For in-depth analysis of serial port drivers, refer to [ UDM-serial.txt ]. -For in-depth analysis of keyboard drivers, refer to [ UDM-keyboard.txt ]. -For in-depth analysis of video drivers, refer to [ UDM-video.txt ]. - - arch/blackfin/cpu/jtag-console.c - -------------------------------- - This driver is a classic STDIO driver, no problem with conversion is expected. - - board/mpl/pati/pati.c - --------------------- - This driver registers with the STDIO framework, though it uses a lot of ad-hoc - stuff which will need to be sorted out. - - board/netphone/phone_console.c - ------------------------------ - This driver is a classic STDIO driver, no problem with conversion is expected. - - drivers/net/netconsole.c - ------------------------ - This driver is a classic STDIO driver, no problem with conversion is expected. - -IV) Other involved files (To be removed) ----------------------------------------- - -common/cmd_console.c -common/cmd_log.c -common/cmd_terminal.c -common/console.c -common/fdt_support.c -common/iomux.c -common/lcd.c -common/serial.c -common/stdio.c -common/usb_kbd.c -doc/README.iomux diff --git a/doc/driver-model/UDM-tpm.txt b/doc/driver-model/UDM-tpm.txt deleted file mode 100644 index 0beff4a..0000000 --- a/doc/driver-model/UDM-tpm.txt +++ /dev/null @@ -1,48 +0,0 @@ -The U-Boot Driver Model Project -=============================== -TPM system analysis -=================== -Marek Vasut <marek.vasut@gmail.com> -2012-02-23 - -I) Overview ------------ - -There is currently only one TPM chip driver available and therefore the API -controlling it is very much based on this. The API is very simple: - - int tis_open(void); - int tis_close(void); - int tis_sendrecv(const u8 *sendbuf, size_t send_size, - u8 *recvbuf, size_t *recv_len); - -The command operating the TPM chip only provides operations to send and receive -bytes from the chip. - -II) Approach ------------- - -The API can't be generalised too much considering there's only one TPM chip -supported. But it's a good idea to split the tis_sendrecv() function in two -functions. Therefore the new API will use register the TPM chip by calling: - - tpm_device_register(struct instance *i, const struct tpm_ops *ops); - -And the struct tpm_ops will contain the following members: - - struct tpm_ops { - int (*tpm_open)(struct instance *i); - int (*tpm_close)(struct instance *i); - int (*tpm_send)(const uint8_t *buf, const size_t size); - int (*tpm_recv)(uint8_t *buf, size_t *size); - }; - -The behaviour of "tpm_open()" and "tpm_close()" will basically copy the -behaviour of "tis_open()" and "tis_close()". The "tpm_send()" will be based on -the "tis_senddata()" and "tis_recv()" will be based on "tis_readresponse()". - -III) Analysis of in-tree drivers --------------------------------- - -There is only one in-tree driver present, the "drivers/tpm/generic_lpc_tpm.c", -which will be simply converted as outlined in previous chapter. diff --git a/doc/driver-model/UDM-twserial.txt b/doc/driver-model/UDM-twserial.txt deleted file mode 100644 index 5f2c5a3..0000000 --- a/doc/driver-model/UDM-twserial.txt +++ /dev/null @@ -1,47 +0,0 @@ -================================== -TWserial device subsystem analysis -================================== - -Tomas Hlavacek<tmshlvck@gmail.com> -2012-03-21 - -I) Overview ------------ - -U-Boot currently implements one common API for TWSerial devices. The interface -is defined in include/tws.h and comprises of functions: - - int tws_read(uchar *buffer, int len); - int tws_write(uchar *buffer, int len); - -The functions are implemented by a proper device driver in drivers/twserial -directory and the driver to be compiled in is selected in a Makefile. There is -only one driver present now. - -The driver depends on ad-hoc code in board specific data, namely functions: - - void tws_ce(unsigned bit); - void tws_wr(unsigned bit); - void tws_clk(unsigned bit); - void tws_data(unsigned bit); - unsigned tws_data_read(void); - void tws_data_config_output(unsigned output); - -implemented in include/configs/inka4x0.h . - -II) Approach ------------- - - U-Boot TWserial drivers exports two simple functions and therefore the conversion - of the driver and creating a core for it is not needed. It should be consolidated - with include/configs/inka4x0.h and taken to the misc/ dir. - - -III) Analysis of in-tree drivers --------------------------------- - - drivers/twserial/soft_tws.c - --------------------------- - The driver is the only TWserial driver. The ad-hoc part in - include/configs/inka4x0.h and the core soft_tws driver should be consolidated - to one compact driver and moved to misc/ . diff --git a/doc/driver-model/UDM-usb.txt b/doc/driver-model/UDM-usb.txt deleted file mode 100644 index 5ce85b5..0000000 --- a/doc/driver-model/UDM-usb.txt +++ /dev/null @@ -1,94 +0,0 @@ -The U-Boot Driver Model Project -=============================== -USB analysis -============ -Marek Vasut <marek.vasut@gmail.com> -2012-02-16 - -I) Overview ------------ - - 1) The USB Host driver - ---------------------- - There are basically four or five USB host drivers. All such drivers currently - provide at least the following fuctions: - - usb_lowlevel_init() ... Do the initialization of the USB controller hardware - usb_lowlevel_stop() ... Do the shutdown of the USB controller hardware - - usb_event_poll() ...... Poll interrupt from USB device, often used by KBD - - submit_control_msg() .. Submit message via Control endpoint - submit_int_msg() ...... Submit message via Interrupt endpoint - submit_bulk_msg() ..... Submit message via Bulk endpoint - - - This allows for the host driver to be easily abstracted. - - 2) The USB hierarchy - -------------------- - - In the current implementation, the USB Host driver provides operations to - communicate via the USB bus. This is realised by providing access to a USB - root port to which an USB root hub is attached. The USB bus is scanned and for - each newly found device, a struct usb_device is allocated. See common/usb.c - and include/usb.h for details. - -II) Approach ------------- - - 1) The USB Host driver - ---------------------- - - Converting the host driver will follow the classic driver model consideration. - Though, the host driver will have to call a function that registers a root - port with the USB core in it's probe() function, let's call this function - - usb_register_root_port(&ops); - - This will allow the USB core to track all available root ports. The ops - parameter will contain structure describing operations supported by the root - port: - - struct usb_port_ops { - void (*usb_event_poll)(); - int (*submit_control_msg)(); - int (*submit_int_msg)(); - int (*submit_bulk_msg)(); - } - - 2) The USB hierarchy and hub drivers - ------------------------------------ - - Converting the USB heirarchy should be fairy simple, considering the already - dynamic nature of the implementation. The current usb_hub_device structure - will have to be converted to a struct instance. Every such instance will - contain components of struct usb_device and struct usb_hub_device in it's - private data, providing only accessors in order to properly encapsulate the - driver. - - By registering the root port, the USB framework will instantiate a USB hub - driver, which is always present, the root hub. The root hub and any subsequent - hub instance is represented by struct instance and it's private data contain - amongst others common bits from struct usb_device. - - Note the USB hub driver is partly defying the usual method of registering a - set of callbacks to a particular core driver. Instead, a static set of - functions is defined and the USB hub instance is passed to those. This creates - certain restrictions as of how the USB hub driver looks, but considering the - specification for USB hub is given and a different type of USB hub won't ever - exist, this approach is ok: - - - Report how many ports does this hub have: - uint get_nr_ports(struct instance *hub); - - Get pointer to device connected to a port: - struct instance *(*get_child)(struct instance *hub, int port); - - Instantiate and configure device on port: - struct instance *(*enum_dev_on_port)(struct instance *hub, int port); - - 3) USB device drivers - --------------------- - - The USB device driver, in turn, will have to register various ops structures - with certain cores. For example, USB disc driver will have to register it's - ops with core handling USB discs etc. diff --git a/doc/driver-model/UDM-video.txt b/doc/driver-model/UDM-video.txt deleted file mode 100644 index e67e9e4..0000000 --- a/doc/driver-model/UDM-video.txt +++ /dev/null @@ -1,74 +0,0 @@ -The U-Boot Driver Model Project -=============================== -Video output analysis -===================== -Marek Vasut <marek.vasut@gmail.com> -2012-02-20 - -I) Overview ------------ - -The video drivers are most often registered with video subsystem. This subsystem -often expects to be allowed access to framebuffer of certain parameters. This -subsystem also provides calls for STDIO subsystem to allow it to output -characters on the screen. For this part, see [ UDM-stdio.txt ]. - -Therefore the API has two parts, the video driver part and the part where the -video driver core registers with STDIO API. - -The video driver part will follow the current cfb_console approach, though -allowing it to be more dynamic. - -II) Approach ------------- - -Registering the video driver into the video driver core is done by calling the -following function from the driver probe() function: - - video_device_register(struct instance *i, GraphicDevice *gd); - -Because the video driver core is in charge or rendering characters as well as -bitmaps on the screen, it will in turn call stdio_device_register(i, so), where -"i" is the same instance as the video driver's one. But "so" will be special -static struct stdio_device_ops handling the character output. - - -III) Analysis of in-tree drivers --------------------------------- - - arch/powerpc/cpu/mpc8xx/video.c - ------------------------------- - This driver copies the cfb_console [ see drivers/video/cfb_console.c ] - approach and acts only as a STDIO device. Therefore there are currently two - possible approaches, first being the conversion of this driver to usual STDIO - device and second, long-term one, being conversion of this driver to video - driver that provides console. - - arch/x86/lib/video.c - -------------------- - This driver registers two separate STDIO devices and should be therefore - converted as such. - - board/bf527-ezkit/video.c - ------------------------- - This driver seems bogus as it behaves as STDIO device, but provides no input - or output capabilities. It relies on DEV_EXT_VIDEO, which is no longer in use - or present otherwise than as a dead code/define. - - board/bf533-stamp/video.c - ------------------------- - This driver seems bogus as it behaves as STDIO device, but provides no input - or output capabilities. It relies on DEV_EXT_VIDEO, which is no longer in use - or present otherwise than as a dead code/define. - - board/bf548-ezkit/video.c - ------------------------- - This driver seems bogus as it behaves as STDIO device, but provides no input - or output capabilities. It relies on DEV_EXT_VIDEO, which is no longer in use - or present otherwise than as a dead code/define. - - board/cm-bf548/video.c - ---------------------- - This driver seems bogus as it behaves as STDIO device, but provides no input - or output capabilities. It relies on DEV_EXT_VIDEO, which is no longer in use - or present otherwise than as a dead code/define. diff --git a/doc/driver-model/UDM-watchdog.txt b/doc/driver-model/UDM-watchdog.txt deleted file mode 100644 index 3f13063..0000000 --- a/doc/driver-model/UDM-watchdog.txt +++ /dev/null @@ -1,329 +0,0 @@ -The U-Boot Driver Model Project -=============================== -Watchdog device subsystem analysis -================================== - -Tomas Hlavacek <tmshlvck@gmail.com> -2012-03-09 - -I) Overview ------------ - -U-Boot currently implements an API for HW watchdog devices as explicit drivers -in drivers/watchdog directory. There are also drivers for both hardware and -software watchdog on particular CPUs implemented in arch/*/cpu/*/cpu.c. There -are macros in include/watchdog.h that selects between SW and HW watchdog and -assembly SW implementation. - -The current common interface comprises of one set out of these two possible -variants: - - 1) - void watchdog_reset(void); - int watchdog_disable(void); - int watchdog_init(void); - - 2) - void hw_watchdog_reset(void); - void hw_watchdog_init(void); - -The watchdog implementations are also spread through board/*/*.c that in -some cases. The API and semantics is in most cases same as the above -mentioned common functions. - - -II) Approach ------------- - - 1) New API - ---------- - - In the UDM each watchdog driver would register itself by a function - - int watchdog_device_register(struct instance *i, - const struct watchdog_device_ops *o); - - The structure being defined as follows: - - struct watchdog_device_ops { - int (*disable)(struct instance *i); - void (*reset)(struct instance *i); - }; - - The watchdog_init() function will be dissolved into probe() function. - - 2) Conversion thougths - ---------------------- - - Conversion of watchdog implementations to a new API could be divided - to three subsections: a) HW implementations, which are mostly compliant - to the above mentioned API; b) SW implementations, which are compliant - to the above mentioned API and c) SW implementations that are not compliant - to the API and has to be rectified or partially rewritten. - -III) Analysis of in-tree drivers --------------------------------- - - drivers/watchdog/at91sam9_wdt.c - ------------------------------- - The driver is standard HW watchdog. Simple conversion is possible. - - - drivers/watchdog/ftwdt010_wdt.c - ------------------------------- - The driver is ad-hoc HW watchdog. Conversion has to take into account - driver parts spread in include/faraday/*. Restructuring the driver and - code cleanup has to be considered. - - - arch/arm/cpu/arm1136/mx31/timer.c - --------------------------------- - The driver is semi-standard ad-hoc HW watchdog. Conversion has to take - into account driver parts spread in the timer.c file. - - - arch/arm/cpu/arm926ejs/davinci/timer.c - -------------------------------------- - The driver is ad-hoc semi-standard HW watchdog. Conversion has to take - into account driver parts spread in the timer.c file. - - - arch/arm/cpu/armv7/omap-common/hwinit-common.c - ---------------------------------------------- - The driver is non-standard ad-hoc HW watchdog. Conversion is possible - but functions has to be renamed and constants moved to another places. - - - arch/arm/cpu/armv7/omap3/board.c - -------------------------------- - The driver is non-standard ad-hoc HW watchdog. Conversion is possible - but functions has to be renamed and constants moved to another places. - - - arch/blackfin/cpu/watchdog.c - ---------------------------- - The driver is standard HW watchdog. Simple conversion is possible. - - - arch/m68k/cpu/mcf523x/cpu.c - --------------------------- - The driver is standard HW watchdog. Simple conversion is possible. - - - arch/m68k/cpu/mcf52x2/cpu.c - --------------------------- - The driver is standard HW watchdog. Simple conversion is possible. - - - arch/m68k/cpu/mcf532x/cpu.c - --------------------------- - The driver is standard HW watchdog. Simple conversion is possible. - - - arch/m68k/cpu/mcf547x_8x/cpu.c - ------------------------------ - The driver is standard HW watchdog (there is slight naming convention - violation that has to be rectified). Simple conversion is possible. - - - arch/powerpc/cpu/74xx_7xx/cpu.c - ------------------------------- - The driver is standard HW watchdog. Simple conversion is possible. - - - arch/powerpc/cpu/mpc512x/cpu.c - ------------------------------ - The driver is standard HW watchdog. Simple conversion is possible. - - - arch/powerpc/cpu/mpc5xx/cpu.c - ----------------------------- - The driver is standard HW watchdog. Simple conversion is possible. - - - arch/powerpc/cpu/mpc5xxx/cpu.c - ------------------------------ - The driver is standard HW watchdog. Simple conversion is possible. - - - arch/powerpc/cpu/mpc8260/cpu.c - ------------------------------ - The driver is standard HW watchdog. Simple conversion is possible. - - - arch/powerpc/cpu/mpc83xx/cpu.c - ------------------------------ - The driver is standard HW watchdog. Simple conversion is possible. - - - arch/powerpc/cpu/mpc85xx/cpu.c - ------------------------------ - The driver is standard HW watchdog. Simple conversion is possible. - - - arch/powerpc/cpu/mpc86xx/cpu.c - ------------------------------ - The driver is standard HW watchdog. Simple conversion is possible. - - - arch/powerpc/cpu/mpc8xx/cpu.c - ----------------------------- - The driver is standard HW watchdog. Simple conversion is possible. - - - arch/powerpc/cpu/ppc4xx/cpu.c - ----------------------------- - The driver is standard HW watchdog. Simple conversion is possible. - - - arch/sh/cpu/sh2/watchdog.c - -------------------------- - The driver is standard HW watchdog. Simple conversion is possible. - - - arch/sh/cpu/sh3/watchdog.c - -------------------------- - The driver is standard HW watchdog. Simple conversion is possible. - - - arch/sh/cpu/sh4/watchdog.c - -------------------------- - The driver is standard HW watchdog. Simple conversion is possible. - - - board/amcc/luan/luan.c - ---------------------- - The driver is standard HW watchdog. Simple conversion is possible. - - - board/amcc/yosemite/yosemite.c - ------------------------------ - The driver is standard HW watchdog. Simple conversion is possible. - - - board/apollon/apollon.c - ----------------------- - The driver is standard HW watchdog however the watchdog_init() - function is called in early initialization. Simple conversion is possible. - - - board/bmw/m48t59y.c - ------------------- - Special watchdog driver. Dead code. To be removed. - - - board/davedenx/qong/qong.c - -------------------------- - The driver is standard HW watchdog. Simple conversion is possible. - - - board/dvlhost/watchdog.c - ------------------------ - The driver is standard HW watchdog. Simple conversion is possible. - - - board/eNET/eNET.c - ----------------- - The driver is standard HW watchdog. Simple conversion is possible. - - - board/eltec/elppc/elppc.c - ------------------------- - The driver is standard HW watchdog. Simple conversion is possible. - - - board/enbw/enbw_cmc/enbw_cmc.c - ------------------------------ - Only function proxy call. Code cleanup needed. - - - board/freescale/mx31pdk/mx31pdk.c - --------------------------------- - Only function proxy call. Code cleanup needed. - - - board/gth2/gth2.c - ----------------- - The driver is standard HW watchdog. Simple conversion is possible. - - - board/lwmon5/lwmon5.c - --------------------- - The driver is standard HW watchdog. Simple conversion is possible. - - - board/manroland/mucmc52/mucmc52.c - --------------------------------- - The driver is standard HW watchdog. Simple conversion is possible. - - - board/manroland/uc101/uc101.c - ----------------------------- - The driver is standard HW watchdog. Simple conversion is possible. - - - board/mousse/m48t59y.c - ---------------------- - Special watchdog driver. Dead code. To be removed. - - - board/mvblue/mvblue.c - --------------------- - The driver is standard HW watchdog. Simple conversion is possible. - - - board/netphone/netphone.c - ------------------------- - The driver is standard HW watchdog. Simple conversion is possible. - - - board/netta/netta.c - ------------------- - The driver is standard HW watchdog. Simple conversion is possible. - - - board/netta2/netta2.c - --------------------- - The driver is standard HW watchdog. Simple conversion is possible. - - - board/omicron/calimain/calimain.c - --------------------------------- - Only function proxy call. Code cleanup needed. - - - board/pcs440ep/pcs440ep.c - ------------------------- - The driver is standard HW watchdog. Simple conversion is possible. - - - board/stx/stxxtc/stxxtc.c - ------------------------- - The driver is standard HW watchdog. Simple conversion is possible. - - - board/ti/omap2420h4/omap2420h4.c - -------------------------------- - The driver is standard HW watchdog. Simple conversion is possible. - - - board/ttcontrol/vision2/vision2.c - --------------------------------- - The driver is standard HW watchdog but namespace is polluted by - non-standard macros. Simple conversion is possible, code cleanup - needed. - - - board/v38b/v38b.c - ----------------- - The driver is standard HW watchdog. Simple conversion is possible. - - - board/ve8313/ve8313.c - --------------------- - The driver is standard HW watchdog. Simple conversion is possible. - - - board/w7o/watchdog.c - -------------------- - The driver is standard HW watchdog. Simple conversion is possible. |