Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 02/11] clk: davinci - add PSC clock driver
From: Murali Karicheri @ 2012-10-25 16:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351181518-11882-1-git-send-email-m-karicheri2@ti.com>

This is the driver for the Power Sleep Controller (PSC) hardware
found on DM SoCs as well Keystone SoCs (c6x). This driver borrowed
code from arch/arm/mach-davinci/psc.c and implemented the driver
as per common clock provider API. The PSC module is responsible for
enabling/disabling the Power Domain and Clock domain for different IPs
present in the SoC. The driver is configured through the clock data
passed to the driver through struct clk_psc_data.

Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
---
 drivers/clk/davinci/clk-psc.c |  207 +++++++++++++++++++++++++++++++++++++++++
 drivers/clk/davinci/clk-psc.h |   46 +++++++++
 2 files changed, 253 insertions(+)
 create mode 100644 drivers/clk/davinci/clk-psc.c
 create mode 100644 drivers/clk/davinci/clk-psc.h

diff --git a/drivers/clk/davinci/clk-psc.c b/drivers/clk/davinci/clk-psc.c
new file mode 100644
index 0000000..40d5f06
--- /dev/null
+++ b/drivers/clk/davinci/clk-psc.c
@@ -0,0 +1,207 @@
+/*
+ * PSC clk driver for DaVinci devices
+ *
+ * Copyright (C) 2006-2012 Texas Instruments.
+ * Copyright (C) 2008-2009 Deep Root Systems, LLC
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+
+#include "clk-psc.h"
+
+/* PSC register offsets */
+#define EPCPR				0x070
+#define PTCMD				0x120
+#define PTSTAT				0x128
+#define PDSTAT				0x200
+#define PDCTL				0x300
+#define MDSTAT				0x800
+#define MDCTL				0xA00
+
+/* PSC module states */
+#define PSC_STATE_SWRSTDISABLE		0
+#define PSC_STATE_SYNCRST		1
+#define PSC_STATE_DISABLE		2
+#define PSC_STATE_ENABLE		3
+
+#define MDSTAT_STATE_MASK		0x3f
+#define PDSTAT_STATE_MASK		0x1f
+#define MDCTL_FORCE			BIT(31)
+#define PDCTL_NEXT			BIT(0)
+#define PDCTL_EPCGOOD			BIT(8)
+
+/**
+ * struct clk_psc - DaVinci PSC clock driver data
+ *
+ * @hw: clk_hw for the psc
+ * @psc_data: Driver specific data
+ */
+struct clk_psc {
+	struct clk_hw hw;
+	struct clk_psc_data *psc_data;
+	spinlock_t *lock;
+};
+
+#define to_clk_psc(_hw) container_of(_hw, struct clk_psc, hw)
+
+/**
+ * clk_psc_config() - configure psc hardware
+ *
+ * @base: io mapped base address of the psc
+ * @domain: Power Domain id of the module
+ * @id: lpsc id
+ * @enable: 1 - enable psc, 0 - disable psc
+ * @flags: psc driver specific flags
+ */
+static void clk_psc_config(void __iomem *base, unsigned int domain,
+		unsigned int id, bool enable, u32 flags)
+{
+	u32 epcpr, ptcmd, ptstat, pdstat, pdctl, mdstat, mdctl;
+	u32 next_state = PSC_STATE_ENABLE;
+	void __iomem *psc_base = base;
+
+	if (!enable) {
+		if (flags & CLK_PSC_SWRSTDISABLE)
+			next_state = PSC_STATE_SWRSTDISABLE;
+		else
+			next_state = PSC_STATE_DISABLE;
+	}
+
+	mdctl = readl(psc_base + MDCTL + 4 * id);
+	mdctl &= ~MDSTAT_STATE_MASK;
+	mdctl |= next_state;
+	if (flags & CLK_PSC_FORCE)
+		mdctl |= MDCTL_FORCE;
+	writel(mdctl, psc_base + MDCTL + 4 * id);
+
+	pdstat = readl(psc_base + PDSTAT + 4 * domain);
+	if ((pdstat & PDSTAT_STATE_MASK) == 0) {
+		pdctl = readl(psc_base + PDCTL + 4 * domain);
+		pdctl |= PDCTL_NEXT;
+		writel(pdctl, psc_base + PDCTL + 4 * domain);
+
+		ptcmd = 1 << domain;
+		writel(ptcmd, psc_base + PTCMD);
+
+		if (flags & CLK_PSC_HAS_EXT_POWER_CNTL) {
+			do {
+				epcpr = readl(psc_base + EPCPR);
+			} while ((((epcpr >> domain) & 1) == 0));
+		}
+
+		pdctl = readl(psc_base + PDCTL + 4 * domain);
+		pdctl |= 0x100;
+		writel(pdctl, psc_base + PDCTL + 4 * domain);
+
+		pdctl = readl(psc_base + PDCTL + 4 * domain);
+		pdctl |= PDCTL_EPCGOOD;
+		writel(pdctl, psc_base + PDCTL + 4 * domain);
+	} else {
+		ptcmd = 1 << domain;
+		writel(ptcmd, psc_base + PTCMD);
+	}
+
+	do {
+		ptstat = readl(psc_base + PTSTAT);
+	} while (!(((ptstat >> domain) & 1) == 0));
+
+	do {
+		mdstat = readl(psc_base + MDSTAT + 4 * id);
+	} while (!((mdstat & MDSTAT_STATE_MASK) == next_state));
+}
+
+/**
+ * clk_psc_is_enabled() - Is psc clock enabled
+ *
+ * @hw: clk hw for the psc
+ */
+static int clk_psc_is_enabled(struct clk_hw *hw)
+{
+	struct clk_psc *psc = to_clk_psc(hw);
+	struct clk_psc_data *psc_data = psc->psc_data;
+	u32 mdstat;
+
+	mdstat = readl(psc_data->reg_base + MDSTAT + 4 * psc_data->lpsc_id);
+
+	/* if clocked, state can be "Enable" or "SyncReset" */
+	return (mdstat & BIT(12)) ? 1 : 0;
+}
+
+/**
+ * clk_psc_enable() - Enable psc clock
+ *
+ * @hw: clk hw for the psc
+ */
+static int clk_psc_enable(struct clk_hw *hw)
+{
+	struct clk_psc *psc = to_clk_psc(hw);
+	struct clk_psc_data *psc_data = psc->psc_data;
+
+	clk_psc_config(psc_data->reg_base, psc_data->domain_id,
+			psc_data->lpsc_id, 1, psc_data->psc_flags);
+	return 0;
+}
+
+/**
+ * clk_psc_disable() - disable psc clock
+ *
+ * @hw: clk hw for the psc
+ */
+static void clk_psc_disable(struct clk_hw *hw)
+{
+	struct clk_psc *psc = to_clk_psc(hw);
+	struct clk_psc_data *psc_data = psc->psc_data;
+
+	clk_psc_config(psc_data->reg_base, psc_data->domain_id,
+			psc_data->lpsc_id, 0, psc_data->psc_flags);
+}
+
+static const struct clk_ops clk_psc_ops = {
+	.enable = clk_psc_enable,
+	.disable = clk_psc_disable,
+	.is_enabled = clk_psc_is_enabled,
+};
+
+/**
+ * clk_register_davinci_psc() - register function for DaVinci PSC clock
+ *
+ * @dev: clk device
+ * @name: name of the clock
+ * @parent_name: name of the parent clock
+ * @psc_data: ptr to psc clk data
+ */
+struct clk *clk_register_davinci_psc(struct device *dev, const char *name,
+			const char *parent_name, struct clk_psc_data *psc_data)
+{
+	struct clk_init_data init;
+	struct clk_psc *psc;
+	struct clk *clk;
+
+	psc = kzalloc(sizeof(*psc), GFP_KERNEL);
+	if (!psc)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &clk_psc_ops;
+	init.flags = psc_data->flags;
+	init.parent_names = (parent_name ? &parent_name : NULL);
+	init.num_parents = (parent_name ? 1 : 0);
+
+	psc->psc_data = psc_data;
+	psc->hw.init = &init;
+
+	clk = clk_register(NULL, &psc->hw);
+	if (IS_ERR(clk))
+		kfree(psc);
+
+	return clk;
+}
diff --git a/drivers/clk/davinci/clk-psc.h b/drivers/clk/davinci/clk-psc.h
new file mode 100644
index 0000000..26327d6
--- /dev/null
+++ b/drivers/clk/davinci/clk-psc.h
@@ -0,0 +1,46 @@
+/*
+ * PSC clk driver for DaVinci devices
+ *
+ * Copyright (C) 2006-2012 Texas Instruments.
+ * Copyright (C) 2008-2009 Deep Root Systems, LLC
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#ifndef __CLK_DAVINCI_PSC_H
+#define __CLK_DAVINCI_PSC_H
+
+/* PSC flags */
+
+/* Disable state is SwRstDisable */
+#define CLK_PSC_SWRSTDISABLE		BIT(0)
+/* Force module state transtition */
+#define CLK_PSC_FORCE			BIT(1)
+/* PSC has external power control available (for DM6446 SoC) */
+#define CLK_PSC_HAS_EXT_POWER_CNTL	BIT(2)
+
+/**
+ * struct clk_psc_data - configuration for DaVinci psc clk driver
+ *
+ * @reg_base:	io mapped address of psc register base
+ * @flags: clk driver base flags
+ * @psc_flags: clk_psc driver flags
+ * @lpsc_id: local power sleep controller id
+ * @gpsc_id: global power sleep controller id
+ * @domain_id: Power domain id
+ */
+struct clk_psc_data {
+	void __iomem *reg_base;
+	u32	flags;
+	u32	psc_flags;
+	u8	lpsc_id;
+	u8	gpsc_id;
+	u8	domain_id;
+};
+
+struct clk *clk_register_davinci_psc(struct device *dev,
+			const char *name, const char *parent_name,
+			struct clk_psc_data *psc_data);
+#endif /* __CLK_DAVINCI_PSC_H */
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH v3 01/11] clk: davinci - add main PLL clock driver
From: Murali Karicheri @ 2012-10-25 16:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351181518-11882-1-git-send-email-m-karicheri2@ti.com>

