Compare commits

..

1 Commits

Author SHA1 Message Date
2f081d3e19 fix: panel-cwu50 timing fix from Rex's kernel - native 720x1280 mode
Swap H/V display mode to native panel resolution (720x1280) instead of
rotated (1280x720). The DRM/KMS pipeline handles rotation via connector
orientation property. Setting wrong horizontal resolution caused DSI
controller to send extra pixels per line, resulting in horizontal
repetition.

Add DCS-based panel detection in init_sequence2 as supplemental check.

Based on ak-rex/ClockworkPi-linux rpi-6.12.y branch panel-cwu50.c.

Replaces old 0008 patches (DSI_INIT0, BURST removal) that didn't fix
the issue.
2026-06-13 20:19:19 -04:00
5 changed files with 162 additions and 201 deletions

187
flake.nix
View File

@@ -12,18 +12,21 @@
url = "git+https://git.lix.systems/lix-project/lix?ref=main"; url = "git+https://git.lix.systems/lix-project/lix?ref=main";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
nixpkgs-uconsole.url = "github:NixOS/nixpkgs/nixos-25.11";
nixos-uconsole = { nixos-uconsole = {
url = "github:nixos-uconsole/nixos-uconsole"; url = "github:nixos-uconsole/nixos-uconsole/v1.1.0";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs-uconsole";
inputs.nixos-raspberrypi.follows = "nixos-raspberrypi";
}; };
nixos-raspberrypi = { nixos-raspberrypi = {
url = "github:nvmd/nixos-raspberrypi/v1.20260517.0"; url = "github:gortium/nixos-raspberrypi/cm5-cross-v1";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs-uconsole";
}; };
self.submodules = true;
}; };
outputs = { self, nixpkgs, agenix, lix, nixos-uconsole, nixos-raspberrypi, ... }@inputs: outputs = { self, nixpkgs, agenix, lix
, nixpkgs-uconsole, nixos-uconsole, nixos-raspberrypi
, ... }@inputs:
let let
system = "x86_64-linux"; system = "x86_64-linux";
keys = import ./lib/keys.nix; keys = import ./lib/keys.nix;
@@ -34,78 +37,120 @@
"/etc/ssh/ssh_host_ed25519_key" "/etc/ssh/ssh_host_ed25519_key"
"/root/.age/bootstrap.key" ]; "/root/.age/bootstrap.key" ];
}; };
overlays = [ agenix.overlays.default (import ./overlays/reticulum.nix) ]; overlays = [ agenix.overlays.default ];
pkgs = import nixpkgs { pkgs = import nixpkgs {
inherit system overlays; inherit system overlays;
config.allowUnfree = true; config.allowUnfree = true;
config.permittedInsecurePackages = [ config.permittedInsecurePackages = [ "openclaw-2026.3.12" ];
"openclaw-2026.3.12"
];
}; };
devShell = import ./shells/nix_dev.nix { devShell = import ./shells/nix_dev.nix {
inherit pkgs system agenix; inherit pkgs system agenix;
}; };
in in {
{ nixosConfigurations = {
nixosConfigurations = { lazyworkhorse = nixpkgs.lib.nixosSystem {
lazyworkhorse = nixpkgs.lib.nixosSystem { specialArgs = { inherit system self keys paths inputs; };
specialArgs = { inherit system self keys paths inputs; }; modules = [
modules = [ {
{ nixpkgs.overlays = overlays;
nixpkgs.overlays = overlays; nixpkgs.config.allowUnfree = true;
nixpkgs.config.allowUnfree = true; nixpkgs.config.rocmSupport = true;
nixpkgs.config.rocmSupport = true; nixpkgs.config.permittedInsecurePackages = [ "openclaw-2026.3.12" ];
nixpkgs.config.permittedInsecurePackages = [ nix.package = lix.packages.${system}.default;
"openclaw-2026.3.12" }
]; agenix.nixosModules.default
nix.package = lix.packages.${system}.default; ./hosts/lazyworkhorse/configuration.nix
} ./hosts/lazyworkhorse/hardware-configuration.nix
agenix.nixosModules.default ./modules/nixos/filesystem/hoardingcow-mount.nix
./hosts/lazyworkhorse/configuration.nix ./modules/nixos/services/docker_manager.nix
./hosts/lazyworkhorse/hardware-configuration.nix ./modules/nixos/services/open_code_server.nix
./modules/nixos/filesystem/hoardingcow-mount.nix ./modules/nixos/services/ollama_init_custom_models.nix
./modules/nixos/filesystem/poup-16t-disk.nix ./modules/nixos/services/openclaw_node.nix
./modules/nixos/services/docker_manager.nix ./modules/nixos/security/ai-worker-restricted.nix
./modules/nixos/services/open_code_server.nix ./users/gortium.nix
./modules/nixos/services/ollama_init_custom_models.nix ./users/ai-worker.nix
./modules/nixos/services/openclaw_node.nix ];
./modules/nixos/security/ai-worker-restricted.nix };
./users/gortium.nix
./users/ai-worker.nix cyt-pi = nixpkgs.lib.nixosSystem {
]; specialArgs = { inherit self keys paths inputs; };
}; modules = [
{
cyt-pi = nixpkgs.lib.nixosSystem { nixpkgs.overlays = overlays;
specialArgs = { inherit self keys paths inputs; }; nixpkgs.config.allowUnfree = true;
modules = [ nixpkgs.hostPlatform = "aarch64-linux";
{ nix.package = lix.packages."aarch64-linux".default;
nixpkgs.overlays = overlays; }
nixpkgs.config.allowUnfree = true; ./hosts/cyt-pi/configuration.nix
nixpkgs.hostPlatform = "aarch64-linux"; ./hosts/cyt-pi/hardware-configuration.nix
nix.package = lix.packages."aarch64-linux".default; ];
} };
./hosts/cyt-pi/configuration.nix
./hosts/cyt-pi/hardware-configuration.nix uconsole-cm5 = nixpkgs-uconsole.lib.nixosSystem {
]; system = "aarch64-linux";
}; specialArgs = {
inherit self keys paths inputs;
uConsole = nixos-raspberrypi.lib.nixosSystem { nixos-raspberrypi = nixos-raspberrypi;
specialArgs = { inherit self keys paths inputs nixos-raspberrypi; }; isCM4 = false;
modules = [ };
{ modules = [
nixpkgs.overlays = overlays; {
nixpkgs.config.allowUnfree = true; nixpkgs.buildPlatform = "x86_64-linux";
nixpkgs.hostPlatform = "aarch64-linux"; nixpkgs.hostPlatform = "aarch64-linux";
nix.package = lix.packages."aarch64-linux".default; nixpkgs.config.allowUnfree = true;
} boot.loader.raspberry-pi.bootloader = "kernel";
nixos-raspberrypi.nixosModules.raspberry-pi-5.base }
nixos-uconsole.nixosModules.uconsole-cm5 nixos-raspberrypi.nixosModules.nixpkgs-rpi
./hosts/uConsole/configuration.nix # Fix display timings from Rex's kernel: native 720x1280 instead of
./hosts/uConsole/hardware-configuration.nix # rotated 1280x720, plus DCS-based panel detection.
]; ({ lib, ... }: {
}; boot.kernelPatches = [{
name = "panel-cwu50-rex-timing-fix";
patch = ./patches/0008-panel-cwu50-rex-timing-fix.patch;
}];
})
nixos-raspberrypi.nixosModules.raspberry-pi-5.base
nixos-raspberrypi.lib.inject-overlays
nixos-raspberrypi.lib.inject-overlays-global
nixos-uconsole.nixosModules.uconsole-cm5
({ config, lib, pkgs, inputs, ... }: let
lix-cross = import inputs.nixpkgs-uconsole {
localSystem = { system = "x86_64-linux"; };
crossSystem = { system = "aarch64-linux"; };
overlays = [ inputs.lix.overlays.default ];
};
in { nix.package = lix-cross.lix; })
agenix.nixosModules.default
./hosts/uconsole-cm5/configuration.nix
./hosts/uconsole-cm5/hardware-configuration.nix
];
}; };
devShells.${system}.default = devShell;
}; };
devShells.${system}.default = devShell;
packages.${system} = {
uconsole-cm5-image = (nixos-raspberrypi.lib.nixosSystem {
system = "aarch64-linux";
specialArgs = {
inherit self keys inputs;
nixos-raspberrypi = nixos-raspberrypi;
isCM4 = false;
};
modules = [
{
nixpkgs.buildPlatform = system;
nixpkgs.hostPlatform = "aarch64-linux";
}
nixos-raspberrypi.nixosModules.nixpkgs-rpi
nixos-raspberrypi.nixosModules.raspberry-pi-5.base
nixos-raspberrypi.lib.inject-overlays-global
nixos-raspberrypi.nixosModules.sd-image
nixos-uconsole.nixosModules.uconsole-cm5
agenix.nixosModules.default
./hosts/uconsole-cm5/configuration.nix
];
}).config.system.build.sdImage;
};
};
} }

