mirror of
https://xff.cz/git/u-boot/
synced 2025-09-01 08:42:12 +02:00
Merge branch 'next' of https://gitlab.denx.de/u-boot/custodians/u-boot-x86 into next
- 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:
@@ -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
|
||||
|
@@ -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 */
|
||||
|
@@ -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_ */
|
||||
|
144
drivers/i2c/designware_i2c_pci.c
Normal file
144
drivers/i2c/designware_i2c_pci.c
Normal 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);
|
@@ -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)
|
||||
{
|
||||
|
@@ -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))
|
||||
|
Reference in New Issue
Block a user