PXA2xx/PXA3xx 处理器多功能引脚配置

MFP 代表多功能引脚,它是 PXA3xx 及更高版本 PXA 系列处理器上的引脚复用逻辑。本文档描述了现有的 MFP API,以及板/平台驱动程序作者如何使用它。

基本概念

与 PXA25x 和 PXA27x 上的 GPIO 备用功能设置不同,从 PXA3xx 引入了一种新的 MFP 机制,将引脚复用功能完全移出 GPIO 控制器。除了引脚复用配置外,MFP 还控制每个引脚的低功耗状态、驱动强度、上拉/下拉和事件检测。下面是 MFP 逻辑与其余 SoC 外围设备之间内部连接的示意图

+--------+
|        |--(GPIO19)--+
|  GPIO  |            |
|        |--(GPIO...) |
+--------+            |
                      |       +---------+
+--------+            +------>|         |
|  PWM2  |--(PWM_OUT)-------->|   MFP   |
+--------+            +------>|         |-------> to external PAD
                      | +---->|         |
+--------+            | | +-->|         |
|  SSP2  |---(TXD)----+ | |   +---------+
+--------+              | |
                        | |
+--------+              | |
| Keypad |--(MKOUT4)----+ |
+--------+                |
                          |
+--------+                |
|  UART2 |---(TXD)--------+
+--------+

注意:外部焊盘命名为 MFP_PIN_GPIO19,这并不一定意味着它专用于 GPIO19,只是提示内部此引脚可以从 GPIO 控制器的 GPIO19 路由。

为了更好地理解从 PXA25x/PXA27x GPIO 备用功能到这种新 MFP 机制的变化,以下是几个关键点

  1. PXA3xx 上的 GPIO 控制器现在是一个专用控制器,与其他内部控制器(如 PWM、SSP 和 UART)相同,具有 128 个内部信号,这些信号可以通过一个或多个 MFP 路由到外部(例如,GPIO<0> 可以通过 MFP_PIN_GPIO0 以及 MFP_PIN_GPIO0_2 路由,请参阅 arch/arm/mach-pxa/mfp-pxa300.h)

  2. 备用功能配置已从此 GPIO 控制器中删除,剩余的功能是纯 GPIO 特定的,即

    • GPIO 信号电平控制

    • GPIO 方向控制

    • GPIO 电平变化检测

  3. 每个引脚的低功耗状态现在由 MFP 控制,这意味着 PXA2xx 上的 PGSRx 寄存器在 PXA3xx 上现在无用

  4. 唤醒检测现在由 MFP 控制,PWER 不再控制来自 GPIO 的唤醒,根据睡眠状态,ADxER(在 pxa3xx-regs.h 中定义)控制来自 MFP 的唤醒

注意:通过如此清晰地分离 MFP 和 GPIO,我们通常所说的 GPIO<xx> 是指它是一个 GPIO 信号,而 MFP<xxx> 或引脚 xxx,是指一个物理焊盘(或球)。

MFP API 用法

