diff options
author | Tom Rini <trini@konsulko.com> | 2024-01-16 09:51:16 -0500 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2024-01-16 09:51:16 -0500 |
commit | 043ca8c8a9b181cf6f17441e9b89b5ee33206309 (patch) | |
tree | 7971baea0d859a44a15339ffc505e07dddc44956 | |
parent | 6ca9349b6723dbb00385ca9c04e6478d4a03b109 (diff) | |
parent | 4c3dfa1b8babf9fc0575ce08eed99f950d3bab84 (diff) | |
download | u-boot-WIP/16Jan2024.zip u-boot-WIP/16Jan2024.tar.gz u-boot-WIP/16Jan2024.tar.bz2 |
Merge tag 'qcom-2024.04-rc1' of https://gitlab.denx.de/u-boot/custodians/u-boot-snapdragonWIP/16Jan2024
Qualcomm architecture changes:
* Move clock and pinctrl drivers out of mach-snapdragon
* Various clock driver improvements
* Convert PMIC power/reset key driver to use the button API
* Preparetory work for migrating to upstream DT
81 files changed, 1773 insertions, 1792 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 4fec063..da477a4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -575,9 +575,12 @@ M: Neil Armstrong <neil.armstrong@linaro.org> R: Sumit Garg <sumit.garg@linaro.org> S: Maintained F: arch/arm/mach-snapdragon/ +F: drivers/button/button-qcom-pmic.c +F: drivers/clk/qcom/ F: drivers/gpio/msm_gpio.c F: drivers/mmc/msm_sdhci.c F: drivers/phy/msm8916-usbh-phy.c +F: drivers/pinctrl/qcom/ F: drivers/serial/serial_msm.c F: drivers/serial/serial_msm_geni.c F: drivers/smem/msm_smem.c diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 2d4458b..9e73b69 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -776,6 +776,8 @@ config ARCH_IPQ40XX select CLK select SMEM select OF_CONTROL + select CLK_QCOM_IPQ4019 + select PINCTRL_QCOM_IPQ4019 imply CMD_DM config ARCH_KEYSTONE @@ -1076,6 +1078,7 @@ config ARCH_SNAPDRAGON select DM select DM_GPIO select DM_SERIAL + select DM_RESET select GPIO_EXTRA_HEADER select MSM_SMEM select OF_CONTROL diff --git a/arch/arm/dts/dragonboard410c-uboot.dtsi b/arch/arm/dts/dragonboard410c-uboot.dtsi index 3b0bd0e..cec64bf 100644 --- a/arch/arm/dts/dragonboard410c-uboot.dtsi +++ b/arch/arm/dts/dragonboard410c-uboot.dtsi @@ -42,14 +42,3 @@ gpios = <&pm8916_gpios 3 0>; }; }; - - -&pm8916_pon { - key_vol_down { - gpios = <&pm8916_pon 1 0>; - }; - - key_power { - gpios = <&pm8916_pon 0 0>; - }; -}; diff --git a/arch/arm/dts/dragonboard410c.dts b/arch/arm/dts/dragonboard410c.dts index 9230dd3..6a4e3cc 100644 --- a/arch/arm/dts/dragonboard410c.dts +++ b/arch/arm/dts/dragonboard410c.dts @@ -147,20 +147,31 @@ #address-cells = <0x1>; #size-cells = <0x1>; - pm8916_pon: pm8916_pon@800 { - compatible = "qcom,pm8916-pwrkey"; - reg = <0x800 0x96>; - #gpio-cells = <2>; - gpio-controller; + pon@800 { + compatible = "qcom,pm8916-pon"; + reg = <0x800 0x100>; + mode-bootloader = <0x2>; + mode-recovery = <0x1>; + + pwrkey { + compatible = "qcom,pm8941-pwrkey"; + debounce = <15625>; + bias-pull-up; + }; + + pm8916_resin: resin { + compatible = "qcom,pm8941-resin"; + debounce = <15625>; + bias-pull-up; + }; }; pm8916_gpios: pm8916_gpios@c000 { compatible = "qcom,pm8916-gpio"; reg = <0xc000 0x400>; gpio-controller; - gpio-count = <4>; + gpio-ranges = <&pm8916_gpios 0 0 4>; #gpio-cells = <2>; - gpio-bank-name="pmic"; }; }; diff --git a/arch/arm/dts/dragonboard820c-uboot.dtsi b/arch/arm/dts/dragonboard820c-uboot.dtsi index 457728a..d93c7c1 100644 --- a/arch/arm/dts/dragonboard820c-uboot.dtsi +++ b/arch/arm/dts/dragonboard820c-uboot.dtsi @@ -30,15 +30,3 @@ }; }; }; - -&pm8994_pon { - key_vol_down { - gpios = <&pm8994_pon 1 0>; - label = "key_vol_down"; - }; - - key_power { - gpios = <&pm8994_pon 0 0>; - label = "key_power"; - }; -}; diff --git a/arch/arm/dts/dragonboard820c.dts b/arch/arm/dts/dragonboard820c.dts index ad201d4..146a0af 100644 --- a/arch/arm/dts/dragonboard820c.dts +++ b/arch/arm/dts/dragonboard820c.dts @@ -109,21 +109,31 @@ #address-cells = <0x1>; #size-cells = <0x1>; - pm8994_pon: pm8994_pon@800 { - compatible = "qcom,pm8994-pwrkey"; - reg = <0x800 0x96>; - #gpio-cells = <2>; - gpio-controller; - gpio-bank-name="pm8994_key."; + pm8994_pon: pon@800 { + compatible = "qcom,pm8916-pon"; + reg = <0x800 0x100>; + mode-bootloader = <0x2>; + mode-recovery = <0x1>; + + pwrkey { + compatible = "qcom,pm8941-pwrkey"; + debounce = <15625>; + bias-pull-up; + }; + + pm8994_resin: resin { + compatible = "qcom,pm8941-resin"; + debounce = <15625>; + bias-pull-up; + }; }; pm8994_gpios: pm8994_gpios@c000 { compatible = "qcom,pm8994-gpio"; reg = <0xc000 0x400>; gpio-controller; - gpio-count = <24>; + gpio-ranges = <&pm8994_gpios 0 0 22>; #gpio-cells = <2>; - gpio-bank-name="pm8994."; }; }; diff --git a/arch/arm/dts/dragonboard845c-uboot.dtsi b/arch/arm/dts/dragonboard845c-uboot.dtsi index 7106db8..775f45c 100644 --- a/arch/arm/dts/dragonboard845c-uboot.dtsi +++ b/arch/arm/dts/dragonboard845c-uboot.dtsi @@ -19,19 +19,8 @@ bootph-all; }; - pinctrl_north@3900000 { + pinctrl@3400000 { bootph-all; }; }; }; - -&pm8998_pon { - key_vol_down { - gpios = <&pm8998_pon 1 0>; - label = "key_vol_down"; - }; - key_power { - gpios = <&pm8998_pon 0 0>; - label = "key_power"; - }; -}; diff --git a/arch/arm/dts/dragonboard845c.dts b/arch/arm/dts/dragonboard845c.dts index b4f057a..054f253 100644 --- a/arch/arm/dts/dragonboard845c.dts +++ b/arch/arm/dts/dragonboard845c.dts @@ -41,4 +41,8 @@ }; }; +&pm8998_resin { + status = "okay"; +}; + #include "dragonboard845c-uboot.dtsi" diff --git a/arch/arm/dts/qcom-ipq4019.dtsi b/arch/arm/dts/qcom-ipq4019.dtsi index 0850ae5..f9489e4 100644 --- a/arch/arm/dts/qcom-ipq4019.dtsi +++ b/arch/arm/dts/qcom-ipq4019.dtsi @@ -66,14 +66,6 @@ status = "disabled"; }; - reset: gcc-reset@1800000 { - compatible = "qcom,gcc-reset-ipq4019"; - reg = <0x1800000 0x60000>; - #clock-cells = <1>; - #reset-cells = <1>; - bootph-all; - }; - soc_gpios: pinctrl@1000000 { compatible = "qcom,ipq4019-pinctrl"; reg = <0x1000000 0x300000>; @@ -136,7 +128,7 @@ #phy-cells = <0>; reg = <0x9a000 0x800>; reg-names = "phy_base"; - resets = <&reset USB3_UNIPHY_PHY_ARES>; + resets = <&gcc USB3_UNIPHY_PHY_ARES>; reset-names = "por_rst"; status = "disabled"; }; @@ -146,7 +138,7 @@ #phy-cells = <0>; reg = <0xa6000 0x40>; reg-names = "phy_base"; - resets = <&reset USB3_HSPHY_POR_ARES>, <&reset USB3_HSPHY_S_ARES>; + resets = <&gcc USB3_HSPHY_POR_ARES>, <&gcc USB3_HSPHY_S_ARES>; reset-names = "por_rst", "srif_rst"; status = "disabled"; }; @@ -179,7 +171,7 @@ #phy-cells = <0>; reg = <0xa8000 0x40>; reg-names = "phy_base"; - resets = <&reset USB2_HSPHY_POR_ARES>, <&reset USB2_HSPHY_S_ARES>; + resets = <&gcc USB2_HSPHY_POR_ARES>, <&gcc USB2_HSPHY_S_ARES>; reset-names = "por_rst", "srif_rst"; status = "disabled"; }; diff --git a/arch/arm/dts/qcs404-evb.dts b/arch/arm/dts/qcs404-evb.dts index 8d7893c..07bf7dd 100644 --- a/arch/arm/dts/qcs404-evb.dts +++ b/arch/arm/dts/qcs404-evb.dts @@ -208,11 +208,6 @@ #address-cells = <0x1>; #size-cells = <0x0>; #clock-cells = <1>; - }; - - reset: gcc-reset@1800000 { - compatible = "qcom,gcc-reset-qcs404"; - reg = <0x1800000 0x80000>; #reset-cells = <1>; }; @@ -245,8 +240,8 @@ clocks = <&gcc GCC_USB_HS_PHY_CFG_AHB_CLK>, <&gcc GCC_USB3_PHY_PIPE_CLK>; clock-names = "ahb", "pipe"; - resets = <&reset GCC_USB3_PHY_BCR>, - <&reset GCC_USB3PHY_PHY_BCR>; + resets = <&gcc GCC_USB3_PHY_BCR>, + <&gcc GCC_USB3PHY_PHY_BCR>; reset-names = "com", "phy"; }; @@ -257,8 +252,8 @@ clocks = <&gcc GCC_USB_HS_PHY_CFG_AHB_CLK>, <&gcc GCC_USB2A_PHY_SLEEP_CLK>; clock-names = "ahb", "sleep"; - resets = <&reset GCC_USB_HS_PHY_CFG_AHB_BCR>, - <&reset GCC_USB2A_PHY_BCR>; + resets = <&gcc GCC_USB_HS_PHY_CFG_AHB_BCR>, + <&gcc GCC_USB2A_PHY_BCR>; reset-names = "phy", "por"; }; @@ -269,8 +264,8 @@ clocks = <&gcc GCC_USB_HS_PHY_CFG_AHB_CLK>, <&gcc GCC_USB2A_PHY_SLEEP_CLK>; clock-names = "ahb", "sleep"; - resets = <&reset GCC_QUSB2_PHY_BCR>, - <&reset GCC_USB2_HS_PHY_ONLY_BCR>; + resets = <&gcc GCC_QUSB2_PHY_BCR>, + <&gcc GCC_USB2_HS_PHY_ONLY_BCR>; reset-names = "phy", "por"; }; @@ -335,7 +330,7 @@ <&gcc GCC_ETH_PTP_CLK>, <&gcc GCC_ETH_RGMII_CLK>; - resets = <&reset GCC_EMAC_BCR>; + resets = <&gcc GCC_EMAC_BCR>; reset-names = "emac"; snps,tso; @@ -367,9 +362,10 @@ spmi@200f000 { compatible = "qcom,spmi-pmic-arb"; - reg = <0x200f000 0x1000 - 0x2400000 0x400000 - 0x2c00000 0x400000>; + reg = <0x200f000 0x001000>, + <0x2400000 0x800000>, + <0x2c00000 0x800000>; + reg-names = "core", "chnls", "obsrvr"; #address-cells = <0x1>; #size-cells = <0x1>; @@ -383,9 +379,8 @@ compatible = "qcom,pms405-gpio"; reg = <0xc000 0x400>; gpio-controller; - gpio-count = <12>; + gpio-ranges = <&pms405_gpios 0 0 12>; #gpio-cells = <2>; - gpio-bank-name="pmic"; }; }; }; diff --git a/arch/arm/dts/sdm845.dtsi b/arch/arm/dts/sdm845.dtsi index 3b86b93..96c9749 100644 --- a/arch/arm/dts/sdm845.dtsi +++ b/arch/arm/dts/sdm845.dtsi @@ -26,23 +26,13 @@ #power-domain-cells = <1>; }; - gpio_north: gpio_north@3900000 { - #gpio-cells = <2>; - compatible = "qcom,sdm845-pinctrl"; - reg = <0x3900000 0x400000>; - gpio-count = <150>; - gpio-controller; - gpio-ranges = <&gpio_north 0 0 150>; - gpio-bank-name = "soc_north."; - }; - - tlmm_north: pinctrl_north@3900000 { + tlmm: pinctrl@3400000 { compatible = "qcom,sdm845-pinctrl"; - reg = <0x3900000 0x400000>; + reg = <0x3400000 0xc00000>; gpio-count = <150>; gpio-controller; #gpio-cells = <2>; - gpio-ranges = <&tlmm_north 0 0 150>; + gpio-ranges = <&tlmm 0 0 150>; /* DEBUG UART */ qup_uart9: qup-uart9-default { @@ -73,7 +63,7 @@ reg = <0xc440000 0x1100>, <0xc600000 0x2000000>, <0xe600000 0x100000>; - reg-names = "cnfg", "core", "obsrvr"; + reg-names = "core", "chnls", "obsrvr"; #address-cells = <0x1>; #size-cells = <0x1>; @@ -88,21 +78,33 @@ #address-cells = <0x1>; #size-cells = <0x1>; - pm8998_pon: pm8998_pon@800 { - compatible = "qcom,pm8998-pwrkey"; + pm8998_pon: pon@800 { + compatible = "qcom,pm8998-pon"; + reg = <0x800 0x100>; - #gpio-cells = <2>; - gpio-controller; - gpio-bank-name = "pm8998_key."; + mode-bootloader = <0x2>; + mode-recovery = <0x1>; + + pm8998_pwrkey: pwrkey { + compatible = "qcom,pm8941-pwrkey"; + debounce = <15625>; + bias-pull-up; + }; + + pm8998_resin: resin { + compatible = "qcom,pm8941-resin"; + debounce = <15625>; + bias-pull-up; + status = "disabled"; + }; }; pm8998_gpios: pm8998_gpios@c000 { compatible = "qcom,pm8998-gpio"; reg = <0xc000 0x1a00>; gpio-controller; - gpio-count = <21>; + gpio-ranges = <&pm8998_gpios 0 0 26>; #gpio-cells = <2>; - gpio-bank-name = "pm8998."; }; }; diff --git a/arch/arm/dts/starqltechn-uboot.dtsi b/arch/arm/dts/starqltechn-uboot.dtsi index d81a22f..55c6d18 100644 --- a/arch/arm/dts/starqltechn-uboot.dtsi +++ b/arch/arm/dts/starqltechn-uboot.dtsi @@ -19,22 +19,9 @@ clock-controller@100000 { bootph-all; }; - gpio_north@3900000 { - bootph-all; - }; - pinctrl_north@3900000 { + pinctrl@3400000 { bootph-all; }; }; }; -&pm8998_pon { - key_vol_down { - gpios = <&pm8998_pon 1 0>; - label = "key_vol_down"; - }; - key_power { - gpios = <&pm8998_pon 0 0>; - label = "key_power"; - }; -}; diff --git a/arch/arm/dts/starqltechn.dts b/arch/arm/dts/starqltechn.dts index eec51d1..0842e19 100644 --- a/arch/arm/dts/starqltechn.dts +++ b/arch/arm/dts/starqltechn.dts @@ -45,35 +45,23 @@ format = "a8r8g8b8"; }; - gpio-keys { - compatible = "gpio-keys"; - - key-pwr { - label = "Power"; - linux,code = <KEY_ENTER>; - gpios = <&pm8998_pon 0 GPIO_ACTIVE_LOW>; - }; - - key-vol-down { - label = "Volume Down"; - linux,code = <KEY_DOWN>; - gpios = <&pm8998_pon 1 GPIO_ACTIVE_LOW>; - }; - }; - soc: soc { serial@a84000 { status = "okay"; }; + }; +}; - pinctrl_north@3900000 { - muic_i2c: muic_i2c { - pins = "GPIO_33", "GPIO_34"; - drive-strength = <0x2>; - function = "gpio"; - bias-disable; - }; - }; +&pm8998_resin { + status = "okay"; +}; + +&tlmm { + muic_i2c: muic-i2c-n { + pins = "GPIO_33", "GPIO_34"; + drive-strength = <0x2>; + function = "gpio"; + bias-disable; }; }; diff --git a/arch/arm/mach-ipq40xx/Makefile b/arch/arm/mach-ipq40xx/Makefile deleted file mode 100644 index 08a65b8..0000000 --- a/arch/arm/mach-ipq40xx/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# 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 deleted file mode 100644 index c1d5c4e..0000000 --- a/arch/arm/mach-ipq40xx/clock-ipq4019.c +++ /dev/null @@ -1,88 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Clock drivers for Qualcomm IPQ40xx - * - * Copyright (c) 2020 Sartura Ltd. - * - * Author: Robert Marko <robert.marko@sartura.hr> - * - */ - -#include <clk-uclass.h> -#include <common.h> -#include <dm.h> -#include <errno.h> - -#include <dt-bindings/clock/qcom,ipq4019-gcc.h> - -struct msm_clk_priv { - phys_addr_t base; -}; - -ulong msm_set_rate(struct clk *clk, ulong rate) -{ - switch (clk->id) { - case GCC_BLSP1_UART1_APPS_CLK: /*UART1*/ - /* This clock is already initialized by SBL1 */ - return 0; - default: - return -EINVAL; - } -} - -static int msm_clk_probe(struct udevice *dev) -{ - struct msm_clk_priv *priv = dev_get_priv(dev); - - priv->base = dev_read_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 int msm_enable(struct clk *clk) -{ - switch (clk->id) { - case GCC_BLSP1_QUP1_SPI_APPS_CLK: /*SPI1*/ - /* This clock is already initialized by SBL1 */ - return 0; - case GCC_PRNG_AHB_CLK: /*PRNG*/ - /* This clock is already initialized by SBL1 */ - return 0; - case GCC_USB3_MASTER_CLK: - case GCC_USB3_SLEEP_CLK: - case GCC_USB3_MOCK_UTMI_CLK: - case GCC_USB2_MASTER_CLK: - case GCC_USB2_SLEEP_CLK: - case GCC_USB2_MOCK_UTMI_CLK: - /* These clocks is already initialized by SBL1 */ - return 0; - default: - return -EINVAL; - } -} - -static struct clk_ops msm_clk_ops = { - .set_rate = msm_clk_set_rate, - .enable = msm_enable, -}; - -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 = sizeof(struct msm_clk_priv), - .probe = msm_clk_probe, -}; diff --git a/arch/arm/mach-ipq40xx/pinctrl-snapdragon.c b/arch/arm/mach-ipq40xx/pinctrl-snapdragon.c deleted file mode 100644 index 036fec9..0000000 --- a/arch/arm/mach-ipq40xx/pinctrl-snapdragon.c +++ /dev/null @@ -1,166 +0,0 @@ -// 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/device_compat.h> -#include <dm/lists.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 int msm_pinctrl_bind(struct udevice *dev) -{ - ofnode node = dev_ofnode(dev); - const char *name; - int ret; - - ofnode_get_property(node, "gpio-controller", &ret); - if (ret < 0) - return 0; - - /* Get the name of gpio node */ - name = ofnode_get_name(node); - if (!name) - return -EINVAL; - - /* Bind gpio node */ - ret = device_bind_driver_to_node(dev, "gpio_msm", - name, node, NULL); - if (ret) - return ret; - - dev_dbg(dev, "bind %s\n", name); - - 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,ipq4019-pinctrl", .data = (ulong)&ipq4019_data }, - { } -}; - -U_BOOT_DRIVER(pinctrl_snapdraon) = { - .name = "pinctrl_msm", - .id = UCLASS_PINCTRL, - .of_match = msm_pinctrl_ids, - .priv_auto = sizeof(struct msm_pinctrl_priv), - .ops = &msm_pinctrl_ops, - .probe = msm_pinctrl_probe, - .bind = msm_pinctrl_bind, -}; diff --git a/arch/arm/mach-snapdragon/Kconfig b/arch/arm/mach-snapdragon/Kconfig index 2fc1521..ad66710 100644 --- a/arch/arm/mach-snapdragon/Kconfig +++ b/arch/arm/mach-snapdragon/Kconfig @@ -15,6 +15,9 @@ config SPL_SYS_MALLOC_F_LEN config SDM845 bool "Qualcomm Snapdragon 845 SoC" select LINUX_KERNEL_IMAGE_HEADER + imply CLK_QCOM_SDM845 + imply PINCTRL_QCOM_SDM845 + imply BUTTON_QCOM_PMIC config LNX_KRNL_IMG_TEXT_OFFSET_BASE default 0x80000000 @@ -26,6 +29,9 @@ config TARGET_DRAGONBOARD410C bool "96Boards Dragonboard 410C" select BOARD_LATE_INIT select ENABLE_ARM_SOC_BOOT0_HOOK + imply CLK_QCOM_APQ8016 + imply PINCTRL_QCOM_APQ8016 + imply BUTTON_QCOM_PMIC help Support for 96Boards Dragonboard 410C. This board complies with 96Board Open Platform Specifications. Features: @@ -39,6 +45,9 @@ config TARGET_DRAGONBOARD410C config TARGET_DRAGONBOARD820C bool "96Boards Dragonboard 820C" + imply CLK_QCOM_APQ8096 + imply PINCTRL_QCOM_APQ8096 + imply BUTTON_QCOM_PMIC help Support for 96Boards Dragonboard 820C. This board complies with 96Board Open Platform Specifications. Features: @@ -72,6 +81,8 @@ config TARGET_STARQLTECHN config TARGET_QCS404EVB bool "Qualcomm Technologies, Inc. QCS404 EVB" select LINUX_KERNEL_IMAGE_HEADER + imply CLK_QCOM_QCS404 + imply PINCTRL_QCOM_QCS404 help Support for Qualcomm Technologies, Inc. QCS404 evaluation board. Features: diff --git a/arch/arm/mach-snapdragon/Makefile b/arch/arm/mach-snapdragon/Makefile index cbaaf23..3a3a297 100644 --- a/arch/arm/mach-snapdragon/Makefile +++ b/arch/arm/mach-snapdragon/Makefile @@ -2,20 +2,10 @@ # # (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com> -obj-$(CONFIG_SDM845) += clock-sdm845.o obj-$(CONFIG_SDM845) += sysmap-sdm845.o obj-$(CONFIG_SDM845) += init_sdm845.o -obj-$(CONFIG_TARGET_DRAGONBOARD820C) += clock-apq8096.o obj-$(CONFIG_TARGET_DRAGONBOARD820C) += sysmap-apq8096.o -obj-$(CONFIG_TARGET_DRAGONBOARD410C) += clock-apq8016.o obj-$(CONFIG_TARGET_DRAGONBOARD410C) += sysmap-apq8016.o obj-y += misc.o -obj-y += clock-snapdragon.o obj-y += dram.o -obj-y += pinctrl-snapdragon.o -obj-y += pinctrl-apq8016.o -obj-y += pinctrl-apq8096.o -obj-y += pinctrl-qcs404.o -obj-y += pinctrl-sdm845.o -obj-$(CONFIG_TARGET_QCS404EVB) += clock-qcs404.o obj-$(CONFIG_TARGET_QCS404EVB) += sysmap-qcs404.o diff --git a/arch/arm/mach-snapdragon/clock-sdm845.c b/arch/arm/mach-snapdragon/clock-sdm845.c deleted file mode 100644 index d6df036..0000000 --- a/arch/arm/mach-snapdragon/clock-sdm845.c +++ /dev/null @@ -1,98 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -/* - * Clock drivers for Qualcomm SDM845 - * - * (C) Copyright 2017 Jorge Ramirez Ortiz <jorge.ramirez-ortiz@linaro.org> - * (C) Copyright 2021 Dzmitry Sankouski <dsankouski@gmail.com> - * - * Based on Little Kernel driver, simplified - */ - -#include <common.h> -#include <clk-uclass.h> -#include <dm.h> -#include <errno.h> -#include <asm/io.h> -#include <linux/bitops.h> -#include <dt-bindings/clock/qcom,gcc-sdm845.h> -#include "clock-snapdragon.h" - -#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } - -struct freq_tbl { - uint freq; - uint src; - u8 pre_div; - u16 m; - u16 n; -}; - -static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = { - F(7372800, CFG_CLK_SRC_GPLL0_EVEN, 1, 384, 15625), - F(14745600, CFG_CLK_SRC_GPLL0_EVEN, 1, 768, 15625), - F(19200000, CFG_CLK_SRC_CXO, 1, 0, 0), - F(29491200, CFG_CLK_SRC_GPLL0_EVEN, 1, 1536, 15625), - F(32000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 8, 75), - F(48000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 4, 25), - F(64000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 16, 75), - F(80000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 4, 15), - F(96000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 8, 25), - F(100000000, CFG_CLK_SRC_GPLL0_EVEN, 3, 0, 0), - F(102400000, CFG_CLK_SRC_GPLL0_EVEN, 1, 128, 375), - F(112000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 28, 75), - F(117964800, CFG_CLK_SRC_GPLL0_EVEN, 1, 6144, 15625), - F(120000000, CFG_CLK_SRC_GPLL0_EVEN, 2.5, 0, 0), - F(128000000, CFG_CLK_SRC_GPLL0, 1, 16, 75), - { } -}; - -static const struct bcr_regs uart2_regs = { - .cfg_rcgr = SE9_UART_APPS_CFG_RCGR, - .cmd_rcgr = SE9_UART_APPS_CMD_RCGR, - .M = SE9_UART_APPS_M, - .N = SE9_UART_APPS_N, - .D = SE9_UART_APPS_D, -}; - -const struct freq_tbl *qcom_find_freq(const struct freq_tbl *f, uint rate) -{ - if (!f) - return NULL; - - if (!f->freq) - return f; - - for (; f->freq; f++) - if (rate <= f->freq) - return f; - - /* Default to our fastest rate */ - return f - 1; -} - -static int clk_init_uart(struct msm_clk_priv *priv, uint rate) -{ - const struct freq_tbl *freq = qcom_find_freq(ftbl_gcc_qupv3_wrap0_s0_clk_src, rate); - - clk_rcg_set_rate_mnd(priv->base, &uart2_regs, - freq->pre_div, freq->m, freq->n, freq->src); - - return 0; -} - -ulong msm_set_rate(struct clk *clk, ulong rate) -{ - struct msm_clk_priv *priv = dev_get_priv(clk->dev); - - switch (clk->id) { - case GCC_QUPV3_WRAP1_S1_CLK: /*UART2*/ - return clk_init_uart(priv, rate); - default: - return 0; - } -} - -int msm_enable(struct clk *clk) -{ - return 0; -} diff --git a/arch/arm/mach-snapdragon/clock-snapdragon.c b/arch/arm/mach-snapdragon/clock-snapdragon.c deleted file mode 100644 index 0ac45dc..0000000 --- a/arch/arm/mach-snapdragon/clock-snapdragon.c +++ /dev/null @@ -1,181 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -/* - * Clock drivers for Qualcomm APQ8016, APQ8096 - * - * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com> - * - * Based on Little Kernel driver, simplified - */ - -#include <common.h> -#include <clk-uclass.h> -#include <dm.h> -#include <errno.h> -#include <asm/io.h> -#include <linux/bitops.h> -#include "clock-snapdragon.h" - -/* CBCR register fields */ -#define CBCR_BRANCH_ENABLE_BIT BIT(0) -#define CBCR_BRANCH_OFF_BIT BIT(31) - -extern ulong msm_set_rate(struct clk *clk, ulong rate); -extern int msm_enable(struct clk *clk); - -/* Enable clock controlled by CBC soft macro */ -void clk_enable_cbc(phys_addr_t cbcr) -{ - setbits_le32(cbcr, CBCR_BRANCH_ENABLE_BIT); - - while (readl(cbcr) & CBCR_BRANCH_OFF_BIT) - ; -} - -void clk_enable_gpll0(phys_addr_t base, const struct pll_vote_clk *gpll0) -{ - if (readl(base + gpll0->status) & gpll0->status_bit) - return; /* clock already enabled */ - - setbits_le32(base + gpll0->ena_vote, gpll0->vote_bit); - - while ((readl(base + gpll0->status) & gpll0->status_bit) == 0) - ; -} - -#define BRANCH_ON_VAL (0) -#define BRANCH_NOC_FSM_ON_VAL BIT(29) -#define BRANCH_CHECK_MASK GENMASK(31, 28) - -void clk_enable_vote_clk(phys_addr_t base, const struct vote_clk *vclk) -{ - u32 val; - - setbits_le32(base + vclk->ena_vote, vclk->vote_bit); - do { - val = readl(base + vclk->cbcr_reg); - val &= BRANCH_CHECK_MASK; - } while ((val != BRANCH_ON_VAL) && (val != BRANCH_NOC_FSM_ON_VAL)); -} - -#define APPS_CMD_RCGR_UPDATE BIT(0) - -/* Update clock command via CMD_RCGR */ -void clk_bcr_update(phys_addr_t apps_cmd_rcgr) -{ - setbits_le32(apps_cmd_rcgr, APPS_CMD_RCGR_UPDATE); - - /* Wait for frequency to be updated. */ - while (readl(apps_cmd_rcgr) & APPS_CMD_RCGR_UPDATE) - ; -} - -#define CFG_MODE_DUAL_EDGE (0x2 << 12) /* Counter mode */ - -#define CFG_MASK 0x3FFF - -#define CFG_DIVIDER_MASK 0x1F - -/* root set rate for clocks with half integer and MND divider */ -void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs, - int div, int m, int n, int source) -{ - u32 cfg; - /* M value for MND divider. */ - u32 m_val = m; - /* NOT(N-M) value for MND divider. */ - u32 n_val = ~((n) - (m)) * !!(n); - /* NOT 2D value for MND divider. */ - u32 d_val = ~(n); - - /* Program MND values */ - writel(m_val, base + regs->M); - writel(n_val, base + regs->N); - writel(d_val, base + regs->D); - - /* setup src select and divider */ - cfg = readl(base + regs->cfg_rcgr); - cfg &= ~CFG_MASK; - cfg |= source & CFG_CLK_SRC_MASK; /* Select clock source */ - - /* Set the divider; HW permits fraction dividers (+0.5), but - for simplicity, we will support integers only */ - if (div) - cfg |= (2 * div - 1) & CFG_DIVIDER_MASK; - - if (n_val) - cfg |= CFG_MODE_DUAL_EDGE; - - writel(cfg, base + regs->cfg_rcgr); /* Write new clock configuration */ - - /* Inform h/w to start using the new config. */ - clk_bcr_update(base + regs->cmd_rcgr); -} - -/* root set rate for clocks with half integer and mnd_width=0 */ -void clk_rcg_set_rate(phys_addr_t base, const struct bcr_regs *regs, int div, - int source) -{ - u32 cfg; - - /* setup src select and divider */ - cfg = readl(base + regs->cfg_rcgr); - cfg &= ~CFG_MASK; - cfg |= source & CFG_CLK_SRC_MASK; /* Select clock source */ - - /* - * Set the divider; HW permits fraction dividers (+0.5), but - * for simplicity, we will support integers only - */ - if (div) - cfg |= (2 * div - 1) & CFG_DIVIDER_MASK; - - writel(cfg, base + regs->cfg_rcgr); /* Write new clock configuration */ - - /* Inform h/w to start using the new config. */ - clk_bcr_update(base + regs->cmd_rcgr); -} - -static int msm_clk_probe(struct udevice *dev) -{ - struct msm_clk_priv *priv = dev_get_priv(dev); - - priv->base = dev_read_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 int msm_clk_enable(struct clk *clk) -{ - return msm_enable(clk); -} - -static struct clk_ops msm_clk_ops = { - .set_rate = msm_clk_set_rate, - .enable = msm_clk_enable, -}; - -static const struct udevice_id msm_clk_ids[] = { - { .compatible = "qcom,gcc-msm8916" }, - { .compatible = "qcom,gcc-apq8016" }, - { .compatible = "qcom,gcc-msm8996" }, - { .compatible = "qcom,gcc-apq8096" }, - { .compatible = "qcom,gcc-sdm845" }, - { .compatible = "qcom,gcc-qcs404" }, - { } -}; - -U_BOOT_DRIVER(clk_msm) = { - .name = "clk_msm", - .id = UCLASS_CLK, - .of_match = msm_clk_ids, - .ops = &msm_clk_ops, - .priv_auto = sizeof(struct msm_clk_priv), - .probe = msm_clk_probe, -}; diff --git a/arch/arm/mach-snapdragon/clock-snapdragon.h b/arch/arm/mach-snapdragon/clock-snapdragon.h deleted file mode 100644 index c90bbef..0000000 --- a/arch/arm/mach-snapdragon/clock-snapdragon.h +++ /dev/null @@ -1,48 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Qualcomm APQ8016, APQ8096, SDM845 - * - * (C) Copyright 2017 Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org> - */ -#ifndef _CLOCK_SNAPDRAGON_H -#define _CLOCK_SNAPDRAGON_H - -#define CFG_CLK_SRC_CXO (0 << 8) -#define CFG_CLK_SRC_GPLL0 (1 << 8) -#define CFG_CLK_SRC_GPLL0_EVEN (6 << 8) -#define CFG_CLK_SRC_MASK (7 << 8) - -struct pll_vote_clk { - uintptr_t status; - int status_bit; - uintptr_t ena_vote; - int vote_bit; -}; - -struct vote_clk { - uintptr_t cbcr_reg; - uintptr_t ena_vote; - int vote_bit; -}; -struct bcr_regs { - uintptr_t cfg_rcgr; - uintptr_t cmd_rcgr; - uintptr_t M; - uintptr_t N; - uintptr_t D; -}; - -struct msm_clk_priv { - phys_addr_t base; -}; - -void clk_enable_gpll0(phys_addr_t base, const struct pll_vote_clk *gpll0); -void clk_bcr_update(phys_addr_t apps_cmd_rgcr); -void clk_enable_cbc(phys_addr_t cbcr); -void clk_enable_vote_clk(phys_addr_t base, const struct vote_clk *vclk); -void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs, - int div, int m, int n, int source); -void clk_rcg_set_rate(phys_addr_t base, const struct bcr_regs *regs, int div, - int source); - -#endif diff --git a/arch/arm/mach-snapdragon/include/mach/gpio.h b/arch/arm/mach-snapdragon/include/mach/gpio.h index bbc2bc1..8dac62f 100644 --- a/arch/arm/mach-snapdragon/include/mach/gpio.h +++ b/arch/arm/mach-snapdragon/include/mach/gpio.h @@ -1,8 +1,28 @@ /* SPDX-License-Identifier: GPL-2.0+ */ /* - * Empty gpio.h + * Qualcomm common pin control data. * - * This file must stay as arch/arm/include/asm/gpio.h requires it. - * - * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com> + * Copyright (C) 2023 Linaro Ltd. */ +#ifndef _QCOM_GPIO_H_ +#define _QCOM_GPIO_H_ + +#include <asm/types.h> +#include <stdbool.h> + +struct msm_pin_data { + int pin_count; + const unsigned int *pin_offsets; +}; + +static inline u32 qcom_pin_offset(const unsigned int *offs, unsigned int selector) +{ + u32 out = (selector * 0x1000); + + if (offs) + return out + offs[selector]; + + return out; +} + +#endif /* _QCOM_GPIO_H_ */ diff --git a/arch/arm/mach-snapdragon/include/mach/sysmap-apq8016.h b/arch/arm/mach-snapdragon/include/mach/sysmap-apq8016.h deleted file mode 100644 index d9a3b1a..0000000 --- a/arch/arm/mach-snapdragon/include/mach/sysmap-apq8016.h +++ /dev/null @@ -1,39 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Qualcomm APQ8916 sysmap - * - * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com> - */ -#ifndef _MACH_SYSMAP_APQ8016_H -#define _MACH_SYSMAP_APQ8016_H - -#define GICD_BASE (0x0b000000) -#define GICC_BASE (0x0b002000) - -/* Clocks: (from CLK_CTL_BASE) */ -#define GPLL0_STATUS (0x2101C) -#define APCS_GPLL_ENA_VOTE (0x45000) -#define APCS_CLOCK_BRANCH_ENA_VOTE (0x45004) - -#define SDCC_BCR(n) ((n * 0x1000) + 0x41000) -#define SDCC_CMD_RCGR(n) ((n * 0x1000) + 0x41004) -#define SDCC_CFG_RCGR(n) ((n * 0x1000) + 0x41008) -#define SDCC_M(n) ((n * 0x1000) + 0x4100C) -#define SDCC_N(n) ((n * 0x1000) + 0x41010) -#define SDCC_D(n) ((n * 0x1000) + 0x41014) -#define SDCC_APPS_CBCR(n) ((n * 0x1000) + 0x41018) -#define SDCC_AHB_CBCR(n) ((n * 0x1000) + 0x4101C) - -/* BLSP1 AHB clock (root clock for BLSP) */ -#define BLSP1_AHB_CBCR 0x1008 - -/* Uart clock control registers */ -#define BLSP1_UART2_BCR (0x3028) -#define BLSP1_UART2_APPS_CBCR (0x302C) -#define BLSP1_UART2_APPS_CMD_RCGR (0x3034) -#define BLSP1_UART2_APPS_CFG_RCGR (0x3038) -#define BLSP1_UART2_APPS_M (0x303C) -#define BLSP1_UART2_APPS_N (0x3040) -#define BLSP1_UART2_APPS_D (0x3044) - -#endif diff --git a/arch/arm/mach-snapdragon/include/mach/sysmap-apq8096.h b/arch/arm/mach-snapdragon/include/mach/sysmap-apq8096.h deleted file mode 100644 index 36a902b..0000000 --- a/arch/arm/mach-snapdragon/include/mach/sysmap-apq8096.h +++ /dev/null @@ -1,37 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Qualcomm APQ8096 sysmap - * - * (C) Copyright 2017 Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org> - */ -#ifndef _MACH_SYSMAP_APQ8096_H -#define _MACH_SYSMAP_APQ8096_H - -#define TLMM_BASE_ADDR (0x1010000) - -/* Strength (sdc1) */ -#define SDC1_HDRV_PULL_CTL_REG (TLMM_BASE_ADDR + 0x0012D000) - -/* Clocks: (from CLK_CTL_BASE) */ -#define GPLL0_STATUS (0x0000) -#define APCS_GPLL_ENA_VOTE (0x52000) -#define APCS_CLOCK_BRANCH_ENA_VOTE (0x52004) - -#define SDCC2_BCR (0x14000) /* block reset */ -#define SDCC2_APPS_CBCR (0x14004) /* branch control */ -#define SDCC2_AHB_CBCR (0x14008) -#define SDCC2_CMD_RCGR (0x14010) -#define SDCC2_CFG_RCGR (0x14014) -#define SDCC2_M (0x14018) -#define SDCC2_N (0x1401C) -#define SDCC2_D (0x14020) - -#define BLSP2_AHB_CBCR (0x25004) -#define BLSP2_UART2_APPS_CBCR (0x29004) -#define BLSP2_UART2_APPS_CMD_RCGR (0x2900C) -#define BLSP2_UART2_APPS_CFG_RCGR (0x29010) -#define BLSP2_UART2_APPS_M (0x29014) -#define BLSP2_UART2_APPS_N (0x29018) -#define BLSP2_UART2_APPS_D (0x2901C) - -#endif diff --git a/arch/arm/mach-snapdragon/include/mach/sysmap-qcs404.h b/arch/arm/mach-snapdragon/include/mach/sysmap-qcs404.h deleted file mode 100644 index 5768fb1..0000000 --- a/arch/arm/mach-snapdragon/include/mach/sysmap-qcs404.h +++ /dev/null @@ -1,88 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Qualcomm QCS404 sysmap - * - * (C) Copyright 2022 Sumit Garg <sumit.garg@linaro.org> - */ -#ifndef _MACH_SYSMAP_QCS404_H -#define _MACH_SYSMAP_QCS404_H - -#define GICD_BASE (0x0b000000) -#define GICC_BASE (0x0b002000) - -/* Clocks: (from CLK_CTL_BASE) */ -#define GPLL0_STATUS (0x21000) -#define GPLL1_STATUS (0x20000) -#define APCS_GPLL_ENA_VOTE (0x45000) -#define APCS_CLOCK_BRANCH_ENA_VOTE (0x45004) - -/* BLSP1 AHB clock (root clock for BLSP) */ -#define BLSP1_AHB_CBCR 0x1008 - -/* Uart clock control registers */ -#define BLSP1_UART2_BCR (0x3028) -#define BLSP1_UART2_APPS_CBCR (0x302C) -#define BLSP1_UART2_APPS_CMD_RCGR (0x3034) -#define BLSP1_UART2_APPS_CFG_RCGR (0x3038) -#define BLSP1_UART2_APPS_M (0x303C) -#define BLSP1_UART2_APPS_N (0x3040) -#define BLSP1_UART2_APPS_D (0x3044) - -/* I2C controller clock control registerss */ -#define BLSP1_QUP0_I2C_APPS_CBCR (0x6028) -#define BLSP1_QUP0_I2C_APPS_CMD_RCGR (0x602C) -#define BLSP1_QUP0_I2C_APPS_CFG_RCGR (0x6030) -#define BLSP1_QUP1_I2C_APPS_CBCR (0x2008) -#define BLSP1_QUP1_I2C_APPS_CMD_RCGR (0x200C) -#define BLSP1_QUP1_I2C_APPS_CFG_RCGR (0x2010) -#define BLSP1_QUP2_I2C_APPS_CBCR (0x3010) -#define BLSP1_QUP2_I2C_APPS_CMD_RCGR (0x3000) -#define BLSP1_QUP2_I2C_APPS_CFG_RCGR (0x3004) -#define BLSP1_QUP3_I2C_APPS_CBCR (0x4020) -#define BLSP1_QUP3_I2C_APPS_CMD_RCGR (0x4000) -#define BLSP1_QUP3_I2C_APPS_CFG_RCGR (0x4004) -#define BLSP1_QUP4_I2C_APPS_CBCR (0x5020) -#define BLSP1_QUP4_I2C_APPS_CMD_RCGR (0x5000) -#define BLSP1_QUP4_I2C_APPS_CFG_RCGR (0x5004) - -/* SD controller clock control registers */ -#define SDCC_BCR(n) (((n) * 0x1000) + 0x41000) -#define SDCC_CMD_RCGR(n) (((n) * 0x1000) + 0x41004) -#define SDCC_CFG_RCGR(n) (((n) * 0x1000) + 0x41008) -#define SDCC_M(n) (((n) * 0x1000) + 0x4100C) -#define SDCC_N(n) (((n) * 0x1000) + 0x41010) -#define SDCC_D(n) (((n) * 0x1000) + 0x41014) -#define SDCC_APPS_CBCR(n) (((n) * 0x1000) + 0x41018) -#define SDCC_AHB_CBCR(n) (((n) * 0x1000) + 0x4101C) - -/* USB-3.0 controller clock control registers */ -#define SYS_NOC_USB3_CBCR (0x26014) -#define USB30_BCR (0x39000) -#define USB3PHY_BCR (0x39008) -#define USB30_MASTER_CBCR (0x3900C) -#define USB30_SLEEP_CBCR (0x39010) -#define USB30_MOCK_UTMI_CBCR (0x39014) -#define USB30_MOCK_UTMI_CMD_RCGR (0x3901C) -#define USB30_MOCK_UTMI_CFG_RCGR (0x39020) -#define USB30_MASTER_CMD_RCGR (0x39028) -#define USB30_MASTER_CFG_RCGR (0x3902C) -#define USB30_MASTER_M (0x39030) -#define USB30_MASTER_N (0x39034) -#define USB30_MASTER_D (0x39038) -#define USB2A_PHY_SLEEP_CBCR (0x4102C) -#define USB_HS_PHY_CFG_AHB_CBCR (0x41030) - -/* ETH controller clock control registers */ -#define ETH_PTP_CBCR (0x4e004) -#define ETH_RGMII_CBCR (0x4e008) -#define ETH_SLAVE_AHB_CBCR (0x4e00c) -#define ETH_AXI_CBCR (0x4e010) -#define EMAC_PTP_CMD_RCGR (0x4e014) -#define EMAC_PTP_CFG_RCGR (0x4e018) -#define EMAC_CMD_RCGR (0x4e01c) -#define EMAC_CFG_RCGR (0x4e020) -#define EMAC_M (0x4e024) -#define EMAC_N (0x4e028) -#define EMAC_D (0x4e02c) - -#endif diff --git a/arch/arm/mach-snapdragon/include/mach/sysmap-sdm845.h b/arch/arm/mach-snapdragon/include/mach/sysmap-sdm845.h deleted file mode 100644 index 7165985..0000000 --- a/arch/arm/mach-snapdragon/include/mach/sysmap-sdm845.h +++ /dev/null @@ -1,42 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Qualcomm SDM845 sysmap - * - * (C) Copyright 2021 Dzmitry Sankouski <dsankouski@gmail.com> - */ -#ifndef _MACH_SYSMAP_SDM845_H -#define _MACH_SYSMAP_SDM845_H - -#define TLMM_BASE_ADDR (0x1010000) - -/* Strength (sdc1) */ -#define SDC1_HDRV_PULL_CTL_REG (TLMM_BASE_ADDR + 0x0012D000) - -/* Clocks: (from CLK_CTL_BASE) */ -#define GPLL0_STATUS (0x0000) -#define APCS_GPLL_ENA_VOTE (0x52000) -#define APCS_CLOCK_BRANCH_ENA_VOTE (0x52004) - -#define SDCC2_BCR (0x14000) /* block reset */ -#define SDCC2_APPS_CBCR (0x14004) /* branch control */ -#define SDCC2_AHB_CBCR (0x14008) -#define SDCC2_CMD_RCGR (0x1400c) -#define SDCC2_CFG_RCGR (0x14010) -#define SDCC2_M (0x14014) -#define SDCC2_N (0x14018) -#define SDCC2_D (0x1401C) - -#define RCG2_CFG_REG 0x4 -#define M_REG 0x8 -#define N_REG 0xc -#define D_REG 0x10 - -#define SE9_AHB_CBCR (0x25004) -#define SE9_UART_APPS_CBCR (0x29004) -#define SE9_UART_APPS_CMD_RCGR (0x18148) -#define SE9_UART_APPS_CFG_RCGR (0x1814C) -#define SE9_UART_APPS_M (0x18150) -#define SE9_UART_APPS_N (0x18154) -#define SE9_UART_APPS_D (0x18158) - -#endif diff --git a/arch/arm/mach-snapdragon/init_sdm845.c b/arch/arm/mach-snapdragon/init_sdm845.c index 1f88502..067acc9 100644 --- a/arch/arm/mach-snapdragon/init_sdm845.c +++ b/arch/arm/mach-snapdragon/init_sdm845.c @@ -5,6 +5,7 @@ * (C) Copyright 2021 Dzmitry Sankouski <dsankouski@gmail.com> */ +#include <button.h> #include <init.h> #include <env.h> #include <common.h> @@ -32,46 +33,18 @@ __weak int board_init(void) /* Check for vol- and power buttons */ __weak int misc_init_r(void) { - struct udevice *pon; - struct gpio_desc resin; - int node, ret; + struct udevice *btn; + int ret; + enum button_state_t state; - ret = uclass_get_device_by_name(UCLASS_GPIO, "pm8998_pon@800", &pon); + ret = button_get_by_label("pwrkey", &btn); if (ret < 0) { - printf("Failed to find PMIC pon node. Check device tree\n"); - return 0; + printf("Couldn't find power button!\n"); + return ret; } - node = fdt_subnode_offset(gd->fdt_blob, dev_of_offset(pon), - "key_vol_down"); - if (node < 0) { - printf("Failed to find key_vol_down node. Check device tree\n"); - return 0; - } - if (gpio_request_by_name_nodev(offset_to_ofnode(node), "gpios", 0, - &resin, 0)) { - printf("Failed to request key_vol_down button.\n"); - return 0; - } - if (dm_gpio_get_value(&resin)) { - env_set("key_vol_down", "1"); - printf("Volume down button pressed\n"); - } else { - env_set("key_vol_down", "0"); - } - - node = fdt_subnode_offset(gd->fdt_blob, dev_of_offset(pon), - "key_power"); - if (node < 0) { - printf("Failed to find key_power node. Check device tree\n"); - return 0; - } - if (gpio_request_by_name_nodev(offset_to_ofnode(node), "gpios", 0, - &resin, 0)) { - printf("Failed to request key_power button.\n"); - return 0; - } - if (dm_gpio_get_value(&resin)) { + state = button_get_state(btn); + if (state == BUTTON_ON) { env_set("key_power", "1"); printf("Power button pressed\n"); } else { diff --git a/arch/arm/mach-snapdragon/pinctrl-sdm845.c b/arch/arm/mach-snapdragon/pinctrl-sdm845.c deleted file mode 100644 index 40f2f01..0000000 --- a/arch/arm/mach-snapdragon/pinctrl-sdm845.c +++ /dev/null @@ -1,44 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Qualcomm SDM845 pinctrl - * - * (C) Copyright 2021 Dzmitry Sankouski <dsankouski@gmail.com> - * - */ - -#include "pinctrl-snapdragon.h" -#include <common.h> - -#define MAX_PIN_NAME_LEN 32 -static char pin_name[MAX_PIN_NAME_LEN] __section(".data"); - -static const struct pinctrl_function msm_pinctrl_functions[] = { - {"qup9", 1}, - {"gpio", 0}, -}; - -static const char *sdm845_get_function_name(struct udevice *dev, - unsigned int selector) -{ - return msm_pinctrl_functions[selector].name; -} - -static const char *sdm845_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 sdm845_get_function_mux(unsigned int selector) -{ - return msm_pinctrl_functions[selector].val; -} - -struct msm_pinctrl_data sdm845_data = { - .pin_count = 150, - .functions_count = ARRAY_SIZE(msm_pinctrl_functions), - .get_function_name = sdm845_get_function_name, - .get_function_mux = sdm845_get_function_mux, - .get_pin_name = sdm845_get_pin_name, -}; diff --git a/arch/arm/mach-snapdragon/pinctrl-snapdragon.h b/arch/arm/mach-snapdragon/pinctrl-snapdragon.h deleted file mode 100644 index 178ee01..0000000 --- a/arch/arm/mach-snapdragon/pinctrl-snapdragon.h +++ /dev/null @@ -1,33 +0,0 @@ -/* 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 - -struct udevice; - -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 apq8016_data; -extern struct msm_pinctrl_data apq8096_data; -extern struct msm_pinctrl_data sdm845_data; -extern struct msm_pinctrl_data qcs404_data; - -#endif diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index 4fe7266..e264b29 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -1544,10 +1544,10 @@ spmi_gpios: gpios@c000 { compatible = "qcom,pm8916-gpio"; reg = <0xc000 0x400>; + gpio-ranges = <&spmi_gpios 0 0 4>; gpio-controller; gpio-count = <4>; #gpio-cells = <2>; - gpio-bank-name="spmi"; }; }; }; diff --git a/board/qualcomm/dragonboard410c/dragonboard410c.c b/board/qualcomm/dragonboard410c/dragonboard410c.c index 371b326..350e0e9 100644 --- a/board/qualcomm/dragonboard410c/dragonboard410c.c +++ b/board/qualcomm/dragonboard410c/dragonboard410c.c @@ -5,6 +5,7 @@ * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com> */ +#include <button.h> #include <common.h> #include <cpu_func.h> #include <dm.h> @@ -108,32 +109,20 @@ int board_usb_init(int index, enum usb_init_type init) /* Check for vol- button - if pressed - stop autoboot */ int misc_init_r(void) { - struct udevice *pon; - struct gpio_desc resin; - int node, ret; + struct udevice *btn; + int ret; + enum button_state_t state; - ret = uclass_get_device_by_name(UCLASS_GPIO, "pm8916_pon@800", &pon); + ret = button_get_by_label("vol_down", &btn); if (ret < 0) { - printf("Failed to find PMIC pon node. Check device tree\n"); - return 0; + printf("Couldn't find power button!\n"); + return ret; } - node = fdt_subnode_offset(gd->fdt_blob, dev_of_offset(pon), - "key_vol_down"); - if (node < 0) { - printf("Failed to find key_vol_down node. Check device tree\n"); - return 0; - } - - if (gpio_request_by_name_nodev(offset_to_ofnode(node), "gpios", 0, - &resin, 0)) { - printf("Failed to request key_vol_down button.\n"); - return 0; - } - - if (dm_gpio_get_value(&resin)) { + state = button_get_state(btn); + if (state == BUTTON_ON) { env_set("preboot", "setenv preboot; fastboot 0"); - printf("key_vol_down pressed - Starting fastboot.\n"); + printf("vol_down pressed - Starting fastboot.\n"); } return 0; diff --git a/board/qualcomm/dragonboard820c/dragonboard820c.c b/board/qualcomm/dragonboard820c/dragonboard820c.c index f9cc762..2f0db62 100644 --- a/board/qualcomm/dragonboard820c/dragonboard820c.c +++ b/board/qualcomm/dragonboard820c/dragonboard820c.c @@ -5,9 +5,9 @@ * (C) Copyright 2017 Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org> */ +#include <button.h> #include <cpu_func.h> #include <init.h> -#include <asm/arch/sysmap-apq8096.h> #include <env.h> #include <asm/cache.h> #include <asm/global_data.h> @@ -20,6 +20,11 @@ #include <asm/psci.h> #include <asm/gpio.h> +#define TLMM_BASE_ADDR (0x1010000) + +/* Strength (sdc1) */ +#define SDC1_HDRV_PULL_CTL_REG (TLMM_BASE_ADDR + 0x0012D000) + DECLARE_GLOBAL_DATA_PTR; int dram_init(void) @@ -135,30 +140,18 @@ void reset_cpu(void) /* Check for vol- button - if pressed - stop autoboot */ int misc_init_r(void) { - struct udevice *pon; - struct gpio_desc resin; - int node, ret; + struct udevice *btn; + int ret; + enum button_state_t state; - ret = uclass_get_device_by_name(UCLASS_GPIO, "pm8994_pon@800", &pon); + ret = button_get_by_label("pwrkey", &btn); if (ret < 0) { - printf("Failed to find PMIC pon node. Check device tree\n"); - return 0; - } - - node = fdt_subnode_offset(gd->fdt_blob, dev_of_offset(pon), - "key_vol_down"); - if (node < 0) { - printf("Failed to find key_vol_down node. Check device tree\n"); - return 0; - } - - if (gpio_request_by_name_nodev(offset_to_ofnode(node), "gpios", 0, - &resin, 0)) { - printf("Failed to request key_vol_down button.\n"); - return 0; + printf("Couldn't find power button!\n"); + return ret; } - if (dm_gpio_get_value(&resin)) { + state = button_get_state(btn); + if (state == BUTTON_ON) { env_set("bootdelay", "-1"); printf("Power button pressed - dropping to console.\n"); } diff --git a/configs/sandbox_flattree_defconfig b/configs/sandbox_flattree_defconfig index 1bd9109..36f384b 100644 --- a/configs/sandbox_flattree_defconfig +++ b/configs/sandbox_flattree_defconfig @@ -101,6 +101,9 @@ CONFIG_SYS_ATA_DATA_OFFSET=0 CONFIG_SYS_ATA_REG_OFFSET=1 CONFIG_SYS_ATA_ALT_OFFSET=2 CONFIG_SYS_ATA_IDE0_OFFSET=0 +CONFIG_BUTTON=y +CONFIG_BUTTON_ADC=y +CONFIG_BUTTON_GPIO=y CONFIG_CLK=y CONFIG_CLK_COMPOSITE_CCF=y CONFIG_CLK_K210=y diff --git a/doc/device-tree-bindings/gpio/pm8916_gpio.txt b/doc/device-tree-bindings/gpio/pm8916_gpio.txt deleted file mode 100644 index 58185b8..0000000 --- a/doc/device-tree-bindings/gpio/pm8916_gpio.txt +++ /dev/null @@ -1,48 +0,0 @@ -Driver for part of pm8916 PMIC - gpio and power/reset keys - -This device should be child of SPMI pmic. - -1) GPIO driver - -Required properties: -- compatible: "qcom,pm8916-gpio" -- reg: peripheral ID, size of register block -- gpio-controller -- gpio-count: number of GPIOs -- #gpio-cells: 2 - -Optional properties: -- gpio-bank-name: name of bank (as default "pm8916" is used) - -Example: - -pmic_gpios: gpios@c000 { - compatible = "qcom,pm8916-gpio"; - reg = <0xc000 0x400>; - gpio-controller; - gpio-count = <4>; - #gpio-cells = <2>; - gpio-bank-name="pmic"; -}; - - -2) Power/Reset key driver - -Required properties: -- compatible: "qcom,pm8916-pwrkey" -- reg: peripheral ID, size of register block -- gpio-controller -- #gpio-cells: 2 - -Optional properties: -- gpio-bank-name: name of bank (as default "pm8916_key" is used) - - -Example: - -pmic_pon: pon@800 { - compatible = "qcom,pm8916-pwrkey"; - reg = <0x800 0x96>; - #gpio-cells = <2>; - gpio-controller; -}; diff --git a/doc/device-tree-bindings/pmic/qcom,spmi-pmic.txt b/doc/device-tree-bindings/pmic/qcom,spmi-pmic.txt deleted file mode 100644 index eb78e3a..0000000 --- a/doc/device-tree-bindings/pmic/qcom,spmi-pmic.txt +++ /dev/null @@ -1,94 +0,0 @@ - Qualcomm SPMI PMICs multi-function device bindings - -The Qualcomm SPMI series presently includes PM8941, PM8841 and PMA8084 -PMICs. These PMICs use a QPNP scheme through SPMI interface. -QPNP is effectively a partitioning scheme for dividing the SPMI extended -register space up into logical pieces, and set of fixed register -locations/definitions within these regions, with some of these regions -specifically used for interrupt handling. - -The QPNP PMICs are used with the Qualcomm Snapdragon series SoCs, and are -interfaced to the chip via the SPMI (System Power Management Interface) bus. -Support for multiple independent functions are implemented by splitting the -16-bit SPMI slave address space into 256 smaller fixed-size regions, 256 bytes -each. A function can consume one or more of these fixed-size register regions. - -Required properties: -- compatible: Should contain one of: - "qcom,pm660", - "qcom,pm660l", - "qcom,pm7325", - "qcom,pm8004", - "qcom,pm8005", - "qcom,pm8019", - "qcom,pm8028", - "qcom,pm8110", - "qcom,pm8150", - "qcom,pm8150b", - "qcom,pm8150c", - "qcom,pm8150l", - "qcom,pm8226", - "qcom,pm8350c", - "qcom,pm8841", - "qcom,pm8901", - "qcom,pm8909", - "qcom,pm8916", - "qcom,pm8941", - "qcom,pm8950", - "qcom,pm8953", - "qcom,pm8994", - "qcom,pm8998", - "qcom,pma8084", - "qcom,pmd9635", - "qcom,pmi8950", - "qcom,pmi8962", - "qcom,pmi8994", - "qcom,pmi8998", - "qcom,pmk8002", - "qcom,pmk8350", - "qcom,pmr735a", - "qcom,smb2351", - or generalized "qcom,spmi-pmic". -- reg: Specifies the SPMI USID slave address for this device. - For more information see: - Documentation/devicetree/bindings/spmi/spmi.yaml - -Required properties for peripheral child nodes: -- compatible: Should contain "qcom,xxx", where "xxx" is a peripheral name. - -Optional properties for peripheral child nodes: -- interrupts: Interrupts are specified as a 4-tuple. For more information - see: - Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb.yaml -- interrupt-names: Corresponding interrupt name to the interrupts property - -Each child node of SPMI slave id represents a function of the PMIC. In the -example below the rtc device node represents a peripheral of pm8941 -SID = 0. The regulator device node represents a peripheral of pm8941 SID = 1. - -Example: - - spmi { - compatible = "qcom,spmi-pmic-arb"; - - pm8941@0 { - compatible = "qcom,pm8941", "qcom,spmi-pmic"; - reg = <0x0 SPMI_USID>; - - rtc { - compatible = "qcom,rtc"; - interrupts = <0x0 0x61 0x1 IRQ_TYPE_EDGE_RISING>; - interrupt-names = "alarm"; - }; - }; - - pm8941@1 { - compatible = "qcom,pm8941", "qcom,spmi-pmic"; - reg = <0x1 SPMI_USID>; - - regulator { - compatible = "qcom,regulator"; - regulator-name = "8941_boost"; - }; - }; - }; diff --git a/doc/device-tree-bindings/spmi/spmi-msm.txt b/doc/device-tree-bindings/spmi/spmi-msm.txt deleted file mode 100644 index ae47673..0000000 --- a/doc/device-tree-bindings/spmi/spmi-msm.txt +++ /dev/null @@ -1,26 +0,0 @@ -Qualcomm SPMI arbiter/bus driver - -This is bus driver for Qualcomm chips that use SPMI to communicate with PMICs. - -Required properties: -- compatible: "qcom,spmi-pmic-arb" -- reg: Register block adresses and sizes for various parts of device: - 1) PMIC arbiter channel mapping base (PMIC_ARB_REG_CHNLn) - 2) SPMI write command (master) registers (PMIC_ARB_CORE_SW_DEC_CHANNELS) - 3) SPMI read command (observer) registers (PMIC_ARB_CORE_REGISTERS_OBS) - -Optional properties (if not set by parent): -- #address-cells: 0x1 - childs slave ID address -- #size-cells: 0x1 - -All PMICs should be placed as a child nodes of bus arbiter. -Automatic detection of childs is currently not supported. - -Example: - -spmi@200f000 { - compatible = "qcom,spmi-pmic-arb"; - reg = <0x200f800 0x200 0x2400000 0x400000 0x2c00000 0x400000>; - #address-cells = <0x1>; - #size-cells = <0x1>; -}; diff --git a/drivers/button/Kconfig b/drivers/button/Kconfig index 8ce2de3..097b05f 100644 --- a/drivers/button/Kconfig +++ b/drivers/button/Kconfig @@ -27,4 +27,13 @@ config BUTTON_GPIO The GPIO driver must used driver model. Buttons are configured using the device tree. +config BUTTON_QCOM_PMIC + bool "Qualcomm power button" + depends on BUTTON + depends on PMIC_QCOM + help + Enable support for the power and "resin" (usually volume down) buttons + on Qualcomm SoCs. These will be configured as the Enter and Down keys + respectively, allowing navigation of bootmenu with buttons on device. + endmenu diff --git a/drivers/button/Makefile b/drivers/button/Makefile index bbd18af..6855508 100644 --- a/drivers/button/Makefile +++ b/drivers/button/Makefile @@ -5,3 +5,4 @@ obj-$(CONFIG_BUTTON) += button-uclass.o obj-$(CONFIG_BUTTON_ADC) += button-adc.o obj-$(CONFIG_BUTTON_GPIO) += button-gpio.o +obj-$(CONFIG_BUTTON_QCOM_PMIC) += button-qcom-pmic.o
\ No newline at end of file diff --git a/drivers/button/button-qcom-pmic.c b/drivers/button/button-qcom-pmic.c new file mode 100644 index 0000000..34a976d --- /dev/null +++ b/drivers/button/button-qcom-pmic.c @@ -0,0 +1,165 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Qualcomm generic pmic gpio driver + * + * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com> + * (C) Copyright 2023 Linaro Ltd. + */ + +#include <button.h> +#include <dt-bindings/input/linux-event-codes.h> +#include <dm.h> +#include <dm/device-internal.h> +#include <dm/lists.h> +#include <log.h> +#include <power/pmic.h> +#include <spmi/spmi.h> +#include <linux/bitops.h> + +#define REG_TYPE 0x4 +#define REG_SUBTYPE 0x5 + +struct qcom_pmic_btn_priv { + u32 base; + u32 status_bit; + int code; + struct udevice *pmic; +}; + +#define PON_INT_RT_STS 0x10 +#define KPDPWR_ON_INT_BIT 0 +#define RESIN_ON_INT_BIT 1 + +#define NODE_IS_PWRKEY(node) (!strncmp(ofnode_get_name(node), "pwrkey", strlen("pwrkey"))) +#define NODE_IS_RESIN(node) (!strncmp(ofnode_get_name(node), "resin", strlen("resin"))) + +static enum button_state_t qcom_pwrkey_get_state(struct udevice *dev) +{ + struct qcom_pmic_btn_priv *priv = dev_get_priv(dev); + + int reg = pmic_reg_read(priv->pmic, priv->base + PON_INT_RT_STS); + + if (reg < 0) + return 0; + + return (reg & BIT(priv->status_bit)) != 0; +} + +static int qcom_pwrkey_get_code(struct udevice *dev) +{ + struct qcom_pmic_btn_priv *priv = dev_get_priv(dev); + + return priv->code; +} + +static int qcom_pwrkey_probe(struct udevice *dev) +{ + struct button_uc_plat *uc_plat = dev_get_uclass_plat(dev); + struct qcom_pmic_btn_priv *priv = dev_get_priv(dev); + ofnode node = dev_ofnode(dev); + int ret; + u64 base; + + /* Ignore the top-level pon node */ + if (!uc_plat->label) + return 0; + + /* the pwrkey and resin nodes are children of the "pon" node, get the + * PMIC device to use in pmic_reg_* calls. + */ + priv->pmic = dev->parent->parent; + + /* Get the address of the parent pon node */ + base = dev_read_addr(dev->parent); + if (base == FDT_ADDR_T_NONE) { + printf("%s: Can't find address\n", dev->name); + return -EINVAL; + } + + priv->base = base; + + /* Do a sanity check */ + ret = pmic_reg_read(priv->pmic, priv->base + REG_TYPE); + if (ret != 0x1 && ret != 0xb) { + printf("%s: unexpected PMIC function type %d\n", dev->name, ret); + return -ENXIO; + } + + ret = pmic_reg_read(priv->pmic, priv->base + REG_SUBTYPE); + if ((ret & 0x7) == 0) { + printf("%s: unexpected PMCI function subtype %d\n", dev->name, ret); + return -ENXIO; + } + + if (NODE_IS_PWRKEY(node)) { + priv->status_bit = 0; + priv->code = KEY_ENTER; + } else if (NODE_IS_RESIN(node)) { + priv->status_bit = 1; + priv->code = KEY_DOWN; + } else { + /* Should not get here! */ + printf("Invalid pon node '%s' should be 'pwrkey' or 'resin'\n", + ofnode_get_name(node)); + return -EINVAL; + } + + return 0; +} + +static int button_qcom_pmic_bind(struct udevice *parent) +{ + struct udevice *dev; + ofnode node; + int ret; + + dev_for_each_subnode(node, parent) { + struct button_uc_plat *uc_plat; + const char *label; + + if (!ofnode_is_enabled(node)) + continue; + + ret = device_bind_driver_to_node(parent, "qcom_pwrkey", + ofnode_get_name(node), + node, &dev); + if (ret) { + printf("Failed to bind %s! %d\n", label, ret); + return ret; + } + uc_plat = dev_get_uclass_plat(dev); + if (NODE_IS_PWRKEY(node)) { + uc_plat->label = "pwrkey"; + } else if (NODE_IS_RESIN(node)) { + uc_plat->label = "vol_down"; + } else { + printf("Unknown button node '%s' should be 'pwrkey' or 'resin'\n", + ofnode_get_name(node)); + device_unbind(dev); + } + } + + return 0; +} + +static const struct button_ops button_qcom_pmic_ops = { + .get_state = qcom_pwrkey_get_state, + .get_code = qcom_pwrkey_get_code, +}; + +static const struct udevice_id qcom_pwrkey_ids[] = { + { .compatible = "qcom,pm8916-pon" }, + { .compatible = "qcom,pm8941-pon" }, + { .compatible = "qcom,pm8998-pon" }, + { } +}; + +U_BOOT_DRIVER(qcom_pwrkey) = { + .name = "qcom_pwrkey", + .id = UCLASS_BUTTON, + .of_match = qcom_pwrkey_ids, + .bind = button_qcom_pmic_bind, + .probe = qcom_pwrkey_probe, + .ops = &button_qcom_pmic_ops, + .priv_auto = sizeof(struct qcom_pmic_btn_priv), +}; diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index bfd23a9..017dd26 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -254,6 +254,7 @@ source "drivers/clk/meson/Kconfig" source "drivers/clk/microchip/Kconfig" source "drivers/clk/mvebu/Kconfig" source "drivers/clk/owl/Kconfig" +source "drivers/clk/qcom/Kconfig" source "drivers/clk/renesas/Kconfig" source "drivers/clk/sunxi/Kconfig" source "drivers/clk/sifive/Kconfig" diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index af27ceb..638ad04 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -39,6 +39,7 @@ obj-$(CONFIG_CLK_MPFS) += microchip/ obj-$(CONFIG_CLK_MVEBU) += mvebu/ obj-$(CONFIG_CLK_OCTEON) += clk_octeon.o obj-$(CONFIG_CLK_OWL) += owl/ +obj-$(CONFIG_CLK_QCOM) += qcom/ obj-$(CONFIG_CLK_RENESAS) += renesas/ obj-$(CONFIG_$(SPL_TPL_)CLK_SCMI) += clk_scmi.o obj-$(CONFIG_CLK_SIFIVE) += sifive/ diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig new file mode 100644 index 0000000..0df0d18 --- /dev/null +++ b/drivers/clk/qcom/Kconfig @@ -0,0 +1,52 @@ +if ARCH_SNAPDRAGON || ARCH_IPQ40XX + +config CLK_QCOM + bool + depends on CLK && DM_RESET + def_bool n + +menu "Qualcomm clock drivers" + +config CLK_QCOM_APQ8016 + bool "Qualcomm APQ8016 GCC" + select CLK_QCOM + help + Say Y here to enable support for the Global Clock Controller + on the Snapdragon APQ8016 SoC. This driver supports the clocks + and resets exposed by the GCC hardware block. + +config CLK_QCOM_APQ8096 + bool "Qualcomm APQ8096 GCC" + select CLK_QCOM + help + Say Y here to enable support for the Global Clock Controller + on the Snapdragon APQ8096 SoC. This driver supports the clocks + and resets exposed by the GCC hardware block. + +config CLK_QCOM_IPQ4019 + bool "Qualcomm IPQ4019 GCC" + select CLK_QCOM + help + Say Y here to enable support for the Global Clock Controller + on the Snapdragon IPQ4019 SoC. This driver supports the clocks + and resets exposed by the GCC hardware block. + +config CLK_QCOM_QCS404 + bool "Qualcomm QCS404 GCC" + select CLK_QCOM + help + Say Y here to enable support for the Global Clock Controller + on the Snapdragon QCS404 SoC. This driver supports the clocks + and resets exposed by the GCC hardware block. + +config CLK_QCOM_SDM845 + bool "Qualcomm SDM845 GCC" + select CLK_QCOM + help + Say Y here to enable support for the Global Clock Controller + on the Snapdragon 845 SoC. This driver supports the clocks + and resets exposed by the GCC hardware block. + +endmenu + +endif diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile new file mode 100644 index 0000000..cb179fd --- /dev/null +++ b/drivers/clk/qcom/Makefile @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# (C) Copyright 2023 Linaro + +obj-y += clock-qcom.o +obj-$(CONFIG_CLK_QCOM_SDM845) += clock-sdm845.o +obj-$(CONFIG_CLK_QCOM_APQ8016) += clock-apq8016.o +obj-$(CONFIG_CLK_QCOM_APQ8096) += clock-apq8096.o +obj-$(CONFIG_CLK_QCOM_IPQ4019) += clock-ipq4019.o +obj-$(CONFIG_CLK_QCOM_QCS404) += clock-qcs404.o diff --git a/arch/arm/mach-snapdragon/clock-apq8016.c b/drivers/clk/qcom/clock-apq8016.c index 23a37a1..c0ce570 100644 --- a/arch/arm/mach-snapdragon/clock-apq8016.c +++ b/drivers/clk/qcom/clock-apq8016.c @@ -13,7 +13,34 @@ #include <errno.h> #include <asm/io.h> #include <linux/bitops.h> -#include "clock-snapdragon.h" + +#include "clock-qcom.h" + +/* Clocks: (from CLK_CTL_BASE) */ +#define GPLL0_STATUS (0x2101C) +#define APCS_GPLL_ENA_VOTE (0x45000) +#define APCS_CLOCK_BRANCH_ENA_VOTE (0x45004) + +#define SDCC_BCR(n) ((n * 0x1000) + 0x41000) +#define SDCC_CMD_RCGR(n) ((n * 0x1000) + 0x41004) +#define SDCC_CFG_RCGR(n) ((n * 0x1000) + 0x41008) +#define SDCC_M(n) ((n * 0x1000) + 0x4100C) +#define SDCC_N(n) ((n * 0x1000) + 0x41010) +#define SDCC_D(n) ((n * 0x1000) + 0x41014) +#define SDCC_APPS_CBCR(n) ((n * 0x1000) + 0x41018) +#define SDCC_AHB_CBCR(n) ((n * 0x1000) + 0x4101C) + +/* BLSP1 AHB clock (root clock for BLSP) */ +#define BLSP1_AHB_CBCR 0x1008 + +/* Uart clock control registers */ +#define BLSP1_UART2_BCR (0x3028) +#define BLSP1_UART2_APPS_CBCR (0x302C) +#define BLSP1_UART2_APPS_CMD_RCGR (0x3034) +#define BLSP1_UART2_APPS_CFG_RCGR (0x3038) +#define BLSP1_UART2_APPS_M (0x303C) +#define BLSP1_UART2_APPS_N (0x3040) +#define BLSP1_UART2_APPS_D (0x3044) /* GPLL0 clock control registers */ #define GPLL0_STATUS_ACTIVE BIT(17) @@ -51,7 +78,7 @@ static struct vote_clk gcc_blsp1_ahb_clk = { /* SDHCI */ static int clk_init_sdc(struct msm_clk_priv *priv, int slot, uint rate) { - int div = 8; /* 100MHz default */ + int div = 15; /* 100MHz default */ if (rate == 200000000) div = 4; @@ -59,7 +86,7 @@ static int clk_init_sdc(struct msm_clk_priv *priv, int slot, uint rate) clk_enable_cbc(priv->base + SDCC_AHB_CBCR(slot)); /* 800Mhz/div, gpll0 */ clk_rcg_set_rate_mnd(priv->base, &sdc_regs[slot], div, 0, 0, - CFG_CLK_SRC_GPLL0); + CFG_CLK_SRC_GPLL0, 8); clk_enable_gpll0(priv->base, &gpll0_vote_clk); clk_enable_cbc(priv->base + SDCC_APPS_CBCR(slot)); @@ -82,7 +109,7 @@ static int clk_init_uart(struct msm_clk_priv *priv) /* 7372800 uart block clock @ GPLL0 */ clk_rcg_set_rate_mnd(priv->base, &uart2_regs, 1, 144, 15625, - CFG_CLK_SRC_GPLL0); + CFG_CLK_SRC_GPLL0, 16); /* Vote for gpll0 clock */ clk_enable_gpll0(priv->base, &gpll0_vote_clk); @@ -93,7 +120,7 @@ static int clk_init_uart(struct msm_clk_priv *priv) return 0; } -ulong msm_set_rate(struct clk *clk, ulong rate) +static ulong apq8016_clk_set_rate(struct clk *clk, ulong rate) { struct msm_clk_priv *priv = dev_get_priv(clk->dev); @@ -112,7 +139,22 @@ ulong msm_set_rate(struct clk *clk, ulong rate) } } -int msm_enable(struct clk *clk) -{ - return 0; -} +static struct msm_clk_data apq8016_clk_data = { + .set_rate = apq8016_clk_set_rate, +}; + +static const struct udevice_id gcc_apq8016_of_match[] = { + { + .compatible = "qcom,gcc-apq8016", + .data = (ulong)&apq8016_clk_data, + }, + { } +}; + +U_BOOT_DRIVER(gcc_apq8016) = { + .name = "gcc_apq8016", + .id = UCLASS_NOP, + .of_match = gcc_apq8016_of_match, + .bind = qcom_cc_bind, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/arch/arm/mach-snapdragon/clock-apq8096.c b/drivers/clk/qcom/clock-apq8096.c index 6618459..cf1a347 100644 --- a/arch/arm/mach-snapdragon/clock-apq8096.c +++ b/drivers/clk/qcom/clock-apq8096.c @@ -13,7 +13,30 @@ #include <errno.h> #include <asm/io.h> #include <linux/bitops.h> -#include "clock-snapdragon.h" + +#include "clock-qcom.h" + +/* Clocks: (from CLK_CTL_BASE) */ +#define GPLL0_STATUS (0x0000) +#define APCS_GPLL_ENA_VOTE (0x52000) +#define APCS_CLOCK_BRANCH_ENA_VOTE (0x52004) + +#define SDCC2_BCR (0x14000) /* block reset */ +#define SDCC2_APPS_CBCR (0x14004) /* branch control */ +#define SDCC2_AHB_CBCR (0x14008) +#define SDCC2_CMD_RCGR (0x14010) +#define SDCC2_CFG_RCGR (0x14014) +#define SDCC2_M (0x14018) +#define SDCC2_N (0x1401C) +#define SDCC2_D (0x14020) + +#define BLSP2_AHB_CBCR (0x25004) +#define BLSP2_UART2_APPS_CBCR (0x29004) +#define BLSP2_UART2_APPS_CMD_RCGR (0x2900C) +#define BLSP2_UART2_APPS_CFG_RCGR (0x29010) +#define BLSP2_UART2_APPS_M (0x29014) +#define BLSP2_UART2_APPS_N (0x29018) +#define BLSP2_UART2_APPS_D (0x2901C) /* GPLL0 clock control registers */ #define GPLL0_STATUS_ACTIVE BIT(30) @@ -42,11 +65,11 @@ static struct vote_clk gcc_blsp2_ahb_clk = { static int clk_init_sdc(struct msm_clk_priv *priv, uint rate) { - int div = 3; + int div = 5; clk_enable_cbc(priv->base + SDCC2_AHB_CBCR); clk_rcg_set_rate_mnd(priv->base, &sdc_regs, div, 0, 0, - CFG_CLK_SRC_GPLL0); + CFG_CLK_SRC_GPLL0, 8); clk_enable_gpll0(priv->base, &gpll0_vote_clk); clk_enable_cbc(priv->base + SDCC2_APPS_CBCR); @@ -68,7 +91,7 @@ static int clk_init_uart(struct msm_clk_priv *priv) /* 7372800 uart block clock @ GPLL0 */ clk_rcg_set_rate_mnd(priv->base, &uart2_regs, 1, 192, 15625, - CFG_CLK_SRC_GPLL0); + CFG_CLK_SRC_GPLL0, 16); /* Vote for gpll0 clock */ clk_enable_gpll0(priv->base, &gpll0_vote_clk); @@ -79,7 +102,7 @@ static int clk_init_uart(struct msm_clk_priv *priv) return 0; } -ulong msm_set_rate(struct clk *clk, ulong rate) +static ulong apq8096_clk_set_rate(struct clk *clk, ulong rate) { struct msm_clk_priv *priv = dev_get_priv(clk->dev); @@ -94,7 +117,22 @@ ulong msm_set_rate(struct clk *clk, ulong rate) } } -int msm_enable(struct clk *clk) -{ - return 0; -} +static struct msm_clk_data apq8096_clk_data = { + .set_rate = apq8096_clk_set_rate, +}; + +static const struct udevice_id gcc_apq8096_of_match[] = { + { + .compatible = "qcom,gcc-apq8096", + .data = (ulong)&apq8096_clk_data, + }, + { } +}; + +U_BOOT_DRIVER(gcc_apq8096) = { + .name = "gcc_apq8096", + .id = UCLASS_NOP, + .of_match = gcc_apq8096_of_match, + .bind = qcom_cc_bind, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/drivers/reset/reset-qcom.c b/drivers/clk/qcom/clock-ipq4019.c index 94315e7..d693776 100644 --- a/drivers/reset/reset-qcom.c +++ b/drivers/clk/qcom/clock-ipq4019.c @@ -1,33 +1,55 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0+ /* + * Clock drivers for Qualcomm IPQ40xx + * * Copyright (c) 2020 Sartura Ltd. - * Copyright (c) 2022 Linaro Ltd. * * Author: Robert Marko <robert.marko@sartura.hr> - * Sumit Garg <sumit.garg@linaro.org> * - * Based on Linux driver */ -#include <asm/io.h> +#include <clk-uclass.h> #include <common.h> #include <dm.h> -#include <reset-uclass.h> -#include <linux/bitops.h> -#include <malloc.h> +#include <errno.h> +#include <dt-bindings/clock/qcom,gcc-ipq4019.h> -struct qcom_reset_priv { - phys_addr_t base; -}; +#include "clock-qcom.h" -struct qcom_reset_map { - unsigned int reg; - u8 bit; -}; +static ulong ipq4019_clk_set_rate(struct clk *clk, ulong rate) +{ + switch (clk->id) { + case GCC_BLSP1_UART1_APPS_CLK: /*UART1*/ + /* This clock is already initialized by SBL1 */ + return 0; + default: + return -EINVAL; + } +} -#ifdef CONFIG_ARCH_IPQ40XX -#include <dt-bindings/reset/qcom,ipq4019-reset.h> -static const struct qcom_reset_map gcc_qcom_resets[] = { +static int ipq4019_clk_enable(struct clk *clk) +{ + switch (clk->id) { + case GCC_BLSP1_QUP1_SPI_APPS_CLK: /*SPI1*/ + /* This clock is already initialized by SBL1 */ + return 0; + case GCC_PRNG_AHB_CLK: /*PRNG*/ + /* This clock is already initialized by SBL1 */ + return 0; + case GCC_USB3_MASTER_CLK: + case GCC_USB3_SLEEP_CLK: + case GCC_USB3_MOCK_UTMI_CLK: + case GCC_USB2_MASTER_CLK: + case GCC_USB2_SLEEP_CLK: + case GCC_USB2_MOCK_UTMI_CLK: + /* These clocks is already initialized by SBL1 */ + return 0; + default: + return -EINVAL; + } +} + +static const struct qcom_reset_map gcc_ipq4019_resets[] = { [WIFI0_CPU_INIT_RESET] = { 0x1f008, 5 }, [WIFI0_RADIO_SRIF_RESET] = { 0x1f008, 4 }, [WIFI0_RADIO_WARM_RESET] = { 0x1f008, 3 }, @@ -100,96 +122,26 @@ static const struct qcom_reset_map gcc_qcom_resets[] = { [GCC_MPM_BCR] = {0x24000, 0}, [GCC_SPDM_BCR] = {0x25000, 0}, }; -#endif - -#ifdef CONFIG_TARGET_QCS404EVB -#include <dt-bindings/clock/qcom,gcc-qcs404.h> -static const struct qcom_reset_map gcc_qcom_resets[] = { - [GCC_GENI_IR_BCR] = { 0x0F000 }, - [GCC_CDSP_RESTART] = { 0x18000 }, - [GCC_USB_HS_BCR] = { 0x41000 }, - [GCC_USB2_HS_PHY_ONLY_BCR] = { 0x41034 }, - [GCC_QUSB2_PHY_BCR] = { 0x4103c }, - [GCC_USB_HS_PHY_CFG_AHB_BCR] = { 0x0000c, 1 }, - [GCC_USB2A_PHY_BCR] = { 0x0000c, 0 }, - [GCC_USB3_PHY_BCR] = { 0x39004 }, - [GCC_USB_30_BCR] = { 0x39000 }, - [GCC_USB3PHY_PHY_BCR] = { 0x39008 }, - [GCC_PCIE_0_BCR] = { 0x3e000 }, - [GCC_PCIE_0_PHY_BCR] = { 0x3e004 }, - [GCC_PCIE_0_LINK_DOWN_BCR] = { 0x3e038 }, - [GCC_PCIEPHY_0_PHY_BCR] = { 0x3e03c }, - [GCC_PCIE_0_AXI_MASTER_STICKY_ARES] = { 0x3e040, 6}, - [GCC_PCIE_0_AHB_ARES] = { 0x3e040, 5 }, - [GCC_PCIE_0_AXI_SLAVE_ARES] = { 0x3e040, 4 }, - [GCC_PCIE_0_AXI_MASTER_ARES] = { 0x3e040, 3 }, - [GCC_PCIE_0_CORE_STICKY_ARES] = { 0x3e040, 2 }, - [GCC_PCIE_0_SLEEP_ARES] = { 0x3e040, 1 }, - [GCC_PCIE_0_PIPE_ARES] = { 0x3e040, 0 }, - [GCC_EMAC_BCR] = { 0x4e000 }, - [GCC_WDSP_RESTART] = {0x19000}, -}; -#endif - -static int qcom_reset_assert(struct reset_ctl *rst) -{ - struct qcom_reset_priv *priv = dev_get_priv(rst->dev); - const struct qcom_reset_map *reset_map = gcc_qcom_resets; - const struct qcom_reset_map *map; - u32 value; - - map = &reset_map[rst->id]; - value = readl(priv->base + map->reg); - value |= BIT(map->bit); - writel(value, priv->base + map->reg); - - return 0; -} - -static int qcom_reset_deassert(struct reset_ctl *rst) -{ - struct qcom_reset_priv *priv = dev_get_priv(rst->dev); - const struct qcom_reset_map *reset_map = gcc_qcom_resets; - const struct qcom_reset_map *map; - u32 value; - - map = &reset_map[rst->id]; - - value = readl(priv->base + map->reg); - value &= ~BIT(map->bit); - writel(value, priv->base + map->reg); - - return 0; -} - -static const struct reset_ops qcom_reset_ops = { - .rst_assert = qcom_reset_assert, - .rst_deassert = qcom_reset_deassert, +static struct msm_clk_data ipq4019_clk_data = { + .enable = ipq4019_clk_enable, + .set_rate = ipq4019_clk_set_rate, + .resets = gcc_ipq4019_resets, + .num_resets = ARRAY_SIZE(gcc_ipq4019_resets), }; -static const struct udevice_id qcom_reset_ids[] = { - { .compatible = "qcom,gcc-reset-ipq4019" }, - { .compatible = "qcom,gcc-reset-qcs404" }, +static const struct udevice_id gcc_ipq4019_of_match[] = { + { + .compatible = "qcom,gcc-ipq4019", + .data = (ulong)&ipq4019_clk_data, + }, { } }; -static int qcom_reset_probe(struct udevice *dev) -{ - struct qcom_reset_priv *priv = dev_get_priv(dev); - - priv->base = dev_read_addr(dev); - if (priv->base == FDT_ADDR_T_NONE) - return -EINVAL; - - return 0; -} - -U_BOOT_DRIVER(qcom_reset) = { - .name = "qcom_reset", - .id = UCLASS_RESET, - .of_match = qcom_reset_ids, - .ops = &qcom_reset_ops, - .probe = qcom_reset_probe, - .priv_auto = sizeof(struct qcom_reset_priv), +U_BOOT_DRIVER(gcc_ipq4019) = { + .name = "gcc_ipq4019", + .id = UCLASS_NOP, + .of_match = gcc_ipq4019_of_match, + .bind = qcom_cc_bind, + .flags = DM_FLAG_PRE_RELOC, }; diff --git a/drivers/clk/qcom/clock-qcom.c b/drivers/clk/qcom/clock-qcom.c new file mode 100644 index 0000000..7c683e5 --- /dev/null +++ b/drivers/clk/qcom/clock-qcom.c @@ -0,0 +1,307 @@ +// SPDX-License-Identifier: BSD-3-Clause AND GPL-2.0 +/* + * Clock and reset drivers for Qualcomm platforms Global Clock + * Controller (GCC). + * + * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com> + * (C) Copyright 2020 Sartura Ltd. (reset driver) + * Author: Robert Marko <robert.marko@sartura.hr> + * (C) Copyright 2022 Linaro Ltd. (reset driver) + * Author: Sumit Garg <sumit.garg@linaro.org> + * + * Based on Little Kernel driver, simplified + */ + +#include <common.h> +#include <clk-uclass.h> +#include <dm.h> +#include <dm/device-internal.h> +#include <dm/lists.h> +#include <errno.h> +#include <asm/io.h> +#include <linux/bug.h> +#include <linux/delay.h> +#include <linux/bitops.h> +#include <reset-uclass.h> + +#include "clock-qcom.h" + +/* CBCR register fields */ +#define CBCR_BRANCH_ENABLE_BIT BIT(0) +#define CBCR_BRANCH_OFF_BIT BIT(31) + +/* Enable clock controlled by CBC soft macro */ +void clk_enable_cbc(phys_addr_t cbcr) +{ + setbits_le32(cbcr, CBCR_BRANCH_ENABLE_BIT); + + while (readl(cbcr) & CBCR_BRANCH_OFF_BIT) + ; +} + +void clk_enable_gpll0(phys_addr_t base, const struct pll_vote_clk *gpll0) +{ + if (readl(base + gpll0->status) & gpll0->status_bit) + return; /* clock already enabled */ + + setbits_le32(base + gpll0->ena_vote, gpll0->vote_bit); + + while ((readl(base + gpll0->status) & gpll0->status_bit) == 0) + ; +} + +#define BRANCH_ON_VAL (0) +#define BRANCH_NOC_FSM_ON_VAL BIT(29) +#define BRANCH_CHECK_MASK GENMASK(31, 28) + +void clk_enable_vote_clk(phys_addr_t base, const struct vote_clk *vclk) +{ + u32 val; + + setbits_le32(base + vclk->ena_vote, vclk->vote_bit); + do { + val = readl(base + vclk->cbcr_reg); + val &= BRANCH_CHECK_MASK; + } while ((val != BRANCH_ON_VAL) && (val != BRANCH_NOC_FSM_ON_VAL)); +} + +#define APPS_CMD_RCGR_UPDATE BIT(0) + +/* Update clock command via CMD_RCGR */ +void clk_bcr_update(phys_addr_t apps_cmd_rcgr) +{ + u32 count; + setbits_le32(apps_cmd_rcgr, APPS_CMD_RCGR_UPDATE); + + /* Wait for frequency to be updated. */ + for (count = 0; count < 50000; count++) { + if (!(readl(apps_cmd_rcgr) & APPS_CMD_RCGR_UPDATE)) + break; + udelay(1); + } + WARN(count == 50000, "WARNING: RCG @ %#llx [%#010x] stuck at off\n", + apps_cmd_rcgr, readl(apps_cmd_rcgr)); +} + +#define CFG_SRC_DIV_MASK 0b11111 +#define CFG_SRC_SEL_SHIFT 8 +#define CFG_SRC_SEL_MASK (0x7 << CFG_SRC_SEL_SHIFT) +#define CFG_MODE_SHIFT 12 +#define CFG_MODE_MASK (0x3 << CFG_MODE_SHIFT) +#define CFG_MODE_DUAL_EDGE (0x2 << CFG_MODE_SHIFT) +#define CFG_HW_CLK_CTRL_MASK BIT(20) + +/* + * root set rate for clocks with half integer and MND divider + * div should be pre-calculated ((div * 2) - 1) + */ +void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs, + int div, int m, int n, int source, u8 mnd_width) +{ + u32 cfg; + /* M value for MND divider. */ + u32 m_val = m; + u32 n_minus_m = n - m; + /* NOT(N-M) value for MND divider. */ + u32 n_val = ~n_minus_m * !!(n); + /* NOT 2D value for MND divider. */ + u32 d_val = ~(clamp_t(u32, n, m, n_minus_m)); + u32 mask = BIT(mnd_width) - 1; + + debug("m %#x n %#x d %#x div %#x mask %#x\n", m_val, n_val, d_val, div, mask); + + /* Program MND values */ + writel(m_val & mask, base + regs->M); + writel(n_val & mask, base + regs->N); + writel(d_val & mask, base + regs->D); + + /* setup src select and divider */ + cfg = readl(base + regs->cfg_rcgr); + cfg &= ~(CFG_SRC_SEL_MASK | CFG_MODE_MASK | CFG_HW_CLK_CTRL_MASK); + cfg |= source & CFG_SRC_SEL_MASK; /* Select clock source */ + + if (div) + cfg |= div & CFG_SRC_DIV_MASK; + + if (n && n != m) + cfg |= CFG_MODE_DUAL_EDGE; + + writel(cfg, base + regs->cfg_rcgr); /* Write new clock configuration */ + + /* Inform h/w to start using the new config. */ + clk_bcr_update(base + regs->cmd_rcgr); +} + +/* root set rate for clocks with half integer and mnd_width=0 */ +void clk_rcg_set_rate(phys_addr_t base, const struct bcr_regs *regs, int div, + int source) +{ + u32 cfg; + + /* setup src select and divider */ + cfg = readl(base + regs->cfg_rcgr); + cfg &= ~(CFG_SRC_SEL_MASK | CFG_MODE_MASK | CFG_HW_CLK_CTRL_MASK); + cfg |= source & CFG_CLK_SRC_MASK; /* Select clock source */ + + /* + * Set the divider; HW permits fraction dividers (+0.5), but + * for simplicity, we will support integers only + */ + if (div) + cfg |= (2 * div - 1) & CFG_SRC_DIV_MASK; + + writel(cfg, base + regs->cfg_rcgr); /* Write new clock configuration */ + + /* Inform h/w to start using the new config. */ + clk_bcr_update(base + regs->cmd_rcgr); +} + +const struct freq_tbl *qcom_find_freq(const struct freq_tbl *f, uint rate) +{ + if (!f) + return NULL; + + if (!f->freq) + return f; + + for (; f->freq; f++) + if (rate <= f->freq) + return f; + + /* Default to our fastest rate */ + return f - 1; +} + +static int msm_clk_probe(struct udevice *dev) +{ + struct msm_clk_data *data = (struct msm_clk_data *)dev_get_driver_data(dev); + struct msm_clk_priv *priv = dev_get_priv(dev); + + priv->base = dev_read_addr(dev); + if (priv->base == FDT_ADDR_T_NONE) + return -EINVAL; + + priv->data = data; + + return 0; +} + +static ulong msm_clk_set_rate(struct clk *clk, ulong rate) +{ + struct msm_clk_data *data = (struct msm_clk_data *)dev_get_driver_data(clk->dev); + + if (data->set_rate) + return data->set_rate(clk, rate); + + return 0; +} + +static int msm_clk_enable(struct clk *clk) +{ + struct msm_clk_data *data = (struct msm_clk_data *)dev_get_driver_data(clk->dev); + + if (data->enable) + return data->enable(clk); + + return 0; +} + +static struct clk_ops msm_clk_ops = { + .set_rate = msm_clk_set_rate, + .enable = msm_clk_enable, +}; + +U_BOOT_DRIVER(qcom_clk) = { + .name = "qcom_clk", + .id = UCLASS_CLK, + .ops = &msm_clk_ops, + .priv_auto = sizeof(struct msm_clk_priv), + .probe = msm_clk_probe, +}; + +int qcom_cc_bind(struct udevice *parent) +{ + struct msm_clk_data *data = (struct msm_clk_data *)dev_get_driver_data(parent); + struct udevice *clkdev, *rstdev; + struct driver *drv; + int ret; + + /* Get a handle to the common clk handler */ + drv = lists_driver_lookup_name("qcom_clk"); + if (!drv) + return -ENOENT; + + /* Register the clock controller */ + ret = device_bind_with_driver_data(parent, drv, "qcom_clk", (ulong)data, + dev_ofnode(parent), &clkdev); + if (ret) + return ret; + + /* Bail out early if resets are not specified for this platform */ + if (!data->resets) + return ret; + + /* Get a handle to the common reset handler */ + drv = lists_driver_lookup_name("qcom_reset"); + if (!drv) + return -ENOENT; + + /* Register the reset controller */ + ret = device_bind_with_driver_data(parent, drv, "qcom_reset", (ulong)data, + dev_ofnode(parent), &rstdev); + if (ret) + device_unbind(clkdev); + + return ret; +} + +static int qcom_reset_set(struct reset_ctl *rst, bool assert) +{ + struct msm_clk_data *data = (struct msm_clk_data *)dev_get_driver_data(rst->dev); + void __iomem *base = dev_get_priv(rst->dev); + const struct qcom_reset_map *map; + u32 value; + + map = &data->resets[rst->id]; + + value = readl(base + map->reg); + + if (assert) + value |= BIT(map->bit); + else + value &= ~BIT(map->bit); + + writel(value, base + map->reg); + + return 0; +} + +static int qcom_reset_assert(struct reset_ctl *rst) +{ + return qcom_reset_set(rst, true); +} + +static int qcom_reset_deassert(struct reset_ctl *rst) +{ + return qcom_reset_set(rst, false); +} + +static const struct reset_ops qcom_reset_ops = { + .rst_assert = qcom_reset_assert, + .rst_deassert = qcom_reset_deassert, +}; + +static int qcom_reset_probe(struct udevice *dev) +{ + /* Set our priv pointer to the base address */ + dev_set_priv(dev, (void *)dev_read_addr(dev)); + + return 0; +} + +U_BOOT_DRIVER(qcom_reset) = { + .name = "qcom_reset", + .id = UCLASS_RESET, + .ops = &qcom_reset_ops, + .probe = qcom_reset_probe, +}; diff --git a/drivers/clk/qcom/clock-qcom.h b/drivers/clk/qcom/clock-qcom.h new file mode 100644 index 0000000..01088c1 --- /dev/null +++ b/drivers/clk/qcom/clock-qcom.h @@ -0,0 +1,100 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2017 Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org> + */ +#ifndef _CLOCK_QCOM_H +#define _CLOCK_QCOM_H + +#include <asm/io.h> + +#define CFG_CLK_SRC_CXO (0 << 8) +#define CFG_CLK_SRC_GPLL0 (1 << 8) +#define CFG_CLK_SRC_GPLL0_EVEN (6 << 8) +#define CFG_CLK_SRC_MASK (7 << 8) + +struct pll_vote_clk { + uintptr_t status; + int status_bit; + uintptr_t ena_vote; + int vote_bit; +}; + +struct vote_clk { + uintptr_t cbcr_reg; + uintptr_t ena_vote; + int vote_bit; +}; +struct bcr_regs { + uintptr_t cfg_rcgr; + uintptr_t cmd_rcgr; + uintptr_t M; + uintptr_t N; + uintptr_t D; +}; + +struct freq_tbl { + uint freq; + uint src; + u8 pre_div; + u16 m; + u16 n; +}; + +#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } + +struct gate_clk { + uintptr_t reg; + u32 en_val; + const char *name; +}; + +#ifdef DEBUG +#define GATE_CLK(clk, reg, val) [clk] = { reg, val, #clk } +#else +#define GATE_CLK(clk, reg, val) [clk] = { reg, val, NULL } +#endif + +struct qcom_reset_map { + unsigned int reg; + u8 bit; +}; + +struct clk; + +struct msm_clk_data { + const struct qcom_reset_map *resets; + unsigned long num_resets; + const struct gate_clk *clks; + unsigned long num_clks; + + int (*enable)(struct clk *clk); + unsigned long (*set_rate)(struct clk *clk, unsigned long rate); +}; + +struct msm_clk_priv { + phys_addr_t base; + struct msm_clk_data *data; +}; + +int qcom_cc_bind(struct udevice *parent); +void clk_enable_gpll0(phys_addr_t base, const struct pll_vote_clk *gpll0); +void clk_bcr_update(phys_addr_t apps_cmd_rgcr); +void clk_enable_cbc(phys_addr_t cbcr); +void clk_enable_vote_clk(phys_addr_t base, const struct vote_clk *vclk); +const struct freq_tbl *qcom_find_freq(const struct freq_tbl *f, uint rate); +void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs, + int div, int m, int n, int source, u8 mnd_width); +void clk_rcg_set_rate(phys_addr_t base, const struct bcr_regs *regs, int div, + int source); + +static inline void qcom_gate_clk_en(const struct msm_clk_priv *priv, unsigned long id) +{ + u32 val; + if (id >= priv->data->num_clks || priv->data->clks[id].reg == 0) + return; + + val = readl(priv->base + priv->data->clks[id].reg); + writel(val | priv->data->clks[id].en_val, priv->base + priv->data->clks[id].reg); +} + +#endif diff --git a/arch/arm/mach-snapdragon/clock-qcs404.c b/drivers/clk/qcom/clock-qcs404.c index 3357b54..f5b3528 100644 --- a/arch/arm/mach-snapdragon/clock-qcs404.c +++ b/drivers/clk/qcom/clock-qcs404.c @@ -11,10 +11,86 @@ #include <errno.h> #include <asm/io.h> #include <linux/bitops.h> -#include "clock-snapdragon.h" - #include <dt-bindings/clock/qcom,gcc-qcs404.h> +#include "clock-qcom.h" + +/* Clocks: (from CLK_CTL_BASE) */ +#define GPLL0_STATUS (0x21000) +#define GPLL1_STATUS (0x20000) +#define APCS_GPLL_ENA_VOTE (0x45000) +#define APCS_CLOCK_BRANCH_ENA_VOTE (0x45004) + +/* BLSP1 AHB clock (root clock for BLSP) */ +#define BLSP1_AHB_CBCR 0x1008 + +/* Uart clock control registers */ +#define BLSP1_UART2_BCR (0x3028) +#define BLSP1_UART2_APPS_CBCR (0x302C) +#define BLSP1_UART2_APPS_CMD_RCGR (0x3034) +#define BLSP1_UART2_APPS_CFG_RCGR (0x3038) +#define BLSP1_UART2_APPS_M (0x303C) +#define BLSP1_UART2_APPS_N (0x3040) +#define BLSP1_UART2_APPS_D (0x3044) + +/* I2C controller clock control registerss */ +#define BLSP1_QUP0_I2C_APPS_CBCR (0x6028) +#define BLSP1_QUP0_I2C_APPS_CMD_RCGR (0x602C) +#define BLSP1_QUP0_I2C_APPS_CFG_RCGR (0x6030) +#define BLSP1_QUP1_I2C_APPS_CBCR (0x2008) +#define BLSP1_QUP1_I2C_APPS_CMD_RCGR (0x200C) +#define BLSP1_QUP1_I2C_APPS_CFG_RCGR (0x2010) +#define BLSP1_QUP2_I2C_APPS_CBCR (0x3010) +#define BLSP1_QUP2_I2C_APPS_CMD_RCGR (0x3000) +#define BLSP1_QUP2_I2C_APPS_CFG_RCGR (0x3004) +#define BLSP1_QUP3_I2C_APPS_CBCR (0x4020) +#define BLSP1_QUP3_I2C_APPS_CMD_RCGR (0x4000) +#define BLSP1_QUP3_I2C_APPS_CFG_RCGR (0x4004) +#define BLSP1_QUP4_I2C_APPS_CBCR (0x5020) +#define BLSP1_QUP4_I2C_APPS_CMD_RCGR (0x5000) +#define BLSP1_QUP4_I2C_APPS_CFG_RCGR (0x5004) + +/* SD controller clock control registers */ +#define SDCC_BCR(n) (((n) * 0x1000) + 0x41000) +#define SDCC_CMD_RCGR(n) (((n) * 0x1000) + 0x41004) +#define SDCC_CFG_RCGR(n) (((n) * 0x1000) + 0x41008) +#define SDCC_M(n) (((n) * 0x1000) + 0x4100C) +#define SDCC_N(n) (((n) * 0x1000) + 0x41010) +#define SDCC_D(n) (((n) * 0x1000) + 0x41014) +#define SDCC_APPS_CBCR(n) (((n) * 0x1000) + 0x41018) +#define SDCC_AHB_CBCR(n) (((n) * 0x1000) + 0x4101C) + +/* USB-3.0 controller clock control registers */ +#define SYS_NOC_USB3_CBCR (0x26014) +#define USB30_BCR (0x39000) +#define USB3PHY_BCR (0x39008) +#define USB30_MASTER_CBCR (0x3900C) +#define USB30_SLEEP_CBCR (0x39010) +#define USB30_MOCK_UTMI_CBCR (0x39014) +#define USB30_MOCK_UTMI_CMD_RCGR (0x3901C) +#define USB30_MOCK_UTMI_CFG_RCGR (0x39020) +#define USB30_MASTER_CMD_RCGR (0x39028) +#define USB30_MASTER_CFG_RCGR (0x3902C) +#define USB30_MASTER_M (0x39030) +#define USB30_MASTER_N (0x39034) +#define USB30_MASTER_D (0x39038) +#define USB2A_PHY_SLEEP_CBCR (0x4102C) +#define USB_HS_PHY_CFG_AHB_CBCR (0x41030) + +/* ETH controller clock control registers */ +#define ETH_PTP_CBCR (0x4e004) +#define ETH_RGMII_CBCR (0x4e008) +#define ETH_SLAVE_AHB_CBCR (0x4e00c) +#define ETH_AXI_CBCR (0x4e010) +#define EMAC_PTP_CMD_RCGR (0x4e014) +#define EMAC_PTP_CFG_RCGR (0x4e018) +#define EMAC_CMD_RCGR (0x4e01c) +#define EMAC_CFG_RCGR (0x4e020) +#define EMAC_M (0x4e024) +#define EMAC_N (0x4e028) +#define EMAC_D (0x4e02c) + + /* GPLL0 clock control registers */ #define GPLL0_STATUS_ACTIVE BIT(31) @@ -111,7 +187,7 @@ static const struct bcr_regs blsp1_qup4_i2c_apps_regs = { /* mnd_width = 0 */ }; -ulong msm_set_rate(struct clk *clk, ulong rate) +static ulong qcs404_clk_set_rate(struct clk *clk, ulong rate) { struct msm_clk_priv *priv = dev_get_priv(clk->dev); @@ -119,7 +195,7 @@ ulong msm_set_rate(struct clk *clk, ulong rate) case GCC_BLSP1_UART2_APPS_CLK: /* UART: 115200 */ clk_rcg_set_rate_mnd(priv->base, &uart2_regs, 0, 12, 125, - CFG_CLK_SRC_CXO); + CFG_CLK_SRC_CXO, 16); clk_enable_cbc(priv->base + BLSP1_UART2_APPS_CBCR); break; case GCC_BLSP1_AHB_CLK: @@ -127,8 +203,8 @@ ulong msm_set_rate(struct clk *clk, ulong rate) break; case GCC_SDCC1_APPS_CLK: /* SDCC1: 200MHz */ - clk_rcg_set_rate_mnd(priv->base, &sdc_regs, 4, 0, 0, - CFG_CLK_SRC_GPLL0); + clk_rcg_set_rate_mnd(priv->base, &sdc_regs, 7, 0, 0, + CFG_CLK_SRC_GPLL0, 8); clk_enable_gpll0(priv->base, &gpll0_vote_clk); clk_enable_cbc(priv->base + SDCC_APPS_CBCR(1)); break; @@ -137,17 +213,17 @@ ulong msm_set_rate(struct clk *clk, ulong rate) break; case GCC_ETH_RGMII_CLK: if (rate == 250000000) - clk_rcg_set_rate_mnd(priv->base, &emac_regs, 2, 0, 0, - CFG_CLK_SRC_GPLL1); + clk_rcg_set_rate_mnd(priv->base, &emac_regs, 3, 0, 0, + CFG_CLK_SRC_GPLL1, 8); else if (rate == 125000000) - clk_rcg_set_rate_mnd(priv->base, &emac_regs, 4, 0, 0, - CFG_CLK_SRC_GPLL1); + clk_rcg_set_rate_mnd(priv->base, &emac_regs, 7, 0, 0, + CFG_CLK_SRC_GPLL1, 8); else if (rate == 50000000) - clk_rcg_set_rate_mnd(priv->base, &emac_regs, 10, 0, 0, - CFG_CLK_SRC_GPLL1); + clk_rcg_set_rate_mnd(priv->base, &emac_regs, 19, 0, 0, + CFG_CLK_SRC_GPLL1, 8); else if (rate == 5000000) - clk_rcg_set_rate_mnd(priv->base, &emac_regs, 2, 1, 50, - CFG_CLK_SRC_GPLL1); + clk_rcg_set_rate_mnd(priv->base, &emac_regs, 3, 1, 50, + CFG_CLK_SRC_GPLL1, 8); break; default: return 0; @@ -156,15 +232,15 @@ ulong msm_set_rate(struct clk *clk, ulong rate) return 0; } -int msm_enable(struct clk *clk) +static int qcs404_clk_enable(struct clk *clk) { struct msm_clk_priv *priv = dev_get_priv(clk->dev); switch (clk->id) { case GCC_USB30_MASTER_CLK: clk_enable_cbc(priv->base + USB30_MASTER_CBCR); - clk_rcg_set_rate_mnd(priv->base, &usb30_master_regs, 4, 0, 0, - CFG_CLK_SRC_GPLL0); + clk_rcg_set_rate_mnd(priv->base, &usb30_master_regs, 7, 0, 0, + CFG_CLK_SRC_GPLL0, 8); break; case GCC_SYS_NOC_USB3_CLK: clk_enable_cbc(priv->base + SYS_NOC_USB3_CBCR); @@ -185,15 +261,15 @@ int msm_enable(struct clk *clk) /* SPEED_1000: freq -> 250MHz */ clk_enable_cbc(priv->base + ETH_PTP_CBCR); clk_enable_gpll0(priv->base, &gpll1_vote_clk); - clk_rcg_set_rate_mnd(priv->base, &emac_ptp_regs, 2, 0, 0, - CFG_CLK_SRC_GPLL1); + clk_rcg_set_rate_mnd(priv->base, &emac_ptp_regs, 3, 0, 0, + CFG_CLK_SRC_GPLL1, 8); break; case GCC_ETH_RGMII_CLK: /* SPEED_1000: freq -> 250MHz */ clk_enable_cbc(priv->base + ETH_RGMII_CBCR); clk_enable_gpll0(priv->base, &gpll1_vote_clk); - clk_rcg_set_rate_mnd(priv->base, &emac_regs, 2, 0, 0, - CFG_CLK_SRC_GPLL1); + clk_rcg_set_rate_mnd(priv->base, &emac_regs, 3, 0, 0, + CFG_CLK_SRC_GPLL1, 8); break; case GCC_ETH_SLAVE_AHB_CLK: clk_enable_cbc(priv->base + ETH_SLAVE_AHB_CBCR); @@ -235,3 +311,52 @@ int msm_enable(struct clk *clk) return 0; } + +static const struct qcom_reset_map qcs404_gcc_resets[] = { + [GCC_GENI_IR_BCR] = { 0x0F000 }, + [GCC_CDSP_RESTART] = { 0x18000 }, + [GCC_USB_HS_BCR] = { 0x41000 }, + [GCC_USB2_HS_PHY_ONLY_BCR] = { 0x41034 }, + [GCC_QUSB2_PHY_BCR] = { 0x4103c }, + [GCC_USB_HS_PHY_CFG_AHB_BCR] = { 0x0000c, 1 }, + [GCC_USB2A_PHY_BCR] = { 0x0000c, 0 }, + [GCC_USB3_PHY_BCR] = { 0x39004 }, + [GCC_USB_30_BCR] = { 0x39000 }, + [GCC_USB3PHY_PHY_BCR] = { 0x39008 }, + [GCC_PCIE_0_BCR] = { 0x3e000 }, + [GCC_PCIE_0_PHY_BCR] = { 0x3e004 }, + [GCC_PCIE_0_LINK_DOWN_BCR] = { 0x3e038 }, + [GCC_PCIEPHY_0_PHY_BCR] = { 0x3e03c }, + [GCC_PCIE_0_AXI_MASTER_STICKY_ARES] = { 0x3e040, 6}, + [GCC_PCIE_0_AHB_ARES] = { 0x3e040, 5 }, + [GCC_PCIE_0_AXI_SLAVE_ARES] = { 0x3e040, 4 }, + [GCC_PCIE_0_AXI_MASTER_ARES] = { 0x3e040, 3 }, + [GCC_PCIE_0_CORE_STICKY_ARES] = { 0x3e040, 2 }, + [GCC_PCIE_0_SLEEP_ARES] = { 0x3e040, 1 }, + [GCC_PCIE_0_PIPE_ARES] = { 0x3e040, 0 }, + [GCC_EMAC_BCR] = { 0x4e000 }, + [GCC_WDSP_RESTART] = {0x19000}, +}; + +static const struct msm_clk_data qcs404_clk_gcc_data = { + .resets = qcs404_gcc_resets, + .num_resets = ARRAY_SIZE(qcs404_gcc_resets), + .enable = qcs404_clk_enable, + .set_rate = qcs404_clk_set_rate, +}; + +static const struct udevice_id gcc_qcs404_of_match[] = { + { + .compatible = "qcom,gcc-qcs404", + .data = (ulong)&qcs404_clk_gcc_data + }, + { } +}; + +U_BOOT_DRIVER(gcc_qcs404) = { + .name = "gcc_qcs404", + .id = UCLASS_NOP, + .of_match = gcc_qcs404_of_match, + .bind = qcom_cc_bind, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/drivers/clk/qcom/clock-sdm845.c b/drivers/clk/qcom/clock-sdm845.c new file mode 100644 index 0000000..36ffee7 --- /dev/null +++ b/drivers/clk/qcom/clock-sdm845.c @@ -0,0 +1,187 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Clock drivers for Qualcomm SDM845 + * + * (C) Copyright 2017 Jorge Ramirez Ortiz <jorge.ramirez-ortiz@linaro.org> + * (C) Copyright 2021 Dzmitry Sankouski <dsankouski@gmail.com> + * + * Based on Little Kernel driver, simplified + */ + +#include <common.h> +#include <clk-uclass.h> +#include <dm.h> +#include <linux/delay.h> +#include <errno.h> +#include <asm/io.h> +#include <linux/bitops.h> +#include <dt-bindings/clock/qcom,gcc-sdm845.h> + +#include "clock-qcom.h" + +#define SE9_AHB_CBCR 0x25004 +#define SE9_UART_APPS_CBCR 0x29004 +#define SE9_UART_APPS_CMD_RCGR 0x18148 +#define SE9_UART_APPS_CFG_RCGR 0x1814C +#define SE9_UART_APPS_M 0x18150 +#define SE9_UART_APPS_N 0x18154 +#define SE9_UART_APPS_D 0x18158 + +static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = { + F(7372800, CFG_CLK_SRC_GPLL0_EVEN, 1, 384, 15625), + F(14745600, CFG_CLK_SRC_GPLL0_EVEN, 1, 768, 15625), + F(19200000, CFG_CLK_SRC_CXO, 1, 0, 0), + F(29491200, CFG_CLK_SRC_GPLL0_EVEN, 1, 1536, 15625), + F(32000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 8, 75), + F(48000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 4, 25), + F(64000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 16, 75), + F(80000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 4, 15), + F(96000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 8, 25), + F(100000000, CFG_CLK_SRC_GPLL0_EVEN, 3, 0, 0), + F(102400000, CFG_CLK_SRC_GPLL0_EVEN, 1, 128, 375), + F(112000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 28, 75), + F(117964800, CFG_CLK_SRC_GPLL0_EVEN, 1, 6144, 15625), + F(120000000, CFG_CLK_SRC_GPLL0_EVEN, 2.5, 0, 0), + F(128000000, CFG_CLK_SRC_GPLL0, 1, 16, 75), + { } +}; + +static const struct bcr_regs uart2_regs = { + .cfg_rcgr = SE9_UART_APPS_CFG_RCGR, + .cmd_rcgr = SE9_UART_APPS_CMD_RCGR, + .M = SE9_UART_APPS_M, + .N = SE9_UART_APPS_N, + .D = SE9_UART_APPS_D, +}; + +static ulong sdm845_clk_set_rate(struct clk *clk, ulong rate) +{ + struct msm_clk_priv *priv = dev_get_priv(clk->dev); + const struct freq_tbl *freq; + + switch (clk->id) { + case GCC_QUPV3_WRAP1_S1_CLK: /* UART9 */ + freq = qcom_find_freq(ftbl_gcc_qupv3_wrap0_s0_clk_src, rate); + clk_rcg_set_rate_mnd(priv->base, &uart2_regs, + freq->pre_div, freq->m, freq->n, freq->src, 16); + return freq->freq; + default: + return 0; + } +} + +static const struct gate_clk sdm845_clks[] = { + GATE_CLK(GCC_QUPV3_WRAP0_S0_CLK, 0x5200c, 0x00000400), + GATE_CLK(GCC_QUPV3_WRAP0_S1_CLK, 0x5200c, 0x00000800), + GATE_CLK(GCC_QUPV3_WRAP0_S2_CLK, 0x5200c, 0x00001000), + GATE_CLK(GCC_QUPV3_WRAP0_S3_CLK, 0x5200c, 0x00002000), + GATE_CLK(GCC_QUPV3_WRAP0_S4_CLK, 0x5200c, 0x00004000), + GATE_CLK(GCC_QUPV3_WRAP0_S5_CLK, 0x5200c, 0x00008000), + GATE_CLK(GCC_QUPV3_WRAP0_S6_CLK, 0x5200c, 0x00010000), + GATE_CLK(GCC_QUPV3_WRAP0_S7_CLK, 0x5200c, 0x00020000), + GATE_CLK(GCC_QUPV3_WRAP1_S0_CLK, 0x5200c, 0x00400000), + GATE_CLK(GCC_QUPV3_WRAP1_S1_CLK, 0x5200c, 0x00800000), + GATE_CLK(GCC_QUPV3_WRAP1_S3_CLK, 0x5200c, 0x02000000), + GATE_CLK(GCC_QUPV3_WRAP1_S4_CLK, 0x5200c, 0x04000000), + GATE_CLK(GCC_QUPV3_WRAP1_S5_CLK, 0x5200c, 0x08000000), + GATE_CLK(GCC_QUPV3_WRAP1_S6_CLK, 0x5200c, 0x10000000), + GATE_CLK(GCC_QUPV3_WRAP1_S7_CLK, 0x5200c, 0x20000000), + GATE_CLK(GCC_QUPV3_WRAP_0_M_AHB_CLK, 0x5200c, 0x00000040), + GATE_CLK(GCC_QUPV3_WRAP_0_S_AHB_CLK, 0x5200c, 0x00000080), + GATE_CLK(GCC_QUPV3_WRAP_1_M_AHB_CLK, 0x5200c, 0x00100000), + GATE_CLK(GCC_QUPV3_WRAP_1_S_AHB_CLK, 0x5200c, 0x00200000), + GATE_CLK(GCC_SDCC2_AHB_CLK, 0x14008, 0x00000001), + GATE_CLK(GCC_SDCC2_APPS_CLK, 0x14004, 0x00000001), + GATE_CLK(GCC_SDCC4_AHB_CLK, 0x16008, 0x00000001), + GATE_CLK(GCC_SDCC4_APPS_CLK, 0x16004, 0x00000001), + GATE_CLK(GCC_UFS_CARD_AHB_CLK, 0x75010, 0x00000001), + GATE_CLK(GCC_UFS_CARD_AXI_CLK, 0x7500c, 0x00000001), + GATE_CLK(GCC_UFS_CARD_CLKREF_CLK, 0x8c004, 0x00000001), + GATE_CLK(GCC_UFS_CARD_ICE_CORE_CLK, 0x75058, 0x00000001), + GATE_CLK(GCC_UFS_CARD_PHY_AUX_CLK, 0x7508c, 0x00000001), + GATE_CLK(GCC_UFS_CARD_RX_SYMBOL_0_CLK, 0x75018, 0x00000001), + GATE_CLK(GCC_UFS_CARD_RX_SYMBOL_1_CLK, 0x750a8, 0x00000001), + GATE_CLK(GCC_UFS_CARD_TX_SYMBOL_0_CLK, 0x75014, 0x00000001), + GATE_CLK(GCC_UFS_CARD_UNIPRO_CORE_CLK, 0x75054, 0x00000001), + GATE_CLK(GCC_UFS_MEM_CLKREF_CLK, 0x8c000, 0x00000001), + GATE_CLK(GCC_UFS_PHY_AHB_CLK, 0x77010, 0x00000001), + GATE_CLK(GCC_UFS_PHY_AXI_CLK, 0x7700c, 0x00000001), + GATE_CLK(GCC_UFS_PHY_ICE_CORE_CLK, 0x77058, 0x00000001), + GATE_CLK(GCC_UFS_PHY_PHY_AUX_CLK, 0x7708c, 0x00000001), + GATE_CLK(GCC_UFS_PHY_RX_SYMBOL_0_CLK, 0x77018, 0x00000001), + GATE_CLK(GCC_UFS_PHY_RX_SYMBOL_1_CLK, 0x770a8, 0x00000001), + GATE_CLK(GCC_UFS_PHY_TX_SYMBOL_0_CLK, 0x77014, 0x00000001), + GATE_CLK(GCC_UFS_PHY_UNIPRO_CORE_CLK, 0x77054, 0x00000001), + GATE_CLK(GCC_USB30_PRIM_MASTER_CLK, 0x0f00c, 0x00000001), + GATE_CLK(GCC_USB30_PRIM_MOCK_UTMI_CLK, 0x0f014, 0x00000001), + GATE_CLK(GCC_USB30_PRIM_SLEEP_CLK, 0x0f010, 0x00000001), + GATE_CLK(GCC_USB30_SEC_MASTER_CLK, 0x1000c, 0x00000001), + GATE_CLK(GCC_USB30_SEC_MOCK_UTMI_CLK, 0x10014, 0x00000001), + GATE_CLK(GCC_USB30_SEC_SLEEP_CLK, 0x10010, 0x00000001), + GATE_CLK(GCC_USB3_PRIM_CLKREF_CLK, 0x8c008, 0x00000001), + GATE_CLK(GCC_USB3_PRIM_PHY_AUX_CLK, 0x0f04c, 0x00000001), + GATE_CLK(GCC_USB3_PRIM_PHY_COM_AUX_CLK, 0x0f050, 0x00000001), + GATE_CLK(GCC_USB3_PRIM_PHY_PIPE_CLK, 0x0f054, 0x00000001), + GATE_CLK(GCC_USB3_SEC_CLKREF_CLK, 0x8c028, 0x00000001), + GATE_CLK(GCC_USB3_SEC_PHY_AUX_CLK, 0x1004c, 0x00000001), + GATE_CLK(GCC_USB3_SEC_PHY_PIPE_CLK, 0x10054, 0x00000001), + GATE_CLK(GCC_USB3_SEC_PHY_COM_AUX_CLK, 0x10050, 0x00000001), + GATE_CLK(GCC_USB_PHY_CFG_AHB2PHY_CLK, 0x6a004, 0x00000001), +}; + +static int sdm845_clk_enable(struct clk *clk) +{ + struct msm_clk_priv *priv = dev_get_priv(clk->dev); + + debug("%s: clk %s\n", __func__, sdm845_clks[clk->id].name); + + qcom_gate_clk_en(priv, clk->id); + + return 0; +} + +static const struct qcom_reset_map sdm845_gcc_resets[] = { + [GCC_QUPV3_WRAPPER_0_BCR] = { 0x17000 }, + [GCC_QUPV3_WRAPPER_1_BCR] = { 0x18000 }, + [GCC_QUSB2PHY_PRIM_BCR] = { 0x12000 }, + [GCC_QUSB2PHY_SEC_BCR] = { 0x12004 }, + [GCC_SDCC2_BCR] = { 0x14000 }, + [GCC_SDCC4_BCR] = { 0x16000 }, + [GCC_UFS_CARD_BCR] = { 0x75000 }, + [GCC_UFS_PHY_BCR] = { 0x77000 }, + [GCC_USB30_PRIM_BCR] = { 0xf000 }, + [GCC_USB30_SEC_BCR] = { 0x10000 }, + [GCC_USB3_PHY_PRIM_BCR] = { 0x50000 }, + [GCC_USB3PHY_PHY_PRIM_BCR] = { 0x50004 }, + [GCC_USB3_DP_PHY_PRIM_BCR] = { 0x50008 }, + [GCC_USB3_PHY_SEC_BCR] = { 0x5000c }, + [GCC_USB3PHY_PHY_SEC_BCR] = { 0x50010 }, + [GCC_USB3_DP_PHY_SEC_BCR] = { 0x50014 }, + [GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0x6a000 }, +}; + +static struct msm_clk_data sdm845_clk_data = { + .resets = sdm845_gcc_resets, + .num_resets = ARRAY_SIZE(sdm845_gcc_resets), + .clks = sdm845_clks, + .num_clks = ARRAY_SIZE(sdm845_clks), + + .enable = sdm845_clk_enable, + .set_rate = sdm845_clk_set_rate, +}; + +static const struct udevice_id gcc_sdm845_of_match[] = { + { + .compatible = "qcom,gcc-sdm845", + .data = (ulong)&sdm845_clk_data, + }, + { } +}; + +U_BOOT_DRIVER(gcc_sdm845) = { + .name = "gcc_sdm845", + .id = UCLASS_NOP, + .of_match = gcc_sdm845_of_match, + .bind = qcom_cc_bind, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 63e62e1..27df5d8 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -318,12 +318,11 @@ config CMD_PCA953X config QCOM_PMIC_GPIO bool "Qualcomm generic PMIC GPIO/keypad driver" depends on DM_GPIO && PMIC_QCOM + select BUTTON help Support for GPIO pins and power/reset buttons found on Qualcomm SoCs PMIC. - Default name for GPIO bank is "pm8916". - Power and reset buttons are placed in "pwkey_qcom" bank and - have gpio numbers 0 and 1 respectively. + The GPIO bank is called "pmic" config PCF8575_GPIO bool "PCF8575 I2C GPIO Expander driver" diff --git a/drivers/gpio/msm_gpio.c b/drivers/gpio/msm_gpio.c index 51670f2..80cd28b 100644 --- a/drivers/gpio/msm_gpio.c +++ b/drivers/gpio/msm_gpio.c @@ -11,13 +11,10 @@ #include <asm/global_data.h> #include <asm/gpio.h> #include <asm/io.h> +#include <mach/gpio.h> DECLARE_GLOBAL_DATA_PTR; -/* Register offsets */ -#define GPIO_CONFIG_OFF(no) ((no) * 0x1000) -#define GPIO_IN_OUT_OFF(no) ((no) * 0x1000 + 0x4) - /* OE */ #define GPIO_OE_DISABLE (0x0 << 9) #define GPIO_OE_ENABLE (0x1 << 9) @@ -29,57 +26,64 @@ DECLARE_GLOBAL_DATA_PTR; struct msm_gpio_bank { phys_addr_t base; + const struct msm_pin_data *pin_data; }; +#define GPIO_CONFIG_REG(dev, x) \ + (qcom_pin_offset(((struct msm_gpio_bank *)dev_get_priv(dev))->pin_data->pin_offsets, x)) + +#define GPIO_IN_OUT_REG(dev, x) \ + (GPIO_CONFIG_REG(dev, x) + 0x4) + static int msm_gpio_direction_input(struct udevice *dev, unsigned int gpio) { struct msm_gpio_bank *priv = dev_get_priv(dev); - phys_addr_t reg = priv->base + GPIO_CONFIG_OFF(gpio); /* Disable OE bit */ - clrsetbits_le32(reg, GPIO_OE_MASK, GPIO_OE_DISABLE); + clrsetbits_le32(priv->base + GPIO_CONFIG_REG(dev, gpio), + GPIO_OE_MASK, GPIO_OE_DISABLE); return 0; } -static int msm_gpio_set_value(struct udevice *dev, unsigned gpio, int value) +static int msm_gpio_set_value(struct udevice *dev, unsigned int gpio, int value) { struct msm_gpio_bank *priv = dev_get_priv(dev); value = !!value; /* set value */ - writel(value << GPIO_OUT, priv->base + GPIO_IN_OUT_OFF(gpio)); + writel(value << GPIO_OUT, priv->base + GPIO_IN_OUT_REG(dev, gpio)); return 0; } -static int msm_gpio_direction_output(struct udevice *dev, unsigned gpio, +static int msm_gpio_direction_output(struct udevice *dev, unsigned int gpio, int value) { struct msm_gpio_bank *priv = dev_get_priv(dev); - phys_addr_t reg = priv->base + GPIO_CONFIG_OFF(gpio); value = !!value; /* set value */ - writel(value << GPIO_OUT, priv->base + GPIO_IN_OUT_OFF(gpio)); + writel(value << GPIO_OUT, priv->base + GPIO_IN_OUT_REG(dev, gpio)); /* switch direction */ - clrsetbits_le32(reg, GPIO_OE_MASK, GPIO_OE_ENABLE); + clrsetbits_le32(priv->base + GPIO_CONFIG_REG(dev, gpio), + GPIO_OE_MASK, GPIO_OE_ENABLE); return 0; } -static int msm_gpio_get_value(struct udevice *dev, unsigned gpio) +static int msm_gpio_get_value(struct udevice *dev, unsigned int gpio) { struct msm_gpio_bank *priv = dev_get_priv(dev); - return !!(readl(priv->base + GPIO_IN_OUT_OFF(gpio)) >> GPIO_IN); + return !!(readl(priv->base + GPIO_IN_OUT_REG(dev, gpio)) >> GPIO_IN); } -static int msm_gpio_get_function(struct udevice *dev, unsigned offset) +static int msm_gpio_get_function(struct udevice *dev, unsigned int gpio) { struct msm_gpio_bank *priv = dev_get_priv(dev); - if (readl(priv->base + GPIO_CONFIG_OFF(offset)) & GPIO_OE_ENABLE) + if (readl(priv->base + GPIO_CONFIG_REG(dev, gpio)) & GPIO_OE_ENABLE) return GPIOF_OUTPUT; return GPIOF_INPUT; @@ -98,6 +102,7 @@ static int msm_gpio_probe(struct udevice *dev) struct msm_gpio_bank *priv = dev_get_priv(dev); priv->base = dev_read_addr(dev); + priv->pin_data = (struct msm_pin_data *)dev_get_driver_data(dev); return priv->base == FDT_ADDR_T_NONE ? -EINVAL : 0; } @@ -105,9 +110,10 @@ static int msm_gpio_probe(struct udevice *dev) static int msm_gpio_of_to_plat(struct udevice *dev) { struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); + const struct msm_pin_data *pin_data = (struct msm_pin_data *)dev_get_driver_data(dev); - uc_priv->gpio_count = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), - "gpio-count", 0); + /* Get the pin count from the pinctrl driver */ + uc_priv->gpio_count = pin_data->pin_count; uc_priv->bank_name = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "gpio-bank-name", NULL); if (uc_priv->bank_name == NULL) diff --git a/drivers/gpio/qcom_pmic_gpio.c b/drivers/gpio/qcom_pmic_gpio.c index 65feb45..6167c84 100644 --- a/drivers/gpio/qcom_pmic_gpio.c +++ b/drivers/gpio/qcom_pmic_gpio.c @@ -221,11 +221,14 @@ static int qcom_gpio_probe(struct udevice *dev) { struct qcom_gpio_bank *priv = dev_get_priv(dev); int reg; + u64 pid; - priv->pid = dev_read_addr(dev); - if (priv->pid == FDT_ADDR_T_NONE) + pid = dev_read_addr(dev); + if (pid == FDT_ADDR_T_NONE) return log_msg_ret("bad address", -EINVAL); + priv->pid = pid; + /* Do a sanity check */ reg = pmic_reg_read(dev->parent, priv->pid + REG_TYPE); if (reg != REG_TYPE_VAL) @@ -242,14 +245,36 @@ static int qcom_gpio_probe(struct udevice *dev) return 0; } +/* + * Parse basic GPIO count specified via the gpio-ranges property + * as specified in Linux devicetrees + * Returns < 0 on error, otherwise gpio count + */ +static int qcom_gpio_of_parse_ranges(struct udevice *dev) +{ + int ret; + struct ofnode_phandle_args args; + + ret = ofnode_parse_phandle_with_args(dev_ofnode(dev), "gpio-ranges", + NULL, 3, 0, &args); + if (ret) + return log_msg_ret("gpio-ranges", ret); + + return args.args[2]; +} + static int qcom_gpio_of_to_plat(struct udevice *dev) { struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); + int ret; + + ret = qcom_gpio_of_parse_ranges(dev); + if (ret > 0) + uc_priv->gpio_count = ret; + else + return ret; - uc_priv->gpio_count = dev_read_u32_default(dev, "gpio-count", 0); - uc_priv->bank_name = dev_read_string(dev, "gpio-bank-name"); - if (uc_priv->bank_name == NULL) - uc_priv->bank_name = "qcom_pmic"; + uc_priv->bank_name = "pmic"; return 0; } @@ -272,104 +297,3 @@ U_BOOT_DRIVER(qcom_pmic_gpio) = { .priv_auto = sizeof(struct qcom_gpio_bank), }; - -/* Add pmic buttons as GPIO as well - there is no generic way for now */ -#define PON_INT_RT_STS 0x10 -#define KPDPWR_ON_INT_BIT 0 -#define RESIN_ON_INT_BIT 1 - -static int qcom_pwrkey_get_function(struct udevice *dev, unsigned offset) -{ - return GPIOF_INPUT; -} - -static int qcom_pwrkey_get_value(struct udevice *dev, unsigned offset) -{ - struct qcom_gpio_bank *priv = dev_get_priv(dev); - - int reg = pmic_reg_read(dev->parent, priv->pid + PON_INT_RT_STS); - - if (reg < 0) - return 0; - - switch (offset) { - case 0: /* Power button */ - return (reg & BIT(KPDPWR_ON_INT_BIT)) != 0; - break; - case 1: /* Reset button */ - default: - return (reg & BIT(RESIN_ON_INT_BIT)) != 0; - break; - } -} - -/* - * Since pmic buttons modelled as GPIO, we need empty direction functions - * to trick u-boot button driver - */ -static int qcom_pwrkey_direction_input(struct udevice *dev, unsigned int offset) -{ - return 0; -} - -static int qcom_pwrkey_direction_output(struct udevice *dev, unsigned int offset, int value) -{ - return -EOPNOTSUPP; -} - -static const struct dm_gpio_ops qcom_pwrkey_ops = { - .get_value = qcom_pwrkey_get_value, - .get_function = qcom_pwrkey_get_function, - .direction_input = qcom_pwrkey_direction_input, - .direction_output = qcom_pwrkey_direction_output, -}; - -static int qcom_pwrkey_probe(struct udevice *dev) -{ - struct qcom_gpio_bank *priv = dev_get_priv(dev); - int reg; - - priv->pid = dev_read_addr(dev); - if (priv->pid == FDT_ADDR_T_NONE) - return log_msg_ret("bad address", -EINVAL); - - /* Do a sanity check */ - reg = pmic_reg_read(dev->parent, priv->pid + REG_TYPE); - if (reg != 0x1) - return log_msg_ret("bad type", -ENXIO); - - reg = pmic_reg_read(dev->parent, priv->pid + REG_SUBTYPE); - if ((reg & 0x5) == 0) - return log_msg_ret("bad subtype", -ENXIO); - - return 0; -} - -static int qcom_pwrkey_of_to_plat(struct udevice *dev) -{ - struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); - - uc_priv->gpio_count = 2; - uc_priv->bank_name = dev_read_string(dev, "gpio-bank-name"); - if (uc_priv->bank_name == NULL) - uc_priv->bank_name = "pwkey_qcom"; - - return 0; -} - -static const struct udevice_id qcom_pwrkey_ids[] = { - { .compatible = "qcom,pm8916-pwrkey" }, - { .compatible = "qcom,pm8994-pwrkey" }, - { .compatible = "qcom,pm8998-pwrkey" }, - { } -}; - -U_BOOT_DRIVER(pwrkey_qcom) = { - .name = "pwrkey_qcom", - .id = UCLASS_GPIO, - .of_match = qcom_pwrkey_ids, - .of_to_plat = qcom_pwrkey_of_to_plat, - .probe = qcom_pwrkey_probe, - .ops = &qcom_pwrkey_ops, - .priv_auto = sizeof(struct qcom_gpio_bank), -}; diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index e8e4400..e85a0dd 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -527,13 +527,6 @@ config WINBOND_W83627 legacy UART or other devices in the Winbond Super IO chips on X86 platforms. -config QCOM_GENI_SE - bool "Qualcomm GENI Serial Engine Driver" - depends on ARCH_SNAPDRAGON - help - The driver manages Generic Interface (GENI) firmware based - Qualcomm Technologies, Inc. Universal Peripheral (QUP) Wrapper. - config QFW bool help diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index cda701d..6bf1e79 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -60,7 +60,6 @@ obj-$(CONFIG_NUVOTON_NCT6102D) += nuvoton_nct6102d.o obj-$(CONFIG_P2SB) += p2sb-uclass.o obj-$(CONFIG_PCA9551_LED) += pca9551_led.o obj-$(CONFIG_$(SPL_)PWRSEQ) += pwrseq-uclass.o -obj-$(CONFIG_QCOM_GENI_SE) += qcom-geni-se.o ifdef CONFIG_QFW obj-y += qfw.o obj-$(CONFIG_QFW_ACPI) += qfw_acpi.o diff --git a/drivers/misc/qcom-geni-se.c b/drivers/misc/qcom-geni-se.c deleted file mode 100644 index 281a5ec..0000000 --- a/drivers/misc/qcom-geni-se.c +++ /dev/null @@ -1,41 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Qualcomm Generic Interface (GENI) Serial Engine (SE) Wrapper - * - * Copyright (C) 2023 Linaro Ltd. <vladimir.zapolskiy@linaro.org> - */ - -#include <common.h> -#include <dm.h> -#include <misc.h> -#include <asm/io.h> - -static int geni_se_qup_read(struct udevice *dev, int offset, - void *buf, int size) -{ - fdt_addr_t base = dev_read_addr(dev); - - if (size != sizeof(u32)) - return -EINVAL; - - *(u32 *)buf = readl(base + offset); - - return size; -} - -static struct misc_ops geni_se_qup_ops = { - .read = geni_se_qup_read, -}; - -static const struct udevice_id geni_se_qup_ids[] = { - { .compatible = "qcom,geni-se-qup" }, - {} -}; - -U_BOOT_DRIVER(geni_se_qup) = { - .name = "geni_se_qup", - .id = UCLASS_MISC, - .of_match = geni_se_qup_ids, - .ops = &geni_se_qup_ops, - .flags = DM_FLAG_PRE_RELOC, -}; diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index fceafea..a1d53cf 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -355,6 +355,7 @@ source "drivers/pinctrl/mvebu/Kconfig" source "drivers/pinctrl/nexell/Kconfig" source "drivers/pinctrl/nuvoton/Kconfig" source "drivers/pinctrl/nxp/Kconfig" +source "drivers/pinctrl/qcom/Kconfig" source "drivers/pinctrl/renesas/Kconfig" source "drivers/pinctrl/rockchip/Kconfig" source "drivers/pinctrl/sunxi/Kconfig" diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index 96a0516..0e929d8 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_ARCH_ATH79) += ath79/ obj-$(CONFIG_PINCTRL_INTEL) += intel/ obj-$(CONFIG_ARCH_MTMIPS) += mtmips/ obj-$(CONFIG_ARCH_NPCM) += nuvoton/ +obj-$(CONFIG_PINCTRL_QCOM) += qcom/ obj-$(CONFIG_ARCH_RMOBILE) += renesas/ obj-$(CONFIG_ARCH_RZN1) += renesas/ obj-$(CONFIG_PINCTRL_SANDBOX) += pinctrl-sandbox.o diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig new file mode 100644 index 0000000..2fe6398 --- /dev/null +++ b/drivers/pinctrl/qcom/Kconfig @@ -0,0 +1,46 @@ +if ARCH_SNAPDRAGON + +config PINCTRL_QCOM + depends on PINCTRL_GENERIC + def_bool n + +menu "Qualcomm pinctrl drivers" + +config PINCTRL_QCOM_APQ8016 + bool "Qualcomm APQ8016 GCC" + select PINCTRL_QCOM + help + Say Y here to enable support for pinctrl on the MSM8916 / APQ8016 + Snapdragon 410 SoC, as well as the associated GPIO driver. + +config PINCTRL_QCOM_APQ8096 + bool "Qualcomm APQ8096 GCC" + select PINCTRL_QCOM + help + Say Y here to enable support for pinctrl on the MSM8996 / APQ8096 + Snapdragon 820 SoC, as well as the associated GPIO driver. + +config PINCTRL_QCOM_IPQ4019 + bool "Qualcomm IPQ4019 GCC" + select PINCTRL_QCOM + help + Say Y here to enable support for pinctrl on the IPQ4019 SoC, + as well as the associated GPIO driver. + +config PINCTRL_QCOM_QCS404 + bool "Qualcomm QCS404 GCC" + select PINCTRL_QCOM + help + Say Y here to enable support for pinctrl on the Snapdragon QCS404 SoC, + as well as the associated GPIO driver. + +config PINCTRL_QCOM_SDM845 + bool "Qualcomm SDM845 GCC" + select PINCTRL_QCOM + help + Say Y here to enable support for pinctrl on the Snapdragon 845 SoC, + as well as the associated GPIO driver. + +endmenu + +endif diff --git a/drivers/pinctrl/qcom/Makefile b/drivers/pinctrl/qcom/Makefile new file mode 100644 index 0000000..6d9aca6 --- /dev/null +++ b/drivers/pinctrl/qcom/Makefile @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (c) 2023 Linaro Ltd. + +obj-$(CONFIG_PINCTRL_QCOM) += pinctrl-qcom.o +obj-$(CONFIG_PINCTRL_QCOM_APQ8016) += pinctrl-apq8016.o +obj-$(CONFIG_PINCTRL_QCOM_IPQ4019) += pinctrl-ipq4019.o +obj-$(CONFIG_PINCTRL_QCOM_APQ8096) += pinctrl-apq8096.o +obj-$(CONFIG_PINCTRL_QCOM_QCS404) += pinctrl-qcs404.o +obj-$(CONFIG_PINCTRL_QCOM_SDM845) += pinctrl-sdm845.o diff --git a/arch/arm/mach-snapdragon/pinctrl-apq8016.c b/drivers/pinctrl/qcom/pinctrl-apq8016.c index 70c0be0..8149ffd 100644 --- a/arch/arm/mach-snapdragon/pinctrl-apq8016.c +++ b/drivers/pinctrl/qcom/pinctrl-apq8016.c @@ -6,8 +6,10 @@ * */ -#include "pinctrl-snapdragon.h" #include <common.h> +#include <dm.h> + +#include "pinctrl-qcom.h" #define MAX_PIN_NAME_LEN 32 static char pin_name[MAX_PIN_NAME_LEN] __section(".data"); @@ -52,10 +54,23 @@ static unsigned int apq8016_get_function_mux(unsigned int selector) return msm_pinctrl_functions[selector].val; } -struct msm_pinctrl_data apq8016_data = { - .pin_count = 133, +static const struct msm_pinctrl_data apq8016_data = { + .pin_data = { .pin_count = 133, }, .functions_count = ARRAY_SIZE(msm_pinctrl_functions), .get_function_name = apq8016_get_function_name, .get_function_mux = apq8016_get_function_mux, .get_pin_name = apq8016_get_pin_name, }; + +static const struct udevice_id msm_pinctrl_ids[] = { + { .compatible = "qcom,msm8916-pinctrl", .data = (ulong)&apq8016_data }, + { /* Sentinal */ } +}; + +U_BOOT_DRIVER(pinctrl_apq8016) = { + .name = "pinctrl_apq8016", + .id = UCLASS_NOP, + .of_match = msm_pinctrl_ids, + .ops = &msm_pinctrl_ops, + .bind = msm_pinctrl_bind, +}; diff --git a/arch/arm/mach-snapdragon/pinctrl-apq8096.c b/drivers/pinctrl/qcom/pinctrl-apq8096.c index 45462f0..d64ab1f 100644 --- a/arch/arm/mach-snapdragon/pinctrl-apq8096.c +++ b/drivers/pinctrl/qcom/pinctrl-apq8096.c @@ -6,8 +6,10 @@ * */ -#include "pinctrl-snapdragon.h" #include <common.h> +#include <dm.h> + +#include "pinctrl-qcom.h" #define MAX_PIN_NAME_LEN 32 static char pin_name[MAX_PIN_NAME_LEN] __section(".data"); @@ -47,10 +49,23 @@ static unsigned int apq8096_get_function_mux(unsigned int selector) return msm_pinctrl_functions[selector].val; } -struct msm_pinctrl_data apq8096_data = { - .pin_count = 157, +static const struct msm_pinctrl_data apq8096_data = { + .pin_data = { .pin_count = 157, }, .functions_count = ARRAY_SIZE(msm_pinctrl_functions), .get_function_name = apq8096_get_function_name, .get_function_mux = apq8096_get_function_mux, .get_pin_name = apq8096_get_pin_name, }; + +static const struct udevice_id msm_pinctrl_ids[] = { + { .compatible = "qcom,msm8996-pinctrl", .data = (ulong)&apq8096_data }, + { /* Sentinal */ } +}; + +U_BOOT_DRIVER(pinctrl_apq8096) = { + .name = "pinctrl_apq8096", + .id = UCLASS_NOP, + .of_match = msm_pinctrl_ids, + .ops = &msm_pinctrl_ops, + .bind = msm_pinctrl_bind, +}; diff --git a/arch/arm/mach-ipq40xx/pinctrl-ipq4019.c b/drivers/pinctrl/qcom/pinctrl-ipq4019.c index 3e365f8..2d99f99 100644 --- a/arch/arm/mach-ipq40xx/pinctrl-ipq4019.c +++ b/drivers/pinctrl/qcom/pinctrl-ipq4019.c @@ -7,12 +7,13 @@ * Author: Robert Marko <robert.marko@sartura.hr> */ -#include "pinctrl-snapdragon.h" #include <common.h> +#include <dm.h> -#define MAX_PIN_NAME_LEN 32 -static char pin_name[MAX_PIN_NAME_LEN]; +#include "pinctrl-qcom.h" +#define MAX_PIN_NAME_LEN 32 +static char pin_name[MAX_PIN_NAME_LEN] __section(".data"); static const struct pinctrl_function msm_pinctrl_functions[] = { {"gpio", 0}, {"blsp_uart0_0", 1}, /* Only for GPIO:16,17 */ @@ -26,7 +27,6 @@ static const struct pinctrl_function msm_pinctrl_functions[] = { {"mdc_0", 1}, /* Only for GPIO7 */ {"mdc_1", 2}, /* Only for GPIO52 */ }; - static const char *ipq4019_get_function_name(struct udevice *dev, unsigned int selector) { @@ -45,10 +45,23 @@ 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, +static const struct msm_pinctrl_data ipq4019_data = { + .pin_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, }; + +static const struct udevice_id msm_pinctrl_ids[] = { + { .compatible = "qcom,ipq4019-pinctrl", .data = (ulong)&ipq4019_data }, + { /* Sentinal */ } +}; + +U_BOOT_DRIVER(pinctrl_ipq4019) = { + .name = "pinctrl_ipq4019", + .id = UCLASS_NOP, + .of_match = msm_pinctrl_ids, + .ops = &msm_pinctrl_ops, + .bind = msm_pinctrl_bind, +}; diff --git a/arch/arm/mach-snapdragon/pinctrl-snapdragon.c b/drivers/pinctrl/qcom/pinctrl-qcom.c index 826dc51..dc3d8c4 100644 --- a/arch/arm/mach-snapdragon/pinctrl-snapdragon.c +++ b/drivers/pinctrl/qcom/pinctrl-qcom.c @@ -11,17 +11,23 @@ #include <errno.h> #include <asm/io.h> #include <dm/device_compat.h> +#include <dm/device-internal.h> #include <dm/lists.h> +#include <asm/gpio.h> #include <dm/pinctrl.h> #include <linux/bitops.h> -#include "pinctrl-snapdragon.h" +#include <mach/gpio.h> + +#include "pinctrl-qcom.h" struct msm_pinctrl_priv { phys_addr_t base; struct msm_pinctrl_data *data; }; -#define GPIO_CONFIG_OFFSET(x) ((x) * 0x1000) +#define GPIO_CONFIG_REG(priv, x) \ + (qcom_pin_offset((priv)->data->pin_data.pin_offsets, x)) + #define TLMM_GPIO_PULL_MASK GENMASK(1, 0) #define TLMM_FUNC_SEL_MASK GENMASK(5, 2) #define TLMM_DRV_STRENGTH_MASK GENMASK(8, 6) @@ -44,7 +50,7 @@ static int msm_get_pins_count(struct udevice *dev) { struct msm_pinctrl_priv *priv = dev_get_priv(dev); - return priv->data->pin_count; + return priv->data->pin_data.pin_count; } static const char *msm_get_function_name(struct udevice *dev, @@ -60,7 +66,7 @@ static int msm_pinctrl_probe(struct udevice *dev) struct msm_pinctrl_priv *priv = dev_get_priv(dev); priv->base = dev_read_addr(dev); - priv->data = (struct msm_pinctrl_data *)dev->driver_data; + priv->data = (struct msm_pinctrl_data *)dev_get_driver_data(dev); return priv->base == FDT_ADDR_T_NONE ? -EINVAL : 0; } @@ -77,7 +83,7 @@ static int msm_pinmux_set(struct udevice *dev, unsigned int pin_selector, { struct msm_pinctrl_priv *priv = dev_get_priv(dev); - clrsetbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector), + clrsetbits_le32(priv->base + GPIO_CONFIG_REG(priv, pin_selector), TLMM_FUNC_SEL_MASK | TLMM_GPIO_DISABLE, priv->data->get_function_mux(func_selector) << 2); return 0; @@ -91,15 +97,15 @@ static int msm_pinconf_set(struct udevice *dev, unsigned int pin_selector, switch (param) { case PIN_CONFIG_DRIVE_STRENGTH: argument = (argument / 2) - 1; - clrsetbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector), + clrsetbits_le32(priv->base + GPIO_CONFIG_REG(priv, pin_selector), TLMM_DRV_STRENGTH_MASK, argument << 6); break; case PIN_CONFIG_BIAS_DISABLE: - clrbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector), + clrbits_le32(priv->base + GPIO_CONFIG_REG(priv, pin_selector), TLMM_GPIO_PULL_MASK); break; case PIN_CONFIG_BIAS_PULL_UP: - clrsetbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector), + clrsetbits_le32(priv->base + GPIO_CONFIG_REG(priv, pin_selector), TLMM_GPIO_PULL_MASK, argument); break; default: @@ -109,7 +115,7 @@ static int msm_pinconf_set(struct udevice *dev, unsigned int pin_selector, return 0; } -static struct pinctrl_ops msm_pinctrl_ops = { +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, @@ -121,12 +127,24 @@ static struct pinctrl_ops msm_pinctrl_ops = { .get_function_name = msm_get_function_name, }; -static int msm_pinctrl_bind(struct udevice *dev) +int msm_pinctrl_bind(struct udevice *dev) { ofnode node = dev_ofnode(dev); + struct msm_pinctrl_data *data = (struct msm_pinctrl_data *)dev_get_driver_data(dev); + struct driver *drv; + struct udevice *pinctrl_dev; const char *name; int ret; + drv = lists_driver_lookup_name("pinctrl_qcom"); + if (!drv) + return -ENOENT; + + ret = device_bind_with_driver_data(dev_get_parent(dev), drv, ofnode_get_name(node), (ulong)data, + dev_ofnode(dev), &pinctrl_dev); + if (ret) + return ret; + ofnode_get_property(node, "gpio-controller", &ret); if (ret < 0) return 0; @@ -136,31 +154,27 @@ static int msm_pinctrl_bind(struct udevice *dev) if (!name) return -EINVAL; - /* Bind gpio node */ - ret = device_bind_driver_to_node(dev, "gpio_msm", - name, node, NULL); - if (ret) - return ret; + drv = lists_driver_lookup_name("gpio_msm"); + if (!drv) { + printf("Can't find gpio_msm driver\n"); + return -ENODEV; + } - dev_dbg(dev, "bind %s\n", name); + /* Bind gpio device as a child of the pinctrl device */ + ret = device_bind_with_driver_data(pinctrl_dev, drv, + name, (ulong)&data->pin_data, node, NULL); + if (ret) { + device_unbind(pinctrl_dev); + return ret; + } return 0; } -static const struct udevice_id msm_pinctrl_ids[] = { - { .compatible = "qcom,msm8916-pinctrl", .data = (ulong)&apq8016_data }, - { .compatible = "qcom,msm8996-pinctrl", .data = (ulong)&apq8096_data }, - { .compatible = "qcom,sdm845-pinctrl", .data = (ulong)&sdm845_data }, - { .compatible = "qcom,qcs404-pinctrl", .data = (ulong)&qcs404_data }, - { } -}; - -U_BOOT_DRIVER(pinctrl_snapdraon) = { - .name = "pinctrl_msm", +U_BOOT_DRIVER(pinctrl_qcom) = { + .name = "pinctrl_qcom", .id = UCLASS_PINCTRL, - .of_match = msm_pinctrl_ids, .priv_auto = sizeof(struct msm_pinctrl_priv), .ops = &msm_pinctrl_ops, .probe = msm_pinctrl_probe, - .bind = msm_pinctrl_bind, }; diff --git a/arch/arm/mach-ipq40xx/pinctrl-snapdragon.h b/drivers/pinctrl/qcom/pinctrl-qcom.h index b4823a3..07f2eae 100644 --- a/arch/arm/mach-ipq40xx/pinctrl-snapdragon.h +++ b/drivers/pinctrl/qcom/pinctrl-qcom.h @@ -5,11 +5,16 @@ * (C) Copyright 2018 Ramon Fried <ramon.fried@gmail.com> * */ -#ifndef _PINCTRL_SNAPDRAGON_H -#define _PINCTRL_SNAPDRAGON_H +#ifndef _PINCTRL_QCOM_H +#define _PINCTRL_QCOM_H + +#include <asm/types.h> +#include <mach/gpio.h> + +struct udevice; struct msm_pinctrl_data { - int pin_count; + struct msm_pin_data pin_data; int functions_count; const char *(*get_function_name)(struct udevice *dev, unsigned int selector); @@ -23,6 +28,8 @@ struct pinctrl_function { int val; }; -extern struct msm_pinctrl_data ipq4019_data; +extern struct pinctrl_ops msm_pinctrl_ops; + +int msm_pinctrl_bind(struct udevice *dev); #endif diff --git a/arch/arm/mach-snapdragon/pinctrl-qcs404.c b/drivers/pinctrl/qcom/pinctrl-qcs404.c index a6e53c4..ac00afa 100644 --- a/arch/arm/mach-snapdragon/pinctrl-qcs404.c +++ b/drivers/pinctrl/qcom/pinctrl-qcs404.c @@ -5,8 +5,10 @@ * (C) Copyright 2022 Sumit Garg <sumit.garg@linaro.org> */ -#include "pinctrl-snapdragon.h" #include <common.h> +#include <dm.h> + +#include "pinctrl-qcom.h" #define MAX_PIN_NAME_LEN 32 static char pin_name[MAX_PIN_NAME_LEN] __section(".data"); @@ -59,10 +61,23 @@ static unsigned int qcs404_get_function_mux(unsigned int selector) return msm_pinctrl_functions[selector].val; } -struct msm_pinctrl_data qcs404_data = { - .pin_count = 126, +static struct msm_pinctrl_data qcs404_data = { + .pin_data = { .pin_count = 126, }, .functions_count = ARRAY_SIZE(msm_pinctrl_functions), .get_function_name = qcs404_get_function_name, .get_function_mux = qcs404_get_function_mux, .get_pin_name = qcs404_get_pin_name, }; + +static const struct udevice_id msm_pinctrl_ids[] = { + { .compatible = "qcom,qcs404-pinctrl", .data = (ulong)&qcs404_data }, + { /* Sentinal */ } +}; + +U_BOOT_DRIVER(pinctrl_qcs404) = { + .name = "pinctrl_qcs404", + .id = UCLASS_NOP, + .of_match = msm_pinctrl_ids, + .ops = &msm_pinctrl_ops, + .bind = msm_pinctrl_bind, +}; diff --git a/drivers/pinctrl/qcom/pinctrl-sdm845.c b/drivers/pinctrl/qcom/pinctrl-sdm845.c new file mode 100644 index 0000000..9f0f408 --- /dev/null +++ b/drivers/pinctrl/qcom/pinctrl-sdm845.c @@ -0,0 +1,100 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Qualcomm SDM845 pinctrl + * + * (C) Copyright 2021 Dzmitry Sankouski <dsankouski@gmail.com> + * (C) Copyright 2023 Linaro Ltd. + * + */ + +#include <common.h> +#include <dm.h> + +#include "pinctrl-qcom.h" + +#define NORTH 0x00500000 +#define SOUTH 0x00900000 +#define EAST 0x00100000 + +#define MAX_PIN_NAME_LEN 32 +static char pin_name[MAX_PIN_NAME_LEN] __section(".data"); + +static const struct pinctrl_function msm_pinctrl_functions[] = { + {"qup9", 1}, + {"gpio", 0}, +}; + +static const unsigned int sdm845_pin_offsets[] = { + [0] = EAST, [1] = EAST, [2] = EAST, [3] = EAST, [4] = NORTH, + [5] = NORTH, [6] = NORTH, [7] = NORTH, [8] = EAST, [9] = EAST, + [10] = EAST, [11] = EAST, [12] = SOUTH, [13] = SOUTH, [14] = SOUTH, + [15] = SOUTH, [16] = SOUTH, [17] = SOUTH, [18] = SOUTH, [19] = SOUTH, + [20] = SOUTH, [21] = SOUTH, [22] = SOUTH, [23] = SOUTH, [24] = SOUTH, + [25] = SOUTH, [26] = SOUTH, [27] = EAST, [28] = EAST, [29] = EAST, + [30] = EAST, [31] = NORTH, [32] = NORTH, [33] = NORTH, [34] = NORTH, + [35] = SOUTH, [36] = SOUTH, [37] = SOUTH, [38] = NORTH, [39] = EAST, + [40] = SOUTH, [41] = EAST, [42] = EAST, [43] = EAST, [44] = EAST, + [45] = EAST, [46] = EAST, [47] = EAST, [48] = EAST, [49] = NORTH, + [50] = NORTH, [51] = NORTH, [52] = NORTH, [53] = NORTH, [54] = NORTH, + [55] = NORTH, [56] = NORTH, [57] = NORTH, [58] = NORTH, [59] = NORTH, + [60] = NORTH, [61] = NORTH, [62] = NORTH, [63] = NORTH, [64] = NORTH, + [65] = NORTH, [66] = NORTH, [67] = NORTH, [68] = NORTH, [69] = EAST, + [70] = EAST, [71] = EAST, [72] = EAST, [73] = EAST, [74] = EAST, + [75] = EAST, [76] = EAST, [77] = EAST, [78] = EAST, [79] = NORTH, + [80] = NORTH, [81] = NORTH, [82] = NORTH, [83] = NORTH, [84] = NORTH, + [85] = EAST, [86] = EAST, [87] = EAST, [88] = EAST, [89] = SOUTH, + [90] = SOUTH, [91] = SOUTH, [92] = SOUTH, [93] = SOUTH, [94] = SOUTH, + [95] = SOUTH, [96] = SOUTH, [97] = NORTH, [98] = NORTH, [99] = NORTH, + [100] = NORTH, [101] = NORTH, [102] = NORTH, [103] = NORTH, [104] = NORTH, + [105] = NORTH, [106] = NORTH, [107] = NORTH, [108] = NORTH, [109] = NORTH, + [110] = NORTH, [111] = NORTH, [112] = NORTH, [113] = NORTH, [114] = NORTH, + [115] = NORTH, [116] = NORTH, [117] = NORTH, [118] = NORTH, [119] = NORTH, + [120] = NORTH, [121] = NORTH, [122] = EAST, [123] = EAST, [124] = EAST, + [125] = EAST, [126] = EAST, [127] = NORTH, [128] = NORTH, [129] = NORTH, + [130] = NORTH, [131] = NORTH, [132] = NORTH, [133] = NORTH, [134] = NORTH, + [135] = NORTH, [136] = NORTH, [137] = NORTH, [138] = NORTH, [139] = NORTH, + [140] = NORTH, [141] = NORTH, [142] = NORTH, [143] = NORTH, [144] = NORTH, + [145] = NORTH, [146] = NORTH, [147] = NORTH, [148] = NORTH, [149] = NORTH, +}; + +static const char *sdm845_get_function_name(struct udevice *dev, + unsigned int selector) +{ + return msm_pinctrl_functions[selector].name; +} + +static const char *sdm845_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 sdm845_get_function_mux(unsigned int selector) +{ + return msm_pinctrl_functions[selector].val; +} + +static struct msm_pinctrl_data sdm845_data = { + .pin_data = { + .pin_offsets = sdm845_pin_offsets, + .pin_count = ARRAY_SIZE(sdm845_pin_offsets), + }, + .functions_count = ARRAY_SIZE(msm_pinctrl_functions), + .get_function_name = sdm845_get_function_name, + .get_function_mux = sdm845_get_function_mux, + .get_pin_name = sdm845_get_pin_name, +}; + +static const struct udevice_id msm_pinctrl_ids[] = { + { .compatible = "qcom,sdm845-pinctrl", .data = (ulong)&sdm845_data }, + { /* Sentinal */ } +}; + +U_BOOT_DRIVER(pinctrl_sdm845) = { + .name = "pinctrl_sdm845", + .id = UCLASS_NOP, + .of_match = msm_pinctrl_ids, + .ops = &msm_pinctrl_ops, + .bind = msm_pinctrl_bind, +}; diff --git a/drivers/power/pmic/pmic_qcom.c b/drivers/power/pmic/pmic_qcom.c index ad8daf4..f2ac649 100644 --- a/drivers/power/pmic/pmic_qcom.c +++ b/drivers/power/pmic/pmic_qcom.c @@ -66,12 +66,19 @@ static const struct udevice_id pmic_qcom_ids[] = { static int pmic_qcom_probe(struct udevice *dev) { struct pmic_qcom_priv *priv = dev_get_priv(dev); - - priv->usid = dev_read_addr(dev); - - if (priv->usid == FDT_ADDR_T_NONE) + int ret; + + /* + * dev_read_addr() can't be used here because the reg property actually + * contains two discrete values, not a single 64-bit address. + * The address is the first value. + */ + ret = ofnode_read_u32_index(dev_ofnode(dev), "reg", 0, &priv->usid); + if (ret < 0) return -EINVAL; + debug("usid: %d\n", priv->usid); + return 0; } diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 73bbd30..88e04d9 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -156,13 +156,6 @@ config RESET_IMX7 help Support for reset controller on i.MX7/8 SoCs. -config RESET_QCOM - bool "Reset driver for Qualcomm SoCs" - depends on DM_RESET && (ARCH_SNAPDRAGON || ARCH_IPQ40XX) - default y - help - Support for reset controller on Qualcomm SoCs. - config RESET_SIFIVE bool "Reset Driver for SiFive SoC's" depends on DM_RESET && CLK_SIFIVE_PRCI && (TARGET_SIFIVE_UNLEASHED || TARGET_SIFIVE_UNMATCHED) diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index e2239a2..7b0066f 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -24,7 +24,6 @@ obj-$(CONFIG_RESET_MTMIPS) += reset-mtmips.o obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o obj-$(CONFIG_RESET_HISILICON) += reset-hisilicon.o obj-$(CONFIG_RESET_IMX7) += reset-imx7.o -obj-$(CONFIG_RESET_QCOM) += reset-qcom.o obj-$(CONFIG_RESET_SIFIVE) += reset-sifive.o obj-$(CONFIG_RESET_SYSCON) += reset-syscon.o obj-$(CONFIG_RESET_RASPBERRYPI) += reset-raspberrypi.o diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 6628a88..26460c4 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -972,8 +972,6 @@ config MSM_SERIAL config MSM_GENI_SERIAL bool "Qualcomm on-chip GENI UART" - select MISC - imply QCOM_GENI_SE help Support UART based on Generic Interface (GENI) Serial Engine (SE), used on Qualcomm Snapdragon SoCs. Should support all qualcomm SOCs diff --git a/drivers/serial/serial_msm_geni.c b/drivers/serial/serial_msm_geni.c index b8bc614..e5c3dcf 100644 --- a/drivers/serial/serial_msm_geni.c +++ b/drivers/serial/serial_msm_geni.c @@ -188,8 +188,8 @@ static int geni_serial_set_clock_rate(struct udevice *dev, u64 rate) int ret; clk = devm_clk_get(dev, NULL); - if (!clk) - return -EINVAL; + if (IS_ERR(clk)) + return PTR_ERR(clk); ret = clk_set_rate(clk, rate); return ret; @@ -248,11 +248,16 @@ static int msm_serial_setbrg(struct udevice *dev, int baud) struct msm_serial_data *priv = dev_get_priv(dev); u64 clk_rate; u32 clk_div; + int ret; priv->baud = baud; clk_rate = get_clk_div_rate(baud, priv->oversampling, &clk_div); - geni_serial_set_clock_rate(dev, clk_rate); + ret = geni_serial_set_clock_rate(dev, clk_rate); + if (ret < 0) { + pr_err("%s: Couldn't set clock rate: %d\n", __func__, ret); + return ret; + } geni_serial_baud(priv->base, clk_div, baud); return 0; @@ -485,12 +490,12 @@ static const struct dm_serial_ops msm_serial_ops = { .setbrg = msm_serial_setbrg, }; -static void geni_set_oversampling(struct udevice *dev) +static int geni_set_oversampling(struct udevice *dev) { struct msm_serial_data *priv = dev_get_priv(dev); - struct udevice *parent_dev = dev_get_parent(dev); + ofnode parent_node = ofnode_get_parent(dev_ofnode(dev)); u32 geni_se_version; - int ret; + fdt_addr_t addr; priv->oversampling = UART_OVERSAMPLING; @@ -498,16 +503,20 @@ static void geni_set_oversampling(struct udevice *dev) * It could happen that GENI SE IP is missing in the board's device * tree or GENI UART node is a direct child of SoC device tree node. */ - if (device_get_uclass_id(parent_dev) != UCLASS_MISC) - return; + if (!ofnode_device_is_compatible(parent_node, "qcom,geni-se-qup")) { + pr_err("%s: UART node must be a child of geniqup node\n", + __func__); + return -ENODEV; + } - ret = misc_read(parent_dev, QUP_HW_VER_REG, - &geni_se_version, sizeof(geni_se_version)); - if (ret != sizeof(geni_se_version)) - return; + /* Read the HW_VER register relative to the parents address space */ + addr = ofnode_get_addr(parent_node); + geni_se_version = readl(addr + QUP_HW_VER_REG); if (geni_se_version >= QUP_SE_VERSION_2_5) priv->oversampling /= 2; + + return 0; } static inline void geni_serial_init(struct udevice *dev) @@ -552,8 +561,11 @@ static inline void geni_serial_init(struct udevice *dev) static int msm_serial_probe(struct udevice *dev) { struct msm_serial_data *priv = dev_get_priv(dev); + int ret; - geni_set_oversampling(dev); + ret = geni_set_oversampling(dev); + if (ret < 0) + return ret; /* No need to reinitialize the UART after relocation */ if (gd->flags & GD_FLG_RELOC) diff --git a/drivers/spmi/spmi-msm.c b/drivers/spmi/spmi-msm.c index 27a035c..5fe8a70 100644 --- a/drivers/spmi/spmi-msm.c +++ b/drivers/spmi/spmi-msm.c @@ -70,7 +70,7 @@ enum pmic_arb_channel { struct msm_spmi_priv { phys_addr_t arb_chnl; /* ARB channel mapping base */ - phys_addr_t spmi_core; /* SPMI core */ + phys_addr_t spmi_chnls; /* SPMI channels */ phys_addr_t spmi_obs; /* SPMI observer */ /* SPMI channel map */ uint8_t channel_map[SPMI_MAX_SLAVES][SPMI_MAX_PERIPH]; @@ -95,10 +95,10 @@ static int msm_spmi_write(struct udevice *dev, int usid, int pid, int off, /* Disable IRQ mode for the current channel*/ writel(0x0, - priv->spmi_core + SPMI_CH_OFFSET(channel) + SPMI_REG_CONFIG); + priv->spmi_chnls + SPMI_CH_OFFSET(channel) + SPMI_REG_CONFIG); /* Write single byte */ - writel(val, priv->spmi_core + SPMI_CH_OFFSET(channel) + SPMI_REG_WDATA); + writel(val, priv->spmi_chnls + SPMI_CH_OFFSET(channel) + SPMI_REG_WDATA); /* Prepare write command */ reg |= SPMI_CMD_EXT_REG_WRITE_LONG << SPMI_CMD_OPCODE_SHIFT; @@ -113,12 +113,12 @@ static int msm_spmi_write(struct udevice *dev, int usid, int pid, int off, ch_offset = SPMI_CH_OFFSET(channel); /* Send write command */ - writel(reg, priv->spmi_core + SPMI_CH_OFFSET(channel) + SPMI_REG_CMD0); + writel(reg, priv->spmi_chnls + SPMI_CH_OFFSET(channel) + SPMI_REG_CMD0); /* Wait till CMD DONE status */ reg = 0; while (!reg) { - reg = readl(priv->spmi_core + SPMI_CH_OFFSET(channel) + + reg = readl(priv->spmi_chnls + SPMI_CH_OFFSET(channel) + SPMI_REG_STATUS); } @@ -186,47 +186,37 @@ static struct dm_spmi_ops msm_spmi_ops = { static int msm_spmi_probe(struct udevice *dev) { struct msm_spmi_priv *priv = dev_get_priv(dev); - phys_addr_t config_addr; + phys_addr_t core_addr; u32 hw_ver; - u32 version; int i; - int err; - config_addr = dev_read_addr_index(dev, 0); - priv->spmi_core = dev_read_addr_index(dev, 1); - priv->spmi_obs = dev_read_addr_index(dev, 2); + core_addr = dev_read_addr_name(dev, "core"); + priv->spmi_chnls = dev_read_addr_name(dev, "chnls"); + priv->spmi_obs = dev_read_addr_name(dev, "obsrvr"); - hw_ver = readl(config_addr + PMIC_ARB_VERSION); + hw_ver = readl(core_addr + PMIC_ARB_VERSION); if (hw_ver < PMIC_ARB_VERSION_V3_MIN) { priv->arb_ver = V2; - version = 2; - priv->arb_chnl = config_addr + APID_MAP_OFFSET_V1_V2_V3; + priv->arb_chnl = core_addr + APID_MAP_OFFSET_V1_V2_V3; } else if (hw_ver < PMIC_ARB_VERSION_V5_MIN) { priv->arb_ver = V3; - version = 3; - priv->arb_chnl = config_addr + APID_MAP_OFFSET_V1_V2_V3; + priv->arb_chnl = core_addr + APID_MAP_OFFSET_V1_V2_V3; } else { priv->arb_ver = V5; - version = 5; - priv->arb_chnl = config_addr + APID_MAP_OFFSET_V5; - - if (err) { - dev_err(dev, "could not read APID->PPID mapping table, rc= %d\n", err); - return -1; - } + priv->arb_chnl = core_addr + APID_MAP_OFFSET_V5; } - dev_dbg(dev, "PMIC Arb Version-%d (0x%x)\n", version, hw_ver); + dev_dbg(dev, "PMIC Arb Version-%d (%#x)\n", hw_ver >> 28, hw_ver); if (priv->arb_chnl == FDT_ADDR_T_NONE || - priv->spmi_core == FDT_ADDR_T_NONE || + priv->spmi_chnls == FDT_ADDR_T_NONE || priv->spmi_obs == FDT_ADDR_T_NONE) return -EINVAL; - dev_dbg(dev, "priv->arb_chnl address (%llu)\n", priv->arb_chnl); - dev_dbg(dev, "priv->spmi_core address (%llu)\n", priv->spmi_core); - dev_dbg(dev, "priv->spmi_obs address (%llu)\n", priv->spmi_obs); + dev_dbg(dev, "priv->arb_chnl address (%#08llx)\n", priv->arb_chnl); + dev_dbg(dev, "priv->spmi_chnls address (%#08llx)\n", priv->spmi_chnls); + dev_dbg(dev, "priv->spmi_obs address (%#08llx)\n", priv->spmi_obs); /* Scan peripherals connected to each SPMI channel */ for (i = 0; i < SPMI_MAX_PERIPH; i++) { uint32_t periph = readl(priv->arb_chnl + ARB_CHANNEL_OFFSET(i)); diff --git a/include/configs/dragonboard410c.h b/include/configs/dragonboard410c.h index 73aec34..00102cd 100644 --- a/include/configs/dragonboard410c.h +++ b/include/configs/dragonboard410c.h @@ -9,7 +9,6 @@ #define __CONFIGS_DRAGONBOARD410C_H #include <linux/sizes.h> -#include <asm/arch/sysmap-apq8016.h> /* Build new ELF image from u-boot.bin (U-Boot + appended DTB) */ diff --git a/include/configs/dragonboard820c.h b/include/configs/dragonboard820c.h index 4997083..c6d9182 100644 --- a/include/configs/dragonboard820c.h +++ b/include/configs/dragonboard820c.h @@ -9,7 +9,6 @@ #define __CONFIGS_DRAGONBOARD820C_H #include <linux/sizes.h> -#include <asm/arch/sysmap-apq8096.h> /* Physical Memory Map */ diff --git a/include/configs/dragonboard845c.h b/include/configs/dragonboard845c.h index c1e590f..14a8a2c 100644 --- a/include/configs/dragonboard845c.h +++ b/include/configs/dragonboard845c.h @@ -9,7 +9,6 @@ #define __CONFIGS_SDM845_H #include <linux/sizes.h> -#include <asm/arch/sysmap-sdm845.h> #define CFG_SYS_BAUDRATE_TABLE { 115200, 230400, 460800, 921600 } diff --git a/include/configs/qcs404-evb.h b/include/configs/qcs404-evb.h index 8ea59aa..9501d43 100644 --- a/include/configs/qcs404-evb.h +++ b/include/configs/qcs404-evb.h @@ -9,7 +9,6 @@ #define __CONFIGS_QCS404EVB_H #include <linux/sizes.h> -#include <asm/arch/sysmap-qcs404.h> #define CFG_SYS_BAUDRATE_TABLE { 115200, 230400, 460800, 921600 } diff --git a/include/configs/sdm845.h b/include/configs/sdm845.h index 673268d..5ad8569 100644 --- a/include/configs/sdm845.h +++ b/include/configs/sdm845.h @@ -9,7 +9,6 @@ #define __CONFIGS_SDM845_H #include <linux/sizes.h> -#include <asm/arch/sysmap-sdm845.h> #define CFG_SYS_BAUDRATE_TABLE { 115200, 230400, 460800, 921600 } diff --git a/include/dt-bindings/clock/qcom,ipq4019-gcc.h b/include/dt-bindings/clock/qcom,gcc-ipq4019.h index 7130e22..7e8a7be 100644 --- a/include/dt-bindings/clock/qcom,ipq4019-gcc.h +++ b/include/dt-bindings/clock/qcom,gcc-ipq4019.h @@ -93,4 +93,77 @@ #define GCC_APSS_CPU_PLLDIV_CLK 74 #define GCC_PCNOC_AHB_CLK_SRC 75 +#define WIFI0_CPU_INIT_RESET 0 +#define WIFI0_RADIO_SRIF_RESET 1 +#define WIFI0_RADIO_WARM_RESET 2 +#define WIFI0_RADIO_COLD_RESET 3 +#define WIFI0_CORE_WARM_RESET 4 +#define WIFI0_CORE_COLD_RESET 5 +#define WIFI1_CPU_INIT_RESET 6 +#define WIFI1_RADIO_SRIF_RESET 7 +#define WIFI1_RADIO_WARM_RESET 8 +#define WIFI1_RADIO_COLD_RESET 9 +#define WIFI1_CORE_WARM_RESET 10 +#define WIFI1_CORE_COLD_RESET 11 +#define USB3_UNIPHY_PHY_ARES 12 +#define USB3_HSPHY_POR_ARES 13 +#define USB3_HSPHY_S_ARES 14 +#define USB2_HSPHY_POR_ARES 15 +#define USB2_HSPHY_S_ARES 16 +#define PCIE_PHY_AHB_ARES 17 +#define PCIE_AHB_ARES 18 +#define PCIE_PWR_ARES 19 +#define PCIE_PIPE_STICKY_ARES 20 +#define PCIE_AXI_M_STICKY_ARES 21 +#define PCIE_PHY_ARES 22 +#define PCIE_PARF_XPU_ARES 23 +#define PCIE_AXI_S_XPU_ARES 24 +#define PCIE_AXI_M_VMIDMT_ARES 25 +#define PCIE_PIPE_ARES 26 +#define PCIE_AXI_S_ARES 27 +#define PCIE_AXI_M_ARES 28 +#define ESS_RESET 29 +#define GCC_BLSP1_BCR 30 +#define GCC_BLSP1_QUP1_BCR 31 +#define GCC_BLSP1_UART1_BCR 32 +#define GCC_BLSP1_QUP2_BCR 33 +#define GCC_BLSP1_UART2_BCR 34 +#define GCC_BIMC_BCR 35 +#define GCC_TLMM_BCR 36 +#define GCC_IMEM_BCR 37 +#define GCC_ESS_BCR 38 +#define GCC_PRNG_BCR 39 +#define GCC_BOOT_ROM_BCR 40 +#define GCC_CRYPTO_BCR 41 +#define GCC_SDCC1_BCR 42 +#define GCC_SEC_CTRL_BCR 43 +#define GCC_AUDIO_BCR 44 +#define GCC_QPIC_BCR 45 +#define GCC_PCIE_BCR 46 +#define GCC_USB2_BCR 47 +#define GCC_USB2_PHY_BCR 48 +#define GCC_USB3_BCR 49 +#define GCC_USB3_PHY_BCR 50 +#define GCC_SYSTEM_NOC_BCR 51 +#define GCC_PCNOC_BCR 52 +#define GCC_DCD_BCR 53 +#define GCC_SNOC_BUS_TIMEOUT0_BCR 54 +#define GCC_SNOC_BUS_TIMEOUT1_BCR 55 +#define GCC_SNOC_BUS_TIMEOUT2_BCR 56 +#define GCC_SNOC_BUS_TIMEOUT3_BCR 57 +#define GCC_PCNOC_BUS_TIMEOUT0_BCR 58 +#define GCC_PCNOC_BUS_TIMEOUT1_BCR 59 +#define GCC_PCNOC_BUS_TIMEOUT2_BCR 60 +#define GCC_PCNOC_BUS_TIMEOUT3_BCR 61 +#define GCC_PCNOC_BUS_TIMEOUT4_BCR 62 +#define GCC_PCNOC_BUS_TIMEOUT5_BCR 63 +#define GCC_PCNOC_BUS_TIMEOUT6_BCR 64 +#define GCC_PCNOC_BUS_TIMEOUT7_BCR 65 +#define GCC_PCNOC_BUS_TIMEOUT8_BCR 66 +#define GCC_PCNOC_BUS_TIMEOUT9_BCR 67 +#define GCC_TCSR_BCR 68 +#define GCC_QDSS_BCR 69 +#define GCC_MPM_BCR 70 +#define GCC_SPDM_BCR 71 + #endif diff --git a/include/dt-bindings/reset/qcom,ipq4019-reset.h b/include/dt-bindings/reset/qcom,ipq4019-reset.h deleted file mode 100644 index ed047d7..0000000 --- a/include/dt-bindings/reset/qcom,ipq4019-reset.h +++ /dev/null @@ -1,92 +0,0 @@ -/* Copyright (c) 2015 The Linux Foundation. All rights reserved. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ -#ifndef __QCOM_RESET_IPQ4019_H__ -#define __QCOM_RESET_IPQ4019_H__ - -#define WIFI0_CPU_INIT_RESET 0 -#define WIFI0_RADIO_SRIF_RESET 1 -#define WIFI0_RADIO_WARM_RESET 2 -#define WIFI0_RADIO_COLD_RESET 3 -#define WIFI0_CORE_WARM_RESET 4 -#define WIFI0_CORE_COLD_RESET 5 -#define WIFI1_CPU_INIT_RESET 6 -#define WIFI1_RADIO_SRIF_RESET 7 -#define WIFI1_RADIO_WARM_RESET 8 -#define WIFI1_RADIO_COLD_RESET 9 -#define WIFI1_CORE_WARM_RESET 10 -#define WIFI1_CORE_COLD_RESET 11 -#define USB3_UNIPHY_PHY_ARES 12 -#define USB3_HSPHY_POR_ARES 13 -#define USB3_HSPHY_S_ARES 14 -#define USB2_HSPHY_POR_ARES 15 -#define USB2_HSPHY_S_ARES 16 -#define PCIE_PHY_AHB_ARES 17 -#define PCIE_AHB_ARES 18 -#define PCIE_PWR_ARES 19 -#define PCIE_PIPE_STICKY_ARES 20 -#define PCIE_AXI_M_STICKY_ARES 21 -#define PCIE_PHY_ARES 22 -#define PCIE_PARF_XPU_ARES 23 -#define PCIE_AXI_S_XPU_ARES 24 -#define PCIE_AXI_M_VMIDMT_ARES 25 -#define PCIE_PIPE_ARES 26 -#define PCIE_AXI_S_ARES 27 -#define PCIE_AXI_M_ARES 28 -#define ESS_RESET 29 -#define GCC_BLSP1_BCR 30 -#define GCC_BLSP1_QUP1_BCR 31 -#define GCC_BLSP1_UART1_BCR 32 -#define GCC_BLSP1_QUP2_BCR 33 -#define GCC_BLSP1_UART2_BCR 34 -#define GCC_BIMC_BCR 35 -#define GCC_TLMM_BCR 36 -#define GCC_IMEM_BCR 37 -#define GCC_ESS_BCR 38 -#define GCC_PRNG_BCR 39 -#define GCC_BOOT_ROM_BCR 40 -#define GCC_CRYPTO_BCR 41 -#define GCC_SDCC1_BCR 42 -#define GCC_SEC_CTRL_BCR 43 -#define GCC_AUDIO_BCR 44 -#define GCC_QPIC_BCR 45 -#define GCC_PCIE_BCR 46 -#define GCC_USB2_BCR 47 -#define GCC_USB2_PHY_BCR 48 -#define GCC_USB3_BCR 49 -#define GCC_USB3_PHY_BCR 50 -#define GCC_SYSTEM_NOC_BCR 51 -#define GCC_PCNOC_BCR 52 -#define GCC_DCD_BCR 53 -#define GCC_SNOC_BUS_TIMEOUT0_BCR 54 -#define GCC_SNOC_BUS_TIMEOUT1_BCR 55 -#define GCC_SNOC_BUS_TIMEOUT2_BCR 56 -#define GCC_SNOC_BUS_TIMEOUT3_BCR 57 -#define GCC_PCNOC_BUS_TIMEOUT0_BCR 58 -#define GCC_PCNOC_BUS_TIMEOUT1_BCR 59 -#define GCC_PCNOC_BUS_TIMEOUT2_BCR 60 -#define GCC_PCNOC_BUS_TIMEOUT3_BCR 61 -#define GCC_PCNOC_BUS_TIMEOUT4_BCR 62 -#define GCC_PCNOC_BUS_TIMEOUT5_BCR 63 -#define GCC_PCNOC_BUS_TIMEOUT6_BCR 64 -#define GCC_PCNOC_BUS_TIMEOUT7_BCR 65 -#define GCC_PCNOC_BUS_TIMEOUT8_BCR 66 -#define GCC_PCNOC_BUS_TIMEOUT9_BCR 67 -#define GCC_TCSR_BCR 68 -#define GCC_QDSS_BCR 69 -#define GCC_MPM_BCR 70 -#define GCC_SPDM_BCR 71 - -#endif diff --git a/test/dm/spmi.c b/test/dm/spmi.c index 9cc284b..97bb0eb 100644 --- a/test/dm/spmi.c +++ b/test/dm/spmi.c @@ -81,7 +81,7 @@ static int dm_test_spmi_access_peripheral(struct unit_test_state *uts) int offset_count; /* Get second pin of PMIC GPIO */ - ut_assertok(gpio_lookup_name("spmi1", &dev, &offset, &gpio)); + ut_assertok(gpio_lookup_name("pmic1", &dev, &offset, &gpio)); /* Check if PMIC is parent */ ut_asserteq(device_get_uclass_id(dev->parent), UCLASS_PMIC); @@ -92,7 +92,7 @@ static int dm_test_spmi_access_peripheral(struct unit_test_state *uts) name = gpio_get_bank_info(dev, &offset_count); /* Check bank name */ - ut_asserteq_str("spmi", name); + ut_asserteq_str("pmic", name); /* Check pin count */ ut_asserteq(4, offset_count); |