mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2026-05-05 04:36:13 +02:00
Merge tag 'qcom-2024.04-rc1' of https://gitlab.denx.de/u-boot/custodians/u-boot-snapdragon
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:
commit
043ca8c8a9
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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>;
|
||||
};
|
||||
};
|
||||
|
||||
@ -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";
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@ -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";
|
||||
};
|
||||
};
|
||||
|
||||
@ -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.";
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@ -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";
|
||||
};
|
||||
};
|
||||
|
||||
@ -41,4 +41,8 @@
|
||||
};
|
||||
};
|
||||
|
||||
&pm8998_resin {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
#include "dragonboard845c-uboot.dtsi"
|
||||
|
||||
@ -66,14 +66,6 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
reset: gcc-reset@1800000 {
|
||||
compatible = "qcom,gcc-reset-ipq4019";
|
||||
reg = <0x1800000 0x60000>;
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
bootph-all;
|
||||
};
|
||||
|
||||
soc_gpios: pinctrl@1000000 {
|
||||
compatible = "qcom,ipq4019-pinctrl";
|
||||
reg = <0x1000000 0x300000>;
|
||||
@ -136,7 +128,7 @@
|
||||
#phy-cells = <0>;
|
||||
reg = <0x9a000 0x800>;
|
||||
reg-names = "phy_base";
|
||||
resets = <&reset USB3_UNIPHY_PHY_ARES>;
|
||||
resets = <&gcc USB3_UNIPHY_PHY_ARES>;
|
||||
reset-names = "por_rst";
|
||||
status = "disabled";
|
||||
};
|
||||
@ -146,7 +138,7 @@
|
||||
#phy-cells = <0>;
|
||||
reg = <0xa6000 0x40>;
|
||||
reg-names = "phy_base";
|
||||
resets = <&reset USB3_HSPHY_POR_ARES>, <&reset USB3_HSPHY_S_ARES>;
|
||||
resets = <&gcc USB3_HSPHY_POR_ARES>, <&gcc USB3_HSPHY_S_ARES>;
|
||||
reset-names = "por_rst", "srif_rst";
|
||||
status = "disabled";
|
||||
};
|
||||
@ -179,7 +171,7 @@
|
||||
#phy-cells = <0>;
|
||||
reg = <0xa8000 0x40>;
|
||||
reg-names = "phy_base";
|
||||
resets = <&reset USB2_HSPHY_POR_ARES>, <&reset USB2_HSPHY_S_ARES>;
|
||||
resets = <&gcc USB2_HSPHY_POR_ARES>, <&gcc USB2_HSPHY_S_ARES>;
|
||||
reset-names = "por_rst", "srif_rst";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
@ -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";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@ -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.";
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@ -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";
|
||||
};
|
||||
};
|
||||
|
||||
@ -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;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@ -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
|
||||
@ -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,
|
||||
};
|
||||
@ -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,
|
||||
};
|
||||
@ -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:
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
}
|
||||
@ -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,
|
||||
};
|
||||
@ -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
|
||||
@ -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_ */
|
||||
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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 {
|
||||
|
||||
@ -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,
|
||||
};
|
||||
@ -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
|
||||
@ -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";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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");
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
};
|
||||
@ -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";
|
||||
};
|
||||
};
|
||||
};
|
||||
@ -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>;
|
||||
};
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
165
drivers/button/button-qcom-pmic.c
Normal file
165
drivers/button/button-qcom-pmic.c
Normal 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),
|
||||
};
|
||||
@ -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"
|
||||
|
||||
@ -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
52
drivers/clk/qcom/Kconfig
Normal 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
10
drivers/clk/qcom/Makefile
Normal 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
|
||||
@ -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,
|
||||
};
|
||||
@ -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,
|
||||
};
|
||||
@ -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,
|
||||
};
|
||||
307
drivers/clk/qcom/clock-qcom.c
Normal file
307
drivers/clk/qcom/clock-qcom.c
Normal 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,
|
||||
};
|
||||
100
drivers/clk/qcom/clock-qcom.h
Normal file
100
drivers/clk/qcom/clock-qcom.h
Normal 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
|
||||
@ -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,
|
||||
};
|
||||
187
drivers/clk/qcom/clock-sdm845.c
Normal file
187
drivers/clk/qcom/clock-sdm845.c
Normal 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,
|
||||
};
|
||||
@ -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"
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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),
|
||||
};
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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,
|
||||
};
|
||||
@ -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"
|
||||
|
||||
@ -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
|
||||
|
||||
46
drivers/pinctrl/qcom/Kconfig
Normal file
46
drivers/pinctrl/qcom/Kconfig
Normal 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
|
||||
10
drivers/pinctrl/qcom/Makefile
Normal file
10
drivers/pinctrl/qcom/Makefile
Normal 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
|
||||
@ -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,
|
||||
};
|
||||
@ -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,
|
||||
};
|
||||
@ -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,
|
||||
};
|
||||
@ -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,
|
||||
};
|
||||
@ -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
|
||||
@ -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,
|
||||
};
|
||||
100
drivers/pinctrl/qcom/pinctrl-sdm845.c
Normal file
100
drivers/pinctrl/qcom/pinctrl-sdm845.c
Normal 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,
|
||||
};
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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));
|
||||
|
||||
@ -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) */
|
||||
|
||||
|
||||
@ -9,7 +9,6 @@
|
||||
#define __CONFIGS_DRAGONBOARD820C_H
|
||||
|
||||
#include <linux/sizes.h>
|
||||
#include <asm/arch/sysmap-apq8096.h>
|
||||
|
||||
/* Physical Memory Map */
|
||||
|
||||
|
||||
@ -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 }
|
||||
|
||||
|
||||
@ -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 }
|
||||
|
||||
|
||||
@ -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 }
|
||||
|
||||
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user