From efaeed6cb29079820a11043d0473a2562a2d4b16 Mon Sep 17 00:00:00 2001 From: Tim Lin Date: Fri, 7 Jan 2022 11:01:07 +0800 Subject: [PATCH] ITE: drviers/pinctrl: Add pinctrl driver for IT8XXX2 Add pinctrl driver for ITE IT8XXX2. Signed-off-by: Tim Lin --- drivers/pinctrl/CMakeLists.txt | 1 + drivers/pinctrl/Kconfig | 1 + drivers/pinctrl/Kconfig.it8xxx2 | 11 + drivers/pinctrl/pinctrl_ite_it8xxx2.c | 206 ++++++++++++++ .../pinctrl/ite,it8xxx2-pinctrl-func.yaml | 37 +++ dts/bindings/pinctrl/ite,it8xxx2-pinctrl.yaml | 95 +++++++ dts/riscv/it8xxx2.dtsi | 262 ++++++++++++++++++ .../dt-bindings/pinctrl/it8xxx2-pinctrl.h | 9 + soc/riscv/riscv-ite/common/check_regs.c | 11 + soc/riscv/riscv-ite/common/chip_chipregs.h | 97 ++++++- soc/riscv/riscv-ite/common/pinctrl_soc.h | 152 ++++++++++ .../it8xxx2/Kconfig.defconfig.series | 3 + 12 files changed, 884 insertions(+), 1 deletion(-) create mode 100644 drivers/pinctrl/Kconfig.it8xxx2 create mode 100644 drivers/pinctrl/pinctrl_ite_it8xxx2.c create mode 100644 dts/bindings/pinctrl/ite,it8xxx2-pinctrl-func.yaml create mode 100644 dts/bindings/pinctrl/ite,it8xxx2-pinctrl.yaml create mode 100644 soc/riscv/riscv-ite/common/pinctrl_soc.h diff --git a/drivers/pinctrl/CMakeLists.txt b/drivers/pinctrl/CMakeLists.txt index fdd9b41d29e..8e49c4a24d5 100644 --- a/drivers/pinctrl/CMakeLists.txt +++ b/drivers/pinctrl/CMakeLists.txt @@ -6,6 +6,7 @@ zephyr_library_sources(common.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_TELINK_B91 pinctrl_b91.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_GD32_AF pinctrl_gd32_af.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_GD32_AFIO pinctrl_gd32_afio.c) +zephyr_library_sources_ifdef(CONFIG_PINCTRL_ITE_IT8XXX2 pinctrl_ite_it8xxx2.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_NRF pinctrl_nrf.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_RCAR_PFC pfc_rcar.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_RPI_PICO pinctrl_rpi_pico.c) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 9a262bcb824..889b159d949 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -31,6 +31,7 @@ config PINCTRL_DYNAMIC source "drivers/pinctrl/Kconfig.b91" source "drivers/pinctrl/Kconfig.gd32" +source "drivers/pinctrl/Kconfig.it8xxx2" source "drivers/pinctrl/Kconfig.nrf" source "drivers/pinctrl/Kconfig.rcar" source "drivers/pinctrl/Kconfig.rpi_pico" diff --git a/drivers/pinctrl/Kconfig.it8xxx2 b/drivers/pinctrl/Kconfig.it8xxx2 new file mode 100644 index 00000000000..5c8b2d9eb6f --- /dev/null +++ b/drivers/pinctrl/Kconfig.it8xxx2 @@ -0,0 +1,11 @@ +# Copyright (c) 2022 ITE Corporation. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 + +DT_COMPAT_ITE_IT8XXX2_PINCTRL := ite,it8xxx2-pinctrl + +config PINCTRL_ITE_IT8XXX2 + bool "ITE IT8XXX2 pin controller driver" + depends on SOC_FAMILY_RISCV_ITE + default $(dt_compat_enabled,$(DT_COMPAT_ITE_IT8XXX2_PINCTRL)) + help + Enable IT8XXX2 pin controller driver. diff --git a/drivers/pinctrl/pinctrl_ite_it8xxx2.c b/drivers/pinctrl/pinctrl_ite_it8xxx2.c new file mode 100644 index 00000000000..14c7b490a20 --- /dev/null +++ b/drivers/pinctrl/pinctrl_ite_it8xxx2.c @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2022 ITE Corporation. All Rights Reserved. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT ite_it8xxx2_pinctrl_func + +#include + +#include +LOG_MODULE_REGISTER(pinctrl_ite_it8xxx2, LOG_LEVEL_ERR); + +#define GPIO_IT8XXX2_REG_BASE \ + ((struct gpio_it8xxx2_regs *)DT_REG_ADDR(DT_NODELABEL(gpiogcr))) +#define GPIO_GROUP_MEMBERS 8 + +struct pinctrl_it8xxx2_config { + /* gpio port control register (byte mapping to pin) */ + uint8_t *reg_gpcr; + /* function 3 general control register */ + uintptr_t func3_gcr[GPIO_GROUP_MEMBERS]; + /* function 3 enable mask */ + uint8_t func3_en_mask[GPIO_GROUP_MEMBERS]; + /* function 4 general control register */ + uintptr_t func4_gcr[GPIO_GROUP_MEMBERS]; + /* function 4 enable mask */ + uint8_t func4_en_mask[GPIO_GROUP_MEMBERS]; + /* Input voltage selection */ + uintptr_t volt_sel[GPIO_GROUP_MEMBERS]; + /* Input voltage selection mask */ + uint8_t volt_sel_mask[GPIO_GROUP_MEMBERS]; +}; + +static int pinctrl_it8xxx2_set(const pinctrl_soc_pin_t *pins) +{ + const struct pinctrl_it8xxx2_config *pinctrl_config = pins->pinctrls->config; + uint32_t pincfg = pins->pincfg; + uint8_t pin = pins->pin; + volatile uint8_t *reg_gpcr = (uint8_t *)pinctrl_config->reg_gpcr + pin; + volatile uint8_t *reg_volt_sel = (uint8_t *)(pinctrl_config->volt_sel[pin]); + + /* Setting pull-up or pull-down. */ + switch (IT8XXX2_DT_PINCFG_PUPDR(pincfg)) { + case IT8XXX2_PULL_PIN_DEFAULT: + /* No pull-up or pull-down */ + *reg_gpcr &= ~(GPCR_PORT_PIN_MODE_PULLUP | + GPCR_PORT_PIN_MODE_PULLDOWN); + break; + case IT8XXX2_PULL_UP: + *reg_gpcr = (*reg_gpcr | GPCR_PORT_PIN_MODE_PULLUP) & + ~GPCR_PORT_PIN_MODE_PULLDOWN; + break; + case IT8XXX2_PULL_DOWN: + *reg_gpcr = (*reg_gpcr | GPCR_PORT_PIN_MODE_PULLDOWN) & + ~GPCR_PORT_PIN_MODE_PULLUP; + break; + default: + LOG_ERR("This pull level is not supported."); + return -EINVAL; + } + + /* Setting voltage 3.3V or 1.8V. */ + switch (IT8XXX2_DT_PINCFG_VOLTAGE(pincfg)) { + case IT8XXX2_VOLTAGE_3V3: + /* Input voltage selection 3.3V. */ + *reg_volt_sel &= ~pinctrl_config->volt_sel_mask[pin]; + break; + case IT8XXX2_VOLTAGE_1V8: + __ASSERT(!(IT8XXX2_DT_PINCFG_PUPDR(pincfg) + == IT8XXX2_PULL_UP), + "Don't enable internal pullup if 1.8V voltage is used"); + /* Input voltage selection 1.8V. */ + *reg_volt_sel |= pinctrl_config->volt_sel_mask[pin]; + break; + default: + LOG_ERR("The voltage selection is not supported"); + return -EINVAL; + } + + /* Setting tri-state mode. */ + if (IT8XXX2_DT_PINCFG_IMPEDANCE(pincfg)) { + *reg_gpcr |= (GPCR_PORT_PIN_MODE_PULLUP | + GPCR_PORT_PIN_MODE_PULLDOWN); + } + + return 0; +} + +int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, + uintptr_t reg) +{ + ARG_UNUSED(reg); + + const struct pinctrl_it8xxx2_config *pinctrl_config; + volatile uint8_t *reg_gpcr; + volatile uint8_t *reg_func3_gcr; + volatile uint8_t *reg_func4_gcr; + uint8_t pin; + + for (uint8_t i = 0U; i < pin_cnt; i++) { + pinctrl_config = pins[i].pinctrls->config; + pin = pins[i].pin; + reg_gpcr = (uint8_t *)pinctrl_config->reg_gpcr + pin; + reg_func3_gcr = (uint8_t *)(pinctrl_config->func3_gcr[pin]); + reg_func4_gcr = (uint8_t *)(pinctrl_config->func4_gcr[pin]); + + /* Handle PIN configuration. */ + if (pinctrl_it8xxx2_set(&pins[i])) { + LOG_ERR("Pin configuration is invalid."); + return -EINVAL; + } + + /* + * If pincfg is input, we don't need to handle + * alternate function. + */ + if (IT8XXX2_DT_PINCFG_INPUT(pins[i].pincfg)) { + *reg_gpcr = (*reg_gpcr | GPCR_PORT_PIN_MODE_INPUT) & + ~GPCR_PORT_PIN_MODE_OUTPUT; + continue; + } + + /* + * Handle alternate function. + */ + /* Common settings for alternate function. */ + *reg_gpcr &= ~(GPCR_PORT_PIN_MODE_INPUT | + GPCR_PORT_PIN_MODE_OUTPUT); + switch (pins[i].alt_func) { + case IT8XXX2_ALT_FUNC_1: + /* Func1: Alternate function has been set above. */ + break; + case IT8XXX2_ALT_FUNC_2: + /* Func2: WUI function: turn the pin into an input */ + *reg_gpcr |= GPCR_PORT_PIN_MODE_INPUT; + break; + case IT8XXX2_ALT_FUNC_3: + /* + * Func3: In addition to the alternate setting above, + * Func3 also need to set the general control. + */ + *reg_func3_gcr |= pinctrl_config->func3_en_mask[pin]; + break; + case IT8XXX2_ALT_FUNC_4: + /* + * Func4: In addition to the alternate setting above, + * Func4 also need to set the general control. + */ + *reg_func4_gcr |= pinctrl_config->func4_en_mask[pin]; + break; + case IT8XXX2_ALT_DEFAULT: + *reg_gpcr = (*reg_gpcr | GPCR_PORT_PIN_MODE_INPUT) & + ~GPCR_PORT_PIN_MODE_OUTPUT; + *reg_func3_gcr &= ~pinctrl_config->func3_en_mask[pin]; + *reg_func4_gcr &= ~pinctrl_config->func4_en_mask[pin]; + break; + default: + LOG_ERR("This function is not supported."); + return -EINVAL; + } + + } + + return 0; +} + +static int pinctrl_it8xxx2_init(const struct device *dev) +{ + struct gpio_it8xxx2_regs *const gpio_base = GPIO_IT8XXX2_REG_BASE; + + /* + * The default value of LPCRSTEN is bit2:1 = 10b(GPD2) in GCR. + * If LPC reset is enabled on GPB7, we have to clear bit2:1 + * to 00b. + */ + gpio_base->GPIO_GCR &= ~IT8XXX2_GPIO_LPCRSTEN; + + /* + * TODO: If UART2 swaps from bit2:1 to bit6:5 in H group, we + * have to set UART1PSEL = 1 in UART1PMR register. + */ + + return 0; +} + +#define PINCTRL_ITE_INIT(inst) \ + static const struct pinctrl_it8xxx2_config pinctrl_it8xxx2_cfg_##inst = { \ + .reg_gpcr = (uint8_t *)DT_INST_REG_ADDR(inst), \ + .func3_gcr = DT_INST_PROP(inst, func3_gcr), \ + .func3_en_mask = DT_INST_PROP(inst, func3_en_mask), \ + .func4_gcr = DT_INST_PROP(inst, func4_gcr), \ + .func4_en_mask = DT_INST_PROP(inst, func4_en_mask), \ + .volt_sel = DT_INST_PROP(inst, volt_sel), \ + .volt_sel_mask = DT_INST_PROP(inst, volt_sel_mask), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(inst, &pinctrl_it8xxx2_init, \ + NULL, \ + NULL, \ + &pinctrl_it8xxx2_cfg_##inst, \ + PRE_KERNEL_1, \ + CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \ + NULL); + +DT_INST_FOREACH_STATUS_OKAY(PINCTRL_ITE_INIT) diff --git a/dts/bindings/pinctrl/ite,it8xxx2-pinctrl-func.yaml b/dts/bindings/pinctrl/ite,it8xxx2-pinctrl-func.yaml new file mode 100644 index 00000000000..c00c4c6f63d --- /dev/null +++ b/dts/bindings/pinctrl/ite,it8xxx2-pinctrl-func.yaml @@ -0,0 +1,37 @@ +# Copyright (c) 2022 ITE Corporation. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 + +description: ITE IT8XXX2 pin controller function node + +compatible: "ite,it8xxx2-pinctrl-func" + +include: base.yaml + +properties: + func3-gcr: + type: array + required: true + + func3-en-mask: + type: array + required: true + + func4-gcr: + type: array + required: true + + func4-en-mask: + type: array + required: true + + volt-sel: + type: array + required: true + + volt-sel-mask: + type: array + required: true + +pinmux-cells: + - pin + - alt_func diff --git a/dts/bindings/pinctrl/ite,it8xxx2-pinctrl.yaml b/dts/bindings/pinctrl/ite,it8xxx2-pinctrl.yaml new file mode 100644 index 00000000000..736b98fbe0f --- /dev/null +++ b/dts/bindings/pinctrl/ite,it8xxx2-pinctrl.yaml @@ -0,0 +1,95 @@ +# Copyright (c) 2022 ITE Corporation. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 + +description: | + The ITE IT8XXX2 pin controller is a node responsible for controlling + pin function selection and pin properties. For example, you can + use this node to route UART1 RX and TX setting the alternate + function on the pin. + + The node has the 'pinctrl' node label set in your SoC's devicetree, + so you can modify it like this: + + &pinctrl { + /* your modifications go here */ + }; + + All device pin configurations should be placed in child nodes of the + 'pinctrl' node, as shown in this example: + + /* You can put this in places like a board-pinctrl.dtsi file in + * your board directory, or a devicetree overlay in your application. + */ + + /* include pre-defined pins and functions for the SoC used by the board */ + #include + + &pinctrl { + /* configuration for I2C0 default state */ + i2c0_clk_pb3_default: i2c0_clk_pb3_default { + pinmuxs = <&pinctrlb 3 IT8XXX2_ALT_FUNC_1>; + gpio-voltage = "1p8"; + }; + i2c0_data_pb4_default: i2c0_data_pb4_default { + pinmuxs = <&pinctrlb 4 IT8XXX2_ALT_FUNC_1>; + gpio-voltage = "1v8"; + }; + /* configuration for UART0 default state */ + uart1_rx_pb0_default: uart1_rx_pb0_default { + pinmuxs = <&pinctrlb 0 IT8XXX2_ALT_FUNC_3>; + bias-pull-up; + }; + uart1_tx_pb1_default: uart1_tx_pb1_default { + pinmuxs = <&pinctrlb 1 IT8XXX2_ALT_FUNC_3>; + }; + }; + + The 'uart1_rx_pb0_default' child node encodes the pin configurations + for a particular state of a device; in this case, the default + (that is, active) sate. + + To link pin configurations with a device, use a pinctrl-N property for some + number N, like this example you could place in your board's DTS file: + + #include "board-pinctrl.dtsi" + + &uart0 { + pinctrl-0 = <&uart1_rx_pb0_default &uart1_tx_pb1_default>; + pinctrl-1 = <&uart1_rx_pb0_sleep &uart1_tx_pb1_sleep>; + pinctrl-names = "default", "sleep"; + }; + +compatible: "ite,it8xxx2-pinctrl" + +include: + - name: base.yaml + - name: pincfg-node.yaml + child-binding: + property-allowlist: + - bias-high-impedance + - bias-pull-pin-default + - bias-pull-up + - bias-pull-down + - input-enable + +child-binding: + description: | + This binding gives a base representation of the ITE IT8XXX2 pins configration. + properties: + pinmuxs: + required: true + type: phandle-array + description: | + ITE IT8XXX2 pin's configuration (pinctrl node, pin and function). + + gpio-voltage: + required: false + type: string + description: | + Pin input voltage selection 3.3V or 1.8V. All gpio pins support 3.3V. + This property only needs to be configured if the board specifies a + pin as 1.8V. So the default is 3.3V + default: "3v3" + enum: + - "3v3" + - "1v8" diff --git a/dts/riscv/it8xxx2.dtsi b/dts/riscv/it8xxx2.dtsi index e6036c65cb9..7a417387e18 100644 --- a/dts/riscv/it8xxx2.dtsi +++ b/dts/riscv/it8xxx2.dtsi @@ -69,6 +69,262 @@ write-block-size = <4>; }; }; + + pinctrl: pin-controller { + compatible = "ite,it8xxx2-pinctrl"; + #address-cells = <1>; + #size-cells = <1>; + status = "okay"; + label = "PINCTRL"; + + pinctrla: pinctrl@f01610 { + compatible = "ite,it8xxx2-pinctrl-func"; + reg = <0x00f01610 8>; /* GPCR */ + label = "PINCTRLA"; + func3-gcr = ; + func3-en-mask = <0 0 0 0 + 0x02 0x02 0x10 0x0C >; + func4-gcr = ; + func4-en-mask = <0 0 0 0 + 0 0 0 0 >; + volt-sel = ; + volt-sel-mask = <0 0 0 0 + 0x1 0x02 0x20 0x40 >; + #pinmux-cells = <2>; + }; + + pinctrlb: pinctrl@f01618 { + compatible = "ite,it8xxx2-pinctrl-func"; + reg = <0x00f01618 8>; /* GPCR */ + label = "PINCTRLB"; + func3-gcr = <0xf016f5 0xf016f5 NO_FUNC NO_FUNC + NO_FUNC NO_FUNC NO_FUNC 0xf01600>; + func3-en-mask = <0x01 0x02 0 0 + 0 0 0 0x02 >; + func4-gcr = ; + func4-en-mask = <0 0 0 0 + 0 0 0 0x40 >; + volt-sel = ; + volt-sel-mask = <0 0 0 0x02 + 0x01 0x80 0x40 0x10 >; + #pinmux-cells = <2>; + }; + + pinctrlc: pinctrl@f01620 { + compatible = "ite,it8xxx2-pinctrl-func"; + reg = <0x00f01620 8>; /* GPCR */ + label = "PINCTRLC"; + func3-gcr = ; + func3-en-mask = <0 0 0 0x10 + 0 0x10 0 0x02 >; + func4-gcr = ; + func4-en-mask = <0 0 0 0 + 0 0 0 0x80 >; + volt-sel = <0xf016e7 0xf016e4 0xf016e4 NO_FUNC + 0xf016e9 NO_FUNC 0xf016e9 0xf016e4>; + volt-sel-mask = <0x80 0x20 0x10 0 + 0x04 0 0x08 0x08 >; + #pinmux-cells = <2>; + }; + + pinctrld: pinctrl@f01628 { + compatible = "ite,it8xxx2-pinctrl-func"; + reg = <0x00f01628 8>; /* GPCR */ + label = "PINCTRLD"; + func3-gcr = ; + func3-en-mask = <0 0 0 0 + 0 0x02 0 0 >; + func4-gcr = ; + func4-en-mask = <0 0 0 0 + 0 0 0 0 >; + volt-sel = <0xf016e4 0xf016e4 0xf016e4 0xf016e5 + 0xf016e5 0xf016e7 0xf016e7 0xf016e7>; + volt-sel-mask = <0x04 0x02 0x01 0x80 + 0x40 0x10 0x20 0x40 >; + #pinmux-cells = <2>; + }; + + pinctrle: pinctrl@f01630 { + compatible = "ite,it8xxx2-pinctrl-func"; + reg = <0x00f01630 8>; /* GPCR */ + label = "PINCTRLE"; + func3-gcr = <0xf02032 NO_FUNC NO_FUNC NO_FUNC + NO_FUNC 0xf016f0 NO_FUNC 0xf02032>; + func3-en-mask = <0x01 0 0 0 + 0 0x08 0 0x01 >; + func4-gcr = <0xf016f3 NO_FUNC NO_FUNC NO_FUNC + NO_FUNC NO_FUNC NO_FUNC NO_FUNC >; + func4-en-mask = <0x01 0 0 0 + 0 0 0 0 >; + volt-sel = <0xf016e5 0xf016d4 0xf016d4 NO_FUNC + 0xf016e7 0xf016e7 0xf016e5 0xf016e5>; + volt-sel-mask = <0x20 0x40 0x80 0 + 0x04 0x08 0x10 0x08 >; + #pinmux-cells = <2>; + }; + + pinctrlf: pinctrl@f01638 { + compatible = "ite,it8xxx2-pinctrl-func"; + reg = <0x00f01638 8>; /* GPCR */ + label = "PINCTRLF"; + func3-gcr = ; + func3-en-mask = <0 0 0x02 0x02 + 0 0 0x10 0x10 >; + func4-gcr = ; + func4-en-mask = <0 0 0x40 0x40 + 0 0 0 0 >; + volt-sel = <0xf016d4 0xf016d4 0xf016e5 0xf016e5 + 0xf016e5 0xf016e6 0xf016e6 0xf016e6>; + volt-sel-mask = <0x10 0x20 0x04 0x02 + 0x01 0x80 0x40 0x20 >; + #pinmux-cells = <2>; + }; + + pinctrlg: pinctrl@f01640 { + compatible = "ite,it8xxx2-pinctrl-func"; + reg = <0x00f01640 8>; /* GPCR */ + label = "PINCTRLG"; + func3-gcr = <0xf016f0 0xf016f0 0xf016f0 NO_FUNC + NO_FUNC NO_FUNC 0xf016f0 NO_FUNC>; + func3-en-mask = <0x20 0x08 0x10 0 + 0 0 0x02 0 >; + func4-gcr = ; + func4-en-mask = <0 0 0 0 + 0 0 0 0 >; + volt-sel = <0xf016d4 0xf016e6 0xf016d4 NO_FUNC + NO_FUNC NO_FUNC 0xf016e6 NO_FUNC>; + volt-sel-mask = <0x04 0x10 0x08 0 + 0 0 0x08 0 >; + #pinmux-cells = <2>; + }; + + pinctrlh: pinctrl@f01648 { + compatible = "ite,it8xxx2-pinctrl-func"; + reg = <0x00f01648 8>; /* GPCR */ + label = "PINCTRLH"; + func3-gcr = ; + func3-en-mask = <0 0x20 0x20 0 + 0 0x04 0x08 0 >; + func4-gcr = ; + func4-en-mask = <0 0x04 0x08 0 + 0 0 0 0 >; + volt-sel = <0xf016e6 0xf016e6 0xf016e6 NO_FUNC + NO_FUNC 0xf016d3 0xf016d4 NO_FUNC>; + volt-sel-mask = <0x04 0x02 0x01 0 + 0 0x80 0x01 0 >; + #pinmux-cells = <2>; + }; + + pinctrli: pinctrl@f01650 { + compatible = "ite,it8xxx2-pinctrl-func"; + reg = <0x00f01650 8>; /* GPCR */ + label = "PINCTRLI"; + func3-gcr = ; + func3-en-mask = <0 0 0 0 + 0 0x08 0x08 0x08 >; + func4-gcr = ; + func4-en-mask = <0 0 0 0 + 0 0 0 0 >; + volt-sel = <0xf016d3 0xf016e8 0xf016e8 0xf016e8 + 0xf016e8 0xf016d3 0xf016d3 0xf016d3>; + volt-sel-mask = <0x08 0x10 0x20 0x40 + 0x80 0x10 0x20 0x40 >; + #pinmux-cells = <2>; + }; + + pinctrlj: pinctrl@f01658 { + compatible = "ite,it8xxx2-pinctrl-func"; + reg = <0x00f01658 8>; /* GPCR */ + label = "PINCTRLJ"; + func3-gcr = <0xf016f4 NO_FUNC 0xf016f4 0xf016f4 + 0xf016f0 0xf016f0 NO_FUNC NO_FUNC>; + func3-en-mask = <0x01 0 0x01 0x02 + 0x02 0x03 0 0 >; + func4-gcr = ; + func4-en-mask = <0 0 0 0 + 0 0 0 0 >; + volt-sel = <0xf016e8 0xf016e8 0xf016e8 0xf016e8 + 0xf016d3 0xf016d3 0xf016d3 0xf016d7>; + volt-sel-mask = <0x01 0x02 0x04 0x08 + 0x01 0x02 0x04 0x04 >; + #pinmux-cells = <2>; + }; + + pinctrlk: pinctrl@f01690 { + compatible = "ite,it8xxx2-pinctrl-func"; + reg = <0x00f01690 8>; /* GPCR */ + label = "PINCTRLK"; + func3-gcr = ; + func3-en-mask = <0 0 0 0 + 0 0 0 0 >; + func4-gcr = ; + func4-en-mask = <0 0 0 0 + 0 0 0 0 >; + volt-sel = <0xf016d2 0xf016d2 0xf016d2 0xf016d2 + 0xf016d2 0xf016d2 0xf016d2 0xf016d2>; + volt-sel-mask = <0x01 0x02 0x04 0x08 + 0x10 0x20 0x40 0x80 >; + #pinmux-cells = <2>; + }; + + pinctrll: pinctrl@f01698 { + compatible = "ite,it8xxx2-pinctrl-func"; + reg = <0x00f01698 8>; /* GPCR */ + label = "PINCTRLL"; + func3-gcr = ; + func3-en-mask = <0 0 0 0 + 0 0 0 0 >; + func4-gcr = ; + func4-en-mask = <0 0 0 0 + 0 0 0 0 >; + volt-sel = <0xf016d1 0xf016d1 0xf016d1 0xf016d1 + 0xf016d1 0xf016d1 0xf016d1 0xf016d1>; + volt-sel-mask = <0x01 0x02 0x04 0x08 + 0x10 0x20 0x40 0x80 >; + #pinmux-cells = <2>; + }; + + pinctrlm: pinctrl@f016a0 { + compatible = "ite,it8xxx2-pinctrl-func"; + reg = <0x00f016a0 8>; /* GPCR */ + label = "PINCTRLM"; + func3-gcr = ; + func3-en-mask = <0 0 0 0 + 0 0 0 0 >; + func4-gcr = ; + func4-en-mask = <0 0 0 0 + 0 0 0 0 >; + volt-sel = <0xf016ed 0xf016ed 0xf016ed 0xf016ed + 0xf016ed 0xf016ed 0xf016ed NO_FUNC >; + volt-sel-mask = <0x10 0x10 0x10 0x10 + 0x10 0x10 0x10 0 >; + #pinmux-cells = <2>; + }; + }; + pinmuxa: pinmux@f01610 { compatible = "ite,it8xxx2-pinmux"; reg = <0x00f01610 0x0008>; @@ -485,6 +741,12 @@ interrupt-parent = <&intc>; }; + gpiogcr: gpio-gcr@f01600 { + compatible = "ite,it8xxx2-gpiogcr"; + reg = <0x00f01600 0x100>; + label = "GPIO_GCR"; + }; + gpioa: gpio@f01601 { compatible = "ite,it8xxx2-gpio"; reg = <0x00f01601 1 /* GPDR (set) */ diff --git a/include/zephyr/dt-bindings/pinctrl/it8xxx2-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/it8xxx2-pinctrl.h index 9f099b9c1ef..39f4531ac4f 100644 --- a/include/zephyr/dt-bindings/pinctrl/it8xxx2-pinctrl.h +++ b/include/zephyr/dt-bindings/pinctrl/it8xxx2-pinctrl.h @@ -15,4 +15,13 @@ #define IT8XXX2_PINMUX_FUNC_4 3 #define IT8XXX2_PINMUX_PINS 8 +/** + * @brief PIN alternate function. + */ +#define IT8XXX2_ALT_FUNC_1 0U +#define IT8XXX2_ALT_FUNC_2 1U +#define IT8XXX2_ALT_FUNC_3 2U +#define IT8XXX2_ALT_FUNC_4 3U +#define IT8XXX2_ALT_DEFAULT 4U + #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_IT8XXX2_PINCTRL_H_ */ diff --git a/soc/riscv/riscv-ite/common/check_regs.c b/soc/riscv/riscv-ite/common/check_regs.c index 32ed216e2f2..3737a2a01b5 100644 --- a/soc/riscv/riscv-ite/common/check_regs.c +++ b/soc/riscv/riscv-ite/common/check_regs.c @@ -86,6 +86,17 @@ IT8XXX2_REG_SIZE_CHECK(espi_queue1_regs, 0xc0); IT8XXX2_REG_OFFSET_CHECK(espi_queue1_regs, UPSTREAM_DATA, 0x00); IT8XXX2_REG_OFFSET_CHECK(espi_queue1_regs, PUT_FLASH_NP_DATA, 0x80); +/* GPIO register structure check */ +IT8XXX2_REG_SIZE_CHECK(gpio_it8xxx2_regs, 0x100); +IT8XXX2_REG_OFFSET_CHECK(gpio_it8xxx2_regs, GPIO_GCR, 0x00); +IT8XXX2_REG_OFFSET_CHECK(gpio_it8xxx2_regs, GPIO_GCR31, 0xD5); +IT8XXX2_REG_OFFSET_CHECK(gpio_it8xxx2_regs, GPIO_GCR18, 0xE2); +IT8XXX2_REG_OFFSET_CHECK(gpio_it8xxx2_regs, GPIO_GCR21, 0xE6); +IT8XXX2_REG_OFFSET_CHECK(gpio_it8xxx2_regs, GPIO_GCR29, 0xEE); +IT8XXX2_REG_OFFSET_CHECK(gpio_it8xxx2_regs, GPIO_GCR2, 0xF1); +IT8XXX2_REG_OFFSET_CHECK(gpio_it8xxx2_regs, GPIO_GCR7, 0xF6); +IT8XXX2_REG_OFFSET_CHECK(gpio_it8xxx2_regs, GPIO_GCR14, 0xFD); + /* GCTRL register structure check */ IT8XXX2_REG_SIZE_CHECK(gctrl_it8xxx2_regs, 0x88); IT8XXX2_REG_OFFSET_CHECK(gctrl_it8xxx2_regs, GCTRL_RSTS, 0x06); diff --git a/soc/riscv/riscv-ite/common/chip_chipregs.h b/soc/riscv/riscv-ite/common/chip_chipregs.h index 0a854b13bfb..a29d4084b26 100644 --- a/soc/riscv/riscv-ite/common/chip_chipregs.h +++ b/soc/riscv/riscv-ite/common/chip_chipregs.h @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2020 ITE Corporation. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0 */ @@ -1444,6 +1444,101 @@ struct flash_it8xxx2_regs { #define IT8XXX2_GPIO_GPCRP0 ECREG(IT8XXX2_GPIO2_BASE + 0x18) #define IT8XXX2_GPIO_GPCRP1 ECREG(IT8XXX2_GPIO2_BASE + 0x19) +/** + * + * (16xxh) General Purpose I/O Port (GPIO) registers + * + */ +#ifndef __ASSEMBLER__ +struct gpio_it8xxx2_regs { + /* 0x00: General Control */ + volatile uint8_t GPIO_GCR; + /* 0x01-D0: Reserved1 */ + volatile uint8_t reserved1[208]; + /* 0xD1: General Control 25 */ + volatile uint8_t GPIO_GCR25; + /* 0xD2: General Control 26 */ + volatile uint8_t GPIO_GCR26; + /* 0xD3: General Control 27 */ + volatile uint8_t GPIO_GCR27; + /* 0xD4: General Control 28 */ + volatile uint8_t GPIO_GCR28; + /* 0xD5: General Control 31 */ + volatile uint8_t GPIO_GCR31; + /* 0xD6: General Control 32 */ + volatile uint8_t GPIO_GCR32; + /* 0xD7: General Control 33 */ + volatile uint8_t GPIO_GCR33; + /* 0xD8-0xDF: Reserved2 */ + volatile uint8_t reserved2[8]; + /* 0xE0: General Control 16 */ + volatile uint8_t GPIO_GCR16; + /* 0xE1: General Control 17 */ + volatile uint8_t GPIO_GCR17; + /* 0xE2: General Control 18 */ + volatile uint8_t GPIO_GCR18; + /* 0xE3: Reserved3 */ + volatile uint8_t reserved3; + /* 0xE4: General Control 19 */ + volatile uint8_t GPIO_GCR19; + /* 0xE5: General Control 20 */ + volatile uint8_t GPIO_GCR20; + /* 0xE6: General Control 21 */ + volatile uint8_t GPIO_GCR21; + /* 0xE7: General Control 22 */ + volatile uint8_t GPIO_GCR22; + /* 0xE8: General Control 23 */ + volatile uint8_t GPIO_GCR23; + /* 0xE9: General Control 24 */ + volatile uint8_t GPIO_GCR24; + /* 0xEA-0xEC: Reserved4 */ + volatile uint8_t reserved4[3]; + /* 0xED: General Control 30 */ + volatile uint8_t GPIO_GCR30; + /* 0xEE: General Control 29 */ + volatile uint8_t GPIO_GCR29; + /* 0xEF: Reserved5 */ + volatile uint8_t reserved5; + /* 0xF0: General Control 1 */ + volatile uint8_t GPIO_GCR1; + /* 0xF1: General Control 2 */ + volatile uint8_t GPIO_GCR2; + /* 0xF2: General Control 3 */ + volatile uint8_t GPIO_GCR3; + /* 0xF3: General Control 4 */ + volatile uint8_t GPIO_GCR4; + /* 0xF4: General Control 5 */ + volatile uint8_t GPIO_GCR5; + /* 0xF5: General Control 6 */ + volatile uint8_t GPIO_GCR6; + /* 0xF6: General Control 7 */ + volatile uint8_t GPIO_GCR7; + /* 0xF7: General Control 8 */ + volatile uint8_t GPIO_GCR8; + /* 0xF8: General Control 9 */ + volatile uint8_t GPIO_GCR9; + /* 0xF9: General Control 10 */ + volatile uint8_t GPIO_GCR10; + /* 0xFA: General Control 11 */ + volatile uint8_t GPIO_GCR11; + /* 0xFB: General Control 12 */ + volatile uint8_t GPIO_GCR12; + /* 0xFC: General Control 13 */ + volatile uint8_t GPIO_GCR13; + /* 0xFD: General Control 14 */ + volatile uint8_t GPIO_GCR14; + /* 0xFE: General Control 15 */ + volatile uint8_t GPIO_GCR15; + /* 0xFF: Power Good Watch Control */ + volatile uint8_t GPIO_PGWCR; +}; +#endif /* !__ASSEMBLER__ */ + +/* GPIO register fields */ +/* 0x00: General Control */ +#define IT8XXX2_GPIO_LPCRSTEN (BIT(2) | BIT(1)) + + /** * * (19xxh) Analog to Digital Converter (ADC) registers diff --git a/soc/riscv/riscv-ite/common/pinctrl_soc.h b/soc/riscv/riscv-ite/common/pinctrl_soc.h new file mode 100644 index 00000000000..150d43dfcc2 --- /dev/null +++ b/soc/riscv/riscv-ite/common/pinctrl_soc.h @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2022 ITE Technology Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_SOC_RISCV_ITE_IT8XXX2_COMMON_PINCTRL_SOC_H_ +#define ZEPHYR_SOC_RISCV_ITE_IT8XXX2_COMMON_PINCTRL_SOC_H_ + +#include +#include +#include + +/** + * @brief ITE IT8XXX2 pin type. + */ +struct pinctrl_soc_pin { + /* Pinmux control group */ + const struct device *pinctrls; + /* Pin configuration (impedance, pullup/down, voltate selection, input). */ + uint32_t pincfg; + /* GPIO pin */ + uint8_t pin; + /* Alternate function */ + uint8_t alt_func; +}; + +typedef struct pinctrl_soc_pin pinctrl_soc_pin_t; + +/** + * @brief PIN configuration bitfield. + * + * Pin configuration is coded with the following + * fields. + * Pin impedance config [ 0 ] + * Pin pull-up/down config [ 4 : 5 ] + * Pin voltage selection [ 8 ] + * Pin input enable config [ 12 ] + */ +#define IT8XXX2_HIGH_IMPEDANCE 0x1U +#define IT8XXX2_PULL_PIN_DEFAULT 0x0U +#define IT8XXX2_PULL_UP 0x1U +#define IT8XXX2_PULL_DOWN 0x2U +#define IT8XXX2_VOLTAGE_3V3 0x0U +#define IT8XXX2_VOLTAGE_1V8 0x1U +#define IT8XXX2_INPUT_ENABLE 0x1U + +/* Pin tri-state mode. */ +#define IT8XXX2_IMPEDANCE_SHIFT 0U +#define IT8XXX2_IMPEDANCE_MASK 0x1U +/* Pin pull-up or pull-down */ +#define IT8XXX2_PUPDR_SHIFT 4U +#define IT8XXX2_PUPDR_MASK 0x3U +/* Pin 3.3V or 1.8V */ +#define IT8XXX2_VOLTAGE_SHIFT 8U +#define IT8XXX2_VOLTAGE_MASK 0x1U +/* Pin INPUT enable or disable */ +#define IT8XXX2_INPUT_SHIFT 12U +#define IT8XXX2_INPUT_MASK 0x1U + +/** + * @brief Utility macro to obtain configuration of tri-state. + */ +#define IT8XXX2_DT_PINCFG_IMPEDANCE(__mode) \ + (((__mode) >> IT8XXX2_IMPEDANCE_SHIFT) & IT8XXX2_IMPEDANCE_MASK) + +/** + * @brief Utility macro to obtain configuration of pull-up or pull-down. + */ +#define IT8XXX2_DT_PINCFG_PUPDR(__mode) \ + (((__mode) >> IT8XXX2_PUPDR_SHIFT) & IT8XXX2_PUPDR_MASK) + +/** + * @brief Utility macro to obtain input voltage selection. + */ +#define IT8XXX2_DT_PINCFG_VOLTAGE(__mode) \ + (((__mode) >> IT8XXX2_VOLTAGE_SHIFT) & IT8XXX2_VOLTAGE_MASK) + +/** + * @brief Utility macro to obtain input enable. + */ +#define IT8XXX2_DT_PINCFG_INPUT(__mode) \ + (((__mode) >> IT8XXX2_INPUT_SHIFT) & IT8XXX2_INPUT_MASK) + +/** + * @brief Utility macro to initialize pincfg field in #pinctrl_pin_t. + * + * @param node_id Node identifier. + */ +#define Z_PINCTRL_IT8XXX2_PINCFG_INIT(node_id) \ + (((IT8XXX2_HIGH_IMPEDANCE * DT_PROP(node_id, bias_high_impedance)) \ + << IT8XXX2_IMPEDANCE_SHIFT) | \ + ((IT8XXX2_PULL_PIN_DEFAULT * DT_PROP(node_id, bias_pull_pin_default)) \ + << IT8XXX2_PUPDR_SHIFT) | \ + ((IT8XXX2_PULL_UP * DT_PROP(node_id, bias_pull_up)) \ + << IT8XXX2_PUPDR_SHIFT) | \ + ((IT8XXX2_PULL_DOWN * DT_PROP(node_id, bias_pull_down)) \ + << IT8XXX2_PUPDR_SHIFT) | \ + ((IT8XXX2_VOLTAGE_1V8 * DT_ENUM_IDX(node_id, gpio_voltage)) \ + << IT8XXX2_VOLTAGE_SHIFT) | \ + ((IT8XXX2_INPUT_ENABLE * DT_PROP(node_id, input_enable)) \ + << IT8XXX2_INPUT_SHIFT)) + +/** + * @brief Utility macro to initialize pinctrls of pinmuxs field in #pinctrl_pin_t. + * + * @param node_id Node identifier. + */ +#define Z_PINCTRL_IT8XXX2_PINCTRL_INIT(node_id) \ + DEVICE_DT_GET(DT_PHANDLE(node_id, pinmuxs)) +/** + * @brief Utility macro to initialize pin of pinmuxs field in #pinctrl_pin_t. + * + * @param node_id Node identifier. + */ +#define Z_PINCTRL_IT8XXX2_PIN_INIT(node_id) \ + DT_PHA(node_id, pinmuxs, pin) +/** + * @brief Utility macro to initialize alt_func of pinmuxs field in #pinctrl_pin_t. + * + * @param node_id Node identifier. + */ +#define Z_PINCTRL_IT8XXX2_ALT_INIT(node_id) \ + DT_PHA(node_id, pinmuxs, alt_func) + +/** + * @brief Utility macro to initialize each pin. + * + * @param node_id Node identifier. + * @param prop Property name. + * @param idx Property entry index. + */ +#define Z_PINCTRL_STATE_PIN_INIT(node_id, prop, idx) \ + { .pinctrls = Z_PINCTRL_IT8XXX2_PINCTRL_INIT( \ + DT_PROP_BY_IDX(node_id, prop, idx)), \ + .pincfg = Z_PINCTRL_IT8XXX2_PINCFG_INIT( \ + DT_PROP_BY_IDX(node_id, prop, idx)), \ + .pin = Z_PINCTRL_IT8XXX2_PIN_INIT( \ + DT_PROP_BY_IDX(node_id, prop, idx)), \ + .alt_func = Z_PINCTRL_IT8XXX2_ALT_INIT( \ + DT_PROP_BY_IDX(node_id, prop, idx)), }, + +/** + * @brief Utility macro to initialize state pins contained in a given property. + * + * @param node_id Node identifier. + * @param prop Property name describing state pins. + */ +#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \ + {DT_FOREACH_PROP_ELEM(node_id, prop, Z_PINCTRL_STATE_PIN_INIT)} + +#endif /* ZEPHYR_SOC_RISCV_ITE_IT8XXX2_COMMON_PINCTRL_SOC_H_ */ diff --git a/soc/riscv/riscv-ite/it8xxx2/Kconfig.defconfig.series b/soc/riscv/riscv-ite/it8xxx2/Kconfig.defconfig.series index 03f62286a9c..9aa04f38b43 100644 --- a/soc/riscv/riscv-ite/it8xxx2/Kconfig.defconfig.series +++ b/soc/riscv/riscv-ite/it8xxx2/Kconfig.defconfig.series @@ -88,6 +88,9 @@ config PECI_ITE_IT8XXX2 depends on PECI select PECI_INTERRUPT_DRIVEN +config PINCTRL + default y + if ITE_IT8XXX2_INTC config NUM_IRQS default 185