drivers: pinctrl: add driver for EOS S3

This adds a new pinctrl driver for Quicklogic EOS S3 SoC

Signed-off-by: Wojciech Sipak <wsipak@antmicro.com>
This commit is contained in:
Wojciech Sipak 2023-07-06 12:17:46 +02:00 committed by Carles Cufí
parent b51dd4ade0
commit bff69f5384
10 changed files with 301 additions and 0 deletions

View file

@ -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)

View file

@ -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

View file

@ -0,0 +1,9 @@
# Copyright (c) 2023 Antmicro <www.antmicro.com>
# 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

View file

@ -0,0 +1,128 @@
/*
* Copyright (c) 2023 Antmicro <www.antmicro.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
#define DT_DRV_COMPAT quicklogic_eos_s3_pinctrl
#include <zephyr/arch/cpu.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/pinctrl.h>
#include <zephyr/logging/log.h>
#include <zephyr/dt-bindings/pinctrl/quicklogic-eos-s3-pinctrl.h>
#include <soc.h>
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;
}

View file

@ -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

View file

@ -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.

View file

@ -64,6 +64,11 @@
pin-secondary-config = <0x00>;
gpio-controller;
};
pinctrl: pinctrl@40004c00 {
compatible = "quicklogic,eos-s3-pinctrl";
reg = <0x40004c00 0x1b0>;
};
};
};

View file

@ -0,0 +1,75 @@
# Copyright (c) 2023 Antmicro <www.antmicro.com>
# 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 <dt-bindings/pinctrl/quicklogic-eos-s3-pinctrl.h>
&pinctrl {
uart0_rx_default: uart0_rx_default {
pinmux = <UART_RX_PAD45>;
input-enable;
};
uart0_tx_default: uart0_tx_default {
pinmux = <UART_TX_PAD44>;
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"

View file

@ -0,0 +1,25 @@
/*
* Copyright (c) 2023 Antmicro <www.antmicro.com>
*
* 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 <zephyr/sys/util_macro.h>
#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_ */

View file

@ -0,0 +1,55 @@
/*
* Copyright (c) 2023 Antmicro <www.antmicro.com>
*
* 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 <zephyr/types.h>
#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_ */