对于板代码编写者,以下是一些指南

  1. 在您的 <board>.c 中包含以下头文件之一

    • #include “mfp-pxa25x.h”

    • #include “mfp-pxa27x.h”

    • #include “mfp-pxa300.h”

    • #include “mfp-pxa320.h”

    • #include “mfp-pxa930.h”

    注意:在您的 <board>.c 中只能有一个文件,具体取决于使用的处理器,因为引脚配置定义在这些文件中可能会冲突(即,相同的名称,但在不同的处理器上具有不同的含义和设置)。例如,对于 zylonite 平台,它支持 PXA300/PXA310 和 PXA320,引入了两个单独的文件:zylonite_pxa300.c 和 zylonite_pxa320.c(除了处理 MFP 配置差异外,它们还处理这两种组合之间的其他差异)。

    注意:PXA300 和 PXA310 在引脚配置方面几乎相同(PXA310 支持一些额外的引脚),因此差异实际上包含在一个 mfp-pxa300.h 中。

  2. 准备一个用于初始引脚配置的数组,例如

    static unsigned long mainstone_pin_config[] __initdata = {
       /* Chip Select */
       GPIO15_nCS_1,
    
       /* LCD - 16bpp Active TFT */
       GPIOxx_TFT_LCD_16BPP,
       GPIO16_PWM0_OUT,        /* Backlight */
    
       /* MMC */
       GPIO32_MMC_CLK,
       GPIO112_MMC_CMD,
       GPIO92_MMC_DAT_0,
       GPIO109_MMC_DAT_1,
       GPIO110_MMC_DAT_2,
       GPIO111_MMC_DAT_3,
    
       ...
    
       /* GPIO */
       GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH,
    };
    

    a) 一旦引脚配置传递给 pxa{2xx,3xx}_mfp_config() 并写入实际寄存器,它们就无用了,可以丢弃,添加 ‘__initdata’ 将有助于在此处节省一些额外的字节。

    b) 当组件只有一种可能的引脚配置时,可以使用一些简化的定义,例如 PXA25x 和 PXA27x 处理器上的 GPIOxx_TFT_LCD_16BPP

    c) 如果按照板设计,可以将引脚配置为从低功耗状态唤醒系统,则可以与以下任何一个“或”运算

    WAKEUP_ON_EDGE_BOTH WAKEUP_ON_EDGE_RISE WAKEUP_ON_EDGE_FALL WAKEUP_ON_LEVEL_HIGH - 专门用于启用键盘 GPIO,

    以指示此引脚具有唤醒系统的能力,以及在哪个或哪些边沿上唤醒。但是,这并不一定意味着引脚 _将_ 唤醒系统,只有在调用 set_irq_wake() 并使用相应的 GPIO IRQ (GPIO_IRQ(xx) 或 gpio_to_irq()) 并最终调用 gpio_set_wake() 进行实际寄存器设置时才会唤醒。

    d) 虽然 PXA3xx MFP 支持每个引脚上的边沿检测,但只有当 ADxER 寄存器中的那些特定位被设置时,内部逻辑才会唤醒系统,这可以很好地映射到相应的外围设备,因此可以调用 set_irq_wake() 并使用外围设备的 IRQ 来启用唤醒。

PXA3xx 上的 MFP

PXA3xx 上的每个外部 I/O 焊盘(不包括那些用于特殊用途的焊盘)都关联一个 MFP 逻辑,并由一个 MFP 寄存器 (MFPR) 控制。

MFPR 具有以下位定义(对于 PXA300/PXA310/PXA320)

31                        16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
 +-------------------------+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
 |         RESERVED        |PS|PU|PD|  DRIVE |SS|SD|SO|EC|EF|ER|--| AF_SEL |
 +-------------------------+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

 Bit 3:   RESERVED
 Bit 4:   EDGE_RISE_EN - enable detection of rising edge on this pin
 Bit 5:   EDGE_FALL_EN - enable detection of falling edge on this pin
 Bit 6:   EDGE_CLEAR   - disable edge detection on this pin
 Bit 7:   SLEEP_OE_N   - enable outputs during low power modes
 Bit 8:   SLEEP_DATA   - output data on the pin during low power modes
 Bit 9:   SLEEP_SEL    - selection control for low power modes signals
 Bit 13:  PULLDOWN_EN  - enable the internal pull-down resistor on this pin
 Bit 14:  PULLUP_EN    - enable the internal pull-up resistor on this pin
 Bit 15:  PULL_SEL     - pull state controlled by selected alternate function
                         (0) or by PULL{UP,DOWN}_EN bits (1)

 Bit 0 - 2: AF_SEL - alternate function selection, 8 possibilities, from 0-7
 Bit 10-12: DRIVE  - drive strength and slew rate
                       0b000 - fast 1mA
                       0b001 - fast 2mA
                       0b002 - fast 3mA
                       0b003 - fast 4mA
                       0b004 - slow 6mA
                       0b005 - fast 6mA
                       0b006 - slow 10mA
                       0b007 - fast 10mA

