"Das U-Boot" Source Tree
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

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.

+1598 -164
+2 -1
arch/arm/Kconfig
··· 1120 1120 select SPMI 1121 1121 select BOARD_LATE_INIT 1122 1122 select OF_BOARD 1123 - select SAVE_PREV_BL_FDT_ADDR 1123 + select SAVE_PREV_BL_FDT_ADDR if !ENABLE_ARM_SOC_BOOT0_HOOK 1124 1124 select LINUX_KERNEL_IMAGE_HEADER if !ENABLE_ARM_SOC_BOOT0_HOOK 1125 1125 select SYSRESET 1126 1126 select SYSRESET_PSCI 1127 1127 imply OF_UPSTREAM 1128 1128 imply CMD_DM 1129 + imply DM_USB_GADGET 1129 1130 1130 1131 config ARCH_SOCFPGA 1131 1132 bool "Altera SOCFPGA family"
+1 -1
arch/arm/dts/apq8016-sbc-u-boot.dtsi
··· 6 6 / { 7 7 /* When running as a first-stage bootloader this isn't filled in automatically */ 8 8 memory@80000000 { 9 - reg = <0 0x80000000 0 0x3da00000>; 9 + reg = <0 0x80000000 0 0x40000000>; 10 10 }; 11 11 }; 12 12
+15
arch/arm/mach-snapdragon/include/mach/gpio.h
··· 46 46 return pindata->special_pins_start && pin >= pindata->special_pins_start; 47 47 } 48 48 49 + struct udevice; 50 + 51 + /** 52 + * msm_pinctrl_is_reserved() - Check if a pin lies in a reserved range 53 + * 54 + * @dev: pinctrl device 55 + * @pin: Pin number 56 + * 57 + * Returns: true if pin is reserved, otherwise false 58 + * 59 + * Call using dev_get_parent() from the GPIO device, it is a child of 60 + * the pinctrl device. 61 + */ 62 + bool msm_pinctrl_is_reserved(struct udevice *dev, unsigned int pin); 63 + 49 64 #endif /* _QCOM_GPIO_H_ */
+10 -10
arch/arm/mach-snapdragon/of_fixup.c
··· 86 86 } 87 87 88 88 /* Overwrite "phy-names" to only contain a single entry */ 89 - ret = of_write_prop(dwc3, "phy-names", strlen("usb2-phy"), "usb2-phy"); 89 + ret = of_write_prop(dwc3, "phy-names", strlen("usb2-phy") + 1, "usb2-phy"); 90 90 if (ret) { 91 91 log_err("Failed to overwrite 'phy-names' property: %d\n", ret); 92 92 return ret; 93 93 } 94 94 95 - ret = of_write_prop(dwc3, "maximum-speed", strlen("high-speed"), "high-speed"); 95 + ret = of_write_prop(dwc3, "maximum-speed", strlen("high-speed") + 1, "high-speed"); 96 96 if (ret) { 97 97 log_err("Failed to set 'maximum-speed' property: %d\n", ret); 98 98 return ret; ··· 161 161 struct fdt_header *fdt = blob; 162 162 int node; 163 163 164 - /* We only want to do this fix-up for the RB1 board, quick return for all others */ 165 - if (!fdt_node_check_compatible(fdt, 0, "qcom,qrb4210-rb2")) 166 - return 0; 167 - 168 - fdt_for_each_node_by_compatible(node, blob, 0, "snps,dwc3") { 169 - log_debug("%s: Setting 'dr_mode' to OTG\n", fdt_get_name(blob, node, NULL)); 170 - fdt_setprop_string(fdt, node, "dr_mode", "otg"); 171 - break; 164 + /* On RB1/2 we need to fix-up the dr_mode */ 165 + if (!fdt_node_check_compatible(fdt, 0, "qcom,qrb4210-rb2") || 166 + !fdt_node_check_compatible(fdt, 0, "qcom,qrb2210-rb1")) { 167 + fdt_for_each_node_by_compatible(node, blob, 0, "snps,dwc3") { 168 + log_debug("%s: Setting 'dr_mode' to OTG\n", fdt_get_name(blob, node, NULL)); 169 + fdt_setprop_string(fdt, node, "dr_mode", "otg"); 170 + break; 171 + } 172 172 } 173 173 174 174 return 0;
+2 -1
board/qualcomm/dragonboard410c/MAINTAINERS
··· 1 1 DRAGONBOARD410C BOARD 2 - M: Ramon Fried <rfried.dev@gmail.com> 2 + M: Stephan Gerhold <stephan@gerhold.net> 3 + R: Sam Day <me@samcday.com> 3 4 S: Maintained 4 5 F: board/qualcomm/dragonboard410c/ 5 6 F: include/configs/dragonboard410c.h
+22 -45
board/qualcomm/dragonboard410c/dragonboard410c.c
··· 22 22 23 23 DECLARE_GLOBAL_DATA_PTR; 24 24 25 - /* UNSTUFF_BITS macro taken from Linux Kernel: drivers/mmc/core/sd.c */ 26 - #define UNSTUFF_BITS(resp, start, size) \ 27 - ({ \ 28 - const int __size = size; \ 29 - const u32 __mask = (__size < 32 ? 1 << __size : 0) - 1; \ 30 - const int __off = 3 - ((start) / 32); \ 31 - const int __shft = (start) & 31; \ 32 - u32 __res; \ 33 - \ 34 - __res = resp[__off] >> __shft; \ 35 - if (__size + __shft > 32) \ 36 - __res |= resp[__off - 1] << ((32 - __shft) % 32); \ 37 - __res & __mask; \ 38 - }) 39 - 40 25 static u32 msm_board_serial(void) 41 26 { 42 27 struct mmc *mmc_dev; ··· 48 33 if (mmc_init(mmc_dev)) 49 34 return 0; 50 35 51 - return UNSTUFF_BITS(mmc_dev->cid, 16, 32); 36 + /* MMC serial number */ 37 + return mmc_dev->cid[2] << 16 | mmc_dev->cid[3] >> 16; 52 38 } 53 39 54 40 static void msm_generate_mac_addr(u8 *mac) ··· 65 51 put_unaligned_be32(msm_board_serial(), &mac[2]); 66 52 } 67 53 68 - /* Check for vol- button - if pressed - stop autoboot */ 69 - int misc_init_r(void) 70 - { 71 - struct udevice *btn; 72 - int ret; 73 - enum button_state_t state; 74 - 75 - ret = button_get_by_label("vol_down", &btn); 76 - if (ret < 0) { 77 - printf("Couldn't find power button!\n"); 78 - return ret; 79 - } 80 - 81 - state = button_get_state(btn); 82 - if (state == BUTTON_ON) { 83 - env_set("preboot", "setenv preboot; fastboot 0"); 84 - printf("vol_down pressed - Starting fastboot.\n"); 85 - } 86 - 87 - return 0; 88 - } 89 - 90 54 int qcom_late_init(void) 91 55 { 92 56 char serial[16]; ··· 97 61 return 0; 98 62 } 99 63 100 - /* Fixup of DTB for Linux Kernel 101 - * 1. Fixup installed DRAM. 102 - * 2. Fixup WLAN/BT Mac address: 64 + /* 65 + * Fixup of DTB for Linux Kernel 66 + * 1. Fixup WLAN/BT Mac address: 103 67 * First, check if MAC addresses for WLAN/BT exists as environemnt 104 68 * variables wlanaddr,btaddr. if not, generate a unique address. 105 69 */ ··· 107 71 int ft_board_setup(void *blob, struct bd_info *bd) 108 72 { 109 73 u8 mac[ARP_HLEN]; 74 + int i; 110 75 111 76 if (!eth_env_get_enetaddr("wlanaddr", mac)) { 112 77 msm_generate_mac_addr(mac); ··· 118 83 if (!eth_env_get_enetaddr("btaddr", mac)) { 119 84 msm_generate_mac_addr(mac); 120 85 121 - /* The BD address is same as WLAN MAC address but with 122 - * least significant bit flipped. 123 - */ 124 - mac[0] ^= 0x01; 86 + /* 87 + * The BD address is same as WLAN MAC address but with 88 + * least significant bit flipped. 89 + */ 90 + mac[ARP_HLEN - 1] ^= 0x01; 125 91 }; 92 + 93 + /* 94 + * Reverse array since local-bd-address is formatted with least 95 + * significant byte first (little endian). 96 + */ 97 + for (i = 0; i < ARP_HLEN / 2; ++i) { 98 + u8 tmp = mac[i]; 99 + 100 + mac[i] = mac[ARP_HLEN - 1 - i]; 101 + mac[ARP_HLEN - 1 - i] = tmp; 102 + } 126 103 127 104 do_fixup_by_compat(blob, "qcom,wcnss-bt", 128 105 "local-bd-address", mac, ARP_HLEN, 1);
+4 -34
board/qualcomm/dragonboard410c/dragonboard410c.env
··· 1 1 /* SPDX-License-Identifier: GPL-2.0+ */ 2 - 3 - /* Does what recovery does */ 4 - #define REFLASH(file, partnum) \ 5 - part start mmc 0 partnum start && \ 6 - part size mmc 0 partnum size && \ 7 - tftp $loadaddr file && \ 8 - mmc write $loadaddr $start $size && 9 - 10 - reflash= 11 - mmc dev 0 && 12 - usb start && 13 - dhcp && 14 - tftp $loadaddr dragonboard/rescue/gpt_both0.bin && 15 - mmc write $loadaddr 0 43 && 16 - mmc rescan && 17 - REFLASH(dragonboard/rescue/NON-HLOS.bin, 1) 18 - REFLASH(dragonboard/rescue/sbl1.mbn, 2) 19 - REFLASH(dragonboard/rescue/rpm.mbn, 3) 20 - REFLASH(dragonboard/rescue/tz.mbn, 4) 21 - REFLASH(dragonboard/rescue/hyp.mbn, 5) 22 - REFLASH(dragonboard/rescue/sec.dat, 6) 23 - REFLASH(dragonboard/rescue/emmc_appsboot.mbn, 7) 24 - REFLASH(dragonboard/u-boot.img, 8) 25 - usb stop && 26 - echo Reflash completed 27 - 28 - loadaddr=0x81000000 29 2 initrd_high=0xffffffffffffffff 30 - linux_image=Image 31 - kernel_addr_r=0x81000000 32 - fdtfile=qcom/apq8016-sbc.dtb 33 - fdt_addr_r=0x83000000 34 - ramdisk_addr_r=0x84000000 35 - scriptaddr=0x90000000 36 - pxefile_addr_r=0x90100000 3 + fastboot=fastboot -l $fastboot_addr_r usb 0 4 + boot_targets=usb mmc1 mmc0 pxe 5 + button_cmd_0_name=vol_down 6 + button_cmd_0=run fastboot
+1 -1
board/qualcomm/dragonboard820c/dragonboard820c.c
··· 106 106 int ret; 107 107 enum button_state_t state; 108 108 109 - ret = button_get_by_label("pwrkey", &btn); 109 + ret = button_get_by_label("Power Button", &btn); 110 110 if (ret < 0) { 111 111 printf("Couldn't find power button!\n"); 112 112 return ret;
+21 -26
board/qualcomm/dragonboard820c/readme.txt
··· 16 16 Build & Run instructions 17 17 ================================================================================ 18 18 19 - 1) Install mkbootimg and dtbTool from Codeaurora: 20 - 21 - git://codeaurora.org/quic/kernel/skales 22 - commit 8492547e404e969262d9070dee9bdd15668bb70f worked for me. 19 + 1) Install mkbootimg 23 20 24 21 2) Setup CROSS_COMPILE to aarch64 compiler or if you use ccache just do 25 22 CROSS_COMPILE="ccache aarch64-linux-gnu-" ··· 33 30 34 31 $ touch rd 35 32 36 - 5) Generate qualcomm device tree table with dtbTool 33 + 5) Append the dtb to the u-boot binary discarding the internal dtb. 37 34 38 - $ dtbTool -o dt.img arch/arm/dts 35 + $ gzip u-boot-nodtb.bin 36 + $ cat u-boot.dtb >> u-boot-nodtb.bin.gz 39 37 40 38 6) Generate Android boot image with mkbootimg: 41 39 42 - $ mkbootimg --kernel=u-boot-dtb.bin \ 40 + $ mkbootimg --kernel=u-boot-nodtb.bin.gz \ 43 41 --output=u-boot.img \ 44 - --dt=dt.img \ 45 42 --pagesize 4096 \ 46 43 --base 0x80000000 \ 47 44 --ramdisk=rd \ ··· 251 248 [5300] booting linux @ 0x80080000, ramdisk @ 0x82200000 (0), tags/device tree @ 0x82000000 252 249 [5310] Jumping to kernel via monitor 253 250 254 - U-Boot 2017.11-00145-ge895117 (Nov 29 2017 - 10:04:06 +0100) 251 + U-Boot 2025.04-rc5-00020-g40a61ca0e7eb-dirty (Apr 07 2025 - 09:37:03 +0200) 255 252 Qualcomm-DragonBoard 820C 256 253 257 - DRAM: 3 GiB 258 - PSCI: v1.0 259 - MMC: sdhci@74a4900: 0 254 + DRAM: 3.5 GiB (effective 3 GiB) 255 + Core: 136 devices, 18 uclasses, devicetree: board 256 + MMC: Bulk clocks not available (-19), trying core clock 257 + mmc@74a4900: 0 258 + Loading Environment from EXT4... OK 260 259 In: serial@75b0000 261 260 Out: serial@75b0000 262 261 Err: serial@75b0000 263 - Net: Net Initialization Skipped 264 - No ethernet found. 262 + Net: No ethernet found. 265 263 Hit any key to stop autoboot: 0 266 264 switch to partitions #0, OK 267 265 mmc0 is current device 268 266 Scanning mmc 0:1... 269 267 Found /extlinux/extlinux.conf 270 268 Retrieving file: /extlinux/extlinux.conf 271 - 433 bytes read in 71 ms (5.9 KiB/s) 272 269 1: nfs root 273 - 270 + Enter choice: 1: nfs root 274 271 Retrieving file: /uImage 275 - 19397184 bytes read in 2024 ms (9.1 MiB/s) 276 - 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 277 - 272 + 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 278 273 Retrieving file: /apq8096-db820c.dtb 279 - 38134 bytes read in 37 ms (1005.9 KiB/s) 280 - 281 - ## Booting kernel from Legacy Image at 95000000 ... 274 + ## Booting kernel from Legacy Image at 155000000 ... 282 275 Image Name: Dragonboard820c 283 276 Image Type: AArch64 Linux Kernel Image (uncompressed) 284 277 Data Size: 19397120 Bytes = 18.5 MiB 285 278 Load Address: 80080000 286 279 Entry Point: 80080000 287 280 Verifying Checksum ... OK 288 - ## Flattened Device Tree blob at 93000000 289 - Booting using the fdt blob at 0x93000000 290 - Loading Kernel Image ... OK 291 - Using Device Tree in place at 0000000093000000, end 000000009300c4f5 281 + ## Flattened Device Tree blob at 148600000 282 + Booting using the fdt blob at 0x148600000 283 + Working FDT set to 148600000 284 + Loading Kernel Image to 80080000 285 + Using Device Tree in place at 0000000148600000, end 000000014860c4f5 286 + Working FDT set to 148600000 292 287 293 288 Starting kernel ... 294 289
+29
board/qualcomm/qcom-phone.config
··· 1 + # Settings for phones 2 + CONFIG_DEFAULT_ENV_FILE="board/qualcomm/qcom-phone.env" 3 + # Hang on panic so the error message can be read 4 + CONFIG_PANIC_HANG=y 5 + # We use pause in various places to allow text to be read 6 + # before it scrolls off the screen 7 + CONFIG_CMD_PAUSE=y 8 + CONFIG_BOOT_RETRY=y 9 + CONFIG_BOOT_RETRY_TIME=1 10 + CONFIG_BUTTON_REMAP_PHONE_KEYS=y 11 + CONFIG_RETRY_BOOTCMD=y 12 + CONFIG_FASTBOOT_BUF_ADDR=0x1A000000 13 + CONFIG_USB_FUNCTION_FASTBOOT=y 14 + CONFIG_USB_FUNCTION_ACM=y 15 + CONFIG_CMD_UMS_ABORT_KEYED=y 16 + 17 + # Record all console output and let it be dumped via fastboot 18 + CONFIG_CONSOLE_RECORD=y 19 + CONFIG_CONSOLE_RECORD_INIT_F=y 20 + CONFIG_CONSOLE_RECORD_OUT_SIZE=0x6000 21 + CONFIG_FASTBOOT_CMD_OEM_CONSOLE=y 22 + 23 + # Only MMC is supported by fastboot currently, but this is still useful. 24 + CONFIG_FASTBOOT_FLASH=y 25 + CONFIG_FASTBOOT_FLASH_MMC_DEV=0 26 + CONFIG_FASTBOOT_OEM_RUN=y 27 + 28 + # Many phones don't actually define a serial port in their DTS 29 + # CONFIG_REQUIRE_SERIAL_CONSOLE is not set
+47
board/qualcomm/qcom-phone.env
··· 1 + bootdelay=0 2 + bootretry=1 3 + stdin=serial,button-kbd 4 + stdout=serial,vidconsole 5 + stderr=serial,vidconsole 6 + 7 + # Fastboot is keen to use the address from kconfig, but we 8 + # allocate its buffer at runtime. 9 + fastboot=fastboot -l $fastboot_addr_r usb 0 10 + 11 + # Always probe for UFS storage, though it should be done by board code. 12 + preboot=scsi scan 13 + 14 + # Shortcut to enable USB serial gadget and disable bootretry 15 + serial_gadget=setenv stdin serial,button-kbd,usbacm; \ 16 + setenv stdout serial,vidconsole,usbacm; \ 17 + setenv stderr serial,vidconsole,usbacm; \ 18 + setenv bootretry -1; \ 19 + echo Enabled U-Boot console serial gadget 20 + 21 + # bootretry will run this command over and over, if we fail once 22 + # then bail out to the boot menu instead (with a pause to read 23 + # the error message) 24 + bootcmd=bootefi bootmgr; pause; run menucmd 25 + 26 + # When entering the menu (either from button press or failed boot) 27 + # remap bootcmd so it will re-open the menu and we won't get stuck 28 + # at the console with no way to type 29 + menucmd=setenv bootcmd run menucmd; bootmenu -1 30 + 31 + # Pause is used so the output can be read on the display 32 + bootmenu_0=Boot=bootefi bootmgr; pause 33 + bootmenu_1=Enable serial console gadget=run serial_gadget 34 + bootmenu_2=Enable USB mass storage=echo "Press any key to exit UMS mode"; ums 0 scsi 0 35 + bootmenu_3=Enable fastboot mode=run fastboot 36 + # Disabling bootretry means we'll just drop the shell 37 + bootmenu_4=Drop to shell=setenv bootretry -1 38 + bootmenu_5=Reset device=reset 39 + bootmenu_6=Dump clocks=clk dump; pause 40 + bootmenu_7=Dump environment=printenv; pause 41 + bootmenu_8=Board info=bdinfo; pause 42 + bootmenu_9=Dump bootargs=fdt print /chosen bootargs; pause 43 + 44 + # Allow holding the volume down button while U-Boot loads to enter 45 + # the boot menu 46 + button_cmd_0_name=Volume Down 47 + button_cmd_0=run menucmd
+7
boot/Kconfig
··· 1704 1704 After the countdown timed out, the board will be reset to restart 1705 1705 again. 1706 1706 1707 + config RETRY_BOOTCMD 1708 + bool "Run bootcmd on retry" 1709 + depends on BOOT_RETRY && HUSH_PARSER && !RESET_TO_RETRY 1710 + help 1711 + If this option is enabled, the "bootcmd" will be run after the 1712 + countdown times out. 1713 + 1707 1714 endmenu 1708 1715 1709 1716 menu "Image support"
+2
boot/bootretry.c
··· 37 37 */ 38 38 void bootretry_reset_cmd_timeout(void) 39 39 { 40 + /* Parse changes to bootretry */ 41 + bootretry_init_cmd_timeout(); 40 42 endtime = endtick(retry_time); 41 43 } 42 44
+4 -2
common/cli_hush.c
··· 1028 1028 puts("\nTimeout waiting for command\n"); 1029 1029 # ifdef CONFIG_RESET_TO_RETRY 1030 1030 do_reset(NULL, 0, 0, NULL); 1031 - # else 1032 - # error "This currently only works with CONFIG_RESET_TO_RETRY enabled" 1031 + # elif IS_ENABLED(CONFIG_RETRY_BOOTCMD) 1032 + strcpy(console_buffer, "run bootcmd\n"); 1033 + # else 1034 + # error "This only works with CONFIG_RESET_TO_RETRY or CONFIG_BOOT_RETRY_COMMAND enabled" 1033 1035 # endif 1034 1036 } 1035 1037 #endif
+4 -2
common/cli_hush_upstream.c
··· 2907 2907 puts("\nTimeout waiting for command\n"); 2908 2908 # ifdef CONFIG_RESET_TO_RETRY 2909 2909 do_reset(NULL, 0, 0, NULL); 2910 - # else 2911 - # error "This currently only works with CONFIG_RESET_TO_RETRY enabled" 2910 + # elif IS_ENABLED(CONFIG_RETRY_BOOTCMD) 2911 + strcpy(console_buffer, "run bootcmd\n"); 2912 + # else 2913 + # error "This only works with CONFIG_RESET_TO_RETRY or CONFIG_BOOT_RETRY_COMMAND enabled" 2912 2914 # endif 2913 2915 } 2914 2916 # endif
+6 -5
configs/dragonboard410c_defconfig
··· 1 1 CONFIG_ARM=y 2 2 CONFIG_SYS_BOARD="dragonboard410c" 3 - CONFIG_COUNTER_FREQUENCY=19000000 3 + CONFIG_COUNTER_FREQUENCY=19200000 4 4 CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK=y 5 5 CONFIG_ARCH_SNAPDRAGON=y 6 6 CONFIG_TEXT_BASE=0x8f600000 ··· 14 14 CONFIG_SYS_LOAD_ADDR=0x80080000 15 15 CONFIG_IDENT_STRING="\nQualcomm-DragonBoard 410C" 16 16 CONFIG_REMAKE_ELF=y 17 - # CONFIG_ANDROID_BOOT_IMAGE is not set 17 + CONFIG_BUTTON_CMD=y 18 18 CONFIG_FIT=y 19 - CONFIG_DISTRO_DEFAULTS=y 19 + CONFIG_BOOTSTD_FULL=y 20 20 CONFIG_OF_BOARD_SETUP=y 21 21 CONFIG_USE_PREBOOT=y 22 22 CONFIG_SYS_CBSIZE=512 23 23 CONFIG_SYS_PBSIZE=548 24 24 # CONFIG_DISPLAY_CPUINFO is not set 25 25 # CONFIG_DISPLAY_BOARDINFO is not set 26 - CONFIG_MISC_INIT_R=y 27 26 CONFIG_SYS_PROMPT="dragonboard410c => " 28 - # CONFIG_CMD_IMI is not set 29 27 CONFIG_CMD_MD5SUM=y 30 28 CONFIG_CMD_MEMINFO=y 31 29 CONFIG_CMD_GPIO=y ··· 35 33 CONFIG_BOOTP_BOOTFILESIZE=y 36 34 CONFIG_CMD_CACHE=y 37 35 CONFIG_CMD_TIMER=y 36 + CONFIG_CMD_SYSBOOT=y 38 37 CONFIG_ENV_IS_IN_MMC=y 39 38 CONFIG_SYS_RELOC_GD_ENV_ADDR=y 40 39 CONFIG_SYS_MMC_ENV_PART=2 ··· 60 59 CONFIG_MSM_SERIAL=y 61 60 CONFIG_SPMI_MSM=y 62 61 CONFIG_USB=y 62 + # CONFIG_DM_USB_GADGET is not set 63 63 CONFIG_USB_EHCI_HCD=y 64 64 CONFIG_USB_EHCI_MSM=y 65 65 CONFIG_USB_ULPI_VIEWPORT=y ··· 68 68 CONFIG_USB_ETHER_ASIX=y 69 69 CONFIG_USB_ETHER_ASIX88179=y 70 70 CONFIG_USB_ETHER_MCS7830=y 71 + CONFIG_USB_ETHER_RTL8152=y 71 72 CONFIG_USB_ETHER_SMSC95XX=y 72 73 CONFIG_USB_GADGET=y 73 74 CONFIG_USB_GADGET_VENDOR_NUM=0x18d1
+2
configs/dragonboard820c_defconfig
··· 45 45 CONFIG_DM_PMIC=y 46 46 CONFIG_PMIC_QCOM=y 47 47 CONFIG_MSM_SERIAL=y 48 + CONFIG_MSM_GPIO=y 48 49 CONFIG_SPMI_MSM=y 50 + CONFIG_CLK_STUB=y
+1
configs/hmibsc_defconfig
··· 70 70 CONFIG_MSM_SERIAL=y 71 71 CONFIG_SPMI_MSM=y 72 72 CONFIG_USB=y 73 + # CONFIG_DM_USB_GADGET is not set 73 74 CONFIG_USB_EHCI_HCD=y 74 75 CONFIG_USB_EHCI_MSM=y 75 76 CONFIG_USB_ULPI_VIEWPORT=y
+7 -1
configs/qcom_defconfig
··· 41 41 CONFIG_CMD_REGULATOR=y 42 42 CONFIG_CMD_LOG=y 43 43 CONFIG_OF_LIVE=y 44 + CONFIG_OF_UPSTREAM_BUILD_VENDOR=y 44 45 CONFIG_USE_DEFAULT_ENV_FILE=y 45 46 CONFIG_DEFAULT_ENV_FILE="board/qualcomm/default.env" 46 47 CONFIG_BUTTON_QCOM_PMIC=y ··· 62 63 CONFIG_DFU_MMC=y 63 64 CONFIG_DFU_SCSI=y 64 65 CONFIG_SYS_DFU_DATA_BUF_SIZE=0x200000 66 + CONFIG_USB_FUNCTION_FASTBOOT=y 67 + CONFIG_FASTBOOT_BUF_ADDR=0x0 68 + CONFIG_FASTBOOT_FLASH=y 69 + CONFIG_FASTBOOT_FLASH_MMC_DEV=0 70 + CONFIG_FASTBOOT_MMC_USER_SUPPORT=y 65 71 CONFIG_MSM_GPIO=y 66 72 CONFIG_QCOM_PMIC_GPIO=y 67 73 CONFIG_DM_I2C=y ··· 75 81 CONFIG_MISC=y 76 82 CONFIG_NVMEM=y 77 83 CONFIG_I2C_EEPROM=y 78 - CONFIG_MMC_HS200_SUPPORT=y 79 84 CONFIG_MMC_SDHCI=y 80 85 CONFIG_MMC_SDHCI_ADMA=y 81 86 CONFIG_MMC_SDHCI_MSM=y ··· 97 102 CONFIG_PINCTRL_QCOM_APQ8096=y 98 103 CONFIG_PINCTRL_QCOM_QCM2290=y 99 104 CONFIG_PINCTRL_QCOM_QCS404=y 105 + CONFIG_PINCTRL_QCOM_SA8775P=y 100 106 CONFIG_PINCTRL_QCOM_SC7280=y 101 107 CONFIG_PINCTRL_QCOM_SDM845=y 102 108 CONFIG_PINCTRL_QCOM_SM6115=y
+5
doc/board/qualcomm/board.rst
··· 90 90 make CROSS_COMPILE=aarch64-linux-gnu- O=.output dragonboard410c_defconfig 91 91 make O=.output -j$(nproc) 92 92 93 + Or for smartphones:: 94 + 95 + make CROSS_COMPILE=aarch64-linux-gnu- O=.output qcom_defconfig qcom-phone.config 96 + make O=.output -j$(nproc) 97 + 93 98 - gzip u-boot:: 94 99 95 100 gzip u-boot-nodtb.bin
+1
doc/board/qualcomm/index.rst
··· 9 9 dragonboard410c 10 10 rb3gen2 11 11 board 12 + phones 12 13 debugging 13 14 rdp
+144
doc/board/qualcomm/phones.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0+ 2 + .. sectionauthor:: Caleb Connolly <caleb.connolly@linaro.org> 3 + 4 + ====================================== 5 + Booting U-Boot on Qualcomm smartphones 6 + ====================================== 7 + 8 + About this 9 + ---------- 10 + 11 + This page attempts to the describe U-Boot support for Qualcomm phones, as a user guide but also a 12 + technical introduction to How Stuff Works to help new porters. 13 + 14 + In broad strokes, U-Boot should boot if the SoC is supported, and the device is already capable of 15 + booting an upstream Linux kernel. 16 + 17 + The list of supported Qualcomm SoCs changes often, for now it is best to look in 18 + ``drivers/clk/qcom/`` to get a rough idea. 19 + 20 + For building instructions, see :doc:`board`. 21 + 22 + Phone bringup 23 + ------------- 24 + 25 + It is usually easier to get Linux booting first, there are many good resources for this such as the 26 + `postmarketOS wiki`_. Once the device can boot Linux with logs on the display and ideally USB gadget 27 + support, it is highly likely that U-Boot will boot as well. 28 + 29 + For logs on display, you should have a simple framebuffer node defined in your DT, newer devices 30 + require that this follow the downstream naming scheme (that the DTB is compiled with labels enabled 31 + and the framebuffer reserved-memory region is labelled ``cont_splash``). Once this is working in 32 + Linux it should also work in U-Boot. 33 + 34 + In practise, U-Boot still has many more papercuts than Linux, which can be sticking points when 35 + porting a new device. In particular, drivers failing to bind/probe (especially pre-relocation) can 36 + be tricky to debug without UART since U-Boot will simply panic with no way to inform you of 37 + the error. As a result, bringing up a new device can be quite frustrating, but there are quite a few 38 + things you can try. 39 + 40 + The phone config 41 + ^^^^^^^^^^^^^^^^ 42 + 43 + Since most phones lack a physical keyboard or serial port, a special config fragment and environment 44 + file can be used to provide a more seamless experience. This can be enabled by generating the config 45 + with:: 46 + 47 + make CROSS_COMPILE=aarch64-linux-gnu- O=.output qcom_defconfig qcom-phone.config 48 + 49 + The config and associated environment file can be found in board/qualcomm/. The main changes are: 50 + 51 + - Panic on hang (so the panic message can be read on the display) 52 + - Boot retry (to automatically open and re-open the bootmenu) 53 + - A boot menu with helpful shortcuts (including USB console gadget) 54 + - Launch the boot menu if power is held during boot or on boot failure 55 + 56 + Fastboot mode 57 + ------------- 58 + 59 + U-Boot's fastboot implementation is much more limited than Qualcomm's, and currently does not have a 60 + backend for UFS storage. If your device uses eMMC or has an sdcard slot, fastboot will use that by 61 + default. 62 + 63 + You may need to run the fastboot command on your PC as root since the USB product/vendor ID may not 64 + match the android udev rules. 65 + 66 + You can also use fastboot to run arbitrary U-Boot commands with ``fastboot oem run`` 67 + 68 + Retrieving early logs 69 + ^^^^^^^^^^^^^^^^^^^^^ 70 + 71 + U-Boot is configured to save it's internal log to a buffer, this can help with debugging some driver 72 + bind/probe issues. If your device can boot and has working USB, you can enable fastboot mode (either 73 + via the U-Boot menu or by adding ``run fastboot`` to the end of the ``preboot=`` config in 74 + ``board/qualcomm/qcom-phone.env``). 75 + 76 + You can then retrieve U-Boot's log buffer with the ``fastboot oem log`` command on your PC. 77 + 78 + Hang/crash bisection 79 + -------------------- 80 + 81 + Without a way to get logs, we can still get quite far with only a few bits of information: what 82 + happens when you ``fastboot boot u-boot.img``? 83 + 84 + Does the device disconnect? 85 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 86 + 87 + This can be verified by watching ``dmesg -w``. If it stays connected, it likely means the boot image 88 + doesn't match what the bootloader expected, use ``unpack_bootimg`` to compare it with a known-good 89 + boot image (ideally one with an upstream kernel). 90 + 91 + Does the device hang? 92 + ^^^^^^^^^^^^^^^^^^^^^ 93 + 94 + If it stays on a black screen and does nothing, then that's a hang! Since ``qcom-phone.config`` 95 + enables CONFIG_PANIC_HANG, this likely means that you're successfully executing U-Boot code (yay!), 96 + but something is causing a panic. 97 + 98 + It could also be due to a bad memory or register access triggering a secure interrupt, it's worth 99 + waiting for around a minute to see if the device eventually reboots or goes to crashdump mode. You 100 + can also disable CONFIG_PANIC_HANG and see if that causes the device to reboot instead, if so then 101 + it is definitely a U-Boot panic. 102 + 103 + With enough time and patience, it should be possible to narrow down the cause of the panic by 104 + inserting calls to ``reset_cpu()`` (with CONFIG_PANIC_HANG enabled). Then if the device resets you 105 + know it executed the ``reset_cpu()`` call. 106 + 107 + A good place to start is ``board_fdt_blob_setup()`` in ``arch/arm/mach-snapdragon/board.c``, this 108 + function is called extremely early so adding a reset call is a good way to validate that U-Boot is 109 + definitely running. 110 + 111 + You can then do a binary search starting from the end of ``board_init_f()`` / start of 112 + ``board_init_r()`` and work from there using the init sequences for reference. 113 + 114 + The Qualcomm RAM parsing code is a likely culprit, as ABL is known to sometimes give bogus entries 115 + in the memory node which can trip U-Boot up. 116 + 117 + To rule out crashes that might be caused by specific drivers, it's a good idea to disable them and 118 + re-enable them one by one. Here is a non-exhaustive list of drivers to disable: 119 + 120 + - pinctrl 121 + - mmc 122 + - scsi/ufs 123 + - usb (dwc3) 124 + - phy (usb, ufs) 125 + - clk (remove clock references from your framebuffer node in DT) 126 + 127 + Ideally, it would be possible to use the framebuffer as an early console / debug output, at the time 128 + of writing there are out of tree patches for this but they haven't been submitted upstream yet. 129 + 130 + Does the device reboot or go to crashdump mode? 131 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 132 + 133 + On many devices crashdump mode is disabled, so they will reboot instead (maybe after some delay). 134 + The same approach as suggested above can be used to figure out where the crash occurs. 135 + 136 + If the device is rebooting, you can insert calls to ``hang()`` instead of ``reset_cpu()`` when 137 + following the instructions above. 138 + 139 + The most likely cause of a crashdump is the pinctrl/gpio driver or the SMMU driver, ensure that the 140 + ``apps_smmu`` node in your SoCs devicetree file has one of its compatible strings referenced in 141 + ``drivers/iommu/qcom-hyp-smmu.c``, you can also try disabling the pinctrl driver for your SoC (or 142 + ``CONFIG_PINCTRL`` altogether). 143 + 144 + .. _`postmarketOS wiki`: https://wiki.postmarketos.org/wiki/Mainlining
+4 -4
drivers/button/button-qcom-pmic.c
··· 73 73 .compatible = "qcom,pm8941-pwrkey", 74 74 .status_bit = PON_KPDPWR_N_SET, 75 75 .code = KEY_ENTER, 76 - .label = "pwrkey", 76 + .label = "Power Button", 77 77 }, 78 78 { 79 79 .compatible = "qcom,pm8941-resin", 80 80 .status_bit = PON_RESIN_N_SET, 81 81 .code = KEY_DOWN, 82 - .label = "vol_down", 82 + .label = "Volume Down", 83 83 }, 84 84 { 85 85 .compatible = "qcom,pmk8350-pwrkey", 86 86 .status_bit = PON_GEN3_KPDPWR_N_SET, 87 87 .code = KEY_ENTER, 88 - .label = "pwrkey", 88 + .label = "Power Button", 89 89 }, 90 90 { 91 91 .compatible = "qcom,pmk8350-resin", 92 92 .status_bit = PON_GEN3_RESIN_N_SET, 93 93 .code = KEY_DOWN, 94 - .label = "vol_down", 94 + .label = "Volume Down", 95 95 }, 96 96 }; 97 97
+1 -1
drivers/button/button-uclass.c
··· 21 21 struct button_uc_plat *uc_plat = dev_get_uclass_plat(dev); 22 22 23 23 /* Ignore the top-level button node */ 24 - if (uc_plat->label && !strcmp(label, uc_plat->label)) 24 + if (uc_plat->label && !strcasecmp(label, uc_plat->label)) 25 25 return uclass_get_device_tail(dev, 0, devp); 26 26 } 27 27
+2 -1
drivers/clk/clk-stub.c
··· 14 14 static const struct udevice_id nop_parent_ids[] = { 15 15 { .compatible = "qcom,rpm-proc" }, 16 16 { .compatible = "qcom,glink-rpm" }, 17 - { .compatible = "qcom,rpm-sm6115" }, 17 + { .compatible = "qcom,glink-smd-rpm" }, 18 18 { } 19 19 }; 20 20 ··· 50 50 51 51 static const struct udevice_id stub_clk_ids[] = { 52 52 { .compatible = "qcom,rpmcc" }, 53 + { .compatible = "qcom,sdm845-rpmh-clk" }, 53 54 { .compatible = "qcom,sc7280-rpmh-clk" }, 54 55 { .compatible = "qcom,sm8150-rpmh-clk" }, 55 56 { .compatible = "qcom,sm8250-rpmh-clk" },
+3 -2
drivers/clk/qcom/clock-apq8096.c
··· 83 83 struct msm_clk_priv *priv = dev_get_priv(clk->dev); 84 84 85 85 switch (clk->id) { 86 - case GCC_SDCC1_APPS_CLK: /* SDC1 */ 86 + case GCC_SDCC2_APPS_CLK: /* SDC2 */ 87 87 return clk_init_sdc(priv, rate); 88 88 break; 89 89 case GCC_BLSP2_UART2_APPS_CLK: /*UART2*/ 90 - return clk_init_uart(priv); 90 + clk_init_uart(priv); 91 + return 7372800; 91 92 default: 92 93 return 0; 93 94 }
+11
drivers/clk/qcom/clock-sc7280.c
··· 107 107 GATE_CLK(GCC_QUPV3_WRAP0_S0_CLK, 0x52008, BIT(10)), 108 108 GATE_CLK(GCC_QUPV3_WRAP0_S1_CLK, 0x52008, BIT(11)), 109 109 GATE_CLK(GCC_QUPV3_WRAP0_S3_CLK, 0x52008, BIT(13)), 110 + GATE_CLK(GCC_UFS_PHY_AXI_CLK, 0x77010, BIT(0)), 111 + GATE_CLK(GCC_AGGRE_UFS_PHY_AXI_CLK, 0x770cc, BIT(0)), 112 + GATE_CLK(GCC_UFS_PHY_AHB_CLK, 0x77018, BIT(0)), 113 + GATE_CLK(GCC_UFS_PHY_UNIPRO_CORE_CLK, 0x7705c, BIT(0)), 114 + GATE_CLK(GCC_UFS_PHY_PHY_AUX_CLK, 0x7709c, BIT(0)), 115 + GATE_CLK(GCC_UFS_PHY_TX_SYMBOL_0_CLK, 0x7701c, BIT(0)), 116 + GATE_CLK(GCC_UFS_PHY_RX_SYMBOL_0_CLK, 0x77020, BIT(0)), 117 + GATE_CLK(GCC_UFS_PHY_RX_SYMBOL_1_CLK, 0x770b8, BIT(0)), 118 + GATE_CLK(GCC_UFS_1_CLKREF_EN, 0x8c000, BIT(0)), 119 + GATE_CLK(GCC_SDCC2_AHB_CLK, 0x14008, BIT(0)), 120 + GATE_CLK(GCC_SDCC2_APPS_CLK, 0x14004, BIT(0)), 110 121 }; 111 122 112 123 static int sc7280_enable(struct clk *clk)
+3
drivers/clk/qcom/clock-sdm845.c
··· 77 77 } 78 78 79 79 static const struct gate_clk sdm845_clks[] = { 80 + GATE_CLK(GCC_AGGRE_USB3_PRIM_AXI_CLK, 0x8201c, 0x00000001), 80 81 GATE_CLK(GCC_AGGRE_USB3_SEC_AXI_CLK, 0x82020, 0x00000001), 82 + GATE_CLK(GCC_CFG_NOC_USB3_PRIM_AXI_CLK, 0x0502c, 0x00000001), 81 83 GATE_CLK(GCC_CFG_NOC_USB3_SEC_AXI_CLK, 0x05030, 0x00000001), 82 84 GATE_CLK(GCC_QUPV3_WRAP0_S0_CLK, 0x5200c, 0x00000400), 83 85 GATE_CLK(GCC_QUPV3_WRAP0_S1_CLK, 0x5200c, 0x00000800), ··· 112 114 GATE_CLK(GCC_UFS_CARD_TX_SYMBOL_0_CLK, 0x75014, 0x00000001), 113 115 GATE_CLK(GCC_UFS_CARD_UNIPRO_CORE_CLK, 0x75054, 0x00000001), 114 116 GATE_CLK(GCC_UFS_MEM_CLKREF_CLK, 0x8c000, 0x00000001), 117 + GATE_CLK(GCC_AGGRE_UFS_PHY_AXI_CLK, 0x82024, 0x00000001), 115 118 GATE_CLK(GCC_UFS_PHY_AHB_CLK, 0x77010, 0x00000001), 116 119 GATE_CLK(GCC_UFS_PHY_AXI_CLK, 0x7700c, 0x00000001), 117 120 GATE_CLK(GCC_UFS_PHY_ICE_CORE_CLK, 0x77058, 0x00000001),
+49 -4
drivers/gpio/msm_gpio.c
··· 151 151 152 152 static int msm_gpio_set_flags(struct udevice *dev, unsigned int gpio, ulong flags) 153 153 { 154 + if (msm_pinctrl_is_reserved(dev_get_parent(dev), gpio)) 155 + return -EPERM; 156 + 154 157 if (flags & GPIOD_IS_OUT_ACTIVE) { 155 158 return msm_gpio_direction_output(dev, gpio, 1); 156 159 } else if (flags & GPIOD_IS_OUT) { ··· 172 175 const struct msm_special_pin_data *data; 173 176 174 177 if (!priv->pin_data->special_pins_data) 175 - return 0; 178 + return -EINVAL; 176 179 177 180 data = &priv->pin_data->special_pins_data[offset]; 178 181 179 - if (!data->io_reg || data->in_bit >= 31) 180 - return 0; 182 + if (!data->io_reg) 183 + return -EINVAL; 184 + 185 + if (data->in_bit >= 31) { 186 + if (data->out_bit >= 31) 187 + return -EINVAL; 188 + 189 + return !!(readl(priv->base + data->io_reg) >> data->out_bit); 190 + } 181 191 182 192 return !!(readl(priv->base + data->io_reg) >> data->in_bit); 183 193 } ··· 186 196 { 187 197 struct msm_gpio_bank *priv = dev_get_priv(dev); 188 198 199 + if (msm_pinctrl_is_reserved(dev_get_parent(dev), gpio)) 200 + return -EPERM; 201 + 189 202 if (qcom_is_special_pin(priv->pin_data, gpio)) 190 203 return msm_gpio_get_value_special(priv, gpio); 191 204 192 205 return !!(readl(priv->base + GPIO_IN_OUT_REG(dev, gpio)) >> GPIO_IN); 193 206 } 194 207 208 + static int msm_gpio_get_function_special(struct msm_gpio_bank *priv, 209 + unsigned int gpio) 210 + { 211 + unsigned int offset = gpio - priv->pin_data->special_pins_start; 212 + const struct msm_special_pin_data *data; 213 + 214 + if (!priv->pin_data->special_pins_data) 215 + return GPIOF_UNKNOWN; 216 + 217 + data = &priv->pin_data->special_pins_data[offset]; 218 + 219 + /* No I/O fields, cannot control/read the I/O value */ 220 + if (!data->io_reg || (data->out_bit >= 31 && data->in_bit >= 31)) 221 + return GPIOF_FUNC; 222 + 223 + /* No Output-Enable register, cannot control I/O direction */ 224 + if (!data->ctl_reg || data->oe_bit >= 31) { 225 + if (data->out_bit >= 31) 226 + return GPIOF_INPUT; 227 + else 228 + return GPIOF_OUTPUT; 229 + } 230 + 231 + if (readl(priv->base + data->ctl_reg) & BIT(data->oe_bit)) 232 + return GPIOF_OUTPUT; 233 + 234 + return GPIOF_INPUT; 235 + } 236 + 195 237 static int msm_gpio_get_function(struct udevice *dev, unsigned int gpio) 196 238 { 197 239 struct msm_gpio_bank *priv = dev_get_priv(dev); 198 240 241 + if (msm_pinctrl_is_reserved(dev_get_parent(dev), gpio)) 242 + return GPIOF_UNKNOWN; 243 + 199 244 /* Always NOP for special pins, assume they're in the correct state */ 200 245 if (qcom_is_special_pin(priv->pin_data, gpio)) 201 - return 0; 246 + return msm_gpio_get_function_special(priv, gpio); 202 247 203 248 if (readl(priv->base + GPIO_CONFIG_REG(dev, gpio)) & GPIO_OE_ENABLE) 204 249 return GPIOF_OUTPUT;
+43 -1
drivers/phy/qcom/phy-qcom-qusb2.c
··· 122 122 123 123 /* true if PHY has PLL_CORE_INPUT_OVERRIDE register to reset PLL */ 124 124 bool has_pll_override; 125 + 126 + /* true if PHY default clk scheme is single-ended */ 127 + bool se_clk_scheme_default; 125 128 }; 126 129 127 130 /* set of registers with offsets different per-PHY */ ··· 173 176 [QUSB2PHY_PORT_POWERDOWN] = 0xb4, [QUSB2PHY_INTR_CTRL] = 0xbc, 174 177 }; 175 178 179 + static const struct qusb2_phy_init_tbl msm8996_init_tbl[] = { 180 + QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE1, 0xf8), 181 + QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE2, 0xb3), 182 + QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE3, 0x83), 183 + QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE4, 0xc0), 184 + QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_TUNE, 0x30), 185 + QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_USER_CTL1, 0x79), 186 + QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_USER_CTL2, 0x21), 187 + QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TEST2, 0x14), 188 + QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_AUTOPGM_CTL1, 0x9f), 189 + QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_PWR_CTRL, 0x00), 190 + }; 191 + 176 192 static const struct qusb2_phy_init_tbl qusb2_v2_init_tbl[] = { 177 193 QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_ANALOG_CONTROLS_TWO, 0x03), 178 194 QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_CLOCK_INVERTERS, 0x7c), ··· 214 230 .regs = sm6115_regs_layout, 215 231 216 232 .has_pll_test = true, 233 + .se_clk_scheme_default = true, 234 + .disable_ctrl = (CLAMP_N_EN | FREEZIO_N | POWER_DOWN), 235 + .mask_core_ready = PLL_LOCKED, 236 + .autoresume_en = BIT(3), 237 + }; 238 + 239 + static const struct qusb2_phy_cfg sdm660_phy_cfg = { 240 + .tbl = msm8996_init_tbl, 241 + .tbl_num = ARRAY_SIZE(msm8996_init_tbl), 242 + .regs = sm6115_regs_layout, 243 + 244 + .has_pll_test = true, 245 + .se_clk_scheme_default = false, 217 246 .disable_ctrl = (CLAMP_N_EN | FREEZIO_N | POWER_DOWN), 218 247 .mask_core_ready = PLL_LOCKED, 219 248 .autoresume_en = BIT(3), ··· 228 257 POWER_DOWN), 229 258 .mask_core_ready = CORE_READY_STATUS, 230 259 .has_pll_override = true, 260 + .se_clk_scheme_default = true, 231 261 .autoresume_en = BIT(0), 232 262 .update_tune1_with_efuse = true, 233 263 }; ··· 316 346 /* Required to get phy pll lock successfully */ 317 347 udelay(150); 318 348 349 + /* 350 + * Not all the SoCs have got a readable TCSR_PHY_CLK_SCHEME 351 + * register in the TCSR so, if there's none, use the default 352 + * value hardcoded in the configuration. 353 + */ 354 + qphy->has_se_clk_scheme = cfg->se_clk_scheme_default; 355 + 319 356 if (cfg->has_pll_test) { 320 - val |= CLK_REF_SEL; 357 + if (!qphy->has_se_clk_scheme) 358 + val &= ~CLK_REF_SEL; 359 + else 360 + val |= CLK_REF_SEL; 321 361 322 362 writel(val, qphy->base + QUSB2PHY_PLL_TEST); 323 363 ··· 413 453 { .compatible = "qcom,qusb2-phy" }, 414 454 { .compatible = "qcom,qcm2290-qusb2-phy", 415 455 .data = (ulong)&sm6115_phy_cfg }, 456 + { .compatible = "qcom,sdm660-qusb2-phy", 457 + .data = (ulong)&sdm660_phy_cfg }, 416 458 { .compatible = "qcom,sm6115-qusb2-phy", 417 459 .data = (ulong)&sm6115_phy_cfg }, 418 460 { .compatible = "qcom,qusb2-v2-phy", .data = (ulong)&qusb2_v2_phy_cfg },
+14 -1
drivers/pinctrl/qcom/Kconfig
··· 48 48 Say Y here to enable support for pinctrl on the Snapdragon QCS404 SoC, 49 49 as well as the associated GPIO driver. 50 50 51 + config PINCTRL_QCOM_SA8775P 52 + bool "Qualcomm SA8775P Pinctrl" 53 + select PINCTRL_QCOM 54 + help 55 + Say Y here to enable support for pinctrl on the Snapdragon SA8775P SoC, 56 + as well as the associated GPIO driver. 57 + 51 58 config PINCTRL_QCOM_SC7280 52 59 bool "Qualcomm SC7280/QCM6490 Pinctrl" 53 60 select PINCTRL_QCOM 54 61 help 55 62 Say Y here to enable support for pinctrl on the Snapdragon SC7280 SoC, 56 - as well as the associated GPIO driver. 63 + 64 + config PINCTRL_QCOM_SDM660 65 + bool "Qualcomm SDM630/660 Pinctrl" 66 + select PINCTRL_QCOM 67 + help 68 + Say Y here to enable support for pinctrl on the Snapdragon 630/636/660 69 + SoCs, as well as the associated GPIO driver. 57 70 58 71 config PINCTRL_QCOM_SDM845 59 72 bool "Qualcomm SDM845 Pinctrl"
+2
drivers/pinctrl/qcom/Makefile
··· 9 9 obj-$(CONFIG_PINCTRL_QCOM_APQ8096) += pinctrl-apq8096.o 10 10 obj-$(CONFIG_PINCTRL_QCOM_QCM2290) += pinctrl-qcm2290.o 11 11 obj-$(CONFIG_PINCTRL_QCOM_QCS404) += pinctrl-qcs404.o 12 + obj-$(CONFIG_PINCTRL_QCOM_SA8775P) += pinctrl-sa8775p.o 12 13 obj-$(CONFIG_PINCTRL_QCOM_SC7280) += pinctrl-sc7280.o 14 + obj-$(CONFIG_PINCTRL_QCOM_SDM660) += pinctrl-sdm660.o 13 15 obj-$(CONFIG_PINCTRL_QCOM_SDM845) += pinctrl-sdm845.o 14 16 obj-$(CONFIG_PINCTRL_QCOM_SM6115) += pinctrl-sm6115.o 15 17 obj-$(CONFIG_PINCTRL_QCOM_SM8150) += pinctrl-sm8150.o
+67
drivers/pinctrl/qcom/pinctrl-qcom.c
··· 15 15 #include <asm/gpio.h> 16 16 #include <dm/pinctrl.h> 17 17 #include <linux/bitops.h> 18 + #include <linux/bitmap.h> 18 19 #include <linux/bug.h> 19 20 #include <mach/gpio.h> 20 21 21 22 #include "pinctrl-qcom.h" 22 23 24 + #define MSM_PINCTRL_MAX_PINS 256 25 + 23 26 struct msm_pinctrl_priv { 24 27 phys_addr_t base; 25 28 struct msm_pinctrl_data *data; 29 + DECLARE_BITMAP(reserved_map, MSM_PINCTRL_MAX_PINS); 26 30 }; 27 31 28 32 #define GPIO_CONFIG_REG(priv, x) \ ··· 71 75 return priv->data->get_function_name(dev, selector); 72 76 } 73 77 78 + static int msm_pinctrl_parse_ranges(struct udevice *dev) 79 + { 80 + struct msm_pinctrl_priv *priv = dev_get_priv(dev); 81 + ofnode node = dev_ofnode(dev); 82 + int ret, count, i; 83 + u32 *ranges; 84 + 85 + if (ofnode_read_prop(node, "gpio-reserved-ranges", &count)) { 86 + if (count % 2 == 1) { 87 + dev_err(dev, "gpio-reserved-ranges must be a multiple of 2\n"); 88 + return -EINVAL; 89 + } 90 + 91 + ranges = malloc(count); 92 + if (!ranges) 93 + return -ENOMEM; 94 + 95 + ret = ofnode_read_u32_array(node, "gpio-reserved-ranges", ranges, count / 4); 96 + if (ret) { 97 + dev_err(dev, "failed to read gpio-reserved-ranges array (%d)\n", ret); 98 + return ret; 99 + } 100 + 101 + for (i = 0; i < count / 4; i += 2) { 102 + if (ranges[i] >= MSM_PINCTRL_MAX_PINS || 103 + (ranges[i] + ranges[i + 1]) >= MSM_PINCTRL_MAX_PINS) { 104 + dev_err(dev, "invalid reserved-range (%d;%d)\n", 105 + ranges[i], ranges[i + 1]); 106 + return -EINVAL; 107 + } 108 + 109 + bitmap_set(priv->reserved_map, ranges[i], ranges[i + 1]); 110 + } 111 + 112 + free(ranges); 113 + } 114 + 115 + return 0; 116 + } 117 + 74 118 static int msm_pinctrl_probe(struct udevice *dev) 75 119 { 76 120 struct msm_pinctrl_priv *priv = dev_get_priv(dev); 121 + int ret; 77 122 78 123 priv->base = dev_read_addr(dev); 79 124 priv->data = (struct msm_pinctrl_data *)dev_get_driver_data(dev); 125 + 126 + ret = msm_pinctrl_parse_ranges(dev); 127 + if (ret) { 128 + printf("Couldn't parse reserved GPIO ranges!\n"); 129 + return ret; 130 + } 80 131 81 132 return priv->base == FDT_ADDR_T_NONE ? -EINVAL : 0; 82 133 } ··· 97 148 if (func < 0) 98 149 return func; 99 150 151 + if (msm_pinctrl_is_reserved(dev, pin_selector)) 152 + return -EPERM; 153 + 100 154 /* Always NOP for special pins, assume they're in the correct state */ 101 155 if (qcom_is_special_pin(&priv->data->pin_data, pin_selector)) 102 156 return 0; ··· 144 198 unsigned int param, unsigned int argument) 145 199 { 146 200 struct msm_pinctrl_priv *priv = dev_get_priv(dev); 201 + 202 + if (msm_pinctrl_is_reserved(dev, pin_selector)) 203 + return -EPERM; 147 204 148 205 if (qcom_is_special_pin(&priv->data->pin_data, pin_selector)) 149 206 return msm_pinconf_set_special(priv, pin_selector, param, argument); ··· 241 298 .ops = &msm_pinctrl_ops, 242 299 .probe = msm_pinctrl_probe, 243 300 }; 301 + 302 + bool msm_pinctrl_is_reserved(struct udevice *dev, unsigned int pin) 303 + { 304 + struct msm_pinctrl_priv *priv = dev_get_priv(dev); 305 + 306 + if (pin >= MSM_PINCTRL_MAX_PINS) 307 + return false; 308 + 309 + return test_bit(pin, priv->reserved_map); 310 + }
+623
drivers/pinctrl/qcom/pinctrl-sa8775p.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. 4 + * Copyright (c) 2023, Linaro Limited 5 + */ 6 + 7 + #include <dm.h> 8 + 9 + #include "pinctrl-qcom.h" 10 + 11 + #define MAX_PIN_NAME_LEN 32 12 + static char pin_name[MAX_PIN_NAME_LEN] __section(".data"); 13 + 14 + typedef unsigned int msm_pin_function[10]; 15 + #define SA8775_PIN_OFFSET 0x100000 16 + 17 + #define PINGROUP(id, f1, f2, f3, f4, f5, f6, f7, f8, f9)\ 18 + { \ 19 + msm_mux_gpio, /* gpio mode */ \ 20 + msm_mux_##f1, \ 21 + msm_mux_##f2, \ 22 + msm_mux_##f3, \ 23 + msm_mux_##f4, \ 24 + msm_mux_##f5, \ 25 + msm_mux_##f6, \ 26 + msm_mux_##f7, \ 27 + msm_mux_##f8, \ 28 + msm_mux_##f9 \ 29 + } 30 + 31 + #define SDC_QDSD_PINGROUP(pg_name, ctl, pull, drv) \ 32 + { \ 33 + .name = pg_name, \ 34 + .ctl_reg = ctl, \ 35 + .io_reg = 0, \ 36 + .pull_bit = pull, \ 37 + .drv_bit = drv, \ 38 + .oe_bit = -1, \ 39 + .in_bit = -1, \ 40 + .out_bit = -1, \ 41 + } 42 + 43 + #define UFS_RESET(pg_name, ctl) \ 44 + { \ 45 + .name = pg_name, \ 46 + .ctl_reg = ctl, \ 47 + .io_reg = ctl + 0x4, \ 48 + .pull_bit = 3, \ 49 + .drv_bit = 0, \ 50 + .oe_bit = -1, \ 51 + .in_bit = -1, \ 52 + .out_bit = 0, \ 53 + } 54 + 55 + enum sa8775p_functions { 56 + msm_mux_gpio, 57 + msm_mux_atest_char, 58 + msm_mux_atest_usb2, 59 + msm_mux_audio_ref, 60 + msm_mux_cam_mclk, 61 + msm_mux_cci_async, 62 + msm_mux_cci_i2c, 63 + msm_mux_cci_timer0, 64 + msm_mux_cci_timer1, 65 + msm_mux_cci_timer2, 66 + msm_mux_cci_timer3, 67 + msm_mux_cci_timer4, 68 + msm_mux_cci_timer5, 69 + msm_mux_cci_timer6, 70 + msm_mux_cci_timer7, 71 + msm_mux_cci_timer8, 72 + msm_mux_cci_timer9, 73 + msm_mux_cri_trng, 74 + msm_mux_cri_trng0, 75 + msm_mux_cri_trng1, 76 + msm_mux_dbg_out, 77 + msm_mux_ddr_bist, 78 + msm_mux_ddr_pxi0, 79 + msm_mux_ddr_pxi1, 80 + msm_mux_ddr_pxi2, 81 + msm_mux_ddr_pxi3, 82 + msm_mux_ddr_pxi4, 83 + msm_mux_ddr_pxi5, 84 + msm_mux_edp0_hot, 85 + msm_mux_edp0_lcd, 86 + msm_mux_edp1_hot, 87 + msm_mux_edp1_lcd, 88 + msm_mux_edp2_hot, 89 + msm_mux_edp2_lcd, 90 + msm_mux_edp3_hot, 91 + msm_mux_edp3_lcd, 92 + msm_mux_emac0_mcg0, 93 + msm_mux_emac0_mcg1, 94 + msm_mux_emac0_mcg2, 95 + msm_mux_emac0_mcg3, 96 + msm_mux_emac0_mdc, 97 + msm_mux_emac0_mdio, 98 + msm_mux_emac0_ptp_aux, 99 + msm_mux_emac0_ptp_pps, 100 + msm_mux_emac1_mcg0, 101 + msm_mux_emac1_mcg1, 102 + msm_mux_emac1_mcg2, 103 + msm_mux_emac1_mcg3, 104 + msm_mux_emac1_mdc, 105 + msm_mux_emac1_mdio, 106 + msm_mux_emac1_ptp_aux, 107 + msm_mux_emac1_ptp_pps, 108 + msm_mux_gcc_gp1, 109 + msm_mux_gcc_gp2, 110 + msm_mux_gcc_gp3, 111 + msm_mux_gcc_gp4, 112 + msm_mux_gcc_gp5, 113 + msm_mux_hs0_mi2s, 114 + msm_mux_hs1_mi2s, 115 + msm_mux_hs2_mi2s, 116 + msm_mux_ibi_i3c, 117 + msm_mux_jitter_bist, 118 + msm_mux_mdp0_vsync0, 119 + msm_mux_mdp0_vsync1, 120 + msm_mux_mdp0_vsync2, 121 + msm_mux_mdp0_vsync3, 122 + msm_mux_mdp0_vsync4, 123 + msm_mux_mdp0_vsync5, 124 + msm_mux_mdp0_vsync6, 125 + msm_mux_mdp0_vsync7, 126 + msm_mux_mdp0_vsync8, 127 + msm_mux_mdp1_vsync0, 128 + msm_mux_mdp1_vsync1, 129 + msm_mux_mdp1_vsync2, 130 + msm_mux_mdp1_vsync3, 131 + msm_mux_mdp1_vsync4, 132 + msm_mux_mdp1_vsync5, 133 + msm_mux_mdp1_vsync6, 134 + msm_mux_mdp1_vsync7, 135 + msm_mux_mdp1_vsync8, 136 + msm_mux_mdp_vsync, 137 + msm_mux_mi2s1_data0, 138 + msm_mux_mi2s1_data1, 139 + msm_mux_mi2s1_sck, 140 + msm_mux_mi2s1_ws, 141 + msm_mux_mi2s2_data0, 142 + msm_mux_mi2s2_data1, 143 + msm_mux_mi2s2_sck, 144 + msm_mux_mi2s2_ws, 145 + msm_mux_mi2s_mclk0, 146 + msm_mux_mi2s_mclk1, 147 + msm_mux_pcie0_clkreq, 148 + msm_mux_pcie1_clkreq, 149 + msm_mux_phase_flag, 150 + msm_mux_pll_bist, 151 + msm_mux_pll_clk, 152 + msm_mux_prng_rosc0, 153 + msm_mux_prng_rosc1, 154 + msm_mux_prng_rosc2, 155 + msm_mux_prng_rosc3, 156 + msm_mux_qdss_cti, 157 + msm_mux_qdss_gpio, 158 + msm_mux_qup0_se0, 159 + msm_mux_qup0_se1, 160 + msm_mux_qup0_se2, 161 + msm_mux_qup0_se3, 162 + msm_mux_qup0_se4, 163 + msm_mux_qup0_se5, 164 + msm_mux_qup1_se0, 165 + msm_mux_qup1_se1, 166 + msm_mux_qup1_se2, 167 + msm_mux_qup1_se3, 168 + msm_mux_qup1_se4, 169 + msm_mux_qup1_se5, 170 + msm_mux_qup1_se6, 171 + msm_mux_qup2_se0, 172 + msm_mux_qup2_se1, 173 + msm_mux_qup2_se2, 174 + msm_mux_qup2_se3, 175 + msm_mux_qup2_se4, 176 + msm_mux_qup2_se5, 177 + msm_mux_qup2_se6, 178 + msm_mux_qup3_se0, 179 + msm_mux_sail_top, 180 + msm_mux_sailss_emac0, 181 + msm_mux_sailss_ospi, 182 + msm_mux_sgmii_phy, 183 + msm_mux_tb_trig, 184 + msm_mux_tgu_ch0, 185 + msm_mux_tgu_ch1, 186 + msm_mux_tgu_ch2, 187 + msm_mux_tgu_ch3, 188 + msm_mux_tgu_ch4, 189 + msm_mux_tgu_ch5, 190 + msm_mux_tsense_pwm1, 191 + msm_mux_tsense_pwm2, 192 + msm_mux_tsense_pwm3, 193 + msm_mux_tsense_pwm4, 194 + msm_mux_usb2phy_ac, 195 + msm_mux_vsense_trigger, 196 + msm_mux__, 197 + }; 198 + 199 + #define MSM_PIN_FUNCTION(fname) \ 200 + [msm_mux_##fname] = {#fname, msm_mux_##fname} 201 + 202 + static const struct pinctrl_function msm_pinctrl_functions[] = { 203 + MSM_PIN_FUNCTION(gpio), 204 + MSM_PIN_FUNCTION(atest_char), 205 + MSM_PIN_FUNCTION(atest_usb2), 206 + MSM_PIN_FUNCTION(audio_ref), 207 + MSM_PIN_FUNCTION(cam_mclk), 208 + MSM_PIN_FUNCTION(cci_async), 209 + MSM_PIN_FUNCTION(cci_i2c), 210 + MSM_PIN_FUNCTION(cci_timer0), 211 + MSM_PIN_FUNCTION(cci_timer1), 212 + MSM_PIN_FUNCTION(cci_timer2), 213 + MSM_PIN_FUNCTION(cci_timer3), 214 + MSM_PIN_FUNCTION(cci_timer4), 215 + MSM_PIN_FUNCTION(cci_timer5), 216 + MSM_PIN_FUNCTION(cci_timer6), 217 + MSM_PIN_FUNCTION(cci_timer7), 218 + MSM_PIN_FUNCTION(cci_timer8), 219 + MSM_PIN_FUNCTION(cci_timer9), 220 + MSM_PIN_FUNCTION(cri_trng), 221 + MSM_PIN_FUNCTION(cri_trng0), 222 + MSM_PIN_FUNCTION(cri_trng1), 223 + MSM_PIN_FUNCTION(dbg_out), 224 + MSM_PIN_FUNCTION(ddr_bist), 225 + MSM_PIN_FUNCTION(ddr_pxi0), 226 + MSM_PIN_FUNCTION(ddr_pxi1), 227 + MSM_PIN_FUNCTION(ddr_pxi2), 228 + MSM_PIN_FUNCTION(ddr_pxi3), 229 + MSM_PIN_FUNCTION(ddr_pxi4), 230 + MSM_PIN_FUNCTION(ddr_pxi5), 231 + MSM_PIN_FUNCTION(edp0_hot), 232 + MSM_PIN_FUNCTION(edp0_lcd), 233 + MSM_PIN_FUNCTION(edp1_hot), 234 + MSM_PIN_FUNCTION(edp1_lcd), 235 + MSM_PIN_FUNCTION(edp2_hot), 236 + MSM_PIN_FUNCTION(edp2_lcd), 237 + MSM_PIN_FUNCTION(edp3_hot), 238 + MSM_PIN_FUNCTION(edp3_lcd), 239 + MSM_PIN_FUNCTION(emac0_mcg0), 240 + MSM_PIN_FUNCTION(emac0_mcg1), 241 + MSM_PIN_FUNCTION(emac0_mcg2), 242 + MSM_PIN_FUNCTION(emac0_mcg3), 243 + MSM_PIN_FUNCTION(emac0_mdc), 244 + MSM_PIN_FUNCTION(emac0_mdio), 245 + MSM_PIN_FUNCTION(emac0_ptp_aux), 246 + MSM_PIN_FUNCTION(emac0_ptp_pps), 247 + MSM_PIN_FUNCTION(emac1_mcg0), 248 + MSM_PIN_FUNCTION(emac1_mcg1), 249 + MSM_PIN_FUNCTION(emac1_mcg2), 250 + MSM_PIN_FUNCTION(emac1_mcg3), 251 + MSM_PIN_FUNCTION(emac1_mdc), 252 + MSM_PIN_FUNCTION(emac1_mdio), 253 + MSM_PIN_FUNCTION(emac1_ptp_aux), 254 + MSM_PIN_FUNCTION(emac1_ptp_pps), 255 + MSM_PIN_FUNCTION(gcc_gp1), 256 + MSM_PIN_FUNCTION(gcc_gp2), 257 + MSM_PIN_FUNCTION(gcc_gp3), 258 + MSM_PIN_FUNCTION(gcc_gp4), 259 + MSM_PIN_FUNCTION(gcc_gp5), 260 + MSM_PIN_FUNCTION(hs0_mi2s), 261 + MSM_PIN_FUNCTION(hs1_mi2s), 262 + MSM_PIN_FUNCTION(hs2_mi2s), 263 + MSM_PIN_FUNCTION(ibi_i3c), 264 + MSM_PIN_FUNCTION(jitter_bist), 265 + MSM_PIN_FUNCTION(mdp0_vsync0), 266 + MSM_PIN_FUNCTION(mdp0_vsync1), 267 + MSM_PIN_FUNCTION(mdp0_vsync2), 268 + MSM_PIN_FUNCTION(mdp0_vsync3), 269 + MSM_PIN_FUNCTION(mdp0_vsync4), 270 + MSM_PIN_FUNCTION(mdp0_vsync5), 271 + MSM_PIN_FUNCTION(mdp0_vsync6), 272 + MSM_PIN_FUNCTION(mdp0_vsync7), 273 + MSM_PIN_FUNCTION(mdp0_vsync8), 274 + MSM_PIN_FUNCTION(mdp1_vsync0), 275 + MSM_PIN_FUNCTION(mdp1_vsync1), 276 + MSM_PIN_FUNCTION(mdp1_vsync2), 277 + MSM_PIN_FUNCTION(mdp1_vsync3), 278 + MSM_PIN_FUNCTION(mdp1_vsync4), 279 + MSM_PIN_FUNCTION(mdp1_vsync5), 280 + MSM_PIN_FUNCTION(mdp1_vsync6), 281 + MSM_PIN_FUNCTION(mdp1_vsync7), 282 + MSM_PIN_FUNCTION(mdp1_vsync8), 283 + MSM_PIN_FUNCTION(mdp_vsync), 284 + MSM_PIN_FUNCTION(mi2s1_data0), 285 + MSM_PIN_FUNCTION(mi2s1_data1), 286 + MSM_PIN_FUNCTION(mi2s1_sck), 287 + MSM_PIN_FUNCTION(mi2s1_ws), 288 + MSM_PIN_FUNCTION(mi2s2_data0), 289 + MSM_PIN_FUNCTION(mi2s2_data1), 290 + MSM_PIN_FUNCTION(mi2s2_sck), 291 + MSM_PIN_FUNCTION(mi2s2_ws), 292 + MSM_PIN_FUNCTION(mi2s_mclk0), 293 + MSM_PIN_FUNCTION(mi2s_mclk1), 294 + MSM_PIN_FUNCTION(pcie0_clkreq), 295 + MSM_PIN_FUNCTION(pcie1_clkreq), 296 + MSM_PIN_FUNCTION(phase_flag), 297 + MSM_PIN_FUNCTION(pll_bist), 298 + MSM_PIN_FUNCTION(pll_clk), 299 + MSM_PIN_FUNCTION(prng_rosc0), 300 + MSM_PIN_FUNCTION(prng_rosc1), 301 + MSM_PIN_FUNCTION(prng_rosc2), 302 + MSM_PIN_FUNCTION(prng_rosc3), 303 + MSM_PIN_FUNCTION(qdss_cti), 304 + MSM_PIN_FUNCTION(qdss_gpio), 305 + MSM_PIN_FUNCTION(qup0_se0), 306 + MSM_PIN_FUNCTION(qup0_se1), 307 + MSM_PIN_FUNCTION(qup0_se2), 308 + MSM_PIN_FUNCTION(qup0_se3), 309 + MSM_PIN_FUNCTION(qup0_se4), 310 + MSM_PIN_FUNCTION(qup0_se5), 311 + MSM_PIN_FUNCTION(qup1_se0), 312 + MSM_PIN_FUNCTION(qup1_se1), 313 + MSM_PIN_FUNCTION(qup1_se2), 314 + MSM_PIN_FUNCTION(qup1_se3), 315 + MSM_PIN_FUNCTION(qup1_se4), 316 + MSM_PIN_FUNCTION(qup1_se5), 317 + MSM_PIN_FUNCTION(qup1_se6), 318 + MSM_PIN_FUNCTION(qup2_se0), 319 + MSM_PIN_FUNCTION(qup2_se1), 320 + MSM_PIN_FUNCTION(qup2_se2), 321 + MSM_PIN_FUNCTION(qup2_se3), 322 + MSM_PIN_FUNCTION(qup2_se4), 323 + MSM_PIN_FUNCTION(qup2_se5), 324 + MSM_PIN_FUNCTION(qup2_se6), 325 + MSM_PIN_FUNCTION(qup3_se0), 326 + MSM_PIN_FUNCTION(sail_top), 327 + MSM_PIN_FUNCTION(sailss_emac0), 328 + MSM_PIN_FUNCTION(sailss_ospi), 329 + MSM_PIN_FUNCTION(sgmii_phy), 330 + MSM_PIN_FUNCTION(tb_trig), 331 + MSM_PIN_FUNCTION(tgu_ch0), 332 + MSM_PIN_FUNCTION(tgu_ch1), 333 + MSM_PIN_FUNCTION(tgu_ch2), 334 + MSM_PIN_FUNCTION(tgu_ch3), 335 + MSM_PIN_FUNCTION(tgu_ch4), 336 + MSM_PIN_FUNCTION(tgu_ch5), 337 + MSM_PIN_FUNCTION(tsense_pwm1), 338 + MSM_PIN_FUNCTION(tsense_pwm2), 339 + MSM_PIN_FUNCTION(tsense_pwm3), 340 + MSM_PIN_FUNCTION(tsense_pwm4), 341 + MSM_PIN_FUNCTION(usb2phy_ac), 342 + MSM_PIN_FUNCTION(vsense_trigger), 343 + }; 344 + 345 + static const msm_pin_function sa8775p_pin_functions[] = { 346 + [0] = PINGROUP(0, _, _, _, _, _, _, _, _, _), 347 + [1] = PINGROUP(1, pcie0_clkreq, _, _, _, _, _, _, _, _), 348 + [2] = PINGROUP(2, _, _, _, _, _, _, _, _, _), 349 + [3] = PINGROUP(3, pcie1_clkreq, _, _, _, _, _, _, _, _), 350 + [4] = PINGROUP(4, _, _, _, _, _, _, _, _, _), 351 + [5] = PINGROUP(5, _, _, _, _, _, _, _, _, _), 352 + [6] = PINGROUP(6, emac0_ptp_aux, emac0_ptp_pps, emac1_ptp_aux, 353 + emac1_ptp_pps, _, _, _, _, _), 354 + [7] = PINGROUP(7, sgmii_phy, _, _, _, _, _, _, _, _), 355 + [8] = PINGROUP(8, emac0_mdc, _, _, _, _, _, _, _, _), 356 + [9] = PINGROUP(9, emac0_mdio, _, _, _, _, _, _, _, _), 357 + [10] = PINGROUP(10, usb2phy_ac, emac0_ptp_aux, emac0_ptp_pps, 358 + emac1_ptp_aux, emac1_ptp_pps, _, _, _, _), 359 + [11] = PINGROUP(11, usb2phy_ac, emac0_ptp_aux, emac0_ptp_pps, 360 + emac1_ptp_aux, emac1_ptp_pps, _, _, _, _), 361 + [12] = PINGROUP(12, usb2phy_ac, emac0_ptp_aux, emac0_ptp_pps, 362 + emac1_ptp_aux, emac1_ptp_pps, emac0_mcg0, _, _, _), 363 + [13] = PINGROUP(13, qup3_se0, emac0_mcg1, _, _, sail_top, _, _, _, _), 364 + [14] = PINGROUP(14, qup3_se0, emac0_mcg2, _, _, sail_top, _, _, _, _), 365 + [15] = PINGROUP(15, qup3_se0, emac0_mcg3, _, _, sail_top, _, _, _, _), 366 + [16] = PINGROUP(16, qup3_se0, emac1_mcg0, _, _, sail_top, _, _, _, _), 367 + [17] = PINGROUP(17, qup3_se0, tb_trig, tb_trig, emac1_mcg1, _, _, _, _, _), 368 + [18] = PINGROUP(18, qup3_se0, emac1_mcg2, _, _, sailss_ospi, sailss_emac0, _, _, _), 369 + [19] = PINGROUP(19, qup3_se0, emac1_mcg3, _, _, sailss_ospi, sailss_emac0, _, _, _), 370 + [20] = PINGROUP(20, qup0_se0, emac1_mdc, qdss_gpio, _, _, _, _, _, _), 371 + [21] = PINGROUP(21, qup0_se0, emac1_mdio, qdss_gpio, _, _, _, _, _, _), 372 + [22] = PINGROUP(22, qup0_se0, qdss_gpio, _, _, _, _, _, _, _), 373 + [23] = PINGROUP(23, qup0_se0, qdss_gpio, _, _, _, _, _, _, _), 374 + [24] = PINGROUP(24, qup0_se1, qdss_gpio, _, _, _, _, _, _, _), 375 + [25] = PINGROUP(25, qup0_se1, phase_flag, _, qdss_gpio, _, _, _, _, _), 376 + [26] = PINGROUP(26, sgmii_phy, qup0_se1, qdss_cti, phase_flag, _, _, _, _, _), 377 + [27] = PINGROUP(27, qup0_se1, qdss_cti, phase_flag, _, atest_char, _, _, _, _), 378 + [28] = PINGROUP(28, qup0_se3, phase_flag, _, qdss_gpio, _, _, _, _, _), 379 + [29] = PINGROUP(29, qup0_se3, phase_flag, _, qdss_gpio, _, _, _, _, _), 380 + [30] = PINGROUP(30, qup0_se3, phase_flag, _, qdss_gpio, _, _, _, _, _), 381 + [31] = PINGROUP(31, qup0_se3, phase_flag, _, qdss_gpio, _, _, _, _, _), 382 + [32] = PINGROUP(32, qup0_se4, phase_flag, _, _, _, _, _, _, _), 383 + [33] = PINGROUP(33, qup0_se4, gcc_gp4, _, ddr_pxi0, _, _, _, _, _), 384 + [34] = PINGROUP(34, qup0_se4, gcc_gp5, _, ddr_pxi0, _, _, _, _, _), 385 + [35] = PINGROUP(35, qup0_se4, phase_flag, _, _, _, _, _, _, _), 386 + [36] = PINGROUP(36, qup0_se2, qup0_se5, phase_flag, tgu_ch2, _, _, _, _, _), 387 + [37] = PINGROUP(37, qup0_se2, qup0_se5, phase_flag, tgu_ch3, _, _, _, _, _), 388 + [38] = PINGROUP(38, qup0_se5, qup0_se2, qdss_cti, phase_flag, tgu_ch4, _, _, _, _), 389 + [39] = PINGROUP(39, qup0_se5, qup0_se2, qdss_cti, phase_flag, tgu_ch5, _, _, _, _), 390 + [40] = PINGROUP(40, qup1_se0, qup1_se1, ibi_i3c, mdp1_vsync0, _, _, _, _, _), 391 + [41] = PINGROUP(41, qup1_se0, qup1_se1, ibi_i3c, mdp1_vsync1, _, _, _, _, _), 392 + [42] = PINGROUP(42, qup1_se1, qup1_se0, ibi_i3c, mdp1_vsync2, gcc_gp5, _, _, _, _), 393 + [43] = PINGROUP(43, qup1_se1, qup1_se0, ibi_i3c, mdp1_vsync3, _, _, _, _, _), 394 + [44] = PINGROUP(44, qup1_se2, qup1_se3, edp0_lcd, _, _, _, _, _, _), 395 + [45] = PINGROUP(45, qup1_se2, qup1_se3, edp1_lcd, _, _, _, _, _, _), 396 + [46] = PINGROUP(46, qup1_se3, qup1_se2, mdp1_vsync4, tgu_ch0, _, _, _, _, _), 397 + [47] = PINGROUP(47, qup1_se3, qup1_se2, mdp1_vsync5, tgu_ch1, _, _, _, _, _), 398 + [48] = PINGROUP(48, qup1_se4, qdss_cti, edp2_lcd, _, _, _, _, _, _), 399 + [49] = PINGROUP(49, qup1_se4, qdss_cti, edp3_lcd, _, _, _, _, _, _), 400 + [50] = PINGROUP(50, qup1_se4, cci_async, qdss_cti, mdp1_vsync8, _, _, _, _, _), 401 + [51] = PINGROUP(51, qup1_se4, qdss_cti, mdp1_vsync6, gcc_gp1, _, _, _, _, _), 402 + [52] = PINGROUP(52, qup1_se5, cci_timer4, cci_i2c, mdp1_vsync7, gcc_gp2, _, ddr_pxi1, _, _), 403 + [53] = PINGROUP(53, qup1_se5, cci_timer5, cci_i2c, gcc_gp3, _, ddr_pxi1, _, _, _), 404 + [54] = PINGROUP(54, qup1_se5, cci_timer6, cci_i2c, _, _, _, _, _, _), 405 + [55] = PINGROUP(55, qup1_se5, cci_timer7, cci_i2c, gcc_gp4, _, ddr_pxi2, _, _, _), 406 + [56] = PINGROUP(56, qup1_se6, qup1_se6, cci_timer8, cci_i2c, phase_flag, ddr_bist, _, _, _), 407 + [57] = PINGROUP(57, qup1_se6, qup1_se6, cci_timer9, cci_i2c, 408 + mdp0_vsync0, phase_flag, ddr_bist, _, _), 409 + [58] = PINGROUP(58, cci_i2c, mdp0_vsync1, ddr_bist, _, atest_usb2, atest_char, _, _, _), 410 + [59] = PINGROUP(59, cci_i2c, mdp0_vsync2, ddr_bist, _, atest_usb2, atest_char, _, _, _), 411 + [60] = PINGROUP(60, cci_i2c, qdss_gpio, _, _, _, _, _, _, _), 412 + [61] = PINGROUP(61, cci_i2c, qdss_gpio, _, _, _, _, _, _, _), 413 + [62] = PINGROUP(62, cci_i2c, qdss_gpio, _, _, _, _, _, _, _), 414 + [63] = PINGROUP(63, cci_i2c, qdss_gpio, _, _, _, _, _, _, _), 415 + [64] = PINGROUP(64, cci_i2c, qdss_gpio, _, _, _, _, _, _, _), 416 + [65] = PINGROUP(65, cci_i2c, qdss_gpio, _, _, _, _, _, _, _), 417 + [66] = PINGROUP(66, cci_i2c, cci_async, qdss_gpio, _, _, _, _, _, _), 418 + [67] = PINGROUP(67, cci_i2c, qdss_gpio, _, _, _, _, _, _, _), 419 + [68] = PINGROUP(68, cci_timer0, cci_async, _, _, _, _, _, _, _), 420 + [69] = PINGROUP(69, cci_timer1, cci_async, _, _, _, _, _, _, _), 421 + [70] = PINGROUP(70, cci_timer2, cci_async, _, _, _, _, _, _, _), 422 + [71] = PINGROUP(71, cci_timer3, cci_async, _, _, _, _, _, _, _), 423 + [72] = PINGROUP(72, cam_mclk, _, _, _, _, _, _, _, _), 424 + [73] = PINGROUP(73, cam_mclk, _, _, _, _, _, _, _, _), 425 + [74] = PINGROUP(74, cam_mclk, _, _, _, _, _, _, _, _), 426 + [75] = PINGROUP(75, cam_mclk, _, _, _, _, _, _, _, _), 427 + [76] = PINGROUP(76, _, _, _, _, _, _, _, _, _), 428 + [77] = PINGROUP(77, _, _, _, _, _, _, _, _, _), 429 + [78] = PINGROUP(78, _, _, _, _, _, _, _, _, _), 430 + [79] = PINGROUP(79, _, _, _, _, _, _, _, _, _), 431 + [80] = PINGROUP(80, qup2_se0, ibi_i3c, mdp0_vsync3, _, _, _, _, _, _), 432 + [81] = PINGROUP(81, qup2_se0, ibi_i3c, mdp0_vsync4, _, _, _, _, _, _), 433 + [82] = PINGROUP(82, qup2_se0, mdp_vsync, gcc_gp1, _, _, _, _, _, _), 434 + [83] = PINGROUP(83, qup2_se0, mdp_vsync, gcc_gp2, _, _, _, _, _, _), 435 + [84] = PINGROUP(84, qup2_se1, qup2_se5, ibi_i3c, mdp_vsync, gcc_gp3, _, _, _, _), 436 + [85] = PINGROUP(85, qup2_se1, qup2_se5, ibi_i3c, _, _, _, _, _, _), 437 + [86] = PINGROUP(86, qup2_se2, jitter_bist, atest_usb2, ddr_pxi2, _, _, _, _, _), 438 + [87] = PINGROUP(87, qup2_se2, pll_clk, atest_usb2, ddr_pxi3, _, _, _, _, _), 439 + [88] = PINGROUP(88, qup2_se2, _, atest_usb2, ddr_pxi3, _, _, _, _, _), 440 + [89] = PINGROUP(89, qup2_se2, _, atest_usb2, ddr_pxi4, atest_char, _, _, _, _), 441 + [90] = PINGROUP(90, qup2_se2, _, atest_usb2, ddr_pxi4, atest_char, _, _, _, _), 442 + [91] = PINGROUP(91, qup2_se3, mdp0_vsync5, _, atest_usb2, _, _, _, _, _), 443 + [92] = PINGROUP(92, qup2_se3, mdp0_vsync6, _, atest_usb2, _, _, _, _, _), 444 + [93] = PINGROUP(93, qup2_se3, mdp0_vsync7, _, atest_usb2, _, _, _, _, _), 445 + [94] = PINGROUP(94, qup2_se3, mdp0_vsync8, _, atest_usb2, _, _, _, _, _), 446 + [95] = PINGROUP(95, qup2_se4, qup2_se6, _, atest_usb2, _, _, _, _, _), 447 + [96] = PINGROUP(96, qup2_se4, qup2_se6, _, atest_usb2, _, _, _, _, _), 448 + [97] = PINGROUP(97, qup2_se6, qup2_se4, cri_trng0, _, atest_usb2, _, _, _, _), 449 + [98] = PINGROUP(98, qup2_se6, qup2_se4, phase_flag, cri_trng1, _, _, _, _, _), 450 + [99] = PINGROUP(99, qup2_se5, qup2_se1, phase_flag, cri_trng, _, _, _, _, _), 451 + [100] = PINGROUP(100, qup2_se5, qup2_se1, _, _, _, _, _, _, _), 452 + [101] = PINGROUP(101, edp0_hot, prng_rosc0, tsense_pwm4, _, _, _, _, _, _), 453 + [102] = PINGROUP(102, edp1_hot, prng_rosc1, tsense_pwm3, _, _, _, _, _, _), 454 + [103] = PINGROUP(103, edp3_hot, prng_rosc2, tsense_pwm2, _, _, _, _, _, _), 455 + [104] = PINGROUP(104, edp2_hot, prng_rosc3, tsense_pwm1, _, _, _, _, _, _), 456 + [105] = PINGROUP(105, mi2s_mclk0, _, qdss_gpio, atest_usb2, _, _, _, _, _), 457 + [106] = PINGROUP(106, mi2s1_sck, phase_flag, _, qdss_gpio, _, _, _, _, _), 458 + [107] = PINGROUP(107, mi2s1_ws, phase_flag, _, qdss_gpio, _, _, _, _, _), 459 + [108] = PINGROUP(108, mi2s1_data0, phase_flag, _, qdss_gpio, _, _, _, _, _), 460 + [109] = PINGROUP(109, mi2s1_data1, phase_flag, _, qdss_gpio, _, _, _, _, _), 461 + [110] = PINGROUP(110, mi2s2_sck, phase_flag, _, qdss_gpio, _, _, _, _, _), 462 + [111] = PINGROUP(111, mi2s2_ws, phase_flag, _, qdss_gpio, vsense_trigger, _, _, _, _), 463 + [112] = PINGROUP(112, mi2s2_data0, phase_flag, _, qdss_gpio, _, _, _, _, _), 464 + [113] = PINGROUP(113, mi2s2_data1, audio_ref, phase_flag, _, qdss_gpio, _, _, _, _), 465 + [114] = PINGROUP(114, hs0_mi2s, pll_bist, phase_flag, _, qdss_gpio, _, _, _, _), 466 + [115] = PINGROUP(115, hs0_mi2s, _, qdss_gpio, _, _, _, _, _, _), 467 + [116] = PINGROUP(116, hs0_mi2s, _, qdss_gpio, _, _, _, _, _, _), 468 + [117] = PINGROUP(117, hs0_mi2s, mi2s_mclk1, _, qdss_gpio, _, _, _, _, _), 469 + [118] = PINGROUP(118, hs1_mi2s, _, qdss_gpio, ddr_pxi5, _, _, _, _, _), 470 + [119] = PINGROUP(119, hs1_mi2s, _, qdss_gpio, ddr_pxi5, _, _, _, _, _), 471 + [120] = PINGROUP(120, hs1_mi2s, phase_flag, _, qdss_gpio, _, _, _, _, _), 472 + [121] = PINGROUP(121, hs1_mi2s, phase_flag, _, qdss_gpio, _, _, _, _, _), 473 + [122] = PINGROUP(122, hs2_mi2s, phase_flag, _, qdss_gpio, _, _, _, _, _), 474 + [123] = PINGROUP(123, hs2_mi2s, phase_flag, _, _, _, _, _, _, _), 475 + [124] = PINGROUP(124, hs2_mi2s, phase_flag, _, _, _, _, _, _, _), 476 + [125] = PINGROUP(125, hs2_mi2s, phase_flag, _, _, _, _, _, _, _), 477 + [126] = PINGROUP(126, _, _, _, _, _, _, _, _, _), 478 + [127] = PINGROUP(127, _, _, _, _, _, _, _, _, _), 479 + [128] = PINGROUP(128, _, _, _, _, _, _, _, _, _), 480 + [129] = PINGROUP(129, _, _, _, _, _, _, _, _, _), 481 + [130] = PINGROUP(130, _, _, _, _, _, _, _, _, _), 482 + [131] = PINGROUP(131, _, _, _, _, _, _, _, _, _), 483 + [132] = PINGROUP(132, _, _, _, _, _, _, _, _, _), 484 + [133] = PINGROUP(133, _, _, _, _, _, _, _, _, _), 485 + [134] = PINGROUP(134, _, _, _, _, _, _, _, _, _), 486 + [135] = PINGROUP(135, _, _, _, _, _, _, _, _, _), 487 + [136] = PINGROUP(136, _, _, _, _, _, _, _, _, _), 488 + [137] = PINGROUP(137, _, _, _, _, _, _, _, _, _), 489 + [138] = PINGROUP(138, _, _, _, _, _, _, _, _, _), 490 + [139] = PINGROUP(139, _, _, _, _, _, _, _, _, _), 491 + [140] = PINGROUP(140, _, _, _, _, _, _, _, _, _), 492 + [141] = PINGROUP(141, _, _, _, _, _, _, _, _, _), 493 + [142] = PINGROUP(142, _, _, _, _, _, _, _, _, _), 494 + [143] = PINGROUP(143, _, _, _, _, _, _, _, _, _), 495 + [144] = PINGROUP(144, dbg_out, _, _, _, _, _, _, _, _), 496 + [145] = PINGROUP(145, _, _, _, _, _, _, _, _, _), 497 + [146] = PINGROUP(146, _, _, _, _, _, _, _, _, _), 498 + [147] = PINGROUP(147, _, _, _, _, _, _, _, _, _), 499 + [148] = PINGROUP(148, _, _, _, _, _, _, _, _, _), 500 + }; 501 + 502 + static const struct msm_special_pin_data msm_special_pins_data[] = { 503 + [0] = UFS_RESET("ufs_reset", 0x1a2000), 504 + [1] = SDC_QDSD_PINGROUP("sdc1_rclk", 0x199000, 15, 0), 505 + [2] = SDC_QDSD_PINGROUP("sdc1_clk", 0x199000, 13, 6), 506 + [3] = SDC_QDSD_PINGROUP("sdc1_cmd", 0x199000, 11, 3), 507 + [4] = SDC_QDSD_PINGROUP("sdc1_data", 0x199000, 9, 0), 508 + }; 509 + 510 + static const char *sa8775p_get_function_name(struct udevice *dev, 511 + unsigned int selector) 512 + { 513 + return msm_pinctrl_functions[selector].name; 514 + } 515 + 516 + static const char *sa8775p_get_pin_name(struct udevice *dev, 517 + unsigned int selector) 518 + { 519 + if (selector >= 149 && selector <= 155) 520 + snprintf(pin_name, MAX_PIN_NAME_LEN, 521 + msm_special_pins_data[selector - 149].name); 522 + else 523 + snprintf(pin_name, MAX_PIN_NAME_LEN, "gpio%u", selector); 524 + 525 + return pin_name; 526 + } 527 + 528 + static int sa8775p_get_function_mux(__maybe_unused unsigned int pin, 529 + unsigned int selector) 530 + { 531 + unsigned int i; 532 + const msm_pin_function *func = sa8775p_pin_functions + pin; 533 + 534 + for (i = 0; i < 10; i++) 535 + if ((*func)[i] == selector) 536 + return i; 537 + 538 + pr_err("Can't find requested function for pin %u pin\n", pin); 539 + 540 + return -EINVAL; 541 + } 542 + 543 + static const unsigned int sa8775p_pin_offsets[] = { 544 + [0] = SA8775_PIN_OFFSET, [1] = SA8775_PIN_OFFSET, [2] = SA8775_PIN_OFFSET, 545 + [3] = SA8775_PIN_OFFSET, [4] = SA8775_PIN_OFFSET, [5] = SA8775_PIN_OFFSET, 546 + [6] = SA8775_PIN_OFFSET, [7] = SA8775_PIN_OFFSET, [8] = SA8775_PIN_OFFSET, 547 + [9] = SA8775_PIN_OFFSET, [10] = SA8775_PIN_OFFSET, [11] = SA8775_PIN_OFFSET, 548 + [12] = SA8775_PIN_OFFSET, [13] = SA8775_PIN_OFFSET, [14] = SA8775_PIN_OFFSET, 549 + [15] = SA8775_PIN_OFFSET, [16] = SA8775_PIN_OFFSET, [17] = SA8775_PIN_OFFSET, 550 + [18] = SA8775_PIN_OFFSET, [19] = SA8775_PIN_OFFSET, [20] = SA8775_PIN_OFFSET, 551 + [21] = SA8775_PIN_OFFSET, [22] = SA8775_PIN_OFFSET, [23] = SA8775_PIN_OFFSET, 552 + [24] = SA8775_PIN_OFFSET, [25] = SA8775_PIN_OFFSET, [26] = SA8775_PIN_OFFSET, 553 + [27] = SA8775_PIN_OFFSET, [28] = SA8775_PIN_OFFSET, [29] = SA8775_PIN_OFFSET, 554 + [30] = SA8775_PIN_OFFSET, [31] = SA8775_PIN_OFFSET, [32] = SA8775_PIN_OFFSET, 555 + [33] = SA8775_PIN_OFFSET, [34] = SA8775_PIN_OFFSET, [35] = SA8775_PIN_OFFSET, 556 + [36] = SA8775_PIN_OFFSET, [37] = SA8775_PIN_OFFSET, [38] = SA8775_PIN_OFFSET, 557 + [39] = SA8775_PIN_OFFSET, [40] = SA8775_PIN_OFFSET, [41] = SA8775_PIN_OFFSET, 558 + [42] = SA8775_PIN_OFFSET, [43] = SA8775_PIN_OFFSET, [44] = SA8775_PIN_OFFSET, 559 + [45] = SA8775_PIN_OFFSET, [46] = SA8775_PIN_OFFSET, [47] = SA8775_PIN_OFFSET, 560 + [48] = SA8775_PIN_OFFSET, [49] = SA8775_PIN_OFFSET, [50] = SA8775_PIN_OFFSET, 561 + [51] = SA8775_PIN_OFFSET, [52] = SA8775_PIN_OFFSET, [53] = SA8775_PIN_OFFSET, 562 + [54] = SA8775_PIN_OFFSET, [55] = SA8775_PIN_OFFSET, [56] = SA8775_PIN_OFFSET, 563 + [57] = SA8775_PIN_OFFSET, [58] = SA8775_PIN_OFFSET, [59] = SA8775_PIN_OFFSET, 564 + [60] = SA8775_PIN_OFFSET, [61] = SA8775_PIN_OFFSET, [62] = SA8775_PIN_OFFSET, 565 + [63] = SA8775_PIN_OFFSET, [64] = SA8775_PIN_OFFSET, [65] = SA8775_PIN_OFFSET, 566 + [66] = SA8775_PIN_OFFSET, [67] = SA8775_PIN_OFFSET, [68] = SA8775_PIN_OFFSET, 567 + [69] = SA8775_PIN_OFFSET, [70] = SA8775_PIN_OFFSET, [71] = SA8775_PIN_OFFSET, 568 + [72] = SA8775_PIN_OFFSET, [73] = SA8775_PIN_OFFSET, [74] = SA8775_PIN_OFFSET, 569 + [75] = SA8775_PIN_OFFSET, [76] = SA8775_PIN_OFFSET, [77] = SA8775_PIN_OFFSET, 570 + [78] = SA8775_PIN_OFFSET, [79] = SA8775_PIN_OFFSET, [80] = SA8775_PIN_OFFSET, 571 + [81] = SA8775_PIN_OFFSET, [82] = SA8775_PIN_OFFSET, [83] = SA8775_PIN_OFFSET, 572 + [84] = SA8775_PIN_OFFSET, [85] = SA8775_PIN_OFFSET, [86] = SA8775_PIN_OFFSET, 573 + [87] = SA8775_PIN_OFFSET, [88] = SA8775_PIN_OFFSET, [89] = SA8775_PIN_OFFSET, 574 + [90] = SA8775_PIN_OFFSET, [91] = SA8775_PIN_OFFSET, [92] = SA8775_PIN_OFFSET, 575 + [93] = SA8775_PIN_OFFSET, [94] = SA8775_PIN_OFFSET, [95] = SA8775_PIN_OFFSET, 576 + [96] = SA8775_PIN_OFFSET, [97] = SA8775_PIN_OFFSET, [98] = SA8775_PIN_OFFSET, 577 + [99] = SA8775_PIN_OFFSET, [100] = SA8775_PIN_OFFSET, [101] = SA8775_PIN_OFFSET, 578 + [102] = SA8775_PIN_OFFSET, [103] = SA8775_PIN_OFFSET, [104] = SA8775_PIN_OFFSET, 579 + [105] = SA8775_PIN_OFFSET, [106] = SA8775_PIN_OFFSET, [107] = SA8775_PIN_OFFSET, 580 + [108] = SA8775_PIN_OFFSET, [109] = SA8775_PIN_OFFSET, [110] = SA8775_PIN_OFFSET, 581 + [111] = SA8775_PIN_OFFSET, [112] = SA8775_PIN_OFFSET, [113] = SA8775_PIN_OFFSET, 582 + [114] = SA8775_PIN_OFFSET, [115] = SA8775_PIN_OFFSET, [116] = SA8775_PIN_OFFSET, 583 + [117] = SA8775_PIN_OFFSET, [118] = SA8775_PIN_OFFSET, [119] = SA8775_PIN_OFFSET, 584 + [120] = SA8775_PIN_OFFSET, [121] = SA8775_PIN_OFFSET, [122] = SA8775_PIN_OFFSET, 585 + [123] = SA8775_PIN_OFFSET, [124] = SA8775_PIN_OFFSET, [125] = SA8775_PIN_OFFSET, 586 + [126] = SA8775_PIN_OFFSET, [127] = SA8775_PIN_OFFSET, [128] = SA8775_PIN_OFFSET, 587 + [129] = SA8775_PIN_OFFSET, [130] = SA8775_PIN_OFFSET, [131] = SA8775_PIN_OFFSET, 588 + [132] = SA8775_PIN_OFFSET, [133] = SA8775_PIN_OFFSET, [134] = SA8775_PIN_OFFSET, 589 + [135] = SA8775_PIN_OFFSET, [136] = SA8775_PIN_OFFSET, [137] = SA8775_PIN_OFFSET, 590 + [138] = SA8775_PIN_OFFSET, [139] = SA8775_PIN_OFFSET, [140] = SA8775_PIN_OFFSET, 591 + [141] = SA8775_PIN_OFFSET, [142] = SA8775_PIN_OFFSET, [143] = SA8775_PIN_OFFSET, 592 + [144] = SA8775_PIN_OFFSET, [145] = SA8775_PIN_OFFSET, [146] = SA8775_PIN_OFFSET, 593 + [147] = SA8775_PIN_OFFSET, [148] = SA8775_PIN_OFFSET, [148] = SA8775_PIN_OFFSET, 594 + [149] = SA8775_PIN_OFFSET, [150] = SA8775_PIN_OFFSET, [151] = SA8775_PIN_OFFSET, 595 + [152] = SA8775_PIN_OFFSET, [153] = SA8775_PIN_OFFSET, [154] = SA8775_PIN_OFFSET, 596 + }; 597 + 598 + static const struct msm_pinctrl_data sa8775p_data = { 599 + .pin_data = { 600 + .pin_count = 155, 601 + .special_pins_start = 149, 602 + .special_pins_data = msm_special_pins_data, 603 + .pin_offsets = sa8775p_pin_offsets, 604 + }, 605 + .functions_count = ARRAY_SIZE(msm_pinctrl_functions), 606 + .get_function_name = sa8775p_get_function_name, 607 + .get_function_mux = sa8775p_get_function_mux, 608 + .get_pin_name = sa8775p_get_pin_name, 609 + }; 610 + 611 + static const struct udevice_id msm_pinctrl_ids[] = { 612 + { .compatible = "qcom,sa8775p-tlmm", .data = (ulong)&sa8775p_data }, 613 + { /* Sentinal */ } 614 + }; 615 + 616 + U_BOOT_DRIVER(pinctrl_sa8775p) = { 617 + .name = "pinctrl_sa8775p", 618 + .id = UCLASS_NOP, 619 + .of_match = msm_pinctrl_ids, 620 + .ops = &msm_pinctrl_ops, 621 + .bind = msm_pinctrl_bind, 622 + .flags = DM_FLAG_PRE_RELOC, 623 + };
+226
drivers/pinctrl/qcom/pinctrl-sdm660.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * Qualcomm SDM630/660 TLMM pinctrl 4 + * 5 + */ 6 + 7 + #include <dm.h> 8 + #include "pinctrl-qcom.h" 9 + 10 + #define TLMM_BASE 0x03100000 11 + #define SOUTH (0x03100000 - TLMM_BASE) /* 0x0 */ 12 + #define CENTER (0x03500000 - TLMM_BASE) /* 0x400000 */ 13 + #define NORTH (0x03900000 - TLMM_BASE) /* 0x800000 */ 14 + 15 + #define MAX_PIN_NAME_LEN 32 16 + static char pin_name[MAX_PIN_NAME_LEN] __section(".data"); 17 + 18 + static const struct pinctrl_function sdm660_pinctrl_functions[] = { 19 + { "gpio", 0 }, 20 + { "blsp_uart2", 3 }, /* gpio 4 and 5, used for debug uart */ 21 + }; 22 + 23 + static const unsigned int sdm660_pin_offsets[] = { 24 + [0] = SOUTH, 25 + [1] = SOUTH, 26 + [2] = SOUTH, 27 + [3] = SOUTH, 28 + [4] = NORTH, 29 + [5] = SOUTH, 30 + [6] = SOUTH, 31 + [7] = SOUTH, 32 + [8] = NORTH, 33 + [9] = NORTH, 34 + [10] = NORTH, 35 + [11] = NORTH, 36 + [12] = NORTH, 37 + [13] = NORTH, 38 + [14] = NORTH, 39 + [15] = NORTH, 40 + [16] = CENTER, 41 + [17] = CENTER, 42 + [18] = CENTER, 43 + [19] = CENTER, 44 + [20] = SOUTH, 45 + [21] = SOUTH, 46 + [22] = CENTER, 47 + [23] = CENTER, 48 + [24] = NORTH, 49 + [25] = NORTH, 50 + [26] = NORTH, 51 + [27] = NORTH, 52 + [28] = CENTER, 53 + [29] = CENTER, 54 + [30] = CENTER, 55 + [31] = CENTER, 56 + [32] = SOUTH, 57 + [33] = SOUTH, 58 + [34] = SOUTH, 59 + [35] = SOUTH, 60 + [36] = SOUTH, 61 + [37] = SOUTH, 62 + [38] = SOUTH, 63 + [39] = SOUTH, 64 + [40] = SOUTH, 65 + [41] = SOUTH, 66 + [42] = SOUTH, 67 + [43] = SOUTH, 68 + [44] = SOUTH, 69 + [45] = SOUTH, 70 + [46] = SOUTH, 71 + [47] = SOUTH, 72 + [48] = SOUTH, 73 + [49] = SOUTH, 74 + [50] = SOUTH, 75 + [51] = SOUTH, 76 + [52] = SOUTH, 77 + [53] = NORTH, 78 + [54] = NORTH, 79 + [55] = SOUTH, 80 + [56] = SOUTH, 81 + [57] = SOUTH, 82 + [58] = SOUTH, 83 + [59] = NORTH, 84 + [60] = NORTH, 85 + [61] = NORTH, 86 + [62] = NORTH, 87 + [63] = NORTH, 88 + [64] = SOUTH, 89 + [65] = SOUTH, 90 + [66] = NORTH, 91 + [67] = NORTH, 92 + [68] = NORTH, 93 + [69] = NORTH, 94 + [70] = NORTH, 95 + [71] = NORTH, 96 + [72] = NORTH, 97 + [73] = NORTH, 98 + [74] = NORTH, 99 + [75] = NORTH, 100 + [76] = NORTH, 101 + [77] = NORTH, 102 + [78] = NORTH, 103 + [79] = SOUTH, 104 + [80] = SOUTH, 105 + [81] = CENTER, 106 + [82] = CENTER, 107 + [83] = SOUTH, 108 + [84] = SOUTH, 109 + [85] = SOUTH, 110 + [86] = SOUTH, 111 + [87] = SOUTH, 112 + [88] = SOUTH, 113 + [89] = SOUTH, 114 + [90] = SOUTH, 115 + [91] = SOUTH, 116 + [92] = SOUTH, 117 + [93] = SOUTH, 118 + [94] = SOUTH, 119 + [95] = SOUTH, 120 + [96] = SOUTH, 121 + [97] = SOUTH, 122 + [98] = SOUTH, 123 + [99] = SOUTH, 124 + [100] = SOUTH, 125 + [101] = SOUTH, 126 + [102] = SOUTH, 127 + [103] = SOUTH, 128 + [104] = SOUTH, 129 + [105] = SOUTH, 130 + [106] = SOUTH, 131 + [107] = SOUTH, 132 + [108] = SOUTH, 133 + [109] = SOUTH, 134 + [110] = SOUTH, 135 + [111] = SOUTH, 136 + [112] = SOUTH, 137 + [113] = SOUTH, 138 + }; 139 + 140 + /* 141 + * Special pins - eMMC/SD related: [114..120], in total 7 special pins 142 + */ 143 + 144 + #define SDC_QDSD_PINGROUP(pg_name, ctl, pull, drv) \ 145 + { \ 146 + .name = pg_name, \ 147 + .ctl_reg = ctl, \ 148 + .io_reg = 0, \ 149 + .pull_bit = pull, \ 150 + .drv_bit = drv, \ 151 + .oe_bit = -1, \ 152 + .in_bit = -1, \ 153 + .out_bit = -1, \ 154 + } 155 + 156 + /* All SDC pins are in the NORTH tile */ 157 + static const struct msm_special_pin_data sdm660_special_pins_data[] = { 158 + SDC_QDSD_PINGROUP("sdc1_clk", NORTH + 0x9a000, 13, 6), 159 + SDC_QDSD_PINGROUP("sdc1_cmd", NORTH + 0x9a000, 11, 3), 160 + SDC_QDSD_PINGROUP("sdc1_data", NORTH + 0x9a000, 9, 0), 161 + SDC_QDSD_PINGROUP("sdc2_clk", NORTH + 0x9b000, 14, 6), 162 + SDC_QDSD_PINGROUP("sdc2_cmd", NORTH + 0x9b000, 11, 3), 163 + SDC_QDSD_PINGROUP("sdc2_data", NORTH + 0x9b000, 9, 0), 164 + SDC_QDSD_PINGROUP("sdc1_rclk", NORTH + 0x9a000, 15, 0), 165 + }; 166 + 167 + static const char *sdm660_get_function_name(struct udevice *dev, unsigned int selector) 168 + { 169 + return sdm660_pinctrl_functions[selector].name; 170 + } 171 + 172 + static const char *sdm660_get_pin_name(struct udevice *dev, unsigned int selector) 173 + { 174 + static const char * const special_pins_names[] = { 175 + "sdc1_clk", "sdc1_cmd", "sdc1_data", 176 + "sdc2_clk", "sdc2_cmd", "sdc2_data", 177 + "sdc1_rclk" 178 + }; 179 + 180 + if (selector >= 114 && selector <= 120) 181 + snprintf(pin_name, MAX_PIN_NAME_LEN, special_pins_names[selector - 114]); 182 + else 183 + snprintf(pin_name, MAX_PIN_NAME_LEN, "gpio%u", selector); 184 + 185 + return pin_name; 186 + } 187 + 188 + static int sdm660_get_function_mux(__maybe_unused unsigned int pin, unsigned int selector) 189 + { 190 + if (selector >= 0 && selector < ARRAY_SIZE(sdm660_pinctrl_functions)) 191 + return sdm660_pinctrl_functions[selector].val; 192 + return -EINVAL; 193 + } 194 + 195 + struct msm_pinctrl_data sdm660_data = { 196 + .pin_data = { 197 + .pin_offsets = sdm660_pin_offsets, 198 + .pin_count = ARRAY_SIZE(sdm660_pin_offsets) + ARRAY_SIZE(sdm660_special_pins_data), 199 + .special_pins_start = 114, 200 + .special_pins_data = sdm660_special_pins_data, 201 + }, 202 + .functions_count = ARRAY_SIZE(sdm660_pinctrl_functions), 203 + .get_function_name = sdm660_get_function_name, 204 + .get_function_mux = sdm660_get_function_mux, 205 + .get_pin_name = sdm660_get_pin_name, 206 + }; 207 + 208 + static const struct udevice_id msm_pinctrl_ids[] = { 209 + { 210 + .compatible = "qcom,sdm630-pinctrl", 211 + .data = (ulong)&sdm660_data 212 + }, 213 + { 214 + .compatible = "qcom,sdm660-pinctrl", 215 + .data = (ulong)&sdm660_data 216 + }, 217 + { /* Sentinel */ } 218 + }; 219 + 220 + U_BOOT_DRIVER(pinctrl_ssdm660) = { 221 + .name = "pinctrl_sdm660", 222 + .id = UCLASS_NOP, 223 + .of_match = msm_pinctrl_ids, 224 + .ops = &msm_pinctrl_ops, 225 + .bind = msm_pinctrl_bind, 226 + };
+7
drivers/power/regulator/Kconfig
··· 224 224 implements get/set api for a limited set of regulators used 225 225 by u-boot. 226 226 227 + config DM_REGULATOR_QCOM_USB_VBUS 228 + bool "Enable driver model for Qualcomm USB vbus regulator" 229 + depends on DM_REGULATOR 230 + ---help--- 231 + Enable support for the Qualcomm USB Vbus regulator. The driver 232 + implements get/set api for the regulator to be used by u-boot. 233 + 227 234 config SPL_DM_REGULATOR_GPIO 228 235 bool "Enable Driver Model for GPIO REGULATOR in SPL" 229 236 depends on DM_REGULATOR_GPIO && SPL_GPIO
+1
drivers/power/regulator/Makefile
··· 22 22 obj-$(CONFIG_$(XPL_)DM_REGULATOR_FIXED) += fixed.o 23 23 obj-$(CONFIG_$(XPL_)DM_REGULATOR_GPIO) += gpio-regulator.o 24 24 obj-$(CONFIG_DM_REGULATOR_QCOM_RPMH) += qcom-rpmh-regulator.o 25 + obj-$(CONFIG_DM_REGULATOR_QCOM_USB_VBUS) += qcom_usb_vbus_regulator.o 25 26 obj-$(CONFIG_$(PHASE_)REGULATOR_RK8XX) += rk8xx.o 26 27 obj-$(CONFIG_DM_REGULATOR_S2MPS11) += s2mps11_regulator.o 27 28 obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
+45
drivers/power/regulator/qcom-rpmh-regulator.c
··· 466 466 .n_modes = ARRAY_SIZE(pmic_mode_map_pmic5_ldo), 467 467 }; 468 468 469 + static const struct rpmh_vreg_hw_data pmic5_ftsmps527 = { 470 + .regulator_type = VRM, 471 + .ops = &rpmh_regulator_vrm_drms_ops, 472 + .voltage_range = REGULATOR_LINEAR_RANGE(320000, 0, 215, 8000), 473 + .n_voltages = 215, 474 + .pmic_mode_map = pmic_mode_map_pmic5_smps, 475 + .n_modes = ARRAY_SIZE(pmic_mode_map_pmic5_smps), 476 + }; 477 + 478 + static const struct rpmh_vreg_hw_data pmic5_pldo515_mv = { 479 + .regulator_type = VRM, 480 + .ops = &rpmh_regulator_vrm_drms_ops, 481 + .voltage_range = REGULATOR_LINEAR_RANGE(1800000, 0, 187, 8000), 482 + .n_voltages = 188, 483 + .hpm_min_load_uA = 10000, 484 + .pmic_mode_map = pmic_mode_map_pmic5_ldo, 485 + .n_modes = ARRAY_SIZE(pmic_mode_map_pmic5_ldo), 486 + }; 487 + 469 488 #define RPMH_VREG(_name, _resource_name, _hw_data, _supply_name) \ 470 489 { \ 471 490 .name = _name, \ ··· 558 577 {} 559 578 }; 560 579 580 + static const struct rpmh_vreg_init_data pmm8654au_vreg_data[] = { 581 + RPMH_VREG("smps1", "smp%s1", &pmic5_ftsmps527, "vdd-s1"), 582 + RPMH_VREG("smps2", "smp%s2", &pmic5_ftsmps527, "vdd-s2"), 583 + RPMH_VREG("smps3", "smp%s3", &pmic5_ftsmps527, "vdd-s3"), 584 + RPMH_VREG("smps4", "smp%s4", &pmic5_ftsmps527, "vdd-s4"), 585 + RPMH_VREG("smps5", "smp%s5", &pmic5_ftsmps527, "vdd-s5"), 586 + RPMH_VREG("smps6", "smp%s6", &pmic5_ftsmps527, "vdd-s6"), 587 + RPMH_VREG("smps7", "smp%s7", &pmic5_ftsmps527, "vdd-s7"), 588 + RPMH_VREG("smps8", "smp%s8", &pmic5_ftsmps527, "vdd-s8"), 589 + RPMH_VREG("smps9", "smp%s9", &pmic5_ftsmps527, "vdd-s9"), 590 + RPMH_VREG("ldo1", "ldo%s1", &pmic5_nldo515, "vdd-s9"), 591 + RPMH_VREG("ldo2", "ldo%s2", &pmic5_nldo515, "vdd-l2-l3"), 592 + RPMH_VREG("ldo3", "ldo%s3", &pmic5_nldo515, "vdd-l2-l3"), 593 + RPMH_VREG("ldo4", "ldo%s4", &pmic5_nldo515, "vdd-s9"), 594 + RPMH_VREG("ldo5", "ldo%s5", &pmic5_nldo515, "vdd-s9"), 595 + RPMH_VREG("ldo6", "ldo%s6", &pmic5_nldo515, "vdd-l6-l7"), 596 + RPMH_VREG("ldo7", "ldo%s7", &pmic5_nldo515, "vdd-l6-l7"), 597 + RPMH_VREG("ldo8", "ldo%s8", &pmic5_pldo515_mv, "vdd-l8-l9"), 598 + RPMH_VREG("ldo9", "ldo%s9", &pmic5_pldo, "vdd-l8-l9"), 599 + {} 600 + }; 601 + 561 602 /* probe an individual regulator */ 562 603 static int rpmh_regulator_probe(struct udevice *dev) 563 604 { ··· 687 728 { 688 729 .compatible = "qcom,pmc8380-rpmh-regulators", 689 730 .data = (ulong)pmc8380_vreg_data, 731 + }, 732 + { 733 + .compatible = "qcom,pmm8654au-rpmh-regulators", 734 + .data = (ulong)pmm8654au_vreg_data, 690 735 }, 691 736 { /* sentinal */ }, 692 737 };
+111
drivers/power/regulator/qcom_usb_vbus_regulator.c
··· 1 + // SPDX-License-Identifier: BSD-3-Clause 2 + /* 3 + * Copyright (c) 2025, Linaro Limited 4 + */ 5 + #define pr_fmt(fmt) "qcom_usb_vbus: " fmt 6 + 7 + #include <bitfield.h> 8 + #include <errno.h> 9 + #include <dm.h> 10 + #include <fdtdec.h> 11 + #include <log.h> 12 + #include <asm/gpio.h> 13 + #include <linux/bitops.h> 14 + #include <linux/printk.h> 15 + #include <power/pmic.h> 16 + #include <power/regulator.h> 17 + 18 + #define CMD_OTG 0x50 19 + #define OTG_EN BIT(0) 20 + // The 0 bit in this register's bit field is undocumented 21 + #define OTG_CFG 0x56 22 + #define OTG_EN_SRC_CFG BIT(1) 23 + 24 + struct qcom_usb_vbus_priv { 25 + phys_addr_t base; 26 + }; 27 + 28 + static int qcom_usb_vbus_regulator_of_to_plat(struct udevice *dev) 29 + { 30 + struct qcom_usb_vbus_priv *priv = dev_get_priv(dev); 31 + 32 + priv->base = dev_read_addr(dev); 33 + if (priv->base == FDT_ADDR_T_NONE) 34 + return -EINVAL; 35 + 36 + return 0; 37 + } 38 + 39 + static int qcom_usb_vbus_regulator_get_enable(struct udevice *dev) 40 + { 41 + struct qcom_usb_vbus_priv *priv = dev_get_priv(dev); 42 + int otg_en_reg = priv->base + CMD_OTG; 43 + int ret; 44 + 45 + ret = pmic_reg_read(dev->parent, otg_en_reg); 46 + if (ret < 0) 47 + log_err("failed to read usb vbus: %d\n", ret); 48 + else 49 + ret &= OTG_EN; 50 + 51 + return ret; 52 + } 53 + 54 + static int qcom_usb_vbus_regulator_set_enable(struct udevice *dev, bool enable) 55 + { 56 + struct qcom_usb_vbus_priv *priv = dev_get_priv(dev); 57 + int otg_en_reg = priv->base + CMD_OTG; 58 + int ret; 59 + 60 + if (enable) { 61 + ret = pmic_clrsetbits(dev->parent, otg_en_reg, 0, OTG_EN); 62 + if (ret < 0) { 63 + log_err("error enabling: %d\n", ret); 64 + return ret; 65 + } 66 + } else { 67 + ret = pmic_clrsetbits(dev->parent, otg_en_reg, OTG_EN, 0); 68 + if (ret < 0) { 69 + log_err("error disabling: %d\n", ret); 70 + return ret; 71 + } 72 + } 73 + 74 + return 0; 75 + } 76 + 77 + static int qcom_usb_vbus_regulator_probe(struct udevice *dev) 78 + { 79 + struct qcom_usb_vbus_priv *priv = dev_get_priv(dev); 80 + int otg_cfg_reg = priv->base + OTG_CFG; 81 + int ret; 82 + 83 + /* Disable HW logic for VBUS enable */ 84 + ret = pmic_clrsetbits(dev->parent, otg_cfg_reg, OTG_EN_SRC_CFG, 0); 85 + if (ret < 0) { 86 + log_err("error setting EN_SRC_CFG: %d\n", ret); 87 + return ret; 88 + } 89 + 90 + return 0; 91 + } 92 + 93 + static const struct dm_regulator_ops qcom_usb_vbus_regulator_ops = { 94 + .get_enable = qcom_usb_vbus_regulator_get_enable, 95 + .set_enable = qcom_usb_vbus_regulator_set_enable, 96 + }; 97 + 98 + static const struct udevice_id qcom_usb_vbus_regulator_ids[] = { 99 + { .compatible = "qcom,pm8150b-vbus-reg"}, 100 + { }, 101 + }; 102 + 103 + U_BOOT_DRIVER(qcom_usb_vbus_regulator) = { 104 + .name = "qcom-usb-vbus-regulator", 105 + .id = UCLASS_REGULATOR, 106 + .of_match = qcom_usb_vbus_regulator_ids, 107 + .of_to_plat = qcom_usb_vbus_regulator_of_to_plat, 108 + .ops = &qcom_usb_vbus_regulator_ops, 109 + .probe = qcom_usb_vbus_regulator_probe, 110 + .priv_auto = sizeof(struct qcom_usb_vbus_priv), 111 + };
+49 -10
drivers/spmi/spmi-msm.c
··· 24 24 #define PMIC_ARB_VERSION_V5_MIN 0x50000000 25 25 #define PMIC_ARB_VERSION_V7_MIN 0x70000000 26 26 27 + #define PMIC_ARB_FEATURES 0x0004 28 + #define PMIC_ARB_FEATURES_PERIPH_MASK GENMASK(10, 0) 29 + 27 30 #define APID_MAP_OFFSET_V1_V2_V3 (0x800) 28 31 #define APID_MAP_OFFSET_V5 (0x900) 29 32 #define APID_MAP_OFFSET_V7 (0x2000) ··· 60 63 #define SPMI_MAX_PERIPH 256 61 64 62 65 #define SPMI_CHANNEL_READ_ONLY BIT(31) 66 + #define SPMI_CHANNEL_VALID BIT(30) 63 67 #define SPMI_CHANNEL_MASK 0xffff 64 68 65 69 enum arb_ver { ··· 114 118 return -EIO; 115 119 if (pid >= SPMI_MAX_PERIPH) 116 120 return -EIO; 121 + if (!(priv->channel_map[usid][pid] & SPMI_CHANNEL_VALID)) 122 + return -EINVAL; 117 123 if (priv->channel_map[usid][pid] & SPMI_CHANNEL_READ_ONLY) 118 124 return -EPERM; 119 125 ··· 183 189 return -EIO; 184 190 if (pid >= SPMI_MAX_PERIPH) 185 191 return -EIO; 192 + if (!(priv->channel_map[usid][pid] & SPMI_CHANNEL_VALID)) 193 + return -EINVAL; 186 194 187 195 channel = priv->channel_map[usid][pid] & SPMI_CHANNEL_MASK; 188 196 ··· 246 254 .write = msm_spmi_write, 247 255 }; 248 256 257 + /* 258 + * In order to allow multiple EEs to write to a single PPID in arbiter 259 + * version 5 and 7, there is more than one APID mapped to each PPID. 260 + * The owner field for each of these mappings specifies the EE which is 261 + * allowed to write to the APID. 262 + */ 263 + static void msm_spmi_channel_map_v5(struct msm_spmi_priv *priv, unsigned int i, 264 + uint8_t slave_id, uint8_t pid) 265 + { 266 + /* Mark channels read-only when from different owner */ 267 + uint32_t cnfg = readl(priv->spmi_cnfg + ARB_CHANNEL_OFFSET(i)); 268 + uint8_t owner = SPMI_OWNERSHIP_PERIPH2OWNER(cnfg); 269 + bool prev_valid = priv->channel_map[slave_id][pid] & SPMI_CHANNEL_VALID; 270 + uint32_t prev_read_only = priv->channel_map[slave_id][pid] & SPMI_CHANNEL_READ_ONLY; 271 + 272 + if (!prev_valid) { 273 + /* First PPID mapping */ 274 + priv->channel_map[slave_id][pid] = i | SPMI_CHANNEL_VALID; 275 + if (owner != priv->owner) 276 + priv->channel_map[slave_id][pid] |= SPMI_CHANNEL_READ_ONLY; 277 + } else if ((owner == priv->owner) && prev_read_only) { 278 + /* Read only and we found one we own, switch */ 279 + priv->channel_map[slave_id][pid] = i | SPMI_CHANNEL_VALID; 280 + } 281 + } 282 + 249 283 static int msm_spmi_probe(struct udevice *dev) 250 284 { 251 285 struct msm_spmi_priv *priv = dev_get_priv(dev); ··· 271 305 } else if (hw_ver < PMIC_ARB_VERSION_V7_MIN) { 272 306 priv->arb_ver = V5; 273 307 priv->arb_chnl = core_addr + APID_MAP_OFFSET_V5; 274 - priv->max_channels = SPMI_MAX_CHANNELS_V5; 308 + priv->max_channels = min_t(u32, readl(core_addr + PMIC_ARB_FEATURES) & 309 + PMIC_ARB_FEATURES_PERIPH_MASK, 310 + SPMI_MAX_CHANNELS_V5); 275 311 priv->spmi_cnfg = dev_read_addr_name(dev, "cnfg"); 276 312 } else { 277 313 /* TOFIX: handle second bus */ 278 314 priv->arb_ver = V7; 279 315 priv->arb_chnl = core_addr + APID_MAP_OFFSET_V7; 280 - priv->max_channels = SPMI_MAX_CHANNELS_V7; 316 + priv->max_channels = min_t(u32, readl(core_addr + PMIC_ARB_FEATURES) & 317 + PMIC_ARB_FEATURES_PERIPH_MASK, 318 + SPMI_MAX_CHANNELS_V7); 281 319 priv->spmi_cnfg = dev_read_addr_name(dev, "cnfg"); 282 320 } 283 321 ··· 297 335 uint8_t slave_id = (periph & 0xf0000) >> 16; 298 336 uint8_t pid = (periph & 0xff00) >> 8; 299 337 300 - priv->channel_map[slave_id][pid] = i; 301 - 302 - /* Mark channels read-only when from different owner */ 303 - if (priv->arb_ver == V5 || priv->arb_ver == V7) { 304 - uint32_t cnfg = readl(priv->spmi_cnfg + ARB_CHANNEL_OFFSET(i)); 305 - uint8_t owner = SPMI_OWNERSHIP_PERIPH2OWNER(cnfg); 338 + switch (priv->arb_ver) { 339 + case V2: 340 + case V3: 341 + priv->channel_map[slave_id][pid] = i | SPMI_CHANNEL_VALID; 342 + break; 306 343 307 - if (owner != priv->owner) 308 - priv->channel_map[slave_id][pid] |= SPMI_CHANNEL_READ_ONLY; 344 + case V5: 345 + case V7: 346 + msm_spmi_channel_map_v5(priv, i, slave_id, pid); 347 + break; 309 348 } 310 349 } 311 350 return 0;
-11
include/configs/dragonboard410c.h
··· 18 18 #define PHYS_SDRAM_1_SIZE SZ_1G 19 19 #define CFG_SYS_SDRAM_BASE PHYS_SDRAM_1 20 20 21 - /* Environment */ 22 - #define BOOT_TARGET_DEVICES(func) \ 23 - func(USB, usb, 0) \ 24 - func(MMC, mmc, 1) \ 25 - func(MMC, mmc, 0) \ 26 - func(DHCP, dhcp, na) 27 - 28 - #include <config_distro_bootcmd.h> 29 - 30 - #define CFG_EXTRA_ENV_SETTINGS BOOTENV 31 - 32 21 #endif