Merge branch '2022-08-26-assorted-platform-updates' into next

- Assorted Arm, TI and Qualcomm platform updates
This commit is contained in:
Tom Rini
2022-08-26 14:47:48 -04:00
53 changed files with 1406 additions and 740 deletions

View File

@@ -14,7 +14,7 @@
soc {
u-boot,dm-pre-reloc;
qcom,tlmm@1000000 {
pinctrl@1000000 {
u-boot,dm-pre-reloc;
uart {

View File

@@ -60,9 +60,13 @@
reg = <0x60000 0x8000>;
};
pinctrl: qcom,tlmm@1000000 {
compatible = "qcom,tlmm-apq8016";
soc_gpios: pinctrl@1000000 {
compatible = "qcom,msm8916-pinctrl";
reg = <0x1000000 0x400000>;
gpio-controller;
gpio-count = <122>;
gpio-bank-name="soc";
#gpio-cells = <2>;
blsp1_uart: uart {
function = "blsp1_uart";
@@ -86,15 +90,6 @@
pinctrl-0 = <&blsp1_uart>;
};
soc_gpios: pinctrl@1000000 {
compatible = "qcom,apq8016-pinctrl";
reg = <0x1000000 0x300000>;
gpio-controller;
gpio-count = <122>;
gpio-bank-name="soc";
#gpio-cells = <2>;
};
ehci@78d9000 {
compatible = "qcom,ehci-host";
reg = <0x78d9000 0x400>;

View File

@@ -13,7 +13,7 @@
soc {
u-boot,dm-pre-reloc;
qcom,tlmm@1010000 {
pinctrl@1010000 {
u-boot,dm-pre-reloc;
uart {

View File

@@ -64,8 +64,8 @@
reg = <0x300000 0x90000>;
};
pinctrl: qcom,tlmm@1010000 {
compatible = "qcom,tlmm-apq8096";
pinctrl: pinctrl@1010000 {
compatible = "qcom,msm8996-pinctrl";
reg = <0x1010000 0x400000>;
blsp8_uart: uart {

View File

@@ -75,9 +75,13 @@
u-boot,dm-pre-reloc;
};
pinctrl: qcom,tlmm@1000000 {
compatible = "qcom,tlmm-ipq4019";
soc_gpios: pinctrl@1000000 {
compatible = "qcom,ipq4019-pinctrl";
reg = <0x1000000 0x300000>;
gpio-controller;
gpio-count = <100>;
gpio-bank-name="soc";
#gpio-cells = <2>;
u-boot,dm-pre-reloc;
};
@@ -90,16 +94,6 @@
u-boot,dm-pre-reloc;
};
soc_gpios: pinctrl@1000000 {
compatible = "qcom,ipq4019-pinctrl";
reg = <0x1000000 0x300000>;
gpio-controller;
gpio-count = <100>;
gpio-bank-name="soc";
#gpio-cells = <2>;
u-boot,dm-pre-reloc;
};
blsp1_spi1: spi@78b5000 {
compatible = "qcom,spi-qup-v2.2.1";
reg = <0x78b5000 0x600>;

View File

@@ -22,3 +22,9 @@
};
};
};
&pms405_gpios {
usb_vbus_boost_pin {
gpios = <&pms405_gpios 2 0>;
};
};

View File

@@ -38,7 +38,7 @@
compatible = "simple-bus";
pinctrl_north@1300000 {
compatible = "qcom,tlmm-qcs404";
compatible = "qcom,qcs404-pinctrl";
reg = <0x1300000 0x200000>;
blsp1_uart2: uart {
@@ -52,6 +52,13 @@
reg = <0x1800000 0x80000>;
#address-cells = <0x1>;
#size-cells = <0x0>;
#clock-cells = <1>;
};
reset: gcc-reset@1800000 {
compatible = "qcom,gcc-reset-qcs404";
reg = <0x1800000 0x80000>;
#reset-cells = <1>;
};
debug_uart: serial@78b1000 {
@@ -75,6 +82,117 @@
mmc-ddr-1_8v;
mmc-hs400-1_8v;
};
usb3_phy: phy@78000 {
compatible = "qcom,usb-ss-28nm-phy";
#phy-cells = <0>;
reg = <0x78000 0x400>;
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>;
reset-names = "com", "phy";
};
usb2_phy_prim: phy@7a000 {
compatible = "qcom,usb-hs-28nm-femtophy";
#phy-cells = <0>;
reg = <0x7a000 0x200>;
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>;
reset-names = "phy", "por";
};
usb2_phy_sec: phy@7c000 {
compatible = "qcom,usb-hs-28nm-femtophy";
#phy-cells = <0>;
reg = <0x7c000 0x200>;
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>;
reset-names = "phy", "por";
};
usb3: usb@7678800 {
compatible = "qcom,dwc3";
reg = <0x7678800 0x400>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
clocks = <&gcc GCC_USB30_MASTER_CLK>,
<&gcc GCC_SYS_NOC_USB3_CLK>,
<&gcc GCC_USB30_SLEEP_CLK>,
<&gcc GCC_USB30_MOCK_UTMI_CLK>;
clock-names = "core", "iface", "sleep", "mock_utmi";
dwc3@7580000 {
compatible = "snps,dwc3";
reg = <0x7580000 0xcd00>;
phys = <&usb2_phy_prim>, <&usb3_phy>;
phy-names = "usb2-phy", "usb3-phy";
dr_mode = "host";
snps,has-lpm-erratum;
snps,hird-threshold = /bits/ 8 <0x10>;
snps,usb3_lpm_capable;
maximum-speed = "super-speed";
};
};
usb2: usb@79b8800 {
compatible = "qcom,dwc3";
reg = <0x79b8800 0x400>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
clocks = <&gcc GCC_USB_HS_SYSTEM_CLK>,
<&gcc GCC_PCNOC_USB2_CLK>,
<&gcc GCC_USB_HS_INACTIVITY_TIMERS_CLK>,
<&gcc GCC_USB20_MOCK_UTMI_CLK>;
clock-names = "core", "iface", "sleep", "mock_utmi";
dwc3@78c0000 {
compatible = "snps,dwc3";
reg = <0x78c0000 0xcc00>;
phys = <&usb2_phy_sec>;
phy-names = "usb2-phy";
dr_mode = "peripheral";
snps,has-lpm-erratum;
snps,hird-threshold = /bits/ 8 <0x10>;
snps,usb3_lpm_capable;
maximum-speed = "high-speed";
};
};
spmi@200f000 {
compatible = "qcom,spmi-pmic-arb";
reg = <0x200f000 0x1000
0x2400000 0x400000
0x2c00000 0x400000>;
#address-cells = <0x1>;
#size-cells = <0x1>;
pms405_0: pms405@0 {
compatible = "qcom,spmi-pmic";
reg = <0x0 0x1>;
#address-cells = <0x1>;
#size-cells = <0x1>;
pms405_gpios: pms405_gpios@c000 {
compatible = "qcom,pms405-gpio";
reg = <0xc000 0x400>;
gpio-controller;
gpio-count = <12>;
#gpio-cells = <2>;
gpio-bank-name="pmic";
};
};
};
};
};

View File

@@ -37,7 +37,7 @@
};
tlmm_north: pinctrl_north@3900000 {
compatible = "qcom,tlmm-sdm845";
compatible = "qcom,sdm845-pinctrl";
reg = <0x3900000 0x400000>;
gpio-count = <150>;
gpio-controller;

View File

@@ -45,4 +45,8 @@
clock-frequency = <24000000>;
clock-output-names = "bp:clock24mhz";
};
psci {
compatible = "arm,psci-1.0", "arm,psci-0.2";
method = "smc";
};
};

View File

@@ -14,6 +14,8 @@
#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"
@@ -110,6 +112,32 @@ static int msm_pinconf_set(struct udevice *dev, unsigned int pin_selector,
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,
@@ -123,7 +151,7 @@ static struct pinctrl_ops msm_pinctrl_ops = {
};
static const struct udevice_id msm_pinctrl_ids[] = {
{ .compatible = "qcom,tlmm-ipq4019", .data = (ulong)&ipq4019_data },
{ .compatible = "qcom,ipq4019-pinctrl", .data = (ulong)&ipq4019_data },
{ }
};
@@ -134,4 +162,5 @@ U_BOOT_DRIVER(pinctrl_snapdraon) = {
.priv_auto = sizeof(struct msm_pinctrl_priv),
.ops = &msm_pinctrl_ops,
.probe = msm_pinctrl_probe,
.bind = msm_pinctrl_bind,
};

View File

@@ -16,6 +16,6 @@ obj-y += pinctrl-snapdragon.o
obj-y += pinctrl-apq8016.o
obj-y += pinctrl-apq8096.o
obj-y += pinctrl-qcs404.o
obj-$(CONFIG_SDM845) += pinctrl-sdm845.o
obj-y += pinctrl-sdm845.o
obj-$(CONFIG_TARGET_QCS404EVB) += clock-qcs404.o
obj-$(CONFIG_TARGET_QCS404EVB) += sysmap-qcs404.o

View File

@@ -111,3 +111,8 @@ ulong msm_set_rate(struct clk *clk, ulong rate)
return 0;
}
}
int msm_enable(struct clk *clk)
{
return 0;
}

View File

@@ -93,3 +93,8 @@ ulong msm_set_rate(struct clk *clk, ulong rate)
return 0;
}
}
int msm_enable(struct clk *clk)
{
return 0;
}

View File

@@ -47,6 +47,14 @@ static struct pll_vote_clk gpll0_vote_clk = {
.vote_bit = BIT(0),
};
static const struct bcr_regs usb30_master_regs = {
.cfg_rcgr = USB30_MASTER_CFG_RCGR,
.cmd_rcgr = USB30_MASTER_CMD_RCGR,
.M = USB30_MASTER_M,
.N = USB30_MASTER_N,
.D = USB30_MASTER_D,
};
ulong msm_set_rate(struct clk *clk, ulong rate)
{
struct msm_clk_priv *priv = dev_get_priv(clk->dev);
@@ -77,3 +85,35 @@ ulong msm_set_rate(struct clk *clk, ulong rate)
return 0;
}
int msm_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);
break;
case GCC_SYS_NOC_USB3_CLK:
clk_enable_cbc(priv->base + SYS_NOC_USB3_CBCR);
break;
case GCC_USB30_SLEEP_CLK:
clk_enable_cbc(priv->base + USB30_SLEEP_CBCR);
break;
case GCC_USB30_MOCK_UTMI_CLK:
clk_enable_cbc(priv->base + USB30_MOCK_UTMI_CBCR);
break;
case GCC_USB_HS_PHY_CFG_AHB_CLK:
clk_enable_cbc(priv->base + USB_HS_PHY_CFG_AHB_CBCR);
break;
case GCC_USB2A_PHY_SLEEP_CLK:
clk_enable_cbc(priv->base + USB_HS_PHY_CFG_AHB_CBCR);
break;
default:
return 0;
}
return 0;
}

View File

@@ -91,3 +91,8 @@ ulong msm_set_rate(struct clk *clk, ulong rate)
return 0;
}
}
int msm_enable(struct clk *clk)
{
return 0;
}

View File

