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

Commit 60389836 authored by Matt Wagantall's avatar Matt Wagantall
Browse files

clk: msm: remove unused clock drivers



Krait CPU support is not present is no longer present in the
kernel. Delete the clock drivers associated with these CPUs.

Similarly, 8994 support is also no longer present, remove
its clock drivers also.

Change-Id: If80992ea1ac3351cc71af3f3f214f616dff00629
Signed-off-by: default avatarMatt Wagantall <mattw@codeaurora.org>
parent c0963f85
Loading
Loading
Loading
Loading
+0 −11
Original line number Diff line number Diff line
@@ -15,12 +15,6 @@ obj-$(CONFIG_DEBUG_FS) += clock-debug.o
obj-$(CONFIG_ARCH_MSM8916)	+= clock-rpm-8916.o
obj-$(CONFIG_ARCH_MSM8916)	+= clock-gcc-8916.o

# MSM8994
obj-$(CONFIG_ARCH_MSM8994)	+= clock-rpm-8994.o
obj-$(CONFIG_ARCH_MSM8994)	+= clock-gcc-8994.o
obj-$(CONFIG_ARCH_MSM8994)	+= clock-mmss-8994.o
obj-$(CONFIG_ARCH_MSM8994)	+= clock-cpu-8994.o

# MSM 8996
obj-$(CONFIG_ARCH_MSM8996)	+= clock-gcc-8996.o
obj-$(CONFIG_ARCH_MSM8996)	+= clock-mmss-8996.o
@@ -35,10 +29,5 @@ obj-$(CONFIG_ARCH_MSM8916) += clock-a7.o
obj-$(CONFIG_ARCH_MSM8916)	+= clock-cpu-8939.o
obj-$(CONFIG_ARCH_MSM8916)	+= clock-cpu-8936.o

obj-$(CONFIG_ARCH_MSM_KRAIT)	+= clock-krait.o
obj-$(CONFIG_ARCH_FSM9900)	+= clock-krait-8974.o
obj-$(CONFIG_ARCH_APQ8084)	+= clock-krait-8974.o
obj-$(CONFIG_ARCH_MSM8974)	+= clock-krait-8974.o

obj-y				+= gdsc.o
obj-y				+= mdss/

drivers/clk/msm/clock-cpu-8994.c

deleted100644 → 0
+0 −2145

File deleted.

Preview size limit exceeded, changes collapsed.

drivers/clk/msm/clock-gcc-8994.c

deleted100644 → 0
+0 −3050

File deleted.

Preview size limit exceeded, changes collapsed.

+0 −1000

File deleted.

Preview size limit exceeded, changes collapsed.

drivers/clk/msm/clock-krait.c

deleted100644 → 0
+0 −523
Original line number Diff line number Diff line
/*
 * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/clk/msm-clk-provider.h>
#include <linux/clk/msm-clk.h>
#include <linux/clk/msm-clock-generic.h>
#include <soc/qcom/avs.h>
#include <soc/qcom/clock-krait.h>

#include <linux/clk.h>
#include <mach/msm-krait-l2-accessors.h>

static DEFINE_SPINLOCK(kpss_clock_reg_lock);

#define LPL_SHIFT	8
static void __kpss_mux_set_sel(struct mux_clk *mux, int sel)
{
	unsigned long flags;
	u32 regval;

	spin_lock_irqsave(&kpss_clock_reg_lock, flags);
	regval = get_l2_indirect_reg(mux->offset);
	regval &= ~(mux->mask << mux->shift);
	regval |= (sel & mux->mask) << mux->shift;
	if (mux->priv) {
		regval &= ~(mux->mask << (mux->shift + LPL_SHIFT));
		regval |= (sel & mux->mask) << (mux->shift + LPL_SHIFT);
	}
	set_l2_indirect_reg(mux->offset, regval);
	spin_unlock_irqrestore(&kpss_clock_reg_lock, flags);

	/* Wait for switch to complete. */
	mb();
	udelay(1);
}
static int kpss_mux_set_sel(struct mux_clk *mux, int sel)
{
	mux->en_mask = sel;
	if (mux->c.count)
		__kpss_mux_set_sel(mux, sel);
	return 0;
}

static int kpss_mux_get_sel(struct mux_clk *mux)
{
	u32 sel;

	sel = get_l2_indirect_reg(mux->offset);
	sel >>= mux->shift;
	sel &= mux->mask;
	mux->en_mask = sel;

	return sel;
}

static int kpss_mux_enable(struct mux_clk *mux)
{
	__kpss_mux_set_sel(mux, mux->en_mask);
	return 0;
}

static void kpss_mux_disable(struct mux_clk *mux)
{
	__kpss_mux_set_sel(mux, mux->safe_sel);
}

