Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'drm-misc-next-2025-09-11' of https://gitlab.freedesktop.org/drm/misc/kernel into drm-next

drm-misc-next for v6.18:

UAPI Changes:

- Provide 'boot_display' attribute on boot-up devices

amdxdma:
- Add ioctl DRM_IOCTL_AMDXDNA_GET_ARRAY

Cross-subsystem Changes:

bindings:
- Add Mayqueen vendor prefix mayqueen-

pci:
- vgaarb: Use screen_info helpers

Core Changes:

ttm:
- Add interface to populate buffers

Driver Changes:

amdgpu:
- Pre-populate exported buffers

ast:
- Clean up detection of DRAM config

bochs:
- Clean up

bridge:
- adv7511: Write full Audio infoframe
- ite6263: Support vendor-specific infoframes
- simple: Add support for Realtek RTD2171 DP-to-HDMI plus DT bindings
- Clean up

gma500:
- Clean up

nouveau:
- Pre-populate exported buffers

panel:
- edp: Add support for additonal mt8189 Chromebook panels
- lvds: Add DT bindings for EDT ETML0700Z8DHA
- Clean up

pixpaper:
- Add support for Mayqueen Pixpaper plus DT bindings

rcar-du:
- Use RUNTIME_PM_OPS
- Add support for DSI commands

vkms:
- Support variants of ARGB8888, ARGB16161616, RGB565, RGB888 and P01x
- Spport YUV with 16-bit components

xe:
- Pre-populate exported buffers

Signed-off-by: Dave Airlie <airlied@redhat.com>

From: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://lore.kernel.org/r/20250911091737.GA39831@linux.fritz.box

