1
0
mirror of https://xff.cz/git/u-boot/ synced 2025-09-01 08:42:12 +02:00
- Various x86 common codes updated for TPL/SPL
- I2C designware driver updated for PCI
- ICH SPI driver updated to support Apollo Lake
- Add Intel FSP2 base support
- Intel Apollo Lake platform specific drivers support
- Add a new board Google Chromebook Coral
This commit is contained in:
Tom Rini
2019-12-18 07:20:19 -05:00
223 changed files with 12379 additions and 715 deletions

View File

@@ -14,6 +14,9 @@ obj-$(CONFIG_SYS_I2C_AT91) += at91_i2c.o
obj-$(CONFIG_SYS_I2C_CADENCE) += i2c-cdns.o
obj-$(CONFIG_SYS_I2C_DAVINCI) += davinci_i2c.o
obj-$(CONFIG_SYS_I2C_DW) += designware_i2c.o
ifdef CONFIG_DM_PCI
obj-$(CONFIG_SYS_I2C_DW) += designware_i2c_pci.o
endif
obj-$(CONFIG_SYS_I2C_FSL) += fsl_i2c.o
obj-$(CONFIG_SYS_I2C_IHS) += ihs_i2c.o
obj-$(CONFIG_SYS_I2C_INTEL) += intel_i2c.o

View File

