mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-30 08:07:59 +00:00
ram: renesas: dbsc5: Add V4H-3/V4H-5/V4H-7 OTP based detection
Add auto-detection and handling of Renesas R-Car V4H-3 and V4H-5 in addition to V4H-7 SoC variants based on OTP fuse programming. The V4H-3 and V4H-5 variants have reduced DRAM frequency options. Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
This commit is contained in:
parent
9ae94d2aed
commit
74e2811361
3 changed files with 35 additions and 17 deletions
|
@ -59,7 +59,8 @@ int renesas_dbsc5_bind(struct udevice *dev)
|
||||||
|
|
||||||
struct renesas_dbsc5_data r8a779g0_dbsc5_data = {
|
struct renesas_dbsc5_data r8a779g0_dbsc5_data = {
|
||||||
.clock_node = "renesas,r8a779g0-cpg-mssr",
|
.clock_node = "renesas,r8a779g0-cpg-mssr",
|
||||||
.reset_node = "renesas,r8a779g0-rst"
|
.reset_node = "renesas,r8a779g0-rst",
|
||||||
|
.otp_node = "renesas,r8a779g0-otp",
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct udevice_id renesas_dbsc5_ids[] = {
|
static const struct udevice_id renesas_dbsc5_ids[] = {
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
struct renesas_dbsc5_data {
|
struct renesas_dbsc5_data {
|
||||||
const char *clock_node;
|
const char *clock_node;
|
||||||
const char *reset_node;
|
const char *reset_node;
|
||||||
|
const char *otp_node;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __DRIVERS_RAM_RENESAS_DBSC5_DBSC5_H__ */
|
#endif /* __DRIVERS_RAM_RENESAS_DBSC5_DBSC5_H__ */
|
||||||
|
|
|
@ -4364,16 +4364,20 @@ static int renesas_dbsc5_dram_probe(struct udevice *dev)
|
||||||
{
|
{
|
||||||
#define RST_MODEMR0 0x0
|
#define RST_MODEMR0 0x0
|
||||||
#define RST_MODEMR1 0x4
|
#define RST_MODEMR1 0x4
|
||||||
|
#define OTP_MONITOR17 0x1144
|
||||||
struct renesas_dbsc5_data *data = (struct renesas_dbsc5_data *)dev_get_driver_data(dev);
|
struct renesas_dbsc5_data *data = (struct renesas_dbsc5_data *)dev_get_driver_data(dev);
|
||||||
ofnode cnode = ofnode_by_compatible(ofnode_null(), data->clock_node);
|
ofnode cnode = ofnode_by_compatible(ofnode_null(), data->clock_node);
|
||||||
ofnode rnode = ofnode_by_compatible(ofnode_null(), data->reset_node);
|
ofnode rnode = ofnode_by_compatible(ofnode_null(), data->reset_node);
|
||||||
|
ofnode onode = ofnode_by_compatible(ofnode_null(), data->otp_node);
|
||||||
struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
|
struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
|
||||||
void __iomem *regs_dbsc_a = priv->regs + DBSC5_DBSC_A_OFFSET;
|
void __iomem *regs_dbsc_a = priv->regs + DBSC5_DBSC_A_OFFSET;
|
||||||
void __iomem *regs_dbsc_d = priv->regs + DBSC5_DBSC_D_OFFSET;
|
void __iomem *regs_dbsc_d = priv->regs + DBSC5_DBSC_D_OFFSET;
|
||||||
phys_addr_t rregs = ofnode_get_addr(rnode);
|
phys_addr_t rregs = ofnode_get_addr(rnode);
|
||||||
const u32 modemr0 = readl(rregs + RST_MODEMR0);
|
const u32 modemr0 = readl(rregs + RST_MODEMR0);
|
||||||
const u32 modemr1 = readl(rregs + RST_MODEMR1);
|
const u32 modemr1 = readl(rregs + RST_MODEMR1);
|
||||||
u32 breg, reg, md, sscg;
|
phys_addr_t oregs = ofnode_get_addr(onode);
|
||||||
|
const u32 otpmon17 = readl(oregs + OTP_MONITOR17);
|
||||||
|
u32 breg, reg, md, sscg, product;
|
||||||
u32 ch, cs;
|
u32 ch, cs;
|
||||||
|
|
||||||
/* Get board data */
|
/* Get board data */
|
||||||
|
@ -4428,29 +4432,41 @@ static int renesas_dbsc5_dram_probe(struct udevice *dev)
|
||||||
|
|
||||||
/* Decode DDR operating frequency from MD[37:36,19,17] pins */
|
/* Decode DDR operating frequency from MD[37:36,19,17] pins */
|
||||||
md = ((modemr0 & BIT(19)) >> 18) | ((modemr0 & BIT(17)) >> 17);
|
md = ((modemr0 & BIT(19)) >> 18) | ((modemr0 & BIT(17)) >> 17);
|
||||||
|
product = otpmon17 & 0xff;
|
||||||
sscg = (modemr1 >> 4) & 0x03;
|
sscg = (modemr1 >> 4) & 0x03;
|
||||||
if (sscg == 2) {
|
if (sscg == 2) {
|
||||||
printf("MD[37:36] setting 0x%x not supported!", sscg);
|
printf("MD[37:36] setting 0x%x not supported!", sscg);
|
||||||
hang();
|
hang();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (md == 0) {
|
if (product == 0x2) { /* V4H-3 */
|
||||||
if (sscg == 0) {
|
|
||||||
priv->ddr_mbps = 6400;
|
|
||||||
priv->ddr_mbpsdiv = 1;
|
|
||||||
} else {
|
|
||||||
priv->ddr_mbps = 19000;
|
|
||||||
priv->ddr_mbpsdiv = 3;
|
|
||||||
}
|
|
||||||
} else if (md == 1) {
|
|
||||||
priv->ddr_mbps = 6000;
|
|
||||||
priv->ddr_mbpsdiv = 1;
|
|
||||||
} else if (md == 2) {
|
|
||||||
priv->ddr_mbps = 5500;
|
|
||||||
priv->ddr_mbpsdiv = 1;
|
|
||||||
} else if (md == 3) {
|
|
||||||
priv->ddr_mbps = 4800;
|
priv->ddr_mbps = 4800;
|
||||||
priv->ddr_mbpsdiv = 1;
|
priv->ddr_mbpsdiv = 1;
|
||||||
|
} else if (product == 0x1) { /* V4H-5 */
|
||||||
|
if (md == 3)
|
||||||
|
priv->ddr_mbps = 4800;
|
||||||
|
else
|
||||||
|
priv->ddr_mbps = 5000;
|
||||||
|
priv->ddr_mbpsdiv = 1;
|
||||||
|
} else { /* V4H-7 */
|
||||||
|
if (md == 0) {
|
||||||
|
if (sscg == 0) {
|
||||||
|
priv->ddr_mbps = 6400;
|
||||||
|
priv->ddr_mbpsdiv = 1;
|
||||||
|
} else {
|
||||||
|
priv->ddr_mbps = 19000;
|
||||||
|
priv->ddr_mbpsdiv = 3;
|
||||||
|
}
|
||||||
|
} else if (md == 1) {
|
||||||
|
priv->ddr_mbps = 6000;
|
||||||
|
priv->ddr_mbpsdiv = 1;
|
||||||
|
} else if (md == 2) {
|
||||||
|
priv->ddr_mbps = 5500;
|
||||||
|
priv->ddr_mbpsdiv = 1;
|
||||||
|
} else if (md == 3) {
|
||||||
|
priv->ddr_mbps = 4800;
|
||||||
|
priv->ddr_mbpsdiv = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
priv->ddr_mul = CLK_DIV(priv->ddr_mbps, priv->ddr_mbpsdiv * 2,
|
priv->ddr_mul = CLK_DIV(priv->ddr_mbps, priv->ddr_mbpsdiv * 2,
|
||||||
|
|
Loading…
Add table
Reference in a new issue