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

Commit 1d61a64b authored by Patrick Daly's avatar Patrick Daly Committed by Deepak Katragadda
Browse files

clk: clock-local2: Support parsing generic mux type in dt



Represents a mux which may optionally have gating capability.
Add functionality to parse the mux definition in device tree.

Change-Id: I03bbf9c7d4e1b5ddefeee02c588f74e0b7169979
Signed-off-by: default avatarPatrick Daly <pdaly@codeaurora.org>
parent 7e40dc41
Loading
Loading
Loading
Loading
+43 −0
Original line number Diff line number Diff line
@@ -447,3 +447,46 @@ axi_clk_src: axi_clk_src {
		<FMAX_NOM 333430000>,
		<FMAX_TURBO 400000000>;
};

*****************************************************************************

"qcom,mux-reg"

Represents a mux which may optionally have gating capability.

Required Properties:
- compatible:		Must be "qcom,mux-reg".

- qcom,offset:		Register selecting the input clk.
- qcom,mask:		Bitmask for the mux src select register.
- qcom,shift:		Shift applied to mask and src sel.
- qcom,parents:		Array of <mux_selection  parent_phandle>.

Optional Properties:
- qcom,en-offset:	Register controlling gating functionality.
- qcom,en-mask:		Bitmask for the enable register.
- qcom,recursive-parents:
			Array of phandles.
			Suppose the following clock-tree.
			A -> B --> C
			       \-> D
			It may be desireable to change the grandparent
			of A to D instead of C directly from clk_set_parent(A, D),
			as opposed to calling clk_set_parent(B, D). Including B on
			this list will allow this behavior.
			Any clocks on this list must also be on the qcom,parents.

mmss_gcc_dbg_clk: mmss_gcc_dbg_clk {
	compatible = "qcom,mux-reg";
	qcom,recursive-parents = <&debug_clk_src>;
	qcom,offset = <MMSS_MMSS_DEBUG_CLK_CTL>;
	qcom,mask = <0xFFF>;
	qcom,shift = <0>;
	qcom,en-offset = <MMSS_MMSS_DEBUG_CLK_CTL>;
	qcom,en-mask = <0x10000>;
	qcom,parents =
		<    0 &gcc_xo>,
		<    1 &gpll0>,
		<    2 &debug_clk_src>,
		<>;
};
+96 −0
Original line number Diff line number Diff line
@@ -1837,3 +1837,99 @@ static void *rcg_clk_dt_parser(struct device *dev, struct device_node *np)
}
MSMCLK_PARSER(rcg_clk_dt_parser, "qcom,rcg-hid", 0);
MSMCLK_PARSER(rcg_clk_dt_parser, "qcom,rcg-mn", 1);

static int parse_rec_parents(struct device *dev,
			struct device_node *np, struct mux_clk *mux)
{
	int i, rc;
	char *name = "qcom,recursive-parents";
	phandle p;

	mux->num_rec_parents = of_property_count_phandles(np, name);
	if (mux->num_rec_parents <= 0)
		return 0;

	mux->rec_parents = devm_kzalloc(dev,
			sizeof(*mux->rec_parents) * mux->num_rec_parents,
			GFP_KERNEL);

	if (!mux->rec_parents) {
		dt_err(np, "memory alloc failure\n");
		return -ENOMEM;
	}

	for (i = 0; i < mux->num_rec_parents; i++) {
		rc = of_property_read_phandle_index(np, name, i, &p);
		if (rc) {
			dt_prop_err(np, name, "unable to read u32\n");
			return rc;
		}

		mux->rec_parents[i] = msmclk_parse_phandle(dev, p);
		if (IS_ERR(mux->rec_parents[i])) {
			dt_prop_err(np, name, "hashtable lookup failure\n");
			return PTR_ERR(mux->rec_parents[i]);
		}
	}

	return 0;
}

static void *mux_reg_clk_dt_parser(struct device *dev, struct device_node *np)
{
	struct mux_clk *mux;
	struct msmclk_data *drv;
	int rc;

	mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
	if (!mux) {
		dt_err(np, "memory alloc failure\n");
		return ERR_PTR(-ENOMEM);
	}

	mux->parents = msmclk_parse_clk_src(dev, np, &mux->num_parents);
	if (IS_ERR(mux->parents))
		return mux->parents;

	mux->c.parents = mux->parents;
	mux->c.num_parents = mux->num_parents;

	drv = msmclk_parse_phandle(dev, np->parent->phandle);
	if (IS_ERR_OR_NULL(drv))
		return drv;
	mux->base = &drv->base;

	rc = parse_rec_parents(dev, np, mux);
	if (rc) {
		dt_err(np, "Incorrect qcom,recursive-parents dt property\n");
		return ERR_PTR(rc);
	}

	rc = of_property_read_u32(np, "qcom,offset", &mux->offset);
	if (rc) {
		dt_err(np, "missing qcom,offset dt property\n");
		return ERR_PTR(-EINVAL);
	}

	rc = of_property_read_u32(np, "qcom,mask", &mux->mask);
	if (rc) {
		dt_err(np, "missing qcom,mask dt property\n");
		return ERR_PTR(-EINVAL);
	}

	rc = of_property_read_u32(np, "qcom,shift", &mux->shift);
	if (rc) {
		dt_err(np, "missing qcom,shift dt property\n");
		return ERR_PTR(-EINVAL);
	}

	mux->c.ops = &clk_ops_gen_mux;
	mux->ops = &mux_reg_ops;

	/* Optional Properties */
	of_property_read_u32(np, "qcom,en-offset", &mux->en_offset);
	of_property_read_u32(np, "qcom,en-mask", &mux->en_mask);

	return msmclk_generic_clk_init(dev, np, &mux->c);
};
MSMCLK_PARSER(mux_reg_clk_dt_parser, "qcom,mux-reg", 0);