Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cf0681ca authored by Tomasz Figa's avatar Tomasz Figa Committed by Russell King
Browse files

ARM: 8262/1: l2c: Add support for overriding prefetch settings



Firmware on certain boards (e.g. ODROID-U3) can leave incorrect L2C prefetch
settings configured in registers leading to crashes if L2C is enabled
without overriding them. This patch introduces bindings to enable
prefetch settings to be specified from DT and necessary support in the
driver.

[mszyprow: rebased onto v3.18-rc1, added error message when prefetch related
 dt property has been provided without any value]

Signed-off-by: default avatarTomasz Figa <t.figa@samsung.com>
Signed-off-by: default avatarMarek Szyprowski <m.szyprowski@samsung.com>
Tested-by: default avatarNishanth Menon <nm@ti.com>
Acked-by: default avatarNishanth Menon <nm@ti.com>
Acked-by: default avatarTony Lindgren <tony@atomide.com>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 0c4c2edc
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -57,6 +57,16 @@ Optional properties:
- cache-id-part: cache id part number to be used if it is not present
  on hardware
- wt-override: If present then L2 is forced to Write through mode
- arm,double-linefill : Override double linefill enable setting. Enable if
  non-zero, disable if zero.
- arm,double-linefill-incr : Override double linefill on INCR read. Enable
  if non-zero, disable if zero.
- arm,double-linefill-wrap : Override double linefill on WRAP read. Enable
  if non-zero, disable if zero.
- arm,prefetch-drop : Override prefetch drop enable setting. Enable if non-zero,
  disable if zero.
- arm,prefetch-offset : Override prefetch offset value. Valid values are
  0-7, 15, 23, and 31.

Example:

+54 −0
Original line number Diff line number Diff line
@@ -1169,6 +1169,8 @@ static void __init l2c310_of_parse(const struct device_node *np,
	u32 tag[3] = { 0, 0, 0 };
	u32 filter[2] = { 0, 0 };
	u32 assoc;
	u32 prefetch;
	u32 val;
	int ret;

	of_property_read_u32_array(np, "arm,tag-latency", tag, ARRAY_SIZE(tag));
@@ -1214,6 +1216,58 @@ static void __init l2c310_of_parse(const struct device_node *np,
		       assoc);
		break;
	}

	prefetch = l2x0_saved_regs.prefetch_ctrl;

	ret = of_property_read_u32(np, "arm,double-linefill", &val);
	if (ret == 0) {
		if (val)
			prefetch |= L310_PREFETCH_CTRL_DBL_LINEFILL;
		else
			prefetch &= ~L310_PREFETCH_CTRL_DBL_LINEFILL;
	} else if (ret != -EINVAL) {
		pr_err("L2C-310 OF arm,double-linefill property value is missing\n");
	}

	ret = of_property_read_u32(np, "arm,double-linefill-incr", &val);
	if (ret == 0) {
		if (val)
			prefetch |= L310_PREFETCH_CTRL_DBL_LINEFILL_INCR;
		else
			prefetch &= ~L310_PREFETCH_CTRL_DBL_LINEFILL_INCR;
	} else if (ret != -EINVAL) {
		pr_err("L2C-310 OF arm,double-linefill-incr property value is missing\n");
	}

	ret = of_property_read_u32(np, "arm,double-linefill-wrap", &val);
	if (ret == 0) {
		if (!val)
			prefetch |= L310_PREFETCH_CTRL_DBL_LINEFILL_WRAP;
		else
			prefetch &= ~L310_PREFETCH_CTRL_DBL_LINEFILL_WRAP;
	} else if (ret != -EINVAL) {
		pr_err("L2C-310 OF arm,double-linefill-wrap property value is missing\n");
	}

	ret = of_property_read_u32(np, "arm,prefetch-drop", &val);
	if (ret == 0) {
		if (val)
			prefetch |= L310_PREFETCH_CTRL_PREFETCH_DROP;
		else
			prefetch &= ~L310_PREFETCH_CTRL_PREFETCH_DROP;
	} else if (ret != -EINVAL) {
		pr_err("L2C-310 OF arm,prefetch-drop property value is missing\n");
	}

	ret = of_property_read_u32(np, "arm,prefetch-offset", &val);
	if (ret == 0) {
		prefetch &= ~L310_PREFETCH_CTRL_OFFSET_MASK;
		prefetch |= val & L310_PREFETCH_CTRL_OFFSET_MASK;
	} else if (ret != -EINVAL) {
		pr_err("L2C-310 OF arm,prefetch-offset property value is missing\n");
	}

	l2x0_saved_regs.prefetch_ctrl = prefetch;
}

static const struct l2c_init_data of_l2c310_data __initconst = {