From bff69f538481a76638d295fcb683679c0a894840 Mon Sep 17 00:00:00 2001 From: Wojciech Sipak Date: Thu, 6 Jul 2023 12:17:46 +0200 Subject: [PATCH] drivers: pinctrl: add driver for EOS S3 This adds a new pinctrl driver for Quicklogic EOS S3 SoC Signed-off-by: Wojciech Sipak --- drivers/pinctrl/CMakeLists.txt | 1 + drivers/pinctrl/Kconfig | 1 + drivers/pinctrl/Kconfig.eos_s3 | 9 ++ drivers/pinctrl/pinctrl_eos_s3.c | 128 ++++++++++++++++++ drivers/serial/Kconfig.pl011 | 1 + drivers/serial/Kconfig.ql_usbserialport_s3b | 1 + dts/arm/quicklogic/quicklogic_eos_s3.dtsi | 5 + .../pinctrl/quicklogic,eos-s3-pinctrl.yaml | 75 ++++++++++ .../pinctrl/quicklogic-eos-s3-pinctrl.h | 25 ++++ soc/arm/quicklogic_eos_s3/pinctrl_soc.h | 55 ++++++++ 10 files changed, 301 insertions(+) create mode 100644 drivers/pinctrl/Kconfig.eos_s3 create mode 100644 drivers/pinctrl/pinctrl_eos_s3.c create mode 100644 dts/bindings/pinctrl/quicklogic,eos-s3-pinctrl.yaml create mode 100644 include/zephyr/dt-bindings/pinctrl/quicklogic-eos-s3-pinctrl.h create mode 100644 soc/arm/quicklogic_eos_s3/pinctrl_soc.h diff --git a/drivers/pinctrl/CMakeLists.txt b/drivers/pinctrl/CMakeLists.txt index 521f1e61c19..a14ee14286e 100644 --- a/drivers/pinctrl/CMakeLists.txt +++ b/drivers/pinctrl/CMakeLists.txt @@ -33,3 +33,4 @@ zephyr_library_sources_ifdef(CONFIG_PINCTRL_TI_K3 pinctrl_ti_k3.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_EMSDP pinctrl_emsdp.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_TI_CC32XX pinctrl_ti_cc32xx.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_NUMAKER pinctrl_numaker.c) +zephyr_library_sources_ifdef(CONFIG_PINCTRL_QUICKLOGIC_EOS_S3 pinctrl_eos_s3.c) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 80551869d59..cdecc3ae554 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -62,5 +62,6 @@ source "drivers/pinctrl/Kconfig.ti_k3" source "drivers/pinctrl/Kconfig.emsdp" source "drivers/pinctrl/Kconfig.ti_cc32xx" source "drivers/pinctrl/Kconfig.numaker" +source "drivers/pinctrl/Kconfig.eos_s3" endif # PINCTRL diff --git a/drivers/pinctrl/Kconfig.eos_s3 b/drivers/pinctrl/Kconfig.eos_s3 new file mode 100644 index 00000000000..04d8cd1cbe1 --- /dev/null +++ b/drivers/pinctrl/Kconfig.eos_s3 @@ -0,0 +1,9 @@ +# Copyright (c) 2023 Antmicro +# SPDX-License-Identifier: Apache-2.0 + +config PINCTRL_QUICKLOGIC_EOS_S3 + bool "QuickLogic EOS S3 SoC pinctrl driver" + default y + depends on DT_HAS_QUICKLOGIC_EOS_S3_PINCTRL_ENABLED + help + Enable driver for the QuickLogic EOS S3 SoC pinctrl driver diff --git a/drivers/pinctrl/pinctrl_eos_s3.c b/drivers/pinctrl/pinctrl_eos_s3.c new file mode 100644 index 00000000000..5fcd62711da --- /dev/null +++ b/drivers/pinctrl/pinctrl_eos_s3.c @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2023 Antmicro + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT quicklogic_eos_s3_pinctrl + +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(pinctrl_eos_s3, CONFIG_PINCTRL_LOG_LEVEL); + +#define FUNCTION_REGISTER(func) (func >> 13) +#define PAD_FUNC_SEL_MASK GENMASK(2, 0) +#define PAD_CTRL_SEL_BIT0 3 +#define PAD_CTRL_SEL_BIT1 4 +#define PAD_OUTPUT_EN_BIT 5 +#define PAD_PULL_UP_BIT 6 +#define PAD_PULL_DOWN_BIT 7 +#define PAD_DRIVE_STRENGTH_BIT0 8 +#define PAD_DRIVE_STRENGTH_BIT1 9 +#define PAD_SLEW_RATE_BIT 10 +#define PAD_INPUT_EN_BIT 11 +#define PAD_SCHMITT_EN_BIT 12 + +/* + * Program IOMUX_func_SEL register. + */ +static int pinctrl_eos_s3_input_selection(uint32_t pin, uint32_t sel_reg) +{ + volatile uint32_t *reg = (uint32_t *)IO_MUX_BASE; + + if (sel_reg <= IO_MUX_MAX_PAD_NR || sel_reg > IO_MUX_REG_MAX_OFFSET) { + return -EINVAL; + } + reg += sel_reg; + *reg = pin; + + return 0; +} + +/* + * Program IOMUX_PAD_x_CTRL register. + */ +static int pinctrl_eos_s3_set(uint32_t pin, uint32_t func) +{ + volatile uint32_t *reg = (uint32_t *)IO_MUX_BASE; + + if (pin > IO_MUX_REG_MAX_OFFSET) { + return -EINVAL; + } + reg += pin; + *reg = func; + + return 0; +} + +static int pinctrl_eos_s3_configure_pin(const pinctrl_soc_pin_t *pin) +{ + uint32_t reg_value = 0; + + /* Set function. */ + reg_value |= (pin->iof & PAD_FUNC_SEL_MASK); + + /* Output enable is active low. */ + WRITE_BIT(reg_value, PAD_OUTPUT_EN_BIT, pin->output_enable ? 0 : 1); + + /* These are active high. */ + WRITE_BIT(reg_value, PAD_INPUT_EN_BIT, pin->input_enable); + WRITE_BIT(reg_value, PAD_SLEW_RATE_BIT, pin->slew_rate); + WRITE_BIT(reg_value, PAD_SCHMITT_EN_BIT, pin->schmitt_enable); + WRITE_BIT(reg_value, PAD_CTRL_SEL_BIT0, pin->control_selection & BIT(0)); + WRITE_BIT(reg_value, PAD_CTRL_SEL_BIT1, pin->control_selection & BIT(1)); + + switch (pin->drive_strength) { + case 2: + WRITE_BIT(reg_value, PAD_DRIVE_STRENGTH_BIT0, 0); + WRITE_BIT(reg_value, PAD_DRIVE_STRENGTH_BIT1, 0); + break; + case 4: + WRITE_BIT(reg_value, PAD_DRIVE_STRENGTH_BIT0, 1); + WRITE_BIT(reg_value, PAD_DRIVE_STRENGTH_BIT1, 0); + break; + case 8: + WRITE_BIT(reg_value, PAD_DRIVE_STRENGTH_BIT0, 0); + WRITE_BIT(reg_value, PAD_DRIVE_STRENGTH_BIT1, 1); + break; + case 12: + WRITE_BIT(reg_value, PAD_DRIVE_STRENGTH_BIT0, 1); + WRITE_BIT(reg_value, PAD_DRIVE_STRENGTH_BIT1, 1); + break; + default: + LOG_ERR("Selected drive-strength is not supported: %d\n", pin->drive_strength); + } + + /* Enable pull-up by default; overwrite if any setting was chosen. */ + WRITE_BIT(reg_value, PAD_PULL_UP_BIT, 1); + WRITE_BIT(reg_value, PAD_PULL_DOWN_BIT, 0); + if (pin->high_impedance) { + WRITE_BIT(reg_value, PAD_PULL_UP_BIT, 0); + } else if (pin->pull_up | pin->pull_down) { + WRITE_BIT(reg_value, PAD_PULL_UP_BIT, pin->pull_up); + WRITE_BIT(reg_value, PAD_PULL_DOWN_BIT, pin->pull_down); + } + + /* Program registers. */ + pinctrl_eos_s3_set(pin->pin, reg_value); + if (pin->input_enable && FUNCTION_REGISTER(pin->iof)) { + pinctrl_eos_s3_input_selection(pin->pin, FUNCTION_REGISTER(pin->iof)); + } + return 0; +} + +int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintptr_t reg) +{ + ARG_UNUSED(reg); + + for (int i = 0; i < pin_cnt; i++) { + pinctrl_eos_s3_configure_pin(&pins[i]); + } + + return 0; +} diff --git a/drivers/serial/Kconfig.pl011 b/drivers/serial/Kconfig.pl011 index 9c48001835a..95dd947b9dc 100644 --- a/drivers/serial/Kconfig.pl011 +++ b/drivers/serial/Kconfig.pl011 @@ -7,6 +7,7 @@ menuconfig UART_PL011 depends on DT_HAS_ARM_PL011_ENABLED || DT_HAS_ARM_SBSA_UART_ENABLED select SERIAL_HAS_DRIVER select SERIAL_SUPPORT_INTERRUPT + select PINCTRL if SOC_EOS_S3 help This option enables the UART driver for the PL011 diff --git a/drivers/serial/Kconfig.ql_usbserialport_s3b b/drivers/serial/Kconfig.ql_usbserialport_s3b index 197d26f5faf..b989c91516e 100644 --- a/drivers/serial/Kconfig.ql_usbserialport_s3b +++ b/drivers/serial/Kconfig.ql_usbserialport_s3b @@ -8,5 +8,6 @@ config UART_QUICKLOGIC_USBSERIALPORT_S3B default y depends on DT_HAS_QUICKLOGIC_USBSERIALPORT_S3B_ENABLED select SERIAL_HAS_DRIVER + select PINCTRL help This option enables the QuickLogic USBserialport_S3B serial driver. diff --git a/dts/arm/quicklogic/quicklogic_eos_s3.dtsi b/dts/arm/quicklogic/quicklogic_eos_s3.dtsi index 8d3f3998e30..f29b1c482ff 100644 --- a/dts/arm/quicklogic/quicklogic_eos_s3.dtsi +++ b/dts/arm/quicklogic/quicklogic_eos_s3.dtsi @@ -64,6 +64,11 @@ pin-secondary-config = <0x00>; gpio-controller; }; + + pinctrl: pinctrl@40004c00 { + compatible = "quicklogic,eos-s3-pinctrl"; + reg = <0x40004c00 0x1b0>; + }; }; }; diff --git a/dts/bindings/pinctrl/quicklogic,eos-s3-pinctrl.yaml b/dts/bindings/pinctrl/quicklogic,eos-s3-pinctrl.yaml new file mode 100644 index 00000000000..cd9cd5ac532 --- /dev/null +++ b/dts/bindings/pinctrl/quicklogic,eos-s3-pinctrl.yaml @@ -0,0 +1,75 @@ +# Copyright (c) 2023 Antmicro +# SPDX-License-Identifier: Apache-2.0 + +description: | + Quicklogic EOS S3 IO MUX binding covers the 46 IOMUX_PAD_x_CTRL registers + that can be used to set the direction and the function of a pad. + + Device pin configuration should be placed in the child nodes of this node. + Populate the 'pinmux' field with IO function and pin number. + + For example, setting pins 44 and 45 for use as UART would look like this: + + #include + + &pinctrl { + uart0_rx_default: uart0_rx_default { + pinmux = ; + input-enable; + }; + uart0_tx_default: uart0_tx_default { + pinmux = ; + output-enable; + }; + }; + +compatible: "quicklogic,eos-s3-pinctrl" + +include: base.yaml + +properties: + reg: + required: true + +child-binding: + description: | + This binding gives a base representation of the SiFive FE310 pins + configuration. + + include: + - name: pincfg-node.yaml + property-allowlist: + - input-enable + - output-enable + - bias-pull-up + - bias-pull-down + - bias-high-impedance + - input-schmitt-enable + - drive-strength + properties: + pinmux: + required: true + type: array + description: | + Quicklogic EOS S3 pin's configuration (pin, IO function). + slew-rate: + description: | + The default value "slow" matches the power-on reset value. + default: "slow" + type: string + enum: + - "slow" + - "fast" + quicklogic,control-selection: + description: | + Control selection for IO output. + It's either controlled from registers of the A0 always-on domain, + fabric-controlled for signaling with FPGA, + or other-controller for bidirectional signals. + The default value "a0registers" matches the power-on reset value. + default: "a0registers" + type: string + enum: + - "a0registers" + - "others" + - "fabric" diff --git a/include/zephyr/dt-bindings/pinctrl/quicklogic-eos-s3-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/quicklogic-eos-s3-pinctrl.h new file mode 100644 index 00000000000..b49e2141444 --- /dev/null +++ b/include/zephyr/dt-bindings/pinctrl/quicklogic-eos-s3-pinctrl.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2023 Antmicro + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_QUICKLOGIC_EOS_S3_PINCTRL_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_QUICKLOGIC_EOS_S3_PINCTRL_H_ + +#include + +#define IO_MUX_REG_MAX_OFFSET 107 +#define IO_MUX_MAX_PAD_NR 45 + +#define FUNC_SEL_UART_RX (77 << 13) + +#define QUICKLOGIC_EOS_S3_PINMUX(pin, fun) (pin) (fun) + +#define UART_TX_PAD44 QUICKLOGIC_EOS_S3_PINMUX(44, 0x3) +#define UART_RX_PAD45 QUICKLOGIC_EOS_S3_PINMUX(45, FUNC_SEL_UART_RX | BIT(2)) +#define USB_PU_CTRL_PAD23 QUICKLOGIC_EOS_S3_PINMUX(23, 0x0) +#define USB_DN_PAD28 QUICKLOGIC_EOS_S3_PINMUX(28, 0x0) +#define USB_DP_PAD31 QUICKLOGIC_EOS_S3_PINMUX(31, 0x0) + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_QUICKLOGIC_EOS_S3_PINCTRL_H_ */ diff --git a/soc/arm/quicklogic_eos_s3/pinctrl_soc.h b/soc/arm/quicklogic_eos_s3/pinctrl_soc.h new file mode 100644 index 00000000000..957129a3d0e --- /dev/null +++ b/soc/arm/quicklogic_eos_s3/pinctrl_soc.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2023 Antmicro + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_SOC_ARM_QUICKLOGIC_EOS_S3_PINCTRL_H_ +#define ZEPHYR_SOC_ARM_QUICKLOGIC_EOS_S3_PINCTRL_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct pinctrl_soc_pin_t { + uint32_t pin; + uint32_t iof; + uint32_t input_enable: 1; + uint32_t output_enable: 1; + uint32_t pull_up: 1; + uint32_t pull_down: 1; + uint32_t high_impedance: 1; + uint32_t slew_rate: 2; + uint8_t drive_strength; + uint32_t schmitt_enable: 1; + uint32_t control_selection: 2; +} pinctrl_soc_pin_t; + +#define QUICKLOGIC_EOS_S3_DT_PIN(node_id) \ + { \ + .pin = DT_PROP_BY_IDX(node_id, pinmux, 0), \ + .iof = DT_PROP_BY_IDX(node_id, pinmux, 1), \ + .input_enable = DT_PROP(node_id, input_enable), \ + .output_enable = DT_PROP(node_id, output_enable), \ + .pull_up = DT_PROP(node_id, bias_pull_up), \ + .pull_down = DT_PROP(node_id, bias_pull_down), \ + .high_impedance = DT_PROP(node_id, bias_high_impedance), \ + .slew_rate = DT_ENUM_IDX(node_id, slew_rate), \ + .drive_strength = DT_PROP_OR(node_id, drive_strength, 4), \ + .schmitt_enable = DT_PROP(node_id, input_schmitt_enable), \ + .control_selection = DT_ENUM_IDX(node_id, quicklogic_control_selection), \ + }, + +#define Z_PINCTRL_STATE_PIN_INIT(node_id, prop, idx) \ + QUICKLOGIC_EOS_S3_DT_PIN(DT_PROP_BY_IDX(node_id, prop, idx)) + +#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \ + { DT_FOREACH_PROP_ELEM(node_id, prop, Z_PINCTRL_STATE_PIN_INIT) } + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_SOC_ARM_QUICKLOGIC_EOS_S3_PINCTRL_H_ */