Add table driven way to add platform specific reg_script routines
Extend lib/reg_script.c to use a platform table to declare additional platform specific register access routine functions. REG_SCRIPT_TYPE_PLATFORM_BASE is the starting value for platform specific register types. Additional register access types may be defined above this value. The type and access routines are placed into reg_script_type_table. The Baytrail type value for IOSF was left the enumeration since it was already defined and is being used for Braswell. BRANCH=none BUG=None TEST=Use the following steps to test: 1. Build for a Baytrail platform 2. Build for the Samus platform 3. Add a platform_bus_table routine to a platform which returns the address of an array of reg_script_bus_entry structures and the number of entries in the array. Change-Id: Ic99d345c4b067c52b4e9c47e59ed4472a05bc1a5 Signed-off-by: Stefan Reinauer <reinauer@chromium.org> Original-Commit-Id: 2d9fecf4287dff6311a81d818603212248f1a248 Original-Signed-off-by: Lee Leahy <leroy.p.leahy@intel.com> Original-Reviewed-on: https://chromium-review.googlesource.com/215645 Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org> Original-Change-Id: I7cd37abc5a08cadb3166d4048f65b919b86ab5db Original-Reviewed-on: https://chromium-review.googlesource.com/229612 Original-Reviewed-by: Duncan Laurie <dlaurie@chromium.org> Reviewed-on: http://review.coreboot.org/9279 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi <pgeorgi@google.com>
This commit is contained in:
committed by
Patrick Georgi
parent
a19a4e1d64
commit
9f5a5c5323
@ -60,6 +60,10 @@ enum {
|
|||||||
REG_SCRIPT_TYPE_RES,
|
REG_SCRIPT_TYPE_RES,
|
||||||
REG_SCRIPT_TYPE_IOSF,
|
REG_SCRIPT_TYPE_IOSF,
|
||||||
REG_SCRIPT_TYPE_MSR,
|
REG_SCRIPT_TYPE_MSR,
|
||||||
|
|
||||||
|
/* Insert other platform independent values above this comment */
|
||||||
|
|
||||||
|
REG_SCRIPT_TYPE_PLATFORM_BASE = 0x10000
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@ -85,6 +89,24 @@ struct reg_script {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct reg_script_context {
|
||||||
|
device_t dev;
|
||||||
|
struct resource *res;
|
||||||
|
const struct reg_script *step;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef __PRE_RAM__
|
||||||
|
struct reg_script_bus_entry {
|
||||||
|
int type;
|
||||||
|
uint64_t (*reg_script_read)(struct reg_script_context *ctx);
|
||||||
|
void (*reg_script_write)(struct reg_script_context *ctx);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Get the address and length of the platform bus table */
|
||||||
|
const struct reg_script_bus_entry *platform_bus_table(size_t *table_entries);
|
||||||
|
|
||||||
|
#endif /* __PRE_RAM */
|
||||||
|
|
||||||
/* Internal helper Macros. */
|
/* Internal helper Macros. */
|
||||||
|
|
||||||
#define _REG_SCRIPT_ENCODE_RAW(cmd_, type_, size_, reg_, \
|
#define _REG_SCRIPT_ENCODE_RAW(cmd_, type_, size_, reg_, \
|
||||||
@ -271,6 +293,8 @@ struct reg_script {
|
|||||||
#define REG_RES_POLL32(bar_, reg_, mask_, value_, timeout_) \
|
#define REG_RES_POLL32(bar_, reg_, mask_, value_, timeout_) \
|
||||||
REG_SCRIPT_RES(POLL, 32, bar_, reg_, mask_, value_, timeout_)
|
REG_SCRIPT_RES(POLL, 32, bar_, reg_, mask_, value_, timeout_)
|
||||||
|
|
||||||
|
|
||||||
|
#if CONFIG_SOC_INTEL_BAYTRAIL
|
||||||
/*
|
/*
|
||||||
* IO Sideband Function
|
* IO Sideband Function
|
||||||
*/
|
*/
|
||||||
@ -290,6 +314,7 @@ struct reg_script {
|
|||||||
REG_IOSF_RMW(unit_, reg_, 0xffffffff, value_)
|
REG_IOSF_RMW(unit_, reg_, 0xffffffff, value_)
|
||||||
#define REG_IOSF_POLL(unit_, reg_, mask_, value_, timeout_) \
|
#define REG_IOSF_POLL(unit_, reg_, mask_, value_, timeout_) \
|
||||||
REG_SCRIPT_IOSF(POLL, unit_, reg_, mask_, value_, timeout_)
|
REG_SCRIPT_IOSF(POLL, unit_, reg_, mask_, value_, timeout_)
|
||||||
|
#endif /* CONFIG_SOC_INTEL_BAYTRAIL */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CPU Model Specific Register
|
* CPU Model Specific Register
|
||||||
|
@ -41,12 +41,6 @@
|
|||||||
#define EMPTY_DEV NULL
|
#define EMPTY_DEV NULL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct reg_script_context {
|
|
||||||
device_t dev;
|
|
||||||
struct resource *res;
|
|
||||||
const struct reg_script *step;
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline void reg_script_set_dev(struct reg_script_context *ctx,
|
static inline void reg_script_set_dev(struct reg_script_context *ctx,
|
||||||
device_t dev)
|
device_t dev)
|
||||||
{
|
{
|
||||||
@ -243,9 +237,9 @@ static void reg_script_write_res(struct reg_script_context *ctx)
|
|||||||
reg_script_set_step(ctx, step);
|
reg_script_set_step(ctx, step);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CONFIG_SOC_INTEL_BAYTRAIL
|
||||||
static uint32_t reg_script_read_iosf(struct reg_script_context *ctx)
|
static uint32_t reg_script_read_iosf(struct reg_script_context *ctx)
|
||||||
{
|
{
|
||||||
#if CONFIG_SOC_INTEL_BAYTRAIL
|
|
||||||
const struct reg_script *step = reg_script_get_step(ctx);
|
const struct reg_script *step = reg_script_get_step(ctx);
|
||||||
|
|
||||||
switch (step->id) {
|
switch (step->id) {
|
||||||
@ -296,13 +290,11 @@ static uint32_t reg_script_read_iosf(struct reg_script_context *ctx)
|
|||||||
step->id);
|
step->id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void reg_script_write_iosf(struct reg_script_context *ctx)
|
static void reg_script_write_iosf(struct reg_script_context *ctx)
|
||||||
{
|
{
|
||||||
#if CONFIG_SOC_INTEL_BAYTRAIL
|
|
||||||
const struct reg_script *step = reg_script_get_step(ctx);
|
const struct reg_script *step = reg_script_get_step(ctx);
|
||||||
|
|
||||||
switch (step->id) {
|
switch (step->id) {
|
||||||
@ -374,8 +366,9 @@ static void reg_script_write_iosf(struct reg_script_context *ctx)
|
|||||||
step->id);
|
step->id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static uint64_t reg_script_read_msr(struct reg_script_context *ctx)
|
static uint64_t reg_script_read_msr(struct reg_script_context *ctx)
|
||||||
{
|
{
|
||||||
@ -401,6 +394,36 @@ static void reg_script_write_msr(struct reg_script_context *ctx)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef __PRE_RAM__
|
||||||
|
/* Default routine provided for systems without platform specific busses */
|
||||||
|
const struct reg_script_bus_entry *__attribute__((weak))
|
||||||
|
platform_bus_table(size_t *table_entries)
|
||||||
|
{
|
||||||
|
/* No platform bus type table supplied */
|
||||||
|
*table_entries = 0;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Locate the structure containing the platform specific bus access routines */
|
||||||
|
static const struct reg_script_bus_entry
|
||||||
|
*find_bus(const struct reg_script *step)
|
||||||
|
{
|
||||||
|
const struct reg_script_bus_entry *bus;
|
||||||
|
size_t table_entries;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
/* Locate the platform specific bus */
|
||||||
|
bus = platform_bus_table(&table_entries);
|
||||||
|
for (i = 0; i < table_entries; i++) {
|
||||||
|
if (bus[i].type == step->type)
|
||||||
|
return &bus[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bus not found */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static uint64_t reg_script_read(struct reg_script_context *ctx)
|
static uint64_t reg_script_read(struct reg_script_context *ctx)
|
||||||
{
|
{
|
||||||
const struct reg_script *step = reg_script_get_step(ctx);
|
const struct reg_script *step = reg_script_get_step(ctx);
|
||||||
@ -414,10 +437,27 @@ static uint64_t reg_script_read(struct reg_script_context *ctx)
|
|||||||
return reg_script_read_mmio(ctx);
|
return reg_script_read_mmio(ctx);
|
||||||
case REG_SCRIPT_TYPE_RES:
|
case REG_SCRIPT_TYPE_RES:
|
||||||
return reg_script_read_res(ctx);
|
return reg_script_read_res(ctx);
|
||||||
case REG_SCRIPT_TYPE_IOSF:
|
|
||||||
return reg_script_read_iosf(ctx);
|
|
||||||
case REG_SCRIPT_TYPE_MSR:
|
case REG_SCRIPT_TYPE_MSR:
|
||||||
return reg_script_read_msr(ctx);
|
return reg_script_read_msr(ctx);
|
||||||
|
#if CONFIG_SOC_INTEL_BAYTRAIL
|
||||||
|
case REG_SCRIPT_TYPE_IOSF:
|
||||||
|
return reg_script_read_iosf(ctx);
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
#ifndef __PRE_RAM__
|
||||||
|
{
|
||||||
|
const struct reg_script_bus_entry *bus;
|
||||||
|
|
||||||
|
/* Read from the platform specific bus */
|
||||||
|
bus = find_bus(step);
|
||||||
|
if (NULL != bus)
|
||||||
|
return bus->reg_script_read(ctx);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
printk(BIOS_ERR,
|
||||||
|
"Unsupported read type (0x%x) for this device!\n",
|
||||||
|
step->type);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -439,11 +479,30 @@ static void reg_script_write(struct reg_script_context *ctx)
|
|||||||
case REG_SCRIPT_TYPE_RES:
|
case REG_SCRIPT_TYPE_RES:
|
||||||
reg_script_write_res(ctx);
|
reg_script_write_res(ctx);
|
||||||
break;
|
break;
|
||||||
|
case REG_SCRIPT_TYPE_MSR:
|
||||||
|
reg_script_write_msr(ctx);
|
||||||
|
break;
|
||||||
|
#if CONFIG_SOC_INTEL_BAYTRAIL
|
||||||
case REG_SCRIPT_TYPE_IOSF:
|
case REG_SCRIPT_TYPE_IOSF:
|
||||||
reg_script_write_iosf(ctx);
|
reg_script_write_iosf(ctx);
|
||||||
break;
|
break;
|
||||||
case REG_SCRIPT_TYPE_MSR:
|
#endif
|
||||||
reg_script_write_msr(ctx);
|
default:
|
||||||
|
#ifndef __PRE_RAM__
|
||||||
|
{
|
||||||
|
const struct reg_script_bus_entry *bus;
|
||||||
|
|
||||||
|
/* Write to the platform specific bus */
|
||||||
|
bus = find_bus(step);
|
||||||
|
if (NULL != bus) {
|
||||||
|
bus->reg_script_write(ctx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
printk(BIOS_ERR,
|
||||||
|
"Unsupported write type (0x%x) for this device!\n",
|
||||||
|
step->type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user