Commit 6b689d02 authored by Laurentiu Mihalcea's avatar Laurentiu Mihalcea Committed by Anas Nashif
Browse files

firmware: scmi: add support for pinctrl protocol

This includes helper function for pin configuration
and a DT binding for the pinctrl DT node.

There's two important notes to be made regarding this
protocol:

* pinctrl drivers have no subsytem API to implement as opposed
to clock control drivers. Because of this (and the fact that
`pinctrl_configure_pins()` doesn't require a `struct device`
handle) the pinctrl driver consists only of a helper function,
which implements the `PINCTRL_CONFIGURE_PINS` command.
Additionally, the `scmi_protocol` structure is defined inside
the pinctrl helpers source file to avoid redundant code
(otherwise, each SCMI-based pinctrl driver would have to define
it its source file).

* each vendor may have their own set of pin propeties and DT
representations for them. Because of this, there can't be a
generic, SCMI-based pinctrl driver. As such, each vendor who
wants to use the SCMI support for pinctrl operations will have
to implement their pinctrl driver (which, to put it simply,
revolves around implemeting `pinctrl_configure_pins()`) and
make use of the pin configuration function introduced in this
commit. Moreover, this means that each vendor will have control
over the way their pin properties are encoded in the
`scmi_pinctrl_settings` structure.

Signed-off-by: default avatarLaurentiu Mihalcea <laurentiu.mihalcea@nxp.com>
parent 350e36a4
Loading
Loading
Loading
Loading
+1 −0
Changes for drivers/firmware/scmi/CMakeLists.txt: 1 added line, 0 removed lines.
Original line number Diff line number Diff line
@@ -9,3 +9,4 @@ zephyr_library_sources_ifdef(CONFIG_ARM_SCMI_SHMEM shmem.c)

# SCMI protocol helper files
zephyr_library_sources_ifdef(CONFIG_ARM_SCMI_CLK_HELPERS clk.c)
zephyr_library_sources_ifdef(CONFIG_ARM_SCMI_PINCTRL_HELPERS pinctrl.c)
+7 −0
Changes for drivers/firmware/scmi/Kconfig: 7 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -20,6 +20,13 @@ config ARM_SCMI_MAILBOX_TRANSPORT
	  Enable support for SCMI transport based on shared memory
	  and doorbells.

config ARM_SCMI_PINCTRL_HELPERS
	bool "Helper functions for SCMI pinctrl protocol"
	default y
	depends on DT_HAS_ARM_SCMI_PINCTRL_ENABLED
	help
	  Enable support for SCMI pinctrl protocol helper functions.

config ARM_SCMI_SHMEM
	bool "SCMI shared memory (SHMEM) driver"
	default y
+63 −0
Changes for drivers/firmware/scmi/pinctrl.c: 63 added lines, 0 removed lines.
Original line number Diff line number Diff line
/*
 * Copyright 2024 NXP
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/drivers/firmware/scmi/pinctrl.h>

DT_SCMI_PROTOCOL_DEFINE_NODEV(DT_INST(0, arm_scmi_pinctrl), NULL);

int scmi_pinctrl_settings_configure(struct scmi_pinctrl_settings *settings)
{
	struct scmi_protocol *proto;
	struct scmi_message msg, reply;
	uint32_t config_num;
	int32_t status, ret;

	proto = &SCMI_PROTOCOL_NAME(SCMI_PROTOCOL_PINCTRL);

	/* sanity checks */
	if (!settings) {
		return -EINVAL;
	}

	if (!proto) {
		return -EINVAL;
	}

	if (proto->id != SCMI_PROTOCOL_PINCTRL) {
		return -EINVAL;
	}

	config_num = SCMI_PINCTRL_ATTRIBUTES_CONFIG_NUM(settings->attributes);

	if (!config_num) {
		return -EINVAL;
	}

	if ((config_num * 2) > ARM_SCMI_PINCTRL_MAX_CONFIG_SIZE) {
		return -EINVAL;
	}

	msg.hdr = SCMI_MESSAGE_HDR_MAKE(SCMI_PINCTRL_MSG_PINCTRL_SETTINGS_CONFIGURE,
					SCMI_COMMAND, proto->id, 0x0);
	msg.len = sizeof(*settings) -
		(ARM_SCMI_PINCTRL_MAX_CONFIG_SIZE - config_num * 2) * 4;
	msg.content = settings;

	reply.hdr = msg.hdr;
	reply.len = sizeof(status);
	reply.content = &status;

	ret = scmi_send_message(proto, &msg, &reply);
	if (ret < 0) {
		return ret;
	}

	if (status != SCMI_SUCCESS) {
		return scmi_status_to_errno(status);
	}

	return 0;
}
+20 −0
Changes for dts/bindings/firmware/arm,scmi-pinctrl.yaml: 20 added lines, 0 removed lines.
Original line number Diff line number Diff line
# Copyright 2024 NXP
# SPDX-License-Identifier: Apache-2.0

description: System Control and Management Interface (SCMI) pinctrl protocol

compatible: "arm,scmi-pinctrl"

include: base.yaml

properties:
  reg:
    required: true
    const: [0x19]

child-binding:
  description: SCMI pin protocol pin group
  properties:
    pinmux:
      required: true
      type: array