View File

@@ -8,14 +8,6 @@
# NAS Mounting # NAS Mounting
hoardingcow-mount.enable = true; hoardingcow-mount.enable = true;
# 16TB btrfs storage disk (WD Red Pro — Poup_16T — LUKS2 + btrfs + btrbk snapshots)
# ⚠ SETUP REQUIRED: Connect the disk, get the LUKS UUID with 'blkid /dev/sdb',
# then set gortium.poup16t.luksUuid here and deploy.
# gortium.poup16t = {
# enable = true;
# luksUuid = "REPLACE_ME_WITH_REAL_UUID";
# };
# Flakesss # Flakesss
nix.settings.experimental-features = [ "nix-command" "flakes" "flake-self-attrs" ]; nix.settings.experimental-features = [ "nix-command" "flakes" "flake-self-attrs" ];
nix.settings.trusted-users = [ "root" "gortium" ]; nix.settings.trusted-users = [ "root" "gortium" ];

View File

@@ -1,121 +0,0 @@
{ config, lib, pkgs, ... }:
let
cfg = config.gortium.poup16t;
luksName = cfg.luksName;
in
with lib;
{
options.gortium.poup16t = {
enable = mkEnableOption "Poup_16T storage disk (btrfs + LUKS + btrbk snapshots)";
luksUuid = mkOption {
type = types.str;
description = ''
UUID of the LUKS partition on the 16TB disk (WD Red Pro).
Find this by running as root when the disk is connected:
blkid /dev/sdb # or wherever the disk appears
lsblk -o NAME,SIZE,FSTYPE,UUID
Since btrfs is inside LUKS, the FS UUID is hidden use the
LUKS partition UUID from blkid (it'll show TYPE=\"crypto_LUKS\").
'';
example = "00000000-0000-0000-0000-000000000000";
};
luksName = mkOption {
type = types.str;
default = "poup_16t";
description = "Name for the LUKS /dev/mapper/ mapping";
};
mountPoint = mkOption {
type = types.str;
default = "/mnt/Poup_16T";
description = "Mount point for the 16TB data disk";
};
btrfsOptions = mkOption {
type = types.listOf types.str;
default = [ "defaults" "noatime" "compress=zstd:3" "nofail" ];
description = "Mount options for the btrfs filesystem. 'nofail' ensures boot succeeds when disk is disconnected.";
};
btrbk = {
enable = mkOption {
type = types.bool;
default = true;
description = "Enable btrbk snapshot management on this volume";
};
schedule = mkOption {
type = types.str;
default = "daily";
description = "systemd calendar event for btrbk (e.g. 'daily', 'hourly', '*-*-* 00:00:00')";
};
preserveMin = mkOption {
type = types.str;
default = "2d";
description = "btrbk snapshot_preserve_min minimum age before pruning";
};
preserve = mkOption {
type = types.str;
default = "14d 4w 3m";
description = "btrbk snapshot_preserve retention policy (daily, weekly, monthly)";
};
snapshotDir = mkOption {
type = types.str;
default = ".snapshots";
description = "Directory name for snapshots relative to volume root";
};
};
};
config = mkIf cfg.enable {
# Enable btrfs kernel support (no DKMS needed — it's in-tree)
boot.supportedFilesystems = [ "btrfs" ];
# Install btrfs administration tools
environment.systemPackages = with pkgs; [
btrfs-progs # mkfs.btrfs, btrfs, fsck, balance, scrub
btrbk # Snapshot management + rotation
];
# LUKS2 unlock at boot (uses keyfile or prompts if unavailable)
# Since the disk may be disconnected, initrd times out gracefully (~30s)
boot.initrd.luks.devices.${luksName} = {
device = "/dev/disk/by-uuid/${cfg.luksUuid}";
preLVM = false;
allowDiscards = true;
};
# Mount the unlocked mapper device as btrfs
fileSystems.${cfg.mountPoint} = {
device = "/dev/mapper/${luksName}";
fsType = "btrfs";
options = cfg.btrfsOptions;
};
# btrbk — automated snapshot creation and rotation
services.btrbk = mkIf cfg.btrbk.enable {
instances.poup16t = {
onCalendar = cfg.btrbk.schedule;
settings = {
snapshot_preserve_min = cfg.btrbk.preserveMin;
snapshot_preserve = cfg.btrbk.preserve;
volume.${cfg.mountPoint} = {
snapshot_create = "always";
snapshot_dir = cfg.btrbk.snapshotDir;
subvolume = ".";
};
};
};
};
};
}

View File

@@ -0,0 +1,45 @@
--- a/drivers/gpu/drm/panel/panel-cwu50.c
+++ b/drivers/gpu/drm/panel/panel-cwu50.c
@@ -27,12 +27,12 @@ static const struct drm_display_mode default_mode = {
.clock = 61020,
- .hdisplay = 1280,
- .hsync_start = 1280 + 8,
- .hsync_end = 1280 + 8 + 2,
- .htotal = 1280 + 8 + 2 + 16,
- .vdisplay = 720,
- .vsync_start = 720 + 30,
- .vsync_end = 720 + 30 + 15,
- .vtotal = 720 + 30 + 15 + 15,
+ .hdisplay = 720,
+ .hsync_start = 720 + 30,
+ .hsync_end = 720 + 30 + 15,
+ .htotal = 720 + 30 + 15 + 15,
+ .vdisplay = 1280,
+ .vsync_start = 1280 + 8,
+ .vsync_end = 1280 + 8 + 2,
+ .vtotal = 1280 + 8 + 2 + 16,
};
static inline struct cwu50 *panel_to_cwu50(struct drm_panel *panel)
@@ -586,7 +586,8 @@ static int cwu50_init_sequence2(struct cwu50 *ctx)
{
struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
- int err;
+ int err;
+ u8 buf[4];
dcs_write_seq(0xE0,0x00);
@@ -633,6 +634,12 @@ static int cwu50_init_sequence2(struct cwu50 *ctx)
dcs_write_seq(0x11);// SLPOUT
msleep (200);
+ dcs_write_seq(0xE0,0x00);
+ mipi_dsi_dcs_read(dsi, 0x04, buf, 3);
+
+ if(buf[0] == 0x39) ctx->is_new_panel = 1;
+
+ dcs_write_seq(0xE0,0x00);
dcs_write_seq(0x29);// DSiPON
msleep (100);