1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright 2020 B&R Industrial Automation GmbH - http://www.br-automation.com
9 #include <asm/arch/fsp_bindings.h>
12 * read_u8_prop() - Read an u8 property from devicetree (scalar or array)
13 * @node: Valid node reference to read property from
14 * @name: Name of the property to read from
15 * @count: If the property is expected to be an array, this is the
16 * number of expected elements
17 * Set to 0 if the property is expected to be a scalar
18 * @dst: Pointer to destination of where to save the value(s) read
21 static void read_u8_prop(ofnode node, char *name, size_t count, u8 *dst)
28 ret = ofnode_read_u32(node, name, &tmp);
32 buf = ofnode_read_u8_array_ptr(node, name, count);
34 memcpy(dst, buf, count);
39 * read_u16_prop() - Read an u16 property from devicetree (scalar or array)
40 * @node: Valid node reference to read property from
41 * @name: Name of the property to read from
42 * @count: If the property is expected to be an array, this is the
43 * number of expected elements
44 * Set to 0 if the property is expected to be a scalar
45 * @dst: Pointer to destination of where to save the value(s) read
47 * @return 0 on success, -ve on error
49 static int read_u16_prop(ofnode node, char *name, size_t count, u16 *dst)
55 if (ARRAY_SIZE(buf) < count) {
56 debug("ERROR: %s buffer to small!\n", __func__);
61 ret = ofnode_read_u32(node, name, &tmp);
65 ret = ofnode_read_u32_array(node, name, buf, count);
67 for (int i = 0; i < count; i++)
75 * read_u32_prop() - Read an u32 property from devicetree (scalar or array)
76 * @node: Valid node reference to read property from
77 * @name: Name of the property to read from
78 * @count: If the property is expected to be an array, this is the
79 * number of expected elements
80 * set to 0 if the property is expected to be a scalar
81 * @dst: Pointer to destination of where to save the value(s) read
84 static void read_u32_prop(ofnode node, char *name, size_t count, u32 *dst)
87 ofnode_read_u32(node, name, dst);
89 ofnode_read_u32_array(node, name, dst, count);
93 * read_string_prop() - Read a string property from devicetree
94 * @node: Valid node reference to read property from
95 * @name: Name of the property to read from
96 * @count: Size of the destination buffer
97 * @dst: Pointer to destination of where to save the values read
100 static void read_string_prop(ofnode node, char *name, size_t count, char *dst)
102 const char *string_buf;
105 string_buf = ofnode_read_string(node, name);
107 strlcpy(dst, string_buf, count);
112 * read_swizzle_prop() - Read a swizzle property from devicetree
113 * @node: Valid node reference to read property from
114 * @name: Name of the property to read from
115 * @count: Number of elements in the swizzle configuration
116 * @dst: pointer to destination of where to save the values read
119 static void read_swizzle_prop(ofnode node, char *name, size_t count, u8 *dst)
121 const struct lpddr4_chan_swizzle_cfg *sch;
122 /* Number of bytes to copy per DQS */
123 const size_t sz = DQ_BITS_PER_DQS;
124 const struct lpddr4_swizzle_cfg *swizzle_cfg;
126 swizzle_cfg = (const struct lpddr4_swizzle_cfg *)
127 ofnode_read_u8_array_ptr(node, name, count);
132 * CH0_DQB byte lanes in the bit swizzle configuration field are
133 * not 1:1. The mapping within the swizzling field is:
134 * indices [0:7] - byte lane 1 (DQS1) DQ[8:15]
135 * indices [8:15] - byte lane 0 (DQS0) DQ[0:7]
136 * indices [16:23] - byte lane 3 (DQS3) DQ[24:31]
137 * indices [24:31] - byte lane 2 (DQS2) DQ[16:23]
139 sch = &swizzle_cfg->phys[LP4_PHYS_CH0B];
140 memcpy(&dst[0 * DQ_BITS_PER_DQS], &sch->dqs[LP4_DQS1], sz);
141 memcpy(&dst[1 * DQ_BITS_PER_DQS], &sch->dqs[LP4_DQS0], sz);
142 memcpy(&dst[2 * DQ_BITS_PER_DQS], &sch->dqs[LP4_DQS3], sz);
143 memcpy(&dst[3 * DQ_BITS_PER_DQS], &sch->dqs[LP4_DQS2], sz);
146 * CH0_DQA byte lanes in the bit swizzle configuration field are 1:1.
148 sch = &swizzle_cfg->phys[LP4_PHYS_CH0A];
149 memcpy(&dst[4 * DQ_BITS_PER_DQS], &sch->dqs[LP4_DQS0], sz);
150 memcpy(&dst[5 * DQ_BITS_PER_DQS], &sch->dqs[LP4_DQS1], sz);
151 memcpy(&dst[6 * DQ_BITS_PER_DQS], &sch->dqs[LP4_DQS2], sz);
152 memcpy(&dst[7 * DQ_BITS_PER_DQS], &sch->dqs[LP4_DQS3], sz);
154 sch = &swizzle_cfg->phys[LP4_PHYS_CH1B];
155 memcpy(&dst[8 * DQ_BITS_PER_DQS], &sch->dqs[LP4_DQS1], sz);
156 memcpy(&dst[9 * DQ_BITS_PER_DQS], &sch->dqs[LP4_DQS0], sz);
157 memcpy(&dst[10 * DQ_BITS_PER_DQS], &sch->dqs[LP4_DQS3], sz);
158 memcpy(&dst[11 * DQ_BITS_PER_DQS], &sch->dqs[LP4_DQS2], sz);
161 * CH0_DQA byte lanes in the bit swizzle configuration field are 1:1.
163 sch = &swizzle_cfg->phys[LP4_PHYS_CH1A];
164 memcpy(&dst[12 * DQ_BITS_PER_DQS], &sch->dqs[LP4_DQS0], sz);
165 memcpy(&dst[13 * DQ_BITS_PER_DQS], &sch->dqs[LP4_DQS1], sz);
166 memcpy(&dst[14 * DQ_BITS_PER_DQS], &sch->dqs[LP4_DQS2], sz);
167 memcpy(&dst[15 * DQ_BITS_PER_DQS], &sch->dqs[LP4_DQS3], sz);
171 * fsp_update_config_from_dtb() - Read FSP config from devicetree node
172 * @node: Valid node reference to read property from
173 * @cfg: Pointer to FSP config structure
174 * @fsp_bindings: Binding describing which devicetree properties should
175 * be stored where in the FSP configuration structure
176 * The end of the list is declared by a NULL pointer in propname
177 * @return 0 on success, -ve on error
179 * This function reads the configuration for FSP from the provided
180 * devicetree node and saves it in the FSP configuration structure.
181 * Configuration options that are not present in the devicetree are
182 * left at their current value.
185 static int fsp_update_config_from_dtb(ofnode node, u8 *cfg,
186 const struct fsp_binding *fsp_bindings)
188 const struct fsp_binding *fspb;
191 for (int i = 0; fsp_bindings[i].propname; i++) {
192 fspb = &fsp_bindings[i];
194 switch (fspb->type) {
196 read_u8_prop(node, fspb->propname, fspb->count,
200 ret = read_u16_prop(node, fspb->propname, fspb->count,
201 (u16 *)&cfg[fspb->offset]);
206 read_u32_prop(node, fspb->propname, fspb->count,
207 (u32 *)&cfg[fspb->offset]);
210 read_string_prop(node, fspb->propname, fspb->count,
211 (char *)&cfg[fspb->offset]);
213 case FSP_LPDDR4_SWIZZLE:
214 read_swizzle_prop(node, fspb->propname, fspb->count,
223 #if defined(CONFIG_SPL_BUILD)
224 const struct fsp_binding fsp_m_bindings[] = {
227 .offset = offsetof(struct fsp_m_config, serial_debug_port_address),
228 .propname = "fspm,serial-debug-port-address",
231 .offset = offsetof(struct fsp_m_config, serial_debug_port_type),
232 .propname = "fspm,serial-debug-port-type",
235 .offset = offsetof(struct fsp_m_config, serial_debug_port_device),
236 .propname = "fspm,serial-debug-port-device",
239 .offset = offsetof(struct fsp_m_config, serial_debug_port_stride_size),
240 .propname = "fspm,serial-debug-port-stride-size",
243 .offset = offsetof(struct fsp_m_config, mrc_fast_boot),
244 .propname = "fspm,mrc-fast-boot",
247 .offset = offsetof(struct fsp_m_config, igd),
248 .propname = "fspm,igd",
251 .offset = offsetof(struct fsp_m_config, igd_dvmt50_pre_alloc),
252 .propname = "fspm,igd-dvmt50-pre-alloc",
255 .offset = offsetof(struct fsp_m_config, igd_aperture_size),
256 .propname = "fspm,igd-aperture-size",
259 .offset = offsetof(struct fsp_m_config, gtt_size),
260 .propname = "fspm,gtt-size",
263 .offset = offsetof(struct fsp_m_config, primary_video_adaptor),
264 .propname = "fspm,primary-video-adaptor",
267 .offset = offsetof(struct fsp_m_config, package),
268 .propname = "fspm,package",
271 .offset = offsetof(struct fsp_m_config, profile),
272 .propname = "fspm,profile",
275 .offset = offsetof(struct fsp_m_config, memory_down),
276 .propname = "fspm,memory-down",
279 .offset = offsetof(struct fsp_m_config, ddr3_l_page_size),
280 .propname = "fspm,ddr3-l-page-size",
283 .offset = offsetof(struct fsp_m_config, ddr3_lasr),
284 .propname = "fspm,ddr3-lasr",
287 .offset = offsetof(struct fsp_m_config, scrambler_support),
288 .propname = "fspm,scrambler-support",
291 .offset = offsetof(struct fsp_m_config, interleaved_mode),
292 .propname = "fspm,interleaved-mode",
295 .offset = offsetof(struct fsp_m_config, channel_hash_mask),
296 .propname = "fspm,channel-hash-mask",
299 .offset = offsetof(struct fsp_m_config, slice_hash_mask),
300 .propname = "fspm,slice-hash-mask",
303 .offset = offsetof(struct fsp_m_config, channels_slices_enable),
304 .propname = "fspm,channels-slices-enable",
307 .offset = offsetof(struct fsp_m_config, min_ref_rate2x_enable),
308 .propname = "fspm,min-ref-rate2x-enable",
311 .offset = offsetof(struct fsp_m_config, dual_rank_support_enable),
312 .propname = "fspm,dual-rank-support-enable",
315 .offset = offsetof(struct fsp_m_config, rmt_mode),
316 .propname = "fspm,rmt-mode",
319 .offset = offsetof(struct fsp_m_config, memory_size_limit),
320 .propname = "fspm,memory-size-limit",
323 .offset = offsetof(struct fsp_m_config, low_memory_max_value),
324 .propname = "fspm,low-memory-max-value",
327 .offset = offsetof(struct fsp_m_config, high_memory_max_value),
328 .propname = "fspm,high-memory-max-value",
331 .offset = offsetof(struct fsp_m_config, disable_fast_boot),
332 .propname = "fspm,disable-fast-boot",
335 .offset = offsetof(struct fsp_m_config, dimm0_spd_address),
336 .propname = "fspm,dimm0-spd-address",
339 .offset = offsetof(struct fsp_m_config, dimm1_spd_address),
340 .propname = "fspm,dimm1-spd-address",
343 .offset = offsetof(struct fsp_m_config, chan[0].rank_enable),
344 .propname = "fspm,ch0-rank-enable",
347 .offset = offsetof(struct fsp_m_config, chan[0].device_width),
348 .propname = "fspm,ch0-device-width",
351 .offset = offsetof(struct fsp_m_config, chan[0].dram_density),
352 .propname = "fspm,ch0-dram-density",
355 .offset = offsetof(struct fsp_m_config, chan[0].option),
356 .propname = "fspm,ch0-option",
359 .offset = offsetof(struct fsp_m_config, chan[0].odt_config),
360 .propname = "fspm,ch0-odt-config",
363 .offset = offsetof(struct fsp_m_config, chan[0].tristate_clk1),
364 .propname = "fspm,ch0-tristate-clk1",
367 .offset = offsetof(struct fsp_m_config, chan[0].mode2_n),
368 .propname = "fspm,ch0-mode2-n",
371 .offset = offsetof(struct fsp_m_config, chan[0].odt_levels),
372 .propname = "fspm,ch0-odt-levels",
375 .offset = offsetof(struct fsp_m_config, chan[1].rank_enable),
376 .propname = "fspm,ch1-rank-enable",
379 .offset = offsetof(struct fsp_m_config, chan[1].device_width),
380 .propname = "fspm,ch1-device-width",
383 .offset = offsetof(struct fsp_m_config, chan[1].dram_density),
384 .propname = "fspm,ch1-dram-density",
387 .offset = offsetof(struct fsp_m_config, chan[1].option),
388 .propname = "fspm,ch1-option",
391 .offset = offsetof(struct fsp_m_config, chan[1].odt_config),
392 .propname = "fspm,ch1-odt-config",
395 .offset = offsetof(struct fsp_m_config, chan[1].tristate_clk1),
396 .propname = "fspm,ch1-tristate-clk1",
399 .offset = offsetof(struct fsp_m_config, chan[1].mode2_n),
400 .propname = "fspm,ch1-mode2-n",
403 .offset = offsetof(struct fsp_m_config, chan[1].odt_levels),
404 .propname = "fspm,ch1-odt-levels",
407 .offset = offsetof(struct fsp_m_config, chan[2].rank_enable),
408 .propname = "fspm,ch2-rank-enable",
411 .offset = offsetof(struct fsp_m_config, chan[2].device_width),
412 .propname = "fspm,ch2-device-width",
415 .offset = offsetof(struct fsp_m_config, chan[2].dram_density),
416 .propname = "fspm,ch2-dram-density",
419 .offset = offsetof(struct fsp_m_config, chan[2].option),
420 .propname = "fspm,ch2-option",
423 .offset = offsetof(struct fsp_m_config, chan[2].odt_config),
424 .propname = "fspm,ch2-odt-config",
427 .offset = offsetof(struct fsp_m_config, chan[2].tristate_clk1),
428 .propname = "fspm,ch2-tristate-clk1",
431 .offset = offsetof(struct fsp_m_config, chan[2].mode2_n),
432 .propname = "fspm,ch2-mode2-n",
435 .offset = offsetof(struct fsp_m_config, chan[2].odt_levels),
436 .propname = "fspm,ch2-odt-levels",
439 .offset = offsetof(struct fsp_m_config, chan[3].rank_enable),
440 .propname = "fspm,ch3-rank-enable",
443 .offset = offsetof(struct fsp_m_config, chan[3].device_width),
444 .propname = "fspm,ch3-device-width",
447 .offset = offsetof(struct fsp_m_config, chan[3].dram_density),
448 .propname = "fspm,ch3-dram-density",
451 .offset = offsetof(struct fsp_m_config, chan[3].option),
452 .propname = "fspm,ch3-option",
455 .offset = offsetof(struct fsp_m_config, chan[3].odt_config),
456 .propname = "fspm,ch3-odt-config",
459 .offset = offsetof(struct fsp_m_config, chan[3].tristate_clk1),
460 .propname = "fspm,ch3-tristate-clk1",
463 .offset = offsetof(struct fsp_m_config, chan[3].mode2_n),
464 .propname = "fspm,ch3-mode2-n",
467 .offset = offsetof(struct fsp_m_config, chan[3].odt_levels),
468 .propname = "fspm,ch3-odt-levels",
471 .offset = offsetof(struct fsp_m_config, rmt_check_run),
472 .propname = "fspm,rmt-check-run",
475 .offset = offsetof(struct fsp_m_config,
476 rmt_margin_check_scale_high_threshold),
477 .propname = "fspm,rmt-margin-check-scale-high-threshold",
479 .type = FSP_LPDDR4_SWIZZLE,
480 .offset = offsetof(struct fsp_m_config, ch_bit_swizzling),
481 .propname = "fspm,ch-bit-swizzling",
482 .count = SIZE_OF_MEMBER(struct fsp_m_config, ch_bit_swizzling) /
483 SIZE_OF_MEMBER(struct fsp_m_config, ch_bit_swizzling[0][0])
486 .offset = offsetof(struct fsp_m_config, msg_level_mask),
487 .propname = "fspm,msg-level-mask",
490 .offset = offsetof(struct fsp_m_config, pre_mem_gpio_table_pin_num),
491 .propname = "fspm,pre-mem-gpio-table-pin-num",
492 .count = ARRAY_SIZE_OF_MEMBER(struct fsp_m_config,
493 pre_mem_gpio_table_pin_num),
496 .offset = offsetof(struct fsp_m_config, pre_mem_gpio_table_ptr),
497 .propname = "fspm,pre-mem-gpio-table-ptr",
500 .offset = offsetof(struct fsp_m_config, pre_mem_gpio_table_entry_num),
501 .propname = "fspm,pre-mem-gpio-table-entry-num",
504 .offset = offsetof(struct fsp_m_config, enhance_port8xh_decoding),
505 .propname = "fspm,enhance-port8xh-decoding",
508 .offset = offsetof(struct fsp_m_config, spd_write_enable),
509 .propname = "fspm,spd-write-enable",
512 .offset = offsetof(struct fsp_m_config, mrc_data_saving),
513 .propname = "fspm,mrc-data-saving",
516 .offset = offsetof(struct fsp_m_config, oem_loading_base),
517 .propname = "fspm,oem-loading-base",
520 .offset = offsetof(struct fsp_m_config, oem_file_name),
521 .propname = "fspm,oem-file-name",
522 .count = ARRAY_SIZE_OF_MEMBER(struct fsp_m_config, oem_file_name),
525 .offset = offsetof(struct fsp_m_config, mrc_boot_data_ptr),
526 .propname = "fspm,mrc-boot-data-ptr",
529 .offset = offsetof(struct fsp_m_config, e_mmc_trace_len),
530 .propname = "fspm,e-mmc-trace-len",
533 .offset = offsetof(struct fsp_m_config, skip_cse_rbp),
534 .propname = "fspm,skip-cse-rbp",
537 .offset = offsetof(struct fsp_m_config, npk_en),
538 .propname = "fspm,npk-en",
541 .offset = offsetof(struct fsp_m_config, fw_trace_en),
542 .propname = "fspm,fw-trace-en",
545 .offset = offsetof(struct fsp_m_config, fw_trace_destination),
546 .propname = "fspm,fw-trace-destination",
549 .offset = offsetof(struct fsp_m_config, recover_dump),
550 .propname = "fspm,recover-dump",
553 .offset = offsetof(struct fsp_m_config, msc0_wrap),
554 .propname = "fspm,msc0-wrap",
557 .offset = offsetof(struct fsp_m_config, msc1_wrap),
558 .propname = "fspm,msc1-wrap",
561 .offset = offsetof(struct fsp_m_config, msc0_size),
562 .propname = "fspm,msc0-size",
565 .offset = offsetof(struct fsp_m_config, msc1_size),
566 .propname = "fspm,msc1-size",
569 .offset = offsetof(struct fsp_m_config, pti_mode),
570 .propname = "fspm,pti-mode",
573 .offset = offsetof(struct fsp_m_config, pti_training),
574 .propname = "fspm,pti-training",
577 .offset = offsetof(struct fsp_m_config, pti_speed),
578 .propname = "fspm,pti-speed",
581 .offset = offsetof(struct fsp_m_config, punit_mlvl),
582 .propname = "fspm,punit-mlvl",
585 .offset = offsetof(struct fsp_m_config, pmc_mlvl),
586 .propname = "fspm,pmc-mlvl",
589 .offset = offsetof(struct fsp_m_config, sw_trace_en),
590 .propname = "fspm,sw-trace-en",
593 .offset = offsetof(struct fsp_m_config, periodic_retraining_disable),
594 .propname = "fspm,periodic-retraining-disable",
597 .offset = offsetof(struct fsp_m_config, enable_reset_system),
598 .propname = "fspm,enable-reset-system",
601 .offset = offsetof(struct fsp_m_config, enable_s3_heci2),
602 .propname = "fspm,enable-s3-heci2",
605 .offset = offsetof(struct fsp_m_config, variable_nvs_buffer_ptr),
606 .propname = "fspm,variable-nvs-buffer-ptr",
612 int fsp_m_update_config_from_dtb(ofnode node, struct fsp_m_config *cfg)
614 return fsp_update_config_from_dtb(node, (u8 *)cfg, fsp_m_bindings);