This is the driver for the main PLL clock hardware found on DM SoCs.
This driver borrowed code from arch/arm/mach-davinci/clock.c and
implemented the driver as per common clock provider API. The main PLL
hardware typically has a multiplier, a pre-divider and a post-divider.
Some of the SoCs has the divider fixed meaning they can not be
configured through a register. HAS_PREDIV and HAS_POSTDIV flags are used
to tell the driver if a hardware has these dividers present or not.
Driver is configured through the struct clk_pll_data that has the
SoC specific clock data.

Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
---
 drivers/clk/davinci/clk-pll.c |  146 +++++++++++++++++++++++++++++++++++++++++
 drivers/clk/davinci/clk-pll.h |   57 ++++++++++++++++
 2 files changed, 203 insertions(+)
 create mode 100644 drivers/clk/davinci/clk-pll.c
 create mode 100644 drivers/clk/davinci/clk-pll.h

diff --git a/drivers/clk/davinci/clk-pll.c b/drivers/clk/davinci/clk-pll.c
new file mode 100644
index 0000000..337e9af
--- /dev/null
+++ b/drivers/clk/davinci/clk-pll.c
@@ -0,0 +1,146 @@
+/*
+ * DaVinci main pll clk driver
+ *
+ * Copyright (C) 2006-2012 Texas Instruments.
+ * Copyright (C) 2008-2009 Deep Root Systems, LLC
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * DaVinci PLL clk driver implementation
+ *
+ * TODO - Add set_parent_rate()
+ */
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+
+#include "clk-pll.h"
+
+#define PLLDIV_EN       BIT(15)
+
+/**
+ * struct clk_pll - DaVinci main pll clock
+ * @hw: clk_hw for the pll
+ * @pll_data: ptr to driver specific data
+ */
+struct clk_pll {
+	struct clk_hw hw;
+	struct clk_pll_data *pll_data;
+};
+
+#define to_clk_pll(_hw) container_of(_hw, struct clk_pll, hw)
+
+/**
+ * clk_pllclk_recalc() - function to calculate rate
+ *
+ * @hw: clk_hw for the pll
+ * @parent_rate: Parent clk rate
+ */
+static unsigned long clk_pllclk_recalc(struct clk_hw *hw,
+					unsigned long parent_rate)
+{
+	struct clk_pll *pll = to_clk_pll(hw);
+	struct clk_pll_data *pll_data = pll->pll_data;
+	u32 mult = 1, prediv = 1, postdiv = 1;
+	unsigned long rate = parent_rate;
+
+	mult = readl(pll_data->reg_pllm);
+
+	/*
+	 * if fixed_multiplier is non zero, multiply pllm value by this
+	 * value.
+	 */
+	if (pll_data->fixed_multiplier)
+		mult =  pll_data->fixed_multiplier *
+				(mult & pll_data->pllm_mask);
+	else
+		mult = (mult & pll_data->pllm_mask) + 1;
+
+	if (pll_data->pll_flags & CLK_DAVINCI_PLL_HAS_PREDIV) {
+		/*
+		 * prediv register is not present, take fixed_prediv value from
+		 * pll_data for prediv
+		 */
+		if (pll_data->fixed_prediv) {
+			prediv = pll_data->fixed_prediv;
+		} else {
+			prediv = readl(pll_data->reg_prediv);
+			if (prediv & PLLDIV_EN)
+				prediv = (prediv & pll_data->prediv_mask) + 1;
+			else
+				prediv = 1;
+		}
+	}
+
+	if (pll_data->pll_flags & CLK_DAVINCI_PLL_HAS_POSTDIV) {
+		postdiv = readl(pll_data->reg_postdiv);
+		if (postdiv & PLLDIV_EN)
+			postdiv = (postdiv & pll_data->postdiv_mask) + 1;
+		else
+			postdiv = 1;
+	}
+
+	rate /= prediv;
+	rate *= mult;
+	rate /= postdiv;
+
+	pr_debug("PLL%d: input = %lu MHz [ ",
+		 pll_data->num, parent_rate / 1000000);
+	if (prediv > 1)
+		pr_debug("/ %d ", prediv);
+	if (mult > 1)
+		pr_debug("* %d ", mult);
+	if (postdiv > 1)
+		pr_debug("/ %d ", postdiv);
+	pr_debug("] --> %lu MHz output.\n", rate / 1000000);
+
+	return rate;
+}
+
+static const struct clk_ops clk_pll_ops = {
+	.recalc_rate = clk_pllclk_recalc,
+};
+
+/**
+ * clk_register_davinci_pll() - register function for DaVinci main pll clk
+ *
+ * @dev: device ptr
+ * @name: name of the clk
+ * @parent_name: name of the parent clk
+ * @pll_data: ptr to pll clk data
+ */
+struct clk *clk_register_davinci_pll(struct device *dev, const char *name,
+			const char *parent_name,
+			struct clk_pll_data *pll_data)
+{
+	struct clk_init_data init;
+	struct clk_pll *pll;
+	struct clk *clk;
+
+	if (!pll_data)
+		return ERR_PTR(-ENODEV);
+
+	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+	if (!pll)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &clk_pll_ops;
+	init.flags = pll_data->flags;
+	init.parent_names = (parent_name ? &parent_name : NULL);
+	init.num_parents = (parent_name ? 1 : 0);
+
+	pll->pll_data	= pll_data;
+	pll->hw.init = &init;
+
+	clk = clk_register(NULL, &pll->hw);
+	if (IS_ERR(clk))
+		kfree(pll);
+
+	return clk;
+}
diff --git a/drivers/clk/davinci/clk-pll.h b/drivers/clk/davinci/clk-pll.h
new file mode 100644
index 0000000..c9e4826
--- /dev/null
+++ b/drivers/clk/davinci/clk-pll.h
@@ -0,0 +1,57 @@
+/*
+ * Header file for DaVinci main pll clk driver
+ *
+ * Copyright (C) 2006-2012 Texas Instruments.
+ * Copyright (C) 2008-2009 Deep Root Systems, LLC
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * DaVinci PLL clk driver implementation
+ *
+ * TODO - Add set_parent_rate()
+ */
+
+#ifndef __CLK_DAVINCI_PLL_H
+#define __CLK_DAVINCI_PLL_H
+
+/* PLL flags */
+#define CLK_DAVINCI_PLL_HAS_PREDIV			BIT(0)
+#define CLK_DAVINCI_PLL_HAS_POSTDIV			BIT(1)
+
+/**
+ * struct clk_pll_data - configuration for DaVinci main PLL clk driver
+ *
+ * @reg_pllm: io mapped address of pllm register
+ * @reg_prediv: io mapped address of prediv register
+ * @reg_postdiv: io mapped address of postdiv register
+ * @pllm_mask: mask bits for pllm val
+ * @prediv_mask: mask bits for prediv val
+ * @postdiv_mask: mask bits for postdiv val
+ * @num: PLL number. Some SoCs have more than one main PLL
+ *       0 - PLL0 and 1 - PLL1
+ * @flags - clk driver base flags
+ * @pll_flags - clk_pll driver flags
+ * @fixed_prediv - fixed value of prediv used instead of value from prediv reg
+ * @fixed_multiplier - pllm register value is multiplied by this factor on a
+ *		a particular SoC. For other SoCs, this is set to zero.
+ */
+struct clk_pll_data {
+	void __iomem *reg_pllm;
+	void __iomem *reg_prediv;
+	void __iomem *reg_postdiv;
+	u32 pllm_mask;
+	u32 prediv_mask;
+	u32 postdiv_mask;
+	u32 num;
+	u32 flags;
+	u32 pll_flags;
+	u32 fixed_prediv;
+	u32 fixed_multiplier;
+};
+
+struct clk *clk_register_davinci_pll(struct device *dev,
+			const char *name, const char *parent_name,
+			struct clk_pll_data *pll_data);
+#endif /* CLK_DAVINCI_PLL_H */
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH v3 00/11] common clk drivers migration for DaVinci SoCs
From: Murali Karicheri @ 2012-10-25 16:11 UTC (permalink / raw)
  To: linux-arm-kernel

This is v3 of the patch series for implementing clock tree for DaVinci SoCs
using common clk framework.

supported platforms: DM644x

This code base can be accessed at

https://gitorious.org/~m-karicheri/linux-davinci/linux-davinci-clk/commits/common-clk-v3

The patch series is split in two parts:-
	 patches prefixed with "clk" are for clk drivers
	 patches prefixed with "ARM" are for davinci machine specific code.

revision history:
-----------------
updates in v3:
	- Major changes done based on review of v2 to move the clock data and
	  initialization code to drivers/clk/davinci. There is a soc specific
	  code (for example dm644x-clock.c) for doing clock initialization.
	- Files renamed based on the review comments.
	- Only DM644x is supported. Other devices will be added as the code
	  matures so that unnecessary rework can be avoided.
	- Incorporated comments from Nori Sekhar and Linus (comments coding
	  style)
	- Added clk-div clock to represent DaVinci pll divider clocks
	- Removed clk-keystone-pll.c (will be added later)

updates in v2:
	- updates to davinci_clk to use union for clk driver platform data
	- Fixed Linus Walleij' comment on code comment
	- added code clean up that takes out the ifdef used in previous patches

updates in v1:
	- Added DM365 and DM355
	- updates to davinci_clk struct to accomodate clk-fixed-factor data

initial version:-

Currently arch/arm/mach-davinci/clock.c and arch/arm/mach-davinci/psc.c
implements clock drivers for DaVinci. This patch makes these code obsolete
and migrate the SoC code to use the common clk based drivers. This adds
two clk drivers specific to DaVinci and Keystone (found in c6x arch such
as C6678) devices. Some of the existing clk drivers such as clk-fixed-rate,
clk-divider, and clk-mux are re-used in addition to the DaVinci specific
drivers to initialize the clock tree for the SoCs. Please refer chapter 6
of http://www.ti.com/lit/ug/sprue14c/sprue14c.pdf for details of the
PLL hardware in DM6446 and chapter 7 for defails of the PSC hardware.

There are two Main PLLs in DM644x. PLL1 and PLL2. Each of these generate
different clocks in the DM device through PLL dividers. Figure above shows this
for PLL1. Similar hardware exists for PLL2 and the related output clocks. The
hardware is similar in most of the DM SoCs. Some of the recent Keystone devices
(c6678 under c6x architecture) include a slight variant of the PLL that
implemented different registers for the multipliers and dividers. All of these
devices include PLL dividers (PLLDIVx) and Power Sleep controllers (PSC). The
SoCs defines various Power Domains and Clock domains and there are PSC modules
that controls power and clocks to various hardware IPs of the SoC. 

Following drivers are used for various clock hardware blocks:-

CLKIN and OSCIN - clk-fixed-rate (existing driver)
MUX - clk-mux (existing driver)
PLLDIVx - davinci/clk-div (new driver)
PLL mult/div - clk-pll (new driver)
PSC - clk-psc.c (new driver)

Please note that initially only platforms listed above are supported. The
idea is to review the initial patch set and get a feedback on the overall
structure of the code organization. The other SoCs will be added in subsequent
patch revisions.

