Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

arm: introduce basic scmi support and scmi reset driver #124

Open
wants to merge 6 commits into
base: zephyr-v3.6.0-xt
Choose a base branch
from

Conversation

GrygiriiS
Copy link

@GrygiriiS GrygiriiS commented Aug 7, 2024

The SCMI [1] is a set of operating system-independent software interfaces
that are used in system management. The SCMI is intended to resolve
critical HW platform resources management problem in the modern
multiprocessor systems where different software (Operating systems,
firmware) are running on different processors (or in virtualized
environment), but still have to access some shared system resources like
power, clocks, etc.

SCMI Design Document v3.2 is currently defines interfaces for:

  • Discovery and self-description of the interfaces it supports.
  • Power domain management.
  • Performance management
  • Clock management.
  • Sensor management.
  • Reset domain management.
  • Voltage domain management.
  • Power capping and monitoring.
  • Pin control protocol

In terms of the SCMI design, the platform code is designated to handle
resource management requests in centralized manner and can run - or on
separate System Control Processor (SCP), or as part of Trusted Firmware
(ARM TF, OPTEE). In terms of the SCMI design, the agent is used to
describe the caller of the SCMI. The SCMI Transport describes how messages
are exchanged between agents and the platform.

This patch introduces basic support for ARM System Control and Management
Interface (SCMI) which implements interface to SCMI compliant firmware with
ARM SMC/HVC transport through the shared memory and can be extended.
The SCMI DT bindings are overall based on Linux Kernel ARM SCMI bindings
[2] with major difference that the SCMI protocol nodes are required to have
compatibility property.

      +-------------+
      |   SCMI      |
      |   Transport |
      |   device    |
      +------+------+
             |
       +-----v-------+
       |SCMI XFER API|
+------+             |
|      +-------------+
|
|
|     +---------------+  Zephyr reset API
+----->SCMI reset     +--------->
|     |  device       |
|     +---------------+
|
|     +---------------+  Zephyr clock API
+-----> SCMI clock    +--------->
|     |  device       |
|     +---------------+
|      ...
|     +---------------+
+-----> SCMI X        |
      |  device       |
      +---------------+

The SCMI Transport device is intended to implement required SCMI transport
according to the SCMI DT compatibility property.
For example:

  • "arm,scmi-smc" SCMI compliant firmware with ARM SMC/HVC transport;
  • "arm,scmi-smc-param" SCMI compliant firmware with ARM SMC/HVC transport
    with shmem address(4KB-page, offset) as parameters.
    And expose SCMI transfer (XFER) API which can be used by other SCMI
    functional devices.

The SCMI functional devices appear as child devices of the SCMI Transport
device, implement SCMI protocols for resource management and provide
corresponding standard Zephyr APIs.

For example, SCMI Reset domain management protocol (0x16, compatible
"arm,scmi-reset") is implemented as standard Zephyr Reset Controller
device/driver.

This implementation provides:

  • only SCMI Transport device which implements ARM SMC/HVC transport with
    shared memory;
  • only sync transfers are implemented hence SMC/HVC transport only supports
    "completed on return" functionality.

[1] https://developer.arm.com/Architectures/System%20Control%20and%20Management%20Interface
[2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/firmware/arm,scmi.yaml

@GrygiriiS
Copy link
Author

@lorc @oleksiimoisieiev

Copy link
Collaborator

@lorc lorc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great job!

I have a number of minor questions, though.

default ARM_SCMI_TRANSPORT_SMC

config ARM_SCMI_TRANSPORT_MBOX
bool "ARM SCMI compliant firmware with mailbox transport (todo)"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need KConfig entries for features that are not available yet?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1. And keep on mind that for mailbox transport - new compatible string should be introduced - "arm,scmi"
That's why I think that transport can be deternime based on copmatibility string. Also you have mentioned "arm,scmi-smc-param" compatible in the commit description, but haven't introduce it in the code. Maybe it will be better to remove this/

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

xfer->hdr.protocol_id,
xfer->hdr.msg_id);

data->smc_call_f(cfg->smc_func_id, page, offset, 0, 0, 0, 0, 0, &res);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you really need this callback? As I can see, depending on build configuration scmi_smccc_smc/hvc can call either arm_smccc_smc or arm_smccc_hvc. Why do you need extra layer of indirection?