PXA2xx/PXA3xx 的 MFP 设计

由于 PXA2xx 和 PXA3xx 之间的引脚复用处理方式不同,因此引入了统一的 MFP API 来覆盖这两个系列的处理器。

此设计的基本思想是为所有可能的引脚配置引入定义,这些定义是独立于处理器和平台的,并且实际调用的 API 会将这些定义转换为寄存器设置,并在此之后使它们生效。

涉及的文件

  • arch/arm/mach-pxa/include/mach/mfp.h

用于
  1. 统一引脚定义 - 所有可配置引脚的枚举常量

  2. 用于可能的 MFP 配置的处理器无关的位定义

  • arch/arm/mach-pxa/mfp-pxa3xx.h

用于 PXA3xx 特定 MFPR 寄存器位定义和 PXA3xx 通用引脚配置

  • arch/arm/mach-pxa/mfp-pxa2xx.h

用于 PXA2xx 特定定义和 PXA25x/PXA27x 通用引脚配置

  • arch/arm/mach-pxa/mfp-pxa25x.h arch/arm/mach-pxa/mfp-pxa27x.h arch/arm/mach-pxa/mfp-pxa300.h arch/arm/mach-pxa/mfp-pxa320.h arch/arm/mach-pxa/mfp-pxa930.h

用于处理器特定定义

  • arch/arm/mach-pxa/mfp-pxa3xx.c

  • arch/arm/mach-pxa/mfp-pxa2xx.c

用于实现引脚配置,使其对实际处理器生效。

引脚配置

以下注释是从 mfp.h 中复制的(有关最新信息,请参阅实际源代码)

 /*
  * a possible MFP configuration is represented by a 32-bit integer
  *
  * bit  0.. 9 - MFP Pin Number (1024 Pins Maximum)
  * bit 10..12 - Alternate Function Selection
  * bit 13..15 - Drive Strength
  * bit 16..18 - Low Power Mode State
  * bit 19..20 - Low Power Mode Edge Detection
  * bit 21..22 - Run Mode Pull State
  *
  * to facilitate the definition, the following macros are provided
  *
  * MFP_CFG_DEFAULT - default MFP configuration value, with
  *            alternate function = 0,
  *            drive strength = fast 3mA (MFP_DS03X)
  *            low power mode = default
  *            edge detection = none
  *
  * MFP_CFG  - default MFPR value with alternate function
  * MFP_CFG_DRV      - default MFPR value with alternate function and
  *            pin drive strength
  * MFP_CFG_LPM      - default MFPR value with alternate function and
  *            low power mode
  * MFP_CFG_X        - default MFPR value with alternate function,
  *            pin drive strength and low power mode
  */

Examples of pin configurations are::

  #define GPIO94_SSP3_RXD            MFP_CFG_X(GPIO94, AF1, DS08X, FLOAT)

which reads GPIO94 can be configured as SSP3_RXD, with alternate function
selection of 1, driving strength of 0b101, and a float state in low power
modes.

NOTE: this is the default setting of this pin being configured as SSP3_RXD
which can be modified a bit in board code, though it is not recommended to
do so, simply because this default setting is usually carefully encoded,
and is supposed to work in most cases.

寄存器设置

PXA3xx 上引脚配置的寄存器设置实际上非常简单,大多数位都可以更容易地直接转换为 MFPR 值。计算了两组 MFPR 值:运行时值和低功耗模式值,以允许不同的设置。

从通用引脚配置到 PXA2xx 上实际寄存器设置的转换有点复杂:涉及许多寄存器,包括 GAFRx、GPDRx、PGSRx、PWER、PKWR、PFER 和 PRER。请参阅 mfp-pxa2xx.c 以了解如何进行转换。