@@ -13,34 +13,6 @@
#include <asm/io.h>
#include "designware_i2c.h"
struct dw_scl_sda_cfg {
u32 ss_hcnt;
u32 fs_hcnt;
u32 ss_lcnt;
u32 fs_lcnt;
u32 sda_hold;
};
#ifdef CONFIG_X86
/* BayTrail HCNT/LCNT/SDA hold time */
static struct dw_scl_sda_cfg byt_config = {
.ss_hcnt = 0x200,
.fs_hcnt = 0x55,
.ss_lcnt = 0x200,
.fs_lcnt = 0x99,
.sda_hold = 0x6,
};
#endif
struct dw_i2c {
struct i2c_regs *regs;
struct dw_scl_sda_cfg *scl_sda_cfg;
struct reset_ctl_bulk resets;
#if CONFIG_IS_ENABLED(CLK)
struct clk clk;
#endif
};
#ifdef CONFIG_SYS_I2C_DW_ENABLE_STATUS_UNSUPPORTED
static int dw_i2c_enable(struct i2c_regs *i2c_base, bool enable)
{
@@ -90,7 +62,9 @@ static unsigned int __dw_i2c_set_bus_speed(struct i2c_regs *i2c_base,
unsigned int ena;
int i2c_spd;
if (speed >= I2C_MAX_SPEED)
/* Allow max speed if there is no config, or the config allows it */
if (speed >= I2C_MAX_SPEED &&
(!scl_sda_cfg || scl_sda_cfg->has_max_speed))
i2c_spd = IC_SPEED_MODE_MAX;
else if (speed >= I2C_FAST_SPEED)
i2c_spd = IC_SPEED_MODE_FAST;
@@ -106,7 +80,6 @@ static unsigned int __dw_i2c_set_bus_speed(struct i2c_regs *i2c_base,
cntl = (readl(&i2c_base->ic_con) & (~IC_CON_SPD_MSK));
switch (i2c_spd) {
#ifndef CONFIG_X86 /* No High-speed for BayTrail yet */
case IC_SPEED_MODE_MAX:
cntl |= IC_CON_SPD_SS;
if (scl_sda_cfg) {
@@ -119,7 +92,6 @@ static unsigned int __dw_i2c_set_bus_speed(struct i2c_regs *i2c_base,
writel(hcnt, &i2c_base->ic_hs_scl_hcnt);
writel(lcnt, &i2c_base->ic_hs_scl_lcnt);
break;
#endif
case IC_SPEED_MODE_STANDARD:
cntl |= IC_CON_SPD_SS;
@@ -565,25 +537,20 @@ static int designware_i2c_probe_chip(struct udevice *bus, uint chip_addr,
return ret;
}
static int designware_i2c_probe(struct udevice *bus)
static int designware_i2c_ofdata_to_platdata(struct udevice *bus)
{
struct dw_i2c *priv = dev_get_priv(bus);
priv->regs = (struct i2c_regs *)devfdt_get_addr_ptr(bus);
return 0;
}
int designware_i2c_probe(struct udevice *bus)
{
struct dw_i2c *priv = dev_get_priv(bus);
int ret;
if (device_is_on_pci_bus(bus)) {
#ifdef CONFIG_DM_PCI
/* Save base address from PCI BAR */
priv->regs = (struct i2c_regs *)
dm_pci_map_bar(bus, PCI_BASE_ADDRESS_0, PCI_REGION_MEM);
#ifdef CONFIG_X86
/* Use BayTrail specific timing values */
priv->scl_sda_cfg = &byt_config;
#endif
#endif
} else {
priv->regs = (struct i2c_regs *)devfdt_get_addr_ptr(bus);
}
ret = reset_get_bulk(bus, &priv->resets);
if (ret)
dev_warn(bus, "Can't get reset: %d\n", ret);
@@ -606,7 +573,7 @@ static int designware_i2c_probe(struct udevice *bus)
return __dw_i2c_init(priv->regs, 0, 0);
}
static int designware_i2c_remove(struct udevice *dev)
int designware_i2c_remove(struct udevice *dev)
{
struct dw_i2c *priv = dev_get_priv(dev);
@@ -618,30 +585,7 @@ static int designware_i2c_remove(struct udevice *dev)
return reset_release_bulk(&priv->resets);
}
static int designware_i2c_bind(struct udevice *dev)
{
static int num_cards;
char name[20];
/* Create a unique device name for PCI type devices */
if (device_is_on_pci_bus(dev)) {
/*
* ToDo:
* Setting req_seq in the driver is probably not recommended.
* But without a DT alias the number is not configured. And
* using this driver is impossible for PCIe I2C devices.
* This can be removed, once a better (correct) way for this
* is found and implemented.
*/
dev->req_seq = num_cards;
sprintf(name, "i2c_designware#%u", num_cards++);
device_set_name(dev, name);
}
return 0;
}
static const struct dm_i2c_ops designware_i2c_ops = {
const struct dm_i2c_ops designware_i2c_ops = {
.xfer = designware_i2c_xfer,
.probe_chip = designware_i2c_probe_chip,
.set_bus_speed = designware_i2c_set_bus_speed,
@@ -656,28 +600,12 @@ U_BOOT_DRIVER(i2c_designware) = {
.name = "i2c_designware",
.id = UCLASS_I2C,
.of_match = designware_i2c_ids,
.bind = designware_i2c_bind,
.ofdata_to_platdata = designware_i2c_ofdata_to_platdata,
.probe = designware_i2c_probe,
.priv_auto_alloc_size = sizeof(struct dw_i2c),
.remove = designware_i2c_remove,
.flags = DM_FLAG_OS_PREPARE,
.flags = DM_FLAG_OS_PREPARE,
.ops = &designware_i2c_ops,
};
#ifdef CONFIG_X86
static struct pci_device_id designware_pci_supported[] = {
/* Intel BayTrail has 7 I2C controller located on the PCI bus */
{ PCI_VDEVICE(INTEL, 0x0f41) },
{ PCI_VDEVICE(INTEL, 0x0f42) },
{ PCI_VDEVICE(INTEL, 0x0f43) },
{ PCI_VDEVICE(INTEL, 0x0f44) },
{ PCI_VDEVICE(INTEL, 0x0f45) },
{ PCI_VDEVICE(INTEL, 0x0f46) },
{ PCI_VDEVICE(INTEL, 0x0f47) },
{},
};
U_BOOT_PCI_DEVICE(i2c_designware, designware_pci_supported);
#endif
#endif /* CONFIG_DM_I2C */

View File

@@ -7,6 +7,8 @@
#ifndef __DW_I2C_H_
#define __DW_I2C_H_
#include <reset.h>
struct i2c_regs {
u32 ic_con; /* 0x00 */
u32 ic_tar; /* 0x04 */
@@ -131,4 +133,37 @@ struct i2c_regs {
#define I2C_FAST_SPEED 400000
#define I2C_STANDARD_SPEED 100000
/**
* struct dw_scl_sda_cfg - I2C timing configuration
*
* @has_max_speed: Support maximum speed (1Mbps)
* @ss_hcnt: Standard speed high time in ns
* @fs_hcnt: Fast speed high time in ns
* @ss_lcnt: Standard speed low time in ns
* @fs_lcnt: Fast speed low time in ns
* @sda_hold: SDA hold time
*/
struct dw_scl_sda_cfg {
bool has_max_speed;
u32 ss_hcnt;
u32 fs_hcnt;
u32 ss_lcnt;
u32 fs_lcnt;
u32 sda_hold;
};
struct dw_i2c {
struct i2c_regs *regs;
struct dw_scl_sda_cfg *scl_sda_cfg;
struct reset_ctl_bulk resets;
#if CONFIG_IS_ENABLED(CLK)
struct clk clk;
#endif
};
extern const struct dm_i2c_ops designware_i2c_ops;
int designware_i2c_probe(struct udevice *bus);
int designware_i2c_remove(struct udevice *dev);
#endif /* __DW_I2C_H_ */

View File

@@ -0,0 +1,144 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* (C) Copyright 2009
* Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com.
* Copyright 2019 Google Inc
*/
#include <common.h>
#include <dm.h>
#include <spl.h>
#include <asm/lpss.h>
#include "designware_i2c.h"
enum {
VANILLA = 0, /* standard I2C with no tweaks */
INTEL_APL, /* Apollo Lake I2C */
};
/* BayTrail HCNT/LCNT/SDA hold time */
static struct dw_scl_sda_cfg byt_config = {
.ss_hcnt = 0x200,
.fs_hcnt = 0x55,
.ss_lcnt = 0x200,
.fs_lcnt = 0x99,
.sda_hold = 0x6,
};
/* Have a weak function for now - possibly should be a new uclass */
__weak void lpss_reset_release(void *regs);
static int designware_i2c_pci_ofdata_to_platdata(struct udevice *dev)
{
struct dw_i2c *priv = dev_get_priv(dev);
if (spl_phase() < PHASE_SPL) {
u32 base;
int ret;
ret = dev_read_u32(dev, "early-regs", &base);
if (ret)
return log_msg_ret("early-regs", ret);
/* Set i2c base address */
dm_pci_write_config32(dev, PCI_BASE_ADDRESS_0, base);
/* Enable memory access and bus master */
dm_pci_write_config32(dev, PCI_COMMAND, PCI_COMMAND_MEMORY |
PCI_COMMAND_MASTER);
}
if (spl_phase() < PHASE_BOARD_F) {
/* Handle early, fixed mapping into a different address space */
priv->regs = (struct i2c_regs *)dm_pci_read_bar32(dev, 0);
} else {
priv->regs = (struct i2c_regs *)
dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, PCI_REGION_MEM);
}
if (!priv->regs)
return -EINVAL;
/* Save base address from PCI BAR */
if (IS_ENABLED(CONFIG_INTEL_BAYTRAIL))
/* Use BayTrail specific timing values */
priv->scl_sda_cfg = &byt_config;
return 0;
}
static int designware_i2c_pci_probe(struct udevice *dev)
{
struct dw_i2c *priv = dev_get_priv(dev);
if (dev_get_driver_data(dev) == INTEL_APL) {
/* Ensure controller is in D0 state */
lpss_set_power_state(dev, STATE_D0);
lpss_reset_release(priv->regs);
}
return designware_i2c_probe(dev);
}
static int designware_i2c_pci_bind(struct udevice *dev)
{
char name[20];
/*
* Create a unique device name for PCI type devices
* ToDo:
* Setting req_seq in the driver is probably not recommended.
* But without a DT alias the number is not configured. And
* using this driver is impossible for PCIe I2C devices.
* This can be removed, once a better (correct) way for this
* is found and implemented.
*
* TODO(sjg@chromium.org): Perhaps if uclasses had platdata this would
* be possible. We cannot use static data in drivers since they may be
* used in SPL or before relocation.
*/
dev->req_seq = gd->arch.dw_i2c_num_cards++;
sprintf(name, "i2c_designware#%u", dev->req_seq);
device_set_name(dev, name);
return 0;
}
static const struct udevice_id designware_i2c_pci_ids[] = {
{ .compatible = "snps,designware-i2c-pci" },
{ .compatible = "intel,apl-i2c", .data = INTEL_APL },
{ }
};
U_BOOT_DRIVER(i2c_designware_pci) = {
.name = "i2c_designware_pci",
.id = UCLASS_I2C,
.of_match = designware_i2c_pci_ids,
.bind = designware_i2c_pci_bind,
.ofdata_to_platdata = designware_i2c_pci_ofdata_to_platdata,
.probe = designware_i2c_pci_probe,
.priv_auto_alloc_size = sizeof(struct dw_i2c),
.remove = designware_i2c_remove,
.flags = DM_FLAG_OS_PREPARE,
.ops = &designware_i2c_ops,
};
static struct pci_device_id designware_pci_supported[] = {
/* Intel BayTrail has 7 I2C controller located on the PCI bus */
{ PCI_VDEVICE(INTEL, 0x0f41) },
{ PCI_VDEVICE(INTEL, 0x0f42) },
{ PCI_VDEVICE(INTEL, 0x0f43) },
{ PCI_VDEVICE(INTEL, 0x0f44) },
{ PCI_VDEVICE(INTEL, 0x0f45) },
{ PCI_VDEVICE(INTEL, 0x0f46) },
{ PCI_VDEVICE(INTEL, 0x0f47) },
{ PCI_VDEVICE(INTEL, 0x5aac), .driver_data = INTEL_APL },
{ PCI_VDEVICE(INTEL, 0x5aae), .driver_data = INTEL_APL },
{ PCI_VDEVICE(INTEL, 0x5ab0), .driver_data = INTEL_APL },
{ PCI_VDEVICE(INTEL, 0x5ab2), .driver_data = INTEL_APL },
{ PCI_VDEVICE(INTEL, 0x5ab4), .driver_data = INTEL_APL },
{ PCI_VDEVICE(INTEL, 0x5ab6), .driver_data = INTEL_APL },
{},
};
U_BOOT_PCI_DEVICE(i2c_designware_pci, designware_pci_supported);

View File

@@ -11,7 +11,7 @@
#include <dm/device-internal.h>
#include <dm/lists.h>
#include <dm/pinctrl.h>
#ifdef CONFIG_DM_GPIO
#if CONFIG_IS_ENABLED(DM_GPIO)
#include <asm/gpio.h>
#endif
@@ -485,7 +485,7 @@ uint i2c_get_chip_addr_offset_mask(struct udevice *dev)
return chip->chip_addr_offset_mask;
}
#ifdef CONFIG_DM_GPIO
#if CONFIG_IS_ENABLED(DM_GPIO)
static void i2c_gpio_set_pin(struct gpio_desc *pin, int bit)
{
if (bit)
@@ -581,7 +581,7 @@ static int i2c_deblock_gpio(struct udevice *bus)
{
return -ENOSYS;
}
#endif // CONFIG_DM_GPIO
#endif /* DM_GPIO */
int i2c_deblock(struct udevice *bus)
{

View File

@@ -125,7 +125,7 @@ static int pca954x_ofdata_to_platdata(struct udevice *dev)
static int pca954x_probe(struct udevice *dev)
{
if (IS_ENABLED(CONFIG_DM_GPIO)) {
if (CONFIG_IS_ENABLED(DM_GPIO)) {
struct pca954x_priv *priv = dev_get_priv(dev);
int err;
@@ -146,7 +146,7 @@ static int pca954x_probe(struct udevice *dev)
static int pca954x_remove(struct udevice *dev)
{
if (IS_ENABLED(CONFIG_DM_GPIO)) {
if (CONFIG_IS_ENABLED(DM_GPIO)) {
struct pca954x_priv *priv = dev_get_priv(dev);
if (dm_gpio_is_valid(&priv->gpio_mux_reset))