summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJani Nikula <jani.nikula@intel.com>2023-05-31 12:01:51 +0300
committerJani Nikula <jani.nikula@intel.com>2023-05-31 12:01:51 +0300
commite2a9f0a32464f435dbdb190ff7dbf09745703b60 (patch)
treebae874fad606918fdae32a99a2b47a76f3a605b3
parent3e36c490698660ba4fa7cedfab03f3ed81a07192 (diff)
parent85d712f033d23bb56a373e29465470c036532d46 (diff)
downloadlinux-e2a9f0a32464f435dbdb190ff7dbf09745703b60.tar.xz
Merge drm/drm-next into drm-intel-next
Sync the drm-intel-gt-next changes back to drm-intel-next via drm-next. Signed-off-by: Jani Nikula <jani.nikula@intel.com>
-rw-r--r--Documentation/block/index.rst1
-rw-r--r--Documentation/block/request.rst99
-rw-r--r--Documentation/devicetree/bindings/display/bridge/fsl,ldb.yaml5
-rw-r--r--Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml23
-rw-r--r--Documentation/devicetree/bindings/display/bridge/toshiba,tc358767.yaml14
-rw-r--r--Documentation/devicetree/bindings/display/panel/novatek,nt36523.yaml16
-rw-r--r--Documentation/devicetree/bindings/display/panel/panel-simple.yaml4
-rw-r--r--Documentation/devicetree/bindings/display/panel/rocktech,jh057n00900.yaml2
-rw-r--r--Documentation/devicetree/bindings/display/panel/samsung,s6d7aa0.yaml70
-rw-r--r--Documentation/devicetree/bindings/media/i2c/ovti,ov2685.yaml1
-rw-r--r--Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-common.yaml13
-rw-r--r--Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-ep.yaml38
-rw-r--r--Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml77
-rw-r--r--Documentation/gpu/rfc/index.rst4
-rw-r--r--Documentation/gpu/rfc/xe.rst235
-rw-r--r--Documentation/gpu/todo.rst7
-rw-r--r--Documentation/gpu/vkms.rst7
-rw-r--r--Documentation/networking/bonding.rst9
-rw-r--r--Documentation/networking/index.rst2
-rw-r--r--Documentation/networking/x25-iface.rst3
-rw-r--r--MAINTAINERS2240
-rw-r--r--Makefile2
-rw-r--r--arch/arc/include/asm/fb.h16
-rw-r--r--arch/arm/include/asm/fb.h15
-rw-r--r--arch/arm/kernel/unwind.c25
-rw-r--r--arch/arm/mach-sa1100/jornada720_ssp.c5
-rw-r--r--arch/arm/vfp/entry.S7
-rw-r--r--arch/arm/vfp/vfphw.S6
-rw-r--r--arch/arm64/include/asm/fb.h15
-rw-r--r--arch/ia64/include/asm/fb.h27
-rw-r--r--arch/loongarch/include/asm/fb.h24
-rw-r--r--arch/m68k/include/asm/fb.h22
-rw-r--r--arch/mips/include/asm/fb.h28
-rw-r--r--arch/parisc/Makefile4
-rw-r--r--arch/parisc/include/asm/fb.h20
-rw-r--r--arch/parisc/include/asm/pgtable.h8
-rw-r--r--arch/parisc/kernel/kexec.c2
-rw-r--r--arch/parisc/video/Makefile3
-rw-r--r--arch/parisc/video/fbdev.c26
-rw-r--r--arch/powerpc/include/asm/fb.h8
-rw-r--r--arch/riscv/kernel/pi/Makefile2
-rw-r--r--arch/riscv/kernel/vmlinux.lds.S7
-rw-r--r--arch/sh/include/asm/fb.h15
-rw-r--r--arch/sparc/Makefile1
-rw-r--r--arch/sparc/include/asm/fb.h47
-rw-r--r--arch/sparc/video/Makefile3
-rw-r--r--arch/sparc/video/fbdev.c23
-rw-r--r--arch/x86/events/core.c6
-rw-r--r--arch/x86/events/intel/ds.c56
-rw-r--r--arch/x86/include/asm/fb.h21
-rw-r--r--arch/x86/include/asm/perf_event.h3
-rw-r--r--arch/x86/kernel/amd_nb.c2
-rw-r--r--arch/x86/lib/retpoline.S4
-rw-r--r--arch/x86/video/fbdev.c28
-rw-r--r--drivers/auxdisplay/cfag12864bfb.c2
-rw-r--r--drivers/auxdisplay/ht16k33.c2
-rw-r--r--drivers/block/nbd.c4
-rw-r--r--drivers/block/rnbd/rnbd-proto.h2
-rw-r--r--drivers/block/ublk_drv.c2
-rw-r--r--drivers/cxl/core/pci.c1
-rw-r--r--drivers/dma-buf/dma-resv.c2
-rw-r--r--drivers/dma-buf/sw_sync.c2
-rw-r--r--drivers/firewire/net.c21
-rw-r--r--drivers/firmware/sysfb.c2
-rw-r--r--drivers/firmware/sysfb_simplefb.c4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_device.c12
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c8
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c46
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c3
-rw-r--r--drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/nv.c22
-rw-r--r--drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c8
-rw-r--r--drivers/gpu/drm/amd/amdgpu/soc21.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.c65
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn314/dcn314_init.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c5
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.h1
-rw-r--r--drivers/gpu/drm/amd/pm/amdgpu_dpm.c25
-rw-r--r--drivers/gpu/drm/arm/hdlcd_drv.c2
-rw-r--r--drivers/gpu/drm/armada/Makefile3
-rw-r--r--drivers/gpu/drm/armada/armada_drm.h10
-rw-r--r--drivers/gpu/drm/armada/armada_drv.c14
-rw-r--r--drivers/gpu/drm/armada/armada_fb.c1
-rw-r--r--drivers/gpu/drm/armada/armada_fbdev.c119
-rw-r--r--drivers/gpu/drm/ast/ast_main.c9
-rw-r--r--drivers/gpu/drm/bridge/analogix/anx7625.c129
-rw-r--r--drivers/gpu/drm/bridge/fsl-ldb.c14
-rw-r--r--drivers/gpu/drm/bridge/ite-it6505.c3
-rw-r--r--drivers/gpu/drm/bridge/lontium-lt9211.c4
-rw-r--r--drivers/gpu/drm/bridge/lontium-lt9611.c4
-rw-r--r--drivers/gpu/drm/bridge/samsung-dsim.c28
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-hdmi.c2
-rw-r--r--drivers/gpu/drm/bridge/tc358767.c4
-rw-r--r--drivers/gpu/drm/bridge/tc358768.c97
-rw-r--r--drivers/gpu/drm/bridge/ti-sn65dsi83.c1
-rw-r--r--drivers/gpu/drm/bridge/ti-sn65dsi86.c19
-rw-r--r--drivers/gpu/drm/drm_aperture.c11
-rw-r--r--drivers/gpu/drm/drm_atomic_helper.c13
-rw-r--r--drivers/gpu/drm/drm_drv.c4
-rw-r--r--drivers/gpu/drm/drm_fb_helper.c190
-rw-r--r--drivers/gpu/drm/drm_gem_framebuffer_helper.c9
-rw-r--r--drivers/gpu/drm/drm_gem_vram_helper.c6
-rw-r--r--drivers/gpu/drm/drm_mipi_dsi.c2
-rw-r--r--drivers/gpu/drm/drm_sysfs.c51
-rw-r--r--drivers/gpu/drm/gma500/fbdev.c2
-rw-r--r--drivers/gpu/drm/gma500/psb_drv.c43
-rw-r--r--drivers/gpu/drm/hyperv/hyperv_drm_drv.c1
-rw-r--r--drivers/gpu/drm/i915/Makefile6
-rw-r--r--drivers/gpu/drm/i915/display/intel_dpt.c14
-rw-r--r--drivers/gpu/drm/i915/display/intel_fb.c9
-rw-r--r--drivers/gpu/drm/i915/display/intel_fbdev.c38
-rw-r--r--drivers/gpu/drm/i915/display/intel_plane_initial.c4
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_domain.c61
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c15
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_mman.c148
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_mman.h2
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_object.c60
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_object.h10
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_object_types.h68
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_pages.c5
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_region.h4
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_shmem.c9
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_shrinker.c2
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_stolen.c12
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_ttm.h3
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c13
-rw-r--r--drivers/gpu/drm/i915/gem/selftests/huge_pages.c108
-rw-r--r--drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c18
-rw-r--r--drivers/gpu/drm/i915/gem/selftests/i915_gem_migrate.c2
-rw-r--r--drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c2
-rw-r--r--drivers/gpu/drm/i915/gt/gen6_ppgtt.c10
-rw-r--r--drivers/gpu/drm/i915/gt/gen8_ppgtt.c84
-rw-r--r--drivers/gpu/drm/i915/gt/gen8_ppgtt.h3
-rw-r--r--drivers/gpu/drm/i915/gt/intel_context.c5
-rw-r--r--drivers/gpu/drm/i915/gt/intel_context.h8
-rw-r--r--drivers/gpu/drm/i915/gt/intel_context_types.h2
-rw-r--r--drivers/gpu/drm/i915/gt/intel_engine_cs.c2
-rw-r--r--drivers/gpu/drm/i915/gt/intel_engine_types.h1
-rw-r--r--drivers/gpu/drm/i915/gt/intel_engine_user.c2
-rw-r--r--drivers/gpu/drm/i915/gt/intel_ggtt.c84
-rw-r--r--drivers/gpu/drm/i915/gt/intel_gt_irq.c25
-rw-r--r--drivers/gpu/drm/i915/gt/intel_gt_pm.c4
-rw-r--r--drivers/gpu/drm/i915/gt/intel_gt_pm_debugfs.c5
-rw-r--r--drivers/gpu/drm/i915/gt/intel_gt_regs.h14
-rw-r--r--drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c35
-rw-r--r--drivers/gpu/drm/i915/gt/intel_gtt.c47
-rw-r--r--drivers/gpu/drm/i915/gt/intel_gtt.h36
-rw-r--r--drivers/gpu/drm/i915/gt/intel_lrc.c4
-rw-r--r--drivers/gpu/drm/i915/gt/intel_migrate.c51
-rw-r--r--drivers/gpu/drm/i915/gt/intel_migrate.h13
-rw-r--r--drivers/gpu/drm/i915/gt/intel_mocs.c70
-rw-r--r--drivers/gpu/drm/i915/gt/intel_ppgtt.c4
-rw-r--r--drivers/gpu/drm/i915/gt/intel_rc6.c167
-rw-r--r--drivers/gpu/drm/i915/gt/intel_workarounds.c56
-rw-r--r--drivers/gpu/drm/i915/gt/selftest_engine_pm.c3
-rw-r--r--drivers/gpu/drm/i915/gt/selftest_migrate.c47
-rw-r--r--drivers/gpu/drm/i915/gt/selftest_mocs.c3
-rw-r--r--drivers/gpu/drm/i915/gt/selftest_reset.c8
-rw-r--r--drivers/gpu/drm/i915/gt/selftest_slpc.c42
-rw-r--r--drivers/gpu/drm/i915/gt/selftest_timeline.c2
-rw-r--r--drivers/gpu/drm/i915/gt/selftest_tlb.c4
-rw-r--r--drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h1
-rw-r--r--drivers/gpu/drm/i915/gt/uc/guc_capture_fwif.h20
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c23
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.h1
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c424
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.h18
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c76
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.h17
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_heci_cmd_submit.c102
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_heci_cmd_submit.h27
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_guc.c7
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_guc.h1
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c36
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c269
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_guc_capture.h3
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c59
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_guc_ct.h6
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c12
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h11
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c40
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.h1
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_guc_slpc_types.h1
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c75
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_uc.c16
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_uc.h1
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c238
-rw-r--r--drivers/gpu/drm/i915/gvt/aperture_gm.c2
-rw-r--r--drivers/gpu/drm/i915/i915_active.h14
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c53
-rw-r--r--drivers/gpu/drm/i915/i915_drm_client.c6
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h391
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c27
-rw-r--r--drivers/gpu/drm/i915/i915_getparam.c7
-rw-r--r--drivers/gpu/drm/i915/i915_gpu_error.c153
-rw-r--r--drivers/gpu/drm/i915/i915_gpu_error.h10
-rw-r--r--drivers/gpu/drm/i915/i915_hwmon.c87
-rw-r--r--drivers/gpu/drm/i915/i915_hwmon.h7
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c17
-rw-r--r--drivers/gpu/drm/i915/i915_pci.c80
-rw-r--r--drivers/gpu/drm/i915/i915_perf.c1
-rw-r--r--drivers/gpu/drm/i915/i915_perf_oa_regs.h4
-rw-r--r--drivers/gpu/drm/i915/i915_pmu.c290
-rw-r--r--drivers/gpu/drm/i915/i915_pmu.h28
-rw-r--r--drivers/gpu/drm/i915/i915_request.h52
-rw-r--r--drivers/gpu/drm/i915/i915_scatterlist.h9
-rw-r--r--drivers/gpu/drm/i915/i915_utils.h2
-rw-r--r--drivers/gpu/drm/i915/i915_vma.c16
-rw-r--r--drivers/gpu/drm/i915/i915_vma.h4
-rw-r--r--drivers/gpu/drm/i915/i915_vma_resource.h46
-rw-r--r--drivers/gpu/drm/i915/i915_vma_types.h2
-rw-r--r--drivers/gpu/drm/i915/intel_device_info.h5
-rw-r--r--drivers/gpu/drm/i915/pxp/intel_pxp.c102
-rw-r--r--drivers/gpu/drm/i915/pxp/intel_pxp.h2
-rw-r--r--drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_43.h24
-rw-r--r--drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.c6
-rw-r--r--drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.c444
-rw-r--r--drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.h43
-rw-r--r--drivers/gpu/drm/i915/pxp/intel_pxp_pm.c3
-rw-r--r--drivers/gpu/drm/i915/pxp/intel_pxp_regs.h27
-rw-r--r--drivers/gpu/drm/i915/pxp/intel_pxp_session.c25
-rw-r--r--drivers/gpu/drm/i915/pxp/intel_pxp_tee.c2
-rw-r--r--drivers/gpu/drm/i915/pxp/intel_pxp_types.h24
-rw-r--r--drivers/gpu/drm/i915/selftests/i915_gem.c5
-rw-r--r--drivers/gpu/drm/i915/selftests/i915_gem_evict.c8
-rw-r--r--drivers/gpu/drm/i915/selftests/i915_gem_gtt.c15
-rw-r--r--drivers/gpu/drm/i915/selftests/igt_live_test.c47
-rw-r--r--drivers/gpu/drm/i915/selftests/intel_memory_region.c4
-rw-r--r--drivers/gpu/drm/i915/selftests/mock_gem_device.c9
-rw-r--r--drivers/gpu/drm/i915/selftests/mock_gtt.c8
-rw-r--r--drivers/gpu/drm/imx/lcdc/imx-lcdc.c4
-rw-r--r--drivers/gpu/drm/meson/meson_drv.c2
-rw-r--r--drivers/gpu/drm/meson/meson_venc.c32
-rw-r--r--drivers/gpu/drm/msm/msm_drv.c2
-rw-r--r--drivers/gpu/drm/msm/msm_fbdev.c6
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/disp.c1
-rw-r--r--drivers/gpu/drm/nouveau/include/nvif/if0012.h4
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_debugfs.c19
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_hwmon.c2
-rw-r--r--drivers/gpu/drm/nouveau/nv50_display.h4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/power_budget.c3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga102.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pci/pcie.c7
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/therm/fanpwm.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/therm/fantog.c2
-rw-r--r--drivers/gpu/drm/panel/Kconfig7
-rw-r--r--drivers/gpu/drm/panel/Makefile1
-rw-r--r--drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c404
-rw-r--r--drivers/gpu/drm/panel/panel-novatek-nt36523.c569
-rw-r--r--drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c585
-rw-r--r--drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c43
-rw-r--r--drivers/gpu/drm/panel/panel-simple.c69
-rw-r--r--drivers/gpu/drm/panel/panel-sitronix-st7703.c102
-rw-r--r--drivers/gpu/drm/rockchip/cdn-dp-core.c5
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_drv.c2
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_vop.c8
-rw-r--r--drivers/gpu/drm/scheduler/sched_entity.c53
-rw-r--r--drivers/gpu/drm/scheduler/sched_fence.c4
-rw-r--r--drivers/gpu/drm/scheduler/sched_main.c39
-rw-r--r--drivers/gpu/drm/shmobile/Kconfig4
-rw-r--r--drivers/gpu/drm/shmobile/shmob_drm_crtc.c35
-rw-r--r--drivers/gpu/drm/shmobile/shmob_drm_drv.c3
-rw-r--r--drivers/gpu/drm/shmobile/shmob_drm_kms.c9
-rw-r--r--drivers/gpu/drm/shmobile/shmob_drm_plane.c5
-rw-r--r--drivers/gpu/drm/solomon/ssd130x.h6
-rw-r--r--drivers/gpu/drm/sti/sti_dvo.c2
-rw-r--r--drivers/gpu/drm/sti/sti_hdmi.c11
-rw-r--r--drivers/gpu/drm/sti/sti_hdmi.h2
-rw-r--r--drivers/gpu/drm/stm/drv.c2
-rw-r--r--drivers/gpu/drm/sun4i/Makefile2
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_drv.c2
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_tcon.c65
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_tcon_dclk.c (renamed from drivers/gpu/drm/sun4i/sun4i_dotclock.c)2
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_tcon_dclk.h (renamed from drivers/gpu/drm/sun4i/sun4i_dotclock.h)0
-rw-r--r--drivers/gpu/drm/tegra/drm.c2
-rw-r--r--drivers/gpu/drm/tests/drm_rect_test.c315
-rw-r--r--drivers/gpu/drm/ttm/ttm_device.c2
-rw-r--r--drivers/gpu/drm/tve200/tve200_drv.c4
-rw-r--r--drivers/gpu/drm/udl/udl_main.c2
-rw-r--r--drivers/gpu/drm/vc4/tests/vc4_mock.h3
-rw-r--r--drivers/gpu/drm/vc4/tests/vc4_mock_output.c4
-rw-r--r--drivers/gpu/drm/vc4/vc4_dpi.c7
-rw-r--r--drivers/gpu/drm/vc4/vc4_drv.c2
-rw-r--r--drivers/gpu/drm/vc4/vc4_drv.h65
-rw-r--r--drivers/gpu/drm/vc4/vc4_dsi.c17
-rw-r--r--drivers/gpu/drm/vc4/vc4_hdmi.c336
-rw-r--r--drivers/gpu/drm/vc4/vc4_hdmi.h25
-rw-r--r--drivers/gpu/drm/vc4/vc4_kms.c16
-rw-r--r--drivers/gpu/drm/vc4/vc4_plane.c3
-rw-r--r--drivers/gpu/drm/vc4/vc4_txp.c12
-rw-r--r--drivers/gpu/drm/vc4/vc4_vec.c14
-rw-r--r--drivers/gpu/drm/vkms/vkms_composer.c38
-rw-r--r--drivers/gpu/drm/vkms/vkms_crtc.c5
-rw-r--r--drivers/gpu/drm/vkms/vkms_drv.c6
-rw-r--r--drivers/gpu/drm/vkms/vkms_drv.h6
-rw-r--r--drivers/gpu/drm/vkms/vkms_formats.c145
-rw-r--r--drivers/gpu/drm/vkms/vkms_formats.h2
-rw-r--r--drivers/gpu/drm/vkms/vkms_plane.c50
-rw-r--r--drivers/gpu/ipu-v3/ipu-prv.h1
-rw-r--r--drivers/hid/hid-picolcd_fb.c4
-rw-r--r--drivers/hwmon/k10temp.c1
-rw-r--r--drivers/media/pci/ivtv/ivtvfb.c4
-rw-r--r--drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c3
-rw-r--r--drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c6
-rw-r--r--drivers/media/platform/nxp/imx8-isi/imx8-isi-hw.c41
-rw-r--r--drivers/media/platform/renesas/rcar-vin/rcar-dma.c21
-rw-r--r--drivers/misc/mei/Kconfig2
-rw-r--r--drivers/misc/mei/Makefile1
-rw-r--r--drivers/misc/mei/gsc_proxy/Kconfig14
-rw-r--r--drivers/misc/mei/gsc_proxy/Makefile7
-rw-r--r--drivers/misc/mei/gsc_proxy/mei_gsc_proxy.c208
-rw-r--r--drivers/net/bonding/bond_netlink.c7
-rw-r--r--drivers/net/bonding/bond_options.c8
-rw-r--r--drivers/net/ethernet/google/gve/gve_main.c13
-rw-r--r--drivers/net/ethernet/mediatek/mtk_wed.c2
-rw-r--r--drivers/net/ethernet/mscc/vsc7514_regs.c18
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac4.h1
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c5
-rw-r--r--drivers/net/ipvlan/ipvlan_core.c6
-rw-r--r--drivers/net/mdio/mdio-mvusb.c11
-rw-r--r--drivers/net/pcs/pcs-xpcs.c2
-rw-r--r--drivers/net/phy/bcm-phy-lib.h5
-rw-r--r--drivers/net/phy/bcm7xxx.c2
-rw-r--r--drivers/net/tap.c4
-rw-r--r--drivers/platform/mellanox/mlxbf-tmfifo.c11
-rw-r--r--drivers/platform/x86/hp/hp-wmi.c1
-rw-r--r--drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c6
-rw-r--r--drivers/platform/x86/intel_scu_pcidrv.c1
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c24
-rw-r--r--drivers/platform/x86/touchscreen_dmi.c41
-rw-r--r--drivers/staging/sm750fb/sm750.c2
-rw-r--r--drivers/ufs/core/ufshcd.c10
-rw-r--r--drivers/video/Kconfig7
-rw-r--r--drivers/video/Makefile1
-rw-r--r--drivers/video/aperture.c70
-rw-r--r--drivers/video/console/Kconfig1
-rw-r--r--drivers/video/console/Makefile4
-rw-r--r--drivers/video/console/sticon.c6
-rw-r--r--drivers/video/fbdev/68328fb.c12
-rw-r--r--drivers/video/fbdev/Kconfig3
-rw-r--r--drivers/video/fbdev/arcfb.c27
-rw-r--r--drivers/video/fbdev/atmel_lcdfb.c2
-rw-r--r--drivers/video/fbdev/aty/atyfb.h2
-rw-r--r--drivers/video/fbdev/aty/mach64_cursor.c2
-rw-r--r--drivers/video/fbdev/au1200fb.c2
-rw-r--r--drivers/video/fbdev/broadsheetfb.c16
-rw-r--r--drivers/video/fbdev/cg14.c2
-rw-r--r--drivers/video/fbdev/chipsfb.c2
-rw-r--r--drivers/video/fbdev/cobalt_lcdfb.c6
-rw-r--r--drivers/video/fbdev/controlfb.c34
-rw-r--r--drivers/video/fbdev/core/Makefile2
-rw-r--r--drivers/video/fbdev/core/fb_io_fops.c133
-rw-r--r--drivers/video/fbdev/core/fb_sys_fops.c36
-rw-r--r--drivers/video/fbdev/core/fbcon.c1
-rw-r--r--drivers/video/fbdev/core/fbmem.c113
-rw-r--r--drivers/video/fbdev/core/modedb.c5
-rw-r--r--drivers/video/fbdev/g364fb.c6
-rw-r--r--drivers/video/fbdev/hecubafb.c12
-rw-r--r--drivers/video/fbdev/hgafb.c36
-rw-r--r--drivers/video/fbdev/hitfb.c122
-rw-r--r--drivers/video/fbdev/hpfb.c8
-rw-r--r--drivers/video/fbdev/hyperv_fb.c2
-rw-r--r--drivers/video/fbdev/imsttfb.c15
-rw-r--r--drivers/video/fbdev/kyro/fbdev.c2
-rw-r--r--drivers/video/fbdev/macfb.c10
-rw-r--r--drivers/video/fbdev/matrox/matroxfb_accel.c6
-rw-r--r--drivers/video/fbdev/matrox/matroxfb_base.h4
-rw-r--r--drivers/video/fbdev/maxinefb.c2
-rw-r--r--drivers/video/fbdev/metronomefb.c16
-rw-r--r--drivers/video/fbdev/p9100.c4
-rw-r--r--drivers/video/fbdev/platinumfb.c30
-rw-r--r--drivers/video/fbdev/ps3fb.c4
-rw-r--r--drivers/video/fbdev/pvr2fb.c5
-rw-r--r--drivers/video/fbdev/sa1100fb.c32
-rw-r--r--drivers/video/fbdev/sm712fb.c10
-rw-r--r--drivers/video/fbdev/smscufx.c14
-rw-r--r--drivers/video/fbdev/ssd1307fb.c3
-rw-r--r--drivers/video/fbdev/sstfb.c2
-rw-r--r--drivers/video/fbdev/stifb.c163
-rw-r--r--drivers/video/fbdev/tdfxfb.c2
-rw-r--r--drivers/video/fbdev/udlfb.c12
-rw-r--r--drivers/video/fbdev/valkyriefb.c14
-rw-r--r--drivers/video/fbdev/vfb.c12
-rw-r--r--drivers/video/fbdev/wmt_ge_rops.c2
-rw-r--r--drivers/video/fbdev/xen-fbfront.c2
-rw-r--r--drivers/video/sticore.c (renamed from drivers/video/console/sticore.c)123
-rw-r--r--fs/btrfs/backref.c19
-rw-r--r--fs/btrfs/backref.h6
-rw-r--r--fs/btrfs/block-rsv.c3
-rw-r--r--fs/btrfs/ctree.c38
-rw-r--r--fs/btrfs/disk-io.c25
-rw-r--r--fs/btrfs/file-item.c5
-rw-r--r--fs/btrfs/free-space-cache.c7
-rw-r--r--fs/btrfs/free-space-tree.c50
-rw-r--r--fs/btrfs/free-space-tree.h3
-rw-r--r--fs/btrfs/inode.c3
-rw-r--r--fs/btrfs/ioctl.c4
-rw-r--r--fs/btrfs/print-tree.c6
-rw-r--r--fs/btrfs/relocation.c2
-rw-r--r--fs/btrfs/super.c6
-rw-r--r--fs/btrfs/volumes.c1
-rw-r--r--fs/btrfs/zoned.c17
-rw-r--r--fs/cifs/cifsfs.c18
-rw-r--r--fs/cifs/connect.c7
-rw-r--r--fs/cifs/smb2ops.c2
-rw-r--r--fs/cifs/smb2pdu.c3
-rw-r--r--fs/ext4/balloc.c43
-rw-r--r--fs/ext4/ext4.h39
-rw-r--r--fs/ext4/extents_status.c30
-rw-r--r--fs/ext4/hash.c6
-rw-r--r--fs/ext4/ialloc.c12
-rw-r--r--fs/ext4/inline.c17
-rw-r--r--fs/ext4/inode.c20
-rw-r--r--fs/ext4/mballoc.c70
-rw-r--r--fs/ext4/migrate.c11
-rw-r--r--fs/ext4/mmp.c30
-rw-r--r--fs/ext4/namei.c53
-rw-r--r--fs/ext4/super.c37
-rw-r--r--fs/ext4/xattr.c5
-rw-r--r--fs/gfs2/super.c8
-rw-r--r--fs/nfs/dir.c2
-rw-r--r--fs/notify/inotify/inotify_fsnotify.c11
-rw-r--r--fs/pipe.c6
-rw-r--r--fs/xfs/libxfs/xfs_ag.c19
-rw-r--r--fs/xfs/libxfs/xfs_bmap.c5
-rw-r--r--fs/xfs/scrub/bmap.c4
-rw-r--r--fs/xfs/scrub/common.c26
-rw-r--r--fs/xfs/scrub/common.h2
-rw-r--r--fs/xfs/scrub/fscounters.c13
-rw-r--r--fs/xfs/scrub/scrub.c2
-rw-r--r--fs/xfs/scrub/scrub.h1
-rw-r--r--fs/xfs/scrub/trace.h1
-rw-r--r--fs/xfs/xfs_bmap_util.c4
-rw-r--r--fs/xfs/xfs_icache.c40
-rw-r--r--fs/xfs/xfs_iomap.c5
-rw-r--r--fs/xfs/xfs_mount.h3
-rw-r--r--fs/xfs/xfs_super.c3
-rw-r--r--include/asm-generic/fb.h126
-rw-r--r--include/drm/bridge/samsung-dsim.h2
-rw-r--r--include/drm/display/drm_dp.h8
-rw-r--r--include/drm/display/drm_dp_helper.h5
-rw-r--r--include/drm/drm_aperture.h7
-rw-r--r--include/drm/drm_connector.h5
-rw-r--r--include/drm/drm_fixed.h6
-rw-r--r--include/drm/gpu_scheduler.h7
-rw-r--r--include/drm/i915_component.h3
-rw-r--r--include/drm/i915_gsc_proxy_mei_interface.h53
-rw-r--r--include/drm/ttm/ttm_device.h4
-rw-r--r--include/linux/aperture.h16
-rw-r--r--include/linux/dim.h3
-rw-r--r--include/linux/fb.h65
-rw-r--r--include/linux/if_vlan.h17
-rw-r--r--include/linux/io_uring.h10
-rw-r--r--include/linux/pci_ids.h1
-rw-r--r--include/net/bonding.h2
-rw-r--r--include/net/sock.h2
-rw-r--r--include/uapi/drm/drm_mode.h5
-rw-r--r--include/uapi/drm/i915_drm.h51
-rw-r--r--include/video/sticore.h (renamed from drivers/video/fbdev/sticore.h)16
-rw-r--r--kernel/events/core.c14
-rw-r--r--kernel/locking/rwsem.c8
-rw-r--r--kernel/sched/core.c4
-rw-r--r--kernel/time/tick-broadcast.c120
-rw-r--r--lib/dim/dim.c5
-rw-r--r--lib/dim/net_dim.c3
-rw-r--r--lib/dim/rdma_dim.c3
-rw-r--r--net/bridge/br_forward.c2
-rw-r--r--net/core/datagram.c15
-rw-r--r--net/core/dev.c2
-rw-r--r--net/core/skbuff.c4
-rw-r--r--net/core/stream.c12
-rw-r--r--net/ipv4/af_inet.c2
-rw-r--r--net/ipv4/tcp.c14
-rw-r--r--net/ipv4/tcp_bpf.c2
-rw-r--r--net/ipv4/tcp_input.c4
-rw-r--r--net/llc/af_llc.c8
-rw-r--r--net/netfilter/core.c6
-rw-r--r--net/netfilter/nf_conntrack_standalone.c3
-rw-r--r--net/netfilter/nft_chain_filter.c9
-rw-r--r--net/netlink/af_netlink.c8
-rw-r--r--net/packet/af_packet.c6
-rw-r--r--net/smc/smc_close.c4
-rw-r--r--net/smc/smc_rx.c4
-rw-r--r--net/smc/smc_tx.c4
-rw-r--r--net/socket.c2
-rw-r--r--net/tipc/socket.c4
-rw-r--r--net/tls/tls_main.c3
-rw-r--r--net/unix/af_unix.c22
-rw-r--r--tools/testing/cxl/test/mock.c2
-rwxr-xr-xtools/testing/selftests/drivers/net/bonding/bond_options.sh50
-rw-r--r--tools/testing/selftests/drivers/net/bonding/bond_topo_3d1c.sh2
-rwxr-xr-xtools/testing/selftests/net/forwarding/lib.sh3
-rwxr-xr-xtools/testing/selftests/netfilter/nft_flowtable.sh145
497 files changed, 11271 insertions, 4715 deletions
diff --git a/Documentation/block/index.rst b/Documentation/block/index.rst
index 102953166429..9fea696f9daa 100644
--- a/Documentation/block/index.rst
+++ b/Documentation/block/index.rst
@@ -18,7 +18,6 @@ Block
kyber-iosched
null_blk
pr
- request
stat
switching-sched
writeback_cache_control
diff --git a/Documentation/block/request.rst b/Documentation/block/request.rst
deleted file mode 100644
index 747021e1ffdb..000000000000
--- a/Documentation/block/request.rst
+++ /dev/null
@@ -1,99 +0,0 @@
-============================
-struct request documentation
-============================
-
-Jens Axboe <jens.axboe@oracle.com> 27/05/02
-
-
-.. FIXME:
- No idea about what does mean - seems just some noise, so comment it
-
- 1.0
- Index
-
- 2.0 Struct request members classification
-
- 2.1 struct request members explanation
-
- 3.0
-
-
- 2.0
-
-
-
-Short explanation of request members
-====================================
-
-Classification flags:
-
- = ====================
- D driver member
- B block layer member
- I I/O scheduler member
- = ====================
-
-Unless an entry contains a D classification, a device driver must not access
-this member. Some members may contain D classifications, but should only be
-access through certain macros or functions (eg ->flags).
-
-<linux/blkdev.h>
-
-=============================== ======= =======================================
-Member Flag Comment
-=============================== ======= =======================================
-struct list_head queuelist BI Organization on various internal
- queues
-
-``void *elevator_private`` I I/O scheduler private data
-
-unsigned char cmd[16] D Driver can use this for setting up
- a cdb before execution, see
- blk_queue_prep_rq
-
-unsigned long flags DBI Contains info about data direction,
- request type, etc.
-
-int rq_status D Request status bits
-
-kdev_t rq_dev DBI Target device
-
-int errors DB Error counts
-
-sector_t sector DBI Target location
-
-unsigned long hard_nr_sectors B Used to keep sector sane
-
-unsigned long nr_sectors DBI Total number of sectors in request
-
-unsigned long hard_nr_sectors B Used to keep nr_sectors sane
-
-unsigned short nr_phys_segments DB Number of physical scatter gather
- segments in a request
-
-unsigned short nr_hw_segments DB Number of hardware scatter gather
- segments in a request
-
-unsigned int current_nr_sectors DB Number of sectors in first segment
- of request
-
-unsigned int hard_cur_sectors B Used to keep current_nr_sectors sane
-
-int tag DB TCQ tag, if assigned
-
-``void *special`` D Free to be used by driver
-
-``char *buffer`` D Map of first segment, also see
- section on bouncing SECTION
-
-``struct completion *waiting`` D Can be used by driver to get signalled
- on request completion
-
-``struct bio *bio`` DBI First bio in request
-
-``struct bio *biotail`` DBI Last bio in request
-
-``struct request_queue *q`` DB Request queue this request belongs to
-
-``struct request_list *rl`` B Request list this request came from
-=============================== ======= =======================================
diff --git a/Documentation/devicetree/bindings/display/bridge/fsl,ldb.yaml b/Documentation/devicetree/bindings/display/bridge/fsl,ldb.yaml
index 6e0e3ba9b49e..07388bf2b90d 100644
--- a/Documentation/devicetree/bindings/display/bridge/fsl,ldb.yaml
+++ b/Documentation/devicetree/bindings/display/bridge/fsl,ldb.yaml
@@ -17,6 +17,7 @@ description: |
properties:
compatible:
enum:
+ - fsl,imx6sx-ldb
- fsl,imx8mp-ldb
- fsl,imx93-ldb
@@ -64,7 +65,9 @@ allOf:
properties:
compatible:
contains:
- const: fsl,imx93-ldb
+ enum:
+ - fsl,imx6sx-ldb
+ - fsl,imx93-ldb
then:
properties:
ports:
diff --git a/Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml b/Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml
index e841659e20cd..9f61ebdfefa8 100644
--- a/Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml
+++ b/Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml
@@ -105,6 +105,29 @@ properties:
DSI output port node to the panel or the next bridge
in the chain.
+ properties:
+ endpoint:
+ $ref: /schemas/media/video-interfaces.yaml#
+ unevaluatedProperties: false
+
+ properties:
+ data-lanes:
+ minItems: 1
+ maxItems: 4
+ uniqueItems: true
+ items:
+ enum: [ 1, 2, 3, 4 ]
+
+ lane-polarities:
+ minItems: 1
+ maxItems: 5
+ description:
+ The Samsung MIPI DSI IP requires that all the data lanes have
+ the same polarity.
+
+ dependencies:
+ lane-polarities: [data-lanes]
+
required:
- clock-names
- clocks
diff --git a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358767.yaml b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358767.yaml
index e1494b5007cb..0521261b04a9 100644
--- a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358767.yaml
+++ b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358767.yaml
@@ -4,16 +4,24 @@
$id: http://devicetree.org/schemas/display/bridge/toshiba,tc358767.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
-title: Toshiba TC358767 eDP bridge
+title: Toshiba TC358767/TC358867/TC9595 DSI/DPI/eDP bridge
maintainers:
- Andrey Gusakov <andrey.gusakov@cogentembedded.com>
-description: The TC358767 is bridge device which converts DSI/DPI to eDP/DP
+description: |
+ The TC358767/TC358867/TC9595 is bridge device which
+ converts DSI/DPI to eDP/DP .
properties:
compatible:
- const: toshiba,tc358767
+ oneOf:
+ - items:
+ - enum:
+ - toshiba,tc358867
+ - toshiba,tc9595
+ - const: toshiba,tc358767
+ - const: toshiba,tc358767
reg:
enum:
diff --git a/Documentation/devicetree/bindings/display/panel/novatek,nt36523.yaml b/Documentation/devicetree/bindings/display/panel/novatek,nt36523.yaml
index 0039561ef04c..5f7e4c486094 100644
--- a/Documentation/devicetree/bindings/display/panel/novatek,nt36523.yaml
+++ b/Documentation/devicetree/bindings/display/panel/novatek,nt36523.yaml
@@ -19,11 +19,16 @@ allOf:
properties:
compatible:
- items:
- - enum:
- - xiaomi,elish-boe-nt36523
- - xiaomi,elish-csot-nt36523
- - const: novatek,nt36523
+ oneOf:
+ - items:
+ - enum:
+ - xiaomi,elish-boe-nt36523
+ - xiaomi,elish-csot-nt36523
+ - const: novatek,nt36523
+ - items:
+ - enum:
+ - lenovo,j606f-boe-nt36523w
+ - const: novatek,nt36523w
reset-gpios:
maxItems: 1
@@ -34,6 +39,7 @@ properties:
reg: true
ports: true
+ rotation: true
backlight: true
required:
diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
index 01560fe226dd..733e47da36e8 100644
--- a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
+++ b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
@@ -77,6 +77,8 @@ properties:
- auo,t215hvn01
# Shanghai AVIC Optoelectronics 7" 1024x600 color TFT-LCD panel
- avic,tm070ddh03
+ # BOE EV121WXM-N10-1850 12.1" WXGA (1280x800) TFT LCD panel
+ - boe,ev121wxm-n10-1850
# BOE HV070WSA-100 7.01" WSVGA TFT LCD panel
- boe,hv070wsa-100
# BOE OPTOELECTRONICS TECHNOLOGY 10.1" WXGA TFT LCD panel
@@ -174,6 +176,8 @@ properties:
- innolux,at043tn24
# Innolux AT070TN92 7.0" WQVGA TFT LCD panel
- innolux,at070tn92
+ # Innolux G070ACE-L01 7" WVGA (800x480) TFT LCD panel
+ - innolux,g070ace-l01
# Innolux G070Y2-L01 7" WVGA (800x480) TFT LCD panel
- innolux,g070y2-l01
# Innolux G070Y2-T02 7" WVGA (800x480) TFT LCD TTL panel
diff --git a/Documentation/devicetree/bindings/display/panel/rocktech,jh057n00900.yaml b/Documentation/devicetree/bindings/display/panel/rocktech,jh057n00900.yaml
index 09b5eb7542f8..150e81090af2 100644
--- a/Documentation/devicetree/bindings/display/panel/rocktech,jh057n00900.yaml
+++ b/Documentation/devicetree/bindings/display/panel/rocktech,jh057n00900.yaml
@@ -20,6 +20,8 @@ allOf:
properties:
compatible:
enum:
+ # Anberic RG353V-V2 5.0" 640x480 TFT LCD panel
+ - anbernic,rg353v-panel-v2
# Rocktech JH057N00900 5.5" 720x1440 TFT LCD panel
- rocktech,jh057n00900
# Xingbangda XBD599 5.99" 720x1440 TFT LCD panel
diff --git a/Documentation/devicetree/bindings/display/panel/samsung,s6d7aa0.yaml b/Documentation/devicetree/bindings/display/panel/samsung,s6d7aa0.yaml
new file mode 100644
index 000000000000..45a236d2cc70
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/samsung,s6d7aa0.yaml
@@ -0,0 +1,70 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/samsung,s6d7aa0.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung S6D7AA0 MIPI-DSI LCD panel controller
+
+maintainers:
+ - Artur Weber <aweber.kernel@gmail.com>
+
+allOf:
+ - $ref: panel-common.yaml#
+
+properties:
+ compatible:
+ items:
+ - enum:
+ # 1280x800 LSL080AL02 panel
+ - samsung,lsl080al02
+ # 1024x768 LSL080AL03 panel
+ - samsung,lsl080al03
+ # 1024x768 LTL101AT01 panel
+ - samsung,ltl101at01
+ - const: samsung,s6d7aa0
+
+ reg: true
+
+ backlight:
+ description:
+ Backlight to use for the panel. If this property is set on panels
+ that have DSI-based backlight control (LSL080AL03 and LTL101AT01),
+ it overrides the DSI-based backlight.
+
+ reset-gpios:
+ description: Reset GPIO pin, usually GPIO_ACTIVE_LOW.
+
+ power-supply:
+ description:
+ Main power supply for the panel; the exact voltage differs between
+ panels, and is usually somewhere around 3.3-5v.
+
+ vmipi-supply:
+ description: VMIPI supply, usually 1.8v.
+
+required:
+ - compatible
+ - reg
+ - reset-gpios
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+
+ dsi {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ panel@0 {
+ compatible = "samsung,lsl080al02", "samsung,s6d7aa0";
+ reg = <0>;
+ power-supply = <&display_3v3_supply>;
+ reset-gpios = <&gpf0 4 GPIO_ACTIVE_LOW>;
+ backlight = <&backlight>;
+ };
+ };
+
+...
diff --git a/Documentation/devicetree/bindings/media/i2c/ovti,ov2685.yaml b/Documentation/devicetree/bindings/media/i2c/ovti,ov2685.yaml
index 8b389314c352..e2ffe0a9c26b 100644
--- a/Documentation/devicetree/bindings/media/i2c/ovti,ov2685.yaml
+++ b/Documentation/devicetree/bindings/media/i2c/ovti,ov2685.yaml
@@ -49,6 +49,7 @@ properties:
properties:
data-lanes:
+ minItems: 1
maxItems: 2
required:
diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-common.yaml b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-common.yaml
index 9bff8ecb653c..d91b639ae7ae 100644
--- a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-common.yaml
+++ b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-common.yaml
@@ -17,20 +17,11 @@ description:
properties:
clocks:
minItems: 3
- items:
- - description: PCIe bridge clock.
- - description: PCIe bus clock.
- - description: PCIe PHY clock.
- - description: Additional required clock entry for imx6sx-pcie,
- imx6sx-pcie-ep, imx8mq-pcie, imx8mq-pcie-ep.
+ maxItems: 4
clock-names:
minItems: 3
- items:
- - const: pcie
- - const: pcie_bus
- - enum: [ pcie_phy, pcie_aux ]
- - enum: [ pcie_inbound_axi, pcie_aux ]
+ maxItems: 4
num-lanes:
const: 1
diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-ep.yaml b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-ep.yaml
index f4a328ec1daa..ee155ed5f181 100644
--- a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-ep.yaml
+++ b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-ep.yaml
@@ -31,6 +31,19 @@ properties:
- const: dbi
- const: addr_space
+ clocks:
+ minItems: 3
+ items:
+ - description: PCIe bridge clock.
+ - description: PCIe bus clock.
+ - description: PCIe PHY clock.
+ - description: Additional required clock entry for imx6sx-pcie,
+ imx6sx-pcie-ep, imx8mq-pcie, imx8mq-pcie-ep.
+
+ clock-names:
+ minItems: 3
+ maxItems: 4
+
interrupts:
items:
- description: builtin eDMA interrupter.
@@ -49,6 +62,31 @@ required:
allOf:
- $ref: /schemas/pci/snps,dw-pcie-ep.yaml#
- $ref: /schemas/pci/fsl,imx6q-pcie-common.yaml#
+ - if:
+ properties:
+ compatible:
+ enum:
+ - fsl,imx8mq-pcie-ep
+ then:
+ properties:
+ clocks:
+ minItems: 4
+ clock-names:
+ items:
+ - const: pcie
+ - const: pcie_bus
+ - const: pcie_phy
+ - const: pcie_aux
+ else:
+ properties:
+ clocks:
+ maxItems: 3
+ clock-names:
+ items:
+ - const: pcie
+ - const: pcie_bus
+ - const: pcie_aux
+
unevaluatedProperties: false
diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
index 2443641754d3..81bbb8728f0f 100644
--- a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
+++ b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
@@ -40,6 +40,19 @@ properties:
- const: dbi
- const: config
+ clocks:
+ minItems: 3
+ items:
+ - description: PCIe bridge clock.
+ - description: PCIe bus clock.
+ - description: PCIe PHY clock.
+ - description: Additional required clock entry for imx6sx-pcie,
+ imx6sx-pcie-ep, imx8mq-pcie, imx8mq-pcie-ep.
+
+ clock-names:
+ minItems: 3
+ maxItems: 4
+
interrupts:
items:
- description: builtin MSI controller.
@@ -77,6 +90,70 @@ required:
allOf:
- $ref: /schemas/pci/snps,dw-pcie.yaml#
- $ref: /schemas/pci/fsl,imx6q-pcie-common.yaml#
+ - if:
+ properties:
+ compatible:
+ enum:
+ - fsl,imx6sx-pcie
+ then:
+ properties:
+ clocks:
+ minItems: 4
+ clock-names:
+ items:
+ - const: pcie
+ - const: pcie_bus
+ - const: pcie_phy
+ - const: pcie_inbound_axi
+
+ - if:
+ properties:
+ compatible:
+ enum:
+ - fsl,imx8mq-pcie
+ then:
+ properties:
+ clocks:
+ minItems: 4
+ clock-names:
+ items:
+ - const: pcie
+ - const: pcie_bus
+ - const: pcie_phy
+ - const: pcie_aux
+
+ - if:
+ properties:
+ compatible:
+ enum:
+ - fsl,imx6q-pcie
+ - fsl,imx6qp-pcie
+ - fsl,imx7d-pcie
+ then:
+ properties:
+ clocks:
+ maxItems: 3
+ clock-names:
+ items:
+ - const: pcie
+ - const: pcie_bus
+ - const: pcie_phy
+
+ - if:
+ properties:
+ compatible:
+ enum:
+ - fsl,imx8mm-pcie
+ - fsl,imx8mp-pcie
+ then:
+ properties:
+ clocks:
+ maxItems: 3
+ clock-names:
+ items:
+ - const: pcie
+ - const: pcie_bus
+ - const: pcie_aux
unevaluatedProperties: false
diff --git a/Documentation/gpu/rfc/index.rst b/Documentation/gpu/rfc/index.rst
index 476719771eef..e4f7b005138d 100644
--- a/Documentation/gpu/rfc/index.rst
+++ b/Documentation/gpu/rfc/index.rst
@@ -31,3 +31,7 @@ host such documentation:
.. toctree::
i915_vm_bind.rst
+
+.. toctree::
+
+ xe.rst
diff --git a/Documentation/gpu/rfc/xe.rst b/Documentation/gpu/rfc/xe.rst
new file mode 100644
index 000000000000..2516fe141db6
--- /dev/null
+++ b/Documentation/gpu/rfc/xe.rst
@@ -0,0 +1,235 @@
+==========================
+Xe – Merge Acceptance Plan
+==========================
+Xe is a new driver for Intel GPUs that supports both integrated and
+discrete platforms starting with Tiger Lake (first Intel Xe Architecture).
+
+This document aims to establish a merge plan for the Xe, by writing down clear
+pre-merge goals, in order to avoid unnecessary delays.
+
+Xe – Overview
+=============
+The main motivation of Xe is to have a fresh base to work from that is
+unencumbered by older platforms, whilst also taking the opportunity to
+rearchitect our driver to increase sharing across the drm subsystem, both
+leveraging and allowing us to contribute more towards other shared components
+like TTM and drm/scheduler.
+
+This is also an opportunity to start from the beginning with a clean uAPI that is
+extensible by design and already aligned with the modern userspace needs. For
+this reason, the memory model is solely based on GPU Virtual Address space
+bind/unbind (‘VM_BIND’) of GEM buffer objects (BOs) and execution only supporting
+explicit synchronization. With persistent mapping across the execution, the
+userspace does not need to provide a list of all required mappings during each
+submission.
+
+The new driver leverages a lot from i915. As for display, the intent is to share
+the display code with the i915 driver so that there is maximum reuse there.
+
+As for the power management area, the goal is to have a much-simplified support
+for the system suspend states (S-states), PCI device suspend states (D-states),
+GPU/Render suspend states (R-states) and frequency management. It should leverage
+as much as possible all the existent PCI-subsystem infrastructure (pm and
+runtime_pm) and underlying firmware components such PCODE and GuC for the power
+states and frequency decisions.
+
+Repository:
+
+https://gitlab.freedesktop.org/drm/xe/kernel (branch drm-xe-next)
+
+Xe – Platforms
+==============
+Currently, Xe is already functional and has experimental support for multiple
+platforms starting from Tiger Lake, with initial support in userspace implemented
+in Mesa (for Iris and Anv, our OpenGL and Vulkan drivers), as well as in NEO
+(for OpenCL and Level0).
+
+During a transition period, platforms will be supported by both Xe and i915.
+However, the force_probe mechanism existent in both drivers will allow only one
+official and by-default probe at a given time.
+
+For instance, in order to probe a DG2 which PCI ID is 0x5690 by Xe instead of
+i915, the following set of parameters need to be used:
+
+```
+i915.force_probe=!5690 xe.force_probe=5690
+```
+
+In both drivers, the ‘.require_force_probe’ protection forces the user to use the
+force_probe parameter while the driver is under development. This protection is
+only removed when the support for the platform and the uAPI are stable. Stability
+which needs to be demonstrated by CI results.
+
+In order to avoid user space regressions, i915 will continue to support all the
+current platforms that are already out of this protection. Xe support will be
+forever experimental and dependent on the usage of force_probe for these
+platforms.
+
+When the time comes for Xe, the protection will be lifted on Xe and kept in i915.
+
+Xe driver will be protected with both STAGING Kconfig and force_probe. Changes in
+the uAPI are expected while the driver is behind these protections. STAGING will
+be removed when the driver uAPI gets to a mature state where we can guarantee the
+‘no regression’ rule. Then force_probe will be lifted only for future platforms
+that will be productized with Xe driver, but not with i915.
+
+Xe – Pre-Merge Goals
+====================
+
+Drm_scheduler
+-------------
+Xe primarily uses Firmware based scheduling (GuC FW). However, it will use
+drm_scheduler as the scheduler ‘frontend’ for userspace submission in order to
+resolve syncobj and dma-buf implicit sync dependencies. However, drm_scheduler is
+not yet prepared to handle the 1-to-1 relationship between drm_gpu_scheduler and
+drm_sched_entity.
+
+Deeper changes to drm_scheduler should *not* be required to get Xe accepted, but
+some consensus needs to be reached between Xe and other community drivers that
+could also benefit from this work, for coupling FW based/assisted submission such
+as the ARM’s new Mali GPU driver, and others.
+
+As a key measurable result, the patch series introducing Xe itself shall not
+depend on any other patch touching drm_scheduler itself that was not yet merged
+through drm-misc. This, by itself, already includes the reach of an agreement for
+uniform 1 to 1 relationship implementation / usage across drivers.
+
+GPU VA
+------
+Two main goals of Xe are meeting together here:
+
+1) Have an uAPI that aligns with modern UMD needs.
+
+2) Early upstream engagement.
+
+RedHat engineers working on Nouveau proposed a new DRM feature to handle keeping
+track of GPU virtual address mappings. This is still not merged upstream, but
+this aligns very well with our goals and with our VM_BIND. The engagement with
+upstream and the port of Xe towards GPUVA is already ongoing.
+
+As a key measurable result, Xe needs to be aligned with the GPU VA and working in
+our tree. Missing Nouveau patches should *not* block Xe and any needed GPUVA
+related patch should be independent and present on dri-devel or acked by
+maintainers to go along with the first Xe pull request towards drm-next.
+
+DRM_VM_BIND
+-----------
+Nouveau, and Xe are all implementing ‘VM_BIND’ and new ‘Exec’ uAPIs in order to
+fulfill the needs of the modern uAPI. Xe merge should *not* be blocked on the
+development of a common new drm_infrastructure. However, the Xe team needs to
+engage with the community to explore the options of a common API.
+
+As a key measurable result, the DRM_VM_BIND needs to be documented in this file
+below, or this entire block deleted if the consensus is for independent drivers
+vm_bind ioctls.
+
+Although having a common DRM level IOCTL for VM_BIND is not a requirement to get
+Xe merged, it is mandatory to enforce the overall locking scheme for all major
+structs and list (so vm and vma). So, a consensus is needed, and possibly some
+common helpers. If helpers are needed, they should be also documented in this
+document.
+
+ASYNC VM_BIND
+-------------
+Although having a common DRM level IOCTL for VM_BIND is not a requirement to get
+Xe merged, it is mandatory to have a consensus with other drivers and Mesa.
+It needs to be clear how to handle async VM_BIND and interactions with userspace
+memory fences. Ideally with helper support so people don't get it wrong in all
+possible ways.
+
+As a key measurable result, the benefits of ASYNC VM_BIND and a discussion of
+various flavors, error handling and a sample API should be documented here or in
+a separate document pointed to by this document.
+
+Userptr integration and vm_bind
+-------------------------------
+Different drivers implement different ways of dealing with execution of userptr.
+With multiple drivers currently introducing support to VM_BIND, the goal is to
+aim for a DRM consensus on what’s the best way to have that support. To some
+extent this is already getting addressed itself with the GPUVA where likely the
+userptr will be a GPUVA with a NULL GEM call VM bind directly on the userptr.
+However, there are more aspects around the rules for that and the usage of
+mmu_notifiers, locking and other aspects.
+
+This task here has the goal of introducing a documentation of the basic rules.
+
+The documentation *needs* to first live in this document (API session below) and
+then moved to another more specific document or at Xe level or at DRM level.
+
+Documentation should include:
+
+ * The userptr part of the VM_BIND api.
+
+ * Locking, including the page-faulting case.
+
+ * O(1) complexity under VM_BIND.
+
+Some parts of userptr like mmu_notifiers should become GPUVA or DRM helpers when
+the second driver supporting VM_BIND+userptr appears. Details to be defined when
+the time comes.
+
+Long running compute: minimal data structure/scaffolding
+--------------------------------------------------------
+The generic scheduler code needs to include the handling of endless compute
+contexts, with the minimal scaffolding for preempt-ctx fences (probably on the
+drm_sched_entity) and making sure drm_scheduler can cope with the lack of job
+completion fence.
+
+The goal is to achieve a consensus ahead of Xe initial pull-request, ideally with
+this minimal drm/scheduler work, if needed, merged to drm-misc in a way that any
+drm driver, including Xe, could re-use and add their own individual needs on top
+in a next stage. However, this should not block the initial merge.
+
+This is a non-blocker item since the driver without the support for the long
+running compute enabled is not a showstopper.
+
+Display integration with i915
+-----------------------------
+In order to share the display code with the i915 driver so that there is maximum
+reuse, the i915/display/ code is built twice, once for i915.ko and then for
+xe.ko. Currently, the i915/display code in Xe tree is polluted with many 'ifdefs'
+depending on the build target. The goal is to refactor both Xe and i915/display
+code simultaneously in order to get a clean result before they land upstream, so
+that display can already be part of the initial pull request towards drm-next.
+
+However, display code should not gate the acceptance of Xe in upstream. Xe
+patches will be refactored in a way that display code can be removed, if needed,
+from the first pull request of Xe towards drm-next. The expectation is that when
+both drivers are part of the drm-tip, the introduction of cleaner patches will be
+easier and speed up.
+
+Drm_exec
+--------
+Helper to make dma_resv locking for a big number of buffers is getting removed in
+the drm_exec series proposed in https://patchwork.freedesktop.org/patch/524376/
+If that happens, Xe needs to change and incorporate the changes in the driver.
+The goal is to engage with the Community to understand if the best approach is to
+move that to the drivers that are using it or if we should keep the helpers in
+place waiting for Xe to get merged.
+
+This item ties into the GPUVA, VM_BIND, and even long-running compute support.
+
+As a key measurable result, we need to have a community consensus documented in
+this document and the Xe driver prepared for the changes, if necessary.
+
+Dev_coredump
+------------
+
+Xe needs to align with other drivers on the way that the error states are
+dumped, avoiding a Xe only error_state solution. The goal is to use devcoredump
+infrastructure to report error states, since it produces a standardized way
+by exposing a virtual and temporary /sys/class/devcoredump device.
+
+As the key measurable result, Xe driver needs to provide GPU snapshots captured
+at hang time through devcoredump, but without depending on any core modification
+of devcoredump infrastructure itself.
+
+Later, when we are in-tree, the goal is to collaborate with devcoredump
+infrastructure with overall possible improvements, like multiple file support
+for better organization of the dumps, snapshot support, dmesg extra print,
+and whatever may make sense and help the overall infrastructure.
+
+Xe – uAPI high level overview
+=============================
+
+...Warning: To be done in follow up patches after/when/where the main consensus in various items are individually reached.
diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst
index 1f8a5ebe188e..68bdafa0284f 100644
--- a/Documentation/gpu/todo.rst
+++ b/Documentation/gpu/todo.rst
@@ -276,11 +276,8 @@ Various hold-ups:
- Need to switch to drm_fbdev_generic_setup(), otherwise a lot of the custom fb
setup code can't be deleted.
-- Many drivers wrap drm_gem_fb_create() only to check for valid formats. For
- atomic drivers we could check for valid formats by calling
- drm_plane_check_pixel_format() against all planes, and pass if any plane
- supports the format. For non-atomic that's not possible since like the format
- list for the primary plane is fake and we'd therefor reject valid formats.
+- Need to switch to drm_gem_fb_create(), as now drm_gem_fb_create() checks for
+ valid formats for atomic drivers.
- Many drivers subclass drm_framebuffer, we'd need a embedding compatible
version of the varios drm_gem_fb_create functions. Maybe called
diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst
index 49db221c0f52..ba04ac7c2167 100644
--- a/Documentation/gpu/vkms.rst
+++ b/Documentation/gpu/vkms.rst
@@ -118,14 +118,9 @@ Add Plane Features
There's lots of plane features we could add support for:
-- ARGB format on primary plane: blend the primary plane into background with
- translucent alpha.
-
- Add background color KMS property[Good to get started].
-- Full alpha blending on all planes.
-
-- Rotation, scaling.
+- Scaling.
- Additional buffer formats, especially YUV formats for video like NV12.
Low/high bpp RGB formats would also be interesting.
diff --git a/Documentation/networking/bonding.rst b/Documentation/networking/bonding.rst
index adc4bf4f3c50..28925e19622d 100644
--- a/Documentation/networking/bonding.rst
+++ b/Documentation/networking/bonding.rst
@@ -776,10 +776,11 @@ peer_notif_delay
Specify the delay, in milliseconds, between each peer
notification (gratuitous ARP and unsolicited IPv6 Neighbor
Advertisement) when they are issued after a failover event.
- This delay should be a multiple of the link monitor interval
- (arp_interval or miimon, whichever is active). The default
- value is 0 which means to match the value of the link monitor
- interval.
+ This delay should be a multiple of the MII link monitor interval
+ (miimon).
+
+ The valid range is 0 - 300000. The default value is 0, which means
+ to match the value of the MII link monitor interval.
prio
Slave priority. A higher number means higher priority.
diff --git a/Documentation/networking/index.rst b/Documentation/networking/index.rst
index a164ff074356..5b75c3f7a137 100644
--- a/Documentation/networking/index.rst
+++ b/Documentation/networking/index.rst
@@ -116,8 +116,8 @@ Contents:
udplite
vrf
vxlan
- x25-iface
x25
+ x25-iface
xfrm_device
xfrm_proc
xfrm_sync
diff --git a/Documentation/networking/x25-iface.rst b/Documentation/networking/x25-iface.rst
index f34e9ec64937..285cefcfce87 100644
--- a/Documentation/networking/x25-iface.rst
+++ b/Documentation/networking/x25-iface.rst
@@ -1,8 +1,7 @@
.. SPDX-License-Identifier: GPL-2.0
-============================-
X.25 Device Driver Interface
-============================-
+============================
Version 1.1
diff --git a/MAINTAINERS b/MAINTAINERS
index 7e0b87d5aa2e..b344e1318ac3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -273,8 +273,8 @@ ABI/API
L: linux-api@vger.kernel.org
F: include/linux/syscalls.h
F: kernel/sys_ni.c
-X: include/uapi/
X: arch/*/include/uapi/
+X: include/uapi/
ABIT UGURU 1,2 HARDWARE MONITOR DRIVER
M: Hans de Goede <hdegoede@redhat.com>
@@ -406,12 +406,6 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
F: drivers/acpi/arm64
-ACPI SERIAL MULTI INSTANTIATE DRIVER
-M: Hans de Goede <hdegoede@redhat.com>
-L: platform-driver-x86@vger.kernel.org
-S: Maintained
-F: drivers/platform/x86/serial-multi-instantiate.c
-
ACPI PCC(Platform Communication Channel) MAILBOX DRIVER
M: Sudeep Holla <sudeep.holla@arm.com>
L: linux-acpi@vger.kernel.org
@@ -430,6 +424,12 @@ B: https://bugzilla.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
F: drivers/acpi/pmic/
+ACPI SERIAL MULTI INSTANTIATE DRIVER
+M: Hans de Goede <hdegoede@redhat.com>
+L: platform-driver-x86@vger.kernel.org
+S: Maintained
+F: drivers/platform/x86/serial-multi-instantiate.c
+
ACPI THERMAL DRIVER
M: Rafael J. Wysocki <rafael@kernel.org>
R: Zhang Rui <rui.zhang@intel.com>
@@ -823,6 +823,13 @@ L: linux-crypto@vger.kernel.org
S: Maintained
F: drivers/crypto/allwinner/
+ALLWINNER DMIC DRIVERS
+M: Ban Tao <fengzheng923@gmail.com>
+L: alsa-devel@alsa-project.org (moderated for non-subscribers)
+S: Maintained
+F: Documentation/devicetree/bindings/sound/allwinner,sun50i-h6-dmic.yaml
+F: sound/soc/sunxi/sun50i-dmic.c
+
ALLWINNER HARDWARE SPINLOCK SUPPORT
M: Wilken Gottwalt <wilken.gottwalt@posteo.net>
S: Maintained
@@ -844,13 +851,6 @@ L: linux-media@vger.kernel.org
S: Maintained
F: drivers/staging/media/sunxi/cedrus/
-ALLWINNER DMIC DRIVERS
-M: Ban Tao <fengzheng923@gmail.com>
-L: alsa-devel@alsa-project.org (moderated for non-subscribers)
-S: Maintained
-F: Documentation/devicetree/bindings/sound/allwinner,sun50i-h6-dmic.yaml
-F: sound/soc/sunxi/sun50i-dmic.c
-
ALPHA PORT
M: Richard Henderson <richard.henderson@linaro.org>
M: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
@@ -1026,6 +1026,16 @@ F: drivers/char/hw_random/geode-rng.c
F: drivers/crypto/geode*
F: drivers/video/fbdev/geode/
+AMD HSMP DRIVER
+M: Naveen Krishna Chatradhi <naveenkrishna.chatradhi@amd.com>
+R: Carlos Bilbao <carlos.bilbao@amd.com>
+L: platform-driver-x86@vger.kernel.org
+S: Maintained
+F: Documentation/arch/x86/amd_hsmp.rst
+F: arch/x86/include/asm/amd_hsmp.h
+F: arch/x86/include/uapi/asm/amd_hsmp.h
+F: drivers/platform/x86/amd/hsmp.c
+
AMD IOMMU (AMD-VI)
M: Joerg Roedel <joro@8bytes.org>
R: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
@@ -1049,6 +1059,13 @@ F: drivers/gpu/drm/amd/include/vi_structs.h
F: include/uapi/linux/kfd_ioctl.h
F: include/uapi/linux/kfd_sysfs.h
+AMD MP2 I2C DRIVER
+M: Elie Morisse <syniurge@gmail.com>
+M: Shyam Sundar S K <shyam-sundar.s-k@amd.com>
+L: linux-i2c@vger.kernel.org
+S: Maintained
+F: drivers/i2c/busses/i2c-amd-mp2*
+
AMD PDS CORE DRIVER
M: Shannon Nelson <shannon.nelson@amd.com>
M: Brett Creeley <brett.creeley@amd.com>
@@ -1058,18 +1075,6 @@ F: Documentation/networking/device_drivers/ethernet/amd/pds_core.rst
F: drivers/net/ethernet/amd/pds_core/
F: include/linux/pds/
-AMD SPI DRIVER
-M: Sanjay R Mehta <sanju.mehta@amd.com>
-S: Maintained
-F: drivers/spi/spi-amd.c
-
-AMD MP2 I2C DRIVER
-M: Elie Morisse <syniurge@gmail.com>
-M: Shyam Sundar S K <shyam-sundar.s-k@amd.com>
-L: linux-i2c@vger.kernel.org
-S: Maintained
-F: drivers/i2c/busses/i2c-amd-mp2*
-
AMD PMC DRIVER
M: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
L: platform-driver-x86@vger.kernel.org
@@ -1083,16 +1088,6 @@ S: Maintained
F: Documentation/ABI/testing/sysfs-amd-pmf
F: drivers/platform/x86/amd/pmf/
-AMD HSMP DRIVER
-M: Naveen Krishna Chatradhi <naveenkrishna.chatradhi@amd.com>
-R: Carlos Bilbao <carlos.bilbao@amd.com>
-L: platform-driver-x86@vger.kernel.org
-S: Maintained
-F: Documentation/arch/x86/amd_hsmp.rst
-F: arch/x86/include/asm/amd_hsmp.h
-F: arch/x86/include/uapi/asm/amd_hsmp.h
-F: drivers/platform/x86/amd/hsmp.c
-
AMD POWERPLAY AND SWSMU
M: Evan Quan <evan.quan@amd.com>
L: amd-gfx@lists.freedesktop.org
@@ -1121,13 +1116,6 @@ M: Tom Lendacky <thomas.lendacky@amd.com>
S: Supported
F: arch/arm64/boot/dts/amd/
-AMD XGBE DRIVER
-M: "Shyam Sundar S K" <Shyam-sundar.S-k@amd.com>
-L: netdev@vger.kernel.org
-S: Supported
-F: arch/arm64/boot/dts/amd/amd-seattle-xgbe*.dtsi
-F: drivers/net/ethernet/amd/xgbe/
-
AMD SENSOR FUSION HUB DRIVER
M: Basavaraj Natikar <basavaraj.natikar@amd.com>
L: linux-input@vger.kernel.org
@@ -1135,6 +1123,18 @@ S: Maintained
F: Documentation/hid/amd-sfh*
F: drivers/hid/amd-sfh-hid/
+AMD SPI DRIVER
+M: Sanjay R Mehta <sanju.mehta@amd.com>
+S: Maintained
+F: drivers/spi/spi-amd.c
+
+AMD XGBE DRIVER
+M: "Shyam Sundar S K" <Shyam-sundar.S-k@amd.com>
+L: netdev@vger.kernel.org
+S: Supported
+F: arch/arm64/boot/dts/amd/amd-seattle-xgbe*.dtsi
+F: drivers/net/ethernet/amd/xgbe/
+
AMLOGIC DDR PMU DRIVER
M: Jiucheng Xu <jiucheng.xu@amlogic.com>
L: linux-amlogic@lists.infradead.org
@@ -1169,6 +1169,14 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git
T: git git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git
F: drivers/net/amt.c
+ANALOG DEVICES INC AD3552R DRIVER
+M: Nuno Sá <nuno.sa@analog.com>
+L: linux-iio@vger.kernel.org
+S: Supported
+W: https://ez.analog.com/linux-software-drivers
+F: Documentation/devicetree/bindings/iio/dac/adi,ad3552r.yaml
+F: drivers/iio/dac/ad3552r.c
+
ANALOG DEVICES INC AD4130 DRIVER
M: Cosmin Tanislav <cosmin.tanislav@analog.com>
L: linux-iio@vger.kernel.org
@@ -1194,14 +1202,6 @@ W: https://ez.analog.com/linux-software-drivers
F: Documentation/devicetree/bindings/iio/adc/adi,ad7292.yaml
F: drivers/iio/adc/ad7292.c
-ANALOG DEVICES INC AD3552R DRIVER
-M: Nuno Sá <nuno.sa@analog.com>
-L: linux-iio@vger.kernel.org
-S: Supported
-W: https://ez.analog.com/linux-software-drivers
-F: Documentation/devicetree/bindings/iio/dac/adi,ad3552r.yaml
-F: drivers/iio/dac/ad3552r.c
-
ANALOG DEVICES INC AD7293 DRIVER
M: Antoniu Miclaus <antoniu.miclaus@analog.com>
L: linux-iio@vger.kernel.org
@@ -1210,23 +1210,6 @@ W: https://ez.analog.com/linux-software-drivers
F: Documentation/devicetree/bindings/iio/dac/adi,ad7293.yaml
F: drivers/iio/dac/ad7293.c
-ANALOG DEVICES INC AD7768-1 DRIVER
-M: Michael Hennerich <Michael.Hennerich@analog.com>
-L: linux-iio@vger.kernel.org
-S: Supported
-W: https://ez.analog.com/linux-software-drivers
-F: Documentation/devicetree/bindings/iio/adc/adi,ad7768-1.yaml
-F: drivers/iio/adc/ad7768-1.c
-
-ANALOG DEVICES INC AD7780 DRIVER
-M: Michael Hennerich <Michael.Hennerich@analog.com>
-M: Renato Lui Geh <renatogeh@gmail.com>
-L: linux-iio@vger.kernel.org
-S: Supported
-W: https://ez.analog.com/linux-software-drivers
-F: Documentation/devicetree/bindings/iio/adc/adi,ad7780.yaml
-F: drivers/iio/adc/ad7780.c
-
ANALOG DEVICES INC AD74115 DRIVER
M: Cosmin Tanislav <cosmin.tanislav@analog.com>
L: linux-iio@vger.kernel.org
@@ -1244,6 +1227,23 @@ F: Documentation/devicetree/bindings/iio/addac/adi,ad74413r.yaml
F: drivers/iio/addac/ad74413r.c
F: include/dt-bindings/iio/addac/adi,ad74413r.h
+ANALOG DEVICES INC AD7768-1 DRIVER
+M: Michael Hennerich <Michael.Hennerich@analog.com>
+L: linux-iio@vger.kernel.org
+S: Supported
+W: https://ez.analog.com/linux-software-drivers
+F: Documentation/devicetree/bindings/iio/adc/adi,ad7768-1.yaml
+F: drivers/iio/adc/ad7768-1.c
+
+ANALOG DEVICES INC AD7780 DRIVER
+M: Michael Hennerich <Michael.Hennerich@analog.com>
+M: Renato Lui Geh <renatogeh@gmail.com>
+L: linux-iio@vger.kernel.org
+S: Supported
+W: https://ez.analog.com/linux-software-drivers
+F: Documentation/devicetree/bindings/iio/adc/adi,ad7780.yaml
+F: drivers/iio/adc/ad7780.c
+
ANALOG DEVICES INC ADA4250 DRIVER
M: Antoniu Miclaus <antoniu.miclaus@analog.com>
L: linux-iio@vger.kernel.org
@@ -1294,10 +1294,10 @@ F: drivers/iio/imu/adis16460.c
ANALOG DEVICES INC ADIS16475 DRIVER
M: Nuno Sa <nuno.sa@analog.com>
L: linux-iio@vger.kernel.org
-W: https://ez.analog.com/linux-software-drivers
S: Supported
-F: drivers/iio/imu/adis16475.c
+W: https://ez.analog.com/linux-software-drivers
F: Documentation/devicetree/bindings/iio/imu/adi,adis16475.yaml
+F: drivers/iio/imu/adis16475.c
ANALOG DEVICES INC ADM1177 DRIVER
M: Michael Hennerich <Michael.Hennerich@analog.com>
@@ -1315,21 +1315,21 @@ W: https://ez.analog.com/linux-software-drivers
F: Documentation/devicetree/bindings/iio/frequency/adi,admv1013.yaml
F: drivers/iio/frequency/admv1013.c
-ANALOG DEVICES INC ADMV8818 DRIVER
+ANALOG DEVICES INC ADMV1014 DRIVER
M: Antoniu Miclaus <antoniu.miclaus@analog.com>
L: linux-iio@vger.kernel.org
S: Supported
W: https://ez.analog.com/linux-software-drivers
-F: Documentation/devicetree/bindings/iio/filter/adi,admv8818.yaml
-F: drivers/iio/filter/admv8818.c
+F: Documentation/devicetree/bindings/iio/frequency/adi,admv1014.yaml
+F: drivers/iio/frequency/admv1014.c
-ANALOG DEVICES INC ADMV1014 DRIVER
+ANALOG DEVICES INC ADMV8818 DRIVER
M: Antoniu Miclaus <antoniu.miclaus@analog.com>
L: linux-iio@vger.kernel.org
S: Supported
W: https://ez.analog.com/linux-software-drivers
-F: Documentation/devicetree/bindings/iio/frequency/adi,admv1014.yaml
-F: drivers/iio/frequency/admv1014.c
+F: Documentation/devicetree/bindings/iio/filter/adi,admv8818.yaml
+F: drivers/iio/filter/admv8818.c
ANALOG DEVICES INC ADP5061 DRIVER
M: Michael Hennerich <Michael.Hennerich@analog.com>
@@ -1351,8 +1351,8 @@ M: Lars-Peter Clausen <lars@metafoo.de>
L: linux-media@vger.kernel.org
S: Supported
W: https://ez.analog.com/linux-software-drivers
-F: drivers/media/i2c/adv7180.c
F: Documentation/devicetree/bindings/media/i2c/adv7180.yaml
+F: drivers/media/i2c/adv7180.c
ANALOG DEVICES INC ADV748X DRIVER
M: Kieran Bingham <kieran.bingham@ideasonboard.com>
@@ -1371,8 +1371,8 @@ ANALOG DEVICES INC ADV7604 DRIVER
M: Hans Verkuil <hverkuil-cisco@xs4all.nl>
L: linux-media@vger.kernel.org
S: Maintained
-F: drivers/media/i2c/adv7604*
F: Documentation/devicetree/bindings/media/i2c/adv7604.yaml
+F: drivers/media/i2c/adv7604*
ANALOG DEVICES INC ADV7842 DRIVER
M: Hans Verkuil <hverkuil-cisco@xs4all.nl>
@@ -1384,8 +1384,8 @@ ANALOG DEVICES INC ADXRS290 DRIVER
M: Nishant Malpani <nish.malpani25@gmail.com>
L: linux-iio@vger.kernel.org
S: Supported
-F: drivers/iio/gyro/adxrs290.c
F: Documentation/devicetree/bindings/iio/gyroscope/adi,adxrs290.yaml
+F: drivers/iio/gyro/adxrs290.c
ANALOG DEVICES INC ASOC CODEC DRIVERS
M: Lars-Peter Clausen <lars@metafoo.de>
@@ -1625,6 +1625,17 @@ S: Maintained
F: drivers/net/arcnet/
F: include/uapi/linux/if_arcnet.h
+ARM AND ARM64 SoC SUB-ARCHITECTURES (COMMON PARTS)
+M: Arnd Bergmann <arnd@arndb.de>
+M: Olof Johansson <olof@lixom.net>
+M: soc@kernel.org
+L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S: Maintained
+C: irc://irc.libera.chat/armlinux
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git
+F: arch/arm/boot/dts/Makefile
+F: arch/arm64/boot/dts/Makefile
+
ARM ARCHITECTED TIMER DRIVER
M: Mark Rutland <mark.rutland@arm.com>
M: Marc Zyngier <maz@kernel.org>
@@ -1738,22 +1749,6 @@ S: Odd Fixes
F: drivers/amba/
F: include/linux/amba/bus.h
-ARM PRIMECELL PL35X NAND CONTROLLER DRIVER
-M: Miquel Raynal <miquel.raynal@bootlin.com>
-M: Naga Sureshkumar Relli <nagasure@xilinx.com>
-L: linux-mtd@lists.infradead.org
-S: Maintained
-F: Documentation/devicetree/bindings/mtd/arm,pl353-nand-r2p1.yaml
-F: drivers/mtd/nand/raw/pl35x-nand-controller.c
-
-ARM PRIMECELL PL35X SMC DRIVER
-M: Miquel Raynal <miquel.raynal@bootlin.com>
-M: Naga Sureshkumar Relli <nagasure@xilinx.com>
-L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-S: Maintained
-F: Documentation/devicetree/bindings/memory-controllers/arm,pl35x-smc.yaml
-F: drivers/memory/pl353-smc.c
-
ARM PRIMECELL CLCD PL110 DRIVER
M: Russell King <linux@armlinux.org.uk>
S: Odd Fixes
@@ -1771,6 +1766,22 @@ S: Odd Fixes
F: drivers/mmc/host/mmci.*
F: include/linux/amba/mmci.h
+ARM PRIMECELL PL35X NAND CONTROLLER DRIVER
+M: Miquel Raynal <miquel.raynal@bootlin.com>
+M: Naga Sureshkumar Relli <nagasure@xilinx.com>
+L: linux-mtd@lists.infradead.org
+S: Maintained
+F: Documentation/devicetree/bindings/mtd/arm,pl353-nand-r2p1.yaml
+F: drivers/mtd/nand/raw/pl35x-nand-controller.c
+
+ARM PRIMECELL PL35X SMC DRIVER
+M: Miquel Raynal <miquel.raynal@bootlin.com>
+M: Naga Sureshkumar Relli <nagasure@xilinx.com>
+L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S: Maintained
+F: Documentation/devicetree/bindings/memory-controllers/arm,pl35x-smc.yaml
+F: drivers/memory/pl353-smc.c
+
ARM PRIMECELL SSP PL022 SPI DRIVER
M: Linus Walleij <linus.walleij@linaro.org>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -1807,17 +1818,6 @@ F: Documentation/devicetree/bindings/iommu/arm,smmu*
F: drivers/iommu/arm/
F: drivers/iommu/io-pgtable-arm*
-ARM AND ARM64 SoC SUB-ARCHITECTURES (COMMON PARTS)
-M: Arnd Bergmann <arnd@arndb.de>
-M: Olof Johansson <olof@lixom.net>
-M: soc@kernel.org
-L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-S: Maintained
-C: irc://irc.libera.chat/armlinux
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git
-F: arch/arm/boot/dts/Makefile
-F: arch/arm64/boot/dts/Makefile
-
ARM SUB-ARCHITECTURES
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
@@ -1869,9 +1869,9 @@ M: Chen-Yu Tsai <wens@csie.org>
M: Jernej Skrabec <jernej.skrabec@gmail.com>
M: Samuel Holland <samuel@sholland.org>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+L: linux-sunxi@lists.linux.dev
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux.git
-L: linux-sunxi@lists.linux.dev
F: arch/arm/mach-sunxi/
F: arch/arm64/boot/dts/allwinner/
F: drivers/clk/sunxi-ng/
@@ -1934,6 +1934,15 @@ F: arch/arm/mach-alpine/
F: arch/arm64/boot/dts/amazon/
F: drivers/*/*alpine*
+ARM/APPLE MACHINE SOUND DRIVERS
+M: Martin Povišer <povik+lin@cutebit.org>
+L: asahi@lists.linux.dev
+L: alsa-devel@alsa-project.org (moderated for non-subscribers)
+S: Maintained
+F: Documentation/devicetree/bindings/sound/apple,*
+F: sound/soc/apple/*
+F: sound/soc/codecs/cs42l83-i2c.c
+
ARM/APPLE MACHINE SUPPORT
M: Hector Martin <marcan@marcan.st>
M: Sven Peter <sven@svenpeter.dev>
@@ -1961,7 +1970,7 @@ F: Documentation/devicetree/bindings/nvmem/apple,efuses.yaml
F: Documentation/devicetree/bindings/pci/apple,pcie.yaml
F: Documentation/devicetree/bindings/pinctrl/apple,pinctrl.yaml
F: Documentation/devicetree/bindings/power/apple*
-F: Documentation/devicetree/bindings/pwm/pwm-apple.yaml
+F: Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
F: Documentation/devicetree/bindings/watchdog/apple,wdt.yaml
F: arch/arm64/boot/dts/apple/
F: drivers/bluetooth/hci_bcm4377.c
@@ -1985,15 +1994,6 @@ F: include/dt-bindings/pinctrl/apple.h
F: include/linux/apple-mailbox.h
F: include/linux/soc/apple/*
-ARM/APPLE MACHINE SOUND DRIVERS
-M: Martin Povišer <povik+lin@cutebit.org>
-L: asahi@lists.linux.dev
-L: alsa-devel@alsa-project.org (moderated for non-subscribers)
-S: Maintained
-F: Documentation/devicetree/bindings/sound/apple,*
-F: sound/soc/apple/*
-F: sound/soc/codecs/cs42l83-i2c.c
-
ARM/ARTPEC MACHINE SUPPORT
M: Jesper Nilsson <jesper.nilsson@axis.com>
M: Lars Persson <lars.persson@axis.com>
@@ -2109,19 +2109,19 @@ S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/coresight/linux.git
F: Documentation/ABI/testing/sysfs-bus-coresight-devices-*
F: Documentation/devicetree/bindings/arm/arm,coresight-*.yaml
-F: Documentation/devicetree/bindings/arm/qcom,coresight-*.yaml
F: Documentation/devicetree/bindings/arm/arm,embedded-trace-extension.yaml
F: Documentation/devicetree/bindings/arm/arm,trace-buffer-extension.yaml
+F: Documentation/devicetree/bindings/arm/qcom,coresight-*.yaml
F: Documentation/trace/coresight/*
F: drivers/hwtracing/coresight/*
F: include/dt-bindings/arm/coresight-cti-dt.h
F: include/linux/coresight*
F: samples/coresight/*
-F: tools/perf/tests/shell/coresight/*
F: tools/perf/arch/arm/util/auxtrace.c
F: tools/perf/arch/arm/util/cs-etm.c
F: tools/perf/arch/arm/util/cs-etm.h
F: tools/perf/arch/arm/util/pmu.c
+F: tools/perf/tests/shell/coresight/*
F: tools/perf/util/cs-etm-decoder/*
F: tools/perf/util/cs-etm.*
@@ -2156,9 +2156,9 @@ F: Documentation/devicetree/bindings/leds/cznic,turris-omnia-leds.yaml
F: Documentation/devicetree/bindings/watchdog/armada-37xx-wdt.txt
F: drivers/bus/moxtet.c
F: drivers/firmware/turris-mox-rwtm.c
+F: drivers/gpio/gpio-moxtet.c
F: drivers/leds/leds-turris-omnia.c
F: drivers/mailbox/armada-37xx-rwtm-mailbox.c
-F: drivers/gpio/gpio-moxtet.c
F: drivers/watchdog/armada_37xx_wdt.c
F: include/dt-bindings/bus/moxtet.h
F: include/linux/armada-37xx-rwtm-mailbox.h
@@ -2188,10 +2188,10 @@ R: NXP Linux Team <linux-imx@nxp.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git
-X: drivers/media/i2c/
F: arch/arm64/boot/dts/freescale/
X: arch/arm64/boot/dts/freescale/fsl-*
X: arch/arm64/boot/dts/freescale/qoriq-*
+X: drivers/media/i2c/
N: imx
N: mxs
@@ -2245,12 +2245,12 @@ ARM/HPE GXP ARCHITECTURE
M: Jean-Marie Verdun <verdun@hpe.com>
M: Nick Hawkins <nick.hawkins@hpe.com>
S: Maintained
-F: Documentation/hwmon/gxp-fan-ctrl.rst
F: Documentation/devicetree/bindings/arm/hpe,gxp.yaml
F: Documentation/devicetree/bindings/hwmon/hpe,gxp-fan-ctrl.yaml
F: Documentation/devicetree/bindings/i2c/hpe,gxp-i2c.yaml
F: Documentation/devicetree/bindings/spi/hpe,gxp-spifi.yaml
F: Documentation/devicetree/bindings/timer/hpe,gxp-timer.yaml
+F: Documentation/hwmon/gxp-fan-ctrl.rst
F: arch/arm/boot/dts/hpe-bmc*
F: arch/arm/boot/dts/hpe-gxp*
F: arch/arm/mach-hpe/
@@ -2275,9 +2275,9 @@ M: Krzysztof Halasa <khalasa@piap.pl>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
F: Documentation/devicetree/bindings/arm/intel-ixp4xx.yaml
-F: Documentation/devicetree/bindings/memory-controllers/intel,ixp4xx-expansion*
F: Documentation/devicetree/bindings/gpio/intel,ixp4xx-gpio.txt
F: Documentation/devicetree/bindings/interrupt-controller/intel,ixp4xx-interrupt.yaml
+F: Documentation/devicetree/bindings/memory-controllers/intel,ixp4xx-expansion*
F: Documentation/devicetree/bindings/timer/intel,ixp4xx-timer.yaml
F: arch/arm/boot/dts/intel-ixp*
F: arch/arm/mach-ixp4xx/
@@ -2447,13 +2447,6 @@ F: drivers/net/ethernet/microchip/vcap/
F: drivers/pinctrl/pinctrl-microchip-sgpio.c
N: sparx5
-Microchip Timer Counter Block (TCB) Capture Driver
-M: Kamel Bouhara <kamel.bouhara@bootlin.com>
-L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-L: linux-iio@vger.kernel.org
-S: Maintained
-F: drivers/counter/microchip-tcb-capture.c
-
ARM/MILBEAUT ARCHITECTURE
M: Taichi Sugaya <sugaya.taichi@socionext.com>
M: Takao Orito <orito.takao@socionext.com>
@@ -2525,8 +2518,8 @@ F: Documentation/devicetree/bindings/rtc/nuvoton,nct3018y.yaml
F: arch/arm/boot/dts/nuvoton-npcm*
F: arch/arm/mach-npcm/
F: arch/arm64/boot/dts/nuvoton/
-F: drivers/*/*npcm*
F: drivers/*/*/*npcm*
+F: drivers/*/*npcm*
F: drivers/rtc/rtc-nct3018y.c
F: include/dt-bindings/clock/nuvoton,npcm7xx-clock.h
F: include/dt-bindings/clock/nuvoton,npcm845-clk.h
@@ -2569,6 +2562,12 @@ F: arch/arm/mach-oxnas/
F: drivers/power/reset/oxnas-restart.c
N: oxnas
+ARM/QUALCOMM CHROMEBOOK SUPPORT
+R: cros-qcom-dts-watchers@chromium.org
+F: arch/arm64/boot/dts/qcom/sc7180*
+F: arch/arm64/boot/dts/qcom/sc7280*
+F: arch/arm64/boot/dts/qcom/sdm845-cheza*
+
ARM/QUALCOMM SUPPORT
M: Andy Gross <agross@kernel.org>
M: Bjorn Andersson <andersson@kernel.org>
@@ -2602,22 +2601,16 @@ F: drivers/pci/controller/dwc/pcie-qcom.c
F: drivers/phy/qualcomm/
F: drivers/power/*/msm*
F: drivers/reset/reset-qcom-*
-F: drivers/ufs/host/ufs-qcom*
F: drivers/spi/spi-geni-qcom.c
F: drivers/spi/spi-qcom-qspi.c
F: drivers/spi/spi-qup.c
F: drivers/tty/serial/msm_serial.c
+F: drivers/ufs/host/ufs-qcom*
F: drivers/usb/dwc3/dwc3-qcom.c
F: include/dt-bindings/*/qcom*
F: include/linux/*/qcom*
F: include/linux/soc/qcom/
-ARM/QUALCOMM CHROMEBOOK SUPPORT
-R: cros-qcom-dts-watchers@chromium.org
-F: arch/arm64/boot/dts/qcom/sc7180*
-F: arch/arm64/boot/dts/qcom/sc7280*
-F: arch/arm64/boot/dts/qcom/sdm845-cheza*
-
ARM/RDA MICRO ARCHITECTURE
M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -2709,9 +2702,9 @@ R: Alim Akhtar <alim.akhtar@samsung.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
L: linux-samsung-soc@vger.kernel.org
S: Maintained
-C: irc://irc.libera.chat/linux-exynos
Q: https://patchwork.kernel.org/project/linux-samsung-soc/list/
B: mailto:linux-samsung-soc@vger.kernel.org
+C: irc://irc.libera.chat/linux-exynos
T: git git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git
F: Documentation/arm/samsung/
F: Documentation/devicetree/bindings/arm/samsung/
@@ -2811,8 +2804,8 @@ M: Patrice Chotard <patrice.chotard@foss.st.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
W: http://www.stlinux.com
-F: Documentation/devicetree/bindings/spi/st,ssc-spi.yaml
F: Documentation/devicetree/bindings/i2c/st,sti-i2c.yaml
+F: Documentation/devicetree/bindings/spi/st,ssc-spi.yaml
F: arch/arm/boot/dts/sti*
F: arch/arm/mach-sti/
F: drivers/ata/ahci_st.c
@@ -2959,15 +2952,15 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/iwamatsu/linux-visconti.git
F: Documentation/devicetree/bindings/arm/toshiba.yaml
F: Documentation/devicetree/bindings/clock/toshiba,tmpv770x-pipllct.yaml
F: Documentation/devicetree/bindings/clock/toshiba,tmpv770x-pismu.yaml
-F: Documentation/devicetree/bindings/net/toshiba,visconti-dwmac.yaml
F: Documentation/devicetree/bindings/gpio/toshiba,gpio-visconti.yaml
+F: Documentation/devicetree/bindings/net/toshiba,visconti-dwmac.yaml
F: Documentation/devicetree/bindings/pci/toshiba,visconti-pcie.yaml
F: Documentation/devicetree/bindings/pinctrl/toshiba,visconti-pinctrl.yaml
F: Documentation/devicetree/bindings/watchdog/toshiba,visconti-wdt.yaml
F: arch/arm64/boot/dts/toshiba/
F: drivers/clk/visconti/
-F: drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c
F: drivers/gpio/gpio-visconti.c
+F: drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c
F: drivers/pci/controller/dwc/pcie-visconti.c
F: drivers/pinctrl/visconti/
F: drivers/watchdog/visconti_wdt.c
@@ -3112,6 +3105,13 @@ S: Maintained
F: Documentation/devicetree/bindings/net/asix,ax88796c.yaml
F: drivers/net/ethernet/asix/ax88796c_*
+ASPEED CRYPTO DRIVER
+M: Neal Liu <neal_liu@aspeedtech.com>
+L: linux-aspeed@lists.ozlabs.org (moderated for non-subscribers)
+S: Maintained
+F: Documentation/devicetree/bindings/crypto/aspeed,*
+F: drivers/crypto/aspeed/
+
ASPEED PECI CONTROLLER
M: Iwona Winiarska <iwona.winiarska@intel.com>
L: linux-aspeed@lists.ozlabs.org (moderated for non-subscribers)
@@ -3156,6 +3156,13 @@ S: Maintained
F: Documentation/devicetree/bindings/spi/aspeed,ast2600-fmc.yaml
F: drivers/spi/spi-aspeed-smc.c
+ASPEED USB UDC DRIVER
+M: Neal Liu <neal_liu@aspeedtech.com>
+L: linux-aspeed@lists.ozlabs.org (moderated for non-subscribers)
+S: Maintained
+F: Documentation/devicetree/bindings/usb/aspeed,ast2600-udc.yaml
+F: drivers/usb/gadget/udc/aspeed_udc.c
+
ASPEED VIDEO ENGINE DRIVER
M: Eddie James <eajames@linux.ibm.com>
L: linux-media@vger.kernel.org
@@ -3164,19 +3171,11 @@ S: Maintained
F: Documentation/devicetree/bindings/media/aspeed-video.txt
F: drivers/media/platform/aspeed/
-ASPEED USB UDC DRIVER
-M: Neal Liu <neal_liu@aspeedtech.com>
-L: linux-aspeed@lists.ozlabs.org (moderated for non-subscribers)
-S: Maintained
-F: Documentation/devicetree/bindings/usb/aspeed,ast2600-udc.yaml
-F: drivers/usb/gadget/udc/aspeed_udc.c
-
-ASPEED CRYPTO DRIVER
-M: Neal Liu <neal_liu@aspeedtech.com>
-L: linux-aspeed@lists.ozlabs.org (moderated for non-subscribers)
+ASUS EC HARDWARE MONITOR DRIVER
+M: Eugene Shalygin <eugene.shalygin@gmail.com>
+L: linux-hwmon@vger.kernel.org
S: Maintained
-F: Documentation/devicetree/bindings/crypto/aspeed,*
-F: drivers/crypto/aspeed/
+F: drivers/hwmon/asus-ec-sensors.c
ASUS NOTEBOOKS AND EEEPC ACPI/WMI EXTRAS DRIVERS
M: Corentin Chary <corentin.chary@gmail.com>
@@ -3194,6 +3193,12 @@ S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86.git
F: drivers/platform/x86/asus-tf103c-dock.c
+ASUS WIRELESS RADIO CONTROL DRIVER
+M: João Paulo Rechi Vita <jprvita@gmail.com>
+L: platform-driver-x86@vger.kernel.org
+S: Maintained
+F: drivers/platform/x86/asus-wireless.c
+
ASUS WMI HARDWARE MONITOR DRIVER
M: Ed Brindley <kernel@maidavale.org>
M: Denis Pauk <pauk.denis@gmail.com>
@@ -3201,18 +3206,6 @@ L: linux-hwmon@vger.kernel.org
S: Maintained
F: drivers/hwmon/asus_wmi_sensors.c
-ASUS EC HARDWARE MONITOR DRIVER
-M: Eugene Shalygin <eugene.shalygin@gmail.com>
-L: linux-hwmon@vger.kernel.org
-S: Maintained
-F: drivers/hwmon/asus-ec-sensors.c
-
-ASUS WIRELESS RADIO CONTROL DRIVER
-M: João Paulo Rechi Vita <jprvita@gmail.com>
-L: platform-driver-x86@vger.kernel.org
-S: Maintained
-F: drivers/platform/x86/asus-wireless.c
-
ASYMMETRIC KEYS
M: David Howells <dhowells@redhat.com>
L: keyrings@vger.kernel.org
@@ -3352,10 +3345,10 @@ R: Boqun Feng <boqun.feng@gmail.com>
R: Mark Rutland <mark.rutland@arm.com>
L: linux-kernel@vger.kernel.org
S: Maintained
+F: Documentation/atomic_*.txt
F: arch/*/include/asm/atomic*.h
F: include/*/atomic*.h
F: include/linux/refcount.h
-F: Documentation/atomic_*.txt
F: scripts/atomic/
ATTO EXPRESSSAS SAS/SATA RAID SCSI DRIVER
@@ -3649,50 +3642,6 @@ S: Maintained
F: Documentation/devicetree/bindings/iio/accel/bosch,bma400.yaml
F: drivers/iio/accel/bma400*
-BPF [GENERAL] (Safe Dynamic Programs and Tools)
-M: Alexei Starovoitov <ast@kernel.org>
-M: Daniel Borkmann <daniel@iogearbox.net>
-M: Andrii Nakryiko <andrii@kernel.org>
-R: Martin KaFai Lau <martin.lau@linux.dev>
-R: Song Liu <song@kernel.org>
-R: Yonghong Song <yhs@fb.com>
-R: John Fastabend <john.fastabend@gmail.com>
-R: KP Singh <kpsingh@kernel.org>
-R: Stanislav Fomichev <sdf@google.com>
-R: Hao Luo <haoluo@google.com>
-R: Jiri Olsa <jolsa@kernel.org>
-L: bpf@vger.kernel.org
-S: Supported
-W: https://bpf.io/
-Q: https://patchwork.kernel.org/project/netdevbpf/list/?delegate=121173
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf.git
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git
-F: Documentation/bpf/
-F: Documentation/networking/filter.rst
-F: Documentation/userspace-api/ebpf/
-F: arch/*/net/*
-F: include/linux/bpf*
-F: include/linux/btf*
-F: include/linux/filter.h
-F: include/trace/events/xdp.h
-F: include/uapi/linux/bpf*
-F: include/uapi/linux/btf*
-F: include/uapi/linux/filter.h
-F: kernel/bpf/
-F: kernel/trace/bpf_trace.c
-F: lib/test_bpf.c
-F: net/bpf/
-F: net/core/filter.c
-F: net/sched/act_bpf.c
-F: net/sched/cls_bpf.c
-F: samples/bpf/
-F: scripts/bpf_doc.py
-F: scripts/pahole-flags.sh
-F: scripts/pahole-version.sh
-F: tools/bpf/
-F: tools/lib/bpf/
-F: tools/testing/selftests/bpf/
-
BPF JIT for ARM
M: Shubham Bansal <illusionist.neo@gmail.com>
L: bpf@vger.kernel.org
@@ -3771,79 +3720,79 @@ S: Supported
F: arch/x86/net/
X: arch/x86/net/bpf_jit_comp32.c
+BPF [BTF]
+M: Martin KaFai Lau <martin.lau@linux.dev>
+L: bpf@vger.kernel.org
+S: Maintained
+F: include/linux/btf*
+F: kernel/bpf/btf.c
+
BPF [CORE]
M: Alexei Starovoitov <ast@kernel.org>
M: Daniel Borkmann <daniel@iogearbox.net>
R: John Fastabend <john.fastabend@gmail.com>
L: bpf@vger.kernel.org
S: Maintained
-F: kernel/bpf/verifier.c
-F: kernel/bpf/tnum.c
-F: kernel/bpf/core.c
-F: kernel/bpf/syscall.c
-F: kernel/bpf/dispatcher.c
-F: kernel/bpf/trampoline.c
F: include/linux/bpf*
F: include/linux/filter.h
F: include/linux/tnum.h
+F: kernel/bpf/core.c
+F: kernel/bpf/dispatcher.c
+F: kernel/bpf/syscall.c
+F: kernel/bpf/tnum.c
+F: kernel/bpf/trampoline.c
+F: kernel/bpf/verifier.c
-BPF [BTF]
-M: Martin KaFai Lau <martin.lau@linux.dev>
-L: bpf@vger.kernel.org
-S: Maintained
-F: kernel/bpf/btf.c
-F: include/linux/btf*
-
-BPF [TRACING]
-M: Song Liu <song@kernel.org>
-R: Jiri Olsa <jolsa@kernel.org>
+BPF [DOCUMENTATION] (Related to Standardization)
+R: David Vernet <void@manifault.com>
L: bpf@vger.kernel.org
+L: bpf@ietf.org
S: Maintained
-F: kernel/trace/bpf_trace.c
-F: kernel/bpf/stackmap.c
+F: Documentation/bpf/instruction-set.rst
-BPF [NETWORKING] (tc BPF, sock_addr)
-M: Martin KaFai Lau <martin.lau@linux.dev>
+BPF [GENERAL] (Safe Dynamic Programs and Tools)
+M: Alexei Starovoitov <ast@kernel.org>
M: Daniel Borkmann <daniel@iogearbox.net>
+M: Andrii Nakryiko <andrii@kernel.org>
+R: Martin KaFai Lau <martin.lau@linux.dev>
+R: Song Liu <song@kernel.org>
+R: Yonghong Song <yhs@fb.com>
R: John Fastabend <john.fastabend@gmail.com>
+R: KP Singh <kpsingh@kernel.org>
+R: Stanislav Fomichev <sdf@google.com>
+R: Hao Luo <haoluo@google.com>
+R: Jiri Olsa <jolsa@kernel.org>
L: bpf@vger.kernel.org
-L: netdev@vger.kernel.org
-S: Maintained
+S: Supported
+W: https://bpf.io/
+Q: https://patchwork.kernel.org/project/netdevbpf/list/?delegate=121173
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git
+F: Documentation/bpf/
+F: Documentation/networking/filter.rst
+F: Documentation/userspace-api/ebpf/
+F: arch/*/net/*
+F: include/linux/bpf*
+F: include/linux/btf*
+F: include/linux/filter.h
+F: include/trace/events/xdp.h
+F: include/uapi/linux/bpf*
+F: include/uapi/linux/btf*
+F: include/uapi/linux/filter.h
+F: kernel/bpf/
+F: kernel/trace/bpf_trace.c
+F: lib/test_bpf.c
+F: net/bpf/
F: net/core/filter.c
F: net/sched/act_bpf.c
F: net/sched/cls_bpf.c
-
-BPF [NETWORKING] (struct_ops, reuseport)
-M: Martin KaFai Lau <martin.lau@linux.dev>
-L: bpf@vger.kernel.org
-L: netdev@vger.kernel.org
-S: Maintained
-F: kernel/bpf/bpf_struct*
-
-BPF [SECURITY & LSM] (Security Audit and Enforcement using BPF)
-M: KP Singh <kpsingh@kernel.org>
-R: Florent Revest <revest@chromium.org>
-R: Brendan Jackman <jackmanb@chromium.org>
-L: bpf@vger.kernel.org
-S: Maintained
-F: Documentation/bpf/prog_lsm.rst
-F: include/linux/bpf_lsm.h
-F: kernel/bpf/bpf_lsm.c
-F: security/bpf/
-
-BPF [STORAGE & CGROUPS]
-M: Martin KaFai Lau <martin.lau@linux.dev>
-L: bpf@vger.kernel.org
-S: Maintained
-F: kernel/bpf/cgroup.c
-F: kernel/bpf/*storage.c
-F: kernel/bpf/bpf_lru*
-
-BPF [RINGBUF]
-M: Andrii Nakryiko <andrii@kernel.org>
-L: bpf@vger.kernel.org
-S: Maintained
-F: kernel/bpf/ringbuf.c
+F: samples/bpf/
+F: scripts/bpf_doc.py
+F: scripts/pahole-flags.sh
+F: scripts/pahole-version.sh
+F: tools/bpf/
+F: tools/lib/bpf/
+F: tools/testing/selftests/bpf/
BPF [ITERATOR]
M: Yonghong Song <yhs@fb.com>
@@ -3870,12 +3819,45 @@ L: bpf@vger.kernel.org
S: Maintained
F: tools/lib/bpf/
-BPF [TOOLING] (bpftool)
-M: Quentin Monnet <quentin@isovalent.com>
+BPF [MISC]
L: bpf@vger.kernel.org
+S: Odd Fixes
+K: (?:\b|_)bpf(?:\b|_)
+
+BPF [NETWORKING] (struct_ops, reuseport)
+M: Martin KaFai Lau <martin.lau@linux.dev>
+L: bpf@vger.kernel.org
+L: netdev@vger.kernel.org
S: Maintained
-F: kernel/bpf/disasm.*
-F: tools/bpf/bpftool/
+F: kernel/bpf/bpf_struct*
+
+BPF [NETWORKING] (tc BPF, sock_addr)
+M: Martin KaFai Lau <martin.lau@linux.dev>
+M: Daniel Borkmann <daniel@iogearbox.net>
+R: John Fastabend <john.fastabend@gmail.com>
+L: bpf@vger.kernel.org
+L: netdev@vger.kernel.org
+S: Maintained
+F: net/core/filter.c
+F: net/sched/act_bpf.c
+F: net/sched/cls_bpf.c
+
+BPF [RINGBUF]
+M: Andrii Nakryiko <andrii@kernel.org>
+L: bpf@vger.kernel.org
+S: Maintained
+F: kernel/bpf/ringbuf.c
+
+BPF [SECURITY & LSM] (Security Audit and Enforcement using BPF)
+M: KP Singh <kpsingh@kernel.org>
+R: Florent Revest <revest@chromium.org>
+R: Brendan Jackman <jackmanb@chromium.org>
+L: bpf@vger.kernel.org
+S: Maintained
+F: Documentation/bpf/prog_lsm.rst
+F: include/linux/bpf_lsm.h
+F: kernel/bpf/bpf_lsm.c
+F: security/bpf/
BPF [SELFTESTS] (Test Runners & Infrastructure)
M: Andrii Nakryiko <andrii@kernel.org>
@@ -3884,17 +3866,28 @@ L: bpf@vger.kernel.org
S: Maintained
F: tools/testing/selftests/bpf/
-BPF [DOCUMENTATION] (Related to Standardization)
-R: David Vernet <void@manifault.com>
+BPF [STORAGE & CGROUPS]
+M: Martin KaFai Lau <martin.lau@linux.dev>
L: bpf@vger.kernel.org
-L: bpf@ietf.org
S: Maintained
-F: Documentation/bpf/instruction-set.rst
+F: kernel/bpf/*storage.c
+F: kernel/bpf/bpf_lru*
+F: kernel/bpf/cgroup.c
-BPF [MISC]
+BPF [TOOLING] (bpftool)
+M: Quentin Monnet <quentin@isovalent.com>
L: bpf@vger.kernel.org
-S: Odd Fixes
-K: (?:\b|_)bpf(?:\b|_)
+S: Maintained
+F: kernel/bpf/disasm.*
+F: tools/bpf/bpftool/
+
+BPF [TRACING]
+M: Song Liu <song@kernel.org>
+R: Jiri Olsa <jolsa@kernel.org>
+L: bpf@vger.kernel.org
+S: Maintained
+F: kernel/bpf/stackmap.c
+F: kernel/trace/bpf_trace.c
BROADCOM B44 10/100 ETHERNET DRIVER
M: Michael Chan <michael.chan@broadcom.com>
@@ -3913,34 +3906,6 @@ F: drivers/net/dsa/bcm_sf2*
F: include/linux/dsa/brcm.h
F: include/linux/platform_data/b53.h
-BROADCOM BCMBCA ARM ARCHITECTURE
-M: William Zhang <william.zhang@broadcom.com>
-M: Anand Gore <anand.gore@broadcom.com>
-M: Kursad Oney <kursad.oney@broadcom.com>
-M: Florian Fainelli <f.fainelli@gmail.com>
-M: Rafał Miłecki <rafal@milecki.pl>
-R: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
-L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-S: Maintained
-T: git https://github.com/broadcom/stblinux.git
-F: Documentation/devicetree/bindings/arm/bcm/brcm,bcmbca.yaml
-F: arch/arm64/boot/dts/broadcom/bcmbca/*
-N: bcmbca
-N: bcm[9]?47622
-N: bcm[9]?4912
-N: bcm[9]?63138
-N: bcm[9]?63146
-N: bcm[9]?63148
-N: bcm[9]?63158
-N: bcm[9]?63178
-N: bcm[9]?6756
-N: bcm[9]?6813
-N: bcm[9]?6846
-N: bcm[9]?6855
-N: bcm[9]?6856
-N: bcm[9]?6858
-N: bcm[9]?6878
-
BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE
M: Florian Fainelli <f.fainelli@gmail.com>
R: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
@@ -4038,11 +4003,39 @@ N: brcmstb
N: bcm7038
N: bcm7120
+BROADCOM BCMBCA ARM ARCHITECTURE
+M: William Zhang <william.zhang@broadcom.com>
+M: Anand Gore <anand.gore@broadcom.com>
+M: Kursad Oney <kursad.oney@broadcom.com>
+M: Florian Fainelli <f.fainelli@gmail.com>
+M: Rafał Miłecki <rafal@milecki.pl>
+R: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
+L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S: Maintained
+T: git https://github.com/broadcom/stblinux.git
+F: Documentation/devicetree/bindings/arm/bcm/brcm,bcmbca.yaml
+F: arch/arm64/boot/dts/broadcom/bcmbca/*
+N: bcmbca
+N: bcm[9]?47622
+N: bcm[9]?4912
+N: bcm[9]?63138
+N: bcm[9]?63146
+N: bcm[9]?63148
+N: bcm[9]?63158
+N: bcm[9]?63178
+N: bcm[9]?6756
+N: bcm[9]?6813
+N: bcm[9]?6846
+N: bcm[9]?6855
+N: bcm[9]?6856
+N: bcm[9]?6858
+N: bcm[9]?6878
+
BROADCOM BDC DRIVER
M: Justin Chen <justinpopo6@gmail.com>
M: Al Cooper <alcooperx@gmail.com>
-L: linux-usb@vger.kernel.org
R: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
+L: linux-usb@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/usb/brcm,bdc.yaml
F: drivers/usb/gadget/udc/bdc/
@@ -4064,10 +4057,10 @@ F: arch/mips/bmips/*
F: arch/mips/boot/dts/brcm/bcm*.dts*
F: arch/mips/include/asm/mach-bmips/*
F: arch/mips/kernel/*bmips*
-F: drivers/soc/bcm/bcm63xx
F: drivers/irqchip/irq-bcm63*
F: drivers/irqchip/irq-bcm7*
F: drivers/irqchip/irq-brcmstb*
+F: drivers/soc/bcm/bcm63xx
F: include/linux/bcm963xx_nvram.h
F: include/linux/bcm963xx_tag.h
@@ -4349,9 +4342,9 @@ M: Florian Fainelli <f.fainelli@gmail.com>
R: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
L: netdev@vger.kernel.org
S: Supported
+F: Documentation/devicetree/bindings/net/brcm,systemport.yaml
F: drivers/net/ethernet/broadcom/bcmsysport.*
F: drivers/net/ethernet/broadcom/unimac.h
-F: Documentation/devicetree/bindings/net/brcm,systemport.yaml
BROADCOM TG3 GIGABIT ETHERNET DRIVER
M: Siva Reddy Kallam <siva.kallam@broadcom.com>
@@ -4483,29 +4476,6 @@ W: https://github.com/Cascoda/ca8210-linux.git
F: Documentation/devicetree/bindings/net/ieee802154/ca8210.txt
F: drivers/net/ieee802154/ca8210.c
-CANAAN/KENDRYTE K210 SOC FPIOA DRIVER
-M: Damien Le Moal <dlemoal@kernel.org>
-L: linux-riscv@lists.infradead.org
-L: linux-gpio@vger.kernel.org (pinctrl driver)
-F: Documentation/devicetree/bindings/pinctrl/canaan,k210-fpioa.yaml
-F: drivers/pinctrl/pinctrl-k210.c
-
-CANAAN/KENDRYTE K210 SOC RESET CONTROLLER DRIVER
-M: Damien Le Moal <dlemoal@kernel.org>
-L: linux-kernel@vger.kernel.org
-L: linux-riscv@lists.infradead.org
-S: Maintained
-F: Documentation/devicetree/bindings/reset/canaan,k210-rst.yaml
-F: drivers/reset/reset-k210.c
-
-CANAAN/KENDRYTE K210 SOC SYSTEM CONTROLLER DRIVER
-M: Damien Le Moal <dlemoal@kernel.org>
-L: linux-riscv@lists.infradead.org
-S: Maintained
-F: Documentation/devicetree/bindings/mfd/canaan,k210-sysctl.yaml
-F: drivers/soc/canaan/
-F: include/soc/canaan/
-
CACHEFILES: FS-CACHE BACKEND FOR CACHING ON MOUNTED FILESYSTEMS
M: David Howells <dhowells@redhat.com>
L: linux-cachefs@redhat.com (moderated for non-subscribers)
@@ -4627,6 +4597,29 @@ F: Documentation/networking/j1939.rst
F: include/uapi/linux/can/j1939.h
F: net/can/j1939/
+CANAAN/KENDRYTE K210 SOC FPIOA DRIVER
+M: Damien Le Moal <dlemoal@kernel.org>
+L: linux-riscv@lists.infradead.org
+L: linux-gpio@vger.kernel.org (pinctrl driver)
+F: Documentation/devicetree/bindings/pinctrl/canaan,k210-fpioa.yaml
+F: drivers/pinctrl/pinctrl-k210.c
+
+CANAAN/KENDRYTE K210 SOC RESET CONTROLLER DRIVER
+M: Damien Le Moal <dlemoal@kernel.org>
+L: linux-kernel@vger.kernel.org
+L: linux-riscv@lists.infradead.org
+S: Maintained
+F: Documentation/devicetree/bindings/reset/canaan,k210-rst.yaml
+F: drivers/reset/reset-k210.c
+
+CANAAN/KENDRYTE K210 SOC SYSTEM CONTROLLER DRIVER
+M: Damien Le Moal <dlemoal@kernel.org>
+L: linux-riscv@lists.infradead.org
+S: Maintained
+F: Documentation/devicetree/bindings/mfd/canaan,k210-sysctl.yaml
+F: drivers/soc/canaan/
+F: include/soc/canaan/
+
CAPABILITIES
M: Serge Hallyn <serge@hallyn.com>
L: linux-security-module@vger.kernel.org
@@ -4686,8 +4679,8 @@ F: arch/arm64/boot/dts/cavium/thunder2-99xx*
CBS/ETF/TAPRIO QDISCS
M: Vinicius Costa Gomes <vinicius.gomes@intel.com>
-S: Maintained
L: netdev@vger.kernel.org
+S: Maintained
F: net/sched/sch_cbs.c
F: net/sched/sch_etf.c
F: net/sched/sch_taprio.c
@@ -4710,10 +4703,10 @@ CCTRNG ARM TRUSTZONE CRYPTOCELL TRUE RANDOM NUMBER GENERATOR (TRNG) DRIVER
M: Hadar Gat <hadar.gat@arm.com>
L: linux-crypto@vger.kernel.org
S: Supported
+W: https://developer.arm.com/products/system-ip/trustzone-cryptocell/cryptocell-700-family
+F: Documentation/devicetree/bindings/rng/arm-cctrng.yaml
F: drivers/char/hw_random/cctrng.c
F: drivers/char/hw_random/cctrng.h
-F: Documentation/devicetree/bindings/rng/arm-cctrng.yaml
-W: https://developer.arm.com/products/system-ip/trustzone-cryptocell/cryptocell-700-family
CEC FRAMEWORK
M: Hans Verkuil <hverkuil-cisco@xs4all.nl>
@@ -4873,13 +4866,6 @@ S: Maintained
F: Documentation/devicetree/bindings/sound/google,cros-ec-codec.yaml
F: sound/soc/codecs/cros_ec_codec.*
-CHROMEOS EC UART DRIVER
-M: Bhanu Prakash Maiya <bhanumaiya@chromium.org>
-R: Benson Leung <bleung@chromium.org>
-R: Tzung-Bi Shih <tzungbi@kernel.org>
-S: Maintained
-F: drivers/platform/chrome/cros_ec_uart.c
-
CHROMEOS EC SUBDRIVERS
M: Benson Leung <bleung@chromium.org>
R: Guenter Roeck <groeck@chromium.org>
@@ -4889,13 +4875,12 @@ F: drivers/power/supply/cros_usbpd-charger.c
N: cros_ec
N: cros-ec
-CHROMEOS EC USB TYPE-C DRIVER
-M: Prashant Malani <pmalani@chromium.org>
-L: chrome-platform@lists.linux.dev
+CHROMEOS EC UART DRIVER
+M: Bhanu Prakash Maiya <bhanumaiya@chromium.org>
+R: Benson Leung <bleung@chromium.org>
+R: Tzung-Bi Shih <tzungbi@kernel.org>
S: Maintained
-F: drivers/platform/chrome/cros_ec_typec.*
-F: drivers/platform/chrome/cros_typec_switch.c
-F: drivers/platform/chrome/cros_typec_vdm.*
+F: drivers/platform/chrome/cros_ec_uart.c
CHROMEOS EC USB PD NOTIFY DRIVER
M: Prashant Malani <pmalani@chromium.org>
@@ -4904,6 +4889,14 @@ S: Maintained
F: drivers/platform/chrome/cros_usbpd_notify.c
F: include/linux/platform_data/cros_usbpd_notify.h
+CHROMEOS EC USB TYPE-C DRIVER
+M: Prashant Malani <pmalani@chromium.org>
+L: chrome-platform@lists.linux.dev
+S: Maintained
+F: drivers/platform/chrome/cros_ec_typec.*
+F: drivers/platform/chrome/cros_typec_switch.c
+F: drivers/platform/chrome/cros_typec_vdm.*
+
CHROMEOS HPS DRIVER
M: Dan Callaghan <dcallagh@chromium.org>
R: Sami Kyöstilä <skyostil@chromium.org>
@@ -5021,6 +5014,18 @@ M: Nelson Escobar <neescoba@cisco.com>
S: Supported
F: drivers/infiniband/hw/usnic/
+CLANG CONTROL FLOW INTEGRITY SUPPORT
+M: Sami Tolvanen <samitolvanen@google.com>
+M: Kees Cook <keescook@chromium.org>
+R: Nathan Chancellor <nathan@kernel.org>
+R: Nick Desaulniers <ndesaulniers@google.com>
+L: llvm@lists.linux.dev
+S: Supported
+B: https://github.com/ClangBuiltLinux/linux/issues
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening
+F: include/linux/cfi.h
+F: kernel/cfi.c
+
CLANG-FORMAT FILE
M: Miguel Ojeda <ojeda@kernel.org>
S: Maintained
@@ -5041,18 +5046,6 @@ F: scripts/Makefile.clang
F: scripts/clang-tools/
K: \b(?i:clang|llvm)\b
-CLANG CONTROL FLOW INTEGRITY SUPPORT
-M: Sami Tolvanen <samitolvanen@google.com>
-M: Kees Cook <keescook@chromium.org>
-R: Nathan Chancellor <nathan@kernel.org>
-R: Nick Desaulniers <ndesaulniers@google.com>
-L: llvm@lists.linux.dev
-S: Supported
-B: https://github.com/ClangBuiltLinux/linux/issues
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening
-F: include/linux/cfi.h
-F: kernel/cfi.c
-
CLK API
M: Russell King <linux@armlinux.org.uk>
L: linux-clk@vger.kernel.org
@@ -5223,8 +5216,8 @@ CONTEXT TRACKING
M: Frederic Weisbecker <frederic@kernel.org>
M: "Paul E. McKenney" <paulmck@kernel.org>
S: Maintained
-F: kernel/context_tracking.c
F: include/linux/context_tracking*
+F: kernel/context_tracking.c
CONTROL GROUP (CGROUP)
M: Tejun Heo <tj@kernel.org>
@@ -5385,8 +5378,8 @@ F: drivers/cpuidle/cpuidle-big_little.c
CPUIDLE DRIVER - ARM EXYNOS
M: Daniel Lezcano <daniel.lezcano@linaro.org>
-R: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
M: Kukjin Kim <kgene@kernel.org>
+R: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
L: linux-pm@vger.kernel.org
L: linux-samsung-soc@vger.kernel.org
S: Supported
@@ -5407,8 +5400,8 @@ M: Ulf Hansson <ulf.hansson@linaro.org>
L: linux-pm@vger.kernel.org
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Supported
-F: drivers/cpuidle/cpuidle-psci.h
F: drivers/cpuidle/cpuidle-psci-domain.c
+F: drivers/cpuidle/cpuidle-psci.h
CPUIDLE DRIVER - DT IDLE PM DOMAIN
M: Ulf Hansson <ulf.hansson@linaro.org>
@@ -5552,19 +5545,19 @@ S: Supported
W: http://www.chelsio.com
F: drivers/crypto/chelsio
-CXGB4 INLINE CRYPTO DRIVER
-M: Ayush Sawal <ayush.sawal@chelsio.com>
+CXGB4 ETHERNET DRIVER (CXGB4)
+M: Raju Rangoju <rajur@chelsio.com>
L: netdev@vger.kernel.org
S: Supported
W: http://www.chelsio.com
-F: drivers/net/ethernet/chelsio/inline_crypto/
+F: drivers/net/ethernet/chelsio/cxgb4/
-CXGB4 ETHERNET DRIVER (CXGB4)
-M: Raju Rangoju <rajur@chelsio.com>
+CXGB4 INLINE CRYPTO DRIVER
+M: Ayush Sawal <ayush.sawal@chelsio.com>
L: netdev@vger.kernel.org
S: Supported
W: http://www.chelsio.com
-F: drivers/net/ethernet/chelsio/cxgb4/
+F: drivers/net/ethernet/chelsio/inline_crypto/
CXGB4 ISCSI DRIVER (CXGB4I)
M: Varun Prakash <varun@chelsio.com>
@@ -5621,16 +5614,6 @@ CYCLADES PC300 DRIVER
S: Orphan
F: drivers/net/wan/pc300*
-CYPRESS_FIRMWARE MEDIA DRIVER
-M: Antti Palosaari <crope@iki.fi>
-L: linux-media@vger.kernel.org
-S: Maintained
-W: https://linuxtv.org
-W: http://palosaari.fi/linux/
-Q: http://patchwork.linuxtv.org/project/linux-media/list/
-T: git git://linuxtv.org/anttip/media_tree.git
-F: drivers/media/common/cypress_firmware*
-
CYPRESS CY8C95X0 PINCTRL DRIVER
M: Patrick Rudolph <patrick.rudolph@9elements.com>
L: linux-gpio@vger.kernel.org
@@ -5650,6 +5633,16 @@ S: Maintained
F: Documentation/devicetree/bindings/input/cypress-sf.yaml
F: drivers/input/keyboard/cypress-sf.c
+CYPRESS_FIRMWARE MEDIA DRIVER
+M: Antti Palosaari <crope@iki.fi>
+L: linux-media@vger.kernel.org
+S: Maintained
+W: https://linuxtv.org
+W: http://palosaari.fi/linux/
+Q: http://patchwork.linuxtv.org/project/linux-media/list/
+T: git git://linuxtv.org/anttip/media_tree.git
+F: drivers/media/common/cypress_firmware*
+
CYTTSP TOUCHSCREEN DRIVER
M: Linus Walleij <linus.walleij@linaro.org>
L: linux-input@vger.kernel.org
@@ -5816,11 +5809,6 @@ S: Maintained
F: Documentation/driver-api/dcdbas.rst
F: drivers/platform/x86/dell/dcdbas.*
-DELL WMI DESCRIPTOR DRIVER
-L: Dell.Client.Kernel@dell.com
-S: Maintained
-F: drivers/platform/x86/dell/dell-wmi-descriptor.c
-
DELL WMI DDV DRIVER
M: Armin Wolf <W_Armin@gmx.de>
S: Maintained
@@ -5828,13 +5816,17 @@ F: Documentation/ABI/testing/debugfs-dell-wmi-ddv
F: Documentation/ABI/testing/sysfs-platform-dell-wmi-ddv
F: drivers/platform/x86/dell/dell-wmi-ddv.c
-DELL WMI SYSMAN DRIVER
-M: Prasanth Ksr <prasanth.ksr@dell.com>
+DELL WMI DESCRIPTOR DRIVER
+L: Dell.Client.Kernel@dell.com
+S: Maintained
+F: drivers/platform/x86/dell/dell-wmi-descriptor.c
+
+DELL WMI HARDWARE PRIVACY SUPPORT
+M: Perry Yuan <Perry.Yuan@dell.com>
L: Dell.Client.Kernel@dell.com
L: platform-driver-x86@vger.kernel.org
S: Maintained
-F: Documentation/ABI/testing/sysfs-class-firmware-attributes
-F: drivers/platform/x86/dell/dell-wmi-sysman/
+F: drivers/platform/x86/dell/dell-wmi-privacy.c
DELL WMI NOTIFICATIONS DRIVER
M: Matthew Garrett <mjg59@srcf.ucam.org>
@@ -5842,20 +5834,13 @@ M: Pali Rohár <pali@kernel.org>
S: Maintained
F: drivers/platform/x86/dell/dell-wmi-base.c
-DELL WMI HARDWARE PRIVACY SUPPORT
-M: Perry Yuan <Perry.Yuan@dell.com>
+DELL WMI SYSMAN DRIVER
+M: Prasanth Ksr <prasanth.ksr@dell.com>
L: Dell.Client.Kernel@dell.com
L: platform-driver-x86@vger.kernel.org
S: Maintained
-F: drivers/platform/x86/dell/dell-wmi-privacy.c
-
-DELTA ST MEDIA DRIVER
-M: Hugues Fruchet <hugues.fruchet@foss.st.com>
-L: linux-media@vger.kernel.org
-S: Supported
-W: https://linuxtv.org
-T: git git://linuxtv.org/media_tree.git
-F: drivers/media/platform/st/sti/delta
+F: Documentation/ABI/testing/sysfs-class-firmware-attributes
+F: drivers/platform/x86/dell/dell-wmi-sysman/
DELTA AHE-50DC FAN CONTROL MODULE DRIVER
M: Zev Weiss <zev@bewilderbeest.net>
@@ -5879,6 +5864,14 @@ F: Documentation/devicetree/bindings/reset/delta,tn48m-reset.yaml
F: drivers/gpio/gpio-tn48m.c
F: include/dt-bindings/reset/delta,tn48m-reset.h
+DELTA ST MEDIA DRIVER
+M: Hugues Fruchet <hugues.fruchet@foss.st.com>
+L: linux-media@vger.kernel.org
+S: Supported
+W: https://linuxtv.org
+T: git git://linuxtv.org/media_tree.git
+F: drivers/media/platform/st/sti/delta
+
DENALI NAND DRIVER
L: linux-mtd@lists.infradead.org
S: Orphan
@@ -5891,13 +5884,6 @@ S: Maintained
F: drivers/dma/dw-edma/
F: include/linux/dma/edma.h
-DESIGNWARE XDATA IP DRIVER
-M: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
-L: linux-pci@vger.kernel.org
-S: Maintained
-F: Documentation/misc-devices/dw-xdata-pcie.rst
-F: drivers/misc/dw-xdata-pcie.c
-
DESIGNWARE USB2 DRD IP DRIVER
M: Minas Harutyunyan <hminas@synopsys.com>
L: linux-usb@vger.kernel.org
@@ -5911,6 +5897,13 @@ L: linux-usb@vger.kernel.org
S: Maintained
F: drivers/usb/dwc3/
+DESIGNWARE XDATA IP DRIVER
+M: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
+L: linux-pci@vger.kernel.org
+S: Maintained
+F: Documentation/misc-devices/dw-xdata-pcie.rst
+F: drivers/misc/dw-xdata-pcie.c
+
DEVANTECH SRF ULTRASONIC RANGER IIO DRIVER
M: Andreas Klinger <ak@it-klinger.de>
L: linux-iio@vger.kernel.org
@@ -6020,8 +6013,8 @@ F: Documentation/devicetree/bindings/input/da90??-onkey.txt
F: Documentation/devicetree/bindings/input/dlg,da72??.txt
F: Documentation/devicetree/bindings/mfd/da90*.txt
F: Documentation/devicetree/bindings/mfd/da90*.yaml
-F: Documentation/devicetree/bindings/regulator/dlg,da9*.yaml
F: Documentation/devicetree/bindings/regulator/da92*.txt
+F: Documentation/devicetree/bindings/regulator/dlg,da9*.yaml
F: Documentation/devicetree/bindings/regulator/slg51000.txt
F: Documentation/devicetree/bindings/sound/da[79]*.txt
F: Documentation/devicetree/bindings/thermal/da90??-thermal.txt
@@ -6140,6 +6133,12 @@ F: include/linux/dma/
F: include/linux/dmaengine.h
F: include/linux/of_dma.h
+DMA MAPPING BENCHMARK
+M: Xiang Chen <chenxiang66@hisilicon.com>
+L: iommu@lists.linux.dev
+F: kernel/dma/map_benchmark.c
+F: tools/testing/selftests/dma/
+
DMA MAPPING HELPERS
M: Christoph Hellwig <hch@lst.de>
M: Marek Szyprowski <m.szyprowski@samsung.com>
@@ -6150,17 +6149,11 @@ W: http://git.infradead.org/users/hch/dma-mapping.git
T: git git://git.infradead.org/users/hch/dma-mapping.git
F: include/asm-generic/dma-mapping.h
F: include/linux/dma-direct.h
-F: include/linux/dma-mapping.h
F: include/linux/dma-map-ops.h
+F: include/linux/dma-mapping.h
F: include/linux/swiotlb.h
F: kernel/dma/
-DMA MAPPING BENCHMARK
-M: Xiang Chen <chenxiang66@hisilicon.com>
-L: iommu@lists.linux.dev
-F: kernel/dma/map_benchmark.c
-F: tools/testing/selftests/dma/
-
DMA-BUF HEAPS FRAMEWORK
M: Sumit Semwal <sumit.semwal@linaro.org>
R: Benjamin Gaignard <benjamin.gaignard@collabora.com>
@@ -6350,6 +6343,25 @@ S: Maintained
F: drivers/soc/ti/smartreflex.c
F: include/linux/power/smartreflex.h
+DRM ACCEL DRIVERS FOR INTEL VPU
+M: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com>
+M: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
+L: dri-devel@lists.freedesktop.org
+S: Supported
+T: git git://anongit.freedesktop.org/drm/drm-misc
+F: drivers/accel/ivpu/
+F: include/uapi/drm/ivpu_accel.h
+
+DRM COMPUTE ACCELERATORS DRIVERS AND FRAMEWORK
+M: Oded Gabbay <ogabbay@kernel.org>
+L: dri-devel@lists.freedesktop.org
+S: Maintained
+C: irc://irc.oftc.net/dri-devel
+T: git https://git.kernel.org/pub/scm/linux/kernel/git/ogabbay/accel.git
+F: Documentation/accel/
+F: drivers/accel/
+F: include/drm/drm_accel.h
+
DRM DRIVER FOR ALLWINNER DE2 AND DE3 ENGINE
M: Maxime Ripard <mripard@kernel.org>
M: Chen-Yu Tsai <wens@csie.org>
@@ -6432,6 +6444,21 @@ S: Maintained
F: Documentation/devicetree/bindings/display/panel/feiyang,fy07024di26a30d.yaml
F: drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c
+DRM DRIVER FOR FIRMWARE FRAMEBUFFERS
+M: Thomas Zimmermann <tzimmermann@suse.de>
+M: Javier Martinez Canillas <javierm@redhat.com>
+L: dri-devel@lists.freedesktop.org
+S: Maintained
+T: git git://anongit.freedesktop.org/drm/drm-misc
+F: drivers/gpu/drm/drm_aperture.c
+F: drivers/gpu/drm/tiny/ofdrm.c
+F: drivers/gpu/drm/tiny/simpledrm.c
+F: drivers/video/aperture.c
+F: drivers/video/nomodeset.c
+F: include/drm/drm_aperture.h
+F: include/linux/aperture.h
+F: include/video/nomodeset.h
+
DRM DRIVER FOR GENERIC EDP PANELS
R: Douglas Anderson <dianders@chromium.org>
F: Documentation/devicetree/bindings/display/panel/panel-edp.yaml
@@ -6466,6 +6493,14 @@ T: git git://anongit.freedesktop.org/drm/drm-misc
F: Documentation/devicetree/bindings/display/himax,hx8357d.txt
F: drivers/gpu/drm/tiny/hx8357d.c
+DRM DRIVER FOR HYPERV SYNTHETIC VIDEO DEVICE
+M: Deepak Rawat <drawat.floss@gmail.com>
+L: linux-hyperv@vger.kernel.org
+L: dri-devel@lists.freedesktop.org
+S: Maintained
+T: git git://anongit.freedesktop.org/drm/drm-misc
+F: drivers/gpu/drm/hyperv
+
DRM DRIVER FOR ILITEK ILI9225 PANELS
M: David Lechner <david@lechnology.com>
S: Maintained
@@ -6495,11 +6530,11 @@ F: drivers/gpu/drm/logicvc/
DRM DRIVER FOR LVDS PANELS
M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
L: dri-devel@lists.freedesktop.org
-T: git git://anongit.freedesktop.org/drm/drm-misc
S: Maintained
-F: drivers/gpu/drm/panel/panel-lvds.c
+T: git git://anongit.freedesktop.org/drm/drm-misc
F: Documentation/devicetree/bindings/display/lvds.yaml
F: Documentation/devicetree/bindings/display/panel/panel-lvds.yaml
+F: drivers/gpu/drm/panel/panel-lvds.c
DRM DRIVER FOR MANTIX MLAF057WE51 PANELS
M: Guido Günther <agx@sigxcpu.org>
@@ -6608,13 +6643,6 @@ T: git git://anongit.freedesktop.org/drm/drm-misc
F: Documentation/devicetree/bindings/display/repaper.txt
F: drivers/gpu/drm/tiny/repaper.c
-DRM DRIVER FOR SOLOMON SSD130X OLED DISPLAYS
-M: Javier Martinez Canillas <javierm@redhat.com>
-S: Maintained
-T: git git://anongit.freedesktop.org/drm/drm-misc
-F: Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml
-F: drivers/gpu/drm/solomon/ssd130x*
-
DRM DRIVER FOR QEMU'S CIRRUS DEVICE
M: Dave Airlie <airlied@redhat.com>
M: Gerd Hoffmann <kraxel@redhat.com>
@@ -6663,28 +6691,11 @@ S: Maintained
F: Documentation/devicetree/bindings/display/panel/samsung,s6d27a1.yaml
F: drivers/gpu/drm/panel/panel-samsung-s6d27a1.c
-DRM DRIVER FOR SITRONIX ST7703 PANELS
-M: Guido Günther <agx@sigxcpu.org>
-R: Purism Kernel Team <kernel@puri.sm>
-R: Ondrej Jirman <megous@megous.com>
-S: Maintained
-F: Documentation/devicetree/bindings/display/panel/rocktech,jh057n00900.yaml
-F: drivers/gpu/drm/panel/panel-sitronix-st7703.c
-
-DRM DRIVER FOR FIRMWARE FRAMEBUFFERS
-M: Thomas Zimmermann <tzimmermann@suse.de>
-M: Javier Martinez Canillas <javierm@redhat.com>
-L: dri-devel@lists.freedesktop.org
+DRM DRIVER FOR SAMSUNG S6D7AA0 PANELS
+M: Artur Weber <aweber.kernel@gmail.com>
S: Maintained
-T: git git://anongit.freedesktop.org/drm/drm-misc
-F: drivers/gpu/drm/drm_aperture.c
-F: drivers/gpu/drm/tiny/ofdrm.c
-F: drivers/gpu/drm/tiny/simpledrm.c
-F: drivers/video/aperture.c
-F: drivers/video/nomodeset.c
-F: include/drm/drm_aperture.h
-F: include/linux/aperture.h
-F: include/video/nomodeset.h
+F: Documentation/devicetree/bindings/display/panel/samsung,s6d7aa0.yaml
+F: drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c
DRM DRIVER FOR SITRONIX ST7586 PANELS
M: David Lechner <david@lechnology.com>
@@ -6699,6 +6710,14 @@ S: Maintained
F: Documentation/devicetree/bindings/display/panel/sitronix,st7701.yaml
F: drivers/gpu/drm/panel/panel-sitronix-st7701.c
+DRM DRIVER FOR SITRONIX ST7703 PANELS
+M: Guido Günther <agx@sigxcpu.org>
+R: Purism Kernel Team <kernel@puri.sm>
+R: Ondrej Jirman <megous@megous.com>
+S: Maintained
+F: Documentation/devicetree/bindings/display/panel/rocktech,jh057n00900.yaml
+F: drivers/gpu/drm/panel/panel-sitronix-st7703.c
+
DRM DRIVER FOR SITRONIX ST7735R PANELS
M: David Lechner <david@lechnology.com>
S: Maintained
@@ -6706,6 +6725,13 @@ T: git git://anongit.freedesktop.org/drm/drm-misc
F: Documentation/devicetree/bindings/display/sitronix,st7735r.yaml
F: drivers/gpu/drm/tiny/st7735r.c
+DRM DRIVER FOR SOLOMON SSD130X OLED DISPLAYS
+M: Javier Martinez Canillas <javierm@redhat.com>
+S: Maintained
+T: git git://anongit.freedesktop.org/drm/drm-misc
+F: Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml
+F: drivers/gpu/drm/solomon/ssd130x*
+
DRM DRIVER FOR ST-ERICSSON MCDE
M: Linus Walleij <linus.walleij@linaro.org>
S: Maintained
@@ -6743,6 +6769,7 @@ F: drivers/gpu/drm/udl/
DRM DRIVER FOR VIRTUAL KERNEL MODESETTING (VKMS)
M: Rodrigo Siqueira <rodrigosiqueiramelo@gmail.com>
M: Melissa Wen <melissa.srw@gmail.com>
+M: Maíra Canal <mairacanal@riseup.net>
R: Haneen Mohammed <hamohammed.sa@gmail.com>
R: Daniel Vetter <daniel@ffwll.ch>
L: dri-devel@lists.freedesktop.org
@@ -6804,25 +6831,6 @@ F: include/drm/drm*
F: include/linux/vga*
F: include/uapi/drm/drm*
-DRM COMPUTE ACCELERATORS DRIVERS AND FRAMEWORK
-M: Oded Gabbay <ogabbay@kernel.org>
-L: dri-devel@lists.freedesktop.org
-S: Maintained
-C: irc://irc.oftc.net/dri-devel
-T: git https://git.kernel.org/pub/scm/linux/kernel/git/ogabbay/accel.git
-F: Documentation/accel/
-F: drivers/accel/
-F: include/drm/drm_accel.h
-
-DRM ACCEL DRIVERS FOR INTEL VPU
-M: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com>
-M: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
-L: dri-devel@lists.freedesktop.org
-S: Supported
-T: git git://anongit.freedesktop.org/drm/drm-misc
-F: drivers/accel/ivpu/
-F: include/uapi/drm/ivpu_accel.h
-
DRM DRIVERS FOR ALLWINNER A10
M: Maxime Ripard <mripard@kernel.org>
M: Chen-Yu Tsai <wens@csie.org>
@@ -6864,6 +6872,7 @@ S: Maintained
T: git git://anongit.freedesktop.org/drm/drm-misc
F: Documentation/devicetree/bindings/display/bridge/
F: drivers/gpu/drm/bridge/
+F: drivers/gpu/drm/drm_bridge.c
F: include/drm/drm_bridge.h
DRM DRIVERS FOR EXYNOS
@@ -6926,14 +6935,6 @@ T: git git://anongit.freedesktop.org/drm/drm-misc
F: Documentation/devicetree/bindings/display/hisilicon/
F: drivers/gpu/drm/hisilicon/
-DRM DRIVER FOR HYPERV SYNTHETIC VIDEO DEVICE
-M: Deepak Rawat <drawat.floss@gmail.com>
-L: linux-hyperv@vger.kernel.org
-L: dri-devel@lists.freedesktop.org
-S: Maintained
-T: git git://anongit.freedesktop.org/drm/drm-misc
-F: drivers/gpu/drm/hyperv
-
DRM DRIVERS FOR LIMA
M: Qiang Yu <yuq825@gmail.com>
L: dri-devel@lists.freedesktop.org
@@ -7085,6 +7086,14 @@ T: git git://anongit.freedesktop.org/drm/drm-misc
F: Documentation/devicetree/bindings/display/xlnx/
F: drivers/gpu/drm/xlnx/
+DRM GPU SCHEDULER
+M: Luben Tuikov <luben.tuikov@amd.com>
+L: dri-devel@lists.freedesktop.org
+S: Maintained
+T: git git://anongit.freedesktop.org/drm/drm-misc
+F: drivers/gpu/drm/scheduler/
+F: include/drm/gpu_scheduler.h
+
DRM PANEL DRIVERS
M: Neil Armstrong <neil.armstrong@linaro.org>
R: Sam Ravnborg <sam@ravnborg.org>
@@ -7113,14 +7122,6 @@ T: git git://anongit.freedesktop.org/drm/drm-misc
F: drivers/gpu/drm/ttm/
F: include/drm/ttm/
-DRM GPU SCHEDULER
-M: Luben Tuikov <luben.tuikov@amd.com>
-L: dri-devel@lists.freedesktop.org
-S: Maintained
-T: git git://anongit.freedesktop.org/drm/drm-misc
-F: drivers/gpu/drm/scheduler/
-F: include/drm/gpu_scheduler.h
-
DSBR100 USB FM RADIO DRIVER
M: Alexey Klimov <klimov.linux@gmail.com>
L: linux-media@vger.kernel.org
@@ -7248,10 +7249,10 @@ F: drivers/media/usb/dvb-usb-v2/usb_urb.c
DYNAMIC DEBUG
M: Jason Baron <jbaron@akamai.com>
+M: Jim Cromie <jim.cromie@gmail.com>
S: Maintained
F: include/linux/dynamic_debug.h
F: lib/dynamic_debug.c
-M: Jim Cromie <jim.cromie@gmail.com>
F: lib/test_dynamic_debug.c
DYNAMIC INTERRUPT MODERATION
@@ -7261,6 +7262,15 @@ F: Documentation/networking/net_dim.rst
F: include/linux/dim.h
F: lib/dim/
+DYNAMIC THERMAL POWER MANAGEMENT (DTPM)
+M: Daniel Lezcano <daniel.lezcano@kernel.org>
+L: linux-pm@vger.kernel.org
+S: Supported
+B: https://bugzilla.kernel.org
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
+F: drivers/powercap/dtpm*
+F: include/linux/dtpm.h
+
DZ DECSTATION DZ11 SERIAL DRIVER
M: "Maciej W. Rozycki" <macro@orcam.me.uk>
S: Maintained
@@ -7599,22 +7609,22 @@ W: http://www.broadcom.com
F: drivers/infiniband/hw/ocrdma/
F: include/uapi/rdma/ocrdma-abi.h
-EMULEX/BROADCOM LPFC FC/FCOE SCSI DRIVER
+EMULEX/BROADCOM EFCT FC/FCOE SCSI TARGET DRIVER
M: James Smart <james.smart@broadcom.com>
-M: Dick Kennedy <dick.kennedy@broadcom.com>
+M: Ram Vegesna <ram.vegesna@broadcom.com>
L: linux-scsi@vger.kernel.org
+L: target-devel@vger.kernel.org
S: Supported
W: http://www.broadcom.com
-F: drivers/scsi/lpfc/
+F: drivers/scsi/elx/
-EMULEX/BROADCOM EFCT FC/FCOE SCSI TARGET DRIVER
+EMULEX/BROADCOM LPFC FC/FCOE SCSI DRIVER
M: James Smart <james.smart@broadcom.com>
-M: Ram Vegesna <ram.vegesna@broadcom.com>
+M: Dick Kennedy <dick.kennedy@broadcom.com>
L: linux-scsi@vger.kernel.org
-L: target-devel@vger.kernel.org
S: Supported
W: http://www.broadcom.com
-F: drivers/scsi/elx/
+F: drivers/scsi/lpfc/
ENE CB710 FLASH CARD READER DRIVER
M: Michał Mirosław <mirq-linux@rere.qmqm.pl>
@@ -7707,8 +7717,8 @@ F: drivers/net/mdio/of_mdio.c
F: drivers/net/pcs/
F: drivers/net/phy/
F: include/dt-bindings/net/qca-ar803x.h
-F: include/linux/linkmode.h
F: include/linux/*mdio*.h
+F: include/linux/linkmode.h
F: include/linux/mdio/*.h
F: include/linux/mii.h
F: include/linux/of_net.h
@@ -7771,8 +7781,8 @@ M: Mimi Zohar <zohar@linux.ibm.com>
L: linux-integrity@vger.kernel.org
S: Supported
T: git git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity.git
-F: security/integrity/evm/
F: security/integrity/
+F: security/integrity/evm/
EXTENSIBLE FIRMWARE INTERFACE (EFI)
M: Ard Biesheuvel <ardb@kernel.org>
@@ -7803,8 +7813,8 @@ EXTRA BOOT CONFIG
M: Masami Hiramatsu <mhiramat@kernel.org>
L: linux-kernel@vger.kernel.org
L: linux-trace-kernel@vger.kernel.org
-Q: https://patchwork.kernel.org/project/linux-trace-kernel/list/
S: Maintained
+Q: https://patchwork.kernel.org/project/linux-trace-kernel/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace.git
F: Documentation/admin-guide/bootconfig.rst
F: fs/proc/bootconfig.c
@@ -8091,21 +8101,6 @@ F: Documentation/fpga/
F: drivers/fpga/
F: include/linux/fpga/
-INTEL MAX10 BMC SECURE UPDATES
-M: Russ Weight <russell.h.weight@intel.com>
-L: linux-fpga@vger.kernel.org
-S: Maintained
-F: Documentation/ABI/testing/sysfs-driver-intel-m10-bmc-sec-update
-F: drivers/fpga/intel-m10-bmc-sec-update.c
-
-MICROCHIP POLARFIRE FPGA DRIVERS
-M: Conor Dooley <conor.dooley@microchip.com>
-R: Ivan Bornyakov <i.bornyakov@metrotek.ru>
-L: linux-fpga@vger.kernel.org
-S: Supported
-F: Documentation/devicetree/bindings/fpga/microchip,mpf-spi-fpga-mgr.yaml
-F: drivers/fpga/microchip-spi.c
-
FPU EMULATOR
M: Bill Metzenthen <billm@melbpc.org.au>
S: Maintained
@@ -8114,9 +8109,9 @@ F: arch/x86/math-emu/
FRAMEBUFFER CORE
M: Daniel Vetter <daniel@ffwll.ch>
-F: drivers/video/fbdev/core/
S: Odd Fixes
T: git git://anongit.freedesktop.org/drm/drm-misc
+F: drivers/video/fbdev/core/
FRAMEBUFFER LAYER
M: Helge Deller <deller@gmx.de>
@@ -8493,15 +8488,15 @@ M: Masami Hiramatsu <mhiramat@kernel.org>
R: Mark Rutland <mark.rutland@arm.com>
L: linux-kernel@vger.kernel.org
L: linux-trace-kernel@vger.kernel.org
-Q: https://patchwork.kernel.org/project/linux-trace-kernel/list/
S: Maintained
+Q: https://patchwork.kernel.org/project/linux-trace-kernel/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace.git
F: Documentation/trace/ftrace*
-F: kernel/trace/ftrace*
-F: kernel/trace/fgraph.c
F: arch/*/*/*/*ftrace*
F: arch/*/*/*ftrace*
F: include/*/ftrace.h
+F: kernel/trace/fgraph.c
+F: kernel/trace/ftrace*
F: samples/ftrace
FUNGIBLE ETHERNET DRIVERS
@@ -8542,10 +8537,10 @@ GATEWORKS SYSTEM CONTROLLER (GSC) DRIVER
M: Tim Harvey <tharvey@gateworks.com>
S: Maintained
F: Documentation/devicetree/bindings/mfd/gateworks-gsc.yaml
-F: drivers/mfd/gateworks-gsc.c
-F: include/linux/mfd/gsc.h
F: Documentation/hwmon/gsc-hwmon.rst
F: drivers/hwmon/gsc-hwmon.c
+F: drivers/mfd/gateworks-gsc.c
+F: include/linux/mfd/gsc.h
F: include/linux/platform_data/gsc_hwmon.h
GCC PLUGINS
@@ -8673,8 +8668,8 @@ R: Andy Shevchenko <andy@kernel.org>
S: Maintained
F: lib/string.c
F: lib/string_helpers.c
-F: lib/test_string.c
F: lib/test-string_helpers.c
+F: lib/test_string.c
GENERIC UIO DRIVER FOR PCI DEVICES
M: "Michael S. Tsirkin" <mst@redhat.com>
@@ -9157,12 +9152,11 @@ L: linux-input@vger.kernel.org
S: Maintained
F: drivers/hid/hid-logitech-*
-HID++ LOGITECH DRIVERS
-R: Filipe Laíns <lains@riseup.net>
-R: Bastien Nocera <hadess@hadess.net>
+HID PHOENIX RC FLIGHT CONTROLLER
+M: Marcus Folkesson <marcus.folkesson@gmail.com>
L: linux-input@vger.kernel.org
S: Maintained
-F: drivers/hid/hid-logitech-hidpp.c
+F: drivers/hid/hid-pxrc.c
HID PLAYSTATION DRIVER
M: Roderick Colenbrander <roderick.colenbrander@sony.com>
@@ -9170,12 +9164,6 @@ L: linux-input@vger.kernel.org
S: Supported
F: drivers/hid/hid-playstation.c
-HID PHOENIX RC FLIGHT CONTROLLER
-M: Marcus Folkesson <marcus.folkesson@gmail.com>
-L: linux-input@vger.kernel.org
-S: Maintained
-F: drivers/hid/hid-pxrc.c
-
HID SENSOR HUB DRIVERS
M: Jiri Kosina <jikos@kernel.org>
M: Jonathan Cameron <jic23@kernel.org>
@@ -9202,6 +9190,13 @@ S: Maintained
F: drivers/hid/wacom.h
F: drivers/hid/wacom_*
+HID++ LOGITECH DRIVERS
+R: Filipe Laíns <lains@riseup.net>
+R: Bastien Nocera <hadess@hadess.net>
+L: linux-input@vger.kernel.org
+S: Maintained
+F: drivers/hid/hid-logitech-hidpp.c
+
HIGH-RESOLUTION TIMERS, CLOCKEVENTS
M: Thomas Gleixner <tglx@linutronix.de>
L: linux-kernel@vger.kernel.org
@@ -9226,6 +9221,12 @@ W: http://www.highpoint-tech.com
F: Documentation/scsi/hptiop.rst
F: drivers/scsi/hptiop.c
+HIKEY960 ONBOARD USB GPIO HUB DRIVER
+M: John Stultz <jstultz@google.com>
+L: linux-kernel@vger.kernel.org
+S: Maintained
+F: drivers/misc/hisi_hikey_usb.c
+
HIMAX HX83112B TOUCHSCREEN SUPPORT
M: Job Noorman <job@noorman.info>
L: linux-input@vger.kernel.org
@@ -9274,6 +9275,12 @@ F: drivers/crypto/hisilicon/hpre/hpre.h
F: drivers/crypto/hisilicon/hpre/hpre_crypto.c
F: drivers/crypto/hisilicon/hpre/hpre_main.c
+HISILICON HNS3 PMU DRIVER
+M: Guangbin Huang <huangguangbin2@huawei.com>
+S: Supported
+F: Documentation/admin-guide/perf/hns3-pmu.rst
+F: drivers/perf/hisilicon/hns3_pmu.c
+
HISILICON I2C CONTROLLER DRIVER
M: Yicong Yang <yangyicong@hisilicon.com>
L: linux-i2c@vger.kernel.org
@@ -9306,12 +9313,6 @@ W: http://www.hisilicon.com
F: Documentation/devicetree/bindings/net/hisilicon*.txt
F: drivers/net/ethernet/hisilicon/
-HIKEY960 ONBOARD USB GPIO HUB DRIVER
-M: John Stultz <jstultz@google.com>
-L: linux-kernel@vger.kernel.org
-S: Maintained
-F: drivers/misc/hisi_hikey_usb.c
-
HISILICON PMU DRIVER
M: Shaokun Zhang <zhangshaokun@hisilicon.com>
M: Jonathan Cameron <jonathan.cameron@huawei.com>
@@ -9321,12 +9322,6 @@ F: Documentation/admin-guide/perf/hisi-pcie-pmu.rst
F: Documentation/admin-guide/perf/hisi-pmu.rst
F: drivers/perf/hisilicon
-HISILICON HNS3 PMU DRIVER
-M: Guangbin Huang <huangguangbin2@huawei.com>
-S: Supported
-F: Documentation/admin-guide/perf/hns3-pmu.rst
-F: drivers/perf/hisilicon/hns3_pmu.c
-
HISILICON PTT DRIVER
M: Yicong Yang <yangyicong@hisilicon.com>
M: Jonathan Cameron <jonathan.cameron@huawei.com>
@@ -9350,14 +9345,6 @@ F: drivers/crypto/hisilicon/qm.c
F: drivers/crypto/hisilicon/sgl.c
F: include/linux/hisi_acc_qm.h
-HISILICON ZIP Controller DRIVER
-M: Yang Shen <shenyang39@huawei.com>
-M: Zhou Wang <wangzhou1@hisilicon.com>
-L: linux-crypto@vger.kernel.org
-S: Maintained
-F: Documentation/ABI/testing/debugfs-hisi-zip
-F: drivers/crypto/hisilicon/zip/
-
HISILICON ROCE DRIVER
M: Haoyue Xu <xuhaoyue1@hisilicon.com>
M: Wenpeng Liang <liangwenpeng@huawei.com>
@@ -9416,6 +9403,14 @@ S: Maintained
W: http://www.hisilicon.com
F: drivers/spi/spi-hisi-sfc-v3xx.c
+HISILICON ZIP Controller DRIVER
+M: Yang Shen <shenyang39@huawei.com>
+M: Zhou Wang <wangzhou1@hisilicon.com>
+L: linux-crypto@vger.kernel.org
+S: Maintained
+F: Documentation/ABI/testing/debugfs-hisi-zip
+F: drivers/crypto/hisilicon/zip/
+
HMM - Heterogeneous Memory Management
M: Jérôme Glisse <jglisse@redhat.com>
L: linux-mm@kvack.org
@@ -9492,9 +9487,9 @@ F: drivers/input/touchscreen/htcpen.c
HTE SUBSYSTEM
M: Dipen Patel <dipenp@nvidia.com>
L: timestamp@lists.linux.dev
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/pateldipen1984/linux.git
-Q: https://patchwork.kernel.org/project/timestamp/list/
S: Maintained
+Q: https://patchwork.kernel.org/project/timestamp/list/
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/pateldipen1984/linux.git
F: Documentation/devicetree/bindings/timestamp/
F: Documentation/driver-api/hte/
F: drivers/hte/
@@ -9589,8 +9584,8 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux.git
F: Documentation/ABI/stable/sysfs-bus-vmbus
F: Documentation/ABI/testing/debugfs-hyperv
F: Documentation/devicetree/bindings/bus/microsoft,vmbus.yaml
-F: Documentation/virt/hyperv
F: Documentation/networking/device_drivers/ethernet/microsoft/netvsc.rst
+F: Documentation/virt/hyperv
F: arch/arm64/hyperv
F: arch/arm64/include/asm/hyperv-tlfs.h
F: arch/arm64/include/asm/mshyperv.h
@@ -9772,6 +9767,12 @@ L: linux-i2c@vger.kernel.org
S: Maintained
F: drivers/i2c/i2c-stub.c
+I3C DRIVER FOR ASPEED AST2600
+M: Jeremy Kerr <jk@codeconstruct.com.au>
+S: Maintained
+F: Documentation/devicetree/bindings/i3c/aspeed,ast2600-i3c.yaml
+F: drivers/i3c/master/ast2600-i3c-master.c
+
I3C DRIVER FOR CADENCE I3C MASTER IP
M: Przemysław Gaj <pgaj@cadence.com>
S: Maintained
@@ -9783,12 +9784,6 @@ S: Orphan
F: Documentation/devicetree/bindings/i3c/snps,dw-i3c-master.yaml
F: drivers/i3c/master/dw*
-I3C DRIVER FOR ASPEED AST2600
-M: Jeremy Kerr <jk@codeconstruct.com.au>
-S: Maintained
-F: Documentation/devicetree/bindings/i3c/aspeed,ast2600-i3c.yaml
-F: drivers/i3c/master/ast2600-i3c-master.c
-
I3C SUBSYSTEM
M: Alexandre Belloni <alexandre.belloni@bootlin.com>
L: linux-i3c@lists.infradead.org (moderated for non-subscribers)
@@ -9867,6 +9862,11 @@ L: netdev@vger.kernel.org
S: Supported
F: drivers/net/ethernet/ibm/ibmvnic.*
+IBM Power VFIO Support
+M: Timothy Pearson <tpearson@raptorengineering.com>
+S: Supported
+F: drivers/vfio/vfio_iommu_spapr_tce.c
+
IBM Power Virtual Ethernet Device Driver
M: Nick Child <nnac123@linux.ibm.com>
L: netdev@vger.kernel.org
@@ -9912,11 +9912,6 @@ F: drivers/crypto/vmx/ghash*
F: drivers/crypto/vmx/ppc-xlate.pl
F: drivers/crypto/vmx/vmx.c
-IBM Power VFIO Support
-M: Timothy Pearson <tpearson@raptorengineering.com>
-S: Supported
-F: drivers/vfio/vfio_iommu_spapr_tce.c
-
IBM ServeRAID RAID DRIVER
S: Orphan
F: drivers/scsi/ips.*
@@ -9984,6 +9979,10 @@ F: include/net/nl802154.h
F: net/ieee802154/
F: net/mac802154/
+IFCVF VIRTIO DATA PATH ACCELERATOR
+R: Zhu Lingshan <lingshan.zhu@intel.com>
+F: drivers/vdpa/ifcvf/
+
IFE PROTOCOL
M: Yotam Gigi <yotam.gi@gmail.com>
M: Jamal Hadi Salim <jhs@mojatatu.com>
@@ -10248,8 +10247,8 @@ M: Dmitry Kasatkin <dmitry.kasatkin@gmail.com>
L: linux-integrity@vger.kernel.org
S: Supported
T: git git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity.git
-F: security/integrity/ima/
F: security/integrity/
+F: security/integrity/ima/
INTEL 810/815 FRAMEBUFFER DRIVER
M: Antonino Daplas <adaplas@gmail.com>
@@ -10403,14 +10402,6 @@ S: Supported
Q: https://patchwork.kernel.org/project/linux-dmaengine/list/
F: drivers/dma/ioat*
-INTEL IDXD DRIVER
-M: Fenghua Yu <fenghua.yu@intel.com>
-M: Dave Jiang <dave.jiang@intel.com>
-L: dmaengine@vger.kernel.org
-S: Supported
-F: drivers/dma/idxd/*
-F: include/uapi/linux/idxd.h
-
INTEL IDLE DRIVER
M: Jacob Pan <jacob.jun.pan@linux.intel.com>
M: Len Brown <lenb@kernel.org>
@@ -10420,6 +10411,14 @@ B: https://bugzilla.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux.git
F: drivers/idle/intel_idle.c
+INTEL IDXD DRIVER
+M: Fenghua Yu <fenghua.yu@intel.com>
+M: Dave Jiang <dave.jiang@intel.com>
+L: dmaengine@vger.kernel.org
+S: Supported
+F: drivers/dma/idxd/*
+F: include/uapi/linux/idxd.h
+
INTEL IN FIELD SCAN (IFS) DEVICE
M: Jithu Joseph <jithu.joseph@intel.com>
R: Ashok Raj <ashok.raj@intel.com>
@@ -10466,18 +10465,18 @@ F: Documentation/admin-guide/media/ipu3_rcb.svg
F: Documentation/userspace-api/media/v4l/pixfmt-meta-intel-ipu3.rst
F: drivers/staging/media/ipu3/
-INTEL IXP4XX CRYPTO SUPPORT
-M: Corentin Labbe <clabbe@baylibre.com>
-L: linux-crypto@vger.kernel.org
-S: Maintained
-F: drivers/crypto/intel/ixp4xx/ixp4xx_crypto.c
-
INTEL ISHTP ECLITE DRIVER
M: Sumesh K Naduvalath <sumesh.k.naduvalath@intel.com>
L: platform-driver-x86@vger.kernel.org
S: Supported
F: drivers/platform/x86/intel/ishtp_eclite.c
+INTEL IXP4XX CRYPTO SUPPORT
+M: Corentin Labbe <clabbe@baylibre.com>
+L: linux-crypto@vger.kernel.org
+S: Maintained
+F: drivers/crypto/intel/ixp4xx/ixp4xx_crypto.c
+
INTEL IXP4XX QMGR, NPE, ETHERNET and HSS SUPPORT
M: Krzysztof Halasa <khalasa@piap.pl>
S: Maintained
@@ -10556,6 +10555,13 @@ F: drivers/hwmon/intel-m10-bmc-hwmon.c
F: drivers/mfd/intel-m10-bmc*
F: include/linux/mfd/intel-m10-bmc.h
+INTEL MAX10 BMC SECURE UPDATES
+M: Russ Weight <russell.h.weight@intel.com>
+L: linux-fpga@vger.kernel.org
+S: Maintained
+F: Documentation/ABI/testing/sysfs-driver-intel-m10-bmc-sec-update
+F: drivers/fpga/intel-m10-bmc-sec-update.c
+
INTEL P-Unit IPC DRIVER
M: Zha Qipeng <qipeng.zha@intel.com>
L: platform-driver-x86@vger.kernel.org
@@ -10603,6 +10609,13 @@ L: linux-pm@vger.kernel.org
S: Supported
F: drivers/cpufreq/intel_pstate.c
+INTEL PTP DFL ToD DRIVER
+M: Tianfei Zhang <tianfei.zhang@intel.com>
+L: linux-fpga@vger.kernel.org
+L: netdev@vger.kernel.org
+S: Maintained
+F: drivers/ptp/ptp_dfl_tod.c
+
INTEL QUADRATURE ENCODER PERIPHERAL DRIVER
M: Jarkko Nikula <jarkko.nikula@linux.intel.com>
L: linux-iio@vger.kernel.org
@@ -10621,6 +10634,21 @@ F: drivers/platform/x86/intel/sdsi.c
F: tools/arch/x86/intel_sdsi/
F: tools/testing/selftests/drivers/sdsi/
+INTEL SGX
+M: Jarkko Sakkinen <jarkko@kernel.org>
+R: Dave Hansen <dave.hansen@linux.intel.com>
+L: linux-sgx@vger.kernel.org
+S: Supported
+Q: https://patchwork.kernel.org/project/intel-sgx/list/
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86/sgx
+F: Documentation/arch/x86/sgx.rst
+F: arch/x86/entry/vdso/vsgx.S
+F: arch/x86/include/asm/sgx.h
+F: arch/x86/include/uapi/asm/sgx.h
+F: arch/x86/kernel/cpu/sgx/*
+F: tools/testing/selftests/sgx/*
+K: \bSGX_
+
INTEL SKYLAKE INT3472 ACPI DEVICE DRIVER
M: Daniel Scally <djrscally@gmail.com>
S: Maintained
@@ -10638,13 +10666,13 @@ INTEL STRATIX10 FIRMWARE DRIVERS
M: Dinh Nguyen <dinguyen@kernel.org>
L: linux-kernel@vger.kernel.org
S: Maintained
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/dinguyen/linux.git
F: Documentation/ABI/testing/sysfs-devices-platform-stratix10-rsu
F: Documentation/devicetree/bindings/firmware/intel,stratix10-svc.txt
F: drivers/firmware/stratix10-rsu.c
F: drivers/firmware/stratix10-svc.c
F: include/linux/firmware/intel/stratix10-smc.h
F: include/linux/firmware/intel/stratix10-svc-client.h
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/dinguyen/linux.git
INTEL TELEMETRY DRIVER
M: Rajneesh Bhardwaj <irenic.rajneesh@gmail.com>
@@ -10729,21 +10757,6 @@ F: Documentation/arch/x86/intel_txt.rst
F: arch/x86/kernel/tboot.c
F: include/linux/tboot.h
-INTEL SGX
-M: Jarkko Sakkinen <jarkko@kernel.org>
-R: Dave Hansen <dave.hansen@linux.intel.com>
-L: linux-sgx@vger.kernel.org
-S: Supported
-Q: https://patchwork.kernel.org/project/intel-sgx/list/
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86/sgx
-F: Documentation/arch/x86/sgx.rst
-F: arch/x86/entry/vdso/vsgx.S
-F: arch/x86/include/asm/sgx.h
-F: arch/x86/include/uapi/asm/sgx.h
-F: arch/x86/kernel/cpu/sgx/*
-F: tools/testing/selftests/sgx/*
-K: \bSGX_
-
INTERCONNECT API
M: Georgi Djakov <djakov@kernel.org>
L: linux-pm@vger.kernel.org
@@ -10812,18 +10825,6 @@ F: drivers/iommu/dma-iommu.h
F: drivers/iommu/iova.c
F: include/linux/iova.h
-IOMMUFD
-M: Jason Gunthorpe <jgg@nvidia.com>
-M: Kevin Tian <kevin.tian@intel.com>
-L: iommu@lists.linux.dev
-S: Maintained
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/jgg/iommufd.git
-F: Documentation/userspace-api/iommufd.rst
-F: drivers/iommu/iommufd/
-F: include/linux/iommufd.h
-F: include/uapi/linux/iommufd.h
-F: tools/testing/selftests/iommu/
-
IOMMU SUBSYSTEM
M: Joerg Roedel <joro@8bytes.org>
M: Will Deacon <will@kernel.org>
@@ -10839,6 +10840,18 @@ F: include/linux/iova.h
F: include/linux/of_iommu.h
F: include/uapi/linux/iommu.h
+IOMMUFD
+M: Jason Gunthorpe <jgg@nvidia.com>
+M: Kevin Tian <kevin.tian@intel.com>
+L: iommu@lists.linux.dev
+S: Maintained
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/jgg/iommufd.git
+F: Documentation/userspace-api/iommufd.rst
+F: drivers/iommu/iommufd/
+F: include/linux/iommufd.h
+F: include/uapi/linux/iommufd.h
+F: tools/testing/selftests/iommu/
+
IOSYS-MAP HELPERS
M: Thomas Zimmermann <tzimmermann@suse.de>
L: dri-devel@lists.freedesktop.org
@@ -10853,11 +10866,11 @@ L: io-uring@vger.kernel.org
S: Maintained
T: git git://git.kernel.dk/linux-block
T: git git://git.kernel.dk/liburing
-F: io_uring/
F: include/linux/io_uring.h
F: include/linux/io_uring_types.h
F: include/trace/events/io_uring.h
F: include/uapi/linux/io_uring.h
+F: io_uring/
F: tools/io_uring/
IPMI SUBSYSTEM
@@ -10866,8 +10879,8 @@ L: openipmi-developer@lists.sourceforge.net (moderated for non-subscribers)
S: Supported
W: http://openipmi.sourceforge.net/
T: git https://github.com/cminyard/linux-ipmi.git for-next
-F: Documentation/driver-api/ipmi.rst
F: Documentation/devicetree/bindings/ipmi/
+F: Documentation/driver-api/ipmi.rst
F: drivers/char/ipmi/
F: include/linux/ipmi*
F: include/uapi/linux/ipmi*
@@ -10919,8 +10932,8 @@ M: Thomas Gleixner <tglx@linutronix.de>
L: linux-kernel@vger.kernel.org
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq/core
-F: kernel/irq/
F: include/linux/group_cpus.h
+F: kernel/irq/
F: lib/group_cpus.c
IRQCHIP DRIVERS
@@ -11258,6 +11271,7 @@ L: linux-nfs@vger.kernel.org
S: Supported
W: http://nfs.sourceforge.net/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux.git
+F: Documentation/filesystems/nfs/
F: fs/exportfs/
F: fs/lockd/
F: fs/nfs_common/
@@ -11273,7 +11287,6 @@ F: include/trace/misc/sunrpc.h
F: include/uapi/linux/nfsd/
F: include/uapi/linux/sunrpc/
F: net/sunrpc/
-F: Documentation/filesystems/nfs/
KERNEL REGRESSIONS
M: Thorsten Leemhuis <linux@leemhuis.info>
@@ -11425,47 +11438,6 @@ F: arch/x86/include/uapi/asm/vmx.h
F: arch/x86/kvm/
F: arch/x86/kvm/*/
-KVM PARAVIRT (KVM/paravirt)
-M: Paolo Bonzini <pbonzini@redhat.com>
-R: Wanpeng Li <wanpengli@tencent.com>
-R: Vitaly Kuznetsov <vkuznets@redhat.com>
-L: kvm@vger.kernel.org
-S: Supported
-T: git git://git.kernel.org/pub/scm/virt/kvm/kvm.git
-F: arch/x86/kernel/kvm.c
-F: arch/x86/kernel/kvmclock.c
-F: arch/x86/include/asm/pvclock-abi.h
-F: include/linux/kvm_para.h
-F: include/uapi/linux/kvm_para.h
-F: include/uapi/asm-generic/kvm_para.h
-F: include/asm-generic/kvm_para.h
-F: arch/um/include/asm/kvm_para.h
-F: arch/x86/include/asm/kvm_para.h
-F: arch/x86/include/uapi/asm/kvm_para.h
-
-KVM X86 HYPER-V (KVM/hyper-v)
-M: Vitaly Kuznetsov <vkuznets@redhat.com>
-M: Sean Christopherson <seanjc@google.com>
-M: Paolo Bonzini <pbonzini@redhat.com>
-L: kvm@vger.kernel.org
-S: Supported
-T: git git://git.kernel.org/pub/scm/virt/kvm/kvm.git
-F: arch/x86/kvm/hyperv.*
-F: arch/x86/kvm/kvm_onhyperv.*
-F: arch/x86/kvm/svm/hyperv.*
-F: arch/x86/kvm/svm/svm_onhyperv.*
-F: arch/x86/kvm/vmx/hyperv.*
-
-KVM X86 Xen (KVM/Xen)
-M: David Woodhouse <dwmw2@infradead.org>
-M: Paul Durrant <paul@xen.org>
-M: Sean Christopherson <seanjc@google.com>
-M: Paolo Bonzini <pbonzini@redhat.com>
-L: kvm@vger.kernel.org
-S: Supported
-T: git git://git.kernel.org/pub/scm/virt/kvm/kvm.git
-F: arch/x86/kvm/xen.*
-
KERNFS
M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
M: Tejun Heo <tj@kernel.org>
@@ -11504,14 +11476,6 @@ F: include/keys/trusted-type.h
F: include/keys/trusted_tpm.h
F: security/keys/trusted-keys/
-KEYS-TRUSTED-TEE
-M: Sumit Garg <sumit.garg@linaro.org>
-L: linux-integrity@vger.kernel.org
-L: keyrings@vger.kernel.org
-S: Supported
-F: include/keys/trusted_tee.h
-F: security/keys/trusted-keys/trusted_tee.c
-
KEYS-TRUSTED-CAAM
M: Ahmad Fatoum <a.fatoum@pengutronix.de>
R: Pengutronix Kernel Team <kernel@pengutronix.de>
@@ -11521,6 +11485,14 @@ S: Maintained
F: include/keys/trusted_caam.h
F: security/keys/trusted-keys/trusted_caam.c
+KEYS-TRUSTED-TEE
+M: Sumit Garg <sumit.garg@linaro.org>
+L: linux-integrity@vger.kernel.org
+L: keyrings@vger.kernel.org
+S: Supported
+F: include/keys/trusted_tee.h
+F: security/keys/trusted-keys/trusted_tee.c
+
KEYS/KEYRINGS
M: David Howells <dhowells@redhat.com>
M: Jarkko Sakkinen <jarkko@kernel.org>
@@ -11583,8 +11555,8 @@ L: linux-amlogic@lists.infradead.org
S: Maintained
F: Documentation/devicetree/bindings/mfd/khadas,mcu.yaml
F: drivers/mfd/khadas-mcu.c
-F: include/linux/mfd/khadas-mcu.h
F: drivers/thermal/khadas_mcu_fan.c
+F: include/linux/mfd/khadas-mcu.h
KIONIX/ROHM KX022A ACCELEROMETER
M: Matti Vaittinen <mazziesaccount@gmail.com>
@@ -11621,8 +11593,8 @@ M: "David S. Miller" <davem@davemloft.net>
M: Masami Hiramatsu <mhiramat@kernel.org>
L: linux-kernel@vger.kernel.org
L: linux-trace-kernel@vger.kernel.org
-Q: https://patchwork.kernel.org/project/linux-trace-kernel/list/
S: Maintained
+Q: https://patchwork.kernel.org/project/linux-trace-kernel/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace.git
F: Documentation/trace/kprobes.rst
F: include/asm-generic/kprobes.h
@@ -11656,6 +11628,47 @@ S: Maintained
F: Documentation/devicetree/bindings/leds/backlight/kinetic,ktz8866.yaml
F: drivers/video/backlight/ktz8866.c
+KVM PARAVIRT (KVM/paravirt)
+M: Paolo Bonzini <pbonzini@redhat.com>
+R: Wanpeng Li <wanpengli@tencent.com>
+R: Vitaly Kuznetsov <vkuznets@redhat.com>
+L: kvm@vger.kernel.org
+S: Supported
+T: git git://git.kernel.org/pub/scm/virt/kvm/kvm.git
+F: arch/um/include/asm/kvm_para.h
+F: arch/x86/include/asm/kvm_para.h
+F: arch/x86/include/asm/pvclock-abi.h
+F: arch/x86/include/uapi/asm/kvm_para.h
+F: arch/x86/kernel/kvm.c
+F: arch/x86/kernel/kvmclock.c
+F: include/asm-generic/kvm_para.h
+F: include/linux/kvm_para.h
+F: include/uapi/asm-generic/kvm_para.h
+F: include/uapi/linux/kvm_para.h
+
+KVM X86 HYPER-V (KVM/hyper-v)
+M: Vitaly Kuznetsov <vkuznets@redhat.com>
+M: Sean Christopherson <seanjc@google.com>
+M: Paolo Bonzini <pbonzini@redhat.com>
+L: kvm@vger.kernel.org
+S: Supported
+T: git git://git.kernel.org/pub/scm/virt/kvm/kvm.git
+F: arch/x86/kvm/hyperv.*
+F: arch/x86/kvm/kvm_onhyperv.*
+F: arch/x86/kvm/svm/hyperv.*
+F: arch/x86/kvm/svm/svm_onhyperv.*
+F: arch/x86/kvm/vmx/hyperv.*
+
+KVM X86 Xen (KVM/Xen)
+M: David Woodhouse <dwmw2@infradead.org>
+M: Paul Durrant <paul@xen.org>
+M: Sean Christopherson <seanjc@google.com>
+M: Paolo Bonzini <pbonzini@redhat.com>
+L: kvm@vger.kernel.org
+S: Supported
+T: git git://git.kernel.org/pub/scm/virt/kvm/kvm.git
+F: arch/x86/kvm/xen.*
+
L3MDEV
M: David Ahern <dsahern@kernel.org>
L: netdev@vger.kernel.org
@@ -11897,9 +11910,9 @@ F: scripts/spdxexclude
LINEAR RANGES HELPERS
M: Mark Brown <broonie@kernel.org>
R: Matti Vaittinen <mazziesaccount@gmail.com>
+F: include/linux/linear_range.h
F: lib/linear_ranges.c
F: lib/test_linear_ranges.c
-F: include/linux/linear_range.h
LINUX FOR POWER MACINTOSH
M: Benjamin Herrenschmidt <benh@kernel.crashing.org>
@@ -12026,11 +12039,11 @@ M: Joel Stanley <joel@jms.id.au>
S: Maintained
F: Documentation/devicetree/bindings/*/litex,*.yaml
F: arch/openrisc/boot/dts/or1klitex.dts
-F: include/linux/litex.h
-F: drivers/tty/serial/liteuart.c
-F: drivers/soc/litex/*
-F: drivers/net/ethernet/litex/*
F: drivers/mmc/host/litex_mmc.c
+F: drivers/net/ethernet/litex/*
+F: drivers/soc/litex/*
+F: drivers/tty/serial/liteuart.c
+F: include/linux/litex.h
N: litex
LIVE PATCHING
@@ -12159,10 +12172,17 @@ R: WANG Xuerui <kernel@xen0n.name>
L: loongarch@lists.linux.dev
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson.git
-F: arch/loongarch/
-F: drivers/*/*loongarch*
F: Documentation/loongarch/
F: Documentation/translations/zh_CN/loongarch/
+F: arch/loongarch/
+F: drivers/*/*loongarch*
+
+LOONGSON GPIO DRIVER
+M: Yinbo Zhu <zhuyinbo@loongson.cn>
+L: linux-gpio@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/gpio/loongson,ls-gpio.yaml
+F: drivers/gpio/gpio-loongson-64bit.c
LOONGSON LS2X I2C DRIVER
M: Binbin Zhou <zhoubinbin@loongson.cn>
@@ -12171,6 +12191,14 @@ S: Maintained
F: Documentation/devicetree/bindings/i2c/loongson,ls2x-i2c.yaml
F: drivers/i2c/busses/i2c-ls2x.c
+LOONGSON-2 SOC SERIES CLOCK DRIVER
+M: Yinbo Zhu <zhuyinbo@loongson.cn>
+L: linux-clk@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/clock/loongson,ls2k-clk.yaml
+F: drivers/clk/clk-loongson2.c
+F: include/dt-bindings/clock/loongson,ls2k-clk.h
+
LOONGSON-2 SOC SERIES GUTS DRIVER
M: Yinbo Zhu <zhuyinbo@loongson.cn>
L: loongarch@lists.linux.dev
@@ -12186,21 +12214,6 @@ S: Maintained
F: Documentation/devicetree/bindings/pinctrl/loongson,ls2k-pinctrl.yaml
F: drivers/pinctrl/pinctrl-loongson2.c
-LOONGSON GPIO DRIVER
-M: Yinbo Zhu <zhuyinbo@loongson.cn>
-L: linux-gpio@vger.kernel.org
-S: Maintained
-F: Documentation/devicetree/bindings/gpio/loongson,ls-gpio.yaml
-F: drivers/gpio/gpio-loongson-64bit.c
-
-LOONGSON-2 SOC SERIES CLOCK DRIVER
-M: Yinbo Zhu <zhuyinbo@loongson.cn>
-L: linux-clk@vger.kernel.org
-S: Maintained
-F: Documentation/devicetree/bindings/clock/loongson,ls2k-clk.yaml
-F: drivers/clk/clk-loongson2.c
-F: include/dt-bindings/clock/loongson,ls2k-clk.h
-
LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI)
M: Sathya Prakash <sathya.prakash@broadcom.com>
M: Sreekanth Reddy <sreekanth.reddy@broadcom.com>
@@ -12361,20 +12374,26 @@ MAILBOX API
M: Jassi Brar <jassisinghbrar@gmail.com>
L: linux-kernel@vger.kernel.org
S: Maintained
+F: Documentation/devicetree/bindings/mailbox/
F: drivers/mailbox/
+F: include/dt-bindings/mailbox/
F: include/linux/mailbox_client.h
F: include/linux/mailbox_controller.h
-F: include/dt-bindings/mailbox/
-F: Documentation/devicetree/bindings/mailbox/
MAILBOX ARM MHUv2
M: Viresh Kumar <viresh.kumar@linaro.org>
M: Tushar Khandelwal <Tushar.Khandelwal@arm.com>
L: linux-kernel@vger.kernel.org
S: Maintained
+F: Documentation/devicetree/bindings/mailbox/arm,mhuv2.yaml
F: drivers/mailbox/arm_mhuv2.c
F: include/linux/mailbox/arm_mhuv2_message.h
-F: Documentation/devicetree/bindings/mailbox/arm,mhuv2.yaml
+
+MAN-PAGES: MANUAL PAGES FOR LINUX -- Sections 2, 3, 4, 5, and 7
+M: Michael Kerrisk <mtk.manpages@gmail.com>
+L: linux-man@vger.kernel.org
+S: Maintained
+W: http://www.kernel.org/doc/man-pages
MANAGEMENT COMPONENT TRANSPORT PROTOCOL (MCTP)
M: Jeremy Kerr <jk@codeconstruct.com.au>
@@ -12388,12 +12407,6 @@ F: include/net/mctpdevice.h
F: include/net/netns/mctp.h
F: net/mctp/
-MAN-PAGES: MANUAL PAGES FOR LINUX -- Sections 2, 3, 4, 5, and 7
-M: Michael Kerrisk <mtk.manpages@gmail.com>
-L: linux-man@vger.kernel.org
-S: Maintained
-W: http://www.kernel.org/doc/man-pages
-
MAPLE TREE
M: Liam R. Howlett <Liam.Howlett@oracle.com>
L: linux-mm@kvack.org
@@ -12425,8 +12438,8 @@ F: include/linux/platform_data/mv88e6xxx.h
MARVELL ARMADA 3700 PHY DRIVERS
M: Miquel Raynal <miquel.raynal@bootlin.com>
S: Maintained
-F: Documentation/devicetree/bindings/phy/phy-mvebu-comphy.txt
F: Documentation/devicetree/bindings/phy/marvell,armada-3700-utmi-phy.yaml
+F: Documentation/devicetree/bindings/phy/phy-mvebu-comphy.txt
F: drivers/phy/marvell/phy-mvebu-a3700-comphy.c
F: drivers/phy/marvell/phy-mvebu-a3700-utmi.c
@@ -12528,6 +12541,13 @@ S: Maintained
F: Documentation/devicetree/bindings/mtd/marvell-nand.txt
F: drivers/mtd/nand/raw/marvell_nand.c
+MARVELL OCTEON ENDPOINT DRIVER
+M: Veerasenareddy Burru <vburru@marvell.com>
+M: Abhijit Ayarekar <aayarekar@marvell.com>
+L: netdev@vger.kernel.org
+S: Supported
+F: drivers/net/ethernet/marvell/octeon_ep
+
MARVELL OCTEONTX2 PHYSICAL FUNCTION DRIVER
M: Sunil Goutham <sgoutham@marvell.com>
M: Geetha sowjanya <gakula@marvell.com>
@@ -12575,13 +12595,6 @@ S: Supported
F: Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.yaml
F: drivers/mmc/host/sdhci-xenon*
-MARVELL OCTEON ENDPOINT DRIVER
-M: Veerasenareddy Burru <vburru@marvell.com>
-M: Abhijit Ayarekar <aayarekar@marvell.com>
-L: netdev@vger.kernel.org
-S: Supported
-F: drivers/net/ethernet/marvell/octeon_ep
-
MATROX FRAMEBUFFER DRIVER
L: linux-fbdev@vger.kernel.org
S: Orphan
@@ -12781,12 +12794,6 @@ L: netdev@vger.kernel.org
S: Supported
F: drivers/net/phy/mxl-gpy.c
-MCBA MICROCHIP CAN BUS ANALYZER TOOL DRIVER
-R: Yasushi SHOJI <yashi@spacecubics.com>
-L: linux-can@vger.kernel.org
-S: Maintained
-F: drivers/net/can/usb/mcba_usb.c
-
MCAN MMIO DEVICE DRIVER
M: Chandrasekar Ramakrishnan <rcsekar@samsung.com>
L: linux-can@vger.kernel.org
@@ -12796,6 +12803,12 @@ F: drivers/net/can/m_can/m_can.c
F: drivers/net/can/m_can/m_can.h
F: drivers/net/can/m_can/m_can_platform.c
+MCBA MICROCHIP CAN BUS ANALYZER TOOL DRIVER
+R: Yasushi SHOJI <yashi@spacecubics.com>
+L: linux-can@vger.kernel.org
+S: Maintained
+F: drivers/net/can/usb/mcba_usb.c
+
MCP2221A MICROCHIP USB-HID TO I2C BRIDGE DRIVER
M: Rishi Gupta <gupt21@gmail.com>
L: linux-i2c@vger.kernel.org
@@ -13204,13 +13217,6 @@ S: Maintained
F: Documentation/devicetree/bindings/clock/mediatek,mt7621-sysc.yaml
F: drivers/clk/ralink/clk-mt7621.c
-MEDIATEK MT7621/28/88 I2C DRIVER
-M: Stefan Roese <sr@denx.de>
-L: linux-i2c@vger.kernel.org
-S: Maintained
-F: Documentation/devicetree/bindings/i2c/mediatek,mt7621-i2c.yaml
-F: drivers/i2c/busses/i2c-mt7621.c
-
MEDIATEK MT7621 PCIE CONTROLLER DRIVER
M: Sergio Paracuellos <sergio.paracuellos@gmail.com>
S: Maintained
@@ -13223,6 +13229,13 @@ S: Maintained
F: Documentation/devicetree/bindings/phy/mediatek,mt7621-pci-phy.yaml
F: drivers/phy/ralink/phy-mt7621-pci.c
+MEDIATEK MT7621/28/88 I2C DRIVER
+M: Stefan Roese <sr@denx.de>
+L: linux-i2c@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/i2c/mediatek,mt7621-i2c.yaml
+F: drivers/i2c/busses/i2c-mt7621.c
+
MEDIATEK NAND CONTROLLER DRIVER
L: linux-mtd@lists.infradead.org
S: Orphan
@@ -13482,10 +13495,22 @@ MEMORY FREQUENCY SCALING DRIVERS FOR NVIDIA TEGRA
M: Dmitry Osipenko <digetx@gmail.com>
L: linux-pm@vger.kernel.org
L: linux-tegra@vger.kernel.org
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/linux.git
S: Maintained
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/linux.git
F: drivers/devfreq/tegra30-devfreq.c
+MEMORY HOT(UN)PLUG
+M: David Hildenbrand <david@redhat.com>
+M: Oscar Salvador <osalvador@suse.de>
+L: linux-mm@kvack.org
+S: Maintained
+F: Documentation/admin-guide/mm/memory-hotplug.rst
+F: Documentation/core-api/memory-hotplug.rst
+F: drivers/base/memory.c
+F: include/linux/memory_hotplug.h
+F: mm/memory_hotplug.c
+F: tools/testing/selftests/memory-hotplug/
+
MEMORY MANAGEMENT
M: Andrew Morton <akpm@linux-foundation.org>
L: linux-mm@kvack.org
@@ -13504,30 +13529,6 @@ F: mm/
F: tools/mm/
F: tools/testing/selftests/mm/
-VMALLOC
-M: Andrew Morton <akpm@linux-foundation.org>
-R: Uladzislau Rezki <urezki@gmail.com>
-R: Christoph Hellwig <hch@infradead.org>
-R: Lorenzo Stoakes <lstoakes@gmail.com>
-L: linux-mm@kvack.org
-S: Maintained
-W: http://www.linux-mm.org
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
-F: include/linux/vmalloc.h
-F: mm/vmalloc.c
-
-MEMORY HOT(UN)PLUG
-M: David Hildenbrand <david@redhat.com>
-M: Oscar Salvador <osalvador@suse.de>
-L: linux-mm@kvack.org
-S: Maintained
-F: Documentation/admin-guide/mm/memory-hotplug.rst
-F: Documentation/core-api/memory-hotplug.rst
-F: drivers/base/memory.c
-F: include/linux/memory_hotplug.h
-F: mm/memory_hotplug.c
-F: tools/testing/selftests/memory-hotplug/
-
MEMORY TECHNOLOGY DEVICES (MTD)
M: Miquel Raynal <miquel.raynal@bootlin.com>
M: Richard Weinberger <richard@nod.at>
@@ -13638,6 +13639,12 @@ W: http://www.monstr.eu/fdt/
T: git git://git.monstr.eu/linux-2.6-microblaze.git
F: arch/microblaze/
+MICROBLAZE TMR INJECT
+M: Appana Durga Kedareswara rao <appana.durga.kedareswara.rao@amd.com>
+S: Supported
+F: Documentation/devicetree/bindings/misc/xlnx,tmr-inject.yaml
+F: drivers/misc/xilinx_tmr_inject.c
+
MICROBLAZE TMR MANAGER
M: Appana Durga Kedareswara rao <appana.durga.kedareswara.rao@amd.com>
S: Supported
@@ -13645,12 +13652,6 @@ F: Documentation/ABI/testing/sysfs-driver-xilinx-tmr-manager
F: Documentation/devicetree/bindings/misc/xlnx,tmr-manager.yaml
F: drivers/misc/xilinx_tmr_manager.c
-MICROBLAZE TMR INJECT
-M: Appana Durga Kedareswara rao <appana.durga.kedareswara.rao@amd.com>
-S: Supported
-F: Documentation/devicetree/bindings/misc/xlnx,tmr-inject.yaml
-F: drivers/misc/xilinx_tmr_inject.c
-
MICROCHIP AT91 DMA DRIVERS
M: Ludovic Desroches <ludovic.desroches@microchip.com>
M: Tudor Ambarus <tudor.ambarus@linaro.org>
@@ -13726,10 +13727,10 @@ L: linux-media@vger.kernel.org
S: Supported
F: Documentation/devicetree/bindings/media/atmel,isc.yaml
F: Documentation/devicetree/bindings/media/microchip,xisc.yaml
-F: drivers/staging/media/deprecated/atmel/atmel-isc*
-F: drivers/staging/media/deprecated/atmel/atmel-sama*-isc*
F: drivers/media/platform/microchip/microchip-isc*
F: drivers/media/platform/microchip/microchip-sama*-isc*
+F: drivers/staging/media/deprecated/atmel/atmel-isc*
+F: drivers/staging/media/deprecated/atmel/atmel-sama*-isc*
F: include/linux/atmel-isc-media.h
MICROCHIP ISI DRIVER
@@ -13751,13 +13752,6 @@ F: include/linux/dsa/ksz_common.h
F: include/linux/platform_data/microchip-ksz.h
F: net/dsa/tag_ksz.c
-MICROCHIP LAN87xx/LAN937x T1 PHY DRIVER
-M: Arun Ramadoss <arun.ramadoss@microchip.com>
-R: UNGLinuxDriver@microchip.com
-L: netdev@vger.kernel.org
-S: Maintained
-F: drivers/net/phy/microchip_t1.c
-
MICROCHIP LAN743X ETHERNET DRIVER
M: Bryan Whitehead <bryan.whitehead@microchip.com>
M: UNGLinuxDriver@microchip.com
@@ -13765,6 +13759,13 @@ L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/ethernet/microchip/lan743x_*
+MICROCHIP LAN87xx/LAN937x T1 PHY DRIVER
+M: Arun Ramadoss <arun.ramadoss@microchip.com>
+R: UNGLinuxDriver@microchip.com
+L: netdev@vger.kernel.org
+S: Maintained
+F: drivers/net/phy/microchip_t1.c
+
MICROCHIP LAN966X ETHERNET DRIVER
M: Horatiu Vultur <horatiu.vultur@microchip.com>
M: UNGLinuxDriver@microchip.com
@@ -13806,14 +13807,6 @@ S: Supported
F: Documentation/devicetree/bindings/mtd/atmel-nand.txt
F: drivers/mtd/nand/raw/atmel/*
-MICROCHIP PCI1XXXX GP DRIVER
-M: Kumaravel Thiagarajan <kumaravel.thiagarajan@microchip.com>
-L: linux-gpio@vger.kernel.org
-S: Supported
-F: drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_gp.c
-F: drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_gp.h
-F: drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_gpio.c
-
MICROCHIP OTPC DRIVER
M: Claudiu Beznea <claudiu.beznea@microchip.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -13822,6 +13815,14 @@ F: Documentation/devicetree/bindings/nvmem/microchip,sama7g5-otpc.yaml
F: drivers/nvmem/microchip-otpc.c
F: include/dt-bindings/nvmem/microchip,sama7g5-otpc.h
+MICROCHIP PCI1XXXX GP DRIVER
+M: Kumaravel Thiagarajan <kumaravel.thiagarajan@microchip.com>
+L: linux-gpio@vger.kernel.org
+S: Supported
+F: drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_gp.c
+F: drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_gp.h
+F: drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_gpio.c
+
MICROCHIP PCI1XXXX I2C DRIVER
M: Tharun Kumar P <tharunkumar.pasumarthi@microchip.com>
M: Kumaravel Thiagarajan <kumaravel.thiagarajan@microchip.com>
@@ -13837,6 +13838,14 @@ L: linux-serial@vger.kernel.org
S: Maintained
F: drivers/tty/serial/8250/8250_pci1xxxx.c
+MICROCHIP POLARFIRE FPGA DRIVERS
+M: Conor Dooley <conor.dooley@microchip.com>
+R: Ivan Bornyakov <i.bornyakov@metrotek.ru>
+L: linux-fpga@vger.kernel.org
+S: Supported
+F: Documentation/devicetree/bindings/fpga/microchip,mpf-spi-fpga-mgr.yaml
+F: drivers/fpga/microchip-spi.c
+
MICROCHIP PWM DRIVER
M: Claudiu Beznea <claudiu.beznea@microchip.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -13858,6 +13867,12 @@ M: Claudiu Beznea <claudiu.beznea@microchip.com>
S: Supported
F: drivers/power/reset/at91-sama5d2_shdwc.c
+MICROCHIP SOC DRIVERS
+M: Conor Dooley <conor@kernel.org>
+S: Supported
+T: git https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/
+F: drivers/soc/microchip/
+
MICROCHIP SPI DRIVER
M: Tudor Ambarus <tudor.ambarus@linaro.org>
S: Supported
@@ -13871,11 +13886,12 @@ F: Documentation/devicetree/bindings/misc/atmel-ssc.txt
F: drivers/misc/atmel-ssc.c
F: include/linux/atmel-ssc.h
-MICROCHIP SOC DRIVERS
-M: Conor Dooley <conor@kernel.org>
-S: Supported
-T: git https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/
-F: drivers/soc/microchip/
+Microchip Timer Counter Block (TCB) Capture Driver
+M: Kamel Bouhara <kamel.bouhara@bootlin.com>
+L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+L: linux-iio@vger.kernel.org
+S: Maintained
+F: drivers/counter/microchip-tcb-capture.c
MICROCHIP USB251XB DRIVER
M: Richard Leitner <richard.leitner@skidata.com>
@@ -13992,6 +14008,12 @@ L: platform-driver-x86@vger.kernel.org
S: Supported
F: drivers/platform/surface/surfacepro3_button.c
+MICROSOFT SURFACE SYSTEM AGGREGATOR HUB DRIVER
+M: Maximilian Luz <luzmaximilian@gmail.com>
+L: platform-driver-x86@vger.kernel.org
+S: Maintained
+F: drivers/platform/surface/surface_aggregator_hub.c
+
MICROSOFT SURFACE SYSTEM AGGREGATOR SUBSYSTEM
M: Maximilian Luz <luzmaximilian@gmail.com>
L: platform-driver-x86@vger.kernel.org
@@ -14007,12 +14029,6 @@ F: include/linux/surface_acpi_notify.h
F: include/linux/surface_aggregator/
F: include/uapi/linux/surface_aggregator/
-MICROSOFT SURFACE SYSTEM AGGREGATOR HUB DRIVER
-M: Maximilian Luz <luzmaximilian@gmail.com>
-L: platform-driver-x86@vger.kernel.org
-S: Maintained
-F: drivers/platform/surface/surface_aggregator_hub.c
-
MICROTEK X6 SCANNER
M: Oliver Neukum <oliver@neukum.org>
S: Maintained
@@ -14178,11 +14194,11 @@ L: linux-modules@vger.kernel.org
L: linux-kernel@vger.kernel.org
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux.git modules-next
-F: include/linux/module.h
F: include/linux/kmod.h
+F: include/linux/module.h
F: kernel/module/
-F: scripts/module*
F: lib/test_kmod.c
+F: scripts/module*
F: tools/testing/selftests/kmod/
MONOLITHIC POWER SYSTEM PMIC DRIVER
@@ -14771,6 +14787,7 @@ L: linux-nfs@vger.kernel.org
S: Maintained
W: http://client.linux-nfs.org
T: git git://git.linux-nfs.org/projects/trondmy/linux-nfs.git
+F: Documentation/filesystems/nfs/
F: fs/lockd/
F: fs/nfs/
F: fs/nfs_common/
@@ -14780,7 +14797,6 @@ F: include/linux/sunrpc/
F: include/uapi/linux/nfs*
F: include/uapi/linux/sunrpc/
F: net/sunrpc/
-F: Documentation/filesystems/nfs/
NILFS2 FILESYSTEM
M: Ryusuke Konishi <konishi.ryusuke@gmail.com>
@@ -14984,12 +15000,6 @@ F: drivers/nvme/target/auth.c
F: drivers/nvme/target/fabrics-cmd-auth.c
F: include/linux/nvme-auth.h
-NVM EXPRESS HARDWARE MONITORING SUPPORT
-M: Guenter Roeck <linux@roeck-us.net>
-L: linux-nvme@lists.infradead.org
-S: Supported
-F: drivers/nvme/host/hwmon.c
-
NVM EXPRESS FC TRANSPORT DRIVERS
M: James Smart <james.smart@broadcom.com>
L: linux-nvme@lists.infradead.org
@@ -15000,6 +15010,12 @@ F: drivers/nvme/target/fcloop.c
F: include/linux/nvme-fc-driver.h
F: include/linux/nvme-fc.h
+NVM EXPRESS HARDWARE MONITORING SUPPORT
+M: Guenter Roeck <linux@roeck-us.net>
+L: linux-nvme@lists.infradead.org
+S: Supported
+F: drivers/nvme/host/hwmon.c
+
NVM EXPRESS TARGET DRIVER
M: Christoph Hellwig <hch@lst.de>
M: Sagi Grimberg <sagi@grimberg.me>
@@ -15020,6 +15036,13 @@ F: drivers/nvmem/
F: include/linux/nvmem-consumer.h
F: include/linux/nvmem-provider.h
+NXP BLUETOOTH WIRELESS DRIVERS
+M: Amitkumar Karwar <amitkumar.karwar@nxp.com>
+M: Neeraj Kale <neeraj.sanjaykale@nxp.com>
+S: Maintained
+F: Documentation/devicetree/bindings/net/bluetooth/nxp,88w8987-bt.yaml
+F: drivers/bluetooth/btnxpuart.c
+
NXP C45 TJA11XX PHY DRIVER
M: Radu Pirea <radu-nicolae.pirea@oss.nxp.com>
L: netdev@vger.kernel.org
@@ -15045,16 +15068,17 @@ F: drivers/iio/gyro/fxas21002c_core.c
F: drivers/iio/gyro/fxas21002c_i2c.c
F: drivers/iio/gyro/fxas21002c_spi.c
-NXP i.MX CLOCK DRIVERS
-M: Abel Vesa <abelvesa@kernel.org>
-R: Peng Fan <peng.fan@nxp.com>
-L: linux-clk@vger.kernel.org
+NXP i.MX 7D/6SX/6UL/93 AND VF610 ADC DRIVER
+M: Haibo Chen <haibo.chen@nxp.com>
+L: linux-iio@vger.kernel.org
L: linux-imx@nxp.com
S: Maintained
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/abelvesa/linux.git clk/imx
-F: Documentation/devicetree/bindings/clock/imx*
-F: drivers/clk/imx/
-F: include/dt-bindings/clock/imx*
+F: Documentation/devicetree/bindings/iio/adc/fsl,imx7d-adc.yaml
+F: Documentation/devicetree/bindings/iio/adc/fsl,vf610-adc.yaml
+F: Documentation/devicetree/bindings/iio/adc/nxp,imx93-adc.yaml
+F: drivers/iio/adc/imx7d_adc.c
+F: drivers/iio/adc/imx93_adc.c
+F: drivers/iio/adc/vf610_adc.c
NXP i.MX 8M ISI DRIVER
M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
@@ -15063,6 +15087,15 @@ S: Maintained
F: Documentation/devicetree/bindings/media/nxp,imx8-isi.yaml
F: drivers/media/platform/nxp/imx8-isi/
+NXP i.MX 8MP DW100 V4L2 DRIVER
+M: Xavier Roumegue <xavier.roumegue@oss.nxp.com>
+L: linux-media@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/media/nxp,dw100.yaml
+F: Documentation/userspace-api/media/drivers/dw100.rst
+F: drivers/media/platform/nxp/dw100/
+F: include/uapi/linux/dw100.h
+
NXP i.MX 8MQ DCSS DRIVER
M: Laurentiu Palcu <laurentiu.palcu@oss.nxp.com>
R: Lucas Stach <l.stach@pengutronix.de>
@@ -15080,17 +15113,24 @@ S: Maintained
F: Documentation/devicetree/bindings/iio/adc/nxp,imx8qxp-adc.yaml
F: drivers/iio/adc/imx8qxp-adc.c
-NXP i.MX 7D/6SX/6UL/93 AND VF610 ADC DRIVER
-M: Haibo Chen <haibo.chen@nxp.com>
-L: linux-iio@vger.kernel.org
+NXP i.MX 8QXP/8QM JPEG V4L2 DRIVER
+M: Mirela Rabulea <mirela.rabulea@nxp.com>
+R: NXP Linux Team <linux-imx@nxp.com>
+L: linux-media@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/media/nxp,imx8-jpeg.yaml
+F: drivers/media/platform/nxp/imx-jpeg
+
+NXP i.MX CLOCK DRIVERS
+M: Abel Vesa <abelvesa@kernel.org>
+R: Peng Fan <peng.fan@nxp.com>
+L: linux-clk@vger.kernel.org
L: linux-imx@nxp.com
S: Maintained
-F: Documentation/devicetree/bindings/iio/adc/fsl,imx7d-adc.yaml
-F: Documentation/devicetree/bindings/iio/adc/fsl,vf610-adc.yaml
-F: Documentation/devicetree/bindings/iio/adc/nxp,imx93-adc.yaml
-F: drivers/iio/adc/imx7d_adc.c
-F: drivers/iio/adc/imx93_adc.c
-F: drivers/iio/adc/vf610_adc.c
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/abelvesa/linux.git clk/imx
+F: Documentation/devicetree/bindings/clock/imx*
+F: drivers/clk/imx/
+F: include/dt-bindings/clock/imx*
NXP PF8100/PF8121A/PF8200 PMIC REGULATOR DEVICE DRIVER
M: Jagan Teki <jagan@amarulasolutions.com>
@@ -15136,34 +15176,17 @@ S: Maintained
F: Documentation/devicetree/bindings/sound/tfa9879.txt
F: sound/soc/codecs/tfa9879*
-NXP/Goodix TFA989X (TFA1) DRIVER
-M: Stephan Gerhold <stephan@gerhold.net>
-L: alsa-devel@alsa-project.org (moderated for non-subscribers)
-S: Maintained
-F: Documentation/devicetree/bindings/sound/nxp,tfa989x.yaml
-F: sound/soc/codecs/tfa989x.c
-
NXP-NCI NFC DRIVER
S: Orphan
F: Documentation/devicetree/bindings/net/nfc/nxp,nci.yaml
F: drivers/nfc/nxp-nci
-NXP i.MX 8MP DW100 V4L2 DRIVER
-M: Xavier Roumegue <xavier.roumegue@oss.nxp.com>
-L: linux-media@vger.kernel.org
-S: Maintained
-F: Documentation/devicetree/bindings/media/nxp,dw100.yaml
-F: Documentation/userspace-api/media/drivers/dw100.rst
-F: drivers/media/platform/nxp/dw100/
-F: include/uapi/linux/dw100.h
-
-NXP i.MX 8QXP/8QM JPEG V4L2 DRIVER
-M: Mirela Rabulea <mirela.rabulea@nxp.com>
-R: NXP Linux Team <linux-imx@nxp.com>
-L: linux-media@vger.kernel.org
+NXP/Goodix TFA989X (TFA1) DRIVER
+M: Stephan Gerhold <stephan@gerhold.net>
+L: alsa-devel@alsa-project.org (moderated for non-subscribers)
S: Maintained
-F: Documentation/devicetree/bindings/media/nxp,imx8-jpeg.yaml
-F: drivers/media/platform/nxp/imx-jpeg
+F: Documentation/devicetree/bindings/sound/nxp,tfa989x.yaml
+F: sound/soc/codecs/tfa989x.c
NZXT-KRAKEN2 HARDWARE MONITORING DRIVER
M: Jonas Malaco <jonas@protocubo.io>
@@ -15689,8 +15712,8 @@ M: Rob Herring <robh+dt@kernel.org>
M: Frank Rowand <frowand.list@gmail.com>
L: devicetree@vger.kernel.org
S: Maintained
-C: irc://irc.libera.chat/devicetree
W: http://www.devicetree.org/
+C: irc://irc.libera.chat/devicetree
T: git git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git
F: Documentation/ABI/testing/sysfs-firmware-ofw
F: drivers/of/
@@ -15706,8 +15729,8 @@ M: Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>
M: Conor Dooley <conor+dt@kernel.org>
L: devicetree@vger.kernel.org
S: Maintained
-C: irc://irc.libera.chat/devicetree
Q: http://patchwork.ozlabs.org/project/devicetree-bindings/list/
+C: irc://irc.libera.chat/devicetree
T: git git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git
F: Documentation/devicetree/
F: arch/*/boot/dts/
@@ -15720,13 +15743,6 @@ L: netdev@vger.kernel.org
S: Maintained
F: drivers/ptp/ptp_ocp.c
-INTEL PTP DFL ToD DRIVER
-M: Tianfei Zhang <tianfei.zhang@intel.com>
-L: linux-fpga@vger.kernel.org
-L: netdev@vger.kernel.org
-S: Maintained
-F: drivers/ptp/ptp_dfl_tod.c
-
OPENCORES I2C BUS DRIVER
M: Peter Korsgaard <peter@korsgaard.com>
M: Andrew Lunn <andrew@lunn.ch>
@@ -15745,8 +15761,8 @@ L: linux-openrisc@vger.kernel.org
S: Maintained
W: http://openrisc.io
T: git https://github.com/openrisc/linux.git
-F: Documentation/devicetree/bindings/openrisc/
F: Documentation/arch/openrisc/
+F: Documentation/devicetree/bindings/openrisc/
F: arch/openrisc/
F: drivers/irqchip/irq-ompic.c
F: drivers/irqchip/irq-or1k-*
@@ -16062,6 +16078,14 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
F: drivers/pci/controller/dwc/*layerscape*
+PCI DRIVER FOR FU740
+M: Paul Walmsley <paul.walmsley@sifive.com>
+M: Greentime Hu <greentime.hu@sifive.com>
+L: linux-pci@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml
+F: drivers/pci/controller/dwc/pcie-fu740.c
+
PCI DRIVER FOR GENERIC OF HOSTS
M: Will Deacon <will@kernel.org>
L: linux-pci@vger.kernel.org
@@ -16082,14 +16106,6 @@ F: Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-ep.yaml
F: Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
F: drivers/pci/controller/dwc/*imx6*
-PCI DRIVER FOR FU740
-M: Paul Walmsley <paul.walmsley@sifive.com>
-M: Greentime Hu <greentime.hu@sifive.com>
-L: linux-pci@vger.kernel.org
-S: Maintained
-F: Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml
-F: drivers/pci/controller/dwc/pcie-fu740.c
-
PCI DRIVER FOR INTEL IXP4XX
M: Linus Walleij <linus.walleij@linaro.org>
S: Maintained
@@ -16169,8 +16185,8 @@ M: Jingoo Han <jingoohan1@gmail.com>
M: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
L: linux-pci@vger.kernel.org
S: Maintained
-F: Documentation/devicetree/bindings/pci/snps,dw-pcie.yaml
F: Documentation/devicetree/bindings/pci/snps,dw-pcie-ep.yaml
+F: Documentation/devicetree/bindings/pci/snps,dw-pcie.yaml
F: drivers/pci/controller/dwc/*designware*
PCI DRIVER FOR TI DRA7XX/J721E
@@ -16190,6 +16206,14 @@ S: Maintained
F: Documentation/devicetree/bindings/pci/v3-v360epc-pci.txt
F: drivers/pci/controller/pci-v3-semi.c
+PCI DRIVER FOR XILINX VERSAL CPM
+M: Bharat Kumar Gogada <bharat.kumar.gogada@amd.com>
+M: Michal Simek <michal.simek@amd.com>
+L: linux-pci@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/pci/xilinx-versal-cpm.yaml
+F: drivers/pci/controller/pcie-xilinx-cpm.c
+
PCI ENDPOINT SUBSYSTEM
M: Lorenzo Pieralisi <lpieralisi@kernel.org>
M: Krzysztof Wilczyński <kw@linux.com>
@@ -16227,19 +16251,6 @@ L: linux-pci@vger.kernel.org
S: Supported
F: Documentation/PCI/pci-error-recovery.rst
-PCI PEER-TO-PEER DMA (P2PDMA)
-M: Bjorn Helgaas <bhelgaas@google.com>
-M: Logan Gunthorpe <logang@deltatee.com>
-L: linux-pci@vger.kernel.org
-S: Supported
-Q: https://patchwork.kernel.org/project/linux-pci/list/
-B: https://bugzilla.kernel.org
-C: irc://irc.oftc.net/linux-pci
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git
-F: Documentation/driver-api/pci/p2pdma.rst
-F: drivers/pci/p2pdma.c
-F: include/linux/pci-p2pdma.h
-
PCI MSI DRIVER FOR ALTERA MSI IP
M: Joyce Ooi <joyce.ooi@intel.com>
L: linux-pci@vger.kernel.org
@@ -16270,6 +16281,19 @@ F: drivers/pci/controller/
F: drivers/pci/pci-bridge-emul.c
F: drivers/pci/pci-bridge-emul.h
+PCI PEER-TO-PEER DMA (P2PDMA)
+M: Bjorn Helgaas <bhelgaas@google.com>
+M: Logan Gunthorpe <logang@deltatee.com>
+L: linux-pci@vger.kernel.org
+S: Supported
+Q: https://patchwork.kernel.org/project/linux-pci/list/
+B: https://bugzilla.kernel.org
+C: irc://irc.oftc.net/linux-pci
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git
+F: Documentation/driver-api/pci/p2pdma.rst
+F: drivers/pci/p2pdma.c
+F: include/linux/pci-p2pdma.h
+
PCI SUBSYSTEM
M: Bjorn Helgaas <bhelgaas@google.com>
L: linux-pci@vger.kernel.org
@@ -16378,14 +16402,6 @@ L: linux-arm-msm@vger.kernel.org
S: Maintained
F: drivers/pci/controller/dwc/pcie-qcom.c
-PCIE ENDPOINT DRIVER FOR QUALCOMM
-M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
-L: linux-pci@vger.kernel.org
-L: linux-arm-msm@vger.kernel.org
-S: Maintained
-F: Documentation/devicetree/bindings/pci/qcom,pcie-ep.yaml
-F: drivers/pci/controller/dwc/pcie-qcom-ep.c
-
PCIE DRIVER FOR ROCKCHIP
M: Shawn Lin <shawn.lin@rock-chips.com>
L: linux-pci@vger.kernel.org
@@ -16407,13 +16423,13 @@ L: linux-pci@vger.kernel.org
S: Maintained
F: drivers/pci/controller/dwc/*spear*
-PCI DRIVER FOR XILINX VERSAL CPM
-M: Bharat Kumar Gogada <bharat.kumar.gogada@amd.com>
-M: Michal Simek <michal.simek@amd.com>
+PCIE ENDPOINT DRIVER FOR QUALCOMM
+M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
L: linux-pci@vger.kernel.org
+L: linux-arm-msm@vger.kernel.org
S: Maintained
-F: Documentation/devicetree/bindings/pci/xilinx-versal-cpm.yaml
-F: drivers/pci/controller/pcie-xilinx-cpm.c
+F: Documentation/devicetree/bindings/pci/qcom,pcie-ep.yaml
+F: drivers/pci/controller/dwc/pcie-qcom-ep.c
PCMCIA SUBSYSTEM
M: Dominik Brodowski <linux@dominikbrodowski.net>
@@ -16683,9 +16699,9 @@ R: Alim Akhtar <alim.akhtar@samsung.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
L: linux-samsung-soc@vger.kernel.org
S: Maintained
-C: irc://irc.libera.chat/linux-exynos
Q: https://patchwork.kernel.org/project/linux-samsung-soc/list/
B: mailto:linux-samsung-soc@vger.kernel.org
+C: irc://irc.libera.chat/linux-exynos
T: git git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/samsung.git
F: Documentation/devicetree/bindings/pinctrl/samsung,pinctrl*yaml
F: drivers/pinctrl/samsung/
@@ -16747,13 +16763,6 @@ M: Logan Gunthorpe <logang@deltatee.com>
S: Maintained
F: drivers/dma/plx_dma.c
-PM6764TR DRIVER
-M: Charles Hsu <hsu.yungteng@gmail.com>
-L: linux-hwmon@vger.kernel.org
-S: Maintained
-F: Documentation/hwmon/pm6764tr.rst
-F: drivers/hwmon/pmbus/pm6764tr.c
-
PM-GRAPH UTILITY
M: "Todd E Brandt" <todd.e.brandt@linux.intel.com>
L: linux-pm@vger.kernel.org
@@ -16763,6 +16772,13 @@ B: https://bugzilla.kernel.org/buglist.cgi?component=pm-graph&product=Tools
T: git git://github.com/intel/pm-graph
F: tools/power/pm-graph
+PM6764TR DRIVER
+M: Charles Hsu <hsu.yungteng@gmail.com>
+L: linux-hwmon@vger.kernel.org
+S: Maintained
+F: Documentation/hwmon/pm6764tr.rst
+F: drivers/hwmon/pmbus/pm6764tr.c
+
PMBUS HARDWARE MONITORING DRIVERS
M: Guenter Roeck <linux@roeck-us.net>
L: linux-hwmon@vger.kernel.org
@@ -16843,15 +16859,6 @@ F: include/linux/pm_*
F: include/linux/powercap.h
F: kernel/configs/nopm.config
-DYNAMIC THERMAL POWER MANAGEMENT (DTPM)
-M: Daniel Lezcano <daniel.lezcano@kernel.org>
-L: linux-pm@vger.kernel.org
-S: Supported
-B: https://bugzilla.kernel.org
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
-F: drivers/powercap/dtpm*
-F: include/linux/dtpm.h
-
POWER STATE COORDINATION INTERFACE (PSCI)
M: Mark Rutland <mark.rutland@arm.com>
M: Lorenzo Pieralisi <lpieralisi@kernel.org>
@@ -17010,8 +17017,8 @@ R: Guilherme G. Piccoli <gpiccoli@igalia.com>
L: linux-hardening@vger.kernel.org
S: Supported
T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/pstore
-F: Documentation/admin-guide/ramoops.rst
F: Documentation/admin-guide/pstore-blk.rst
+F: Documentation/admin-guide/ramoops.rst
F: Documentation/devicetree/bindings/reserved-memory/ramoops.yaml
F: drivers/acpi/apei/erst.c
F: drivers/firmware/efi/efi-pstore.c
@@ -17160,10 +17167,10 @@ F: sound/soc/codecs/lpass-va-macro.c
F: sound/soc/codecs/lpass-wsa-macro.*
F: sound/soc/codecs/msm8916-wcd-analog.c
F: sound/soc/codecs/msm8916-wcd-digital.c
-F: sound/soc/codecs/wcd9335.*
-F: sound/soc/codecs/wcd934x.c
F: sound/soc/codecs/wcd-clsh-v2.*
F: sound/soc/codecs/wcd-mbhc-v2.*
+F: sound/soc/codecs/wcd9335.*
+F: sound/soc/codecs/wcd934x.c
F: sound/soc/codecs/wsa881x.c
F: sound/soc/codecs/wsa883x.c
F: sound/soc/qcom/
@@ -17320,14 +17327,21 @@ Q: http://patchwork.linuxtv.org/project/linux-media/list/
T: git git://linuxtv.org/anttip/media_tree.git
F: drivers/media/tuners/qt1010*
+QUALCOMM ATH12K WIRELESS DRIVER
+M: Kalle Valo <kvalo@kernel.org>
+L: ath12k@lists.infradead.org
+S: Supported
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
+F: drivers/net/wireless/ath/ath12k/
+
QUALCOMM ATHEROS ATH10K WIRELESS DRIVER
M: Kalle Valo <kvalo@kernel.org>
L: ath10k@lists.infradead.org
S: Supported
W: https://wireless.wiki.kernel.org/en/users/Drivers/ath10k
T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
-F: drivers/net/wireless/ath/ath10k/
F: Documentation/devicetree/bindings/net/wireless/qcom,ath10k.yaml
+F: drivers/net/wireless/ath/ath10k/
QUALCOMM ATHEROS ATH11K WIRELESS DRIVER
M: Kalle Valo <kvalo@kernel.org>
@@ -17337,13 +17351,6 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
F: Documentation/devicetree/bindings/net/wireless/qcom,ath11k.yaml
F: drivers/net/wireless/ath/ath11k/
-QUALCOMM ATH12K WIRELESS DRIVER
-M: Kalle Valo <kvalo@kernel.org>
-L: ath12k@lists.infradead.org
-S: Supported
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
-F: drivers/net/wireless/ath/ath12k/
-
QUALCOMM ATHEROS ATH9K WIRELESS DRIVER
M: Toke Høiland-Jørgensen <toke@toke.dk>
L: linux-wireless@vger.kernel.org
@@ -17440,8 +17447,8 @@ F: include/uapi/misc/fastrpc.h
QUALCOMM HEXAGON ARCHITECTURE
M: Brian Cain <bcain@quicinc.com>
L: linux-hexagon@vger.kernel.org
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/bcain/linux.git
S: Supported
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/bcain/linux.git
F: arch/hexagon/
QUALCOMM HIDMA DRIVER
@@ -17563,9 +17570,9 @@ M: Christian König <christian.koenig@amd.com>
M: Pan, Xinhui <Xinhui.Pan@amd.com>
L: amd-gfx@lists.freedesktop.org
S: Supported
-T: git https://gitlab.freedesktop.org/agd5f/linux.git
B: https://gitlab.freedesktop.org/drm/amd/-/issues
C: irc://irc.oftc.net/radeon
+T: git https://gitlab.freedesktop.org/agd5f/linux.git
F: Documentation/gpu/amdgpu/
F: drivers/gpu/drm/amd/
F: drivers/gpu/drm/radeon/
@@ -17653,8 +17660,8 @@ F: arch/mips/generic/board-ranchu.c
RANDOM NUMBER DRIVER
M: "Theodore Ts'o" <tytso@mit.edu>
M: Jason A. Donenfeld <Jason@zx2c4.com>
-T: git https://git.kernel.org/pub/scm/linux/kernel/git/crng/random.git
S: Maintained
+T: git https://git.kernel.org/pub/scm/linux/kernel/git/crng/random.git
F: drivers/char/random.c
F: drivers/virt/vmgenid.c
@@ -17688,8 +17695,8 @@ T: git git://linuxtv.org/media_tree.git
F: Documentation/driver-api/media/rc-core.rst
F: Documentation/userspace-api/media/rc/
F: drivers/media/rc/
-F: include/media/rc-map.h
F: include/media/rc-core.h
+F: include/media/rc-map.h
F: include/uapi/linux/lirc.h
RCMM REMOTE CONTROLS DECODER
@@ -17806,6 +17813,14 @@ F: include/linux/rtc/
F: include/uapi/linux/rtc.h
F: tools/testing/selftests/rtc/
+Real-time Linux Analysis (RTLA) tools
+M: Daniel Bristot de Oliveira <bristot@kernel.org>
+M: Steven Rostedt <rostedt@goodmis.org>
+L: linux-trace-devel@vger.kernel.org
+S: Maintained
+F: Documentation/tools/rtla/
+F: tools/tracing/rtla/
+
REALTEK AUDIO CODECS
M: Oder Chiou <oder_chiou@realtek.com>
S: Maintained
@@ -17929,6 +17944,14 @@ S: Maintained
F: Documentation/devicetree/bindings/sound/renesas,idt821034.yaml
F: sound/soc/codecs/idt821034.c
+RENESAS R-CAR GEN3 & RZ/N1 NAND CONTROLLER DRIVER
+M: Miquel Raynal <miquel.raynal@bootlin.com>
+L: linux-mtd@lists.infradead.org
+L: linux-renesas-soc@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/mtd/renesas-nandc.yaml
+F: drivers/mtd/nand/raw/renesas-nand-controller.c
+
RENESAS R-CAR GYROADC DRIVER
M: Marek Vasut <marek.vasut@gmail.com>
L: linux-iio@vger.kernel.org
@@ -17947,9 +17970,9 @@ F: drivers/i2c/busses/i2c-sh_mobile.c
RENESAS R-CAR SATA DRIVER
R: Sergey Shtylyov <s.shtylyov@omp.ru>
-S: Supported
L: linux-ide@vger.kernel.org
L: linux-renesas-soc@vger.kernel.org
+S: Supported
F: Documentation/devicetree/bindings/ata/renesas,rcar-sata.yaml
F: drivers/ata/sata_rcar.c
@@ -17969,12 +17992,6 @@ S: Supported
F: Documentation/devicetree/bindings/i2c/renesas,riic.yaml
F: drivers/i2c/busses/i2c-riic.c
-RENESAS USB PHY DRIVER
-M: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
-L: linux-renesas-soc@vger.kernel.org
-S: Maintained
-F: drivers/phy/renesas/phy-rcar-gen3-usb*.c
-
RENESAS RZ/G2L A/D DRIVER
M: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
L: linux-iio@vger.kernel.org
@@ -18020,13 +18037,11 @@ S: Maintained
F: Documentation/devicetree/bindings/usb/renesas,rzn1-usbf.yaml
F: drivers/usb/gadget/udc/renesas_usbf.c
-RENESAS R-CAR GEN3 & RZ/N1 NAND CONTROLLER DRIVER
-M: Miquel Raynal <miquel.raynal@bootlin.com>
-L: linux-mtd@lists.infradead.org
+RENESAS USB PHY DRIVER
+M: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
L: linux-renesas-soc@vger.kernel.org
S: Maintained
-F: Documentation/devicetree/bindings/mtd/renesas-nandc.yaml
-F: drivers/mtd/nand/raw/renesas-nand-controller.c
+F: drivers/phy/renesas/phy-rcar-gen3-usb*.c
RENESAS VERSACLOCK 7 CLOCK DRIVER
M: Alex Helms <alexander.helms.jy@renesas.com>
@@ -18094,15 +18109,6 @@ S: Maintained
F: drivers/mtd/nand/raw/r852.c
F: drivers/mtd/nand/raw/r852.h
-RISC-V PMU DRIVERS
-M: Atish Patra <atishp@atishpatra.org>
-R: Anup Patel <anup@brainfault.org>
-L: linux-riscv@lists.infradead.org
-S: Supported
-F: drivers/perf/riscv_pmu.c
-F: drivers/perf/riscv_pmu_legacy.c
-F: drivers/perf/riscv_pmu_sbi.c
-
RISC-V ARCHITECTURE
M: Paul Walmsley <paul.walmsley@sifive.com>
M: Palmer Dabbelt <palmer@dabbelt.com>
@@ -18155,6 +18161,15 @@ T: git https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/
F: Documentation/devicetree/bindings/riscv/
F: arch/riscv/boot/dts/
+RISC-V PMU DRIVERS
+M: Atish Patra <atishp@atishpatra.org>
+R: Anup Patel <anup@brainfault.org>
+L: linux-riscv@lists.infradead.org
+S: Supported
+F: drivers/perf/riscv_pmu.c
+F: drivers/perf/riscv_pmu_legacy.c
+F: drivers/perf/riscv_pmu_sbi.c
+
RNBD BLOCK DRIVERS
M: Md. Haris Iqbal <haris.iqbal@ionos.com>
M: Jack Wang <jinpu.wang@ionos.com>
@@ -18459,14 +18474,6 @@ F: drivers/s390/net/*iucv*
F: include/net/iucv/
F: net/iucv/
-S390 NETWORK DRIVERS
-M: Alexandra Winter <wintera@linux.ibm.com>
-M: Wenjia Zhang <wenjia@linux.ibm.com>
-L: linux-s390@vger.kernel.org
-L: netdev@vger.kernel.org
-S: Supported
-F: drivers/s390/net/
-
S390 MM
M: Alexander Gordeev <agordeev@linux.ibm.com>
M: Gerald Schaefer <gerald.schaefer@linux.ibm.com>
@@ -18476,14 +18483,22 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git
F: arch/s390/include/asm/pgtable.h
F: arch/s390/mm
+S390 NETWORK DRIVERS
+M: Alexandra Winter <wintera@linux.ibm.com>
+M: Wenjia Zhang <wenjia@linux.ibm.com>
+L: linux-s390@vger.kernel.org
+L: netdev@vger.kernel.org
+S: Supported
+F: drivers/s390/net/
+
S390 PCI SUBSYSTEM
M: Niklas Schnelle <schnelle@linux.ibm.com>
M: Gerald Schaefer <gerald.schaefer@linux.ibm.com>
L: linux-s390@vger.kernel.org
S: Supported
+F: Documentation/s390/pci.rst
F: arch/s390/pci/
F: drivers/pci/hotplug/s390_pci_hpc.c
-F: Documentation/s390/pci.rst
S390 SCM DRIVER
M: Vineeth Vijayan <vneethv@linux.ibm.com>
@@ -18916,6 +18931,13 @@ L: linux-mmc@vger.kernel.org
S: Supported
F: drivers/mmc/host/sdhci-of-at91.c
+SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) NXP i.MX DRIVER
+M: Haibo Chen <haibo.chen@nxp.com>
+L: linux-imx@nxp.com
+L: linux-mmc@vger.kernel.org
+S: Maintained
+F: drivers/mmc/host/sdhci-esdhc-imx.c
+
SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) SAMSUNG DRIVER
M: Ben Dooks <ben-linux@fluff.org>
M: Jaehoon Chung <jh80.chung@samsung.com>
@@ -18935,13 +18957,6 @@ L: linux-mmc@vger.kernel.org
S: Maintained
F: drivers/mmc/host/sdhci-omap.c
-SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) NXP i.MX DRIVER
-M: Haibo Chen <haibo.chen@nxp.com>
-L: linux-imx@nxp.com
-L: linux-mmc@vger.kernel.org
-S: Maintained
-F: drivers/mmc/host/sdhci-esdhc-imx.c
-
SECURE ENCRYPTING DEVICE (SED) OPAL DRIVER
M: Jonathan Derrick <jonathan.derrick@linux.dev>
L: linux-block@vger.kernel.org
@@ -18951,6 +18966,15 @@ F: block/sed*
F: include/linux/sed*
F: include/uapi/linux/sed*
+SECURE MONITOR CALL(SMC) CALLING CONVENTION (SMCCC)
+M: Mark Rutland <mark.rutland@arm.com>
+M: Lorenzo Pieralisi <lpieralisi@kernel.org>
+M: Sudeep Holla <sudeep.holla@arm.com>
+L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S: Maintained
+F: drivers/firmware/smccc/
+F: include/linux/arm-smccc.h
+
SECURITY CONTACT
M: Security Officers <security@kernel.org>
S: Supported
@@ -19400,15 +19424,6 @@ M: Nicolas Pitre <nico@fluxnic.net>
S: Odd Fixes
F: drivers/net/ethernet/smsc/smc91x.*
-SECURE MONITOR CALL(SMC) CALLING CONVENTION (SMCCC)
-M: Mark Rutland <mark.rutland@arm.com>
-M: Lorenzo Pieralisi <lpieralisi@kernel.org>
-M: Sudeep Holla <sudeep.holla@arm.com>
-L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-S: Maintained
-F: drivers/firmware/smccc/
-F: include/linux/arm-smccc.h
-
SMM665 HARDWARE MONITOR DRIVER
M: Guenter Roeck <linux@roeck-us.net>
L: linux-hwmon@vger.kernel.org
@@ -19456,6 +19471,10 @@ L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/ethernet/smsc/smsc9420.*
+SNET DPU VIRTIO DATA PATH ACCELERATOR
+R: Alvaro Karsz <alvaro.karsz@solid-run.com>
+F: drivers/vdpa/solidrun/
+
SOCIONEXT (SNI) AVE NETWORK DRIVER
M: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
L: netdev@vger.kernel.org
@@ -19725,6 +19744,13 @@ F: include/uapi/sound/
F: sound/
F: tools/testing/selftests/alsa
+SOUND - ALSA SELFTESTS
+M: Mark Brown <broonie@kernel.org>
+L: alsa-devel@alsa-project.org (moderated for non-subscribers)
+L: linux-kselftest@vger.kernel.org
+S: Supported
+F: tools/testing/selftests/alsa
+
SOUND - COMPRESSED AUDIO
M: Vinod Koul <vkoul@kernel.org>
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
@@ -19743,13 +19769,6 @@ F: include/sound/dmaengine_pcm.h
F: sound/core/pcm_dmaengine.c
F: sound/soc/soc-generic-dmaengine-pcm.c
-SOUND - ALSA SELFTESTS
-M: Mark Brown <broonie@kernel.org>
-L: alsa-devel@alsa-project.org (moderated for non-subscribers)
-L: linux-kselftest@vger.kernel.org
-S: Supported
-F: tools/testing/selftests/alsa
-
SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEMENT (ASoC)
M: Liam Girdwood <lgirdwood@gmail.com>
M: Mark Brown <broonie@kernel.org>
@@ -19769,8 +19788,8 @@ M: Liam Girdwood <lgirdwood@gmail.com>
M: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
M: Bard Liao <yung-chuan.liao@linux.intel.com>
M: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
-R: Kai Vehmanen <kai.vehmanen@linux.intel.com>
M: Daniel Baluta <daniel.baluta@nxp.com>
+R: Kai Vehmanen <kai.vehmanen@linux.intel.com>
L: sound-open-firmware@alsa-project.org (moderated for non-subscribers)
S: Supported
W: https://github.com/thesofproject/linux/
@@ -19832,9 +19851,9 @@ M: "Luc Van Oostenryck" <luc.vanoostenryck@gmail.com>
L: linux-sparse@vger.kernel.org
S: Maintained
W: https://sparse.docs.kernel.org/
-T: git git://git.kernel.org/pub/scm/devel/sparse/sparse.git
Q: https://patchwork.kernel.org/project/linux-sparse/list/
B: https://bugzilla.kernel.org/enter_bug.cgi?component=Sparse&product=Tools
+T: git git://git.kernel.org/pub/scm/devel/sparse/sparse.git
F: include/linux/compiler.h
SPEAKUP CONSOLE SPEECH DRIVER
@@ -20203,6 +20222,11 @@ W: http://www.stlinux.com
F: Documentation/networking/device_drivers/ethernet/stmicro/
F: drivers/net/ethernet/stmicro/stmmac/
+SUN HAPPY MEAL ETHERNET DRIVER
+M: Sean Anderson <seanga2@gmail.com>
+S: Maintained
+F: drivers/net/ethernet/sun/sunhme.*
+
SUN3/3X
M: Sam Creasey <sammy@sammy.net>
S: Maintained
@@ -20225,11 +20249,6 @@ L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/ethernet/dlink/sundance.c
-SUN HAPPY MEAL ETHERNET DRIVER
-M: Sean Anderson <seanga2@gmail.com>
-S: Maintained
-F: drivers/net/ethernet/sun/sunhme.*
-
SUNPLUS ETHERNET DRIVER
M: Wells Lu <wellslutw@gmail.com>
L: netdev@vger.kernel.org
@@ -20251,15 +20270,6 @@ S: Maintained
F: Documentation/devicetree/bindings/nvmem/sunplus,sp7021-ocotp.yaml
F: drivers/nvmem/sunplus-ocotp.c
-SUNPLUS USB2 PHY DRIVER
-M: Vincent Shih <vincent.sunplus@gmail.com>
-L: linux-usb@vger.kernel.org
-S: Maintained
-F: Documentation/devicetree/bindings/phy/sunplus,sp7021-usb2-phy.yaml
-F: drivers/phy/sunplus/Kconfig
-F: drivers/phy/sunplus/Makefile
-F: drivers/phy/sunplus/phy-sunplus-usb2.c
-
SUNPLUS PWM DRIVER
M: Hammer Hsieh <hammerh0314@gmail.com>
S: Maintained
@@ -20286,6 +20296,15 @@ S: Maintained
F: Documentation/devicetree/bindings/serial/sunplus,sp7021-uart.yaml
F: drivers/tty/serial/sunplus-uart.c
+SUNPLUS USB2 PHY DRIVER
+M: Vincent Shih <vincent.sunplus@gmail.com>
+L: linux-usb@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/phy/sunplus,sp7021-usb2-phy.yaml
+F: drivers/phy/sunplus/Kconfig
+F: drivers/phy/sunplus/Makefile
+F: drivers/phy/sunplus/phy-sunplus-usb2.c
+
SUNPLUS WATCHDOG DRIVER
M: Xiantao Hu <xt.hu@cqplus1.com>
L: linux-watchdog@vger.kernel.org
@@ -20697,6 +20716,14 @@ F: include/linux/if_team.h
F: include/uapi/linux/if_team.h
F: tools/testing/selftests/drivers/net/team/
+TECHNICAL ADVISORY BOARD PROCESS DOCS
+M: "Theodore Ts'o" <tytso@mit.edu>
+M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+L: tech-board-discuss@lists.linux-foundation.org
+S: Maintained
+F: Documentation/process/contribution-maturity-model.rst
+F: Documentation/process/researcher-guidelines.rst
+
TECHNOLOGIC SYSTEMS TS-5500 PLATFORM SUPPORT
M: "Savoir-faire Linux Inc." <kernel@savoirfairelinux.com>
S: Maintained
@@ -20776,6 +20803,14 @@ M: Thierry Reding <thierry.reding@gmail.com>
S: Supported
F: drivers/pwm/pwm-tegra.c
+TEGRA QUAD SPI DRIVER
+M: Thierry Reding <thierry.reding@gmail.com>
+M: Jonathan Hunter <jonathanh@nvidia.com>
+M: Sowjanya Komatineni <skomatineni@nvidia.com>
+L: linux-tegra@vger.kernel.org
+S: Maintained
+F: drivers/spi/spi-tegra210-quad.c
+
TEGRA SERIAL DRIVER
M: Laxman Dewangan <ldewangan@nvidia.com>
S: Supported
@@ -20786,14 +20821,6 @@ M: Laxman Dewangan <ldewangan@nvidia.com>
S: Supported
F: drivers/spi/spi-tegra*
-TEGRA QUAD SPI DRIVER
-M: Thierry Reding <thierry.reding@gmail.com>
-M: Jonathan Hunter <jonathanh@nvidia.com>
-M: Sowjanya Komatineni <skomatineni@nvidia.com>
-L: linux-tegra@vger.kernel.org
-S: Maintained
-F: drivers/spi/spi-tegra210-quad.c
-
TEGRA VIDEO DRIVER
M: Thierry Reding <thierry.reding@gmail.com>
M: Jonathan Hunter <jonathanh@nvidia.com>
@@ -20842,13 +20869,6 @@ S: Maintained
F: Documentation/devicetree/bindings/sound/davinci-mcasp-audio.yaml
F: sound/soc/ti/
-TEXAS INSTRUMENTS' DAC7612 DAC DRIVER
-M: Ricardo Ribalda <ribalda@kernel.org>
-L: linux-iio@vger.kernel.org
-S: Supported
-F: Documentation/devicetree/bindings/iio/dac/ti,dac7612.yaml
-F: drivers/iio/dac/ti-dac7612.c
-
TEXAS INSTRUMENTS DMA DRIVERS
M: Peter Ujfalusi <peter.ujfalusi@gmail.com>
L: dmaengine@vger.kernel.org
@@ -20857,10 +20877,26 @@ F: Documentation/devicetree/bindings/dma/ti-dma-crossbar.txt
F: Documentation/devicetree/bindings/dma/ti-edma.txt
F: Documentation/devicetree/bindings/dma/ti/
F: drivers/dma/ti/
-X: drivers/dma/ti/cppi41.c
+F: include/linux/dma/k3-psil.h
F: include/linux/dma/k3-udma-glue.h
F: include/linux/dma/ti-cppi5.h
-F: include/linux/dma/k3-psil.h
+X: drivers/dma/ti/cppi41.c
+
+TEXAS INSTRUMENTS TPS23861 PoE PSE DRIVER
+M: Robert Marko <robert.marko@sartura.hr>
+M: Luka Perkov <luka.perkov@sartura.hr>
+L: linux-hwmon@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/hwmon/ti,tps23861.yaml
+F: Documentation/hwmon/tps23861.rst
+F: drivers/hwmon/tps23861.c
+
+TEXAS INSTRUMENTS' DAC7612 DAC DRIVER
+M: Ricardo Ribalda <ribalda@kernel.org>
+L: linux-iio@vger.kernel.org
+S: Supported
+F: Documentation/devicetree/bindings/iio/dac/ti,dac7612.yaml
+F: drivers/iio/dac/ti-dac7612.c
TEXAS INSTRUMENTS' SYSTEM CONTROL INTERFACE (TISCI) PROTOCOL DRIVER
M: Nishanth Menon <nm@ti.com>
@@ -20886,15 +20922,6 @@ F: include/dt-bindings/soc/ti,sci_pm_domain.h
F: include/linux/soc/ti/ti_sci_inta_msi.h
F: include/linux/soc/ti/ti_sci_protocol.h
-TEXAS INSTRUMENTS TPS23861 PoE PSE DRIVER
-M: Robert Marko <robert.marko@sartura.hr>
-M: Luka Perkov <luka.perkov@sartura.hr>
-L: linux-hwmon@vger.kernel.org
-S: Maintained
-F: Documentation/devicetree/bindings/hwmon/ti,tps23861.yaml
-F: Documentation/hwmon/tps23861.rst
-F: drivers/hwmon/tps23861.c
-
TEXAS INSTRUMENTS' TMP117 TEMPERATURE SENSOR DRIVER
M: Puranjay Mohan <puranjay12@gmail.com>
L: linux-iio@vger.kernel.org
@@ -21371,8 +21398,8 @@ M: Steven Rostedt <rostedt@goodmis.org>
M: Masami Hiramatsu <mhiramat@kernel.org>
L: linux-kernel@vger.kernel.org
L: linux-trace-kernel@vger.kernel.org
-Q: https://patchwork.kernel.org/project/linux-trace-kernel/list/
S: Maintained
+Q: https://patchwork.kernel.org/project/linux-trace-kernel/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace.git
F: Documentation/trace/*
F: fs/tracefs/
@@ -21400,31 +21427,15 @@ TRACING OS NOISE / LATENCY TRACERS
M: Steven Rostedt <rostedt@goodmis.org>
M: Daniel Bristot de Oliveira <bristot@kernel.org>
S: Maintained
-F: kernel/trace/trace_osnoise.c
+F: Documentation/trace/hwlat_detector.rst
+F: Documentation/trace/osnoise-tracer.rst
+F: Documentation/trace/timerlat-tracer.rst
+F: arch/*/kernel/trace.c
F: include/trace/events/osnoise.h
F: kernel/trace/trace_hwlat.c
F: kernel/trace/trace_irqsoff.c
+F: kernel/trace/trace_osnoise.c
F: kernel/trace/trace_sched_wakeup.c
-F: Documentation/trace/osnoise-tracer.rst
-F: Documentation/trace/timerlat-tracer.rst
-F: Documentation/trace/hwlat_detector.rst
-F: arch/*/kernel/trace.c
-
-Real-time Linux Analysis (RTLA) tools
-M: Daniel Bristot de Oliveira <bristot@kernel.org>
-M: Steven Rostedt <rostedt@goodmis.org>
-L: linux-trace-devel@vger.kernel.org
-S: Maintained
-F: Documentation/tools/rtla/
-F: tools/tracing/rtla/
-
-TECHNICAL ADVISORY BOARD PROCESS DOCS
-M: "Theodore Ts'o" <tytso@mit.edu>
-M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-L: tech-board-discuss@lists.linux-foundation.org
-S: Maintained
-F: Documentation/process/researcher-guidelines.rst
-F: Documentation/process/contribution-maturity-model.rst
TRADITIONAL CHINESE DOCUMENTATION
M: Hu Haowen <src.res@email.cn>
@@ -21782,8 +21793,8 @@ USB ISP1760 DRIVER
M: Rui Miguel Silva <rui.silva@linaro.org>
L: linux-usb@vger.kernel.org
S: Maintained
-F: drivers/usb/isp1760/*
F: Documentation/devicetree/bindings/usb/nxp,isp1760.yaml
+F: drivers/usb/isp1760/*
USB LAN78XX ETHERNET DRIVER
M: Woojung Huh <woojung.huh@microchip.com>
@@ -21854,6 +21865,13 @@ L: linux-usb@vger.kernel.org
S: Supported
F: drivers/usb/class/usblp.c
+USB QMI WWAN NETWORK DRIVER
+M: Bjørn Mork <bjorn@mork.no>
+L: netdev@vger.kernel.org
+S: Maintained
+F: Documentation/ABI/testing/sysfs-class-net-qmi
+F: drivers/net/usb/qmi_wwan.c
+
USB RAW GADGET DRIVER
R: Andrey Konovalov <andreyknvl@gmail.com>
L: linux-usb@vger.kernel.org
@@ -21862,13 +21880,6 @@ F: Documentation/usb/raw-gadget.rst
F: drivers/usb/gadget/legacy/raw_gadget.c
F: include/uapi/linux/usb/raw_gadget.h
-USB QMI WWAN NETWORK DRIVER
-M: Bjørn Mork <bjorn@mork.no>
-L: netdev@vger.kernel.org
-S: Maintained
-F: Documentation/ABI/testing/sysfs-class-net-qmi
-F: drivers/net/usb/qmi_wwan.c
-
USB RTL8150 DRIVER
M: Petko Manolov <petkan@nucleusys.com>
L: linux-usb@vger.kernel.org
@@ -22120,6 +22131,12 @@ F: drivers/vfio/mdev/
F: include/linux/mdev.h
F: samples/vfio-mdev/
+VFIO MLX5 PCI DRIVER
+M: Yishai Hadas <yishaih@nvidia.com>
+L: kvm@vger.kernel.org
+S: Maintained
+F: drivers/vfio/pci/mlx5/
+
VFIO PCI DEVICE SPECIFIC DRIVERS
R: Jason Gunthorpe <jgg@nvidia.com>
R: Yishai Hadas <yishaih@nvidia.com>
@@ -22136,12 +22153,6 @@ L: kvm@vger.kernel.org
S: Maintained
F: drivers/vfio/platform/
-VFIO MLX5 PCI DRIVER
-M: Yishai Hadas <yishaih@nvidia.com>
-L: kvm@vger.kernel.org
-S: Maintained
-F: drivers/vfio/pci/mlx5/
-
VGA_SWITCHEROO
R: Lukas Wunner <lukas@wunner.de>
S: Maintained
@@ -22151,8 +22162,8 @@ F: drivers/gpu/vga/vga_switcheroo.c
F: include/linux/vga_switcheroo.h
VIA RHINE NETWORK DRIVER
-S: Maintained
M: Kevin Brace <kevinbrace@bracecomputerlab.com>
+S: Maintained
F: drivers/net/ethernet/via/via-rhine.c
VIA SD/MMC CARD CONTROLLER DRIVER
@@ -22204,6 +22215,14 @@ S: Maintained
F: drivers/media/common/videobuf2/*
F: include/media/videobuf2-*
+VIDTV VIRTUAL DIGITAL TV DRIVER
+M: Daniel W. S. Almeida <dwlsalmeida@gmail.com>
+L: linux-media@vger.kernel.org
+S: Maintained
+W: https://linuxtv.org
+T: git git://linuxtv.org/media_tree.git
+F: drivers/media/test-drivers/vidtv/*
+
VIMC VIRTUAL MEDIA CONTROLLER DRIVER
M: Shuah Khan <skhan@linuxfoundation.org>
R: Kieran Bingham <kieran.bingham@ideasonboard.com>
@@ -22233,6 +22252,16 @@ F: include/uapi/linux/virtio_vsock.h
F: net/vmw_vsock/virtio_transport.c
F: net/vmw_vsock/virtio_transport_common.c
+VIRTIO BALLOON
+M: "Michael S. Tsirkin" <mst@redhat.com>
+M: David Hildenbrand <david@redhat.com>
+L: virtualization@lists.linux-foundation.org
+S: Maintained
+F: drivers/virtio/virtio_balloon.c
+F: include/linux/balloon_compaction.h
+F: include/uapi/linux/virtio_balloon.h
+F: mm/balloon_compaction.c
+
VIRTIO BLOCK AND SCSI DRIVERS
M: "Michael S. Tsirkin" <mst@redhat.com>
M: Jason Wang <jasowang@redhat.com>
@@ -22275,30 +22304,6 @@ F: include/linux/vringh.h
F: include/uapi/linux/virtio_*.h
F: tools/virtio/
-VISL VIRTUAL STATELESS DECODER DRIVER
-M: Daniel Almeida <daniel.almeida@collabora.com>
-L: linux-media@vger.kernel.org
-S: Supported
-F: drivers/media/test-drivers/visl
-
-IFCVF VIRTIO DATA PATH ACCELERATOR
-R: Zhu Lingshan <lingshan.zhu@intel.com>
-F: drivers/vdpa/ifcvf/
-
-SNET DPU VIRTIO DATA PATH ACCELERATOR
-R: Alvaro Karsz <alvaro.karsz@solid-run.com>
-F: drivers/vdpa/solidrun/
-
-VIRTIO BALLOON
-M: "Michael S. Tsirkin" <mst@redhat.com>
-M: David Hildenbrand <david@redhat.com>
-L: virtualization@lists.linux-foundation.org
-S: Maintained
-F: drivers/virtio/virtio_balloon.c
-F: include/uapi/linux/virtio_balloon.h
-F: include/linux/balloon_compaction.h
-F: mm/balloon_compaction.c
-
VIRTIO CRYPTO DRIVER
M: Gonglei <arei.gonglei@huawei.com>
L: virtualization@lists.linux-foundation.org
@@ -22359,11 +22364,20 @@ L: virtualization@lists.linux-foundation.org
L: netdev@vger.kernel.org
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost.git
-F: kernel/vhost_task.c
F: drivers/vhost/
F: include/linux/sched/vhost_task.h
F: include/linux/vhost_iotlb.h
F: include/uapi/linux/vhost.h
+F: kernel/vhost_task.c
+
+VIRTIO I2C DRIVER
+M: Conghui Chen <conghui.chen@intel.com>
+M: Viresh Kumar <viresh.kumar@linaro.org>
+L: linux-i2c@vger.kernel.org
+L: virtualization@lists.linux-foundation.org
+S: Maintained
+F: drivers/i2c/busses/i2c-virtio.c
+F: include/uapi/linux/virtio_i2c.h
VIRTIO INPUT DRIVER
M: Gerd Hoffmann <kraxel@redhat.com>
@@ -22386,6 +22400,13 @@ W: https://virtio-mem.gitlab.io/
F: drivers/virtio/virtio_mem.c
F: include/uapi/linux/virtio_mem.h
+VIRTIO PMEM DRIVER
+M: Pankaj Gupta <pankaj.gupta.linux@gmail.com>
+L: virtualization@lists.linux-foundation.org
+S: Maintained
+F: drivers/nvdimm/nd_virtio.c
+F: drivers/nvdimm/virtio_pmem.c
+
VIRTIO SOUND DRIVER
M: Anton Yakovlev <anton.yakovlev@opensynergy.com>
M: "Michael S. Tsirkin" <mst@redhat.com>
@@ -22395,22 +22416,6 @@ S: Maintained
F: include/uapi/linux/virtio_snd.h
F: sound/virtio/*
-VIRTIO I2C DRIVER
-M: Conghui Chen <conghui.chen@intel.com>
-M: Viresh Kumar <viresh.kumar@linaro.org>
-L: linux-i2c@vger.kernel.org
-L: virtualization@lists.linux-foundation.org
-S: Maintained
-F: drivers/i2c/busses/i2c-virtio.c
-F: include/uapi/linux/virtio_i2c.h
-
-VIRTIO PMEM DRIVER
-M: Pankaj Gupta <pankaj.gupta.linux@gmail.com>
-L: virtualization@lists.linux-foundation.org
-S: Maintained
-F: drivers/nvdimm/virtio_pmem.c
-F: drivers/nvdimm/nd_virtio.c
-
VIRTUAL BOX GUEST DEVICE DRIVER
M: Hans de Goede <hdegoede@redhat.com>
M: Arnd Bergmann <arnd@arndb.de>
@@ -22432,6 +22437,12 @@ S: Maintained
F: drivers/input/serio/userio.c
F: include/uapi/linux/userio.h
+VISL VIRTUAL STATELESS DECODER DRIVER
+M: Daniel Almeida <daniel.almeida@collabora.com>
+L: linux-media@vger.kernel.org
+S: Supported
+F: drivers/media/test-drivers/visl
+
VIVID VIRTUAL VIDEO DRIVER
M: Hans Verkuil <hverkuil@xs4all.nl>
L: linux-media@vger.kernel.org
@@ -22440,14 +22451,6 @@ W: https://linuxtv.org
T: git git://linuxtv.org/media_tree.git
F: drivers/media/test-drivers/vivid/*
-VIDTV VIRTUAL DIGITAL TV DRIVER
-M: Daniel W. S. Almeida <dwlsalmeida@gmail.com>
-L: linux-media@vger.kernel.org
-S: Maintained
-W: https://linuxtv.org
-T: git git://linuxtv.org/media_tree.git
-F: drivers/media/test-drivers/vidtv/*
-
VLYNQ BUS
M: Florian Fainelli <f.fainelli@gmail.com>
L: openwrt-devel@lists.openwrt.org (subscribers-only)
@@ -22455,16 +22458,6 @@ S: Maintained
F: drivers/vlynq/vlynq.c
F: include/linux/vlynq.h
-VME SUBSYSTEM
-M: Martyn Welch <martyn@welchs.me.uk>
-M: Manohar Vanga <manohar.vanga@gmail.com>
-M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-L: linux-kernel@vger.kernel.org
-S: Odd fixes
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git
-F: Documentation/driver-api/vme.rst
-F: drivers/staging/vme_user/
-
VM SOCKETS (AF_VSOCK)
M: Stefano Garzarella <sgarzare@redhat.com>
L: virtualization@lists.linux-foundation.org
@@ -22478,6 +22471,28 @@ F: include/uapi/linux/vsockmon.h
F: net/vmw_vsock/
F: tools/testing/vsock/
+VMALLOC
+M: Andrew Morton <akpm@linux-foundation.org>
+R: Uladzislau Rezki <urezki@gmail.com>
+R: Christoph Hellwig <hch@infradead.org>
+R: Lorenzo Stoakes <lstoakes@gmail.com>
+L: linux-mm@kvack.org
+S: Maintained
+W: http://www.linux-mm.org
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
+F: include/linux/vmalloc.h
+F: mm/vmalloc.c
+
+VME SUBSYSTEM
+M: Martyn Welch <martyn@welchs.me.uk>
+M: Manohar Vanga <manohar.vanga@gmail.com>
+M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+L: linux-kernel@vger.kernel.org
+S: Odd fixes
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git
+F: Documentation/driver-api/vme.rst
+F: drivers/staging/vme_user/
+
VMWARE BALLOON DRIVER
M: Nadav Amit <namit@vmware.com>
R: VMware PV-Drivers Reviewers <pv-drivers@vmware.com>
@@ -22659,9 +22674,9 @@ F: drivers/input/tablet/wacom_serial4.c
WANGXUN ETHERNET DRIVER
M: Jiawen Wu <jiawenwu@trustnetic.com>
M: Mengyuan Lou <mengyuanlou@net-swift.com>
-W: https://www.net-swift.com
L: netdev@vger.kernel.org
S: Maintained
+W: https://www.net-swift.com
F: Documentation/networking/device_drivers/ethernet/wangxun/*
F: drivers/net/ethernet/wangxun/
@@ -22676,8 +22691,8 @@ F: Documentation/devicetree/bindings/watchdog/
F: Documentation/watchdog/
F: drivers/watchdog/
F: include/linux/watchdog.h
-F: include/uapi/linux/watchdog.h
F: include/trace/events/watchdog.h
+F: include/uapi/linux/watchdog.h
WHISKEYCOVE PMIC GPIO DRIVER
M: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
@@ -22834,8 +22849,8 @@ R: "H. Peter Anvin" <hpa@zytor.com>
L: linux-kernel@vger.kernel.org
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86/core
-F: Documentation/devicetree/bindings/x86/
F: Documentation/arch/x86/
+F: Documentation/devicetree/bindings/x86/
F: arch/x86/
X86 ENTRY CODE
@@ -22966,6 +22981,8 @@ M: John Fastabend <john.fastabend@gmail.com>
L: netdev@vger.kernel.org
L: bpf@vger.kernel.org
S: Supported
+F: drivers/net/ethernet/*/*/*/*/*xdp*
+F: drivers/net/ethernet/*/*/*xdp*
F: include/net/xdp.h
F: include/net/xdp_priv.h
F: include/trace/events/xdp.h
@@ -22973,10 +22990,8 @@ F: kernel/bpf/cpumap.c
F: kernel/bpf/devmap.c
F: net/core/xdp.c
F: samples/bpf/xdp*
-F: tools/testing/selftests/bpf/*xdp*
F: tools/testing/selftests/bpf/*/*xdp*
-F: drivers/net/ethernet/*/*/*/*/*xdp*
-F: drivers/net/ethernet/*/*/*xdp*
+F: tools/testing/selftests/bpf/*xdp*
K: (?:\b|_)xdp(?:\b|_)
XDP SOCKETS (AF_XDP)
@@ -22988,11 +23003,11 @@ L: netdev@vger.kernel.org
L: bpf@vger.kernel.org
S: Maintained
F: Documentation/networking/af_xdp.rst
+F: include/net/netns/xdp.h
F: include/net/xdp_sock*
F: include/net/xsk_buff_pool.h
F: include/uapi/linux/if_xdp.h
F: include/uapi/linux/xdp_diag.h
-F: include/net/netns/xdp.h
F: net/xdp/
F: tools/testing/selftests/bpf/*xsk*
@@ -23094,11 +23109,11 @@ F: include/xen/arm/swiotlb-xen.h
F: include/xen/swiotlb-xen.h
XFS FILESYSTEM
-C: irc://irc.oftc.net/xfs
M: Darrick J. Wong <djwong@kernel.org>
L: linux-xfs@vger.kernel.org
S: Supported
W: http://xfs.org/
+C: irc://irc.oftc.net/xfs
T: git git://git.kernel.org/pub/scm/fs/xfs/xfs-linux.git
F: Documentation/ABI/testing/sysfs-fs-xfs
F: Documentation/admin-guide/xfs.rst
@@ -23128,16 +23143,28 @@ S: Maintained
F: Documentation/devicetree/bindings/net/can/xilinx,can.yaml
F: drivers/net/can/xilinx_can.c
+XILINX EVENT MANAGEMENT DRIVER
+M: Abhyuday Godhasara <abhyuday.godhasara@xilinx.com>
+S: Maintained
+F: drivers/soc/xilinx/xlnx_event_manager.c
+F: include/linux/firmware/xlnx-event-manager.h
+
XILINX GPIO DRIVER
M: Shubhrajyoti Datta <shubhrajyoti.datta@xilinx.com>
R: Srinivas Neeli <srinivas.neeli@xilinx.com>
R: Michal Simek <michal.simek@amd.com>
S: Maintained
-F: Documentation/devicetree/bindings/gpio/xlnx,gpio-xilinx.yaml
F: Documentation/devicetree/bindings/gpio/gpio-zynq.yaml
+F: Documentation/devicetree/bindings/gpio/xlnx,gpio-xilinx.yaml
F: drivers/gpio/gpio-xilinx.c
F: drivers/gpio/gpio-zynq.c
+XILINX PWM DRIVER
+M: Sean Anderson <sean.anderson@seco.com>
+S: Maintained
+F: drivers/pwm/pwm-xilinx.c
+F: include/clocksource/timer-xilinx.h
+
XILINX SD-FEC IP CORES
M: Derek Kiernan <derek.kiernan@xilinx.com>
M: Dragan Cvetic <dragan.cvetic@xilinx.com>
@@ -23149,12 +23176,6 @@ F: drivers/misc/Makefile
F: drivers/misc/xilinx_sdfec.c
F: include/uapi/misc/xilinx_sdfec.h
-XILINX PWM DRIVER
-M: Sean Anderson <sean.anderson@seco.com>
-S: Maintained
-F: drivers/pwm/pwm-xilinx.c
-F: include/clocksource/timer-xilinx.h
-
XILINX UARTLITE SERIAL DRIVER
M: Peter Korsgaard <jacmet@sunsite.dk>
L: linux-serial@vger.kernel.org
@@ -23220,12 +23241,6 @@ M: Harsha <harsha.harsha@xilinx.com>
S: Maintained
F: drivers/crypto/xilinx/zynqmp-sha.c
-XILINX EVENT MANAGEMENT DRIVER
-M: Abhyuday Godhasara <abhyuday.godhasara@xilinx.com>
-S: Maintained
-F: drivers/soc/xilinx/xlnx_event_manager.c
-F: include/linux/firmware/xlnx-event-manager.h
-
XILLYBUS DRIVER
M: Eli Billauer <eli.billauer@gmail.com>
L: linux-kernel@vger.kernel.org
@@ -23273,6 +23288,13 @@ S: Maintained
F: Documentation/input/devices/yealink.rst
F: drivers/input/misc/yealink.*
+Z3FOLD COMPRESSED PAGE ALLOCATOR
+M: Vitaly Wool <vitaly.wool@konsulko.com>
+R: Miaohe Lin <linmiaohe@huawei.com>
+L: linux-mm@kvack.org
+S: Maintained
+F: mm/z3fold.c
+
Z8530 DRIVER FOR AX.25
M: Joerg Reuter <jreuter@yaina.de>
L: linux-hams@vger.kernel.org
@@ -23290,13 +23312,6 @@ L: linux-mm@kvack.org
S: Maintained
F: mm/zbud.c
-Z3FOLD COMPRESSED PAGE ALLOCATOR
-M: Vitaly Wool <vitaly.wool@konsulko.com>
-R: Miaohe Lin <linmiaohe@huawei.com>
-L: linux-mm@kvack.org
-S: Maintained
-F: mm/z3fold.c
-
ZD1211RW WIRELESS DRIVER
M: Ulrich Kunitz <kune@deine-taler.de>
L: linux-wireless@vger.kernel.org
@@ -23383,10 +23398,10 @@ M: Nick Terrell <terrelln@fb.com>
S: Maintained
B: https://github.com/facebook/zstd/issues
T: git https://github.com/terrelln/linux.git
+F: crypto/zstd.c
F: include/linux/zstd*
-F: lib/zstd/
F: lib/decompress_unzstd.c
-F: crypto/zstd.c
+F: lib/zstd/
N: zstd
K: zstd
@@ -23398,13 +23413,6 @@ L: linux-mm@kvack.org
S: Maintained
F: mm/zswap.c
-NXP BLUETOOTH WIRELESS DRIVERS
-M: Amitkumar Karwar <amitkumar.karwar@nxp.com>
-M: Neeraj Kale <neeraj.sanjaykale@nxp.com>
-S: Maintained
-F: Documentation/devicetree/bindings/net/bluetooth/nxp,88w8987-bt.yaml
-F: drivers/bluetooth/btnxpuart.c
-
THE REST
M: Linus Torvalds <torvalds@linux-foundation.org>
L: linux-kernel@vger.kernel.org
diff --git a/Makefile b/Makefile
index 9d765ebcccf1..f836936fb4d8 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
VERSION = 6
PATCHLEVEL = 4
SUBLEVEL = 0
-EXTRAVERSION = -rc1
+EXTRAVERSION = -rc2
NAME = Hurr durr I'ma ninja sloth
# *DOCUMENTATION*
diff --git a/arch/arc/include/asm/fb.h b/arch/arc/include/asm/fb.h
index dc2e303cdbbb..9c2383d29cbb 100644
--- a/arch/arc/include/asm/fb.h
+++ b/arch/arc/include/asm/fb.h
@@ -1,20 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0 */
+
#ifndef _ASM_FB_H_
#define _ASM_FB_H_
-#include <linux/fb.h>
-#include <linux/fs.h>
-#include <asm/page.h>
-
-static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
- unsigned long off)
-{
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-}
-
-static inline int fb_is_primary_device(struct fb_info *info)
-{
- return 0;
-}
+#include <asm-generic/fb.h>
#endif /* _ASM_FB_H_ */
diff --git a/arch/arm/include/asm/fb.h b/arch/arm/include/asm/fb.h
index d92e99cd8c8a..ce20a43c3033 100644
--- a/arch/arm/include/asm/fb.h
+++ b/arch/arm/include/asm/fb.h
@@ -1,19 +1,6 @@
#ifndef _ASM_FB_H_
#define _ASM_FB_H_
-#include <linux/fb.h>
-#include <linux/fs.h>
-#include <asm/page.h>
-
-static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
- unsigned long off)
-{
- vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
-}
-
-static inline int fb_is_primary_device(struct fb_info *info)
-{
- return 0;
-}
+#include <asm-generic/fb.h>
#endif /* _ASM_FB_H_ */
diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c
index 53be7ea6181b..9d2192156087 100644
--- a/arch/arm/kernel/unwind.c
+++ b/arch/arm/kernel/unwind.c
@@ -308,6 +308,29 @@ static int unwind_exec_pop_subset_r0_to_r3(struct unwind_ctrl_block *ctrl,
return URC_OK;
}
+static unsigned long unwind_decode_uleb128(struct unwind_ctrl_block *ctrl)
+{
+ unsigned long bytes = 0;
+ unsigned long insn;
+ unsigned long result = 0;
+
+ /*
+ * unwind_get_byte() will advance `ctrl` one instruction at a time, so
+ * loop until we get an instruction byte where bit 7 is not set.
+ *
+ * Note: This decodes a maximum of 4 bytes to output 28 bits data where
+ * max is 0xfffffff: that will cover a vsp increment of 1073742336, hence
+ * it is sufficient for unwinding the stack.
+ */
+ do {
+ insn = unwind_get_byte(ctrl);
+ result |= (insn & 0x7f) << (bytes * 7);
+ bytes++;
+ } while (!!(insn & 0x80) && (bytes != sizeof(result)));
+
+ return result;
+}
+
/*
* Execute the current unwind instruction.
*/
@@ -361,7 +384,7 @@ static int unwind_exec_insn(struct unwind_ctrl_block *ctrl)
if (ret)
goto error;
} else if (insn == 0xb2) {
- unsigned long uleb128 = unwind_get_byte(ctrl);
+ unsigned long uleb128 = unwind_decode_uleb128(ctrl);
ctrl->vrs[SP] += 0x204 + (uleb128 << 2);
} else {
diff --git a/arch/arm/mach-sa1100/jornada720_ssp.c b/arch/arm/mach-sa1100/jornada720_ssp.c
index 67f72ca984b2..1956b095e699 100644
--- a/arch/arm/mach-sa1100/jornada720_ssp.c
+++ b/arch/arm/mach-sa1100/jornada720_ssp.c
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-only
-/**
+/*
* arch/arm/mac-sa1100/jornada720_ssp.c
*
* Copyright (C) 2006/2007 Kristoffer Ericson <Kristoffer.Ericson@gmail.com>
@@ -26,6 +26,7 @@ static unsigned long jornada_ssp_flags;
/**
* jornada_ssp_reverse - reverses input byte
+ * @byte: input byte to reverse
*
* we need to reverse all data we receive from the mcu due to its physical location
* returns : 01110111 -> 11101110
@@ -46,6 +47,7 @@ EXPORT_SYMBOL(jornada_ssp_reverse);
/**
* jornada_ssp_byte - waits for ready ssp bus and sends byte
+ * @byte: input byte to transmit
*
* waits for fifo buffer to clear and then transmits, if it doesn't then we will
* timeout after <timeout> rounds. Needs mcu running before its called.
@@ -77,6 +79,7 @@ EXPORT_SYMBOL(jornada_ssp_byte);
/**
* jornada_ssp_inout - decide if input is command or trading byte
+ * @byte: input byte to send (may be %TXDUMMY)
*
* returns : (jornada_ssp_byte(byte)) on success
* : %-ETIMEDOUT on timeout failure
diff --git a/arch/arm/vfp/entry.S b/arch/arm/vfp/entry.S
index 7483ef8bccda..62206ef25037 100644
--- a/arch/arm/vfp/entry.S
+++ b/arch/arm/vfp/entry.S
@@ -23,6 +23,9 @@
@
ENTRY(do_vfp)
mov r1, r10
- mov r3, r9
- b vfp_entry
+ str lr, [sp, #-8]!
+ add r3, sp, #4
+ str r9, [r3]
+ bl vfp_entry
+ ldr pc, [sp], #8
ENDPROC(do_vfp)
diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S
index 4d8478264d82..a4610d0f3215 100644
--- a/arch/arm/vfp/vfphw.S
+++ b/arch/arm/vfp/vfphw.S
@@ -172,13 +172,14 @@ vfp_hw_state_valid:
@ out before setting an FPEXC that
@ stops us reading stuff
VFPFMXR FPEXC, r1 @ Restore FPEXC last
+ mov sp, r3 @ we think we have handled things
+ pop {lr}
sub r2, r2, #4 @ Retry current instruction - if Thumb
str r2, [sp, #S_PC] @ mode it's two 16-bit instructions,
@ else it's one 32-bit instruction, so
@ always subtract 4 from the following
@ instruction address.
- mov lr, r3 @ we think we have handled things
local_bh_enable_and_ret:
adr r0, .
mov r1, #SOFTIRQ_DISABLE_OFFSET
@@ -209,8 +210,9 @@ skip:
process_exception:
DBGSTR "bounce"
+ mov sp, r3 @ setup for a return to the user code.
+ pop {lr}
mov r2, sp @ nothing stacked - regdump is at TOS
- mov lr, r3 @ setup for a return to the user code.
@ Now call the C code to package up the bounce to the support code
@ r0 holds the trigger instruction
diff --git a/arch/arm64/include/asm/fb.h b/arch/arm64/include/asm/fb.h
index bdc735ee1f67..1a495d8fb2ce 100644
--- a/arch/arm64/include/asm/fb.h
+++ b/arch/arm64/include/asm/fb.h
@@ -5,19 +5,6 @@
#ifndef __ASM_FB_H_
#define __ASM_FB_H_
-#include <linux/fb.h>
-#include <linux/fs.h>
-#include <asm/page.h>
-
-static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
- unsigned long off)
-{
- vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
-}
-
-static inline int fb_is_primary_device(struct fb_info *info)
-{
- return 0;
-}
+#include <asm-generic/fb.h>
#endif /* __ASM_FB_H_ */
diff --git a/arch/ia64/include/asm/fb.h b/arch/ia64/include/asm/fb.h
index 5f95782bfa46..1717b26fd423 100644
--- a/arch/ia64/include/asm/fb.h
+++ b/arch/ia64/include/asm/fb.h
@@ -2,11 +2,14 @@
#ifndef _ASM_FB_H_
#define _ASM_FB_H_
-#include <linux/fb.h>
-#include <linux/fs.h>
+#include <linux/compiler.h>
#include <linux/efi.h>
+#include <linux/string.h>
+
#include <asm/page.h>
+struct file;
+
static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
unsigned long off)
{
@@ -15,10 +18,26 @@ static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
else
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
}
+#define fb_pgprotect fb_pgprotect
+
+static inline void fb_memcpy_fromio(void *to, const volatile void __iomem *from, size_t n)
+{
+ memcpy(to, (void __force *)from, n);
+}
+#define fb_memcpy_fromio fb_memcpy_fromio
-static inline int fb_is_primary_device(struct fb_info *info)
+static inline void fb_memcpy_toio(volatile void __iomem *to, const void *from, size_t n)
{
- return 0;
+ memcpy((void __force *)to, from, n);
}
+#define fb_memcpy_toio fb_memcpy_toio
+
+static inline void fb_memset_io(volatile void __iomem *addr, int c, size_t n)
+{
+ memset((void __force *)addr, c, n);
+}
+#define fb_memset fb_memset_io
+
+#include <asm-generic/fb.h>
#endif /* _ASM_FB_H_ */
diff --git a/arch/loongarch/include/asm/fb.h b/arch/loongarch/include/asm/fb.h
index 3116bde8772d..0b218b10a9ec 100644
--- a/arch/loongarch/include/asm/fb.h
+++ b/arch/loongarch/include/asm/fb.h
@@ -5,19 +5,27 @@
#ifndef _ASM_FB_H_
#define _ASM_FB_H_
-#include <linux/fb.h>
-#include <linux/fs.h>
-#include <asm/page.h>
+#include <linux/compiler.h>
+#include <linux/string.h>
-static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
- unsigned long off)
+static inline void fb_memcpy_fromio(void *to, const volatile void __iomem *from, size_t n)
{
- vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+ memcpy(to, (void __force *)from, n);
}
+#define fb_memcpy_fromio fb_memcpy_fromio
-static inline int fb_is_primary_device(struct fb_info *info)
+static inline void fb_memcpy_toio(volatile void __iomem *to, const void *from, size_t n)
{
- return 0;
+ memcpy((void __force *)to, from, n);
}
+#define fb_memcpy_toio fb_memcpy_toio
+
+static inline void fb_memset_io(volatile void __iomem *addr, int c, size_t n)
+{
+ memset((void __force *)addr, c, n);
+}
+#define fb_memset fb_memset_io
+
+#include <asm-generic/fb.h>
#endif /* _ASM_FB_H_ */
diff --git a/arch/m68k/include/asm/fb.h b/arch/m68k/include/asm/fb.h
index b86c6e2e26dd..24273fc7ad91 100644
--- a/arch/m68k/include/asm/fb.h
+++ b/arch/m68k/include/asm/fb.h
@@ -2,22 +2,18 @@
#ifndef _ASM_FB_H_
#define _ASM_FB_H_
-#include <linux/fb.h>
-#include <linux/fs.h>
#include <asm/page.h>
#include <asm/setup.h>
-#ifdef CONFIG_MMU
-#ifdef CONFIG_SUN3
+struct file;
+
static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
unsigned long off)
{
+#ifdef CONFIG_MMU
+#ifdef CONFIG_SUN3
pgprot_val(vma->vm_page_prot) |= SUN3_PAGE_NOCACHE;
-}
#else
-static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
- unsigned long off)
-{
if (CPU_IS_020_OR_030)
pgprot_val(vma->vm_page_prot) |= _PAGE_NOCACHE030;
if (CPU_IS_040_OR_060) {
@@ -25,15 +21,11 @@ static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
/* Use no-cache mode, serialized */
pgprot_val(vma->vm_page_prot) |= _PAGE_NOCACHE_S;
}
-}
#endif /* CONFIG_SUN3 */
-#else
-#define fb_pgprotect(...) do {} while (0)
#endif /* CONFIG_MMU */
-
-static inline int fb_is_primary_device(struct fb_info *info)
-{
- return 0;
}
+#define fb_pgprotect fb_pgprotect
+
+#include <asm-generic/fb.h>
#endif /* _ASM_FB_H_ */
diff --git a/arch/mips/include/asm/fb.h b/arch/mips/include/asm/fb.h
index bd3f68c9ddfc..18b7226403ba 100644
--- a/arch/mips/include/asm/fb.h
+++ b/arch/mips/include/asm/fb.h
@@ -1,19 +1,39 @@
#ifndef _ASM_FB_H_
#define _ASM_FB_H_
-#include <linux/fb.h>
-#include <linux/fs.h>
#include <asm/page.h>
+struct file;
+
static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
unsigned long off)
{
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
}
+#define fb_pgprotect fb_pgprotect
-static inline int fb_is_primary_device(struct fb_info *info)
+/*
+ * MIPS doesn't define __raw_ I/O macros, so the helpers
+ * in <asm-generic/fb.h> don't generate fb_readq() and
+ * fb_write(). We have to provide them here.
+ *
+ * TODO: Convert MIPS to generic I/O. The helpers below can
+ * then be removed.
+ */
+#ifdef CONFIG_64BIT
+static inline u64 fb_readq(const volatile void __iomem *addr)
{
- return 0;
+ return __raw_readq(addr);
}
+#define fb_readq fb_readq
+
+static inline void fb_writeq(u64 b, volatile void __iomem *addr)
+{
+ __raw_writeq(b, addr);
+}
+#define fb_writeq fb_writeq
+#endif
+
+#include <asm-generic/fb.h>
#endif /* _ASM_FB_H_ */
diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile
index a2d8600521f9..968ebe17494c 100644
--- a/arch/parisc/Makefile
+++ b/arch/parisc/Makefile
@@ -11,7 +11,7 @@
# Copyright (C) 1994 by Linus Torvalds
# Portions Copyright (C) 1999 The Puffin Group
#
-# Modified for PA-RISC Linux by Paul Lahaie, Alex deVries,
+# Modified for PA-RISC Linux by Paul Lahaie, Alex deVries,
# Mike Shaver, Helge Deller and Martin K. Petersen
#
@@ -119,6 +119,8 @@ export LIBGCC
libs-y += arch/parisc/lib/ $(LIBGCC)
+drivers-y += arch/parisc/video/
+
boot := arch/parisc/boot
PALO := $(shell if (which palo 2>&1); then : ; \
diff --git a/arch/parisc/include/asm/fb.h b/arch/parisc/include/asm/fb.h
index 55d29c4f716e..658a8a7dc531 100644
--- a/arch/parisc/include/asm/fb.h
+++ b/arch/parisc/include/asm/fb.h
@@ -2,23 +2,13 @@
#ifndef _ASM_FB_H_
#define _ASM_FB_H_
-#include <linux/fb.h>
-#include <linux/fs.h>
-#include <asm/page.h>
+struct fb_info;
-static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
- unsigned long off)
-{
- pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE;
-}
-
-#if defined(CONFIG_FB_STI)
+#if defined(CONFIG_STI_CORE)
int fb_is_primary_device(struct fb_info *info);
-#else
-static inline int fb_is_primary_device(struct fb_info *info)
-{
- return 0;
-}
+#define fb_is_primary_device fb_is_primary_device
#endif
+#include <asm-generic/fb.h>
+
#endif /* _ASM_FB_H_ */
diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h
index e2950f5db7c9..e715df5385d6 100644
--- a/arch/parisc/include/asm/pgtable.h
+++ b/arch/parisc/include/asm/pgtable.h
@@ -413,12 +413,12 @@ extern void paging_init (void);
* For the 64bit version, the offset is extended by 32bit.
*/
#define __swp_type(x) ((x).val & 0x1f)
-#define __swp_offset(x) ( (((x).val >> 6) & 0x7) | \
- (((x).val >> 8) & ~0x7) )
+#define __swp_offset(x) ( (((x).val >> 5) & 0x7) | \
+ (((x).val >> 10) << 3) )
#define __swp_entry(type, offset) ((swp_entry_t) { \
((type) & 0x1f) | \
- ((offset & 0x7) << 6) | \
- ((offset & ~0x7) << 8) })
+ ((offset & 0x7) << 5) | \
+ ((offset >> 3) << 10) })
#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
diff --git a/arch/parisc/kernel/kexec.c b/arch/parisc/kernel/kexec.c
index 5eb7f30edc1f..db57345a9daf 100644
--- a/arch/parisc/kernel/kexec.c
+++ b/arch/parisc/kernel/kexec.c
@@ -4,6 +4,8 @@
#include <linux/console.h>
#include <linux/kexec.h>
#include <linux/delay.h>
+#include <linux/reboot.h>
+
#include <asm/cacheflush.h>
#include <asm/sections.h>
diff --git a/arch/parisc/video/Makefile b/arch/parisc/video/Makefile
new file mode 100644
index 000000000000..16a73cce4661
--- /dev/null
+++ b/arch/parisc/video/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+obj-$(CONFIG_STI_CORE) += fbdev.o
diff --git a/arch/parisc/video/fbdev.c b/arch/parisc/video/fbdev.c
new file mode 100644
index 000000000000..137561d98246
--- /dev/null
+++ b/arch/parisc/video/fbdev.c
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
+ * Copyright (C) 2001-2020 Helge Deller <deller@gmx.de>
+ * Copyright (C) 2001-2002 Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+ */
+
+#include <linux/fb.h>
+#include <linux/module.h>
+
+#include <video/sticore.h>
+
+int fb_is_primary_device(struct fb_info *info)
+{
+ struct sti_struct *sti;
+
+ sti = sti_get_rom(0);
+
+ /* if no built-in graphics card found, allow any fb driver as default */
+ if (!sti)
+ return true;
+
+ /* return true if it's the default built-in framebuffer driver */
+ return (sti->info == info);
+}
+EXPORT_SYMBOL(fb_is_primary_device);
diff --git a/arch/powerpc/include/asm/fb.h b/arch/powerpc/include/asm/fb.h
index 6541ab77c5b9..5f1a2e5f7654 100644
--- a/arch/powerpc/include/asm/fb.h
+++ b/arch/powerpc/include/asm/fb.h
@@ -2,8 +2,8 @@
#ifndef _ASM_FB_H_
#define _ASM_FB_H_
-#include <linux/fb.h>
#include <linux/fs.h>
+
#include <asm/page.h>
static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
@@ -13,10 +13,8 @@ static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
vma->vm_end - vma->vm_start,
vma->vm_page_prot);
}
+#define fb_pgprotect fb_pgprotect
-static inline int fb_is_primary_device(struct fb_info *info)
-{
- return 0;
-}
+#include <asm-generic/fb.h>
#endif /* _ASM_FB_H_ */
diff --git a/arch/riscv/kernel/pi/Makefile b/arch/riscv/kernel/pi/Makefile
index 5d7cb991f2b8..7b593d44c712 100644
--- a/arch/riscv/kernel/pi/Makefile
+++ b/arch/riscv/kernel/pi/Makefile
@@ -22,7 +22,7 @@ KCOV_INSTRUMENT := n
$(obj)/%.pi.o: OBJCOPYFLAGS := --prefix-symbols=__pi_ \
--remove-section=.note.gnu.property \
- --prefix-alloc-sections=.init
+ --prefix-alloc-sections=.init.pi
$(obj)/%.pi.o: $(obj)/%.o FORCE
$(call if_changed,objcopy)
diff --git a/arch/riscv/kernel/vmlinux.lds.S b/arch/riscv/kernel/vmlinux.lds.S
index f03b5697f8e0..e5f9f4677bbf 100644
--- a/arch/riscv/kernel/vmlinux.lds.S
+++ b/arch/riscv/kernel/vmlinux.lds.S
@@ -84,11 +84,8 @@ SECTIONS
__init_data_begin = .;
INIT_DATA_SECTION(16)
- /* Those sections result from the compilation of kernel/pi/string.c */
- .init.pidata : {
- *(.init.srodata.cst8*)
- *(.init__bug_table*)
- *(.init.sdata*)
+ .init.pi : {
+ *(.init.pi*)
}
.init.bss : {
diff --git a/arch/sh/include/asm/fb.h b/arch/sh/include/asm/fb.h
index 9a0bca2686fd..19df13ee9ca7 100644
--- a/arch/sh/include/asm/fb.h
+++ b/arch/sh/include/asm/fb.h
@@ -2,19 +2,6 @@
#ifndef _ASM_FB_H_
#define _ASM_FB_H_
-#include <linux/fb.h>
-#include <linux/fs.h>
-#include <asm/page.h>
-
-static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
- unsigned long off)
-{
- vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
-}
-
-static inline int fb_is_primary_device(struct fb_info *info)
-{
- return 0;
-}
+#include <asm-generic/fb.h>
#endif /* _ASM_FB_H_ */
diff --git a/arch/sparc/Makefile b/arch/sparc/Makefile
index 74be90529a18..7417345c6639 100644
--- a/arch/sparc/Makefile
+++ b/arch/sparc/Makefile
@@ -60,6 +60,7 @@ libs-y += arch/sparc/prom/
libs-y += arch/sparc/lib/
drivers-$(CONFIG_PM) += arch/sparc/power/
+drivers-$(CONFIG_FB) += arch/sparc/video/
boot := arch/sparc/boot
diff --git a/arch/sparc/include/asm/fb.h b/arch/sparc/include/asm/fb.h
index f699962e9ddf..572ecd3e1cc4 100644
--- a/arch/sparc/include/asm/fb.h
+++ b/arch/sparc/include/asm/fb.h
@@ -1,34 +1,41 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _SPARC_FB_H_
#define _SPARC_FB_H_
-#include <linux/console.h>
-#include <linux/fb.h>
-#include <linux/fs.h>
-#include <asm/page.h>
-#include <asm/prom.h>
+#include <linux/io.h>
+
+struct fb_info;
+struct file;
+struct vm_area_struct;
+
+#ifdef CONFIG_SPARC32
static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
unsigned long off)
-{
-#ifdef CONFIG_SPARC64
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+{ }
+#define fb_pgprotect fb_pgprotect
#endif
-}
-static inline int fb_is_primary_device(struct fb_info *info)
-{
- struct device *dev = info->device;
- struct device_node *node;
+int fb_is_primary_device(struct fb_info *info);
+#define fb_is_primary_device fb_is_primary_device
- if (console_set_on_cmdline)
- return 0;
+static inline void fb_memcpy_fromio(void *to, const volatile void __iomem *from, size_t n)
+{
+ sbus_memcpy_fromio(to, from, n);
+}
+#define fb_memcpy_fromio fb_memcpy_fromio
- node = dev->of_node;
- if (node &&
- node == of_console_device)
- return 1;
+static inline void fb_memcpy_toio(volatile void __iomem *to, const void *from, size_t n)
+{
+ sbus_memcpy_toio(to, from, n);
+}
+#define fb_memcpy_toio fb_memcpy_toio
- return 0;
+static inline void fb_memset_io(volatile void __iomem *addr, int c, size_t n)
+{
+ sbus_memset_io(addr, c, n);
}
+#define fb_memset fb_memset_io
+
+#include <asm-generic/fb.h>
#endif /* _SPARC_FB_H_ */
diff --git a/arch/sparc/video/Makefile b/arch/sparc/video/Makefile
new file mode 100644
index 000000000000..6baddbd58e4d
--- /dev/null
+++ b/arch/sparc/video/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+obj-$(CONFIG_FB) += fbdev.o
diff --git a/arch/sparc/video/fbdev.c b/arch/sparc/video/fbdev.c
new file mode 100644
index 000000000000..25837f128132
--- /dev/null
+++ b/arch/sparc/video/fbdev.c
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/console.h>
+#include <linux/fb.h>
+#include <linux/module.h>
+
+#include <asm/prom.h>
+
+int fb_is_primary_device(struct fb_info *info)
+{
+ struct device *dev = info->device;
+ struct device_node *node;
+
+ if (console_set_on_cmdline)
+ return 0;
+
+ node = dev->of_node;
+ if (node && node == of_console_device)
+ return 1;
+
+ return 0;
+}
+EXPORT_SYMBOL(fb_is_primary_device);
diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
index d096b04bf80e..9d248703cbdd 100644
--- a/arch/x86/events/core.c
+++ b/arch/x86/events/core.c
@@ -1703,10 +1703,8 @@ int x86_pmu_handle_irq(struct pt_regs *regs)
perf_sample_data_init(&data, 0, event->hw.last_period);
- if (has_branch_stack(event)) {
- data.br_stack = &cpuc->lbr_stack;
- data.sample_flags |= PERF_SAMPLE_BRANCH_STACK;
- }
+ if (has_branch_stack(event))
+ perf_sample_save_brstack(&data, event, &cpuc->lbr_stack);
if (perf_event_overflow(event, &data, regs))
x86_pmu_stop(event, 0);
diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c
index a2e566e53076..df88576d6b2a 100644
--- a/arch/x86/events/intel/ds.c
+++ b/arch/x86/events/intel/ds.c
@@ -1229,12 +1229,14 @@ pebs_update_state(bool needed_cb, struct cpu_hw_events *cpuc,
struct perf_event *event, bool add)
{
struct pmu *pmu = event->pmu;
+
/*
* Make sure we get updated with the first PEBS
* event. It will trigger also during removal, but
* that does not hurt:
*/
- bool update = cpuc->n_pebs == 1;
+ if (cpuc->n_pebs == 1)
+ cpuc->pebs_data_cfg = PEBS_UPDATE_DS_SW;
if (needed_cb != pebs_needs_sched_cb(cpuc)) {
if (!needed_cb)
@@ -1242,7 +1244,7 @@ pebs_update_state(bool needed_cb, struct cpu_hw_events *cpuc,
else
perf_sched_cb_dec(pmu);
- update = true;
+ cpuc->pebs_data_cfg |= PEBS_UPDATE_DS_SW;
}
/*
@@ -1252,24 +1254,13 @@ pebs_update_state(bool needed_cb, struct cpu_hw_events *cpuc,
if (x86_pmu.intel_cap.pebs_baseline && add) {
u64 pebs_data_cfg;
- /* Clear pebs_data_cfg and pebs_record_size for first PEBS. */
- if (cpuc->n_pebs == 1) {
- cpuc->pebs_data_cfg = 0;
- cpuc->pebs_record_size = sizeof(struct pebs_basic);
- }
-
pebs_data_cfg = pebs_update_adaptive_cfg(event);
-
- /* Update pebs_record_size if new event requires more data. */
- if (pebs_data_cfg & ~cpuc->pebs_data_cfg) {
- cpuc->pebs_data_cfg |= pebs_data_cfg;
- adaptive_pebs_record_size_update();
- update = true;
- }
+ /*
+ * Be sure to update the thresholds when we change the record.
+ */
+ if (pebs_data_cfg & ~cpuc->pebs_data_cfg)
+ cpuc->pebs_data_cfg |= pebs_data_cfg | PEBS_UPDATE_DS_SW;
}
-
- if (update)
- pebs_update_threshold(cpuc);
}
void intel_pmu_pebs_add(struct perf_event *event)
@@ -1326,9 +1317,17 @@ static void intel_pmu_pebs_via_pt_enable(struct perf_event *event)
wrmsrl(base + idx, value);
}
+static inline void intel_pmu_drain_large_pebs(struct cpu_hw_events *cpuc)
+{
+ if (cpuc->n_pebs == cpuc->n_large_pebs &&
+ cpuc->n_pebs != cpuc->n_pebs_via_pt)
+ intel_pmu_drain_pebs_buffer();
+}
+
void intel_pmu_pebs_enable(struct perf_event *event)
{
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+ u64 pebs_data_cfg = cpuc->pebs_data_cfg & ~PEBS_UPDATE_DS_SW;
struct hw_perf_event *hwc = &event->hw;
struct debug_store *ds = cpuc->ds;
unsigned int idx = hwc->idx;
@@ -1344,11 +1343,22 @@ void intel_pmu_pebs_enable(struct perf_event *event)
if (x86_pmu.intel_cap.pebs_baseline) {
hwc->config |= ICL_EVENTSEL_ADAPTIVE;
- if (cpuc->pebs_data_cfg != cpuc->active_pebs_data_cfg) {
- wrmsrl(MSR_PEBS_DATA_CFG, cpuc->pebs_data_cfg);
- cpuc->active_pebs_data_cfg = cpuc->pebs_data_cfg;
+ if (pebs_data_cfg != cpuc->active_pebs_data_cfg) {
+ /*
+ * drain_pebs() assumes uniform record size;
+ * hence we need to drain when changing said
+ * size.
+ */
+ intel_pmu_drain_large_pebs(cpuc);
+ adaptive_pebs_record_size_update();
+ wrmsrl(MSR_PEBS_DATA_CFG, pebs_data_cfg);
+ cpuc->active_pebs_data_cfg = pebs_data_cfg;
}
}
+ if (cpuc->pebs_data_cfg & PEBS_UPDATE_DS_SW) {
+ cpuc->pebs_data_cfg = pebs_data_cfg;
+ pebs_update_threshold(cpuc);
+ }
if (idx >= INTEL_PMC_IDX_FIXED) {
if (x86_pmu.intel_cap.pebs_format < 5)
@@ -1391,9 +1401,7 @@ void intel_pmu_pebs_disable(struct perf_event *event)
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
struct hw_perf_event *hwc = &event->hw;
- if (cpuc->n_pebs == cpuc->n_large_pebs &&
- cpuc->n_pebs != cpuc->n_pebs_via_pt)
- intel_pmu_drain_pebs_buffer();
+ intel_pmu_drain_large_pebs(cpuc);
cpuc->pebs_enabled &= ~(1ULL << hwc->idx);
diff --git a/arch/x86/include/asm/fb.h b/arch/x86/include/asm/fb.h
index ab4c960146e3..23873da8fb77 100644
--- a/arch/x86/include/asm/fb.h
+++ b/arch/x86/include/asm/fb.h
@@ -2,21 +2,16 @@
#ifndef _ASM_X86_FB_H
#define _ASM_X86_FB_H
-#include <linux/fb.h>
-#include <linux/fs.h>
-#include <asm/page.h>
+struct fb_info;
+struct file;
+struct vm_area_struct;
-static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
- unsigned long off)
-{
- unsigned long prot;
+void fb_pgprotect(struct file *file, struct vm_area_struct *vma, unsigned long off);
+#define fb_pgprotect fb_pgprotect
- prot = pgprot_val(vma->vm_page_prot) & ~_PAGE_CACHE_MASK;
- if (boot_cpu_data.x86 > 3)
- pgprot_val(vma->vm_page_prot) =
- prot | cachemode2protval(_PAGE_CACHE_MODE_UC_MINUS);
-}
+int fb_is_primary_device(struct fb_info *info);
+#define fb_is_primary_device fb_is_primary_device
-extern int fb_is_primary_device(struct fb_info *info);
+#include <asm-generic/fb.h>
#endif /* _ASM_X86_FB_H */
diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h
index 8fc15ed5e60b..abf09882f58b 100644
--- a/arch/x86/include/asm/perf_event.h
+++ b/arch/x86/include/asm/perf_event.h
@@ -121,6 +121,9 @@
#define PEBS_DATACFG_LBRS BIT_ULL(3)
#define PEBS_DATACFG_LBR_SHIFT 24
+/* Steal the highest bit of pebs_data_cfg for SW usage */
+#define PEBS_UPDATE_DS_SW BIT_ULL(63)
+
/*
* Intel "Architectural Performance Monitoring" CPUID
* detection/enumeration details:
diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c
index 4266b64631a4..7e331e8f3692 100644
--- a/arch/x86/kernel/amd_nb.c
+++ b/arch/x86/kernel/amd_nb.c
@@ -36,6 +36,7 @@
#define PCI_DEVICE_ID_AMD_19H_M50H_DF_F4 0x166e
#define PCI_DEVICE_ID_AMD_19H_M60H_DF_F4 0x14e4
#define PCI_DEVICE_ID_AMD_19H_M70H_DF_F4 0x14f4
+#define PCI_DEVICE_ID_AMD_19H_M78H_DF_F4 0x12fc
/* Protect the PCI config register pairs used for SMN. */
static DEFINE_MUTEX(smn_mutex);
@@ -79,6 +80,7 @@ static const struct pci_device_id amd_nb_misc_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M50H_DF_F3) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M60H_DF_F3) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M70H_DF_F3) },
+ { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M78H_DF_F3) },
{}
};
diff --git a/arch/x86/lib/retpoline.S b/arch/x86/lib/retpoline.S
index 27ef53fab6bd..b3b1e376dce8 100644
--- a/arch/x86/lib/retpoline.S
+++ b/arch/x86/lib/retpoline.S
@@ -144,8 +144,8 @@ SYM_CODE_END(__x86_indirect_jump_thunk_array)
*/
.align 64
.skip 63, 0xcc
-SYM_FUNC_START_NOALIGN(zen_untrain_ret);
-
+SYM_START(zen_untrain_ret, SYM_L_GLOBAL, SYM_A_NONE)
+ ANNOTATE_NOENDBR
/*
* As executed from zen_untrain_ret, this is:
*
diff --git a/arch/x86/video/fbdev.c b/arch/x86/video/fbdev.c
index 9fd24846d094..f41a17ebac48 100644
--- a/arch/x86/video/fbdev.c
+++ b/arch/x86/video/fbdev.c
@@ -6,35 +6,37 @@
* for more details.
*
*/
+
#include <linux/fb.h>
-#include <linux/pci.h>
#include <linux/module.h>
+#include <linux/pci.h>
#include <linux/vgaarb.h>
+void fb_pgprotect(struct file *file, struct vm_area_struct *vma, unsigned long off)
+{
+ unsigned long prot;
+
+ prot = pgprot_val(vma->vm_page_prot) & ~_PAGE_CACHE_MASK;
+ if (boot_cpu_data.x86 > 3)
+ pgprot_val(vma->vm_page_prot) =
+ prot | cachemode2protval(_PAGE_CACHE_MODE_UC_MINUS);
+}
+EXPORT_SYMBOL(fb_pgprotect);
+
int fb_is_primary_device(struct fb_info *info)
{
struct device *device = info->device;
- struct pci_dev *default_device = vga_default_device();
struct pci_dev *pci_dev;
- struct resource *res;
if (!device || !dev_is_pci(device))
return 0;
pci_dev = to_pci_dev(device);
- if (default_device) {
- if (pci_dev == default_device)
- return 1;
- return 0;
- }
-
- res = pci_dev->resource + PCI_ROM_RESOURCE;
-
- if (res->flags & IORESOURCE_ROM_SHADOW)
+ if (pci_dev == vga_default_device())
return 1;
-
return 0;
}
EXPORT_SYMBOL(fb_is_primary_device);
+
MODULE_LICENSE("GPL");
diff --git a/drivers/auxdisplay/cfag12864bfb.c b/drivers/auxdisplay/cfag12864bfb.c
index 0df474506fb9..c2cab7e2b126 100644
--- a/drivers/auxdisplay/cfag12864bfb.c
+++ b/drivers/auxdisplay/cfag12864bfb.c
@@ -72,7 +72,7 @@ static int cfag12864bfb_probe(struct platform_device *device)
if (!info)
goto none;
- info->screen_base = (char __iomem *) cfag12864b_buffer;
+ info->screen_buffer = cfag12864b_buffer;
info->screen_size = CFAG12864B_SIZE;
info->fbops = &cfag12864bfb_ops;
info->fix = cfag12864bfb_fix;
diff --git a/drivers/auxdisplay/ht16k33.c b/drivers/auxdisplay/ht16k33.c
index 02425991c159..edaf92b7ea77 100644
--- a/drivers/auxdisplay/ht16k33.c
+++ b/drivers/auxdisplay/ht16k33.c
@@ -640,7 +640,7 @@ static int ht16k33_fbdev_probe(struct device *dev, struct ht16k33_priv *priv,
INIT_DELAYED_WORK(&priv->work, ht16k33_fb_update);
fbdev->info->fbops = &ht16k33_fb_ops;
- fbdev->info->screen_base = (char __iomem *) fbdev->buffer;
+ fbdev->info->screen_buffer = fbdev->buffer;
fbdev->info->screen_size = HT16K33_FB_SIZE;
fbdev->info->fix = ht16k33_fb_fix;
fbdev->info->var = ht16k33_fb_var;
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index 9c35c958f2c8..65ecde3e2a5b 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -1666,7 +1666,7 @@ static int nbd_dev_dbg_init(struct nbd_device *nbd)
return -EIO;
dir = debugfs_create_dir(nbd_name(nbd), nbd_dbg_dir);
- if (!dir) {
+ if (IS_ERR(dir)) {
dev_err(nbd_to_dev(nbd), "Failed to create debugfs dir for '%s'\n",
nbd_name(nbd));
return -EIO;
@@ -1692,7 +1692,7 @@ static int nbd_dbg_init(void)
struct dentry *dbg_dir;
dbg_dir = debugfs_create_dir("nbd", NULL);
- if (!dbg_dir)
+ if (IS_ERR(dbg_dir))
return -EIO;
nbd_dbg_dir = dbg_dir;
diff --git a/drivers/block/rnbd/rnbd-proto.h b/drivers/block/rnbd/rnbd-proto.h
index ea7ac8bca63c..da1d0542d7e2 100644
--- a/drivers/block/rnbd/rnbd-proto.h
+++ b/drivers/block/rnbd/rnbd-proto.h
@@ -241,7 +241,7 @@ static inline blk_opf_t rnbd_to_bio_flags(u32 rnbd_opf)
bio_opf = REQ_OP_WRITE;
break;
case RNBD_OP_FLUSH:
- bio_opf = REQ_OP_FLUSH | REQ_PREFLUSH;
+ bio_opf = REQ_OP_WRITE | REQ_PREFLUSH;
break;
case RNBD_OP_DISCARD:
bio_opf = REQ_OP_DISCARD;
diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
index c7331f519750..c7ed5d69e9ee 100644
--- a/drivers/block/ublk_drv.c
+++ b/drivers/block/ublk_drv.c
@@ -1281,7 +1281,7 @@ static inline int ublk_check_cmd_op(u32 cmd_op)
{
u32 ioc_type = _IOC_TYPE(cmd_op);
- if (IS_ENABLED(CONFIG_BLKDEV_UBLK_LEGACY_OPCODES) && ioc_type != 'u')
+ if (!IS_ENABLED(CONFIG_BLKDEV_UBLK_LEGACY_OPCODES) && ioc_type != 'u')
return -EOPNOTSUPP;
if (ioc_type != 'u' && ioc_type != 0)
diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c
index bdbd907884ce..f332fe7af92b 100644
--- a/drivers/cxl/core/pci.c
+++ b/drivers/cxl/core/pci.c
@@ -571,6 +571,7 @@ void read_cdat_data(struct cxl_port *port)
/* Don't leave table data allocated on error */
devm_kfree(dev, cdat_table);
dev_err(dev, "CDAT data read error\n");
+ return;
}
port->cdat.table = cdat_table + sizeof(__le32);
diff --git a/drivers/dma-buf/dma-resv.c b/drivers/dma-buf/dma-resv.c
index 2a594b754af1..b6f71eb00866 100644
--- a/drivers/dma-buf/dma-resv.c
+++ b/drivers/dma-buf/dma-resv.c
@@ -660,7 +660,7 @@ EXPORT_SYMBOL_GPL(dma_resv_get_singleton);
* dma_resv_lock() already
* RETURNS
* Returns -ERESTARTSYS if interrupted, 0 if the wait timed out, or
- * greater than zer on success.
+ * greater than zero on success.
*/
long dma_resv_wait_timeout(struct dma_resv *obj, enum dma_resv_usage usage,
bool intr, unsigned long timeout)
diff --git a/drivers/dma-buf/sw_sync.c b/drivers/dma-buf/sw_sync.c
index 348b3a9170fa..63f0aeb66db6 100644
--- a/drivers/dma-buf/sw_sync.c
+++ b/drivers/dma-buf/sw_sync.c
@@ -85,7 +85,7 @@ static struct sync_timeline *sync_timeline_create(const char *name)
kref_init(&obj->kref);
obj->context = dma_fence_context_alloc(1);
- strlcpy(obj->name, name, sizeof(obj->name));
+ strscpy(obj->name, name, sizeof(obj->name));
obj->pt_tree = RB_ROOT;
INIT_LIST_HEAD(&obj->pt_list);
diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c
index af22be84034b..538bd677c254 100644
--- a/drivers/firewire/net.c
+++ b/drivers/firewire/net.c
@@ -706,21 +706,22 @@ static void fwnet_receive_packet(struct fw_card *card, struct fw_request *r,
int rcode;
if (destination == IEEE1394_ALL_NODES) {
- kfree(r);
-
- return;
- }
-
- if (offset != dev->handler.offset)
+ // Although the response to the broadcast packet is not necessarily required, the
+ // fw_send_response() function should still be called to maintain the reference
+ // counting of the object. In the case, the call of function just releases the
+ // object as a result to decrease the reference counting.
+ rcode = RCODE_COMPLETE;
+ } else if (offset != dev->handler.offset) {
rcode = RCODE_ADDRESS_ERROR;
- else if (tcode != TCODE_WRITE_BLOCK_REQUEST)
+ } else if (tcode != TCODE_WRITE_BLOCK_REQUEST) {
rcode = RCODE_TYPE_ERROR;
- else if (fwnet_incoming_packet(dev, payload, length,
- source, generation, false) != 0) {
+ } else if (fwnet_incoming_packet(dev, payload, length,
+ source, generation, false) != 0) {
dev_err(&dev->netdev->dev, "incoming packet failure\n");
rcode = RCODE_CONFLICT_ERROR;
- } else
+ } else {
rcode = RCODE_COMPLETE;
+ }
fw_send_response(card, r, rcode);
}
diff --git a/drivers/firmware/sysfb.c b/drivers/firmware/sysfb.c
index 3c197db42c9d..82fcfd29bc4d 100644
--- a/drivers/firmware/sysfb.c
+++ b/drivers/firmware/sysfb.c
@@ -128,4 +128,4 @@ unlock_mutex:
}
/* must execute after PCI subsystem for EFI quirks */
-device_initcall(sysfb_init);
+subsys_initcall_sync(sysfb_init);
diff --git a/drivers/firmware/sysfb_simplefb.c b/drivers/firmware/sysfb_simplefb.c
index 82c64cb9f531..74363ed7501f 100644
--- a/drivers/firmware/sysfb_simplefb.c
+++ b/drivers/firmware/sysfb_simplefb.c
@@ -51,7 +51,8 @@ __init bool sysfb_parse_mode(const struct screen_info *si,
*
* It's not easily possible to fix this in struct screen_info,
* as this could break UAPI. The best solution is to compute
- * bits_per_pixel here and ignore lfb_depth. In the loop below,
+ * bits_per_pixel from the color bits, reserved bits and
+ * reported lfb_depth, whichever is highest. In the loop below,
* ignore simplefb formats with alpha bits, as EFI and VESA
* don't specify alpha channels.
*/
@@ -60,6 +61,7 @@ __init bool sysfb_parse_mode(const struct screen_info *si,
si->green_size + si->green_pos,
si->blue_size + si->blue_pos),
si->rsvd_size + si->rsvd_pos);
+ bits_per_pixel = max_t(u32, bits_per_pixel, si->lfb_depth);
} else {
bits_per_pixel = si->lfb_depth;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 981a9cfb63b5..5c7d40873ee2 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -3757,6 +3757,12 @@ int amdgpu_device_init(struct amdgpu_device *adev,
adev->have_atomics_support = ((struct amd_sriov_msg_pf2vf_info *)
adev->virt.fw_reserve.p_pf2vf)->pcie_atomic_ops_support_flags ==
(PCI_EXP_DEVCAP2_ATOMIC_COMP32 | PCI_EXP_DEVCAP2_ATOMIC_COMP64);
+ /* APUs w/ gfx9 onwards doesn't reply on PCIe atomics, rather it is a
+ * internal path natively support atomics, set have_atomics_support to true.
+ */
+ else if ((adev->flags & AMD_IS_APU) &&
+ (adev->ip_versions[GC_HWIP][0] > IP_VERSION(9, 0, 0)))
+ adev->have_atomics_support = true;
else
adev->have_atomics_support =
!pci_enable_atomic_ops_to_root(adev->pdev,
@@ -4506,7 +4512,11 @@ static int amdgpu_device_recover_vram(struct amdgpu_device *adev)
dev_info(adev->dev, "recover vram bo from shadow start\n");
mutex_lock(&adev->shadow_list_lock);
list_for_each_entry(vmbo, &adev->shadow_list, shadow_list) {
- shadow = &vmbo->bo;
+ /* If vm is compute context or adev is APU, shadow will be NULL */
+ if (!vmbo->shadow)
+ continue;
+ shadow = vmbo->shadow;
+
/* No need to recover an evicted BO */
if (shadow->tbo.resource->mem_type != TTM_PL_TT ||
shadow->tbo.resource->start == AMDGPU_BO_INVALID_OFFSET ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
index 9d3a0542c996..f3f541ba0aca 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
@@ -687,9 +687,11 @@ int amdgpu_gfx_ras_late_init(struct amdgpu_device *adev, struct ras_common_if *r
if (r)
return r;
- r = amdgpu_irq_get(adev, &adev->gfx.cp_ecc_error_irq, 0);
- if (r)
- goto late_fini;
+ if (adev->gfx.cp_ecc_error_irq.funcs) {
+ r = amdgpu_irq_get(adev, &adev->gfx.cp_ecc_error_irq, 0);
+ if (r)
+ goto late_fini;
+ }
} else {
amdgpu_ras_feature_enable_on_boot(adev, ras_block, 0);
}
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
index a9da0486467a..f5c376276984 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
@@ -1315,13 +1315,6 @@ static int gfx_v11_0_sw_init(void *handle)
if (r)
return r;
- /* ECC error */
- r = amdgpu_irq_add_id(adev, SOC21_IH_CLIENTID_GRBM_CP,
- GFX_11_0_0__SRCID__CP_ECC_ERROR,
- &adev->gfx.cp_ecc_error_irq);
- if (r)
- return r;
-
/* FED error */
r = amdgpu_irq_add_id(adev, SOC21_IH_CLIENTID_GFX,
GFX_11_0_0__SRCID__RLC_GC_FED_INTERRUPT,
@@ -4444,7 +4437,6 @@ static int gfx_v11_0_hw_fini(void *handle)
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
int r;
- amdgpu_irq_put(adev, &adev->gfx.cp_ecc_error_irq, 0);
amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
@@ -5897,36 +5889,6 @@ static void gfx_v11_0_set_compute_eop_interrupt_state(struct amdgpu_device *adev
}
}
-#define CP_ME1_PIPE_INST_ADDR_INTERVAL 0x1
-#define SET_ECC_ME_PIPE_STATE(reg_addr, state) \
- do { \
- uint32_t tmp = RREG32_SOC15_IP(GC, reg_addr); \
- tmp = REG_SET_FIELD(tmp, CP_ME1_PIPE0_INT_CNTL, CP_ECC_ERROR_INT_ENABLE, state); \
- WREG32_SOC15_IP(GC, reg_addr, tmp); \
- } while (0)
-
-static int gfx_v11_0_set_cp_ecc_error_state(struct amdgpu_device *adev,
- struct amdgpu_irq_src *source,
- unsigned type,
- enum amdgpu_interrupt_state state)
-{
- uint32_t ecc_irq_state = 0;
- uint32_t pipe0_int_cntl_addr = 0;
- int i = 0;
-
- ecc_irq_state = (state == AMDGPU_IRQ_STATE_ENABLE) ? 1 : 0;
-
- pipe0_int_cntl_addr = SOC15_REG_OFFSET(GC, 0, regCP_ME1_PIPE0_INT_CNTL);
-
- WREG32_FIELD15_PREREG(GC, 0, CP_INT_CNTL_RING0, CP_ECC_ERROR_INT_ENABLE, ecc_irq_state);
-
- for (i = 0; i < adev->gfx.mec.num_pipe_per_mec; i++)
- SET_ECC_ME_PIPE_STATE(pipe0_int_cntl_addr + i * CP_ME1_PIPE_INST_ADDR_INTERVAL,
- ecc_irq_state);
-
- return 0;
-}
-
static int gfx_v11_0_set_eop_interrupt_state(struct amdgpu_device *adev,
struct amdgpu_irq_src *src,
unsigned type,
@@ -6341,11 +6303,6 @@ static const struct amdgpu_irq_src_funcs gfx_v11_0_priv_inst_irq_funcs = {
.process = gfx_v11_0_priv_inst_irq,
};
-static const struct amdgpu_irq_src_funcs gfx_v11_0_cp_ecc_error_irq_funcs = {
- .set = gfx_v11_0_set_cp_ecc_error_state,
- .process = amdgpu_gfx_cp_ecc_error_irq,
-};
-
static const struct amdgpu_irq_src_funcs gfx_v11_0_rlc_gc_fed_irq_funcs = {
.process = gfx_v11_0_rlc_gc_fed_irq,
};
@@ -6361,9 +6318,6 @@ static void gfx_v11_0_set_irq_funcs(struct amdgpu_device *adev)
adev->gfx.priv_inst_irq.num_types = 1;
adev->gfx.priv_inst_irq.funcs = &gfx_v11_0_priv_inst_irq_funcs;
- adev->gfx.cp_ecc_error_irq.num_types = 1; /* CP ECC error */
- adev->gfx.cp_ecc_error_irq.funcs = &gfx_v11_0_cp_ecc_error_irq_funcs;
-
adev->gfx.rlc_gc_fed_irq.num_types = 1; /* 0x80 FED error */
adev->gfx.rlc_gc_fed_irq.funcs = &gfx_v11_0_rlc_gc_fed_irq_funcs;
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
index adbcd8127c82..f46d4b18a3fa 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
@@ -3764,7 +3764,8 @@ static int gfx_v9_0_hw_fini(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
- amdgpu_irq_put(adev, &adev->gfx.cp_ecc_error_irq, 0);
+ if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__GFX))
+ amdgpu_irq_put(adev, &adev->gfx.cp_ecc_error_irq, 0);
amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c
index c55e09432e26..1c2292cc5f2c 100644
--- a/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c
@@ -54,6 +54,7 @@ static int jpeg_v3_0_early_init(void *handle)
switch (adev->ip_versions[UVD_HWIP][0]) {
case IP_VERSION(3, 1, 1):
+ case IP_VERSION(3, 1, 2):
break;
default:
harvest = RREG32_SOC15(JPEG, 0, mmCC_UVD_HARVESTING);
diff --git a/drivers/gpu/drm/amd/amdgpu/nv.c b/drivers/gpu/drm/amd/amdgpu/nv.c
index 98c826f1f89b..0fb6013441f0 100644
--- a/drivers/gpu/drm/amd/amdgpu/nv.c
+++ b/drivers/gpu/drm/amd/amdgpu/nv.c
@@ -98,6 +98,16 @@ static const struct amdgpu_video_codecs nv_video_codecs_decode =
};
/* Sienna Cichlid */
+static const struct amdgpu_video_codec_info sc_video_codecs_encode_array[] = {
+ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 2160, 0)},
+ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 7680, 4352, 0)},
+};
+
+static const struct amdgpu_video_codecs sc_video_codecs_encode = {
+ .codec_count = ARRAY_SIZE(sc_video_codecs_encode_array),
+ .codec_array = sc_video_codecs_encode_array,
+};
+
static const struct amdgpu_video_codec_info sc_video_codecs_decode_array_vcn0[] =
{
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)},
@@ -136,8 +146,8 @@ static const struct amdgpu_video_codecs sc_video_codecs_decode_vcn1 =
/* SRIOV Sienna Cichlid, not const since data is controlled by host */
static struct amdgpu_video_codec_info sriov_sc_video_codecs_encode_array[] =
{
- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 2304, 0)},
- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 2304, 0)},
+ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 2160, 0)},
+ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 7680, 4352, 0)},
};
static struct amdgpu_video_codec_info sriov_sc_video_codecs_decode_array_vcn0[] =
@@ -237,12 +247,12 @@ static int nv_query_video_codecs(struct amdgpu_device *adev, bool encode,
} else {
if (adev->vcn.harvest_config & AMDGPU_VCN_HARVEST_VCN0) {
if (encode)
- *codecs = &nv_video_codecs_encode;
+ *codecs = &sc_video_codecs_encode;
else
*codecs = &sc_video_codecs_decode_vcn1;
} else {
if (encode)
- *codecs = &nv_video_codecs_encode;
+ *codecs = &sc_video_codecs_encode;
else
*codecs = &sc_video_codecs_decode_vcn0;
}
@@ -251,14 +261,14 @@ static int nv_query_video_codecs(struct amdgpu_device *adev, bool encode,
case IP_VERSION(3, 0, 16):
case IP_VERSION(3, 0, 2):
if (encode)
- *codecs = &nv_video_codecs_encode;
+ *codecs = &sc_video_codecs_encode;
else
*codecs = &sc_video_codecs_decode_vcn0;
return 0;
case IP_VERSION(3, 1, 1):
case IP_VERSION(3, 1, 2):
if (encode)
- *codecs = &nv_video_codecs_encode;
+ *codecs = &sc_video_codecs_encode;
else
*codecs = &yc_video_codecs_decode;
return 0;
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
index b3cc04dd8653..9295ac7edd56 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
@@ -1917,9 +1917,11 @@ static int sdma_v4_0_hw_fini(void *handle)
return 0;
}
- for (i = 0; i < adev->sdma.num_instances; i++) {
- amdgpu_irq_put(adev, &adev->sdma.ecc_irq,
- AMDGPU_SDMA_IRQ_INSTANCE0 + i);
+ if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__SDMA)) {
+ for (i = 0; i < adev->sdma.num_instances; i++) {
+ amdgpu_irq_put(adev, &adev->sdma.ecc_irq,
+ AMDGPU_SDMA_IRQ_INSTANCE0 + i);
+ }
}
sdma_v4_0_ctx_switch_enable(adev, false);
diff --git a/drivers/gpu/drm/amd/amdgpu/soc21.c b/drivers/gpu/drm/amd/amdgpu/soc21.c
index 744be2a05623..d77162536514 100644
--- a/drivers/gpu/drm/amd/amdgpu/soc21.c
+++ b/drivers/gpu/drm/amd/amdgpu/soc21.c
@@ -711,7 +711,7 @@ static int soc21_common_early_init(void *handle)
AMD_PG_SUPPORT_VCN_DPG |
AMD_PG_SUPPORT_GFX_PG |
AMD_PG_SUPPORT_JPEG;
- adev->external_rev_id = adev->rev_id + 0x1;
+ adev->external_rev_id = adev->rev_id + 0x80;
break;
default:
diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.c
index 40c488b26901..cc3fe9cac5b5 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.c
@@ -423,3 +423,68 @@ void dcn314_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool
PERF_TRACE();
}
+static void apply_symclk_on_tx_off_wa(struct dc_link *link)
+{
+ /* There are use cases where SYMCLK is referenced by OTG. For instance
+ * for TMDS signal, OTG relies SYMCLK even if TX video output is off.
+ * However current link interface will power off PHY when disabling link
+ * output. This will turn off SYMCLK generated by PHY. The workaround is
+ * to identify such case where SYMCLK is still in use by OTG when we
+ * power off PHY. When this is detected, we will temporarily power PHY
+ * back on and move PHY's SYMCLK state to SYMCLK_ON_TX_OFF by calling
+ * program_pix_clk interface. When OTG is disabled, we will then power
+ * off PHY by calling disable link output again.
+ *
+ * In future dcn generations, we plan to rework transmitter control
+ * interface so that we could have an option to set SYMCLK ON TX OFF
+ * state in one step without this workaround
+ */
+
+ struct dc *dc = link->ctx->dc;
+ struct pipe_ctx *pipe_ctx = NULL;
+ uint8_t i;
+
+ if (link->phy_state.symclk_ref_cnts.otg > 0) {
+ for (i = 0; i < MAX_PIPES; i++) {
+ pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
+ if (pipe_ctx->stream && pipe_ctx->stream->link == link && pipe_ctx->top_pipe == NULL) {
+ pipe_ctx->clock_source->funcs->program_pix_clk(
+ pipe_ctx->clock_source,
+ &pipe_ctx->stream_res.pix_clk_params,
+ dc->link_srv->dp_get_encoding_format(
+ &pipe_ctx->link_config.dp_link_settings),
+ &pipe_ctx->pll_settings);
+ link->phy_state.symclk_state = SYMCLK_ON_TX_OFF;
+ break;
+ }
+ }
+ }
+}
+
+void dcn314_disable_link_output(struct dc_link *link,
+ const struct link_resource *link_res,
+ enum signal_type signal)
+{
+ struct dc *dc = link->ctx->dc;
+ const struct link_hwss *link_hwss = get_link_hwss(link, link_res);
+ struct dmcu *dmcu = dc->res_pool->dmcu;
+
+ if (signal == SIGNAL_TYPE_EDP &&
+ link->dc->hwss.edp_backlight_control)
+ link->dc->hwss.edp_backlight_control(link, false);
+ else if (dmcu != NULL && dmcu->funcs->lock_phy)
+ dmcu->funcs->lock_phy(dmcu);
+
+ link_hwss->disable_link_output(link, link_res, signal);
+ link->phy_state.symclk_state = SYMCLK_OFF_TX_OFF;
+ /*
+ * Add the logic to extract BOTH power up and power down sequences
+ * from enable/disable link output and only call edp panel control
+ * in enable_link_dp and disable_link_dp once.
+ */
+ if (dmcu != NULL && dmcu->funcs->lock_phy)
+ dmcu->funcs->unlock_phy(dmcu);
+ dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY);
+
+ apply_symclk_on_tx_off_wa(link);
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.h b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.h
index c786d5e6a428..6d0b62503caa 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.h
@@ -45,4 +45,6 @@ void dcn314_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool
void dcn314_dpp_root_clock_control(struct dce_hwseq *hws, unsigned int dpp_inst, bool clock_on);
+void dcn314_disable_link_output(struct dc_link *link, const struct link_resource *link_res, enum signal_type signal);
+
#endif /* __DC_HWSS_DCN314_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_init.c b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_init.c
index 5267e901a35c..a588f46b166f 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_init.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_init.c
@@ -105,7 +105,7 @@ static const struct hw_sequencer_funcs dcn314_funcs = {
.enable_lvds_link_output = dce110_enable_lvds_link_output,
.enable_tmds_link_output = dce110_enable_tmds_link_output,
.enable_dp_link_output = dce110_enable_dp_link_output,
- .disable_link_output = dce110_disable_link_output,
+ .disable_link_output = dcn314_disable_link_output,
.z10_restore = dcn31_z10_restore,
.z10_save_init = dcn31_z10_save_init,
.set_disp_pattern_generator = dcn30_set_disp_pattern_generator,
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c
index 13c7e7394b1c..d75248b6cae9 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c
@@ -810,7 +810,8 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman
v->SwathHeightY[k],
v->SwathHeightC[k],
TWait,
- v->DRAMSpeedPerState[mode_lib->vba.VoltageLevel] <= MEM_STROBE_FREQ_MHZ ?
+ (v->DRAMSpeedPerState[mode_lib->vba.VoltageLevel] <= MEM_STROBE_FREQ_MHZ ||
+ v->DCFCLKPerState[mode_lib->vba.VoltageLevel] <= MIN_DCFCLK_FREQ_MHZ) ?
mode_lib->vba.ip.min_prefetch_in_strobe_us : 0,
/* Output */
&v->DSTXAfterScaler[k],
@@ -3310,7 +3311,7 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
v->swath_width_chroma_ub_this_state[k],
v->SwathHeightYThisState[k],
v->SwathHeightCThisState[k], v->TWait,
- v->DRAMSpeedPerState[i] <= MEM_STROBE_FREQ_MHZ ?
+ (v->DRAMSpeedPerState[i] <= MEM_STROBE_FREQ_MHZ || v->DCFCLKState[i][j] <= MIN_DCFCLK_FREQ_MHZ) ?
mode_lib->vba.ip.min_prefetch_in_strobe_us : 0,
/* Output */
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.h b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.h
index 500b3dd6052d..d98e36a9a09c 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.h
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.h
@@ -53,6 +53,7 @@
#define BPP_BLENDED_PIPE 0xffffffff
#define MEM_STROBE_FREQ_MHZ 1600
+#define MIN_DCFCLK_FREQ_MHZ 200
#define MEM_STROBE_MAX_DELIVERY_TIME_US 60.0
struct display_mode_lib;
diff --git a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c
index 300e156b924f..078aaaa53162 100644
--- a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c
+++ b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c
@@ -36,6 +36,8 @@
#define amdgpu_dpm_enable_bapm(adev, e) \
((adev)->powerplay.pp_funcs->enable_bapm((adev)->powerplay.pp_handle, (e)))
+#define amdgpu_dpm_is_legacy_dpm(adev) ((adev)->powerplay.pp_handle == (adev))
+
int amdgpu_dpm_get_sclk(struct amdgpu_device *adev, bool low)
{
const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
@@ -1460,15 +1462,24 @@ int amdgpu_dpm_get_smu_prv_buf_details(struct amdgpu_device *adev,
int amdgpu_dpm_is_overdrive_supported(struct amdgpu_device *adev)
{
- struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle;
- struct smu_context *smu = adev->powerplay.pp_handle;
+ if (is_support_sw_smu(adev)) {
+ struct smu_context *smu = adev->powerplay.pp_handle;
- if ((is_support_sw_smu(adev) && smu->od_enabled) ||
- (is_support_sw_smu(adev) && smu->is_apu) ||
- (!is_support_sw_smu(adev) && hwmgr->od_enabled))
- return true;
+ return (smu->od_enabled || smu->is_apu);
+ } else {
+ struct pp_hwmgr *hwmgr;
- return false;
+ /*
+ * dpm on some legacy asics don't carry od_enabled member
+ * as its pp_handle is casted directly from adev.
+ */
+ if (amdgpu_dpm_is_legacy_dpm(adev))
+ return false;
+
+ hwmgr = (struct pp_hwmgr *)adev->powerplay.pp_handle;
+
+ return hwmgr->od_enabled;
+ }
}
int amdgpu_dpm_set_pp_table(struct amdgpu_device *adev,
diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c
index 9020bf820bc8..12f5a2c7f03d 100644
--- a/drivers/gpu/drm/arm/hdlcd_drv.c
+++ b/drivers/gpu/drm/arm/hdlcd_drv.c
@@ -285,7 +285,7 @@ static int hdlcd_drm_bind(struct device *dev)
*/
if (hdlcd_read(hdlcd, HDLCD_REG_COMMAND)) {
hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 0);
- drm_aperture_remove_framebuffers(false, &hdlcd_driver);
+ drm_aperture_remove_framebuffers(&hdlcd_driver);
}
drm_mode_config_reset(drm);
diff --git a/drivers/gpu/drm/armada/Makefile b/drivers/gpu/drm/armada/Makefile
index 9bc3c3213724..dc75a7db9ed3 100644
--- a/drivers/gpu/drm/armada/Makefile
+++ b/drivers/gpu/drm/armada/Makefile
@@ -1,7 +1,8 @@
# SPDX-License-Identifier: GPL-2.0
-armada-y := armada_crtc.o armada_drv.o armada_fb.o armada_fbdev.o \
+armada-y := armada_crtc.o armada_drv.o armada_fb.o \
armada_gem.o armada_overlay.o armada_plane.o armada_trace.o
armada-y += armada_510.o
armada-$(CONFIG_DEBUG_FS) += armada_debugfs.o
+armada-$(CONFIG_DRM_FBDEV_EMULATION) += armada_fbdev.o
obj-$(CONFIG_DRM_ARMADA) := armada.o
diff --git a/drivers/gpu/drm/armada/armada_drm.h b/drivers/gpu/drm/armada/armada_drm.h
index 6a5a87932576..c303e8c7ff6c 100644
--- a/drivers/gpu/drm/armada/armada_drm.h
+++ b/drivers/gpu/drm/armada/armada_drm.h
@@ -16,7 +16,6 @@ struct armada_crtc;
struct armada_gem_object;
struct clk;
struct drm_display_mode;
-struct drm_fb_helper;
static inline void
armada_updatel(uint32_t val, uint32_t mask, void __iomem *ptr)
@@ -55,7 +54,6 @@ extern const struct armada_variant armada510_ops;
struct armada_private {
struct drm_device drm;
- struct drm_fb_helper *fbdev;
struct armada_crtc *dcrtc[2];
struct drm_mm linear; /* protected by linear_lock */
struct mutex linear_lock;
@@ -75,8 +73,12 @@ struct armada_private {
#define drm_to_armada_dev(dev) container_of(dev, struct armada_private, drm)
-int armada_fbdev_init(struct drm_device *);
-void armada_fbdev_fini(struct drm_device *);
+#if defined(CONFIG_DRM_FBDEV_EMULATION)
+void armada_fbdev_setup(struct drm_device *dev);
+#else
+static inline void armada_fbdev_setup(struct drm_device *dev)
+{ }
+#endif
int armada_overlay_plane_create(struct drm_device *, unsigned long);
diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c
index 142668cd6d7c..e120144d4b47 100644
--- a/drivers/gpu/drm/armada/armada_drv.c
+++ b/drivers/gpu/drm/armada/armada_drv.c
@@ -6,6 +6,7 @@
#include <linux/clk.h>
#include <linux/component.h>
#include <linux/module.h>
+#include <linux/of.h>
#include <linux/of_graph.h>
#include <linux/platform_device.h>
@@ -16,7 +17,6 @@
#include <drm/drm_managed.h>
#include <drm/drm_prime.h>
#include <drm/drm_probe_helper.h>
-#include <drm/drm_fb_helper.h>
#include <drm/drm_of.h>
#include <drm/drm_vblank.h>
@@ -37,7 +37,6 @@ static const struct drm_ioctl_desc armada_ioctls[] = {
DEFINE_DRM_GEM_FOPS(armada_drm_fops);
static const struct drm_driver armada_drm_driver = {
- .lastclose = drm_fb_helper_lastclose,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
.gem_prime_import = armada_gem_prime_import,
@@ -55,7 +54,6 @@ static const struct drm_driver armada_drm_driver = {
static const struct drm_mode_config_funcs armada_drm_mode_config_funcs = {
.fb_create = armada_fb_create,
- .output_poll_changed = drm_fb_helper_output_poll_changed,
.atomic_check = drm_atomic_helper_check,
.atomic_commit = drm_atomic_helper_commit,
};
@@ -95,7 +93,7 @@ static int armada_drm_bind(struct device *dev)
}
/* Remove early framebuffers */
- ret = drm_aperture_remove_framebuffers(false, &armada_drm_driver);
+ ret = drm_aperture_remove_framebuffers(&armada_drm_driver);
if (ret) {
dev_err(dev, "[" DRM_NAME ":%s] can't kick out simple-fb: %d\n",
__func__, ret);
@@ -131,10 +129,6 @@ static int armada_drm_bind(struct device *dev)
drm_mode_config_reset(&priv->drm);
- ret = armada_fbdev_init(&priv->drm);
- if (ret)
- goto err_comp;
-
drm_kms_helper_poll_init(&priv->drm);
ret = drm_dev_register(&priv->drm, 0);
@@ -145,11 +139,12 @@ static int armada_drm_bind(struct device *dev)
armada_drm_debugfs_init(priv->drm.primary);
#endif
+ armada_fbdev_setup(&priv->drm);
+
return 0;
err_poll:
drm_kms_helper_poll_fini(&priv->drm);
- armada_fbdev_fini(&priv->drm);
err_comp:
component_unbind_all(dev, &priv->drm);
err_kms:
@@ -164,7 +159,6 @@ static void armada_drm_unbind(struct device *dev)
struct armada_private *priv = drm_to_armada_dev(drm);
drm_kms_helper_poll_fini(&priv->drm);
- armada_fbdev_fini(&priv->drm);
drm_dev_unregister(&priv->drm);
diff --git a/drivers/gpu/drm/armada/armada_fb.c b/drivers/gpu/drm/armada/armada_fb.c
index b87c71703c85..cf2e88218dc0 100644
--- a/drivers/gpu/drm/armada/armada_fb.c
+++ b/drivers/gpu/drm/armada/armada_fb.c
@@ -4,7 +4,6 @@
*/
#include <drm/drm_modeset_helper.h>
-#include <drm/drm_fb_helper.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_gem_framebuffer_helper.h>
diff --git a/drivers/gpu/drm/armada/armada_fbdev.c b/drivers/gpu/drm/armada/armada_fbdev.c
index 0e44f53e9fa4..0a5fd1aa86eb 100644
--- a/drivers/gpu/drm/armada/armada_fbdev.c
+++ b/drivers/gpu/drm/armada/armada_fbdev.c
@@ -8,6 +8,8 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_drv.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_fourcc.h>
@@ -16,6 +18,19 @@
#include "armada_fb.h"
#include "armada_gem.h"
+static void armada_fbdev_fb_destroy(struct fb_info *info)
+{
+ struct drm_fb_helper *fbh = info->par;
+
+ drm_fb_helper_fini(fbh);
+
+ fbh->fb->funcs->destroy(fbh->fb);
+
+ drm_client_release(&fbh->client);
+ drm_fb_helper_unprepare(fbh);
+ kfree(fbh);
+}
+
static const struct fb_ops armada_fb_ops = {
.owner = THIS_MODULE,
DRM_FB_HELPER_DEFAULT_OPS,
@@ -24,6 +39,7 @@ static const struct fb_ops armada_fb_ops = {
.fb_fillrect = drm_fb_helper_cfb_fillrect,
.fb_copyarea = drm_fb_helper_cfb_copyarea,
.fb_imageblit = drm_fb_helper_cfb_imageblit,
+ .fb_destroy = armada_fbdev_fb_destroy,
};
static int armada_fbdev_create(struct drm_fb_helper *fbh,
@@ -117,56 +133,95 @@ static const struct drm_fb_helper_funcs armada_fb_helper_funcs = {
.fb_probe = armada_fb_probe,
};
-int armada_fbdev_init(struct drm_device *dev)
+/*
+ * Fbdev client and struct drm_client_funcs
+ */
+
+static void armada_fbdev_client_unregister(struct drm_client_dev *client)
{
- struct armada_private *priv = drm_to_armada_dev(dev);
- struct drm_fb_helper *fbh;
- int ret;
+ struct drm_fb_helper *fbh = drm_fb_helper_from_client(client);
- fbh = devm_kzalloc(dev->dev, sizeof(*fbh), GFP_KERNEL);
- if (!fbh)
- return -ENOMEM;
+ if (fbh->info) {
+ drm_fb_helper_unregister_info(fbh);
+ } else {
+ drm_client_release(&fbh->client);
+ drm_fb_helper_unprepare(fbh);
+ kfree(fbh);
+ }
+}
- priv->fbdev = fbh;
+static int armada_fbdev_client_restore(struct drm_client_dev *client)
+{
+ drm_fb_helper_lastclose(client->dev);
- drm_fb_helper_prepare(dev, fbh, 32, &armada_fb_helper_funcs);
+ return 0;
+}
+
+static int armada_fbdev_client_hotplug(struct drm_client_dev *client)
+{
+ struct drm_fb_helper *fbh = drm_fb_helper_from_client(client);
+ struct drm_device *dev = client->dev;
+ int ret;
+
+ if (dev->fb_helper)
+ return drm_fb_helper_hotplug_event(dev->fb_helper);
ret = drm_fb_helper_init(dev, fbh);
- if (ret) {
- DRM_ERROR("failed to initialize drm fb helper\n");
- goto err_fb_helper;
- }
+ if (ret)
+ goto err_drm_err;
+
+ if (!drm_drv_uses_atomic_modeset(dev))
+ drm_helper_disable_unused_functions(dev);
ret = drm_fb_helper_initial_config(fbh);
- if (ret) {
- DRM_ERROR("failed to set initial config\n");
- goto err_fb_setup;
- }
+ if (ret)
+ goto err_drm_fb_helper_fini;
return 0;
- err_fb_setup:
+
+err_drm_fb_helper_fini:
drm_fb_helper_fini(fbh);
- err_fb_helper:
- drm_fb_helper_unprepare(fbh);
- priv->fbdev = NULL;
+err_drm_err:
+ drm_err(dev, "armada: Failed to setup fbdev emulation (ret=%d)\n", ret);
return ret;
}
-void armada_fbdev_fini(struct drm_device *dev)
+static const struct drm_client_funcs armada_fbdev_client_funcs = {
+ .owner = THIS_MODULE,
+ .unregister = armada_fbdev_client_unregister,
+ .restore = armada_fbdev_client_restore,
+ .hotplug = armada_fbdev_client_hotplug,
+};
+
+void armada_fbdev_setup(struct drm_device *dev)
{
- struct armada_private *priv = drm_to_armada_dev(dev);
- struct drm_fb_helper *fbh = priv->fbdev;
+ struct drm_fb_helper *fbh;
+ int ret;
- if (fbh) {
- drm_fb_helper_unregister_info(fbh);
+ drm_WARN(dev, !dev->registered, "Device has not been registered.\n");
+ drm_WARN(dev, dev->fb_helper, "fb_helper is already set!\n");
+
+ fbh = kzalloc(sizeof(*fbh), GFP_KERNEL);
+ if (!fbh)
+ return;
+ drm_fb_helper_prepare(dev, fbh, 32, &armada_fb_helper_funcs);
- drm_fb_helper_fini(fbh);
+ ret = drm_client_init(dev, &fbh->client, "fbdev", &armada_fbdev_client_funcs);
+ if (ret) {
+ drm_err(dev, "Failed to register client: %d\n", ret);
+ goto err_drm_client_init;
+ }
- if (fbh->fb)
- fbh->fb->funcs->destroy(fbh->fb);
+ ret = armada_fbdev_client_hotplug(&fbh->client);
+ if (ret)
+ drm_dbg_kms(dev, "client hotplug ret=%d\n", ret);
- drm_fb_helper_unprepare(fbh);
+ drm_client_register(&fbh->client);
- priv->fbdev = NULL;
- }
+ return;
+
+err_drm_client_init:
+ drm_fb_helper_unprepare(fbh);
+ kfree(fbh);
+ return;
}
diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c
index 794ffd4a29c5..f32ce29edba7 100644
--- a/drivers/gpu/drm/ast/ast_main.c
+++ b/drivers/gpu/drm/ast/ast_main.c
@@ -425,11 +425,12 @@ struct ast_device *ast_device_create(const struct drm_driver *drv,
return ERR_PTR(-EIO);
/*
- * If we don't have IO space at all, use MMIO now and
- * assume the chip has MMIO enabled by default (rev 0x20
- * and higher).
+ * After AST2500, MMIO is enabled by default, and it should be adopted
+ * to be compatible with Arm.
*/
- if (!(pci_resource_flags(pdev, 2) & IORESOURCE_IO)) {
+ if (pdev->revision >= 0x40) {
+ ast->ioregs = ast->regs + AST_IO_MM_OFFSET;
+ } else if (!(pci_resource_flags(pdev, 2) & IORESOURCE_IO)) {
drm_info(dev, "platform has no IO space, trying MMIO\n");
ast->ioregs = ast->regs + AST_IO_MM_OFFSET;
}
diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c
index 6846199a2ee1..c86531f7b072 100644
--- a/drivers/gpu/drm/bridge/analogix/anx7625.c
+++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
@@ -17,7 +17,6 @@
#include <linux/types.h>
#include <linux/workqueue.h>
-#include <linux/of_gpio.h>
#include <linux/of_graph.h>
#include <linux/of_platform.h>
@@ -1687,6 +1686,14 @@ static int anx7625_parse_dt(struct device *dev,
if (of_property_read_bool(np, "analogix,audio-enable"))
pdata->audio_en = 1;
+ return 0;
+}
+
+static int anx7625_parse_dt_panel(struct device *dev,
+ struct anx7625_platform_data *pdata)
+{
+ struct device_node *np = dev->of_node;
+
pdata->panel_bridge = devm_drm_of_get_bridge(dev, np, 1, 0);
if (IS_ERR(pdata->panel_bridge)) {
if (PTR_ERR(pdata->panel_bridge) == -ENODEV) {
@@ -2032,7 +2039,7 @@ static int anx7625_register_audio(struct device *dev, struct anx7625_data *ctx)
return 0;
}
-static int anx7625_attach_dsi(struct anx7625_data *ctx)
+static int anx7625_setup_dsi_device(struct anx7625_data *ctx)
{
struct mipi_dsi_device *dsi;
struct device *dev = &ctx->client->dev;
@@ -2042,9 +2049,6 @@ static int anx7625_attach_dsi(struct anx7625_data *ctx)
.channel = 0,
.node = NULL,
};
- int ret;
-
- DRM_DEV_DEBUG_DRIVER(dev, "attach dsi\n");
host = of_find_mipi_dsi_host_by_node(ctx->pdata.mipi_host_node);
if (!host) {
@@ -2065,14 +2069,24 @@ static int anx7625_attach_dsi(struct anx7625_data *ctx)
MIPI_DSI_MODE_VIDEO_HSE |
MIPI_DSI_HS_PKT_END_ALIGNED;
- ret = devm_mipi_dsi_attach(dev, dsi);
+ ctx->dsi = dsi;
+
+ return 0;
+}
+
+static int anx7625_attach_dsi(struct anx7625_data *ctx)
+{
+ struct device *dev = &ctx->client->dev;
+ int ret;
+
+ DRM_DEV_DEBUG_DRIVER(dev, "attach dsi\n");
+
+ ret = devm_mipi_dsi_attach(dev, ctx->dsi);
if (ret) {
DRM_DEV_ERROR(dev, "fail to attach dsi to host.\n");
return ret;
}
- ctx->dsi = dsi;
-
DRM_DEV_DEBUG_DRIVER(dev, "attach dsi succeeded.\n");
return 0;
@@ -2560,6 +2574,40 @@ static void anx7625_runtime_disable(void *data)
pm_runtime_disable(data);
}
+static int anx7625_link_bridge(struct drm_dp_aux *aux)
+{
+ struct anx7625_data *platform = container_of(aux, struct anx7625_data, aux);
+ struct device *dev = aux->dev;
+ int ret;
+
+ ret = anx7625_parse_dt_panel(dev, &platform->pdata);
+ if (ret) {
+ DRM_DEV_ERROR(dev, "fail to parse DT for panel : %d\n", ret);
+ return ret;
+ }
+
+ platform->bridge.funcs = &anx7625_bridge_funcs;
+ platform->bridge.of_node = dev->of_node;
+ if (!anx7625_of_panel_on_aux_bus(dev))
+ platform->bridge.ops |= DRM_BRIDGE_OP_EDID;
+ if (!platform->pdata.panel_bridge)
+ platform->bridge.ops |= DRM_BRIDGE_OP_HPD |
+ DRM_BRIDGE_OP_DETECT;
+ platform->bridge.type = platform->pdata.panel_bridge ?
+ DRM_MODE_CONNECTOR_eDP :
+ DRM_MODE_CONNECTOR_DisplayPort;
+
+ drm_bridge_add(&platform->bridge);
+
+ if (!platform->pdata.is_dpi) {
+ ret = anx7625_attach_dsi(platform);
+ if (ret)
+ drm_bridge_remove(&platform->bridge);
+ }
+
+ return ret;
+}
+
static int anx7625_i2c_probe(struct i2c_client *client)
{
struct anx7625_data *platform;
@@ -2634,6 +2682,24 @@ static int anx7625_i2c_probe(struct i2c_client *client)
platform->aux.wait_hpd_asserted = anx7625_wait_hpd_asserted;
drm_dp_aux_init(&platform->aux);
+ ret = anx7625_parse_dt(dev, pdata);
+ if (ret) {
+ if (ret != -EPROBE_DEFER)
+ DRM_DEV_ERROR(dev, "fail to parse DT : %d\n", ret);
+ goto free_wq;
+ }
+
+ if (!platform->pdata.is_dpi) {
+ ret = anx7625_setup_dsi_device(platform);
+ if (ret < 0)
+ goto free_wq;
+ }
+
+ /*
+ * Registering the i2c devices will retrigger deferred probe, so it
+ * needs to be done after calls that might return EPROBE_DEFER,
+ * otherwise we can get an infinite loop.
+ */
if (anx7625_register_i2c_dummy_clients(platform, client) != 0) {
ret = -ENOMEM;
DRM_DEV_ERROR(dev, "fail to reserve I2C bus.\n");
@@ -2648,13 +2714,21 @@ static int anx7625_i2c_probe(struct i2c_client *client)
if (ret)
goto free_wq;
- devm_of_dp_aux_populate_ep_devices(&platform->aux);
-
- ret = anx7625_parse_dt(dev, pdata);
+ /*
+ * Populating the aux bus will retrigger deferred probe, so it needs to
+ * be done after calls that might return EPROBE_DEFER, otherwise we can
+ * get an infinite loop.
+ */
+ ret = devm_of_dp_aux_populate_bus(&platform->aux, anx7625_link_bridge);
if (ret) {
- if (ret != -EPROBE_DEFER)
- DRM_DEV_ERROR(dev, "fail to parse DT : %d\n", ret);
- goto free_wq;
+ if (ret != -ENODEV) {
+ DRM_DEV_ERROR(dev, "failed to populate aux bus : %d\n", ret);
+ goto free_wq;
+ }
+
+ ret = anx7625_link_bridge(&platform->aux);
+ if (ret)
+ goto free_wq;
}
if (!platform->pdata.low_power_mode) {
@@ -2667,27 +2741,6 @@ static int anx7625_i2c_probe(struct i2c_client *client)
if (platform->pdata.intp_irq)
queue_work(platform->workqueue, &platform->work);
- platform->bridge.funcs = &anx7625_bridge_funcs;
- platform->bridge.of_node = client->dev.of_node;
- if (!anx7625_of_panel_on_aux_bus(&client->dev))
- platform->bridge.ops |= DRM_BRIDGE_OP_EDID;
- if (!platform->pdata.panel_bridge)
- platform->bridge.ops |= DRM_BRIDGE_OP_HPD |
- DRM_BRIDGE_OP_DETECT;
- platform->bridge.type = platform->pdata.panel_bridge ?
- DRM_MODE_CONNECTOR_eDP :
- DRM_MODE_CONNECTOR_DisplayPort;
-
- drm_bridge_add(&platform->bridge);
-
- if (!platform->pdata.is_dpi) {
- ret = anx7625_attach_dsi(platform);
- if (ret) {
- DRM_DEV_ERROR(dev, "Fail to attach to dsi : %d\n", ret);
- goto unregister_bridge;
- }
- }
-
if (platform->pdata.audio_en)
anx7625_register_audio(dev, platform);
@@ -2695,12 +2748,6 @@ static int anx7625_i2c_probe(struct i2c_client *client)
return 0;
-unregister_bridge:
- drm_bridge_remove(&platform->bridge);
-
- if (!platform->pdata.low_power_mode)
- pm_runtime_put_sync_suspend(&client->dev);
-
free_wq:
if (platform->workqueue)
destroy_workqueue(platform->workqueue);
diff --git a/drivers/gpu/drm/bridge/fsl-ldb.c b/drivers/gpu/drm/bridge/fsl-ldb.c
index 682623369498..b8e52156b07a 100644
--- a/drivers/gpu/drm/bridge/fsl-ldb.c
+++ b/drivers/gpu/drm/bridge/fsl-ldb.c
@@ -56,6 +56,7 @@
#define LVDS_CTRL_VBG_ADJ_MASK GENMASK(19, 17)
enum fsl_ldb_devtype {
+ IMX6SX_LDB,
IMX8MP_LDB,
IMX93_LDB,
};
@@ -64,9 +65,14 @@ struct fsl_ldb_devdata {
u32 ldb_ctrl;
u32 lvds_ctrl;
bool lvds_en_bit;
+ bool single_ctrl_reg;
};
static const struct fsl_ldb_devdata fsl_ldb_devdata[] = {
+ [IMX6SX_LDB] = {
+ .ldb_ctrl = 0x18,
+ .single_ctrl_reg = true,
+ },
[IMX8MP_LDB] = {
.ldb_ctrl = 0x5c,
.lvds_ctrl = 0x128,
@@ -201,6 +207,9 @@ static void fsl_ldb_atomic_enable(struct drm_bridge *bridge,
regmap_write(fsl_ldb->regmap, fsl_ldb->devdata->ldb_ctrl, reg);
+ if (fsl_ldb->devdata->single_ctrl_reg)
+ return;
+
/* Program LVDS_CTRL */
reg = LVDS_CTRL_CC_ADJ(2) | LVDS_CTRL_PRE_EMPH_EN |
LVDS_CTRL_PRE_EMPH_ADJ(3) | LVDS_CTRL_VBG_EN;
@@ -226,7 +235,8 @@ static void fsl_ldb_atomic_disable(struct drm_bridge *bridge,
regmap_write(fsl_ldb->regmap, fsl_ldb->devdata->lvds_ctrl,
LVDS_CTRL_LVDS_EN);
else
- regmap_write(fsl_ldb->regmap, fsl_ldb->devdata->lvds_ctrl, 0);
+ if (!fsl_ldb->devdata->single_ctrl_reg)
+ regmap_write(fsl_ldb->regmap, fsl_ldb->devdata->lvds_ctrl, 0);
regmap_write(fsl_ldb->regmap, fsl_ldb->devdata->ldb_ctrl, 0);
clk_disable_unprepare(fsl_ldb->clk);
@@ -372,6 +382,8 @@ static void fsl_ldb_remove(struct platform_device *pdev)
}
static const struct of_device_id fsl_ldb_match[] = {
+ { .compatible = "fsl,imx6sx-ldb",
+ .data = &fsl_ldb_devdata[IMX6SX_LDB], },
{ .compatible = "fsl,imx8mp-ldb",
.data = &fsl_ldb_devdata[IMX8MP_LDB], },
{ .compatible = "fsl,imx93-ldb",
diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c
index abaf6e23775e..45f579c365e7 100644
--- a/drivers/gpu/drm/bridge/ite-it6505.c
+++ b/drivers/gpu/drm/bridge/ite-it6505.c
@@ -3207,7 +3207,7 @@ static ssize_t receive_timing_debugfs_show(struct file *file, char __user *buf,
size_t len, loff_t *ppos)
{
struct it6505 *it6505 = file->private_data;
- struct drm_display_mode *vid = &it6505->video_info;
+ struct drm_display_mode *vid;
u8 read_buf[READ_BUFFER_SIZE];
u8 *str = read_buf, *end = read_buf + READ_BUFFER_SIZE;
ssize_t ret, count;
@@ -3216,6 +3216,7 @@ static ssize_t receive_timing_debugfs_show(struct file *file, char __user *buf,
return -ENODEV;
it6505_calc_video_info(it6505);
+ vid = &it6505->video_info;
str += scnprintf(str, end - str, "---video timing---\n");
str += scnprintf(str, end - str, "PCLK:%d.%03dMHz\n",
vid->clock / 1000, vid->clock % 1000);
diff --git a/drivers/gpu/drm/bridge/lontium-lt9211.c b/drivers/gpu/drm/bridge/lontium-lt9211.c
index 3e19fff6547a..00db68151238 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9211.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9211.c
@@ -709,7 +709,9 @@ static int lt9211_host_attach(struct lt9211 *ctx)
dsi->lanes = dsi_lanes;
dsi->format = MIPI_DSI_FMT_RGB888;
dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
- MIPI_DSI_MODE_VIDEO_HSE;
+ MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO_NO_HSA |
+ MIPI_DSI_MODE_VIDEO_NO_HFP | MIPI_DSI_MODE_VIDEO_NO_HBP |
+ MIPI_DSI_MODE_NO_EOT_PACKET;
ret = devm_mipi_dsi_attach(dev, dsi);
if (ret < 0) {
diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c b/drivers/gpu/drm/bridge/lontium-lt9611.c
index a25d21a7d5c1..151efe92711c 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
@@ -774,7 +774,9 @@ static struct mipi_dsi_device *lt9611_attach_dsi(struct lt9611 *lt9611,
dsi->lanes = 4;
dsi->format = MIPI_DSI_FMT_RGB888;
dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
- MIPI_DSI_MODE_VIDEO_HSE;
+ MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO_NO_HSA |
+ MIPI_DSI_MODE_VIDEO_NO_HFP | MIPI_DSI_MODE_VIDEO_NO_HBP |
+ MIPI_DSI_MODE_NO_EOT_PACKET;
ret = devm_mipi_dsi_attach(dev, dsi);
if (ret < 0) {
diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c b/drivers/gpu/drm/bridge/samsung-dsim.c
index e0a402a85787..0f3f6846beea 100644
--- a/drivers/gpu/drm/bridge/samsung-dsim.c
+++ b/drivers/gpu/drm/bridge/samsung-dsim.c
@@ -183,6 +183,8 @@
#define DSIM_AFC_CTL(x) (((x) & 0x7) << 5)
/* DSIM_PLLCTRL */
+#define DSIM_PLL_DPDNSWAP_CLK (1 << 25)
+#define DSIM_PLL_DPDNSWAP_DAT (1 << 24)
#define DSIM_FREQ_BAND(x) ((x) << 24)
#define DSIM_PLL_EN BIT(23)
#define DSIM_PLL_P(x, offset) ((x) << (offset))
@@ -622,6 +624,11 @@ static unsigned long samsung_dsim_set_pll(struct samsung_dsim *dsi,
reg |= DSIM_FREQ_BAND(band);
}
+ if (dsi->swap_dn_dp_clk)
+ reg |= DSIM_PLL_DPDNSWAP_CLK;
+ if (dsi->swap_dn_dp_data)
+ reg |= DSIM_PLL_DPDNSWAP_DAT;
+
samsung_dsim_write(dsi, DSIM_PLLCTRL_REG, reg);
timeout = 1000;
@@ -1696,7 +1703,9 @@ static int samsung_dsim_parse_dt(struct samsung_dsim *dsi)
{
struct device *dev = dsi->dev;
struct device_node *node = dev->of_node;
- int ret;
+ u32 lane_polarities[5] = { 0 };
+ struct device_node *endpoint;
+ int i, nr_lanes, ret;
ret = samsung_dsim_of_read_u32(node, "samsung,pll-clock-frequency",
&dsi->pll_clk_rate);
@@ -1713,6 +1722,22 @@ static int samsung_dsim_parse_dt(struct samsung_dsim *dsi)
if (ret < 0)
return ret;
+ endpoint = of_graph_get_endpoint_by_regs(node, 1, -1);
+ nr_lanes = of_property_count_u32_elems(endpoint, "data-lanes");
+ if (nr_lanes > 0 && nr_lanes <= 4) {
+ /* Polarity 0 is clock lane, 1..4 are data lanes. */
+ of_property_read_u32_array(endpoint, "lane-polarities",
+ lane_polarities, nr_lanes + 1);
+ for (i = 1; i <= nr_lanes; i++) {
+ if (lane_polarities[1] != lane_polarities[i])
+ DRM_DEV_ERROR(dsi->dev, "Data lanes polarities do not match");
+ }
+ if (lane_polarities[0])
+ dsi->swap_dn_dp_clk = true;
+ if (lane_polarities[1])
+ dsi->swap_dn_dp_data = true;
+ }
+
return 0;
}
@@ -1954,7 +1979,6 @@ static struct platform_driver samsung_dsim_driver = {
.remove = samsung_dsim_remove,
.driver = {
.name = "samsung-dsim",
- .owner = THIS_MODULE,
.pm = &samsung_dsim_pm_ops,
.of_match_table = samsung_dsim_of_match,
},
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 603bb3c51027..9d6dcaf317a1 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -533,7 +533,7 @@ static struct i2c_adapter *dw_hdmi_i2c_adapter(struct dw_hdmi *hdmi)
adap->owner = THIS_MODULE;
adap->dev.parent = hdmi->dev;
adap->algo = &dw_hdmi_algorithm;
- strlcpy(adap->name, "DesignWare HDMI", sizeof(adap->name));
+ strscpy(adap->name, "DesignWare HDMI", sizeof(adap->name));
i2c_set_adapdata(adap, hdmi);
ret = i2c_add_adapter(adap);
diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c
index 91f7cb56a654..d6349af4f1b6 100644
--- a/drivers/gpu/drm/bridge/tc358767.c
+++ b/drivers/gpu/drm/bridge/tc358767.c
@@ -1890,7 +1890,7 @@ static int tc_mipi_dsi_host_attach(struct tc_data *tc)
if (dsi_lanes < 0)
return dsi_lanes;
- dsi = mipi_dsi_device_register_full(host, &info);
+ dsi = devm_mipi_dsi_device_register_full(dev, host, &info);
if (IS_ERR(dsi))
return dev_err_probe(dev, PTR_ERR(dsi),
"failed to create dsi device\n");
@@ -1901,7 +1901,7 @@ static int tc_mipi_dsi_host_attach(struct tc_data *tc)
dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS;
- ret = mipi_dsi_attach(dsi);
+ ret = devm_mipi_dsi_attach(dev, dsi);
if (ret < 0) {
dev_err(dev, "failed to attach dsi to host: %d\n", ret);
return ret;
diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c
index 7c0cbe84611b..97ae3a9c90da 100644
--- a/drivers/gpu/drm/bridge/tc358768.c
+++ b/drivers/gpu/drm/bridge/tc358768.c
@@ -9,6 +9,8 @@
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/kernel.h>
+#include <linux/media-bus-format.h>
+#include <linux/minmax.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
@@ -146,6 +148,7 @@ struct tc358768_priv {
u32 pd_lines; /* number of Parallel Port Input Data Lines */
u32 dsi_lanes; /* number of DSI Lanes */
+ u32 dsi_bpp; /* number of Bits Per Pixel over DSI */
/* Parameters for PLL programming */
u32 fbd; /* PLL feedback divider */
@@ -284,12 +287,12 @@ static void tc358768_hw_disable(struct tc358768_priv *priv)
static u32 tc358768_pll_to_pclk(struct tc358768_priv *priv, u32 pll_clk)
{
- return (u32)div_u64((u64)pll_clk * priv->dsi_lanes, priv->pd_lines);
+ return (u32)div_u64((u64)pll_clk * priv->dsi_lanes, priv->dsi_bpp);
}
static u32 tc358768_pclk_to_pll(struct tc358768_priv *priv, u32 pclk)
{
- return (u32)div_u64((u64)pclk * priv->pd_lines, priv->dsi_lanes);
+ return (u32)div_u64((u64)pclk * priv->dsi_bpp, priv->dsi_lanes);
}
static int tc358768_calc_pll(struct tc358768_priv *priv,
@@ -334,13 +337,17 @@ static int tc358768_calc_pll(struct tc358768_priv *priv,
u32 fbd;
for (fbd = 0; fbd < 512; ++fbd) {
- u32 pll, diff;
+ u32 pll, diff, pll_in;
pll = (u32)div_u64((u64)refclk * (fbd + 1), divisor);
if (pll >= max_pll || pll < min_pll)
continue;
+ pll_in = (u32)div_u64((u64)refclk, prd + 1);
+ if (pll_in < 4000000)
+ continue;
+
diff = max(pll, target_pll) - min(pll, target_pll);
if (diff < best_diff) {
@@ -422,6 +429,7 @@ static int tc358768_dsi_host_attach(struct mipi_dsi_host *host,
priv->output.panel = panel;
priv->dsi_lanes = dev->lanes;
+ priv->dsi_bpp = mipi_dsi_pixel_format_to_bpp(dev->format);
/* get input ep (port0/endpoint0) */
ret = -EINVAL;
@@ -433,7 +441,7 @@ static int tc358768_dsi_host_attach(struct mipi_dsi_host *host,
}
if (ret)
- priv->pd_lines = mipi_dsi_pixel_format_to_bpp(dev->format);
+ priv->pd_lines = priv->dsi_bpp;
drm_bridge_add(&priv->bridge);
@@ -632,8 +640,9 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)
struct mipi_dsi_device *dsi_dev = priv->output.dev;
unsigned long mode_flags = dsi_dev->mode_flags;
u32 val, val2, lptxcnt, hact, data_type;
+ s32 raw_val;
const struct drm_display_mode *mode;
- u32 dsibclk_nsk, dsiclk_nsk, ui_nsk, phy_delay_nsk;
+ u32 dsibclk_nsk, dsiclk_nsk, ui_nsk;
u32 dsiclk, dsibclk, video_start;
const u32 internal_delay = 40;
int ret, i;
@@ -717,11 +726,9 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)
dsibclk);
dsiclk_nsk = (u32)div_u64((u64)1000000000 * TC358768_PRECISION, dsiclk);
ui_nsk = dsiclk_nsk / 2;
- phy_delay_nsk = dsibclk_nsk + 2 * dsiclk_nsk;
dev_dbg(priv->dev, "dsiclk_nsk: %u\n", dsiclk_nsk);
dev_dbg(priv->dev, "ui_nsk: %u\n", ui_nsk);
dev_dbg(priv->dev, "dsibclk_nsk: %u\n", dsibclk_nsk);
- dev_dbg(priv->dev, "phy_delay_nsk: %u\n", phy_delay_nsk);
/* LP11 > 100us for D-PHY Rx Init */
val = tc358768_ns_to_cnt(100 * 1000, dsibclk_nsk) - 1;
@@ -736,25 +743,26 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)
/* 38ns < TCLK_PREPARE < 95ns */
val = tc358768_ns_to_cnt(65, dsibclk_nsk) - 1;
- /* TCLK_PREPARE > 300ns */
- val2 = tc358768_ns_to_cnt(300 + tc358768_to_ns(3 * ui_nsk),
- dsibclk_nsk);
- val |= (val2 - tc358768_to_ns(phy_delay_nsk - dsibclk_nsk)) << 8;
+ /* TCLK_PREPARE + TCLK_ZERO > 300ns */
+ val2 = tc358768_ns_to_cnt(300 - tc358768_to_ns(2 * ui_nsk),
+ dsibclk_nsk) - 2;
+ val |= val2 << 8;
dev_dbg(priv->dev, "TCLK_HEADERCNT: 0x%x\n", val);
tc358768_write(priv, TC358768_TCLK_HEADERCNT, val);
- /* TCLK_TRAIL > 60ns + 3*UI */
- val = 60 + tc358768_to_ns(3 * ui_nsk);
- val = tc358768_ns_to_cnt(val, dsibclk_nsk) - 5;
+ /* TCLK_TRAIL > 60ns AND TEOT <= 105 ns + 12*UI */
+ raw_val = tc358768_ns_to_cnt(60 + tc358768_to_ns(2 * ui_nsk), dsibclk_nsk) - 5;
+ val = clamp(raw_val, 0, 127);
dev_dbg(priv->dev, "TCLK_TRAILCNT: 0x%x\n", val);
tc358768_write(priv, TC358768_TCLK_TRAILCNT, val);
/* 40ns + 4*UI < THS_PREPARE < 85ns + 6*UI */
val = 50 + tc358768_to_ns(4 * ui_nsk);
val = tc358768_ns_to_cnt(val, dsibclk_nsk) - 1;
- /* THS_ZERO > 145ns + 10*UI */
- val2 = tc358768_ns_to_cnt(145 - tc358768_to_ns(ui_nsk), dsibclk_nsk);
- val |= (val2 - tc358768_to_ns(phy_delay_nsk)) << 8;
+ /* THS_PREPARE + THS_ZERO > 145ns + 10*UI */
+ raw_val = tc358768_ns_to_cnt(145 - tc358768_to_ns(3 * ui_nsk), dsibclk_nsk) - 10;
+ val2 = clamp(raw_val, 0, 127);
+ val |= val2 << 8;
dev_dbg(priv->dev, "THS_HEADERCNT: 0x%x\n", val);
tc358768_write(priv, TC358768_THS_HEADERCNT, val);
@@ -770,9 +778,10 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)
dev_dbg(priv->dev, "TCLK_POSTCNT: 0x%x\n", val);
tc358768_write(priv, TC358768_TCLK_POSTCNT, val);
- /* 60ns + 4*UI < THS_PREPARE < 105ns + 12*UI */
- val = tc358768_ns_to_cnt(60 + tc358768_to_ns(15 * ui_nsk),
- dsibclk_nsk) - 5;
+ /* max(60ns + 4*UI, 8*UI) < THS_TRAILCNT < 105ns + 12*UI */
+ raw_val = tc358768_ns_to_cnt(60 + tc358768_to_ns(18 * ui_nsk),
+ dsibclk_nsk) - 4;
+ val = clamp(raw_val, 0, 15);
dev_dbg(priv->dev, "THS_TRAILCNT: 0x%x\n", val);
tc358768_write(priv, TC358768_THS_TRAILCNT, val);
@@ -786,7 +795,7 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)
/* TXTAGOCNT[26:16] RXTASURECNT[10:0] */
val = tc358768_to_ns((lptxcnt + 1) * dsibclk_nsk * 4);
- val = tc358768_ns_to_cnt(val, dsibclk_nsk) - 1;
+ val = tc358768_ns_to_cnt(val, dsibclk_nsk) / 4 - 1;
val2 = tc358768_ns_to_cnt(tc358768_to_ns((lptxcnt + 1) * dsibclk_nsk),
dsibclk_nsk) - 2;
val = val << 16 | val2;
@@ -866,8 +875,7 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)
val = TC358768_DSI_CONFW_MODE_SET | TC358768_DSI_CONFW_ADDR_DSI_CONTROL;
val |= (dsi_dev->lanes - 1) << 1;
- if (!(dsi_dev->mode_flags & MIPI_DSI_MODE_LPM))
- val |= TC358768_DSI_CONTROL_TXMD;
+ val |= TC358768_DSI_CONTROL_TXMD;
if (!(mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS))
val |= TC358768_DSI_CONTROL_HSCKMD;
@@ -913,6 +921,44 @@ static void tc358768_bridge_enable(struct drm_bridge *bridge)
}
}
+#define MAX_INPUT_SEL_FORMATS 1
+
+static u32 *
+tc358768_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
+ struct drm_bridge_state *bridge_state,
+ struct drm_crtc_state *crtc_state,
+ struct drm_connector_state *conn_state,
+ u32 output_fmt,
+ unsigned int *num_input_fmts)
+{
+ struct tc358768_priv *priv = bridge_to_tc358768(bridge);
+ u32 *input_fmts;
+
+ *num_input_fmts = 0;
+
+ input_fmts = kcalloc(MAX_INPUT_SEL_FORMATS, sizeof(*input_fmts),
+ GFP_KERNEL);
+ if (!input_fmts)
+ return NULL;
+
+ switch (priv->pd_lines) {
+ case 16:
+ input_fmts[0] = MEDIA_BUS_FMT_RGB565_1X16;
+ break;
+ case 18:
+ input_fmts[0] = MEDIA_BUS_FMT_RGB666_1X18;
+ break;
+ default:
+ case 24:
+ input_fmts[0] = MEDIA_BUS_FMT_RGB888_1X24;
+ break;
+ }
+
+ *num_input_fmts = MAX_INPUT_SEL_FORMATS;
+
+ return input_fmts;
+}
+
static const struct drm_bridge_funcs tc358768_bridge_funcs = {
.attach = tc358768_bridge_attach,
.mode_valid = tc358768_bridge_mode_valid,
@@ -920,6 +966,11 @@ static const struct drm_bridge_funcs tc358768_bridge_funcs = {
.enable = tc358768_bridge_enable,
.disable = tc358768_bridge_disable,
.post_disable = tc358768_bridge_post_disable,
+
+ .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
+ .atomic_reset = drm_atomic_helper_bridge_reset,
+ .atomic_get_input_bus_fmts = tc358768_atomic_get_input_bus_fmts,
};
static const struct drm_bridge_timings default_tc358768_timings = {
diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
index 75286c9afbb9..1f5c07989e2b 100644
--- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c
+++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
@@ -478,6 +478,7 @@ static void sn65dsi83_atomic_enable(struct drm_bridge *bridge,
dev_err(ctx->dev, "failed to lock PLL, ret=%i\n", ret);
/* On failure, disable PLL again and exit. */
regmap_write(ctx->regmap, REG_RC_PLL_EN, 0x00);
+ regulator_disable(ctx->vcc);
return;
}
diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
index 7a748785c545..260cad1fd1da 100644
--- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c
+++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
@@ -618,6 +618,24 @@ exit:
return len;
}
+static int ti_sn_aux_wait_hpd_asserted(struct drm_dp_aux *aux, unsigned long wait_us)
+{
+ /*
+ * The HPD in this chip is a bit useless (See comment in
+ * ti_sn65dsi86_enable_comms) so if our driver is expected to wait
+ * for HPD, we just assume it's asserted after the wait_us delay.
+ *
+ * In case we are asked to wait forever (wait_us=0) take conservative
+ * 500ms delay.
+ */
+ if (wait_us == 0)
+ wait_us = 500000;
+
+ usleep_range(wait_us, wait_us + 1000);
+
+ return 0;
+}
+
static int ti_sn_aux_probe(struct auxiliary_device *adev,
const struct auxiliary_device_id *id)
{
@@ -627,6 +645,7 @@ static int ti_sn_aux_probe(struct auxiliary_device *adev,
pdata->aux.name = "ti-sn65dsi86-aux";
pdata->aux.dev = &adev->dev;
pdata->aux.transfer = ti_sn_aux_transfer;
+ pdata->aux.wait_hpd_asserted = ti_sn_aux_wait_hpd_asserted;
drm_dp_aux_init(&pdata->aux);
ret = devm_of_dp_aux_populate_ep_devices(&pdata->aux);
diff --git a/drivers/gpu/drm/drm_aperture.c b/drivers/gpu/drm/drm_aperture.c
index 3b8fdeeafd53..5729f3bb4398 100644
--- a/drivers/gpu/drm/drm_aperture.c
+++ b/drivers/gpu/drm/drm_aperture.c
@@ -32,17 +32,13 @@
*
* static int remove_conflicting_framebuffers(struct pci_dev *pdev)
* {
- * bool primary = false;
* resource_size_t base, size;
* int ret;
*
* base = pci_resource_start(pdev, 0);
* size = pci_resource_len(pdev, 0);
- * #ifdef CONFIG_X86
- * primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
- * #endif
*
- * return drm_aperture_remove_conflicting_framebuffers(base, size, primary,
+ * return drm_aperture_remove_conflicting_framebuffers(base, size,
* &example_driver);
* }
*
@@ -161,7 +157,6 @@ EXPORT_SYMBOL(devm_aperture_acquire_from_firmware);
* drm_aperture_remove_conflicting_framebuffers - remove existing framebuffers in the given range
* @base: the aperture's base address in physical memory
* @size: aperture size in bytes
- * @primary: also kick vga16fb if present
* @req_driver: requesting DRM driver
*
* This function removes graphics device drivers which use the memory range described by
@@ -171,9 +166,9 @@ EXPORT_SYMBOL(devm_aperture_acquire_from_firmware);
* 0 on success, or a negative errno code otherwise
*/
int drm_aperture_remove_conflicting_framebuffers(resource_size_t base, resource_size_t size,
- bool primary, const struct drm_driver *req_driver)
+ const struct drm_driver *req_driver)
{
- return aperture_remove_conflicting_devices(base, size, primary, req_driver->name);
+ return aperture_remove_conflicting_devices(base, size, req_driver->name);
}
EXPORT_SYMBOL(drm_aperture_remove_conflicting_framebuffers);
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 2c2c9caf0be5..41b8066f61ff 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -1209,7 +1209,16 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state)
continue;
ret = drm_crtc_vblank_get(crtc);
- WARN_ONCE(ret != -EINVAL, "driver forgot to call drm_crtc_vblank_off()\n");
+ /*
+ * Self-refresh is not a true "disable"; ensure vblank remains
+ * enabled.
+ */
+ if (new_crtc_state->self_refresh_active)
+ WARN_ONCE(ret != 0,
+ "driver disabled vblank in self-refresh\n");
+ else
+ WARN_ONCE(ret != -EINVAL,
+ "driver forgot to call drm_crtc_vblank_off()\n");
if (ret == 0)
drm_crtc_vblank_put(crtc);
}
@@ -3145,7 +3154,7 @@ fail:
EXPORT_SYMBOL(drm_atomic_helper_update_plane);
/**
- * drm_atomic_helper_disable_plane - Helper for primary plane disable using * atomic
+ * drm_atomic_helper_disable_plane - Helper for primary plane disable using atomic
* @plane: plane to disable
* @ctx: lock acquire context
*
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index cee0cc522ed9..12687dd9e1ac 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -969,7 +969,9 @@ EXPORT_SYMBOL(drm_dev_register);
*
* Unregister the DRM device from the system. This does the reverse of
* drm_dev_register() but does not deallocate the device. The caller must call
- * drm_dev_put() to drop their final reference.
+ * drm_dev_put() to drop their final reference, unless it is managed with devres
+ * (as devices allocated with devm_drm_dev_alloc() are), in which case there is
+ * already an unwind action registered.
*
* A special form of unregistering for hotpluggable devices is drm_dev_unplug(),
* which can be called while there are still open users of @dev.
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 64458982be40..f0e9549b6bd7 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -641,19 +641,27 @@ static void drm_fb_helper_damage(struct drm_fb_helper *helper, u32 x, u32 y,
static void drm_fb_helper_memory_range_to_clip(struct fb_info *info, off_t off, size_t len,
struct drm_rect *clip)
{
+ u32 line_length = info->fix.line_length;
+ u32 fb_height = info->var.yres;
off_t end = off + len;
u32 x1 = 0;
- u32 y1 = off / info->fix.line_length;
+ u32 y1 = off / line_length;
u32 x2 = info->var.xres;
- u32 y2 = DIV_ROUND_UP(end, info->fix.line_length);
+ u32 y2 = DIV_ROUND_UP(end, line_length);
+
+ /* Don't allow any of them beyond the bottom bound of display area */
+ if (y1 > fb_height)
+ y1 = fb_height;
+ if (y2 > fb_height)
+ y2 = fb_height;
if ((y2 - y1) == 1) {
/*
* We've only written to a single scanline. Try to reduce
* the number of horizontal pixels that need an update.
*/
- off_t bit_off = (off % info->fix.line_length) * 8;
- off_t bit_end = (end % info->fix.line_length) * 8;
+ off_t bit_off = (off % line_length) * 8;
+ off_t bit_end = (end % line_length) * 8;
x1 = bit_off / info->var.bits_per_pixel;
x2 = DIV_ROUND_UP(bit_end, info->var.bits_per_pixel);
@@ -706,95 +714,6 @@ void drm_fb_helper_deferred_io(struct fb_info *info, struct list_head *pagerefli
}
EXPORT_SYMBOL(drm_fb_helper_deferred_io);
-typedef ssize_t (*drm_fb_helper_read_screen)(struct fb_info *info, char __user *buf,
- size_t count, loff_t pos);
-
-static ssize_t __drm_fb_helper_read(struct fb_info *info, char __user *buf, size_t count,
- loff_t *ppos, drm_fb_helper_read_screen read_screen)
-{
- loff_t pos = *ppos;
- size_t total_size;
- ssize_t ret;
-
- if (info->screen_size)
- total_size = info->screen_size;
- else
- total_size = info->fix.smem_len;
-
- if (pos >= total_size)
- return 0;
- if (count >= total_size)
- count = total_size;
- if (total_size - count < pos)
- count = total_size - pos;
-
- if (info->fbops->fb_sync)
- info->fbops->fb_sync(info);
-
- ret = read_screen(info, buf, count, pos);
- if (ret > 0)
- *ppos += ret;
-
- return ret;
-}
-
-typedef ssize_t (*drm_fb_helper_write_screen)(struct fb_info *info, const char __user *buf,
- size_t count, loff_t pos);
-
-static ssize_t __drm_fb_helper_write(struct fb_info *info, const char __user *buf, size_t count,
- loff_t *ppos, drm_fb_helper_write_screen write_screen)
-{
- loff_t pos = *ppos;
- size_t total_size;
- ssize_t ret;
- int err = 0;
-
- if (info->screen_size)
- total_size = info->screen_size;
- else
- total_size = info->fix.smem_len;
-
- if (pos > total_size)
- return -EFBIG;
- if (count > total_size) {
- err = -EFBIG;
- count = total_size;
- }
- if (total_size - count < pos) {
- if (!err)
- err = -ENOSPC;
- count = total_size - pos;
- }
-
- if (info->fbops->fb_sync)
- info->fbops->fb_sync(info);
-
- /*
- * Copy to framebuffer even if we already logged an error. Emulates
- * the behavior of the original fbdev implementation.
- */
- ret = write_screen(info, buf, count, pos);
- if (ret < 0)
- return ret; /* return last error, if any */
- else if (!ret)
- return err; /* return previous error, if any */
-
- *ppos += ret;
-
- return ret;
-}
-
-static ssize_t drm_fb_helper_read_screen_buffer(struct fb_info *info, char __user *buf,
- size_t count, loff_t pos)
-{
- const char *src = info->screen_buffer + pos;
-
- if (copy_to_user(buf, src, count))
- return -EFAULT;
-
- return count;
-}
-
/**
* drm_fb_helper_sys_read - Implements struct &fb_ops.fb_read for system memory
* @info: fb_info struct pointer
@@ -808,21 +727,10 @@ static ssize_t drm_fb_helper_read_screen_buffer(struct fb_info *info, char __use
ssize_t drm_fb_helper_sys_read(struct fb_info *info, char __user *buf,
size_t count, loff_t *ppos)
{
- return __drm_fb_helper_read(info, buf, count, ppos, drm_fb_helper_read_screen_buffer);
+ return fb_sys_read(info, buf, count, ppos);
}
EXPORT_SYMBOL(drm_fb_helper_sys_read);
-static ssize_t drm_fb_helper_write_screen_buffer(struct fb_info *info, const char __user *buf,
- size_t count, loff_t pos)
-{
- char *dst = info->screen_buffer + pos;
-
- if (copy_from_user(dst, buf, count))
- return -EFAULT;
-
- return count;
-}
-
/**
* drm_fb_helper_sys_write - Implements struct &fb_ops.fb_write for system memory
* @info: fb_info struct pointer
@@ -841,7 +749,7 @@ ssize_t drm_fb_helper_sys_write(struct fb_info *info, const char __user *buf,
ssize_t ret;
struct drm_rect damage_area;
- ret = __drm_fb_helper_write(info, buf, count, ppos, drm_fb_helper_write_screen_buffer);
+ ret = fb_sys_write(info, buf, count, ppos);
if (ret <= 0)
return ret;
@@ -913,39 +821,6 @@ void drm_fb_helper_sys_imageblit(struct fb_info *info,
}
EXPORT_SYMBOL(drm_fb_helper_sys_imageblit);
-static ssize_t fb_read_screen_base(struct fb_info *info, char __user *buf, size_t count,
- loff_t pos)
-{
- const char __iomem *src = info->screen_base + pos;
- size_t alloc_size = min_t(size_t, count, PAGE_SIZE);
- ssize_t ret = 0;
- int err = 0;
- char *tmp;
-
- tmp = kmalloc(alloc_size, GFP_KERNEL);
- if (!tmp)
- return -ENOMEM;
-
- while (count) {
- size_t c = min_t(size_t, count, alloc_size);
-
- memcpy_fromio(tmp, src, c);
- if (copy_to_user(buf, tmp, c)) {
- err = -EFAULT;
- break;
- }
-
- src += c;
- buf += c;
- ret += c;
- count -= c;
- }
-
- kfree(tmp);
-
- return ret ? ret : err;
-}
-
/**
* drm_fb_helper_cfb_read - Implements struct &fb_ops.fb_read for I/O memory
* @info: fb_info struct pointer
@@ -959,43 +834,10 @@ static ssize_t fb_read_screen_base(struct fb_info *info, char __user *buf, size_
ssize_t drm_fb_helper_cfb_read(struct fb_info *info, char __user *buf,
size_t count, loff_t *ppos)
{
- return __drm_fb_helper_read(info, buf, count, ppos, fb_read_screen_base);
+ return fb_io_read(info, buf, count, ppos);
}
EXPORT_SYMBOL(drm_fb_helper_cfb_read);
-static ssize_t fb_write_screen_base(struct fb_info *info, const char __user *buf, size_t count,
- loff_t pos)
-{
- char __iomem *dst = info->screen_base + pos;
- size_t alloc_size = min_t(size_t, count, PAGE_SIZE);
- ssize_t ret = 0;
- int err = 0;
- u8 *tmp;
-
- tmp = kmalloc(alloc_size, GFP_KERNEL);
- if (!tmp)
- return -ENOMEM;
-
- while (count) {
- size_t c = min_t(size_t, count, alloc_size);
-
- if (copy_from_user(tmp, buf, c)) {
- err = -EFAULT;
- break;
- }
- memcpy_toio(dst, tmp, c);
-
- dst += c;
- buf += c;
- ret += c;
- count -= c;
- }
-
- kfree(tmp);
-
- return ret ? ret : err;
-}
-
/**
* drm_fb_helper_cfb_write - Implements struct &fb_ops.fb_write for I/O memory
* @info: fb_info struct pointer
@@ -1014,7 +856,7 @@ ssize_t drm_fb_helper_cfb_write(struct fb_info *info, const char __user *buf,
ssize_t ret;
struct drm_rect damage_area;
- ret = __drm_fb_helper_write(info, buf, count, ppos, fb_write_screen_base);
+ ret = fb_io_write(info, buf, count, ppos);
if (ret <= 0)
return ret;
diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
index e93533b86037..b8a615a138cd 100644
--- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c
+++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
@@ -9,6 +9,7 @@
#include <linux/module.h>
#include <drm/drm_damage_helper.h>
+#include <drm/drm_drv.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_framebuffer.h>
#include <drm/drm_gem.h>
@@ -164,6 +165,14 @@ int drm_gem_fb_init_with_funcs(struct drm_device *dev,
return -EINVAL;
}
+ if (drm_drv_uses_atomic_modeset(dev) &&
+ !drm_any_plane_has_format(dev, mode_cmd->pixel_format,
+ mode_cmd->modifier[0])) {
+ drm_dbg(dev, "Unsupported pixel format %p4cc / modifier 0x%llx\n",
+ &mode_cmd->pixel_format, mode_cmd->modifier[0]);
+ return -EINVAL;
+ }
+
for (i = 0; i < info->num_planes; i++) {
unsigned int width = mode_cmd->width / (i ? info->hsub : 1);
unsigned int height = mode_cmd->height / (i ? info->vsub : 1);
diff --git a/drivers/gpu/drm/drm_gem_vram_helper.c b/drivers/gpu/drm/drm_gem_vram_helper.c
index 0bea3df2a16d..b67eafa55715 100644
--- a/drivers/gpu/drm/drm_gem_vram_helper.c
+++ b/drivers/gpu/drm/drm_gem_vram_helper.c
@@ -45,7 +45,7 @@ static const struct drm_gem_object_funcs drm_gem_vram_object_funcs;
* the frame's scanout buffer or the cursor image. If there's no more space
* left in VRAM, inactive GEM objects can be moved to system memory.
*
- * To initialize the VRAM helper library call drmm_vram_helper_alloc_mm().
+ * To initialize the VRAM helper library call drmm_vram_helper_init().
* The function allocates and initializes an instance of &struct drm_vram_mm
* in &struct drm_device.vram_mm . Use &DRM_GEM_VRAM_DRIVER to initialize
* &struct drm_driver and &DRM_VRAM_MM_FILE_OPERATIONS to initialize
@@ -73,7 +73,7 @@ static const struct drm_gem_object_funcs drm_gem_vram_object_funcs;
* // setup device, vram base and size
* // ...
*
- * ret = drmm_vram_helper_alloc_mm(dev, vram_base, vram_size);
+ * ret = drmm_vram_helper_init(dev, vram_base, vram_size);
* if (ret)
* return ret;
* return 0;
@@ -86,7 +86,7 @@ static const struct drm_gem_object_funcs drm_gem_vram_object_funcs;
* to userspace.
*
* You don't have to clean up the instance of VRAM MM.
- * drmm_vram_helper_alloc_mm() is a managed interface that installs a
+ * drmm_vram_helper_init() is a managed interface that installs a
* clean-up handler to run during the DRM device's release.
*
* For drawing or scanout operations, rsp. buffer objects have to be pinned
diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index 295382cd09b0..3fd6c733ff4e 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -221,7 +221,7 @@ mipi_dsi_device_register_full(struct mipi_dsi_host *host,
return dsi;
}
- dsi->dev.of_node = info->node;
+ device_set_node(&dsi->dev, of_fwnode_handle(info->node));
dsi->channel = info->channel;
strlcpy(dsi->name, info->type, sizeof(dsi->name));
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
index 3c22a803201d..f62767ff34b2 100644
--- a/drivers/gpu/drm/drm_sysfs.c
+++ b/drivers/gpu/drm/drm_sysfs.c
@@ -11,12 +11,14 @@
*/
#include <linux/acpi.h>
+#include <linux/component.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/export.h>
#include <linux/gfp.h>
#include <linux/i2c.h>
#include <linux/kdev_t.h>
+#include <linux/property.h>
#include <linux/slab.h>
#include <drm/drm_accel.h>
@@ -96,6 +98,34 @@ static char *drm_devnode(const struct device *dev, umode_t *mode)
return kasprintf(GFP_KERNEL, "dri/%s", dev_name(dev));
}
+static int typec_connector_bind(struct device *dev,
+ struct device *typec_connector, void *data)
+{
+ int ret;
+
+ ret = sysfs_create_link(&dev->kobj, &typec_connector->kobj, "typec_connector");
+ if (ret)
+ return ret;
+
+ ret = sysfs_create_link(&typec_connector->kobj, &dev->kobj, "drm_connector");
+ if (ret)
+ sysfs_remove_link(&dev->kobj, "typec_connector");
+
+ return ret;
+}
+
+static void typec_connector_unbind(struct device *dev,
+ struct device *typec_connector, void *data)
+{
+ sysfs_remove_link(&typec_connector->kobj, "drm_connector");
+ sysfs_remove_link(&dev->kobj, "typec_connector");
+}
+
+static const struct component_ops typec_connector_ops = {
+ .bind = typec_connector_bind,
+ .unbind = typec_connector_unbind,
+};
+
static CLASS_ATTR_STRING(version, S_IRUGO, "drm 1.1.0 20060810");
/**
@@ -282,16 +312,27 @@ static ssize_t modes_show(struct device *device,
return written;
}
+static ssize_t connector_id_show(struct device *device,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct drm_connector *connector = to_drm_connector(device);
+
+ return sysfs_emit(buf, "%d\n", connector->base.id);
+}
+
static DEVICE_ATTR_RW(status);
static DEVICE_ATTR_RO(enabled);
static DEVICE_ATTR_RO(dpms);
static DEVICE_ATTR_RO(modes);
+static DEVICE_ATTR_RO(connector_id);
static struct attribute *connector_dev_attrs[] = {
&dev_attr_status.attr,
&dev_attr_enabled.attr,
&dev_attr_dpms.attr,
&dev_attr_modes.attr,
+ &dev_attr_connector_id.attr,
NULL
};
@@ -353,9 +394,16 @@ int drm_sysfs_connector_add(struct drm_connector *connector)
connector->kdev = kdev;
+ if (dev_fwnode(kdev)) {
+ r = component_add(kdev, &typec_connector_ops);
+ if (r)
+ drm_err(dev, "failed to add component to create link to typec connector\n");
+ }
+
if (connector->ddc)
return sysfs_create_link(&connector->kdev->kobj,
&connector->ddc->dev.kobj, "ddc");
+
return 0;
err_free:
@@ -371,6 +419,9 @@ void drm_sysfs_connector_remove(struct drm_connector *connector)
if (connector->ddc)
sysfs_remove_link(&connector->kdev->kobj, "ddc");
+ if (dev_fwnode(connector->kdev))
+ component_del(connector->kdev, &typec_connector_ops);
+
DRM_DEBUG("removing \"%s\" from sysfs\n",
connector->name);
diff --git a/drivers/gpu/drm/gma500/fbdev.c b/drivers/gpu/drm/gma500/fbdev.c
index 62287407e717..4f0309548b2b 100644
--- a/drivers/gpu/drm/gma500/fbdev.c
+++ b/drivers/gpu/drm/gma500/fbdev.c
@@ -231,7 +231,7 @@ static int psb_fbdev_fb_probe(struct drm_fb_helper *fb_helper,
info->fix.mmio_start = pci_resource_start(pdev, 0);
info->fix.mmio_len = pci_resource_len(pdev, 0);
- memset(info->screen_base, 0, info->screen_size);
+ fb_memset_io(info->screen_base, 0, info->screen_size);
/* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c
index 2ce96b1b9c74..8b64f61ffaf9 100644
--- a/drivers/gpu/drm/gma500/psb_drv.c
+++ b/drivers/gpu/drm/gma500/psb_drv.c
@@ -7,6 +7,7 @@
*
**************************************************************************/
+#include <linux/aperture.h>
#include <linux/cpu.h>
#include <linux/module.h>
#include <linux/notifier.h>
@@ -19,7 +20,6 @@
#include <acpi/video.h>
#include <drm/drm.h>
-#include <drm/drm_aperture.h>
#include <drm/drm_drv.h>
#include <drm/drm_file.h>
#include <drm/drm_ioctl.h>
@@ -414,20 +414,45 @@ out_err:
return ret;
}
+/*
+ * Hardware for gma500 is a hybrid device, which both acts as a PCI
+ * device (for legacy vga functionality) but also more like an
+ * integrated display on a SoC where the framebuffer simply
+ * resides in main memory and not in a special PCI bar (that
+ * internally redirects to a stolen range of main memory) like all
+ * other integrated PCI display devices implement it.
+ *
+ * To catch all cases we need to remove conflicting firmware devices
+ * for the stolen system memory and for the VGA functionality. As we
+ * currently cannot easily find the framebuffer's location in stolen
+ * memory, we remove all framebuffers here.
+ *
+ * TODO: Refactor psb_driver_load() to map vdc_reg earlier. Then
+ * we might be able to read the framebuffer range from the
+ * device.
+ */
+static int gma_remove_conflicting_framebuffers(struct pci_dev *pdev,
+ const struct drm_driver *req_driver)
+{
+ resource_size_t base = 0;
+ resource_size_t size = U32_MAX; /* 4 GiB HW limit */
+ const char *name = req_driver->name;
+ int ret;
+
+ ret = aperture_remove_conflicting_devices(base, size, name);
+ if (ret)
+ return ret;
+
+ return __aperture_remove_legacy_vga_devices(pdev);
+}
+
static int psb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
struct drm_psb_private *dev_priv;
struct drm_device *dev;
int ret;
- /*
- * We cannot yet easily find the framebuffer's location in memory. So
- * remove all framebuffers here.
- *
- * TODO: Refactor psb_driver_load() to map vdc_reg earlier. Then we
- * might be able to read the framebuffer range from the device.
- */
- ret = drm_aperture_remove_framebuffers(true, &driver);
+ ret = gma_remove_conflicting_framebuffers(pdev, &driver);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/hyperv/hyperv_drm_drv.c b/drivers/gpu/drm/hyperv/hyperv_drm_drv.c
index f830d62a5ce6..a7d2c92d6c6a 100644
--- a/drivers/gpu/drm/hyperv/hyperv_drm_drv.c
+++ b/drivers/gpu/drm/hyperv/hyperv_drm_drv.c
@@ -74,7 +74,6 @@ static int hyperv_setup_vram(struct hyperv_drm_device *hv,
drm_aperture_remove_conflicting_framebuffers(screen_info.lfb_base,
screen_info.lfb_size,
- false,
&hyperv_driver);
hv->fb_size = (unsigned long)hv->mmio_megabytes * 1024 * 1024;
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 83ba84f78800..06374fc072d3 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -195,6 +195,7 @@ i915-y += \
# general-purpose microcontroller (GuC) support
i915-y += \
gt/uc/intel_gsc_fw.o \
+ gt/uc/intel_gsc_proxy.o \
gt/uc/intel_gsc_uc.o \
gt/uc/intel_gsc_uc_heci_cmd_submit.o\
gt/uc/intel_guc.o \
@@ -347,6 +348,7 @@ i915-y += \
i915-$(CONFIG_DRM_I915_PXP) += \
pxp/intel_pxp_cmd.o \
pxp/intel_pxp_debugfs.o \
+ pxp/intel_pxp_gsccs.o \
pxp/intel_pxp_irq.o \
pxp/intel_pxp_pm.o \
pxp/intel_pxp_session.o
@@ -382,7 +384,7 @@ obj-$(CONFIG_DRM_I915_GVT_KVMGT) += kvmgt.o
#
# Enable locally for CONFIG_DRM_I915_WERROR=y. See also scripts/Makefile.build
ifdef CONFIG_DRM_I915_WERROR
- cmd_checkdoc = $(srctree)/scripts/kernel-doc -none $<
+ cmd_checkdoc = $(srctree)/scripts/kernel-doc -none -Werror $<
endif
# header test
@@ -397,7 +399,7 @@ always-$(CONFIG_DRM_I915_WERROR) += \
quiet_cmd_hdrtest = HDRTEST $(patsubst %.hdrtest,%.h,$@)
cmd_hdrtest = $(CC) $(filter-out $(CFLAGS_GCOV), $(c_flags)) -S -o /dev/null -x c /dev/null -include $<; \
- $(srctree)/scripts/kernel-doc -none $<; touch $@
+ $(srctree)/scripts/kernel-doc -none -Werror $<; touch $@
$(obj)/%.hdrtest: $(src)/%.h FORCE
$(call if_changed_dep,hdrtest)
diff --git a/drivers/gpu/drm/i915/display/intel_dpt.c b/drivers/gpu/drm/i915/display/intel_dpt.c
index b8027392144d..7c5fddb203ba 100644
--- a/drivers/gpu/drm/i915/display/intel_dpt.c
+++ b/drivers/gpu/drm/i915/display/intel_dpt.c
@@ -43,24 +43,24 @@ static void gen8_set_pte(void __iomem *addr, gen8_pte_t pte)
static void dpt_insert_page(struct i915_address_space *vm,
dma_addr_t addr,
u64 offset,
- enum i915_cache_level level,
+ unsigned int pat_index,
u32 flags)
{
struct i915_dpt *dpt = i915_vm_to_dpt(vm);
gen8_pte_t __iomem *base = dpt->iomem;
gen8_set_pte(base + offset / I915_GTT_PAGE_SIZE,
- vm->pte_encode(addr, level, flags));
+ vm->pte_encode(addr, pat_index, flags));
}
static void dpt_insert_entries(struct i915_address_space *vm,
struct i915_vma_resource *vma_res,
- enum i915_cache_level level,
+ unsigned int pat_index,
u32 flags)
{
struct i915_dpt *dpt = i915_vm_to_dpt(vm);
gen8_pte_t __iomem *base = dpt->iomem;
- const gen8_pte_t pte_encode = vm->pte_encode(0, level, flags);
+ const gen8_pte_t pte_encode = vm->pte_encode(0, pat_index, flags);
struct sgt_iter sgt_iter;
dma_addr_t addr;
int i;
@@ -83,7 +83,7 @@ static void dpt_clear_range(struct i915_address_space *vm,
static void dpt_bind_vma(struct i915_address_space *vm,
struct i915_vm_pt_stash *stash,
struct i915_vma_resource *vma_res,
- enum i915_cache_level cache_level,
+ unsigned int pat_index,
u32 flags)
{
u32 pte_flags;
@@ -98,7 +98,7 @@ static void dpt_bind_vma(struct i915_address_space *vm,
if (vma_res->bi.lmem)
pte_flags |= PTE_LM;
- vm->insert_entries(vm, vma_res, cache_level, pte_flags);
+ vm->insert_entries(vm, vma_res, pat_index, pte_flags);
vma_res->page_sizes_gtt = I915_GTT_PAGE_SIZE;
@@ -300,7 +300,7 @@ intel_dpt_create(struct intel_framebuffer *fb)
vm->vma_ops.bind_vma = dpt_bind_vma;
vm->vma_ops.unbind_vma = dpt_unbind_vma;
- vm->pte_encode = gen8_ggtt_pte_encode;
+ vm->pte_encode = vm->gt->ggtt->vm.pte_encode;
dpt->obj = dpt_obj;
dpt->obj->is_dpt = true;
diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c
index 9db7aabef9b6..0d27a98dcbbe 100644
--- a/drivers/gpu/drm/i915/display/intel_fb.c
+++ b/drivers/gpu/drm/i915/display/intel_fb.c
@@ -1230,7 +1230,8 @@ bool intel_fb_needs_pot_stride_remap(const struct intel_framebuffer *fb)
{
struct drm_i915_private *i915 = to_i915(fb->base.dev);
- return IS_ALDERLAKE_P(i915) && intel_fb_uses_dpt(&fb->base);
+ return (IS_ALDERLAKE_P(i915) || DISPLAY_VER(i915) >= 14) &&
+ intel_fb_uses_dpt(&fb->base);
}
static int intel_fb_pitch(const struct intel_framebuffer *fb, int color_plane, unsigned int rotation)
@@ -1366,9 +1367,10 @@ plane_view_scanout_stride(const struct intel_framebuffer *fb, int color_plane,
unsigned int tile_width,
unsigned int src_stride_tiles, unsigned int dst_stride_tiles)
{
+ struct drm_i915_private *i915 = to_i915(fb->base.dev);
unsigned int stride_tiles;
- if (IS_ALDERLAKE_P(to_i915(fb->base.dev)))
+ if (IS_ALDERLAKE_P(i915) || DISPLAY_VER(i915) >= 14)
stride_tiles = src_stride_tiles;
else
stride_tiles = dst_stride_tiles;
@@ -1562,7 +1564,8 @@ static void intel_fb_view_init(struct drm_i915_private *i915, struct intel_fb_vi
memset(view, 0, sizeof(*view));
view->gtt.type = view_type;
- if (view_type == I915_GTT_VIEW_REMAPPED && IS_ALDERLAKE_P(i915))
+ if (view_type == I915_GTT_VIEW_REMAPPED &&
+ (IS_ALDERLAKE_P(i915) || DISPLAY_VER(i915) >= 14))
view->gtt.remapped.plane_alignment = SZ_2M / PAGE_SIZE;
}
diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c
index 673bcdfb7ff6..aab1ae74a8f7 100644
--- a/drivers/gpu/drm/i915/display/intel_fbdev.c
+++ b/drivers/gpu/drm/i915/display/intel_fbdev.c
@@ -40,8 +40,10 @@
#include <drm/drm_crtc.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_fourcc.h>
+#include <drm/drm_gem_framebuffer_helper.h>
#include "gem/i915_gem_lmem.h"
+#include "gem/i915_gem_mman.h"
#include "i915_drv.h"
#include "intel_display_types.h"
@@ -67,6 +69,11 @@ struct intel_fbdev {
struct mutex hpd_lock;
};
+static struct intel_fbdev *to_intel_fbdev(struct drm_fb_helper *fb_helper)
+{
+ return container_of(fb_helper, struct intel_fbdev, helper);
+}
+
static struct intel_frontbuffer *to_frontbuffer(struct intel_fbdev *ifbdev)
{
return ifbdev->fb->frontbuffer;
@@ -79,9 +86,7 @@ static void intel_fbdev_invalidate(struct intel_fbdev *ifbdev)
static int intel_fbdev_set_par(struct fb_info *info)
{
- struct drm_fb_helper *fb_helper = info->par;
- struct intel_fbdev *ifbdev =
- container_of(fb_helper, struct intel_fbdev, helper);
+ struct intel_fbdev *ifbdev = to_intel_fbdev(info->par);
int ret;
ret = drm_fb_helper_set_par(info);
@@ -93,9 +98,7 @@ static int intel_fbdev_set_par(struct fb_info *info)
static int intel_fbdev_blank(int blank, struct fb_info *info)
{
- struct drm_fb_helper *fb_helper = info->par;
- struct intel_fbdev *ifbdev =
- container_of(fb_helper, struct intel_fbdev, helper);
+ struct intel_fbdev *ifbdev = to_intel_fbdev(info->par);
int ret;
ret = drm_fb_helper_blank(blank, info);
@@ -108,9 +111,7 @@ static int intel_fbdev_blank(int blank, struct fb_info *info)
static int intel_fbdev_pan_display(struct fb_var_screeninfo *var,
struct fb_info *info)
{
- struct drm_fb_helper *fb_helper = info->par;
- struct intel_fbdev *ifbdev =
- container_of(fb_helper, struct intel_fbdev, helper);
+ struct intel_fbdev *ifbdev = to_intel_fbdev(info->par);
int ret;
ret = drm_fb_helper_pan_display(var, info);
@@ -120,6 +121,15 @@ static int intel_fbdev_pan_display(struct fb_var_screeninfo *var,
return ret;
}
+static int intel_fbdev_mmap(struct fb_info *info, struct vm_area_struct *vma)
+{
+ struct intel_fbdev *fbdev = to_intel_fbdev(info->par);
+ struct drm_gem_object *bo = drm_gem_fb_get_obj(&fbdev->fb->base, 0);
+ struct drm_i915_gem_object *obj = to_intel_bo(bo);
+
+ return i915_gem_fb_mmap(obj, vma);
+}
+
static const struct fb_ops intelfb_ops = {
.owner = THIS_MODULE,
DRM_FB_HELPER_DEFAULT_OPS,
@@ -131,13 +141,13 @@ static const struct fb_ops intelfb_ops = {
.fb_imageblit = drm_fb_helper_cfb_imageblit,
.fb_pan_display = intel_fbdev_pan_display,
.fb_blank = intel_fbdev_blank,
+ .fb_mmap = intel_fbdev_mmap,
};
static int intelfb_alloc(struct drm_fb_helper *helper,
struct drm_fb_helper_surface_size *sizes)
{
- struct intel_fbdev *ifbdev =
- container_of(helper, struct intel_fbdev, helper);
+ struct intel_fbdev *ifbdev = to_intel_fbdev(helper);
struct drm_framebuffer *fb;
struct drm_device *dev = helper->dev;
struct drm_i915_private *dev_priv = to_i915(dev);
@@ -163,7 +173,8 @@ static int intelfb_alloc(struct drm_fb_helper *helper,
obj = ERR_PTR(-ENODEV);
if (HAS_LMEM(dev_priv)) {
obj = i915_gem_object_create_lmem(dev_priv, size,
- I915_BO_ALLOC_CONTIGUOUS);
+ I915_BO_ALLOC_CONTIGUOUS |
+ I915_BO_ALLOC_USER);
} else {
/*
* If the FB is too big, just don't use it since fbdev is not very
@@ -193,8 +204,7 @@ static int intelfb_alloc(struct drm_fb_helper *helper,
static int intelfb_create(struct drm_fb_helper *helper,
struct drm_fb_helper_surface_size *sizes)
{
- struct intel_fbdev *ifbdev =
- container_of(helper, struct intel_fbdev, helper);
+ struct intel_fbdev *ifbdev = to_intel_fbdev(helper);
struct intel_framebuffer *intel_fb = ifbdev->fb;
struct drm_device *dev = helper->dev;
struct drm_i915_private *dev_priv = to_i915(dev);
diff --git a/drivers/gpu/drm/i915/display/intel_plane_initial.c b/drivers/gpu/drm/i915/display/intel_plane_initial.c
index bb6ea7de5c61..736072a8b2b0 100644
--- a/drivers/gpu/drm/i915/display/intel_plane_initial.c
+++ b/drivers/gpu/drm/i915/display/intel_plane_initial.c
@@ -110,7 +110,9 @@ initial_plane_vma(struct drm_i915_private *i915,
size * 2 > i915->dsm.usable_size)
return NULL;
- obj = i915_gem_object_create_region_at(mem, phys_base, size, 0);
+ obj = i915_gem_object_create_region_at(mem, phys_base, size,
+ I915_BO_ALLOC_USER |
+ I915_BO_PREALLOC);
if (IS_ERR(obj))
return NULL;
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_domain.c b/drivers/gpu/drm/i915/gem/i915_gem_domain.c
index d2d5a24301b2..dfaaa8b66ac3 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_domain.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_domain.c
@@ -27,8 +27,15 @@ static bool gpu_write_needs_clflush(struct drm_i915_gem_object *obj)
if (IS_DGFX(i915))
return false;
- return !(obj->cache_level == I915_CACHE_NONE ||
- obj->cache_level == I915_CACHE_WT);
+ /*
+ * For objects created by userspace through GEM_CREATE with pat_index
+ * set by set_pat extension, i915_gem_object_has_cache_level() will
+ * always return true, because the coherency of such object is managed
+ * by userspace. Othereise the call here would fall back to checking
+ * whether the object is un-cached or write-through.
+ */
+ return !(i915_gem_object_has_cache_level(obj, I915_CACHE_NONE) ||
+ i915_gem_object_has_cache_level(obj, I915_CACHE_WT));
}
bool i915_gem_cpu_write_needs_clflush(struct drm_i915_gem_object *obj)
@@ -267,7 +274,13 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj,
{
int ret;
- if (obj->cache_level == cache_level)
+ /*
+ * For objects created by userspace through GEM_CREATE with pat_index
+ * set by set_pat extension, simply return 0 here without touching
+ * the cache setting, because such objects should have an immutable
+ * cache setting by desgin and always managed by userspace.
+ */
+ if (i915_gem_object_has_cache_level(obj, cache_level))
return 0;
ret = i915_gem_object_wait(obj,
@@ -278,10 +291,8 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj,
return ret;
/* Always invalidate stale cachelines */
- if (obj->cache_level != cache_level) {
- i915_gem_object_set_cache_coherency(obj, cache_level);
- obj->cache_dirty = true;
- }
+ i915_gem_object_set_cache_coherency(obj, cache_level);
+ obj->cache_dirty = true;
/* The cache-level will be applied when each vma is rebound. */
return i915_gem_object_unbind(obj,
@@ -306,20 +317,22 @@ int i915_gem_get_caching_ioctl(struct drm_device *dev, void *data,
goto out;
}
- switch (obj->cache_level) {
- case I915_CACHE_LLC:
- case I915_CACHE_L3_LLC:
- args->caching = I915_CACHING_CACHED;
- break;
+ /*
+ * This ioctl should be disabled for the objects with pat_index
+ * set by user space.
+ */
+ if (obj->pat_set_by_user) {
+ err = -EOPNOTSUPP;
+ goto out;
+ }
- case I915_CACHE_WT:
+ if (i915_gem_object_has_cache_level(obj, I915_CACHE_LLC) ||
+ i915_gem_object_has_cache_level(obj, I915_CACHE_L3_LLC))
+ args->caching = I915_CACHING_CACHED;
+ else if (i915_gem_object_has_cache_level(obj, I915_CACHE_WT))
args->caching = I915_CACHING_DISPLAY;
- break;
-
- default:
+ else
args->caching = I915_CACHING_NONE;
- break;
- }
out:
rcu_read_unlock();
return err;
@@ -337,6 +350,9 @@ int i915_gem_set_caching_ioctl(struct drm_device *dev, void *data,
if (IS_DGFX(i915))
return -ENODEV;
+ if (GRAPHICS_VER_FULL(i915) >= IP_VER(12, 70))
+ return -EOPNOTSUPP;
+
switch (args->caching) {
case I915_CACHING_NONE:
level = I915_CACHE_NONE;
@@ -365,6 +381,15 @@ int i915_gem_set_caching_ioctl(struct drm_device *dev, void *data,
return -ENOENT;
/*
+ * This ioctl should be disabled for the objects with pat_index
+ * set by user space.
+ */
+ if (obj->pat_set_by_user) {
+ ret = -EOPNOTSUPP;
+ goto out;
+ }
+
+ /*
* The caching mode of proxy object is handled by its generator, and
* not allowed to be changed by userspace.
*/
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
index 3aeede6aee4d..5fb459ea4294 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -640,9 +640,15 @@ static inline int use_cpu_reloc(const struct reloc_cache *cache,
if (DBG_FORCE_RELOC == FORCE_GTT_RELOC)
return false;
+ /*
+ * For objects created by userspace through GEM_CREATE with pat_index
+ * set by set_pat extension, i915_gem_object_has_cache_level() always
+ * return true, otherwise the call would fall back to checking whether
+ * the object is un-cached.
+ */
return (cache->has_llc ||
obj->cache_dirty ||
- obj->cache_level != I915_CACHE_NONE);
+ !i915_gem_object_has_cache_level(obj, I915_CACHE_NONE));
}
static int eb_reserve_vma(struct i915_execbuffer *eb,
@@ -1324,7 +1330,10 @@ static void *reloc_iomap(struct i915_vma *batch,
if (drm_mm_node_allocated(&cache->node)) {
ggtt->vm.insert_page(&ggtt->vm,
i915_gem_object_get_dma_address(obj, page),
- offset, I915_CACHE_NONE, 0);
+ offset,
+ i915_gem_get_pat_index(ggtt->vm.i915,
+ I915_CACHE_NONE),
+ 0);
} else {
offset += page << PAGE_SHIFT;
}
@@ -1464,7 +1473,7 @@ eb_relocate_entry(struct i915_execbuffer *eb,
reloc_cache_unmap(&eb->reloc_cache);
mutex_lock(&vma->vm->mutex);
err = i915_vma_bind(target->vma,
- target->vma->obj->cache_level,
+ target->vma->obj->pat_index,
PIN_GLOBAL, NULL, NULL);
mutex_unlock(&vma->vm->mutex);
reloc_cache_remap(&eb->reloc_cache, ev->vma->obj);
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index d3c1dee16af2..4e7a838ab7bd 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -383,7 +383,16 @@ retry:
}
/* Access to snoopable pages through the GTT is incoherent. */
- if (obj->cache_level != I915_CACHE_NONE && !HAS_LLC(i915)) {
+ /*
+ * For objects created by userspace through GEM_CREATE with pat_index
+ * set by set_pat extension, coherency is managed by userspace, make
+ * sure we don't fail handling the vm fault by calling
+ * i915_gem_object_has_cache_level() which always return true for such
+ * objects. Otherwise this helper function would fall back to checking
+ * whether the object is un-cached.
+ */
+ if (!(i915_gem_object_has_cache_level(obj, I915_CACHE_NONE) ||
+ HAS_LLC(i915))) {
ret = -EFAULT;
goto err_unpin;
}
@@ -927,53 +936,15 @@ static struct file *mmap_singleton(struct drm_i915_private *i915)
return file;
}
-/*
- * This overcomes the limitation in drm_gem_mmap's assignment of a
- * drm_gem_object as the vma->vm_private_data. Since we need to
- * be able to resolve multiple mmap offsets which could be tied
- * to a single gem object.
- */
-int i915_gem_mmap(struct file *filp, struct vm_area_struct *vma)
+static int
+i915_gem_object_mmap(struct drm_i915_gem_object *obj,
+ struct i915_mmap_offset *mmo,
+ struct vm_area_struct *vma)
{
- struct drm_vma_offset_node *node;
- struct drm_file *priv = filp->private_data;
- struct drm_device *dev = priv->minor->dev;
- struct drm_i915_gem_object *obj = NULL;
- struct i915_mmap_offset *mmo = NULL;
+ struct drm_i915_private *i915 = to_i915(obj->base.dev);
+ struct drm_device *dev = &i915->drm;
struct file *anon;
- if (drm_dev_is_unplugged(dev))
- return -ENODEV;
-
- rcu_read_lock();
- drm_vma_offset_lock_lookup(dev->vma_offset_manager);
- node = drm_vma_offset_exact_lookup_locked(dev->vma_offset_manager,
- vma->vm_pgoff,
- vma_pages(vma));
- if (node && drm_vma_node_is_allowed(node, priv)) {
- /*
- * Skip 0-refcnted objects as it is in the process of being
- * destroyed and will be invalid when the vma manager lock
- * is released.
- */
- if (!node->driver_private) {
- mmo = container_of(node, struct i915_mmap_offset, vma_node);
- obj = i915_gem_object_get_rcu(mmo->obj);
-
- GEM_BUG_ON(obj && obj->ops->mmap_ops);
- } else {
- obj = i915_gem_object_get_rcu
- (container_of(node, struct drm_i915_gem_object,
- base.vma_node));
-
- GEM_BUG_ON(obj && !obj->ops->mmap_ops);
- }
- }
- drm_vma_offset_unlock_lookup(dev->vma_offset_manager);
- rcu_read_unlock();
- if (!obj)
- return node ? -EACCES : -EINVAL;
-
if (i915_gem_object_is_readonly(obj)) {
if (vma->vm_flags & VM_WRITE) {
i915_gem_object_put(obj);
@@ -1005,7 +976,7 @@ int i915_gem_mmap(struct file *filp, struct vm_area_struct *vma)
if (obj->ops->mmap_ops) {
vma->vm_page_prot = pgprot_decrypted(vm_get_page_prot(vma->vm_flags));
vma->vm_ops = obj->ops->mmap_ops;
- vma->vm_private_data = node->driver_private;
+ vma->vm_private_data = obj->base.vma_node.driver_private;
return 0;
}
@@ -1043,6 +1014,91 @@ int i915_gem_mmap(struct file *filp, struct vm_area_struct *vma)
return 0;
}
+/*
+ * This overcomes the limitation in drm_gem_mmap's assignment of a
+ * drm_gem_object as the vma->vm_private_data. Since we need to
+ * be able to resolve multiple mmap offsets which could be tied
+ * to a single gem object.
+ */
+int i915_gem_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+ struct drm_vma_offset_node *node;
+ struct drm_file *priv = filp->private_data;
+ struct drm_device *dev = priv->minor->dev;
+ struct drm_i915_gem_object *obj = NULL;
+ struct i915_mmap_offset *mmo = NULL;
+
+ if (drm_dev_is_unplugged(dev))
+ return -ENODEV;
+
+ rcu_read_lock();
+ drm_vma_offset_lock_lookup(dev->vma_offset_manager);
+ node = drm_vma_offset_exact_lookup_locked(dev->vma_offset_manager,
+ vma->vm_pgoff,
+ vma_pages(vma));
+ if (node && drm_vma_node_is_allowed(node, priv)) {
+ /*
+ * Skip 0-refcnted objects as it is in the process of being
+ * destroyed and will be invalid when the vma manager lock
+ * is released.
+ */
+ if (!node->driver_private) {
+ mmo = container_of(node, struct i915_mmap_offset, vma_node);
+ obj = i915_gem_object_get_rcu(mmo->obj);
+
+ GEM_BUG_ON(obj && obj->ops->mmap_ops);
+ } else {
+ obj = i915_gem_object_get_rcu
+ (container_of(node, struct drm_i915_gem_object,
+ base.vma_node));
+
+ GEM_BUG_ON(obj && !obj->ops->mmap_ops);
+ }
+ }
+ drm_vma_offset_unlock_lookup(dev->vma_offset_manager);
+ rcu_read_unlock();
+ if (!obj)
+ return node ? -EACCES : -EINVAL;
+
+ return i915_gem_object_mmap(obj, mmo, vma);
+}
+
+int i915_gem_fb_mmap(struct drm_i915_gem_object *obj, struct vm_area_struct *vma)
+{
+ struct drm_i915_private *i915 = to_i915(obj->base.dev);
+ struct drm_device *dev = &i915->drm;
+ struct i915_mmap_offset *mmo = NULL;
+ enum i915_mmap_type mmap_type;
+ struct i915_ggtt *ggtt = to_gt(i915)->ggtt;
+
+ if (drm_dev_is_unplugged(dev))
+ return -ENODEV;
+
+ /* handle ttm object */
+ if (obj->ops->mmap_ops) {
+ /*
+ * ttm fault handler, ttm_bo_vm_fault_reserved() uses fake offset
+ * to calculate page offset so set that up.
+ */
+ vma->vm_pgoff += drm_vma_node_start(&obj->base.vma_node);
+ } else {
+ /* handle stolen and smem objects */
+ mmap_type = i915_ggtt_has_aperture(ggtt) ? I915_MMAP_TYPE_GTT : I915_MMAP_TYPE_WC;
+ mmo = mmap_offset_attach(obj, mmap_type, NULL);
+ if (!mmo)
+ return -ENODEV;
+ }
+
+ /*
+ * When we install vm_ops for mmap we are too late for
+ * the vm_ops->open() which increases the ref_count of
+ * this obj and then it gets decreased by the vm_ops->close().
+ * To balance this increase the obj ref_count here.
+ */
+ obj = i915_gem_object_get(obj);
+ return i915_gem_object_mmap(obj, mmo, vma);
+}
+
#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
#include "selftests/i915_gem_mman.c"
#endif
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.h b/drivers/gpu/drm/i915/gem/i915_gem_mman.h
index 1fa91b3033b3..196417fd0f5c 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.h
@@ -29,5 +29,5 @@ void i915_gem_object_release_mmap_gtt(struct drm_i915_gem_object *obj);
void i915_gem_object_runtime_pm_release_mmap_offset(struct drm_i915_gem_object *obj);
void i915_gem_object_release_mmap_offset(struct drm_i915_gem_object *obj);
-
+int i915_gem_fb_mmap(struct drm_i915_gem_object *obj, struct vm_area_struct *vma);
#endif
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c
index 4666bb82f312..46a19b099ec8 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
@@ -45,6 +45,33 @@ static struct kmem_cache *slab_objects;
static const struct drm_gem_object_funcs i915_gem_object_funcs;
+unsigned int i915_gem_get_pat_index(struct drm_i915_private *i915,
+ enum i915_cache_level level)
+{
+ if (drm_WARN_ON(&i915->drm, level >= I915_MAX_CACHE_LEVEL))
+ return 0;
+
+ return INTEL_INFO(i915)->cachelevel_to_pat[level];
+}
+
+bool i915_gem_object_has_cache_level(const struct drm_i915_gem_object *obj,
+ enum i915_cache_level lvl)
+{
+ /*
+ * In case the pat_index is set by user space, this kernel mode
+ * driver should leave the coherency to be managed by user space,
+ * simply return true here.
+ */
+ if (obj->pat_set_by_user)
+ return true;
+
+ /*
+ * Otherwise the pat_index should have been converted from cache_level
+ * so that the following comparison is valid.
+ */
+ return obj->pat_index == i915_gem_get_pat_index(obj_to_i915(obj), lvl);
+}
+
struct drm_i915_gem_object *i915_gem_object_alloc(void)
{
struct drm_i915_gem_object *obj;
@@ -124,7 +151,7 @@ void i915_gem_object_set_cache_coherency(struct drm_i915_gem_object *obj,
{
struct drm_i915_private *i915 = to_i915(obj->base.dev);
- obj->cache_level = cache_level;
+ obj->pat_index = i915_gem_get_pat_index(i915, cache_level);
if (cache_level != I915_CACHE_NONE)
obj->cache_coherent = (I915_BO_CACHE_COHERENT_FOR_READ |
@@ -139,6 +166,37 @@ void i915_gem_object_set_cache_coherency(struct drm_i915_gem_object *obj,
!IS_DGFX(i915);
}
+/**
+ * i915_gem_object_set_pat_index - set PAT index to be used in PTE encode
+ * @obj: #drm_i915_gem_object
+ * @pat_index: PAT index
+ *
+ * This is a clone of i915_gem_object_set_cache_coherency taking pat index
+ * instead of cache_level as its second argument.
+ */
+void i915_gem_object_set_pat_index(struct drm_i915_gem_object *obj,
+ unsigned int pat_index)
+{
+ struct drm_i915_private *i915 = to_i915(obj->base.dev);
+
+ if (obj->pat_index == pat_index)
+ return;
+
+ obj->pat_index = pat_index;
+
+ if (pat_index != i915_gem_get_pat_index(i915, I915_CACHE_NONE))
+ obj->cache_coherent = (I915_BO_CACHE_COHERENT_FOR_READ |
+ I915_BO_CACHE_COHERENT_FOR_WRITE);
+ else if (HAS_LLC(i915))
+ obj->cache_coherent = I915_BO_CACHE_COHERENT_FOR_READ;
+ else
+ obj->cache_coherent = 0;
+
+ obj->cache_dirty =
+ !(obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_WRITE) &&
+ !IS_DGFX(i915);
+}
+
bool i915_gem_object_can_bypass_llc(struct drm_i915_gem_object *obj)
{
struct drm_i915_private *i915 = to_i915(obj->base.dev);
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h
index 885ccde9dc3c..884a17275b3a 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
@@ -20,6 +20,8 @@
enum intel_region_id;
+#define obj_to_i915(obj__) to_i915((obj__)->base.dev)
+
static inline bool i915_gem_object_size_2big(u64 size)
{
struct drm_i915_gem_object *obj;
@@ -30,6 +32,10 @@ static inline bool i915_gem_object_size_2big(u64 size)
return false;
}
+unsigned int i915_gem_get_pat_index(struct drm_i915_private *i915,
+ enum i915_cache_level level);
+bool i915_gem_object_has_cache_level(const struct drm_i915_gem_object *obj,
+ enum i915_cache_level lvl);
void i915_gem_init__objects(struct drm_i915_private *i915);
void i915_objects_module_exit(void);
@@ -80,7 +86,7 @@ __i915_gem_object_unset_pages(struct drm_i915_gem_object *obj);
/**
* i915_gem_object_lookup_rcu - look up a temporary GEM object from its handle
- * @filp: DRM file private date
+ * @file: DRM file private date
* @handle: userspace handle
*
* Returns:
@@ -760,6 +766,8 @@ bool i915_gem_object_has_unknown_state(struct drm_i915_gem_object *obj);
void i915_gem_object_set_cache_coherency(struct drm_i915_gem_object *obj,
unsigned int cache_level);
+void i915_gem_object_set_pat_index(struct drm_i915_gem_object *obj,
+ unsigned int pat_index);
bool i915_gem_object_can_bypass_llc(struct drm_i915_gem_object *obj);
void i915_gem_object_flush_if_display(struct drm_i915_gem_object *obj);
void i915_gem_object_flush_if_display_locked(struct drm_i915_gem_object *obj);
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
index 5dcbbef31d44..e72c57716bee 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
@@ -194,6 +194,13 @@ enum i915_cache_level {
* engine.
*/
I915_CACHE_WT,
+ /**
+ * @I915_MAX_CACHE_LEVEL:
+ *
+ * Mark the last entry in the enum. Used for defining cachelevel_to_pat
+ * array for cache_level to pat translation table.
+ */
+ I915_MAX_CACHE_LEVEL,
};
enum i915_map_type {
@@ -328,6 +335,12 @@ struct drm_i915_gem_object {
*/
#define I915_BO_ALLOC_GPU_ONLY BIT(6)
#define I915_BO_ALLOC_CCS_AUX BIT(7)
+/*
+ * Object is allowed to retain its initial data and will not be cleared on first
+ * access if used along with I915_BO_ALLOC_USER. This is mainly to keep
+ * preallocated framebuffer data intact while transitioning it to i915drmfb.
+ */
+#define I915_BO_PREALLOC BIT(8)
#define I915_BO_ALLOC_FLAGS (I915_BO_ALLOC_CONTIGUOUS | \
I915_BO_ALLOC_VOLATILE | \
I915_BO_ALLOC_CPU_CLEAR | \
@@ -335,10 +348,11 @@ struct drm_i915_gem_object {
I915_BO_ALLOC_PM_VOLATILE | \
I915_BO_ALLOC_PM_EARLY | \
I915_BO_ALLOC_GPU_ONLY | \
- I915_BO_ALLOC_CCS_AUX)
-#define I915_BO_READONLY BIT(8)
-#define I915_TILING_QUIRK_BIT 9 /* unknown swizzling; do not release! */
-#define I915_BO_PROTECTED BIT(10)
+ I915_BO_ALLOC_CCS_AUX | \
+ I915_BO_PREALLOC)
+#define I915_BO_READONLY BIT(9)
+#define I915_TILING_QUIRK_BIT 10 /* unknown swizzling; do not release! */
+#define I915_BO_PROTECTED BIT(11)
/**
* @mem_flags - Mutable placement-related flags
*
@@ -350,15 +364,43 @@ struct drm_i915_gem_object {
#define I915_BO_FLAG_STRUCT_PAGE BIT(0) /* Object backed by struct pages */
#define I915_BO_FLAG_IOMEM BIT(1) /* Object backed by IO memory */
/**
- * @cache_level: The desired GTT caching level.
+ * @pat_index: The desired PAT index.
+ *
+ * See hardware specification for valid PAT indices for each platform.
+ * This field replaces the @cache_level that contains a value of enum
+ * i915_cache_level since PAT indices are being used by both userspace
+ * and kernel mode driver for caching policy control after GEN12.
+ * In the meantime platform specific tables are created to translate
+ * i915_cache_level into pat index, for more details check the macros
+ * defined i915/i915_pci.c, e.g. PVC_CACHELEVEL.
+ * For backward compatibility, this field contains values exactly match
+ * the entries of enum i915_cache_level for pre-GEN12 platforms (See
+ * LEGACY_CACHELEVEL), so that the PTE encode functions for these
+ * legacy platforms can stay the same.
+ */
+ unsigned int pat_index:6;
+ /**
+ * @pat_set_by_user: Indicate whether pat_index is set by user space
*
- * See enum i915_cache_level for possible values, along with what
- * each does.
+ * This field is set to false by default, only set to true if the
+ * pat_index is set by user space. By design, user space is capable of
+ * managing caching behavior by setting pat_index, in which case this
+ * kernel mode driver should never touch the pat_index.
*/
- unsigned int cache_level:3;
+ unsigned int pat_set_by_user:1;
/**
* @cache_coherent:
*
+ * Note: with the change above which replaced @cache_level with pat_index,
+ * the use of @cache_coherent is limited to the objects created by kernel
+ * or by userspace without pat index specified.
+ * Check for @pat_set_by_user to find out if an object has pat index set
+ * by userspace. The ioctl's to change cache settings have also been
+ * disabled for the objects with pat index set by userspace. Please don't
+ * assume @cache_coherent having the flags set as describe here. A helper
+ * function i915_gem_object_has_cache_level() provides one way to bypass
+ * the use of this field.
+ *
* Track whether the pages are coherent with the GPU if reading or
* writing through the CPU caches. The largely depends on the
* @cache_level setting.
@@ -432,6 +474,16 @@ struct drm_i915_gem_object {
/**
* @cache_dirty:
*
+ * Note: with the change above which replaced cache_level with pat_index,
+ * the use of @cache_dirty is limited to the objects created by kernel
+ * or by userspace without pat index specified.
+ * Check for @pat_set_by_user to find out if an object has pat index set
+ * by userspace. The ioctl's to change cache settings have also been
+ * disabled for the objects with pat_index set by userspace. Please don't
+ * assume @cache_dirty is set as describe here. Also see helper function
+ * i915_gem_object_has_cache_level() for possible ways to bypass the use
+ * of this field.
+ *
* Track if we are we dirty with writes through the CPU cache for this
* object. As a result reading directly from main memory might yield
* stale data.
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
index ecd86130b74f..89fc8ea6bcfc 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
@@ -469,7 +469,10 @@ enum i915_map_type i915_coherent_map_type(struct drm_i915_private *i915,
struct drm_i915_gem_object *obj,
bool always_coherent)
{
- if (i915_gem_object_is_lmem(obj))
+ /*
+ * Wa_22016122933: always return I915_MAP_WC for MTL
+ */
+ if (i915_gem_object_is_lmem(obj) || IS_METEORLAKE(i915))
return I915_MAP_WC;
if (HAS_LLC(i915) || always_coherent)
return I915_MAP_WB;
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_region.h b/drivers/gpu/drm/i915/gem/i915_gem_region.h
index 2dfcc41c0170..8a7650b27cc2 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_region.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_region.h
@@ -22,9 +22,7 @@ struct i915_gem_apply_to_region;
*/
struct i915_gem_apply_to_region_ops {
/**
- * process_obj - Process the current object
- * @apply: Embed this for private data.
- * @obj: The current object.
+ * @process_obj: Process the current object
*
* Note that if this function is part of a ww transaction, and
* if returns -EDEADLK for one of the objects, it may be
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
index 37d1efcd3ca6..cad4a6017f4b 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
@@ -601,7 +601,14 @@ static int shmem_object_init(struct intel_memory_region *mem,
obj->write_domain = I915_GEM_DOMAIN_CPU;
obj->read_domains = I915_GEM_DOMAIN_CPU;
- if (HAS_LLC(i915))
+ /*
+ * MTL doesn't snoop CPU cache by default for GPU access (namely
+ * 1-way coherency). However some UMD's are currently depending on
+ * that. Make 1-way coherent the default setting for MTL. A follow
+ * up patch will extend the GEM_CREATE uAPI to allow UMD's specify
+ * caching mode at BO creation time
+ */
+ if (HAS_LLC(i915) || (GRAPHICS_VER_FULL(i915) >= IP_VER(12, 70)))
/* On some devices, we can have the GPU use the LLC (the CPU
* cache) for about a 10% performance improvement
* compared to uncached. Graphics requests other than
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
index b1672e054b21..214763942aa2 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
@@ -460,8 +460,6 @@ void i915_gem_shrinker_taints_mutex(struct drm_i915_private *i915,
fs_reclaim_release(GFP_KERNEL);
}
-#define obj_to_i915(obj__) to_i915((obj__)->base.dev)
-
/**
* i915_gem_object_make_unshrinkable - Hide the object from the shrinker. By
* default all object types that support shrinking(see IS_SHRINKABLE), will also
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
index 8ac376c24aa2..3b094d36a0b0 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
@@ -535,6 +535,14 @@ static int i915_gem_init_stolen(struct intel_memory_region *mem)
/* Basic memrange allocator for stolen space. */
drm_mm_init(&i915->mm.stolen, 0, i915->dsm.usable_size);
+ /*
+ * Access to stolen lmem beyond certain size for MTL A0 stepping
+ * would crash the machine. Disable stolen lmem for userspace access
+ * by setting usable_size to zero.
+ */
+ if (IS_METEORLAKE(i915) && INTEL_REVID(i915) == 0x0)
+ i915->dsm.usable_size = 0;
+
return 0;
}
@@ -557,7 +565,9 @@ static void dbg_poison(struct i915_ggtt *ggtt,
ggtt->vm.insert_page(&ggtt->vm, addr,
ggtt->error_capture.start,
- I915_CACHE_NONE, 0);
+ i915_gem_get_pat_index(ggtt->vm.i915,
+ I915_CACHE_NONE),
+ 0);
mb();
s = io_mapping_map_wc(&ggtt->iomap,
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.h b/drivers/gpu/drm/i915/gem/i915_gem_ttm.h
index f8f6bed1b297..67347e62e29b 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.h
@@ -42,8 +42,9 @@ static inline bool i915_ttm_is_ghost_object(struct ttm_buffer_object *bo)
/**
* i915_ttm_to_gem - Convert a struct ttm_buffer_object to an embedding
* struct drm_i915_gem_object.
+ * @bo: Pointer to the ttm buffer object
*
- * Return: Pointer to the embedding struct ttm_buffer_object.
+ * Return: Pointer to the embedding struct drm_i915_gem_object.
*/
static inline struct drm_i915_gem_object *
i915_ttm_to_gem(struct ttm_buffer_object *bo)
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c
index dd188dfcc423..7078af2f8f79 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c
@@ -214,7 +214,8 @@ static struct dma_fence *i915_ttm_accel_move(struct ttm_buffer_object *bo,
intel_engine_pm_get(to_gt(i915)->migrate.context->engine);
ret = intel_context_migrate_clear(to_gt(i915)->migrate.context, deps,
- dst_st->sgl, dst_level,
+ dst_st->sgl,
+ i915_gem_get_pat_index(i915, dst_level),
i915_ttm_gtt_binds_lmem(dst_mem),
0, &rq);
} else {
@@ -228,9 +229,10 @@ static struct dma_fence *i915_ttm_accel_move(struct ttm_buffer_object *bo,
intel_engine_pm_get(to_gt(i915)->migrate.context->engine);
ret = intel_context_migrate_copy(to_gt(i915)->migrate.context,
deps, src_rsgt->table.sgl,
- src_level,
+ i915_gem_get_pat_index(i915, src_level),
i915_ttm_gtt_binds_lmem(bo->resource),
- dst_st->sgl, dst_level,
+ dst_st->sgl,
+ i915_gem_get_pat_index(i915, dst_level),
i915_ttm_gtt_binds_lmem(dst_mem),
&rq);
@@ -576,7 +578,7 @@ int i915_ttm_move(struct ttm_buffer_object *bo, bool evict,
struct dma_fence *migration_fence = NULL;
struct ttm_tt *ttm = bo->ttm;
struct i915_refct_sgt *dst_rsgt;
- bool clear;
+ bool clear, prealloc_bo;
int ret;
if (GEM_WARN_ON(i915_ttm_is_ghost_object(bo))) {
@@ -632,7 +634,8 @@ int i915_ttm_move(struct ttm_buffer_object *bo, bool evict,
return PTR_ERR(dst_rsgt);
clear = !i915_ttm_cpu_maps_iomem(bo->resource) && (!ttm || !ttm_tt_is_populated(ttm));
- if (!(clear && ttm && !(ttm->page_flags & TTM_TT_FLAG_ZERO_ALLOC))) {
+ prealloc_bo = obj->flags & I915_BO_PREALLOC;
+ if (!(clear && ttm && !((ttm->page_flags & TTM_TT_FLAG_ZERO_ALLOC) && !prealloc_bo))) {
struct i915_deps deps;
i915_deps_init(&deps, GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN);
diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
index 99f39a5feca1..df6c9a84252c 100644
--- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
+++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
@@ -354,7 +354,7 @@ fake_huge_pages_object(struct drm_i915_private *i915, u64 size, bool single)
obj->write_domain = I915_GEM_DOMAIN_CPU;
obj->read_domains = I915_GEM_DOMAIN_CPU;
- obj->cache_level = I915_CACHE_NONE;
+ obj->pat_index = i915_gem_get_pat_index(i915, I915_CACHE_NONE);
return obj;
}
@@ -695,8 +695,7 @@ out_put:
return err;
}
-static void close_object_list(struct list_head *objects,
- struct i915_ppgtt *ppgtt)
+static void close_object_list(struct list_head *objects)
{
struct drm_i915_gem_object *obj, *on;
@@ -710,17 +709,36 @@ static void close_object_list(struct list_head *objects,
}
}
-static int igt_mock_ppgtt_huge_fill(void *arg)
+static int igt_ppgtt_huge_fill(void *arg)
{
- struct i915_ppgtt *ppgtt = arg;
- struct drm_i915_private *i915 = ppgtt->vm.i915;
- unsigned long max_pages = ppgtt->vm.total >> PAGE_SHIFT;
+ struct drm_i915_private *i915 = arg;
+ unsigned int supported = RUNTIME_INFO(i915)->page_sizes;
+ bool has_pte64 = GRAPHICS_VER_FULL(i915) >= IP_VER(12, 50);
+ struct i915_address_space *vm;
+ struct i915_gem_context *ctx;
+ unsigned long max_pages;
unsigned long page_num;
+ struct file *file;
bool single = false;
LIST_HEAD(objects);
IGT_TIMEOUT(end_time);
int err = -ENODEV;
+ if (supported == I915_GTT_PAGE_SIZE_4K)
+ return 0;
+
+ file = mock_file(i915);
+ if (IS_ERR(file))
+ return PTR_ERR(file);
+
+ ctx = hugepage_ctx(i915, file);
+ if (IS_ERR(ctx)) {
+ err = PTR_ERR(ctx);
+ goto out;
+ }
+ vm = i915_gem_context_get_eb_vm(ctx);
+ max_pages = vm->total >> PAGE_SHIFT;
+
for_each_prime_number_from(page_num, 1, max_pages) {
struct drm_i915_gem_object *obj;
u64 size = page_num << PAGE_SHIFT;
@@ -750,13 +768,14 @@ static int igt_mock_ppgtt_huge_fill(void *arg)
list_add(&obj->st_link, &objects);
- vma = i915_vma_instance(obj, &ppgtt->vm, NULL);
+ vma = i915_vma_instance(obj, vm, NULL);
if (IS_ERR(vma)) {
err = PTR_ERR(vma);
break;
}
- err = i915_vma_pin(vma, 0, 0, PIN_USER);
+ /* vma start must be aligned to BIT(21) to allow 2M PTEs */
+ err = i915_vma_pin(vma, 0, BIT(21), PIN_USER);
if (err)
break;
@@ -784,12 +803,13 @@ static int igt_mock_ppgtt_huge_fill(void *arg)
GEM_BUG_ON(!expected_gtt);
GEM_BUG_ON(size);
- if (expected_gtt & I915_GTT_PAGE_SIZE_4K)
+ if (!has_pte64 && (obj->base.size < I915_GTT_PAGE_SIZE_2M ||
+ expected_gtt & I915_GTT_PAGE_SIZE_2M))
expected_gtt &= ~I915_GTT_PAGE_SIZE_64K;
i915_vma_unpin(vma);
- if (vma->page_sizes.sg & I915_GTT_PAGE_SIZE_64K) {
+ if (!has_pte64 && vma->page_sizes.sg & I915_GTT_PAGE_SIZE_64K) {
if (!IS_ALIGNED(vma->node.start,
I915_GTT_PAGE_SIZE_2M)) {
pr_err("node.start(%llx) not aligned to 2M\n",
@@ -808,7 +828,7 @@ static int igt_mock_ppgtt_huge_fill(void *arg)
}
if (vma->resource->page_sizes_gtt != expected_gtt) {
- pr_err("gtt=%u, expected=%u, size=%zd, single=%s\n",
+ pr_err("gtt=%#x, expected=%#x, size=0x%zx, single=%s\n",
vma->resource->page_sizes_gtt, expected_gtt,
obj->base.size, str_yes_no(!!single));
err = -EINVAL;
@@ -823,19 +843,25 @@ static int igt_mock_ppgtt_huge_fill(void *arg)
single = !single;
}
- close_object_list(&objects, ppgtt);
+ close_object_list(&objects);
if (err == -ENOMEM || err == -ENOSPC)
err = 0;
+ i915_vm_put(vm);
+out:
+ fput(file);
return err;
}
-static int igt_mock_ppgtt_64K(void *arg)
+static int igt_ppgtt_64K(void *arg)
{
- struct i915_ppgtt *ppgtt = arg;
- struct drm_i915_private *i915 = ppgtt->vm.i915;
+ struct drm_i915_private *i915 = arg;
+ bool has_pte64 = GRAPHICS_VER_FULL(i915) >= IP_VER(12, 50);
struct drm_i915_gem_object *obj;
+ struct i915_address_space *vm;
+ struct i915_gem_context *ctx;
+ struct file *file;
const struct object_info {
unsigned int size;
unsigned int gtt;
@@ -907,16 +933,41 @@ static int igt_mock_ppgtt_64K(void *arg)
if (!HAS_PAGE_SIZES(i915, I915_GTT_PAGE_SIZE_64K))
return 0;
+ file = mock_file(i915);
+ if (IS_ERR(file))
+ return PTR_ERR(file);
+
+ ctx = hugepage_ctx(i915, file);
+ if (IS_ERR(ctx)) {
+ err = PTR_ERR(ctx);
+ goto out;
+ }
+ vm = i915_gem_context_get_eb_vm(ctx);
+
for (i = 0; i < ARRAY_SIZE(objects); ++i) {
unsigned int size = objects[i].size;
unsigned int expected_gtt = objects[i].gtt;
unsigned int offset = objects[i].offset;
unsigned int flags = PIN_USER;
+ /*
+ * For modern GTT models, the requirements for marking a page-table
+ * as 64K have been relaxed. Account for this.
+ */
+ if (has_pte64) {
+ expected_gtt = 0;
+ if (size >= SZ_64K)
+ expected_gtt |= I915_GTT_PAGE_SIZE_64K;
+ if (size & (SZ_64K - 1))
+ expected_gtt |= I915_GTT_PAGE_SIZE_4K;
+ }
+
for (single = 0; single <= 1; single++) {
obj = fake_huge_pages_object(i915, size, !!single);
- if (IS_ERR(obj))
- return PTR_ERR(obj);
+ if (IS_ERR(obj)) {
+ err = PTR_ERR(obj);
+ goto out_vm;
+ }
err = i915_gem_object_pin_pages_unlocked(obj);
if (err)
@@ -928,7 +979,7 @@ static int igt_mock_ppgtt_64K(void *arg)
*/
obj->mm.page_sizes.sg &= ~I915_GTT_PAGE_SIZE_2M;
- vma = i915_vma_instance(obj, &ppgtt->vm, NULL);
+ vma = i915_vma_instance(obj, vm, NULL);
if (IS_ERR(vma)) {
err = PTR_ERR(vma);
goto out_object_unpin;
@@ -945,7 +996,8 @@ static int igt_mock_ppgtt_64K(void *arg)
if (err)
goto out_vma_unpin;
- if (!offset && vma->page_sizes.sg & I915_GTT_PAGE_SIZE_64K) {
+ if (!has_pte64 && !offset &&
+ vma->page_sizes.sg & I915_GTT_PAGE_SIZE_64K) {
if (!IS_ALIGNED(vma->node.start,
I915_GTT_PAGE_SIZE_2M)) {
pr_err("node.start(%llx) not aligned to 2M\n",
@@ -964,9 +1016,10 @@ static int igt_mock_ppgtt_64K(void *arg)
}
if (vma->resource->page_sizes_gtt != expected_gtt) {
- pr_err("gtt=%u, expected=%u, i=%d, single=%s\n",
+ pr_err("gtt=%#x, expected=%#x, i=%d, single=%s offset=%#x size=%#x\n",
vma->resource->page_sizes_gtt,
- expected_gtt, i, str_yes_no(!!single));
+ expected_gtt, i, str_yes_no(!!single),
+ offset, size);
err = -EINVAL;
goto out_vma_unpin;
}
@@ -982,7 +1035,7 @@ static int igt_mock_ppgtt_64K(void *arg)
}
}
- return 0;
+ goto out_vm;
out_vma_unpin:
i915_vma_unpin(vma);
@@ -992,7 +1045,10 @@ out_object_unpin:
i915_gem_object_unlock(obj);
out_object_put:
i915_gem_object_put(obj);
-
+out_vm:
+ i915_vm_put(vm);
+out:
+ fput(file);
return err;
}
@@ -1910,8 +1966,6 @@ int i915_gem_huge_page_mock_selftests(void)
SUBTEST(igt_mock_exhaust_device_supported_pages),
SUBTEST(igt_mock_memory_region_huge_pages),
SUBTEST(igt_mock_ppgtt_misaligned_dma),
- SUBTEST(igt_mock_ppgtt_huge_fill),
- SUBTEST(igt_mock_ppgtt_64K),
};
struct drm_i915_private *dev_priv;
struct i915_ppgtt *ppgtt;
@@ -1962,6 +2016,8 @@ int i915_gem_huge_page_live_selftests(struct drm_i915_private *i915)
SUBTEST(igt_ppgtt_sanity_check),
SUBTEST(igt_ppgtt_compact),
SUBTEST(igt_ppgtt_mixed),
+ SUBTEST(igt_ppgtt_huge_fill),
+ SUBTEST(igt_ppgtt_64K),
};
if (!HAS_PPGTT(i915)) {
diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c
index a81fa6a20f5a..ad6a3b2fb387 100644
--- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c
@@ -66,7 +66,7 @@ static int live_nop_switch(void *arg)
ctx[n] = live_context(i915, file);
if (IS_ERR(ctx[n])) {
err = PTR_ERR(ctx[n]);
- goto out_file;
+ goto out_ctx;
}
}
@@ -82,7 +82,7 @@ static int live_nop_switch(void *arg)
this = igt_request_alloc(ctx[n], engine);
if (IS_ERR(this)) {
err = PTR_ERR(this);
- goto out_file;
+ goto out_ctx;
}
if (rq) {
i915_request_await_dma_fence(this, &rq->fence);
@@ -93,10 +93,10 @@ static int live_nop_switch(void *arg)
}
if (i915_request_wait(rq, 0, 10 * HZ) < 0) {
pr_err("Failed to populated %d contexts\n", nctx);
- intel_gt_set_wedged(to_gt(i915));
+ intel_gt_set_wedged(engine->gt);
i915_request_put(rq);
err = -EIO;
- goto out_file;
+ goto out_ctx;
}
i915_request_put(rq);
@@ -107,7 +107,7 @@ static int live_nop_switch(void *arg)
err = igt_live_test_begin(&t, i915, __func__, engine->name);
if (err)
- goto out_file;
+ goto out_ctx;
end_time = jiffies + i915_selftest.timeout_jiffies;
for_each_prime_number_from(prime, 2, 8192) {
@@ -120,7 +120,7 @@ static int live_nop_switch(void *arg)
this = igt_request_alloc(ctx[n % nctx], engine);
if (IS_ERR(this)) {
err = PTR_ERR(this);
- goto out_file;
+ goto out_ctx;
}
if (rq) { /* Force submission order */
@@ -149,7 +149,7 @@ static int live_nop_switch(void *arg)
if (i915_request_wait(rq, 0, HZ / 5) < 0) {
pr_err("Switching between %ld contexts timed out\n",
prime);
- intel_gt_set_wedged(to_gt(i915));
+ intel_gt_set_wedged(engine->gt);
i915_request_put(rq);
break;
}
@@ -165,7 +165,7 @@ static int live_nop_switch(void *arg)
err = igt_live_test_end(&t);
if (err)
- goto out_file;
+ goto out_ctx;
pr_info("Switch latencies on %s: 1 = %lluns, %lu = %lluns\n",
engine->name,
@@ -173,6 +173,8 @@ static int live_nop_switch(void *arg)
prime - 1, div64_u64(ktime_to_ns(times[1]), prime - 1));
}
+out_ctx:
+ kfree(ctx);
out_file:
fput(file);
return err;
diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_migrate.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_migrate.c
index fe6c37fd7859..a93a90b15907 100644
--- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_migrate.c
+++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_migrate.c
@@ -219,7 +219,7 @@ static int __igt_lmem_pages_migrate(struct intel_gt *gt,
continue;
err = intel_migrate_clear(&gt->migrate, &ww, deps,
- obj->mm.pages->sgl, obj->cache_level,
+ obj->mm.pages->sgl, obj->pat_index,
i915_gem_object_is_lmem(obj),
0xdeadbeaf, &rq);
if (rq) {
diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
index 56279908ed30..a93d8f9f8bc1 100644
--- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
@@ -1222,7 +1222,7 @@ static int __igt_mmap_migrate(struct intel_memory_region **placements,
}
err = intel_context_migrate_clear(to_gt(i915)->migrate.context, NULL,
- obj->mm.pages->sgl, obj->cache_level,
+ obj->mm.pages->sgl, obj->pat_index,
i915_gem_object_is_lmem(obj),
expand32(POISON_INUSE), &rq);
i915_gem_object_unpin_pages(obj);
diff --git a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
index 5aaacc53fa4c..c2bdc133c89a 100644
--- a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
+++ b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
@@ -109,7 +109,7 @@ static void gen6_ppgtt_clear_range(struct i915_address_space *vm,
static void gen6_ppgtt_insert_entries(struct i915_address_space *vm,
struct i915_vma_resource *vma_res,
- enum i915_cache_level cache_level,
+ unsigned int pat_index,
u32 flags)
{
struct i915_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
@@ -117,7 +117,7 @@ static void gen6_ppgtt_insert_entries(struct i915_address_space *vm,
unsigned int first_entry = vma_res->start / I915_GTT_PAGE_SIZE;
unsigned int act_pt = first_entry / GEN6_PTES;
unsigned int act_pte = first_entry % GEN6_PTES;
- const u32 pte_encode = vm->pte_encode(0, cache_level, flags);
+ const u32 pte_encode = vm->pte_encode(0, pat_index, flags);
struct sgt_dma iter = sgt_dma(vma_res);
gen6_pte_t *vaddr;
@@ -227,7 +227,9 @@ static int gen6_ppgtt_init_scratch(struct gen6_ppgtt *ppgtt)
vm->scratch[0]->encode =
vm->pte_encode(px_dma(vm->scratch[0]),
- I915_CACHE_NONE, PTE_READ_ONLY);
+ i915_gem_get_pat_index(vm->i915,
+ I915_CACHE_NONE),
+ PTE_READ_ONLY);
vm->scratch[1] = vm->alloc_pt_dma(vm, I915_GTT_PAGE_SIZE_4K);
if (IS_ERR(vm->scratch[1])) {
@@ -278,7 +280,7 @@ static void gen6_ppgtt_cleanup(struct i915_address_space *vm)
static void pd_vma_bind(struct i915_address_space *vm,
struct i915_vm_pt_stash *stash,
struct i915_vma_resource *vma_res,
- enum i915_cache_level cache_level,
+ unsigned int pat_index,
u32 unused)
{
struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm);
diff --git a/drivers/gpu/drm/i915/gt/gen8_ppgtt.c b/drivers/gpu/drm/i915/gt/gen8_ppgtt.c
index 4daaa6f55668..f948d33e5ec5 100644
--- a/drivers/gpu/drm/i915/gt/gen8_ppgtt.c
+++ b/drivers/gpu/drm/i915/gt/gen8_ppgtt.c
@@ -29,7 +29,7 @@ static u64 gen8_pde_encode(const dma_addr_t addr,
}
static u64 gen8_pte_encode(dma_addr_t addr,
- enum i915_cache_level level,
+ unsigned int pat_index,
u32 flags)
{
gen8_pte_t pte = addr | GEN8_PAGE_PRESENT | GEN8_PAGE_RW;
@@ -40,7 +40,12 @@ static u64 gen8_pte_encode(dma_addr_t addr,
if (flags & PTE_LM)
pte |= GEN12_PPGTT_PTE_LM;
- switch (level) {
+ /*
+ * For pre-gen12 platforms pat_index is the same as enum
+ * i915_cache_level, so the switch-case here is still valid.
+ * See translation table defined by LEGACY_CACHELEVEL.
+ */
+ switch (pat_index) {
case I915_CACHE_NONE:
pte |= PPAT_UNCACHED;
break;
@@ -55,6 +60,33 @@ static u64 gen8_pte_encode(dma_addr_t addr,
return pte;
}
+static u64 gen12_pte_encode(dma_addr_t addr,
+ unsigned int pat_index,
+ u32 flags)
+{
+ gen8_pte_t pte = addr | GEN8_PAGE_PRESENT | GEN8_PAGE_RW;
+
+ if (unlikely(flags & PTE_READ_ONLY))
+ pte &= ~GEN8_PAGE_RW;
+
+ if (flags & PTE_LM)
+ pte |= GEN12_PPGTT_PTE_LM;
+
+ if (pat_index & BIT(0))
+ pte |= GEN12_PPGTT_PTE_PAT0;
+
+ if (pat_index & BIT(1))
+ pte |= GEN12_PPGTT_PTE_PAT1;
+
+ if (pat_index & BIT(2))
+ pte |= GEN12_PPGTT_PTE_PAT2;
+
+ if (pat_index & BIT(3))
+ pte |= MTL_PPGTT_PTE_PAT3;
+
+ return pte;
+}
+
static void gen8_ppgtt_notify_vgt(struct i915_ppgtt *ppgtt, bool create)
{
struct drm_i915_private *i915 = ppgtt->vm.i915;
@@ -423,11 +455,11 @@ gen8_ppgtt_insert_pte(struct i915_ppgtt *ppgtt,
struct i915_page_directory *pdp,
struct sgt_dma *iter,
u64 idx,
- enum i915_cache_level cache_level,
+ unsigned int pat_index,
u32 flags)
{
struct i915_page_directory *pd;
- const gen8_pte_t pte_encode = gen8_pte_encode(0, cache_level, flags);
+ const gen8_pte_t pte_encode = ppgtt->vm.pte_encode(0, pat_index, flags);
gen8_pte_t *vaddr;
pd = i915_pd_entry(pdp, gen8_pd_index(idx, 2));
@@ -470,10 +502,10 @@ static void
xehpsdv_ppgtt_insert_huge(struct i915_address_space *vm,
struct i915_vma_resource *vma_res,
struct sgt_dma *iter,
- enum i915_cache_level cache_level,
+ unsigned int pat_index,
u32 flags)
{
- const gen8_pte_t pte_encode = vm->pte_encode(0, cache_level, flags);
+ const gen8_pte_t pte_encode = vm->pte_encode(0, pat_index, flags);
unsigned int rem = sg_dma_len(iter->sg);
u64 start = vma_res->start;
u64 end = start + vma_res->vma_size;
@@ -570,6 +602,7 @@ xehpsdv_ppgtt_insert_huge(struct i915_address_space *vm,
}
} while (rem >= page_size && index < max);
+ drm_clflush_virt_range(vaddr, PAGE_SIZE);
vma_res->page_sizes_gtt |= page_size;
} while (iter->sg && sg_dma_len(iter->sg));
}
@@ -577,10 +610,10 @@ xehpsdv_ppgtt_insert_huge(struct i915_address_space *vm,
static void gen8_ppgtt_insert_huge(struct i915_address_space *vm,
struct i915_vma_resource *vma_res,
struct sgt_dma *iter,
- enum i915_cache_level cache_level,
+ unsigned int pat_index,
u32 flags)
{
- const gen8_pte_t pte_encode = gen8_pte_encode(0, cache_level, flags);
+ const gen8_pte_t pte_encode = vm->pte_encode(0, pat_index, flags);
unsigned int rem = sg_dma_len(iter->sg);
u64 start = vma_res->start;
@@ -700,17 +733,17 @@ static void gen8_ppgtt_insert_huge(struct i915_address_space *vm,
static void gen8_ppgtt_insert(struct i915_address_space *vm,
struct i915_vma_resource *vma_res,
- enum i915_cache_level cache_level,
+ unsigned int pat_index,
u32 flags)
{
struct i915_ppgtt * const ppgtt = i915_vm_to_ppgtt(vm);
struct sgt_dma iter = sgt_dma(vma_res);
if (vma_res->bi.page_sizes.sg > I915_GTT_PAGE_SIZE) {
- if (HAS_64K_PAGES(vm->i915))
- xehpsdv_ppgtt_insert_huge(vm, vma_res, &iter, cache_level, flags);
+ if (GRAPHICS_VER_FULL(vm->i915) >= IP_VER(12, 50))
+ xehpsdv_ppgtt_insert_huge(vm, vma_res, &iter, pat_index, flags);
else
- gen8_ppgtt_insert_huge(vm, vma_res, &iter, cache_level, flags);
+ gen8_ppgtt_insert_huge(vm, vma_res, &iter, pat_index, flags);
} else {
u64 idx = vma_res->start >> GEN8_PTE_SHIFT;
@@ -719,7 +752,7 @@ static void gen8_ppgtt_insert(struct i915_address_space *vm,
gen8_pdp_for_page_index(vm, idx);
idx = gen8_ppgtt_insert_pte(ppgtt, pdp, &iter, idx,
- cache_level, flags);
+ pat_index, flags);
} while (idx);
vma_res->page_sizes_gtt = I915_GTT_PAGE_SIZE;
@@ -729,7 +762,7 @@ static void gen8_ppgtt_insert(struct i915_address_space *vm,
static void gen8_ppgtt_insert_entry(struct i915_address_space *vm,
dma_addr_t addr,
u64 offset,
- enum i915_cache_level level,
+ unsigned int pat_index,
u32 flags)
{
u64 idx = offset >> GEN8_PTE_SHIFT;
@@ -743,14 +776,14 @@ static void gen8_ppgtt_insert_entry(struct i915_address_space *vm,
GEM_BUG_ON(pt->is_compact);
vaddr = px_vaddr(pt);
- vaddr[gen8_pd_index(idx, 0)] = gen8_pte_encode(addr, level, flags);
+ vaddr[gen8_pd_index(idx, 0)] = vm->pte_encode(addr, pat_index, flags);
drm_clflush_virt_range(&vaddr[gen8_pd_index(idx, 0)], sizeof(*vaddr));
}
static void __xehpsdv_ppgtt_insert_entry_lm(struct i915_address_space *vm,
dma_addr_t addr,
u64 offset,
- enum i915_cache_level level,
+ unsigned int pat_index,
u32 flags)
{
u64 idx = offset >> GEN8_PTE_SHIFT;
@@ -773,20 +806,20 @@ static void __xehpsdv_ppgtt_insert_entry_lm(struct i915_address_space *vm,
}
vaddr = px_vaddr(pt);
- vaddr[gen8_pd_index(idx, 0) / 16] = gen8_pte_encode(addr, level, flags);
+ vaddr[gen8_pd_index(idx, 0) / 16] = vm->pte_encode(addr, pat_index, flags);
}
static void xehpsdv_ppgtt_insert_entry(struct i915_address_space *vm,
dma_addr_t addr,
u64 offset,
- enum i915_cache_level level,
+ unsigned int pat_index,
u32 flags)
{
if (flags & PTE_LM)
return __xehpsdv_ppgtt_insert_entry_lm(vm, addr, offset,
- level, flags);
+ pat_index, flags);
- return gen8_ppgtt_insert_entry(vm, addr, offset, level, flags);
+ return gen8_ppgtt_insert_entry(vm, addr, offset, pat_index, flags);
}
static int gen8_init_scratch(struct i915_address_space *vm)
@@ -820,8 +853,10 @@ static int gen8_init_scratch(struct i915_address_space *vm)
pte_flags |= PTE_LM;
vm->scratch[0]->encode =
- gen8_pte_encode(px_dma(vm->scratch[0]),
- I915_CACHE_NONE, pte_flags);
+ vm->pte_encode(px_dma(vm->scratch[0]),
+ i915_gem_get_pat_index(vm->i915,
+ I915_CACHE_NONE),
+ pte_flags);
for (i = 1; i <= vm->top; i++) {
struct drm_i915_gem_object *obj;
@@ -963,7 +998,10 @@ struct i915_ppgtt *gen8_ppgtt_create(struct intel_gt *gt,
*/
ppgtt->vm.alloc_scratch_dma = alloc_pt_dma;
- ppgtt->vm.pte_encode = gen8_pte_encode;
+ if (GRAPHICS_VER(gt->i915) >= 12)
+ ppgtt->vm.pte_encode = gen12_pte_encode;
+ else
+ ppgtt->vm.pte_encode = gen8_pte_encode;
ppgtt->vm.bind_async_flags = I915_VMA_LOCAL_BIND;
ppgtt->vm.insert_entries = gen8_ppgtt_insert;
diff --git a/drivers/gpu/drm/i915/gt/gen8_ppgtt.h b/drivers/gpu/drm/i915/gt/gen8_ppgtt.h
index f541d19264b4..19c635441642 100644
--- a/drivers/gpu/drm/i915/gt/gen8_ppgtt.h
+++ b/drivers/gpu/drm/i915/gt/gen8_ppgtt.h
@@ -10,13 +10,12 @@
struct i915_address_space;
struct intel_gt;
-enum i915_cache_level;
struct i915_ppgtt *gen8_ppgtt_create(struct intel_gt *gt,
unsigned long lmem_pt_obj_flags);
u64 gen8_ggtt_pte_encode(dma_addr_t addr,
- enum i915_cache_level level,
+ unsigned int pat_index,
u32 flags);
#endif
diff --git a/drivers/gpu/drm/i915/gt/intel_context.c b/drivers/gpu/drm/i915/gt/intel_context.c
index 2aa63ec521b8..a53b26178f0a 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -578,10 +578,13 @@ void intel_context_bind_parent_child(struct intel_context *parent,
child->parallel.parent = parent;
}
-u64 intel_context_get_total_runtime_ns(const struct intel_context *ce)
+u64 intel_context_get_total_runtime_ns(struct intel_context *ce)
{
u64 total, active;
+ if (ce->ops->update_stats)
+ ce->ops->update_stats(ce);
+
total = ce->stats.runtime.total;
if (ce->ops->flags & COPS_RUNTIME_CYCLES)
total *= ce->engine->gt->clock_period_ns;
diff --git a/drivers/gpu/drm/i915/gt/intel_context.h b/drivers/gpu/drm/i915/gt/intel_context.h
index 48f888c3da08..a80e3b7c24ff 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.h
+++ b/drivers/gpu/drm/i915/gt/intel_context.h
@@ -97,7 +97,7 @@ void intel_context_bind_parent_child(struct intel_context *parent,
/**
* intel_context_lock_pinned - Stablises the 'pinned' status of the HW context
- * @ce - the context
+ * @ce: the context
*
* Acquire a lock on the pinned status of the HW context, such that the context
* can neither be bound to the GPU or unbound whilst the lock is held, i.e.
@@ -111,7 +111,7 @@ static inline int intel_context_lock_pinned(struct intel_context *ce)
/**
* intel_context_is_pinned - Reports the 'pinned' status
- * @ce - the context
+ * @ce: the context
*
* While in use by the GPU, the context, along with its ring and page
* tables is pinned into memory and the GTT.
@@ -133,7 +133,7 @@ static inline void intel_context_cancel_request(struct intel_context *ce,
/**
* intel_context_unlock_pinned - Releases the earlier locking of 'pinned' status
- * @ce - the context
+ * @ce: the context
*
* Releases the lock earlier acquired by intel_context_unlock_pinned().
*/
@@ -375,7 +375,7 @@ intel_context_clear_nopreempt(struct intel_context *ce)
clear_bit(CONTEXT_NOPREEMPT, &ce->flags);
}
-u64 intel_context_get_total_runtime_ns(const struct intel_context *ce);
+u64 intel_context_get_total_runtime_ns(struct intel_context *ce);
u64 intel_context_get_avg_runtime_ns(struct intel_context *ce);
static inline u64 intel_context_clock(void)
diff --git a/drivers/gpu/drm/i915/gt/intel_context_types.h b/drivers/gpu/drm/i915/gt/intel_context_types.h
index e36670f2e626..aceaac28a33e 100644
--- a/drivers/gpu/drm/i915/gt/intel_context_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_context_types.h
@@ -58,6 +58,8 @@ struct intel_context_ops {
void (*sched_disable)(struct intel_context *ce);
+ void (*update_stats)(struct intel_context *ce);
+
void (*reset)(struct intel_context *ce);
void (*destroy)(struct kref *kref);
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
index 5c6c9a6d469c..0aff5bb13c53 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
@@ -1515,7 +1515,7 @@ int intel_engines_init(struct intel_gt *gt)
}
/**
- * intel_engines_cleanup_common - cleans up the engine state created by
+ * intel_engine_cleanup_common - cleans up the engine state created by
* the common initiailizers.
* @engine: Engine to cleanup.
*
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h b/drivers/gpu/drm/i915/gt/intel_engine_types.h
index 960291f88fd6..e99a6fa03d45 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h
@@ -289,6 +289,7 @@ struct intel_engine_execlists {
*/
u8 csb_head;
+ /* private: selftest */
I915_SELFTEST_DECLARE(struct st_preempt_hang preempt_hang;)
};
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_user.c b/drivers/gpu/drm/i915/gt/intel_engine_user.c
index cd4f1b126f75..dcedff41a825 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_user.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_user.c
@@ -117,7 +117,7 @@ static void set_scheduler_caps(struct drm_i915_private *i915)
disabled |= (I915_SCHEDULER_CAP_ENABLED |
I915_SCHEDULER_CAP_PRIORITY);
- if (intel_uc_uses_guc_submission(&to_gt(i915)->uc))
+ if (intel_uc_uses_guc_submission(&engine->gt->uc))
enabled |= I915_SCHEDULER_CAP_STATIC_PRIORITY_MAP;
for (i = 0; i < ARRAY_SIZE(map); i++) {
diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c
index 3c7f1ed92f5b..2a7942fac798 100644
--- a/drivers/gpu/drm/i915/gt/intel_ggtt.c
+++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c
@@ -220,8 +220,28 @@ static void guc_ggtt_invalidate(struct i915_ggtt *ggtt)
}
}
+static u64 mtl_ggtt_pte_encode(dma_addr_t addr,
+ unsigned int pat_index,
+ u32 flags)
+{
+ gen8_pte_t pte = addr | GEN8_PAGE_PRESENT;
+
+ WARN_ON_ONCE(addr & ~GEN12_GGTT_PTE_ADDR_MASK);
+
+ if (flags & PTE_LM)
+ pte |= GEN12_GGTT_PTE_LM;
+
+ if (pat_index & BIT(0))
+ pte |= MTL_GGTT_PTE_PAT0;
+
+ if (pat_index & BIT(1))
+ pte |= MTL_GGTT_PTE_PAT1;
+
+ return pte;
+}
+
u64 gen8_ggtt_pte_encode(dma_addr_t addr,
- enum i915_cache_level level,
+ unsigned int pat_index,
u32 flags)
{
gen8_pte_t pte = addr | GEN8_PAGE_PRESENT;
@@ -240,25 +260,25 @@ static void gen8_set_pte(void __iomem *addr, gen8_pte_t pte)
static void gen8_ggtt_insert_page(struct i915_address_space *vm,
dma_addr_t addr,
u64 offset,
- enum i915_cache_level level,
+ unsigned int pat_index,
u32 flags)
{
struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm);
gen8_pte_t __iomem *pte =
(gen8_pte_t __iomem *)ggtt->gsm + offset / I915_GTT_PAGE_SIZE;
- gen8_set_pte(pte, gen8_ggtt_pte_encode(addr, level, flags));
+ gen8_set_pte(pte, ggtt->vm.pte_encode(addr, pat_index, flags));
ggtt->invalidate(ggtt);
}
static void gen8_ggtt_insert_entries(struct i915_address_space *vm,
struct i915_vma_resource *vma_res,
- enum i915_cache_level level,
+ unsigned int pat_index,
u32 flags)
{
- const gen8_pte_t pte_encode = gen8_ggtt_pte_encode(0, level, flags);
struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm);
+ const gen8_pte_t pte_encode = ggtt->vm.pte_encode(0, pat_index, flags);
gen8_pte_t __iomem *gte;
gen8_pte_t __iomem *end;
struct sgt_iter iter;
@@ -315,14 +335,14 @@ static void gen8_ggtt_clear_range(struct i915_address_space *vm,
static void gen6_ggtt_insert_page(struct i915_address_space *vm,
dma_addr_t addr,
u64 offset,
- enum i915_cache_level level,
+ unsigned int pat_index,
u32 flags)
{
struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm);
gen6_pte_t __iomem *pte =
(gen6_pte_t __iomem *)ggtt->gsm + offset / I915_GTT_PAGE_SIZE;
- iowrite32(vm->pte_encode(addr, level, flags), pte);
+ iowrite32(vm->pte_encode(addr, pat_index, flags), pte);
ggtt->invalidate(ggtt);
}
@@ -335,7 +355,7 @@ static void gen6_ggtt_insert_page(struct i915_address_space *vm,
*/
static void gen6_ggtt_insert_entries(struct i915_address_space *vm,
struct i915_vma_resource *vma_res,
- enum i915_cache_level level,
+ unsigned int pat_index,
u32 flags)
{
struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm);
@@ -352,7 +372,7 @@ static void gen6_ggtt_insert_entries(struct i915_address_space *vm,
iowrite32(vm->scratch[0]->encode, gte++);
end += (vma_res->node_size + vma_res->guard) / I915_GTT_PAGE_SIZE;
for_each_sgt_daddr(addr, iter, vma_res->bi.pages)
- iowrite32(vm->pte_encode(addr, level, flags), gte++);
+ iowrite32(vm->pte_encode(addr, pat_index, flags), gte++);
GEM_BUG_ON(gte > end);
/* Fill the allocated but "unused" space beyond the end of the buffer */
@@ -387,14 +407,15 @@ struct insert_page {
struct i915_address_space *vm;
dma_addr_t addr;
u64 offset;
- enum i915_cache_level level;
+ unsigned int pat_index;
};
static int bxt_vtd_ggtt_insert_page__cb(void *_arg)
{
struct insert_page *arg = _arg;
- gen8_ggtt_insert_page(arg->vm, arg->addr, arg->offset, arg->level, 0);
+ gen8_ggtt_insert_page(arg->vm, arg->addr, arg->offset,
+ arg->pat_index, 0);
bxt_vtd_ggtt_wa(arg->vm);
return 0;
@@ -403,10 +424,10 @@ static int bxt_vtd_ggtt_insert_page__cb(void *_arg)
static void bxt_vtd_ggtt_insert_page__BKL(struct i915_address_space *vm,
dma_addr_t addr,
u64 offset,
- enum i915_cache_level level,
+ unsigned int pat_index,
u32 unused)
{
- struct insert_page arg = { vm, addr, offset, level };
+ struct insert_page arg = { vm, addr, offset, pat_index };
stop_machine(bxt_vtd_ggtt_insert_page__cb, &arg, NULL);
}
@@ -414,7 +435,7 @@ static void bxt_vtd_ggtt_insert_page__BKL(struct i915_address_space *vm,
struct insert_entries {
struct i915_address_space *vm;
struct i915_vma_resource *vma_res;
- enum i915_cache_level level;
+ unsigned int pat_index;
u32 flags;
};
@@ -422,7 +443,8 @@ static int bxt_vtd_ggtt_insert_entries__cb(void *_arg)
{
struct insert_entries *arg = _arg;
- gen8_ggtt_insert_entries(arg->vm, arg->vma_res, arg->level, arg->flags);
+ gen8_ggtt_insert_entries(arg->vm, arg->vma_res,
+ arg->pat_index, arg->flags);
bxt_vtd_ggtt_wa(arg->vm);
return 0;
@@ -430,10 +452,10 @@ static int bxt_vtd_ggtt_insert_entries__cb(void *_arg)
static void bxt_vtd_ggtt_insert_entries__BKL(struct i915_address_space *vm,
struct i915_vma_resource *vma_res,
- enum i915_cache_level level,
+ unsigned int pat_index,
u32 flags)
{
- struct insert_entries arg = { vm, vma_res, level, flags };
+ struct insert_entries arg = { vm, vma_res, pat_index, flags };
stop_machine(bxt_vtd_ggtt_insert_entries__cb, &arg, NULL);
}
@@ -462,7 +484,7 @@ static void gen6_ggtt_clear_range(struct i915_address_space *vm,
void intel_ggtt_bind_vma(struct i915_address_space *vm,
struct i915_vm_pt_stash *stash,
struct i915_vma_resource *vma_res,
- enum i915_cache_level cache_level,
+ unsigned int pat_index,
u32 flags)
{
u32 pte_flags;
@@ -479,7 +501,7 @@ void intel_ggtt_bind_vma(struct i915_address_space *vm,
if (vma_res->bi.lmem)
pte_flags |= PTE_LM;
- vm->insert_entries(vm, vma_res, cache_level, pte_flags);
+ vm->insert_entries(vm, vma_res, pat_index, pte_flags);
vma_res->page_sizes_gtt = I915_GTT_PAGE_SIZE;
}
@@ -628,7 +650,7 @@ err:
static void aliasing_gtt_bind_vma(struct i915_address_space *vm,
struct i915_vm_pt_stash *stash,
struct i915_vma_resource *vma_res,
- enum i915_cache_level cache_level,
+ unsigned int pat_index,
u32 flags)
{
u32 pte_flags;
@@ -640,10 +662,10 @@ static void aliasing_gtt_bind_vma(struct i915_address_space *vm,
if (flags & I915_VMA_LOCAL_BIND)
ppgtt_bind_vma(&i915_vm_to_ggtt(vm)->alias->vm,
- stash, vma_res, cache_level, flags);
+ stash, vma_res, pat_index, flags);
if (flags & I915_VMA_GLOBAL_BIND)
- vm->insert_entries(vm, vma_res, cache_level, pte_flags);
+ vm->insert_entries(vm, vma_res, pat_index, pte_flags);
vma_res->bound_flags |= flags;
}
@@ -900,7 +922,9 @@ static int ggtt_probe_common(struct i915_ggtt *ggtt, u64 size)
ggtt->vm.scratch[0]->encode =
ggtt->vm.pte_encode(px_dma(ggtt->vm.scratch[0]),
- I915_CACHE_NONE, pte_flags);
+ i915_gem_get_pat_index(i915,
+ I915_CACHE_NONE),
+ pte_flags);
return 0;
}
@@ -981,11 +1005,19 @@ static int gen8_gmch_probe(struct i915_ggtt *ggtt)
ggtt->vm.vma_ops.bind_vma = intel_ggtt_bind_vma;
ggtt->vm.vma_ops.unbind_vma = intel_ggtt_unbind_vma;
- ggtt->vm.pte_encode = gen8_ggtt_pte_encode;
+ if (GRAPHICS_VER_FULL(i915) >= IP_VER(12, 70))
+ ggtt->vm.pte_encode = mtl_ggtt_pte_encode;
+ else
+ ggtt->vm.pte_encode = gen8_ggtt_pte_encode;
return ggtt_probe_common(ggtt, size);
}
+/*
+ * For pre-gen8 platforms pat_index is the same as enum i915_cache_level,
+ * so these PTE encode functions are left with using cache_level.
+ * See translation table LEGACY_CACHELEVEL.
+ */
static u64 snb_pte_encode(dma_addr_t addr,
enum i915_cache_level level,
u32 flags)
@@ -1266,7 +1298,9 @@ bool i915_ggtt_resume_vm(struct i915_address_space *vm)
*/
vma->resource->bound_flags = 0;
vma->ops->bind_vma(vm, NULL, vma->resource,
- obj ? obj->cache_level : 0,
+ obj ? obj->pat_index :
+ i915_gem_get_pat_index(vm->i915,
+ I915_CACHE_NONE),
was_bound);
if (obj) { /* only used during resume => exclusive access */
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_irq.c b/drivers/gpu/drm/i915/gt/intel_gt_irq.c
index c0f3ff4746ad..8f888d36f16d 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_irq.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_irq.c
@@ -16,6 +16,7 @@
#include "intel_uncore.h"
#include "intel_rps.h"
#include "pxp/intel_pxp_irq.h"
+#include "uc/intel_gsc_proxy.h"
static void guc_irq_handler(struct intel_guc *guc, u16 iir)
{
@@ -82,6 +83,9 @@ gen11_other_irq_handler(struct intel_gt *gt, const u8 instance,
if (instance == OTHER_GSC_INSTANCE)
return intel_gsc_irq_handler(gt, iir);
+ if (instance == OTHER_GSC_HECI_2_INSTANCE)
+ return intel_gsc_proxy_irq_handler(&gt->uc.gsc, iir);
+
WARN_ONCE(1, "unhandled other interrupt instance=0x%x, iir=0x%x\n",
instance, iir);
}
@@ -101,7 +105,10 @@ static struct intel_gt *pick_gt(struct intel_gt *gt, u8 class, u8 instance)
case VIDEO_ENHANCEMENT_CLASS:
return media_gt;
case OTHER_CLASS:
- if (instance == OTHER_GSC_INSTANCE && HAS_ENGINE(media_gt, GSC0))
+ if (instance == OTHER_GSC_HECI_2_INSTANCE)
+ return media_gt;
+ if ((instance == OTHER_GSC_INSTANCE || instance == OTHER_KCR_INSTANCE) &&
+ HAS_ENGINE(media_gt, GSC0))
return media_gt;
fallthrough;
default:
@@ -257,6 +264,7 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt)
u32 irqs = GT_RENDER_USER_INTERRUPT;
u32 guc_mask = intel_uc_wants_guc(&gt->uc) ? GUC_INTR_GUC2HOST : 0;
u32 gsc_mask = 0;
+ u32 heci_mask = 0;
u32 dmask;
u32 smask;
@@ -268,10 +276,16 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt)
dmask = irqs << 16 | irqs;
smask = irqs << 16;
- if (HAS_ENGINE(gt, GSC0))
+ if (HAS_ENGINE(gt, GSC0)) {
+ /*
+ * the heci2 interrupt is enabled via the same register as the
+ * GSC interrupt, but it has its own mask register.
+ */
gsc_mask = irqs;
- else if (HAS_HECI_GSC(gt->i915))
+ heci_mask = GSC_IRQ_INTF(1); /* HECI2 IRQ for SW Proxy*/
+ } else if (HAS_HECI_GSC(gt->i915)) {
gsc_mask = GSC_IRQ_INTF(0) | GSC_IRQ_INTF(1);
+ }
BUILD_BUG_ON(irqs & 0xffff0000);
@@ -281,7 +295,7 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt)
if (CCS_MASK(gt))
intel_uncore_write(uncore, GEN12_CCS_RSVD_INTR_ENABLE, smask);
if (gsc_mask)
- intel_uncore_write(uncore, GEN11_GUNIT_CSME_INTR_ENABLE, gsc_mask);
+ intel_uncore_write(uncore, GEN11_GUNIT_CSME_INTR_ENABLE, gsc_mask | heci_mask);
/* Unmask irqs on RCS, BCS, VCS and VECS engines. */
intel_uncore_write(uncore, GEN11_RCS0_RSVD_INTR_MASK, ~smask);
@@ -309,6 +323,9 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt)
intel_uncore_write(uncore, GEN12_CCS2_CCS3_INTR_MASK, ~dmask);
if (gsc_mask)
intel_uncore_write(uncore, GEN11_GUNIT_CSME_INTR_MASK, ~gsc_mask);
+ if (heci_mask)
+ intel_uncore_write(uncore, GEN12_HECI2_RSVD_INTR_MASK,
+ ~REG_FIELD_PREP(ENGINE1_MASK, heci_mask));
if (guc_mask) {
/* the enable bit is common for both GTs but the masks are separate */
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm.c b/drivers/gpu/drm/i915/gt/intel_gt_pm.c
index e02cb90723ae..c2e69bafd02b 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_pm.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_pm.c
@@ -87,7 +87,7 @@ static int __gt_unpark(struct intel_wakeref *wf)
intel_rc6_unpark(&gt->rc6);
intel_rps_unpark(&gt->rps);
- i915_pmu_gt_unparked(i915);
+ i915_pmu_gt_unparked(gt);
intel_guc_busyness_unpark(gt);
intel_gt_unpark_requests(gt);
@@ -109,7 +109,7 @@ static int __gt_park(struct intel_wakeref *wf)
intel_guc_busyness_park(gt);
i915_vma_parked(gt);
- i915_pmu_gt_parked(i915);
+ i915_pmu_gt_parked(gt);
intel_rps_park(&gt->rps);
intel_rc6_park(&gt->rc6);
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm_debugfs.c b/drivers/gpu/drm/i915/gt/intel_gt_pm_debugfs.c
index 80dbbef86b1d..357e2f865727 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_pm_debugfs.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_pm_debugfs.c
@@ -539,7 +539,10 @@ static bool rps_eval(void *data)
{
struct intel_gt *gt = data;
- return HAS_RPS(gt->i915);
+ if (intel_guc_slpc_is_used(&gt->uc.guc))
+ return false;
+ else
+ return HAS_RPS(gt->i915);
}
DEFINE_INTEL_GT_DEBUGFS_ATTRIBUTE(rps_boost);
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_regs.h b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
index c122eab33738..718cb2c80f79 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
@@ -357,7 +357,11 @@
#define GEN7_TLB_RD_ADDR _MMIO(0x4700)
#define GEN12_PAT_INDEX(index) _MMIO(0x4800 + (index) * 4)
-#define XEHP_PAT_INDEX(index) MCR_REG(0x4800 + (index) * 4)
+#define _PAT_INDEX(index) _PICK_EVEN_2RANGES(index, 8, \
+ 0x4800, 0x4804, \
+ 0x4848, 0x484c)
+#define XEHP_PAT_INDEX(index) MCR_REG(_PAT_INDEX(index))
+#define XELPMP_PAT_INDEX(index) _MMIO(_PAT_INDEX(index))
#define XEHP_TILE0_ADDR_RANGE MCR_REG(0x4900)
#define XEHP_TILE_LMEM_RANGE_SHIFT 8
@@ -526,6 +530,11 @@
#define GEN8_RC6_CTX_INFO _MMIO(0x8504)
+#define GEN12_SQCNT1 _MMIO(0x8718)
+#define GEN12_SQCNT1_PMON_ENABLE REG_BIT(30)
+#define GEN12_SQCNT1_OABPC REG_BIT(29)
+#define GEN12_STRICT_RAR_ENABLE REG_BIT(23)
+
#define XEHP_SQCM MCR_REG(0x8724)
#define EN_32B_ACCESS REG_BIT(30)
@@ -1588,6 +1597,7 @@
#define GEN11_GT_INTR_DW(x) _MMIO(0x190018 + ((x) * 4))
#define GEN11_CSME (31)
+#define GEN12_HECI_2 (30)
#define GEN11_GUNIT (28)
#define GEN11_GUC (25)
#define MTL_MGUC (24)
@@ -1629,6 +1639,7 @@
/* irq instances for OTHER_CLASS */
#define OTHER_GUC_INSTANCE 0
#define OTHER_GTPM_INSTANCE 1
+#define OTHER_GSC_HECI_2_INSTANCE 3
#define OTHER_KCR_INSTANCE 4
#define OTHER_GSC_INSTANCE 6
#define OTHER_MEDIA_GUC_INSTANCE 16
@@ -1644,6 +1655,7 @@
#define GEN12_VCS6_VCS7_INTR_MASK _MMIO(0x1900b4)
#define GEN11_VECS0_VECS1_INTR_MASK _MMIO(0x1900d0)
#define GEN12_VECS2_VECS3_INTR_MASK _MMIO(0x1900d4)
+#define GEN12_HECI2_RSVD_INTR_MASK _MMIO(0x1900e4)
#define GEN11_GUC_SG_INTR_MASK _MMIO(0x1900e8)
#define MTL_GUC_MGUC_INTR_MASK _MMIO(0x1900e8) /* MTL+ */
#define GEN11_GPM_WGBOXPERF_INTR_MASK _MMIO(0x1900ec)
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c b/drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c
index 28f27091cd3b..ee2b44f896a2 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c
@@ -451,6 +451,33 @@ static ssize_t punit_req_freq_mhz_show(struct kobject *kobj,
return sysfs_emit(buff, "%u\n", preq);
}
+static ssize_t slpc_ignore_eff_freq_show(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ char *buff)
+{
+ struct intel_gt *gt = intel_gt_sysfs_get_drvdata(kobj, attr->attr.name);
+ struct intel_guc_slpc *slpc = &gt->uc.guc.slpc;
+
+ return sysfs_emit(buff, "%u\n", slpc->ignore_eff_freq);
+}
+
+static ssize_t slpc_ignore_eff_freq_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buff, size_t count)
+{
+ struct intel_gt *gt = intel_gt_sysfs_get_drvdata(kobj, attr->attr.name);
+ struct intel_guc_slpc *slpc = &gt->uc.guc.slpc;
+ int err;
+ u32 val;
+
+ err = kstrtou32(buff, 0, &val);
+ if (err)
+ return err;
+
+ err = intel_guc_slpc_set_ignore_eff_freq(slpc, val);
+ return err ?: count;
+}
+
struct intel_gt_bool_throttle_attr {
struct attribute attr;
ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *attr,
@@ -663,6 +690,8 @@ static struct kobj_attribute attr_media_freq_factor_scale =
INTEL_GT_ATTR_RO(media_RP0_freq_mhz);
INTEL_GT_ATTR_RO(media_RPn_freq_mhz);
+INTEL_GT_ATTR_RW(slpc_ignore_eff_freq);
+
static const struct attribute *media_perf_power_attrs[] = {
&attr_media_freq_factor.attr,
&attr_media_freq_factor_scale.attr,
@@ -744,6 +773,12 @@ void intel_gt_sysfs_pm_init(struct intel_gt *gt, struct kobject *kobj)
if (ret)
gt_warn(gt, "failed to create punit_req_freq_mhz sysfs (%pe)", ERR_PTR(ret));
+ if (intel_uc_uses_guc_slpc(&gt->uc)) {
+ ret = sysfs_create_file(kobj, &attr_slpc_ignore_eff_freq.attr);
+ if (ret)
+ gt_warn(gt, "failed to create ignore_eff_freq sysfs (%pe)", ERR_PTR(ret));
+ }
+
if (i915_mmio_reg_valid(intel_gt_perf_limit_reasons_reg(gt))) {
ret = sysfs_create_files(kobj, throttle_reason_attrs);
if (ret)
diff --git a/drivers/gpu/drm/i915/gt/intel_gtt.c b/drivers/gpu/drm/i915/gt/intel_gtt.c
index 4f436ba7a3c8..2f6a9be0ffe6 100644
--- a/drivers/gpu/drm/i915/gt/intel_gtt.c
+++ b/drivers/gpu/drm/i915/gt/intel_gtt.c
@@ -468,6 +468,44 @@ void gtt_write_workarounds(struct intel_gt *gt)
}
}
+static void xelpmp_setup_private_ppat(struct intel_uncore *uncore)
+{
+ intel_uncore_write(uncore, XELPMP_PAT_INDEX(0),
+ MTL_PPAT_L4_0_WB);
+ intel_uncore_write(uncore, XELPMP_PAT_INDEX(1),
+ MTL_PPAT_L4_1_WT);
+ intel_uncore_write(uncore, XELPMP_PAT_INDEX(2),
+ MTL_PPAT_L4_3_UC);
+ intel_uncore_write(uncore, XELPMP_PAT_INDEX(3),
+ MTL_PPAT_L4_0_WB | MTL_2_COH_1W);
+ intel_uncore_write(uncore, XELPMP_PAT_INDEX(4),
+ MTL_PPAT_L4_0_WB | MTL_3_COH_2W);
+
+ /*
+ * Remaining PAT entries are left at the hardware-default
+ * fully-cached setting
+ */
+}
+
+static void xelpg_setup_private_ppat(struct intel_gt *gt)
+{
+ intel_gt_mcr_multicast_write(gt, XEHP_PAT_INDEX(0),
+ MTL_PPAT_L4_0_WB);
+ intel_gt_mcr_multicast_write(gt, XEHP_PAT_INDEX(1),
+ MTL_PPAT_L4_1_WT);
+ intel_gt_mcr_multicast_write(gt, XEHP_PAT_INDEX(2),
+ MTL_PPAT_L4_3_UC);
+ intel_gt_mcr_multicast_write(gt, XEHP_PAT_INDEX(3),
+ MTL_PPAT_L4_0_WB | MTL_2_COH_1W);
+ intel_gt_mcr_multicast_write(gt, XEHP_PAT_INDEX(4),
+ MTL_PPAT_L4_0_WB | MTL_3_COH_2W);
+
+ /*
+ * Remaining PAT entries are left at the hardware-default
+ * fully-cached setting
+ */
+}
+
static void tgl_setup_private_ppat(struct intel_uncore *uncore)
{
/* TGL doesn't support LLC or AGE settings */
@@ -603,7 +641,14 @@ void setup_private_pat(struct intel_gt *gt)
GEM_BUG_ON(GRAPHICS_VER(i915) < 8);
- if (GRAPHICS_VER_FULL(i915) >= IP_VER(12, 50))
+ if (gt->type == GT_MEDIA) {
+ xelpmp_setup_private_ppat(gt->uncore);
+ return;
+ }
+
+ if (GRAPHICS_VER_FULL(i915) >= IP_VER(12, 70))
+ xelpg_setup_private_ppat(gt);
+ else if (GRAPHICS_VER_FULL(i915) >= IP_VER(12, 50))
xehp_setup_private_ppat(gt);
else if (GRAPHICS_VER(i915) >= 12)
tgl_setup_private_ppat(uncore);
diff --git a/drivers/gpu/drm/i915/gt/intel_gtt.h b/drivers/gpu/drm/i915/gt/intel_gtt.h
index 69ce55f517f5..4d6296cdbcfd 100644
--- a/drivers/gpu/drm/i915/gt/intel_gtt.h
+++ b/drivers/gpu/drm/i915/gt/intel_gtt.h
@@ -88,9 +88,17 @@ typedef u64 gen8_pte_t;
#define BYT_PTE_SNOOPED_BY_CPU_CACHES REG_BIT(2)
#define BYT_PTE_WRITEABLE REG_BIT(1)
+#define MTL_PPGTT_PTE_PAT3 BIT_ULL(62)
#define GEN12_PPGTT_PTE_LM BIT_ULL(11)
+#define GEN12_PPGTT_PTE_PAT2 BIT_ULL(7)
+#define GEN12_PPGTT_PTE_PAT1 BIT_ULL(4)
+#define GEN12_PPGTT_PTE_PAT0 BIT_ULL(3)
-#define GEN12_GGTT_PTE_LM BIT_ULL(1)
+#define GEN12_GGTT_PTE_LM BIT_ULL(1)
+#define MTL_GGTT_PTE_PAT0 BIT_ULL(52)
+#define MTL_GGTT_PTE_PAT1 BIT_ULL(53)
+#define GEN12_GGTT_PTE_ADDR_MASK GENMASK_ULL(45, 12)
+#define MTL_GGTT_PTE_PAT_MASK GENMASK_ULL(53, 52)
#define GEN12_PDE_64K BIT(6)
#define GEN12_PTE_PS64 BIT(8)
@@ -147,7 +155,13 @@ typedef u64 gen8_pte_t;
#define GEN8_PDE_IPS_64K BIT(11)
#define GEN8_PDE_PS_2M BIT(7)
-enum i915_cache_level;
+#define MTL_PPAT_L4_CACHE_POLICY_MASK REG_GENMASK(3, 2)
+#define MTL_PAT_INDEX_COH_MODE_MASK REG_GENMASK(1, 0)
+#define MTL_PPAT_L4_3_UC REG_FIELD_PREP(MTL_PPAT_L4_CACHE_POLICY_MASK, 3)
+#define MTL_PPAT_L4_1_WT REG_FIELD_PREP(MTL_PPAT_L4_CACHE_POLICY_MASK, 1)
+#define MTL_PPAT_L4_0_WB REG_FIELD_PREP(MTL_PPAT_L4_CACHE_POLICY_MASK, 0)
+#define MTL_3_COH_2W REG_FIELD_PREP(MTL_PAT_INDEX_COH_MODE_MASK, 3)
+#define MTL_2_COH_1W REG_FIELD_PREP(MTL_PAT_INDEX_COH_MODE_MASK, 2)
struct drm_i915_gem_object;
struct i915_fence_reg;
@@ -216,7 +230,7 @@ struct i915_vma_ops {
void (*bind_vma)(struct i915_address_space *vm,
struct i915_vm_pt_stash *stash,
struct i915_vma_resource *vma_res,
- enum i915_cache_level cache_level,
+ unsigned int pat_index,
u32 flags);
/*
* Unmap an object from an address space. This usually consists of
@@ -288,7 +302,7 @@ struct i915_address_space {
(*alloc_scratch_dma)(struct i915_address_space *vm, int sz);
u64 (*pte_encode)(dma_addr_t addr,
- enum i915_cache_level level,
+ unsigned int pat_index,
u32 flags); /* Create a valid PTE */
#define PTE_READ_ONLY BIT(0)
#define PTE_LM BIT(1)
@@ -303,20 +317,20 @@ struct i915_address_space {
void (*insert_page)(struct i915_address_space *vm,
dma_addr_t addr,
u64 offset,
- enum i915_cache_level cache_level,
+ unsigned int pat_index,
u32 flags);
void (*insert_entries)(struct i915_address_space *vm,
struct i915_vma_resource *vma_res,
- enum i915_cache_level cache_level,
+ unsigned int pat_index,
u32 flags);
void (*raw_insert_page)(struct i915_address_space *vm,
dma_addr_t addr,
u64 offset,
- enum i915_cache_level cache_level,
+ unsigned int pat_index,
u32 flags);
void (*raw_insert_entries)(struct i915_address_space *vm,
struct i915_vma_resource *vma_res,
- enum i915_cache_level cache_level,
+ unsigned int pat_index,
u32 flags);
void (*cleanup)(struct i915_address_space *vm);
@@ -493,7 +507,7 @@ static inline void i915_vm_put(struct i915_address_space *vm)
/**
* i915_vm_resv_put - Release a reference on the vm's reservation lock
- * @resv: Pointer to a reservation lock obtained from i915_vm_resv_get()
+ * @vm: The vm whose reservation lock reference we want to release
*/
static inline void i915_vm_resv_put(struct i915_address_space *vm)
{
@@ -563,7 +577,7 @@ void ppgtt_init(struct i915_ppgtt *ppgtt, struct intel_gt *gt,
void intel_ggtt_bind_vma(struct i915_address_space *vm,
struct i915_vm_pt_stash *stash,
struct i915_vma_resource *vma_res,
- enum i915_cache_level cache_level,
+ unsigned int pat_index,
u32 flags);
void intel_ggtt_unbind_vma(struct i915_address_space *vm,
struct i915_vma_resource *vma_res);
@@ -641,7 +655,7 @@ void gen6_ggtt_invalidate(struct i915_ggtt *ggtt);
void ppgtt_bind_vma(struct i915_address_space *vm,
struct i915_vm_pt_stash *stash,
struct i915_vma_resource *vma_res,
- enum i915_cache_level cache_level,
+ unsigned int pat_index,
u32 flags);
void ppgtt_unbind_vma(struct i915_address_space *vm,
struct i915_vma_resource *vma_res);
diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c
index 81a96c52a92b..a4ec20aaafe2 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc.c
+++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
@@ -1370,7 +1370,9 @@ gen12_emit_indirect_ctx_rcs(const struct intel_context *ce, u32 *cs)
cs, GEN12_GFX_CCS_AUX_NV);
/* Wa_16014892111 */
- if (IS_DG2(ce->engine->i915))
+ if (IS_MTL_GRAPHICS_STEP(ce->engine->i915, M, STEP_A0, STEP_B0) ||
+ IS_MTL_GRAPHICS_STEP(ce->engine->i915, P, STEP_A0, STEP_B0) ||
+ IS_DG2(ce->engine->i915))
cs = dg2_emit_draw_watermark_setting(cs);
return cs;
diff --git a/drivers/gpu/drm/i915/gt/intel_migrate.c b/drivers/gpu/drm/i915/gt/intel_migrate.c
index 3f638f198796..6023288b0e2d 100644
--- a/drivers/gpu/drm/i915/gt/intel_migrate.c
+++ b/drivers/gpu/drm/i915/gt/intel_migrate.c
@@ -45,7 +45,9 @@ static void xehpsdv_toggle_pdes(struct i915_address_space *vm,
* Insert a dummy PTE into every PT that will map to LMEM to ensure
* we have a correctly setup PDE structure for later use.
*/
- vm->insert_page(vm, 0, d->offset, I915_CACHE_NONE, PTE_LM);
+ vm->insert_page(vm, 0, d->offset,
+ i915_gem_get_pat_index(vm->i915, I915_CACHE_NONE),
+ PTE_LM);
GEM_BUG_ON(!pt->is_compact);
d->offset += SZ_2M;
}
@@ -63,7 +65,9 @@ static void xehpsdv_insert_pte(struct i915_address_space *vm,
* alignment is 64K underneath for the pt, and we are careful
* not to access the space in the void.
*/
- vm->insert_page(vm, px_dma(pt), d->offset, I915_CACHE_NONE, PTE_LM);
+ vm->insert_page(vm, px_dma(pt), d->offset,
+ i915_gem_get_pat_index(vm->i915, I915_CACHE_NONE),
+ PTE_LM);
d->offset += SZ_64K;
}
@@ -73,7 +77,8 @@ static void insert_pte(struct i915_address_space *vm,
{
struct insert_pte_data *d = data;
- vm->insert_page(vm, px_dma(pt), d->offset, I915_CACHE_NONE,
+ vm->insert_page(vm, px_dma(pt), d->offset,
+ i915_gem_get_pat_index(vm->i915, I915_CACHE_NONE),
i915_gem_object_is_lmem(pt->base) ? PTE_LM : 0);
d->offset += PAGE_SIZE;
}
@@ -356,13 +361,13 @@ static int max_pte_pkt_size(struct i915_request *rq, int pkt)
static int emit_pte(struct i915_request *rq,
struct sgt_dma *it,
- enum i915_cache_level cache_level,
+ unsigned int pat_index,
bool is_lmem,
u64 offset,
int length)
{
bool has_64K_pages = HAS_64K_PAGES(rq->engine->i915);
- const u64 encode = rq->context->vm->pte_encode(0, cache_level,
+ const u64 encode = rq->context->vm->pte_encode(0, pat_index,
is_lmem ? PTE_LM : 0);
struct intel_ring *ring = rq->ring;
int pkt, dword_length;
@@ -673,17 +678,17 @@ int
intel_context_migrate_copy(struct intel_context *ce,
const struct i915_deps *deps,
struct scatterlist *src,
- enum i915_cache_level src_cache_level,
+ unsigned int src_pat_index,
bool src_is_lmem,
struct scatterlist *dst,
- enum i915_cache_level dst_cache_level,
+ unsigned int dst_pat_index,
bool dst_is_lmem,
struct i915_request **out)
{
struct sgt_dma it_src = sg_sgt(src), it_dst = sg_sgt(dst), it_ccs;
struct drm_i915_private *i915 = ce->engine->i915;
u64 ccs_bytes_to_cpy = 0, bytes_to_cpy;
- enum i915_cache_level ccs_cache_level;
+ unsigned int ccs_pat_index;
u32 src_offset, dst_offset;
u8 src_access, dst_access;
struct i915_request *rq;
@@ -707,12 +712,12 @@ intel_context_migrate_copy(struct intel_context *ce,
dst_sz = scatter_list_length(dst);
if (src_is_lmem) {
it_ccs = it_dst;
- ccs_cache_level = dst_cache_level;
+ ccs_pat_index = dst_pat_index;
ccs_is_src = false;
} else if (dst_is_lmem) {
bytes_to_cpy = dst_sz;
it_ccs = it_src;
- ccs_cache_level = src_cache_level;
+ ccs_pat_index = src_pat_index;
ccs_is_src = true;
}
@@ -773,7 +778,7 @@ intel_context_migrate_copy(struct intel_context *ce,
src_sz = calculate_chunk_sz(i915, src_is_lmem,
bytes_to_cpy, ccs_bytes_to_cpy);
- len = emit_pte(rq, &it_src, src_cache_level, src_is_lmem,
+ len = emit_pte(rq, &it_src, src_pat_index, src_is_lmem,
src_offset, src_sz);
if (!len) {
err = -EINVAL;
@@ -784,7 +789,7 @@ intel_context_migrate_copy(struct intel_context *ce,
goto out_rq;
}
- err = emit_pte(rq, &it_dst, dst_cache_level, dst_is_lmem,
+ err = emit_pte(rq, &it_dst, dst_pat_index, dst_is_lmem,
dst_offset, len);
if (err < 0)
goto out_rq;
@@ -811,7 +816,7 @@ intel_context_migrate_copy(struct intel_context *ce,
goto out_rq;
ccs_sz = GET_CCS_BYTES(i915, len);
- err = emit_pte(rq, &it_ccs, ccs_cache_level, false,
+ err = emit_pte(rq, &it_ccs, ccs_pat_index, false,
ccs_is_src ? src_offset : dst_offset,
ccs_sz);
if (err < 0)
@@ -920,7 +925,7 @@ static int emit_clear(struct i915_request *rq, u32 offset, int size,
GEM_BUG_ON(size >> PAGE_SHIFT > S16_MAX);
- if (HAS_FLAT_CCS(i915) && ver >= 12)
+ if (GRAPHICS_VER_FULL(i915) >= IP_VER(12, 50))
ring_sz = XY_FAST_COLOR_BLT_DW;
else if (ver >= 8)
ring_sz = 8;
@@ -931,7 +936,7 @@ static int emit_clear(struct i915_request *rq, u32 offset, int size,
if (IS_ERR(cs))
return PTR_ERR(cs);
- if (HAS_FLAT_CCS(i915) && ver >= 12) {
+ if (GRAPHICS_VER_FULL(i915) >= IP_VER(12, 50)) {
*cs++ = XY_FAST_COLOR_BLT_CMD | XY_FAST_COLOR_BLT_DEPTH_32 |
(XY_FAST_COLOR_BLT_DW - 2);
*cs++ = FIELD_PREP(XY_FAST_COLOR_BLT_MOCS_MASK, mocs) |
@@ -979,7 +984,7 @@ int
intel_context_migrate_clear(struct intel_context *ce,
const struct i915_deps *deps,
struct scatterlist *sg,
- enum i915_cache_level cache_level,
+ unsigned int pat_index,
bool is_lmem,
u32 value,
struct i915_request **out)
@@ -1027,7 +1032,7 @@ intel_context_migrate_clear(struct intel_context *ce,
if (err)
goto out_rq;
- len = emit_pte(rq, &it, cache_level, is_lmem, offset, CHUNK_SZ);
+ len = emit_pte(rq, &it, pat_index, is_lmem, offset, CHUNK_SZ);
if (len <= 0) {
err = len;
goto out_rq;
@@ -1074,10 +1079,10 @@ int intel_migrate_copy(struct intel_migrate *m,
struct i915_gem_ww_ctx *ww,
const struct i915_deps *deps,
struct scatterlist *src,
- enum i915_cache_level src_cache_level,
+ unsigned int src_pat_index,
bool src_is_lmem,
struct scatterlist *dst,
- enum i915_cache_level dst_cache_level,
+ unsigned int dst_pat_index,
bool dst_is_lmem,
struct i915_request **out)
{
@@ -1098,8 +1103,8 @@ int intel_migrate_copy(struct intel_migrate *m,
goto out;
err = intel_context_migrate_copy(ce, deps,
- src, src_cache_level, src_is_lmem,
- dst, dst_cache_level, dst_is_lmem,
+ src, src_pat_index, src_is_lmem,
+ dst, dst_pat_index, dst_is_lmem,
out);
intel_context_unpin(ce);
@@ -1113,7 +1118,7 @@ intel_migrate_clear(struct intel_migrate *m,
struct i915_gem_ww_ctx *ww,
const struct i915_deps *deps,
struct scatterlist *sg,
- enum i915_cache_level cache_level,
+ unsigned int pat_index,
bool is_lmem,
u32 value,
struct i915_request **out)
@@ -1134,7 +1139,7 @@ intel_migrate_clear(struct intel_migrate *m,
if (err)
goto out;
- err = intel_context_migrate_clear(ce, deps, sg, cache_level,
+ err = intel_context_migrate_clear(ce, deps, sg, pat_index,
is_lmem, value, out);
intel_context_unpin(ce);
diff --git a/drivers/gpu/drm/i915/gt/intel_migrate.h b/drivers/gpu/drm/i915/gt/intel_migrate.h
index ccc677ec4aa3..11fc09a00c4b 100644
--- a/drivers/gpu/drm/i915/gt/intel_migrate.h
+++ b/drivers/gpu/drm/i915/gt/intel_migrate.h
@@ -16,7 +16,6 @@ struct i915_request;
struct i915_gem_ww_ctx;
struct intel_gt;
struct scatterlist;
-enum i915_cache_level;
int intel_migrate_init(struct intel_migrate *m, struct intel_gt *gt);
@@ -26,20 +25,20 @@ int intel_migrate_copy(struct intel_migrate *m,
struct i915_gem_ww_ctx *ww,
const struct i915_deps *deps,
struct scatterlist *src,
- enum i915_cache_level src_cache_level,
+ unsigned int src_pat_index,
bool src_is_lmem,
struct scatterlist *dst,
- enum i915_cache_level dst_cache_level,
+ unsigned int dst_pat_index,
bool dst_is_lmem,
struct i915_request **out);
int intel_context_migrate_copy(struct intel_context *ce,
const struct i915_deps *deps,
struct scatterlist *src,
- enum i915_cache_level src_cache_level,
+ unsigned int src_pat_index,
bool src_is_lmem,
struct scatterlist *dst,
- enum i915_cache_level dst_cache_level,
+ unsigned int dst_pat_index,
bool dst_is_lmem,
struct i915_request **out);
@@ -48,7 +47,7 @@ intel_migrate_clear(struct intel_migrate *m,
struct i915_gem_ww_ctx *ww,
const struct i915_deps *deps,
struct scatterlist *sg,
- enum i915_cache_level cache_level,
+ unsigned int pat_index,
bool is_lmem,
u32 value,
struct i915_request **out);
@@ -56,7 +55,7 @@ int
intel_context_migrate_clear(struct intel_context *ce,
const struct i915_deps *deps,
struct scatterlist *sg,
- enum i915_cache_level cache_level,
+ unsigned int pat_index,
bool is_lmem,
u32 value,
struct i915_request **out);
diff --git a/drivers/gpu/drm/i915/gt/intel_mocs.c b/drivers/gpu/drm/i915/gt/intel_mocs.c
index 69b489e8dfed..2c014407225c 100644
--- a/drivers/gpu/drm/i915/gt/intel_mocs.c
+++ b/drivers/gpu/drm/i915/gt/intel_mocs.c
@@ -40,6 +40,10 @@ struct drm_i915_mocs_table {
#define LE_COS(value) ((value) << 15)
#define LE_SSE(value) ((value) << 17)
+/* Defines for the tables (GLOB_MOCS_0 - GLOB_MOCS_16) */
+#define _L4_CACHEABILITY(value) ((value) << 2)
+#define IG_PAT(value) ((value) << 8)
+
/* Defines for the tables (LNCFMOCS0 - LNCFMOCS31) - two entries per word */
#define L3_ESC(value) ((value) << 0)
#define L3_SCC(value) ((value) << 1)
@@ -50,6 +54,7 @@ struct drm_i915_mocs_table {
/* Helper defines */
#define GEN9_NUM_MOCS_ENTRIES 64 /* 63-64 are reserved, but configured. */
#define PVC_NUM_MOCS_ENTRIES 3
+#define MTL_NUM_MOCS_ENTRIES 16
/* (e)LLC caching options */
/*
@@ -73,6 +78,12 @@ struct drm_i915_mocs_table {
#define L3_2_RESERVED _L3_CACHEABILITY(2)
#define L3_3_WB _L3_CACHEABILITY(3)
+/* L4 caching options */
+#define L4_0_WB _L4_CACHEABILITY(0)
+#define L4_1_WT _L4_CACHEABILITY(1)
+#define L4_2_RESERVED _L4_CACHEABILITY(2)
+#define L4_3_UC _L4_CACHEABILITY(3)
+
#define MOCS_ENTRY(__idx, __control_value, __l3cc_value) \
[__idx] = { \
.control_value = __control_value, \
@@ -416,6 +427,57 @@ static const struct drm_i915_mocs_entry pvc_mocs_table[] = {
MOCS_ENTRY(2, 0, L3_3_WB),
};
+static const struct drm_i915_mocs_entry mtl_mocs_table[] = {
+ /* Error - Reserved for Non-Use */
+ MOCS_ENTRY(0,
+ IG_PAT(0),
+ L3_LKUP(1) | L3_3_WB),
+ /* Cached - L3 + L4 */
+ MOCS_ENTRY(1,
+ IG_PAT(1),
+ L3_LKUP(1) | L3_3_WB),
+ /* L4 - GO:L3 */
+ MOCS_ENTRY(2,
+ IG_PAT(1),
+ L3_LKUP(1) | L3_1_UC),
+ /* Uncached - GO:L3 */
+ MOCS_ENTRY(3,
+ IG_PAT(1) | L4_3_UC,
+ L3_LKUP(1) | L3_1_UC),
+ /* L4 - GO:Mem */
+ MOCS_ENTRY(4,
+ IG_PAT(1),
+ L3_LKUP(1) | L3_GLBGO(1) | L3_1_UC),
+ /* Uncached - GO:Mem */
+ MOCS_ENTRY(5,
+ IG_PAT(1) | L4_3_UC,
+ L3_LKUP(1) | L3_GLBGO(1) | L3_1_UC),
+ /* L4 - L3:NoLKUP; GO:L3 */
+ MOCS_ENTRY(6,
+ IG_PAT(1),
+ L3_1_UC),
+ /* Uncached - L3:NoLKUP; GO:L3 */
+ MOCS_ENTRY(7,
+ IG_PAT(1) | L4_3_UC,
+ L3_1_UC),
+ /* L4 - L3:NoLKUP; GO:Mem */
+ MOCS_ENTRY(8,
+ IG_PAT(1),
+ L3_GLBGO(1) | L3_1_UC),
+ /* Uncached - L3:NoLKUP; GO:Mem */
+ MOCS_ENTRY(9,
+ IG_PAT(1) | L4_3_UC,
+ L3_GLBGO(1) | L3_1_UC),
+ /* Display - L3; L4:WT */
+ MOCS_ENTRY(14,
+ IG_PAT(1) | L4_1_WT,
+ L3_LKUP(1) | L3_3_WB),
+ /* CCS - Non-Displayable */
+ MOCS_ENTRY(15,
+ IG_PAT(1),
+ L3_GLBGO(1) | L3_1_UC),
+};
+
enum {
HAS_GLOBAL_MOCS = BIT(0),
HAS_ENGINE_MOCS = BIT(1),
@@ -445,7 +507,13 @@ static unsigned int get_mocs_settings(const struct drm_i915_private *i915,
memset(table, 0, sizeof(struct drm_i915_mocs_table));
table->unused_entries_index = I915_MOCS_PTE;
- if (IS_PONTEVECCHIO(i915)) {
+ if (IS_METEORLAKE(i915)) {
+ table->size = ARRAY_SIZE(mtl_mocs_table);
+ table->table = mtl_mocs_table;
+ table->n_entries = MTL_NUM_MOCS_ENTRIES;
+ table->uc_index = 9;
+ table->unused_entries_index = 1;
+ } else if (IS_PONTEVECCHIO(i915)) {
table->size = ARRAY_SIZE(pvc_mocs_table);
table->table = pvc_mocs_table;
table->n_entries = PVC_NUM_MOCS_ENTRIES;
diff --git a/drivers/gpu/drm/i915/gt/intel_ppgtt.c b/drivers/gpu/drm/i915/gt/intel_ppgtt.c
index 7ecfa672f738..436756bfbb1a 100644
--- a/drivers/gpu/drm/i915/gt/intel_ppgtt.c
+++ b/drivers/gpu/drm/i915/gt/intel_ppgtt.c
@@ -181,7 +181,7 @@ struct i915_ppgtt *i915_ppgtt_create(struct intel_gt *gt,
void ppgtt_bind_vma(struct i915_address_space *vm,
struct i915_vm_pt_stash *stash,
struct i915_vma_resource *vma_res,
- enum i915_cache_level cache_level,
+ unsigned int pat_index,
u32 flags)
{
u32 pte_flags;
@@ -199,7 +199,7 @@ void ppgtt_bind_vma(struct i915_address_space *vm,
if (vma_res->bi.lmem)
pte_flags |= PTE_LM;
- vm->insert_entries(vm, vma_res, cache_level, pte_flags);
+ vm->insert_entries(vm, vma_res, pat_index, pte_flags);
wmb();
}
diff --git a/drivers/gpu/drm/i915/gt/intel_rc6.c b/drivers/gpu/drm/i915/gt/intel_rc6.c
index 8f3cd68d14f8..58bb1c55294c 100644
--- a/drivers/gpu/drm/i915/gt/intel_rc6.c
+++ b/drivers/gpu/drm/i915/gt/intel_rc6.c
@@ -53,11 +53,6 @@ static struct drm_i915_private *rc6_to_i915(struct intel_rc6 *rc)
return rc6_to_gt(rc)->i915;
}
-static void set(struct intel_uncore *uncore, i915_reg_t reg, u32 val)
-{
- intel_uncore_write_fw(uncore, reg, val);
-}
-
static void gen11_rc6_enable(struct intel_rc6 *rc6)
{
struct intel_gt *gt = rc6_to_gt(rc6);
@@ -72,19 +67,19 @@ static void gen11_rc6_enable(struct intel_rc6 *rc6)
*/
if (!intel_uc_uses_guc_rc(&gt->uc)) {
/* 2b: Program RC6 thresholds.*/
- set(uncore, GEN6_RC6_WAKE_RATE_LIMIT, 54 << 16 | 85);
- set(uncore, GEN10_MEDIA_WAKE_RATE_LIMIT, 150);
+ intel_uncore_write_fw(uncore, GEN6_RC6_WAKE_RATE_LIMIT, 54 << 16 | 85);
+ intel_uncore_write_fw(uncore, GEN10_MEDIA_WAKE_RATE_LIMIT, 150);
- set(uncore, GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */
- set(uncore, GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */
+ intel_uncore_write_fw(uncore, GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */
+ intel_uncore_write_fw(uncore, GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */
for_each_engine(engine, rc6_to_gt(rc6), id)
- set(uncore, RING_MAX_IDLE(engine->mmio_base), 10);
+ intel_uncore_write_fw(uncore, RING_MAX_IDLE(engine->mmio_base), 10);
- set(uncore, GUC_MAX_IDLE_COUNT, 0xA);
+ intel_uncore_write_fw(uncore, GUC_MAX_IDLE_COUNT, 0xA);
- set(uncore, GEN6_RC_SLEEP, 0);
+ intel_uncore_write_fw(uncore, GEN6_RC_SLEEP, 0);
- set(uncore, GEN6_RC6_THRESHOLD, 50000); /* 50/125ms per EI */
+ intel_uncore_write_fw(uncore, GEN6_RC6_THRESHOLD, 50000); /* 50/125ms per EI */
}
/*
@@ -105,8 +100,8 @@ static void gen11_rc6_enable(struct intel_rc6 *rc6)
* Broadwell+, To be conservative, we want to factor in a context
* switch on top (due to ksoftirqd).
*/
- set(uncore, GEN9_MEDIA_PG_IDLE_HYSTERESIS, 60);
- set(uncore, GEN9_RENDER_PG_IDLE_HYSTERESIS, 60);
+ intel_uncore_write_fw(uncore, GEN9_MEDIA_PG_IDLE_HYSTERESIS, 60);
+ intel_uncore_write_fw(uncore, GEN9_RENDER_PG_IDLE_HYSTERESIS, 60);
/* 3a: Enable RC6
*
@@ -122,8 +117,14 @@ static void gen11_rc6_enable(struct intel_rc6 *rc6)
GEN6_RC_CTL_RC6_ENABLE |
GEN6_RC_CTL_EI_MODE(1);
- /* Wa_16011777198 - Render powergating must remain disabled */
- if (IS_DG2_GRAPHICS_STEP(gt->i915, G10, STEP_A0, STEP_C0) ||
+ /*
+ * Wa_16011777198 and BSpec 52698 - Render powergating must be off.
+ * FIXME BSpec is outdated, disabling powergating for MTL is just
+ * temporary wa and should be removed after fixing real cause
+ * of forcewake timeouts.
+ */
+ if (IS_METEORLAKE(gt->i915) ||
+ IS_DG2_GRAPHICS_STEP(gt->i915, G10, STEP_A0, STEP_C0) ||
IS_DG2_GRAPHICS_STEP(gt->i915, G11, STEP_A0, STEP_B0))
pg_enable =
GEN9_MEDIA_PG_ENABLE |
@@ -141,7 +142,7 @@ static void gen11_rc6_enable(struct intel_rc6 *rc6)
VDN_MFX_POWERGATE_ENABLE(i));
}
- set(uncore, GEN9_PG_ENABLE, pg_enable);
+ intel_uncore_write_fw(uncore, GEN9_PG_ENABLE, pg_enable);
}
static void gen9_rc6_enable(struct intel_rc6 *rc6)
@@ -152,26 +153,26 @@ static void gen9_rc6_enable(struct intel_rc6 *rc6)
/* 2b: Program RC6 thresholds.*/
if (GRAPHICS_VER(rc6_to_i915(rc6)) >= 11) {
- set(uncore, GEN6_RC6_WAKE_RATE_LIMIT, 54 << 16 | 85);
- set(uncore, GEN10_MEDIA_WAKE_RATE_LIMIT, 150);
+ intel_uncore_write_fw(uncore, GEN6_RC6_WAKE_RATE_LIMIT, 54 << 16 | 85);
+ intel_uncore_write_fw(uncore, GEN10_MEDIA_WAKE_RATE_LIMIT, 150);
} else if (IS_SKYLAKE(rc6_to_i915(rc6))) {
/*
* WaRsDoubleRc6WrlWithCoarsePowerGating:skl Doubling WRL only
* when CPG is enabled
*/
- set(uncore, GEN6_RC6_WAKE_RATE_LIMIT, 108 << 16);
+ intel_uncore_write_fw(uncore, GEN6_RC6_WAKE_RATE_LIMIT, 108 << 16);
} else {
- set(uncore, GEN6_RC6_WAKE_RATE_LIMIT, 54 << 16);
+ intel_uncore_write_fw(uncore, GEN6_RC6_WAKE_RATE_LIMIT, 54 << 16);
}
- set(uncore, GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */
- set(uncore, GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */
+ intel_uncore_write_fw(uncore, GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */
+ intel_uncore_write_fw(uncore, GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */
for_each_engine(engine, rc6_to_gt(rc6), id)
- set(uncore, RING_MAX_IDLE(engine->mmio_base), 10);
+ intel_uncore_write_fw(uncore, RING_MAX_IDLE(engine->mmio_base), 10);
- set(uncore, GUC_MAX_IDLE_COUNT, 0xA);
+ intel_uncore_write_fw(uncore, GUC_MAX_IDLE_COUNT, 0xA);
- set(uncore, GEN6_RC_SLEEP, 0);
+ intel_uncore_write_fw(uncore, GEN6_RC_SLEEP, 0);
/*
* 2c: Program Coarse Power Gating Policies.
@@ -194,11 +195,11 @@ static void gen9_rc6_enable(struct intel_rc6 *rc6)
* conservative, we have to factor in a context switch on top (due
* to ksoftirqd).
*/
- set(uncore, GEN9_MEDIA_PG_IDLE_HYSTERESIS, 250);
- set(uncore, GEN9_RENDER_PG_IDLE_HYSTERESIS, 250);
+ intel_uncore_write_fw(uncore, GEN9_MEDIA_PG_IDLE_HYSTERESIS, 250);
+ intel_uncore_write_fw(uncore, GEN9_RENDER_PG_IDLE_HYSTERESIS, 250);
/* 3a: Enable RC6 */
- set(uncore, GEN6_RC6_THRESHOLD, 37500); /* 37.5/125ms per EI */
+ intel_uncore_write_fw(uncore, GEN6_RC6_THRESHOLD, 37500); /* 37.5/125ms per EI */
rc6->ctl_enable =
GEN6_RC_CTL_HW_ENABLE |
@@ -210,8 +211,8 @@ static void gen9_rc6_enable(struct intel_rc6 *rc6)
* - Render/Media PG need to be disabled with RC6.
*/
if (!NEEDS_WaRsDisableCoarsePowerGating(rc6_to_i915(rc6)))
- set(uncore, GEN9_PG_ENABLE,
- GEN9_RENDER_PG_ENABLE | GEN9_MEDIA_PG_ENABLE);
+ intel_uncore_write_fw(uncore, GEN9_PG_ENABLE,
+ GEN9_RENDER_PG_ENABLE | GEN9_MEDIA_PG_ENABLE);
}
static void gen8_rc6_enable(struct intel_rc6 *rc6)
@@ -221,13 +222,13 @@ static void gen8_rc6_enable(struct intel_rc6 *rc6)
enum intel_engine_id id;
/* 2b: Program RC6 thresholds.*/
- set(uncore, GEN6_RC6_WAKE_RATE_LIMIT, 40 << 16);
- set(uncore, GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */
- set(uncore, GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */
+ intel_uncore_write_fw(uncore, GEN6_RC6_WAKE_RATE_LIMIT, 40 << 16);
+ intel_uncore_write_fw(uncore, GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */
+ intel_uncore_write_fw(uncore, GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */
for_each_engine(engine, rc6_to_gt(rc6), id)
- set(uncore, RING_MAX_IDLE(engine->mmio_base), 10);
- set(uncore, GEN6_RC_SLEEP, 0);
- set(uncore, GEN6_RC6_THRESHOLD, 625); /* 800us/1.28 for TO */
+ intel_uncore_write_fw(uncore, RING_MAX_IDLE(engine->mmio_base), 10);
+ intel_uncore_write_fw(uncore, GEN6_RC_SLEEP, 0);
+ intel_uncore_write_fw(uncore, GEN6_RC6_THRESHOLD, 625); /* 800us/1.28 for TO */
/* 3: Enable RC6 */
rc6->ctl_enable =
@@ -245,20 +246,20 @@ static void gen6_rc6_enable(struct intel_rc6 *rc6)
u32 rc6vids, rc6_mask;
int ret;
- set(uncore, GEN6_RC1_WAKE_RATE_LIMIT, 1000 << 16);
- set(uncore, GEN6_RC6_WAKE_RATE_LIMIT, 40 << 16 | 30);
- set(uncore, GEN6_RC6pp_WAKE_RATE_LIMIT, 30);
- set(uncore, GEN6_RC_EVALUATION_INTERVAL, 125000);
- set(uncore, GEN6_RC_IDLE_HYSTERSIS, 25);
+ intel_uncore_write_fw(uncore, GEN6_RC1_WAKE_RATE_LIMIT, 1000 << 16);
+ intel_uncore_write_fw(uncore, GEN6_RC6_WAKE_RATE_LIMIT, 40 << 16 | 30);
+ intel_uncore_write_fw(uncore, GEN6_RC6pp_WAKE_RATE_LIMIT, 30);
+ intel_uncore_write_fw(uncore, GEN6_RC_EVALUATION_INTERVAL, 125000);
+ intel_uncore_write_fw(uncore, GEN6_RC_IDLE_HYSTERSIS, 25);
for_each_engine(engine, rc6_to_gt(rc6), id)
- set(uncore, RING_MAX_IDLE(engine->mmio_base), 10);
+ intel_uncore_write_fw(uncore, RING_MAX_IDLE(engine->mmio_base), 10);
- set(uncore, GEN6_RC_SLEEP, 0);
- set(uncore, GEN6_RC1e_THRESHOLD, 1000);
- set(uncore, GEN6_RC6_THRESHOLD, 50000);
- set(uncore, GEN6_RC6p_THRESHOLD, 150000);
- set(uncore, GEN6_RC6pp_THRESHOLD, 64000); /* unused */
+ intel_uncore_write_fw(uncore, GEN6_RC_SLEEP, 0);
+ intel_uncore_write_fw(uncore, GEN6_RC1e_THRESHOLD, 1000);
+ intel_uncore_write_fw(uncore, GEN6_RC6_THRESHOLD, 50000);
+ intel_uncore_write_fw(uncore, GEN6_RC6p_THRESHOLD, 150000);
+ intel_uncore_write_fw(uncore, GEN6_RC6pp_THRESHOLD, 64000); /* unused */
/* We don't use those on Haswell */
rc6_mask = GEN6_RC_CTL_RC6_ENABLE;
@@ -372,22 +373,22 @@ static void chv_rc6_enable(struct intel_rc6 *rc6)
enum intel_engine_id id;
/* 2a: Program RC6 thresholds.*/
- set(uncore, GEN6_RC6_WAKE_RATE_LIMIT, 40 << 16);
- set(uncore, GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */
- set(uncore, GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */
+ intel_uncore_write_fw(uncore, GEN6_RC6_WAKE_RATE_LIMIT, 40 << 16);
+ intel_uncore_write_fw(uncore, GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */
+ intel_uncore_write_fw(uncore, GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */
for_each_engine(engine, rc6_to_gt(rc6), id)
- set(uncore, RING_MAX_IDLE(engine->mmio_base), 10);
- set(uncore, GEN6_RC_SLEEP, 0);
+ intel_uncore_write_fw(uncore, RING_MAX_IDLE(engine->mmio_base), 10);
+ intel_uncore_write_fw(uncore, GEN6_RC_SLEEP, 0);
/* TO threshold set to 500 us (0x186 * 1.28 us) */
- set(uncore, GEN6_RC6_THRESHOLD, 0x186);
+ intel_uncore_write_fw(uncore, GEN6_RC6_THRESHOLD, 0x186);
/* Allows RC6 residency counter to work */
- set(uncore, VLV_COUNTER_CONTROL,
- _MASKED_BIT_ENABLE(VLV_COUNT_RANGE_HIGH |
- VLV_MEDIA_RC6_COUNT_EN |
- VLV_RENDER_RC6_COUNT_EN));
+ intel_uncore_write_fw(uncore, VLV_COUNTER_CONTROL,
+ _MASKED_BIT_ENABLE(VLV_COUNT_RANGE_HIGH |
+ VLV_MEDIA_RC6_COUNT_EN |
+ VLV_RENDER_RC6_COUNT_EN));
/* 3: Enable RC6 */
rc6->ctl_enable = GEN7_RC_CTL_TO_MODE;
@@ -399,22 +400,22 @@ static void vlv_rc6_enable(struct intel_rc6 *rc6)
struct intel_engine_cs *engine;
enum intel_engine_id id;
- set(uncore, GEN6_RC6_WAKE_RATE_LIMIT, 0x00280000);
- set(uncore, GEN6_RC_EVALUATION_INTERVAL, 125000);
- set(uncore, GEN6_RC_IDLE_HYSTERSIS, 25);
+ intel_uncore_write_fw(uncore, GEN6_RC6_WAKE_RATE_LIMIT, 0x00280000);
+ intel_uncore_write_fw(uncore, GEN6_RC_EVALUATION_INTERVAL, 125000);
+ intel_uncore_write_fw(uncore, GEN6_RC_IDLE_HYSTERSIS, 25);
for_each_engine(engine, rc6_to_gt(rc6), id)
- set(uncore, RING_MAX_IDLE(engine->mmio_base), 10);
+ intel_uncore_write_fw(uncore, RING_MAX_IDLE(engine->mmio_base), 10);
- set(uncore, GEN6_RC6_THRESHOLD, 0x557);
+ intel_uncore_write_fw(uncore, GEN6_RC6_THRESHOLD, 0x557);
/* Allows RC6 residency counter to work */
- set(uncore, VLV_COUNTER_CONTROL,
- _MASKED_BIT_ENABLE(VLV_COUNT_RANGE_HIGH |
- VLV_MEDIA_RC0_COUNT_EN |
- VLV_RENDER_RC0_COUNT_EN |
- VLV_MEDIA_RC6_COUNT_EN |
- VLV_RENDER_RC6_COUNT_EN));
+ intel_uncore_write_fw(uncore, VLV_COUNTER_CONTROL,
+ _MASKED_BIT_ENABLE(VLV_COUNT_RANGE_HIGH |
+ VLV_MEDIA_RC0_COUNT_EN |
+ VLV_RENDER_RC0_COUNT_EN |
+ VLV_MEDIA_RC6_COUNT_EN |
+ VLV_RENDER_RC6_COUNT_EN));
rc6->ctl_enable =
GEN7_RC_CTL_TO_MODE | VLV_RC_CTL_CTX_RST_PARALLEL;
@@ -575,9 +576,9 @@ static void __intel_rc6_disable(struct intel_rc6 *rc6)
intel_uncore_forcewake_get(uncore, FORCEWAKE_ALL);
if (GRAPHICS_VER(i915) >= 9)
- set(uncore, GEN9_PG_ENABLE, 0);
- set(uncore, GEN6_RC_CONTROL, 0);
- set(uncore, GEN6_RC_STATE, 0);
+ intel_uncore_write_fw(uncore, GEN9_PG_ENABLE, 0);
+ intel_uncore_write_fw(uncore, GEN6_RC_CONTROL, 0);
+ intel_uncore_write_fw(uncore, GEN6_RC_STATE, 0);
intel_uncore_forcewake_put(uncore, FORCEWAKE_ALL);
}
@@ -684,7 +685,7 @@ void intel_rc6_unpark(struct intel_rc6 *rc6)
return;
/* Restore HW timers for automatic RC6 entry while busy */
- set(uncore, GEN6_RC_CONTROL, rc6->ctl_enable);
+ intel_uncore_write_fw(uncore, GEN6_RC_CONTROL, rc6->ctl_enable);
}
void intel_rc6_park(struct intel_rc6 *rc6)
@@ -704,7 +705,7 @@ void intel_rc6_park(struct intel_rc6 *rc6)
return;
/* Turn off the HW timers and go directly to rc6 */
- set(uncore, GEN6_RC_CONTROL, GEN6_RC_CTL_RC6_ENABLE);
+ intel_uncore_write_fw(uncore, GEN6_RC_CONTROL, GEN6_RC_CTL_RC6_ENABLE);
if (HAS_RC6pp(rc6_to_i915(rc6)))
target = 0x6; /* deepest rc6 */
@@ -712,7 +713,7 @@ void intel_rc6_park(struct intel_rc6 *rc6)
target = 0x5; /* deep rc6 */
else
target = 0x4; /* normal rc6 */
- set(uncore, GEN6_RC_STATE, target << RC_SW_TARGET_STATE_SHIFT);
+ intel_uncore_write_fw(uncore, GEN6_RC_STATE, target << RC_SW_TARGET_STATE_SHIFT);
}
void intel_rc6_disable(struct intel_rc6 *rc6)
@@ -735,7 +736,7 @@ void intel_rc6_fini(struct intel_rc6 *rc6)
/* We want the BIOS C6 state preserved across loads for MTL */
if (IS_METEORLAKE(rc6_to_i915(rc6)) && rc6->bios_state_captured)
- set(uncore, GEN6_RC_STATE, rc6->bios_rc_state);
+ intel_uncore_write_fw(uncore, GEN6_RC_STATE, rc6->bios_rc_state);
pctx = fetch_and_zero(&rc6->pctx);
if (pctx)
@@ -766,18 +767,18 @@ static u64 vlv_residency_raw(struct intel_uncore *uncore, const i915_reg_t reg)
* before we have set the default VLV_COUNTER_CONTROL value. So always
* set the high bit to be safe.
*/
- set(uncore, VLV_COUNTER_CONTROL,
- _MASKED_BIT_ENABLE(VLV_COUNT_RANGE_HIGH));
+ intel_uncore_write_fw(uncore, VLV_COUNTER_CONTROL,
+ _MASKED_BIT_ENABLE(VLV_COUNT_RANGE_HIGH));
upper = intel_uncore_read_fw(uncore, reg);
do {
tmp = upper;
- set(uncore, VLV_COUNTER_CONTROL,
- _MASKED_BIT_DISABLE(VLV_COUNT_RANGE_HIGH));
+ intel_uncore_write_fw(uncore, VLV_COUNTER_CONTROL,
+ _MASKED_BIT_DISABLE(VLV_COUNT_RANGE_HIGH));
lower = intel_uncore_read_fw(uncore, reg);
- set(uncore, VLV_COUNTER_CONTROL,
- _MASKED_BIT_ENABLE(VLV_COUNT_RANGE_HIGH));
+ intel_uncore_write_fw(uncore, VLV_COUNTER_CONTROL,
+ _MASKED_BIT_ENABLE(VLV_COUNT_RANGE_HIGH));
upper = intel_uncore_read_fw(uncore, reg);
} while (upper != tmp && --loop);
diff --git a/drivers/gpu/drm/i915/gt/intel_workarounds.c b/drivers/gpu/drm/i915/gt/intel_workarounds.c
index b925ef47304b..4d2dece96011 100644
--- a/drivers/gpu/drm/i915/gt/intel_workarounds.c
+++ b/drivers/gpu/drm/i915/gt/intel_workarounds.c
@@ -812,11 +812,25 @@ static void dg2_ctx_workarounds_init(struct intel_engine_cs *engine,
wa_masked_en(wal, CACHE_MODE_1, MSAA_OPTIMIZATION_REDUC_DISABLE);
}
+static void mtl_ctx_gt_tuning_init(struct intel_engine_cs *engine,
+ struct i915_wa_list *wal)
+{
+ struct drm_i915_private *i915 = engine->i915;
+
+ dg2_ctx_gt_tuning_init(engine, wal);
+
+ if (IS_MTL_GRAPHICS_STEP(i915, M, STEP_B0, STEP_FOREVER) ||
+ IS_MTL_GRAPHICS_STEP(i915, P, STEP_B0, STEP_FOREVER))
+ wa_add(wal, DRAW_WATERMARK, VERT_WM_VAL, 0x3FF, 0, false);
+}
+
static void mtl_ctx_workarounds_init(struct intel_engine_cs *engine,
struct i915_wa_list *wal)
{
struct drm_i915_private *i915 = engine->i915;
+ mtl_ctx_gt_tuning_init(engine, wal);
+
if (IS_MTL_GRAPHICS_STEP(i915, M, STEP_A0, STEP_B0) ||
IS_MTL_GRAPHICS_STEP(i915, P, STEP_A0, STEP_B0)) {
/* Wa_14014947963 */
@@ -1695,14 +1709,20 @@ pvc_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
static void
xelpg_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
{
+ /* Wa_14018778641 / Wa_18018781329 */
+ wa_mcr_write_or(wal, RENDER_MOD_CTRL, FORCE_MISS_FTLB);
+ wa_mcr_write_or(wal, COMP_MOD_CTRL, FORCE_MISS_FTLB);
+
+ /* Wa_22016670082 */
+ wa_write_or(wal, GEN12_SQCNT1, GEN12_STRICT_RAR_ENABLE);
+
if (IS_MTL_GRAPHICS_STEP(gt->i915, M, STEP_A0, STEP_B0) ||
IS_MTL_GRAPHICS_STEP(gt->i915, P, STEP_A0, STEP_B0)) {
/* Wa_14014830051 */
wa_mcr_write_clr(wal, SARB_CHICKEN1, COMP_CKN_IN);
- /* Wa_18018781329 */
- wa_mcr_write_or(wal, RENDER_MOD_CTRL, FORCE_MISS_FTLB);
- wa_mcr_write_or(wal, COMP_MOD_CTRL, FORCE_MISS_FTLB);
+ /* Wa_14015795083 */
+ wa_write_clr(wal, GEN7_MISCCPCTL, GEN12_DOP_CLOCK_GATE_RENDER_ENABLE);
}
/*
@@ -1715,17 +1735,16 @@ xelpg_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
static void
xelpmp_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
{
- if (IS_MTL_MEDIA_STEP(gt->i915, STEP_A0, STEP_B0)) {
- /*
- * Wa_18018781329
- *
- * Note that although these registers are MCR on the primary
- * GT, the media GT's versions are regular singleton registers.
- */
- wa_write_or(wal, XELPMP_GSC_MOD_CTRL, FORCE_MISS_FTLB);
- wa_write_or(wal, XELPMP_VDBX_MOD_CTRL, FORCE_MISS_FTLB);
- wa_write_or(wal, XELPMP_VEBX_MOD_CTRL, FORCE_MISS_FTLB);
- }
+ /*
+ * Wa_14018778641
+ * Wa_18018781329
+ *
+ * Note that although these registers are MCR on the primary
+ * GT, the media GT's versions are regular singleton registers.
+ */
+ wa_write_or(wal, XELPMP_GSC_MOD_CTRL, FORCE_MISS_FTLB);
+ wa_write_or(wal, XELPMP_VDBX_MOD_CTRL, FORCE_MISS_FTLB);
+ wa_write_or(wal, XELPMP_VEBX_MOD_CTRL, FORCE_MISS_FTLB);
debug_dump_steering(gt);
}
@@ -1743,6 +1762,13 @@ xelpmp_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
*/
static void gt_tuning_settings(struct intel_gt *gt, struct i915_wa_list *wal)
{
+ if (IS_METEORLAKE(gt->i915)) {
+ if (gt->type != GT_MEDIA)
+ wa_mcr_write_or(wal, XEHP_L3SCQREG7, BLEND_FILL_CACHING_OPT_DIS);
+
+ wa_mcr_write_or(wal, XEHP_SQCM, EN_32B_ACCESS);
+ }
+
if (IS_PONTEVECCHIO(gt->i915)) {
wa_mcr_write(wal, XEHPC_L3SCRUB,
SCRUB_CL_DWNGRADE_SHARED | SCRUB_RATE_4B_PER_CLK);
@@ -2939,7 +2965,7 @@ static void
add_render_compute_tuning_settings(struct drm_i915_private *i915,
struct i915_wa_list *wal)
{
- if (IS_DG2(i915))
+ if (IS_METEORLAKE(i915) || IS_DG2(i915))
wa_mcr_write_clr_set(wal, RT_CTRL, STACKID_CTRL, STACKID_CTRL_512);
/*
diff --git a/drivers/gpu/drm/i915/gt/selftest_engine_pm.c b/drivers/gpu/drm/i915/gt/selftest_engine_pm.c
index 87c94314cf67..10e556a7eac4 100644
--- a/drivers/gpu/drm/i915/gt/selftest_engine_pm.c
+++ b/drivers/gpu/drm/i915/gt/selftest_engine_pm.c
@@ -5,6 +5,7 @@
#include <linux/sort.h>
+#include "gt/intel_gt_print.h"
#include "i915_selftest.h"
#include "intel_engine_regs.h"
#include "intel_gpu_commands.h"
@@ -402,7 +403,7 @@ static int live_engine_pm(void *arg)
/* gt wakeref is async (deferred to workqueue) */
if (intel_gt_pm_wait_for_idle(gt)) {
- pr_err("GT failed to idle\n");
+ gt_err(gt, "GT failed to idle\n");
return -EINVAL;
}
}
diff --git a/drivers/gpu/drm/i915/gt/selftest_migrate.c b/drivers/gpu/drm/i915/gt/selftest_migrate.c
index e677f2da093d..3def5ca72dec 100644
--- a/drivers/gpu/drm/i915/gt/selftest_migrate.c
+++ b/drivers/gpu/drm/i915/gt/selftest_migrate.c
@@ -137,7 +137,7 @@ err_free_src:
static int intel_context_copy_ccs(struct intel_context *ce,
const struct i915_deps *deps,
struct scatterlist *sg,
- enum i915_cache_level cache_level,
+ unsigned int pat_index,
bool write_to_ccs,
struct i915_request **out)
{
@@ -185,7 +185,7 @@ static int intel_context_copy_ccs(struct intel_context *ce,
if (err)
goto out_rq;
- len = emit_pte(rq, &it, cache_level, true, offset, CHUNK_SZ);
+ len = emit_pte(rq, &it, pat_index, true, offset, CHUNK_SZ);
if (len <= 0) {
err = len;
goto out_rq;
@@ -223,7 +223,7 @@ intel_migrate_ccs_copy(struct intel_migrate *m,
struct i915_gem_ww_ctx *ww,
const struct i915_deps *deps,
struct scatterlist *sg,
- enum i915_cache_level cache_level,
+ unsigned int pat_index,
bool write_to_ccs,
struct i915_request **out)
{
@@ -243,7 +243,7 @@ intel_migrate_ccs_copy(struct intel_migrate *m,
if (err)
goto out;
- err = intel_context_copy_ccs(ce, deps, sg, cache_level,
+ err = intel_context_copy_ccs(ce, deps, sg, pat_index,
write_to_ccs, out);
intel_context_unpin(ce);
@@ -300,7 +300,7 @@ static int clear(struct intel_migrate *migrate,
/* Write the obj data into ccs surface */
err = intel_migrate_ccs_copy(migrate, &ww, NULL,
obj->mm.pages->sgl,
- obj->cache_level,
+ obj->pat_index,
true, &rq);
if (rq && !err) {
if (i915_request_wait(rq, 0, HZ) < 0) {
@@ -351,7 +351,7 @@ static int clear(struct intel_migrate *migrate,
err = intel_migrate_ccs_copy(migrate, &ww, NULL,
obj->mm.pages->sgl,
- obj->cache_level,
+ obj->pat_index,
false, &rq);
if (rq && !err) {
if (i915_request_wait(rq, 0, HZ) < 0) {
@@ -414,9 +414,9 @@ static int __migrate_copy(struct intel_migrate *migrate,
struct i915_request **out)
{
return intel_migrate_copy(migrate, ww, NULL,
- src->mm.pages->sgl, src->cache_level,
+ src->mm.pages->sgl, src->pat_index,
i915_gem_object_is_lmem(src),
- dst->mm.pages->sgl, dst->cache_level,
+ dst->mm.pages->sgl, dst->pat_index,
i915_gem_object_is_lmem(dst),
out);
}
@@ -428,9 +428,9 @@ static int __global_copy(struct intel_migrate *migrate,
struct i915_request **out)
{
return intel_context_migrate_copy(migrate->context, NULL,
- src->mm.pages->sgl, src->cache_level,
+ src->mm.pages->sgl, src->pat_index,
i915_gem_object_is_lmem(src),
- dst->mm.pages->sgl, dst->cache_level,
+ dst->mm.pages->sgl, dst->pat_index,
i915_gem_object_is_lmem(dst),
out);
}
@@ -455,7 +455,7 @@ static int __migrate_clear(struct intel_migrate *migrate,
{
return intel_migrate_clear(migrate, ww, NULL,
obj->mm.pages->sgl,
- obj->cache_level,
+ obj->pat_index,
i915_gem_object_is_lmem(obj),
value, out);
}
@@ -468,7 +468,7 @@ static int __global_clear(struct intel_migrate *migrate,
{
return intel_context_migrate_clear(migrate->context, NULL,
obj->mm.pages->sgl,
- obj->cache_level,
+ obj->pat_index,
i915_gem_object_is_lmem(obj),
value, out);
}
@@ -648,7 +648,7 @@ static int live_emit_pte_full_ring(void *arg)
*/
pr_info("%s emite_pte ring space=%u\n", __func__, rq->ring->space);
it = sg_sgt(obj->mm.pages->sgl);
- len = emit_pte(rq, &it, obj->cache_level, false, 0, CHUNK_SZ);
+ len = emit_pte(rq, &it, obj->pat_index, false, 0, CHUNK_SZ);
if (!len) {
err = -EINVAL;
goto out_rq;
@@ -844,7 +844,7 @@ static int wrap_ktime_compare(const void *A, const void *B)
static int __perf_clear_blt(struct intel_context *ce,
struct scatterlist *sg,
- enum i915_cache_level cache_level,
+ unsigned int pat_index,
bool is_lmem,
size_t sz)
{
@@ -858,7 +858,7 @@ static int __perf_clear_blt(struct intel_context *ce,
t0 = ktime_get();
- err = intel_context_migrate_clear(ce, NULL, sg, cache_level,
+ err = intel_context_migrate_clear(ce, NULL, sg, pat_index,
is_lmem, 0, &rq);
if (rq) {
if (i915_request_wait(rq, 0, MAX_SCHEDULE_TIMEOUT) < 0)
@@ -904,7 +904,8 @@ static int perf_clear_blt(void *arg)
err = __perf_clear_blt(gt->migrate.context,
dst->mm.pages->sgl,
- I915_CACHE_NONE,
+ i915_gem_get_pat_index(gt->i915,
+ I915_CACHE_NONE),
i915_gem_object_is_lmem(dst),
sizes[i]);
@@ -919,10 +920,10 @@ static int perf_clear_blt(void *arg)
static int __perf_copy_blt(struct intel_context *ce,
struct scatterlist *src,
- enum i915_cache_level src_cache_level,
+ unsigned int src_pat_index,
bool src_is_lmem,
struct scatterlist *dst,
- enum i915_cache_level dst_cache_level,
+ unsigned int dst_pat_index,
bool dst_is_lmem,
size_t sz)
{
@@ -937,9 +938,9 @@ static int __perf_copy_blt(struct intel_context *ce,
t0 = ktime_get();
err = intel_context_migrate_copy(ce, NULL,
- src, src_cache_level,
+ src, src_pat_index,
src_is_lmem,
- dst, dst_cache_level,
+ dst, dst_pat_index,
dst_is_lmem,
&rq);
if (rq) {
@@ -994,10 +995,12 @@ static int perf_copy_blt(void *arg)
err = __perf_copy_blt(gt->migrate.context,
src->mm.pages->sgl,
- I915_CACHE_NONE,
+ i915_gem_get_pat_index(gt->i915,
+ I915_CACHE_NONE),
i915_gem_object_is_lmem(src),
dst->mm.pages->sgl,
- I915_CACHE_NONE,
+ i915_gem_get_pat_index(gt->i915,
+ I915_CACHE_NONE),
i915_gem_object_is_lmem(dst),
sz);
diff --git a/drivers/gpu/drm/i915/gt/selftest_mocs.c b/drivers/gpu/drm/i915/gt/selftest_mocs.c
index ca009a6a13bd..a8446ab82501 100644
--- a/drivers/gpu/drm/i915/gt/selftest_mocs.c
+++ b/drivers/gpu/drm/i915/gt/selftest_mocs.c
@@ -131,13 +131,14 @@ static int read_mocs_table(struct i915_request *rq,
const struct drm_i915_mocs_table *table,
u32 *offset)
{
+ struct intel_gt *gt = rq->engine->gt;
u32 addr;
if (!table)
return 0;
if (HAS_GLOBAL_MOCS_REGISTERS(rq->engine->i915))
- addr = global_mocs_offset();
+ addr = global_mocs_offset() + gt->uncore->gsi_offset;
else
addr = mocs_offset(rq->engine);
diff --git a/drivers/gpu/drm/i915/gt/selftest_reset.c b/drivers/gpu/drm/i915/gt/selftest_reset.c
index a9e0a91bc0e0..79aa6ac66ad2 100644
--- a/drivers/gpu/drm/i915/gt/selftest_reset.c
+++ b/drivers/gpu/drm/i915/gt/selftest_reset.c
@@ -86,7 +86,9 @@ __igt_reset_stolen(struct intel_gt *gt,
ggtt->vm.insert_page(&ggtt->vm, dma,
ggtt->error_capture.start,
- I915_CACHE_NONE, 0);
+ i915_gem_get_pat_index(gt->i915,
+ I915_CACHE_NONE),
+ 0);
mb();
s = io_mapping_map_wc(&ggtt->iomap,
@@ -127,7 +129,9 @@ __igt_reset_stolen(struct intel_gt *gt,
ggtt->vm.insert_page(&ggtt->vm, dma,
ggtt->error_capture.start,
- I915_CACHE_NONE, 0);
+ i915_gem_get_pat_index(gt->i915,
+ I915_CACHE_NONE),
+ 0);
mb();
s = io_mapping_map_wc(&ggtt->iomap,
diff --git a/drivers/gpu/drm/i915/gt/selftest_slpc.c b/drivers/gpu/drm/i915/gt/selftest_slpc.c
index bd44ce73a504..952c8d52d68a 100644
--- a/drivers/gpu/drm/i915/gt/selftest_slpc.c
+++ b/drivers/gpu/drm/i915/gt/selftest_slpc.c
@@ -70,6 +70,31 @@ static int slpc_set_freq(struct intel_gt *gt, u32 freq)
return err;
}
+static int slpc_restore_freq(struct intel_guc_slpc *slpc, u32 min, u32 max)
+{
+ int err;
+
+ err = slpc_set_max_freq(slpc, max);
+ if (err) {
+ pr_err("Unable to restore max freq");
+ return err;
+ }
+
+ err = slpc_set_min_freq(slpc, min);
+ if (err) {
+ pr_err("Unable to restore min freq");
+ return err;
+ }
+
+ err = intel_guc_slpc_set_ignore_eff_freq(slpc, false);
+ if (err) {
+ pr_err("Unable to restore efficient freq");
+ return err;
+ }
+
+ return 0;
+}
+
static u64 measure_power_at_freq(struct intel_gt *gt, int *freq, u64 *power)
{
int err = 0;
@@ -268,8 +293,7 @@ static int run_test(struct intel_gt *gt, int test_type)
/*
* Set min frequency to RPn so that we can test the whole
- * range of RPn-RP0. This also turns off efficient freq
- * usage and makes results more predictable.
+ * range of RPn-RP0.
*/
err = slpc_set_min_freq(slpc, slpc->min_freq);
if (err) {
@@ -277,6 +301,15 @@ static int run_test(struct intel_gt *gt, int test_type)
return err;
}
+ /*
+ * Turn off efficient frequency so RPn/RP0 ranges are obeyed.
+ */
+ err = intel_guc_slpc_set_ignore_eff_freq(slpc, true);
+ if (err) {
+ pr_err("Unable to turn off efficient freq!");
+ return err;
+ }
+
intel_gt_pm_wait_for_idle(gt);
intel_gt_pm_get(gt);
for_each_engine(engine, gt, id) {
@@ -358,9 +391,8 @@ static int run_test(struct intel_gt *gt, int test_type)
break;
}
- /* Restore min/max frequencies */
- slpc_set_max_freq(slpc, slpc_max_freq);
- slpc_set_min_freq(slpc, slpc_min_freq);
+ /* Restore min/max/efficient frequencies */
+ err = slpc_restore_freq(slpc, slpc_min_freq, slpc_max_freq);
if (igt_flush_test(gt->i915))
err = -EIO;
diff --git a/drivers/gpu/drm/i915/gt/selftest_timeline.c b/drivers/gpu/drm/i915/gt/selftest_timeline.c
index 9f536c251179..39c3ec12df1a 100644
--- a/drivers/gpu/drm/i915/gt/selftest_timeline.c
+++ b/drivers/gpu/drm/i915/gt/selftest_timeline.c
@@ -836,7 +836,7 @@ static int setup_watcher(struct hwsp_watcher *w, struct intel_gt *gt,
return PTR_ERR(obj);
/* keep the same cache settings as timeline */
- i915_gem_object_set_cache_coherency(obj, tl->hwsp_ggtt->obj->cache_level);
+ i915_gem_object_set_pat_index(obj, tl->hwsp_ggtt->obj->pat_index);
w->map = i915_gem_object_pin_map_unlocked(obj,
page_unmask_bits(tl->hwsp_ggtt->obj->mm.mapping));
if (IS_ERR(w->map)) {
diff --git a/drivers/gpu/drm/i915/gt/selftest_tlb.c b/drivers/gpu/drm/i915/gt/selftest_tlb.c
index e6cac1f15d6e..4493c8518e91 100644
--- a/drivers/gpu/drm/i915/gt/selftest_tlb.c
+++ b/drivers/gpu/drm/i915/gt/selftest_tlb.c
@@ -36,6 +36,8 @@ pte_tlbinv(struct intel_context *ce,
u64 length,
struct rnd_state *prng)
{
+ const unsigned int pat_index =
+ i915_gem_get_pat_index(ce->vm->i915, I915_CACHE_NONE);
struct drm_i915_gem_object *batch;
struct drm_mm_node vb_node;
struct i915_request *rq;
@@ -155,7 +157,7 @@ pte_tlbinv(struct intel_context *ce,
/* Flip the PTE between A and B */
if (i915_gem_object_is_lmem(vb->obj))
pte_flags |= PTE_LM;
- ce->vm->insert_entries(ce->vm, &vb_res, 0, pte_flags);
+ ce->vm->insert_entries(ce->vm, &vb_res, pat_index, pte_flags);
/* Flush the PTE update to concurrent HW */
tlbinv(ce->vm, addr & -length, length);
diff --git a/drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h b/drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h
index bcb1129b3610..dabeaf4f245f 100644
--- a/drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h
+++ b/drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h
@@ -44,6 +44,7 @@ enum intel_guc_load_status {
enum intel_bootrom_load_status {
INTEL_BOOTROM_STATUS_NO_KEY_FOUND = 0x13,
INTEL_BOOTROM_STATUS_AES_PROD_KEY_FOUND = 0x1A,
+ INTEL_BOOTROM_STATUS_PROD_KEY_CHECK_FAILURE = 0x2B,
INTEL_BOOTROM_STATUS_RSA_FAILED = 0x50,
INTEL_BOOTROM_STATUS_PAVPC_FAILED = 0x73,
INTEL_BOOTROM_STATUS_WOPCM_FAILED = 0x74,
diff --git a/drivers/gpu/drm/i915/gt/uc/guc_capture_fwif.h b/drivers/gpu/drm/i915/gt/uc/guc_capture_fwif.h
index 9d589c28f40f..1fc0c17b1230 100644
--- a/drivers/gpu/drm/i915/gt/uc/guc_capture_fwif.h
+++ b/drivers/gpu/drm/i915/gt/uc/guc_capture_fwif.h
@@ -12,7 +12,7 @@
struct intel_guc;
struct file;
-/**
+/*
* struct __guc_capture_bufstate
*
* Book-keeping structure used to track read and write pointers
@@ -26,7 +26,7 @@ struct __guc_capture_bufstate {
u32 wr;
};
-/**
+/*
* struct __guc_capture_parsed_output - extracted error capture node
*
* A single unit of extracted error-capture output data grouped together
@@ -58,7 +58,7 @@ struct __guc_capture_parsed_output {
#define GCAP_PARSED_REGLIST_INDEX_ENGINST BIT(GUC_CAPTURE_LIST_TYPE_ENGINE_INSTANCE)
};
-/**
+/*
* struct guc_debug_capture_list_header / struct guc_debug_capture_list
*
* As part of ADS registration, these header structures (followed by
@@ -76,7 +76,7 @@ struct guc_debug_capture_list {
struct guc_mmio_reg regs[];
} __packed;
-/**
+/*
* struct __guc_mmio_reg_descr / struct __guc_mmio_reg_descr_group
*
* intel_guc_capture module uses these structures to maintain static
@@ -101,7 +101,7 @@ struct __guc_mmio_reg_descr_group {
struct __guc_mmio_reg_descr *extlist; /* only used for steered registers */
};
-/**
+/*
* struct guc_state_capture_header_t / struct guc_state_capture_t /
* guc_state_capture_group_header_t / guc_state_capture_group_t
*
@@ -148,7 +148,7 @@ struct guc_state_capture_group_t {
struct guc_state_capture_t capture_entries[];
} __packed;
-/**
+/*
* struct __guc_capture_ads_cache
*
* A structure to cache register lists that were populated and registered
@@ -187,6 +187,10 @@ struct intel_guc_state_capture {
struct __guc_capture_ads_cache ads_cache[GUC_CAPTURE_LIST_INDEX_MAX]
[GUC_CAPTURE_LIST_TYPE_MAX]
[GUC_MAX_ENGINE_CLASSES];
+
+ /**
+ * @ads_null_cache: ADS null cache.
+ */
void *ads_null_cache;
/**
@@ -202,6 +206,10 @@ struct intel_guc_state_capture {
struct list_head cachelist;
#define PREALLOC_NODES_MAX_COUNT (3 * GUC_MAX_ENGINE_CLASSES * GUC_MAX_INSTANCES_PER_CLASS)
#define PREALLOC_NODES_DEFAULT_NUMREGS 64
+
+ /**
+ * @max_mmio_per_node: Max MMIO per node.
+ */
int max_mmio_per_node;
/**
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
index 1d9fdfb11268..f46eb17a7a98 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
@@ -13,6 +13,7 @@
#define GSC_FW_STATUS_REG _MMIO(0x116C40)
#define GSC_FW_CURRENT_STATE REG_GENMASK(3, 0)
#define GSC_FW_CURRENT_STATE_RESET 0
+#define GSC_FW_PROXY_STATE_NORMAL 5
#define GSC_FW_INIT_COMPLETE_BIT REG_BIT(9)
static bool gsc_is_in_reset(struct intel_uncore *uncore)
@@ -23,6 +24,15 @@ static bool gsc_is_in_reset(struct intel_uncore *uncore)
GSC_FW_CURRENT_STATE_RESET;
}
+bool intel_gsc_uc_fw_proxy_init_done(struct intel_gsc_uc *gsc)
+{
+ struct intel_uncore *uncore = gsc_uc_to_gt(gsc)->uncore;
+ u32 fw_status = intel_uncore_read(uncore, GSC_FW_STATUS_REG);
+
+ return REG_FIELD_GET(GSC_FW_CURRENT_STATE, fw_status) ==
+ GSC_FW_PROXY_STATE_NORMAL;
+}
+
bool intel_gsc_uc_fw_init_done(struct intel_gsc_uc *gsc)
{
struct intel_uncore *uncore = gsc_uc_to_gt(gsc)->uncore;
@@ -110,6 +120,13 @@ static int gsc_fw_load_prepare(struct intel_gsc_uc *gsc)
if (obj->base.size < gsc->fw.size)
return -ENOSPC;
+ /*
+ * Wa_22016122933: For MTL the shared memory needs to be mapped
+ * as WC on CPU side and UC (PAT index 2) on GPU side
+ */
+ if (IS_METEORLAKE(i915))
+ i915_gem_object_set_cache_coherency(obj, I915_CACHE_NONE);
+
dst = i915_gem_object_pin_map_unlocked(obj,
i915_coherent_map_type(i915, obj, true));
if (IS_ERR(dst))
@@ -125,6 +142,12 @@ static int gsc_fw_load_prepare(struct intel_gsc_uc *gsc)
memset(dst, 0, obj->base.size);
memcpy(dst, src, gsc->fw.size);
+ /*
+ * Wa_22016122933: Making sure the data in dst is
+ * visible to GSC right away
+ */
+ intel_guc_write_barrier(&gt->uc.guc);
+
i915_gem_object_unpin_map(gsc->fw.obj);
i915_gem_object_unpin_map(obj);
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.h b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.h
index f4c1106bb2a9..fff8928218df 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.h
@@ -13,5 +13,6 @@ struct intel_uncore;
int intel_gsc_uc_fw_upload(struct intel_gsc_uc *gsc);
bool intel_gsc_uc_fw_init_done(struct intel_gsc_uc *gsc);
+bool intel_gsc_uc_fw_proxy_init_done(struct intel_gsc_uc *gsc);
#endif
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c b/drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c
new file mode 100644
index 000000000000..ebee0b5a2c1d
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c
@@ -0,0 +1,424 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2023 Intel Corporation
+ */
+
+#include <linux/component.h>
+
+#include "drm/i915_component.h"
+#include "drm/i915_gsc_proxy_mei_interface.h"
+
+#include "gt/intel_gt.h"
+#include "gt/intel_gt_print.h"
+#include "intel_gsc_proxy.h"
+#include "intel_gsc_uc.h"
+#include "intel_gsc_uc_heci_cmd_submit.h"
+#include "i915_drv.h"
+#include "i915_reg.h"
+
+/*
+ * GSC proxy:
+ * The GSC uC needs to communicate with the CSME to perform certain operations.
+ * Since the GSC can't perform this communication directly on platforms where it
+ * is integrated in GT, i915 needs to transfer the messages from GSC to CSME
+ * and back. i915 must manually start the proxy flow after the GSC is loaded to
+ * signal to GSC that we're ready to handle its messages and allow it to query
+ * its init data from CSME; GSC will then trigger an HECI2 interrupt if it needs
+ * to send messages to CSME again.
+ * The proxy flow is as follow:
+ * 1 - i915 submits a request to GSC asking for the message to CSME
+ * 2 - GSC replies with the proxy header + payload for CSME
+ * 3 - i915 sends the reply from GSC as-is to CSME via the mei proxy component
+ * 4 - CSME replies with the proxy header + payload for GSC
+ * 5 - i915 submits a request to GSC with the reply from CSME
+ * 6 - GSC replies either with a new header + payload (same as step 2, so we
+ * restart from there) or with an end message.
+ */
+
+/*
+ * The component should load quite quickly in most cases, but it could take
+ * a bit. Using a very big timeout just to cover the worst case scenario
+ */
+#define GSC_PROXY_INIT_TIMEOUT_MS 20000
+
+/* the protocol supports up to 32K in each direction */
+#define GSC_PROXY_BUFFER_SIZE SZ_32K
+#define GSC_PROXY_CHANNEL_SIZE (GSC_PROXY_BUFFER_SIZE * 2)
+#define GSC_PROXY_MAX_MSG_SIZE (GSC_PROXY_BUFFER_SIZE - sizeof(struct intel_gsc_mtl_header))
+
+/* FW-defined proxy header */
+struct intel_gsc_proxy_header {
+ /*
+ * hdr:
+ * Bits 0-7: type of the proxy message (see enum intel_gsc_proxy_type)
+ * Bits 8-15: rsvd
+ * Bits 16-31: length in bytes of the payload following the proxy header
+ */
+ u32 hdr;
+#define GSC_PROXY_TYPE GENMASK(7, 0)
+#define GSC_PROXY_PAYLOAD_LENGTH GENMASK(31, 16)
+
+ u32 source; /* Source of the Proxy message */
+ u32 destination; /* Destination of the Proxy message */
+#define GSC_PROXY_ADDRESSING_KMD 0x10000
+#define GSC_PROXY_ADDRESSING_GSC 0x20000
+#define GSC_PROXY_ADDRESSING_CSME 0x30000
+
+ u32 status; /* Command status */
+} __packed;
+
+/* FW-defined proxy types */
+enum intel_gsc_proxy_type {
+ GSC_PROXY_MSG_TYPE_PROXY_INVALID = 0,
+ GSC_PROXY_MSG_TYPE_PROXY_QUERY = 1,
+ GSC_PROXY_MSG_TYPE_PROXY_PAYLOAD = 2,
+ GSC_PROXY_MSG_TYPE_PROXY_END = 3,
+ GSC_PROXY_MSG_TYPE_PROXY_NOTIFICATION = 4,
+};
+
+struct gsc_proxy_msg {
+ struct intel_gsc_mtl_header header;
+ struct intel_gsc_proxy_header proxy_header;
+} __packed;
+
+static int proxy_send_to_csme(struct intel_gsc_uc *gsc)
+{
+ struct intel_gt *gt = gsc_uc_to_gt(gsc);
+ struct i915_gsc_proxy_component *comp = gsc->proxy.component;
+ struct intel_gsc_mtl_header *hdr;
+ void *in = gsc->proxy.to_csme;
+ void *out = gsc->proxy.to_gsc;
+ u32 in_size;
+ int ret;
+
+ /* CSME msg only includes the proxy */
+ hdr = in;
+ in += sizeof(struct intel_gsc_mtl_header);
+ out += sizeof(struct intel_gsc_mtl_header);
+
+ in_size = hdr->message_size - sizeof(struct intel_gsc_mtl_header);
+
+ /* the message must contain at least the proxy header */
+ if (in_size < sizeof(struct intel_gsc_proxy_header) ||
+ in_size > GSC_PROXY_MAX_MSG_SIZE) {
+ gt_err(gt, "Invalid CSME message size: %u\n", in_size);
+ return -EINVAL;
+ }
+
+ ret = comp->ops->send(comp->mei_dev, in, in_size);
+ if (ret < 0) {
+ gt_err(gt, "Failed to send CSME message\n");
+ return ret;
+ }
+
+ ret = comp->ops->recv(comp->mei_dev, out, GSC_PROXY_MAX_MSG_SIZE);
+ if (ret < 0) {
+ gt_err(gt, "Failed to receive CSME message\n");
+ return ret;
+ }
+
+ return ret;
+}
+
+static int proxy_send_to_gsc(struct intel_gsc_uc *gsc)
+{
+ struct intel_gt *gt = gsc_uc_to_gt(gsc);
+ u32 *marker = gsc->proxy.to_csme; /* first dw of the reply header */
+ u64 addr_in = i915_ggtt_offset(gsc->proxy.vma);
+ u64 addr_out = addr_in + GSC_PROXY_BUFFER_SIZE;
+ u32 size = ((struct gsc_proxy_msg *)gsc->proxy.to_gsc)->header.message_size;
+ int err;
+
+ /* the message must contain at least the gsc and proxy headers */
+ if (size < sizeof(struct gsc_proxy_msg) || size > GSC_PROXY_BUFFER_SIZE) {
+ gt_err(gt, "Invalid GSC proxy message size: %u\n", size);
+ return -EINVAL;
+ }
+
+ /* clear the message marker */
+ *marker = 0;
+
+ /* make sure the marker write is flushed */
+ wmb();
+
+ /* send the request */
+ err = intel_gsc_uc_heci_cmd_submit_packet(gsc, addr_in, size,
+ addr_out, GSC_PROXY_BUFFER_SIZE);
+
+ if (!err) {
+ /* wait for the reply to show up */
+ err = wait_for(*marker != 0, 300);
+ if (err)
+ gt_err(gt, "Failed to get a proxy reply from gsc\n");
+ }
+
+ return err;
+}
+
+static int validate_proxy_header(struct intel_gsc_proxy_header *header,
+ u32 source, u32 dest)
+{
+ u32 type = FIELD_GET(GSC_PROXY_TYPE, header->hdr);
+ u32 length = FIELD_GET(GSC_PROXY_PAYLOAD_LENGTH, header->hdr);
+ int ret = 0;
+
+ if (header->destination != dest || header->source != source) {
+ ret = -ENOEXEC;
+ goto fail;
+ }
+
+ switch (type) {
+ case GSC_PROXY_MSG_TYPE_PROXY_PAYLOAD:
+ if (length > 0)
+ break;
+ fallthrough;
+ case GSC_PROXY_MSG_TYPE_PROXY_INVALID:
+ ret = -EIO;
+ goto fail;
+ default:
+ break;
+ }
+
+fail:
+ return ret;
+}
+
+static int proxy_query(struct intel_gsc_uc *gsc)
+{
+ struct intel_gt *gt = gsc_uc_to_gt(gsc);
+ struct gsc_proxy_msg *to_gsc = gsc->proxy.to_gsc;
+ struct gsc_proxy_msg *to_csme = gsc->proxy.to_csme;
+ int ret;
+
+ intel_gsc_uc_heci_cmd_emit_mtl_header(&to_gsc->header,
+ HECI_MEADDRESS_PROXY,
+ sizeof(struct gsc_proxy_msg),
+ 0);
+
+ to_gsc->proxy_header.hdr =
+ FIELD_PREP(GSC_PROXY_TYPE, GSC_PROXY_MSG_TYPE_PROXY_QUERY) |
+ FIELD_PREP(GSC_PROXY_PAYLOAD_LENGTH, 0);
+
+ to_gsc->proxy_header.source = GSC_PROXY_ADDRESSING_KMD;
+ to_gsc->proxy_header.destination = GSC_PROXY_ADDRESSING_GSC;
+ to_gsc->proxy_header.status = 0;
+
+ while (1) {
+ /* clear the GSC response header space */
+ memset(gsc->proxy.to_csme, 0, sizeof(struct gsc_proxy_msg));
+
+ /* send proxy message to GSC */
+ ret = proxy_send_to_gsc(gsc);
+ if (ret) {
+ gt_err(gt, "failed to send proxy message to GSC! %d\n", ret);
+ goto proxy_error;
+ }
+
+ /* stop if this was the last message */
+ if (FIELD_GET(GSC_PROXY_TYPE, to_csme->proxy_header.hdr) ==
+ GSC_PROXY_MSG_TYPE_PROXY_END)
+ break;
+
+ /* make sure the GSC-to-CSME proxy header is sane */
+ ret = validate_proxy_header(&to_csme->proxy_header,
+ GSC_PROXY_ADDRESSING_GSC,
+ GSC_PROXY_ADDRESSING_CSME);
+ if (ret) {
+ gt_err(gt, "invalid GSC to CSME proxy header! %d\n", ret);
+ goto proxy_error;
+ }
+
+ /* send the GSC message to the CSME */
+ ret = proxy_send_to_csme(gsc);
+ if (ret < 0) {
+ gt_err(gt, "failed to send proxy message to CSME! %d\n", ret);
+ goto proxy_error;
+ }
+
+ /* update the GSC message size with the returned value from CSME */
+ to_gsc->header.message_size = ret + sizeof(struct intel_gsc_mtl_header);
+
+ /* make sure the CSME-to-GSC proxy header is sane */
+ ret = validate_proxy_header(&to_gsc->proxy_header,
+ GSC_PROXY_ADDRESSING_CSME,
+ GSC_PROXY_ADDRESSING_GSC);
+ if (ret) {
+ gt_err(gt, "invalid CSME to GSC proxy header! %d\n", ret);
+ goto proxy_error;
+ }
+ }
+
+proxy_error:
+ return ret < 0 ? ret : 0;
+}
+
+int intel_gsc_proxy_request_handler(struct intel_gsc_uc *gsc)
+{
+ struct intel_gt *gt = gsc_uc_to_gt(gsc);
+ int err;
+
+ if (!gsc->proxy.component_added)
+ return -ENODEV;
+
+ assert_rpm_wakelock_held(gt->uncore->rpm);
+
+ /* when GSC is loaded, we can queue this before the component is bound */
+ err = wait_for(gsc->proxy.component, GSC_PROXY_INIT_TIMEOUT_MS);
+ if (err) {
+ gt_err(gt, "GSC proxy component didn't bind within the expected timeout\n");
+ return -EIO;
+ }
+
+ mutex_lock(&gsc->proxy.mutex);
+ if (!gsc->proxy.component) {
+ gt_err(gt, "GSC proxy worker called without the component being bound!\n");
+ err = -EIO;
+ } else {
+ /*
+ * write the status bit to clear it and allow new proxy
+ * interrupts to be generated while we handle the current
+ * request, but be sure not to write the reset bit
+ */
+ intel_uncore_rmw(gt->uncore, HECI_H_CSR(MTL_GSC_HECI2_BASE),
+ HECI_H_CSR_RST, HECI_H_CSR_IS);
+ err = proxy_query(gsc);
+ }
+ mutex_unlock(&gsc->proxy.mutex);
+ return err;
+}
+
+void intel_gsc_proxy_irq_handler(struct intel_gsc_uc *gsc, u32 iir)
+{
+ struct intel_gt *gt = gsc_uc_to_gt(gsc);
+
+ if (unlikely(!iir))
+ return;
+
+ lockdep_assert_held(gt->irq_lock);
+
+ if (!gsc->proxy.component) {
+ gt_err(gt, "GSC proxy irq received without the component being bound!\n");
+ return;
+ }
+
+ gsc->gsc_work_actions |= GSC_ACTION_SW_PROXY;
+ queue_work(gsc->wq, &gsc->work);
+}
+
+static int i915_gsc_proxy_component_bind(struct device *i915_kdev,
+ struct device *mei_kdev, void *data)
+{
+ struct drm_i915_private *i915 = kdev_to_i915(i915_kdev);
+ struct intel_gt *gt = i915->media_gt;
+ struct intel_gsc_uc *gsc = &gt->uc.gsc;
+ intel_wakeref_t wakeref;
+
+ /* enable HECI2 IRQs */
+ with_intel_runtime_pm(&i915->runtime_pm, wakeref)
+ intel_uncore_rmw(gt->uncore, HECI_H_CSR(MTL_GSC_HECI2_BASE),
+ HECI_H_CSR_RST, HECI_H_CSR_IE);
+
+ mutex_lock(&gsc->proxy.mutex);
+ gsc->proxy.component = data;
+ gsc->proxy.component->mei_dev = mei_kdev;
+ mutex_unlock(&gsc->proxy.mutex);
+
+ return 0;
+}
+
+static void i915_gsc_proxy_component_unbind(struct device *i915_kdev,
+ struct device *mei_kdev, void *data)
+{
+ struct drm_i915_private *i915 = kdev_to_i915(i915_kdev);
+ struct intel_gt *gt = i915->media_gt;
+ struct intel_gsc_uc *gsc = &gt->uc.gsc;
+ intel_wakeref_t wakeref;
+
+ mutex_lock(&gsc->proxy.mutex);
+ gsc->proxy.component = NULL;
+ mutex_unlock(&gsc->proxy.mutex);
+
+ /* disable HECI2 IRQs */
+ with_intel_runtime_pm(&i915->runtime_pm, wakeref)
+ intel_uncore_rmw(gt->uncore, HECI_H_CSR(MTL_GSC_HECI2_BASE),
+ HECI_H_CSR_IE | HECI_H_CSR_RST, 0);
+}
+
+static const struct component_ops i915_gsc_proxy_component_ops = {
+ .bind = i915_gsc_proxy_component_bind,
+ .unbind = i915_gsc_proxy_component_unbind,
+};
+
+static int proxy_channel_alloc(struct intel_gsc_uc *gsc)
+{
+ struct intel_gt *gt = gsc_uc_to_gt(gsc);
+ struct i915_vma *vma;
+ void *vaddr;
+ int err;
+
+ err = intel_guc_allocate_and_map_vma(&gt->uc.guc, GSC_PROXY_CHANNEL_SIZE,
+ &vma, &vaddr);
+ if (err)
+ return err;
+
+ gsc->proxy.vma = vma;
+ gsc->proxy.to_gsc = vaddr;
+ gsc->proxy.to_csme = vaddr + GSC_PROXY_BUFFER_SIZE;
+
+ return 0;
+}
+
+static void proxy_channel_free(struct intel_gsc_uc *gsc)
+{
+ if (!gsc->proxy.vma)
+ return;
+
+ gsc->proxy.to_gsc = NULL;
+ gsc->proxy.to_csme = NULL;
+ i915_vma_unpin_and_release(&gsc->proxy.vma, I915_VMA_RELEASE_MAP);
+}
+
+void intel_gsc_proxy_fini(struct intel_gsc_uc *gsc)
+{
+ struct intel_gt *gt = gsc_uc_to_gt(gsc);
+ struct drm_i915_private *i915 = gt->i915;
+
+ if (fetch_and_zero(&gsc->proxy.component_added))
+ component_del(i915->drm.dev, &i915_gsc_proxy_component_ops);
+
+ proxy_channel_free(gsc);
+}
+
+int intel_gsc_proxy_init(struct intel_gsc_uc *gsc)
+{
+ int err;
+ struct intel_gt *gt = gsc_uc_to_gt(gsc);
+ struct drm_i915_private *i915 = gt->i915;
+
+ mutex_init(&gsc->proxy.mutex);
+
+ if (!IS_ENABLED(CONFIG_INTEL_MEI_GSC_PROXY)) {
+ gt_info(gt, "can't init GSC proxy due to missing mei component\n");
+ return -ENODEV;
+ }
+
+ err = proxy_channel_alloc(gsc);
+ if (err)
+ return err;
+
+ err = component_add_typed(i915->drm.dev, &i915_gsc_proxy_component_ops,
+ I915_COMPONENT_GSC_PROXY);
+ if (err < 0) {
+ gt_err(gt, "Failed to add GSC_PROXY component (%d)\n", err);
+ goto out_free;
+ }
+
+ gsc->proxy.component_added = true;
+
+ return 0;
+
+out_free:
+ proxy_channel_free(gsc);
+ return err;
+}
+
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.h b/drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.h
new file mode 100644
index 000000000000..fc5aef10bfb4
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2023 Intel Corporation
+ */
+
+#ifndef _INTEL_GSC_PROXY_H_
+#define _INTEL_GSC_PROXY_H_
+
+#include <linux/types.h>
+
+struct intel_gsc_uc;
+
+int intel_gsc_proxy_init(struct intel_gsc_uc *gsc);
+void intel_gsc_proxy_fini(struct intel_gsc_uc *gsc);
+int intel_gsc_proxy_request_handler(struct intel_gsc_uc *gsc);
+void intel_gsc_proxy_irq_handler(struct intel_gsc_uc *gsc, u32 iir);
+
+#endif
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
index 2d5b70b3384c..fb0984f875f9 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
@@ -10,15 +10,60 @@
#include "intel_gsc_uc.h"
#include "intel_gsc_fw.h"
#include "i915_drv.h"
+#include "intel_gsc_proxy.h"
static void gsc_work(struct work_struct *work)
{
struct intel_gsc_uc *gsc = container_of(work, typeof(*gsc), work);
struct intel_gt *gt = gsc_uc_to_gt(gsc);
intel_wakeref_t wakeref;
+ u32 actions;
+ int ret;
+
+ wakeref = intel_runtime_pm_get(gt->uncore->rpm);
+
+ spin_lock_irq(gt->irq_lock);
+ actions = gsc->gsc_work_actions;
+ gsc->gsc_work_actions = 0;
+ spin_unlock_irq(gt->irq_lock);
+
+ if (actions & GSC_ACTION_FW_LOAD) {
+ ret = intel_gsc_uc_fw_upload(gsc);
+ if (ret == -EEXIST) /* skip proxy if not a new load */
+ actions &= ~GSC_ACTION_FW_LOAD;
+ else if (ret)
+ goto out_put;
+ }
+
+ if (actions & (GSC_ACTION_FW_LOAD | GSC_ACTION_SW_PROXY)) {
+ if (!intel_gsc_uc_fw_init_done(gsc)) {
+ gt_err(gt, "Proxy request received with GSC not loaded!\n");
+ goto out_put;
+ }
+
+ ret = intel_gsc_proxy_request_handler(gsc);
+ if (ret)
+ goto out_put;
+
+ /* mark the GSC FW init as done the first time we run this */
+ if (actions & GSC_ACTION_FW_LOAD) {
+ /*
+ * If there is a proxy establishment error, the GSC might still
+ * complete the request handling cleanly, so we need to check the
+ * status register to check if the proxy init was actually successful
+ */
+ if (intel_gsc_uc_fw_proxy_init_done(gsc)) {
+ drm_dbg(&gt->i915->drm, "GSC Proxy initialized\n");
+ intel_uc_fw_change_status(&gsc->fw, INTEL_UC_FIRMWARE_RUNNING);
+ } else {
+ drm_err(&gt->i915->drm,
+ "GSC status reports proxy init not complete\n");
+ }
+ }
+ }
- with_intel_runtime_pm(gt->uncore->rpm, wakeref)
- intel_gsc_uc_fw_upload(gsc);
+out_put:
+ intel_runtime_pm_put(gt->uncore->rpm, wakeref);
}
static bool gsc_engine_supported(struct intel_gt *gt)
@@ -43,6 +88,8 @@ static bool gsc_engine_supported(struct intel_gt *gt)
void intel_gsc_uc_init_early(struct intel_gsc_uc *gsc)
{
+ struct intel_gt *gt = gsc_uc_to_gt(gsc);
+
intel_uc_fw_init_early(&gsc->fw, INTEL_UC_FW_TYPE_GSC);
INIT_WORK(&gsc->work, gsc_work);
@@ -50,10 +97,16 @@ void intel_gsc_uc_init_early(struct intel_gsc_uc *gsc)
* GT with it being not fully setup hence check device info's
* engine mask
*/
- if (!gsc_engine_supported(gsc_uc_to_gt(gsc))) {
+ if (!gsc_engine_supported(gt)) {
intel_uc_fw_change_status(&gsc->fw, INTEL_UC_FIRMWARE_NOT_SUPPORTED);
return;
}
+
+ gsc->wq = alloc_ordered_workqueue("i915_gsc", 0);
+ if (!gsc->wq) {
+ gt_err(gt, "failed to allocate WQ for GSC, disabling FW\n");
+ intel_uc_fw_change_status(&gsc->fw, INTEL_UC_FIRMWARE_NOT_SUPPORTED);
+ }
}
int intel_gsc_uc_init(struct intel_gsc_uc *gsc)
@@ -88,6 +141,9 @@ int intel_gsc_uc_init(struct intel_gsc_uc *gsc)
gsc->ce = ce;
+ /* if we fail to init proxy we still want to load GSC for PM */
+ intel_gsc_proxy_init(gsc);
+
intel_uc_fw_change_status(&gsc->fw, INTEL_UC_FIRMWARE_LOADABLE);
return 0;
@@ -107,6 +163,12 @@ void intel_gsc_uc_fini(struct intel_gsc_uc *gsc)
return;
flush_work(&gsc->work);
+ if (gsc->wq) {
+ destroy_workqueue(gsc->wq);
+ gsc->wq = NULL;
+ }
+
+ intel_gsc_proxy_fini(gsc);
if (gsc->ce)
intel_engine_destroy_pinned_context(fetch_and_zero(&gsc->ce));
@@ -145,11 +207,17 @@ void intel_gsc_uc_resume(struct intel_gsc_uc *gsc)
void intel_gsc_uc_load_start(struct intel_gsc_uc *gsc)
{
+ struct intel_gt *gt = gsc_uc_to_gt(gsc);
+
if (!intel_uc_fw_is_loadable(&gsc->fw))
return;
if (intel_gsc_uc_fw_init_done(gsc))
return;
- queue_work(system_unbound_wq, &gsc->work);
+ spin_lock_irq(gt->irq_lock);
+ gsc->gsc_work_actions |= GSC_ACTION_FW_LOAD;
+ spin_unlock_irq(gt->irq_lock);
+
+ queue_work(gsc->wq, &gsc->work);
}
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.h b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.h
index 5f50fa1ff8b9..a2a0813b8a76 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.h
@@ -10,6 +10,7 @@
struct i915_vma;
struct intel_context;
+struct i915_gsc_proxy_component;
struct intel_gsc_uc {
/* Generic uC firmware management */
@@ -19,7 +20,21 @@ struct intel_gsc_uc {
struct i915_vma *local; /* private memory for GSC usage */
struct intel_context *ce; /* for submission to GSC FW via GSC engine */
- struct work_struct work; /* for delayed load */
+ /* for delayed load and proxy handling */
+ struct workqueue_struct *wq;
+ struct work_struct work;
+ u32 gsc_work_actions; /* protected by gt->irq_lock */
+#define GSC_ACTION_FW_LOAD BIT(0)
+#define GSC_ACTION_SW_PROXY BIT(1)
+
+ struct {
+ struct i915_gsc_proxy_component *component;
+ bool component_added;
+ struct i915_vma *vma;
+ void *to_gsc;
+ void *to_csme;
+ struct mutex mutex; /* protects the tee channel binding */
+ } proxy;
};
void intel_gsc_uc_init_early(struct intel_gsc_uc *gsc);
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_heci_cmd_submit.c b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_heci_cmd_submit.c
index ea0da06e2f39..579c0f5a1438 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_heci_cmd_submit.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_heci_cmd_submit.c
@@ -3,6 +3,7 @@
* Copyright © 2023 Intel Corporation
*/
+#include "gt/intel_context.h"
#include "gt/intel_engine_pm.h"
#include "gt/intel_gpu_commands.h"
#include "gt/intel_gt.h"
@@ -107,3 +108,104 @@ void intel_gsc_uc_heci_cmd_emit_mtl_header(struct intel_gsc_mtl_header *header,
header->header_version = MTL_GSC_HEADER_VERSION;
header->message_size = message_size;
}
+
+static void
+emit_gsc_heci_pkt_nonpriv(u32 *cmd, struct intel_gsc_heci_non_priv_pkt *pkt)
+{
+ *cmd++ = GSC_HECI_CMD_PKT;
+ *cmd++ = lower_32_bits(pkt->addr_in);
+ *cmd++ = upper_32_bits(pkt->addr_in);
+ *cmd++ = pkt->size_in;
+ *cmd++ = lower_32_bits(pkt->addr_out);
+ *cmd++ = upper_32_bits(pkt->addr_out);
+ *cmd++ = pkt->size_out;
+ *cmd++ = 0;
+ *cmd++ = MI_BATCH_BUFFER_END;
+}
+
+int
+intel_gsc_uc_heci_cmd_submit_nonpriv(struct intel_gsc_uc *gsc,
+ struct intel_context *ce,
+ struct intel_gsc_heci_non_priv_pkt *pkt,
+ u32 *cmd, int timeout_ms)
+{
+ struct intel_engine_cs *engine;
+ struct i915_gem_ww_ctx ww;
+ struct i915_request *rq;
+ int err, trials = 0;
+
+ i915_gem_ww_ctx_init(&ww, false);
+retry:
+ err = i915_gem_object_lock(pkt->bb_vma->obj, &ww);
+ if (err)
+ goto out_ww;
+ err = i915_gem_object_lock(pkt->heci_pkt_vma->obj, &ww);
+ if (err)
+ goto out_ww;
+ err = intel_context_pin_ww(ce, &ww);
+ if (err)
+ goto out_ww;
+
+ rq = i915_request_create(ce);
+ if (IS_ERR(rq)) {
+ err = PTR_ERR(rq);
+ goto out_unpin_ce;
+ }
+
+ emit_gsc_heci_pkt_nonpriv(cmd, pkt);
+
+ err = i915_vma_move_to_active(pkt->bb_vma, rq, 0);
+ if (err)
+ goto out_rq;
+ err = i915_vma_move_to_active(pkt->heci_pkt_vma, rq, EXEC_OBJECT_WRITE);
+ if (err)
+ goto out_rq;
+
+ engine = rq->context->engine;
+ if (engine->emit_init_breadcrumb) {
+ err = engine->emit_init_breadcrumb(rq);
+ if (err)
+ goto out_rq;
+ }
+
+ err = engine->emit_bb_start(rq, i915_vma_offset(pkt->bb_vma), PAGE_SIZE, 0);
+ if (err)
+ goto out_rq;
+
+ err = ce->engine->emit_flush(rq, 0);
+ if (err)
+ drm_err(&gsc_uc_to_gt(gsc)->i915->drm,
+ "Failed emit-flush for gsc-heci-non-priv-pkterr=%d\n", err);
+
+out_rq:
+ i915_request_get(rq);
+
+ if (unlikely(err))
+ i915_request_set_error_once(rq, err);
+
+ i915_request_add(rq);
+
+ if (!err) {
+ if (i915_request_wait(rq, I915_WAIT_INTERRUPTIBLE,
+ msecs_to_jiffies(timeout_ms)) < 0)
+ err = -ETIME;
+ }
+
+ i915_request_put(rq);
+
+out_unpin_ce:
+ intel_context_unpin(ce);
+out_ww:
+ if (err == -EDEADLK) {
+ err = i915_gem_ww_ctx_backoff(&ww);
+ if (!err) {
+ if (++trials < 10)
+ goto retry;
+ else
+ err = EAGAIN;
+ }
+ }
+ i915_gem_ww_ctx_fini(&ww);
+
+ return err;
+}
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_heci_cmd_submit.h b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_heci_cmd_submit.h
index 3d56ae501991..ef70e304904a 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_heci_cmd_submit.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_heci_cmd_submit.h
@@ -8,12 +8,16 @@
#include <linux/types.h>
+struct i915_vma;
+struct intel_context;
struct intel_gsc_uc;
+
struct intel_gsc_mtl_header {
u32 validity_marker;
#define GSC_HECI_VALIDITY_MARKER 0xA578875A
u8 heci_client_id;
+#define HECI_MEADDRESS_PROXY 10
#define HECI_MEADDRESS_PXP 17
#define HECI_MEADDRESS_HDCP 18
@@ -47,7 +51,8 @@ struct intel_gsc_mtl_header {
* we distinguish the flags using OUTFLAG or INFLAG
*/
u32 flags;
-#define GSC_OUTFLAG_MSG_PENDING 1
+#define GSC_OUTFLAG_MSG_PENDING BIT(0)
+#define GSC_INFLAG_MSG_CLEANUP BIT(1)
u32 status;
} __packed;
@@ -58,4 +63,24 @@ int intel_gsc_uc_heci_cmd_submit_packet(struct intel_gsc_uc *gsc,
void intel_gsc_uc_heci_cmd_emit_mtl_header(struct intel_gsc_mtl_header *header,
u8 heci_client_id, u32 message_size,
u64 host_session_id);
+
+struct intel_gsc_heci_non_priv_pkt {
+ u64 addr_in;
+ u32 size_in;
+ u64 addr_out;
+ u32 size_out;
+ struct i915_vma *heci_pkt_vma;
+ struct i915_vma *bb_vma;
+};
+
+void
+intel_gsc_uc_heci_cmd_emit_mtl_header(struct intel_gsc_mtl_header *header,
+ u8 heci_client_id, u32 msg_size,
+ u64 host_session_id);
+
+int
+intel_gsc_uc_heci_cmd_submit_nonpriv(struct intel_gsc_uc *gsc,
+ struct intel_context *ce,
+ struct intel_gsc_heci_non_priv_pkt *pkt,
+ u32 *cs, int timeout_ms);
#endif
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
index e89f16ecf1ae..c9f20385f6a0 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
@@ -744,6 +744,13 @@ struct i915_vma *intel_guc_allocate_vma(struct intel_guc *guc, u32 size)
if (IS_ERR(obj))
return ERR_CAST(obj);
+ /*
+ * Wa_22016122933: For MTL the shared memory needs to be mapped
+ * as WC on CPU side and UC (PAT index 2) on GPU side
+ */
+ if (IS_METEORLAKE(gt->i915))
+ i915_gem_object_set_cache_coherency(obj, I915_CACHE_NONE);
+
vma = i915_vma_instance(obj, &gt->ggtt->vm, NULL);
if (IS_ERR(vma))
goto err;
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
index e46aac1a41e6..8dc291ff0093 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -42,6 +42,7 @@ struct intel_guc {
/** @capture: the error-state-capture module's data and objects */
struct intel_guc_state_capture *capture;
+ /** @dbgfs_node: debugfs node */
struct dentry *dbgfs_node;
/** @sched_engine: Global engine used to submit requests to GuC */
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
index 69ce06faf8cd..63724e17829a 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -643,6 +643,39 @@ static void guc_init_golden_context(struct intel_guc *guc)
GEM_BUG_ON(guc->ads_golden_ctxt_size != total_size);
}
+static u32 guc_get_capture_engine_mask(struct iosys_map *info_map, u32 capture_class)
+{
+ u32 mask;
+
+ switch (capture_class) {
+ case GUC_CAPTURE_LIST_CLASS_RENDER_COMPUTE:
+ mask = info_map_read(info_map, engine_enabled_masks[GUC_RENDER_CLASS]);
+ mask |= info_map_read(info_map, engine_enabled_masks[GUC_COMPUTE_CLASS]);
+ break;
+
+ case GUC_CAPTURE_LIST_CLASS_VIDEO:
+ mask = info_map_read(info_map, engine_enabled_masks[GUC_VIDEO_CLASS]);
+ break;
+
+ case GUC_CAPTURE_LIST_CLASS_VIDEOENHANCE:
+ mask = info_map_read(info_map, engine_enabled_masks[GUC_VIDEOENHANCE_CLASS]);
+ break;
+
+ case GUC_CAPTURE_LIST_CLASS_BLITTER:
+ mask = info_map_read(info_map, engine_enabled_masks[GUC_BLITTER_CLASS]);
+ break;
+
+ case GUC_CAPTURE_LIST_CLASS_GSC_OTHER:
+ mask = info_map_read(info_map, engine_enabled_masks[GUC_GSC_OTHER_CLASS]);
+ break;
+
+ default:
+ mask = 0;
+ }
+
+ return mask;
+}
+
static int
guc_capture_prep_lists(struct intel_guc *guc)
{
@@ -678,9 +711,10 @@ guc_capture_prep_lists(struct intel_guc *guc)
for (i = 0; i < GUC_CAPTURE_LIST_INDEX_MAX; i++) {
for (j = 0; j < GUC_MAX_ENGINE_CLASSES; j++) {
+ u32 engine_mask = guc_get_capture_engine_mask(&info_map, j);
/* null list if we dont have said engine or list */
- if (!info_map_read(&info_map, engine_enabled_masks[j])) {
+ if (!engine_mask) {
if (ads_is_mapped) {
ads_blob_write(guc, ads.capture_class[i][j], null_ggtt);
ads_blob_write(guc, ads.capture_instance[i][j], null_ggtt);
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
index cf49188db6a6..0ff864da92df 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
@@ -30,13 +30,15 @@
#define COMMON_BASE_GLOBAL \
{ FORCEWAKE_MT, 0, 0, "FORCEWAKE" }
-#define COMMON_GEN9BASE_GLOBAL \
- { GEN8_FAULT_TLB_DATA0, 0, 0, "GEN8_FAULT_TLB_DATA0" }, \
- { GEN8_FAULT_TLB_DATA1, 0, 0, "GEN8_FAULT_TLB_DATA1" }, \
+#define COMMON_GEN8BASE_GLOBAL \
{ ERROR_GEN6, 0, 0, "ERROR_GEN6" }, \
{ DONE_REG, 0, 0, "DONE_REG" }, \
{ HSW_GTT_CACHE_EN, 0, 0, "HSW_GTT_CACHE_EN" }
+#define GEN8_GLOBAL \
+ { GEN8_FAULT_TLB_DATA0, 0, 0, "GEN8_FAULT_TLB_DATA0" }, \
+ { GEN8_FAULT_TLB_DATA1, 0, 0, "GEN8_FAULT_TLB_DATA1" }
+
#define COMMON_GEN12BASE_GLOBAL \
{ GEN12_FAULT_TLB_DATA0, 0, 0, "GEN12_FAULT_TLB_DATA0" }, \
{ GEN12_FAULT_TLB_DATA1, 0, 0, "GEN12_FAULT_TLB_DATA1" }, \
@@ -94,66 +96,65 @@
{ GEN12_SFC_DONE(2), 0, 0, "SFC_DONE[2]" }, \
{ GEN12_SFC_DONE(3), 0, 0, "SFC_DONE[3]" }
-/* XE_LPD - Global */
-static const struct __guc_mmio_reg_descr xe_lpd_global_regs[] = {
+/* XE_LP Global */
+static const struct __guc_mmio_reg_descr xe_lp_global_regs[] = {
COMMON_BASE_GLOBAL,
- COMMON_GEN9BASE_GLOBAL,
+ COMMON_GEN8BASE_GLOBAL,
COMMON_GEN12BASE_GLOBAL,
};
-/* XE_LPD - Render / Compute Per-Class */
-static const struct __guc_mmio_reg_descr xe_lpd_rc_class_regs[] = {
+/* XE_LP Render / Compute Per-Class */
+static const struct __guc_mmio_reg_descr xe_lp_rc_class_regs[] = {
COMMON_BASE_HAS_EU,
COMMON_BASE_RENDER,
COMMON_GEN12BASE_RENDER,
};
-/* GEN9/XE_LPD - Render / Compute Per-Engine-Instance */
-static const struct __guc_mmio_reg_descr xe_lpd_rc_inst_regs[] = {
+/* GEN8+ Render / Compute Per-Engine-Instance */
+static const struct __guc_mmio_reg_descr gen8_rc_inst_regs[] = {
COMMON_BASE_ENGINE_INSTANCE,
};
-/* GEN9/XE_LPD - Media Decode/Encode Per-Engine-Instance */
-static const struct __guc_mmio_reg_descr xe_lpd_vd_inst_regs[] = {
+/* GEN8+ Media Decode/Encode Per-Engine-Instance */
+static const struct __guc_mmio_reg_descr gen8_vd_inst_regs[] = {
COMMON_BASE_ENGINE_INSTANCE,
};
-/* XE_LPD - Video Enhancement Per-Class */
-static const struct __guc_mmio_reg_descr xe_lpd_vec_class_regs[] = {
+/* XE_LP Video Enhancement Per-Class */
+static const struct __guc_mmio_reg_descr xe_lp_vec_class_regs[] = {
COMMON_GEN12BASE_VEC,
};
-/* GEN9/XE_LPD - Video Enhancement Per-Engine-Instance */
-static const struct __guc_mmio_reg_descr xe_lpd_vec_inst_regs[] = {
+/* GEN8+ Video Enhancement Per-Engine-Instance */
+static const struct __guc_mmio_reg_descr gen8_vec_inst_regs[] = {
COMMON_BASE_ENGINE_INSTANCE,
};
-/* GEN9/XE_LPD - Blitter Per-Engine-Instance */
-static const struct __guc_mmio_reg_descr xe_lpd_blt_inst_regs[] = {
+/* GEN8+ Blitter Per-Engine-Instance */
+static const struct __guc_mmio_reg_descr gen8_blt_inst_regs[] = {
COMMON_BASE_ENGINE_INSTANCE,
};
-/* XE_LPD - GSC Per-Engine-Instance */
-static const struct __guc_mmio_reg_descr xe_lpd_gsc_inst_regs[] = {
+/* XE_LP - GSC Per-Engine-Instance */
+static const struct __guc_mmio_reg_descr xe_lp_gsc_inst_regs[] = {
COMMON_BASE_ENGINE_INSTANCE,
};
-/* GEN9 - Global */
-static const struct __guc_mmio_reg_descr default_global_regs[] = {
+/* GEN8 - Global */
+static const struct __guc_mmio_reg_descr gen8_global_regs[] = {
COMMON_BASE_GLOBAL,
- COMMON_GEN9BASE_GLOBAL,
+ COMMON_GEN8BASE_GLOBAL,
+ GEN8_GLOBAL,
};
-static const struct __guc_mmio_reg_descr default_rc_class_regs[] = {
+static const struct __guc_mmio_reg_descr gen8_rc_class_regs[] = {
COMMON_BASE_HAS_EU,
COMMON_BASE_RENDER,
};
/*
- * Empty lists:
- * GEN9/XE_LPD - Blitter Per-Class
- * GEN9/XE_LPD - Media Decode/Encode Per-Class
- * GEN9 - VEC Class
+ * Empty list to prevent warnings about unknown class/instance types
+ * as not all class/instanace types have entries on all platforms.
*/
static const struct __guc_mmio_reg_descr empty_regs_list[] = {
};
@@ -171,37 +172,33 @@ static const struct __guc_mmio_reg_descr empty_regs_list[] = {
}
/* List of lists */
-static const struct __guc_mmio_reg_descr_group default_lists[] = {
- MAKE_REGLIST(default_global_regs, PF, GLOBAL, 0),
- MAKE_REGLIST(default_rc_class_regs, PF, ENGINE_CLASS, GUC_RENDER_CLASS),
- MAKE_REGLIST(xe_lpd_rc_inst_regs, PF, ENGINE_INSTANCE, GUC_RENDER_CLASS),
- MAKE_REGLIST(default_rc_class_regs, PF, ENGINE_CLASS, GUC_COMPUTE_CLASS),
- MAKE_REGLIST(xe_lpd_rc_inst_regs, PF, ENGINE_INSTANCE, GUC_COMPUTE_CLASS),
- MAKE_REGLIST(empty_regs_list, PF, ENGINE_CLASS, GUC_VIDEO_CLASS),
- MAKE_REGLIST(xe_lpd_vd_inst_regs, PF, ENGINE_INSTANCE, GUC_VIDEO_CLASS),
- MAKE_REGLIST(empty_regs_list, PF, ENGINE_CLASS, GUC_VIDEOENHANCE_CLASS),
- MAKE_REGLIST(xe_lpd_vec_inst_regs, PF, ENGINE_INSTANCE, GUC_VIDEOENHANCE_CLASS),
- MAKE_REGLIST(empty_regs_list, PF, ENGINE_CLASS, GUC_BLITTER_CLASS),
- MAKE_REGLIST(xe_lpd_blt_inst_regs, PF, ENGINE_INSTANCE, GUC_BLITTER_CLASS),
- MAKE_REGLIST(empty_regs_list, PF, ENGINE_CLASS, GUC_GSC_OTHER_CLASS),
- MAKE_REGLIST(xe_lpd_gsc_inst_regs, PF, ENGINE_INSTANCE, GUC_GSC_OTHER_CLASS),
+static const struct __guc_mmio_reg_descr_group gen8_lists[] = {
+ MAKE_REGLIST(gen8_global_regs, PF, GLOBAL, 0),
+ MAKE_REGLIST(gen8_rc_class_regs, PF, ENGINE_CLASS, GUC_CAPTURE_LIST_CLASS_RENDER_COMPUTE),
+ MAKE_REGLIST(gen8_rc_inst_regs, PF, ENGINE_INSTANCE, GUC_CAPTURE_LIST_CLASS_RENDER_COMPUTE),
+ MAKE_REGLIST(empty_regs_list, PF, ENGINE_CLASS, GUC_CAPTURE_LIST_CLASS_VIDEO),
+ MAKE_REGLIST(gen8_vd_inst_regs, PF, ENGINE_INSTANCE, GUC_CAPTURE_LIST_CLASS_VIDEO),
+ MAKE_REGLIST(empty_regs_list, PF, ENGINE_CLASS, GUC_CAPTURE_LIST_CLASS_VIDEOENHANCE),
+ MAKE_REGLIST(gen8_vec_inst_regs, PF, ENGINE_INSTANCE, GUC_CAPTURE_LIST_CLASS_VIDEOENHANCE),
+ MAKE_REGLIST(empty_regs_list, PF, ENGINE_CLASS, GUC_CAPTURE_LIST_CLASS_BLITTER),
+ MAKE_REGLIST(gen8_blt_inst_regs, PF, ENGINE_INSTANCE, GUC_CAPTURE_LIST_CLASS_BLITTER),
+ MAKE_REGLIST(empty_regs_list, PF, ENGINE_CLASS, GUC_CAPTURE_LIST_CLASS_GSC_OTHER),
+ MAKE_REGLIST(empty_regs_list, PF, ENGINE_INSTANCE, GUC_CAPTURE_LIST_CLASS_GSC_OTHER),
{}
};
-static const struct __guc_mmio_reg_descr_group xe_lpd_lists[] = {
- MAKE_REGLIST(xe_lpd_global_regs, PF, GLOBAL, 0),
- MAKE_REGLIST(xe_lpd_rc_class_regs, PF, ENGINE_CLASS, GUC_RENDER_CLASS),
- MAKE_REGLIST(xe_lpd_rc_inst_regs, PF, ENGINE_INSTANCE, GUC_RENDER_CLASS),
- MAKE_REGLIST(xe_lpd_rc_class_regs, PF, ENGINE_CLASS, GUC_COMPUTE_CLASS),
- MAKE_REGLIST(xe_lpd_rc_inst_regs, PF, ENGINE_INSTANCE, GUC_COMPUTE_CLASS),
- MAKE_REGLIST(empty_regs_list, PF, ENGINE_CLASS, GUC_VIDEO_CLASS),
- MAKE_REGLIST(xe_lpd_vd_inst_regs, PF, ENGINE_INSTANCE, GUC_VIDEO_CLASS),
- MAKE_REGLIST(xe_lpd_vec_class_regs, PF, ENGINE_CLASS, GUC_VIDEOENHANCE_CLASS),
- MAKE_REGLIST(xe_lpd_vec_inst_regs, PF, ENGINE_INSTANCE, GUC_VIDEOENHANCE_CLASS),
- MAKE_REGLIST(empty_regs_list, PF, ENGINE_CLASS, GUC_BLITTER_CLASS),
- MAKE_REGLIST(xe_lpd_blt_inst_regs, PF, ENGINE_INSTANCE, GUC_BLITTER_CLASS),
- MAKE_REGLIST(empty_regs_list, PF, ENGINE_CLASS, GUC_GSC_OTHER_CLASS),
- MAKE_REGLIST(xe_lpd_gsc_inst_regs, PF, ENGINE_INSTANCE, GUC_GSC_OTHER_CLASS),
+static const struct __guc_mmio_reg_descr_group xe_lp_lists[] = {
+ MAKE_REGLIST(xe_lp_global_regs, PF, GLOBAL, 0),
+ MAKE_REGLIST(xe_lp_rc_class_regs, PF, ENGINE_CLASS, GUC_CAPTURE_LIST_CLASS_RENDER_COMPUTE),
+ MAKE_REGLIST(gen8_rc_inst_regs, PF, ENGINE_INSTANCE, GUC_CAPTURE_LIST_CLASS_RENDER_COMPUTE),
+ MAKE_REGLIST(empty_regs_list, PF, ENGINE_CLASS, GUC_CAPTURE_LIST_CLASS_VIDEO),
+ MAKE_REGLIST(gen8_vd_inst_regs, PF, ENGINE_INSTANCE, GUC_CAPTURE_LIST_CLASS_VIDEO),
+ MAKE_REGLIST(xe_lp_vec_class_regs, PF, ENGINE_CLASS, GUC_CAPTURE_LIST_CLASS_VIDEOENHANCE),
+ MAKE_REGLIST(gen8_vec_inst_regs, PF, ENGINE_INSTANCE, GUC_CAPTURE_LIST_CLASS_VIDEOENHANCE),
+ MAKE_REGLIST(empty_regs_list, PF, ENGINE_CLASS, GUC_CAPTURE_LIST_CLASS_BLITTER),
+ MAKE_REGLIST(gen8_blt_inst_regs, PF, ENGINE_INSTANCE, GUC_CAPTURE_LIST_CLASS_BLITTER),
+ MAKE_REGLIST(empty_regs_list, PF, ENGINE_CLASS, GUC_CAPTURE_LIST_CLASS_GSC_OTHER),
+ MAKE_REGLIST(xe_lp_gsc_inst_regs, PF, ENGINE_INSTANCE, GUC_CAPTURE_LIST_CLASS_GSC_OTHER),
{}
};
@@ -257,11 +254,15 @@ struct __ext_steer_reg {
i915_mcr_reg_t reg;
};
-static const struct __ext_steer_reg xe_extregs[] = {
+static const struct __ext_steer_reg gen8_extregs[] = {
{"GEN8_SAMPLER_INSTDONE", GEN8_SAMPLER_INSTDONE},
{"GEN8_ROW_INSTDONE", GEN8_ROW_INSTDONE}
};
+static const struct __ext_steer_reg xehpg_extregs[] = {
+ {"XEHPG_INSTDONE_GEOM_SVG", XEHPG_INSTDONE_GEOM_SVG}
+};
+
static void __fill_ext_reg(struct __guc_mmio_reg_descr *ext,
const struct __ext_steer_reg *extlist,
int slice_id, int subslice_id)
@@ -292,8 +293,8 @@ __alloc_ext_regs(struct __guc_mmio_reg_descr_group *newlist,
}
static void
-guc_capture_alloc_steered_lists_xe_lpd(struct intel_guc *guc,
- const struct __guc_mmio_reg_descr_group *lists)
+guc_capture_alloc_steered_lists(struct intel_guc *guc,
+ const struct __guc_mmio_reg_descr_group *lists)
{
struct intel_gt *gt = guc_to_gt(guc);
int slice, subslice, iter, i, num_steer_regs, num_tot_regs = 0;
@@ -301,74 +302,20 @@ guc_capture_alloc_steered_lists_xe_lpd(struct intel_guc *guc,
struct __guc_mmio_reg_descr_group *extlists;
struct __guc_mmio_reg_descr *extarray;
struct sseu_dev_info *sseu;
+ bool has_xehpg_extregs;
- /* In XE_LPD we only have steered registers for the render-class */
+ /* steered registers currently only exist for the render-class */
list = guc_capture_get_one_list(lists, GUC_CAPTURE_LIST_INDEX_PF,
- GUC_CAPTURE_LIST_TYPE_ENGINE_CLASS, GUC_RENDER_CLASS);
+ GUC_CAPTURE_LIST_TYPE_ENGINE_CLASS,
+ GUC_CAPTURE_LIST_CLASS_RENDER_COMPUTE);
/* skip if extlists was previously allocated */
if (!list || guc->capture->extlists)
return;
- num_steer_regs = ARRAY_SIZE(xe_extregs);
-
- sseu = &gt->info.sseu;
- for_each_ss_steering(iter, gt, slice, subslice)
- num_tot_regs += num_steer_regs;
-
- if (!num_tot_regs)
- return;
-
- /* allocate an extra for an end marker */
- extlists = kcalloc(2, sizeof(struct __guc_mmio_reg_descr_group), GFP_KERNEL);
- if (!extlists)
- return;
+ has_xehpg_extregs = GRAPHICS_VER_FULL(gt->i915) >= IP_VER(12, 55);
- if (__alloc_ext_regs(&extlists[0], list, num_tot_regs)) {
- kfree(extlists);
- return;
- }
-
- extarray = extlists[0].extlist;
- for_each_ss_steering(iter, gt, slice, subslice) {
- for (i = 0; i < num_steer_regs; ++i) {
- __fill_ext_reg(extarray, &xe_extregs[i], slice, subslice);
- ++extarray;
- }
- }
-
- guc->capture->extlists = extlists;
-}
-
-static const struct __ext_steer_reg xehpg_extregs[] = {
- {"XEHPG_INSTDONE_GEOM_SVG", XEHPG_INSTDONE_GEOM_SVG}
-};
-
-static bool __has_xehpg_extregs(u32 ipver)
-{
- return (ipver >= IP_VER(12, 55));
-}
-
-static void
-guc_capture_alloc_steered_lists_xe_hpg(struct intel_guc *guc,
- const struct __guc_mmio_reg_descr_group *lists,
- u32 ipver)
-{
- struct intel_gt *gt = guc_to_gt(guc);
- struct sseu_dev_info *sseu;
- int slice, subslice, i, iter, num_steer_regs, num_tot_regs = 0;
- const struct __guc_mmio_reg_descr_group *list;
- struct __guc_mmio_reg_descr_group *extlists;
- struct __guc_mmio_reg_descr *extarray;
-
- /* In XE_LP / HPG we only have render-class steering registers during error-capture */
- list = guc_capture_get_one_list(lists, GUC_CAPTURE_LIST_INDEX_PF,
- GUC_CAPTURE_LIST_TYPE_ENGINE_CLASS, GUC_RENDER_CLASS);
- /* skip if extlists was previously allocated */
- if (!list || guc->capture->extlists)
- return;
-
- num_steer_regs = ARRAY_SIZE(xe_extregs);
- if (__has_xehpg_extregs(ipver))
+ num_steer_regs = ARRAY_SIZE(gen8_extregs);
+ if (has_xehpg_extregs)
num_steer_regs += ARRAY_SIZE(xehpg_extregs);
sseu = &gt->info.sseu;
@@ -390,11 +337,12 @@ guc_capture_alloc_steered_lists_xe_hpg(struct intel_guc *guc,
extarray = extlists[0].extlist;
for_each_ss_steering(iter, gt, slice, subslice) {
- for (i = 0; i < ARRAY_SIZE(xe_extregs); ++i) {
- __fill_ext_reg(extarray, &xe_extregs[i], slice, subslice);
+ for (i = 0; i < ARRAY_SIZE(gen8_extregs); ++i) {
+ __fill_ext_reg(extarray, &gen8_extregs[i], slice, subslice);
++extarray;
}
- if (__has_xehpg_extregs(ipver)) {
+
+ if (has_xehpg_extregs) {
for (i = 0; i < ARRAY_SIZE(xehpg_extregs); ++i) {
__fill_ext_reg(extarray, &xehpg_extregs[i], slice, subslice);
++extarray;
@@ -410,26 +358,22 @@ static const struct __guc_mmio_reg_descr_group *
guc_capture_get_device_reglist(struct intel_guc *guc)
{
struct drm_i915_private *i915 = guc_to_gt(guc)->i915;
+ const struct __guc_mmio_reg_descr_group *lists;
- if (GRAPHICS_VER(i915) > 11) {
- /*
- * For certain engine classes, there are slice and subslice
- * level registers requiring steering. We allocate and populate
- * these at init time based on hw config add it as an extension
- * list at the end of the pre-populated render list.
- */
- if (IS_DG2(i915))
- guc_capture_alloc_steered_lists_xe_hpg(guc, xe_lpd_lists, IP_VER(12, 55));
- else if (IS_XEHPSDV(i915))
- guc_capture_alloc_steered_lists_xe_hpg(guc, xe_lpd_lists, IP_VER(12, 50));
- else
- guc_capture_alloc_steered_lists_xe_lpd(guc, xe_lpd_lists);
+ if (GRAPHICS_VER(i915) >= 12)
+ lists = xe_lp_lists;
+ else
+ lists = gen8_lists;
- return xe_lpd_lists;
- }
+ /*
+ * For certain engine classes, there are slice and subslice
+ * level registers requiring steering. We allocate and populate
+ * these at init time based on hw config add it as an extension
+ * list at the end of the pre-populated render list.
+ */
+ guc_capture_alloc_steered_lists(guc, lists);
- /* if GuC submission is enabled on a non-POR platform, just use a common baseline */
- return default_lists;
+ return lists;
}
static const char *
@@ -453,17 +397,15 @@ static const char *
__stringify_engclass(u32 class)
{
switch (class) {
- case GUC_RENDER_CLASS:
- return "Render";
- case GUC_VIDEO_CLASS:
+ case GUC_CAPTURE_LIST_CLASS_RENDER_COMPUTE:
+ return "Render/Compute";
+ case GUC_CAPTURE_LIST_CLASS_VIDEO:
return "Video";
- case GUC_VIDEOENHANCE_CLASS:
+ case GUC_CAPTURE_LIST_CLASS_VIDEOENHANCE:
return "VideoEnhance";
- case GUC_BLITTER_CLASS:
+ case GUC_CAPTURE_LIST_CLASS_BLITTER:
return "Blitter";
- case GUC_COMPUTE_CLASS:
- return "Compute";
- case GUC_GSC_OTHER_CLASS:
+ case GUC_CAPTURE_LIST_CLASS_GSC_OTHER:
return "GSC-Other";
default:
break;
@@ -1593,6 +1535,36 @@ void intel_guc_capture_free_node(struct intel_engine_coredump *ee)
ee->guc_capture_node = NULL;
}
+bool intel_guc_capture_is_matching_engine(struct intel_gt *gt,
+ struct intel_context *ce,
+ struct intel_engine_cs *engine)
+{
+ struct __guc_capture_parsed_output *n;
+ struct intel_guc *guc;
+
+ if (!gt || !ce || !engine)
+ return false;
+
+ guc = &gt->uc.guc;
+ if (!guc->capture)
+ return false;
+
+ /*
+ * Look for a matching GuC reported error capture node from
+ * the internal output link-list based on lrca, guc-id and engine
+ * identification.
+ */
+ list_for_each_entry(n, &guc->capture->outlist, link) {
+ if (n->eng_inst == GUC_ID_TO_ENGINE_INSTANCE(engine->guc_id) &&
+ n->eng_class == GUC_ID_TO_ENGINE_CLASS(engine->guc_id) &&
+ n->guc_id == ce->guc_id.id &&
+ (n->lrca & CTX_GTT_ADDRESS_MASK) == (ce->lrc.lrca & CTX_GTT_ADDRESS_MASK))
+ return true;
+ }
+
+ return false;
+}
+
void intel_guc_capture_get_matching_node(struct intel_gt *gt,
struct intel_engine_coredump *ee,
struct intel_context *ce)
@@ -1608,6 +1580,7 @@ void intel_guc_capture_get_matching_node(struct intel_gt *gt,
return;
GEM_BUG_ON(ee->guc_capture_node);
+
/*
* Look for a matching GuC reported error capture node from
* the internal output link-list based on lrca, guc-id and engine
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.h
index fbd3713c7832..302256d45431 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.h
@@ -11,6 +11,7 @@
struct drm_i915_error_state_buf;
struct guc_gt_system_info;
struct intel_engine_coredump;
+struct intel_engine_cs;
struct intel_context;
struct intel_gt;
struct intel_guc;
@@ -20,6 +21,8 @@ int intel_guc_capture_print_engine_node(struct drm_i915_error_state_buf *m,
const struct intel_engine_coredump *ee);
void intel_guc_capture_get_matching_node(struct intel_gt *gt, struct intel_engine_coredump *ee,
struct intel_context *ce);
+bool intel_guc_capture_is_matching_engine(struct intel_gt *gt, struct intel_context *ce,
+ struct intel_engine_cs *engine);
void intel_guc_capture_process(struct intel_guc *guc);
int intel_guc_capture_getlist(struct intel_guc *guc, u32 owner, u32 type, u32 classid,
void **outptr);
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
index 1803a633ed64..a22e33f37cae 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
@@ -13,6 +13,30 @@
#include "intel_guc_ct.h"
#include "intel_guc_print.h"
+#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GUC)
+enum {
+ CT_DEAD_ALIVE = 0,
+ CT_DEAD_SETUP,
+ CT_DEAD_WRITE,
+ CT_DEAD_DEADLOCK,
+ CT_DEAD_H2G_HAS_ROOM,
+ CT_DEAD_READ,
+ CT_DEAD_PROCESS_FAILED,
+};
+
+static void ct_dead_ct_worker_func(struct work_struct *w);
+
+#define CT_DEAD(ct, reason) \
+ do { \
+ if (!(ct)->dead_ct_reported) { \
+ (ct)->dead_ct_reason |= 1 << CT_DEAD_##reason; \
+ queue_work(system_unbound_wq, &(ct)->dead_ct_worker); \
+ } \
+ } while (0)
+#else
+#define CT_DEAD(ct, reason) do { } while (0)
+#endif
+
static inline struct intel_guc *ct_to_guc(struct intel_guc_ct *ct)
{
return container_of(ct, struct intel_guc, ct);
@@ -93,6 +117,9 @@ void intel_guc_ct_init_early(struct intel_guc_ct *ct)
spin_lock_init(&ct->requests.lock);
INIT_LIST_HEAD(&ct->requests.pending);
INIT_LIST_HEAD(&ct->requests.incoming);
+#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GUC)
+ INIT_WORK(&ct->dead_ct_worker, ct_dead_ct_worker_func);
+#endif
INIT_WORK(&ct->requests.worker, ct_incoming_request_worker_func);
tasklet_setup(&ct->receive_tasklet, ct_receive_tasklet_func);
init_waitqueue_head(&ct->wq);
@@ -319,11 +346,16 @@ int intel_guc_ct_enable(struct intel_guc_ct *ct)
ct->enabled = true;
ct->stall_time = KTIME_MAX;
+#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GUC)
+ ct->dead_ct_reported = false;
+ ct->dead_ct_reason = CT_DEAD_ALIVE;
+#endif
return 0;
err_out:
CT_PROBE_ERROR(ct, "Failed to enable CTB (%pe)\n", ERR_PTR(err));
+ CT_DEAD(ct, SETUP);
return err;
}
@@ -434,6 +466,7 @@ static int ct_write(struct intel_guc_ct *ct,
corrupted:
CT_ERROR(ct, "Corrupted descriptor head=%u tail=%u status=%#x\n",
desc->head, desc->tail, desc->status);
+ CT_DEAD(ct, WRITE);
ctb->broken = true;
return -EPIPE;
}
@@ -504,6 +537,7 @@ static inline bool ct_deadlocked(struct intel_guc_ct *ct)
CT_ERROR(ct, "Head: %u\n (Dwords)", ct->ctbs.recv.desc->head);
CT_ERROR(ct, "Tail: %u\n (Dwords)", ct->ctbs.recv.desc->tail);
+ CT_DEAD(ct, DEADLOCK);
ct->ctbs.send.broken = true;
}
@@ -552,6 +586,7 @@ static inline bool h2g_has_room(struct intel_guc_ct *ct, u32 len_dw)
head, ctb->size);
desc->status |= GUC_CTB_STATUS_OVERFLOW;
ctb->broken = true;
+ CT_DEAD(ct, H2G_HAS_ROOM);
return false;
}
@@ -902,12 +937,19 @@ static int ct_read(struct intel_guc_ct *ct, struct ct_incoming_msg **msg)
/* now update descriptor */
WRITE_ONCE(desc->head, head);
+ /*
+ * Wa_22016122933: Making sure the head update is
+ * visible to GuC right away
+ */
+ intel_guc_write_barrier(ct_to_guc(ct));
+
return available - len;
corrupted:
CT_ERROR(ct, "Corrupted descriptor head=%u tail=%u status=%#x\n",
desc->head, desc->tail, desc->status);
ctb->broken = true;
+ CT_DEAD(ct, READ);
return -EPIPE;
}
@@ -1057,6 +1099,7 @@ static bool ct_process_incoming_requests(struct intel_guc_ct *ct)
if (unlikely(err)) {
CT_ERROR(ct, "Failed to process CT message (%pe) %*ph\n",
ERR_PTR(err), 4 * request->size, request->msg);
+ CT_DEAD(ct, PROCESS_FAILED);
ct_free_msg(request);
}
@@ -1233,3 +1276,19 @@ void intel_guc_ct_print_info(struct intel_guc_ct *ct,
drm_printf(p, "Tail: %u\n",
ct->ctbs.recv.desc->tail);
}
+
+#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GUC)
+static void ct_dead_ct_worker_func(struct work_struct *w)
+{
+ struct intel_guc_ct *ct = container_of(w, struct intel_guc_ct, dead_ct_worker);
+ struct intel_guc *guc = ct_to_guc(ct);
+
+ if (ct->dead_ct_reported)
+ return;
+
+ ct->dead_ct_reported = true;
+
+ guc_info(guc, "CTB is dead - reason=0x%X\n", ct->dead_ct_reason);
+ intel_klog_error_capture(guc_to_gt(guc), (intel_engine_mask_t)~0U);
+}
+#endif
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.h
index f709a19c7e21..818415b64f4d 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.h
@@ -85,6 +85,12 @@ struct intel_guc_ct {
/** @stall_time: time of first time a CTB submission is stalled */
ktime_t stall_time;
+
+#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GUC)
+ int dead_ct_reason;
+ bool dead_ct_reported;
+ struct work_struct dead_ct_worker;
+#endif
};
void intel_guc_ct_init_early(struct intel_guc_ct *ct);
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
index 6fda3aec5c66..364d0d546ec8 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
@@ -129,6 +129,7 @@ static inline bool guc_load_done(struct intel_uncore *uncore, u32 *status, bool
case INTEL_BOOTROM_STATUS_RC6CTXCONFIG_FAILED:
case INTEL_BOOTROM_STATUS_MPUMAP_INCORRECT:
case INTEL_BOOTROM_STATUS_EXCEPTION:
+ case INTEL_BOOTROM_STATUS_PROD_KEY_CHECK_FAILURE:
*success = false;
return true;
}
@@ -190,8 +191,10 @@ static int guc_wait_ucode(struct intel_guc *guc)
if (!ret || !success)
break;
- guc_dbg(guc, "load still in progress, count = %d, freq = %dMHz\n",
- count, intel_rps_read_actual_frequency(&uncore->gt->rps));
+ guc_dbg(guc, "load still in progress, count = %d, freq = %dMHz, status = 0x%08X [0x%02X/%02X]\n",
+ count, intel_rps_read_actual_frequency(&uncore->gt->rps), status,
+ REG_FIELD_GET(GS_BOOTROM_MASK, status),
+ REG_FIELD_GET(GS_UKERNEL_MASK, status));
}
after = ktime_get();
delta = ktime_sub(after, before);
@@ -219,6 +222,11 @@ static int guc_wait_ucode(struct intel_guc *guc)
guc_info(guc, "firmware signature verification failed\n");
ret = -ENOEXEC;
break;
+
+ case INTEL_BOOTROM_STATUS_PROD_KEY_CHECK_FAILURE:
+ guc_info(guc, "firmware production part check failure\n");
+ ret = -ENOEXEC;
+ break;
}
switch (ukernel) {
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
index 4ae5fc2f6002..4e57bd09d50d 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
@@ -411,6 +411,15 @@ enum guc_capture_type {
GUC_CAPTURE_LIST_TYPE_MAX,
};
+/* Class indecies for capture_class and capture_instance arrays */
+enum {
+ GUC_CAPTURE_LIST_CLASS_RENDER_COMPUTE = 0,
+ GUC_CAPTURE_LIST_CLASS_VIDEO = 1,
+ GUC_CAPTURE_LIST_CLASS_VIDEOENHANCE = 2,
+ GUC_CAPTURE_LIST_CLASS_BLITTER = 3,
+ GUC_CAPTURE_LIST_CLASS_GSC_OTHER = 4,
+};
+
/* GuC Additional Data Struct */
struct guc_ads {
struct guc_mmio_reg_set reg_state_list[GUC_MAX_ENGINE_CLASSES][GUC_MAX_INSTANCES_PER_CLASS];
@@ -451,7 +460,7 @@ enum guc_log_buffer_type {
GUC_MAX_LOG_BUFFER
};
-/**
+/*
* struct guc_log_buffer_state - GuC log buffer state
*
* Below state structure is used for coordination of retrieval of GuC firmware
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
index 026d73855f36..01b75529311c 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
@@ -277,6 +277,7 @@ int intel_guc_slpc_init(struct intel_guc_slpc *slpc)
slpc->max_freq_softlimit = 0;
slpc->min_freq_softlimit = 0;
+ slpc->ignore_eff_freq = false;
slpc->min_is_rpmax = false;
slpc->boost_freq = 0;
@@ -457,6 +458,29 @@ int intel_guc_slpc_get_max_freq(struct intel_guc_slpc *slpc, u32 *val)
return ret;
}
+int intel_guc_slpc_set_ignore_eff_freq(struct intel_guc_slpc *slpc, bool val)
+{
+ struct drm_i915_private *i915 = slpc_to_i915(slpc);
+ intel_wakeref_t wakeref;
+ int ret;
+
+ mutex_lock(&slpc->lock);
+ wakeref = intel_runtime_pm_get(&i915->runtime_pm);
+
+ ret = slpc_set_param(slpc,
+ SLPC_PARAM_IGNORE_EFFICIENT_FREQUENCY,
+ val);
+ if (ret)
+ guc_probe_error(slpc_to_guc(slpc), "Failed to set efficient freq(%d): %pe\n",
+ val, ERR_PTR(ret));
+ else
+ slpc->ignore_eff_freq = val;
+
+ intel_runtime_pm_put(&i915->runtime_pm, wakeref);
+ mutex_unlock(&slpc->lock);
+ return ret;
+}
+
/**
* intel_guc_slpc_set_min_freq() - Set min frequency limit for SLPC.
* @slpc: pointer to intel_guc_slpc.
@@ -482,16 +506,6 @@ int intel_guc_slpc_set_min_freq(struct intel_guc_slpc *slpc, u32 val)
mutex_lock(&slpc->lock);
wakeref = intel_runtime_pm_get(&i915->runtime_pm);
- /* Ignore efficient freq if lower min freq is requested */
- ret = slpc_set_param(slpc,
- SLPC_PARAM_IGNORE_EFFICIENT_FREQUENCY,
- val < slpc->rp1_freq);
- if (ret) {
- guc_probe_error(slpc_to_guc(slpc), "Failed to toggle efficient freq: %pe\n",
- ERR_PTR(ret));
- goto out;
- }
-
ret = slpc_set_param(slpc,
SLPC_PARAM_GLOBAL_MIN_GT_UNSLICE_FREQ_MHZ,
val);
@@ -499,7 +513,6 @@ int intel_guc_slpc_set_min_freq(struct intel_guc_slpc *slpc, u32 val)
if (!ret)
slpc->min_freq_softlimit = val;
-out:
intel_runtime_pm_put(&i915->runtime_pm, wakeref);
mutex_unlock(&slpc->lock);
@@ -752,6 +765,9 @@ int intel_guc_slpc_enable(struct intel_guc_slpc *slpc)
/* Set cached media freq ratio mode */
intel_guc_slpc_set_media_ratio_mode(slpc, slpc->media_ratio_mode);
+ /* Set cached value of ignore efficient freq */
+ intel_guc_slpc_set_ignore_eff_freq(slpc, slpc->ignore_eff_freq);
+
return 0;
}
@@ -821,6 +837,8 @@ int intel_guc_slpc_print_info(struct intel_guc_slpc *slpc, struct drm_printer *p
slpc_decode_min_freq(slpc));
drm_printf(p, "\twaitboosts: %u\n",
slpc->num_boosts);
+ drm_printf(p, "\tBoosts outstanding: %u\n",
+ atomic_read(&slpc->num_waiters));
}
}
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.h
index 17ed515f6a85..597eb5413ddf 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.h
@@ -46,5 +46,6 @@ void intel_guc_slpc_boost(struct intel_guc_slpc *slpc);
void intel_guc_slpc_dec_waiters(struct intel_guc_slpc *slpc);
int intel_guc_slpc_unset_gucrc_mode(struct intel_guc_slpc *slpc);
int intel_guc_slpc_override_gucrc_mode(struct intel_guc_slpc *slpc, u32 mode);
+int intel_guc_slpc_set_ignore_eff_freq(struct intel_guc_slpc *slpc, bool val);
#endif
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc_types.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc_types.h
index a6ef53b04e04..a88651331497 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc_types.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc_types.h
@@ -31,6 +31,7 @@ struct intel_guc_slpc {
/* frequency softlimits */
u32 min_freq_softlimit;
u32 max_freq_softlimit;
+ bool ignore_eff_freq;
/* cached media ratio mode */
u32 media_ratio_mode;
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index 88e881b100cf..a0e3ef1c65d2 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -1402,13 +1402,34 @@ static void __update_guc_busyness_stats(struct intel_guc *guc)
spin_unlock_irqrestore(&guc->timestamp.lock, flags);
}
+static void __guc_context_update_stats(struct intel_context *ce)
+{
+ struct intel_guc *guc = ce_to_guc(ce);
+ unsigned long flags;
+
+ spin_lock_irqsave(&guc->timestamp.lock, flags);
+ lrc_update_runtime(ce);
+ spin_unlock_irqrestore(&guc->timestamp.lock, flags);
+}
+
+static void guc_context_update_stats(struct intel_context *ce)
+{
+ if (!intel_context_pin_if_active(ce))
+ return;
+
+ __guc_context_update_stats(ce);
+ intel_context_unpin(ce);
+}
+
static void guc_timestamp_ping(struct work_struct *wrk)
{
struct intel_guc *guc = container_of(wrk, typeof(*guc),
timestamp.work.work);
struct intel_uc *uc = container_of(guc, typeof(*uc), guc);
struct intel_gt *gt = guc_to_gt(guc);
+ struct intel_context *ce;
intel_wakeref_t wakeref;
+ unsigned long index;
int srcu, ret;
/*
@@ -1424,6 +1445,10 @@ static void guc_timestamp_ping(struct work_struct *wrk)
with_intel_runtime_pm(&gt->i915->runtime_pm, wakeref)
__update_guc_busyness_stats(guc);
+ /* adjust context stats for overflow */
+ xa_for_each(&guc->context_lookup, index, ce)
+ guc_context_update_stats(ce);
+
intel_gt_reset_unlock(gt, srcu);
guc_enable_busyness_worker(guc);
@@ -1629,16 +1654,16 @@ static void guc_reset_state(struct intel_context *ce, u32 head, bool scrub)
static void guc_engine_reset_prepare(struct intel_engine_cs *engine)
{
- if (!IS_GRAPHICS_VER(engine->i915, 11, 12))
- return;
-
- intel_engine_stop_cs(engine);
-
/*
* Wa_22011802037: In addition to stopping the cs, we need
* to wait for any pending mi force wakeups
*/
- intel_engine_wait_for_pending_mi_fw(engine);
+ if (IS_MTL_GRAPHICS_STEP(engine->i915, M, STEP_A0, STEP_B0) ||
+ (GRAPHICS_VER(engine->i915) >= 11 &&
+ GRAPHICS_VER_FULL(engine->i915) < IP_VER(12, 70))) {
+ intel_engine_stop_cs(engine);
+ intel_engine_wait_for_pending_mi_fw(engine);
+ }
}
static void guc_reset_nop(struct intel_engine_cs *engine)
@@ -2774,6 +2799,7 @@ static void guc_context_unpin(struct intel_context *ce)
{
struct intel_guc *guc = ce_to_guc(ce);
+ __guc_context_update_stats(ce);
unpin_guc_id(guc, ce);
lrc_unpin(ce);
@@ -3455,6 +3481,7 @@ static void remove_from_context(struct i915_request *rq)
}
static const struct intel_context_ops guc_context_ops = {
+ .flags = COPS_RUNTIME_CYCLES,
.alloc = guc_context_alloc,
.close = guc_context_close,
@@ -3473,6 +3500,8 @@ static const struct intel_context_ops guc_context_ops = {
.sched_disable = guc_context_sched_disable,
+ .update_stats = guc_context_update_stats,
+
.reset = lrc_reset,
.destroy = guc_context_destroy,
@@ -3728,6 +3757,7 @@ static int guc_virtual_context_alloc(struct intel_context *ce)
}
static const struct intel_context_ops virtual_guc_context_ops = {
+ .flags = COPS_RUNTIME_CYCLES,
.alloc = guc_virtual_context_alloc,
.close = guc_context_close,
@@ -3745,6 +3775,7 @@ static const struct intel_context_ops virtual_guc_context_ops = {
.exit = guc_virtual_context_exit,
.sched_disable = guc_context_sched_disable,
+ .update_stats = guc_context_update_stats,
.destroy = guc_context_destroy,
@@ -4697,13 +4728,37 @@ static void capture_error_state(struct intel_guc *guc,
{
struct intel_gt *gt = guc_to_gt(guc);
struct drm_i915_private *i915 = gt->i915;
- struct intel_engine_cs *engine = __context_to_physical_engine(ce);
intel_wakeref_t wakeref;
+ intel_engine_mask_t engine_mask;
+
+ if (intel_engine_is_virtual(ce->engine)) {
+ struct intel_engine_cs *e;
+ intel_engine_mask_t tmp, virtual_mask = ce->engine->mask;
+
+ engine_mask = 0;
+ for_each_engine_masked(e, ce->engine->gt, virtual_mask, tmp) {
+ bool match = intel_guc_capture_is_matching_engine(gt, ce, e);
+
+ if (match) {
+ intel_engine_set_hung_context(e, ce);
+ engine_mask |= e->mask;
+ atomic_inc(&i915->gpu_error.reset_engine_count[e->uabi_class]);
+ }
+ }
+
+ if (!engine_mask) {
+ guc_warn(guc, "No matching physical engine capture for virtual engine context 0x%04X / %s",
+ ce->guc_id.id, ce->engine->name);
+ engine_mask = ~0U;
+ }
+ } else {
+ intel_engine_set_hung_context(ce->engine, ce);
+ engine_mask = ce->engine->mask;
+ atomic_inc(&i915->gpu_error.reset_engine_count[ce->engine->uabi_class]);
+ }
- intel_engine_set_hung_context(engine, ce);
with_intel_runtime_pm(&i915->runtime_pm, wakeref)
- i915_capture_error_state(gt, engine->mask, CORE_DUMP_FLAG_IS_GUC_CAPTURE);
- atomic_inc(&i915->gpu_error.reset_engine_count[engine->uabi_class]);
+ i915_capture_error_state(gt, engine_mask, CORE_DUMP_FLAG_IS_GUC_CAPTURE);
}
static void guc_context_replay(struct intel_context *ce)
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
index 4ccb4be4c9cb..c8b9cbb7ba3a 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
@@ -18,6 +18,7 @@
#include "intel_uc.h"
#include "i915_drv.h"
+#include "i915_hwmon.h"
static const struct intel_uc_ops uc_ops_off;
static const struct intel_uc_ops uc_ops_on;
@@ -431,6 +432,9 @@ static bool uc_is_wopcm_locked(struct intel_uc *uc)
static int __uc_check_hw(struct intel_uc *uc)
{
+ if (uc->fw_table_invalid)
+ return -EIO;
+
if (!intel_uc_supports_guc(uc))
return 0;
@@ -461,6 +465,7 @@ static int __uc_init_hw(struct intel_uc *uc)
struct intel_guc *guc = &uc->guc;
struct intel_huc *huc = &uc->huc;
int ret, attempts;
+ bool pl1en = false;
GEM_BUG_ON(!intel_uc_supports_guc(uc));
GEM_BUG_ON(!intel_uc_wants_guc(uc));
@@ -491,6 +496,9 @@ static int __uc_init_hw(struct intel_uc *uc)
else
attempts = 1;
+ /* Disable a potentially low PL1 power limit to allow freq to be raised */
+ i915_hwmon_power_max_disable(gt->i915, &pl1en);
+
intel_rps_raise_unslice(&uc_to_gt(uc)->rps);
while (attempts--) {
@@ -500,7 +508,7 @@ static int __uc_init_hw(struct intel_uc *uc)
*/
ret = __uc_sanitize(uc);
if (ret)
- goto err_out;
+ goto err_rps;
intel_huc_fw_upload(huc);
intel_guc_ads_reset(guc);
@@ -547,6 +555,8 @@ static int __uc_init_hw(struct intel_uc *uc)
intel_rps_lower_unslice(&uc_to_gt(uc)->rps);
}
+ i915_hwmon_power_max_restore(gt->i915, pl1en);
+
guc_info(guc, "submission %s\n", str_enabled_disabled(intel_uc_uses_guc_submission(uc)));
guc_info(guc, "SLPC %s\n", str_enabled_disabled(intel_uc_uses_guc_slpc(uc)));
@@ -559,10 +569,12 @@ err_submission:
intel_guc_submission_disable(guc);
err_log_capture:
__uc_capture_load_err_log(uc);
-err_out:
+err_rps:
/* Return GT back to RPn */
intel_rps_lower_unslice(&uc_to_gt(uc)->rps);
+ i915_hwmon_power_max_restore(gt->i915, pl1en);
+err_out:
__uc_sanitize(uc);
if (!ret) {
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.h b/drivers/gpu/drm/i915/gt/uc/intel_uc.h
index 5d0f1bcc381e..d585524d94de 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.h
@@ -36,6 +36,7 @@ struct intel_uc {
struct drm_i915_gem_object *load_err_log;
bool reset_in_progress;
+ bool fw_table_invalid;
};
void intel_uc_init_early(struct intel_uc *uc);
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
index c36e68e23a14..dc5c96c503a9 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -17,6 +17,12 @@
#include "i915_drv.h"
#include "i915_reg.h"
+#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)
+#define UNEXPECTED gt_probe_error
+#else
+#define UNEXPECTED gt_notice
+#endif
+
static inline struct intel_gt *
____uc_fw_to_gt(struct intel_uc_fw *uc_fw, enum intel_uc_fw_type type)
{
@@ -79,14 +85,15 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
* security fixes, etc. to be enabled.
*/
#define INTEL_GUC_FIRMWARE_DEFS(fw_def, guc_maj, guc_mmp) \
- fw_def(DG2, 0, guc_maj(dg2, 70, 5)) \
- fw_def(ALDERLAKE_P, 0, guc_maj(adlp, 70, 5)) \
+ fw_def(METEORLAKE, 0, guc_maj(mtl, 70, 6, 6)) \
+ fw_def(DG2, 0, guc_maj(dg2, 70, 5, 1)) \
+ fw_def(ALDERLAKE_P, 0, guc_maj(adlp, 70, 5, 1)) \
fw_def(ALDERLAKE_P, 0, guc_mmp(adlp, 70, 1, 1)) \
fw_def(ALDERLAKE_P, 0, guc_mmp(adlp, 69, 0, 3)) \
- fw_def(ALDERLAKE_S, 0, guc_maj(tgl, 70, 5)) \
+ fw_def(ALDERLAKE_S, 0, guc_maj(tgl, 70, 5, 1)) \
fw_def(ALDERLAKE_S, 0, guc_mmp(tgl, 70, 1, 1)) \
fw_def(ALDERLAKE_S, 0, guc_mmp(tgl, 69, 0, 3)) \
- fw_def(DG1, 0, guc_maj(dg1, 70, 5)) \
+ fw_def(DG1, 0, guc_maj(dg1, 70, 5, 1)) \
fw_def(ROCKETLAKE, 0, guc_mmp(tgl, 70, 1, 1)) \
fw_def(TIGERLAKE, 0, guc_mmp(tgl, 70, 1, 1)) \
fw_def(JASPERLAKE, 0, guc_mmp(ehl, 70, 1, 1)) \
@@ -140,7 +147,7 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
__stringify(patch_) ".bin"
/* Minor for internal driver use, not part of file name */
-#define MAKE_GUC_FW_PATH_MAJOR(prefix_, major_, minor_) \
+#define MAKE_GUC_FW_PATH_MAJOR(prefix_, major_, minor_, patch_) \
__MAKE_UC_FW_PATH_MAJOR(prefix_, "guc", major_)
#define MAKE_GUC_FW_PATH_MMP(prefix_, major_, minor_, patch_) \
@@ -196,9 +203,9 @@ struct __packed uc_fw_blob {
{ UC_FW_BLOB_BASE(major_, minor_, patch_, path_) \
.legacy = true }
-#define GUC_FW_BLOB(prefix_, major_, minor_) \
- UC_FW_BLOB_NEW(major_, minor_, 0, false, \
- MAKE_GUC_FW_PATH_MAJOR(prefix_, major_, minor_))
+#define GUC_FW_BLOB(prefix_, major_, minor_, patch_) \
+ UC_FW_BLOB_NEW(major_, minor_, patch_, false, \
+ MAKE_GUC_FW_PATH_MAJOR(prefix_, major_, minor_, patch_))
#define GUC_FW_BLOB_MMP(prefix_, major_, minor_, patch_) \
UC_FW_BLOB_OLD(major_, minor_, patch_, \
@@ -232,20 +239,22 @@ struct fw_blobs_by_type {
u32 count;
};
+static const struct uc_fw_platform_requirement blobs_guc[] = {
+ INTEL_GUC_FIRMWARE_DEFS(MAKE_FW_LIST, GUC_FW_BLOB, GUC_FW_BLOB_MMP)
+};
+
+static const struct uc_fw_platform_requirement blobs_huc[] = {
+ INTEL_HUC_FIRMWARE_DEFS(MAKE_FW_LIST, HUC_FW_BLOB, HUC_FW_BLOB_MMP, HUC_FW_BLOB_GSC)
+};
+
+static const struct fw_blobs_by_type blobs_all[INTEL_UC_FW_NUM_TYPES] = {
+ [INTEL_UC_FW_TYPE_GUC] = { blobs_guc, ARRAY_SIZE(blobs_guc) },
+ [INTEL_UC_FW_TYPE_HUC] = { blobs_huc, ARRAY_SIZE(blobs_huc) },
+};
+
static void
__uc_fw_auto_select(struct drm_i915_private *i915, struct intel_uc_fw *uc_fw)
{
- static const struct uc_fw_platform_requirement blobs_guc[] = {
- INTEL_GUC_FIRMWARE_DEFS(MAKE_FW_LIST, GUC_FW_BLOB, GUC_FW_BLOB_MMP)
- };
- static const struct uc_fw_platform_requirement blobs_huc[] = {
- INTEL_HUC_FIRMWARE_DEFS(MAKE_FW_LIST, HUC_FW_BLOB, HUC_FW_BLOB_MMP, HUC_FW_BLOB_GSC)
- };
- static const struct fw_blobs_by_type blobs_all[INTEL_UC_FW_NUM_TYPES] = {
- [INTEL_UC_FW_TYPE_GUC] = { blobs_guc, ARRAY_SIZE(blobs_guc) },
- [INTEL_UC_FW_TYPE_HUC] = { blobs_huc, ARRAY_SIZE(blobs_huc) },
- };
- static bool verified[INTEL_UC_FW_NUM_TYPES];
const struct uc_fw_platform_requirement *fw_blobs;
enum intel_platform p = INTEL_INFO(i915)->platform;
u32 fw_count;
@@ -285,6 +294,11 @@ __uc_fw_auto_select(struct drm_i915_private *i915, struct intel_uc_fw *uc_fw)
continue;
if (uc_fw->file_selected.path) {
+ /*
+ * Continuing an earlier search after a found blob failed to load.
+ * Once the previously chosen path has been found, clear it out
+ * and let the search continue from there.
+ */
if (uc_fw->file_selected.path == blob->path)
uc_fw->file_selected.path = NULL;
@@ -295,6 +309,7 @@ __uc_fw_auto_select(struct drm_i915_private *i915, struct intel_uc_fw *uc_fw)
uc_fw->file_wanted.path = blob->path;
uc_fw->file_wanted.ver.major = blob->major;
uc_fw->file_wanted.ver.minor = blob->minor;
+ uc_fw->file_wanted.ver.patch = blob->patch;
uc_fw->loaded_via_gsc = blob->loaded_via_gsc;
found = true;
break;
@@ -304,76 +319,111 @@ __uc_fw_auto_select(struct drm_i915_private *i915, struct intel_uc_fw *uc_fw)
/* Failed to find a match for the last attempt?! */
uc_fw->file_selected.path = NULL;
}
+}
- /* make sure the list is ordered as expected */
- if (IS_ENABLED(CONFIG_DRM_I915_SELFTEST) && !verified[uc_fw->type]) {
- verified[uc_fw->type] = true;
+static bool validate_fw_table_type(struct drm_i915_private *i915, enum intel_uc_fw_type type)
+{
+ const struct uc_fw_platform_requirement *fw_blobs;
+ u32 fw_count;
+ int i, j;
+
+ if (type >= ARRAY_SIZE(blobs_all)) {
+ drm_err(&i915->drm, "No blob array for %s\n", intel_uc_fw_type_repr(type));
+ return false;
+ }
+
+ fw_blobs = blobs_all[type].blobs;
+ fw_count = blobs_all[type].count;
+
+ if (!fw_count)
+ return true;
- for (i = 1; i < fw_count; i++) {
- /* Next platform is good: */
- if (fw_blobs[i].p < fw_blobs[i - 1].p)
+ /* make sure the list is ordered as expected */
+ for (i = 1; i < fw_count; i++) {
+ /* Versionless file names must be unique per platform: */
+ for (j = i + 1; j < fw_count; j++) {
+ /* Same platform? */
+ if (fw_blobs[i].p != fw_blobs[j].p)
continue;
- /* Next platform revision is good: */
- if (fw_blobs[i].p == fw_blobs[i - 1].p &&
- fw_blobs[i].rev < fw_blobs[i - 1].rev)
+ if (fw_blobs[i].blob.path != fw_blobs[j].blob.path)
continue;
- /* Platform/revision must be in order: */
- if (fw_blobs[i].p != fw_blobs[i - 1].p ||
- fw_blobs[i].rev != fw_blobs[i - 1].rev)
- goto bad;
+ drm_err(&i915->drm, "Duplicate %s blobs: %s r%u %s%d.%d.%d [%s] matches %s%d.%d.%d [%s]\n",
+ intel_uc_fw_type_repr(type),
+ intel_platform_name(fw_blobs[j].p), fw_blobs[j].rev,
+ fw_blobs[j].blob.legacy ? "L" : "v",
+ fw_blobs[j].blob.major, fw_blobs[j].blob.minor,
+ fw_blobs[j].blob.patch, fw_blobs[j].blob.path,
+ fw_blobs[i].blob.legacy ? "L" : "v",
+ fw_blobs[i].blob.major, fw_blobs[i].blob.minor,
+ fw_blobs[i].blob.patch, fw_blobs[i].blob.path);
+ }
- /* Next major version is good: */
- if (fw_blobs[i].blob.major < fw_blobs[i - 1].blob.major)
- continue;
+ /* Next platform is good: */
+ if (fw_blobs[i].p < fw_blobs[i - 1].p)
+ continue;
- /* New must be before legacy: */
- if (!fw_blobs[i].blob.legacy && fw_blobs[i - 1].blob.legacy)
- goto bad;
+ /* Next platform revision is good: */
+ if (fw_blobs[i].p == fw_blobs[i - 1].p &&
+ fw_blobs[i].rev < fw_blobs[i - 1].rev)
+ continue;
- /* New to legacy also means 0.0 to X.Y (HuC), or X.0 to X.Y (GuC) */
- if (fw_blobs[i].blob.legacy && !fw_blobs[i - 1].blob.legacy) {
- if (!fw_blobs[i - 1].blob.major)
- continue;
+ /* Platform/revision must be in order: */
+ if (fw_blobs[i].p != fw_blobs[i - 1].p ||
+ fw_blobs[i].rev != fw_blobs[i - 1].rev)
+ goto bad;
- if (fw_blobs[i].blob.major == fw_blobs[i - 1].blob.major)
- continue;
- }
+ /* Next major version is good: */
+ if (fw_blobs[i].blob.major < fw_blobs[i - 1].blob.major)
+ continue;
- /* Major versions must be in order: */
- if (fw_blobs[i].blob.major != fw_blobs[i - 1].blob.major)
- goto bad;
+ /* New must be before legacy: */
+ if (!fw_blobs[i].blob.legacy && fw_blobs[i - 1].blob.legacy)
+ goto bad;
- /* Next minor version is good: */
- if (fw_blobs[i].blob.minor < fw_blobs[i - 1].blob.minor)
+ /* New to legacy also means 0.0 to X.Y (HuC), or X.0 to X.Y (GuC) */
+ if (fw_blobs[i].blob.legacy && !fw_blobs[i - 1].blob.legacy) {
+ if (!fw_blobs[i - 1].blob.major)
continue;
- /* Minor versions must be in order: */
- if (fw_blobs[i].blob.minor != fw_blobs[i - 1].blob.minor)
- goto bad;
-
- /* Patch versions must be in order: */
- if (fw_blobs[i].blob.patch <= fw_blobs[i - 1].blob.patch)
+ if (fw_blobs[i].blob.major == fw_blobs[i - 1].blob.major)
continue;
+ }
-bad:
- drm_err(&i915->drm, "Invalid %s blob order: %s r%u %s%d.%d.%d comes before %s r%u %s%d.%d.%d\n",
- intel_uc_fw_type_repr(uc_fw->type),
- intel_platform_name(fw_blobs[i - 1].p), fw_blobs[i - 1].rev,
- fw_blobs[i - 1].blob.legacy ? "L" : "v",
- fw_blobs[i - 1].blob.major,
- fw_blobs[i - 1].blob.minor,
- fw_blobs[i - 1].blob.patch,
- intel_platform_name(fw_blobs[i].p), fw_blobs[i].rev,
- fw_blobs[i].blob.legacy ? "L" : "v",
- fw_blobs[i].blob.major,
- fw_blobs[i].blob.minor,
- fw_blobs[i].blob.patch);
+ /* Major versions must be in order: */
+ if (fw_blobs[i].blob.major != fw_blobs[i - 1].blob.major)
+ goto bad;
- uc_fw->file_selected.path = NULL;
- }
+ /* Next minor version is good: */
+ if (fw_blobs[i].blob.minor < fw_blobs[i - 1].blob.minor)
+ continue;
+
+ /* Minor versions must be in order: */
+ if (fw_blobs[i].blob.minor != fw_blobs[i - 1].blob.minor)
+ goto bad;
+
+ /* Patch versions must be in order and unique: */
+ if (fw_blobs[i].blob.patch < fw_blobs[i - 1].blob.patch)
+ continue;
+
+bad:
+ drm_err(&i915->drm, "Invalid %s blob order: %s r%u %s%d.%d.%d comes before %s r%u %s%d.%d.%d\n",
+ intel_uc_fw_type_repr(type),
+ intel_platform_name(fw_blobs[i - 1].p), fw_blobs[i - 1].rev,
+ fw_blobs[i - 1].blob.legacy ? "L" : "v",
+ fw_blobs[i - 1].blob.major,
+ fw_blobs[i - 1].blob.minor,
+ fw_blobs[i - 1].blob.patch,
+ intel_platform_name(fw_blobs[i].p), fw_blobs[i].rev,
+ fw_blobs[i].blob.legacy ? "L" : "v",
+ fw_blobs[i].blob.major,
+ fw_blobs[i].blob.minor,
+ fw_blobs[i].blob.patch);
+ return false;
}
+
+ return true;
}
static const char *__override_guc_firmware_path(struct drm_i915_private *i915)
@@ -428,7 +478,8 @@ static void __uc_fw_user_override(struct drm_i915_private *i915, struct intel_uc
void intel_uc_fw_init_early(struct intel_uc_fw *uc_fw,
enum intel_uc_fw_type type)
{
- struct drm_i915_private *i915 = ____uc_fw_to_gt(uc_fw, type)->i915;
+ struct intel_gt *gt = ____uc_fw_to_gt(uc_fw, type);
+ struct drm_i915_private *i915 = gt->i915;
/*
* we use FIRMWARE_UNINITIALIZED to detect checks against uc_fw->status
@@ -441,6 +492,12 @@ void intel_uc_fw_init_early(struct intel_uc_fw *uc_fw,
uc_fw->type = type;
if (HAS_GT_UC(i915)) {
+ if (!validate_fw_table_type(i915, type)) {
+ gt->uc.fw_table_invalid = true;
+ intel_uc_fw_change_status(uc_fw, INTEL_UC_FIRMWARE_NOT_SUPPORTED);
+ return;
+ }
+
__uc_fw_auto_select(i915, uc_fw);
__uc_fw_user_override(i915, uc_fw);
}
@@ -782,10 +839,10 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
if (uc_fw->file_wanted.ver.major && uc_fw->file_selected.ver.major) {
/* Check the file's major version was as it claimed */
if (uc_fw->file_selected.ver.major != uc_fw->file_wanted.ver.major) {
- gt_notice(gt, "%s firmware %s: unexpected version: %u.%u != %u.%u\n",
- intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path,
- uc_fw->file_selected.ver.major, uc_fw->file_selected.ver.minor,
- uc_fw->file_wanted.ver.major, uc_fw->file_wanted.ver.minor);
+ UNEXPECTED(gt, "%s firmware %s: unexpected version: %u.%u != %u.%u\n",
+ intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path,
+ uc_fw->file_selected.ver.major, uc_fw->file_selected.ver.minor,
+ uc_fw->file_wanted.ver.major, uc_fw->file_wanted.ver.minor);
if (!intel_uc_fw_is_overridden(uc_fw)) {
err = -ENOEXEC;
goto fail;
@@ -793,6 +850,9 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
} else {
if (uc_fw->file_selected.ver.minor < uc_fw->file_wanted.ver.minor)
old_ver = true;
+ else if ((uc_fw->file_selected.ver.minor == uc_fw->file_wanted.ver.minor) &&
+ (uc_fw->file_selected.ver.patch < uc_fw->file_wanted.ver.patch))
+ old_ver = true;
}
}
@@ -800,12 +860,16 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
/* Preserve the version that was really wanted */
memcpy(&uc_fw->file_wanted, &file_ideal, sizeof(uc_fw->file_wanted));
- gt_notice(gt, "%s firmware %s (%d.%d) is recommended, but only %s (%d.%d) was found\n",
- intel_uc_fw_type_repr(uc_fw->type),
- uc_fw->file_wanted.path,
- uc_fw->file_wanted.ver.major, uc_fw->file_wanted.ver.minor,
- uc_fw->file_selected.path,
- uc_fw->file_selected.ver.major, uc_fw->file_selected.ver.minor);
+ UNEXPECTED(gt, "%s firmware %s (%d.%d.%d) is recommended, but only %s (%d.%d.%d) was found\n",
+ intel_uc_fw_type_repr(uc_fw->type),
+ uc_fw->file_wanted.path,
+ uc_fw->file_wanted.ver.major,
+ uc_fw->file_wanted.ver.minor,
+ uc_fw->file_wanted.ver.patch,
+ uc_fw->file_selected.path,
+ uc_fw->file_selected.ver.major,
+ uc_fw->file_selected.ver.minor,
+ uc_fw->file_selected.ver.patch);
gt_info(gt, "Consider updating your linux-firmware pkg or downloading from %s\n",
INTEL_UC_FIRMWARE_URL);
}
@@ -893,9 +957,15 @@ static void uc_fw_bind_ggtt(struct intel_uc_fw *uc_fw)
pte_flags |= PTE_LM;
if (ggtt->vm.raw_insert_entries)
- ggtt->vm.raw_insert_entries(&ggtt->vm, dummy, I915_CACHE_NONE, pte_flags);
+ ggtt->vm.raw_insert_entries(&ggtt->vm, dummy,
+ i915_gem_get_pat_index(ggtt->vm.i915,
+ I915_CACHE_NONE),
+ pte_flags);
else
- ggtt->vm.insert_entries(&ggtt->vm, dummy, I915_CACHE_NONE, pte_flags);
+ ggtt->vm.insert_entries(&ggtt->vm, dummy,
+ i915_gem_get_pat_index(ggtt->vm.i915,
+ I915_CACHE_NONE),
+ pte_flags);
}
static void uc_fw_unbind_ggtt(struct intel_uc_fw *uc_fw)
diff --git a/drivers/gpu/drm/i915/gvt/aperture_gm.c b/drivers/gpu/drm/i915/gvt/aperture_gm.c
index 076c779f776a..eedd1865bb98 100644
--- a/drivers/gpu/drm/i915/gvt/aperture_gm.c
+++ b/drivers/gpu/drm/i915/gvt/aperture_gm.c
@@ -330,7 +330,7 @@ void intel_vgpu_reset_resource(struct intel_vgpu *vgpu)
/**
* intel_vgpu_alloc_resource() - allocate HW resource for a vGPU
* @vgpu: vGPU
- * @param: vGPU creation params
+ * @conf: vGPU creation params
*
* This function is used to allocate HW resource for a vGPU. User specifies
* the resource configuration through the creation params.
diff --git a/drivers/gpu/drm/i915/i915_active.h b/drivers/gpu/drm/i915/i915_active.h
index 7eb44132183a..77c676ecc263 100644
--- a/drivers/gpu/drm/i915/i915_active.h
+++ b/drivers/gpu/drm/i915/i915_active.h
@@ -49,9 +49,9 @@ void i915_active_noop(struct dma_fence *fence, struct dma_fence_cb *cb);
/**
* __i915_active_fence_init - prepares the activity tracker for use
- * @active - the active tracker
- * @fence - initial fence to track, can be NULL
- * @func - a callback when then the tracker is retired (becomes idle),
+ * @active: the active tracker
+ * @fence: initial fence to track, can be NULL
+ * @fn: a callback when then the tracker is retired (becomes idle),
* can be NULL
*
* i915_active_fence_init() prepares the embedded @active struct for use as
@@ -77,8 +77,8 @@ __i915_active_fence_set(struct i915_active_fence *active,
/**
* i915_active_fence_set - updates the tracker to watch the current fence
- * @active - the active tracker
- * @rq - the request to watch
+ * @active: the active tracker
+ * @rq: the request to watch
*
* i915_active_fence_set() watches the given @rq for completion. While
* that @rq is busy, the @active reports busy. When that @rq is signaled
@@ -89,7 +89,7 @@ i915_active_fence_set(struct i915_active_fence *active,
struct i915_request *rq);
/**
* i915_active_fence_get - return a reference to the active fence
- * @active - the active tracker
+ * @active: the active tracker
*
* i915_active_fence_get() returns a reference to the active fence,
* or NULL if the active tracker is idle. The reference is obtained under RCU,
@@ -111,7 +111,7 @@ i915_active_fence_get(struct i915_active_fence *active)
/**
* i915_active_fence_isset - report whether the active tracker is assigned
- * @active - the active tracker
+ * @active: the active tracker
*
* i915_active_fence_isset() returns true if the active tracker is currently
* assigned to a fence. Due to the lazy retiring, that fence may be idle
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 41389a32e998..76ccd4e03e31 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -139,21 +139,54 @@ static const char *stringify_vma_type(const struct i915_vma *vma)
return "ppgtt";
}
-static const char *i915_cache_level_str(struct drm_i915_private *i915, int type)
-{
- switch (type) {
- case I915_CACHE_NONE: return " uncached";
- case I915_CACHE_LLC: return HAS_LLC(i915) ? " LLC" : " snooped";
- case I915_CACHE_L3_LLC: return " L3+LLC";
- case I915_CACHE_WT: return " WT";
- default: return "";
+static const char *i915_cache_level_str(struct drm_i915_gem_object *obj)
+{
+ struct drm_i915_private *i915 = obj_to_i915(obj);
+
+ if (IS_METEORLAKE(i915)) {
+ switch (obj->pat_index) {
+ case 0: return " WB";
+ case 1: return " WT";
+ case 2: return " UC";
+ case 3: return " WB (1-Way Coh)";
+ case 4: return " WB (2-Way Coh)";
+ default: return " not defined";
+ }
+ } else if (IS_PONTEVECCHIO(i915)) {
+ switch (obj->pat_index) {
+ case 0: return " UC";
+ case 1: return " WC";
+ case 2: return " WT";
+ case 3: return " WB";
+ case 4: return " WT (CLOS1)";
+ case 5: return " WB (CLOS1)";
+ case 6: return " WT (CLOS2)";
+ case 7: return " WT (CLOS2)";
+ default: return " not defined";
+ }
+ } else if (GRAPHICS_VER(i915) >= 12) {
+ switch (obj->pat_index) {
+ case 0: return " WB";
+ case 1: return " WC";
+ case 2: return " WT";
+ case 3: return " UC";
+ default: return " not defined";
+ }
+ } else {
+ switch (obj->pat_index) {
+ case 0: return " UC";
+ case 1: return HAS_LLC(i915) ?
+ " LLC" : " snooped";
+ case 2: return " L3+LLC";
+ case 3: return " WT";
+ default: return " not defined";
+ }
}
}
void
i915_debugfs_describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
{
- struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
struct i915_vma *vma;
int pin_count = 0;
@@ -165,7 +198,7 @@ i915_debugfs_describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
obj->base.size / 1024,
obj->read_domains,
obj->write_domain,
- i915_cache_level_str(dev_priv, obj->cache_level),
+ i915_cache_level_str(obj),
obj->mm.dirty ? " dirty" : "",
obj->mm.madv == I915_MADV_DONTNEED ? " purgeable" : "");
if (obj->base.name)
diff --git a/drivers/gpu/drm/i915/i915_drm_client.c b/drivers/gpu/drm/i915/i915_drm_client.c
index e8fa172ebe5e..d18d0a3ed905 100644
--- a/drivers/gpu/drm/i915/i915_drm_client.c
+++ b/drivers/gpu/drm/i915/i915_drm_client.c
@@ -147,11 +147,7 @@ void i915_drm_client_fdinfo(struct seq_file *m, struct file *f)
PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
seq_printf(m, "drm-client-id:\t%u\n", client->id);
- /*
- * Temporarily skip showing client engine information with GuC submission till
- * fetching engine busyness is implemented in the GuC submission backend
- */
- if (GRAPHICS_VER(i915) < 8 || intel_uc_uses_guc_submission(&i915->gt0.uc))
+ if (GRAPHICS_VER(i915) < 8)
return;
for (i = 0; i < ARRAY_SIZE(uabi_class_names); i++)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index e9c403def9c9..f1205ed3ba71 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -382,11 +382,11 @@ static inline struct intel_gt *to_gt(struct drm_i915_private *i915)
}
/* Simple iterator over all initialised engines */
-#define for_each_engine(engine__, dev_priv__, id__) \
+#define for_each_engine(engine__, gt__, id__) \
for ((id__) = 0; \
(id__) < I915_NUM_ENGINES; \
(id__)++) \
- for_each_if ((engine__) = (dev_priv__)->engine[(id__)])
+ for_each_if ((engine__) = (gt__)->engine[(id__)])
/* Iterator over subset of engines selected by mask */
#define for_each_engine_masked(engine__, gt__, mask__, tmp__) \
@@ -408,13 +408,13 @@ static inline struct intel_gt *to_gt(struct drm_i915_private *i915)
(engine__) && (engine__)->uabi_class == (class__); \
(engine__) = rb_to_uabi_engine(rb_next(&(engine__)->uabi_node)))
-#define INTEL_INFO(dev_priv) (&(dev_priv)->__info)
+#define INTEL_INFO(i915) (&(i915)->__info)
#define DISPLAY_INFO(i915) (INTEL_INFO(i915)->display)
-#define RUNTIME_INFO(dev_priv) (&(dev_priv)->__runtime)
+#define RUNTIME_INFO(i915) (&(i915)->__runtime)
#define DISPLAY_RUNTIME_INFO(i915) (&(i915)->__display_runtime)
-#define DRIVER_CAPS(dev_priv) (&(dev_priv)->caps)
+#define DRIVER_CAPS(i915) (&(i915)->caps)
-#define INTEL_DEVID(dev_priv) (RUNTIME_INFO(dev_priv)->device_id)
+#define INTEL_DEVID(i915) (RUNTIME_INFO(i915)->device_id)
#define IP_VER(ver, rel) ((ver) << 8 | (rel))
@@ -434,7 +434,7 @@ static inline struct intel_gt *to_gt(struct drm_i915_private *i915)
#define IS_DISPLAY_VER(i915, from, until) \
(DISPLAY_VER(i915) >= (from) && DISPLAY_VER(i915) <= (until))
-#define INTEL_REVID(dev_priv) (to_pci_dev((dev_priv)->drm.dev)->revision)
+#define INTEL_REVID(i915) (to_pci_dev((i915)->drm.dev)->revision)
#define INTEL_DISPLAY_STEP(__i915) (RUNTIME_INFO(__i915)->step.display_step)
#define INTEL_GRAPHICS_STEP(__i915) (RUNTIME_INFO(__i915)->step.graphics_step)
@@ -519,135 +519,135 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
return ((mask << (msb - pb)) & (mask << (msb - s))) & BIT(msb);
}
-#define IS_MOBILE(dev_priv) (INTEL_INFO(dev_priv)->is_mobile)
-#define IS_DGFX(dev_priv) (INTEL_INFO(dev_priv)->is_dgfx)
-
-#define IS_I830(dev_priv) IS_PLATFORM(dev_priv, INTEL_I830)
-#define IS_I845G(dev_priv) IS_PLATFORM(dev_priv, INTEL_I845G)
-#define IS_I85X(dev_priv) IS_PLATFORM(dev_priv, INTEL_I85X)
-#define IS_I865G(dev_priv) IS_PLATFORM(dev_priv, INTEL_I865G)
-#define IS_I915G(dev_priv) IS_PLATFORM(dev_priv, INTEL_I915G)
-#define IS_I915GM(dev_priv) IS_PLATFORM(dev_priv, INTEL_I915GM)
-#define IS_I945G(dev_priv) IS_PLATFORM(dev_priv, INTEL_I945G)
-#define IS_I945GM(dev_priv) IS_PLATFORM(dev_priv, INTEL_I945GM)
-#define IS_I965G(dev_priv) IS_PLATFORM(dev_priv, INTEL_I965G)
-#define IS_I965GM(dev_priv) IS_PLATFORM(dev_priv, INTEL_I965GM)
-#define IS_G45(dev_priv) IS_PLATFORM(dev_priv, INTEL_G45)
-#define IS_GM45(dev_priv) IS_PLATFORM(dev_priv, INTEL_GM45)
-#define IS_G4X(dev_priv) (IS_G45(dev_priv) || IS_GM45(dev_priv))
-#define IS_PINEVIEW(dev_priv) IS_PLATFORM(dev_priv, INTEL_PINEVIEW)
-#define IS_G33(dev_priv) IS_PLATFORM(dev_priv, INTEL_G33)
-#define IS_IRONLAKE(dev_priv) IS_PLATFORM(dev_priv, INTEL_IRONLAKE)
-#define IS_IRONLAKE_M(dev_priv) \
- (IS_PLATFORM(dev_priv, INTEL_IRONLAKE) && IS_MOBILE(dev_priv))
-#define IS_SANDYBRIDGE(dev_priv) IS_PLATFORM(dev_priv, INTEL_SANDYBRIDGE)
-#define IS_IVYBRIDGE(dev_priv) IS_PLATFORM(dev_priv, INTEL_IVYBRIDGE)
-#define IS_IVB_GT1(dev_priv) (IS_IVYBRIDGE(dev_priv) && \
- INTEL_INFO(dev_priv)->gt == 1)
-#define IS_VALLEYVIEW(dev_priv) IS_PLATFORM(dev_priv, INTEL_VALLEYVIEW)
-#define IS_CHERRYVIEW(dev_priv) IS_PLATFORM(dev_priv, INTEL_CHERRYVIEW)
-#define IS_HASWELL(dev_priv) IS_PLATFORM(dev_priv, INTEL_HASWELL)
-#define IS_BROADWELL(dev_priv) IS_PLATFORM(dev_priv, INTEL_BROADWELL)
-#define IS_SKYLAKE(dev_priv) IS_PLATFORM(dev_priv, INTEL_SKYLAKE)
-#define IS_BROXTON(dev_priv) IS_PLATFORM(dev_priv, INTEL_BROXTON)
-#define IS_KABYLAKE(dev_priv) IS_PLATFORM(dev_priv, INTEL_KABYLAKE)
-#define IS_GEMINILAKE(dev_priv) IS_PLATFORM(dev_priv, INTEL_GEMINILAKE)
-#define IS_COFFEELAKE(dev_priv) IS_PLATFORM(dev_priv, INTEL_COFFEELAKE)
-#define IS_COMETLAKE(dev_priv) IS_PLATFORM(dev_priv, INTEL_COMETLAKE)
-#define IS_ICELAKE(dev_priv) IS_PLATFORM(dev_priv, INTEL_ICELAKE)
-#define IS_JSL_EHL(dev_priv) (IS_PLATFORM(dev_priv, INTEL_JASPERLAKE) || \
- IS_PLATFORM(dev_priv, INTEL_ELKHARTLAKE))
-#define IS_TIGERLAKE(dev_priv) IS_PLATFORM(dev_priv, INTEL_TIGERLAKE)
-#define IS_ROCKETLAKE(dev_priv) IS_PLATFORM(dev_priv, INTEL_ROCKETLAKE)
-#define IS_DG1(dev_priv) IS_PLATFORM(dev_priv, INTEL_DG1)
-#define IS_ALDERLAKE_S(dev_priv) IS_PLATFORM(dev_priv, INTEL_ALDERLAKE_S)
-#define IS_ALDERLAKE_P(dev_priv) IS_PLATFORM(dev_priv, INTEL_ALDERLAKE_P)
-#define IS_XEHPSDV(dev_priv) IS_PLATFORM(dev_priv, INTEL_XEHPSDV)
-#define IS_DG2(dev_priv) IS_PLATFORM(dev_priv, INTEL_DG2)
-#define IS_PONTEVECCHIO(dev_priv) IS_PLATFORM(dev_priv, INTEL_PONTEVECCHIO)
-#define IS_METEORLAKE(dev_priv) IS_PLATFORM(dev_priv, INTEL_METEORLAKE)
-
-#define IS_METEORLAKE_M(dev_priv) \
- IS_SUBPLATFORM(dev_priv, INTEL_METEORLAKE, INTEL_SUBPLATFORM_M)
-#define IS_METEORLAKE_P(dev_priv) \
- IS_SUBPLATFORM(dev_priv, INTEL_METEORLAKE, INTEL_SUBPLATFORM_P)
-#define IS_DG2_G10(dev_priv) \
- IS_SUBPLATFORM(dev_priv, INTEL_DG2, INTEL_SUBPLATFORM_G10)
-#define IS_DG2_G11(dev_priv) \
- IS_SUBPLATFORM(dev_priv, INTEL_DG2, INTEL_SUBPLATFORM_G11)
-#define IS_DG2_G12(dev_priv) \
- IS_SUBPLATFORM(dev_priv, INTEL_DG2, INTEL_SUBPLATFORM_G12)
-#define IS_ADLS_RPLS(dev_priv) \
- IS_SUBPLATFORM(dev_priv, INTEL_ALDERLAKE_S, INTEL_SUBPLATFORM_RPL)
-#define IS_ADLP_N(dev_priv) \
- IS_SUBPLATFORM(dev_priv, INTEL_ALDERLAKE_P, INTEL_SUBPLATFORM_N)
-#define IS_ADLP_RPLP(dev_priv) \
- IS_SUBPLATFORM(dev_priv, INTEL_ALDERLAKE_P, INTEL_SUBPLATFORM_RPL)
-#define IS_ADLP_RPLU(dev_priv) \
- IS_SUBPLATFORM(dev_priv, INTEL_ALDERLAKE_P, INTEL_SUBPLATFORM_RPLU)
-#define IS_HSW_EARLY_SDV(dev_priv) (IS_HASWELL(dev_priv) && \
- (INTEL_DEVID(dev_priv) & 0xFF00) == 0x0C00)
-#define IS_BDW_ULT(dev_priv) \
- IS_SUBPLATFORM(dev_priv, INTEL_BROADWELL, INTEL_SUBPLATFORM_ULT)
-#define IS_BDW_ULX(dev_priv) \
- IS_SUBPLATFORM(dev_priv, INTEL_BROADWELL, INTEL_SUBPLATFORM_ULX)
-#define IS_BDW_GT3(dev_priv) (IS_BROADWELL(dev_priv) && \
- INTEL_INFO(dev_priv)->gt == 3)
-#define IS_HSW_ULT(dev_priv) \
- IS_SUBPLATFORM(dev_priv, INTEL_HASWELL, INTEL_SUBPLATFORM_ULT)
-#define IS_HSW_GT3(dev_priv) (IS_HASWELL(dev_priv) && \
- INTEL_INFO(dev_priv)->gt == 3)
-#define IS_HSW_GT1(dev_priv) (IS_HASWELL(dev_priv) && \
- INTEL_INFO(dev_priv)->gt == 1)
+#define IS_MOBILE(i915) (INTEL_INFO(i915)->is_mobile)
+#define IS_DGFX(i915) (INTEL_INFO(i915)->is_dgfx)
+
+#define IS_I830(i915) IS_PLATFORM(i915, INTEL_I830)
+#define IS_I845G(i915) IS_PLATFORM(i915, INTEL_I845G)
+#define IS_I85X(i915) IS_PLATFORM(i915, INTEL_I85X)
+#define IS_I865G(i915) IS_PLATFORM(i915, INTEL_I865G)
+#define IS_I915G(i915) IS_PLATFORM(i915, INTEL_I915G)
+#define IS_I915GM(i915) IS_PLATFORM(i915, INTEL_I915GM)
+#define IS_I945G(i915) IS_PLATFORM(i915, INTEL_I945G)
+#define IS_I945GM(i915) IS_PLATFORM(i915, INTEL_I945GM)
+#define IS_I965G(i915) IS_PLATFORM(i915, INTEL_I965G)
+#define IS_I965GM(i915) IS_PLATFORM(i915, INTEL_I965GM)
+#define IS_G45(i915) IS_PLATFORM(i915, INTEL_G45)
+#define IS_GM45(i915) IS_PLATFORM(i915, INTEL_GM45)
+#define IS_G4X(i915) (IS_G45(i915) || IS_GM45(i915))
+#define IS_PINEVIEW(i915) IS_PLATFORM(i915, INTEL_PINEVIEW)
+#define IS_G33(i915) IS_PLATFORM(i915, INTEL_G33)
+#define IS_IRONLAKE(i915) IS_PLATFORM(i915, INTEL_IRONLAKE)
+#define IS_IRONLAKE_M(i915) \
+ (IS_PLATFORM(i915, INTEL_IRONLAKE) && IS_MOBILE(i915))
+#define IS_SANDYBRIDGE(i915) IS_PLATFORM(i915, INTEL_SANDYBRIDGE)
+#define IS_IVYBRIDGE(i915) IS_PLATFORM(i915, INTEL_IVYBRIDGE)
+#define IS_IVB_GT1(i915) (IS_IVYBRIDGE(i915) && \
+ INTEL_INFO(i915)->gt == 1)
+#define IS_VALLEYVIEW(i915) IS_PLATFORM(i915, INTEL_VALLEYVIEW)
+#define IS_CHERRYVIEW(i915) IS_PLATFORM(i915, INTEL_CHERRYVIEW)
+#define IS_HASWELL(i915) IS_PLATFORM(i915, INTEL_HASWELL)
+#define IS_BROADWELL(i915) IS_PLATFORM(i915, INTEL_BROADWELL)
+#define IS_SKYLAKE(i915) IS_PLATFORM(i915, INTEL_SKYLAKE)
+#define IS_BROXTON(i915) IS_PLATFORM(i915, INTEL_BROXTON)
+#define IS_KABYLAKE(i915) IS_PLATFORM(i915, INTEL_KABYLAKE)
+#define IS_GEMINILAKE(i915) IS_PLATFORM(i915, INTEL_GEMINILAKE)
+#define IS_COFFEELAKE(i915) IS_PLATFORM(i915, INTEL_COFFEELAKE)
+#define IS_COMETLAKE(i915) IS_PLATFORM(i915, INTEL_COMETLAKE)
+#define IS_ICELAKE(i915) IS_PLATFORM(i915, INTEL_ICELAKE)
+#define IS_JSL_EHL(i915) (IS_PLATFORM(i915, INTEL_JASPERLAKE) || \
+ IS_PLATFORM(i915, INTEL_ELKHARTLAKE))
+#define IS_TIGERLAKE(i915) IS_PLATFORM(i915, INTEL_TIGERLAKE)
+#define IS_ROCKETLAKE(i915) IS_PLATFORM(i915, INTEL_ROCKETLAKE)
+#define IS_DG1(i915) IS_PLATFORM(i915, INTEL_DG1)
+#define IS_ALDERLAKE_S(i915) IS_PLATFORM(i915, INTEL_ALDERLAKE_S)
+#define IS_ALDERLAKE_P(i915) IS_PLATFORM(i915, INTEL_ALDERLAKE_P)
+#define IS_XEHPSDV(i915) IS_PLATFORM(i915, INTEL_XEHPSDV)
+#define IS_DG2(i915) IS_PLATFORM(i915, INTEL_DG2)
+#define IS_PONTEVECCHIO(i915) IS_PLATFORM(i915, INTEL_PONTEVECCHIO)
+#define IS_METEORLAKE(i915) IS_PLATFORM(i915, INTEL_METEORLAKE)
+
+#define IS_METEORLAKE_M(i915) \
+ IS_SUBPLATFORM(i915, INTEL_METEORLAKE, INTEL_SUBPLATFORM_M)
+#define IS_METEORLAKE_P(i915) \
+ IS_SUBPLATFORM(i915, INTEL_METEORLAKE, INTEL_SUBPLATFORM_P)
+#define IS_DG2_G10(i915) \
+ IS_SUBPLATFORM(i915, INTEL_DG2, INTEL_SUBPLATFORM_G10)
+#define IS_DG2_G11(i915) \
+ IS_SUBPLATFORM(i915, INTEL_DG2, INTEL_SUBPLATFORM_G11)
+#define IS_DG2_G12(i915) \
+ IS_SUBPLATFORM(i915, INTEL_DG2, INTEL_SUBPLATFORM_G12)
+#define IS_ADLS_RPLS(i915) \
+ IS_SUBPLATFORM(i915, INTEL_ALDERLAKE_S, INTEL_SUBPLATFORM_RPL)
+#define IS_ADLP_N(i915) \
+ IS_SUBPLATFORM(i915, INTEL_ALDERLAKE_P, INTEL_SUBPLATFORM_N)
+#define IS_ADLP_RPLP(i915) \
+ IS_SUBPLATFORM(i915, INTEL_ALDERLAKE_P, INTEL_SUBPLATFORM_RPL)
+#define IS_ADLP_RPLU(i915) \
+ IS_SUBPLATFORM(i915, INTEL_ALDERLAKE_P, INTEL_SUBPLATFORM_RPLU)
+#define IS_HSW_EARLY_SDV(i915) (IS_HASWELL(i915) && \
+ (INTEL_DEVID(i915) & 0xFF00) == 0x0C00)
+#define IS_BDW_ULT(i915) \
+ IS_SUBPLATFORM(i915, INTEL_BROADWELL, INTEL_SUBPLATFORM_ULT)
+#define IS_BDW_ULX(i915) \
+ IS_SUBPLATFORM(i915, INTEL_BROADWELL, INTEL_SUBPLATFORM_ULX)
+#define IS_BDW_GT3(i915) (IS_BROADWELL(i915) && \
+ INTEL_INFO(i915)->gt == 3)
+#define IS_HSW_ULT(i915) \
+ IS_SUBPLATFORM(i915, INTEL_HASWELL, INTEL_SUBPLATFORM_ULT)
+#define IS_HSW_GT3(i915) (IS_HASWELL(i915) && \
+ INTEL_INFO(i915)->gt == 3)
+#define IS_HSW_GT1(i915) (IS_HASWELL(i915) && \
+ INTEL_INFO(i915)->gt == 1)
/* ULX machines are also considered ULT. */
-#define IS_HSW_ULX(dev_priv) \
- IS_SUBPLATFORM(dev_priv, INTEL_HASWELL, INTEL_SUBPLATFORM_ULX)
-#define IS_SKL_ULT(dev_priv) \
- IS_SUBPLATFORM(dev_priv, INTEL_SKYLAKE, INTEL_SUBPLATFORM_ULT)
-#define IS_SKL_ULX(dev_priv) \
- IS_SUBPLATFORM(dev_priv, INTEL_SKYLAKE, INTEL_SUBPLATFORM_ULX)
-#define IS_KBL_ULT(dev_priv) \
- IS_SUBPLATFORM(dev_priv, INTEL_KABYLAKE, INTEL_SUBPLATFORM_ULT)
-#define IS_KBL_ULX(dev_priv) \
- IS_SUBPLATFORM(dev_priv, INTEL_KABYLAKE, INTEL_SUBPLATFORM_ULX)
-#define IS_SKL_GT2(dev_priv) (IS_SKYLAKE(dev_priv) && \
- INTEL_INFO(dev_priv)->gt == 2)
-#define IS_SKL_GT3(dev_priv) (IS_SKYLAKE(dev_priv) && \
- INTEL_INFO(dev_priv)->gt == 3)
-#define IS_SKL_GT4(dev_priv) (IS_SKYLAKE(dev_priv) && \
- INTEL_INFO(dev_priv)->gt == 4)
-#define IS_KBL_GT2(dev_priv) (IS_KABYLAKE(dev_priv) && \
- INTEL_INFO(dev_priv)->gt == 2)
-#define IS_KBL_GT3(dev_priv) (IS_KABYLAKE(dev_priv) && \
- INTEL_INFO(dev_priv)->gt == 3)
-#define IS_CFL_ULT(dev_priv) \
- IS_SUBPLATFORM(dev_priv, INTEL_COFFEELAKE, INTEL_SUBPLATFORM_ULT)
-#define IS_CFL_ULX(dev_priv) \
- IS_SUBPLATFORM(dev_priv, INTEL_COFFEELAKE, INTEL_SUBPLATFORM_ULX)
-#define IS_CFL_GT2(dev_priv) (IS_COFFEELAKE(dev_priv) && \
- INTEL_INFO(dev_priv)->gt == 2)
-#define IS_CFL_GT3(dev_priv) (IS_COFFEELAKE(dev_priv) && \
- INTEL_INFO(dev_priv)->gt == 3)
-
-#define IS_CML_ULT(dev_priv) \
- IS_SUBPLATFORM(dev_priv, INTEL_COMETLAKE, INTEL_SUBPLATFORM_ULT)
-#define IS_CML_ULX(dev_priv) \
- IS_SUBPLATFORM(dev_priv, INTEL_COMETLAKE, INTEL_SUBPLATFORM_ULX)
-#define IS_CML_GT2(dev_priv) (IS_COMETLAKE(dev_priv) && \
- INTEL_INFO(dev_priv)->gt == 2)
-
-#define IS_ICL_WITH_PORT_F(dev_priv) \
- IS_SUBPLATFORM(dev_priv, INTEL_ICELAKE, INTEL_SUBPLATFORM_PORTF)
-
-#define IS_TGL_UY(dev_priv) \
- IS_SUBPLATFORM(dev_priv, INTEL_TIGERLAKE, INTEL_SUBPLATFORM_UY)
+#define IS_HSW_ULX(i915) \
+ IS_SUBPLATFORM(i915, INTEL_HASWELL, INTEL_SUBPLATFORM_ULX)
+#define IS_SKL_ULT(i915) \
+ IS_SUBPLATFORM(i915, INTEL_SKYLAKE, INTEL_SUBPLATFORM_ULT)
+#define IS_SKL_ULX(i915) \
+ IS_SUBPLATFORM(i915, INTEL_SKYLAKE, INTEL_SUBPLATFORM_ULX)
+#define IS_KBL_ULT(i915) \
+ IS_SUBPLATFORM(i915, INTEL_KABYLAKE, INTEL_SUBPLATFORM_ULT)
+#define IS_KBL_ULX(i915) \
+ IS_SUBPLATFORM(i915, INTEL_KABYLAKE, INTEL_SUBPLATFORM_ULX)
+#define IS_SKL_GT2(i915) (IS_SKYLAKE(i915) && \
+ INTEL_INFO(i915)->gt == 2)
+#define IS_SKL_GT3(i915) (IS_SKYLAKE(i915) && \
+ INTEL_INFO(i915)->gt == 3)
+#define IS_SKL_GT4(i915) (IS_SKYLAKE(i915) && \
+ INTEL_INFO(i915)->gt == 4)
+#define IS_KBL_GT2(i915) (IS_KABYLAKE(i915) && \
+ INTEL_INFO(i915)->gt == 2)
+#define IS_KBL_GT3(i915) (IS_KABYLAKE(i915) && \
+ INTEL_INFO(i915)->gt == 3)
+#define IS_CFL_ULT(i915) \
+ IS_SUBPLATFORM(i915, INTEL_COFFEELAKE, INTEL_SUBPLATFORM_ULT)
+#define IS_CFL_ULX(i915) \
+ IS_SUBPLATFORM(i915, INTEL_COFFEELAKE, INTEL_SUBPLATFORM_ULX)
+#define IS_CFL_GT2(i915) (IS_COFFEELAKE(i915) && \
+ INTEL_INFO(i915)->gt == 2)
+#define IS_CFL_GT3(i915) (IS_COFFEELAKE(i915) && \
+ INTEL_INFO(i915)->gt == 3)
+
+#define IS_CML_ULT(i915) \
+ IS_SUBPLATFORM(i915, INTEL_COMETLAKE, INTEL_SUBPLATFORM_ULT)
+#define IS_CML_ULX(i915) \
+ IS_SUBPLATFORM(i915, INTEL_COMETLAKE, INTEL_SUBPLATFORM_ULX)
+#define IS_CML_GT2(i915) (IS_COMETLAKE(i915) && \
+ INTEL_INFO(i915)->gt == 2)
+
+#define IS_ICL_WITH_PORT_F(i915) \
+ IS_SUBPLATFORM(i915, INTEL_ICELAKE, INTEL_SUBPLATFORM_PORTF)
+
+#define IS_TGL_UY(i915) \
+ IS_SUBPLATFORM(i915, INTEL_TIGERLAKE, INTEL_SUBPLATFORM_UY)
#define IS_SKL_GRAPHICS_STEP(p, since, until) (IS_SKYLAKE(p) && IS_GRAPHICS_STEP(p, since, until))
-#define IS_KBL_GRAPHICS_STEP(dev_priv, since, until) \
- (IS_KABYLAKE(dev_priv) && IS_GRAPHICS_STEP(dev_priv, since, until))
-#define IS_KBL_DISPLAY_STEP(dev_priv, since, until) \
- (IS_KABYLAKE(dev_priv) && IS_DISPLAY_STEP(dev_priv, since, until))
+#define IS_KBL_GRAPHICS_STEP(i915, since, until) \
+ (IS_KABYLAKE(i915) && IS_GRAPHICS_STEP(i915, since, until))
+#define IS_KBL_DISPLAY_STEP(i915, since, until) \
+ (IS_KABYLAKE(i915) && IS_DISPLAY_STEP(i915, since, until))
#define IS_JSL_EHL_GRAPHICS_STEP(p, since, until) \
(IS_JSL_EHL(p) && IS_GRAPHICS_STEP(p, since, until))
@@ -723,9 +723,9 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
(IS_PONTEVECCHIO(__i915) && \
IS_GRAPHICS_STEP(__i915, since, until))
-#define IS_LP(dev_priv) (INTEL_INFO(dev_priv)->is_lp)
-#define IS_GEN9_LP(dev_priv) (GRAPHICS_VER(dev_priv) == 9 && IS_LP(dev_priv))
-#define IS_GEN9_BC(dev_priv) (GRAPHICS_VER(dev_priv) == 9 && !IS_LP(dev_priv))
+#define IS_LP(i915) (INTEL_INFO(i915)->is_lp)
+#define IS_GEN9_LP(i915) (GRAPHICS_VER(i915) == 9 && IS_LP(i915))
+#define IS_GEN9_BC(i915) (GRAPHICS_VER(i915) == 9 && !IS_LP(i915))
#define __HAS_ENGINE(engine_mask, id) ((engine_mask) & BIT(id))
#define HAS_ENGINE(gt, id) __HAS_ENGINE((gt)->info.engine_mask, id)
@@ -750,122 +750,121 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
#define CCS_MASK(gt) \
ENGINE_INSTANCES_MASK(gt, CCS0, I915_MAX_CCS)
-#define HAS_MEDIA_RATIO_MODE(dev_priv) (INTEL_INFO(dev_priv)->has_media_ratio_mode)
+#define HAS_MEDIA_RATIO_MODE(i915) (INTEL_INFO(i915)->has_media_ratio_mode)
/*
* The Gen7 cmdparser copies the scanned buffer to the ggtt for execution
* All later gens can run the final buffer from the ppgtt
*/
-#define CMDPARSER_USES_GGTT(dev_priv) (GRAPHICS_VER(dev_priv) == 7)
+#define CMDPARSER_USES_GGTT(i915) (GRAPHICS_VER(i915) == 7)
-#define HAS_LLC(dev_priv) (INTEL_INFO(dev_priv)->has_llc)
-#define HAS_4TILE(dev_priv) (INTEL_INFO(dev_priv)->has_4tile)
-#define HAS_SNOOP(dev_priv) (INTEL_INFO(dev_priv)->has_snoop)
-#define HAS_EDRAM(dev_priv) ((dev_priv)->edram_size_mb)
-#define HAS_SECURE_BATCHES(dev_priv) (GRAPHICS_VER(dev_priv) < 6)
-#define HAS_WT(dev_priv) HAS_EDRAM(dev_priv)
+#define HAS_LLC(i915) (INTEL_INFO(i915)->has_llc)
+#define HAS_4TILE(i915) (INTEL_INFO(i915)->has_4tile)
+#define HAS_SNOOP(i915) (INTEL_INFO(i915)->has_snoop)
+#define HAS_EDRAM(i915) ((i915)->edram_size_mb)
+#define HAS_SECURE_BATCHES(i915) (GRAPHICS_VER(i915) < 6)
+#define HAS_WT(i915) HAS_EDRAM(i915)
-#define HWS_NEEDS_PHYSICAL(dev_priv) (INTEL_INFO(dev_priv)->hws_needs_physical)
+#define HWS_NEEDS_PHYSICAL(i915) (INTEL_INFO(i915)->hws_needs_physical)
-#define HAS_LOGICAL_RING_CONTEXTS(dev_priv) \
- (INTEL_INFO(dev_priv)->has_logical_ring_contexts)
-#define HAS_LOGICAL_RING_ELSQ(dev_priv) \
- (INTEL_INFO(dev_priv)->has_logical_ring_elsq)
+#define HAS_LOGICAL_RING_CONTEXTS(i915) \
+ (INTEL_INFO(i915)->has_logical_ring_contexts)
+#define HAS_LOGICAL_RING_ELSQ(i915) \
+ (INTEL_INFO(i915)->has_logical_ring_elsq)
-#define HAS_EXECLISTS(dev_priv) HAS_LOGICAL_RING_CONTEXTS(dev_priv)
+#define HAS_EXECLISTS(i915) HAS_LOGICAL_RING_CONTEXTS(i915)
-#define INTEL_PPGTT(dev_priv) (RUNTIME_INFO(dev_priv)->ppgtt_type)
-#define HAS_PPGTT(dev_priv) \
- (INTEL_PPGTT(dev_priv) != INTEL_PPGTT_NONE)
-#define HAS_FULL_PPGTT(dev_priv) \
- (INTEL_PPGTT(dev_priv) >= INTEL_PPGTT_FULL)
+#define INTEL_PPGTT(i915) (RUNTIME_INFO(i915)->ppgtt_type)
+#define HAS_PPGTT(i915) \
+ (INTEL_PPGTT(i915) != INTEL_PPGTT_NONE)
+#define HAS_FULL_PPGTT(i915) \
+ (INTEL_PPGTT(i915) >= INTEL_PPGTT_FULL)
-#define HAS_PAGE_SIZES(dev_priv, sizes) ({ \
+#define HAS_PAGE_SIZES(i915, sizes) ({ \
GEM_BUG_ON((sizes) == 0); \
- ((sizes) & ~RUNTIME_INFO(dev_priv)->page_sizes) == 0; \
+ ((sizes) & ~RUNTIME_INFO(i915)->page_sizes) == 0; \
})
/* Early gen2 have a totally busted CS tlb and require pinned batches. */
-#define HAS_BROKEN_CS_TLB(dev_priv) (IS_I830(dev_priv) || IS_I845G(dev_priv))
+#define HAS_BROKEN_CS_TLB(i915) (IS_I830(i915) || IS_I845G(i915))
-#define NEEDS_RC6_CTX_CORRUPTION_WA(dev_priv) \
- (IS_BROADWELL(dev_priv) || GRAPHICS_VER(dev_priv) == 9)
+#define NEEDS_RC6_CTX_CORRUPTION_WA(i915) \
+ (IS_BROADWELL(i915) || GRAPHICS_VER(i915) == 9)
/* WaRsDisableCoarsePowerGating:skl,cnl */
-#define NEEDS_WaRsDisableCoarsePowerGating(dev_priv) \
- (IS_SKL_GT3(dev_priv) || IS_SKL_GT4(dev_priv))
+#define NEEDS_WaRsDisableCoarsePowerGating(i915) \
+ (IS_SKL_GT3(i915) || IS_SKL_GT4(i915))
/* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte
* rows, which changed the alignment requirements and fence programming.
*/
-#define HAS_128_BYTE_Y_TILING(dev_priv) (GRAPHICS_VER(dev_priv) != 2 && \
- !(IS_I915G(dev_priv) || IS_I915GM(dev_priv)))
+#define HAS_128_BYTE_Y_TILING(i915) (GRAPHICS_VER(i915) != 2 && \
+ !(IS_I915G(i915) || IS_I915GM(i915)))
+#define HAS_RC6(i915) (INTEL_INFO(i915)->has_rc6)
+#define HAS_RC6p(i915) (INTEL_INFO(i915)->has_rc6p)
+#define HAS_RC6pp(i915) (false) /* HW was never validated */
-#define HAS_RC6(dev_priv) (INTEL_INFO(dev_priv)->has_rc6)
-#define HAS_RC6p(dev_priv) (INTEL_INFO(dev_priv)->has_rc6p)
-#define HAS_RC6pp(dev_priv) (false) /* HW was never validated */
+#define HAS_RPS(i915) (INTEL_INFO(i915)->has_rps)
-#define HAS_RPS(dev_priv) (INTEL_INFO(dev_priv)->has_rps)
+#define HAS_HECI_PXP(i915) \
+ (INTEL_INFO(i915)->has_heci_pxp)
-#define HAS_HECI_PXP(dev_priv) \
- (INTEL_INFO(dev_priv)->has_heci_pxp)
+#define HAS_HECI_GSCFI(i915) \
+ (INTEL_INFO(i915)->has_heci_gscfi)
-#define HAS_HECI_GSCFI(dev_priv) \
- (INTEL_INFO(dev_priv)->has_heci_gscfi)
+#define HAS_HECI_GSC(i915) (HAS_HECI_PXP(i915) || HAS_HECI_GSCFI(i915))
-#define HAS_HECI_GSC(dev_priv) (HAS_HECI_PXP(dev_priv) || HAS_HECI_GSCFI(dev_priv))
+#define HAS_RUNTIME_PM(i915) (INTEL_INFO(i915)->has_runtime_pm)
+#define HAS_64BIT_RELOC(i915) (INTEL_INFO(i915)->has_64bit_reloc)
-#define HAS_RUNTIME_PM(dev_priv) (INTEL_INFO(dev_priv)->has_runtime_pm)
-#define HAS_64BIT_RELOC(dev_priv) (INTEL_INFO(dev_priv)->has_64bit_reloc)
-
-#define HAS_OA_BPC_REPORTING(dev_priv) \
- (INTEL_INFO(dev_priv)->has_oa_bpc_reporting)
-#define HAS_OA_SLICE_CONTRIB_LIMITS(dev_priv) \
- (INTEL_INFO(dev_priv)->has_oa_slice_contrib_limits)
-#define HAS_OAM(dev_priv) \
- (INTEL_INFO(dev_priv)->has_oam)
+#define HAS_OA_BPC_REPORTING(i915) \
+ (INTEL_INFO(i915)->has_oa_bpc_reporting)
+#define HAS_OA_SLICE_CONTRIB_LIMITS(i915) \
+ (INTEL_INFO(i915)->has_oa_slice_contrib_limits)
+#define HAS_OAM(i915) \
+ (INTEL_INFO(i915)->has_oam)
/*
* Set this flag, when platform requires 64K GTT page sizes or larger for
* device local memory access.
*/
-#define HAS_64K_PAGES(dev_priv) (INTEL_INFO(dev_priv)->has_64k_pages)
+#define HAS_64K_PAGES(i915) (INTEL_INFO(i915)->has_64k_pages)
#define HAS_REGION(i915, i) (RUNTIME_INFO(i915)->memory_regions & (i))
#define HAS_LMEM(i915) HAS_REGION(i915, REGION_LMEM)
-#define HAS_EXTRA_GT_LIST(dev_priv) (INTEL_INFO(dev_priv)->extra_gt_list)
+#define HAS_EXTRA_GT_LIST(i915) (INTEL_INFO(i915)->extra_gt_list)
/*
* Platform has the dedicated compression control state for each lmem surfaces
* stored in lmem to support the 3D and media compression formats.
*/
-#define HAS_FLAT_CCS(dev_priv) (INTEL_INFO(dev_priv)->has_flat_ccs)
+#define HAS_FLAT_CCS(i915) (INTEL_INFO(i915)->has_flat_ccs)
-#define HAS_GT_UC(dev_priv) (INTEL_INFO(dev_priv)->has_gt_uc)
+#define HAS_GT_UC(i915) (INTEL_INFO(i915)->has_gt_uc)
-#define HAS_POOLED_EU(dev_priv) (RUNTIME_INFO(dev_priv)->has_pooled_eu)
+#define HAS_POOLED_EU(i915) (RUNTIME_INFO(i915)->has_pooled_eu)
-#define HAS_GLOBAL_MOCS_REGISTERS(dev_priv) (INTEL_INFO(dev_priv)->has_global_mocs)
+#define HAS_GLOBAL_MOCS_REGISTERS(i915) (INTEL_INFO(i915)->has_global_mocs)
#define HAS_GMD_ID(i915) (INTEL_INFO(i915)->has_gmd_id)
#define HAS_L3_CCS_READ(i915) (INTEL_INFO(i915)->has_l3_ccs_read)
/* DPF == dynamic parity feature */
-#define HAS_L3_DPF(dev_priv) (INTEL_INFO(dev_priv)->has_l3_dpf)
-#define NUM_L3_SLICES(dev_priv) (IS_HSW_GT3(dev_priv) ? \
- 2 : HAS_L3_DPF(dev_priv))
+#define HAS_L3_DPF(i915) (INTEL_INFO(i915)->has_l3_dpf)
+#define NUM_L3_SLICES(i915) (IS_HSW_GT3(i915) ? \
+ 2 : HAS_L3_DPF(i915))
/* Only valid when HAS_DISPLAY() is true */
-#define INTEL_DISPLAY_ENABLED(dev_priv) \
- (drm_WARN_ON(&(dev_priv)->drm, !HAS_DISPLAY(dev_priv)), \
- !(dev_priv)->params.disable_display && \
- !intel_opregion_headless_sku(dev_priv))
+#define INTEL_DISPLAY_ENABLED(i915) \
+ (drm_WARN_ON(&(i915)->drm, !HAS_DISPLAY(i915)), \
+ !(i915)->params.disable_display && \
+ !intel_opregion_headless_sku(i915))
-#define HAS_GUC_DEPRIVILEGE(dev_priv) \
- (INTEL_INFO(dev_priv)->has_guc_deprivilege)
+#define HAS_GUC_DEPRIVILEGE(i915) \
+ (INTEL_INFO(i915)->has_guc_deprivilege)
#define HAS_3D_PIPELINE(i915) (INTEL_INFO(i915)->has_3d_pipeline)
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 0a78bdbd36b1..e70b762f0b03 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -420,8 +420,11 @@ i915_gem_gtt_pread(struct drm_i915_gem_object *obj,
page_length = remain < page_length ? remain : page_length;
if (drm_mm_node_allocated(&node)) {
ggtt->vm.insert_page(&ggtt->vm,
- i915_gem_object_get_dma_address(obj, offset >> PAGE_SHIFT),
- node.start, I915_CACHE_NONE, 0);
+ i915_gem_object_get_dma_address(obj,
+ offset >> PAGE_SHIFT),
+ node.start,
+ i915_gem_get_pat_index(i915,
+ I915_CACHE_NONE), 0);
} else {
page_base += offset & PAGE_MASK;
}
@@ -598,8 +601,11 @@ i915_gem_gtt_pwrite_fast(struct drm_i915_gem_object *obj,
/* flush the write before we modify the GGTT */
intel_gt_flush_ggtt_writes(ggtt->vm.gt);
ggtt->vm.insert_page(&ggtt->vm,
- i915_gem_object_get_dma_address(obj, offset >> PAGE_SHIFT),
- node.start, I915_CACHE_NONE, 0);
+ i915_gem_object_get_dma_address(obj,
+ offset >> PAGE_SHIFT),
+ node.start,
+ i915_gem_get_pat_index(i915,
+ I915_CACHE_NONE), 0);
wmb(); /* flush modifications to the GGTT (insert_page) */
} else {
page_base += offset & PAGE_MASK;
@@ -1142,6 +1148,19 @@ int i915_gem_init(struct drm_i915_private *dev_priv)
unsigned int i;
int ret;
+ /*
+ * In the proccess of replacing cache_level with pat_index a tricky
+ * dependency is created on the definition of the enum i915_cache_level.
+ * in case this enum is changed, PTE encode would be broken.
+ * Add a WARNING here. And remove when we completely quit using this
+ * enum
+ */
+ BUILD_BUG_ON(I915_CACHE_NONE != 0 ||
+ I915_CACHE_LLC != 1 ||
+ I915_CACHE_L3_LLC != 2 ||
+ I915_CACHE_WT != 3 ||
+ I915_MAX_CACHE_LEVEL != 4);
+
/* We need to fallback to 4K pages if host doesn't support huge gtt. */
if (intel_vgpu_active(dev_priv) && !intel_vgpu_has_huge_gtt(dev_priv))
RUNTIME_INFO(dev_priv)->page_sizes = I915_GTT_PAGE_SIZE_4K;
diff --git a/drivers/gpu/drm/i915/i915_getparam.c b/drivers/gpu/drm/i915/i915_getparam.c
index 2238e096c957..6f11d7eaa91a 100644
--- a/drivers/gpu/drm/i915/i915_getparam.c
+++ b/drivers/gpu/drm/i915/i915_getparam.c
@@ -5,6 +5,8 @@
#include "gem/i915_gem_mman.h"
#include "gt/intel_engine_user.h"
+#include "pxp/intel_pxp.h"
+
#include "i915_cmd_parser.h"
#include "i915_drv.h"
#include "i915_getparam.h"
@@ -102,6 +104,11 @@ int i915_getparam_ioctl(struct drm_device *dev, void *data,
if (value < 0)
return value;
break;
+ case I915_PARAM_PXP_STATUS:
+ value = intel_pxp_get_readiness_status(i915->pxp);
+ if (value < 0)
+ return value;
+ break;
case I915_PARAM_MMAP_GTT_VERSION:
/* Though we've started our numbering from 1, and so class all
* earlier versions as 0, in effect their value is undefined as
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
index f020c0086fbc..ec368e700235 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -808,10 +808,15 @@ static void err_print_gt_engines(struct drm_i915_error_state_buf *m,
for (ee = gt->engine; ee; ee = ee->next) {
const struct i915_vma_coredump *vma;
- if (ee->guc_capture_node)
- intel_guc_capture_print_engine_node(m, ee);
- else
+ if (gt->uc && gt->uc->guc.is_guc_capture) {
+ if (ee->guc_capture_node)
+ intel_guc_capture_print_engine_node(m, ee);
+ else
+ err_printf(m, " Missing GuC capture node for %s\n",
+ ee->engine->name);
+ } else {
error_print_engine(m, ee);
+ }
err_printf(m, " hung: %u\n", ee->hung);
err_printf(m, " engine reset count: %u\n", ee->reset_count);
@@ -1117,10 +1122,14 @@ i915_vma_coredump_create(const struct intel_gt *gt,
mutex_lock(&ggtt->error_mutex);
if (ggtt->vm.raw_insert_page)
ggtt->vm.raw_insert_page(&ggtt->vm, dma, slot,
- I915_CACHE_NONE, 0);
+ i915_gem_get_pat_index(gt->i915,
+ I915_CACHE_NONE),
+ 0);
else
ggtt->vm.insert_page(&ggtt->vm, dma, slot,
- I915_CACHE_NONE, 0);
+ i915_gem_get_pat_index(gt->i915,
+ I915_CACHE_NONE),
+ 0);
mb();
s = io_mapping_map_wc(&ggtt->iomap, slot, PAGE_SIZE);
@@ -2162,7 +2171,7 @@ void i915_error_state_store(struct i915_gpu_coredump *error)
* i915_capture_error_state - capture an error record for later analysis
* @gt: intel_gt which originated the hang
* @engine_mask: hung engines
- *
+ * @dump_flags: dump flags
*
* Should be called when an error is detected (either a hang or an error
* interrupt) to capture error state from the time of the error. Fills
@@ -2219,3 +2228,135 @@ void i915_disable_error_state(struct drm_i915_private *i915, int err)
i915->gpu_error.first_error = ERR_PTR(err);
spin_unlock_irq(&i915->gpu_error.lock);
}
+
+#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)
+void intel_klog_error_capture(struct intel_gt *gt,
+ intel_engine_mask_t engine_mask)
+{
+ static int g_count;
+ struct drm_i915_private *i915 = gt->i915;
+ struct i915_gpu_coredump *error;
+ intel_wakeref_t wakeref;
+ size_t buf_size = PAGE_SIZE * 128;
+ size_t pos_err;
+ char *buf, *ptr, *next;
+ int l_count = g_count++;
+ int line = 0;
+
+ /* Can't allocate memory during a reset */
+ if (test_bit(I915_RESET_BACKOFF, &gt->reset.flags)) {
+ drm_err(&gt->i915->drm, "[Capture/%d.%d] Inside GT reset, skipping error capture :(\n",
+ l_count, line++);
+ return;
+ }
+
+ error = READ_ONCE(i915->gpu_error.first_error);
+ if (error) {
+ drm_err(&i915->drm, "[Capture/%d.%d] Clearing existing error capture first...\n",
+ l_count, line++);
+ i915_reset_error_state(i915);
+ }
+
+ with_intel_runtime_pm(&i915->runtime_pm, wakeref)
+ error = i915_gpu_coredump(gt, engine_mask, CORE_DUMP_FLAG_NONE);
+
+ if (IS_ERR(error)) {
+ drm_err(&i915->drm, "[Capture/%d.%d] Failed to capture error capture: %ld!\n",
+ l_count, line++, PTR_ERR(error));
+ return;
+ }
+
+ buf = kvmalloc(buf_size, GFP_KERNEL);
+ if (!buf) {
+ drm_err(&i915->drm, "[Capture/%d.%d] Failed to allocate buffer for error capture!\n",
+ l_count, line++);
+ i915_gpu_coredump_put(error);
+ return;
+ }
+
+ drm_info(&i915->drm, "[Capture/%d.%d] Dumping i915 error capture for %ps...\n",
+ l_count, line++, __builtin_return_address(0));
+
+ /* Largest string length safe to print via dmesg */
+# define MAX_CHUNK 800
+
+ pos_err = 0;
+ while (1) {
+ ssize_t got = i915_gpu_coredump_copy_to_buffer(error, buf, pos_err, buf_size - 1);
+
+ if (got <= 0)
+ break;
+
+ buf[got] = 0;
+ pos_err += got;
+
+ ptr = buf;
+ while (got > 0) {
+ size_t count;
+ char tag[2];
+
+ next = strnchr(ptr, got, '\n');
+ if (next) {
+ count = next - ptr;
+ *next = 0;
+ tag[0] = '>';
+ tag[1] = '<';
+ } else {
+ count = got;
+ tag[0] = '}';
+ tag[1] = '{';
+ }
+
+ if (count > MAX_CHUNK) {
+ size_t pos;
+ char *ptr2 = ptr;
+
+ for (pos = MAX_CHUNK; pos < count; pos += MAX_CHUNK) {
+ char chr = ptr[pos];
+
+ ptr[pos] = 0;
+ drm_info(&i915->drm, "[Capture/%d.%d] }%s{\n",
+ l_count, line++, ptr2);
+ ptr[pos] = chr;
+ ptr2 = ptr + pos;
+
+ /*
+ * If spewing large amounts of data via a serial console,
+ * this can be a very slow process. So be friendly and try
+ * not to cause 'softlockup on CPU' problems.
+ */
+ cond_resched();
+ }
+
+ if (ptr2 < (ptr + count))
+ drm_info(&i915->drm, "[Capture/%d.%d] %c%s%c\n",
+ l_count, line++, tag[0], ptr2, tag[1]);
+ else if (tag[0] == '>')
+ drm_info(&i915->drm, "[Capture/%d.%d] ><\n",
+ l_count, line++);
+ } else {
+ drm_info(&i915->drm, "[Capture/%d.%d] %c%s%c\n",
+ l_count, line++, tag[0], ptr, tag[1]);
+ }
+
+ ptr = next;
+ got -= count;
+ if (next) {
+ ptr++;
+ got--;
+ }
+
+ /* As above. */
+ cond_resched();
+ }
+
+ if (got)
+ drm_info(&i915->drm, "[Capture/%d.%d] Got %zd bytes remaining!\n",
+ l_count, line++, got);
+ }
+
+ kvfree(buf);
+
+ drm_info(&i915->drm, "[Capture/%d.%d] Dumped %zd bytes\n", l_count, line++, pos_err);
+}
+#endif
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.h b/drivers/gpu/drm/i915/i915_gpu_error.h
index a91932cc6531..a78c061ce26f 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.h
+++ b/drivers/gpu/drm/i915/i915_gpu_error.h
@@ -258,6 +258,16 @@ static inline u32 i915_reset_engine_count(struct i915_gpu_error *error,
#define CORE_DUMP_FLAG_NONE 0x0
#define CORE_DUMP_FLAG_IS_GUC_CAPTURE BIT(0)
+#if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR) && IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)
+void intel_klog_error_capture(struct intel_gt *gt,
+ intel_engine_mask_t engine_mask);
+#else
+static inline void intel_klog_error_capture(struct intel_gt *gt,
+ intel_engine_mask_t engine_mask)
+{
+}
+#endif
+
#if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR)
__printf(2, 3)
diff --git a/drivers/gpu/drm/i915/i915_hwmon.c b/drivers/gpu/drm/i915/i915_hwmon.c
index e99e8c97ef01..975da8e7f2a9 100644
--- a/drivers/gpu/drm/i915/i915_hwmon.c
+++ b/drivers/gpu/drm/i915/i915_hwmon.c
@@ -50,6 +50,8 @@ struct hwm_drvdata {
struct hwm_energy_info ei; /* Energy info for energy1_input */
char name[12];
int gt_n;
+ bool reset_in_progress;
+ wait_queue_head_t waitq;
};
struct i915_hwmon {
@@ -396,31 +398,56 @@ hwm_power_max_write(struct hwm_drvdata *ddat, long val)
{
struct i915_hwmon *hwmon = ddat->hwmon;
intel_wakeref_t wakeref;
+ DEFINE_WAIT(wait);
+ int ret = 0;
u32 nval;
- /* Disable PL1 limit and verify, because the limit cannot be disabled on all platforms */
- if (val == PL1_DISABLE) {
+ /* Block waiting for GuC reset to complete when needed */
+ for (;;) {
mutex_lock(&hwmon->hwmon_lock);
- with_intel_runtime_pm(ddat->uncore->rpm, wakeref) {
- intel_uncore_rmw(ddat->uncore, hwmon->rg.pkg_rapl_limit,
- PKG_PWR_LIM_1_EN, 0);
- nval = intel_uncore_read(ddat->uncore, hwmon->rg.pkg_rapl_limit);
+
+ prepare_to_wait(&ddat->waitq, &wait, TASK_INTERRUPTIBLE);
+
+ if (!hwmon->ddat.reset_in_progress)
+ break;
+
+ if (signal_pending(current)) {
+ ret = -EINTR;
+ break;
}
+
mutex_unlock(&hwmon->hwmon_lock);
+ schedule();
+ }
+ finish_wait(&ddat->waitq, &wait);
+ if (ret)
+ goto unlock;
+
+ wakeref = intel_runtime_pm_get(ddat->uncore->rpm);
+
+ /* Disable PL1 limit and verify, because the limit cannot be disabled on all platforms */
+ if (val == PL1_DISABLE) {
+ intel_uncore_rmw(ddat->uncore, hwmon->rg.pkg_rapl_limit,
+ PKG_PWR_LIM_1_EN, 0);
+ nval = intel_uncore_read(ddat->uncore, hwmon->rg.pkg_rapl_limit);
+
if (nval & PKG_PWR_LIM_1_EN)
- return -ENODEV;
- return 0;
+ ret = -ENODEV;
+ goto exit;
}
/* Computation in 64-bits to avoid overflow. Round to nearest. */
nval = DIV_ROUND_CLOSEST_ULL((u64)val << hwmon->scl_shift_power, SF_POWER);
nval = PKG_PWR_LIM_1_EN | REG_FIELD_PREP(PKG_PWR_LIM_1, nval);
- hwm_locked_with_pm_intel_uncore_rmw(ddat, hwmon->rg.pkg_rapl_limit,
- PKG_PWR_LIM_1_EN | PKG_PWR_LIM_1,
- nval);
- return 0;
+ intel_uncore_rmw(ddat->uncore, hwmon->rg.pkg_rapl_limit,
+ PKG_PWR_LIM_1_EN | PKG_PWR_LIM_1, nval);
+exit:
+ intel_runtime_pm_put(ddat->uncore->rpm, wakeref);
+unlock:
+ mutex_unlock(&hwmon->hwmon_lock);
+ return ret;
}
static int
@@ -470,6 +497,41 @@ hwm_power_write(struct hwm_drvdata *ddat, u32 attr, int chan, long val)
}
}
+void i915_hwmon_power_max_disable(struct drm_i915_private *i915, bool *old)
+{
+ struct i915_hwmon *hwmon = i915->hwmon;
+ u32 r;
+
+ if (!hwmon || !i915_mmio_reg_valid(hwmon->rg.pkg_rapl_limit))
+ return;
+
+ mutex_lock(&hwmon->hwmon_lock);
+
+ hwmon->ddat.reset_in_progress = true;
+ r = intel_uncore_rmw(hwmon->ddat.uncore, hwmon->rg.pkg_rapl_limit,
+ PKG_PWR_LIM_1_EN, 0);
+ *old = !!(r & PKG_PWR_LIM_1_EN);
+
+ mutex_unlock(&hwmon->hwmon_lock);
+}
+
+void i915_hwmon_power_max_restore(struct drm_i915_private *i915, bool old)
+{
+ struct i915_hwmon *hwmon = i915->hwmon;
+
+ if (!hwmon || !i915_mmio_reg_valid(hwmon->rg.pkg_rapl_limit))
+ return;
+
+ mutex_lock(&hwmon->hwmon_lock);
+
+ intel_uncore_rmw(hwmon->ddat.uncore, hwmon->rg.pkg_rapl_limit,
+ PKG_PWR_LIM_1_EN, old ? PKG_PWR_LIM_1_EN : 0);
+ hwmon->ddat.reset_in_progress = false;
+ wake_up_all(&hwmon->ddat.waitq);
+
+ mutex_unlock(&hwmon->hwmon_lock);
+}
+
static umode_t
hwm_energy_is_visible(const struct hwm_drvdata *ddat, u32 attr)
{
@@ -742,6 +804,7 @@ void i915_hwmon_register(struct drm_i915_private *i915)
ddat->uncore = &i915->uncore;
snprintf(ddat->name, sizeof(ddat->name), "i915");
ddat->gt_n = -1;
+ init_waitqueue_head(&ddat->waitq);
for_each_gt(gt, i915, i) {
ddat_gt = hwmon->ddat_gt + i;
diff --git a/drivers/gpu/drm/i915/i915_hwmon.h b/drivers/gpu/drm/i915/i915_hwmon.h
index 7ca9cf2c34c9..0fcb7de84406 100644
--- a/drivers/gpu/drm/i915/i915_hwmon.h
+++ b/drivers/gpu/drm/i915/i915_hwmon.h
@@ -7,14 +7,21 @@
#ifndef __I915_HWMON_H__
#define __I915_HWMON_H__
+#include <linux/types.h>
+
struct drm_i915_private;
+struct intel_gt;
#if IS_REACHABLE(CONFIG_HWMON)
void i915_hwmon_register(struct drm_i915_private *i915);
void i915_hwmon_unregister(struct drm_i915_private *i915);
+void i915_hwmon_power_max_disable(struct drm_i915_private *i915, bool *old);
+void i915_hwmon_power_max_restore(struct drm_i915_private *i915, bool old);
#else
static inline void i915_hwmon_register(struct drm_i915_private *i915) { };
static inline void i915_hwmon_unregister(struct drm_i915_private *i915) { };
+static inline void i915_hwmon_power_max_disable(struct drm_i915_private *i915, bool *old) { };
+static inline void i915_hwmon_power_max_restore(struct drm_i915_private *i915, bool old) { };
#endif
#endif /* __I915_HWMON_H__ */
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index c2de0ae2d347..82fbabcdd7a5 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -738,12 +738,15 @@ static void gen11_irq_reset(struct drm_i915_private *dev_priv)
static void dg1_irq_reset(struct drm_i915_private *dev_priv)
{
- struct intel_gt *gt = to_gt(dev_priv);
- struct intel_uncore *uncore = gt->uncore;
+ struct intel_uncore *uncore = &dev_priv->uncore;
+ struct intel_gt *gt;
+ unsigned int i;
dg1_master_intr_disable(dev_priv->uncore.regs);
- gen11_gt_irq_reset(gt);
+ for_each_gt(gt, dev_priv, i)
+ gen11_gt_irq_reset(gt);
+
gen11_display_irq_reset(dev_priv);
GEN3_IRQ_RESET(uncore, GEN11_GU_MISC_);
@@ -856,11 +859,13 @@ static void gen11_irq_postinstall(struct drm_i915_private *dev_priv)
static void dg1_irq_postinstall(struct drm_i915_private *dev_priv)
{
- struct intel_gt *gt = to_gt(dev_priv);
- struct intel_uncore *uncore = gt->uncore;
+ struct intel_uncore *uncore = &dev_priv->uncore;
u32 gu_misc_masked = GEN11_GU_MISC_GSE;
+ struct intel_gt *gt;
+ unsigned int i;
- gen11_gt_irq_postinstall(gt);
+ for_each_gt(gt, dev_priv, i)
+ gen11_gt_irq_postinstall(gt);
GEN3_IRQ_INIT(uncore, GEN11_GU_MISC_, ~gu_misc_masked, gu_misc_masked);
diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
index 34bc732a6375..928975d5fe2f 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -30,6 +30,7 @@
#include "display/intel_display_driver.h"
#include "gt/intel_gt_regs.h"
#include "gt/intel_sa_media.h"
+#include "gem/i915_gem_object_types.h"
#include "i915_driver.h"
#include "i915_drv.h"
@@ -42,6 +43,38 @@
.__runtime.graphics.ip.ver = (x), \
.__runtime.media.ip.ver = (x)
+#define LEGACY_CACHELEVEL \
+ .cachelevel_to_pat = { \
+ [I915_CACHE_NONE] = 0, \
+ [I915_CACHE_LLC] = 1, \
+ [I915_CACHE_L3_LLC] = 2, \
+ [I915_CACHE_WT] = 3, \
+ }
+
+#define TGL_CACHELEVEL \
+ .cachelevel_to_pat = { \
+ [I915_CACHE_NONE] = 3, \
+ [I915_CACHE_LLC] = 0, \
+ [I915_CACHE_L3_LLC] = 0, \
+ [I915_CACHE_WT] = 2, \
+ }
+
+#define PVC_CACHELEVEL \
+ .cachelevel_to_pat = { \
+ [I915_CACHE_NONE] = 0, \
+ [I915_CACHE_LLC] = 3, \
+ [I915_CACHE_L3_LLC] = 3, \
+ [I915_CACHE_WT] = 2, \
+ }
+
+#define MTL_CACHELEVEL \
+ .cachelevel_to_pat = { \
+ [I915_CACHE_NONE] = 2, \
+ [I915_CACHE_LLC] = 3, \
+ [I915_CACHE_L3_LLC] = 3, \
+ [I915_CACHE_WT] = 1, \
+ }
+
/* Keep in gen based order, and chronological order within a gen */
#define GEN_DEFAULT_PAGE_SIZES \
@@ -61,8 +94,10 @@
.has_snoop = true, \
.has_coherent_ggtt = false, \
.dma_mask_size = 32, \
+ .max_pat_index = 3, \
GEN_DEFAULT_PAGE_SIZES, \
- GEN_DEFAULT_REGIONS
+ GEN_DEFAULT_REGIONS, \
+ LEGACY_CACHELEVEL
#define I845_FEATURES \
GEN(2), \
@@ -74,8 +109,10 @@
.has_snoop = true, \
.has_coherent_ggtt = false, \
.dma_mask_size = 32, \
+ .max_pat_index = 3, \
GEN_DEFAULT_PAGE_SIZES, \
- GEN_DEFAULT_REGIONS
+ GEN_DEFAULT_REGIONS, \
+ LEGACY_CACHELEVEL
static const struct intel_device_info i830_info = {
I830_FEATURES,
@@ -105,8 +142,10 @@ static const struct intel_device_info i865g_info = {
.has_snoop = true, \
.has_coherent_ggtt = true, \
.dma_mask_size = 32, \
+ .max_pat_index = 3, \
GEN_DEFAULT_PAGE_SIZES, \
- GEN_DEFAULT_REGIONS
+ GEN_DEFAULT_REGIONS, \
+ LEGACY_CACHELEVEL
static const struct intel_device_info i915g_info = {
GEN3_FEATURES,
@@ -166,8 +205,10 @@ static const struct intel_device_info pnv_m_info = {
.has_snoop = true, \
.has_coherent_ggtt = true, \
.dma_mask_size = 36, \
+ .max_pat_index = 3, \
GEN_DEFAULT_PAGE_SIZES, \
- GEN_DEFAULT_REGIONS
+ GEN_DEFAULT_REGIONS, \
+ LEGACY_CACHELEVEL
static const struct intel_device_info i965g_info = {
GEN4_FEATURES,
@@ -208,8 +249,10 @@ static const struct intel_device_info gm45_info = {
/* ilk does support rc6, but we do not implement [power] contexts */ \
.has_rc6 = 0, \
.dma_mask_size = 36, \
+ .max_pat_index = 3, \
GEN_DEFAULT_PAGE_SIZES, \
- GEN_DEFAULT_REGIONS
+ GEN_DEFAULT_REGIONS, \
+ LEGACY_CACHELEVEL
static const struct intel_device_info ilk_d_info = {
GEN5_FEATURES,
@@ -234,10 +277,12 @@ static const struct intel_device_info ilk_m_info = {
.has_rc6p = 0, \
.has_rps = true, \
.dma_mask_size = 40, \
+ .max_pat_index = 3, \
.__runtime.ppgtt_type = INTEL_PPGTT_ALIASING, \
.__runtime.ppgtt_size = 31, \
GEN_DEFAULT_PAGE_SIZES, \
- GEN_DEFAULT_REGIONS
+ GEN_DEFAULT_REGIONS, \
+ LEGACY_CACHELEVEL
#define SNB_D_PLATFORM \
GEN6_FEATURES, \
@@ -280,10 +325,12 @@ static const struct intel_device_info snb_m_gt2_info = {
.has_reset_engine = true, \
.has_rps = true, \
.dma_mask_size = 40, \
+ .max_pat_index = 3, \
.__runtime.ppgtt_type = INTEL_PPGTT_ALIASING, \
.__runtime.ppgtt_size = 31, \
GEN_DEFAULT_PAGE_SIZES, \
- GEN_DEFAULT_REGIONS
+ GEN_DEFAULT_REGIONS, \
+ LEGACY_CACHELEVEL
#define IVB_D_PLATFORM \
GEN7_FEATURES, \
@@ -332,6 +379,7 @@ static const struct intel_device_info vlv_info = {
.has_reset_engine = true,
.has_rps = true,
.dma_mask_size = 40,
+ .max_pat_index = 3,
.__runtime.ppgtt_type = INTEL_PPGTT_ALIASING,
.__runtime.ppgtt_size = 31,
.has_snoop = true,
@@ -339,6 +387,7 @@ static const struct intel_device_info vlv_info = {
.__runtime.platform_engine_mask = BIT(RCS0) | BIT(VCS0) | BIT(BCS0),
GEN_DEFAULT_PAGE_SIZES,
GEN_DEFAULT_REGIONS,
+ LEGACY_CACHELEVEL,
};
#define G75_FEATURES \
@@ -416,6 +465,7 @@ static const struct intel_device_info chv_info = {
.has_rps = true,
.has_logical_ring_contexts = 1,
.dma_mask_size = 39,
+ .max_pat_index = 3,
.__runtime.ppgtt_type = INTEL_PPGTT_FULL,
.__runtime.ppgtt_size = 32,
.has_reset_engine = 1,
@@ -423,6 +473,7 @@ static const struct intel_device_info chv_info = {
.has_coherent_ggtt = false,
GEN_DEFAULT_PAGE_SIZES,
GEN_DEFAULT_REGIONS,
+ LEGACY_CACHELEVEL,
};
#define GEN9_DEFAULT_PAGE_SIZES \
@@ -482,8 +533,10 @@ static const struct intel_device_info skl_gt4_info = {
.has_reset_engine = 1, \
.has_snoop = true, \
.has_coherent_ggtt = false, \
+ .max_pat_index = 3, \
GEN9_DEFAULT_PAGE_SIZES, \
- GEN_DEFAULT_REGIONS
+ GEN_DEFAULT_REGIONS, \
+ LEGACY_CACHELEVEL
static const struct intel_device_info bxt_info = {
GEN9_LP_FEATURES,
@@ -587,8 +640,10 @@ static const struct intel_device_info jsl_info = {
#define GEN12_FEATURES \
GEN11_FEATURES, \
GEN(12), \
+ TGL_CACHELEVEL, \
.has_global_mocs = 1, \
- .has_pxp = 1
+ .has_pxp = 1, \
+ .max_pat_index = 3
static const struct intel_device_info tgl_info = {
GEN12_FEATURES,
@@ -653,6 +708,7 @@ static const struct intel_device_info adl_p_info = {
.__runtime.graphics.ip.ver = 12, \
.__runtime.graphics.ip.rel = 50, \
XE_HP_PAGE_SIZES, \
+ TGL_CACHELEVEL, \
.dma_mask_size = 46, \
.has_3d_pipeline = 1, \
.has_64bit_reloc = 1, \
@@ -671,6 +727,7 @@ static const struct intel_device_info adl_p_info = {
.has_reset_engine = 1, \
.has_rps = 1, \
.has_runtime_pm = 1, \
+ .max_pat_index = 3, \
.__runtime.ppgtt_size = 48, \
.__runtime.ppgtt_type = INTEL_PPGTT_FULL
@@ -740,11 +797,13 @@ static const struct intel_device_info pvc_info = {
.__runtime.media.ip.rel = 60,
PLATFORM(INTEL_PONTEVECCHIO),
.has_flat_ccs = 0,
+ .max_pat_index = 7,
.__runtime.platform_engine_mask =
BIT(BCS0) |
BIT(VCS0) |
BIT(CCS0) | BIT(CCS1) | BIT(CCS2) | BIT(CCS3),
.require_force_probe = 1,
+ PVC_CACHELEVEL,
};
static const struct intel_gt_definition xelpmp_extra_gt[] = {
@@ -774,9 +833,12 @@ static const struct intel_device_info mtl_info = {
.has_llc = 0,
.has_mslice_steering = 0,
.has_snoop = 1,
+ .max_pat_index = 4,
+ .has_pxp = 1,
.__runtime.memory_regions = REGION_SMEM | REGION_STOLEN_LMEM,
.__runtime.platform_engine_mask = BIT(RCS0) | BIT(BCS0) | BIT(CCS0),
.require_force_probe = 1,
+ MTL_CACHELEVEL,
};
#undef PLATFORM
diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c
index 050b8ae7b8e7..19d5652300ee 100644
--- a/drivers/gpu/drm/i915/i915_perf.c
+++ b/drivers/gpu/drm/i915/i915_perf.c
@@ -5300,6 +5300,7 @@ void i915_perf_fini(struct drm_i915_private *i915)
/**
* i915_perf_ioctl_version - Version of the i915-perf subsystem
+ * @i915: The i915 device
*
* This version number is used by userspace to detect available features.
*/
diff --git a/drivers/gpu/drm/i915/i915_perf_oa_regs.h b/drivers/gpu/drm/i915/i915_perf_oa_regs.h
index ba103875e19f..e5ac7a8b5cb6 100644
--- a/drivers/gpu/drm/i915/i915_perf_oa_regs.h
+++ b/drivers/gpu/drm/i915/i915_perf_oa_regs.h
@@ -134,10 +134,6 @@
#define GDT_CHICKEN_BITS _MMIO(0x9840)
#define GT_NOA_ENABLE 0x00000080
-#define GEN12_SQCNT1 _MMIO(0x8718)
-#define GEN12_SQCNT1_PMON_ENABLE REG_BIT(30)
-#define GEN12_SQCNT1_OABPC REG_BIT(29)
-
/* Gen12 OAM unit */
#define GEN12_OAM_HEAD_POINTER_OFFSET (0x1a0)
#define GEN12_OAM_HEAD_POINTER_MASK 0xffffffc0
diff --git a/drivers/gpu/drm/i915/i915_pmu.c b/drivers/gpu/drm/i915/i915_pmu.c
index 7ece883a7d95..a814583e19fd 100644
--- a/drivers/gpu/drm/i915/i915_pmu.c
+++ b/drivers/gpu/drm/i915/i915_pmu.c
@@ -10,6 +10,7 @@
#include "gt/intel_engine_pm.h"
#include "gt/intel_engine_regs.h"
#include "gt/intel_engine_user.h"
+#include "gt/intel_gt.h"
#include "gt/intel_gt_pm.h"
#include "gt/intel_gt_regs.h"
#include "gt/intel_rc6.h"
@@ -50,16 +51,26 @@ static u8 engine_event_instance(struct perf_event *event)
return (event->attr.config >> I915_PMU_SAMPLE_BITS) & 0xff;
}
-static bool is_engine_config(u64 config)
+static bool is_engine_config(const u64 config)
{
return config < __I915_PMU_OTHER(0);
}
+static unsigned int config_gt_id(const u64 config)
+{
+ return config >> __I915_PMU_GT_SHIFT;
+}
+
+static u64 config_counter(const u64 config)
+{
+ return config & ~(~0ULL << __I915_PMU_GT_SHIFT);
+}
+
static unsigned int other_bit(const u64 config)
{
unsigned int val;
- switch (config) {
+ switch (config_counter(config)) {
case I915_PMU_ACTUAL_FREQUENCY:
val = __I915_PMU_ACTUAL_FREQUENCY_ENABLED;
break;
@@ -77,7 +88,9 @@ static unsigned int other_bit(const u64 config)
return -1;
}
- return I915_ENGINE_SAMPLE_COUNT + val;
+ return I915_ENGINE_SAMPLE_COUNT +
+ config_gt_id(config) * __I915_PMU_TRACKED_EVENT_COUNT +
+ val;
}
static unsigned int config_bit(const u64 config)
@@ -88,9 +101,20 @@ static unsigned int config_bit(const u64 config)
return other_bit(config);
}
-static u64 config_mask(u64 config)
+static u32 config_mask(const u64 config)
{
- return BIT_ULL(config_bit(config));
+ unsigned int bit = config_bit(config);
+
+ if (__builtin_constant_p(config))
+ BUILD_BUG_ON(bit >
+ BITS_PER_TYPE(typeof_member(struct i915_pmu,
+ enable)) - 1);
+ else
+ WARN_ON_ONCE(bit >
+ BITS_PER_TYPE(typeof_member(struct i915_pmu,
+ enable)) - 1);
+
+ return BIT(config_bit(config));
}
static bool is_engine_event(struct perf_event *event)
@@ -103,6 +127,18 @@ static unsigned int event_bit(struct perf_event *event)
return config_bit(event->attr.config);
}
+static u32 frequency_enabled_mask(void)
+{
+ unsigned int i;
+ u32 mask = 0;
+
+ for (i = 0; i < I915_PMU_MAX_GTS; i++)
+ mask |= config_mask(__I915_PMU_ACTUAL_FREQUENCY(i)) |
+ config_mask(__I915_PMU_REQUESTED_FREQUENCY(i));
+
+ return mask;
+}
+
static bool pmu_needs_timer(struct i915_pmu *pmu, bool gpu_active)
{
struct drm_i915_private *i915 = container_of(pmu, typeof(*i915), pmu);
@@ -119,9 +155,7 @@ static bool pmu_needs_timer(struct i915_pmu *pmu, bool gpu_active)
* Mask out all the ones which do not need the timer, or in
* other words keep all the ones that could need the timer.
*/
- enable &= config_mask(I915_PMU_ACTUAL_FREQUENCY) |
- config_mask(I915_PMU_REQUESTED_FREQUENCY) |
- ENGINE_SAMPLE_MASK;
+ enable &= frequency_enabled_mask() | ENGINE_SAMPLE_MASK;
/*
* When the GPU is idle per-engine counters do not need to be
@@ -163,9 +197,37 @@ static inline s64 ktime_since_raw(const ktime_t kt)
return ktime_to_ns(ktime_sub(ktime_get_raw(), kt));
}
+static unsigned int
+__sample_idx(struct i915_pmu *pmu, unsigned int gt_id, int sample)
+{
+ unsigned int idx = gt_id * __I915_NUM_PMU_SAMPLERS + sample;
+
+ GEM_BUG_ON(idx >= ARRAY_SIZE(pmu->sample));
+
+ return idx;
+}
+
+static u64 read_sample(struct i915_pmu *pmu, unsigned int gt_id, int sample)
+{
+ return pmu->sample[__sample_idx(pmu, gt_id, sample)].cur;
+}
+
+static void
+store_sample(struct i915_pmu *pmu, unsigned int gt_id, int sample, u64 val)
+{
+ pmu->sample[__sample_idx(pmu, gt_id, sample)].cur = val;
+}
+
+static void
+add_sample_mult(struct i915_pmu *pmu, unsigned int gt_id, int sample, u32 val, u32 mul)
+{
+ pmu->sample[__sample_idx(pmu, gt_id, sample)].cur += mul_u32_u32(val, mul);
+}
+
static u64 get_rc6(struct intel_gt *gt)
{
struct drm_i915_private *i915 = gt->i915;
+ const unsigned int gt_id = gt->info.id;
struct i915_pmu *pmu = &i915->pmu;
unsigned long flags;
bool awake = false;
@@ -180,7 +242,7 @@ static u64 get_rc6(struct intel_gt *gt)
spin_lock_irqsave(&pmu->lock, flags);
if (awake) {
- pmu->sample[__I915_SAMPLE_RC6].cur = val;
+ store_sample(pmu, gt_id, __I915_SAMPLE_RC6, val);
} else {
/*
* We think we are runtime suspended.
@@ -189,14 +251,14 @@ static u64 get_rc6(struct intel_gt *gt)
* on top of the last known real value, as the approximated RC6
* counter value.
*/
- val = ktime_since_raw(pmu->sleep_last);
- val += pmu->sample[__I915_SAMPLE_RC6].cur;
+ val = ktime_since_raw(pmu->sleep_last[gt_id]);
+ val += read_sample(pmu, gt_id, __I915_SAMPLE_RC6);
}
- if (val < pmu->sample[__I915_SAMPLE_RC6_LAST_REPORTED].cur)
- val = pmu->sample[__I915_SAMPLE_RC6_LAST_REPORTED].cur;
+ if (val < read_sample(pmu, gt_id, __I915_SAMPLE_RC6_LAST_REPORTED))
+ val = read_sample(pmu, gt_id, __I915_SAMPLE_RC6_LAST_REPORTED);
else
- pmu->sample[__I915_SAMPLE_RC6_LAST_REPORTED].cur = val;
+ store_sample(pmu, gt_id, __I915_SAMPLE_RC6_LAST_REPORTED, val);
spin_unlock_irqrestore(&pmu->lock, flags);
@@ -206,22 +268,29 @@ static u64 get_rc6(struct intel_gt *gt)
static void init_rc6(struct i915_pmu *pmu)
{
struct drm_i915_private *i915 = container_of(pmu, typeof(*i915), pmu);
- intel_wakeref_t wakeref;
+ struct intel_gt *gt;
+ unsigned int i;
- with_intel_runtime_pm(to_gt(i915)->uncore->rpm, wakeref) {
- pmu->sample[__I915_SAMPLE_RC6].cur = __get_rc6(to_gt(i915));
- pmu->sample[__I915_SAMPLE_RC6_LAST_REPORTED].cur =
- pmu->sample[__I915_SAMPLE_RC6].cur;
- pmu->sleep_last = ktime_get_raw();
+ for_each_gt(gt, i915, i) {
+ intel_wakeref_t wakeref;
+
+ with_intel_runtime_pm(gt->uncore->rpm, wakeref) {
+ u64 val = __get_rc6(gt);
+
+ store_sample(pmu, i, __I915_SAMPLE_RC6, val);
+ store_sample(pmu, i, __I915_SAMPLE_RC6_LAST_REPORTED,
+ val);
+ pmu->sleep_last[i] = ktime_get_raw();
+ }
}
}
-static void park_rc6(struct drm_i915_private *i915)
+static void park_rc6(struct intel_gt *gt)
{
- struct i915_pmu *pmu = &i915->pmu;
+ struct i915_pmu *pmu = &gt->i915->pmu;
- pmu->sample[__I915_SAMPLE_RC6].cur = __get_rc6(to_gt(i915));
- pmu->sleep_last = ktime_get_raw();
+ store_sample(pmu, gt->info.id, __I915_SAMPLE_RC6, __get_rc6(gt));
+ pmu->sleep_last[gt->info.id] = ktime_get_raw();
}
static void __i915_pmu_maybe_start_timer(struct i915_pmu *pmu)
@@ -235,29 +304,31 @@ static void __i915_pmu_maybe_start_timer(struct i915_pmu *pmu)
}
}
-void i915_pmu_gt_parked(struct drm_i915_private *i915)
+void i915_pmu_gt_parked(struct intel_gt *gt)
{
- struct i915_pmu *pmu = &i915->pmu;
+ struct i915_pmu *pmu = &gt->i915->pmu;
if (!pmu->base.event_init)
return;
spin_lock_irq(&pmu->lock);
- park_rc6(i915);
+ park_rc6(gt);
/*
* Signal sampling timer to stop if only engine events are enabled and
* GPU went idle.
*/
- pmu->timer_enabled = pmu_needs_timer(pmu, false);
+ pmu->unparked &= ~BIT(gt->info.id);
+ if (pmu->unparked == 0)
+ pmu->timer_enabled = pmu_needs_timer(pmu, false);
spin_unlock_irq(&pmu->lock);
}
-void i915_pmu_gt_unparked(struct drm_i915_private *i915)
+void i915_pmu_gt_unparked(struct intel_gt *gt)
{
- struct i915_pmu *pmu = &i915->pmu;
+ struct i915_pmu *pmu = &gt->i915->pmu;
if (!pmu->base.event_init)
return;
@@ -267,7 +338,10 @@ void i915_pmu_gt_unparked(struct drm_i915_private *i915)
/*
* Re-enable sampling timer when GPU goes active.
*/
- __i915_pmu_maybe_start_timer(pmu);
+ if (pmu->unparked == 0)
+ __i915_pmu_maybe_start_timer(pmu);
+
+ pmu->unparked |= BIT(gt->info.id);
spin_unlock_irq(&pmu->lock);
}
@@ -338,6 +412,9 @@ engines_sample(struct intel_gt *gt, unsigned int period_ns)
return;
for_each_engine(engine, gt, id) {
+ if (!engine->pmu.enable)
+ continue;
+
if (!intel_engine_pm_get_if_awake(engine))
continue;
@@ -353,34 +430,30 @@ engines_sample(struct intel_gt *gt, unsigned int period_ns)
}
}
-static void
-add_sample_mult(struct i915_pmu_sample *sample, u32 val, u32 mul)
-{
- sample->cur += mul_u32_u32(val, mul);
-}
-
-static bool frequency_sampling_enabled(struct i915_pmu *pmu)
+static bool
+frequency_sampling_enabled(struct i915_pmu *pmu, unsigned int gt)
{
return pmu->enable &
- (config_mask(I915_PMU_ACTUAL_FREQUENCY) |
- config_mask(I915_PMU_REQUESTED_FREQUENCY));
+ (config_mask(__I915_PMU_ACTUAL_FREQUENCY(gt)) |
+ config_mask(__I915_PMU_REQUESTED_FREQUENCY(gt)));
}
static void
frequency_sample(struct intel_gt *gt, unsigned int period_ns)
{
struct drm_i915_private *i915 = gt->i915;
+ const unsigned int gt_id = gt->info.id;
struct i915_pmu *pmu = &i915->pmu;
struct intel_rps *rps = &gt->rps;
- if (!frequency_sampling_enabled(pmu))
+ if (!frequency_sampling_enabled(pmu, gt_id))
return;
/* Report 0/0 (actual/requested) frequency while parked. */
if (!intel_gt_pm_get_if_awake(gt))
return;
- if (pmu->enable & config_mask(I915_PMU_ACTUAL_FREQUENCY)) {
+ if (pmu->enable & config_mask(__I915_PMU_ACTUAL_FREQUENCY(gt_id))) {
u32 val;
/*
@@ -396,12 +469,12 @@ frequency_sample(struct intel_gt *gt, unsigned int period_ns)
if (!val)
val = intel_gpu_freq(rps, rps->cur_freq);
- add_sample_mult(&pmu->sample[__I915_SAMPLE_FREQ_ACT],
+ add_sample_mult(pmu, gt_id, __I915_SAMPLE_FREQ_ACT,
val, period_ns / 1000);
}
- if (pmu->enable & config_mask(I915_PMU_REQUESTED_FREQUENCY)) {
- add_sample_mult(&pmu->sample[__I915_SAMPLE_FREQ_REQ],
+ if (pmu->enable & config_mask(__I915_PMU_REQUESTED_FREQUENCY(gt_id))) {
+ add_sample_mult(pmu, gt_id, __I915_SAMPLE_FREQ_REQ,
intel_rps_get_requested_frequency(rps),
period_ns / 1000);
}
@@ -414,8 +487,9 @@ static enum hrtimer_restart i915_sample(struct hrtimer *hrtimer)
struct drm_i915_private *i915 =
container_of(hrtimer, struct drm_i915_private, pmu.timer);
struct i915_pmu *pmu = &i915->pmu;
- struct intel_gt *gt = to_gt(i915);
unsigned int period_ns;
+ struct intel_gt *gt;
+ unsigned int i;
ktime_t now;
if (!READ_ONCE(pmu->timer_enabled))
@@ -431,8 +505,14 @@ static enum hrtimer_restart i915_sample(struct hrtimer *hrtimer)
* grabbing the forcewake. However the potential error from timer call-
* back delay greatly dominates this so we keep it simple.
*/
- engines_sample(gt, period_ns);
- frequency_sample(gt, period_ns);
+
+ for_each_gt(gt, i915, i) {
+ if (!(pmu->unparked & BIT(i)))
+ continue;
+
+ engines_sample(gt, period_ns);
+ frequency_sample(gt, period_ns);
+ }
hrtimer_forward(hrtimer, now, ns_to_ktime(PERIOD));
@@ -473,7 +553,13 @@ config_status(struct drm_i915_private *i915, u64 config)
{
struct intel_gt *gt = to_gt(i915);
- switch (config) {
+ unsigned int gt_id = config_gt_id(config);
+ unsigned int max_gt_id = HAS_EXTRA_GT_LIST(i915) ? 1 : 0;
+
+ if (gt_id > max_gt_id)
+ return -ENOENT;
+
+ switch (config_counter(config)) {
case I915_PMU_ACTUAL_FREQUENCY:
if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915))
/* Requires a mutex for sampling! */
@@ -484,6 +570,8 @@ config_status(struct drm_i915_private *i915, u64 config)
return -ENODEV;
break;
case I915_PMU_INTERRUPTS:
+ if (gt_id)
+ return -ENOENT;
break;
case I915_PMU_RC6_RESIDENCY:
if (!gt->rc6.supported)
@@ -581,22 +669,27 @@ static u64 __i915_pmu_event_read(struct perf_event *event)
val = engine->pmu.sample[sample].cur;
}
} else {
- switch (event->attr.config) {
+ const unsigned int gt_id = config_gt_id(event->attr.config);
+ const u64 config = config_counter(event->attr.config);
+
+ switch (config) {
case I915_PMU_ACTUAL_FREQUENCY:
val =
- div_u64(pmu->sample[__I915_SAMPLE_FREQ_ACT].cur,
+ div_u64(read_sample(pmu, gt_id,
+ __I915_SAMPLE_FREQ_ACT),
USEC_PER_SEC /* to MHz */);
break;
case I915_PMU_REQUESTED_FREQUENCY:
val =
- div_u64(pmu->sample[__I915_SAMPLE_FREQ_REQ].cur,
+ div_u64(read_sample(pmu, gt_id,
+ __I915_SAMPLE_FREQ_REQ),
USEC_PER_SEC /* to MHz */);
break;
case I915_PMU_INTERRUPTS:
val = READ_ONCE(pmu->irq_count);
break;
case I915_PMU_RC6_RESIDENCY:
- val = get_rc6(to_gt(i915));
+ val = get_rc6(i915->gt[gt_id]);
break;
case I915_PMU_SOFTWARE_GT_AWAKE_TIME:
val = ktime_to_ns(intel_gt_get_awake_time(to_gt(i915)));
@@ -633,11 +726,10 @@ static void i915_pmu_enable(struct perf_event *event)
{
struct drm_i915_private *i915 =
container_of(event->pmu, typeof(*i915), pmu.base);
+ const unsigned int bit = event_bit(event);
struct i915_pmu *pmu = &i915->pmu;
unsigned long flags;
- unsigned int bit;
- bit = event_bit(event);
if (bit == -1)
goto update;
@@ -651,7 +743,7 @@ static void i915_pmu_enable(struct perf_event *event)
GEM_BUG_ON(bit >= ARRAY_SIZE(pmu->enable_count));
GEM_BUG_ON(pmu->enable_count[bit] == ~0);
- pmu->enable |= BIT_ULL(bit);
+ pmu->enable |= BIT(bit);
pmu->enable_count[bit]++;
/*
@@ -698,7 +790,7 @@ static void i915_pmu_disable(struct perf_event *event)
{
struct drm_i915_private *i915 =
container_of(event->pmu, typeof(*i915), pmu.base);
- unsigned int bit = event_bit(event);
+ const unsigned int bit = event_bit(event);
struct i915_pmu *pmu = &i915->pmu;
unsigned long flags;
@@ -734,7 +826,7 @@ static void i915_pmu_disable(struct perf_event *event)
* bitmask when the last listener on an event goes away.
*/
if (--pmu->enable_count[bit] == 0) {
- pmu->enable &= ~BIT_ULL(bit);
+ pmu->enable &= ~BIT(bit);
pmu->timer_enabled &= pmu_needs_timer(pmu, true);
}
@@ -848,11 +940,20 @@ static const struct attribute_group i915_pmu_cpumask_attr_group = {
.attrs = i915_cpumask_attrs,
};
-#define __event(__config, __name, __unit) \
+#define __event(__counter, __name, __unit) \
{ \
- .config = (__config), \
+ .counter = (__counter), \
.name = (__name), \
.unit = (__unit), \
+ .global = false, \
+}
+
+#define __global_event(__counter, __name, __unit) \
+{ \
+ .counter = (__counter), \
+ .name = (__name), \
+ .unit = (__unit), \
+ .global = true, \
}
#define __engine_event(__sample, __name) \
@@ -891,15 +992,16 @@ create_event_attributes(struct i915_pmu *pmu)
{
struct drm_i915_private *i915 = container_of(pmu, typeof(*i915), pmu);
static const struct {
- u64 config;
+ unsigned int counter;
const char *name;
const char *unit;
+ bool global;
} events[] = {
- __event(I915_PMU_ACTUAL_FREQUENCY, "actual-frequency", "M"),
- __event(I915_PMU_REQUESTED_FREQUENCY, "requested-frequency", "M"),
- __event(I915_PMU_INTERRUPTS, "interrupts", NULL),
- __event(I915_PMU_RC6_RESIDENCY, "rc6-residency", "ns"),
- __event(I915_PMU_SOFTWARE_GT_AWAKE_TIME, "software-gt-awake-time", "ns"),
+ __event(0, "actual-frequency", "M"),
+ __event(1, "requested-frequency", "M"),
+ __global_event(2, "interrupts", NULL),
+ __event(3, "rc6-residency", "ns"),
+ __event(4, "software-gt-awake-time", "ns"),
};
static const struct {
enum drm_i915_pmu_engine_sample sample;
@@ -914,12 +1016,17 @@ create_event_attributes(struct i915_pmu *pmu)
struct i915_ext_attribute *i915_attr = NULL, *i915_iter;
struct attribute **attr = NULL, **attr_iter;
struct intel_engine_cs *engine;
- unsigned int i;
+ struct intel_gt *gt;
+ unsigned int i, j;
/* Count how many counters we will be exposing. */
- for (i = 0; i < ARRAY_SIZE(events); i++) {
- if (!config_status(i915, events[i].config))
- count++;
+ for_each_gt(gt, i915, j) {
+ for (i = 0; i < ARRAY_SIZE(events); i++) {
+ u64 config = ___I915_PMU_OTHER(j, events[i].counter);
+
+ if (!config_status(i915, config))
+ count++;
+ }
}
for_each_uabi_engine(engine, i915) {
@@ -949,26 +1056,39 @@ create_event_attributes(struct i915_pmu *pmu)
attr_iter = attr;
/* Initialize supported non-engine counters. */
- for (i = 0; i < ARRAY_SIZE(events); i++) {
- char *str;
-
- if (config_status(i915, events[i].config))
- continue;
-
- str = kstrdup(events[i].name, GFP_KERNEL);
- if (!str)
- goto err;
+ for_each_gt(gt, i915, j) {
+ for (i = 0; i < ARRAY_SIZE(events); i++) {
+ u64 config = ___I915_PMU_OTHER(j, events[i].counter);
+ char *str;
- *attr_iter++ = &i915_iter->attr.attr;
- i915_iter = add_i915_attr(i915_iter, str, events[i].config);
+ if (config_status(i915, config))
+ continue;
- if (events[i].unit) {
- str = kasprintf(GFP_KERNEL, "%s.unit", events[i].name);
+ if (events[i].global || !HAS_EXTRA_GT_LIST(i915))
+ str = kstrdup(events[i].name, GFP_KERNEL);
+ else
+ str = kasprintf(GFP_KERNEL, "%s-gt%u",
+ events[i].name, j);
if (!str)
goto err;
- *attr_iter++ = &pmu_iter->attr.attr;
- pmu_iter = add_pmu_attr(pmu_iter, str, events[i].unit);
+ *attr_iter++ = &i915_iter->attr.attr;
+ i915_iter = add_i915_attr(i915_iter, str, config);
+
+ if (events[i].unit) {
+ if (events[i].global || !HAS_EXTRA_GT_LIST(i915))
+ str = kasprintf(GFP_KERNEL, "%s.unit",
+ events[i].name);
+ else
+ str = kasprintf(GFP_KERNEL, "%s-gt%u.unit",
+ events[i].name, j);
+ if (!str)
+ goto err;
+
+ *attr_iter++ = &pmu_iter->attr.attr;
+ pmu_iter = add_pmu_attr(pmu_iter, str,
+ events[i].unit);
+ }
}
}
diff --git a/drivers/gpu/drm/i915/i915_pmu.h b/drivers/gpu/drm/i915/i915_pmu.h
index 449057648f39..33d80fbaab8b 100644
--- a/drivers/gpu/drm/i915/i915_pmu.h
+++ b/drivers/gpu/drm/i915/i915_pmu.h
@@ -13,8 +13,9 @@
#include <uapi/drm/i915_drm.h>
struct drm_i915_private;
+struct intel_gt;
-/**
+/*
* Non-engine events that we need to track enabled-disabled transition and
* current state.
*/
@@ -25,7 +26,7 @@ enum i915_pmu_tracked_events {
__I915_PMU_TRACKED_EVENT_COUNT, /* count marker */
};
-/**
+/*
* Slots used from the sampling timer (non-engine events) with some extras for
* convenience.
*/
@@ -37,13 +38,16 @@ enum {
__I915_NUM_PMU_SAMPLERS
};
-/**
+#define I915_PMU_MAX_GTS 2
+
+/*
* How many different events we track in the global PMU mask.
*
* It is also used to know to needed number of event reference counters.
*/
#define I915_PMU_MASK_BITS \
- (I915_ENGINE_SAMPLE_COUNT + __I915_PMU_TRACKED_EVENT_COUNT)
+ (I915_ENGINE_SAMPLE_COUNT + \
+ I915_PMU_MAX_GTS * __I915_PMU_TRACKED_EVENT_COUNT)
#define I915_ENGINE_SAMPLE_COUNT (I915_SAMPLE_SEMA + 1)
@@ -76,6 +80,10 @@ struct i915_pmu {
*/
spinlock_t lock;
/**
+ * @unparked: GT unparked mask.
+ */
+ unsigned int unparked;
+ /**
* @timer: Timer for internal i915 PMU sampling.
*/
struct hrtimer timer;
@@ -119,11 +127,11 @@ struct i915_pmu {
* Only global counters are held here, while the per-engine ones are in
* struct intel_engine_cs.
*/
- struct i915_pmu_sample sample[__I915_NUM_PMU_SAMPLERS];
+ struct i915_pmu_sample sample[I915_PMU_MAX_GTS * __I915_NUM_PMU_SAMPLERS];
/**
* @sleep_last: Last time GT parked for RC6 estimation.
*/
- ktime_t sleep_last;
+ ktime_t sleep_last[I915_PMU_MAX_GTS];
/**
* @irq_count: Number of interrupts
*
@@ -151,15 +159,15 @@ int i915_pmu_init(void);
void i915_pmu_exit(void);
void i915_pmu_register(struct drm_i915_private *i915);
void i915_pmu_unregister(struct drm_i915_private *i915);
-void i915_pmu_gt_parked(struct drm_i915_private *i915);
-void i915_pmu_gt_unparked(struct drm_i915_private *i915);
+void i915_pmu_gt_parked(struct intel_gt *gt);
+void i915_pmu_gt_unparked(struct intel_gt *gt);
#else
static inline int i915_pmu_init(void) { return 0; }
static inline void i915_pmu_exit(void) {}
static inline void i915_pmu_register(struct drm_i915_private *i915) {}
static inline void i915_pmu_unregister(struct drm_i915_private *i915) {}
-static inline void i915_pmu_gt_parked(struct drm_i915_private *i915) {}
-static inline void i915_pmu_gt_unparked(struct drm_i915_private *i915) {}
+static inline void i915_pmu_gt_parked(struct intel_gt *gt) {}
+static inline void i915_pmu_gt_unparked(struct intel_gt *gt) {}
#endif
#endif
diff --git a/drivers/gpu/drm/i915/i915_request.h b/drivers/gpu/drm/i915/i915_request.h
index f5e1bb5e857a..0ac55b2e4223 100644
--- a/drivers/gpu/drm/i915/i915_request.h
+++ b/drivers/gpu/drm/i915/i915_request.h
@@ -172,7 +172,7 @@ enum {
I915_FENCE_FLAG_COMPOSITE,
};
-/**
+/*
* Request queue structure.
*
* The request queue allows us to note sequence numbers that have been emitted
@@ -198,7 +198,7 @@ struct i915_request {
struct drm_i915_private *i915;
- /**
+ /*
* Context and ring buffer related to this request
* Contexts are refcounted, so when this request is associated with a
* context, we must increment the context's refcount, to guarantee that
@@ -251,9 +251,9 @@ struct i915_request {
};
struct llist_head execute_cb;
struct i915_sw_fence semaphore;
- /**
- * @submit_work: complete submit fence from an IRQ if needed for
- * locking hierarchy reasons.
+ /*
+ * complete submit fence from an IRQ if needed for locking hierarchy
+ * reasons.
*/
struct irq_work submit_work;
@@ -277,35 +277,35 @@ struct i915_request {
*/
const u32 *hwsp_seqno;
- /** Position in the ring of the start of the request */
+ /* Position in the ring of the start of the request */
u32 head;
- /** Position in the ring of the start of the user packets */
+ /* Position in the ring of the start of the user packets */
u32 infix;
- /**
+ /*
* Position in the ring of the start of the postfix.
* This is required to calculate the maximum available ring space
* without overwriting the postfix.
*/
u32 postfix;
- /** Position in the ring of the end of the whole request */
+ /* Position in the ring of the end of the whole request */
u32 tail;
- /** Position in the ring of the end of any workarounds after the tail */
+ /* Position in the ring of the end of any workarounds after the tail */
u32 wa_tail;
- /** Preallocate space in the ring for the emitting the request */
+ /* Preallocate space in the ring for the emitting the request */
u32 reserved_space;
- /** Batch buffer pointer for selftest internal use. */
+ /* Batch buffer pointer for selftest internal use. */
I915_SELFTEST_DECLARE(struct i915_vma *batch);
struct i915_vma_resource *batch_res;
#if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR)
- /**
+ /*
* Additional buffers requested by userspace to be captured upon
* a GPU hang. The vma/obj on this list are protected by their
* active reference - all objects on this list must also be
@@ -314,29 +314,29 @@ struct i915_request {
struct i915_capture_list *capture_list;
#endif
- /** Time at which this request was emitted, in jiffies. */
+ /* Time at which this request was emitted, in jiffies. */
unsigned long emitted_jiffies;
- /** timeline->request entry for this request */
+ /* timeline->request entry for this request */
struct list_head link;
- /** Watchdog support fields. */
+ /* Watchdog support fields. */
struct i915_request_watchdog {
struct llist_node link;
struct hrtimer timer;
} watchdog;
- /**
- * @guc_fence_link: Requests may need to be stalled when using GuC
- * submission waiting for certain GuC operations to complete. If that is
- * the case, stalled requests are added to a per context list of stalled
- * requests. The below list_head is the link in that list. Protected by
+ /*
+ * Requests may need to be stalled when using GuC submission waiting for
+ * certain GuC operations to complete. If that is the case, stalled
+ * requests are added to a per context list of stalled requests. The
+ * below list_head is the link in that list. Protected by
* ce->guc_state.lock.
*/
struct list_head guc_fence_link;
- /**
- * @guc_prio: Priority level while the request is in flight. Differs
+ /*
+ * Priority level while the request is in flight. Differs
* from i915 scheduler priority. See comment above
* I915_SCHEDULER_CAP_STATIC_PRIORITY_MAP for details. Protected by
* ce->guc_active.lock. Two special values (GUC_PRIO_INIT and
@@ -348,8 +348,8 @@ struct i915_request {
#define GUC_PRIO_FINI 0xfe
u8 guc_prio;
- /**
- * @hucq: wait queue entry used to wait on the HuC load to complete
+ /*
+ * wait queue entry used to wait on the HuC load to complete
*/
wait_queue_entry_t hucq;
@@ -473,7 +473,7 @@ i915_request_has_initial_breadcrumb(const struct i915_request *rq)
return test_bit(I915_FENCE_FLAG_INITIAL_BREADCRUMB, &rq->fence.flags);
}
-/**
+/*
* Returns true if seq1 is later than seq2.
*/
static inline bool i915_seqno_passed(u32 seq1, u32 seq2)
diff --git a/drivers/gpu/drm/i915/i915_scatterlist.h b/drivers/gpu/drm/i915/i915_scatterlist.h
index b0a1db44f895..5a10c1a31183 100644
--- a/drivers/gpu/drm/i915/i915_scatterlist.h
+++ b/drivers/gpu/drm/i915/i915_scatterlist.h
@@ -157,8 +157,7 @@ bool i915_sg_trim(struct sg_table *orig_st);
*/
struct i915_refct_sgt_ops {
/**
- * release() - Free the memory of the struct i915_refct_sgt
- * @ref: struct kref that is embedded in the struct i915_refct_sgt
+ * @release: Free the memory of the struct i915_refct_sgt
*/
void (*release)(struct kref *ref);
};
@@ -181,7 +180,7 @@ struct i915_refct_sgt {
/**
* i915_refct_sgt_put - Put a refcounted sg-table
- * @rsgt the struct i915_refct_sgt to put.
+ * @rsgt: the struct i915_refct_sgt to put.
*/
static inline void i915_refct_sgt_put(struct i915_refct_sgt *rsgt)
{
@@ -191,7 +190,7 @@ static inline void i915_refct_sgt_put(struct i915_refct_sgt *rsgt)
/**
* i915_refct_sgt_get - Get a refcounted sg-table
- * @rsgt the struct i915_refct_sgt to get.
+ * @rsgt: the struct i915_refct_sgt to get.
*/
static inline struct i915_refct_sgt *
i915_refct_sgt_get(struct i915_refct_sgt *rsgt)
@@ -203,7 +202,7 @@ i915_refct_sgt_get(struct i915_refct_sgt *rsgt)
/**
* __i915_refct_sgt_init - Initialize a refcounted sg-list with a custom
* operations structure
- * @rsgt The struct i915_refct_sgt to initialize.
+ * @rsgt: The struct i915_refct_sgt to initialize.
* @size: Size in bytes of the underlying memory buffer.
* @ops: A customized operations structure in case the refcounted sg-list
* is embedded into another structure.
diff --git a/drivers/gpu/drm/i915/i915_utils.h b/drivers/gpu/drm/i915/i915_utils.h
index 2c430c0c3bad..c61066498bf2 100644
--- a/drivers/gpu/drm/i915/i915_utils.h
+++ b/drivers/gpu/drm/i915/i915_utils.h
@@ -250,7 +250,7 @@ wait_remaining_ms_from_jiffies(unsigned long timestamp_jiffies, int to_wait_ms)
}
}
-/**
+/*
* __wait_for - magic wait macro
*
* Macro to help avoid open coding check/wait/timeout patterns. Note that it's
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index bad698bece27..ffb425ba591c 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -315,7 +315,7 @@ struct i915_vma_work {
struct i915_vma_resource *vma_res;
struct drm_i915_gem_object *obj;
struct i915_sw_dma_fence_cb cb;
- enum i915_cache_level cache_level;
+ unsigned int pat_index;
unsigned int flags;
};
@@ -334,7 +334,7 @@ static void __vma_bind(struct dma_fence_work *work)
return;
vma_res->ops->bind_vma(vma_res->vm, &vw->stash,
- vma_res, vw->cache_level, vw->flags);
+ vma_res, vw->pat_index, vw->flags);
}
static void __vma_release(struct dma_fence_work *work)
@@ -426,7 +426,7 @@ i915_vma_resource_init_from_vma(struct i915_vma_resource *vma_res,
/**
* i915_vma_bind - Sets up PTEs for an VMA in it's corresponding address space.
* @vma: VMA to map
- * @cache_level: mapping cache level
+ * @pat_index: PAT index to set in PTE
* @flags: flags like global or local mapping
* @work: preallocated worker for allocating and binding the PTE
* @vma_res: pointer to a preallocated vma resource. The resource is either
@@ -437,7 +437,7 @@ i915_vma_resource_init_from_vma(struct i915_vma_resource *vma_res,
* Note that DMA addresses are also the only part of the SG table we care about.
*/
int i915_vma_bind(struct i915_vma *vma,
- enum i915_cache_level cache_level,
+ unsigned int pat_index,
u32 flags,
struct i915_vma_work *work,
struct i915_vma_resource *vma_res)
@@ -507,7 +507,7 @@ int i915_vma_bind(struct i915_vma *vma,
struct dma_fence *prev;
work->vma_res = i915_vma_resource_get(vma->resource);
- work->cache_level = cache_level;
+ work->pat_index = pat_index;
work->flags = bind_flags;
/*
@@ -537,7 +537,7 @@ int i915_vma_bind(struct i915_vma *vma,
return ret;
}
- vma->ops->bind_vma(vma->vm, NULL, vma->resource, cache_level,
+ vma->ops->bind_vma(vma->vm, NULL, vma->resource, pat_index,
bind_flags);
}
@@ -814,7 +814,7 @@ i915_vma_insert(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
color = 0;
if (i915_vm_has_cache_coloring(vma->vm))
- color = vma->obj->cache_level;
+ color = vma->obj->pat_index;
if (flags & PIN_OFFSET_FIXED) {
u64 offset = flags & PIN_OFFSET_MASK;
@@ -1518,7 +1518,7 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
GEM_BUG_ON(!vma->pages);
err = i915_vma_bind(vma,
- vma->obj->cache_level,
+ vma->obj->pat_index,
flags, work, vma_res);
vma_res = NULL;
if (err)
diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
index ed5c9d682a1b..9a9729205d5b 100644
--- a/drivers/gpu/drm/i915/i915_vma.h
+++ b/drivers/gpu/drm/i915/i915_vma.h
@@ -132,7 +132,7 @@ static inline u64 __i915_vma_size(const struct i915_vma *vma)
}
/**
- * i915_vma_offset - Obtain the va range size of the vma
+ * i915_vma_size - Obtain the va range size of the vma
* @vma: The vma
*
* GPU virtual address space may be allocated with padding. This
@@ -250,7 +250,7 @@ i915_vma_compare(struct i915_vma *vma,
struct i915_vma_work *i915_vma_work(void);
int i915_vma_bind(struct i915_vma *vma,
- enum i915_cache_level cache_level,
+ unsigned int pat_index,
u32 flags,
struct i915_vma_work *work,
struct i915_vma_resource *vma_res);
diff --git a/drivers/gpu/drm/i915/i915_vma_resource.h b/drivers/gpu/drm/i915/i915_vma_resource.h
index c1864e3d0b43..ca2b0f7f59bc 100644
--- a/drivers/gpu/drm/i915/i915_vma_resource.h
+++ b/drivers/gpu/drm/i915/i915_vma_resource.h
@@ -34,6 +34,27 @@ struct i915_page_sizes {
};
/**
+ * struct i915_vma_bindinfo - Information needed for async bind
+ * only but that can be dropped after the bind has taken place.
+ * Consider making this a separate argument to the bind_vma
+ * op, coalescing with other arguments like vm, stash, cache_level
+ * and flags
+ * @pages: The pages sg-table.
+ * @page_sizes: Page sizes of the pages.
+ * @pages_rsgt: Refcounted sg-table when delayed object destruction
+ * is supported. May be NULL.
+ * @readonly: Whether the vma should be bound read-only.
+ * @lmem: Whether the vma points to lmem.
+ */
+struct i915_vma_bindinfo {
+ struct sg_table *pages;
+ struct i915_page_sizes page_sizes;
+ struct i915_refct_sgt *pages_rsgt;
+ bool readonly:1;
+ bool lmem:1;
+};
+
+/**
* struct i915_vma_resource - Snapshotted unbind information.
* @unbind_fence: Fence to mark unbinding complete. Note that this fence
* is not considered published until unbind is scheduled, and as such it
@@ -47,6 +68,7 @@ struct i915_page_sizes {
* @chain: Pointer to struct i915_sw_fence used to await dependencies.
* @rb: Rb node for the vm's pending unbind interval tree.
* @__subtree_last: Interval tree private member.
+ * @wakeref: wakeref.
* @vm: non-refcounted pointer to the vm. This is for internal use only and
* this member is cleared after vm_resource unbind.
* @mr: The memory region of the object pointed to by the vma.
@@ -88,25 +110,13 @@ struct i915_vma_resource {
intel_wakeref_t wakeref;
/**
- * struct i915_vma_bindinfo - Information needed for async bind
- * only but that can be dropped after the bind has taken place.
- * Consider making this a separate argument to the bind_vma
- * op, coalescing with other arguments like vm, stash, cache_level
- * and flags
- * @pages: The pages sg-table.
- * @page_sizes: Page sizes of the pages.
- * @pages_rsgt: Refcounted sg-table when delayed object destruction
- * is supported. May be NULL.
- * @readonly: Whether the vma should be bound read-only.
- * @lmem: Whether the vma points to lmem.
+ * @bi: Information needed for async bind only but that can be dropped
+ * after the bind has taken place.
+ *
+ * Consider making this a separate argument to the bind_vma op,
+ * coalescing with other arguments like vm, stash, cache_level and flags
*/
- struct i915_vma_bindinfo {
- struct sg_table *pages;
- struct i915_page_sizes page_sizes;
- struct i915_refct_sgt *pages_rsgt;
- bool readonly:1;
- bool lmem:1;
- } bi;
+ struct i915_vma_bindinfo bi;
#if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR)
struct intel_memory_region *mr;
diff --git a/drivers/gpu/drm/i915/i915_vma_types.h b/drivers/gpu/drm/i915/i915_vma_types.h
index 77fda2244d16..64472b7f0e77 100644
--- a/drivers/gpu/drm/i915/i915_vma_types.h
+++ b/drivers/gpu/drm/i915/i915_vma_types.h
@@ -32,8 +32,6 @@
#include "gem/i915_gem_object_types.h"
-enum i915_cache_level;
-
/**
* DOC: Global GTT views
*
diff --git a/drivers/gpu/drm/i915/intel_device_info.h b/drivers/gpu/drm/i915/intel_device_info.h
index faf6cccdb343..069291b3bd37 100644
--- a/drivers/gpu/drm/i915/intel_device_info.h
+++ b/drivers/gpu/drm/i915/intel_device_info.h
@@ -35,6 +35,8 @@
#include "gt/intel_context_types.h"
#include "gt/intel_sseu.h"
+#include "gem/i915_gem_object_types.h"
+
struct drm_printer;
struct drm_i915_private;
struct intel_gt_definition;
@@ -245,6 +247,9 @@ struct intel_device_info {
* Initial runtime info. Do not access outside of i915_driver_create().
*/
const struct intel_runtime_info __runtime;
+
+ u32 cachelevel_to_pat[I915_MAX_CACHE_LEVEL];
+ u32 max_pat_index;
};
struct intel_driver_caps {
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
index 9d4c7724e98e..bb2e15329f34 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -12,7 +12,9 @@
#include "i915_drv.h"
#include "intel_pxp.h"
+#include "intel_pxp_gsccs.h"
#include "intel_pxp_irq.h"
+#include "intel_pxp_regs.h"
#include "intel_pxp_session.h"
#include "intel_pxp_tee.h"
#include "intel_pxp_types.h"
@@ -60,21 +62,22 @@ bool intel_pxp_is_active(const struct intel_pxp *pxp)
return IS_ENABLED(CONFIG_DRM_I915_PXP) && pxp && pxp->arb_is_valid;
}
-/* KCR register definitions */
-#define KCR_INIT _MMIO(0x320f0)
-/* Setting KCR Init bit is required after system boot */
-#define KCR_INIT_ALLOW_DISPLAY_ME_WRITES REG_BIT(14)
+static void kcr_pxp_set_status(const struct intel_pxp *pxp, bool enable)
+{
+ u32 val = enable ? _MASKED_BIT_ENABLE(KCR_INIT_ALLOW_DISPLAY_ME_WRITES) :
+ _MASKED_BIT_DISABLE(KCR_INIT_ALLOW_DISPLAY_ME_WRITES);
+
+ intel_uncore_write(pxp->ctrl_gt->uncore, KCR_INIT(pxp->kcr_base), val);
+}
-static void kcr_pxp_enable(struct intel_gt *gt)
+static void kcr_pxp_enable(const struct intel_pxp *pxp)
{
- intel_uncore_write(gt->uncore, KCR_INIT,
- _MASKED_BIT_ENABLE(KCR_INIT_ALLOW_DISPLAY_ME_WRITES));
+ kcr_pxp_set_status(pxp, true);
}
-static void kcr_pxp_disable(struct intel_gt *gt)
+static void kcr_pxp_disable(const struct intel_pxp *pxp)
{
- intel_uncore_write(gt->uncore, KCR_INIT,
- _MASKED_BIT_DISABLE(KCR_INIT_ALLOW_DISPLAY_ME_WRITES));
+ kcr_pxp_set_status(pxp, false);
}
static int create_vcs_context(struct intel_pxp *pxp)
@@ -126,13 +129,21 @@ static void pxp_init_full(struct intel_pxp *pxp)
init_completion(&pxp->termination);
complete_all(&pxp->termination);
+ if (pxp->ctrl_gt->type == GT_MEDIA)
+ pxp->kcr_base = MTL_KCR_BASE;
+ else
+ pxp->kcr_base = GEN12_KCR_BASE;
+
intel_pxp_session_management_init(pxp);
ret = create_vcs_context(pxp);
if (ret)
return;
- ret = intel_pxp_tee_component_init(pxp);
+ if (HAS_ENGINE(pxp->ctrl_gt, GSC0))
+ ret = intel_pxp_gsccs_init(pxp);
+ else
+ ret = intel_pxp_tee_component_init(pxp);
if (ret)
goto out_context;
@@ -165,9 +176,12 @@ static struct intel_gt *find_gt_for_required_protected_content(struct drm_i915_p
/*
* For MTL onwards, PXP-controller-GT needs to have a valid GSC engine
* on the media GT. NOTE: if we have a media-tile with a GSC-engine,
- * the VDBOX is already present so skip that check
+ * the VDBOX is already present so skip that check. We also have to
+ * ensure the GSC and HUC firmware are coming online
*/
- if (i915->media_gt && HAS_ENGINE(i915->media_gt, GSC0))
+ if (i915->media_gt && HAS_ENGINE(i915->media_gt, GSC0) &&
+ intel_uc_fw_is_loadable(&i915->media_gt->uc.gsc.fw) &&
+ intel_uc_fw_is_loadable(&i915->media_gt->uc.huc.fw))
return i915->media_gt;
/*
@@ -207,7 +221,9 @@ int intel_pxp_init(struct drm_i915_private *i915)
if (!i915->pxp)
return -ENOMEM;
+ /* init common info used by all feature-mode usages*/
i915->pxp->ctrl_gt = gt;
+ mutex_init(&i915->pxp->tee_mutex);
/*
* If full PXP feature is not available but HuC is loaded by GSC on pre-MTL
@@ -229,7 +245,10 @@ void intel_pxp_fini(struct drm_i915_private *i915)
i915->pxp->arb_is_valid = false;
- intel_pxp_tee_component_fini(i915->pxp);
+ if (HAS_ENGINE(i915->pxp->ctrl_gt, GSC0))
+ intel_pxp_gsccs_fini(i915->pxp);
+ else
+ intel_pxp_tee_component_fini(i915->pxp);
destroy_vcs_context(i915->pxp);
@@ -270,8 +289,18 @@ static bool pxp_component_bound(struct intel_pxp *pxp)
return bound;
}
+int intel_pxp_get_backend_timeout_ms(struct intel_pxp *pxp)
+{
+ if (HAS_ENGINE(pxp->ctrl_gt, GSC0))
+ return GSCFW_MAX_ROUND_TRIP_LATENCY_MS;
+ else
+ return 250;
+}
+
static int __pxp_global_teardown_final(struct intel_pxp *pxp)
{
+ int timeout;
+
if (!pxp->arb_is_valid)
return 0;
/*
@@ -281,7 +310,9 @@ static int __pxp_global_teardown_final(struct intel_pxp *pxp)
intel_pxp_mark_termination_in_progress(pxp);
intel_pxp_terminate(pxp, false);
- if (!wait_for_completion_timeout(&pxp->termination, msecs_to_jiffies(250)))
+ timeout = intel_pxp_get_backend_timeout_ms(pxp);
+
+ if (!wait_for_completion_timeout(&pxp->termination, msecs_to_jiffies(timeout)))
return -ETIMEDOUT;
return 0;
@@ -289,6 +320,8 @@ static int __pxp_global_teardown_final(struct intel_pxp *pxp)
static int __pxp_global_teardown_restart(struct intel_pxp *pxp)
{
+ int timeout;
+
if (pxp->arb_is_valid)
return 0;
/*
@@ -297,7 +330,9 @@ static int __pxp_global_teardown_restart(struct intel_pxp *pxp)
*/
pxp_queue_termination(pxp);
- if (!wait_for_completion_timeout(&pxp->termination, msecs_to_jiffies(250)))
+ timeout = intel_pxp_get_backend_timeout_ms(pxp);
+
+ if (!wait_for_completion_timeout(&pxp->termination, msecs_to_jiffies(timeout)))
return -ETIMEDOUT;
return 0;
@@ -325,6 +360,26 @@ void intel_pxp_end(struct intel_pxp *pxp)
}
/*
+ * this helper is used by both intel_pxp_start and by
+ * the GET_PARAM IOCTL that user space calls. Thus, the
+ * return values here should match the UAPI spec.
+ */
+int intel_pxp_get_readiness_status(struct intel_pxp *pxp)
+{
+ if (!intel_pxp_is_enabled(pxp))
+ return -ENODEV;
+
+ if (HAS_ENGINE(pxp->ctrl_gt, GSC0)) {
+ if (wait_for(intel_pxp_gsccs_is_ready_for_sessions(pxp), 250))
+ return 2;
+ } else {
+ if (wait_for(pxp_component_bound(pxp), 250))
+ return 2;
+ }
+ return 1;
+}
+
+/*
* the arb session is restarted from the irq work when we receive the
* termination completion interrupt
*/
@@ -332,11 +387,11 @@ int intel_pxp_start(struct intel_pxp *pxp)
{
int ret = 0;
- if (!intel_pxp_is_enabled(pxp))
- return -ENODEV;
-
- if (wait_for(pxp_component_bound(pxp), 250))
- return -ENXIO;
+ ret = intel_pxp_get_readiness_status(pxp);
+ if (ret < 0)
+ return ret;
+ else if (ret > 1)
+ return -EIO; /* per UAPI spec, user may retry later */
mutex_lock(&pxp->arb_mutex);
@@ -357,14 +412,13 @@ unlock:
void intel_pxp_init_hw(struct intel_pxp *pxp)
{
- kcr_pxp_enable(pxp->ctrl_gt);
+ kcr_pxp_enable(pxp);
intel_pxp_irq_enable(pxp);
}
void intel_pxp_fini_hw(struct intel_pxp *pxp)
{
- kcr_pxp_disable(pxp->ctrl_gt);
-
+ kcr_pxp_disable(pxp);
intel_pxp_irq_disable(pxp);
}
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h
index 3ded0890cd27..17254c3f1267 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
@@ -26,6 +26,8 @@ void intel_pxp_fini_hw(struct intel_pxp *pxp);
void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp);
void intel_pxp_tee_end_arb_fw_session(struct intel_pxp *pxp, u32 arb_session_id);
+int intel_pxp_get_readiness_status(struct intel_pxp *pxp);
+int intel_pxp_get_backend_timeout_ms(struct intel_pxp *pxp);
int intel_pxp_start(struct intel_pxp *pxp);
void intel_pxp_end(struct intel_pxp *pxp);
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_43.h b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_43.h
index ad67e3f49c20..09777719cd84 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_43.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_43.h
@@ -11,6 +11,10 @@
/* PXP-Cmd-Op definitions */
#define PXP43_CMDID_START_HUC_AUTH 0x0000003A
+#define PXP43_CMDID_INIT_SESSION 0x00000036
+
+/* PXP-Packet sizes for MTL's GSCCS-HECI instruction */
+#define PXP43_MAX_HECI_INOUT_SIZE (SZ_32K)
/* PXP-Input-Packet: HUC-Authentication */
struct pxp43_start_huc_auth_in {
@@ -23,4 +27,24 @@ struct pxp43_start_huc_auth_out {
struct pxp_cmd_header header;
} __packed;
+/* PXP-Input-Packet: Init PXP session */
+struct pxp43_create_arb_in {
+ struct pxp_cmd_header header;
+ /* header.stream_id fields for vesion 4.3 of Init PXP session: */
+ #define PXP43_INIT_SESSION_VALID BIT(0)
+ #define PXP43_INIT_SESSION_APPTYPE BIT(1)
+ #define PXP43_INIT_SESSION_APPID GENMASK(17, 2)
+ u32 protection_mode;
+ #define PXP43_INIT_SESSION_PROTECTION_ARB 0x2
+ u32 sub_session_id;
+ u32 init_flags;
+ u32 rsvd[12];
+} __packed;
+
+/* PXP-Input-Packet: Init PXP session */
+struct pxp43_create_arb_out {
+ struct pxp_cmd_header header;
+ u32 rsvd[8];
+} __packed;
+
#endif /* __INTEL_PXP_FW_INTERFACE_43_H__ */
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.c b/drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.c
index 4b8e70caa3ad..e07c5b380789 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.c
@@ -14,6 +14,7 @@
#include "intel_pxp.h"
#include "intel_pxp_debugfs.h"
+#include "intel_pxp_gsccs.h"
#include "intel_pxp_irq.h"
#include "intel_pxp_types.h"
@@ -45,6 +46,7 @@ static int pxp_terminate_set(void *data, u64 val)
{
struct intel_pxp *pxp = data;
struct intel_gt *gt = pxp->ctrl_gt;
+ int timeout_ms;
if (!intel_pxp_is_active(pxp))
return -ENODEV;
@@ -54,8 +56,10 @@ static int pxp_terminate_set(void *data, u64 val)
intel_pxp_irq_handler(pxp, GEN12_DISPLAY_PXP_STATE_TERMINATED_INTERRUPT);
spin_unlock_irq(gt->irq_lock);
+ timeout_ms = intel_pxp_get_backend_timeout_ms(pxp);
+
if (!wait_for_completion_timeout(&pxp->termination,
- msecs_to_jiffies(100)))
+ msecs_to_jiffies(timeout_ms)))
return -ETIMEDOUT;
return 0;
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.c b/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.c
new file mode 100644
index 000000000000..8dc41de3f6f7
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.c
@@ -0,0 +1,444 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright(c) 2023 Intel Corporation.
+ */
+
+#include "gem/i915_gem_internal.h"
+
+#include "gt/intel_context.h"
+#include "gt/uc/intel_gsc_fw.h"
+#include "gt/uc/intel_gsc_uc_heci_cmd_submit.h"
+
+#include "i915_drv.h"
+#include "intel_pxp.h"
+#include "intel_pxp_cmd_interface_42.h"
+#include "intel_pxp_cmd_interface_43.h"
+#include "intel_pxp_gsccs.h"
+#include "intel_pxp_types.h"
+
+static bool
+is_fw_err_platform_config(u32 type)
+{
+ switch (type) {
+ case PXP_STATUS_ERROR_API_VERSION:
+ case PXP_STATUS_PLATFCONFIG_KF1_NOVERIF:
+ case PXP_STATUS_PLATFCONFIG_KF1_BAD:
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
+
+static const char *
+fw_err_to_string(u32 type)
+{
+ switch (type) {
+ case PXP_STATUS_ERROR_API_VERSION:
+ return "ERR_API_VERSION";
+ case PXP_STATUS_NOT_READY:
+ return "ERR_NOT_READY";
+ case PXP_STATUS_PLATFCONFIG_KF1_NOVERIF:
+ case PXP_STATUS_PLATFCONFIG_KF1_BAD:
+ return "ERR_PLATFORM_CONFIG";
+ default:
+ break;
+ }
+ return NULL;
+}
+
+static int
+gsccs_send_message(struct intel_pxp *pxp,
+ void *msg_in, size_t msg_in_size,
+ void *msg_out, size_t msg_out_size_max,
+ size_t *msg_out_len,
+ u64 *gsc_msg_handle_retry)
+{
+ struct intel_gt *gt = pxp->ctrl_gt;
+ struct drm_i915_private *i915 = gt->i915;
+ struct gsccs_session_resources *exec_res = &pxp->gsccs_res;
+ struct intel_gsc_mtl_header *header = exec_res->pkt_vaddr;
+ struct intel_gsc_heci_non_priv_pkt pkt;
+ size_t max_msg_size;
+ u32 reply_size;
+ int ret;
+
+ if (!exec_res->ce)
+ return -ENODEV;
+
+ max_msg_size = PXP43_MAX_HECI_INOUT_SIZE - sizeof(*header);
+
+ if (msg_in_size > max_msg_size || msg_out_size_max > max_msg_size)
+ return -ENOSPC;
+
+ if (!exec_res->pkt_vma || !exec_res->bb_vma)
+ return -ENOENT;
+
+ GEM_BUG_ON(exec_res->pkt_vma->size < (2 * PXP43_MAX_HECI_INOUT_SIZE));
+
+ mutex_lock(&pxp->tee_mutex);
+
+ memset(header, 0, sizeof(*header));
+ intel_gsc_uc_heci_cmd_emit_mtl_header(header, HECI_MEADDRESS_PXP,
+ msg_in_size + sizeof(*header),
+ exec_res->host_session_handle);
+
+ /* check if this is a host-session-handle cleanup call (empty packet) */
+ if (!msg_in && !msg_out)
+ header->flags |= GSC_INFLAG_MSG_CLEANUP;
+
+ /* copy caller provided gsc message handle if this is polling for a prior msg completion */
+ header->gsc_message_handle = *gsc_msg_handle_retry;
+
+ /* NOTE: zero size packets are used for session-cleanups */
+ if (msg_in && msg_in_size)
+ memcpy(exec_res->pkt_vaddr + sizeof(*header), msg_in, msg_in_size);
+
+ pkt.addr_in = i915_vma_offset(exec_res->pkt_vma);
+ pkt.size_in = header->message_size;
+ pkt.addr_out = pkt.addr_in + PXP43_MAX_HECI_INOUT_SIZE;
+ pkt.size_out = msg_out_size_max + sizeof(*header);
+ pkt.heci_pkt_vma = exec_res->pkt_vma;
+ pkt.bb_vma = exec_res->bb_vma;
+
+ /*
+ * Before submitting, let's clear-out the validity marker on the reply offset.
+ * We use offset PXP43_MAX_HECI_INOUT_SIZE for reply location so point header there.
+ */
+ header = exec_res->pkt_vaddr + PXP43_MAX_HECI_INOUT_SIZE;
+ header->validity_marker = 0;
+
+ ret = intel_gsc_uc_heci_cmd_submit_nonpriv(&gt->uc.gsc,
+ exec_res->ce, &pkt, exec_res->bb_vaddr,
+ GSC_REPLY_LATENCY_MS);
+ if (ret) {
+ drm_err(&i915->drm, "failed to send gsc PXP msg (%d)\n", ret);
+ goto unlock;
+ }
+
+ /* Response validity marker, status and busyness */
+ if (header->validity_marker != GSC_HECI_VALIDITY_MARKER) {
+ drm_err(&i915->drm, "gsc PXP reply with invalid validity marker\n");
+ ret = -EINVAL;
+ goto unlock;
+ }
+ if (header->status != 0) {
+ drm_dbg(&i915->drm, "gsc PXP reply status has error = 0x%08x\n",
+ header->status);
+ ret = -EINVAL;
+ goto unlock;
+ }
+ if (header->flags & GSC_OUTFLAG_MSG_PENDING) {
+ drm_dbg(&i915->drm, "gsc PXP reply is busy\n");
+ /*
+ * When the GSC firmware replies with pending bit, it means that the requested
+ * operation has begun but the completion is pending and the caller needs
+ * to re-request with the gsc_message_handle that was returned by the firmware.
+ * until the pending bit is turned off.
+ */
+ *gsc_msg_handle_retry = header->gsc_message_handle;
+ ret = -EAGAIN;
+ goto unlock;
+ }
+
+ reply_size = header->message_size - sizeof(*header);
+ if (reply_size > msg_out_size_max) {
+ drm_warn(&i915->drm, "caller with insufficient PXP reply size %u (%ld)\n",
+ reply_size, msg_out_size_max);
+ reply_size = msg_out_size_max;
+ }
+
+ if (msg_out)
+ memcpy(msg_out, exec_res->pkt_vaddr + PXP43_MAX_HECI_INOUT_SIZE + sizeof(*header),
+ reply_size);
+ if (msg_out_len)
+ *msg_out_len = reply_size;
+
+unlock:
+ mutex_unlock(&pxp->tee_mutex);
+ return ret;
+}
+
+static int
+gsccs_send_message_retry_complete(struct intel_pxp *pxp,
+ void *msg_in, size_t msg_in_size,
+ void *msg_out, size_t msg_out_size_max,
+ size_t *msg_out_len)
+{
+ u64 gsc_session_retry = 0;
+ int ret, tries = 0;
+
+ /*
+ * Keep sending request if GSC firmware was busy. Based on fw specs +
+ * sw overhead (and testing) we expect a worst case pending-bit delay of
+ * GSC_PENDING_RETRY_MAXCOUNT x GSC_PENDING_RETRY_PAUSE_MS millisecs.
+ */
+ do {
+ ret = gsccs_send_message(pxp, msg_in, msg_in_size, msg_out, msg_out_size_max,
+ msg_out_len, &gsc_session_retry);
+ /* Only try again if gsc says so */
+ if (ret != -EAGAIN)
+ break;
+
+ msleep(GSC_PENDING_RETRY_PAUSE_MS);
+ } while (++tries < GSC_PENDING_RETRY_MAXCOUNT);
+
+ return ret;
+}
+
+bool intel_pxp_gsccs_is_ready_for_sessions(struct intel_pxp *pxp)
+{
+ /*
+ * GSC-fw loading, HuC-fw loading, HuC-fw authentication and
+ * GSC-proxy init flow (requiring an mei component driver)
+ * must all occur first before we can start requesting for PXP
+ * sessions. Checking for completion on HuC authentication and
+ * gsc-proxy init flow (the last set of dependencies that
+ * are out of order) will suffice.
+ */
+ if (intel_huc_is_authenticated(&pxp->ctrl_gt->uc.huc) &&
+ intel_gsc_uc_fw_proxy_init_done(&pxp->ctrl_gt->uc.gsc))
+ return true;
+
+ return false;
+}
+
+int intel_pxp_gsccs_create_session(struct intel_pxp *pxp,
+ int arb_session_id)
+{
+ struct drm_i915_private *i915 = pxp->ctrl_gt->i915;
+ struct pxp43_create_arb_in msg_in = {0};
+ struct pxp43_create_arb_out msg_out = {0};
+ int ret;
+
+ msg_in.header.api_version = PXP_APIVER(4, 3);
+ msg_in.header.command_id = PXP43_CMDID_INIT_SESSION;
+ msg_in.header.stream_id = (FIELD_PREP(PXP43_INIT_SESSION_APPID, arb_session_id) |
+ FIELD_PREP(PXP43_INIT_SESSION_VALID, 1) |
+ FIELD_PREP(PXP43_INIT_SESSION_APPTYPE, 0));
+ msg_in.header.buffer_len = sizeof(msg_in) - sizeof(msg_in.header);
+ msg_in.protection_mode = PXP43_INIT_SESSION_PROTECTION_ARB;
+
+ ret = gsccs_send_message_retry_complete(pxp,
+ &msg_in, sizeof(msg_in),
+ &msg_out, sizeof(msg_out), NULL);
+ if (ret) {
+ drm_err(&i915->drm, "Failed to init session %d, ret=[%d]\n", arb_session_id, ret);
+ } else if (msg_out.header.status != 0) {
+ if (is_fw_err_platform_config(msg_out.header.status)) {
+ drm_info_once(&i915->drm,
+ "PXP init-session-%d failed due to BIOS/SOC:0x%08x:%s\n",
+ arb_session_id, msg_out.header.status,
+ fw_err_to_string(msg_out.header.status));
+ } else {
+ drm_dbg(&i915->drm, "PXP init-session-%d failed 0x%08x:%st:\n",
+ arb_session_id, msg_out.header.status,
+ fw_err_to_string(msg_out.header.status));
+ drm_dbg(&i915->drm, " cmd-detail: ID=[0x%08x],API-Ver-[0x%08x]\n",
+ msg_in.header.command_id, msg_in.header.api_version);
+ }
+ }
+
+ return ret;
+}
+
+void intel_pxp_gsccs_end_arb_fw_session(struct intel_pxp *pxp, u32 session_id)
+{
+ struct drm_i915_private *i915 = pxp->ctrl_gt->i915;
+ struct pxp42_inv_stream_key_in msg_in = {0};
+ struct pxp42_inv_stream_key_out msg_out = {0};
+ int ret = 0;
+
+ /*
+ * Stream key invalidation reuses the same version 4.2 input/output
+ * command format but firmware requires 4.3 API interaction
+ */
+ msg_in.header.api_version = PXP_APIVER(4, 3);
+ msg_in.header.command_id = PXP42_CMDID_INVALIDATE_STREAM_KEY;
+ msg_in.header.buffer_len = sizeof(msg_in) - sizeof(msg_in.header);
+
+ msg_in.header.stream_id = FIELD_PREP(PXP_CMDHDR_EXTDATA_SESSION_VALID, 1);
+ msg_in.header.stream_id |= FIELD_PREP(PXP_CMDHDR_EXTDATA_APP_TYPE, 0);
+ msg_in.header.stream_id |= FIELD_PREP(PXP_CMDHDR_EXTDATA_SESSION_ID, session_id);
+
+ ret = gsccs_send_message_retry_complete(pxp,
+ &msg_in, sizeof(msg_in),
+ &msg_out, sizeof(msg_out), NULL);
+ if (ret) {
+ drm_err(&i915->drm, "Failed to inv-stream-key-%u, ret=[%d]\n",
+ session_id, ret);
+ } else if (msg_out.header.status != 0) {
+ if (is_fw_err_platform_config(msg_out.header.status)) {
+ drm_info_once(&i915->drm,
+ "PXP inv-stream-key-%u failed due to BIOS/SOC :0x%08x:%s\n",
+ session_id, msg_out.header.status,
+ fw_err_to_string(msg_out.header.status));
+ } else {
+ drm_dbg(&i915->drm, "PXP inv-stream-key-%u failed 0x%08x:%s:\n",
+ session_id, msg_out.header.status,
+ fw_err_to_string(msg_out.header.status));
+ drm_dbg(&i915->drm, " cmd-detail: ID=[0x%08x],API-Ver-[0x%08x]\n",
+ msg_in.header.command_id, msg_in.header.api_version);
+ }
+ }
+}
+
+static void
+gsccs_cleanup_fw_host_session_handle(struct intel_pxp *pxp)
+{
+ struct drm_i915_private *i915 = pxp->ctrl_gt->i915;
+ int ret;
+
+ ret = gsccs_send_message_retry_complete(pxp, NULL, 0, NULL, 0, NULL);
+ if (ret)
+ drm_dbg(&i915->drm, "Failed to send gsccs msg host-session-cleanup: ret=[%d]\n",
+ ret);
+}
+
+static void
+gsccs_destroy_execution_resource(struct intel_pxp *pxp)
+{
+ struct gsccs_session_resources *exec_res = &pxp->gsccs_res;
+
+ if (exec_res->host_session_handle)
+ gsccs_cleanup_fw_host_session_handle(pxp);
+ if (exec_res->ce)
+ intel_context_put(exec_res->ce);
+ if (exec_res->bb_vma)
+ i915_vma_unpin_and_release(&exec_res->bb_vma, I915_VMA_RELEASE_MAP);
+ if (exec_res->pkt_vma)
+ i915_vma_unpin_and_release(&exec_res->pkt_vma, I915_VMA_RELEASE_MAP);
+
+ memset(exec_res, 0, sizeof(*exec_res));
+}
+
+static int
+gsccs_create_buffer(struct intel_gt *gt,
+ const char *bufname, size_t size,
+ struct i915_vma **vma, void **map)
+{
+ struct drm_i915_private *i915 = gt->i915;
+ struct drm_i915_gem_object *obj;
+ int err = 0;
+
+ obj = i915_gem_object_create_internal(i915, size);
+ if (IS_ERR(obj)) {
+ drm_err(&i915->drm, "Failed to allocate gsccs backend %s.\n", bufname);
+ err = PTR_ERR(obj);
+ goto out_none;
+ }
+
+ *vma = i915_vma_instance(obj, gt->vm, NULL);
+ if (IS_ERR(*vma)) {
+ drm_err(&i915->drm, "Failed to vma-instance gsccs backend %s.\n", bufname);
+ err = PTR_ERR(*vma);
+ goto out_put;
+ }
+
+ /* return a virtual pointer */
+ *map = i915_gem_object_pin_map_unlocked(obj, i915_coherent_map_type(i915, obj, true));
+ if (IS_ERR(*map)) {
+ drm_err(&i915->drm, "Failed to map gsccs backend %s.\n", bufname);
+ err = PTR_ERR(*map);
+ goto out_put;
+ }
+
+ /* all PXP sessions commands are treated as non-privileged */
+ err = i915_vma_pin(*vma, 0, 0, PIN_USER);
+ if (err) {
+ drm_err(&i915->drm, "Failed to vma-pin gsccs backend %s.\n", bufname);
+ goto out_unmap;
+ }
+
+ return 0;
+
+out_unmap:
+ i915_gem_object_unpin_map(obj);
+out_put:
+ i915_gem_object_put(obj);
+out_none:
+ *vma = NULL;
+ *map = NULL;
+
+ return err;
+}
+
+static int
+gsccs_allocate_execution_resource(struct intel_pxp *pxp)
+{
+ struct intel_gt *gt = pxp->ctrl_gt;
+ struct gsccs_session_resources *exec_res = &pxp->gsccs_res;
+ struct intel_engine_cs *engine = gt->engine[GSC0];
+ struct intel_context *ce;
+ int err = 0;
+
+ /*
+ * First, ensure the GSC engine is present.
+ * NOTE: Backend would only be called with the correct gt.
+ */
+ if (!engine)
+ return -ENODEV;
+
+ /*
+ * Now, allocate, pin and map two objects, one for the heci message packet
+ * and another for the batch buffer we submit into GSC engine (that includes the packet).
+ * NOTE: GSC-CS backend is currently only supported on MTL, so we allocate shmem.
+ */
+ err = gsccs_create_buffer(pxp->ctrl_gt, "Heci Packet",
+ 2 * PXP43_MAX_HECI_INOUT_SIZE,
+ &exec_res->pkt_vma, &exec_res->pkt_vaddr);
+ if (err)
+ return err;
+
+ err = gsccs_create_buffer(pxp->ctrl_gt, "Batch Buffer", PAGE_SIZE,
+ &exec_res->bb_vma, &exec_res->bb_vaddr);
+ if (err)
+ goto free_pkt;
+
+ /* Finally, create an intel_context to be used during the submission */
+ ce = intel_context_create(engine);
+ if (IS_ERR(ce)) {
+ drm_err(&gt->i915->drm, "Failed creating gsccs backend ctx\n");
+ err = PTR_ERR(ce);
+ goto free_batch;
+ }
+
+ i915_vm_put(ce->vm);
+ ce->vm = i915_vm_get(pxp->ctrl_gt->vm);
+ exec_res->ce = ce;
+
+ /* initialize host-session-handle (for all i915-to-gsc-firmware PXP cmds) */
+ get_random_bytes(&exec_res->host_session_handle, sizeof(exec_res->host_session_handle));
+
+ return 0;
+
+free_batch:
+ i915_vma_unpin_and_release(&exec_res->bb_vma, I915_VMA_RELEASE_MAP);
+free_pkt:
+ i915_vma_unpin_and_release(&exec_res->pkt_vma, I915_VMA_RELEASE_MAP);
+ memset(exec_res, 0, sizeof(*exec_res));
+
+ return err;
+}
+
+void intel_pxp_gsccs_fini(struct intel_pxp *pxp)
+{
+ intel_wakeref_t wakeref;
+
+ gsccs_destroy_execution_resource(pxp);
+ with_intel_runtime_pm(&pxp->ctrl_gt->i915->runtime_pm, wakeref)
+ intel_pxp_fini_hw(pxp);
+}
+
+int intel_pxp_gsccs_init(struct intel_pxp *pxp)
+{
+ int ret;
+ intel_wakeref_t wakeref;
+
+ ret = gsccs_allocate_execution_resource(pxp);
+ if (!ret) {
+ with_intel_runtime_pm(&pxp->ctrl_gt->i915->runtime_pm, wakeref)
+ intel_pxp_init_hw(pxp);
+ }
+ return ret;
+}
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.h b/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.h
new file mode 100644
index 000000000000..298ad38e6c7d
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.h
@@ -0,0 +1,43 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright(c) 2022, Intel Corporation. All rights reserved.
+ */
+
+#ifndef __INTEL_PXP_GSCCS_H__
+#define __INTEL_PXP_GSCCS_H__
+
+#include <linux/types.h>
+
+struct intel_pxp;
+
+#define GSC_REPLY_LATENCY_MS 210
+/*
+ * Max FW response time is 200ms, to which we add 10ms to account for overhead
+ * such as request preparation, GuC submission to hw and pipeline completion times.
+ */
+#define GSC_PENDING_RETRY_MAXCOUNT 40
+#define GSC_PENDING_RETRY_PAUSE_MS 50
+#define GSCFW_MAX_ROUND_TRIP_LATENCY_MS (GSC_PENDING_RETRY_MAXCOUNT * GSC_PENDING_RETRY_PAUSE_MS)
+
+#ifdef CONFIG_DRM_I915_PXP
+void intel_pxp_gsccs_fini(struct intel_pxp *pxp);
+int intel_pxp_gsccs_init(struct intel_pxp *pxp);
+
+int intel_pxp_gsccs_create_session(struct intel_pxp *pxp, int arb_session_id);
+void intel_pxp_gsccs_end_arb_fw_session(struct intel_pxp *pxp, u32 arb_session_id);
+
+#else
+static inline void intel_pxp_gsccs_fini(struct intel_pxp *pxp)
+{
+}
+
+static inline int intel_pxp_gsccs_init(struct intel_pxp *pxp)
+{
+ return 0;
+}
+
+#endif
+
+bool intel_pxp_gsccs_is_ready_for_sessions(struct intel_pxp *pxp);
+
+#endif /*__INTEL_PXP_GSCCS_H__ */
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c b/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c
index 4f836b317424..1a04067f61fc 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c
@@ -43,8 +43,9 @@ void intel_pxp_resume_complete(struct intel_pxp *pxp)
* The PXP component gets automatically unbound when we go into S3 and
* re-bound after we come out, so in that scenario we can defer the
* hw init to the bind call.
+ * NOTE: GSC-CS backend doesn't rely on components.
*/
- if (!pxp->pxp_component)
+ if (!HAS_ENGINE(pxp->ctrl_gt, GSC0) && !pxp->pxp_component)
return;
intel_pxp_init_hw(pxp);
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_regs.h b/drivers/gpu/drm/i915/pxp/intel_pxp_regs.h
new file mode 100644
index 000000000000..a9e7e6efa4c7
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_regs.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright(c) 2023, Intel Corporation. All rights reserved.
+ */
+
+#ifndef __INTEL_PXP_REGS_H__
+#define __INTEL_PXP_REGS_H__
+
+#include "i915_reg_defs.h"
+
+/* KCR subsystem register base address */
+#define GEN12_KCR_BASE 0x32000
+#define MTL_KCR_BASE 0x386000
+
+/* KCR enable/disable control */
+#define KCR_INIT(base) _MMIO((base) + 0xf0)
+
+/* Setting KCR Init bit is required after system boot */
+#define KCR_INIT_ALLOW_DISPLAY_ME_WRITES REG_BIT(14)
+
+/* KCR hwdrm session in play status 0-31 */
+#define KCR_SIP(base) _MMIO((base) + 0x260)
+
+/* PXP global terminate register for session termination */
+#define KCR_GLOBAL_TERMINATE(base) _MMIO((base) + 0xf8)
+
+#endif /* __INTEL_PXP_REGS_H__ */
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
index 7de849cb6c47..0a3e66b0265e 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
@@ -7,17 +7,14 @@
#include "intel_pxp.h"
#include "intel_pxp_cmd.h"
+#include "intel_pxp_gsccs.h"
#include "intel_pxp_session.h"
#include "intel_pxp_tee.h"
#include "intel_pxp_types.h"
+#include "intel_pxp_regs.h"
#define ARB_SESSION I915_PROTECTED_CONTENT_DEFAULT_SESSION /* shorter define */
-#define GEN12_KCR_SIP _MMIO(0x32260) /* KCR hwdrm session in play 0-31 */
-
-/* PXP global terminate register for session termination */
-#define PXP_GLOBAL_TERMINATE _MMIO(0x320f8)
-
static bool intel_pxp_session_is_in_play(struct intel_pxp *pxp, u32 id)
{
struct intel_uncore *uncore = pxp->ctrl_gt->uncore;
@@ -26,7 +23,7 @@ static bool intel_pxp_session_is_in_play(struct intel_pxp *pxp, u32 id)
/* if we're suspended the session is considered off */
with_intel_runtime_pm_if_in_use(uncore->rpm, wakeref)
- sip = intel_uncore_read(uncore, GEN12_KCR_SIP);
+ sip = intel_uncore_read(uncore, KCR_SIP(pxp->kcr_base));
return sip & BIT(id);
}
@@ -44,10 +41,10 @@ static int pxp_wait_for_session_state(struct intel_pxp *pxp, u32 id, bool in_pla
return in_play ? -ENODEV : 0;
ret = intel_wait_for_register(uncore,
- GEN12_KCR_SIP,
+ KCR_SIP(pxp->kcr_base),
mask,
in_play ? mask : 0,
- 100);
+ 250);
intel_runtime_pm_put(uncore->rpm, wakeref);
@@ -66,7 +63,10 @@ static int pxp_create_arb_session(struct intel_pxp *pxp)
return -EEXIST;
}
- ret = intel_pxp_tee_cmd_create_arb_session(pxp, ARB_SESSION);
+ if (HAS_ENGINE(pxp->ctrl_gt, GSC0))
+ ret = intel_pxp_gsccs_create_session(pxp, ARB_SESSION);
+ else
+ ret = intel_pxp_tee_cmd_create_arb_session(pxp, ARB_SESSION);
if (ret) {
drm_err(&gt->i915->drm, "tee cmd for arb session creation failed\n");
return ret;
@@ -108,9 +108,12 @@ static int pxp_terminate_arb_session_and_global(struct intel_pxp *pxp)
return ret;
}
- intel_uncore_write(gt->uncore, PXP_GLOBAL_TERMINATE, 1);
+ intel_uncore_write(gt->uncore, KCR_GLOBAL_TERMINATE(pxp->kcr_base), 1);
- intel_pxp_tee_end_arb_fw_session(pxp, ARB_SESSION);
+ if (HAS_ENGINE(gt, GSC0))
+ intel_pxp_gsccs_end_arb_fw_session(pxp, ARB_SESSION);
+ else
+ intel_pxp_tee_end_arb_fw_session(pxp, ARB_SESSION);
return ret;
}
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
index a2846b1dbbee..1ce07d7e8769 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
@@ -284,8 +284,6 @@ int intel_pxp_tee_component_init(struct intel_pxp *pxp)
struct intel_gt *gt = pxp->ctrl_gt;
struct drm_i915_private *i915 = gt->i915;
- mutex_init(&pxp->tee_mutex);
-
ret = alloc_streaming_command(pxp);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
index 007de49e1ea4..1a8765866b8b 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
@@ -27,13 +27,35 @@ struct intel_pxp {
struct intel_gt *ctrl_gt;
/**
+ * @kcr_base: base mmio offset for the KCR engine which is different on legacy platforms
+ * vs newer platforms where the KCR is inside the media-tile.
+ */
+ u32 kcr_base;
+
+ /**
+ * @gsccs_res: resources for request submission for platforms that have a GSC engine.
+ */
+ struct gsccs_session_resources {
+ u64 host_session_handle; /* used by firmware to link commands to sessions */
+ struct intel_context *ce; /* context for gsc command submission */
+
+ struct i915_vma *pkt_vma; /* GSC FW cmd packet vma */
+ void *pkt_vaddr; /* GSC FW cmd packet virt pointer */
+
+ struct i915_vma *bb_vma; /* HECI_PKT batch buffer vma */
+ void *bb_vaddr; /* HECI_PKT batch buffer virt pointer */
+ } gsccs_res;
+
+ /**
* @pxp_component: i915_pxp_component struct of the bound mei_pxp
* module. Only set and cleared inside component bind/unbind functions,
* which are protected by &tee_mutex.
*/
struct i915_pxp_component *pxp_component;
- /* @dev_link: Enforce module relationship for power management ordering. */
+ /**
+ * @dev_link: Enforce module relationship for power management ordering.
+ */
struct device_link *dev_link;
/**
* @pxp_component_added: track if the pxp component has been added.
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem.c b/drivers/gpu/drm/i915/selftests/i915_gem.c
index d91d0ade8abd..61da4ed9d521 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem.c
@@ -57,7 +57,10 @@ static void trash_stolen(struct drm_i915_private *i915)
u32 __iomem *s;
int x;
- ggtt->vm.insert_page(&ggtt->vm, dma, slot, I915_CACHE_NONE, 0);
+ ggtt->vm.insert_page(&ggtt->vm, dma, slot,
+ i915_gem_get_pat_index(i915,
+ I915_CACHE_NONE),
+ 0);
s = io_mapping_map_atomic_wc(&ggtt->iomap, slot);
for (x = 0; x < PAGE_SIZE / sizeof(u32); x++) {
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_evict.c b/drivers/gpu/drm/i915/selftests/i915_gem_evict.c
index 37068542aafe..f8fe3681c3dc 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_evict.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_evict.c
@@ -27,6 +27,7 @@
#include "gem/selftests/igt_gem_utils.h"
#include "gem/selftests/mock_context.h"
#include "gt/intel_gt.h"
+#include "gt/intel_gt_print.h"
#include "i915_selftest.h"
@@ -245,7 +246,7 @@ static int igt_evict_for_cache_color(void *arg)
struct drm_mm_node target = {
.start = I915_GTT_PAGE_SIZE * 2,
.size = I915_GTT_PAGE_SIZE,
- .color = I915_CACHE_LLC,
+ .color = i915_gem_get_pat_index(gt->i915, I915_CACHE_LLC),
};
struct drm_i915_gem_object *obj;
struct i915_vma *vma;
@@ -308,7 +309,7 @@ static int igt_evict_for_cache_color(void *arg)
/* Attempt to remove the first *pinned* vma, by removing the (empty)
* neighbour -- this should fail.
*/
- target.color = I915_CACHE_L3_LLC;
+ target.color = i915_gem_get_pat_index(gt->i915, I915_CACHE_L3_LLC);
mutex_lock(&ggtt->vm.mutex);
err = i915_gem_evict_for_node(&ggtt->vm, NULL, &target, 0);
@@ -507,7 +508,8 @@ static int igt_evict_contexts(void *arg)
}
err = intel_gt_wait_for_idle(engine->gt, HZ * 3);
if (err) {
- pr_err("Failed to idle GT (on %s)", engine->name);
+ gt_err(engine->gt, "Failed to idle GT (on %s)",
+ engine->name);
break;
}
}
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
index 154801f1c468..36940ef10108 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
@@ -135,7 +135,7 @@ fake_dma_object(struct drm_i915_private *i915, u64 size)
obj->write_domain = I915_GEM_DOMAIN_CPU;
obj->read_domains = I915_GEM_DOMAIN_CPU;
- obj->cache_level = I915_CACHE_NONE;
+ obj->pat_index = i915_gem_get_pat_index(i915, I915_CACHE_NONE);
/* Preallocate the "backing storage" */
if (i915_gem_object_pin_pages_unlocked(obj))
@@ -359,7 +359,9 @@ alloc_vm_end:
with_intel_runtime_pm(vm->gt->uncore->rpm, wakeref)
vm->insert_entries(vm, mock_vma_res,
- I915_CACHE_NONE, 0);
+ i915_gem_get_pat_index(vm->i915,
+ I915_CACHE_NONE),
+ 0);
}
count = n;
@@ -1377,7 +1379,10 @@ static int igt_ggtt_page(void *arg)
ggtt->vm.insert_page(&ggtt->vm,
i915_gem_object_get_dma_address(obj, 0),
- offset, I915_CACHE_NONE, 0);
+ offset,
+ i915_gem_get_pat_index(i915,
+ I915_CACHE_NONE),
+ 0);
}
order = i915_random_order(count, &prng);
@@ -1510,7 +1515,7 @@ static int reserve_gtt_with_resource(struct i915_vma *vma, u64 offset)
mutex_lock(&vm->mutex);
err = i915_gem_gtt_reserve(vm, NULL, &vma->node, obj->base.size,
offset,
- obj->cache_level,
+ obj->pat_index,
0);
if (!err) {
i915_vma_resource_init_from_vma(vma_res, vma);
@@ -1690,7 +1695,7 @@ static int insert_gtt_with_resource(struct i915_vma *vma)
mutex_lock(&vm->mutex);
err = i915_gem_gtt_insert(vm, NULL, &vma->node, obj->base.size, 0,
- obj->cache_level, 0, vm->total, 0);
+ obj->pat_index, 0, vm->total, 0);
if (!err) {
i915_vma_resource_init_from_vma(vma_res, vma);
vma->resource = vma_res;
diff --git a/drivers/gpu/drm/i915/selftests/igt_live_test.c b/drivers/gpu/drm/i915/selftests/igt_live_test.c
index 72b58b66692a..4ddc6d902752 100644
--- a/drivers/gpu/drm/i915/selftests/igt_live_test.c
+++ b/drivers/gpu/drm/i915/selftests/igt_live_test.c
@@ -6,6 +6,7 @@
#include "i915_drv.h"
#include "gt/intel_gt.h"
+#include "gt/intel_gt_print.h"
#include "../i915_selftest.h"
#include "igt_flush_test.h"
@@ -16,27 +17,31 @@ int igt_live_test_begin(struct igt_live_test *t,
const char *func,
const char *name)
{
- struct intel_gt *gt = to_gt(i915);
struct intel_engine_cs *engine;
enum intel_engine_id id;
+ struct intel_gt *gt;
+ unsigned int i;
int err;
t->i915 = i915;
t->func = func;
t->name = name;
- err = intel_gt_wait_for_idle(gt, MAX_SCHEDULE_TIMEOUT);
- if (err) {
- pr_err("%s(%s): failed to idle before, with err=%d!",
- func, name, err);
- return err;
- }
+ for_each_gt(gt, i915, i) {
- t->reset_global = i915_reset_count(&i915->gpu_error);
+ err = intel_gt_wait_for_idle(gt, MAX_SCHEDULE_TIMEOUT);
+ if (err) {
+ gt_err(gt, "%s(%s): GT failed to idle before, with err=%d!",
+ func, name, err);
+ return err;
+ }
- for_each_engine(engine, gt, id)
- t->reset_engine[id] =
+ for_each_engine(engine, gt, id)
+ t->reset_engine[id] =
i915_reset_engine_count(&i915->gpu_error, engine);
+ }
+
+ t->reset_global = i915_reset_count(&i915->gpu_error);
return 0;
}
@@ -46,6 +51,8 @@ int igt_live_test_end(struct igt_live_test *t)
struct drm_i915_private *i915 = t->i915;
struct intel_engine_cs *engine;
enum intel_engine_id id;
+ struct intel_gt *gt;
+ unsigned int i;
if (igt_flush_test(i915))
return -EIO;
@@ -57,16 +64,18 @@ int igt_live_test_end(struct igt_live_test *t)
return -EIO;
}
- for_each_engine(engine, to_gt(i915), id) {
- if (t->reset_engine[id] ==
- i915_reset_engine_count(&i915->gpu_error, engine))
- continue;
+ for_each_gt(gt, i915, i) {
+ for_each_engine(engine, gt, id) {
+ if (t->reset_engine[id] ==
+ i915_reset_engine_count(&i915->gpu_error, engine))
+ continue;
- pr_err("%s(%s): engine '%s' was reset %d times!\n",
- t->func, t->name, engine->name,
- i915_reset_engine_count(&i915->gpu_error, engine) -
- t->reset_engine[id]);
- return -EIO;
+ gt_err(gt, "%s(%s): engine '%s' was reset %d times!\n",
+ t->func, t->name, engine->name,
+ i915_reset_engine_count(&i915->gpu_error, engine) -
+ t->reset_engine[id]);
+ return -EIO;
+ }
}
return 0;
diff --git a/drivers/gpu/drm/i915/selftests/intel_memory_region.c b/drivers/gpu/drm/i915/selftests/intel_memory_region.c
index 3b18e5905c86..d985d9bae2e8 100644
--- a/drivers/gpu/drm/i915/selftests/intel_memory_region.c
+++ b/drivers/gpu/drm/i915/selftests/intel_memory_region.c
@@ -1070,7 +1070,9 @@ static int igt_lmem_write_cpu(void *arg)
/* Put the pages into a known state -- from the gpu for added fun */
intel_engine_pm_get(engine);
err = intel_context_migrate_clear(engine->gt->migrate.context, NULL,
- obj->mm.pages->sgl, I915_CACHE_NONE,
+ obj->mm.pages->sgl,
+ i915_gem_get_pat_index(i915,
+ I915_CACHE_NONE),
true, 0xdeadbeaf, &rq);
if (rq) {
dma_resv_add_fence(obj->base.resv, &rq->fence,
diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
index f6a7c0bd2955..0eda8b4ee17f 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
@@ -123,7 +123,9 @@ struct drm_i915_private *mock_gem_device(void)
static struct dev_iommu fake_iommu = { .priv = (void *)-1 };
#endif
struct drm_i915_private *i915;
+ struct intel_device_info *i915_info;
struct pci_dev *pdev;
+ unsigned int i;
int ret;
pdev = kzalloc(sizeof(*pdev), GFP_KERNEL);
@@ -180,6 +182,13 @@ struct drm_i915_private *mock_gem_device(void)
I915_GTT_PAGE_SIZE_2M;
RUNTIME_INFO(i915)->memory_regions = REGION_SMEM;
+
+ /* simply use legacy cache level for mock device */
+ i915_info = (struct intel_device_info *)INTEL_INFO(i915);
+ i915_info->max_pat_index = 3;
+ for (i = 0; i < I915_MAX_CACHE_LEVEL; i++)
+ i915_info->cachelevel_to_pat[i] = i;
+
intel_memory_regions_hw_probe(i915);
spin_lock_init(&i915->gpu_error.lock);
diff --git a/drivers/gpu/drm/i915/selftests/mock_gtt.c b/drivers/gpu/drm/i915/selftests/mock_gtt.c
index ece97e4faacb..a516c0aa88fd 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gtt.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gtt.c
@@ -27,21 +27,21 @@
static void mock_insert_page(struct i915_address_space *vm,
dma_addr_t addr,
u64 offset,
- enum i915_cache_level level,
+ unsigned int pat_index,
u32 flags)
{
}
static void mock_insert_entries(struct i915_address_space *vm,
struct i915_vma_resource *vma_res,
- enum i915_cache_level level, u32 flags)
+ unsigned int pat_index, u32 flags)
{
}
static void mock_bind_ppgtt(struct i915_address_space *vm,
struct i915_vm_pt_stash *stash,
struct i915_vma_resource *vma_res,
- enum i915_cache_level cache_level,
+ unsigned int pat_index,
u32 flags)
{
GEM_BUG_ON(flags & I915_VMA_GLOBAL_BIND);
@@ -94,7 +94,7 @@ struct i915_ppgtt *mock_ppgtt(struct drm_i915_private *i915, const char *name)
static void mock_bind_ggtt(struct i915_address_space *vm,
struct i915_vm_pt_stash *stash,
struct i915_vma_resource *vma_res,
- enum i915_cache_level cache_level,
+ unsigned int pat_index,
u32 flags)
{
}
diff --git a/drivers/gpu/drm/imx/lcdc/imx-lcdc.c b/drivers/gpu/drm/imx/lcdc/imx-lcdc.c
index 8e6d457917da..277ead6a459a 100644
--- a/drivers/gpu/drm/imx/lcdc/imx-lcdc.c
+++ b/drivers/gpu/drm/imx/lcdc/imx-lcdc.c
@@ -400,8 +400,8 @@ static int imx_lcdc_probe(struct platform_device *pdev)
lcdc = devm_drm_dev_alloc(dev, &imx_lcdc_drm_driver,
struct imx_lcdc, drm);
- if (!lcdc)
- return -ENOMEM;
+ if (IS_ERR(lcdc))
+ return PTR_ERR(lcdc);
drm = &lcdc->drm;
diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
index bb72fda9106d..ca6d1e59e5d9 100644
--- a/drivers/gpu/drm/meson/meson_drv.c
+++ b/drivers/gpu/drm/meson/meson_drv.c
@@ -285,7 +285,7 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
* Remove early framebuffers (ie. simplefb). The framebuffer can be
* located anywhere in RAM
*/
- ret = drm_aperture_remove_framebuffers(false, &meson_driver);
+ ret = drm_aperture_remove_framebuffers(&meson_driver);
if (ret)
goto free_drm;
diff --git a/drivers/gpu/drm/meson/meson_venc.c b/drivers/gpu/drm/meson/meson_venc.c
index fcd532db19c1..27ef9f88e4ff 100644
--- a/drivers/gpu/drm/meson/meson_venc.c
+++ b/drivers/gpu/drm/meson/meson_venc.c
@@ -186,7 +186,7 @@ union meson_hdmi_venc_mode {
} encp;
};
-union meson_hdmi_venc_mode meson_hdmi_enci_mode_480i = {
+static union meson_hdmi_venc_mode meson_hdmi_enci_mode_480i = {
.enci = {
.hso_begin = 5,
.hso_end = 129,
@@ -206,7 +206,7 @@ union meson_hdmi_venc_mode meson_hdmi_enci_mode_480i = {
},
};
-union meson_hdmi_venc_mode meson_hdmi_enci_mode_576i = {
+static union meson_hdmi_venc_mode meson_hdmi_enci_mode_576i = {
.enci = {
.hso_begin = 3,
.hso_end = 129,
@@ -226,7 +226,7 @@ union meson_hdmi_venc_mode meson_hdmi_enci_mode_576i = {
},
};
-union meson_hdmi_venc_mode meson_hdmi_encp_mode_480p = {
+static union meson_hdmi_venc_mode meson_hdmi_encp_mode_480p = {
.encp = {
.dvi_settings = 0x21,
.video_mode = 0x4000,
@@ -272,7 +272,7 @@ union meson_hdmi_venc_mode meson_hdmi_encp_mode_480p = {
},
};
-union meson_hdmi_venc_mode meson_hdmi_encp_mode_576p = {
+static union meson_hdmi_venc_mode meson_hdmi_encp_mode_576p = {
.encp = {
.dvi_settings = 0x21,
.video_mode = 0x4000,
@@ -318,7 +318,7 @@ union meson_hdmi_venc_mode meson_hdmi_encp_mode_576p = {
},
};
-union meson_hdmi_venc_mode meson_hdmi_encp_mode_720p60 = {
+static union meson_hdmi_venc_mode meson_hdmi_encp_mode_720p60 = {
.encp = {
.dvi_settings = 0x2029,
.video_mode = 0x4040,
@@ -360,7 +360,7 @@ union meson_hdmi_venc_mode meson_hdmi_encp_mode_720p60 = {
},
};
-union meson_hdmi_venc_mode meson_hdmi_encp_mode_720p50 = {
+static union meson_hdmi_venc_mode meson_hdmi_encp_mode_720p50 = {
.encp = {
.dvi_settings = 0x202d,
.video_mode = 0x4040,
@@ -405,7 +405,7 @@ union meson_hdmi_venc_mode meson_hdmi_encp_mode_720p50 = {
},
};
-union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080i60 = {
+static union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080i60 = {
.encp = {
.dvi_settings = 0x2029,
.video_mode = 0x5ffc,
@@ -454,7 +454,7 @@ union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080i60 = {
},
};
-union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080i50 = {
+static union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080i50 = {
.encp = {
.dvi_settings = 0x202d,
.video_mode = 0x5ffc,
@@ -503,7 +503,7 @@ union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080i50 = {
},
};
-union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p24 = {
+static union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p24 = {
.encp = {
.dvi_settings = 0xd,
.video_mode = 0x4040,
@@ -552,7 +552,7 @@ union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p24 = {
},
};
-union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p30 = {
+static union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p30 = {
.encp = {
.dvi_settings = 0x1,
.video_mode = 0x4040,
@@ -596,7 +596,7 @@ union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p30 = {
},
};
-union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p50 = {
+static union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p50 = {
.encp = {
.dvi_settings = 0xd,
.video_mode = 0x4040,
@@ -644,7 +644,7 @@ union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p50 = {
},
};
-union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p60 = {
+static union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p60 = {
.encp = {
.dvi_settings = 0x1,
.video_mode = 0x4040,
@@ -688,7 +688,7 @@ union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p60 = {
},
};
-union meson_hdmi_venc_mode meson_hdmi_encp_mode_2160p24 = {
+static union meson_hdmi_venc_mode meson_hdmi_encp_mode_2160p24 = {
.encp = {
.dvi_settings = 0x1,
.video_mode = 0x4040,
@@ -730,7 +730,7 @@ union meson_hdmi_venc_mode meson_hdmi_encp_mode_2160p24 = {
},
};
-union meson_hdmi_venc_mode meson_hdmi_encp_mode_2160p25 = {
+static union meson_hdmi_venc_mode meson_hdmi_encp_mode_2160p25 = {
.encp = {
.dvi_settings = 0x1,
.video_mode = 0x4040,
@@ -772,7 +772,7 @@ union meson_hdmi_venc_mode meson_hdmi_encp_mode_2160p25 = {
},
};
-union meson_hdmi_venc_mode meson_hdmi_encp_mode_2160p30 = {
+static union meson_hdmi_venc_mode meson_hdmi_encp_mode_2160p30 = {
.encp = {
.dvi_settings = 0x1,
.video_mode = 0x4040,
@@ -814,7 +814,7 @@ union meson_hdmi_venc_mode meson_hdmi_encp_mode_2160p30 = {
},
};
-struct meson_hdmi_venc_vic_mode {
+static struct meson_hdmi_venc_vic_mode {
unsigned int vic;
union meson_hdmi_venc_mode *mode;
} meson_hdmi_venc_vic_modes[] = {
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index b4cfa44a8a5c..060c7689a739 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -455,7 +455,7 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv)
goto err_deinit_vram;
/* the fw fb could be anywhere in memory */
- ret = drm_aperture_remove_framebuffers(false, drv);
+ ret = drm_aperture_remove_framebuffers(drv);
if (ret)
goto err_msm_uninit;
diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c
index 2ebc86381e1c..ce0ba6d1979a 100644
--- a/drivers/gpu/drm/msm/msm_fbdev.c
+++ b/drivers/gpu/drm/msm/msm_fbdev.c
@@ -121,9 +121,9 @@ static int msm_fbdev_create(struct drm_fb_helper *helper,
drm_fb_helper_fill_info(fbi, helper, sizes);
- fbi->screen_base = msm_gem_get_vaddr(bo);
- if (IS_ERR(fbi->screen_base)) {
- ret = PTR_ERR(fbi->screen_base);
+ fbi->screen_buffer = msm_gem_get_vaddr(bo);
+ if (IS_ERR(fbi->screen_buffer)) {
+ ret = PTR_ERR(fbi->screen_buffer);
goto fail;
}
fbi->screen_size = bo->size;
diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 5bb777ff1313..9b6824f6b9e4 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -64,6 +64,7 @@
#include "nouveau_connector.h"
#include "nouveau_encoder.h"
#include "nouveau_fence.h"
+#include "nv50_display.h"
#include <subdev/bios/dp.h>
diff --git a/drivers/gpu/drm/nouveau/include/nvif/if0012.h b/drivers/gpu/drm/nouveau/include/nvif/if0012.h
index eb99d84eb844..16d4ad5023a3 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/if0012.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/if0012.h
@@ -2,6 +2,8 @@
#ifndef __NVIF_IF0012_H__
#define __NVIF_IF0012_H__
+#include <drm/display/drm_dp.h>
+
union nvif_outp_args {
struct nvif_outp_v0 {
__u8 version;
@@ -63,7 +65,7 @@ union nvif_outp_acquire_args {
__u8 hda;
__u8 mst;
__u8 pad04[4];
- __u8 dpcd[16];
+ __u8 dpcd[DP_RECEIVER_CAP_SIZE];
} dp;
};
} v0;
diff --git a/drivers/gpu/drm/nouveau/nouveau_debugfs.c b/drivers/gpu/drm/nouveau/nouveau_debugfs.c
index 2a36d1ca8fda..99d022a91afc 100644
--- a/drivers/gpu/drm/nouveau/nouveau_debugfs.c
+++ b/drivers/gpu/drm/nouveau/nouveau_debugfs.c
@@ -73,13 +73,14 @@ nouveau_debugfs_pstate_get(struct seq_file *m, void *data)
{
struct drm_device *drm = m->private;
struct nouveau_debugfs *debugfs = nouveau_debugfs(drm);
- struct nvif_object *ctrl = &debugfs->ctrl;
+ struct nvif_object *ctrl;
struct nvif_control_pstate_info_v0 info = {};
int ret, i;
if (!debugfs)
return -ENODEV;
+ ctrl = &debugfs->ctrl;
ret = nvif_mthd(ctrl, NVIF_CONTROL_PSTATE_INFO, &info, sizeof(info));
if (ret)
return ret;
@@ -119,19 +120,19 @@ nouveau_debugfs_pstate_get(struct seq_file *m, void *data)
if (state >= 0) {
if (info.ustate_ac == state)
- seq_printf(m, " AC");
+ seq_puts(m, " AC");
if (info.ustate_dc == state)
- seq_printf(m, " DC");
+ seq_puts(m, " DC");
if (info.pstate == state)
- seq_printf(m, " *");
+ seq_puts(m, " *");
} else {
if (info.ustate_ac < -1)
- seq_printf(m, " AC");
+ seq_puts(m, " AC");
if (info.ustate_dc < -1)
- seq_printf(m, " DC");
+ seq_puts(m, " DC");
}
- seq_printf(m, "\n");
+ seq_putc(m, '\n');
}
return 0;
@@ -144,7 +145,6 @@ nouveau_debugfs_pstate_set(struct file *file, const char __user *ubuf,
struct seq_file *m = file->private_data;
struct drm_device *drm = m->private;
struct nouveau_debugfs *debugfs = nouveau_debugfs(drm);
- struct nvif_object *ctrl = &debugfs->ctrl;
struct nvif_control_pstate_user_v0 args = { .pwrsrc = -EINVAL };
char buf[32] = {}, *tmp, *cur = buf;
long value, ret;
@@ -188,7 +188,8 @@ nouveau_debugfs_pstate_set(struct file *file, const char __user *ubuf,
return ret;
}
- ret = nvif_mthd(ctrl, NVIF_CONTROL_PSTATE_USER, &args, sizeof(args));
+ ret = nvif_mthd(&debugfs->ctrl, NVIF_CONTROL_PSTATE_USER,
+ &args, sizeof(args));
pm_runtime_put_autosuspend(drm->dev);
if (ret < 0)
return ret;
diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
index e844be49e11e..db30a4c2cd4d 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
@@ -211,7 +211,7 @@ static const struct attribute_group temp1_auto_point_sensor_group = {
#define N_ATTR_GROUPS 3
-static const struct hwmon_channel_info *nouveau_info[] = {
+static const struct hwmon_channel_info * const nouveau_info[] = {
HWMON_CHANNEL_INFO(chip,
HWMON_C_UPDATE_INTERVAL),
HWMON_CHANNEL_INFO(temp,
diff --git a/drivers/gpu/drm/nouveau/nv50_display.h b/drivers/gpu/drm/nouveau/nv50_display.h
index fbd3b15583bc..60f77766766e 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.h
+++ b/drivers/gpu/drm/nouveau/nv50_display.h
@@ -31,7 +31,5 @@
#include "nouveau_reg.h"
int nv50_display_create(struct drm_device *);
-void nv50_display_destroy(struct drm_device *);
-int nv50_display_init(struct drm_device *);
-void nv50_display_fini(struct drm_device *);
+
#endif /* __NV50_DISPLAY_H__ */
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h
index b7631c1ab242..4e7f873f66e2 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h
@@ -3,6 +3,7 @@
#define __NVKM_DISP_OUTP_H__
#include "priv.h"
+#include <drm/display/drm_dp.h>
#include <subdev/bios.h>
#include <subdev/bios/dcb.h>
#include <subdev/bios/dp.h>
@@ -42,7 +43,7 @@ struct nvkm_outp {
bool aux_pwr_pu;
u8 lttpr[6];
u8 lttprs;
- u8 dpcd[16];
+ u8 dpcd[DP_RECEIVER_CAP_SIZE];
struct {
int dpcd; /* -1, or index into SUPPORTED_LINK_RATES table */
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
index 4f0ca709c85a..fc283a4a1522 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
@@ -146,7 +146,7 @@ nvkm_uoutp_mthd_release(struct nvkm_outp *outp, void *argv, u32 argc)
}
static int
-nvkm_uoutp_mthd_acquire_dp(struct nvkm_outp *outp, u8 dpcd[16],
+nvkm_uoutp_mthd_acquire_dp(struct nvkm_outp *outp, u8 dpcd[DP_RECEIVER_CAP_SIZE],
u8 link_nr, u8 link_bw, bool hda, bool mst)
{
int ret;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/power_budget.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/power_budget.c
index 03d2f970a29f..2ba992bdb19d 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/power_budget.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/power_budget.c
@@ -59,7 +59,6 @@ int
nvbios_power_budget_header(struct nvkm_bios *bios,
struct nvbios_power_budget *budget)
{
- struct nvkm_subdev *subdev = &bios->subdev;
u8 ver, hdr, cnt, len, cap_entry;
u32 header;
@@ -82,7 +81,7 @@ nvbios_power_budget_header(struct nvkm_bios *bios,
}
if (cap_entry >= cnt && cap_entry != 0xff) {
- nvkm_warn(subdev,
+ nvkm_warn(&bios->subdev,
"invalid cap_entry in power budget table found\n");
budget->cap_entry = 0xff;
return -EINVAL;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c
index da07a2fbef06..178dc56909c2 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c
@@ -417,7 +417,6 @@ nvkm_pstate_new(struct nvkm_clk *clk, int idx)
return 0;
pstate = kzalloc(sizeof(*pstate), GFP_KERNEL);
- cstate = &pstate->base;
if (!pstate)
return -ENOMEM;
@@ -427,6 +426,7 @@ nvkm_pstate_new(struct nvkm_clk *clk, int idx)
pstate->fanspeed = perfE.fanspeed;
pstate->pcie_speed = perfE.pcie_speed;
pstate->pcie_width = perfE.pcie_width;
+ cstate = &pstate->base;
cstate->voltage = perfE.voltage;
cstate->domain[nv_clk_src_core] = perfE.core;
cstate->domain[nv_clk_src_shader] = perfE.shader;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga102.c
index 525267412c3e..a3996ceca995 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga102.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga102.c
@@ -45,7 +45,7 @@ ga102_gsp_nofw(struct nvkm_gsp *gsp, int ver, const struct nvkm_gsp_fwif *fwif)
return 0;
}
-struct nvkm_gsp_fwif
+static struct nvkm_gsp_fwif
ga102_gsps[] = {
{ -1, ga102_gsp_nofw, &ga102_gsp },
{}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/pcie.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/pcie.c
index d71e5db5028a..dd18d9d0bade 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/pcie.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/pcie.c
@@ -114,18 +114,17 @@ nvkm_pcie_init(struct nvkm_pci *pci)
int
nvkm_pcie_set_link(struct nvkm_pci *pci, enum nvkm_pcie_speed speed, u8 width)
{
- struct nvkm_subdev *subdev = &pci->subdev;
+ struct nvkm_subdev *subdev;
enum nvkm_pcie_speed cur_speed, max_speed;
- struct pci_bus *pbus;
int ret;
if (!pci || !pci_is_pcie(pci->pdev))
return 0;
- pbus = pci->pdev->bus;
if (!pci->func->pcie.set_link)
return -ENOSYS;
+ subdev = &pci->subdev;
nvkm_trace(subdev, "requested %s\n", nvkm_pcie_speeds[speed]);
if (pci->func->pcie.version(pci) < 2) {
@@ -134,7 +133,7 @@ nvkm_pcie_set_link(struct nvkm_pci *pci, enum nvkm_pcie_speed speed, u8 width)
}
cur_speed = pci->func->pcie.cur_speed(pci);
- max_speed = min(nvkm_pcie_speed(pbus->max_bus_speed),
+ max_speed = min(nvkm_pcie_speed(pci->pdev->bus->max_bus_speed),
pci->func->pcie.max_speed(pci));
nvkm_trace(subdev, "current speed: %s\n", nvkm_pcie_speeds[cur_speed]);
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/fanpwm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/fanpwm.c
index 340f37a299dc..b13ba9b2f6be 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/fanpwm.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/fanpwm.c
@@ -98,10 +98,10 @@ nvkm_fanpwm_create(struct nvkm_therm *therm, struct dcb_gpio_func *func)
return -ENODEV;
fan = kzalloc(sizeof(*fan), GFP_KERNEL);
- therm->fan = &fan->base;
if (!fan)
return -ENOMEM;
+ therm->fan = &fan->base;
fan->base.type = "PWM";
fan->base.get = nvkm_fanpwm_get;
fan->base.set = nvkm_fanpwm_set;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/fantog.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/fantog.c
index ff9fbe7950e5..bfdf4ca5625c 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/fantog.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/fantog.c
@@ -100,10 +100,10 @@ nvkm_fantog_create(struct nvkm_therm *therm, struct dcb_gpio_func *func)
}
fan = kzalloc(sizeof(*fan), GFP_KERNEL);
- therm->fan = &fan->base;
if (!fan)
return -ENOMEM;
+ therm->fan = &fan->base;
fan->base.type = "toggle";
fan->base.get = nvkm_fantog_get;
fan->base.set = nvkm_fantog_set;
diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 2b9d6db7860b..203c0ef0bbfd 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -553,6 +553,13 @@ config DRM_PANEL_SAMSUNG_S6D27A1
This panel can be found in Samsung Galaxy Ace 2
GT-I8160 mobile phone.
+config DRM_PANEL_SAMSUNG_S6D7AA0
+ tristate "Samsung S6D7AA0 MIPI-DSI video mode panel controller"
+ depends on OF
+ depends on BACKLIGHT_CLASS_DEVICE
+ select DRM_MIPI_DSI
+ select VIDEOMODE_HELPERS
+
config DRM_PANEL_SAMSUNG_S6E3HA2
tristate "Samsung S6E3HA2 DSI video mode panel"
depends on OF
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index ff169781e82d..30cf553c8d1d 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -54,6 +54,7 @@ obj-$(CONFIG_DRM_PANEL_SAMSUNG_DB7430) += panel-samsung-db7430.o
obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o
obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6D16D0) += panel-samsung-s6d16d0.o
obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6D27A1) += panel-samsung-s6d27a1.o
+obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6D7AA0) += panel-samsung-s6d7aa0.o
obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2) += panel-samsung-s6e3ha2.o
obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03) += panel-samsung-s6e63j0x03.o
obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E63M0) += panel-samsung-s6e63m0.o
diff --git a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
index 783234ae0f57..f5a6046f1d19 100644
--- a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
+++ b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
@@ -36,6 +36,7 @@ struct panel_desc {
const struct panel_init_cmd *init_cmds;
unsigned int lanes;
bool discharge_on_disable;
+ bool lp11_before_reset;
};
struct boe_panel {
@@ -451,11 +452,14 @@ static const struct panel_init_cmd inx_hj110iz_init_cmd[] = {
_INIT_DCS_CMD(0xFF, 0x20),
_INIT_DCS_CMD(0xFB, 0x01),
_INIT_DCS_CMD(0x05, 0xD1),
- _INIT_DCS_CMD(0x0D, 0x63),
- _INIT_DCS_CMD(0x07, 0x8C),
+ _INIT_DCS_CMD(0x06, 0xC0),
+ _INIT_DCS_CMD(0x07, 0x87),
_INIT_DCS_CMD(0x08, 0x4B),
+
+ _INIT_DCS_CMD(0x0D, 0x63),
_INIT_DCS_CMD(0x0E, 0x91),
_INIT_DCS_CMD(0x0F, 0x69),
+ _INIT_DCS_CMD(0x94, 0x00),
_INIT_DCS_CMD(0x95, 0xF5),
_INIT_DCS_CMD(0x96, 0xF5),
_INIT_DCS_CMD(0x9D, 0x00),
@@ -463,98 +467,96 @@ static const struct panel_init_cmd inx_hj110iz_init_cmd[] = {
_INIT_DCS_CMD(0x69, 0x98),
_INIT_DCS_CMD(0x75, 0xA2),
_INIT_DCS_CMD(0x77, 0xB3),
+
+ _INIT_DCS_CMD(0x58, 0x43),
_INIT_DCS_CMD(0xFF, 0x24),
_INIT_DCS_CMD(0xFB, 0x01),
_INIT_DCS_CMD(0x91, 0x44),
- _INIT_DCS_CMD(0x92, 0x7A),
- _INIT_DCS_CMD(0x93, 0x1A),
- _INIT_DCS_CMD(0x94, 0x40),
- _INIT_DCS_CMD(0x9A, 0x08),
+ _INIT_DCS_CMD(0x92, 0x4C),
+ _INIT_DCS_CMD(0x94, 0x86),
_INIT_DCS_CMD(0x60, 0x96),
_INIT_DCS_CMD(0x61, 0xD0),
_INIT_DCS_CMD(0x63, 0x70),
- _INIT_DCS_CMD(0xC2, 0xCF),
- _INIT_DCS_CMD(0x9B, 0x0F),
- _INIT_DCS_CMD(0x9A, 0x08),
+ _INIT_DCS_CMD(0xC2, 0xCA),
+
_INIT_DCS_CMD(0x00, 0x03),
_INIT_DCS_CMD(0x01, 0x03),
_INIT_DCS_CMD(0x02, 0x03),
- _INIT_DCS_CMD(0x03, 0x03),
- _INIT_DCS_CMD(0x04, 0x03),
- _INIT_DCS_CMD(0x05, 0x03),
- _INIT_DCS_CMD(0x06, 0x22),
- _INIT_DCS_CMD(0x07, 0x06),
- _INIT_DCS_CMD(0x08, 0x00),
- _INIT_DCS_CMD(0x09, 0x1D),
- _INIT_DCS_CMD(0x0A, 0x1C),
- _INIT_DCS_CMD(0x0B, 0x13),
- _INIT_DCS_CMD(0x0C, 0x12),
- _INIT_DCS_CMD(0x0D, 0x11),
- _INIT_DCS_CMD(0x0E, 0x10),
- _INIT_DCS_CMD(0x0F, 0x0F),
- _INIT_DCS_CMD(0x10, 0x0E),
- _INIT_DCS_CMD(0x11, 0x0D),
- _INIT_DCS_CMD(0x12, 0x0C),
+ _INIT_DCS_CMD(0x03, 0x29),
+ _INIT_DCS_CMD(0x04, 0x22),
+ _INIT_DCS_CMD(0x05, 0x22),
+ _INIT_DCS_CMD(0x06, 0x0B),
+ _INIT_DCS_CMD(0x07, 0x1D),
+ _INIT_DCS_CMD(0x08, 0x1C),
+ _INIT_DCS_CMD(0x09, 0x05),
+ _INIT_DCS_CMD(0x0A, 0x08),
+ _INIT_DCS_CMD(0x0B, 0x09),
+ _INIT_DCS_CMD(0x0C, 0x0A),
+ _INIT_DCS_CMD(0x0D, 0x0C),
+ _INIT_DCS_CMD(0x0E, 0x0D),
+ _INIT_DCS_CMD(0x0F, 0x0E),
+ _INIT_DCS_CMD(0x10, 0x0F),
+ _INIT_DCS_CMD(0x11, 0x10),
+ _INIT_DCS_CMD(0x12, 0x11),
_INIT_DCS_CMD(0x13, 0x04),
- _INIT_DCS_CMD(0x14, 0x03),
+ _INIT_DCS_CMD(0x14, 0x00),
_INIT_DCS_CMD(0x15, 0x03),
_INIT_DCS_CMD(0x16, 0x03),
_INIT_DCS_CMD(0x17, 0x03),
_INIT_DCS_CMD(0x18, 0x03),
- _INIT_DCS_CMD(0x19, 0x03),
- _INIT_DCS_CMD(0x1A, 0x03),
- _INIT_DCS_CMD(0x1B, 0x03),
- _INIT_DCS_CMD(0x1C, 0x22),
- _INIT_DCS_CMD(0x1D, 0x06),
- _INIT_DCS_CMD(0x1E, 0x00),
- _INIT_DCS_CMD(0x1F, 0x1D),
- _INIT_DCS_CMD(0x20, 0x1C),
- _INIT_DCS_CMD(0x21, 0x13),
- _INIT_DCS_CMD(0x22, 0x12),
- _INIT_DCS_CMD(0x23, 0x11),
- _INIT_DCS_CMD(0x24, 0x10),
- _INIT_DCS_CMD(0x25, 0x0F),
- _INIT_DCS_CMD(0x26, 0x0E),
- _INIT_DCS_CMD(0x27, 0x0D),
- _INIT_DCS_CMD(0x28, 0x0C),
+ _INIT_DCS_CMD(0x19, 0x29),
+ _INIT_DCS_CMD(0x1A, 0x22),
+ _INIT_DCS_CMD(0x1B, 0x22),
+ _INIT_DCS_CMD(0x1C, 0x0B),
+ _INIT_DCS_CMD(0x1D, 0x1D),
+ _INIT_DCS_CMD(0x1E, 0x1C),
+ _INIT_DCS_CMD(0x1F, 0x05),
+ _INIT_DCS_CMD(0x20, 0x08),
+ _INIT_DCS_CMD(0x21, 0x09),
+ _INIT_DCS_CMD(0x22, 0x0A),
+ _INIT_DCS_CMD(0x23, 0x0C),
+ _INIT_DCS_CMD(0x24, 0x0D),
+ _INIT_DCS_CMD(0x25, 0x0E),
+ _INIT_DCS_CMD(0x26, 0x0F),
+ _INIT_DCS_CMD(0x27, 0x10),
+ _INIT_DCS_CMD(0x28, 0x11),
_INIT_DCS_CMD(0x29, 0x04),
- _INIT_DCS_CMD(0x2A, 0x03),
+ _INIT_DCS_CMD(0x2A, 0x00),
_INIT_DCS_CMD(0x2B, 0x03),
- _INIT_DCS_CMD(0x2F, 0x05),
- _INIT_DCS_CMD(0x30, 0x32),
- _INIT_DCS_CMD(0x31, 0x43),
- _INIT_DCS_CMD(0x33, 0x05),
- _INIT_DCS_CMD(0x34, 0x32),
- _INIT_DCS_CMD(0x35, 0x43),
- _INIT_DCS_CMD(0x37, 0x44),
- _INIT_DCS_CMD(0x38, 0x40),
+ _INIT_DCS_CMD(0x2F, 0x0A),
+ _INIT_DCS_CMD(0x30, 0x35),
+ _INIT_DCS_CMD(0x37, 0xA7),
_INIT_DCS_CMD(0x39, 0x00),
- _INIT_DCS_CMD(0x3A, 0x18),
- _INIT_DCS_CMD(0x3B, 0x00),
- _INIT_DCS_CMD(0x3D, 0x93),
- _INIT_DCS_CMD(0xAB, 0x44),
- _INIT_DCS_CMD(0xAC, 0x40),
+ _INIT_DCS_CMD(0x3A, 0x46),
+ _INIT_DCS_CMD(0x3B, 0x32),
+ _INIT_DCS_CMD(0x3D, 0x12),
+
+ _INIT_DCS_CMD(0x3F, 0x33),
+ _INIT_DCS_CMD(0x40, 0x31),
+ _INIT_DCS_CMD(0x41, 0x40),
+ _INIT_DCS_CMD(0x42, 0x42),
+ _INIT_DCS_CMD(0x47, 0x77),
+ _INIT_DCS_CMD(0x48, 0x77),
+ _INIT_DCS_CMD(0x4A, 0x45),
+ _INIT_DCS_CMD(0x4B, 0x45),
+ _INIT_DCS_CMD(0x4C, 0x14),
_INIT_DCS_CMD(0x4D, 0x21),
_INIT_DCS_CMD(0x4E, 0x43),
_INIT_DCS_CMD(0x4F, 0x65),
- _INIT_DCS_CMD(0x50, 0x87),
- _INIT_DCS_CMD(0x51, 0x78),
- _INIT_DCS_CMD(0x52, 0x56),
- _INIT_DCS_CMD(0x53, 0x34),
- _INIT_DCS_CMD(0x54, 0x21),
- _INIT_DCS_CMD(0x55, 0x83),
- _INIT_DCS_CMD(0x56, 0x08),
+ _INIT_DCS_CMD(0x55, 0x06),
+ _INIT_DCS_CMD(0x56, 0x06),
_INIT_DCS_CMD(0x58, 0x21),
- _INIT_DCS_CMD(0x59, 0x40),
- _INIT_DCS_CMD(0x5A, 0x00),
- _INIT_DCS_CMD(0x5B, 0x2C),
- _INIT_DCS_CMD(0x5E, 0x00, 0x10),
+ _INIT_DCS_CMD(0x59, 0x70),
+ _INIT_DCS_CMD(0x5A, 0x46),
+ _INIT_DCS_CMD(0x5B, 0x32),
+ _INIT_DCS_CMD(0x5C, 0x88),
+ _INIT_DCS_CMD(0x5E, 0x00, 0x00),
_INIT_DCS_CMD(0x5F, 0x00),
- _INIT_DCS_CMD(0x7A, 0x00),
- _INIT_DCS_CMD(0x7B, 0x00),
+ _INIT_DCS_CMD(0x7A, 0xFF),
+ _INIT_DCS_CMD(0x7B, 0xFF),
_INIT_DCS_CMD(0x7C, 0x00),
_INIT_DCS_CMD(0x7D, 0x00),
_INIT_DCS_CMD(0x7E, 0x20),
@@ -564,152 +566,183 @@ static const struct panel_init_cmd inx_hj110iz_init_cmd[] = {
_INIT_DCS_CMD(0x82, 0x08),
_INIT_DCS_CMD(0x97, 0x02),
_INIT_DCS_CMD(0xC5, 0x10),
+
+ _INIT_DCS_CMD(0xD7, 0x55),
+ _INIT_DCS_CMD(0xD8, 0x55),
+ _INIT_DCS_CMD(0xD9, 0x23),
_INIT_DCS_CMD(0xDA, 0x05),
_INIT_DCS_CMD(0xDB, 0x01),
- _INIT_DCS_CMD(0xDC, 0x7A),
+ _INIT_DCS_CMD(0xDC, 0x65),
_INIT_DCS_CMD(0xDD, 0x55),
_INIT_DCS_CMD(0xDE, 0x27),
_INIT_DCS_CMD(0xDF, 0x01),
- _INIT_DCS_CMD(0xE0, 0x7A),
+ _INIT_DCS_CMD(0xE0, 0x65),
_INIT_DCS_CMD(0xE1, 0x01),
- _INIT_DCS_CMD(0xE2, 0x7A),
+ _INIT_DCS_CMD(0xE2, 0x65),
_INIT_DCS_CMD(0xE3, 0x01),
- _INIT_DCS_CMD(0xE4, 0x7A),
+ _INIT_DCS_CMD(0xE4, 0x65),
_INIT_DCS_CMD(0xE5, 0x01),
- _INIT_DCS_CMD(0xE6, 0x7A),
+ _INIT_DCS_CMD(0xE6, 0x65),
_INIT_DCS_CMD(0xE7, 0x00),
_INIT_DCS_CMD(0xE8, 0x00),
_INIT_DCS_CMD(0xE9, 0x01),
- _INIT_DCS_CMD(0xEA, 0x7A),
+ _INIT_DCS_CMD(0xEA, 0x65),
_INIT_DCS_CMD(0xEB, 0x01),
- _INIT_DCS_CMD(0xEE, 0x7A),
+ _INIT_DCS_CMD(0xEE, 0x65),
_INIT_DCS_CMD(0xEF, 0x01),
- _INIT_DCS_CMD(0xF0, 0x7A),
-
+ _INIT_DCS_CMD(0xF0, 0x65),
_INIT_DCS_CMD(0xB6, 0x05, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x05, 0x00, 0x00),
+
_INIT_DCS_CMD(0xFF, 0x25),
- _INIT_DCS_CMD(0xFB, 0x01),
+ _INIT_DCS_CMD(0xFB, 0x01),
_INIT_DCS_CMD(0x05, 0x00),
-
- _INIT_DCS_CMD(0x13, 0x02),
- _INIT_DCS_CMD(0x14, 0xDF),
_INIT_DCS_CMD(0xF1, 0x10),
+
_INIT_DCS_CMD(0x1E, 0x00),
- _INIT_DCS_CMD(0x1F, 0x00),
- _INIT_DCS_CMD(0x20, 0x2C),
+ _INIT_DCS_CMD(0x1F, 0x46),
+ _INIT_DCS_CMD(0x20, 0x32),
+
_INIT_DCS_CMD(0x25, 0x00),
- _INIT_DCS_CMD(0x26, 0x00),
- _INIT_DCS_CMD(0x27, 0x2C),
+ _INIT_DCS_CMD(0x26, 0x46),
+ _INIT_DCS_CMD(0x27, 0x32),
+
_INIT_DCS_CMD(0x3F, 0x80),
_INIT_DCS_CMD(0x40, 0x00),
_INIT_DCS_CMD(0x43, 0x00),
- _INIT_DCS_CMD(0x44, 0x18),
- _INIT_DCS_CMD(0x45, 0x00),
+ _INIT_DCS_CMD(0x44, 0x46),
+ _INIT_DCS_CMD(0x45, 0x46),
+
+ _INIT_DCS_CMD(0x48, 0x46),
+ _INIT_DCS_CMD(0x49, 0x32),
- _INIT_DCS_CMD(0x48, 0x00),
- _INIT_DCS_CMD(0x49, 0x2C),
_INIT_DCS_CMD(0x5B, 0x80),
+
_INIT_DCS_CMD(0x5C, 0x00),
- _INIT_DCS_CMD(0x5D, 0x00),
- _INIT_DCS_CMD(0x5E, 0x00),
- _INIT_DCS_CMD(0x61, 0x00),
- _INIT_DCS_CMD(0x62, 0x2C),
- _INIT_DCS_CMD(0x68, 0x10),
+ _INIT_DCS_CMD(0x5D, 0x46),
+ _INIT_DCS_CMD(0x5E, 0x32),
+
+ _INIT_DCS_CMD(0x5F, 0x46),
+ _INIT_DCS_CMD(0x60, 0x32),
+
+ _INIT_DCS_CMD(0x61, 0x46),
+ _INIT_DCS_CMD(0x62, 0x32),
+ _INIT_DCS_CMD(0x68, 0x0C),
+
+ _INIT_DCS_CMD(0x6C, 0x0D),
+ _INIT_DCS_CMD(0x6E, 0x0D),
+ _INIT_DCS_CMD(0x78, 0x00),
+ _INIT_DCS_CMD(0x79, 0xC5),
+ _INIT_DCS_CMD(0x7A, 0x0C),
+ _INIT_DCS_CMD(0x7B, 0xB0),
+
_INIT_DCS_CMD(0xFF, 0x26),
_INIT_DCS_CMD(0xFB, 0x01),
_INIT_DCS_CMD(0x00, 0xA1),
_INIT_DCS_CMD(0x02, 0x31),
- _INIT_DCS_CMD(0x0A, 0xF2),
- _INIT_DCS_CMD(0x04, 0x28),
+ _INIT_DCS_CMD(0x0A, 0xF4),
+ _INIT_DCS_CMD(0x04, 0x50),
_INIT_DCS_CMD(0x06, 0x30),
_INIT_DCS_CMD(0x0C, 0x16),
_INIT_DCS_CMD(0x0D, 0x0D),
_INIT_DCS_CMD(0x0F, 0x00),
_INIT_DCS_CMD(0x11, 0x00),
_INIT_DCS_CMD(0x12, 0x50),
- _INIT_DCS_CMD(0x13, 0x56),
- _INIT_DCS_CMD(0x14, 0x57),
+ _INIT_DCS_CMD(0x13, 0x40),
+ _INIT_DCS_CMD(0x14, 0x58),
_INIT_DCS_CMD(0x15, 0x00),
_INIT_DCS_CMD(0x16, 0x10),
_INIT_DCS_CMD(0x17, 0xA0),
_INIT_DCS_CMD(0x18, 0x86),
_INIT_DCS_CMD(0x22, 0x00),
_INIT_DCS_CMD(0x23, 0x00),
- _INIT_DCS_CMD(0x19, 0x0D),
- _INIT_DCS_CMD(0x1A, 0x7F),
- _INIT_DCS_CMD(0x1B, 0x0C),
- _INIT_DCS_CMD(0x1C, 0xBF),
- _INIT_DCS_CMD(0x2A, 0x0D),
- _INIT_DCS_CMD(0x2B, 0x7F),
- _INIT_DCS_CMD(0x20, 0x00),
+
+ _INIT_DCS_CMD(0x19, 0x0E),
+ _INIT_DCS_CMD(0x1A, 0x31),
+ _INIT_DCS_CMD(0x1B, 0x0D),
+ _INIT_DCS_CMD(0x1C, 0x29),
+ _INIT_DCS_CMD(0x2A, 0x0E),
+ _INIT_DCS_CMD(0x2B, 0x31),
_INIT_DCS_CMD(0x1D, 0x00),
- _INIT_DCS_CMD(0x1E, 0x78),
- _INIT_DCS_CMD(0x1F, 0x78),
+ _INIT_DCS_CMD(0x1E, 0x62),
+ _INIT_DCS_CMD(0x1F, 0x62),
- _INIT_DCS_CMD(0x2F, 0x03),
- _INIT_DCS_CMD(0x30, 0x78),
- _INIT_DCS_CMD(0x33, 0x78),
- _INIT_DCS_CMD(0x34, 0x66),
- _INIT_DCS_CMD(0x35, 0x11),
+ _INIT_DCS_CMD(0x2F, 0x06),
+ _INIT_DCS_CMD(0x30, 0x62),
+ _INIT_DCS_CMD(0x31, 0x06),
+ _INIT_DCS_CMD(0x32, 0x7F),
+ _INIT_DCS_CMD(0x33, 0x11),
+ _INIT_DCS_CMD(0x34, 0x89),
+ _INIT_DCS_CMD(0x35, 0x67),
- _INIT_DCS_CMD(0x39, 0x10),
- _INIT_DCS_CMD(0x3A, 0x78),
+ _INIT_DCS_CMD(0x39, 0x0B),
+ _INIT_DCS_CMD(0x3A, 0x62),
_INIT_DCS_CMD(0x3B, 0x06),
_INIT_DCS_CMD(0xC8, 0x04),
- _INIT_DCS_CMD(0xC9, 0x84),
+ _INIT_DCS_CMD(0xC9, 0x89),
_INIT_DCS_CMD(0xCA, 0x4E),
_INIT_DCS_CMD(0xCB, 0x00),
+ _INIT_DCS_CMD(0xA9, 0x3F),
+ _INIT_DCS_CMD(0xAA, 0x3E),
+ _INIT_DCS_CMD(0xAB, 0x3D),
+ _INIT_DCS_CMD(0xAC, 0x3C),
+ _INIT_DCS_CMD(0xAD, 0x3B),
+ _INIT_DCS_CMD(0xAE, 0x3A),
+ _INIT_DCS_CMD(0xAF, 0x39),
+ _INIT_DCS_CMD(0xB0, 0x38),
- _INIT_DCS_CMD(0xA9, 0x50),
- _INIT_DCS_CMD(0xAA, 0x4F),
- _INIT_DCS_CMD(0xAB, 0x4D),
- _INIT_DCS_CMD(0xAC, 0x4A),
- _INIT_DCS_CMD(0xAD, 0x48),
- _INIT_DCS_CMD(0xAE, 0x46),
_INIT_DCS_CMD(0xFF, 0x27),
_INIT_DCS_CMD(0xFB, 0x01),
+
+ _INIT_DCS_CMD(0xD0, 0x11),
+ _INIT_DCS_CMD(0xD1, 0x54),
+ _INIT_DCS_CMD(0xDE, 0x43),
+ _INIT_DCS_CMD(0xDF, 0x02),
+
_INIT_DCS_CMD(0xC0, 0x18),
_INIT_DCS_CMD(0xC1, 0x00),
_INIT_DCS_CMD(0xC2, 0x00),
+ _INIT_DCS_CMD(0x00, 0x00),
+ _INIT_DCS_CMD(0xC3, 0x00),
_INIT_DCS_CMD(0x56, 0x06),
+
_INIT_DCS_CMD(0x58, 0x80),
- _INIT_DCS_CMD(0x59, 0x75),
+ _INIT_DCS_CMD(0x59, 0x78),
_INIT_DCS_CMD(0x5A, 0x00),
- _INIT_DCS_CMD(0x5B, 0x02),
+ _INIT_DCS_CMD(0x5B, 0x18),
_INIT_DCS_CMD(0x5C, 0x00),
- _INIT_DCS_CMD(0x5D, 0x00),
+ _INIT_DCS_CMD(0x5D, 0x01),
_INIT_DCS_CMD(0x5E, 0x20),
_INIT_DCS_CMD(0x5F, 0x10),
_INIT_DCS_CMD(0x60, 0x00),
- _INIT_DCS_CMD(0x61, 0x2E),
+ _INIT_DCS_CMD(0x61, 0x1C),
_INIT_DCS_CMD(0x62, 0x00),
_INIT_DCS_CMD(0x63, 0x01),
- _INIT_DCS_CMD(0x64, 0x43),
- _INIT_DCS_CMD(0x65, 0x2D),
+ _INIT_DCS_CMD(0x64, 0x44),
+ _INIT_DCS_CMD(0x65, 0x1B),
_INIT_DCS_CMD(0x66, 0x00),
_INIT_DCS_CMD(0x67, 0x01),
- _INIT_DCS_CMD(0x68, 0x43),
+ _INIT_DCS_CMD(0x68, 0x44),
+
_INIT_DCS_CMD(0x98, 0x01),
_INIT_DCS_CMD(0xB4, 0x03),
- _INIT_DCS_CMD(0x9B, 0xBD),
- _INIT_DCS_CMD(0xA0, 0x90),
- _INIT_DCS_CMD(0xAB, 0x1B),
- _INIT_DCS_CMD(0xBC, 0x0C),
+ _INIT_DCS_CMD(0x9B, 0xBE),
+
+ _INIT_DCS_CMD(0xAB, 0x14),
+ _INIT_DCS_CMD(0xBC, 0x08),
_INIT_DCS_CMD(0xBD, 0x28),
_INIT_DCS_CMD(0xFF, 0x2A),
_INIT_DCS_CMD(0xFB, 0x01),
-
_INIT_DCS_CMD(0x22, 0x2F),
_INIT_DCS_CMD(0x23, 0x08),
_INIT_DCS_CMD(0x24, 0x00),
- _INIT_DCS_CMD(0x25, 0x65),
+ _INIT_DCS_CMD(0x25, 0x62),
_INIT_DCS_CMD(0x26, 0xF8),
_INIT_DCS_CMD(0x27, 0x00),
_INIT_DCS_CMD(0x28, 0x1A),
@@ -719,18 +752,29 @@ static const struct panel_init_cmd inx_hj110iz_init_cmd[] = {
_INIT_DCS_CMD(0x2D, 0x1A),
_INIT_DCS_CMD(0x64, 0x96),
- _INIT_DCS_CMD(0x65, 0x00),
+ _INIT_DCS_CMD(0x65, 0x10),
_INIT_DCS_CMD(0x66, 0x00),
+ _INIT_DCS_CMD(0x67, 0x96),
+ _INIT_DCS_CMD(0x68, 0x10),
+ _INIT_DCS_CMD(0x69, 0x00),
_INIT_DCS_CMD(0x6A, 0x96),
- _INIT_DCS_CMD(0x6B, 0x00),
+ _INIT_DCS_CMD(0x6B, 0x10),
_INIT_DCS_CMD(0x6C, 0x00),
_INIT_DCS_CMD(0x70, 0x92),
- _INIT_DCS_CMD(0x71, 0x00),
+ _INIT_DCS_CMD(0x71, 0x10),
_INIT_DCS_CMD(0x72, 0x00),
- _INIT_DCS_CMD(0xA2, 0x33),
+ _INIT_DCS_CMD(0x79, 0x96),
+ _INIT_DCS_CMD(0x7A, 0x10),
+ _INIT_DCS_CMD(0x88, 0x96),
+ _INIT_DCS_CMD(0x89, 0x10),
+
+ _INIT_DCS_CMD(0xA2, 0x3F),
_INIT_DCS_CMD(0xA3, 0x30),
_INIT_DCS_CMD(0xA4, 0xC0),
+ _INIT_DCS_CMD(0xA5, 0x03),
+
_INIT_DCS_CMD(0xE8, 0x00),
+
_INIT_DCS_CMD(0x97, 0x3C),
_INIT_DCS_CMD(0x98, 0x02),
_INIT_DCS_CMD(0x99, 0x95),
@@ -739,38 +783,68 @@ static const struct panel_init_cmd inx_hj110iz_init_cmd[] = {
_INIT_DCS_CMD(0x9C, 0x0B),
_INIT_DCS_CMD(0x9D, 0x0A),
_INIT_DCS_CMD(0x9E, 0x90),
+
+ _INIT_DCS_CMD(0xFF, 0x25),
+ _INIT_DCS_CMD(0x13, 0x02),
+ _INIT_DCS_CMD(0x14, 0xD7),
+ _INIT_DCS_CMD(0xDB, 0x02),
+ _INIT_DCS_CMD(0xDC, 0xD7),
+ _INIT_DCS_CMD(0x17, 0xCF),
+ _INIT_DCS_CMD(0x19, 0x0F),
+ _INIT_DCS_CMD(0x1B, 0x5B),
+
+ _INIT_DCS_CMD(0xFF, 0x20),
+
+ _INIT_DCS_CMD(0xB0, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x24, 0x00, 0x38, 0x00, 0x4C, 0x00, 0x5E, 0x00, 0x6F, 0x00, 0x7E),
+ _INIT_DCS_CMD(0xB1, 0x00, 0x8C, 0x00, 0xBE, 0x00, 0xE5, 0x01, 0x27, 0x01, 0x58, 0x01, 0xA8, 0x01, 0xE8, 0x01, 0xEA),
+ _INIT_DCS_CMD(0xB2, 0x02, 0x28, 0x02, 0x71, 0x02, 0x9E, 0x02, 0xDA, 0x03, 0x00, 0x03, 0x31, 0x03, 0x40, 0x03, 0x51),
+ _INIT_DCS_CMD(0xB3, 0x03, 0x62, 0x03, 0x75, 0x03, 0x89, 0x03, 0x9C, 0x03, 0xAA, 0x03, 0xB2),
+
+ _INIT_DCS_CMD(0xB4, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x27, 0x00, 0x3D, 0x00, 0x52, 0x00, 0x64, 0x00, 0x75, 0x00, 0x84),
+ _INIT_DCS_CMD(0xB5, 0x00, 0x93, 0x00, 0xC5, 0x00, 0xEC, 0x01, 0x2C, 0x01, 0x5D, 0x01, 0xAC, 0x01, 0xEC, 0x01, 0xEE),
+ _INIT_DCS_CMD(0xB6, 0x02, 0x2B, 0x02, 0x73, 0x02, 0xA0, 0x02, 0xDB, 0x03, 0x01, 0x03, 0x31, 0x03, 0x41, 0x03, 0x51),
+ _INIT_DCS_CMD(0xB7, 0x03, 0x63, 0x03, 0x75, 0x03, 0x89, 0x03, 0x9C, 0x03, 0xAA, 0x03, 0xB2),
+
+ _INIT_DCS_CMD(0xB8, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x2A, 0x00, 0x40, 0x00, 0x56, 0x00, 0x68, 0x00, 0x7A, 0x00, 0x89),
+ _INIT_DCS_CMD(0xB9, 0x00, 0x98, 0x00, 0xC9, 0x00, 0xF1, 0x01, 0x30, 0x01, 0x61, 0x01, 0xB0, 0x01, 0xEF, 0x01, 0xF1),
+ _INIT_DCS_CMD(0xBA, 0x02, 0x2E, 0x02, 0x76, 0x02, 0xA3, 0x02, 0xDD, 0x03, 0x02, 0x03, 0x32, 0x03, 0x42, 0x03, 0x53),
+ _INIT_DCS_CMD(0xBB, 0x03, 0x66, 0x03, 0x75, 0x03, 0x89, 0x03, 0x9C, 0x03, 0xAA, 0x03, 0xB2),
+
+ _INIT_DCS_CMD(0xFF, 0x21),
+ _INIT_DCS_CMD(0xB0, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x24, 0x00, 0x38, 0x00, 0x4C, 0x00, 0x5E, 0x00, 0x6F, 0x00, 0x7E),
+ _INIT_DCS_CMD(0xB1, 0x00, 0x8C, 0x00, 0xBE, 0x00, 0xE5, 0x01, 0x27, 0x01, 0x58, 0x01, 0xA8, 0x01, 0xE8, 0x01, 0xEA),
+ _INIT_DCS_CMD(0xB2, 0x02, 0x28, 0x02, 0x71, 0x02, 0x9E, 0x02, 0xDA, 0x03, 0x00, 0x03, 0x31, 0x03, 0x40, 0x03, 0x51),
+ _INIT_DCS_CMD(0xB3, 0x03, 0x62, 0x03, 0x77, 0x03, 0x90, 0x03, 0xAC, 0x03, 0xCA, 0x03, 0xDA),
+
+ _INIT_DCS_CMD(0xB4, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x27, 0x00, 0x3D, 0x00, 0x52, 0x00, 0x64, 0x00, 0x75, 0x00, 0x84),
+ _INIT_DCS_CMD(0xB5, 0x00, 0x93, 0x00, 0xC5, 0x00, 0xEC, 0x01, 0x2C, 0x01, 0x5D, 0x01, 0xAC, 0x01, 0xEC, 0x01, 0xEE),
+ _INIT_DCS_CMD(0xB6, 0x02, 0x2B, 0x02, 0x73, 0x02, 0xA0, 0x02, 0xDB, 0x03, 0x01, 0x03, 0x31, 0x03, 0x41, 0x03, 0x51),
+ _INIT_DCS_CMD(0xB7, 0x03, 0x63, 0x03, 0x77, 0x03, 0x90, 0x03, 0xAC, 0x03, 0xCA, 0x03, 0xDA),
+
+ _INIT_DCS_CMD(0xB8, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x2A, 0x00, 0x40, 0x00, 0x56, 0x00, 0x68, 0x00, 0x7A, 0x00, 0x89),
+ _INIT_DCS_CMD(0xB9, 0x00, 0x98, 0x00, 0xC9, 0x00, 0xF1, 0x01, 0x30, 0x01, 0x61, 0x01, 0xB0, 0x01, 0xEF, 0x01, 0xF1),
+ _INIT_DCS_CMD(0xBA, 0x02, 0x2E, 0x02, 0x76, 0x02, 0xA3, 0x02, 0xDD, 0x03, 0x02, 0x03, 0x32, 0x03, 0x42, 0x03, 0x53),
+ _INIT_DCS_CMD(0xBB, 0x03, 0x66, 0x03, 0x77, 0x03, 0x90, 0x03, 0xAC, 0x03, 0xCA, 0x03, 0xDA),
+
_INIT_DCS_CMD(0xFF, 0xF0),
_INIT_DCS_CMD(0xFB, 0x01),
_INIT_DCS_CMD(0x3A, 0x08),
- _INIT_DCS_CMD(0xFF, 0xD0),
- _INIT_DCS_CMD(0xFB, 0x01),
- _INIT_DCS_CMD(0x00, 0x33),
- _INIT_DCS_CMD(0x08, 0x01),
- _INIT_DCS_CMD(0x09, 0xBF),
- _INIT_DCS_CMD(0x2F, 0x33),
- _INIT_DCS_CMD(0xFF, 0x23),
- _INIT_DCS_CMD(0xFB, 0x01),
- _INIT_DCS_CMD(0x00, 0x80),
- _INIT_DCS_CMD(0x07, 0x00),
- _INIT_DCS_CMD(0xFF, 0x20),
- _INIT_DCS_CMD(0xFB, 0x01),
- _INIT_DCS_CMD(0x30, 0x00),
- _INIT_DCS_CMD(0xFF, 0x24),
- _INIT_DCS_CMD(0x5C, 0x88),
- _INIT_DCS_CMD(0x5D, 0x08),
+
_INIT_DCS_CMD(0xFF, 0x10),
_INIT_DCS_CMD(0xB9, 0x01),
+
_INIT_DCS_CMD(0xFF, 0x20),
+
_INIT_DCS_CMD(0x18, 0x40),
_INIT_DCS_CMD(0xFF, 0x10),
+
_INIT_DCS_CMD(0xB9, 0x02),
_INIT_DCS_CMD(0xFF, 0x10),
+
_INIT_DCS_CMD(0xFB, 0x01),
- _INIT_DCS_CMD(0xBB, 0x13),
- _INIT_DCS_CMD(0x3B, 0x03, 0x96, 0x1A, 0x04, 0x04),
+ _INIT_DCS_CMD(0xB0, 0x01),
_INIT_DCS_CMD(0x35, 0x00),
- _INIT_DCS_CMD(0x51, 0x0F, 0xFF),
- _INIT_DCS_CMD(0x53, 0x24),
+ _INIT_DCS_CMD(0x3B, 0x03, 0xAE, 0x1A, 0x04, 0x04),
_INIT_DELAY_CMD(100),
_INIT_DCS_CMD(0x11),
_INIT_DELAY_CMD(200),
@@ -780,7 +854,6 @@ static const struct panel_init_cmd inx_hj110iz_init_cmd[] = {
};
static const struct panel_init_cmd boe_init_cmd[] = {
- _INIT_DELAY_CMD(24),
_INIT_DCS_CMD(0xB0, 0x05),
_INIT_DCS_CMD(0xB1, 0xE5),
_INIT_DCS_CMD(0xB3, 0x52),
@@ -1366,6 +1439,10 @@ static int boe_panel_prepare(struct drm_panel *panel)
usleep_range(10000, 11000);
+ if (boe->desc->lp11_before_reset) {
+ mipi_dsi_dcs_nop(boe->dsi);
+ usleep_range(1000, 2000);
+ }
gpiod_set_value(boe->enable_gpio, 1);
usleep_range(1000, 2000);
gpiod_set_value(boe->enable_gpio, 0);
@@ -1431,15 +1508,15 @@ static const struct panel_desc boe_tv110c9m_desc = {
};
static const struct drm_display_mode inx_hj110iz_default_mode = {
- .clock = 166594,
+ .clock = 168432,
.hdisplay = 1200,
.hsync_start = 1200 + 40,
.hsync_end = 1200 + 40 + 8,
.htotal = 1200 + 40 + 8 + 28,
.vdisplay = 2000,
.vsync_start = 2000 + 26,
- .vsync_end = 2000 + 26 + 1,
- .vtotal = 2000 + 26 + 1 + 149,
+ .vsync_end = 2000 + 26 + 2,
+ .vtotal = 2000 + 26 + 2 + 172,
.type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
};
@@ -1592,6 +1669,7 @@ static const struct panel_desc boe_tv105wum_nw0_desc = {
.mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
MIPI_DSI_MODE_LPM,
.init_cmds = boe_init_cmd,
+ .lp11_before_reset = true,
};
static const struct drm_display_mode starry_qfh032011_53g_default_mode = {
diff --git a/drivers/gpu/drm/panel/panel-novatek-nt36523.c b/drivers/gpu/drm/panel/panel-novatek-nt36523.c
index d30dbbfb67b1..c3befa7f253d 100644
--- a/drivers/gpu/drm/panel/panel-novatek-nt36523.c
+++ b/drivers/gpu/drm/panel/panel-novatek-nt36523.c
@@ -5,6 +5,7 @@
* Copyright (c) 2022, 2023 Jianhua Lu <lujianhua000@gmail.com>
*/
+#include <linux/backlight.h>
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/module.h>
@@ -12,6 +13,8 @@
#include <linux/of_graph.h>
#include <linux/regulator/consumer.h>
+#include <video/mipi_display.h>
+
#include <drm/drm_connector.h>
#include <drm/drm_crtc.h>
#include <drm/drm_mipi_dsi.h>
@@ -30,6 +33,7 @@ struct panel_info {
struct drm_panel panel;
struct mipi_dsi_device *dsi[2];
const struct panel_desc *desc;
+ enum drm_panel_orientation orientation;
struct gpio_desc *reset_gpio;
struct backlight_device *backlight;
@@ -53,6 +57,7 @@ struct panel_desc {
int (*init_sequence)(struct panel_info *pinfo);
bool is_dual_dsi;
+ bool has_dcs_backlight;
};
static inline struct panel_info *to_panel_info(struct drm_panel *panel)
@@ -478,6 +483,456 @@ static int elish_csot_init_sequence(struct panel_info *pinfo)
return 0;
}
+static int j606f_boe_init_sequence(struct panel_info *pinfo)
+{
+ struct mipi_dsi_device *dsi = pinfo->dsi[0];
+ struct device *dev = &dsi->dev;
+ int ret;
+
+ mipi_dsi_dcs_write_seq(dsi, 0xff, 0x20);
+ mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
+ mipi_dsi_dcs_write_seq(dsi, 0x05, 0xd9);
+ mipi_dsi_dcs_write_seq(dsi, 0x07, 0x78);
+ mipi_dsi_dcs_write_seq(dsi, 0x08, 0x5a);
+ mipi_dsi_dcs_write_seq(dsi, 0x0d, 0x63);
+ mipi_dsi_dcs_write_seq(dsi, 0x0e, 0x91);
+ mipi_dsi_dcs_write_seq(dsi, 0x0f, 0x73);
+ mipi_dsi_dcs_write_seq(dsi, 0x95, 0xeb);
+ mipi_dsi_dcs_write_seq(dsi, 0x96, 0xeb);
+ mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_SET_PARTIAL_ROWS, 0x11);
+ mipi_dsi_dcs_write_seq(dsi, 0x6d, 0x66);
+ mipi_dsi_dcs_write_seq(dsi, 0x75, 0xa2);
+ mipi_dsi_dcs_write_seq(dsi, 0x77, 0xb3);
+ mipi_dsi_dcs_write_seq(dsi, 0xb0, 0x00, 0x08, 0x00, 0x23, 0x00, 0x4d, 0x00, 0x6d, 0x00,
+ 0x89, 0x00, 0xa1, 0x00, 0xb6, 0x00, 0xc9);
+ mipi_dsi_dcs_write_seq(dsi, 0xb1, 0x00, 0xda, 0x01, 0x13, 0x01, 0x3c, 0x01, 0x7e, 0x01,
+ 0xab, 0x01, 0xf7, 0x02, 0x2f, 0x02, 0x31);
+ mipi_dsi_dcs_write_seq(dsi, 0xb2, 0x02, 0x67, 0x02, 0xa6, 0x02, 0xd1, 0x03, 0x08, 0x03,
+ 0x2e, 0x03, 0x5b, 0x03, 0x6b, 0x03, 0x7b);
+ mipi_dsi_dcs_write_seq(dsi, 0xb3, 0x03, 0x8e, 0x03, 0xa2, 0x03, 0xb7, 0x03, 0xe7, 0x03,
+ 0xfd, 0x03, 0xff);
+ mipi_dsi_dcs_write_seq(dsi, 0xb4, 0x00, 0x08, 0x00, 0x23, 0x00, 0x4d, 0x00, 0x6d, 0x00,
+ 0x89, 0x00, 0xa1, 0x00, 0xb6, 0x00, 0xc9);
+ mipi_dsi_dcs_write_seq(dsi, 0xb5, 0x00, 0xda, 0x01, 0x13, 0x01, 0x3c, 0x01, 0x7e, 0x01,
+ 0xab, 0x01, 0xf7, 0x02, 0x2f, 0x02, 0x31);
+ mipi_dsi_dcs_write_seq(dsi, 0xb6, 0x02, 0x67, 0x02, 0xa6, 0x02, 0xd1, 0x03, 0x08, 0x03,
+ 0x2e, 0x03, 0x5b, 0x03, 0x6b, 0x03, 0x7b);
+ mipi_dsi_dcs_write_seq(dsi, 0xb7, 0x03, 0x8e, 0x03, 0xa2, 0x03, 0xb7, 0x03, 0xe7, 0x03,
+ 0xfd, 0x03, 0xff);
+ mipi_dsi_dcs_write_seq(dsi, 0xb8, 0x00, 0x08, 0x00, 0x23, 0x00, 0x4d, 0x00, 0x6d, 0x00,
+ 0x89, 0x00, 0xa1, 0x00, 0xb6, 0x00, 0xc9);
+ mipi_dsi_dcs_write_seq(dsi, 0xb9, 0x00, 0xda, 0x01, 0x13, 0x01, 0x3c, 0x01, 0x7e, 0x01,
+ 0xab, 0x01, 0xf7, 0x02, 0x2f, 0x02, 0x31);
+ mipi_dsi_dcs_write_seq(dsi, 0xba, 0x02, 0x67, 0x02, 0xa6, 0x02, 0xd1, 0x03, 0x08, 0x03,
+ 0x2e, 0x03, 0x5b, 0x03, 0x6b, 0x03, 0x7b);
+ mipi_dsi_dcs_write_seq(dsi, 0xbb, 0x03, 0x8e, 0x03, 0xa2, 0x03, 0xb7, 0x03, 0xe7, 0x03,
+ 0xfd, 0x03, 0xff);
+ mipi_dsi_dcs_write_seq(dsi, 0xff, 0x21);
+ mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
+ mipi_dsi_dcs_write_seq(dsi, 0xb0, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x45, 0x00, 0x65, 0x00,
+ 0x81, 0x00, 0x99, 0x00, 0xae, 0x00, 0xc1);
+ mipi_dsi_dcs_write_seq(dsi, 0xb1, 0x00, 0xd2, 0x01, 0x0b, 0x01, 0x34, 0x01, 0x76, 0x01,
+ 0xa3, 0x01, 0xef, 0x02, 0x27, 0x02, 0x29);
+ mipi_dsi_dcs_write_seq(dsi, 0xb2, 0x02, 0x5f, 0x02, 0x9e, 0x02, 0xc9, 0x03, 0x00, 0x03,
+ 0x26, 0x03, 0x53, 0x03, 0x63, 0x03, 0x73);
+ mipi_dsi_dcs_write_seq(dsi, 0xb3, 0x03, 0x86, 0x03, 0x9a, 0x03, 0xaf, 0x03, 0xdf, 0x03,
+ 0xf5, 0x03, 0xf7);
+ mipi_dsi_dcs_write_seq(dsi, 0xb4, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x45, 0x00, 0x65, 0x00,
+ 0x81, 0x00, 0x99, 0x00, 0xae, 0x00, 0xc1);
+ mipi_dsi_dcs_write_seq(dsi, 0xb5, 0x00, 0xd2, 0x01, 0x0b, 0x01, 0x34, 0x01, 0x76, 0x01,
+ 0xa3, 0x01, 0xef, 0x02, 0x27, 0x02, 0x29);
+ mipi_dsi_dcs_write_seq(dsi, 0xb6, 0x02, 0x5f, 0x02, 0x9e, 0x02, 0xc9, 0x03, 0x00, 0x03,
+ 0x26, 0x03, 0x53, 0x03, 0x63, 0x03, 0x73);
+ mipi_dsi_dcs_write_seq(dsi, 0xb7, 0x03, 0x86, 0x03, 0x9a, 0x03, 0xaf, 0x03, 0xdf, 0x03,
+ 0xf5, 0x03, 0xf7);
+ mipi_dsi_dcs_write_seq(dsi, 0xb8, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x45, 0x00, 0x65, 0x00,
+ 0x81, 0x00, 0x99, 0x00, 0xae, 0x00, 0xc1);
+ mipi_dsi_dcs_write_seq(dsi, 0xb9, 0x00, 0xd2, 0x01, 0x0b, 0x01, 0x34, 0x01, 0x76, 0x01,
+ 0xa3, 0x01, 0xef, 0x02, 0x27, 0x02, 0x29);
+ mipi_dsi_dcs_write_seq(dsi, 0xba, 0x02, 0x5f, 0x02, 0x9e, 0x02, 0xc9, 0x03, 0x00, 0x03,
+ 0x26, 0x03, 0x53, 0x03, 0x63, 0x03, 0x73);
+ mipi_dsi_dcs_write_seq(dsi, 0xbb, 0x03, 0x86, 0x03, 0x9a, 0x03, 0xaf, 0x03, 0xdf, 0x03,
+ 0xf5, 0x03, 0xf7);
+ mipi_dsi_dcs_write_seq(dsi, 0xff, 0x23);
+ mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
+ mipi_dsi_dcs_write_seq(dsi, 0x00, 0x80);
+ mipi_dsi_dcs_write_seq(dsi, 0x07, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, 0x11, 0x01);
+ mipi_dsi_dcs_write_seq(dsi, 0x12, 0x77);
+ mipi_dsi_dcs_write_seq(dsi, 0x15, 0x07);
+ mipi_dsi_dcs_write_seq(dsi, 0x16, 0x07);
+ mipi_dsi_dcs_write_seq(dsi, 0xff, 0x24);
+ mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
+ mipi_dsi_dcs_write_seq(dsi, 0x00, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, 0x01, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, 0x02, 0x1c);
+ mipi_dsi_dcs_write_seq(dsi, 0x03, 0x1c);
+ mipi_dsi_dcs_write_seq(dsi, 0x04, 0x1d);
+ mipi_dsi_dcs_write_seq(dsi, 0x05, 0x1d);
+ mipi_dsi_dcs_write_seq(dsi, 0x06, 0x04);
+ mipi_dsi_dcs_write_seq(dsi, 0x07, 0x04);
+ mipi_dsi_dcs_write_seq(dsi, 0x08, 0x0f);
+ mipi_dsi_dcs_write_seq(dsi, 0x09, 0x0f);
+ mipi_dsi_dcs_write_seq(dsi, 0x0a, 0x0e);
+ mipi_dsi_dcs_write_seq(dsi, 0x0b, 0x0e);
+ mipi_dsi_dcs_write_seq(dsi, 0x0c, 0x0d);
+ mipi_dsi_dcs_write_seq(dsi, 0x0d, 0x0d);
+ mipi_dsi_dcs_write_seq(dsi, 0x0e, 0x0c);
+ mipi_dsi_dcs_write_seq(dsi, 0x0f, 0x0c);
+ mipi_dsi_dcs_write_seq(dsi, 0x10, 0x08);
+ mipi_dsi_dcs_write_seq(dsi, 0x11, 0x08);
+ mipi_dsi_dcs_write_seq(dsi, 0x12, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, 0x13, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, 0x14, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, 0x15, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, 0x16, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, 0x17, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, 0x18, 0x1c);
+ mipi_dsi_dcs_write_seq(dsi, 0x19, 0x1c);
+ mipi_dsi_dcs_write_seq(dsi, 0x1a, 0x1d);
+ mipi_dsi_dcs_write_seq(dsi, 0x1b, 0x1d);
+ mipi_dsi_dcs_write_seq(dsi, 0x1c, 0x04);
+ mipi_dsi_dcs_write_seq(dsi, 0x1d, 0x04);
+ mipi_dsi_dcs_write_seq(dsi, 0x1e, 0x0f);
+ mipi_dsi_dcs_write_seq(dsi, 0x1f, 0x0f);
+ mipi_dsi_dcs_write_seq(dsi, 0x20, 0x0e);
+ mipi_dsi_dcs_write_seq(dsi, 0x21, 0x0e);
+ mipi_dsi_dcs_write_seq(dsi, 0x22, 0x0d);
+ mipi_dsi_dcs_write_seq(dsi, 0x23, 0x0d);
+ mipi_dsi_dcs_write_seq(dsi, 0x24, 0x0c);
+ mipi_dsi_dcs_write_seq(dsi, 0x25, 0x0c);
+ mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_SET_GAMMA_CURVE, 0x08);
+ mipi_dsi_dcs_write_seq(dsi, 0x27, 0x08);
+ mipi_dsi_dcs_write_seq(dsi, 0x28, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, 0x29, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, 0x2a, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, 0x2b, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_WRITE_LUT, 0x20);
+ mipi_dsi_dcs_write_seq(dsi, 0x2f, 0x0a);
+ mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_SET_PARTIAL_ROWS, 0x44);
+ mipi_dsi_dcs_write_seq(dsi, 0x33, 0x0c);
+ mipi_dsi_dcs_write_seq(dsi, 0x34, 0x32);
+ mipi_dsi_dcs_write_seq(dsi, 0x37, 0x44);
+ mipi_dsi_dcs_write_seq(dsi, 0x38, 0x40);
+ mipi_dsi_dcs_write_seq(dsi, 0x39, 0x00);
+
+ ret = mipi_dsi_dcs_set_pixel_format(dsi, 0x9a);
+ if (ret < 0) {
+ dev_err(dev, "Failed to set pixel format: %d\n", ret);
+ return ret;
+ }
+
+ mipi_dsi_dcs_write_seq(dsi, 0x3b, 0xa0);
+ mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_SET_3D_CONTROL, 0x42);
+ mipi_dsi_dcs_write_seq(dsi, 0x3f, 0x06);
+ mipi_dsi_dcs_write_seq(dsi, 0x43, 0x06);
+ mipi_dsi_dcs_write_seq(dsi, 0x47, 0x66);
+ mipi_dsi_dcs_write_seq(dsi, 0x4a, 0x9a);
+ mipi_dsi_dcs_write_seq(dsi, 0x4b, 0xa0);
+ mipi_dsi_dcs_write_seq(dsi, 0x4c, 0x91);
+ mipi_dsi_dcs_write_seq(dsi, 0x4d, 0x21);
+ mipi_dsi_dcs_write_seq(dsi, 0x4e, 0x43);
+
+ ret = mipi_dsi_dcs_set_display_brightness(dsi, 18);
+ if (ret < 0) {
+ dev_err(dev, "Failed to set display brightness: %d\n", ret);
+ return ret;
+ }
+
+ mipi_dsi_dcs_write_seq(dsi, 0x52, 0x34);
+ mipi_dsi_dcs_write_seq(dsi, 0x55, 0x82, 0x02);
+ mipi_dsi_dcs_write_seq(dsi, 0x56, 0x04);
+ mipi_dsi_dcs_write_seq(dsi, 0x58, 0x21);
+ mipi_dsi_dcs_write_seq(dsi, 0x59, 0x30);
+ mipi_dsi_dcs_write_seq(dsi, 0x5a, 0xba);
+ mipi_dsi_dcs_write_seq(dsi, 0x5b, 0xa0);
+ mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_SET_CABC_MIN_BRIGHTNESS, 0x00, 0x06);
+ mipi_dsi_dcs_write_seq(dsi, 0x5f, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, 0x65, 0x82);
+ mipi_dsi_dcs_write_seq(dsi, 0x7e, 0x20);
+ mipi_dsi_dcs_write_seq(dsi, 0x7f, 0x3c);
+ mipi_dsi_dcs_write_seq(dsi, 0x82, 0x04);
+ mipi_dsi_dcs_write_seq(dsi, 0x97, 0xc0);
+ mipi_dsi_dcs_write_seq(dsi, 0xb6,
+ 0x05, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x05, 0x00, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, 0x92, 0xc4);
+ mipi_dsi_dcs_write_seq(dsi, 0x93, 0x1a);
+ mipi_dsi_dcs_write_seq(dsi, 0x94, 0x5f);
+ mipi_dsi_dcs_write_seq(dsi, 0xd7, 0x55);
+ mipi_dsi_dcs_write_seq(dsi, 0xda, 0x0a);
+ mipi_dsi_dcs_write_seq(dsi, 0xde, 0x08);
+ mipi_dsi_dcs_write_seq(dsi, 0xdb, 0x05);
+ mipi_dsi_dcs_write_seq(dsi, 0xdc, 0xc4);
+ mipi_dsi_dcs_write_seq(dsi, 0xdd, 0x22);
+ mipi_dsi_dcs_write_seq(dsi, 0xdf, 0x05);
+ mipi_dsi_dcs_write_seq(dsi, 0xe0, 0xc4);
+ mipi_dsi_dcs_write_seq(dsi, 0xe1, 0x05);
+ mipi_dsi_dcs_write_seq(dsi, 0xe2, 0xc4);
+ mipi_dsi_dcs_write_seq(dsi, 0xe3, 0x05);
+ mipi_dsi_dcs_write_seq(dsi, 0xe4, 0xc4);
+ mipi_dsi_dcs_write_seq(dsi, 0xe5, 0x05);
+ mipi_dsi_dcs_write_seq(dsi, 0xe6, 0xc4);
+ mipi_dsi_dcs_write_seq(dsi, 0x5c, 0x88);
+ mipi_dsi_dcs_write_seq(dsi, 0x5d, 0x08);
+ mipi_dsi_dcs_write_seq(dsi, 0x8d, 0x88);
+ mipi_dsi_dcs_write_seq(dsi, 0x8e, 0x08);
+ mipi_dsi_dcs_write_seq(dsi, 0xb5, 0x90);
+ mipi_dsi_dcs_write_seq(dsi, 0xff, 0x25);
+ mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
+ mipi_dsi_dcs_write_seq(dsi, 0x05, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, 0x19, 0x07);
+ mipi_dsi_dcs_write_seq(dsi, 0x1f, 0xba);
+ mipi_dsi_dcs_write_seq(dsi, 0x20, 0xa0);
+ mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_SET_GAMMA_CURVE, 0xba);
+ mipi_dsi_dcs_write_seq(dsi, 0x27, 0xa0);
+ mipi_dsi_dcs_write_seq(dsi, 0x33, 0xba);
+ mipi_dsi_dcs_write_seq(dsi, 0x34, 0xa0);
+ mipi_dsi_dcs_write_seq(dsi, 0x3f, 0xe0);
+ mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_SET_VSYNC_TIMING, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, 0x44, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_GET_SCANLINE, 0x40);
+ mipi_dsi_dcs_write_seq(dsi, 0x48, 0xba);
+ mipi_dsi_dcs_write_seq(dsi, 0x49, 0xa0);
+ mipi_dsi_dcs_write_seq(dsi, 0x5b, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, 0x5c, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, 0x5d, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_SET_CABC_MIN_BRIGHTNESS, 0xd0);
+ mipi_dsi_dcs_write_seq(dsi, 0x61, 0xba);
+ mipi_dsi_dcs_write_seq(dsi, 0x62, 0xa0);
+ mipi_dsi_dcs_write_seq(dsi, 0xf1, 0x10);
+ mipi_dsi_dcs_write_seq(dsi, 0xff, 0x2a);
+ mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
+ mipi_dsi_dcs_write_seq(dsi, 0x64, 0x16);
+ mipi_dsi_dcs_write_seq(dsi, 0x67, 0x16);
+ mipi_dsi_dcs_write_seq(dsi, 0x6a, 0x16);
+ mipi_dsi_dcs_write_seq(dsi, 0x70, 0x30);
+ mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_READ_PPS_START, 0xf3);
+ mipi_dsi_dcs_write_seq(dsi, 0xa3, 0xff);
+ mipi_dsi_dcs_write_seq(dsi, 0xa4, 0xff);
+ mipi_dsi_dcs_write_seq(dsi, 0xa5, 0xff);
+ mipi_dsi_dcs_write_seq(dsi, 0xd6, 0x08);
+ mipi_dsi_dcs_write_seq(dsi, 0xff, 0x26);
+ mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
+ mipi_dsi_dcs_write_seq(dsi, 0x00, 0xa1);
+ mipi_dsi_dcs_write_seq(dsi, 0x0a, 0xf2);
+ mipi_dsi_dcs_write_seq(dsi, 0x04, 0x28);
+ mipi_dsi_dcs_write_seq(dsi, 0x06, 0x30);
+ mipi_dsi_dcs_write_seq(dsi, 0x0c, 0x13);
+ mipi_dsi_dcs_write_seq(dsi, 0x0d, 0x0a);
+ mipi_dsi_dcs_write_seq(dsi, 0x0f, 0x0a);
+ mipi_dsi_dcs_write_seq(dsi, 0x11, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, 0x12, 0x50);
+ mipi_dsi_dcs_write_seq(dsi, 0x13, 0x51);
+ mipi_dsi_dcs_write_seq(dsi, 0x14, 0x65);
+ mipi_dsi_dcs_write_seq(dsi, 0x15, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, 0x16, 0x10);
+ mipi_dsi_dcs_write_seq(dsi, 0x17, 0xa0);
+ mipi_dsi_dcs_write_seq(dsi, 0x18, 0x86);
+ mipi_dsi_dcs_write_seq(dsi, 0x19, 0x11);
+ mipi_dsi_dcs_write_seq(dsi, 0x1a, 0x7b);
+ mipi_dsi_dcs_write_seq(dsi, 0x1b, 0x10);
+ mipi_dsi_dcs_write_seq(dsi, 0x1c, 0xbb);
+ mipi_dsi_dcs_write_seq(dsi, 0x22, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, 0x23, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, 0x2a, 0x11);
+ mipi_dsi_dcs_write_seq(dsi, 0x2b, 0x7b);
+ mipi_dsi_dcs_write_seq(dsi, 0x1d, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, 0x1e, 0xc3);
+ mipi_dsi_dcs_write_seq(dsi, 0x1f, 0xc3);
+ mipi_dsi_dcs_write_seq(dsi, 0x24, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, 0x25, 0xc3);
+ mipi_dsi_dcs_write_seq(dsi, 0x2f, 0x05);
+ mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_SET_PARTIAL_ROWS, 0xc3);
+ mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_SET_PARTIAL_COLUMNS, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, 0x32, 0xc3);
+ mipi_dsi_dcs_write_seq(dsi, 0x39, 0x00);
+
+ ret = mipi_dsi_dcs_set_pixel_format(dsi, 0xc3);
+ if (ret < 0) {
+ dev_err(dev, "Failed to set pixel format: %d\n", ret);
+ return ret;
+ }
+
+ mipi_dsi_dcs_write_seq(dsi, 0x20, 0x01);
+ mipi_dsi_dcs_write_seq(dsi, 0x33, 0x11);
+ mipi_dsi_dcs_write_seq(dsi, 0x34, 0x78);
+ mipi_dsi_dcs_write_seq(dsi, 0x35, 0x16);
+ mipi_dsi_dcs_write_seq(dsi, 0xc8, 0x04);
+ mipi_dsi_dcs_write_seq(dsi, 0xc9, 0x82);
+ mipi_dsi_dcs_write_seq(dsi, 0xca, 0x4e);
+ mipi_dsi_dcs_write_seq(dsi, 0xcb, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_READ_PPS_CONTINUE, 0x4c);
+ mipi_dsi_dcs_write_seq(dsi, 0xaa, 0x47);
+ mipi_dsi_dcs_write_seq(dsi, 0xff, 0x27);
+ mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
+ mipi_dsi_dcs_write_seq(dsi, 0x56, 0x06);
+ mipi_dsi_dcs_write_seq(dsi, 0x58, 0x80);
+ mipi_dsi_dcs_write_seq(dsi, 0x59, 0x53);
+ mipi_dsi_dcs_write_seq(dsi, 0x5a, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, 0x5b, 0x14);
+ mipi_dsi_dcs_write_seq(dsi, 0x5c, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, 0x5d, 0x01);
+ mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_SET_CABC_MIN_BRIGHTNESS, 0x20);
+ mipi_dsi_dcs_write_seq(dsi, 0x5f, 0x10);
+ mipi_dsi_dcs_write_seq(dsi, 0x60, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, 0x61, 0x1d);
+ mipi_dsi_dcs_write_seq(dsi, 0x62, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, 0x63, 0x01);
+ mipi_dsi_dcs_write_seq(dsi, 0x64, 0x24);
+ mipi_dsi_dcs_write_seq(dsi, 0x65, 0x1c);
+ mipi_dsi_dcs_write_seq(dsi, 0x66, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, 0x67, 0x01);
+ mipi_dsi_dcs_write_seq(dsi, 0x68, 0x25);
+ mipi_dsi_dcs_write_seq(dsi, 0x00, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, 0x78, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, 0xc3, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, 0xd1, 0x24);
+ mipi_dsi_dcs_write_seq(dsi, 0xd2, 0x30);
+ mipi_dsi_dcs_write_seq(dsi, 0xff, 0x2a);
+ mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
+ mipi_dsi_dcs_write_seq(dsi, 0x22, 0x2f);
+ mipi_dsi_dcs_write_seq(dsi, 0x23, 0x08);
+ mipi_dsi_dcs_write_seq(dsi, 0x24, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, 0x25, 0xc3);
+ mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_SET_GAMMA_CURVE, 0xf8);
+ mipi_dsi_dcs_write_seq(dsi, 0x27, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, 0x28, 0x1a);
+ mipi_dsi_dcs_write_seq(dsi, 0x29, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, 0x2a, 0x1a);
+ mipi_dsi_dcs_write_seq(dsi, 0x2b, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_WRITE_LUT, 0x1a);
+ mipi_dsi_dcs_write_seq(dsi, 0xff, 0xe0);
+ mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
+ mipi_dsi_dcs_write_seq(dsi, 0x14, 0x60);
+ mipi_dsi_dcs_write_seq(dsi, 0x16, 0xc0);
+ mipi_dsi_dcs_write_seq(dsi, 0xff, 0xf0);
+ mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
+
+ ret = mipi_dsi_dcs_set_pixel_format(dsi, 0x08);
+ if (ret < 0) {
+ dev_err(dev, "Failed to set pixel format: %d\n", ret);
+ return ret;
+ }
+
+ mipi_dsi_dcs_write_seq(dsi, 0xff, 0x24);
+ mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
+
+ ret = mipi_dsi_dcs_set_pixel_format(dsi, 0x5d);
+ if (ret < 0) {
+ dev_err(dev, "Failed to set pixel format: %d\n", ret);
+ return ret;
+ }
+
+ mipi_dsi_dcs_write_seq(dsi, 0x3b, 0x60);
+ mipi_dsi_dcs_write_seq(dsi, 0x4a, 0x5d);
+ mipi_dsi_dcs_write_seq(dsi, 0x4b, 0x60);
+ mipi_dsi_dcs_write_seq(dsi, 0x5a, 0x70);
+ mipi_dsi_dcs_write_seq(dsi, 0x5b, 0x60);
+ mipi_dsi_dcs_write_seq(dsi, 0x91, 0x44);
+ mipi_dsi_dcs_write_seq(dsi, 0x92, 0x75);
+ mipi_dsi_dcs_write_seq(dsi, 0xdb, 0x05);
+ mipi_dsi_dcs_write_seq(dsi, 0xdc, 0x75);
+ mipi_dsi_dcs_write_seq(dsi, 0xdd, 0x22);
+ mipi_dsi_dcs_write_seq(dsi, 0xdf, 0x05);
+ mipi_dsi_dcs_write_seq(dsi, 0xe0, 0x75);
+ mipi_dsi_dcs_write_seq(dsi, 0xe1, 0x05);
+ mipi_dsi_dcs_write_seq(dsi, 0xe2, 0x75);
+ mipi_dsi_dcs_write_seq(dsi, 0xe3, 0x05);
+ mipi_dsi_dcs_write_seq(dsi, 0xe4, 0x75);
+ mipi_dsi_dcs_write_seq(dsi, 0xe5, 0x05);
+ mipi_dsi_dcs_write_seq(dsi, 0xe6, 0x75);
+ mipi_dsi_dcs_write_seq(dsi, 0x5c, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, 0x5d, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, 0x8d, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, 0x8e, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, 0xff, 0x25);
+ mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
+ mipi_dsi_dcs_write_seq(dsi, 0x1f, 0x70);
+ mipi_dsi_dcs_write_seq(dsi, 0x20, 0x60);
+ mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_SET_GAMMA_CURVE, 0x70);
+ mipi_dsi_dcs_write_seq(dsi, 0x27, 0x60);
+ mipi_dsi_dcs_write_seq(dsi, 0x33, 0x70);
+ mipi_dsi_dcs_write_seq(dsi, 0x34, 0x60);
+ mipi_dsi_dcs_write_seq(dsi, 0x48, 0x70);
+ mipi_dsi_dcs_write_seq(dsi, 0x49, 0x60);
+ mipi_dsi_dcs_write_seq(dsi, 0x5b, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, 0x61, 0x70);
+ mipi_dsi_dcs_write_seq(dsi, 0x62, 0x60);
+ mipi_dsi_dcs_write_seq(dsi, 0xff, 0x26);
+ mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
+ mipi_dsi_dcs_write_seq(dsi, 0x02, 0x31);
+ mipi_dsi_dcs_write_seq(dsi, 0x19, 0x0a);
+ mipi_dsi_dcs_write_seq(dsi, 0x1a, 0x7f);
+ mipi_dsi_dcs_write_seq(dsi, 0x1b, 0x0a);
+ mipi_dsi_dcs_write_seq(dsi, 0x1c, 0x0c);
+ mipi_dsi_dcs_write_seq(dsi, 0x2a, 0x0a);
+ mipi_dsi_dcs_write_seq(dsi, 0x2b, 0x7f);
+ mipi_dsi_dcs_write_seq(dsi, 0x1e, 0x75);
+ mipi_dsi_dcs_write_seq(dsi, 0x1f, 0x75);
+ mipi_dsi_dcs_write_seq(dsi, 0x25, 0x75);
+ mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_SET_PARTIAL_ROWS, 0x75);
+ mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_SET_PARTIAL_COLUMNS, 0x05);
+ mipi_dsi_dcs_write_seq(dsi, 0x32, 0x8d);
+
+ ret = mipi_dsi_dcs_set_pixel_format(dsi, 0x75);
+ if (ret < 0) {
+ dev_err(dev, "Failed to set pixel format: %d\n", ret);
+ return ret;
+ }
+
+ mipi_dsi_dcs_write_seq(dsi, 0xff, 0x2a);
+ mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
+ mipi_dsi_dcs_write_seq(dsi, 0x25, 0x75);
+ mipi_dsi_dcs_write_seq(dsi, 0xff, 0x10);
+ mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
+ mipi_dsi_dcs_write_seq(dsi, 0xb9, 0x01);
+ mipi_dsi_dcs_write_seq(dsi, 0xff, 0x20);
+ mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
+ mipi_dsi_dcs_write_seq(dsi, 0x18, 0x40);
+ mipi_dsi_dcs_write_seq(dsi, 0xff, 0x10);
+ mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
+ mipi_dsi_dcs_write_seq(dsi, 0xb9, 0x02);
+
+ ret = mipi_dsi_dcs_set_tear_on(dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK);
+ if (ret < 0) {
+ dev_err(dev, "Failed to set tear on: %d\n", ret);
+ return ret;
+ }
+
+ mipi_dsi_dcs_write_seq(dsi, 0xbb, 0x13);
+ mipi_dsi_dcs_write_seq(dsi, 0x3b, 0x03, 0x5f, 0x1a, 0x04, 0x04);
+ mipi_dsi_dcs_write_seq(dsi, 0xff, 0x10);
+ usleep_range(10000, 11000);
+ mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
+
+ ret = mipi_dsi_dcs_set_display_brightness(dsi, 0);
+ if (ret < 0) {
+ dev_err(dev, "Failed to set display brightness: %d\n", ret);
+ return ret;
+ }
+
+ mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x2c);
+ mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_WRITE_POWER_SAVE, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, 0x68, 0x05, 0x01);
+
+ ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
+ if (ret < 0) {
+ dev_err(dev, "Failed to exit sleep mode: %d\n", ret);
+ return ret;
+ }
+ msleep(100);
+
+ ret = mipi_dsi_dcs_set_display_on(dsi);
+ if (ret < 0) {
+ dev_err(dev, "Failed to set display on: %d\n", ret);
+ return ret;
+ }
+ msleep(30);
+
+ return 0;
+}
+
static const struct drm_display_mode elish_boe_modes[] = {
{
/* There is only one 120 Hz timing, but it doesn't work perfectly, 104 Hz preferred */
@@ -508,6 +963,22 @@ static const struct drm_display_mode elish_csot_modes[] = {
},
};
+static const struct drm_display_mode j606f_boe_modes[] = {
+ {
+ .clock = (1200 + 58 + 2 + 60) * (2000 + 26 + 2 + 93) * 60 / 1000,
+ .hdisplay = 1200,
+ .hsync_start = 1200 + 58,
+ .hsync_end = 1200 + 58 + 2,
+ .htotal = 1200 + 58 + 2 + 60,
+ .vdisplay = 2000,
+ .vsync_start = 2000 + 26,
+ .vsync_end = 2000 + 26 + 2,
+ .vtotal = 2000 + 26 + 2 + 93,
+ .width_mm = 143,
+ .height_mm = 235,
+ },
+};
+
static const struct panel_desc elish_boe_desc = {
.modes = elish_boe_modes,
.num_modes = ARRAY_SIZE(elish_boe_modes),
@@ -544,6 +1015,20 @@ static const struct panel_desc elish_csot_desc = {
.is_dual_dsi = true,
};
+static const struct panel_desc j606f_boe_desc = {
+ .modes = j606f_boe_modes,
+ .num_modes = ARRAY_SIZE(j606f_boe_modes),
+ .width_mm = 143,
+ .height_mm = 235,
+ .bpc = 8,
+ .lanes = 4,
+ .format = MIPI_DSI_FMT_RGB888,
+ .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
+ MIPI_DSI_CLOCK_NON_CONTINUOUS | MIPI_DSI_MODE_LPM,
+ .init_sequence = j606f_boe_init_sequence,
+ .has_dcs_backlight = true,
+};
+
static void nt36523_reset(struct panel_info *pinfo)
{
gpiod_set_value_cansleep(pinfo->reset_gpio, 1);
@@ -672,13 +1157,74 @@ static int nt36523_get_modes(struct drm_panel *panel,
return pinfo->desc->num_modes;
}
+static enum drm_panel_orientation nt36523_get_orientation(struct drm_panel *panel)
+{
+ struct panel_info *pinfo = to_panel_info(panel);
+
+ return pinfo->orientation;
+}
+
static const struct drm_panel_funcs nt36523_panel_funcs = {
.disable = nt36523_disable,
.prepare = nt36523_prepare,
.unprepare = nt36523_unprepare,
.get_modes = nt36523_get_modes,
+ .get_orientation = nt36523_get_orientation,
};
+static int nt36523_bl_update_status(struct backlight_device *bl)
+{
+ struct mipi_dsi_device *dsi = bl_get_data(bl);
+ u16 brightness = backlight_get_brightness(bl);
+ int ret;
+
+ dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
+
+ ret = mipi_dsi_dcs_set_display_brightness_large(dsi, brightness);
+ if (ret < 0)
+ return ret;
+
+ dsi->mode_flags |= MIPI_DSI_MODE_LPM;
+
+ return 0;
+}
+
+static int nt36523_bl_get_brightness(struct backlight_device *bl)
+{
+ struct mipi_dsi_device *dsi = bl_get_data(bl);
+ u16 brightness;
+ int ret;
+
+ dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
+
+ ret = mipi_dsi_dcs_get_display_brightness_large(dsi, &brightness);
+ if (ret < 0)
+ return ret;
+
+ dsi->mode_flags |= MIPI_DSI_MODE_LPM;
+
+ return brightness;
+}
+
+static const struct backlight_ops nt36523_bl_ops = {
+ .update_status = nt36523_bl_update_status,
+ .get_brightness = nt36523_bl_get_brightness,
+};
+
+static struct backlight_device *nt36523_create_backlight(struct mipi_dsi_device *dsi)
+{
+ struct device *dev = &dsi->dev;
+ const struct backlight_properties props = {
+ .type = BACKLIGHT_RAW,
+ .brightness = 512,
+ .max_brightness = 4095,
+ .scale = BACKLIGHT_SCALE_NON_LINEAR,
+ };
+
+ return devm_backlight_device_register(dev, dev_name(dev), dev, dsi,
+ &nt36523_bl_ops, &props);
+}
+
static int nt36523_probe(struct mipi_dsi_device *dsi)
{
struct device *dev = &dsi->dev;
@@ -730,9 +1276,22 @@ static int nt36523_probe(struct mipi_dsi_device *dsi)
mipi_dsi_set_drvdata(dsi, pinfo);
drm_panel_init(&pinfo->panel, dev, &nt36523_panel_funcs, DRM_MODE_CONNECTOR_DSI);
- ret = drm_panel_of_backlight(&pinfo->panel);
- if (ret)
- return dev_err_probe(dev, ret, "failed to get backlight\n");
+ ret = of_drm_get_panel_orientation(dev->of_node, &pinfo->orientation);
+ if (ret < 0) {
+ dev_err(dev, "%pOF: failed to get orientation %d\n", dev->of_node, ret);
+ return ret;
+ }
+
+ if (pinfo->desc->has_dcs_backlight) {
+ pinfo->panel.backlight = nt36523_create_backlight(dsi);
+ if (IS_ERR(pinfo->panel.backlight))
+ return dev_err_probe(dev, PTR_ERR(pinfo->panel.backlight),
+ "Failed to create backlight\n");
+ } else {
+ ret = drm_panel_of_backlight(&pinfo->panel);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to get backlight\n");
+ }
drm_panel_add(&pinfo->panel);
@@ -751,6 +1310,10 @@ static int nt36523_probe(struct mipi_dsi_device *dsi)
static const struct of_device_id nt36523_of_match[] = {
{
+ .compatible = "lenovo,j606f-boe-nt36523w",
+ .data = &j606f_boe_desc,
+ },
+ {
.compatible = "xiaomi,elish-boe-nt36523",
.data = &elish_boe_desc,
},
diff --git a/drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c b/drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c
new file mode 100644
index 000000000000..102e1fc7ee38
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c
@@ -0,0 +1,585 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Samsung S6D7AA0 MIPI-DSI TFT LCD controller drm_panel driver.
+ *
+ * Copyright (C) 2022 Artur Weber <aweber.kernel@gmail.com>
+ */
+
+#include <linux/backlight.h>
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <linux/regulator/consumer.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+
+#include <video/mipi_display.h>
+#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_modes.h>
+#include <drm/drm_panel.h>
+
+/* Manufacturer command set */
+#define MCS_BL_CTL 0xc3
+#define MCS_OTP_RELOAD 0xd0
+#define MCS_PASSWD1 0xf0
+#define MCS_PASSWD2 0xf1
+#define MCS_PASSWD3 0xfc
+
+struct s6d7aa0 {
+ struct drm_panel panel;
+ struct mipi_dsi_device *dsi;
+ struct gpio_desc *reset_gpio;
+ struct regulator_bulk_data supplies[2];
+ const struct s6d7aa0_panel_desc *desc;
+};
+
+struct s6d7aa0_panel_desc {
+ unsigned int panel_type;
+ int (*init_func)(struct s6d7aa0 *ctx);
+ int (*off_func)(struct s6d7aa0 *ctx);
+ const struct drm_display_mode *drm_mode;
+ unsigned long mode_flags;
+ u32 bus_flags;
+ bool has_backlight;
+ bool use_passwd3;
+};
+
+enum s6d7aa0_panels {
+ S6D7AA0_PANEL_LSL080AL02,
+ S6D7AA0_PANEL_LSL080AL03,
+ S6D7AA0_PANEL_LTL101AT01,
+};
+
+static inline struct s6d7aa0 *panel_to_s6d7aa0(struct drm_panel *panel)
+{
+ return container_of(panel, struct s6d7aa0, panel);
+}
+
+static void s6d7aa0_reset(struct s6d7aa0 *ctx)
+{
+ gpiod_set_value_cansleep(ctx->reset_gpio, 1);
+ msleep(50);
+ gpiod_set_value_cansleep(ctx->reset_gpio, 0);
+ msleep(50);
+}
+
+static int s6d7aa0_lock(struct s6d7aa0 *ctx, bool lock)
+{
+ struct mipi_dsi_device *dsi = ctx->dsi;
+ int ret = 0;
+
+ if (lock) {
+ mipi_dsi_dcs_write_seq(dsi, MCS_PASSWD1, 0xa5, 0xa5);
+ mipi_dsi_dcs_write_seq(dsi, MCS_PASSWD2, 0xa5, 0xa5);
+ if (ctx->desc->use_passwd3)
+ mipi_dsi_dcs_write_seq(dsi, MCS_PASSWD3, 0x5a, 0x5a);
+ } else {
+ mipi_dsi_dcs_write_seq(dsi, MCS_PASSWD1, 0x5a, 0x5a);
+ mipi_dsi_dcs_write_seq(dsi, MCS_PASSWD2, 0x5a, 0x5a);
+ if (ctx->desc->use_passwd3)
+ mipi_dsi_dcs_write_seq(dsi, MCS_PASSWD3, 0xa5, 0xa5);
+ }
+
+ return ret;
+}
+
+static int s6d7aa0_on(struct s6d7aa0 *ctx)
+{
+ struct mipi_dsi_device *dsi = ctx->dsi;
+ struct device *dev = &dsi->dev;
+ int ret;
+
+ ret = ctx->desc->init_func(ctx);
+ if (ret < 0) {
+ dev_err(dev, "Failed to initialize panel: %d\n", ret);
+ gpiod_set_value_cansleep(ctx->reset_gpio, 1);
+ return ret;
+ }
+
+ ret = mipi_dsi_dcs_set_display_on(dsi);
+ if (ret < 0) {
+ dev_err(dev, "Failed to set display on: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int s6d7aa0_off(struct s6d7aa0 *ctx)
+{
+ struct mipi_dsi_device *dsi = ctx->dsi;
+ struct device *dev = &dsi->dev;
+ int ret;
+
+ ret = ctx->desc->off_func(ctx);
+ if (ret < 0) {
+ dev_err(dev, "Panel-specific off function failed: %d\n", ret);
+ return ret;
+ }
+
+ ret = mipi_dsi_dcs_set_display_off(dsi);
+ if (ret < 0) {
+ dev_err(dev, "Failed to set display off: %d\n", ret);
+ return ret;
+ }
+ msleep(64);
+
+ ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
+ if (ret < 0) {
+ dev_err(dev, "Failed to enter sleep mode: %d\n", ret);
+ return ret;
+ }
+ msleep(120);
+
+ return 0;
+}
+
+static int s6d7aa0_prepare(struct drm_panel *panel)
+{
+ struct s6d7aa0 *ctx = panel_to_s6d7aa0(panel);
+ struct device *dev = &ctx->dsi->dev;
+ int ret;
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
+ if (ret < 0) {
+ dev_err(dev, "Failed to enable regulators: %d\n", ret);
+ return ret;
+ }
+
+ s6d7aa0_reset(ctx);
+
+ ret = s6d7aa0_on(ctx);
+ if (ret < 0) {
+ dev_err(dev, "Failed to initialize panel: %d\n", ret);
+ gpiod_set_value_cansleep(ctx->reset_gpio, 1);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int s6d7aa0_disable(struct drm_panel *panel)
+{
+ struct s6d7aa0 *ctx = panel_to_s6d7aa0(panel);
+ struct device *dev = &ctx->dsi->dev;
+ int ret;
+
+ ret = s6d7aa0_off(ctx);
+ if (ret < 0)
+ dev_err(dev, "Failed to un-initialize panel: %d\n", ret);
+
+ return 0;
+}
+
+static int s6d7aa0_unprepare(struct drm_panel *panel)
+{
+ struct s6d7aa0 *ctx = panel_to_s6d7aa0(panel);
+
+ gpiod_set_value_cansleep(ctx->reset_gpio, 1);
+ regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
+
+ return 0;
+}
+
+/* Backlight control code */
+
+static int s6d7aa0_bl_update_status(struct backlight_device *bl)
+{
+ struct mipi_dsi_device *dsi = bl_get_data(bl);
+ u16 brightness = backlight_get_brightness(bl);
+ int ret;
+
+ ret = mipi_dsi_dcs_set_display_brightness(dsi, brightness);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int s6d7aa0_bl_get_brightness(struct backlight_device *bl)
+{
+ struct mipi_dsi_device *dsi = bl_get_data(bl);
+ u16 brightness;
+ int ret;
+
+ ret = mipi_dsi_dcs_get_display_brightness(dsi, &brightness);
+ if (ret < 0)
+ return ret;
+
+ return brightness & 0xff;
+}
+
+static const struct backlight_ops s6d7aa0_bl_ops = {
+ .update_status = s6d7aa0_bl_update_status,
+ .get_brightness = s6d7aa0_bl_get_brightness,
+};
+
+static struct backlight_device *
+s6d7aa0_create_backlight(struct mipi_dsi_device *dsi)
+{
+ struct device *dev = &dsi->dev;
+ const struct backlight_properties props = {
+ .type = BACKLIGHT_RAW,
+ .brightness = 255,
+ .max_brightness = 255,
+ };
+
+ return devm_backlight_device_register(dev, dev_name(dev), dev, dsi,
+ &s6d7aa0_bl_ops, &props);
+}
+
+/* Initialization code and structures for LSL080AL02 panel */
+
+static int s6d7aa0_lsl080al02_init(struct s6d7aa0 *ctx)
+{
+ struct mipi_dsi_device *dsi = ctx->dsi;
+ struct device *dev = &dsi->dev;
+ int ret;
+
+ usleep_range(20000, 25000);
+
+ ret = s6d7aa0_lock(ctx, false);
+ if (ret < 0) {
+ dev_err(dev, "Failed to unlock registers: %d\n", ret);
+ return ret;
+ }
+
+ mipi_dsi_dcs_write_seq(dsi, MCS_OTP_RELOAD, 0x00, 0x10);
+ usleep_range(1000, 1500);
+
+ /* SEQ_B6_PARAM_8_R01 */
+ mipi_dsi_dcs_write_seq(dsi, 0xb6, 0x10);
+
+ /* BL_CTL_ON */
+ mipi_dsi_dcs_write_seq(dsi, MCS_BL_CTL, 0x40, 0x00, 0x28);
+
+ usleep_range(5000, 6000);
+
+ mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_SET_ADDRESS_MODE, 0x04);
+
+ ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
+ if (ret < 0) {
+ dev_err(dev, "Failed to exit sleep mode: %d\n", ret);
+ return ret;
+ }
+
+ msleep(120);
+ mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_SET_ADDRESS_MODE, 0x00);
+
+ ret = s6d7aa0_lock(ctx, true);
+ if (ret < 0) {
+ dev_err(dev, "Failed to lock registers: %d\n", ret);
+ return ret;
+ }
+
+ ret = mipi_dsi_dcs_set_display_on(dsi);
+ if (ret < 0) {
+ dev_err(dev, "Failed to set display on: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int s6d7aa0_lsl080al02_off(struct s6d7aa0 *ctx)
+{
+ struct mipi_dsi_device *dsi = ctx->dsi;
+
+ /* BL_CTL_OFF */
+ mipi_dsi_dcs_write_seq(dsi, MCS_BL_CTL, 0x40, 0x00, 0x20);
+
+ return 0;
+}
+
+static const struct drm_display_mode s6d7aa0_lsl080al02_mode = {
+ .clock = (800 + 16 + 4 + 140) * (1280 + 8 + 4 + 4) * 60 / 1000,
+ .hdisplay = 800,
+ .hsync_start = 800 + 16,
+ .hsync_end = 800 + 16 + 4,
+ .htotal = 800 + 16 + 4 + 140,
+ .vdisplay = 1280,
+ .vsync_start = 1280 + 8,
+ .vsync_end = 1280 + 8 + 4,
+ .vtotal = 1280 + 8 + 4 + 4,
+ .width_mm = 108,
+ .height_mm = 173,
+};
+
+static const struct s6d7aa0_panel_desc s6d7aa0_lsl080al02_desc = {
+ .panel_type = S6D7AA0_PANEL_LSL080AL02,
+ .init_func = s6d7aa0_lsl080al02_init,
+ .off_func = s6d7aa0_lsl080al02_off,
+ .drm_mode = &s6d7aa0_lsl080al02_mode,
+ .mode_flags = MIPI_DSI_MODE_VSYNC_FLUSH | MIPI_DSI_MODE_VIDEO_NO_HFP,
+ .bus_flags = DRM_BUS_FLAG_DE_HIGH,
+
+ .has_backlight = false,
+ .use_passwd3 = false,
+};
+
+/* Initialization code and structures for LSL080AL03 panel */
+
+static int s6d7aa0_lsl080al03_init(struct s6d7aa0 *ctx)
+{
+ struct mipi_dsi_device *dsi = ctx->dsi;
+ struct device *dev = &dsi->dev;
+ int ret;
+
+ usleep_range(20000, 25000);
+
+ ret = s6d7aa0_lock(ctx, false);
+ if (ret < 0) {
+ dev_err(dev, "Failed to unlock registers: %d\n", ret);
+ return ret;
+ }
+
+ if (ctx->desc->panel_type == S6D7AA0_PANEL_LSL080AL03) {
+ mipi_dsi_dcs_write_seq(dsi, MCS_BL_CTL, 0xc7, 0x00, 0x29);
+ mipi_dsi_dcs_write_seq(dsi, 0xbc, 0x01, 0x4e, 0xa0);
+ mipi_dsi_dcs_write_seq(dsi, 0xfd, 0x16, 0x10, 0x11, 0x23,
+ 0x09);
+ mipi_dsi_dcs_write_seq(dsi, 0xfe, 0x00, 0x02, 0x03, 0x21,
+ 0x80, 0x78);
+ } else if (ctx->desc->panel_type == S6D7AA0_PANEL_LTL101AT01) {
+ mipi_dsi_dcs_write_seq(dsi, MCS_BL_CTL, 0x40, 0x00, 0x08);
+ mipi_dsi_dcs_write_seq(dsi, 0xbc, 0x01, 0x4e, 0x0b);
+ mipi_dsi_dcs_write_seq(dsi, 0xfd, 0x16, 0x10, 0x11, 0x23,
+ 0x09);
+ mipi_dsi_dcs_write_seq(dsi, 0xfe, 0x00, 0x02, 0x03, 0x21,
+ 0x80, 0x68);
+ }
+
+ mipi_dsi_dcs_write_seq(dsi, 0xb3, 0x51);
+ mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x24);
+ mipi_dsi_dcs_write_seq(dsi, 0xf2, 0x02, 0x08, 0x08);
+
+ usleep_range(10000, 11000);
+
+ mipi_dsi_dcs_write_seq(dsi, 0xc0, 0x80, 0x80, 0x30);
+ mipi_dsi_dcs_write_seq(dsi, 0xcd,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e);
+ mipi_dsi_dcs_write_seq(dsi, 0xce,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, 0xc1, 0x03);
+
+ ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
+ if (ret < 0) {
+ dev_err(dev, "Failed to exit sleep mode: %d\n", ret);
+ return ret;
+ }
+
+ ret = s6d7aa0_lock(ctx, true);
+ if (ret < 0) {
+ dev_err(dev, "Failed to lock registers: %d\n", ret);
+ return ret;
+ }
+
+ ret = mipi_dsi_dcs_set_display_on(dsi);
+ if (ret < 0) {
+ dev_err(dev, "Failed to set display on: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int s6d7aa0_lsl080al03_off(struct s6d7aa0 *ctx)
+{
+ struct mipi_dsi_device *dsi = ctx->dsi;
+
+ mipi_dsi_dcs_write_seq(dsi, 0x22, 0x00);
+
+ return 0;
+}
+
+static const struct drm_display_mode s6d7aa0_lsl080al03_mode = {
+ .clock = (768 + 18 + 16 + 126) * (1024 + 8 + 2 + 6) * 60 / 1000,
+ .hdisplay = 768,
+ .hsync_start = 768 + 18,
+ .hsync_end = 768 + 18 + 16,
+ .htotal = 768 + 18 + 16 + 126,
+ .vdisplay = 1024,
+ .vsync_start = 1024 + 8,
+ .vsync_end = 1024 + 8 + 2,
+ .vtotal = 1024 + 8 + 2 + 6,
+ .width_mm = 122,
+ .height_mm = 163,
+};
+
+static const struct s6d7aa0_panel_desc s6d7aa0_lsl080al03_desc = {
+ .panel_type = S6D7AA0_PANEL_LSL080AL03,
+ .init_func = s6d7aa0_lsl080al03_init,
+ .off_func = s6d7aa0_lsl080al03_off,
+ .drm_mode = &s6d7aa0_lsl080al03_mode,
+ .mode_flags = MIPI_DSI_MODE_NO_EOT_PACKET,
+ .bus_flags = 0,
+
+ .has_backlight = true,
+ .use_passwd3 = true,
+};
+
+/* Initialization structures for LTL101AT01 panel */
+
+static const struct drm_display_mode s6d7aa0_ltl101at01_mode = {
+ .clock = (768 + 96 + 16 + 184) * (1024 + 8 + 2 + 6) * 60 / 1000,
+ .hdisplay = 768,
+ .hsync_start = 768 + 96,
+ .hsync_end = 768 + 96 + 16,
+ .htotal = 768 + 96 + 16 + 184,
+ .vdisplay = 1024,
+ .vsync_start = 1024 + 8,
+ .vsync_end = 1024 + 8 + 2,
+ .vtotal = 1024 + 8 + 2 + 6,
+ .width_mm = 148,
+ .height_mm = 197,
+};
+
+static const struct s6d7aa0_panel_desc s6d7aa0_ltl101at01_desc = {
+ .panel_type = S6D7AA0_PANEL_LTL101AT01,
+ .init_func = s6d7aa0_lsl080al03_init, /* Similar init to LSL080AL03 */
+ .off_func = s6d7aa0_lsl080al03_off,
+ .drm_mode = &s6d7aa0_ltl101at01_mode,
+ .mode_flags = MIPI_DSI_MODE_NO_EOT_PACKET,
+ .bus_flags = 0,
+
+ .has_backlight = true,
+ .use_passwd3 = true,
+};
+
+static int s6d7aa0_get_modes(struct drm_panel *panel,
+ struct drm_connector *connector)
+{
+ struct drm_display_mode *mode;
+ struct s6d7aa0 *ctx;
+
+ ctx = container_of(panel, struct s6d7aa0, panel);
+ if (!ctx)
+ return -EINVAL;
+
+ mode = drm_mode_duplicate(connector->dev, ctx->desc->drm_mode);
+ if (!mode)
+ return -ENOMEM;
+
+ drm_mode_set_name(mode);
+
+ mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
+ connector->display_info.width_mm = mode->width_mm;
+ connector->display_info.height_mm = mode->height_mm;
+ connector->display_info.bus_flags = ctx->desc->bus_flags;
+ drm_mode_probed_add(connector, mode);
+
+ return 1;
+}
+
+static const struct drm_panel_funcs s6d7aa0_panel_funcs = {
+ .disable = s6d7aa0_disable,
+ .prepare = s6d7aa0_prepare,
+ .unprepare = s6d7aa0_unprepare,
+ .get_modes = s6d7aa0_get_modes,
+};
+
+static int s6d7aa0_probe(struct mipi_dsi_device *dsi)
+{
+ struct device *dev = &dsi->dev;
+ struct s6d7aa0 *ctx;
+ int ret;
+
+ ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+
+ ctx->desc = of_device_get_match_data(dev);
+ if (!ctx->desc)
+ return -ENODEV;
+
+ ctx->supplies[0].supply = "power";
+ ctx->supplies[1].supply = "vmipi";
+ ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ctx->supplies),
+ ctx->supplies);
+ if (ret < 0)
+ return dev_err_probe(dev, ret, "Failed to get regulators\n");
+
+ ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
+ if (IS_ERR(ctx->reset_gpio))
+ return dev_err_probe(dev, PTR_ERR(ctx->reset_gpio),
+ "Failed to get reset-gpios\n");
+
+ ctx->dsi = dsi;
+ mipi_dsi_set_drvdata(dsi, ctx);
+
+ dsi->lanes = 4;
+ dsi->format = MIPI_DSI_FMT_RGB888;
+ dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST
+ | ctx->desc->mode_flags;
+
+ drm_panel_init(&ctx->panel, dev, &s6d7aa0_panel_funcs,
+ DRM_MODE_CONNECTOR_DSI);
+ ctx->panel.prepare_prev_first = true;
+
+ ret = drm_panel_of_backlight(&ctx->panel);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to get backlight\n");
+
+ /* Use DSI-based backlight as fallback if available */
+ if (ctx->desc->has_backlight && !ctx->panel.backlight) {
+ ctx->panel.backlight = s6d7aa0_create_backlight(dsi);
+ if (IS_ERR(ctx->panel.backlight))
+ return dev_err_probe(dev, PTR_ERR(ctx->panel.backlight),
+ "Failed to create backlight\n");
+ }
+
+ drm_panel_add(&ctx->panel);
+
+ ret = mipi_dsi_attach(dsi);
+ if (ret < 0) {
+ dev_err(dev, "Failed to attach to DSI host: %d\n", ret);
+ drm_panel_remove(&ctx->panel);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void s6d7aa0_remove(struct mipi_dsi_device *dsi)
+{
+ struct s6d7aa0 *ctx = mipi_dsi_get_drvdata(dsi);
+ int ret;
+
+ ret = mipi_dsi_detach(dsi);
+ if (ret < 0)
+ dev_err(&dsi->dev, "Failed to detach from DSI host: %d\n", ret);
+
+ drm_panel_remove(&ctx->panel);
+}
+
+static const struct of_device_id s6d7aa0_of_match[] = {
+ {
+ .compatible = "samsung,lsl080al02",
+ .data = &s6d7aa0_lsl080al02_desc
+ },
+ {
+ .compatible = "samsung,lsl080al03",
+ .data = &s6d7aa0_lsl080al03_desc
+ },
+ {
+ .compatible = "samsung,ltl101at01",
+ .data = &s6d7aa0_ltl101at01_desc
+ },
+ { /* sentinel */ }
+};
+
+static struct mipi_dsi_driver s6d7aa0_driver = {
+ .probe = s6d7aa0_probe,
+ .remove = s6d7aa0_remove,
+ .driver = {
+ .name = "panel-samsung-s6d7aa0",
+ .of_match_table = s6d7aa0_of_match,
+ },
+};
+module_mipi_dsi_driver(s6d7aa0_driver);
+
+MODULE_AUTHOR("Artur Weber <aweber.kernel@gmail.com>");
+MODULE_DESCRIPTION("Samsung S6D7AA0 MIPI-DSI LCD controller driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c b/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c
index d1ec80a3e3c7..855e64444daa 100644
--- a/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c
+++ b/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c
@@ -28,9 +28,6 @@ struct sharp_nt_panel {
struct gpio_desc *reset_gpio;
bool prepared;
- bool enabled;
-
- const struct drm_display_mode *mode;
};
static inline struct sharp_nt_panel *to_sharp_nt_panel(struct drm_panel *panel)
@@ -97,19 +94,6 @@ static int sharp_nt_panel_off(struct sharp_nt_panel *sharp_nt)
return 0;
}
-
-static int sharp_nt_panel_disable(struct drm_panel *panel)
-{
- struct sharp_nt_panel *sharp_nt = to_sharp_nt_panel(panel);
-
- if (!sharp_nt->enabled)
- return 0;
-
- sharp_nt->enabled = false;
-
- return 0;
-}
-
static int sharp_nt_panel_unprepare(struct drm_panel *panel)
{
struct sharp_nt_panel *sharp_nt = to_sharp_nt_panel(panel);
@@ -179,28 +163,16 @@ poweroff:
return ret;
}
-static int sharp_nt_panel_enable(struct drm_panel *panel)
-{
- struct sharp_nt_panel *sharp_nt = to_sharp_nt_panel(panel);
-
- if (sharp_nt->enabled)
- return 0;
-
- sharp_nt->enabled = true;
-
- return 0;
-}
-
static const struct drm_display_mode default_mode = {
- .clock = 41118,
+ .clock = (540 + 48 + 32 + 80) * (960 + 3 + 10 + 15) * 60 / 1000,
.hdisplay = 540,
.hsync_start = 540 + 48,
- .hsync_end = 540 + 48 + 80,
- .htotal = 540 + 48 + 80 + 32,
+ .hsync_end = 540 + 48 + 32,
+ .htotal = 540 + 48 + 32 + 80,
.vdisplay = 960,
.vsync_start = 960 + 3,
- .vsync_end = 960 + 3 + 15,
- .vtotal = 960 + 3 + 15 + 1,
+ .vsync_end = 960 + 3 + 10,
+ .vtotal = 960 + 3 + 10 + 15,
};
static int sharp_nt_panel_get_modes(struct drm_panel *panel,
@@ -227,10 +199,8 @@ static int sharp_nt_panel_get_modes(struct drm_panel *panel,
}
static const struct drm_panel_funcs sharp_nt_panel_funcs = {
- .disable = sharp_nt_panel_disable,
.unprepare = sharp_nt_panel_unprepare,
.prepare = sharp_nt_panel_prepare,
- .enable = sharp_nt_panel_enable,
.get_modes = sharp_nt_panel_get_modes,
};
@@ -239,8 +209,6 @@ static int sharp_nt_panel_add(struct sharp_nt_panel *sharp_nt)
struct device *dev = &sharp_nt->dsi->dev;
int ret;
- sharp_nt->mode = &default_mode;
-
sharp_nt->supply = devm_regulator_get(dev, "avdd");
if (IS_ERR(sharp_nt->supply))
return PTR_ERR(sharp_nt->supply);
@@ -280,6 +248,7 @@ static int sharp_nt_panel_probe(struct mipi_dsi_device *dsi)
dsi->lanes = 2;
dsi->format = MIPI_DSI_FMT_RGB888;
dsi->mode_flags = MIPI_DSI_MODE_VIDEO |
+ MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
MIPI_DSI_MODE_VIDEO_HSE |
MIPI_DSI_CLOCK_NON_CONTINUOUS |
MIPI_DSI_MODE_NO_EOT_PACKET;
diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
index 065f378bba9d..5778824dffd4 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -1211,6 +1211,37 @@ static const struct panel_desc bananapi_s070wv20_ct16 = {
},
};
+static const struct display_timing boe_ev121wxm_n10_1850_timing = {
+ .pixelclock = { 69922000, 71000000, 72293000 },
+ .hactive = { 1280, 1280, 1280 },
+ .hfront_porch = { 48, 48, 48 },
+ .hback_porch = { 80, 80, 80 },
+ .hsync_len = { 32, 32, 32 },
+ .vactive = { 800, 800, 800 },
+ .vfront_porch = { 3, 3, 3 },
+ .vback_porch = { 14, 14, 14 },
+ .vsync_len = { 6, 6, 6 },
+};
+
+static const struct panel_desc boe_ev121wxm_n10_1850 = {
+ .timings = &boe_ev121wxm_n10_1850_timing,
+ .num_timings = 1,
+ .bpc = 8,
+ .size = {
+ .width = 261,
+ .height = 163,
+ },
+ .delay = {
+ .prepare = 9,
+ .enable = 300,
+ .unprepare = 300,
+ .disable = 560,
+ },
+ .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
+ .bus_flags = DRM_BUS_FLAG_DE_HIGH,
+ .connector_type = DRM_MODE_CONNECTOR_LVDS,
+};
+
static const struct drm_display_mode boe_hv070wsa_mode = {
.clock = 42105,
.hdisplay = 1024,
@@ -2142,6 +2173,38 @@ static const struct panel_desc innolux_at070tn92 = {
.bus_format = MEDIA_BUS_FMT_RGB888_1X24,
};
+static const struct display_timing innolux_g070ace_l01_timing = {
+ .pixelclock = { 25200000, 35000000, 35700000 },
+ .hactive = { 800, 800, 800 },
+ .hfront_porch = { 30, 32, 87 },
+ .hback_porch = { 30, 32, 87 },
+ .hsync_len = { 1, 1, 1 },
+ .vactive = { 480, 480, 480 },
+ .vfront_porch = { 3, 3, 3 },
+ .vback_porch = { 13, 13, 13 },
+ .vsync_len = { 1, 1, 4 },
+ .flags = DISPLAY_FLAGS_DE_HIGH,
+};
+
+static const struct panel_desc innolux_g070ace_l01 = {
+ .timings = &innolux_g070ace_l01_timing,
+ .num_timings = 1,
+ .bpc = 8,
+ .size = {
+ .width = 152,
+ .height = 91,
+ },
+ .delay = {
+ .prepare = 10,
+ .enable = 50,
+ .disable = 50,
+ .unprepare = 500,
+ },
+ .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
+ .bus_flags = DRM_BUS_FLAG_DE_HIGH,
+ .connector_type = DRM_MODE_CONNECTOR_LVDS,
+};
+
static const struct display_timing innolux_g070y2_l01_timing = {
.pixelclock = { 28000000, 29500000, 32000000 },
.hactive = { 800, 800, 800 },
@@ -3985,6 +4048,9 @@ static const struct of_device_id platform_of_match[] = {
.compatible = "bananapi,s070wv20-ct16",
.data = &bananapi_s070wv20_ct16,
}, {
+ .compatible = "boe,ev121wxm-n10-1850",
+ .data = &boe_ev121wxm_n10_1850,
+ }, {
.compatible = "boe,hv070wsa-100",
.data = &boe_hv070wsa
}, {
@@ -4099,6 +4165,9 @@ static const struct of_device_id platform_of_match[] = {
.compatible = "innolux,at070tn92",
.data = &innolux_at070tn92,
}, {
+ .compatible = "innolux,g070ace-l01",
+ .data = &innolux_g070ace_l01,
+ }, {
.compatible = "innolux,g070y2-l01",
.data = &innolux_g070y2_l01,
}, {
diff --git a/drivers/gpu/drm/panel/panel-sitronix-st7703.c b/drivers/gpu/drm/panel/panel-sitronix-st7703.c
index 6747ca237ced..3aa31f3d6157 100644
--- a/drivers/gpu/drm/panel/panel-sitronix-st7703.c
+++ b/drivers/gpu/drm/panel/panel-sitronix-st7703.c
@@ -28,6 +28,7 @@
/* Manufacturer specific Commands send via DSI */
#define ST7703_CMD_ALL_PIXEL_OFF 0x22
#define ST7703_CMD_ALL_PIXEL_ON 0x23
+#define ST7703_CMD_SETAPID 0xB1
#define ST7703_CMD_SETDISP 0xB2
#define ST7703_CMD_SETRGBIF 0xB3
#define ST7703_CMD_SETCYC 0xB4
@@ -41,12 +42,15 @@
#define ST7703_CMD_UNKNOWN_BF 0xBF
#define ST7703_CMD_SETSCR 0xC0
#define ST7703_CMD_SETPOWER 0xC1
+#define ST7703_CMD_SETECO 0xC6
+#define ST7703_CMD_SETIO 0xC7
+#define ST7703_CMD_SETCABC 0xC8
#define ST7703_CMD_SETPANEL 0xCC
-#define ST7703_CMD_UNKNOWN_C6 0xC6
#define ST7703_CMD_SETGAMMA 0xE0
#define ST7703_CMD_SETEQ 0xE3
#define ST7703_CMD_SETGIP1 0xE9
#define ST7703_CMD_SETGIP2 0xEA
+#define ST7703_CMD_UNKNOWN_EF 0xEF
struct st7703 {
struct device *dev;
@@ -249,8 +253,7 @@ static int xbd599_init_sequence(struct st7703 *ctx)
* ESD_DET_TIME_SEL = 0 frames
*/);
- /* Undocumented command. */
- mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_UNKNOWN_C6, 0x01, 0x00, 0xFF, 0xFF, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETECO, 0x01, 0x00, 0xFF, 0xFF, 0x00);
mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETPOWER,
0x74, /* VBTHS, VBTLS: VGH = 17V, VBL = -11V */
@@ -338,6 +341,98 @@ static const struct st7703_panel_desc xbd599_desc = {
.init_sequence = xbd599_init_sequence,
};
+static int rg353v2_init_sequence(struct st7703 *ctx)
+{
+ struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
+
+ /*
+ * Init sequence was supplied by the panel vendor.
+ */
+
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETEXTC, 0xf1, 0x12, 0x83);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETAPID, 0x00, 0x00, 0x00,
+ 0xda, 0x80);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETDISP, 0x00, 0x13, 0x70);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETRGBIF, 0x10, 0x10, 0x28,
+ 0x28, 0x03, 0xff, 0x00, 0x00, 0x00, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETCYC, 0x80);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETBGP, 0x0a, 0x0a);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETVCOM, 0x92, 0x92);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETPOWER_EXT, 0x25, 0x22,
+ 0xf0, 0x63);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETMIPI, 0x33, 0x81, 0x05,
+ 0xf9, 0x0e, 0x0e, 0x20, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x25, 0x00, 0x90, 0x0a,
+ 0x00, 0x00, 0x01, 0x4f, 0x01, 0x00, 0x00, 0x37);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETVDC, 0x47);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_UNKNOWN_BF, 0x02, 0x11, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETSCR, 0x73, 0x73, 0x50, 0x50,
+ 0x00, 0x00, 0x12, 0x50, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETPOWER, 0x53, 0xc0, 0x32,
+ 0x32, 0x77, 0xe1, 0xdd, 0xdd, 0x77, 0x77, 0x33,
+ 0x33);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETECO, 0x82, 0x00, 0xbf, 0xff,
+ 0x00, 0xff);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETIO, 0xb8, 0x00, 0x0a, 0x00,
+ 0x00, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETCABC, 0x10, 0x40, 0x1e,
+ 0x02);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETPANEL, 0x0b);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETGAMMA, 0x00, 0x07, 0x0d,
+ 0x37, 0x35, 0x3f, 0x41, 0x44, 0x06, 0x0c, 0x0d,
+ 0x0f, 0x11, 0x10, 0x12, 0x14, 0x1a, 0x00, 0x07,
+ 0x0d, 0x37, 0x35, 0x3f, 0x41, 0x44, 0x06, 0x0c,
+ 0x0d, 0x0f, 0x11, 0x10, 0x12, 0x14, 0x1a);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETEQ, 0x07, 0x07, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
+ 0xc0, 0x10);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETGIP1, 0xc8, 0x10, 0x02, 0x00,
+ 0x00, 0xb0, 0xb1, 0x11, 0x31, 0x23, 0x28, 0x80,
+ 0xb0, 0xb1, 0x27, 0x08, 0x00, 0x04, 0x02, 0x00,
+ 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x00,
+ 0x88, 0x88, 0xba, 0x60, 0x24, 0x08, 0x88, 0x88,
+ 0x88, 0x88, 0x88, 0x88, 0x88, 0xba, 0x71, 0x35,
+ 0x18, 0x88, 0x88, 0x88, 0x88, 0x88, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETGIP2, 0x97, 0x0a, 0x82, 0x02,
+ 0x03, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x81, 0x88, 0xba, 0x17, 0x53, 0x88, 0x88, 0x88,
+ 0x88, 0x88, 0x88, 0x80, 0x88, 0xba, 0x06, 0x42,
+ 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x23, 0x00,
+ 0x00, 0x02, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_UNKNOWN_EF, 0xff, 0xff, 0x01);
+
+ return 0;
+}
+
+static const struct drm_display_mode rg353v2_mode = {
+ .hdisplay = 640,
+ .hsync_start = 640 + 40,
+ .hsync_end = 640 + 40 + 2,
+ .htotal = 640 + 40 + 2 + 80,
+ .vdisplay = 480,
+ .vsync_start = 480 + 18,
+ .vsync_end = 480 + 18 + 2,
+ .vtotal = 480 + 18 + 2 + 28,
+ .clock = 24150,
+ .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
+ .width_mm = 70,
+ .height_mm = 57,
+};
+
+static const struct st7703_panel_desc rg353v2_desc = {
+ .mode = &rg353v2_mode,
+ .lanes = 4,
+ .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
+ MIPI_DSI_MODE_NO_EOT_PACKET | MIPI_DSI_MODE_LPM,
+ .format = MIPI_DSI_FMT_RGB888,
+ .init_sequence = rg353v2_init_sequence,
+};
+
static int st7703_enable(struct drm_panel *panel)
{
struct st7703 *ctx = panel_to_st7703(panel);
@@ -598,6 +693,7 @@ static void st7703_remove(struct mipi_dsi_device *dsi)
}
static const struct of_device_id st7703_of_match[] = {
+ { .compatible = "anbernic,rg353v-panel-v2", .data = &rg353v2_desc },
{ .compatible = "rocktech,jh057n00900", .data = &jh057n00900_panel_desc },
{ .compatible = "xingbangda,xbd599", .data = &xbd599_desc },
{ /* sentinel */ }
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index 8526dda91931..b6afe3786b74 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -273,10 +273,9 @@ static int cdn_dp_connector_get_modes(struct drm_connector *connector)
edid->width_cm, edid->height_cm);
dp->sink_has_audio = drm_detect_monitor_audio(edid);
+
+ drm_connector_update_edid_property(connector, edid);
ret = drm_add_edid_modes(connector, edid);
- if (ret)
- drm_connector_update_edid_property(connector,
- edid);
}
mutex_unlock(&dp->lock);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index 6e0788d14c10..d97f2edc646b 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -140,7 +140,7 @@ static int rockchip_drm_bind(struct device *dev)
int ret;
/* Remove existing drivers that may own the framebuffer memory. */
- ret = drm_aperture_remove_framebuffers(false, &rockchip_drm_driver);
+ ret = drm_aperture_remove_framebuffers(&rockchip_drm_driver);
if (ret) {
DRM_DEV_ERROR(dev,
"Failed to remove existing framebuffers - %d.\n",
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index d8f5e064a1ba..a530ecc4d207 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -714,13 +714,13 @@ static void vop_crtc_atomic_disable(struct drm_crtc *crtc,
if (crtc->state->self_refresh_active)
rockchip_drm_set_win_enabled(crtc, false);
+ if (crtc->state->self_refresh_active)
+ goto out;
+
mutex_lock(&vop->vop_lock);
drm_crtc_vblank_off(crtc);
- if (crtc->state->self_refresh_active)
- goto out;
-
/*
* Vop standby will take effect at end of current frame,
* if dsp hold valid irq happen, it means standby complete.
@@ -754,9 +754,9 @@ static void vop_crtc_atomic_disable(struct drm_crtc *crtc,
vop_core_clks_disable(vop);
pm_runtime_put(vop->dev);
-out:
mutex_unlock(&vop->vop_lock);
+out:
if (crtc->state->event && !crtc->state->active) {
spin_lock_irq(&crtc->dev->event_lock);
drm_crtc_send_vblank_event(crtc, crtc->state->event);
diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c
index e0a8890a62e2..68e807ae136a 100644
--- a/drivers/gpu/drm/scheduler/sched_entity.c
+++ b/drivers/gpu/drm/scheduler/sched_entity.c
@@ -72,7 +72,7 @@ int drm_sched_entity_init(struct drm_sched_entity *entity,
entity->num_sched_list = num_sched_list;
entity->priority = priority;
entity->sched_list = num_sched_list > 1 ? sched_list : NULL;
- entity->last_scheduled = NULL;
+ RCU_INIT_POINTER(entity->last_scheduled, NULL);
RB_CLEAR_NODE(&entity->rb_tree_node);
if(num_sched_list)
@@ -140,11 +140,32 @@ bool drm_sched_entity_is_ready(struct drm_sched_entity *entity)
return true;
}
+/**
+ * drm_sched_entity_error - return error of last scheduled job
+ * @entity: scheduler entity to check
+ *
+ * Opportunistically return the error of the last scheduled job. Result can
+ * change any time when new jobs are pushed to the hw.
+ */
+int drm_sched_entity_error(struct drm_sched_entity *entity)
+{
+ struct dma_fence *fence;
+ int r;
+
+ rcu_read_lock();
+ fence = rcu_dereference(entity->last_scheduled);
+ r = fence ? fence->error : 0;
+ rcu_read_unlock();
+
+ return r;
+}
+EXPORT_SYMBOL(drm_sched_entity_error);
+
static void drm_sched_entity_kill_jobs_work(struct work_struct *wrk)
{
struct drm_sched_job *job = container_of(wrk, typeof(*job), work);
- drm_sched_fence_finished(job->s_fence);
+ drm_sched_fence_finished(job->s_fence, -ESRCH);
WARN_ON(job->s_fence->parent);
job->sched->ops->free_job(job);
}
@@ -191,12 +212,12 @@ static void drm_sched_entity_kill(struct drm_sched_entity *entity)
/* Make sure this entity is not used by the scheduler at the moment */
wait_for_completion(&entity->entity_idle);
- prev = dma_fence_get(entity->last_scheduled);
+ /* The entity is guaranteed to not be used by the scheduler */
+ prev = rcu_dereference_check(entity->last_scheduled, true);
+ dma_fence_get(prev);
while ((job = to_drm_sched_job(spsc_queue_pop(&entity->job_queue)))) {
struct drm_sched_fence *s_fence = job->s_fence;
- dma_fence_set_error(&s_fence->finished, -ESRCH);
-
dma_fence_get(&s_fence->finished);
if (!prev || dma_fence_add_callback(prev, &job->finish_cb,
drm_sched_entity_kill_jobs_cb))
@@ -280,8 +301,8 @@ void drm_sched_entity_fini(struct drm_sched_entity *entity)
entity->dependency = NULL;
}
- dma_fence_put(entity->last_scheduled);
- entity->last_scheduled = NULL;
+ dma_fence_put(rcu_dereference_check(entity->last_scheduled, true));
+ RCU_INIT_POINTER(entity->last_scheduled, NULL);
}
EXPORT_SYMBOL(drm_sched_entity_fini);
@@ -321,7 +342,7 @@ static void drm_sched_entity_wakeup(struct dma_fence *f,
container_of(cb, struct drm_sched_entity, cb);
drm_sched_entity_clear_dep(f, cb);
- drm_sched_wakeup(entity->rq->sched);
+ drm_sched_wakeup_if_can_queue(entity->rq->sched);
}
/**
@@ -423,9 +444,9 @@ struct drm_sched_job *drm_sched_entity_pop_job(struct drm_sched_entity *entity)
if (entity->guilty && atomic_read(entity->guilty))
dma_fence_set_error(&sched_job->s_fence->finished, -ECANCELED);
- dma_fence_put(entity->last_scheduled);
-
- entity->last_scheduled = dma_fence_get(&sched_job->s_fence->finished);
+ dma_fence_put(rcu_dereference_check(entity->last_scheduled, true));
+ rcu_assign_pointer(entity->last_scheduled,
+ dma_fence_get(&sched_job->s_fence->finished));
/*
* If the queue is empty we allow drm_sched_entity_select_rq() to
@@ -448,6 +469,12 @@ struct drm_sched_job *drm_sched_entity_pop_job(struct drm_sched_entity *entity)
drm_sched_rq_update_fifo(entity, next->submit_ts);
}
+ /* Jobs and entities might have different lifecycles. Since we're
+ * removing the job from the entities queue, set the jobs entity pointer
+ * to NULL to prevent any future access of the entity through this job.
+ */
+ sched_job->entity = NULL;
+
return sched_job;
}
@@ -473,7 +500,7 @@ void drm_sched_entity_select_rq(struct drm_sched_entity *entity)
*/
smp_rmb();
- fence = entity->last_scheduled;
+ fence = rcu_dereference_check(entity->last_scheduled, true);
/* stay on the same engine if the previous job hasn't finished */
if (fence && !dma_fence_is_signaled(fence))
@@ -538,7 +565,7 @@ void drm_sched_entity_push_job(struct drm_sched_job *sched_job)
if (drm_sched_policy == DRM_SCHED_POLICY_FIFO)
drm_sched_rq_update_fifo(entity, submit_ts);
- drm_sched_wakeup(entity->rq->sched);
+ drm_sched_wakeup_if_can_queue(entity->rq->sched);
}
}
EXPORT_SYMBOL(drm_sched_entity_push_job);
diff --git a/drivers/gpu/drm/scheduler/sched_fence.c b/drivers/gpu/drm/scheduler/sched_fence.c
index fe9c6468e440..ef120475e7c6 100644
--- a/drivers/gpu/drm/scheduler/sched_fence.c
+++ b/drivers/gpu/drm/scheduler/sched_fence.c
@@ -53,8 +53,10 @@ void drm_sched_fence_scheduled(struct drm_sched_fence *fence)
dma_fence_signal(&fence->scheduled);
}
-void drm_sched_fence_finished(struct drm_sched_fence *fence)
+void drm_sched_fence_finished(struct drm_sched_fence *fence, int result)
{
+ if (result)
+ dma_fence_set_error(&fence->finished, result);
dma_fence_signal(&fence->finished);
}
diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c
index fcd5bd7e5e8e..394010a60821 100644
--- a/drivers/gpu/drm/scheduler/sched_main.c
+++ b/drivers/gpu/drm/scheduler/sched_main.c
@@ -42,6 +42,10 @@
* the hardware.
*
* The jobs in a entity are always scheduled in the order that they were pushed.
+ *
+ * Note that once a job was taken from the entities queue and pushed to the
+ * hardware, i.e. the pending queue, the entity must not be referenced anymore
+ * through the jobs entity pointer.
*/
#include <linux/kthread.h>
@@ -258,7 +262,7 @@ drm_sched_rq_select_entity_fifo(struct drm_sched_rq *rq)
*
* Finish the job's fence and wake up the worker thread.
*/
-static void drm_sched_job_done(struct drm_sched_job *s_job)
+static void drm_sched_job_done(struct drm_sched_job *s_job, int result)
{
struct drm_sched_fence *s_fence = s_job->s_fence;
struct drm_gpu_scheduler *sched = s_fence->sched;
@@ -269,7 +273,7 @@ static void drm_sched_job_done(struct drm_sched_job *s_job)
trace_drm_sched_process_job(s_fence);
dma_fence_get(&s_fence->finished);
- drm_sched_fence_finished(s_fence);
+ drm_sched_fence_finished(s_fence, result);
dma_fence_put(&s_fence->finished);
wake_up_interruptible(&sched->wake_up_worker);
}
@@ -283,7 +287,7 @@ static void drm_sched_job_done_cb(struct dma_fence *f, struct dma_fence_cb *cb)
{
struct drm_sched_job *s_job = container_of(cb, struct drm_sched_job, cb);
- drm_sched_job_done(s_job);
+ drm_sched_job_done(s_job, f->error);
}
/**
@@ -309,7 +313,7 @@ static void drm_sched_start_timeout(struct drm_gpu_scheduler *sched)
*/
void drm_sched_fault(struct drm_gpu_scheduler *sched)
{
- if (sched->ready)
+ if (sched->timeout_wq)
mod_delayed_work(sched->timeout_wq, &sched->work_tdr, 0);
}
EXPORT_SYMBOL(drm_sched_fault);
@@ -534,12 +538,12 @@ void drm_sched_start(struct drm_gpu_scheduler *sched, bool full_recovery)
r = dma_fence_add_callback(fence, &s_job->cb,
drm_sched_job_done_cb);
if (r == -ENOENT)
- drm_sched_job_done(s_job);
+ drm_sched_job_done(s_job, fence->error);
else if (r)
DRM_DEV_ERROR(sched->dev, "fence add callback failed (%d)\n",
r);
} else
- drm_sched_job_done(s_job);
+ drm_sched_job_done(s_job, -ECANCELED);
}
if (full_recovery) {
@@ -844,27 +848,26 @@ void drm_sched_job_cleanup(struct drm_sched_job *job)
EXPORT_SYMBOL(drm_sched_job_cleanup);
/**
- * drm_sched_ready - is the scheduler ready
- *
+ * drm_sched_can_queue -- Can we queue more to the hardware?
* @sched: scheduler instance
*
* Return true if we can push more jobs to the hw, otherwise false.
*/
-static bool drm_sched_ready(struct drm_gpu_scheduler *sched)
+static bool drm_sched_can_queue(struct drm_gpu_scheduler *sched)
{
return atomic_read(&sched->hw_rq_count) <
sched->hw_submission_limit;
}
/**
- * drm_sched_wakeup - Wake up the scheduler when it is ready
- *
+ * drm_sched_wakeup_if_can_queue - Wake up the scheduler
* @sched: scheduler instance
*
+ * Wake up the scheduler if we can queue jobs.
*/
-void drm_sched_wakeup(struct drm_gpu_scheduler *sched)
+void drm_sched_wakeup_if_can_queue(struct drm_gpu_scheduler *sched)
{
- if (drm_sched_ready(sched))
+ if (drm_sched_can_queue(sched))
wake_up_interruptible(&sched->wake_up_worker);
}
@@ -881,7 +884,7 @@ drm_sched_select_entity(struct drm_gpu_scheduler *sched)
struct drm_sched_entity *entity;
int i;
- if (!drm_sched_ready(sched))
+ if (!drm_sched_can_queue(sched))
return NULL;
/* Kernel run queue has higher priority than normal run queue*/
@@ -1050,15 +1053,13 @@ static int drm_sched_main(void *param)
r = dma_fence_add_callback(fence, &sched_job->cb,
drm_sched_job_done_cb);
if (r == -ENOENT)
- drm_sched_job_done(sched_job);
+ drm_sched_job_done(sched_job, fence->error);
else if (r)
DRM_DEV_ERROR(sched->dev, "fence add callback failed (%d)\n",
r);
} else {
- if (IS_ERR(fence))
- dma_fence_set_error(&s_fence->finished, PTR_ERR(fence));
-
- drm_sched_job_done(sched_job);
+ drm_sched_job_done(sched_job, IS_ERR(fence) ?
+ PTR_ERR(fence) : 0);
}
wake_up(&sched->job_scheduled);
diff --git a/drivers/gpu/drm/shmobile/Kconfig b/drivers/gpu/drm/shmobile/Kconfig
index 4ec5dc74a6b0..ad14112999ad 100644
--- a/drivers/gpu/drm/shmobile/Kconfig
+++ b/drivers/gpu/drm/shmobile/Kconfig
@@ -1,8 +1,8 @@
# SPDX-License-Identifier: GPL-2.0
config DRM_SHMOBILE
tristate "DRM Support for SH Mobile"
- depends on DRM && ARM
- depends on ARCH_SHMOBILE || COMPILE_TEST
+ depends on DRM
+ depends on ARCH_RENESAS || ARCH_SHMOBILE || COMPILE_TEST
select BACKLIGHT_CLASS_DEVICE
select DRM_KMS_HELPER
select DRM_GEM_DMA_HELPER
diff --git a/drivers/gpu/drm/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/shmobile/shmob_drm_crtc.c
index d354ab3077ce..11dd2bc803e7 100644
--- a/drivers/gpu/drm/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/shmobile/shmob_drm_crtc.c
@@ -18,6 +18,7 @@
#include <drm/drm_gem_dma_helper.h>
#include <drm/drm_modeset_helper.h>
#include <drm/drm_modeset_helper_vtables.h>
+#include <drm/drm_plane_helper.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_simple_kms_helper.h>
#include <drm/drm_vblank.h>
@@ -232,6 +233,7 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
value = LDDDSR_LS | LDDDSR_WS | LDDDSR_BS;
break;
case DRM_FORMAT_ARGB8888:
+ case DRM_FORMAT_XRGB8888:
default:
value = LDDDSR_LS;
break;
@@ -355,8 +357,8 @@ static int shmob_drm_crtc_mode_set(struct drm_crtc *crtc,
format = shmob_drm_format_info(crtc->primary->fb->format->format);
if (format == NULL) {
- dev_dbg(sdev->dev, "mode_set: unsupported format %08x\n",
- crtc->primary->fb->format->format);
+ dev_dbg(sdev->dev, "mode_set: unsupported format %p4cc\n",
+ &crtc->primary->fb->format->format);
return -EINVAL;
}
@@ -477,16 +479,41 @@ static const struct drm_crtc_funcs crtc_funcs = {
.disable_vblank = shmob_drm_disable_vblank,
};
+static const uint32_t modeset_formats[] = {
+ DRM_FORMAT_RGB565,
+ DRM_FORMAT_RGB888,
+ DRM_FORMAT_ARGB8888,
+ DRM_FORMAT_XRGB8888,
+};
+
+static const struct drm_plane_funcs primary_plane_funcs = {
+ DRM_PLANE_NON_ATOMIC_FUNCS,
+};
+
int shmob_drm_crtc_create(struct shmob_drm_device *sdev)
{
struct drm_crtc *crtc = &sdev->crtc.crtc;
+ struct drm_plane *primary;
int ret;
sdev->crtc.dpms = DRM_MODE_DPMS_OFF;
- ret = drm_crtc_init(sdev->ddev, crtc, &crtc_funcs);
- if (ret < 0)
+ primary = __drm_universal_plane_alloc(sdev->ddev, sizeof(*primary), 0,
+ 0, &primary_plane_funcs,
+ modeset_formats,
+ ARRAY_SIZE(modeset_formats),
+ NULL, DRM_PLANE_TYPE_PRIMARY,
+ NULL);
+ if (IS_ERR(primary))
+ return PTR_ERR(primary);
+
+ ret = drm_crtc_init_with_planes(sdev->ddev, crtc, primary, NULL,
+ &crtc_funcs, NULL);
+ if (ret < 0) {
+ drm_plane_cleanup(primary);
+ kfree(primary);
return ret;
+ }
drm_crtc_helper_add(crtc, &crtc_helper_funcs);
diff --git a/drivers/gpu/drm/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/shmobile/shmob_drm_drv.c
index faacfee24763..30493ce87419 100644
--- a/drivers/gpu/drm/shmobile/shmob_drm_drv.c
+++ b/drivers/gpu/drm/shmobile/shmob_drm_drv.c
@@ -16,6 +16,7 @@
#include <linux/slab.h>
#include <drm/drm_drv.h>
+#include <drm/drm_fbdev_generic.h>
#include <drm/drm_gem_dma_helper.h>
#include <drm/drm_module.h>
#include <drm/drm_probe_helper.h>
@@ -271,6 +272,8 @@ static int shmob_drm_probe(struct platform_device *pdev)
if (ret < 0)
goto err_irq_uninstall;
+ drm_fbdev_generic_setup(ddev, 16);
+
return 0;
err_irq_uninstall:
diff --git a/drivers/gpu/drm/shmobile/shmob_drm_kms.c b/drivers/gpu/drm/shmobile/shmob_drm_kms.c
index 60a2c8d8a0d9..99381cc0abf3 100644
--- a/drivers/gpu/drm/shmobile/shmob_drm_kms.c
+++ b/drivers/gpu/drm/shmobile/shmob_drm_kms.c
@@ -40,6 +40,11 @@ static const struct shmob_drm_format_info shmob_drm_format_infos[] = {
.yuv = false,
.lddfr = LDDFR_PKF_ARGB32,
}, {
+ .fourcc = DRM_FORMAT_XRGB8888,
+ .bpp = 32,
+ .yuv = false,
+ .lddfr = LDDFR_PKF_ARGB32,
+ }, {
.fourcc = DRM_FORMAT_NV12,
.bpp = 12,
.yuv = true,
@@ -96,8 +101,8 @@ shmob_drm_fb_create(struct drm_device *dev, struct drm_file *file_priv,
format = shmob_drm_format_info(mode_cmd->pixel_format);
if (format == NULL) {
- dev_dbg(dev->dev, "unsupported pixel format %08x\n",
- mode_cmd->pixel_format);
+ dev_dbg(dev->dev, "unsupported pixel format %p4cc\n",
+ &mode_cmd->pixel_format);
return ERR_PTR(-EINVAL);
}
diff --git a/drivers/gpu/drm/shmobile/shmob_drm_plane.c b/drivers/gpu/drm/shmobile/shmob_drm_plane.c
index 604ae23825da..850986cee848 100644
--- a/drivers/gpu/drm/shmobile/shmob_drm_plane.c
+++ b/drivers/gpu/drm/shmobile/shmob_drm_plane.c
@@ -80,6 +80,7 @@ static void __shmob_drm_plane_setup(struct shmob_drm_plane *splane,
format |= LDBBSIFR_SWPL | LDBBSIFR_SWPW | LDBBSIFR_SWPB;
break;
case DRM_FORMAT_ARGB8888:
+ case DRM_FORMAT_XRGB8888:
default:
format |= LDBBSIFR_SWPL;
break;
@@ -95,6 +96,9 @@ static void __shmob_drm_plane_setup(struct shmob_drm_plane *splane,
case DRM_FORMAT_ARGB8888:
format |= LDBBSIFR_AL_PK | LDBBSIFR_RY | LDDFR_PKF_ARGB32;
break;
+ case DRM_FORMAT_XRGB8888:
+ format |= LDBBSIFR_AL_1 | LDBBSIFR_RY | LDDFR_PKF_ARGB32;
+ break;
case DRM_FORMAT_NV12:
case DRM_FORMAT_NV21:
format |= LDBBSIFR_AL_1 | LDBBSIFR_CHRR_420;
@@ -231,6 +235,7 @@ static const uint32_t formats[] = {
DRM_FORMAT_RGB565,
DRM_FORMAT_RGB888,
DRM_FORMAT_ARGB8888,
+ DRM_FORMAT_XRGB8888,
DRM_FORMAT_NV12,
DRM_FORMAT_NV21,
DRM_FORMAT_NV16,
diff --git a/drivers/gpu/drm/solomon/ssd130x.h b/drivers/gpu/drm/solomon/ssd130x.h
index 03038c1b6476..db03ee5db392 100644
--- a/drivers/gpu/drm/solomon/ssd130x.h
+++ b/drivers/gpu/drm/solomon/ssd130x.h
@@ -10,8 +10,8 @@
* Copyright 2012 Free Electrons
*/
-#ifndef __SSD1307X_H__
-#define __SSD1307X_H__
+#ifndef __SSD130X_H__
+#define __SSD130X_H__
#include <drm/drm_connector.h>
#include <drm/drm_crtc.h>
@@ -94,4 +94,4 @@ struct ssd130x_device *ssd130x_probe(struct device *dev, struct regmap *regmap);
void ssd130x_remove(struct ssd130x_device *ssd130x);
void ssd130x_shutdown(struct ssd130x_device *ssd130x);
-#endif /* __SSD1307X_H__ */
+#endif /* __SSD130X_H__ */
diff --git a/drivers/gpu/drm/sti/sti_dvo.c b/drivers/gpu/drm/sti/sti_dvo.c
index 577c477b5f46..0c6679e361c8 100644
--- a/drivers/gpu/drm/sti/sti_dvo.c
+++ b/drivers/gpu/drm/sti/sti_dvo.c
@@ -8,7 +8,7 @@
#include <linux/component.h>
#include <linux/debugfs.h>
#include <linux/module.h>
-#include <linux/of_gpio.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <drm/drm_atomic_helper.h>
diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c
index 8539fe1fedc4..dc1562f14ceb 100644
--- a/drivers/gpu/drm/sti/sti_hdmi.c
+++ b/drivers/gpu/drm/sti/sti_hdmi.c
@@ -266,6 +266,7 @@ static void hdmi_active_area(struct sti_hdmi *hdmi)
*/
static void hdmi_config(struct sti_hdmi *hdmi)
{
+ struct drm_connector *connector = hdmi->drm_connector;
u32 conf;
DRM_DEBUG_DRIVER("\n");
@@ -275,7 +276,7 @@ static void hdmi_config(struct sti_hdmi *hdmi)
/* Select encryption type and the framing mode */
conf |= HDMI_CFG_ESS_NOT_OESS;
- if (hdmi->hdmi_monitor)
+ if (connector->display_info.is_hdmi)
conf |= HDMI_CFG_HDMI_NOT_DVI;
/* Set Hsync polarity */
@@ -985,15 +986,15 @@ static int sti_hdmi_connector_get_modes(struct drm_connector *connector)
if (!edid)
goto fail;
- hdmi->hdmi_monitor = drm_detect_hdmi_monitor(edid);
- DRM_DEBUG_KMS("%s : %dx%d cm\n",
- (hdmi->hdmi_monitor ? "hdmi monitor" : "dvi monitor"),
- edid->width_cm, edid->height_cm);
cec_notifier_set_phys_addr_from_edid(hdmi->notifier, edid);
count = drm_add_edid_modes(connector, edid);
drm_connector_update_edid_property(connector, edid);
+ DRM_DEBUG_KMS("%s : %dx%d cm\n",
+ (connector->display_info.is_hdmi ? "hdmi monitor" : "dvi monitor"),
+ edid->width_cm, edid->height_cm);
+
kfree(edid);
return count;
diff --git a/drivers/gpu/drm/sti/sti_hdmi.h b/drivers/gpu/drm/sti/sti_hdmi.h
index 05b2f3d0d48d..6d4c3f57bc46 100644
--- a/drivers/gpu/drm/sti/sti_hdmi.h
+++ b/drivers/gpu/drm/sti/sti_hdmi.h
@@ -57,7 +57,6 @@ struct hdmi_audio_params {
* @reset: reset control of the hdmi phy
* @ddc_adapt: i2c ddc adapter
* @colorspace: current colorspace selected
- * @hdmi_monitor: true if HDMI monitor detected else DVI monitor assumed
* @audio_pdev: ASoC hdmi-codec platform device
* @audio: hdmi audio parameters.
* @drm_connector: hdmi connector
@@ -83,7 +82,6 @@ struct sti_hdmi {
struct reset_control *reset;
struct i2c_adapter *ddc_adapt;
enum hdmi_colorspace colorspace;
- bool hdmi_monitor;
struct platform_device *audio_pdev;
struct hdmi_audio_params audio;
struct drm_connector *drm_connector;
diff --git a/drivers/gpu/drm/stm/drv.c b/drivers/gpu/drm/stm/drv.c
index 422220df7d8c..cb4404b3ce62 100644
--- a/drivers/gpu/drm/stm/drv.c
+++ b/drivers/gpu/drm/stm/drv.c
@@ -185,7 +185,7 @@ static int stm_drm_platform_probe(struct platform_device *pdev)
DRM_DEBUG("%s\n", __func__);
- ret = drm_aperture_remove_framebuffers(false, &drv_driver);
+ ret = drm_aperture_remove_framebuffers(&drv_driver);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/sun4i/Makefile b/drivers/gpu/drm/sun4i/Makefile
index 0d04f2447b01..bad7497a0d11 100644
--- a/drivers/gpu/drm/sun4i/Makefile
+++ b/drivers/gpu/drm/sun4i/Makefile
@@ -19,7 +19,7 @@ sun8i-mixer-y += sun8i_mixer.o sun8i_ui_layer.o \
sun8i_vi_scaler.o sun8i_csc.o
sun4i-tcon-y += sun4i_crtc.o
-sun4i-tcon-y += sun4i_dotclock.o
+sun4i-tcon-y += sun4i_tcon_dclk.o
sun4i-tcon-y += sun4i_lvds.o
sun4i-tcon-y += sun4i_tcon.o
sun4i-tcon-y += sun4i_rgb.o
diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c
index e49f78a6a8cf..daa7faf72a4b 100644
--- a/drivers/gpu/drm/sun4i/sun4i_drv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
@@ -98,7 +98,7 @@ static int sun4i_drv_bind(struct device *dev)
goto unbind_all;
/* Remove early framebuffers (ie. simplefb) */
- ret = drm_aperture_remove_framebuffers(false, &sun4i_drv_driver);
+ ret = drm_aperture_remove_framebuffers(&sun4i_drv_driver);
if (ret)
goto unbind_all;
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index 523a6d787921..6a52fb12cbfb 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -31,12 +31,12 @@
#include <uapi/drm/drm_mode.h>
#include "sun4i_crtc.h"
-#include "sun4i_dotclock.h"
#include "sun4i_drv.h"
#include "sun4i_lvds.h"
#include "sun4i_rgb.h"
#include "sun4i_tcon.h"
#include "sun6i_mipi_dsi.h"
+#include "sun4i_tcon_dclk.h"
#include "sun8i_tcon_top.h"
#include "sunxi_engine.h"
@@ -291,18 +291,6 @@ static int sun4i_tcon_get_clk_delay(const struct drm_display_mode *mode,
return delay;
}
-static void sun4i_tcon0_mode_set_common(struct sun4i_tcon *tcon,
- const struct drm_display_mode *mode)
-{
- /* Configure the dot clock */
- clk_set_rate(tcon->dclk, mode->crtc_clock * 1000);
-
- /* Set the resolution */
- regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG,
- SUN4I_TCON0_BASIC0_X(mode->crtc_hdisplay) |
- SUN4I_TCON0_BASIC0_Y(mode->crtc_vdisplay));
-}
-
static void sun4i_tcon0_mode_set_dithering(struct sun4i_tcon *tcon,
const struct drm_connector *connector)
{
@@ -367,10 +355,18 @@ static void sun4i_tcon0_mode_set_cpu(struct sun4i_tcon *tcon,
u32 block_space, start_delay;
u32 tcon_div;
+ /*
+ * dclk is required to run at 1/4 the DSI per-lane bit rate.
+ */
tcon->dclk_min_div = SUN6I_DSI_TCON_DIV;
tcon->dclk_max_div = SUN6I_DSI_TCON_DIV;
+ clk_set_rate(tcon->dclk, mode->crtc_clock * 1000 * (bpp / lanes)
+ / SUN6I_DSI_TCON_DIV);
- sun4i_tcon0_mode_set_common(tcon, mode);
+ /* Set the resolution */
+ regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG,
+ SUN4I_TCON0_BASIC0_X(mode->crtc_hdisplay) |
+ SUN4I_TCON0_BASIC0_Y(mode->crtc_vdisplay));
/* Set dithering if needed */
sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder));
@@ -438,7 +434,12 @@ static void sun4i_tcon0_mode_set_lvds(struct sun4i_tcon *tcon,
tcon->dclk_min_div = 7;
tcon->dclk_max_div = 7;
- sun4i_tcon0_mode_set_common(tcon, mode);
+ clk_set_rate(tcon->dclk, mode->crtc_clock * 1000);
+
+ /* Set the resolution */
+ regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG,
+ SUN4I_TCON0_BASIC0_X(mode->crtc_hdisplay) |
+ SUN4I_TCON0_BASIC0_Y(mode->crtc_vdisplay));
/* Set dithering if needed */
sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder));
@@ -515,7 +516,12 @@ static void sun4i_tcon0_mode_set_rgb(struct sun4i_tcon *tcon,
tcon->dclk_min_div = tcon->quirks->dclk_min_div;
tcon->dclk_max_div = 127;
- sun4i_tcon0_mode_set_common(tcon, mode);
+ clk_set_rate(tcon->dclk, mode->crtc_clock * 1000);
+
+ /* Set the resolution */
+ regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG,
+ SUN4I_TCON0_BASIC0_X(mode->crtc_hdisplay) |
+ SUN4I_TCON0_BASIC0_Y(mode->crtc_vdisplay));
/* Set dithering if needed */
sun4i_tcon0_mode_set_dithering(tcon, connector);
@@ -778,21 +784,19 @@ static irqreturn_t sun4i_tcon_handler(int irq, void *private)
static int sun4i_tcon_init_clocks(struct device *dev,
struct sun4i_tcon *tcon)
{
- tcon->clk = devm_clk_get(dev, "ahb");
+ tcon->clk = devm_clk_get_enabled(dev, "ahb");
if (IS_ERR(tcon->clk)) {
dev_err(dev, "Couldn't get the TCON bus clock\n");
return PTR_ERR(tcon->clk);
}
- clk_prepare_enable(tcon->clk);
if (tcon->quirks->has_channel_0) {
- tcon->sclk0 = devm_clk_get(dev, "tcon-ch0");
+ tcon->sclk0 = devm_clk_get_enabled(dev, "tcon-ch0");
if (IS_ERR(tcon->sclk0)) {
dev_err(dev, "Couldn't get the TCON channel 0 clock\n");
return PTR_ERR(tcon->sclk0);
}
}
- clk_prepare_enable(tcon->sclk0);
if (tcon->quirks->has_channel_1) {
tcon->sclk1 = devm_clk_get(dev, "tcon-ch1");
@@ -805,12 +809,6 @@ static int sun4i_tcon_init_clocks(struct device *dev,
return 0;
}
-static void sun4i_tcon_free_clocks(struct sun4i_tcon *tcon)
-{
- clk_disable_unprepare(tcon->sclk0);
- clk_disable_unprepare(tcon->clk);
-}
-
static int sun4i_tcon_init_irq(struct device *dev,
struct sun4i_tcon *tcon)
{
@@ -1223,28 +1221,28 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
ret = sun4i_tcon_init_regmap(dev, tcon);
if (ret) {
dev_err(dev, "Couldn't init our TCON regmap\n");
- goto err_free_clocks;
+ goto err_assert_reset;
}
if (tcon->quirks->has_channel_0) {
ret = sun4i_dclk_create(dev, tcon);
if (ret) {
dev_err(dev, "Couldn't create our TCON dot clock\n");
- goto err_free_clocks;
+ goto err_assert_reset;
}
}
ret = sun4i_tcon_init_irq(dev, tcon);
if (ret) {
dev_err(dev, "Couldn't init our TCON interrupts\n");
- goto err_free_dotclock;
+ goto err_free_dclk;
}
tcon->crtc = sun4i_crtc_init(drm, engine, tcon);
if (IS_ERR(tcon->crtc)) {
dev_err(dev, "Couldn't create our CRTC\n");
ret = PTR_ERR(tcon->crtc);
- goto err_free_dotclock;
+ goto err_free_dclk;
}
if (tcon->quirks->has_channel_0) {
@@ -1264,7 +1262,7 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
of_node_put(remote);
if (ret < 0)
- goto err_free_dotclock;
+ goto err_free_dclk;
}
if (tcon->quirks->needs_de_be_mux) {
@@ -1290,11 +1288,9 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
return 0;
-err_free_dotclock:
+err_free_dclk:
if (tcon->quirks->has_channel_0)
sun4i_dclk_free(tcon);
-err_free_clocks:
- sun4i_tcon_free_clocks(tcon);
err_assert_reset:
reset_control_assert(tcon->lcd_rst);
return ret;
@@ -1308,7 +1304,6 @@ static void sun4i_tcon_unbind(struct device *dev, struct device *master,
list_del(&tcon->list);
if (tcon->quirks->has_channel_0)
sun4i_dclk_free(tcon);
- sun4i_tcon_free_clocks(tcon);
}
static const struct component_ops sun4i_tcon_ops = {
diff --git a/drivers/gpu/drm/sun4i/sun4i_dotclock.c b/drivers/gpu/drm/sun4i/sun4i_tcon_dclk.c
index 417ade3d2565..03d7de1911cd 100644
--- a/drivers/gpu/drm/sun4i/sun4i_dotclock.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon_dclk.c
@@ -10,7 +10,7 @@
#include <linux/regmap.h>
#include "sun4i_tcon.h"
-#include "sun4i_dotclock.h"
+#include "sun4i_tcon_dclk.h"
struct sun4i_dclk {
struct clk_hw hw;
diff --git a/drivers/gpu/drm/sun4i/sun4i_dotclock.h b/drivers/gpu/drm/sun4i/sun4i_tcon_dclk.h
index ac60da2455ca..ac60da2455ca 100644
--- a/drivers/gpu/drm/sun4i/sun4i_dotclock.h
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon_dclk.h
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
index 85ba96cddd51..35ff303c6674 100644
--- a/drivers/gpu/drm/tegra/drm.c
+++ b/drivers/gpu/drm/tegra/drm.c
@@ -1244,7 +1244,7 @@ static int host1x_drm_probe(struct host1x_device *dev)
drm_mode_config_reset(drm);
- err = drm_aperture_remove_framebuffers(false, &tegra_drm_driver);
+ err = drm_aperture_remove_framebuffers(&tegra_drm_driver);
if (err < 0)
goto hub;
diff --git a/drivers/gpu/drm/tests/drm_rect_test.c b/drivers/gpu/drm/tests/drm_rect_test.c
index e9809ea32696..76332cd2ead8 100644
--- a/drivers/gpu/drm/tests/drm_rect_test.c
+++ b/drivers/gpu/drm/tests/drm_rect_test.c
@@ -8,6 +8,19 @@
#include <kunit/test.h>
#include <drm/drm_rect.h>
+#include <drm/drm_mode.h>
+
+#include <linux/string_helpers.h>
+#include <linux/errno.h>
+
+static void drm_rect_compare(struct kunit *test, const struct drm_rect *r,
+ const struct drm_rect *expected)
+{
+ KUNIT_EXPECT_EQ(test, r->x1, expected->x1);
+ KUNIT_EXPECT_EQ(test, r->y1, expected->y1);
+ KUNIT_EXPECT_EQ(test, drm_rect_width(r), drm_rect_width(expected));
+ KUNIT_EXPECT_EQ(test, drm_rect_height(r), drm_rect_height(expected));
+}
static void drm_test_rect_clip_scaled_div_by_zero(struct kunit *test)
{
@@ -196,11 +209,313 @@ static void drm_test_rect_clip_scaled_signed_vs_unsigned(struct kunit *test)
KUNIT_EXPECT_FALSE_MSG(test, drm_rect_visible(&src), "Source should not be visible\n");
}
+struct drm_rect_intersect_case {
+ const char *description;
+ struct drm_rect r1, r2;
+ bool should_be_visible;
+ struct drm_rect expected_intersection;
+};
+
+static const struct drm_rect_intersect_case drm_rect_intersect_cases[] = {
+ {
+ .description = "top-left x bottom-right",
+ .r1 = DRM_RECT_INIT(1, 1, 2, 2),
+ .r2 = DRM_RECT_INIT(0, 0, 2, 2),
+ .should_be_visible = true,
+ .expected_intersection = DRM_RECT_INIT(1, 1, 1, 1),
+ },
+ {
+ .description = "top-right x bottom-left",
+ .r1 = DRM_RECT_INIT(0, 0, 2, 2),
+ .r2 = DRM_RECT_INIT(1, -1, 2, 2),
+ .should_be_visible = true,
+ .expected_intersection = DRM_RECT_INIT(1, 0, 1, 1),
+ },
+ {
+ .description = "bottom-left x top-right",
+ .r1 = DRM_RECT_INIT(1, -1, 2, 2),
+ .r2 = DRM_RECT_INIT(0, 0, 2, 2),
+ .should_be_visible = true,
+ .expected_intersection = DRM_RECT_INIT(1, 0, 1, 1),
+ },
+ {
+ .description = "bottom-right x top-left",
+ .r1 = DRM_RECT_INIT(0, 0, 2, 2),
+ .r2 = DRM_RECT_INIT(1, 1, 2, 2),
+ .should_be_visible = true,
+ .expected_intersection = DRM_RECT_INIT(1, 1, 1, 1),
+ },
+ {
+ .description = "right x left",
+ .r1 = DRM_RECT_INIT(0, 0, 2, 1),
+ .r2 = DRM_RECT_INIT(1, 0, 3, 1),
+ .should_be_visible = true,
+ .expected_intersection = DRM_RECT_INIT(1, 0, 1, 1),
+ },
+ {
+ .description = "left x right",
+ .r1 = DRM_RECT_INIT(1, 0, 3, 1),
+ .r2 = DRM_RECT_INIT(0, 0, 2, 1),
+ .should_be_visible = true,
+ .expected_intersection = DRM_RECT_INIT(1, 0, 1, 1),
+ },
+ {
+ .description = "up x bottom",
+ .r1 = DRM_RECT_INIT(0, 0, 1, 2),
+ .r2 = DRM_RECT_INIT(0, -1, 1, 3),
+ .should_be_visible = true,
+ .expected_intersection = DRM_RECT_INIT(0, 0, 1, 2),
+ },
+ {
+ .description = "bottom x up",
+ .r1 = DRM_RECT_INIT(0, -1, 1, 3),
+ .r2 = DRM_RECT_INIT(0, 0, 1, 2),
+ .should_be_visible = true,
+ .expected_intersection = DRM_RECT_INIT(0, 0, 1, 2),
+ },
+ {
+ .description = "touching corner",
+ .r1 = DRM_RECT_INIT(0, 0, 1, 1),
+ .r2 = DRM_RECT_INIT(1, 1, 2, 2),
+ .should_be_visible = false,
+ .expected_intersection = DRM_RECT_INIT(1, 1, 0, 0),
+ },
+ {
+ .description = "touching side",
+ .r1 = DRM_RECT_INIT(0, 0, 1, 1),
+ .r2 = DRM_RECT_INIT(1, 0, 1, 1),
+ .should_be_visible = false,
+ .expected_intersection = DRM_RECT_INIT(1, 0, 0, 1),
+ },
+ {
+ .description = "equal rects",
+ .r1 = DRM_RECT_INIT(0, 0, 2, 2),
+ .r2 = DRM_RECT_INIT(0, 0, 2, 2),
+ .should_be_visible = true,
+ .expected_intersection = DRM_RECT_INIT(0, 0, 2, 2),
+ },
+ {
+ .description = "inside another",
+ .r1 = DRM_RECT_INIT(0, 0, 2, 2),
+ .r2 = DRM_RECT_INIT(1, 1, 1, 1),
+ .should_be_visible = true,
+ .expected_intersection = DRM_RECT_INIT(1, 1, 1, 1),
+ },
+ {
+ .description = "far away",
+ .r1 = DRM_RECT_INIT(0, 0, 1, 1),
+ .r2 = DRM_RECT_INIT(3, 6, 1, 1),
+ .should_be_visible = false,
+ .expected_intersection = DRM_RECT_INIT(3, 6, -2, -5),
+ },
+ {
+ .description = "points intersecting",
+ .r1 = DRM_RECT_INIT(5, 10, 0, 0),
+ .r2 = DRM_RECT_INIT(5, 10, 0, 0),
+ .should_be_visible = false,
+ .expected_intersection = DRM_RECT_INIT(5, 10, 0, 0),
+ },
+ {
+ .description = "points not intersecting",
+ .r1 = DRM_RECT_INIT(0, 0, 0, 0),
+ .r2 = DRM_RECT_INIT(5, 10, 0, 0),
+ .should_be_visible = false,
+ .expected_intersection = DRM_RECT_INIT(5, 10, -5, -10),
+ },
+};
+
+static void drm_rect_intersect_case_desc(const struct drm_rect_intersect_case *t, char *desc)
+{
+ snprintf(desc, KUNIT_PARAM_DESC_SIZE,
+ "%s: " DRM_RECT_FMT " x " DRM_RECT_FMT,
+ t->description, DRM_RECT_ARG(&t->r1), DRM_RECT_ARG(&t->r2));
+}
+
+KUNIT_ARRAY_PARAM(drm_rect_intersect, drm_rect_intersect_cases, drm_rect_intersect_case_desc);
+
+static void drm_test_rect_intersect(struct kunit *test)
+{
+ const struct drm_rect_intersect_case *params = test->param_value;
+ struct drm_rect r1_aux = params->r1;
+ bool visible;
+
+ visible = drm_rect_intersect(&r1_aux, &params->r2);
+
+ KUNIT_EXPECT_EQ(test, visible, params->should_be_visible);
+ drm_rect_compare(test, &r1_aux, &params->expected_intersection);
+}
+
+struct drm_rect_scale_case {
+ const char *name;
+ struct drm_rect src, dst;
+ int min_range, max_range;
+ int expected_scaling_factor;
+};
+
+static const struct drm_rect_scale_case drm_rect_scale_cases[] = {
+ {
+ .name = "normal use",
+ .src = DRM_RECT_INIT(0, 0, 2 << 16, 2 << 16),
+ .dst = DRM_RECT_INIT(0, 0, 1 << 16, 1 << 16),
+ .min_range = 0, .max_range = INT_MAX,
+ .expected_scaling_factor = 2,
+ },
+ {
+ .name = "out of max range",
+ .src = DRM_RECT_INIT(0, 0, 10 << 16, 10 << 16),
+ .dst = DRM_RECT_INIT(0, 0, 1 << 16, 1 << 16),
+ .min_range = 3, .max_range = 5,
+ .expected_scaling_factor = -ERANGE,
+ },
+ {
+ .name = "out of min range",
+ .src = DRM_RECT_INIT(0, 0, 2 << 16, 2 << 16),
+ .dst = DRM_RECT_INIT(0, 0, 1 << 16, 1 << 16),
+ .min_range = 3, .max_range = 5,
+ .expected_scaling_factor = -ERANGE,
+ },
+ {
+ .name = "zero dst",
+ .src = DRM_RECT_INIT(0, 0, 2 << 16, 2 << 16),
+ .dst = DRM_RECT_INIT(0, 0, 0 << 16, 0 << 16),
+ .min_range = 0, .max_range = INT_MAX,
+ .expected_scaling_factor = 0,
+ },
+ {
+ .name = "negative src",
+ .src = DRM_RECT_INIT(0, 0, -(1 << 16), -(1 << 16)),
+ .dst = DRM_RECT_INIT(0, 0, 1 << 16, 1 << 16),
+ .min_range = 0, .max_range = INT_MAX,
+ .expected_scaling_factor = -EINVAL,
+ },
+ {
+ .name = "negative dst",
+ .src = DRM_RECT_INIT(0, 0, 1 << 16, 1 << 16),
+ .dst = DRM_RECT_INIT(0, 0, -(1 << 16), -(1 << 16)),
+ .min_range = 0, .max_range = INT_MAX,
+ .expected_scaling_factor = -EINVAL,
+ },
+};
+
+static void drm_rect_scale_case_desc(const struct drm_rect_scale_case *t, char *desc)
+{
+ strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE);
+}
+
+KUNIT_ARRAY_PARAM(drm_rect_scale, drm_rect_scale_cases, drm_rect_scale_case_desc);
+
+static void drm_test_rect_calc_hscale(struct kunit *test)
+{
+ const struct drm_rect_scale_case *params = test->param_value;
+ int scaling_factor;
+
+ scaling_factor = drm_rect_calc_hscale(&params->src, &params->dst,
+ params->min_range, params->max_range);
+
+ KUNIT_EXPECT_EQ(test, scaling_factor, params->expected_scaling_factor);
+}
+
+static void drm_test_rect_calc_vscale(struct kunit *test)
+{
+ const struct drm_rect_scale_case *params = test->param_value;
+ int scaling_factor;
+
+ scaling_factor = drm_rect_calc_vscale(&params->src, &params->dst,
+ params->min_range, params->max_range);
+
+ KUNIT_EXPECT_EQ(test, scaling_factor, params->expected_scaling_factor);
+}
+
+struct drm_rect_rotate_case {
+ const char *name;
+ unsigned int rotation;
+ struct drm_rect rect;
+ int width, height;
+ struct drm_rect expected;
+};
+
+static const struct drm_rect_rotate_case drm_rect_rotate_cases[] = {
+ {
+ .name = "reflect-x",
+ .rotation = DRM_MODE_REFLECT_X,
+ .rect = DRM_RECT_INIT(0, 0, 5, 5),
+ .width = 5, .height = 10,
+ .expected = DRM_RECT_INIT(0, 0, 5, 5),
+ },
+ {
+ .name = "reflect-y",
+ .rotation = DRM_MODE_REFLECT_Y,
+ .rect = DRM_RECT_INIT(2, 0, 5, 5),
+ .width = 5, .height = 10,
+ .expected = DRM_RECT_INIT(2, 5, 5, 5),
+ },
+ {
+ .name = "rotate-0",
+ .rotation = DRM_MODE_ROTATE_0,
+ .rect = DRM_RECT_INIT(0, 2, 5, 5),
+ .width = 5, .height = 10,
+ .expected = DRM_RECT_INIT(0, 2, 5, 5),
+ },
+ {
+ .name = "rotate-90",
+ .rotation = DRM_MODE_ROTATE_90,
+ .rect = DRM_RECT_INIT(0, 0, 5, 10),
+ .width = 5, .height = 10,
+ .expected = DRM_RECT_INIT(0, 0, 10, 5),
+ },
+ {
+ .name = "rotate-180",
+ .rotation = DRM_MODE_ROTATE_180,
+ .rect = DRM_RECT_INIT(11, 3, 5, 10),
+ .width = 5, .height = 10,
+ .expected = DRM_RECT_INIT(-11, -3, 5, 10),
+ },
+ {
+ .name = "rotate-270",
+ .rotation = DRM_MODE_ROTATE_270,
+ .rect = DRM_RECT_INIT(6, 3, 5, 10),
+ .width = 5, .height = 10,
+ .expected = DRM_RECT_INIT(-3, 6, 10, 5),
+ },
+};
+
+static void drm_rect_rotate_case_desc(const struct drm_rect_rotate_case *t, char *desc)
+{
+ strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE);
+}
+
+KUNIT_ARRAY_PARAM(drm_rect_rotate, drm_rect_rotate_cases, drm_rect_rotate_case_desc);
+
+static void drm_test_rect_rotate(struct kunit *test)
+{
+ const struct drm_rect_rotate_case *params = test->param_value;
+ struct drm_rect r = params->rect;
+
+ drm_rect_rotate(&r, params->width, params->height, params->rotation);
+
+ drm_rect_compare(test, &r, &params->expected);
+}
+
+static void drm_test_rect_rotate_inv(struct kunit *test)
+{
+ const struct drm_rect_rotate_case *params = test->param_value;
+ struct drm_rect r = params->expected;
+
+ drm_rect_rotate_inv(&r, params->width, params->height, params->rotation);
+
+ drm_rect_compare(test, &r, &params->rect);
+}
+
static struct kunit_case drm_rect_tests[] = {
KUNIT_CASE(drm_test_rect_clip_scaled_div_by_zero),
KUNIT_CASE(drm_test_rect_clip_scaled_not_clipped),
KUNIT_CASE(drm_test_rect_clip_scaled_clipped),
KUNIT_CASE(drm_test_rect_clip_scaled_signed_vs_unsigned),
+ KUNIT_CASE_PARAM(drm_test_rect_intersect, drm_rect_intersect_gen_params),
+ KUNIT_CASE_PARAM(drm_test_rect_calc_hscale, drm_rect_scale_gen_params),
+ KUNIT_CASE_PARAM(drm_test_rect_calc_vscale, drm_rect_scale_gen_params),
+ KUNIT_CASE_PARAM(drm_test_rect_rotate, drm_rect_rotate_gen_params),
+ KUNIT_CASE_PARAM(drm_test_rect_rotate_inv, drm_rect_rotate_gen_params),
{ }
};
diff --git a/drivers/gpu/drm/ttm/ttm_device.c b/drivers/gpu/drm/ttm/ttm_device.c
index 64a59f46f6c3..df4cf5468e7f 100644
--- a/drivers/gpu/drm/ttm/ttm_device.c
+++ b/drivers/gpu/drm/ttm/ttm_device.c
@@ -189,7 +189,7 @@ EXPORT_SYMBOL(ttm_device_swapout);
* Returns:
* !0: Failure.
*/
-int ttm_device_init(struct ttm_device *bdev, struct ttm_device_funcs *funcs,
+int ttm_device_init(struct ttm_device *bdev, const struct ttm_device_funcs *funcs,
struct device *dev, struct address_space *mapping,
struct drm_vma_offset_manager *vma_manager,
bool use_dma_alloc, bool use_dma32)
diff --git a/drivers/gpu/drm/tve200/tve200_drv.c b/drivers/gpu/drm/tve200/tve200_drv.c
index abd557332b28..40b1168ad671 100644
--- a/drivers/gpu/drm/tve200/tve200_drv.c
+++ b/drivers/gpu/drm/tve200/tve200_drv.c
@@ -156,7 +156,6 @@ static int tve200_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct tve200_drm_dev_private *priv;
struct drm_device *drm;
- struct resource *res;
int irq;
int ret;
@@ -192,8 +191,7 @@ static int tve200_probe(struct platform_device *pdev)
goto clk_disable;
}
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- priv->regs = devm_ioremap_resource(dev, res);
+ priv->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(priv->regs)) {
dev_err(dev, "%s failed mmio\n", __func__);
ret = -EINVAL;
diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c
index 061cb88c08a2..3ebe2ce55dfd 100644
--- a/drivers/gpu/drm/udl/udl_main.c
+++ b/drivers/gpu/drm/udl/udl_main.c
@@ -255,7 +255,7 @@ static struct urb *udl_get_urb_locked(struct udl_device *udl, long timeout)
list_del_init(&unode->entry);
udl->urbs.available--;
- return unode ? unode->urb : NULL;
+ return unode->urb;
}
#define GET_URB_TIMEOUT HZ
diff --git a/drivers/gpu/drm/vc4/tests/vc4_mock.h b/drivers/gpu/drm/vc4/tests/vc4_mock.h
index db8e9a141ef8..2d0b339bd9f3 100644
--- a/drivers/gpu/drm/vc4/tests/vc4_mock.h
+++ b/drivers/gpu/drm/vc4/tests/vc4_mock.h
@@ -43,6 +43,9 @@ struct vc4_dummy_output {
struct drm_connector connector;
};
+#define encoder_to_vc4_dummy_output(_enc) \
+ container_of_const(_enc, struct vc4_dummy_output, encoder.base)
+
struct vc4_dummy_output *vc4_dummy_output(struct kunit *test,
struct drm_device *drm,
struct drm_crtc *crtc,
diff --git a/drivers/gpu/drm/vc4/tests/vc4_mock_output.c b/drivers/gpu/drm/vc4/tests/vc4_mock_output.c
index 8d33be828d9a..6e11fcc9ef45 100644
--- a/drivers/gpu/drm/vc4/tests/vc4_mock_output.c
+++ b/drivers/gpu/drm/vc4/tests/vc4_mock_output.c
@@ -80,7 +80,7 @@ int vc4_mock_atomic_add_output(struct kunit *test,
crtc = vc4_find_crtc_for_encoder(test, drm, encoder);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc);
- output = container_of(encoder, struct vc4_dummy_output, encoder.base);
+ output = encoder_to_vc4_dummy_output(encoder);
conn = &output->connector;
conn_state = drm_atomic_get_connector_state(state, conn);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
@@ -126,7 +126,7 @@ int vc4_mock_atomic_del_output(struct kunit *test,
ret = drm_atomic_set_mode_for_crtc(crtc_state, NULL);
KUNIT_ASSERT_EQ(test, ret, 0);
- output = container_of(encoder, struct vc4_dummy_output, encoder.base);
+ output = encoder_to_vc4_dummy_output(encoder);
conn = &output->connector;
conn_state = drm_atomic_get_connector_state(state, conn);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
diff --git a/drivers/gpu/drm/vc4/vc4_dpi.c b/drivers/gpu/drm/vc4/vc4_dpi.c
index f518d6e59ed6..e68c07d86040 100644
--- a/drivers/gpu/drm/vc4/vc4_dpi.c
+++ b/drivers/gpu/drm/vc4/vc4_dpi.c
@@ -97,11 +97,8 @@ struct vc4_dpi {
struct debugfs_regset32 regset;
};
-static inline struct vc4_dpi *
-to_vc4_dpi(struct drm_encoder *encoder)
-{
- return container_of(encoder, struct vc4_dpi, encoder.base);
-}
+#define to_vc4_dpi(_encoder) \
+ container_of_const(_encoder, struct vc4_dpi, encoder.base)
#define DPI_READ(offset) \
({ \
diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
index c8bf954042e0..823395c23cc3 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.c
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -350,7 +350,7 @@ static int vc4_drm_bind(struct device *dev)
return -EPROBE_DEFER;
}
- ret = drm_aperture_remove_framebuffers(false, driver);
+ ret = drm_aperture_remove_framebuffers(driver);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 8768566c610b..bf66499765fb 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -232,11 +232,8 @@ struct vc4_dev {
struct kref bin_bo_kref;
};
-static inline struct vc4_dev *
-to_vc4_dev(const struct drm_device *dev)
-{
- return container_of(dev, struct vc4_dev, base);
-}
+#define to_vc4_dev(_dev) \
+ container_of_const(_dev, struct vc4_dev, base)
struct vc4_bo {
struct drm_gem_dma_object base;
@@ -285,11 +282,8 @@ struct vc4_bo {
struct mutex madv_lock;
};
-static inline struct vc4_bo *
-to_vc4_bo(const struct drm_gem_object *bo)
-{
- return container_of(to_drm_gem_dma_obj(bo), struct vc4_bo, base);
-}
+#define to_vc4_bo(_bo) \
+ container_of_const(to_drm_gem_dma_obj(_bo), struct vc4_bo, base)
struct vc4_fence {
struct dma_fence base;
@@ -298,11 +292,8 @@ struct vc4_fence {
uint64_t seqno;
};
-static inline struct vc4_fence *
-to_vc4_fence(const struct dma_fence *fence)
-{
- return container_of(fence, struct vc4_fence, base);
-}
+#define to_vc4_fence(_fence) \
+ container_of_const(_fence, struct vc4_fence, base)
struct vc4_seqno_cb {
struct work_struct work;
@@ -368,11 +359,8 @@ struct vc4_hvs_state {
} fifo_state[HVS_NUM_CHANNELS];
};
-static inline struct vc4_hvs_state *
-to_vc4_hvs_state(const struct drm_private_state *priv)
-{
- return container_of(priv, struct vc4_hvs_state, base);
-}
+#define to_vc4_hvs_state(_state) \
+ container_of_const(_state, struct vc4_hvs_state, base)
struct vc4_hvs_state *vc4_hvs_get_global_state(struct drm_atomic_state *state);
struct vc4_hvs_state *vc4_hvs_get_old_global_state(const struct drm_atomic_state *state);
@@ -382,11 +370,8 @@ struct vc4_plane {
struct drm_plane base;
};
-static inline struct vc4_plane *
-to_vc4_plane(const struct drm_plane *plane)
-{
- return container_of(plane, struct vc4_plane, base);
-}
+#define to_vc4_plane(_plane) \
+ container_of_const(_plane, struct vc4_plane, base)
enum vc4_scaling_mode {
VC4_SCALING_NONE,
@@ -458,11 +443,8 @@ struct vc4_plane_state {
u64 membus_load;
};
-static inline struct vc4_plane_state *
-to_vc4_plane_state(const struct drm_plane_state *state)
-{
- return container_of(state, struct vc4_plane_state, base);
-}
+#define to_vc4_plane_state(_state) \
+ container_of_const(_state, struct vc4_plane_state, base)
enum vc4_encoder_type {
VC4_ENCODER_TYPE_NONE,
@@ -489,11 +471,8 @@ struct vc4_encoder {
void (*post_crtc_powerdown)(struct drm_encoder *encoder, struct drm_atomic_state *state);
};
-static inline struct vc4_encoder *
-to_vc4_encoder(const struct drm_encoder *encoder)
-{
- return container_of(encoder, struct vc4_encoder, base);
-}
+#define to_vc4_encoder(_encoder) \
+ container_of_const(_encoder, struct vc4_encoder, base)
static inline
struct drm_encoder *vc4_find_encoder_by_type(struct drm_device *drm,
@@ -591,11 +570,8 @@ struct vc4_crtc {
unsigned int current_hvs_channel;
};
-static inline struct vc4_crtc *
-to_vc4_crtc(const struct drm_crtc *crtc)
-{
- return container_of(crtc, struct vc4_crtc, base);
-}
+#define to_vc4_crtc(_crtc) \
+ container_of_const(_crtc, struct vc4_crtc, base)
static inline const struct vc4_crtc_data *
vc4_crtc_to_vc4_crtc_data(const struct vc4_crtc *crtc)
@@ -608,7 +584,7 @@ vc4_crtc_to_vc4_pv_data(const struct vc4_crtc *crtc)
{
const struct vc4_crtc_data *data = vc4_crtc_to_vc4_crtc_data(crtc);
- return container_of(data, struct vc4_pv_data, base);
+ return container_of_const(data, struct vc4_pv_data, base);
}
struct drm_encoder *vc4_get_crtc_encoder(struct drm_crtc *crtc,
@@ -636,11 +612,8 @@ struct vc4_crtc_state {
#define VC4_HVS_CHANNEL_DISABLED ((unsigned int)-1)
-static inline struct vc4_crtc_state *
-to_vc4_crtc_state(const struct drm_crtc_state *crtc_state)
-{
- return container_of(crtc_state, struct vc4_crtc_state, base);
-}
+#define to_vc4_crtc_state(_state) \
+ container_of_const(_state, struct vc4_crtc_state, base)
#define V3D_READ(offset) \
({ \
diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c
index a5c075f802e4..9e0c355b236f 100644
--- a/drivers/gpu/drm/vc4/vc4_dsi.c
+++ b/drivers/gpu/drm/vc4/vc4_dsi.c
@@ -600,19 +600,14 @@ struct vc4_dsi {
struct debugfs_regset32 regset;
};
-#define host_to_dsi(host) container_of(host, struct vc4_dsi, dsi_host)
+#define host_to_dsi(host) \
+ container_of_const(host, struct vc4_dsi, dsi_host)
-static inline struct vc4_dsi *
-to_vc4_dsi(struct drm_encoder *encoder)
-{
- return container_of(encoder, struct vc4_dsi, encoder.base);
-}
+#define to_vc4_dsi(_encoder) \
+ container_of_const(_encoder, struct vc4_dsi, encoder.base)
-static inline struct vc4_dsi *
-bridge_to_vc4_dsi(struct drm_bridge *bridge)
-{
- return container_of(bridge, struct vc4_dsi, bridge);
-}
+#define bridge_to_vc4_dsi(_bridge) \
+ container_of_const(_bridge, struct vc4_dsi, bridge)
static inline void
dsi_dma_workaround_write(struct vc4_dsi *dsi, u32 offset, u32 val)
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 06713d8b82b5..6da41ea1250a 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -153,11 +153,17 @@ static bool vc4_hdmi_mode_needs_scrambling(const struct drm_display_mode *mode,
return clock > HDMI_14_MAX_TMDS_CLK;
}
-static bool vc4_hdmi_is_full_range_rgb(struct vc4_hdmi *vc4_hdmi,
- const struct drm_display_mode *mode)
+static bool vc4_hdmi_is_full_range(struct vc4_hdmi *vc4_hdmi,
+ struct vc4_hdmi_connector_state *vc4_state)
{
+ const struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode;
struct drm_display_info *display = &vc4_hdmi->connector.display_info;
+ if (vc4_state->broadcast_rgb == VC4_HDMI_BROADCAST_RGB_LIMITED)
+ return false;
+ else if (vc4_state->broadcast_rgb == VC4_HDMI_BROADCAST_RGB_FULL)
+ return true;
+
return !display->is_hdmi ||
drm_default_rgb_quant_range(mode) == HDMI_QUANTIZATION_RANGE_FULL;
}
@@ -528,14 +534,45 @@ static int vc4_hdmi_connector_atomic_check(struct drm_connector *connector,
{
struct drm_connector_state *old_state =
drm_atomic_get_old_connector_state(state, connector);
+ struct vc4_hdmi_connector_state *old_vc4_state =
+ conn_state_to_vc4_hdmi_conn_state(old_state);
struct drm_connector_state *new_state =
drm_atomic_get_new_connector_state(state, connector);
+ struct vc4_hdmi_connector_state *new_vc4_state =
+ conn_state_to_vc4_hdmi_conn_state(new_state);
struct drm_crtc *crtc = new_state->crtc;
if (!crtc)
return 0;
+ if (old_state->tv.margins.left != new_state->tv.margins.left ||
+ old_state->tv.margins.right != new_state->tv.margins.right ||
+ old_state->tv.margins.top != new_state->tv.margins.top ||
+ old_state->tv.margins.bottom != new_state->tv.margins.bottom) {
+ struct drm_crtc_state *crtc_state;
+ int ret;
+
+ crtc_state = drm_atomic_get_crtc_state(state, crtc);
+ if (IS_ERR(crtc_state))
+ return PTR_ERR(crtc_state);
+
+ /*
+ * Strictly speaking, we should be calling
+ * drm_atomic_helper_check_planes() after our call to
+ * drm_atomic_add_affected_planes(). However, the
+ * connector atomic_check is called as part of
+ * drm_atomic_helper_check_modeset() that already
+ * happens before a call to
+ * drm_atomic_helper_check_planes() in
+ * drm_atomic_helper_check().
+ */
+ ret = drm_atomic_add_affected_planes(state, crtc);
+ if (ret)
+ return ret;
+ }
+
if (old_state->colorspace != new_state->colorspace ||
+ old_vc4_state->broadcast_rgb != new_vc4_state->broadcast_rgb ||
!drm_connector_atomic_hdr_metadata_equal(old_state, new_state)) {
struct drm_crtc_state *crtc_state;
@@ -549,6 +586,49 @@ static int vc4_hdmi_connector_atomic_check(struct drm_connector *connector,
return 0;
}
+static int vc4_hdmi_connector_get_property(struct drm_connector *connector,
+ const struct drm_connector_state *state,
+ struct drm_property *property,
+ uint64_t *val)
+{
+ struct drm_device *drm = connector->dev;
+ struct vc4_hdmi *vc4_hdmi =
+ connector_to_vc4_hdmi(connector);
+ const struct vc4_hdmi_connector_state *vc4_conn_state =
+ conn_state_to_vc4_hdmi_conn_state(state);
+
+ if (property == vc4_hdmi->broadcast_rgb_property) {
+ *val = vc4_conn_state->broadcast_rgb;
+ } else {
+ drm_dbg(drm, "Unknown property [PROP:%d:%s]\n",
+ property->base.id, property->name);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int vc4_hdmi_connector_set_property(struct drm_connector *connector,
+ struct drm_connector_state *state,
+ struct drm_property *property,
+ uint64_t val)
+{
+ struct drm_device *drm = connector->dev;
+ struct vc4_hdmi *vc4_hdmi =
+ connector_to_vc4_hdmi(connector);
+ struct vc4_hdmi_connector_state *vc4_conn_state =
+ conn_state_to_vc4_hdmi_conn_state(state);
+
+ if (property == vc4_hdmi->broadcast_rgb_property) {
+ vc4_conn_state->broadcast_rgb = val;
+ return 0;
+ }
+
+ drm_dbg(drm, "Unknown property [PROP:%d:%s]\n",
+ property->base.id, property->name);
+ return -EINVAL;
+}
+
static void vc4_hdmi_connector_reset(struct drm_connector *connector)
{
struct vc4_hdmi_connector_state *old_state =
@@ -568,6 +648,7 @@ static void vc4_hdmi_connector_reset(struct drm_connector *connector)
new_state->base.max_bpc = 8;
new_state->base.max_requested_bpc = 8;
new_state->output_format = VC4_HDMI_OUTPUT_RGB;
+ new_state->broadcast_rgb = VC4_HDMI_BROADCAST_RGB_AUTO;
drm_atomic_helper_connector_tv_margins_reset(connector);
}
@@ -585,6 +666,7 @@ vc4_hdmi_connector_duplicate_state(struct drm_connector *connector)
new_state->tmds_char_rate = vc4_state->tmds_char_rate;
new_state->output_bpc = vc4_state->output_bpc;
new_state->output_format = vc4_state->output_format;
+ new_state->broadcast_rgb = vc4_state->broadcast_rgb;
__drm_atomic_helper_connector_duplicate_state(connector, &new_state->base);
return &new_state->base;
@@ -595,6 +677,8 @@ static const struct drm_connector_funcs vc4_hdmi_connector_funcs = {
.reset = vc4_hdmi_connector_reset,
.atomic_duplicate_state = vc4_hdmi_connector_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+ .atomic_get_property = vc4_hdmi_connector_get_property,
+ .atomic_set_property = vc4_hdmi_connector_set_property,
};
static const struct drm_connector_helper_funcs vc4_hdmi_connector_helper_funcs = {
@@ -603,6 +687,33 @@ static const struct drm_connector_helper_funcs vc4_hdmi_connector_helper_funcs =
.atomic_check = vc4_hdmi_connector_atomic_check,
};
+static const struct drm_prop_enum_list broadcast_rgb_names[] = {
+ { VC4_HDMI_BROADCAST_RGB_AUTO, "Automatic" },
+ { VC4_HDMI_BROADCAST_RGB_FULL, "Full" },
+ { VC4_HDMI_BROADCAST_RGB_LIMITED, "Limited 16:235" },
+};
+
+static void
+vc4_hdmi_attach_broadcast_rgb_property(struct drm_device *dev,
+ struct vc4_hdmi *vc4_hdmi)
+{
+ struct drm_property *prop = vc4_hdmi->broadcast_rgb_property;
+
+ if (!prop) {
+ prop = drm_property_create_enum(dev, DRM_MODE_PROP_ENUM,
+ "Broadcast RGB",
+ broadcast_rgb_names,
+ ARRAY_SIZE(broadcast_rgb_names));
+ if (!prop)
+ return;
+
+ vc4_hdmi->broadcast_rgb_property = prop;
+ }
+
+ drm_object_attach_property(&vc4_hdmi->connector.base, prop,
+ VC4_HDMI_BROADCAST_RGB_AUTO);
+}
+
static int vc4_hdmi_connector_init(struct drm_device *dev,
struct vc4_hdmi *vc4_hdmi)
{
@@ -649,6 +760,8 @@ static int vc4_hdmi_connector_init(struct drm_device *dev,
if (vc4_hdmi->variant->supports_hdr)
drm_connector_attach_hdr_output_metadata_property(connector);
+ vc4_hdmi_attach_broadcast_rgb_property(dev, vc4_hdmi);
+
drm_connector_attach_encoder(connector, encoder);
return 0;
@@ -803,7 +916,7 @@ static void vc4_hdmi_set_avi_infoframe(struct drm_encoder *encoder)
drm_hdmi_avi_infoframe_quant_range(&frame.avi,
connector, mode,
- vc4_hdmi_is_full_range_rgb(vc4_hdmi, mode) ?
+ vc4_hdmi_is_full_range(vc4_hdmi, vc4_state) ?
HDMI_QUANTIZATION_RANGE_FULL :
HDMI_QUANTIZATION_RANGE_LIMITED);
drm_hdmi_avi_infoframe_colorimetry(&frame.avi, cstate);
@@ -1046,6 +1159,8 @@ static void vc4_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi,
struct drm_connector_state *state,
const struct drm_display_mode *mode)
{
+ struct vc4_hdmi_connector_state *vc4_state =
+ conn_state_to_vc4_hdmi_conn_state(state);
struct drm_device *drm = vc4_hdmi->connector.dev;
unsigned long flags;
u32 csc_ctl;
@@ -1059,7 +1174,7 @@ static void vc4_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi,
csc_ctl = VC4_SET_FIELD(VC4_HD_CSC_CTL_ORDER_BGR,
VC4_HD_CSC_CTL_ORDER);
- if (!vc4_hdmi_is_full_range_rgb(vc4_hdmi, mode)) {
+ if (!vc4_hdmi_is_full_range(vc4_hdmi, vc4_state)) {
/* CEA VICs other than #1 requre limited range RGB
* output unless overridden by an AVI infoframe.
* Apply a colorspace conversion to squash 0-255 down
@@ -1092,68 +1207,134 @@ static void vc4_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi,
}
/*
- * If we need to output Full Range RGB, then use the unity matrix
- *
- * [ 1 0 0 0]
- * [ 0 1 0 0]
- * [ 0 0 1 0]
+ * Matrices for (internal) RGB to RGB output.
*
- * Matrix is signed 2p13 fixed point, with signed 9p6 offsets
+ * Matrices are signed 2p13 fixed point, with signed 9p6 offsets
*/
-static const u16 vc5_hdmi_csc_full_rgb_unity[3][4] = {
- { 0x2000, 0x0000, 0x0000, 0x0000 },
- { 0x0000, 0x2000, 0x0000, 0x0000 },
- { 0x0000, 0x0000, 0x2000, 0x0000 },
+static const u16 vc5_hdmi_csc_full_rgb_to_rgb[2][3][4] = {
+ {
+ /*
+ * Full range - unity
+ *
+ * [ 1 0 0 0]
+ * [ 0 1 0 0]
+ * [ 0 0 1 0]
+ */
+ { 0x2000, 0x0000, 0x0000, 0x0000 },
+ { 0x0000, 0x2000, 0x0000, 0x0000 },
+ { 0x0000, 0x0000, 0x2000, 0x0000 },
+ },
+ {
+ /*
+ * Limited range
+ *
+ * CEA VICs other than #1 require limited range RGB
+ * output unless overridden by an AVI infoframe. Apply a
+ * colorspace conversion to squash 0-255 down to 16-235.
+ * The matrix here is:
+ *
+ * [ 0.8594 0 0 16]
+ * [ 0 0.8594 0 16]
+ * [ 0 0 0.8594 16]
+ */
+ { 0x1b80, 0x0000, 0x0000, 0x0400 },
+ { 0x0000, 0x1b80, 0x0000, 0x0400 },
+ { 0x0000, 0x0000, 0x1b80, 0x0400 },
+ },
};
/*
- * CEA VICs other than #1 require limited range RGB output unless
- * overridden by an AVI infoframe. Apply a colorspace conversion to
- * squash 0-255 down to 16-235. The matrix here is:
- *
- * [ 0.8594 0 0 16]
- * [ 0 0.8594 0 16]
- * [ 0 0 0.8594 16]
+ * Conversion between Full Range RGB and YUV using the BT.601 Colorspace
*
- * Matrix is signed 2p13 fixed point, with signed 9p6 offsets
+ * Matrices are signed 2p13 fixed point, with signed 9p6 offsets
*/
-static const u16 vc5_hdmi_csc_full_rgb_to_limited_rgb[3][4] = {
- { 0x1b80, 0x0000, 0x0000, 0x0400 },
- { 0x0000, 0x1b80, 0x0000, 0x0400 },
- { 0x0000, 0x0000, 0x1b80, 0x0400 },
+static const u16 vc5_hdmi_csc_full_rgb_to_yuv_bt601[2][3][4] = {
+ {
+ /*
+ * Full Range
+ *
+ * [ 0.299000 0.587000 0.114000 0 ]
+ * [ -0.168736 -0.331264 0.500000 128 ]
+ * [ 0.500000 -0.418688 -0.081312 128 ]
+ */
+ { 0x0991, 0x12c9, 0x03a6, 0x0000 },
+ { 0xfa9b, 0xf567, 0x1000, 0x2000 },
+ { 0x1000, 0xf29b, 0xfd67, 0x2000 },
+ },
+ {
+ /* Limited Range
+ *
+ * [ 0.255785 0.502160 0.097523 16 ]
+ * [ -0.147644 -0.289856 0.437500 128 ]
+ * [ 0.437500 -0.366352 -0.071148 128 ]
+ */
+ { 0x082f, 0x1012, 0x031f, 0x0400 },
+ { 0xfb48, 0xf6ba, 0x0e00, 0x2000 },
+ { 0x0e00, 0xf448, 0xfdba, 0x2000 },
+ },
};
/*
- * Conversion between Full Range RGB and Full Range YUV422 using the
- * BT.709 Colorspace
+ * Conversion between Full Range RGB and YUV using the BT.709 Colorspace
*
- *
- * [ 0.181906 0.611804 0.061758 16 ]
- * [ -0.100268 -0.337232 0.437500 128 ]
- * [ 0.437500 -0.397386 -0.040114 128 ]
- *
- * Matrix is signed 2p13 fixed point, with signed 9p6 offsets
+ * Matrices are signed 2p13 fixed point, with signed 9p6 offsets
*/
-static const u16 vc5_hdmi_csc_full_rgb_to_limited_yuv422_bt709[3][4] = {
- { 0x05d2, 0x1394, 0x01fa, 0x0400 },
- { 0xfccc, 0xf536, 0x0e00, 0x2000 },
- { 0x0e00, 0xf34a, 0xfeb8, 0x2000 },
+static const u16 vc5_hdmi_csc_full_rgb_to_yuv_bt709[2][3][4] = {
+ {
+ /*
+ * Full Range
+ *
+ * [ 0.212600 0.715200 0.072200 0 ]
+ * [ -0.114572 -0.385428 0.500000 128 ]
+ * [ 0.500000 -0.454153 -0.045847 128 ]
+ */
+ { 0x06ce, 0x16e3, 0x024f, 0x0000 },
+ { 0xfc56, 0xf3ac, 0x1000, 0x2000 },
+ { 0x1000, 0xf179, 0xfe89, 0x2000 },
+ },
+ {
+ /*
+ * Limited Range
+ *
+ * [ 0.181906 0.611804 0.061758 16 ]
+ * [ -0.100268 -0.337232 0.437500 128 ]
+ * [ 0.437500 -0.397386 -0.040114 128 ]
+ */
+ { 0x05d2, 0x1394, 0x01fa, 0x0400 },
+ { 0xfccc, 0xf536, 0x0e00, 0x2000 },
+ { 0x0e00, 0xf34a, 0xfeb8, 0x2000 },
+ },
};
/*
- * Conversion between Full Range RGB and Full Range YUV444 using the
- * BT.709 Colorspace
+ * Conversion between Full Range RGB and YUV using the BT.2020 Colorspace
*
- * [ -0.100268 -0.337232 0.437500 128 ]
- * [ 0.437500 -0.397386 -0.040114 128 ]
- * [ 0.181906 0.611804 0.061758 16 ]
- *
- * Matrix is signed 2p13 fixed point, with signed 9p6 offsets
+ * Matrices are signed 2p13 fixed point, with signed 9p6 offsets
*/
-static const u16 vc5_hdmi_csc_full_rgb_to_limited_yuv444_bt709[3][4] = {
- { 0xfccc, 0xf536, 0x0e00, 0x2000 },
- { 0x0e00, 0xf34a, 0xfeb8, 0x2000 },
- { 0x05d2, 0x1394, 0x01fa, 0x0400 },
+static const u16 vc5_hdmi_csc_full_rgb_to_yuv_bt2020[2][3][4] = {
+ {
+ /*
+ * Full Range
+ *
+ * [ 0.262700 0.678000 0.059300 0 ]
+ * [ -0.139630 -0.360370 0.500000 128 ]
+ * [ 0.500000 -0.459786 -0.040214 128 ]
+ */
+ { 0x0868, 0x15b2, 0x01e6, 0x0000 },
+ { 0xfb89, 0xf479, 0x1000, 0x2000 },
+ { 0x1000, 0xf14a, 0xfeb8, 0x2000 },
+ },
+ {
+ /* Limited Range
+ *
+ * [ 0.224732 0.580008 0.050729 16 ]
+ * [ -0.122176 -0.315324 0.437500 128 ]
+ * [ 0.437500 -0.402312 -0.035188 128 ]
+ */
+ { 0x082f, 0x1012, 0x031f, 0x0400 },
+ { 0xfb48, 0xf6ba, 0x0e00, 0x2000 },
+ { 0x0e00, 0xf448, 0xfdba, 0x2000 },
+ },
};
static void vc5_hdmi_set_csc_coeffs(struct vc4_hdmi *vc4_hdmi,
@@ -1169,6 +1350,48 @@ static void vc5_hdmi_set_csc_coeffs(struct vc4_hdmi *vc4_hdmi,
HDMI_WRITE(HDMI_CSC_34_33, (coeffs[2][3] << 16) | coeffs[2][2]);
}
+static void vc5_hdmi_set_csc_coeffs_swap(struct vc4_hdmi *vc4_hdmi,
+ const u16 coeffs[3][4])
+{
+ lockdep_assert_held(&vc4_hdmi->hw_lock);
+
+ /* YUV444 needs the CSC matrices using the channels in a different order */
+ HDMI_WRITE(HDMI_CSC_12_11, (coeffs[1][1] << 16) | coeffs[1][0]);
+ HDMI_WRITE(HDMI_CSC_14_13, (coeffs[1][3] << 16) | coeffs[1][2]);
+ HDMI_WRITE(HDMI_CSC_22_21, (coeffs[2][1] << 16) | coeffs[2][0]);
+ HDMI_WRITE(HDMI_CSC_24_23, (coeffs[2][3] << 16) | coeffs[2][2]);
+ HDMI_WRITE(HDMI_CSC_32_31, (coeffs[0][1] << 16) | coeffs[0][0]);
+ HDMI_WRITE(HDMI_CSC_34_33, (coeffs[0][3] << 16) | coeffs[0][2]);
+}
+
+static const u16
+(*vc5_hdmi_find_yuv_csc_coeffs(struct vc4_hdmi *vc4_hdmi, u32 colorspace, bool limited))[4]
+{
+ switch (colorspace) {
+ case DRM_MODE_COLORIMETRY_SMPTE_170M_YCC:
+ case DRM_MODE_COLORIMETRY_XVYCC_601:
+ case DRM_MODE_COLORIMETRY_SYCC_601:
+ case DRM_MODE_COLORIMETRY_OPYCC_601:
+ case DRM_MODE_COLORIMETRY_BT601_YCC:
+ return vc5_hdmi_csc_full_rgb_to_yuv_bt601[limited];
+
+ default:
+ case DRM_MODE_COLORIMETRY_NO_DATA:
+ case DRM_MODE_COLORIMETRY_BT709_YCC:
+ case DRM_MODE_COLORIMETRY_XVYCC_709:
+ case DRM_MODE_COLORIMETRY_RGB_WIDE_FIXED:
+ case DRM_MODE_COLORIMETRY_RGB_WIDE_FLOAT:
+ return vc5_hdmi_csc_full_rgb_to_yuv_bt709[limited];
+
+ case DRM_MODE_COLORIMETRY_BT2020_CYCC:
+ case DRM_MODE_COLORIMETRY_BT2020_YCC:
+ case DRM_MODE_COLORIMETRY_BT2020_RGB:
+ case DRM_MODE_COLORIMETRY_DCI_P3_RGB_D65:
+ case DRM_MODE_COLORIMETRY_DCI_P3_RGB_THEATER:
+ return vc5_hdmi_csc_full_rgb_to_yuv_bt2020[limited];
+ }
+}
+
static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi,
struct drm_connector_state *state,
const struct drm_display_mode *mode)
@@ -1176,7 +1399,9 @@ static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi,
struct drm_device *drm = vc4_hdmi->connector.dev;
struct vc4_hdmi_connector_state *vc4_state =
conn_state_to_vc4_hdmi_conn_state(state);
+ unsigned int lim_range = vc4_hdmi_is_full_range(vc4_hdmi, vc4_state) ? 0 : 1;
unsigned long flags;
+ const u16 (*csc)[4];
u32 if_cfg = 0;
u32 if_xbar = 0x543210;
u32 csc_chan_ctl = 0;
@@ -1191,10 +1416,14 @@ static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi,
switch (vc4_state->output_format) {
case VC4_HDMI_OUTPUT_YUV444:
- vc5_hdmi_set_csc_coeffs(vc4_hdmi, vc5_hdmi_csc_full_rgb_to_limited_yuv444_bt709);
+ csc = vc5_hdmi_find_yuv_csc_coeffs(vc4_hdmi, state->colorspace, !!lim_range);
+
+ vc5_hdmi_set_csc_coeffs_swap(vc4_hdmi, csc);
break;
case VC4_HDMI_OUTPUT_YUV422:
+ csc = vc5_hdmi_find_yuv_csc_coeffs(vc4_hdmi, state->colorspace, !!lim_range);
+
csc_ctl |= VC4_SET_FIELD(VC5_MT_CP_CSC_CTL_FILTER_MODE_444_TO_422_STANDARD,
VC5_MT_CP_CSC_CTL_FILTER_MODE_444_TO_422) |
VC5_MT_CP_CSC_CTL_USE_444_TO_422 |
@@ -1206,16 +1435,13 @@ static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi,
if_cfg |= VC4_SET_FIELD(VC5_DVP_HT_VEC_INTERFACE_CFG_SEL_422_FORMAT_422_LEGACY,
VC5_DVP_HT_VEC_INTERFACE_CFG_SEL_422);
- vc5_hdmi_set_csc_coeffs(vc4_hdmi, vc5_hdmi_csc_full_rgb_to_limited_yuv422_bt709);
+ vc5_hdmi_set_csc_coeffs(vc4_hdmi, csc);
break;
case VC4_HDMI_OUTPUT_RGB:
if_xbar = 0x354021;
- if (!vc4_hdmi_is_full_range_rgb(vc4_hdmi, mode))
- vc5_hdmi_set_csc_coeffs(vc4_hdmi, vc5_hdmi_csc_full_rgb_to_limited_rgb);
- else
- vc5_hdmi_set_csc_coeffs(vc4_hdmi, vc5_hdmi_csc_full_rgb_unity);
+ vc5_hdmi_set_csc_coeffs(vc4_hdmi, vc5_hdmi_csc_full_rgb_to_rgb[lim_range]);
break;
default:
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h
index e3619836ca17..934d5d61485a 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.h
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
@@ -117,6 +117,12 @@ enum vc4_hdmi_output_format {
VC4_HDMI_OUTPUT_YUV420,
};
+enum vc4_hdmi_broadcast_rgb {
+ VC4_HDMI_BROADCAST_RGB_AUTO,
+ VC4_HDMI_BROADCAST_RGB_FULL,
+ VC4_HDMI_BROADCAST_RGB_LIMITED,
+};
+
/* General HDMI hardware state. */
struct vc4_hdmi {
struct vc4_hdmi_audio audio;
@@ -129,6 +135,8 @@ struct vc4_hdmi {
struct delayed_work scrambling_work;
+ struct drm_property *broadcast_rgb_property;
+
struct i2c_adapter *ddc;
void __iomem *hdmicore_regs;
void __iomem *hd_regs;
@@ -222,17 +230,14 @@ struct vc4_hdmi {
enum vc4_hdmi_output_format output_format;
};
-static inline struct vc4_hdmi *
-connector_to_vc4_hdmi(struct drm_connector *connector)
-{
- return container_of(connector, struct vc4_hdmi, connector);
-}
+#define connector_to_vc4_hdmi(_connector) \
+ container_of_const(_connector, struct vc4_hdmi, connector)
static inline struct vc4_hdmi *
encoder_to_vc4_hdmi(struct drm_encoder *encoder)
{
struct vc4_encoder *_encoder = to_vc4_encoder(encoder);
- return container_of(_encoder, struct vc4_hdmi, encoder);
+ return container_of_const(_encoder, struct vc4_hdmi, encoder);
}
struct vc4_hdmi_connector_state {
@@ -240,13 +245,11 @@ struct vc4_hdmi_connector_state {
unsigned long long tmds_char_rate;
unsigned int output_bpc;
enum vc4_hdmi_output_format output_format;
+ enum vc4_hdmi_broadcast_rgb broadcast_rgb;
};
-static inline struct vc4_hdmi_connector_state *
-conn_state_to_vc4_hdmi_conn_state(struct drm_connector_state *conn_state)
-{
- return container_of(conn_state, struct vc4_hdmi_connector_state, base);
-}
+#define conn_state_to_vc4_hdmi_conn_state(_state) \
+ container_of_const(_state, struct vc4_hdmi_connector_state, base)
void vc4_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi,
struct vc4_hdmi_connector_state *vc4_conn_state);
diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
index a7e3d47c50f4..5495f2a94fa9 100644
--- a/drivers/gpu/drm/vc4/vc4_kms.c
+++ b/drivers/gpu/drm/vc4/vc4_kms.c
@@ -31,11 +31,8 @@ struct vc4_ctm_state {
int fifo;
};
-static struct vc4_ctm_state *
-to_vc4_ctm_state(const struct drm_private_state *priv)
-{
- return container_of(priv, struct vc4_ctm_state, base);
-}
+#define to_vc4_ctm_state(_state) \
+ container_of_const(_state, struct vc4_ctm_state, base)
struct vc4_load_tracker_state {
struct drm_private_state base;
@@ -43,11 +40,8 @@ struct vc4_load_tracker_state {
u64 membus_load;
};
-static struct vc4_load_tracker_state *
-to_vc4_load_tracker_state(const struct drm_private_state *priv)
-{
- return container_of(priv, struct vc4_load_tracker_state, base);
-}
+#define to_vc4_load_tracker_state(_state) \
+ container_of_const(_state, struct vc4_load_tracker_state, base)
static struct vc4_ctm_state *vc4_get_ctm_state(struct drm_atomic_state *state,
struct drm_private_obj *manager)
@@ -717,7 +711,7 @@ static void vc4_hvs_channels_destroy_state(struct drm_private_obj *obj,
static void vc4_hvs_channels_print_state(struct drm_printer *p,
const struct drm_private_state *state)
{
- struct vc4_hvs_state *hvs_state = to_vc4_hvs_state(state);
+ const struct vc4_hvs_state *hvs_state = to_vc4_hvs_state(state);
unsigned int i;
drm_printf(p, "HVS State\n");
diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
index 97c84a3f5a46..00e713faecd5 100644
--- a/drivers/gpu/drm/vc4/vc4_plane.c
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
@@ -1334,8 +1334,7 @@ out:
u32 vc4_plane_dlist_size(const struct drm_plane_state *state)
{
- const struct vc4_plane_state *vc4_state =
- container_of(state, typeof(*vc4_state), base);
+ const struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
return vc4_state->dlist_count;
}
diff --git a/drivers/gpu/drm/vc4/vc4_txp.c b/drivers/gpu/drm/vc4/vc4_txp.c
index ef5cab2a3aa9..c5abdec03103 100644
--- a/drivers/gpu/drm/vc4/vc4_txp.c
+++ b/drivers/gpu/drm/vc4/vc4_txp.c
@@ -168,15 +168,11 @@ struct vc4_txp {
void __iomem *regs;
};
-static inline struct vc4_txp *encoder_to_vc4_txp(struct drm_encoder *encoder)
-{
- return container_of(encoder, struct vc4_txp, encoder.base);
-}
+#define encoder_to_vc4_txp(_encoder) \
+ container_of_const(_encoder, struct vc4_txp, encoder.base)
-static inline struct vc4_txp *connector_to_vc4_txp(struct drm_connector *conn)
-{
- return container_of(conn, struct vc4_txp, connector.base);
-}
+#define connector_to_vc4_txp(_connector) \
+ container_of_const(_connector, struct vc4_txp, connector.base)
static const struct debugfs_reg32 txp_regs[] = {
VC4_REG32(TXP_DST_PTR),
diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c
index a3782d05cd66..d6e6a1a22eba 100644
--- a/drivers/gpu/drm/vc4/vc4_vec.c
+++ b/drivers/gpu/drm/vc4/vc4_vec.c
@@ -219,17 +219,11 @@ struct vc4_vec {
writel(val, vec->regs + (offset)); \
} while (0)
-static inline struct vc4_vec *
-encoder_to_vc4_vec(struct drm_encoder *encoder)
-{
- return container_of(encoder, struct vc4_vec, encoder.base);
-}
+#define encoder_to_vc4_vec(_encoder) \
+ container_of_const(_encoder, struct vc4_vec, encoder.base)
-static inline struct vc4_vec *
-connector_to_vc4_vec(struct drm_connector *connector)
-{
- return container_of(connector, struct vc4_vec, connector);
-}
+#define connector_to_vc4_vec(_connector) \
+ container_of_const(_connector, struct vc4_vec, connector)
enum vc4_vec_tv_mode_id {
VC4_VEC_TV_MODE_NTSC,
diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c
index 8e53fa80742b..906d3df40cdb 100644
--- a/drivers/gpu/drm/vkms/vkms_composer.c
+++ b/drivers/gpu/drm/vkms/vkms_composer.c
@@ -4,6 +4,7 @@
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
+#include <drm/drm_blend.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_vblank.h>
@@ -53,10 +54,30 @@ static void pre_mul_alpha_blend(struct vkms_frame_info *frame_info,
}
}
-static bool check_y_limit(struct vkms_frame_info *frame_info, int y)
+static int get_y_pos(struct vkms_frame_info *frame_info, int y)
{
- if (y >= frame_info->dst.y1 && y < frame_info->dst.y2)
- return true;
+ if (frame_info->rotation & DRM_MODE_REFLECT_Y)
+ return drm_rect_height(&frame_info->rotated) - y - 1;
+
+ switch (frame_info->rotation & DRM_MODE_ROTATE_MASK) {
+ case DRM_MODE_ROTATE_90:
+ return frame_info->rotated.x2 - y - 1;
+ case DRM_MODE_ROTATE_270:
+ return y + frame_info->rotated.x1;
+ default:
+ return y;
+ }
+}
+
+static bool check_limit(struct vkms_frame_info *frame_info, int pos)
+{
+ if (drm_rotation_90_or_270(frame_info->rotation)) {
+ if (pos >= 0 && pos < drm_rect_width(&frame_info->rotated))
+ return true;
+ } else {
+ if (pos >= frame_info->rotated.y1 && pos < frame_info->rotated.y2)
+ return true;
+ }
return false;
}
@@ -86,6 +107,7 @@ static void blend(struct vkms_writeback_job *wb,
{
struct vkms_plane_state **plane = crtc_state->active_planes;
u32 n_active_planes = crtc_state->num_active_planes;
+ int y_pos;
const struct pixel_argb_u16 background_color = { .a = 0xffff };
@@ -96,10 +118,12 @@ static void blend(struct vkms_writeback_job *wb,
/* The active planes are composed associatively in z-order. */
for (size_t i = 0; i < n_active_planes; i++) {
- if (!check_y_limit(plane[i]->frame_info, y))
+ y_pos = get_y_pos(plane[i]->frame_info, y);
+
+ if (!check_limit(plane[i]->frame_info, y_pos))
continue;
- plane[i]->plane_read(stage_buffer, plane[i]->frame_info, y);
+ vkms_compose_row(stage_buffer, plane[i], y_pos);
pre_mul_alpha_blend(plane[i]->frame_info, stage_buffer,
output_buffer);
}
@@ -107,7 +131,7 @@ static void blend(struct vkms_writeback_job *wb,
*crc32 = crc32_le(*crc32, (void *)output_buffer->pixels, row_size);
if (wb)
- wb->wb_write(&wb->wb_frame_info, output_buffer, y);
+ wb->wb_write(&wb->wb_frame_info, output_buffer, y_pos);
}
}
@@ -118,7 +142,7 @@ static int check_format_funcs(struct vkms_crtc_state *crtc_state,
u32 n_active_planes = crtc_state->num_active_planes;
for (size_t i = 0; i < n_active_planes; i++)
- if (!planes[i]->plane_read)
+ if (!planes[i]->pixel_read)
return -1;
if (active_wb && !active_wb->wb_write)
diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c
index 57bbd32e9beb..515f6772b866 100644
--- a/drivers/gpu/drm/vkms/vkms_crtc.c
+++ b/drivers/gpu/drm/vkms/vkms_crtc.c
@@ -161,7 +161,6 @@ static void vkms_atomic_crtc_reset(struct drm_crtc *crtc)
static const struct drm_crtc_funcs vkms_crtc_funcs = {
.set_config = drm_atomic_helper_set_config,
- .destroy = drm_crtc_cleanup,
.page_flip = drm_atomic_helper_page_flip,
.reset = vkms_atomic_crtc_reset,
.atomic_duplicate_state = vkms_atomic_crtc_duplicate_state,
@@ -282,8 +281,8 @@ int vkms_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
struct vkms_output *vkms_out = drm_crtc_to_vkms_output(crtc);
int ret;
- ret = drm_crtc_init_with_planes(dev, crtc, primary, cursor,
- &vkms_crtc_funcs, NULL);
+ ret = drmm_crtc_init_with_planes(dev, crtc, primary, cursor,
+ &vkms_crtc_funcs, NULL);
if (ret) {
DRM_ERROR("Failed to init CRTC\n");
return ret;
diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c
index 6d3a2d57d992..e3c9c9571c8d 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.c
+++ b/drivers/gpu/drm/vkms/vkms_drv.c
@@ -133,8 +133,12 @@ static const struct drm_mode_config_helper_funcs vkms_mode_config_helpers = {
static int vkms_modeset_init(struct vkms_device *vkmsdev)
{
struct drm_device *dev = &vkmsdev->drm;
+ int ret;
+
+ ret = drmm_mode_config_init(dev);
+ if (ret)
+ return ret;
- drm_mode_config_init(dev);
dev->mode_config.funcs = &vkms_mode_funcs;
dev->mode_config.min_width = XRES_MIN;
dev->mode_config.min_height = YRES_MIN;
diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
index 4a248567efb2..5f1a0a44a78c 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.h
+++ b/drivers/gpu/drm/vkms/vkms_drv.h
@@ -26,7 +26,9 @@
struct vkms_frame_info {
struct drm_framebuffer *fb;
struct drm_rect src, dst;
+ struct drm_rect rotated;
struct iosys_map map[DRM_FORMAT_MAX_PLANES];
+ unsigned int rotation;
unsigned int offset;
unsigned int pitch;
unsigned int cpp;
@@ -56,8 +58,7 @@ struct vkms_writeback_job {
struct vkms_plane_state {
struct drm_shadow_plane_state base;
struct vkms_frame_info *frame_info;
- void (*plane_read)(struct line_buffer *buffer,
- const struct vkms_frame_info *frame_info, int y);
+ void (*pixel_read)(u8 *src_buffer, struct pixel_argb_u16 *out_pixel);
};
struct vkms_plane {
@@ -155,6 +156,7 @@ int vkms_verify_crc_source(struct drm_crtc *crtc, const char *source_name,
/* Composer Support */
void vkms_composer_worker(struct work_struct *work);
void vkms_set_composer(struct vkms_output *out, bool enabled);
+void vkms_compose_row(struct line_buffer *stage_buffer, struct vkms_plane_state *plane, int y);
/* Writeback */
int vkms_enable_writeback_connector(struct vkms_device *vkmsdev);
diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c
index d4950688b3f1..5945da0beba6 100644
--- a/drivers/gpu/drm/vkms/vkms_formats.c
+++ b/drivers/gpu/drm/vkms/vkms_formats.c
@@ -2,6 +2,8 @@
#include <linux/kernel.h>
#include <linux/minmax.h>
+
+#include <drm/drm_blend.h>
#include <drm/drm_rect.h>
#include <drm/drm_fixed.h>
@@ -37,104 +39,93 @@ static void *packed_pixels_addr(const struct vkms_frame_info *frame_info,
static void *get_packed_src_addr(const struct vkms_frame_info *frame_info, int y)
{
int x_src = frame_info->src.x1 >> 16;
- int y_src = y - frame_info->dst.y1 + (frame_info->src.y1 >> 16);
+ int y_src = y - frame_info->rotated.y1 + (frame_info->src.y1 >> 16);
return packed_pixels_addr(frame_info, x_src, y_src);
}
-static void ARGB8888_to_argb_u16(struct line_buffer *stage_buffer,
- const struct vkms_frame_info *frame_info, int y)
+static int get_x_position(const struct vkms_frame_info *frame_info, int limit, int x)
{
- struct pixel_argb_u16 *out_pixels = stage_buffer->pixels;
- u8 *src_pixels = get_packed_src_addr(frame_info, y);
- int x_limit = min_t(size_t, drm_rect_width(&frame_info->dst),
- stage_buffer->n_pixels);
-
- for (size_t x = 0; x < x_limit; x++, src_pixels += 4) {
- /*
- * The 257 is the "conversion ratio". This number is obtained by the
- * (2^16 - 1) / (2^8 - 1) division. Which, in this case, tries to get
- * the best color value in a pixel format with more possibilities.
- * A similar idea applies to others RGB color conversions.
- */
- out_pixels[x].a = (u16)src_pixels[3] * 257;
- out_pixels[x].r = (u16)src_pixels[2] * 257;
- out_pixels[x].g = (u16)src_pixels[1] * 257;
- out_pixels[x].b = (u16)src_pixels[0] * 257;
- }
+ if (frame_info->rotation & (DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_270))
+ return limit - x - 1;
+ return x;
}
-static void XRGB8888_to_argb_u16(struct line_buffer *stage_buffer,
- const struct vkms_frame_info *frame_info, int y)
+static void ARGB8888_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 *out_pixel)
{
- struct pixel_argb_u16 *out_pixels = stage_buffer->pixels;
- u8 *src_pixels = get_packed_src_addr(frame_info, y);
- int x_limit = min_t(size_t, drm_rect_width(&frame_info->dst),
- stage_buffer->n_pixels);
+ /*
+ * The 257 is the "conversion ratio". This number is obtained by the
+ * (2^16 - 1) / (2^8 - 1) division. Which, in this case, tries to get
+ * the best color value in a pixel format with more possibilities.
+ * A similar idea applies to others RGB color conversions.
+ */
+ out_pixel->a = (u16)src_pixels[3] * 257;
+ out_pixel->r = (u16)src_pixels[2] * 257;
+ out_pixel->g = (u16)src_pixels[1] * 257;
+ out_pixel->b = (u16)src_pixels[0] * 257;
+}
- for (size_t x = 0; x < x_limit; x++, src_pixels += 4) {
- out_pixels[x].a = (u16)0xffff;
- out_pixels[x].r = (u16)src_pixels[2] * 257;
- out_pixels[x].g = (u16)src_pixels[1] * 257;
- out_pixels[x].b = (u16)src_pixels[0] * 257;
- }
+static void XRGB8888_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 *out_pixel)
+{
+ out_pixel->a = (u16)0xffff;
+ out_pixel->r = (u16)src_pixels[2] * 257;
+ out_pixel->g = (u16)src_pixels[1] * 257;
+ out_pixel->b = (u16)src_pixels[0] * 257;
}
-static void ARGB16161616_to_argb_u16(struct line_buffer *stage_buffer,
- const struct vkms_frame_info *frame_info,
- int y)
+static void ARGB16161616_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 *out_pixel)
{
- struct pixel_argb_u16 *out_pixels = stage_buffer->pixels;
- u16 *src_pixels = get_packed_src_addr(frame_info, y);
- int x_limit = min_t(size_t, drm_rect_width(&frame_info->dst),
- stage_buffer->n_pixels);
+ u16 *pixels = (u16 *)src_pixels;
- for (size_t x = 0; x < x_limit; x++, src_pixels += 4) {
- out_pixels[x].a = le16_to_cpu(src_pixels[3]);
- out_pixels[x].r = le16_to_cpu(src_pixels[2]);
- out_pixels[x].g = le16_to_cpu(src_pixels[1]);
- out_pixels[x].b = le16_to_cpu(src_pixels[0]);
- }
+ out_pixel->a = le16_to_cpu(pixels[3]);
+ out_pixel->r = le16_to_cpu(pixels[2]);
+ out_pixel->g = le16_to_cpu(pixels[1]);
+ out_pixel->b = le16_to_cpu(pixels[0]);
}
-static void XRGB16161616_to_argb_u16(struct line_buffer *stage_buffer,
- const struct vkms_frame_info *frame_info,
- int y)
+static void XRGB16161616_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 *out_pixel)
{
- struct pixel_argb_u16 *out_pixels = stage_buffer->pixels;
- u16 *src_pixels = get_packed_src_addr(frame_info, y);
- int x_limit = min_t(size_t, drm_rect_width(&frame_info->dst),
- stage_buffer->n_pixels);
+ u16 *pixels = (u16 *)src_pixels;
- for (size_t x = 0; x < x_limit; x++, src_pixels += 4) {
- out_pixels[x].a = (u16)0xffff;
- out_pixels[x].r = le16_to_cpu(src_pixels[2]);
- out_pixels[x].g = le16_to_cpu(src_pixels[1]);
- out_pixels[x].b = le16_to_cpu(src_pixels[0]);
- }
+ out_pixel->a = (u16)0xffff;
+ out_pixel->r = le16_to_cpu(pixels[2]);
+ out_pixel->g = le16_to_cpu(pixels[1]);
+ out_pixel->b = le16_to_cpu(pixels[0]);
}
-static void RGB565_to_argb_u16(struct line_buffer *stage_buffer,
- const struct vkms_frame_info *frame_info, int y)
+static void RGB565_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 *out_pixel)
{
- struct pixel_argb_u16 *out_pixels = stage_buffer->pixels;
- u16 *src_pixels = get_packed_src_addr(frame_info, y);
- int x_limit = min_t(size_t, drm_rect_width(&frame_info->dst),
- stage_buffer->n_pixels);
+ u16 *pixels = (u16 *)src_pixels;
s64 fp_rb_ratio = drm_fixp_div(drm_int2fixp(65535), drm_int2fixp(31));
s64 fp_g_ratio = drm_fixp_div(drm_int2fixp(65535), drm_int2fixp(63));
- for (size_t x = 0; x < x_limit; x++, src_pixels++) {
- u16 rgb_565 = le16_to_cpu(*src_pixels);
- s64 fp_r = drm_int2fixp((rgb_565 >> 11) & 0x1f);
- s64 fp_g = drm_int2fixp((rgb_565 >> 5) & 0x3f);
- s64 fp_b = drm_int2fixp(rgb_565 & 0x1f);
+ u16 rgb_565 = le16_to_cpu(*pixels);
+ s64 fp_r = drm_int2fixp((rgb_565 >> 11) & 0x1f);
+ s64 fp_g = drm_int2fixp((rgb_565 >> 5) & 0x3f);
+ s64 fp_b = drm_int2fixp(rgb_565 & 0x1f);
+
+ out_pixel->a = (u16)0xffff;
+ out_pixel->r = drm_fixp2int_round(drm_fixp_mul(fp_r, fp_rb_ratio));
+ out_pixel->g = drm_fixp2int_round(drm_fixp_mul(fp_g, fp_g_ratio));
+ out_pixel->b = drm_fixp2int_round(drm_fixp_mul(fp_b, fp_rb_ratio));
+}
+
+void vkms_compose_row(struct line_buffer *stage_buffer, struct vkms_plane_state *plane, int y)
+{
+ struct pixel_argb_u16 *out_pixels = stage_buffer->pixels;
+ struct vkms_frame_info *frame_info = plane->frame_info;
+ u8 *src_pixels = get_packed_src_addr(frame_info, y);
+ int limit = min_t(size_t, drm_rect_width(&frame_info->dst), stage_buffer->n_pixels);
+
+ for (size_t x = 0; x < limit; x++, src_pixels += frame_info->cpp) {
+ int x_pos = get_x_position(frame_info, limit, x);
+
+ if (drm_rotation_90_or_270(frame_info->rotation))
+ src_pixels = get_packed_src_addr(frame_info, x + frame_info->rotated.y1)
+ + frame_info->cpp * y;
- out_pixels[x].a = (u16)0xffff;
- out_pixels[x].r = drm_fixp2int(drm_fixp_mul(fp_r, fp_rb_ratio));
- out_pixels[x].g = drm_fixp2int(drm_fixp_mul(fp_g, fp_g_ratio));
- out_pixels[x].b = drm_fixp2int(drm_fixp_mul(fp_b, fp_rb_ratio));
+ plane->pixel_read(src_pixels, &out_pixels[x_pos]);
}
}
@@ -241,15 +232,15 @@ static void argb_u16_to_RGB565(struct vkms_frame_info *frame_info,
s64 fp_g = drm_int2fixp(in_pixels[x].g);
s64 fp_b = drm_int2fixp(in_pixels[x].b);
- u16 r = drm_fixp2int(drm_fixp_div(fp_r, fp_rb_ratio));
- u16 g = drm_fixp2int(drm_fixp_div(fp_g, fp_g_ratio));
- u16 b = drm_fixp2int(drm_fixp_div(fp_b, fp_rb_ratio));
+ u16 r = drm_fixp2int_round(drm_fixp_div(fp_r, fp_rb_ratio));
+ u16 g = drm_fixp2int_round(drm_fixp_div(fp_g, fp_g_ratio));
+ u16 b = drm_fixp2int_round(drm_fixp_div(fp_b, fp_rb_ratio));
*dst_pixels = cpu_to_le16(r << 11 | g << 5 | b);
}
}
-void *get_frame_to_line_function(u32 format)
+void *get_pixel_conversion_function(u32 format)
{
switch (format) {
case DRM_FORMAT_ARGB8888:
diff --git a/drivers/gpu/drm/vkms/vkms_formats.h b/drivers/gpu/drm/vkms/vkms_formats.h
index 43b7c1979018..c5b113495d0c 100644
--- a/drivers/gpu/drm/vkms/vkms_formats.h
+++ b/drivers/gpu/drm/vkms/vkms_formats.h
@@ -5,7 +5,7 @@
#include "vkms_drv.h"
-void *get_frame_to_line_function(u32 format);
+void *get_pixel_conversion_function(u32 format);
void *get_line_to_frame_function(u32 format);
diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
index c41cec7dcb70..e5c625ab8e3e 100644
--- a/drivers/gpu/drm/vkms/vkms_plane.c
+++ b/drivers/gpu/drm/vkms/vkms_plane.c
@@ -4,6 +4,7 @@
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
+#include <drm/drm_blend.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_gem_atomic_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
@@ -12,12 +13,6 @@
#include "vkms_formats.h"
static const u32 vkms_formats[] = {
- DRM_FORMAT_XRGB8888,
- DRM_FORMAT_XRGB16161616,
- DRM_FORMAT_RGB565
-};
-
-static const u32 vkms_plane_formats[] = {
DRM_FORMAT_ARGB8888,
DRM_FORMAT_XRGB8888,
DRM_FORMAT_XRGB16161616,
@@ -117,13 +112,23 @@ static void vkms_plane_atomic_update(struct drm_plane *plane,
frame_info = vkms_plane_state->frame_info;
memcpy(&frame_info->src, &new_state->src, sizeof(struct drm_rect));
memcpy(&frame_info->dst, &new_state->dst, sizeof(struct drm_rect));
+ memcpy(&frame_info->rotated, &new_state->dst, sizeof(struct drm_rect));
frame_info->fb = fb;
memcpy(&frame_info->map, &shadow_plane_state->data, sizeof(frame_info->map));
drm_framebuffer_get(frame_info->fb);
+ frame_info->rotation = drm_rotation_simplify(new_state->rotation, DRM_MODE_ROTATE_0 |
+ DRM_MODE_ROTATE_90 |
+ DRM_MODE_ROTATE_270 |
+ DRM_MODE_REFLECT_X |
+ DRM_MODE_REFLECT_Y);
+
+ drm_rect_rotate(&frame_info->rotated, drm_rect_width(&frame_info->rotated),
+ drm_rect_height(&frame_info->rotated), frame_info->rotation);
+
frame_info->offset = fb->offsets[0];
frame_info->pitch = fb->pitches[0];
frame_info->cpp = fb->format->cpp[0];
- vkms_plane_state->plane_read = get_frame_to_line_function(fmt);
+ vkms_plane_state->pixel_read = get_pixel_conversion_function(fmt);
}
static int vkms_plane_atomic_check(struct drm_plane *plane,
@@ -185,7 +190,7 @@ static void vkms_cleanup_fb(struct drm_plane *plane,
drm_gem_fb_vunmap(fb, shadow_plane_state->map);
}
-static const struct drm_plane_helper_funcs vkms_primary_helper_funcs = {
+static const struct drm_plane_helper_funcs vkms_plane_helper_funcs = {
.atomic_update = vkms_plane_atomic_update,
.atomic_check = vkms_plane_atomic_check,
.prepare_fb = vkms_prepare_fb,
@@ -196,38 +201,19 @@ struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev,
enum drm_plane_type type, int index)
{
struct drm_device *dev = &vkmsdev->drm;
- const struct drm_plane_helper_funcs *funcs;
struct vkms_plane *plane;
- const u32 *formats;
- int nformats;
-
- switch (type) {
- case DRM_PLANE_TYPE_PRIMARY:
- formats = vkms_formats;
- nformats = ARRAY_SIZE(vkms_formats);
- funcs = &vkms_primary_helper_funcs;
- break;
- case DRM_PLANE_TYPE_CURSOR:
- case DRM_PLANE_TYPE_OVERLAY:
- formats = vkms_plane_formats;
- nformats = ARRAY_SIZE(vkms_plane_formats);
- funcs = &vkms_primary_helper_funcs;
- break;
- default:
- formats = vkms_formats;
- nformats = ARRAY_SIZE(vkms_formats);
- funcs = &vkms_primary_helper_funcs;
- break;
- }
plane = drmm_universal_plane_alloc(dev, struct vkms_plane, base, 1 << index,
&vkms_plane_funcs,
- formats, nformats,
+ vkms_formats, ARRAY_SIZE(vkms_formats),
NULL, type, NULL);
if (IS_ERR(plane))
return plane;
- drm_plane_helper_add(&plane->base, funcs);
+ drm_plane_helper_add(&plane->base, &vkms_plane_helper_funcs);
+
+ drm_plane_create_rotation_property(&plane->base, DRM_MODE_ROTATE_0,
+ DRM_MODE_ROTATE_MASK | DRM_MODE_REFLECT_MASK);
return plane;
}
diff --git a/drivers/gpu/ipu-v3/ipu-prv.h b/drivers/gpu/ipu-v3/ipu-prv.h
index 291ac1bab66d..d4621b1ea7f1 100644
--- a/drivers/gpu/ipu-v3/ipu-prv.h
+++ b/drivers/gpu/ipu-v3/ipu-prv.h
@@ -8,6 +8,7 @@
struct ipu_soc;
+#include <linux/io.h>
#include <linux/types.h>
#include <linux/device.h>
#include <linux/clk.h>
diff --git a/drivers/hid/hid-picolcd_fb.c b/drivers/hid/hid-picolcd_fb.c
index de61c08fabea..dabcd054dad9 100644
--- a/drivers/hid/hid-picolcd_fb.c
+++ b/drivers/hid/hid-picolcd_fb.c
@@ -221,7 +221,7 @@ int picolcd_fb_reset(struct picolcd_data *data, int clear)
return 0;
}
-/* Update fb_vbitmap from the screen_base and send changed tiles to device */
+/* Update fb_vbitmap from the screen_buffer and send changed tiles to device */
static void picolcd_fb_update(struct fb_info *info)
{
int chip, tile, n;
@@ -541,7 +541,7 @@ int picolcd_init_framebuffer(struct picolcd_data *data)
dev_err(dev, "can't get a free page for framebuffer\n");
goto err_nomem;
}
- info->screen_base = (char __force __iomem *)fbdata->bitmap;
+ info->screen_buffer = fbdata->bitmap;
info->fix.smem_start = (unsigned long)fbdata->bitmap;
memset(fbdata->vbitmap, 0xff, PICOLCDFB_SIZE);
data->fb_info = info;
diff --git a/drivers/hwmon/k10temp.c b/drivers/hwmon/k10temp.c
index ba2f6a4f8c16..7b177b9fbb09 100644
--- a/drivers/hwmon/k10temp.c
+++ b/drivers/hwmon/k10temp.c
@@ -507,6 +507,7 @@ static const struct pci_device_id k10temp_id_table[] = {
{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_19H_M50H_DF_F3) },
{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_19H_M60H_DF_F3) },
{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_19H_M70H_DF_F3) },
+ { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_19H_M78H_DF_F3) },
{ PCI_VDEVICE(HYGON, PCI_DEVICE_ID_AMD_17H_DF_F3) },
{}
};
diff --git a/drivers/media/pci/ivtv/ivtvfb.c b/drivers/media/pci/ivtv/ivtvfb.c
index 00ac94d4ab19..0aeb9daaee4c 100644
--- a/drivers/media/pci/ivtv/ivtvfb.c
+++ b/drivers/media/pci/ivtv/ivtvfb.c
@@ -378,8 +378,8 @@ static ssize_t ivtvfb_write(struct fb_info *info, const char __user *buf,
unsigned long dma_size;
u16 lead = 0, tail = 0;
- if (info->state != FBINFO_STATE_RUNNING)
- return -EPERM;
+ if (!info->screen_base)
+ return -ENODEV;
total_size = info->screen_size;
diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c
index 75c92e282fa2..19a4a085f73a 100644
--- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c
+++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c
@@ -1035,7 +1035,6 @@ static int mdp_comp_sub_create(struct mdp_dev *mdp)
{
struct device *dev = &mdp->pdev->dev;
struct device_node *node, *parent;
- const struct mtk_mdp_driver_data *data = mdp->mdp_data;
parent = dev->of_node->parent;
@@ -1045,7 +1044,7 @@ static int mdp_comp_sub_create(struct mdp_dev *mdp)
int id, alias_id;
struct mdp_comp *comp;
- of_id = of_match_node(data->mdp_sub_comp_dt_ids, node);
+ of_id = of_match_node(mdp->mdp_data->mdp_sub_comp_dt_ids, node);
if (!of_id)
continue;
if (!of_device_is_available(node)) {
diff --git a/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c b/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c
index 238521622b75..253e77189b69 100644
--- a/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c
+++ b/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c
@@ -378,8 +378,8 @@ static int mxc_isi_runtime_resume(struct device *dev)
}
static const struct dev_pm_ops mxc_isi_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(mxc_isi_pm_suspend, mxc_isi_pm_resume)
- SET_RUNTIME_PM_OPS(mxc_isi_runtime_suspend, mxc_isi_runtime_resume, NULL)
+ SYSTEM_SLEEP_PM_OPS(mxc_isi_pm_suspend, mxc_isi_pm_resume)
+ RUNTIME_PM_OPS(mxc_isi_runtime_suspend, mxc_isi_runtime_resume, NULL)
};
/* -----------------------------------------------------------------------------
@@ -528,7 +528,7 @@ static struct platform_driver mxc_isi_driver = {
.driver = {
.of_match_table = mxc_isi_of_match,
.name = MXC_ISI_DRIVER_NAME,
- .pm = &mxc_isi_pm_ops,
+ .pm = pm_ptr(&mxc_isi_pm_ops),
}
};
module_platform_driver(mxc_isi_driver);
diff --git a/drivers/media/platform/nxp/imx8-isi/imx8-isi-hw.c b/drivers/media/platform/nxp/imx8-isi/imx8-isi-hw.c
index db538f3d88ec..19e80b95ffea 100644
--- a/drivers/media/platform/nxp/imx8-isi/imx8-isi-hw.c
+++ b/drivers/media/platform/nxp/imx8-isi/imx8-isi-hw.c
@@ -29,11 +29,10 @@ static inline void mxc_isi_write(struct mxc_isi_pipe *pipe, u32 reg, u32 val)
void mxc_isi_channel_set_inbuf(struct mxc_isi_pipe *pipe, dma_addr_t dma_addr)
{
- mxc_isi_write(pipe, CHNL_IN_BUF_ADDR, dma_addr);
-#if CONFIG_ARCH_DMA_ADDR_T_64BIT
+ mxc_isi_write(pipe, CHNL_IN_BUF_ADDR, lower_32_bits(dma_addr));
if (pipe->isi->pdata->has_36bit_dma)
- mxc_isi_write(pipe, CHNL_IN_BUF_XTND_ADDR, dma_addr >> 32);
-#endif
+ mxc_isi_write(pipe, CHNL_IN_BUF_XTND_ADDR,
+ upper_32_bits(dma_addr));
}
void mxc_isi_channel_set_outbuf(struct mxc_isi_pipe *pipe,
@@ -45,34 +44,36 @@ void mxc_isi_channel_set_outbuf(struct mxc_isi_pipe *pipe,
val = mxc_isi_read(pipe, CHNL_OUT_BUF_CTRL);
if (buf_id == MXC_ISI_BUF1) {
- mxc_isi_write(pipe, CHNL_OUT_BUF1_ADDR_Y, dma_addrs[0]);
- mxc_isi_write(pipe, CHNL_OUT_BUF1_ADDR_U, dma_addrs[1]);
- mxc_isi_write(pipe, CHNL_OUT_BUF1_ADDR_V, dma_addrs[2]);
-#if CONFIG_ARCH_DMA_ADDR_T_64BIT
+ mxc_isi_write(pipe, CHNL_OUT_BUF1_ADDR_Y,
+ lower_32_bits(dma_addrs[0]));
+ mxc_isi_write(pipe, CHNL_OUT_BUF1_ADDR_U,
+ lower_32_bits(dma_addrs[1]));
+ mxc_isi_write(pipe, CHNL_OUT_BUF1_ADDR_V,
+ lower_32_bits(dma_addrs[2]));
if (pipe->isi->pdata->has_36bit_dma) {
mxc_isi_write(pipe, CHNL_Y_BUF1_XTND_ADDR,
- dma_addrs[0] >> 32);
+ upper_32_bits(dma_addrs[0]));
mxc_isi_write(pipe, CHNL_U_BUF1_XTND_ADDR,
- dma_addrs[1] >> 32);
+ upper_32_bits(dma_addrs[1]));
mxc_isi_write(pipe, CHNL_V_BUF1_XTND_ADDR,
- dma_addrs[2] >> 32);
+ upper_32_bits(dma_addrs[2]));
}
-#endif
val ^= CHNL_OUT_BUF_CTRL_LOAD_BUF1_ADDR;
} else {
- mxc_isi_write(pipe, CHNL_OUT_BUF2_ADDR_Y, dma_addrs[0]);
- mxc_isi_write(pipe, CHNL_OUT_BUF2_ADDR_U, dma_addrs[1]);
- mxc_isi_write(pipe, CHNL_OUT_BUF2_ADDR_V, dma_addrs[2]);
-#if CONFIG_ARCH_DMA_ADDR_T_64BIT
+ mxc_isi_write(pipe, CHNL_OUT_BUF2_ADDR_Y,
+ lower_32_bits(dma_addrs[0]));
+ mxc_isi_write(pipe, CHNL_OUT_BUF2_ADDR_U,
+ lower_32_bits(dma_addrs[1]));
+ mxc_isi_write(pipe, CHNL_OUT_BUF2_ADDR_V,
+ lower_32_bits(dma_addrs[2]));
if (pipe->isi->pdata->has_36bit_dma) {
mxc_isi_write(pipe, CHNL_Y_BUF2_XTND_ADDR,
- dma_addrs[0] >> 32);
+ upper_32_bits(dma_addrs[0]));
mxc_isi_write(pipe, CHNL_U_BUF2_XTND_ADDR,
- dma_addrs[1] >> 32);
+ upper_32_bits(dma_addrs[1]));
mxc_isi_write(pipe, CHNL_V_BUF2_XTND_ADDR,
- dma_addrs[2] >> 32);
+ upper_32_bits(dma_addrs[2]));
}
-#endif
val ^= CHNL_OUT_BUF_CTRL_LOAD_BUF2_ADDR;
}
diff --git a/drivers/media/platform/renesas/rcar-vin/rcar-dma.c b/drivers/media/platform/renesas/rcar-vin/rcar-dma.c
index 98bfd445a649..2a77353f10b5 100644
--- a/drivers/media/platform/renesas/rcar-vin/rcar-dma.c
+++ b/drivers/media/platform/renesas/rcar-vin/rcar-dma.c
@@ -728,11 +728,9 @@ static int rvin_setup(struct rvin_dev *vin)
case V4L2_FIELD_SEQ_TB:
case V4L2_FIELD_SEQ_BT:
case V4L2_FIELD_NONE:
- vnmc = VNMC_IM_ODD_EVEN;
- progressive = true;
- break;
case V4L2_FIELD_ALTERNATE:
vnmc = VNMC_IM_ODD_EVEN;
+ progressive = true;
break;
default:
vnmc = VNMC_IM_ODD;
@@ -1312,12 +1310,23 @@ static int rvin_mc_validate_format(struct rvin_dev *vin, struct v4l2_subdev *sd,
}
if (rvin_scaler_needed(vin)) {
+ /* Gen3 can't scale NV12 */
+ if (vin->info->model == RCAR_GEN3 &&
+ vin->format.pixelformat == V4L2_PIX_FMT_NV12)
+ return -EPIPE;
+
if (!vin->scaler)
return -EPIPE;
} else {
- if (fmt.format.width != vin->format.width ||
- fmt.format.height != vin->format.height)
- return -EPIPE;
+ if (vin->format.pixelformat == V4L2_PIX_FMT_NV12) {
+ if (ALIGN(fmt.format.width, 32) != vin->format.width ||
+ ALIGN(fmt.format.height, 32) != vin->format.height)
+ return -EPIPE;
+ } else {
+ if (fmt.format.width != vin->format.width ||
+ fmt.format.height != vin->format.height)
+ return -EPIPE;
+ }
}
if (fmt.format.code != vin->mbus_code)
diff --git a/drivers/misc/mei/Kconfig b/drivers/misc/mei/Kconfig
index d21486d69df2..37db142de413 100644
--- a/drivers/misc/mei/Kconfig
+++ b/drivers/misc/mei/Kconfig
@@ -62,4 +62,4 @@ config INTEL_MEI_GSC
source "drivers/misc/mei/hdcp/Kconfig"
source "drivers/misc/mei/pxp/Kconfig"
-
+source "drivers/misc/mei/gsc_proxy/Kconfig"
diff --git a/drivers/misc/mei/Makefile b/drivers/misc/mei/Makefile
index fb740d754900..14aee253ae48 100644
--- a/drivers/misc/mei/Makefile
+++ b/drivers/misc/mei/Makefile
@@ -30,3 +30,4 @@ CFLAGS_mei-trace.o = -I$(src)
obj-$(CONFIG_INTEL_MEI_HDCP) += hdcp/
obj-$(CONFIG_INTEL_MEI_PXP) += pxp/
+obj-$(CONFIG_INTEL_MEI_GSC_PROXY) += gsc_proxy/
diff --git a/drivers/misc/mei/gsc_proxy/Kconfig b/drivers/misc/mei/gsc_proxy/Kconfig
new file mode 100644
index 000000000000..5f68d9f3d691
--- /dev/null
+++ b/drivers/misc/mei/gsc_proxy/Kconfig
@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+#
+config INTEL_MEI_GSC_PROXY
+ tristate "Intel GSC Proxy services of ME Interface"
+ select INTEL_MEI_ME
+ depends on DRM_I915
+ help
+ MEI Support for GSC Proxy Services on Intel platforms.
+
+ MEI GSC proxy enables messaging between GSC service on
+ Intel graphics card and services on CSE (MEI) firmware
+ residing SoC or PCH.
+
diff --git a/drivers/misc/mei/gsc_proxy/Makefile b/drivers/misc/mei/gsc_proxy/Makefile
new file mode 100644
index 000000000000..358847e9aaa9
--- /dev/null
+++ b/drivers/misc/mei/gsc_proxy/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+#
+# Makefile - GSC Proxy client driver for Intel MEI Bus Driver.
+
+obj-$(CONFIG_INTEL_MEI_GSC_PROXY) += mei_gsc_proxy.o
diff --git a/drivers/misc/mei/gsc_proxy/mei_gsc_proxy.c b/drivers/misc/mei/gsc_proxy/mei_gsc_proxy.c
new file mode 100644
index 000000000000..be52b113aea9
--- /dev/null
+++ b/drivers/misc/mei/gsc_proxy/mei_gsc_proxy.c
@@ -0,0 +1,208 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022-2023 Intel Corporation
+ */
+
+/**
+ * DOC: MEI_GSC_PROXY Client Driver
+ *
+ * The mei_gsc_proxy driver acts as a translation layer between
+ * proxy user (I915) and ME FW by proxying messages to ME FW
+ */
+
+#include <linux/component.h>
+#include <linux/mei_cl_bus.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/uuid.h>
+#include <drm/drm_connector.h>
+#include <drm/i915_component.h>
+#include <drm/i915_gsc_proxy_mei_interface.h>
+
+/**
+ * mei_gsc_proxy_send - Sends a proxy message to ME FW.
+ * @dev: device corresponding to the mei_cl_device
+ * @buf: a message buffer to send
+ * @size: size of the message
+ * Return: bytes sent on Success, <0 on Failure
+ */
+static int mei_gsc_proxy_send(struct device *dev, const void *buf, size_t size)
+{
+ ssize_t ret;
+
+ if (!dev || !buf)
+ return -EINVAL;
+
+ ret = mei_cldev_send(to_mei_cl_device(dev), buf, size);
+ if (ret < 0)
+ dev_dbg(dev, "mei_cldev_send failed. %zd\n", ret);
+
+ return ret;
+}
+
+/**
+ * mei_gsc_proxy_recv - Receives a proxy message from ME FW.
+ * @dev: device corresponding to the mei_cl_device
+ * @buf: a message buffer to contain the received message
+ * @size: size of the buffer
+ * Return: bytes received on Success, <0 on Failure
+ */
+static int mei_gsc_proxy_recv(struct device *dev, void *buf, size_t size)
+{
+ ssize_t ret;
+
+ if (!dev || !buf)
+ return -EINVAL;
+
+ ret = mei_cldev_recv(to_mei_cl_device(dev), buf, size);
+ if (ret < 0)
+ dev_dbg(dev, "mei_cldev_recv failed. %zd\n", ret);
+
+ return ret;
+}
+
+static const struct i915_gsc_proxy_component_ops mei_gsc_proxy_ops = {
+ .owner = THIS_MODULE,
+ .send = mei_gsc_proxy_send,
+ .recv = mei_gsc_proxy_recv,
+};
+
+static int mei_component_master_bind(struct device *dev)
+{
+ struct mei_cl_device *cldev = to_mei_cl_device(dev);
+ struct i915_gsc_proxy_component *comp_master = mei_cldev_get_drvdata(cldev);
+
+ comp_master->ops = &mei_gsc_proxy_ops;
+ comp_master->mei_dev = dev;
+ return component_bind_all(dev, comp_master);
+}
+
+static void mei_component_master_unbind(struct device *dev)
+{
+ struct mei_cl_device *cldev = to_mei_cl_device(dev);
+ struct i915_gsc_proxy_component *comp_master = mei_cldev_get_drvdata(cldev);
+
+ component_unbind_all(dev, comp_master);
+}
+
+static const struct component_master_ops mei_component_master_ops = {
+ .bind = mei_component_master_bind,
+ .unbind = mei_component_master_unbind,
+};
+
+/**
+ * mei_gsc_proxy_component_match - compare function for matching mei.
+ *
+ * The function checks if the device is pci device and
+ * Intel VGA adapter, the subcomponent is SW Proxy
+ * and the parent of MEI PCI and the parent of VGA are the same PCH device.
+ *
+ * @dev: master device
+ * @subcomponent: subcomponent to match (I915_COMPONENT_SWPROXY)
+ * @data: compare data (mei pci parent)
+ *
+ * Return:
+ * * 1 - if components match
+ * * 0 - otherwise
+ */
+static int mei_gsc_proxy_component_match(struct device *dev, int subcomponent,
+ void *data)
+{
+ struct pci_dev *pdev;
+
+ if (!dev_is_pci(dev))
+ return 0;
+
+ pdev = to_pci_dev(dev);
+
+ if (pdev->class != (PCI_CLASS_DISPLAY_VGA << 8) ||
+ pdev->vendor != PCI_VENDOR_ID_INTEL)
+ return 0;
+
+ if (subcomponent != I915_COMPONENT_GSC_PROXY)
+ return 0;
+
+ return component_compare_dev(dev->parent, ((struct device *)data)->parent);
+}
+
+static int mei_gsc_proxy_probe(struct mei_cl_device *cldev,
+ const struct mei_cl_device_id *id)
+{
+ struct i915_gsc_proxy_component *comp_master;
+ struct component_match *master_match = NULL;
+ int ret;
+
+ ret = mei_cldev_enable(cldev);
+ if (ret < 0) {
+ dev_err(&cldev->dev, "mei_cldev_enable Failed. %d\n", ret);
+ goto enable_err_exit;
+ }
+
+ comp_master = kzalloc(sizeof(*comp_master), GFP_KERNEL);
+ if (!comp_master) {
+ ret = -ENOMEM;
+ goto err_exit;
+ }
+
+ component_match_add_typed(&cldev->dev, &master_match,
+ mei_gsc_proxy_component_match, cldev->dev.parent);
+ if (IS_ERR_OR_NULL(master_match)) {
+ ret = -ENOMEM;
+ goto err_exit;
+ }
+
+ mei_cldev_set_drvdata(cldev, comp_master);
+ ret = component_master_add_with_match(&cldev->dev,
+ &mei_component_master_ops,
+ master_match);
+ if (ret < 0) {
+ dev_err(&cldev->dev, "Master comp add failed %d\n", ret);
+ goto err_exit;
+ }
+
+ return 0;
+
+err_exit:
+ mei_cldev_set_drvdata(cldev, NULL);
+ kfree(comp_master);
+ mei_cldev_disable(cldev);
+enable_err_exit:
+ return ret;
+}
+
+static void mei_gsc_proxy_remove(struct mei_cl_device *cldev)
+{
+ struct i915_gsc_proxy_component *comp_master = mei_cldev_get_drvdata(cldev);
+ int ret;
+
+ component_master_del(&cldev->dev, &mei_component_master_ops);
+ kfree(comp_master);
+ mei_cldev_set_drvdata(cldev, NULL);
+
+ ret = mei_cldev_disable(cldev);
+ if (ret)
+ dev_warn(&cldev->dev, "mei_cldev_disable() failed %d\n", ret);
+}
+
+#define MEI_UUID_GSC_PROXY UUID_LE(0xf73db04, 0x97ab, 0x4125, \
+ 0xb8, 0x93, 0xe9, 0x4, 0xad, 0xd, 0x54, 0x64)
+
+static struct mei_cl_device_id mei_gsc_proxy_tbl[] = {
+ { .uuid = MEI_UUID_GSC_PROXY, .version = MEI_CL_VERSION_ANY },
+ { }
+};
+MODULE_DEVICE_TABLE(mei, mei_gsc_proxy_tbl);
+
+static struct mei_cl_driver mei_gsc_proxy_driver = {
+ .id_table = mei_gsc_proxy_tbl,
+ .name = KBUILD_MODNAME,
+ .probe = mei_gsc_proxy_probe,
+ .remove = mei_gsc_proxy_remove,
+};
+
+module_mei_cl_driver(mei_gsc_proxy_driver);
+
+MODULE_AUTHOR("Intel Corporation");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("MEI GSC PROXY");
diff --git a/drivers/net/bonding/bond_netlink.c b/drivers/net/bonding/bond_netlink.c
index c2d080fc4fc4..27cbe148f0db 100644
--- a/drivers/net/bonding/bond_netlink.c
+++ b/drivers/net/bonding/bond_netlink.c
@@ -84,6 +84,11 @@ nla_put_failure:
return -EMSGSIZE;
}
+/* Limit the max delay range to 300s */
+static struct netlink_range_validation delay_range = {
+ .max = 300000,
+};
+
static const struct nla_policy bond_policy[IFLA_BOND_MAX + 1] = {
[IFLA_BOND_MODE] = { .type = NLA_U8 },
[IFLA_BOND_ACTIVE_SLAVE] = { .type = NLA_U32 },
@@ -114,7 +119,7 @@ static const struct nla_policy bond_policy[IFLA_BOND_MAX + 1] = {
[IFLA_BOND_AD_ACTOR_SYSTEM] = { .type = NLA_BINARY,
.len = ETH_ALEN },
[IFLA_BOND_TLB_DYNAMIC_LB] = { .type = NLA_U8 },
- [IFLA_BOND_PEER_NOTIF_DELAY] = { .type = NLA_U32 },
+ [IFLA_BOND_PEER_NOTIF_DELAY] = NLA_POLICY_FULL_RANGE(NLA_U32, &delay_range),
[IFLA_BOND_MISSED_MAX] = { .type = NLA_U8 },
[IFLA_BOND_NS_IP6_TARGET] = { .type = NLA_NESTED },
};
diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c
index 0498fc6731f8..f3f27f0bd2a6 100644
--- a/drivers/net/bonding/bond_options.c
+++ b/drivers/net/bonding/bond_options.c
@@ -169,6 +169,12 @@ static const struct bond_opt_value bond_num_peer_notif_tbl[] = {
{ NULL, -1, 0}
};
+static const struct bond_opt_value bond_peer_notif_delay_tbl[] = {
+ { "off", 0, 0},
+ { "maxval", 300000, BOND_VALFLAG_MAX},
+ { NULL, -1, 0}
+};
+
static const struct bond_opt_value bond_primary_reselect_tbl[] = {
{ "always", BOND_PRI_RESELECT_ALWAYS, BOND_VALFLAG_DEFAULT},
{ "better", BOND_PRI_RESELECT_BETTER, 0},
@@ -488,7 +494,7 @@ static const struct bond_option bond_opts[BOND_OPT_LAST] = {
.id = BOND_OPT_PEER_NOTIF_DELAY,
.name = "peer_notif_delay",
.desc = "Delay between each peer notification on failover event, in milliseconds",
- .values = bond_intmax_tbl,
+ .values = bond_peer_notif_delay_tbl,
.set = bond_option_peer_notif_delay_set
}
};
diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c
index 57ce74315eba..caa00c72aeeb 100644
--- a/drivers/net/ethernet/google/gve/gve_main.c
+++ b/drivers/net/ethernet/google/gve/gve_main.c
@@ -294,19 +294,6 @@ static int gve_napi_poll_dqo(struct napi_struct *napi, int budget)
bool reschedule = false;
int work_done = 0;
- /* Clear PCI MSI-X Pending Bit Array (PBA)
- *
- * This bit is set if an interrupt event occurs while the vector is
- * masked. If this bit is set and we reenable the interrupt, it will
- * fire again. Since we're just about to poll the queue state, we don't
- * need it to fire again.
- *
- * Under high softirq load, it's possible that the interrupt condition
- * is triggered twice before we got the chance to process it.
- */
- gve_write_irq_doorbell_dqo(priv, block,
- GVE_ITR_NO_UPDATE_DQO | GVE_ITR_CLEAR_PBA_BIT_DQO);
-
if (block->tx)
reschedule |= gve_tx_poll_dqo(block, /*do_clean=*/true);
diff --git a/drivers/net/ethernet/mediatek/mtk_wed.c b/drivers/net/ethernet/mediatek/mtk_wed.c
index 4c205afbd230..985cff910f30 100644
--- a/drivers/net/ethernet/mediatek/mtk_wed.c
+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
@@ -654,7 +654,7 @@ __mtk_wed_detach(struct mtk_wed_device *dev)
BIT(hw->index), BIT(hw->index));
}
- if (!hw_list[!hw->index]->wed_dev &&
+ if ((!hw_list[!hw->index] || !hw_list[!hw->index]->wed_dev) &&
hw->eth->dma_dev != hw->eth->dev)
mtk_eth_set_dma_device(hw->eth, hw->eth->dev);
diff --git a/drivers/net/ethernet/mscc/vsc7514_regs.c b/drivers/net/ethernet/mscc/vsc7514_regs.c
index ef6fd3f6be30..5595bfe84bbb 100644
--- a/drivers/net/ethernet/mscc/vsc7514_regs.c
+++ b/drivers/net/ethernet/mscc/vsc7514_regs.c
@@ -307,15 +307,15 @@ static const u32 vsc7514_sys_regmap[] = {
REG(SYS_COUNT_DROP_YELLOW_PRIO_4, 0x000218),
REG(SYS_COUNT_DROP_YELLOW_PRIO_5, 0x00021c),
REG(SYS_COUNT_DROP_YELLOW_PRIO_6, 0x000220),
- REG(SYS_COUNT_DROP_YELLOW_PRIO_7, 0x000214),
- REG(SYS_COUNT_DROP_GREEN_PRIO_0, 0x000218),
- REG(SYS_COUNT_DROP_GREEN_PRIO_1, 0x00021c),
- REG(SYS_COUNT_DROP_GREEN_PRIO_2, 0x000220),
- REG(SYS_COUNT_DROP_GREEN_PRIO_3, 0x000224),
- REG(SYS_COUNT_DROP_GREEN_PRIO_4, 0x000228),
- REG(SYS_COUNT_DROP_GREEN_PRIO_5, 0x00022c),
- REG(SYS_COUNT_DROP_GREEN_PRIO_6, 0x000230),
- REG(SYS_COUNT_DROP_GREEN_PRIO_7, 0x000234),
+ REG(SYS_COUNT_DROP_YELLOW_PRIO_7, 0x000224),
+ REG(SYS_COUNT_DROP_GREEN_PRIO_0, 0x000228),
+ REG(SYS_COUNT_DROP_GREEN_PRIO_1, 0x00022c),
+ REG(SYS_COUNT_DROP_GREEN_PRIO_2, 0x000230),
+ REG(SYS_COUNT_DROP_GREEN_PRIO_3, 0x000234),
+ REG(SYS_COUNT_DROP_GREEN_PRIO_4, 0x000238),
+ REG(SYS_COUNT_DROP_GREEN_PRIO_5, 0x00023c),
+ REG(SYS_COUNT_DROP_GREEN_PRIO_6, 0x000240),
+ REG(SYS_COUNT_DROP_GREEN_PRIO_7, 0x000244),
REG(SYS_RESET_CFG, 0x000508),
REG(SYS_CMID, 0x00050c),
REG(SYS_VLAN_ETYPE_CFG, 0x000510),
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
index 4538f334df57..d3c5306f1c41 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
@@ -181,6 +181,7 @@ enum power_event {
#define GMAC4_LPI_CTRL_STATUS 0xd0
#define GMAC4_LPI_TIMER_CTRL 0xd4
#define GMAC4_LPI_ENTRY_TIMER 0xd8
+#define GMAC4_MAC_ONEUS_TIC_COUNTER 0xdc
/* LPI control and status defines */
#define GMAC4_LPI_CTRL_STATUS_LPITCSE BIT(21) /* LPI Tx Clock Stop Enable */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
index afaec3fb9ab6..03b1c5a97826 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
@@ -25,6 +25,7 @@ static void dwmac4_core_init(struct mac_device_info *hw,
struct stmmac_priv *priv = netdev_priv(dev);
void __iomem *ioaddr = hw->pcsr;
u32 value = readl(ioaddr + GMAC_CONFIG);
+ u32 clk_rate;
value |= GMAC_CORE_INIT;
@@ -47,6 +48,10 @@ static void dwmac4_core_init(struct mac_device_info *hw,
writel(value, ioaddr + GMAC_CONFIG);
+ /* Configure LPI 1us counter to number of CSR clock ticks in 1us - 1 */
+ clk_rate = clk_get_rate(priv->plat->stmmac_clk);
+ writel((clk_rate / 1000000) - 1, ioaddr + GMAC4_MAC_ONEUS_TIC_COUNTER);
+
/* Enable GMAC interrupts */
value = GMAC_INT_DEFAULT_ENABLE;
diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c
index 460b3d4f2245..ab5133eb1d51 100644
--- a/drivers/net/ipvlan/ipvlan_core.c
+++ b/drivers/net/ipvlan/ipvlan_core.c
@@ -436,6 +436,9 @@ static int ipvlan_process_v4_outbound(struct sk_buff *skb)
goto err;
}
skb_dst_set(skb, &rt->dst);
+
+ memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
+
err = ip_local_out(net, skb->sk, skb);
if (unlikely(net_xmit_eval(err)))
dev->stats.tx_errors++;
@@ -474,6 +477,9 @@ static int ipvlan_process_v6_outbound(struct sk_buff *skb)
goto err;
}
skb_dst_set(skb, dst);
+
+ memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
+
err = ip6_local_out(net, skb->sk, skb);
if (unlikely(net_xmit_eval(err)))
dev->stats.tx_errors++;
diff --git a/drivers/net/mdio/mdio-mvusb.c b/drivers/net/mdio/mdio-mvusb.c
index 68fc55906e78..554837c21e73 100644
--- a/drivers/net/mdio/mdio-mvusb.c
+++ b/drivers/net/mdio/mdio-mvusb.c
@@ -67,6 +67,7 @@ static int mvusb_mdio_probe(struct usb_interface *interface,
struct device *dev = &interface->dev;
struct mvusb_mdio *mvusb;
struct mii_bus *mdio;
+ int ret;
mdio = devm_mdiobus_alloc_size(dev, sizeof(*mvusb));
if (!mdio)
@@ -87,7 +88,15 @@ static int mvusb_mdio_probe(struct usb_interface *interface,
mdio->write = mvusb_mdio_write;
usb_set_intfdata(interface, mvusb);
- return of_mdiobus_register(mdio, dev->of_node);
+ ret = of_mdiobus_register(mdio, dev->of_node);
+ if (ret)
+ goto put_dev;
+
+ return 0;
+
+put_dev:
+ usb_put_dev(mvusb->udev);
+ return ret;
}
static void mvusb_mdio_disconnect(struct usb_interface *interface)
diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c
index 539cd43eae8d..f19d48c94fe0 100644
--- a/drivers/net/pcs/pcs-xpcs.c
+++ b/drivers/net/pcs/pcs-xpcs.c
@@ -1203,7 +1203,7 @@ static const struct xpcs_compat synopsys_xpcs_compat[DW_XPCS_INTERFACE_MAX] = {
[DW_XPCS_2500BASEX] = {
.supported = xpcs_2500basex_features,
.interface = xpcs_2500basex_interfaces,
- .num_interfaces = ARRAY_SIZE(xpcs_2500basex_features),
+ .num_interfaces = ARRAY_SIZE(xpcs_2500basex_interfaces),
.an_mode = DW_2500BASEX,
},
};
diff --git a/drivers/net/phy/bcm-phy-lib.h b/drivers/net/phy/bcm-phy-lib.h
index 9902fb182099..729db441797a 100644
--- a/drivers/net/phy/bcm-phy-lib.h
+++ b/drivers/net/phy/bcm-phy-lib.h
@@ -40,6 +40,11 @@ static inline int bcm_phy_write_exp_sel(struct phy_device *phydev,
return bcm_phy_write_exp(phydev, reg | MII_BCM54XX_EXP_SEL_ER, val);
}
+static inline int bcm_phy_read_exp_sel(struct phy_device *phydev, u16 reg)
+{
+ return bcm_phy_read_exp(phydev, reg | MII_BCM54XX_EXP_SEL_ER);
+}
+
int bcm54xx_auxctl_write(struct phy_device *phydev, u16 regnum, u16 val);
int bcm54xx_auxctl_read(struct phy_device *phydev, u16 regnum);
diff --git a/drivers/net/phy/bcm7xxx.c b/drivers/net/phy/bcm7xxx.c
index 06be71ecd2f8..f8c17a253f8b 100644
--- a/drivers/net/phy/bcm7xxx.c
+++ b/drivers/net/phy/bcm7xxx.c
@@ -486,7 +486,7 @@ static int bcm7xxx_16nm_ephy_afe_config(struct phy_device *phydev)
bcm_phy_write_misc(phydev, 0x0038, 0x0002, 0xede0);
/* Read CORE_EXPA9 */
- tmp = bcm_phy_read_exp(phydev, 0x00a9);
+ tmp = bcm_phy_read_exp_sel(phydev, 0x00a9);
/* CORE_EXPA9[6:1] is rcalcode[5:0] */
rcalcode = (tmp & 0x7e) / 2;
/* Correct RCAL code + 1 is -1% rprogr, LP: +16 */
diff --git a/drivers/net/tap.c b/drivers/net/tap.c
index ce993cc75bf3..d30d730ed5a7 100644
--- a/drivers/net/tap.c
+++ b/drivers/net/tap.c
@@ -742,7 +742,7 @@ static ssize_t tap_get_user(struct tap_queue *q, void *msg_control,
/* Move network header to the right position for VLAN tagged packets */
if (eth_type_vlan(skb->protocol) &&
- __vlan_get_protocol(skb, skb->protocol, &depth) != 0)
+ vlan_get_protocol_and_depth(skb, skb->protocol, &depth) != 0)
skb_set_network_header(skb, depth);
/* copy skb_ubuf_info for callback when skb has no error */
@@ -1197,7 +1197,7 @@ static int tap_get_user_xdp(struct tap_queue *q, struct xdp_buff *xdp)
/* Move network header to the right position for VLAN tagged packets */
if (eth_type_vlan(skb->protocol) &&
- __vlan_get_protocol(skb, skb->protocol, &depth) != 0)
+ vlan_get_protocol_and_depth(skb, skb->protocol, &depth) != 0)
skb_set_network_header(skb, depth);
rcu_read_lock();
diff --git a/drivers/platform/mellanox/mlxbf-tmfifo.c b/drivers/platform/mellanox/mlxbf-tmfifo.c
index 91a077c35b8b..a79318e90a13 100644
--- a/drivers/platform/mellanox/mlxbf-tmfifo.c
+++ b/drivers/platform/mellanox/mlxbf-tmfifo.c
@@ -784,7 +784,7 @@ static void mlxbf_tmfifo_rxtx(struct mlxbf_tmfifo_vring *vring, bool is_rx)
fifo = vring->fifo;
/* Return if vdev is not ready. */
- if (!fifo->vdev[devid])
+ if (!fifo || !fifo->vdev[devid])
return;
/* Return if another vring is running. */
@@ -980,9 +980,13 @@ static int mlxbf_tmfifo_virtio_find_vqs(struct virtio_device *vdev,
vq->num_max = vring->num;
+ vq->priv = vring;
+
+ /* Make vq update visible before using it. */
+ virtio_mb(false);
+
vqs[i] = vq;
vring->vq = vq;
- vq->priv = vring;
}
return 0;
@@ -1302,6 +1306,9 @@ static int mlxbf_tmfifo_probe(struct platform_device *pdev)
mod_timer(&fifo->timer, jiffies + MLXBF_TMFIFO_TIMER_INTERVAL);
+ /* Make all updates visible before setting the 'is_ready' flag. */
+ virtio_mb(false);
+
fifo->is_ready = true;
return 0;
diff --git a/drivers/platform/x86/hp/hp-wmi.c b/drivers/platform/x86/hp/hp-wmi.c
index 873f59c3e280..6364ae262705 100644
--- a/drivers/platform/x86/hp/hp-wmi.c
+++ b/drivers/platform/x86/hp/hp-wmi.c
@@ -211,6 +211,7 @@ struct bios_rfkill2_state {
static const struct key_entry hp_wmi_keymap[] = {
{ KE_KEY, 0x02, { KEY_BRIGHTNESSUP } },
{ KE_KEY, 0x03, { KEY_BRIGHTNESSDOWN } },
+ { KE_KEY, 0x270, { KEY_MICMUTE } },
{ KE_KEY, 0x20e6, { KEY_PROG1 } },
{ KE_KEY, 0x20e8, { KEY_MEDIA } },
{ KE_KEY, 0x2142, { KEY_MEDIA } },
diff --git a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c
index 1a300e14f350..064f186ae81b 100644
--- a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c
+++ b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c
@@ -44,14 +44,18 @@ static ssize_t store_min_max_freq_khz(struct uncore_data *data,
int min_max)
{
unsigned int input;
+ int ret;
if (kstrtouint(buf, 10, &input))
return -EINVAL;
mutex_lock(&uncore_lock);
- uncore_write(data, input, min_max);
+ ret = uncore_write(data, input, min_max);
mutex_unlock(&uncore_lock);
+ if (ret)
+ return ret;
+
return count;
}
diff --git a/drivers/platform/x86/intel_scu_pcidrv.c b/drivers/platform/x86/intel_scu_pcidrv.c
index 80abc708e4f2..d904fad499aa 100644
--- a/drivers/platform/x86/intel_scu_pcidrv.c
+++ b/drivers/platform/x86/intel_scu_pcidrv.c
@@ -34,6 +34,7 @@ static int intel_scu_pci_probe(struct pci_dev *pdev,
static const struct pci_device_id pci_ids[] = {
{ PCI_VDEVICE(INTEL, 0x080e) },
+ { PCI_VDEVICE(INTEL, 0x082a) },
{ PCI_VDEVICE(INTEL, 0x08ea) },
{ PCI_VDEVICE(INTEL, 0x0a94) },
{ PCI_VDEVICE(INTEL, 0x11a0) },
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index 6fe82f805ea8..b3808ad77278 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -10318,6 +10318,7 @@ static atomic_t dytc_ignore_event = ATOMIC_INIT(0);
static DEFINE_MUTEX(dytc_mutex);
static int dytc_capabilities;
static bool dytc_mmc_get_available;
+static int profile_force;
static int convert_dytc_to_profile(int funcmode, int dytcmode,
enum platform_profile_option *profile)
@@ -10580,6 +10581,21 @@ static int tpacpi_dytc_profile_init(struct ibm_init_struct *iibm)
if (err)
return err;
+ /* Check if user wants to override the profile selection */
+ if (profile_force) {
+ switch (profile_force) {
+ case -1:
+ dytc_capabilities = 0;
+ break;
+ case 1:
+ dytc_capabilities = BIT(DYTC_FC_MMC);
+ break;
+ case 2:
+ dytc_capabilities = BIT(DYTC_FC_PSC);
+ break;
+ }
+ pr_debug("Profile selection forced: 0x%x\n", dytc_capabilities);
+ }
if (dytc_capabilities & BIT(DYTC_FC_MMC)) { /* MMC MODE */
pr_debug("MMC is supported\n");
/*
@@ -10593,11 +10609,6 @@ static int tpacpi_dytc_profile_init(struct ibm_init_struct *iibm)
dytc_mmc_get_available = true;
}
} else if (dytc_capabilities & BIT(DYTC_FC_PSC)) { /* PSC MODE */
- /* Support for this only works on AMD platforms */
- if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) {
- dbg_printk(TPACPI_DBG_INIT, "PSC not support on Intel platforms\n");
- return -ENODEV;
- }
pr_debug("PSC is supported\n");
} else {
dbg_printk(TPACPI_DBG_INIT, "No DYTC support available\n");
@@ -11646,6 +11657,9 @@ MODULE_PARM_DESC(uwb_state,
"Initial state of the emulated UWB switch");
#endif
+module_param(profile_force, int, 0444);
+MODULE_PARM_DESC(profile_force, "Force profile mode. -1=off, 1=MMC, 2=PSC");
+
static void thinkpad_acpi_module_exit(void)
{
struct ibm_struct *ibm, *itmp;
diff --git a/drivers/platform/x86/touchscreen_dmi.c b/drivers/platform/x86/touchscreen_dmi.c
index 13802a3c3591..68e66b60445c 100644
--- a/drivers/platform/x86/touchscreen_dmi.c
+++ b/drivers/platform/x86/touchscreen_dmi.c
@@ -336,6 +336,22 @@ static const struct ts_dmi_data dexp_ursus_7w_data = {
.properties = dexp_ursus_7w_props,
};
+static const struct property_entry dexp_ursus_kx210i_props[] = {
+ PROPERTY_ENTRY_U32("touchscreen-min-x", 5),
+ PROPERTY_ENTRY_U32("touchscreen-min-y", 2),
+ PROPERTY_ENTRY_U32("touchscreen-size-x", 1720),
+ PROPERTY_ENTRY_U32("touchscreen-size-y", 1137),
+ PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-dexp-ursus-kx210i.fw"),
+ PROPERTY_ENTRY_U32("silead,max-fingers", 10),
+ PROPERTY_ENTRY_BOOL("silead,home-button"),
+ { }
+};
+
+static const struct ts_dmi_data dexp_ursus_kx210i_data = {
+ .acpi_name = "MSSL1680:00",
+ .properties = dexp_ursus_kx210i_props,
+};
+
static const struct property_entry digma_citi_e200_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-x", 1980),
PROPERTY_ENTRY_U32("touchscreen-size-y", 1500),
@@ -378,6 +394,11 @@ static const struct ts_dmi_data gdix1001_01_upside_down_data = {
.properties = gdix1001_upside_down_props,
};
+static const struct ts_dmi_data gdix1002_00_upside_down_data = {
+ .acpi_name = "GDIX1002:00",
+ .properties = gdix1001_upside_down_props,
+};
+
static const struct property_entry gp_electronic_t701_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-x", 960),
PROPERTY_ENTRY_U32("touchscreen-size-y", 640),
@@ -1186,6 +1207,14 @@ const struct dmi_system_id touchscreen_dmi_table[] = {
},
},
{
+ /* DEXP Ursus KX210i */
+ .driver_data = (void *)&dexp_ursus_kx210i_data,
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "INSYDE Corp."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "S107I"),
+ },
+ },
+ {
/* Digma Citi E200 */
.driver_data = (void *)&digma_citi_e200_data,
.matches = {
@@ -1296,6 +1325,18 @@ const struct dmi_system_id touchscreen_dmi_table[] = {
},
},
{
+ /* Juno Tablet */
+ .driver_data = (void *)&gdix1002_00_upside_down_data,
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Default string"),
+ /* Both product- and board-name being "Default string" is somewhat rare */
+ DMI_MATCH(DMI_PRODUCT_NAME, "Default string"),
+ DMI_MATCH(DMI_BOARD_NAME, "Default string"),
+ /* Above matches are too generic, add partial bios-version match */
+ DMI_MATCH(DMI_BIOS_VERSION, "JP2V1."),
+ },
+ },
+ {
/* Mediacom WinPad 7.0 W700 (same hw as Wintron surftab 7") */
.driver_data = (void *)&trekstor_surftab_wintron70_data,
.matches = {
diff --git a/drivers/staging/sm750fb/sm750.c b/drivers/staging/sm750fb/sm750.c
index 22ace3168723..55e302a27847 100644
--- a/drivers/staging/sm750fb/sm750.c
+++ b/drivers/staging/sm750fb/sm750.c
@@ -16,7 +16,7 @@
#include <linux/pagemap.h>
#include <linux/screen_info.h>
#include <linux/console.h>
-#include <asm/fb.h>
+
#include "sm750.h"
#include "sm750_accel.h"
#include "sm750_cursor.h"
diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index 17d7bb875fee..45fd374fe56c 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -9459,8 +9459,16 @@ static int __ufshcd_wl_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op)
* that performance might be impacted.
*/
ret = ufshcd_urgent_bkops(hba);
- if (ret)
+ if (ret) {
+ /*
+ * If return err in suspend flow, IO will hang.
+ * Trigger error handler and break suspend for
+ * error recovery.
+ */
+ ufshcd_force_error_recovery(hba);
+ ret = -EBUSY;
goto enable_scaling;
+ }
} else {
/* make sure that auto bkops is disabled */
ufshcd_disable_auto_bkops(hba);
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index bf05363d8906..8b2b9ac37c3d 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -11,6 +11,13 @@ config APERTURE_HELPERS
Support tracking and hand-over of aperture ownership. Required
by graphics drivers for firmware-provided framebuffers.
+config STI_CORE
+ bool
+ depends on PARISC
+ help
+ STI refers to the HP "Standard Text Interface" which is a set of
+ BIOS routines contained in a ROM chip in HP PA-RISC based machines.
+
config VIDEO_CMDLINE
bool
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 831c9fa57a6c..6bbc03950899 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_APERTURE_HELPERS) += aperture.o
+obj-$(CONFIG_STI_CORE) += sticore.o
obj-$(CONFIG_VGASTATE) += vgastate.o
obj-$(CONFIG_VIDEO_CMDLINE) += cmdline.o
obj-$(CONFIG_VIDEO_NOMODESET) += nomodeset.o
diff --git a/drivers/video/aperture.c b/drivers/video/aperture.c
index b009468ffdff..561be8feca96 100644
--- a/drivers/video/aperture.c
+++ b/drivers/video/aperture.c
@@ -43,7 +43,7 @@
* base = mem->start;
* size = resource_size(mem);
*
- * ret = aperture_remove_conflicting_devices(base, size, false, "example");
+ * ret = aperture_remove_conflicting_devices(base, size, "example");
* if (ret)
* return ret;
*
@@ -274,7 +274,6 @@ static void aperture_detach_devices(resource_size_t base, resource_size_t size)
* aperture_remove_conflicting_devices - remove devices in the given range
* @base: the aperture's base address in physical memory
* @size: aperture size in bytes
- * @primary: also kick vga16fb if present; only relevant for VGA devices
* @name: a descriptive name of the requesting driver
*
* This function removes devices that own apertures within @base and @size.
@@ -283,7 +282,7 @@ static void aperture_detach_devices(resource_size_t base, resource_size_t size)
* 0 on success, or a negative errno code otherwise
*/
int aperture_remove_conflicting_devices(resource_size_t base, resource_size_t size,
- bool primary, const char *name)
+ const char *name)
{
/*
* If a driver asked to unregister a platform device registered by
@@ -298,19 +297,42 @@ int aperture_remove_conflicting_devices(resource_size_t base, resource_size_t si
aperture_detach_devices(base, size);
- /*
- * If this is the primary adapter, there could be a VGA device
- * that consumes the VGA framebuffer I/O range. Remove this device
- * as well.
- */
- if (primary)
- aperture_detach_devices(VGA_FB_PHYS_BASE, VGA_FB_PHYS_SIZE);
-
return 0;
}
EXPORT_SYMBOL(aperture_remove_conflicting_devices);
/**
+ * __aperture_remove_legacy_vga_devices - remove legacy VGA devices of a PCI devices
+ * @pdev: PCI device
+ *
+ * This function removes VGA devices provided by @pdev, such as a VGA
+ * framebuffer or a console. This is useful if you have a VGA-compatible
+ * PCI graphics device with framebuffers in non-BAR locations. Drivers
+ * should acquire ownership of those memory areas and afterwards call
+ * this helper to release remaining VGA devices.
+ *
+ * If your hardware has its framebuffers accessible via PCI BARS, use
+ * aperture_remove_conflicting_pci_devices() instead. The function will
+ * release any VGA devices automatically.
+ *
+ * WARNING: Apparently we must remove graphics drivers before calling
+ * this helper. Otherwise the vga fbdev driver falls over if
+ * we have vgacon configured.
+ *
+ * Returns:
+ * 0 on success, or a negative errno code otherwise
+ */
+int __aperture_remove_legacy_vga_devices(struct pci_dev *pdev)
+{
+ /* VGA framebuffer */
+ aperture_detach_devices(VGA_FB_PHYS_BASE, VGA_FB_PHYS_SIZE);
+
+ /* VGA textmode console */
+ return vga_remove_vgacon(pdev);
+}
+EXPORT_SYMBOL(__aperture_remove_legacy_vga_devices);
+
+/**
* aperture_remove_conflicting_pci_devices - remove existing framebuffers for PCI devices
* @pdev: PCI device
* @name: a descriptive name of the requesting driver
@@ -326,11 +348,13 @@ int aperture_remove_conflicting_pci_devices(struct pci_dev *pdev, const char *na
{
bool primary = false;
resource_size_t base, size;
- int bar, ret;
+ int bar, ret = 0;
-#ifdef CONFIG_X86
- primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
-#endif
+ if (pdev == vga_default_device())
+ primary = true;
+
+ if (primary)
+ sysfb_disable();
for (bar = 0; bar < PCI_STD_NUM_BARS; ++bar) {
if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM))
@@ -338,20 +362,18 @@ int aperture_remove_conflicting_pci_devices(struct pci_dev *pdev, const char *na
base = pci_resource_start(pdev, bar);
size = pci_resource_len(pdev, bar);
- ret = aperture_remove_conflicting_devices(base, size, primary, name);
- if (ret)
- return ret;
+ aperture_detach_devices(base, size);
}
/*
- * WARNING: Apparently we must kick fbdev drivers before vgacon,
- * otherwise the vga fbdev driver falls over.
+ * If this is the primary adapter, there could be a VGA device
+ * that consumes the VGA framebuffer I/O range. Remove this
+ * device as well.
*/
- ret = vga_remove_vgacon(pdev);
- if (ret)
- return ret;
+ if (primary)
+ ret = __aperture_remove_legacy_vga_devices(pdev);
- return 0;
+ return ret;
}
EXPORT_SYMBOL(aperture_remove_conflicting_pci_devices);
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index 22cea5082ac4..a2a88d42edf0 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -141,6 +141,7 @@ config STI_CONSOLE
depends on PARISC && HAS_IOMEM
select FONT_SUPPORT
select CRC32
+ select STI_CORE
default y
help
The STI console is the builtin display/keyboard on HP-PARISC
diff --git a/drivers/video/console/Makefile b/drivers/video/console/Makefile
index db07b784bd2c..fd79016a0d95 100644
--- a/drivers/video/console/Makefile
+++ b/drivers/video/console/Makefile
@@ -5,8 +5,6 @@
obj-$(CONFIG_DUMMY_CONSOLE) += dummycon.o
obj-$(CONFIG_SGI_NEWPORT_CONSOLE) += newport_con.o
-obj-$(CONFIG_STI_CONSOLE) += sticon.o sticore.o
+obj-$(CONFIG_STI_CONSOLE) += sticon.o
obj-$(CONFIG_VGA_CONSOLE) += vgacon.o
obj-$(CONFIG_MDA_CONSOLE) += mdacon.o
-
-obj-$(CONFIG_FB_STI) += sticore.o
diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c
index 2cea69418a83..d11cfd2d68b5 100644
--- a/drivers/video/console/sticon.c
+++ b/drivers/video/console/sticon.c
@@ -50,7 +50,7 @@
#include <asm/io.h>
-#include "../fbdev/sticore.h"
+#include <video/sticore.h>
/* switching to graphics mode */
#define BLANK 0
@@ -282,7 +282,7 @@ static void sticon_init(struct vc_data *c, int init)
vc_cols = sti_onscreen_x(sti) / sti->font->width;
vc_rows = sti_onscreen_y(sti) / sti->font->height;
c->vc_can_do_color = 1;
-
+
if (init) {
c->vc_cols = vc_cols;
c->vc_rows = vc_rows;
@@ -374,7 +374,7 @@ static const struct consw sti_con = {
.con_font_set = sticon_font_set,
.con_font_default = sticon_font_default,
.con_build_attr = sticon_build_attr,
- .con_invert_region = sticon_invert_region,
+ .con_invert_region = sticon_invert_region,
};
diff --git a/drivers/video/fbdev/68328fb.c b/drivers/video/fbdev/68328fb.c
index 3ccf46f8ffd0..07d6e8dc686b 100644
--- a/drivers/video/fbdev/68328fb.c
+++ b/drivers/video/fbdev/68328fb.c
@@ -124,7 +124,7 @@ static u_long get_line_length(int xres_virtual, int bpp)
* First part, xxxfb_check_var, must not write anything
* to hardware, it should only verify and adjust var.
* This means it doesn't alter par but it does use hardware
- * data from it to check this var.
+ * data from it to check this var.
*/
static int mc68x328fb_check_var(struct fb_var_screeninfo *var,
@@ -182,7 +182,7 @@ static int mc68x328fb_check_var(struct fb_var_screeninfo *var,
/*
* Now that we checked it we alter var. The reason being is that the video
- * mode passed in might not work but slight changes to it might make it
+ * mode passed in might not work but slight changes to it might make it
* work. This way we let the user know what is acceptable.
*/
switch (var->bits_per_pixel) {
@@ -257,8 +257,8 @@ static int mc68x328fb_check_var(struct fb_var_screeninfo *var,
}
/* This routine actually sets the video mode. It's in here where we
- * the hardware state info->par and fix which can be affected by the
- * change in par. For this driver it doesn't do much.
+ * the hardware state info->par and fix which can be affected by the
+ * change in par. For this driver it doesn't do much.
*/
static int mc68x328fb_set_par(struct fb_info *info)
{
@@ -295,7 +295,7 @@ static int mc68x328fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
* {hardwarespecific} contains width of RAMDAC
* cmap[X] is programmed to (X << red.offset) | (X << green.offset) | (X << blue.offset)
* RAMDAC[X] is programmed to (red, green, blue)
- *
+ *
* Pseudocolor:
* uses offset = 0 && length = RAMDAC register width.
* var->{color}.offset is 0
@@ -384,7 +384,7 @@ static int mc68x328fb_pan_display(struct fb_var_screeninfo *var,
}
/*
- * Most drivers don't need their own mmap function
+ * Most drivers don't need their own mmap function
*/
static int mc68x328fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index 96e91570cdd3..485e8c35d5c6 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -551,10 +551,9 @@ config FB_STI
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
+ select STI_CORE
default y
help
- STI refers to the HP "Standard Text Interface" which is a set of
- BIOS routines contained in a ROM chip in HP PA-RISC based machines.
Enabling this option will implement the linux framebuffer device
using calls to the STI BIOS routines for initialisation.
diff --git a/drivers/video/fbdev/arcfb.c b/drivers/video/fbdev/arcfb.c
index 45e64016db32..3d926c3ada73 100644
--- a/drivers/video/fbdev/arcfb.c
+++ b/drivers/video/fbdev/arcfb.c
@@ -41,6 +41,7 @@
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
+#include <linux/io.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/arcfb.h>
@@ -260,7 +261,7 @@ static void arcfb_lcd_update_page(struct arcfb_par *par, unsigned int upper,
ks108_set_yaddr(par, chipindex, upper/8);
linesize = par->info->var.xres/8;
- src = (unsigned char __force *) par->info->screen_base + (left/8) +
+ src = (unsigned char *)par->info->screen_buffer + (left/8) +
(upper * linesize);
ks108_set_xaddr(par, chipindex, left);
@@ -451,6 +452,9 @@ static ssize_t arcfb_write(struct fb_info *info, const char __user *buf,
struct arcfb_par *par;
unsigned int xres;
+ if (!info->screen_buffer)
+ return -ENODEV;
+
p = *ppos;
par = info->par;
xres = info->var.xres;
@@ -468,7 +472,7 @@ static ssize_t arcfb_write(struct fb_info *info, const char __user *buf,
if (count) {
char *base_addr;
- base_addr = (char __force *)info->screen_base;
+ base_addr = info->screen_buffer;
count -= copy_from_user(base_addr + p, buf, count);
*ppos += count;
err = -EFAULT;
@@ -523,9 +527,9 @@ static int arcfb_probe(struct platform_device *dev)
info = framebuffer_alloc(sizeof(struct arcfb_par), &dev->dev);
if (!info)
- goto err;
+ goto err_fb_alloc;
- info->screen_base = (char __iomem *)videomemory;
+ info->screen_buffer = videomemory;
info->fbops = &arcfb_ops;
info->var = arcfb_var;
@@ -535,7 +539,7 @@ static int arcfb_probe(struct platform_device *dev)
if (!dio_addr || !cio_addr || !c2io_addr) {
printk(KERN_WARNING "no IO addresses supplied\n");
- goto err1;
+ goto err_addr;
}
par->dio_addr = dio_addr;
par->cio_addr = cio_addr;
@@ -551,12 +555,12 @@ static int arcfb_probe(struct platform_device *dev)
printk(KERN_INFO
"arcfb: Failed req IRQ %d\n", par->irq);
retval = -EBUSY;
- goto err1;
+ goto err_addr;
}
}
retval = register_framebuffer(info);
if (retval < 0)
- goto err1;
+ goto err_register_fb;
platform_set_drvdata(dev, info);
fb_info(info, "Arc frame buffer device, using %dK of video memory\n",
videomemorysize >> 10);
@@ -580,9 +584,12 @@ static int arcfb_probe(struct platform_device *dev)
}
return 0;
-err1:
+
+err_register_fb:
+ free_irq(par->irq, info);
+err_addr:
framebuffer_release(info);
-err:
+err_fb_alloc:
vfree(videomemory);
return retval;
}
@@ -595,7 +602,7 @@ static int arcfb_remove(struct platform_device *dev)
unregister_framebuffer(info);
if (irq)
free_irq(((struct arcfb_par *)(info->par))->irq, info);
- vfree((void __force *)info->screen_base);
+ vfree(info->screen_buffer);
framebuffer_release(info);
}
return 0;
diff --git a/drivers/video/fbdev/atmel_lcdfb.c b/drivers/video/fbdev/atmel_lcdfb.c
index 8187a7c4f910..987c5f5f0241 100644
--- a/drivers/video/fbdev/atmel_lcdfb.c
+++ b/drivers/video/fbdev/atmel_lcdfb.c
@@ -317,7 +317,7 @@ static inline void atmel_lcdfb_free_video_memory(struct atmel_lcdfb_info *sinfo)
/**
* atmel_lcdfb_alloc_video_memory - Allocate framebuffer memory
* @sinfo: the frame buffer to allocate memory for
- *
+ *
* This function is called only from the atmel_lcdfb_probe()
* so no locking by fb_info->mm_lock around smem_len setting is needed.
*/
diff --git a/drivers/video/fbdev/aty/atyfb.h b/drivers/video/fbdev/aty/atyfb.h
index 465f55beb97f..30da3e82ed3c 100644
--- a/drivers/video/fbdev/aty/atyfb.h
+++ b/drivers/video/fbdev/aty/atyfb.h
@@ -3,8 +3,10 @@
* ATI Frame Buffer Device Driver Core Definitions
*/
+#include <linux/io.h>
#include <linux/spinlock.h>
#include <linux/wait.h>
+
/*
* Elements of the hardware specific atyfb_par structure
*/
diff --git a/drivers/video/fbdev/aty/mach64_cursor.c b/drivers/video/fbdev/aty/mach64_cursor.c
index 4ad0331a8c57..971355c2cd7e 100644
--- a/drivers/video/fbdev/aty/mach64_cursor.c
+++ b/drivers/video/fbdev/aty/mach64_cursor.c
@@ -153,7 +153,7 @@ static int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
u8 m, b;
// Clear cursor image with 1010101010...
- fb_memset(dst, 0xaa, 1024);
+ fb_memset_io(dst, 0xaa, 1024);
offset = align - width*2;
diff --git a/drivers/video/fbdev/au1200fb.c b/drivers/video/fbdev/au1200fb.c
index b6b22fa4a8a0..847f82ed52ff 100644
--- a/drivers/video/fbdev/au1200fb.c
+++ b/drivers/video/fbdev/au1200fb.c
@@ -1568,7 +1568,7 @@ static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev)
fbi->fix.mmio_len = 0;
fbi->fix.accel = FB_ACCEL_NONE;
- fbi->screen_base = (char __iomem *) fbdev->fb_mem;
+ fbi->screen_buffer = fbdev->fb_mem;
au1200fb_update_fbinfo(fbi);
diff --git a/drivers/video/fbdev/broadsheetfb.c b/drivers/video/fbdev/broadsheetfb.c
index 55e62dd96f9b..e9c5d5c04062 100644
--- a/drivers/video/fbdev/broadsheetfb.c
+++ b/drivers/video/fbdev/broadsheetfb.c
@@ -824,7 +824,7 @@ static void broadsheet_init_display(struct broadsheetfb_par *par)
broadsheet_burst_write(par, (panel_table[par->panel_index].w *
panel_table[par->panel_index].h)/2,
- (u16 *) par->info->screen_base);
+ (u16 *)par->info->screen_buffer);
broadsheet_send_command(par, BS_CMD_LD_IMG_END);
@@ -865,7 +865,7 @@ static void broadsheetfb_dpy_update_pages(struct broadsheetfb_par *par,
u16 y1, u16 y2)
{
u16 args[5];
- unsigned char *buf = (unsigned char *)par->info->screen_base;
+ unsigned char *buf = par->info->screen_buffer;
mutex_lock(&(par->io_lock));
/* y1 must be a multiple of 4 so drop the lower bits */
@@ -913,7 +913,7 @@ static void broadsheetfb_dpy_update(struct broadsheetfb_par *par)
broadsheet_send_cmdargs(par, BS_CMD_WR_REG, 1, args);
broadsheet_burst_write(par, (panel_table[par->panel_index].w *
panel_table[par->panel_index].h)/2,
- (u16 *) par->info->screen_base);
+ (u16 *)par->info->screen_buffer);
broadsheet_send_command(par, BS_CMD_LD_IMG_END);
@@ -1013,8 +1013,8 @@ static ssize_t broadsheetfb_write(struct fb_info *info, const char __user *buf,
int err = 0;
unsigned long total_size;
- if (info->state != FBINFO_STATE_RUNNING)
- return -EPERM;
+ if (!info->screen_buffer)
+ return -ENODEV;
total_size = info->fix.smem_len;
@@ -1033,7 +1033,7 @@ static ssize_t broadsheetfb_write(struct fb_info *info, const char __user *buf,
count = total_size - p;
}
- dst = (void *)(info->screen_base + p);
+ dst = info->screen_buffer + p;
if (copy_from_user(dst, buf, count))
err = -EFAULT;
@@ -1109,7 +1109,7 @@ static int broadsheetfb_probe(struct platform_device *dev)
if (!videomemory)
goto err_fb_rel;
- info->screen_base = (char *)videomemory;
+ info->screen_buffer = videomemory;
info->fbops = &broadsheetfb_ops;
broadsheetfb_var.xres = dpyw;
@@ -1205,7 +1205,7 @@ static int broadsheetfb_remove(struct platform_device *dev)
fb_deferred_io_cleanup(info);
par->board->cleanup(par);
fb_dealloc_cmap(&info->cmap);
- vfree((void *)info->screen_base);
+ vfree(info->screen_buffer);
module_put(par->board->owner);
framebuffer_release(info);
}
diff --git a/drivers/video/fbdev/cg14.c b/drivers/video/fbdev/cg14.c
index a028ede39c12..832a82f45c80 100644
--- a/drivers/video/fbdev/cg14.c
+++ b/drivers/video/fbdev/cg14.c
@@ -512,7 +512,7 @@ static int cg14_probe(struct platform_device *op)
is_8mb = (resource_size(&op->resource[1]) == (8 * 1024 * 1024));
BUILD_BUG_ON(sizeof(par->mmap_map) != sizeof(__cg14_mmap_map));
-
+
memcpy(&par->mmap_map, &__cg14_mmap_map, sizeof(par->mmap_map));
for (i = 0; i < CG14_MMAP_ENTRIES; i++) {
diff --git a/drivers/video/fbdev/chipsfb.c b/drivers/video/fbdev/chipsfb.c
index 7799d52a651f..2a27ba94f652 100644
--- a/drivers/video/fbdev/chipsfb.c
+++ b/drivers/video/fbdev/chipsfb.c
@@ -332,7 +332,7 @@ static const struct fb_var_screeninfo chipsfb_var = {
static void init_chips(struct fb_info *p, unsigned long addr)
{
- fb_memset(p->screen_base, 0, 0x100000);
+ fb_memset_io(p->screen_base, 0, 0x100000);
p->fix = chipsfb_fix;
p->fix.smem_start = addr;
diff --git a/drivers/video/fbdev/cobalt_lcdfb.c b/drivers/video/fbdev/cobalt_lcdfb.c
index feeace079425..3d59a01ec677 100644
--- a/drivers/video/fbdev/cobalt_lcdfb.c
+++ b/drivers/video/fbdev/cobalt_lcdfb.c
@@ -129,6 +129,9 @@ static ssize_t cobalt_lcdfb_read(struct fb_info *info, char __user *buf,
unsigned long pos;
int len, retval = 0;
+ if (!info->screen_base)
+ return -ENODEV;
+
pos = *ppos;
if (pos >= LCD_CHARS_MAX || count == 0)
return 0;
@@ -175,6 +178,9 @@ static ssize_t cobalt_lcdfb_write(struct fb_info *info, const char __user *buf,
unsigned long pos;
int len, retval = 0;
+ if (!info->screen_base)
+ return -ENODEV;
+
pos = *ppos;
if (pos >= LCD_CHARS_MAX || count == 0)
return 0;
diff --git a/drivers/video/fbdev/controlfb.c b/drivers/video/fbdev/controlfb.c
index 77dbf94aae5f..82eeb139c4eb 100644
--- a/drivers/video/fbdev/controlfb.c
+++ b/drivers/video/fbdev/controlfb.c
@@ -113,14 +113,14 @@ struct fb_info_control {
struct fb_info info;
struct fb_par_control par;
u32 pseudo_palette[16];
-
+
struct cmap_regs __iomem *cmap_regs;
unsigned long cmap_regs_phys;
-
+
struct control_regs __iomem *control_regs;
unsigned long control_regs_phys;
unsigned long control_regs_size;
-
+
__u8 __iomem *frame_buffer;
unsigned long frame_buffer_phys;
unsigned long fb_orig_base;
@@ -196,7 +196,7 @@ static void set_control_clock(unsigned char *params)
while (!req.complete)
cuda_poll();
}
-#endif
+#endif
}
/*
@@ -233,19 +233,19 @@ static void control_set_hardware(struct fb_info_control *p, struct fb_par_contro
if (p->par.xoffset != par->xoffset ||
p->par.yoffset != par->yoffset)
set_screen_start(par->xoffset, par->yoffset, p);
-
+
return;
}
-
+
p->par = *par;
cmode = p->par.cmode;
r = &par->regvals;
-
+
/* Turn off display */
out_le32(CNTRL_REG(p,ctrl), 0x400 | par->ctrl);
-
+
set_control_clock(r->clock_params);
-
+
RADACAL_WRITE(0x20, r->radacal_ctrl);
RADACAL_WRITE(0x21, p->control_use_bank2 ? 0 : 1);
RADACAL_WRITE(0x10, 0);
@@ -254,7 +254,7 @@ static void control_set_hardware(struct fb_info_control *p, struct fb_par_contro
rp = &p->control_regs->vswin;
for (i = 0; i < 16; ++i, ++rp)
out_le32(&rp->r, r->regs[i]);
-
+
out_le32(CNTRL_REG(p,pitch), par->pitch);
out_le32(CNTRL_REG(p,mode), r->mode);
out_le32(CNTRL_REG(p,vram_attr), p->vram_attr);
@@ -366,7 +366,7 @@ static int read_control_sense(struct fb_info_control *p)
sense |= (in_le32(CNTRL_REG(p,mon_sense)) & 0x180) >> 7;
out_le32(CNTRL_REG(p,mon_sense), 077); /* turn off drivers */
-
+
return sense;
}
@@ -558,9 +558,9 @@ static int control_var_to_par(struct fb_var_screeninfo *var,
static void control_par_to_var(struct fb_par_control *par, struct fb_var_screeninfo *var)
{
struct control_regints *rv;
-
+
rv = (struct control_regints *) par->regvals.regs;
-
+
memset(var, 0, sizeof(*var));
var->xres = par->xres;
var->yres = par->yres;
@@ -568,7 +568,7 @@ static void control_par_to_var(struct fb_par_control *par, struct fb_var_screeni
var->yres_virtual = par->vyres;
var->xoffset = par->xoffset;
var->yoffset = par->yoffset;
-
+
switch(par->cmode) {
default:
case CMODE_8:
@@ -634,7 +634,7 @@ static int controlfb_check_var (struct fb_var_screeninfo *var, struct fb_info *i
err = control_var_to_par(var, &par, info);
if (err)
- return err;
+ return err;
control_par_to_var(&par, var);
return 0;
@@ -655,7 +655,7 @@ static int controlfb_set_par (struct fb_info *info)
" control_var_to_par: %d.\n", err);
return err;
}
-
+
control_set_hardware(p, &par);
info->fix.visual = (p->par.cmode == CMODE_8) ?
@@ -840,7 +840,7 @@ static int __init init_control(struct fb_info_control *p)
int full, sense, vmode, cmode, vyres;
struct fb_var_screeninfo var;
int rc;
-
+
printk(KERN_INFO "controlfb: ");
full = p->total_vram == 0x400000;
diff --git a/drivers/video/fbdev/core/Makefile b/drivers/video/fbdev/core/Makefile
index 08fabce76b74..8f0060160ffb 100644
--- a/drivers/video/fbdev/core/Makefile
+++ b/drivers/video/fbdev/core/Makefile
@@ -2,7 +2,7 @@
obj-$(CONFIG_FB_NOTIFY) += fb_notify.o
obj-$(CONFIG_FB) += fb.o
fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \
- modedb.o fbcvt.o fb_cmdline.o
+ modedb.o fbcvt.o fb_cmdline.o fb_io_fops.o
fb-$(CONFIG_FB_DEFERRED_IO) += fb_defio.o
ifeq ($(CONFIG_FRAMEBUFFER_CONSOLE),y)
diff --git a/drivers/video/fbdev/core/fb_io_fops.c b/drivers/video/fbdev/core/fb_io_fops.c
new file mode 100644
index 000000000000..5985e5e1b040
--- /dev/null
+++ b/drivers/video/fbdev/core/fb_io_fops.c
@@ -0,0 +1,133 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/fb.h>
+#include <linux/module.h>
+#include <linux/uaccess.h>
+
+ssize_t fb_io_read(struct fb_info *info, char __user *buf, size_t count, loff_t *ppos)
+{
+ unsigned long p = *ppos;
+ u8 *buffer, *dst;
+ u8 __iomem *src;
+ int c, cnt = 0, err = 0;
+ unsigned long total_size, trailing;
+
+ if (!info->screen_base)
+ return -ENODEV;
+
+ total_size = info->screen_size;
+
+ if (total_size == 0)
+ total_size = info->fix.smem_len;
+
+ if (p >= total_size)
+ return 0;
+
+ if (count >= total_size)
+ count = total_size;
+
+ if (count + p > total_size)
+ count = total_size - p;
+
+ buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count,
+ GFP_KERNEL);
+ if (!buffer)
+ return -ENOMEM;
+
+ src = (u8 __iomem *) (info->screen_base + p);
+
+ if (info->fbops->fb_sync)
+ info->fbops->fb_sync(info);
+
+ while (count) {
+ c = (count > PAGE_SIZE) ? PAGE_SIZE : count;
+ dst = buffer;
+ fb_memcpy_fromio(dst, src, c);
+ dst += c;
+ src += c;
+
+ trailing = copy_to_user(buf, buffer, c);
+ if (trailing == c) {
+ err = -EFAULT;
+ break;
+ }
+ c -= trailing;
+
+ *ppos += c;
+ buf += c;
+ cnt += c;
+ count -= c;
+ }
+
+ kfree(buffer);
+
+ return cnt ? cnt : err;
+}
+EXPORT_SYMBOL(fb_io_read);
+
+ssize_t fb_io_write(struct fb_info *info, const char __user *buf, size_t count, loff_t *ppos)
+{
+ unsigned long p = *ppos;
+ u8 *buffer, *src;
+ u8 __iomem *dst;
+ int c, cnt = 0, err = 0;
+ unsigned long total_size, trailing;
+
+ if (!info->screen_base)
+ return -ENODEV;
+
+ total_size = info->screen_size;
+
+ if (total_size == 0)
+ total_size = info->fix.smem_len;
+
+ if (p > total_size)
+ return -EFBIG;
+
+ if (count > total_size) {
+ err = -EFBIG;
+ count = total_size;
+ }
+
+ if (count + p > total_size) {
+ if (!err)
+ err = -ENOSPC;
+
+ count = total_size - p;
+ }
+
+ buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count,
+ GFP_KERNEL);
+ if (!buffer)
+ return -ENOMEM;
+
+ dst = (u8 __iomem *) (info->screen_base + p);
+
+ if (info->fbops->fb_sync)
+ info->fbops->fb_sync(info);
+
+ while (count) {
+ c = (count > PAGE_SIZE) ? PAGE_SIZE : count;
+ src = buffer;
+
+ trailing = copy_from_user(src, buf, c);
+ if (trailing == c) {
+ err = -EFAULT;
+ break;
+ }
+ c -= trailing;
+
+ fb_memcpy_toio(dst, src, c);
+ dst += c;
+ src += c;
+ *ppos += c;
+ buf += c;
+ cnt += c;
+ count -= c;
+ }
+
+ kfree(buffer);
+
+ return (cnt) ? cnt : err;
+}
+EXPORT_SYMBOL(fb_io_write);
diff --git a/drivers/video/fbdev/core/fb_sys_fops.c b/drivers/video/fbdev/core/fb_sys_fops.c
index ff275d7f3eaf..0cb0989abda6 100644
--- a/drivers/video/fbdev/core/fb_sys_fops.c
+++ b/drivers/video/fbdev/core/fb_sys_fops.c
@@ -19,10 +19,11 @@ ssize_t fb_sys_read(struct fb_info *info, char __user *buf, size_t count,
unsigned long p = *ppos;
void *src;
int err = 0;
- unsigned long total_size;
+ unsigned long total_size, c;
+ ssize_t ret;
- if (info->state != FBINFO_STATE_RUNNING)
- return -EPERM;
+ if (!info->screen_buffer)
+ return -ENODEV;
total_size = info->screen_size;
@@ -38,18 +39,19 @@ ssize_t fb_sys_read(struct fb_info *info, char __user *buf, size_t count,
if (count + p > total_size)
count = total_size - p;
- src = (void __force *)(info->screen_base + p);
+ src = info->screen_buffer + p;
if (info->fbops->fb_sync)
info->fbops->fb_sync(info);
- if (copy_to_user(buf, src, count))
+ c = copy_to_user(buf, src, count);
+ if (c)
err = -EFAULT;
+ ret = count - c;
- if (!err)
- *ppos += count;
+ *ppos += ret;
- return (err) ? err : count;
+ return ret ? ret : err;
}
EXPORT_SYMBOL_GPL(fb_sys_read);
@@ -59,10 +61,11 @@ ssize_t fb_sys_write(struct fb_info *info, const char __user *buf,
unsigned long p = *ppos;
void *dst;
int err = 0;
- unsigned long total_size;
+ unsigned long total_size, c;
+ size_t ret;
- if (info->state != FBINFO_STATE_RUNNING)
- return -EPERM;
+ if (!info->screen_buffer)
+ return -ENODEV;
total_size = info->screen_size;
@@ -84,18 +87,19 @@ ssize_t fb_sys_write(struct fb_info *info, const char __user *buf,
count = total_size - p;
}
- dst = (void __force *) (info->screen_base + p);
+ dst = info->screen_buffer + p;
if (info->fbops->fb_sync)
info->fbops->fb_sync(info);
- if (copy_from_user(dst, buf, count))
+ c = copy_from_user(dst, buf, count);
+ if (c)
err = -EFAULT;
+ ret = count - c;
- if (!err)
- *ppos += count;
+ *ppos += ret;
- return (err) ? err : count;
+ return ret ? ret : err;
}
EXPORT_SYMBOL_GPL(fb_sys_write);
diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
index eb565a10e5cd..c6c9d040bdec 100644
--- a/drivers/video/fbdev/core/fbcon.c
+++ b/drivers/video/fbdev/core/fbcon.c
@@ -75,7 +75,6 @@
#include <linux/interrupt.h>
#include <linux/crc32.h> /* For counting font checksums */
#include <linux/uaccess.h>
-#include <asm/fb.h>
#include <asm/irq.h>
#include "fbcon.h"
diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c
index e808dc86001c..d5f897b5ba54 100644
--- a/drivers/video/fbdev/core/fbmem.c
+++ b/drivers/video/fbdev/core/fbmem.c
@@ -37,8 +37,6 @@
#include <linux/mem_encrypt.h>
#include <linux/pci.h>
-#include <asm/fb.h>
-
#include <video/nomodeset.h>
#include <video/vga.h>
@@ -761,14 +759,9 @@ static struct fb_info *file_fb_info(struct file *file)
static ssize_t
fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
- unsigned long p = *ppos;
struct fb_info *info = file_fb_info(file);
- u8 *buffer, *dst;
- u8 __iomem *src;
- int c, cnt = 0, err = 0;
- unsigned long total_size;
- if (!info || ! info->screen_base)
+ if (!info)
return -ENODEV;
if (info->state != FBINFO_STATE_RUNNING)
@@ -777,63 +770,15 @@ fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
if (info->fbops->fb_read)
return info->fbops->fb_read(info, buf, count, ppos);
- total_size = info->screen_size;
-
- if (total_size == 0)
- total_size = info->fix.smem_len;
-
- if (p >= total_size)
- return 0;
-
- if (count >= total_size)
- count = total_size;
-
- if (count + p > total_size)
- count = total_size - p;
-
- buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count,
- GFP_KERNEL);
- if (!buffer)
- return -ENOMEM;
-
- src = (u8 __iomem *) (info->screen_base + p);
-
- if (info->fbops->fb_sync)
- info->fbops->fb_sync(info);
-
- while (count) {
- c = (count > PAGE_SIZE) ? PAGE_SIZE : count;
- dst = buffer;
- fb_memcpy_fromfb(dst, src, c);
- dst += c;
- src += c;
-
- if (copy_to_user(buf, buffer, c)) {
- err = -EFAULT;
- break;
- }
- *ppos += c;
- buf += c;
- cnt += c;
- count -= c;
- }
-
- kfree(buffer);
-
- return (err) ? err : cnt;
+ return fb_io_read(info, buf, count, ppos);
}
static ssize_t
fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
- unsigned long p = *ppos;
struct fb_info *info = file_fb_info(file);
- u8 *buffer, *src;
- u8 __iomem *dst;
- int c, cnt = 0, err = 0;
- unsigned long total_size;
- if (!info || !info->screen_base)
+ if (!info)
return -ENODEV;
if (info->state != FBINFO_STATE_RUNNING)
@@ -842,57 +787,7 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
if (info->fbops->fb_write)
return info->fbops->fb_write(info, buf, count, ppos);
- total_size = info->screen_size;
-
- if (total_size == 0)
- total_size = info->fix.smem_len;
-
- if (p > total_size)
- return -EFBIG;
-
- if (count > total_size) {
- err = -EFBIG;
- count = total_size;
- }
-
- if (count + p > total_size) {
- if (!err)
- err = -ENOSPC;
-
- count = total_size - p;
- }
-
- buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count,
- GFP_KERNEL);
- if (!buffer)
- return -ENOMEM;
-
- dst = (u8 __iomem *) (info->screen_base + p);
-
- if (info->fbops->fb_sync)
- info->fbops->fb_sync(info);
-
- while (count) {
- c = (count > PAGE_SIZE) ? PAGE_SIZE : count;
- src = buffer;
-
- if (copy_from_user(src, buf, c)) {
- err = -EFAULT;
- break;
- }
-
- fb_memcpy_tofb(dst, src, c);
- dst += c;
- src += c;
- *ppos += c;
- buf += c;
- cnt += c;
- count -= c;
- }
-
- kfree(buffer);
-
- return (cnt) ? cnt : err;
+ return fb_io_write(info, buf, count, ppos);
}
int
diff --git a/drivers/video/fbdev/core/modedb.c b/drivers/video/fbdev/core/modedb.c
index 23cf8eba785d..f7e019dded0f 100644
--- a/drivers/video/fbdev/core/modedb.c
+++ b/drivers/video/fbdev/core/modedb.c
@@ -257,6 +257,11 @@ static const struct fb_videomode modedb[] = {
{ NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3, 0,
FB_VMODE_DOUBLE },
+ /* 1920x1080 @ 60 Hz, 67.3 kHz hsync */
+ { NULL, 60, 1920, 1080, 6734, 148, 88, 36, 4, 44, 5, 0,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ FB_VMODE_NONINTERLACED },
+
/* 1920x1200 @ 60 Hz, 74.5 Khz hsync */
{ NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3,
FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
diff --git a/drivers/video/fbdev/g364fb.c b/drivers/video/fbdev/g364fb.c
index 05837a3b985c..c5b7673ddc6c 100644
--- a/drivers/video/fbdev/g364fb.c
+++ b/drivers/video/fbdev/g364fb.c
@@ -6,7 +6,7 @@
*
* This driver is based on tgafb.c
*
- * Copyright (C) 1997 Geert Uytterhoeven
+ * Copyright (C) 1997 Geert Uytterhoeven
* Copyright (C) 1995 Jay Estabrook
*
* This file is subject to the terms and conditions of the GNU General Public
@@ -28,7 +28,7 @@
#include <asm/io.h>
#include <asm/jazz.h>
-/*
+/*
* Various defines for the G364
*/
#define G364_MEM_BASE 0xe4400000
@@ -125,7 +125,7 @@ static const struct fb_ops g364fb_ops = {
*
* This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
*/
-static int g364fb_pan_display(struct fb_var_screeninfo *var,
+static int g364fb_pan_display(struct fb_var_screeninfo *var,
struct fb_info *info)
{
if (var->xoffset ||
diff --git a/drivers/video/fbdev/hecubafb.c b/drivers/video/fbdev/hecubafb.c
index 5a149458d3b4..7ce0a16ce8b9 100644
--- a/drivers/video/fbdev/hecubafb.c
+++ b/drivers/video/fbdev/hecubafb.c
@@ -102,7 +102,7 @@ static void apollo_send_command(struct hecubafb_par *par, unsigned char data)
static void hecubafb_dpy_update(struct hecubafb_par *par)
{
int i;
- unsigned char *buf = (unsigned char __force *)par->info->screen_base;
+ unsigned char *buf = par->info->screen_buffer;
apollo_send_command(par, APOLLO_START_NEW_IMG);
@@ -163,8 +163,8 @@ static ssize_t hecubafb_write(struct fb_info *info, const char __user *buf,
int err = 0;
unsigned long total_size;
- if (info->state != FBINFO_STATE_RUNNING)
- return -EPERM;
+ if (!info->screen_buffer)
+ return -ENODEV;
total_size = info->fix.smem_len;
@@ -183,7 +183,7 @@ static ssize_t hecubafb_write(struct fb_info *info, const char __user *buf,
count = total_size - p;
}
- dst = (void __force *) (info->screen_base + p);
+ dst = info->screen_buffer + p;
if (copy_from_user(dst, buf, count))
err = -EFAULT;
@@ -239,7 +239,7 @@ static int hecubafb_probe(struct platform_device *dev)
if (!info)
goto err_fballoc;
- info->screen_base = (char __force __iomem *)videomemory;
+ info->screen_buffer = videomemory;
info->fbops = &hecubafb_ops;
info->var = hecubafb_var;
@@ -287,7 +287,7 @@ static void hecubafb_remove(struct platform_device *dev)
struct hecubafb_par *par = info->par;
fb_deferred_io_cleanup(info);
unregister_framebuffer(info);
- vfree((void __force *)info->screen_base);
+ vfree(info->screen_buffer);
if (par->board->remove)
par->board->remove(par);
module_put(par->board->owner);
diff --git a/drivers/video/fbdev/hgafb.c b/drivers/video/fbdev/hgafb.c
index 20bdab738ab7..0af58018441d 100644
--- a/drivers/video/fbdev/hgafb.c
+++ b/drivers/video/fbdev/hgafb.c
@@ -1,6 +1,6 @@
/*
* linux/drivers/video/hgafb.c -- Hercules graphics adaptor frame buffer device
- *
+ *
* Created 25 Nov 1999 by Ferenc Bakonyi (fero@drama.obuda.kando.hu)
* Based on skeletonfb.c by Geert Uytterhoeven and
* mdacon.c by Andrew Apted
@@ -8,14 +8,14 @@
* History:
*
* - Revision 0.1.8 (23 Oct 2002): Ported to new framebuffer api.
- *
- * - Revision 0.1.7 (23 Jan 2001): fix crash resulting from MDA only cards
+ *
+ * - Revision 0.1.7 (23 Jan 2001): fix crash resulting from MDA only cards
* being detected as Hercules. (Paul G.)
* - Revision 0.1.6 (17 Aug 2000): new style structs
* documentation
* - Revision 0.1.5 (13 Mar 2000): spinlocks instead of saveflags();cli();etc
* minor fixes
- * - Revision 0.1.4 (24 Jan 2000): fixed a bug in hga_card_detect() for
+ * - Revision 0.1.4 (24 Jan 2000): fixed a bug in hga_card_detect() for
* HGA-only systems
* - Revision 0.1.3 (22 Jan 2000): modified for the new fb_info structure
* screen is cleared after rmmod
@@ -143,7 +143,7 @@ static bool nologo = 0;
static void write_hga_b(unsigned int val, unsigned char reg)
{
- outb_p(reg, HGA_INDEX_PORT);
+ outb_p(reg, HGA_INDEX_PORT);
outb_p(val, HGA_VALUE_PORT);
}
@@ -155,7 +155,7 @@ static void write_hga_w(unsigned int val, unsigned char reg)
static int test_hga_b(unsigned char val, unsigned char reg)
{
- outb_p(reg, HGA_INDEX_PORT);
+ outb_p(reg, HGA_INDEX_PORT);
outb (val, HGA_VALUE_PORT);
udelay(20); val = (inb_p(HGA_VALUE_PORT) == val);
return val;
@@ -244,7 +244,7 @@ static void hga_show_logo(struct fb_info *info)
void __iomem *dest = hga_vram;
char *logo = linux_logo_bw;
int x, y;
-
+
for (y = 134; y < 134 + 80 ; y++) * this needs some cleanup *
for (x = 0; x < 10 ; x++)
writeb(~*(logo++),(dest + HGA_ROWADDR(y) + x + 40));
@@ -255,7 +255,7 @@ static void hga_pan(unsigned int xoffset, unsigned int yoffset)
{
unsigned int base;
unsigned long flags;
-
+
base = (yoffset / 8) * 90 + xoffset;
spin_lock_irqsave(&hga_reg_lock, flags);
write_hga_w(base, 0x0c); /* start address */
@@ -310,7 +310,7 @@ static int hga_card_detect(void)
/* Ok, there is definitely a card registering at the correct
* memory location, so now we do an I/O port test.
*/
-
+
if (!test_hga_b(0x66, 0x0f)) /* cursor low register */
goto error;
@@ -321,7 +321,7 @@ static int hga_card_detect(void)
* bit of the status register is changing. This test lasts for
* approximately 1/10th of a second.
*/
-
+
p_save = q_save = inb_p(HGA_STATUS_PORT) & HGA_STATUS_VSYNC;
for (count=0; count < 50000 && p_save == q_save; count++) {
@@ -329,7 +329,7 @@ static int hga_card_detect(void)
udelay(2);
}
- if (p_save == q_save)
+ if (p_save == q_save)
goto error;
switch (inb_p(HGA_STATUS_PORT) & 0x70) {
@@ -415,7 +415,7 @@ static int hgafb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
* @info:pointer to fb_info object containing info for current hga board
*
* This function looks only at xoffset, yoffset and the %FB_VMODE_YWRAP
- * flag in @var. If input parameters are correct it calls hga_pan() to
+ * flag in @var. If input parameters are correct it calls hga_pan() to
* program the hardware. @info->var is updated to the new values.
* A zero is returned on success and %-EINVAL for failure.
*/
@@ -442,9 +442,9 @@ static int hgafb_pan_display(struct fb_var_screeninfo *var,
* hgafb_blank - (un)blank the screen
* @blank_mode:blanking method to use
* @info:unused
- *
- * Blank the screen if blank_mode != 0, else unblank.
- * Implements VESA suspend and powerdown modes on hardware that supports
+ *
+ * Blank the screen if blank_mode != 0, else unblank.
+ * Implements VESA suspend and powerdown modes on hardware that supports
* disabling hsync/vsync:
* @blank_mode == 2 means suspend vsync,
* @blank_mode == 3 means suspend hsync,
@@ -539,15 +539,15 @@ static const struct fb_ops hgafb_ops = {
.fb_copyarea = hgafb_copyarea,
.fb_imageblit = hgafb_imageblit,
};
-
+
/* ------------------------------------------------------------------------- *
*
* Functions in fb_info
- *
+ *
* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
-
+
/*
* Initialization
*/
diff --git a/drivers/video/fbdev/hitfb.c b/drivers/video/fbdev/hitfb.c
index 3033f5056976..7737923b7a0a 100644
--- a/drivers/video/fbdev/hitfb.c
+++ b/drivers/video/fbdev/hitfb.c
@@ -42,17 +42,33 @@ static struct fb_fix_screeninfo hitfb_fix = {
.accel = FB_ACCEL_NONE,
};
+static volatile void __iomem *hitfb_offset_to_addr(unsigned int offset)
+{
+ return (__force volatile void __iomem *)(uintptr_t)offset;
+}
+
+static u16 hitfb_readw(unsigned int offset)
+{
+ return fb_readw(hitfb_offset_to_addr(offset));
+}
+
+static void hitfb_writew(u16 value, unsigned int offset)
+{
+ fb_writew(value, hitfb_offset_to_addr(offset));
+}
+
static inline void hitfb_accel_wait(void)
{
- while (fb_readw(HD64461_GRCFGR) & HD64461_GRCFGR_ACCSTATUS) ;
+ while (hitfb_readw(HD64461_GRCFGR) & HD64461_GRCFGR_ACCSTATUS)
+ ;
}
static inline void hitfb_accel_start(int truecolor)
{
if (truecolor) {
- fb_writew(6, HD64461_GRCFGR);
+ hitfb_writew(6, HD64461_GRCFGR);
} else {
- fb_writew(7, HD64461_GRCFGR);
+ hitfb_writew(7, HD64461_GRCFGR);
}
}
@@ -63,11 +79,11 @@ static inline void hitfb_accel_set_dest(int truecolor, u16 dx, u16 dy,
if (truecolor)
saddr <<= 1;
- fb_writew(width-1, HD64461_BBTDWR);
- fb_writew(height-1, HD64461_BBTDHR);
+ hitfb_writew(width-1, HD64461_BBTDWR);
+ hitfb_writew(height-1, HD64461_BBTDHR);
- fb_writew(saddr & 0xffff, HD64461_BBTDSARL);
- fb_writew(saddr >> 16, HD64461_BBTDSARH);
+ hitfb_writew(saddr & 0xffff, HD64461_BBTDSARL);
+ hitfb_writew(saddr >> 16, HD64461_BBTDSARH);
}
@@ -80,7 +96,7 @@ static inline void hitfb_accel_bitblt(int truecolor, u16 sx, u16 sy, u16 dx,
height--;
width--;
- fb_writew(rop, HD64461_BBTROPR);
+ hitfb_writew(rop, HD64461_BBTROPR);
if ((sy < dy) || ((sy == dy) && (sx <= dx))) {
saddr = WIDTH * (sy + height) + sx + width;
daddr = WIDTH * (dy + height) + dx + width;
@@ -91,32 +107,32 @@ static inline void hitfb_accel_bitblt(int truecolor, u16 sx, u16 sy, u16 dx,
maddr =
(((width >> 4) + 1) * (height + 1) - 1) * 2;
- fb_writew((1 << 5) | 1, HD64461_BBTMDR);
+ hitfb_writew((1 << 5) | 1, HD64461_BBTMDR);
} else
- fb_writew(1, HD64461_BBTMDR);
+ hitfb_writew(1, HD64461_BBTMDR);
} else {
saddr = WIDTH * sy + sx;
daddr = WIDTH * dy + dx;
if (mask_addr) {
- fb_writew((1 << 5), HD64461_BBTMDR);
+ hitfb_writew((1 << 5), HD64461_BBTMDR);
} else {
- fb_writew(0, HD64461_BBTMDR);
+ hitfb_writew(0, HD64461_BBTMDR);
}
}
if (truecolor) {
saddr <<= 1;
daddr <<= 1;
}
- fb_writew(width, HD64461_BBTDWR);
- fb_writew(height, HD64461_BBTDHR);
- fb_writew(saddr & 0xffff, HD64461_BBTSSARL);
- fb_writew(saddr >> 16, HD64461_BBTSSARH);
- fb_writew(daddr & 0xffff, HD64461_BBTDSARL);
- fb_writew(daddr >> 16, HD64461_BBTDSARH);
+ hitfb_writew(width, HD64461_BBTDWR);
+ hitfb_writew(height, HD64461_BBTDHR);
+ hitfb_writew(saddr & 0xffff, HD64461_BBTSSARL);
+ hitfb_writew(saddr >> 16, HD64461_BBTSSARH);
+ hitfb_writew(daddr & 0xffff, HD64461_BBTDSARL);
+ hitfb_writew(daddr >> 16, HD64461_BBTDSARH);
if (mask_addr) {
maddr += mask_addr;
- fb_writew(maddr & 0xffff, HD64461_BBTMARL);
- fb_writew(maddr >> 16, HD64461_BBTMARH);
+ hitfb_writew(maddr & 0xffff, HD64461_BBTMARL);
+ hitfb_writew(maddr >> 16, HD64461_BBTMARH);
}
hitfb_accel_start(truecolor);
}
@@ -127,17 +143,17 @@ static void hitfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
cfb_fillrect(p, rect);
else {
hitfb_accel_wait();
- fb_writew(0x00f0, HD64461_BBTROPR);
- fb_writew(16, HD64461_BBTMDR);
+ hitfb_writew(0x00f0, HD64461_BBTROPR);
+ hitfb_writew(16, HD64461_BBTMDR);
if (p->var.bits_per_pixel == 16) {
- fb_writew(((u32 *) (p->pseudo_palette))[rect->color],
+ hitfb_writew(((u32 *) (p->pseudo_palette))[rect->color],
HD64461_GRSCR);
hitfb_accel_set_dest(1, rect->dx, rect->dy, rect->width,
rect->height);
hitfb_accel_start(1);
} else {
- fb_writew(rect->color, HD64461_GRSCR);
+ hitfb_writew(rect->color, HD64461_GRSCR);
hitfb_accel_set_dest(0, rect->dx, rect->dy, rect->width,
rect->height);
hitfb_accel_start(0);
@@ -162,7 +178,7 @@ static int hitfb_pan_display(struct fb_var_screeninfo *var,
if (xoffset != 0)
return -EINVAL;
- fb_writew((yoffset*info->fix.line_length)>>10, HD64461_LCDCBAR);
+ hitfb_writew((yoffset*info->fix.line_length)>>10, HD64461_LCDCBAR);
return 0;
}
@@ -172,33 +188,33 @@ int hitfb_blank(int blank_mode, struct fb_info *info)
unsigned short v;
if (blank_mode) {
- v = fb_readw(HD64461_LDR1);
+ v = hitfb_readw(HD64461_LDR1);
v &= ~HD64461_LDR1_DON;
- fb_writew(v, HD64461_LDR1);
+ hitfb_writew(v, HD64461_LDR1);
- v = fb_readw(HD64461_LCDCCR);
+ v = hitfb_readw(HD64461_LCDCCR);
v |= HD64461_LCDCCR_MOFF;
- fb_writew(v, HD64461_LCDCCR);
+ hitfb_writew(v, HD64461_LCDCCR);
- v = fb_readw(HD64461_STBCR);
+ v = hitfb_readw(HD64461_STBCR);
v |= HD64461_STBCR_SLCDST;
- fb_writew(v, HD64461_STBCR);
+ hitfb_writew(v, HD64461_STBCR);
} else {
- v = fb_readw(HD64461_STBCR);
+ v = hitfb_readw(HD64461_STBCR);
v &= ~HD64461_STBCR_SLCDST;
- fb_writew(v, HD64461_STBCR);
+ hitfb_writew(v, HD64461_STBCR);
- v = fb_readw(HD64461_LCDCCR);
+ v = hitfb_readw(HD64461_LCDCCR);
v &= ~(HD64461_LCDCCR_MOFF | HD64461_LCDCCR_STREQ);
- fb_writew(v, HD64461_LCDCCR);
+ hitfb_writew(v, HD64461_LCDCCR);
do {
- v = fb_readw(HD64461_LCDCCR);
+ v = hitfb_readw(HD64461_LCDCCR);
} while(v&HD64461_LCDCCR_STBACK);
- v = fb_readw(HD64461_LDR1);
+ v = hitfb_readw(HD64461_LDR1);
v |= HD64461_LDR1_DON;
- fb_writew(v, HD64461_LDR1);
+ hitfb_writew(v, HD64461_LDR1);
}
return 0;
}
@@ -211,10 +227,10 @@ static int hitfb_setcolreg(unsigned regno, unsigned red, unsigned green,
switch (info->var.bits_per_pixel) {
case 8:
- fb_writew(regno << 8, HD64461_CPTWAR);
- fb_writew(red >> 10, HD64461_CPTWDR);
- fb_writew(green >> 10, HD64461_CPTWDR);
- fb_writew(blue >> 10, HD64461_CPTWDR);
+ hitfb_writew(regno << 8, HD64461_CPTWAR);
+ hitfb_writew(red >> 10, HD64461_CPTWDR);
+ hitfb_writew(green >> 10, HD64461_CPTWDR);
+ hitfb_writew(blue >> 10, HD64461_CPTWDR);
break;
case 16:
if (regno >= 16)
@@ -302,11 +318,11 @@ static int hitfb_set_par(struct fb_info *info)
break;
}
- fb_writew(info->fix.line_length, HD64461_LCDCLOR);
- ldr3 = fb_readw(HD64461_LDR3);
+ hitfb_writew(info->fix.line_length, HD64461_LCDCLOR);
+ ldr3 = hitfb_readw(HD64461_LDR3);
ldr3 &= ~15;
ldr3 |= (info->var.bits_per_pixel == 8) ? 4 : 8;
- fb_writew(ldr3, HD64461_LDR3);
+ hitfb_writew(ldr3, HD64461_LDR3);
return 0;
}
@@ -337,9 +353,9 @@ static int hitfb_probe(struct platform_device *dev)
hitfb_fix.smem_start = HD64461_IO_OFFSET(0x02000000);
hitfb_fix.smem_len = 512 * 1024;
- lcdclor = fb_readw(HD64461_LCDCLOR);
- ldvndr = fb_readw(HD64461_LDVNDR);
- ldr3 = fb_readw(HD64461_LDR3);
+ lcdclor = hitfb_readw(HD64461_LCDCLOR);
+ ldvndr = hitfb_readw(HD64461_LDVNDR);
+ ldr3 = hitfb_readw(HD64461_LDR3);
switch (ldr3 & 15) {
default:
@@ -429,9 +445,9 @@ static int hitfb_suspend(struct device *dev)
u16 v;
hitfb_blank(1,0);
- v = fb_readw(HD64461_STBCR);
+ v = hitfb_readw(HD64461_STBCR);
v |= HD64461_STBCR_SLCKE_IST;
- fb_writew(v, HD64461_STBCR);
+ hitfb_writew(v, HD64461_STBCR);
return 0;
}
@@ -440,12 +456,12 @@ static int hitfb_resume(struct device *dev)
{
u16 v;
- v = fb_readw(HD64461_STBCR);
+ v = hitfb_readw(HD64461_STBCR);
v &= ~HD64461_STBCR_SLCKE_OST;
msleep(100);
- v = fb_readw(HD64461_STBCR);
+ v = hitfb_readw(HD64461_STBCR);
v &= ~HD64461_STBCR_SLCKE_IST;
- fb_writew(v, HD64461_STBCR);
+ hitfb_writew(v, HD64461_STBCR);
hitfb_blank(0,0);
return 0;
diff --git a/drivers/video/fbdev/hpfb.c b/drivers/video/fbdev/hpfb.c
index cdd44e5deafe..77fbff47b1a8 100644
--- a/drivers/video/fbdev/hpfb.c
+++ b/drivers/video/fbdev/hpfb.c
@@ -92,7 +92,7 @@ static int hpfb_setcolreg(unsigned regno, unsigned red, unsigned green,
if (regno >= info->cmap.len)
return 1;
-
+
while (in_be16(fb_regs + 0x6002) & 0x4) udelay(1);
out_be16(fb_regs + 0x60ba, 0xff);
@@ -143,7 +143,7 @@ static void topcat_blit(int x0, int y0, int x1, int y1, int w, int h, int rr)
out_8(fb_regs + WMOVE, fb_bitmask);
}
-static void hpfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
+static void hpfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
{
topcat_blit(area->sx, area->sy, area->dx, area->dy, area->width, area->height, RR_COPY);
}
@@ -315,7 +315,7 @@ unmap_screen_base:
return ret;
}
-/*
+/*
* Check that the secondary ID indicates that we have some hope of working with this
* framebuffer. The catseye boards are pretty much like topcats and we can muddle through.
*/
@@ -323,7 +323,7 @@ unmap_screen_base:
#define topcat_sid_ok(x) (((x) == DIO_ID2_LRCATSEYE) || ((x) == DIO_ID2_HRCCATSEYE) \
|| ((x) == DIO_ID2_HRMCATSEYE) || ((x) == DIO_ID2_TOPCAT))
-/*
+/*
* Initialise the framebuffer
*/
static int hpfb_dio_probe(struct dio_dev *d, const struct dio_device_id *ent)
diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c
index 34781dec3856..1ae35ab62b29 100644
--- a/drivers/video/fbdev/hyperv_fb.c
+++ b/drivers/video/fbdev/hyperv_fb.c
@@ -1073,7 +1073,7 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info)
info->screen_size = dio_fb_size;
getmem_done:
- aperture_remove_conflicting_devices(base, size, false, KBUILD_MODNAME);
+ aperture_remove_conflicting_devices(base, size, KBUILD_MODNAME);
if (gen2vm) {
/* framebuffer is reallocated, clear screen_info to avoid misuse from kexec */
diff --git a/drivers/video/fbdev/imsttfb.c b/drivers/video/fbdev/imsttfb.c
index bea45647184e..975dd682fae4 100644
--- a/drivers/video/fbdev/imsttfb.c
+++ b/drivers/video/fbdev/imsttfb.c
@@ -1347,7 +1347,7 @@ static const struct fb_ops imsttfb_ops = {
.fb_ioctl = imsttfb_ioctl,
};
-static void init_imstt(struct fb_info *info)
+static int init_imstt(struct fb_info *info)
{
struct imstt_par *par = info->par;
__u32 i, tmp, *ip, *end;
@@ -1420,7 +1420,7 @@ static void init_imstt(struct fb_info *info)
|| !(compute_imstt_regvals(par, info->var.xres, info->var.yres))) {
printk("imsttfb: %ux%ux%u not supported\n", info->var.xres, info->var.yres, info->var.bits_per_pixel);
framebuffer_release(info);
- return;
+ return -ENODEV;
}
sprintf(info->fix.id, "IMS TT (%s)", par->ramdac == IBM ? "IBM" : "TVP");
@@ -1456,12 +1456,13 @@ static void init_imstt(struct fb_info *info)
if (register_framebuffer(info) < 0) {
framebuffer_release(info);
- return;
+ return -ENODEV;
}
tmp = (read_reg_le32(par->dc_regs, SSTATUS) & 0x0f00) >> 8;
fb_info(info, "%s frame buffer; %uMB vram; chip version %u\n",
info->fix.id, info->fix.smem_len >> 20, tmp);
+ return 0;
}
static int imsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
@@ -1529,10 +1530,10 @@ static int imsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (!par->cmap_regs)
goto error;
info->pseudo_palette = par->palette;
- init_imstt(info);
-
- pci_set_drvdata(pdev, info);
- return 0;
+ ret = init_imstt(info);
+ if (!ret)
+ pci_set_drvdata(pdev, info);
+ return ret;
error:
if (par->dc_regs)
diff --git a/drivers/video/fbdev/kyro/fbdev.c b/drivers/video/fbdev/kyro/fbdev.c
index 0596573ef140..3f277bdb3a32 100644
--- a/drivers/video/fbdev/kyro/fbdev.c
+++ b/drivers/video/fbdev/kyro/fbdev.c
@@ -737,7 +737,7 @@ static int kyrofb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
info->var.bits_per_pixel);
size *= info->var.yres_virtual;
- fb_memset(info->screen_base, 0, size);
+ fb_memset_io(info->screen_base, 0, size);
if (register_framebuffer(info) < 0)
goto out_unmap;
diff --git a/drivers/video/fbdev/macfb.c b/drivers/video/fbdev/macfb.c
index 312e35c9aa6c..44ff860a3f37 100644
--- a/drivers/video/fbdev/macfb.c
+++ b/drivers/video/fbdev/macfb.c
@@ -339,7 +339,7 @@ static int civic_setpalette(unsigned int regno, unsigned int red,
{
unsigned long flags;
int clut_status;
-
+
local_irq_save(flags);
/* Set the register address */
@@ -439,7 +439,7 @@ static int macfb_setcolreg(unsigned regno, unsigned red, unsigned green,
* (according to the entries in the `var' structure).
* Return non-zero for invalid regno.
*/
-
+
if (regno >= fb_info->cmap.len)
return 1;
@@ -548,7 +548,7 @@ static int __init macfb_init(void)
return -ENODEV;
macfb_setup(option);
- if (!MACH_IS_MAC)
+ if (!MACH_IS_MAC)
return -ENODEV;
if (mac_bi_data.id == MAC_MODEL_Q630 ||
@@ -644,7 +644,7 @@ static int __init macfb_init(void)
err = -EINVAL;
goto fail_unmap;
}
-
+
/*
* We take a wild guess that if the video physical address is
* in nubus slot space, that the nubus card is driving video.
@@ -774,7 +774,7 @@ static int __init macfb_init(void)
civic_cmap_regs = ioremap(CIVIC_BASE, 0x1000);
break;
-
+
/*
* Assorted weirdos
* We think this may be like the LC II
diff --git a/drivers/video/fbdev/matrox/matroxfb_accel.c b/drivers/video/fbdev/matrox/matroxfb_accel.c
index 9cb0685feddd..ce51227798a1 100644
--- a/drivers/video/fbdev/matrox/matroxfb_accel.c
+++ b/drivers/video/fbdev/matrox/matroxfb_accel.c
@@ -88,7 +88,7 @@
static inline void matrox_cfb4_pal(u_int32_t* pal) {
unsigned int i;
-
+
for (i = 0; i < 16; i++) {
pal[i] = i * 0x11111111U;
}
@@ -96,7 +96,7 @@ static inline void matrox_cfb4_pal(u_int32_t* pal) {
static inline void matrox_cfb8_pal(u_int32_t* pal) {
unsigned int i;
-
+
for (i = 0; i < 16; i++) {
pal[i] = i * 0x01010101U;
}
@@ -482,7 +482,7 @@ static void matroxfb_1bpp_imageblit(struct matrox_fb_info *minfo, u_int32_t fgx,
/* Tell... well, why bother... */
while (height--) {
size_t i;
-
+
for (i = 0; i < step; i += 4) {
/* Hope that there are at least three readable bytes beyond the end of bitmap */
fb_writel(get_unaligned((u_int32_t*)(chardata + i)),mmio.vaddr);
diff --git a/drivers/video/fbdev/matrox/matroxfb_base.h b/drivers/video/fbdev/matrox/matroxfb_base.h
index 958be6805f87..c93c69bbcd57 100644
--- a/drivers/video/fbdev/matrox/matroxfb_base.h
+++ b/drivers/video/fbdev/matrox/matroxfb_base.h
@@ -301,9 +301,9 @@ struct matrox_altout {
int (*verifymode)(void* altout_dev, u_int32_t mode);
int (*getqueryctrl)(void* altout_dev,
struct v4l2_queryctrl* ctrl);
- int (*getctrl)(void* altout_dev,
+ int (*getctrl)(void *altout_dev,
struct v4l2_control* ctrl);
- int (*setctrl)(void* altout_dev,
+ int (*setctrl)(void *altout_dev,
struct v4l2_control* ctrl);
};
diff --git a/drivers/video/fbdev/maxinefb.c b/drivers/video/fbdev/maxinefb.c
index ae1a42bcb0ea..4e6b05232ae2 100644
--- a/drivers/video/fbdev/maxinefb.c
+++ b/drivers/video/fbdev/maxinefb.c
@@ -138,7 +138,7 @@ int __init maxinefb_init(void)
*(volatile unsigned char *)fboff = 0x0;
maxinefb_fix.smem_start = fb_start;
-
+
/* erase hardware cursor */
for (i = 0; i < 512; i++) {
maxinefb_ims332_write_register(IMS332_REG_CURSOR_RAM + i,
diff --git a/drivers/video/fbdev/metronomefb.c b/drivers/video/fbdev/metronomefb.c
index bbdbf463f0c8..bac255c749e7 100644
--- a/drivers/video/fbdev/metronomefb.c
+++ b/drivers/video/fbdev/metronomefb.c
@@ -438,7 +438,7 @@ static void metronomefb_dpy_update(struct metronomefb_par *par)
{
int fbsize;
u16 cksum;
- unsigned char *buf = (unsigned char __force *)par->info->screen_base;
+ unsigned char *buf = par->info->screen_buffer;
fbsize = par->info->fix.smem_len;
/* copy from vm to metromem */
@@ -453,7 +453,7 @@ static u16 metronomefb_dpy_update_page(struct metronomefb_par *par, int index)
{
int i;
u16 csum = 0;
- u16 *buf = (u16 __force *)(par->info->screen_base + index);
+ u16 *buf = (u16 *)(par->info->screen_buffer + index);
u16 *img = (u16 *)(par->metromem_img + index);
/* swizzle from vm to metromem and recalc cksum at the same time*/
@@ -523,8 +523,8 @@ static ssize_t metronomefb_write(struct fb_info *info, const char __user *buf,
int err = 0;
unsigned long total_size;
- if (info->state != FBINFO_STATE_RUNNING)
- return -EPERM;
+ if (!info->screen_buffer)
+ return -ENODEV;
total_size = info->fix.smem_len;
@@ -543,7 +543,7 @@ static ssize_t metronomefb_write(struct fb_info *info, const char __user *buf,
count = total_size - p;
}
- dst = (void __force *)(info->screen_base + p);
+ dst = info->screen_buffer + p;
if (copy_from_user(dst, buf, count))
err = -EFAULT;
@@ -599,7 +599,7 @@ static int metronomefb_probe(struct platform_device *dev)
goto err;
/* we have two blocks of memory.
- info->screen_base which is vm, and is the fb used by apps.
+ info->screen_buffer which is vm, and is the fb used by apps.
par->metromem which is physically contiguous memory and
contains the display controller commands, waveform,
processed image data and padding. this is the data pulled
@@ -634,7 +634,7 @@ static int metronomefb_probe(struct platform_device *dev)
if (!videomemory)
goto err_fb_rel;
- info->screen_base = (char __force __iomem *)videomemory;
+ info->screen_buffer = videomemory;
info->fbops = &metronomefb_ops;
metronomefb_fix.line_length = fw;
@@ -756,7 +756,7 @@ static void metronomefb_remove(struct platform_device *dev)
fb_dealloc_cmap(&info->cmap);
par->board->cleanup(par);
vfree(par->csum_table);
- vfree((void __force *)info->screen_base);
+ vfree(info->screen_buffer);
module_put(par->board->owner);
dev_dbg(&dev->dev, "calling release\n");
framebuffer_release(info);
diff --git a/drivers/video/fbdev/p9100.c b/drivers/video/fbdev/p9100.c
index 3e44f9516318..0876962c52eb 100644
--- a/drivers/video/fbdev/p9100.c
+++ b/drivers/video/fbdev/p9100.c
@@ -65,7 +65,7 @@ static const struct fb_ops p9100_ops = {
#define P9100_FB_OFF 0x0UL
/* 3 bits: 2=8bpp 3=16bpp 5=32bpp 7=24bpp */
-#define SYS_CONFIG_PIXELSIZE_SHIFT 26
+#define SYS_CONFIG_PIXELSIZE_SHIFT 26
#define SCREENPAINT_TIMECTL1_ENABLE_VIDEO 0x20 /* 0 = off, 1 = on */
@@ -110,7 +110,7 @@ struct p9100_regs {
u32 vram_xxx[25];
/* Registers for IBM RGB528 Palette */
- u32 ramdac_cmap_wridx;
+ u32 ramdac_cmap_wridx;
u32 ramdac_palette_data;
u32 ramdac_pixel_mask;
u32 ramdac_palette_rdaddr;
diff --git a/drivers/video/fbdev/platinumfb.c b/drivers/video/fbdev/platinumfb.c
index 82f019f0a0d6..f8283fcd5edb 100644
--- a/drivers/video/fbdev/platinumfb.c
+++ b/drivers/video/fbdev/platinumfb.c
@@ -52,17 +52,17 @@ struct fb_info_platinum {
__u8 red, green, blue;
} palette[256];
u32 pseudo_palette[16];
-
+
volatile struct cmap_regs __iomem *cmap_regs;
unsigned long cmap_regs_phys;
-
+
volatile struct platinum_regs __iomem *platinum_regs;
unsigned long platinum_regs_phys;
-
+
__u8 __iomem *frame_buffer;
volatile __u8 __iomem *base_frame_buffer;
unsigned long frame_buffer_phys;
-
+
unsigned long total_vram;
int clktype;
int dactype;
@@ -133,7 +133,7 @@ static int platinumfb_set_par (struct fb_info *info)
platinum_set_hardware(pinfo);
init = platinum_reg_init[pinfo->vmode-1];
-
+
if ((pinfo->vmode == VMODE_832_624_75) && (pinfo->cmode > CMODE_8))
offset = 0x10;
@@ -214,7 +214,7 @@ static int platinumfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
break;
}
}
-
+
return 0;
}
@@ -269,7 +269,7 @@ static void platinum_set_hardware(struct fb_info_platinum *pinfo)
struct platinum_regvals *init;
int i;
int vmode, cmode;
-
+
vmode = pinfo->vmode;
cmode = pinfo->cmode;
@@ -436,7 +436,7 @@ static int read_platinum_sense(struct fb_info_platinum *info)
* This routine takes a user-supplied var, and picks the best vmode/cmode from it.
* It also updates the var structure to the actual mode data obtained
*/
-static int platinum_var_to_par(struct fb_var_screeninfo *var,
+static int platinum_var_to_par(struct fb_var_screeninfo *var,
struct fb_info_platinum *pinfo,
int check_only)
{
@@ -478,12 +478,12 @@ static int platinum_var_to_par(struct fb_var_screeninfo *var,
pinfo->yoffset = 0;
pinfo->vxres = pinfo->xres;
pinfo->vyres = pinfo->yres;
-
+
return 0;
}
-/*
+/*
* Parse user specified options (`video=platinumfb:')
*/
static int __init platinumfb_setup(char *options)
@@ -624,7 +624,7 @@ static int platinumfb_probe(struct platform_device* odev)
break;
}
dev_set_drvdata(&odev->dev, info);
-
+
rc = platinum_init_fb(info);
if (rc != 0) {
iounmap(pinfo->frame_buffer);
@@ -640,9 +640,9 @@ static void platinumfb_remove(struct platform_device* odev)
{
struct fb_info *info = dev_get_drvdata(&odev->dev);
struct fb_info_platinum *pinfo = info->par;
-
+
unregister_framebuffer (info);
-
+
/* Unmap frame buffer and registers */
iounmap(pinfo->frame_buffer);
iounmap(pinfo->platinum_regs);
@@ -656,7 +656,7 @@ static void platinumfb_remove(struct platform_device* odev)
framebuffer_release(info);
}
-static struct of_device_id platinumfb_match[] =
+static struct of_device_id platinumfb_match[] =
{
{
.name = "platinum",
@@ -664,7 +664,7 @@ static struct of_device_id platinumfb_match[] =
{},
};
-static struct platform_driver platinum_driver =
+static struct platform_driver platinum_driver =
{
.driver = {
.name = "platinumfb",
diff --git a/drivers/video/fbdev/ps3fb.c b/drivers/video/fbdev/ps3fb.c
index 98aaa330a193..d4abcf8aff75 100644
--- a/drivers/video/fbdev/ps3fb.c
+++ b/drivers/video/fbdev/ps3fb.c
@@ -650,7 +650,7 @@ static int ps3fb_set_par(struct fb_info *info)
}
/* Clear XDR frame buffer memory */
- memset((void __force *)info->screen_base, 0, info->fix.smem_len);
+ memset(info->screen_buffer, 0, info->fix.smem_len);
/* Clear DDR frame buffer memory */
lines = vmode->yres * par->num_frames;
@@ -1140,7 +1140,7 @@ static int ps3fb_probe(struct ps3_system_bus_device *dev)
* memory
*/
fb_start = ps3fb_videomemory.address + GPU_FB_START;
- info->screen_base = (char __force __iomem *)fb_start;
+ info->screen_buffer = fb_start;
info->fix.smem_start = __pa(fb_start);
info->fix.smem_len = ps3fb_videomemory.size - GPU_FB_START;
diff --git a/drivers/video/fbdev/pvr2fb.c b/drivers/video/fbdev/pvr2fb.c
index 6888127a5eb8..c692cd597ce3 100644
--- a/drivers/video/fbdev/pvr2fb.c
+++ b/drivers/video/fbdev/pvr2fb.c
@@ -647,6 +647,9 @@ static ssize_t pvr2fb_write(struct fb_info *info, const char *buf,
struct page **pages;
int ret, i;
+ if (!info->screen_base)
+ return -ENODEV;
+
nr_pages = (count + PAGE_SIZE - 1) >> PAGE_SHIFT;
pages = kmalloc_array(nr_pages, sizeof(struct page *), GFP_KERNEL);
@@ -798,7 +801,7 @@ static int __maybe_unused pvr2fb_common_init(void)
goto out_err;
}
- fb_memset(fb_info->screen_base, 0, pvr2_fix.smem_len);
+ fb_memset_io(fb_info->screen_base, 0, pvr2_fix.smem_len);
pvr2_fix.ypanstep = nopan ? 0 : 1;
pvr2_fix.ywrapstep = nowrap ? 0 : 1;
diff --git a/drivers/video/fbdev/sa1100fb.c b/drivers/video/fbdev/sa1100fb.c
index b1b8ccdbac4a..a2408bf00ca0 100644
--- a/drivers/video/fbdev/sa1100fb.c
+++ b/drivers/video/fbdev/sa1100fb.c
@@ -57,14 +57,14 @@
* - Driver appears to be working for Brutus 320x200x8bpp mode. Other
* resolutions are working, but only the 8bpp mode is supported.
* Changes need to be made to the palette encode and decode routines
- * to support 4 and 16 bpp modes.
+ * to support 4 and 16 bpp modes.
* Driver is not designed to be a module. The FrameBuffer is statically
- * allocated since dynamic allocation of a 300k buffer cannot be
- * guaranteed.
+ * allocated since dynamic allocation of a 300k buffer cannot be
+ * guaranteed.
*
* 1999/06/17:
* - FrameBuffer memory is now allocated at run-time when the
- * driver is initialized.
+ * driver is initialized.
*
* 2000/04/10: Nicolas Pitre <nico@fluxnic.net>
* - Big cleanup for dynamic selection of machine type at run time.
@@ -74,8 +74,8 @@
*
* 2000/08/07: Tak-Shing Chan <tchan.rd@idthk.com>
* Jeff Sutherland <jsutherland@accelent.com>
- * - Resolved an issue caused by a change made to the Assabet's PLD
- * earlier this year which broke the framebuffer driver for newer
+ * - Resolved an issue caused by a change made to the Assabet's PLD
+ * earlier this year which broke the framebuffer driver for newer
* Phase 4 Assabets. Some other parameters were changed to optimize
* for the Sharp display.
*
@@ -102,7 +102,7 @@
* 2000/11/23: Eric Peng <ericpeng@coventive.com>
* - Freebird add
*
- * 2001/02/07: Jamey Hicks <jamey.hicks@compaq.com>
+ * 2001/02/07: Jamey Hicks <jamey.hicks@compaq.com>
* Cliff Brake <cbrake@accelent.com>
* - Added PM callback
*
@@ -500,7 +500,7 @@ sa1100fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
* the shortest recovery time
* Suspend
* This refers to a level of power management in which substantial power
- * reduction is achieved by the display. The display can have a longer
+ * reduction is achieved by the display. The display can have a longer
* recovery time from this state than from the Stand-by state
* Off
* This indicates that the display is consuming the lowest level of power
@@ -522,9 +522,9 @@ sa1100fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
*/
/*
* sa1100fb_blank():
- * Blank the display by setting all palette values to zero. Note, the
+ * Blank the display by setting all palette values to zero. Note, the
* 12 and 16 bpp modes don't really use the palette, so this will not
- * blank the display in all modes.
+ * blank the display in all modes.
*/
static int sa1100fb_blank(int blank, struct fb_info *info)
{
@@ -603,8 +603,8 @@ static inline unsigned int get_pcd(struct sa1100fb_info *fbi,
/*
* sa1100fb_activate_var():
- * Configures LCD Controller based on entries in var parameter. Settings are
- * only written to the controller if changes were made.
+ * Configures LCD Controller based on entries in var parameter. Settings are
+ * only written to the controller if changes were made.
*/
static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_info *fbi)
{
@@ -747,7 +747,7 @@ static void sa1100fb_setup_gpio(struct sa1100fb_info *fbi)
*
* SA1110 spec update nr. 25 says we can and should
* clear LDD15 to 12 for 4 or 8bpp modes with active
- * panels.
+ * panels.
*/
if ((fbi->reg_lccr0 & LCCR0_CMS) == LCCR0_Color &&
(fbi->reg_lccr0 & (LCCR0_Dual|LCCR0_Act)) != 0) {
@@ -1020,9 +1020,9 @@ static int sa1100fb_resume(struct platform_device *dev)
/*
* sa1100fb_map_video_memory():
- * Allocates the DRAM memory for the frame buffer. This buffer is
- * remapped into a non-cached, non-buffered, memory region to
- * allow palette and pixel writes to occur without flushing the
+ * Allocates the DRAM memory for the frame buffer. This buffer is
+ * remapped into a non-cached, non-buffered, memory region to
+ * allow palette and pixel writes to occur without flushing the
* cache. Once this area is remapped, all virtual memory
* access to the video memory should occur at the new region.
*/
diff --git a/drivers/video/fbdev/sm712fb.c b/drivers/video/fbdev/sm712fb.c
index b528776c7612..b7ad3c644e13 100644
--- a/drivers/video/fbdev/sm712fb.c
+++ b/drivers/video/fbdev/sm712fb.c
@@ -1028,12 +1028,9 @@ static ssize_t smtcfb_read(struct fb_info *info, char __user *buf,
int c, i, cnt = 0, err = 0;
unsigned long total_size;
- if (!info || !info->screen_base)
+ if (!info->screen_base)
return -ENODEV;
- if (info->state != FBINFO_STATE_RUNNING)
- return -EPERM;
-
total_size = info->screen_size;
if (total_size == 0)
@@ -1094,12 +1091,9 @@ static ssize_t smtcfb_write(struct fb_info *info, const char __user *buf,
int c, i, cnt = 0, err = 0;
unsigned long total_size;
- if (!info || !info->screen_base)
+ if (!info->screen_base)
return -ENODEV;
- if (info->state != FBINFO_STATE_RUNNING)
- return -EPERM;
-
total_size = info->screen_size;
if (total_size == 0)
diff --git a/drivers/video/fbdev/smscufx.c b/drivers/video/fbdev/smscufx.c
index 2ad6e98ce10d..17cec62cc65d 100644
--- a/drivers/video/fbdev/smscufx.c
+++ b/drivers/video/fbdev/smscufx.c
@@ -1150,7 +1150,7 @@ static void ufx_free_framebuffer(struct ufx_data *dev)
fb_dealloc_cmap(&info->cmap);
if (info->monspecs.modedb)
fb_destroy_modedb(info->monspecs.modedb);
- vfree(info->screen_base);
+ vfree(info->screen_buffer);
fb_destroy_modelist(&info->modelist);
@@ -1257,7 +1257,7 @@ static int ufx_ops_set_par(struct fb_info *info)
if ((result == 0) && (dev->fb_count == 0)) {
/* paint greenscreen */
- pix_framebuffer = (u16 *) info->screen_base;
+ pix_framebuffer = (u16 *)info->screen_buffer;
for (i = 0; i < info->fix.smem_len / 2; i++)
pix_framebuffer[i] = 0x37e6;
@@ -1303,7 +1303,7 @@ static int ufx_realloc_framebuffer(struct ufx_data *dev, struct fb_info *info)
{
int old_len = info->fix.smem_len;
int new_len;
- unsigned char *old_fb = info->screen_base;
+ unsigned char *old_fb = info->screen_buffer;
unsigned char *new_fb;
pr_debug("Reallocating framebuffer. Addresses will change!");
@@ -1318,12 +1318,12 @@ static int ufx_realloc_framebuffer(struct ufx_data *dev, struct fb_info *info)
if (!new_fb)
return -ENOMEM;
- if (info->screen_base) {
+ if (info->screen_buffer) {
memcpy(new_fb, old_fb, old_len);
- vfree(info->screen_base);
+ vfree(info->screen_buffer);
}
- info->screen_base = new_fb;
+ info->screen_buffer = new_fb;
info->fix.smem_len = PAGE_ALIGN(new_len);
info->fix.smem_start = (unsigned long) new_fb;
info->flags = smscufx_info_flags;
@@ -1746,7 +1746,7 @@ reset_active:
atomic_set(&dev->usb_active, 0);
setup_modes:
fb_destroy_modedb(info->monspecs.modedb);
- vfree(info->screen_base);
+ vfree(info->screen_buffer);
fb_destroy_modelist(&info->modelist);
error:
fb_dealloc_cmap(&info->cmap);
diff --git a/drivers/video/fbdev/ssd1307fb.c b/drivers/video/fbdev/ssd1307fb.c
index 046b9990d27c..a8f2975de76b 100644
--- a/drivers/video/fbdev/ssd1307fb.c
+++ b/drivers/video/fbdev/ssd1307fb.c
@@ -301,6 +301,9 @@ static ssize_t ssd1307fb_write(struct fb_info *info, const char __user *buf,
void *dst;
int ret;
+ if (!info->screen_buffer)
+ return -ENODEV;
+
total_size = info->fix.smem_len;
if (p > total_size)
diff --git a/drivers/video/fbdev/sstfb.c b/drivers/video/fbdev/sstfb.c
index da296b2ab54a..582324f5d869 100644
--- a/drivers/video/fbdev/sstfb.c
+++ b/drivers/video/fbdev/sstfb.c
@@ -335,7 +335,7 @@ static int sst_calc_pll(const int freq, int *freq_out, struct pll_timing *t)
static void sstfb_clear_screen(struct fb_info *info)
{
/* clear screen */
- fb_memset(info->screen_base, 0, info->fix.smem_len);
+ fb_memset_io(info->screen_base, 0, info->fix.smem_len);
}
diff --git a/drivers/video/fbdev/stifb.c b/drivers/video/fbdev/stifb.c
index ef8a4c5fc687..66d82f6d17c7 100644
--- a/drivers/video/fbdev/stifb.c
+++ b/drivers/video/fbdev/stifb.c
@@ -1,11 +1,11 @@
/*
- * linux/drivers/video/stifb.c -
- * Low level Frame buffer driver for HP workstations with
+ * linux/drivers/video/stifb.c -
+ * Low level Frame buffer driver for HP workstations with
* STI (standard text interface) video firmware.
*
* Copyright (C) 2001-2006 Helge Deller <deller@gmx.de>
* Portions Copyright (C) 2001 Thomas Bogendoerfer <tsbogend@alpha.franken.de>
- *
+ *
* Based on:
* - linux/drivers/video/artistfb.c -- Artist frame buffer driver
* Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
@@ -14,7 +14,7 @@
* - HP Xhp cfb-based X11 window driver for XFree86
* (c)Copyright 1992 Hewlett-Packard Co.
*
- *
+ *
* The following graphics display devices (NGLE family) are supported by this driver:
*
* HPA4070A known as "HCRX", a 1280x1024 color device with 8 planes
@@ -30,7 +30,7 @@
* supports 1280x1024 color displays with 8 planes.
* HP710G same as HP710C, 1280x1024 grayscale only
* HP710L same as HP710C, 1024x768 color only
- * HP712 internal graphics support on HP9000s712 SPU, supports 640x480,
+ * HP712 internal graphics support on HP9000s712 SPU, supports 640x480,
* 1024x768 or 1280x1024 color displays on 8 planes (Artist)
*
* This file is subject to the terms and conditions of the GNU General Public
@@ -69,7 +69,7 @@
#include <asm/grfioctl.h> /* for HP-UX compatibility */
#include <linux/uaccess.h>
-#include "sticore.h"
+#include <video/sticore.h>
/* REGION_BASE(fb_info, index) returns the virtual address for region <index> */
#define REGION_BASE(fb_info, index) \
@@ -92,7 +92,7 @@ typedef struct {
__s32 misc_video_end;
} video_setup_t;
-typedef struct {
+typedef struct {
__s16 sizeof_ngle_data;
__s16 x_size_visible; /* visible screen dim in pixels */
__s16 y_size_visible;
@@ -177,10 +177,10 @@ static int __initdata stifb_bpp_pref[MAX_STI_ROMS];
#endif /* DEBUG_STIFB_REGS */
-#define ENABLE 1 /* for enabling/disabling screen */
+#define ENABLE 1 /* for enabling/disabling screen */
#define DISABLE 0
-#define NGLE_LOCK(fb_info) do { } while (0)
+#define NGLE_LOCK(fb_info) do { } while (0)
#define NGLE_UNLOCK(fb_info) do { } while (0)
static void
@@ -198,9 +198,9 @@ SETUP_HW(struct stifb_info *fb)
static void
SETUP_FB(struct stifb_info *fb)
-{
+{
unsigned int reg10_value = 0;
-
+
SETUP_HW(fb);
switch (fb->id)
{
@@ -210,15 +210,15 @@ SETUP_FB(struct stifb_info *fb)
reg10_value = 0x13601000;
break;
case S9000_ID_A1439A:
- if (fb->info.var.bits_per_pixel == 32)
+ if (fb->info.var.bits_per_pixel == 32)
reg10_value = 0xBBA0A000;
- else
+ else
reg10_value = 0x13601000;
break;
case S9000_ID_HCRX:
if (fb->info.var.bits_per_pixel == 32)
reg10_value = 0xBBA0A000;
- else
+ else
reg10_value = 0x13602000;
break;
case S9000_ID_TIMBER:
@@ -243,7 +243,7 @@ START_IMAGE_COLORMAP_ACCESS(struct stifb_info *fb)
}
static void
-WRITE_IMAGE_COLOR(struct stifb_info *fb, int index, int color)
+WRITE_IMAGE_COLOR(struct stifb_info *fb, int index, int color)
{
SETUP_HW(fb);
WRITE_WORD(((0x100+index)<<2), fb, REG_3);
@@ -251,30 +251,30 @@ WRITE_IMAGE_COLOR(struct stifb_info *fb, int index, int color)
}
static void
-FINISH_IMAGE_COLORMAP_ACCESS(struct stifb_info *fb)
-{
+FINISH_IMAGE_COLORMAP_ACCESS(struct stifb_info *fb)
+{
WRITE_WORD(0x400, fb, REG_2);
if (fb->info.var.bits_per_pixel == 32) {
WRITE_WORD(0x83000100, fb, REG_1);
} else {
if (fb->id == S9000_ID_ARTIST || fb->id == CRT_ID_VISUALIZE_EG)
WRITE_WORD(0x80000100, fb, REG_26);
- else
+ else
WRITE_WORD(0x80000100, fb, REG_1);
}
SETUP_FB(fb);
}
static void
-SETUP_RAMDAC(struct stifb_info *fb)
+SETUP_RAMDAC(struct stifb_info *fb)
{
SETUP_HW(fb);
WRITE_WORD(0x04000000, fb, 0x1020);
WRITE_WORD(0xff000000, fb, 0x1028);
}
-static void
-CRX24_SETUP_RAMDAC(struct stifb_info *fb)
+static void
+CRX24_SETUP_RAMDAC(struct stifb_info *fb)
{
SETUP_HW(fb);
WRITE_WORD(0x04000000, fb, 0x1000);
@@ -286,14 +286,14 @@ CRX24_SETUP_RAMDAC(struct stifb_info *fb)
}
#if 0
-static void
+static void
HCRX_SETUP_RAMDAC(struct stifb_info *fb)
{
WRITE_WORD(0xffffffff, fb, REG_32);
}
#endif
-static void
+static void
CRX24_SET_OVLY_MASK(struct stifb_info *fb)
{
SETUP_HW(fb);
@@ -314,7 +314,7 @@ ENABLE_DISABLE_DISPLAY(struct stifb_info *fb, int enable)
WRITE_WORD(value, fb, 0x1038);
}
-static void
+static void
CRX24_ENABLE_DISABLE_DISPLAY(struct stifb_info *fb, int enable)
{
unsigned int value = enable ? 0x10000000 : 0x30000000;
@@ -325,11 +325,11 @@ CRX24_ENABLE_DISABLE_DISPLAY(struct stifb_info *fb, int enable)
}
static void
-ARTIST_ENABLE_DISABLE_DISPLAY(struct stifb_info *fb, int enable)
+ARTIST_ENABLE_DISABLE_DISPLAY(struct stifb_info *fb, int enable)
{
u32 DregsMiscVideo = REG_21;
u32 DregsMiscCtl = REG_27;
-
+
SETUP_HW(fb);
if (enable) {
WRITE_WORD(READ_WORD(fb, DregsMiscVideo) | 0x0A000000, fb, DregsMiscVideo);
@@ -344,7 +344,7 @@ ARTIST_ENABLE_DISABLE_DISPLAY(struct stifb_info *fb, int enable)
(READ_BYTE(fb, REG_16b3) - 1)
#define HYPER_CONFIG_PLANES_24 0x00000100
-
+
#define IS_24_DEVICE(fb) \
(fb->deviceSpecificConfig & HYPER_CONFIG_PLANES_24)
@@ -470,15 +470,15 @@ SETUP_ATTR_ACCESS(struct stifb_info *fb, unsigned BufferNumber)
}
static void
-SET_ATTR_SIZE(struct stifb_info *fb, int width, int height)
+SET_ATTR_SIZE(struct stifb_info *fb, int width, int height)
{
- /* REG_6 seems to have special values when run on a
+ /* REG_6 seems to have special values when run on a
RDI precisionbook parisc laptop (INTERNAL_EG_DX1024 or
INTERNAL_EG_X1024). The values are:
0x2f0: internal (LCD) & external display enabled
0x2a0: external display only
0x000: zero on standard artist graphic cards
- */
+ */
WRITE_WORD(0x00000000, fb, REG_6);
WRITE_WORD((width<<16) | height, fb, REG_9);
WRITE_WORD(0x05000000, fb, REG_6);
@@ -486,7 +486,7 @@ SET_ATTR_SIZE(struct stifb_info *fb, int width, int height)
}
static void
-FINISH_ATTR_ACCESS(struct stifb_info *fb)
+FINISH_ATTR_ACCESS(struct stifb_info *fb)
{
SETUP_HW(fb);
WRITE_WORD(0x00000000, fb, REG_12);
@@ -499,7 +499,7 @@ elkSetupPlanes(struct stifb_info *fb)
SETUP_FB(fb);
}
-static void
+static void
ngleSetupAttrPlanes(struct stifb_info *fb, int BufferNumber)
{
SETUP_ATTR_ACCESS(fb, BufferNumber);
@@ -519,7 +519,7 @@ rattlerSetupPlanes(struct stifb_info *fb)
* read mask register for overlay planes, not image planes).
*/
CRX24_SETUP_RAMDAC(fb);
-
+
/* change fb->id temporarily to fool SETUP_FB() */
saved_id = fb->id;
fb->id = CRX24_OVERLAY_PLANES;
@@ -527,8 +527,8 @@ rattlerSetupPlanes(struct stifb_info *fb)
fb->id = saved_id;
for (y = 0; y < fb->info.var.yres; ++y)
- fb_memset(fb->info.screen_base + y * fb->info.fix.line_length,
- 0xff, fb->info.var.xres * fb->info.var.bits_per_pixel/8);
+ fb_memset_io(fb->info.screen_base + y * fb->info.fix.line_length,
+ 0xff, fb->info.var.xres * fb->info.var.bits_per_pixel/8);
CRX24_SET_OVLY_MASK(fb);
SETUP_FB(fb);
@@ -565,7 +565,7 @@ setNgleLutBltCtl(struct stifb_info *fb, int offsetWithinLut, int length)
lutBltCtl.all = 0x80000000;
lutBltCtl.fields.length = length;
- switch (fb->id)
+ switch (fb->id)
{
case S9000_ID_A1439A: /* CRX24 */
if (fb->var.bits_per_pixel == 8) {
@@ -576,12 +576,12 @@ setNgleLutBltCtl(struct stifb_info *fb, int offsetWithinLut, int length)
lutBltCtl.fields.lutOffset = 0 * 256;
}
break;
-
+
case S9000_ID_ARTIST:
lutBltCtl.fields.lutType = NGLE_CMAP_INDEXED0_TYPE;
lutBltCtl.fields.lutOffset = 0 * 256;
break;
-
+
default:
lutBltCtl.fields.lutType = NGLE_CMAP_INDEXED0_TYPE;
lutBltCtl.fields.lutOffset = 0;
@@ -596,7 +596,7 @@ setNgleLutBltCtl(struct stifb_info *fb, int offsetWithinLut, int length)
#endif
static NgleLutBltCtl
-setHyperLutBltCtl(struct stifb_info *fb, int offsetWithinLut, int length)
+setHyperLutBltCtl(struct stifb_info *fb, int offsetWithinLut, int length)
{
NgleLutBltCtl lutBltCtl;
@@ -633,7 +633,7 @@ static void hyperUndoITE(struct stifb_info *fb)
/* Hardware setup for full-depth write to "magic" location */
GET_FIFO_SLOTS(fb, nFreeFifoSlots, 7);
- NGLE_QUICK_SET_DST_BM_ACCESS(fb,
+ NGLE_QUICK_SET_DST_BM_ACCESS(fb,
BA(IndexedDcd, Otc04, Ots08, AddrLong,
BAJustPoint(0), BINovly, BAIndexBase(0)));
NGLE_QUICK_SET_IMAGE_BITMAP_OP(fb,
@@ -653,13 +653,13 @@ static void hyperUndoITE(struct stifb_info *fb)
NGLE_UNLOCK(fb);
}
-static void
+static void
ngleDepth8_ClearImagePlanes(struct stifb_info *fb)
{
/* FIXME! */
}
-static void
+static void
ngleDepth24_ClearImagePlanes(struct stifb_info *fb)
{
/* FIXME! */
@@ -675,7 +675,7 @@ ngleResetAttrPlanes(struct stifb_info *fb, unsigned int ctlPlaneReg)
NGLE_LOCK(fb);
GET_FIFO_SLOTS(fb, nFreeFifoSlots, 4);
- NGLE_QUICK_SET_DST_BM_ACCESS(fb,
+ NGLE_QUICK_SET_DST_BM_ACCESS(fb,
BA(IndexedDcd, Otc32, OtsIndirect,
AddrLong, BAJustPoint(0),
BINattr, BAIndexBase(0)));
@@ -713,22 +713,22 @@ ngleResetAttrPlanes(struct stifb_info *fb, unsigned int ctlPlaneReg)
/**** Finally, set the Control Plane Register back to zero: ****/
GET_FIFO_SLOTS(fb, nFreeFifoSlots, 1);
NGLE_QUICK_SET_CTL_PLN_REG(fb, 0);
-
+
NGLE_UNLOCK(fb);
}
-
+
static void
ngleClearOverlayPlanes(struct stifb_info *fb, int mask, int data)
{
int nFreeFifoSlots = 0;
u32 packed_dst;
u32 packed_len;
-
+
NGLE_LOCK(fb);
/* Hardware setup */
GET_FIFO_SLOTS(fb, nFreeFifoSlots, 8);
- NGLE_QUICK_SET_DST_BM_ACCESS(fb,
+ NGLE_QUICK_SET_DST_BM_ACCESS(fb,
BA(IndexedDcd, Otc04, Ots08, AddrLong,
BAJustPoint(0), BINovly, BAIndexBase(0)));
@@ -736,23 +736,23 @@ ngleClearOverlayPlanes(struct stifb_info *fb, int mask, int data)
NGLE_REALLY_SET_IMAGE_FG_COLOR(fb, data);
NGLE_REALLY_SET_IMAGE_PLANEMASK(fb, mask);
-
+
packed_dst = 0;
packed_len = (fb->info.var.xres << 16) | fb->info.var.yres;
NGLE_SET_DSTXY(fb, packed_dst);
-
- /* Write zeroes to overlay planes */
+
+ /* Write zeroes to overlay planes */
NGLE_QUICK_SET_IMAGE_BITMAP_OP(fb,
IBOvals(RopSrc, MaskAddrOffset(0),
BitmapExtent08, StaticReg(0),
DataDynamic, MaskOtc, BGx(0), FGx(0)));
-
+
SET_LENXY_START_RECFILL(fb, packed_len);
NGLE_UNLOCK(fb);
}
-static void
+static void
hyperResetPlanes(struct stifb_info *fb, int enable)
{
unsigned int controlPlaneReg;
@@ -783,7 +783,7 @@ hyperResetPlanes(struct stifb_info *fb, int enable)
ngleClearOverlayPlanes(fb, 0xff, 255);
/**************************************************
- ** Also need to counteract ITE settings
+ ** Also need to counteract ITE settings
**************************************************/
hyperUndoITE(fb);
break;
@@ -803,13 +803,13 @@ hyperResetPlanes(struct stifb_info *fb, int enable)
ngleResetAttrPlanes(fb, controlPlaneReg);
break;
}
-
+
NGLE_UNLOCK(fb);
}
/* Return pointer to in-memory structure holding ELK device-dependent ROM values. */
-static void
+static void
ngleGetDeviceRomData(struct stifb_info *fb)
{
#if 0
@@ -821,7 +821,7 @@ XXX: FIXME: !!!
char *pCard8;
int i;
char *mapOrigin = NULL;
-
+
int romTableIdx;
pPackedDevRomData = fb->ngle_rom;
@@ -888,7 +888,7 @@ SETUP_HCRX(struct stifb_info *fb)
/* Initialize Hyperbowl registers */
GET_FIFO_SLOTS(fb, nFreeFifoSlots, 7);
-
+
if (IS_24_DEVICE(fb)) {
hyperbowl = (fb->info.var.bits_per_pixel == 32) ?
HYPERBOWL_MODE01_8_24_LUT0_TRANSPARENT_LUT1_OPAQUE :
@@ -897,9 +897,9 @@ SETUP_HCRX(struct stifb_info *fb)
/* First write to Hyperbowl must happen twice (bug) */
WRITE_WORD(hyperbowl, fb, REG_40);
WRITE_WORD(hyperbowl, fb, REG_40);
-
+
WRITE_WORD(HYPERBOWL_MODE2_8_24, fb, REG_39);
-
+
WRITE_WORD(0x014c0148, fb, REG_42); /* Set lut 0 to be the direct color */
WRITE_WORD(0x404c4048, fb, REG_43);
WRITE_WORD(0x034c0348, fb, REG_44);
@@ -990,7 +990,7 @@ stifb_setcolreg(u_int regno, u_int red, u_int green,
0, /* Offset w/i LUT */
256); /* Load entire LUT */
NGLE_BINC_SET_SRCADDR(fb,
- NGLE_LONG_FB_ADDRESS(0, 0x100, 0));
+ NGLE_LONG_FB_ADDRESS(0, 0x100, 0));
/* 0x100 is same as used in WRITE_IMAGE_COLOR() */
START_COLORMAPLOAD(fb, lutBltCtl.all);
SETUP_FB(fb);
@@ -1028,7 +1028,7 @@ stifb_blank(int blank_mode, struct fb_info *info)
ENABLE_DISABLE_DISPLAY(fb, enable);
break;
}
-
+
SETUP_FB(fb);
return 0;
}
@@ -1114,15 +1114,15 @@ stifb_init_display(struct stifb_info *fb)
/* HCRX specific initialization */
SETUP_HCRX(fb);
-
+
/*
if (id == S9000_ID_HCRX)
hyperInitSprite(fb);
else
ngleInitSprite(fb);
*/
-
- /* Initialize the image planes. */
+
+ /* Initialize the image planes. */
switch (id) {
case S9000_ID_HCRX:
hyperResetPlanes(fb, ENABLE);
@@ -1194,7 +1194,7 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
fb = kzalloc(sizeof(*fb), GFP_ATOMIC);
if (!fb)
return -ENOMEM;
-
+
info = &fb->info;
/* set struct to a known state */
@@ -1235,7 +1235,7 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
dev_name, fb->id);
goto out_err0;
}
-
+
/* default to 8 bpp on most graphic chips */
bpp = 8;
xres = sti_onscreen_x(fb->sti);
@@ -1256,7 +1256,7 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
fb->id = S9000_ID_A1659A;
break;
case S9000_ID_TIMBER: /* HP9000/710 Any (may be a grayscale device) */
- if (strstr(dev_name, "GRAYSCALE") ||
+ if (strstr(dev_name, "GRAYSCALE") ||
strstr(dev_name, "Grayscale") ||
strstr(dev_name, "grayscale"))
var->grayscale = 1;
@@ -1295,16 +1295,16 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
case CRT_ID_VISUALIZE_EG:
case S9000_ID_ARTIST: /* Artist */
break;
- default:
+ default:
#ifdef FALLBACK_TO_1BPP
- printk(KERN_WARNING
+ printk(KERN_WARNING
"stifb: Unsupported graphics card (id=0x%08x) "
"- now trying 1bpp mode instead\n",
fb->id);
bpp = 1; /* default to 1 bpp */
break;
#else
- printk(KERN_WARNING
+ printk(KERN_WARNING
"stifb: Unsupported graphics card (id=0x%08x) "
"- skipping.\n",
fb->id);
@@ -1320,11 +1320,11 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
fix->line_length = (fb->sti->glob_cfg->total_x * bpp) / 8;
if (!fix->line_length)
fix->line_length = 2048; /* default */
-
+
/* limit fbsize to max visible screen size */
if (fix->smem_len > yres*fix->line_length)
fix->smem_len = ALIGN(yres*fix->line_length, 4*1024*1024);
-
+
fix->accel = FB_ACCEL_NONE;
switch (bpp) {
@@ -1350,7 +1350,7 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
default:
break;
}
-
+
var->xres = var->xres_virtual = xres;
var->yres = var->yres_virtual = yres;
var->bits_per_pixel = bpp;
@@ -1379,7 +1379,7 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
fix->smem_start, fix->smem_start+fix->smem_len);
goto out_err2;
}
-
+
if (!request_mem_region(fix->mmio_start, fix->mmio_len, "stifb mmio")) {
printk(KERN_ERR "stifb: cannot reserve sti mmio region 0x%04lx-0x%04lx\n",
fix->mmio_start, fix->mmio_start+fix->mmio_len);
@@ -1393,11 +1393,11 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
fb_info(&fb->info, "%s %dx%d-%d frame buffer device, %s, id: %04x, mmio: 0x%04lx\n",
fix->id,
- var->xres,
+ var->xres,
var->yres,
var->bits_per_pixel,
dev_name,
- fb->id,
+ fb->id,
fix->mmio_start);
return 0;
@@ -1413,6 +1413,7 @@ out_err1:
iounmap(info->screen_base);
out_err0:
kfree(fb);
+ sti->info = NULL;
return -ENXIO;
}
@@ -1426,7 +1427,7 @@ static int __init stifb_init(void)
struct sti_struct *sti;
struct sti_struct *def_sti;
int i;
-
+
#ifndef MODULE
char *option = NULL;
@@ -1438,7 +1439,7 @@ static int __init stifb_init(void)
printk(KERN_INFO "stifb: disabled by \"stifb=off\" kernel parameter\n");
return -ENXIO;
}
-
+
def_sti = sti_get_rom(0);
if (def_sti) {
for (i = 1; i <= MAX_STI_ROMS; i++) {
@@ -1472,7 +1473,7 @@ stifb_cleanup(void)
{
struct sti_struct *sti;
int i;
-
+
for (i = 1; i <= MAX_STI_ROMS; i++) {
sti = sti_get_rom(i);
if (!sti)
@@ -1495,10 +1496,10 @@ int __init
stifb_setup(char *options)
{
int i;
-
+
if (!options || !*options)
return 1;
-
+
if (strncmp(options, "off", 3) == 0) {
stifb_disabled = 1;
options += 3;
diff --git a/drivers/video/fbdev/tdfxfb.c b/drivers/video/fbdev/tdfxfb.c
index d17e5e1472aa..cdf8e9fe9948 100644
--- a/drivers/video/fbdev/tdfxfb.c
+++ b/drivers/video/fbdev/tdfxfb.c
@@ -1116,7 +1116,7 @@ static int tdfxfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
u8 *mask = (u8 *)cursor->mask;
int i;
- fb_memset(cursorbase, 0, 1024);
+ fb_memset_io(cursorbase, 0, 1024);
for (i = 0; i < cursor->image.height; i++) {
int h = 0;
diff --git a/drivers/video/fbdev/udlfb.c b/drivers/video/fbdev/udlfb.c
index 216d49c9d47e..09cf9381075a 100644
--- a/drivers/video/fbdev/udlfb.c
+++ b/drivers/video/fbdev/udlfb.c
@@ -1006,7 +1006,7 @@ static void dlfb_ops_destroy(struct fb_info *info)
fb_dealloc_cmap(&info->cmap);
if (info->monspecs.modedb)
fb_destroy_modedb(info->monspecs.modedb);
- vfree(info->screen_base);
+ vfree(info->screen_buffer);
fb_destroy_modelist(&info->modelist);
@@ -1120,7 +1120,7 @@ static int dlfb_ops_set_par(struct fb_info *info)
/* paint greenscreen */
- pix_framebuffer = (u16 *) info->screen_base;
+ pix_framebuffer = (u16 *)info->screen_buffer;
for (i = 0; i < info->fix.smem_len / 2; i++)
pix_framebuffer[i] = 0x37e6;
}
@@ -1219,7 +1219,7 @@ static void dlfb_deferred_vfree(struct dlfb_data *dlfb, void *mem)
static int dlfb_realloc_framebuffer(struct dlfb_data *dlfb, struct fb_info *info, u32 new_len)
{
u32 old_len = info->fix.smem_len;
- const void *old_fb = (const void __force *)info->screen_base;
+ const void *old_fb = info->screen_buffer;
unsigned char *new_fb;
unsigned char *new_back = NULL;
@@ -1236,12 +1236,12 @@ static int dlfb_realloc_framebuffer(struct dlfb_data *dlfb, struct fb_info *info
}
memset(new_fb, 0xff, new_len);
- if (info->screen_base) {
+ if (info->screen_buffer) {
memcpy(new_fb, old_fb, old_len);
- dlfb_deferred_vfree(dlfb, (void __force *)info->screen_base);
+ dlfb_deferred_vfree(dlfb, info->screen_buffer);
}
- info->screen_base = (char __iomem *)new_fb;
+ info->screen_buffer = new_fb;
info->fix.smem_len = new_len;
info->fix.smem_start = (unsigned long) new_fb;
info->flags = udlfb_info_flags;
diff --git a/drivers/video/fbdev/valkyriefb.c b/drivers/video/fbdev/valkyriefb.c
index 1007023a5e88..b166b7cfe0e5 100644
--- a/drivers/video/fbdev/valkyriefb.c
+++ b/drivers/video/fbdev/valkyriefb.c
@@ -1,7 +1,7 @@
/*
* valkyriefb.c -- frame buffer device for the PowerMac 'valkyrie' display
*
- * Created 8 August 1998 by
+ * Created 8 August 1998 by
* Martin Costabel <costabel@wanadoo.fr> and Kevin Schoedel
*
* Vmode-switching changes and vmode 15/17 modifications created 29 August
@@ -77,13 +77,13 @@ struct fb_info_valkyrie {
struct fb_par_valkyrie par;
struct cmap_regs __iomem *cmap_regs;
unsigned long cmap_regs_phys;
-
+
struct valkyrie_regs __iomem *valkyrie_regs;
unsigned long valkyrie_regs_phys;
-
+
__u8 __iomem *frame_buffer;
unsigned long frame_buffer_phys;
-
+
int sense;
unsigned long total_vram;
@@ -244,7 +244,7 @@ static inline int valkyrie_vram_reqd(int video_mode, int color_mode)
{
int pitch;
struct valkyrie_regvals *init = valkyrie_reg_init[video_mode-1];
-
+
if ((pitch = init->pitch[color_mode]) == 0)
pitch = 2 * init->pitch[0];
return init->vres * pitch;
@@ -467,7 +467,7 @@ static int valkyrie_var_to_par(struct fb_var_screeninfo *var,
printk(KERN_ERR "valkyriefb: vmode %d not valid.\n", vmode);
return -EINVAL;
}
-
+
if (cmode != CMODE_8 && cmode != CMODE_16) {
printk(KERN_ERR "valkyriefb: cmode %d not valid.\n", cmode);
return -EINVAL;
@@ -516,7 +516,7 @@ static void valkyrie_init_fix(struct fb_fix_screeninfo *fix, struct fb_info_valk
fix->ywrapstep = 0;
fix->ypanstep = 0;
fix->xpanstep = 0;
-
+
}
/* Fix must already be inited above */
diff --git a/drivers/video/fbdev/vfb.c b/drivers/video/fbdev/vfb.c
index a94573997d15..cf3c72754ce7 100644
--- a/drivers/video/fbdev/vfb.c
+++ b/drivers/video/fbdev/vfb.c
@@ -111,7 +111,7 @@ static u_long get_line_length(int xres_virtual, int bpp)
* First part, xxxfb_check_var, must not write anything
* to hardware, it should only verify and adjust var.
* This means it doesn't alter par but it does use hardware
- * data from it to check this var.
+ * data from it to check this var.
*/
static int vfb_check_var(struct fb_var_screeninfo *var,
@@ -169,7 +169,7 @@ static int vfb_check_var(struct fb_var_screeninfo *var,
/*
* Now that we checked it we alter var. The reason being is that the video
- * mode passed in might not work but slight changes to it might make it
+ * mode passed in might not work but slight changes to it might make it
* work. This way we let the user know what is acceptable.
*/
switch (var->bits_per_pixel) {
@@ -235,8 +235,8 @@ static int vfb_check_var(struct fb_var_screeninfo *var,
}
/* This routine actually sets the video mode. It's in here where we
- * the hardware state info->par and fix which can be affected by the
- * change in par. For this driver it doesn't do much.
+ * the hardware state info->par and fix which can be affected by the
+ * change in par. For this driver it doesn't do much.
*/
static int vfb_set_par(struct fb_info *info)
{
@@ -379,7 +379,7 @@ static int vfb_pan_display(struct fb_var_screeninfo *var,
}
/*
- * Most drivers don't need their own mmap function
+ * Most drivers don't need their own mmap function
*/
static int vfb_mmap(struct fb_info *info,
@@ -440,7 +440,7 @@ static int vfb_probe(struct platform_device *dev)
if (!info)
goto err;
- info->screen_base = (char __iomem *)videomemory;
+ info->screen_buffer = videomemory;
info->fbops = &vfb_ops;
if (!fb_find_mode(&info->var, info, mode_option,
diff --git a/drivers/video/fbdev/wmt_ge_rops.c b/drivers/video/fbdev/wmt_ge_rops.c
index 3ed143457d22..b70961901683 100644
--- a/drivers/video/fbdev/wmt_ge_rops.c
+++ b/drivers/video/fbdev/wmt_ge_rops.c
@@ -9,7 +9,9 @@
#include <linux/module.h>
#include <linux/fb.h>
+#include <linux/io.h>
#include <linux/platform_device.h>
+
#include "core/fb_draw.h"
#include "wmt_ge_rops.h"
diff --git a/drivers/video/fbdev/xen-fbfront.c b/drivers/video/fbdev/xen-fbfront.c
index d7f3e6281ce4..9b2a786621a6 100644
--- a/drivers/video/fbdev/xen-fbfront.c
+++ b/drivers/video/fbdev/xen-fbfront.c
@@ -429,7 +429,7 @@ static int xenfb_probe(struct xenbus_device *dev,
fb_info->pseudo_palette = fb_info->par;
fb_info->par = info;
- fb_info->screen_base = info->fb;
+ fb_info->screen_buffer = info->fb;
fb_info->fbops = &xenfb_fb_ops;
fb_info->var.xres_virtual = fb_info->var.xres = video[KPARAM_WIDTH];
diff --git a/drivers/video/console/sticore.c b/drivers/video/sticore.c
index db568f67e4dc..7eb925f2ba9c 100644
--- a/drivers/video/console/sticore.c
+++ b/drivers/video/sticore.c
@@ -6,12 +6,12 @@
* Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
* Copyright (C) 2001-2020 Helge Deller <deller@gmx.de>
* Copyright (C) 2001-2002 Thomas Bogendoerfer <tsbogend@alpha.franken.de>
- *
+ *
* TODO:
* - call STI in virtual mode rather than in real mode
- * - screen blanking with state_mgmt() in text mode STI ?
+ * - screen blanking with state_mgmt() in text mode STI ?
* - try to make it work on m68k hp workstations ;)
- *
+ *
*/
#define pr_fmt(fmt) "%s: " fmt, KBUILD_MODNAME
@@ -30,9 +30,8 @@
#include <asm/pdc.h>
#include <asm/cacheflush.h>
#include <asm/grfioctl.h>
-#include <asm/fb.h>
-#include "../fbdev/sticore.h"
+#include <video/sticore.h>
#define STI_DRIVERVERSION "Version 0.9c"
@@ -66,12 +65,12 @@ static const u8 col_trans[8] = {
#define c_index(sti, c) ((c) & 0xff)
static const struct sti_init_flags default_init_flags = {
- .wait = STI_WAIT,
+ .wait = STI_WAIT,
.reset = 1,
- .text = 1,
+ .text = 1,
.nontext = 1,
- .no_chg_bet = 1,
- .no_chg_bei = 1,
+ .no_chg_bet = 1,
+ .no_chg_bei = 1,
.init_cmap_tx = 1,
};
@@ -104,7 +103,7 @@ static int sti_init_graph(struct sti_struct *sti)
pr_err("STI init_graph failed (ret %d, errno %d)\n", ret, err);
return -1;
}
-
+
return 0;
}
@@ -120,7 +119,7 @@ static void sti_inq_conf(struct sti_struct *sti)
s32 ret;
outptr->ext_ptr = STI_PTR(&sti->sti_data->inq_outptr_ext);
-
+
do {
spin_lock_irqsave(&sti->lock, flags);
memset(inptr, 0, sizeof(*inptr));
@@ -162,9 +161,9 @@ sti_putc(struct sti_struct *sti, int c, int y, int x,
}
static const struct sti_blkmv_flags clear_blkmv_flags = {
- .wait = STI_WAIT,
- .color = 1,
- .clear = 1,
+ .wait = STI_WAIT,
+ .color = 1,
+ .clear = 1,
};
void
@@ -185,7 +184,7 @@ sti_set(struct sti_struct *sti, int src_y, int src_x,
struct sti_blkmv_outptr *outptr = &sti->sti_data->blkmv_outptr;
s32 ret;
unsigned long flags;
-
+
do {
spin_lock_irqsave(&sti->lock, flags);
*inptr = inptr_default;
@@ -224,7 +223,7 @@ sti_clear(struct sti_struct *sti, int src_y, int src_x,
}
static const struct sti_blkmv_flags default_blkmv_flags = {
- .wait = STI_WAIT,
+ .wait = STI_WAIT,
};
void
@@ -291,14 +290,14 @@ static int __init sti_setup(char *str)
{
if (str)
strscpy(default_sti_path, str, sizeof(default_sti_path));
-
+
return 1;
}
/* Assuming the machine has multiple STI consoles (=graphic cards) which
* all get detected by sticon, the user may define with the linux kernel
* parameter sti=<x> which of them will be the initial boot-console.
- * <x> is a number between 0 and MAX_STI_ROMS, with 0 as the default
+ * <x> is a number between 0 and MAX_STI_ROMS, with 0 as the default
* STI screen.
*/
__setup("sti=", sti_setup);
@@ -341,13 +340,13 @@ static int sti_font_setup(char *str)
* should be used by the sticon driver to draw characters to the screen.
* Possible values are:
* - sti_font=<fb_fontname>:
- * <fb_fontname> is the name of one of the linux-kernel built-in
- * framebuffer font names (e.g. VGA8x16, SUN22x18).
- * This is only available if the fonts have been statically compiled
+ * <fb_fontname> is the name of one of the linux-kernel built-in
+ * framebuffer font names (e.g. VGA8x16, SUN22x18).
+ * This is only available if the fonts have been statically compiled
* in with e.g. the CONFIG_FONT_8x16 or CONFIG_FONT_SUN12x22 options.
* - sti_font=<number> (<number> = 1,2,3,...)
* most STI ROMs have built-in HP specific fonts, which can be selected
- * by giving the desired number to the sticon driver.
+ * by giving the desired number to the sticon driver.
* NOTE: This number is machine and STI ROM dependend.
* - sti_font=<height>x<width> (e.g. sti_font=16x8)
* <height> and <width> gives hints to the height and width of the
@@ -359,12 +358,12 @@ __setup("sti_font=", sti_font_setup);
#endif
-
+
static void sti_dump_globcfg(struct sti_glob_cfg *glob_cfg,
unsigned int sti_mem_request)
{
struct sti_glob_cfg_ext *cfg;
-
+
pr_debug("%d text planes\n"
"%4d x %4d screen resolution\n"
"%4d x %4d offscreen\n"
@@ -384,7 +383,7 @@ static void sti_dump_globcfg(struct sti_glob_cfg *glob_cfg,
glob_cfg->reent_lvl,
glob_cfg->save_addr);
- /* dump extended cfg */
+ /* dump extended cfg */
cfg = PTR_STI((unsigned long)glob_cfg->ext_ptr);
pr_debug("monitor %d\n"
"in friendly mode: %d\n"
@@ -437,10 +436,10 @@ static int sti_init_glob_cfg(struct sti_struct *sti, unsigned long rom_address,
glob_cfg->save_addr = STI_PTR(save_addr);
for (i=0; i<8; i++) {
unsigned long newhpa, len;
-
+
if (sti->pd) {
unsigned char offs = sti->rm_entry[i];
-
+
if (offs == 0)
continue;
if (offs != PCI_ROM_ADDRESS &&
@@ -456,18 +455,18 @@ static int sti_init_glob_cfg(struct sti_struct *sti, unsigned long rom_address,
sti->regions_phys[i] =
REGION_OFFSET_TO_PHYS(sti->regions[i], newhpa);
-
+
len = sti->regions[i].region_desc.length * 4096;
if (len)
glob_cfg->region_ptrs[i] = sti->regions_phys[i];
-
+
pr_debug("region #%d: phys %08lx, region_ptr %08x, len=%lukB, "
"btlb=%d, sysonly=%d, cache=%d, last=%d\n",
i, sti->regions_phys[i], glob_cfg->region_ptrs[i],
len/1024,
sti->regions[i].region_desc.btlb,
sti->regions[i].region_desc.sys_only,
- sti->regions[i].region_desc.cache,
+ sti->regions[i].region_desc.cache,
sti->regions[i].region_desc.last);
/* last entry reached ? */
@@ -482,7 +481,7 @@ static int sti_init_glob_cfg(struct sti_struct *sti, unsigned long rom_address,
glob_cfg_ext->sti_mem_addr = STI_PTR(sti_mem_addr);
sti->glob_cfg = glob_cfg;
-
+
return 0;
}
@@ -495,7 +494,7 @@ sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name)
void *dest;
struct sti_rom_font *nf;
struct sti_cooked_font *cooked_font;
-
+
if (fbfont_name && strlen(fbfont_name))
fbfont = find_font(fbfont_name);
if (!fbfont)
@@ -505,8 +504,8 @@ sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name)
pr_info(" using %ux%u framebuffer font %s\n",
fbfont->width, fbfont->height, fbfont->name);
-
- bpc = ((fbfont->width+7)/8) * fbfont->height;
+
+ bpc = ((fbfont->width+7)/8) * fbfont->height;
size = bpc * fbfont->charcount;
size += sizeof(struct sti_rom_font);
@@ -533,7 +532,7 @@ sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name)
kfree(nf);
return NULL;
}
-
+
cooked_font->raw = nf;
cooked_font->raw_ptr = nf;
cooked_font->next_font = NULL;
@@ -617,9 +616,9 @@ static void sti_dump_rom(struct sti_struct *sti)
int nr;
pr_info(" id %04x-%04x, conforms to spec rev. %d.%02x\n",
- rom->graphics_id[0],
+ rom->graphics_id[0],
rom->graphics_id[1],
- rom->revno[0] >> 4,
+ rom->revno[0] >> 4,
rom->revno[0] & 0x0f);
pr_debug(" supports %d monitors\n", rom->num_mons);
pr_debug(" font start %08x\n", rom->font_start);
@@ -647,7 +646,7 @@ static int sti_cook_fonts(struct sti_cooked_rom *cooked_rom,
{
struct sti_rom_font *raw_font, *font_start;
struct sti_cooked_font *cooked_font;
-
+
cooked_font = kzalloc(sizeof(*cooked_font), GFP_KERNEL);
if (!cooked_font)
return 0;
@@ -745,7 +744,7 @@ static struct sti_rom *sti_get_bmode_rom (unsigned long address)
raw_font = ((void *)raw) + raw->font_start;
font_start = raw_font;
-
+
while (raw_font->next_font) {
BMODE_RELOCATE (raw_font->next_font);
raw_font = ((void *)font_start) + raw_font->next_font;
@@ -759,7 +758,7 @@ static struct sti_rom *sti_get_wmode_rom(unsigned long address)
struct sti_rom *raw;
unsigned long size;
- /* read the ROM size directly from the struct in ROM */
+ /* read the ROM size directly from the struct in ROM */
size = gsc_readl(address + offsetof(struct sti_rom,last_addr));
raw = kmalloc(size, STI_LOWMEM);
@@ -869,7 +868,7 @@ static struct sti_struct *sti_try_rom_generic(unsigned long address,
pr_warn("maximum number of STI ROMS reached !\n");
return NULL;
}
-
+
sti = kzalloc(sizeof(*sti), GFP_KERNEL);
if (!sti)
return NULL;
@@ -890,19 +889,19 @@ test_rom:
u32 *rm;
i = gsc_readl(address+0x04);
if (i != 1) {
- /* The ROM could have multiple architecture
+ /* The ROM could have multiple architecture
* dependent images (e.g. i386, parisc,...) */
pr_warn("PCI ROM is not a STI ROM type image (0x%8x)\n", i);
goto out_err;
}
-
+
sti->pd = pd;
i = gsc_readl(address+0x0c);
pr_debug("PCI ROM size (from header) = %d kB\n",
le16_to_cpu(i>>16)*512/1024);
rm_offset = le16_to_cpu(i & 0xffff);
- if (rm_offset) {
+ if (rm_offset) {
/* read 16 bytes from the pci region mapper array */
rm = (u32*) &sti->rm_entry;
*rm++ = gsc_readl(address+rm_offset+0x00);
@@ -915,9 +914,9 @@ test_rom:
pr_debug("sig %04x, PCI STI ROM at %08lx\n", sig, address);
goto test_rom;
}
-
+
ok = 0;
-
+
if ((sig & 0xff) == 0x01) {
pr_debug(" byte mode ROM at %08lx, hpa at %08lx\n",
address, hpa);
@@ -941,7 +940,7 @@ test_rom:
*/
if (sti->pd) {
unsigned long rom_base;
- rom_base = pci_resource_start(sti->pd, PCI_ROM_RESOURCE);
+ rom_base = pci_resource_start(sti->pd, PCI_ROM_RESOURCE);
pci_write_config_dword(sti->pd, PCI_ROM_ADDRESS, rom_base & ~PCI_ROM_ADDRESS_ENABLE);
pr_debug("STI PCI ROM disabled\n");
}
@@ -952,13 +951,13 @@ test_rom:
sti_inq_conf(sti);
sti_dump_globcfg(sti->glob_cfg, sti->sti_mem_request);
sti_dump_outptr(sti);
-
+
pr_info(" graphics card name: %s\n",
sti->sti_data->inq_outptr.dev_name);
sti_roms[num_sti_roms] = sti;
num_sti_roms++;
-
+
return sti;
out_err:
@@ -974,9 +973,9 @@ static void sticore_check_for_default_sti(struct sti_struct *sti, char *path)
}
/*
- * on newer systems PDC gives the address of the ROM
+ * on newer systems PDC gives the address of the ROM
* in the additional address field addr[1] while on
- * older Systems the PDC stores it in page0->proc_sti
+ * older Systems the PDC stores it in page0->proc_sti
*/
static int __init sticore_pa_init(struct parisc_device *dev)
{
@@ -1005,7 +1004,7 @@ static int sticore_pci_init(struct pci_dev *pd, const struct pci_device_id *ent)
unsigned int fb_len, rom_len;
int err;
struct sti_struct *sti;
-
+
err = pci_enable_device(pd);
if (err < 0) {
dev_err(&pd->dev, "Cannot enable PCI device\n");
@@ -1032,7 +1031,7 @@ static int sticore_pci_init(struct pci_dev *pd, const struct pci_device_id *ent)
print_pci_hwpath(pd, sti->pa_path);
sticore_check_for_default_sti(sti, sti->pa_path);
}
-
+
if (!sti) {
pr_warn("Unable to handle STI device '%s'\n", pci_name(pd));
return -ENODEV;
@@ -1148,24 +1147,6 @@ int sti_call(const struct sti_struct *sti, unsigned long func,
return ret;
}
-#if defined(CONFIG_FB_STI)
-/* check if given fb_info is the primary device */
-int fb_is_primary_device(struct fb_info *info)
-{
- struct sti_struct *sti;
-
- sti = sti_get_rom(0);
-
- /* if no built-in graphics card found, allow any fb driver as default */
- if (!sti)
- return true;
-
- /* return true if it's the default built-in framebuffer driver */
- return (sti->info == info);
-}
-EXPORT_SYMBOL(fb_is_primary_device);
-#endif
-
MODULE_AUTHOR("Philipp Rumpf, Helge Deller, Thomas Bogendoerfer");
MODULE_DESCRIPTION("Core STI driver for HP's NGLE series graphics cards in HP PARISC machines");
MODULE_LICENSE("GPL v2");
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
index e54f0884802a..79336fa853db 100644
--- a/fs/btrfs/backref.c
+++ b/fs/btrfs/backref.c
@@ -45,7 +45,8 @@ static int check_extent_in_eb(struct btrfs_backref_walk_ctx *ctx,
int root_count;
bool cached;
- if (!btrfs_file_extent_compression(eb, fi) &&
+ if (!ctx->ignore_extent_item_pos &&
+ !btrfs_file_extent_compression(eb, fi) &&
!btrfs_file_extent_encryption(eb, fi) &&
!btrfs_file_extent_other_encoding(eb, fi)) {
u64 data_offset;
@@ -552,7 +553,7 @@ static int add_all_parents(struct btrfs_backref_walk_ctx *ctx,
count++;
else
goto next;
- if (!ctx->ignore_extent_item_pos) {
+ if (!ctx->skip_inode_ref_list) {
ret = check_extent_in_eb(ctx, &key, eb, fi, &eie);
if (ret == BTRFS_ITERATE_EXTENT_INODES_STOP ||
ret < 0)
@@ -564,7 +565,7 @@ static int add_all_parents(struct btrfs_backref_walk_ctx *ctx,
eie, (void **)&old, GFP_NOFS);
if (ret < 0)
break;
- if (!ret && !ctx->ignore_extent_item_pos) {
+ if (!ret && !ctx->skip_inode_ref_list) {
while (old->next)
old = old->next;
old->next = eie;
@@ -1606,7 +1607,7 @@ again:
goto out;
}
if (ref->count && ref->parent) {
- if (!ctx->ignore_extent_item_pos && !ref->inode_list &&
+ if (!ctx->skip_inode_ref_list && !ref->inode_list &&
ref->level == 0) {
struct btrfs_tree_parent_check check = { 0 };
struct extent_buffer *eb;
@@ -1647,7 +1648,7 @@ again:
(void **)&eie, GFP_NOFS);
if (ret < 0)
goto out;
- if (!ret && !ctx->ignore_extent_item_pos) {
+ if (!ret && !ctx->skip_inode_ref_list) {
/*
* We've recorded that parent, so we must extend
* its inode list here.
@@ -1743,7 +1744,7 @@ int btrfs_find_all_leafs(struct btrfs_backref_walk_ctx *ctx)
static int btrfs_find_all_roots_safe(struct btrfs_backref_walk_ctx *ctx)
{
const u64 orig_bytenr = ctx->bytenr;
- const bool orig_ignore_extent_item_pos = ctx->ignore_extent_item_pos;
+ const bool orig_skip_inode_ref_list = ctx->skip_inode_ref_list;
bool roots_ulist_allocated = false;
struct ulist_iterator uiter;
int ret = 0;
@@ -1764,7 +1765,7 @@ static int btrfs_find_all_roots_safe(struct btrfs_backref_walk_ctx *ctx)
roots_ulist_allocated = true;
}
- ctx->ignore_extent_item_pos = true;
+ ctx->skip_inode_ref_list = true;
ULIST_ITER_INIT(&uiter);
while (1) {
@@ -1789,7 +1790,7 @@ static int btrfs_find_all_roots_safe(struct btrfs_backref_walk_ctx *ctx)
ulist_free(ctx->refs);
ctx->refs = NULL;
ctx->bytenr = orig_bytenr;
- ctx->ignore_extent_item_pos = orig_ignore_extent_item_pos;
+ ctx->skip_inode_ref_list = orig_skip_inode_ref_list;
return ret;
}
@@ -1912,7 +1913,7 @@ int btrfs_is_data_extent_shared(struct btrfs_inode *inode, u64 bytenr,
goto out_trans;
}
- walk_ctx.ignore_extent_item_pos = true;
+ walk_ctx.skip_inode_ref_list = true;
walk_ctx.trans = trans;
walk_ctx.fs_info = fs_info;
walk_ctx.refs = &ctx->refs;
diff --git a/fs/btrfs/backref.h b/fs/btrfs/backref.h
index ef6bbea3f456..1616e3e3f1e4 100644
--- a/fs/btrfs/backref.h
+++ b/fs/btrfs/backref.h
@@ -60,6 +60,12 @@ struct btrfs_backref_walk_ctx {
* @extent_item_pos is ignored.
*/
bool ignore_extent_item_pos;
+ /*
+ * If true and bytenr corresponds to a data extent, then the inode list
+ * (each member describing inode number, file offset and root) is not
+ * added to each reference added to the @refs ulist.
+ */
+ bool skip_inode_ref_list;
/* A valid transaction handle or NULL. */
struct btrfs_trans_handle *trans;
/*
diff --git a/fs/btrfs/block-rsv.c b/fs/btrfs/block-rsv.c
index 3ab707e26fa2..ac18c43fadad 100644
--- a/fs/btrfs/block-rsv.c
+++ b/fs/btrfs/block-rsv.c
@@ -124,7 +124,8 @@ static u64 block_rsv_release_bytes(struct btrfs_fs_info *fs_info,
} else {
num_bytes = 0;
}
- if (block_rsv->qgroup_rsv_reserved >= block_rsv->qgroup_rsv_size) {
+ if (qgroup_to_release_ret &&
+ block_rsv->qgroup_rsv_reserved >= block_rsv->qgroup_rsv_size) {
qgroup_to_release = block_rsv->qgroup_rsv_reserved -
block_rsv->qgroup_rsv_size;
block_rsv->qgroup_rsv_reserved = block_rsv->qgroup_rsv_size;
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 3c983c70028a..2ff2961b1183 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -2627,6 +2627,10 @@ static bool check_sibling_keys(struct extent_buffer *left,
}
if (btrfs_comp_cpu_keys(&left_last, &right_first) >= 0) {
+ btrfs_crit(left->fs_info, "left extent buffer:");
+ btrfs_print_tree(left, false);
+ btrfs_crit(left->fs_info, "right extent buffer:");
+ btrfs_print_tree(right, false);
btrfs_crit(left->fs_info,
"bad key order, sibling blocks, left last (%llu %u %llu) right first (%llu %u %llu)",
left_last.objectid, left_last.type,
@@ -3215,6 +3219,7 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
if (check_sibling_keys(left, right)) {
ret = -EUCLEAN;
+ btrfs_abort_transaction(trans, ret);
btrfs_tree_unlock(right);
free_extent_buffer(right);
return ret;
@@ -3433,6 +3438,7 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
if (check_sibling_keys(left, right)) {
ret = -EUCLEAN;
+ btrfs_abort_transaction(trans, ret);
goto out;
}
return __push_leaf_left(trans, path, min_data_size, empty, left,
@@ -4478,10 +4484,12 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root,
int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path)
{
struct btrfs_key key;
+ struct btrfs_key orig_key;
struct btrfs_disk_key found_key;
int ret;
btrfs_item_key_to_cpu(path->nodes[0], &key, 0);
+ orig_key = key;
if (key.offset > 0) {
key.offset--;
@@ -4498,8 +4506,36 @@ int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path)
btrfs_release_path(path);
ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
- if (ret < 0)
+ if (ret <= 0)
return ret;
+
+ /*
+ * Previous key not found. Even if we were at slot 0 of the leaf we had
+ * before releasing the path and calling btrfs_search_slot(), we now may
+ * be in a slot pointing to the same original key - this can happen if
+ * after we released the path, one of more items were moved from a
+ * sibling leaf into the front of the leaf we had due to an insertion
+ * (see push_leaf_right()).
+ * If we hit this case and our slot is > 0 and just decrement the slot
+ * so that the caller does not process the same key again, which may or
+ * may not break the caller, depending on its logic.
+ */
+ if (path->slots[0] < btrfs_header_nritems(path->nodes[0])) {
+ btrfs_item_key(path->nodes[0], &found_key, path->slots[0]);
+ ret = comp_keys(&found_key, &orig_key);
+ if (ret == 0) {
+ if (path->slots[0] > 0) {
+ path->slots[0]--;
+ return 0;
+ }
+ /*
+ * At slot 0, same key as before, it means orig_key is
+ * the lowest, leftmost, key in the tree. We're done.
+ */
+ return 1;
+ }
+ }
+
btrfs_item_key(path->nodes[0], &found_key, 0);
ret = comp_keys(&found_key, &key);
/*
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 59ea049fe7ee..fbf9006c6234 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -3121,23 +3121,34 @@ int btrfs_start_pre_rw_mount(struct btrfs_fs_info *fs_info)
{
int ret;
const bool cache_opt = btrfs_test_opt(fs_info, SPACE_CACHE);
- bool clear_free_space_tree = false;
+ bool rebuild_free_space_tree = false;
if (btrfs_test_opt(fs_info, CLEAR_CACHE) &&
btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE)) {
- clear_free_space_tree = true;
+ rebuild_free_space_tree = true;
} else if (btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE) &&
!btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE_VALID)) {
btrfs_warn(fs_info, "free space tree is invalid");
- clear_free_space_tree = true;
+ rebuild_free_space_tree = true;
}
- if (clear_free_space_tree) {
- btrfs_info(fs_info, "clearing free space tree");
- ret = btrfs_clear_free_space_tree(fs_info);
+ if (rebuild_free_space_tree) {
+ btrfs_info(fs_info, "rebuilding free space tree");
+ ret = btrfs_rebuild_free_space_tree(fs_info);
if (ret) {
btrfs_warn(fs_info,
- "failed to clear free space tree: %d", ret);
+ "failed to rebuild free space tree: %d", ret);
+ goto out;
+ }
+ }
+
+ if (btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE) &&
+ !btrfs_test_opt(fs_info, FREE_SPACE_TREE)) {
+ btrfs_info(fs_info, "disabling free space tree");
+ ret = btrfs_delete_free_space_tree(fs_info);
+ if (ret) {
+ btrfs_warn(fs_info,
+ "failed to disable free space tree: %d", ret);
goto out;
}
}
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c
index 018c711a0bc8..cd4cce9ba443 100644
--- a/fs/btrfs/file-item.c
+++ b/fs/btrfs/file-item.c
@@ -52,13 +52,13 @@ void btrfs_inode_safe_disk_i_size_write(struct btrfs_inode *inode, u64 new_i_siz
u64 start, end, i_size;
int ret;
+ spin_lock(&inode->lock);
i_size = new_i_size ?: i_size_read(&inode->vfs_inode);
if (btrfs_fs_incompat(fs_info, NO_HOLES)) {
inode->disk_i_size = i_size;
- return;
+ goto out_unlock;
}
- spin_lock(&inode->lock);
ret = find_contiguous_extent_bit(&inode->file_extent_tree, 0, &start,
&end, EXTENT_DIRTY);
if (!ret && start == 0)
@@ -66,6 +66,7 @@ void btrfs_inode_safe_disk_i_size_write(struct btrfs_inode *inode, u64 new_i_siz
else
i_size = 0;
inode->disk_i_size = i_size;
+out_unlock:
spin_unlock(&inode->lock);
}
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
index d84cef89cdff..cf98a3c05480 100644
--- a/fs/btrfs/free-space-cache.c
+++ b/fs/btrfs/free-space-cache.c
@@ -870,15 +870,16 @@ static int __load_free_space_cache(struct btrfs_root *root, struct inode *inode,
}
spin_lock(&ctl->tree_lock);
ret = link_free_space(ctl, e);
- ctl->total_bitmaps++;
- recalculate_thresholds(ctl);
- spin_unlock(&ctl->tree_lock);
if (ret) {
+ spin_unlock(&ctl->tree_lock);
btrfs_err(fs_info,
"Duplicate entries in free space cache, dumping");
kmem_cache_free(btrfs_free_space_cachep, e);
goto free_cache;
}
+ ctl->total_bitmaps++;
+ recalculate_thresholds(ctl);
+ spin_unlock(&ctl->tree_lock);
list_add_tail(&e->list, &bitmaps);
}
diff --git a/fs/btrfs/free-space-tree.c b/fs/btrfs/free-space-tree.c
index 4d155a48ec59..b21da1446f2a 100644
--- a/fs/btrfs/free-space-tree.c
+++ b/fs/btrfs/free-space-tree.c
@@ -1252,7 +1252,7 @@ out:
return ret;
}
-int btrfs_clear_free_space_tree(struct btrfs_fs_info *fs_info)
+int btrfs_delete_free_space_tree(struct btrfs_fs_info *fs_info)
{
struct btrfs_trans_handle *trans;
struct btrfs_root *tree_root = fs_info->tree_root;
@@ -1298,6 +1298,54 @@ abort:
return ret;
}
+int btrfs_rebuild_free_space_tree(struct btrfs_fs_info *fs_info)
+{
+ struct btrfs_trans_handle *trans;
+ struct btrfs_key key = {
+ .objectid = BTRFS_FREE_SPACE_TREE_OBJECTID,
+ .type = BTRFS_ROOT_ITEM_KEY,
+ .offset = 0,
+ };
+ struct btrfs_root *free_space_root = btrfs_global_root(fs_info, &key);
+ struct rb_node *node;
+ int ret;
+
+ trans = btrfs_start_transaction(free_space_root, 1);
+ if (IS_ERR(trans))
+ return PTR_ERR(trans);
+
+ set_bit(BTRFS_FS_CREATING_FREE_SPACE_TREE, &fs_info->flags);
+ set_bit(BTRFS_FS_FREE_SPACE_TREE_UNTRUSTED, &fs_info->flags);
+
+ ret = clear_free_space_tree(trans, free_space_root);
+ if (ret)
+ goto abort;
+
+ node = rb_first_cached(&fs_info->block_group_cache_tree);
+ while (node) {
+ struct btrfs_block_group *block_group;
+
+ block_group = rb_entry(node, struct btrfs_block_group,
+ cache_node);
+ ret = populate_free_space_tree(trans, block_group);
+ if (ret)
+ goto abort;
+ node = rb_next(node);
+ }
+
+ btrfs_set_fs_compat_ro(fs_info, FREE_SPACE_TREE);
+ btrfs_set_fs_compat_ro(fs_info, FREE_SPACE_TREE_VALID);
+ clear_bit(BTRFS_FS_CREATING_FREE_SPACE_TREE, &fs_info->flags);
+
+ ret = btrfs_commit_transaction(trans);
+ clear_bit(BTRFS_FS_FREE_SPACE_TREE_UNTRUSTED, &fs_info->flags);
+ return ret;
+abort:
+ btrfs_abort_transaction(trans, ret);
+ btrfs_end_transaction(trans);
+ return ret;
+}
+
static int __add_block_group_free_space(struct btrfs_trans_handle *trans,
struct btrfs_block_group *block_group,
struct btrfs_path *path)
diff --git a/fs/btrfs/free-space-tree.h b/fs/btrfs/free-space-tree.h
index dc2463e4cfe3..6d5551d0ced8 100644
--- a/fs/btrfs/free-space-tree.h
+++ b/fs/btrfs/free-space-tree.h
@@ -18,7 +18,8 @@ struct btrfs_caching_control;
void set_free_space_tree_thresholds(struct btrfs_block_group *block_group);
int btrfs_create_free_space_tree(struct btrfs_fs_info *fs_info);
-int btrfs_clear_free_space_tree(struct btrfs_fs_info *fs_info);
+int btrfs_delete_free_space_tree(struct btrfs_fs_info *fs_info);
+int btrfs_rebuild_free_space_tree(struct btrfs_fs_info *fs_info);
int load_free_space_tree(struct btrfs_caching_control *caching_ctl);
int add_block_group_free_space(struct btrfs_trans_handle *trans,
struct btrfs_block_group *block_group);
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 57d070025c7a..19c707bc8801 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -3108,6 +3108,9 @@ int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent)
btrfs_rewrite_logical_zoned(ordered_extent);
btrfs_zone_finish_endio(fs_info, ordered_extent->disk_bytenr,
ordered_extent->disk_num_bytes);
+ } else if (btrfs_is_data_reloc_root(inode->root)) {
+ btrfs_zone_finish_endio(fs_info, ordered_extent->disk_bytenr,
+ ordered_extent->disk_num_bytes);
}
if (test_bit(BTRFS_ORDERED_TRUNCATED, &ordered_extent->flags)) {
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 25833b4eeaf5..2fa36f694daa 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -454,7 +454,9 @@ void btrfs_exclop_balance(struct btrfs_fs_info *fs_info,
case BTRFS_EXCLOP_BALANCE_PAUSED:
spin_lock(&fs_info->super_lock);
ASSERT(fs_info->exclusive_operation == BTRFS_EXCLOP_BALANCE ||
- fs_info->exclusive_operation == BTRFS_EXCLOP_DEV_ADD);
+ fs_info->exclusive_operation == BTRFS_EXCLOP_DEV_ADD ||
+ fs_info->exclusive_operation == BTRFS_EXCLOP_NONE ||
+ fs_info->exclusive_operation == BTRFS_EXCLOP_BALANCE_PAUSED);
fs_info->exclusive_operation = BTRFS_EXCLOP_BALANCE_PAUSED;
spin_unlock(&fs_info->super_lock);
break;
diff --git a/fs/btrfs/print-tree.c b/fs/btrfs/print-tree.c
index b93c96213304..497b9dbd8a13 100644
--- a/fs/btrfs/print-tree.c
+++ b/fs/btrfs/print-tree.c
@@ -151,10 +151,10 @@ static void print_extent_item(struct extent_buffer *eb, int slot, int type)
pr_cont("shared data backref parent %llu count %u\n",
offset, btrfs_shared_data_ref_count(eb, sref));
/*
- * offset is supposed to be a tree block which
- * must be aligned to nodesize.
+ * Offset is supposed to be a tree block which must be
+ * aligned to sectorsize.
*/
- if (!IS_ALIGNED(offset, eb->fs_info->nodesize))
+ if (!IS_ALIGNED(offset, eb->fs_info->sectorsize))
pr_info(
"\t\t\t(parent %llu not aligned to sectorsize %u)\n",
offset, eb->fs_info->sectorsize);
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 09b1988d1791..59a06499c647 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -3422,7 +3422,7 @@ int add_data_references(struct reloc_control *rc,
btrfs_release_path(path);
ctx.bytenr = extent_key->objectid;
- ctx.ignore_extent_item_pos = true;
+ ctx.skip_inode_ref_list = true;
ctx.fs_info = rc->extent_root->fs_info;
ret = btrfs_find_all_leafs(&ctx);
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 6cb97efee976..ec18e2210602 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -826,7 +826,11 @@ out:
!btrfs_test_opt(info, CLEAR_CACHE)) {
btrfs_err(info, "cannot disable free space tree");
ret = -EINVAL;
-
+ }
+ if (btrfs_fs_compat_ro(info, BLOCK_GROUP_TREE) &&
+ !btrfs_test_opt(info, FREE_SPACE_TREE)) {
+ btrfs_err(info, "cannot disable free space tree with block-group-tree feature");
+ ret = -EINVAL;
}
if (!ret)
ret = btrfs_check_mountopts_zoned(info);
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 03f52e4a20aa..841e799dece5 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -395,6 +395,7 @@ void btrfs_free_device(struct btrfs_device *device)
{
WARN_ON(!list_empty(&device->post_commit_list));
rcu_string_free(device->name);
+ extent_io_tree_release(&device->alloc_state);
btrfs_destroy_dev_zone_info(device);
kfree(device);
}
diff --git a/fs/btrfs/zoned.c b/fs/btrfs/zoned.c
index a9b32ba6b2ce..39828af4a4e8 100644
--- a/fs/btrfs/zoned.c
+++ b/fs/btrfs/zoned.c
@@ -122,10 +122,9 @@ static int sb_write_pointer(struct block_device *bdev, struct blk_zone *zones,
int i;
for (i = 0; i < BTRFS_NR_SB_LOG_ZONES; i++) {
- u64 bytenr;
-
- bytenr = ((zones[i].start + zones[i].len)
- << SECTOR_SHIFT) - BTRFS_SUPER_INFO_SIZE;
+ u64 zone_end = (zones[i].start + zones[i].capacity) << SECTOR_SHIFT;
+ u64 bytenr = ALIGN_DOWN(zone_end, BTRFS_SUPER_INFO_SIZE) -
+ BTRFS_SUPER_INFO_SIZE;
page[i] = read_cache_page_gfp(mapping,
bytenr >> PAGE_SHIFT, GFP_NOFS);
@@ -1168,12 +1167,12 @@ int btrfs_ensure_empty_zones(struct btrfs_device *device, u64 start, u64 size)
return -ERANGE;
/* All the zones are conventional */
- if (find_next_bit(zinfo->seq_zones, begin, end) == end)
+ if (find_next_bit(zinfo->seq_zones, end, begin) == end)
return 0;
/* All the zones are sequential and empty */
- if (find_next_zero_bit(zinfo->seq_zones, begin, end) == end &&
- find_next_zero_bit(zinfo->empty_zones, begin, end) == end)
+ if (find_next_zero_bit(zinfo->seq_zones, end, begin) == end &&
+ find_next_zero_bit(zinfo->empty_zones, end, begin) == end)
return 0;
for (pos = start; pos < start + size; pos += zinfo->zone_size) {
@@ -1610,11 +1609,11 @@ void btrfs_redirty_list_add(struct btrfs_transaction *trans,
!list_empty(&eb->release_list))
return;
+ memzero_extent_buffer(eb, 0, eb->len);
+ set_bit(EXTENT_BUFFER_NO_CHECK, &eb->bflags);
set_extent_buffer_dirty(eb);
set_extent_bits_nowait(&trans->dirty_pages, eb->start,
eb->start + eb->len - 1, EXTENT_DIRTY);
- memzero_extent_buffer(eb, 0, eb->len);
- set_bit(EXTENT_BUFFER_NO_CHECK, &eb->bflags);
spin_lock(&trans->releasing_ebs_lock);
list_add_tail(&eb->release_list, &trans->releasing_ebs);
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 32f7c81a7b89..43a4d8603db3 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -246,7 +246,7 @@ cifs_read_super(struct super_block *sb)
if (cifs_sb->ctx->rasize)
sb->s_bdi->ra_pages = cifs_sb->ctx->rasize / PAGE_SIZE;
else
- sb->s_bdi->ra_pages = cifs_sb->ctx->rsize / PAGE_SIZE;
+ sb->s_bdi->ra_pages = 2 * (cifs_sb->ctx->rsize / PAGE_SIZE);
sb->s_blocksize = CIFS_MAX_MSGSIZE;
sb->s_blocksize_bits = 14; /* default 2**14 = CIFS_MAX_MSGSIZE */
@@ -744,6 +744,7 @@ static void cifs_umount_begin(struct super_block *sb)
spin_unlock(&tcon->tc_lock);
spin_unlock(&cifs_tcp_ses_lock);
+ cifs_close_all_deferred_files(tcon);
/* cancel_brl_requests(tcon); */ /* BB mark all brl mids as exiting */
/* cancel_notify_requests(tcon); */
if (tcon->ses && tcon->ses->server) {
@@ -759,6 +760,20 @@ static void cifs_umount_begin(struct super_block *sb)
return;
}
+static int cifs_freeze(struct super_block *sb)
+{
+ struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
+ struct cifs_tcon *tcon;
+
+ if (cifs_sb == NULL)
+ return 0;
+
+ tcon = cifs_sb_master_tcon(cifs_sb);
+
+ cifs_close_all_deferred_files(tcon);
+ return 0;
+}
+
#ifdef CONFIG_CIFS_STATS2
static int cifs_show_stats(struct seq_file *s, struct dentry *root)
{
@@ -797,6 +812,7 @@ static const struct super_operations cifs_super_ops = {
as opens */
.show_options = cifs_show_options,
.umount_begin = cifs_umount_begin,
+ .freeze_fs = cifs_freeze,
#ifdef CONFIG_CIFS_STATS2
.show_stats = cifs_show_stats,
#endif
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index eeeed6fda13b..8e9a672320ab 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -2709,6 +2709,13 @@ cifs_match_super(struct super_block *sb, void *data)
spin_lock(&cifs_tcp_ses_lock);
cifs_sb = CIFS_SB(sb);
+
+ /* We do not want to use a superblock that has been shutdown */
+ if (CIFS_MOUNT_SHUTDOWN & cifs_sb->mnt_cifs_flags) {
+ spin_unlock(&cifs_tcp_ses_lock);
+ return 0;
+ }
+
tlink = cifs_get_tlink(cifs_sb_master_tlink(cifs_sb));
if (tlink == NULL) {
/* can not match superblock if tlink were ever null */
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index a81758225fcd..a295e4c2d54e 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -1682,7 +1682,7 @@ smb2_copychunk_range(const unsigned int xid,
pcchunk->SourceOffset = cpu_to_le64(src_off);
pcchunk->TargetOffset = cpu_to_le64(dest_off);
pcchunk->Length =
- cpu_to_le32(min_t(u32, len, tcon->max_bytes_chunk));
+ cpu_to_le32(min_t(u64, len, tcon->max_bytes_chunk));
/* Request server copy to target from src identified by key */
kfree(retbuf);
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index e33ca0d33906..9ed61b6f9b21 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -1947,6 +1947,9 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree,
init_copy_chunk_defaults(tcon);
if (server->ops->validate_negotiate)
rc = server->ops->validate_negotiate(xid, tcon);
+ if (rc == 0) /* See MS-SMB2 2.2.10 and 3.2.5.5 */
+ if (tcon->share_flags & SMB2_SHAREFLAG_ISOLATED_TRANSPORT)
+ server->nosharesock = true;
tcon_exit:
free_rsp_buf(resp_buftype, rsp);
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
index 094269488183..c1edde817be8 100644
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
@@ -305,6 +305,38 @@ struct ext4_group_desc * ext4_get_group_desc(struct super_block *sb,
return desc;
}
+static ext4_fsblk_t ext4_valid_block_bitmap_padding(struct super_block *sb,
+ ext4_group_t block_group,
+ struct buffer_head *bh)
+{
+ ext4_grpblk_t next_zero_bit;
+ unsigned long bitmap_size = sb->s_blocksize * 8;
+ unsigned int offset = num_clusters_in_group(sb, block_group);
+
+ if (bitmap_size <= offset)
+ return 0;
+
+ next_zero_bit = ext4_find_next_zero_bit(bh->b_data, bitmap_size, offset);
+
+ return (next_zero_bit < bitmap_size ? next_zero_bit : 0);
+}
+
+struct ext4_group_info *ext4_get_group_info(struct super_block *sb,
+ ext4_group_t group)
+{
+ struct ext4_group_info **grp_info;
+ long indexv, indexh;
+
+ if (unlikely(group >= EXT4_SB(sb)->s_groups_count)) {
+ ext4_error(sb, "invalid group %u", group);
+ return NULL;
+ }
+ indexv = group >> (EXT4_DESC_PER_BLOCK_BITS(sb));
+ indexh = group & ((EXT4_DESC_PER_BLOCK(sb)) - 1);
+ grp_info = sbi_array_rcu_deref(EXT4_SB(sb), s_group_info, indexv);
+ return grp_info[indexh];
+}
+
/*
* Return the block number which was discovered to be invalid, or 0 if
* the block bitmap is valid.
@@ -379,7 +411,7 @@ static int ext4_validate_block_bitmap(struct super_block *sb,
if (buffer_verified(bh))
return 0;
- if (EXT4_MB_GRP_BBITMAP_CORRUPT(grp))
+ if (!grp || EXT4_MB_GRP_BBITMAP_CORRUPT(grp))
return -EFSCORRUPTED;
ext4_lock_group(sb, block_group);
@@ -402,6 +434,15 @@ static int ext4_validate_block_bitmap(struct super_block *sb,
EXT4_GROUP_INFO_BBITMAP_CORRUPT);
return -EFSCORRUPTED;
}
+ blk = ext4_valid_block_bitmap_padding(sb, block_group, bh);
+ if (unlikely(blk != 0)) {
+ ext4_unlock_group(sb, block_group);
+ ext4_error(sb, "bg %u: block %llu: padding at end of block bitmap is not set",
+ block_group, blk);
+ ext4_mark_group_bitmap_corrupted(sb, block_group,
+ EXT4_GROUP_INFO_BBITMAP_CORRUPT);
+ return -EFSCORRUPTED;
+ }
set_buffer_verified(bh);
verified:
ext4_unlock_group(sb, block_group);
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 18cb2680dc39..6948d673bba2 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1684,6 +1684,30 @@ static inline struct ext4_inode_info *EXT4_I(struct inode *inode)
return container_of(inode, struct ext4_inode_info, vfs_inode);
}
+static inline int ext4_writepages_down_read(struct super_block *sb)
+{
+ percpu_down_read(&EXT4_SB(sb)->s_writepages_rwsem);
+ return memalloc_nofs_save();
+}
+
+static inline void ext4_writepages_up_read(struct super_block *sb, int ctx)
+{
+ memalloc_nofs_restore(ctx);
+ percpu_up_read(&EXT4_SB(sb)->s_writepages_rwsem);
+}
+
+static inline int ext4_writepages_down_write(struct super_block *sb)
+{
+ percpu_down_write(&EXT4_SB(sb)->s_writepages_rwsem);
+ return memalloc_nofs_save();
+}
+
+static inline void ext4_writepages_up_write(struct super_block *sb, int ctx)
+{
+ memalloc_nofs_restore(ctx);
+ percpu_up_write(&EXT4_SB(sb)->s_writepages_rwsem);
+}
+
static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino)
{
return ino == EXT4_ROOT_INO ||
@@ -2625,6 +2649,8 @@ extern void ext4_check_blocks_bitmap(struct super_block *);
extern struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb,
ext4_group_t block_group,
struct buffer_head ** bh);
+extern struct ext4_group_info *ext4_get_group_info(struct super_block *sb,
+ ext4_group_t group);
extern int ext4_should_retry_alloc(struct super_block *sb, int *retries);
extern struct buffer_head *ext4_read_block_bitmap_nowait(struct super_block *sb,
@@ -3232,19 +3258,6 @@ static inline void ext4_isize_set(struct ext4_inode *raw_inode, loff_t i_size)
raw_inode->i_size_high = cpu_to_le32(i_size >> 32);
}
-static inline
-struct ext4_group_info *ext4_get_group_info(struct super_block *sb,
- ext4_group_t group)
-{
- struct ext4_group_info **grp_info;
- long indexv, indexh;
- BUG_ON(group >= EXT4_SB(sb)->s_groups_count);
- indexv = group >> (EXT4_DESC_PER_BLOCK_BITS(sb));
- indexh = group & ((EXT4_DESC_PER_BLOCK(sb)) - 1);
- grp_info = sbi_array_rcu_deref(EXT4_SB(sb), s_group_info, indexv);
- return grp_info[indexh];
-}
-
/*
* Reading s_groups_count requires using smp_rmb() afterwards. See
* the locking protocol documented in the comments of ext4_group_add()
diff --git a/fs/ext4/extents_status.c b/fs/ext4/extents_status.c
index 7bc221038c6c..595abb9e7d74 100644
--- a/fs/ext4/extents_status.c
+++ b/fs/ext4/extents_status.c
@@ -267,14 +267,12 @@ static void __es_find_extent_range(struct inode *inode,
/* see if the extent has been cached */
es->es_lblk = es->es_len = es->es_pblk = 0;
- if (tree->cache_es) {
- es1 = tree->cache_es;
- if (in_range(lblk, es1->es_lblk, es1->es_len)) {
- es_debug("%u cached by [%u/%u) %llu %x\n",
- lblk, es1->es_lblk, es1->es_len,
- ext4_es_pblock(es1), ext4_es_status(es1));
- goto out;
- }
+ es1 = READ_ONCE(tree->cache_es);
+ if (es1 && in_range(lblk, es1->es_lblk, es1->es_len)) {
+ es_debug("%u cached by [%u/%u) %llu %x\n",
+ lblk, es1->es_lblk, es1->es_len,
+ ext4_es_pblock(es1), ext4_es_status(es1));
+ goto out;
}
es1 = __es_tree_search(&tree->root, lblk);
@@ -293,7 +291,7 @@ out:
}
if (es1 && matching_fn(es1)) {
- tree->cache_es = es1;
+ WRITE_ONCE(tree->cache_es, es1);
es->es_lblk = es1->es_lblk;
es->es_len = es1->es_len;
es->es_pblk = es1->es_pblk;
@@ -931,14 +929,12 @@ int ext4_es_lookup_extent(struct inode *inode, ext4_lblk_t lblk,
/* find extent in cache firstly */
es->es_lblk = es->es_len = es->es_pblk = 0;
- if (tree->cache_es) {
- es1 = tree->cache_es;
- if (in_range(lblk, es1->es_lblk, es1->es_len)) {
- es_debug("%u cached by [%u/%u)\n",
- lblk, es1->es_lblk, es1->es_len);
- found = 1;
- goto out;
- }
+ es1 = READ_ONCE(tree->cache_es);
+ if (es1 && in_range(lblk, es1->es_lblk, es1->es_len)) {
+ es_debug("%u cached by [%u/%u)\n",
+ lblk, es1->es_lblk, es1->es_len);
+ found = 1;
+ goto out;
}
node = tree->root.rb_node;
diff --git a/fs/ext4/hash.c b/fs/ext4/hash.c
index 147b5241dd94..46c3423ddfa1 100644
--- a/fs/ext4/hash.c
+++ b/fs/ext4/hash.c
@@ -277,7 +277,11 @@ static int __ext4fs_dirhash(const struct inode *dir, const char *name, int len,
}
default:
hinfo->hash = 0;
- return -1;
+ hinfo->minor_hash = 0;
+ ext4_warning(dir->i_sb,
+ "invalid/unsupported hash tree version %u",
+ hinfo->hash_version);
+ return -EINVAL;
}
hash = hash & ~1;
if (hash == (EXT4_HTREE_EOF_32BIT << 1))
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index 787ab89c2c26..754f961cd9fd 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -91,7 +91,7 @@ static int ext4_validate_inode_bitmap(struct super_block *sb,
if (buffer_verified(bh))
return 0;
- if (EXT4_MB_GRP_IBITMAP_CORRUPT(grp))
+ if (!grp || EXT4_MB_GRP_IBITMAP_CORRUPT(grp))
return -EFSCORRUPTED;
ext4_lock_group(sb, block_group);
@@ -293,7 +293,7 @@ void ext4_free_inode(handle_t *handle, struct inode *inode)
}
if (!(sbi->s_mount_state & EXT4_FC_REPLAY)) {
grp = ext4_get_group_info(sb, block_group);
- if (unlikely(EXT4_MB_GRP_IBITMAP_CORRUPT(grp))) {
+ if (!grp || unlikely(EXT4_MB_GRP_IBITMAP_CORRUPT(grp))) {
fatal = -EFSCORRUPTED;
goto error_return;
}
@@ -1046,7 +1046,7 @@ got_group:
* Skip groups with already-known suspicious inode
* tables
*/
- if (EXT4_MB_GRP_IBITMAP_CORRUPT(grp))
+ if (!grp || EXT4_MB_GRP_IBITMAP_CORRUPT(grp))
goto next_group;
}
@@ -1183,6 +1183,10 @@ got:
if (!(sbi->s_mount_state & EXT4_FC_REPLAY)) {
grp = ext4_get_group_info(sb, group);
+ if (!grp) {
+ err = -EFSCORRUPTED;
+ goto out;
+ }
down_read(&grp->alloc_sem); /*
* protect vs itable
* lazyinit
@@ -1526,7 +1530,7 @@ int ext4_init_inode_table(struct super_block *sb, ext4_group_t group,
}
gdp = ext4_get_group_desc(sb, group, &group_desc_bh);
- if (!gdp)
+ if (!gdp || !grp)
goto out;
/*
diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c
index 859bc4e2c9b0..5854bd5a3352 100644
--- a/fs/ext4/inline.c
+++ b/fs/ext4/inline.c
@@ -34,6 +34,7 @@ static int get_max_inline_xattr_value_size(struct inode *inode,
struct ext4_xattr_ibody_header *header;
struct ext4_xattr_entry *entry;
struct ext4_inode *raw_inode;
+ void *end;
int free, min_offs;
if (!EXT4_INODE_HAS_XATTR_SPACE(inode))
@@ -57,14 +58,23 @@ static int get_max_inline_xattr_value_size(struct inode *inode,
raw_inode = ext4_raw_inode(iloc);
header = IHDR(inode, raw_inode);
entry = IFIRST(header);
+ end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size;
/* Compute min_offs. */
- for (; !IS_LAST_ENTRY(entry); entry = EXT4_XATTR_NEXT(entry)) {
+ while (!IS_LAST_ENTRY(entry)) {
+ void *next = EXT4_XATTR_NEXT(entry);
+
+ if (next >= end) {
+ EXT4_ERROR_INODE(inode,
+ "corrupt xattr in inline inode");
+ return 0;
+ }
if (!entry->e_value_inum && entry->e_value_size) {
size_t offs = le16_to_cpu(entry->e_value_offs);
if (offs < min_offs)
min_offs = offs;
}
+ entry = next;
}
free = min_offs -
((void *)entry - (void *)IFIRST(header)) - sizeof(__u32);
@@ -350,7 +360,7 @@ static int ext4_update_inline_data(handle_t *handle, struct inode *inode,
error = ext4_xattr_ibody_get(inode, i.name_index, i.name,
value, len);
- if (error == -ENODATA)
+ if (error < 0)
goto out;
BUFFER_TRACE(is.iloc.bh, "get_write_access");
@@ -1175,6 +1185,7 @@ static int ext4_finish_convert_inline_dir(handle_t *handle,
ext4_initialize_dirent_tail(dir_block,
inode->i_sb->s_blocksize);
set_buffer_uptodate(dir_block);
+ unlock_buffer(dir_block);
err = ext4_handle_dirty_dirblock(handle, inode, dir_block);
if (err)
return err;
@@ -1249,6 +1260,7 @@ static int ext4_convert_inline_data_nolock(handle_t *handle,
if (!S_ISDIR(inode->i_mode)) {
memcpy(data_bh->b_data, buf, inline_size);
set_buffer_uptodate(data_bh);
+ unlock_buffer(data_bh);
error = ext4_handle_dirty_metadata(handle,
inode, data_bh);
} else {
@@ -1256,7 +1268,6 @@ static int ext4_convert_inline_data_nolock(handle_t *handle,
buf, inline_size);
}
- unlock_buffer(data_bh);
out_restore:
if (error)
ext4_restore_inline_data(handle, inode, iloc, buf, inline_size);
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 0d5ba922e411..ce5f21b6c2b3 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -2783,11 +2783,12 @@ static int ext4_writepages(struct address_space *mapping,
.can_map = 1,
};
int ret;
+ int alloc_ctx;
if (unlikely(ext4_forced_shutdown(EXT4_SB(sb))))
return -EIO;
- percpu_down_read(&EXT4_SB(sb)->s_writepages_rwsem);
+ alloc_ctx = ext4_writepages_down_read(sb);
ret = ext4_do_writepages(&mpd);
/*
* For data=journal writeback we could have come across pages marked
@@ -2796,7 +2797,7 @@ static int ext4_writepages(struct address_space *mapping,
*/
if (!ret && mpd.journalled_more_data)
ret = ext4_do_writepages(&mpd);
- percpu_up_read(&EXT4_SB(sb)->s_writepages_rwsem);
+ ext4_writepages_up_read(sb, alloc_ctx);
return ret;
}
@@ -2824,17 +2825,18 @@ static int ext4_dax_writepages(struct address_space *mapping,
long nr_to_write = wbc->nr_to_write;
struct inode *inode = mapping->host;
struct ext4_sb_info *sbi = EXT4_SB(mapping->host->i_sb);
+ int alloc_ctx;
if (unlikely(ext4_forced_shutdown(EXT4_SB(inode->i_sb))))
return -EIO;
- percpu_down_read(&sbi->s_writepages_rwsem);
+ alloc_ctx = ext4_writepages_down_read(inode->i_sb);
trace_ext4_writepages(inode, wbc);
ret = dax_writeback_mapping_range(mapping, sbi->s_daxdev, wbc);
trace_ext4_writepages_result(inode, wbc, ret,
nr_to_write - wbc->nr_to_write);
- percpu_up_read(&sbi->s_writepages_rwsem);
+ ext4_writepages_up_read(inode->i_sb, alloc_ctx);
return ret;
}
@@ -3375,7 +3377,7 @@ static int ext4_iomap_overwrite_begin(struct inode *inode, loff_t offset,
*/
flags &= ~IOMAP_WRITE;
ret = ext4_iomap_begin(inode, offset, length, flags, iomap, srcmap);
- WARN_ON_ONCE(iomap->type != IOMAP_MAPPED);
+ WARN_ON_ONCE(!ret && iomap->type != IOMAP_MAPPED);
return ret;
}
@@ -5928,7 +5930,7 @@ int ext4_change_inode_journal_flag(struct inode *inode, int val)
journal_t *journal;
handle_t *handle;
int err;
- struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
+ int alloc_ctx;
/*
* We have to be very careful here: changing a data block's
@@ -5966,7 +5968,7 @@ int ext4_change_inode_journal_flag(struct inode *inode, int val)
}
}
- percpu_down_write(&sbi->s_writepages_rwsem);
+ alloc_ctx = ext4_writepages_down_write(inode->i_sb);
jbd2_journal_lock_updates(journal);
/*
@@ -5983,7 +5985,7 @@ int ext4_change_inode_journal_flag(struct inode *inode, int val)
err = jbd2_journal_flush(journal, 0);
if (err < 0) {
jbd2_journal_unlock_updates(journal);
- percpu_up_write(&sbi->s_writepages_rwsem);
+ ext4_writepages_up_write(inode->i_sb, alloc_ctx);
return err;
}
ext4_clear_inode_flag(inode, EXT4_INODE_JOURNAL_DATA);
@@ -5991,7 +5993,7 @@ int ext4_change_inode_journal_flag(struct inode *inode, int val)
ext4_set_aops(inode);
jbd2_journal_unlock_updates(journal);
- percpu_up_write(&sbi->s_writepages_rwsem);
+ ext4_writepages_up_write(inode->i_sb, alloc_ctx);
if (val)
filemap_invalidate_unlock(inode->i_mapping);
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index 78259bddbc4d..7b2e36d103cb 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -745,6 +745,8 @@ static int __mb_check_buddy(struct ext4_buddy *e4b, char *file,
MB_CHECK_ASSERT(e4b->bd_info->bb_fragments == fragments);
grp = ext4_get_group_info(sb, e4b->bd_group);
+ if (!grp)
+ return NULL;
list_for_each(cur, &grp->bb_prealloc_list) {
ext4_group_t groupnr;
struct ext4_prealloc_space *pa;
@@ -1060,9 +1062,9 @@ mb_set_largest_free_order(struct super_block *sb, struct ext4_group_info *grp)
static noinline_for_stack
void ext4_mb_generate_buddy(struct super_block *sb,
- void *buddy, void *bitmap, ext4_group_t group)
+ void *buddy, void *bitmap, ext4_group_t group,
+ struct ext4_group_info *grp)
{
- struct ext4_group_info *grp = ext4_get_group_info(sb, group);
struct ext4_sb_info *sbi = EXT4_SB(sb);
ext4_grpblk_t max = EXT4_CLUSTERS_PER_GROUP(sb);
ext4_grpblk_t i = 0;
@@ -1181,6 +1183,8 @@ static int ext4_mb_init_cache(struct page *page, char *incore, gfp_t gfp)
break;
grinfo = ext4_get_group_info(sb, group);
+ if (!grinfo)
+ continue;
/*
* If page is uptodate then we came here after online resize
* which added some new uninitialized group info structs, so
@@ -1246,6 +1250,10 @@ static int ext4_mb_init_cache(struct page *page, char *incore, gfp_t gfp)
group, page->index, i * blocksize);
trace_ext4_mb_buddy_bitmap_load(sb, group);
grinfo = ext4_get_group_info(sb, group);
+ if (!grinfo) {
+ err = -EFSCORRUPTED;
+ goto out;
+ }
grinfo->bb_fragments = 0;
memset(grinfo->bb_counters, 0,
sizeof(*grinfo->bb_counters) *
@@ -1256,7 +1264,7 @@ static int ext4_mb_init_cache(struct page *page, char *incore, gfp_t gfp)
ext4_lock_group(sb, group);
/* init the buddy */
memset(data, 0xff, blocksize);
- ext4_mb_generate_buddy(sb, data, incore, group);
+ ext4_mb_generate_buddy(sb, data, incore, group, grinfo);
ext4_unlock_group(sb, group);
incore = NULL;
} else {
@@ -1370,6 +1378,9 @@ int ext4_mb_init_group(struct super_block *sb, ext4_group_t group, gfp_t gfp)
might_sleep();
mb_debug(sb, "init group %u\n", group);
this_grp = ext4_get_group_info(sb, group);
+ if (!this_grp)
+ return -EFSCORRUPTED;
+
/*
* This ensures that we don't reinit the buddy cache
* page which map to the group from which we are already
@@ -1444,6 +1455,8 @@ ext4_mb_load_buddy_gfp(struct super_block *sb, ext4_group_t group,
blocks_per_page = PAGE_SIZE / sb->s_blocksize;
grp = ext4_get_group_info(sb, group);
+ if (!grp)
+ return -EFSCORRUPTED;
e4b->bd_blkbits = sb->s_blocksize_bits;
e4b->bd_info = grp;
@@ -2159,6 +2172,8 @@ int ext4_mb_find_by_goal(struct ext4_allocation_context *ac,
struct ext4_group_info *grp = ext4_get_group_info(ac->ac_sb, group);
struct ext4_free_extent ex;
+ if (!grp)
+ return -EFSCORRUPTED;
if (!(ac->ac_flags & (EXT4_MB_HINT_TRY_GOAL | EXT4_MB_HINT_GOAL_ONLY)))
return 0;
if (grp->bb_free == 0)
@@ -2385,7 +2400,7 @@ static bool ext4_mb_good_group(struct ext4_allocation_context *ac,
BUG_ON(cr < 0 || cr >= 4);
- if (unlikely(EXT4_MB_GRP_BBITMAP_CORRUPT(grp)))
+ if (unlikely(EXT4_MB_GRP_BBITMAP_CORRUPT(grp) || !grp))
return false;
free = grp->bb_free;
@@ -2454,6 +2469,8 @@ static int ext4_mb_good_group_nolock(struct ext4_allocation_context *ac,
ext4_grpblk_t free;
int ret = 0;
+ if (!grp)
+ return -EFSCORRUPTED;
if (sbi->s_mb_stats)
atomic64_inc(&sbi->s_bal_cX_groups_considered[ac->ac_criteria]);
if (should_lock) {
@@ -2534,7 +2551,7 @@ ext4_group_t ext4_mb_prefetch(struct super_block *sb, ext4_group_t group,
* prefetch once, so we avoid getblk() call, which can
* be expensive.
*/
- if (!EXT4_MB_GRP_TEST_AND_SET_READ(grp) &&
+ if (gdp && grp && !EXT4_MB_GRP_TEST_AND_SET_READ(grp) &&
EXT4_MB_GRP_NEED_INIT(grp) &&
ext4_free_group_clusters(sb, gdp) > 0 &&
!(ext4_has_group_desc_csum(sb) &&
@@ -2578,7 +2595,7 @@ void ext4_mb_prefetch_fini(struct super_block *sb, ext4_group_t group,
gdp = ext4_get_group_desc(sb, group, NULL);
grp = ext4_get_group_info(sb, group);
- if (EXT4_MB_GRP_NEED_INIT(grp) &&
+ if (grp && gdp && EXT4_MB_GRP_NEED_INIT(grp) &&
ext4_free_group_clusters(sb, gdp) > 0 &&
!(ext4_has_group_desc_csum(sb) &&
(gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)))) {
@@ -2837,6 +2854,8 @@ static int ext4_mb_seq_groups_show(struct seq_file *seq, void *v)
sizeof(struct ext4_group_info);
grinfo = ext4_get_group_info(sb, group);
+ if (!grinfo)
+ return 0;
/* Load the group info in memory only if not already loaded. */
if (unlikely(EXT4_MB_GRP_NEED_INIT(grinfo))) {
err = ext4_mb_load_buddy(sb, group, &e4b);
@@ -2847,7 +2866,7 @@ static int ext4_mb_seq_groups_show(struct seq_file *seq, void *v)
buddy_loaded = 1;
}
- memcpy(&sg, ext4_get_group_info(sb, group), i);
+ memcpy(&sg, grinfo, i);
if (buddy_loaded)
ext4_mb_unload_buddy(&e4b);
@@ -3208,8 +3227,12 @@ static int ext4_mb_init_backend(struct super_block *sb)
err_freebuddy:
cachep = get_groupinfo_cache(sb->s_blocksize_bits);
- while (i-- > 0)
- kmem_cache_free(cachep, ext4_get_group_info(sb, i));
+ while (i-- > 0) {
+ struct ext4_group_info *grp = ext4_get_group_info(sb, i);
+
+ if (grp)
+ kmem_cache_free(cachep, grp);
+ }
i = sbi->s_group_info_size;
rcu_read_lock();
group_info = rcu_dereference(sbi->s_group_info);
@@ -3522,6 +3545,8 @@ int ext4_mb_release(struct super_block *sb)
for (i = 0; i < ngroups; i++) {
cond_resched();
grinfo = ext4_get_group_info(sb, i);
+ if (!grinfo)
+ continue;
mb_group_bb_bitmap_free(grinfo);
ext4_lock_group(sb, i);
count = ext4_mb_cleanup_pa(grinfo);
@@ -4606,6 +4631,8 @@ static void ext4_mb_generate_from_freelist(struct super_block *sb, void *bitmap,
struct ext4_free_data *entry;
grp = ext4_get_group_info(sb, group);
+ if (!grp)
+ return;
n = rb_first(&(grp->bb_free_root));
while (n) {
@@ -4633,6 +4660,9 @@ void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap,
int preallocated = 0;
int len;
+ if (!grp)
+ return;
+
/* all form of preallocation discards first load group,
* so the only competing code is preallocation use.
* we don't need any locking here
@@ -4869,6 +4899,8 @@ adjust_bex:
ei = EXT4_I(ac->ac_inode);
grp = ext4_get_group_info(sb, ac->ac_b_ex.fe_group);
+ if (!grp)
+ return;
pa->pa_node_lock.inode_lock = &ei->i_prealloc_lock;
pa->pa_inode = ac->ac_inode;
@@ -4918,6 +4950,8 @@ ext4_mb_new_group_pa(struct ext4_allocation_context *ac)
atomic_add(pa->pa_free, &EXT4_SB(sb)->s_mb_preallocated);
grp = ext4_get_group_info(sb, ac->ac_b_ex.fe_group);
+ if (!grp)
+ return;
lg = ac->ac_lg;
BUG_ON(lg == NULL);
@@ -5013,7 +5047,11 @@ ext4_mb_release_group_pa(struct ext4_buddy *e4b,
trace_ext4_mb_release_group_pa(sb, pa);
BUG_ON(pa->pa_deleted == 0);
ext4_get_group_no_and_offset(sb, pa->pa_pstart, &group, &bit);
- BUG_ON(group != e4b->bd_group && pa->pa_len != 0);
+ if (unlikely(group != e4b->bd_group && pa->pa_len != 0)) {
+ ext4_warning(sb, "bad group: expected %u, group %u, pa_start %llu",
+ e4b->bd_group, group, pa->pa_pstart);
+ return 0;
+ }
mb_free_blocks(pa->pa_inode, e4b, bit, pa->pa_len);
atomic_add(pa->pa_len, &EXT4_SB(sb)->s_mb_discarded);
trace_ext4_mballoc_discard(sb, NULL, group, bit, pa->pa_len);
@@ -5043,6 +5081,8 @@ ext4_mb_discard_group_preallocations(struct super_block *sb,
int err;
int free = 0;
+ if (!grp)
+ return 0;
mb_debug(sb, "discard preallocation for group %u\n", group);
if (list_empty(&grp->bb_prealloc_list))
goto out_dbg;
@@ -5297,6 +5337,9 @@ static inline void ext4_mb_show_pa(struct super_block *sb)
struct ext4_prealloc_space *pa;
ext4_grpblk_t start;
struct list_head *cur;
+
+ if (!grp)
+ continue;
ext4_lock_group(sb, i);
list_for_each(cur, &grp->bb_prealloc_list) {
pa = list_entry(cur, struct ext4_prealloc_space,
@@ -6064,6 +6107,7 @@ static void ext4_mb_clear_bb(handle_t *handle, struct inode *inode,
struct buffer_head *bitmap_bh = NULL;
struct super_block *sb = inode->i_sb;
struct ext4_group_desc *gdp;
+ struct ext4_group_info *grp;
unsigned int overflow;
ext4_grpblk_t bit;
struct buffer_head *gd_bh;
@@ -6089,8 +6133,8 @@ do_more:
overflow = 0;
ext4_get_group_no_and_offset(sb, block, &block_group, &bit);
- if (unlikely(EXT4_MB_GRP_BBITMAP_CORRUPT(
- ext4_get_group_info(sb, block_group))))
+ grp = ext4_get_group_info(sb, block_group);
+ if (unlikely(!grp || EXT4_MB_GRP_BBITMAP_CORRUPT(grp)))
return;
/*
@@ -6692,6 +6736,8 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range)
for (group = first_group; group <= last_group; group++) {
grp = ext4_get_group_info(sb, group);
+ if (!grp)
+ continue;
/* We only do this if the grp has never been initialized */
if (unlikely(EXT4_MB_GRP_NEED_INIT(grp))) {
ret = ext4_mb_init_group(sb, group, GFP_NOFS);
diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c
index a19a9661646e..d98ac2af8199 100644
--- a/fs/ext4/migrate.c
+++ b/fs/ext4/migrate.c
@@ -408,7 +408,6 @@ static int free_ext_block(handle_t *handle, struct inode *inode)
int ext4_ext_migrate(struct inode *inode)
{
- struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
handle_t *handle;
int retval = 0, i;
__le32 *i_data;
@@ -418,6 +417,7 @@ int ext4_ext_migrate(struct inode *inode)
unsigned long max_entries;
__u32 goal, tmp_csum_seed;
uid_t owner[2];
+ int alloc_ctx;
/*
* If the filesystem does not support extents, or the inode
@@ -434,7 +434,7 @@ int ext4_ext_migrate(struct inode *inode)
*/
return retval;
- percpu_down_write(&sbi->s_writepages_rwsem);
+ alloc_ctx = ext4_writepages_down_write(inode->i_sb);
/*
* Worst case we can touch the allocation bitmaps and a block
@@ -586,7 +586,7 @@ out_tmp_inode:
unlock_new_inode(tmp_inode);
iput(tmp_inode);
out_unlock:
- percpu_up_write(&sbi->s_writepages_rwsem);
+ ext4_writepages_up_write(inode->i_sb, alloc_ctx);
return retval;
}
@@ -605,6 +605,7 @@ int ext4_ind_migrate(struct inode *inode)
ext4_fsblk_t blk;
handle_t *handle;
int ret, ret2 = 0;
+ int alloc_ctx;
if (!ext4_has_feature_extents(inode->i_sb) ||
(!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
@@ -621,7 +622,7 @@ int ext4_ind_migrate(struct inode *inode)
if (test_opt(inode->i_sb, DELALLOC))
ext4_alloc_da_blocks(inode);
- percpu_down_write(&sbi->s_writepages_rwsem);
+ alloc_ctx = ext4_writepages_down_write(inode->i_sb);
handle = ext4_journal_start(inode, EXT4_HT_MIGRATE, 1);
if (IS_ERR(handle)) {
@@ -665,6 +666,6 @@ errout:
ext4_journal_stop(handle);
up_write(&EXT4_I(inode)->i_data_sem);
out_unlock:
- percpu_up_write(&sbi->s_writepages_rwsem);
+ ext4_writepages_up_write(inode->i_sb, alloc_ctx);
return ret;
}
diff --git a/fs/ext4/mmp.c b/fs/ext4/mmp.c
index 4022bc713421..0aaf38ffcb6e 100644
--- a/fs/ext4/mmp.c
+++ b/fs/ext4/mmp.c
@@ -39,28 +39,36 @@ static void ext4_mmp_csum_set(struct super_block *sb, struct mmp_struct *mmp)
* Write the MMP block using REQ_SYNC to try to get the block on-disk
* faster.
*/
-static int write_mmp_block(struct super_block *sb, struct buffer_head *bh)
+static int write_mmp_block_thawed(struct super_block *sb,
+ struct buffer_head *bh)
{
struct mmp_struct *mmp = (struct mmp_struct *)(bh->b_data);
- /*
- * We protect against freezing so that we don't create dirty buffers
- * on frozen filesystem.
- */
- sb_start_write(sb);
ext4_mmp_csum_set(sb, mmp);
lock_buffer(bh);
bh->b_end_io = end_buffer_write_sync;
get_bh(bh);
submit_bh(REQ_OP_WRITE | REQ_SYNC | REQ_META | REQ_PRIO, bh);
wait_on_buffer(bh);
- sb_end_write(sb);
if (unlikely(!buffer_uptodate(bh)))
return -EIO;
-
return 0;
}
+static int write_mmp_block(struct super_block *sb, struct buffer_head *bh)
+{
+ int err;
+
+ /*
+ * We protect against freezing so that we don't create dirty buffers
+ * on frozen filesystem.
+ */
+ sb_start_write(sb);
+ err = write_mmp_block_thawed(sb, bh);
+ sb_end_write(sb);
+ return err;
+}
+
/*
* Read the MMP block. It _must_ be read from disk and hence we clear the
* uptodate flag on the buffer.
@@ -344,7 +352,11 @@ skip:
seq = mmp_new_seq();
mmp->mmp_seq = cpu_to_le32(seq);
- retval = write_mmp_block(sb, bh);
+ /*
+ * On mount / remount we are protected against fs freezing (by s_umount
+ * semaphore) and grabbing freeze protection upsets lockdep
+ */
+ retval = write_mmp_block_thawed(sb, bh);
if (retval)
goto failed;
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index a5010b5b8a8c..45b579805c95 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -674,7 +674,7 @@ static struct stats dx_show_leaf(struct inode *dir,
len = de->name_len;
if (!IS_ENCRYPTED(dir)) {
/* Directory is not encrypted */
- ext4fs_dirhash(dir, de->name,
+ (void) ext4fs_dirhash(dir, de->name,
de->name_len, &h);
printk("%*.s:(U)%x.%u ", len,
name, h.hash,
@@ -709,8 +709,9 @@ static struct stats dx_show_leaf(struct inode *dir,
if (IS_CASEFOLDED(dir))
h.hash = EXT4_DIRENT_HASH(de);
else
- ext4fs_dirhash(dir, de->name,
- de->name_len, &h);
+ (void) ext4fs_dirhash(dir,
+ de->name,
+ de->name_len, &h);
printk("%*.s:(E)%x.%u ", len, name,
h.hash, (unsigned) ((char *) de
- base));
@@ -720,7 +721,8 @@ static struct stats dx_show_leaf(struct inode *dir,
#else
int len = de->name_len;
char *name = de->name;
- ext4fs_dirhash(dir, de->name, de->name_len, &h);
+ (void) ext4fs_dirhash(dir, de->name,
+ de->name_len, &h);
printk("%*.s:%x.%u ", len, name, h.hash,
(unsigned) ((char *) de - base));
#endif
@@ -849,8 +851,14 @@ dx_probe(struct ext4_filename *fname, struct inode *dir,
hinfo->seed = EXT4_SB(dir->i_sb)->s_hash_seed;
/* hash is already computed for encrypted casefolded directory */
if (fname && fname_name(fname) &&
- !(IS_ENCRYPTED(dir) && IS_CASEFOLDED(dir)))
- ext4fs_dirhash(dir, fname_name(fname), fname_len(fname), hinfo);
+ !(IS_ENCRYPTED(dir) && IS_CASEFOLDED(dir))) {
+ int ret = ext4fs_dirhash(dir, fname_name(fname),
+ fname_len(fname), hinfo);
+ if (ret < 0) {
+ ret_err = ERR_PTR(ret);
+ goto fail;
+ }
+ }
hash = hinfo->hash;
if (root->info.unused_flags & 1) {
@@ -1111,7 +1119,12 @@ static int htree_dirblock_to_tree(struct file *dir_file,
hinfo->minor_hash = 0;
}
} else {
- ext4fs_dirhash(dir, de->name, de->name_len, hinfo);
+ err = ext4fs_dirhash(dir, de->name,
+ de->name_len, hinfo);
+ if (err < 0) {
+ count = err;
+ goto errout;
+ }
}
if ((hinfo->hash < start_hash) ||
((hinfo->hash == start_hash) &&
@@ -1313,8 +1326,12 @@ static int dx_make_map(struct inode *dir, struct buffer_head *bh,
if (de->name_len && de->inode) {
if (ext4_hash_in_dirent(dir))
h.hash = EXT4_DIRENT_HASH(de);
- else
- ext4fs_dirhash(dir, de->name, de->name_len, &h);
+ else {
+ int err = ext4fs_dirhash(dir, de->name,
+ de->name_len, &h);
+ if (err < 0)
+ return err;
+ }
map_tail--;
map_tail->hash = h.hash;
map_tail->offs = ((char *) de - base)>>2;
@@ -1452,10 +1469,9 @@ int ext4_fname_setup_ci_filename(struct inode *dir, const struct qstr *iname,
hinfo->hash_version = DX_HASH_SIPHASH;
hinfo->seed = NULL;
if (cf_name->name)
- ext4fs_dirhash(dir, cf_name->name, cf_name->len, hinfo);
+ return ext4fs_dirhash(dir, cf_name->name, cf_name->len, hinfo);
else
- ext4fs_dirhash(dir, iname->name, iname->len, hinfo);
- return 0;
+ return ext4fs_dirhash(dir, iname->name, iname->len, hinfo);
}
#endif
@@ -2298,10 +2314,15 @@ static int make_indexed_dir(handle_t *handle, struct ext4_filename *fname,
fname->hinfo.seed = EXT4_SB(dir->i_sb)->s_hash_seed;
/* casefolded encrypted hashes are computed on fname setup */
- if (!ext4_hash_in_dirent(dir))
- ext4fs_dirhash(dir, fname_name(fname),
- fname_len(fname), &fname->hinfo);
-
+ if (!ext4_hash_in_dirent(dir)) {
+ int err = ext4fs_dirhash(dir, fname_name(fname),
+ fname_len(fname), &fname->hinfo);
+ if (err < 0) {
+ brelse(bh2);
+ brelse(bh);
+ return err;
+ }
+ }
memset(frames, 0, sizeof(frames));
frame = frames;
frame->entries = entries;
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index d39f386e9baf..9680fe753e59 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1048,6 +1048,8 @@ void ext4_mark_group_bitmap_corrupted(struct super_block *sb,
struct ext4_group_desc *gdp = ext4_get_group_desc(sb, group, NULL);
int ret;
+ if (!grp || !gdp)
+ return;
if (flags & EXT4_GROUP_INFO_BBITMAP_CORRUPT) {
ret = ext4_test_and_set_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT,
&grp->bb_state);
@@ -3238,11 +3240,9 @@ static __le16 ext4_group_desc_csum(struct super_block *sb, __u32 block_group,
crc = crc16(crc, (__u8 *)gdp, offset);
offset += sizeof(gdp->bg_checksum); /* skip checksum */
/* for checksum of struct ext4_group_desc do the rest...*/
- if (ext4_has_feature_64bit(sb) &&
- offset < le16_to_cpu(sbi->s_es->s_desc_size))
+ if (ext4_has_feature_64bit(sb) && offset < sbi->s_desc_size)
crc = crc16(crc, (__u8 *)gdp + offset,
- le16_to_cpu(sbi->s_es->s_desc_size) -
- offset);
+ sbi->s_desc_size - offset);
out:
return cpu_to_le16(crc);
@@ -5684,8 +5684,9 @@ static int ext4_fill_super(struct super_block *sb, struct fs_context *fc)
descr = "out journal";
if (___ratelimit(&ext4_mount_msg_ratelimit, "EXT4-fs mount"))
- ext4_msg(sb, KERN_INFO, "mounted filesystem %pU with%s. "
- "Quota mode: %s.", &sb->s_uuid, descr,
+ ext4_msg(sb, KERN_INFO, "mounted filesystem %pU %s with%s. "
+ "Quota mode: %s.", &sb->s_uuid,
+ sb_rdonly(sb) ? "ro" : "r/w", descr,
ext4_quota_mode(sb));
/* Update the s_overhead_clusters if necessary */
@@ -6387,6 +6388,7 @@ static int __ext4_remount(struct fs_context *fc, struct super_block *sb)
struct ext4_mount_options old_opts;
ext4_group_t g;
int err = 0;
+ int enable_rw = 0;
#ifdef CONFIG_QUOTA
int enable_quota = 0;
int i, j;
@@ -6573,7 +6575,7 @@ static int __ext4_remount(struct fs_context *fc, struct super_block *sb)
if (err)
goto restore_opts;
- sb->s_flags &= ~SB_RDONLY;
+ enable_rw = 1;
if (ext4_has_feature_mmp(sb)) {
err = ext4_multi_mount_protect(sb,
le64_to_cpu(es->s_mmp_block));
@@ -6616,9 +6618,6 @@ static int __ext4_remount(struct fs_context *fc, struct super_block *sb)
}
#ifdef CONFIG_QUOTA
- /* Release old quota file names */
- for (i = 0; i < EXT4_MAXQUOTAS; i++)
- kfree(old_opts.s_qf_names[i]);
if (enable_quota) {
if (sb_any_quota_suspended(sb))
dquot_resume(sb, -1);
@@ -6628,16 +6627,29 @@ static int __ext4_remount(struct fs_context *fc, struct super_block *sb)
goto restore_opts;
}
}
+ /* Release old quota file names */
+ for (i = 0; i < EXT4_MAXQUOTAS; i++)
+ kfree(old_opts.s_qf_names[i]);
#endif
if (!test_opt(sb, BLOCK_VALIDITY) && sbi->s_system_blks)
ext4_release_system_zone(sb);
+ if (enable_rw)
+ sb->s_flags &= ~SB_RDONLY;
+
if (!ext4_has_feature_mmp(sb) || sb_rdonly(sb))
ext4_stop_mmpd(sbi);
return 0;
restore_opts:
+ /*
+ * If there was a failing r/w to ro transition, we may need to
+ * re-enable quota
+ */
+ if ((sb->s_flags & SB_RDONLY) && !(old_sb_flags & SB_RDONLY) &&
+ sb_any_quota_suspended(sb))
+ dquot_resume(sb, -1);
sb->s_flags = old_sb_flags;
sbi->s_mount_opt = old_opts.s_mount_opt;
sbi->s_mount_opt2 = old_opts.s_mount_opt2;
@@ -6678,8 +6690,9 @@ static int ext4_reconfigure(struct fs_context *fc)
if (ret < 0)
return ret;
- ext4_msg(sb, KERN_INFO, "re-mounted %pU. Quota mode: %s.",
- &sb->s_uuid, ext4_quota_mode(sb));
+ ext4_msg(sb, KERN_INFO, "re-mounted %pU %s. Quota mode: %s.",
+ &sb->s_uuid, sb_rdonly(sb) ? "ro" : "r/w",
+ ext4_quota_mode(sb));
return 0;
}
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
index dadad29bd81b..dfc2e223bd10 100644
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -2614,6 +2614,7 @@ static int ext4_xattr_move_to_block(handle_t *handle, struct inode *inode,
.in_inode = !!entry->e_value_inum,
};
struct ext4_xattr_ibody_header *header = IHDR(inode, raw_inode);
+ int needs_kvfree = 0;
int error;
is = kzalloc(sizeof(struct ext4_xattr_ibody_find), GFP_NOFS);
@@ -2636,7 +2637,7 @@ static int ext4_xattr_move_to_block(handle_t *handle, struct inode *inode,
error = -ENOMEM;
goto out;
}
-
+ needs_kvfree = 1;
error = ext4_xattr_inode_get(inode, entry, buffer, value_size);
if (error)
goto out;
@@ -2675,7 +2676,7 @@ static int ext4_xattr_move_to_block(handle_t *handle, struct inode *inode,
out:
kfree(b_entry_name);
- if (entry->e_value_inum && buffer)
+ if (needs_kvfree && buffer)
kvfree(buffer);
if (is)
brelse(is->iloc.bh);
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index 5eed8c237500..a84bf6444bba 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -1419,6 +1419,14 @@ static void gfs2_evict_inode(struct inode *inode)
if (inode->i_nlink || sb_rdonly(sb) || !ip->i_no_addr)
goto out;
+ /*
+ * In case of an incomplete mount, gfs2_evict_inode() may be called for
+ * system files without having an active journal to write to. In that
+ * case, skip the filesystem evict.
+ */
+ if (!sdp->sd_jdesc)
+ goto out;
+
gfs2_holder_mark_uninitialized(&gh);
ret = evict_should_delete(inode, &gh);
if (ret == SHOULD_DEFER_EVICTION)
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index bacad0c57810..e63c1d46f189 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -402,7 +402,7 @@ static struct folio *nfs_readdir_folio_get_locked(struct address_space *mapping,
struct folio *folio;
folio = filemap_grab_folio(mapping, index);
- if (!folio)
+ if (IS_ERR(folio))
return NULL;
nfs_readdir_folio_init_and_validate(folio, cookie, change_attr);
return folio;
diff --git a/fs/notify/inotify/inotify_fsnotify.c b/fs/notify/inotify/inotify_fsnotify.c
index 49cfe2ae6d23..993375f0db67 100644
--- a/fs/notify/inotify/inotify_fsnotify.c
+++ b/fs/notify/inotify/inotify_fsnotify.c
@@ -65,7 +65,7 @@ int inotify_handle_inode_event(struct fsnotify_mark *inode_mark, u32 mask,
struct fsnotify_event *fsn_event;
struct fsnotify_group *group = inode_mark->group;
int ret;
- int len = 0;
+ int len = 0, wd;
int alloc_len = sizeof(struct inotify_event_info);
struct mem_cgroup *old_memcg;
@@ -81,6 +81,13 @@ int inotify_handle_inode_event(struct fsnotify_mark *inode_mark, u32 mask,
fsn_mark);
/*
+ * We can be racing with mark being detached. Don't report event with
+ * invalid wd.
+ */
+ wd = READ_ONCE(i_mark->wd);
+ if (wd == -1)
+ return 0;
+ /*
* Whoever is interested in the event, pays for the allocation. Do not
* trigger OOM killer in the target monitoring memcg as it may have
* security repercussion.
@@ -110,7 +117,7 @@ int inotify_handle_inode_event(struct fsnotify_mark *inode_mark, u32 mask,
fsn_event = &event->fse;
fsnotify_init_event(fsn_event);
event->mask = mask;
- event->wd = i_mark->wd;
+ event->wd = wd;
event->sync_cookie = cookie;
event->name_len = len;
if (len)
diff --git a/fs/pipe.c b/fs/pipe.c
index ceb17d2dfa19..2d88f73f585a 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -342,7 +342,8 @@ pipe_read(struct kiocb *iocb, struct iov_iter *to)
break;
if (ret)
break;
- if (filp->f_flags & O_NONBLOCK) {
+ if ((filp->f_flags & O_NONBLOCK) ||
+ (iocb->ki_flags & IOCB_NOWAIT)) {
ret = -EAGAIN;
break;
}
@@ -547,7 +548,8 @@ pipe_write(struct kiocb *iocb, struct iov_iter *from)
continue;
/* Wait for buffer space to become available. */
- if (filp->f_flags & O_NONBLOCK) {
+ if ((filp->f_flags & O_NONBLOCK) ||
+ (iocb->ki_flags & IOCB_NOWAIT)) {
if (!ret)
ret = -EAGAIN;
break;
diff --git a/fs/xfs/libxfs/xfs_ag.c b/fs/xfs/libxfs/xfs_ag.c
index 1b078bbbf225..9b373a0c7aaf 100644
--- a/fs/xfs/libxfs/xfs_ag.c
+++ b/fs/xfs/libxfs/xfs_ag.c
@@ -495,10 +495,12 @@ xfs_freesp_init_recs(
ASSERT(start >= mp->m_ag_prealloc_blocks);
if (start != mp->m_ag_prealloc_blocks) {
/*
- * Modify first record to pad stripe align of log
+ * Modify first record to pad stripe align of log and
+ * bump the record count.
*/
arec->ar_blockcount = cpu_to_be32(start -
mp->m_ag_prealloc_blocks);
+ be16_add_cpu(&block->bb_numrecs, 1);
nrec = arec + 1;
/*
@@ -509,7 +511,6 @@ xfs_freesp_init_recs(
be32_to_cpu(arec->ar_startblock) +
be32_to_cpu(arec->ar_blockcount));
arec = nrec;
- be16_add_cpu(&block->bb_numrecs, 1);
}
/*
* Change record start to after the internal log
@@ -518,15 +519,13 @@ xfs_freesp_init_recs(
}
/*
- * Calculate the record block count and check for the case where
- * the log might have consumed all available space in the AG. If
- * so, reset the record count to 0 to avoid exposure of an invalid
- * record start block.
+ * Calculate the block count of this record; if it is nonzero,
+ * increment the record count.
*/
arec->ar_blockcount = cpu_to_be32(id->agsize -
be32_to_cpu(arec->ar_startblock));
- if (!arec->ar_blockcount)
- block->bb_numrecs = 0;
+ if (arec->ar_blockcount)
+ be16_add_cpu(&block->bb_numrecs, 1);
}
/*
@@ -538,7 +537,7 @@ xfs_bnoroot_init(
struct xfs_buf *bp,
struct aghdr_init_data *id)
{
- xfs_btree_init_block(mp, bp, XFS_BTNUM_BNO, 0, 1, id->agno);
+ xfs_btree_init_block(mp, bp, XFS_BTNUM_BNO, 0, 0, id->agno);
xfs_freesp_init_recs(mp, bp, id);
}
@@ -548,7 +547,7 @@ xfs_cntroot_init(
struct xfs_buf *bp,
struct aghdr_init_data *id)
{
- xfs_btree_init_block(mp, bp, XFS_BTNUM_CNT, 0, 1, id->agno);
+ xfs_btree_init_block(mp, bp, XFS_BTNUM_CNT, 0, 0, id->agno);
xfs_freesp_init_recs(mp, bp, id);
}
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
index b512de0540d5..cd8870a16fd1 100644
--- a/fs/xfs/libxfs/xfs_bmap.c
+++ b/fs/xfs/libxfs/xfs_bmap.c
@@ -3494,8 +3494,10 @@ xfs_bmap_btalloc_at_eof(
if (!caller_pag)
args->pag = xfs_perag_get(mp, XFS_FSB_TO_AGNO(mp, ap->blkno));
error = xfs_alloc_vextent_exact_bno(args, ap->blkno);
- if (!caller_pag)
+ if (!caller_pag) {
xfs_perag_put(args->pag);
+ args->pag = NULL;
+ }
if (error)
return error;
@@ -3505,7 +3507,6 @@ xfs_bmap_btalloc_at_eof(
* Exact allocation failed. Reset to try an aligned allocation
* according to the original allocation specification.
*/
- args->pag = NULL;
args->alignment = stripe_align;
args->minlen = nextminlen;
args->minalignslop = 0;
diff --git a/fs/xfs/scrub/bmap.c b/fs/xfs/scrub/bmap.c
index 87ab9f95a487..69bc89d0fc68 100644
--- a/fs/xfs/scrub/bmap.c
+++ b/fs/xfs/scrub/bmap.c
@@ -42,12 +42,12 @@ xchk_setup_inode_bmap(
xfs_ilock(sc->ip, XFS_IOLOCK_EXCL);
/*
- * We don't want any ephemeral data fork updates sitting around
+ * We don't want any ephemeral data/cow fork updates sitting around
* while we inspect block mappings, so wait for directio to finish
* and flush dirty data if we have delalloc reservations.
*/
if (S_ISREG(VFS_I(sc->ip)->i_mode) &&
- sc->sm->sm_type == XFS_SCRUB_TYPE_BMBTD) {
+ sc->sm->sm_type != XFS_SCRUB_TYPE_BMBTA) {
struct address_space *mapping = VFS_I(sc->ip)->i_mapping;
sc->ilock_flags |= XFS_MMAPLOCK_EXCL;
diff --git a/fs/xfs/scrub/common.c b/fs/xfs/scrub/common.c
index 9aa79665c608..7a20256be969 100644
--- a/fs/xfs/scrub/common.c
+++ b/fs/xfs/scrub/common.c
@@ -1164,32 +1164,6 @@ xchk_metadata_inode_forks(
return 0;
}
-/* Pause background reaping of resources. */
-void
-xchk_stop_reaping(
- struct xfs_scrub *sc)
-{
- sc->flags |= XCHK_REAPING_DISABLED;
- xfs_blockgc_stop(sc->mp);
- xfs_inodegc_stop(sc->mp);
-}
-
-/* Restart background reaping of resources. */
-void
-xchk_start_reaping(
- struct xfs_scrub *sc)
-{
- /*
- * Readonly filesystems do not perform inactivation or speculative
- * preallocation, so there's no need to restart the workers.
- */
- if (!xfs_is_readonly(sc->mp)) {
- xfs_inodegc_start(sc->mp);
- xfs_blockgc_start(sc->mp);
- }
- sc->flags &= ~XCHK_REAPING_DISABLED;
-}
-
/*
* Enable filesystem hooks (i.e. runtime code patching) before starting a scrub
* operation. Callers must not hold any locks that intersect with the CPU
diff --git a/fs/xfs/scrub/common.h b/fs/xfs/scrub/common.h
index 18b5f2b62f13..791235cd9b00 100644
--- a/fs/xfs/scrub/common.h
+++ b/fs/xfs/scrub/common.h
@@ -156,8 +156,6 @@ static inline bool xchk_skip_xref(struct xfs_scrub_metadata *sm)
}
int xchk_metadata_inode_forks(struct xfs_scrub *sc);
-void xchk_stop_reaping(struct xfs_scrub *sc);
-void xchk_start_reaping(struct xfs_scrub *sc);
/*
* Setting up a hook to wait for intents to drain is costly -- we have to take
diff --git a/fs/xfs/scrub/fscounters.c b/fs/xfs/scrub/fscounters.c
index faa315be7978..e382a35e98d8 100644
--- a/fs/xfs/scrub/fscounters.c
+++ b/fs/xfs/scrub/fscounters.c
@@ -150,13 +150,6 @@ xchk_setup_fscounters(
if (error)
return error;
- /*
- * Pause background reclaim while we're scrubbing to reduce the
- * likelihood of background perturbations to the counters throwing off
- * our calculations.
- */
- xchk_stop_reaping(sc);
-
return xchk_trans_alloc(sc, 0);
}
@@ -454,6 +447,12 @@ xchk_fscounters(
xchk_set_corrupt(sc);
/*
+ * XXX: We can't quiesce percpu counter updates, so exit early.
+ * This can be re-enabled when we gain exclusive freeze functionality.
+ */
+ return 0;
+
+ /*
* If ifree exceeds icount by more than the minimum variance then
* something's probably wrong with the counters.
*/
diff --git a/fs/xfs/scrub/scrub.c b/fs/xfs/scrub/scrub.c
index 02819bedc5b1..3d98f604765e 100644
--- a/fs/xfs/scrub/scrub.c
+++ b/fs/xfs/scrub/scrub.c
@@ -186,8 +186,6 @@ xchk_teardown(
}
if (sc->sm->sm_flags & XFS_SCRUB_IFLAG_REPAIR)
mnt_drop_write_file(sc->file);
- if (sc->flags & XCHK_REAPING_DISABLED)
- xchk_start_reaping(sc);
if (sc->buf) {
if (sc->buf_cleanup)
sc->buf_cleanup(sc->buf);
diff --git a/fs/xfs/scrub/scrub.h b/fs/xfs/scrub/scrub.h
index e71903474cd7..b38e93830dde 100644
--- a/fs/xfs/scrub/scrub.h
+++ b/fs/xfs/scrub/scrub.h
@@ -106,7 +106,6 @@ struct xfs_scrub {
/* XCHK state flags grow up from zero, XREP state flags grown down from 2^31 */
#define XCHK_TRY_HARDER (1 << 0) /* can't get resources, try again */
-#define XCHK_REAPING_DISABLED (1 << 1) /* background block reaping paused */
#define XCHK_FSGATES_DRAIN (1 << 2) /* defer ops draining enabled */
#define XCHK_NEED_DRAIN (1 << 3) /* scrub needs to drain defer ops */
#define XREP_ALREADY_FIXED (1 << 31) /* checking our repair work */
diff --git a/fs/xfs/scrub/trace.h b/fs/xfs/scrub/trace.h
index 68efd6fda61c..b3894daeb86a 100644
--- a/fs/xfs/scrub/trace.h
+++ b/fs/xfs/scrub/trace.h
@@ -98,7 +98,6 @@ TRACE_DEFINE_ENUM(XFS_SCRUB_TYPE_FSCOUNTERS);
#define XFS_SCRUB_STATE_STRINGS \
{ XCHK_TRY_HARDER, "try_harder" }, \
- { XCHK_REAPING_DISABLED, "reaping_disabled" }, \
{ XCHK_FSGATES_DRAIN, "fsgates_drain" }, \
{ XCHK_NEED_DRAIN, "need_drain" }, \
{ XREP_ALREADY_FIXED, "already_fixed" }
diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c
index f032d3a4b727..fbb675563208 100644
--- a/fs/xfs/xfs_bmap_util.c
+++ b/fs/xfs/xfs_bmap_util.c
@@ -558,7 +558,9 @@ xfs_getbmap(
if (!xfs_iext_next_extent(ifp, &icur, &got)) {
xfs_fileoff_t end = XFS_B_TO_FSB(mp, XFS_ISIZE(ip));
- out[bmv->bmv_entries - 1].bmv_oflags |= BMV_OF_LAST;
+ if (bmv->bmv_entries > 0)
+ out[bmv->bmv_entries - 1].bmv_oflags |=
+ BMV_OF_LAST;
if (whichfork != XFS_ATTR_FORK && bno < end &&
!xfs_getbmap_full(bmv)) {
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
index 351849fc18ff..0f60e301eb1f 100644
--- a/fs/xfs/xfs_icache.c
+++ b/fs/xfs/xfs_icache.c
@@ -435,18 +435,23 @@ xfs_iget_check_free_state(
}
/* Make all pending inactivation work start immediately. */
-static void
+static bool
xfs_inodegc_queue_all(
struct xfs_mount *mp)
{
struct xfs_inodegc *gc;
int cpu;
+ bool ret = false;
for_each_online_cpu(cpu) {
gc = per_cpu_ptr(mp->m_inodegc, cpu);
- if (!llist_empty(&gc->list))
+ if (!llist_empty(&gc->list)) {
mod_delayed_work_on(cpu, mp->m_inodegc_wq, &gc->work, 0);
+ ret = true;
+ }
}
+
+ return ret;
}
/*
@@ -1856,6 +1861,8 @@ xfs_inodegc_worker(
struct xfs_inode *ip, *n;
unsigned int nofs_flag;
+ ASSERT(gc->cpu == smp_processor_id());
+
WRITE_ONCE(gc->items, 0);
if (!node)
@@ -1909,24 +1916,41 @@ xfs_inodegc_flush(
/*
* Flush all the pending work and then disable the inode inactivation background
- * workers and wait for them to stop.
+ * workers and wait for them to stop. Caller must hold sb->s_umount to
+ * coordinate changes in the inodegc_enabled state.
*/
void
xfs_inodegc_stop(
struct xfs_mount *mp)
{
+ bool rerun;
+
if (!xfs_clear_inodegc_enabled(mp))
return;
+ /*
+ * Drain all pending inodegc work, including inodes that could be
+ * queued by racing xfs_inodegc_queue or xfs_inodegc_shrinker_scan
+ * threads that sample the inodegc state just prior to us clearing it.
+ * The inodegc flag state prevents new threads from queuing more
+ * inodes, so we queue pending work items and flush the workqueue until
+ * all inodegc lists are empty. IOWs, we cannot use drain_workqueue
+ * here because it does not allow other unserialized mechanisms to
+ * reschedule inodegc work while this draining is in progress.
+ */
xfs_inodegc_queue_all(mp);
- drain_workqueue(mp->m_inodegc_wq);
+ do {
+ flush_workqueue(mp->m_inodegc_wq);
+ rerun = xfs_inodegc_queue_all(mp);
+ } while (rerun);
trace_xfs_inodegc_stop(mp, __return_address);
}
/*
* Enable the inode inactivation background workers and schedule deferred inode
- * inactivation work if there is any.
+ * inactivation work if there is any. Caller must hold sb->s_umount to
+ * coordinate changes in the inodegc_enabled state.
*/
void
xfs_inodegc_start(
@@ -2069,7 +2093,8 @@ xfs_inodegc_queue(
queue_delay = 0;
trace_xfs_inodegc_queue(mp, __return_address);
- mod_delayed_work(mp->m_inodegc_wq, &gc->work, queue_delay);
+ mod_delayed_work_on(current_cpu(), mp->m_inodegc_wq, &gc->work,
+ queue_delay);
put_cpu_ptr(gc);
if (xfs_inodegc_want_flush_work(ip, items, shrinker_hits)) {
@@ -2113,7 +2138,8 @@ xfs_inodegc_cpu_dead(
if (xfs_is_inodegc_enabled(mp)) {
trace_xfs_inodegc_queue(mp, __return_address);
- mod_delayed_work(mp->m_inodegc_wq, &gc->work, 0);
+ mod_delayed_work_on(current_cpu(), mp->m_inodegc_wq, &gc->work,
+ 0);
}
put_cpu_ptr(gc);
}
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index 285885c308bd..18c8f168b153 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -1006,8 +1006,9 @@ xfs_buffered_write_iomap_begin(
if (eof)
imap.br_startoff = end_fsb; /* fake hole until the end */
- /* We never need to allocate blocks for zeroing a hole. */
- if ((flags & IOMAP_ZERO) && imap.br_startoff > offset_fsb) {
+ /* We never need to allocate blocks for zeroing or unsharing a hole. */
+ if ((flags & (IOMAP_UNSHARE | IOMAP_ZERO)) &&
+ imap.br_startoff > offset_fsb) {
xfs_hole_to_iomap(ip, iomap, offset_fsb, imap.br_startoff);
goto out_unlock;
}
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index f3269c0626f0..aaaf5ec13492 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -66,6 +66,9 @@ struct xfs_inodegc {
/* approximate count of inodes in the list */
unsigned int items;
unsigned int shrinker_hits;
+#if defined(DEBUG) || defined(XFS_WARN)
+ unsigned int cpu;
+#endif
};
/*
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 4d2e87462ac4..7e706255f165 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -1095,6 +1095,9 @@ xfs_inodegc_init_percpu(
for_each_possible_cpu(cpu) {
gc = per_cpu_ptr(mp->m_inodegc, cpu);
+#if defined(DEBUG) || defined(XFS_WARN)
+ gc->cpu = cpu;
+#endif
init_llist_head(&gc->list);
gc->items = 0;
INIT_DELAYED_WORK(&gc->work, xfs_inodegc_worker);
diff --git a/include/asm-generic/fb.h b/include/asm-generic/fb.h
index f9f18101ed36..bb7ee9c70e60 100644
--- a/include/asm-generic/fb.h
+++ b/include/asm-generic/fb.h
@@ -1,13 +1,135 @@
/* SPDX-License-Identifier: GPL-2.0 */
+
#ifndef __ASM_GENERIC_FB_H_
#define __ASM_GENERIC_FB_H_
-#include <linux/fb.h>
-#define fb_pgprotect(...) do {} while (0)
+/*
+ * Only include this header file from your architecture's <asm/fb.h>.
+ */
+
+#include <linux/io.h>
+#include <linux/mm_types.h>
+#include <linux/pgtable.h>
+
+struct fb_info;
+struct file;
+
+#ifndef fb_pgprotect
+#define fb_pgprotect fb_pgprotect
+static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
+ unsigned long off)
+{
+ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+}
+#endif
+#ifndef fb_is_primary_device
+#define fb_is_primary_device fb_is_primary_device
static inline int fb_is_primary_device(struct fb_info *info)
{
return 0;
}
+#endif
+
+/*
+ * I/O helpers for the framebuffer. Prefer these functions over their
+ * regular counterparts. The regular I/O functions provide in-order
+ * access and swap bytes to/from little-endian ordering. Neither is
+ * required for framebuffers. Instead, the helpers read and write
+ * raw framebuffer data. Independent operations can be reordered for
+ * improved performance.
+ */
+
+#ifndef fb_readb
+static inline u8 fb_readb(const volatile void __iomem *addr)
+{
+ return __raw_readb(addr);
+}
+#define fb_readb fb_readb
+#endif
+
+#ifndef fb_readw
+static inline u16 fb_readw(const volatile void __iomem *addr)
+{
+ return __raw_readw(addr);
+}
+#define fb_readw fb_readw
+#endif
+
+#ifndef fb_readl
+static inline u32 fb_readl(const volatile void __iomem *addr)
+{
+ return __raw_readl(addr);
+}
+#define fb_readl fb_readl
+#endif
+
+#ifndef fb_readq
+#if defined(__raw_readq)
+static inline u64 fb_readq(const volatile void __iomem *addr)
+{
+ return __raw_readq(addr);
+}
+#define fb_readq fb_readq
+#endif
+#endif
+
+#ifndef fb_writeb
+static inline void fb_writeb(u8 b, volatile void __iomem *addr)
+{
+ __raw_writeb(b, addr);
+}
+#define fb_writeb fb_writeb
+#endif
+
+#ifndef fb_writew
+static inline void fb_writew(u16 b, volatile void __iomem *addr)
+{
+ __raw_writew(b, addr);
+}
+#define fb_writew fb_writew
+#endif
+
+#ifndef fb_writel
+static inline void fb_writel(u32 b, volatile void __iomem *addr)
+{
+ __raw_writel(b, addr);
+}
+#define fb_writel fb_writel
+#endif
+
+#ifndef fb_writeq
+#if defined(__raw_writeq)
+static inline void fb_writeq(u64 b, volatile void __iomem *addr)
+{
+ __raw_writeq(b, addr);
+}
+#define fb_writeq fb_writeq
+#endif
+#endif
+
+#ifndef fb_memcpy_fromio
+static inline void fb_memcpy_fromio(void *to, const volatile void __iomem *from, size_t n)
+{
+ memcpy_fromio(to, from, n);
+}
+#define fb_memcpy_fromio fb_memcpy_fromio
+#endif
+
+#ifndef fb_memcpy_toio
+static inline void fb_memcpy_toio(volatile void __iomem *to, const void *from, size_t n)
+{
+ memcpy_toio(to, from, n);
+}
+#define fb_memcpy_toio fb_memcpy_toio
+#endif
+
+#ifndef fb_memset
+static inline void fb_memset_io(volatile void __iomem *addr, int c, size_t n)
+{
+ memset_io(addr, c, n);
+}
+#define fb_memset fb_memset_io
+#endif
#endif /* __ASM_GENERIC_FB_H_ */
diff --git a/include/drm/bridge/samsung-dsim.h b/include/drm/bridge/samsung-dsim.h
index ba5484de2b30..6a37d1e079bf 100644
--- a/include/drm/bridge/samsung-dsim.h
+++ b/include/drm/bridge/samsung-dsim.h
@@ -95,6 +95,8 @@ struct samsung_dsim {
u32 mode_flags;
u32 format;
+ bool swap_dn_dp_clk;
+ bool swap_dn_dp_data;
int state;
struct drm_property *brightness;
struct completion completed;
diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h
index 358db4a9f167..b046f79f4744 100644
--- a/include/drm/display/drm_dp.h
+++ b/include/drm/display/drm_dp.h
@@ -286,9 +286,8 @@
#define DP_DSC_MAX_BITS_PER_PIXEL_HI 0x068 /* eDP 1.4 */
# define DP_DSC_MAX_BITS_PER_PIXEL_HI_MASK (0x3 << 0)
-# define DP_DSC_MAX_BITS_PER_PIXEL_HI_SHIFT 8
-# define DP_DSC_MAX_BPP_DELTA_VERSION_MASK 0x06
-# define DP_DSC_MAX_BPP_DELTA_AVAILABILITY 0x08
+# define DP_DSC_MAX_BPP_DELTA_VERSION_MASK (0x3 << 5) /* eDP 1.5 & DP 2.0 */
+# define DP_DSC_MAX_BPP_DELTA_AVAILABILITY (1 << 7) /* eDP 1.5 & DP 2.0 */
#define DP_DSC_DEC_COLOR_FORMAT_CAP 0x069
# define DP_DSC_RGB (1 << 0)
@@ -983,6 +982,7 @@
#define DP_EDP_GENERAL_CAP_2 0x703
# define DP_EDP_OVERDRIVE_ENGINE_ENABLED (1 << 0)
+# define DP_EDP_PANEL_LUMINANCE_CONTROL_CAPABLE (1 << 4)
#define DP_EDP_GENERAL_CAP_3 0x704 /* eDP 1.4 */
# define DP_EDP_X_REGION_CAP_MASK (0xf << 0)
@@ -1008,6 +1008,7 @@
# define DP_EDP_DYNAMIC_BACKLIGHT_ENABLE (1 << 4)
# define DP_EDP_REGIONAL_BACKLIGHT_ENABLE (1 << 5)
# define DP_EDP_UPDATE_REGION_BRIGHTNESS (1 << 6) /* eDP 1.4 */
+# define DP_EDP_PANEL_LUMINANCE_CONTROL_ENABLE (1 << 7)
#define DP_EDP_BACKLIGHT_BRIGHTNESS_MSB 0x722
#define DP_EDP_BACKLIGHT_BRIGHTNESS_LSB 0x723
@@ -1032,6 +1033,7 @@
#define DP_EDP_DBC_MINIMUM_BRIGHTNESS_SET 0x732
#define DP_EDP_DBC_MAXIMUM_BRIGHTNESS_SET 0x733
+#define DP_EDP_PANEL_TARGET_LUMINANCE_VALUE 0x734
#define DP_EDP_REGIONAL_BACKLIGHT_BASE 0x740 /* eDP 1.4 */
#define DP_EDP_REGIONAL_BACKLIGHT_0 0x741 /* eDP 1.4 */
diff --git a/include/drm/display/drm_dp_helper.h b/include/drm/display/drm_dp_helper.h
index 533d3ee7fe05..86f24a759268 100644
--- a/include/drm/display/drm_dp_helper.h
+++ b/include/drm/display/drm_dp_helper.h
@@ -181,9 +181,8 @@ static inline u16
drm_edp_dsc_sink_output_bpp(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE])
{
return dsc_dpcd[DP_DSC_MAX_BITS_PER_PIXEL_LOW - DP_DSC_SUPPORT] |
- (dsc_dpcd[DP_DSC_MAX_BITS_PER_PIXEL_HI - DP_DSC_SUPPORT] &
- DP_DSC_MAX_BITS_PER_PIXEL_HI_MASK <<
- DP_DSC_MAX_BITS_PER_PIXEL_HI_SHIFT);
+ ((dsc_dpcd[DP_DSC_MAX_BITS_PER_PIXEL_HI - DP_DSC_SUPPORT] &
+ DP_DSC_MAX_BITS_PER_PIXEL_HI_MASK) << 8);
}
static inline u32
diff --git a/include/drm/drm_aperture.h b/include/drm/drm_aperture.h
index 7096703c3949..cbe33b49fd5d 100644
--- a/include/drm/drm_aperture.h
+++ b/include/drm/drm_aperture.h
@@ -13,14 +13,13 @@ int devm_aperture_acquire_from_firmware(struct drm_device *dev, resource_size_t
resource_size_t size);
int drm_aperture_remove_conflicting_framebuffers(resource_size_t base, resource_size_t size,
- bool primary, const struct drm_driver *req_driver);
+ const struct drm_driver *req_driver);
int drm_aperture_remove_conflicting_pci_framebuffers(struct pci_dev *pdev,
const struct drm_driver *req_driver);
/**
* drm_aperture_remove_framebuffers - remove all existing framebuffers
- * @primary: also kick vga16fb if present
* @req_driver: requesting DRM driver
*
* This function removes all graphics device drivers. Use this function on systems
@@ -30,9 +29,9 @@ int drm_aperture_remove_conflicting_pci_framebuffers(struct pci_dev *pdev,
* 0 on success, or a negative errno code otherwise
*/
static inline int
-drm_aperture_remove_framebuffers(bool primary, const struct drm_driver *req_driver)
+drm_aperture_remove_framebuffers(const struct drm_driver *req_driver)
{
- return drm_aperture_remove_conflicting_framebuffers(0, (resource_size_t)-1, primary,
+ return drm_aperture_remove_conflicting_framebuffers(0, (resource_size_t)-1,
req_driver);
}
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 7b5048516185..e6478fafa6b0 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -199,6 +199,11 @@ enum drm_connector_tv_mode {
*/
DRM_MODE_TV_MODE_SECAM,
+ /**
+ * @DRM_MODE_TV_MODE_MAX: Number of analog TV output modes.
+ *
+ * Internal implementation detail; this is not uABI.
+ */
DRM_MODE_TV_MODE_MAX,
};
diff --git a/include/drm/drm_fixed.h b/include/drm/drm_fixed.h
index 255645c1f9a8..6ea339d5de08 100644
--- a/include/drm/drm_fixed.h
+++ b/include/drm/drm_fixed.h
@@ -71,6 +71,7 @@ static inline u32 dfixed_div(fixed20_12 A, fixed20_12 B)
}
#define DRM_FIXED_POINT 32
+#define DRM_FIXED_POINT_HALF 16
#define DRM_FIXED_ONE (1ULL << DRM_FIXED_POINT)
#define DRM_FIXED_DECIMAL_MASK (DRM_FIXED_ONE - 1)
#define DRM_FIXED_DIGITS_MASK (~DRM_FIXED_DECIMAL_MASK)
@@ -87,6 +88,11 @@ static inline int drm_fixp2int(s64 a)
return ((s64)a) >> DRM_FIXED_POINT;
}
+static inline int drm_fixp2int_round(s64 a)
+{
+ return drm_fixp2int(a + (1 << (DRM_FIXED_POINT_HALF - 1)));
+}
+
static inline int drm_fixp2int_ceil(s64 a)
{
if (a > 0)
diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h
index c0586d832260..e95b4837e5a3 100644
--- a/include/drm/gpu_scheduler.h
+++ b/include/drm/gpu_scheduler.h
@@ -201,7 +201,7 @@ struct drm_sched_entity {
* by the scheduler thread, can be accessed locklessly from
* drm_sched_job_arm() iff the queue is empty.
*/
- struct dma_fence *last_scheduled;
+ struct dma_fence __rcu *last_scheduled;
/**
* @last_user: last group leader pushing a job into the entity.
@@ -549,7 +549,7 @@ void drm_sched_entity_modify_sched(struct drm_sched_entity *entity,
unsigned int num_sched_list);
void drm_sched_job_cleanup(struct drm_sched_job *job);
-void drm_sched_wakeup(struct drm_gpu_scheduler *sched);
+void drm_sched_wakeup_if_can_queue(struct drm_gpu_scheduler *sched);
void drm_sched_stop(struct drm_gpu_scheduler *sched, struct drm_sched_job *bad);
void drm_sched_start(struct drm_gpu_scheduler *sched, bool full_recovery);
void drm_sched_resubmit_jobs(struct drm_gpu_scheduler *sched);
@@ -581,6 +581,7 @@ void drm_sched_entity_push_job(struct drm_sched_job *sched_job);
void drm_sched_entity_set_priority(struct drm_sched_entity *entity,
enum drm_sched_priority priority);
bool drm_sched_entity_is_ready(struct drm_sched_entity *entity);
+int drm_sched_entity_error(struct drm_sched_entity *entity);
void drm_sched_fence_set_parent(struct drm_sched_fence *s_fence,
struct dma_fence *fence);
@@ -591,7 +592,7 @@ void drm_sched_fence_init(struct drm_sched_fence *fence,
void drm_sched_fence_free(struct drm_sched_fence *fence);
void drm_sched_fence_scheduled(struct drm_sched_fence *fence);
-void drm_sched_fence_finished(struct drm_sched_fence *fence);
+void drm_sched_fence_finished(struct drm_sched_fence *fence, int result);
unsigned long drm_sched_suspend_timeout(struct drm_gpu_scheduler *sched);
void drm_sched_resume_timeout(struct drm_gpu_scheduler *sched,
diff --git a/include/drm/i915_component.h b/include/drm/i915_component.h
index c1e2a43d2d1e..56a84ee1c64c 100644
--- a/include/drm/i915_component.h
+++ b/include/drm/i915_component.h
@@ -29,7 +29,8 @@
enum i915_component_type {
I915_COMPONENT_AUDIO = 1,
I915_COMPONENT_HDCP,
- I915_COMPONENT_PXP
+ I915_COMPONENT_PXP,
+ I915_COMPONENT_GSC_PROXY,
};
/* MAX_PORT is the number of port
diff --git a/include/drm/i915_gsc_proxy_mei_interface.h b/include/drm/i915_gsc_proxy_mei_interface.h
new file mode 100644
index 000000000000..9462341d3ae1
--- /dev/null
+++ b/include/drm/i915_gsc_proxy_mei_interface.h
@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright (c) 2022-2023 Intel Corporation
+ */
+
+#ifndef _I915_GSC_PROXY_MEI_INTERFACE_H_
+#define _I915_GSC_PROXY_MEI_INTERFACE_H_
+
+#include <linux/types.h>
+
+struct device;
+struct module;
+
+/**
+ * struct i915_gsc_proxy_component_ops - ops for GSC Proxy services.
+ * @owner: Module providing the ops
+ * @send: sends a proxy message from GSC FW to ME FW
+ * @recv: receives a proxy message for GSC FW from ME FW
+ */
+struct i915_gsc_proxy_component_ops {
+ struct module *owner;
+
+ /**
+ * send - Sends a proxy message to ME FW.
+ * @dev: device struct corresponding to the mei device
+ * @buf: message buffer to send
+ * @size: size of the message
+ * Return: bytes sent on success, negative errno value on failure
+ */
+ int (*send)(struct device *dev, const void *buf, size_t size);
+
+ /**
+ * recv - Receives a proxy message from ME FW.
+ * @dev: device struct corresponding to the mei device
+ * @buf: message buffer to contain the received message
+ * @size: size of the buffer
+ * Return: bytes received on success, negative errno value on failure
+ */
+ int (*recv)(struct device *dev, void *buf, size_t size);
+};
+
+/**
+ * struct i915_gsc_proxy_component - Used for communication between i915 and
+ * MEI drivers for GSC proxy services
+ * @mei_dev: device that provide the GSC proxy service.
+ * @ops: Ops implemented by GSC proxy driver, used by i915 driver.
+ */
+struct i915_gsc_proxy_component {
+ struct device *mei_dev;
+ const struct i915_gsc_proxy_component_ops *ops;
+};
+
+#endif /* _I915_GSC_PROXY_MEI_INTERFACE_H_ */
diff --git a/include/drm/ttm/ttm_device.h b/include/drm/ttm/ttm_device.h
index 56e82ba2d046..c22f30535c84 100644
--- a/include/drm/ttm/ttm_device.h
+++ b/include/drm/ttm/ttm_device.h
@@ -223,7 +223,7 @@ struct ttm_device {
* @funcs: Function table for the device.
* Constant after bo device init
*/
- struct ttm_device_funcs *funcs;
+ const struct ttm_device_funcs *funcs;
/**
* @sysman: Resource manager for the system domain.
@@ -287,7 +287,7 @@ static inline void ttm_set_driver_manager(struct ttm_device *bdev, int type,
bdev->man_drv[type] = manager;
}
-int ttm_device_init(struct ttm_device *bdev, struct ttm_device_funcs *funcs,
+int ttm_device_init(struct ttm_device *bdev, const struct ttm_device_funcs *funcs,
struct device *dev, struct address_space *mapping,
struct drm_vma_offset_manager *vma_manager,
bool use_dma_alloc, bool use_dma32);
diff --git a/include/linux/aperture.h b/include/linux/aperture.h
index 442f15a57cad..1a9a88b11584 100644
--- a/include/linux/aperture.h
+++ b/include/linux/aperture.h
@@ -14,7 +14,9 @@ int devm_aperture_acquire_for_platform_device(struct platform_device *pdev,
resource_size_t size);
int aperture_remove_conflicting_devices(resource_size_t base, resource_size_t size,
- bool primary, const char *name);
+ const char *name);
+
+int __aperture_remove_legacy_vga_devices(struct pci_dev *pdev);
int aperture_remove_conflicting_pci_devices(struct pci_dev *pdev, const char *name);
#else
@@ -26,7 +28,12 @@ static inline int devm_aperture_acquire_for_platform_device(struct platform_devi
}
static inline int aperture_remove_conflicting_devices(resource_size_t base, resource_size_t size,
- bool primary, const char *name)
+ const char *name)
+{
+ return 0;
+}
+
+static inline int __aperture_remove_legacy_vga_devices(struct pci_dev *pdev)
{
return 0;
}
@@ -39,7 +46,6 @@ static inline int aperture_remove_conflicting_pci_devices(struct pci_dev *pdev,
/**
* aperture_remove_all_conflicting_devices - remove all existing framebuffers
- * @primary: also kick vga16fb if present; only relevant for VGA devices
* @name: a descriptive name of the requesting driver
*
* This function removes all graphics device drivers. Use this function on systems
@@ -48,9 +54,9 @@ static inline int aperture_remove_conflicting_pci_devices(struct pci_dev *pdev,
* Returns:
* 0 on success, or a negative errno code otherwise
*/
-static inline int aperture_remove_all_conflicting_devices(bool primary, const char *name)
+static inline int aperture_remove_all_conflicting_devices(const char *name)
{
- return aperture_remove_conflicting_devices(0, (resource_size_t)-1, primary, name);
+ return aperture_remove_conflicting_devices(0, (resource_size_t)-1, name);
}
#endif
diff --git a/include/linux/dim.h b/include/linux/dim.h
index 6c5733981563..f343bc9aa2ec 100644
--- a/include/linux/dim.h
+++ b/include/linux/dim.h
@@ -236,8 +236,9 @@ void dim_park_tired(struct dim *dim);
*
* Calculate the delta between two samples (in data rates).
* Takes into consideration counter wrap-around.
+ * Returned boolean indicates whether curr_stats are reliable.
*/
-void dim_calc_stats(struct dim_sample *start, struct dim_sample *end,
+bool dim_calc_stats(struct dim_sample *start, struct dim_sample *end,
struct dim_stats *curr_stats);
/**
diff --git a/include/linux/fb.h b/include/linux/fb.h
index 08cb47da71f8..2cf8efcb9e32 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -15,7 +15,8 @@
#include <linux/list.h>
#include <linux/backlight.h>
#include <linux/slab.h>
-#include <asm/io.h>
+
+#include <asm/fb.h>
struct vm_area_struct;
struct fb_info;
@@ -511,58 +512,6 @@ struct fb_info {
*/
#define STUPID_ACCELF_TEXT_SHIT
-// This will go away
-#if defined(__sparc__)
-
-/* We map all of our framebuffers such that big-endian accesses
- * are what we want, so the following is sufficient.
- */
-
-// This will go away
-#define fb_readb sbus_readb
-#define fb_readw sbus_readw
-#define fb_readl sbus_readl
-#define fb_readq sbus_readq
-#define fb_writeb sbus_writeb
-#define fb_writew sbus_writew
-#define fb_writel sbus_writel
-#define fb_writeq sbus_writeq
-#define fb_memset sbus_memset_io
-#define fb_memcpy_fromfb sbus_memcpy_fromio
-#define fb_memcpy_tofb sbus_memcpy_toio
-
-#elif defined(__i386__) || defined(__alpha__) || defined(__x86_64__) || \
- defined(__hppa__) || defined(__sh__) || defined(__powerpc__) || \
- defined(__arm__) || defined(__aarch64__) || defined(__mips__)
-
-#define fb_readb __raw_readb
-#define fb_readw __raw_readw
-#define fb_readl __raw_readl
-#define fb_readq __raw_readq
-#define fb_writeb __raw_writeb
-#define fb_writew __raw_writew
-#define fb_writel __raw_writel
-#define fb_writeq __raw_writeq
-#define fb_memset memset_io
-#define fb_memcpy_fromfb memcpy_fromio
-#define fb_memcpy_tofb memcpy_toio
-
-#else
-
-#define fb_readb(addr) (*(volatile u8 *) (addr))
-#define fb_readw(addr) (*(volatile u16 *) (addr))
-#define fb_readl(addr) (*(volatile u32 *) (addr))
-#define fb_readq(addr) (*(volatile u64 *) (addr))
-#define fb_writeb(b,addr) (*(volatile u8 *) (addr) = (b))
-#define fb_writew(b,addr) (*(volatile u16 *) (addr) = (b))
-#define fb_writel(b,addr) (*(volatile u32 *) (addr) = (b))
-#define fb_writeq(b,addr) (*(volatile u64 *) (addr) = (b))
-#define fb_memset memset
-#define fb_memcpy_fromfb memcpy
-#define fb_memcpy_tofb memcpy
-
-#endif
-
#define FB_LEFT_POS(p, bpp) (fb_be_math(p) ? (32 - (bpp)) : 0)
#define FB_SHIFT_HIGH(p, val, bits) (fb_be_math(p) ? (val) >> (bits) : \
(val) << (bits))
@@ -576,9 +525,19 @@ struct fb_info {
extern int fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var);
extern int fb_pan_display(struct fb_info *info, struct fb_var_screeninfo *var);
extern int fb_blank(struct fb_info *info, int blank);
+
+/*
+ * Drawing operations where framebuffer is in I/O memory
+ */
+
extern void cfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
extern void cfb_copyarea(struct fb_info *info, const struct fb_copyarea *area);
extern void cfb_imageblit(struct fb_info *info, const struct fb_image *image);
+extern ssize_t fb_io_read(struct fb_info *info, char __user *buf,
+ size_t count, loff_t *ppos);
+extern ssize_t fb_io_write(struct fb_info *info, const char __user *buf,
+ size_t count, loff_t *ppos);
+
/*
* Drawing operations where framebuffer is in system RAM
*/
diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
index 0f40f379d75c..6ba71957851e 100644
--- a/include/linux/if_vlan.h
+++ b/include/linux/if_vlan.h
@@ -637,6 +637,23 @@ static inline __be16 vlan_get_protocol(const struct sk_buff *skb)
return __vlan_get_protocol(skb, skb->protocol, NULL);
}
+/* This version of __vlan_get_protocol() also pulls mac header in skb->head */
+static inline __be16 vlan_get_protocol_and_depth(struct sk_buff *skb,
+ __be16 type, int *depth)
+{
+ int maclen;
+
+ type = __vlan_get_protocol(skb, type, &maclen);
+
+ if (type) {
+ if (!pskb_may_pull(skb, maclen))
+ type = 0;
+ else if (depth)
+ *depth = maclen;
+ }
+ return type;
+}
+
/* A getter for the SKB protocol field which will handle VLAN tags consistently
* whether VLAN acceleration is enabled or not.
*/
diff --git a/include/linux/io_uring.h b/include/linux/io_uring.h
index 3399d979ee1c..7fe31b2cd02f 100644
--- a/include/linux/io_uring.h
+++ b/include/linux/io_uring.h
@@ -36,6 +36,11 @@ struct io_uring_cmd {
u8 pdu[32]; /* available inline for free use */
};
+static inline const void *io_uring_sqe_cmd(const struct io_uring_sqe *sqe)
+{
+ return sqe->cmd;
+}
+
#if defined(CONFIG_IO_URING)
int io_uring_cmd_import_fixed(u64 ubuf, unsigned long len, int rw,
struct iov_iter *iter, void *ioucmd);
@@ -66,11 +71,6 @@ static inline void io_uring_free(struct task_struct *tsk)
if (tsk->io_uring)
__io_uring_free(tsk);
}
-
-static inline const void *io_uring_sqe_cmd(const struct io_uring_sqe *sqe)
-{
- return sqe->cmd;
-}
#else
static inline int io_uring_cmd_import_fixed(u64 ubuf, unsigned long len, int rw,
struct iov_iter *iter, void *ioucmd)
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 45c3d62e616d..95f33dadb2be 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -567,6 +567,7 @@
#define PCI_DEVICE_ID_AMD_19H_M50H_DF_F3 0x166d
#define PCI_DEVICE_ID_AMD_19H_M60H_DF_F3 0x14e3
#define PCI_DEVICE_ID_AMD_19H_M70H_DF_F3 0x14f3
+#define PCI_DEVICE_ID_AMD_19H_M78H_DF_F3 0x12fb
#define PCI_DEVICE_ID_AMD_CNB17H_F3 0x1703
#define PCI_DEVICE_ID_AMD_LANCE 0x2000
#define PCI_DEVICE_ID_AMD_LANCE_HOME 0x2001
diff --git a/include/net/bonding.h b/include/net/bonding.h
index a60a24923b55..0efef2a952b7 100644
--- a/include/net/bonding.h
+++ b/include/net/bonding.h
@@ -233,7 +233,7 @@ struct bonding {
*/
spinlock_t mode_lock;
spinlock_t stats_lock;
- u8 send_peer_notif;
+ u32 send_peer_notif;
u8 igmp_retrans;
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *proc_entry;
diff --git a/include/net/sock.h b/include/net/sock.h
index 8b7ed7167243..656ea89f60ff 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -2718,7 +2718,7 @@ static inline void sock_recv_cmsgs(struct msghdr *msg, struct sock *sk,
__sock_recv_cmsgs(msg, sk, skb);
else if (unlikely(sock_flag(sk, SOCK_TIMESTAMP)))
sock_write_timestamp(sk, skb->tstamp);
- else if (unlikely(sk->sk_stamp == SK_DEFAULT_STAMP))
+ else if (unlikely(sock_read_timestamp(sk) == SK_DEFAULT_STAMP))
sock_write_timestamp(sk, 0);
}
diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index 46becedf5b2f..43691058d28f 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -834,6 +834,11 @@ struct drm_color_ctm {
/*
* Conversion matrix in S31.32 sign-magnitude
* (not two's complement!) format.
+ *
+ * out matrix in
+ * |R| |0 1 2| |R|
+ * |G| = |3 4 5| x |G|
+ * |B| |6 7 8| |B|
*/
__u64 matrix[9];
};
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index dba7c5a5b25e..f31dfacde601 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -280,7 +280,16 @@ enum drm_i915_pmu_engine_sample {
#define I915_PMU_ENGINE_SEMA(class, instance) \
__I915_PMU_ENGINE(class, instance, I915_SAMPLE_SEMA)
-#define __I915_PMU_OTHER(x) (__I915_PMU_ENGINE(0xff, 0xff, 0xf) + 1 + (x))
+/*
+ * Top 4 bits of every non-engine counter are GT id.
+ */
+#define __I915_PMU_GT_SHIFT (60)
+
+#define ___I915_PMU_OTHER(gt, x) \
+ (((__u64)__I915_PMU_ENGINE(0xff, 0xff, 0xf) + 1 + (x)) | \
+ ((__u64)(gt) << __I915_PMU_GT_SHIFT))
+
+#define __I915_PMU_OTHER(x) ___I915_PMU_OTHER(0, x)
#define I915_PMU_ACTUAL_FREQUENCY __I915_PMU_OTHER(0)
#define I915_PMU_REQUESTED_FREQUENCY __I915_PMU_OTHER(1)
@@ -290,6 +299,12 @@ enum drm_i915_pmu_engine_sample {
#define I915_PMU_LAST /* Deprecated - do not use */ I915_PMU_RC6_RESIDENCY
+#define __I915_PMU_ACTUAL_FREQUENCY(gt) ___I915_PMU_OTHER(gt, 0)
+#define __I915_PMU_REQUESTED_FREQUENCY(gt) ___I915_PMU_OTHER(gt, 1)
+#define __I915_PMU_INTERRUPTS(gt) ___I915_PMU_OTHER(gt, 2)
+#define __I915_PMU_RC6_RESIDENCY(gt) ___I915_PMU_OTHER(gt, 3)
+#define __I915_PMU_SOFTWARE_GT_AWAKE_TIME(gt) ___I915_PMU_OTHER(gt, 4)
+
/* Each region is a minimum of 16k, and there are at most 255 of them.
*/
#define I915_NR_TEX_REGIONS 255 /* table size 2k - maximum due to use
@@ -771,6 +786,25 @@ typedef struct drm_i915_irq_wait {
*/
#define I915_PARAM_OA_TIMESTAMP_FREQUENCY 57
+/*
+ * Query the status of PXP support in i915.
+ *
+ * The query can fail in the following scenarios with the listed error codes:
+ * -ENODEV = PXP support is not available on the GPU device or in the
+ * kernel due to missing component drivers or kernel configs.
+ *
+ * If the IOCTL is successful, the returned parameter will be set to one of
+ * the following values:
+ * 1 = PXP feature is supported and is ready for use.
+ * 2 = PXP feature is supported but should be ready soon (pending
+ * initialization of non-i915 system dependencies).
+ *
+ * NOTE: When param is supported (positive return values), user space should
+ * still refer to the GEM PXP context-creation UAPI header specs to be
+ * aware of possible failure due to system state machine at the time.
+ */
+#define I915_PARAM_PXP_STATUS 58
+
/* Must be kept compact -- no holes and well documented */
/**
@@ -2096,6 +2130,21 @@ struct drm_i915_gem_context_param {
*
* -ENODEV: feature not available
* -EPERM: trying to mark a recoverable or not bannable context as protected
+ * -ENXIO: A dependency such as a component driver or firmware is not yet
+ * loaded so user space may need to attempt again. Depending on the
+ * device, this error may be reported if protected context creation is
+ * attempted very early after kernel start because the internal timeout
+ * waiting for such dependencies is not guaranteed to be larger than
+ * required (numbers differ depending on system and kernel config):
+ * - ADL/RPL: dependencies may take up to 3 seconds from kernel start
+ * while context creation internal timeout is 250 milisecs
+ * - MTL: dependencies may take up to 8 seconds from kernel start
+ * while context creation internal timeout is 250 milisecs
+ * NOTE: such dependencies happen once, so a subsequent call to create a
+ * protected context after a prior successful call will not experience
+ * such timeouts and will not return -ENXIO (unless the driver is reloaded,
+ * or, depending on the device, resumes from a suspended state).
+ * -EIO: The firmware did not succeed in creating the protected context.
*/
#define I915_CONTEXT_PARAM_PROTECTED_CONTENT 0xd
/* Must be kept compact -- no holes and well documented */
diff --git a/drivers/video/fbdev/sticore.h b/include/video/sticore.h
index 0ebdd28a0b81..fbb78d7e7565 100644
--- a/drivers/video/fbdev/sticore.h
+++ b/include/video/sticore.h
@@ -2,6 +2,8 @@
#ifndef STICORE_H
#define STICORE_H
+struct fb_info;
+
/* generic STI structures & functions */
#define MAX_STI_ROMS 4 /* max no. of ROMs which this driver handles */
@@ -27,11 +29,11 @@
*
* Probably the best solution to all this is have the generic code manage
* the screen buffer and a kernel thread to call STI occasionally.
- *
+ *
* Luckily, the frame buffer guys have the same problem so we can just wait
* for them to fix it and steal their solution. prumpf
*/
-
+
#include <asm/io.h>
#define STI_WAIT 1
@@ -56,7 +58,7 @@
/* STI function configuration structs */
typedef union region {
- struct {
+ struct {
u32 offset : 14; /* offset in 4kbyte page */
u32 sys_only : 1; /* don't map to user space */
u32 cache : 1; /* map to data cache */
@@ -154,7 +156,7 @@ struct sti_conf_inptr {
};
struct sti_conf_outptr_ext {
- u32 crt_config[3]; /* hardware specific X11/OGL information */
+ u32 crt_config[3]; /* hardware specific X11/OGL information */
u32 crt_hdw[3];
u32 future_ptr;
};
@@ -211,7 +213,7 @@ struct sti_rom {
u32 set_cm_entry;
u32 dma_ctrl;
u8 res040[7 * 4];
-
+
u32 init_graph_addr;
u32 state_mgmt_addr;
u32 font_unp_addr;
@@ -271,7 +273,7 @@ struct sti_font_flags {
u32 pad : 30; /* pad to word boundary */
u32 future_ptr; /* pointer to future data */
};
-
+
struct sti_font_outptr {
s32 errno; /* error number on failure */
u32 future_ptr; /* pointer to future data */
@@ -338,7 +340,7 @@ struct sti_all_data {
struct sti_struct {
spinlock_t lock;
-
+
/* char **mon_strings; */
int sti_mem_request;
u32 graphics_id[2];
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 68baa8194d9f..db016e418931 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -10150,8 +10150,20 @@ void perf_tp_event(u16 event_type, u64 count, void *record, int entry_size,
perf_trace_buf_update(record, event_type);
hlist_for_each_entry_rcu(event, head, hlist_entry) {
- if (perf_tp_event_match(event, &data, regs))
+ if (perf_tp_event_match(event, &data, regs)) {
perf_swevent_event(event, count, &data, regs);
+
+ /*
+ * Here use the same on-stack perf_sample_data,
+ * some members in data are event-specific and
+ * need to be re-computed for different sweveents.
+ * Re-initialize data->sample_flags safely to avoid
+ * the problem that next event skips preparing data
+ * because data->sample_flags is set.
+ */
+ perf_sample_data_init(&data, 0, 0);
+ perf_sample_save_raw_data(&data, &raw);
+ }
}
/*
diff --git a/kernel/locking/rwsem.c b/kernel/locking/rwsem.c
index acb5a50309a1..9eabd585ce7a 100644
--- a/kernel/locking/rwsem.c
+++ b/kernel/locking/rwsem.c
@@ -1240,7 +1240,7 @@ static struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem)
/*
* lock for reading
*/
-static inline int __down_read_common(struct rw_semaphore *sem, int state)
+static __always_inline int __down_read_common(struct rw_semaphore *sem, int state)
{
int ret = 0;
long count;
@@ -1258,17 +1258,17 @@ out:
return ret;
}
-static inline void __down_read(struct rw_semaphore *sem)
+static __always_inline void __down_read(struct rw_semaphore *sem)
{
__down_read_common(sem, TASK_UNINTERRUPTIBLE);
}
-static inline int __down_read_interruptible(struct rw_semaphore *sem)
+static __always_inline int __down_read_interruptible(struct rw_semaphore *sem)
{
return __down_read_common(sem, TASK_INTERRUPTIBLE);
}
-static inline int __down_read_killable(struct rw_semaphore *sem)
+static __always_inline int __down_read_killable(struct rw_semaphore *sem)
{
return __down_read_common(sem, TASK_KILLABLE);
}
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 944c3ae39861..a68d1276bab0 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -11492,7 +11492,7 @@ void call_trace_sched_update_nr_running(struct rq *rq, int count)
#ifdef CONFIG_SCHED_MM_CID
-/**
+/*
* @cid_lock: Guarantee forward-progress of cid allocation.
*
* Concurrency ID allocation within a bitmap is mostly lock-free. The cid_lock
@@ -11501,7 +11501,7 @@ void call_trace_sched_update_nr_running(struct rq *rq, int count)
*/
DEFINE_RAW_SPINLOCK(cid_lock);
-/**
+/*
* @use_cid_lock: Select cid allocation behavior: lock-free vs spinlock.
*
* When @use_cid_lock is 0, the cid allocation is lock-free. When contention is
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c
index 93bf2b4e47e5..771d1e040303 100644
--- a/kernel/time/tick-broadcast.c
+++ b/kernel/time/tick-broadcast.c
@@ -35,14 +35,15 @@ static __cacheline_aligned_in_smp DEFINE_RAW_SPINLOCK(tick_broadcast_lock);
#ifdef CONFIG_TICK_ONESHOT
static DEFINE_PER_CPU(struct clock_event_device *, tick_oneshot_wakeup_device);
-static void tick_broadcast_setup_oneshot(struct clock_event_device *bc);
+static void tick_broadcast_setup_oneshot(struct clock_event_device *bc, bool from_periodic);
static void tick_broadcast_clear_oneshot(int cpu);
static void tick_resume_broadcast_oneshot(struct clock_event_device *bc);
# ifdef CONFIG_HOTPLUG_CPU
static void tick_broadcast_oneshot_offline(unsigned int cpu);
# endif
#else
-static inline void tick_broadcast_setup_oneshot(struct clock_event_device *bc) { BUG(); }
+static inline void
+tick_broadcast_setup_oneshot(struct clock_event_device *bc, bool from_periodic) { BUG(); }
static inline void tick_broadcast_clear_oneshot(int cpu) { }
static inline void tick_resume_broadcast_oneshot(struct clock_event_device *bc) { }
# ifdef CONFIG_HOTPLUG_CPU
@@ -264,7 +265,7 @@ int tick_device_uses_broadcast(struct clock_event_device *dev, int cpu)
if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC)
tick_broadcast_start_periodic(bc);
else
- tick_broadcast_setup_oneshot(bc);
+ tick_broadcast_setup_oneshot(bc, false);
ret = 1;
} else {
/*
@@ -500,7 +501,7 @@ void tick_broadcast_control(enum tick_broadcast_mode mode)
if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC)
tick_broadcast_start_periodic(bc);
else
- tick_broadcast_setup_oneshot(bc);
+ tick_broadcast_setup_oneshot(bc, false);
}
}
out:
@@ -1020,48 +1021,101 @@ static inline ktime_t tick_get_next_period(void)
/**
* tick_broadcast_setup_oneshot - setup the broadcast device
*/
-static void tick_broadcast_setup_oneshot(struct clock_event_device *bc)
+static void tick_broadcast_setup_oneshot(struct clock_event_device *bc,
+ bool from_periodic)
{
int cpu = smp_processor_id();
+ ktime_t nexttick = 0;
if (!bc)
return;
- /* Set it up only once ! */
- if (bc->event_handler != tick_handle_oneshot_broadcast) {
- int was_periodic = clockevent_state_periodic(bc);
-
- bc->event_handler = tick_handle_oneshot_broadcast;
-
+ /*
+ * When the broadcast device was switched to oneshot by the first
+ * CPU handling the NOHZ change, the other CPUs will reach this
+ * code via hrtimer_run_queues() -> tick_check_oneshot_change()
+ * too. Set up the broadcast device only once!
+ */
+ if (bc->event_handler == tick_handle_oneshot_broadcast) {
/*
- * We must be careful here. There might be other CPUs
- * waiting for periodic broadcast. We need to set the
- * oneshot_mask bits for those and program the
- * broadcast device to fire.
+ * The CPU which switched from periodic to oneshot mode
+ * set the broadcast oneshot bit for all other CPUs which
+ * are in the general (periodic) broadcast mask to ensure
+ * that CPUs which wait for the periodic broadcast are
+ * woken up.
+ *
+ * Clear the bit for the local CPU as the set bit would
+ * prevent the first tick_broadcast_enter() after this CPU
+ * switched to oneshot state to program the broadcast
+ * device.
+ *
+ * This code can also be reached via tick_broadcast_control(),
+ * but this cannot avoid the tick_broadcast_clear_oneshot()
+ * as that would break the periodic to oneshot transition of
+ * secondary CPUs. But that's harmless as the below only
+ * clears already cleared bits.
*/
+ tick_broadcast_clear_oneshot(cpu);
+ return;
+ }
+
+
+ bc->event_handler = tick_handle_oneshot_broadcast;
+ bc->next_event = KTIME_MAX;
+
+ /*
+ * When the tick mode is switched from periodic to oneshot it must
+ * be ensured that CPUs which are waiting for periodic broadcast
+ * get their wake-up at the next tick. This is achieved by ORing
+ * tick_broadcast_mask into tick_broadcast_oneshot_mask.
+ *
+ * For other callers, e.g. broadcast device replacement,
+ * tick_broadcast_oneshot_mask must not be touched as this would
+ * set bits for CPUs which are already NOHZ, but not idle. Their
+ * next tick_broadcast_enter() would observe the bit set and fail
+ * to update the expiry time and the broadcast event device.
+ */
+ if (from_periodic) {
cpumask_copy(tmpmask, tick_broadcast_mask);
+ /* Remove the local CPU as it is obviously not idle */
cpumask_clear_cpu(cpu, tmpmask);
- cpumask_or(tick_broadcast_oneshot_mask,
- tick_broadcast_oneshot_mask, tmpmask);
+ cpumask_or(tick_broadcast_oneshot_mask, tick_broadcast_oneshot_mask, tmpmask);
- if (was_periodic && !cpumask_empty(tmpmask)) {
- ktime_t nextevt = tick_get_next_period();
+ /*
+ * Ensure that the oneshot broadcast handler will wake the
+ * CPUs which are still waiting for periodic broadcast.
+ */
+ nexttick = tick_get_next_period();
+ tick_broadcast_init_next_event(tmpmask, nexttick);
- clockevents_switch_state(bc, CLOCK_EVT_STATE_ONESHOT);
- tick_broadcast_init_next_event(tmpmask, nextevt);
- tick_broadcast_set_event(bc, cpu, nextevt);
- } else
- bc->next_event = KTIME_MAX;
- } else {
/*
- * The first cpu which switches to oneshot mode sets
- * the bit for all other cpus which are in the general
- * (periodic) broadcast mask. So the bit is set and
- * would prevent the first broadcast enter after this
- * to program the bc device.
+ * If the underlying broadcast clock event device is
+ * already in oneshot state, then there is nothing to do.
+ * The device was already armed for the next tick
+ * in tick_handle_broadcast_periodic()
*/
- tick_broadcast_clear_oneshot(cpu);
+ if (clockevent_state_oneshot(bc))
+ return;
}
+
+ /*
+ * When switching from periodic to oneshot mode arm the broadcast
+ * device for the next tick.
+ *
+ * If the broadcast device has been replaced in oneshot mode and
+ * the oneshot broadcast mask is not empty, then arm it to expire
+ * immediately in order to reevaluate the next expiring timer.
+ * @nexttick is 0 and therefore in the past which will cause the
+ * clockevent code to force an event.
+ *
+ * For both cases the programming can be avoided when the oneshot
+ * broadcast mask is empty.
+ *
+ * tick_broadcast_set_event() implicitly switches the broadcast
+ * device to oneshot state.
+ */
+ if (!cpumask_empty(tick_broadcast_oneshot_mask))
+ tick_broadcast_set_event(bc, cpu, nexttick);
}
/*
@@ -1070,14 +1124,16 @@ static void tick_broadcast_setup_oneshot(struct clock_event_device *bc)
void tick_broadcast_switch_to_oneshot(void)
{
struct clock_event_device *bc;
+ enum tick_device_mode oldmode;
unsigned long flags;
raw_spin_lock_irqsave(&tick_broadcast_lock, flags);
+ oldmode = tick_broadcast_device.mode;
tick_broadcast_device.mode = TICKDEV_MODE_ONESHOT;
bc = tick_broadcast_device.evtdev;
if (bc)
- tick_broadcast_setup_oneshot(bc);
+ tick_broadcast_setup_oneshot(bc, oldmode == TICKDEV_MODE_PERIODIC);
raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
}
diff --git a/lib/dim/dim.c b/lib/dim/dim.c
index 38045d6d0538..e89aaf07bde5 100644
--- a/lib/dim/dim.c
+++ b/lib/dim/dim.c
@@ -54,7 +54,7 @@ void dim_park_tired(struct dim *dim)
}
EXPORT_SYMBOL(dim_park_tired);
-void dim_calc_stats(struct dim_sample *start, struct dim_sample *end,
+bool dim_calc_stats(struct dim_sample *start, struct dim_sample *end,
struct dim_stats *curr_stats)
{
/* u32 holds up to 71 minutes, should be enough */
@@ -66,7 +66,7 @@ void dim_calc_stats(struct dim_sample *start, struct dim_sample *end,
start->comp_ctr);
if (!delta_us)
- return;
+ return false;
curr_stats->ppms = DIV_ROUND_UP(npkts * USEC_PER_MSEC, delta_us);
curr_stats->bpms = DIV_ROUND_UP(nbytes * USEC_PER_MSEC, delta_us);
@@ -79,5 +79,6 @@ void dim_calc_stats(struct dim_sample *start, struct dim_sample *end,
else
curr_stats->cpe_ratio = 0;
+ return true;
}
EXPORT_SYMBOL(dim_calc_stats);
diff --git a/lib/dim/net_dim.c b/lib/dim/net_dim.c
index 53f6b9c6e936..4e32f7aaac86 100644
--- a/lib/dim/net_dim.c
+++ b/lib/dim/net_dim.c
@@ -227,7 +227,8 @@ void net_dim(struct dim *dim, struct dim_sample end_sample)
dim->start_sample.event_ctr);
if (nevents < DIM_NEVENTS)
break;
- dim_calc_stats(&dim->start_sample, &end_sample, &curr_stats);
+ if (!dim_calc_stats(&dim->start_sample, &end_sample, &curr_stats))
+ break;
if (net_dim_decision(&curr_stats, dim)) {
dim->state = DIM_APPLY_NEW_PROFILE;
schedule_work(&dim->work);
diff --git a/lib/dim/rdma_dim.c b/lib/dim/rdma_dim.c
index 15462d54758d..88f779486707 100644
--- a/lib/dim/rdma_dim.c
+++ b/lib/dim/rdma_dim.c
@@ -88,7 +88,8 @@ void rdma_dim(struct dim *dim, u64 completions)
nevents = curr_sample->event_ctr - dim->start_sample.event_ctr;
if (nevents < DIM_NEVENTS)
break;
- dim_calc_stats(&dim->start_sample, curr_sample, &curr_stats);
+ if (!dim_calc_stats(&dim->start_sample, curr_sample, &curr_stats))
+ break;
if (rdma_dim_decision(&curr_stats, dim)) {
dim->state = DIM_APPLY_NEW_PROFILE;
schedule_work(&dim->work);
diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c
index 57744704ff69..84d6dd5e5b1a 100644
--- a/net/bridge/br_forward.c
+++ b/net/bridge/br_forward.c
@@ -42,7 +42,7 @@ int br_dev_queue_push_xmit(struct net *net, struct sock *sk, struct sk_buff *skb
eth_type_vlan(skb->protocol)) {
int depth;
- if (!__vlan_get_protocol(skb, skb->protocol, &depth))
+ if (!vlan_get_protocol_and_depth(skb, skb->protocol, &depth))
goto drop;
skb_set_network_header(skb, depth);
diff --git a/net/core/datagram.c b/net/core/datagram.c
index 5662dff3d381..176eb5834746 100644
--- a/net/core/datagram.c
+++ b/net/core/datagram.c
@@ -807,18 +807,21 @@ __poll_t datagram_poll(struct file *file, struct socket *sock,
{
struct sock *sk = sock->sk;
__poll_t mask;
+ u8 shutdown;
sock_poll_wait(file, sock, wait);
mask = 0;
/* exceptional events? */
- if (sk->sk_err || !skb_queue_empty_lockless(&sk->sk_error_queue))
+ if (READ_ONCE(sk->sk_err) ||
+ !skb_queue_empty_lockless(&sk->sk_error_queue))
mask |= EPOLLERR |
(sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? EPOLLPRI : 0);
- if (sk->sk_shutdown & RCV_SHUTDOWN)
+ shutdown = READ_ONCE(sk->sk_shutdown);
+ if (shutdown & RCV_SHUTDOWN)
mask |= EPOLLRDHUP | EPOLLIN | EPOLLRDNORM;
- if (sk->sk_shutdown == SHUTDOWN_MASK)
+ if (shutdown == SHUTDOWN_MASK)
mask |= EPOLLHUP;
/* readable? */
@@ -827,10 +830,12 @@ __poll_t datagram_poll(struct file *file, struct socket *sock,
/* Connection-based need to check for termination and startup */
if (connection_based(sk)) {
- if (sk->sk_state == TCP_CLOSE)
+ int state = READ_ONCE(sk->sk_state);
+
+ if (state == TCP_CLOSE)
mask |= EPOLLHUP;
/* connection hasn't started yet? */
- if (sk->sk_state == TCP_SYN_SENT)
+ if (state == TCP_SYN_SENT)
return mask;
}
diff --git a/net/core/dev.c b/net/core/dev.c
index 735096d42c1d..b3c13e041935 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3335,7 +3335,7 @@ __be16 skb_network_protocol(struct sk_buff *skb, int *depth)
type = eth->h_proto;
}
- return __vlan_get_protocol(skb, type, depth);
+ return vlan_get_protocol_and_depth(skb, type, depth);
}
/* openvswitch calls this on rx path, so we need a different check.
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 26a586007d8b..515ec5cdc79c 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -5298,7 +5298,7 @@ bool skb_partial_csum_set(struct sk_buff *skb, u16 start, u16 off)
u32 csum_end = (u32)start + (u32)off + sizeof(__sum16);
u32 csum_start = skb_headroom(skb) + (u32)start;
- if (unlikely(csum_start > U16_MAX || csum_end > skb_headlen(skb))) {
+ if (unlikely(csum_start >= U16_MAX || csum_end > skb_headlen(skb))) {
net_warn_ratelimited("bad partial csum: csum=%u/%u headroom=%u headlen=%u\n",
start, off, skb_headroom(skb), skb_headlen(skb));
return false;
@@ -5306,7 +5306,7 @@ bool skb_partial_csum_set(struct sk_buff *skb, u16 start, u16 off)
skb->ip_summed = CHECKSUM_PARTIAL;
skb->csum_start = csum_start;
skb->csum_offset = off;
- skb_set_transport_header(skb, start);
+ skb->transport_header = csum_start;
return true;
}
EXPORT_SYMBOL_GPL(skb_partial_csum_set);
diff --git a/net/core/stream.c b/net/core/stream.c
index 434446ab14c5..f5c4e47df165 100644
--- a/net/core/stream.c
+++ b/net/core/stream.c
@@ -73,8 +73,8 @@ int sk_stream_wait_connect(struct sock *sk, long *timeo_p)
add_wait_queue(sk_sleep(sk), &wait);
sk->sk_write_pending++;
done = sk_wait_event(sk, timeo_p,
- !sk->sk_err &&
- !((1 << sk->sk_state) &
+ !READ_ONCE(sk->sk_err) &&
+ !((1 << READ_ONCE(sk->sk_state)) &
~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)), &wait);
remove_wait_queue(sk_sleep(sk), &wait);
sk->sk_write_pending--;
@@ -87,9 +87,9 @@ EXPORT_SYMBOL(sk_stream_wait_connect);
* sk_stream_closing - Return 1 if we still have things to send in our buffers.
* @sk: socket to verify
*/
-static inline int sk_stream_closing(struct sock *sk)
+static int sk_stream_closing(const struct sock *sk)
{
- return (1 << sk->sk_state) &
+ return (1 << READ_ONCE(sk->sk_state)) &
(TCPF_FIN_WAIT1 | TCPF_CLOSING | TCPF_LAST_ACK);
}
@@ -142,8 +142,8 @@ int sk_stream_wait_memory(struct sock *sk, long *timeo_p)
set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
sk->sk_write_pending++;
- sk_wait_event(sk, &current_timeo, sk->sk_err ||
- (sk->sk_shutdown & SEND_SHUTDOWN) ||
+ sk_wait_event(sk, &current_timeo, READ_ONCE(sk->sk_err) ||
+ (READ_ONCE(sk->sk_shutdown) & SEND_SHUTDOWN) ||
(sk_stream_memory_free(sk) &&
!vm_wait), &wait);
sk->sk_write_pending--;
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 940062e08f57..c4aab3aacbd8 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -894,7 +894,7 @@ int inet_shutdown(struct socket *sock, int how)
EPOLLHUP, even on eg. unconnected UDP sockets -- RR */
fallthrough;
default:
- sk->sk_shutdown |= how;
+ WRITE_ONCE(sk->sk_shutdown, sk->sk_shutdown | how);
if (sk->sk_prot->shutdown)
sk->sk_prot->shutdown(sk, how);
break;
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 20db115c38c4..4d6392c16b7a 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -498,6 +498,7 @@ __poll_t tcp_poll(struct file *file, struct socket *sock, poll_table *wait)
__poll_t mask;
struct sock *sk = sock->sk;
const struct tcp_sock *tp = tcp_sk(sk);
+ u8 shutdown;
int state;
sock_poll_wait(file, sock, wait);
@@ -540,9 +541,10 @@ __poll_t tcp_poll(struct file *file, struct socket *sock, poll_table *wait)
* NOTE. Check for TCP_CLOSE is added. The goal is to prevent
* blocking on fresh not-connected or disconnected socket. --ANK
*/
- if (sk->sk_shutdown == SHUTDOWN_MASK || state == TCP_CLOSE)
+ shutdown = READ_ONCE(sk->sk_shutdown);
+ if (shutdown == SHUTDOWN_MASK || state == TCP_CLOSE)
mask |= EPOLLHUP;
- if (sk->sk_shutdown & RCV_SHUTDOWN)
+ if (shutdown & RCV_SHUTDOWN)
mask |= EPOLLIN | EPOLLRDNORM | EPOLLRDHUP;
/* Connected or passive Fast Open socket? */
@@ -559,7 +561,7 @@ __poll_t tcp_poll(struct file *file, struct socket *sock, poll_table *wait)
if (tcp_stream_is_readable(sk, target))
mask |= EPOLLIN | EPOLLRDNORM;
- if (!(sk->sk_shutdown & SEND_SHUTDOWN)) {
+ if (!(shutdown & SEND_SHUTDOWN)) {
if (__sk_stream_is_writeable(sk, 1)) {
mask |= EPOLLOUT | EPOLLWRNORM;
} else { /* send SIGIO later */
@@ -2867,7 +2869,7 @@ void __tcp_close(struct sock *sk, long timeout)
int data_was_unread = 0;
int state;
- sk->sk_shutdown = SHUTDOWN_MASK;
+ WRITE_ONCE(sk->sk_shutdown, SHUTDOWN_MASK);
if (sk->sk_state == TCP_LISTEN) {
tcp_set_state(sk, TCP_CLOSE);
@@ -3119,7 +3121,7 @@ int tcp_disconnect(struct sock *sk, int flags)
inet_bhash2_reset_saddr(sk);
- sk->sk_shutdown = 0;
+ WRITE_ONCE(sk->sk_shutdown, 0);
sock_reset_flag(sk, SOCK_DONE);
tp->srtt_us = 0;
tp->mdev_us = jiffies_to_usecs(TCP_TIMEOUT_INIT);
@@ -4649,7 +4651,7 @@ void tcp_done(struct sock *sk)
if (req)
reqsk_fastopen_remove(sk, req, false);
- sk->sk_shutdown = SHUTDOWN_MASK;
+ WRITE_ONCE(sk->sk_shutdown, SHUTDOWN_MASK);
if (!sock_flag(sk, SOCK_DEAD))
sk->sk_state_change(sk);
diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c
index ebf917511937..2e9547467edb 100644
--- a/net/ipv4/tcp_bpf.c
+++ b/net/ipv4/tcp_bpf.c
@@ -168,7 +168,7 @@ static int tcp_msg_wait_data(struct sock *sk, struct sk_psock *psock,
sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
ret = sk_wait_event(sk, &timeo,
!list_empty(&psock->ingress_msg) ||
- !skb_queue_empty(&sk->sk_receive_queue), &wait);
+ !skb_queue_empty_lockless(&sk->sk_receive_queue), &wait);
sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk);
remove_wait_queue(sk_sleep(sk), &wait);
return ret;
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index a057330d6f59..61b6710f337a 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -4362,7 +4362,7 @@ void tcp_fin(struct sock *sk)
inet_csk_schedule_ack(sk);
- sk->sk_shutdown |= RCV_SHUTDOWN;
+ WRITE_ONCE(sk->sk_shutdown, sk->sk_shutdown | RCV_SHUTDOWN);
sock_set_flag(sk, SOCK_DONE);
switch (sk->sk_state) {
@@ -6599,7 +6599,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb)
break;
tcp_set_state(sk, TCP_FIN_WAIT2);
- sk->sk_shutdown |= SEND_SHUTDOWN;
+ WRITE_ONCE(sk->sk_shutdown, sk->sk_shutdown | SEND_SHUTDOWN);
sk_dst_confirm(sk);
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
index da7fe94bea2e..9ffbc667be6c 100644
--- a/net/llc/af_llc.c
+++ b/net/llc/af_llc.c
@@ -583,7 +583,8 @@ static int llc_ui_wait_for_disc(struct sock *sk, long timeout)
add_wait_queue(sk_sleep(sk), &wait);
while (1) {
- if (sk_wait_event(sk, &timeout, sk->sk_state == TCP_CLOSE, &wait))
+ if (sk_wait_event(sk, &timeout,
+ READ_ONCE(sk->sk_state) == TCP_CLOSE, &wait))
break;
rc = -ERESTARTSYS;
if (signal_pending(current))
@@ -603,7 +604,8 @@ static bool llc_ui_wait_for_conn(struct sock *sk, long timeout)
add_wait_queue(sk_sleep(sk), &wait);
while (1) {
- if (sk_wait_event(sk, &timeout, sk->sk_state != TCP_SYN_SENT, &wait))
+ if (sk_wait_event(sk, &timeout,
+ READ_ONCE(sk->sk_state) != TCP_SYN_SENT, &wait))
break;
if (signal_pending(current) || !timeout)
break;
@@ -622,7 +624,7 @@ static int llc_ui_wait_for_busy_core(struct sock *sk, long timeout)
while (1) {
rc = 0;
if (sk_wait_event(sk, &timeout,
- (sk->sk_shutdown & RCV_SHUTDOWN) ||
+ (READ_ONCE(sk->sk_shutdown) & RCV_SHUTDOWN) ||
(!llc_data_accept_state(llc->state) &&
!llc->remote_busy_flag &&
!llc->p_flag), &wait))
diff --git a/net/netfilter/core.c b/net/netfilter/core.c
index f0783e42108b..5f76ae86a656 100644
--- a/net/netfilter/core.c
+++ b/net/netfilter/core.c
@@ -711,9 +711,11 @@ void nf_conntrack_destroy(struct nf_conntrack *nfct)
rcu_read_lock();
ct_hook = rcu_dereference(nf_ct_hook);
- BUG_ON(ct_hook == NULL);
- ct_hook->destroy(nfct);
+ if (ct_hook)
+ ct_hook->destroy(nfct);
rcu_read_unlock();
+
+ WARN_ON(!ct_hook);
}
EXPORT_SYMBOL(nf_conntrack_destroy);
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
index 57f6724c99a7..169e16fc2bce 100644
--- a/net/netfilter/nf_conntrack_standalone.c
+++ b/net/netfilter/nf_conntrack_standalone.c
@@ -1218,11 +1218,12 @@ static int __init nf_conntrack_standalone_init(void)
nf_conntrack_htable_size_user = nf_conntrack_htable_size;
#endif
+ nf_conntrack_init_end();
+
ret = register_pernet_subsys(&nf_conntrack_net_ops);
if (ret < 0)
goto out_pernet;
- nf_conntrack_init_end();
return 0;
out_pernet:
diff --git a/net/netfilter/nft_chain_filter.c b/net/netfilter/nft_chain_filter.c
index c3563f0be269..680fe557686e 100644
--- a/net/netfilter/nft_chain_filter.c
+++ b/net/netfilter/nft_chain_filter.c
@@ -344,6 +344,12 @@ static void nft_netdev_event(unsigned long event, struct net_device *dev,
return;
}
+ /* UNREGISTER events are also happening on netns exit.
+ *
+ * Although nf_tables core releases all tables/chains, only this event
+ * handler provides guarantee that hook->ops.dev is still accessible,
+ * so we cannot skip exiting net namespaces.
+ */
__nft_release_basechain(ctx);
}
@@ -362,9 +368,6 @@ static int nf_tables_netdev_event(struct notifier_block *this,
event != NETDEV_CHANGENAME)
return NOTIFY_DONE;
- if (!check_net(ctx.net))
- return NOTIFY_DONE;
-
nft_net = nft_pernet(ctx.net);
mutex_lock(&nft_net->commit_mutex);
list_for_each_entry(table, &nft_net->tables, list) {
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 7ef8b9a1e30c..c87804112d0c 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1990,7 +1990,7 @@ static int netlink_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
skb_free_datagram(sk, skb);
- if (nlk->cb_running &&
+ if (READ_ONCE(nlk->cb_running) &&
atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf / 2) {
ret = netlink_dump(sk);
if (ret) {
@@ -2302,7 +2302,7 @@ static int netlink_dump(struct sock *sk)
if (cb->done)
cb->done(cb);
- nlk->cb_running = false;
+ WRITE_ONCE(nlk->cb_running, false);
module = cb->module;
skb = cb->skb;
mutex_unlock(nlk->cb_mutex);
@@ -2365,7 +2365,7 @@ int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
goto error_put;
}
- nlk->cb_running = true;
+ WRITE_ONCE(nlk->cb_running, true);
nlk->dump_done_errno = INT_MAX;
mutex_unlock(nlk->cb_mutex);
@@ -2703,7 +2703,7 @@ static int netlink_native_seq_show(struct seq_file *seq, void *v)
nlk->groups ? (u32)nlk->groups[0] : 0,
sk_rmem_alloc_get(s),
sk_wmem_alloc_get(s),
- nlk->cb_running,
+ READ_ONCE(nlk->cb_running),
refcount_read(&s->sk_refcnt),
atomic_read(&s->sk_drops),
sock_i_ino(s)
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 640d94e34635..94c6a1ffa459 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -1934,10 +1934,8 @@ static void packet_parse_headers(struct sk_buff *skb, struct socket *sock)
/* Move network header to the right position for VLAN tagged packets */
if (likely(skb->dev->type == ARPHRD_ETHER) &&
eth_type_vlan(skb->protocol) &&
- __vlan_get_protocol(skb, skb->protocol, &depth) != 0) {
- if (pskb_may_pull(skb, depth))
- skb_set_network_header(skb, depth);
- }
+ vlan_get_protocol_and_depth(skb, skb->protocol, &depth) != 0)
+ skb_set_network_header(skb, depth);
skb_probe_transport_header(skb);
}
diff --git a/net/smc/smc_close.c b/net/smc/smc_close.c
index 31db7438857c..dbdf03e8aa5b 100644
--- a/net/smc/smc_close.c
+++ b/net/smc/smc_close.c
@@ -67,8 +67,8 @@ static void smc_close_stream_wait(struct smc_sock *smc, long timeout)
rc = sk_wait_event(sk, &timeout,
!smc_tx_prepared_sends(&smc->conn) ||
- sk->sk_err == ECONNABORTED ||
- sk->sk_err == ECONNRESET ||
+ READ_ONCE(sk->sk_err) == ECONNABORTED ||
+ READ_ONCE(sk->sk_err) == ECONNRESET ||
smc->conn.killed,
&wait);
if (rc)
diff --git a/net/smc/smc_rx.c b/net/smc/smc_rx.c
index 4380d32f5a5f..9a2f3638d161 100644
--- a/net/smc/smc_rx.c
+++ b/net/smc/smc_rx.c
@@ -267,9 +267,9 @@ int smc_rx_wait(struct smc_sock *smc, long *timeo,
sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
add_wait_queue(sk_sleep(sk), &wait);
rc = sk_wait_event(sk, timeo,
- sk->sk_err ||
+ READ_ONCE(sk->sk_err) ||
cflags->peer_conn_abort ||
- sk->sk_shutdown & RCV_SHUTDOWN ||
+ READ_ONCE(sk->sk_shutdown) & RCV_SHUTDOWN ||
conn->killed ||
fcrit(conn),
&wait);
diff --git a/net/smc/smc_tx.c b/net/smc/smc_tx.c
index f4b6a71ac488..45128443f1f1 100644
--- a/net/smc/smc_tx.c
+++ b/net/smc/smc_tx.c
@@ -113,8 +113,8 @@ static int smc_tx_wait(struct smc_sock *smc, int flags)
break; /* at least 1 byte of free & no urgent data */
set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
sk_wait_event(sk, &timeo,
- sk->sk_err ||
- (sk->sk_shutdown & SEND_SHUTDOWN) ||
+ READ_ONCE(sk->sk_err) ||
+ (READ_ONCE(sk->sk_shutdown) & SEND_SHUTDOWN) ||
smc_cdc_rxed_any_close(conn) ||
(atomic_read(&conn->sndbuf_space) &&
!conn->urg_tx_pend),
diff --git a/net/socket.c b/net/socket.c
index a7b4b37d86df..b7e01d0fe082 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -2911,7 +2911,7 @@ static int do_recvmmsg(int fd, struct mmsghdr __user *mmsg,
* error to return on the next call or if the
* app asks about it using getsockopt(SO_ERROR).
*/
- sock->sk->sk_err = -err;
+ WRITE_ONCE(sock->sk->sk_err, -err);
}
out_put:
fput_light(sock->file, fput_needed);
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 37edfe10f8c6..dd73d71c02a9 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -314,9 +314,9 @@ static void tsk_rej_rx_queue(struct sock *sk, int error)
tipc_sk_respond(sk, skb, error);
}
-static bool tipc_sk_connected(struct sock *sk)
+static bool tipc_sk_connected(const struct sock *sk)
{
- return sk->sk_state == TIPC_ESTABLISHED;
+ return READ_ONCE(sk->sk_state) == TIPC_ESTABLISHED;
}
/* tipc_sk_type_connectionless - check if the socket is datagram socket
diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c
index b32c112984dd..f2e7302a4d96 100644
--- a/net/tls/tls_main.c
+++ b/net/tls/tls_main.c
@@ -111,7 +111,8 @@ int wait_on_pending_writer(struct sock *sk, long *timeo)
break;
}
- if (sk_wait_event(sk, timeo, !sk->sk_write_pending, &wait))
+ if (sk_wait_event(sk, timeo,
+ !READ_ONCE(sk->sk_write_pending), &wait))
break;
}
remove_wait_queue(sk_sleep(sk), &wait);
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index fb31e8a4409e..cc695c9f09ec 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -603,7 +603,7 @@ static void unix_release_sock(struct sock *sk, int embrion)
/* Clear state */
unix_state_lock(sk);
sock_orphan(sk);
- sk->sk_shutdown = SHUTDOWN_MASK;
+ WRITE_ONCE(sk->sk_shutdown, SHUTDOWN_MASK);
path = u->path;
u->path.dentry = NULL;
u->path.mnt = NULL;
@@ -628,7 +628,7 @@ static void unix_release_sock(struct sock *sk, int embrion)
if (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) {
unix_state_lock(skpair);
/* No more writes */
- skpair->sk_shutdown = SHUTDOWN_MASK;
+ WRITE_ONCE(skpair->sk_shutdown, SHUTDOWN_MASK);
if (!skb_queue_empty(&sk->sk_receive_queue) || embrion)
WRITE_ONCE(skpair->sk_err, ECONNRESET);
unix_state_unlock(skpair);
@@ -1442,7 +1442,7 @@ static long unix_wait_for_peer(struct sock *other, long timeo)
sched = !sock_flag(other, SOCK_DEAD) &&
!(other->sk_shutdown & RCV_SHUTDOWN) &&
- unix_recvq_full(other);
+ unix_recvq_full_lockless(other);
unix_state_unlock(other);
@@ -3008,7 +3008,7 @@ static int unix_shutdown(struct socket *sock, int mode)
++mode;
unix_state_lock(sk);
- sk->sk_shutdown |= mode;
+ WRITE_ONCE(sk->sk_shutdown, sk->sk_shutdown | mode);
other = unix_peer(sk);
if (other)
sock_hold(other);
@@ -3028,7 +3028,7 @@ static int unix_shutdown(struct socket *sock, int mode)
if (mode&SEND_SHUTDOWN)
peer_mode |= RCV_SHUTDOWN;
unix_state_lock(other);
- other->sk_shutdown |= peer_mode;
+ WRITE_ONCE(other->sk_shutdown, other->sk_shutdown | peer_mode);
unix_state_unlock(other);
other->sk_state_change(other);
if (peer_mode == SHUTDOWN_MASK)
@@ -3160,16 +3160,18 @@ static __poll_t unix_poll(struct file *file, struct socket *sock, poll_table *wa
{
struct sock *sk = sock->sk;
__poll_t mask;
+ u8 shutdown;
sock_poll_wait(file, sock, wait);
mask = 0;
+ shutdown = READ_ONCE(sk->sk_shutdown);
/* exceptional events? */
if (READ_ONCE(sk->sk_err))
mask |= EPOLLERR;
- if (sk->sk_shutdown == SHUTDOWN_MASK)
+ if (shutdown == SHUTDOWN_MASK)
mask |= EPOLLHUP;
- if (sk->sk_shutdown & RCV_SHUTDOWN)
+ if (shutdown & RCV_SHUTDOWN)
mask |= EPOLLRDHUP | EPOLLIN | EPOLLRDNORM;
/* readable? */
@@ -3203,9 +3205,11 @@ static __poll_t unix_dgram_poll(struct file *file, struct socket *sock,
struct sock *sk = sock->sk, *other;
unsigned int writable;
__poll_t mask;
+ u8 shutdown;
sock_poll_wait(file, sock, wait);
mask = 0;
+ shutdown = READ_ONCE(sk->sk_shutdown);
/* exceptional events? */
if (READ_ONCE(sk->sk_err) ||
@@ -3213,9 +3217,9 @@ static __poll_t unix_dgram_poll(struct file *file, struct socket *sock,
mask |= EPOLLERR |
(sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? EPOLLPRI : 0);
- if (sk->sk_shutdown & RCV_SHUTDOWN)
+ if (shutdown & RCV_SHUTDOWN)
mask |= EPOLLRDHUP | EPOLLIN | EPOLLRDNORM;
- if (sk->sk_shutdown == SHUTDOWN_MASK)
+ if (shutdown == SHUTDOWN_MASK)
mask |= EPOLLHUP;
/* readable? */
diff --git a/tools/testing/cxl/test/mock.c b/tools/testing/cxl/test/mock.c
index c4e53f22e421..de3933a776fd 100644
--- a/tools/testing/cxl/test/mock.c
+++ b/tools/testing/cxl/test/mock.c
@@ -19,7 +19,7 @@ void register_cxl_mock_ops(struct cxl_mock_ops *ops)
}
EXPORT_SYMBOL_GPL(register_cxl_mock_ops);
-static DEFINE_SRCU(cxl_mock_srcu);
+DEFINE_STATIC_SRCU(cxl_mock_srcu);
void unregister_cxl_mock_ops(struct cxl_mock_ops *ops)
{
diff --git a/tools/testing/selftests/drivers/net/bonding/bond_options.sh b/tools/testing/selftests/drivers/net/bonding/bond_options.sh
index db29a3146a86..607ba5c38977 100755
--- a/tools/testing/selftests/drivers/net/bonding/bond_options.sh
+++ b/tools/testing/selftests/drivers/net/bonding/bond_options.sh
@@ -6,6 +6,7 @@
ALL_TESTS="
prio
arp_validate
+ num_grat_arp
"
REQUIRE_MZ=no
@@ -255,6 +256,55 @@ arp_validate()
arp_validate_ns "active-backup"
}
+garp_test()
+{
+ local param="$1"
+ local active_slave exp_num real_num i
+ RET=0
+
+ # create bond
+ bond_reset "${param}"
+
+ bond_check_connection
+ [ $RET -ne 0 ] && log_test "num_grat_arp" "$retmsg"
+
+
+ # Add tc rules to count GARP number
+ for i in $(seq 0 2); do
+ tc -n ${g_ns} filter add dev s$i ingress protocol arp pref 1 handle 101 \
+ flower skip_hw arp_op request arp_sip ${s_ip4} arp_tip ${s_ip4} action pass
+ done
+
+ # Do failover
+ active_slave=$(cmd_jq "ip -n ${s_ns} -d -j link show bond0" ".[].linkinfo.info_data.active_slave")
+ ip -n ${s_ns} link set ${active_slave} down
+
+ exp_num=$(echo "${param}" | cut -f6 -d ' ')
+ sleep $((exp_num + 2))
+
+ active_slave=$(cmd_jq "ip -n ${s_ns} -d -j link show bond0" ".[].linkinfo.info_data.active_slave")
+
+ # check result
+ real_num=$(tc_rule_handle_stats_get "dev s${active_slave#eth} ingress" 101 ".packets" "-n ${g_ns}")
+ if [ "${real_num}" -ne "${exp_num}" ]; then
+ echo "$real_num garp packets sent on active slave ${active_slave}"
+ RET=1
+ fi
+
+ for i in $(seq 0 2); do
+ tc -n ${g_ns} filter del dev s$i ingress
+ done
+}
+
+num_grat_arp()
+{
+ local val
+ for val in 10 20 30 50; do
+ garp_test "mode active-backup miimon 100 num_grat_arp $val peer_notify_delay 1000"
+ log_test "num_grat_arp" "active-backup miimon num_grat_arp $val"
+ done
+}
+
trap cleanup EXIT
setup_prepare
diff --git a/tools/testing/selftests/drivers/net/bonding/bond_topo_3d1c.sh b/tools/testing/selftests/drivers/net/bonding/bond_topo_3d1c.sh
index 4045ca97fb22..69ab99a56043 100644
--- a/tools/testing/selftests/drivers/net/bonding/bond_topo_3d1c.sh
+++ b/tools/testing/selftests/drivers/net/bonding/bond_topo_3d1c.sh
@@ -61,6 +61,8 @@ server_create()
ip -n ${g_ns} link set s${i} up
ip -n ${g_ns} link set s${i} master br0
ip -n ${s_ns} link set eth${i} master bond0
+
+ tc -n ${g_ns} qdisc add dev s${i} clsact
done
ip -n ${s_ns} link set bond0 up
diff --git a/tools/testing/selftests/net/forwarding/lib.sh b/tools/testing/selftests/net/forwarding/lib.sh
index 057c3d0ad620..9ddb68dd6a08 100755
--- a/tools/testing/selftests/net/forwarding/lib.sh
+++ b/tools/testing/selftests/net/forwarding/lib.sh
@@ -791,8 +791,9 @@ tc_rule_handle_stats_get()
local id=$1; shift
local handle=$1; shift
local selector=${1:-.packets}; shift
+ local netns=${1:-""}; shift
- tc -j -s filter show $id \
+ tc $netns -j -s filter show $id \
| jq ".[] | select(.options.handle == $handle) | \
.options.actions[0].stats$selector"
}
diff --git a/tools/testing/selftests/netfilter/nft_flowtable.sh b/tools/testing/selftests/netfilter/nft_flowtable.sh
index 7060bae04ec8..a32f490f7539 100755
--- a/tools/testing/selftests/netfilter/nft_flowtable.sh
+++ b/tools/testing/selftests/netfilter/nft_flowtable.sh
@@ -188,6 +188,26 @@ if [ $? -ne 0 ]; then
exit $ksft_skip
fi
+ip netns exec $ns2 nft -f - <<EOF
+table inet filter {
+ counter ip4dscp0 { }
+ counter ip4dscp3 { }
+
+ chain input {
+ type filter hook input priority 0; policy accept;
+ meta l4proto tcp goto {
+ ip dscp cs3 counter name ip4dscp3 accept
+ ip dscp 0 counter name ip4dscp0 accept
+ }
+ }
+}
+EOF
+
+if [ $? -ne 0 ]; then
+ echo "SKIP: Could not load nft ruleset"
+ exit $ksft_skip
+fi
+
# test basic connectivity
if ! ip netns exec $ns1 ping -c 1 -q 10.0.2.99 > /dev/null; then
echo "ERROR: $ns1 cannot reach ns2" 1>&2
@@ -255,6 +275,60 @@ check_counters()
fi
}
+check_dscp()
+{
+ local what=$1
+ local ok=1
+
+ local counter=$(ip netns exec $ns2 nft reset counter inet filter ip4dscp3 | grep packets)
+
+ local pc4=${counter%*bytes*}
+ local pc4=${pc4#*packets}
+
+ local counter=$(ip netns exec $ns2 nft reset counter inet filter ip4dscp0 | grep packets)
+ local pc4z=${counter%*bytes*}
+ local pc4z=${pc4z#*packets}
+
+ case "$what" in
+ "dscp_none")
+ if [ $pc4 -gt 0 ] || [ $pc4z -eq 0 ]; then
+ echo "FAIL: dscp counters do not match, expected dscp3 == 0, dscp0 > 0, but got $pc4,$pc4z" 1>&2
+ ret=1
+ ok=0
+ fi
+ ;;
+ "dscp_fwd")
+ if [ $pc4 -eq 0 ] || [ $pc4z -eq 0 ]; then
+ echo "FAIL: dscp counters do not match, expected dscp3 and dscp0 > 0 but got $pc4,$pc4z" 1>&2
+ ret=1
+ ok=0
+ fi
+ ;;
+ "dscp_ingress")
+ if [ $pc4 -eq 0 ] || [ $pc4z -gt 0 ]; then
+ echo "FAIL: dscp counters do not match, expected dscp3 > 0, dscp0 == 0 but got $pc4,$pc4z" 1>&2
+ ret=1
+ ok=0
+ fi
+ ;;
+ "dscp_egress")
+ if [ $pc4 -eq 0 ] || [ $pc4z -gt 0 ]; then
+ echo "FAIL: dscp counters do not match, expected dscp3 > 0, dscp0 == 0 but got $pc4,$pc4z" 1>&2
+ ret=1
+ ok=0
+ fi
+ ;;
+ *)
+ echo "FAIL: Unknown DSCP check" 1>&2
+ ret=1
+ ok=0
+ esac
+
+ if [ $ok -eq 1 ] ;then
+ echo "PASS: $what: dscp packet counters match"
+ fi
+}
+
check_transfer()
{
in=$1
@@ -286,17 +360,26 @@ test_tcp_forwarding_ip()
ip netns exec $nsa nc -w 4 "$dstip" "$dstport" < "$nsin" > "$ns1out" &
cpid=$!
- sleep 3
+ sleep 1
- if ps -p $lpid > /dev/null;then
+ prev="$(ls -l $ns1out $ns2out)"
+ sleep 1
+
+ while [[ "$prev" != "$(ls -l $ns1out $ns2out)" ]]; do
+ sleep 1;
+ prev="$(ls -l $ns1out $ns2out)"
+ done
+
+ if test -d /proc/"$lpid"/; then
kill $lpid
fi
- if ps -p $cpid > /dev/null;then
+ if test -d /proc/"$cpid"/; then
kill $cpid
fi
- wait
+ wait $lpid
+ wait $cpid
if ! check_transfer "$nsin" "$ns2out" "ns1 -> ns2"; then
lret=1
@@ -316,6 +399,51 @@ test_tcp_forwarding()
return $?
}
+test_tcp_forwarding_set_dscp()
+{
+ check_dscp "dscp_none"
+
+ip netns exec $nsr1 nft -f - <<EOF
+table netdev dscpmangle {
+ chain setdscp0 {
+ type filter hook ingress device "veth0" priority 0; policy accept
+ ip dscp set cs3
+ }
+}
+EOF
+if [ $? -eq 0 ]; then
+ test_tcp_forwarding_ip "$1" "$2" 10.0.2.99 12345
+ check_dscp "dscp_ingress"
+
+ ip netns exec $nsr1 nft delete table netdev dscpmangle
+else
+ echo "SKIP: Could not load netdev:ingress for veth0"
+fi
+
+ip netns exec $nsr1 nft -f - <<EOF
+table netdev dscpmangle {
+ chain setdscp0 {
+ type filter hook egress device "veth1" priority 0; policy accept
+ ip dscp set cs3
+ }
+}
+EOF
+if [ $? -eq 0 ]; then
+ test_tcp_forwarding_ip "$1" "$2" 10.0.2.99 12345
+ check_dscp "dscp_egress"
+
+ ip netns exec $nsr1 nft flush table netdev dscpmangle
+else
+ echo "SKIP: Could not load netdev:egress for veth1"
+fi
+
+ # partial. If flowtable really works, then both dscp-is-0 and dscp-is-cs3
+ # counters should have seen packets (before and after ft offload kicks in).
+ ip netns exec $nsr1 nft -a insert rule inet filter forward ip dscp set cs3
+ test_tcp_forwarding_ip "$1" "$2" 10.0.2.99 12345
+ check_dscp "dscp_fwd"
+}
+
test_tcp_forwarding_nat()
{
local lret
@@ -385,6 +513,11 @@ table ip nat {
}
EOF
+if ! test_tcp_forwarding_set_dscp $ns1 $ns2 0 ""; then
+ echo "FAIL: flow offload for ns1/ns2 with dscp update" 1>&2
+ exit 0
+fi
+
if ! test_tcp_forwarding_nat $ns1 $ns2 0 ""; then
echo "FAIL: flow offload for ns1/ns2 with NAT" 1>&2
ip netns exec $nsr1 nft list ruleset
@@ -489,8 +622,8 @@ ip -net $nsr1 addr add 10.0.1.1/24 dev veth0
ip -net $nsr1 addr add dead:1::1/64 dev veth0
ip -net $nsr1 link set up dev veth0
-KEY_SHA="0x"$(ps -xaf | sha1sum | cut -d " " -f 1)
-KEY_AES="0x"$(ps -xaf | md5sum | cut -d " " -f 1)
+KEY_SHA="0x"$(ps -af | sha1sum | cut -d " " -f 1)
+KEY_AES="0x"$(ps -af | md5sum | cut -d " " -f 1)
SPI1=$RANDOM
SPI2=$RANDOM