avionic design with actual uboot and tooling
submodule of avionic design uboot bootloader and with included tools to get you started , read readme.md and readme-tk1-loader.md
This commit is contained in:
144
u-boot/arch/x86/cpu/broadwell/iobp.c
Normal file
144
u-boot/arch/x86/cpu/broadwell/iobp.c
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Google, Inc
|
||||
*
|
||||
* Modified from coreboot
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <errno.h>
|
||||
#include <asm/intel_regs.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/pch.h>
|
||||
|
||||
#define IOBP_RETRY 1000
|
||||
|
||||
/* IO Buffer Programming */
|
||||
#define IOBPIRI 0x2330
|
||||
#define IOBPD 0x2334
|
||||
#define IOBPS 0x2338
|
||||
#define IOBPS_READY 0x0001
|
||||
#define IOBPS_TX_MASK 0x0006
|
||||
#define IOBPS_MASK 0xff00
|
||||
#define IOBPS_READ 0x0600
|
||||
#define IOBPS_WRITE 0x0700
|
||||
#define IOBPU 0x233a
|
||||
#define IOBPU_MAGIC 0xf000
|
||||
#define IOBP_PCICFG_READ 0x0400
|
||||
#define IOBP_PCICFG_WRITE 0x0500
|
||||
|
||||
static inline int iobp_poll(void)
|
||||
{
|
||||
unsigned try;
|
||||
|
||||
for (try = IOBP_RETRY; try > 0; try--) {
|
||||
u16 status = readw(RCB_REG(IOBPS));
|
||||
if ((status & IOBPS_READY) == 0)
|
||||
return 1;
|
||||
udelay(10);
|
||||
}
|
||||
|
||||
printf("IOBP: timeout waiting for transaction to complete\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pch_iobp_trans_start(u32 address, int op)
|
||||
{
|
||||
if (!iobp_poll())
|
||||
return 0;
|
||||
|
||||
/* Set the address */
|
||||
writel(address, RCB_REG(IOBPIRI));
|
||||
|
||||
/* READ OPCODE */
|
||||
clrsetbits_le16(RCB_REG(IOBPS), IOBPS_MASK, op);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int pch_iobp_trans_finish(void)
|
||||
{
|
||||
u16 status;
|
||||
|
||||
/* Undocumented magic */
|
||||
writew(IOBPU_MAGIC, RCB_REG(IOBPU));
|
||||
|
||||
/* Set ready bit */
|
||||
setbits_le16(RCB_REG(IOBPS), IOBPS_READY);
|
||||
|
||||
if (!iobp_poll())
|
||||
return 1;
|
||||
|
||||
/* Check for successful transaction */
|
||||
status = readw(RCB_REG(IOBPS));
|
||||
if (status & IOBPS_TX_MASK)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 pch_iobp_read(u32 address)
|
||||
{
|
||||
if (!pch_iobp_trans_start(address, IOBPS_READ))
|
||||
return 0;
|
||||
if (pch_iobp_trans_finish()) {
|
||||
printf("IOBP: read 0x%08x failed\n", address);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Read IOBP data */
|
||||
return readl(RCB_REG(IOBPD));
|
||||
}
|
||||
|
||||
int pch_iobp_write(u32 address, u32 data)
|
||||
{
|
||||
if (!pch_iobp_trans_start(address, IOBPS_WRITE))
|
||||
return -EIO;
|
||||
|
||||
writel(data, RCB_REG(IOBPD));
|
||||
|
||||
if (pch_iobp_trans_finish()) {
|
||||
printf("IOBP: write 0x%08x failed\n", address);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pch_iobp_update(u32 address, u32 andvalue, u32 orvalue)
|
||||
{
|
||||
u32 data = pch_iobp_read(address);
|
||||
|
||||
/* Update the data */
|
||||
data &= andvalue;
|
||||
data |= orvalue;
|
||||
|
||||
return pch_iobp_write(address, data);
|
||||
}
|
||||
|
||||
int pch_iobp_exec(u32 addr, u16 op_code, u8 route_id, u32 *data, u8 *resp)
|
||||
{
|
||||
if (!data || !resp)
|
||||
return 0;
|
||||
|
||||
*resp = -1;
|
||||
if (!iobp_poll())
|
||||
return -EIO;
|
||||
|
||||
writel(addr, RCB_REG(IOBPIRI));
|
||||
clrsetbits_le16(RCB_REG(IOBPS), 0xff00, op_code);
|
||||
writew(IOBPU_MAGIC | route_id, RCB_REG(IOBPU));
|
||||
|
||||
writel(*data, RCB_REG(IOBPD));
|
||||
/* Set IOBPS[0] to trigger IOBP transaction*/
|
||||
setbits_le16(RCB_REG(IOBPS), 1);
|
||||
|
||||
if (!iobp_poll())
|
||||
return -EIO;
|
||||
|
||||
*resp = (readw(RCB_REG(IOBPS)) & IOBPS_TX_MASK) >> 1;
|
||||
*data = readl(RCB_REG(IOBPD));
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user