Skip to content

Commit

Permalink
drivers: pinctrl: add driver for EOS S3
Browse files Browse the repository at this point in the history
This adds a new pinctrl driver for Quicklogic EOS S3 SoC

Signed-off-by: Wojciech Sipak <wsipak@antmicro.com>
  • Loading branch information
wsipak committed Jul 26, 2023
1 parent 7bfe096 commit 35235a1
Show file tree
Hide file tree
Showing 10 changed files with 301 additions and 0 deletions.
1 change: 1 addition & 0 deletions drivers/pinctrl/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
1 change: 1 addition & 0 deletions drivers/pinctrl/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
9 changes: 9 additions & 0 deletions drivers/pinctrl/Kconfig.eos_s3
Original file line number Diff line number Diff line change
@@ -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
128 changes: 128 additions & 0 deletions drivers/pinctrl/pinctrl_eos_s3.c
Original file line number Diff line number Diff line change
@@ -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;
}
1 change: 1 addition & 0 deletions drivers/serial/Kconfig.pl011
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
1 change: 1 addition & 0 deletions drivers/serial/Kconfig.ql_usbserialport_s3b
Original file line number Diff line number Diff line change
Expand Up @@ -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.
5 changes: 5 additions & 0 deletions dts/arm/quicklogic/quicklogic_eos_s3.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@
pin-secondary-config = <0x00>;
gpio-controller;
};

pinctrl: pinctrl@40004c00 {
compatible = "quicklogic,eos-s3-pinctrl";
reg = <0x40004c00 0x1b0>;
};
};
};

Expand Down
75 changes: 75 additions & 0 deletions dts/bindings/pinctrl/quicklogic,eos-s3-pinctrl.yaml
Original file line number Diff line number Diff line change
@@ -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"
25 changes: 25 additions & 0 deletions include/zephyr/dt-bindings/pinctrl/quicklogic-eos-s3-pinctrl.h
Original file line number Diff line number Diff line change
@@ -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_ */
55 changes: 55 additions & 0 deletions soc/arm/quicklogic_eos_s3/pinctrl_soc.h
Original file line number Diff line number Diff line change
@@ -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, 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_ */

0 comments on commit 35235a1

Please sign in to comment.