struct clk_mux_ops clk_mux_ops_kpss = {
	.enable = kpss_mux_enable,
	.disable = kpss_mux_disable,
	.set_mux_sel = kpss_mux_set_sel,
	.get_mux_sel = kpss_mux_get_sel,
};

/*
 * The divider can divide by 2, 4, 6 and 8. But we only really need div-2. So
 * force it to div-2 during handoff and treat it like a fixed div-2 clock.
 */
static int kpss_div2_get_div(struct div_clk *div)
{
	unsigned long flags;
	u32 regval;
	int val;

	spin_lock_irqsave(&kpss_clock_reg_lock, flags);
	regval = get_l2_indirect_reg(div->offset);
	val = (regval >> div->shift) & div->mask;
	regval &= ~(div->mask << div->shift);
	if (div->priv)
		regval &= ~(div->mask << (div->shift + LPL_SHIFT));
	set_l2_indirect_reg(div->offset, regval);
	spin_unlock_irqrestore(&kpss_clock_reg_lock, flags);

	val = (val + 1) * 2;
	WARN(val != 2, "Divider %s was configured to div-%d instead of 2!\n",
		div->c.dbg_name, val);

	return 2;
}

struct clk_div_ops clk_div_ops_kpss_div2 = {
	.get_div = kpss_div2_get_div,
};

#define LOCK_BIT	BIT(16)

/* Initialize a HFPLL at a given rate and enable it. */
static void __hfpll_clk_init_once(struct clk *c)
{
	struct hfpll_clk *h = to_hfpll_clk(c);
	struct hfpll_data const *hd = h->d;

	if (likely(h->init_done))
		return;

	/* Configure PLL parameters for integer mode. */
	if (hd->config_val)
		writel_relaxed(hd->config_val, h->base + hd->config_offset);
	writel_relaxed(0, h->base + hd->m_offset);
	writel_relaxed(1, h->base + hd->n_offset);

	if (hd->user_offset) {
		u32 regval = hd->user_val;
		unsigned long rate;

		rate = readl_relaxed(h->base + hd->l_offset) * h->src_rate;

		/* Pick the right VCO. */
		if (hd->user_vco_mask && rate > hd->low_vco_max_rate)
			regval |= hd->user_vco_mask;
		writel_relaxed(regval, h->base + hd->user_offset);
	}

	if (hd->droop_offset)
		writel_relaxed(hd->droop_val, h->base + hd->droop_offset);

	h->init_done = true;
}

/* Enable an already-configured HFPLL. */
static int hfpll_clk_enable(struct clk *c)
{
	struct hfpll_clk *h = to_hfpll_clk(c);
	struct hfpll_data const *hd = h->d;

	if (!h->base)
		return -ENODEV;

	__hfpll_clk_init_once(c);

	/* Disable PLL bypass mode. */
	writel_relaxed(0x2, h->base + hd->mode_offset);

	/*
	 * H/W requires a 5us delay between disabling the bypass and
	 * de-asserting the reset. Delay 10us just to be safe.
	 */
	mb();
	udelay(10);

	/* De-assert active-low PLL reset. */
	writel_relaxed(0x6, h->base + hd->mode_offset);

	/* Wait for PLL to lock. */
	if (hd->status_offset) {
		while (!(readl_relaxed(h->base + hd->status_offset) & LOCK_BIT))
			;
	} else {
		mb();
		udelay(60);
	}

	/* Enable PLL output. */
	writel_relaxed(0x7, h->base + hd->mode_offset);

	/* Make sure the enable is done before returning. */
	mb();

	return 0;
}

static void hfpll_clk_disable(struct clk *c)
{
	struct hfpll_clk *h = to_hfpll_clk(c);
	struct hfpll_data const *hd = h->d;

	/*
	 * Disable the PLL output, disable test mode, enable the bypass mode,
	 * and assert the reset.
	 */
	writel_relaxed(0, h->base + hd->mode_offset);
}

static long hfpll_clk_round_rate(struct clk *c, unsigned long rate)
{
	struct hfpll_clk *h = to_hfpll_clk(c);
	struct hfpll_data const *hd = h->d;
	unsigned long rrate;

	if (!h->src_rate)
		return 0;

	rate = max(rate, hd->min_rate);
	rate = min(rate, hd->max_rate);

	rrate = DIV_ROUND_UP(rate, h->src_rate) * h->src_rate;
	if (rrate > hd->max_rate)
		rrate -= h->src_rate;

	return rrate;
}

/*
 * For optimization reasons, assumes no downstream clocks are actively using
 * it.
 */
static int hfpll_clk_set_rate(struct clk *c, unsigned long rate)
{
	struct hfpll_clk *h = to_hfpll_clk(c);
	struct hfpll_data const *hd = h->d;
	unsigned long flags;
	u32 l_val;

	if (!h->base)
		return -ENODEV;

	if (rate != hfpll_clk_round_rate(c, rate))
		return -EINVAL;

	l_val = rate / h->src_rate;

	spin_lock_irqsave(&c->lock, flags);

	if (c->count)
		hfpll_clk_disable(c);

	/* Pick the right VCO. */
	if (hd->user_offset && hd->user_vco_mask) {
		u32 regval;
		regval = readl_relaxed(h->base + hd->user_offset);
		if (rate <= hd->low_vco_max_rate)
			regval &= ~hd->user_vco_mask;
		else
			regval |= hd->user_vco_mask;
		writel_relaxed(regval, h->base  + hd->user_offset);
	}

	writel_relaxed(l_val, h->base + hd->l_offset);

	if (c->count)
		hfpll_clk_enable(c);

	spin_unlock_irqrestore(&c->lock, flags);

	return 0;
}

static enum handoff hfpll_clk_handoff(struct clk *c)
{
	struct hfpll_clk *h = to_hfpll_clk(c);
	struct hfpll_data const *hd = h->d;
	u32 l_val, mode;

	if (!hd)
		return HANDOFF_DISABLED_CLK;

	if (!h->base)
		return HANDOFF_DISABLED_CLK;

	/* Assume parent rate doesn't change and cache it. */
	h->src_rate = clk_get_rate(c->parent);
	l_val = readl_relaxed(h->base + hd->l_offset);
	c->rate = l_val * h->src_rate;

	mode = readl_relaxed(h->base + hd->mode_offset) & 0x7;
	if (mode != 0x7) {
		__hfpll_clk_init_once(c);
		return HANDOFF_DISABLED_CLK;
	}

	if (hd->status_offset &&
		!(readl_relaxed(h->base + hd->status_offset) & LOCK_BIT)) {
		WARN(1, "HFPLL %s is ON, but not locked!\n", c->dbg_name);
		hfpll_clk_disable(c);
		__hfpll_clk_init_once(c);
		return HANDOFF_DISABLED_CLK;
	}

	WARN(c->rate < hd->min_rate || c->rate > hd->max_rate,
		"HFPLL %s rate %lu outside spec!\n", c->dbg_name, c->rate);

	return HANDOFF_ENABLED_CLK;
}

struct clk_ops clk_ops_hfpll = {
	.enable = hfpll_clk_enable,
	.disable = hfpll_clk_disable,
	.round_rate = hfpll_clk_round_rate,
	.set_rate = hfpll_clk_set_rate,
	.handoff = hfpll_clk_handoff,
};

struct cpu_hwcg_action {
	bool read;
	bool enable;
};

static void cpu_hwcg_rw(void *info)
{
	struct cpu_hwcg_action *action = info;

	u32 val;
	asm volatile ("mrc p15, 7, %[cpmr0], c15, c0, 5\n\t"
			: [cpmr0]"=r" (val));

	if (action->read) {
		action->enable = !(val & BIT(0));
		return;
	}

	if (action->enable)
		val &= ~BIT(0);
	else
		val |= BIT(0);

	asm volatile ("mcr p15, 7, %[cpmr0], c15, c0, 5\n\t"
			: : [cpmr0]"r" (val));
}

static void kpss_cpu_enable_hwcg(struct clk *c)
{
	struct kpss_core_clk *cpu = to_kpss_core_clk(c);
	struct cpu_hwcg_action action = { .enable = true };

	smp_call_function_single(cpu->id, cpu_hwcg_rw, &action, 1);
}

static void kpss_cpu_disable_hwcg(struct clk *c)
{
	struct kpss_core_clk *cpu = to_kpss_core_clk(c);
	struct cpu_hwcg_action action = { .enable = false };

	smp_call_function_single(cpu->id, cpu_hwcg_rw, &action, 1);
}

static int kpss_cpu_in_hwcg_mode(struct clk *c)
{
	struct kpss_core_clk *cpu = to_kpss_core_clk(c);
	struct cpu_hwcg_action action = { .read = true };

	smp_call_function_single(cpu->id, cpu_hwcg_rw, &action, 1);
	return action.enable;
}

static enum handoff kpss_cpu_handoff(struct clk *c)
{
	struct kpss_core_clk *cpu = to_kpss_core_clk(c);

	c->rate = clk_get_rate(c->parent);

	/*
	 * Don't unnecessarily turn on the parents for an offline CPU and
	 * then have them turned off at late init.
	 */
	return (cpu_online(cpu->id) ?
		HANDOFF_ENABLED_CLK : HANDOFF_DISABLED_CLK);
}

u32 find_dscr(struct avs_data *t, unsigned long rate)
{
	int i;

	if (!t)
		return 0;

	for (i = 0; i < t->num; i++) {
		if (t->rate[i] == rate)
			return t->dscr[i];
	}

	return 0;
}

