提交 2e10289d 编写于 作者: C Conor Dooley 提交者: Jassi Brar

mailbox: mpfs: fix handling of the reg property

The "data" region of the PolarFire SoC's system controller mailbox is
not one continuous register space - the system controller's QSPI sits
between the control and data registers. Split the "data" reg into two
parts: "data" & "control". Optionally get the "data" register address
from the 3rd reg property in the devicetree & fall back to using the
old base + MAILBOX_REG_OFFSET that the current code uses.

Fixes: 83d7b156 ("mbox: add polarfire soc system controller mailbox")
Signed-off-by: NConor Dooley <conor.dooley@microchip.com>
Signed-off-by: NJassi Brar <jaswinder.singh@linaro.org>
上级 6e2bdf7d
...@@ -62,6 +62,7 @@ struct mpfs_mbox { ...@@ -62,6 +62,7 @@ struct mpfs_mbox {
struct mbox_controller controller; struct mbox_controller controller;
struct device *dev; struct device *dev;
int irq; int irq;
void __iomem *ctrl_base;
void __iomem *mbox_base; void __iomem *mbox_base;
void __iomem *int_reg; void __iomem *int_reg;
struct mbox_chan chans[1]; struct mbox_chan chans[1];
...@@ -73,7 +74,7 @@ static bool mpfs_mbox_busy(struct mpfs_mbox *mbox) ...@@ -73,7 +74,7 @@ static bool mpfs_mbox_busy(struct mpfs_mbox *mbox)
{ {
u32 status; u32 status;
status = readl_relaxed(mbox->mbox_base + SERVICES_SR_OFFSET); status = readl_relaxed(mbox->ctrl_base + SERVICES_SR_OFFSET);
return status & SCB_STATUS_BUSY_MASK; return status & SCB_STATUS_BUSY_MASK;
} }
...@@ -99,14 +100,13 @@ static int mpfs_mbox_send_data(struct mbox_chan *chan, void *data) ...@@ -99,14 +100,13 @@ static int mpfs_mbox_send_data(struct mbox_chan *chan, void *data)
for (index = 0; index < (msg->cmd_data_size / 4); index++) for (index = 0; index < (msg->cmd_data_size / 4); index++)
writel_relaxed(word_buf[index], writel_relaxed(word_buf[index],
mbox->mbox_base + MAILBOX_REG_OFFSET + index * 0x4); mbox->mbox_base + index * 0x4);
if (extra_bits) { if (extra_bits) {
u8 i; u8 i;
u8 byte_off = ALIGN_DOWN(msg->cmd_data_size, 4); u8 byte_off = ALIGN_DOWN(msg->cmd_data_size, 4);
u8 *byte_buf = msg->cmd_data + byte_off; u8 *byte_buf = msg->cmd_data + byte_off;
val = readl_relaxed(mbox->mbox_base + val = readl_relaxed(mbox->mbox_base + index * 0x4);
MAILBOX_REG_OFFSET + index * 0x4);
for (i = 0u; i < extra_bits; i++) { for (i = 0u; i < extra_bits; i++) {
val &= ~(0xffu << (i * 8u)); val &= ~(0xffu << (i * 8u));
...@@ -114,14 +114,14 @@ static int mpfs_mbox_send_data(struct mbox_chan *chan, void *data) ...@@ -114,14 +114,14 @@ static int mpfs_mbox_send_data(struct mbox_chan *chan, void *data)
} }
writel_relaxed(val, writel_relaxed(val,
mbox->mbox_base + MAILBOX_REG_OFFSET + index * 0x4); mbox->mbox_base + index * 0x4);
} }
} }
opt_sel = ((msg->mbox_offset << 7u) | (msg->cmd_opcode & 0x7fu)); opt_sel = ((msg->mbox_offset << 7u) | (msg->cmd_opcode & 0x7fu));
tx_trigger = (opt_sel << SCB_CTRL_POS) & SCB_CTRL_MASK; tx_trigger = (opt_sel << SCB_CTRL_POS) & SCB_CTRL_MASK;
tx_trigger |= SCB_CTRL_REQ_MASK | SCB_STATUS_NOTIFY_MASK; tx_trigger |= SCB_CTRL_REQ_MASK | SCB_STATUS_NOTIFY_MASK;
writel_relaxed(tx_trigger, mbox->mbox_base + SERVICES_CR_OFFSET); writel_relaxed(tx_trigger, mbox->ctrl_base + SERVICES_CR_OFFSET);
return 0; return 0;
} }
...@@ -141,7 +141,7 @@ static void mpfs_mbox_rx_data(struct mbox_chan *chan) ...@@ -141,7 +141,7 @@ static void mpfs_mbox_rx_data(struct mbox_chan *chan)
if (!mpfs_mbox_busy(mbox)) { if (!mpfs_mbox_busy(mbox)) {
for (i = 0; i < num_words; i++) { for (i = 0; i < num_words; i++) {
response->resp_msg[i] = response->resp_msg[i] =
readl_relaxed(mbox->mbox_base + MAILBOX_REG_OFFSET readl_relaxed(mbox->mbox_base
+ mbox->resp_offset + i * 0x4); + mbox->resp_offset + i * 0x4);
} }
} }
...@@ -200,14 +200,18 @@ static int mpfs_mbox_probe(struct platform_device *pdev) ...@@ -200,14 +200,18 @@ static int mpfs_mbox_probe(struct platform_device *pdev)
if (!mbox) if (!mbox)
return -ENOMEM; return -ENOMEM;
mbox->mbox_base = devm_platform_get_and_ioremap_resource(pdev, 0, &regs); mbox->ctrl_base = devm_platform_get_and_ioremap_resource(pdev, 0, &regs);
if (IS_ERR(mbox->mbox_base)) if (IS_ERR(mbox->ctrl_base))
return PTR_ERR(mbox->mbox_base); return PTR_ERR(mbox->ctrl_base);
mbox->int_reg = devm_platform_get_and_ioremap_resource(pdev, 1, &regs); mbox->int_reg = devm_platform_get_and_ioremap_resource(pdev, 1, &regs);
if (IS_ERR(mbox->int_reg)) if (IS_ERR(mbox->int_reg))
return PTR_ERR(mbox->int_reg); return PTR_ERR(mbox->int_reg);
mbox->mbox_base = devm_platform_get_and_ioremap_resource(pdev, 2, &regs);
if (IS_ERR(mbox->mbox_base)) // account for the old dt-binding w/ 2 regs
mbox->mbox_base = mbox->ctrl_base + MAILBOX_REG_OFFSET;
mbox->irq = platform_get_irq(pdev, 0); mbox->irq = platform_get_irq(pdev, 0);
if (mbox->irq < 0) if (mbox->irq < 0)
return mbox->irq; return mbox->irq;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册