PXA2xx/PXA3xx 處理器的 MFP 配置

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 中僅包含一個檔案,具體取決於所使用的處理器,因為引腳配置定義在這些檔案中可能衝突(即,在不同處理器上具有相同的名稱、不同的含義和設定)。 例如,對於支援 PXA300/PXA310 和 PXA320 的 zylonite 平臺,引入了兩個單獨的檔案: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,

    以表明該引腳具有喚醒系統的能力,以及在哪個邊沿。 然而,這並不一定意味著該引腳_會_喚醒系統,只有在呼叫帶有相應 GPIO IRQ(GPIO_IRQ(xx) 或 gpio_to_irq())的 set_irq_wake() 並最終呼叫 gpio_set_wake() 來進行實際暫存器設定時才會喚醒系統。

    d) 雖然 PXA3xx MFP 支援每個引腳上的邊沿檢測,但只有在設定了 ADxER 暫存器中的那些特定位時,內部邏輯才會喚醒系統,這些位可以很好地對映到相應的外設,因此可以呼叫帶有外設 IRQ 的 set_irq_wake() 以啟用喚醒。

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 以瞭解如何進行轉換。