The driver code implements the features needed to support the platforms
listed above. It is expected that these drivers get updated in subsequent
patch revisions to support additional SoCs. I have boot tested this on DM6446
EVM. Also verified reboot command works and the clock rates are set as before.
The patches depends on the following patches that I had sent for review earlier:

davinci spi driver preparation @
https://patchwork.kernel.org/patch/1389321/
davinci watchdog driver preparation @
https://lkml.org/lkml/2012/9/7/634
davinci nand driver preparation @
https://lkml.org/lkml/2012/9/7/635
davinci i2c driver preparation @
https://patchwork.kernel.org/patch/1388841/
davinci gpio driver preparation @
https://lkml.org/lkml/2012/8/31/341

[RFC - PATCH] base:pm: prepare driver for common clock framework

ISSUES to discuss
-----------------
Following are to be discussed as part of this patch review.

 1. arch/arm/pm.c. This is configuring PLL controller registers for suspend and
    resume. It appears that we need to move this code to clk-pll.c?? But
    I can't find APIs for suspend and resume in the common clk framework. How
    is this expected to work? Currently i have kept the code ASIS.   

 2. There are usecount=1 in the old clock implementation for dsp, vicp and timer2
    clocks. CLK_IGNORE_UNUSED flag is used currently to implement the same as
    disabling these unused clocks causes issues in boot up,

HELP NEEDED!!:
--------------
I am doing this work as a background activity and hence the progress will be
slow. Please volunteer to help me in this effort by offering to test or migrating
other devices to this framework.

Murali Karicheri (11):
  clk: davinci - add main PLL clock driver
  clk: davinci - add PSC clock driver
  clk: davinci - common clk utilities to init clk driver
  clk: davinci - add pll divider clock driver
  clk: davinci - add dm644x clock initialization
  clk: davinci - add build infrastructure for DaVinci clock drivers
  ARM: davinci - restructure header files for common clock migration
  ARM: davinci - migrating to use common clock init code
  ARM: davinci - dm644x: update SoC code to remove the clock data
  ARM: davinci - migrate to common clock
  ARM: davinci - common clock migration: clean up the old code

 arch/arm/Kconfig                            |    1 +
 arch/arm/mach-davinci/Kconfig               |    2 +
 arch/arm/mach-davinci/Makefile              |   15 +-
 arch/arm/mach-davinci/clock.c               |  669 ---------------------------
 arch/arm/mach-davinci/clock.h               |  135 ------
 arch/arm/mach-davinci/common.c              |   10 -
 arch/arm/mach-davinci/cpufreq.c             |    2 -
 arch/arm/mach-davinci/davinci.h             |    3 +
 arch/arm/mach-davinci/devices.c             |    1 -
 arch/arm/mach-davinci/dm644x.c              |  302 +-----------
 arch/arm/mach-davinci/include/mach/clock.h  |   21 -
 arch/arm/mach-davinci/include/mach/common.h |   10 +-
 arch/arm/mach-davinci/include/mach/pll.h    |   46 ++
 arch/arm/mach-davinci/include/mach/psc.h    |  209 ---------
 arch/arm/mach-davinci/include/mach/time.h   |    2 +-
 arch/arm/mach-davinci/pm.c                  |    3 +-
 arch/arm/mach-davinci/psc.c                 |  112 -----
 arch/arm/mach-davinci/sleep.S               |    3 +-
 arch/arm/mach-davinci/time.c                |    6 +-
 drivers/clk/Kconfig                         |    2 +
 drivers/clk/Makefile                        |    1 +
 drivers/clk/davinci/Kconfig                 |   44 ++
 drivers/clk/davinci/Makefile                |    5 +
 drivers/clk/davinci/clk-div.c               |  124 +++++
 drivers/clk/davinci/clk-div.h               |   42 ++
 drivers/clk/davinci/clk-pll.c               |  146 ++++++
 drivers/clk/davinci/clk-pll.h               |   57 +++
 drivers/clk/davinci/clk-psc.c               |  207 +++++++++
 drivers/clk/davinci/clk-psc.h               |   46 ++
 drivers/clk/davinci/clock.c                 |  112 +++++
 drivers/clk/davinci/clock.h                 |   80 ++++
 drivers/clk/davinci/dm644x-clock.c          |  304 ++++++++++++
 drivers/clk/davinci/pll.h                   |   83 ++++
 drivers/clk/davinci/psc.h                   |  215 +++++++++
 34 files changed, 1530 insertions(+), 1490 deletions(-)
 delete mode 100644 arch/arm/mach-davinci/clock.c
 delete mode 100644 arch/arm/mach-davinci/clock.h
 delete mode 100644 arch/arm/mach-davinci/include/mach/clock.h
 create mode 100644 arch/arm/mach-davinci/include/mach/pll.h
 delete mode 100644 arch/arm/mach-davinci/psc.c
 create mode 100644 drivers/clk/davinci/Kconfig
 create mode 100644 drivers/clk/davinci/Makefile
 create mode 100644 drivers/clk/davinci/clk-div.c
 create mode 100644 drivers/clk/davinci/clk-div.h
 create mode 100644 drivers/clk/davinci/clk-pll.c
 create mode 100644 drivers/clk/davinci/clk-pll.h
 create mode 100644 drivers/clk/davinci/clk-psc.c
 create mode 100644 drivers/clk/davinci/clk-psc.h
 create mode 100644 drivers/clk/davinci/clock.c
 create mode 100644 drivers/clk/davinci/clock.h
 create mode 100644 drivers/clk/davinci/dm644x-clock.c
 create mode 100644 drivers/clk/davinci/pll.h
 create mode 100644 drivers/clk/davinci/psc.h

-- 
1.7.9.5

^ permalink raw reply

* [PATCH 2/6] pinctrl: Update clock handling for the pinctrl-nomadik GPIO driver
From: Linus Walleij @ 2012-10-25 16:03 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121025155143.GK4008@gmail.com>

On Thu, Oct 25, 2012 at 5:51 PM, Lee Jones <lee.jones@linaro.org> wrote:
> On Thu, 25 Oct 2012, Linus Walleij wrote:

>> Probably some driver is needing a clk_get() or a clk_get_sys() is
>> needs to be added somewhere to bring up some vital cluster,
>> or there may be some out-of-tree driver needed to bring up the
>> cluster properly I have no clue... Maybe some cluster just
>> cannot be declocked like that.
>
> I leave work in 10 mins and won't be coding again for ~2.5 weeks.
> So if this is something you could squeeze in and fix-up, I'd be
> very grateful.

I'll try. It doesn't look right that a clk_prepare() in the pinctrl
driver is saving the day for somebody else...

Yours,
Linus Walleij

^ permalink raw reply

* [PATCH 2/2] arm: mvebu: adding SATA support: dt binding and config update
From: Gregory CLEMENT @ 2012-10-25 16:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <50894534.2000602@gmail.com>

