tree: drop last paragraph of GPL copyright header
[coreboot.git] / src / lib / reg_script.c
blobbcfb6c5fbe25babb24dbc6c9ce9d2df11f0726dc
1 /*
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.
16 #include <arch/io.h>
17 #include <console/console.h>
18 #include <delay.h>
19 #include <device/device.h>
20 #include <device/resource.h>
21 #include <device/pci.h>
22 #include <stdint.h>
23 #include <reg_script.h>
25 #if CONFIG_ARCH_X86
26 #include <cpu/x86/msr.h>
27 #endif
29 #if CONFIG_SOC_INTEL_BAYTRAIL
30 #include <soc/iosf.h> /* TODO: wrap in <soc/reg_script.h, remove #ifdef? */
31 #endif
33 #define POLL_DELAY 100 /* 100us */
34 #if defined(__PRE_RAM__)
35 #define EMPTY_DEV 0
36 #else
37 #define EMPTY_DEV NULL
38 #endif
40 static inline void reg_script_set_dev(struct reg_script_context *ctx,
41 device_t dev)
43 ctx->dev = dev;
44 ctx->res = NULL;
47 static inline void reg_script_set_step(struct reg_script_context *ctx,
48 const struct reg_script *step)
50 ctx->step = step;
53 static inline const struct reg_script *
54 reg_script_get_step(struct reg_script_context *ctx)
56 return ctx->step;
59 static struct resource *reg_script_get_resource(struct reg_script_context *ctx)
61 #if defined(__PRE_RAM__)
62 return NULL;
63 #else
64 struct resource *res;
65 const struct reg_script *step = reg_script_get_step(ctx);
67 res = ctx->res;
69 if (res != NULL && res->index == step->res_index)
70 return res;
72 res = find_resource(ctx->dev, step->res_index);
73 ctx->res = res;
74 return res;
75 #endif
78 static uint32_t reg_script_read_pci(struct reg_script_context *ctx)
80 const struct reg_script *step = reg_script_get_step(ctx);
82 switch (step->size) {
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);
90 return 0;
93 static void reg_script_write_pci(struct reg_script_context *ctx)
95 const struct reg_script *step = reg_script_get_step(ctx);
97 switch (step->size) {
98 case REG_SCRIPT_SIZE_8:
99 pci_write_config8(ctx->dev, step->reg, step->value);
100 break;
101 case REG_SCRIPT_SIZE_16:
102 pci_write_config16(ctx->dev, step->reg, step->value);
103 break;
104 case REG_SCRIPT_SIZE_32:
105 pci_write_config32(ctx->dev, step->reg, step->value);
106 break;
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);
122 return 0;
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);
132 break;
133 case REG_SCRIPT_SIZE_16:
134 outw(step->value, step->reg);
135 break;
136 case REG_SCRIPT_SIZE_32:
137 outl(step->value, step->reg);
138 break;
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);
154 return 0;
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);
164 break;
165 case REG_SCRIPT_SIZE_16:
166 write16((u16 *)step->reg, step->value);
167 break;
168 case REG_SCRIPT_SIZE_32:
169 write32((u32 *)step->reg, step->value);
170 break;
174 static uint32_t reg_script_read_res(struct reg_script_context *ctx)
176 struct resource *res;
177 uint32_t val = 0;
178 const struct reg_script *step = reg_script_get_step(ctx);
180 res = reg_script_get_resource(ctx);
182 if (res == NULL)
183 return val;
185 if (res->flags & IORESOURCE_IO) {
186 const struct reg_script io_step = {
187 .size = step->size,
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 = {
195 .size = step->size,
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);
202 return val;
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);
212 if (res == NULL)
213 return;
215 if (res->flags & IORESOURCE_IO) {
216 const struct reg_script io_step = {
217 .size = step->size,
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 = {
226 .size = step->size,
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);
241 switch (step->id) {
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);
250 case IOSF_PORT_PMC:
251 return iosf_punit_read(step->reg);
252 case IOSF_PORT_USBPHY:
253 return iosf_usbphy_read(step->reg);
254 case IOSF_PORT_SEC:
255 return iosf_sec_read(step->reg);
256 case IOSF_PORT_0x45:
257 return iosf_port45_read(step->reg);
258 case IOSF_PORT_0x46:
259 return iosf_port46_read(step->reg);
260 case IOSF_PORT_0x47:
261 return iosf_port47_read(step->reg);
262 case IOSF_PORT_SCORE:
263 return iosf_score_read(step->reg);
264 case IOSF_PORT_0x55:
265 return iosf_port55_read(step->reg);
266 case IOSF_PORT_0x58:
267 return iosf_port58_read(step->reg);
268 case IOSF_PORT_0x59:
269 return iosf_port59_read(step->reg);
270 case IOSF_PORT_0x5a:
271 return iosf_port5a_read(step->reg);
272 case IOSF_PORT_USHPHY:
273 return iosf_ushphy_read(step->reg);
274 case IOSF_PORT_SCC:
275 return iosf_scc_read(step->reg);
276 case IOSF_PORT_LPSS:
277 return iosf_lpss_read(step->reg);
278 case IOSF_PORT_0xa2:
279 return iosf_porta2_read(step->reg);
280 case IOSF_PORT_CCU:
281 return iosf_ccu_read(step->reg);
282 case IOSF_PORT_SSUS:
283 return iosf_ssus_read(step->reg);
284 default:
285 printk(BIOS_DEBUG, "No read support for IOSF port 0x%x.\n",
286 step->id);
287 break;
289 return 0;
292 static void reg_script_write_iosf(struct reg_script_context *ctx)
294 const struct reg_script *step = reg_script_get_step(ctx);
296 switch (step->id) {
297 case IOSF_PORT_AUNIT:
298 iosf_aunit_write(step->reg, step->value);
299 break;
300 case IOSF_PORT_CPU_BUS:
301 iosf_cpu_bus_write(step->reg, step->value);
302 break;
303 case IOSF_PORT_BUNIT:
304 iosf_bunit_write(step->reg, step->value);
305 break;
306 case IOSF_PORT_DUNIT_CH0:
307 iosf_dunit_write(step->reg, step->value);
308 break;
309 case IOSF_PORT_PMC:
310 iosf_punit_write(step->reg, step->value);
311 break;
312 case IOSF_PORT_USBPHY:
313 iosf_usbphy_write(step->reg, step->value);
314 break;
315 case IOSF_PORT_SEC:
316 iosf_sec_write(step->reg, step->value);
317 break;
318 case IOSF_PORT_0x45:
319 iosf_port45_write(step->reg, step->value);
320 break;
321 case IOSF_PORT_0x46:
322 iosf_port46_write(step->reg, step->value);
323 break;
324 case IOSF_PORT_0x47:
325 iosf_port47_write(step->reg, step->value);
326 break;
327 case IOSF_PORT_SCORE:
328 iosf_score_write(step->reg, step->value);
329 break;
330 case IOSF_PORT_0x55:
331 iosf_port55_write(step->reg, step->value);
332 break;
333 case IOSF_PORT_0x58:
334 iosf_port58_write(step->reg, step->value);
335 break;
336 case IOSF_PORT_0x59:
337 iosf_port59_write(step->reg, step->value);
338 break;
339 case IOSF_PORT_0x5a:
340 iosf_port5a_write(step->reg, step->value);
341 break;
342 case IOSF_PORT_USHPHY:
343 iosf_ushphy_write(step->reg, step->value);
344 break;
345 case IOSF_PORT_SCC:
346 iosf_scc_write(step->reg, step->value);
347 break;
348 case IOSF_PORT_LPSS:
349 iosf_lpss_write(step->reg, step->value);
350 break;
351 case IOSF_PORT_0xa2:
352 iosf_porta2_write(step->reg, step->value);
353 break;
354 case IOSF_PORT_CCU:
355 iosf_ccu_write(step->reg, step->value);
356 break;
357 case IOSF_PORT_SSUS:
358 iosf_ssus_write(step->reg, step->value);
359 break;
360 default:
361 printk(BIOS_DEBUG, "No write support for IOSF port 0x%x.\n",
362 step->id);
363 break;
366 #endif
369 static uint64_t reg_script_read_msr(struct reg_script_context *ctx)
371 #if CONFIG_ARCH_X86
372 const struct reg_script *step = reg_script_get_step(ctx);
373 msr_t msr = rdmsr(step->reg);
374 uint64_t value = msr.hi;
375 value = msr.hi;
376 value <<= 32;
377 value |= msr.lo;
378 return value;
379 #endif
382 static void reg_script_write_msr(struct reg_script_context *ctx)
384 #if CONFIG_ARCH_X86
385 const struct reg_script *step = reg_script_get_step(ctx);
386 msr_t msr;
387 msr.hi = step->value >> 32;
388 msr.lo = step->value & 0xffffffff;
389 wrmsr(step->reg, msr);
390 #endif
393 #ifndef __PRE_RAM__
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 */
399 *table_entries = 0;
400 return NULL;
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;
409 size_t i;
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)
415 return &bus[i];
418 /* Bus not found */
419 return NULL;
421 #endif
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);
441 #endif
442 default:
443 #ifndef __PRE_RAM__
445 const struct reg_script_bus_entry *bus;
447 /* Read from the platform specific bus */
448 bus = find_bus(step);
449 if (NULL != bus)
450 return bus->reg_script_read(ctx);
452 #endif
453 printk(BIOS_ERR,
454 "Unsupported read type (0x%x) for this device!\n",
455 step->type);
456 break;
458 return 0;
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);
468 break;
469 case REG_SCRIPT_TYPE_IO:
470 reg_script_write_io(ctx);
471 break;
472 case REG_SCRIPT_TYPE_MMIO:
473 reg_script_write_mmio(ctx);
474 break;
475 case REG_SCRIPT_TYPE_RES:
476 reg_script_write_res(ctx);
477 break;
478 case REG_SCRIPT_TYPE_MSR:
479 reg_script_write_msr(ctx);
480 break;
481 #if CONFIG_SOC_INTEL_BAYTRAIL
482 case REG_SCRIPT_TYPE_IOSF:
483 reg_script_write_iosf(ctx);
484 break;
485 #endif
486 default:
487 #ifndef __PRE_RAM__
489 const struct reg_script_bus_entry *bus;
491 /* Write to the platform specific bus */
492 bus = find_bus(step);
493 if (NULL != bus) {
494 bus->reg_script_write(ctx);
495 return;
498 #endif
499 printk(BIOS_ERR,
500 "Unsupported write type (0x%x) for this device!\n",
501 step->type);
502 break;
506 static void reg_script_rmw(struct reg_script_context *ctx)
508 uint64_t value;
509 const struct reg_script *step = reg_script_get_step(ctx);
510 struct reg_script write_step = *step;
512 value = reg_script_read(ctx);
513 value &= step->mask;
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);
537 break;
538 case REG_SCRIPT_COMMAND_WRITE:
539 reg_script_write(ctx);
540 break;
541 case REG_SCRIPT_COMMAND_RMW:
542 reg_script_rmw(ctx);
543 break;
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)
548 break;
549 udelay(POLL_DELAY);
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);
556 break;
557 case REG_SCRIPT_COMMAND_SET_DEV:
558 reg_script_set_dev(ctx, step->dev);
559 break;
560 case REG_SCRIPT_COMMAND_NEXT:
561 reg_script_run_next(ctx, step->next);
562 break;
563 default:
564 printk(BIOS_WARNING, "Invalid command: %08x\n",
565 step->command);
566 break;
570 static void reg_script_run_with_context(struct reg_script_context *ctx)
572 while (1) {
573 const struct reg_script *step = reg_script_get_step(ctx);
575 if (step->command == REG_SCRIPT_COMMAND_END)
576 break;
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. */
589 ctx = *prev_ctx;
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);