summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorStefano Babic <sbabic@denx.de>2018-09-18 16:53:34 +0200
committerStefano Babic <sbabic@denx.de>2018-09-18 16:53:55 +0200
commit0eee446ee811ea3ebbade82cb1d19558736e5603 (patch)
treeec086d3b613610ff7c2b13cc092b38bc36d45c1f /arch
parentd27748b7cb3b7f447ef7d7d7c6cfe91852cd14e6 (diff)
parentb57f1895b669e3fbdca486e7c40dfea00f22bb93 (diff)
downloadu-boot-0eee446ee811ea3ebbade82cb1d19558736e5603.tar.gz
Merge branch 'master' of git://git.denx.de/u-boot into master
Signed-off-by: Stefano Babic <sbabic@denx.de>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/dts/da850-evm-u-boot.dtsi11
-rw-r--r--arch/arm/dts/da850-evm.dts308
-rw-r--r--arch/arm/mach-omap2/boot-common.c2
-rw-r--r--arch/arm/mach-socfpga/include/mach/sdram_s10.h2
-rw-r--r--arch/m68k/cpu/mcf5445x/cpu_init.c10
-rw-r--r--arch/m68k/cpu/mcf5445x/speed.c2
-rw-r--r--arch/m68k/include/asm/byteorder.h34
-rw-r--r--arch/m68k/include/asm/global_data.h3
-rw-r--r--arch/m68k/include/asm/immap.h2
-rw-r--r--arch/sh/include/asm/config.h9
-rw-r--r--arch/sh/include/asm/cpu_sh7724.h3
-rw-r--r--arch/sh/lib/time.c45
-rw-r--r--arch/x86/cpu/tangier/Makefile2
-rw-r--r--arch/x86/cpu/tangier/pinmux.c194
-rw-r--r--arch/x86/dts/edison.dts22
-rw-r--r--arch/x86/include/asm/arch-tangier/acpi/southcluster.asl10
-rw-r--r--arch/x86/include/asm/scu.h4
-rw-r--r--arch/x86/lib/scu.c62
18 files changed, 525 insertions, 200 deletions
diff --git a/arch/arm/dts/da850-evm-u-boot.dtsi b/arch/arm/dts/da850-evm-u-boot.dtsi
index b3546e792a..ab1de77954 100644
--- a/arch/arm/dts/da850-evm-u-boot.dtsi
+++ b/arch/arm/dts/da850-evm-u-boot.dtsi
@@ -6,17 +6,6 @@
* Copyright (C) Adam Ford
*/
-/ {
- chosen {
- stdout-path = &serial2;
- };
-
- aliases {
- i2c0 = &i2c0;
- spi0 = &spi1;
- };
-};
-
&flash {
compatible = "m25p64", "spi-flash";
};
diff --git a/arch/arm/dts/da850-evm.dts b/arch/arm/dts/da850-evm.dts
index 67e72bc72e..0e82bb988f 100644
--- a/arch/arm/dts/da850-evm.dts
+++ b/arch/arm/dts/da850-evm.dts
@@ -15,143 +15,18 @@
compatible = "ti,da850-evm", "ti,da850";
model = "DA850/AM1808/OMAP-L138 EVM";
- soc@1c00000 {
- pmx_core: pinmux@14120 {
- status = "okay";
-
- mcasp0_pins: pinmux_mcasp0_pins {
- pinctrl-single,bits = <
- /*
- * AHCLKX, ACLKX, AFSX, AHCLKR, ACLKR,
- * AFSR, AMUTE
- */
- 0x00 0x11111111 0xffffffff
- /* AXR11, AXR12 */
- 0x04 0x00011000 0x000ff000
- >;
- };
- nand_pins: nand_pins {
- pinctrl-single,bits = <
- /* EMA_WAIT[0], EMA_OE, EMA_WE, EMA_CS[4], EMA_CS[3] */
- 0x1c 0x10110110 0xf0ff0ff0
- /*
- * EMA_D[0], EMA_D[1], EMA_D[2],
- * EMA_D[3], EMA_D[4], EMA_D[5],
- * EMA_D[6], EMA_D[7]
- */
- 0x24 0x11111111 0xffffffff
- /* EMA_A[1], EMA_A[2] */
- 0x30 0x01100000 0x0ff00000
- >;
- };
- };
- serial0: serial@42000 {
- status = "okay";
- };
- serial1: serial@10c000 {
- status = "okay";
- };
- serial2: serial@10d000 {
- status = "okay";
- };
- rtc0: rtc@23000 {
- status = "okay";
- };
- i2c0: i2c@22000 {
- status = "okay";
- clock-frequency = <100000>;
- pinctrl-names = "default";
- pinctrl-0 = <&i2c0_pins>;
-
- tps: tps@48 {
- reg = <0x48>;
- };
- tlv320aic3106: tlv320aic3106@18 {
- #sound-dai-cells = <0>;
- compatible = "ti,tlv320aic3106";
- reg = <0x18>;
- status = "okay";
-
- /* Regulators */
- IOVDD-supply = <&vdcdc2_reg>;
- /* Derived from VBAT: Baseboard 3.3V / 1.8V */
- AVDD-supply = <&vbat>;
- DRVDD-supply = <&vbat>;
- DVDD-supply = <&vbat>;
- };
- tca6416: gpio@20 {
- compatible = "ti,tca6416";
- reg = <0x20>;
- gpio-controller;
- #gpio-cells = <2>;
- };
- };
- wdt: wdt@21000 {
- status = "okay";
- };
- mmc0: mmc@40000 {
- max-frequency = <50000000>;
- bus-width = <4>;
- status = "okay";
- pinctrl-names = "default";
- pinctrl-0 = <&mmc0_pins>;
- };
- spi1: spi@30e000 {
- status = "okay";
- pinctrl-names = "default";
- pinctrl-0 = <&spi1_pins &spi1_cs0_pin>;
- flash: m25p80@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "m25p64";
- spi-max-frequency = <30000000>;
- m25p,fast-read;
- reg = <0>;
- partition@0 {
- label = "U-Boot-SPL";
- reg = <0x00000000 0x00010000>;
- read-only;
- };
- partition@1 {
- label = "U-Boot";
- reg = <0x00010000 0x00080000>;
- read-only;
- };
- partition@2 {
- label = "U-Boot-Env";
- reg = <0x00090000 0x00010000>;
- read-only;
- };
- partition@3 {
- label = "Kernel";
- reg = <0x000a0000 0x00280000>;
- };
- partition@4 {
- label = "Filesystem";
- reg = <0x00320000 0x00400000>;
- };
- partition@5 {
- label = "MAC-Address";
- reg = <0x007f0000 0x00010000>;
- read-only;
- };
- };
- };
- mdio: mdio@224000 {
- status = "okay";
- pinctrl-names = "default";
- pinctrl-0 = <&mdio_pins>;
- bus_freq = <2200000>;
- };
- eth0: ethernet@220000 {
- status = "okay";
- pinctrl-names = "default";
- pinctrl-0 = <&mii_pins>;
- };
- gpio: gpio@226000 {
- status = "okay";
- };
+ chosen {
+ stdout-path = &serial2;
+ };
+
+ aliases {
+ serial0 = &serial0;
+ serial1 = &serial1;
+ serial2 = &serial2;
+ ethernet0 = &eth0;
+ spi0 = &spi1;
};
+
vbat: fixedregulator0 {
compatible = "regulator-fixed";
regulator-name = "vbat";
@@ -188,6 +63,155 @@
};
};
+&pmx_core {
+ status = "okay";
+
+ mcasp0_pins: pinmux_mcasp0_pins {
+ pinctrl-single,bits = <
+ /*
+ * AHCLKX, ACLKX, AFSX, AHCLKR, ACLKR,
+ * AFSR, AMUTE
+ */
+ 0x00 0x11111111 0xffffffff
+ /* AXR11, AXR12 */
+ 0x04 0x00011000 0x000ff000
+ >;
+ };
+ nand_pins: nand_pins {
+ pinctrl-single,bits = <
+ /* EMA_WAIT[0], EMA_OE, EMA_WE, EMA_CS[4], EMA_CS[3] */
+ 0x1c 0x10110110 0xf0ff0ff0
+ /*
+ * EMA_D[0], EMA_D[1], EMA_D[2],
+ * EMA_D[3], EMA_D[4], EMA_D[5],
+ * EMA_D[6], EMA_D[7]
+ */
+ 0x24 0x11111111 0xffffffff
+ /* EMA_A[1], EMA_A[2] */
+ 0x30 0x01100000 0x0ff00000
+ >;
+ };
+};
+
+&serial0 {
+ status = "okay";
+};
+
+&serial1 {
+ status = "okay";
+};
+
+&serial2 {
+ status = "okay";
+};
+
+&rtc0 {
+ status = "okay";
+};
+
+&i2c0 {
+ status = "okay";
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+
+ tps: tps@48 {
+ reg = <0x48>;
+ };
+ tlv320aic3106: tlv320aic3106@18 {
+ #sound-dai-cells = <0>;
+ compatible = "ti,tlv320aic3106";
+ reg = <0x18>;
+ status = "okay";
+
+ /* Regulators */
+ IOVDD-supply = <&vdcdc2_reg>;
+ /* Derived from VBAT: Baseboard 3.3V / 1.8V */
+ AVDD-supply = <&vbat>;
+ DRVDD-supply = <&vbat>;
+ DVDD-supply = <&vbat>;
+ };
+ tca6416: gpio@20 {
+ compatible = "ti,tca6416";
+ reg = <0x20>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+};
+
+&wdt {
+ status = "okay";
+};
+
+&mmc0 {
+ max-frequency = <50000000>;
+ bus-width = <4>;
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins>;
+ cd-gpios = <&gpio 64 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio 65 GPIO_ACTIVE_HIGH>;
+};
+
+&spi1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi1_pins &spi1_cs0_pin>;
+ flash: m25p80@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "m25p64";
+ spi-max-frequency = <30000000>;
+ m25p,fast-read;
+ reg = <0>;
+ partition@0 {
+ label = "U-Boot-SPL";
+ reg = <0x00000000 0x00010000>;
+ read-only;
+ };
+ partition@1 {
+ label = "U-Boot";
+ reg = <0x00010000 0x00080000>;
+ read-only;
+ };
+ partition@2 {
+ label = "U-Boot-Env";
+ reg = <0x00090000 0x00010000>;
+ read-only;
+ };
+ partition@3 {
+ label = "Kernel";
+ reg = <0x000a0000 0x00280000>;
+ };
+ partition@4 {
+ label = "Filesystem";
+ reg = <0x00320000 0x00400000>;
+ };
+ partition@5 {
+ label = "MAC-Address";
+ reg = <0x007f0000 0x00010000>;
+ read-only;
+ };
+ };
+};
+
+&mdio {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mdio_pins>;
+ bus_freq = <2200000>;
+};
+
+&eth0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mii_pins>;
+};
+
+&gpio {
+ status = "okay";
+};
+
/include/ "tps6507x.dtsi"
&tps {
@@ -297,6 +321,18 @@
};
};
+&usb_phy {
+ status = "okay";
+};
+
+&usb0 {
+ status = "okay";
+};
+
+&usb1 {
+ status = "okay";
+};
+
&vpif {
pinctrl-names = "default";
pinctrl-0 = <&vpif_capture_pins>, <&vpif_display_pins>;
diff --git a/arch/arm/mach-omap2/boot-common.c b/arch/arm/mach-omap2/boot-common.c
index d4a1e2e42c..176d4f67cb 100644
--- a/arch/arm/mach-omap2/boot-common.c
+++ b/arch/arm/mach-omap2/boot-common.c
@@ -202,7 +202,7 @@ void spl_board_init(void)
#if defined(CONFIG_SPL_NAND_SUPPORT) || defined(CONFIG_SPL_ONENAND_SUPPORT)
gpmc_init();
#endif
-#ifdef CONFIG_SPL_I2C_SUPPORT
+#if defined(CONFIG_SPL_I2C_SUPPORT) && !defined(CONFIG_DM_I2C)
i2c_init(CONFIG_SYS_OMAP24_I2C_SPEED, CONFIG_SYS_OMAP24_I2C_SLAVE);
#endif
#if defined(CONFIG_AM33XX) && defined(CONFIG_SPL_MUSB_NEW_SUPPORT)
diff --git a/arch/arm/mach-socfpga/include/mach/sdram_s10.h b/arch/arm/mach-socfpga/include/mach/sdram_s10.h
index 91bfc0e5ec..ca68594445 100644
--- a/arch/arm/mach-socfpga/include/mach/sdram_s10.h
+++ b/arch/arm/mach-socfpga/include/mach/sdram_s10.h
@@ -7,7 +7,7 @@
#ifndef _SDRAM_S10_H_
#define _SDRAM_S10_H_
-unsigned long sdram_calculate_size(void);
+phys_size_t sdram_calculate_size(void);
int sdram_mmr_init_full(unsigned int sdr_phy_reg);
int sdram_calibration_full(void);
diff --git a/arch/m68k/cpu/mcf5445x/cpu_init.c b/arch/m68k/cpu/mcf5445x/cpu_init.c
index 0b86020204..7632d9262c 100644
--- a/arch/m68k/cpu/mcf5445x/cpu_init.c
+++ b/arch/m68k/cpu/mcf5445x/cpu_init.c
@@ -173,6 +173,15 @@ void cpu_init_f(void)
/* Lowest slew rate for UART0,1,2 */
out_8(&gpio->srcr_uart, 0x00);
+
+#ifdef CONFIG_FSL_ESDHC
+ /* eSDHC pin as faster speed */
+ out_8(&gpio->srcr_sdhc, 0x03);
+
+ /* All esdhc pins as SD */
+ out_8(&gpio->par_sdhch, 0xff);
+ out_8(&gpio->par_sdhcl, 0xff);
+#endif
#endif /* CONFIG_MCF5441x */
#ifdef CONFIG_MCF5445x
@@ -534,4 +543,5 @@ void cfspi_release_bus(uint bus, uint cs)
clrbits_8(&gpio->par_dspiow, GPIO_PAR_DSPIOW_DSPI0PSC1);
#endif
}
+
#endif
diff --git a/arch/m68k/cpu/mcf5445x/speed.c b/arch/m68k/cpu/mcf5445x/speed.c
index 5214730a0f..e15e32ebde 100644
--- a/arch/m68k/cpu/mcf5445x/speed.c
+++ b/arch/m68k/cpu/mcf5445x/speed.c
@@ -120,6 +120,8 @@ void setup_5441x_clocks(void)
temp = ((pdr & PLL_DR_OUTDIV2_BITS) >> 5) + 1;
gd->bus_clk = vco / temp; /* bus clock */
+ temp = ((pdr & PLL_DR_OUTDIV3_BITS) >> 10) + 1;
+ gd->arch.sdhc_clk = vco / temp;
}
#endif
diff --git a/arch/m68k/include/asm/byteorder.h b/arch/m68k/include/asm/byteorder.h
index eb03b6a053..9179622250 100644
--- a/arch/m68k/include/asm/byteorder.h
+++ b/arch/m68k/include/asm/byteorder.h
@@ -10,21 +10,28 @@
#include <asm/types.h>
#ifdef __GNUC__
-#define __sw16(x) \
- ((__u16)( \
- (((__u16)(x) & (__u16)0x00ffU) << 8) | \
- (((__u16)(x) & (__u16)0xff00U) >> 8) ))
-#define __sw32(x) \
- ((__u32)( \
- (((__u32)(x)) << 24) | \
- (((__u32)(x) & (__u32)0x0000ff00UL) << 8) | \
- (((__u32)(x) & (__u32)0x00ff0000UL) >> 8) | \
- (((__u32)(x)) >> 24) ))
+
+static inline __u32 __sw32(__u32 x)
+{
+ __u32 v = x;
+
+ return v << 24 |
+ (v & (__u32)0x0000ff00UL) << 8 |
+ (v & (__u32)0x00ff0000UL) >> 8 |
+ v >> 24;
+}
+
+static inline __u16 __sw16(__u16 x)
+{
+ __u16 v = x;
+
+ return (v & (__u16)0x00ffU) << 8 |
+ (v & (__u16)0xff00U) >> 8;
+}
static __inline__ unsigned ld_le16(const volatile unsigned short *addr)
{
- unsigned result = *addr;
- return __sw16(result);
+ return __sw16(*addr);
}
static __inline__ void st_le16(volatile unsigned short *addr,
@@ -35,8 +42,7 @@ static __inline__ void st_le16(volatile unsigned short *addr,
static __inline__ unsigned ld_le32(const volatile unsigned *addr)
{
- unsigned result = *addr;
- return __sw32(result);
+ return __sw32(*addr);
}
static __inline__ void st_le32(volatile unsigned *addr, const unsigned val)
diff --git a/arch/m68k/include/asm/global_data.h b/arch/m68k/include/asm/global_data.h
index aa0be8191a..188055e9d3 100644
--- a/arch/m68k/include/asm/global_data.h
+++ b/arch/m68k/include/asm/global_data.h
@@ -18,6 +18,9 @@ struct arch_global_data {
unsigned long vco_clk;
unsigned long flb_clk;
#endif
+#ifdef CONFIG_MCF5441x
+ unsigned long sdhc_clk;
+#endif
};
#include <asm-generic/global_data.h>
diff --git a/arch/m68k/include/asm/immap.h b/arch/m68k/include/asm/immap.h
index 06bc2a0a58..80fa25769b 100644
--- a/arch/m68k/include/asm/immap.h
+++ b/arch/m68k/include/asm/immap.h
@@ -362,7 +362,7 @@
#endif
#define CONFIG_SYS_INTR_BASE (MMAP_INTC0)
-#define CONFIG_SYS_NUM_IRQS (128)
+#define CONFIG_SYS_NUM_IRQS (192)
#endif /* CONFIG_M54418 */
diff --git a/arch/sh/include/asm/config.h b/arch/sh/include/asm/config.h
index bad0026648..d2862df4a5 100644
--- a/arch/sh/include/asm/config.h
+++ b/arch/sh/include/asm/config.h
@@ -6,4 +6,13 @@
#ifndef _ASM_CONFIG_H_
#define _ASM_CONFIG_H_
+#if !defined(CONFIG_CPU_SH2)
+#include <asm/processor.h>
+
+/* Timer */
+#define CONFIG_SYS_TIMER_COUNTS_DOWN
+#define CONFIG_SYS_TIMER_COUNTER (TMU_BASE + 0x8) /* TCNT0 */
+#define CONFIG_SYS_TIMER_RATE (CONFIG_SYS_CLK_FREQ / 4)
+#endif
+
#endif
diff --git a/arch/sh/include/asm/cpu_sh7724.h b/arch/sh/include/asm/cpu_sh7724.h
index 7a81e1677e..7b217959ed 100644
--- a/arch/sh/include/asm/cpu_sh7724.h
+++ b/arch/sh/include/asm/cpu_sh7724.h
@@ -203,9 +203,6 @@
#define PYDR 0xA405016A
#define PZDR 0xA405016C
-/* Ether */
-#define EDMR 0xA4600000
-
/* UBC */
/* H-UDI */
diff --git a/arch/sh/lib/time.c b/arch/sh/lib/time.c
index eb642969aa..fb317f95d5 100644
--- a/arch/sh/lib/time.c
+++ b/arch/sh/lib/time.c
@@ -13,44 +13,25 @@
#include <common.h>
#include <asm/processor.h>
#include <asm/io.h>
-#include <sh_tmu.h>
-#define TCR_TPSC 0x07
+#if defined(CONFIG_CPU_SH3)
+#define TSTR 0x2
+#define TCR0 0xc
+#endif /* CONFIG_CPU_SH3 */
-static struct tmu_regs *tmu = (struct tmu_regs *)TMU_BASE;
+#if defined(CONFIG_CPU_SH4) || defined(CONFIG_ARCH_RMOBILE)
+#define TSTR 0x4
+#define TCR0 0x10
+#endif /* CONFIG_CPU_SH4 */
-unsigned long get_tbclk(void)
-{
- u16 tmu_bit = (ffs(CONFIG_SYS_TMU_CLK_DIV) >> 1) - 1;
- return get_tmu0_clk_rate() >> ((tmu_bit + 1) * 2);
-}
-
-unsigned long timer_read_counter(void)
-{
- return ~readl(&tmu->tcnt0);
-}
-
-static void tmu_timer_start(unsigned int timer)
-{
- if (timer > 2)
- return;
- writeb(readb(&tmu->tstr) | (1 << timer), &tmu->tstr);
-}
-
-static void tmu_timer_stop(unsigned int timer)
-{
- if (timer > 2)
- return;
- writeb(readb(&tmu->tstr) & ~(1 << timer), &tmu->tstr);
-}
+#define TCR_TPSC 0x07
+#define TSTR_STR0 BIT(0)
int timer_init(void)
{
- u16 tmu_bit = (ffs(CONFIG_SYS_TMU_CLK_DIV) >> 1) - 1;
- writew((readw(&tmu->tcr0) & ~TCR_TPSC) | tmu_bit, &tmu->tcr0);
-
- tmu_timer_stop(0);
- tmu_timer_start(0);
+ writew(readw(TMU_BASE + TCR0) & ~TCR_TPSC, TMU_BASE + TCR0);
+ writeb(readb(TMU_BASE + TSTR) & ~TSTR_STR0, TMU_BASE + TSTR);
+ writeb(readb(TMU_BASE + TSTR) | TSTR_STR0, TMU_BASE + TSTR);
return 0;
}
diff --git a/arch/x86/cpu/tangier/Makefile b/arch/x86/cpu/tangier/Makefile
index 827448257e..68f4a326ee 100644
--- a/arch/x86/cpu/tangier/Makefile
+++ b/arch/x86/cpu/tangier/Makefile
@@ -2,5 +2,5 @@
#
# Copyright (c) 2017 Intel Corporation
-obj-y += car.o tangier.o sdram.o sysreset.o
+obj-y += car.o tangier.o sdram.o sysreset.o pinmux.o
obj-$(CONFIG_GENERATE_ACPI_TABLE) += acpi.o
diff --git a/arch/x86/cpu/tangier/pinmux.c b/arch/x86/cpu/tangier/pinmux.c
new file mode 100644
index 0000000000..fdd653026b
--- /dev/null
+++ b/arch/x86/cpu/tangier/pinmux.c
@@ -0,0 +1,194 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2018 Emlid Limited
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/pinctrl.h>
+#include <dm/read.h>
+#include <regmap.h>
+#include <syscon.h>
+#include <asm/cpu.h>
+#include <asm/scu.h>
+#include <linux/io.h>
+
+#define BUFCFG_OFFSET 0x100
+
+#define MRFLD_FAMILY_LEN 0x400
+
+/* These are taken from Linux kernel */
+#define MRFLD_PINMODE_MASK 0x07
+
+#define pin_to_bufno(f, p) ((p) - (f)->pin_base)
+
+struct mrfld_family {
+ unsigned int family_number;
+ unsigned int pin_base;
+ size_t npins;
+ void __iomem *regs;
+};
+
+#define MRFLD_FAMILY(b, s, e) \
+ { \
+ .family_number = (b), \
+ .pin_base = (s), \
+ .npins = (e) - (s) + 1, \
+ }
+
+/* Now we only support I2C family of pins */
+static struct mrfld_family mrfld_families[] = {
+ MRFLD_FAMILY(7, 101, 114),
+};
+
+struct mrfld_pinctrl {
+ const struct mrfld_family *families;
+ size_t nfamilies;
+};
+
+static const struct mrfld_family *
+mrfld_get_family(struct mrfld_pinctrl *mp, unsigned int pin)
+{
+ const struct mrfld_family *family;
+ unsigned int i;
+
+ for (i = 0; i < mp->nfamilies; i++) {
+ family = &mp->families[i];
+ if (pin >= family->pin_base &&
+ pin < family->pin_base + family->npins)
+ return family;
+ }
+
+ pr_err("failed to find family for pin %u\n", pin);
+ return NULL;
+}
+
+static void __iomem *
+mrfld_get_bufcfg(struct mrfld_pinctrl *pinctrl, unsigned int pin)
+{
+ const struct mrfld_family *family;
+ unsigned int bufno;
+
+ family = mrfld_get_family(pinctrl, pin);
+ if (!family)
+ return NULL;
+
+ bufno = pin_to_bufno(family, pin);
+
+ return family->regs + BUFCFG_OFFSET + bufno * 4;
+}
+
+static void
+mrfld_setup_families(void *base_addr,
+ struct mrfld_family *families, unsigned int nfam)
+{
+ for (int i = 0; i < nfam; i++) {
+ struct mrfld_family *family = &families[i];
+
+ family->regs = base_addr +
+ family->family_number * MRFLD_FAMILY_LEN;
+ }
+}
+
+static int mrfld_pinconfig_protected(unsigned int pin, u32 mask, u32 bits)
+{
+ struct mrfld_pinctrl *pinctrl;
+ struct udevice *dev;
+ void __iomem *bufcfg;
+ u32 v, value;
+ int ret;
+
+ ret = syscon_get_by_driver_data(X86_SYSCON_PINCONF, &dev);
+ if (ret)
+ return ret;
+
+ pinctrl = dev_get_priv(dev);
+
+ bufcfg = mrfld_get_bufcfg(pinctrl, pin);
+ if (!bufcfg)
+ return -EINVAL;
+
+ value = readl(bufcfg);
+
+ v = (value & ~mask) | (bits & mask);
+
+ debug("scu: v: 0x%x p: 0x%x bits: %d, mask: %d bufcfg: 0x%p\n",
+ v, (u32)bufcfg, bits, mask, bufcfg);
+
+ ret = scu_ipc_raw_command(IPCMSG_INDIRECT_WRITE, 0, &v, 4,
+ NULL, 0, (u32)bufcfg, 0);
+ if (ret)
+ pr_err("Failed to set mode via SCU for pin %u (%d)\n",
+ pin, ret);
+
+ return ret;
+}
+
+static int mrfld_pinctrl_cfg_pin(ofnode pin_node)
+{
+ bool is_protected;
+ int pad_offset;
+ int mode;
+ u32 mask;
+ int ret;
+
+ /* For now we only support just protected Family of pins */
+ is_protected = ofnode_read_bool(pin_node, "protected");
+ if (!is_protected)
+ return -ENOTSUPP;
+
+ pad_offset = ofnode_read_s32_default(pin_node, "pad-offset", -1);
+ if (pad_offset == -1)
+ return -EINVAL;
+
+ mode = ofnode_read_s32_default(pin_node, "mode-func", -1);
+ if (mode == -1)
+ return -EINVAL;
+
+ mask = MRFLD_PINMODE_MASK;
+
+ /* We don't support modes not in range 0..7 */
+ if (mode & ~mask)
+ return -ENOTSUPP;
+
+ ret = mrfld_pinconfig_protected(pad_offset, mask, mode);
+
+ return ret;
+}
+
+static int tangier_pinctrl_probe(struct udevice *dev)
+{
+ void *base_addr = syscon_get_first_range(X86_SYSCON_PINCONF);
+ struct mrfld_pinctrl *pinctrl = dev_get_priv(dev);
+ ofnode pin_node;
+ int ret;
+
+ mrfld_setup_families(base_addr, mrfld_families,
+ ARRAY_SIZE(mrfld_families));
+
+ pinctrl->families = mrfld_families;
+ pinctrl->nfamilies = ARRAY_SIZE(mrfld_families);
+
+ ofnode_for_each_subnode(pin_node, dev_ofnode(dev)) {
+ ret = mrfld_pinctrl_cfg_pin(pin_node);
+ if (ret) {
+ pr_err("%s: invalid configuration for the pin %ld\n",
+ __func__, pin_node.of_offset);
+ }
+ }
+
+ return 0;
+}
+
+static const struct udevice_id tangier_pinctrl_match[] = {
+ { .compatible = "intel,pinctrl-tangier", .data = X86_SYSCON_PINCONF },
+ { /* sentinel */ }
+};
+
+U_BOOT_DRIVER(tangier_pinctrl) = {
+ .name = "tangier_pinctrl",
+ .id = UCLASS_SYSCON,
+ .of_match = tangier_pinctrl_match,
+ .probe = tangier_pinctrl_probe,
+ .priv_auto_alloc_size = sizeof(struct mrfld_pinctrl),
+};
diff --git a/arch/x86/dts/edison.dts b/arch/x86/dts/edison.dts
index 5c80f5c7fa..ca8dfb4287 100644
--- a/arch/x86/dts/edison.dts
+++ b/arch/x86/dts/edison.dts
@@ -90,4 +90,26 @@
compatible = "intel,reset-tangier";
u-boot,dm-pre-reloc;
};
+
+ pinctrl {
+ compatible = "intel,pinctrl-tangier";
+ reg = <0xff0c0000 0x8000>;
+
+ /*
+ * Initial configuration came from the firmware.
+ * Which quite likely has been used in the phones, where I2C #8,
+ * that is not part of Atom peripheral, is in use.
+ * Thus we need to override the leftover.
+ */
+ i2c6_scl@0 {
+ pad-offset = <111>;
+ mode-func = <1>;
+ protected;
+ };
+ i2c6_sda@0 {
+ pad-offset = <112>;
+ mode-func = <1>;
+ protected;
+ };
+ };
};
diff --git a/arch/x86/include/asm/arch-tangier/acpi/southcluster.asl b/arch/x86/include/asm/arch-tangier/acpi/southcluster.asl
index 3c35089665..48193ba957 100644
--- a/arch/x86/include/asm/arch-tangier/acpi/southcluster.asl
+++ b/arch/x86/include/asm/arch-tangier/acpi/southcluster.asl
@@ -221,6 +221,16 @@ Device (PCI0)
}
}
+ Device (I2C6)
+ {
+ Name (_ADR, 0x00090001)
+
+ Method (_STA, 0, NotSerialized)
+ {
+ Return (STA_VISIBLE)
+ }
+ }
+
Device (GPIO)
{
Name (_ADR, 0x000c0000)
diff --git a/arch/x86/include/asm/scu.h b/arch/x86/include/asm/scu.h
index 7ce5824167..f5ec5a19d9 100644
--- a/arch/x86/include/asm/scu.h
+++ b/arch/x86/include/asm/scu.h
@@ -6,6 +6,8 @@
#define _X86_ASM_SCU_IPC_H_
/* IPC defines the following message types */
+#define IPCMSG_INDIRECT_READ 0x02
+#define IPCMSG_INDIRECT_WRITE 0x05
#define IPCMSG_WARM_RESET 0xf0
#define IPCMSG_COLD_RESET 0xf1
#define IPCMSG_SOFT_RESET 0xf2
@@ -23,5 +25,7 @@ struct ipc_ifwi_version {
/* Issue commands to the SCU with or without data */
int scu_ipc_simple_command(u32 cmd, u32 sub);
int scu_ipc_command(u32 cmd, u32 sub, u32 *in, int inlen, u32 *out, int outlen);
+int scu_ipc_raw_command(u32 cmd, u32 sub, u32 *in, int inlen, u32 *out,
+ int outlen, u32 dptr, u32 sptr);
#endif /* _X86_ASM_SCU_IPC_H_ */
diff --git a/arch/x86/lib/scu.c b/arch/x86/lib/scu.c
index caa04c688e..a6f8297e72 100644
--- a/arch/x86/lib/scu.c
+++ b/arch/x86/lib/scu.c
@@ -102,6 +102,57 @@ static int scu_ipc_cmd(struct ipc_regs *regs, u32 cmd, u32 sub,
}
/**
+ * scu_ipc_raw_command() - IPC command with data and pointers
+ * @cmd: IPC command code
+ * @sub: IPC command sub type
+ * @in: input data of this IPC command
+ * @inlen: input data length in dwords
+ * @out: output data of this IPC command
+ * @outlen: output data length in dwords
+ * @dptr: data writing to SPTR register
+ * @sptr: data writing to DPTR register
+ *
+ * Send an IPC command to SCU with input/output data and source/dest pointers.
+ *
+ * Return: an IPC error code or 0 on success.
+ */
+int scu_ipc_raw_command(u32 cmd, u32 sub, u32 *in, int inlen, u32 *out,
+ int outlen, u32 dptr, u32 sptr)
+{
+ int inbuflen = DIV_ROUND_UP(inlen, 4);
+ struct udevice *dev;
+ struct scu *scu;
+ int ret;
+
+ ret = syscon_get_by_driver_data(X86_SYSCON_SCU, &dev);
+ if (ret)
+ return ret;
+
+ scu = dev_get_priv(dev);
+
+ /* Up to 16 bytes */
+ if (inbuflen > 4)
+ return -EINVAL;
+
+ writel(dptr, &scu->regs->dptr);
+ writel(sptr, &scu->regs->sptr);
+
+ /*
+ * SRAM controller doesn't support 8-bit writes, it only
+ * supports 32-bit writes, so we have to copy input data into
+ * the temporary buffer, and SCU FW will use the inlen to
+ * determine the actual input data length in the temporary
+ * buffer.
+ */
+
+ u32 inbuf[4] = {0};
+
+ memcpy(inbuf, in, inlen);
+
+ return scu_ipc_cmd(scu->regs, cmd, sub, inbuf, inlen, out, outlen);
+}
+
+/**
* scu_ipc_simple_command() - send a simple command
* @cmd: command
* @sub: sub type
@@ -129,6 +180,17 @@ int scu_ipc_simple_command(u32 cmd, u32 sub)
return scu_ipc_check_status(scu->regs);
}
+/**
+ * scu_ipc_command - command with data
+ * @cmd: command
+ * @sub: sub type
+ * @in: input data
+ * @inlen: input length in dwords
+ * @out: output data
+ * @outlen: output length in dwords
+ *
+ * Issue a command to the SCU which involves data transfers.
+ */
int scu_ipc_command(u32 cmd, u32 sub, u32 *in, int inlen, u32 *out, int outlen)
{
struct scu *scu;