]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
arm: Add support for Qualcomm IPQ40xx family
authorRobert Marko <robert.marko@sartura.hr>
Mon, 6 Jul 2020 08:37:54 +0000 (10:37 +0200)
committerTom Rini <trini@konsulko.com>
Wed, 29 Jul 2020 12:43:40 +0000 (08:43 -0400)
This introduces initial support for the popular Qualcomm
IPQ40x8 and IPQ40x9 WiSoC series.

IPQ40xx series have 4x Cortex A7 ARM-v7A cores.
Supported are: IPQ4018, IPQ4019, IPQ4028 and IPQ4029.

IPQ40x8 and IPQ40x9 use the same cores, but differ in
addressable RAM size (1GB for IPQ40x9 and 256MB for IPQ40x8)
and supported peripherals (IPQ40x8 lacks RGMII, LCD controller
and EMMC/SDHCI controllers).

IQP4028/IPQ4029 models differ from IPQ4018/IPQ4019 only
by their rated temperatures rates with IPQ402X models being
rated for wider temperature ranges.

Initially this supports:
* Simple clock driver (Only for UART1 now, will be extended)
* Pinctrl driver (Supports UARTX and GPIO now, will be extended)
* GPIOs already supported by msm_gpio driver with updates
* UARTs already supported by serial_msm driver with updates

Further peripherals will come in later patches.

Signed-off-by: Robert Marko <robert.marko@sartura.hr>
MAINTAINERS
arch/arm/Kconfig
arch/arm/Makefile
arch/arm/dts/qcom-ipq4019.dtsi [new file with mode: 0644]
arch/arm/mach-ipq40xx/Kconfig [new file with mode: 0644]
arch/arm/mach-ipq40xx/Makefile [new file with mode: 0644]
arch/arm/mach-ipq40xx/clock-ipq4019.c [new file with mode: 0644]
arch/arm/mach-ipq40xx/include/mach/gpio.h [new file with mode: 0644]
arch/arm/mach-ipq40xx/pinctrl-ipq4019.c [new file with mode: 0644]
arch/arm/mach-ipq40xx/pinctrl-snapdragon.c [new file with mode: 0644]
arch/arm/mach-ipq40xx/pinctrl-snapdragon.h [new file with mode: 0644]

index 4c84c4da54d350a2e2de66566cd1fdf1898f7449..d4cef2f0f347146a313121691b1ccf5373db1b96 100644 (file)
@@ -218,6 +218,13 @@ F: arch/arm/cpu/armv8/hisilicon
 F:     arch/arm/include/asm/arch-hi6220/
 F:     arch/arm/include/asm/arch-hi3660/
 
+ARM IPQ40XX
+M:     Robert Marko <robert.marko@sartura.hr>
+M:     Luka Kovacic <luka.kovacic@sartura.hr>
+M:     Luka Perkov <luka.perkov@sartura.hr>
+S:     Maintained
+F:     arch/arm/mach-ipq40xx/
+
 ARM MARVELL KIRKWOOD ARMADA-XP ARMADA-38X ARMADA-37XX ARMADA-7K/8K
 M:     Stefan Roese <sr@denx.de>
 S:     Maintained
index e16fe038872a0b45f40b60d0d4b888bfc42d145d..f951dca0071c513c09a6817d61af86abc6a4f3ae 100644 (file)
@@ -767,6 +767,17 @@ config ARCH_INTEGRATOR
        select PL01X_SERIAL
        imply CMD_DM
 
+config ARCH_IPQ40XX
+       bool "Qualcomm IPQ40xx SoCs"
+       select CPU_V7A
+       select DM
+       select DM_GPIO
+       select DM_SERIAL
+       select PINCTRL
+       select CLK
+       select OF_CONTROL
+       imply CMD_DM
+
 config ARCH_KEYSTONE
        bool "TI Keystone"
        select CMD_POWEROFF
@@ -1793,6 +1804,8 @@ source "arch/arm/mach-highbank/Kconfig"
 
 source "arch/arm/mach-integrator/Kconfig"
 
+source "arch/arm/mach-ipq40xx/Kconfig"
+
 source "arch/arm/mach-k3/Kconfig"
 
 source "arch/arm/mach-keystone/Kconfig"
index 94eb50bf721b70bfc36556dc28b5aa182a04ea83..a20b82bc8d5c5c0896c834a93411cc30f805aba2 100644 (file)
@@ -58,6 +58,7 @@ machine-$(CONFIG_ARCH_BCMSTB)         += bcmstb
 machine-$(CONFIG_ARCH_DAVINCI)         += davinci
 machine-$(CONFIG_ARCH_EXYNOS)          += exynos
 machine-$(CONFIG_ARCH_HIGHBANK)                += highbank
