diff options
author | Markus Mayer <mmayer@broadcom.com> | 2018-02-13 15:40:40 -0500 |
---|---|---|
committer | Florian Fainelli <f.fainelli@gmail.com> | 2018-02-23 13:56:59 -0500 |
commit | fee5f1ef6cf76f87d9799596d06979c9e6589f2b (patch) | |
tree | 74cc6257c8db33ad6a60ee68c9a9ab251d6ed6ec | |
parent | 9f2c4d95e088a44b2b68fedbd4593070b53754a7 (diff) |
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>
-rw-r--r-- | drivers/memory/brcmstb_dpfe.c | 65 |
1 files changed, 55 insertions, 10 deletions
diff --git a/drivers/memory/brcmstb_dpfe.c b/drivers/memory/brcmstb_dpfe.c index 2013a91217a9..e9c1485c32b9 100644 --- a/drivers/memory/brcmstb_dpfe.c +++ b/drivers/memory/brcmstb_dpfe.c | |||
@@ -45,8 +45,16 @@ | |||
45 | #define REG_TO_DCPU_MBOX 0x10 | 45 | #define REG_TO_DCPU_MBOX 0x10 |
46 | #define REG_TO_HOST_MBOX 0x14 | 46 | #define REG_TO_HOST_MBOX 0x14 |
47 | 47 | ||
48 | /* Macros to process offsets returned by the DCPU */ | ||
49 | #define DRAM_MSG_ADDR_OFFSET 0x0 | ||
50 | #define DRAM_MSG_TYPE_OFFSET 0x1c | ||
51 | #define DRAM_MSG_ADDR_MASK ((1UL << DRAM_MSG_TYPE_OFFSET) - 1) | ||
52 | #define DRAM_MSG_TYPE_MASK ((1UL << \ | ||
53 | (BITS_PER_LONG - DRAM_MSG_TYPE_OFFSET)) - 1) | ||
54 | |||
48 | /* Message RAM */ | 55 | /* Message RAM */ |
49 | #define DCPU_MSG_RAM(x) (0x100 + (x) * sizeof(u32)) | 56 | #define DCPU_MSG_RAM_START 0x100 |
57 | #define DCPU_MSG_RAM(x) (DCPU_MSG_RAM_START + (x) * sizeof(u32)) | ||
50 | 58 | ||
51 | /* DRAM Info Offsets & Masks */ | 59 | /* DRAM Info Offsets & Masks */ |
52 | #define DRAM_INFO_INTERVAL 0x0 | 60 | #define DRAM_INFO_INTERVAL 0x0 |
@@ -255,6 +263,40 @@ static unsigned int get_msg_chksum(const u32 msg[]) | |||
255 | return sum; | 263 | return sum; |
256 | } | 264 | } |
257 | 265 | ||
266 | static void __iomem *get_msg_ptr(struct private_data *priv, u32 response, | ||
267 | char *buf, ssize_t *size) | ||
268 | { | ||
269 | unsigned int msg_type; | ||
270 | unsigned int offset; | ||
271 | void __iomem *ptr = NULL; | ||
272 | |||
273 | msg_type = (response >> DRAM_MSG_TYPE_OFFSET) & DRAM_MSG_TYPE_MASK; | ||
274 | offset = (response >> DRAM_MSG_ADDR_OFFSET) & DRAM_MSG_ADDR_MASK; | ||
275 | |||
276 | /* | ||
277 | * msg_type == 1: the offset is relative to the message RAM | ||
278 | * msg_type == 0: the offset is relative to the data RAM (this is the | ||
279 | * previous way of passing data) | ||
280 | * msg_type is anything else: there's critical hardware problem | ||
281 | */ | ||
282 | switch (msg_type) { | ||
283 | case 1: | ||
284 | ptr = priv->regs + DCPU_MSG_RAM_START + offset; | ||
285 | break; | ||
286 | case 0: | ||
287 | ptr = priv->dmem + offset; | ||
288 | break; | ||
289 | default: | ||
290 | dev_emerg(priv->dev, "invalid message reply from DCPU: %#x\n", | ||
291 | response); | ||
292 | if (buf && size) | ||
293 | *size = sprintf(buf, | ||
294 | "FATAL: communication error with DCPU\n"); | ||
295 | } | ||
296 | |||
297 | return ptr; | ||
298 | } | ||
299 | |||
258 | static int __send_command(struct private_data *priv, unsigned int cmd, | 300 | static int __send_command(struct private_data *priv, unsigned int cmd, |
259 | u32 result[]) | 301 | u32 result[]) |
260 | { | 302 | { |
@@ -528,7 +570,6 @@ static ssize_t show_refresh(struct device *dev, | |||
528 | u32 response[MSG_FIELD_MAX]; | 570 | u32 response[MSG_FIELD_MAX]; |
529 | void __iomem *info; | 571 | void __iomem *info; |
530 | struct private_data *priv; | 572 | struct private_data *priv; |
531 | unsigned int offset; | ||
532 | u8 refresh, sr_abort, ppre, thermal_offs, tuf; | 573 | u8 refresh, sr_abort, ppre, thermal_offs, tuf; |
533 | u32 mr4; | 574 | u32 mr4; |
534 | ssize_t ret; | 575 | ssize_t ret; |
@@ -538,8 +579,10 @@ static ssize_t show_refresh(struct device *dev, | |||
538 | return ret; | 579 | return ret; |
539 | 580 | ||
540 | priv = dev_get_drvdata(dev); | 581 | priv = dev_get_drvdata(dev); |
541 | offset = response[MSG_ARG0]; | 582 | |
542 | info = priv->dmem + offset; | 583 | info = get_msg_ptr(priv, response[MSG_ARG0], buf, &ret); |
584 | if (!info) | ||
585 | return ret; | ||
543 | 586 | ||
544 | mr4 = readl_relaxed(info + DRAM_INFO_MR4) & DRAM_INFO_MR4_MASK; | 587 | mr4 = readl_relaxed(info + DRAM_INFO_MR4) & DRAM_INFO_MR4_MASK; |
545 | 588 | ||
@@ -561,7 +604,6 @@ static ssize_t store_refresh(struct device *dev, struct device_attribute *attr, | |||
561 | u32 response[MSG_FIELD_MAX]; | 604 | u32 response[MSG_FIELD_MAX]; |
562 | struct private_data *priv; | 605 | struct private_data *priv; |
563 | void __iomem *info; | 606 | void __iomem *info; |
564 | unsigned int offset; | ||
565 | unsigned long val; | 607 | unsigned long val; |
566 | int ret; | 608 | int ret; |
567 | 609 | ||
@@ -574,8 +616,10 @@ static ssize_t store_refresh(struct device *dev, struct device_attribute *attr, | |||
574 | if (ret) | 616 | if (ret) |
575 | return ret; | 617 | return ret; |
576 | 618 | ||
577 | offset = response[MSG_ARG0]; | 619 | info = get_msg_ptr(priv, response[MSG_ARG0], NULL, NULL); |
578 | info = priv->dmem + offset; | 620 | if (!info) |
621 | return -EIO; | ||
622 | |||
579 | writel_relaxed(val, info + DRAM_INFO_INTERVAL); | 623 | writel_relaxed(val, info + DRAM_INFO_INTERVAL); |
580 | 624 | ||
581 | return count; | 625 | return count; |
@@ -587,16 +631,17 @@ static ssize_t show_vendor(struct device *dev, struct device_attribute *devattr, | |||
587 | u32 response[MSG_FIELD_MAX]; | 631 | u32 response[MSG_FIELD_MAX]; |
588 | struct private_data *priv; | 632 | struct private_data *priv; |
589 | void __iomem *info; | 633 | void __iomem *info; |
590 | unsigned int offset; | ||
591 | ssize_t ret; | 634 | ssize_t ret; |
592 | 635 | ||
593 | ret = generic_show(DPFE_CMD_GET_VENDOR, response, dev, buf); | 636 | ret = generic_show(DPFE_CMD_GET_VENDOR, response, dev, buf); |
594 | if (ret) | 637 | if (ret) |
595 | return ret; | 638 | return ret; |
596 | 639 | ||
597 | offset = response[MSG_ARG0]; | ||
598 | priv = dev_get_drvdata(dev); | 640 | priv = dev_get_drvdata(dev); |
599 | info = priv->dmem + offset; | 641 | |
642 | info = get_msg_ptr(priv, response[MSG_ARG0], buf, &ret); | ||
643 | if (!info) | ||
644 | return ret; | ||
600 | 645 | ||
601 | return sprintf(buf, "%#x %#x %#x %#x %#x\n", | 646 | return sprintf(buf, "%#x %#x %#x %#x %#x\n", |
602 | readl_relaxed(info + DRAM_VENDOR_MR5) & DRAM_VENDOR_MASK, | 647 | readl_relaxed(info + DRAM_VENDOR_MR5) & DRAM_VENDOR_MASK, |