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

Commit 4dc7ed32 authored by Mike Turquette's avatar Mike Turquette
Browse files

Merge tag 'sunxi-clocks-for-3.18' of...

Merge tag 'sunxi-clocks-for-3.18' of git://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux into clk-next

Allwinner Clocks Additions for 3.18

The most important part of this serie is the addition of the phase API to
handle the MMC clocks in the Allwinner SoCs.

Apart from that, the A23 gained a new mbus driver, and there's a fix for a
incorrect divider table on the APB0 clock.
parents 5ad67d3e 9c8176bf
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -46,7 +46,11 @@ Required properties:
	"allwinner,sun6i-a31-apb2-div-clk" - for the APB2 gates on A31
	"allwinner,sun6i-a31-apb2-gates-clk" - for the APB2 gates on A31
	"allwinner,sun8i-a23-apb2-gates-clk" - for the APB2 gates on A23
	"allwinner,sun5i-a13-mbus-clk" - for the MBUS clock on A13
	"allwinner,sun4i-a10-mmc-output-clk" - for the MMC output clock on A10
	"allwinner,sun4i-a10-mmc-sample-clk" - for the MMC sample clock on A10
	"allwinner,sun4i-a10-mod0-clk" - for the module 0 family of clocks
	"allwinner,sun8i-a23-mbus-clk" - for the MBUS clock on A23
	"allwinner,sun7i-a20-out-clk" - for the external output clocks
	"allwinner,sun7i-a20-gmac-clk" - for the GMAC clock module on A20/A31
	"allwinner,sun4i-a10-usb-clk" - for usb gates + resets on A10 / A20
+1 −1
Original line number Diff line number Diff line
@@ -287,7 +287,7 @@

		mbus_clk: clk@01c2015c {
			#clock-cells = <0>;
			compatible = "allwinner,sun4i-a10-mod0-clk";
			compatible = "allwinner,sun5i-a13-mbus-clk";
			reg = <0x01c2015c 0x4>;
			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
			clock-output-names = "mbus";
+1 −1
Original line number Diff line number Diff line
@@ -285,7 +285,7 @@

		mbus_clk: clk@01c2015c {
			#clock-cells = <0>;
			compatible = "allwinner,sun4i-a10-mod0-clk";
			compatible = "allwinner,sun5i-a13-mbus-clk";
			reg = <0x01c2015c 0x4>;
			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
			clock-output-names = "mbus";
+1 −1
Original line number Diff line number Diff line
@@ -346,7 +346,7 @@

		mbus_clk: clk@01c2015c {
			#clock-cells = <0>;
			compatible = "allwinner,sun4i-a10-mod0-clk";
			compatible = "allwinner,sun5i-a13-mbus-clk";
			reg = <0x01c2015c 0x4>;
			clocks = <&osc24M>, <&pll6 2>, <&pll5 1>;
			clock-output-names = "mbus";
+91 −4
Original line number Diff line number Diff line
@@ -119,11 +119,11 @@ static void clk_summary_show_one(struct seq_file *s, struct clk *c, int level)
	if (!c)
		return;

	seq_printf(s, "%*s%-*s %11d %12d %11lu %10lu\n",
	seq_printf(s, "%*s%-*s %11d %12d %11lu %10lu %-3d\n",
		   level * 3 + 1, "",
		   30 - level * 3, c->name,
		   c->enable_count, c->prepare_count, clk_get_rate(c),
		   clk_get_accuracy(c));
		   clk_get_accuracy(c), clk_get_phase(c));
}

static void clk_summary_show_subtree(struct seq_file *s, struct clk *c,
@@ -145,8 +145,8 @@ static int clk_summary_show(struct seq_file *s, void *data)
	struct clk *c;
	struct hlist_head **lists = (struct hlist_head **)s->private;

	seq_puts(s, "   clock                         enable_cnt  prepare_cnt        rate   accuracy\n");
	seq_puts(s, "--------------------------------------------------------------------------------\n");
	seq_puts(s, "   clock                         enable_cnt  prepare_cnt        rate   accuracy   phase\n");
	seq_puts(s, "----------------------------------------------------------------------------------------\n");

	clk_prepare_lock();

@@ -182,6 +182,7 @@ static void clk_dump_one(struct seq_file *s, struct clk *c, int level)
	seq_printf(s, "\"prepare_count\": %d,", c->prepare_count);
	seq_printf(s, "\"rate\": %lu", clk_get_rate(c));
	seq_printf(s, "\"accuracy\": %lu", clk_get_accuracy(c));
	seq_printf(s, "\"phase\": %d", clk_get_phase(c));
}

static void clk_dump_subtree(struct seq_file *s, struct clk *c, int level)
@@ -266,6 +267,11 @@ static int clk_debug_create_one(struct clk *clk, struct dentry *pdentry)
	if (!d)
		goto err_out;

	d = debugfs_create_u32("clk_phase", S_IRUGO, clk->dentry,
			(u32 *)&clk->phase);
	if (!d)
		goto err_out;

	d = debugfs_create_x32("clk_flags", S_IRUGO, clk->dentry,
			(u32 *)&clk->flags);
	if (!d)
@@ -1725,6 +1731,77 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
}
EXPORT_SYMBOL_GPL(clk_set_parent);

/**
 * clk_set_phase - adjust the phase shift of a clock signal
 * @clk: clock signal source
 * @degrees: number of degrees the signal is shifted
 *
 * Shifts the phase of a clock signal by the specified
 * degrees. Returns 0 on success, -EERROR otherwise.
 *
 * This function makes no distinction about the input or reference
 * signal that we adjust the clock signal phase against. For example
 * phase locked-loop clock signal generators we may shift phase with
 * respect to feedback clock signal input, but for other cases the
 * clock phase may be shifted with respect to some other, unspecified
 * signal.
 *
 * Additionally the concept of phase shift does not propagate through
 * the clock tree hierarchy, which sets it apart from clock rates and
 * clock accuracy. A parent clock phase attribute does not have an
 * impact on the phase attribute of a child clock.
 */
int clk_set_phase(struct clk *clk, int degrees)
{
	int ret = 0;

	if (!clk)
		goto out;

	/* sanity check degrees */
	degrees %= 360;
	if (degrees < 0)
		degrees += 360;

	clk_prepare_lock();

	if (!clk->ops->set_phase)
		goto out_unlock;

	ret = clk->ops->set_phase(clk->hw, degrees);

	if (!ret)
		clk->phase = degrees;

out_unlock:
	clk_prepare_unlock();

out:
	return ret;
}

/**
 * clk_get_phase - return the phase shift of a clock signal
 * @clk: clock signal source
 *
 * Returns the phase shift of a clock node in degrees, otherwise returns
 * -EERROR.
 */
int clk_get_phase(struct clk *clk)
{
	int ret = 0;

	if (!clk)
		goto out;

	clk_prepare_lock();
	ret = clk->phase;
	clk_prepare_unlock();

out:
	return ret;
}

/**
 * __clk_init - initialize the data structures in a struct clk
 * @dev:	device initializing this clk, placeholder for now
@@ -1843,6 +1920,16 @@ int __clk_init(struct device *dev, struct clk *clk)
	else
		clk->accuracy = 0;

	/*
	 * Set clk's phase.
	 * Since a phase is by definition relative to its parent, just
	 * query the current clock phase, or just assume it's in phase.
	 */
	if (clk->ops->get_phase)
		clk->phase = clk->ops->get_phase(clk->hw);
	else
		clk->phase = 0;

	/*
	 * Set clk's rate.  The preferred method is to use .recalc_rate.  For
	 * simple clocks and lazy developers the default fallback is to use the
Loading