Repository navigation
Support pre-GCN AMD GPUs and BCM4321 wireless #10936
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: quattro
Are you sure you want to change the base?
Changes from all commits
12af73f
20196a2
6ef21ac
38f95ed
93a0fdb
8e7f294
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| #!/bin/bash | ||
|
|
||
| # omarchy:summary=Detect whether the GPU can apply a nightlight color temperature. | ||
|
|
||
| # hyprsunset sends its color temperature to Hyprland as a colour transform | ||
| # matrix over hyprland-ctm-control-v1, and aquamarine only submits a CTM on the | ||
| # DRM atomic path. A driver without atomic modesetting accepts the request and | ||
| # drops it, so hyprctl answers "ok", the temperature reads back, and the panel | ||
| # never changes — a silent no-op rather than an error. | ||
| # | ||
| # radeon is the one such driver still in use: it drives pre-GCN AMD cards | ||
| # (TeraScale and older, e.g. the Radeon HD 2400 in a 2007 iMac) and reports | ||
| # "crtc doesn't support CTM". Everything newer is on amdgpu and is atomic. | ||
| # | ||
| # Only answer no when every DRM card is on radeon. A machine that also has a | ||
| # non-radeon GPU may well be driving its display from that one, and hiding a | ||
| # working feature is worse than leaving a broken one visible. | ||
| drm_path="${OMARCHY_DRM_PATH:-/sys/class/drm}" | ||
|
|
||
| cards=0 | ||
|
|
||
| for card in "$drm_path"/card[0-9]*; do | ||
| name=${card##*/} | ||
|
|
||
| # Connectors are exposed as card0-LVDS-1 alongside the card itself. | ||
| [[ $name == *-* ]] && continue | ||
| [[ -e $card/device/driver ]] || continue | ||
|
|
||
| (( ++cards )) | ||
| [[ $(readlink -f "$card/device/driver") == */radeon ]] || exit 0 | ||
| done | ||
|
|
||
| (( cards > 0 )) && exit 1 | ||
|
|
||
| exit 0 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,10 +1,11 @@ | ||
| # Install Wi-Fi drivers for Broadcom chips found in some MacBooks, as well as other systems: | ||
| # - BCM4360 (2013–2015 MacBooks) | ||
| # - BCM4331 (2012, early 2013 MacBooks) | ||
| # - BCM4321 (2007–2008 iMacs and MacBooks; 4329 and 432a are the same chip) | ||
|
|
||
| pci_info=$(lspci -nn) | ||
|
|
||
| if (echo "$pci_info" | grep -q "14e4:43a0" || echo "$pci_info" | grep -q "14e4:4331"); then | ||
| echo "BCM4360 / BCM4331 detected" | ||
| if echo "$pci_info" | grep -qE "14e4:(43a0|4331|4328|4329|432a)"; then | ||
| echo "Broadcom BCM4360 / BCM4331 / BCM4321 detected" | ||
| omarchy-pkg-add broadcom-wl-dkms | ||
| fi |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,8 +9,39 @@ declare -A VULKAN_DRIVERS=( | |
|
|
||
| PACKAGES=() | ||
|
|
||
| # RADV only drives GPUs bound to amdgpu. Pre-GCN cards (TeraScale and older, | ||
| # e.g. the Radeon HD 2400 in a 2007 iMac) stay on the radeon driver, where | ||
| # vulkan-radeon still installs radeon_icd.json but every device enumeration | ||
| # fails with VK_ERROR_INCOMPATIBLE_DRIVER. That stray ICD makes | ||
| # omarchy-hw-vulkan answer yes on a machine with no working Vulkan. | ||
| # | ||
| # Skip only on radeon: an installer booted with nomodeset binds no driver at | ||
| # all, which says nothing about the installed system. | ||
| amd_gpu_only_on_radeon() { | ||
| local device driver | ||
| local on_radeon=false | ||
| local pci_devices_path="${OMARCHY_PCI_DEVICES_PATH:-/sys/bus/pci/devices}" | ||
|
|
||
| for device in "$pci_devices_path"/*; do | ||
| [[ -e $device/vendor ]] || continue | ||
| [[ $(< "$device/vendor") == "0x1002" ]] || continue | ||
| [[ $(< "$device/class") == 0x03* ]] || continue | ||
|
|
||
| driver=$(readlink -f "$device/driver") | ||
| [[ $driver == */amdgpu ]] && return 1 | ||
| [[ $driver == */radeon ]] && on_radeon=true | ||
| done | ||
|
|
||
| [[ $on_radeon == true ]] | ||
| } | ||
|
|
||
| for vendor in "${!VULKAN_DRIVERS[@]}"; do | ||
| if lspci | grep -iE "(VGA|Display).*$vendor" > /dev/null; then | ||
| if [[ $vendor == "AMD" ]] && amd_gpu_only_on_radeon; then | ||
| echo "Skipping vulkan-radeon: AMD GPU is on the radeon driver, which RADV cannot drive" | ||
| continue | ||
|
Comment on lines
+40
to
+42
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
On a radeon-only machine, this hardware pass skips Knowledge Base Used: Install stages and package sets |
||
| fi | ||
|
|
||
| PACKAGES+=("${VULKAN_DRIVERS[$vendor]}") | ||
| fi | ||
| done | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| #!/bin/bash | ||
|
|
||
| set -euo pipefail | ||
|
|
||
| source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh" | ||
|
|
||
| fix_bcm="$ROOT/install/hardware/fix-bcm43xx.sh" | ||
|
|
||
| test_tmp=$(mktemp -d) | ||
| trap 'rm -rf "$test_tmp"' EXIT | ||
|
|
||
| stub_bin="$test_tmp/bin" | ||
| mkdir -p "$stub_bin" | ||
|
|
||
| # Real lspci keeps printing well past any match, so a grep -q consumer can be | ||
| # killed by SIGPIPE; keep the stub chatty for the same reason as the T2 test. | ||
| cat >"$stub_bin/lspci" <<'SH' | ||
| #!/bin/bash | ||
| [[ -n ${STUB_WIFI_ID:-} ]] && | ||
| echo "04:00.0 Network controller [0280]: Broadcom Inc. and subsidiaries Wireless [$STUB_WIFI_ID] (rev 03)" | ||
| for _ in {1..4096}; do | ||
| echo '02:00.0 Host bridge [0600]: Filler Device [ffff:0000]' | ||
| done | ||
| SH | ||
| chmod +x "$stub_bin/lspci" | ||
|
|
||
| installs_driver_for() { | ||
| local wifi_id=${1:-} | ||
| local calls="$test_tmp/calls-$RANDOM" | ||
|
|
||
| PATH="$stub_bin:$PATH" \ | ||
| STUB_WIFI_ID="$wifi_id" \ | ||
| OMARCHY_TEST_CALLS="$calls" \ | ||
| "$BASH" -c ' | ||
| omarchy-pkg-add() { printf "%s\n" "$@" >>"$OMARCHY_TEST_CALLS"; } | ||
| source "$1" | ||
| ' _ "$fix_bcm" >/dev/null 2>&1 | ||
|
|
||
| [[ -f $calls ]] && grep -qx 'broadcom-wl-dkms' "$calls" | ||
| } | ||
|
|
||
| # BCM4321 is the 2007-2008 iMac/MacBook card. b43 can drive it, but Omarchy | ||
| # standardized on the wl driver, which covers it too. | ||
| for id in 14e4:4328 14e4:4329 14e4:432a; do | ||
| installs_driver_for "$id" || | ||
| fail "BCM4321 ($id) gets broadcom-wl-dkms" | ||
| done | ||
| pass "BCM4321 device ids pull in broadcom-wl-dkms" | ||
|
|
||
| # Regression guard: the ids that already worked must keep working. | ||
| installs_driver_for 14e4:43a0 || fail "BCM4360 still gets broadcom-wl-dkms" | ||
| installs_driver_for 14e4:4331 || fail "BCM4331 still gets broadcom-wl-dkms" | ||
| pass "BCM4360 and BCM4331 keep their driver" | ||
|
|
||
| # A Broadcom card brcmfmac drives (BCM4350) must not drag wl in. | ||
| ! installs_driver_for 14e4:43a3 || | ||
| fail "a brcmfmac Broadcom id does not install broadcom-wl-dkms" | ||
| ! installs_driver_for || | ||
| fail "a machine with no Broadcom wireless installs nothing" | ||
| pass "non-matching hardware installs no Broadcom driver" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,67 @@ | ||
| #!/bin/bash | ||
|
|
||
| set -euo pipefail | ||
|
|
||
| source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh" | ||
|
|
||
| hw_nightlight="$ROOT/bin/omarchy-hw-nightlight" | ||
| toggle="$ROOT/bin/omarchy-toggle-nightlight" | ||
| menu="$ROOT/default/omarchy/omarchy-menu.jsonc" | ||
|
|
||
| test_tmp=$(mktemp -d) | ||
| trap 'rm -rf "$test_tmp"' EXIT | ||
|
|
||
| # A /sys/class/drm shaped tree: one directory per card bound to the named | ||
| # driver, plus the connector directories the real thing interleaves with them. | ||
| make_drm_tree() { | ||
| local tree="$test_tmp/drm-$RANDOM" | ||
| local index=0 | ||
| local driver | ||
|
|
||
| mkdir -p "$tree/drivers" | ||
|
|
||
| for driver in "$@"; do | ||
| mkdir -p "$tree/card$index/device" "$tree/drivers/$driver" | ||
| ln -s "../../drivers/$driver" "$tree/card$index/device/driver" | ||
| # Connectors hang off the same directory and must not be counted as cards. | ||
| mkdir -p "$tree/card$index-LVDS-1" "$tree/card$index-DVI-I-1" | ||
| (( ++index )) | ||
| done | ||
|
|
||
| echo "$tree" | ||
| } | ||
|
|
||
| supports_nightlight() { | ||
| OMARCHY_DRM_PATH="$1" "$BASH" "$hw_nightlight" | ||
| } | ||
|
|
||
| # Pre-GCN AMD: aquamarine's legacy DRM path never submits a CTM, so hyprsunset | ||
| # is a silent no-op here. | ||
| ! supports_nightlight "$(make_drm_tree radeon)" || | ||
| fail "a radeon-only machine reports no nightlight support" | ||
| pass "radeon-only hardware reports no nightlight support" | ||
|
|
||
| # Everything atomic must keep the feature. | ||
| supports_nightlight "$(make_drm_tree amdgpu)" || | ||
| fail "an amdgpu machine still supports nightlight" | ||
| supports_nightlight "$(make_drm_tree i915)" || | ||
| fail "an Intel machine still supports nightlight" | ||
| pass "atomic drivers keep nightlight" | ||
|
|
||
| # Conservative on mixed hardware: the display may be driven by the other GPU, | ||
| # and hiding a working feature is worse than leaving a broken one visible. | ||
| supports_nightlight "$(make_drm_tree radeon i915)" || | ||
| fail "a machine with both radeon and an atomic GPU keeps nightlight" | ||
| pass "mixed radeon plus atomic hardware keeps nightlight" | ||
|
|
||
| # Nothing to go on is not evidence of breakage. | ||
| supports_nightlight "$(make_drm_tree)" || | ||
| fail "a tree with no DRM cards does not claim nightlight is broken" | ||
| pass "an empty DRM tree keeps nightlight" | ||
|
|
||
| # The guard has to be wired up in both places, or the silent no-op comes back. | ||
| grep -Fq '"when":"omarchy-hw-nightlight"' "$menu" || | ||
| fail "the menu hides the Nightlight row on hardware that cannot do it" | ||
| grep -Fq 'if ! omarchy-hw-nightlight; then' "$toggle" || | ||
| fail "omarchy-toggle-nightlight refuses instead of reporting a false success" | ||
| pass "the nightlight guard is wired into the menu and the toggle" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,87 @@ | ||
| #!/bin/bash | ||
|
|
||
| set -euo pipefail | ||
|
|
||
| source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh" | ||
|
|
||
| vulkan="$ROOT/install/hardware/vulkan.sh" | ||
|
|
||
| test_tmp=$(mktemp -d) | ||
| trap 'rm -rf "$test_tmp"' EXIT | ||
|
|
||
| stub_bin="$test_tmp/bin" | ||
| mkdir -p "$stub_bin" | ||
|
|
||
| # lspci only has to name the vendor on a VGA line; the driver question is | ||
| # answered from sysfs, which is what this script actually gates on. | ||
| cat >"$stub_bin/lspci" <<'SH' | ||
| #!/bin/bash | ||
| echo "01:00.0 VGA compatible controller: ${STUB_GPU_VENDOR:-Advanced Micro Devices, Inc. [AMD/ATI]} RV610" | ||
| SH | ||
| chmod +x "$stub_bin/lspci" | ||
|
|
||
| # A GPU claimed by $1 ("radeon" or "amdgpu"), shaped like /sys/bus/pci/devices. | ||
| make_pci_tree() { | ||
| local driver=$1 | ||
| local vendor=${2:-0x1002} | ||
| local tree="$test_tmp/pci-$driver-$RANDOM" | ||
|
|
||
| mkdir -p "$tree/0000:01:00.0" "$tree/drivers/$driver" | ||
| echo "$vendor" >"$tree/0000:01:00.0/vendor" | ||
| echo "0x030000" >"$tree/0000:01:00.0/class" | ||
| ln -s "../drivers/$driver" "$tree/0000:01:00.0/driver" | ||
|
|
||
| echo "$tree" | ||
| } | ||
|
|
||
| # Sourcing vulkan.sh with omarchy-pkg-add stubbed records what it would install. | ||
| # The packages go to a file rather than stdout: the script also explains itself | ||
| # on stdout, and those messages name the very packages being asserted on. | ||
| installed_packages() { | ||
| local pci_path=$1 | ||
| local calls="$test_tmp/calls-$RANDOM" | ||
|
|
||
| # "$BASH", not "bash": vulkan.sh needs an associative array, and a stray | ||
| # bash 3.2 earlier in PATH would silently drop the AMD entry instead. | ||
| PATH="$stub_bin:$PATH" \ | ||
| OMARCHY_PCI_DEVICES_PATH="$pci_path" \ | ||
| OMARCHY_TEST_CALLS="$calls" \ | ||
| "$BASH" -c ' | ||
| omarchy-pkg-add() { printf "%s\n" "$@" >>"$OMARCHY_TEST_CALLS"; } | ||
| source "$1" | ||
| ' _ "$vulkan" >/dev/null 2>&1 | ||
|
|
||
| [[ -f $calls ]] && cat "$calls" || true | ||
| } | ||
|
|
||
| # Pre-GCN: radeon-driven AMD GPUs cannot be used by RADV, and the ICD that | ||
| # vulkan-radeon drops in would otherwise make omarchy-hw-vulkan answer yes. | ||
| pre_gcn=$(make_pci_tree radeon) | ||
| result=$(installed_packages "$pre_gcn") | ||
| [[ $result != *vulkan-radeon* ]] || | ||
| fail "vulkan-radeon is skipped on a pre-GCN AMD GPU bound to radeon (got: $result)" | ||
| pass "pre-GCN AMD GPUs on the radeon driver do not get vulkan-radeon" | ||
|
|
||
| # GCN and newer still must, or every supported AMD machine loses Vulkan. | ||
| gcn=$(make_pci_tree amdgpu) | ||
| result=$(installed_packages "$gcn") | ||
| [[ $result == *vulkan-radeon* ]] || | ||
| fail "vulkan-radeon is still installed for an amdgpu-bound GPU (got: $result)" | ||
| pass "AMD GPUs on the amdgpu driver still get vulkan-radeon" | ||
|
|
||
| # A GPU with no bound driver (an installer booted with nomodeset) says nothing | ||
| # about the installed system, so it keeps vulkan-radeon as before. | ||
| unbound="$test_tmp/pci-unbound" | ||
| mkdir -p "$unbound/0000:01:00.0" | ||
| echo "0x1002" >"$unbound/0000:01:00.0/vendor" | ||
| echo "0x030000" >"$unbound/0000:01:00.0/class" | ||
| result=$(installed_packages "$unbound") | ||
| [[ $result == *vulkan-radeon* ]] || | ||
| fail "vulkan-radeon is still installed when no driver is bound to the AMD GPU (got: $result)" | ||
| pass "an AMD GPU with no bound driver still gets vulkan-radeon" | ||
|
|
||
| # The AMD guard must not touch the other vendors' drivers. | ||
| result=$(STUB_GPU_VENDOR="Intel Corporation" installed_packages "$pre_gcn") | ||
| [[ $result == *vulkan-intel* ]] || | ||
| fail "Intel GPUs still get vulkan-intel regardless of the AMD guard (got: $result)" | ||
| pass "the AMD guard leaves vulkan-intel selection alone" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On a radeon-only machine, this guard blocks the CLI toggle, but the bar indicator calls the QML nightlight service directly. That service still sends the temperature to Hyprland and marks nightlight as enabled. Clicking the indicator therefore reports success even though the panel does not change. The same capability check needs to cover the bar’s control path.
Knowledge Base Used: Hardware profiles and device controls