###############################################################################
# Helper script: /load_kernel_modules.scr/platform/aarch64/snapdragon
# Purpose......: Set the Kernel modules for the Snapdragon SoCs
#                Hardware Models, within the Slackware initial RAM disk
#                ('OS initrd') and the Slackware Installer.
#                This script is sourced from '/load_kernel_modules'
#
# Important Note:
# * You must _append_ to the module lists (as this script does)
#   otherwise the base set of modules will not be loaded and would result in
#   a Kernel panic.
# * The initrd uses the 'bash' shell, rather than 'busybox'
#   (as in upstream/x86 Slackware). This allows you (for example)
#   to use 'fallthrough' (case statements terminated with ';&'
#   rather than ';;') within case statements and regular expression
#   matches within 'if' statements.
#   This permits the 'c'-style switch statements where you can
#   'inherit' the previous matches as you move down the cases.
#   This enables you to match on varients of boards, and inherit
#   a 'baseline' of platform modules for that board.
#
# The 'PLATWALK' match is to enable build scripts to process these
# scripts outside of the initrd environment and determine which
# modules will be loaded by a particular Hardware Model.  This must remain
# in place for all scripts.
###############################################################################

# As an example, $HWM might contain the string:
# "Lenovo ThinkPad X13s"
#
# Listed on: https://wiki.gentoo.org/wiki/Lenovo_ThinkPad_X13s 
# nvme phy_qcom_qmp_pcie pcie_qcom i2c_hid_of i2c_qcom_geni leds_qcom_lpg
# pwm_bl qrtr pmic_glink_altmode gpio_sbu_mux phy_qcom_qmp_combo panel-edp msm phy_qcom_edp
case $HWM in
   "Lenovo ThinkPad X13s"*|PLATWALK)
      platform_detected=1

      # Load the parent platform drivers for the SoC:
      kmod_load_subsyst_soc=1

      # If one of the modules within the base list is causing problems on
      # your platform, here are the options laid out as examples:
      # USB="${USB/ehci_orion/differentmodule}" # Substitute module 'ehci_orion' with 'differentmodule'
      # USB="${USB/ehci_orion/}" # Remove the 'ehci_orion' module from the list

      # Backlight and display chain, in Johan Hovold's order: msm must come
      # after qrtr, pmic_glink_altmode, gpio_sbu_mux and phy_qcom_qmp_combo, or
      # it hits a probe-deferral problem. /load_kernel_modules loads MOD_VIDEO
      # before every other list, so these are not put in the MOD_* lists: they
      # are loaded, in this order, by hwm_hook_post-modload() below, after the
      # storage, keyboard, RPMh/interconnect, USB and PHY modules.
      HWM_X13S_DISPLAY="leds_qcom_lpg pwm_bl qrtr pmic_glink_altmode gpio_sbu_mux phy_qcom_qmp_combo gpucc_sc8280xp dispcc_sc8280xp phy_qcom_edp panel_edp msm"
      # Build scripts (PLATWALK) collect and validate modules from the MOD_*
      # lists, so list the display chain there for them only:
      [ "$HWM" = "PLATWALK" ] && MOD_VIDEO+="  $HWM_X13S_DISPLAY"

      # Drivers for PCI and other core sub systems:
      MOD_PHY+="    phy_qcom_qmp_pcie phy_qcom_snps_femto_v2 phy_qcom_qmp_usb"
      # MFD (Multi Functional Devices) drivers:
      MOD_MFD+="    qcom_rpmh_regulator"
      # For SDHC/MMC storage:
      #MOD_CARDS+="  "
      # Drivers for USB hardware for this particular Hardware Model:
      MOD_USB+="    dwc3 dwc3_qcom pmic_glink ucsi_glink hid_generic"
      # Ethernet network driver:
      # There is no on-board Ethernet; these cover common USB Ethernet adapters
      # and phone tethering (usbnet is in the base list):
      MOD_NET+="    cdc_ether cdc_ncm rndis_host r8152 ax88179_178a asix"
      # TODO: Consider adding wifi support for this device to ease the installation
      # process for users without an ethernet adapter for usb-c?
      # - There isn't a serial port to use
      # MOD_WIFI+="   ath11k_pci" 
      # Any modules related to compression/decompression and cryptography
      #MOD_CMP+="    "
      #MOD_CRYPTO+=" "
      # The following modules do not inherit from the parent loader '/load_kernel_modules'
      #MOD_RTC+="    rtc_XYZ"

      # Modules for the IP blocks/peripherals embedded within the SoC:
      # RPMh, power domains and interconnects:
      MOD_SOC+="    qcom_rpmh clk_rpmh rpmhpd icc_bcm_voter icc_rpmh qnoc_sc8280xp"
      MOD_SOC+="    i2c_hid_of i2c_qcom_geni hid_multitouch"
      # Qualcomm WCN/PCIe power sequencing helper:
      MOD_SOC+="    pwrseq-core pwrseq-qcom-wcn"

      # Modules for the peripherals on the Hardware Model's main board
      # (outside of the SoC itself):
      MOD_HWM+="    pci-pwrctrl-pwrseq"

      # Runs once /load_kernel_modules has loaded the MOD_* lists:
      # 1. The display chain, in order. Every display block sits behind GCC
      #    (100000.clock-controller), which can only bind once rpmhpd and the
      #    RPMh/interconnect modules from MOD_SOC have loaded, so wait up to
      #    10 s for GCC first: msm then probes with all its suppliers present
      #    instead of deferring. modprobe by name ignores the 'blacklist msm'
      #    in snapdragon_thinkpad-x13s.conf, as before.
      # 2. USB: the multiport controller (dwc3 a400000.usb, internal devices)
      #    can fail its first probe because its PHY (88ef000) times out:
      #      qcom-qmp-usb-phy 88ef000.phy: phy initialization timed-out
      #      dwc3 a400000.usb: probe with driver dwc3 failed with error -110
      #    Binding it again once the modules have loaded works, so retry
      #    briefly here, only while it is still unbound.
      #    The second USB-C port (dwc3 a800000.usb) fails the same way but
      #    cannot be bound from the OS InitRD; /etc/rc.d/rc.platform.d/aarch64/snapdragon
      #    retries it from the OS proper.
      function hwm_hook_post-modload() {
         local m n=0
         while [ ! -e /sys/bus/platform/devices/100000.clock-controller/driver ] && [ $n -lt 10 ]; do
            n=$((n+1))
            sleep 1
         done
         n=0
         for m in $HWM_X13S_DISPLAY ; do
            modprobe $m 2>/dev/null
         done
         [ -e /sys/bus/platform/devices/a400000.usb ] || return 0
         while [ ! -e /sys/bus/platform/drivers/dwc3/a400000.usb ] && [ $n -lt 5 ]; do
            echo a400000.usb 2>/dev/null > /sys/bus/platform/drivers/dwc3/bind && break
            n=$((n+1))
            sleep 1
         done
         return 0
      }

      ;;
esac

# Set the short name that is used by /load_kernel_modules to install
# the appropriate configuration for modprobe for this Hardware Model:
# These files are stored within the source tree:
# source/k/SlkOS-initrd-overlay/usr/share/hwm-configure/platform/aarch64/modprobe.d/
#
# Note: Typically these are only used to blacklist particular modules from loading
# within the OS InitRD or Installer.  Within the OS the regular location of
# /lib/modprobe.d/ is used and has no connection to the content of the
# OS InitRD/Installer.
case $hwm in
  "Lenovo ThinkPad X13s"*)
      SOC_NAME=snapdragon
      HWM_SHORTNAME=thinkpad-x13s ;;
esac

# The '/load_kernel_modules' script will load the modules
# set above.
