2 * This file is part of the coreboot project.
4 * Copyright 2013 Google Inc.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
17 #include <console/console.h>
19 #include <device/device.h>
20 #include <device/resource.h>
21 #include <device/pci.h>
23 #include <reg_script.h>
26 #include <cpu/x86/msr.h>
29 #if CONFIG_SOC_INTEL_BAYTRAIL
30 #include <soc/iosf.h> /* TODO: wrap in <soc/reg_script.h, remove #ifdef? */
33 #define POLL_DELAY 100 /* 100us */
34 #if defined(__PRE_RAM__)
37 #define EMPTY_DEV NULL
40 static inline void reg_script_set_dev(struct reg_script_context
*ctx
,
47 static inline void reg_script_set_step(struct reg_script_context
*ctx
,
48 const struct reg_script
*step
)
53 static inline const struct reg_script
*
54 reg_script_get_step(struct reg_script_context
*ctx
)
59 static struct resource
*reg_script_get_resource(struct reg_script_context
*ctx
)
61 #if defined(__PRE_RAM__)
65 const struct reg_script
*step
= reg_script_get_step(ctx
);
69 if (res
!= NULL
&& res
->index
== step
->res_index
)
72 res
= find_resource(ctx
->dev
, step
->res_index
);
78 static uint32_t reg_script_read_pci(struct reg_script_context
*ctx
)
80 const struct reg_script
*step
= reg_script_get_step(ctx
);
83 case REG_SCRIPT_SIZE_8
:
84 return pci_read_config8(ctx
->dev
, step
->reg
);
85 case REG_SCRIPT_SIZE_16
:
86 return pci_read_config16(ctx
->dev
, step
->reg
);
87 case REG_SCRIPT_SIZE_32
:
88 return pci_read_config32(ctx
->dev
, step
->reg
);
93 static void reg_script_write_pci(struct reg_script_context
*ctx
)
95 const struct reg_script
*step
= reg_script_get_step(ctx
);
98 case REG_SCRIPT_SIZE_8
:
99 pci_write_config8(ctx
->dev
, step
->reg
, step
->value
);
101 case REG_SCRIPT_SIZE_16
:
102 pci_write_config16(ctx
->dev
, step
->reg
, step
->value
);
104 case REG_SCRIPT_SIZE_32
:
105 pci_write_config32(ctx
->dev
, step
->reg
, step
->value
);
110 static uint32_t reg_script_read_io(struct reg_script_context
*ctx
)
112 const struct reg_script
*step
= reg_script_get_step(ctx
);
114 switch (step
->size
) {
115 case REG_SCRIPT_SIZE_8
:
116 return inb(step
->reg
);
117 case REG_SCRIPT_SIZE_16
:
118 return inw(step
->reg
);
119 case REG_SCRIPT_SIZE_32
:
120 return inl(step
->reg
);
125 static void reg_script_write_io(struct reg_script_context
*ctx
)
127 const struct reg_script
*step
= reg_script_get_step(ctx
);
129 switch (step
->size
) {
130 case REG_SCRIPT_SIZE_8
:
131 outb(step
->value
, step
->reg
);
133 case REG_SCRIPT_SIZE_16
:
134 outw(step
->value
, step
->reg
);
136 case REG_SCRIPT_SIZE_32
:
137 outl(step
->value
, step
->reg
);
142 static uint32_t reg_script_read_mmio(struct reg_script_context
*ctx
)
144 const struct reg_script
*step
= reg_script_get_step(ctx
);
146 switch (step
->size
) {
147 case REG_SCRIPT_SIZE_8
:
148 return read8((u8
*)step
->reg
);
149 case REG_SCRIPT_SIZE_16
:
150 return read16((u16
*)step
->reg
);
151 case REG_SCRIPT_SIZE_32
:
152 return read32((u32
*)step
->reg
);
157 static void reg_script_write_mmio(struct reg_script_context
*ctx
)
159 const struct reg_script
*step
= reg_script_get_step(ctx
);
161 switch (step
->size
) {
162 case REG_SCRIPT_SIZE_8
:
163 write8((u8
*)step
->reg
, step
->value
);
165 case REG_SCRIPT_SIZE_16
:
166 write16((u16
*)step
->reg
, step
->value
);
168 case REG_SCRIPT_SIZE_32
:
169 write32((u32
*)step
->reg
, step
->value
);
174 static uint32_t reg_script_read_res(struct reg_script_context
*ctx
)
176 struct resource
*res
;
178 const struct reg_script
*step
= reg_script_get_step(ctx
);
180 res
= reg_script_get_resource(ctx
);
185 if (res
->flags
& IORESOURCE_IO
) {
186 const struct reg_script io_step
= {
188 .reg
= res
->base
+ step
->reg
,
190 reg_script_set_step(ctx
, &io_step
);
191 val
= reg_script_read_io(ctx
);
193 else if (res
->flags
& IORESOURCE_MEM
) {
194 const struct reg_script mmio_step
= {
196 .reg
= res
->base
+ step
->reg
,
198 reg_script_set_step(ctx
, &mmio_step
);
199 val
= reg_script_read_mmio(ctx
);
201 reg_script_set_step(ctx
, step
);
205 static void reg_script_write_res(struct reg_script_context
*ctx
)
207 struct resource
*res
;
208 const struct reg_script
*step
= reg_script_get_step(ctx
);
210 res
= reg_script_get_resource(ctx
);
215 if (res
->flags
& IORESOURCE_IO
) {
216 const struct reg_script io_step
= {
218 .reg
= res
->base
+ step
->reg
,
219 .value
= step
->value
,
221 reg_script_set_step(ctx
, &io_step
);
222 reg_script_write_io(ctx
);
224 else if (res
->flags
& IORESOURCE_MEM
) {
225 const struct reg_script mmio_step
= {
227 .reg
= res
->base
+ step
->reg
,
228 .value
= step
->value
,
230 reg_script_set_step(ctx
, &mmio_step
);
231 reg_script_write_mmio(ctx
);
233 reg_script_set_step(ctx
, step
);
236 #if CONFIG_SOC_INTEL_BAYTRAIL
237 static uint32_t reg_script_read_iosf(struct reg_script_context
*ctx
)
239 const struct reg_script
*step
= reg_script_get_step(ctx
);
242 case IOSF_PORT_AUNIT
:
243 return iosf_aunit_read(step
->reg
);
244 case IOSF_PORT_CPU_BUS
:
245 return iosf_cpu_bus_read(step
->reg
);
246 case IOSF_PORT_BUNIT
:
247 return iosf_bunit_read(step
->reg
);
248 case IOSF_PORT_DUNIT_CH0
:
249 return iosf_dunit_ch0_read(step
->reg
);
251 return iosf_punit_read(step
->reg
);
252 case IOSF_PORT_USBPHY
:
253 return iosf_usbphy_read(step
->reg
);
255 return iosf_sec_read(step
->reg
);
257 return iosf_port45_read(step
->reg
);
259 return iosf_port46_read(step
->reg
);
261 return iosf_port47_read(step
->reg
);
262 case IOSF_PORT_SCORE
:
263 return iosf_score_read(step
->reg
);
265 return iosf_port55_read(step
->reg
);
267 return iosf_port58_read(step
->reg
);
269 return iosf_port59_read(step
->reg
);
271 return iosf_port5a_read(step
->reg
);
272 case IOSF_PORT_USHPHY
:
273 return iosf_ushphy_read(step
->reg
);
275 return iosf_scc_read(step
->reg
);
277 return iosf_lpss_read(step
->reg
);
279 return iosf_porta2_read(step
->reg
);
281 return iosf_ccu_read(step
->reg
);
283 return iosf_ssus_read(step
->reg
);
285 printk(BIOS_DEBUG
, "No read support for IOSF port 0x%x.\n",
292 static void reg_script_write_iosf(struct reg_script_context
*ctx
)
294 const struct reg_script
*step
= reg_script_get_step(ctx
);
297 case IOSF_PORT_AUNIT
:
298 iosf_aunit_write(step
->reg
, step
->value
);
300 case IOSF_PORT_CPU_BUS
:
301 iosf_cpu_bus_write(step
->reg
, step
->value
);
303 case IOSF_PORT_BUNIT
:
304 iosf_bunit_write(step
->reg
, step
->value
);
306 case IOSF_PORT_DUNIT_CH0
:
307 iosf_dunit_write(step
->reg
, step
->value
);
310 iosf_punit_write(step
->reg
, step
->value
);
312 case IOSF_PORT_USBPHY
:
313 iosf_usbphy_write(step
->reg
, step
->value
);
316 iosf_sec_write(step
->reg
, step
->value
);
319 iosf_port45_write(step
->reg
, step
->value
);
322 iosf_port46_write(step
->reg
, step
->value
);
325 iosf_port47_write(step
->reg
, step
->value
);
327 case IOSF_PORT_SCORE
:
328 iosf_score_write(step
->reg
, step
->value
);
331 iosf_port55_write(step
->reg
, step
->value
);
334 iosf_port58_write(step
->reg
, step
->value
);
337 iosf_port59_write(step
->reg
, step
->value
);
340 iosf_port5a_write(step
->reg
, step
->value
);
342 case IOSF_PORT_USHPHY
:
343 iosf_ushphy_write(step
->reg
, step
->value
);
346 iosf_scc_write(step
->reg
, step
->value
);
349 iosf_lpss_write(step
->reg
, step
->value
);
352 iosf_porta2_write(step
->reg
, step
->value
);
355 iosf_ccu_write(step
->reg
, step
->value
);
358 iosf_ssus_write(step
->reg
, step
->value
);
361 printk(BIOS_DEBUG
, "No write support for IOSF port 0x%x.\n",
369 static uint64_t reg_script_read_msr(struct reg_script_context
*ctx
)
372 const struct reg_script
*step
= reg_script_get_step(ctx
);
373 msr_t msr
= rdmsr(step
->reg
);
374 uint64_t value
= msr
.hi
;
382 static void reg_script_write_msr(struct reg_script_context
*ctx
)
385 const struct reg_script
*step
= reg_script_get_step(ctx
);
387 msr
.hi
= step
->value
>> 32;
388 msr
.lo
= step
->value
& 0xffffffff;
389 wrmsr(step
->reg
, msr
);
394 /* Default routine provided for systems without platform specific busses */
395 const struct reg_script_bus_entry
*__attribute__((weak
))
396 platform_bus_table(size_t *table_entries
)
398 /* No platform bus type table supplied */
403 /* Locate the structure containing the platform specific bus access routines */
404 static const struct reg_script_bus_entry
405 *find_bus(const struct reg_script
*step
)
407 const struct reg_script_bus_entry
*bus
;
408 size_t table_entries
;
411 /* Locate the platform specific bus */
412 bus
= platform_bus_table(&table_entries
);
413 for (i
= 0; i
< table_entries
; i
++) {
414 if (bus
[i
].type
== step
->type
)
423 static uint64_t reg_script_read(struct reg_script_context
*ctx
)
425 const struct reg_script
*step
= reg_script_get_step(ctx
);
427 switch (step
->type
) {
428 case REG_SCRIPT_TYPE_PCI
:
429 return reg_script_read_pci(ctx
);
430 case REG_SCRIPT_TYPE_IO
:
431 return reg_script_read_io(ctx
);
432 case REG_SCRIPT_TYPE_MMIO
:
433 return reg_script_read_mmio(ctx
);
434 case REG_SCRIPT_TYPE_RES
:
435 return reg_script_read_res(ctx
);
436 case REG_SCRIPT_TYPE_MSR
:
437 return reg_script_read_msr(ctx
);
438 #if CONFIG_SOC_INTEL_BAYTRAIL
439 case REG_SCRIPT_TYPE_IOSF
:
440 return reg_script_read_iosf(ctx
);
445 const struct reg_script_bus_entry
*bus
;
447 /* Read from the platform specific bus */
448 bus
= find_bus(step
);
450 return bus
->reg_script_read(ctx
);
454 "Unsupported read type (0x%x) for this device!\n",
461 static void reg_script_write(struct reg_script_context
*ctx
)
463 const struct reg_script
*step
= reg_script_get_step(ctx
);
465 switch (step
->type
) {
466 case REG_SCRIPT_TYPE_PCI
:
467 reg_script_write_pci(ctx
);
469 case REG_SCRIPT_TYPE_IO
:
470 reg_script_write_io(ctx
);
472 case REG_SCRIPT_TYPE_MMIO
:
473 reg_script_write_mmio(ctx
);
475 case REG_SCRIPT_TYPE_RES
:
476 reg_script_write_res(ctx
);
478 case REG_SCRIPT_TYPE_MSR
:
479 reg_script_write_msr(ctx
);
481 #if CONFIG_SOC_INTEL_BAYTRAIL
482 case REG_SCRIPT_TYPE_IOSF
:
483 reg_script_write_iosf(ctx
);
489 const struct reg_script_bus_entry
*bus
;
491 /* Write to the platform specific bus */
492 bus
= find_bus(step
);
494 bus
->reg_script_write(ctx
);
500 "Unsupported write type (0x%x) for this device!\n",
506 static void reg_script_rmw(struct reg_script_context
*ctx
)
509 const struct reg_script
*step
= reg_script_get_step(ctx
);
510 struct reg_script write_step
= *step
;
512 value
= reg_script_read(ctx
);
514 value
|= step
->value
;
515 write_step
.value
= value
;
516 reg_script_set_step(ctx
, &write_step
);
517 reg_script_write(ctx
);
518 reg_script_set_step(ctx
, step
);
521 /* In order to easily chain scripts together handle the REG_SCRIPT_COMMAND_NEXT
522 * as recursive call with a new context that has the same dev and resource
523 * as the previous one. That will run to completion and then move on to the
524 * next step of the previous context. */
525 static void reg_script_run_next(struct reg_script_context
*ctx
,
526 const struct reg_script
*step
);
529 static void reg_script_run_step(struct reg_script_context
*ctx
,
530 const struct reg_script
*step
)
532 uint64_t value
= 0, try;
534 switch (step
->command
) {
535 case REG_SCRIPT_COMMAND_READ
:
536 (void)reg_script_read(ctx
);
538 case REG_SCRIPT_COMMAND_WRITE
:
539 reg_script_write(ctx
);
541 case REG_SCRIPT_COMMAND_RMW
:
544 case REG_SCRIPT_COMMAND_POLL
:
545 for (try = 0; try < step
->timeout
; try += POLL_DELAY
) {
546 value
= reg_script_read(ctx
) & step
->mask
;
547 if (value
== step
->value
)
551 if (try >= step
->timeout
)
552 printk(BIOS_WARNING
, "%s: POLL timeout waiting for "
553 "0x%x to be 0x%lx, got 0x%lx\n", __func__
,
554 step
->reg
, (unsigned long)step
->value
,
555 (unsigned long)value
);
557 case REG_SCRIPT_COMMAND_SET_DEV
:
558 reg_script_set_dev(ctx
, step
->dev
);
560 case REG_SCRIPT_COMMAND_NEXT
:
561 reg_script_run_next(ctx
, step
->next
);
564 printk(BIOS_WARNING
, "Invalid command: %08x\n",
570 static void reg_script_run_with_context(struct reg_script_context
*ctx
)
573 const struct reg_script
*step
= reg_script_get_step(ctx
);
575 if (step
->command
== REG_SCRIPT_COMMAND_END
)
578 reg_script_run_step(ctx
, step
);
579 reg_script_set_step(ctx
, step
+ 1);
583 static void reg_script_run_next(struct reg_script_context
*prev_ctx
,
584 const struct reg_script
*step
)
586 struct reg_script_context ctx
;
588 /* Use prev context as a basis but start at a new step. */
590 reg_script_set_step(&ctx
, step
);
591 reg_script_run_with_context(&ctx
);
594 void reg_script_run_on_dev(device_t dev
, const struct reg_script
*step
)
596 struct reg_script_context ctx
;
598 reg_script_set_dev(&ctx
, dev
);
599 reg_script_set_step(&ctx
, step
);
600 reg_script_run_with_context(&ctx
);
603 void reg_script_run(const struct reg_script
*step
)
605 reg_script_run_on_dev(EMPTY_DEV
, step
);