memory: brcmstb: dpfe: support new way of passing data from the DCPU
The DCPU can now send message data in two ways: - via the data RAM, as before (this is now message type 0) - via the message RAM (this is message type 1) In order to support both methods, we check the message type of the response (bits 31:28) and then treat the offset (bits 27:0) accordingly. Signed-off-by: Markus Mayer <mmayer@broadcom.com> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
This commit is contained in:
parent
9f2c4d95e0
commit
fee5f1ef6c
|
@ -45,8 +45,16 @@
|
||||||
#define REG_TO_DCPU_MBOX 0x10
|
#define REG_TO_DCPU_MBOX 0x10
|
||||||
#define REG_TO_HOST_MBOX 0x14
|
#define REG_TO_HOST_MBOX 0x14
|
||||||
|
|
||||||
|
/* Macros to process offsets returned by the DCPU */
|
||||||
|
#define DRAM_MSG_ADDR_OFFSET 0x0
|
||||||
|
#define DRAM_MSG_TYPE_OFFSET 0x1c
|
||||||
|
#define DRAM_MSG_ADDR_MASK ((1UL << DRAM_MSG_TYPE_OFFSET) - 1)
|
||||||
|
#define DRAM_MSG_TYPE_MASK ((1UL << \
|
||||||
|
(BITS_PER_LONG - DRAM_MSG_TYPE_OFFSET)) - 1)
|
||||||
|
|
||||||
/* Message RAM */
|
/* Message RAM */
|
||||||
#define DCPU_MSG_RAM(x) (0x100 + (x) * sizeof(u32))
|
#define DCPU_MSG_RAM_START 0x100
|
||||||
|
#define DCPU_MSG_RAM(x) (DCPU_MSG_RAM_START + (x) * sizeof(u32))
|
||||||
|
|
||||||
/* DRAM Info Offsets & Masks */
|
/* DRAM Info Offsets & Masks */
|
||||||
#define DRAM_INFO_INTERVAL 0x0
|
#define DRAM_INFO_INTERVAL 0x0
|
||||||
|
@ -255,6 +263,40 @@ static unsigned int get_msg_chksum(const u32 msg[])
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void __iomem *get_msg_ptr(struct private_data *priv, u32 response,
|
||||||
|
char *buf, ssize_t *size)
|
||||||
|
{
|
||||||
|
unsigned int msg_type;
|
||||||
|
unsigned int offset;
|
||||||
|
void __iomem *ptr = NULL;
|
||||||
|
|
||||||
|
msg_type = (response >> DRAM_MSG_TYPE_OFFSET) & DRAM_MSG_TYPE_MASK;
|
||||||
|
offset = (response >> DRAM_MSG_ADDR_OFFSET) & DRAM_MSG_ADDR_MASK;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* msg_type == 1: the offset is relative to the message RAM
|
||||||
|
* msg_type == 0: the offset is relative to the data RAM (this is the
|
||||||
|
* previous way of passing data)
|
||||||
|
* msg_type is anything else: there's critical hardware problem
|
||||||
|
*/
|
||||||
|
switch (msg_type) {
|
||||||
|
case 1:
|
||||||
|
ptr = priv->regs + DCPU_MSG_RAM_START + offset;
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
ptr = priv->dmem + offset;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dev_emerg(priv->dev, "invalid message reply from DCPU: %#x\n",
|
||||||
|
response);
|
||||||
|
if (buf && size)
|
||||||
|
*size = sprintf(buf,
|
||||||
|
"FATAL: communication error with DCPU\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
static int __send_command(struct private_data *priv, unsigned int cmd,
|
static int __send_command(struct private_data *priv, unsigned int cmd,
|
||||||
u32 result[])
|
u32 result[])
|
||||||
{
|
{
|
||||||
|
@ -528,7 +570,6 @@ static ssize_t show_refresh(struct device *dev,
|
||||||
u32 response[MSG_FIELD_MAX];
|
u32 response[MSG_FIELD_MAX];
|
||||||
void __iomem *info;
|
void __iomem *info;
|
||||||
struct private_data *priv;
|
struct private_data *priv;
|
||||||
unsigned int offset;
|
|
||||||
u8 refresh, sr_abort, ppre, thermal_offs, tuf;
|
u8 refresh, sr_abort, ppre, thermal_offs, tuf;
|
||||||
u32 mr4;
|
u32 mr4;
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
@ -538,8 +579,10 @@ static ssize_t show_refresh(struct device *dev,
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
priv = dev_get_drvdata(dev);
|
priv = dev_get_drvdata(dev);
|
||||||
offset = response[MSG_ARG0];
|
|
||||||
info = priv->dmem + offset;
|
info = get_msg_ptr(priv, response[MSG_ARG0], buf, &ret);
|
||||||
|
if (!info)
|
||||||
|
return ret;
|
||||||
|
|
||||||
mr4 = readl_relaxed(info + DRAM_INFO_MR4) & DRAM_INFO_MR4_MASK;
|
mr4 = readl_relaxed(info + DRAM_INFO_MR4) & DRAM_INFO_MR4_MASK;
|
||||||
|
|
||||||
|
@ -561,7 +604,6 @@ static ssize_t store_refresh(struct device *dev, struct device_attribute *attr,
|
||||||
u32 response[MSG_FIELD_MAX];
|
u32 response[MSG_FIELD_MAX];
|
||||||
struct private_data *priv;
|
struct private_data *priv;
|
||||||
void __iomem *info;
|
void __iomem *info;
|
||||||
unsigned int offset;
|
|
||||||
unsigned long val;
|
unsigned long val;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -574,8 +616,10 @@ static ssize_t store_refresh(struct device *dev, struct device_attribute *attr,
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
offset = response[MSG_ARG0];
|
info = get_msg_ptr(priv, response[MSG_ARG0], NULL, NULL);
|
||||||
info = priv->dmem + offset;
|
if (!info)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
writel_relaxed(val, info + DRAM_INFO_INTERVAL);
|
writel_relaxed(val, info + DRAM_INFO_INTERVAL);
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
|
@ -587,16 +631,17 @@ static ssize_t show_vendor(struct device *dev, struct device_attribute *devattr,
|
||||||
u32 response[MSG_FIELD_MAX];
|
u32 response[MSG_FIELD_MAX];
|
||||||
struct private_data *priv;
|
struct private_data *priv;
|
||||||
void __iomem *info;
|
void __iomem *info;
|
||||||
unsigned int offset;
|
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
|
||||||
ret = generic_show(DPFE_CMD_GET_VENDOR, response, dev, buf);
|
ret = generic_show(DPFE_CMD_GET_VENDOR, response, dev, buf);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
offset = response[MSG_ARG0];
|
|
||||||
priv = dev_get_drvdata(dev);
|
priv = dev_get_drvdata(dev);
|
||||||
info = priv->dmem + offset;
|
|
||||||
|
info = get_msg_ptr(priv, response[MSG_ARG0], buf, &ret);
|
||||||
|
if (!info)
|
||||||
|
return ret;
|
||||||
|
|
||||||
return sprintf(buf, "%#x %#x %#x %#x %#x\n",
|
return sprintf(buf, "%#x %#x %#x %#x %#x\n",
|
||||||
readl_relaxed(info + DRAM_VENDOR_MR5) & DRAM_VENDOR_MASK,
|
readl_relaxed(info + DRAM_VENDOR_MR5) & DRAM_VENDOR_MASK,
|
||||||
|
|
Loading…
Reference in New Issue