rockchip: otp: Add support for rv1126

This adds the necessary data for handling otp on the rv1126.

Change-Id: Ie78ad04861ee8dca506f0bb7b851570b360694de
Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com>
This commit is contained in:
Finley Xiao 2020-09-29 17:53:27 +08:00 committed by Jianhong Chen
parent 230491661d
commit a4c57e8a07
2 changed files with 103 additions and 7 deletions

View File

@ -9,9 +9,15 @@
#include <dm.h>
#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/iopoll.h>
#include <misc.h>
#include <rockchip-otp.h>
struct otp_data {
int (*init)(struct udevice *dev);
int (*read)(struct udevice *dev, int offset, void *buf, int size);
};
static int rockchip_otp_wait_status(struct rockchip_otp_platdata *otp,
u32 flag)
{
@ -91,16 +97,65 @@ read_end:
return ret;
}
static int rockchip_rv1126_otp_init(struct udevice *dev)
{
struct rockchip_otp_platdata *otp = dev_get_platdata(dev);
u32 status = 0;
int ret;
writel(0x0, otp->base + RV1126_OTP_NVM_CEB);
ret = readl_poll_timeout(otp->base + RV1126_OTP_NVM_ST, status,
status & 0x1, OTPC_TIMEOUT);
if (ret < 0) {
printf("%s timeout during set ceb\n", __func__);
return ret;
}
writel(0x1, otp->base + RV1126_OTP_NVM_RSTB);
ret = readl_poll_timeout(otp->base + RV1126_OTP_NVM_ST, status,
status & 0x4, OTPC_TIMEOUT);
if (ret < 0) {
printf("%s timeout during set rstb\n", __func__);
return ret;
}
return 0;
}
static int rockchip_rv1126_otp_read(struct udevice *dev, int offset, void *buf,
int size)
{
struct rockchip_otp_platdata *otp = dev_get_platdata(dev);
u32 status = 0;
u8 *buffer = buf;
int ret = 0;
while (size--) {
writel(offset++, otp->base + RV1126_OTP_NVM_RADDR);
writel(0x1, otp->base + RV1126_OTP_NVM_RSTART);
ret = readl_poll_timeout(otp->base + RV1126_OTP_READ_ST,
status, status == 0, OTPC_TIMEOUT);
if (ret < 0) {
printf("%s timeout during read setup\n", __func__);
return ret;
}
*buffer++ = readb(otp->base + RV1126_OTP_NVM_RDATA);
}
return 0;
}
static int rockchip_otp_read(struct udevice *dev, int offset,
void *buf, int size)
{
OTP_READ otp_read = NULL;
struct otp_data *data;
otp_read = (OTP_READ)dev_get_driver_data(dev);
if (!otp_read)
data = (struct otp_data *)dev_get_driver_data(dev);
if (!data)
return -ENOSYS;
return (*otp_read)(dev, offset, buf, size);
return data->read(dev, offset, buf, size);
}
static const struct misc_ops rockchip_otp_ops = {
@ -116,14 +171,41 @@ static int rockchip_otp_ofdata_to_platdata(struct udevice *dev)
return 0;
}
static int rockchip_otp_probe(struct udevice *dev)
{
struct otp_data *data;
data = (struct otp_data *)dev_get_driver_data(dev);
if (!data)
return -EINVAL;
if (data->init)
return data->init(dev);
return 0;
}
static const struct otp_data px30_data = {
.read = rockchip_px30_otp_read,
};
static const struct otp_data rv1126_data = {
.init = rockchip_rv1126_otp_init,
.read = rockchip_rv1126_otp_read,
};
static const struct udevice_id rockchip_otp_ids[] = {
{
.compatible = "rockchip,px30-otp",
.data = (ulong)&rockchip_px30_otp_read,
.data = (ulong)&px30_data,
},
{
.compatible = "rockchip,rk3308-otp",
.data = (ulong)&rockchip_px30_otp_read,
.data = (ulong)&px30_data,
},
{
.compatible = "rockchip,rv1126-otp",
.data = (ulong)&rv1126_data,
},
{}
};
@ -135,4 +217,5 @@ U_BOOT_DRIVER(rockchip_otp) = {
.ops = &rockchip_otp_ops,
.ofdata_to_platdata = rockchip_otp_ofdata_to_platdata,
.platdata_auto_alloc_size = sizeof(struct rockchip_otp_platdata),
.probe = rockchip_otp_probe,
};

View File

@ -42,7 +42,20 @@
#define OTPC_TIMEOUT 10000
typedef int (*OTP_READ)(struct udevice *dev, int offset, void *buf, int size);
#define RV1126_OTP_NVM_CEB 0x00
#define RV1126_OTP_NVM_RSTB 0x04
#define RV1126_OTP_NVM_ST 0x18
#define RV1126_OTP_NVM_RADDR 0x1C
#define RV1126_OTP_NVM_RSTART 0x20
#define RV1126_OTP_NVM_RDATA 0x24
#define RV1126_OTP_NVM_TRWH 0x28
#define RV1126_OTP_READ_ST 0x30
#define RV1126_OTP_NVM_PRADDR 0x34
#define RV1126_OTP_NVM_PRLEN 0x38
#define RV1126_OTP_NVM_PRDATA 0x3c
#define RV1126_OTP_NVM_FAILTIME 0x40
#define RV1126_OTP_NVM_PRSTART 0x44
#define RV1126_OTP_NVM_PRSTATE 0x48
struct rockchip_otp_platdata {
void __iomem *base;