Merge tag 'v2024.10-rc3' into next

Prepare v2024.10-rc3
This commit is contained in:
Tom Rini
2024-08-19 18:24:58 -06:00
304 changed files with 14534 additions and 8494 deletions

View File

@@ -650,7 +650,7 @@ config SYS_I2C_GENI
config SYS_I2C_S3C24X0
bool "Samsung I2C driver"
depends on (ARCH_EXYNOS4 || ARCH_EXYNOS5) && DM_I2C
depends on DM_I2C
help
Support for Samsung I2C controller as Samsung SoCs.

View File

@@ -9,11 +9,15 @@
#include <dm.h>
#include <i2c.h>
#include <log.h>
#if IS_ENABLED(CONFIG_ARCH_EXYNOS4) || IS_ENABLED(CONFIG_ARCH_EXYNOS5)
#include <asm/arch/clk.h>
#include <asm/arch/cpu.h>
#include <asm/arch/pinmux.h>
#endif
#include <asm/global_data.h>
#include <asm/io.h>
#include <linux/delay.h>
#include <clk.h>
#include "s3c24x0_i2c.h"
DECLARE_GLOBAL_DATA_PTR;
@@ -137,18 +141,25 @@ static int hsi2c_wait_for_trx(struct exynos5_hsi2c *i2c)
return I2C_NOK_TOUT;
}
static int hsi2c_get_clk_details(struct s3c24x0_i2c_bus *i2c_bus)
static int hsi2c_get_clk_details(struct udevice *dev)
{
struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev);
struct exynos5_hsi2c *hsregs = i2c_bus->hsregs;
ulong clkin;
unsigned int op_clk = i2c_bus->clock_frequency;
unsigned int i = 0, utemp0 = 0, utemp1 = 0;
unsigned int t_ftl_cycle;
#if defined(CONFIG_ARCH_EXYNOS4) || defined(CONFIG_ARCH_EXYNOS5)
#if IS_ENABLED(CONFIG_ARCH_EXYNOS4) || IS_ENABLED(CONFIG_ARCH_EXYNOS5)
clkin = get_i2c_clk();
#else
clkin = get_PCLK();
struct clk clk;
int ret;
ret = clk_get_by_name(dev, "hsi2c", &clk);
if (ret < 0)
return ret;
clkin = clk_get_rate(&clk);
#endif
/* FPCLK / FI2C =
* (CLK_DIV + 1) * (TSCLK_L + TSCLK_H + 2) + 8 + 2 * FLT_CYCLE
@@ -491,7 +502,7 @@ static int s3c24x0_i2c_set_bus_speed(struct udevice *dev, unsigned int speed)
i2c_bus->clock_frequency = speed;
if (hsi2c_get_clk_details(i2c_bus))
if (hsi2c_get_clk_details(dev))
return -EFAULT;
hsi2c_ch_init(i2c_bus);
@@ -518,7 +529,9 @@ static int s3c24x0_i2c_probe(struct udevice *dev, uint chip, uint chip_flags)
static int s3c_i2c_of_to_plat(struct udevice *dev)
{
#if IS_ENABLED(CONFIG_ARCH_EXYNOS4) || IS_ENABLED(CONFIG_ARCH_EXYNOS5)
const void *blob = gd->fdt_blob;
#endif
struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev);
int node;
@@ -526,7 +539,9 @@ static int s3c_i2c_of_to_plat(struct udevice *dev)
i2c_bus->hsregs = dev_read_addr_ptr(dev);
#if IS_ENABLED(CONFIG_ARCH_EXYNOS4) || IS_ENABLED(CONFIG_ARCH_EXYNOS5)
i2c_bus->id = pinmux_decode_periph_id(blob, node);
#endif
i2c_bus->clock_frequency =
dev_read_u32_default(dev, "clock-frequency",
@@ -534,7 +549,9 @@ static int s3c_i2c_of_to_plat(struct udevice *dev)
i2c_bus->node = node;
i2c_bus->bus_num = dev_seq(dev);
#if IS_ENABLED(CONFIG_ARCH_EXYNOS4) || IS_ENABLED(CONFIG_ARCH_EXYNOS5)
exynos_pinmux_config(i2c_bus->id, PINMUX_FLAG_HS_MODE);
#endif
i2c_bus->active = true;

View File

@@ -19,7 +19,10 @@
#define LPI2C_NACK_TOUT_MS 1
#define LPI2C_TIMEOUT_MS 100
static int bus_i2c_init(struct udevice *bus, int speed);
#define LPI2C_CHUNK_DATA 256U
#define LPI2C_CHUNK_LEN_MIN 1U
static int bus_i2c_init(struct udevice *bus);
/* Weak linked function for overridden by some SoC power function */
int __weak init_i2c_power(unsigned i2c_num)
@@ -118,8 +121,10 @@ static int bus_i2c_send(struct udevice *bus, u8 *txbuf, int len)
static int bus_i2c_receive(struct udevice *bus, u8 *rxbuf, int len)
{
struct dm_i2c_bus *i2c = dev_get_uclass_priv(bus);
struct imx_lpi2c_bus *i2c_bus = dev_get_priv(bus);
struct imx_lpi2c_reg *regs = (struct imx_lpi2c_reg *)(i2c_bus->base);
unsigned int chunk_len, rx_remain, timeout;
lpi2c_status_t result = LPI2C_SUCESS;
u32 val;
ulong start_time = get_timer(0);
@@ -128,33 +133,50 @@ static int bus_i2c_receive(struct udevice *bus, u8 *rxbuf, int len)
if (!len)
return result;
result = bus_i2c_wait_for_tx_ready(regs);
if (result) {
debug("i2c: receive wait fot tx ready: %d\n", result);
return result;
}
/*
* Extend the timeout for a bulk read if needed.
* The calculated timeout is the result of multiplying the
* transfer length with 8 bit + ACK + one clock of extra time,
* considering the I2C bus frequency.
*/
timeout = max(len * 10 * 1000 / i2c->speed_hz, LPI2C_TIMEOUT_MS);
/* clear all status flags */
writel(0x7f00, &regs->msr);
/* send receive command */
val = LPI2C_MTDR_CMD(0x1) | LPI2C_MTDR_DATA(len - 1);
writel(val, &regs->mtdr);
rx_remain = len;
while (rx_remain > 0) {
chunk_len = clamp(rx_remain, LPI2C_CHUNK_LEN_MIN, LPI2C_CHUNK_DATA) - 1;
while (len--) {
do {
result = imx_lpci2c_check_clear_error(regs);
if (result) {
debug("i2c: receive check clear error: %d\n",
result);
return result;
}
if (get_timer(start_time) > LPI2C_TIMEOUT_MS) {
debug("i2c: receive mrdr: timeout\n");
return -1;
}
val = readl(&regs->mrdr);
} while (val & LPI2C_MRDR_RXEMPTY_MASK);
*rxbuf++ = LPI2C_MRDR_DATA(val);
result = bus_i2c_wait_for_tx_ready(regs);
if (result) {
debug("i2c: receive wait for tx ready: %d\n", result);
return result;
}
/* clear all status flags */
writel(0x7f00, &regs->msr);
/* send receive command */
writel(LPI2C_MTDR_CMD(0x1) | LPI2C_MTDR_DATA(chunk_len), &regs->mtdr);
rx_remain = rx_remain - (chunk_len & 0xff) - 1;
while (len--) {
do {
result = imx_lpci2c_check_clear_error(regs);
if (result) {
debug("i2c: receive check clear error: %d\n",
result);
return result;
}
if (get_timer(start_time) > timeout) {
debug("i2c: receive mrdr: timeout\n");
return -1;
}
val = readl(&regs->mrdr);
} while (val & LPI2C_MRDR_RXEMPTY_MASK);
*rxbuf++ = LPI2C_MRDR_DATA(val);
/* send next receive command before controller NACKs last byte */
if ((len - rx_remain) < 2 && rx_remain > 0)
break;
}
}
return result;
@@ -172,7 +194,7 @@ static int bus_i2c_start(struct udevice *bus, u8 addr, u8 dir)
debug("i2c: start check busy bus: 0x%x\n", result);
/* Try to init the lpi2c then check the bus busy again */
bus_i2c_init(bus, I2C_SPEED_STANDARD_RATE);
bus_i2c_init(bus);
result = imx_lpci2c_check_busy_bus(regs);
if (result) {
printf("i2c: Error check busy bus: 0x%x\n", result);
@@ -344,11 +366,14 @@ static int bus_i2c_set_bus_speed(struct udevice *bus, int speed)
return 0;
}
static int bus_i2c_init(struct udevice *bus, int speed)
static int bus_i2c_init(struct udevice *bus)
{
u32 val;
int ret;
struct dm_i2c_bus *i2c = dev_get_uclass_priv(bus);
int speed = i2c->speed_hz;
struct imx_lpi2c_bus *i2c_bus = dev_get_priv(bus);
struct imx_lpi2c_reg *regs = (struct imx_lpi2c_reg *)(i2c_bus->base);
/* reset peripheral */
@@ -388,13 +413,13 @@ static int imx_lpi2c_probe_chip(struct udevice *bus, u32 chip,
result = bus_i2c_start(bus, chip, 0);
if (result) {
bus_i2c_stop(bus);
bus_i2c_init(bus, I2C_SPEED_STANDARD_RATE);
bus_i2c_init(bus);
return result;
}
result = bus_i2c_stop(bus);
if (result)
bus_i2c_init(bus, I2C_SPEED_STANDARD_RATE);
bus_i2c_init(bus);
return result;
}
@@ -489,7 +514,7 @@ static int imx_lpi2c_probe(struct udevice *bus)
return ret;
}
ret = bus_i2c_init(bus, I2C_SPEED_STANDARD_RATE);
ret = bus_i2c_init(bus);
if (ret < 0)
return ret;

View File

@@ -54,7 +54,7 @@ int i2c_arbitrator_select(struct udevice *mux, struct udevice *bus,
/* Indicate that we want to claim the bus */
ret = dm_gpio_set_value(&priv->ap_claim, 1);
if (ret)
goto err;
return ret;
udelay(priv->slew_delay_us);
/* Wait for the EC to release it */
@@ -62,7 +62,7 @@ int i2c_arbitrator_select(struct udevice *mux, struct udevice *bus,
while (get_timer(start_retry) < priv->wait_retry_ms) {
ret = dm_gpio_get_value(&priv->ec_claim);
if (ret < 0) {
goto err;
return ret;
} else if (!ret) {
/* We got it, so return */
return 0;
@@ -75,17 +75,14 @@ int i2c_arbitrator_select(struct udevice *mux, struct udevice *bus,
/* It didn't release, so give up, wait, and try again */
ret = dm_gpio_set_value(&priv->ap_claim, 0);
if (ret)
goto err;
return ret;
mdelay(priv->wait_retry_ms);
} while (get_timer(start) < priv->wait_free_ms);
/* Give up, release our claim */
printf("I2C: Could not claim bus, timeout %lu\n", get_timer(start));
ret = -ETIMEDOUT;
ret = 0;
err:
return ret;
return -ETIMEDOUT;
}
static int i2c_arbitrator_probe(struct udevice *dev)

View File

@@ -10,12 +10,9 @@
#include <i2c.h>
#include <log.h>
#include <malloc.h>
#include <asm/global_data.h>
#include <asm-generic/gpio.h>
DECLARE_GLOBAL_DATA_PTR;
enum pca_type {
PCA9543,
PCA9544,

View File

@@ -8,17 +8,16 @@
#include <dm.h>
#include <fdtdec.h>
#include <time.h>
#if defined(CONFIG_ARCH_EXYNOS4) || defined(CONFIG_ARCH_EXYNOS5)
#include <log.h>
#if IS_ENABLED(CONFIG_ARCH_EXYNOS4) || IS_ENABLED(CONFIG_ARCH_EXYNOS5)
#include <asm/arch/clk.h>
#include <asm/arch/cpu.h>
#include <asm/arch/pinmux.h>
#else
#include <asm/arch/s3c24x0_cpu.h>
#endif
#include <asm/global_data.h>
#include <asm/io.h>
#include <i2c.h>
#include <clk.h>
#include "s3c24x0_i2c.h"
DECLARE_GLOBAL_DATA_PTR;
@@ -50,13 +49,22 @@ static void read_write_byte(struct s3c24x0_i2c *i2c)
clrbits_le32(&i2c->iiccon, I2CCON_IRPND);
}
static void i2c_ch_init(struct s3c24x0_i2c *i2c, int speed, int slaveadd)
static int i2c_ch_init(struct udevice *dev, int speed, int slaveadd)
{
struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev);
struct s3c24x0_i2c *i2c = i2c_bus->regs;
ulong freq, pres = 16, div;
#if defined(CONFIG_ARCH_EXYNOS4) || defined(CONFIG_ARCH_EXYNOS5)
#if IS_ENABLED(CONFIG_ARCH_EXYNOS4) || defined(CONFIG_ARCH_EXYNOS5)
freq = get_i2c_clk();
#else
freq = get_PCLK();
struct clk clk;
int ret;
ret = clk_get_by_name(dev, "i2c", &clk);
if (ret < 0)
return ret;
freq = clk_get_rate(&clk);
#endif
/* calculate prescaler and divisor values */
if ((freq / pres / (16 + 1)) > speed)
@@ -75,6 +83,7 @@ static void i2c_ch_init(struct s3c24x0_i2c *i2c, int speed, int slaveadd)
writel(slaveadd, &i2c->iicadd);
/* program Master Transmit (and implicit STOP) */
writel(I2C_MODE_MT | I2C_TXRX_ENA, &i2c->iicstat);
return 0;
}
#define SYS_I2C_S3C24X0_SLAVE_ADDR 0
@@ -85,8 +94,9 @@ static int s3c24x0_i2c_set_bus_speed(struct udevice *dev, unsigned int speed)
i2c_bus->clock_frequency = speed;
i2c_ch_init(i2c_bus->regs, i2c_bus->clock_frequency,
SYS_I2C_S3C24X0_SLAVE_ADDR);
if (i2c_ch_init(dev, i2c_bus->clock_frequency,
SYS_I2C_S3C24X0_SLAVE_ADDR))
return -EFAULT;
return 0;
}
@@ -301,7 +311,9 @@ static int s3c24x0_i2c_xfer(struct udevice *dev, struct i2c_msg *msg,
static int s3c_i2c_of_to_plat(struct udevice *dev)
{
#if IS_ENABLED(CONFIG_ARCH_EXYNOS4) || IS_ENABLED(CONFIG_ARCH_EXYNOS5)
const void *blob = gd->fdt_blob;
#endif
struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev);
int node;
@@ -309,7 +321,9 @@ static int s3c_i2c_of_to_plat(struct udevice *dev)
i2c_bus->regs = dev_read_addr_ptr(dev);
#if IS_ENABLED(CONFIG_ARCH_EXYNOS4) || IS_ENABLED(CONFIG_ARCH_EXYNOS5)
i2c_bus->id = pinmux_decode_periph_id(blob, node);
#endif
i2c_bus->clock_frequency =
dev_read_u32_default(dev, "clock-frequency",
@@ -317,7 +331,9 @@ static int s3c_i2c_of_to_plat(struct udevice *dev)
i2c_bus->node = node;
i2c_bus->bus_num = dev_seq(dev);
#if IS_ENABLED(CONFIG_ARCH_EXYNOS4) || IS_ENABLED(CONFIG_ARCH_EXYNOS5)
exynos_pinmux_config(i2c_bus->id, 0);
#endif
i2c_bus->active = true;

View File

@@ -54,7 +54,9 @@ struct s3c24x0_i2c_bus {
struct exynos5_hsi2c *hsregs;
int is_highspeed; /* High speed type, rather than I2C */
unsigned clock_frequency;
#if IS_ENABLED(CONFIG_ARCH_EXYNOS4) || IS_ENABLED(CONFIG_ARCH_EXYNOS5)
int id;
#endif
unsigned clk_cycle;
unsigned clk_div;
};