On Lager a da9210 regulator is used to supply DVFS power to the SoC. This
patch series adds I2C and Z-clock support on r8a7790 and CPUFreq support
for the Lager board. Please note, that patch 4/4 is an RFC as explained
inline.
Developed on top of today's
git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git devel
plus i2c-rcar patches from my earlier patch series
[PATCH v2 0/5] i2c: rcar: Device Tree support and clock improvements
and the "sh-pfc: r8a7790: Add I2C pin groups and functions" patch from
Ulrich Hecht.
All changes since v1 are noted in respective patches. They all are trivial,
still as soon as test hardware is available, it would be good to run-time
test this version too.
Cc: Guennadi Liakhovetski <[email protected]>
Guennadi Liakhovetski (5):
pinctrl: sh-pfc: r8a7790: add pin definitions for the I2C3 interface
ARM: shmobile: r8a7790: add I2C clocks and aliases for the DT mode
ARM: shmobile: r8a7790: add I2C DT nodes
ARM: shmobile: r8a7790: add CPUFreq clock support
ARM: shmobile: lager: (DEVEL) add CPUFreq support
arch/arm/boot/dts/r8a7790-lager-reference.dts | 33 +++++
arch/arm/boot/dts/r8a7790.dtsi | 40 ++++++
arch/arm/mach-shmobile/Kconfig | 2 +
arch/arm/mach-shmobile/board-lager-reference.c | 4 +-
arch/arm/mach-shmobile/clock-r8a7790.c | 160 ++++++++++++++++++++++++
drivers/pinctrl/sh-pfc/pfc-r8a7790.c | 28 ++++
6 files changed, 266 insertions(+), 1 deletions(-)
--
1.7.2.5
Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/
The Lager board uses a DA9210 voltage regulator to supply DVFS power to the
CA15 cores on the r8a7790 SoC. This patch adds CPUFreq support for that
board using the cpufreq-cpu0 driver.
Signed-off-by: Guennadi Liakhovetski <[email protected]>
---
v2: added 'status = "okay";' to the i2c bus
arch/arm/boot/dts/r8a7790-lager-reference.dts | 33 ++++++++++++++++++++++++
arch/arm/mach-shmobile/board-lager-reference.c | 4 ++-
2 files changed, 36 insertions(+), 1 deletions(-)
diff --git a/arch/arm/boot/dts/r8a7790-lager-reference.dts b/arch/arm/boot/dts/r8a7790-lager-reference.dts
index c462ef1..1ce0a97 100644
--- a/arch/arm/boot/dts/r8a7790-lager-reference.dts
+++ b/arch/arm/boot/dts/r8a7790-lager-reference.dts
@@ -43,3 +43,36 @@
};
};
};
+
+&i2c3 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3_pins>;
+
+ vdd_dvfs: da9210@68 {
+ compatible = "diasemi,da9210";
+ reg = <0x68>;
+
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+};
+
+&cpu0 {
+ cpu0-supply = <&vdd_dvfs>;
+ operating-points = <
+ /* kHz uV - OPs unknown yet */
+ 1300000 1000000
+ 1000000 900000
+ >;
+ voltage-tolerance = <1>; /* 1% */
+};
+
+&pfc {
+ i2c3_pins: i2c3 {
+ renesas,groups = "i2c3";
+ renesas,function = "i2c3";
+ };
+};
diff --git a/arch/arm/mach-shmobile/board-lager-reference.c b/arch/arm/mach-shmobile/board-lager-reference.c
index 1a1a4a8..2bc8bae 100644
--- a/arch/arm/mach-shmobile/board-lager-reference.c
+++ b/arch/arm/mach-shmobile/board-lager-reference.c
@@ -20,6 +20,7 @@
#include <linux/init.h>
#include <linux/of_platform.h>
+#include <linux/platform_device.h>
#include <mach/r8a7790.h>
#include <asm/mach/arch.h>
@@ -29,7 +30,8 @@ static void __init lager_add_standard_devices(void)
r8a7790_clock_init();
r8a7790_add_dt_devices();
- of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+ platform_device_register_simple("cpufreq-cpu0", -1, NULL, 0);
}
static const char *lager_boards_compat_dt[] __initdata = {
--
1.7.2.5
There are four I2C interfaces on r8a7790, each of them can be connected to
one of the two respective I2C controllers, e.g. interface #0 can be
configured to work with I2C0 or with IIC0. Additionally some of those
interfaces can also use one of several pin sets. Interface #3 is special,
because it can be used in automatic mode for DVFS. It only has one set
of pins available and those pins cannot be used for anything else, they
also lack the GPIO function.
This patch uses the sh-pfc ability to configure pins, not associated with
GPIOs and adds support for I2C3 to the r8a7790 PFC set up.
Signed-off-by: Guennadi Liakhovetski <[email protected]>
---
v2: s/16/31/ in pin number calculation, thanks to Laurent for pointing out.
drivers/pinctrl/sh-pfc/pfc-r8a7790.c | 28 ++++++++++++++++++++++++++++
1 files changed, 28 insertions(+), 0 deletions(-)
diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7790.c b/drivers/pinctrl/sh-pfc/pfc-r8a7790.c
index 5c2657b..72786fc 100644
--- a/drivers/pinctrl/sh-pfc/pfc-r8a7790.c
+++ b/drivers/pinctrl/sh-pfc/pfc-r8a7790.c
@@ -781,6 +781,8 @@ enum {
ADICS_SAMP_MARK, DU2_CDE_MARK, QPOLB_MARK, SCIFA2_RXD_B_MARK,
USB1_PWEN_MARK, AUDIO_CLKOUT_D_MARK, USB1_OVC_MARK,
TCLK1_B_MARK,
+
+ I2C3_SCL_MARK, I2C3_SDA_MARK,
PINMUX_MARK_END,
};
@@ -1719,10 +1721,22 @@ static const u16 pinmux_data[] = {
PINMUX_IPSR_DATA(IP16_6, AUDIO_CLKOUT_D),
PINMUX_IPSR_DATA(IP16_7, USB1_OVC),
PINMUX_IPSR_MODSEL_DATA(IP16_7, TCLK1_B, SEL_TMU1_1),
+
+ PINMUX_DATA(I2C3_SCL_MARK, FN_SEL_IICDVFS_1),
+ PINMUX_DATA(I2C3_SDA_MARK, FN_SEL_IICDVFS_1),
};
+/* R8A7790 has 6 banks with 32 GPIOs in each = 192 GPIOs */
+#define ROW_GROUP_A(r) ('Z' - 'A' + 1 + (r))
+#define PIN_NUMBER(r, c) (((r) - 'A') * 31 + (c) + 200)
+#define PIN_A_NUMBER(r, c) PIN_NUMBER(ROW_GROUP_A(r), c)
+
static struct sh_pfc_pin pinmux_pins[] = {
PINMUX_GPIO_GP_ALL(),
+
+ /* Pins not associated with a GPIO port */
+ SH_PFC_PIN_NAMED(ROW_GROUP_A('J'), 15, AJ15),
+ SH_PFC_PIN_NAMED(ROW_GROUP_A('H'), 15, AH15),
};
/* - DU RGB ----------------------------------------------------------------- */
@@ -2048,6 +2062,14 @@ static const unsigned int i2c2_e_pins[] = {
static const unsigned int i2c2_e_mux[] = {
I2C2_SCL_E_MARK, I2C2_SDA_E_MARK,
};
+/* - I2C3 ------------------------------------------------------------------- */
+static const unsigned int i2c3_pins[] = {
+ /* SCL, SDA */
+ PIN_A_NUMBER('J', 15), PIN_A_NUMBER('H', 15),
+};
+static const unsigned int i2c3_mux[] = {
+ I2C3_SCL_MARK, I2C3_SDA_MARK,
+};
/* - INTC ------------------------------------------------------------------- */
static const unsigned int intc_irq0_pins[] = {
/* IRQ */
@@ -3113,6 +3135,7 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
SH_PFC_PIN_GROUP(i2c2_c),
SH_PFC_PIN_GROUP(i2c2_d),
SH_PFC_PIN_GROUP(i2c2_e),
+ SH_PFC_PIN_GROUP(i2c3),
SH_PFC_PIN_GROUP(intc_irq0),
SH_PFC_PIN_GROUP(intc_irq1),
SH_PFC_PIN_GROUP(intc_irq2),
@@ -3323,6 +3346,10 @@ static const char * const i2c2_groups[] = {
"i2c2_e",
};
+static const char * const i2c3_groups[] = {
+ "i2c3",
+};
+
static const char * const intc_groups[] = {
"intc_irq0",
"intc_irq1",
@@ -3551,6 +3578,7 @@ static const struct sh_pfc_function pinmux_functions[] = {
SH_PFC_FUNCTION(hscif1),
SH_PFC_FUNCTION(i2c1),
SH_PFC_FUNCTION(i2c2),
+ SH_PFC_FUNCTION(i2c3),
SH_PFC_FUNCTION(intc),
SH_PFC_FUNCTION(mmc0),
SH_PFC_FUNCTION(mmc1),
--
1.7.2.5
This patch adds clock definitions for the 4 I2C interfaces on r8a7790 and
clock aliases, suitable for the DT mode.
Signed-off-by: Guennadi Liakhovetski <[email protected]>
---
v2: part one of former [PATCH 2/4]
arch/arm/mach-shmobile/clock-r8a7790.c | 10 ++++++++++
1 files changed, 10 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-shmobile/clock-r8a7790.c b/arch/arm/mach-shmobile/clock-r8a7790.c
index af088c0..a64f965 100644
--- a/arch/arm/mach-shmobile/clock-r8a7790.c
+++ b/arch/arm/mach-shmobile/clock-r8a7790.c
@@ -52,6 +52,7 @@
#define SMSTPCR5 0xe6150144
#define SMSTPCR7 0xe615014c
#define SMSTPCR8 0xe6150990
+#define SMSTPCR9 0xe6150994
#define SDCKCR 0xE6150074
#define SD2CKCR 0xE6150078
@@ -181,6 +182,7 @@ static struct clk div6_clks[DIV6_NR] = {
/* MSTP */
enum {
+ MSTP931, MSTP930, MSTP929, MSTP928,
MSTP813,
MSTP726, MSTP725, MSTP724, MSTP723, MSTP722, MSTP721, MSTP720,
MSTP717, MSTP716,
@@ -192,6 +194,10 @@ enum {
};
static struct clk mstp_clks[MSTP_NR] = {
+ [MSTP931] = SH_CLK_MSTP32(&hp_clk, SMSTPCR9, 31, 0), /* I2C0 */
+ [MSTP930] = SH_CLK_MSTP32(&hp_clk, SMSTPCR9, 30, 0), /* I2C1 */
+ [MSTP929] = SH_CLK_MSTP32(&hp_clk, SMSTPCR9, 29, 0), /* I2C2 */
+ [MSTP928] = SH_CLK_MSTP32(&hp_clk, SMSTPCR9, 28, 0), /* I2C3 */
[MSTP813] = SH_CLK_MSTP32(&p_clk, SMSTPCR8, 13, 0), /* Ether */
[MSTP726] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 26, 0), /* LVDS0 */
[MSTP725] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 25, 0), /* LVDS1 */
@@ -271,6 +277,10 @@ static struct clk_lookup lookups[] = {
CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP720]),
CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP717]),
CLKDEV_DEV_ID("sh-sci.9", &mstp_clks[MSTP716]),
+ CLKDEV_DEV_ID("e6508000.i2c", &mstp_clks[MSTP931]),
+ CLKDEV_DEV_ID("e6518000.i2c", &mstp_clks[MSTP930]),
+ CLKDEV_DEV_ID("e6530000.i2c", &mstp_clks[MSTP929]),
+ CLKDEV_DEV_ID("e6540000.i2c", &mstp_clks[MSTP928]),
CLKDEV_DEV_ID("r8a7790-ether", &mstp_clks[MSTP813]),
CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]),
CLKDEV_DEV_ID("ee200000.mmcif", &mstp_clks[MSTP315]),
--
1.7.2.5
Add DT nodes for the four I2C interfacces on r8a7790.
Signed-off-by: Guennadi Liakhovetski <[email protected]>
---
v2: part two of former [PATCH 2/4], set i2c bus status to "disabled" by
default.
arch/arm/boot/dts/r8a7790.dtsi | 40 ++++++++++++++++++++++++++++++++++++++++
1 files changed, 40 insertions(+), 0 deletions(-)
diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi
index 28fc18c..ee845fa 100644
--- a/arch/arm/boot/dts/r8a7790.dtsi
+++ b/arch/arm/boot/dts/r8a7790.dtsi
@@ -176,6 +176,46 @@
interrupts = <0 0 4>, <0 1 4>, <0 2 4>, <0 3 4>;
};
+ i2c0: i2c@e6508000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a7790";
+ reg = <0 0xe6508000 0 0x40>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 287 0x4>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@e6518000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a7790";
+ reg = <0 0xe6518000 0 0x40>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 288 0x4>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@e6530000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a7790";
+ reg = <0 0xe6530000 0 0x40>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 286 0x4>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@e6540000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a7790";
+ reg = <0 0xe6540000 0 0x40>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 290 0x4>;
+ status = "disabled";
+ };
+
mmcif0: mmcif@ee200000 {
compatible = "renesas,sh-mmcif";
reg = <0 0xee200000 0 0x80>;
--
1.7.2.5
Add support for the Z clock on r8a7790, driving the four SoC's CA15 cores,
and its parent - PLL0. This is required for CPUFreq support on this SoC.
Signed-off-by: Guennadi Liakhovetski <[email protected]>
---
v2: changed clock alias to "cpu0" instead of deprecated "cpufreq-cpu0" to
comply with changes, introduced in patches from Sudeep KarkadaNagesha
cpufreq: cpufreq-cpu0: assign cpu_dev correctly to cpu0 device
ARM: shmobile: change dev_id to cpu0 while registering cpu clock
arch/arm/mach-shmobile/Kconfig | 2 +
arch/arm/mach-shmobile/clock-r8a7790.c | 150 ++++++++++++++++++++++++++++++++
2 files changed, 152 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
index eda2857..7f08bca 100644
--- a/arch/arm/mach-shmobile/Kconfig
+++ b/arch/arm/mach-shmobile/Kconfig
@@ -100,6 +100,8 @@ config ARCH_R8A7790
select CPU_V7
select SH_CLK_CPG
select RENESAS_IRQC
+ select ARCH_HAS_CPUFREQ
+ select ARCH_HAS_OPP
config ARCH_R8A7791
bool "R-Car M2 (R8A77910)"
diff --git a/arch/arm/mach-shmobile/clock-r8a7790.c b/arch/arm/mach-shmobile/clock-r8a7790.c
index a64f965..062d997 100644
--- a/arch/arm/mach-shmobile/clock-r8a7790.c
+++ b/arch/arm/mach-shmobile/clock-r8a7790.c
@@ -54,9 +54,12 @@
#define SMSTPCR8 0xe6150990
#define SMSTPCR9 0xe6150994
+#define FRQCRB 0xE6150004
#define SDCKCR 0xE6150074
#define SD2CKCR 0xE6150078
#define SD3CKCR 0xE615007C
+#define FRQCRC 0xE61500E0
+#define PLLECR 0xE61500D0
#define MMC0CKCR 0xE6150240
#define MMC1CKCR 0xE6150244
#define SSPCKCR 0xE6150248
@@ -85,6 +88,7 @@ static struct clk main_clk = {
* clock ratio of these clock will be updated
* on r8a7790_clock_init()
*/
+SH_FIXED_RATIO_CLK_SET(pll0_clk, main_clk, 1, 1);
SH_FIXED_RATIO_CLK_SET(pll1_clk, main_clk, 1, 1);
SH_FIXED_RATIO_CLK_SET(pll3_clk, main_clk, 1, 1);
SH_FIXED_RATIO_CLK_SET(lb_clk, pll1_clk, 1, 1);
@@ -113,15 +117,155 @@ SH_FIXED_RATIO_CLK_SET(zb3d2_clk, pll3_clk, 1, 8);
SH_FIXED_RATIO_CLK_SET(ddr_clk, pll3_clk, 1, 8);
SH_FIXED_RATIO_CLK_SET(mp_clk, pll1_div2_clk, 1, 15);
+/* Locking not needed yet, only one clock is using FRQCR[BC] divisors so far */
+static atomic_t frqcr_lock;
+#define CPG_MAP(o) ((o) - CPG_BASE + cpg_mapping.base)
+
+/* Several clocks need to access FRQCRB, have to lock */
+static bool frqcr_kick_check(struct clk *clk)
+{
+ return !(ioread32(CPG_MAP(FRQCRB)) & BIT(31));
+}
+
+static int frqcr_kick_do(struct clk *clk)
+{
+ int i;
+
+ /* set KICK bit in FRQCRB to update hardware setting, check success */
+ iowrite32(ioread32(CPG_MAP(FRQCRB)) | BIT(31), CPG_MAP(FRQCRB));
+ for (i = 1000; i; i--)
+ if (ioread32(CPG_MAP(FRQCRB)) & BIT(31))
+ cpu_relax();
+ else
+ return 0;
+
+ return -ETIMEDOUT;
+}
+
+static int zclk_set_rate(struct clk *clk, unsigned long rate)
+{
+ void __iomem *frqcrc;
+ int ret;
+ unsigned long step, p_rate;
+ u32 val;
+
+ if (!clk->parent || !__clk_get(clk->parent))
+ return -ENODEV;
+
+ if (!atomic_inc_and_test(&frqcr_lock) || !frqcr_kick_check(clk)) {
+ ret = -EBUSY;
+ goto done;
+ }
+
+ /*
+ * Users are supposed to first call clk_set_rate() only with
+ * clk_round_rate() results. So, we don't fix wrong rates here, but
+ * guard against them anyway
+ */
+
+ p_rate = clk_get_rate(clk->parent);
+ if (rate == p_rate) {
+ val = 0;
+ } else {
+ step = DIV_ROUND_CLOSEST(p_rate, 32);
+
+ if (rate > p_rate || rate < step) {
+ ret = -EINVAL;
+ goto done;
+ }
+
+ val = 32 - rate / step;
+ }
+
+ frqcrc = clk->mapped_reg + (FRQCRC - (u32)clk->enable_reg);
+
+ iowrite32((ioread32(frqcrc) & ~(clk->div_mask << clk->enable_bit)) |
+ (val << clk->enable_bit), frqcrc);
+
+ ret = frqcr_kick_do(clk);
+
+done:
+ atomic_dec(&frqcr_lock);
+ __clk_put(clk->parent);
+ return ret;
+}
+
+static long zclk_round_rate(struct clk *clk, unsigned long rate)
+{
+ /*
+ * theoretical rate = parent rate * multiplier / 32,
+ * where 1 <= multiplier <= 32. Therefore we should do
+ * multiplier = rate * 32 / parent rate
+ * rounded rate = parent rate * multiplier / 32.
+ * However, multiplication before division won't fit in 32 bits, so
+ * we sacrifice some precision by first dividing and then multiplying.
+ * To find the nearest divisor we calculate both and pick up the best
+ * one. This avoids 64-bit arithmetics.
+ */
+ unsigned long step, mul_min, mul_max, rate_min, rate_max;
+
+ rate_max = clk_get_rate(clk->parent);
+
+ /* output freq <= parent */
+ if (rate >= rate_max)
+ return rate_max;
+
+ step = DIV_ROUND_CLOSEST(rate_max, 32);
+ /* output freq >= parent / 32 */
+ if (step >= rate)
+ return step;
+
+ mul_min = rate / step;
+ mul_max = DIV_ROUND_UP(rate, step);
+ rate_min = step * mul_min;
+ if (mul_max == mul_min)
+ return rate_min;
+
+ rate_max = step * mul_max;
+
+ if (rate_max - rate < rate - rate_min)
+ return rate_max;
+
+ return rate_min;
+}
+
+static unsigned long zclk_recalc(struct clk *clk)
+{
+ void __iomem *frqcrc = FRQCRC - (u32)clk->enable_reg + clk->mapped_reg;
+ unsigned int max = clk->div_mask + 1;
+ unsigned long val = ((ioread32(frqcrc) >> clk->enable_bit) &
+ clk->div_mask);
+
+ return DIV_ROUND_CLOSEST(clk_get_rate(clk->parent), max) *
+ (max - val);
+}
+
+static struct sh_clk_ops zclk_ops = {
+ .recalc = zclk_recalc,
+ .set_rate = zclk_set_rate,
+ .round_rate = zclk_round_rate,
+};
+
+static struct clk z_clk = {
+ .parent = &pll0_clk,
+ .div_mask = 0x1f,
+ .enable_bit = 8,
+ /* We'll need to access FRQCRB and FRQCRC */
+ .enable_reg = (void __iomem *)FRQCRB,
+ .ops = &zclk_ops,
+};
+
static struct clk *main_clks[] = {
&extal_clk,
&extal_div2_clk,
&main_clk,
+ &pll0_clk,
&pll1_clk,
&pll1_div2_clk,
&pll3_clk,
&lb_clk,
&qspi_clk,
+ &z_clk,
&zg_clk,
&zx_clk,
&zs_clk,
@@ -254,6 +398,9 @@ static struct clk_lookup lookups[] = {
CLKDEV_CON_ID("qspi", &qspi_clk),
CLKDEV_CON_ID("cp", &cp_clk),
+ /* CPU clock */
+ CLKDEV_DEV_ID("cpu0", &z_clk),
+
/* DIV4 */
CLKDEV_CON_ID("sdh", &div4_clks[DIV4_SDH]),
@@ -301,6 +448,7 @@ static struct clk_lookup lookups[] = {
#define R8A7790_CLOCK_ROOT(e, m, p0, p1, p30, p31) \
extal_clk.rate = e * 1000 * 1000; \
main_clk.parent = m; \
+ SH_CLK_SET_RATIO(&pll0_clk_ratio, p0 / 2, 1); \
SH_CLK_SET_RATIO(&pll1_clk_ratio, p1 / 2, 1); \
if (mode & MD(19)) \
SH_CLK_SET_RATIO(&pll3_clk_ratio, p31, 1); \
@@ -313,6 +461,8 @@ void __init r8a7790_clock_init(void)
u32 mode = rcar_gen2_read_mode_pins();
int k, ret = 0;
+ atomic_set(&frqcr_lock, -1);
+
switch (mode & (MD(14) | MD(13))) {
case 0:
R8A7790_CLOCK_ROOT(15, &extal_clk, 172, 208, 106, 88);
--
1.7.2.5
Hello.
On 09/26/2013 09:21 PM, Guennadi Liakhovetski wrote:
> The Lager board uses a DA9210 voltage regulator to supply DVFS power to the
> CA15 cores on the r8a7790 SoC. This patch adds CPUFreq support for that
> board using the cpufreq-cpu0 driver.
> Signed-off-by: Guennadi Liakhovetski <[email protected]>
> ---
> v2: added 'status = "okay";' to the i2c bus
> arch/arm/boot/dts/r8a7790-lager-reference.dts | 33 ++++++++++++++++++++++++
> arch/arm/mach-shmobile/board-lager-reference.c | 4 ++-
> 2 files changed, 36 insertions(+), 1 deletions(-)
> diff --git a/arch/arm/boot/dts/r8a7790-lager-reference.dts b/arch/arm/boot/dts/r8a7790-lager-reference.dts
> index c462ef1..1ce0a97 100644
> --- a/arch/arm/boot/dts/r8a7790-lager-reference.dts
> +++ b/arch/arm/boot/dts/r8a7790-lager-reference.dts
> @@ -43,3 +43,36 @@
> };
> };
> };
> +
> +&i2c3 {
> + status = "okay";
> + pinctrl-names = "default";
> + pinctrl-0 = <&i2c3_pins>;
> +
> + vdd_dvfs: da9210@68 {
ePAPR spec [1] says: "The name of a node should be somewhat generic,
reflecting the function of the device and not its precise programming model."
So I suggest "regulator" instead of "da9210".
> + compatible = "diasemi,da9210";
> + reg = <0x68>;
> +
> + regulator-min-microvolt = <900000>;
> + regulator-max-microvolt = <1000000>;
> + regulator-boot-on;
> + regulator-always-on;
> + };
> +};
[...]
> diff --git a/arch/arm/mach-shmobile/board-lager-reference.c b/arch/arm/mach-shmobile/board-lager-reference.c
> index 1a1a4a8..2bc8bae 100644
> --- a/arch/arm/mach-shmobile/board-lager-reference.c
> +++ b/arch/arm/mach-shmobile/board-lager-reference.c
[...]
> @@ -29,7 +30,8 @@ static void __init lager_add_standard_devices(void)
> r8a7790_clock_init();
>
> r8a7790_add_dt_devices();
> - of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
> + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
Hm, "drove-by" cleanup?
> + platform_device_register_simple("cpufreq-cpu0", -1, NULL, 0);
> }
>
> static const char *lager_boards_compat_dt[] __initdata = {
Shouldn't the patch be split into .dts and .c parts, I wonder?
[1] http://www.power.org/resources/downloads/Power_ePAPR_APPROVED_v1.0.pdf
WBR, Sergei
Hi Guennadi,
Thank you for the patch.
On Thursday 26 September 2013 19:21:00 Guennadi Liakhovetski wrote:
> The Lager board uses a DA9210 voltage regulator to supply DVFS power to the
> CA15 cores on the r8a7790 SoC. This patch adds CPUFreq support for that
> board using the cpufreq-cpu0 driver.
>
> Signed-off-by: Guennadi Liakhovetski <[email protected]>
> ---
>
> v2: added 'status = "okay";' to the i2c bus
>
> arch/arm/boot/dts/r8a7790-lager-reference.dts | 33 +++++++++++++++++++++
> arch/arm/mach-shmobile/board-lager-reference.c | 4 ++-
> 2 files changed, 36 insertions(+), 1 deletions(-)
>
> diff --git a/arch/arm/boot/dts/r8a7790-lager-reference.dts
> b/arch/arm/boot/dts/r8a7790-lager-reference.dts index c462ef1..1ce0a97
> 100644
> --- a/arch/arm/boot/dts/r8a7790-lager-reference.dts
> +++ b/arch/arm/boot/dts/r8a7790-lager-reference.dts
> @@ -43,3 +43,36 @@
> };
> };
> };
> +
> +&i2c3 {
> + status = "okay";
> + pinctrl-names = "default";
> + pinctrl-0 = <&i2c3_pins>;
> +
> + vdd_dvfs: da9210@68 {
> + compatible = "diasemi,da9210";
> + reg = <0x68>;
> +
> + regulator-min-microvolt = <900000>;
> + regulator-max-microvolt = <1000000>;
> + regulator-boot-on;
> + regulator-always-on;
> + };
> +};
> +
> +&cpu0 {
> + cpu0-supply = <&vdd_dvfs>;
> + operating-points = <
> + /* kHz uV - OPs unknown yet */
> + 1300000 1000000
> + 1000000 900000
> + >;
> + voltage-tolerance = <1>; /* 1% */
> +};
> +
> +&pfc {
> + i2c3_pins: i2c3 {
> + renesas,groups = "i2c3";
> + renesas,function = "i2c3";
> + };
> +};
> diff --git a/arch/arm/mach-shmobile/board-lager-reference.c
> b/arch/arm/mach-shmobile/board-lager-reference.c index 1a1a4a8..2bc8bae
> 100644
> --- a/arch/arm/mach-shmobile/board-lager-reference.c
> +++ b/arch/arm/mach-shmobile/board-lager-reference.c
> @@ -20,6 +20,7 @@
>
> #include <linux/init.h>
> #include <linux/of_platform.h>
> +#include <linux/platform_device.h>
> #include <mach/r8a7790.h>
> #include <asm/mach/arch.h>
>
> @@ -29,7 +30,8 @@ static void __init lager_add_standard_devices(void)
> r8a7790_clock_init();
>
> r8a7790_add_dt_devices();
> - of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
> + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
> + platform_device_register_simple("cpufreq-cpu0", -1, NULL, 0);
Out of curiosity, could you explain how this cpufreq-cpu0 platform device gets
associated with the cpu0 DT node ? The cpufreq-cpu0 driver requires a DT node
(its probe function returns -ENOENT if pdev->dev.of_node is NULL), and I don't
see how the of_node gets set as the platform device is registered through
board code. I might of course be missing something obvious :-)
> }
>
> static const char *lager_boards_compat_dt[] __initdata = {
--
Regards,
Laurent Pinchart
Hi Guennadi,
Thank you for the patch.
On Thursday 26 September 2013 19:20:56 Guennadi Liakhovetski wrote:
> There are four I2C interfaces on r8a7790, each of them can be connected to
> one of the two respective I2C controllers, e.g. interface #0 can be
> configured to work with I2C0 or with IIC0. Additionally some of those
> interfaces can also use one of several pin sets. Interface #3 is special,
> because it can be used in automatic mode for DVFS. It only has one set
> of pins available and those pins cannot be used for anything else, they
> also lack the GPIO function.
>
> This patch uses the sh-pfc ability to configure pins, not associated with
> GPIOs and adds support for I2C3 to the r8a7790 PFC set up.
>
> Signed-off-by: Guennadi Liakhovetski <[email protected]>
Acked-by: Laurent Pinchart <[email protected]>
I've taken the patch in my tree and sent an update to my previous pull request
for the pinctrl tree.
> ---
>
> v2: s/16/31/ in pin number calculation, thanks to Laurent for pointing out.
>
> drivers/pinctrl/sh-pfc/pfc-r8a7790.c | 28 ++++++++++++++++++++++++++++
> 1 files changed, 28 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7790.c
> b/drivers/pinctrl/sh-pfc/pfc-r8a7790.c index 5c2657b..72786fc 100644
> --- a/drivers/pinctrl/sh-pfc/pfc-r8a7790.c
> +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7790.c
> @@ -781,6 +781,8 @@ enum {
> ADICS_SAMP_MARK, DU2_CDE_MARK, QPOLB_MARK, SCIFA2_RXD_B_MARK,
> USB1_PWEN_MARK, AUDIO_CLKOUT_D_MARK, USB1_OVC_MARK,
> TCLK1_B_MARK,
> +
> + I2C3_SCL_MARK, I2C3_SDA_MARK,
> PINMUX_MARK_END,
> };
>
> @@ -1719,10 +1721,22 @@ static const u16 pinmux_data[] = {
> PINMUX_IPSR_DATA(IP16_6, AUDIO_CLKOUT_D),
> PINMUX_IPSR_DATA(IP16_7, USB1_OVC),
> PINMUX_IPSR_MODSEL_DATA(IP16_7, TCLK1_B, SEL_TMU1_1),
> +
> + PINMUX_DATA(I2C3_SCL_MARK, FN_SEL_IICDVFS_1),
> + PINMUX_DATA(I2C3_SDA_MARK, FN_SEL_IICDVFS_1),
> };
>
> +/* R8A7790 has 6 banks with 32 GPIOs in each = 192 GPIOs */
> +#define ROW_GROUP_A(r) ('Z' - 'A' + 1 + (r))
> +#define PIN_NUMBER(r, c) (((r) - 'A') * 31 + (c) + 200)
> +#define PIN_A_NUMBER(r, c) PIN_NUMBER(ROW_GROUP_A(r), c)
> +
> static struct sh_pfc_pin pinmux_pins[] = {
> PINMUX_GPIO_GP_ALL(),
> +
> + /* Pins not associated with a GPIO port */
> + SH_PFC_PIN_NAMED(ROW_GROUP_A('J'), 15, AJ15),
> + SH_PFC_PIN_NAMED(ROW_GROUP_A('H'), 15, AH15),
> };
>
> /* - DU RGB
> ----------------------------------------------------------------- */ @@
> -2048,6 +2062,14 @@ static const unsigned int i2c2_e_pins[] = { static
> const unsigned int i2c2_e_mux[] = {
> I2C2_SCL_E_MARK, I2C2_SDA_E_MARK,
> };
> +/* - I2C3
> ------------------------------------------------------------------- */
> +static const unsigned int i2c3_pins[] = {
> + /* SCL, SDA */
> + PIN_A_NUMBER('J', 15), PIN_A_NUMBER('H', 15),
> +};
> +static const unsigned int i2c3_mux[] = {
> + I2C3_SCL_MARK, I2C3_SDA_MARK,
> +};
> /* - INTC
> ------------------------------------------------------------------- */
> static const unsigned int intc_irq0_pins[] = {
> /* IRQ */
> @@ -3113,6 +3135,7 @@ static const struct sh_pfc_pin_group pinmux_groups[] =
> { SH_PFC_PIN_GROUP(i2c2_c),
> SH_PFC_PIN_GROUP(i2c2_d),
> SH_PFC_PIN_GROUP(i2c2_e),
> + SH_PFC_PIN_GROUP(i2c3),
> SH_PFC_PIN_GROUP(intc_irq0),
> SH_PFC_PIN_GROUP(intc_irq1),
> SH_PFC_PIN_GROUP(intc_irq2),
> @@ -3323,6 +3346,10 @@ static const char * const i2c2_groups[] = {
> "i2c2_e",
> };
>
> +static const char * const i2c3_groups[] = {
> + "i2c3",
> +};
> +
> static const char * const intc_groups[] = {
> "intc_irq0",
> "intc_irq1",
> @@ -3551,6 +3578,7 @@ static const struct sh_pfc_function pinmux_functions[]
> = { SH_PFC_FUNCTION(hscif1),
> SH_PFC_FUNCTION(i2c1),
> SH_PFC_FUNCTION(i2c2),
> + SH_PFC_FUNCTION(i2c3),
> SH_PFC_FUNCTION(intc),
> SH_PFC_FUNCTION(mmc0),
> SH_PFC_FUNCTION(mmc1),
--
Regards,
Laurent Pinchart
On Thu, Sep 26, 2013 at 07:20:58PM +0200, Guennadi Liakhovetski wrote:
> Add DT nodes for the four I2C interfacces on r8a7790.
>
> Signed-off-by: Guennadi Liakhovetski <[email protected]>
> ---
>
> v2: part two of former [PATCH 2/4], set i2c bus status to "disabled" by
> default.
Thanks, queued up for v3.13.
On Thu, Sep 26, 2013 at 07:20:57PM +0200, Guennadi Liakhovetski wrote:
> This patch adds clock definitions for the 4 I2C interfaces on r8a7790 and
> clock aliases, suitable for the DT mode.
>
> Signed-off-by: Guennadi Liakhovetski <[email protected]>
Thanks, queued up for v3.13.
Hi Laurent
On Fri, 27 Sep 2013, Laurent Pinchart wrote:
> Hi Guennadi,
>
> Thank you for the patch.
>
> On Thursday 26 September 2013 19:21:00 Guennadi Liakhovetski wrote:
> > The Lager board uses a DA9210 voltage regulator to supply DVFS power to the
> > CA15 cores on the r8a7790 SoC. This patch adds CPUFreq support for that
> > board using the cpufreq-cpu0 driver.
> >
> > Signed-off-by: Guennadi Liakhovetski <[email protected]>
> > ---
> >
> > v2: added 'status = "okay";' to the i2c bus
> >
> > arch/arm/boot/dts/r8a7790-lager-reference.dts | 33 +++++++++++++++++++++
> > arch/arm/mach-shmobile/board-lager-reference.c | 4 ++-
> > 2 files changed, 36 insertions(+), 1 deletions(-)
> >
> > diff --git a/arch/arm/boot/dts/r8a7790-lager-reference.dts
> > b/arch/arm/boot/dts/r8a7790-lager-reference.dts index c462ef1..1ce0a97
> > 100644
> > --- a/arch/arm/boot/dts/r8a7790-lager-reference.dts
> > +++ b/arch/arm/boot/dts/r8a7790-lager-reference.dts
> > @@ -43,3 +43,36 @@
> > };
> > };
> > };
> > +
> > +&i2c3 {
> > + status = "okay";
> > + pinctrl-names = "default";
> > + pinctrl-0 = <&i2c3_pins>;
> > +
> > + vdd_dvfs: da9210@68 {
> > + compatible = "diasemi,da9210";
> > + reg = <0x68>;
> > +
> > + regulator-min-microvolt = <900000>;
> > + regulator-max-microvolt = <1000000>;
> > + regulator-boot-on;
> > + regulator-always-on;
> > + };
> > +};
> > +
> > +&cpu0 {
> > + cpu0-supply = <&vdd_dvfs>;
> > + operating-points = <
> > + /* kHz uV - OPs unknown yet */
> > + 1300000 1000000
> > + 1000000 900000
> > + >;
> > + voltage-tolerance = <1>; /* 1% */
> > +};
> > +
> > +&pfc {
> > + i2c3_pins: i2c3 {
> > + renesas,groups = "i2c3";
> > + renesas,function = "i2c3";
> > + };
> > +};
> > diff --git a/arch/arm/mach-shmobile/board-lager-reference.c
> > b/arch/arm/mach-shmobile/board-lager-reference.c index 1a1a4a8..2bc8bae
> > 100644
> > --- a/arch/arm/mach-shmobile/board-lager-reference.c
> > +++ b/arch/arm/mach-shmobile/board-lager-reference.c
> > @@ -20,6 +20,7 @@
> >
> > #include <linux/init.h>
> > #include <linux/of_platform.h>
> > +#include <linux/platform_device.h>
> > #include <mach/r8a7790.h>
> > #include <asm/mach/arch.h>
> >
> > @@ -29,7 +30,8 @@ static void __init lager_add_standard_devices(void)
> > r8a7790_clock_init();
> >
> > r8a7790_add_dt_devices();
> > - of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
> > + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
> > + platform_device_register_simple("cpufreq-cpu0", -1, NULL, 0);
>
> Out of curiosity, could you explain how this cpufreq-cpu0 platform device gets
> associated with the cpu0 DT node ?
I can try, yes.
> The cpufreq-cpu0 driver requires a DT node
> (its probe function returns -ENOENT if pdev->dev.of_node is NULL), and I don't
> see how the of_node gets set as the platform device is registered through
> board code. I might of course be missing something obvious :-)
I think you can just follow this threads:
http://thread.gmane.org/gmane.linux.kernel.cpufreq/11427/focus=1547510
http://thread.gmane.org/gmane.linux.kernel.cpufreq/12408
and there's also a comment in another my patch from yesterday from the
same thread:
http://marc.info/?l=linux-sh&m=138021613314913&w=2
So, in short, you seem to be looking at a buggy driver state, yes. A fix
is on its way.
Thanks
Guennadi
> > }
> >
> > static const char *lager_boards_compat_dt[] __initdata = {
> --
> Regards,
>
> Laurent Pinchart
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/
Hi Sergei
On Thu, 26 Sep 2013, Sergei Shtylyov wrote:
> Hello.
>
> On 09/26/2013 09:21 PM, Guennadi Liakhovetski wrote:
>
> > The Lager board uses a DA9210 voltage regulator to supply DVFS power to the
> > CA15 cores on the r8a7790 SoC. This patch adds CPUFreq support for that
> > board using the cpufreq-cpu0 driver.
>
> > Signed-off-by: Guennadi Liakhovetski <[email protected]>
> > ---
>
> > v2: added 'status = "okay";' to the i2c bus
>
> > arch/arm/boot/dts/r8a7790-lager-reference.dts | 33
> > ++++++++++++++++++++++++
> > arch/arm/mach-shmobile/board-lager-reference.c | 4 ++-
> > 2 files changed, 36 insertions(+), 1 deletions(-)
>
> > diff --git a/arch/arm/boot/dts/r8a7790-lager-reference.dts
> > b/arch/arm/boot/dts/r8a7790-lager-reference.dts
> > index c462ef1..1ce0a97 100644
> > --- a/arch/arm/boot/dts/r8a7790-lager-reference.dts
> > +++ b/arch/arm/boot/dts/r8a7790-lager-reference.dts
> > @@ -43,3 +43,36 @@
> > };
> > };
> > };
> > +
> > +&i2c3 {
> > + status = "okay";
> > + pinctrl-names = "default";
> > + pinctrl-0 = <&i2c3_pins>;
> > +
> > + vdd_dvfs: da9210@68 {
>
> ePAPR spec [1] says: "The name of a node should be somewhat generic,
> reflecting the function of the device and not its precise programming model."
Sure, but I think it is common in Linux .dts files for I2C devices to use
"<model>@<i2c addr>" as a name.
> So I suggest "regulator" instead of "da9210".
>
> > + compatible = "diasemi,da9210";
> > + reg = <0x68>;
> > +
> > + regulator-min-microvolt = <900000>;
> > + regulator-max-microvolt = <1000000>;
> > + regulator-boot-on;
> > + regulator-always-on;
> > + };
> > +};
> [...]
> > diff --git a/arch/arm/mach-shmobile/board-lager-reference.c
> > b/arch/arm/mach-shmobile/board-lager-reference.c
> > index 1a1a4a8..2bc8bae 100644
> > --- a/arch/arm/mach-shmobile/board-lager-reference.c
> > +++ b/arch/arm/mach-shmobile/board-lager-reference.c
> [...]
> > @@ -29,7 +30,8 @@ static void __init lager_add_standard_devices(void)
> > r8a7790_clock_init();
> >
> > r8a7790_add_dt_devices();
> > - of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
> > + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
>
> Hm, "drove-by" cleanup?
This should be avoided in general, but this kind of stuff really doesn't
deserve neither a separate patch nor a mention. Don't waste your precious
brain cycles.
> > + platform_device_register_simple("cpufreq-cpu0", -1, NULL, 0);
> > }
> >
> > static const char *lager_boards_compat_dt[] __initdata = {
>
> Shouldn't the patch be split into .dts and .c parts, I wonder?
Simon didn't complain, but perhaps it should, yes. I think I'll resubmit
this as 2 patches with no changes.
Thanks
Guennadi
> [1] http://www.power.org/resources/downloads/Power_ePAPR_APPROVED_v1.0.pdf
>
> WBR, Sergei
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/
Hi Simon,
Just a quick check of the status of this patch series:
On Thu, 26 Sep 2013, Guennadi Liakhovetski wrote:
> On Lager a da9210 regulator is used to supply DVFS power to the SoC. This
> patch series adds I2C and Z-clock support on r8a7790 and CPUFreq support
> for the Lager board. Please note, that patch 4/4 is an RFC as explained
> inline.
>
> Developed on top of today's
>
> git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git devel
>
> plus i2c-rcar patches from my earlier patch series
>
> [PATCH v2 0/5] i2c: rcar: Device Tree support and clock improvements
>
> and the "sh-pfc: r8a7790: Add I2C pin groups and functions" patch from
> Ulrich Hecht.
>
> All changes since v1 are noted in respective patches. They all are trivial,
> still as soon as test hardware is available, it would be good to run-time
> test this version too.
>
> Cc: Guennadi Liakhovetski <[email protected]>
>
> Guennadi Liakhovetski (5):
> pinctrl: sh-pfc: r8a7790: add pin definitions for the I2C3 interface
Laurent has taken this one.
> ARM: shmobile: r8a7790: add I2C clocks and aliases for the DT mode
> ARM: shmobile: r8a7790: add I2C DT nodes
You've applied the above two too, thanks.
> ARM: shmobile: r8a7790: add CPUFreq clock support
Do I see it right, that you're waiting for a review for the above one?
> ARM: shmobile: lager: (DEVEL) add CPUFreq support
Once a review of #4/5 is posted, I can split the above patch into two to
separate shmobile and DT parts, as requested by Sergei. Is that about what
you're expecting too?
Thanks
Guennadi
> arch/arm/boot/dts/r8a7790-lager-reference.dts | 33 +++++
> arch/arm/boot/dts/r8a7790.dtsi | 40 ++++++
> arch/arm/mach-shmobile/Kconfig | 2 +
> arch/arm/mach-shmobile/board-lager-reference.c | 4 +-
> arch/arm/mach-shmobile/clock-r8a7790.c | 160 ++++++++++++++++++++++++
> drivers/pinctrl/sh-pfc/pfc-r8a7790.c | 28 ++++
> 6 files changed, 266 insertions(+), 1 deletions(-)
>
> --
> 1.7.2.5
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/
Hi Guennadi,
On Mon, Sep 30, 2013 at 05:25:42PM +0200, Guennadi Liakhovetski wrote:
> Hi Simon,
>
> Just a quick check of the status of this patch series:
>
> On Thu, 26 Sep 2013, Guennadi Liakhovetski wrote:
>
> > On Lager a da9210 regulator is used to supply DVFS power to the SoC. This
> > patch series adds I2C and Z-clock support on r8a7790 and CPUFreq support
> > for the Lager board. Please note, that patch 4/4 is an RFC as explained
> > inline.
> >
> > Developed on top of today's
> >
> > git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git devel
> >
> > plus i2c-rcar patches from my earlier patch series
> >
> > [PATCH v2 0/5] i2c: rcar: Device Tree support and clock improvements
> >
> > and the "sh-pfc: r8a7790: Add I2C pin groups and functions" patch from
> > Ulrich Hecht.
> >
> > All changes since v1 are noted in respective patches. They all are trivial,
> > still as soon as test hardware is available, it would be good to run-time
> > test this version too.
> >
> > Cc: Guennadi Liakhovetski <[email protected]>
> >
> > Guennadi Liakhovetski (5):
> > pinctrl: sh-pfc: r8a7790: add pin definitions for the I2C3 interface
>
> Laurent has taken this one.
>
> > ARM: shmobile: r8a7790: add I2C clocks and aliases for the DT mode
> > ARM: shmobile: r8a7790: add I2C DT nodes
>
> You've applied the above two too, thanks.
>
> > ARM: shmobile: r8a7790: add CPUFreq clock support
>
> Do I see it right, that you're waiting for a review for the above one?
Yes, sorry for not being clearer.
I would like a review of this.
> > ARM: shmobile: lager: (DEVEL) add CPUFreq support
>
> Once a review of #4/5 is posted, I can split the above patch into two to
> separate shmobile and DT parts, as requested by Sergei. Is that about what
> you're expecting too?
Again, sorry for not being clearer. Yes, I agree with Sergei.
I would like the patch split into a DT patch and a board patch.