static int kpss_cpu_pre_set_rate(struct clk *c, unsigned long new_rate)
{
	struct kpss_core_clk *cpu = to_kpss_core_clk(c);
	u32 dscr = find_dscr(cpu->avs_tbl, c->rate);

	if (dscr)
		AVS_DISABLE(cpu->id);
	return 0;
}

static long kpss_core_round_rate(struct clk *c, unsigned long rate)
{
	if (c->fmax && c->num_fmax)
		rate = min(rate, c->fmax[c->num_fmax-1]);

	return clk_round_rate(c->parent, rate);
}

static int kpss_core_set_rate(struct clk *c, unsigned long rate)
{
	return clk_set_rate(c->parent, rate);
}

static void kpss_cpu_post_set_rate(struct clk *c, unsigned long old_rate)
{
	struct kpss_core_clk *cpu = to_kpss_core_clk(c);
	u32 dscr = find_dscr(cpu->avs_tbl, c->rate);

	/*
	 * FIXME: If AVS enable/disable needs to be done in the
	 * enable/disable op to correctly handle power collapse, then might
	 * need to grab the spinlock here.
	 */
	if (dscr)
		AVS_ENABLE(cpu->id, dscr);
}

static unsigned long kpss_core_get_rate(struct clk *c)
{
	return clk_get_rate(c->parent);
}

static long kpss_core_list_rate(struct clk *c, unsigned n)
{
	if (!c->fmax || c->num_fmax <= n)
		return -ENXIO;

	return c->fmax[n];
}

struct clk_ops clk_ops_kpss_cpu = {
	.enable_hwcg = kpss_cpu_enable_hwcg,
	.disable_hwcg = kpss_cpu_disable_hwcg,
	.in_hwcg_mode = kpss_cpu_in_hwcg_mode,
	.pre_set_rate = kpss_cpu_pre_set_rate,
	.round_rate = kpss_core_round_rate,
	.set_rate = kpss_core_set_rate,
	.post_set_rate = kpss_cpu_post_set_rate,
	.get_rate = kpss_core_get_rate,
	.list_rate = kpss_core_list_rate,
	.handoff = kpss_cpu_handoff,
};

#define SLPDLY_SHIFT		10
#define SLPDLY_MASK		0x3
static void kpss_l2_enable_hwcg(struct clk *c)
{
	struct kpss_core_clk *l2 = to_kpss_core_clk(c);
	u32 regval;
	unsigned long flags;

	spin_lock_irqsave(&kpss_clock_reg_lock, flags);
	regval = get_l2_indirect_reg(l2->cp15_iaddr);
	regval &= ~(SLPDLY_MASK << SLPDLY_SHIFT);
	regval |= l2->l2_slp_delay;
	set_l2_indirect_reg(l2->cp15_iaddr, regval);
	spin_unlock_irqrestore(&kpss_clock_reg_lock, flags);
}

static void kpss_l2_disable_hwcg(struct clk *c)
{
	struct kpss_core_clk *l2 = to_kpss_core_clk(c);
	u32 regval;
	unsigned long flags;

	/*
	 * NOTE: Should not be called when HW clock gating is already
	 * disabled.
	 */
	spin_lock_irqsave(&kpss_clock_reg_lock, flags);
	regval = get_l2_indirect_reg(l2->cp15_iaddr);
	l2->l2_slp_delay = regval & (SLPDLY_MASK << SLPDLY_SHIFT);
	regval |= (SLPDLY_MASK << SLPDLY_SHIFT);
	set_l2_indirect_reg(l2->cp15_iaddr, regval);
	spin_unlock_irqrestore(&kpss_clock_reg_lock, flags);
}

static int kpss_l2_in_hwcg_mode(struct clk *c)
{
	struct kpss_core_clk *l2 = to_kpss_core_clk(c);
	u32 regval;

	regval = get_l2_indirect_reg(l2->cp15_iaddr);
	regval >>= SLPDLY_SHIFT;
	regval &= SLPDLY_MASK;
	return (regval != SLPDLY_MASK);
}

static enum handoff kpss_l2_handoff(struct clk *c)
{
	c->rate = clk_get_rate(c->parent);
	return HANDOFF_ENABLED_CLK;
}

struct clk_ops clk_ops_kpss_l2 = {
	.enable_hwcg = kpss_l2_enable_hwcg,
	.disable_hwcg = kpss_l2_disable_hwcg,
	.in_hwcg_mode = kpss_l2_in_hwcg_mode,
	.round_rate = kpss_core_round_rate,
	.set_rate = kpss_core_set_rate,
	.get_rate = kpss_core_get_rate,
	.list_rate = kpss_core_list_rate,
	.handoff = kpss_l2_handoff,
};
Loading