+machine-$(CONFIG_ARCH_IPQ40XX)         += ipq40xx
 machine-$(CONFIG_ARCH_K3)              += k3
 machine-$(CONFIG_ARCH_KEYSTONE)                += keystone
 machine-$(CONFIG_ARCH_KIRKWOOD)                += kirkwood
diff --git a/arch/arm/dts/qcom-ipq4019.dtsi b/arch/arm/dts/qcom-ipq4019.dtsi
new file mode 100644 (file)
index 0000000..5f78bc5
--- /dev/null
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2019 Sartura Ltd.
+ *
+ * Author: Robert Marko <robert.marko@sartura.hr>
+ */
+
+ /dts-v1/;
+
+#include "skeleton.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/pinctrl-snapdragon.h>
+
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       model = "Qualcomm Technologies, Inc. IPQ4019";
+       compatible = "qcom,ipq4019";
+
+       aliases {
+               serial0 = &blsp1_uart1;
+       };
+
+       reserved-memory {
+               #address-cells = <0x1>;
+               #size-cells = <0x1>;
+               ranges;
+
+               smem_mem: smem_region: smem@87e00000 {
+                       reg = <0x87e00000 0x080000>;
+                       no-map;
+               };
+
+               tz@87e80000 {
+                       reg = <0x87e80000 0x180000>;
+                       no-map;
+               };
+       };
+
+       soc: soc {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+               compatible = "simple-bus";
+
+               gcc: clock-controller@1800000 {
+                       compatible = "qcom,gcc-ipq4019";
+                       reg = <0x1800000 0x60000>;
+                       #clock-cells = <1>;
+                       #reset-cells = <1>;
+                       u-boot,dm-pre-reloc;
+               };
+
+               pinctrl: qcom,tlmm@1000000 {
+                       compatible = "qcom,tlmm-ipq4019";
+                       reg = <0x1000000 0x300000>;
+                       u-boot,dm-pre-reloc;
+               };
+
+               blsp1_uart1: serial@78af000 {
+                       compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+                       reg = <0x78af000 0x200>;
+                       clock = <&gcc 26>;
+                       bit-rate = <0xFF>;
+                       status = "disabled";
+                       u-boot,dm-pre-reloc;
+               };
+
+               soc_gpios: pinctrl@1000000 {
+                       compatible = "qcom,ipq4019-pinctrl";
+                       reg = <0x1000000 0x300000>;
+                       gpio-controller;
+                       gpio-count = <100>;
+                       gpio-bank-name="soc";
+                       #gpio-cells = <2>;
+               };
+       };
+};
diff --git a/arch/arm/mach-ipq40xx/Kconfig b/arch/arm/mach-ipq40xx/Kconfig
new file mode 100644 (file)
index 0000000..4eef80e
--- /dev/null
@@ -0,0 +1,15 @@
+if ARCH_IPQ40XX
+
+config SYS_SOC
+       default "ipq40xx"
+
+config SYS_MALLOC_F_LEN
+       default 0x2000
+
+config SYS_TEXT_BASE
+       default 0x87300000
+
+config NR_DRAM_BANKS
+       default 1
+
+endif
diff --git a/arch/arm/mach-ipq40xx/Makefile b/arch/arm/mach-ipq40xx/Makefile
new file mode 100644 (file)
index 0000000..08a65b8
--- /dev/null
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (c) 2019 Sartura Ltd.
+#
+# Author: Robert Marko <robert.marko@sartura.hr>
+
+obj-y += clock-ipq4019.o
+obj-y += pinctrl-snapdragon.o
+obj-y += pinctrl-ipq4019.o
diff --git a/arch/arm/mach-ipq40xx/clock-ipq4019.c b/arch/arm/mach-ipq40xx/clock-ipq4019.c
new file mode 100644 (file)
index 0000000..7cf98a2
--- /dev/null
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Clock drivers for Qualcomm IPQ40xx
+ *
+ * Copyright (c) 2019 Sartura Ltd.
+ *
+ * Author: Robert Marko <robert.marko@sartura.hr>
+ *
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <errno.h>
+
+struct msm_clk_priv {
+       phys_addr_t base;
+};
+
+ulong msm_set_rate(struct clk *clk, ulong rate)
+{
+       switch (clk->id) {
+       case 26: /*UART1*/
+               /* This clock is already initialized by SBL1 */
+               return 0; 
+               break;
+       default:
+               return 0;
+       }
+}
+
+static int msm_clk_probe(struct udevice *dev)
+{
+       struct msm_clk_priv *priv = dev_get_priv(dev);
+
+       priv->base = devfdt_get_addr(dev);
+       if (priv->base == FDT_ADDR_T_NONE)
+               return -EINVAL;
+
+       return 0;
+}
+
+static ulong msm_clk_set_rate(struct clk *clk, ulong rate)
+{
+       return msm_set_rate(clk, rate);
+}
+
+static struct clk_ops msm_clk_ops = {
+       .set_rate = msm_clk_set_rate,
+};
+
+static const struct udevice_id msm_clk_ids[] = {
+       { .compatible = "qcom,gcc-ipq4019" },
+       { }
+};
+
+U_BOOT_DRIVER(clk_msm) = {
+       .name           = "clk_msm",
+       .id             = UCLASS_CLK,
+       .of_match       = msm_clk_ids,
+       .ops            = &msm_clk_ops,
+       .priv_auto_alloc_size = sizeof(struct msm_clk_priv),
+       .probe          = msm_clk_probe,
+};
diff --git a/arch/arm/mach-ipq40xx/include/mach/gpio.h b/arch/arm/mach-ipq40xx/include/mach/gpio.h
new file mode 100644 (file)
index 0000000..a45747c
--- /dev/null
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Empty gpio.h
+ *
+ * This file must stay as arch/arm/include/asm/gpio.h requires it.
+ *
+ * Copyright (c) 2019 Sartura Ltd.
+ *
+ * Author: Robert Marko <robert.marko@sartura.hr>
+ */
diff --git a/arch/arm/mach-ipq40xx/pinctrl-ipq4019.c b/arch/arm/mach-ipq40xx/pinctrl-ipq4019.c
new file mode 100644 (file)
index 0000000..06a57f2
--- /dev/null
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Qualcomm IPQ40xx pinctrl
+ *
+ * Copyright (c) 2019 Sartura Ltd.
+ *
+ * Author: Robert Marko <robert.marko@sartura.hr>
+ */
+
+#include "pinctrl-snapdragon.h"
+#include <common.h>
+
+#define MAX_PIN_NAME_LEN 32
+static char pin_name[MAX_PIN_NAME_LEN];
+
+static const struct pinctrl_function msm_pinctrl_functions[] = {
+       {"gpio", 0},
+       {"blsp_uart0_0", 1}, /* Only for GPIO:16,17 */
+       {"blsp_uart0_1", 2}, /* Only for GPIO:60,61 */
+       {"blsp_uart1", 1},
+};
+
+static const char *ipq4019_get_function_name(struct udevice *dev,
+                                            unsigned int selector)
+{
+       return msm_pinctrl_functions[selector].name;
+}
+
+static const char *ipq4019_get_pin_name(struct udevice *dev,
+                                       unsigned int selector)
+{
+       snprintf(pin_name, MAX_PIN_NAME_LEN, "GPIO_%u", selector);
+       return pin_name;
+}
+
+static unsigned int ipq4019_get_function_mux(unsigned int selector)
+{
+       return msm_pinctrl_functions[selector].val;
+}
+
+struct msm_pinctrl_data ipq4019_data = {
+       .pin_count = 100,
+       .functions_count = ARRAY_SIZE(msm_pinctrl_functions),
+       .get_function_name = ipq4019_get_function_name,
+       .get_function_mux = ipq4019_get_function_mux,
+       .get_pin_name = ipq4019_get_pin_name,
+};
diff --git a/arch/arm/mach-ipq40xx/pinctrl-snapdragon.c b/arch/arm/mach-ipq40xx/pinctrl-snapdragon.c
new file mode 100644 (file)
index 0000000..64b8b04
--- /dev/null
@@ -0,0 +1,137 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * TLMM driver for Qualcomm IPQ40xx
+ *
+ * (C) Copyright 2018 Ramon Fried <ramon.fried@gmail.com>
+ *
+ * Copyright (c) 2020 Sartura Ltd.
+ *
+ * Author: Robert Marko <robert.marko@sartura.hr>
+ *
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <dm/pinctrl.h>
+#include <linux/bitops.h>
+#include "pinctrl-snapdragon.h"
+
+struct msm_pinctrl_priv {
+       phys_addr_t base;
+       struct msm_pinctrl_data *data;
+};
+
+#define GPIO_CONFIG_OFFSET(x)         ((x) * 0x1000)
+#define TLMM_GPIO_PULL_MASK GENMASK(1, 0)
+#define TLMM_FUNC_SEL_MASK GENMASK(5, 2)
+#define TLMM_DRV_STRENGTH_MASK GENMASK(8, 6)
+#define TLMM_GPIO_DISABLE BIT(9)
+
+static const struct pinconf_param msm_conf_params[] = {
+       { "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 2 },
+       { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
+       { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 2 },
+};
+
+static int msm_get_functions_count(struct udevice *dev)
+{
+       struct msm_pinctrl_priv *priv = dev_get_priv(dev);
+
+       return priv->data->functions_count;
+}
+
+static int msm_get_pins_count(struct udevice *dev)
+{
+       struct msm_pinctrl_priv *priv = dev_get_priv(dev);
+
+       return priv->data->pin_count;
+}
+
+static const char *msm_get_function_name(struct udevice *dev,
+                                        unsigned int selector)
+{
+       struct msm_pinctrl_priv *priv = dev_get_priv(dev);
+
+       return priv->data->get_function_name(dev, selector);
+}
+
+static int msm_pinctrl_probe(struct udevice *dev)
+{
+       struct msm_pinctrl_priv *priv = dev_get_priv(dev);
+
+       priv->base = devfdt_get_addr(dev);
+       priv->data = (struct msm_pinctrl_data *)dev->driver_data;
+
+       return priv->base == FDT_ADDR_T_NONE ? -EINVAL : 0;
+}
+
+static const char *msm_get_pin_name(struct udevice *dev, unsigned int selector)
+{
+       struct msm_pinctrl_priv *priv = dev_get_priv(dev);
+
+       return priv->data->get_pin_name(dev, selector);
+}
+
+static int msm_pinmux_set(struct udevice *dev, unsigned int pin_selector,
+                         unsigned int func_selector)
+{
+       struct msm_pinctrl_priv *priv = dev_get_priv(dev);
+
+       clrsetbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector),
+                       TLMM_FUNC_SEL_MASK | TLMM_GPIO_DISABLE,
+                       priv->data->get_function_mux(func_selector) << 2);
+       return 0;
+}
+
+static int msm_pinconf_set(struct udevice *dev, unsigned int pin_selector,
+                          unsigned int param, unsigned int argument)
+{
+       struct msm_pinctrl_priv *priv = dev_get_priv(dev);
+
+       switch (param) {
+       case PIN_CONFIG_DRIVE_STRENGTH:
+               clrsetbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector),
+                               TLMM_DRV_STRENGTH_MASK, argument << 6);
+               break;
+       case PIN_CONFIG_BIAS_DISABLE:
+               clrbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector),
+                            TLMM_GPIO_PULL_MASK);
+               break;
+       case PIN_CONFIG_BIAS_PULL_UP:
+               clrsetbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector),
+                            TLMM_GPIO_PULL_MASK, argument);
+               break;
+       default:
+               return 0;
+       }
+
+       return 0;
+}
+
+static struct pinctrl_ops msm_pinctrl_ops = {
+       .get_pins_count = msm_get_pins_count,
+       .get_pin_name = msm_get_pin_name,
+       .set_state = pinctrl_generic_set_state,
+       .pinmux_set = msm_pinmux_set,
+       .pinconf_num_params = ARRAY_SIZE(msm_conf_params),
+       .pinconf_params = msm_conf_params,
+       .pinconf_set = msm_pinconf_set,
+       .get_functions_count = msm_get_functions_count,
+       .get_function_name = msm_get_function_name,
+};
+
+static const struct udevice_id msm_pinctrl_ids[] = {
+       { .compatible = "qcom,tlmm-ipq4019", .data = (ulong)&ipq4019_data },
+       { }
+};
+
+U_BOOT_DRIVER(pinctrl_snapdraon) = {
+       .name           = "pinctrl_msm",
+       .id             = UCLASS_PINCTRL,
+       .of_match       = msm_pinctrl_ids,
+       .priv_auto_alloc_size = sizeof(struct msm_pinctrl_priv),
+       .ops            = &msm_pinctrl_ops,
+       .probe          = msm_pinctrl_probe,
+};
diff --git a/arch/arm/mach-ipq40xx/pinctrl-snapdragon.h b/arch/arm/mach-ipq40xx/pinctrl-snapdragon.h
new file mode 100644 (file)
index 0000000..2341a71
--- /dev/null
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Qualcomm Pin control
+ *
+ * (C) Copyright 2018 Ramon Fried <ramon.fried@gmail.com>
+ *
+ */
+#ifndef _PINCTRL_SNAPDRAGON_H
+#define _PINCTRL_SNAPDRAGON_H
+
+#include <common.h>
+
+struct msm_pinctrl_data {
+       int pin_count;
+       int functions_count;
+       const char *(*get_function_name)(struct udevice *dev,
+                                        unsigned int selector);
+       unsigned int (*get_function_mux)(unsigned int selector);
+       const char *(*get_pin_name)(struct udevice *dev,
+                                   unsigned int selector);
+};
+
+struct pinctrl_function {
+       const char *name;
+       int val;
+};
+
+extern struct msm_pinctrl_data ipq4019_data;
+
+#endif