+103 −0
Changes for include/zephyr/drivers/firmware/scmi/pinctrl.h: 103 added lines, 0 removed lines.
Original line number Diff line number Diff line
/*
 * Copyright 2024 NXP
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @file
 * @brief SCMI pinctrl protocol helpers
 */

#ifndef _INCLUDE_ZEPHYR_DRIVERS_FIRMWARE_SCMI_PINCTRL_H_
#define _INCLUDE_ZEPHYR_DRIVERS_FIRMWARE_SCMI_PINCTRL_H_

#include <zephyr/drivers/firmware/scmi/protocol.h>

#define ARM_SCMI_PINCTRL_MAX_CONFIG_SIZE (10 * 2)

#define SCMI_PINCTRL_NO_FUNCTION 0xFFFFFFFF

#define SCMI_PINCTRL_CONFIG_ATTRIBUTES(fid_valid, cfg_num, selector)	\
	(SCMI_FIELD_MAKE(fid_valid, BIT(1), 10) |			\
	 SCMI_FIELD_MAKE(cfg_num, GENMASK(7, 0), 2) |			\
	 SCMI_FIELD_MAKE(selector, GENMASK(1, 0), 0))

#define SCMI_PINCTRL_SELECTOR_PIN 0x0
#define SCMI_PINCTRL_SELECTOR_GROUP 0x1

#define SCMI_PINCTRL_ATTRIBUTES_CONFIG_NUM(attributes)\
	(((attributes) & GENMASK(9, 2)) >> 2)

/**
 * @brief Pinctrl protocol command message IDs
 */
enum scmi_pinctrl_message {
	SCMI_PINCTRL_MSG_PROTOCOL_VERSION = 0x0,
	SCMI_PINCTRL_MSG_PROTOCOL_ATTRIBUTES = 0x1,
	SCMI_PINCTRL_MSG_PROTOCOL_MESSAGE_ATTRIBUTES = 0x2,
	SCMI_PINCTRL_MSG_PINCTRL_ATTRIBUTES = 0x3,
	SCMI_PINCTRL_MSG_PINCTRL_LIST_ASSOCIATIONS = 0x4,
	SCMI_PINCTRL_MSG_PINCTRL_SETTINGS_GET = 0x5,
	SCMI_PINCTRL_MSG_PINCTRL_SETTINGS_CONFIGURE = 0x6,
	SCMI_PINCTRL_MSG_PINCTRL_REQUEST = 0x7,
	SCMI_PINCTRL_MSG_PINCTRL_RELEASE = 0x8,
	SCMI_PINCTRL_MSG_PINCTRL_NAME_GET = 0x9,
	SCMI_PINCTRL_MSG_PINCTRL_SET_PERMISSIONS = 0xa,
	SCMI_PINCTRL_MSG_NEGOTIATE_PROTOCOL_VERSION = 0x10,
};

/**
 * @brief Pinctrl configurations
 */
enum scmi_pinctrl_config {
	SCMI_PINCTRL_DEFAULT = 0,
	SCMI_PINCTRL_BIAS_BUS_HOLD = 1,
	SCMI_PINCTRL_BIAS_DISABLE = 2,
	SCMI_PINCTRL_BIAS_HIGH_Z = 3,
	SCMI_PINCTRL_BIAS_PULL_UP = 4,
	SCMI_PINCTRL_BIAS_PULL_DEFAULT = 5,
	SCMI_PINCTRL_BIAS_PULL_DOWN = 6,
	SCMI_PINCTRL_DRIVE_OPEN_DRAIN = 7,
	SCMI_PINCTRL_DRIVE_OPEN_SOURCE = 8,
	SCMI_PCINTRL_DRIVE_PUSH_PULL = 9,
	SCMI_PCINTRL_DRIVE_STRENGTH = 10,
	SCMI_PINCTRL_INPUT_DEBOUNCE = 11,
	SCMI_PINCTRL_INPUT_MODE = 12,
	SCMI_PINCTRL_PULL_MODE = 13,
	SCMI_PINCTRL_INPUT_VALUE = 14,
	SCMI_PINCTRL_INPUT_SCHMITT = 15,
	SCMI_PINCTRL_LP_MODE = 16,
	SCMI_PINCTRL_OUTPUT_MODE = 17,
	SCMI_PINCTRL_OUTPUT_VALUE = 18,
	SCMI_PINCTRL_POWER_SOURCE = 19,
	SCMI_PINCTRL_SLEW_RATE = 20,
	SCMI_PINCTRL_RESERVED_START = 21,
	SCMI_PINCTRL_RESERVED_END = 191,
	SCMI_PINCTRL_VENDOR_START = 192,
};

/**
 * @struct scmi_pinctrl_settings
 *
 * @brief Describes the parameters for the PINCTRL_SETTINGS_CONFIGURE
 * command
 */
struct scmi_pinctrl_settings {
	uint32_t id;
	uint32_t function;
	uint32_t attributes;
	uint32_t config[ARM_SCMI_PINCTRL_MAX_CONFIG_SIZE];
};

/**
 * @brief Send the PINCTRL_SETTINGS_CONFIGURE command and get its reply
 *
 * @param settings pointer to settings to be applied
 *
 * @retval 0 if successful
 * @retval negative errno if failure
 */
int scmi_pinctrl_settings_configure(struct scmi_pinctrl_settings *settings);

#endif /* _INCLUDE_ZEPHYR_DRIVERS_FIRMWARE_SCMI_PINCTRL_H_ */