mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-25 06:46:00 +00:00
Qualcomm changes for v2025.07
-----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEtlGhRjxqvtBpDFXNBYMxKxlfZLYFAmf5HL8ACgkQBYMxKxlf ZLaY6A//Ry5wkX1f/WTVFUO6gBJQom6hsEpkNgYwtgzaWOWhqvR53e5sbsiMPKnO 5BRtKhrs0Jp2/kl06+k5tsGQbr3rogvwNS9m8DFyF2Hfq7uT2ooQKzxeBM9MaGhI p+7d92JjcHeYP7ejWcoAnag0ZvM/3iofdsrRcGsFjbYbcbAkBtAUDj2RqaZFIAFk A6g6/IZ62K6QH24oAMPv5yR4ru2tfzRMJHdZh79FHMXNp9wOLgMsHAV8NToQ/ZHU ACn9EHc4g9aI8h8gXPTEjCzOx6saYcmV+zzn0mSeICCSbOqvJ/C2/96NUlD5BW8/ XFIeuBNgnHyxv4O3idFpyaxF34SMp2j2dDAIQFLN+0lG1M1Zi75pqf9UzlSvvSjm d1xd/LbrOEwNEyTKG7Ss0e3nf03lP22s2COpFUPJAijkfRZ8K/Y8RISeQv+MJKwa AZqYofLua0Uo0kuKTiHuOdD5oWUxmEcjtisaP/X9hcXWteTillntp120qm/a93s2 X015V56B/e2+uf9xAQW+iqnrcgpMGKffqbs7tVhVr3SDTDa+c4/c6EXX2naqzgDQ T/S0hetOONuNXZvyAguUq5HKNI0IoC+OZQhA1uIgq+JyV/7qgENyrERlt29435cg NAr+410m0OKYUGHz5xwLSUh2j68v/4fZj7I4nZt4eYjEfYk/2dI= =Ep2x -----END PGP SIGNATURE----- Merge tag 'qcom-for-2025.07' of https://source.denx.de/u-boot/custodians/u-boot-snapdragon Qualcomm changes for v2025.07: CI: https://source.denx.de/u-boot/custodians/u-boot-snapdragon/-/pipelines/25653 There's been a surprising amount of activity lately on the Qualcomm side with the two oldest boards getting some fresh attention and a lot of cleanup and polish going on across the board. * SDM660 gets USB phy fixes and a pinctrl driver * The recently added SA8775P/QCS9100 SoC gets a pinctrl driver * The Qualcomm pinctrl driver now handles reserved pins correctly, fixing crashes on some boards when running "gpio status -a" * OF_UPSTREAM_BUILD_VENDOR is enabled in qcom_defconfig * SDM845 and SC7280 get missing clocks added (since we're now stricter about those). This gets USB working more reliably in more cases. * DM_USB_GADGET is enabled for all boards using DWC3 and fasbtoot is enabled too * A bug in the livetree fixup code is fixed (making USB work on a lot more platforms) * Button label lookup is made case insensitive* bootretry becomes more dynamic, allowing it to be hijacked to make a "persistent" boot menu that allows dropping to U-Boot shell later on * A new qcom-phone.config fragment is added along with a phone-specific default environment and phone-specific debugging/bringup docs. These make U-Boot more usable on devices without a serial port or keyboard. * The db820c gets fixed up and updated documentation * The db410c also gets some love and modernisation as well as a new reviewer. * A new driver is added for the USB VBUS regulator found on various Qualcomm PMICs * The Qualcomm SPMI driver gets some fixes and cleanup for SPMI v5 and v7 support.
This commit is contained in:
commit
ff0b7d741d
41 changed files with 1598 additions and 164 deletions
|
@ -1120,12 +1120,13 @@ config ARCH_SNAPDRAGON
|
||||||
select SPMI
|
select SPMI
|
||||||
select BOARD_LATE_INIT
|
select BOARD_LATE_INIT
|
||||||
select OF_BOARD
|
select OF_BOARD
|
||||||
select SAVE_PREV_BL_FDT_ADDR
|
select SAVE_PREV_BL_FDT_ADDR if !ENABLE_ARM_SOC_BOOT0_HOOK
|
||||||
select LINUX_KERNEL_IMAGE_HEADER if !ENABLE_ARM_SOC_BOOT0_HOOK
|
select LINUX_KERNEL_IMAGE_HEADER if !ENABLE_ARM_SOC_BOOT0_HOOK
|
||||||
select SYSRESET
|
select SYSRESET
|
||||||
select SYSRESET_PSCI
|
select SYSRESET_PSCI
|
||||||
imply OF_UPSTREAM
|
imply OF_UPSTREAM
|
||||||
imply CMD_DM
|
imply CMD_DM
|
||||||
|
imply DM_USB_GADGET
|
||||||
|
|
||||||
config ARCH_SOCFPGA
|
config ARCH_SOCFPGA
|
||||||
bool "Altera SOCFPGA family"
|
bool "Altera SOCFPGA family"
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
/ {
|
/ {
|
||||||
/* When running as a first-stage bootloader this isn't filled in automatically */
|
/* When running as a first-stage bootloader this isn't filled in automatically */
|
||||||
memory@80000000 {
|
memory@80000000 {
|
||||||
reg = <0 0x80000000 0 0x3da00000>;
|
reg = <0 0x80000000 0 0x40000000>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -46,4 +46,19 @@ static inline bool qcom_is_special_pin(const struct msm_pin_data *pindata, unsig
|
||||||
return pindata->special_pins_start && pin >= pindata->special_pins_start;
|
return pindata->special_pins_start && pin >= pindata->special_pins_start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct udevice;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* msm_pinctrl_is_reserved() - Check if a pin lies in a reserved range
|
||||||
|
*
|
||||||
|
* @dev: pinctrl device
|
||||||
|
* @pin: Pin number
|
||||||
|
*
|
||||||
|
* Returns: true if pin is reserved, otherwise false
|
||||||
|
*
|
||||||
|
* Call using dev_get_parent() from the GPIO device, it is a child of
|
||||||
|
* the pinctrl device.
|
||||||
|
*/
|
||||||
|
bool msm_pinctrl_is_reserved(struct udevice *dev, unsigned int pin);
|
||||||
|
|
||||||
#endif /* _QCOM_GPIO_H_ */
|
#endif /* _QCOM_GPIO_H_ */
|
||||||
|
|
|
@ -86,13 +86,13 @@ static int fixup_qcom_dwc3(struct device_node *glue_np)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Overwrite "phy-names" to only contain a single entry */
|
/* Overwrite "phy-names" to only contain a single entry */
|
||||||
ret = of_write_prop(dwc3, "phy-names", strlen("usb2-phy"), "usb2-phy");
|
ret = of_write_prop(dwc3, "phy-names", strlen("usb2-phy") + 1, "usb2-phy");
|
||||||
if (ret) {
|
if (ret) {
|
||||||
log_err("Failed to overwrite 'phy-names' property: %d\n", ret);
|
log_err("Failed to overwrite 'phy-names' property: %d\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = of_write_prop(dwc3, "maximum-speed", strlen("high-speed"), "high-speed");
|
ret = of_write_prop(dwc3, "maximum-speed", strlen("high-speed") + 1, "high-speed");
|
||||||
if (ret) {
|
if (ret) {
|
||||||
log_err("Failed to set 'maximum-speed' property: %d\n", ret);
|
log_err("Failed to set 'maximum-speed' property: %d\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -161,14 +161,14 @@ int ft_board_setup(void *blob, struct bd_info __maybe_unused *bd)
|
||||||
struct fdt_header *fdt = blob;
|
struct fdt_header *fdt = blob;
|
||||||
int node;
|
int node;
|
||||||
|
|
||||||
/* We only want to do this fix-up for the RB1 board, quick return for all others */
|
/* On RB1/2 we need to fix-up the dr_mode */
|
||||||
if (!fdt_node_check_compatible(fdt, 0, "qcom,qrb4210-rb2"))
|
if (!fdt_node_check_compatible(fdt, 0, "qcom,qrb4210-rb2") ||
|
||||||
return 0;
|
!fdt_node_check_compatible(fdt, 0, "qcom,qrb2210-rb1")) {
|
||||||
|
fdt_for_each_node_by_compatible(node, blob, 0, "snps,dwc3") {
|
||||||
fdt_for_each_node_by_compatible(node, blob, 0, "snps,dwc3") {
|
log_debug("%s: Setting 'dr_mode' to OTG\n", fdt_get_name(blob, node, NULL));
|
||||||
log_debug("%s: Setting 'dr_mode' to OTG\n", fdt_get_name(blob, node, NULL));
|
fdt_setprop_string(fdt, node, "dr_mode", "otg");
|
||||||
fdt_setprop_string(fdt, node, "dr_mode", "otg");
|
break;
|
||||||
break;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
DRAGONBOARD410C BOARD
|
DRAGONBOARD410C BOARD
|
||||||
M: Ramon Fried <rfried.dev@gmail.com>
|
M: Stephan Gerhold <stephan@gerhold.net>
|
||||||
|
R: Sam Day <me@samcday.com>
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: board/qualcomm/dragonboard410c/
|
F: board/qualcomm/dragonboard410c/
|
||||||
F: include/configs/dragonboard410c.h
|
F: include/configs/dragonboard410c.h
|
||||||
|
|
|
@ -22,21 +22,6 @@
|
||||||
|
|
||||||
DECLARE_GLOBAL_DATA_PTR;
|
DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
|
||||||
/* UNSTUFF_BITS macro taken from Linux Kernel: drivers/mmc/core/sd.c */
|
|
||||||
#define UNSTUFF_BITS(resp, start, size) \
|
|
||||||
({ \
|
|
||||||
const int __size = size; \
|
|
||||||
const u32 __mask = (__size < 32 ? 1 << __size : 0) - 1; \
|
|
||||||
const int __off = 3 - ((start) / 32); \
|
|
||||||
const int __shft = (start) & 31; \
|
|
||||||
u32 __res; \
|
|
||||||
\
|
|
||||||
__res = resp[__off] >> __shft; \
|
|
||||||
if (__size + __shft > 32) \
|
|
||||||
__res |= resp[__off - 1] << ((32 - __shft) % 32); \
|
|
||||||
__res & __mask; \
|
|
||||||
})
|
|
||||||
|
|
||||||
static u32 msm_board_serial(void)
|
static u32 msm_board_serial(void)
|
||||||
{
|
{
|
||||||
struct mmc *mmc_dev;
|
struct mmc *mmc_dev;
|
||||||
|
@ -48,7 +33,8 @@ static u32 msm_board_serial(void)
|
||||||
if (mmc_init(mmc_dev))
|
if (mmc_init(mmc_dev))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return UNSTUFF_BITS(mmc_dev->cid, 16, 32);
|
/* MMC serial number */
|
||||||
|
return mmc_dev->cid[2] << 16 | mmc_dev->cid[3] >> 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void msm_generate_mac_addr(u8 *mac)
|
static void msm_generate_mac_addr(u8 *mac)
|
||||||
|
@ -65,28 +51,6 @@ static void msm_generate_mac_addr(u8 *mac)
|
||||||
put_unaligned_be32(msm_board_serial(), &mac[2]);
|
put_unaligned_be32(msm_board_serial(), &mac[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for vol- button - if pressed - stop autoboot */
|
|
||||||
int misc_init_r(void)
|
|
||||||
{
|
|
||||||
struct udevice *btn;
|
|
||||||
int ret;
|
|
||||||
enum button_state_t state;
|
|
||||||
|
|
||||||
ret = button_get_by_label("vol_down", &btn);
|
|
||||||
if (ret < 0) {
|
|
||||||
printf("Couldn't find power button!\n");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
state = button_get_state(btn);
|
|
||||||
if (state == BUTTON_ON) {
|
|
||||||
env_set("preboot", "setenv preboot; fastboot 0");
|
|
||||||
printf("vol_down pressed - Starting fastboot.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int qcom_late_init(void)
|
int qcom_late_init(void)
|
||||||
{
|
{
|
||||||
char serial[16];
|
char serial[16];
|
||||||
|
@ -97,9 +61,9 @@ int qcom_late_init(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fixup of DTB for Linux Kernel
|
/*
|
||||||
* 1. Fixup installed DRAM.
|
* Fixup of DTB for Linux Kernel
|
||||||
* 2. Fixup WLAN/BT Mac address:
|
* 1. Fixup WLAN/BT Mac address:
|
||||||
* First, check if MAC addresses for WLAN/BT exists as environemnt
|
* First, check if MAC addresses for WLAN/BT exists as environemnt
|
||||||
* variables wlanaddr,btaddr. if not, generate a unique address.
|
* variables wlanaddr,btaddr. if not, generate a unique address.
|
||||||
*/
|
*/
|
||||||
|
@ -107,6 +71,7 @@ int qcom_late_init(void)
|
||||||
int ft_board_setup(void *blob, struct bd_info *bd)
|
int ft_board_setup(void *blob, struct bd_info *bd)
|
||||||
{
|
{
|
||||||
u8 mac[ARP_HLEN];
|
u8 mac[ARP_HLEN];
|
||||||
|
int i;
|
||||||
|
|
||||||
if (!eth_env_get_enetaddr("wlanaddr", mac)) {
|
if (!eth_env_get_enetaddr("wlanaddr", mac)) {
|
||||||
msm_generate_mac_addr(mac);
|
msm_generate_mac_addr(mac);
|
||||||
|
@ -118,12 +83,24 @@ int ft_board_setup(void *blob, struct bd_info *bd)
|
||||||
if (!eth_env_get_enetaddr("btaddr", mac)) {
|
if (!eth_env_get_enetaddr("btaddr", mac)) {
|
||||||
msm_generate_mac_addr(mac);
|
msm_generate_mac_addr(mac);
|
||||||
|
|
||||||
/* The BD address is same as WLAN MAC address but with
|
/*
|
||||||
* least significant bit flipped.
|
* The BD address is same as WLAN MAC address but with
|
||||||
*/
|
* least significant bit flipped.
|
||||||
mac[0] ^= 0x01;
|
*/
|
||||||
|
mac[ARP_HLEN - 1] ^= 0x01;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reverse array since local-bd-address is formatted with least
|
||||||
|
* significant byte first (little endian).
|
||||||
|
*/
|
||||||
|
for (i = 0; i < ARP_HLEN / 2; ++i) {
|
||||||
|
u8 tmp = mac[i];
|
||||||
|
|
||||||
|
mac[i] = mac[ARP_HLEN - 1 - i];
|
||||||
|
mac[ARP_HLEN - 1 - i] = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
do_fixup_by_compat(blob, "qcom,wcnss-bt",
|
do_fixup_by_compat(blob, "qcom,wcnss-bt",
|
||||||
"local-bd-address", mac, ARP_HLEN, 1);
|
"local-bd-address", mac, ARP_HLEN, 1);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -1,36 +1,6 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||||
|
|
||||||
/* Does what recovery does */
|
|
||||||
#define REFLASH(file, partnum) \
|
|
||||||
part start mmc 0 partnum start && \
|
|
||||||
part size mmc 0 partnum size && \
|
|
||||||
tftp $loadaddr file && \
|
|
||||||
mmc write $loadaddr $start $size &&
|
|
||||||
|
|
||||||
reflash=
|
|
||||||
mmc dev 0 &&
|
|
||||||
usb start &&
|
|
||||||
dhcp &&
|
|
||||||
tftp $loadaddr dragonboard/rescue/gpt_both0.bin &&
|
|
||||||
mmc write $loadaddr 0 43 &&
|
|
||||||
mmc rescan &&
|
|
||||||
REFLASH(dragonboard/rescue/NON-HLOS.bin, 1)
|
|
||||||
REFLASH(dragonboard/rescue/sbl1.mbn, 2)
|
|
||||||
REFLASH(dragonboard/rescue/rpm.mbn, 3)
|
|
||||||
REFLASH(dragonboard/rescue/tz.mbn, 4)
|
|
||||||
REFLASH(dragonboard/rescue/hyp.mbn, 5)
|
|
||||||
REFLASH(dragonboard/rescue/sec.dat, 6)
|
|
||||||
REFLASH(dragonboard/rescue/emmc_appsboot.mbn, 7)
|
|
||||||
REFLASH(dragonboard/u-boot.img, 8)
|
|
||||||
usb stop &&
|
|
||||||
echo Reflash completed
|
|
||||||
|
|
||||||
loadaddr=0x81000000
|
|
||||||
initrd_high=0xffffffffffffffff
|
initrd_high=0xffffffffffffffff
|
||||||
linux_image=Image
|
fastboot=fastboot -l $fastboot_addr_r usb 0
|
||||||
kernel_addr_r=0x81000000
|
boot_targets=usb mmc1 mmc0 pxe
|
||||||
fdtfile=qcom/apq8016-sbc.dtb
|
button_cmd_0_name=vol_down
|
||||||
fdt_addr_r=0x83000000
|
button_cmd_0=run fastboot
|
||||||
ramdisk_addr_r=0x84000000
|
|
||||||
scriptaddr=0x90000000
|
|
||||||
pxefile_addr_r=0x90100000
|
|
||||||
|
|
|
@ -106,7 +106,7 @@ int misc_init_r(void)
|
||||||
int ret;
|
int ret;
|
||||||
enum button_state_t state;
|
enum button_state_t state;
|
||||||
|
|
||||||
ret = button_get_by_label("pwrkey", &btn);
|
ret = button_get_by_label("Power Button", &btn);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
printf("Couldn't find power button!\n");
|
printf("Couldn't find power button!\n");
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -16,10 +16,7 @@
|
||||||
Build & Run instructions
|
Build & Run instructions
|
||||||
================================================================================
|
================================================================================
|
||||||
|
|
||||||
1) Install mkbootimg and dtbTool from Codeaurora:
|
1) Install mkbootimg
|
||||||
|
|
||||||
git://codeaurora.org/quic/kernel/skales
|
|
||||||
commit 8492547e404e969262d9070dee9bdd15668bb70f worked for me.
|
|
||||||
|
|
||||||
2) Setup CROSS_COMPILE to aarch64 compiler or if you use ccache just do
|
2) Setup CROSS_COMPILE to aarch64 compiler or if you use ccache just do
|
||||||
CROSS_COMPILE="ccache aarch64-linux-gnu-"
|
CROSS_COMPILE="ccache aarch64-linux-gnu-"
|
||||||
|
@ -33,15 +30,15 @@
|
||||||
|
|
||||||
$ touch rd
|
$ touch rd
|
||||||
|
|
||||||
5) Generate qualcomm device tree table with dtbTool
|
5) Append the dtb to the u-boot binary discarding the internal dtb.
|
||||||
|
|
||||||
$ dtbTool -o dt.img arch/arm/dts
|
$ gzip u-boot-nodtb.bin
|
||||||
|
$ cat u-boot.dtb >> u-boot-nodtb.bin.gz
|
||||||
|
|
||||||
6) Generate Android boot image with mkbootimg:
|
6) Generate Android boot image with mkbootimg:
|
||||||
|
|
||||||
$ mkbootimg --kernel=u-boot-dtb.bin \
|
$ mkbootimg --kernel=u-boot-nodtb.bin.gz \
|
||||||
--output=u-boot.img \
|
--output=u-boot.img \
|
||||||
--dt=dt.img \
|
|
||||||
--pagesize 4096 \
|
--pagesize 4096 \
|
||||||
--base 0x80000000 \
|
--base 0x80000000 \
|
||||||
--ramdisk=rd \
|
--ramdisk=rd \
|
||||||
|
@ -251,44 +248,42 @@ Wait for 5 seconds before proceeding
|
||||||
[5300] booting linux @ 0x80080000, ramdisk @ 0x82200000 (0), tags/device tree @ 0x82000000
|
[5300] booting linux @ 0x80080000, ramdisk @ 0x82200000 (0), tags/device tree @ 0x82000000
|
||||||
[5310] Jumping to kernel via monitor
|
[5310] Jumping to kernel via monitor
|
||||||
|
|
||||||
U-Boot 2017.11-00145-ge895117 (Nov 29 2017 - 10:04:06 +0100)
|
U-Boot 2025.04-rc5-00020-g40a61ca0e7eb-dirty (Apr 07 2025 - 09:37:03 +0200)
|
||||||
Qualcomm-DragonBoard 820C
|
Qualcomm-DragonBoard 820C
|
||||||
|
|
||||||
DRAM: 3 GiB
|
DRAM: 3.5 GiB (effective 3 GiB)
|
||||||
PSCI: v1.0
|
Core: 136 devices, 18 uclasses, devicetree: board
|
||||||
MMC: sdhci@74a4900: 0
|
MMC: Bulk clocks not available (-19), trying core clock
|
||||||
|
mmc@74a4900: 0
|
||||||
|
Loading Environment from EXT4... OK
|
||||||
In: serial@75b0000
|
In: serial@75b0000
|
||||||
Out: serial@75b0000
|
Out: serial@75b0000
|
||||||
Err: serial@75b0000
|
Err: serial@75b0000
|
||||||
Net: Net Initialization Skipped
|
Net: No ethernet found.
|
||||||
No ethernet found.
|
|
||||||
Hit any key to stop autoboot: 0
|
Hit any key to stop autoboot: 0
|
||||||
switch to partitions #0, OK
|
switch to partitions #0, OK
|
||||||
mmc0 is current device
|
mmc0 is current device
|
||||||
Scanning mmc 0:1...
|
Scanning mmc 0:1...
|
||||||
Found /extlinux/extlinux.conf
|
Found /extlinux/extlinux.conf
|
||||||
Retrieving file: /extlinux/extlinux.conf
|
Retrieving file: /extlinux/extlinux.conf
|
||||||
433 bytes read in 71 ms (5.9 KiB/s)
|
|
||||||
1: nfs root
|
1: nfs root
|
||||||
|
Enter choice: 1: nfs root
|
||||||
Retrieving file: /uImage
|
Retrieving file: /uImage
|
||||||
19397184 bytes read in 2024 ms (9.1 MiB/s)
|
append: root=/dev/nfs rw nfsroot=192.168.1.6:/home/jramirez/Src/qualcomm-lt/db820c/rootfs,v3,tcp rootwait ip=dhcp consoleblank=0 console=tty0 console=ttyMSM0,115200n8 earlyprintk earlyco0
|
||||||
append: root=/dev/nfs rw nfsroot=192.168.1.2:/db820c/rootfs,v3,tcp rootwait ip=dhcp consoleblank=0 console=tty0 console=ttyMSM0,115200n8 earlyprintk earlycon=msm_serial_dm,0x75b0000 androidboot.bootdevice=624000.ufshc androidboot.verifiedbootstate=orange androidboot.ver0
|
|
||||||
|
|
||||||
Retrieving file: /apq8096-db820c.dtb
|
Retrieving file: /apq8096-db820c.dtb
|
||||||
38134 bytes read in 37 ms (1005.9 KiB/s)
|
## Booting kernel from Legacy Image at 155000000 ...
|
||||||
|
|
||||||
## Booting kernel from Legacy Image at 95000000 ...
|
|
||||||
Image Name: Dragonboard820c
|
Image Name: Dragonboard820c
|
||||||
Image Type: AArch64 Linux Kernel Image (uncompressed)
|
Image Type: AArch64 Linux Kernel Image (uncompressed)
|
||||||
Data Size: 19397120 Bytes = 18.5 MiB
|
Data Size: 19397120 Bytes = 18.5 MiB
|
||||||
Load Address: 80080000
|
Load Address: 80080000
|
||||||
Entry Point: 80080000
|
Entry Point: 80080000
|
||||||
Verifying Checksum ... OK
|
Verifying Checksum ... OK
|
||||||
## Flattened Device Tree blob at 93000000
|
## Flattened Device Tree blob at 148600000
|
||||||
Booting using the fdt blob at 0x93000000
|
Booting using the fdt blob at 0x148600000
|
||||||
Loading Kernel Image ... OK
|
Working FDT set to 148600000
|
||||||
Using Device Tree in place at 0000000093000000, end 000000009300c4f5
|
Loading Kernel Image to 80080000
|
||||||
|
Using Device Tree in place at 0000000148600000, end 000000014860c4f5
|
||||||
|
Working FDT set to 148600000
|
||||||
|
|
||||||
Starting kernel ...
|
Starting kernel ...
|
||||||
|
|
||||||
|
|
29
board/qualcomm/qcom-phone.config
Normal file
29
board/qualcomm/qcom-phone.config
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
# Settings for phones
|
||||||
|
CONFIG_DEFAULT_ENV_FILE="board/qualcomm/qcom-phone.env"
|
||||||
|
# Hang on panic so the error message can be read
|
||||||
|
CONFIG_PANIC_HANG=y
|
||||||
|
# We use pause in various places to allow text to be read
|
||||||
|
# before it scrolls off the screen
|
||||||
|
CONFIG_CMD_PAUSE=y
|
||||||
|
CONFIG_BOOT_RETRY=y
|
||||||
|
CONFIG_BOOT_RETRY_TIME=1
|
||||||
|
CONFIG_BUTTON_REMAP_PHONE_KEYS=y
|
||||||
|
CONFIG_RETRY_BOOTCMD=y
|
||||||
|
CONFIG_FASTBOOT_BUF_ADDR=0x1A000000
|
||||||
|
CONFIG_USB_FUNCTION_FASTBOOT=y
|
||||||
|
CONFIG_USB_FUNCTION_ACM=y
|
||||||
|
CONFIG_CMD_UMS_ABORT_KEYED=y
|
||||||
|
|
||||||
|
# Record all console output and let it be dumped via fastboot
|
||||||
|
CONFIG_CONSOLE_RECORD=y
|
||||||
|
CONFIG_CONSOLE_RECORD_INIT_F=y
|
||||||
|
CONFIG_CONSOLE_RECORD_OUT_SIZE=0x6000
|
||||||
|
CONFIG_FASTBOOT_CMD_OEM_CONSOLE=y
|
||||||
|
|
||||||
|
# Only MMC is supported by fastboot currently, but this is still useful.
|
||||||
|
CONFIG_FASTBOOT_FLASH=y
|
||||||
|
CONFIG_FASTBOOT_FLASH_MMC_DEV=0
|
||||||
|
CONFIG_FASTBOOT_OEM_RUN=y
|
||||||
|
|
||||||
|
# Many phones don't actually define a serial port in their DTS
|
||||||
|
# CONFIG_REQUIRE_SERIAL_CONSOLE is not set
|
47
board/qualcomm/qcom-phone.env
Normal file
47
board/qualcomm/qcom-phone.env
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
bootdelay=0
|
||||||
|
bootretry=1
|
||||||
|
stdin=serial,button-kbd
|
||||||
|
stdout=serial,vidconsole
|
||||||
|
stderr=serial,vidconsole
|
||||||
|
|
||||||
|
# Fastboot is keen to use the address from kconfig, but we
|
||||||
|
# allocate its buffer at runtime.
|
||||||
|
fastboot=fastboot -l $fastboot_addr_r usb 0
|
||||||
|
|
||||||
|
# Always probe for UFS storage, though it should be done by board code.
|
||||||
|
preboot=scsi scan
|
||||||
|
|
||||||
|
# Shortcut to enable USB serial gadget and disable bootretry
|
||||||
|
serial_gadget=setenv stdin serial,button-kbd,usbacm; \
|
||||||
|
setenv stdout serial,vidconsole,usbacm; \
|
||||||
|
setenv stderr serial,vidconsole,usbacm; \
|
||||||
|
setenv bootretry -1; \
|
||||||
|
echo Enabled U-Boot console serial gadget
|
||||||
|
|
||||||
|
# bootretry will run this command over and over, if we fail once
|
||||||
|
# then bail out to the boot menu instead (with a pause to read
|
||||||
|
# the error message)
|
||||||
|
bootcmd=bootefi bootmgr; pause; run menucmd
|
||||||
|
|
||||||
|
# When entering the menu (either from button press or failed boot)
|
||||||
|
# remap bootcmd so it will re-open the menu and we won't get stuck
|
||||||
|
# at the console with no way to type
|
||||||
|
menucmd=setenv bootcmd run menucmd; bootmenu -1
|
||||||
|
|
||||||
|
# Pause is used so the output can be read on the display
|
||||||
|
bootmenu_0=Boot=bootefi bootmgr; pause
|
||||||
|
bootmenu_1=Enable serial console gadget=run serial_gadget
|
||||||
|
bootmenu_2=Enable USB mass storage=echo "Press any key to exit UMS mode"; ums 0 scsi 0
|
||||||
|
bootmenu_3=Enable fastboot mode=run fastboot
|
||||||
|
# Disabling bootretry means we'll just drop the shell
|
||||||
|
bootmenu_4=Drop to shell=setenv bootretry -1
|
||||||
|
bootmenu_5=Reset device=reset
|
||||||
|
bootmenu_6=Dump clocks=clk dump; pause
|
||||||
|
bootmenu_7=Dump environment=printenv; pause
|
||||||
|
bootmenu_8=Board info=bdinfo; pause
|
||||||
|
bootmenu_9=Dump bootargs=fdt print /chosen bootargs; pause
|
||||||
|
|
||||||
|
# Allow holding the volume down button while U-Boot loads to enter
|
||||||
|
# the boot menu
|
||||||
|
button_cmd_0_name=Volume Down
|
||||||
|
button_cmd_0=run menucmd
|
|
@ -1704,6 +1704,13 @@ config RESET_TO_RETRY
|
||||||
After the countdown timed out, the board will be reset to restart
|
After the countdown timed out, the board will be reset to restart
|
||||||
again.
|
again.
|
||||||
|
|
||||||
|
config RETRY_BOOTCMD
|
||||||
|
bool "Run bootcmd on retry"
|
||||||
|
depends on BOOT_RETRY && HUSH_PARSER && !RESET_TO_RETRY
|
||||||
|
help
|
||||||
|
If this option is enabled, the "bootcmd" will be run after the
|
||||||
|
countdown times out.
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
menu "Image support"
|
menu "Image support"
|
||||||
|
|
|
@ -37,6 +37,8 @@ void bootretry_init_cmd_timeout(void)
|
||||||
*/
|
*/
|
||||||
void bootretry_reset_cmd_timeout(void)
|
void bootretry_reset_cmd_timeout(void)
|
||||||
{
|
{
|
||||||
|
/* Parse changes to bootretry */
|
||||||
|
bootretry_init_cmd_timeout();
|
||||||
endtime = endtick(retry_time);
|
endtime = endtick(retry_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1028,8 +1028,10 @@ static void get_user_input(struct in_str *i)
|
||||||
puts("\nTimeout waiting for command\n");
|
puts("\nTimeout waiting for command\n");
|
||||||
# ifdef CONFIG_RESET_TO_RETRY
|
# ifdef CONFIG_RESET_TO_RETRY
|
||||||
do_reset(NULL, 0, 0, NULL);
|
do_reset(NULL, 0, 0, NULL);
|
||||||
# else
|
# elif IS_ENABLED(CONFIG_RETRY_BOOTCMD)
|
||||||
# error "This currently only works with CONFIG_RESET_TO_RETRY enabled"
|
strcpy(console_buffer, "run bootcmd\n");
|
||||||
|
# else
|
||||||
|
# error "This only works with CONFIG_RESET_TO_RETRY or CONFIG_BOOT_RETRY_COMMAND enabled"
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2907,8 +2907,10 @@ static void get_user_input(struct in_str *i)
|
||||||
puts("\nTimeout waiting for command\n");
|
puts("\nTimeout waiting for command\n");
|
||||||
# ifdef CONFIG_RESET_TO_RETRY
|
# ifdef CONFIG_RESET_TO_RETRY
|
||||||
do_reset(NULL, 0, 0, NULL);
|
do_reset(NULL, 0, 0, NULL);
|
||||||
# else
|
# elif IS_ENABLED(CONFIG_RETRY_BOOTCMD)
|
||||||
# error "This currently only works with CONFIG_RESET_TO_RETRY enabled"
|
strcpy(console_buffer, "run bootcmd\n");
|
||||||
|
# else
|
||||||
|
# error "This only works with CONFIG_RESET_TO_RETRY or CONFIG_BOOT_RETRY_COMMAND enabled"
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
CONFIG_ARM=y
|
CONFIG_ARM=y
|
||||||
CONFIG_SYS_BOARD="dragonboard410c"
|
CONFIG_SYS_BOARD="dragonboard410c"
|
||||||
CONFIG_COUNTER_FREQUENCY=19000000
|
CONFIG_COUNTER_FREQUENCY=19200000
|
||||||
CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK=y
|
CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK=y
|
||||||
CONFIG_ARCH_SNAPDRAGON=y
|
CONFIG_ARCH_SNAPDRAGON=y
|
||||||
CONFIG_TEXT_BASE=0x8f600000
|
CONFIG_TEXT_BASE=0x8f600000
|
||||||
|
@ -14,18 +14,16 @@ CONFIG_OF_LIBFDT_OVERLAY=y
|
||||||
CONFIG_SYS_LOAD_ADDR=0x80080000
|
CONFIG_SYS_LOAD_ADDR=0x80080000
|
||||||
CONFIG_IDENT_STRING="\nQualcomm-DragonBoard 410C"
|
CONFIG_IDENT_STRING="\nQualcomm-DragonBoard 410C"
|
||||||
CONFIG_REMAKE_ELF=y
|
CONFIG_REMAKE_ELF=y
|
||||||
# CONFIG_ANDROID_BOOT_IMAGE is not set
|
CONFIG_BUTTON_CMD=y
|
||||||
CONFIG_FIT=y
|
CONFIG_FIT=y
|
||||||
CONFIG_DISTRO_DEFAULTS=y
|
CONFIG_BOOTSTD_FULL=y
|
||||||
CONFIG_OF_BOARD_SETUP=y
|
CONFIG_OF_BOARD_SETUP=y
|
||||||
CONFIG_USE_PREBOOT=y
|
CONFIG_USE_PREBOOT=y
|
||||||
CONFIG_SYS_CBSIZE=512
|
CONFIG_SYS_CBSIZE=512
|
||||||
CONFIG_SYS_PBSIZE=548
|
CONFIG_SYS_PBSIZE=548
|
||||||
# CONFIG_DISPLAY_CPUINFO is not set
|
# CONFIG_DISPLAY_CPUINFO is not set
|
||||||
# CONFIG_DISPLAY_BOARDINFO is not set
|
# CONFIG_DISPLAY_BOARDINFO is not set
|
||||||
CONFIG_MISC_INIT_R=y
|
|
||||||
CONFIG_SYS_PROMPT="dragonboard410c => "
|
CONFIG_SYS_PROMPT="dragonboard410c => "
|
||||||
# CONFIG_CMD_IMI is not set
|
|
||||||
CONFIG_CMD_MD5SUM=y
|
CONFIG_CMD_MD5SUM=y
|
||||||
CONFIG_CMD_MEMINFO=y
|
CONFIG_CMD_MEMINFO=y
|
||||||
CONFIG_CMD_GPIO=y
|
CONFIG_CMD_GPIO=y
|
||||||
|
@ -35,6 +33,7 @@ CONFIG_CMD_USB=y
|
||||||
CONFIG_BOOTP_BOOTFILESIZE=y
|
CONFIG_BOOTP_BOOTFILESIZE=y
|
||||||
CONFIG_CMD_CACHE=y
|
CONFIG_CMD_CACHE=y
|
||||||
CONFIG_CMD_TIMER=y
|
CONFIG_CMD_TIMER=y
|
||||||
|
CONFIG_CMD_SYSBOOT=y
|
||||||
CONFIG_ENV_IS_IN_MMC=y
|
CONFIG_ENV_IS_IN_MMC=y
|
||||||
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
|
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
|
||||||
CONFIG_SYS_MMC_ENV_PART=2
|
CONFIG_SYS_MMC_ENV_PART=2
|
||||||
|
@ -60,6 +59,7 @@ CONFIG_PMIC_QCOM=y
|
||||||
CONFIG_MSM_SERIAL=y
|
CONFIG_MSM_SERIAL=y
|
||||||
CONFIG_SPMI_MSM=y
|
CONFIG_SPMI_MSM=y
|
||||||
CONFIG_USB=y
|
CONFIG_USB=y
|
||||||
|
# CONFIG_DM_USB_GADGET is not set
|
||||||
CONFIG_USB_EHCI_HCD=y
|
CONFIG_USB_EHCI_HCD=y
|
||||||
CONFIG_USB_EHCI_MSM=y
|
CONFIG_USB_EHCI_MSM=y
|
||||||
CONFIG_USB_ULPI_VIEWPORT=y
|
CONFIG_USB_ULPI_VIEWPORT=y
|
||||||
|
@ -68,6 +68,7 @@ CONFIG_USB_HOST_ETHER=y
|
||||||
CONFIG_USB_ETHER_ASIX=y
|
CONFIG_USB_ETHER_ASIX=y
|
||||||
CONFIG_USB_ETHER_ASIX88179=y
|
CONFIG_USB_ETHER_ASIX88179=y
|
||||||
CONFIG_USB_ETHER_MCS7830=y
|
CONFIG_USB_ETHER_MCS7830=y
|
||||||
|
CONFIG_USB_ETHER_RTL8152=y
|
||||||
CONFIG_USB_ETHER_SMSC95XX=y
|
CONFIG_USB_ETHER_SMSC95XX=y
|
||||||
CONFIG_USB_GADGET=y
|
CONFIG_USB_GADGET=y
|
||||||
CONFIG_USB_GADGET_VENDOR_NUM=0x18d1
|
CONFIG_USB_GADGET_VENDOR_NUM=0x18d1
|
||||||
|
|
|
@ -45,4 +45,6 @@ CONFIG_PINCTRL_QCOM_APQ8096=y
|
||||||
CONFIG_DM_PMIC=y
|
CONFIG_DM_PMIC=y
|
||||||
CONFIG_PMIC_QCOM=y
|
CONFIG_PMIC_QCOM=y
|
||||||
CONFIG_MSM_SERIAL=y
|
CONFIG_MSM_SERIAL=y
|
||||||
|
CONFIG_MSM_GPIO=y
|
||||||
CONFIG_SPMI_MSM=y
|
CONFIG_SPMI_MSM=y
|
||||||
|
CONFIG_CLK_STUB=y
|
||||||
|
|
|
@ -70,6 +70,7 @@ CONFIG_PMIC_QCOM=y
|
||||||
CONFIG_MSM_SERIAL=y
|
CONFIG_MSM_SERIAL=y
|
||||||
CONFIG_SPMI_MSM=y
|
CONFIG_SPMI_MSM=y
|
||||||
CONFIG_USB=y
|
CONFIG_USB=y
|
||||||
|
# CONFIG_DM_USB_GADGET is not set
|
||||||
CONFIG_USB_EHCI_HCD=y
|
CONFIG_USB_EHCI_HCD=y
|
||||||
CONFIG_USB_EHCI_MSM=y
|
CONFIG_USB_EHCI_MSM=y
|
||||||
CONFIG_USB_ULPI_VIEWPORT=y
|
CONFIG_USB_ULPI_VIEWPORT=y
|
||||||
|
|
|
@ -41,6 +41,7 @@ CONFIG_CMD_RNG=y
|
||||||
CONFIG_CMD_REGULATOR=y
|
CONFIG_CMD_REGULATOR=y
|
||||||
CONFIG_CMD_LOG=y
|
CONFIG_CMD_LOG=y
|
||||||
CONFIG_OF_LIVE=y
|
CONFIG_OF_LIVE=y
|
||||||
|
CONFIG_OF_UPSTREAM_BUILD_VENDOR=y
|
||||||
CONFIG_USE_DEFAULT_ENV_FILE=y
|
CONFIG_USE_DEFAULT_ENV_FILE=y
|
||||||
CONFIG_DEFAULT_ENV_FILE="board/qualcomm/default.env"
|
CONFIG_DEFAULT_ENV_FILE="board/qualcomm/default.env"
|
||||||
CONFIG_BUTTON_QCOM_PMIC=y
|
CONFIG_BUTTON_QCOM_PMIC=y
|
||||||
|
@ -62,6 +63,11 @@ CONFIG_CLK_QCOM_X1E80100=y
|
||||||
CONFIG_DFU_MMC=y
|
CONFIG_DFU_MMC=y
|
||||||
CONFIG_DFU_SCSI=y
|
CONFIG_DFU_SCSI=y
|
||||||
CONFIG_SYS_DFU_DATA_BUF_SIZE=0x200000
|
CONFIG_SYS_DFU_DATA_BUF_SIZE=0x200000
|
||||||
|
CONFIG_USB_FUNCTION_FASTBOOT=y
|
||||||
|
CONFIG_FASTBOOT_BUF_ADDR=0x0
|
||||||
|
CONFIG_FASTBOOT_FLASH=y
|
||||||
|
CONFIG_FASTBOOT_FLASH_MMC_DEV=0
|
||||||
|
CONFIG_FASTBOOT_MMC_USER_SUPPORT=y
|
||||||
CONFIG_MSM_GPIO=y
|
CONFIG_MSM_GPIO=y
|
||||||
CONFIG_QCOM_PMIC_GPIO=y
|
CONFIG_QCOM_PMIC_GPIO=y
|
||||||
CONFIG_DM_I2C=y
|
CONFIG_DM_I2C=y
|
||||||
|
@ -75,7 +81,6 @@ CONFIG_QCOM_HYP_SMMU=y
|
||||||
CONFIG_MISC=y
|
CONFIG_MISC=y
|
||||||
CONFIG_NVMEM=y
|
CONFIG_NVMEM=y
|
||||||
CONFIG_I2C_EEPROM=y
|
CONFIG_I2C_EEPROM=y
|
||||||
CONFIG_MMC_HS200_SUPPORT=y
|
|
||||||
CONFIG_MMC_SDHCI=y
|
CONFIG_MMC_SDHCI=y
|
||||||
CONFIG_MMC_SDHCI_ADMA=y
|
CONFIG_MMC_SDHCI_ADMA=y
|
||||||
CONFIG_MMC_SDHCI_MSM=y
|
CONFIG_MMC_SDHCI_MSM=y
|
||||||
|
@ -97,6 +102,7 @@ CONFIG_PINCTRL_QCOM_APQ8016=y
|
||||||
CONFIG_PINCTRL_QCOM_APQ8096=y
|
CONFIG_PINCTRL_QCOM_APQ8096=y
|
||||||
CONFIG_PINCTRL_QCOM_QCM2290=y
|
CONFIG_PINCTRL_QCOM_QCM2290=y
|
||||||
CONFIG_PINCTRL_QCOM_QCS404=y
|
CONFIG_PINCTRL_QCOM_QCS404=y
|
||||||
|
CONFIG_PINCTRL_QCOM_SA8775P=y
|
||||||
CONFIG_PINCTRL_QCOM_SC7280=y
|
CONFIG_PINCTRL_QCOM_SC7280=y
|
||||||
CONFIG_PINCTRL_QCOM_SDM845=y
|
CONFIG_PINCTRL_QCOM_SDM845=y
|
||||||
CONFIG_PINCTRL_QCOM_SM6115=y
|
CONFIG_PINCTRL_QCOM_SM6115=y
|
||||||
|
|
|
@ -90,6 +90,11 @@ Or for db410c (and other boards not supported by the generic target)::
|
||||||
make CROSS_COMPILE=aarch64-linux-gnu- O=.output dragonboard410c_defconfig
|
make CROSS_COMPILE=aarch64-linux-gnu- O=.output dragonboard410c_defconfig
|
||||||
make O=.output -j$(nproc)
|
make O=.output -j$(nproc)
|
||||||
|
|
||||||
|
Or for smartphones::
|
||||||
|
|
||||||
|
make CROSS_COMPILE=aarch64-linux-gnu- O=.output qcom_defconfig qcom-phone.config
|
||||||
|
make O=.output -j$(nproc)
|
||||||
|
|
||||||
- gzip u-boot::
|
- gzip u-boot::
|
||||||
|
|
||||||
gzip u-boot-nodtb.bin
|
gzip u-boot-nodtb.bin
|
||||||
|
|
|
@ -9,5 +9,6 @@ Qualcomm
|
||||||
dragonboard410c
|
dragonboard410c
|
||||||
rb3gen2
|
rb3gen2
|
||||||
board
|
board
|
||||||
|
phones
|
||||||
debugging
|
debugging
|
||||||
rdp
|
rdp
|
||||||
|
|
144
doc/board/qualcomm/phones.rst
Normal file
144
doc/board/qualcomm/phones.rst
Normal file
|
@ -0,0 +1,144 @@
|
||||||
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
.. sectionauthor:: Caleb Connolly <caleb.connolly@linaro.org>
|
||||||
|
|
||||||
|
======================================
|
||||||
|
Booting U-Boot on Qualcomm smartphones
|
||||||
|
======================================
|
||||||
|
|
||||||
|
About this
|
||||||
|
----------
|
||||||
|
|
||||||
|
This page attempts to the describe U-Boot support for Qualcomm phones, as a user guide but also a
|
||||||
|
technical introduction to How Stuff Works to help new porters.
|
||||||
|
|
||||||
|
In broad strokes, U-Boot should boot if the SoC is supported, and the device is already capable of
|
||||||
|
booting an upstream Linux kernel.
|
||||||
|
|
||||||
|
The list of supported Qualcomm SoCs changes often, for now it is best to look in
|
||||||
|
``drivers/clk/qcom/`` to get a rough idea.
|
||||||
|
|
||||||
|
For building instructions, see :doc:`board`.
|
||||||
|
|
||||||
|
Phone bringup
|
||||||
|
-------------
|
||||||
|
|
||||||
|
It is usually easier to get Linux booting first, there are many good resources for this such as the
|
||||||
|
`postmarketOS wiki`_. Once the device can boot Linux with logs on the display and ideally USB gadget
|
||||||
|
support, it is highly likely that U-Boot will boot as well.
|
||||||
|
|
||||||
|
For logs on display, you should have a simple framebuffer node defined in your DT, newer devices
|
||||||
|
require that this follow the downstream naming scheme (that the DTB is compiled with labels enabled
|
||||||
|
and the framebuffer reserved-memory region is labelled ``cont_splash``). Once this is working in
|
||||||
|
Linux it should also work in U-Boot.
|
||||||
|
|
||||||
|
In practise, U-Boot still has many more papercuts than Linux, which can be sticking points when
|
||||||
|
porting a new device. In particular, drivers failing to bind/probe (especially pre-relocation) can
|
||||||
|
be tricky to debug without UART since U-Boot will simply panic with no way to inform you of
|
||||||
|
the error. As a result, bringing up a new device can be quite frustrating, but there are quite a few
|
||||||
|
things you can try.
|
||||||
|
|
||||||
|
The phone config
|
||||||
|
^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Since most phones lack a physical keyboard or serial port, a special config fragment and environment
|
||||||
|
file can be used to provide a more seamless experience. This can be enabled by generating the config
|
||||||
|
with::
|
||||||
|
|
||||||
|
make CROSS_COMPILE=aarch64-linux-gnu- O=.output qcom_defconfig qcom-phone.config
|
||||||
|
|
||||||
|
The config and associated environment file can be found in board/qualcomm/. The main changes are:
|
||||||
|
|
||||||
|
- Panic on hang (so the panic message can be read on the display)
|
||||||
|
- Boot retry (to automatically open and re-open the bootmenu)
|
||||||
|
- A boot menu with helpful shortcuts (including USB console gadget)
|
||||||
|
- Launch the boot menu if power is held during boot or on boot failure
|
||||||
|
|
||||||
|
Fastboot mode
|
||||||
|
-------------
|
||||||
|
|
||||||
|
U-Boot's fastboot implementation is much more limited than Qualcomm's, and currently does not have a
|
||||||
|
backend for UFS storage. If your device uses eMMC or has an sdcard slot, fastboot will use that by
|
||||||
|
default.
|
||||||
|
|
||||||
|
You may need to run the fastboot command on your PC as root since the USB product/vendor ID may not
|
||||||
|
match the android udev rules.
|
||||||
|
|
||||||
|
You can also use fastboot to run arbitrary U-Boot commands with ``fastboot oem run``
|
||||||
|
|
||||||
|
Retrieving early logs
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
U-Boot is configured to save it's internal log to a buffer, this can help with debugging some driver
|
||||||
|
bind/probe issues. If your device can boot and has working USB, you can enable fastboot mode (either
|
||||||
|
via the U-Boot menu or by adding ``run fastboot`` to the end of the ``preboot=`` config in
|
||||||
|
``board/qualcomm/qcom-phone.env``).
|
||||||
|
|
||||||
|
You can then retrieve U-Boot's log buffer with the ``fastboot oem log`` command on your PC.
|
||||||
|
|
||||||
|
Hang/crash bisection
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
Without a way to get logs, we can still get quite far with only a few bits of information: what
|
||||||
|
happens when you ``fastboot boot u-boot.img``?
|
||||||
|
|
||||||
|
Does the device disconnect?
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
This can be verified by watching ``dmesg -w``. If it stays connected, it likely means the boot image
|
||||||
|
doesn't match what the bootloader expected, use ``unpack_bootimg`` to compare it with a known-good
|
||||||
|
boot image (ideally one with an upstream kernel).
|
||||||
|
|
||||||
|
Does the device hang?
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
If it stays on a black screen and does nothing, then that's a hang! Since ``qcom-phone.config``
|
||||||
|
enables CONFIG_PANIC_HANG, this likely means that you're successfully executing U-Boot code (yay!),
|
||||||
|
but something is causing a panic.
|
||||||
|
|
||||||
|
It could also be due to a bad memory or register access triggering a secure interrupt, it's worth
|
||||||
|
waiting for around a minute to see if the device eventually reboots or goes to crashdump mode. You
|
||||||
|
can also disable CONFIG_PANIC_HANG and see if that causes the device to reboot instead, if so then
|
||||||
|
it is definitely a U-Boot panic.
|
||||||
|
|
||||||
|
With enough time and patience, it should be possible to narrow down the cause of the panic by
|
||||||
|
inserting calls to ``reset_cpu()`` (with CONFIG_PANIC_HANG enabled). Then if the device resets you
|
||||||
|
know it executed the ``reset_cpu()`` call.
|
||||||
|
|
||||||
|
A good place to start is ``board_fdt_blob_setup()`` in ``arch/arm/mach-snapdragon/board.c``, this
|
||||||
|
function is called extremely early so adding a reset call is a good way to validate that U-Boot is
|
||||||
|
definitely running.
|
||||||
|
|
||||||
|
You can then do a binary search starting from the end of ``board_init_f()`` / start of
|
||||||
|
``board_init_r()`` and work from there using the init sequences for reference.
|
||||||
|
|
||||||
|
The Qualcomm RAM parsing code is a likely culprit, as ABL is known to sometimes give bogus entries
|
||||||
|
in the memory node which can trip U-Boot up.
|
||||||
|
|
||||||
|
To rule out crashes that might be caused by specific drivers, it's a good idea to disable them and
|
||||||
|
re-enable them one by one. Here is a non-exhaustive list of drivers to disable:
|
||||||
|
|
||||||
|
- pinctrl
|
||||||
|
- mmc
|
||||||
|
- scsi/ufs
|
||||||
|
- usb (dwc3)
|
||||||
|
- phy (usb, ufs)
|
||||||
|
- clk (remove clock references from your framebuffer node in DT)
|
||||||
|
|
||||||
|
Ideally, it would be possible to use the framebuffer as an early console / debug output, at the time
|
||||||
|
of writing there are out of tree patches for this but they haven't been submitted upstream yet.
|
||||||
|
|
||||||
|
Does the device reboot or go to crashdump mode?
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
On many devices crashdump mode is disabled, so they will reboot instead (maybe after some delay).
|
||||||
|
The same approach as suggested above can be used to figure out where the crash occurs.
|
||||||
|
|
||||||
|
If the device is rebooting, you can insert calls to ``hang()`` instead of ``reset_cpu()`` when
|
||||||
|
following the instructions above.
|
||||||
|
|
||||||
|
The most likely cause of a crashdump is the pinctrl/gpio driver or the SMMU driver, ensure that the
|
||||||
|
``apps_smmu`` node in your SoCs devicetree file has one of its compatible strings referenced in
|
||||||
|
``drivers/iommu/qcom-hyp-smmu.c``, you can also try disabling the pinctrl driver for your SoC (or
|
||||||
|
``CONFIG_PINCTRL`` altogether).
|
||||||
|
|
||||||
|
.. _`postmarketOS wiki`: https://wiki.postmarketos.org/wiki/Mainlining
|
|
@ -73,25 +73,25 @@ static const struct qcom_pmic_btn_data qcom_pmic_btn_data_table[] = {
|
||||||
.compatible = "qcom,pm8941-pwrkey",
|
.compatible = "qcom,pm8941-pwrkey",
|
||||||
.status_bit = PON_KPDPWR_N_SET,
|
.status_bit = PON_KPDPWR_N_SET,
|
||||||
.code = KEY_ENTER,
|
.code = KEY_ENTER,
|
||||||
.label = "pwrkey",
|
.label = "Power Button",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.compatible = "qcom,pm8941-resin",
|
.compatible = "qcom,pm8941-resin",
|
||||||
.status_bit = PON_RESIN_N_SET,
|
.status_bit = PON_RESIN_N_SET,
|
||||||
.code = KEY_DOWN,
|
.code = KEY_DOWN,
|
||||||
.label = "vol_down",
|
.label = "Volume Down",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.compatible = "qcom,pmk8350-pwrkey",
|
.compatible = "qcom,pmk8350-pwrkey",
|
||||||
.status_bit = PON_GEN3_KPDPWR_N_SET,
|
.status_bit = PON_GEN3_KPDPWR_N_SET,
|
||||||
.code = KEY_ENTER,
|
.code = KEY_ENTER,
|
||||||
.label = "pwrkey",
|
.label = "Power Button",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.compatible = "qcom,pmk8350-resin",
|
.compatible = "qcom,pmk8350-resin",
|
||||||
.status_bit = PON_GEN3_RESIN_N_SET,
|
.status_bit = PON_GEN3_RESIN_N_SET,
|
||||||
.code = KEY_DOWN,
|
.code = KEY_DOWN,
|
||||||
.label = "vol_down",
|
.label = "Volume Down",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ int button_get_by_label(const char *label, struct udevice **devp)
|
||||||
struct button_uc_plat *uc_plat = dev_get_uclass_plat(dev);
|
struct button_uc_plat *uc_plat = dev_get_uclass_plat(dev);
|
||||||
|
|
||||||
/* Ignore the top-level button node */
|
/* Ignore the top-level button node */
|
||||||
if (uc_plat->label && !strcmp(label, uc_plat->label))
|
if (uc_plat->label && !strcasecmp(label, uc_plat->label))
|
||||||
return uclass_get_device_tail(dev, 0, devp);
|
return uclass_get_device_tail(dev, 0, devp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
static const struct udevice_id nop_parent_ids[] = {
|
static const struct udevice_id nop_parent_ids[] = {
|
||||||
{ .compatible = "qcom,rpm-proc" },
|
{ .compatible = "qcom,rpm-proc" },
|
||||||
{ .compatible = "qcom,glink-rpm" },
|
{ .compatible = "qcom,glink-rpm" },
|
||||||
{ .compatible = "qcom,rpm-sm6115" },
|
{ .compatible = "qcom,glink-smd-rpm" },
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -50,6 +50,7 @@ static struct clk_ops stub_clk_ops = {
|
||||||
|
|
||||||
static const struct udevice_id stub_clk_ids[] = {
|
static const struct udevice_id stub_clk_ids[] = {
|
||||||
{ .compatible = "qcom,rpmcc" },
|
{ .compatible = "qcom,rpmcc" },
|
||||||
|
{ .compatible = "qcom,sdm845-rpmh-clk" },
|
||||||
{ .compatible = "qcom,sc7280-rpmh-clk" },
|
{ .compatible = "qcom,sc7280-rpmh-clk" },
|
||||||
{ .compatible = "qcom,sm8150-rpmh-clk" },
|
{ .compatible = "qcom,sm8150-rpmh-clk" },
|
||||||
{ .compatible = "qcom,sm8250-rpmh-clk" },
|
{ .compatible = "qcom,sm8250-rpmh-clk" },
|
||||||
|
|
|
@ -83,11 +83,12 @@ static ulong apq8096_clk_set_rate(struct clk *clk, ulong rate)
|
||||||
struct msm_clk_priv *priv = dev_get_priv(clk->dev);
|
struct msm_clk_priv *priv = dev_get_priv(clk->dev);
|
||||||
|
|
||||||
switch (clk->id) {
|
switch (clk->id) {
|
||||||
case GCC_SDCC1_APPS_CLK: /* SDC1 */
|
case GCC_SDCC2_APPS_CLK: /* SDC2 */
|
||||||
return clk_init_sdc(priv, rate);
|
return clk_init_sdc(priv, rate);
|
||||||
break;
|
break;
|
||||||
case GCC_BLSP2_UART2_APPS_CLK: /*UART2*/
|
case GCC_BLSP2_UART2_APPS_CLK: /*UART2*/
|
||||||
return clk_init_uart(priv);
|
clk_init_uart(priv);
|
||||||
|
return 7372800;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,6 +107,17 @@ static const struct gate_clk sc7280_clks[] = {
|
||||||
GATE_CLK(GCC_QUPV3_WRAP0_S0_CLK, 0x52008, BIT(10)),
|
GATE_CLK(GCC_QUPV3_WRAP0_S0_CLK, 0x52008, BIT(10)),
|
||||||
GATE_CLK(GCC_QUPV3_WRAP0_S1_CLK, 0x52008, BIT(11)),
|
GATE_CLK(GCC_QUPV3_WRAP0_S1_CLK, 0x52008, BIT(11)),
|
||||||
GATE_CLK(GCC_QUPV3_WRAP0_S3_CLK, 0x52008, BIT(13)),
|
GATE_CLK(GCC_QUPV3_WRAP0_S3_CLK, 0x52008, BIT(13)),
|
||||||
|
GATE_CLK(GCC_UFS_PHY_AXI_CLK, 0x77010, BIT(0)),
|
||||||
|
GATE_CLK(GCC_AGGRE_UFS_PHY_AXI_CLK, 0x770cc, BIT(0)),
|
||||||
|
GATE_CLK(GCC_UFS_PHY_AHB_CLK, 0x77018, BIT(0)),
|
||||||
|
GATE_CLK(GCC_UFS_PHY_UNIPRO_CORE_CLK, 0x7705c, BIT(0)),
|
||||||
|
GATE_CLK(GCC_UFS_PHY_PHY_AUX_CLK, 0x7709c, BIT(0)),
|
||||||
|
GATE_CLK(GCC_UFS_PHY_TX_SYMBOL_0_CLK, 0x7701c, BIT(0)),
|
||||||
|
GATE_CLK(GCC_UFS_PHY_RX_SYMBOL_0_CLK, 0x77020, BIT(0)),
|
||||||
|
GATE_CLK(GCC_UFS_PHY_RX_SYMBOL_1_CLK, 0x770b8, BIT(0)),
|
||||||
|
GATE_CLK(GCC_UFS_1_CLKREF_EN, 0x8c000, BIT(0)),
|
||||||
|
GATE_CLK(GCC_SDCC2_AHB_CLK, 0x14008, BIT(0)),
|
||||||
|
GATE_CLK(GCC_SDCC2_APPS_CLK, 0x14004, BIT(0)),
|
||||||
};
|
};
|
||||||
|
|
||||||
static int sc7280_enable(struct clk *clk)
|
static int sc7280_enable(struct clk *clk)
|
||||||
|
|
|
@ -77,7 +77,9 @@ static ulong sdm845_clk_set_rate(struct clk *clk, ulong rate)
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct gate_clk sdm845_clks[] = {
|
static const struct gate_clk sdm845_clks[] = {
|
||||||
|
GATE_CLK(GCC_AGGRE_USB3_PRIM_AXI_CLK, 0x8201c, 0x00000001),
|
||||||
GATE_CLK(GCC_AGGRE_USB3_SEC_AXI_CLK, 0x82020, 0x00000001),
|
GATE_CLK(GCC_AGGRE_USB3_SEC_AXI_CLK, 0x82020, 0x00000001),
|
||||||
|
GATE_CLK(GCC_CFG_NOC_USB3_PRIM_AXI_CLK, 0x0502c, 0x00000001),
|
||||||
GATE_CLK(GCC_CFG_NOC_USB3_SEC_AXI_CLK, 0x05030, 0x00000001),
|
GATE_CLK(GCC_CFG_NOC_USB3_SEC_AXI_CLK, 0x05030, 0x00000001),
|
||||||
GATE_CLK(GCC_QUPV3_WRAP0_S0_CLK, 0x5200c, 0x00000400),
|
GATE_CLK(GCC_QUPV3_WRAP0_S0_CLK, 0x5200c, 0x00000400),
|
||||||
GATE_CLK(GCC_QUPV3_WRAP0_S1_CLK, 0x5200c, 0x00000800),
|
GATE_CLK(GCC_QUPV3_WRAP0_S1_CLK, 0x5200c, 0x00000800),
|
||||||
|
@ -112,6 +114,7 @@ static const struct gate_clk sdm845_clks[] = {
|
||||||
GATE_CLK(GCC_UFS_CARD_TX_SYMBOL_0_CLK, 0x75014, 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_CARD_UNIPRO_CORE_CLK, 0x75054, 0x00000001),
|
||||||
GATE_CLK(GCC_UFS_MEM_CLKREF_CLK, 0x8c000, 0x00000001),
|
GATE_CLK(GCC_UFS_MEM_CLKREF_CLK, 0x8c000, 0x00000001),
|
||||||
|
GATE_CLK(GCC_AGGRE_UFS_PHY_AXI_CLK, 0x82024, 0x00000001),
|
||||||
GATE_CLK(GCC_UFS_PHY_AHB_CLK, 0x77010, 0x00000001),
|
GATE_CLK(GCC_UFS_PHY_AHB_CLK, 0x77010, 0x00000001),
|
||||||
GATE_CLK(GCC_UFS_PHY_AXI_CLK, 0x7700c, 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_ICE_CORE_CLK, 0x77058, 0x00000001),
|
||||||
|
|
|
@ -151,6 +151,9 @@ static int msm_gpio_direction_output(struct udevice *dev, unsigned int gpio,
|
||||||
|
|
||||||
static int msm_gpio_set_flags(struct udevice *dev, unsigned int gpio, ulong flags)
|
static int msm_gpio_set_flags(struct udevice *dev, unsigned int gpio, ulong flags)
|
||||||
{
|
{
|
||||||
|
if (msm_pinctrl_is_reserved(dev_get_parent(dev), gpio))
|
||||||
|
return -EPERM;
|
||||||
|
|
||||||
if (flags & GPIOD_IS_OUT_ACTIVE) {
|
if (flags & GPIOD_IS_OUT_ACTIVE) {
|
||||||
return msm_gpio_direction_output(dev, gpio, 1);
|
return msm_gpio_direction_output(dev, gpio, 1);
|
||||||
} else if (flags & GPIOD_IS_OUT) {
|
} else if (flags & GPIOD_IS_OUT) {
|
||||||
|
@ -172,12 +175,19 @@ static int msm_gpio_get_value_special(struct msm_gpio_bank *priv, unsigned int g
|
||||||
const struct msm_special_pin_data *data;
|
const struct msm_special_pin_data *data;
|
||||||
|
|
||||||
if (!priv->pin_data->special_pins_data)
|
if (!priv->pin_data->special_pins_data)
|
||||||
return 0;
|
return -EINVAL;
|
||||||
|
|
||||||
data = &priv->pin_data->special_pins_data[offset];
|
data = &priv->pin_data->special_pins_data[offset];
|
||||||
|
|
||||||
if (!data->io_reg || data->in_bit >= 31)
|
if (!data->io_reg)
|
||||||
return 0;
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (data->in_bit >= 31) {
|
||||||
|
if (data->out_bit >= 31)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
return !!(readl(priv->base + data->io_reg) >> data->out_bit);
|
||||||
|
}
|
||||||
|
|
||||||
return !!(readl(priv->base + data->io_reg) >> data->in_bit);
|
return !!(readl(priv->base + data->io_reg) >> data->in_bit);
|
||||||
}
|
}
|
||||||
|
@ -186,19 +196,54 @@ static int msm_gpio_get_value(struct udevice *dev, unsigned int gpio)
|
||||||
{
|
{
|
||||||
struct msm_gpio_bank *priv = dev_get_priv(dev);
|
struct msm_gpio_bank *priv = dev_get_priv(dev);
|
||||||
|
|
||||||
|
if (msm_pinctrl_is_reserved(dev_get_parent(dev), gpio))
|
||||||
|
return -EPERM;
|
||||||
|
|
||||||
if (qcom_is_special_pin(priv->pin_data, gpio))
|
if (qcom_is_special_pin(priv->pin_data, gpio))
|
||||||
return msm_gpio_get_value_special(priv, gpio);
|
return msm_gpio_get_value_special(priv, gpio);
|
||||||
|
|
||||||
return !!(readl(priv->base + GPIO_IN_OUT_REG(dev, gpio)) >> GPIO_IN);
|
return !!(readl(priv->base + GPIO_IN_OUT_REG(dev, gpio)) >> GPIO_IN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int msm_gpio_get_function_special(struct msm_gpio_bank *priv,
|
||||||
|
unsigned int gpio)
|
||||||
|
{
|
||||||
|
unsigned int offset = gpio - priv->pin_data->special_pins_start;
|
||||||
|
const struct msm_special_pin_data *data;
|
||||||
|
|
||||||
|
if (!priv->pin_data->special_pins_data)
|
||||||
|
return GPIOF_UNKNOWN;
|
||||||
|
|
||||||
|
data = &priv->pin_data->special_pins_data[offset];
|
||||||
|
|
||||||
|
/* No I/O fields, cannot control/read the I/O value */
|
||||||
|
if (!data->io_reg || (data->out_bit >= 31 && data->in_bit >= 31))
|
||||||
|
return GPIOF_FUNC;
|
||||||
|
|
||||||
|
/* No Output-Enable register, cannot control I/O direction */
|
||||||
|
if (!data->ctl_reg || data->oe_bit >= 31) {
|
||||||
|
if (data->out_bit >= 31)
|
||||||
|
return GPIOF_INPUT;
|
||||||
|
else
|
||||||
|
return GPIOF_OUTPUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (readl(priv->base + data->ctl_reg) & BIT(data->oe_bit))
|
||||||
|
return GPIOF_OUTPUT;
|
||||||
|
|
||||||
|
return GPIOF_INPUT;
|
||||||
|
}
|
||||||
|
|
||||||
static int msm_gpio_get_function(struct udevice *dev, unsigned int gpio)
|
static int msm_gpio_get_function(struct udevice *dev, unsigned int gpio)
|
||||||
{
|
{
|
||||||
struct msm_gpio_bank *priv = dev_get_priv(dev);
|
struct msm_gpio_bank *priv = dev_get_priv(dev);
|
||||||
|
|
||||||
|
if (msm_pinctrl_is_reserved(dev_get_parent(dev), gpio))
|
||||||
|
return GPIOF_UNKNOWN;
|
||||||
|
|
||||||
/* Always NOP for special pins, assume they're in the correct state */
|
/* Always NOP for special pins, assume they're in the correct state */
|
||||||
if (qcom_is_special_pin(priv->pin_data, gpio))
|
if (qcom_is_special_pin(priv->pin_data, gpio))
|
||||||
return 0;
|
return msm_gpio_get_function_special(priv, gpio);
|
||||||
|
|
||||||
if (readl(priv->base + GPIO_CONFIG_REG(dev, gpio)) & GPIO_OE_ENABLE)
|
if (readl(priv->base + GPIO_CONFIG_REG(dev, gpio)) & GPIO_OE_ENABLE)
|
||||||
return GPIOF_OUTPUT;
|
return GPIOF_OUTPUT;
|
||||||
|
|
|
@ -122,6 +122,9 @@ struct qusb2_phy_cfg {
|
||||||
|
|
||||||
/* true if PHY has PLL_CORE_INPUT_OVERRIDE register to reset PLL */
|
/* true if PHY has PLL_CORE_INPUT_OVERRIDE register to reset PLL */
|
||||||
bool has_pll_override;
|
bool has_pll_override;
|
||||||
|
|
||||||
|
/* true if PHY default clk scheme is single-ended */
|
||||||
|
bool se_clk_scheme_default;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* set of registers with offsets different per-PHY */
|
/* set of registers with offsets different per-PHY */
|
||||||
|
@ -173,6 +176,19 @@ static const unsigned int sm6115_regs_layout[] = {
|
||||||
[QUSB2PHY_PORT_POWERDOWN] = 0xb4, [QUSB2PHY_INTR_CTRL] = 0xbc,
|
[QUSB2PHY_PORT_POWERDOWN] = 0xb4, [QUSB2PHY_INTR_CTRL] = 0xbc,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct qusb2_phy_init_tbl msm8996_init_tbl[] = {
|
||||||
|
QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE1, 0xf8),
|
||||||
|
QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE2, 0xb3),
|
||||||
|
QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE3, 0x83),
|
||||||
|
QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE4, 0xc0),
|
||||||
|
QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_TUNE, 0x30),
|
||||||
|
QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_USER_CTL1, 0x79),
|
||||||
|
QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_USER_CTL2, 0x21),
|
||||||
|
QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TEST2, 0x14),
|
||||||
|
QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_AUTOPGM_CTL1, 0x9f),
|
||||||
|
QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_PWR_CTRL, 0x00),
|
||||||
|
};
|
||||||
|
|
||||||
static const struct qusb2_phy_init_tbl qusb2_v2_init_tbl[] = {
|
static const struct qusb2_phy_init_tbl qusb2_v2_init_tbl[] = {
|
||||||
QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_ANALOG_CONTROLS_TWO, 0x03),
|
QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_ANALOG_CONTROLS_TWO, 0x03),
|
||||||
QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_CLOCK_INVERTERS, 0x7c),
|
QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_CLOCK_INVERTERS, 0x7c),
|
||||||
|
@ -214,6 +230,19 @@ static const struct qusb2_phy_cfg sm6115_phy_cfg = {
|
||||||
.regs = sm6115_regs_layout,
|
.regs = sm6115_regs_layout,
|
||||||
|
|
||||||
.has_pll_test = true,
|
.has_pll_test = true,
|
||||||
|
.se_clk_scheme_default = true,
|
||||||
|
.disable_ctrl = (CLAMP_N_EN | FREEZIO_N | POWER_DOWN),
|
||||||
|
.mask_core_ready = PLL_LOCKED,
|
||||||
|
.autoresume_en = BIT(3),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct qusb2_phy_cfg sdm660_phy_cfg = {
|
||||||
|
.tbl = msm8996_init_tbl,
|
||||||
|
.tbl_num = ARRAY_SIZE(msm8996_init_tbl),
|
||||||
|
.regs = sm6115_regs_layout,
|
||||||
|
|
||||||
|
.has_pll_test = true,
|
||||||
|
.se_clk_scheme_default = false,
|
||||||
.disable_ctrl = (CLAMP_N_EN | FREEZIO_N | POWER_DOWN),
|
.disable_ctrl = (CLAMP_N_EN | FREEZIO_N | POWER_DOWN),
|
||||||
.mask_core_ready = PLL_LOCKED,
|
.mask_core_ready = PLL_LOCKED,
|
||||||
.autoresume_en = BIT(3),
|
.autoresume_en = BIT(3),
|
||||||
|
@ -228,6 +257,7 @@ static const struct qusb2_phy_cfg qusb2_v2_phy_cfg = {
|
||||||
POWER_DOWN),
|
POWER_DOWN),
|
||||||
.mask_core_ready = CORE_READY_STATUS,
|
.mask_core_ready = CORE_READY_STATUS,
|
||||||
.has_pll_override = true,
|
.has_pll_override = true,
|
||||||
|
.se_clk_scheme_default = true,
|
||||||
.autoresume_en = BIT(0),
|
.autoresume_en = BIT(0),
|
||||||
.update_tune1_with_efuse = true,
|
.update_tune1_with_efuse = true,
|
||||||
};
|
};
|
||||||
|
@ -316,8 +346,18 @@ static int qusb2phy_power_on(struct phy *phy)
|
||||||
/* Required to get phy pll lock successfully */
|
/* Required to get phy pll lock successfully */
|
||||||
udelay(150);
|
udelay(150);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Not all the SoCs have got a readable TCSR_PHY_CLK_SCHEME
|
||||||
|
* register in the TCSR so, if there's none, use the default
|
||||||
|
* value hardcoded in the configuration.
|
||||||
|
*/
|
||||||
|
qphy->has_se_clk_scheme = cfg->se_clk_scheme_default;
|
||||||
|
|
||||||
if (cfg->has_pll_test) {
|
if (cfg->has_pll_test) {
|
||||||
val |= CLK_REF_SEL;
|
if (!qphy->has_se_clk_scheme)
|
||||||
|
val &= ~CLK_REF_SEL;
|
||||||
|
else
|
||||||
|
val |= CLK_REF_SEL;
|
||||||
|
|
||||||
writel(val, qphy->base + QUSB2PHY_PLL_TEST);
|
writel(val, qphy->base + QUSB2PHY_PLL_TEST);
|
||||||
|
|
||||||
|
@ -413,6 +453,8 @@ static const struct udevice_id qusb2phy_ids[] = {
|
||||||
{ .compatible = "qcom,qusb2-phy" },
|
{ .compatible = "qcom,qusb2-phy" },
|
||||||
{ .compatible = "qcom,qcm2290-qusb2-phy",
|
{ .compatible = "qcom,qcm2290-qusb2-phy",
|
||||||
.data = (ulong)&sm6115_phy_cfg },
|
.data = (ulong)&sm6115_phy_cfg },
|
||||||
|
{ .compatible = "qcom,sdm660-qusb2-phy",
|
||||||
|
.data = (ulong)&sdm660_phy_cfg },
|
||||||
{ .compatible = "qcom,sm6115-qusb2-phy",
|
{ .compatible = "qcom,sm6115-qusb2-phy",
|
||||||
.data = (ulong)&sm6115_phy_cfg },
|
.data = (ulong)&sm6115_phy_cfg },
|
||||||
{ .compatible = "qcom,qusb2-v2-phy", .data = (ulong)&qusb2_v2_phy_cfg },
|
{ .compatible = "qcom,qusb2-v2-phy", .data = (ulong)&qusb2_v2_phy_cfg },
|
||||||
|
|
|
@ -48,12 +48,25 @@ config PINCTRL_QCOM_QCS404
|
||||||
Say Y here to enable support for pinctrl on the Snapdragon QCS404 SoC,
|
Say Y here to enable support for pinctrl on the Snapdragon QCS404 SoC,
|
||||||
as well as the associated GPIO driver.
|
as well as the associated GPIO driver.
|
||||||
|
|
||||||
|
config PINCTRL_QCOM_SA8775P
|
||||||
|
bool "Qualcomm SA8775P Pinctrl"
|
||||||
|
select PINCTRL_QCOM
|
||||||
|
help
|
||||||
|
Say Y here to enable support for pinctrl on the Snapdragon SA8775P SoC,
|
||||||
|
as well as the associated GPIO driver.
|
||||||
|
|
||||||
config PINCTRL_QCOM_SC7280
|
config PINCTRL_QCOM_SC7280
|
||||||
bool "Qualcomm SC7280/QCM6490 Pinctrl"
|
bool "Qualcomm SC7280/QCM6490 Pinctrl"
|
||||||
select PINCTRL_QCOM
|
select PINCTRL_QCOM
|
||||||
help
|
help
|
||||||
Say Y here to enable support for pinctrl on the Snapdragon SC7280 SoC,
|
Say Y here to enable support for pinctrl on the Snapdragon SC7280 SoC,
|
||||||
as well as the associated GPIO driver.
|
|
||||||
|
config PINCTRL_QCOM_SDM660
|
||||||
|
bool "Qualcomm SDM630/660 Pinctrl"
|
||||||
|
select PINCTRL_QCOM
|
||||||
|
help
|
||||||
|
Say Y here to enable support for pinctrl on the Snapdragon 630/636/660
|
||||||
|
SoCs, as well as the associated GPIO driver.
|
||||||
|
|
||||||
config PINCTRL_QCOM_SDM845
|
config PINCTRL_QCOM_SDM845
|
||||||
bool "Qualcomm SDM845 Pinctrl"
|
bool "Qualcomm SDM845 Pinctrl"
|
||||||
|
|
|
@ -9,7 +9,9 @@ obj-$(CONFIG_PINCTRL_QCOM_IPQ9574) += pinctrl-ipq9574.o
|
||||||
obj-$(CONFIG_PINCTRL_QCOM_APQ8096) += pinctrl-apq8096.o
|
obj-$(CONFIG_PINCTRL_QCOM_APQ8096) += pinctrl-apq8096.o
|
||||||
obj-$(CONFIG_PINCTRL_QCOM_QCM2290) += pinctrl-qcm2290.o
|
obj-$(CONFIG_PINCTRL_QCOM_QCM2290) += pinctrl-qcm2290.o
|
||||||
obj-$(CONFIG_PINCTRL_QCOM_QCS404) += pinctrl-qcs404.o
|
obj-$(CONFIG_PINCTRL_QCOM_QCS404) += pinctrl-qcs404.o
|
||||||
|
obj-$(CONFIG_PINCTRL_QCOM_SA8775P) += pinctrl-sa8775p.o
|
||||||
obj-$(CONFIG_PINCTRL_QCOM_SC7280) += pinctrl-sc7280.o
|
obj-$(CONFIG_PINCTRL_QCOM_SC7280) += pinctrl-sc7280.o
|
||||||
|
obj-$(CONFIG_PINCTRL_QCOM_SDM660) += pinctrl-sdm660.o
|
||||||
obj-$(CONFIG_PINCTRL_QCOM_SDM845) += pinctrl-sdm845.o
|
obj-$(CONFIG_PINCTRL_QCOM_SDM845) += pinctrl-sdm845.o
|
||||||
obj-$(CONFIG_PINCTRL_QCOM_SM6115) += pinctrl-sm6115.o
|
obj-$(CONFIG_PINCTRL_QCOM_SM6115) += pinctrl-sm6115.o
|
||||||
obj-$(CONFIG_PINCTRL_QCOM_SM8150) += pinctrl-sm8150.o
|
obj-$(CONFIG_PINCTRL_QCOM_SM8150) += pinctrl-sm8150.o
|
||||||
|
|
|
@ -15,14 +15,18 @@
|
||||||
#include <asm/gpio.h>
|
#include <asm/gpio.h>
|
||||||
#include <dm/pinctrl.h>
|
#include <dm/pinctrl.h>
|
||||||
#include <linux/bitops.h>
|
#include <linux/bitops.h>
|
||||||
|
#include <linux/bitmap.h>
|
||||||
#include <linux/bug.h>
|
#include <linux/bug.h>
|
||||||
#include <mach/gpio.h>
|
#include <mach/gpio.h>
|
||||||
|
|
||||||
#include "pinctrl-qcom.h"
|
#include "pinctrl-qcom.h"
|
||||||
|
|
||||||
|
#define MSM_PINCTRL_MAX_PINS 256
|
||||||
|
|
||||||
struct msm_pinctrl_priv {
|
struct msm_pinctrl_priv {
|
||||||
phys_addr_t base;
|
phys_addr_t base;
|
||||||
struct msm_pinctrl_data *data;
|
struct msm_pinctrl_data *data;
|
||||||
|
DECLARE_BITMAP(reserved_map, MSM_PINCTRL_MAX_PINS);
|
||||||
};
|
};
|
||||||
|
|
||||||
#define GPIO_CONFIG_REG(priv, x) \
|
#define GPIO_CONFIG_REG(priv, x) \
|
||||||
|
@ -71,13 +75,60 @@ static const char *msm_get_function_name(struct udevice *dev,
|
||||||
return priv->data->get_function_name(dev, selector);
|
return priv->data->get_function_name(dev, selector);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int msm_pinctrl_parse_ranges(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct msm_pinctrl_priv *priv = dev_get_priv(dev);
|
||||||
|
ofnode node = dev_ofnode(dev);
|
||||||
|
int ret, count, i;
|
||||||
|
u32 *ranges;
|
||||||
|
|
||||||
|
if (ofnode_read_prop(node, "gpio-reserved-ranges", &count)) {
|
||||||
|
if (count % 2 == 1) {
|
||||||
|
dev_err(dev, "gpio-reserved-ranges must be a multiple of 2\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ranges = malloc(count);
|
||||||
|
if (!ranges)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
ret = ofnode_read_u32_array(node, "gpio-reserved-ranges", ranges, count / 4);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(dev, "failed to read gpio-reserved-ranges array (%d)\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < count / 4; i += 2) {
|
||||||
|
if (ranges[i] >= MSM_PINCTRL_MAX_PINS ||
|
||||||
|
(ranges[i] + ranges[i + 1]) >= MSM_PINCTRL_MAX_PINS) {
|
||||||
|
dev_err(dev, "invalid reserved-range (%d;%d)\n",
|
||||||
|
ranges[i], ranges[i + 1]);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bitmap_set(priv->reserved_map, ranges[i], ranges[i + 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(ranges);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int msm_pinctrl_probe(struct udevice *dev)
|
static int msm_pinctrl_probe(struct udevice *dev)
|
||||||
{
|
{
|
||||||
struct msm_pinctrl_priv *priv = dev_get_priv(dev);
|
struct msm_pinctrl_priv *priv = dev_get_priv(dev);
|
||||||
|
int ret;
|
||||||
|
|
||||||
priv->base = dev_read_addr(dev);
|
priv->base = dev_read_addr(dev);
|
||||||
priv->data = (struct msm_pinctrl_data *)dev_get_driver_data(dev);
|
priv->data = (struct msm_pinctrl_data *)dev_get_driver_data(dev);
|
||||||
|
|
||||||
|
ret = msm_pinctrl_parse_ranges(dev);
|
||||||
|
if (ret) {
|
||||||
|
printf("Couldn't parse reserved GPIO ranges!\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
return priv->base == FDT_ADDR_T_NONE ? -EINVAL : 0;
|
return priv->base == FDT_ADDR_T_NONE ? -EINVAL : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,6 +148,9 @@ static int msm_pinmux_set(struct udevice *dev, unsigned int pin_selector,
|
||||||
if (func < 0)
|
if (func < 0)
|
||||||
return func;
|
return func;
|
||||||
|
|
||||||
|
if (msm_pinctrl_is_reserved(dev, pin_selector))
|
||||||
|
return -EPERM;
|
||||||
|
|
||||||
/* Always NOP for special pins, assume they're in the correct state */
|
/* Always NOP for special pins, assume they're in the correct state */
|
||||||
if (qcom_is_special_pin(&priv->data->pin_data, pin_selector))
|
if (qcom_is_special_pin(&priv->data->pin_data, pin_selector))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -145,6 +199,9 @@ static int msm_pinconf_set(struct udevice *dev, unsigned int pin_selector,
|
||||||
{
|
{
|
||||||
struct msm_pinctrl_priv *priv = dev_get_priv(dev);
|
struct msm_pinctrl_priv *priv = dev_get_priv(dev);
|
||||||
|
|
||||||
|
if (msm_pinctrl_is_reserved(dev, pin_selector))
|
||||||
|
return -EPERM;
|
||||||
|
|
||||||
if (qcom_is_special_pin(&priv->data->pin_data, pin_selector))
|
if (qcom_is_special_pin(&priv->data->pin_data, pin_selector))
|
||||||
return msm_pinconf_set_special(priv, pin_selector, param, argument);
|
return msm_pinconf_set_special(priv, pin_selector, param, argument);
|
||||||
|
|
||||||
|
@ -241,3 +298,13 @@ U_BOOT_DRIVER(pinctrl_qcom) = {
|
||||||
.ops = &msm_pinctrl_ops,
|
.ops = &msm_pinctrl_ops,
|
||||||
.probe = msm_pinctrl_probe,
|
.probe = msm_pinctrl_probe,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool msm_pinctrl_is_reserved(struct udevice *dev, unsigned int pin)
|
||||||
|
{
|
||||||
|
struct msm_pinctrl_priv *priv = dev_get_priv(dev);
|
||||||
|
|
||||||
|
if (pin >= MSM_PINCTRL_MAX_PINS)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return test_bit(pin, priv->reserved_map);
|
||||||
|
}
|
||||||
|
|
623
drivers/pinctrl/qcom/pinctrl-sa8775p.c
Normal file
623
drivers/pinctrl/qcom/pinctrl-sa8775p.c
Normal file
|
@ -0,0 +1,623 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
|
* Copyright (c) 2023, Linaro Limited
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <dm.h>
|
||||||
|
|
||||||
|
#include "pinctrl-qcom.h"
|
||||||
|
|
||||||
|
#define MAX_PIN_NAME_LEN 32
|
||||||
|
static char pin_name[MAX_PIN_NAME_LEN] __section(".data");
|
||||||
|
|
||||||
|
typedef unsigned int msm_pin_function[10];
|
||||||
|
#define SA8775_PIN_OFFSET 0x100000
|
||||||
|
|
||||||
|
#define PINGROUP(id, f1, f2, f3, f4, f5, f6, f7, f8, f9)\
|
||||||
|
{ \
|
||||||
|
msm_mux_gpio, /* gpio mode */ \
|
||||||
|
msm_mux_##f1, \
|
||||||
|
msm_mux_##f2, \
|
||||||
|
msm_mux_##f3, \
|
||||||
|
msm_mux_##f4, \
|
||||||
|
msm_mux_##f5, \
|
||||||
|
msm_mux_##f6, \
|
||||||
|
msm_mux_##f7, \
|
||||||
|
msm_mux_##f8, \
|
||||||
|
msm_mux_##f9 \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SDC_QDSD_PINGROUP(pg_name, ctl, pull, drv) \
|
||||||
|
{ \
|
||||||
|
.name = pg_name, \
|
||||||
|
.ctl_reg = ctl, \
|
||||||
|
.io_reg = 0, \
|
||||||
|
.pull_bit = pull, \
|
||||||
|
.drv_bit = drv, \
|
||||||
|
.oe_bit = -1, \
|
||||||
|
.in_bit = -1, \
|
||||||
|
.out_bit = -1, \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define UFS_RESET(pg_name, ctl) \
|
||||||
|
{ \
|
||||||
|
.name = pg_name, \
|
||||||
|
.ctl_reg = ctl, \
|
||||||
|
.io_reg = ctl + 0x4, \
|
||||||
|
.pull_bit = 3, \
|
||||||
|
.drv_bit = 0, \
|
||||||
|
.oe_bit = -1, \
|
||||||
|
.in_bit = -1, \
|
||||||
|
.out_bit = 0, \
|
||||||
|
}
|
||||||
|
|
||||||
|
enum sa8775p_functions {
|
||||||
|
msm_mux_gpio,
|
||||||
|
msm_mux_atest_char,
|
||||||
|
msm_mux_atest_usb2,
|
||||||
|
msm_mux_audio_ref,
|
||||||
|
msm_mux_cam_mclk,
|
||||||
|
msm_mux_cci_async,
|
||||||
|
msm_mux_cci_i2c,
|
||||||
|
msm_mux_cci_timer0,
|
||||||
|
msm_mux_cci_timer1,
|
||||||
|
msm_mux_cci_timer2,
|
||||||
|
msm_mux_cci_timer3,
|
||||||
|
msm_mux_cci_timer4,
|
||||||
|
msm_mux_cci_timer5,
|
||||||
|
msm_mux_cci_timer6,
|
||||||
|
msm_mux_cci_timer7,
|
||||||
|
msm_mux_cci_timer8,
|
||||||
|
msm_mux_cci_timer9,
|
||||||
|
msm_mux_cri_trng,
|
||||||
|
msm_mux_cri_trng0,
|
||||||
|
msm_mux_cri_trng1,
|
||||||
|
msm_mux_dbg_out,
|
||||||
|
msm_mux_ddr_bist,
|
||||||
|
msm_mux_ddr_pxi0,
|
||||||
|
msm_mux_ddr_pxi1,
|
||||||
|
msm_mux_ddr_pxi2,
|
||||||
|
msm_mux_ddr_pxi3,
|
||||||
|
msm_mux_ddr_pxi4,
|
||||||
|
msm_mux_ddr_pxi5,
|
||||||
|
msm_mux_edp0_hot,
|
||||||
|
msm_mux_edp0_lcd,
|
||||||
|
msm_mux_edp1_hot,
|
||||||
|
msm_mux_edp1_lcd,
|
||||||
|
msm_mux_edp2_hot,
|
||||||
|
msm_mux_edp2_lcd,
|
||||||
|
msm_mux_edp3_hot,
|
||||||
|
msm_mux_edp3_lcd,
|
||||||
|
msm_mux_emac0_mcg0,
|
||||||
|
msm_mux_emac0_mcg1,
|
||||||
|
msm_mux_emac0_mcg2,
|
||||||
|
msm_mux_emac0_mcg3,
|
||||||
|
msm_mux_emac0_mdc,
|
||||||
|
msm_mux_emac0_mdio,
|
||||||
|
msm_mux_emac0_ptp_aux,
|
||||||
|
msm_mux_emac0_ptp_pps,
|
||||||
|
msm_mux_emac1_mcg0,
|
||||||
|
msm_mux_emac1_mcg1,
|
||||||
|
msm_mux_emac1_mcg2,
|
||||||
|
msm_mux_emac1_mcg3,
|
||||||
|
msm_mux_emac1_mdc,
|
||||||
|
msm_mux_emac1_mdio,
|
||||||
|
msm_mux_emac1_ptp_aux,
|
||||||
|
msm_mux_emac1_ptp_pps,
|
||||||
|
msm_mux_gcc_gp1,
|
||||||
|
msm_mux_gcc_gp2,
|
||||||
|
msm_mux_gcc_gp3,
|
||||||
|
msm_mux_gcc_gp4,
|
||||||
|
msm_mux_gcc_gp5,
|
||||||
|
msm_mux_hs0_mi2s,
|
||||||
|
msm_mux_hs1_mi2s,
|
||||||
|
msm_mux_hs2_mi2s,
|
||||||
|
msm_mux_ibi_i3c,
|
||||||
|
msm_mux_jitter_bist,
|
||||||
|
msm_mux_mdp0_vsync0,
|
||||||
|
msm_mux_mdp0_vsync1,
|
||||||
|
msm_mux_mdp0_vsync2,
|
||||||
|
msm_mux_mdp0_vsync3,
|
||||||
|
msm_mux_mdp0_vsync4,
|
||||||
|
msm_mux_mdp0_vsync5,
|
||||||
|
msm_mux_mdp0_vsync6,
|
||||||
|
msm_mux_mdp0_vsync7,
|
||||||
|
msm_mux_mdp0_vsync8,
|
||||||
|
msm_mux_mdp1_vsync0,
|
||||||
|
msm_mux_mdp1_vsync1,
|
||||||
|
msm_mux_mdp1_vsync2,
|
||||||
|
msm_mux_mdp1_vsync3,
|
||||||
|
msm_mux_mdp1_vsync4,
|
||||||
|
msm_mux_mdp1_vsync5,
|
||||||
|
msm_mux_mdp1_vsync6,
|
||||||
|
msm_mux_mdp1_vsync7,
|
||||||
|
msm_mux_mdp1_vsync8,
|
||||||
|
msm_mux_mdp_vsync,
|
||||||
|
msm_mux_mi2s1_data0,
|
||||||
|
msm_mux_mi2s1_data1,
|
||||||
|
msm_mux_mi2s1_sck,
|
||||||
|
msm_mux_mi2s1_ws,
|
||||||
|
msm_mux_mi2s2_data0,
|
||||||
|
msm_mux_mi2s2_data1,
|
||||||
|
msm_mux_mi2s2_sck,
|
||||||
|
msm_mux_mi2s2_ws,
|
||||||
|
msm_mux_mi2s_mclk0,
|
||||||
|
msm_mux_mi2s_mclk1,
|
||||||
|
msm_mux_pcie0_clkreq,
|
||||||
|
msm_mux_pcie1_clkreq,
|
||||||
|
msm_mux_phase_flag,
|
||||||
|
msm_mux_pll_bist,
|
||||||
|
msm_mux_pll_clk,
|
||||||
|
msm_mux_prng_rosc0,
|
||||||
|
msm_mux_prng_rosc1,
|
||||||
|
msm_mux_prng_rosc2,
|
||||||
|
msm_mux_prng_rosc3,
|
||||||
|
msm_mux_qdss_cti,
|
||||||
|
msm_mux_qdss_gpio,
|
||||||
|
msm_mux_qup0_se0,
|
||||||
|
msm_mux_qup0_se1,
|
||||||
|
msm_mux_qup0_se2,
|
||||||
|
msm_mux_qup0_se3,
|
||||||
|
msm_mux_qup0_se4,
|
||||||
|
msm_mux_qup0_se5,
|
||||||
|
msm_mux_qup1_se0,
|
||||||
|
msm_mux_qup1_se1,
|
||||||
|
msm_mux_qup1_se2,
|
||||||
|
msm_mux_qup1_se3,
|
||||||
|
msm_mux_qup1_se4,
|
||||||
|
msm_mux_qup1_se5,
|
||||||
|
msm_mux_qup1_se6,
|
||||||
|
msm_mux_qup2_se0,
|
||||||
|
msm_mux_qup2_se1,
|
||||||
|
msm_mux_qup2_se2,
|
||||||
|
msm_mux_qup2_se3,
|
||||||
|
msm_mux_qup2_se4,
|
||||||
|
msm_mux_qup2_se5,
|
||||||
|
msm_mux_qup2_se6,
|
||||||
|
msm_mux_qup3_se0,
|
||||||
|
msm_mux_sail_top,
|
||||||
|
msm_mux_sailss_emac0,
|
||||||
|
msm_mux_sailss_ospi,
|
||||||
|
msm_mux_sgmii_phy,
|
||||||
|
msm_mux_tb_trig,
|
||||||
|
msm_mux_tgu_ch0,
|
||||||
|
msm_mux_tgu_ch1,
|
||||||
|
msm_mux_tgu_ch2,
|
||||||
|
msm_mux_tgu_ch3,
|
||||||
|
msm_mux_tgu_ch4,
|
||||||
|
msm_mux_tgu_ch5,
|
||||||
|
msm_mux_tsense_pwm1,
|
||||||
|
msm_mux_tsense_pwm2,
|
||||||
|
msm_mux_tsense_pwm3,
|
||||||
|
msm_mux_tsense_pwm4,
|
||||||
|
msm_mux_usb2phy_ac,
|
||||||
|
msm_mux_vsense_trigger,
|
||||||
|
msm_mux__,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MSM_PIN_FUNCTION(fname) \
|
||||||
|
[msm_mux_##fname] = {#fname, msm_mux_##fname}
|
||||||
|
|
||||||
|
static const struct pinctrl_function msm_pinctrl_functions[] = {
|
||||||
|
MSM_PIN_FUNCTION(gpio),
|
||||||
|
MSM_PIN_FUNCTION(atest_char),
|
||||||
|
MSM_PIN_FUNCTION(atest_usb2),
|
||||||
|
MSM_PIN_FUNCTION(audio_ref),
|
||||||
|
MSM_PIN_FUNCTION(cam_mclk),
|
||||||
|
MSM_PIN_FUNCTION(cci_async),
|
||||||
|
MSM_PIN_FUNCTION(cci_i2c),
|
||||||
|
MSM_PIN_FUNCTION(cci_timer0),
|
||||||
|
MSM_PIN_FUNCTION(cci_timer1),
|
||||||
|
MSM_PIN_FUNCTION(cci_timer2),
|
||||||
|
MSM_PIN_FUNCTION(cci_timer3),
|
||||||
|
MSM_PIN_FUNCTION(cci_timer4),
|
||||||
|
MSM_PIN_FUNCTION(cci_timer5),
|
||||||
|
MSM_PIN_FUNCTION(cci_timer6),
|
||||||
|
MSM_PIN_FUNCTION(cci_timer7),
|
||||||
|
MSM_PIN_FUNCTION(cci_timer8),
|
||||||
|
MSM_PIN_FUNCTION(cci_timer9),
|
||||||
|
MSM_PIN_FUNCTION(cri_trng),
|
||||||
|
MSM_PIN_FUNCTION(cri_trng0),
|
||||||
|
MSM_PIN_FUNCTION(cri_trng1),
|
||||||
|
MSM_PIN_FUNCTION(dbg_out),
|
||||||
|
MSM_PIN_FUNCTION(ddr_bist),
|
||||||
|
MSM_PIN_FUNCTION(ddr_pxi0),
|
||||||
|
MSM_PIN_FUNCTION(ddr_pxi1),
|
||||||
|
MSM_PIN_FUNCTION(ddr_pxi2),
|
||||||
|
MSM_PIN_FUNCTION(ddr_pxi3),
|
||||||
|
MSM_PIN_FUNCTION(ddr_pxi4),
|
||||||
|
MSM_PIN_FUNCTION(ddr_pxi5),
|
||||||
|
MSM_PIN_FUNCTION(edp0_hot),
|
||||||
|
MSM_PIN_FUNCTION(edp0_lcd),
|
||||||
|
MSM_PIN_FUNCTION(edp1_hot),
|
||||||
|
MSM_PIN_FUNCTION(edp1_lcd),
|
||||||
|
MSM_PIN_FUNCTION(edp2_hot),
|
||||||
|
MSM_PIN_FUNCTION(edp2_lcd),
|
||||||
|
MSM_PIN_FUNCTION(edp3_hot),
|
||||||
|
MSM_PIN_FUNCTION(edp3_lcd),
|
||||||
|
MSM_PIN_FUNCTION(emac0_mcg0),
|
||||||
|
MSM_PIN_FUNCTION(emac0_mcg1),
|
||||||
|
MSM_PIN_FUNCTION(emac0_mcg2),
|
||||||
|
MSM_PIN_FUNCTION(emac0_mcg3),
|
||||||
|
MSM_PIN_FUNCTION(emac0_mdc),
|
||||||
|
MSM_PIN_FUNCTION(emac0_mdio),
|
||||||
|
MSM_PIN_FUNCTION(emac0_ptp_aux),
|
||||||
|
MSM_PIN_FUNCTION(emac0_ptp_pps),
|
||||||
|
MSM_PIN_FUNCTION(emac1_mcg0),
|
||||||
|
MSM_PIN_FUNCTION(emac1_mcg1),
|
||||||
|
MSM_PIN_FUNCTION(emac1_mcg2),
|
||||||
|
MSM_PIN_FUNCTION(emac1_mcg3),
|
||||||
|
MSM_PIN_FUNCTION(emac1_mdc),
|
||||||
|
MSM_PIN_FUNCTION(emac1_mdio),
|
||||||
|
MSM_PIN_FUNCTION(emac1_ptp_aux),
|
||||||
|
MSM_PIN_FUNCTION(emac1_ptp_pps),
|
||||||
|
MSM_PIN_FUNCTION(gcc_gp1),
|
||||||
|
MSM_PIN_FUNCTION(gcc_gp2),
|
||||||
|
MSM_PIN_FUNCTION(gcc_gp3),
|
||||||
|
MSM_PIN_FUNCTION(gcc_gp4),
|
||||||
|
MSM_PIN_FUNCTION(gcc_gp5),
|
||||||
|
MSM_PIN_FUNCTION(hs0_mi2s),
|
||||||
|
MSM_PIN_FUNCTION(hs1_mi2s),
|
||||||
|
MSM_PIN_FUNCTION(hs2_mi2s),
|
||||||
|
MSM_PIN_FUNCTION(ibi_i3c),
|
||||||
|
MSM_PIN_FUNCTION(jitter_bist),
|
||||||
|
MSM_PIN_FUNCTION(mdp0_vsync0),
|
||||||
|
MSM_PIN_FUNCTION(mdp0_vsync1),
|
||||||
|
MSM_PIN_FUNCTION(mdp0_vsync2),
|
||||||
|
MSM_PIN_FUNCTION(mdp0_vsync3),
|
||||||
|
MSM_PIN_FUNCTION(mdp0_vsync4),
|
||||||
|
MSM_PIN_FUNCTION(mdp0_vsync5),
|
||||||
|
MSM_PIN_FUNCTION(mdp0_vsync6),
|
||||||
|
MSM_PIN_FUNCTION(mdp0_vsync7),
|
||||||
|
MSM_PIN_FUNCTION(mdp0_vsync8),
|
||||||
|
MSM_PIN_FUNCTION(mdp1_vsync0),
|
||||||
|
MSM_PIN_FUNCTION(mdp1_vsync1),
|
||||||
|
MSM_PIN_FUNCTION(mdp1_vsync2),
|
||||||
|
MSM_PIN_FUNCTION(mdp1_vsync3),
|
||||||
|
MSM_PIN_FUNCTION(mdp1_vsync4),
|
||||||
|
MSM_PIN_FUNCTION(mdp1_vsync5),
|
||||||
|
MSM_PIN_FUNCTION(mdp1_vsync6),
|
||||||
|
MSM_PIN_FUNCTION(mdp1_vsync7),
|
||||||
|
MSM_PIN_FUNCTION(mdp1_vsync8),
|
||||||
|
MSM_PIN_FUNCTION(mdp_vsync),
|
||||||
|
MSM_PIN_FUNCTION(mi2s1_data0),
|
||||||
|
MSM_PIN_FUNCTION(mi2s1_data1),
|
||||||
|
MSM_PIN_FUNCTION(mi2s1_sck),
|
||||||
|
MSM_PIN_FUNCTION(mi2s1_ws),
|
||||||
|
MSM_PIN_FUNCTION(mi2s2_data0),
|
||||||
|
MSM_PIN_FUNCTION(mi2s2_data1),
|
||||||
|
MSM_PIN_FUNCTION(mi2s2_sck),
|
||||||
|
MSM_PIN_FUNCTION(mi2s2_ws),
|
||||||
|
MSM_PIN_FUNCTION(mi2s_mclk0),
|
||||||
|
MSM_PIN_FUNCTION(mi2s_mclk1),
|
||||||
|
MSM_PIN_FUNCTION(pcie0_clkreq),
|
||||||
|
MSM_PIN_FUNCTION(pcie1_clkreq),
|
||||||
|
MSM_PIN_FUNCTION(phase_flag),
|
||||||
|
MSM_PIN_FUNCTION(pll_bist),
|
||||||
|
MSM_PIN_FUNCTION(pll_clk),
|
||||||
|
MSM_PIN_FUNCTION(prng_rosc0),
|
||||||
|
MSM_PIN_FUNCTION(prng_rosc1),
|
||||||
|
MSM_PIN_FUNCTION(prng_rosc2),
|
||||||
|
MSM_PIN_FUNCTION(prng_rosc3),
|
||||||
|
MSM_PIN_FUNCTION(qdss_cti),
|
||||||
|
MSM_PIN_FUNCTION(qdss_gpio),
|
||||||
|
MSM_PIN_FUNCTION(qup0_se0),
|
||||||
|
MSM_PIN_FUNCTION(qup0_se1),
|
||||||
|
MSM_PIN_FUNCTION(qup0_se2),
|
||||||
|
MSM_PIN_FUNCTION(qup0_se3),
|
||||||
|
MSM_PIN_FUNCTION(qup0_se4),
|
||||||
|
MSM_PIN_FUNCTION(qup0_se5),
|
||||||
|
MSM_PIN_FUNCTION(qup1_se0),
|
||||||
|
MSM_PIN_FUNCTION(qup1_se1),
|
||||||
|
MSM_PIN_FUNCTION(qup1_se2),
|
||||||
|
MSM_PIN_FUNCTION(qup1_se3),
|
||||||
|
MSM_PIN_FUNCTION(qup1_se4),
|
||||||
|
MSM_PIN_FUNCTION(qup1_se5),
|
||||||
|
MSM_PIN_FUNCTION(qup1_se6),
|
||||||
|
MSM_PIN_FUNCTION(qup2_se0),
|
||||||
|
MSM_PIN_FUNCTION(qup2_se1),
|
||||||
|
MSM_PIN_FUNCTION(qup2_se2),
|
||||||
|
MSM_PIN_FUNCTION(qup2_se3),
|
||||||
|
MSM_PIN_FUNCTION(qup2_se4),
|
||||||
|
MSM_PIN_FUNCTION(qup2_se5),
|
||||||
|
MSM_PIN_FUNCTION(qup2_se6),
|
||||||
|
MSM_PIN_FUNCTION(qup3_se0),
|
||||||
|
MSM_PIN_FUNCTION(sail_top),
|
||||||
|
MSM_PIN_FUNCTION(sailss_emac0),
|
||||||
|
MSM_PIN_FUNCTION(sailss_ospi),
|
||||||
|
MSM_PIN_FUNCTION(sgmii_phy),
|
||||||
|
MSM_PIN_FUNCTION(tb_trig),
|
||||||
|
MSM_PIN_FUNCTION(tgu_ch0),
|
||||||
|
MSM_PIN_FUNCTION(tgu_ch1),
|
||||||
|
MSM_PIN_FUNCTION(tgu_ch2),
|
||||||
|
MSM_PIN_FUNCTION(tgu_ch3),
|
||||||
|
MSM_PIN_FUNCTION(tgu_ch4),
|
||||||
|
MSM_PIN_FUNCTION(tgu_ch5),
|
||||||
|
MSM_PIN_FUNCTION(tsense_pwm1),
|
||||||
|
MSM_PIN_FUNCTION(tsense_pwm2),
|
||||||
|
MSM_PIN_FUNCTION(tsense_pwm3),
|
||||||
|
MSM_PIN_FUNCTION(tsense_pwm4),
|
||||||
|
MSM_PIN_FUNCTION(usb2phy_ac),
|
||||||
|
MSM_PIN_FUNCTION(vsense_trigger),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const msm_pin_function sa8775p_pin_functions[] = {
|
||||||
|
[0] = PINGROUP(0, _, _, _, _, _, _, _, _, _),
|
||||||
|
[1] = PINGROUP(1, pcie0_clkreq, _, _, _, _, _, _, _, _),
|
||||||
|
[2] = PINGROUP(2, _, _, _, _, _, _, _, _, _),
|
||||||
|
[3] = PINGROUP(3, pcie1_clkreq, _, _, _, _, _, _, _, _),
|
||||||
|
[4] = PINGROUP(4, _, _, _, _, _, _, _, _, _),
|
||||||
|
[5] = PINGROUP(5, _, _, _, _, _, _, _, _, _),
|
||||||
|
[6] = PINGROUP(6, emac0_ptp_aux, emac0_ptp_pps, emac1_ptp_aux,
|
||||||
|
emac1_ptp_pps, _, _, _, _, _),
|
||||||
|
[7] = PINGROUP(7, sgmii_phy, _, _, _, _, _, _, _, _),
|
||||||
|
[8] = PINGROUP(8, emac0_mdc, _, _, _, _, _, _, _, _),
|
||||||
|
[9] = PINGROUP(9, emac0_mdio, _, _, _, _, _, _, _, _),
|
||||||
|
[10] = PINGROUP(10, usb2phy_ac, emac0_ptp_aux, emac0_ptp_pps,
|
||||||
|
emac1_ptp_aux, emac1_ptp_pps, _, _, _, _),
|
||||||
|
[11] = PINGROUP(11, usb2phy_ac, emac0_ptp_aux, emac0_ptp_pps,
|
||||||
|
emac1_ptp_aux, emac1_ptp_pps, _, _, _, _),
|
||||||
|
[12] = PINGROUP(12, usb2phy_ac, emac0_ptp_aux, emac0_ptp_pps,
|
||||||
|
emac1_ptp_aux, emac1_ptp_pps, emac0_mcg0, _, _, _),
|
||||||
|
[13] = PINGROUP(13, qup3_se0, emac0_mcg1, _, _, sail_top, _, _, _, _),
|
||||||
|
[14] = PINGROUP(14, qup3_se0, emac0_mcg2, _, _, sail_top, _, _, _, _),
|
||||||
|
[15] = PINGROUP(15, qup3_se0, emac0_mcg3, _, _, sail_top, _, _, _, _),
|
||||||
|
[16] = PINGROUP(16, qup3_se0, emac1_mcg0, _, _, sail_top, _, _, _, _),
|
||||||
|
[17] = PINGROUP(17, qup3_se0, tb_trig, tb_trig, emac1_mcg1, _, _, _, _, _),
|
||||||
|
[18] = PINGROUP(18, qup3_se0, emac1_mcg2, _, _, sailss_ospi, sailss_emac0, _, _, _),
|
||||||
|
[19] = PINGROUP(19, qup3_se0, emac1_mcg3, _, _, sailss_ospi, sailss_emac0, _, _, _),
|
||||||
|
[20] = PINGROUP(20, qup0_se0, emac1_mdc, qdss_gpio, _, _, _, _, _, _),
|
||||||
|
[21] = PINGROUP(21, qup0_se0, emac1_mdio, qdss_gpio, _, _, _, _, _, _),
|
||||||
|
[22] = PINGROUP(22, qup0_se0, qdss_gpio, _, _, _, _, _, _, _),
|
||||||
|
[23] = PINGROUP(23, qup0_se0, qdss_gpio, _, _, _, _, _, _, _),
|
||||||
|
[24] = PINGROUP(24, qup0_se1, qdss_gpio, _, _, _, _, _, _, _),
|
||||||
|
[25] = PINGROUP(25, qup0_se1, phase_flag, _, qdss_gpio, _, _, _, _, _),
|
||||||
|
[26] = PINGROUP(26, sgmii_phy, qup0_se1, qdss_cti, phase_flag, _, _, _, _, _),
|
||||||
|
[27] = PINGROUP(27, qup0_se1, qdss_cti, phase_flag, _, atest_char, _, _, _, _),
|
||||||
|
[28] = PINGROUP(28, qup0_se3, phase_flag, _, qdss_gpio, _, _, _, _, _),
|
||||||
|
[29] = PINGROUP(29, qup0_se3, phase_flag, _, qdss_gpio, _, _, _, _, _),
|
||||||
|
[30] = PINGROUP(30, qup0_se3, phase_flag, _, qdss_gpio, _, _, _, _, _),
|
||||||
|
[31] = PINGROUP(31, qup0_se3, phase_flag, _, qdss_gpio, _, _, _, _, _),
|
||||||
|
[32] = PINGROUP(32, qup0_se4, phase_flag, _, _, _, _, _, _, _),
|
||||||
|
[33] = PINGROUP(33, qup0_se4, gcc_gp4, _, ddr_pxi0, _, _, _, _, _),
|
||||||
|
[34] = PINGROUP(34, qup0_se4, gcc_gp5, _, ddr_pxi0, _, _, _, _, _),
|
||||||
|
[35] = PINGROUP(35, qup0_se4, phase_flag, _, _, _, _, _, _, _),
|
||||||
|
[36] = PINGROUP(36, qup0_se2, qup0_se5, phase_flag, tgu_ch2, _, _, _, _, _),
|
||||||
|
[37] = PINGROUP(37, qup0_se2, qup0_se5, phase_flag, tgu_ch3, _, _, _, _, _),
|
||||||
|
[38] = PINGROUP(38, qup0_se5, qup0_se2, qdss_cti, phase_flag, tgu_ch4, _, _, _, _),
|
||||||
|
[39] = PINGROUP(39, qup0_se5, qup0_se2, qdss_cti, phase_flag, tgu_ch5, _, _, _, _),
|
||||||
|
[40] = PINGROUP(40, qup1_se0, qup1_se1, ibi_i3c, mdp1_vsync0, _, _, _, _, _),
|
||||||
|
[41] = PINGROUP(41, qup1_se0, qup1_se1, ibi_i3c, mdp1_vsync1, _, _, _, _, _),
|
||||||
|
[42] = PINGROUP(42, qup1_se1, qup1_se0, ibi_i3c, mdp1_vsync2, gcc_gp5, _, _, _, _),
|
||||||
|
[43] = PINGROUP(43, qup1_se1, qup1_se0, ibi_i3c, mdp1_vsync3, _, _, _, _, _),
|
||||||
|
[44] = PINGROUP(44, qup1_se2, qup1_se3, edp0_lcd, _, _, _, _, _, _),
|
||||||
|
[45] = PINGROUP(45, qup1_se2, qup1_se3, edp1_lcd, _, _, _, _, _, _),
|
||||||
|
[46] = PINGROUP(46, qup1_se3, qup1_se2, mdp1_vsync4, tgu_ch0, _, _, _, _, _),
|
||||||
|
[47] = PINGROUP(47, qup1_se3, qup1_se2, mdp1_vsync5, tgu_ch1, _, _, _, _, _),
|
||||||
|
[48] = PINGROUP(48, qup1_se4, qdss_cti, edp2_lcd, _, _, _, _, _, _),
|
||||||
|
[49] = PINGROUP(49, qup1_se4, qdss_cti, edp3_lcd, _, _, _, _, _, _),
|
||||||
|
[50] = PINGROUP(50, qup1_se4, cci_async, qdss_cti, mdp1_vsync8, _, _, _, _, _),
|
||||||
|
[51] = PINGROUP(51, qup1_se4, qdss_cti, mdp1_vsync6, gcc_gp1, _, _, _, _, _),
|
||||||
|
[52] = PINGROUP(52, qup1_se5, cci_timer4, cci_i2c, mdp1_vsync7, gcc_gp2, _, ddr_pxi1, _, _),
|
||||||
|
[53] = PINGROUP(53, qup1_se5, cci_timer5, cci_i2c, gcc_gp3, _, ddr_pxi1, _, _, _),
|
||||||
|
[54] = PINGROUP(54, qup1_se5, cci_timer6, cci_i2c, _, _, _, _, _, _),
|
||||||
|
[55] = PINGROUP(55, qup1_se5, cci_timer7, cci_i2c, gcc_gp4, _, ddr_pxi2, _, _, _),
|
||||||
|
[56] = PINGROUP(56, qup1_se6, qup1_se6, cci_timer8, cci_i2c, phase_flag, ddr_bist, _, _, _),
|
||||||
|
[57] = PINGROUP(57, qup1_se6, qup1_se6, cci_timer9, cci_i2c,
|
||||||
|
mdp0_vsync0, phase_flag, ddr_bist, _, _),
|
||||||
|
[58] = PINGROUP(58, cci_i2c, mdp0_vsync1, ddr_bist, _, atest_usb2, atest_char, _, _, _),
|
||||||
|
[59] = PINGROUP(59, cci_i2c, mdp0_vsync2, ddr_bist, _, atest_usb2, atest_char, _, _, _),
|
||||||
|
[60] = PINGROUP(60, cci_i2c, qdss_gpio, _, _, _, _, _, _, _),
|
||||||
|
[61] = PINGROUP(61, cci_i2c, qdss_gpio, _, _, _, _, _, _, _),
|
||||||
|
[62] = PINGROUP(62, cci_i2c, qdss_gpio, _, _, _, _, _, _, _),
|
||||||
|
[63] = PINGROUP(63, cci_i2c, qdss_gpio, _, _, _, _, _, _, _),
|
||||||
|
[64] = PINGROUP(64, cci_i2c, qdss_gpio, _, _, _, _, _, _, _),
|
||||||
|
[65] = PINGROUP(65, cci_i2c, qdss_gpio, _, _, _, _, _, _, _),
|
||||||
|
[66] = PINGROUP(66, cci_i2c, cci_async, qdss_gpio, _, _, _, _, _, _),
|
||||||
|
[67] = PINGROUP(67, cci_i2c, qdss_gpio, _, _, _, _, _, _, _),
|
||||||
|
[68] = PINGROUP(68, cci_timer0, cci_async, _, _, _, _, _, _, _),
|
||||||
|
[69] = PINGROUP(69, cci_timer1, cci_async, _, _, _, _, _, _, _),
|
||||||
|
[70] = PINGROUP(70, cci_timer2, cci_async, _, _, _, _, _, _, _),
|
||||||
|
[71] = PINGROUP(71, cci_timer3, cci_async, _, _, _, _, _, _, _),
|
||||||
|
[72] = PINGROUP(72, cam_mclk, _, _, _, _, _, _, _, _),
|
||||||
|
[73] = PINGROUP(73, cam_mclk, _, _, _, _, _, _, _, _),
|
||||||
|
[74] = PINGROUP(74, cam_mclk, _, _, _, _, _, _, _, _),
|
||||||
|
[75] = PINGROUP(75, cam_mclk, _, _, _, _, _, _, _, _),
|
||||||
|
[76] = PINGROUP(76, _, _, _, _, _, _, _, _, _),
|
||||||
|
[77] = PINGROUP(77, _, _, _, _, _, _, _, _, _),
|
||||||
|
[78] = PINGROUP(78, _, _, _, _, _, _, _, _, _),
|
||||||
|
[79] = PINGROUP(79, _, _, _, _, _, _, _, _, _),
|
||||||
|
[80] = PINGROUP(80, qup2_se0, ibi_i3c, mdp0_vsync3, _, _, _, _, _, _),
|
||||||
|
[81] = PINGROUP(81, qup2_se0, ibi_i3c, mdp0_vsync4, _, _, _, _, _, _),
|
||||||
|
[82] = PINGROUP(82, qup2_se0, mdp_vsync, gcc_gp1, _, _, _, _, _, _),
|
||||||
|
[83] = PINGROUP(83, qup2_se0, mdp_vsync, gcc_gp2, _, _, _, _, _, _),
|
||||||
|
[84] = PINGROUP(84, qup2_se1, qup2_se5, ibi_i3c, mdp_vsync, gcc_gp3, _, _, _, _),
|
||||||
|
[85] = PINGROUP(85, qup2_se1, qup2_se5, ibi_i3c, _, _, _, _, _, _),
|
||||||
|
[86] = PINGROUP(86, qup2_se2, jitter_bist, atest_usb2, ddr_pxi2, _, _, _, _, _),
|
||||||
|
[87] = PINGROUP(87, qup2_se2, pll_clk, atest_usb2, ddr_pxi3, _, _, _, _, _),
|
||||||
|
[88] = PINGROUP(88, qup2_se2, _, atest_usb2, ddr_pxi3, _, _, _, _, _),
|
||||||
|
[89] = PINGROUP(89, qup2_se2, _, atest_usb2, ddr_pxi4, atest_char, _, _, _, _),
|
||||||
|
[90] = PINGROUP(90, qup2_se2, _, atest_usb2, ddr_pxi4, atest_char, _, _, _, _),
|
||||||
|
[91] = PINGROUP(91, qup2_se3, mdp0_vsync5, _, atest_usb2, _, _, _, _, _),
|
||||||
|
[92] = PINGROUP(92, qup2_se3, mdp0_vsync6, _, atest_usb2, _, _, _, _, _),
|
||||||
|
[93] = PINGROUP(93, qup2_se3, mdp0_vsync7, _, atest_usb2, _, _, _, _, _),
|
||||||
|
[94] = PINGROUP(94, qup2_se3, mdp0_vsync8, _, atest_usb2, _, _, _, _, _),
|
||||||
|
[95] = PINGROUP(95, qup2_se4, qup2_se6, _, atest_usb2, _, _, _, _, _),
|
||||||
|
[96] = PINGROUP(96, qup2_se4, qup2_se6, _, atest_usb2, _, _, _, _, _),
|
||||||
|
[97] = PINGROUP(97, qup2_se6, qup2_se4, cri_trng0, _, atest_usb2, _, _, _, _),
|
||||||
|
[98] = PINGROUP(98, qup2_se6, qup2_se4, phase_flag, cri_trng1, _, _, _, _, _),
|
||||||
|
[99] = PINGROUP(99, qup2_se5, qup2_se1, phase_flag, cri_trng, _, _, _, _, _),
|
||||||
|
[100] = PINGROUP(100, qup2_se5, qup2_se1, _, _, _, _, _, _, _),
|
||||||
|
[101] = PINGROUP(101, edp0_hot, prng_rosc0, tsense_pwm4, _, _, _, _, _, _),
|
||||||
|
[102] = PINGROUP(102, edp1_hot, prng_rosc1, tsense_pwm3, _, _, _, _, _, _),
|
||||||
|
[103] = PINGROUP(103, edp3_hot, prng_rosc2, tsense_pwm2, _, _, _, _, _, _),
|
||||||
|
[104] = PINGROUP(104, edp2_hot, prng_rosc3, tsense_pwm1, _, _, _, _, _, _),
|
||||||
|
[105] = PINGROUP(105, mi2s_mclk0, _, qdss_gpio, atest_usb2, _, _, _, _, _),
|
||||||
|
[106] = PINGROUP(106, mi2s1_sck, phase_flag, _, qdss_gpio, _, _, _, _, _),
|
||||||
|
[107] = PINGROUP(107, mi2s1_ws, phase_flag, _, qdss_gpio, _, _, _, _, _),
|
||||||
|
[108] = PINGROUP(108, mi2s1_data0, phase_flag, _, qdss_gpio, _, _, _, _, _),
|
||||||
|
[109] = PINGROUP(109, mi2s1_data1, phase_flag, _, qdss_gpio, _, _, _, _, _),
|
||||||
|
[110] = PINGROUP(110, mi2s2_sck, phase_flag, _, qdss_gpio, _, _, _, _, _),
|
||||||
|
[111] = PINGROUP(111, mi2s2_ws, phase_flag, _, qdss_gpio, vsense_trigger, _, _, _, _),
|
||||||
|
[112] = PINGROUP(112, mi2s2_data0, phase_flag, _, qdss_gpio, _, _, _, _, _),
|
||||||
|
[113] = PINGROUP(113, mi2s2_data1, audio_ref, phase_flag, _, qdss_gpio, _, _, _, _),
|
||||||
|
[114] = PINGROUP(114, hs0_mi2s, pll_bist, phase_flag, _, qdss_gpio, _, _, _, _),
|
||||||
|
[115] = PINGROUP(115, hs0_mi2s, _, qdss_gpio, _, _, _, _, _, _),
|
||||||
|
[116] = PINGROUP(116, hs0_mi2s, _, qdss_gpio, _, _, _, _, _, _),
|
||||||
|
[117] = PINGROUP(117, hs0_mi2s, mi2s_mclk1, _, qdss_gpio, _, _, _, _, _),
|
||||||
|
[118] = PINGROUP(118, hs1_mi2s, _, qdss_gpio, ddr_pxi5, _, _, _, _, _),
|
||||||
|
[119] = PINGROUP(119, hs1_mi2s, _, qdss_gpio, ddr_pxi5, _, _, _, _, _),
|
||||||
|
[120] = PINGROUP(120, hs1_mi2s, phase_flag, _, qdss_gpio, _, _, _, _, _),
|
||||||
|
[121] = PINGROUP(121, hs1_mi2s, phase_flag, _, qdss_gpio, _, _, _, _, _),
|
||||||
|
[122] = PINGROUP(122, hs2_mi2s, phase_flag, _, qdss_gpio, _, _, _, _, _),
|
||||||
|
[123] = PINGROUP(123, hs2_mi2s, phase_flag, _, _, _, _, _, _, _),
|
||||||
|
[124] = PINGROUP(124, hs2_mi2s, phase_flag, _, _, _, _, _, _, _),
|
||||||
|
[125] = PINGROUP(125, hs2_mi2s, phase_flag, _, _, _, _, _, _, _),
|
||||||
|
[126] = PINGROUP(126, _, _, _, _, _, _, _, _, _),
|
||||||
|
[127] = PINGROUP(127, _, _, _, _, _, _, _, _, _),
|
||||||
|
[128] = PINGROUP(128, _, _, _, _, _, _, _, _, _),
|
||||||
|
[129] = PINGROUP(129, _, _, _, _, _, _, _, _, _),
|
||||||
|
[130] = PINGROUP(130, _, _, _, _, _, _, _, _, _),
|
||||||
|
[131] = PINGROUP(131, _, _, _, _, _, _, _, _, _),
|
||||||
|
[132] = PINGROUP(132, _, _, _, _, _, _, _, _, _),
|
||||||
|
[133] = PINGROUP(133, _, _, _, _, _, _, _, _, _),
|
||||||
|
[134] = PINGROUP(134, _, _, _, _, _, _, _, _, _),
|
||||||
|
[135] = PINGROUP(135, _, _, _, _, _, _, _, _, _),
|
||||||
|
[136] = PINGROUP(136, _, _, _, _, _, _, _, _, _),
|
||||||
|
[137] = PINGROUP(137, _, _, _, _, _, _, _, _, _),
|
||||||
|
[138] = PINGROUP(138, _, _, _, _, _, _, _, _, _),
|
||||||
|
[139] = PINGROUP(139, _, _, _, _, _, _, _, _, _),
|
||||||
|
[140] = PINGROUP(140, _, _, _, _, _, _, _, _, _),
|
||||||
|
[141] = PINGROUP(141, _, _, _, _, _, _, _, _, _),
|
||||||
|
[142] = PINGROUP(142, _, _, _, _, _, _, _, _, _),
|
||||||
|
[143] = PINGROUP(143, _, _, _, _, _, _, _, _, _),
|
||||||
|
[144] = PINGROUP(144, dbg_out, _, _, _, _, _, _, _, _),
|
||||||
|
[145] = PINGROUP(145, _, _, _, _, _, _, _, _, _),
|
||||||
|
[146] = PINGROUP(146, _, _, _, _, _, _, _, _, _),
|
||||||
|
[147] = PINGROUP(147, _, _, _, _, _, _, _, _, _),
|
||||||
|
[148] = PINGROUP(148, _, _, _, _, _, _, _, _, _),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct msm_special_pin_data msm_special_pins_data[] = {
|
||||||
|
[0] = UFS_RESET("ufs_reset", 0x1a2000),
|
||||||
|
[1] = SDC_QDSD_PINGROUP("sdc1_rclk", 0x199000, 15, 0),
|
||||||
|
[2] = SDC_QDSD_PINGROUP("sdc1_clk", 0x199000, 13, 6),
|
||||||
|
[3] = SDC_QDSD_PINGROUP("sdc1_cmd", 0x199000, 11, 3),
|
||||||
|
[4] = SDC_QDSD_PINGROUP("sdc1_data", 0x199000, 9, 0),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *sa8775p_get_function_name(struct udevice *dev,
|
||||||
|
unsigned int selector)
|
||||||
|
{
|
||||||
|
return msm_pinctrl_functions[selector].name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *sa8775p_get_pin_name(struct udevice *dev,
|
||||||
|
unsigned int selector)
|
||||||
|
{
|
||||||
|
if (selector >= 149 && selector <= 155)
|
||||||
|
snprintf(pin_name, MAX_PIN_NAME_LEN,
|
||||||
|
msm_special_pins_data[selector - 149].name);
|
||||||
|
else
|
||||||
|
snprintf(pin_name, MAX_PIN_NAME_LEN, "gpio%u", selector);
|
||||||
|
|
||||||
|
return pin_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sa8775p_get_function_mux(__maybe_unused unsigned int pin,
|
||||||
|
unsigned int selector)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
const msm_pin_function *func = sa8775p_pin_functions + pin;
|
||||||
|
|
||||||
|
for (i = 0; i < 10; i++)
|
||||||
|
if ((*func)[i] == selector)
|
||||||
|
return i;
|
||||||
|
|
||||||
|
pr_err("Can't find requested function for pin %u pin\n", pin);
|
||||||
|
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const unsigned int sa8775p_pin_offsets[] = {
|
||||||
|
[0] = SA8775_PIN_OFFSET, [1] = SA8775_PIN_OFFSET, [2] = SA8775_PIN_OFFSET,
|
||||||
|
[3] = SA8775_PIN_OFFSET, [4] = SA8775_PIN_OFFSET, [5] = SA8775_PIN_OFFSET,
|
||||||
|
[6] = SA8775_PIN_OFFSET, [7] = SA8775_PIN_OFFSET, [8] = SA8775_PIN_OFFSET,
|
||||||
|
[9] = SA8775_PIN_OFFSET, [10] = SA8775_PIN_OFFSET, [11] = SA8775_PIN_OFFSET,
|
||||||
|
[12] = SA8775_PIN_OFFSET, [13] = SA8775_PIN_OFFSET, [14] = SA8775_PIN_OFFSET,
|
||||||
|
[15] = SA8775_PIN_OFFSET, [16] = SA8775_PIN_OFFSET, [17] = SA8775_PIN_OFFSET,
|
||||||
|
[18] = SA8775_PIN_OFFSET, [19] = SA8775_PIN_OFFSET, [20] = SA8775_PIN_OFFSET,
|
||||||
|
[21] = SA8775_PIN_OFFSET, [22] = SA8775_PIN_OFFSET, [23] = SA8775_PIN_OFFSET,
|
||||||
|
[24] = SA8775_PIN_OFFSET, [25] = SA8775_PIN_OFFSET, [26] = SA8775_PIN_OFFSET,
|
||||||
|
[27] = SA8775_PIN_OFFSET, [28] = SA8775_PIN_OFFSET, [29] = SA8775_PIN_OFFSET,
|
||||||
|
[30] = SA8775_PIN_OFFSET, [31] = SA8775_PIN_OFFSET, [32] = SA8775_PIN_OFFSET,
|
||||||
|
[33] = SA8775_PIN_OFFSET, [34] = SA8775_PIN_OFFSET, [35] = SA8775_PIN_OFFSET,
|
||||||
|
[36] = SA8775_PIN_OFFSET, [37] = SA8775_PIN_OFFSET, [38] = SA8775_PIN_OFFSET,
|
||||||
|
[39] = SA8775_PIN_OFFSET, [40] = SA8775_PIN_OFFSET, [41] = SA8775_PIN_OFFSET,
|
||||||
|
[42] = SA8775_PIN_OFFSET, [43] = SA8775_PIN_OFFSET, [44] = SA8775_PIN_OFFSET,
|
||||||
|
[45] = SA8775_PIN_OFFSET, [46] = SA8775_PIN_OFFSET, [47] = SA8775_PIN_OFFSET,
|
||||||
|
[48] = SA8775_PIN_OFFSET, [49] = SA8775_PIN_OFFSET, [50] = SA8775_PIN_OFFSET,
|
||||||
|
[51] = SA8775_PIN_OFFSET, [52] = SA8775_PIN_OFFSET, [53] = SA8775_PIN_OFFSET,
|
||||||
|
[54] = SA8775_PIN_OFFSET, [55] = SA8775_PIN_OFFSET, [56] = SA8775_PIN_OFFSET,
|
||||||
|
[57] = SA8775_PIN_OFFSET, [58] = SA8775_PIN_OFFSET, [59] = SA8775_PIN_OFFSET,
|
||||||
|
[60] = SA8775_PIN_OFFSET, [61] = SA8775_PIN_OFFSET, [62] = SA8775_PIN_OFFSET,
|
||||||
|
[63] = SA8775_PIN_OFFSET, [64] = SA8775_PIN_OFFSET, [65] = SA8775_PIN_OFFSET,
|
||||||
|
[66] = SA8775_PIN_OFFSET, [67] = SA8775_PIN_OFFSET, [68] = SA8775_PIN_OFFSET,
|
||||||
|
[69] = SA8775_PIN_OFFSET, [70] = SA8775_PIN_OFFSET, [71] = SA8775_PIN_OFFSET,
|
||||||
|
[72] = SA8775_PIN_OFFSET, [73] = SA8775_PIN_OFFSET, [74] = SA8775_PIN_OFFSET,
|
||||||
|
[75] = SA8775_PIN_OFFSET, [76] = SA8775_PIN_OFFSET, [77] = SA8775_PIN_OFFSET,
|
||||||
|
[78] = SA8775_PIN_OFFSET, [79] = SA8775_PIN_OFFSET, [80] = SA8775_PIN_OFFSET,
|
||||||
|
[81] = SA8775_PIN_OFFSET, [82] = SA8775_PIN_OFFSET, [83] = SA8775_PIN_OFFSET,
|
||||||
|
[84] = SA8775_PIN_OFFSET, [85] = SA8775_PIN_OFFSET, [86] = SA8775_PIN_OFFSET,
|
||||||
|
[87] = SA8775_PIN_OFFSET, [88] = SA8775_PIN_OFFSET, [89] = SA8775_PIN_OFFSET,
|
||||||
|
[90] = SA8775_PIN_OFFSET, [91] = SA8775_PIN_OFFSET, [92] = SA8775_PIN_OFFSET,
|
||||||
|
[93] = SA8775_PIN_OFFSET, [94] = SA8775_PIN_OFFSET, [95] = SA8775_PIN_OFFSET,
|
||||||
|
[96] = SA8775_PIN_OFFSET, [97] = SA8775_PIN_OFFSET, [98] = SA8775_PIN_OFFSET,
|
||||||
|
[99] = SA8775_PIN_OFFSET, [100] = SA8775_PIN_OFFSET, [101] = SA8775_PIN_OFFSET,
|
||||||
|
[102] = SA8775_PIN_OFFSET, [103] = SA8775_PIN_OFFSET, [104] = SA8775_PIN_OFFSET,
|
||||||
|
[105] = SA8775_PIN_OFFSET, [106] = SA8775_PIN_OFFSET, [107] = SA8775_PIN_OFFSET,
|
||||||
|
[108] = SA8775_PIN_OFFSET, [109] = SA8775_PIN_OFFSET, [110] = SA8775_PIN_OFFSET,
|
||||||
|
[111] = SA8775_PIN_OFFSET, [112] = SA8775_PIN_OFFSET, [113] = SA8775_PIN_OFFSET,
|
||||||
|
[114] = SA8775_PIN_OFFSET, [115] = SA8775_PIN_OFFSET, [116] = SA8775_PIN_OFFSET,
|
||||||
|
[117] = SA8775_PIN_OFFSET, [118] = SA8775_PIN_OFFSET, [119] = SA8775_PIN_OFFSET,
|
||||||
|
[120] = SA8775_PIN_OFFSET, [121] = SA8775_PIN_OFFSET, [122] = SA8775_PIN_OFFSET,
|
||||||
|
[123] = SA8775_PIN_OFFSET, [124] = SA8775_PIN_OFFSET, [125] = SA8775_PIN_OFFSET,
|
||||||
|
[126] = SA8775_PIN_OFFSET, [127] = SA8775_PIN_OFFSET, [128] = SA8775_PIN_OFFSET,
|
||||||
|
[129] = SA8775_PIN_OFFSET, [130] = SA8775_PIN_OFFSET, [131] = SA8775_PIN_OFFSET,
|
||||||
|
[132] = SA8775_PIN_OFFSET, [133] = SA8775_PIN_OFFSET, [134] = SA8775_PIN_OFFSET,
|
||||||
|
[135] = SA8775_PIN_OFFSET, [136] = SA8775_PIN_OFFSET, [137] = SA8775_PIN_OFFSET,
|
||||||
|
[138] = SA8775_PIN_OFFSET, [139] = SA8775_PIN_OFFSET, [140] = SA8775_PIN_OFFSET,
|
||||||
|
[141] = SA8775_PIN_OFFSET, [142] = SA8775_PIN_OFFSET, [143] = SA8775_PIN_OFFSET,
|
||||||
|
[144] = SA8775_PIN_OFFSET, [145] = SA8775_PIN_OFFSET, [146] = SA8775_PIN_OFFSET,
|
||||||
|
[147] = SA8775_PIN_OFFSET, [148] = SA8775_PIN_OFFSET, [148] = SA8775_PIN_OFFSET,
|
||||||
|
[149] = SA8775_PIN_OFFSET, [150] = SA8775_PIN_OFFSET, [151] = SA8775_PIN_OFFSET,
|
||||||
|
[152] = SA8775_PIN_OFFSET, [153] = SA8775_PIN_OFFSET, [154] = SA8775_PIN_OFFSET,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct msm_pinctrl_data sa8775p_data = {
|
||||||
|
.pin_data = {
|
||||||
|
.pin_count = 155,
|
||||||
|
.special_pins_start = 149,
|
||||||
|
.special_pins_data = msm_special_pins_data,
|
||||||
|
.pin_offsets = sa8775p_pin_offsets,
|
||||||
|
},
|
||||||
|
.functions_count = ARRAY_SIZE(msm_pinctrl_functions),
|
||||||
|
.get_function_name = sa8775p_get_function_name,
|
||||||
|
.get_function_mux = sa8775p_get_function_mux,
|
||||||
|
.get_pin_name = sa8775p_get_pin_name,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct udevice_id msm_pinctrl_ids[] = {
|
||||||
|
{ .compatible = "qcom,sa8775p-tlmm", .data = (ulong)&sa8775p_data },
|
||||||
|
{ /* Sentinal */ }
|
||||||
|
};
|
||||||
|
|
||||||
|
U_BOOT_DRIVER(pinctrl_sa8775p) = {
|
||||||
|
.name = "pinctrl_sa8775p",
|
||||||
|
.id = UCLASS_NOP,
|
||||||
|
.of_match = msm_pinctrl_ids,
|
||||||
|
.ops = &msm_pinctrl_ops,
|
||||||
|
.bind = msm_pinctrl_bind,
|
||||||
|
.flags = DM_FLAG_PRE_RELOC,
|
||||||
|
};
|
226
drivers/pinctrl/qcom/pinctrl-sdm660.c
Normal file
226
drivers/pinctrl/qcom/pinctrl-sdm660.c
Normal file
|
@ -0,0 +1,226 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
/*
|
||||||
|
* Qualcomm SDM630/660 TLMM pinctrl
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <dm.h>
|
||||||
|
#include "pinctrl-qcom.h"
|
||||||
|
|
||||||
|
#define TLMM_BASE 0x03100000
|
||||||
|
#define SOUTH (0x03100000 - TLMM_BASE) /* 0x0 */
|
||||||
|
#define CENTER (0x03500000 - TLMM_BASE) /* 0x400000 */
|
||||||
|
#define NORTH (0x03900000 - TLMM_BASE) /* 0x800000 */
|
||||||
|
|
||||||
|
#define MAX_PIN_NAME_LEN 32
|
||||||
|
static char pin_name[MAX_PIN_NAME_LEN] __section(".data");
|
||||||
|
|
||||||
|
static const struct pinctrl_function sdm660_pinctrl_functions[] = {
|
||||||
|
{ "gpio", 0 },
|
||||||
|
{ "blsp_uart2", 3 }, /* gpio 4 and 5, used for debug uart */
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned int sdm660_pin_offsets[] = {
|
||||||
|
[0] = SOUTH,
|
||||||
|
[1] = SOUTH,
|
||||||
|
[2] = SOUTH,
|
||||||
|
[3] = SOUTH,
|
||||||
|
[4] = NORTH,
|
||||||
|
[5] = SOUTH,
|
||||||
|
[6] = SOUTH,
|
||||||
|
[7] = SOUTH,
|
||||||
|
[8] = NORTH,
|
||||||
|
[9] = NORTH,
|
||||||
|
[10] = NORTH,
|
||||||
|
[11] = NORTH,
|
||||||
|
[12] = NORTH,
|
||||||
|
[13] = NORTH,
|
||||||
|
[14] = NORTH,
|
||||||
|
[15] = NORTH,
|
||||||
|
[16] = CENTER,
|
||||||
|
[17] = CENTER,
|
||||||
|
[18] = CENTER,
|
||||||
|
[19] = CENTER,
|
||||||
|
[20] = SOUTH,
|
||||||
|
[21] = SOUTH,
|
||||||
|
[22] = CENTER,
|
||||||
|
[23] = CENTER,
|
||||||
|
[24] = NORTH,
|
||||||
|
[25] = NORTH,
|
||||||
|
[26] = NORTH,
|
||||||
|
[27] = NORTH,
|
||||||
|
[28] = CENTER,
|
||||||
|
[29] = CENTER,
|
||||||
|
[30] = CENTER,
|
||||||
|
[31] = CENTER,
|
||||||
|
[32] = SOUTH,
|
||||||
|
[33] = SOUTH,
|
||||||
|
[34] = SOUTH,
|
||||||
|
[35] = SOUTH,
|
||||||
|
[36] = SOUTH,
|
||||||
|
[37] = SOUTH,
|
||||||
|
[38] = SOUTH,
|
||||||
|
[39] = SOUTH,
|
||||||
|
[40] = SOUTH,
|
||||||
|
[41] = SOUTH,
|
||||||
|
[42] = SOUTH,
|
||||||
|
[43] = SOUTH,
|
||||||
|
[44] = SOUTH,
|
||||||
|
[45] = SOUTH,
|
||||||
|
[46] = SOUTH,
|
||||||
|
[47] = SOUTH,
|
||||||
|
[48] = SOUTH,
|
||||||
|
[49] = SOUTH,
|
||||||
|
[50] = SOUTH,
|
||||||
|
[51] = SOUTH,
|
||||||
|
[52] = SOUTH,
|
||||||
|
[53] = NORTH,
|
||||||
|
[54] = NORTH,
|
||||||
|
[55] = SOUTH,
|
||||||
|
[56] = SOUTH,
|
||||||
|
[57] = SOUTH,
|
||||||
|
[58] = SOUTH,
|
||||||
|
[59] = NORTH,
|
||||||
|
[60] = NORTH,
|
||||||
|
[61] = NORTH,
|
||||||
|
[62] = NORTH,
|
||||||
|
[63] = NORTH,
|
||||||
|
[64] = SOUTH,
|
||||||
|
[65] = SOUTH,
|
||||||
|
[66] = NORTH,
|
||||||
|
[67] = NORTH,
|
||||||
|
[68] = NORTH,
|
||||||
|
[69] = NORTH,
|
||||||
|
[70] = NORTH,
|
||||||
|
[71] = NORTH,
|
||||||
|
[72] = NORTH,
|
||||||
|
[73] = NORTH,
|
||||||
|
[74] = NORTH,
|
||||||
|
[75] = NORTH,
|
||||||
|
[76] = NORTH,
|
||||||
|
[77] = NORTH,
|
||||||
|
[78] = NORTH,
|
||||||
|
[79] = SOUTH,
|
||||||
|
[80] = SOUTH,
|
||||||
|
[81] = CENTER,
|
||||||
|
[82] = CENTER,
|
||||||
|
[83] = SOUTH,
|
||||||
|
[84] = SOUTH,
|
||||||
|
[85] = SOUTH,
|
||||||
|
[86] = SOUTH,
|
||||||
|
[87] = SOUTH,
|
||||||
|
[88] = SOUTH,
|
||||||
|
[89] = SOUTH,
|
||||||
|
[90] = SOUTH,
|
||||||
|
[91] = SOUTH,
|
||||||
|
[92] = SOUTH,
|
||||||
|
[93] = SOUTH,
|
||||||
|
[94] = SOUTH,
|
||||||
|
[95] = SOUTH,
|
||||||
|
[96] = SOUTH,
|
||||||
|
[97] = SOUTH,
|
||||||
|
[98] = SOUTH,
|
||||||
|
[99] = SOUTH,
|
||||||
|
[100] = SOUTH,
|
||||||
|
[101] = SOUTH,
|
||||||
|
[102] = SOUTH,
|
||||||
|
[103] = SOUTH,
|
||||||
|
[104] = SOUTH,
|
||||||
|
[105] = SOUTH,
|
||||||
|
[106] = SOUTH,
|
||||||
|
[107] = SOUTH,
|
||||||
|
[108] = SOUTH,
|
||||||
|
[109] = SOUTH,
|
||||||
|
[110] = SOUTH,
|
||||||
|
[111] = SOUTH,
|
||||||
|
[112] = SOUTH,
|
||||||
|
[113] = SOUTH,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Special pins - eMMC/SD related: [114..120], in total 7 special pins
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SDC_QDSD_PINGROUP(pg_name, ctl, pull, drv) \
|
||||||
|
{ \
|
||||||
|
.name = pg_name, \
|
||||||
|
.ctl_reg = ctl, \
|
||||||
|
.io_reg = 0, \
|
||||||
|
.pull_bit = pull, \
|
||||||
|
.drv_bit = drv, \
|
||||||
|
.oe_bit = -1, \
|
||||||
|
.in_bit = -1, \
|
||||||
|
.out_bit = -1, \
|
||||||
|
}
|
||||||
|
|
||||||
|
/* All SDC pins are in the NORTH tile */
|
||||||
|
static const struct msm_special_pin_data sdm660_special_pins_data[] = {
|
||||||
|
SDC_QDSD_PINGROUP("sdc1_clk", NORTH + 0x9a000, 13, 6),
|
||||||
|
SDC_QDSD_PINGROUP("sdc1_cmd", NORTH + 0x9a000, 11, 3),
|
||||||
|
SDC_QDSD_PINGROUP("sdc1_data", NORTH + 0x9a000, 9, 0),
|
||||||
|
SDC_QDSD_PINGROUP("sdc2_clk", NORTH + 0x9b000, 14, 6),
|
||||||
|
SDC_QDSD_PINGROUP("sdc2_cmd", NORTH + 0x9b000, 11, 3),
|
||||||
|
SDC_QDSD_PINGROUP("sdc2_data", NORTH + 0x9b000, 9, 0),
|
||||||
|
SDC_QDSD_PINGROUP("sdc1_rclk", NORTH + 0x9a000, 15, 0),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *sdm660_get_function_name(struct udevice *dev, unsigned int selector)
|
||||||
|
{
|
||||||
|
return sdm660_pinctrl_functions[selector].name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *sdm660_get_pin_name(struct udevice *dev, unsigned int selector)
|
||||||
|
{
|
||||||
|
static const char * const special_pins_names[] = {
|
||||||
|
"sdc1_clk", "sdc1_cmd", "sdc1_data",
|
||||||
|
"sdc2_clk", "sdc2_cmd", "sdc2_data",
|
||||||
|
"sdc1_rclk"
|
||||||
|
};
|
||||||
|
|
||||||
|
if (selector >= 114 && selector <= 120)
|
||||||
|
snprintf(pin_name, MAX_PIN_NAME_LEN, special_pins_names[selector - 114]);
|
||||||
|
else
|
||||||
|
snprintf(pin_name, MAX_PIN_NAME_LEN, "gpio%u", selector);
|
||||||
|
|
||||||
|
return pin_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sdm660_get_function_mux(__maybe_unused unsigned int pin, unsigned int selector)
|
||||||
|
{
|
||||||
|
if (selector >= 0 && selector < ARRAY_SIZE(sdm660_pinctrl_functions))
|
||||||
|
return sdm660_pinctrl_functions[selector].val;
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct msm_pinctrl_data sdm660_data = {
|
||||||
|
.pin_data = {
|
||||||
|
.pin_offsets = sdm660_pin_offsets,
|
||||||
|
.pin_count = ARRAY_SIZE(sdm660_pin_offsets) + ARRAY_SIZE(sdm660_special_pins_data),
|
||||||
|
.special_pins_start = 114,
|
||||||
|
.special_pins_data = sdm660_special_pins_data,
|
||||||
|
},
|
||||||
|
.functions_count = ARRAY_SIZE(sdm660_pinctrl_functions),
|
||||||
|
.get_function_name = sdm660_get_function_name,
|
||||||
|
.get_function_mux = sdm660_get_function_mux,
|
||||||
|
.get_pin_name = sdm660_get_pin_name,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct udevice_id msm_pinctrl_ids[] = {
|
||||||
|
{
|
||||||
|
.compatible = "qcom,sdm630-pinctrl",
|
||||||
|
.data = (ulong)&sdm660_data
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.compatible = "qcom,sdm660-pinctrl",
|
||||||
|
.data = (ulong)&sdm660_data
|
||||||
|
},
|
||||||
|
{ /* Sentinel */ }
|
||||||
|
};
|
||||||
|
|
||||||
|
U_BOOT_DRIVER(pinctrl_ssdm660) = {
|
||||||
|
.name = "pinctrl_sdm660",
|
||||||
|
.id = UCLASS_NOP,
|
||||||
|
.of_match = msm_pinctrl_ids,
|
||||||
|
.ops = &msm_pinctrl_ops,
|
||||||
|
.bind = msm_pinctrl_bind,
|
||||||
|
};
|
|
@ -224,6 +224,13 @@ config DM_REGULATOR_QCOM_RPMH
|
||||||
implements get/set api for a limited set of regulators used
|
implements get/set api for a limited set of regulators used
|
||||||
by u-boot.
|
by u-boot.
|
||||||
|
|
||||||
|
config DM_REGULATOR_QCOM_USB_VBUS
|
||||||
|
bool "Enable driver model for Qualcomm USB vbus regulator"
|
||||||
|
depends on DM_REGULATOR
|
||||||
|
---help---
|
||||||
|
Enable support for the Qualcomm USB Vbus regulator. The driver
|
||||||
|
implements get/set api for the regulator to be used by u-boot.
|
||||||
|
|
||||||
config SPL_DM_REGULATOR_GPIO
|
config SPL_DM_REGULATOR_GPIO
|
||||||
bool "Enable Driver Model for GPIO REGULATOR in SPL"
|
bool "Enable Driver Model for GPIO REGULATOR in SPL"
|
||||||
depends on DM_REGULATOR_GPIO && SPL_GPIO
|
depends on DM_REGULATOR_GPIO && SPL_GPIO
|
||||||
|
|
|
@ -22,6 +22,7 @@ obj-$(CONFIG_$(XPL_)DM_REGULATOR_COMMON) += regulator_common.o
|
||||||
obj-$(CONFIG_$(XPL_)DM_REGULATOR_FIXED) += fixed.o
|
obj-$(CONFIG_$(XPL_)DM_REGULATOR_FIXED) += fixed.o
|
||||||
obj-$(CONFIG_$(XPL_)DM_REGULATOR_GPIO) += gpio-regulator.o
|
obj-$(CONFIG_$(XPL_)DM_REGULATOR_GPIO) += gpio-regulator.o
|
||||||
obj-$(CONFIG_DM_REGULATOR_QCOM_RPMH) += qcom-rpmh-regulator.o
|
obj-$(CONFIG_DM_REGULATOR_QCOM_RPMH) += qcom-rpmh-regulator.o
|
||||||
|
obj-$(CONFIG_DM_REGULATOR_QCOM_USB_VBUS) += qcom_usb_vbus_regulator.o
|
||||||
obj-$(CONFIG_$(PHASE_)REGULATOR_RK8XX) += rk8xx.o
|
obj-$(CONFIG_$(PHASE_)REGULATOR_RK8XX) += rk8xx.o
|
||||||
obj-$(CONFIG_DM_REGULATOR_S2MPS11) += s2mps11_regulator.o
|
obj-$(CONFIG_DM_REGULATOR_S2MPS11) += s2mps11_regulator.o
|
||||||
obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
|
obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
|
||||||
|
|
|
@ -466,6 +466,25 @@ static const struct rpmh_vreg_hw_data pmic5_nldo515 = {
|
||||||
.n_modes = ARRAY_SIZE(pmic_mode_map_pmic5_ldo),
|
.n_modes = ARRAY_SIZE(pmic_mode_map_pmic5_ldo),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct rpmh_vreg_hw_data pmic5_ftsmps527 = {
|
||||||
|
.regulator_type = VRM,
|
||||||
|
.ops = &rpmh_regulator_vrm_drms_ops,
|
||||||
|
.voltage_range = REGULATOR_LINEAR_RANGE(320000, 0, 215, 8000),
|
||||||
|
.n_voltages = 215,
|
||||||
|
.pmic_mode_map = pmic_mode_map_pmic5_smps,
|
||||||
|
.n_modes = ARRAY_SIZE(pmic_mode_map_pmic5_smps),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct rpmh_vreg_hw_data pmic5_pldo515_mv = {
|
||||||
|
.regulator_type = VRM,
|
||||||
|
.ops = &rpmh_regulator_vrm_drms_ops,
|
||||||
|
.voltage_range = REGULATOR_LINEAR_RANGE(1800000, 0, 187, 8000),
|
||||||
|
.n_voltages = 188,
|
||||||
|
.hpm_min_load_uA = 10000,
|
||||||
|
.pmic_mode_map = pmic_mode_map_pmic5_ldo,
|
||||||
|
.n_modes = ARRAY_SIZE(pmic_mode_map_pmic5_ldo),
|
||||||
|
};
|
||||||
|
|
||||||
#define RPMH_VREG(_name, _resource_name, _hw_data, _supply_name) \
|
#define RPMH_VREG(_name, _resource_name, _hw_data, _supply_name) \
|
||||||
{ \
|
{ \
|
||||||
.name = _name, \
|
.name = _name, \
|
||||||
|
@ -558,6 +577,28 @@ static const struct rpmh_vreg_init_data pmc8380_vreg_data[] = {
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct rpmh_vreg_init_data pmm8654au_vreg_data[] = {
|
||||||
|
RPMH_VREG("smps1", "smp%s1", &pmic5_ftsmps527, "vdd-s1"),
|
||||||
|
RPMH_VREG("smps2", "smp%s2", &pmic5_ftsmps527, "vdd-s2"),
|
||||||
|
RPMH_VREG("smps3", "smp%s3", &pmic5_ftsmps527, "vdd-s3"),
|
||||||
|
RPMH_VREG("smps4", "smp%s4", &pmic5_ftsmps527, "vdd-s4"),
|
||||||
|
RPMH_VREG("smps5", "smp%s5", &pmic5_ftsmps527, "vdd-s5"),
|
||||||
|
RPMH_VREG("smps6", "smp%s6", &pmic5_ftsmps527, "vdd-s6"),
|
||||||
|
RPMH_VREG("smps7", "smp%s7", &pmic5_ftsmps527, "vdd-s7"),
|
||||||
|
RPMH_VREG("smps8", "smp%s8", &pmic5_ftsmps527, "vdd-s8"),
|
||||||
|
RPMH_VREG("smps9", "smp%s9", &pmic5_ftsmps527, "vdd-s9"),
|
||||||
|
RPMH_VREG("ldo1", "ldo%s1", &pmic5_nldo515, "vdd-s9"),
|
||||||
|
RPMH_VREG("ldo2", "ldo%s2", &pmic5_nldo515, "vdd-l2-l3"),
|
||||||
|
RPMH_VREG("ldo3", "ldo%s3", &pmic5_nldo515, "vdd-l2-l3"),
|
||||||
|
RPMH_VREG("ldo4", "ldo%s4", &pmic5_nldo515, "vdd-s9"),
|
||||||
|
RPMH_VREG("ldo5", "ldo%s5", &pmic5_nldo515, "vdd-s9"),
|
||||||
|
RPMH_VREG("ldo6", "ldo%s6", &pmic5_nldo515, "vdd-l6-l7"),
|
||||||
|
RPMH_VREG("ldo7", "ldo%s7", &pmic5_nldo515, "vdd-l6-l7"),
|
||||||
|
RPMH_VREG("ldo8", "ldo%s8", &pmic5_pldo515_mv, "vdd-l8-l9"),
|
||||||
|
RPMH_VREG("ldo9", "ldo%s9", &pmic5_pldo, "vdd-l8-l9"),
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
/* probe an individual regulator */
|
/* probe an individual regulator */
|
||||||
static int rpmh_regulator_probe(struct udevice *dev)
|
static int rpmh_regulator_probe(struct udevice *dev)
|
||||||
{
|
{
|
||||||
|
@ -688,6 +729,10 @@ static const struct udevice_id rpmh_regulator_ids[] = {
|
||||||
.compatible = "qcom,pmc8380-rpmh-regulators",
|
.compatible = "qcom,pmc8380-rpmh-regulators",
|
||||||
.data = (ulong)pmc8380_vreg_data,
|
.data = (ulong)pmc8380_vreg_data,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.compatible = "qcom,pmm8654au-rpmh-regulators",
|
||||||
|
.data = (ulong)pmm8654au_vreg_data,
|
||||||
|
},
|
||||||
{ /* sentinal */ },
|
{ /* sentinal */ },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
111
drivers/power/regulator/qcom_usb_vbus_regulator.c
Normal file
111
drivers/power/regulator/qcom_usb_vbus_regulator.c
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Linaro Limited
|
||||||
|
*/
|
||||||
|
#define pr_fmt(fmt) "qcom_usb_vbus: " fmt
|
||||||
|
|
||||||
|
#include <bitfield.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <dm.h>
|
||||||
|
#include <fdtdec.h>
|
||||||
|
#include <log.h>
|
||||||
|
#include <asm/gpio.h>
|
||||||
|
#include <linux/bitops.h>
|
||||||
|
#include <linux/printk.h>
|
||||||
|
#include <power/pmic.h>
|
||||||
|
#include <power/regulator.h>
|
||||||
|
|
||||||
|
#define CMD_OTG 0x50
|
||||||
|
#define OTG_EN BIT(0)
|
||||||
|
// The 0 bit in this register's bit field is undocumented
|
||||||
|
#define OTG_CFG 0x56
|
||||||
|
#define OTG_EN_SRC_CFG BIT(1)
|
||||||
|
|
||||||
|
struct qcom_usb_vbus_priv {
|
||||||
|
phys_addr_t base;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int qcom_usb_vbus_regulator_of_to_plat(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct qcom_usb_vbus_priv *priv = dev_get_priv(dev);
|
||||||
|
|
||||||
|
priv->base = dev_read_addr(dev);
|
||||||
|
if (priv->base == FDT_ADDR_T_NONE)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int qcom_usb_vbus_regulator_get_enable(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct qcom_usb_vbus_priv *priv = dev_get_priv(dev);
|
||||||
|
int otg_en_reg = priv->base + CMD_OTG;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = pmic_reg_read(dev->parent, otg_en_reg);
|
||||||
|
if (ret < 0)
|
||||||
|
log_err("failed to read usb vbus: %d\n", ret);
|
||||||
|
else
|
||||||
|
ret &= OTG_EN;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int qcom_usb_vbus_regulator_set_enable(struct udevice *dev, bool enable)
|
||||||
|
{
|
||||||
|
struct qcom_usb_vbus_priv *priv = dev_get_priv(dev);
|
||||||
|
int otg_en_reg = priv->base + CMD_OTG;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (enable) {
|
||||||
|
ret = pmic_clrsetbits(dev->parent, otg_en_reg, 0, OTG_EN);
|
||||||
|
if (ret < 0) {
|
||||||
|
log_err("error enabling: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ret = pmic_clrsetbits(dev->parent, otg_en_reg, OTG_EN, 0);
|
||||||
|
if (ret < 0) {
|
||||||
|
log_err("error disabling: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int qcom_usb_vbus_regulator_probe(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct qcom_usb_vbus_priv *priv = dev_get_priv(dev);
|
||||||
|
int otg_cfg_reg = priv->base + OTG_CFG;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Disable HW logic for VBUS enable */
|
||||||
|
ret = pmic_clrsetbits(dev->parent, otg_cfg_reg, OTG_EN_SRC_CFG, 0);
|
||||||
|
if (ret < 0) {
|
||||||
|
log_err("error setting EN_SRC_CFG: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct dm_regulator_ops qcom_usb_vbus_regulator_ops = {
|
||||||
|
.get_enable = qcom_usb_vbus_regulator_get_enable,
|
||||||
|
.set_enable = qcom_usb_vbus_regulator_set_enable,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct udevice_id qcom_usb_vbus_regulator_ids[] = {
|
||||||
|
{ .compatible = "qcom,pm8150b-vbus-reg"},
|
||||||
|
{ },
|
||||||
|
};
|
||||||
|
|
||||||
|
U_BOOT_DRIVER(qcom_usb_vbus_regulator) = {
|
||||||
|
.name = "qcom-usb-vbus-regulator",
|
||||||
|
.id = UCLASS_REGULATOR,
|
||||||
|
.of_match = qcom_usb_vbus_regulator_ids,
|
||||||
|
.of_to_plat = qcom_usb_vbus_regulator_of_to_plat,
|
||||||
|
.ops = &qcom_usb_vbus_regulator_ops,
|
||||||
|
.probe = qcom_usb_vbus_regulator_probe,
|
||||||
|
.priv_auto = sizeof(struct qcom_usb_vbus_priv),
|
||||||
|
};
|
|
@ -24,6 +24,9 @@ DECLARE_GLOBAL_DATA_PTR;
|
||||||
#define PMIC_ARB_VERSION_V5_MIN 0x50000000
|
#define PMIC_ARB_VERSION_V5_MIN 0x50000000
|
||||||
#define PMIC_ARB_VERSION_V7_MIN 0x70000000
|
#define PMIC_ARB_VERSION_V7_MIN 0x70000000
|
||||||
|
|
||||||
|
#define PMIC_ARB_FEATURES 0x0004
|
||||||
|
#define PMIC_ARB_FEATURES_PERIPH_MASK GENMASK(10, 0)
|
||||||
|
|
||||||
#define APID_MAP_OFFSET_V1_V2_V3 (0x800)
|
#define APID_MAP_OFFSET_V1_V2_V3 (0x800)
|
||||||
#define APID_MAP_OFFSET_V5 (0x900)
|
#define APID_MAP_OFFSET_V5 (0x900)
|
||||||
#define APID_MAP_OFFSET_V7 (0x2000)
|
#define APID_MAP_OFFSET_V7 (0x2000)
|
||||||
|
@ -60,6 +63,7 @@ DECLARE_GLOBAL_DATA_PTR;
|
||||||
#define SPMI_MAX_PERIPH 256
|
#define SPMI_MAX_PERIPH 256
|
||||||
|
|
||||||
#define SPMI_CHANNEL_READ_ONLY BIT(31)
|
#define SPMI_CHANNEL_READ_ONLY BIT(31)
|
||||||
|
#define SPMI_CHANNEL_VALID BIT(30)
|
||||||
#define SPMI_CHANNEL_MASK 0xffff
|
#define SPMI_CHANNEL_MASK 0xffff
|
||||||
|
|
||||||
enum arb_ver {
|
enum arb_ver {
|
||||||
|
@ -114,6 +118,8 @@ static int msm_spmi_write(struct udevice *dev, int usid, int pid, int off,
|
||||||
return -EIO;
|
return -EIO;
|
||||||
if (pid >= SPMI_MAX_PERIPH)
|
if (pid >= SPMI_MAX_PERIPH)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
if (!(priv->channel_map[usid][pid] & SPMI_CHANNEL_VALID))
|
||||||
|
return -EINVAL;
|
||||||
if (priv->channel_map[usid][pid] & SPMI_CHANNEL_READ_ONLY)
|
if (priv->channel_map[usid][pid] & SPMI_CHANNEL_READ_ONLY)
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
||||||
|
@ -183,6 +189,8 @@ static int msm_spmi_read(struct udevice *dev, int usid, int pid, int off)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
if (pid >= SPMI_MAX_PERIPH)
|
if (pid >= SPMI_MAX_PERIPH)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
if (!(priv->channel_map[usid][pid] & SPMI_CHANNEL_VALID))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
channel = priv->channel_map[usid][pid] & SPMI_CHANNEL_MASK;
|
channel = priv->channel_map[usid][pid] & SPMI_CHANNEL_MASK;
|
||||||
|
|
||||||
|
@ -246,6 +254,32 @@ static struct dm_spmi_ops msm_spmi_ops = {
|
||||||
.write = msm_spmi_write,
|
.write = msm_spmi_write,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In order to allow multiple EEs to write to a single PPID in arbiter
|
||||||
|
* version 5 and 7, there is more than one APID mapped to each PPID.
|
||||||
|
* The owner field for each of these mappings specifies the EE which is
|
||||||
|
* allowed to write to the APID.
|
||||||
|
*/
|
||||||
|
static void msm_spmi_channel_map_v5(struct msm_spmi_priv *priv, unsigned int i,
|
||||||
|
uint8_t slave_id, uint8_t pid)
|
||||||
|
{
|
||||||
|
/* Mark channels read-only when from different owner */
|
||||||
|
uint32_t cnfg = readl(priv->spmi_cnfg + ARB_CHANNEL_OFFSET(i));
|
||||||
|
uint8_t owner = SPMI_OWNERSHIP_PERIPH2OWNER(cnfg);
|
||||||
|
bool prev_valid = priv->channel_map[slave_id][pid] & SPMI_CHANNEL_VALID;
|
||||||
|
uint32_t prev_read_only = priv->channel_map[slave_id][pid] & SPMI_CHANNEL_READ_ONLY;
|
||||||
|
|
||||||
|
if (!prev_valid) {
|
||||||
|
/* First PPID mapping */
|
||||||
|
priv->channel_map[slave_id][pid] = i | SPMI_CHANNEL_VALID;
|
||||||
|
if (owner != priv->owner)
|
||||||
|
priv->channel_map[slave_id][pid] |= SPMI_CHANNEL_READ_ONLY;
|
||||||
|
} else if ((owner == priv->owner) && prev_read_only) {
|
||||||
|
/* Read only and we found one we own, switch */
|
||||||
|
priv->channel_map[slave_id][pid] = i | SPMI_CHANNEL_VALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int msm_spmi_probe(struct udevice *dev)
|
static int msm_spmi_probe(struct udevice *dev)
|
||||||
{
|
{
|
||||||
struct msm_spmi_priv *priv = dev_get_priv(dev);
|
struct msm_spmi_priv *priv = dev_get_priv(dev);
|
||||||
|
@ -271,13 +305,17 @@ static int msm_spmi_probe(struct udevice *dev)
|
||||||
} else if (hw_ver < PMIC_ARB_VERSION_V7_MIN) {
|
} else if (hw_ver < PMIC_ARB_VERSION_V7_MIN) {
|
||||||
priv->arb_ver = V5;
|
priv->arb_ver = V5;
|
||||||
priv->arb_chnl = core_addr + APID_MAP_OFFSET_V5;
|
priv->arb_chnl = core_addr + APID_MAP_OFFSET_V5;
|
||||||
priv->max_channels = SPMI_MAX_CHANNELS_V5;
|
priv->max_channels = min_t(u32, readl(core_addr + PMIC_ARB_FEATURES) &
|
||||||
|
PMIC_ARB_FEATURES_PERIPH_MASK,
|
||||||
|
SPMI_MAX_CHANNELS_V5);
|
||||||
priv->spmi_cnfg = dev_read_addr_name(dev, "cnfg");
|
priv->spmi_cnfg = dev_read_addr_name(dev, "cnfg");
|
||||||
} else {
|
} else {
|
||||||
/* TOFIX: handle second bus */
|
/* TOFIX: handle second bus */
|
||||||
priv->arb_ver = V7;
|
priv->arb_ver = V7;
|
||||||
priv->arb_chnl = core_addr + APID_MAP_OFFSET_V7;
|
priv->arb_chnl = core_addr + APID_MAP_OFFSET_V7;
|
||||||
priv->max_channels = SPMI_MAX_CHANNELS_V7;
|
priv->max_channels = min_t(u32, readl(core_addr + PMIC_ARB_FEATURES) &
|
||||||
|
PMIC_ARB_FEATURES_PERIPH_MASK,
|
||||||
|
SPMI_MAX_CHANNELS_V7);
|
||||||
priv->spmi_cnfg = dev_read_addr_name(dev, "cnfg");
|
priv->spmi_cnfg = dev_read_addr_name(dev, "cnfg");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,15 +335,16 @@ static int msm_spmi_probe(struct udevice *dev)
|
||||||
uint8_t slave_id = (periph & 0xf0000) >> 16;
|
uint8_t slave_id = (periph & 0xf0000) >> 16;
|
||||||
uint8_t pid = (periph & 0xff00) >> 8;
|
uint8_t pid = (periph & 0xff00) >> 8;
|
||||||
|
|
||||||
priv->channel_map[slave_id][pid] = i;
|
switch (priv->arb_ver) {
|
||||||
|
case V2:
|
||||||
|
case V3:
|
||||||
|
priv->channel_map[slave_id][pid] = i | SPMI_CHANNEL_VALID;
|
||||||
|
break;
|
||||||
|
|
||||||
/* Mark channels read-only when from different owner */
|
case V5:
|
||||||
if (priv->arb_ver == V5 || priv->arb_ver == V7) {
|
case V7:
|
||||||
uint32_t cnfg = readl(priv->spmi_cnfg + ARB_CHANNEL_OFFSET(i));
|
msm_spmi_channel_map_v5(priv, i, slave_id, pid);
|
||||||
uint8_t owner = SPMI_OWNERSHIP_PERIPH2OWNER(cnfg);
|
break;
|
||||||
|
|
||||||
if (owner != priv->owner)
|
|
||||||
priv->channel_map[slave_id][pid] |= SPMI_CHANNEL_READ_ONLY;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -18,15 +18,4 @@
|
||||||
#define PHYS_SDRAM_1_SIZE SZ_1G
|
#define PHYS_SDRAM_1_SIZE SZ_1G
|
||||||
#define CFG_SYS_SDRAM_BASE PHYS_SDRAM_1
|
#define CFG_SYS_SDRAM_BASE PHYS_SDRAM_1
|
||||||
|
|
||||||
/* Environment */
|
|
||||||
#define BOOT_TARGET_DEVICES(func) \
|
|
||||||
func(USB, usb, 0) \
|
|
||||||
func(MMC, mmc, 1) \
|
|
||||||
func(MMC, mmc, 0) \
|
|
||||||
func(DHCP, dhcp, na)
|
|
||||||
|
|
||||||
#include <config_distro_bootcmd.h>
|
|
||||||
|
|
||||||
#define CFG_EXTRA_ENV_SETTINGS BOOTENV
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Reference in a new issue