GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
config PCH
|
||||
bool "Enable Platform-controller Hub (PCH) support"
|
||||
depends on X86 || SANDBOX
|
||||
help
|
||||
Most x86 chips include a PCH which is responsible for handling
|
||||
parts of the system not handled by that CPU. It supersedes the
|
||||
northbridge / southbridge architecture that was previously used. The
|
||||
PCH allows for higher performance since the memory functions are
|
||||
handled in the CPU.
|
||||
@@ -0,0 +1,6 @@
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
obj-y += pch-uclass.o
|
||||
obj-y += pch7.o
|
||||
obj-y += pch9.o
|
||||
obj-$(CONFIG_SANDBOX) += sandbox_pch.o
|
||||
@@ -0,0 +1,70 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (c) 2015 Google, Inc
|
||||
* Written by Simon Glass <sjg@chromium.org>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <pch.h>
|
||||
|
||||
int pch_get_spi_base(struct udevice *dev, ulong *sbasep)
|
||||
{
|
||||
struct pch_ops *ops = pch_get_ops(dev);
|
||||
|
||||
*sbasep = 0;
|
||||
if (!ops->get_spi_base)
|
||||
return -ENOSYS;
|
||||
|
||||
return ops->get_spi_base(dev, sbasep);
|
||||
}
|
||||
|
||||
int pch_set_spi_protect(struct udevice *dev, bool protect)
|
||||
{
|
||||
struct pch_ops *ops = pch_get_ops(dev);
|
||||
|
||||
if (!ops->set_spi_protect)
|
||||
return -ENOSYS;
|
||||
|
||||
return ops->set_spi_protect(dev, protect);
|
||||
}
|
||||
|
||||
int pch_get_gpio_base(struct udevice *dev, u32 *gbasep)
|
||||
{
|
||||
struct pch_ops *ops = pch_get_ops(dev);
|
||||
|
||||
*gbasep = 0;
|
||||
if (!ops->get_gpio_base)
|
||||
return -ENOSYS;
|
||||
|
||||
return ops->get_gpio_base(dev, gbasep);
|
||||
}
|
||||
|
||||
int pch_get_io_base(struct udevice *dev, u32 *iobasep)
|
||||
{
|
||||
struct pch_ops *ops = pch_get_ops(dev);
|
||||
|
||||
*iobasep = 0;
|
||||
if (!ops->get_io_base)
|
||||
return -ENOSYS;
|
||||
|
||||
return ops->get_io_base(dev, iobasep);
|
||||
}
|
||||
|
||||
int pch_ioctl(struct udevice *dev, ulong req, void *data, int size)
|
||||
{
|
||||
struct pch_ops *ops = pch_get_ops(dev);
|
||||
|
||||
if (!ops->ioctl)
|
||||
return -ENOSYS;
|
||||
|
||||
return ops->ioctl(dev, req, data, size);
|
||||
}
|
||||
|
||||
UCLASS_DRIVER(pch) = {
|
||||
.id = UCLASS_PCH,
|
||||
.name = "pch",
|
||||
#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
|
||||
.post_bind = dm_scan_fdt_dev,
|
||||
#endif
|
||||
};
|
||||
@@ -0,0 +1,87 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2014 Google, Inc
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <pch.h>
|
||||
|
||||
#define GPIO_BASE 0x44
|
||||
#define BIOS_CTRL 0xd8
|
||||
|
||||
static int pch7_get_spi_base(struct udevice *dev, ulong *sbasep)
|
||||
{
|
||||
u32 rcba;
|
||||
|
||||
dm_pci_read_config32(dev, PCH_RCBA, &rcba);
|
||||
/* Bits 31-14 are the base address, 13-1 are reserved, 0 is enable */
|
||||
rcba = rcba & 0xffffc000;
|
||||
*sbasep = rcba + 0x3020;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pch7_set_spi_protect(struct udevice *dev, bool protect)
|
||||
{
|
||||
uint8_t bios_cntl;
|
||||
|
||||
/* Adjust the BIOS write protect to dis/allow write commands */
|
||||
dm_pci_read_config8(dev, BIOS_CTRL, &bios_cntl);
|
||||
if (protect)
|
||||
bios_cntl &= ~BIOS_CTRL_BIOSWE;
|
||||
else
|
||||
bios_cntl |= BIOS_CTRL_BIOSWE;
|
||||
dm_pci_write_config8(dev, BIOS_CTRL, bios_cntl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pch7_get_gpio_base(struct udevice *dev, u32 *gbasep)
|
||||
{
|
||||
u32 base;
|
||||
|
||||
/*
|
||||
* GPIO_BASE moved to its current offset with ICH6, but prior to
|
||||
* that it was unused (or undocumented). Check that it looks
|
||||
* okay: not all ones or zeros.
|
||||
*
|
||||
* Note we don't need check bit0 here, because the Tunnel Creek
|
||||
* GPIO base address register bit0 is reserved (read returns 0),
|
||||
* while on the Ivybridge the bit0 is used to indicate it is an
|
||||
* I/O space.
|
||||
*/
|
||||
dm_pci_read_config32(dev, GPIO_BASE, &base);
|
||||
if (base == 0x00000000 || base == 0xffffffff) {
|
||||
debug("%s: unexpected BASE value\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/*
|
||||
* Okay, I guess we're looking at the right device. The actual
|
||||
* GPIO registers are in the PCI device's I/O space, starting
|
||||
* at the offset that we just read. Bit 0 indicates that it's
|
||||
* an I/O address, not a memory address, so mask that off.
|
||||
*/
|
||||
*gbasep = base & 1 ? base & ~3 : base & ~15;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct pch_ops pch7_ops = {
|
||||
.get_spi_base = pch7_get_spi_base,
|
||||
.set_spi_protect = pch7_set_spi_protect,
|
||||
.get_gpio_base = pch7_get_gpio_base,
|
||||
};
|
||||
|
||||
static const struct udevice_id pch7_ids[] = {
|
||||
{ .compatible = "intel,pch7" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(pch7_drv) = {
|
||||
.name = "intel-pch7",
|
||||
.id = UCLASS_PCH,
|
||||
.of_match = pch7_ids,
|
||||
.ops = &pch7_ops,
|
||||
};
|
||||
@@ -0,0 +1,86 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2014 Google, Inc
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <pch.h>
|
||||
|
||||
#define GPIO_BASE 0x48
|
||||
#define IO_BASE 0x4c
|
||||
#define SBASE_ADDR 0x54
|
||||
|
||||
static int pch9_get_spi_base(struct udevice *dev, ulong *sbasep)
|
||||
{
|
||||
uint32_t sbase_addr;
|
||||
|
||||
dm_pci_read_config32(dev, SBASE_ADDR, &sbase_addr);
|
||||
*sbasep = sbase_addr & 0xfffffe00;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pch9_get_gpio_base(struct udevice *dev, u32 *gbasep)
|
||||
{
|
||||
u32 base;
|
||||
|
||||
/*
|
||||
* GPIO_BASE moved to its current offset with ICH6, but prior to
|
||||
* that it was unused (or undocumented). Check that it looks
|
||||
* okay: not all ones or zeros.
|
||||
*
|
||||
* Note we don't need check bit0 here, because the Tunnel Creek
|
||||
* GPIO base address register bit0 is reserved (read returns 0),
|
||||
* while on the Ivybridge the bit0 is used to indicate it is an
|
||||
* I/O space.
|
||||
*/
|
||||
dm_pci_read_config32(dev, GPIO_BASE, &base);
|
||||
if (base == 0x00000000 || base == 0xffffffff) {
|
||||
debug("%s: unexpected BASE value\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/*
|
||||
* Okay, I guess we're looking at the right device. The actual
|
||||
* GPIO registers are in the PCI device's I/O space, starting
|
||||
* at the offset that we just read. Bit 0 indicates that it's
|
||||
* an I/O address, not a memory address, so mask that off.
|
||||
*/
|
||||
*gbasep = base & 1 ? base & ~3 : base & ~15;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pch9_get_io_base(struct udevice *dev, u32 *iobasep)
|
||||
{
|
||||
u32 base;
|
||||
|
||||
dm_pci_read_config32(dev, IO_BASE, &base);
|
||||
if (base == 0x00000000 || base == 0xffffffff) {
|
||||
debug("%s: unexpected BASE value\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
*iobasep = base & 1 ? base & ~3 : base & ~15;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct pch_ops pch9_ops = {
|
||||
.get_spi_base = pch9_get_spi_base,
|
||||
.get_gpio_base = pch9_get_gpio_base,
|
||||
.get_io_base = pch9_get_io_base,
|
||||
};
|
||||
|
||||
static const struct udevice_id pch9_ids[] = {
|
||||
{ .compatible = "intel,pch9" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(pch9_drv) = {
|
||||
.name = "intel-pch9",
|
||||
.id = UCLASS_PCH,
|
||||
.of_match = pch9_ids,
|
||||
.ops = &pch9_ops,
|
||||
};
|
||||
@@ -0,0 +1,86 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2018 Google LLC
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <pch.h>
|
||||
|
||||
struct sandbox_pch_priv {
|
||||
bool protect;
|
||||
};
|
||||
|
||||
int sandbox_get_pch_spi_protect(struct udevice *dev)
|
||||
{
|
||||
struct sandbox_pch_priv *priv = dev_get_priv(dev);
|
||||
|
||||
return priv->protect;
|
||||
}
|
||||
|
||||
static int sandbox_pch_get_spi_base(struct udevice *dev, ulong *sbasep)
|
||||
{
|
||||
*sbasep = 0x10;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sandbox_pch_set_spi_protect(struct udevice *dev, bool protect)
|
||||
{
|
||||
struct sandbox_pch_priv *priv = dev_get_priv(dev);
|
||||
|
||||
priv->protect = protect;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sandbox_pch_get_gpio_base(struct udevice *dev, u32 *gbasep)
|
||||
{
|
||||
*gbasep = 0x20;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sandbox_pch_get_io_base(struct udevice *dev, u32 *iobasep)
|
||||
{
|
||||
*iobasep = 0x30;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sandbox_pch_ioctl(struct udevice *dev, enum pch_req_t req, void *data,
|
||||
int size)
|
||||
{
|
||||
switch (req) {
|
||||
case PCH_REQ_TEST1:
|
||||
return -ENOSYS;
|
||||
case PCH_REQ_TEST2:
|
||||
return *(char *)data;
|
||||
case PCH_REQ_TEST3:
|
||||
*(char *)data = 'x';
|
||||
return 1;
|
||||
default:
|
||||
return -ENOSYS;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct pch_ops sandbox_pch_ops = {
|
||||
.get_spi_base = sandbox_pch_get_spi_base,
|
||||
.set_spi_protect = sandbox_pch_set_spi_protect,
|
||||
.get_gpio_base = sandbox_pch_get_gpio_base,
|
||||
.get_io_base = sandbox_pch_get_io_base,
|
||||
.ioctl = sandbox_pch_ioctl,
|
||||
};
|
||||
|
||||
static const struct udevice_id sandbox_pch_ids[] = {
|
||||
{ .compatible = "sandbox,pch" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(sandbox_pch_drv) = {
|
||||
.name = "sandbox-pch",
|
||||
.id = UCLASS_PCH,
|
||||
.of_match = sandbox_pch_ids,
|
||||
.ops = &sandbox_pch_ops,
|
||||
.priv_auto_alloc_size = sizeof(struct sandbox_pch_priv),
|
||||
};
|
||||
Reference in New Issue
Block a user