diff options
-rw-r--r-- | Documentation/getting_started/gpio.md | 136 | ||||
-rw-r--r-- | Documentation/getting_started/index.md | 1 |
2 files changed, 137 insertions, 0 deletions
diff --git a/Documentation/getting_started/gpio.md b/Documentation/getting_started/gpio.md new file mode 100644 index 0000000000..26939ce7cf --- /dev/null +++ b/Documentation/getting_started/gpio.md @@ -0,0 +1,136 @@ +# Configuring a mainboard's GPIOs in coreboot + +## Introduction + +Every mainboard needs to appropriately configure its General Purpose Inputs / +Outputs (GPIOs). There are many facets of this issue, including which boot +stage a GPIO might need to be configured. + +## Boot stages + +Typically, coreboot does most of its non-memory related initialization work in +ramstage, when DRAM is available for use. Hence, the bulk of a mainboard's GPIOs +are configured in this stage. However, some boards might need a few GPIOs +configured before that; think of memory strapping pins which indicate what kind +of DRAM is installed. These pins might need to be read before initializing the +memory, so these GPIOs are then typically configured in bootblock or romstage. + +## Configuration + +Most mainboards will have a ``gpio.c`` file in their mainboard directory. This +file typically contains tables which describe the configuration of the GPIO +registers. Since these registers could be different on a per-SoC or per +SoC-family basis, you may need to consult the datasheet for your SoC to find out +how to appropriately set these registers. In addition, some mainboards are +based on a baseboard/variant model, where several variant mainboards may share a +lot of their circuitry and ICs and the commonality between the boards is +collected into a virtual ``baseboard.`` In that case, the GPIOs which are shared +between multiple boards are placed in the baseboard's ``gpio.c` file, while the +ones that are board-specific go into each variant's ``gpio.c`` file. + +## Intel SoCs + +Many newer Intel SoCs share a common IP block for GPIOs, and that commonality +has been taken advantage of in coreboot, which has a large set of macros that +can be used to describe the configuration of each GPIO pad. This file lives in +``src/soc/intel/common/block/include/intelblocks/gpio_defs.h``. + +### Older Intel SoCs + +Baytrail and Braswell, for example, simply expect the mainboard to supply a +callback, `mainboard_get_gpios` which returns an array of `struct soc_gpio` +objects, defining the configuration of each pin. + +### AMD SoCs + +Some AMD SoCs use a list of `struct soc_amd_gpio` objects to define the +register values configuring each pin, similar to Intel. + +### Register details + +GPIO configuration registers typically control properties such as: +1. Input / Output +2. Pullups / Pulldowns +3. Termination +4. Tx / Rx Disable +5. Which reset signal to use +6. Native Function / IO +7. Interrupts + * IRQ routing (e.g. on x86, APIC, SCI, SMI) + * Edge or Level Triggered + * Active High or Active Low +8. Debouncing + +## Configuring GPIOs for pre-ramstage + +coreboot provides for several SoC-specific and mainboard-specific callbacks at +specific points in time, such as bootblock-early, bootblock, romstage entry, +pre-silicon init, pre-RAM init, or post-RAM init. The GPIOs that are +configured in either bootblock or romstage, depending on when they are needed, +are denoted the "early" GPIOs. Some mainboard will use +``bootblock_mainboard_init()`` to configure their early GPIOs, and this is +probably a good place to start. Many mainboards will declare their GPIO +configuration as structs, i.e. (Intel), + +```C +struct pad_config { + /* offset of pad within community */ + int pad; + /* Pad config data corresponding to DW0, DW1,.... */ + uint32_t pad_config[GPIO_NUM_PAD_CFG_REGS]; +}; +``` + +and will usually place these in an array, one for each pad to be configured. +Mainboards using Intel SoCs can use a library which combines common +configurations together into a set of macros, e.g., + +```C + /* Native function configuration */ + #define PAD_CFG_NF(pad, pull, rst, func) + /* + * Set native function with RX Level/Edge configuration and disable + * input/output buffer if necessary + */ + #define PAD_CFG_NF_BUF_TRIG(pad, pull, rst, func, bufdis, trig) + /* General purpose output, no pullup/down. */ + #define PAD_CFG_GPO(pad, val, rst) + /* General purpose output, with termination specified */ + #define PAD_CFG_TERM_GPO(pad, val, pull, rst) + /* General purpose output, no pullup/down. */ + #define PAD_CFG_GPO_GPIO_DRIVER(pad, val, rst, pull) + /* General purpose input */ + #define PAD_CFG_GPI(pad, pull, rst) +``` +etc. + +## Configuring GPIOs for ramstage and beyond... + +In ramstage, most mainboards will configure the rest of their GPIOs for the +function they will be performing while the device is active. The goal is the +same as above in bootblock; another ``static const`` array is created, and the +rest of the GPIO registers are programmed. + +In the baseboard/variant model described above, the baseboard will provide the +configuration for the GPIOs which are configured identically between variants, +and will provide a mechanism for a variant to override the baseboard's +configuration. This is usually done via two tables: the baseboard table and the +variant's override table. + +This configuration is often hooked into the mainboard's `enable_dev` callback, +defined in its `struct chip_operations`. + +## Potential issues (gotchas!) + +There are a couple of configurations that you need to especially careful about, +as they can have a large impact on your mainboard. + +The first is configuring a pin as an output, when it was designed to be an +input. There is a real risk in this case of short-circuiting a component which +could cause catastrophic failures, up to and including your mainboard! + +The other configuration option to watch out for deals with unconnected GPIOs. +If no pullup or pulldown is declared with these, they may end up "floating", +i.e., not at logical high or logical low. This can cause problems such as +unwanted power consumption or not reading the pin correctly, if it was intended +to be strapped. diff --git a/Documentation/getting_started/index.md b/Documentation/getting_started/index.md index 52d873ece2..9b9ac7f9e3 100644 --- a/Documentation/getting_started/index.md +++ b/Documentation/getting_started/index.md @@ -7,3 +7,4 @@ * [Gerrit Guidelines](gerrit_guidelines.md) * [Documentation License](license.md) * [Writing Documentation](writing_documentation.md) +* [Setting up GPIOs](gpio.md) |