blob: 96c2922b067e2886b3fa963bcd7e396f4569a569 [file] [log] [blame]
Etienne Carriere2d94c08fa2020-09-09 18:44:05 +02001// SPDX-License-Identifier: GPL-2.0
2/*
Etienne Carriereb8f15cd2021-03-08 22:38:07 +01003 * Copyright (C) 2020-2021, Linaro Limited
Etienne Carriere2d94c08fa2020-09-09 18:44:05 +02004 */
5
Patrick Delaunay5dd84d42021-02-24 11:19:44 +01006#define LOG_CATEGORY UCLASS_MISC
7
Etienne Carriere2d94c08fa2020-09-09 18:44:05 +02008#include <clk.h>
9#include <dm.h>
Etienne Carriereb8f15cd2021-03-08 22:38:07 +010010#include <log.h>
Etienne Carriere2d94c08fa2020-09-09 18:44:05 +020011#include <malloc.h>
Etienne Carriere8b9b6892020-09-09 18:44:07 +020012#include <reset.h>
Etienne Carriere2d94c08fa2020-09-09 18:44:05 +020013#include <asm/io.h>
14#include <asm/scmi_test.h>
15#include <dm/device_compat.h>
Etienne Carriereb8f15cd2021-03-08 22:38:07 +010016#include <power/regulator.h>
Etienne Carriere2d94c08fa2020-09-09 18:44:05 +020017
18/*
19 * Simulate to some extent a SCMI exchange.
20 * This drivers gets SCMI resources and offers API function to the
Etienne Carriere8b9b6892020-09-09 18:44:07 +020021 * SCMI test sequence manipulate the resources, currently clock
22 * and reset controllers.
Etienne Carriere2d94c08fa2020-09-09 18:44:05 +020023 */
24
Etienne Carriere09665cb2022-02-21 09:22:39 +010025#define SCMI_TEST_DEVICES_CLK_COUNT 2
Etienne Carriere8b9b6892020-09-09 18:44:07 +020026#define SCMI_TEST_DEVICES_RD_COUNT 1
Etienne Carriereb8f15cd2021-03-08 22:38:07 +010027#define SCMI_TEST_DEVICES_VOLTD_COUNT 2
Etienne Carriere2d94c08fa2020-09-09 18:44:05 +020028
29/*
30 * struct sandbox_scmi_device_priv - Storage for device handles used by test
AKASHI Takahiro535a7bd2023-10-16 14:39:45 +090031 * @pwdom: Power domain device
Etienne Carriere2d94c08fa2020-09-09 18:44:05 +020032 * @clk: Array of clock instances used by tests
Etienne Carriere8b9b6892020-09-09 18:44:07 +020033 * @reset_clt: Array of the reset controller instances used by tests
Etienne Carriereb8f15cd2021-03-08 22:38:07 +010034 * @regulators: Array of regulator device references used by the tests
Etienne Carriere2d94c08fa2020-09-09 18:44:05 +020035 * @devices: Resources exposed by sandbox_scmi_devices_ctx()
36 */
37struct sandbox_scmi_device_priv {
AKASHI Takahiro535a7bd2023-10-16 14:39:45 +090038 struct power_domain pwdom;
Etienne Carriere2d94c08fa2020-09-09 18:44:05 +020039 struct clk clk[SCMI_TEST_DEVICES_CLK_COUNT];
Etienne Carriere8b9b6892020-09-09 18:44:07 +020040 struct reset_ctl reset_ctl[SCMI_TEST_DEVICES_RD_COUNT];
Etienne Carriereb8f15cd2021-03-08 22:38:07 +010041 struct udevice *regulators[SCMI_TEST_DEVICES_VOLTD_COUNT];
Etienne Carriere2d94c08fa2020-09-09 18:44:05 +020042 struct sandbox_scmi_devices devices;
43};
44
45struct sandbox_scmi_devices *sandbox_scmi_devices_ctx(struct udevice *dev)
46{
47 struct sandbox_scmi_device_priv *priv = dev_get_priv(dev);
48
49 if (priv)
50 return &priv->devices;
51
52 return NULL;
53}
54
Etienne Carriere8b9b6892020-09-09 18:44:07 +020055static int sandbox_scmi_devices_remove(struct udevice *dev)
56{
57 struct sandbox_scmi_devices *devices = sandbox_scmi_devices_ctx(dev);
58 int ret = 0;
59 size_t n;
60
Heinrich Schuchardt748cbaa2021-02-01 03:01:54 +010061 if (!devices)
62 return 0;
63
AKASHI Takahiro59171ff2023-11-14 11:14:25 +090064 if (CONFIG_IS_ENABLED(RESET_SCMI))
65 for (n = 0; n < SCMI_TEST_DEVICES_RD_COUNT; n++) {
66 int ret2 = reset_free(devices->reset + n);
Etienne Carriere8b9b6892020-09-09 18:44:07 +020067
AKASHI Takahiro59171ff2023-11-14 11:14:25 +090068 if (ret2 && !ret)
69 ret = ret2;
70 }
Etienne Carriere8b9b6892020-09-09 18:44:07 +020071
72 return ret;
73}
74
Etienne Carriere2d94c08fa2020-09-09 18:44:05 +020075static int sandbox_scmi_devices_probe(struct udevice *dev)
76{
77 struct sandbox_scmi_device_priv *priv = dev_get_priv(dev);
78 int ret;
79 size_t n;
80
81 priv->devices = (struct sandbox_scmi_devices){
AKASHI Takahiro535a7bd2023-10-16 14:39:45 +090082 .pwdom = &priv->pwdom,
83 .pwdom_count = 1,
Etienne Carriere2d94c08fa2020-09-09 18:44:05 +020084 .clk = priv->clk,
85 .clk_count = SCMI_TEST_DEVICES_CLK_COUNT,
Etienne Carriere8b9b6892020-09-09 18:44:07 +020086 .reset = priv->reset_ctl,
87 .reset_count = SCMI_TEST_DEVICES_RD_COUNT,
Etienne Carriereb8f15cd2021-03-08 22:38:07 +010088 .regul = priv->regulators,
89 .regul_count = SCMI_TEST_DEVICES_VOLTD_COUNT,
Etienne Carriere2d94c08fa2020-09-09 18:44:05 +020090 };
91
AKASHI Takahiro59171ff2023-11-14 11:14:25 +090092 if (CONFIG_IS_ENABLED(SCMI_POWER_DOMAIN)) {
93 ret = power_domain_get_by_index(dev, priv->devices.pwdom, 0);
Etienne Carriere2d94c08fa2020-09-09 18:44:05 +020094 if (ret) {
AKASHI Takahiro59171ff2023-11-14 11:14:25 +090095 dev_err(dev, "%s: Failed on power domain\n", __func__);
Etienne Carriere2d94c08fa2020-09-09 18:44:05 +020096 return ret;
97 }
98 }
99
AKASHI Takahiro59171ff2023-11-14 11:14:25 +0900100 if (CONFIG_IS_ENABLED(CLK_SCMI)) {
101 for (n = 0; n < SCMI_TEST_DEVICES_CLK_COUNT; n++) {
102 ret = clk_get_by_index(dev, n, priv->devices.clk + n);
103 if (ret) {
104 dev_err(dev, "%s: Failed on clk %zu\n",
105 __func__, n);
106 return ret;
107 }
Etienne Carriere8b9b6892020-09-09 18:44:07 +0200108 }
109 }
110
AKASHI Takahiro59171ff2023-11-14 11:14:25 +0900111 if (CONFIG_IS_ENABLED(RESET_SCMI)) {
112 for (n = 0; n < SCMI_TEST_DEVICES_RD_COUNT; n++) {
113 ret = reset_get_by_index(dev, n,
114 priv->devices.reset + n);
115 if (ret) {
116 dev_err(dev, "%s: Failed on reset %zu\n",
117 __func__, n);
118 goto err_reset;
119 }
120 }
121 }
Etienne Carriereb8f15cd2021-03-08 22:38:07 +0100122
AKASHI Takahiro59171ff2023-11-14 11:14:25 +0900123 if (CONFIG_IS_ENABLED(DM_REGULATOR_SCMI)) {
124 for (n = 0; n < SCMI_TEST_DEVICES_VOLTD_COUNT; n++) {
125 char name[32];
Etienne Carriereb8f15cd2021-03-08 22:38:07 +0100126
AKASHI Takahiro59171ff2023-11-14 11:14:25 +0900127 ret = snprintf(name, sizeof(name), "regul%zu-supply",
128 n);
129 assert(ret >= 0 && ret < sizeof(name));
130
131 ret = device_get_supply_regulator(dev, name,
132 priv->devices.regul
133 + n);
134 if (ret) {
135 dev_err(dev, "%s: Failed on voltd %zu\n",
136 __func__, n);
137 goto err_regul;
138 }
Etienne Carriereb8f15cd2021-03-08 22:38:07 +0100139 }
140 }
141
Etienne Carriere2d94c08fa2020-09-09 18:44:05 +0200142 return 0;
Etienne Carriere8b9b6892020-09-09 18:44:07 +0200143
Etienne Carriereb8f15cd2021-03-08 22:38:07 +0100144err_regul:
145 n = SCMI_TEST_DEVICES_RD_COUNT;
Etienne Carriere8b9b6892020-09-09 18:44:07 +0200146err_reset:
AKASHI Takahiro59171ff2023-11-14 11:14:25 +0900147 if (CONFIG_IS_ENABLED(RESET_SCMI))
148 for (; n > 0; n--)
149 reset_free(priv->devices.reset + n - 1);
Etienne Carriere8b9b6892020-09-09 18:44:07 +0200150
151 return ret;
Etienne Carriere2d94c08fa2020-09-09 18:44:05 +0200152}
153
154static const struct udevice_id sandbox_scmi_devices_ids[] = {
155 { .compatible = "sandbox,scmi-devices" },
156 { }
157};
158
159U_BOOT_DRIVER(sandbox_scmi_devices) = {
160 .name = "sandbox-scmi_devices",
161 .id = UCLASS_MISC,
162 .of_match = sandbox_scmi_devices_ids,
Etienne Carriere09665cb2022-02-21 09:22:39 +0100163 .priv_auto = sizeof(struct sandbox_scmi_device_priv),
Etienne Carriere8b9b6892020-09-09 18:44:07 +0200164 .remove = sandbox_scmi_devices_remove,
Etienne Carriere2d94c08fa2020-09-09 18:44:05 +0200165 .probe = sandbox_scmi_devices_probe,
166};