| -rw-r--r-- | README.md | 20 | ||||
| -rw-r--r-- | kernel-surface.spec | 18 | ||||
| -rwxr-xr-x | make-sources.sh | 24 | ||||
| -rw-r--r-- | patch-order.txt | 9 | ||||
| -rw-r--r-- | patches/camera/0027-media-i2c-ov13858-fix-bayer-order-when-mirrored.patch | 115 | ||||
| -rw-r--r-- | patches/surface/0016-arm64-dts-qcom-purwa-Microsoft-Surface-Pro-12in-iris-firmware-name.patch | 32 |
6 files changed, 8 insertions, 210 deletions
@@ -13,26 +13,6 @@ Used in [Fedora KIWI descriptions, modified by me for Surface Pro 12"](https://s `vanilla-kernel-*.ebuild` applies them, minus `gpu` (does not exist) and `rockchip` (irrelevant). -An entry prefixed with `local:` is not the overlay's, it is `patches/<name>/` -in this repository. Those carry fixes the overlay has not picked up, and they -live outside the submodule so that `git submodule update` cannot silently drop -them. They are listed right after the overlay directory they extend, so the -same numbering that orders the overlay's series orders these too. - -- `patches/camera/0027-media-i2c-ov13858-fix-bayer-order-when-mirrored.patch` - the rear camera advertises GRBG while the horizontal mirror, which - `rotation = <180>` turns on, makes it deliver RGGB. Debayering with the wrong - pattern puts both greens into the red and blue channels, so the picture comes - out close to monochrome. -- `patches/surface/0016-arm64-dts-qcom-purwa-Microsoft-Surface-Pro-12in-iris-firmware-name.patch` - the video codec firmware in linux-firmware is signed with Qualcomm's SecTools - test key, which this device's TrustZone rejects with `error -22 initializing - firmware`. Points the iris node at the production-signed build shipped in the - Windows driver package instead. - -Send them upstream to the overlay when they are ready; drop the `local:` entry -and the directory once the overlay carries them. - ## Configuration The starting point is `config/base-aarch64.config`: Fedora's own aarch64 diff --git a/kernel-surface.spec b/kernel-surface.spec index e238be7..5acf949 100644 --- a/kernel-surface.spec +++ b/kernel-surface.spec @@ -17,7 +17,7 @@ # Bumped whenever the patch tarball changes without the upstream version moving. %if %{undefined patchset_ver} -%global patchset_ver 2 +%global patchset_ver 1 %endif # rpm gives - to the version-release separator, so it cannot appear in Version @@ -143,18 +143,6 @@ for patchdir in patches/*/; do done rm -rf patches -# The camera series calls devm_phy_get_by_of_node(), which only the phy series -# adds -- and the overlay's own 7.2.3 ebuild left phy out of its loop while -# shipping the camera patch that needs it. Applying one without the other -# compiles for twenty-odd minutes before failing in camss-csiphy.c, so assert -# the declaration is here while it is still cheap to say so. -grep -q 'devm_phy_get_by_of_node' include/linux/phy/phy.h || { - echo "ERROR: include/linux/phy/phy.h does not declare devm_phy_get_by_of_node." - echo "The camera patches need the phy ones; check phy is in patch-order.txt" - echo "and that it exists at the pinned overlay commit." - exit 1 -} - # Fold the -rcN suffix into the package release instead of carrying it in # uname -r, so the module directory is named the way Fedora names it. sed -i 's/^EXTRAVERSION[[:space:]]*=.*/EXTRAVERSION =/' Makefile @@ -246,9 +234,5 @@ fi %ghost %attr(0644,root,root) /boot/vmlinuz-%{kverrel} %changelog -* Sun Sep 06 2026 Saya Andy 7.2.3-2 -- Local camera patch: report the right bayer order when mirrored (fixes the black-green monochrome output issue) -- Local surface patch: point iris at the OEM video firmware (fixes error -22 for video encoding/decoding) - * Sun Sep 06 2026 Saya Andy 7.2.3-1 - Initial package: vanilla 7.2.3 with the overlay's Surface Pro 12" patch set diff --git a/make-sources.sh b/make-sources.sh index 7271bf8..b4abb4b 100755 --- a/make-sources.sh +++ b/make-sources.sh @@ -3,9 +3,8 @@ # Assemble the rpmbuild sources for kernel-surface.spec: # # * kernel-surface-patches-<upstream_ver>-<patchset_ver>.tar.gz, built from the -# directories listed in patch-order.txt: bare names come from the overlay -# submodule's sys-kernel/vanilla-kernel/files, "local:" ones from this -# repository's patches/ +# overlay submodule's sys-kernel/vanilla-kernel/files directories listed in +# patch-order.txt # * the upstream kernel tarball # * the base kernel config and the fragments from config/ # @@ -33,7 +32,6 @@ spec="${script_dir}/kernel-surface.spec" order_file="${script_dir}/patch-order.txt" overlay_dir=${OVERLAY_DIR:-${script_dir}/overlay} patch_root="${overlay_dir}/sys-kernel/vanilla-kernel/files" -local_patch_root="${script_dir}/patches" output_dir="" skip_download=false @@ -97,19 +95,7 @@ while read -r dir; do dir=${dir//[[:space:]]/} [[ -n ${dir} ]] || continue - # "local:foo" is patches/foo in this repository, "foo" is the overlay's - # files/foo. The staging name keeps the prefix so the tarball, and the - # spec's "Applying ..." log, say where each patch came from. - if [[ ${dir} == local:* ]]; then - name=${dir#local:} - src="${local_patch_root}/${name}" - label="local-${name}" - else - name=${dir} - src="${patch_root}/${name}" - label=${name} - fi - + src="${patch_root}/${dir}" if [[ ! -d ${src} ]]; then echo "ERROR: ${src} does not exist (listed in patch-order.txt)" >&2 exit 1 @@ -121,11 +107,11 @@ while read -r dir; do exit 1 fi - dest=$(printf '%s/patches/%02d-%s' "${staging}" "${index}" "${label}") + dest=$(printf '%s/patches/%02d-%s' "${staging}" "${index}" "${dir}") mkdir -p "${dest}" cp "${src}"/*.patch "${dest}/" - printf ' %02d %-18s %2d patches\n' "${index}" "${label}" "${count}" + printf ' %02d %-12s %2d patches\n' "${index}" "${dir}" "${count}" index=$((index + 1)) total=$((total + count)) done < "${order_file}" diff --git a/patch-order.txt b/patch-order.txt index d47080f..5a4b0c8 100644 --- a/patch-order.txt +++ b/patch-order.txt @@ -1,8 +1,5 @@ -# Patch directories in application order. -# -# A bare name is a directory under the Gentoo overlay's -# sys-kernel/vanilla-kernel/files. A "local:" prefix means patches/<name> in -# this repository, for fixes the overlay does not carry yet. +# Patch directories under the Gentoo overlay's sys-kernel/vanilla-kernel/files, +# in application order. # # This mirrors the loop in vanilla-kernel-7.2.3.ebuild's src_prepare(), minus # rockchip (irrelevant), plus phy -- which that ebuild leaves out even though it @@ -21,7 +18,5 @@ input el2 phy camera -local:camera irq surface -local:surface diff --git a/patches/camera/0027-media-i2c-ov13858-fix-bayer-order-when-mirrored.patch b/patches/camera/0027-media-i2c-ov13858-fix-bayer-order-when-mirrored.patch deleted file mode 100644 index 06b8495..0000000 --- a/patches/camera/0027-media-i2c-ov13858-fix-bayer-order-when-mirrored.patch +++ /dev/null @@ -1,115 +0,0 @@ -media: i2c: ov13858: report the right bayer order when mirrored - -The driver always advertises MEDIA_BUS_FMT_SGRBG10_1X10, but the horizontal -mirror moves the Bayer phase by one column, so the sensor actually delivers -RGGB while HFLIP is set. The Surface Pro 12in has the rear ov13858 mounted -upside down (rotation = <180> in DT), so both flips end up enabled and every -frame is debayered with the wrong pattern: the two greens land in the red and -blue output channels and the picture comes out desaturated, close to -monochrome. - -Measured on a Surface Pro 12in by capturing raw frames off the CAMSS RDI node -and comparing the mean absolute difference of the two diagonal pairs of each -2x2 quad (the two green samples correlate far better than red against blue): - - hflip=0 vflip=0 diagonal 4.29 antidiagonal 6.84 -> greens diagonal - hflip=1 vflip=0 diagonal 7.03 antidiagonal 4.31 -> greens antidiagonal - hflip=0 vflip=1 diagonal 4.35 antidiagonal 6.84 -> greens diagonal - hflip=1 vflip=1 diagonal 6.93 antidiagonal 4.34 -> greens antidiagonal - -So only the horizontal mirror moves the phase; the ISP Y window offset written -for VFLIP compensates the vertical one. Derive the media bus code from HFLIP -and tag the control with V4L2_CTRL_FLAG_MODIFY_LAYOUT so userspace knows to -renegotiate the format after toggling it. - ---- a/drivers/media/i2c/ov13858.c -+++ b/drivers/media/i2c/ov13858.c -@@ -1032,6 +1032,7 @@ - struct v4l2_ctrl *vblank; - struct v4l2_ctrl *hblank; - struct v4l2_ctrl *exposure; -+ struct v4l2_ctrl *hflip; - - struct clk *img_clk; - struct gpio_desc *reset_gpio; -@@ -1222,8 +1223,10 @@ - OV13858_DGTL_GAIN_MIN, OV13858_DGTL_GAIN_MAX, - OV13858_DGTL_GAIN_STEP, OV13858_DGTL_GAIN_DEFAULT); - -- v4l2_ctrl_new_std(ctrl_hdlr, &ov13858_ctrl_ops, V4L2_CID_HFLIP, -- 0, 1, 1, 0); -+ ov13858->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &ov13858_ctrl_ops, -+ V4L2_CID_HFLIP, 0, 1, 1, 0); -+ if (ov13858->hflip) -+ ov13858->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT; - - v4l2_ctrl_new_std(ctrl_hdlr, &ov13858_ctrl_ops, V4L2_CID_VFLIP, - 0, 1, 1, 0); -@@ -1258,12 +1261,24 @@ - return ret; - } - --static void ov13858_update_pad_format(const struct ov13858_mode *mode, -+/* -+ * Mirroring shifts the Bayer phase by one column, so the native GRBG order -+ * becomes RGGB. The vertical flip is compensated by the ISP Y window offset -+ * and leaves the order alone. -+ */ -+static u32 ov13858_get_format_code(struct ov13858 *ov13858) -+{ -+ return ov13858->hflip->val ? MEDIA_BUS_FMT_SRGGB10_1X10 -+ : MEDIA_BUS_FMT_SGRBG10_1X10; -+} -+ -+static void ov13858_update_pad_format(struct ov13858 *ov13858, -+ const struct ov13858_mode *mode, - struct v4l2_mbus_framefmt *fmt) - { - fmt->width = mode->width; - fmt->height = mode->height; -- fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10; -+ fmt->code = ov13858_get_format_code(ov13858); - fmt->field = V4L2_FIELD_NONE; - } - -@@ -1418,7 +1433,7 @@ - ARRAY_SIZE(supported_modes), - width, height, - fmt->format.width, fmt->format.height); -- ov13858_update_pad_format(mode, &fmt->format); -+ ov13858_update_pad_format(ov13858, mode, &fmt->format); - *v4l2_subdev_state_get_format(sd_state, fmt->pad) = fmt->format; - - if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) -@@ -1453,11 +1468,11 @@ - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_mbus_code_enum *code) - { -- /* Only one bayer order(GRBG) is supported */ -+ /* Only one bayer order is supported, which one depends on the mirror */ - if (code->index > 0) - return -EINVAL; - -- code->code = MEDIA_BUS_FMT_SGRBG10_1X10; -+ code->code = ov13858_get_format_code(to_ov13858(sd)); - - return 0; - } -@@ -1469,7 +1484,7 @@ - if (fse->index >= ARRAY_SIZE(supported_modes)) - return -EINVAL; - -- if (fse->code != MEDIA_BUS_FMT_SGRBG10_1X10) -+ if (fse->code != ov13858_get_format_code(to_ov13858(sd))) - return -EINVAL; - - fse->min_width = supported_modes[fse->index].width; -@@ -1520,7 +1535,7 @@ - { - struct ov13858 *ov13858 = to_ov13858(sd); - -- ov13858_update_pad_format(ov13858->cur_mode, -+ ov13858_update_pad_format(ov13858, ov13858->cur_mode, - v4l2_subdev_state_get_format(sd_state, 0)); - - return 0; diff --git a/patches/surface/0016-arm64-dts-qcom-purwa-Microsoft-Surface-Pro-12in-iris-firmware-name.patch b/patches/surface/0016-arm64-dts-qcom-purwa-Microsoft-Surface-Pro-12in-iris-firmware-name.patch deleted file mode 100644 index b182b0b..0000000 --- a/patches/surface/0016-arm64-dts-qcom-purwa-Microsoft-Surface-Pro-12in-iris-firmware-name.patch +++ /dev/null @@ -1,32 +0,0 @@ -arm64: dts: qcom: purwa: Microsoft Surface Pro 12in: point iris at the OEM video firmware - -The generic qcom/vpu/vpu30_p1_s7.mbn shipped by linux-firmware is signed with -the Qualcomm SecTools test key chain ("SECTOOLS SECP384R1 CURVE TEST ROOT" / -"General Use Test Key (for testing only)"), which the TrustZone on a retail -Surface Pro 12in refuses: - - qcom-iris aa00000.video-codec: error -22 initializing firmware qcom/vpu/vpu30_p1_s7.mbn - qcom-iris aa00000.video-codec: firmware download failed - qcom-iris aa00000.video-codec: core init failed - -The -22 comes straight out of qcom_scm_pas_init_image() in -__qcom_mdt_pas_init(), i.e. the image metadata is rejected before anything is -loaded. - -The Windows driver package for this machine carries the same firmware signed -with the production chain ("QMC Attestation Root CA 6"), in two builds: -qcvss8380.mbn and qcvss8380_pa.mbn. The _pa one is what loads here. It has an -identical 7 MiB load span, so it fits the existing video_mem reservation -unchanged. Point the iris node at it, the same way the board already does for -the aDSP, cDSP and GPU firmware. - ---- a/arch/arm64/boot/dts/qcom/x1p42100-microsoft-sp12in.dts -+++ b/arch/arm64/boot/dts/qcom/x1p42100-microsoft-sp12in.dts -@@ -1098,6 +1098,7 @@ - }; - - &iris { -+ firmware-name = "qcom/x1p42100/Microsoft/Surface12/qcvss8380_pa.mbn"; - status = "okay"; - }; - |