"Das U-Boot" Source Tree
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'scmi-master-2025-11-11' of https://source.denx.de/u-boot/custodians/u-boot-fsl-qoriq

CI: https://source.denx.de/u-boot/custodians/u-boot-fsl-qoriq/-/pipelines/28272

- Support scmi v3.2 CONFIG_SET for clock protocol
- A patchset from Marek to optimize the scmi clk booting time
- Fix scmi clk set_parent in non-CCF case
- Drop mmu_set_region_dcache_behaviour in firmware scmi

Tom Rini c7e33aae 365a7079

+123 -90
+1 -1
arch/arm/mach-imx/imx9/scmi/clock_scmi.c
··· 10 10 11 11 int imx_clk_scmi_enable(u32 clock_id, bool enable) 12 12 { 13 - struct scmi_clk_state_in in = { 13 + struct scmi_clk_state_in_v1 in = { 14 14 .clock_id = clock_id, 15 15 .attributes = !!enable, 16 16 };
+94 -62
drivers/clk/clk_scmi.c
··· 8 8 #include <clk-uclass.h> 9 9 #include <dm.h> 10 10 #include <dm/device_compat.h> 11 + #include <dm/device-internal.h> 11 12 #include <scmi_agent.h> 12 13 #include <scmi_agent-uclass.h> 13 14 #include <scmi_protocols.h> ··· 16 17 17 18 struct clk_scmi { 18 19 struct clk clk; 20 + char name[SCMI_CLOCK_NAME_LENGTH_MAX]; 19 21 u32 ctrl_flags; 22 + bool attrs_resolved; 20 23 }; 21 24 22 25 struct scmi_clock_priv { ··· 84 87 return 0; 85 88 } 86 89 87 - static int scmi_clk_get_attibute(struct udevice *dev, int clkid, char **name, 90 + static int scmi_clk_get_attibute(struct udevice *dev, int clkid, char *name, 88 91 u32 *attr) 89 92 { 90 93 struct scmi_clock_priv *priv = dev_get_priv(dev); ··· 108 111 if (ret) 109 112 return ret; 110 113 111 - *name = strdup(out.clock_name); 114 + strncpy(name, out.clock_name, SCMI_CLOCK_NAME_LENGTH_MAX); 112 115 *attr = out.attributes; 113 116 } else { 114 117 struct scmi_clk_attribute_out out; ··· 125 128 if (ret) 126 129 return ret; 127 130 128 - *name = strdup(out.clock_name); 131 + strncpy(name, out.clock_name, SCMI_CLOCK_NAME_LENGTH_MAX); 129 132 *attr = out.attributes; 130 133 } 131 134 ··· 134 137 135 138 static int scmi_clk_gate(struct clk *clk, int enable) 136 139 { 137 - struct scmi_clk_state_in in = { 140 + struct scmi_clock_priv *priv = dev_get_parent_priv(clk->dev); 141 + struct scmi_clk_state_in_v1 in_v1 = { 142 + .clock_id = clk_get_id(clk), 143 + .attributes = enable, 144 + }; 145 + /* Valid only from SCMI clock v2.1 */ 146 + struct scmi_clk_state_in_v2 in_v2 = { 138 147 .clock_id = clk_get_id(clk), 139 148 .attributes = enable, 140 149 }; 141 150 struct scmi_clk_state_out out; 142 - struct scmi_msg msg = SCMI_MSG_IN(SCMI_PROTOCOL_ID_CLOCK, 143 - SCMI_CLOCK_CONFIG_SET, 144 - in, out); 151 + struct scmi_msg msg_v1 = SCMI_MSG_IN(SCMI_PROTOCOL_ID_CLOCK, 152 + SCMI_CLOCK_CONFIG_SET, 153 + in_v1, out); 154 + struct scmi_msg msg_v2 = SCMI_MSG_IN(SCMI_PROTOCOL_ID_CLOCK, 155 + SCMI_CLOCK_CONFIG_SET, 156 + in_v2, out); 145 157 int ret; 146 158 147 - ret = devm_scmi_process_msg(clk->dev, &msg); 159 + ret = devm_scmi_process_msg(clk->dev, 160 + (priv->version < CLOCK_PROTOCOL_VERSION_2_1) ? 161 + &msg_v1 : &msg_v2); 148 162 if (ret) 149 163 return ret; 150 164 151 165 return scmi_to_linux_errno(out.status); 152 166 } 153 167 154 - static int scmi_clk_enable(struct clk *clk) 168 + static int scmi_clk_get_ctrl_flags(struct clk *clk, u32 *ctrl_flags) 155 169 { 156 170 struct clk_scmi *clkscmi; 171 + struct udevice *dev; 172 + u32 attributes; 157 173 struct clk *c; 158 174 int ret; 159 175 160 - if (!CONFIG_IS_ENABLED(CLK_CCF)) 161 - return scmi_clk_gate(clk, 1); 162 - 163 176 ret = clk_get_by_id(clk->id, &c); 164 177 if (ret) 165 178 return ret; 179 + 180 + dev = c->dev->parent; 166 181 167 182 clkscmi = container_of(c, struct clk_scmi, clk); 168 183 169 - if (clkscmi->ctrl_flags & SUPPORT_CLK_STAT_CONTROL) 184 + if (!clkscmi->attrs_resolved) { 185 + char name[SCMI_CLOCK_NAME_LENGTH_MAX]; 186 + ret = scmi_clk_get_attibute(dev, clk->id & CLK_ID_MSK, 187 + name, &attributes); 188 + if (ret) 189 + return ret; 190 + 191 + strncpy(clkscmi->name, name, SCMI_CLOCK_NAME_LENGTH_MAX); 192 + if (CLK_HAS_RESTRICTIONS(attributes)) { 193 + u32 perm; 194 + 195 + ret = scmi_clk_get_permissions(dev, clk->id & CLK_ID_MSK, &perm); 196 + if (ret < 0) 197 + clkscmi->ctrl_flags = 0; 198 + else 199 + clkscmi->ctrl_flags = perm; 200 + } else { 201 + clkscmi->ctrl_flags = SUPPORT_CLK_STAT_CONTROL | 202 + SUPPORT_CLK_PARENT_CONTROL | 203 + SUPPORT_CLK_RATE_CONTROL; 204 + } 205 + 206 + clkscmi->attrs_resolved = true; 207 + } 208 + 209 + *ctrl_flags = clkscmi->ctrl_flags; 210 + 211 + return 0; 212 + } 213 + 214 + static int scmi_clk_enable(struct clk *clk) 215 + { 216 + u32 ctrl_flags; 217 + int ret; 218 + 219 + if (!CONFIG_IS_ENABLED(CLK_CCF)) 220 + return scmi_clk_gate(clk, 1); 221 + 222 + ret = scmi_clk_get_ctrl_flags(clk, &ctrl_flags); 223 + if (ret) 224 + return ret; 225 + 226 + if (ctrl_flags & SUPPORT_CLK_STAT_CONTROL) 170 227 return scmi_clk_gate(clk, 1); 171 228 172 229 /* Following Linux drivers/clk/clk-scmi.c, directly return 0 if agent has no permission. */ ··· 176 233 177 234 static int scmi_clk_disable(struct clk *clk) 178 235 { 179 - struct clk_scmi *clkscmi; 180 - struct clk *c; 236 + u32 ctrl_flags; 181 237 int ret; 182 238 183 239 if (!CONFIG_IS_ENABLED(CLK_CCF)) 184 240 return scmi_clk_gate(clk, 0); 185 241 186 - ret = clk_get_by_id(clk->id, &c); 242 + ret = scmi_clk_get_ctrl_flags(clk, &ctrl_flags); 187 243 if (ret) 188 244 return ret; 189 245 190 - clkscmi = container_of(c, struct clk_scmi, clk); 191 - 192 - if (clkscmi->ctrl_flags & SUPPORT_CLK_STAT_CONTROL) 246 + if (ctrl_flags & SUPPORT_CLK_STAT_CONTROL) 193 247 return scmi_clk_gate(clk, 0); 194 248 195 249 /* Following Linux drivers/clk/clk-scmi.c, directly return 0 if agent has no permission. */ ··· 247 301 248 302 static ulong scmi_clk_set_rate(struct clk *clk, ulong rate) 249 303 { 250 - struct clk_scmi *clkscmi; 251 - struct clk *c; 304 + u32 ctrl_flags; 252 305 int ret; 253 306 254 307 if (!CONFIG_IS_ENABLED(CLK_CCF)) 255 308 return __scmi_clk_set_rate(clk, rate); 256 309 257 - ret = clk_get_by_id(clk->id, &c); 310 + ret = scmi_clk_get_ctrl_flags(clk, &ctrl_flags); 258 311 if (ret) 259 312 return ret; 260 313 261 - clkscmi = container_of(c, struct clk_scmi, clk); 262 - 263 - if (clkscmi->ctrl_flags & SUPPORT_CLK_RATE_CONTROL) 314 + if (ctrl_flags & SUPPORT_CLK_RATE_CONTROL) 264 315 return __scmi_clk_set_rate(clk, rate); 265 316 266 317 /* Following Linux drivers/clk/clk-scmi.c, directly return 0 if agent has no permission. */ ··· 271 322 272 323 static int scmi_clk_probe(struct udevice *dev) 273 324 { 274 - struct clk_scmi *clk_scmi; 325 + struct clk_scmi *clk_scmi_bulk, *clk_scmi; 275 326 struct scmi_clock_priv *priv = dev_get_priv(dev); 276 327 size_t num_clocks, i; 277 328 int ret; ··· 300 351 return ret; 301 352 } 302 353 303 - for (i = 0; i < num_clocks; i++) { 304 - char *clock_name; 305 - u32 attributes; 306 - 307 - if (!scmi_clk_get_attibute(dev, i, &clock_name, &attributes)) { 308 - clk_scmi = kzalloc(sizeof(*clk_scmi), GFP_KERNEL); 309 - if (!clk_scmi || !clock_name) 310 - ret = -ENOMEM; 311 - else 312 - ret = clk_register(&clk_scmi->clk, dev->driver->name, 313 - clock_name, dev->name); 354 + clk_scmi_bulk = kzalloc(num_clocks * sizeof(*clk_scmi), GFP_KERNEL); 355 + if (!clk_scmi_bulk) 356 + return -ENOMEM; 314 357 315 - if (ret) { 316 - free(clk_scmi); 317 - free(clock_name); 318 - return ret; 319 - } 358 + for (i = 0; i < num_clocks; i++) { 359 + clk_scmi = clk_scmi_bulk + i; 360 + char *clock_name = clk_scmi->name; 320 361 321 - dev_clk_dm(dev, i, &clk_scmi->clk); 362 + snprintf(clock_name, SCMI_CLOCK_NAME_LENGTH_MAX, "scmi-%zu", i); 322 363 323 - if (CLK_HAS_RESTRICTIONS(attributes)) { 324 - u32 perm; 364 + ret = clk_register(&clk_scmi->clk, dev->driver->name, 365 + clock_name, dev->name); 366 + if (ret) 367 + return ret; 325 368 326 - ret = scmi_clk_get_permissions(dev, i, &perm); 327 - if (ret < 0) 328 - clk_scmi->ctrl_flags = 0; 329 - else 330 - clk_scmi->ctrl_flags = perm; 331 - } else { 332 - clk_scmi->ctrl_flags = SUPPORT_CLK_STAT_CONTROL | SUPPORT_CLK_PARENT_CONTROL | 333 - SUPPORT_CLK_RATE_CONTROL; 334 - } 335 - } 369 + dev_clk_dm(dev, i, &clk_scmi->clk); 370 + dev_set_parent_priv(clk_scmi->clk.dev, priv); 336 371 } 337 372 338 373 return 0; ··· 359 394 360 395 static int scmi_clk_set_parent(struct clk *clk, struct clk *parent) 361 396 { 362 - struct clk_scmi *clkscmi; 363 - struct clk *c; 397 + u32 ctrl_flags; 364 398 int ret; 365 399 366 400 if (!CONFIG_IS_ENABLED(CLK_CCF)) 367 - return -ENOTSUPP; 401 + return __scmi_clk_set_parent(clk, parent); 368 402 369 - ret = clk_get_by_id(clk->id, &c); 403 + ret = scmi_clk_get_ctrl_flags(clk, &ctrl_flags); 370 404 if (ret) 371 405 return ret; 372 406 373 - clkscmi = container_of(c, struct clk_scmi, clk); 374 - 375 - if (clkscmi->ctrl_flags & SUPPORT_CLK_PARENT_CONTROL) 407 + if (ctrl_flags & SUPPORT_CLK_PARENT_CONTROL) 376 408 return __scmi_clk_set_parent(clk, parent); 377 409 378 410 /* Following Linux drivers/clk/clk-scmi.c, directly return 0 if agent has no permission. */
+2 -2
drivers/firmware/scmi/sandbox-scmi_agent.c
··· 828 828 829 829 static int sandbox_scmi_clock_gate(struct udevice *dev, struct scmi_msg *msg) 830 830 { 831 - struct scmi_clk_state_in *in = NULL; 831 + struct scmi_clk_state_in_v1 *in = NULL; 832 832 struct scmi_clk_state_out *out = NULL; 833 833 struct sandbox_scmi_clk *clk_state = NULL; 834 834 ··· 836 836 !msg->out_msg || msg->out_msg_sz < sizeof(*out)) 837 837 return -EINVAL; 838 838 839 - in = (struct scmi_clk_state_in *)msg->in_msg; 839 + in = (struct scmi_clk_state_in_v1 *)msg->in_msg; 840 840 out = (struct scmi_clk_state_out *)msg->out_msg; 841 841 842 842 clk_state = get_scmi_clk_state(in->clock_id);
-14
drivers/firmware/scmi/smt.c
··· 61 61 if (device_is_compatible(dev, "arm,scmi") && ofnode_has_property(dev_ofnode(dev), "mboxes")) 62 62 scmi_smt_enable_intr(smt, true); 63 63 64 - #ifdef CONFIG_ARM 65 - if (dcache_status()) { 66 - u32 align_size; 67 - 68 - if (IS_ENABLED(CONFIG_ARM64)) 69 - align_size = PAGE_SIZE; 70 - else 71 - align_size = MMU_SECTION_SIZE; 72 - 73 - mmu_set_region_dcache_behaviour(ALIGN_DOWN((uintptr_t)smt->buf, align_size), 74 - ALIGN(smt->size, align_size), DCACHE_OFF); 75 - } 76 - #endif 77 - 78 64 return 0; 79 65 } 80 66
+26 -11
include/scmi_protocols.h
··· 399 399 int scmi_base_protocol_version(struct udevice *dev, u32 *version); 400 400 401 401 /** 402 - * scmi_protocol_attrs - get protocol attributes 402 + * scmi_base_protocol_attrs - get protocol attributes 403 403 * @dev: SCMI protocol device 404 404 * @num_agents: Number of SCMI agents 405 405 * @num_protocols: Number of SCMI protocols ··· 414 414 u32 *num_protocols); 415 415 416 416 /** 417 - * scmi_protocol_message_attrs - get message-specific attributes 417 + * scmi_base_protocol_message_attrs - get message-specific attributes 418 418 * @dev: SCMI protocol device 419 419 * @message_id: SCMI message ID 420 420 * @attributes: Message-specific attributes ··· 733 733 /* 734 734 * SCMI Clock Protocol 735 735 */ 736 + #define CLOCK_PROTOCOL_VERSION_2_1 0x20001 736 737 #define CLOCK_PROTOCOL_VERSION_3_0 0x30000 737 738 738 739 enum scmi_clock_message_id { ··· 754 755 #define SCMI_CLOCK_NAME_LENGTH_MAX 16 755 756 756 757 /** 757 - * struct scmi_clk_get_nb_out - Response for SCMI_PROTOCOL_ATTRIBUTES command 758 + * struct scmi_clk_protocol_attr_out - Response for SCMI_PROTOCOL_ATTRIBUTES command 758 759 * @status: SCMI command status 759 760 * @attributes: Attributes of the clock protocol, mainly number of clocks exposed 760 761 */ ··· 772 773 }; 773 774 774 775 /** 775 - * struct scmi_clk_get_nb_out - Response payload for SCMI_CLOCK_ATTRIBUTES command 776 + * struct scmi_clk_attribute_out - Response payload for SCMI_CLOCK_ATTRIBUTES command 776 777 * @status: SCMI command status 777 778 * @attributes: clock attributes 778 779 * @clock_name: name of the clock ··· 785 786 }; 786 787 787 788 /** 788 - * struct scmi_clk_get_nb_out_v2 - Response payload for SCMI_CLOCK_ATTRIBUTES command 789 + * struct scmi_clk_attribute_out_v2 - Response payload for SCMI_CLOCK_ATTRIBUTES command 789 790 * Clock management Protocol 2.0 790 791 * @status: SCMI command status 791 792 * @attributes: clock attributes ··· 800 801 }; 801 802 802 803 /** 803 - * struct scmi_clk_state_in - Message payload for CLOCK_CONFIG_SET command 804 + * struct scmi_clk_state_in_v1 - Message payload for CLOCK_CONFIG_SET command for protocol < 2.1 805 + * @clock_id: SCMI clock ID 806 + * @attributes: Attributes of the targets clock state 807 + */ 808 + struct scmi_clk_state_in_v1 { 809 + u32 clock_id; 810 + u32 attributes; 811 + }; 812 + 813 + /** 814 + * struct scmi_clk_state_in_v2 - Message payload for CLOCK_CONFIG_SET command for protocol >= 2.1 804 815 * @clock_id: SCMI clock ID 805 816 * @attributes: Attributes of the targets clock state 817 + * @extended_config_val: Extended and OEM specific configuration 806 818 */ 807 - struct scmi_clk_state_in { 819 + struct scmi_clk_state_in_v2 { 808 820 u32 clock_id; 809 821 u32 attributes; 822 + u32 extended_config_val; 810 823 }; 811 824 812 825 /** ··· 818 831 }; 819 832 820 833 /** 821 - * struct scmi_clk_state_in - Message payload for CLOCK_RATE_GET command 834 + * struct scmi_clk_rate_get_in - Message payload for CLOCK_RATE_GET command 822 835 * @clock_id: SCMI clock ID 823 836 * @attributes: Attributes of the targets clock state 824 837 */ ··· 839 852 }; 840 853 841 854 /** 842 - * struct scmi_clk_state_in - Message payload for CLOCK_RATE_SET command 855 + * struct scmi_clk_rate_set_in - Message payload for CLOCK_RATE_SET command 843 856 * @flags: Flags for the clock rate set request 844 857 * @clock_id: SCMI clock ID 845 858 * @rate_lsb: 32bit LSB of the clock rate in Hertz ··· 861 874 }; 862 875 863 876 /** 864 - * struct scmi_clk_parent_state_in - Message payload for CLOCK_PARENT_SET command 877 + * struct scmi_clk_parent_set_in - Message payload for CLOCK_PARENT_SET command 865 878 * @clock_id: SCMI clock ID 866 879 * @parent_clk: SCMI clock ID 867 880 */ ··· 879 892 }; 880 893 881 894 /** 895 + * struct scmi_clk_get_permissions_in - Message payload for CLOCK_GET_PERMISSIONS command 882 896 * @clock_id: Identifier for the clock device. 883 897 */ 884 898 struct scmi_clk_get_permissions_in { ··· 886 900 }; 887 901 888 902 /** 903 + * struct scmi_clk_get_permissions_out - Response payload for CLOCK_GET_PERMISSIONS command 889 904 * @status: Negative 32-bit integers are used to return error status codes. 890 905 * @permissions: Bit[31] Clock state control, Bit[30] Clock parent control, 891 906 * Bit[29] Clock rate control, Bits[28:0] Reserved, must be zero. ··· 1082 1097 }; 1083 1098 1084 1099 /** 1085 - * struct scmi_pad_config_set_in - Message payload for PAD_CONFIG_SET command 1100 + * struct scmi_pinctrl_config_set_in - Message payload for PAD_CONFIG_SET command 1086 1101 * @identifier: Identifier for the pin or group. 1087 1102 * @function_id: Identifier for the function selected to be enabled 1088 1103 * for the selected pin or group. This field is set to