diff options
author | Todd Doucet <todd.doucet@timesys.com> | 2010-02-03 17:06:33 -0500 |
---|---|---|
committer | Todd Doucet <todd.doucet@timesys.com> | 2010-02-03 17:06:33 -0500 |
commit | ff238a4df84428befc55d49f58864dfc47ff853d (patch) | |
tree | 8796b828b396f5b7ed017904ff77b614dbf38677 /Documentation | |
parent | 4a6908a3a050aacc9c3a2f36b276b46c0629ad91 (diff) |
Kernel as received from Digi for their Wi-Mx51 SoC running on their
CCWMX51JS carrier board.
Diffstat (limited to 'Documentation')
-rw-r--r-- | Documentation/imx_nfc.txt | 369 | ||||
-rw-r--r-- | Documentation/pwm.txt | 257 |
2 files changed, 626 insertions, 0 deletions
diff --git a/Documentation/imx_nfc.txt b/Documentation/imx_nfc.txt new file mode 100644 index 000000000000..7fec999c2884 --- /dev/null +++ b/Documentation/imx_nfc.txt @@ -0,0 +1,369 @@ +i.MX NAND Flash Controller Driver Documentation +=============================================== + + +Definitions of Terms +==================== + +To avoid confusion, let's carefully define some of the terms we'll be using: + + "NAND Flash Chip" or "Chip" + A NAND Flash storage array and controller (including a chip select + signal, ready/busy signal, data register, etc.). + + "NAND Flash Package" or "Package" + A hardware package containing one or more NAND Flash chips that share + data lines and most control signals, but with separate chip select + and ready/busy signals. Package "boundaries" are unimportant to MTD. + + "NAND Flash Medium" or "Medium" + A collection of one or more NAND Flash chips that the system views as + logically contiguous. + + "Memory Technology Device" or "MTD" + An abstraction of underlying memory hardware, represented by a single + struct mtd_info. + + "NAND Flash MTD" + An abstraction of a NAND Flash medium that is represented by a single + struct nand_chip (the name of this structure is misleading because it + has evolved to represent an entire medium, not just a single chip). + All the physical chips in a NAND Flash MTD medium have answered the + "Read ID" command with the same manufacturer code and device code and + are presumed to have identical characteristics. + + "NAND Flash MTD Hardware-independent Layer" or "HIL" + The code that implements an MTD interface and drives all NAND Flash + MTDs. + + "NAND Flash MTD Hardware Abstraction Layer" or "HAL" + Code that implements the internal NAND Flash hardware model and + matches it to specific hardware. + + "NAND Flash MTD Reference Implementation" + A reference implementation of a HAL "stack." + + "Out-of-Band" or "OOB" + An adjective describing information that is not part of the "data" in + a NAND Flash page. NAND Flash pages are generally described in terms + of the amount of data they can hold (e.g., "2K pages" or "4K pages"). + The physical page size is actually larger than this and the + additional bytes are called "out-of-band." + + + +The Structure of the MTD NAND Flash System +========================================== + +The following figure illustrates how control flows down from the system's +MTD interface into the NAND Flash MTD system and down to the hardware- +specific implementation (this driver): + + + + / +---------------------------------------+ + | | MTD | + | +---------------------------------------+ + MTD | | + | | +----------+ + | | | | + | v v | + \ ======================================== | + - struct mtd_info | + / ======================================== | + | | | + | v | + | +---------------------------------------+ | + | | NAND Flash MTD | | + NAND Flash | | Interface Functions | | + Hardware- | +---------------------------------------+ | + Independent | | | | + Layer | | v | + (HIL) | +-------------+ | +-------------+ +-------------+ + | | Init | | | Support | | Reference | + | | Functions | | | Functions | |BBT Functions| + | +-------------+ | +-------------+ +-------------+ + | | | | ^ + | v v v | + \ ======================================== | + - struct nand_chip | + / ======================================== | + | | ^ | ^ | | + NAND Flash | | | | | | | + Hardware | v | v | | | + Abstraction | +--------------+ +---------------+ | | + Layer | | Hardware- | | Reference | +-----------+ + (HAL) | | Specific | | | + | |Implementation| |Implementations| + \ +--------------+ +---------------+ + + + +The function pointers and attributes in struct mtd_info embody an abstract +model of memory technology devices. + +The struct nand_chip is an aggregation of two categories of function pointers +and attributes: + + - Function pointers and attributes used by the HIL. These members embody + an abstract model of NAND Flash media, or a hardware abstraction + layer (HAL). + + - Function pointers and attributes used by the reference implementations. + +The single most confusing thing about the MTD NAND Flash system is that +struct nand_chip contains all the main HAL members mixed up with all the +members used only by the reference implementation, without any clear +distinction. Recognizing the distinction is critical for understanding the +relationship between the HIL and HAL, and can greatly simplify driver +implementation. + +The fundamental operations represented by the function pointers in +struct nand_chip fall into the following categories (from conceptually +"low-level" to "high-level"): + + - Signal Control + - Chip Control + - Low-level I/O + - ECC Control + - ECC-aware I/O + - Error Recovery + - High-level I/O + - Bad Block Management + +The HIL uses only the following "Replaceable" function pointers in +struct nand_chip: + + - Signal Control + - None + - Chip Control + - dev_ready + - select_chip + - cmdfunc + - waitfunc + - Low-level I/O + - read_byte + - ECC Control + - None + - ECC-aware I/O + - ecc.read_page + - ecc.read_page_raw + - Error Recovery + - None + - High-level I/O + - write_page + - ecc.read_oob + - ecc.write_oob + - Bad Block Management + - block_bad + - block_markbad + - scan_bbt + +Note that the HIL calls erase_cmd, but this member is marked "Internal." + +The HIL uses only the following commands with cmdfunc: + + * NAND_CMD_STATUS + - nand_check_wp() - Checks if the current chip is + write-protected. + * NAND_CMD_READID + - nand_get_flash_type() - Gets information about the first chip. + - nand_scan_ident() - Scans for additional chips. + * NAND_CMD_RESET + - nand_do_write_oob() - Clears a bug observed on the + Toshiba TC5832DC and DiskOnChip 2000. + * NAND_CMD_READ0 + - nand_do_read_ops() - Used to begin a full page read (both with + and without ECC). + * NAND_CMD_ERASE1 + - single_erase_cmd() - Starts a block erase operation. + - multi_erase_cmd() - Starts a block erase operation. + * NAND_CMD_ERASE2 + - single_erase_cmd() - Finishes a block erase operation. + - multi_erase_cmd() - Finishes a block erase operation. + + +Since this is all the HIL uses, this is all a driver needs to implement. + + + +The Structure of the imx_nfc Driver +=================================== + +This driver supports many different versions of underlying controller, and +also supports higher-level abstractions like interleaving. To facilitate this +versatility, the code is layered as shown in the following diagram: + + + +--------------------------------------+ + | MTD | + +--------------------------------------+ + | NAND Flash MTD | + ======================================== <-- struct nand_chip + / | MTD Interface Layer (mil_*) | + | | +----------------------------------+ + | | | Medium Abstraction Layer (mal_*) | + imx_nfc | | | | + driver | | | +------------------------+ + | | | | NFC Utils (nfc_util_*) | + | ======================================== <-- struct nfc_hal + \ | NFC HAL (nfc_x_y_*) | + ======================================== <-- Hardware Interface + | NFC Hardware | + +--------------------------------------+ + + +MTD Interface Layer +------------------- +This layer includes functions that the NAND Flash MTD system calls directly. +In a manner of speaking, this layer "parses" the function calls made by MTD +and translates them into fundamental operations understood by the Medium +Abstraction Layer. Some simple operations don't need any abstraction, so code +in this layer can sometimes use the NFC HAL directly. + + +Medium Abstraction Layer +------------------------ +This layer implements the abstract model of the NAND Flash medium and hides +details that shouldn't concern higher layers (e.g., interleaving). + + +NFC Utilities +------------- +These functions make it easier to use the NFC HAL. Even though this layer +is shown above the NFC HAL in the diagram, it's actually possible for the +NFC HAL to call some of these functions. + + +NFC HAL +------- +This layer implements the abstract model of an i.MX NAND Flash controller. + + +Other Collections of Functions +------------------------------ + +- System Interface + - imx_nfc_* + +- sysfs Interface + - get_module_* + - set_module_* + - show_device_* + - store_device_* + + + + +i.MX NAND Flash Controller Versions +=================================== + +The i.MX NAND Flash controller (NFC) has evolved over time. Both its memory +layout and behaviors have changed. In this driver, we use major and minor +version numbers to label these stages in the NFC's evolution. These version +numbers are very useful, but they are entirely a figment of this driver's +imagination -- you will never find them in Freescale hardware reference +manuals. + +When the platform code instantiates an i.MX NFC device, it provides a struct +imx_nfc_platform_data that contains platform-specific information. This +includes the major and minor version numbers for the NFC. This driver uses +the version numbers to select an appopriate NFC HAL structure. + + + +i.MX NFC Memory Map +=================== + +While many things have changed during the evolution of the NFC, much has +remained the same. All i.MX NFCs have two or three essential memory-mapped +regions: a set of buffers, and one or two sets of registers (one on the AXI +bus and perhaps a second on the IP bus). + +The buffer area contains the captive memory to which the NFC writes data +received from the NAND Flash medium. This area is subdivided into several +contiguous "main" buffers that hold 512-byte chunks of data, and several +"spare" buffers that hold varying-size chunks of out-of-band bytes. The +number of main buffers is always the same as the number of spare buffers, but +the exact count and the size of the spare buffers varies across NFC versions. + +The register areas contain the NFC's control interface. Some versions have +only one set of registers, and some have two. + +The platform-specific resources passed to this driver include the starting +and ending physical addresses of the buffer and register areas. This driver +maps those physical addresses to virtual addresses, and then uses version- +specific offsets and bit masks to operate the NFC. + + + +Matching the NAND Flash MTD Page Model with the i.MX NFC +======================================================== + +The NAND Flash MTD HAL model views a page as containing two essentially +independent groups of bytes: "data" bytes and "out-of-band" bytes. If the +underlying physical format has data and out-of-band bytes distributed across +the page, they must be reassembled before being delivered to the caller +(e.g., see the function nand_read_page_syndrome(), which is part of the +reference implementation). + +The i.MX NFC hardware imposes both a physical page layout and a layout in its +memory buffer that differ from the HAL model. The following figure shows how +all these layouts relate to each other: + + + i.MX NFC i.MX NFC + Physical Memory NAND Flash + Page Buffers MTD Model + + +--------+ +--------+ +--------+ + |OOB[N-1]| |OOB[N-1]| |OOB[N-1]| + +--------+ +--------+ +--------+ + | | <gap> |OOB[ 1 ]| + | Data | +--------+ +--------+ + | [N-1] | |OOB[ 1 ]| |OOB[ 0 ]| + | | +--------+ +--------+ + +--------+ <gap> + ... +--------+ +--------+ + +--------+ |OOB[ 0 ]| | | + |OOB[ 1 ]| +--------+ | Data | + +--------+ | | | [N-1] | + | | | Data | | | + | Data | | [N-1] | +--------+ + | [ 1 ] | | | | | + | | +--------+ | Data | + +--------+ ... | [ 1 ] | + |OOB[ 0 ]| +--------+ | | + +--------+ | | +--------+ + | | | Data | | | + | Data | | [ 1 ] | | Data | + | [ 0 ] | | | | [ 0 ] | + | | +--------+ | | + +--------+ | | +--------+ + | Data | + | [ 0 ] | + | | + +--------+ + + +The NFC memory is *almost* what we want, but not quite. The problems are: + + 1) There are gaps between the out-of-band fragments. + + 2) The NFC memory responds only to 16-byte or 32-byte reads and writes. + +To resolve these problems, we've encapsulated the NFC memory behind these +functions: + + nfc_util_copy_from_the_nfc() - Copies data to main memory from the the NFC. + nfc_util_copy_to_the_nfc() - Copies data from main memory to the NFC. + +These functions don't take pointers to locations within the NFC memory - they +take a "column address." These functions know how to skip over the gaps and +handle the NFC memory such that it looks like all the data and out-of-band +bytes are completely contiguous. They also handle copying arbitrary bytes +from/to a memory that only responds to 16- or 32-byte reads/writes. If you're +accessing the NFC memory without these functions, you're *probably* doing +something wrong. + + diff --git a/Documentation/pwm.txt b/Documentation/pwm.txt new file mode 100644 index 000000000000..d6f87984f889 --- /dev/null +++ b/Documentation/pwm.txt @@ -0,0 +1,257 @@ + Generic PWM Device API + + October 8, 2008 + Bill Gatliff + <bgat <at> billgatliff.com> + + + +The code in drivers/pwm and include/linux/pwm.h implements an API for +applications involving pulse-width-modulation signals. This document +describes how the API implementation facilitates both PWM-generating +devices, and users of those devices. + + + +Motivation + +The primary goals for implementing the "generic PWM API" are to +consolidate the various PWM implementations within a consistent and +redundancy-reducing framework, and to facilitate the use of +hotpluggable PWM devices. + +Previous PWM-related implementations within the Linux kernel achieved +their consistency via cut-and-paste, but did not need to (and didn't) +facilitate more than one PWM-generating device within the system--- +hotplug or otherwise. The Generic PWM Device API might be most +appropriately viewed as an update to those implementations, rather +than a complete rewrite. + + + +Challenges + +One of the difficulties in implementing a generic PWM framework is the +fact that pulse-width-modulation applications involve real-world +signals, which often must be carefully managed to prevent destruction +of hardware that is linked to those signals. A DC motor that +experiences a brief interruption in the PWM signal controlling it +might destructively overheat; it could change speed, losing +synchronization with a sensor; it could even suddenly change direction +or torque, breaking the mechanical device connected to it. + +(A generic PWM device framework is not directly responsible for +preventing the above scenarios: that responsibility lies with the +hardware designer and the application and driver authors. But it must +to the greatest extent possible make it easy to avoid such problems). + +A generic PWM device framework must accomodate the substantial +differences between available PWM-generating hardware devices, without +becoming sub-optimal for any of them. + +Finally, a generic PWM device framework must be relatively +lightweight, computationally speaking. Some PWM users demand +high-speed outputs, plus the ability to regulate those outputs +quickly. A device framework must be able to "keep up" with such +hardware, while still leaving time to do real work. + +The Generic PWM Device API is an attempt to meet all of the above +requirements. At its initial publication, the API was already in use +managing small DC motors through a custom-designed, optically-isolated +H-bridge driver. + + + +Functional Overview + +The Generic PWM Device API framework is implemented in +include/linux/pwm.h and drivers/pwm/pwm.c. The functions therein use +information from pwm_device, pwm_channel and pwm_channel_config +structures to invoke services in PWM peripheral device drivers. +Consult drivers/pwm/atmel-pwm.c for an example driver. + +There are two classes of adopters of the PWM framework: + + "Users" -- those wishing to employ the API merely to produce PWM + signals; once they have identified the appropriate physical output + on the platform in question, they don't care about the details of + the underlying hardware + + "Driver authors" -- those wishing to bind devices that can generate + PWM signals to the Generic PWM Device API, so that the services of + those devices become available to users; assuming the hardware can + support the needs of a user, driver authors don't care about the + details of the user's application + +Generally speaking, users will first invoke pwm_request() to obtain a +handle to a PWM device. They will then pass that handle to functions +like pwm_duty_ns() and pwm_period_ns() to set the duty cycle and +period of the PWM signal, respectively. They will also invoke +pwm_start() and pwm_stop() to turn the signal on and off. + +The framework also provides a sysfs interface to PWM devices, which is +adequate for basic needs and testing. + +Driver authors fill out a pwm_device structure, which describes the +capabilities of the PWM hardware being driven--- including the number +of distinct output "channels" the peripheral offers. They then invoke +pwm_register() (usually from within their device's probe() handler) to +make the PWM API aware of their device. The framework will call back +to the methods described in the pwm_device structure to configure and +use the hardware. + +Note that PWM signals can be produced by a variety of peripherals, +beyond the true "PWM hardware" offered by many system-on-chip devices. +Other possibilities include timer/counters with compare-match +capabilities, carefully-programmed synchronous serial ports +(e.g. SPI), and GPIO pins driven by kernel interval timers. With a +proper pwm_device structure, these devices and pseudo-devices can all +be accomodated by the Generic PWM Device API framework. + + + +Using the API to Generate PWM Signals -- Basic Functions for Users + + +pwm_request() -- Returns a pwm_channel pointer, which is subsequently +passed to the other user-related PWM functions. Once requested, a PWM +channel is marked as in-use and subsequent requests prior to +pwm_free() will fail. + +The names used to refer to PWM devices are defined by driver authors. +Typically they are platform device bus identifiers, and this +convention is encouraged for consistency. + + +pwm_free() -- Marks a PWM channel as no longer in use. The PWM device +is stopped before it is released by the API. + + +pwm_period_ns() -- Specifies the PWM signal's period, in nanoseconds. + + +pwm_duty_ns() -- Specifies the PWM signal's active duration, in nanoseconds. + + +pwm_duty_percent() -- Specifies the PWM signal's active duration, as a +percentage of the current period of the signal. NOTE: this value is +not recalculated if the period of the signal is subsequently changed. + + +pwm_start(), pwm_stop() -- Turns the PWM signal on and off. Except +where stated otherwise by a driver author, signals are stopped at the +end of the current period, at which time the output is set to its +inactive state. + + +pwm_polarity() -- Defines whether the PWM signal output's active +region is "1" or "0". A 10% duty-cycle, polarity=1 signal will +conventionally be at 5V (or 3.3V, or 1000V, or whatever the platform +hardware does) for 10% of the period. The same configuration of a +polarity=0 signal will be at 5V (or 3.3V, or ...) for 90% of the +period. + + + +Using the API to Generate PWM Signals -- Advanced Functions + + +pwm_config() -- Passes a pwm_channel_config structure to the +associated device driver. This function is invoked by pwm_start(), +pwm_duty_ns(), etc. and is one of two main entry points to the PWM +driver for the hardware being used. The configuration change is +guaranteed atomic if multiple configuration changes are specified. +This function might sleep, depending on what the device driver has to +do to satisfy the request. All PWM device drivers must support this +entry point. + + +pwm_config_nosleep() -- Passes a pwm_channel_config structure to the +associated device driver. If the driver must sleep in order to +implement the requested configuration change, -EWOULDBLOCK is +returned. Users may call this function from interrupt handlers, for +example. This is the other main entry point into the PWM hardware +driver, but not all device drivers support this entry point. + + +pwm_synchronize(), pwm_unsynchronize() -- "Synchronizes" two or more +PWM channels, if the underlying hardware permits. (If it doesn't, the +framework facilitates emulating this capability but it is not yet +implemented). Synchronized channels will start and stop +simultaneously when any single channel in the group is started or +stopped. Use pwm_unsynchronize(..., NULL) to completely detach a +channel from any other synchronized channels. + + +pwm_set_handler() -- Defines an end-of-period callback. The indicated +function will be invoked in a worker thread at the end of each PWM +period, and can subsequently invoke pwm_config(), etc. Must be used +with extreme care for high-speed PWM outputs. Set the handler +function to NULL to un-set the handler. + + + +Implementing a PWM Device API Driver -- Functions for Driver Authors + + +Fill out the appropriate fields in a pwm_device structure, and submit +to pwm_register(): + + +bus_id -- the plaintext name of the device. Users will bind to a +channel on the device using this name plus the channel number. For +example, the Atmel PWMC's bus_id is "atmel_pwmc", the same as used by +the platform device driver (recommended). The first device registered +thereby receives bus_id "atmel_pwmc.0", which is what you put in +pwm_device.bus_id. Channels are then named "atmel_pwmc.0:[0-3]". +(Hint: just use pdev->dev.bus_id in your probe() method). + + +nchan -- the number of distinct output channels provided by the device. + + +request -- (optional) Invoked each time a user requests a channel. +Use to turn on clocks, clean up register states, etc. The framework +takes care of device locking/unlocking; you will see only successful +requests. + + +free -- (optional) Callback for each time a user relinquishes a +channel. The framework will have already stopped, unsynchronized and +un-handled the channel. Use to turn off clocks, etc. as necessary. + + +synchronize, unsynchronize -- (optional) Callbacks to +synchronize/unsynchronize channels. Some devices provide this +capability in hardware; for others, it can be emulated (see +atmel_pwmc.c's sync_mask for an example). + + +set_callback -- (optional) Invoked when a user requests a handler. If +the hardware supports an end-of-period interrupt, invoke the function +indicated during your interrupt handler. The callback function itself +is always internal to the API, and does not map directly to the user's +callback function. + + +config -- Invoked to change the device configuration, always from a +sleep-capable context. All the changes indicated must be performed +atomically, ideally synchronized to an end-of-period event (so that +you avoid short or long output pulses). You may sleep, etc. as +necessary within this function. + + +config_nosleep -- (optional) Invoked to change device configuration +from within a context that is not allowed to sleep. If you cannot +perform the requested configuration changes without sleeping, return +-EWOULDBLOCK. + + + +Acknowledgements + + +The author expresses his gratitude to the countless developers who +have reviewed and submitted feedback on the various versions of the +Generic PWM Device API code, and those who have submitted drivers and +applications that use the framework. You know who you are. ;) |