On 10/25/2012 03:57 PM, Rob Herring wrote:
> On 10/25/2012 08:34 AM, Gregory CLEMENT wrote:
>> On 10/25/2012 03:21 PM, Thomas Petazzoni wrote:
>>> Jason,
>>>
>>> On Thu, 25 Oct 2012 09:18:18 -0400, Jason Cooper wrote:
>>>
>>>>> Jason, Andrew, do you want I split this patch as suggested by
>>>>> Thomas or are you fine with having one single patch?
>>>>
>>>> Yes, please make the defconfig changes a separate patch.  Also, please
>>>> make sure only the minimum is enabled (eq RAID... isn't needed).
>>>
>>> I haven't looked in details at the driver, but is nr-ports = <foo> the
>>> right way of doing things? We may have platforms were port 0 is not
>>> used, but port 1 is used, and just a number of ports doesn't allow to
>>> express this.
>>>
>>> Shouldn't the DT property be
>>>
>>>   ports = <0>, <1>
>>>   ports = <1>
>>>   ports = <1>, <3>
>>>
>>> In order to allow to more precisely enabled SATA ports? Or maybe the
>>> SATA ports cannot be enabled/disabled on a per-port basis, in which
>>> case I'm obviously wrong here.
>>
>> The actual implementation of mv_sata.c doesn't work like this. You can
>> only pass the number of ports supported not the list of the port you
>> want to support. I've checked in the device tree binding documentation
>> _and_ also in the code.
> 
> Is that a statement about the driver or the h/w? It does not matter what
> the driver does. If the h/w can support skipping a port, then the dts
> should allow that.

Indeed I didn't see anything in the datasheet which would prevent to use
only port 2. I agree to add this feature if needed, but currently there
is no Marvell based board whith this kind of configuration. Can we keep
this series as a simple series to enable SATA on Armada 370/XP, and
prepare an other series for this new feature?

> 
> A bitmask would be most appropriate here (and matches how AHCI does the
> equivalent).

I didn't see any bitmask for AHCI, just an optional list of phandle on
combophy.

> 
> Rob
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

^ permalink raw reply

* [GIT PULL] first set of ux500 for ARM SoC for v3.8
From: Linus Walleij @ 2012-10-25 15:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <201210251513.43931.arnd@arndb.de>

On Thu, Oct 25, 2012 at 5:13 PM, Arnd Bergmann <arnd@arndb.de> wrote:

> The tag looks great, but you were sending the pull request for
> the branch "ux500-core", not for the tag "ux500-core-for-arm-soc".
>
> This has happened to me a few times before, especially when pushing
> the tag just before sending the pull request. In that case,
> git-request-pull cannot find the tag on the server because it has
> not been mirrored back from the git+ssh server to the publically
> accessible one that it reads the tags from.

Ah yes this mirror thing is a bit dangerous, I usually check it
by inspecting the warning message that request-pull generates,
but must've missed it.

Yours,
Linus Walleij

^ permalink raw reply

* [RFC PATCH 00/13] sched: Integrating Per-entity-load-tracking with the core scheduler
From: Peter Zijlstra @ 2012-10-25 15:56 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121025102045.21022.92489.stgit@preeti.in.ibm.com>

OK, so I tried reading a few patches and I'm completely failing.. maybe
its late and my brain stopped working, but it simply doesn't make any
sense.

Most changelogs and comments aren't really helping either. At best they
mention what you're doing, not why and how. This means I get to
basically duplicate your entire thought pattern and I might as well do
the patches myself.

I also don't see the 'big' picture of what you're doing, you start out
by some weird avoid short running task movement.. why is that a good
start?

I would have expected a series like this to replace rq->cpu_load /
rq->load with a saner metric and go from there.. instead it looks like
its going about at things completely backwards. Fixing small details
instead of the big things.

Do explain..

^ permalink raw reply

* [PATCH v2 2/2] USB: doc: Binding document for ehci-platform driver
From: Stephen Warren @ 2012-10-25 15:53 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121025102301.GA3469@breakpoint.cc>

On 10/25/2012 04:23 AM, Sebastian Andrzej Siewior wrote:
> On Wed, Oct 24, 2012 at 08:55:27AM -1000, Mitch Bradley wrote:
>>>> So by listing "usb-ehci" in its device ID table, a driver would
>>>> essentially be saying that it can handle _all_ USB EHCI controllers.  
>>
>>
>> Actually, it means that the driver can handle at least USB EHCI
>> controllers that are 100% compatible with the EHCI spec (requiring
>> nothing extra).  The driver might be able to handle almost-compatible
>> controllers, possibly with the help of additional properties.
>>
>> If a DT node lists "usb-ehci" as a "fallback", it's not guaranteed that
>> a given version of that driver will work, but it's worth a try in the
>> event that no more-specific driver is matched.
> 
> Not sure fallback is a good term here. The of parses the compatible from left
> to right. If the device specific entry is not found (in the driver) then end
> up with usb-ehci. If we need a quirk later on we add the device specific entry
> to the driver (which will match before usb-ehci is found) and we could use
> this entry to apply the quirk. That way you can apply quirks without touch the
> firmware / device tree.

That's the theory on how the compatible values are used, but in
practice, each driver is tested against all the values in a node before
moving on to the next driver, so the (current kernel's implementation of
the) matching order is not what's needed to make that work.

^ permalink raw reply

* [PATCH 2/6] pinctrl: Update clock handling for the pinctrl-nomadik GPIO driver
From: Lee Jones @ 2012-10-25 15:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CACRpkdbNWE6hOdVFPxHv7MVHkZUBW3LC035CxJkZVmr8j05Kqw@mail.gmail.com>

On Thu, 25 Oct 2012, Linus Walleij wrote:

> On Thu, Oct 25, 2012 at 2:41 PM, Linus Walleij <linus.walleij@linaro.org> wrote:
> > On Wed, Oct 24, 2012 at 4:45 PM, Lee Jones <lee.jones@linaro.org> wrote:
> >
> >> The clock framework has changed somewhat and it's now better to
> >> invoke clock_prepare_enable() and clk_disable_unprepare() rather
> >> than the legacy clk_enable() and clk_disable() calls. This patch
> >> converts the Nomadik Pin Control driver to the new framework.
> >>
> >> Signed-off-by: Lee Jones <lee.jones@linaro.org>
> >
> > I was convinced that this is a good change but no regression,
> > so applied to the devel branch for 3.8.
> >
> > I also removed the initial clk_prepare() so the reference count
> > may actually go down to 0 for the GPIO block and the peripheral
> > cluster eventually gets relaxed.
> 
> Famous last words!
> 
> The good news is that this actually works, and the refcount
> *does* go down to zero and gate off entire peripheral
> clusters.
> 
> However that was not good because something vital in
> some peripheral cluster died and killed the system :-D
> 
> Lee, could to to track down the reason and fix it so the patch
> can be applied?
> 
> The only thing you need to do is to remove the superfluous
> clk_prepare() right after the devm_clk_get() that hogs each
> peripheral cluster.
> 
> Probably some driver is needing a clk_get() or a clk_get_sys() is
> needs to be added somewhere to bring up some vital cluster,
> or there may be some out-of-tree driver needed to bring up the
> cluster properly I have no clue... Maybe some cluster just
> cannot be declocked like that.

I leave work in 10 mins and won't be coding again for ~2.5 weeks.
So if this is something you could squeeze in and fix-up, I'd be
very grateful.

Kind regards,
Lee

-- 
Lee Jones
Linaro ST-Ericsson Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply

* [PATCH V3 1/5] ARM: dts: OMAP: Add timer nodes
From: Hiremath, Vaibhav @ 2012-10-25 15:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <508931A1.50608@ti.com>

On Thu, Oct 25, 2012 at 18:03:37, Hunter, Jon wrote:
> 
> On 10/25/2012 07:18 AM, Jon Hunter wrote:
> 
> ...
> 
> >> @@ -113,6 +114,9 @@ static int omap_timer_interrupt_test(struct omap_dm_timer *gptimer)
> >>
> >>         irq_data.gptimer = gptimer;
> >>         init_completion(&irq_data.complete);
> >> +
> >> +       omap_dm_timer_enable(gptimer);
> >> +
> >>         omap_dm_timer_set_int_enable(gptimer, OMAP_TIMER_INT_OVERFLOW);
> >>         omap_dm_timer_set_load_start(gptimer, 0, 0xffffff00);
> >>
> >> @@ -128,6 +132,8 @@ static int omap_timer_interrupt_test(struct omap_dm_timer *gptimer)
> >>
> >>         omap_dm_timer_stop(gptimer);
> >>         omap_dm_timer_set_int_enable(gptimer, 0);
> >> +       omap_dm_timer_disable(gptimer);
> >> +
> > 
> > Hmmm ... I am wondering if there is another bug lingering in the dmtimer
> > driver. Ideally, the context should be preserved by the driver.
> 
> Looking at omap_dm_timer_set_load_start() we have the following code to
> restore context ...
> 
> if (!(timer->capability & OMAP_TIMER_ALWON)) {
> 	if (omap_pm_get_dev_context_loss_count(&timer->pdev->dev) !=
> 			timer->ctx_loss_count)		
> 		omap_timer_restore_context(timer);
> }
> 
> Can you see if this is getting called for AM33xx for the failing timers?
> If not then it would suggest that we are not detecting context loss
> correctly and not restoring the context. With the above context restore
> code we should not need those extra omap_dm_timer_enable/disable calls.
> 

OK, below log explains all now,

----------------------
Testing 48042000.timer with 24000000 Hz clock ...
omap_dm_timer_set_load_start:559 ctx_loss_count - 0, get_dev_context - 0
Timer read test PASSED! No errors, 100 loops
omap_dm_timer_set_int_enable:665: irq_ena - 0
omap_dm_timer_set_int_enable:671: irq_ena - 2
omap_dm_timer_set_load_start:559 ctx_loss_count - 0, get_dev_context - 0
Timer interrupt test FAILED! No interrupt occurred in 1 sec
omap_dm_timer_set_int_enable:665: irq_ena - 0
omap_dm_timer_set_int_enable:671: irq_ena - 0
Testing 48042000.timer with 32768 Hz clock ...
omap_dm_timer_set_load_start:559 ctx_loss_count - 0, get_dev_context - 0
----------------------


So below condition is not passing for AM33xx which results into context loss.

if (omap_pm_get_dev_context_loss_count(&timer->pdev->dev) !=
                                 timer->ctx_loss_count)


Let me debug on this, this looks something specific to am33xx missing from 
baseport.

Thanks,
Vaibhav

^ permalink raw reply

* [GIT PULL] ux500 fixes due for v3.7 RCs
From: Lee Jones @ 2012-10-25 15:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CACRpkdZM3wHh9jey1eUfw9yjRTMK_fW5nKf1HcQuf2aExpPxbg@mail.gmail.com>

On Thu, 25 Oct 2012, Linus Walleij wrote:

> On Thu, Oct 25, 2012 at 3:52 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> 
> > Since we're now getting pull requests from both of you, Lee and Linus,
> > I'd like to understand how you are organized.
> >
> > Lee, are you just sending bug fixes directly and send future work through
> > Linus, or are you acting as backup maintainer when he is busy otherwise
> > in general?
> 
> Let us say that Lee is pushing stuff that is DT-related, e.g. fixes that
> only manifest in DT environments and I'm pushing most other stuff.
> 
> I'm happy that Lee is doing some nice offloading as pinctrl and gpio is
> currently quite busy.
> 
> One day Srinidhi may also send pull requests, as co-maintainer.

Right. As I was creating quite a lot of traffic, I've basically been
asked to push all my own stuff after I've acquired the right Acks.
I won't be pushing/acking anything else i.e. not acting as a co-
maintainer.

Hope that clears things up.

Kind regards,
Lee

-- 
Lee Jones
Linaro ST-Ericsson Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply

* [PATCH] ARM i.MX: fix error-valued pointer dereference in clk_register_gate2()
From: Sascha Hauer @ 2012-10-25 15:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAPgLHd9Q3bZVth2NSxwH6kBpPsBmRGD+4pfZRpWL69KCw4HY4g@mail.gmail.com>

On Thu, Oct 25, 2012 at 11:02:18PM +0800, Wei Yongjun wrote:
> From: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
> 
> The error-valued pointer clk is used for the arg of kfree, it should be
> kfree(gate) if clk_register() return ERR_PTR().
> 
> dpatch engine is used to auto generate this patch.
> (https://github.com/weiyj/dpatch)
> 
> Signed-off-by: Wei Yongjun <yongjun_wei@trendmicro.com.cn>

Applied, thanks

Sascha

> ---
>  arch/arm/mach-imx/clk-gate2.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm/mach-imx/clk-gate2.c b/arch/arm/mach-imx/clk-gate2.c
> index 3c1b8ff..cc49c7a 100644
> --- a/arch/arm/mach-imx/clk-gate2.c
> +++ b/arch/arm/mach-imx/clk-gate2.c
> @@ -112,7 +112,7 @@ struct clk *clk_register_gate2(struct device *dev, const char *name,
>  
>  	clk = clk_register(dev, &gate->hw);
>  	if (IS_ERR(clk))
> -		kfree(clk);
> +		kfree(gate);
>  
>  	return clk;
>  }
> 
> 
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply

* [PATCH] [RFC] pinctrl: mvebu: reset pins to an UNKNOWN state on startup
From: Stephen Warren @ 2012-10-25 15:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351106281-31288-1-git-send-email-thomas.petazzoni@free-electrons.com>

On 10/24/2012 01:18 PM, Thomas Petazzoni wrote:
> Note: this patch is a *RFC*, it is not intended for merging, only to
> get a discussion started. The code is horrible, makes terrible
> assumptions and so on.
> 
> On many platforms, most of the pinmux initialization is done in the
> bootloader, and therefore persists when we boot the Linux kernel. This
> prevents us from making sure that the pinmux configuration in the
> board device trees is correct.

Well, it's easy enough to determine that the kernel's configuration is
correct as far as it goes, since it's applied, and if everything still
works, the pinmux configuration is presumably correct. The issue is more
that the kernel's configuration may be missing some entries, and hence
relying on the bootloader having already set up some pins/groups.

> One idea to make sure our device trees are correct in terms of
> pinmuxing is to set the state of each pin to an unavailable function
> during the initialization of the pinctrl driver. This way, only pins
> that are explicitly configured through proper device tree attributes
> will actually be functional.

On Tegra at least, and I imagine many SoCs, there is not an
"unavailable" function for each pin/group. Hence, this would be
impossible to implement. For pins/groups where there is a mux function
that is reserved or actually does do nothing, the value of that mux
function is potentially different per pin/group. At least I suppose we
could force tristate on for all pingroups, so no output signals would work.

> Remaining questions to solve:
> 
>  * Is this useful?

I can certainly see the use of this, as an explicitly enabled option
used for testing at least. On Tegra, we've certainly had issues where
the kernel accidentally relies on the bootloader having set things up,
so when switching to a different lighter-weight bootloader, things stop
working. That was more w.r.t. clocks, but it could easily happen for
pinmux too.

>  * How to figure out what function number is a good function number to
>    set all pins to at startup? It could be passed by the SoC-specific
>    pinctrl drivers.

Yes, this would have to be either implemented by individual drivers, or
use data passed in by the individual drivers.

>  * Maybe some pins should be excluded for this, especially if the
>    console serial port pins are muxed. On Armada XP, it's not the
>    case: UART0 RX/UART0 TX pins are not part of MPPs, so we can clear
>    all pins. But on other mvebu platforms, it may be the case.

I don't think excluding the serial port pins would be useful.
Presumably, if you enable this option, you're doing so explicitly to
test the pinmux setup after you've tested that the kernel otherwise
works correctly. As such, if the serial port stops working when you flip
on this option, it's a pretty good clue that the serial port pinmux
setup isn't correct. Presumably, you might also enable earlyprintk over
the UART when debugging with this new option.

>  * If this sounds like an interesting thing, should we keep it only at
>    the mvebu driver level, or make it something more generically
>    available in the pinctrl subsystem?

Making this generic is probably complex for reasons I outlined above.
I'd tend towards a common kernel Kconfig or cmdline option to trigger
this, but have each driver use that option as it sees fit in its own
custom code. I imagine that will reduce the overall amount of code it
takes to implement this. If using a cmdline option, the pinmux core
should parse it, and set up some variable or function for the drivers to
query.

^ permalink raw reply

* [PATCH 1/2] ARM: clk-imx27: Add missing clock for mx2-camera
From: Sascha Hauer @ 2012-10-25 15:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1349473981-15084-2-git-send-email-fabio.estevam@freescale.com>

On Fri, Oct 05, 2012 at 06:53:01PM -0300, Fabio Estevam wrote:
> During the clock conversion for mx27 the "per4_gate" clock was missed to get
> registered as a dependency of mx2-camera driver.
> 
> In the old mx27 clock driver we used to have:
> 
> DEFINE_CLOCK1(csi_clk, 0, NULL, 0, parent, &csi_clk1, &per4_clk);
> 
> ,so does the same in the new clock driver.
> 
> Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>

I'm fine with merging this through the media tree.

Acked-by: Sascha Hauer <s.hauer@pengutronix.de>

Sascha

> ---
>  arch/arm/mach-imx/clk-imx27.c |    1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm/mach-imx/clk-imx27.c b/arch/arm/mach-imx/clk-imx27.c
> index 3b6b640..5ef0f08 100644
> --- a/arch/arm/mach-imx/clk-imx27.c
> +++ b/arch/arm/mach-imx/clk-imx27.c
> @@ -224,6 +224,7 @@ int __init mx27_clocks_init(unsigned long fref)
>  	clk_register_clkdev(clk[lcdc_ipg_gate], "ipg", "imx-fb.0");
>  	clk_register_clkdev(clk[lcdc_ahb_gate], "ahb", "imx-fb.0");
>  	clk_register_clkdev(clk[csi_ahb_gate], "ahb", "mx2-camera.0");
> +	clk_register_clkdev(clk[per4_gate], "per", "mx2-camera.0");
>  	clk_register_clkdev(clk[usb_div], "per", "fsl-usb2-udc");
>  	clk_register_clkdev(clk[usb_ipg_gate], "ipg", "fsl-usb2-udc");
>  	clk_register_clkdev(clk[usb_ahb_gate], "ahb", "fsl-usb2-udc");
> -- 
> 1.7.9.5
> 
> 
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply

* [PATCHv2] arm:socfpga: Enable SMP for socfpga
From: Rob Herring @ 2012-10-25 15:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351182356.15182.7.camel@dinh-ubuntu>



On 10/25/2012 11:25 AM, Dinh Nguyen wrote:
> Hi Rob,
> 
> On Wed, 2012-10-24 at 18:01 -0500, Rob Herring wrote:
>> On 10/18/2012 12:32 PM, dinguyen at altera.com wrote:
>>> From: Dinh Nguyen <dinguyen@altera.com>
>>>
>>> Enable SMP for the SOCFPGA platform.
>>>
>>> Signed-off-by: Pavel Machek <pavel@denx.de>
>>> Signed-off-by: Dinh Nguyen <dinguyen@altera.com>
>>> ---
>>> v2:
>>> -Remove pen_release code
>>> -Remove code that was already done by v7_setup
>>> -Add bindings document for reset and system manager
>>> -Move socfpga_sysmgr_init from platsmp.c to socfpga.c, because
>>> we will need to use the reset and system manager for more than SMP.
>>> -Move core.h to mach-socfpga from mach-socfpga/include/mach
>>
>> Just some lingering comments on the defconfig. Otherwise,
>>
>> Reviewed-by: Rob Herring <rob.herring@calxeda.com>
>>
>>> diff --git a/arch/arm/configs/socfpga_defconfig b/arch/arm/configs/socfpga_defconfig
>>> index 0ac1293..349ac22 100644
>>> --- a/arch/arm/configs/socfpga_defconfig
>>> +++ b/arch/arm/configs/socfpga_defconfig
>>
>> I'm still not clear why multi_v7 config does not work for you?
> 
> multi_v7 works fine for me. But I need
> +#CONFIG_ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA is not set 

Why? I don't think those should break other versions of A9. If they do,
we need to fix that. In general, we should turn on all errata for
multi-platform builds, so we need to make sure they are done in a
compatible way and can be bypassed if they have performance impacts.
That may ultimately require some runtime patching though.

Rob

> 
> in order for SMP to work correctly on our platform.
> 
> 
>>
>>> @@ -1,5 +1,5 @@
>>>  CONFIG_EXPERIMENTAL=y
>>> -CONFIG_SYSVIPC=y
>>> +CONFIG_NO_HZ=y
>>>  CONFIG_IKCONFIG=y
>>>  CONFIG_IKCONFIG_PROC=y
>>>  CONFIG_LOG_BUF_SHIFT=14
>>> @@ -16,10 +16,13 @@ CONFIG_MODULE_UNLOAD=y
>>>  # CONFIG_IOSCHED_DEADLINE is not set
>>>  # CONFIG_IOSCHED_CFQ is not set
>>>  CONFIG_ARCH_SOCFPGA=y
>>> -CONFIG_MACH_SOCFPGA_CYCLONE5=y
>>> -CONFIG_ARM_THUMBEE=y
>>> +# CONFIG_ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA is not set
>>>  # CONFIG_CACHE_L2X0 is not set
>>>  CONFIG_HIGH_RES_TIMERS=y
>>> +CONFIG_SMP=y
>>> +CONFIG_ARM_ARCH_TIMER=y
>>
>> You're an A9, right? You don't have arch timers.
> 
> Yes, will remove in v3.
>>
>>> +CONFIG_HIGHMEM=y
>>
>> How much RAM? You need more than 2GB with CONFIG_VMSPLIT_2G.
> 
> 1G for RAM only, so will remove in v3.
> 
> Thanks,
> Dinh
>>
>>> +CONFIG_HIGHPTE=y
>>>  CONFIG_VMSPLIT_2G=y
>>>  CONFIG_NR_CPUS=2
>>>  CONFIG_AEABI=y
>>
>>
> 
> 
> 

^ permalink raw reply

* [PATCH 5/7] ARM: OMAP2+: WDT: move init; add read_reset_sources pdata function pointer
From: Aaro Koskinen @ 2012-10-25 15:38 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121016013213.21844.20016.stgit@dusk.lan>

Hi,

On Mon, Oct 15, 2012 at 07:32:33PM -0600, Paul Walmsley wrote:
> The OMAP watchdog timer driver directly calls a function exported by
> code in arch/arm/mach-omap2.  This is not good; it tightly couples
> this driver to the mach-omap2 integration code.  Instead, add a
> temporary platform_data function pointer to abstract this function
> call.  A subsequent patch will convert the watchdog driver to use this
> function pointer.

Why a function is needed? Reset cause won't change until the next reset,
so it should be enough to read it once during the init and store it into
the platform data.

A.

^ permalink raw reply

* [PATCH] ARM: dt: tegra: ventana: define pinmux for ddc
From: Stephen Warren @ 2012-10-25 15:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <5088DCF2.7030000@nvidia.com>

On 10/25/2012 12:32 AM, Mark Zhang wrote:
> On 10/23/2012 01:14 AM, Stephen Warren wrote:
...
>> I don't recall why pta was defined to be HDMI. The issue isn't that this
>> patch changes the pinmux selection for the pta pingroup, but simply that
>> both the pinctrl node's state definition, and the new I2C mux node's
>> state definition both attempt to configure pingroup pta. The solution is
>> most likely to simply remove the pta configuration from the main pinctrl
>> node.
> 
> Understood. I tried to remove the hdmi function definition of pta
> pingroup yesterday then found HDMI can't work anymore. The EDID of HDMI
> monitor can't be fetched. After some debugging, I have found that it's
> caused by "i2c-mux-pinctrl" driver is loaded after drm driver. That
> makes drm driver can't get EDID data via this i2c mux adapter because it
> doesn't exist at that time. So I think we need to promote the load level
> of "i2c-mux-pinctrl" driver. Any other ideas?

(BTW, your message that I'm replying to wasn't word-wrapped correctly)

No, i2c-mux-pinctrl shouldn't need to change. It sounds like tegra-drm
isn't supporting deferred probe correctly; when it needs access to an
I2C adapter that doesn't exist, it should defer its own probe until the
I2C adapter does exist.

^ permalink raw reply

* [PATCH 1/7] ARM: clps711x: convert to clockevents
From: Arnd Bergmann @ 2012-10-25 15:30 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1349883933-8881-1-git-send-email-shc_work@mail.ru>

On Wednesday 10 October 2012, Alexander Shiyan wrote:
> This patch converts CLPS711X-platform to use modern clockevent API.
> 
> Signed-off-by: Alexander Shiyan <shc_work@mail.ru>

Applied the entire series. There are a few things that you can do
to simplify the process so you don't have to remind us to pull in
patches you send:

* Use 'git format-patch --cover-letter' to create an introductory
email, and in that mail, ask us specifically to pull it into arm-soc
of that is the idea, or to just do a review for the first version.

* Send one patch to add yourself to the maintainers file. You are
the only person who is sending patches for clps711x at the moment,
and we don't have a formal maintainer besides you, so I think you
should do it officially.

* If possible, provide a git URL to pull from directly, and use
a signed tag to describe the series overall. Use "git request-pull"
to send the email asking for your changes to be pulled in.

The patches from this set are now in the clps711x/soc branch,
merged into the next/soc branch that will be sent in the 3.8
merge window and they are part of the for-next branch to get
testing in the linux-next kernel.

	Arnd

^ permalink raw reply

* [PATCH V3 1/5] ARM: dts: OMAP: Add timer nodes
From: Hiremath, Vaibhav @ 2012-10-25 15:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <50892E27.7070102@ti.com>

On Thu, Oct 25, 2012 at 17:48:47, Hunter, Jon wrote:
> 
> On 10/25/2012 07:12 AM, Hiremath, Vaibhav wrote:
> > On Thu, Oct 25, 2012 at 04:30:37, Hunter, Jon wrote:
> >>
> >> On 10/24/2012 01:17 PM, Hiremath, Vaibhav wrote:
> >>> On Wed, Oct 17, 2012 at 23:31:09, Hunter, Jon wrote:
> >>>> Add the 12 GP timers nodes present in OMAP2.
> >>>> Add the 12 GP timers nodes present in OMAP3.
> >>>> Add the 11 GP timers nodes present in OMAP4.
> >>>> Add the 7 GP timers nodes present in AM33xx.
> >>>>
> >>>> Add documentation for timer properties specific to OMAP.
> >>>>
> >>>> Please note that for OMAP2/3 devices, there is only one interrupt controller
> >>>> for the ARM CPU (which has the label "intc") and so globally define this as the
> >>>> interrupt parent to save duplicating the interrupt parent for all device nodes.
> >>>>
> >>>> Thanks to Vaibhav Hiremath for creating the AM33xx timer nodes. I have modified
> >>>> Vaibhav's original nodes adding information on which timers support a PWM
> >>>> output.
> >>>>
> >>>> Cc: Benoit Cousson <b-cousson@ti.com>
> >>>> Signed-off-by: Jon Hunter <jon-hunter@ti.com>
> >>>> ---
> >>>>  .../devicetree/bindings/arm/omap/timer.txt         |   29 ++++++
> >>>>  arch/arm/boot/dts/am33xx.dtsi                      |   61 +++++++++++++
> >>>>  arch/arm/boot/dts/omap2.dtsi                       |   86 ++++++++++++++++++
> >>>>  arch/arm/boot/dts/omap2420.dtsi                    |    8 ++
> >>>>  arch/arm/boot/dts/omap2430.dtsi                    |    8 ++
> >>>>  arch/arm/boot/dts/omap3.dtsi                       |   96 ++++++++++++++++++++
> >>>>  arch/arm/boot/dts/omap4.dtsi                       |   86 ++++++++++++++++++
> >>>>  7 files changed, 374 insertions(+)
> >>>>  create mode 100644 Documentation/devicetree/bindings/arm/omap/timer.txt
> >>>>
> >>>
> >>> Although I have not tested this version of patch series at my end, but 
> >>> whole patch-series Looks ok to me.
> >>>
> >>> Acked-By: Vaibhav Hiremath <hvaibhav@ti.com>
> >>
> >> Thanks. I made a couple cosmetic changes in V4 apart from the
> >> "interrupt-parent" addition which we are now dropping. Care to ACK
> >> patches 2-5 of V4?
> >>
> > 
> > Jon,
> > 
> > Good news, I could able to spend some time today on Timer issue on Am33xx 
> > and figure out what is going wrong there. The register context is loosing,
> > which leads to failure of interrupt test cases.
> 
> Thanks!
> 
> > Below log describes more on this,
> > 
> > 
> > [root at arago /]# echo 1 > /tmp/omap-test/timer/all
> > [    9.156122] Testing 48042000.timer with 24000000 Hz clock ...
> > [root at arago /]#
> > [root at arago /]#
> > [root at arago /]#
> > [root at arago /]# [   11.505497] Timer read test PASSED! No errors, 100 loops
> > [   11.511493] omap_dm_timer_set_int_enable:664: irq_ena - 0
> > [   11.517277] omap_dm_timer_set_int_enable:670: irq_ena - 2
> > [   11.523095] omap_timer_interrupt_test:120: irq_ena - 0 	[BOOOOOOOOM]
> > [   12.521111] Timer interrupt test FAILED! No interrupt occurred in 1 sec
> > 
> > 
> > I changed the Test code as below, and not with your Timer patches, I have 
> > tested all the timers without any issues.
> > 
> > So for all patch series, 
> > 
> > Acked-Reviewed-&-Tested-By: Vaibhav Hiremath <hvaibhav@ti.com>
> 
> Thanks!
> 
> > 
> > Test code diff:
> > ===============
> > 
> > diff --git a/timer_test.c b/timer_test.c
> > index e502881..c87a830 100644
> > --- a/timer_test.c
> > +++ b/timer_test.c
> > @@ -13,6 +13,7 @@
> > 
> >  #define OMAP1_NUM_TIMERS       8
> >  #define OMAP2_NUM_TIMERS       11
> > +#define AM33XX_NUM_TIMERS      7
> >  #define OMAP_MAX_NUM_TIMERS    12
> >  #define OMAP_TIMER_SRC_CLKS    2
> >  #define TIMER_TIMEOUT          (msecs_to_jiffies(1000))
> > @@ -113,6 +114,9 @@ static int omap_timer_interrupt_test(struct omap_dm_timer *gptimer)
> > 
> >         irq_data.gptimer = gptimer;
> >         init_completion(&irq_data.complete);
> > +
> > +       omap_dm_timer_enable(gptimer);
> > +
> >         omap_dm_timer_set_int_enable(gptimer, OMAP_TIMER_INT_OVERFLOW);
> >         omap_dm_timer_set_load_start(gptimer, 0, 0xffffff00);
> > 
> > @@ -128,6 +132,8 @@ static int omap_timer_interrupt_test(struct omap_dm_timer *gptimer)
> > 
> >         omap_dm_timer_stop(gptimer);
> >         omap_dm_timer_set_int_enable(gptimer, 0);
> > +       omap_dm_timer_disable(gptimer);
> > +
> 
> Hmmm ... I am wondering if there is another bug lingering in the dmtimer
> driver. Ideally, the context should be preserved by the driver.
> 

That's what I am going behind...

> >         free_irq(timer_irq, &irq_data);
> > 
> >         return r;
> > @@ -141,6 +147,8 @@ static u32 omap_timer_num_timers(void)
> >                 max_num_timers = OMAP1_NUM_TIMERS;
> >         else if (cpu_is_omap34xx() && (omap_type() == OMAP2_DEVICE_TYPE_GP))
> >                 max_num_timers = OMAP2_NUM_TIMERS + 1;
> > +       else if (soc_is_am33xx())
> > +               max_num_timers = AM33XX_NUM_TIMERS;
> 
> Thanks, I noticed that too when testing AM33xx.
> 

Can you merge it to your test module? I am thinking of pushing application 
to github for others to use. I believe you are ok with this. I am planning 
to push all the application there.

https://github.com/hvaibhav/sample-applications

Thanks,
Vaibhav

> Cheers
> Jon
> 

^ permalink raw reply

* [PATCH v3 6/6] ARM: EXYNOS: Add secure firmware support to secondary CPU bring-up
From: Tomasz Figa @ 2012-10-25 15:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351178560-19188-1-git-send-email-t.figa@samsung.com>

Boards using secure firmware must use different CPU boot registers and
call secure firmware to boot the CPU.

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
 arch/arm/mach-exynos/platsmp.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
index 4ca8ff1..9f8bdaf 100644
--- a/arch/arm/mach-exynos/platsmp.c
+++ b/arch/arm/mach-exynos/platsmp.c
@@ -25,6 +25,7 @@
 #include <asm/hardware/gic.h>
 #include <asm/smp_plat.h>
 #include <asm/smp_scu.h>
+#include <asm/firmware.h>
 
 #include <mach/hardware.h>
 #include <mach/regs-clock.h>
@@ -47,6 +48,8 @@ static inline void __iomem *cpu_boot_reg(int cpu)
 {
 	void __iomem *boot_reg;
 
+	if (!call_firmware_op(cpu_boot_reg, cpu, &boot_reg))
+		return boot_reg;
 	boot_reg = cpu_boot_reg_base();
 	if (soc_is_exynos4412())
 		boot_reg += 4*cpu;
@@ -149,6 +152,10 @@ static int __cpuinit exynos_boot_secondary(unsigned int cpu, struct task_struct
 
 		__raw_writel(virt_to_phys(exynos4_secondary_startup),
 							cpu_boot_reg(phys_cpu));
+
+		/* Call Exynos specific smc call */
+		call_firmware_op(cpu_boot, phys_cpu);
+
 		gic_raise_softirq(cpumask_of(cpu), 0);
 
 		if (pen_release == -1)
-- 
1.7.12

^ permalink raw reply related

* [PATCH v3 5/6] ARM: EXYNOS: Add support for secondary CPU bring-up on Exynos4412
From: Tomasz Figa @ 2012-10-25 15:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351178560-19188-1-git-send-email-t.figa@samsung.com>

Exynos4412 uses different information register for each core. This patch
adjusts the bring-up code to take that into account.

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
 arch/arm/mach-exynos/platsmp.c | 30 ++++++++++++++++++++++++------
 1 file changed, 24 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
index f93d820..4ca8ff1 100644
--- a/arch/arm/mach-exynos/platsmp.c
+++ b/arch/arm/mach-exynos/platsmp.c
@@ -36,8 +36,22 @@
 
 extern void exynos4_secondary_startup(void);
 
-#define CPU1_BOOT_REG		(samsung_rev() == EXYNOS4210_REV_1_1 ? \
-				S5P_INFORM5 : S5P_VA_SYSRAM)
+static inline void __iomem *cpu_boot_reg_base(void)
+{
+	if (soc_is_exynos4210() && samsung_rev() == EXYNOS4210_REV_1_1)
+		return S5P_INFORM5;
+	return S5P_VA_SYSRAM;
+}
+
+static inline void __iomem *cpu_boot_reg(int cpu)
+{
+	void __iomem *boot_reg;
+
+	boot_reg = cpu_boot_reg_base();
+	if (soc_is_exynos4412())
+		boot_reg += 4*cpu;
+	return boot_reg;
+}
 
 /*
  * Write pen_release in a way that is guaranteed to be visible to all
@@ -84,6 +98,7 @@ static void __cpuinit exynos_secondary_init(unsigned int cpu)
 static int __cpuinit exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
 	unsigned long timeout;
+	unsigned long phys_cpu = cpu_logical_map(cpu);
 
 	/*
 	 * Set synchronisation state between this boot processor
@@ -99,7 +114,7 @@ static int __cpuinit exynos_boot_secondary(unsigned int cpu, struct task_struct
 	 * Note that "pen_release" is the hardware CPU ID, whereas
 	 * "cpu" is Linux's internal ID.
 	 */
-	write_pen_release(cpu_logical_map(cpu));
+	write_pen_release(phys_cpu);
 
 	if (!(__raw_readl(S5P_ARM_CORE1_STATUS) & S5P_CORE_LOCAL_PWR_EN)) {
 		__raw_writel(S5P_CORE_LOCAL_PWR_EN,
@@ -133,7 +148,7 @@ static int __cpuinit exynos_boot_secondary(unsigned int cpu, struct task_struct
 		smp_rmb();
 
 		__raw_writel(virt_to_phys(exynos4_secondary_startup),
-			CPU1_BOOT_REG);
+							cpu_boot_reg(phys_cpu));
 		gic_raise_softirq(cpumask_of(cpu), 0);
 
 		if (pen_release == -1)
@@ -181,6 +196,8 @@ static void __init exynos_smp_init_cpus(void)
 
 static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
 {
+	int i;
+
 	if (!soc_is_exynos5250())
 		scu_enable(scu_base_addr());
 
@@ -190,8 +207,9 @@ static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
 	 * until it receives a soft interrupt, and then the
 	 * secondary CPU branches to this address.
 	 */
-	__raw_writel(virt_to_phys(exynos4_secondary_startup),
-			CPU1_BOOT_REG);
+	for (i = 1; i < max_cpus; ++i)
+		__raw_writel(virt_to_phys(exynos4_secondary_startup),
+					cpu_boot_reg(cpu_logical_map(i)));
 }
 
 struct smp_operations exynos_smp_ops __initdata = {
-- 
1.7.12

^ permalink raw reply related

* [PATCH v3 4/6] ARM: EXYNOS: Add support for Exynos secure firmware
From: Tomasz Figa @ 2012-10-25 15:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351178560-19188-1-git-send-email-t.figa@samsung.com>

Some Exynos-based boards contain secure firmware and must use firmware
operations to set up some hardware.

This patch adds firmware operations for Exynos secure firmware and a way
for board code and device tree to specify that they must be used.

Example of use:

In board code:

	...MACHINE_START(...)
		/* ... */
		.init_early	= exynos_firmware_init,
		/* ... */
	MACHINE_END

In device tree:

	/ {
		/* ... */

		firmware at 0203F000 {
			compatible = "samsung,secure-firmware";
			reg = <0x0203F000 0x1000>;
		};

		/* ... */
	};

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
 .../devicetree/bindings/arm/samsung-boards.txt     | 10 ++++
 arch/arm/mach-exynos/Makefile                      |  1 +
 arch/arm/mach-exynos/common.h                      |  2 +
 arch/arm/mach-exynos/firmware.c                    | 67 ++++++++++++++++++++++
 arch/arm/mach-exynos/mach-exynos4-dt.c             |  1 +
 5 files changed, 81 insertions(+)
 create mode 100644 arch/arm/mach-exynos/firmware.c

diff --git a/Documentation/devicetree/bindings/arm/samsung-boards.txt b/Documentation/devicetree/bindings/arm/samsung-boards.txt
index 0bf68be..2168ed3 100644
--- a/Documentation/devicetree/bindings/arm/samsung-boards.txt
+++ b/Documentation/devicetree/bindings/arm/samsung-boards.txt
@@ -6,3 +6,13 @@ Required root node properties:
     - compatible = should be one or more of the following.
         (a) "samsung,smdkv310" - for Samsung's SMDKV310 eval board.
         (b) "samsung,exynos4210"  - for boards based on Exynos4210 SoC.
+
+Optional:
+    - firmware node, specifying presence and type of secure firmware:
+        - compatible: only "samsung,secure-firmware" is currently supported
+        - reg: address of non-secure SYSRAM used for communication with firmware
+
+	firmware at 0203F000 {
+		compatible = "samsung,secure-firmware";
+		reg = <0x0203F000 0x1000>;
+	};
diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile
index 5c1de47..b464333 100644
--- a/arch/arm/mach-exynos/Makefile
+++ b/arch/arm/mach-exynos/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_EXYNOS4_MCT)	+= mct.o
 obj-$(CONFIG_HOTPLUG_CPU)	+= hotplug.o
 
 obj-$(CONFIG_ARCH_EXYNOS)	+= exynos-smc.o
+obj-$(CONFIG_ARCH_EXYNOS)	+= firmware.o
 
 plus_sec := $(call as-instr,.arch_extension sec,+sec)
 AFLAGS_exynos-smc.o		:=-Wa,-march=armv7-a$(plus_sec)
diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h
index dac146d..5f1d393 100644
--- a/arch/arm/mach-exynos/common.h
+++ b/arch/arm/mach-exynos/common.h
@@ -22,6 +22,8 @@ void exynos4_restart(char mode, const char *cmd);
 void exynos5_restart(char mode, const char *cmd);
 void exynos_init_late(void);
 
+void exynos_firmware_init(void);
+
 #ifdef CONFIG_PM_GENERIC_DOMAINS
 int exynos_pm_late_initcall(void);
 #else
diff --git a/arch/arm/mach-exynos/firmware.c b/arch/arm/mach-exynos/firmware.c
new file mode 100644
index 0000000..15d3c87
--- /dev/null
+++ b/arch/arm/mach-exynos/firmware.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics.
+ * Kyungmin Park <kyungmin.park@samsung.com>
+ * Tomasz Figa <t.figa@samsung.com>
+ *
+ * This program is free software,you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include <asm/firmware.h>
+
+#include <mach/map.h>
+
+#include "smc.h"
+
+static int exynos_do_idle(void)
+{
+        exynos_smc(SMC_CMD_SLEEP, 0, 0, 0);
+        return 0;
+}
+
+static int exynos_cpu_boot(int cpu)
+{
+	exynos_smc(SMC_CMD_CPU1BOOT, cpu, 0, 0);
+	return 0;
+}
+
+static int exynos_cpu_boot_reg(int cpu, void __iomem **ptr)
+{
+	*ptr = S5P_VA_SYSRAM_NS + 0x1c + 4*cpu;
+	return 0;
+}
+
+static const struct firmware_ops exynos_firmware_ops = {
+	.do_idle	= exynos_do_idle,
+	.cpu_boot	= exynos_cpu_boot,
+	.cpu_boot_reg	= exynos_cpu_boot_reg,
+};
+
+void __init exynos_firmware_init(void)
+{
+	if (of_have_populated_dt()) {
+		struct device_node *nd;
+		const __be32 *addr;
+
+		nd = of_find_compatible_node(NULL, NULL,
+						"samsung,secure-firmware");
+		if (!nd)
+			return;
+
+		addr = of_get_address(nd, 0, NULL, NULL);
+		if (!addr) {
+			pr_err("%s: No address specified.\n", __func__);
+			return;
+		}
+	}
+
+	pr_info("Running under secure firmware.\n");
+
+	register_firmware_ops(&exynos_firmware_ops);
+}
diff --git a/arch/arm/mach-exynos/mach-exynos4-dt.c b/arch/arm/mach-exynos/mach-exynos4-dt.c
index eadf4b5..977bd39 100644
--- a/arch/arm/mach-exynos/mach-exynos4-dt.c
+++ b/arch/arm/mach-exynos/mach-exynos4-dt.c
@@ -103,6 +103,7 @@ DT_MACHINE_START(EXYNOS4210_DT, "Samsung Exynos4 (Flattened Device Tree)")
 	.init_irq	= exynos4_init_irq,
 	.map_io		= exynos4_dt_map_io,
 	.handle_irq	= gic_handle_irq,
+	.init_early	= exynos_firmware_init,
 	.init_machine	= exynos4_dt_machine_init,
 	.init_late	= exynos_init_late,
 	.timer		= &exynos4_timer,
-- 
1.7.12

^ permalink raw reply related

* [PATCH v3 3/6] ARM: EXYNOS: Add IO mapping for non-secure SYSRAM.
From: Tomasz Figa @ 2012-10-25 15:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351178560-19188-1-git-send-email-t.figa@samsung.com>

On TrustZone-enabled boards the non-secure SYSRAM is used for secondary
CPU bring-up, so add a mapping for it.

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
 arch/arm/mach-exynos/common.c                | 35 ++++++++++++++++++++++++++++
 arch/arm/mach-exynos/include/mach/map.h      |  3 +++
 arch/arm/plat-samsung/include/plat/map-s5p.h |  1 +
 3 files changed, 39 insertions(+)

diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c
index 1947be8..cb891a7 100644
--- a/arch/arm/mach-exynos/common.c
+++ b/arch/arm/mach-exynos/common.c
@@ -215,6 +215,33 @@ static struct map_desc exynos4_iodesc1[] __initdata = {
 	},
 };
 
+static struct map_desc exynos4210_iodesc[] __initdata = {
+	{
+		.virtual	= (unsigned long)S5P_VA_SYSRAM_NS,
+		.pfn		= __phys_to_pfn(EXYNOS4210_PA_SYSRAM_NS),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
+	},
+};
+
+static struct map_desc exynos4x12_iodesc[] __initdata = {
+	{
+		.virtual	= (unsigned long)S5P_VA_SYSRAM_NS,
+		.pfn		= __phys_to_pfn(EXYNOS4x12_PA_SYSRAM_NS),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
+	},
+};
+
+static struct map_desc exynos5250_iodesc[] __initdata = {
+	{
+		.virtual	= (unsigned long)S5P_VA_SYSRAM_NS,
+		.pfn		= __phys_to_pfn(EXYNOS5250_PA_SYSRAM_NS),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
+	},
+};
+
 static struct map_desc exynos5_iodesc[] __initdata = {
 	{
 		.virtual	= (unsigned long)S3C_VA_SYS,
@@ -322,6 +349,11 @@ static void __init exynos4_map_io(void)
 	else
 		iotable_init(exynos4_iodesc1, ARRAY_SIZE(exynos4_iodesc1));
 
+	if (soc_is_exynos4210())
+		iotable_init(exynos4210_iodesc, ARRAY_SIZE(exynos4210_iodesc));
+	if (soc_is_exynos4212() || soc_is_exynos4412())
+		iotable_init(exynos4x12_iodesc, ARRAY_SIZE(exynos4x12_iodesc));
+
 	/* initialize device information early */
 	exynos4_default_sdhci0();
 	exynos4_default_sdhci1();
@@ -355,6 +387,9 @@ static void __init exynos5_map_io(void)
 {
 	iotable_init(exynos5_iodesc, ARRAY_SIZE(exynos5_iodesc));
 
+	if (soc_is_exynos5250())
+		iotable_init(exynos5250_iodesc, ARRAY_SIZE(exynos5250_iodesc));
+
 	s3c_device_i2c0.resource[0].start = EXYNOS5_PA_IIC(0);
 	s3c_device_i2c0.resource[0].end   = EXYNOS5_PA_IIC(0) + SZ_4K - 1;
 	s3c_device_i2c0.resource[1].start = EXYNOS5_IRQ_IIC;
diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h
index 8480849..42f4444 100644
--- a/arch/arm/mach-exynos/include/mach/map.h
+++ b/arch/arm/mach-exynos/include/mach/map.h
@@ -26,6 +26,9 @@
 #define EXYNOS4_PA_SYSRAM0		0x02025000
 #define EXYNOS4_PA_SYSRAM1		0x02020000
 #define EXYNOS5_PA_SYSRAM		0x02020000
+#define EXYNOS4210_PA_SYSRAM_NS		0x0203F000
+#define EXYNOS4x12_PA_SYSRAM_NS		0x0204F000
+#define EXYNOS5250_PA_SYSRAM_NS		0x0204F000
 
 #define EXYNOS4_PA_FIMC0		0x11800000
 #define EXYNOS4_PA_FIMC1		0x11810000
diff --git a/arch/arm/plat-samsung/include/plat/map-s5p.h b/arch/arm/plat-samsung/include/plat/map-s5p.h
index c2d7bda..c186786 100644
--- a/arch/arm/plat-samsung/include/plat/map-s5p.h
+++ b/arch/arm/plat-samsung/include/plat/map-s5p.h
@@ -22,6 +22,7 @@
 #define S5P_VA_GPIO3		S3C_ADDR(0x02280000)
 
 #define S5P_VA_SYSRAM		S3C_ADDR(0x02400000)
+#define S5P_VA_SYSRAM_NS	S3C_ADDR(0x02410000)
 #define S5P_VA_DMC0		S3C_ADDR(0x02440000)
 #define S5P_VA_DMC1		S3C_ADDR(0x02480000)
 #define S5P_VA_SROMC		S3C_ADDR(0x024C0000)
-- 
1.7.12

^ permalink raw reply related

* [PATCH v3 2/6] ARM: EXYNOS: Add support for secure monitor calls
From: Tomasz Figa @ 2012-10-25 15:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351178560-19188-1-git-send-email-t.figa@samsung.com>

Some boards use secure monitor calls to communicate with secure
firmware.

This patch adds exynos_smc function which uses smc assembly instruction
to do secure monitor calls.

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
 arch/arm/mach-exynos/Makefile     |  5 +++++
 arch/arm/mach-exynos/exynos-smc.S | 22 ++++++++++++++++++++++
 arch/arm/mach-exynos/smc.h        | 31 +++++++++++++++++++++++++++++++
 3 files changed, 58 insertions(+)
 create mode 100644 arch/arm/mach-exynos/exynos-smc.S
 create mode 100644 arch/arm/mach-exynos/smc.h

diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile
index 9b58024..5c1de47 100644
--- a/arch/arm/mach-exynos/Makefile
+++ b/arch/arm/mach-exynos/Makefile
@@ -30,6 +30,11 @@ obj-$(CONFIG_EXYNOS4_MCT)	+= mct.o
 
 obj-$(CONFIG_HOTPLUG_CPU)	+= hotplug.o
 
+obj-$(CONFIG_ARCH_EXYNOS)	+= exynos-smc.o
+
+plus_sec := $(call as-instr,.arch_extension sec,+sec)
+AFLAGS_exynos-smc.o		:=-Wa,-march=armv7-a$(plus_sec)
+
 # machine support
 
 obj-$(CONFIG_MACH_SMDKC210)		+= mach-smdkv310.o
diff --git a/arch/arm/mach-exynos/exynos-smc.S b/arch/arm/mach-exynos/exynos-smc.S
new file mode 100644
index 0000000..2e27aa3
--- /dev/null
+++ b/arch/arm/mach-exynos/exynos-smc.S
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics.
+ *
+ * Copied from omap-smc.S Copyright (C) 2010 Texas Instruments, Inc.
+ *
+ * This program is free software,you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/linkage.h>
+
+/*
+ * Function signature: void exynos_smc(u32 cmd, u32 arg1, u32 arg2, u32 arg3)
+ */
+
+ENTRY(exynos_smc)
+	stmfd	sp!, {r4-r11, lr}
+	dsb
+	smc	#0
+	ldmfd	sp!, {r4-r11, pc}
+ENDPROC(exynos_smc)
diff --git a/arch/arm/mach-exynos/smc.h b/arch/arm/mach-exynos/smc.h
new file mode 100644
index 0000000..e972390
--- /dev/null
+++ b/arch/arm/mach-exynos/smc.h
@@ -0,0 +1,31 @@
+/*
+ *  Copyright (c) 2012 Samsung Electronics.
+ *
+ * EXYNOS - SMC Call
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_EXYNOS_SMC_H
+#define __ASM_ARCH_EXYNOS_SMC_H
+
+#define SMC_CMD_INIT            (-1)
+#define SMC_CMD_INFO            (-2)
+/* For Power Management */
+#define SMC_CMD_SLEEP           (-3)
+#define SMC_CMD_CPU1BOOT        (-4)
+#define SMC_CMD_CPU0AFTR        (-5)
+/* For CP15 Access */
+#define SMC_CMD_C15RESUME       (-11)
+/* For L2 Cache Access */
+#define SMC_CMD_L2X0CTRL        (-21)
+#define SMC_CMD_L2X0SETUP1      (-22)
+#define SMC_CMD_L2X0SETUP2      (-23)
+#define SMC_CMD_L2X0INVALL      (-24)
+#define SMC_CMD_L2X0DEBUG       (-25)
+
+extern void exynos_smc(u32 cmd, u32 arg1, u32 arg2, u32 arg3);
+
+#endif
-- 
1.7.12

^ permalink raw reply related

* [PATCH v3 1/6] ARM: Add interface for registering and calling firmware-specific operations
From: Tomasz Figa @ 2012-10-25 15:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351178560-19188-1-git-send-email-t.figa@samsung.com>

Some boards are running with secure firmware running in TrustZone secure
world, which changes the way some things have to be initialized.

This patch adds an interface for platforms to specify available firmware
operations and call them.

A wrapper macro, call_firmware_op(), checks if the operation is provided
and calls it if so, otherwise returns -ENOSYS to allow fallback to
legacy operation..

By default no operations are provided.

Example of use:

In code using firmware ops:

	__raw_writel(virt_to_phys(exynos4_secondary_startup),
		CPU1_BOOT_REG);

	/* Call Exynos specific smc call */
	if (call_firmware_op(cpu_boot, cpu) == -ENOSYS)
		cpu_boot_legacy(...); /* Try legacy way */

	gic_raise_softirq(cpumask_of(cpu), 1);

In board-/platform-specific code:

	static int platformX_do_idle(void)
	{
		/* tell platformX firmware to enter idle */
	        return 0;
	}

	static int platformX_cpu_boot(int i)
	{
		/* tell platformX firmware to boot CPU i */
		return 0;
	}

	static const struct firmware_ops platformX_firmware_ops = {
		.do_idle	= exynos_do_idle,
		.cpu_boot	= exynos_cpu_boot,
		/* other operations not available on platformX */
	};

	static void __init board_init_early(void)
	{
	????????register_firmware_ops(&platformX_firmware_ops);
	}

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
 arch/arm/common/Makefile        |  2 ++
 arch/arm/common/firmware.c      | 18 ++++++++++++++++++
 arch/arm/include/asm/firmware.h | 31 +++++++++++++++++++++++++++++++
 3 files changed, 51 insertions(+)
 create mode 100644 arch/arm/common/firmware.c
 create mode 100644 arch/arm/include/asm/firmware.h

diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile
index e8a4e58..55d4182 100644
--- a/arch/arm/common/Makefile
+++ b/arch/arm/common/Makefile
@@ -2,6 +2,8 @@
 # Makefile for the linux kernel.
 #
 
+obj-y += firmware.o
+
 obj-$(CONFIG_ARM_GIC)		+= gic.o
 obj-$(CONFIG_ARM_VIC)		+= vic.o
 obj-$(CONFIG_ICST)		+= icst.o
diff --git a/arch/arm/common/firmware.c b/arch/arm/common/firmware.c
new file mode 100644
index 0000000..27ddccb
--- /dev/null
+++ b/arch/arm/common/firmware.c
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics.
+ * Kyungmin Park <kyungmin.park@samsung.com>
+ * Tomasz Figa <t.figa@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/suspend.h>
+
+#include <asm/firmware.h>
+
+static const struct firmware_ops default_firmware_ops;
+
+const struct firmware_ops *firmware_ops = &default_firmware_ops;
diff --git a/arch/arm/include/asm/firmware.h b/arch/arm/include/asm/firmware.h
new file mode 100644
index 0000000..5d87d8e
--- /dev/null
+++ b/arch/arm/include/asm/firmware.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics.
+ * Kyungmin Park <kyungmin.park@samsung.com>
+ * Tomasz Figa <t.figa@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARM_FIRMWARE_H
+#define __ASM_ARM_FIRMWARE_H
+
+struct firmware_ops {
+	int (*do_idle)(void);
+	int (*cpu_boot)(int cpu);
+	int (*cpu_boot_reg)(int cpu, void __iomem **ptr);
+	int (*l2x0_init)(void);
+};
+
+extern const struct firmware_ops *firmware_ops;
+
+#define call_firmware_op(op, ...)					\
+	((firmware_ops->op) ? firmware_ops->op(__VA_ARGS__) : (-ENOSYS))
+
+static inline void register_firmware_ops(const struct firmware_ops *ops)
+{
+	firmware_ops = ops;
+}
+
+#endif
-- 
1.7.12

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox