Commit 8f148f32 authored by Arnd Bergmann's avatar Arnd Bergmann
Browse files

Merge tag 'arm-soc/for-4.16/drivers-fixes' of https://github.com/Broadcom/stblinux into fixes

Pull "Broadcom drivers fixes for 4.16" from Florian Fainelli:

This pull request contains Broadcom SoCs drivers fixes for 4.16, please
pull the following:

- Markus provides two minor fixes to the Broadcom STB DPFE driver, one
  to properly mask bits, and a second one to use the correct type. The
  third commit is a consequence of a newer DFPE firmware which would
  unfortunately crash without appropriate kernel changes.

* tag 'arm-soc/for-4.16/drivers-fixes' of https://github.com/Broadcom/stblinux:
  memory: brcmstb: dpfe: support new way of passing data from the DCPU
  memory: brcmstb: dpfe: fix type declaration of variable "ret"
  memory: brcmstb: dpfe: properly mask vendor error bits
parents c98e140f fee5f1ef
Loading
Loading
Loading
Loading
+60 −14
Original line number Diff line number Diff line
@@ -45,8 +45,16 @@
#define REG_TO_DCPU_MBOX	0x10
#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 */
#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 */
#define DRAM_INFO_INTERVAL	0x0
@@ -255,6 +263,40 @@ static unsigned int get_msg_chksum(const u32 msg[])
	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,
			  u32 result[])
{
@@ -507,7 +549,7 @@ static ssize_t show_info(struct device *dev, struct device_attribute *devattr,
{
	u32 response[MSG_FIELD_MAX];
	unsigned int info;
	int ret;
	ssize_t ret;

	ret = generic_show(DPFE_CMD_GET_INFO, response, dev, buf);
	if (ret)
@@ -528,18 +570,19 @@ static ssize_t show_refresh(struct device *dev,
	u32 response[MSG_FIELD_MAX];
	void __iomem *info;
	struct private_data *priv;
	unsigned int offset;
	u8 refresh, sr_abort, ppre, thermal_offs, tuf;
	u32 mr4;
	int ret;
	ssize_t ret;

	ret = generic_show(DPFE_CMD_GET_REFRESH, response, dev, buf);
	if (ret)
		return ret;

	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;

@@ -561,7 +604,6 @@ static ssize_t store_refresh(struct device *dev, struct device_attribute *attr,
	u32 response[MSG_FIELD_MAX];
	struct private_data *priv;
	void __iomem *info;
	unsigned int offset;
	unsigned long val;
	int ret;

@@ -574,8 +616,10 @@ static ssize_t store_refresh(struct device *dev, struct device_attribute *attr,
	if (ret)
		return ret;

	offset = response[MSG_ARG0];
	info = priv->dmem + offset;
	info = get_msg_ptr(priv, response[MSG_ARG0], NULL, NULL);
	if (!info)
		return -EIO;

	writel_relaxed(val, info + DRAM_INFO_INTERVAL);

	return count;
@@ -587,23 +631,25 @@ static ssize_t show_vendor(struct device *dev, struct device_attribute *devattr,
	u32 response[MSG_FIELD_MAX];
	struct private_data *priv;
	void __iomem *info;
	unsigned int offset;
	int ret;
	ssize_t ret;

	ret = generic_show(DPFE_CMD_GET_VENDOR, response, dev, buf);
	if (ret)
		return ret;

	offset = response[MSG_ARG0];
	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",
		       readl_relaxed(info + DRAM_VENDOR_MR5) & DRAM_VENDOR_MASK,
		       readl_relaxed(info + DRAM_VENDOR_MR6) & DRAM_VENDOR_MASK,
		       readl_relaxed(info + DRAM_VENDOR_MR7) & DRAM_VENDOR_MASK,
		       readl_relaxed(info + DRAM_VENDOR_MR8) & DRAM_VENDOR_MASK,
		       readl_relaxed(info + DRAM_VENDOR_ERROR));
		       readl_relaxed(info + DRAM_VENDOR_ERROR) &
				     DRAM_VENDOR_MASK);
}

static int brcmstb_dpfe_resume(struct platform_device *pdev)