Unverified Commit d551bdf3 authored by Arnd Bergmann's avatar Arnd Bergmann
Browse files

Merge tag 'memory-controller-drv-6.1' of...

Merge tag 'memory-controller-drv-6.1' of https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux-mem-ctrl into arm/drivers

Memory controller drivers for v6.1

1. Fix OF node refcount leaks in pl353-smc and generic of_memory code.
2. Add support for FPGA DFL EMIF revision 1.
3. Update bindings for Mediatek SMI mt8195.

* tag 'memory-controller-drv-6.1' of https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux-mem-ctrl:
  dt-bindings: memory: mediatek,smi: Update condition for mt8195 smi node
  memory: of: Fix refcount leak bug in of_lpddr3_get_ddr_timings()
  memory: of: Fix refcount leak bug in of_get_ddr_timings()
  memory: dfl-emif: Update the dfl emif driver support revision 1
  memory: pl353-smc: Fix refcount leak bug in pl353_smc_probe()

Link: https://lore.kernel.org/r/20220909153037.824092-2-krzysztof.kozlowski@linaro.org


Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parents 3e3dcb46 9f8fb803
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -144,7 +144,16 @@ allOf:
            - const: gals0
            - const: gals1

    else:  # for gen2 HW that don't have gals
  - if:  # for gen2 HW that don't have gals
      properties:
        compatible:
          enum:
            - mediatek,mt2712-smi-common
            - mediatek,mt6795-smi-common
            - mediatek,mt8167-smi-common
            - mediatek,mt8173-smi-common

    then:
      properties:
        clocks:
          minItems: 2
+57 −5
Original line number Diff line number Diff line
@@ -24,11 +24,24 @@
#define EMIF_STAT_CLEAR_BUSY_SFT	16
#define EMIF_CTRL			0x10
#define EMIF_CTRL_CLEAR_EN_SFT		0
#define EMIF_CTRL_CLEAR_EN_MSK		GENMASK_ULL(3, 0)
#define EMIF_CTRL_CLEAR_EN_MSK		GENMASK_ULL(7, 0)

#define EMIF_POLL_INVL			10000 /* us */
#define EMIF_POLL_TIMEOUT		5000000 /* us */

/*
 * The Capability Register replaces the Control Register (at the same
 * offset) for EMIF feature revisions > 0. The bitmask that indicates
 * the presence of memory channels exists in both the Capability Register
 * and Control Register definitions. These can be thought of as a C union.
 * The Capability Register definitions are used to check for the existence
 * of a memory channel, and the Control Register definitions are used for
 * managing the memory-clear functionality in revision 0.
 */
#define EMIF_CAPABILITY_BASE		0x10
#define EMIF_CAPABILITY_CHN_MSK_V0	GENMASK_ULL(3, 0)
#define EMIF_CAPABILITY_CHN_MSK		GENMASK_ULL(7, 0)

struct dfl_emif {
	struct device *dev;
	void __iomem *base;
@@ -106,16 +119,30 @@ emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 0);
emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 1);
emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 2);
emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 3);
emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 4);
emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 5);
emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 6);
emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 7);

emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 0);
emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 1);
emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 2);
emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 3);
emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 4);
emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 5);
emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 6);
emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 7);


emif_clear_attr(0);
emif_clear_attr(1);
emif_clear_attr(2);
emif_clear_attr(3);
emif_clear_attr(4);
emif_clear_attr(5);
emif_clear_attr(6);
emif_clear_attr(7);


static struct attribute *dfl_emif_attrs[] = {
	&emif_attr_inf0_init_done.attr.attr,
@@ -134,6 +161,22 @@ static struct attribute *dfl_emif_attrs[] = {
	&emif_attr_inf3_cal_fail.attr.attr,
	&emif_attr_inf3_clear.attr.attr,

	&emif_attr_inf4_init_done.attr.attr,
	&emif_attr_inf4_cal_fail.attr.attr,
	&emif_attr_inf4_clear.attr.attr,

	&emif_attr_inf5_init_done.attr.attr,
	&emif_attr_inf5_cal_fail.attr.attr,
	&emif_attr_inf5_clear.attr.attr,

	&emif_attr_inf6_init_done.attr.attr,
	&emif_attr_inf6_cal_fail.attr.attr,
	&emif_attr_inf6_clear.attr.attr,

	&emif_attr_inf7_init_done.attr.attr,
	&emif_attr_inf7_cal_fail.attr.attr,
	&emif_attr_inf7_clear.attr.attr,

	NULL,
};

@@ -143,15 +186,24 @@ static umode_t dfl_emif_visible(struct kobject *kobj,
	struct dfl_emif *de = dev_get_drvdata(kobj_to_dev(kobj));
	struct emif_attr *eattr = container_of(attr, struct emif_attr,
					       attr.attr);
	struct dfl_device *ddev = to_dfl_dev(de->dev);
	u64 val;

	/*
	 * This device supports upto 4 memory interfaces, but not all
	 * This device supports up to 8 memory interfaces, but not all
	 * interfaces are used on different platforms. The read out value of
	 * CLEAN_EN field (which is a bitmap) could tell how many interfaces
	 * are available.
	 * CAPABILITY_CHN_MSK field (which is a bitmap) indicates which
	 * interfaces are available.
	 */
	val = FIELD_GET(EMIF_CTRL_CLEAR_EN_MSK, readq(de->base + EMIF_CTRL));
	if (ddev->revision > 0 && strstr(attr->name, "_clear"))
		return 0;

	if (ddev->revision == 0)
		val = FIELD_GET(EMIF_CAPABILITY_CHN_MSK_V0,
				readq(de->base + EMIF_CAPABILITY_BASE));
	else
		val = FIELD_GET(EMIF_CAPABILITY_CHN_MSK,
				readq(de->base + EMIF_CAPABILITY_BASE));

	return (val & BIT_ULL(eattr->index)) ? attr->mode : 0;
}
+2 −0
Original line number Diff line number Diff line
@@ -134,6 +134,7 @@ const struct lpddr2_timings *of_get_ddr_timings(struct device_node *np_ddr,
	for_each_child_of_node(np_ddr, np_tim) {
		if (of_device_is_compatible(np_tim, tim_compat)) {
			if (of_do_get_timings(np_tim, &timings[i])) {
				of_node_put(np_tim);
				devm_kfree(dev, timings);
				goto default_timings;
			}
@@ -284,6 +285,7 @@ const struct lpddr3_timings
		if (of_device_is_compatible(np_tim, tim_compat)) {
			if (of_lpddr3_do_get_timings(np_tim, &timings[i])) {
				devm_kfree(dev, timings);
				of_node_put(np_tim);
				goto default_timings;
			}
			i++;
+1 −0
Original line number Diff line number Diff line
@@ -122,6 +122,7 @@ static int pl353_smc_probe(struct amba_device *adev, const struct amba_id *id)
	}

	of_platform_device_create(child, NULL, &adev->dev);
	of_node_put(child);

	return 0;