+2419 -486
+8
Documentation/ABI/testing/sysfs-class-drm
··· 1 + What: /sys/class/drm/.../boot_display 2 + Date: January 2026 3 + Contact: Linux DRI developers <dri-devel@vger.kernel.org> 4 + Description: 5 + This file indicates that displays connected to the device were 6 + used to display the boot sequence. If a display connected to 7 + the device was used to display the boot sequence the file will 8 + be present and contain "1".
+1
Documentation/devicetree/bindings/display/bridge/simple-bridge.yaml
··· 29 29 - adi,adv7123 30 30 - dumb-vga-dac 31 31 - radxa,ra620 32 + - realtek,rtd2171 32 33 - ti,opa362 33 34 - ti,ths8134 34 35 - ti,ths8135
+63
Documentation/devicetree/bindings/display/mayqueen,pixpaper.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/display/mayqueen,pixpaper.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Mayqueen Pixpaper e-ink display panel 8 + 9 + maintainers: 10 + - LiangCheng Wang <zaq14760@gmail.com> 11 + 12 + description: 13 + The Pixpaper is an e-ink display panel controlled via an SPI interface. 14 + The panel has a resolution of 122x250 pixels and requires GPIO pins for 15 + reset, busy, and data/command control. 16 + 17 + allOf: 18 + - $ref: /schemas/spi/spi-peripheral-props.yaml# 19 + 20 + properties: 21 + compatible: 22 + const: mayqueen,pixpaper 23 + 24 + reg: 25 + maxItems: 1 26 + 27 + spi-max-frequency: 28 + maximum: 1000000 29 + default: 1000000 30 + 31 + reset-gpios: 32 + maxItems: 1 33 + 34 + busy-gpios: 35 + maxItems: 1 36 + 37 + dc-gpios: 38 + maxItems: 1 39 + 40 + required: 41 + - compatible 42 + - reg 43 + - reset-gpios 44 + - busy-gpios 45 + - dc-gpios 46 + 47 + unevaluatedProperties: false 48 + 49 + examples: 50 + - | 51 + #include <dt-bindings/gpio/gpio.h> 52 + spi { 53 + #address-cells = <1>; 54 + #size-cells = <0>; 55 + display@0 { 56 + compatible = "mayqueen,pixpaper"; 57 + reg = <0>; 58 + spi-max-frequency = <1000000>; 59 + reset-gpios = <&gpio1 17 GPIO_ACTIVE_HIGH>; 60 + busy-gpios = <&gpio1 18 GPIO_ACTIVE_HIGH>; 61 + dc-gpios = <&gpio1 19 GPIO_ACTIVE_HIGH>; 62 + }; 63 + };
+2
Documentation/devicetree/bindings/display/panel/panel-lvds.yaml
··· 48 48 - auo,g084sn05 49 49 # Chunghwa Picture Tubes Ltd. 7" WXGA (800x1280) TFT LCD LVDS panel 50 50 - chunghwa,claa070wp03xg 51 + # EDT ETML0700Z8DHA 7.0" Full HD (1920x1080) color TFT LCD LVDS panel 52 + - edt,etml0700z8dha 51 53 # EDT ETML0700Z9NDHA 7.0" WSVGA (1024x600) color TFT LCD LVDS panel 52 54 - edt,etml0700z9ndha 53 55 # HannStar Display Corp. HSD101PWW2 10.1" WXGA (1280x800) LVDS panel
+2
Documentation/devicetree/bindings/vendor-prefixes.yaml
··· 933 933 description: Maxim Integrated Products 934 934 "^maxlinear,.*": 935 935 description: MaxLinear Inc. 936 + "^mayqueen,.*": 937 + description: Mayqueen Technologies Ltd. 936 938 "^mbvl,.*": 937 939 description: Mobiveil Inc. 938 940 "^mcube,.*":
+8 -2
MAINTAINERS
··· 1243 1243 F: drivers/spi/spi-amd.h 1244 1244 1245 1245 AMD XDNA DRIVER 1246 - M: Min Ma <min.ma@amd.com> 1246 + M: Min Ma <mamin506@gmail.com> 1247 1247 M: Lizhi Hou <lizhi.hou@amd.com> 1248 1248 L: dri-devel@lists.freedesktop.org 1249 1249 S: Supported ··· 7490 7490 F: include/linux/power/smartreflex.h 7491 7491 7492 7492 DRM ACCEL DRIVERS FOR INTEL VPU 7493 - M: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> 7494 7493 M: Maciej Falkowski <maciej.falkowski@linux.intel.com> 7495 7494 M: Karol Wachowski <karol.wachowski@linux.intel.com> 7496 7495 L: dri-devel@lists.freedesktop.org ··· 7875 7876 T: git https://gitlab.freedesktop.org/drm/misc/kernel.git 7876 7877 F: Documentation/devicetree/bindings/display/repaper.txt 7877 7878 F: drivers/gpu/drm/tiny/repaper.c 7879 + 7880 + DRM DRIVER FOR PIXPAPER E-INK PANEL 7881 + M: LiangCheng Wang <zaq14760@gmail.com> 7882 + L: dri-devel@lists.freedesktop.org 7883 + S: Maintained 7884 + F: Documentation/devicetree/bindings/display/mayqueen,pixpaper.yaml 7885 + F: drivers/gpu/drm/tiny/pixpaper.c 7878 7886 7879 7887 DRM DRIVER FOR QEMU'S CIRRUS DEVICE 7880 7888 M: Dave Airlie <airlied@redhat.com>
+1 -1
arch/parisc/include/asm/video.h
··· 6 6 7 7 struct device; 8 8 9 - #if defined(CONFIG_STI_CORE) 9 + #if defined(CONFIG_STI_CORE) && defined(CONFIG_VIDEO) 10 10 bool video_is_primary_device(struct device *dev); 11 11 #define video_is_primary_device video_is_primary_device 12 12 #endif
+2
arch/sparc/include/asm/video.h
··· 19 19 #define pgprot_framebuffer pgprot_framebuffer 20 20 #endif 21 21 22 + #ifdef CONFIG_VIDEO 22 23 bool video_is_primary_device(struct device *dev); 23 24 #define video_is_primary_device video_is_primary_device 25 + #endif 24 26 25 27 static inline void fb_memcpy_fromio(void *to, const volatile void __iomem *from, size_t n) 26 28 {
+2
arch/x86/include/asm/video.h
··· 13 13 unsigned long offset); 14 14 #define pgprot_framebuffer pgprot_framebuffer 15 15 16 + #ifdef CONFIG_VIDEO 16 17 bool video_is_primary_device(struct device *dev); 17 18 #define video_is_primary_device video_is_primary_device 19 + #endif 18 20 19 21 #include <asm-generic/video.h> 20 22
+24 -1
arch/x86/video/video-common.c
··· 9 9 10 10 #include <linux/module.h> 11 11 #include <linux/pci.h> 12 + #include <linux/screen_info.h> 12 13 #include <linux/vgaarb.h> 13 14 14 15 #include <asm/video.h> ··· 28 27 29 28 bool video_is_primary_device(struct device *dev) 30 29 { 30 + #ifdef CONFIG_SCREEN_INFO 31 + struct screen_info *si = &screen_info; 32 + struct resource res[SCREEN_INFO_MAX_RESOURCES]; 33 + ssize_t i, numres; 34 + #endif 31 35 struct pci_dev *pdev; 32 36 33 37 if (!dev_is_pci(dev)) ··· 40 34 41 35 pdev = to_pci_dev(dev); 42 36 43 - return (pdev == vga_default_device()); 37 + if (!pci_is_display(pdev)) 38 + return false; 39 + 40 + if (pdev == vga_default_device()) 41 + return true; 42 + 43 + #ifdef CONFIG_SCREEN_INFO 44 + numres = screen_info_resources(si, res, ARRAY_SIZE(res)); 45 + for (i = 0; i < numres; ++i) { 46 + if (!(res[i].flags & IORESOURCE_MEM)) 47 + continue; 48 + 49 + if (pci_find_resource(pdev, &res[i])) 50 + return true; 51 + } 52 + #endif 53 + 54 + return false; 44 55 } 45 56 EXPORT_SYMBOL(video_is_primary_device); 46 57
+88 -24
drivers/accel/amdxdna/aie2_pci.c
··· 785 785 786 786 static int aie2_hwctx_status_cb(struct amdxdna_hwctx *hwctx, void *arg) 787 787 { 788 - struct amdxdna_drm_query_hwctx *tmp __free(kfree) = NULL; 789 - struct amdxdna_drm_get_info *get_info_args = arg; 790 - struct amdxdna_drm_query_hwctx __user *buf; 788 + struct amdxdna_drm_hwctx_entry *tmp __free(kfree) = NULL; 789 + struct amdxdna_drm_get_array *array_args = arg; 790 + struct amdxdna_drm_hwctx_entry __user *buf; 791 + u32 size; 791 792 792 - if (get_info_args->buffer_size < sizeof(*tmp)) 793 + if (!array_args->num_element) 793 794 return -EINVAL; 794 795 795 796 tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); ··· 803 802 tmp->num_col = hwctx->num_col; 804 803 tmp->command_submissions = hwctx->priv->seq; 805 804 tmp->command_completions = hwctx->priv->completed; 805 + tmp->pasid = hwctx->client->pasid; 806 + tmp->priority = hwctx->qos.priority; 807 + tmp->gops = hwctx->qos.gops; 808 + tmp->fps = hwctx->qos.fps; 809 + tmp->dma_bandwidth = hwctx->qos.dma_bandwidth; 810 + tmp->latency = hwctx->qos.latency; 811 + tmp->frame_exec_time = hwctx->qos.frame_exec_time; 812 + tmp->state = AMDXDNA_HWCTX_STATE_ACTIVE; 806 813 807 - buf = u64_to_user_ptr(get_info_args->buffer); 814 + buf = u64_to_user_ptr(array_args->buffer); 815 + size = min(sizeof(*tmp), array_args->element_size); 808 816 809 - if (copy_to_user(buf, tmp, sizeof(*tmp))) 817 + if (copy_to_user(buf, tmp, size)) 810 818 return -EFAULT; 811 819 812 - get_info_args->buffer += sizeof(*tmp); 813 - get_info_args->buffer_size -= sizeof(*tmp); 820 + array_args->buffer += size; 821 + array_args->num_element--; 814 822 815 823 return 0; 816 824 } ··· 827 817 static int aie2_get_hwctx_status(struct amdxdna_client *client, 828 818 struct amdxdna_drm_get_info *args) 829 819 { 820 + struct amdxdna_drm_get_array array_args; 830 821 struct amdxdna_dev *xdna = client->xdna; 831 - struct amdxdna_drm_get_info info_args; 832 822 struct amdxdna_client *tmp_client; 833 823 int ret; 834 824 835 825 drm_WARN_ON(&xdna->ddev, !mutex_is_locked(&xdna->dev_lock)); 836 826 837 - info_args.buffer = args->buffer; 838 - info_args.buffer_size = args->buffer_size; 839 - 827 + array_args.element_size = sizeof(struct amdxdna_drm_query_hwctx); 828 + array_args.buffer = args->buffer; 829 + array_args.num_element = args->buffer_size / array_args.element_size; 840 830 list_for_each_entry(tmp_client, &xdna->client_list, node) { 841 - ret = amdxdna_hwctx_walk(tmp_client, &info_args, aie2_hwctx_status_cb); 831 + ret = amdxdna_hwctx_walk(tmp_client, &array_args, 832 + aie2_hwctx_status_cb); 842 833 if (ret) 843 834 break; 844 835 } 845 836 846 - args->buffer_size = (u32)(info_args.buffer - args->buffer); 837 + args->buffer_size -= (u32)(array_args.buffer - args->buffer); 847 838 return ret; 848 839 } 849 840 ··· 877 866 break; 878 867 case DRM_AMDXDNA_GET_POWER_MODE: 879 868 ret = aie2_get_power_mode(client, args); 869 + break; 870 + default: 871 + XDNA_ERR(xdna, "Not supported request parameter %u", args->param); 872 + ret = -EOPNOTSUPP; 873 + } 874 + XDNA_DBG(xdna, "Got param %d", args->param); 875 + 876 + drm_dev_exit(idx); 877 + return ret; 878 + } 879 + 880 + static int aie2_query_ctx_status_array(struct amdxdna_client *client, 881 + struct amdxdna_drm_get_array *args) 882 + { 883 + struct amdxdna_drm_get_array array_args; 884 + struct amdxdna_dev *xdna = client->xdna; 885 + struct amdxdna_client *tmp_client; 886 + int ret; 887 + 888 + drm_WARN_ON(&xdna->ddev, !mutex_is_locked(&xdna->dev_lock)); 889 + 890 + array_args.element_size = min(args->element_size, 891 + sizeof(struct amdxdna_drm_hwctx_entry)); 892 + array_args.buffer = args->buffer; 893 + array_args.num_element = args->num_element * args->element_size / 894 + array_args.element_size; 895 + list_for_each_entry(tmp_client, &xdna->client_list, node) { 896 + ret = amdxdna_hwctx_walk(tmp_client, &array_args, 897 + aie2_hwctx_status_cb); 898 + if (ret) 899 + break; 900 + } 901 + 902 + args->element_size = array_args.element_size; 903 + args->num_element = (u32)((array_args.buffer - args->buffer) / 904 + args->element_size); 905 + 906 + return ret; 907 + } 908 + 909 + static int aie2_get_array(struct amdxdna_client *client, 910 + struct amdxdna_drm_get_array *args) 911 + { 912 + struct amdxdna_dev *xdna = client->xdna; 913 + int ret, idx; 914 + 915 + if (!drm_dev_enter(&xdna->ddev, &idx)) 916 + return -ENODEV; 917 + 918 + switch (args->param) { 919 + case DRM_AMDXDNA_HW_CONTEXT_ALL: 920 + ret = aie2_query_ctx_status_array(client, args); 880 921 break; 881 922 default: 882 923 XDNA_ERR(xdna, "Not supported request parameter %u", args->param); ··· 989 926 } 990 927 991 928 const struct amdxdna_dev_ops aie2_ops = { 992 - .init = aie2_init, 993 - .fini = aie2_fini, 994 - .resume = aie2_hw_resume, 995 - .suspend = aie2_hw_suspend, 996 - .get_aie_info = aie2_get_info, 997 - .set_aie_state = aie2_set_state, 998 - .hwctx_init = aie2_hwctx_init, 999 - .hwctx_fini = aie2_hwctx_fini, 1000 - .hwctx_config = aie2_hwctx_config, 1001 - .cmd_submit = aie2_cmd_submit, 929 + .init = aie2_init, 930 + .fini = aie2_fini, 931 + .resume = aie2_hw_resume, 932 + .suspend = aie2_hw_suspend, 933 + .get_aie_info = aie2_get_info, 934 + .set_aie_state = aie2_set_state, 935 + .hwctx_init = aie2_hwctx_init, 936 + .hwctx_fini = aie2_hwctx_fini, 937 + .hwctx_config = aie2_hwctx_config, 938 + .cmd_submit = aie2_cmd_submit, 1002 939 .hmm_invalidate = aie2_hmm_invalidate, 940 + .get_array = aie2_get_array, 1003 941 };
+27
drivers/accel/amdxdna/amdxdna_pci_drv.c
··· 27 27 MODULE_FIRMWARE("amdnpu/17f0_20/npu.sbin"); 28 28 29 29 /* 30 + * 0.0: Initial version 31 + * 0.1: Support getting all hardware contexts by DRM_IOCTL_AMDXDNA_GET_ARRAY 32 + */ 33 + #define AMDXDNA_DRIVER_MAJOR 0 34 + #define AMDXDNA_DRIVER_MINOR 1 35 + 36 + /* 30 37 * Bind the driver base on (vendor_id, device_id) pair and later use the 31 38 * (device_id, rev_id) pair as a key to select the devices. The devices with 32 39 * same device_id have very similar interface to host driver. ··· 171 164 return ret; 172 165 } 173 166 167 + static int amdxdna_drm_get_array_ioctl(struct drm_device *dev, void *data, 168 + struct drm_file *filp) 169 + { 170 + struct amdxdna_client *client = filp->driver_priv; 171 + struct amdxdna_dev *xdna = to_xdna_dev(dev); 172 + struct amdxdna_drm_get_array *args = data; 173 + 174 + if (!xdna->dev_info->ops->get_array) 175 + return -EOPNOTSUPP; 176 + 177 + if (args->pad || !args->num_element || !args->element_size) 178 + return -EINVAL; 179 + 180 + guard(mutex)(&xdna->dev_lock); 181 + return xdna->dev_info->ops->get_array(client, args); 182 + } 183 + 174 184 static int amdxdna_drm_set_state_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) 175 185 { 176 186 struct amdxdna_client *client = filp->driver_priv; ··· 219 195 DRM_IOCTL_DEF_DRV(AMDXDNA_EXEC_CMD, amdxdna_drm_submit_cmd_ioctl, 0), 220 196 /* AIE hardware */ 221 197 DRM_IOCTL_DEF_DRV(AMDXDNA_GET_INFO, amdxdna_drm_get_info_ioctl, 0), 198 + DRM_IOCTL_DEF_DRV(AMDXDNA_GET_ARRAY, amdxdna_drm_get_array_ioctl, 0), 222 199 DRM_IOCTL_DEF_DRV(AMDXDNA_SET_STATE, amdxdna_drm_set_state_ioctl, DRM_ROOT_ONLY), 223 200 }; 224 201 ··· 243 218 .fops = &amdxdna_fops, 244 219 .name = "amdxdna_accel_driver", 245 220 .desc = "AMD XDNA DRM implementation", 221 + .major = AMDXDNA_DRIVER_MAJOR, 222 + .minor = AMDXDNA_DRIVER_MINOR, 246 223 .open = amdxdna_drm_open, 247 224 .postclose = amdxdna_drm_close, 248 225 .ioctls = amdxdna_drm_ioctls,
+1
drivers/accel/amdxdna/amdxdna_pci_drv.h
··· 58 58 int (*cmd_submit)(struct amdxdna_hwctx *hwctx, struct amdxdna_sched_job *job, u64 *seq); 59 59 int (*get_aie_info)(struct amdxdna_client *client, struct amdxdna_drm_get_info *args); 60 60 int (*set_aie_state)(struct amdxdna_client *client, struct amdxdna_drm_set_state *args); 61 + int (*get_array)(struct amdxdna_client *client, struct amdxdna_drm_get_array *args); 61 62 }; 62 63 63 64 /*
+12
drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
··· 313 313 { 314 314 struct amdgpu_bo *bo = gem_to_amdgpu_bo(gobj); 315 315 struct dma_buf *buf; 316 + struct ttm_operation_ctx ctx = { 317 + .interruptible = true, 318 + .no_wait_gpu = true, 319 + /* We opt to avoid OOM on system pages allocations */ 320 + .gfp_retry_mayfail = true, 321 + .allow_res_evict = false, 322 + }; 323 + int ret; 316 324 317 325 if (amdgpu_ttm_tt_get_usermm(bo->tbo.ttm) || 318 326 bo->flags & AMDGPU_GEM_CREATE_VM_ALWAYS_VALID) 319 327 return ERR_PTR(-EPERM); 328 + 329 + ret = ttm_bo_setup_export(&bo->tbo, &ctx); 330 + if (ret) 331 + return ERR_PTR(ret); 320 332 321 333 buf = drm_gem_prime_export(gobj, flags); 322 334 if (!IS_ERR(buf))
+43 -3
drivers/gpu/drm/ast/ast_2100.c
··· 32 32 #include "ast_post.h" 33 33 34 34 /* 35 + * DRAM type 36 + */ 37 + 38 + static enum ast_dram_layout ast_2100_get_dram_layout_p2a(struct ast_device *ast) 39 + { 40 + u32 mcr_cfg; 41 + enum ast_dram_layout dram_layout; 42 + 43 + ast_write32(ast, 0xf004, 0x1e6e0000); 44 + ast_write32(ast, 0xf000, 0x1); 45 + mcr_cfg = ast_read32(ast, 0x10004); 46 + 47 + switch (mcr_cfg & 0x0c) { 48 + case 0: 49 + case 4: 50 + default: 51 + dram_layout = AST_DRAM_512Mx16; 52 + break; 53 + case 8: 54 + if (mcr_cfg & 0x40) 55 + dram_layout = AST_DRAM_1Gx16; 56 + else 57 + dram_layout = AST_DRAM_512Mx32; 58 + break; 59 + case 0xc: 60 + dram_layout = AST_DRAM_1Gx32; 61 + break; 62 + } 63 + 64 + return dram_layout; 65 + } 66 + 67 + /* 35 68 * POST 36 69 */ 37 70 ··· 299 266 u8 j; 300 267 u32 data, temp, i; 301 268 const struct ast_dramstruct *dram_reg_info; 269 + enum ast_dram_layout dram_layout = ast_2100_get_dram_layout_p2a(ast); 302 270 303 271 j = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff); 304 272 ··· 326 292 for (i = 0; i < 15; i++) 327 293 udelay(dram_reg_info->data); 328 294 } else if (AST_DRAMSTRUCT_IS(dram_reg_info, DRAM_TYPE)) { 329 - data = dram_reg_info->data; 330 - if (ast->dram_type == AST_DRAM_1Gx16) 295 + switch (dram_layout) { 296 + case AST_DRAM_1Gx16: 331 297 data = 0x00000d89; 332 - else if (ast->dram_type == AST_DRAM_1Gx32) 298 + break; 299 + case AST_DRAM_1Gx32: 333 300 data = 0x00000c8d; 301 + break; 302 + default: 303 + data = dram_reg_info->data; 304 + break; 305 + } 334 306 335 307 temp = ast_read32(ast, 0x12070); 336 308 temp &= 0xc;
+9 -11
drivers/gpu/drm/ast/ast_drv.h
··· 98 98 ast_use_defaults 99 99 }; 100 100 101 - #define AST_DRAM_512Mx16 0 102 - #define AST_DRAM_1Gx16 1 103 - #define AST_DRAM_512Mx32 2 104 - #define AST_DRAM_1Gx32 3 105 - #define AST_DRAM_2Gx16 6 106 - #define AST_DRAM_4Gx16 7 107 - #define AST_DRAM_8Gx16 8 101 + enum ast_dram_layout { 102 + AST_DRAM_512Mx16 = 0, 103 + AST_DRAM_1Gx16 = 1, 104 + AST_DRAM_512Mx32 = 2, 105 + AST_DRAM_1Gx32 = 3, 106 + AST_DRAM_2Gx16 = 6, 107 + AST_DRAM_4Gx16 = 7, 108 + AST_DRAM_8Gx16 = 8, 109 + }; 108 110 109 111 /* 110 112 * Hardware cursor ··· 173 171 174 172 enum ast_config_mode config_mode; 175 173 enum ast_chip chip; 176 - 177 - uint32_t dram_bus_width; 178 - uint32_t dram_type; 179 - uint32_t mclk; 180 174 181 175 void __iomem *vram; 182 176 unsigned long vram_base;
-126
drivers/gpu/drm/ast/ast_main.c
··· 210 210 drm_info(dev, "Using %s\n", info_str[ast->tx_chip]); 211 211 } 212 212 213 - static int ast_get_dram_info(struct ast_device *ast) 214 - { 215 - struct drm_device *dev = &ast->base; 216 - struct device_node *np = dev->dev->of_node; 217 - uint32_t mcr_cfg, mcr_scu_mpll, mcr_scu_strap; 218 - uint32_t denum, num, div, ref_pll, dsel; 219 - 220 - switch (ast->config_mode) { 221 - case ast_use_dt: 222 - /* 223 - * If some properties are missing, use reasonable 224 - * defaults for GEN5 225 - */ 226 - if (of_property_read_u32(np, "aspeed,mcr-configuration", 227 - &mcr_cfg)) 228 - mcr_cfg = 0x00000577; 229 - if (of_property_read_u32(np, "aspeed,mcr-scu-mpll", 230 - &mcr_scu_mpll)) 231 - mcr_scu_mpll = 0x000050C0; 232 - if (of_property_read_u32(np, "aspeed,mcr-scu-strap", 233 - &mcr_scu_strap)) 234 - mcr_scu_strap = 0; 235 - break; 236 - case ast_use_p2a: 237 - ast_write32(ast, 0xf004, 0x1e6e0000); 238 - ast_write32(ast, 0xf000, 0x1); 239 - mcr_cfg = ast_read32(ast, 0x10004); 240 - mcr_scu_mpll = ast_read32(ast, 0x10120); 241 - mcr_scu_strap = ast_read32(ast, 0x10170); 242 - break; 243 - case ast_use_defaults: 244 - default: 245 - ast->dram_bus_width = 16; 246 - ast->dram_type = AST_DRAM_1Gx16; 247 - if (IS_AST_GEN6(ast)) 248 - ast->mclk = 800; 249 - else 250 - ast->mclk = 396; 251 - return 0; 252 - } 253 - 254 - if (mcr_cfg & 0x40) 255 - ast->dram_bus_width = 16; 256 - else 257 - ast->dram_bus_width = 32; 258 - 259 - if (IS_AST_GEN6(ast)) { 260 - switch (mcr_cfg & 0x03) { 261 - case 0: 262 - ast->dram_type = AST_DRAM_1Gx16; 263 - break; 264 - default: 265 - case 1: 266 - ast->dram_type = AST_DRAM_2Gx16; 267 - break; 268 - case 2: 269 - ast->dram_type = AST_DRAM_4Gx16; 270 - break; 271 - case 3: 272 - ast->dram_type = AST_DRAM_8Gx16; 273 - break; 274 - } 275 - } else if (IS_AST_GEN4(ast) || IS_AST_GEN5(ast)) { 276 - switch (mcr_cfg & 0x03) { 277 - case 0: 278 - ast->dram_type = AST_DRAM_512Mx16; 279 - break; 280 - default: 281 - case 1: 282 - ast->dram_type = AST_DRAM_1Gx16; 283 - break; 284 - case 2: 285 - ast->dram_type = AST_DRAM_2Gx16; 286 - break; 287 - case 3: 288 - ast->dram_type = AST_DRAM_4Gx16; 289 - break; 290 - } 291 - } else { 292 - switch (mcr_cfg & 0x0c) { 293 - case 0: 294 - case 4: 295 - ast->dram_type = AST_DRAM_512Mx16; 296 - break; 297 - case 8: 298 - if (mcr_cfg & 0x40) 299 - ast->dram_type = AST_DRAM_1Gx16; 300 - else 301 - ast->dram_type = AST_DRAM_512Mx32; 302 - break; 303 - case 0xc: 304 - ast->dram_type = AST_DRAM_1Gx32; 305 - break; 306 - } 307 - } 308 - 309 - if (mcr_scu_strap & 0x2000) 310 - ref_pll = 14318; 311 - else 312 - ref_pll = 12000; 313 - 314 - denum = mcr_scu_mpll & 0x1f; 315 - num = (mcr_scu_mpll & 0x3fe0) >> 5; 316 - dsel = (mcr_scu_mpll & 0xc000) >> 14; 317 - switch (dsel) { 318 - case 3: 319 - div = 0x4; 320 - break; 321 - case 2: 322 - case 1: 323 - div = 0x2; 324 - break; 325 - default: 326 - div = 0x1; 327 - break; 328 - } 329 - ast->mclk = ref_pll * (num + 2) / ((denum + 2) * (div * 1000)); 330 - return 0; 331 - } 332 - 333 213 struct drm_device *ast_device_create(struct pci_dev *pdev, 334 214 const struct drm_driver *drv, 335 215 enum ast_chip chip, ··· 231 351 ast->config_mode = config_mode; 232 352 ast->regs = regs; 233 353 ast->ioregs = ioregs; 234 - 235 - ret = ast_get_dram_info(ast); 236 - if (ret) 237 - return ERR_PTR(ret); 238 - drm_info(dev, "dram MCLK=%u Mhz type=%d bus_width=%d\n", 239 - ast->mclk, ast->dram_type, ast->dram_bus_width); 240 354 241 355 ast_detect_tx_chip(ast, need_post); 242 356 switch (ast->tx_chip) {
+6 -17
drivers/gpu/drm/bridge/adv7511/adv7511_audio.c
··· 12 12 #include <sound/soc.h> 13 13 #include <linux/of_graph.h> 14 14 15 + #include <drm/display/drm_hdmi_state_helper.h> 16 + 15 17 #include "adv7511.h" 16 18 17 19 static void adv7511_calc_cts_n(unsigned int f_tmds, unsigned int fs, ··· 157 155 regmap_update_bits(adv7511->regmap, ADV7511_REG_I2C_FREQ_ID_CFG, 158 156 ADV7511_I2C_FREQ_ID_CFG_RATE_MASK, rate << 4); 159 157 160 - /* send current Audio infoframe values while updating */ 161 - regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE, 162 - BIT(5), BIT(5)); 163 - 164 - regmap_write(adv7511->regmap, ADV7511_REG_AUDIO_INFOFRAME(0), 0x1); 165 - 166 - /* use Audio infoframe updated info */ 167 - regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE, 168 - BIT(5), 0); 169 - 170 - return 0; 158 + return drm_atomic_helper_connector_hdmi_update_audio_infoframe(connector, 159 + &hparms->cea); 171 160 } 172 161 173 162 int adv7511_hdmi_audio_startup(struct drm_bridge *bridge, ··· 181 188 /* not copyrighted */ 182 189 regmap_update_bits(adv7511->regmap, ADV7511_REG_AUDIO_CFG1, 183 190 BIT(5), BIT(5)); 184 - /* enable audio infoframes */ 185 - regmap_update_bits(adv7511->regmap, ADV7511_REG_PACKET_ENABLE1, 186 - BIT(3), BIT(3)); 187 191 /* AV mute disable */ 188 192 regmap_update_bits(adv7511->regmap, ADV7511_REG_GC(0), 189 193 BIT(7) | BIT(6), BIT(7)); 190 - /* use Audio infoframe updated info */ 191 - regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE, 192 - BIT(5), 0); 193 194 194 195 /* enable SPDIF receiver */ 195 196 if (adv7511->audio_source == ADV7511_AUDIO_SOURCE_SPDIF) ··· 201 214 if (adv7511->audio_source == ADV7511_AUDIO_SOURCE_SPDIF) 202 215 regmap_update_bits(adv7511->regmap, ADV7511_REG_AUDIO_CONFIG, 203 216 BIT(7), 0); 217 + 218 + drm_atomic_helper_connector_hdmi_clear_audio_infoframe(connector); 204 219 }
+31 -2
drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
··· 893 893 struct adv7511 *adv7511 = bridge_to_adv7511(bridge); 894 894 895 895 switch (type) { 896 + case HDMI_INFOFRAME_TYPE_AUDIO: 897 + adv7511_packet_disable(adv7511, ADV7511_PACKET_ENABLE_AUDIO_INFOFRAME); 898 + break; 896 899 case HDMI_INFOFRAME_TYPE_AVI: 897 900 adv7511_packet_disable(adv7511, ADV7511_PACKET_ENABLE_AVI_INFOFRAME); 898 901 break; ··· 919 916 { 920 917 struct adv7511 *adv7511 = bridge_to_adv7511(bridge); 921 918 922 - adv7511_bridge_hdmi_clear_infoframe(bridge, type); 923 - 924 919 switch (type) { 920 + case HDMI_INFOFRAME_TYPE_AUDIO: 921 + /* send current Audio infoframe values while updating */ 922 + regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE, 923 + BIT(5), BIT(5)); 924 + 925 + /* The Audio infoframe id is not configurable */ 926 + regmap_bulk_write(adv7511->regmap, ADV7511_REG_AUDIO_INFOFRAME_VERSION, 927 + buffer + 1, len - 1); 928 + 929 + /* use Audio infoframe updated info */ 930 + regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE, 931 + BIT(5), 0); 932 + 933 + adv7511_packet_enable(adv7511, ADV7511_PACKET_ENABLE_AUDIO_INFOFRAME); 934 + break; 925 935 case HDMI_INFOFRAME_TYPE_AVI: 936 + /* send current AVI infoframe values while updating */ 937 + regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE, 938 + BIT(6), BIT(6)); 939 + 926 940 /* The AVI infoframe id is not configurable */ 927 941 regmap_bulk_write(adv7511->regmap, ADV7511_REG_AVI_INFOFRAME_VERSION, 928 942 buffer + 1, len - 1); 929 943 944 + regmap_write(adv7511->regmap, ADV7511_REG_AUDIO_INFOFRAME_LENGTH, 0x2); 945 + regmap_write(adv7511->regmap, ADV7511_REG_AUDIO_INFOFRAME(1), 0x1); 946 + 947 + /* use AVI infoframe updated info */ 948 + regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE, 949 + BIT(6), 0); 950 + 930 951 adv7511_packet_enable(adv7511, ADV7511_PACKET_ENABLE_AVI_INFOFRAME); 931 952 break; 932 953 case HDMI_INFOFRAME_TYPE_SPD: 954 + adv7511_packet_disable(adv7511, ADV7511_PACKET_ENABLE_SPD); 933 955 regmap_bulk_write(adv7511->regmap_packet, ADV7511_PACKET_SPD(0), 934 956 buffer, len); 935 957 adv7511_packet_enable(adv7511, ADV7511_PACKET_ENABLE_SPD); 936 958 break; 937 959 case HDMI_INFOFRAME_TYPE_VENDOR: 960 + adv7511_packet_disable(adv7511, ADV7511_PACKET_ENABLE_SPARE1); 938 961 regmap_bulk_write(adv7511->regmap_packet, ADV7511_PACKET_SPARE1(0), 939 962 buffer, len); 940 963 adv7511_packet_enable(adv7511, ADV7511_PACKET_ENABLE_SPARE1);
+1
drivers/gpu/drm/bridge/cadence/Kconfig
··· 6 6 select DRM_PANEL_BRIDGE 7 7 select GENERIC_PHY 8 8 select GENERIC_PHY_MIPI_DPHY 9 + select VIDEOMODE_HELPERS 9 10 depends on OF 10 11 help 11 12 Support Cadence DPI to DSI bridge. This is an internal
+44 -20
drivers/gpu/drm/bridge/ite-it6263.c
··· 146 146 #define HDMI_COLOR_DEPTH_24 FIELD_PREP(HDMI_COLOR_DEPTH, 4) 147 147 148 148 #define HDMI_REG_PKT_GENERAL_CTRL 0xc6 149 + #define HDMI_REG_PKT_NULL_CTRL 0xc9 149 150 #define HDMI_REG_AVI_INFOFRM_CTRL 0xcd 150 151 #define ENABLE_PKT BIT(0) 151 152 #define REPEAT_PKT BIT(1) ··· 154 153 /* ----------------------------------------------------------------------------- 155 154 * 3) HDMI register bank1: 0x130 ~ 0x1ff (HDMI packet registers) 156 155 */ 156 + 157 + /* NULL packet registers */ 158 + /* Header Byte(HB): n = 0 ~ 2 */ 159 + #define HDMI_REG_PKT_HB(n) (0x138 + (n)) 160 + /* Packet Byte(PB): n = 0 ~ 27(HDMI_MAX_INFOFRAME_SIZE), n = 0 for checksum */ 161 + #define HDMI_REG_PKT_PB(n) (0x13b + (n)) 157 162 158 163 /* AVI packet registers */ 159 164 #define HDMI_REG_AVI_DB1 0x158 ··· 231 224 case HDMI_REG_HDMI_MODE: 232 225 case HDMI_REG_GCP: 233 226 case HDMI_REG_PKT_GENERAL_CTRL: 227 + case HDMI_REG_PKT_NULL_CTRL: 234 228 case HDMI_REG_AVI_INFOFRM_CTRL: 229 + case HDMI_REG_PKT_HB(0) ... HDMI_REG_PKT_PB(HDMI_MAX_INFOFRAME_SIZE): 235 230 case HDMI_REG_AVI_DB1: 236 231 case HDMI_REG_AVI_DB2: 237 232 case HDMI_REG_AVI_DB3: ··· 764 755 { 765 756 struct it6263 *it = bridge_to_it6263(bridge); 766 757 767 - if (type == HDMI_INFOFRAME_TYPE_AVI) 758 + switch (type) { 759 + case HDMI_INFOFRAME_TYPE_AVI: 768 760 regmap_write(it->hdmi_regmap, HDMI_REG_AVI_INFOFRM_CTRL, 0); 769 - else 761 + break; 762 + case HDMI_INFOFRAME_TYPE_VENDOR: 763 + regmap_write(it->hdmi_regmap, HDMI_REG_PKT_NULL_CTRL, 0); 764 + break; 765 + default: 770 766 dev_dbg(it->dev, "unsupported HDMI infoframe 0x%x\n", type); 767 + } 771 768 772 769 return 0; 773 770 } ··· 785 770 struct it6263 *it = bridge_to_it6263(bridge); 786 771 struct regmap *regmap = it->hdmi_regmap; 787 772 788 - if (type != HDMI_INFOFRAME_TYPE_AVI) { 773 + switch (type) { 774 + case HDMI_INFOFRAME_TYPE_AVI: 775 + /* write the first AVI infoframe data byte chunk(DB1-DB5) */ 776 + regmap_bulk_write(regmap, HDMI_REG_AVI_DB1, 777 + &buffer[HDMI_INFOFRAME_HEADER_SIZE], 778 + HDMI_AVI_DB_CHUNK1_SIZE); 779 + 780 + /* write the second AVI infoframe data byte chunk(DB6-DB13) */ 781 + regmap_bulk_write(regmap, HDMI_REG_AVI_DB6, 782 + &buffer[HDMI_INFOFRAME_HEADER_SIZE + 783 + HDMI_AVI_DB_CHUNK1_SIZE], 784 + HDMI_AVI_DB_CHUNK2_SIZE); 785 + 786 + /* write checksum */ 787 + regmap_write(regmap, HDMI_REG_AVI_CSUM, buffer[3]); 788 + 789 + regmap_write(regmap, HDMI_REG_AVI_INFOFRM_CTRL, 790 + ENABLE_PKT | REPEAT_PKT); 791 + break; 792 + case HDMI_INFOFRAME_TYPE_VENDOR: 793 + /* write header and payload */ 794 + regmap_bulk_write(regmap, HDMI_REG_PKT_HB(0), buffer, len); 795 + 796 + regmap_write(regmap, HDMI_REG_PKT_NULL_CTRL, 797 + ENABLE_PKT | REPEAT_PKT); 798 + break; 799 + default: 789 800 dev_dbg(it->dev, "unsupported HDMI infoframe 0x%x\n", type); 790 - return 0; 791 801 } 792 - 793 - /* write the first AVI infoframe data byte chunk(DB1-DB5) */ 794 - regmap_bulk_write(regmap, HDMI_REG_AVI_DB1, 795 - &buffer[HDMI_INFOFRAME_HEADER_SIZE], 796 - HDMI_AVI_DB_CHUNK1_SIZE); 797 - 798 - /* write the second AVI infoframe data byte chunk(DB6-DB13) */ 799 - regmap_bulk_write(regmap, HDMI_REG_AVI_DB6, 800 - &buffer[HDMI_INFOFRAME_HEADER_SIZE + 801 - HDMI_AVI_DB_CHUNK1_SIZE], 802 - HDMI_AVI_DB_CHUNK2_SIZE); 803 - 804 - /* write checksum */ 805 - regmap_write(regmap, HDMI_REG_AVI_CSUM, buffer[3]); 806 - 807 - regmap_write(regmap, HDMI_REG_AVI_INFOFRM_CTRL, ENABLE_PKT | REPEAT_PKT); 808 802 809 803 return 0; 810 804 }
+5
drivers/gpu/drm/bridge/simple-bridge.c
··· 267 267 .connector_type = DRM_MODE_CONNECTOR_HDMIA, 268 268 }, 269 269 }, { 270 + .compatible = "realtek,rtd2171", 271 + .data = &(const struct simple_bridge_info) { 272 + .connector_type = DRM_MODE_CONNECTOR_HDMIA, 273 + }, 274 + }, { 270 275 .compatible = "ti,opa362", 271 276 .data = &(const struct simple_bridge_info) { 272 277 .connector_type = DRM_MODE_CONNECTOR_Composite,
-2
drivers/gpu/drm/display/drm_bridge_connector.c
··· 776 776 if (!connector->ycbcr_420_allowed) 777 777 supported_formats &= ~BIT(HDMI_COLORSPACE_YUV420); 778 778 779 - bridge = bridge_connector->bridge_hdmi; 780 - 781 779 ret = drmm_connector_hdmi_init(drm, connector, 782 780 bridge_connector->bridge_hdmi->vendor, 783 781 bridge_connector->bridge_hdmi->product,
+41
drivers/gpu/drm/drm_sysfs.c
··· 18 18 #include <linux/gfp.h> 19 19 #include <linux/i2c.h> 20 20 #include <linux/kdev_t.h> 21 + #include <linux/pci.h> 21 22 #include <linux/property.h> 22 23 #include <linux/slab.h> 23 24 ··· 30 29 #include <drm/drm_print.h> 31 30 #include <drm/drm_property.h> 32 31 #include <drm/drm_sysfs.h> 32 + 33 + #include <asm/video.h> 33 34 34 35 #include "drm_internal.h" 35 36 #include "drm_crtc_internal.h" ··· 511 508 } 512 509 EXPORT_SYMBOL(drm_sysfs_connector_property_event); 513 510 511 + static ssize_t boot_display_show(struct device *dev, struct device_attribute *attr, 512 + char *buf) 513 + { 514 + return sysfs_emit(buf, "1\n"); 515 + } 516 + static DEVICE_ATTR_RO(boot_display); 517 + 518 + static struct attribute *display_attrs[] = { 519 + &dev_attr_boot_display.attr, 520 + NULL 521 + }; 522 + 523 + static umode_t boot_display_visible(struct kobject *kobj, 524 + struct attribute *a, int n) 525 + { 526 + struct device *dev = kobj_to_dev(kobj)->parent; 527 + 528 + if (dev_is_pci(dev)) { 529 + struct pci_dev *pdev = to_pci_dev(dev); 530 + 531 + if (video_is_primary_device(&pdev->dev)) 532 + return a->mode; 533 + } 534 + 535 + return 0; 536 + } 537 + 538 + static const struct attribute_group display_attr_group = { 539 + .attrs = display_attrs, 540 + .is_visible = boot_display_visible, 541 + }; 542 + 543 + static const struct attribute_group *card_dev_groups[] = { 544 + &display_attr_group, 545 + NULL 546 + }; 547 + 514 548 struct device *drm_sysfs_minor_alloc(struct drm_minor *minor) 515 549 { 516 550 const char *minor_str; ··· 571 531 572 532 kdev->devt = MKDEV(DRM_MAJOR, minor->index); 573 533 kdev->class = drm_class; 534 + kdev->groups = card_dev_groups; 574 535 kdev->type = &drm_sysfs_device_minor; 575 536 } 576 537
-2
drivers/gpu/drm/gma500/fbdev.c
··· 120 120 drm_fb_helper_fini(fb_helper); 121 121 122 122 drm_framebuffer_unregister_private(fb); 123 - fb->obj[0] = NULL; 124 123 drm_framebuffer_cleanup(fb); 125 124 kfree(fb); 126 125 ··· 244 245 245 246 err_drm_framebuffer_unregister_private: 246 247 drm_framebuffer_unregister_private(fb); 247 - fb->obj[0] = NULL; 248 248 drm_framebuffer_cleanup(fb); 249 249 kfree(fb); 250 250 err_drm_gem_object_put:
+12
drivers/gpu/drm/nouveau/nouveau_prime.c
··· 108 108 int flags) 109 109 { 110 110 struct nouveau_bo *nvbo = nouveau_gem_object(gobj); 111 + struct ttm_operation_ctx ctx = { 112 + .interruptible = true, 113 + .no_wait_gpu = true, 114 + /* We opt to avoid OOM on system pages allocations */ 115 + .gfp_retry_mayfail = true, 116 + .allow_res_evict = false, 117 + }; 118 + int ret; 111 119 112 120 if (nvbo->no_share) 113 121 return ERR_PTR(-EPERM); 122 + 123 + ret = ttm_bo_setup_export(&nvbo->bo, &ctx); 124 + if (ret) 125 + return ERR_PTR(ret); 114 126 115 127 return drm_gem_prime_export(gobj, flags); 116 128 }
+11
drivers/gpu/drm/panel/panel-edp.c
··· 1843 1843 .disable = 100, 1844 1844 }; 1845 1845 1846 + static const struct panel_delay delay_80_500_e50_d50 = { 1847 + .hpd_absent = 80, 1848 + .unprepare = 500, 1849 + .enable = 50, 1850 + .disable = 50, 1851 + }; 1852 + 1846 1853 #define EDP_PANEL_ENTRY(vend_chr_0, vend_chr_1, vend_chr_2, product_id, _delay, _name) \ 1847 1854 { \ 1848 1855 .ident = { \ ··· 1962 1955 EDP_PANEL_ENTRY('B', 'O', 'E', 0x0a36, &delay_200_500_e200, "Unknown"), 1963 1956 EDP_PANEL_ENTRY('B', 'O', 'E', 0x0a3e, &delay_200_500_e80_d50, "NV116WHM-N49"), 1964 1957 EDP_PANEL_ENTRY('B', 'O', 'E', 0x0a5d, &delay_200_500_e50, "NV116WHM-N45"), 1958 + EDP_PANEL_ENTRY('B', 'O', 'E', 0x0a6a, &delay_200_500_e80, "NV140WUM-N44"), 1965 1959 EDP_PANEL_ENTRY('B', 'O', 'E', 0x0ac5, &delay_200_500_e50, "NV116WHM-N4C"), 1966 1960 EDP_PANEL_ENTRY('B', 'O', 'E', 0x0ae8, &delay_200_500_e50_p2e80, "NV140WUM-N41"), 1967 1961 EDP_PANEL_ENTRY('B', 'O', 'E', 0x0b09, &delay_200_500_e50_po2e200, "NV140FHM-NZ"), ··· 2004 1996 EDP_PANEL_ENTRY('C', 'M', 'N', 0x124c, &delay_200_500_e80_d50, "N122JCA-ENK"), 2005 1997 EDP_PANEL_ENTRY('C', 'M', 'N', 0x142b, &delay_200_500_e80_d50, "N140HCA-EAC"), 2006 1998 EDP_PANEL_ENTRY('C', 'M', 'N', 0x142e, &delay_200_500_e80_d50, "N140BGA-EA4"), 1999 + EDP_PANEL_ENTRY('C', 'M', 'N', 0x1441, &delay_200_500_e80_d50, "N140JCA-ELK"), 2007 2000 EDP_PANEL_ENTRY('C', 'M', 'N', 0x144f, &delay_200_500_e80_d50, "N140HGA-EA1"), 2008 2001 EDP_PANEL_ENTRY('C', 'M', 'N', 0x1468, &delay_200_500_e80, "N140HGA-EA1"), 2009 2002 EDP_PANEL_ENTRY('C', 'M', 'N', 0x14a8, &delay_200_500_e80, "N140JCA-ELP"), ··· 2020 2011 EDP_PANEL_ENTRY('C', 'S', 'W', 0x1100, &delay_200_500_e80_d50, "MNB601LS1-1"), 2021 2012 EDP_PANEL_ENTRY('C', 'S', 'W', 0x1103, &delay_200_500_e80_d50, "MNB601LS1-3"), 2022 2013 EDP_PANEL_ENTRY('C', 'S', 'W', 0x1104, &delay_200_500_e50_d100, "MNB601LS1-4"), 2014 + EDP_PANEL_ENTRY('C', 'S', 'W', 0x143f, &delay_200_500_e50, "MNE007QS3-6"), 2023 2015 EDP_PANEL_ENTRY('C', 'S', 'W', 0x1448, &delay_200_500_e50, "MNE007QS3-7"), 2024 2016 EDP_PANEL_ENTRY('C', 'S', 'W', 0x1457, &delay_80_500_e80_p2e200, "MNE007QS3-8"), 2025 2017 EDP_PANEL_ENTRY('C', 'S', 'W', 0x1462, &delay_200_500_e50, "MNE007QS5-2"), 2026 2018 EDP_PANEL_ENTRY('C', 'S', 'W', 0x1468, &delay_200_500_e50, "MNE007QB2-2"), 2019 + EDP_PANEL_ENTRY('C', 'S', 'W', 0x146e, &delay_80_500_e50_d50, "MNE007QB3-1"), 2027 2020 2028 2021 EDP_PANEL_ENTRY('E', 'T', 'C', 0x0000, &delay_50_500_e200_d200_po2e335, "LP079QX1-SP0V"), 2029 2022
-2
drivers/gpu/drm/panel/panel-lvds.c
··· 28 28 struct device *dev; 29 29 30 30 const char *label; 31 - unsigned int width; 32 - unsigned int height; 33 31 struct drm_display_mode dmode; 34 32 u32 bus_flags; 35 33 unsigned int bus_format;
+2 -2
drivers/gpu/drm/renesas/rcar-du/rcar_lvds.c
··· 1013 1013 } 1014 1014 1015 1015 static const struct dev_pm_ops rcar_lvds_pm_ops = { 1016 - SET_RUNTIME_PM_OPS(rcar_lvds_runtime_suspend, rcar_lvds_runtime_resume, NULL) 1016 + RUNTIME_PM_OPS(rcar_lvds_runtime_suspend, rcar_lvds_runtime_resume, NULL) 1017 1017 }; 1018 1018 1019 1019 static struct platform_driver rcar_lvds_platform_driver = { ··· 1021 1021 .remove = rcar_lvds_remove, 1022 1022 .driver = { 1023 1023 .name = "rcar-lvds", 1024 - .pm = &rcar_lvds_pm_ops, 1024 + .pm = pm_ptr(&rcar_lvds_pm_ops), 1025 1025 .of_match_table = rcar_lvds_of_table, 1026 1026 }, 1027 1027 };
+225
drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c
··· 937 937 return 0; 938 938 } 939 939 940 + static ssize_t rcar_mipi_dsi_host_tx_transfer(struct mipi_dsi_host *host, 941 + const struct mipi_dsi_msg *msg, 942 + bool is_rx_xfer) 943 + { 944 + const bool is_tx_long = mipi_dsi_packet_format_is_long(msg->type); 945 + struct rcar_mipi_dsi *dsi = host_to_rcar_mipi_dsi(host); 946 + struct mipi_dsi_packet packet; 947 + u8 payload[16] = { 0 }; 948 + u32 status; 949 + int ret; 950 + 951 + ret = mipi_dsi_create_packet(&packet, msg); 952 + if (ret) 953 + return ret; 954 + 955 + /* Configure LP or HS command transfer. */ 956 + rcar_mipi_dsi_write(dsi, TXCMSETR, (msg->flags & MIPI_DSI_MSG_USE_LPM) ? 957 + TXCMSETR_SPDTYP : 0); 958 + 959 + /* Register access mode for RX transfer. */ 960 + if (is_rx_xfer) 961 + rcar_mipi_dsi_write(dsi, RXPSETR, 0); 962 + 963 + /* Do not use IRQ, poll for completion, the completion is quick. */ 964 + rcar_mipi_dsi_write(dsi, TXCMIER, 0); 965 + 966 + /* 967 + * Send the header: 968 + * header[0] = Virtual Channel + Data Type 969 + * header[1] = Word Count LSB (LP) or first param (SP) 970 + * header[2] = Word Count MSB (LP) or second param (SP) 971 + */ 972 + rcar_mipi_dsi_write(dsi, TXCMPHDR, 973 + (is_tx_long ? TXCMPHDR_FMT : 0) | 974 + TXCMPHDR_VC(msg->channel) | 975 + TXCMPHDR_DT(msg->type) | 976 + TXCMPHDR_DATA1(packet.header[2]) | 977 + TXCMPHDR_DATA0(packet.header[1])); 978 + 979 + if (is_tx_long) { 980 + memcpy(payload, packet.payload, 981 + min(msg->tx_len, sizeof(payload))); 982 + 983 + rcar_mipi_dsi_write(dsi, TXCMPPD0R, 984 + (payload[3] << 24) | (payload[2] << 16) | 985 + (payload[1] << 8) | payload[0]); 986 + rcar_mipi_dsi_write(dsi, TXCMPPD1R, 987 + (payload[7] << 24) | (payload[6] << 16) | 988 + (payload[5] << 8) | payload[4]); 989 + rcar_mipi_dsi_write(dsi, TXCMPPD2R, 990 + (payload[11] << 24) | (payload[10] << 16) | 991 + (payload[9] << 8) | payload[8]); 992 + rcar_mipi_dsi_write(dsi, TXCMPPD3R, 993 + (payload[15] << 24) | (payload[14] << 16) | 994 + (payload[13] << 8) | payload[12]); 995 + } 996 + 997 + /* Start the transfer, RX with BTA, TX without BTA. */ 998 + if (is_rx_xfer) { 999 + rcar_mipi_dsi_write(dsi, TXCMCR, TXCMCR_BTAREQ); 1000 + 1001 + /* Wait until the transmission, BTA, reception completed. */ 1002 + ret = read_poll_timeout(rcar_mipi_dsi_read, status, 1003 + (status & RXPSR_BTAREQEND), 1004 + 2000, 50000, false, dsi, RXPSR); 1005 + } else { 1006 + rcar_mipi_dsi_write(dsi, TXCMCR, TXCMCR_TXREQ); 1007 + 1008 + /* Wait until the transmission completed. */ 1009 + ret = read_poll_timeout(rcar_mipi_dsi_read, status, 1010 + (status & TXCMSR_TXREQEND), 1011 + 2000, 50000, false, dsi, TXCMSR); 1012 + } 1013 + 1014 + if (ret < 0) { 1015 + dev_err(dsi->dev, "Command transfer timeout (0x%08x)\n", 1016 + status); 1017 + return ret; 1018 + } 1019 + 1020 + return packet.size; 1021 + } 1022 + 1023 + static ssize_t rcar_mipi_dsi_host_rx_transfer(struct mipi_dsi_host *host, 1024 + const struct mipi_dsi_msg *msg) 1025 + { 1026 + struct rcar_mipi_dsi *dsi = host_to_rcar_mipi_dsi(host); 1027 + u8 *rx_buf = (u8 *)(msg->rx_buf); 1028 + u32 reg, data, status, wc; 1029 + int i, ret; 1030 + 1031 + /* RX transfer received data validation and parsing starts here. */ 1032 + reg = rcar_mipi_dsi_read(dsi, TOSR); 1033 + if (reg & TOSR_TATO) { /* Turn-Around TimeOut. */ 1034 + /* Clear TATO Turn-Around TimeOut bit. */ 1035 + rcar_mipi_dsi_write(dsi, TOSR, TOSR_TATO); 1036 + return -ETIMEDOUT; 1037 + } 1038 + 1039 + reg = rcar_mipi_dsi_read(dsi, RXPSR); 1040 + 1041 + if (msg->flags & MIPI_DSI_MSG_REQ_ACK) { 1042 + /* Transfer with zero-length RX. */ 1043 + if (!(reg & RXPSR_RCVACK)) { 1044 + /* No ACK on RX response received. */ 1045 + return -EINVAL; 1046 + } 1047 + } else { 1048 + /* Transfer with non-zero-length RX. */ 1049 + if (!(reg & RXPSR_RCVRESP)) { 1050 + /* No packet header of RX response received. */ 1051 + return -EINVAL; 1052 + } 1053 + 1054 + if (reg & (RXPSR_CRCERR | RXPSR_WCERR | RXPSR_AXIERR | RXPSR_OVRERR)) { 1055 + /* Incorrect response payload. */ 1056 + return -ENODATA; 1057 + } 1058 + 1059 + data = rcar_mipi_dsi_read(dsi, RXPHDR); 1060 + if (data & RXPHDR_FMT) { /* Long Packet Response. */ 1061 + /* Read Long Packet Response length from packet header. */ 1062 + wc = data & 0xffff; 1063 + if (wc > msg->rx_len) { 1064 + dev_warn(dsi->dev, 1065 + "Long Packet Response longer than RX buffer (%d), limited to %zu Bytes\n", 1066 + wc, msg->rx_len); 1067 + wc = msg->rx_len; 1068 + } 1069 + 1070 + if (wc > 16) { 1071 + dev_warn(dsi->dev, 1072 + "Long Packet Response too long (%d), limited to 16 Bytes\n", 1073 + wc); 1074 + wc = 16; 1075 + } 1076 + 1077 + for (i = 0; i < msg->rx_len; i++) { 1078 + if (!(i % 4)) 1079 + data = rcar_mipi_dsi_read(dsi, RXPPD0R + i); 1080 + 1081 + rx_buf[i] = data & 0xff; 1082 + data >>= 8; 1083 + } 1084 + } else { /* Short Packet Response. */ 1085 + if (msg->rx_len >= 1) 1086 + rx_buf[0] = data & 0xff; 1087 + if (msg->rx_len >= 2) 1088 + rx_buf[1] = (data >> 8) & 0xff; 1089 + if (msg->rx_len >= 3) { 1090 + dev_warn(dsi->dev, 1091 + "Expected Short Packet Response too long (%zu), limited to 2 Bytes\n", 1092 + msg->rx_len); 1093 + } 1094 + } 1095 + } 1096 + 1097 + if (reg & RXPSR_RCVAKE) { 1098 + /* Acknowledge and Error report received. */ 1099 + return -EFAULT; 1100 + } 1101 + 1102 + /* Wait until the bus handover to host processor completed. */ 1103 + ret = read_poll_timeout(rcar_mipi_dsi_read, status, 1104 + !(status & PPIDL0SR_DIR), 1105 + 2000, 50000, false, dsi, PPIDL0SR); 1106 + if (ret < 0) { 1107 + dev_err(dsi->dev, "Command RX DIR timeout (0x%08x)\n", status); 1108 + return ret; 1109 + } 1110 + 1111 + /* Wait until the data lane is in LP11 stop state. */ 1112 + ret = read_poll_timeout(rcar_mipi_dsi_read, status, 1113 + status & PPIDL0SR_STPST, 1114 + 2000, 50000, false, dsi, PPIDL0SR); 1115 + if (ret < 0) { 1116 + dev_err(dsi->dev, "Command RX STPST timeout (0x%08x)\n", status); 1117 + return ret; 1118 + } 1119 + 1120 + return 0; 1121 + } 1122 + 1123 + static ssize_t rcar_mipi_dsi_host_transfer(struct mipi_dsi_host *host, 1124 + const struct mipi_dsi_msg *msg) 1125 + { 1126 + const bool is_rx_xfer = (msg->flags & MIPI_DSI_MSG_REQ_ACK) || msg->rx_len; 1127 + struct rcar_mipi_dsi *dsi = host_to_rcar_mipi_dsi(host); 1128 + int ret; 1129 + 1130 + if (msg->tx_len > 16 || msg->rx_len > 16) { 1131 + /* ToDo: Implement Memory on AXI bus command mode. */ 1132 + dev_warn(dsi->dev, 1133 + "Register-based command mode supports only up to 16 Bytes long payload\n"); 1134 + return -EOPNOTSUPP; 1135 + } 1136 + 1137 + ret = rcar_mipi_dsi_host_tx_transfer(host, msg, is_rx_xfer); 1138 + 1139 + /* If TX transfer succeeded and this transfer has RX part. */ 1140 + if (ret >= 0 && is_rx_xfer) { 1141 + ret = rcar_mipi_dsi_host_rx_transfer(host, msg); 1142 + if (ret) 1143 + return ret; 1144 + 1145 + ret = msg->rx_len; 1146 + } 1147 + 1148 + /* 1149 + * Wait a bit between commands, otherwise panels based on ILI9881C 1150 + * TCON may fail to correctly receive all commands sent to them. 1151 + * Until we can actually test with another DSI device, keep the 1152 + * delay here, but eventually this delay might have to be moved 1153 + * into the ILI9881C panel driver. 1154 + */ 1155 + usleep_range(1000, 2000); 1156 + 1157 + /* Clear the completion interrupt. */ 1158 + if (!msg->rx_len) 1159 + rcar_mipi_dsi_write(dsi, TXCMSR, TXCMSR_TXREQEND); 1160 + 1161 + return ret; 1162 + } 1163 + 940 1164 static const struct mipi_dsi_host_ops rcar_mipi_dsi_host_ops = { 941 1165 .attach = rcar_mipi_dsi_host_attach, 942 1166 .detach = rcar_mipi_dsi_host_detach, 1167 + .transfer = rcar_mipi_dsi_host_transfer 943 1168 }; 944 1169 945 1170 /* -----------------------------------------------------------------------------
+125
drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h
··· 16 16 #define TXSETR_LANECNT_MASK (0x3 << 0) 17 17 18 18 /* 19 + * DSI Command Transfer Registers 20 + */ 21 + #define TXCMSETR 0x110 22 + #define TXCMSETR_SPDTYP (1 << 8) /* 0:HS 1:LP */ 23 + #define TXCMSETR_LPPDACC (1 << 0) 24 + #define TXCMCR 0x120 25 + #define TXCMCR_BTATYP (1 << 2) 26 + #define TXCMCR_BTAREQ (1 << 1) 27 + #define TXCMCR_TXREQ (1 << 0) 28 + #define TXCMSR 0x130 29 + #define TXCMSR_CLSNERR (1 << 18) 30 + #define TXCMSR_AXIERR (1 << 16) 31 + #define TXCMSR_TXREQEND (1 << 0) 32 + #define TXCMSCR 0x134 33 + #define TXCMSCR_CLSNERR (1 << 18) 34 + #define TXCMSCR_AXIERR (1 << 16) 35 + #define TXCMSCR_TXREQEND (1 << 0) 36 + #define TXCMIER 0x138 37 + #define TXCMIER_CLSNERR (1 << 18) 38 + #define TXCMIER_AXIERR (1 << 16) 39 + #define TXCMIER_TXREQEND (1 << 0) 40 + #define TXCMADDRSET0R 0x140 41 + #define TXCMPHDR 0x150 42 + #define TXCMPHDR_FMT (1 << 24) /* 0:SP 1:LP */ 43 + #define TXCMPHDR_VC(n) (((n) & 0x3) << 22) 44 + #define TXCMPHDR_DT(n) (((n) & 0x3f) << 16) 45 + #define TXCMPHDR_DATA1(n) (((n) & 0xff) << 8) 46 + #define TXCMPHDR_DATA0(n) (((n) & 0xff) << 0) 47 + #define TXCMPPD0R 0x160 48 + #define TXCMPPD1R 0x164 49 + #define TXCMPPD2R 0x168 50 + #define TXCMPPD3R 0x16c 51 + 52 + #define RXSETR 0x200 53 + #define RXSETR_CRCEN (((n) & 0xf) << 24) 54 + #define RXSETR_ECCEN (((n) & 0xf) << 16) 55 + #define RXPSETR 0x210 56 + #define RXPSETR_LPPDACC (1 << 0) 57 + #define RXPSR 0x220 58 + #define RXPSR_ECCERR1B (1 << 28) 59 + #define RXPSR_UEXTRGERR (1 << 25) 60 + #define RXPSR_RESPTOERR (1 << 24) 61 + #define RXPSR_OVRERR (1 << 23) 62 + #define RXPSR_AXIERR (1 << 22) 63 + #define RXPSR_CRCERR (1 << 21) 64 + #define RXPSR_WCERR (1 << 20) 65 + #define RXPSR_UEXDTERR (1 << 19) 66 + #define RXPSR_UEXPKTERR (1 << 18) 67 + #define RXPSR_ECCERR (1 << 17) 68 + #define RXPSR_MLFERR (1 << 16) 69 + #define RXPSR_RCVACK (1 << 14) 70 + #define RXPSR_RCVEOT (1 << 10) 71 + #define RXPSR_RCVAKE (1 << 9) 72 + #define RXPSR_RCVRESP (1 << 8) 73 + #define RXPSR_BTAREQEND (1 << 0) 74 + #define RXPSCR 0x224 75 + #define RXPSCR_ECCERR1B (1 << 28) 76 + #define RXPSCR_UEXTRGERR (1 << 25) 77 + #define RXPSCR_RESPTOERR (1 << 24) 78 + #define RXPSCR_OVRERR (1 << 23) 79 + #define RXPSCR_AXIERR (1 << 22) 80 + #define RXPSCR_CRCERR (1 << 21) 81 + #define RXPSCR_WCERR (1 << 20) 82 + #define RXPSCR_UEXDTERR (1 << 19) 83 + #define RXPSCR_UEXPKTERR (1 << 18) 84 + #define RXPSCR_ECCERR (1 << 17) 85 + #define RXPSCR_MLFERR (1 << 16) 86 + #define RXPSCR_RCVACK (1 << 14) 87 + #define RXPSCR_RCVEOT (1 << 10) 88 + #define RXPSCR_RCVAKE (1 << 9) 89 + #define RXPSCR_RCVRESP (1 << 8) 90 + #define RXPSCR_BTAREQEND (1 << 0) 91 + #define RXPIER 0x228 92 + #define RXPIER_ECCERR1B (1 << 28) 93 + #define RXPIER_UEXTRGERR (1 << 25) 94 + #define RXPIER_RESPTOERR (1 << 24) 95 + #define RXPIER_OVRERR (1 << 23) 96 + #define RXPIER_AXIERR (1 << 22) 97 + #define RXPIER_CRCERR (1 << 21) 98 + #define RXPIER_WCERR (1 << 20) 99 + #define RXPIER_UEXDTERR (1 << 19) 100 + #define RXPIER_UEXPKTERR (1 << 18) 101 + #define RXPIER_ECCERR (1 << 17) 102 + #define RXPIER_MLFERR (1 << 16) 103 + #define RXPIER_RCVACK (1 << 14) 104 + #define RXPIER_RCVEOT (1 << 10) 105 + #define RXPIER_RCVAKE (1 << 9) 106 + #define RXPIER_RCVRESP (1 << 8) 107 + #define RXPIER_BTAREQEND (1 << 0) 108 + #define RXPADDRSET0R 0x230 109 + #define RXPSIZESETR 0x238 110 + #define RXPSIZESETR_SIZE(n) (((n) & 0xf) << 3) 111 + #define RXPHDR 0x240 112 + #define RXPHDR_FMT (1 << 24) /* 0:SP 1:LP */ 113 + #define RXPHDR_VC(n) (((n) & 0x3) << 22) 114 + #define RXPHDR_DT(n) (((n) & 0x3f) << 16) 115 + #define RXPHDR_DATA1(n) (((n) & 0xff) << 8) 116 + #define RXPHDR_DATA0(n) (((n) & 0xff) << 0) 117 + #define RXPPD0R 0x250 118 + #define RXPPD1R 0x254 119 + #define RXPPD2R 0x258 120 + #define RXPPD3R 0x25c 121 + #define AKEPR 0x300 122 + #define AKEPR_VC(n) (((n) & 0x3) << 22) 123 + #define AKEPR_DT(n) (((n) & 0x3f) << 16) 124 + #define AKEPR_ERRRPT(n) (((n) & 0xffff) << 0) 125 + #define RXRESPTOSETR 0x400 126 + #define TACR 0x500 127 + #define TASR 0x510 128 + #define TASCR 0x514 129 + #define TAIER 0x518 130 + #define TOSR 0x610 131 + #define TOSR_TATO (1 << 2) 132 + #define TOSR_LRXHTO (1 << 1) 133 + #define TOSR_HRXTO (1 << 0) 134 + #define TOSCR 0x614 135 + #define TOSCR_TATO (1 << 2) 136 + #define TOSCR_LRXHTO (1 << 1) 137 + #define TOSCR_HRXTO (1 << 0) 138 + 139 + /* 19 140 * Video Mode Register 20 141 */ 21 142 #define TXVMSETR 0x180 ··· 220 99 #define PPICLSCR 0x724 221 100 #define PPICLSCR_HSTOLP (1 << 27) 222 101 #define PPICLSCR_TOHS (1 << 26) 102 + 103 + #define PPIDL0SR 0x740 104 + #define PPIDL0SR_DIR (1 << 10) 105 + #define PPIDL0SR_STPST (1 << 6) 223 106 224 107 #define PPIDLSR 0x760 225 108 #define PPIDLSR_STPST (0xf << 0)
+1 -1
drivers/gpu/drm/sti/sti_hqvdp.c
··· 744 744 745 745 inv_zy = DIV_ROUND_UP(src_h, dst_h); 746 746 747 - return (inv_zy <= lfw) ? true : false; 747 + return inv_zy <= lfw; 748 748 } 749 749 750 750 /**
+15
drivers/gpu/drm/tiny/Kconfig
··· 82 82 https://github.com/notro/panel-mipi-dbi/wiki. 83 83 To compile this driver as a module, choose M here. 84 84 85 + config DRM_PIXPAPER 86 + tristate "DRM support for PIXPAPER display panels" 87 + depends on DRM && SPI 88 + select DRM_CLIENT_SELECTION 89 + select DRM_GEM_DMA_HELPER 90 + select DRM_KMS_HELPER 91 + help 92 + DRM driver for the Mayqueen Pixpaper e-ink display panel. 93 + 94 + This driver supports small e-paper displays connected over SPI, 95 + with a resolution of 122x250 and XRGB8888 framebuffer format. 96 + It is intended for low-power embedded applications. 97 + 98 + If M is selected, the module will be built as pixpaper.ko. 99 + 85 100 config TINYDRM_HX8357D 86 101 tristate "DRM support for HX8357D display panels" 87 102 depends on DRM && SPI
+1
drivers/gpu/drm/tiny/Makefile
··· 6 6 obj-$(CONFIG_DRM_CIRRUS_QEMU) += cirrus-qemu.o 7 7 obj-$(CONFIG_DRM_GM12U320) += gm12u320.o 8 8 obj-$(CONFIG_DRM_PANEL_MIPI_DBI) += panel-mipi-dbi.o 9 + obj-$(CONFIG_DRM_PIXPAPER) += pixpaper.o 9 10 obj-$(CONFIG_TINYDRM_HX8357D) += hx8357d.o 10 11 obj-$(CONFIG_TINYDRM_ILI9163) += ili9163.o 11 12 obj-$(CONFIG_TINYDRM_ILI9225) += ili9225.o
+1 -1
drivers/gpu/drm/tiny/bochs.c
··· 252 252 } 253 253 bochs->ioports = 1; 254 254 } else { 255 - dev_err(dev->dev, "I/O ports are not supported\n"); 255 + drm_err(dev, "I/O ports are not supported\n"); 256 256 return -EIO; 257 257 } 258 258
+1165
drivers/gpu/drm/tiny/pixpaper.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * DRM driver for PIXPAPER e-ink panel 4 + * 5 + * Author: LiangCheng Wang <zaq14760@gmail.com>, 6 + */ 7 + #include <linux/delay.h> 8 + #include <linux/module.h> 9 + #include <linux/spi/spi.h> 10 + 11 + #include <drm/clients/drm_client_setup.h> 12 + #include <drm/drm_atomic.h> 13 + #include <drm/drm_atomic_helper.h> 14 + #include <drm/drm_drv.h> 15 + #include <drm/drm_fbdev_shmem.h> 16 + #include <drm/drm_framebuffer.h> 17 + #include <drm/drm_gem_atomic_helper.h> 18 + #include <drm/drm_gem_shmem_helper.h> 19 + #include <drm/drm_gem_framebuffer_helper.h> 20 + #include <drm/drm_probe_helper.h> 21 + 22 + /* 23 + * Note on Undocumented Commands/Registers: 24 + * 25 + * Several commands and register parameters defined in this header are not 26 + * documented in the datasheet. Their values and usage have been derived 27 + * through analysis of existing userspace example programs. 28 + * 29 + * These 'unknown' definitions are crucial for the proper initialization 30 + * and stable operation of the panel. Modifying these values without 31 + * thorough understanding may lead to display anomalies, panel damage, 32 + * or unexpected behavior. 33 + */ 34 + 35 + /* Command definitions */ 36 + #define PIXPAPER_CMD_PANEL_SETTING 0x00 /* R00H: Panel settings */ 37 + #define PIXPAPER_CMD_POWER_SETTING 0x01 /* R01H: Power settings */ 38 + #define PIXPAPER_CMD_POWER_OFF 0x02 /* R02H: Power off */ 39 + #define PIXPAPER_CMD_POWER_OFF_SEQUENCE 0x03 /* R03H: Power off sequence */ 40 + #define PIXPAPER_CMD_POWER_ON 0x04 /* R04H: Power on */ 41 + #define PIXPAPER_CMD_BOOSTER_SOFT_START 0x06 /* R06H: Booster soft start */ 42 + #define PIXPAPER_CMD_DEEP_SLEEP 0x07 /* R07H: Deep sleep */ 43 + #define PIXPAPER_CMD_DATA_START_TRANSMISSION 0x10 44 + /* R10H: Data transmission start */ 45 + #define PIXPAPER_CMD_DISPLAY_REFRESH 0x12 /* R12H: Display refresh */ 46 + #define PIXPAPER_CMD_PLL_CONTROL 0x30 /* R30H: PLL control */ 47 + #define PIXPAPER_CMD_TEMP_SENSOR_CALIB 0x41 48 + /* R41H: Temperature sensor calibration */ 49 + #define PIXPAPER_CMD_UNKNOWN_4D 0x4D /* R4DH: Unknown command */ 50 + #define PIXPAPER_CMD_VCOM_INTERVAL 0x50 /* R50H: VCOM interval */ 51 + #define PIXPAPER_CMD_UNKNOWN_60 0x60 /* R60H: Unknown command */ 52 + #define PIXPAPER_CMD_RESOLUTION_SETTING 0x61 /* R61H: Resolution settings */ 53 + #define PIXPAPER_CMD_GATE_SOURCE_START 0x65 /* R65H: Gate/source start */ 54 + #define PIXPAPER_CMD_UNKNOWN_B4 0xB4 /* RB4H: Unknown command */ 55 + #define PIXPAPER_CMD_UNKNOWN_B5 0xB5 /* RB5H: Unknown command */ 56 + #define PIXPAPER_CMD_UNKNOWN_E0 0xE0 /* RE0H: Unknown command */ 57 + #define PIXPAPER_CMD_POWER_SAVING 0xE3 /* RE3H: Power saving */ 58 + #define PIXPAPER_CMD_UNKNOWN_E7 0xE7 /* RE7H: Unknown command */ 59 + #define PIXPAPER_CMD_UNKNOWN_E9 0xE9 /* RE9H: Unknown command */ 60 + 61 + /* R00H PSR - First Parameter */ 62 + #define PIXPAPER_PSR_RST_N BIT(0) 63 + /* Bit 0: RST_N, 1=no effect (default), 0=reset with booster OFF */ 64 + #define PIXPAPER_PSR_SHD_N BIT(1) 65 + /* Bit 1: SHD_N, 1=booster ON (default), 0=booster OFF */ 66 + #define PIXPAPER_PSR_SHL BIT(2) 67 + /* Bit 2: SHL, 1=shift right (default), 0=shift left */ 68 + #define PIXPAPER_PSR_UD BIT(3) 69 + /* Bit 3: UD, 1=scan up (default), 0=scan down */ 70 + #define PIXPAPER_PSR_PST_MODE BIT(5) 71 + /* Bit 5: PST_MODE, 0=frame scanning (default), 1=external */ 72 + #define PIXPAPER_PSR_RES_MASK (3 << 6) 73 + /* Bits 7-6: RES[1:0], resolution setting */ 74 + #define PIXPAPER_PSR_RES_176x296 (0x0 << 6) /* 00: 176x296 */ 75 + #define PIXPAPER_PSR_RES_128x296 (0x1 << 6) /* 01: 128x296 */ 76 + #define PIXPAPER_PSR_RES_128x250 (0x2 << 6) /* 10: 128x250 */ 77 + #define PIXPAPER_PSR_RES_112x204 (0x3 << 6) /* 11: 112x204 */ 78 + #define PIXPAPER_PSR_CONFIG \ 79 + (PIXPAPER_PSR_RST_N | PIXPAPER_PSR_SHD_N | PIXPAPER_PSR_SHL | \ 80 + PIXPAPER_PSR_UD) 81 + /* 0x0F: Default settings, resolution set by R61H */ 82 + 83 + /* R00H PSR - Second Parameter */ 84 + #define PIXPAPER_PSR2_VC_LUTZ \ 85 + (1 << 0) /* Bit 0: VC_LUTZ, 1=VCOM float after refresh (default), 0=no effect */ 86 + #define PIXPAPER_PSR2_NORG \ 87 + (1 << 1) /* Bit 1: NORG, 1=VCOM to GND before power off, 0=no effect (default) */ 88 + #define PIXPAPER_PSR2_TIEG \ 89 + (1 << 2) /* Bit 2: TIEG, 1=VGN to GND on power off, 0=no effect (default) */ 90 + #define PIXPAPER_PSR2_TS_AUTO \ 91 + (1 << 3) /* Bit 3: TS_AUTO, 1=sensor on RST_N low to high (default), 0=on booster */ 92 + #define PIXPAPER_PSR2_VCMZ \ 93 + (1 << 4) /* Bit 4: VCMZ, 1=VCOM always floating, 0=no effect (default) */ 94 + #define PIXPAPER_PSR2_FOPT \ 95 + (1 << 5) /* Bit 5: FOPT, 0=scan 1 frame (default), 1=no scan, HiZ */ 96 + #define PIXPAPER_PSR_CONFIG2 \ 97 + (PIXPAPER_PSR2_VC_LUTZ | \ 98 + PIXPAPER_PSR2_TS_AUTO) /* 0x09: Default VCOM and temp sensor settings */ 99 + 100 + /* R01H PWR - Power Setting Register */ 101 + /* First Parameter */ 102 + #define PIXPAPER_PWR_VDG_EN \ 103 + (1 << 0) /* Bit 0: VDG_EN, 1=internal DCDC for VGP/VGN (default), 0=external */ 104 + #define PIXPAPER_PWR_VDS_EN \ 105 + (1 << 1) /* Bit 1: VDS_EN, 1=internal regulator for VSP/VSN (default), 0=external */ 106 + #define PIXPAPER_PWR_VSC_EN \ 107 + (1 << 2) /* Bit 2: VSC_EN, 1=internal regulator for VSPL (default), 0=external */ 108 + #define PIXPAPER_PWR_V_MODE \ 109 + (1 << 3) /* Bit 3: V_MODE, 0=Mode0 (default), 1=Mode1 */ 110 + #define PIXPAPER_PWR_CONFIG1 \ 111 + (PIXPAPER_PWR_VDG_EN | PIXPAPER_PWR_VDS_EN | \ 112 + PIXPAPER_PWR_VSC_EN) /* 0x07: Internal power for VGP/VGN, VSP/VSN, VSPL */ 113 + 114 + /* Second Parameter */ 115 + #define PIXPAPER_PWR_VGPN_MASK \ 116 + (3 << 0) /* Bits 1-0: VGPN, VGP/VGN voltage levels */ 117 + #define PIXPAPER_PWR_VGPN_20V (0x0 << 0) /* 00: VGP=20V, VGN=-20V (default) */ 118 + #define PIXPAPER_PWR_VGPN_17V (0x1 << 0) /* 01: VGP=17V, VGN=-17V */ 119 + #define PIXPAPER_PWR_VGPN_15V (0x2 << 0) /* 10: VGP=15V, VGN=-15V */ 120 + #define PIXPAPER_PWR_VGPN_10V (0x3 << 0) /* 11: VGP=10V, VGN=-10V */ 121 + #define PIXPAPER_PWR_CONFIG2 PIXPAPER_PWR_VGPN_20V /* 0x00: VGP=20V, VGN=-20V */ 122 + 123 + /* Third, Fourth, Sixth Parameters (VSP_1, VSPL_0, VSPL_1) */ 124 + #define PIXPAPER_PWR_VSP_8_2V 0x22 /* VSP_1/VSPL_1: 8.2V (34 decimal) */ 125 + #define PIXPAPER_PWR_VSPL_15V 0x78 /* VSPL_0: 15V (120 decimal) */ 126 + 127 + /* Fifth Parameter (VSN_1) */ 128 + #define PIXPAPER_PWR_VSN_4V 0x0A /* VSN_1: -4V (10 decimal) */ 129 + 130 + /* R03H PFS - Power Off Sequence Setting Register */ 131 + /* First Parameter */ 132 + #define PIXPAPER_PFS_T_VDS_OFF_MASK \ 133 + (3 << 0) /* Bits 1-0: T_VDS_OFF, VSP/VSN power-off sequence */ 134 + #define PIXPAPER_PFS_T_VDS_OFF_20MS (0x0 << 0) /* 00: 20 ms (default) */ 135 + #define PIXPAPER_PFS_T_VDS_OFF_40MS (0x1 << 0) /* 01: 40 ms */ 136 + #define PIXPAPER_PFS_T_VDS_OFF_60MS (0x2 << 0) /* 10: 60 ms */ 137 + #define PIXPAPER_PFS_T_VDS_OFF_80MS (0x3 << 0) /* 11: 80 ms */ 138 + #define PIXPAPER_PFS_T_VDPG_OFF_MASK \ 139 + (3 << 4) /* Bits 5-4: T_VDPG_OFF, VGP/VGN power-off sequence */ 140 + #define PIXPAPER_PFS_T_VDPG_OFF_20MS (0x0 << 4) /* 00: 20 ms (default) */ 141 + #define PIXPAPER_PFS_T_VDPG_OFF_40MS (0x1 << 4) /* 01: 40 ms */ 142 + #define PIXPAPER_PFS_T_VDPG_OFF_60MS (0x2 << 4) /* 10: 60 ms */ 143 + #define PIXPAPER_PFS_T_VDPG_OFF_80MS (0x3 << 4) /* 11: 80 ms */ 144 + #define PIXPAPER_PFS_CONFIG1 \ 145 + (PIXPAPER_PFS_T_VDS_OFF_20MS | \ 146 + PIXPAPER_PFS_T_VDPG_OFF_20MS) /* 0x10: Default 20 ms for VSP/VSN and VGP/VGN */ 147 + 148 + /* Second Parameter */ 149 + #define PIXPAPER_PFS_VGP_EXT_MASK \ 150 + (0xF << 0) /* Bits 3-0: VGP_EXT, VGP extension time */ 151 + #define PIXPAPER_PFS_VGP_EXT_0MS (0x0 << 0) /* 0000: 0 ms */ 152 + #define PIXPAPER_PFS_VGP_EXT_500MS (0x1 << 0) /* 0001: 500 ms */ 153 + #define PIXPAPER_PFS_VGP_EXT_1000MS (0x2 << 0) /* 0010: 1000 ms */ 154 + #define PIXPAPER_PFS_VGP_EXT_1500MS (0x3 << 0) /* 0011: 1500 ms */ 155 + #define PIXPAPER_PFS_VGP_EXT_2000MS (0x4 << 0) /* 0100: 2000 ms (default) */ 156 + #define PIXPAPER_PFS_VGP_EXT_2500MS (0x5 << 0) /* 0101: 2500 ms */ 157 + #define PIXPAPER_PFS_VGP_EXT_3000MS (0x6 << 0) /* 0110: 3000 ms */ 158 + #define PIXPAPER_PFS_VGP_EXT_3500MS (0x7 << 0) /* 0111: 3500 ms */ 159 + #define PIXPAPER_PFS_VGP_EXT_4000MS (0x8 << 0) /* 1000: 4000 ms */ 160 + #define PIXPAPER_PFS_VGP_EXT_4500MS (0x9 << 0) /* 1001: 4500 ms */ 161 + #define PIXPAPER_PFS_VGP_EXT_5000MS (0xA << 0) /* 1010: 5000 ms */ 162 + #define PIXPAPER_PFS_VGP_EXT_5500MS (0xB << 0) /* 1011: 5500 ms */ 163 + #define PIXPAPER_PFS_VGP_EXT_6000MS (0xC << 0) /* 1100: 6000 ms */ 164 + #define PIXPAPER_PFS_VGP_EXT_6500MS (0xD << 0) /* 1101: 6500 ms */ 165 + #define PIXPAPER_PFS_VGP_LEN_MASK \ 166 + (0xF << 4) /* Bits 7-4: VGP_LEN, VGP at 10V during power-off */ 167 + #define PIXPAPER_PFS_VGP_LEN_0MS (0x0 << 4) /* 0000: 0 ms */ 168 + #define PIXPAPER_PFS_VGP_LEN_500MS (0x1 << 4) /* 0001: 500 ms */ 169 + #define PIXPAPER_PFS_VGP_LEN_1000MS (0x2 << 4) /* 0010: 1000 ms */ 170 + #define PIXPAPER_PFS_VGP_LEN_1500MS (0x3 << 4) /* 0011: 1500 ms */ 171 + #define PIXPAPER_PFS_VGP_LEN_2000MS (0x4 << 4) /* 0100: 2000 ms */ 172 + #define PIXPAPER_PFS_VGP_LEN_2500MS (0x5 << 4) /* 0101: 2500 ms (default) */ 173 + #define PIXPAPER_PFS_VGP_LEN_3000MS (0x6 << 4) /* 0110: 3000 ms */ 174 + #define PIXPAPER_PFS_VGP_LEN_3500MS (0x7 << 4) /* 0111: 3500 ms */ 175 + #define PIXPAPER_PFS_VGP_LEN_4000MS (0x8 << 4) /* 1000: 4000 ms */ 176 + #define PIXPAPER_PFS_VGP_LEN_4500MS (0x9 << 4) /* 1001: 4500 ms */ 177 + #define PIXPAPER_PFS_VGP_LEN_5000MS (0xA << 4) /* 1010: 5000 ms */ 178 + #define PIXPAPER_PFS_VGP_LEN_5500MS (0xB << 4) /* 1011: 5500 ms */ 179 + #define PIXPAPER_PFS_VGP_LEN_6000MS (0xC << 4) /* 1100: 6000 ms */ 180 + #define PIXPAPER_PFS_VGP_LEN_6500MS (0xD << 4) /* 1101: 6500 ms */ 181 + #define PIXPAPER_PFS_CONFIG2 \ 182 + (PIXPAPER_PFS_VGP_EXT_1000MS | \ 183 + PIXPAPER_PFS_VGP_LEN_2500MS) /* 0x54: VGP extension 1000 ms, VGP at 10V for 2500 ms */ 184 + 185 + /* Third Parameter */ 186 + #define PIXPAPER_PFS_XON_LEN_MASK \ 187 + (0xF << 0) /* Bits 3-0: XON_LEN, XON enable time */ 188 + #define PIXPAPER_PFS_XON_LEN_0MS (0x0 << 0) /* 0000: 0 ms */ 189 + #define PIXPAPER_PFS_XON_LEN_500MS (0x1 << 0) /* 0001: 500 ms */ 190 + #define PIXPAPER_PFS_XON_LEN_1000MS (0x2 << 0) /* 0010: 1000 ms */ 191 + #define PIXPAPER_PFS_XON_LEN_1500MS (0x3 << 0) /* 0011: 1500 ms */ 192 + #define PIXPAPER_PFS_XON_LEN_2000MS (0x4 << 0) /* 0100: 2000 ms (default) */ 193 + #define PIXPAPER_PFS_XON_LEN_2500MS (0x5 << 0) /* 0101: 2500 ms */ 194 + #define PIXPAPER_PFS_XON_LEN_3000MS (0x6 << 0) /* 0110: 3000 ms */ 195 + #define PIXPAPER_PFS_XON_LEN_3500MS (0x7 << 0) /* 0111: 3500 ms */ 196 + #define PIXPAPER_PFS_XON_LEN_4000MS (0x8 << 0) /* 1000: 4000 ms */ 197 + #define PIXPAPER_PFS_XON_LEN_4500MS (0x9 << 0) /* 1001: 4500 ms */ 198 + #define PIXPAPER_PFS_XON_LEN_5000MS (0xA << 0) /* 1010: 5000 ms */ 199 + #define PIXPAPER_PFS_XON_LEN_5500MS (0xB << 0) /* 1011: 5500 ms */ 200 + #define PIXPAPER_PFS_XON_LEN_6000MS (0xC << 0) /* 1100: 6000 ms */ 201 + #define PIXPAPER_PFS_XON_DLY_MASK \ 202 + (0xF << 4) /* Bits 7-4: XON_DLY, XON delay time */ 203 + #define PIXPAPER_PFS_XON_DLY_0MS (0x0 << 4) /* 0000: 0 ms */ 204 + #define PIXPAPER_PFS_XON_DLY_500MS (0x1 << 4) /* 0001: 500 ms */ 205 + #define PIXPAPER_PFS_XON_DLY_1000MS (0x2 << 4) /* 0010: 1000 ms */ 206 + #define PIXPAPER_PFS_XON_DLY_1500MS (0x3 << 4) /* 0011: 1500 ms */ 207 + #define PIXPAPER_PFS_XON_DLY_2000MS (0x4 << 4) /* 0100: 2000 ms (default) */ 208 + #define PIXPAPER_PFS_XON_DLY_2500MS (0x5 << 4) /* 0101: 2500 ms */ 209 + #define PIXPAPER_PFS_XON_DLY_3000MS (0x6 << 4) /* 0110: 3000 ms */ 210 + #define PIXPAPER_PFS_XON_DLY_3500MS (0x7 << 4) /* 0111: 3500 ms */ 211 + #define PIXPAPER_PFS_XON_DLY_4000MS (0x8 << 4) /* 1000: 4000 ms */ 212 + #define PIXPAPER_PFS_XON_DLY_4500MS (0x9 << 4) /* 1001: 4500 ms */ 213 + #define PIXPAPER_PFS_XON_DLY_5000MS (0xA << 4) /* 1010: 5000 ms */ 214 + #define PIXPAPER_PFS_XON_DLY_5500MS (0xB << 4) /* 1011: 5500 ms */ 215 + #define PIXPAPER_PFS_XON_DLY_6000MS (0xC << 4) /* 1100: 6000 ms */ 216 + #define PIXPAPER_PFS_CONFIG3 \ 217 + (PIXPAPER_PFS_XON_LEN_2000MS | \ 218 + PIXPAPER_PFS_XON_DLY_2000MS) /* 0x44: XON enable and delay at 2000 ms */ 219 + 220 + /* R06H BTST - Booster Soft Start Command */ 221 + /* First Parameter */ 222 + #define PIXPAPER_BTST_PHA_SFT_MASK \ 223 + (3 << 0) /* Bits 1-0: PHA_SFT, soft start period for phase A */ 224 + #define PIXPAPER_BTST_PHA_SFT_10MS (0x0 << 0) /* 00: 10 ms (default) */ 225 + #define PIXPAPER_BTST_PHA_SFT_20MS (0x1 << 0) /* 01: 20 ms */ 226 + #define PIXPAPER_BTST_PHA_SFT_30MS (0x2 << 0) /* 10: 30 ms */ 227 + #define PIXPAPER_BTST_PHA_SFT_40MS (0x3 << 0) /* 11: 40 ms */ 228 + #define PIXPAPER_BTST_PHB_SFT_MASK \ 229 + (3 << 2) /* Bits 3-2: PHB_SFT, soft start period for phase B */ 230 + #define PIXPAPER_BTST_PHB_SFT_10MS (0x0 << 2) /* 00: 10 ms (default) */ 231 + #define PIXPAPER_BTST_PHB_SFT_20MS (0x1 << 2) /* 01: 20 ms */ 232 + #define PIXPAPER_BTST_PHB_SFT_30MS (0x2 << 2) /* 10: 30 ms */ 233 + #define PIXPAPER_BTST_PHB_SFT_40MS (0x3 << 2) /* 11: 40 ms */ 234 + #define PIXPAPER_BTST_CONFIG1 \ 235 + (PIXPAPER_BTST_PHA_SFT_40MS | \ 236 + PIXPAPER_BTST_PHB_SFT_40MS) /* 0x0F: 40 ms for phase A and B */ 237 + 238 + /* Second to Seventh Parameters (Driving Strength or Minimum OFF Time) */ 239 + #define PIXPAPER_BTST_CONFIG2 0x0A /* Strength11 */ 240 + #define PIXPAPER_BTST_CONFIG3 0x2F /* Period48 */ 241 + #define PIXPAPER_BTST_CONFIG4 0x25 /* Strength38 */ 242 + #define PIXPAPER_BTST_CONFIG5 0x22 /* Period35 */ 243 + #define PIXPAPER_BTST_CONFIG6 0x2E /* Strength47 */ 244 + #define PIXPAPER_BTST_CONFIG7 0x21 /* Period34 */ 245 + 246 + /* R12H: DRF (Display Refresh) */ 247 + #define PIXPAPER_DRF_VCOM_AC 0x00 /* AC VCOM: VCOM follows LUTC (default) */ 248 + #define PIXPAPER_DRF_VCOM_DC 0x01 /* DC VCOM: VCOM fixed to VCOMDC */ 249 + 250 + /* R30H PLL - PLL Control Register */ 251 + /* First Parameter */ 252 + #define PIXPAPER_PLL_FR_MASK (0x7 << 0) /* Bits 2-0: FR, frame rate */ 253 + #define PIXPAPER_PLL_FR_12_5HZ (0x0 << 0) /* 000: 12.5 Hz */ 254 + #define PIXPAPER_PLL_FR_25HZ (0x1 << 0) /* 001: 25 Hz */ 255 + #define PIXPAPER_PLL_FR_50HZ (0x2 << 0) /* 010: 50 Hz (default) */ 256 + #define PIXPAPER_PLL_FR_65HZ (0x3 << 0) /* 011: 65 Hz */ 257 + #define PIXPAPER_PLL_FR_75HZ (0x4 << 0) /* 100: 75 Hz */ 258 + #define PIXPAPER_PLL_FR_85HZ (0x5 << 0) /* 101: 85 Hz */ 259 + #define PIXPAPER_PLL_FR_100HZ (0x6 << 0) /* 110: 100 Hz */ 260 + #define PIXPAPER_PLL_FR_120HZ (0x7 << 0) /* 111: 120 Hz */ 261 + #define PIXPAPER_PLL_DFR \ 262 + (1 << 3) /* Bit 3: Dynamic frame rate, 0=disabled (default), 1=enabled */ 263 + #define PIXPAPER_PLL_CONFIG \ 264 + (PIXPAPER_PLL_FR_50HZ) /* 0x02: 50 Hz, dynamic frame rate disabled */ 265 + 266 + /* R41H TSE - Temperature Sensor Calibration Register */ 267 + /* First Parameter */ 268 + #define PIXPAPER_TSE_TO_MASK \ 269 + (0xF << 0) /* Bits 3-0: TO[3:0], temperature offset */ 270 + #define PIXPAPER_TSE_TO_POS_0C (0x0 << 0) /* 0000: +0°C (default) */ 271 + #define PIXPAPER_TSE_TO_POS_0_5C (0x1 << 0) /* 0001: +0.5°C */ 272 + #define PIXPAPER_TSE_TO_POS_1C (0x2 << 0) /* 0010: +1°C */ 273 + #define PIXPAPER_TSE_TO_POS_1_5C (0x3 << 0) /* 0011: +1.5°C */ 274 + #define PIXPAPER_TSE_TO_POS_2C (0x4 << 0) /* 0100: +2°C */ 275 + #define PIXPAPER_TSE_TO_POS_2_5C (0x5 << 0) /* 0101: +2.5°C */ 276 + #define PIXPAPER_TSE_TO_POS_3C (0x6 << 0) /* 0110: +3°C */ 277 + #define PIXPAPER_TSE_TO_POS_3_5C (0x7 << 0) /* 0111: +3.5°C */ 278 + #define PIXPAPER_TSE_TO_NEG_4C (0x8 << 0) /* 1000: -4°C */ 279 + #define PIXPAPER_TSE_TO_NEG_3_5C (0x9 << 0) /* 1001: -3.5°C */ 280 + #define PIXPAPER_TSE_TO_NEG_3C (0xA << 0) /* 1010: -3°C */ 281 + #define PIXPAPER_TSE_TO_NEG_2_5C (0xB << 0) /* 1011: -2.5°C */ 282 + #define PIXPAPER_TSE_TO_NEG_2C (0xC << 0) /* 1100: -2°C */ 283 + #define PIXPAPER_TSE_TO_NEG_1_5C (0xD << 0) /* 1101: -1.5°C */ 284 + #define PIXPAPER_TSE_TO_NEG_1C (0xE << 0) /* 1110: -1°C */ 285 + #define PIXPAPER_TSE_TO_NEG_0_5C (0xF << 0) /* 1111: -0.5°C */ 286 + #define PIXPAPER_TSE_TO_FINE_MASK \ 287 + (0x3 << 4) /* Bits 5-4: TO[5:4], fine adjustment for positive offsets */ 288 + #define PIXPAPER_TSE_TO_FINE_0C (0x0 << 4) /* 00: +0.0°C (default) */ 289 + #define PIXPAPER_TSE_TO_FINE_0_25C (0x1 << 4) /* 01: +0.25°C */ 290 + #define PIXPAPER_TSE_ENABLE \ 291 + (0 << 7) /* Bit 7: TSE, 0=internal sensor enabled (default), 1=disabled (external) */ 292 + #define PIXPAPER_TSE_DISABLE \ 293 + (1 << 7) /* Bit 7: TSE, 1=internal sensor disabled, use external */ 294 + #define PIXPAPER_TSE_CONFIG \ 295 + (PIXPAPER_TSE_TO_POS_0C | PIXPAPER_TSE_TO_FINE_0C | \ 296 + PIXPAPER_TSE_ENABLE) /* 0x00: Internal sensor enabled, +0°C offset */ 297 + 298 + /* R4DH */ 299 + #define PIXPAPER_UNKNOWN_4D_CONFIG \ 300 + 0x78 /* This value is essential for initialization, derived from userspace examples. */ 301 + 302 + /* R50H CDI - VCOM and DATA Interval Setting Register */ 303 + /* First Parameter */ 304 + #define PIXPAPER_CDI_INTERVAL_MASK \ 305 + (0xF << 0) /* Bits 3-0: CDI[3:0], VCOM and data interval (hsync) */ 306 + #define PIXPAPER_CDI_17_HSYNC (0x0 << 0) /* 0000: 17 hsync */ 307 + #define PIXPAPER_CDI_16_HSYNC (0x1 << 0) /* 0001: 16 hsync */ 308 + #define PIXPAPER_CDI_15_HSYNC (0x2 << 0) /* 0010: 15 hsync */ 309 + #define PIXPAPER_CDI_14_HSYNC (0x3 << 0) /* 0011: 14 hsync */ 310 + #define PIXPAPER_CDI_13_HSYNC (0x4 << 0) /* 0100: 13 hsync */ 311 + #define PIXPAPER_CDI_12_HSYNC (0x5 << 0) /* 0101: 12 hsync */ 312 + #define PIXPAPER_CDI_11_HSYNC (0x6 << 0) /* 0110: 11 hsync */ 313 + #define PIXPAPER_CDI_10_HSYNC (0x7 << 0) /* 0111: 10 hsync (default) */ 314 + #define PIXPAPER_CDI_9_HSYNC (0x8 << 0) /* 1000: 9 hsync */ 315 + #define PIXPAPER_CDI_8_HSYNC (0x9 << 0) /* 1001: 8 hsync */ 316 + #define PIXPAPER_CDI_7_HSYNC (0xA << 0) /* 1010: 7 hsync */ 317 + #define PIXPAPER_CDI_6_HSYNC (0xB << 0) /* 1011: 6 hsync */ 318 + #define PIXPAPER_CDI_5_HSYNC (0xC << 0) /* 1100: 5 hsync */ 319 + #define PIXPAPER_CDI_4_HSYNC (0xD << 0) /* 1101: 4 hsync */ 320 + #define PIXPAPER_CDI_3_HSYNC (0xE << 0) /* 1110: 3 hsync */ 321 + #define PIXPAPER_CDI_2_HSYNC (0xF << 0) /* 1111: 2 hsync */ 322 + #define PIXPAPER_CDI_DDX \ 323 + (1 << 4) /* Bit 4: DDX, 0=grayscale mapping 0, 1=grayscale mapping 1 (default) */ 324 + #define PIXPAPER_CDI_VBD_MASK \ 325 + (0x7 << 5) /* Bits 7-5: VBD[2:0], border data selection */ 326 + #define PIXPAPER_CDI_VBD_FLOAT (0x0 << 5) /* 000: Floating (DDX=0 or 1) */ 327 + #define PIXPAPER_CDI_VBD_GRAY3_DDX0 \ 328 + (0x1 << 5) /* 001: Gray3 (border_buf=011) when DDX=0 */ 329 + #define PIXPAPER_CDI_VBD_GRAY2_DDX0 \ 330 + (0x2 << 5) /* 010: Gray2 (border_buf=010) when DDX=0 */ 331 + #define PIXPAPER_CDI_VBD_GRAY1_DDX0 \ 332 + (0x3 << 5) /* 011: Gray1 (border_buf=001) when DDX=0 */ 333 + #define PIXPAPER_CDI_VBD_GRAY0_DDX0 \ 334 + (0x4 << 5) /* 100: Gray0 (border_buf=000) when DDX=0 */ 335 + #define PIXPAPER_CDI_VBD_GRAY0_DDX1 \ 336 + (0x0 << 5) /* 000: Gray0 (border_buf=000) when DDX=1 */ 337 + #define PIXPAPER_CDI_VBD_GRAY1_DDX1 \ 338 + (0x1 << 5) /* 001: Gray1 (border_buf=001) when DDX=1 */ 339 + #define PIXPAPER_CDI_VBD_GRAY2_DDX1 \ 340 + (0x2 << 5) /* 010: Gray2 (border_buf=010) when DDX=1 */ 341 + #define PIXPAPER_CDI_VBD_GRAY3_DDX1 \ 342 + (0x3 << 5) /* 011: Gray3 (border_buf=011) when DDX=1 */ 343 + #define PIXPAPER_CDI_VBD_FLOAT_DDX1 (0x4 << 5) /* 100: Floating when DDX=1 */ 344 + #define PIXPAPER_CDI_CONFIG \ 345 + (PIXPAPER_CDI_10_HSYNC | PIXPAPER_CDI_DDX | \ 346 + PIXPAPER_CDI_VBD_GRAY1_DDX1) /* 0x37: 10 hsync, DDX=1, border Gray1 */ 347 + 348 + /* R60H */ 349 + #define PIXPAPER_UNKNOWN_60_CONFIG1 \ 350 + 0x02 /* This value is essential for initialization, derived from userspace examples. */ 351 + #define PIXPAPER_UNKNOWN_60_CONFIG2 \ 352 + 0x02 /* This value is essential for initialization, derived from userspace examples. */ 353 + 354 + /* R61H TRES - Resolution Setting Register */ 355 + #define PIXPAPER_TRES_HRES_H \ 356 + ((PIXPAPER_PANEL_BUFFER_WIDTH >> 8) & \ 357 + 0xFF) /* HRES[9:8]: High byte of horizontal resolution (128) */ 358 + #define PIXPAPER_TRES_HRES_L \ 359 + (PIXPAPER_PANEL_BUFFER_WIDTH & \ 360 + 0xFF) /* HRES[7:0]: Low byte of horizontal resolution (128 = 0x80) */ 361 + #define PIXPAPER_TRES_VRES_H \ 362 + ((PIXPAPER_HEIGHT >> 8) & \ 363 + 0xFF) /* VRES[9:8]: High byte of vertical resolution (250) */ 364 + #define PIXPAPER_TRES_VRES_L \ 365 + (PIXPAPER_HEIGHT & \ 366 + 0xFF) /* VRES[7:0]: Low byte of vertical resolution (250 = 0xFA) */ 367 + 368 + /* R65H GSST - Gate/Source Start Setting Register */ 369 + #define PIXPAPER_GSST_S_START 0x00 /* S_Start[7:0]: First source line (S0) */ 370 + #define PIXPAPER_GSST_RESERVED 0x00 /* Reserved byte */ 371 + #define PIXPAPER_GSST_G_START_H \ 372 + 0x00 /* G_Start[8]: High bit of first gate line (G0) */ 373 + #define PIXPAPER_GSST_G_START_L \ 374 + 0x00 /* G_Start[7:0]: Low byte of first gate line (G0) */ 375 + 376 + /* RB4H */ 377 + #define PIXPAPER_UNKNOWN_B4_CONFIG \ 378 + 0xD0 /* This value is essential for initialization, derived from userspace examples. */ 379 + 380 + /* RB5H */ 381 + #define PIXPAPER_UNKNOWN_B5_CONFIG \ 382 + 0x03 /* This value is essential for initialization, derived from userspace examples. */ 383 + 384 + /* RE0H */ 385 + #define PIXPAPER_UNKNOWN_E0_CONFIG \ 386 + 0x00 /* This value is essential for initialization, derived from userspace examples. */ 387 + 388 + /* RE3H PWS - Power Saving Register */ 389 + /* First Parameter */ 390 + #define PIXPAPER_PWS_VCOM_W_MASK \ 391 + (0xF \ 392 + << 4) /* Bits 7-4: VCOM_W[3:0], VCOM power-saving width (line periods) */ 393 + #define PIXPAPER_PWS_VCOM_W_0 (0x0 << 4) /* 0000: 0 line periods */ 394 + #define PIXPAPER_PWS_VCOM_W_1 (0x1 << 4) /* 0001: 1 line period */ 395 + #define PIXPAPER_PWS_VCOM_W_2 (0x2 << 4) /* 0010: 2 line periods */ 396 + #define PIXPAPER_PWS_VCOM_W_3 (0x3 << 4) /* 0011: 3 line periods */ 397 + #define PIXPAPER_PWS_VCOM_W_4 (0x4 << 4) /* 0100: 4 line periods */ 398 + #define PIXPAPER_PWS_VCOM_W_5 (0x5 << 4) /* 0101: 5 line periods */ 399 + #define PIXPAPER_PWS_VCOM_W_6 (0x6 << 4) /* 0110: 6 line periods */ 400 + #define PIXPAPER_PWS_VCOM_W_7 (0x7 << 4) /* 0111: 7 line periods */ 401 + #define PIXPAPER_PWS_VCOM_W_8 (0x8 << 4) /* 1000: 8 line periods */ 402 + #define PIXPAPER_PWS_VCOM_W_9 (0x9 << 4) /* 1001: 9 line periods */ 403 + #define PIXPAPER_PWS_VCOM_W_10 (0xA << 4) /* 1010: 10 line periods */ 404 + #define PIXPAPER_PWS_VCOM_W_11 (0xB << 4) /* 1011: 11 line periods */ 405 + #define PIXPAPER_PWS_VCOM_W_12 (0xC << 4) /* 1100: 12 line periods */ 406 + #define PIXPAPER_PWS_VCOM_W_13 (0xD << 4) /* 1101: 13 line periods */ 407 + #define PIXPAPER_PWS_VCOM_W_14 (0xE << 4) /* 1110: 14 line periods */ 408 + #define PIXPAPER_PWS_VCOM_W_15 (0xF << 4) /* 1111: 15 line periods */ 409 + #define PIXPAPER_PWS_SD_W_MASK \ 410 + (0xF << 0) /* Bits 3-0: SD_W[3:0], source power-saving width (660 ns units) */ 411 + #define PIXPAPER_PWS_SD_W_0 (0x0 << 0) /* 0000: 0 ns */ 412 + #define PIXPAPER_PWS_SD_W_1 (0x1 << 0) /* 0001: 660 ns */ 413 + #define PIXPAPER_PWS_SD_W_2 (0x2 << 0) /* 0010: 1320 ns */ 414 + #define PIXPAPER_PWS_SD_W_3 (0x3 << 0) /* 0011: 1980 ns */ 415 + #define PIXPAPER_PWS_SD_W_4 (0x4 << 0) /* 0100: 2640 ns */ 416 + #define PIXPAPER_PWS_SD_W_5 (0x5 << 0) /* 0101: 3300 ns */ 417 + #define PIXPAPER_PWS_SD_W_6 (0x6 << 0) /* 0110: 3960 ns */ 418 + #define PIXPAPER_PWS_SD_W_7 (0x7 << 0) /* 0111: 4620 ns */ 419 + #define PIXPAPER_PWS_SD_W_8 (0x8 << 0) /* 1000: 5280 ns */ 420 + #define PIXPAPER_PWS_SD_W_9 (0x9 << 0) /* 1001: 5940 ns */ 421 + #define PIXPAPER_PWS_SD_W_10 (0xA << 0) /* 1010: 6600 ns */ 422 + #define PIXPAPER_PWS_SD_W_11 (0xB << 0) /* 1011: 7260 ns */ 423 + #define PIXPAPER_PWS_SD_W_12 (0xC << 0) /* 1100: 7920 ns */ 424 + #define PIXPAPER_PWS_SD_W_13 (0xD << 0) /* 1101: 8580 ns */ 425 + #define PIXPAPER_PWS_SD_W_14 (0xE << 0) /* 1110: 9240 ns */ 426 + #define PIXPAPER_PWS_SD_W_15 (0xF << 0) /* 1111: 9900 ns */ 427 + #define PIXPAPER_PWS_CONFIG \ 428 + (PIXPAPER_PWS_VCOM_W_2 | \ 429 + PIXPAPER_PWS_SD_W_2) /* 0x22: VCOM 2 line periods (160 µs), source 1320 ns */ 430 + 431 + /* RE7H */ 432 + #define PIXPAPER_UNKNOWN_E7_CONFIG \ 433 + 0x1C /* This value is essential for initialization, derived from userspace examples. */ 434 + 435 + /* RE9H */ 436 + #define PIXPAPER_UNKNOWN_E9_CONFIG \ 437 + 0x01 /* This value is essential for initialization, derived from userspace examples. */ 438 + 439 + MODULE_IMPORT_NS("DMA_BUF"); 440 + 441 + /* 442 + * The panel has a visible resolution of 122x250. 443 + * However, the controller requires the horizontal resolution to be aligned to 128 pixels. 444 + * No porch or sync timing values are provided in the datasheet, so we define minimal 445 + * placeholder values to satisfy the DRM framework. 446 + */ 447 + 448 + /* Panel visible resolution */ 449 + #define PIXPAPER_WIDTH 122 450 + #define PIXPAPER_HEIGHT 250 451 + 452 + /* Controller requires 128 horizontal pixels total (for memory alignment) */ 453 + #define PIXPAPER_HTOTAL 128 454 + #define PIXPAPER_HFP 2 455 + #define PIXPAPER_HSYNC 2 456 + #define PIXPAPER_HBP (PIXPAPER_HTOTAL - PIXPAPER_WIDTH - PIXPAPER_HFP - PIXPAPER_HSYNC) 457 + 458 + /* 459 + * According to the datasheet, the total vertical blanking must be 55 lines, 460 + * regardless of how the vertical back porch is set. 461 + * Here we allocate VFP=2, VSYNC=2, and VBP=51 to sum up to 55 lines. 462 + * Total vertical lines = 250 (visible) + 55 (blanking) = 305. 463 + */ 464 + #define PIXPAPER_VTOTAL (250 + 55) 465 + #define PIXPAPER_VFP 2 466 + #define PIXPAPER_VSYNC 2 467 + #define PIXPAPER_VBP (55 - PIXPAPER_VFP - PIXPAPER_VSYNC) 468 + 469 + /* 470 + * Pixel clock calculation: 471 + * pixel_clock = htotal * vtotal * refresh_rate 472 + * = 128 * 305 * 50 473 + * = 1,952,000 Hz = 1952 kHz 474 + */ 475 + #define PIXPAPER_PIXEL_CLOCK 1952 476 + 477 + #define PIXPAPER_WIDTH_MM 24 /* approximate from 23.7046mm */ 478 + #define PIXPAPER_HEIGHT_MM 49 /* approximate from 48.55mm */ 479 + 480 + #define PIXPAPER_SPI_BITS_PER_WORD 8 481 + #define PIXPAPER_SPI_SPEED_DEFAULT 1000000 482 + 483 + #define PIXPAPER_PANEL_BUFFER_WIDTH 128 484 + #define PIXPAPER_PANEL_BUFFER_TWO_BYTES_PER_ROW (PIXPAPER_PANEL_BUFFER_WIDTH / 4) 485 + 486 + #define PIXPAPER_COLOR_THRESHOLD_LOW_CHANNEL 60 487 + #define PIXPAPER_COLOR_THRESHOLD_HIGH_CHANNEL 200 488 + #define PIXPAPER_COLOR_THRESHOLD_YELLOW_MIN_GREEN 180 489 + 490 + struct pixpaper_error_ctx { 491 + int errno_code; 492 + }; 493 + 494 + struct pixpaper_panel { 495 + struct drm_device drm; 496 + struct drm_plane plane; 497 + struct drm_crtc crtc; 498 + struct drm_encoder encoder; 499 + struct drm_connector connector; 500 + 501 + struct spi_device *spi; 502 + struct gpio_desc *reset; 503 + struct gpio_desc *busy; 504 + struct gpio_desc *dc; 505 + }; 506 + 507 + static inline struct pixpaper_panel *to_pixpaper_panel(struct drm_device *drm) 508 + { 509 + return container_of(drm, struct pixpaper_panel, drm); 510 + } 511 + 512 + static void pixpaper_wait_for_panel(struct pixpaper_panel *panel) 513 + { 514 + unsigned int timeout_ms = 10000; 515 + unsigned long timeout_jiffies = jiffies + msecs_to_jiffies(timeout_ms); 516 + 517 + usleep_range(1000, 1500); 518 + while (gpiod_get_value_cansleep(panel->busy) != 1) { 519 + if (time_after(jiffies, timeout_jiffies)) { 520 + drm_warn(&panel->drm, "Busy wait timed out\n"); 521 + return; 522 + } 523 + usleep_range(100, 200); 524 + } 525 + } 526 + 527 + static void pixpaper_spi_sync(struct spi_device *spi, struct spi_message *msg, 528 + struct pixpaper_error_ctx *err) 529 + { 530 + if (err->errno_code) 531 + return; 532 + 533 + int ret = spi_sync(spi, msg); 534 + 535 + if (ret < 0) 536 + err->errno_code = ret; 537 + } 538 + 539 + static void pixpaper_send_cmd(struct pixpaper_panel *panel, u8 cmd, 540 + struct pixpaper_error_ctx *err) 541 + { 542 + if (err->errno_code) 543 + return; 544 + 545 + struct spi_transfer xfer = { 546 + .tx_buf = &cmd, 547 + .len = 1, 548 + }; 549 + struct spi_message msg; 550 + 551 + spi_message_init(&msg); 552 + spi_message_add_tail(&xfer, &msg); 553 + 554 + gpiod_set_value_cansleep(panel->dc, 0); 555 + usleep_range(1, 5); 556 + pixpaper_spi_sync(panel->spi, &msg, err); 557 + } 558 + 559 + static void pixpaper_send_data(struct pixpaper_panel *panel, u8 data, 560 + struct pixpaper_error_ctx *err) 561 + { 562 + if (err->errno_code) 563 + return; 564 + 565 + struct spi_transfer xfer = { 566 + .tx_buf = &data, 567 + .len = 1, 568 + }; 569 + struct spi_message msg; 570 + 571 + spi_message_init(&msg); 572 + spi_message_add_tail(&xfer, &msg); 573 + 574 + gpiod_set_value_cansleep(panel->dc, 1); 575 + usleep_range(1, 5); 576 + pixpaper_spi_sync(panel->spi, &msg, err); 577 + } 578 + 579 + static int pixpaper_panel_hw_init(struct pixpaper_panel *panel) 580 + { 581 + struct pixpaper_error_ctx err = { .errno_code = 0 }; 582 + 583 + gpiod_set_value_cansleep(panel->reset, 0); 584 + msleep(50); 585 + gpiod_set_value_cansleep(panel->reset, 1); 586 + msleep(50); 587 + 588 + pixpaper_wait_for_panel(panel); 589 + 590 + pixpaper_send_cmd(panel, PIXPAPER_CMD_UNKNOWN_4D, &err); 591 + pixpaper_send_data(panel, PIXPAPER_UNKNOWN_4D_CONFIG, &err); 592 + if (err.errno_code) 593 + goto init_fail; 594 + pixpaper_wait_for_panel(panel); 595 + 596 + pixpaper_send_cmd(panel, PIXPAPER_CMD_PANEL_SETTING, &err); 597 + pixpaper_send_data(panel, PIXPAPER_PSR_CONFIG, &err); 598 + pixpaper_send_data(panel, PIXPAPER_PSR_CONFIG2, &err); 599 + if (err.errno_code) 600 + goto init_fail; 601 + pixpaper_wait_for_panel(panel); 602 + 603 + pixpaper_send_cmd(panel, PIXPAPER_CMD_POWER_SETTING, &err); 604 + pixpaper_send_data(panel, PIXPAPER_PWR_CONFIG1, &err); 605 + pixpaper_send_data(panel, PIXPAPER_PWR_CONFIG2, &err); 606 + pixpaper_send_data(panel, PIXPAPER_PWR_VSP_8_2V, &err); 607 + pixpaper_send_data(panel, PIXPAPER_PWR_VSPL_15V, &err); 608 + pixpaper_send_data(panel, PIXPAPER_PWR_VSN_4V, &err); 609 + pixpaper_send_data(panel, PIXPAPER_PWR_VSP_8_2V, &err); 610 + if (err.errno_code) 611 + goto init_fail; 612 + pixpaper_wait_for_panel(panel); 613 + 614 + pixpaper_send_cmd(panel, PIXPAPER_CMD_POWER_OFF_SEQUENCE, &err); 615 + pixpaper_send_data(panel, PIXPAPER_PFS_CONFIG1, &err); 616 + pixpaper_send_data(panel, PIXPAPER_PFS_CONFIG2, &err); 617 + pixpaper_send_data(panel, PIXPAPER_PFS_CONFIG3, &err); 618 + if (err.errno_code) 619 + goto init_fail; 620 + pixpaper_wait_for_panel(panel); 621 + 622 + pixpaper_send_cmd(panel, PIXPAPER_CMD_BOOSTER_SOFT_START, &err); 623 + pixpaper_send_data(panel, PIXPAPER_BTST_CONFIG1, &err); 624 + pixpaper_send_data(panel, PIXPAPER_BTST_CONFIG2, &err); 625 + pixpaper_send_data(panel, PIXPAPER_BTST_CONFIG3, &err); 626 + pixpaper_send_data(panel, PIXPAPER_BTST_CONFIG4, &err); 627 + pixpaper_send_data(panel, PIXPAPER_BTST_CONFIG5, &err); 628 + pixpaper_send_data(panel, PIXPAPER_BTST_CONFIG6, &err); 629 + pixpaper_send_data(panel, PIXPAPER_BTST_CONFIG7, &err); 630 + if (err.errno_code) 631 + goto init_fail; 632 + pixpaper_wait_for_panel(panel); 633 + 634 + pixpaper_send_cmd(panel, PIXPAPER_CMD_PLL_CONTROL, &err); 635 + pixpaper_send_data(panel, PIXPAPER_PLL_CONFIG, &err); 636 + if (err.errno_code) 637 + goto init_fail; 638 + pixpaper_wait_for_panel(panel); 639 + 640 + pixpaper_send_cmd(panel, PIXPAPER_CMD_TEMP_SENSOR_CALIB, &err); 641 + pixpaper_send_data(panel, PIXPAPER_TSE_CONFIG, &err); 642 + if (err.errno_code) 643 + goto init_fail; 644 + pixpaper_wait_for_panel(panel); 645 + 646 + pixpaper_send_cmd(panel, PIXPAPER_CMD_VCOM_INTERVAL, &err); 647 + pixpaper_send_data(panel, PIXPAPER_CDI_CONFIG, &err); 648 + if (err.errno_code) 649 + goto init_fail; 650 + pixpaper_wait_for_panel(panel); 651 + 652 + pixpaper_send_cmd(panel, PIXPAPER_CMD_UNKNOWN_60, &err); 653 + pixpaper_send_data(panel, PIXPAPER_UNKNOWN_60_CONFIG1, &err); 654 + pixpaper_send_data(panel, PIXPAPER_UNKNOWN_60_CONFIG2, &err); 655 + if (err.errno_code) 656 + goto init_fail; 657 + pixpaper_wait_for_panel(panel); 658 + 659 + pixpaper_send_cmd(panel, PIXPAPER_CMD_RESOLUTION_SETTING, &err); 660 + pixpaper_send_data(panel, PIXPAPER_TRES_HRES_H, &err); 661 + pixpaper_send_data(panel, PIXPAPER_TRES_HRES_L, &err); 662 + pixpaper_send_data(panel, PIXPAPER_TRES_VRES_H, &err); 663 + pixpaper_send_data(panel, PIXPAPER_TRES_VRES_L, &err); 664 + if (err.errno_code) 665 + goto init_fail; 666 + pixpaper_wait_for_panel(panel); 667 + 668 + pixpaper_send_cmd(panel, PIXPAPER_CMD_GATE_SOURCE_START, &err); 669 + pixpaper_send_data(panel, PIXPAPER_GSST_S_START, &err); 670 + pixpaper_send_data(panel, PIXPAPER_GSST_RESERVED, &err); 671 + pixpaper_send_data(panel, PIXPAPER_GSST_G_START_H, &err); 672 + pixpaper_send_data(panel, PIXPAPER_GSST_G_START_L, &err); 673 + if (err.errno_code) 674 + goto init_fail; 675 + pixpaper_wait_for_panel(panel); 676 + 677 + pixpaper_send_cmd(panel, PIXPAPER_CMD_UNKNOWN_E7, &err); 678 + pixpaper_send_data(panel, PIXPAPER_UNKNOWN_E7_CONFIG, &err); 679 + if (err.errno_code) 680 + goto init_fail; 681 + pixpaper_wait_for_panel(panel); 682 + 683 + pixpaper_send_cmd(panel, PIXPAPER_CMD_POWER_SAVING, &err); 684 + pixpaper_send_data(panel, PIXPAPER_PWS_CONFIG, &err); 685 + if (err.errno_code) 686 + goto init_fail; 687 + pixpaper_wait_for_panel(panel); 688 + 689 + pixpaper_send_cmd(panel, PIXPAPER_CMD_UNKNOWN_E0, &err); 690 + pixpaper_send_data(panel, PIXPAPER_UNKNOWN_E0_CONFIG, &err); 691 + if (err.errno_code) 692 + goto init_fail; 693 + pixpaper_wait_for_panel(panel); 694 + 695 + pixpaper_send_cmd(panel, PIXPAPER_CMD_UNKNOWN_B4, &err); 696 + pixpaper_send_data(panel, PIXPAPER_UNKNOWN_B4_CONFIG, &err); 697 + if (err.errno_code) 698 + goto init_fail; 699 + pixpaper_wait_for_panel(panel); 700 + 701 + pixpaper_send_cmd(panel, PIXPAPER_CMD_UNKNOWN_B5, &err); 702 + pixpaper_send_data(panel, PIXPAPER_UNKNOWN_B5_CONFIG, &err); 703 + if (err.errno_code) 704 + goto init_fail; 705 + pixpaper_wait_for_panel(panel); 706 + 707 + pixpaper_send_cmd(panel, PIXPAPER_CMD_UNKNOWN_E9, &err); 708 + pixpaper_send_data(panel, PIXPAPER_UNKNOWN_E9_CONFIG, &err); 709 + if (err.errno_code) 710 + goto init_fail; 711 + pixpaper_wait_for_panel(panel); 712 + 713 + return 0; 714 + 715 + init_fail: 716 + drm_err(&panel->drm, "Hardware initialization failed (err=%d)\n", 717 + err.errno_code); 718 + return err.errno_code; 719 + } 720 + 721 + /* 722 + * Convert framebuffer pixels to 2-bit e-paper format: 723 + * 00 - White 724 + * 01 - Black 725 + * 10 - Yellow 726 + * 11 - Red 727 + */ 728 + static u8 pack_pixels_to_byte(__le32 *src_pixels, int i, int j, 729 + struct drm_framebuffer *fb) 730 + { 731 + u8 packed_byte = 0; 732 + int k; 733 + 734 + for (k = 0; k < 4; k++) { 735 + int current_pixel_x = j * 4 + k; 736 + u8 two_bit_val; 737 + 738 + if (current_pixel_x < PIXPAPER_WIDTH) { 739 + u32 pixel_offset = 740 + (i * (fb->pitches[0] / 4)) + current_pixel_x; 741 + u32 pixel = le32_to_cpu(src_pixels[pixel_offset]); 742 + u32 r = (pixel >> 16) & 0xFF; 743 + u32 g = (pixel >> 8) & 0xFF; 744 + u32 b = pixel & 0xFF; 745 + 746 + if (r < PIXPAPER_COLOR_THRESHOLD_LOW_CHANNEL && 747 + g < PIXPAPER_COLOR_THRESHOLD_LOW_CHANNEL && 748 + b < PIXPAPER_COLOR_THRESHOLD_LOW_CHANNEL) { 749 + two_bit_val = 0b00; 750 + } else if (r > PIXPAPER_COLOR_THRESHOLD_HIGH_CHANNEL && 751 + g > PIXPAPER_COLOR_THRESHOLD_HIGH_CHANNEL && 752 + b > PIXPAPER_COLOR_THRESHOLD_HIGH_CHANNEL) { 753 + two_bit_val = 0b01; 754 + } else if (r > PIXPAPER_COLOR_THRESHOLD_HIGH_CHANNEL && 755 + g < PIXPAPER_COLOR_THRESHOLD_LOW_CHANNEL && 756 + b < PIXPAPER_COLOR_THRESHOLD_LOW_CHANNEL) { 757 + two_bit_val = 0b11; 758 + } else if (r > PIXPAPER_COLOR_THRESHOLD_HIGH_CHANNEL && 759 + g > PIXPAPER_COLOR_THRESHOLD_YELLOW_MIN_GREEN && 760 + b < PIXPAPER_COLOR_THRESHOLD_LOW_CHANNEL) { 761 + two_bit_val = 0b10; 762 + } else { 763 + two_bit_val = 0b01; 764 + } 765 + } else { 766 + two_bit_val = 0b01; 767 + } 768 + 769 + packed_byte |= two_bit_val << ((3 - k) * 2); 770 + } 771 + 772 + return packed_byte; 773 + } 774 + 775 + static int pixpaper_plane_helper_atomic_check(struct drm_plane *plane, 776 + struct drm_atomic_state *state) 777 + { 778 + struct drm_plane_state *new_plane_state = 779 + drm_atomic_get_new_plane_state(state, plane); 780 + struct drm_crtc *new_crtc = new_plane_state->crtc; 781 + struct drm_crtc_state *new_crtc_state = NULL; 782 + int ret; 783 + 784 + if (new_crtc) 785 + new_crtc_state = drm_atomic_get_new_crtc_state(state, new_crtc); 786 + 787 + ret = drm_atomic_helper_check_plane_state(new_plane_state, 788 + new_crtc_state, DRM_PLANE_NO_SCALING, 789 + DRM_PLANE_NO_SCALING, false, false); 790 + if (ret) 791 + return ret; 792 + else if (!new_plane_state->visible) 793 + return 0; 794 + 795 + return 0; 796 + } 797 + 798 + static int pixpaper_crtc_helper_atomic_check(struct drm_crtc *crtc, 799 + struct drm_atomic_state *state) 800 + { 801 + struct drm_crtc_state *crtc_state = 802 + drm_atomic_get_new_crtc_state(state, crtc); 803 + 804 + if (!crtc_state->enable) 805 + return 0; 806 + 807 + return drm_atomic_helper_check_crtc_primary_plane(crtc_state); 808 + } 809 + 810 + static void pixpaper_crtc_atomic_enable(struct drm_crtc *crtc, 811 + struct drm_atomic_state *state) 812 + { 813 + struct pixpaper_panel *panel = to_pixpaper_panel(crtc->dev); 814 + struct drm_device *drm = &panel->drm; 815 + int idx; 816 + struct pixpaper_error_ctx err = { .errno_code = 0 }; 817 + 818 + if (!drm_dev_enter(drm, &idx)) 819 + return; 820 + 821 + pixpaper_send_cmd(panel, PIXPAPER_CMD_POWER_ON, &err); 822 + if (err.errno_code) { 823 + drm_err_once(drm, "Failed to send PON command: %d\n", err.errno_code); 824 + goto exit_drm_dev; 825 + } 826 + 827 + pixpaper_wait_for_panel(panel); 828 + 829 + drm_dbg(drm, "Panel enabled and powered on\n"); 830 + 831 + exit_drm_dev: 832 + drm_dev_exit(idx); 833 + } 834 + 835 + static void pixpaper_crtc_atomic_disable(struct drm_crtc *crtc, 836 + struct drm_atomic_state *state) 837 + { 838 + struct pixpaper_panel *panel = to_pixpaper_panel(crtc->dev); 839 + struct drm_device *drm = &panel->drm; 840 + struct pixpaper_error_ctx err = { .errno_code = 0 }; 841 + int idx; 842 + 843 + if (!drm_dev_enter(drm, &idx)) 844 + return; 845 + 846 + pixpaper_send_cmd(panel, PIXPAPER_CMD_POWER_OFF, &err); 847 + if (err.errno_code) { 848 + drm_err_once(drm, "Failed to send POF command: %d\n", err.errno_code); 849 + goto exit_drm_dev; 850 + } 851 + pixpaper_wait_for_panel(panel); 852 + 853 + drm_dbg(drm, "Panel disabled\n"); 854 + 855 + exit_drm_dev: 856 + drm_dev_exit(idx); 857 + } 858 + 859 + static void pixpaper_plane_atomic_update(struct drm_plane *plane, 860 + struct drm_atomic_state *state) 861 + { 862 + struct drm_plane_state *plane_state = 863 + drm_atomic_get_new_plane_state(state, plane); 864 + struct drm_shadow_plane_state *shadow_plane_state = 865 + to_drm_shadow_plane_state(plane_state); 866 + struct drm_crtc *crtc = plane_state->crtc; 867 + struct pixpaper_panel *panel = to_pixpaper_panel(crtc->dev); 868 + 869 + struct drm_device *drm = &panel->drm; 870 + struct drm_framebuffer *fb = plane_state->fb; 871 + struct iosys_map map = shadow_plane_state->data[0]; 872 + void *vaddr = map.vaddr; 873 + int i, j, idx; 874 + __le32 *src_pixels = NULL; 875 + struct pixpaper_error_ctx err = { .errno_code = 0 }; 876 + 877 + if (!drm_dev_enter(drm, &idx)) 878 + return; 879 + 880 + drm_dbg(drm, "Starting frame update (phys=%dx%d, buf_w=%d)\n", 881 + PIXPAPER_WIDTH, PIXPAPER_HEIGHT, PIXPAPER_PANEL_BUFFER_WIDTH); 882 + 883 + if (!fb || !plane_state->visible) { 884 + drm_err_once(drm, "No framebuffer or plane not visible, skipping update\n"); 885 + goto update_cleanup; 886 + } 887 + 888 + src_pixels = (__le32 *)vaddr; 889 + 890 + pixpaper_send_cmd(panel, PIXPAPER_CMD_DATA_START_TRANSMISSION, &err); 891 + if (err.errno_code) 892 + goto update_cleanup; 893 + 894 + pixpaper_wait_for_panel(panel); 895 + 896 + for (i = 0; i < PIXPAPER_HEIGHT; i++) { 897 + for (j = 0; j < PIXPAPER_PANEL_BUFFER_TWO_BYTES_PER_ROW; j++) { 898 + u8 packed_byte = 899 + pack_pixels_to_byte(src_pixels, i, j, fb); 900 + 901 + pixpaper_wait_for_panel(panel); 902 + pixpaper_send_data(panel, packed_byte, &err); 903 + } 904 + } 905 + pixpaper_wait_for_panel(panel); 906 + 907 + pixpaper_send_cmd(panel, PIXPAPER_CMD_POWER_ON, &err); 908 + if (err.errno_code) { 909 + drm_err_once(drm, "Failed to send PON command: %d\n", err.errno_code); 910 + goto update_cleanup; 911 + } 912 + pixpaper_wait_for_panel(panel); 913 + 914 + pixpaper_send_cmd(panel, PIXPAPER_CMD_DISPLAY_REFRESH, &err); 915 + pixpaper_send_data(panel, PIXPAPER_DRF_VCOM_AC, &err); 916 + if (err.errno_code) { 917 + drm_err_once(drm, "Failed sending data after DRF: %d\n", err.errno_code); 918 + goto update_cleanup; 919 + } 920 + pixpaper_wait_for_panel(panel); 921 + 922 + update_cleanup: 923 + if (err.errno_code && err.errno_code != -ETIMEDOUT) 924 + drm_err_once(drm, "Frame update function failed with error %d\n", err.errno_code); 925 + 926 + drm_dev_exit(idx); 927 + } 928 + 929 + static const struct drm_display_mode pixpaper_mode = { 930 + .clock = PIXPAPER_PIXEL_CLOCK, 931 + .hdisplay = PIXPAPER_WIDTH, 932 + .hsync_start = PIXPAPER_WIDTH + PIXPAPER_HFP, 933 + .hsync_end = PIXPAPER_WIDTH + PIXPAPER_HFP + PIXPAPER_HSYNC, 934 + .htotal = PIXPAPER_HTOTAL, 935 + .vdisplay = PIXPAPER_HEIGHT, 936 + .vsync_start = PIXPAPER_HEIGHT + PIXPAPER_VFP, 937 + .vsync_end = PIXPAPER_HEIGHT + PIXPAPER_VFP + PIXPAPER_VSYNC, 938 + .vtotal = PIXPAPER_VTOTAL, 939 + .width_mm = PIXPAPER_WIDTH_MM, 940 + .height_mm = PIXPAPER_HEIGHT_MM, 941 + .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, 942 + }; 943 + 944 + static int pixpaper_connector_get_modes(struct drm_connector *connector) 945 + { 946 + return drm_connector_helper_get_modes_fixed(connector, &pixpaper_mode); 947 + } 948 + 949 + static const struct drm_plane_funcs pixpaper_plane_funcs = { 950 + .update_plane = drm_atomic_helper_update_plane, 951 + .disable_plane = drm_atomic_helper_disable_plane, 952 + .destroy = drm_plane_cleanup, 953 + DRM_GEM_SHADOW_PLANE_FUNCS, 954 + }; 955 + 956 + static const struct drm_plane_helper_funcs pixpaper_plane_helper_funcs = { 957 + DRM_GEM_SHADOW_PLANE_HELPER_FUNCS, 958 + .atomic_check = pixpaper_plane_helper_atomic_check, 959 + .atomic_update = pixpaper_plane_atomic_update, 960 + }; 961 + 962 + static const struct drm_crtc_funcs pixpaper_crtc_funcs = { 963 + .set_config = drm_atomic_helper_set_config, 964 + .page_flip = drm_atomic_helper_page_flip, 965 + .reset = drm_atomic_helper_crtc_reset, 966 + .destroy = drm_crtc_cleanup, 967 + .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, 968 + .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, 969 + }; 970 + 971 + static int pixpaper_mode_valid(struct drm_crtc *crtc, 972 + const struct drm_display_mode *mode) 973 + { 974 + if (mode->hdisplay == PIXPAPER_WIDTH && 975 + mode->vdisplay == PIXPAPER_HEIGHT) { 976 + return MODE_OK; 977 + } 978 + return MODE_BAD; 979 + } 980 + 981 + static const struct drm_crtc_helper_funcs pixpaper_crtc_helper_funcs = { 982 + .mode_valid = pixpaper_mode_valid, 983 + .atomic_check = pixpaper_crtc_helper_atomic_check, 984 + .atomic_enable = pixpaper_crtc_atomic_enable, 985 + .atomic_disable = pixpaper_crtc_atomic_disable, 986 + }; 987 + 988 + static const struct drm_encoder_funcs pixpaper_encoder_funcs = { 989 + .destroy = drm_encoder_cleanup, 990 + }; 991 + 992 + static const struct drm_connector_funcs pixpaper_connector_funcs = { 993 + .reset = drm_atomic_helper_connector_reset, 994 + .fill_modes = drm_helper_probe_single_connector_modes, 995 + .destroy = drm_connector_cleanup, 996 + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 997 + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 998 + }; 999 + 1000 + static const struct drm_connector_helper_funcs pixpaper_connector_helper_funcs = { 1001 + .get_modes = pixpaper_connector_get_modes, 1002 + }; 1003 + 1004 + DEFINE_DRM_GEM_FOPS(pixpaper_fops); 1005 + 1006 + static struct drm_driver pixpaper_drm_driver = { 1007 + .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, 1008 + .fops = &pixpaper_fops, 1009 + .name = "pixpaper", 1010 + .desc = "DRM driver for PIXPAPER e-ink", 1011 + .major = 1, 1012 + .minor = 0, 1013 + DRM_GEM_SHMEM_DRIVER_OPS, 1014 + DRM_FBDEV_SHMEM_DRIVER_OPS, 1015 + }; 1016 + 1017 + static const struct drm_mode_config_funcs pixpaper_mode_config_funcs = { 1018 + .fb_create = drm_gem_fb_create_with_dirty, 1019 + .atomic_check = drm_atomic_helper_check, 1020 + .atomic_commit = drm_atomic_helper_commit, 1021 + }; 1022 + 1023 + static int pixpaper_probe(struct spi_device *spi) 1024 + { 1025 + struct device *dev = &spi->dev; 1026 + struct pixpaper_panel *panel; 1027 + struct drm_device *drm; 1028 + int ret; 1029 + 1030 + panel = devm_drm_dev_alloc(dev, &pixpaper_drm_driver, 1031 + struct pixpaper_panel, drm); 1032 + if (IS_ERR(panel)) 1033 + return PTR_ERR(panel); 1034 + 1035 + drm = &panel->drm; 1036 + panel->spi = spi; 1037 + spi_set_drvdata(spi, panel); 1038 + 1039 + spi->mode = SPI_MODE_0; 1040 + spi->bits_per_word = PIXPAPER_SPI_BITS_PER_WORD; 1041 + 1042 + if (!spi->max_speed_hz) { 1043 + drm_warn(drm, 1044 + "spi-max-frequency not specified in DT, using default %u Hz\n", 1045 + PIXPAPER_SPI_SPEED_DEFAULT); 1046 + spi->max_speed_hz = PIXPAPER_SPI_SPEED_DEFAULT; 1047 + } 1048 + 1049 + ret = spi_setup(spi); 1050 + if (ret < 0) { 1051 + drm_err(drm, "SPI setup failed: %d\n", ret); 1052 + return ret; 1053 + } 1054 + 1055 + if (!dev->dma_mask) 1056 + dev->dma_mask = &dev->coherent_dma_mask; 1057 + ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); 1058 + if (ret) { 1059 + drm_err(drm, "Failed to set DMA mask: %d\n", ret); 1060 + return ret; 1061 + } 1062 + 1063 + panel->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); 1064 + if (IS_ERR(panel->reset)) 1065 + return PTR_ERR(panel->reset); 1066 + 1067 + panel->busy = devm_gpiod_get(dev, "busy", GPIOD_IN); 1068 + if (IS_ERR(panel->busy)) 1069 + return PTR_ERR(panel->busy); 1070 + 1071 + panel->dc = devm_gpiod_get(dev, "dc", GPIOD_OUT_HIGH); 1072 + if (IS_ERR(panel->dc)) 1073 + return PTR_ERR(panel->dc); 1074 + 1075 + ret = pixpaper_panel_hw_init(panel); 1076 + if (ret) { 1077 + drm_err(drm, "Panel hardware initialization failed: %d\n", ret); 1078 + return ret; 1079 + } 1080 + 1081 + ret = drmm_mode_config_init(drm); 1082 + if (ret) 1083 + return ret; 1084 + drm->mode_config.funcs = &pixpaper_mode_config_funcs; 1085 + drm->mode_config.min_width = PIXPAPER_WIDTH; 1086 + drm->mode_config.max_width = PIXPAPER_WIDTH; 1087 + drm->mode_config.min_height = PIXPAPER_HEIGHT; 1088 + drm->mode_config.max_height = PIXPAPER_HEIGHT; 1089 + 1090 + ret = drm_universal_plane_init(drm, &panel->plane, 1, 1091 + &pixpaper_plane_funcs, 1092 + (const uint32_t[]){ DRM_FORMAT_XRGB8888 }, 1093 + 1, NULL, DRM_PLANE_TYPE_PRIMARY, NULL); 1094 + if (ret) 1095 + return ret; 1096 + drm_plane_helper_add(&panel->plane, &pixpaper_plane_helper_funcs); 1097 + 1098 + ret = drm_crtc_init_with_planes(drm, &panel->crtc, &panel->plane, NULL, 1099 + &pixpaper_crtc_funcs, NULL); 1100 + if (ret) 1101 + return ret; 1102 + drm_crtc_helper_add(&panel->crtc, &pixpaper_crtc_helper_funcs); 1103 + 1104 + ret = drm_encoder_init(drm, &panel->encoder, &pixpaper_encoder_funcs, 1105 + DRM_MODE_ENCODER_NONE, NULL); 1106 + if (ret) 1107 + return ret; 1108 + panel->encoder.possible_crtcs = drm_crtc_mask(&panel->crtc); 1109 + 1110 + ret = drm_connector_init(drm, &panel->connector, 1111 + &pixpaper_connector_funcs, 1112 + DRM_MODE_CONNECTOR_SPI); 1113 + if (ret) 1114 + return ret; 1115 + 1116 + drm_connector_helper_add(&panel->connector, 1117 + &pixpaper_connector_helper_funcs); 1118 + drm_connector_attach_encoder(&panel->connector, &panel->encoder); 1119 + 1120 + drm_mode_config_reset(drm); 1121 + 1122 + ret = drm_dev_register(drm, 0); 1123 + if (ret) 1124 + return ret; 1125 + 1126 + drm_client_setup(drm, NULL); 1127 + 1128 + return 0; 1129 + } 1130 + 1131 + static void pixpaper_remove(struct spi_device *spi) 1132 + { 1133 + struct pixpaper_panel *panel = spi_get_drvdata(spi); 1134 + 1135 + if (!panel) 1136 + return; 1137 + 1138 + drm_dev_unplug(&panel->drm); 1139 + drm_atomic_helper_shutdown(&panel->drm); 1140 + } 1141 + 1142 + static const struct spi_device_id pixpaper_ids[] = { { "pixpaper", 0 }, {} }; 1143 + MODULE_DEVICE_TABLE(spi, pixpaper_ids); 1144 + 1145 + static const struct of_device_id pixpaper_dt_ids[] = { 1146 + { .compatible = "mayqueen,pixpaper" }, 1147 + {} 1148 + }; 1149 + MODULE_DEVICE_TABLE(of, pixpaper_dt_ids); 1150 + 1151 + static struct spi_driver pixpaper_spi_driver = { 1152 + .driver = { 1153 + .name = "pixpaper", 1154 + .of_match_table = pixpaper_dt_ids, 1155 + }, 1156 + .id_table = pixpaper_ids, 1157 + .probe = pixpaper_probe, 1158 + .remove = pixpaper_remove, 1159 + }; 1160 + 1161 + module_spi_driver(pixpaper_spi_driver); 1162 + 1163 + MODULE_AUTHOR("LiangCheng Wang"); 1164 + MODULE_DESCRIPTION("DRM SPI driver for PIXPAPER e-ink panel"); 1165 + MODULE_LICENSE("GPL");
+15
drivers/gpu/drm/ttm/ttm_bo.c
··· 1283 1283 return 0; 1284 1284 } 1285 1285 EXPORT_SYMBOL(ttm_bo_populate); 1286 + 1287 + int ttm_bo_setup_export(struct ttm_buffer_object *bo, 1288 + struct ttm_operation_ctx *ctx) 1289 + { 1290 + int ret; 1291 + 1292 + ret = ttm_bo_reserve(bo, false, false, NULL); 1293 + if (ret != 0) 1294 + return ret; 1295 + 1296 + ret = ttm_bo_populate(bo, ctx); 1297 + ttm_bo_unreserve(bo); 1298 + return ret; 1299 + } 1300 + EXPORT_SYMBOL(ttm_bo_setup_export);
+46 -5
drivers/gpu/drm/vkms/tests/vkms_config_test.c
··· 200 200 KUNIT_ASSERT_EQ(test, n_planes, 0); 201 201 202 202 plane_cfg1 = vkms_config_create_plane(config); 203 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane_cfg1); 203 204 vkms_config_for_each_plane(config, plane_cfg) { 204 205 n_planes++; 205 206 if (plane_cfg != plane_cfg1) ··· 210 209 n_planes = 0; 211 210 212 211 plane_cfg2 = vkms_config_create_plane(config); 212 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane_cfg2); 213 213 vkms_config_for_each_plane(config, plane_cfg) { 214 214 n_planes++; 215 215 if (plane_cfg != plane_cfg1 && plane_cfg != plane_cfg2) ··· 244 242 KUNIT_FAIL(test, "Unexpected CRTC"); 245 243 246 244 crtc_cfg1 = vkms_config_create_crtc(config); 245 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_cfg1); 247 246 KUNIT_ASSERT_EQ(test, vkms_config_get_num_crtcs(config), 1); 248 247 vkms_config_for_each_crtc(config, crtc_cfg) { 249 248 if (crtc_cfg != crtc_cfg1) ··· 252 249 } 253 250 254 251 crtc_cfg2 = vkms_config_create_crtc(config); 252 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_cfg2); 255 253 KUNIT_ASSERT_EQ(test, vkms_config_get_num_crtcs(config), 2); 256 254 vkms_config_for_each_crtc(config, crtc_cfg) { 257 255 if (crtc_cfg != crtc_cfg1 && crtc_cfg != crtc_cfg2) ··· 284 280 KUNIT_ASSERT_EQ(test, n_encoders, 0); 285 281 286 282 encoder_cfg1 = vkms_config_create_encoder(config); 283 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, encoder_cfg1); 287 284 vkms_config_for_each_encoder(config, encoder_cfg) { 288 285 n_encoders++; 289 286 if (encoder_cfg != encoder_cfg1) ··· 294 289 n_encoders = 0; 295 290 296 291 encoder_cfg2 = vkms_config_create_encoder(config); 292 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, encoder_cfg2); 297 293 vkms_config_for_each_encoder(config, encoder_cfg) { 298 294 n_encoders++; 299 295 if (encoder_cfg != encoder_cfg1 && encoder_cfg != encoder_cfg2) ··· 330 324 KUNIT_ASSERT_EQ(test, n_connectors, 0); 331 325 332 326 connector_cfg1 = vkms_config_create_connector(config); 327 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, connector_cfg1); 333 328 vkms_config_for_each_connector(config, connector_cfg) { 334 329 n_connectors++; 335 330 if (connector_cfg != connector_cfg1) ··· 340 333 n_connectors = 0; 341 334 342 335 connector_cfg2 = vkms_config_create_connector(config); 336 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, connector_cfg2); 343 337 vkms_config_for_each_connector(config, connector_cfg) { 344 338 n_connectors++; 345 339 if (connector_cfg != connector_cfg1 && ··· 378 370 379 371 /* Invalid: Too many planes */ 380 372 for (n = 0; n <= 32; n++) 381 - vkms_config_create_plane(config); 373 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, vkms_config_create_plane(config)); 382 374 383 375 KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); 384 376 ··· 403 395 404 396 /* Invalid: No primary plane */ 405 397 plane_cfg = vkms_config_create_plane(config); 398 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane_cfg); 406 399 vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_OVERLAY); 407 400 err = vkms_config_plane_attach_crtc(plane_cfg, crtc_cfg); 408 401 KUNIT_EXPECT_EQ(test, err, 0); ··· 411 402 412 403 /* Invalid: Multiple primary planes */ 413 404 plane_cfg = vkms_config_create_plane(config); 405 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane_cfg); 414 406 vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_PRIMARY); 415 407 err = vkms_config_plane_attach_crtc(plane_cfg, crtc_cfg); 416 408 KUNIT_EXPECT_EQ(test, err, 0); 417 409 418 410 plane_cfg = vkms_config_create_plane(config); 411 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane_cfg); 419 412 vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_PRIMARY); 420 413 err = vkms_config_plane_attach_crtc(plane_cfg, crtc_cfg); 421 414 KUNIT_EXPECT_EQ(test, err, 0); ··· 430 419 431 420 /* Invalid: Multiple cursor planes */ 432 421 plane_cfg = vkms_config_create_plane(config); 422 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane_cfg); 433 423 vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_CURSOR); 434 424 err = vkms_config_plane_attach_crtc(plane_cfg, crtc_cfg); 435 425 KUNIT_EXPECT_EQ(test, err, 0); 436 426 437 427 plane_cfg = vkms_config_create_plane(config); 428 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane_cfg); 438 429 vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_CURSOR); 439 430 err = vkms_config_plane_attach_crtc(plane_cfg, crtc_cfg); 440 431 KUNIT_EXPECT_EQ(test, err, 0); ··· 450 437 /* Invalid: Second CRTC without primary plane */ 451 438 crtc_cfg = vkms_config_create_crtc(config); 452 439 encoder_cfg = vkms_config_create_encoder(config); 440 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_cfg); 441 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, encoder_cfg); 442 + 453 443 err = vkms_config_encoder_attach_crtc(encoder_cfg, crtc_cfg); 454 444 KUNIT_EXPECT_EQ(test, err, 0); 455 445 KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); 456 446 457 447 /* Valid: Second CRTC with a primary plane */ 458 448 plane_cfg = vkms_config_create_plane(config); 449 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane_cfg); 459 450 vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_PRIMARY); 460 451 err = vkms_config_plane_attach_crtc(plane_cfg, crtc_cfg); 461 452 KUNIT_EXPECT_EQ(test, err, 0); ··· 503 486 504 487 /* Invalid: Too many CRTCs */ 505 488 for (n = 0; n <= 32; n++) 506 - vkms_config_create_crtc(config); 489 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, vkms_config_create_crtc(config)); 507 490 508 491 KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); 509 492 ··· 526 509 527 510 /* Invalid: Too many encoders */ 528 511 for (n = 0; n <= 32; n++) 529 - vkms_config_create_encoder(config); 512 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, vkms_config_create_encoder(config)); 530 513 531 514 KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); 532 515 ··· 548 531 549 532 /* Invalid: Encoder without a possible CRTC */ 550 533 encoder_cfg = vkms_config_create_encoder(config); 534 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, encoder_cfg); 551 535 KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); 552 536 553 537 /* Valid: Second CRTC with shared encoder */ 554 538 crtc_cfg2 = vkms_config_create_crtc(config); 555 - 556 539 plane_cfg = vkms_config_create_plane(config); 540 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_cfg2); 541 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane_cfg); 542 + 557 543 vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_PRIMARY); 558 544 err = vkms_config_plane_attach_crtc(plane_cfg, crtc_cfg2); 559 545 KUNIT_EXPECT_EQ(test, err, 0); ··· 597 577 598 578 /* Invalid: Too many connectors */ 599 579 for (n = 0; n <= 32; n++) 600 - connector_cfg = vkms_config_create_connector(config); 580 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, vkms_config_create_connector(config)); 601 581 602 582 KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); 603 583 ··· 689 669 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); 690 670 691 671 overlay_cfg = vkms_config_create_plane(config); 672 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, overlay_cfg); 692 673 vkms_config_plane_set_type(overlay_cfg, DRM_PLANE_TYPE_OVERLAY); 674 + 693 675 primary_cfg = vkms_config_create_plane(config); 676 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, primary_cfg); 694 677 vkms_config_plane_set_type(primary_cfg, DRM_PLANE_TYPE_PRIMARY); 678 + 695 679 cursor_cfg = vkms_config_create_plane(config); 680 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, cursor_cfg); 696 681 vkms_config_plane_set_type(cursor_cfg, DRM_PLANE_TYPE_CURSOR); 697 682 698 683 crtc_cfg = vkms_config_create_crtc(config); 684 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_cfg); 699 685 700 686 /* No primary or cursor planes */ 701 687 KUNIT_EXPECT_NULL(test, vkms_config_crtc_primary_plane(config, crtc_cfg)); ··· 760 734 plane_cfg2 = vkms_config_create_plane(config); 761 735 crtc_cfg1 = vkms_config_create_crtc(config); 762 736 crtc_cfg2 = vkms_config_create_crtc(config); 737 + 738 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane_cfg1); 739 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane_cfg2); 740 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_cfg1); 741 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_cfg2); 763 742 764 743 /* No possible CRTCs */ 765 744 vkms_config_plane_for_each_possible_crtc(plane_cfg1, idx, possible_crtc) ··· 830 799 crtc_cfg1 = vkms_config_create_crtc(config); 831 800 crtc_cfg2 = vkms_config_create_crtc(config); 832 801 802 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, encoder_cfg1); 803 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, encoder_cfg2); 804 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_cfg1); 805 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_cfg2); 806 + 833 807 /* No possible CRTCs */ 834 808 vkms_config_encoder_for_each_possible_crtc(encoder_cfg1, idx, possible_crtc) 835 809 KUNIT_FAIL(test, "Unexpected possible CRTC"); ··· 898 862 connector_cfg2 = vkms_config_create_connector(config); 899 863 encoder_cfg1 = vkms_config_create_encoder(config); 900 864 encoder_cfg2 = vkms_config_create_encoder(config); 865 + 866 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, connector_cfg1); 867 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, connector_cfg2); 868 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, encoder_cfg1); 869 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, encoder_cfg2); 901 870 902 871 /* No possible encoders */ 903 872 vkms_config_connector_for_each_possible_encoder(connector_cfg1, idx,
+71 -72
drivers/gpu/drm/vkms/tests/vkms_format_test.c
··· 14 14 MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING"); 15 15 16 16 /** 17 - * struct pixel_yuv_u8 - Internal representation of a pixel color. 18 - * @y: Luma value, stored in 8 bits, without padding, using 17 + * struct pixel_yuv_u16 - Internal representation of a pixel color. 18 + * @y: Luma value, stored in 16 bits, without padding, using 19 19 * machine endianness 20 - * @u: Blue difference chroma value, stored in 8 bits, without padding, using 20 + * @u: Blue difference chroma value, stored in 16 bits, without padding, using 21 21 * machine endianness 22 - * @v: Red difference chroma value, stored in 8 bits, without padding, using 22 + * @v: Red difference chroma value, stored in 16 bits, without padding, using 23 23 * machine endianness 24 24 */ 25 - struct pixel_yuv_u8 { 26 - u8 y, u, v; 25 + struct pixel_yuv_u16 { 26 + u16 y, u, v; 27 27 }; 28 28 29 29 /* 30 - * struct yuv_u8_to_argb_u16_case - Reference values to test the color 30 + * struct yuv_u16_to_argb_u16_case - Reference values to test the color 31 31 * conversions in VKMS between YUV to ARGB 32 32 * 33 33 * @encoding: Encoding used to convert RGB to YUV ··· 39 39 * @format_pair.yuv: Same color as @format_pair.rgb, but converted to 40 40 * YUV using @encoding and @range. 41 41 */ 42 - struct yuv_u8_to_argb_u16_case { 42 + struct yuv_u16_to_argb_u16_case { 43 43 enum drm_color_encoding encoding; 44 44 enum drm_color_range range; 45 45 size_t n_colors; 46 46 struct format_pair { 47 47 char *name; 48 - struct pixel_yuv_u8 yuv; 48 + struct pixel_yuv_u16 yuv; 49 49 struct pixel_argb_u16 argb; 50 50 } colors[TEST_BUFF_SIZE]; 51 51 }; ··· 57 57 * For more information got to the docs: 58 58 * https://colour.readthedocs.io/en/master/generated/colour.RGB_to_YCbCr.html 59 59 */ 60 - static struct yuv_u8_to_argb_u16_case yuv_u8_to_argb_u16_cases[] = { 60 + static struct yuv_u16_to_argb_u16_case yuv_u16_to_argb_u16_cases[] = { 61 61 /* 62 62 * colour.RGB_to_YCbCr(<rgb color in 16 bit form>, 63 63 * K=colour.WEIGHTS_YCBCR["ITU-R BT.601"], 64 64 * in_bits = 16, 65 65 * in_legal = False, 66 66 * in_int = True, 67 - * out_bits = 8, 67 + * out_bits = 16, 68 68 * out_legal = False, 69 69 * out_int = True) 70 70 * ··· 76 76 .range = DRM_COLOR_YCBCR_FULL_RANGE, 77 77 .n_colors = 6, 78 78 .colors = { 79 - { "white", { 0xff, 0x80, 0x80 }, { 0xffff, 0xffff, 0xffff, 0xffff }}, 80 - { "gray", { 0x80, 0x80, 0x80 }, { 0xffff, 0x8080, 0x8080, 0x8080 }}, 81 - { "black", { 0x00, 0x80, 0x80 }, { 0xffff, 0x0000, 0x0000, 0x0000 }}, 82 - { "red", { 0x4c, 0x55, 0xff }, { 0xffff, 0xffff, 0x0000, 0x0000 }}, 83 - { "green", { 0x96, 0x2c, 0x15 }, { 0xffff, 0x0000, 0xffff, 0x0000 }}, 84 - { "blue", { 0x1d, 0xff, 0x6b }, { 0xffff, 0x0000, 0x0000, 0xffff }}, 85 - }, 79 + { "white", { 0xffff, 0x8000, 0x8000 }, { 0xffff, 0xffff, 0xffff, 0xffff }}, 80 + { "gray", { 0x8080, 0x8000, 0x8000 }, { 0xffff, 0x8080, 0x8080, 0x8080 }}, 81 + { "black", { 0x0000, 0x8000, 0x8000 }, { 0xffff, 0x0000, 0x0000, 0x0000 }}, 82 + { "red", { 0x4c8b, 0x54ce, 0xffff }, { 0xffff, 0xffff, 0x0000, 0x0000 }}, 83 + { "green", { 0x9645, 0x2b33, 0x14d1 }, { 0xffff, 0x0000, 0xffff, 0x0000 }}, 84 + { "blue", { 0x1d2f, 0xffff, 0x6b2f }, { 0xffff, 0x0000, 0x0000, 0xffff }}, 85 + } 86 86 }, 87 87 /* 88 88 * colour.RGB_to_YCbCr(<rgb color in 16 bit form>, ··· 90 90 * in_bits = 16, 91 91 * in_legal = False, 92 92 * in_int = True, 93 - * out_bits = 8, 93 + * out_bits = 16, 94 94 * out_legal = True, 95 95 * out_int = True) 96 96 * Tests cases for color conversion generated by converting RGB ··· 101 101 .range = DRM_COLOR_YCBCR_LIMITED_RANGE, 102 102 .n_colors = 6, 103 103 .colors = { 104 - { "white", { 0xeb, 0x80, 0x80 }, { 0xffff, 0xffff, 0xffff, 0xffff }}, 105 - { "gray", { 0x7e, 0x80, 0x80 }, { 0xffff, 0x8080, 0x8080, 0x8080 }}, 106 - { "black", { 0x10, 0x80, 0x80 }, { 0xffff, 0x0000, 0x0000, 0x0000 }}, 107 - { "red", { 0x51, 0x5a, 0xf0 }, { 0xffff, 0xffff, 0x0000, 0x0000 }}, 108 - { "green", { 0x91, 0x36, 0x22 }, { 0xffff, 0x0000, 0xffff, 0x0000 }}, 109 - { "blue", { 0x29, 0xf0, 0x6e }, { 0xffff, 0x0000, 0x0000, 0xffff }}, 110 - }, 104 + { "white", { 0xeb00, 0x8000, 0x8000 }, { 0xffff, 0xffff, 0xffff, 0xffff }}, 105 + { "gray", { 0x7dee, 0x8000, 0x8000 }, { 0xffff, 0x8080, 0x8080, 0x8080 }}, 106 + { "black", { 0x1000, 0x8000, 0x8000 }, { 0xffff, 0x0000, 0x0000, 0x0000 }}, 107 + { "red", { 0x517b, 0x5a34, 0xf000 }, { 0xffff, 0xffff, 0x0000, 0x0000 }}, 108 + { "green", { 0x908e, 0x35cc, 0x2237 }, { 0xffff, 0x0000, 0xffff, 0x0000 }}, 109 + { "blue", { 0x28f7, 0xf000, 0x6dc9 }, { 0xffff, 0x0000, 0x0000, 0xffff }}, 110 + } 111 111 }, 112 112 /* 113 113 * colour.RGB_to_YCbCr(<rgb color in 16 bit form>, ··· 115 115 * in_bits = 16, 116 116 * in_legal = False, 117 117 * in_int = True, 118 - * out_bits = 8, 118 + * out_bits = 16, 119 119 * out_legal = False, 120 120 * out_int = True) 121 121 * Tests cases for color conversion generated by converting RGB ··· 126 126 .range = DRM_COLOR_YCBCR_FULL_RANGE, 127 127 .n_colors = 6, 128 128 .colors = { 129 - { "white", { 0xff, 0x80, 0x80 }, { 0xffff, 0xffff, 0xffff, 0xffff }}, 130 - { "gray", { 0x80, 0x80, 0x80 }, { 0xffff, 0x8080, 0x8080, 0x8080 }}, 131 - { "black", { 0x00, 0x80, 0x80 }, { 0xffff, 0x0000, 0x0000, 0x0000 }}, 132 - { "red", { 0x36, 0x63, 0xff }, { 0xffff, 0xffff, 0x0000, 0x0000 }}, 133 - { "green", { 0xb6, 0x1e, 0x0c }, { 0xffff, 0x0000, 0xffff, 0x0000 }}, 134 - { "blue", { 0x12, 0xff, 0x74 }, { 0xffff, 0x0000, 0x0000, 0xffff }}, 135 - }, 129 + { "white", { 0xffff, 0x8000, 0x8000 }, { 0xffff, 0xffff, 0xffff, 0xffff }}, 130 + { "gray", { 0x8080, 0x8000, 0x8000 }, { 0xffff, 0x8080, 0x8080, 0x8080 }}, 131 + { "black", { 0x0000, 0x8000, 0x8000 }, { 0xffff, 0x0000, 0x0000, 0x0000 }}, 132 + { "red", { 0x366d, 0x62ac, 0xffff }, { 0xffff, 0xffff, 0x0000, 0x0000 }}, 133 + { "green", { 0xb717, 0x1d55, 0x0bbd }, { 0xffff, 0x0000, 0xffff, 0x0000 }}, 134 + { "blue", { 0x127c, 0xffff, 0x7443 }, { 0xffff, 0x0000, 0x0000, 0xffff }}, 135 + } 136 136 }, 137 137 /* 138 138 * colour.RGB_to_YCbCr(<rgb color in 16 bit form>, 139 139 * K=colour.WEIGHTS_YCBCR["ITU-R BT.709"], 140 140 * in_bits = 16, 141 - * int_legal = False, 141 + * in_legal = False, 142 142 * in_int = True, 143 - * out_bits = 8, 143 + * out_bits = 16, 144 144 * out_legal = True, 145 145 * out_int = True) 146 146 * Tests cases for color conversion generated by converting RGB ··· 151 151 .range = DRM_COLOR_YCBCR_LIMITED_RANGE, 152 152 .n_colors = 6, 153 153 .colors = { 154 - { "white", { 0xeb, 0x80, 0x80 }, { 0xffff, 0xffff, 0xffff, 0xffff }}, 155 - { "gray", { 0x7e, 0x80, 0x80 }, { 0xffff, 0x8080, 0x8080, 0x8080 }}, 156 - { "black", { 0x10, 0x80, 0x80 }, { 0xffff, 0x0000, 0x0000, 0x0000 }}, 157 - { "red", { 0x3f, 0x66, 0xf0 }, { 0xffff, 0xffff, 0x0000, 0x0000 }}, 158 - { "green", { 0xad, 0x2a, 0x1a }, { 0xffff, 0x0000, 0xffff, 0x0000 }}, 159 - { "blue", { 0x20, 0xf0, 0x76 }, { 0xffff, 0x0000, 0x0000, 0xffff }}, 160 - }, 154 + { "white", { 0xeb00, 0x8000, 0x8000 }, { 0xffff, 0xffff, 0xffff, 0xffff }}, 155 + { "gray", { 0x7dee, 0x8000, 0x8000 }, { 0xffff, 0x8080, 0x8080, 0x8080 }}, 156 + { "black", { 0x1000, 0x8000, 0x8000 }, { 0xffff, 0x0000, 0x0000, 0x0000 }}, 157 + { "red", { 0x3e8f, 0x6656, 0xf000 }, { 0xffff, 0xffff, 0x0000, 0x0000 }}, 158 + { "green", { 0xaca1, 0x29aa, 0x1a45 }, { 0xffff, 0x0000, 0xffff, 0x0000 }}, 159 + { "blue", { 0x1fd0, 0xf000, 0x75bb }, { 0xffff, 0x0000, 0x0000, 0xffff }}, 160 + } 161 161 }, 162 162 /* 163 163 * colour.RGB_to_YCbCr(<rgb color in 16 bit form>, ··· 165 165 * in_bits = 16, 166 166 * in_legal = False, 167 167 * in_int = True, 168 - * out_bits = 8, 168 + * out_bits = 16, 169 169 * out_legal = False, 170 170 * out_int = True) 171 171 * Tests cases for color conversion generated by converting RGB ··· 176 176 .range = DRM_COLOR_YCBCR_FULL_RANGE, 177 177 .n_colors = 6, 178 178 .colors = { 179 - { "white", { 0xff, 0x80, 0x80 }, { 0xffff, 0xffff, 0xffff, 0xffff }}, 180 - { "gray", { 0x80, 0x80, 0x80 }, { 0xffff, 0x8080, 0x8080, 0x8080 }}, 181 - { "black", { 0x00, 0x80, 0x80 }, { 0xffff, 0x0000, 0x0000, 0x0000 }}, 182 - { "red", { 0x43, 0x5c, 0xff }, { 0xffff, 0xffff, 0x0000, 0x0000 }}, 183 - { "green", { 0xad, 0x24, 0x0b }, { 0xffff, 0x0000, 0xffff, 0x0000 }}, 184 - { "blue", { 0x0f, 0xff, 0x76 }, { 0xffff, 0x0000, 0x0000, 0xffff }}, 185 - }, 179 + { "white", { 0xffff, 0x8000, 0x8000 }, { 0xffff, 0xffff, 0xffff, 0xffff }}, 180 + { "gray", { 0x8080, 0x8000, 0x8000 }, { 0xffff, 0x8080, 0x8080, 0x8080 }}, 181 + { "black", { 0x0000, 0x8000, 0x8000 }, { 0xffff, 0x0000, 0x0000, 0x0000 }}, 182 + { "red", { 0x4340, 0x5c41, 0xffff }, { 0xffff, 0xffff, 0x0000, 0x0000 }}, 183 + { "green", { 0xad91, 0x23bf, 0x0a4c }, { 0xffff, 0x0000, 0xffff, 0x0000 }}, 184 + { "blue", { 0x0f2e, 0xffff, 0x75b5 }, { 0xffff, 0x0000, 0x0000, 0xffff }}, 185 + } 186 186 }, 187 187 /* 188 188 * colour.RGB_to_YCbCr(<rgb color in 16 bit form>, ··· 190 190 * in_bits = 16, 191 191 * in_legal = False, 192 192 * in_int = True, 193 - * out_bits = 8, 193 + * out_bits = 16, 194 194 * out_legal = True, 195 195 * out_int = True) 196 196 * Tests cases for color conversion generated by converting RGB ··· 201 201 .range = DRM_COLOR_YCBCR_LIMITED_RANGE, 202 202 .n_colors = 6, 203 203 .colors = { 204 - { "white", { 0xeb, 0x80, 0x80 }, { 0xffff, 0xffff, 0xffff, 0xffff }}, 205 - { "gray", { 0x7e, 0x80, 0x80 }, { 0xffff, 0x8080, 0x8080, 0x8080 }}, 206 - { "black", { 0x10, 0x80, 0x80 }, { 0xffff, 0x0000, 0x0000, 0x0000 }}, 207 - { "red", { 0x4a, 0x61, 0xf0 }, { 0xffff, 0xffff, 0x0000, 0x0000 }}, 208 - { "green", { 0xa4, 0x2f, 0x19 }, { 0xffff, 0x0000, 0xffff, 0x0000 }}, 209 - { "blue", { 0x1d, 0xf0, 0x77 }, { 0xffff, 0x0000, 0x0000, 0xffff }}, 210 - }, 204 + { "white", { 0xeb00, 0x8000, 0x8000 }, { 0xffff, 0xffff, 0xffff, 0xffff }}, 205 + { "gray", { 0x7dee, 0x8000, 0x8000 }, { 0xffff, 0x8080, 0x8080, 0x8080 }}, 206 + { "black", { 0x1000, 0x8000, 0x8000 }, { 0xffff, 0x0000, 0x0000, 0x0000 }}, 207 + { "red", { 0x4988, 0x60b9, 0xf000 }, { 0xffff, 0xffff, 0x0000, 0x0000 }}, 208 + { "green", { 0xa47b, 0x2f47, 0x1902 }, { 0xffff, 0x0000, 0xffff, 0x0000 }}, 209 + { "blue", { 0x1cfd, 0xf000, 0x76fe }, { 0xffff, 0x0000, 0x0000, 0xffff }}, 210 + } 211 211 }, 212 212 }; 213 213 214 214 /* 215 - * vkms_format_test_yuv_u8_to_argb_u16 - Testing the conversion between YUV 215 + * vkms_format_test_yuv_u16_to_argb_u16 - Testing the conversion between YUV 216 216 * colors to ARGB colors in VKMS 217 217 * 218 218 * This test will use the functions get_conversion_matrix_to_argb_u16 and 219 - * argb_u16_from_yuv888 to convert YUV colors (stored in 220 - * yuv_u8_to_argb_u16_cases) into ARGB colors. 219 + * argb_u16_from_yuv161616 to convert YUV colors (stored in 220 + * yuv_u16_to_argb_u16_cases) into ARGB colors. 221 221 * 222 222 * The conversion between YUV and RGB is not totally reversible, so there may be 223 223 * some difference between the expected value and the result. 224 - * In addition, there may be some rounding error as the input color is 8 bits 225 - * and output color is 16 bits. 226 224 */ 227 - static void vkms_format_test_yuv_u8_to_argb_u16(struct kunit *test) 225 + static void vkms_format_test_yuv_u16_to_argb_u16(struct kunit *test) 228 226 { 229 - const struct yuv_u8_to_argb_u16_case *param = test->param_value; 227 + const struct yuv_u16_to_argb_u16_case *param = test->param_value; 230 228 struct pixel_argb_u16 argb; 231 229 232 230 for (size_t i = 0; i < param->n_colors; i++) { ··· 234 236 get_conversion_matrix_to_argb_u16 235 237 (DRM_FORMAT_NV12, param->encoding, param->range, &matrix); 236 238 237 - argb = argb_u16_from_yuv888(color->yuv.y, color->yuv.u, color->yuv.v, &matrix); 239 + argb = argb_u16_from_yuv161616(&matrix, color->yuv.y, color->yuv.u, 240 + color->yuv.v); 238 241 239 242 KUNIT_EXPECT_LE_MSG(test, abs_diff(argb.a, color->argb.a), 0x1ff, 240 243 "On the A channel of the color %s expected 0x%04x, got 0x%04x", ··· 252 253 } 253 254 } 254 255 255 - static void vkms_format_test_yuv_u8_to_argb_u16_case_desc(struct yuv_u8_to_argb_u16_case *t, 256 - char *desc) 256 + static void vkms_format_test_yuv_u16_to_argb_u16_case_desc(struct yuv_u16_to_argb_u16_case *t, 257 + char *desc) 257 258 { 258 259 snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%s - %s", 259 260 drm_get_color_encoding_name(t->encoding), drm_get_color_range_name(t->range)); 260 261 } 261 262 262 - KUNIT_ARRAY_PARAM(yuv_u8_to_argb_u16, yuv_u8_to_argb_u16_cases, 263 - vkms_format_test_yuv_u8_to_argb_u16_case_desc 263 + KUNIT_ARRAY_PARAM(yuv_u16_to_argb_u16, yuv_u16_to_argb_u16_cases, 264 + vkms_format_test_yuv_u16_to_argb_u16_case_desc 264 265 ); 265 266 266 267 static struct kunit_case vkms_format_test_cases[] = { 267 - KUNIT_CASE_PARAM(vkms_format_test_yuv_u8_to_argb_u16, yuv_u8_to_argb_u16_gen_params), 268 + KUNIT_CASE_PARAM(vkms_format_test_yuv_u16_to_argb_u16, yuv_u16_to_argb_u16_gen_params), 268 269 {} 269 270 }; 270 271
+164 -163
drivers/gpu/drm/vkms/vkms_formats.c
··· 259 259 return argb_u16_from_u16161616(0xFFFF, gray, gray, gray); 260 260 } 261 261 262 - VISIBLE_IF_KUNIT struct pixel_argb_u16 argb_u16_from_yuv888(u8 y, u8 channel_1, u8 channel_2, 263 - const struct conversion_matrix *matrix) 262 + static struct pixel_argb_u16 argb_u16_from_BGR565(const __le16 *pixel) 263 + { 264 + struct pixel_argb_u16 out_pixel; 265 + 266 + out_pixel = argb_u16_from_RGB565(pixel); 267 + swap(out_pixel.r, out_pixel.b); 268 + 269 + return out_pixel; 270 + } 271 + 272 + VISIBLE_IF_KUNIT 273 + struct pixel_argb_u16 argb_u16_from_yuv161616(const struct conversion_matrix *matrix, 274 + u16 y, u16 channel_1, u16 channel_2) 264 275 { 265 276 u16 r, g, b; 266 277 s64 fp_y, fp_channel_1, fp_channel_2; 267 278 s64 fp_r, fp_g, fp_b; 268 279 269 - fp_y = drm_int2fixp(((int)y - matrix->y_offset) * 257); 270 - fp_channel_1 = drm_int2fixp(((int)channel_1 - 128) * 257); 271 - fp_channel_2 = drm_int2fixp(((int)channel_2 - 128) * 257); 280 + fp_y = drm_int2fixp((int)y - matrix->y_offset * 257); 281 + fp_channel_1 = drm_int2fixp((int)channel_1 - 128 * 257); 282 + fp_channel_2 = drm_int2fixp((int)channel_2 - 128 * 257); 272 283 273 284 fp_r = drm_fixp_mul(matrix->matrix[0][0], fp_y) + 274 285 drm_fixp_mul(matrix->matrix[0][1], fp_channel_1) + ··· 301 290 302 291 return argb_u16_from_u16161616(0xffff, r, g, b); 303 292 } 304 - EXPORT_SYMBOL_IF_KUNIT(argb_u16_from_yuv888); 293 + EXPORT_SYMBOL_IF_KUNIT(argb_u16_from_yuv161616); 294 + 295 + /** 296 + * READ_LINE() - Generic generator for a read_line function which can be used for format with one 297 + * plane and a block_h == block_w == 1. 298 + * 299 + * @function_name: Function name to generate 300 + * @pixel_name: Temporary pixel name used in the @__VA_ARGS__ parameters 301 + * @pixel_type: Used to specify the type you want to cast the pixel pointer 302 + * @callback: Callback to call for each pixels. This fonction should take @__VA_ARGS__ as parameter 303 + * and return a pixel_argb_u16 304 + * __VA_ARGS__: Argument to pass inside the callback. You can use @pixel_name to access current 305 + * pixel. 306 + */ 307 + #define READ_LINE(function_name, pixel_name, pixel_type, callback, ...) \ 308 + static void function_name(const struct vkms_plane_state *plane, int x_start, \ 309 + int y_start, enum pixel_read_direction direction, int count, \ 310 + struct pixel_argb_u16 out_pixel[]) \ 311 + { \ 312 + struct pixel_argb_u16 *end = out_pixel + count; \ 313 + int step = get_block_step_bytes(plane->frame_info->fb, direction, 0); \ 314 + u8 *src_pixels; \ 315 + \ 316 + packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, &src_pixels); \ 317 + \ 318 + while (out_pixel < end) { \ 319 + pixel_type *(pixel_name) = (pixel_type *)src_pixels; \ 320 + *out_pixel = (callback)(__VA_ARGS__); \ 321 + out_pixel += 1; \ 322 + src_pixels += step; \ 323 + } \ 324 + } 325 + 326 + /** 327 + * READ_LINE_ARGB8888() - Generic generator for ARGB8888 formats. 328 + * The pixel type used is u8, so pixel_name[0]..pixel_name[n] are the n components of the pixel. 329 + * 330 + * @function_name: Function name to generate 331 + * @pixel_name: temporary pixel to use in @a, @r, @g and @b parameters 332 + * @a: alpha value 333 + * @r: red value 334 + * @g: green value 335 + * @b: blue value 336 + */ 337 + #define READ_LINE_ARGB8888(function_name, pixel_name, a, r, g, b) \ 338 + READ_LINE(function_name, pixel_name, u8, argb_u16_from_u8888, a, r, g, b) 339 + /** 340 + * READ_LINE_le16161616() - Generic generator for ARGB16161616 formats. 341 + * The pixel type used is u16, so pixel_name[0]..pixel_name[n] are the n components of the pixel. 342 + * 343 + * @function_name: Function name to generate 344 + * @pixel_name: temporary pixel to use in @a, @r, @g and @b parameters 345 + * @a: alpha value 346 + * @r: red value 347 + * @g: green value 348 + * @b: blue value 349 + */ 350 + #define READ_LINE_le16161616(function_name, pixel_name, a, r, g, b) \ 351 + READ_LINE(function_name, pixel_name, __le16, argb_u16_from_le16161616, a, r, g, b) 305 352 306 353 /* 307 354 * The following functions are read_line function for each pixel format supported by VKMS. ··· 447 378 Rx_read_line(plane, x_start, y_start, direction, count, out_pixel); 448 379 } 449 380 450 - static void R8_read_line(const struct vkms_plane_state *plane, int x_start, 451 - int y_start, enum pixel_read_direction direction, int count, 452 - struct pixel_argb_u16 out_pixel[]) 453 - { 454 - struct pixel_argb_u16 *end = out_pixel + count; 455 - u8 *src_pixels; 456 - int step = get_block_step_bytes(plane->frame_info->fb, direction, 0); 457 381 458 - packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, &src_pixels); 382 + READ_LINE_ARGB8888(XRGB8888_read_line, px, 0xFF, px[2], px[1], px[0]) 383 + READ_LINE_ARGB8888(XBGR8888_read_line, px, 0xFF, px[0], px[1], px[2]) 459 384 460 - while (out_pixel < end) { 461 - *out_pixel = argb_u16_from_gray8(*src_pixels); 462 - src_pixels += step; 463 - out_pixel += 1; 464 - } 465 - } 385 + READ_LINE_ARGB8888(ARGB8888_read_line, px, px[3], px[2], px[1], px[0]) 386 + READ_LINE_ARGB8888(ABGR8888_read_line, px, px[3], px[0], px[1], px[2]) 387 + READ_LINE_ARGB8888(RGBA8888_read_line, px, px[0], px[3], px[2], px[1]) 388 + READ_LINE_ARGB8888(BGRA8888_read_line, px, px[0], px[1], px[2], px[3]) 466 389 467 - static void ARGB8888_read_line(const struct vkms_plane_state *plane, int x_start, int y_start, 468 - enum pixel_read_direction direction, int count, 469 - struct pixel_argb_u16 out_pixel[]) 470 - { 471 - struct pixel_argb_u16 *end = out_pixel + count; 472 - u8 *src_pixels; 390 + READ_LINE_ARGB8888(RGB888_read_line, px, 0xFF, px[2], px[1], px[0]) 391 + READ_LINE_ARGB8888(BGR888_read_line, px, 0xFF, px[0], px[1], px[2]) 473 392 474 - packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, &src_pixels); 393 + READ_LINE_le16161616(ARGB16161616_read_line, px, px[3], px[2], px[1], px[0]) 394 + READ_LINE_le16161616(ABGR16161616_read_line, px, px[3], px[0], px[1], px[2]) 395 + READ_LINE_le16161616(XRGB16161616_read_line, px, cpu_to_le16(0xFFFF), px[2], px[1], px[0]) 396 + READ_LINE_le16161616(XBGR16161616_read_line, px, cpu_to_le16(0xFFFF), px[0], px[1], px[2]) 475 397 476 - int step = get_block_step_bytes(plane->frame_info->fb, direction, 0); 398 + READ_LINE(RGB565_read_line, px, __le16, argb_u16_from_RGB565, px) 399 + READ_LINE(BGR565_read_line, px, __le16, argb_u16_from_BGR565, px) 477 400 478 - while (out_pixel < end) { 479 - u8 *px = (u8 *)src_pixels; 480 - *out_pixel = argb_u16_from_u8888(px[3], px[2], px[1], px[0]); 481 - out_pixel += 1; 482 - src_pixels += step; 483 - } 484 - } 485 - 486 - static void XRGB8888_read_line(const struct vkms_plane_state *plane, int x_start, int y_start, 487 - enum pixel_read_direction direction, int count, 488 - struct pixel_argb_u16 out_pixel[]) 489 - { 490 - struct pixel_argb_u16 *end = out_pixel + count; 491 - u8 *src_pixels; 492 - 493 - packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, &src_pixels); 494 - 495 - int step = get_block_step_bytes(plane->frame_info->fb, direction, 0); 496 - 497 - while (out_pixel < end) { 498 - u8 *px = (u8 *)src_pixels; 499 - *out_pixel = argb_u16_from_u8888(255, px[2], px[1], px[0]); 500 - out_pixel += 1; 501 - src_pixels += step; 502 - } 503 - } 504 - 505 - static void ABGR8888_read_line(const struct vkms_plane_state *plane, int x_start, int y_start, 506 - enum pixel_read_direction direction, int count, 507 - struct pixel_argb_u16 out_pixel[]) 508 - { 509 - struct pixel_argb_u16 *end = out_pixel + count; 510 - u8 *src_pixels; 511 - 512 - packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, &src_pixels); 513 - 514 - int step = get_block_step_bytes(plane->frame_info->fb, direction, 0); 515 - 516 - while (out_pixel < end) { 517 - u8 *px = (u8 *)src_pixels; 518 - /* Switch blue and red pixels. */ 519 - *out_pixel = argb_u16_from_u8888(px[3], px[0], px[1], px[2]); 520 - out_pixel += 1; 521 - src_pixels += step; 522 - } 523 - } 524 - 525 - static void ARGB16161616_read_line(const struct vkms_plane_state *plane, int x_start, 526 - int y_start, enum pixel_read_direction direction, int count, 527 - struct pixel_argb_u16 out_pixel[]) 528 - { 529 - struct pixel_argb_u16 *end = out_pixel + count; 530 - u8 *src_pixels; 531 - 532 - packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, &src_pixels); 533 - 534 - int step = get_block_step_bytes(plane->frame_info->fb, direction, 0); 535 - 536 - while (out_pixel < end) { 537 - u16 *px = (u16 *)src_pixels; 538 - *out_pixel = argb_u16_from_u16161616(px[3], px[2], px[1], px[0]); 539 - out_pixel += 1; 540 - src_pixels += step; 541 - } 542 - } 543 - 544 - static void XRGB16161616_read_line(const struct vkms_plane_state *plane, int x_start, 545 - int y_start, enum pixel_read_direction direction, int count, 546 - struct pixel_argb_u16 out_pixel[]) 547 - { 548 - struct pixel_argb_u16 *end = out_pixel + count; 549 - u8 *src_pixels; 550 - 551 - packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, &src_pixels); 552 - 553 - int step = get_block_step_bytes(plane->frame_info->fb, direction, 0); 554 - 555 - while (out_pixel < end) { 556 - __le16 *px = (__le16 *)src_pixels; 557 - *out_pixel = argb_u16_from_le16161616(cpu_to_le16(0xFFFF), px[2], px[1], px[0]); 558 - out_pixel += 1; 559 - src_pixels += step; 560 - } 561 - } 562 - 563 - static void RGB565_read_line(const struct vkms_plane_state *plane, int x_start, 564 - int y_start, enum pixel_read_direction direction, int count, 565 - struct pixel_argb_u16 out_pixel[]) 566 - { 567 - struct pixel_argb_u16 *end = out_pixel + count; 568 - u8 *src_pixels; 569 - 570 - packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, &src_pixels); 571 - 572 - int step = get_block_step_bytes(plane->frame_info->fb, direction, 0); 573 - 574 - while (out_pixel < end) { 575 - __le16 *px = (__le16 *)src_pixels; 576 - 577 - *out_pixel = argb_u16_from_RGB565(px); 578 - out_pixel += 1; 579 - src_pixels += step; 580 - } 581 - } 401 + READ_LINE(R8_read_line, px, u8, argb_u16_from_gray8, *px) 582 402 583 403 /* 584 404 * This callback can be used for YUV formats where U and V values are ··· 479 521 * - Convert YUV and YVU with the same function (a column swap is needed when setting up 480 522 * plane->conversion_matrix) 481 523 */ 482 - static void semi_planar_yuv_read_line(const struct vkms_plane_state *plane, int x_start, 483 - int y_start, enum pixel_read_direction direction, int count, 484 - struct pixel_argb_u16 out_pixel[]) 485 - { 486 - u8 *y_plane; 487 - u8 *uv_plane; 488 524 489 - packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, 490 - &y_plane); 491 - packed_pixels_addr_1x1(plane->frame_info, 492 - x_start / plane->frame_info->fb->format->hsub, 493 - y_start / plane->frame_info->fb->format->vsub, 1, 494 - &uv_plane); 495 - int step_y = get_block_step_bytes(plane->frame_info->fb, direction, 0); 496 - int step_uv = get_block_step_bytes(plane->frame_info->fb, direction, 1); 497 - int subsampling = get_subsampling(plane->frame_info->fb->format, direction); 498 - int subsampling_offset = get_subsampling_offset(direction, x_start, y_start); 499 - const struct conversion_matrix *conversion_matrix = &plane->conversion_matrix; 500 - 501 - for (int i = 0; i < count; i++) { 502 - *out_pixel = argb_u16_from_yuv888(y_plane[0], uv_plane[0], uv_plane[1], 503 - conversion_matrix); 504 - out_pixel += 1; 505 - y_plane += step_y; 506 - if ((i + subsampling_offset + 1) % subsampling == 0) 507 - uv_plane += step_uv; 508 - } 525 + /** 526 + * READ_LINE_YUV_SEMIPLANAR() - Generic generator for a read_line function which can be used for yuv 527 + * formats with two planes and block_w == block_h == 1. 528 + * 529 + * @function_name: Function name to generate 530 + * @pixel_1_name: temporary pixel name for the first plane used in the @__VA_ARGS__ parameters 531 + * @pixel_2_name: temporary pixel name for the second plane used in the @__VA_ARGS__ parameters 532 + * @pixel_1_type: Used to specify the type you want to cast the pixel pointer on the plane 1 533 + * @pixel_2_type: Used to specify the type you want to cast the pixel pointer on the plane 2 534 + * @callback: Callback to call for each pixels. This function should take 535 + * (struct conversion_matrix*, @__VA_ARGS__) as parameter and return a pixel_argb_u16 536 + * __VA_ARGS__: Argument to pass inside the callback. You can use @pixel_1_name and @pixel_2_name 537 + * to access current pixel values 538 + */ 539 + #define READ_LINE_YUV_SEMIPLANAR(function_name, pixel_1_name, pixel_2_name, pixel_1_type, \ 540 + pixel_2_type, callback, ...) \ 541 + static void function_name(const struct vkms_plane_state *plane, int x_start, \ 542 + int y_start, enum pixel_read_direction direction, int count, \ 543 + struct pixel_argb_u16 out_pixel[]) \ 544 + { \ 545 + u8 *plane_1; \ 546 + u8 *plane_2; \ 547 + \ 548 + packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, \ 549 + &plane_1); \ 550 + packed_pixels_addr_1x1(plane->frame_info, \ 551 + x_start / plane->frame_info->fb->format->hsub, \ 552 + y_start / plane->frame_info->fb->format->vsub, 1, \ 553 + &plane_2); \ 554 + int step_1 = get_block_step_bytes(plane->frame_info->fb, direction, 0); \ 555 + int step_2 = get_block_step_bytes(plane->frame_info->fb, direction, 1); \ 556 + int subsampling = get_subsampling(plane->frame_info->fb->format, direction); \ 557 + int subsampling_offset = get_subsampling_offset(direction, x_start, y_start); \ 558 + const struct conversion_matrix *conversion_matrix = &plane->conversion_matrix; \ 559 + \ 560 + for (int i = 0; i < count; i++) { \ 561 + pixel_1_type *(pixel_1_name) = (pixel_1_type *)plane_1; \ 562 + pixel_2_type *(pixel_2_name) = (pixel_2_type *)plane_2; \ 563 + *out_pixel = (callback)(conversion_matrix, __VA_ARGS__); \ 564 + out_pixel += 1; \ 565 + plane_1 += step_1; \ 566 + if ((i + subsampling_offset + 1) % subsampling == 0) \ 567 + plane_2 += step_2; \ 568 + } \ 509 569 } 510 570 571 + READ_LINE_YUV_SEMIPLANAR(YUV888_semiplanar_read_line, y, uv, u8, u8, argb_u16_from_yuv161616, 572 + y[0] * 257, uv[0] * 257, uv[1] * 257) 573 + READ_LINE_YUV_SEMIPLANAR(YUV161616_semiplanar_read_line, y, uv, u16, u16, argb_u16_from_yuv161616, 574 + y[0], uv[0], uv[1]) 511 575 /* 512 576 * This callback can be used for YUV format where each color component is 513 577 * stored in a different plane (often called planar formats). It will ··· 566 586 const struct conversion_matrix *conversion_matrix = &plane->conversion_matrix; 567 587 568 588 for (int i = 0; i < count; i++) { 569 - *out_pixel = argb_u16_from_yuv888(*y_plane, *channel_1_plane, *channel_2_plane, 570 - conversion_matrix); 589 + *out_pixel = argb_u16_from_yuv161616(conversion_matrix, 590 + *y_plane * 257, *channel_1_plane * 257, 591 + *channel_2_plane * 257); 571 592 out_pixel += 1; 572 593 y_plane += step_y; 573 594 if ((i + subsampling_offset + 1) % subsampling == 0) { ··· 693 712 switch (format) { 694 713 case DRM_FORMAT_ARGB8888: 695 714 return &ARGB8888_read_line; 696 - case DRM_FORMAT_XRGB8888: 697 - return &XRGB8888_read_line; 698 715 case DRM_FORMAT_ABGR8888: 699 716 return &ABGR8888_read_line; 717 + case DRM_FORMAT_BGRA8888: 718 + return &BGRA8888_read_line; 719 + case DRM_FORMAT_RGBA8888: 720 + return &RGBA8888_read_line; 721 + case DRM_FORMAT_XRGB8888: 722 + return &XRGB8888_read_line; 723 + case DRM_FORMAT_XBGR8888: 724 + return &XBGR8888_read_line; 725 + case DRM_FORMAT_RGB888: 726 + return &RGB888_read_line; 727 + case DRM_FORMAT_BGR888: 728 + return &BGR888_read_line; 700 729 case DRM_FORMAT_ARGB16161616: 701 730 return &ARGB16161616_read_line; 731 + case DRM_FORMAT_ABGR16161616: 732 + return &ABGR16161616_read_line; 702 733 case DRM_FORMAT_XRGB16161616: 703 734 return &XRGB16161616_read_line; 735 + case DRM_FORMAT_XBGR16161616: 736 + return &XBGR16161616_read_line; 704 737 case DRM_FORMAT_RGB565: 705 738 return &RGB565_read_line; 739 + case DRM_FORMAT_BGR565: 740 + return &BGR565_read_line; 706 741 case DRM_FORMAT_NV12: 707 742 case DRM_FORMAT_NV16: 708 743 case DRM_FORMAT_NV24: 709 744 case DRM_FORMAT_NV21: 710 745 case DRM_FORMAT_NV61: 711 746 case DRM_FORMAT_NV42: 712 - return &semi_planar_yuv_read_line; 747 + return &YUV888_semiplanar_read_line; 748 + case DRM_FORMAT_P010: 749 + case DRM_FORMAT_P012: 750 + case DRM_FORMAT_P016: 751 + return &YUV161616_semiplanar_read_line; 713 752 case DRM_FORMAT_YUV420: 714 753 case DRM_FORMAT_YUV422: 715 754 case DRM_FORMAT_YUV444:
+2 -2
drivers/gpu/drm/vkms/vkms_formats.h
··· 14 14 struct conversion_matrix *matrix); 15 15 16 16 #if IS_ENABLED(CONFIG_KUNIT) 17 - struct pixel_argb_u16 argb_u16_from_yuv888(u8 y, u8 channel_1, u8 channel_2, 18 - const struct conversion_matrix *matrix); 17 + struct pixel_argb_u16 argb_u16_from_yuv161616(const struct conversion_matrix *matrix, 18 + u16 y, u16 channel_1, u16 channel_2); 19 19 #endif 20 20 21 21 #endif /* _VKMS_FORMATS_H_ */
+12 -1
drivers/gpu/drm/vkms/vkms_plane.c
··· 14 14 15 15 static const u32 vkms_formats[] = { 16 16 DRM_FORMAT_ARGB8888, 17 - DRM_FORMAT_XRGB8888, 18 17 DRM_FORMAT_ABGR8888, 18 + DRM_FORMAT_BGRA8888, 19 + DRM_FORMAT_RGBA8888, 20 + DRM_FORMAT_XRGB8888, 21 + DRM_FORMAT_XBGR8888, 22 + DRM_FORMAT_RGB888, 23 + DRM_FORMAT_BGR888, 19 24 DRM_FORMAT_XRGB16161616, 25 + DRM_FORMAT_XBGR16161616, 20 26 DRM_FORMAT_ARGB16161616, 27 + DRM_FORMAT_ABGR16161616, 21 28 DRM_FORMAT_RGB565, 29 + DRM_FORMAT_BGR565, 22 30 DRM_FORMAT_NV12, 23 31 DRM_FORMAT_NV16, 24 32 DRM_FORMAT_NV24, ··· 39 31 DRM_FORMAT_YVU420, 40 32 DRM_FORMAT_YVU422, 41 33 DRM_FORMAT_YVU444, 34 + DRM_FORMAT_P010, 35 + DRM_FORMAT_P012, 36 + DRM_FORMAT_P016, 42 37 DRM_FORMAT_R1, 43 38 DRM_FORMAT_R2, 44 39 DRM_FORMAT_R4,
+12
drivers/gpu/drm/xe/xe_dma_buf.c
··· 191 191 { 192 192 struct xe_bo *bo = gem_to_xe_bo(obj); 193 193 struct dma_buf *buf; 194 + struct ttm_operation_ctx ctx = { 195 + .interruptible = true, 196 + .no_wait_gpu = true, 197 + /* We opt to avoid OOM on system pages allocations */ 198 + .gfp_retry_mayfail = true, 199 + .allow_res_evict = false, 200 + }; 201 + int ret; 194 202 195 203 if (bo->vm) 196 204 return ERR_PTR(-EPERM); 205 + 206 + ret = ttm_bo_setup_export(&bo->ttm, &ctx); 207 + if (ret) 208 + return ERR_PTR(ret); 197 209 198 210 buf = drm_gem_prime_export(obj, flags); 199 211 if (!IS_ERR(buf))
+5 -26
drivers/pci/vgaarb.c
··· 556 556 557 557 static bool vga_is_firmware_default(struct pci_dev *pdev) 558 558 { 559 - #if defined(CONFIG_X86) 560 - u64 base = screen_info.lfb_base; 561 - u64 size = screen_info.lfb_size; 562 - struct resource *r; 563 - u64 limit; 559 + #ifdef CONFIG_SCREEN_INFO 560 + struct screen_info *si = &screen_info; 564 561 565 - /* Select the device owning the boot framebuffer if there is one */ 566 - 567 - if (screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE) 568 - base |= (u64)screen_info.ext_lfb_base << 32; 569 - 570 - limit = base + size; 571 - 572 - /* Does firmware framebuffer belong to us? */ 573 - pci_dev_for_each_resource(pdev, r) { 574 - if (resource_type(r) != IORESOURCE_MEM) 575 - continue; 576 - 577 - if (!r->start || !r->end) 578 - continue; 579 - 580 - if (base < r->start || limit >= r->end) 581 - continue; 582 - 583 - return true; 584 - } 585 - #endif 562 + return pdev == screen_info_pci_dev(si); 563 + #else 586 564 return false; 565 + #endif 587 566 } 588 567 589 568 static bool vga_arb_integrated_gpu(struct device *dev)
+2
include/drm/ttm/ttm_bo.h
··· 466 466 void ttm_bo_tt_destroy(struct ttm_buffer_object *bo); 467 467 int ttm_bo_populate(struct ttm_buffer_object *bo, 468 468 struct ttm_operation_ctx *ctx); 469 + int ttm_bo_setup_export(struct ttm_buffer_object *bo, 470 + struct ttm_operation_ctx *ctx); 469 471 470 472 /* Driver LRU walk helpers initially targeted for shrinking. */ 471 473
+111
include/uapi/drm/amdxdna_accel.h
··· 34 34 DRM_AMDXDNA_EXEC_CMD, 35 35 DRM_AMDXDNA_GET_INFO, 36 36 DRM_AMDXDNA_SET_STATE, 37 + DRM_AMDXDNA_GET_ARRAY = 10, 37 38 }; 38 39 39 40 /** ··· 456 455 __u64 buffer; /* in/out */ 457 456 }; 458 457 458 + #define AMDXDNA_HWCTX_STATE_IDLE 0 459 + #define AMDXDNA_HWCTX_STATE_ACTIVE 1 460 + 461 + /** 462 + * struct amdxdna_drm_hwctx_entry - The hardware context array entry 463 + */ 464 + struct amdxdna_drm_hwctx_entry { 465 + /** @context_id: Context ID. */ 466 + __u32 context_id; 467 + /** @start_col: Start AIE array column assigned to context. */ 468 + __u32 start_col; 469 + /** @num_col: Number of AIE array columns assigned to context. */ 470 + __u32 num_col; 471 + /** @hwctx_id: The real hardware context id. */ 472 + __u32 hwctx_id; 473 + /** @pid: ID of process which created this context. */ 474 + __s64 pid; 475 + /** @command_submissions: Number of commands submitted. */ 476 + __u64 command_submissions; 477 + /** @command_completions: Number of commands completed. */ 478 + __u64 command_completions; 479 + /** @migrations: Number of times been migrated. */ 480 + __u64 migrations; 481 + /** @preemptions: Number of times been preempted. */ 482 + __u64 preemptions; 483 + /** @errors: Number of errors happened. */ 484 + __u64 errors; 485 + /** @priority: Context priority. */ 486 + __u64 priority; 487 + /** @heap_usage: Usage of device heap buffer. */ 488 + __u64 heap_usage; 489 + /** @suspensions: Number of times been suspended. */ 490 + __u64 suspensions; 491 + /** 492 + * @state: Context state. 493 + * %AMDXDNA_HWCTX_STATE_IDLE 494 + * %AMDXDNA_HWCTX_STATE_ACTIVE 495 + */ 496 + __u32 state; 497 + /** @pasid: PASID been bound. */ 498 + __u32 pasid; 499 + /** @gops: Giga operations per second. */ 500 + __u32 gops; 501 + /** @fps: Frames per second. */ 502 + __u32 fps; 503 + /** @dma_bandwidth: DMA bandwidth. */ 504 + __u32 dma_bandwidth; 505 + /** @latency: Frame response latency. */ 506 + __u32 latency; 507 + /** @frame_exec_time: Frame execution time. */ 508 + __u32 frame_exec_time; 509 + /** @txn_op_idx: Index of last control code executed. */ 510 + __u32 txn_op_idx; 511 + /** @ctx_pc: Program counter. */ 512 + __u32 ctx_pc; 513 + /** @fatal_error_type: Fatal error type if context crashes. */ 514 + __u32 fatal_error_type; 515 + /** @fatal_error_exception_type: Firmware exception type. */ 516 + __u32 fatal_error_exception_type; 517 + /** @fatal_error_exception_pc: Firmware exception program counter. */ 518 + __u32 fatal_error_exception_pc; 519 + /** @fatal_error_app_module: Exception module name. */ 520 + __u32 fatal_error_app_module; 521 + /** @pad: Structure pad. */ 522 + __u32 pad; 523 + }; 524 + 525 + #define DRM_AMDXDNA_HW_CONTEXT_ALL 0 526 + 527 + /** 528 + * struct amdxdna_drm_get_array - Get information array. 529 + */ 530 + struct amdxdna_drm_get_array { 531 + /** 532 + * @param: 533 + * 534 + * Supported params: 535 + * 536 + * %DRM_AMDXDNA_HW_CONTEXT_ALL: 537 + * Returns all created hardware contexts. 538 + */ 539 + __u32 param; 540 + /** 541 + * @element_size: 542 + * 543 + * Specifies maximum element size and returns the actual element size. 544 + */ 545 + __u32 element_size; 546 + /** 547 + * @num_element: 548 + * 549 + * Specifies maximum number of elements and returns the actual number 550 + * of elements. 551 + */ 552 + __u32 num_element; /* in/out */ 553 + /** @pad: MBZ */ 554 + __u32 pad; 555 + /** 556 + * @buffer: 557 + * 558 + * Specifies the match conditions and returns the matched information 559 + * array. 560 + */ 561 + __u64 buffer; 562 + }; 563 + 459 564 enum amdxdna_drm_set_param { 460 565 DRM_AMDXDNA_SET_POWER_MODE, 461 566 DRM_AMDXDNA_WRITE_AIE_MEM, ··· 625 518 #define DRM_IOCTL_AMDXDNA_SET_STATE \ 626 519 DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDXDNA_SET_STATE, \ 627 520 struct amdxdna_drm_set_state) 521 + 522 + #define DRM_IOCTL_AMDXDNA_GET_ARRAY \ 523 + DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDXDNA_GET_ARRAY, \ 524 + struct amdxdna_drm_get_array) 628 525 629 526 #if defined(__cplusplus) 630 527 } /* extern c end */