1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <device/mmio.h>
4 #include <device/pci_ops.h>
5 #include <console/console.h>
7 #include <device/device.h>
8 #include <device/resource.h>
9 #include <device/pci.h>
11 #include <reg_script.h>
14 #include <cpu/x86/msr.h>
24 #define HAS_IOSF (CONFIG(SOC_INTEL_BAYTRAIL))
27 #include <soc/iosf.h> /* TODO: wrap in <soc/reg_script.h, remove #ifdef? */
30 #define POLL_DELAY 100 /* 100us */
32 #ifdef __SIMPLE_DEVICE__
35 #define EMPTY_DEV NULL
38 #ifdef __SIMPLE_DEVICE__
39 static inline void reg_script_set_dev(struct reg_script_context
*ctx
,
42 static inline void reg_script_set_dev(struct reg_script_context
*ctx
,
50 static inline void reg_script_set_step(struct reg_script_context
*ctx
,
51 const struct reg_script
*step
)
56 static inline const struct reg_script
*
57 reg_script_get_step(struct reg_script_context
*ctx
)
62 static struct resource
*reg_script_get_resource(struct reg_script_context
*ctx
)
64 #ifdef __SIMPLE_DEVICE__
68 const struct reg_script
*step
= reg_script_get_step(ctx
);
72 if (res
!= NULL
&& res
->index
== step
->res_index
)
75 res
= find_resource(ctx
->dev
, step
->res_index
);
81 static uint32_t reg_script_read_pci(struct reg_script_context
*ctx
)
83 const struct reg_script
*step
= reg_script_get_step(ctx
);
86 case REG_SCRIPT_SIZE_8
:
87 return pci_read_config8(ctx
->dev
, step
->reg
);
88 case REG_SCRIPT_SIZE_16
:
89 return pci_read_config16(ctx
->dev
, step
->reg
);
90 case REG_SCRIPT_SIZE_32
:
91 return pci_read_config32(ctx
->dev
, step
->reg
);
96 static void reg_script_write_pci(struct reg_script_context
*ctx
)
98 const struct reg_script
*step
= reg_script_get_step(ctx
);
100 switch (step
->size
) {
101 case REG_SCRIPT_SIZE_8
:
102 pci_write_config8(ctx
->dev
, step
->reg
, step
->value
);
104 case REG_SCRIPT_SIZE_16
:
105 pci_write_config16(ctx
->dev
, step
->reg
, step
->value
);
107 case REG_SCRIPT_SIZE_32
:
108 pci_write_config32(ctx
->dev
, step
->reg
, step
->value
);
114 static uint32_t reg_script_read_io(struct reg_script_context
*ctx
)
116 const struct reg_script
*step
= reg_script_get_step(ctx
);
118 switch (step
->size
) {
119 case REG_SCRIPT_SIZE_8
:
120 return inb(step
->reg
);
121 case REG_SCRIPT_SIZE_16
:
122 return inw(step
->reg
);
123 case REG_SCRIPT_SIZE_32
:
124 return inl(step
->reg
);
129 static void reg_script_write_io(struct reg_script_context
*ctx
)
131 const struct reg_script
*step
= reg_script_get_step(ctx
);
133 switch (step
->size
) {
134 case REG_SCRIPT_SIZE_8
:
135 outb(step
->value
, step
->reg
);
137 case REG_SCRIPT_SIZE_16
:
138 outw(step
->value
, step
->reg
);
140 case REG_SCRIPT_SIZE_32
:
141 outl(step
->value
, step
->reg
);
147 static uint32_t reg_script_read_mmio(struct reg_script_context
*ctx
)
149 const struct reg_script
*step
= reg_script_get_step(ctx
);
151 switch (step
->size
) {
152 case REG_SCRIPT_SIZE_8
:
153 return read8((u8
*)(uintptr_t)step
->reg
);
154 case REG_SCRIPT_SIZE_16
:
155 return read16((u16
*)(uintptr_t)step
->reg
);
156 case REG_SCRIPT_SIZE_32
:
157 return read32((u32
*)(uintptr_t)step
->reg
);
162 static void reg_script_write_mmio(struct reg_script_context
*ctx
)
164 const struct reg_script
*step
= reg_script_get_step(ctx
);
166 switch (step
->size
) {
167 case REG_SCRIPT_SIZE_8
:
168 write8((u8
*)(uintptr_t)step
->reg
, step
->value
);
170 case REG_SCRIPT_SIZE_16
:
171 write16((u16
*)(uintptr_t)step
->reg
, step
->value
);
173 case REG_SCRIPT_SIZE_32
:
174 write32((u32
*)(uintptr_t)step
->reg
, step
->value
);
179 static uint32_t reg_script_read_res(struct reg_script_context
*ctx
)
181 struct resource
*res
;
183 const struct reg_script
*step
= reg_script_get_step(ctx
);
185 res
= reg_script_get_resource(ctx
);
190 if (res
->flags
& IORESOURCE_IO
) {
191 const struct reg_script io_step
= {
193 .reg
= res
->base
+ step
->reg
,
195 reg_script_set_step(ctx
, &io_step
);
196 val
= reg_script_read_io(ctx
);
197 } else if (res
->flags
& IORESOURCE_MEM
) {
198 const struct reg_script mmio_step
= {
200 .reg
= res
->base
+ step
->reg
,
202 reg_script_set_step(ctx
, &mmio_step
);
203 val
= reg_script_read_mmio(ctx
);
205 reg_script_set_step(ctx
, step
);
209 static void reg_script_write_res(struct reg_script_context
*ctx
)
211 struct resource
*res
;
212 const struct reg_script
*step
= reg_script_get_step(ctx
);
214 res
= reg_script_get_resource(ctx
);
219 if (res
->flags
& IORESOURCE_IO
) {
220 const struct reg_script io_step
= {
222 .reg
= res
->base
+ step
->reg
,
223 .value
= step
->value
,
225 reg_script_set_step(ctx
, &io_step
);
226 reg_script_write_io(ctx
);
227 } else if (res
->flags
& IORESOURCE_MEM
) {
228 const struct reg_script mmio_step
= {
230 .reg
= res
->base
+ step
->reg
,
231 .value
= step
->value
,
233 reg_script_set_step(ctx
, &mmio_step
);
234 reg_script_write_mmio(ctx
);
236 reg_script_set_step(ctx
, step
);
240 static uint32_t reg_script_read_iosf(struct reg_script_context
*ctx
)
242 const struct reg_script
*step
= reg_script_get_step(ctx
);
245 case IOSF_PORT_AUNIT
:
246 return iosf_aunit_read(step
->reg
);
247 case IOSF_PORT_CPU_BUS
:
248 return iosf_cpu_bus_read(step
->reg
);
249 case IOSF_PORT_BUNIT
:
250 return iosf_bunit_read(step
->reg
);
251 case IOSF_PORT_DUNIT_CH0
:
252 return iosf_dunit_ch0_read(step
->reg
);
254 return iosf_punit_read(step
->reg
);
255 case IOSF_PORT_USBPHY
:
256 return iosf_usbphy_read(step
->reg
);
258 return iosf_sec_read(step
->reg
);
260 return iosf_port45_read(step
->reg
);
262 return iosf_port46_read(step
->reg
);
264 return iosf_port47_read(step
->reg
);
265 case IOSF_PORT_SCORE
:
266 return iosf_score_read(step
->reg
);
268 return iosf_port55_read(step
->reg
);
270 return iosf_port58_read(step
->reg
);
272 return iosf_port59_read(step
->reg
);
274 return iosf_port5a_read(step
->reg
);
275 case IOSF_PORT_USHPHY
:
276 return iosf_ushphy_read(step
->reg
);
278 return iosf_scc_read(step
->reg
);
280 return iosf_lpss_read(step
->reg
);
282 return iosf_porta2_read(step
->reg
);
284 return iosf_ccu_read(step
->reg
);
286 return iosf_ssus_read(step
->reg
);
288 printk(BIOS_DEBUG
, "No read support for IOSF port 0x%x.\n",
295 static void reg_script_write_iosf(struct reg_script_context
*ctx
)
297 const struct reg_script
*step
= reg_script_get_step(ctx
);
300 case IOSF_PORT_AUNIT
:
301 iosf_aunit_write(step
->reg
, step
->value
);
303 case IOSF_PORT_CPU_BUS
:
304 iosf_cpu_bus_write(step
->reg
, step
->value
);
306 case IOSF_PORT_BUNIT
:
307 iosf_bunit_write(step
->reg
, step
->value
);
309 case IOSF_PORT_DUNIT_CH0
:
310 iosf_dunit_write(step
->reg
, step
->value
);
313 iosf_punit_write(step
->reg
, step
->value
);
315 case IOSF_PORT_USBPHY
:
316 iosf_usbphy_write(step
->reg
, step
->value
);
319 iosf_sec_write(step
->reg
, step
->value
);
322 iosf_port45_write(step
->reg
, step
->value
);
325 iosf_port46_write(step
->reg
, step
->value
);
328 iosf_port47_write(step
->reg
, step
->value
);
330 case IOSF_PORT_SCORE
:
331 iosf_score_write(step
->reg
, step
->value
);
334 iosf_port55_write(step
->reg
, step
->value
);
337 iosf_port58_write(step
->reg
, step
->value
);
340 iosf_port59_write(step
->reg
, step
->value
);
343 iosf_port5a_write(step
->reg
, step
->value
);
345 case IOSF_PORT_USHPHY
:
346 iosf_ushphy_write(step
->reg
, step
->value
);
349 iosf_scc_write(step
->reg
, step
->value
);
352 iosf_lpss_write(step
->reg
, step
->value
);
355 iosf_porta2_write(step
->reg
, step
->value
);
358 iosf_ccu_write(step
->reg
, step
->value
);
361 iosf_ssus_write(step
->reg
, step
->value
);
364 printk(BIOS_DEBUG
, "No write support for IOSF port 0x%x.\n",
369 #endif /* HAS_IOSF */
372 static uint64_t reg_script_read_msr(struct reg_script_context
*ctx
)
375 const struct reg_script
*step
= reg_script_get_step(ctx
);
376 msr_t msr
= rdmsr(step
->reg
);
377 uint64_t value
= msr
.hi
;
384 static void reg_script_write_msr(struct reg_script_context
*ctx
)
387 const struct reg_script
*step
= reg_script_get_step(ctx
);
389 msr
.hi
= step
->value
>> 32;
390 msr
.lo
= step
->value
& 0xffffffff;
391 wrmsr(step
->reg
, msr
);
395 /* Locate the structure containing the platform specific bus access routines */
396 static const struct reg_script_bus_entry
397 *find_bus(const struct reg_script
*step
)
399 extern const struct reg_script_bus_entry
*_rsbe_init_begin
[];
400 extern const struct reg_script_bus_entry
*_ersbe_init_begin
[];
401 const struct reg_script_bus_entry
* const *bus
;
402 size_t table_entries
;
405 /* Locate the platform specific bus */
406 bus
= _rsbe_init_begin
;
407 table_entries
= &_ersbe_init_begin
[0] - &_rsbe_init_begin
[0];
408 for (i
= 0; i
< table_entries
; i
++) {
409 if (bus
[i
]->type
== step
->type
)
417 static void reg_script_display(struct reg_script_context
*ctx
,
418 const struct reg_script
*step
, const char *arrow
, uint64_t value
)
420 /* Display the register address and data */
421 if (ctx
->display_prefix
!= NULL
)
422 printk(BIOS_INFO
, "%s: ", ctx
->display_prefix
);
423 if (ctx
->display_features
& REG_SCRIPT_DISPLAY_REGISTER
)
424 printk(BIOS_INFO
, "0x%08x %s ", step
->reg
, arrow
);
425 if (ctx
->display_features
& REG_SCRIPT_DISPLAY_VALUE
)
426 switch (step
->size
) {
427 case REG_SCRIPT_SIZE_8
:
428 printk(BIOS_INFO
, "0x%02x\n", (uint8_t)value
);
430 case REG_SCRIPT_SIZE_16
:
431 printk(BIOS_INFO
, "0x%04x\n", (int16_t)value
);
433 case REG_SCRIPT_SIZE_32
:
434 printk(BIOS_INFO
, "0x%08x\n", (uint32_t)value
);
437 printk(BIOS_INFO
, "0x%016llx\n", value
);
442 static uint64_t reg_script_read(struct reg_script_context
*ctx
)
444 const struct reg_script
*step
= reg_script_get_step(ctx
);
447 switch (step
->type
) {
448 case REG_SCRIPT_TYPE_PCI
:
449 ctx
->display_prefix
= "PCI";
450 value
= reg_script_read_pci(ctx
);
453 case REG_SCRIPT_TYPE_IO
:
454 ctx
->display_prefix
= "IO";
455 value
= reg_script_read_io(ctx
);
458 case REG_SCRIPT_TYPE_MMIO
:
459 ctx
->display_prefix
= "MMIO";
460 value
= reg_script_read_mmio(ctx
);
462 case REG_SCRIPT_TYPE_RES
:
463 ctx
->display_prefix
= "RES";
464 value
= reg_script_read_res(ctx
);
466 case REG_SCRIPT_TYPE_MSR
:
467 ctx
->display_prefix
= "MSR";
468 value
= reg_script_read_msr(ctx
);
471 case REG_SCRIPT_TYPE_IOSF
:
472 ctx
->display_prefix
= "IOSF";
473 value
= reg_script_read_iosf(ctx
);
475 #endif /* HAS_IOSF */
478 const struct reg_script_bus_entry
*bus
;
480 /* Read from the platform specific bus */
481 bus
= find_bus(step
);
483 value
= bus
->reg_script_read(ctx
);
488 "Unsupported read type (0x%x) for this device!\n",
493 /* Display the register address and data */
494 if (ctx
->display_features
)
495 reg_script_display(ctx
, step
, "-->", value
);
499 static void reg_script_write(struct reg_script_context
*ctx
)
501 const struct reg_script
*step
= reg_script_get_step(ctx
);
503 switch (step
->type
) {
504 case REG_SCRIPT_TYPE_PCI
:
505 ctx
->display_prefix
= "PCI";
506 reg_script_write_pci(ctx
);
509 case REG_SCRIPT_TYPE_IO
:
510 ctx
->display_prefix
= "IO";
511 reg_script_write_io(ctx
);
514 case REG_SCRIPT_TYPE_MMIO
:
515 ctx
->display_prefix
= "MMIO";
516 reg_script_write_mmio(ctx
);
518 case REG_SCRIPT_TYPE_RES
:
519 ctx
->display_prefix
= "RES";
520 reg_script_write_res(ctx
);
522 case REG_SCRIPT_TYPE_MSR
:
523 ctx
->display_prefix
= "MSR";
524 reg_script_write_msr(ctx
);
527 case REG_SCRIPT_TYPE_IOSF
:
528 ctx
->display_prefix
= "IOSF";
529 reg_script_write_iosf(ctx
);
531 #endif /* HAS_IOSF */
534 const struct reg_script_bus_entry
*bus
;
536 /* Write to the platform specific bus */
537 bus
= find_bus(step
);
539 bus
->reg_script_write(ctx
);
544 "Unsupported write type (0x%x) for this device!\n",
549 /* Display the register address and data */
550 if (ctx
->display_features
)
551 reg_script_display(ctx
, step
, "<--", step
->value
);
554 static void reg_script_rmw(struct reg_script_context
*ctx
)
557 const struct reg_script
*step
= reg_script_get_step(ctx
);
558 struct reg_script write_step
= *step
;
560 value
= reg_script_read(ctx
);
562 value
|= step
->value
;
563 write_step
.value
= value
;
564 reg_script_set_step(ctx
, &write_step
);
565 reg_script_write(ctx
);
566 reg_script_set_step(ctx
, step
);
569 static void reg_script_rxw(struct reg_script_context
*ctx
)
572 const struct reg_script
*step
= reg_script_get_step(ctx
);
573 struct reg_script write_step
= *step
;
583 * Supported operations
585 * Input Mask Temp XOR Value Operation
586 * 0 0 0 0 0 Clear bit
590 * 0 1 0 0 0 Preserve bit
592 * 0 1 0 1 1 Toggle bit
595 value
= reg_script_read(ctx
);
597 value
^= step
->value
;
598 write_step
.value
= value
;
599 reg_script_set_step(ctx
, &write_step
);
600 reg_script_write(ctx
);
601 reg_script_set_step(ctx
, step
);
604 /* In order to easily chain scripts together handle the REG_SCRIPT_COMMAND_NEXT
605 * as recursive call with a new context that has the same dev and resource
606 * as the previous one. That will run to completion and then move on to the
607 * next step of the previous context. */
608 static void reg_script_run_next(struct reg_script_context
*ctx
,
609 const struct reg_script
*step
);
612 static void reg_script_run_step(struct reg_script_context
*ctx
,
613 const struct reg_script
*step
)
615 uint64_t value
= 0, try;
617 ctx
->display_features
= ctx
->display_state
;
618 ctx
->display_prefix
= NULL
;
619 switch (step
->command
) {
620 case REG_SCRIPT_COMMAND_READ
:
621 (void)reg_script_read(ctx
);
623 case REG_SCRIPT_COMMAND_WRITE
:
624 reg_script_write(ctx
);
626 case REG_SCRIPT_COMMAND_RMW
:
629 case REG_SCRIPT_COMMAND_RXW
:
632 case REG_SCRIPT_COMMAND_POLL
:
633 for (try = 0; try < step
->timeout
; try += POLL_DELAY
) {
634 value
= reg_script_read(ctx
) & step
->mask
;
635 if (value
== step
->value
)
639 if (try >= step
->timeout
)
640 printk(BIOS_WARNING
, "%s: POLL timeout waiting for "
641 "0x%x to be 0x%lx, got 0x%lx\n", __func__
,
642 step
->reg
, (unsigned long)step
->value
,
643 (unsigned long)value
);
645 case REG_SCRIPT_COMMAND_SET_DEV
:
646 reg_script_set_dev(ctx
, step
->dev
);
648 case REG_SCRIPT_COMMAND_NEXT
:
649 reg_script_run_next(ctx
, step
->next
);
651 case REG_SCRIPT_COMMAND_DISPLAY
:
652 ctx
->display_state
= step
->value
;
656 printk(BIOS_WARNING
, "Invalid command: %08x\n",
662 static void reg_script_run_with_context(struct reg_script_context
*ctx
)
665 const struct reg_script
*step
= reg_script_get_step(ctx
);
667 if (step
->command
== REG_SCRIPT_COMMAND_END
)
670 reg_script_run_step(ctx
, step
);
671 reg_script_set_step(ctx
, step
+ 1);
675 static void reg_script_run_next(struct reg_script_context
*prev_ctx
,
676 const struct reg_script
*step
)
678 struct reg_script_context ctx
;
680 /* Use prev context as a basis but start at a new step. */
682 reg_script_set_step(&ctx
, step
);
683 reg_script_run_with_context(&ctx
);
686 #ifdef __SIMPLE_DEVICE__
687 void reg_script_run_on_dev(pci_devfn_t dev
, const struct reg_script
*step
)
689 void reg_script_run_on_dev(struct device
*dev
, const struct reg_script
*step
)
692 struct reg_script_context ctx
;
694 ctx
.display_state
= REG_SCRIPT_DISPLAY_NOTHING
;
695 reg_script_set_dev(&ctx
, dev
);
696 reg_script_set_step(&ctx
, step
);
697 reg_script_run_with_context(&ctx
);
700 void reg_script_run(const struct reg_script
*step
)
702 reg_script_run_on_dev(EMPTY_DEV
, step
);