Rex-BC Chen has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/62471 )
Change subject: soc/mediatek/mt8186: Add GPIO driving functions ......................................................................
soc/mediatek/mt8186: Add GPIO driving functions
Add GPIO driving functions to adjust pin driving. This implementation is according to chapter 5.1 in MT8186 Functional Specification.
BUG=b:218775654, b:216462313, b:212375511 TEST=build pass
Signed-off-by: Guodong Liu guodong.liu@mediatek.corp-partner.google.com Change-Id: I6d987f28be98b515fa5c542222bda08bea1d5118 --- M src/soc/mediatek/common/include/soc/gpio_common.h M src/soc/mediatek/mt8186/gpio.c M src/soc/mediatek/mt8186/include/soc/gpio.h 3 files changed, 519 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/71/62471/1
diff --git a/src/soc/mediatek/common/include/soc/gpio_common.h b/src/soc/mediatek/common/include/soc/gpio_common.h index 283cf94..cdf0240 100644 --- a/src/soc/mediatek/common/include/soc/gpio_common.h +++ b/src/soc/mediatek/common/include/soc/gpio_common.h @@ -18,10 +18,50 @@ GPIO_PULL_UP = 1, };
+/* The corresponding value of drive strength is different from different SoCs */ +enum gpio_drv { + GPIO_DRV0 = 0, + GPIO_DRV1 = 1, + GPIO_DRV2 = 2, + GPIO_DRV3 = 3, + GPIO_DRV4 = 4, + GPIO_DRV5 = 5, + GPIO_DRV6 = 6, + GPIO_DRV7 = 7, +}; + +/* + * GPIO DRIVING + * Special IO(I2C, HDMI...) advanced drive strength: + * GPIO_DRV_ADV0: 0.125mA + * GPIO_DRV_ADV1: 0.25mA + * GPIO_DRV_ADV2: 0.5mA + * GPIO_DRV_ADV3: 1mA + */ +enum gpio_drv_adv { + GPIO_DRV_ADV0 = 0, + GPIO_DRV_ADV1 = 1, + GPIO_DRV_ADV2 = 2, + GPIO_DRV_ADV3 = 3, +}; + +struct gpio_drv_info { + int32_t offset; + int8_t shift; + int8_t width; +}; + void gpio_set_pull(gpio_t gpio, enum pull_enable enable, enum pull_select select); void gpio_set_mode(gpio_t gpio, int mode);
+/* Normal driving function */ +int gpio_set_driving(gpio_t gpio, enum gpio_drv drv); +int gpio_get_driving(gpio_t gpio); +/* Advanced driving function */ +int gpio_set_driving_adv(gpio_t gpio, enum gpio_drv_adv drv); +int gpio_get_driving_adv(gpio_t gpio); + enum gpio_irq_type { IRQ_TYPE_EDGE_RISING, IRQ_TYPE_EDGE_FALLING, diff --git a/src/soc/mediatek/mt8186/gpio.c b/src/soc/mediatek/mt8186/gpio.c index bd3ab65..b22a868 100644 --- a/src/soc/mediatek/mt8186/gpio.c +++ b/src/soc/mediatek/mt8186/gpio.c @@ -8,6 +8,388 @@ #include <device/mmio.h> #include <gpio.h>
+static const struct gpio_drv_info gpio_driving_info[] = { + [0] = { 0x0, 27, 3, }, + [1] = { 0x0, 27, 3, }, + [2] = { 0x0, 27, 3, }, + [3] = { 0x0, 27, 3, }, + [4] = { 0x10, 0, 3, }, + [5] = { 0x10, 0, 3, }, + [6] = { 0x0, 9, 3, }, + [7] = { 0x0, 9, 3, }, + [8] = { 0x0, 9, 3, }, + [9] = { 0x0, 12, 3, }, + [10] = { 0x0, 0, 3, }, + [11] = { 0x0, 3, 3, }, + [12] = { 0x0, 6, 3, }, + [13] = { 0x0, 0, 3, }, + [14] = { 0x0, 3, 3, }, + [15] = { 0x10, 3, 3, }, + [16] = { 0x10, 3, 3, }, + [17] = { 0x0, 21, 3, }, + [18] = { 0x10, 0, 3, }, + [19] = { 0x0, 27, 3, }, + [20] = { 0x0, 24, 3, }, + [21] = { 0x0, 27, 3, }, + [22] = { 0x0, 24, 3, }, + [23] = { 0x10, 0, 3, }, + [24] = { 0x10, 9, 3, }, + [25] = { 0x10, 0, 3, }, + [26] = { 0x0, 27, 3, }, + [27] = { 0x0, 27, 3, }, + [28] = { 0x10, 0, 3, }, + [29] = { 0x10, 0, 3, }, + [30] = { 0x10, 0, 3, }, + [31] = { 0x10, 3, 3, }, + [32] = { 0x0, 6, 3, }, + [33] = { 0x0, 6, 3, }, + [34] = { 0x0, 3, 3, }, + [35] = { 0x0, 3, 3, }, + [36] = { 0x0, 9, 3, }, + [37] = { 0x0, 9, 3, }, + [38] = { 0x0, 12, 3, }, + [39] = { 0x0, 9, 3, }, + [40] = { 0x0, 15, 3, }, + [41] = { 0x0, 12, 3, }, + [42] = { 0x0, 12, 3, }, + [43] = { 0x0, 12, 3, }, + [44] = { 0x10, 6, 3, }, + [45] = { 0x10, 3, 3, }, + [46] = { 0x10, 3, 3, }, + [47] = { 0x10, 6, 3, }, + [48] = { 0x0, 15, 3, }, + [49] = { 0x0, 15, 3, }, + [50] = { 0x0, 15, 3, }, + [51] = { 0x0, 18, 3, }, + [52] = { 0x10, 3, 3, }, + [53] = { 0x10, 6, 3, }, + [54] = { 0x10, 3, 3, }, + [55] = { 0x10, 3, 3, }, + [56] = { 0x10, 3, 3, }, + [57] = { 0x10, 6, 3, }, + [58] = { 0x10, 6, 3, }, + [59] = { 0x10, 3, 3, }, + [60] = { 0x0, 24, 3, }, + [61] = { 0x0, 24, 3, }, + [62] = { 0x0, 24, 3, }, + [63] = { 0x0, 24, 3, }, + [64] = { 0x0, 27, 3, }, + [65] = { 0x0, 27, 3, }, + [66] = { 0x0, 27, 3, }, + [67] = { 0x10, 0, 3, }, + [68] = { 0x0, 0, 3, }, + [69] = { 0x0, 3, 3, }, + [70] = { 0x10, 3, 3, }, + [71] = { 0x0, 6, 3, }, + [72] = { 0x0, 9, 3, }, + [73] = { 0x0, 12, 3, }, + [74] = { 0x0, 15, 3, }, + [75] = { 0x0, 18, 3, }, + [76] = { 0x0, 21, 3, }, + [77] = { 0x0, 24, 3, }, + [78] = { 0x0, 27, 3, }, + [79] = { 0x0, 24, 3, }, + [80] = { 0x0, 24, 3, }, + [81] = { 0x0, 21, 3, }, + [82] = { 0x0, 21, 3, }, + [83] = { 0x10, 3, 3, }, + [84] = { 0x0, 6, 3, }, + [85] = { 0x0, 9, 3, }, + [86] = { 0x0, 12, 3, }, + [87] = { 0x0, 15, 3, }, + [88] = { 0x0, 18, 3, }, + [89] = { 0x0, 21, 3, }, + [90] = { 0x0, 27, 3, }, + [91] = { 0x10, 0, 3, }, + [92] = { 0x10, 0, 3, }, + [93] = { 0x10, 0, 3, }, + [94] = { 0x10, 0, 3, }, + [95] = { 0x10, 3, 3, }, + [96] = { 0x0, 9, 3, }, + [97] = { 0x0, 6, 3, }, + [98] = { 0x0, 3, 3, }, + [99] = { 0x0, 18, 3, }, + [100] = { 0x0, 18, 3, }, + [101] = { 0x0, 21, 3, }, + [102] = { 0x0, 21, 3, }, + [103] = { 0x0, 21, 3, }, + [104] = { 0x0, 21, 3, }, + [105] = { 0x0, 24, 3, }, + [106] = { 0x0, 24, 3, }, + [107] = { 0x0, 24, 3, }, + [108] = { 0x0, 24, 3, }, + [109] = { 0x0, 27, 3, }, + [110] = { 0x0, 27, 3, }, + [111] = { 0x0, 27, 3, }, + [112] = { 0x0, 27, 3, }, + [113] = { 0x10, 0, 3, }, + [114] = { 0x10, 0, 3, }, + [115] = { 0x10, 6, 3, }, + [116] = { 0x10, 9, 3, }, + [117] = { 0x10, 6, 3, }, + [118] = { 0x10, 6, 3, }, + [119] = { 0x0, 18, 3, }, + [120] = { 0x0, 9, 3, }, + [121] = { 0x0, 12, 3, }, + [122] = { 0x0, 15, 3, }, + [123] = { 0x0, 21, 3, }, + [124] = { 0x0, 0, 3, }, + [125] = { 0x0, 3, 3, }, + [126] = { 0x0, 6, 3, }, + [127] = { 0x10, 12, 3, }, + [128] = { 0x10, 18, 3, }, + [129] = { 0x10, 12, 3, }, + [130] = { 0x10, 18, 3, }, + [131] = { 0x10, 15, 3, }, + [132] = { 0x10, 21, 3, }, + [133] = { 0x10, 15, 3, }, + [134] = { 0x10, 21, 3, }, + [135] = { 0x10, 6, 3, }, + [136] = { 0x10, 15, 3, }, + [137] = { 0x10, 18, 3, }, + [138] = { 0x10, 24, 3, }, + [139] = { 0x0, 21, 3, }, + [140] = { 0x0, 24, 3, }, + [141] = { 0x10, 15, 3, }, + [142] = { 0x10, 21, 3, }, + [143] = { 0x10, 9, 3, }, + [144] = { 0x10, 18, 3, }, + [145] = { 0x10, 12, 3, }, + [146] = { 0x10, 21, 3, }, + [147] = { 0x0, 12, 3, }, + [148] = { 0x0, 12, 3, }, + [149] = { 0x0, 12, 3, }, + [150] = { 0x0, 15, 3, }, + [151] = { 0x0, 15, 3, }, + [152] = { 0x0, 9, 3, }, + [153] = { 0x0, 15, 3, }, + [154] = { 0x0, 15, 3, }, + [155] = { 0x0, 18, 3, }, + [156] = { 0x0, 18, 3, }, + [157] = { 0x0, 0, 3, }, + [158] = { 0x0, 0, 3, }, + [159] = { 0x0, 0, 3, }, + [160] = { 0x0, 0, 3, }, + [161] = { 0x0, 6, 3, }, + [162] = { 0x0, 3, 3, }, + [163] = { 0x10, 12, 3, }, + [164] = { -1, -1, -1}, + [165] = { 0x10, 6, 3, }, + [166] = { 0x10, 6, 3, }, + [167] = { 0x10, 9, 3, }, + [168] = { 0x10, 6, 3, }, + [169] = { 0x10, 12, 3, }, + [170] = { 0x10, 9, 3, }, + [171] = { 0x10, 9, 3, }, + [172] = { 0x10, 9, 3, }, + [173] = { 0x10, 6, 3, }, + [174] = { 0x0, 9, 3, }, + [175] = { 0x0, 12, 3, }, + [176] = { 0x0, 0, 3, }, + [177] = { 0x0, 3, 3, }, + [178] = { 0x0, 6, 3, }, + [179] = { 0x0, 15, 3, }, + [180] = { 0x0, 18, 3, }, + [181] = { 0x0, 21, 3, }, + [182] = { 0x0, 24, 3, }, + [183] = { 0x0, 27, 3, }, + [184] = { 0x10, 0, 3, }, +}; + +_Static_assert(ARRAY_SIZE(gpio_driving_info) == GPIO_NUM, + "gpio_driving_info array size not match"); + +static const struct gpio_drv_info gpio_driving_adv_info[] = { + [0] = { -1, -1, -1, }, + [1] = { -1, -1, -1, }, + [2] = { -1, -1, -1, }, + [3] = { -1, -1, -1, }, + [4] = { -1, -1, -1, }, + [5] = { -1, -1, -1, }, + [6] = { -1, -1, -1, }, + [7] = { -1, -1, -1, }, + [8] = { -1, -1, -1, }, + [9] = { -1, -1, -1, }, + [10] = { -1, -1, -1, }, + [11] = { -1, -1, -1, }, + [12] = { -1, -1, -1, }, + [13] = { -1, -1, -1, }, + [14] = { -1, -1, -1, }, + [15] = { -1, -1, -1, }, + [16] = { -1, -1, -1, }, + [17] = { -1, -1, -1, }, + [18] = { -1, -1, -1, }, + [19] = { -1, -1, -1, }, + [20] = { -1, -1, -1, }, + [21] = { -1, -1, -1, }, + [22] = { -1, -1, -1, }, + [23] = { -1, -1, -1, }, + [24] = { -1, -1, -1, }, + [25] = { -1, -1, -1, }, + [26] = { -1, -1, -1, }, + [27] = { -1, -1, -1, }, + [28] = { -1, -1, -1, }, + [29] = { -1, -1, -1, }, + [30] = { -1, -1, -1, }, + [31] = { -1, -1, -1, }, + [32] = { -1, -1, -1, }, + [33] = { -1, -1, -1, }, + [34] = { -1, -1, -1, }, + [35] = { -1, -1, -1, }, + [36] = { -1, -1, -1, }, + [37] = { -1, -1, -1, }, + [38] = { -1, -1, -1, }, + [39] = { -1, -1, -1, }, + [40] = { -1, -1, -1, }, + [41] = { -1, -1, -1, }, + [42] = { -1, -1, -1, }, + [43] = { -1, -1, -1, }, + [44] = { -1, -1, -1, }, + [45] = { -1, -1, -1, }, + [46] = { -1, -1, -1, }, + [47] = { -1, -1, -1, }, + [48] = { -1, -1, -1, }, + [49] = { -1, -1, -1, }, + [50] = { -1, -1, -1, }, + [51] = { -1, -1, -1, }, + [52] = { -1, -1, -1, }, + [53] = { -1, -1, -1, }, + [54] = { -1, -1, -1, }, + [55] = { -1, -1, -1, }, + [56] = { -1, -1, -1, }, + [57] = { -1, -1, -1, }, + [58] = { -1, -1, -1, }, + [59] = { -1, -1, -1, }, + [60] = { -1, -1, -1, }, + [61] = { -1, -1, -1, }, + [62] = { -1, -1, -1, }, + [63] = { -1, -1, -1, }, + [64] = { -1, -1, -1, }, + [65] = { -1, -1, -1, }, + [66] = { -1, -1, -1, }, + [67] = { -1, -1, -1, }, + [68] = { -1, -1, -1, }, + [69] = { -1, -1, -1, }, + [70] = { -1, -1, -1, }, + [71] = { -1, -1, -1, }, + [72] = { -1, -1, -1, }, + [73] = { -1, -1, -1, }, + [74] = { -1, -1, -1, }, + [75] = { -1, -1, -1, }, + [76] = { -1, -1, -1, }, + [77] = { -1, -1, -1, }, + [78] = { -1, -1, -1, }, + [79] = { -1, -1, -1, }, + [80] = { -1, -1, -1, }, + [81] = { -1, -1, -1, }, + [82] = { -1, -1, -1, }, + [83] = { -1, -1, -1, }, + [84] = { -1, -1, -1, }, + [85] = { -1, -1, -1, }, + [86] = { -1, -1, -1, }, + [87] = { -1, -1, -1, }, + [88] = { -1, -1, -1, }, + [89] = { -1, -1, -1, }, + [90] = { -1, -1, -1, }, + [91] = { -1, -1, -1, }, + [92] = { -1, -1, -1, }, + [93] = { -1, -1, -1, }, + [94] = { -1, -1, -1, }, + [95] = { -1, -1, -1, }, + [96] = { -1, -1, -1, }, + [97] = { -1, -1, -1, }, + [98] = { -1, -1, -1, }, + [99] = { -1, -1, -1, }, + [100] = { -1, -1, -1, }, + [101] = { -1, -1, -1, }, + [102] = { -1, -1, -1, }, + [103] = { -1, -1, -1, }, + [104] = { -1, -1, -1, }, + [105] = { -1, -1, -1, }, + [106] = { -1, -1, -1, }, + [107] = { -1, -1, -1, }, + [108] = { -1, -1, -1, }, + [109] = { -1, -1, -1, }, + [110] = { -1, -1, -1, }, + [111] = { -1, -1, -1, }, + [112] = { -1, -1, -1, }, + [113] = { -1, -1, -1, }, + [114] = { -1, -1, -1, }, + [115] = { -1, -1, -1, }, + [116] = { -1, -1, -1, }, + [117] = { -1, -1, -1, }, + [118] = { -1, -1, -1, }, + [119] = { -1, -1, -1, }, + [120] = { -1, -1, -1, }, + [121] = { -1, -1, -1, }, + [122] = { -1, -1, -1, }, + [123] = { -1, -1, -1, }, + [124] = { -1, -1, -1, }, + [125] = { -1, -1, -1, }, + [126] = { -1, -1, -1, }, + [127] = { 0x30, 0, 3, }, + [128] = { 0x30, 6, 3, }, + [129] = { 0x30, 0, 3, }, + [130] = { 0x30, 6, 3, }, + [131] = { 0x30, 3, 3, }, + [132] = { 0x30, 9, 3, }, + [133] = { 0x30, 0, 3, }, + [134] = { 0x30, 6, 3, }, + [135] = { 0x20, 0, 3, }, + [136] = { 0x20, 9, 3, }, + [137] = { 0x30, 3, 3, }, + [138] = { 0x30, 9, 3, }, + [139] = { 0x20, 0, 3, }, + [140] = { 0x20, 3, 3, }, + [141] = { 0x30, 3, 3, }, + [142] = { 0x30, 9, 3, }, + [143] = { 0x20, 3, 3, }, + [144] = { 0x20, 12, 3, }, + [145] = { 0x20, 6, 3, }, + [146] = { 0x20, 15, 3, }, + [147] = { -1, -1, -1, }, + [148] = { -1, -1, -1, }, + [149] = { -1, -1, -1, }, + [150] = { -1, -1, -1, }, + [151] = { -1, -1, -1, }, + [152] = { -1, -1, -1, }, + [153] = { -1, -1, -1, }, + [154] = { -1, -1, -1, }, + [155] = { -1, -1, -1, }, + [156] = { -1, -1, -1, }, + [157] = { -1, -1, -1, }, + [158] = { -1, -1, -1, }, + [159] = { -1, -1, -1, }, + [160] = { -1, -1, -1, }, + [161] = { -1, -1, -1, }, + [162] = { -1, -1, -1, }, + [163] = { -1, -1, -1, }, + [164] = { -1, -1, -1, }, + [165] = { -1, -1, -1, }, + [166] = { -1, -1, -1, }, + [167] = { -1, -1, -1, }, + [168] = { -1, -1, -1, }, + [169] = { -1, -1, -1, }, + [170] = { -1, -1, -1, }, + [171] = { -1, -1, -1, }, + [172] = { -1, -1, -1, }, + [173] = { -1, -1, -1, }, + [174] = { -1, -1, -1, }, + [175] = { -1, -1, -1, }, + [176] = { -1, -1, -1, }, + [177] = { -1, -1, -1, }, + [178] = { -1, -1, -1, }, + [179] = { -1, -1, -1, }, + [180] = { -1, -1, -1, }, + [181] = { -1, -1, -1, }, + [182] = { -1, -1, -1, }, + [183] = { -1, -1, -1, }, + [184] = { -1, -1, -1, }, +}; + +_Static_assert(ARRAY_SIZE(gpio_driving_adv_info) == GPIO_NUM, + "gpio_driving_adv_info array size not match"); + static void *gpio_find_reg_addr(gpio_t gpio) { void *reg_addr; @@ -95,3 +477,98 @@ else gpio_set_pull_pu_pd(gpio, enable, select); } + +static inline bool is_valid_drv(enum gpio_drv drv) +{ + return (drv <= GPIO_DRV7 && drv >= GPIO_DRV0); +} + +static inline bool is_valid_drv_adv(enum gpio_drv_adv drv) +{ + return (drv <= GPIO_DRV_ADV3 && drv >= GPIO_DRV_ADV0); +} + +int gpio_set_driving(gpio_t gpio, enum gpio_drv drv) +{ + uint32_t mask; + const struct gpio_drv_info *info = &gpio_driving_info[gpio.id]; + const struct gpio_drv_info *adv_info = &gpio_driving_adv_info[gpio.id]; + void *reg, *reg_adv; + + if (!is_valid_drv(drv)) + return -1; + + reg = gpio_find_reg_addr(gpio) + info->offset; + reg_adv = gpio_find_reg_addr(gpio) + adv_info->offset; + + if (info->shift == -1) + return -1; + + mask = BIT(info->width) - 1; + /* Check setting value is not beyond width */ + if ((uint32_t)drv > mask) + return -1; + + clrsetbits32(reg, mask << info->shift, drv << info->shift); + + /* Disable EH if supported */ + if (adv_info->shift != -1) + clrbits32(reg_adv, BIT(adv_info->shift)); + + return 0; +} + +int gpio_get_driving(gpio_t gpio) +{ + const struct gpio_drv_info *info = &gpio_driving_info[gpio.id]; + void *reg; + + reg = gpio_find_reg_addr(gpio) + info->offset; + if (info->shift == -1) + return -1; + + return (read32(reg) >> info->shift) & (BIT(info->width) - 1); +} + +int gpio_set_driving_adv(gpio_t gpio, enum gpio_drv_adv drv) +{ + uint32_t mask; + const struct gpio_drv_info *adv_info = &gpio_driving_adv_info[gpio.id]; + void *reg_adv; + + if (!is_valid_drv_adv(drv)) + return -1; + + reg_adv = gpio_find_reg_addr(gpio) + adv_info->offset; + + if (adv_info->shift == -1) + return -1; + + /* Not include EH bit (the lowest bit) */ + if ((uint32_t)drv > (BIT(adv_info->width - 1) - 1)) + return -1; + + mask = BIT(adv_info->width) - 1; + /* EH enable */ + drv = (drv << 1) | BIT(0); + + clrsetbits32(reg_adv, mask << adv_info->shift, drv << adv_info->shift); + + return 0; +} + +int gpio_get_driving_adv(gpio_t gpio) +{ + const struct gpio_drv_info *adv_info = &gpio_driving_adv_info[gpio.id]; + void *reg_adv; + uint32_t drv; + + reg_adv = gpio_find_reg_addr(gpio) + adv_info->offset; + if (adv_info->shift == -1) + return -1; + + drv = (read32(reg_adv) >> adv_info->shift) & (BIT(adv_info->width) - 1); + + /* Drop EH bit */ + return drv >> 1; +} diff --git a/src/soc/mediatek/mt8186/include/soc/gpio.h b/src/soc/mediatek/mt8186/include/soc/gpio.h index a47d27c..628b482 100644 --- a/src/soc/mediatek/mt8186/include/soc/gpio.h +++ b/src/soc/mediatek/mt8186/include/soc/gpio.h @@ -12,6 +12,8 @@ #include <soc/gpio_common.h> #include <types.h>
+#define GPIO_NUM 185 + enum { MAX_GPIO_REG_BITS = 32, MAX_GPIO_MODE_PER_REG = 8,