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
This commit is contained in:
Tom Rini 2024-01-16 09:51:16 -05:00
commit 043ca8c8a9
81 changed files with 1772 additions and 1791 deletions

View File

@ -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

View File

@ -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

View File

@ -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>;
};
};

View File

@ -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";
};
};

View File

@ -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";
};
};

View File

@ -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.";
};
};

View File

@ -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";
};
};

View File

@ -41,4 +41,8 @@
};
};
&pm8998_resin {
status = "okay";
};
#include "dragonboard845c-uboot.dtsi"

View File

@ -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";
};

View File

@ -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";
};
};
};

View File

@ -26,23 +26,13 @@
#power-domain-cells = <1>;
};
gpio_north: gpio_north@3900000 {
#gpio-cells = <2>;
tlmm: pinctrl@3400000 {
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 {
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.";
};
};

View File

@ -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";
};
};

View File

@ -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;
};
};

View File

@ -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

View File

@ -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,
};

View File

@ -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,
};

View File

@ -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:

View File

@ -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

View File

@ -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;
}

View File

@ -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,
};

View File

@ -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

View File

@ -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_ */

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 {

View File

@ -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,
};

View File

@ -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

View File

@ -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";
};
};
};

View File

@ -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;

View File

@ -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;
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("bootdelay", "-1");
printf("Power button pressed - dropping to console.\n");
}

View File

@ -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

View File

@ -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;
};

View File

@ -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";
};
};
};

View File

@ -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>;
};

View File

@ -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

View File

@ -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

View File

@ -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),
};

View File

@ -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"

View File

@ -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/

52
drivers/clk/qcom/Kconfig Normal file
View File

@ -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

10
drivers/clk/qcom/Makefile Normal file
View File

@ -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

View File

@ -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,
};

View File

@ -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,
};

View File

@ -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,
};

View File

@ -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,
};

View File

@ -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

View File

@ -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,
};

View File

@ -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,
};

View File

@ -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"

View File

@ -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)

View File

@ -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;
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";
ret = qcom_gpio_of_parse_ranges(dev);
if (ret > 0)
uc_priv->gpio_count = ret;
else
return ret;
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),
};

View File

@ -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

View File

@ -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

View File

@ -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,
};

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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,
};

View File

@ -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,
};

View File

@ -7,12 +7,13 @@
* Author: Robert Marko <robert.marko@sartura.hr>
*/
#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];
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,
};

View File

@ -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,
};

View File

@ -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

View File

@ -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,
};

View File

@ -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,
};

View File

@ -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);
int ret;
priv->usid = dev_read_addr(dev);
if (priv->usid == FDT_ADDR_T_NONE)
/*
* 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;
}

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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));

View File

@ -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) */

View File

@ -9,7 +9,6 @@
#define __CONFIGS_DRAGONBOARD820C_H
#include <linux/sizes.h>
#include <asm/arch/sysmap-apq8096.h>
/* Physical Memory Map */

View File

@ -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 }

View File

@ -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 }

View File

@ -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 }

View File

@ -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

View File

@ -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

View File

@ -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);