commit
9804d88630
File diff suppressed because it is too large
Load Diff
@ -1,36 +0,0 @@ |
||||
/*
|
||||
* arch/arm/mach-rmobile/include/mach/r8a7795.h |
||||
* This file defines registers and value for r8a7795. |
||||
* |
||||
* Copyright (C) 2015 Renesas Electronics Corporation |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#ifndef __ASM_ARCH_R8A7795_H |
||||
#define __ASM_ARCH_R8A7795_H |
||||
|
||||
#include "rcar-gen3-base.h" |
||||
|
||||
/* Module stop control/status register bits */ |
||||
#define MSTP0_BITS 0x00640800 |
||||
#define MSTP1_BITS 0xF3EE9390 |
||||
#define MSTP2_BITS 0x340FAFDC |
||||
#define MSTP3_BITS 0xD80C7CDF |
||||
#define MSTP4_BITS 0x80000184 |
||||
#define MSTP5_BITS 0x40BFFF46 |
||||
#define MSTP6_BITS 0xE5FBEECF |
||||
#define MSTP7_BITS 0x39FFFF0E |
||||
#define MSTP8_BITS 0x01F19FF4 |
||||
#define MSTP9_BITS 0xFFDFFFFF |
||||
#define MSTP10_BITS 0xFFFEFFE0 |
||||
#define MSTP11_BITS 0x00000000 |
||||
|
||||
/* SDHI */ |
||||
#define CONFIG_SYS_SH_SDHI0_BASE 0xEE100000 |
||||
#define CONFIG_SYS_SH_SDHI1_BASE 0xEE120000 |
||||
#define CONFIG_SYS_SH_SDHI2_BASE 0xEE140000 /* either MMC0 */ |
||||
#define CONFIG_SYS_SH_SDHI3_BASE 0xEE160000 /* either MMC1 */ |
||||
#define CONFIG_SYS_SH_SDHI_NR_CHANNEL 4 |
||||
|
||||
#endif /* __ASM_ARCH_R8A7795_H */ |
File diff suppressed because it is too large
Load Diff
@ -1,36 +0,0 @@ |
||||
/*
|
||||
* arch/arm/include/asm/arch-rcar_gen3/r8a7796.h |
||||
* This file defines registers and value for r8a7796. |
||||
* |
||||
* Copyright (C) 2016 Renesas Electronics Corporation |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#ifndef __ASM_ARCH_R8A7796_H |
||||
#define __ASM_ARCH_R8A7796_H |
||||
|
||||
#include "rcar-gen3-base.h" |
||||
|
||||
/* Module stop control/status register bits */ |
||||
#define MSTP0_BITS 0x00200000 |
||||
#define MSTP1_BITS 0xFFFFFFFF |
||||
#define MSTP2_BITS 0x340E2FDC |
||||
#define MSTP3_BITS 0xFFFFFFDF |
||||
#define MSTP4_BITS 0x80000184 |
||||
#define MSTP5_BITS 0xC3FFFFFF |
||||
#define MSTP6_BITS 0xFFFFFFFF |
||||
#define MSTP7_BITS 0xFFFFFFFF |
||||
#define MSTP8_BITS 0x01F1FFF7 |
||||
#define MSTP9_BITS 0xFFFFFFFE |
||||
#define MSTP10_BITS 0xFFFEFFE0 |
||||
#define MSTP11_BITS 0x000000B7 |
||||
|
||||
/* SDHI */ |
||||
#define CONFIG_SYS_SH_SDHI0_BASE 0xEE100000 |
||||
#define CONFIG_SYS_SH_SDHI1_BASE 0xEE120000 |
||||
#define CONFIG_SYS_SH_SDHI2_BASE 0xEE140000 /* either MMC0 */ |
||||
#define CONFIG_SYS_SH_SDHI3_BASE 0xEE160000 /* either MMC1 */ |
||||
#define CONFIG_SYS_SH_SDHI_NR_CHANNEL 4 |
||||
|
||||
#endif /* __ASM_ARCH_R8A7796_H */ |
@ -0,0 +1,66 @@ |
||||
/*
|
||||
* Renesas RCar Gen3 memory map tables |
||||
* |
||||
* Copyright (C) 2017 Marek Vasut <marek.vasut@gmail.com> |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <asm/armv8/mmu.h> |
||||
|
||||
static struct mm_region r8a7795_mem_map[] = { |
||||
{ |
||||
.virt = 0x0UL, |
||||
.phys = 0x0UL, |
||||
.size = 0x80000000UL, |
||||
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | |
||||
PTE_BLOCK_INNER_SHARE |
||||
}, { |
||||
.virt = 0x80000000UL, |
||||
.phys = 0x80000000UL, |
||||
.size = 0x80000000UL, |
||||
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | |
||||
PTE_BLOCK_NON_SHARE | |
||||
PTE_BLOCK_PXN | PTE_BLOCK_UXN |
||||
}, { |
||||
/* List terminator */ |
||||
0, |
||||
} |
||||
}; |
||||
|
||||
static struct mm_region r8a7796_mem_map[] = { |
||||
{ |
||||
.virt = 0x0UL, |
||||
.phys = 0x0UL, |
||||
.size = 0xe0000000UL, |
||||
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | |
||||
PTE_BLOCK_INNER_SHARE |
||||
}, { |
||||
.virt = 0xe0000000UL, |
||||
.phys = 0xe0000000UL, |
||||
.size = 0xe0000000UL, |
||||
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | |
||||
PTE_BLOCK_NON_SHARE | |
||||
PTE_BLOCK_PXN | PTE_BLOCK_UXN |
||||
}, { |
||||
/* List terminator */ |
||||
0, |
||||
} |
||||
}; |
||||
|
||||
struct mm_region *mem_map = r8a7795_mem_map; |
||||
|
||||
void rcar_gen3_memmap_fixup(void) |
||||
{ |
||||
u32 cpu_type = rmobile_get_cpu_type(); |
||||
|
||||
switch (cpu_type) { |
||||
case RMOBILE_CPU_TYPE_R8A7795: |
||||
mem_map = r8a7795_mem_map; |
||||
break; |
||||
case RMOBILE_CPU_TYPE_R8A7796: |
||||
mem_map = r8a7796_mem_map; |
||||
break; |
||||
} |
||||
} |
@ -1,30 +0,0 @@ |
||||
/*
|
||||
* Copyright (C) 2016 Nobuhiro Iwamatsu <iwamatsu@nigauri.org> |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <asm/armv8/mmu.h> |
||||
|
||||
static struct mm_region r8a7795_mem_map[] = { |
||||
{ |
||||
.virt = 0x0UL, |
||||
.phys = 0x0UL, |
||||
.size = 0x80000000UL, |
||||
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | |
||||
PTE_BLOCK_INNER_SHARE |
||||
}, { |
||||
.virt = 0x80000000UL, |
||||
.phys = 0x80000000UL, |
||||
.size = 0x80000000UL, |
||||
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | |
||||
PTE_BLOCK_NON_SHARE | |
||||
PTE_BLOCK_PXN | PTE_BLOCK_UXN |
||||
}, { |
||||
/* List terminator */ |
||||
0, |
||||
} |
||||
}; |
||||
|
||||
struct mm_region *mem_map = r8a7795_mem_map; |
@ -1,30 +0,0 @@ |
||||
/*
|
||||
* Copyright (C) 2017 Marek Vasut <marek.vasut+renesas@gmail.com> |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <asm/armv8/mmu.h> |
||||
|
||||
static struct mm_region r8a7796_mem_map[] = { |
||||
{ |
||||
.virt = 0x0UL, |
||||
.phys = 0x0UL, |
||||
.size = 0xe0000000UL, |
||||
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | |
||||
PTE_BLOCK_INNER_SHARE |
||||
}, { |
||||
.virt = 0xe0000000UL, |
||||
.phys = 0xe0000000UL, |
||||
.size = 0xe0000000UL, |
||||
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | |
||||
PTE_BLOCK_NON_SHARE | |
||||
PTE_BLOCK_PXN | PTE_BLOCK_UXN |
||||
}, { |
||||
/* List terminator */ |
||||
0, |
||||
} |
||||
}; |
||||
|
||||
struct mm_region *mem_map = r8a7796_mem_map; |
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,271 @@ |
||||
/*
|
||||
* Renesas RCar IIC driver |
||||
* |
||||
* Copyright (C) 2017 Marek Vasut <marek.vasut@gmail.com> |
||||
* |
||||
* Based on |
||||
* Copyright (C) 2011, 2013 Renesas Solutions Corp. |
||||
* Copyright (C) 2011, 2013 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com> |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <clk.h> |
||||
#include <dm.h> |
||||
#include <i2c.h> |
||||
#include <asm/io.h> |
||||
|
||||
struct rcar_iic_priv { |
||||
void __iomem *base; |
||||
struct clk clk; |
||||
u8 iccl; |
||||
u8 icch; |
||||
}; |
||||
|
||||
#define RCAR_IIC_ICDR 0x00 |
||||
#define RCAR_IIC_ICCR 0x04 |
||||
#define RCAR_IIC_ICSR 0x08 |
||||
#define RCAR_IIC_ICIC 0x0c |
||||
#define RCAR_IIC_ICCL 0x10 |
||||
#define RCAR_IIC_ICCH 0x14 |
||||
|
||||
/* ICCR */ |
||||
#define RCAR_IIC_ICCR_ICE BIT(7) |
||||
#define RCAR_IIC_ICCR_RACK BIT(6) |
||||
#define RCAR_IIC_ICCR_RTS BIT(4) |
||||
#define RCAR_IIC_ICCR_BUSY BIT(2) |
||||
#define RCAR_IIC_ICCR_SCP BIT(0) |
||||
|
||||
/* ICSR / ICIC */ |
||||
#define RCAR_IC_BUSY BIT(4) |
||||
#define RCAR_IC_TACK BIT(2) |
||||
#define RCAR_IC_DTE BIT(0) |
||||
|
||||
#define IRQ_WAIT 1000 |
||||
|
||||
static void sh_irq_dte(struct udevice *dev) |
||||
{ |
||||
struct rcar_iic_priv *priv = dev_get_priv(dev); |
||||
int i; |
||||
|
||||
for (i = 0; i < IRQ_WAIT; i++) { |
||||
if (RCAR_IC_DTE & readb(priv->base + RCAR_IIC_ICSR)) |
||||
break; |
||||
udelay(10); |
||||
} |
||||
} |
||||
|
||||
static int sh_irq_dte_with_tack(struct udevice *dev) |
||||
{ |
||||
struct rcar_iic_priv *priv = dev_get_priv(dev); |
||||
int i; |
||||
|
||||
for (i = 0; i < IRQ_WAIT; i++) { |
||||
if (RCAR_IC_DTE & readb(priv->base + RCAR_IIC_ICSR)) |
||||
break; |
||||
if (RCAR_IC_TACK & readb(priv->base + RCAR_IIC_ICSR)) |
||||
return -ETIMEDOUT; |
||||
udelay(10); |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
static void sh_irq_busy(struct udevice *dev) |
||||
{ |
||||
struct rcar_iic_priv *priv = dev_get_priv(dev); |
||||
int i; |
||||
|
||||
for (i = 0; i < IRQ_WAIT; i++) { |
||||
if (!(RCAR_IC_BUSY & readb(priv->base + RCAR_IIC_ICSR))) |
||||
break; |
||||
udelay(10); |
||||
} |
||||
} |
||||
|
||||
static int rcar_iic_set_addr(struct udevice *dev, u8 chip, u8 read) |
||||
{ |
||||
struct rcar_iic_priv *priv = dev_get_priv(dev); |
||||
|
||||
clrbits_8(priv->base + RCAR_IIC_ICCR, RCAR_IIC_ICCR_ICE); |
||||
setbits_8(priv->base + RCAR_IIC_ICCR, RCAR_IIC_ICCR_ICE); |
||||
|
||||
writeb(priv->iccl, priv->base + RCAR_IIC_ICCL); |
||||
writeb(priv->icch, priv->base + RCAR_IIC_ICCH); |
||||
writeb(RCAR_IC_TACK, priv->base + RCAR_IIC_ICIC); |
||||
|
||||
writeb(RCAR_IIC_ICCR_ICE | RCAR_IIC_ICCR_RTS | RCAR_IIC_ICCR_BUSY, |
||||
priv->base + RCAR_IIC_ICCR); |
||||
sh_irq_dte(dev); |
||||
|
||||
clrbits_8(priv->base + RCAR_IIC_ICSR, RCAR_IC_TACK); |
||||
writeb(chip << 1 | read, priv->base + RCAR_IIC_ICDR); |
||||
return sh_irq_dte_with_tack(dev); |
||||
} |
||||
|
||||
static void rcar_iic_finish(struct udevice *dev) |
||||
{ |
||||
struct rcar_iic_priv *priv = dev_get_priv(dev); |
||||
|
||||
writeb(0, priv->base + RCAR_IIC_ICSR); |
||||
clrbits_8(priv->base + RCAR_IIC_ICCR, RCAR_IIC_ICCR_ICE); |
||||
} |
||||
|
||||
static int rcar_iic_read_common(struct udevice *dev, struct i2c_msg *msg) |
||||
{ |
||||
struct rcar_iic_priv *priv = dev_get_priv(dev); |
||||
int i, ret = -EREMOTEIO; |
||||
|
||||
if (rcar_iic_set_addr(dev, msg->addr, 1) != 0) |
||||
goto err; |
||||
|
||||
udelay(10); |
||||
|
||||
writeb(RCAR_IIC_ICCR_ICE | RCAR_IIC_ICCR_SCP, |
||||
priv->base + RCAR_IIC_ICCR); |
||||
|
||||
for (i = 0; i < msg->len; i++) { |
||||
if (sh_irq_dte_with_tack(dev) != 0) |
||||
goto err; |
||||
|
||||
msg->buf[i] = readb(priv->base + RCAR_IIC_ICDR) & 0xff; |
||||
|
||||
if (msg->len - 1 == i) { |
||||
writeb(RCAR_IIC_ICCR_ICE | RCAR_IIC_ICCR_RACK, |
||||
priv->base + RCAR_IIC_ICCR); |
||||
} |
||||
} |
||||
|
||||
sh_irq_busy(dev); |
||||
ret = 0; |
||||
|
||||
err: |
||||
rcar_iic_finish(dev); |
||||
return ret; |
||||
} |
||||
|
||||
static int rcar_iic_write_common(struct udevice *dev, struct i2c_msg *msg) |
||||
{ |
||||
struct rcar_iic_priv *priv = dev_get_priv(dev); |
||||
int i, ret = -EREMOTEIO; |
||||
|
||||
if (rcar_iic_set_addr(dev, msg->addr, 0) != 0) |
||||
goto err; |
||||
|
||||
udelay(10); |
||||
|
||||
for (i = 0; i < msg->len; i++) { |
||||
writeb(msg->buf[i], priv->base + RCAR_IIC_ICDR); |
||||
if (sh_irq_dte_with_tack(dev) != 0) |
||||
goto err; |
||||
} |
||||
|
||||
if (msg->flags & I2C_M_STOP) { |
||||
writeb(RCAR_IIC_ICCR_ICE | RCAR_IIC_ICCR_RTS, |
||||
priv->base + RCAR_IIC_ICCR); |
||||
if (sh_irq_dte_with_tack(dev) != 0) |
||||
goto err; |
||||
} |
||||
|
||||
sh_irq_busy(dev); |
||||
ret = 0; |
||||
|
||||
err: |
||||
rcar_iic_finish(dev); |
||||
return ret; |
||||
} |
||||
|
||||
static int rcar_iic_xfer(struct udevice *dev, struct i2c_msg *msg, int nmsgs) |
||||
{ |
||||
int ret; |
||||
|
||||
for (; nmsgs > 0; nmsgs--, msg++) { |
||||
if (msg->flags & I2C_M_RD) |
||||
ret = rcar_iic_read_common(dev, msg); |
||||
else |
||||
ret = rcar_iic_write_common(dev, msg); |
||||
|
||||
if (ret) |
||||
return -EREMOTEIO; |
||||
} |
||||
|
||||
return ret; |
||||
} |
||||
|
||||
static int rcar_iic_set_speed(struct udevice *dev, uint speed) |
||||
{ |
||||
struct rcar_iic_priv *priv = dev_get_priv(dev); |
||||
const unsigned int ratio_high = 4; |
||||
const unsigned int ratio_low = 5; |
||||
int clkrate, denom; |
||||
|
||||
clkrate = clk_get_rate(&priv->clk); |
||||
if (clkrate < 0) |
||||
return clkrate; |
||||
|
||||
/*
|
||||
* Calculate the value for ICCL and ICCH. From the data sheet: |
||||
* iccl = (p-clock / transfer-rate) * (L / (L + H)) |
||||
* icch = (p clock / transfer rate) * (H / (L + H)) |
||||
* where L and H are the SCL low and high ratio. |
||||
*/ |
||||
denom = speed * (ratio_high + ratio_low); |
||||
priv->iccl = DIV_ROUND_CLOSEST(clkrate * ratio_low, denom); |
||||
priv->icch = DIV_ROUND_CLOSEST(clkrate * ratio_high, denom); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static int rcar_iic_probe_chip(struct udevice *dev, uint addr, uint flags) |
||||
{ |
||||
struct rcar_iic_priv *priv = dev_get_priv(dev); |
||||
int ret; |
||||
|
||||
rcar_iic_set_addr(dev, addr, 1); |
||||
writeb(RCAR_IIC_ICCR_ICE | RCAR_IIC_ICCR_SCP, |
||||
priv->base + RCAR_IIC_ICCR); |
||||
ret = sh_irq_dte_with_tack(dev); |
||||
rcar_iic_finish(dev); |
||||
|
||||
return ret; |
||||
} |
||||
|
||||
static int rcar_iic_probe(struct udevice *dev) |
||||
{ |
||||
struct rcar_iic_priv *priv = dev_get_priv(dev); |
||||
int ret; |
||||
|
||||
priv->base = dev_read_addr_ptr(dev); |
||||
|
||||
ret = clk_get_by_index(dev, 0, &priv->clk); |
||||
if (ret) |
||||
return ret; |
||||
|
||||
ret = clk_enable(&priv->clk); |
||||
if (ret) |
||||
return ret; |
||||
|
||||
rcar_iic_finish(dev); |
||||
|
||||
return rcar_iic_set_speed(dev, 100000); |
||||
} |
||||
|
||||
static const struct dm_i2c_ops rcar_iic_ops = { |
||||
.xfer = rcar_iic_xfer, |
||||
.probe_chip = rcar_iic_probe_chip, |
||||
.set_bus_speed = rcar_iic_set_speed, |
||||
}; |
||||
|
||||
static const struct udevice_id rcar_iic_ids[] = { |
||||
{ .compatible = "renesas,rmobile-iic" }, |
||||
{ } |
||||
}; |
||||
|
||||
U_BOOT_DRIVER(iic_rcar) = { |
||||
.name = "iic_rcar", |
||||
.id = UCLASS_I2C, |
||||
.of_match = rcar_iic_ids, |
||||
.probe = rcar_iic_probe, |
||||
.priv_auto_alloc_size = sizeof(struct rcar_iic_priv), |
||||
.ops = &rcar_iic_ops, |
||||
}; |
Loading…
Reference in new issue