dm: Initial import of design documents

This patch contains UDM-design.txt, which is document containing
general description of the driver model. The remaining files contains
descriptions of conversion process of particular subsystems.

Signed-off-by: Marek Vasut <marek.vasut@gmail.com>
diff --git a/doc/driver-model/UDM-design.txt b/doc/driver-model/UDM-design.txt
new file mode 100644
index 0000000..185f477
--- /dev/null
+++ b/doc/driver-model/UDM-design.txt
@@ -0,0 +1,315 @@
+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