@@ -20,6 +20,7 @@
#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)
@@ -126,8 +127,14 @@ 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[] = {

View File

@@ -37,4 +37,21 @@
#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)
#endif

View File

@@ -10,6 +10,8 @@
#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"
@@ -113,13 +115,37 @@ static struct pinctrl_ops msm_pinctrl_ops = {
.get_function_name = msm_get_function_name,
};
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 const struct udevice_id msm_pinctrl_ids[] = {
{ .compatible = "qcom,tlmm-apq8016", .data = (ulong)&apq8016_data },
{ .compatible = "qcom,tlmm-apq8096", .data = (ulong)&apq8096_data },
#ifdef CONFIG_SDM845
{ .compatible = "qcom,tlmm-sdm845", .data = (ulong)&sdm845_data },
#endif
{ .compatible = "qcom,tlmm-qcs404", .data = (ulong)&qcs404_data },
{ .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 },
{ }
};
@@ -130,4 +156,5 @@ U_BOOT_DRIVER(pinctrl_snapdraon) = {
.priv_auto = sizeof(struct msm_pinctrl_priv),
.ops = &msm_pinctrl_ops,
.probe = msm_pinctrl_probe,
.bind = msm_pinctrl_bind,
};

View File

@@ -11,6 +11,7 @@
#include <env.h>
#include <init.h>
#include <asm/cache.h>
#include <asm/gpio.h>
#include <asm/global_data.h>
#include <fdt_support.h>
#include <asm/arch/dram.h>
@@ -24,6 +25,34 @@ int dram_init(void)
int board_init(void)
{
struct udevice *pmic_gpio;
struct gpio_desc usb_vbus_boost_pin;
int ret, node;
ret = uclass_get_device_by_name(UCLASS_GPIO,
"pms405_gpios@c000",
&pmic_gpio);
if (ret < 0) {
printf("Failed to find pms405_gpios@c000 node.\n");
return ret;
}
node = fdt_subnode_offset(gd->fdt_blob, dev_of_offset(pmic_gpio),
"usb_vbus_boost_pin");
if (node < 0) {
printf("Failed to find usb_hub_reset_pm dt node.\n");
return node;
}
ret = gpio_request_by_name_nodev(offset_to_ofnode(node), "gpios", 0,
&usb_vbus_boost_pin, 0);
if (ret < 0) {
printf("Failed to request usb_hub_reset_pm gpio.\n");
return ret;
}
dm_gpio_set_dir_flags(&usb_vbus_boost_pin,
GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
return 0;
}

View File

@@ -43,7 +43,7 @@ CONFIG_FASTBOOT_BUF_ADDR=0x91000000
CONFIG_FASTBOOT_FLASH=y
CONFIG_FASTBOOT_FLASH_MMC_DEV=0
CONFIG_MSM_GPIO=y
CONFIG_PM8916_GPIO=y
CONFIG_QCOM_PMIC_GPIO=y
CONFIG_LED=y
CONFIG_LED_GPIO=y
CONFIG_MMC_SDHCI=y
@@ -52,7 +52,7 @@ CONFIG_PHY=y
CONFIG_PINCTRL=y
CONFIG_PINCONF=y
CONFIG_DM_PMIC=y
CONFIG_PMIC_PM8916=y
CONFIG_PMIC_QCOM=y
CONFIG_MSM_SERIAL=y
CONFIG_SPMI_MSM=y
CONFIG_USB=y

View File

@@ -36,12 +36,12 @@ CONFIG_ENV_EXT4_INTERFACE="mmc"
CONFIG_ENV_EXT4_DEVICE_AND_PART="0:1"
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
CONFIG_CLK=y
CONFIG_PM8916_GPIO=y
CONFIG_QCOM_PMIC_GPIO=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_MSM=y
CONFIG_PINCTRL=y
CONFIG_PINCONF=y
CONFIG_DM_PMIC=y
CONFIG_PMIC_PM8916=y
CONFIG_PMIC_QCOM=y
CONFIG_MSM_SERIAL=y
CONFIG_SPMI_MSM=y

View File

@@ -20,10 +20,10 @@ CONFIG_CMD_GPIO=y
# CONFIG_NET is not set
CONFIG_CLK=y
CONFIG_MSM_GPIO=y
CONFIG_PM8916_GPIO=y
CONFIG_QCOM_PMIC_GPIO=y
CONFIG_PINCTRL=y
CONFIG_DM_PMIC=y
CONFIG_PMIC_PM8916=y
CONFIG_PMIC_QCOM=y
CONFIG_MSM_GENI_SERIAL=y
CONFIG_SPMI_MSM=y
CONFIG_LMB_MAX_REGIONS=64

View File

@@ -32,7 +32,7 @@ CONFIG_SPL_LOAD_FIT=y
CONFIG_SPL_LOAD_FIT_ADDRESS=0x81000000
# CONFIG_USE_SPL_FIT_GENERATOR is not set
CONFIG_OF_BOARD_SETUP=y
CONFIG_BOOTCOMMAND="run findfdt; run envboot; run init_${boot}; run main_cpsw0_qsgmii_phyinit; run boot_rprocs; run get_kern_${boot}; run get_fdt_${boot}; run get_overlay_${boot}; run run_kern"
CONFIG_BOOTCOMMAND="run findfdt; run envboot; run init_${boot}; run boot_rprocs; run get_kern_${boot}; run get_fdt_${boot}; run get_overlay_${boot}; run run_kern"
CONFIG_LOGLEVEL=7
CONFIG_SPL_MAX_SIZE=0xc0000
CONFIG_SPL_HAS_BSS_LINKER_SECTION=y

View File

@@ -27,6 +27,7 @@ CONFIG_CMD_EXT4=y
CONFIG_CMD_EXT4_WRITE=y
CONFIG_CMD_FAT=y
CONFIG_CMD_FS_GENERIC=y
CONFIG_CMD_USB=y
# CONFIG_NET is not set
CONFIG_CLK=y
CONFIG_MMC_HS400_SUPPORT=y
@@ -35,4 +36,21 @@ CONFIG_MMC_SDHCI_ADMA=y
CONFIG_MMC_SDHCI_MSM=y
CONFIG_PINCTRL=y
CONFIG_MSM_SERIAL=y
CONFIG_SPMI_MSM=y
CONFIG_DM_PMIC=y
CONFIG_PMIC_QCOM=y
CONFIG_QCOM_PMIC_GPIO=y
CONFIG_MISC=y
CONFIG_USB=y
CONFIG_DM_USB=y
CONFIG_USB_STORAGE=y
CONFIG_USB_DWC3=y
CONFIG_USB_DWC3_GENERIC=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_DM_RESET=y
CONFIG_RESET_QCOM=y
CONFIG_PHY=y
CONFIG_PHY_QCOM_USB_HS_28NM=y
CONFIG_PHY_QCOM_USB_SS=y
CONFIG_LMB_MAX_REGIONS=64

View File

@@ -127,7 +127,7 @@ CONFIG_FASTBOOT_FLASH=y
CONFIG_FASTBOOT_FLASH_MMC_DEV=0
CONFIG_GPIO_HOG=y
CONFIG_DM_GPIO_LOOKUP_LABEL=y
CONFIG_PM8916_GPIO=y
CONFIG_QCOM_PMIC_GPIO=y
CONFIG_SANDBOX_GPIO=y
CONFIG_I2C_CROS_EC_TUNNEL=y
CONFIG_I2C_CROS_EC_LDO=y
@@ -178,7 +178,7 @@ CONFIG_DM_PMIC=y
CONFIG_PMIC_ACT8846=y
CONFIG_DM_PMIC_PFUZE100=y
CONFIG_DM_PMIC_MAX77686=y
CONFIG_PMIC_PM8916=y
CONFIG_PMIC_QCOM=y
CONFIG_PMIC_RK8XX=y
CONFIG_PMIC_S2MPS11=y
CONFIG_DM_PMIC_SANDBOX=y

View File

@@ -171,7 +171,7 @@ CONFIG_FASTBOOT_FLASH=y
CONFIG_FASTBOOT_FLASH_MMC_DEV=0
CONFIG_GPIO_HOG=y
CONFIG_DM_GPIO_LOOKUP_LABEL=y
CONFIG_PM8916_GPIO=y
CONFIG_QCOM_PMIC_GPIO=y
CONFIG_SANDBOX_GPIO=y
CONFIG_DM_HWSPINLOCK=y
CONFIG_HWSPINLOCK_SANDBOX=y
@@ -231,7 +231,7 @@ CONFIG_PMIC_ACT8846=y
CONFIG_DM_PMIC_PFUZE100=y
CONFIG_DM_PMIC_MAX77686=y
CONFIG_DM_PMIC_MC34708=y
CONFIG_PMIC_PM8916=y
CONFIG_PMIC_QCOM=y
CONFIG_PMIC_RK8XX=y
CONFIG_PMIC_S2MPS11=y
CONFIG_DM_PMIC_SANDBOX=y

View File

@@ -100,7 +100,7 @@ CONFIG_DM_DEMO_SHAPE=y
CONFIG_DFU_SF=y
CONFIG_GPIO_HOG=y
CONFIG_DM_GPIO_LOOKUP_LABEL=y
CONFIG_PM8916_GPIO=y
CONFIG_QCOM_PMIC_GPIO=y
CONFIG_SANDBOX_GPIO=y
CONFIG_I2C_CROS_EC_TUNNEL=y
CONFIG_I2C_CROS_EC_LDO=y
@@ -153,7 +153,7 @@ CONFIG_PMIC_ACT8846=y
CONFIG_DM_PMIC_PFUZE100=y
CONFIG_DM_PMIC_MAX77686=y
CONFIG_DM_PMIC_MC34708=y
CONFIG_PMIC_PM8916=y
CONFIG_PMIC_QCOM=y
CONFIG_PMIC_S2MPS11=y
CONFIG_DM_PMIC_SANDBOX=y
CONFIG_PMIC_S5M8767=y

View File

@@ -126,7 +126,7 @@ CONFIG_DM_DEMO_SIMPLE=y
CONFIG_DM_DEMO_SHAPE=y
CONFIG_SPL_FIRMWARE=y
CONFIG_GPIO_HOG=y
CONFIG_PM8916_GPIO=y
CONFIG_QCOM_PMIC_GPIO=y
CONFIG_SANDBOX_GPIO=y
CONFIG_I2C_CROS_EC_TUNNEL=y
CONFIG_I2C_CROS_EC_LDO=y
@@ -176,7 +176,7 @@ CONFIG_PMIC_ACT8846=y
CONFIG_DM_PMIC_PFUZE100=y
CONFIG_DM_PMIC_MAX77686=y
CONFIG_DM_PMIC_MC34708=y
CONFIG_PMIC_PM8916=y
CONFIG_PMIC_QCOM=y
CONFIG_PMIC_RK8XX=y
CONFIG_PMIC_S2MPS11=y
CONFIG_DM_PMIC_SANDBOX=y

View File

@@ -127,7 +127,7 @@ CONFIG_DM_DEMO_SIMPLE=y
CONFIG_DM_DEMO_SHAPE=y
CONFIG_SPL_FIRMWARE=y
CONFIG_GPIO_HOG=y
CONFIG_PM8916_GPIO=y
CONFIG_QCOM_PMIC_GPIO=y
CONFIG_SANDBOX_GPIO=y
CONFIG_I2C_CROS_EC_TUNNEL=y
CONFIG_I2C_CROS_EC_LDO=y
@@ -179,7 +179,7 @@ CONFIG_PMIC_ACT8846=y
CONFIG_DM_PMIC_PFUZE100=y
CONFIG_DM_PMIC_MAX77686=y
CONFIG_DM_PMIC_MC34708=y
CONFIG_PMIC_PM8916=y
CONFIG_PMIC_QCOM=y
CONFIG_PMIC_RK8XX=y
CONFIG_PMIC_S2MPS11=y
CONFIG_DM_PMIC_SANDBOX=y

View File

@@ -136,7 +136,7 @@ CONFIG_DM_DEMO_SIMPLE=y
CONFIG_DM_DEMO_SHAPE=y
CONFIG_SPL_FIRMWARE=y
CONFIG_GPIO_HOG=y
CONFIG_PM8916_GPIO=y
CONFIG_QCOM_PMIC_GPIO=y
CONFIG_SANDBOX_GPIO=y
CONFIG_I2C_CROS_EC_TUNNEL=y
CONFIG_I2C_CROS_EC_LDO=y
@@ -184,7 +184,7 @@ CONFIG_PMIC_ACT8846=y
CONFIG_DM_PMIC_PFUZE100=y
CONFIG_DM_PMIC_MAX77686=y
CONFIG_DM_PMIC_MC34708=y
CONFIG_PMIC_PM8916=y
CONFIG_PMIC_QCOM=y
CONFIG_PMIC_RK8XX=y
CONFIG_PMIC_S2MPS11=y
CONFIG_DM_PMIC_SANDBOX=y

View File

@@ -23,10 +23,10 @@ CONFIG_CMD_BMP=y
# CONFIG_DM_STDIO is not set
CONFIG_CLK=y
CONFIG_MSM_GPIO=y
CONFIG_PM8916_GPIO=y
CONFIG_QCOM_PMIC_GPIO=y
CONFIG_PINCTRL=y
CONFIG_DM_PMIC=y
CONFIG_PMIC_PM8916=y
CONFIG_PMIC_QCOM=y
# CONFIG_REQUIRE_SERIAL_CONSOLE is not set
CONFIG_SPMI_MSM=y
CONFIG_DM_VIDEO=y

View File

@@ -1,18 +0,0 @@
Qualcomm pm8916 PMIC
This PMIC is connected using SPMI bus so should be child of SPMI bus controller.
Required properties:
- compatible: "qcom,spmi-pmic";
- reg: SPMI Slave ID, size (ignored)
- #address-cells: 0x1 (peripheral ID)
- #size-cells: 0x1 (size of peripheral register space)
Example:
pm8916@0 {
compatible = "qcom,spmi-pmic";
reg = <0x0 0x1>;
#address-cells = <0x1>;
#size-cells = <0x1>;
};

View File

@@ -0,0 +1,94 @@
Qualcomm SPMI PMICs multi-function device bindings
The Qualcomm SPMI series presently includes PM8941, PM8841 and PMA8084
PMICs. These PMICs use a QPNP scheme through SPMI interface.
QPNP is effectively a partitioning scheme for dividing the SPMI extended
register space up into logical pieces, and set of fixed register
locations/definitions within these regions, with some of these regions
specifically used for interrupt handling.
The QPNP PMICs are used with the Qualcomm Snapdragon series SoCs, and are
interfaced to the chip via the SPMI (System Power Management Interface) bus.
Support for multiple independent functions are implemented by splitting the
16-bit SPMI slave address space into 256 smaller fixed-size regions, 256 bytes
each. A function can consume one or more of these fixed-size register regions.
Required properties:
- compatible: Should contain one of:
"qcom,pm660",
"qcom,pm660l",
"qcom,pm7325",
"qcom,pm8004",
"qcom,pm8005",
"qcom,pm8019",
"qcom,pm8028",
"qcom,pm8110",
"qcom,pm8150",
"qcom,pm8150b",
"qcom,pm8150c",
"qcom,pm8150l",
"qcom,pm8226",
"qcom,pm8350c",
"qcom,pm8841",
"qcom,pm8901",
"qcom,pm8909",
"qcom,pm8916",
"qcom,pm8941",
"qcom,pm8950",
"qcom,pm8953",
"qcom,pm8994",
"qcom,pm8998",
"qcom,pma8084",
"qcom,pmd9635",
"qcom,pmi8950",
"qcom,pmi8962",
"qcom,pmi8994",
"qcom,pmi8998",
"qcom,pmk8002",
"qcom,pmk8350",
"qcom,pmr735a",
"qcom,smb2351",
or generalized "qcom,spmi-pmic".
- reg: Specifies the SPMI USID slave address for this device.
For more information see:
Documentation/devicetree/bindings/spmi/spmi.yaml
Required properties for peripheral child nodes:
- compatible: Should contain "qcom,xxx", where "xxx" is a peripheral name.
Optional properties for peripheral child nodes:
- interrupts: Interrupts are specified as a 4-tuple. For more information
see:
Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb.yaml
- interrupt-names: Corresponding interrupt name to the interrupts property
Each child node of SPMI slave id represents a function of the PMIC. In the
example below the rtc device node represents a peripheral of pm8941
SID = 0. The regulator device node represents a peripheral of pm8941 SID = 1.
Example:
spmi {
compatible = "qcom,spmi-pmic-arb";
pm8941@0 {
compatible = "qcom,pm8941", "qcom,spmi-pmic";
reg = <0x0 SPMI_USID>;
rtc {
compatible = "qcom,rtc";
interrupts = <0x0 0x61 0x1 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "alarm";
};
};
pm8941@1 {
compatible = "qcom,pm8941", "qcom,spmi-pmic";
reg = <0x1 SPMI_USID>;
regulator {
compatible = "qcom,regulator";
regulator-name = "8941_boost";
};
};
};

View File

@@ -134,8 +134,11 @@ static struct ti_sci_xfer *ti_sci_setup_one_xfer(struct ti_sci_info *info,
if (rx_message_size > info->desc->max_msg_size ||
tx_message_size > info->desc->max_msg_size ||
(rx_message_size > 0 && rx_message_size < sizeof(*hdr)) ||
tx_message_size < sizeof(*hdr))
tx_message_size < sizeof(*hdr)) {
dev_err(info->dev, "TI-SCI message transfer size not sane\n");
return ERR_PTR(-ERANGE);
}
info->seq = ~info->seq;
xfer->tx_message.buf = buf;
@@ -161,7 +164,7 @@ static struct ti_sci_xfer *ti_sci_setup_one_xfer(struct ti_sci_info *info,
* return corresponding error, else if all goes well,
* return 0.
*/
static inline int ti_sci_get_response(struct ti_sci_info *info,
static int ti_sci_get_response(struct ti_sci_info *info,
struct ti_sci_xfer *xfer,
struct mbox_chan *chan)
{
@@ -208,6 +211,19 @@ static inline int ti_sci_get_response(struct ti_sci_info *info,
return ret;
}
/**
* ti_sci_is_response_ack() - Generic ACK/NACK message checkup
* @r: pointer to response buffer
*
* Return: true if the response was an ACK, else returns false.
*/
static bool ti_sci_is_response_ack(void *r)
{
struct ti_sci_msg_hdr *hdr = r;
return hdr->flags & TI_SCI_FLAG_RESP_GENERIC_ACK ? true : false;
}
/**
* ti_sci_do_xfer() - Do one transfer
* @info: Pointer to SCI entity information
@@ -215,7 +231,7 @@ static inline int ti_sci_get_response(struct ti_sci_info *info,
*
* Return: 0 if all went fine, else return appropriate error.
*/
static inline int ti_sci_do_xfer(struct ti_sci_info *info,
static int ti_sci_do_xfer(struct ti_sci_info *info,
struct ti_sci_xfer *xfer)
{
struct k3_sec_proxy_msg *msg = &xfer->tx_message;
@@ -246,8 +262,13 @@ static inline int ti_sci_do_xfer(struct ti_sci_info *info,
}
/* Get response if requested */
if (xfer->rx_len)
if (xfer->rx_len) {
ret = ti_sci_get_response(info, xfer, &info->chan_rx);
if (!ti_sci_is_response_ack(xfer->tx_message.buf)) {
dev_err(info->dev, "Message not acknowledged");
ret = -ENODEV;
}
}
return ret;
}
@@ -282,15 +303,12 @@ static int ti_sci_cmd_get_revision(struct ti_sci_handle *handle)
sizeof(*rev_info));
if (IS_ERR(xfer)) {
ret = PTR_ERR(xfer);
dev_err(info->dev, "Message alloc failed(%d)\n", ret);
return ret;
}
ret = ti_sci_do_xfer(info, xfer);
if (ret) {
dev_err(info->dev, "Mbox communication fail %d\n", ret);
if (ret)
return ret;
}
rev_info = (struct ti_sci_msg_resp_version *)xfer->tx_message.buf;
@@ -304,19 +322,6 @@ static int ti_sci_cmd_get_revision(struct ti_sci_handle *handle)
return 0;
}
/**
* ti_sci_is_response_ack() - Generic ACK/NACK message checkup
* @r: pointer to response buffer
*
* Return: true if the response was an ACK, else returns false.
*/
static inline bool ti_sci_is_response_ack(void *r)
{
struct ti_sci_msg_hdr *hdr = r;
return hdr->flags & TI_SCI_FLAG_RESP_GENERIC_ACK ? true : false;
}
/**
* cmd_set_board_config_using_msg() - Common command to send board configuration
* message
@@ -348,7 +353,6 @@ static int cmd_set_board_config_using_msg(const struct ti_sci_handle *handle,
(u32 *)&req, sizeof(req), sizeof(*resp));
if (IS_ERR(xfer)) {
ret = PTR_ERR(xfer);
dev_err(info->dev, "Message alloc failed(%d)\n", ret);
return ret;
}
req.boardcfgp_high = (addr >> 32) & 0xffffffff;
@@ -356,15 +360,8 @@ static int cmd_set_board_config_using_msg(const struct ti_sci_handle *handle,
req.boardcfg_size = size;
ret = ti_sci_do_xfer(info, xfer);
if (ret) {
dev_err(info->dev, "Mbox send fail %d\n", ret);
if (ret)
return ret;
}
resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
if (!ti_sci_is_response_ack(resp))
return -ENODEV;
return ret;
}
@@ -509,22 +506,14 @@ static int ti_sci_set_device_state(const struct ti_sci_handle *handle,
(u32 *)&req, sizeof(req), sizeof(*resp));
if (IS_ERR(xfer)) {
ret = PTR_ERR(xfer);
dev_err(info->dev, "Message alloc failed(%d)\n", ret);
return ret;
}
req.id = id;
req.state = state;
ret = ti_sci_do_xfer(info, xfer);
if (ret) {
dev_err(info->dev, "Mbox send fail %d\n", ret);
if (ret)
return ret;
}
resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
if (!ti_sci_is_response_ack(resp))
return -ENODEV;
if (state == MSG_DEVICE_SW_STATE_AUTO_OFF)
ti_sci_delete_exclusive_dev(info, id);
@@ -564,7 +553,6 @@ static int ti_sci_set_device_state_no_wait(const struct ti_sci_handle *handle,
(u32 *)&req, sizeof(req), 0);
if (IS_ERR(xfer)) {
ret = PTR_ERR(xfer);
dev_err(info->dev, "Message alloc failed(%d)\n", ret);
return ret;
}
req.id = id;
@@ -572,7 +560,7 @@ static int ti_sci_set_device_state_no_wait(const struct ti_sci_handle *handle,
ret = ti_sci_do_xfer(info, xfer);
if (ret)
dev_err(info->dev, "Mbox send fail %d\n", ret);
return ret;
return ret;
}
@@ -613,20 +601,15 @@ static int ti_sci_get_device_state(const struct ti_sci_handle *handle,
(u32 *)&req, sizeof(req), sizeof(*resp));
if (IS_ERR(xfer)) {
ret = PTR_ERR(xfer);
dev_err(info->dev, "Message alloc failed(%d)\n", ret);
return ret;
}
req.id = id;
ret = ti_sci_do_xfer(info, xfer);
if (ret) {
dev_err(info->dev, "Mbox send fail %d\n", ret);
if (ret)
return ret;
}
resp = (struct ti_sci_msg_resp_get_device_state *)xfer->tx_message.buf;
if (!ti_sci_is_response_ack(resp))
return -ENODEV;
if (clcnt)
*clcnt = resp->context_loss_count;
@@ -901,22 +884,14 @@ static int ti_sci_cmd_set_device_resets(const struct ti_sci_handle *handle,
(u32 *)&req, sizeof(req), sizeof(*resp));
if (IS_ERR(xfer)) {
ret = PTR_ERR(xfer);
dev_err(info->dev, "Message alloc failed(%d)\n", ret);
return ret;
}
req.id = id;
req.resets = reset_state;
ret = ti_sci_do_xfer(info, xfer);
if (ret) {
dev_err(info->dev, "Mbox send fail %d\n", ret);
if (ret)
return ret;
}
resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
if (!ti_sci_is_response_ack(resp))
return -ENODEV;
return ret;
}
@@ -971,7 +946,6 @@ static int ti_sci_set_clock_state(const struct ti_sci_handle *handle,
(u32 *)&req, sizeof(req), sizeof(*resp));
if (IS_ERR(xfer)) {
ret = PTR_ERR(xfer);
dev_err(info->dev, "Message alloc failed(%d)\n", ret);
return ret;
}
req.dev_id = dev_id;
@@ -979,15 +953,8 @@ static int ti_sci_set_clock_state(const struct ti_sci_handle *handle,
req.request_state = state;
ret = ti_sci_do_xfer(info, xfer);
if (ret) {
dev_err(info->dev, "Mbox send fail %d\n", ret);
if (ret)
return ret;
}
resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
if (!ti_sci_is_response_ack(resp))
return -ENODEV;
return ret;
}
@@ -1029,23 +996,17 @@ static int ti_sci_cmd_get_clock_state(const struct ti_sci_handle *handle,
(u32 *)&req, sizeof(req), sizeof(*resp));
if (IS_ERR(xfer)) {
ret = PTR_ERR(xfer);
dev_err(info->dev, "Message alloc failed(%d)\n", ret);
return ret;
}
req.dev_id = dev_id;
req.clk_id = clk_id;
ret = ti_sci_do_xfer(info, xfer);
if (ret) {
dev_err(info->dev, "Mbox send fail %d\n", ret);
if (ret)
return ret;
}
resp = (struct ti_sci_msg_resp_get_clock_state *)xfer->tx_message.buf;
if (!ti_sci_is_response_ack(resp))
return -ENODEV;
if (programmed_state)
*programmed_state = resp->programmed_state;
if (current_state)
@@ -1245,7 +1206,6 @@ static int ti_sci_cmd_clk_set_parent(const struct ti_sci_handle *handle,
(u32 *)&req, sizeof(req), sizeof(*resp));
if (IS_ERR(xfer)) {
ret = PTR_ERR(xfer);
dev_err(info->dev, "Message alloc failed(%d)\n", ret);
return ret;
}
req.dev_id = dev_id;
@@ -1253,15 +1213,8 @@ static int ti_sci_cmd_clk_set_parent(const struct ti_sci_handle *handle,
req.parent_id = parent_id;
ret = ti_sci_do_xfer(info, xfer);
if (ret) {
dev_err(info->dev, "Mbox send fail %d\n", ret);
if (ret)
return ret;
}
resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
if (!ti_sci_is_response_ack(resp))
return -ENODEV;
return ret;
}
@@ -1298,24 +1251,16 @@ static int ti_sci_cmd_clk_get_parent(const struct ti_sci_handle *handle,
(u32 *)&req, sizeof(req), sizeof(*resp));
if (IS_ERR(xfer)) {
ret = PTR_ERR(xfer);
dev_err(info->dev, "Message alloc failed(%d)\n", ret);
return ret;
}
req.dev_id = dev_id;
req.clk_id = clk_id;
ret = ti_sci_do_xfer(info, xfer);
if (ret) {
dev_err(info->dev, "Mbox send fail %d\n", ret);
if (ret)
return ret;
}
resp = (struct ti_sci_msg_resp_get_clock_parent *)xfer->tx_message.buf;
if (!ti_sci_is_response_ack(resp))
ret = -ENODEV;
else
*parent_id = resp->parent_id;
*parent_id = resp->parent_id;
return ret;
}
@@ -1353,25 +1298,19 @@ static int ti_sci_cmd_clk_get_num_parents(const struct ti_sci_handle *handle,
(u32 *)&req, sizeof(req), sizeof(*resp));
if (IS_ERR(xfer)) {
ret = PTR_ERR(xfer);
dev_err(info->dev, "Message alloc failed(%d)\n", ret);
return ret;
}
req.dev_id = dev_id;
req.clk_id = clk_id;
ret = ti_sci_do_xfer(info, xfer);
if (ret) {
dev_err(info->dev, "Mbox send fail %d\n", ret);
if (ret)
return ret;
}
resp = (struct ti_sci_msg_resp_get_clock_num_parents *)
xfer->tx_message.buf;
if (!ti_sci_is_response_ack(resp))
ret = -ENODEV;
else
*num_parents = resp->num_parents;
*num_parents = resp->num_parents;
return ret;
}
@@ -1418,7 +1357,6 @@ static int ti_sci_cmd_clk_get_match_freq(const struct ti_sci_handle *handle,
(u32 *)&req, sizeof(req), sizeof(*resp));
if (IS_ERR(xfer)) {
ret = PTR_ERR(xfer);
dev_err(info->dev, "Message alloc failed(%d)\n", ret);
return ret;
}
req.dev_id = dev_id;
@@ -1428,17 +1366,12 @@ static int ti_sci_cmd_clk_get_match_freq(const struct ti_sci_handle *handle,
req.max_freq_hz = max_freq;
ret = ti_sci_do_xfer(info, xfer);
if (ret) {
dev_err(info->dev, "Mbox send fail %d\n", ret);
if (ret)
return ret;
}
resp = (struct ti_sci_msg_resp_query_clock_freq *)xfer->tx_message.buf;
if (!ti_sci_is_response_ack(resp))
ret = -ENODEV;
else
*match_freq = resp->freq_hz;
*match_freq = resp->freq_hz;
return ret;
}
@@ -1483,7 +1416,6 @@ static int ti_sci_cmd_clk_set_freq(const struct ti_sci_handle *handle,
(u32 *)&req, sizeof(req), sizeof(*resp));
if (IS_ERR(xfer)) {
ret = PTR_ERR(xfer);
dev_err(info->dev, "Message alloc failed(%d)\n", ret);
return ret;
}
req.dev_id = dev_id;
@@ -1493,15 +1425,8 @@ static int ti_sci_cmd_clk_set_freq(const struct ti_sci_handle *handle,
req.max_freq_hz = max_freq;
ret = ti_sci_do_xfer(info, xfer);
if (ret) {
dev_err(info->dev, "Mbox send fail %d\n", ret);
if (ret)
return ret;
}
resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
if (!ti_sci_is_response_ack(resp))
return -ENODEV;
return ret;
}
@@ -1538,24 +1463,18 @@ static int ti_sci_cmd_clk_get_freq(const struct ti_sci_handle *handle,
(u32 *)&req, sizeof(req), sizeof(*resp));
if (IS_ERR(xfer)) {
ret = PTR_ERR(xfer);
dev_err(info->dev, "Message alloc failed(%d)\n", ret);
return ret;
}
req.dev_id = dev_id;
req.clk_id = clk_id;
ret = ti_sci_do_xfer(info, xfer);
if (ret) {
dev_err(info->dev, "Mbox send fail %d\n", ret);
if (ret)
return ret;
}
resp = (struct ti_sci_msg_resp_get_clock_freq *)xfer->tx_message.buf;
if (!ti_sci_is_response_ack(resp))
ret = -ENODEV;
else
*freq = resp->freq_hz;
*freq = resp->freq_hz;
return ret;
}
@@ -1586,21 +1505,13 @@ static int ti_sci_cmd_core_reboot(const struct ti_sci_handle *handle)
(u32 *)&req, sizeof(req), sizeof(*resp));
if (IS_ERR(xfer)) {
ret = PTR_ERR(xfer);
dev_err(info->dev, "Message alloc failed(%d)\n", ret);
return ret;
}
req.domain = 0;
ret = ti_sci_do_xfer(info, xfer);
if (ret) {
dev_err(info->dev, "Mbox send fail %d\n", ret);
if (ret)
return ret;
}
resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
if (!ti_sci_is_response_ack(resp))
return -ENODEV;
return ret;
}
@@ -1641,7 +1552,6 @@ static int ti_sci_get_resource_range(const struct ti_sci_handle *handle,
(u32 *)&req, sizeof(req), sizeof(*resp));
if (IS_ERR(xfer)) {
ret = PTR_ERR(xfer);
dev_err(info->dev, "Message alloc failed(%d)\n", ret);
return ret;
}
@@ -1650,15 +1560,11 @@ static int ti_sci_get_resource_range(const struct ti_sci_handle *handle,
req.subtype = subtype & MSG_RM_RESOURCE_SUBTYPE_MASK;
ret = ti_sci_do_xfer(info, xfer);
if (ret) {
dev_err(info->dev, "Mbox send fail %d\n", ret);
if (ret)
goto fail;
}
resp = (struct ti_sci_msg_resp_get_resource_range *)xfer->tx_message.buf;
if (!ti_sci_is_response_ack(resp)) {
ret = -ENODEV;
} else if (!resp->range_start && !resp->range_num) {
if (!resp->range_start && !resp->range_num) {
ret = -ENODEV;
} else {
*range_start = resp->range_start;
@@ -1769,21 +1675,15 @@ static int ti_sci_cmd_query_msmc(const struct ti_sci_handle *handle,
(u32 *)&req, sizeof(req), sizeof(*resp));
if (IS_ERR(xfer)) {
ret = PTR_ERR(xfer);
dev_err(info->dev, "Message alloc failed(%d)\n", ret);
return ret;
}
ret = ti_sci_do_xfer(info, xfer);
if (ret) {
dev_err(info->dev, "Mbox send fail %d\n", ret);
if (ret)
return ret;
}
resp = (struct ti_sci_msg_resp_query_msmc *)xfer->tx_message.buf;
if (!ti_sci_is_response_ack(resp))
return -ENODEV;
*msmc_start = ((u64)resp->msmc_start_high << TISCI_ADDR_HIGH_SHIFT) |
resp->msmc_start_low;
*msmc_end = ((u64)resp->msmc_end_high << TISCI_ADDR_HIGH_SHIFT) |
@@ -1820,21 +1720,13 @@ static int ti_sci_cmd_proc_request(const struct ti_sci_handle *handle,
(u32 *)&req, sizeof(req), sizeof(*resp));
if (IS_ERR(xfer)) {
ret = PTR_ERR(xfer);
dev_err(info->dev, "Message alloc failed(%d)\n", ret);
return ret;
}
req.processor_id = proc_id;
ret = ti_sci_do_xfer(info, xfer);
if (ret) {
dev_err(info->dev, "Mbox send fail %d\n", ret);
if (ret)
return ret;
}
resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
if (!ti_sci_is_response_ack(resp))
ret = -ENODEV;
return ret;
}
@@ -1867,21 +1759,13 @@ static int ti_sci_cmd_proc_release(const struct ti_sci_handle *handle,
(u32 *)&req, sizeof(req), sizeof(*resp));
if (IS_ERR(xfer)) {
ret = PTR_ERR(xfer);
dev_err(info->dev, "Message alloc failed(%d)\n", ret);
return ret;
}
req.processor_id = proc_id;
ret = ti_sci_do_xfer(info, xfer);
if (ret) {
dev_err(info->dev, "Mbox send fail %d\n", ret);
if (ret)
return ret;
}
resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
if (!ti_sci_is_response_ack(resp))
ret = -ENODEV;
return ret;
}
@@ -1917,22 +1801,14 @@ static int ti_sci_cmd_proc_handover(const struct ti_sci_handle *handle,
(u32 *)&req, sizeof(req), sizeof(*resp));
if (IS_ERR(xfer)) {
ret = PTR_ERR(xfer);
dev_err(info->dev, "Message alloc failed(%d)\n", ret);
return ret;
}
req.processor_id = proc_id;
req.host_id = host_id;
ret = ti_sci_do_xfer(info, xfer);
if (ret) {
dev_err(info->dev, "Mbox send fail %d\n", ret);
if (ret)
return ret;
}
resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
if (!ti_sci_is_response_ack(resp))
ret = -ENODEV;
return ret;
}
@@ -1970,7 +1846,6 @@ static int ti_sci_cmd_set_proc_boot_cfg(const struct ti_sci_handle *handle,
(u32 *)&req, sizeof(req), sizeof(*resp));
if (IS_ERR(xfer)) {
ret = PTR_ERR(xfer);
dev_err(info->dev, "Message alloc failed(%d)\n", ret);
return ret;
}
req.processor_id = proc_id;
@@ -1981,15 +1856,8 @@ static int ti_sci_cmd_set_proc_boot_cfg(const struct ti_sci_handle *handle,
req.config_flags_clear = config_flags_clear;
ret = ti_sci_do_xfer(info, xfer);
if (ret) {
dev_err(info->dev, "Mbox send fail %d\n", ret);
if (ret)
return ret;
}
resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
if (!ti_sci_is_response_ack(resp))
ret = -ENODEV;
return ret;
}
@@ -2026,7 +1894,6 @@ static int ti_sci_cmd_set_proc_boot_ctrl(const struct ti_sci_handle *handle,
(u32 *)&req, sizeof(req), sizeof(*resp));
if (IS_ERR(xfer)) {
ret = PTR_ERR(xfer);
dev_err(info->dev, "Message alloc failed(%d)\n", ret);
return ret;
}
req.processor_id = proc_id;
@@ -2034,15 +1901,8 @@ static int ti_sci_cmd_set_proc_boot_ctrl(const struct ti_sci_handle *handle,
req.control_flags_clear = control_flags_clear;
ret = ti_sci_do_xfer(info, xfer);
if (ret) {
dev_err(info->dev, "Mbox send fail %d\n", ret);
if (ret)
return ret;
}
resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
if (!ti_sci_is_response_ack(resp))
ret = -ENODEV;
return ret;
}
@@ -2080,7 +1940,6 @@ static int ti_sci_cmd_proc_auth_boot_image(const struct ti_sci_handle *handle,
(u32 *)&req, sizeof(req), sizeof(*resp));
if (IS_ERR(xfer)) {
ret = PTR_ERR(xfer);
dev_err(info->dev, "Message alloc failed(%d)\n", ret);
return ret;
}
req.cert_addr_low = *image_addr & TISCI_ADDR_LOW_MASK;
@@ -2088,16 +1947,11 @@ static int ti_sci_cmd_proc_auth_boot_image(const struct ti_sci_handle *handle,
TISCI_ADDR_HIGH_SHIFT;
ret = ti_sci_do_xfer(info, xfer);
if (ret) {
dev_err(info->dev, "Mbox send fail %d\n", ret);
if (ret)
return ret;
}
resp = (struct ti_sci_msg_resp_proc_auth_boot_image *)xfer->tx_message.buf;
if (!ti_sci_is_response_ack(resp))
return -ENODEV;
*image_addr = (resp->image_addr_low & TISCI_ADDR_LOW_MASK) |
(((u64)resp->image_addr_high <<
TISCI_ADDR_HIGH_SHIFT) & TISCI_ADDR_HIGH_MASK);
@@ -2135,22 +1989,17 @@ static int ti_sci_cmd_get_proc_boot_status(const struct ti_sci_handle *handle,
(u32 *)&req, sizeof(req), sizeof(*resp));
if (IS_ERR(xfer)) {
ret = PTR_ERR(xfer);
dev_err(info->dev, "Message alloc failed(%d)\n", ret);
return ret;
}
req.processor_id = proc_id;
ret = ti_sci_do_xfer(info, xfer);
if (ret) {
dev_err(info->dev, "Mbox send fail %d\n", ret);
if (ret)
return ret;
}
resp = (struct ti_sci_msg_resp_get_proc_boot_status *)
xfer->tx_message.buf;
if (!ti_sci_is_response_ack(resp))
return -ENODEV;
*bv = (resp->bootvector_low & TISCI_ADDR_LOW_MASK) |
(((u64)resp->bootvector_high <<
TISCI_ADDR_HIGH_SHIFT) & TISCI_ADDR_HIGH_MASK);
@@ -2225,7 +2074,6 @@ ti_sci_proc_wait_boot_status_no_wait(const struct ti_sci_handle *handle,
(u32 *)&req, sizeof(req), 0);
if (IS_ERR(xfer)) {
ret = PTR_ERR(xfer);
dev_err(info->dev, "Message alloc failed(%d)\n", ret);
return ret;
}
req.processor_id = proc_id;
@@ -2240,7 +2088,7 @@ ti_sci_proc_wait_boot_status_no_wait(const struct ti_sci_handle *handle,
ret = ti_sci_do_xfer(info, xfer);
if (ret)
dev_err(info->dev, "Mbox send fail %d\n", ret);
return ret;
return ret;
}
@@ -2340,7 +2188,6 @@ static int ti_sci_cmd_ring_config(const struct ti_sci_handle *handle,
(u32 *)&req, sizeof(req), sizeof(*resp));
if (IS_ERR(xfer)) {
ret = PTR_ERR(xfer);
dev_err(info->dev, "RM_RA:Message config failed(%d)\n", ret);
return ret;
}
req.valid_params = valid_params;
@@ -2354,14 +2201,8 @@ static int ti_sci_cmd_ring_config(const struct ti_sci_handle *handle,
req.order_id = order_id;
ret = ti_sci_do_xfer(info, xfer);
if (ret) {
dev_err(info->dev, "RM_RA:Mbox config send fail %d\n", ret);
if (ret)
goto fail;
}
resp = (struct ti_sci_msg_rm_ring_cfg_resp *)xfer->tx_message.buf;
ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
fail:
dev_dbg(info->dev, "RM_RA:config ring %u ret:%d\n", index, ret);
@@ -2389,7 +2230,6 @@ static int ti_sci_cmd_rm_psil_pair(const struct ti_sci_handle *handle,
(u32 *)&req, sizeof(req), sizeof(*resp));
if (IS_ERR(xfer)) {
ret = PTR_ERR(xfer);
dev_err(info->dev, "RM_PSIL:Message alloc failed(%d)\n", ret);
return ret;
}
req.nav_id = nav_id;
@@ -2397,13 +2237,8 @@ static int ti_sci_cmd_rm_psil_pair(const struct ti_sci_handle *handle,
req.dst_thread = dst_thread;
ret = ti_sci_do_xfer(info, xfer);
if (ret) {
dev_err(info->dev, "RM_PSIL:Mbox send fail %d\n", ret);
if (ret)
goto fail;
}
resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
fail:
dev_dbg(info->dev, "RM_PSIL: nav: %u link pair %u->%u ret:%u\n",
@@ -2432,7 +2267,6 @@ static int ti_sci_cmd_rm_psil_unpair(const struct ti_sci_handle *handle,
(u32 *)&req, sizeof(req), sizeof(*resp));
if (IS_ERR(xfer)) {
ret = PTR_ERR(xfer);
dev_err(info->dev, "RM_PSIL:Message alloc failed(%d)\n", ret);
return ret;
}
req.nav_id = nav_id;
@@ -2440,13 +2274,8 @@ static int ti_sci_cmd_rm_psil_unpair(const struct ti_sci_handle *handle,
req.dst_thread = dst_thread;
ret = ti_sci_do_xfer(info, xfer);
if (ret) {
dev_err(info->dev, "RM_PSIL:Mbox send fail %d\n", ret);
if (ret)
goto fail;
}
resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
fail:
dev_dbg(info->dev, "RM_PSIL: link unpair %u->%u ret:%u\n",
@@ -2476,7 +2305,6 @@ static int ti_sci_cmd_rm_udmap_tx_ch_cfg(
(u32 *)&req, sizeof(req), sizeof(*resp));
if (IS_ERR(xfer)) {
ret = PTR_ERR(xfer);
dev_err(info->dev, "Message TX_CH_CFG alloc failed(%d)\n", ret);
return ret;
}
req.valid_params = params->valid_params;
@@ -2501,14 +2329,8 @@ static int ti_sci_cmd_rm_udmap_tx_ch_cfg(
req.extended_ch_type = params->extended_ch_type;
ret = ti_sci_do_xfer(info, xfer);
if (ret) {
dev_err(info->dev, "Mbox send TX_CH_CFG fail %d\n", ret);
if (ret)
goto fail;
}
resp =
(struct ti_sci_msg_rm_udmap_tx_ch_cfg_resp *)xfer->tx_message.buf;
ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL;
fail:
dev_dbg(info->dev, "TX_CH_CFG: chn %u ret:%u\n", params->index, ret);
@@ -2537,7 +2359,6 @@ static int ti_sci_cmd_rm_udmap_rx_ch_cfg(
(u32 *)&req, sizeof(req), sizeof(*resp));
if (IS_ERR(xfer)) {
ret = PTR_ERR(xfer);
dev_err(info->dev, "Message RX_CH_CFG alloc failed(%d)\n", ret);
return ret;
}
@@ -2559,14 +2380,8 @@ static int ti_sci_cmd_rm_udmap_rx_ch_cfg(
req.rx_ignore_long = params->rx_ignore_long;
ret = ti_sci_do_xfer(info, xfer);
if (ret) {
dev_err(info->dev, "Mbox send RX_CH_CFG fail %d\n", ret);
if (ret)
goto fail;
}
resp =
(struct ti_sci_msg_rm_udmap_rx_ch_cfg_resp *)xfer->tx_message.buf;
ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL;
fail:
dev_dbg(info->dev, "RX_CH_CFG: chn %u ret:%d\n", params->index, ret);
@@ -2595,8 +2410,6 @@ static int ti_sci_cmd_rm_udmap_rx_flow_cfg(
(u32 *)&req, sizeof(req), sizeof(*resp));
if (IS_ERR(xfer)) {
ret = PTR_ERR(xfer);
dev_err(info->dev, "RX_FL_CFG: Message alloc failed(%d)\n",
ret);
return ret;
}
@@ -2624,14 +2437,8 @@ static int ti_sci_cmd_rm_udmap_rx_flow_cfg(
req.rx_ps_location = params->rx_ps_location;
ret = ti_sci_do_xfer(info, xfer);
if (ret) {
dev_err(info->dev, "RX_FL_CFG: Mbox send fail %d\n", ret);
if (ret)
goto fail;
}
resp =
(struct ti_sci_msg_rm_udmap_flow_cfg_resp *)xfer->tx_message.buf;
ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL;
fail:
dev_dbg(info->dev, "RX_FL_CFG: %u ret:%d\n", params->flow_index, ret);
@@ -2666,7 +2473,6 @@ static int ti_sci_cmd_set_fwl_region(const struct ti_sci_handle *handle,
(u32 *)&req, sizeof(req), sizeof(*resp));
if (IS_ERR(xfer)) {
ret = PTR_ERR(xfer);
dev_err(info->dev, "Message alloc failed(%d)\n", ret);
return ret;
}
@@ -2681,15 +2487,8 @@ static int ti_sci_cmd_set_fwl_region(const struct ti_sci_handle *handle,
req.end_address = region->end_address;
ret = ti_sci_do_xfer(info, xfer);
if (ret) {
dev_err(info->dev, "Mbox send fail %d\n", ret);
if (ret)
return ret;
}
resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
if (!ti_sci_is_response_ack(resp))
return -ENODEV;
return 0;
}
@@ -2722,7 +2521,6 @@ static int ti_sci_cmd_get_fwl_region(const struct ti_sci_handle *handle,
(u32 *)&req, sizeof(req), sizeof(*resp));
if (IS_ERR(xfer)) {
ret = PTR_ERR(xfer);
dev_err(info->dev, "Message alloc failed(%d)\n", ret);
return ret;
}
@@ -2731,16 +2529,11 @@ static int ti_sci_cmd_get_fwl_region(const struct ti_sci_handle *handle,
req.n_permission_regs = region->n_permission_regs;
ret = ti_sci_do_xfer(info, xfer);
if (ret) {
dev_err(info->dev, "Mbox send fail %d\n", ret);
if (ret)
return ret;
}
resp = (struct ti_sci_msg_fwl_get_firewall_region_resp *)xfer->tx_message.buf;
if (!ti_sci_is_response_ack(resp))
return -ENODEV;
region->fwl_id = resp->fwl_id;
region->region = resp->region;
region->n_permission_regs = resp->n_permission_regs;
@@ -2782,7 +2575,6 @@ static int ti_sci_cmd_change_fwl_owner(const struct ti_sci_handle *handle,
(u32 *)&req, sizeof(req), sizeof(*resp));
if (IS_ERR(xfer)) {
ret = PTR_ERR(xfer);
dev_err(info->dev, "Message alloc failed(%d)\n", ret);
return ret;
}
@@ -2791,16 +2583,11 @@ static int ti_sci_cmd_change_fwl_owner(const struct ti_sci_handle *handle,
req.owner_index = owner->owner_index;
ret = ti_sci_do_xfer(info, xfer);
if (ret) {
dev_err(info->dev, "Mbox send fail %d\n", ret);
if (ret)
return ret;
}
resp = (struct ti_sci_msg_fwl_change_owner_info_resp *)xfer->tx_message.buf;
if (!ti_sci_is_response_ack(resp))
return -ENODEV;
owner->fwl_id = resp->fwl_id;
owner->region = resp->region;
owner->owner_index = resp->owner_index;

View File

@@ -303,14 +303,14 @@ config CMD_PCA953X
legacy GPIO interface. Several subcommands are provided which mirror
the standard 'gpio' command. It should use that instead.
config PM8916_GPIO
bool "Qualcomm PM8916 PMIC GPIO/keypad driver"
depends on DM_GPIO && PMIC_PM8916
config QCOM_PMIC_GPIO
bool "Qualcomm generic PMIC GPIO/keypad driver"
depends on DM_GPIO && PMIC_QCOM
help
Support for GPIO pins and power/reset buttons found on
Qualcomm PM8916 PMIC.
Qualcomm SoCs PMIC.
Default name for GPIO bank is "pm8916".
Power and reset buttons are placed in "pm8916_key" bank and
Power and reset buttons are placed in "pwkey_qcom" bank and
have gpio numbers 0 and 1 respectively.
config PCF8575_GPIO

View File

@@ -63,7 +63,7 @@ obj-$(CONFIG_OCTEON_GPIO) += octeon_gpio.o
obj-$(CONFIG_MVEBU_GPIO) += mvebu_gpio.o
obj-$(CONFIG_MSM_GPIO) += msm_gpio.o
obj-$(CONFIG_$(SPL_)PCF8575_GPIO) += pcf8575_gpio.o
obj-$(CONFIG_$(SPL_TPL_)PM8916_GPIO) += pm8916_gpio.o
obj-$(CONFIG_$(SPL_TPL_)QCOM_PMIC_GPIO) += qcom_pmic_gpio.o
obj-$(CONFIG_MT7620_GPIO) += mt7620_gpio.o
obj-$(CONFIG_MT7621_GPIO) += mt7621_gpio.o
obj-$(CONFIG_MSCC_SGPIO) += mscc_sgpio.o

View File

@@ -116,20 +116,12 @@ static int msm_gpio_of_to_plat(struct udevice *dev)
return 0;
}
static const struct udevice_id msm_gpio_ids[] = {
{ .compatible = "qcom,msm8916-pinctrl" },
{ .compatible = "qcom,apq8016-pinctrl" },
{ .compatible = "qcom,ipq4019-pinctrl" },
{ .compatible = "qcom,sdm845-pinctrl" },
{ }
};
U_BOOT_DRIVER(gpio_msm) = {
.name = "gpio_msm",
.id = UCLASS_GPIO,
.of_match = msm_gpio_ids,
.of_to_plat = msm_gpio_of_to_plat,
.probe = msm_gpio_probe,
.ops = &gpio_msm_ops,
.flags = DM_UC_FLAG_SEQ_ALIAS,
.priv_auto = sizeof(struct msm_gpio_bank),
};

View File

@@ -1,303 +0,0 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Qualcomm pm8916 pmic gpio driver - part of Qualcomm PM8916 PMIC
*
* (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
*/
#include <common.h>
#include <dm.h>
#include <log.h>
#include <power/pmic.h>
#include <spmi/spmi.h>
#include <asm/io.h>
#include <asm/gpio.h>
#include <linux/bitops.h>
/* Register offset for each gpio */
#define REG_OFFSET(x) ((x) * 0x100)
/* Register maps */
/* Type and subtype are shared for all pm8916 peripherals */
#define REG_TYPE 0x4
#define REG_SUBTYPE 0x5
#define REG_STATUS 0x08
#define REG_STATUS_VAL_MASK 0x1
/* MODE_CTL */
#define REG_CTL 0x40
#define REG_CTL_MODE_MASK 0x70
#define REG_CTL_MODE_INPUT 0x00
#define REG_CTL_MODE_INOUT 0x20
#define REG_CTL_MODE_OUTPUT 0x10
#define REG_CTL_OUTPUT_MASK 0x0F
#define REG_DIG_VIN_CTL 0x41
#define REG_DIG_VIN_VIN0 0
#define REG_DIG_PULL_CTL 0x42
#define REG_DIG_PULL_NO_PU 0x5
#define REG_DIG_OUT_CTL 0x45
#define REG_DIG_OUT_CTL_CMOS (0x0 << 4)
#define REG_DIG_OUT_CTL_DRIVE_L 0x1
#define REG_EN_CTL 0x46
#define REG_EN_CTL_ENABLE (1 << 7)
struct pm8916_gpio_bank {
uint32_t pid; /* Peripheral ID on SPMI bus */
};
static int pm8916_gpio_set_direction(struct udevice *dev, unsigned offset,
bool input, int value)
{
struct pm8916_gpio_bank *priv = dev_get_priv(dev);
uint32_t gpio_base = priv->pid + REG_OFFSET(offset);
int ret;
/* Disable the GPIO */
ret = pmic_clrsetbits(dev->parent, gpio_base + REG_EN_CTL,
REG_EN_CTL_ENABLE, 0);
if (ret < 0)
return ret;
/* Select the mode */
if (input)
ret = pmic_reg_write(dev->parent, gpio_base + REG_CTL,
REG_CTL_MODE_INPUT);
else
ret = pmic_reg_write(dev->parent, gpio_base + REG_CTL,
REG_CTL_MODE_INOUT | (value ? 1 : 0));
if (ret < 0)
return ret;
/* Set the right pull (no pull) */
ret = pmic_reg_write(dev->parent, gpio_base + REG_DIG_PULL_CTL,
REG_DIG_PULL_NO_PU);
if (ret < 0)
return ret;
/* Configure output pin drivers if needed */
if (!input) {
/* Select the VIN - VIN0, pin is input so it doesn't matter */
ret = pmic_reg_write(dev->parent, gpio_base + REG_DIG_VIN_CTL,
REG_DIG_VIN_VIN0);
if (ret < 0)
return ret;
/* Set the right dig out control */
ret = pmic_reg_write(dev->parent, gpio_base + REG_DIG_OUT_CTL,
REG_DIG_OUT_CTL_CMOS |
REG_DIG_OUT_CTL_DRIVE_L);
if (ret < 0)
return ret;
}
/* Enable the GPIO */
return pmic_clrsetbits(dev->parent, gpio_base + REG_EN_CTL, 0,
REG_EN_CTL_ENABLE);
}
static int pm8916_gpio_direction_input(struct udevice *dev, unsigned offset)
{
return pm8916_gpio_set_direction(dev, offset, true, 0);
}
static int pm8916_gpio_direction_output(struct udevice *dev, unsigned offset,
int value)
{
return pm8916_gpio_set_direction(dev, offset, false, value);
}
static int pm8916_gpio_get_function(struct udevice *dev, unsigned offset)
{
struct pm8916_gpio_bank *priv = dev_get_priv(dev);
uint32_t gpio_base = priv->pid + REG_OFFSET(offset);
int reg;
/* Set the output value of the gpio */
reg = pmic_reg_read(dev->parent, gpio_base + REG_CTL);
if (reg < 0)
return reg;
switch (reg & REG_CTL_MODE_MASK) {
case REG_CTL_MODE_INPUT:
return GPIOF_INPUT;
case REG_CTL_MODE_INOUT: /* Fallthrough */
case REG_CTL_MODE_OUTPUT:
return GPIOF_OUTPUT;
default:
return GPIOF_UNKNOWN;
}
}
static int pm8916_gpio_get_value(struct udevice *dev, unsigned offset)
{
struct pm8916_gpio_bank *priv = dev_get_priv(dev);
uint32_t gpio_base = priv->pid + REG_OFFSET(offset);
int reg;
reg = pmic_reg_read(dev->parent, gpio_base + REG_STATUS);
if (reg < 0)
return reg;
return !!(reg & REG_STATUS_VAL_MASK);
}
static int pm8916_gpio_set_value(struct udevice *dev, unsigned offset,
int value)
{
struct pm8916_gpio_bank *priv = dev_get_priv(dev);
uint32_t gpio_base = priv->pid + REG_OFFSET(offset);
/* Set the output value of the gpio */
return pmic_clrsetbits(dev->parent, gpio_base + REG_CTL,
REG_CTL_OUTPUT_MASK, !!value);
}
static const struct dm_gpio_ops pm8916_gpio_ops = {
.direction_input = pm8916_gpio_direction_input,
.direction_output = pm8916_gpio_direction_output,
.get_value = pm8916_gpio_get_value,
.set_value = pm8916_gpio_set_value,
.get_function = pm8916_gpio_get_function,
};
static int pm8916_gpio_probe(struct udevice *dev)
{
struct pm8916_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 != 0x10)
return log_msg_ret("bad type", -ENXIO);
reg = pmic_reg_read(dev->parent, priv->pid + REG_SUBTYPE);
if (reg != 0x5 && reg != 0x1)
return log_msg_ret("bad subtype", -ENXIO);
return 0;
}
static int pm8916_gpio_of_to_plat(struct udevice *dev)
{
struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
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 = "pm8916";
return 0;
}
static const struct udevice_id pm8916_gpio_ids[] = {
{ .compatible = "qcom,pm8916-gpio" },
{ .compatible = "qcom,pm8994-gpio" }, /* 22 GPIO's */
{ .compatible = "qcom,pm8998-gpio" },
{ }
};
U_BOOT_DRIVER(gpio_pm8916) = {
.name = "gpio_pm8916",
.id = UCLASS_GPIO,
.of_match = pm8916_gpio_ids,
.of_to_plat = pm8916_gpio_of_to_plat,
.probe = pm8916_gpio_probe,
.ops = &pm8916_gpio_ops,
.priv_auto = sizeof(struct pm8916_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 pm8941_pwrkey_get_function(struct udevice *dev, unsigned offset)
{
return GPIOF_INPUT;
}
static int pm8941_pwrkey_get_value(struct udevice *dev, unsigned offset)
{
struct pm8916_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;
}
}
static const struct dm_gpio_ops pm8941_pwrkey_ops = {
.get_value = pm8941_pwrkey_get_value,
.get_function = pm8941_pwrkey_get_function,
};
static int pm8941_pwrkey_probe(struct udevice *dev)
{
struct pm8916_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 pm8941_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 = "pm8916_key";
return 0;
}
static const struct udevice_id pm8941_pwrkey_ids[] = {
{ .compatible = "qcom,pm8916-pwrkey" },
{ .compatible = "qcom,pm8994-pwrkey" },
{ .compatible = "qcom,pm8998-pwrkey" },
{ }
};
U_BOOT_DRIVER(pwrkey_pm89xx) = {
.name = "pwrkey_pm89xx",
.id = UCLASS_GPIO,
.of_match = pm8941_pwrkey_ids,
.of_to_plat = pm8941_pwrkey_of_to_plat,
.probe = pm8941_pwrkey_probe,
.ops = &pm8941_pwrkey_ops,
.priv_auto = sizeof(struct pm8916_gpio_bank),
};

View File

@@ -0,0 +1,359 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Qualcomm generic pmic gpio driver
*
* (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
*/
#include <common.h>
#include <dm.h>
#include <log.h>
#include <power/pmic.h>
#include <spmi/spmi.h>
#include <asm/io.h>
#include <asm/gpio.h>
#include <linux/bitops.h>
/* Register offset for each gpio */
#define REG_OFFSET(x) ((x) * 0x100)
/* Register maps */
/* Type and subtype are shared for all PMIC peripherals */
#define REG_TYPE 0x4
#define REG_SUBTYPE 0x5
/* GPIO peripheral type and subtype out_values */
#define REG_TYPE_VAL 0x10
#define REG_SUBTYPE_GPIO_4CH 0x1
#define REG_SUBTYPE_GPIOC_4CH 0x5
#define REG_SUBTYPE_GPIO_8CH 0x9
#define REG_SUBTYPE_GPIOC_8CH 0xd
#define REG_SUBTYPE_GPIO_LV 0x10
#define REG_SUBTYPE_GPIO_MV 0x11
#define REG_STATUS 0x08
#define REG_STATUS_VAL_MASK 0x1
/* MODE_CTL */
#define REG_CTL 0x40
#define REG_CTL_MODE_MASK 0x70
#define REG_CTL_MODE_INPUT 0x00
#define REG_CTL_MODE_INOUT 0x20
#define REG_CTL_MODE_OUTPUT 0x10
#define REG_CTL_OUTPUT_MASK 0x0F
#define REG_CTL_LV_MV_MODE_MASK 0x3
#define REG_CTL_LV_MV_MODE_INPUT 0x0
#define REG_CTL_LV_MV_MODE_INOUT 0x2
#define REG_CTL_LV_MV_MODE_OUTPUT 0x1
#define REG_DIG_VIN_CTL 0x41
#define REG_DIG_VIN_VIN0 0
#define REG_DIG_PULL_CTL 0x42
#define REG_DIG_PULL_NO_PU 0x5
#define REG_LV_MV_OUTPUT_CTL 0x44
#define REG_LV_MV_OUTPUT_CTL_MASK 0x80
#define REG_LV_MV_OUTPUT_CTL_SHIFT 7
#define REG_DIG_OUT_CTL 0x45
#define REG_DIG_OUT_CTL_CMOS (0x0 << 4)
#define REG_DIG_OUT_CTL_DRIVE_L 0x1
#define REG_EN_CTL 0x46
#define REG_EN_CTL_ENABLE (1 << 7)
struct qcom_gpio_bank {
uint32_t pid; /* Peripheral ID on SPMI bus */
bool lv_mv_type; /* If subtype is GPIO_LV(0x10) or GPIO_MV(0x11) */
};
static int qcom_gpio_set_direction(struct udevice *dev, unsigned offset,
bool input, int value)
{
struct qcom_gpio_bank *priv = dev_get_priv(dev);
uint32_t gpio_base = priv->pid + REG_OFFSET(offset);
uint32_t reg_ctl_val;
int ret;
/* Disable the GPIO */
ret = pmic_clrsetbits(dev->parent, gpio_base + REG_EN_CTL,
REG_EN_CTL_ENABLE, 0);
if (ret < 0)
return ret;
/* Select the mode and output */
if (priv->lv_mv_type) {
if (input)
reg_ctl_val = REG_CTL_LV_MV_MODE_INPUT;
else
reg_ctl_val = REG_CTL_LV_MV_MODE_INOUT;
} else {
if (input)
reg_ctl_val = REG_CTL_MODE_INPUT;
else
reg_ctl_val = REG_CTL_MODE_INOUT | !!value;
}
ret = pmic_reg_write(dev->parent, gpio_base + REG_CTL, reg_ctl_val);
if (ret < 0)
return ret;
if (priv->lv_mv_type && !input) {
ret = pmic_reg_write(dev->parent,
gpio_base + REG_LV_MV_OUTPUT_CTL,
!!value << REG_LV_MV_OUTPUT_CTL_SHIFT);
if (ret < 0)
return ret;
}
/* Set the right pull (no pull) */
ret = pmic_reg_write(dev->parent, gpio_base + REG_DIG_PULL_CTL,
REG_DIG_PULL_NO_PU);
if (ret < 0)
return ret;
/* Configure output pin drivers if needed */
if (!input) {
/* Select the VIN - VIN0, pin is input so it doesn't matter */
ret = pmic_reg_write(dev->parent, gpio_base + REG_DIG_VIN_CTL,
REG_DIG_VIN_VIN0);
if (ret < 0)
return ret;
/* Set the right dig out control */
ret = pmic_reg_write(dev->parent, gpio_base + REG_DIG_OUT_CTL,
REG_DIG_OUT_CTL_CMOS |
REG_DIG_OUT_CTL_DRIVE_L);
if (ret < 0)
return ret;
}
/* Enable the GPIO */
return pmic_clrsetbits(dev->parent, gpio_base + REG_EN_CTL, 0,
REG_EN_CTL_ENABLE);
}
static int qcom_gpio_direction_input(struct udevice *dev, unsigned offset)
{
return qcom_gpio_set_direction(dev, offset, true, 0);
}
static int qcom_gpio_direction_output(struct udevice *dev, unsigned offset,
int value)
{
return qcom_gpio_set_direction(dev, offset, false, value);
}
static int qcom_gpio_get_function(struct udevice *dev, unsigned offset)
{
struct qcom_gpio_bank *priv = dev_get_priv(dev);
uint32_t gpio_base = priv->pid + REG_OFFSET(offset);
int reg;
reg = pmic_reg_read(dev->parent, gpio_base + REG_CTL);
if (reg < 0)
return reg;
if (priv->lv_mv_type) {
switch (reg & REG_CTL_LV_MV_MODE_MASK) {
case REG_CTL_LV_MV_MODE_INPUT:
return GPIOF_INPUT;
case REG_CTL_LV_MV_MODE_INOUT: /* Fallthrough */
case REG_CTL_LV_MV_MODE_OUTPUT:
return GPIOF_OUTPUT;
default:
return GPIOF_UNKNOWN;
}
} else {
switch (reg & REG_CTL_MODE_MASK) {
case REG_CTL_MODE_INPUT:
return GPIOF_INPUT;
case REG_CTL_MODE_INOUT: /* Fallthrough */
case REG_CTL_MODE_OUTPUT:
return GPIOF_OUTPUT;
default:
return GPIOF_UNKNOWN;
}
}
}
static int qcom_gpio_get_value(struct udevice *dev, unsigned offset)
{
struct qcom_gpio_bank *priv = dev_get_priv(dev);
uint32_t gpio_base = priv->pid + REG_OFFSET(offset);
int reg;
reg = pmic_reg_read(dev->parent, gpio_base + REG_STATUS);
if (reg < 0)
return reg;
return !!(reg & REG_STATUS_VAL_MASK);
}
static int qcom_gpio_set_value(struct udevice *dev, unsigned offset,
int value)
{
struct qcom_gpio_bank *priv = dev_get_priv(dev);
uint32_t gpio_base = priv->pid + REG_OFFSET(offset);
/* Set the output value of the gpio */
if (priv->lv_mv_type)
return pmic_clrsetbits(dev->parent,
gpio_base + REG_LV_MV_OUTPUT_CTL,
REG_LV_MV_OUTPUT_CTL_MASK,
!!value << REG_LV_MV_OUTPUT_CTL_SHIFT);
else
return pmic_clrsetbits(dev->parent, gpio_base + REG_CTL,
REG_CTL_OUTPUT_MASK, !!value);
}
static const struct dm_gpio_ops qcom_gpio_ops = {
.direction_input = qcom_gpio_direction_input,
.direction_output = qcom_gpio_direction_output,
.get_value = qcom_gpio_get_value,
.set_value = qcom_gpio_set_value,
.get_function = qcom_gpio_get_function,
};
static int qcom_gpio_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 != REG_TYPE_VAL)
return log_msg_ret("bad type", -ENXIO);
reg = pmic_reg_read(dev->parent, priv->pid + REG_SUBTYPE);
if (reg != REG_SUBTYPE_GPIO_4CH && reg != REG_SUBTYPE_GPIOC_4CH &&
reg != REG_SUBTYPE_GPIO_LV && reg != REG_SUBTYPE_GPIO_MV)
return log_msg_ret("bad subtype", -ENXIO);
priv->lv_mv_type = reg == REG_SUBTYPE_GPIO_LV ||
reg == REG_SUBTYPE_GPIO_MV;
return 0;
}
static int qcom_gpio_of_to_plat(struct udevice *dev)
{
struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
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";
return 0;
}
static const struct udevice_id qcom_gpio_ids[] = {
{ .compatible = "qcom,pm8916-gpio" },
{ .compatible = "qcom,pm8994-gpio" }, /* 22 GPIO's */
{ .compatible = "qcom,pm8998-gpio" },
{ .compatible = "qcom,pms405-gpio" },
{ }
};
U_BOOT_DRIVER(qcom_pmic_gpio) = {
.name = "qcom_pmic_gpio",
.id = UCLASS_GPIO,
.of_match = qcom_gpio_ids,
.of_to_plat = qcom_gpio_of_to_plat,
.probe = qcom_gpio_probe,
.ops = &qcom_gpio_ops,
.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;
}
}
static const struct dm_gpio_ops qcom_pwrkey_ops = {
.get_value = qcom_pwrkey_get_value,
.get_function = qcom_pwrkey_get_function,
};
static int qcom_pwrkey_probe(struct udevice *dev)
{
struct qcom_gpio_bank *priv = dev_get_priv(dev);
int reg;
priv->pid = dev_read_addr(dev);
if (priv->pid == FDT_ADDR_T_NONE)
return log_msg_ret("bad address", -EINVAL);
/* Do a sanity check */
reg = pmic_reg_read(dev->parent, priv->pid + REG_TYPE);
if (reg != 0x1)
return log_msg_ret("bad type", -ENXIO);
reg = pmic_reg_read(dev->parent, priv->pid + REG_SUBTYPE);
if ((reg & 0x5) == 0)
return log_msg_ret("bad subtype", -ENXIO);
return 0;
}
static int qcom_pwrkey_of_to_plat(struct udevice *dev)
{
struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
uc_priv->gpio_count = 2;
uc_priv->bank_name = dev_read_string(dev, "gpio-bank-name");
if (uc_priv->bank_name == NULL)
uc_priv->bank_name = "pwkey_qcom";
return 0;
}
static const struct udevice_id qcom_pwrkey_ids[] = {
{ .compatible = "qcom,pm8916-pwrkey" },
{ .compatible = "qcom,pm8994-pwrkey" },
{ .compatible = "qcom,pm8998-pwrkey" },
{ }
};
U_BOOT_DRIVER(pwrkey_qcom) = {
.name = "pwrkey_qcom",
.id = UCLASS_GPIO,
.of_match = qcom_pwrkey_ids,
.of_to_plat = qcom_pwrkey_of_to_plat,
.probe = qcom_pwrkey_probe,
.ops = &qcom_pwrkey_ops,
.priv_auto = sizeof(struct qcom_gpio_bank),
};

View File

@@ -143,12 +143,6 @@ config STI_USB_PHY
used by USB2 and USB3 Host controllers available on
STiH407 SoC families.
config PHY_QCOM_IPQ4019_USB
tristate "Qualcomm IPQ4019 USB PHY driver"
depends on PHY && ARCH_IPQ40XX
help
Support for the USB PHY-s on Qualcomm IPQ40xx SoC-s.
config PHY_RCAR_GEN2
tristate "Renesas R-Car Gen2 USB PHY"
depends on PHY && RCAR_GEN2
@@ -220,14 +214,6 @@ config MESON_AXG_MIPI_PCIE_ANALOG_PHY
This is the generic phy driver for the Amlogic Meson AXG
MIPI PCIe Analog PHY.
config MSM8916_USB_PHY
bool "Qualcomm MSM8916 USB PHY support"
depends on PHY
help
Support the USB PHY in msm8916
This PHY is found on qualcomm dragonboard410c development board.
config OMAP_USB2_PHY
bool "Support OMAP's USB2 PHY"
depends on PHY
@@ -298,5 +284,6 @@ config PHY_XILINX_ZYNQMP
source "drivers/phy/rockchip/Kconfig"
source "drivers/phy/cadence/Kconfig"
source "drivers/phy/ti/Kconfig"
source "drivers/phy/qcom/Kconfig"
endmenu

View File

@@ -21,7 +21,6 @@ obj-$(CONFIG_PHY_SANDBOX) += sandbox-phy.o
obj-$(CONFIG_$(SPL_)PIPE3_PHY) += ti-pipe3-phy.o
obj-$(CONFIG_AM654_PHY) += phy-ti-am654.o
obj-$(CONFIG_STI_USB_PHY) += sti_usb_phy.o
obj-$(CONFIG_PHY_QCOM_IPQ4019_USB) += phy-qcom-ipq4019-usb.o
obj-$(CONFIG_PHY_RCAR_GEN2) += phy-rcar-gen2.o
obj-$(CONFIG_PHY_RCAR_GEN3) += phy-rcar-gen3.o
obj-$(CONFIG_PHY_STM32_USBPHYC) += phy-stm32-usbphyc.o
@@ -30,7 +29,6 @@ obj-$(CONFIG_MESON_GXL_USB_PHY) += meson-gxl-usb2.o
obj-$(CONFIG_MESON_G12A_USB_PHY) += meson-g12a-usb2.o meson-g12a-usb3-pcie.o
obj-$(CONFIG_MESON_AXG_MIPI_DPHY) += meson-axg-mipi-dphy.o
obj-$(CONFIG_MESON_AXG_MIPI_PCIE_ANALOG_PHY) += meson-axg-mipi-pcie-analog.o
obj-$(CONFIG_MSM8916_USB_PHY) += msm8916-usbh-phy.o
obj-$(CONFIG_OMAP_USB2_PHY) += omap-usb2-phy.o
obj-$(CONFIG_KEYSTONE_USB_PHY) += keystone-usb-phy.o
obj-$(CONFIG_MT7620_USB_PHY) += mt7620-usb-phy.o
@@ -42,3 +40,4 @@ obj-$(CONFIG_PHY_IMX8MQ_USB) += phy-imx8mq-usb.o
obj-$(CONFIG_PHY_XILINX_ZYNQMP) += phy-zynqmp.o
obj-y += cadence/
obj-y += ti/
obj-y += qcom/

29
drivers/phy/qcom/Kconfig Normal file
View File

@@ -0,0 +1,29 @@
config MSM8916_USB_PHY
bool "Qualcomm MSM8916 USB PHY support"
depends on PHY
help
Support the USB PHY in msm8916
This PHY is found on qualcomm dragonboard410c development board.
config PHY_QCOM_IPQ4019_USB
tristate "Qualcomm IPQ4019 USB PHY driver"
depends on PHY && ARCH_IPQ40XX
help
Support for the USB PHY-s on Qualcomm IPQ40xx SoC-s.
config PHY_QCOM_USB_HS_28NM
tristate "Qualcomm 28nm High-Speed PHY"
depends on PHY && ARCH_SNAPDRAGON
help
Enable this to support the Qualcomm Synopsys DesignWare Core 28nm
High-Speed PHY driver. This driver supports the Hi-Speed PHY which
is usually paired with either the ChipIdea or Synopsys DWC3 USB
IPs on MSM SOCs.
config PHY_QCOM_USB_SS
tristate "Qualcomm USB Super-Speed PHY driver"
depends on PHY && ARCH_SNAPDRAGON
help
Enable this to support the Super-Speed USB transceiver on various
Qualcomm chipsets.

View File

@@ -0,0 +1,4 @@
obj-$(CONFIG_PHY_QCOM_IPQ4019_USB) += phy-qcom-ipq4019-usb.o
obj-$(CONFIG_MSM8916_USB_PHY) += msm8916-usbh-phy.o
obj-$(CONFIG_PHY_QCOM_USB_HS_28NM) += phy-qcom-usb-hs-28nm.o
obj-$(CONFIG_PHY_QCOM_USB_SS) += phy-qcom-usb-ss.o

View File

@@ -0,0 +1,250 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2022 Sumit Garg <sumit.garg@linaro.org>
*
* Based on Linux driver
*/
#include <common.h>
#include <dm.h>
#include <generic-phy.h>
#include <reset.h>
#include <clk.h>
#include <asm/io.h>
#include <linux/delay.h>
/* PHY register and bit definitions */
#define PHY_CTRL_COMMON0 0x078
#define SIDDQ BIT(2)
struct hsphy_init_seq {
int offset;
int val;
int delay;
};
struct hsphy_data {
const struct hsphy_init_seq *init_seq;
unsigned int init_seq_num;
};
struct hsphy_priv {
void __iomem *base;
struct clk_bulk clks;
struct reset_ctl phy_rst;
struct reset_ctl por_rst;
const struct hsphy_data *data;
};
static int hsphy_power_on(struct phy *phy)
{
struct hsphy_priv *priv = dev_get_priv(phy->dev);
u32 val;
val = readb(priv->base + PHY_CTRL_COMMON0);
val &= ~SIDDQ;
writeb(val, priv->base + PHY_CTRL_COMMON0);
return 0;
}
static int hsphy_power_off(struct phy *phy)
{
struct hsphy_priv *priv = dev_get_priv(phy->dev);
u32 val;
val = readb(priv->base + PHY_CTRL_COMMON0);
val |= SIDDQ;
writeb(val, priv->base + PHY_CTRL_COMMON0);
return 0;
}
static int hsphy_reset(struct hsphy_priv *priv)
{
int ret;
ret = reset_assert(&priv->phy_rst);
if (ret)
return ret;
udelay(10);
ret = reset_deassert(&priv->phy_rst);
if (ret)
return ret;
udelay(80);
return 0;
}
static void hsphy_init_sequence(struct hsphy_priv *priv)
{
const struct hsphy_data *data = priv->data;
const struct hsphy_init_seq *seq;
int i;
/* Device match data is optional. */
if (!data)
return;
seq = data->init_seq;
for (i = 0; i < data->init_seq_num; i++, seq++) {
writeb(seq->val, priv->base + seq->offset);
if (seq->delay)
udelay(seq->delay);
}
}
static int hsphy_por_reset(struct hsphy_priv *priv)
{
int ret;
u32 val;
ret = reset_assert(&priv->por_rst);
if (ret)
return ret;
/*
* The Femto PHY is POR reset in the following scenarios.
*
* 1. After overriding the parameter registers.
* 2. Low power mode exit from PHY retention.
*
* Ensure that SIDDQ is cleared before bringing the PHY
* out of reset.
*/
val = readb(priv->base + PHY_CTRL_COMMON0);
val &= ~SIDDQ;
writeb(val, priv->base + PHY_CTRL_COMMON0);
/*
* As per databook, 10 usec delay is required between
* PHY POR assert and de-assert.
*/
udelay(10);
ret = reset_deassert(&priv->por_rst);
if (ret)
return ret;
/*
* As per databook, it takes 75 usec for PHY to stabilize
* after the reset.
*/
udelay(80);
return 0;
}
static int hsphy_clk_init(struct udevice *dev, struct hsphy_priv *priv)
{
int ret;
ret = clk_get_bulk(dev, &priv->clks);
if (ret == -ENOSYS || ret == -ENOENT)
return 0;
if (ret)
return ret;
ret = clk_enable_bulk(&priv->clks);
if (ret) {
clk_release_bulk(&priv->clks);
return ret;
}
return 0;
}
static int hsphy_init(struct phy *phy)
{
struct hsphy_priv *priv = dev_get_priv(phy->dev);
int ret;
ret = hsphy_clk_init(phy->dev, priv);
if (ret)
return ret;
ret = hsphy_reset(priv);
if (ret)
return ret;
hsphy_init_sequence(priv);
hsphy_por_reset(priv);
if (ret)
return ret;
return 0;
}
static int hsphy_probe(struct udevice *dev)
{
struct hsphy_priv *priv = dev_get_priv(dev);
int ret;
priv->base = (void *)dev_read_addr(dev);
if ((ulong)priv->base == FDT_ADDR_T_NONE)
return -EINVAL;
ret = reset_get_by_name(dev, "phy", &priv->phy_rst);
if (ret)
return ret;
ret = reset_get_by_name(dev, "por", &priv->por_rst);
if (ret)
return ret;
priv->data = (const struct hsphy_data *)dev_get_driver_data(dev);
return 0;
}
static struct phy_ops hsphy_ops = {
.power_on = hsphy_power_on,
.power_off = hsphy_power_off,
.init = hsphy_init,
};
/*
* The macro is used to define an initialization sequence. Each tuple
* is meant to program 'value' into phy register at 'offset' with 'delay'
* in us followed.
*/
#define HSPHY_INIT_CFG(o, v, d) { .offset = o, .val = v, .delay = d, }
static const struct hsphy_init_seq init_seq_femtophy[] = {
HSPHY_INIT_CFG(0xc0, 0x01, 0),
HSPHY_INIT_CFG(0xe8, 0x0d, 0),
HSPHY_INIT_CFG(0x74, 0x12, 0),
HSPHY_INIT_CFG(0x98, 0x63, 0),
HSPHY_INIT_CFG(0x9c, 0x03, 0),
HSPHY_INIT_CFG(0xa0, 0x1d, 0),
HSPHY_INIT_CFG(0xa4, 0x03, 0),
HSPHY_INIT_CFG(0x8c, 0x23, 0),
HSPHY_INIT_CFG(0x78, 0x08, 0),
HSPHY_INIT_CFG(0x7c, 0xdc, 0),
HSPHY_INIT_CFG(0x90, 0xe0, 20),
HSPHY_INIT_CFG(0x74, 0x10, 0),
HSPHY_INIT_CFG(0x90, 0x60, 0),
};
static const struct hsphy_data data_femtophy = {
.init_seq = init_seq_femtophy,
.init_seq_num = ARRAY_SIZE(init_seq_femtophy),
};
static const struct udevice_id hsphy_ids[] = {
{ .compatible = "qcom,usb-hs-28nm-femtophy", .data = (ulong)&data_femtophy },
{ }
};
U_BOOT_DRIVER(qcom_usb_hs_28nm) = {
.name = "qcom-usb-hs-28nm",
.id = UCLASS_PHY,
.of_match = hsphy_ids,
.ops = &hsphy_ops,
.probe = hsphy_probe,
.priv_auto = sizeof(struct hsphy_priv),
};

View File

@@ -0,0 +1,154 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2022 Sumit Garg <sumit.garg@linaro.org>
*
* Based on Linux driver
*/
#include <common.h>
#include <dm.h>
#include <generic-phy.h>
#include <linux/bitops.h>
#include <asm/io.h>
#include <reset.h>
#include <clk.h>
#include <linux/delay.h>
#define PHY_CTRL0 0x6C
#define PHY_CTRL1 0x70
#define PHY_CTRL2 0x74
#define PHY_CTRL4 0x7C
/* PHY_CTRL bits */
#define REF_PHY_EN BIT(0)
#define LANE0_PWR_ON BIT(2)
#define SWI_PCS_CLK_SEL BIT(4)
#define TST_PWR_DOWN BIT(4)
#define PHY_RESET BIT(7)
struct ssphy_priv {
void __iomem *base;
struct clk_bulk clks;
struct reset_ctl com_rst;
struct reset_ctl phy_rst;
};
static inline void ssphy_updatel(void __iomem *addr, u32 mask, u32 val)
{
writel((readl(addr) & ~mask) | val, addr);
}
static int ssphy_do_reset(struct ssphy_priv *priv)
{
int ret;
ret = reset_assert(&priv->com_rst);
if (ret)
return ret;
ret = reset_assert(&priv->phy_rst);
if (ret)
return ret;
udelay(10);
ret = reset_deassert(&priv->com_rst);
if (ret)
return ret;
ret = reset_deassert(&priv->phy_rst);
if (ret)
return ret;
return 0;
}
static int ssphy_power_on(struct phy *phy)
{
struct ssphy_priv *priv = dev_get_priv(phy->dev);
int ret;
ret = ssphy_do_reset(priv);
if (ret)
return ret;
writeb(SWI_PCS_CLK_SEL, priv->base + PHY_CTRL0);
ssphy_updatel(priv->base + PHY_CTRL4, LANE0_PWR_ON, LANE0_PWR_ON);
ssphy_updatel(priv->base + PHY_CTRL2, REF_PHY_EN, REF_PHY_EN);
ssphy_updatel(priv->base + PHY_CTRL4, TST_PWR_DOWN, 0);
return 0;
}
static int ssphy_power_off(struct phy *phy)
{
struct ssphy_priv *priv = dev_get_priv(phy->dev);
ssphy_updatel(priv->base + PHY_CTRL4, LANE0_PWR_ON, 0);
ssphy_updatel(priv->base + PHY_CTRL2, REF_PHY_EN, 0);
ssphy_updatel(priv->base + PHY_CTRL4, TST_PWR_DOWN, TST_PWR_DOWN);
return 0;
}
static int ssphy_clk_init(struct udevice *dev, struct ssphy_priv *priv)
{
int ret;
ret = clk_get_bulk(dev, &priv->clks);
if (ret == -ENOSYS || ret == -ENOENT)
return 0;
if (ret)
return ret;
ret = clk_enable_bulk(&priv->clks);
if (ret) {
clk_release_bulk(&priv->clks);
return ret;
}
return 0;
}
static int ssphy_probe(struct udevice *dev)
{
struct ssphy_priv *priv = dev_get_priv(dev);
int ret;
priv->base = (void *)dev_read_addr(dev);
if ((ulong)priv->base == FDT_ADDR_T_NONE)
return -EINVAL;
ret = ssphy_clk_init(dev, priv);
if (ret)
return ret;
ret = reset_get_by_name(dev, "com", &priv->com_rst);
if (ret)
return ret;
ret = reset_get_by_name(dev, "phy", &priv->phy_rst);
if (ret)
return ret;
return 0;
}
static struct phy_ops ssphy_ops = {
.power_on = ssphy_power_on,
.power_off = ssphy_power_off,
};
static const struct udevice_id ssphy_ids[] = {
{ .compatible = "qcom,usb-ss-28nm-phy" },
{ }
};
U_BOOT_DRIVER(qcom_usb_ss) = {
.name = "qcom-usb-ss",
.id = UCLASS_PHY,
.of_match = ssphy_ids,
.ops = &ssphy_ops,
.probe = ssphy_probe,
.priv_auto = sizeof(struct ssphy_priv),
};

View File

@@ -216,10 +216,10 @@ config PMIC_MAX8997
- MUIC
- Others
config PMIC_PM8916
bool "Enable Driver Model for Qualcomm PM8916 PMIC"
config PMIC_QCOM
bool "Enable Driver Model for Qualcomm generic PMIC"
---help---
The PM8916 is a PMIC connected to one (or several) processors
The Qcom PMIC is connected to one (or several) processors
with SPMI bus. It has 2 slaves with several peripherals:
- 18x LDO
- 4x GPIO
@@ -229,7 +229,7 @@ config PMIC_PM8916
- Vibrator drivers
- Others
Driver binding info: doc/device-tree-bindings/pmic/pm8916.txt
Driver binding info: doc/device-tree-bindings/pmic/qcom,spmi-pmic.txt
config PMIC_RK8XX
bool "Enable support for Rockchip PMIC RK8XX"

View File

@@ -20,7 +20,7 @@ obj-$(CONFIG_PMIC_ACT8846) += act8846.o
obj-$(CONFIG_PMIC_AS3722) += as3722.o as3722_gpio.o
obj-$(CONFIG_$(SPL_)PMIC_AXP) += axp.o
obj-$(CONFIG_PMIC_MAX8997) += max8997.o
obj-$(CONFIG_PMIC_PM8916) += pm8916.o
obj-$(CONFIG_PMIC_QCOM) += pmic_qcom.o
obj-$(CONFIG_$(SPL_TPL_)PMIC_RK8XX) += rk8xx.o
obj-$(CONFIG_PMIC_RN5T567) += rn5t567.o
obj-$(CONFIG_PMIC_TPS65090) += tps65090.o

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Qualcomm pm8916 pmic driver
* Qualcomm generic pmic driver
*
* (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
*/
@@ -13,19 +13,19 @@
#define PID_MASK (0xFF << PID_SHIFT)
#define REG_MASK 0xFF
struct pm8916_priv {
struct pmic_qcom_priv {
uint32_t usid; /* Slave ID on SPMI bus */
};
static int pm8916_reg_count(struct udevice *dev)
static int pmic_qcom_reg_count(struct udevice *dev)
{
return 0xFFFF;
}
static int pm8916_write(struct udevice *dev, uint reg, const uint8_t *buff,
int len)
static int pmic_qcom_write(struct udevice *dev, uint reg, const uint8_t *buff,
int len)
{
struct pm8916_priv *priv = dev_get_priv(dev);
struct pmic_qcom_priv *priv = dev_get_priv(dev);
if (len != 1)
return -EINVAL;
@@ -35,9 +35,9 @@ static int pm8916_write(struct udevice *dev, uint reg, const uint8_t *buff,
*buff);
}
static int pm8916_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
static int pmic_qcom_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
{
struct pm8916_priv *priv = dev_get_priv(dev);
struct pmic_qcom_priv *priv = dev_get_priv(dev);
int val;
if (len != 1)
@@ -52,20 +52,20 @@ static int pm8916_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
return 0;
}
static struct dm_pmic_ops pm8916_ops = {
.reg_count = pm8916_reg_count,
.read = pm8916_read,
.write = pm8916_write,
static struct dm_pmic_ops pmic_qcom_ops = {
.reg_count = pmic_qcom_reg_count,
.read = pmic_qcom_read,
.write = pmic_qcom_write,
};
static const struct udevice_id pm8916_ids[] = {
static const struct udevice_id pmic_qcom_ids[] = {
{ .compatible = "qcom,spmi-pmic" },
{ }
};
static int pm8916_probe(struct udevice *dev)
static int pmic_qcom_probe(struct udevice *dev)
{
struct pm8916_priv *priv = dev_get_priv(dev);
struct pmic_qcom_priv *priv = dev_get_priv(dev);
priv->usid = dev_read_addr(dev);
@@ -75,12 +75,12 @@ static int pm8916_probe(struct udevice *dev)
return 0;
}
U_BOOT_DRIVER(pmic_pm8916) = {
.name = "pmic_pm8916",
U_BOOT_DRIVER(pmic_qcom) = {
.name = "pmic_qcom",
.id = UCLASS_PMIC,
.of_match = pm8916_ids,
.of_match = pmic_qcom_ids,
.bind = dm_scan_fdt_dev,
.probe = pm8916_probe,
.ops = &pm8916_ops,
.priv_auto = sizeof(struct pm8916_priv),
.probe = pmic_qcom_probe,
.ops = &pmic_qcom_ops,
.priv_auto = sizeof(struct pmic_qcom_priv),
};

View File

@@ -156,13 +156,12 @@ config RESET_IMX7
help
Support for reset controller on i.MX7/8 SoCs.
config RESET_IPQ419
bool "Reset driver for Qualcomm IPQ40xx SoCs"
depends on DM_RESET && ARCH_IPQ40XX
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
IPQ40xx SoCs.
Support for reset controller on Qualcomm SoCs.
config RESET_SIFIVE
bool "Reset Driver for SiFive SoC's"

View File

@@ -24,7 +24,7 @@ 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_IPQ419) += reset-ipq4019.o
obj-$(CONFIG_RESET_QCOM) += reset-qcom.o
obj-$(CONFIG_RESET_SIFIVE) += reset-sifive.o
obj-$(CONFIG_RESET_SYSCON) += reset-syscon.o
obj-$(CONFIG_RESET_RASPBERRYPI) += reset-raspberrypi.o

View File

@@ -1,8 +1,10 @@
// SPDX-License-Identifier: GPL-2.0
/*
* 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
*/
@@ -10,12 +12,11 @@
#include <asm/io.h>
#include <common.h>
#include <dm.h>
#include <dt-bindings/reset/qcom,ipq4019-reset.h>
#include <reset-uclass.h>
#include <linux/bitops.h>
#include <malloc.h>
struct ipq4019_reset_priv {
struct qcom_reset_priv {
phys_addr_t base;
};
@@ -24,7 +25,9 @@ struct qcom_reset_map {
u8 bit;
};
static const struct qcom_reset_map gcc_ipq4019_resets[] = {
#ifdef CONFIG_ARCH_IPQ40XX
#include <dt-bindings/reset/qcom,ipq4019-reset.h>
static const struct qcom_reset_map gcc_qcom_resets[] = {
[WIFI0_CPU_INIT_RESET] = { 0x1f008, 5 },
[WIFI0_RADIO_SRIF_RESET] = { 0x1f008, 4 },
[WIFI0_RADIO_WARM_RESET] = { 0x1f008, 3 },
@@ -97,11 +100,41 @@ static const struct qcom_reset_map gcc_ipq4019_resets[] = {
[GCC_MPM_BCR] = {0x24000, 0},
[GCC_SPDM_BCR] = {0x25000, 0},
};
#endif
static int ipq4019_reset_assert(struct reset_ctl *rst)
#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 ipq4019_reset_priv *priv = dev_get_priv(rst->dev);
const struct qcom_reset_map *reset_map = gcc_ipq4019_resets;
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;
@@ -114,10 +147,10 @@ static int ipq4019_reset_assert(struct reset_ctl *rst)
return 0;
}
static int ipq4019_reset_deassert(struct reset_ctl *rst)
static int qcom_reset_deassert(struct reset_ctl *rst)
{
struct ipq4019_reset_priv *priv = dev_get_priv(rst->dev);
const struct qcom_reset_map *reset_map = gcc_ipq4019_resets;
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;
@@ -130,19 +163,20 @@ static int ipq4019_reset_deassert(struct reset_ctl *rst)
return 0;
}
static const struct reset_ops ipq4019_reset_ops = {
.rst_assert = ipq4019_reset_assert,
.rst_deassert = ipq4019_reset_deassert,
static const struct reset_ops qcom_reset_ops = {
.rst_assert = qcom_reset_assert,
.rst_deassert = qcom_reset_deassert,
};
static const struct udevice_id ipq4019_reset_ids[] = {
static const struct udevice_id qcom_reset_ids[] = {
{ .compatible = "qcom,gcc-reset-ipq4019" },
{ .compatible = "qcom,gcc-reset-qcs404" },
{ }
};
static int ipq4019_reset_probe(struct udevice *dev)
static int qcom_reset_probe(struct udevice *dev)
{
struct ipq4019_reset_priv *priv = dev_get_priv(dev);
struct qcom_reset_priv *priv = dev_get_priv(dev);
priv->base = dev_read_addr(dev);
if (priv->base == FDT_ADDR_T_NONE)
@@ -151,11 +185,11 @@ static int ipq4019_reset_probe(struct udevice *dev)
return 0;
}
U_BOOT_DRIVER(ipq4019_reset) = {
.name = "ipq4019_reset",
U_BOOT_DRIVER(qcom_reset) = {
.name = "qcom_reset",
.id = UCLASS_RESET,
.of_match = ipq4019_reset_ids,
.ops = &ipq4019_reset_ops,
.probe = ipq4019_reset_probe,
.priv_auto = sizeof(struct ipq4019_reset_priv),
.of_match = qcom_reset_ids,
.ops = &qcom_reset_ops,
.probe = qcom_reset_probe,
.priv_auto = sizeof(struct qcom_reset_priv),
};