This patch fixes the table issue in markdown file identified with commit
96481066 (Documentation: gpio: Update table as per coreboot guidelines).
BUG=b:211573253, b:211950520
Signed-off-by: Subrata Banik <subratabanik@google.com>
Change-Id: Ifd8265b92b5ef0dcabb754371591477ca19c39be
Reviewed-on: https://review.coreboot.org/c/coreboot/+/63177
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Michael Niewöhner <foss@mniewoehner.de>
Reviewed-by: Eric Lai <eric_lai@quanta.corp-partner.google.com>
		
	
		
			
				
	
	
		
			259 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			259 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| # 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)
 | |
|     /* 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`.
 | |
| 
 | |
| ## Unconnected and unused pads
 | |
| 
 | |
| In digital electronics, it is generally recommended to tie unconnected GPIOs to
 | |
| a defined signal like VCC or GND by setting their direction to output, adding an
 | |
| external pull resistor or configuring an internal pull resistor. This is done to
 | |
| prevent floating of the pin state, which can cause various issues like EMI,
 | |
| higher power usage due to continuously switching logic, etc.
 | |
| 
 | |
| On Intel PCHs from Sunrise Point onwards, termination of unconnected GPIOs is
 | |
| explicitly not required, when the input buffer is disabled by setting the bit
 | |
| `GPIORXDIS` which effectively disconnects the pad from the internal logic. All
 | |
| pads defaulting to GPIO mode have this bit set. However, in the mainboard's
 | |
| GPIO configuration the macro `PAD_NC(pad, NONE)` can be used to explicitly
 | |
| configure a pad as unconnected.
 | |
| 
 | |
| In case there are no schematics available for a board and the vendor set a
 | |
| pad to something like `GPIORXDIS=1`, `GPIOTXDIS=1` with an internal pull
 | |
| resistor, an unconnected or otherwise unused pad can be assumed. In this case it
 | |
| is recommended to keep the pull resistor, because the external circuit might
 | |
| rely on it.
 | |
| 
 | |
| Unconnected pads defaulting to a native function (input and output) usually
 | |
| don't need to be configured as GPIO with the `GPIORXDIS` bit set. For clarity
 | |
| and documentation purpose the macro may be used as well for them.
 | |
| 
 | |
| Some pads configured as native input function explicitly require external
 | |
| pull-ups when being unused, according to the PDGs:
 | |
| - eDP_HPD
 | |
| - SMBCLK/SMBDATA
 | |
| - SML0CLK/SML0DATA/SML0ALERT
 | |
| - SATAGP*
 | |
| 
 | |
| When the board was designed correctly, nothing needs to be done for them
 | |
| explicitly, while using `PAD_NC(pad, NONE)` can act as documentation. If such a
 | |
| pad is missing the external pull resistor due to bad board design, the pad
 | |
| should be configured with `PAD_NC(pad, NONE)` anyway to disconnect it
 | |
| internally.
 | |
| 
 | |
| ## 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!
 | |
| 
 | |
| ### Intel SoCs
 | |
| 
 | |
| As per Intel Platform Controller Hub (PCH) EDS since Skylake, a GPIO PAD register
 | |
| supports four different types of GPIO reset as:
 | |
| 
 | |
| ```eval_rst
 | |
| +------------------------+----------------+-------------+-------------+
 | |
| |                        |                |         PAD Reset ?       |
 | |
| + PAD Reset Config       + Platform Reset +-------------+-------------+
 | |
| |                        |                |     GPP     |     GPD     |
 | |
| +========================+================+=============+=============+
 | |
| | | 00 - Power Good      |  Warm Reset    |     N       |    N        |
 | |
| | | (GPP: RSMRST,        +----------------+-------------+-------------+
 | |
| | | GPD: DSW_PWROK)      |  Cold Reset    |     N       |    N        |
 | |
| |                        +----------------+-------------+-------------+
 | |
| |                        |  S3/S4/S5      |     N       |    N        |
 | |
| |                        +----------------+-------------+-------------+
 | |
| |                        |  Global Reset  |     N       |    N        |
 | |
| |                        +----------------+-------------+-------------+
 | |
| |                        |  Deep Sx       |     Y       |    N        |
 | |
| |                        +----------------+-------------+-------------+
 | |
| |                        |  G3            |     Y       |    Y        |
 | |
| +------------------------+----------------+-------------+-------------+
 | |
| | 01 - Deep              |  Warm Reset    |     Y       |    Y        |
 | |
| |                        +----------------+-------------+-------------+
 | |
| |                        |  Cold Reset    |     Y       |    Y        |
 | |
| |                        +----------------+-------------+-------------+
 | |
| |                        |  S3/S4/S5      |     N       |    N        |
 | |
| |                        +----------------+-------------+-------------+
 | |
| |                        |  Global Reset  |     Y       |    Y        |
 | |
| |                        +----------------+-------------+-------------+
 | |
| |                        |  Deep Sx       |     Y       |    Y        |
 | |
| |                        +----------------+-------------+-------------+
 | |
| |                        |  G3            |     Y       |    Y        |
 | |
| +------------------------+----------------+-------------+-------------+
 | |
| | 10 - Host Reset/PLTRST |  Warm Reset    |     Y       |    Y        |
 | |
| |                        +----------------+-------------+-------------+
 | |
| |                        |  Cold Reset    |     Y       |    Y        |
 | |
| |                        +----------------+-------------+-------------+
 | |
| |                        |  S3/S4/S5      |     Y       |    Y        |
 | |
| |                        +----------------+-------------+-------------+
 | |
| |                        |  Global Reset  |     Y       |    Y        |
 | |
| |                        +----------------+-------------+-------------+
 | |
| |                        |  Deep Sx       |     Y       |    Y        |
 | |
| |                        +----------------+-------------+-------------+
 | |
| |                        |  G3            |     Y       |    Y        |
 | |
| +------------------------+----------------+-------------+-------------+
 | |
| | | 11 - Resume Reset    |  Warm Reset    |     n/a     |    N        |
 | |
| | | (GPP: Reserved,      +----------------+-------------+-------------+
 | |
| | | GPD: RSMRST)         |  Cold Reset    |     n/a     |    N        |
 | |
| |                        +----------------+-------------+-------------+
 | |
| |                        |  S3/S4/S5      |     n/a     |    N        |
 | |
| |                        +----------------+-------------+-------------+
 | |
| |                        |  Global Reset  |     n/a     |    N        |
 | |
| |                        +----------------+-------------+-------------+
 | |
| |                        |  Deep Sx       |     n/a     |    Y        |
 | |
| |                        +----------------+-------------+-------------+
 | |
| |                        |  G3            |     n/a     |    Y        |
 | |
| +------------------------+----------------+-------------+-------------+
 | |
| ```
 | |
| 
 | |
| Each GPIO Community has a Pad Configuration Lock register for a GPP allowing locking
 | |
| specific register fields in the PAD configuration register.
 | |
| 
 | |
| The Pad Config Lock registers reset type is default hardcoded to **Power Good** and
 | |
| it's **not** configurable by GPIO PAD DW0.PadRstCfg. Hence, it may appear that for a GPP,
 | |
| the Pad Reset Config (DW0 Bit 31) is configured differently from `Power Good`.
 | |
| 
 | |
| This would create confusion where the Pad configuration is returned to its `default`
 | |
| value but remains `locked`, this would prevent software to reprogram the GPP.
 | |
| Additionally, this means software can't rely on GPIOs being reset by PLTRST# or Sx entry.
 | |
| 
 | |
| Hence, as per GPIO BIOS Writers Guide (BWG) it's recommended to change the Pad Reset
 | |
| Configuration for lock GPP as `Power Good` so that pad configuration and lock bit are
 | |
| always in sync and can be reset at the same time.
 | |
| 
 | |
| ## Soft Straps
 | |
| 
 | |
| Soft straps, that can be configured by the vendor in the Intel Flash Image Tool
 | |
| (FIT), can influence some pads' default mode. It is possible to select either a
 | |
| native function or GPIO mode for some pads on non-server SoCs, while on server
 | |
| SoCs most pads can be controlled. Thus, it is generally recommended to always
 | |
| configure all pads and don't just rely on the defaults mentioned in the
 | |
| datasheet(s) which might not reflect what the vendor configured.
 | |
| 
 | |
| ## Pad-related known issues and workarounds
 | |
| 
 | |
| ### LPC_CLKRUNB blocks S0ix states when board uses eSPI
 | |
| 
 | |
| When using eSPI, the pad implementing `LPC_CLKRUNB` must be set to GPIO mode.
 | |
| Other pin settings i.e. Rx path enable/disable, Tx path enable/disable, pull up
 | |
| enable/disable etc are ignored. Leaving this pin in native mode will keep the
 | |
| LPC Controller awake and prevent S0ix entry. This issues is know at least on
 | |
| Apollolake and Geminilake.
 |