You can have one function scmi_smccc_call that calls either arm_smccc_smc or arm_smccc_hvc, depending on CONFIG_ARM_SCMI_SMC_METHOD_SMC

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

#if defined(CONFIG_DT_HAS_ARM_SCMI_SMC_ENABLED)
static const struct device *scmi_dev = DEVICE_DT_GET_ANY(arm_scmi_smc);
#else
BUILD_ASSERT(1, "unsupported scmi interface");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe you can do this in KConfig. Something like

depends on DT_HAS_ARM_SCMI_SMC_ENABLED

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here no as diferent compatible need to be selected

@@ -190,3 +214,154 @@ static const struct scmi_reset_config scmi_reset_config = {

DEVICE_DT_INST_DEFINE(0, scmi_reset_init, NULL, &scmi_reset_data, &scmi_reset_config, PRE_KERNEL_2,
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &scmi_reset_driver_api);

#if defined(CONFIG_ARM_SCMI_RESET_SHELL)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this is part of the driver itself and not part of the shell.c?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can't be moved there as it uses private reset scmi functions.
This scmi reset and shell.c placed in different driver's folders.

dts/bindings/firmware/arm,scmi-reset.yaml Show resolved Hide resolved
default ARM_SCMI_TRANSPORT_SMC

config ARM_SCMI_TRANSPORT_MBOX
bool "ARM SCMI compliant firmware with mailbox transport (todo)"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1. And keep on mind that for mailbox transport - new compatible string should be introduced - "arm,scmi"
That's why I think that transport can be deternime based on copmatibility string. Also you have mentioned "arm,scmi-smc-param" compatible in the commit description, but haven't introduce it in the code. Maybe it will be better to remove this/

drivers/arm_scmi/shmem.h Outdated Show resolved Hide resolved
drivers/reset/Kconfig.arm_scmi Show resolved Hide resolved
@oleksiimoisieiev
Copy link

Great job. thank you. Also, a few comments from me

@GrygiriiS GrygiriiS force-pushed the rpi5_dev_scmi1 branch 2 times, most recently from 9a16630 to 67fe7d8 Compare August 19, 2024 14:15
@GrygiriiS
Copy link
Author

Updated and ready for review

Copy link

@oleksiimoisieiev oleksiimoisieiev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM Reviewed-by: Oleksii Moisieiev <[email protected]>

dts/bindings/firmware/arm,scmi-reset.yaml Show resolved Hide resolved
drivers/reset/Kconfig.arm_scmi Show resolved Hide resolved
@GrygiriiS
Copy link
Author

Updated:

  • added separate SCMI sample
  • DT changes moved into the board overlay of the SCMI sample
  • added more Base shell commands:
uart:~$ arm_scmi base help
base - SCMI Base proto commands.
Subcommands:
  revision           : SCMI Base get revision info
                      Usage: arm_scmi base revision

  discover_agent     : SCMI Base discover an agent
                      Usage: arm_scmi base discover_agent [agent_id]

  device_permission  : SCMI Base set an agent permissions to access device
                      Usage: arm_scmi base discover_agent <agent_id> <device_id>
                      <allow := 0|1>

  reset_agent_cfg    : SCMI Base reset an agent configuration
                      Usage: arm_scmi base reset_agent_cfg <agent_id>
                      <reset_perm := 0|1>

Copy link
Collaborator

@firscity firscity left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I am not sure if it should go to rpi5_dev branch, all patches that you've asked for were added to zephyr-v3.6.0-xt and I think you can start moving whole RPI5 setup to it.

With 2 comments:
Acked-by: Dmytro Firsov <[email protected]>

samples/drivers/firmware/arm_scmi/README.rst Outdated Show resolved Hide resolved
@GrygiriiS GrygiriiS changed the base branch from rpi5_dev to zephyr-v3.6.0-xt August 23, 2024 13:49
@GrygiriiS GrygiriiS changed the base branch from zephyr-v3.6.0-xt to rpi5_dev August 23, 2024 13:49
@GrygiriiS
Copy link
Author

Also, I am not sure if it should go to rpi5_dev branch, all patches that you've asked for were added to zephyr-v3.6.0-xt and I think you can start moving whole RPI5 setup to it.

With 2 comments: Acked-by: Dmytro Firsov <[email protected]>

It's in a dev stage and rpi5 not switched fully yet. I'll updated it on top zephyr-v3.6.0-xt when rpi is switched.

Grygorii Strashko added 6 commits August 27, 2024 09:13
Add DT bindings for ARM System Control and Management Interface (SCMI) DT
bindings with SMC/shmem based transport and for Reset domain management
protocol.

The SCMI bindings are overall based on Linux Kernel ARM SCMI bindings [1].

Hence Zephyr is not supported multi-compatible bindings definitions in one
yaml file the separate bindings has to be created for each defined ARM SCMI
compatible. This path introduces bindings (arm,scmi-smc.yaml) only for:
 "arm,scmi-smc" - description: SCMI compliant firmware with ARM SMC/HVC
 transport.
 "arm,scmi-smc-param" - SCMI compliant firmware with ARM SMC/HVC transport
 with shmem address(4KB-page, offset) as parameters

In addition, the Zephyr's DT processing design and devices instantiating is
tightly based on compatibility property presence in DT node, therefore, as
per this bindings, the SCMI protocol nodes are required to have
compatibility property.

Example:
firmware {
	scmi {
		compatible = "arm,scmi-smc";
		arm,smc-id = <0x82000002>;
		#address-cells = <1>;
		#size-cells = <0>;
		shmem = <&scmi_buf>;

		scmi_reset: protocol@16 {
			compatible = "arm,scmi-reset";
			reg = <0x16>;
			#reset-cells = <1>;
		};
	};
};

reserved-memory {
	#address-cells = <2>;
	#size-cells = <1>;
	ranges;

	scmi_buf: scmi@2201f000 {
		compatible = "zephyr,memory-region";
		reg = <0x0 0x3ff00000 4096>;
		zephyr,memory-region = "scmi";
	};
};

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/firmware/arm,scmi.yaml
Signed-off-by: Grygorii Strashko <[email protected]>
Reviewed-by: Oleksii Moisieiev <[email protected]>
Acked-by: Dmytro Firsov <[email protected]>
The SCMI [1] is a set of operating system-independent software interfaces
that are used in system management. The SCMI is intended to resolve
critical HW platform resources management problem in the modern
multiprocessor systems where different software (Operating systems,
firmware) are running on different processors (or in virtualized
environment), but still have to access some shared system resources like
power, clocks, etc.

SCMI Design Document v3.2 is currently defines interfaces for:
- Discovery and self-description of the interfaces it supports.
- Power domain management.
- Performance management
- Clock management.
- Sensor management.
- Reset domain management.
- Voltage domain management.
- Power capping and monitoring.
- Pin control protocol

In terms of the SCMI design, the *platform* code is designated to handle
resource management requests in centralized manner and can run - or on
separate System Control Processor (SCP), or as part of Trusted Firmware
(ARM TF, OPTEE). In terms of the SCMI design, the *agent* is used to
describe the caller of the SCMI. The SCMI Transport describes how messages
are exchanged between agents and the platform.

This patch introduces basic support for ARM System Control and Management
Interface (SCMI) which implements interface to SCMI compliant firmware with
ARM SMC/HVC transport through the shared memory and can be extended.
The SCMI DT bindings are overall based on Linux Kernel ARM SCMI bindings
[2] with major difference that the SCMI protocol nodes are required to have
compatibility property.

      +-------------+
      |   SCMI      |
      |   Transport |
      |   device    |
      +------+------+
             |
       +-----v-------+
       |SCMI XFER API|
+------+             |
|      +-------------+
|
|
|     +---------------+  Zephyr reset API
+----->SCMI reset     +--------->
|     |  device       |
|     +---------------+
|
|     +---------------+  Zephyr clock API
+-----> SCMI clock    +--------->
|     |  device       |
|     +---------------+
|      ...
|     +---------------+
+-----> SCMI X        |
      |  device       |
      +---------------+

The SCMI Transport device is intended to implement required SCMI transport
according to the SCMI DT compatibility property.
For example:
- "arm,scmi-smc" SCMI compliant firmware with ARM SMC/HVC transport;
- "arm,scmi-smc-param" SCMI compliant firmware with ARM SMC/HVC transport
with shmem address(4KB-page, offset) as parameters.
And expose SCMI transfer (XFER) API which can be used by other SCMI
functional devices.

The SCMI functional devices appear as child devices of the SCMI Transport
device, implement SCMI protocols for resource management and provide
corresponding standard Zephyr APIs.

For example, SCMI Reset domain management protocol (0x16, compatible
"arm,scmi-reset") is implemented as standard Zephyr Reset Controller
device/driver.

This implementation provides:
- only SCMI Transport device which implements ARM SMC/HVC transport with
shared memory;
- only sync transfers are implemented hence SMC/HVC transport only supports
"completed on return" functionality.

[1] https://developer.arm.com/Architectures/System%20Control%20and%20Management%20Interface
[2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/firmware/arm,scmi.yaml
Signed-off-by: Grygorii Strashko <[email protected]>
Reviewed-by: Oleksii Moisieiev <[email protected]>
Acked-by: Dmytro Firsov <[email protected]>
Add basic shell interface for testing purposes.

This patch introduces base *arm_scmi* shell command with following format:

  arm_scmi <proto> [protocol params]

The following commands introduced for Base protocol:

arm_scmi base help

base - SCMI Base proto commands.
Subcommands:
  revision           : SCMI Base get revision info
                      Usage: arm_scmi base revision

  discover_agent     : SCMI Base discover an agent
                      Usage: arm_scmi base discover_agent [agent_id]

  device_permission  : SCMI Base set an agent permissions to access device
                      Usage: arm_scmi base discover_agent <agent_id>
                      <device_id> <allow := 0|1>

  reset_agent_cfg    : SCMI Base reset an agent configuration
                      Usage: arm_scmi base reset_agent_cfg <agent_id>
                      <reset_perm := 0|1>

In the future more commands will be implemented as for Base protocol as for
other protocols. For example, for Reset domain management protocol
following shell commands are going to be added:

arm_scmi reset <revision|list|info|assert|deassert|autoreset> [params]

Signed-off-by: Grygorii Strashko <[email protected]>
Reviewed-by: Oleksii Moisieiev <[email protected]>
Acked-by: Dmytro Firsov <[email protected]>
This patch adds reset driver which implements ARM SCMI Reset domain
management protocol and exposes Zephyr Reset API.

The current implementation supports only sync operations.

Signed-off-by: Grygorii Strashko <[email protected]>
Reviewed-by: Oleksii Moisieiev <[email protected]>
Acked-by: Dmytro Firsov <[email protected]>
Add ARM SCMI Reset shell interface for demo and testing purposes, which is
defined as sub-command of *arm_scmi* command.
It's optional and can be enabled by CONFIG_ARM_SCMI_RESET_SHELL option.

The ARM SCMI Reset shell interface defined as following:

$arm_scmi reset
reset - SCMI Reset proto commands.
Subcommands:
  revision   : SCMI Reset proto show revision information
              Usage: arm_scmi reset revision

  list       : SCMI Reset domains list
              Usage: arm_scmi reset list

  info       : SCMI Reset domain show info
              Usage: arm_scmi reset info <domain_id>

  assert     : SCMI Reset domain assert
              Usage: arm_scmi reset assert <domain_id>

  deassert   : SCMI Reset domain de-assert
              Usage: arm_scmi reset deassert <domain_id>

  autoreset  : SCMI Reset domain Autonomous reset
              Usage: arm_scmi reset autoreset <domain_id>

Signed-off-by: Grygorii Strashko <[email protected]>
Reviewed-by: Oleksii Moisieiev <[email protected]>
Acked-by: Dmytro Firsov <[email protected]>
Add ARM SCMI shell sample application.

Signed-off-by: Grygorii Strashko <[email protected]>
Reviewed-by: Oleksii Moisieiev <[email protected]>
Acked-by: Dmytro Firsov <[email protected]>
@GrygiriiS GrygiriiS changed the base branch from rpi5_dev to zephyr-v3.6.0-xt August 27, 2024 06:35
@GrygiriiS
Copy link
Author

As requested updated on top of zephyr-v3.6.0-xt

@oleksiimoisieiev
Copy link

@firscity please take a look and merge if everything is ok

@firscity
Copy link
Collaborator

No objections from my side, but I would like to have @lorc AB/RB when he will be available

@lorc
Copy link
Collaborator

lorc commented Sep 2, 2024

This PR should be reworked, taking into account zephyrproject-rtos#75102

@GrygiriiS
Copy link
Author

This PR should be reworked, taking into account zephyrproject-rtos#75102

ok. @klogg @oleksiimoisieiev FYI.

@xakep-amatop
Copy link
Collaborator

Are we going to merge this PR?
Does it need to be reviewed?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants