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

Merge tag 'drm-misc-next-2023-12-14' of git://anongit.freedesktop.org/drm/drm-misc into drm-next

drm-misc-next for $kernel-version:

UAPI Changes:

Cross-subsystem Changes:
- A few fixes for usb/typec

Core Changes:
- ci: Updates to the defconfig, igt version, etc.
- writeback: Move the atomic_check helper from the encoder to connector

Driver Changes:
- rockchip: Add support for rk3588
- xe: Update the TODO list
- panel:
- nv3052c: Register documentation, init sequence improvements and
support for the Fascontek FS035VG158
- st7701: Add support for the Anbernic RG-ARC
- new driver: Synaptics R63353 panel controller, Ilitek ILI9805 panel
controller
- new panel: AUO G156HAN04.0

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

From: Maxime Ripard <mripard@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/aqpn5miejmkks7pbcfex7b6u63uwsruywxsnr3x5ljs45qatin@nbkkej2elk46

+2568 -386
+56
Documentation/devicetree/bindings/display/panel/fascontek,fs035vg158.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/display/panel/fascontek,fs035vg158.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Fascontek FS035VG158 3.5" (640x480 pixels) 24-bit IPS LCD panel 8 + 9 + maintainers: 10 + - John Watts <contact@jookia.org> 11 + 12 + allOf: 13 + - $ref: panel-common.yaml# 14 + - $ref: /schemas/spi/spi-peripheral-props.yaml# 15 + 16 + properties: 17 + compatible: 18 + const: fascontek,fs035vg158 19 + 20 + spi-3wire: true 21 + 22 + required: 23 + - compatible 24 + - reg 25 + - port 26 + - power-supply 27 + - reset-gpios 28 + 29 + unevaluatedProperties: false 30 + 31 + examples: 32 + - | 33 + #include <dt-bindings/gpio/gpio.h> 34 + 35 + spi { 36 + #address-cells = <1>; 37 + #size-cells = <0>; 38 + panel@0 { 39 + compatible = "fascontek,fs035vg158"; 40 + reg = <0>; 41 + 42 + spi-3wire; 43 + spi-max-frequency = <3125000>; 44 + 45 + reset-gpios = <&gpe 2 GPIO_ACTIVE_LOW>; 46 + 47 + backlight = <&backlight>; 48 + power-supply = <&vcc>; 49 + 50 + port { 51 + panel_input: endpoint { 52 + remote-endpoint = <&panel_output>; 53 + }; 54 + }; 55 + }; 56 + };
+62
Documentation/devicetree/bindings/display/panel/ilitek,ili9805.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/display/panel/ilitek,ili9805.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Ilitek ILI9805 based MIPI-DSI panels 8 + 9 + maintainers: 10 + - Michael Trimarchi <michael@amarulasolutions.com> 11 + 12 + allOf: 13 + - $ref: panel-common.yaml# 14 + 15 + properties: 16 + compatible: 17 + items: 18 + - enum: 19 + - giantplus,gpm1790a0 20 + - tianma,tm041xdhg01 21 + - const: ilitek,ili9805 22 + 23 + avdd-supply: true 24 + dvdd-supply: true 25 + reg: true 26 + 27 + required: 28 + - compatible 29 + - avdd-supply 30 + - dvdd-supply 31 + - reg 32 + - reset-gpios 33 + - port 34 + - backlight 35 + 36 + unevaluatedProperties: false 37 + 38 + examples: 39 + - | 40 + #include <dt-bindings/gpio/gpio.h> 41 + 42 + dsi { 43 + #address-cells = <1>; 44 + #size-cells = <0>; 45 + 46 + panel@0 { 47 + compatible = "giantplus,gpm1790a0", "ilitek,ili9805"; 48 + reg = <0>; 49 + avdd-supply = <&avdd_display>; 50 + dvdd-supply = <&dvdd_display>; 51 + reset-gpios = <&r_pio 0 5 GPIO_ACTIVE_LOW>; /* PL05 */ 52 + backlight = <&backlight>; 53 + 54 + port { 55 + panel_in: endpoint { 56 + remote-endpoint = <&mipi_dsi_out>; 57 + }; 58 + }; 59 + }; 60 + }; 61 + 62 + ...
+2 -6
Documentation/devicetree/bindings/display/panel/leadtek,ltk035c5444t.yaml
··· 18 18 compatible: 19 19 const: leadtek,ltk035c5444t 20 20 21 - backlight: true 22 - port: true 23 - power-supply: true 24 - reg: true 25 - reset-gpios: true 26 - 27 21 spi-3wire: true 28 22 29 23 required: 30 24 - compatible 25 + - reg 26 + - port 31 27 - power-supply 32 28 - reset-gpios 33 29
+2
Documentation/devicetree/bindings/display/panel/panel-simple-lvds-dual-ports.yaml
··· 33 33 34 34 # AU Optronics Corporation 13.3" FHD (1920x1080) TFT LCD panel 35 35 - auo,g133han01 36 + # AU Optronics Corporation 15.6" FHD (1920x1080) TFT LCD panel 37 + - auo,g156han04 36 38 # AU Optronics Corporation 18.5" FHD (1920x1080) TFT LCD panel 37 39 - auo,g185han01 38 40 # AU Optronics Corporation 19.0" (1280x1024) TFT LCD panel
+1
Documentation/devicetree/bindings/display/panel/sitronix,st7701.yaml
··· 27 27 compatible: 28 28 items: 29 29 - enum: 30 + - anbernic,rg-arc-panel 30 31 - densitron,dmt028vghmcmi-1a 31 32 - elida,kd50t048a 32 33 - techstar,ts8550b
+81 -19
Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml
··· 8 8 9 9 description: 10 10 VOP2 (Video Output Processor v2) is the display controller for the Rockchip 11 - series of SoCs which transfers the image data from a video memory 12 - buffer to an external LCD interface. 11 + series of SoCs which transfers the image data from a video memory buffer to 12 + an external LCD interface. 13 13 14 14 maintainers: 15 15 - Sandy Huang <hjc@rock-chips.com> ··· 20 20 enum: 21 21 - rockchip,rk3566-vop 22 22 - rockchip,rk3568-vop 23 + - rockchip,rk3588-vop 23 24 24 25 reg: 25 26 items: ··· 28 27 Must contain one entry corresponding to the base address and length 29 28 of the register space. 30 29 - description: 31 - Can optionally contain a second entry corresponding to 32 - the CRTC gamma LUT address. 30 + Can optionally contain a second entry corresponding to the CRTC gamma 31 + LUT address. 33 32 34 33 reg-names: 35 34 items: ··· 42 41 The VOP interrupt is shared by several interrupt sources, such as 43 42 frame start (VSYNC), line flag and other status interrupts. 44 43 44 + # See compatible-specific constraints below. 45 45 clocks: 46 + minItems: 5 46 47 items: 47 - - description: Clock for ddr buffer transfer. 48 - - description: Clock for the ahb bus to R/W the phy regs. 48 + - description: Clock for ddr buffer transfer via axi. 49 + - description: Clock for the ahb bus to R/W the regs. 49 50 - description: Pixel clock for video port 0. 50 51 - description: Pixel clock for video port 1. 51 52 - description: Pixel clock for video port 2. 53 + - description: Pixel clock for video port 3. 54 + - description: Peripheral(vop grf/dsi) clock. 52 55 53 56 clock-names: 57 + minItems: 5 54 58 items: 55 59 - const: aclk 56 60 - const: hclk 57 61 - const: dclk_vp0 58 62 - const: dclk_vp1 59 63 - const: dclk_vp2 64 + - const: dclk_vp3 65 + - const: pclk_vop 60 66 61 67 rockchip,grf: 62 68 $ref: /schemas/types.yaml#/definitions/phandle 63 69 description: 64 - Phandle to GRF regs used for misc control 70 + Phandle to GRF regs used for control the polarity of dclk/hsync/vsync of DPI, 71 + also used for query vop memory bisr enable status, etc. 72 + 73 + rockchip,vo1-grf: 74 + $ref: /schemas/types.yaml#/definitions/phandle 75 + description: 76 + Phandle to VO GRF regs used for control the polarity of dclk/hsync/vsync of hdmi 77 + on rk3588. 78 + 79 + rockchip,vop-grf: 80 + $ref: /schemas/types.yaml#/definitions/phandle 81 + description: 82 + Phandle to VOP GRF regs used for control data path between vopr and hdmi/edp. 83 + 84 + rockchip,pmu: 85 + $ref: /schemas/types.yaml#/definitions/phandle 86 + description: 87 + Phandle to PMU GRF used for query vop memory bisr status on rk3588. 65 88 66 89 ports: 67 90 $ref: /schemas/graph.yaml#/properties/ports 68 91 69 - properties: 70 - port@0: 92 + patternProperties: 93 + "^port@[0-3]$": 71 94 $ref: /schemas/graph.yaml#/properties/port 72 - description: 73 - Output endpoint of VP0 95 + description: Output endpoint of VP0/1/2/3. 74 96 75 - port@1: 76 - $ref: /schemas/graph.yaml#/properties/port 77 - description: 78 - Output endpoint of VP1 97 + required: 98 + - port@0 79 99 80 - port@2: 81 - $ref: /schemas/graph.yaml#/properties/port 82 - description: 83 - Output endpoint of VP2 100 + unevaluatedProperties: false 84 101 85 102 iommus: 86 103 maxItems: 1 ··· 114 95 - clocks 115 96 - clock-names 116 97 - ports 98 + 99 + allOf: 100 + - if: 101 + properties: 102 + compatible: 103 + contains: 104 + const: rockchip,rk3588-vop 105 + then: 106 + properties: 107 + clocks: 108 + minItems: 7 109 + clock-names: 110 + minItems: 7 111 + 112 + ports: 113 + required: 114 + - port@0 115 + - port@1 116 + - port@2 117 + - port@3 118 + 119 + required: 120 + - rockchip,grf 121 + - rockchip,vo1-grf 122 + - rockchip,vop-grf 123 + - rockchip,pmu 124 + 125 + else: 126 + properties: 127 + rockchip,vo1-grf: false 128 + rockchip,vop-grf: false 129 + rockchip,pmu: false 130 + 131 + clocks: 132 + maxItems: 5 133 + clock-names: 134 + maxItems: 5 135 + 136 + ports: 137 + required: 138 + - port@0 139 + - port@1 140 + - port@2 117 141 118 142 additionalProperties: false 119 143
+2
Documentation/devicetree/bindings/vendor-prefixes.yaml
··· 474 474 description: Fairphone B.V. 475 475 "^faraday,.*": 476 476 description: Faraday Technology Corporation 477 + "^fascontek,.*": 478 + description: Fascontek 477 479 "^fastrax,.*": 478 480 description: Fastrax Oy 479 481 "^fcs,.*":
+4 -3
Documentation/gpu/automated_testing.rst
··· 69 69 70 70 Each new flake entry must be associated with a link to the email reporting the 71 71 bug to the author of the affected driver, the board name or Device Tree name of 72 - the board, the first kernel version affected, and an approximation of the 73 - failure rate. 72 + the board, the first kernel version affected, the IGT version used for tests, 73 + and an approximation of the failure rate. 74 74 75 75 They should be provided under the following format:: 76 76 77 77 # Bug Report: $LORE_OR_PATCHWORK_URL 78 78 # Board Name: broken-board.dtb 79 - # Version: 6.6-rc1 79 + # Linux Version: 6.6-rc1 80 + # IGT Version: 1.28-gd2af13d9f 80 81 # Failure Rate: 100 81 82 flaky-test 82 83
+62 -65
Documentation/gpu/rfc/xe.rst
··· 70 70 Xe – Pre-Merge Goals - Work-in-Progress 71 71 ======================================= 72 72 73 - Drm_scheduler 74 - ------------- 75 - Xe primarily uses Firmware based scheduling (GuC FW). However, it will use 76 - drm_scheduler as the scheduler ‘frontend’ for userspace submission in order to 77 - resolve syncobj and dma-buf implicit sync dependencies. However, drm_scheduler is 78 - not yet prepared to handle the 1-to-1 relationship between drm_gpu_scheduler and 79 - drm_sched_entity. 73 + Display integration with i915 74 + ----------------------------- 75 + In order to share the display code with the i915 driver so that there is maximum 76 + reuse, the i915/display/ code is built twice, once for i915.ko and then for 77 + xe.ko. Currently, the i915/display code in Xe tree is polluted with many 'ifdefs' 78 + depending on the build target. The goal is to refactor both Xe and i915/display 79 + code simultaneously in order to get a clean result before they land upstream, so 80 + that display can already be part of the initial pull request towards drm-next. 80 81 81 - Deeper changes to drm_scheduler should *not* be required to get Xe accepted, but 82 - some consensus needs to be reached between Xe and other community drivers that 83 - could also benefit from this work, for coupling FW based/assisted submission such 84 - as the ARM’s new Mali GPU driver, and others. 82 + However, display code should not gate the acceptance of Xe in upstream. Xe 83 + patches will be refactored in a way that display code can be removed, if needed, 84 + from the first pull request of Xe towards drm-next. The expectation is that when 85 + both drivers are part of the drm-tip, the introduction of cleaner patches will be 86 + easier and speed up. 85 87 86 - As a key measurable result, the patch series introducing Xe itself shall not 87 - depend on any other patch touching drm_scheduler itself that was not yet merged 88 - through drm-misc. This, by itself, already includes the reach of an agreement for 89 - uniform 1 to 1 relationship implementation / usage across drivers. 88 + Xe – uAPI high level overview 89 + ============================= 90 90 91 - ASYNC VM_BIND 92 - ------------- 93 - Although having a common DRM level IOCTL for VM_BIND is not a requirement to get 94 - Xe merged, it is mandatory to have a consensus with other drivers and Mesa. 95 - It needs to be clear how to handle async VM_BIND and interactions with userspace 96 - memory fences. Ideally with helper support so people don't get it wrong in all 97 - possible ways. 91 + ...Warning: To be done in follow up patches after/when/where the main consensus in various items are individually reached. 98 92 99 - As a key measurable result, the benefits of ASYNC VM_BIND and a discussion of 100 - various flavors, error handling and sample API suggestions are documented in 101 - :doc:`The ASYNC VM_BIND document </gpu/drm-vm-bind-async>`. 93 + Xe – Pre-Merge Goals - Completed 94 + ================================ 95 + 96 + Drm_exec 97 + -------- 98 + Helper to make dma_resv locking for a big number of buffers is getting removed in 99 + the drm_exec series proposed in https://patchwork.freedesktop.org/patch/524376/ 100 + If that happens, Xe needs to change and incorporate the changes in the driver. 101 + The goal is to engage with the Community to understand if the best approach is to 102 + move that to the drivers that are using it or if we should keep the helpers in 103 + place waiting for Xe to get merged. 104 + 105 + This item ties into the GPUVA, VM_BIND, and even long-running compute support. 106 + 107 + As a key measurable result, we need to have a community consensus documented in 108 + this document and the Xe driver prepared for the changes, if necessary. 102 109 103 110 Userptr integration and vm_bind 104 111 ------------------------------- ··· 139 132 The DRM GPUVM helpers do not yet include the userptr parts, but discussions 140 133 about implementing them are ongoing. 141 134 135 + ASYNC VM_BIND 136 + ------------- 137 + Although having a common DRM level IOCTL for VM_BIND is not a requirement to get 138 + Xe merged, it is mandatory to have a consensus with other drivers and Mesa. 139 + It needs to be clear how to handle async VM_BIND and interactions with userspace 140 + memory fences. Ideally with helper support so people don't get it wrong in all 141 + possible ways. 142 + 143 + As a key measurable result, the benefits of ASYNC VM_BIND and a discussion of 144 + various flavors, error handling and sample API suggestions are documented in 145 + :doc:`The ASYNC VM_BIND document </gpu/drm-vm-bind-async>`. 146 + 147 + Drm_scheduler 148 + ------------- 149 + Xe primarily uses Firmware based scheduling (GuC FW). However, it will use 150 + drm_scheduler as the scheduler ‘frontend’ for userspace submission in order to 151 + resolve syncobj and dma-buf implicit sync dependencies. However, drm_scheduler is 152 + not yet prepared to handle the 1-to-1 relationship between drm_gpu_scheduler and 153 + drm_sched_entity. 154 + 155 + Deeper changes to drm_scheduler should *not* be required to get Xe accepted, but 156 + some consensus needs to be reached between Xe and other community drivers that 157 + could also benefit from this work, for coupling FW based/assisted submission such 158 + as the ARM’s new Mali GPU driver, and others. 159 + 160 + As a key measurable result, the patch series introducing Xe itself shall not 161 + depend on any other patch touching drm_scheduler itself that was not yet merged 162 + through drm-misc. This, by itself, already includes the reach of an agreement for 163 + uniform 1 to 1 relationship implementation / usage across drivers. 164 + 142 165 Long running compute: minimal data structure/scaffolding 143 166 -------------------------------------------------------- 144 167 The generic scheduler code needs to include the handling of endless compute ··· 180 143 this minimal drm/scheduler work, if needed, merged to drm-misc in a way that any 181 144 drm driver, including Xe, could re-use and add their own individual needs on top 182 145 in a next stage. However, this should not block the initial merge. 183 - 184 - This is a non-blocker item since the driver without the support for the long 185 - running compute enabled is not a showstopper. 186 - 187 - Display integration with i915 188 - ----------------------------- 189 - In order to share the display code with the i915 driver so that there is maximum 190 - reuse, the i915/display/ code is built twice, once for i915.ko and then for 191 - xe.ko. Currently, the i915/display code in Xe tree is polluted with many 'ifdefs' 192 - depending on the build target. The goal is to refactor both Xe and i915/display 193 - code simultaneously in order to get a clean result before they land upstream, so 194 - that display can already be part of the initial pull request towards drm-next. 195 - 196 - However, display code should not gate the acceptance of Xe in upstream. Xe 197 - patches will be refactored in a way that display code can be removed, if needed, 198 - from the first pull request of Xe towards drm-next. The expectation is that when 199 - both drivers are part of the drm-tip, the introduction of cleaner patches will be 200 - easier and speed up. 201 - 202 - Drm_exec 203 - -------- 204 - Helper to make dma_resv locking for a big number of buffers is getting removed in 205 - the drm_exec series proposed in https://patchwork.freedesktop.org/patch/524376/ 206 - If that happens, Xe needs to change and incorporate the changes in the driver. 207 - The goal is to engage with the Community to understand if the best approach is to 208 - move that to the drivers that are using it or if we should keep the helpers in 209 - place waiting for Xe to get merged. 210 - 211 - This item ties into the GPUVA, VM_BIND, and even long-running compute support. 212 - 213 - As a key measurable result, we need to have a community consensus documented in 214 - this document and the Xe driver prepared for the changes, if necessary. 215 - 216 - Xe – uAPI high level overview 217 - ============================= 218 - 219 - ...Warning: To be done in follow up patches after/when/where the main consensus in various items are individually reached. 220 - 221 - Xe – Pre-Merge Goals - Completed 222 - ================================ 223 146 224 147 Dev_coredump 225 148 ------------
+13
MAINTAINERS
··· 6627 6627 F: Documentation/devicetree/bindings/display/ilitek,ili9486.yaml 6628 6628 F: drivers/gpu/drm/tiny/ili9486.c 6629 6629 6630 + DRM DRIVER FOR ILITEK ILI9805 PANELS 6631 + M: Michael Trimarchi <michael@amarulasolutions.com> 6632 + S: Maintained 6633 + F: Documentation/devicetree/bindings/display/panel/ilitek,ili9805.yaml 6634 + F: drivers/gpu/drm/panel/panel-ilitek-ili9805.c 6635 + 6630 6636 DRM DRIVER FOR JADARD JD9365DA-H3 MIPI-DSI LCD PANELS 6631 6637 M: Jagan Teki <jagan@edgeble.ai> 6632 6638 S: Maintained ··· 6860 6854 T: git git://anongit.freedesktop.org/drm/drm-misc 6861 6855 F: Documentation/devicetree/bindings/display/ste,mcde.yaml 6862 6856 F: drivers/gpu/drm/mcde/ 6857 + 6858 + DRM DRIVER FOR SYNAPTICS R63353 PANELS 6859 + M: Michael Trimarchi <michael@amarulasolutions.com> 6860 + S: Maintained 6861 + F: Documentation/devicetree/bindings/display/panel/synaptics,r63353.yaml 6862 + F: drivers/gpu/drm/panel/panel-synaptics-r63353.c 6863 6863 6864 6864 DRM DRIVER FOR TI DLPC3433 MIPI DSI TO DMD BRIDGE 6865 6865 M: Jagan Teki <jagan@amarulasolutions.com> ··· 7151 7139 DRM DRIVERS FOR ROCKCHIP 7152 7140 M: Sandy Huang <hjc@rock-chips.com> 7153 7141 M: Heiko Stübner <heiko@sntech.de> 7142 + M: Andy Yan <andy.yan@rock-chips.com> 7154 7143 L: dri-devel@lists.freedesktop.org 7155 7144 S: Maintained 7156 7145 T: git git://anongit.freedesktop.org/drm/drm-misc
+1 -1
drivers/gpu/drm/bridge/aux-hpd-bridge.c
··· 6 6 */ 7 7 #include <linux/auxiliary_bus.h> 8 8 #include <linux/module.h> 9 - #include <linux/of_device.h> 9 + #include <linux/of.h> 10 10 11 11 #include <drm/drm_bridge.h> 12 12 #include <drm/bridge/aux-bridge.h>
+9 -7
drivers/gpu/drm/bridge/ti-sn65dsi86.c
··· 1413 1413 int ret; 1414 1414 1415 1415 if (!pdata->pwm_enabled) { 1416 - ret = pm_runtime_resume_and_get(pdata->dev); 1416 + ret = pm_runtime_resume_and_get(chip->dev); 1417 1417 if (ret < 0) 1418 1418 return ret; 1419 1419 } ··· 1429 1429 SN_GPIO_MUX_MASK << (2 * SN_PWM_GPIO_IDX), 1430 1430 SN_GPIO_MUX_SPECIAL << (2 * SN_PWM_GPIO_IDX)); 1431 1431 if (ret) { 1432 - dev_err(pdata->dev, "failed to mux in PWM function\n"); 1432 + dev_err(chip->dev, "failed to mux in PWM function\n"); 1433 1433 goto out; 1434 1434 } 1435 1435 } ··· 1505 1505 1506 1506 ret = regmap_write(pdata->regmap, SN_PWM_PRE_DIV_REG, pre_div); 1507 1507 if (ret) { 1508 - dev_err(pdata->dev, "failed to update PWM_PRE_DIV\n"); 1508 + dev_err(chip->dev, "failed to update PWM_PRE_DIV\n"); 1509 1509 goto out; 1510 1510 } 1511 1511 ··· 1517 1517 FIELD_PREP(SN_PWM_INV_MASK, state->polarity == PWM_POLARITY_INVERSED); 1518 1518 ret = regmap_write(pdata->regmap, SN_PWM_EN_INV_REG, pwm_en_inv); 1519 1519 if (ret) { 1520 - dev_err(pdata->dev, "failed to update PWM_EN/PWM_INV\n"); 1520 + dev_err(chip->dev, "failed to update PWM_EN/PWM_INV\n"); 1521 1521 goto out; 1522 1522 } 1523 1523 ··· 1525 1525 out: 1526 1526 1527 1527 if (!pdata->pwm_enabled) 1528 - pm_runtime_put_sync(pdata->dev); 1528 + pm_runtime_put_sync(chip->dev); 1529 1529 1530 1530 return ret; 1531 1531 } ··· 1585 1585 { 1586 1586 struct ti_sn65dsi86 *pdata = dev_get_drvdata(adev->dev.parent); 1587 1587 1588 - pdata->pchip.dev = pdata->dev; 1588 + pdata->pchip.dev = &adev->dev; 1589 1589 pdata->pchip.ops = &ti_sn_pwm_ops; 1590 1590 pdata->pchip.npwm = 1; 1591 1591 pdata->pchip.of_xlate = of_pwm_single_xlate; 1592 1592 pdata->pchip.of_pwm_n_cells = 1; 1593 + 1594 + devm_pm_runtime_enable(&adev->dev); 1593 1595 1594 1596 return pwmchip_add(&pdata->pchip); 1595 1597 } ··· 1603 1601 pwmchip_remove(&pdata->pchip); 1604 1602 1605 1603 if (pdata->pwm_enabled) 1606 - pm_runtime_put_sync(pdata->dev); 1604 + pm_runtime_put_sync(&adev->dev); 1607 1605 } 1608 1606 1609 1607 static const struct auxiliary_device_id ti_sn_pwm_id_table[] = {
+1
drivers/gpu/drm/ci/arm64.config
··· 186 186 CONFIG_MTK_DEVAPC=y 187 187 CONFIG_PWM_MTK_DISP=y 188 188 CONFIG_MTK_CMDQ=y 189 + CONFIG_REGULATOR_DA9211=y 189 190 190 191 # For nouveau. Note that DRM must be a module so that it's loaded after NFS is up to provide the firmware. 191 192 CONFIG_ARCH_TEGRA=y
+8 -8
drivers/gpu/drm/ci/build.sh
··· 19 19 DEVICE_TREES+=" arch/arm64/boot/dts/amlogic/meson-gxl-s805x-libretech-ac.dtb" 20 20 DEVICE_TREES+=" arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dtb" 21 21 DEVICE_TREES+=" arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dtb" 22 - DEVICE_TREES+=" arch/arm64/boot/dts/qcom/apq8016-sbc.dtb" 22 + DEVICE_TREES+=" arch/arm64/boot/dts/qcom/apq8016-sbc-usb-host.dtb" 23 23 DEVICE_TREES+=" arch/arm64/boot/dts/qcom/apq8096-db820c.dtb" 24 24 DEVICE_TREES+=" arch/arm64/boot/dts/amlogic/meson-g12b-a311d-khadas-vim3.dtb" 25 25 DEVICE_TREES+=" arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtb" ··· 75 75 fi 76 76 fi 77 77 78 - for opt in $ENABLE_KCONFIGS; do 79 - echo CONFIG_$opt=y >> drivers/gpu/drm/ci/${KERNEL_ARCH}.config 80 - done 81 - for opt in $DISABLE_KCONFIGS; do 82 - echo CONFIG_$opt=n >> drivers/gpu/drm/ci/${KERNEL_ARCH}.config 83 - done 84 - 85 78 if [[ -n "${MERGE_FRAGMENT}" ]]; then 86 79 ./scripts/kconfig/merge_config.sh ${DEFCONFIG} drivers/gpu/drm/ci/${MERGE_FRAGMENT} 87 80 else 88 81 make `basename ${DEFCONFIG}` 89 82 fi 83 + 84 + for opt in $ENABLE_KCONFIGS; do 85 + ./scripts/config --enable CONFIG_$opt 86 + done 87 + for opt in $DISABLE_KCONFIGS; do 88 + ./scripts/config --disable CONFIG_$opt 89 + done 90 90 91 91 make ${KERNEL_IMAGE_NAME} 92 92
+1 -1
drivers/gpu/drm/ci/gitlab-ci.yml
··· 5 5 UPSTREAM_REPO: git://anongit.freedesktop.org/drm/drm 6 6 TARGET_BRANCH: drm-next 7 7 8 - IGT_VERSION: d1db7333d9c5fbbb05e50b0804123950d9dc1c46 8 + IGT_VERSION: d2af13d9f5be5ce23d996e4afd3e45990f5ab977 9 9 10 10 DEQP_RUNNER_GIT_URL: https://gitlab.freedesktop.org/anholt/deqp-runner.git 11 11 DEQP_RUNNER_GIT_TAG: v0.15.0
+8 -2
drivers/gpu/drm/ci/igt_runner.sh
··· 15 15 ' 16 16 17 17 # Dump drm state to confirm that kernel was able to find a connected display: 18 - # TODO this path might not exist for all drivers.. maybe run modetest instead? 19 18 set +e 20 19 cat /sys/kernel/debug/dri/*/state 21 20 set -e 22 21 23 22 case "$DRIVER_NAME" in 24 - rockchip|mediatek|meson) 23 + rockchip|meson) 25 24 export IGT_FORCE_DRIVER="panfrost" 25 + ;; 26 + mediatek) 27 + if [ "$GPU_VERSION" = "mt8173" ]; then 28 + export IGT_FORCE_DRIVER=${DRIVER_NAME} 29 + elif [ "$GPU_VERSION" = "mt8183" ]; then 30 + export IGT_FORCE_DRIVER="panfrost" 31 + fi 26 32 ;; 27 33 amdgpu) 28 34 # Cannot use HWCI_KERNEL_MODULES as at that point we don't have the module in /lib
+3 -10
drivers/gpu/drm/ci/test.yml
··· 102 102 stage: msm 103 103 variables: 104 104 DRIVER_NAME: msm 105 - BM_DTB: https://${PIPELINE_ARTIFACTS_BASE}/arm64/apq8016-sbc.dtb 105 + BM_DTB: https://${PIPELINE_ARTIFACTS_BASE}/arm64/apq8016-sbc-usb-host.dtb 106 106 GPU_VERSION: apq8016 107 107 BM_CMDLINE: "ip=dhcp console=ttyMSM0,115200n8 $BM_KERNEL_EXTRA_ARGS root=/dev/nfs rw nfsrootdebug nfsroot=,tcp,nfsvers=4.2 init=/init $BM_KERNELARGS" 108 108 RUNNER_TAG: google-freedreno-db410c 109 109 script: 110 110 - ./install/bare-metal/fastboot.sh 111 - rules: 112 - # TODO: current issue: it is not fiding the NFS root. Fix and remove this rule. 113 - - when: never 114 111 115 112 msm:apq8096: 116 113 extends: ··· 277 280 DEVICE_TYPE: mt8173-elm-hana 278 281 GPU_VERSION: mt8173 279 282 RUNNER_TAG: mesa-ci-x86-64-lava-mt8173-elm-hana 280 - rules: 281 - # TODO: current issue: device is hanging. Fix and remove this rule. 282 - - when: never 283 283 284 284 mediatek:mt8183: 285 285 extends: ··· 329 335 script: 330 336 - ln -sf $CI_PROJECT_DIR/install /install 331 337 - mv install/bzImage /lava-files/bzImage 338 + - mkdir -p $CI_PROJECT_DIR/results 339 + - ln -sf $CI_PROJECT_DIR/results /results 332 340 - install/crosvm-runner.sh install/igt_runner.sh 333 341 needs: 334 342 - debian/x86_64_test-gl 335 343 - testing:x86_64 336 344 - igt:x86_64 337 - rules: 338 - # TODO: current issue: malloc(): corrupted top size. Fix and remove this rule. 339 - - when: never
+10 -3
drivers/gpu/drm/ci/xfails/mediatek-mt8173-fails.txt
··· 1 1 kms_3d,Fail 2 - kms_addfb_basic@addfb25-bad-modifier,Fail 3 2 kms_bw@linear-tiling-1-displays-1920x1080p,Fail 4 3 kms_bw@linear-tiling-1-displays-2560x1440p,Fail 5 4 kms_bw@linear-tiling-1-displays-3840x2160p,Fail ··· 8 9 kms_bw@linear-tiling-3-displays-1920x1080p,Fail 9 10 kms_bw@linear-tiling-3-displays-2560x1440p,Fail 10 11 kms_bw@linear-tiling-3-displays-3840x2160p,Fail 12 + kms_color@invalid-gamma-lut-sizes,Fail 11 13 kms_color@pipe-A-invalid-gamma-lut-sizes,Fail 12 14 kms_color@pipe-B-invalid-gamma-lut-sizes,Fail 13 - kms_force_connector_basic@force-connector-state,Fail 15 + kms_cursor_legacy@cursor-vs-flip-atomic,Fail 16 + kms_cursor_legacy@cursor-vs-flip-legacy,Fail 17 + kms_flip@flip-vs-modeset-vs-hang,Fail 18 + kms_flip@flip-vs-panning-vs-hang,Fail 19 + kms_flip@flip-vs-suspend,Fail 20 + kms_flip@flip-vs-suspend-interruptible,Fail 14 21 kms_force_connector_basic@force-edid,Fail 15 22 kms_force_connector_basic@force-load-detect,Fail 16 23 kms_force_connector_basic@prune-stale-modes,Fail 17 - kms_invalid_mode@int-max-clock,Fail 24 + kms_hdmi_inject@inject-4k,Fail 18 25 kms_plane_scaling@planes-upscale-20x20,Fail 19 26 kms_plane_scaling@planes-upscale-20x20-downscale-factor-0-25,Fail 20 27 kms_plane_scaling@planes-upscale-20x20-downscale-factor-0-5,Fail ··· 32 27 kms_properties@plane-properties-atomic,Fail 33 28 kms_properties@plane-properties-legacy,Fail 34 29 kms_rmfb@close-fd,Fail 30 + kms_selftest@drm_format,Timeout 31 + kms_selftest@drm_format_helper,Timeout
+5
drivers/gpu/drm/ci/xfails/msm-apq8016-fails.txt
··· 6 6 kms_cursor_legacy@all-pipes-single-move,Fail 7 7 kms_cursor_legacy@all-pipes-torture-bo,Fail 8 8 kms_cursor_legacy@all-pipes-torture-move,Fail 9 + kms_cursor_legacy@forked-bo,Fail 10 + kms_cursor_legacy@forked-move,Fail 9 11 kms_cursor_legacy@pipe-A-forked-bo,Fail 10 12 kms_cursor_legacy@pipe-A-forked-move,Fail 11 13 kms_cursor_legacy@pipe-A-single-bo,Fail 12 14 kms_cursor_legacy@pipe-A-single-move,Fail 13 15 kms_cursor_legacy@pipe-A-torture-bo,Fail 14 16 kms_cursor_legacy@pipe-A-torture-move,Fail 17 + kms_force_connector_basic@force-edid,Fail 15 18 kms_hdmi_inject@inject-4k,Fail 19 + kms_selftest@drm_format,Timeout 20 + kms_selftest@drm_format_helper,Timeout
+46
drivers/gpu/drm/ci/xfails/virtio_gpu-none-fails.txt
··· 10 10 kms_bw@linear-tiling-2-displays-1920x1080p,Fail 11 11 kms_bw@linear-tiling-2-displays-2560x1440p,Fail 12 12 kms_bw@linear-tiling-2-displays-3840x2160p,Fail 13 + kms_bw@linear-tiling-3-displays-1920x1080p,Fail 14 + kms_bw@linear-tiling-3-displays-2560x1440p,Fail 15 + kms_bw@linear-tiling-3-displays-3840x2160p,Fail 16 + kms_bw@linear-tiling-4-displays-1920x1080p,Fail 17 + kms_bw@linear-tiling-4-displays-2560x1440p,Fail 18 + kms_bw@linear-tiling-4-displays-3840x2160p,Fail 19 + kms_bw@linear-tiling-5-displays-1920x1080p,Fail 20 + kms_bw@linear-tiling-5-displays-2560x1440p,Fail 21 + kms_bw@linear-tiling-5-displays-3840x2160p,Fail 22 + kms_bw@linear-tiling-6-displays-1920x1080p,Fail 23 + kms_bw@linear-tiling-6-displays-2560x1440p,Fail 24 + kms_bw@linear-tiling-6-displays-3840x2160p,Fail 25 + kms_bw@linear-tiling-7-displays-1920x1080p,Fail 26 + kms_bw@linear-tiling-7-displays-2560x1440p,Fail 27 + kms_bw@linear-tiling-7-displays-3840x2160p,Fail 28 + kms_bw@linear-tiling-8-displays-1920x1080p,Fail 29 + kms_bw@linear-tiling-8-displays-2560x1440p,Fail 30 + kms_bw@linear-tiling-8-displays-3840x2160p,Fail 31 + kms_flip@absolute-wf_vblank,Fail 32 + kms_flip@absolute-wf_vblank-interruptible,Fail 33 + kms_flip@basic-flip-vs-wf_vblank,Fail 34 + kms_flip@blocking-absolute-wf_vblank,Fail 35 + kms_flip@blocking-absolute-wf_vblank-interruptible,Fail 36 + kms_flip@blocking-wf_vblank,Fail 37 + kms_flip@busy-flip,Fail 38 + kms_flip@dpms-vs-vblank-race,Fail 39 + kms_flip@dpms-vs-vblank-race-interruptible,Fail 40 + kms_flip@flip-vs-absolute-wf_vblank,Fail 41 + kms_flip@flip-vs-absolute-wf_vblank-interruptible,Fail 42 + kms_flip@flip-vs-blocking-wf-vblank,Fail 43 + kms_flip@flip-vs-expired-vblank,Fail 44 + kms_flip@flip-vs-expired-vblank-interruptible,Fail 45 + kms_flip@flip-vs-modeset-vs-hang,Fail 46 + kms_flip@flip-vs-panning-vs-hang,Fail 47 + kms_flip@flip-vs-wf_vblank-interruptible,Fail 48 + kms_flip@modeset-vs-vblank-race,Fail 49 + kms_flip@modeset-vs-vblank-race-interruptible,Fail 50 + kms_flip@plain-flip-fb-recreate,Fail 51 + kms_flip@plain-flip-fb-recreate-interruptible,Fail 52 + kms_flip@plain-flip-ts-check,Fail 53 + kms_flip@plain-flip-ts-check-interruptible,Fail 54 + kms_flip@wf_vblank-ts-check,Fail 55 + kms_flip@wf_vblank-ts-check-interruptible,Fail 13 56 kms_invalid_mode@int-max-clock,Fail 14 57 kms_plane_scaling@downscale-with-modifier-factor-0-25,Fail 15 58 kms_plane_scaling@downscale-with-rotation-factor-0-25,Fail ··· 65 22 kms_plane_scaling@upscale-with-pixel-format-20x20,Fail 66 23 kms_plane_scaling@upscale-with-pixel-format-factor-0-25,Fail 67 24 kms_plane_scaling@upscale-with-rotation-20x20,Fail 25 + kms_selftest@drm_format,Timeout 26 + kms_selftest@drm_format_helper,Timeout 27 + kms_setmode@basic,Fail 68 28 kms_vblank@crtc-id,Fail 69 29 kms_vblank@invalid,Fail 70 30 kms_vblank@pipe-A-accuracy-idle,Fail
+9 -7
drivers/gpu/drm/drm_atomic_helper.c
··· 795 795 EXPORT_SYMBOL(drm_atomic_helper_check_modeset); 796 796 797 797 /** 798 - * drm_atomic_helper_check_wb_encoder_state() - Check writeback encoder state 799 - * @encoder: encoder state to check 800 - * @conn_state: connector state to check 798 + * drm_atomic_helper_check_wb_connector_state() - Check writeback connector state 799 + * @connector: corresponding connector 800 + * @state: the driver state object 801 801 * 802 802 * Checks if the writeback connector state is valid, and returns an error if it 803 803 * isn't. ··· 806 806 * Zero for success or -errno 807 807 */ 808 808 int 809 - drm_atomic_helper_check_wb_encoder_state(struct drm_encoder *encoder, 810 - struct drm_connector_state *conn_state) 809 + drm_atomic_helper_check_wb_connector_state(struct drm_connector *connector, 810 + struct drm_atomic_state *state) 811 811 { 812 + struct drm_connector_state *conn_state = 813 + drm_atomic_get_new_connector_state(state, connector); 812 814 struct drm_writeback_job *wb_job = conn_state->writeback_job; 813 815 struct drm_property_blob *pixel_format_blob; 814 816 struct drm_framebuffer *fb; ··· 829 827 if (fb->format->format == formats[i]) 830 828 return 0; 831 829 832 - drm_dbg_kms(encoder->dev, "Invalid pixel format %p4cc\n", &fb->format->format); 830 + drm_dbg_kms(connector->dev, "Invalid pixel format %p4cc\n", &fb->format->format); 833 831 834 832 return -EINVAL; 835 833 } 836 - EXPORT_SYMBOL(drm_atomic_helper_check_wb_encoder_state); 834 + EXPORT_SYMBOL(drm_atomic_helper_check_wb_connector_state); 837 835 838 836 /** 839 837 * drm_atomic_helper_check_plane_state() - Check plane state for validity
+1 -1
drivers/gpu/drm/drm_debugfs.c
··· 638 638 debugfs_create_file("bridges", 0444, root, encoder, 639 639 &bridges_fops); 640 640 641 - if (encoder->funcs->debugfs_init) 641 + if (encoder->funcs && encoder->funcs->debugfs_init) 642 642 encoder->funcs->debugfs_init(encoder, root); 643 643 } 644 644
+1 -1
drivers/gpu/drm/imagination/pvr_fw_trace.c
··· 248 248 continue; 249 249 250 250 return true; 251 - }; 251 + } 252 252 253 253 /* Hit end of trace data. */ 254 254 return false;
+3 -1
drivers/gpu/drm/imagination/pvr_mmu.c
··· 316 316 static void 317 317 pvr_mmu_backing_page_fini(struct pvr_mmu_backing_page *page) 318 318 { 319 - struct device *dev = from_pvr_device(page->pvr_dev)->dev; 319 + struct device *dev; 320 320 321 321 /* Do nothing if no allocation is present. */ 322 322 if (!page->pvr_dev) 323 323 return; 324 + 325 + dev = from_pvr_device(page->pvr_dev)->dev; 324 326 325 327 dma_unmap_page(dev, page->dma_addr, PVR_MMU_BACKING_PAGE_SIZE, 326 328 DMA_TO_DEVICE);
+1 -1
drivers/gpu/drm/imagination/pvr_vm.c
··· 225 225 u64 device_addr, u64 size) 226 226 { 227 227 struct drm_gem_object *obj = gem_from_pvr_gem(pvr_obj); 228 - const bool is_user = vm_ctx == vm_ctx->pvr_dev->kernel_vm_ctx; 228 + const bool is_user = vm_ctx != vm_ctx->pvr_dev->kernel_vm_ctx; 229 229 const u64 pvr_obj_size = pvr_gem_object_size(pvr_obj); 230 230 struct sg_table *sgt; 231 231 u64 offset_plus_size;
+18
drivers/gpu/drm/panel/Kconfig
··· 194 194 QVGA (240x320) RGB panels. support serial & parallel rgb 195 195 interface. 196 196 197 + config DRM_PANEL_ILITEK_ILI9805 198 + tristate "Ilitek ILI9805-based panels" 199 + depends on OF 200 + depends on DRM_MIPI_DSI 201 + depends on BACKLIGHT_CLASS_DEVICE 202 + help 203 + Say Y if you want to enable support for panels based on the 204 + Ilitek ILI9805 controller. 205 + 197 206 config DRM_PANEL_ILITEK_ILI9881C 198 207 tristate "Ilitek ILI9881C-based panels" 199 208 depends on OF ··· 743 734 help 744 735 Say Y here if you want to enable support for the Sitronix 745 736 ST7789V controller for 240x320 LCD panels 737 + 738 + config DRM_PANEL_SYNAPTICS_R63353 739 + tristate "Synaptics R63353-based panels" 740 + depends on OF 741 + depends on DRM_MIPI_DSI 742 + depends on BACKLIGHT_CLASS_DEVICE 743 + help 744 + Say Y if you want to enable support for panels based on the 745 + Synaptics R63353 controller. 746 746 747 747 config DRM_PANEL_SONY_ACX565AKM 748 748 tristate "Sony ACX565AKM panel"
+2
drivers/gpu/drm/panel/Makefile
··· 17 17 obj-$(CONFIG_DRM_PANEL_HIMAX_HX8394) += panel-himax-hx8394.o 18 18 obj-$(CONFIG_DRM_PANEL_ILITEK_IL9322) += panel-ilitek-ili9322.o 19 19 obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9341) += panel-ilitek-ili9341.o 20 + obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9805) += panel-ilitek-ili9805.o 20 21 obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9881C) += panel-ilitek-ili9881c.o 21 22 obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9882T) += panel-ilitek-ili9882t.o 22 23 obj-$(CONFIG_DRM_PANEL_INNOLUX_EJ030NA) += panel-innolux-ej030na.o ··· 75 74 obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7701) += panel-sitronix-st7701.o 76 75 obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7703) += panel-sitronix-st7703.o 77 76 obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7789V) += panel-sitronix-st7789v.o 77 + obj-$(CONFIG_DRM_PANEL_SYNAPTICS_R63353) += panel-synaptics-r63353.o 78 78 obj-$(CONFIG_DRM_PANEL_SONY_ACX565AKM) += panel-sony-acx565akm.o 79 79 obj-$(CONFIG_DRM_PANEL_SONY_TD4353_JDI) += panel-sony-td4353-jdi.o 80 80 obj-$(CONFIG_DRM_PANEL_SONY_TULIP_TRULY_NT35521) += panel-sony-tulip-truly-nt35521.o
+2 -1
drivers/gpu/drm/panel/panel-edp.c
··· 1980 1980 EDP_PANEL_ENTRY('I', 'V', 'O', 0x8c4d, &delay_200_150_e200, "R140NWFM R1"), 1981 1981 1982 1982 EDP_PANEL_ENTRY('K', 'D', 'B', 0x0624, &kingdisplay_kd116n21_30nv_a010.delay, "116N21-30NV-A010"), 1983 - EDP_PANEL_ENTRY('K', 'D', 'C', 0x0809, &delay_200_500_e50, "KD116N2930A15"), 1984 1983 EDP_PANEL_ENTRY('K', 'D', 'B', 0x1120, &delay_200_500_e80_d50, "116N29-30NK-C007"), 1984 + 1985 + EDP_PANEL_ENTRY('K', 'D', 'C', 0x0809, &delay_200_500_e50, "KD116N2930A15"), 1985 1986 1986 1987 EDP_PANEL_ENTRY('S', 'D', 'C', 0x416d, &delay_100_500_e200, "ATNA45AF01"), 1987 1988
+405
drivers/gpu/drm/panel/panel-ilitek-ili9805.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (C) 2020 BSH Hausgerate GmbH 4 + */ 5 + 6 + #include <linux/delay.h> 7 + #include <linux/device.h> 8 + #include <linux/err.h> 9 + #include <linux/errno.h> 10 + #include <linux/kernel.h> 11 + #include <linux/module.h> 12 + #include <linux/of.h> 13 + 14 + #include <linux/gpio/consumer.h> 15 + #include <linux/regulator/consumer.h> 16 + 17 + #include <drm/drm_mipi_dsi.h> 18 + #include <drm/drm_modes.h> 19 + #include <drm/drm_panel.h> 20 + 21 + #include <video/mipi_display.h> 22 + 23 + #define ILI9805_EXTCMD_CMD_SET_ENABLE_REG (0xff) 24 + #define ILI9805_SETEXTC_PARAMETER1 (0xff) 25 + #define ILI9805_SETEXTC_PARAMETER2 (0x98) 26 + #define ILI9805_SETEXTC_PARAMETER3 (0x05) 27 + 28 + #define ILI9805_INSTR(_delay, ...) { \ 29 + .delay = (_delay), \ 30 + .len = sizeof((u8[]) {__VA_ARGS__}), \ 31 + .data = (u8[]){__VA_ARGS__} \ 32 + } 33 + 34 + struct ili9805_instr { 35 + size_t len; 36 + const u8 *data; 37 + u32 delay; 38 + }; 39 + 40 + struct ili9805_desc { 41 + const char *name; 42 + const struct ili9805_instr *init; 43 + const size_t init_length; 44 + const struct drm_display_mode *mode; 45 + u32 width_mm; 46 + u32 height_mm; 47 + }; 48 + 49 + struct ili9805 { 50 + struct drm_panel panel; 51 + struct mipi_dsi_device *dsi; 52 + const struct ili9805_desc *desc; 53 + 54 + struct regulator *dvdd; 55 + struct regulator *avdd; 56 + struct gpio_desc *reset_gpio; 57 + }; 58 + 59 + static const struct ili9805_instr gpm1780a0_init[] = { 60 + ILI9805_INSTR(100, ILI9805_EXTCMD_CMD_SET_ENABLE_REG, ILI9805_SETEXTC_PARAMETER1, 61 + ILI9805_SETEXTC_PARAMETER2, ILI9805_SETEXTC_PARAMETER3), 62 + ILI9805_INSTR(100, 0xFD, 0x0F, 0x10, 0x44, 0x00), 63 + ILI9805_INSTR(0, 0xf8, 0x18, 0x02, 0x02, 0x18, 0x02, 0x02, 0x30, 0x00, 64 + 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00), 65 + ILI9805_INSTR(0, 0xB8, 0x62), 66 + ILI9805_INSTR(0, 0xF1, 0x00), 67 + ILI9805_INSTR(0, 0xF2, 0x00, 0x58, 0x40), 68 + ILI9805_INSTR(0, 0xF3, 0x60, 0x83, 0x04), 69 + ILI9805_INSTR(0, 0xFC, 0x04, 0x0F, 0x01), 70 + ILI9805_INSTR(0, 0xEB, 0x08, 0x0F), 71 + ILI9805_INSTR(0, 0xe0, 0x00, 0x08, 0x0d, 0x0e, 0x0e, 0x0d, 0x0a, 0x08, 0x04, 72 + 0x08, 0x0d, 0x0f, 0x0b, 0x1c, 0x14, 0x0a), 73 + ILI9805_INSTR(0, 0xe1, 0x00, 0x08, 0x0d, 0x0e, 0x0e, 0x0d, 0x0a, 0x08, 0x04, 74 + 0x08, 0x0d, 0x0f, 0x0b, 0x1c, 0x14, 0x0a), 75 + ILI9805_INSTR(10, 0xc1, 0x13, 0x39, 0x19, 0x06), 76 + ILI9805_INSTR(10, 0xc7, 0xe5), 77 + ILI9805_INSTR(10, 0xB1, 0x00, 0x12, 0x14), 78 + ILI9805_INSTR(10, 0xB4, 0x02), 79 + ILI9805_INSTR(0, 0xBB, 0x14, 0x55), 80 + ILI9805_INSTR(0, MIPI_DCS_SET_ADDRESS_MODE, 0x08), 81 + ILI9805_INSTR(0, MIPI_DCS_SET_PIXEL_FORMAT, 0x77), 82 + ILI9805_INSTR(0, 0x20), 83 + ILI9805_INSTR(0, 0xB0, 0x01), 84 + ILI9805_INSTR(0, 0xB6, 0x31, 0x00, 0xef), 85 + ILI9805_INSTR(0, 0xDF, 0x23), 86 + ILI9805_INSTR(0, 0xB9, 0x02, 0x00), 87 + }; 88 + 89 + static const struct ili9805_instr tm041xdhg01_init[] = { 90 + ILI9805_INSTR(100, ILI9805_EXTCMD_CMD_SET_ENABLE_REG, ILI9805_SETEXTC_PARAMETER1, 91 + ILI9805_SETEXTC_PARAMETER2, ILI9805_SETEXTC_PARAMETER3), 92 + ILI9805_INSTR(100, 0xFD, 0x0F, 0x13, 0x44, 0x00), 93 + ILI9805_INSTR(0, 0xf8, 0x18, 0x02, 0x02, 0x18, 0x02, 0x02, 0x30, 0x01, 94 + 0x01, 0x30, 0x01, 0x01, 0x30, 0x01, 0x01), 95 + ILI9805_INSTR(0, 0xB8, 0x74), 96 + ILI9805_INSTR(0, 0xF1, 0x00), 97 + ILI9805_INSTR(0, 0xF2, 0x00, 0x58, 0x40), 98 + ILI9805_INSTR(0, 0xFC, 0x04, 0x0F, 0x01), 99 + ILI9805_INSTR(0, 0xEB, 0x08, 0x0F), 100 + ILI9805_INSTR(0, 0xe0, 0x01, 0x0d, 0x15, 0x0e, 0x0f, 0x0f, 0x0b, 0x08, 0x04, 101 + 0x07, 0x0a, 0x0d, 0x0c, 0x15, 0x0f, 0x08), 102 + ILI9805_INSTR(0, 0xe1, 0x01, 0x0d, 0x15, 0x0e, 0x0f, 0x0f, 0x0b, 0x08, 0x04, 103 + 0x07, 0x0a, 0x0d, 0x0c, 0x15, 0x0f, 0x08), 104 + ILI9805_INSTR(10, 0xc1, 0x15, 0x03, 0x03, 0x31), 105 + ILI9805_INSTR(10, 0xB1, 0x00, 0x12, 0x14), 106 + ILI9805_INSTR(10, 0xB4, 0x02), 107 + ILI9805_INSTR(0, 0xBB, 0x14, 0x55), 108 + ILI9805_INSTR(0, MIPI_DCS_SET_ADDRESS_MODE, 0x0a), 109 + ILI9805_INSTR(0, MIPI_DCS_SET_PIXEL_FORMAT, 0x77), 110 + ILI9805_INSTR(0, 0x20), 111 + ILI9805_INSTR(0, 0xB0, 0x00), 112 + ILI9805_INSTR(0, 0xB6, 0x01), 113 + ILI9805_INSTR(0, 0xc2, 0x11), 114 + ILI9805_INSTR(0, 0x51, 0xFF), 115 + ILI9805_INSTR(0, 0x53, 0x24), 116 + ILI9805_INSTR(0, 0x55, 0x00), 117 + }; 118 + 119 + static inline struct ili9805 *panel_to_ili9805(struct drm_panel *panel) 120 + { 121 + return container_of(panel, struct ili9805, panel); 122 + } 123 + 124 + static int ili9805_power_on(struct ili9805 *ctx) 125 + { 126 + struct mipi_dsi_device *dsi = ctx->dsi; 127 + struct device *dev = &dsi->dev; 128 + int ret; 129 + 130 + ret = regulator_enable(ctx->avdd); 131 + if (ret) { 132 + dev_err(dev, "Failed to enable avdd regulator (%d)\n", ret); 133 + return ret; 134 + } 135 + 136 + ret = regulator_enable(ctx->dvdd); 137 + if (ret) { 138 + dev_err(dev, "Failed to enable dvdd regulator (%d)\n", ret); 139 + regulator_disable(ctx->avdd); 140 + return ret; 141 + } 142 + 143 + gpiod_set_value(ctx->reset_gpio, 0); 144 + usleep_range(5000, 10000); 145 + gpiod_set_value(ctx->reset_gpio, 1); 146 + msleep(120); 147 + 148 + return 0; 149 + } 150 + 151 + static int ili9805_power_off(struct ili9805 *ctx) 152 + { 153 + gpiod_set_value(ctx->reset_gpio, 0); 154 + regulator_disable(ctx->dvdd); 155 + regulator_disable(ctx->avdd); 156 + 157 + return 0; 158 + } 159 + 160 + static int ili9805_activate(struct ili9805 *ctx) 161 + { 162 + struct mipi_dsi_device *dsi = ctx->dsi; 163 + struct device *dev = &dsi->dev; 164 + int i, ret; 165 + 166 + for (i = 0; i < ctx->desc->init_length; i++) { 167 + const struct ili9805_instr *instr = &ctx->desc->init[i]; 168 + 169 + ret = mipi_dsi_dcs_write_buffer(ctx->dsi, instr->data, instr->len); 170 + if (ret < 0) 171 + return ret; 172 + 173 + if (instr->delay > 0) 174 + msleep(instr->delay); 175 + } 176 + 177 + ret = mipi_dsi_dcs_exit_sleep_mode(ctx->dsi); 178 + if (ret) { 179 + dev_err(dev, "Failed to exit sleep mode (%d)\n", ret); 180 + return ret; 181 + } 182 + 183 + usleep_range(5000, 6000); 184 + 185 + ret = mipi_dsi_dcs_set_display_on(ctx->dsi); 186 + if (ret) { 187 + dev_err(dev, "Failed to set display ON (%d)\n", ret); 188 + return ret; 189 + } 190 + 191 + return 0; 192 + } 193 + 194 + static int ili9805_prepare(struct drm_panel *panel) 195 + { 196 + struct ili9805 *ctx = panel_to_ili9805(panel); 197 + int ret; 198 + 199 + ret = ili9805_power_on(ctx); 200 + if (ret) 201 + return ret; 202 + 203 + ret = ili9805_activate(ctx); 204 + if (ret) { 205 + ili9805_power_off(ctx); 206 + return ret; 207 + } 208 + 209 + return 0; 210 + } 211 + 212 + static int ili9805_deactivate(struct ili9805 *ctx) 213 + { 214 + struct mipi_dsi_device *dsi = ctx->dsi; 215 + struct device *dev = &dsi->dev; 216 + int ret; 217 + 218 + ret = mipi_dsi_dcs_set_display_off(ctx->dsi); 219 + if (ret < 0) { 220 + dev_err(dev, "Failed to set display OFF (%d)\n", ret); 221 + return ret; 222 + } 223 + 224 + usleep_range(5000, 10000); 225 + 226 + ret = mipi_dsi_dcs_enter_sleep_mode(ctx->dsi); 227 + if (ret < 0) { 228 + dev_err(dev, "Failed to enter sleep mode (%d)\n", ret); 229 + return ret; 230 + } 231 + 232 + return 0; 233 + } 234 + 235 + static int ili9805_unprepare(struct drm_panel *panel) 236 + { 237 + struct ili9805 *ctx = panel_to_ili9805(panel); 238 + 239 + ili9805_deactivate(ctx); 240 + ili9805_power_off(ctx); 241 + 242 + return 0; 243 + } 244 + 245 + static const struct drm_display_mode gpm1780a0_timing = { 246 + .clock = 26227, 247 + 248 + .hdisplay = 480, 249 + .hsync_start = 480 + 10, 250 + .hsync_end = 480 + 10 + 2, 251 + .htotal = 480 + 10 + 2 + 36, 252 + 253 + .vdisplay = 480, 254 + .vsync_start = 480 + 2, 255 + .vsync_end = 480 + 10 + 4, 256 + .vtotal = 480 + 2 + 4 + 10, 257 + }; 258 + 259 + static const struct drm_display_mode tm041xdhg01_timing = { 260 + .clock = 26227, 261 + 262 + .hdisplay = 480, 263 + .hsync_start = 480 + 10, 264 + .hsync_end = 480 + 10 + 2, 265 + .htotal = 480 + 10 + 2 + 36, 266 + 267 + .vdisplay = 768, 268 + .vsync_start = 768 + 2, 269 + .vsync_end = 768 + 10 + 4, 270 + .vtotal = 768 + 2 + 4 + 10, 271 + }; 272 + 273 + static int ili9805_get_modes(struct drm_panel *panel, 274 + struct drm_connector *connector) 275 + { 276 + struct ili9805 *ctx = panel_to_ili9805(panel); 277 + struct drm_display_mode *mode; 278 + 279 + mode = drm_mode_duplicate(connector->dev, ctx->desc->mode); 280 + if (!mode) { 281 + dev_err(&ctx->dsi->dev, "failed to add mode %ux%ux@%u\n", 282 + ctx->desc->mode->hdisplay, 283 + ctx->desc->mode->vdisplay, 284 + drm_mode_vrefresh(ctx->desc->mode)); 285 + return -ENOMEM; 286 + } 287 + 288 + drm_mode_set_name(mode); 289 + 290 + mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; 291 + drm_mode_probed_add(connector, mode); 292 + 293 + connector->display_info.width_mm = mode->width_mm; 294 + connector->display_info.height_mm = mode->height_mm; 295 + 296 + return 1; 297 + } 298 + 299 + static const struct drm_panel_funcs ili9805_funcs = { 300 + .prepare = ili9805_prepare, 301 + .unprepare = ili9805_unprepare, 302 + .get_modes = ili9805_get_modes, 303 + }; 304 + 305 + static int ili9805_dsi_probe(struct mipi_dsi_device *dsi) 306 + { 307 + struct ili9805 *ctx; 308 + int ret; 309 + 310 + ctx = devm_kzalloc(&dsi->dev, sizeof(*ctx), GFP_KERNEL); 311 + if (!ctx) 312 + return -ENOMEM; 313 + mipi_dsi_set_drvdata(dsi, ctx); 314 + ctx->dsi = dsi; 315 + ctx->desc = of_device_get_match_data(&dsi->dev); 316 + 317 + dsi->format = MIPI_DSI_FMT_RGB888; 318 + dsi->mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO | 319 + MIPI_DSI_CLOCK_NON_CONTINUOUS | MIPI_DSI_MODE_LPM | 320 + MIPI_DSI_MODE_VIDEO_SYNC_PULSE | MIPI_DSI_MODE_NO_EOT_PACKET; 321 + dsi->lanes = 2; 322 + 323 + drm_panel_init(&ctx->panel, &dsi->dev, &ili9805_funcs, 324 + DRM_MODE_CONNECTOR_DSI); 325 + 326 + ctx->dvdd = devm_regulator_get(&dsi->dev, "dvdd"); 327 + if (IS_ERR(ctx->dvdd)) 328 + return PTR_ERR(ctx->dvdd); 329 + ctx->avdd = devm_regulator_get(&dsi->dev, "avdd"); 330 + if (IS_ERR(ctx->avdd)) 331 + return PTR_ERR(ctx->avdd); 332 + 333 + ctx->reset_gpio = devm_gpiod_get(&dsi->dev, "reset", GPIOD_OUT_LOW); 334 + if (IS_ERR(ctx->reset_gpio)) { 335 + dev_err(&dsi->dev, "Couldn't get our reset GPIO\n"); 336 + return PTR_ERR(ctx->reset_gpio); 337 + } 338 + 339 + ctx->panel.prepare_prev_first = true; 340 + ret = drm_panel_of_backlight(&ctx->panel); 341 + if (ret) 342 + return ret; 343 + 344 + drm_panel_add(&ctx->panel); 345 + 346 + ret = mipi_dsi_attach(dsi); 347 + if (ret < 0) { 348 + dev_err(&dsi->dev, "mipi_dsi_attach failed: %d\n", ret); 349 + drm_panel_remove(&ctx->panel); 350 + return ret; 351 + } 352 + 353 + return 0; 354 + } 355 + 356 + static void ili9805_dsi_remove(struct mipi_dsi_device *dsi) 357 + { 358 + struct ili9805 *ctx = mipi_dsi_get_drvdata(dsi); 359 + int ret; 360 + 361 + ret = mipi_dsi_detach(dsi); 362 + if (ret < 0) 363 + dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", 364 + ret); 365 + 366 + drm_panel_remove(&ctx->panel); 367 + } 368 + 369 + static const struct ili9805_desc gpm1780a0_desc = { 370 + .init = gpm1780a0_init, 371 + .init_length = ARRAY_SIZE(gpm1780a0_init), 372 + .mode = &gpm1780a0_timing, 373 + .width_mm = 65, 374 + .height_mm = 65, 375 + }; 376 + 377 + static const struct ili9805_desc tm041xdhg01_desc = { 378 + .init = tm041xdhg01_init, 379 + .init_length = ARRAY_SIZE(tm041xdhg01_init), 380 + .mode = &tm041xdhg01_timing, 381 + .width_mm = 42, 382 + .height_mm = 96, 383 + }; 384 + 385 + static const struct of_device_id ili9805_of_match[] = { 386 + { .compatible = "giantplus,gpm1790a0", .data = &gpm1780a0_desc }, 387 + { .compatible = "tianma,tm041xdhg01", .data = &tm041xdhg01_desc }, 388 + { } 389 + }; 390 + MODULE_DEVICE_TABLE(of, ili9805_of_match); 391 + 392 + static struct mipi_dsi_driver ili9805_dsi_driver = { 393 + .probe = ili9805_dsi_probe, 394 + .remove = ili9805_dsi_remove, 395 + .driver = { 396 + .name = "ili9805-dsi", 397 + .of_match_table = ili9805_of_match, 398 + }, 399 + }; 400 + module_mipi_dsi_driver(ili9805_dsi_driver); 401 + 402 + MODULE_AUTHOR("Matthias Proske <Matthias.Proske@bshg.com>"); 403 + MODULE_AUTHOR("Michael Trimarchi <michael@amarulasolutions.com>"); 404 + MODULE_DESCRIPTION("Ilitek ILI9805 Controller Driver"); 405 + MODULE_LICENSE("GPL");
+377 -138
drivers/gpu/drm/panel/panel-newvision-nv3052c.c
··· 20 20 #include <drm/drm_modes.h> 21 21 #include <drm/drm_panel.h> 22 22 23 + struct nv3052c_reg { 24 + u8 cmd; 25 + u8 val; 26 + }; 27 + 23 28 struct nv3052c_panel_info { 24 29 const struct drm_display_mode *display_modes; 25 30 unsigned int num_modes; 26 31 u16 width_mm, height_mm; 27 32 u32 bus_format, bus_flags; 33 + const struct nv3052c_reg *panel_regs; 34 + unsigned int panel_regs_len; 28 35 }; 29 36 30 37 struct nv3052c { ··· 43 36 struct gpio_desc *reset_gpio; 44 37 }; 45 38 46 - struct nv3052c_reg { 47 - u8 cmd; 48 - u8 val; 49 - }; 50 - 51 - static const struct nv3052c_reg nv3052c_panel_regs[] = { 52 - { 0xff, 0x30 }, 53 - { 0xff, 0x52 }, 54 - { 0xff, 0x01 }, 39 + static const struct nv3052c_reg ltk035c5444t_panel_regs[] = { 40 + // EXTC Command set enable, select page 1 41 + { 0xff, 0x30 }, { 0xff, 0x52 }, { 0xff, 0x01 }, 42 + // Mostly unknown registers 55 43 { 0xe3, 0x00 }, 56 44 { 0x40, 0x00 }, 57 45 { 0x03, 0x40 }, ··· 64 62 { 0x25, 0x06 }, 65 63 { 0x26, 0x14 }, 66 64 { 0x27, 0x14 }, 67 - { 0x38, 0xcc }, 68 - { 0x39, 0xd7 }, 69 - { 0x3a, 0x4a }, 65 + { 0x38, 0xcc }, // VCOM_ADJ1 66 + { 0x39, 0xd7 }, // VCOM_ADJ2 67 + { 0x3a, 0x4a }, // VCOM_ADJ3 70 68 { 0x28, 0x40 }, 71 69 { 0x29, 0x01 }, 72 70 { 0x2a, 0xdf }, 73 71 { 0x49, 0x3c }, 74 - { 0x91, 0x77 }, 75 - { 0x92, 0x77 }, 72 + { 0x91, 0x77 }, // EXTPW_CTRL2 73 + { 0x92, 0x77 }, // EXTPW_CTRL3 76 74 { 0xa0, 0x55 }, 77 75 { 0xa1, 0x50 }, 78 76 { 0xa4, 0x9c }, ··· 96 94 { 0xb8, 0x26 }, 97 95 { 0xf0, 0x00 }, 98 96 { 0xf6, 0xc0 }, 99 - { 0xff, 0x30 }, 100 - { 0xff, 0x52 }, 101 - { 0xff, 0x02 }, 102 - { 0xb0, 0x0b }, 103 - { 0xb1, 0x16 }, 104 - { 0xb2, 0x17 }, 105 - { 0xb3, 0x2c }, 106 - { 0xb4, 0x32 }, 107 - { 0xb5, 0x3b }, 108 - { 0xb6, 0x29 }, 109 - { 0xb7, 0x40 }, 110 - { 0xb8, 0x0d }, 111 - { 0xb9, 0x05 }, 112 - { 0xba, 0x12 }, 113 - { 0xbb, 0x10 }, 114 - { 0xbc, 0x12 }, 115 - { 0xbd, 0x15 }, 116 - { 0xbe, 0x19 }, 117 - { 0xbf, 0x0e }, 118 - { 0xc0, 0x16 }, 119 - { 0xc1, 0x0a }, 120 - { 0xd0, 0x0c }, 121 - { 0xd1, 0x17 }, 122 - { 0xd2, 0x14 }, 123 - { 0xd3, 0x2e }, 124 - { 0xd4, 0x32 }, 125 - { 0xd5, 0x3c }, 126 - { 0xd6, 0x22 }, 127 - { 0xd7, 0x3d }, 128 - { 0xd8, 0x0d }, 129 - { 0xd9, 0x07 }, 130 - { 0xda, 0x13 }, 131 - { 0xdb, 0x13 }, 132 - { 0xdc, 0x11 }, 133 - { 0xdd, 0x15 }, 134 - { 0xde, 0x19 }, 135 - { 0xdf, 0x10 }, 136 - { 0xe0, 0x17 }, 137 - { 0xe1, 0x0a }, 138 - { 0xff, 0x30 }, 139 - { 0xff, 0x52 }, 140 - { 0xff, 0x03 }, 141 - { 0x00, 0x2a }, 142 - { 0x01, 0x2a }, 143 - { 0x02, 0x2a }, 144 - { 0x03, 0x2a }, 145 - { 0x04, 0x61 }, 146 - { 0x05, 0x80 }, 147 - { 0x06, 0xc7 }, 148 - { 0x07, 0x01 }, 149 - { 0x08, 0x03 }, 150 - { 0x09, 0x04 }, 151 - { 0x70, 0x22 }, 152 - { 0x71, 0x80 }, 153 - { 0x30, 0x2a }, 154 - { 0x31, 0x2a }, 155 - { 0x32, 0x2a }, 156 - { 0x33, 0x2a }, 157 - { 0x34, 0x61 }, 158 - { 0x35, 0xc5 }, 159 - { 0x36, 0x80 }, 160 - { 0x37, 0x23 }, 161 - { 0x40, 0x03 }, 162 - { 0x41, 0x04 }, 163 - { 0x42, 0x05 }, 164 - { 0x43, 0x06 }, 165 - { 0x44, 0x11 }, 166 - { 0x45, 0xe8 }, 167 - { 0x46, 0xe9 }, 168 - { 0x47, 0x11 }, 169 - { 0x48, 0xea }, 170 - { 0x49, 0xeb }, 171 - { 0x50, 0x07 }, 172 - { 0x51, 0x08 }, 173 - { 0x52, 0x09 }, 174 - { 0x53, 0x0a }, 175 - { 0x54, 0x11 }, 176 - { 0x55, 0xec }, 177 - { 0x56, 0xed }, 178 - { 0x57, 0x11 }, 179 - { 0x58, 0xef }, 180 - { 0x59, 0xf0 }, 181 - { 0xb1, 0x01 }, 182 - { 0xb4, 0x15 }, 183 - { 0xb5, 0x16 }, 184 - { 0xb6, 0x09 }, 185 - { 0xb7, 0x0f }, 186 - { 0xb8, 0x0d }, 187 - { 0xb9, 0x0b }, 188 - { 0xba, 0x00 }, 189 - { 0xc7, 0x02 }, 190 - { 0xca, 0x17 }, 191 - { 0xcb, 0x18 }, 192 - { 0xcc, 0x0a }, 193 - { 0xcd, 0x10 }, 194 - { 0xce, 0x0e }, 195 - { 0xcf, 0x0c }, 196 - { 0xd0, 0x00 }, 197 - { 0x81, 0x00 }, 198 - { 0x84, 0x15 }, 199 - { 0x85, 0x16 }, 200 - { 0x86, 0x10 }, 201 - { 0x87, 0x0a }, 202 - { 0x88, 0x0c }, 203 - { 0x89, 0x0e }, 204 - { 0x8a, 0x02 }, 205 - { 0x97, 0x00 }, 206 - { 0x9a, 0x17 }, 207 - { 0x9b, 0x18 }, 208 - { 0x9c, 0x0f }, 209 - { 0x9d, 0x09 }, 210 - { 0x9e, 0x0b }, 211 - { 0x9f, 0x0d }, 212 - { 0xa0, 0x01 }, 213 - { 0xff, 0x30 }, 214 - { 0xff, 0x52 }, 215 - { 0xff, 0x02 }, 97 + // EXTC Command set enable, select page 2 98 + { 0xff, 0x30 }, { 0xff, 0x52 }, { 0xff, 0x02 }, 99 + // Set gray scale voltage to adjust gamma 100 + { 0xb0, 0x0b }, // PGAMVR0 101 + { 0xb1, 0x16 }, // PGAMVR1 102 + { 0xb2, 0x17 }, // PGAMVR2 103 + { 0xb3, 0x2c }, // PGAMVR3 104 + { 0xb4, 0x32 }, // PGAMVR4 105 + { 0xb5, 0x3b }, // PGAMVR5 106 + { 0xb6, 0x29 }, // PGAMPR0 107 + { 0xb7, 0x40 }, // PGAMPR1 108 + { 0xb8, 0x0d }, // PGAMPK0 109 + { 0xb9, 0x05 }, // PGAMPK1 110 + { 0xba, 0x12 }, // PGAMPK2 111 + { 0xbb, 0x10 }, // PGAMPK3 112 + { 0xbc, 0x12 }, // PGAMPK4 113 + { 0xbd, 0x15 }, // PGAMPK5 114 + { 0xbe, 0x19 }, // PGAMPK6 115 + { 0xbf, 0x0e }, // PGAMPK7 116 + { 0xc0, 0x16 }, // PGAMPK8 117 + { 0xc1, 0x0a }, // PGAMPK9 118 + // Set gray scale voltage to adjust gamma 119 + { 0xd0, 0x0c }, // NGAMVR0 120 + { 0xd1, 0x17 }, // NGAMVR0 121 + { 0xd2, 0x14 }, // NGAMVR1 122 + { 0xd3, 0x2e }, // NGAMVR2 123 + { 0xd4, 0x32 }, // NGAMVR3 124 + { 0xd5, 0x3c }, // NGAMVR4 125 + { 0xd6, 0x22 }, // NGAMPR0 126 + { 0xd7, 0x3d }, // NGAMPR1 127 + { 0xd8, 0x0d }, // NGAMPK0 128 + { 0xd9, 0x07 }, // NGAMPK1 129 + { 0xda, 0x13 }, // NGAMPK2 130 + { 0xdb, 0x13 }, // NGAMPK3 131 + { 0xdc, 0x11 }, // NGAMPK4 132 + { 0xdd, 0x15 }, // NGAMPK5 133 + { 0xde, 0x19 }, // NGAMPK6 134 + { 0xdf, 0x10 }, // NGAMPK7 135 + { 0xe0, 0x17 }, // NGAMPK8 136 + { 0xe1, 0x0a }, // NGAMPK9 137 + // EXTC Command set enable, select page 3 138 + { 0xff, 0x30 }, { 0xff, 0x52 }, { 0xff, 0x03 }, 139 + // Set various timing settings 140 + { 0x00, 0x2a }, // GIP_VST_1 141 + { 0x01, 0x2a }, // GIP_VST_2 142 + { 0x02, 0x2a }, // GIP_VST_3 143 + { 0x03, 0x2a }, // GIP_VST_4 144 + { 0x04, 0x61 }, // GIP_VST_5 145 + { 0x05, 0x80 }, // GIP_VST_6 146 + { 0x06, 0xc7 }, // GIP_VST_7 147 + { 0x07, 0x01 }, // GIP_VST_8 148 + { 0x08, 0x03 }, // GIP_VST_9 149 + { 0x09, 0x04 }, // GIP_VST_10 150 + { 0x70, 0x22 }, // GIP_ECLK1 151 + { 0x71, 0x80 }, // GIP_ECLK2 152 + { 0x30, 0x2a }, // GIP_CLK_1 153 + { 0x31, 0x2a }, // GIP_CLK_2 154 + { 0x32, 0x2a }, // GIP_CLK_3 155 + { 0x33, 0x2a }, // GIP_CLK_4 156 + { 0x34, 0x61 }, // GIP_CLK_5 157 + { 0x35, 0xc5 }, // GIP_CLK_6 158 + { 0x36, 0x80 }, // GIP_CLK_7 159 + { 0x37, 0x23 }, // GIP_CLK_8 160 + { 0x40, 0x03 }, // GIP_CLKA_1 161 + { 0x41, 0x04 }, // GIP_CLKA_2 162 + { 0x42, 0x05 }, // GIP_CLKA_3 163 + { 0x43, 0x06 }, // GIP_CLKA_4 164 + { 0x44, 0x11 }, // GIP_CLKA_5 165 + { 0x45, 0xe8 }, // GIP_CLKA_6 166 + { 0x46, 0xe9 }, // GIP_CLKA_7 167 + { 0x47, 0x11 }, // GIP_CLKA_8 168 + { 0x48, 0xea }, // GIP_CLKA_9 169 + { 0x49, 0xeb }, // GIP_CLKA_10 170 + { 0x50, 0x07 }, // GIP_CLKB_1 171 + { 0x51, 0x08 }, // GIP_CLKB_2 172 + { 0x52, 0x09 }, // GIP_CLKB_3 173 + { 0x53, 0x0a }, // GIP_CLKB_4 174 + { 0x54, 0x11 }, // GIP_CLKB_5 175 + { 0x55, 0xec }, // GIP_CLKB_6 176 + { 0x56, 0xed }, // GIP_CLKB_7 177 + { 0x57, 0x11 }, // GIP_CLKB_8 178 + { 0x58, 0xef }, // GIP_CLKB_9 179 + { 0x59, 0xf0 }, // GIP_CLKB_10 180 + // Map internal GOA signals to GOA output pad 181 + { 0xb1, 0x01 }, // PANELD2U2 182 + { 0xb4, 0x15 }, // PANELD2U5 183 + { 0xb5, 0x16 }, // PANELD2U6 184 + { 0xb6, 0x09 }, // PANELD2U7 185 + { 0xb7, 0x0f }, // PANELD2U8 186 + { 0xb8, 0x0d }, // PANELD2U9 187 + { 0xb9, 0x0b }, // PANELD2U10 188 + { 0xba, 0x00 }, // PANELD2U11 189 + { 0xc7, 0x02 }, // PANELD2U24 190 + { 0xca, 0x17 }, // PANELD2U27 191 + { 0xcb, 0x18 }, // PANELD2U28 192 + { 0xcc, 0x0a }, // PANELD2U29 193 + { 0xcd, 0x10 }, // PANELD2U30 194 + { 0xce, 0x0e }, // PANELD2U31 195 + { 0xcf, 0x0c }, // PANELD2U32 196 + { 0xd0, 0x00 }, // PANELD2U33 197 + // Map internal GOA signals to GOA output pad 198 + { 0x81, 0x00 }, // PANELU2D2 199 + { 0x84, 0x15 }, // PANELU2D5 200 + { 0x85, 0x16 }, // PANELU2D6 201 + { 0x86, 0x10 }, // PANELU2D7 202 + { 0x87, 0x0a }, // PANELU2D8 203 + { 0x88, 0x0c }, // PANELU2D9 204 + { 0x89, 0x0e }, // PANELU2D10 205 + { 0x8a, 0x02 }, // PANELU2D11 206 + { 0x97, 0x00 }, // PANELU2D24 207 + { 0x9a, 0x17 }, // PANELU2D27 208 + { 0x9b, 0x18 }, // PANELU2D28 209 + { 0x9c, 0x0f }, // PANELU2D29 210 + { 0x9d, 0x09 }, // PANELU2D30 211 + { 0x9e, 0x0b }, // PANELU2D31 212 + { 0x9f, 0x0d }, // PANELU2D32 213 + { 0xa0, 0x01 }, // PANELU2D33 214 + // EXTC Command set enable, select page 2 215 + { 0xff, 0x30 }, { 0xff, 0x52 }, { 0xff, 0x02 }, 216 + // Unknown registers 216 217 { 0x01, 0x01 }, 217 218 { 0x02, 0xda }, 218 219 { 0x03, 0xba }, ··· 232 227 { 0x0e, 0x48 }, 233 228 { 0x0f, 0x38 }, 234 229 { 0x10, 0x2b }, 235 - { 0xff, 0x30 }, 236 - { 0xff, 0x52 }, 237 - { 0xff, 0x00 }, 238 - { 0x36, 0x0a }, 230 + // EXTC Command set enable, select page 0 231 + { 0xff, 0x30 }, { 0xff, 0x52 }, { 0xff, 0x00 }, 232 + // Display Access Control 233 + { 0x36, 0x0a }, // bgr = 1, ss = 1, gs = 0 234 + }; 235 + 236 + static const struct nv3052c_reg fs035vg158_panel_regs[] = { 237 + // EXTC Command set enable, select page 1 238 + { 0xff, 0x30 }, { 0xff, 0x52 }, { 0xff, 0x01 }, 239 + // Mostly unknown registers 240 + { 0xe3, 0x00 }, 241 + { 0x40, 0x00 }, 242 + { 0x03, 0x40 }, 243 + { 0x04, 0x00 }, 244 + { 0x05, 0x03 }, 245 + { 0x08, 0x00 }, 246 + { 0x09, 0x07 }, 247 + { 0x0a, 0x01 }, 248 + { 0x0b, 0x32 }, 249 + { 0x0c, 0x32 }, 250 + { 0x0d, 0x0b }, 251 + { 0x0e, 0x00 }, 252 + { 0x23, 0x20 }, // RGB interface control: DE MODE PCLK-N 253 + { 0x24, 0x0c }, 254 + { 0x25, 0x06 }, 255 + { 0x26, 0x14 }, 256 + { 0x27, 0x14 }, 257 + { 0x38, 0x9c }, //VCOM_ADJ1, different to ltk035c5444t 258 + { 0x39, 0xa7 }, //VCOM_ADJ2, different to ltk035c5444t 259 + { 0x3a, 0x50 }, //VCOM_ADJ3, different to ltk035c5444t 260 + { 0x28, 0x40 }, 261 + { 0x29, 0x01 }, 262 + { 0x2a, 0xdf }, 263 + { 0x49, 0x3c }, 264 + { 0x91, 0x57 }, //EXTPW_CTRL2, different to ltk035c5444t 265 + { 0x92, 0x57 }, //EXTPW_CTRL3, different to ltk035c5444t 266 + { 0xa0, 0x55 }, 267 + { 0xa1, 0x50 }, 268 + { 0xa4, 0x9c }, 269 + { 0xa7, 0x02 }, 270 + { 0xa8, 0x01 }, 271 + { 0xa9, 0x01 }, 272 + { 0xaa, 0xfc }, 273 + { 0xab, 0x28 }, 274 + { 0xac, 0x06 }, 275 + { 0xad, 0x06 }, 276 + { 0xae, 0x06 }, 277 + { 0xaf, 0x03 }, 278 + { 0xb0, 0x08 }, 279 + { 0xb1, 0x26 }, 280 + { 0xb2, 0x28 }, 281 + { 0xb3, 0x28 }, 282 + { 0xb4, 0x03 }, // Unknown, different to ltk035c5444 283 + { 0xb5, 0x08 }, 284 + { 0xb6, 0x26 }, 285 + { 0xb7, 0x08 }, 286 + { 0xb8, 0x26 }, 287 + { 0xf0, 0x00 }, 288 + { 0xf6, 0xc0 }, 289 + // EXTC Command set enable, select page 0 290 + { 0xff, 0x30 }, { 0xff, 0x52 }, { 0xff, 0x02 }, 291 + // Set gray scale voltage to adjust gamma 292 + { 0xb0, 0x0b }, // PGAMVR0 293 + { 0xb1, 0x16 }, // PGAMVR1 294 + { 0xb2, 0x17 }, // PGAMVR2 295 + { 0xb3, 0x2c }, // PGAMVR3 296 + { 0xb4, 0x32 }, // PGAMVR4 297 + { 0xb5, 0x3b }, // PGAMVR5 298 + { 0xb6, 0x29 }, // PGAMPR0 299 + { 0xb7, 0x40 }, // PGAMPR1 300 + { 0xb8, 0x0d }, // PGAMPK0 301 + { 0xb9, 0x05 }, // PGAMPK1 302 + { 0xba, 0x12 }, // PGAMPK2 303 + { 0xbb, 0x10 }, // PGAMPK3 304 + { 0xbc, 0x12 }, // PGAMPK4 305 + { 0xbd, 0x15 }, // PGAMPK5 306 + { 0xbe, 0x19 }, // PGAMPK6 307 + { 0xbf, 0x0e }, // PGAMPK7 308 + { 0xc0, 0x16 }, // PGAMPK8 309 + { 0xc1, 0x0a }, // PGAMPK9 310 + // Set gray scale voltage to adjust gamma 311 + { 0xd0, 0x0c }, // NGAMVR0 312 + { 0xd1, 0x17 }, // NGAMVR0 313 + { 0xd2, 0x14 }, // NGAMVR1 314 + { 0xd3, 0x2e }, // NGAMVR2 315 + { 0xd4, 0x32 }, // NGAMVR3 316 + { 0xd5, 0x3c }, // NGAMVR4 317 + { 0xd6, 0x22 }, // NGAMPR0 318 + { 0xd7, 0x3d }, // NGAMPR1 319 + { 0xd8, 0x0d }, // NGAMPK0 320 + { 0xd9, 0x07 }, // NGAMPK1 321 + { 0xda, 0x13 }, // NGAMPK2 322 + { 0xdb, 0x13 }, // NGAMPK3 323 + { 0xdc, 0x11 }, // NGAMPK4 324 + { 0xdd, 0x15 }, // NGAMPK5 325 + { 0xde, 0x19 }, // NGAMPK6 326 + { 0xdf, 0x10 }, // NGAMPK7 327 + { 0xe0, 0x17 }, // NGAMPK8 328 + { 0xe1, 0x0a }, // NGAMPK9 329 + // EXTC Command set enable, select page 3 330 + { 0xff, 0x30 }, { 0xff, 0x52 }, { 0xff, 0x03 }, 331 + // Set various timing settings 332 + { 0x00, 0x2a }, // GIP_VST_1 333 + { 0x01, 0x2a }, // GIP_VST_2 334 + { 0x02, 0x2a }, // GIP_VST_3 335 + { 0x03, 0x2a }, // GIP_VST_4 336 + { 0x04, 0x61 }, // GIP_VST_5 337 + { 0x05, 0x80 }, // GIP_VST_6 338 + { 0x06, 0xc7 }, // GIP_VST_7 339 + { 0x07, 0x01 }, // GIP_VST_8 340 + { 0x08, 0x03 }, // GIP_VST_9 341 + { 0x09, 0x04 }, // GIP_VST_10 342 + { 0x70, 0x22 }, // GIP_ECLK1 343 + { 0x71, 0x80 }, // GIP_ECLK2 344 + { 0x30, 0x2a }, // GIP_CLK_1 345 + { 0x31, 0x2a }, // GIP_CLK_2 346 + { 0x32, 0x2a }, // GIP_CLK_3 347 + { 0x33, 0x2a }, // GIP_CLK_4 348 + { 0x34, 0x61 }, // GIP_CLK_5 349 + { 0x35, 0xc5 }, // GIP_CLK_6 350 + { 0x36, 0x80 }, // GIP_CLK_7 351 + { 0x37, 0x23 }, // GIP_CLK_8 352 + { 0x40, 0x03 }, // GIP_CLKA_1 353 + { 0x41, 0x04 }, // GIP_CLKA_2 354 + { 0x42, 0x05 }, // GIP_CLKA_3 355 + { 0x43, 0x06 }, // GIP_CLKA_4 356 + { 0x44, 0x11 }, // GIP_CLKA_5 357 + { 0x45, 0xe8 }, // GIP_CLKA_6 358 + { 0x46, 0xe9 }, // GIP_CLKA_7 359 + { 0x47, 0x11 }, // GIP_CLKA_8 360 + { 0x48, 0xea }, // GIP_CLKA_9 361 + { 0x49, 0xeb }, // GIP_CLKA_10 362 + { 0x50, 0x07 }, // GIP_CLKB_1 363 + { 0x51, 0x08 }, // GIP_CLKB_2 364 + { 0x52, 0x09 }, // GIP_CLKB_3 365 + { 0x53, 0x0a }, // GIP_CLKB_4 366 + { 0x54, 0x11 }, // GIP_CLKB_5 367 + { 0x55, 0xec }, // GIP_CLKB_6 368 + { 0x56, 0xed }, // GIP_CLKB_7 369 + { 0x57, 0x11 }, // GIP_CLKB_8 370 + { 0x58, 0xef }, // GIP_CLKB_9 371 + { 0x59, 0xf0 }, // GIP_CLKB_10 372 + // Map internal GOA signals to GOA output pad 373 + { 0xb1, 0x01 }, // PANELD2U2 374 + { 0xb4, 0x15 }, // PANELD2U5 375 + { 0xb5, 0x16 }, // PANELD2U6 376 + { 0xb6, 0x09 }, // PANELD2U7 377 + { 0xb7, 0x0f }, // PANELD2U8 378 + { 0xb8, 0x0d }, // PANELD2U9 379 + { 0xb9, 0x0b }, // PANELD2U10 380 + { 0xba, 0x00 }, // PANELD2U11 381 + { 0xc7, 0x02 }, // PANELD2U24 382 + { 0xca, 0x17 }, // PANELD2U27 383 + { 0xcb, 0x18 }, // PANELD2U28 384 + { 0xcc, 0x0a }, // PANELD2U29 385 + { 0xcd, 0x10 }, // PANELD2U30 386 + { 0xce, 0x0e }, // PANELD2U31 387 + { 0xcf, 0x0c }, // PANELD2U32 388 + { 0xd0, 0x00 }, // PANELD2U33 389 + // Map internal GOA signals to GOA output pad 390 + { 0x81, 0x00 }, // PANELU2D2 391 + { 0x84, 0x15 }, // PANELU2D5 392 + { 0x85, 0x16 }, // PANELU2D6 393 + { 0x86, 0x10 }, // PANELU2D7 394 + { 0x87, 0x0a }, // PANELU2D8 395 + { 0x88, 0x0c }, // PANELU2D9 396 + { 0x89, 0x0e }, // PANELU2D10 397 + { 0x8a, 0x02 }, // PANELU2D11 398 + { 0x97, 0x00 }, // PANELU2D24 399 + { 0x9a, 0x17 }, // PANELU2D27 400 + { 0x9b, 0x18 }, // PANELU2D28 401 + { 0x9c, 0x0f }, // PANELU2D29 402 + { 0x9d, 0x09 }, // PANELU2D30 403 + { 0x9e, 0x0b }, // PANELU2D31 404 + { 0x9f, 0x0d }, // PANELU2D32 405 + { 0xa0, 0x01 }, // PANELU2D33 406 + // EXTC Command set enable, select page 2 407 + { 0xff, 0x30 }, { 0xff, 0x52 }, { 0xff, 0x02 }, 408 + // Unknown registers 409 + { 0x01, 0x01 }, 410 + { 0x02, 0xda }, 411 + { 0x03, 0xba }, 412 + { 0x04, 0xa8 }, 413 + { 0x05, 0x9a }, 414 + { 0x06, 0x70 }, 415 + { 0x07, 0xff }, 416 + { 0x08, 0x91 }, 417 + { 0x09, 0x90 }, 418 + { 0x0a, 0xff }, 419 + { 0x0b, 0x8f }, 420 + { 0x0c, 0x60 }, 421 + { 0x0d, 0x58 }, 422 + { 0x0e, 0x48 }, 423 + { 0x0f, 0x38 }, 424 + { 0x10, 0x2b }, 425 + // EXTC Command set enable, select page 0 426 + { 0xff, 0x30 }, { 0xff, 0x52 }, { 0xff, 0x00 }, 427 + // Display Access Control 428 + { 0x36, 0x0a }, // bgr = 1, ss = 1, gs = 0 239 429 }; 240 430 241 431 static inline struct nv3052c *to_nv3052c(struct drm_panel *panel) ··· 441 241 static int nv3052c_prepare(struct drm_panel *panel) 442 242 { 443 243 struct nv3052c *priv = to_nv3052c(panel); 244 + const struct nv3052c_reg *panel_regs = priv->panel_info->panel_regs; 245 + unsigned int panel_regs_len = priv->panel_info->panel_regs_len; 444 246 struct mipi_dbi *dbi = &priv->dbi; 445 247 unsigned int i; 446 248 int err; ··· 459 257 gpiod_set_value_cansleep(priv->reset_gpio, 0); 460 258 usleep_range(5000, 20000); 461 259 462 - for (i = 0; i < ARRAY_SIZE(nv3052c_panel_regs); i++) { 463 - err = mipi_dbi_command(dbi, nv3052c_panel_regs[i].cmd, 464 - nv3052c_panel_regs[i].val); 260 + for (i = 0; i < panel_regs_len; i++) { 261 + err = mipi_dbi_command(dbi, panel_regs[i].cmd, 262 + panel_regs[i].val); 465 263 466 264 if (err) { 467 265 dev_err(priv->dev, "Unable to set register: %d\n", err); ··· 655 453 }, 656 454 }; 657 455 456 + static const struct drm_display_mode fs035vg158_modes[] = { 457 + { /* 60 Hz */ 458 + .clock = 21000, 459 + .hdisplay = 640, 460 + .hsync_start = 640 + 34, 461 + .hsync_end = 640 + 34 + 4, 462 + .htotal = 640 + 34 + 4 + 20, 463 + .vdisplay = 480, 464 + .vsync_start = 480 + 12, 465 + .vsync_end = 480 + 12 + 4, 466 + .vtotal = 480 + 12 + 4 + 6, 467 + .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, 468 + }, 469 + }; 470 + 658 471 static const struct nv3052c_panel_info ltk035c5444t_panel_info = { 659 472 .display_modes = ltk035c5444t_modes, 660 473 .num_modes = ARRAY_SIZE(ltk035c5444t_modes), ··· 677 460 .height_mm = 64, 678 461 .bus_format = MEDIA_BUS_FMT_RGB888_1X24, 679 462 .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE, 463 + .panel_regs = ltk035c5444t_panel_regs, 464 + .panel_regs_len = ARRAY_SIZE(ltk035c5444t_panel_regs), 680 465 }; 466 + 467 + static const struct nv3052c_panel_info fs035vg158_panel_info = { 468 + .display_modes = fs035vg158_modes, 469 + .num_modes = ARRAY_SIZE(fs035vg158_modes), 470 + .width_mm = 70, 471 + .height_mm = 53, 472 + .bus_format = MEDIA_BUS_FMT_RGB888_1X24, 473 + .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE, 474 + .panel_regs = fs035vg158_panel_regs, 475 + .panel_regs_len = ARRAY_SIZE(fs035vg158_panel_regs), 476 + }; 477 + 478 + static const struct spi_device_id nv3052c_ids[] = { 479 + { "ltk035c5444t", }, 480 + { "fs035vg158", }, 481 + { /* sentinel */ } 482 + }; 483 + MODULE_DEVICE_TABLE(spi, nv3052c_ids); 681 484 682 485 static const struct of_device_id nv3052c_of_match[] = { 683 486 { .compatible = "leadtek,ltk035c5444t", .data = &ltk035c5444t_panel_info }, 487 + { .compatible = "fascontek,fs035vg158", .data = &fs035vg158_panel_info }, 684 488 { /* sentinel */ } 685 489 }; 686 490 MODULE_DEVICE_TABLE(of, nv3052c_of_match); ··· 711 473 .name = "nv3052c", 712 474 .of_match_table = nv3052c_of_match, 713 475 }, 476 + .id_table = nv3052c_ids, 714 477 .probe = nv3052c_probe, 715 478 .remove = nv3052c_remove, 716 479 };
+34
drivers/gpu/drm/panel/panel-simple.c
··· 1134 1134 .connector_type = DRM_MODE_CONNECTOR_LVDS, 1135 1135 }; 1136 1136 1137 + static const struct display_timing auo_g156han04_timings = { 1138 + .pixelclock = { 137000000, 141000000, 146000000 }, 1139 + .hactive = { 1920, 1920, 1920 }, 1140 + .hfront_porch = { 60, 60, 60 }, 1141 + .hback_porch = { 90, 92, 111 }, 1142 + .hsync_len = { 32, 32, 32 }, 1143 + .vactive = { 1080, 1080, 1080 }, 1144 + .vfront_porch = { 12, 12, 12 }, 1145 + .vback_porch = { 24, 36, 56 }, 1146 + .vsync_len = { 8, 8, 8 }, 1147 + }; 1148 + 1149 + static const struct panel_desc auo_g156han04 = { 1150 + .timings = &auo_g156han04_timings, 1151 + .num_timings = 1, 1152 + .bpc = 8, 1153 + .size = { 1154 + .width = 344, 1155 + .height = 194, 1156 + }, 1157 + .delay = { 1158 + .prepare = 50, /* T2 */ 1159 + .enable = 200, /* T3 */ 1160 + .disable = 110, /* T10 */ 1161 + .unprepare = 1000, /* T13 */ 1162 + }, 1163 + .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, 1164 + .bus_flags = DRM_BUS_FLAG_DE_HIGH, 1165 + .connector_type = DRM_MODE_CONNECTOR_LVDS, 1166 + }; 1167 + 1137 1168 static const struct drm_display_mode auo_g156xtn01_mode = { 1138 1169 .clock = 76000, 1139 1170 .hdisplay = 1366, ··· 4319 4288 }, { 4320 4289 .compatible = "auo,g133han01", 4321 4290 .data = &auo_g133han01, 4291 + }, { 4292 + .compatible = "auo,g156han04", 4293 + .data = &auo_g156han04, 4322 4294 }, { 4323 4295 .compatible = "auo,g156xtn01", 4324 4296 .data = &auo_g156xtn01,
+137 -1
drivers/gpu/drm/panel/panel-sitronix-st7701.c
··· 288 288 FIELD_PREP(DSI_CMD2_BK1_PWRCTRL2_AVDD_MASK, 289 289 DIV_ROUND_CLOSEST(desc->avdd_mv - 6200, 200)) | 290 290 FIELD_PREP(DSI_CMD2_BK1_PWRCTRL2_AVCL_MASK, 291 - DIV_ROUND_CLOSEST(-4400 + desc->avcl_mv, 200))); 291 + DIV_ROUND_CLOSEST(-4400 - desc->avcl_mv, 200))); 292 292 293 293 /* T2D = 0.2us * T2D[3:0] */ 294 294 ST7701_DSI(st7701, DSI_CMD2_BK1_SPD1, ··· 421 421 ST7701_DSI(st7701, 0xEC, 0x02, 0x01); 422 422 ST7701_DSI(st7701, 0xED, 0xAB, 0x89, 0x76, 0x54, 0x01, 0xFF, 0xFF, 423 423 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x45, 0x67, 0x98, 0xBA); 424 + } 425 + 426 + static void rg_arc_gip_sequence(struct st7701 *st7701) 427 + { 428 + st7701_switch_cmd_bkx(st7701, true, 3); 429 + ST7701_DSI(st7701, 0xEF, 0x08); 430 + st7701_switch_cmd_bkx(st7701, true, 0); 431 + ST7701_DSI(st7701, 0xC7, 0x04); 432 + ST7701_DSI(st7701, 0xCC, 0x38); 433 + st7701_switch_cmd_bkx(st7701, true, 1); 434 + ST7701_DSI(st7701, 0xB9, 0x10); 435 + ST7701_DSI(st7701, 0xBC, 0x03); 436 + ST7701_DSI(st7701, 0xC0, 0x89); 437 + ST7701_DSI(st7701, 0xE0, 0x00, 0x00, 0x02); 438 + ST7701_DSI(st7701, 0xE1, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 439 + 0x00, 0x00, 0x20, 0x20); 440 + ST7701_DSI(st7701, 0xE2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 441 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); 442 + ST7701_DSI(st7701, 0xE3, 0x00, 0x00, 0x33, 0x00); 443 + ST7701_DSI(st7701, 0xE4, 0x22, 0x00); 444 + ST7701_DSI(st7701, 0xE5, 0x04, 0x5C, 0xA0, 0xA0, 0x06, 0x5C, 0xA0, 445 + 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); 446 + ST7701_DSI(st7701, 0xE6, 0x00, 0x00, 0x33, 0x00); 447 + ST7701_DSI(st7701, 0xE7, 0x22, 0x00); 448 + ST7701_DSI(st7701, 0xE8, 0x05, 0x5C, 0xA0, 0xA0, 0x07, 0x5C, 0xA0, 449 + 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); 450 + ST7701_DSI(st7701, 0xEB, 0x02, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00); 451 + ST7701_DSI(st7701, 0xEC, 0x00, 0x00); 452 + ST7701_DSI(st7701, 0xED, 0xFA, 0x45, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 453 + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB0, 0x54, 0xAF); 454 + ST7701_DSI(st7701, 0xEF, 0x08, 0x08, 0x08, 0x45, 0x3F, 0x54); 455 + st7701_switch_cmd_bkx(st7701, false, 0); 456 + ST7701_DSI(st7701, MIPI_DCS_SET_ADDRESS_MODE, 0x17); 457 + ST7701_DSI(st7701, MIPI_DCS_SET_PIXEL_FORMAT, 0x77); 458 + ST7701_DSI(st7701, MIPI_DCS_EXIT_SLEEP_MODE, 0x00); 459 + msleep(120); 424 460 } 425 461 426 462 static int st7701_prepare(struct drm_panel *panel) ··· 875 839 .gip_sequence = kd50t048a_gip_sequence, 876 840 }; 877 841 842 + static const struct drm_display_mode rg_arc_mode = { 843 + .clock = 25600, 844 + 845 + .hdisplay = 480, 846 + .hsync_start = 480 + 60, 847 + .hsync_end = 480 + 60 + 42, 848 + .htotal = 480 + 60 + 42 + 60, 849 + 850 + .vdisplay = 640, 851 + .vsync_start = 640 + 10, 852 + .vsync_end = 640 + 10 + 4, 853 + .vtotal = 640 + 10 + 4 + 16, 854 + 855 + .width_mm = 63, 856 + .height_mm = 84, 857 + 858 + .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, 859 + }; 860 + 861 + static const struct st7701_panel_desc rg_arc_desc = { 862 + .mode = &rg_arc_mode, 863 + .lanes = 2, 864 + .format = MIPI_DSI_FMT_RGB888, 865 + .panel_sleep_delay = 80, 866 + 867 + .pv_gamma = { 868 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_AJ_MASK, 0x01) | 869 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC0_MASK, 0), 870 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 871 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC4_MASK, 0x16), 872 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 873 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC8_MASK, 0x1d), 874 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC16_MASK, 0x0e), 875 + 876 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 877 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC24_MASK, 0x12), 878 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC52_MASK, 0x06), 879 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC80_MASK, 0x0c), 880 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC108_MASK, 0x0a), 881 + 882 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC147_MASK, 0x09), 883 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC175_MASK, 0x25), 884 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC203_MASK, 0x00), 885 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 886 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC231_MASK, 0x03), 887 + 888 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC239_MASK, 0x00), 889 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 890 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC247_MASK, 0x3f), 891 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 892 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC251_MASK, 0x3f), 893 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 894 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC255_MASK, 0x1c) 895 + }, 896 + .nv_gamma = { 897 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_AJ_MASK, 0x01) | 898 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC0_MASK, 0), 899 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 900 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC4_MASK, 0x16), 901 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 902 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC8_MASK, 0x1e), 903 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC16_MASK, 0x0e), 904 + 905 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 906 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC24_MASK, 0x11), 907 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC52_MASK, 0x06), 908 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC80_MASK, 0x0c), 909 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC108_MASK, 0x08), 910 + 911 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC147_MASK, 0x09), 912 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC175_MASK, 0x26), 913 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC203_MASK, 0x00), 914 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 915 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC231_MASK, 0x15), 916 + 917 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC239_MASK, 0x00), 918 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 919 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC247_MASK, 0x3f), 920 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 921 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC251_MASK, 0x3f), 922 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | 923 + CFIELD_PREP(DSI_CMD2_BK0_GAMCTRL_VC255_MASK, 0x1c) 924 + }, 925 + .nlinv = 0, 926 + .vop_uv = 4500000, 927 + .vcom_uv = 762500, 928 + .vgh_mv = 15000, 929 + .vgl_mv = -9510, 930 + .avdd_mv = 6600, 931 + .avcl_mv = -4400, 932 + .gamma_op_bias = OP_BIAS_MIDDLE, 933 + .input_op_bias = OP_BIAS_MIN, 934 + .output_op_bias = OP_BIAS_MIN, 935 + .t2d_ns = 1600, 936 + .t3d_ns = 10400, 937 + .eot_en = true, 938 + .gip_sequence = rg_arc_gip_sequence, 939 + }; 940 + 878 941 static int st7701_dsi_probe(struct mipi_dsi_device *dsi) 879 942 { 880 943 const struct st7701_panel_desc *desc; ··· 1052 917 } 1053 918 1054 919 static const struct of_device_id st7701_of_match[] = { 920 + { .compatible = "anbernic,rg-arc-panel", .data = &rg_arc_desc }, 1055 921 { .compatible = "densitron,dmt028vghmcmi-1a", .data = &dmt028vghmcmi_1a_desc }, 1056 922 { .compatible = "elida,kd50t048a", .data = &kd50t048a_desc }, 1057 923 { .compatible = "techstar,ts8550b", .data = &ts8550b_desc },
+362
drivers/gpu/drm/panel/panel-synaptics-r63353.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Synaptics R63353 Controller driver 4 + * 5 + * Copyright (C) 2020 BSH Hausgerate GmbH 6 + */ 7 + 8 + #include <linux/delay.h> 9 + #include <linux/device.h> 10 + #include <linux/err.h> 11 + #include <linux/errno.h> 12 + #include <linux/kernel.h> 13 + #include <linux/module.h> 14 + #include <linux/of.h> 15 + #include <linux/media-bus-format.h> 16 + 17 + #include <linux/gpio/consumer.h> 18 + #include <linux/regulator/consumer.h> 19 + 20 + #include <drm/drm_mipi_dsi.h> 21 + #include <drm/drm_modes.h> 22 + #include <drm/drm_panel.h> 23 + 24 + #include <video/mipi_display.h> 25 + 26 + #define R63353_INSTR(...) { \ 27 + .len = sizeof((u8[]) {__VA_ARGS__}), \ 28 + .data = (u8[]){__VA_ARGS__} \ 29 + } 30 + 31 + struct r63353_instr { 32 + size_t len; 33 + const u8 *data; 34 + }; 35 + 36 + static const struct r63353_instr sharp_ls068b3sx02_init[] = { 37 + R63353_INSTR(0x51, 0xff), 38 + R63353_INSTR(0x53, 0x0c), 39 + R63353_INSTR(0x55, 0x00), 40 + R63353_INSTR(0x84, 0x00), 41 + R63353_INSTR(0x29), 42 + }; 43 + 44 + struct r63353_desc { 45 + const char *name; 46 + const struct r63353_instr *init; 47 + const size_t init_length; 48 + const struct drm_display_mode *mode; 49 + u32 width_mm; 50 + u32 height_mm; 51 + }; 52 + 53 + struct r63353_panel { 54 + struct drm_panel base; 55 + struct mipi_dsi_device *dsi; 56 + 57 + struct gpio_desc *reset_gpio; 58 + struct regulator *dvdd; 59 + struct regulator *avdd; 60 + 61 + struct r63353_desc *pdata; 62 + }; 63 + 64 + static inline struct r63353_panel *to_r63353_panel(struct drm_panel *panel) 65 + { 66 + return container_of(panel, struct r63353_panel, base); 67 + } 68 + 69 + static int r63353_panel_power_on(struct r63353_panel *rpanel) 70 + { 71 + struct mipi_dsi_device *dsi = rpanel->dsi; 72 + struct device *dev = &dsi->dev; 73 + int ret; 74 + 75 + ret = regulator_enable(rpanel->avdd); 76 + if (ret) { 77 + dev_err(dev, "Failed to enable avdd regulator (%d)\n", ret); 78 + return ret; 79 + } 80 + 81 + usleep_range(15000, 25000); 82 + 83 + ret = regulator_enable(rpanel->dvdd); 84 + if (ret) { 85 + dev_err(dev, "Failed to enable dvdd regulator (%d)\n", ret); 86 + regulator_disable(rpanel->avdd); 87 + return ret; 88 + } 89 + 90 + usleep_range(300000, 350000); 91 + gpiod_set_value(rpanel->reset_gpio, 1); 92 + usleep_range(15000, 25000); 93 + 94 + return 0; 95 + } 96 + 97 + static int r63353_panel_power_off(struct r63353_panel *rpanel) 98 + { 99 + gpiod_set_value(rpanel->reset_gpio, 0); 100 + regulator_disable(rpanel->dvdd); 101 + regulator_disable(rpanel->avdd); 102 + 103 + return 0; 104 + } 105 + 106 + static int r63353_panel_activate(struct r63353_panel *rpanel) 107 + { 108 + struct mipi_dsi_device *dsi = rpanel->dsi; 109 + struct device *dev = &dsi->dev; 110 + int i, ret; 111 + 112 + ret = mipi_dsi_dcs_soft_reset(dsi); 113 + if (ret < 0) { 114 + dev_err(dev, "Failed to do Software Reset (%d)\n", ret); 115 + goto fail; 116 + } 117 + 118 + usleep_range(15000, 17000); 119 + 120 + ret = mipi_dsi_dcs_enter_sleep_mode(dsi); 121 + if (ret < 0) { 122 + dev_err(dev, "Failed to enter sleep mode (%d)\n", ret); 123 + goto fail; 124 + } 125 + 126 + for (i = 0; i < rpanel->pdata->init_length; i++) { 127 + const struct r63353_instr *instr = &rpanel->pdata->init[i]; 128 + 129 + ret = mipi_dsi_dcs_write_buffer(dsi, instr->data, instr->len); 130 + if (ret < 0) 131 + goto fail; 132 + } 133 + 134 + msleep(120); 135 + 136 + ret = mipi_dsi_dcs_exit_sleep_mode(dsi); 137 + if (ret < 0) { 138 + dev_err(dev, "Failed to exit sleep mode (%d)\n", ret); 139 + goto fail; 140 + } 141 + 142 + usleep_range(5000, 10000); 143 + 144 + ret = mipi_dsi_dcs_set_display_on(dsi); 145 + if (ret < 0) { 146 + dev_err(dev, "Failed to set display ON (%d)\n", ret); 147 + goto fail; 148 + } 149 + 150 + return 0; 151 + 152 + fail: 153 + gpiod_set_value(rpanel->reset_gpio, 0); 154 + 155 + return ret; 156 + } 157 + 158 + static int r63353_panel_prepare(struct drm_panel *panel) 159 + { 160 + struct r63353_panel *rpanel = to_r63353_panel(panel); 161 + struct mipi_dsi_device *dsi = rpanel->dsi; 162 + struct device *dev = &dsi->dev; 163 + int ret; 164 + 165 + dev_dbg(dev, "Preparing\n"); 166 + 167 + ret = r63353_panel_power_on(rpanel); 168 + if (ret) 169 + return ret; 170 + 171 + ret = r63353_panel_activate(rpanel); 172 + if (ret) { 173 + r63353_panel_power_off(rpanel); 174 + return ret; 175 + } 176 + 177 + dev_dbg(dev, "Prepared\n"); 178 + return 0; 179 + } 180 + 181 + static int r63353_panel_deactivate(struct r63353_panel *rpanel) 182 + { 183 + struct mipi_dsi_device *dsi = rpanel->dsi; 184 + struct device *dev = &dsi->dev; 185 + int ret; 186 + 187 + ret = mipi_dsi_dcs_set_display_off(dsi); 188 + if (ret < 0) { 189 + dev_err(dev, "Failed to set display OFF (%d)\n", ret); 190 + return ret; 191 + } 192 + 193 + usleep_range(5000, 10000); 194 + 195 + ret = mipi_dsi_dcs_enter_sleep_mode(dsi); 196 + if (ret < 0) { 197 + dev_err(dev, "Failed to enter sleep mode (%d)\n", ret); 198 + return ret; 199 + } 200 + 201 + return 0; 202 + } 203 + 204 + static int r63353_panel_unprepare(struct drm_panel *panel) 205 + { 206 + struct r63353_panel *rpanel = to_r63353_panel(panel); 207 + 208 + r63353_panel_deactivate(rpanel); 209 + r63353_panel_power_off(rpanel); 210 + 211 + return 0; 212 + } 213 + 214 + static const struct drm_display_mode sharp_ls068b3sx02_timing = { 215 + .clock = 70000, 216 + .hdisplay = 640, 217 + .hsync_start = 640 + 35, 218 + .hsync_end = 640 + 35 + 2, 219 + .htotal = 640 + 35 + 2 + 150, 220 + .vdisplay = 1280, 221 + .vsync_start = 1280 + 2, 222 + .vsync_end = 1280 + 2 + 4, 223 + .vtotal = 1280 + 2 + 4 + 0, 224 + }; 225 + 226 + static int r63353_panel_get_modes(struct drm_panel *panel, 227 + struct drm_connector *connector) 228 + { 229 + struct r63353_panel *rpanel = to_r63353_panel(panel); 230 + struct drm_display_mode *mode; 231 + static const u32 bus_format = MEDIA_BUS_FMT_RGB888_1X24; 232 + 233 + mode = drm_mode_duplicate(connector->dev, rpanel->pdata->mode); 234 + if (!mode) 235 + return -ENOMEM; 236 + 237 + drm_mode_set_name(mode); 238 + drm_mode_probed_add(connector, mode); 239 + 240 + mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; 241 + connector->display_info.width_mm = rpanel->pdata->width_mm; 242 + connector->display_info.height_mm = rpanel->pdata->height_mm; 243 + 244 + drm_display_info_set_bus_formats(&connector->display_info, 245 + &bus_format, 1); 246 + 247 + return 1; 248 + } 249 + 250 + static const struct drm_panel_funcs r63353_panel_funcs = { 251 + .prepare = r63353_panel_prepare, 252 + .unprepare = r63353_panel_unprepare, 253 + .get_modes = r63353_panel_get_modes, 254 + }; 255 + 256 + static int r63353_panel_probe(struct mipi_dsi_device *dsi) 257 + { 258 + int ret = 0; 259 + struct device *dev = &dsi->dev; 260 + struct r63353_panel *panel; 261 + 262 + panel = devm_kzalloc(&dsi->dev, sizeof(*panel), GFP_KERNEL); 263 + if (!panel) 264 + return -ENOMEM; 265 + 266 + mipi_dsi_set_drvdata(dsi, panel); 267 + panel->dsi = dsi; 268 + panel->pdata = (struct r63353_desc *)of_device_get_match_data(dev); 269 + 270 + dev_info(dev, "Panel %s\n", panel->pdata->name); 271 + 272 + dsi->lanes = 2; 273 + dsi->format = MIPI_DSI_FMT_RGB888; 274 + dsi->mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO | 275 + MIPI_DSI_CLOCK_NON_CONTINUOUS | MIPI_DSI_MODE_LPM | 276 + MIPI_DSI_MODE_VIDEO_SYNC_PULSE | MIPI_DSI_MODE_NO_EOT_PACKET; 277 + 278 + panel->dvdd = devm_regulator_get(dev, "dvdd"); 279 + if (IS_ERR(panel->dvdd)) 280 + return PTR_ERR(panel->dvdd); 281 + panel->avdd = devm_regulator_get(dev, "avdd"); 282 + if (IS_ERR(panel->avdd)) 283 + return PTR_ERR(panel->avdd); 284 + 285 + panel->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); 286 + if (IS_ERR(panel->reset_gpio)) { 287 + dev_err(dev, "failed to get RESET GPIO\n"); 288 + return PTR_ERR(panel->reset_gpio); 289 + } 290 + 291 + drm_panel_init(&panel->base, dev, &r63353_panel_funcs, 292 + DRM_MODE_CONNECTOR_DSI); 293 + 294 + panel->base.prepare_prev_first = true; 295 + ret = drm_panel_of_backlight(&panel->base); 296 + if (ret) 297 + return ret; 298 + 299 + drm_panel_add(&panel->base); 300 + 301 + ret = mipi_dsi_attach(dsi); 302 + if (ret < 0) { 303 + dev_err(dev, "mipi_dsi_attach failed: %d\n", ret); 304 + drm_panel_remove(&panel->base); 305 + return ret; 306 + } 307 + 308 + return ret; 309 + } 310 + 311 + static void r63353_panel_remove(struct mipi_dsi_device *dsi) 312 + { 313 + struct r63353_panel *rpanel = mipi_dsi_get_drvdata(dsi); 314 + struct device *dev = &dsi->dev; 315 + int ret; 316 + 317 + ret = mipi_dsi_detach(dsi); 318 + if (ret < 0) 319 + dev_err(dev, "Failed to detach from host (%d)\n", ret); 320 + 321 + drm_panel_remove(&rpanel->base); 322 + } 323 + 324 + static void r63353_panel_shutdown(struct mipi_dsi_device *dsi) 325 + { 326 + struct r63353_panel *rpanel = mipi_dsi_get_drvdata(dsi); 327 + 328 + r63353_panel_unprepare(&rpanel->base); 329 + } 330 + 331 + static const struct r63353_desc sharp_ls068b3sx02_data = { 332 + .name = "Sharp LS068B3SX02", 333 + .mode = &sharp_ls068b3sx02_timing, 334 + .init = sharp_ls068b3sx02_init, 335 + .init_length = ARRAY_SIZE(sharp_ls068b3sx02_init), 336 + .width_mm = 68, 337 + .height_mm = 159, 338 + }; 339 + 340 + static const struct of_device_id r63353_of_match[] = { 341 + { .compatible = "sharp,ls068b3sx02", .data = &sharp_ls068b3sx02_data }, 342 + { } 343 + }; 344 + 345 + MODULE_DEVICE_TABLE(of, r63353_of_match); 346 + 347 + static struct mipi_dsi_driver r63353_panel_driver = { 348 + .driver = { 349 + .name = "r63353-dsi", 350 + .of_match_table = r63353_of_match, 351 + }, 352 + .probe = r63353_panel_probe, 353 + .remove = r63353_panel_remove, 354 + .shutdown = r63353_panel_shutdown, 355 + }; 356 + 357 + module_mipi_dsi_driver(r63353_panel_driver); 358 + 359 + MODULE_AUTHOR("Matthias Proske <Matthias.Proske@bshg.com>"); 360 + MODULE_AUTHOR("Michael Trimarchi <michael@amarulasolutions.com>"); 361 + MODULE_DESCRIPTION("Synaptics R63353 Controller Driver"); 362 + MODULE_LICENSE("GPL");
-1
drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
··· 30 30 #include <drm/drm_simple_kms_helper.h> 31 31 32 32 #include "rockchip_drm_drv.h" 33 - #include "rockchip_drm_vop.h" 34 33 35 34 #define RK3288_GRF_SOC_CON6 0x25c 36 35 #define RK3288_EDP_LCDC_SEL BIT(5)
-1
drivers/gpu/drm/rockchip/cdn-dp-core.c
··· 24 24 25 25 #include "cdn-dp-core.h" 26 26 #include "cdn-dp-reg.h" 27 - #include "rockchip_drm_vop.h" 28 27 29 28 static inline struct cdn_dp_device *connector_to_dp(struct drm_connector *connector) 30 29 {
-1
drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
··· 26 26 #include <drm/drm_simple_kms_helper.h> 27 27 28 28 #include "rockchip_drm_drv.h" 29 - #include "rockchip_drm_vop.h" 30 29 31 30 #define DSI_PHY_RSTZ 0xa0 32 31 #define PHY_DISFORCEPLL 0
-1
drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
··· 18 18 #include <drm/drm_simple_kms_helper.h> 19 19 20 20 #include "rockchip_drm_drv.h" 21 - #include "rockchip_drm_vop.h" 22 21 23 22 #define RK3228_GRF_SOC_CON2 0x0408 24 23 #define RK3228_HDMI_SDAIN_MSK BIT(14)
-1
drivers/gpu/drm/rockchip/inno_hdmi.c
··· 23 23 #include <drm/drm_simple_kms_helper.h> 24 24 25 25 #include "rockchip_drm_drv.h" 26 - #include "rockchip_drm_vop.h" 27 26 28 27 #include "inno_hdmi.h" 29 28
-1
drivers/gpu/drm/rockchip/rk3066_hdmi.c
··· 18 18 #include "rk3066_hdmi.h" 19 19 20 20 #include "rockchip_drm_drv.h" 21 - #include "rockchip_drm_vop.h" 22 21 23 22 #define DEFAULT_PLLA_RATE 30000000 24 23
+18
drivers/gpu/drm/rockchip/rockchip_drm_drv.h
··· 20 20 #define ROCKCHIP_MAX_CONNECTOR 2 21 21 #define ROCKCHIP_MAX_CRTC 4 22 22 23 + /* 24 + * display output interface supported by rockchip lcdc 25 + */ 26 + #define ROCKCHIP_OUT_MODE_P888 0 27 + #define ROCKCHIP_OUT_MODE_BT1120 0 28 + #define ROCKCHIP_OUT_MODE_P666 1 29 + #define ROCKCHIP_OUT_MODE_P565 2 30 + #define ROCKCHIP_OUT_MODE_BT656 5 31 + #define ROCKCHIP_OUT_MODE_S888 8 32 + #define ROCKCHIP_OUT_MODE_S888_DUMMY 12 33 + #define ROCKCHIP_OUT_MODE_YUV420 14 34 + /* for use special outface */ 35 + #define ROCKCHIP_OUT_MODE_AAAA 15 36 + 37 + /* output flags */ 38 + #define ROCKCHIP_OUTPUT_DSI_DUAL BIT(0) 39 + 23 40 struct drm_device; 24 41 struct drm_connector; 25 42 struct iommu_domain; ··· 48 31 int output_bpc; 49 32 int output_flags; 50 33 bool enable_afbc; 34 + bool yuv_overlay; 51 35 u32 bus_format; 52 36 u32 bus_flags; 53 37 int color_space;
-12
drivers/gpu/drm/rockchip/rockchip_drm_vop.h
··· 277 277 /* dst alpha ctrl define */ 278 278 #define DST_FACTOR_M0(x) (((x) & 0x7) << 6) 279 279 280 - /* 281 - * display output interface supported by rockchip lcdc 282 - */ 283 - #define ROCKCHIP_OUT_MODE_P888 0 284 - #define ROCKCHIP_OUT_MODE_P666 1 285 - #define ROCKCHIP_OUT_MODE_P565 2 286 - /* for use special outface */ 287 - #define ROCKCHIP_OUT_MODE_AAAA 15 288 - 289 - /* output flags */ 290 - #define ROCKCHIP_OUTPUT_DSI_DUAL BIT(0) 291 - 292 280 enum alpha_mode { 293 281 ALPHA_STRAIGHT, 294 282 ALPHA_INVERSE,
+463 -39
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
··· 190 190 void __iomem *regs; 191 191 struct regmap *map; 192 192 193 - struct regmap *grf; 193 + struct regmap *sys_grf; 194 + struct regmap *vop_grf; 195 + struct regmap *vo1_grf; 196 + struct regmap *sys_pmu; 194 197 195 198 /* physical map length of vop2 register */ 196 199 u32 len; ··· 212 209 unsigned int enable_count; 213 210 struct clk *hclk; 214 211 struct clk *aclk; 212 + struct clk *pclk; 215 213 216 214 /* optional internal rgb encoder */ 217 215 struct rockchip_rgb *rgb; ··· 220 216 /* must be put at the end of the struct */ 221 217 struct vop2_win win[]; 222 218 }; 219 + 220 + #define vop2_output_if_is_hdmi(x) ((x) == ROCKCHIP_VOP2_EP_HDMI0 || \ 221 + (x) == ROCKCHIP_VOP2_EP_HDMI1) 222 + 223 + #define vop2_output_if_is_dp(x) ((x) == ROCKCHIP_VOP2_EP_DP0 || \ 224 + (x) == ROCKCHIP_VOP2_EP_DP1) 225 + 226 + #define vop2_output_if_is_edp(x) ((x) == ROCKCHIP_VOP2_EP_EDP0 || \ 227 + (x) == ROCKCHIP_VOP2_EP_EDP1) 228 + 229 + #define vop2_output_if_is_mipi(x) ((x) == ROCKCHIP_VOP2_EP_MIPI0 || \ 230 + (x) == ROCKCHIP_VOP2_EP_MIPI1) 231 + 232 + #define vop2_output_if_is_lvds(x) ((x) == ROCKCHIP_VOP2_EP_LVDS0 || \ 233 + (x) == ROCKCHIP_VOP2_EP_LVDS1) 234 + 235 + #define vop2_output_if_is_dpi(x) ((x) == ROCKCHIP_VOP2_EP_RGB0) 236 + 237 + static const struct regmap_config vop2_regmap_config; 223 238 224 239 static struct vop2_video_port *to_vop2_video_port(struct drm_crtc *crtc) 225 240 { ··· 289 266 return win->data->feature & WIN_FEATURE_CLUSTER; 290 267 } 291 268 269 + /* 270 + * Note: 271 + * The write mask function is documented but missing on rk3566/8, writes 272 + * to these bits have no effect. For newer soc(rk3588 and following) the 273 + * write mask is needed for register writes. 274 + * 275 + * GLB_CFG_DONE_EN has no write mask bit. 276 + * 277 + */ 292 278 static void vop2_cfg_done(struct vop2_video_port *vp) 293 279 { 294 280 struct vop2 *vop2 = vp->vop2; 281 + u32 val = RK3568_REG_CFG_DONE__GLB_CFG_DONE_EN; 295 282 296 - regmap_set_bits(vop2->map, RK3568_REG_CFG_DONE, 297 - BIT(vp->id) | RK3568_REG_CFG_DONE__GLB_CFG_DONE_EN); 283 + val |= BIT(vp->id) | (BIT(vp->id) << 16); 284 + 285 + regmap_set_bits(vop2->map, RK3568_REG_CFG_DONE, val); 298 286 } 299 287 300 288 static void vop2_win_disable(struct vop2_win *win) ··· 496 462 return false; 497 463 } 498 464 465 + static bool vop2_output_rg_swap(struct vop2 *vop2, u32 bus_format) 466 + { 467 + if (vop2->data->soc_id == 3588) { 468 + if (bus_format == MEDIA_BUS_FMT_YUV8_1X24 || 469 + bus_format == MEDIA_BUS_FMT_YUV10_1X30) 470 + return true; 471 + } 472 + 473 + return false; 474 + } 475 + 499 476 static bool is_yuv_output(u32 bus_format) 500 477 { 501 478 switch (bus_format) { ··· 562 517 } 563 518 564 519 return vop2_convert_afbc_format(format) >= 0; 520 + } 521 + 522 + /* 523 + * 0: Full mode, 16 lines for one tail 524 + * 1: half block mode, 8 lines one tail 525 + */ 526 + static bool vop2_half_block_enable(struct drm_plane_state *pstate) 527 + { 528 + if (pstate->rotation & (DRM_MODE_ROTATE_270 | DRM_MODE_ROTATE_90)) 529 + return false; 530 + else 531 + return true; 565 532 } 566 533 567 534 static u32 vop2_afbc_transform_offset(struct drm_plane_state *pstate, ··· 911 854 goto err; 912 855 } 913 856 857 + ret = clk_prepare_enable(vop2->pclk); 858 + if (ret < 0) { 859 + drm_err(vop2->drm, "failed to enable pclk - %d\n", ret); 860 + goto err1; 861 + } 862 + 914 863 return 0; 864 + err1: 865 + clk_disable_unprepare(vop2->aclk); 915 866 err: 916 867 clk_disable_unprepare(vop2->hclk); 917 868 918 869 return ret; 870 + } 871 + 872 + static void rk3588_vop2_power_domain_enable_all(struct vop2 *vop2) 873 + { 874 + u32 pd; 875 + 876 + pd = vop2_readl(vop2, RK3588_SYS_PD_CTRL); 877 + pd &= ~(VOP2_PD_CLUSTER0 | VOP2_PD_CLUSTER1 | VOP2_PD_CLUSTER2 | 878 + VOP2_PD_CLUSTER3 | VOP2_PD_ESMART); 879 + 880 + vop2_writel(vop2, RK3588_SYS_PD_CTRL, pd); 919 881 } 920 882 921 883 static void vop2_enable(struct vop2 *vop2) ··· 959 883 return; 960 884 } 961 885 962 - regcache_sync(vop2->map); 886 + ret = regmap_reinit_cache(vop2->map, &vop2_regmap_config); 887 + if (ret) { 888 + drm_err(vop2->drm, "failed to reinit cache: %d\n", ret); 889 + return; 890 + } 963 891 964 892 if (vop2->data->soc_id == 3566) 965 893 vop2_writel(vop2, RK3568_OTP_WIN_EN, 1); 894 + 895 + if (vop2->data->soc_id == 3588) 896 + rk3588_vop2_power_domain_enable_all(vop2); 966 897 967 898 vop2_writel(vop2, RK3568_REG_CFG_DONE, RK3568_REG_CFG_DONE__GLB_CFG_DONE_EN); 968 899 ··· 996 913 997 914 pm_runtime_put_sync(vop2->dev); 998 915 999 - regcache_mark_dirty(vop2->map); 1000 - 916 + clk_disable_unprepare(vop2->pclk); 1001 917 clk_disable_unprepare(vop2->aclk); 1002 918 clk_disable_unprepare(vop2->hclk); 1003 919 } ··· 1222 1140 bool rotate_90 = pstate->rotation & DRM_MODE_ROTATE_90; 1223 1141 struct rockchip_gem_object *rk_obj; 1224 1142 unsigned long offset; 1143 + bool half_block_en; 1225 1144 bool afbc_en; 1226 1145 dma_addr_t yrgb_mst; 1227 1146 dma_addr_t uv_mst; ··· 1315 1232 dsp_info = (dsp_h - 1) << 16 | ((dsp_w - 1) & 0xffff); 1316 1233 1317 1234 format = vop2_convert_format(fb->format->format); 1235 + half_block_en = vop2_half_block_enable(pstate); 1318 1236 1319 1237 drm_dbg(vop2->drm, "vp%d update %s[%dx%d->%dx%d@%dx%d] fmt[%p4cc_%s] addr[%pad]\n", 1320 1238 vp->id, win->data->name, actual_w, actual_h, dsp_w, dsp_h, 1321 1239 dest->x1, dest->y1, 1322 1240 &fb->format->format, 1323 1241 afbc_en ? "AFBC" : "", &yrgb_mst); 1242 + 1243 + if (vop2_cluster_window(win)) 1244 + vop2_win_write(win, VOP2_WIN_AFBC_HALF_BLOCK_EN, half_block_en); 1324 1245 1325 1246 if (afbc_en) { 1326 1247 u32 stride; ··· 1364 1277 vop2_win_write(win, VOP2_WIN_AFBC_ENABLE, 1); 1365 1278 vop2_win_write(win, VOP2_WIN_AFBC_FORMAT, afbc_format); 1366 1279 vop2_win_write(win, VOP2_WIN_AFBC_UV_SWAP, uv_swap); 1367 - vop2_win_write(win, VOP2_WIN_AFBC_AUTO_GATING_EN, 0); 1280 + /* 1281 + * On rk3566/8, this bit is auto gating enable, 1282 + * but this function is not work well so we need 1283 + * to disable it for these two platform. 1284 + * On rk3588, and the following new soc(rk3528/rk3576), 1285 + * this bit is gating disable, we should write 1 to 1286 + * disable gating when enable afbc. 1287 + */ 1288 + if (vop2->data->soc_id == 3566 || vop2->data->soc_id == 3568) 1289 + vop2_win_write(win, VOP2_WIN_AFBC_AUTO_GATING_EN, 0); 1290 + else 1291 + vop2_win_write(win, VOP2_WIN_AFBC_AUTO_GATING_EN, 1); 1292 + 1368 1293 vop2_win_write(win, VOP2_WIN_AFBC_BLOCK_SPLIT_EN, 0); 1369 - if (pstate->rotation & (DRM_MODE_ROTATE_270 | DRM_MODE_ROTATE_90)) { 1370 - vop2_win_write(win, VOP2_WIN_AFBC_HALF_BLOCK_EN, 0); 1371 - transform_offset = vop2_afbc_transform_offset(pstate, false); 1372 - } else { 1373 - vop2_win_write(win, VOP2_WIN_AFBC_HALF_BLOCK_EN, 1); 1374 - transform_offset = vop2_afbc_transform_offset(pstate, true); 1375 - } 1294 + transform_offset = vop2_afbc_transform_offset(pstate, half_block_en); 1376 1295 vop2_win_write(win, VOP2_WIN_AFBC_HDR_PTR, yrgb_mst); 1377 1296 vop2_win_write(win, VOP2_WIN_AFBC_PIC_SIZE, act_info); 1378 1297 vop2_win_write(win, VOP2_WIN_AFBC_TRANSFORM_OFFSET, transform_offset); ··· 1390 1297 vop2_win_write(win, VOP2_WIN_AFBC_ROTATE_270, rotate_270); 1391 1298 vop2_win_write(win, VOP2_WIN_AFBC_ROTATE_90, rotate_90); 1392 1299 } else { 1300 + if (vop2_cluster_window(win)) { 1301 + vop2_win_write(win, VOP2_WIN_AFBC_ENABLE, 0); 1302 + vop2_win_write(win, VOP2_WIN_AFBC_TRANSFORM_OFFSET, 0); 1303 + } 1304 + 1393 1305 vop2_win_write(win, VOP2_WIN_YRGB_VIR, DIV_ROUND_UP(fb->pitches[0], 4)); 1394 1306 } 1395 1307 ··· 1527 1429 u32 top_margin = 100, bottom_margin = 100; 1528 1430 u16 hsize = hdisplay * (left_margin + right_margin) / 200; 1529 1431 u16 vsize = vdisplay * (top_margin + bottom_margin) / 200; 1432 + u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start; 1530 1433 u16 hact_end, vact_end; 1531 1434 u32 val; 1435 + u32 bg_dly; 1436 + u32 pre_scan_dly; 1437 + 1438 + bg_dly = vp->data->pre_scan_max_dly[3]; 1439 + vop2_writel(vp->vop2, RK3568_VP_BG_MIX_CTRL(vp->id), 1440 + FIELD_PREP(RK3568_VP_BG_MIX_CTRL__BG_DLY, bg_dly)); 1441 + 1442 + pre_scan_dly = ((bg_dly + (hdisplay >> 1) - 1) << 16) | hsync_len; 1443 + vop2_vp_write(vp, RK3568_VP_PRE_SCAN_HTIMING, pre_scan_dly); 1532 1444 1533 1445 vsize = rounddown(vsize, 2); 1534 1446 hsize = rounddown(hsize, 2); ··· 1574 1466 vop2_vp_write(vp, RK3568_VP_DSP_BG, 0); 1575 1467 } 1576 1468 1577 - static void rk3568_set_intf_mux(struct vop2_video_port *vp, int id, 1578 - u32 polflags) 1469 + static unsigned long rk3568_set_intf_mux(struct vop2_video_port *vp, int id, u32 polflags) 1579 1470 { 1580 1471 struct vop2 *vop2 = vp->vop2; 1472 + struct drm_crtc *crtc = &vp->crtc; 1581 1473 u32 die, dip; 1582 1474 1583 1475 die = vop2_readl(vop2, RK3568_DSP_IF_EN); ··· 1591 1483 dip &= ~RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL; 1592 1484 dip |= FIELD_PREP(RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL, polflags); 1593 1485 if (polflags & POLFLAG_DCLK_INV) 1594 - regmap_write(vop2->grf, RK3568_GRF_VO_CON1, BIT(3 + 16) | BIT(3)); 1486 + regmap_write(vop2->sys_grf, RK3568_GRF_VO_CON1, BIT(3 + 16) | BIT(3)); 1595 1487 else 1596 - regmap_write(vop2->grf, RK3568_GRF_VO_CON1, BIT(3 + 16)); 1488 + regmap_write(vop2->sys_grf, RK3568_GRF_VO_CON1, BIT(3 + 16)); 1597 1489 break; 1598 1490 case ROCKCHIP_VOP2_EP_HDMI0: 1599 1491 die &= ~RK3568_SYS_DSP_INFACE_EN_HDMI_MUX; ··· 1639 1531 break; 1640 1532 default: 1641 1533 drm_err(vop2->drm, "Invalid interface id %d on vp%d\n", id, vp->id); 1642 - return; 1534 + return 0; 1643 1535 } 1644 1536 1645 1537 dip |= RK3568_DSP_IF_POL__CFG_DONE_IMD; 1646 1538 1647 1539 vop2_writel(vop2, RK3568_DSP_IF_EN, die); 1648 1540 vop2_writel(vop2, RK3568_DSP_IF_POL, dip); 1541 + 1542 + return crtc->state->adjusted_mode.crtc_clock * 1000LL; 1543 + } 1544 + 1545 + /* 1546 + * calc the dclk on rk3588 1547 + * the available div of dclk is 1, 2, 4 1548 + */ 1549 + static unsigned long rk3588_calc_dclk(unsigned long child_clk, unsigned long max_dclk) 1550 + { 1551 + if (child_clk * 4 <= max_dclk) 1552 + return child_clk * 4; 1553 + else if (child_clk * 2 <= max_dclk) 1554 + return child_clk * 2; 1555 + else if (child_clk <= max_dclk) 1556 + return child_clk; 1557 + else 1558 + return 0; 1559 + } 1560 + 1561 + /* 1562 + * 4 pixclk/cycle on rk3588 1563 + * RGB/eDP/HDMI: if_pixclk >= dclk_core 1564 + * DP: dp_pixclk = dclk_out <= dclk_core 1565 + * DSI: mipi_pixclk <= dclk_out <= dclk_core 1566 + */ 1567 + static unsigned long rk3588_calc_cru_cfg(struct vop2_video_port *vp, int id, 1568 + int *dclk_core_div, int *dclk_out_div, 1569 + int *if_pixclk_div, int *if_dclk_div) 1570 + { 1571 + struct vop2 *vop2 = vp->vop2; 1572 + struct drm_crtc *crtc = &vp->crtc; 1573 + struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode; 1574 + struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state); 1575 + int output_mode = vcstate->output_mode; 1576 + unsigned long v_pixclk = adjusted_mode->crtc_clock * 1000LL; /* video timing pixclk */ 1577 + unsigned long dclk_core_rate = v_pixclk >> 2; 1578 + unsigned long dclk_rate = v_pixclk; 1579 + unsigned long dclk_out_rate; 1580 + unsigned long if_dclk_rate; 1581 + unsigned long if_pixclk_rate; 1582 + int K = 1; 1583 + 1584 + if (vop2_output_if_is_hdmi(id)) { 1585 + /* 1586 + * K = 2: dclk_core = if_pixclk_rate > if_dclk_rate 1587 + * K = 1: dclk_core = hdmie_edp_dclk > if_pixclk_rate 1588 + */ 1589 + if (output_mode == ROCKCHIP_OUT_MODE_YUV420) { 1590 + dclk_rate = dclk_rate >> 1; 1591 + K = 2; 1592 + } 1593 + 1594 + if_pixclk_rate = (dclk_core_rate << 1) / K; 1595 + if_dclk_rate = dclk_core_rate / K; 1596 + /* 1597 + * *if_pixclk_div = dclk_rate / if_pixclk_rate; 1598 + * *if_dclk_div = dclk_rate / if_dclk_rate; 1599 + */ 1600 + *if_pixclk_div = 2; 1601 + *if_dclk_div = 4; 1602 + } else if (vop2_output_if_is_edp(id)) { 1603 + /* 1604 + * edp_pixclk = edp_dclk > dclk_core 1605 + */ 1606 + if_pixclk_rate = v_pixclk / K; 1607 + dclk_rate = if_pixclk_rate * K; 1608 + /* 1609 + * *if_pixclk_div = dclk_rate / if_pixclk_rate; 1610 + * *if_dclk_div = *if_pixclk_div; 1611 + */ 1612 + *if_pixclk_div = K; 1613 + *if_dclk_div = K; 1614 + } else if (vop2_output_if_is_dp(id)) { 1615 + if (output_mode == ROCKCHIP_OUT_MODE_YUV420) 1616 + dclk_out_rate = v_pixclk >> 3; 1617 + else 1618 + dclk_out_rate = v_pixclk >> 2; 1619 + 1620 + dclk_rate = rk3588_calc_dclk(dclk_out_rate, 600000); 1621 + if (!dclk_rate) { 1622 + drm_err(vop2->drm, "DP dclk_out_rate out of range, dclk_out_rate: %ld KHZ\n", 1623 + dclk_out_rate); 1624 + return 0; 1625 + } 1626 + *dclk_out_div = dclk_rate / dclk_out_rate; 1627 + } else if (vop2_output_if_is_mipi(id)) { 1628 + if_pixclk_rate = dclk_core_rate / K; 1629 + /* 1630 + * dclk_core = dclk_out * K = if_pixclk * K = v_pixclk / 4 1631 + */ 1632 + dclk_out_rate = if_pixclk_rate; 1633 + /* 1634 + * dclk_rate = N * dclk_core_rate N = (1,2,4 ), 1635 + * we get a little factor here 1636 + */ 1637 + dclk_rate = rk3588_calc_dclk(dclk_out_rate, 600000); 1638 + if (!dclk_rate) { 1639 + drm_err(vop2->drm, "MIPI dclk out of range, dclk_out_rate: %ld KHZ\n", 1640 + dclk_out_rate); 1641 + return 0; 1642 + } 1643 + *dclk_out_div = dclk_rate / dclk_out_rate; 1644 + /* 1645 + * mipi pixclk == dclk_out 1646 + */ 1647 + *if_pixclk_div = 1; 1648 + } else if (vop2_output_if_is_dpi(id)) { 1649 + dclk_rate = v_pixclk; 1650 + } 1651 + 1652 + *dclk_core_div = dclk_rate / dclk_core_rate; 1653 + *if_pixclk_div = ilog2(*if_pixclk_div); 1654 + *if_dclk_div = ilog2(*if_dclk_div); 1655 + *dclk_core_div = ilog2(*dclk_core_div); 1656 + *dclk_out_div = ilog2(*dclk_out_div); 1657 + 1658 + drm_dbg(vop2->drm, "dclk: %ld, pixclk_div: %d, dclk_div: %d\n", 1659 + dclk_rate, *if_pixclk_div, *if_dclk_div); 1660 + 1661 + return dclk_rate; 1662 + } 1663 + 1664 + /* 1665 + * MIPI port mux on rk3588: 1666 + * 0: Video Port2 1667 + * 1: Video Port3 1668 + * 3: Video Port 1(MIPI1 only) 1669 + */ 1670 + static u32 rk3588_get_mipi_port_mux(int vp_id) 1671 + { 1672 + if (vp_id == 1) 1673 + return 3; 1674 + else if (vp_id == 3) 1675 + return 1; 1676 + else 1677 + return 0; 1678 + } 1679 + 1680 + static u32 rk3588_get_hdmi_pol(u32 flags) 1681 + { 1682 + u32 val; 1683 + 1684 + val = (flags & DRM_MODE_FLAG_NHSYNC) ? BIT(HSYNC_POSITIVE) : 0; 1685 + val |= (flags & DRM_MODE_FLAG_NVSYNC) ? BIT(VSYNC_POSITIVE) : 0; 1686 + 1687 + return val; 1688 + } 1689 + 1690 + static unsigned long rk3588_set_intf_mux(struct vop2_video_port *vp, int id, u32 polflags) 1691 + { 1692 + struct vop2 *vop2 = vp->vop2; 1693 + int dclk_core_div, dclk_out_div, if_pixclk_div, if_dclk_div; 1694 + unsigned long clock; 1695 + u32 die, dip, div, vp_clk_div, val; 1696 + 1697 + clock = rk3588_calc_cru_cfg(vp, id, &dclk_core_div, &dclk_out_div, 1698 + &if_pixclk_div, &if_dclk_div); 1699 + if (!clock) 1700 + return 0; 1701 + 1702 + vp_clk_div = FIELD_PREP(RK3588_VP_CLK_CTRL__DCLK_CORE_DIV, dclk_core_div); 1703 + vp_clk_div |= FIELD_PREP(RK3588_VP_CLK_CTRL__DCLK_OUT_DIV, dclk_out_div); 1704 + 1705 + die = vop2_readl(vop2, RK3568_DSP_IF_EN); 1706 + dip = vop2_readl(vop2, RK3568_DSP_IF_POL); 1707 + div = vop2_readl(vop2, RK3568_DSP_IF_CTRL); 1708 + 1709 + switch (id) { 1710 + case ROCKCHIP_VOP2_EP_HDMI0: 1711 + div &= ~RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV; 1712 + div &= ~RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV; 1713 + div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV, if_dclk_div); 1714 + div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV, if_pixclk_div); 1715 + die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX; 1716 + die |= RK3588_SYS_DSP_INFACE_EN_HDMI0 | 1717 + FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX, vp->id); 1718 + val = rk3588_get_hdmi_pol(polflags); 1719 + regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 1, 1)); 1720 + regmap_write(vop2->vo1_grf, RK3588_GRF_VO1_CON0, HIWORD_UPDATE(val, 6, 5)); 1721 + break; 1722 + case ROCKCHIP_VOP2_EP_HDMI1: 1723 + div &= ~RK3588_DSP_IF_EDP_HDMI1_DCLK_DIV; 1724 + div &= ~RK3588_DSP_IF_EDP_HDMI1_PCLK_DIV; 1725 + div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI1_DCLK_DIV, if_dclk_div); 1726 + div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI1_PCLK_DIV, if_pixclk_div); 1727 + die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX; 1728 + die |= RK3588_SYS_DSP_INFACE_EN_HDMI1 | 1729 + FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX, vp->id); 1730 + val = rk3588_get_hdmi_pol(polflags); 1731 + regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 4, 4)); 1732 + regmap_write(vop2->vo1_grf, RK3588_GRF_VO1_CON0, HIWORD_UPDATE(val, 8, 7)); 1733 + break; 1734 + case ROCKCHIP_VOP2_EP_EDP0: 1735 + div &= ~RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV; 1736 + div &= ~RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV; 1737 + div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV, if_dclk_div); 1738 + div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV, if_pixclk_div); 1739 + die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX; 1740 + die |= RK3588_SYS_DSP_INFACE_EN_EDP0 | 1741 + FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX, vp->id); 1742 + regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 0, 0)); 1743 + break; 1744 + case ROCKCHIP_VOP2_EP_EDP1: 1745 + div &= ~RK3588_DSP_IF_EDP_HDMI1_DCLK_DIV; 1746 + div &= ~RK3588_DSP_IF_EDP_HDMI1_PCLK_DIV; 1747 + div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV, if_dclk_div); 1748 + div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV, if_pixclk_div); 1749 + die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX; 1750 + die |= RK3588_SYS_DSP_INFACE_EN_EDP1 | 1751 + FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX, vp->id); 1752 + regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 3, 3)); 1753 + break; 1754 + case ROCKCHIP_VOP2_EP_MIPI0: 1755 + div &= ~RK3588_DSP_IF_MIPI0_PCLK_DIV; 1756 + div |= FIELD_PREP(RK3588_DSP_IF_MIPI0_PCLK_DIV, if_pixclk_div); 1757 + die &= ~RK3588_SYS_DSP_INFACE_EN_MIPI0_MUX; 1758 + val = rk3588_get_mipi_port_mux(vp->id); 1759 + die |= RK3588_SYS_DSP_INFACE_EN_MIPI0 | 1760 + FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_MIPI0_MUX, !!val); 1761 + break; 1762 + case ROCKCHIP_VOP2_EP_MIPI1: 1763 + div &= ~RK3588_DSP_IF_MIPI1_PCLK_DIV; 1764 + div |= FIELD_PREP(RK3588_DSP_IF_MIPI1_PCLK_DIV, if_pixclk_div); 1765 + die &= ~RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX; 1766 + val = rk3588_get_mipi_port_mux(vp->id); 1767 + die |= RK3588_SYS_DSP_INFACE_EN_MIPI1 | 1768 + FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX, val); 1769 + break; 1770 + case ROCKCHIP_VOP2_EP_DP0: 1771 + die &= ~RK3588_SYS_DSP_INFACE_EN_DP0_MUX; 1772 + die |= RK3588_SYS_DSP_INFACE_EN_DP0 | 1773 + FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_DP0_MUX, vp->id); 1774 + dip &= ~RK3588_DSP_IF_POL__DP0_PIN_POL; 1775 + dip |= FIELD_PREP(RK3588_DSP_IF_POL__DP0_PIN_POL, polflags); 1776 + break; 1777 + case ROCKCHIP_VOP2_EP_DP1: 1778 + die &= ~RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX; 1779 + die |= RK3588_SYS_DSP_INFACE_EN_MIPI1 | 1780 + FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX, vp->id); 1781 + dip &= ~RK3588_DSP_IF_POL__DP1_PIN_POL; 1782 + dip |= FIELD_PREP(RK3588_DSP_IF_POL__DP1_PIN_POL, polflags); 1783 + break; 1784 + default: 1785 + drm_err(vop2->drm, "Invalid interface id %d on vp%d\n", id, vp->id); 1786 + return 0; 1787 + } 1788 + 1789 + dip |= RK3568_DSP_IF_POL__CFG_DONE_IMD; 1790 + 1791 + vop2_vp_write(vp, RK3588_VP_CLK_CTRL, vp_clk_div); 1792 + vop2_writel(vop2, RK3568_DSP_IF_EN, die); 1793 + vop2_writel(vop2, RK3568_DSP_IF_CTRL, div); 1794 + vop2_writel(vop2, RK3568_DSP_IF_POL, dip); 1795 + 1796 + return clock; 1797 + } 1798 + 1799 + static unsigned long vop2_set_intf_mux(struct vop2_video_port *vp, int ep_id, u32 polflags) 1800 + { 1801 + struct vop2 *vop2 = vp->vop2; 1802 + 1803 + if (vop2->data->soc_id == 3566 || vop2->data->soc_id == 3568) 1804 + return rk3568_set_intf_mux(vp, ep_id, polflags); 1805 + else if (vop2->data->soc_id == 3588) 1806 + return rk3588_set_intf_mux(vp, ep_id, polflags); 1807 + else 1808 + return 0; 1649 1809 } 1650 1810 1651 1811 static int us_to_vertical_line(struct drm_display_mode *mode, int us) ··· 1968 1592 1969 1593 vop2->enable_count++; 1970 1594 1595 + vcstate->yuv_overlay = is_yuv_output(vcstate->bus_format); 1596 + 1971 1597 vop2_crtc_enable_irq(vp, VP_INT_POST_BUF_EMPTY); 1972 1598 1973 1599 polflags = 0; ··· 1983 1605 drm_for_each_encoder_mask(encoder, crtc->dev, crtc_state->encoder_mask) { 1984 1606 struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder); 1985 1607 1986 - rk3568_set_intf_mux(vp, rkencoder->crtc_endpoint_id, polflags); 1608 + /* 1609 + * for drive a high resolution(4KP120, 8K), vop on rk3588/rk3576 need 1610 + * process multi(1/2/4/8) pixels per cycle, so the dclk feed by the 1611 + * system cru may be the 1/2 or 1/4 of mode->clock. 1612 + */ 1613 + clock = vop2_set_intf_mux(vp, rkencoder->crtc_endpoint_id, polflags); 1987 1614 } 1988 1615 1616 + if (!clock) 1617 + return; 1618 + 1989 1619 if (vcstate->output_mode == ROCKCHIP_OUT_MODE_AAAA && 1990 - !(vp_data->feature & VOP_FEATURE_OUTPUT_10BIT)) 1620 + !(vp_data->feature & VOP2_VP_FEATURE_OUTPUT_10BIT)) 1991 1621 out_mode = ROCKCHIP_OUT_MODE_P888; 1992 1622 else 1993 1623 out_mode = vcstate->output_mode; ··· 2004 1618 2005 1619 if (vop2_output_uv_swap(vcstate->bus_format, vcstate->output_mode)) 2006 1620 dsp_ctrl |= RK3568_VP_DSP_CTRL__DSP_RB_SWAP; 1621 + if (vop2_output_rg_swap(vop2, vcstate->bus_format)) 1622 + dsp_ctrl |= RK3568_VP_DSP_CTRL__DSP_RG_SWAP; 2007 1623 2008 - if (is_yuv_output(vcstate->bus_format)) 1624 + if (vcstate->yuv_overlay) 2009 1625 dsp_ctrl |= RK3568_VP_DSP_CTRL__POST_DSP_OUT_R2Y; 2010 1626 2011 1627 vop2_dither_setup(crtc, &dsp_ctrl); ··· 2311 1923 u32 layer_sel = 0; 2312 1924 u32 port_sel; 2313 1925 unsigned int nlayer, ofs; 2314 - struct drm_display_mode *adjusted_mode; 2315 - u16 hsync_len; 2316 - u16 hdisplay; 2317 - u32 bg_dly; 2318 - u32 pre_scan_dly; 1926 + u32 ovl_ctrl; 2319 1927 int i; 2320 1928 struct vop2_video_port *vp0 = &vop2->vps[0]; 2321 1929 struct vop2_video_port *vp1 = &vop2->vps[1]; 2322 1930 struct vop2_video_port *vp2 = &vop2->vps[2]; 1931 + struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(vp->crtc.state); 2323 1932 2324 - adjusted_mode = &vp->crtc.state->adjusted_mode; 2325 - hsync_len = adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start; 2326 - hdisplay = adjusted_mode->crtc_hdisplay; 1933 + ovl_ctrl = vop2_readl(vop2, RK3568_OVL_CTRL); 1934 + ovl_ctrl |= RK3568_OVL_CTRL__LAYERSEL_REGDONE_IMD; 1935 + if (vcstate->yuv_overlay) 1936 + ovl_ctrl |= RK3568_OVL_CTRL__YUV_MODE(vp->id); 1937 + else 1938 + ovl_ctrl &= ~RK3568_OVL_CTRL__YUV_MODE(vp->id); 2327 1939 2328 - bg_dly = vp->data->pre_scan_max_dly[3]; 2329 - vop2_writel(vop2, RK3568_VP_BG_MIX_CTRL(vp->id), 2330 - FIELD_PREP(RK3568_VP_BG_MIX_CTRL__BG_DLY, bg_dly)); 1940 + vop2_writel(vop2, RK3568_OVL_CTRL, ovl_ctrl); 2331 1941 2332 - pre_scan_dly = ((bg_dly + (hdisplay >> 1) - 1) << 16) | hsync_len; 2333 - vop2_vp_write(vp, RK3568_VP_PRE_SCAN_HTIMING, pre_scan_dly); 2334 - 2335 - vop2_writel(vop2, RK3568_OVL_CTRL, 0); 2336 1942 port_sel = vop2_readl(vop2, RK3568_OVL_PORT_SEL); 2337 1943 port_sel &= RK3568_OVL_PORT_SEL__SEL_PORT; 2338 1944 ··· 2367 1985 port_sel &= ~RK3568_OVL_PORT_SEL__CLUSTER1; 2368 1986 port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__CLUSTER1, vp->id); 2369 1987 break; 1988 + case ROCKCHIP_VOP2_CLUSTER2: 1989 + port_sel &= ~RK3588_OVL_PORT_SEL__CLUSTER2; 1990 + port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__CLUSTER2, vp->id); 1991 + break; 1992 + case ROCKCHIP_VOP2_CLUSTER3: 1993 + port_sel &= ~RK3588_OVL_PORT_SEL__CLUSTER3; 1994 + port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__CLUSTER3, vp->id); 1995 + break; 2370 1996 case ROCKCHIP_VOP2_ESMART0: 2371 1997 port_sel &= ~RK3568_OVL_PORT_SEL__ESMART0; 2372 1998 port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__ESMART0, vp->id); ··· 2382 1992 case ROCKCHIP_VOP2_ESMART1: 2383 1993 port_sel &= ~RK3568_OVL_PORT_SEL__ESMART1; 2384 1994 port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__ESMART1, vp->id); 1995 + break; 1996 + case ROCKCHIP_VOP2_ESMART2: 1997 + port_sel &= ~RK3588_OVL_PORT_SEL__ESMART2; 1998 + port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__ESMART2, vp->id); 1999 + break; 2000 + case ROCKCHIP_VOP2_ESMART3: 2001 + port_sel &= ~RK3588_OVL_PORT_SEL__ESMART3; 2002 + port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__ESMART3, vp->id); 2385 2003 break; 2386 2004 case ROCKCHIP_VOP2_SMART0: 2387 2005 port_sel &= ~RK3568_OVL_PORT_SEL__SMART0; ··· 2416 2018 2417 2019 vop2_writel(vop2, RK3568_OVL_LAYER_SEL, layer_sel); 2418 2020 vop2_writel(vop2, RK3568_OVL_PORT_SEL, port_sel); 2419 - vop2_writel(vop2, RK3568_OVL_CTRL, RK3568_OVL_CTRL__LAYERSEL_REGDONE_IMD); 2420 2021 } 2421 2022 2422 2023 static void vop2_setup_dly_for_windows(struct vop2 *vop2) ··· 3127 2730 if (IS_ERR(vop2->lut_regs)) 3128 2731 return PTR_ERR(vop2->lut_regs); 3129 2732 } 2733 + if (vop2_data->feature & VOP2_FEATURE_HAS_SYS_GRF) { 2734 + vop2->sys_grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf"); 2735 + if (IS_ERR(vop2->sys_grf)) 2736 + return dev_err_probe(dev, PTR_ERR(vop2->sys_grf), "cannot get sys_grf"); 2737 + } 3130 2738 3131 - vop2->grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf"); 2739 + if (vop2_data->feature & VOP2_FEATURE_HAS_VOP_GRF) { 2740 + vop2->vop_grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,vop-grf"); 2741 + if (IS_ERR(vop2->vop_grf)) 2742 + return dev_err_probe(dev, PTR_ERR(vop2->vop_grf), "cannot get vop_grf"); 2743 + } 2744 + 2745 + if (vop2_data->feature & VOP2_FEATURE_HAS_VO1_GRF) { 2746 + vop2->vo1_grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,vo1-grf"); 2747 + if (IS_ERR(vop2->vo1_grf)) 2748 + return dev_err_probe(dev, PTR_ERR(vop2->vo1_grf), "cannot get vo1_grf"); 2749 + } 2750 + 2751 + if (vop2_data->feature & VOP2_FEATURE_HAS_SYS_PMU) { 2752 + vop2->sys_pmu = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,pmu"); 2753 + if (IS_ERR(vop2->sys_pmu)) 2754 + return dev_err_probe(dev, PTR_ERR(vop2->sys_pmu), "cannot get sys_pmu"); 2755 + } 3132 2756 3133 2757 vop2->hclk = devm_clk_get(vop2->dev, "hclk"); 3134 2758 if (IS_ERR(vop2->hclk)) { ··· 3161 2743 if (IS_ERR(vop2->aclk)) { 3162 2744 drm_err(vop2->drm, "failed to get aclk source\n"); 3163 2745 return PTR_ERR(vop2->aclk); 2746 + } 2747 + 2748 + vop2->pclk = devm_clk_get_optional(vop2->dev, "pclk_vop"); 2749 + if (IS_ERR(vop2->pclk)) { 2750 + drm_err(vop2->drm, "failed to get pclk source\n"); 2751 + return PTR_ERR(vop2->pclk); 3164 2752 } 3165 2753 3166 2754 vop2->irq = platform_get_irq(pdev, 0);
+84 -16
drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
··· 7 7 #ifndef _ROCKCHIP_DRM_VOP2_H 8 8 #define _ROCKCHIP_DRM_VOP2_H 9 9 10 - #include "rockchip_drm_vop.h" 11 - 12 10 #include <linux/regmap.h> 13 11 #include <drm/drm_modes.h> 12 + #include "rockchip_drm_vop.h" 14 13 15 - #define VOP_FEATURE_OUTPUT_10BIT BIT(0) 14 + #define VOP2_VP_FEATURE_OUTPUT_10BIT BIT(0) 15 + 16 + #define VOP2_FEATURE_HAS_SYS_GRF BIT(0) 17 + #define VOP2_FEATURE_HAS_VO0_GRF BIT(1) 18 + #define VOP2_FEATURE_HAS_VO1_GRF BIT(2) 19 + #define VOP2_FEATURE_HAS_VOP_GRF BIT(3) 20 + #define VOP2_FEATURE_HAS_SYS_PMU BIT(4) 16 21 17 22 #define WIN_FEATURE_AFBDC BIT(0) 18 23 #define WIN_FEATURE_CLUSTER BIT(1) 19 24 25 + #define HIWORD_UPDATE(v, h, l) ((GENMASK(h, l) << 16) | ((v) << (l))) 20 26 /* 21 27 * the delay number of a window in different mode. 22 28 */ ··· 44 38 VOP2_SCALE_DOWN_BIL, 45 39 VOP2_SCALE_DOWN_AVG, 46 40 }; 41 + 42 + /* 43 + * vop2 internal power domain id, 44 + * should be all none zero, 0 will be treat as invalid; 45 + */ 46 + #define VOP2_PD_CLUSTER0 BIT(0) 47 + #define VOP2_PD_CLUSTER1 BIT(1) 48 + #define VOP2_PD_CLUSTER2 BIT(2) 49 + #define VOP2_PD_CLUSTER3 BIT(3) 50 + #define VOP2_PD_DSC_8K BIT(5) 51 + #define VOP2_PD_DSC_4K BIT(6) 52 + #define VOP2_PD_ESMART BIT(7) 47 53 48 54 enum vop2_win_regs { 49 55 VOP2_WIN_ENABLE, ··· 157 139 158 140 struct vop2_data { 159 141 u8 nr_vps; 142 + u64 feature; 160 143 const struct vop2_win_data *win; 161 144 const struct vop2_video_port_data *vp; 162 145 struct vop_rect max_input; ··· 185 166 #define WB_YRGB_FIFO_FULL_INTR BIT(18) 186 167 #define WB_COMPLETE_INTR BIT(19) 187 168 188 - /* 189 - * display output interface supported by rockchip lcdc 190 - */ 191 - #define ROCKCHIP_OUT_MODE_P888 0 192 - #define ROCKCHIP_OUT_MODE_BT1120 0 193 - #define ROCKCHIP_OUT_MODE_P666 1 194 - #define ROCKCHIP_OUT_MODE_P565 2 195 - #define ROCKCHIP_OUT_MODE_BT656 5 196 - #define ROCKCHIP_OUT_MODE_S888 8 197 - #define ROCKCHIP_OUT_MODE_S888_DUMMY 12 198 - #define ROCKCHIP_OUT_MODE_YUV420 14 199 - /* for use special outface */ 200 - #define ROCKCHIP_OUT_MODE_AAAA 15 201 169 202 170 enum vop_csc_format { 203 171 CSC_BT601L, ··· 212 206 }; 213 207 214 208 #define RK3568_GRF_VO_CON1 0x0364 209 + 210 + #define RK3588_GRF_SOC_CON1 0x0304 211 + #define RK3588_GRF_VOP_CON2 0x08 212 + #define RK3588_GRF_VO1_CON0 0x00 213 + 215 214 /* System registers definition */ 216 215 #define RK3568_REG_CFG_DONE 0x000 217 216 #define RK3568_VERSION_INFO 0x004 ··· 225 214 #define RK3568_DSP_IF_EN 0x028 226 215 #define RK3568_DSP_IF_CTRL 0x02c 227 216 #define RK3568_DSP_IF_POL 0x030 217 + #define RK3588_SYS_PD_CTRL 0x034 228 218 #define RK3568_WB_CTRL 0x40 229 219 #define RK3568_WB_XSCAL_FACTOR 0x44 230 220 #define RK3568_WB_YRGB_MST 0x48 ··· 246 234 #define RK3568_VP_INT_RAW_STATUS(vp) (0xAC + (vp) * 0x10) 247 235 248 236 /* Video Port registers definition */ 237 + #define RK3568_VP0_CTRL_BASE 0x0C00 238 + #define RK3568_VP1_CTRL_BASE 0x0D00 239 + #define RK3568_VP2_CTRL_BASE 0x0E00 240 + #define RK3588_VP3_CTRL_BASE 0x0F00 249 241 #define RK3568_VP_DSP_CTRL 0x00 250 242 #define RK3568_VP_MIPI_CTRL 0x04 251 243 #define RK3568_VP_COLOR_BAR_CTRL 0x08 244 + #define RK3588_VP_CLK_CTRL 0x0C 252 245 #define RK3568_VP_3D_LUT_CTRL 0x10 253 246 #define RK3568_VP_3D_LUT_MST 0x20 254 247 #define RK3568_VP_DSP_BG 0x2C ··· 295 278 #define RK3568_SMART_DLY_NUM 0x6F8 296 279 297 280 /* Cluster register definition, offset relative to window base */ 281 + #define RK3568_CLUSTER0_CTRL_BASE 0x1000 282 + #define RK3568_CLUSTER1_CTRL_BASE 0x1200 283 + #define RK3588_CLUSTER2_CTRL_BASE 0x1400 284 + #define RK3588_CLUSTER3_CTRL_BASE 0x1600 285 + #define RK3568_ESMART0_CTRL_BASE 0x1800 286 + #define RK3568_ESMART1_CTRL_BASE 0x1A00 287 + #define RK3568_SMART0_CTRL_BASE 0x1C00 288 + #define RK3568_SMART1_CTRL_BASE 0x1E00 289 + #define RK3588_ESMART2_CTRL_BASE 0x1C00 290 + #define RK3588_ESMART3_CTRL_BASE 0x1E00 291 + 298 292 #define RK3568_CLUSTER_WIN_CTRL0 0x00 299 293 #define RK3568_CLUSTER_WIN_CTRL1 0x04 300 294 #define RK3568_CLUSTER_WIN_YRGB_MST 0x10 ··· 399 371 #define RK3568_VP_DSP_CTRL__DITHER_DOWN_EN BIT(17) 400 372 #define RK3568_VP_DSP_CTRL__PRE_DITHER_DOWN_EN BIT(16) 401 373 #define RK3568_VP_DSP_CTRL__POST_DSP_OUT_R2Y BIT(15) 374 + #define RK3568_VP_DSP_CTRL__DSP_RG_SWAP BIT(10) 402 375 #define RK3568_VP_DSP_CTRL__DSP_RB_SWAP BIT(9) 376 + #define RK3568_VP_DSP_CTRL__DSP_BG_SWAP BIT(8) 403 377 #define RK3568_VP_DSP_CTRL__DSP_INTERLACE BIT(7) 404 378 #define RK3568_VP_DSP_CTRL__DSP_FILED_POL BIT(6) 405 379 #define RK3568_VP_DSP_CTRL__P2I_EN BIT(5) 406 380 #define RK3568_VP_DSP_CTRL__CORE_DCLK_DIV BIT(4) 407 381 #define RK3568_VP_DSP_CTRL__OUT_MODE GENMASK(3, 0) 382 + 383 + #define RK3588_VP_CLK_CTRL__DCLK_OUT_DIV GENMASK(3, 2) 384 + #define RK3588_VP_CLK_CTRL__DCLK_CORE_DIV GENMASK(1, 0) 408 385 409 386 #define RK3568_VP_POST_SCL_CTRL__VSCALEDOWN BIT(1) 410 387 #define RK3568_VP_POST_SCL_CTRL__HSCALEDOWN BIT(0) ··· 429 396 #define RK3568_SYS_DSP_INFACE_EN_HDMI BIT(1) 430 397 #define RK3568_SYS_DSP_INFACE_EN_RGB BIT(0) 431 398 399 + #define RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX GENMASK(22, 21) 400 + #define RK3588_SYS_DSP_INFACE_EN_MIPI0_MUX GENMASK(20, 20) 401 + #define RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX GENMASK(19, 18) 402 + #define RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX GENMASK(17, 16) 403 + #define RK3588_SYS_DSP_INFACE_EN_DP1_MUX GENMASK(15, 14) 404 + #define RK3588_SYS_DSP_INFACE_EN_DP0_MUX GENMASK(13, 12) 405 + #define RK3588_SYS_DSP_INFACE_EN_DPI GENMASK(9, 8) 406 + #define RK3588_SYS_DSP_INFACE_EN_MIPI1 BIT(7) 407 + #define RK3588_SYS_DSP_INFACE_EN_MIPI0 BIT(6) 408 + #define RK3588_SYS_DSP_INFACE_EN_HDMI1 BIT(5) 409 + #define RK3588_SYS_DSP_INFACE_EN_EDP1 BIT(4) 410 + #define RK3588_SYS_DSP_INFACE_EN_HDMI0 BIT(3) 411 + #define RK3588_SYS_DSP_INFACE_EN_EDP0 BIT(2) 412 + #define RK3588_SYS_DSP_INFACE_EN_DP1 BIT(1) 413 + #define RK3588_SYS_DSP_INFACE_EN_DP0 BIT(0) 414 + 415 + #define RK3588_DSP_IF_MIPI1_PCLK_DIV GENMASK(27, 26) 416 + #define RK3588_DSP_IF_MIPI0_PCLK_DIV GENMASK(25, 24) 417 + #define RK3588_DSP_IF_EDP_HDMI1_PCLK_DIV GENMASK(22, 22) 418 + #define RK3588_DSP_IF_EDP_HDMI1_DCLK_DIV GENMASK(21, 20) 419 + #define RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV GENMASK(18, 18) 420 + #define RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV GENMASK(17, 16) 421 + 432 422 #define RK3568_DSP_IF_POL__MIPI_PIN_POL GENMASK(19, 16) 433 423 #define RK3568_DSP_IF_POL__EDP_PIN_POL GENMASK(15, 12) 434 424 #define RK3568_DSP_IF_POL__HDMI_PIN_POL GENMASK(7, 4) 435 425 #define RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL GENMASK(3, 0) 426 + 427 + #define RK3588_DSP_IF_POL__DP1_PIN_POL GENMASK(14, 12) 428 + #define RK3588_DSP_IF_POL__DP0_PIN_POL GENMASK(10, 8) 436 429 437 430 #define RK3568_VP0_MIPI_CTRL__DCLK_DIV2_PHASE_LOCK BIT(5) 438 431 #define RK3568_VP0_MIPI_CTRL__DCLK_DIV2 BIT(4) ··· 474 415 #define VOP2_COLOR_KEY_MASK BIT(31) 475 416 476 417 #define RK3568_OVL_CTRL__LAYERSEL_REGDONE_IMD BIT(28) 418 + #define RK3568_OVL_CTRL__YUV_MODE(vp) BIT(vp) 477 419 478 420 #define RK3568_VP_BG_MIX_CTRL__BG_DLY GENMASK(31, 24) 479 421 480 422 #define RK3568_OVL_PORT_SEL__SEL_PORT GENMASK(31, 16) 481 423 #define RK3568_OVL_PORT_SEL__SMART1 GENMASK(31, 30) 482 424 #define RK3568_OVL_PORT_SEL__SMART0 GENMASK(29, 28) 425 + #define RK3588_OVL_PORT_SEL__ESMART3 GENMASK(31, 30) 426 + #define RK3588_OVL_PORT_SEL__ESMART2 GENMASK(29, 28) 483 427 #define RK3568_OVL_PORT_SEL__ESMART1 GENMASK(27, 26) 484 428 #define RK3568_OVL_PORT_SEL__ESMART0 GENMASK(25, 24) 429 + #define RK3588_OVL_PORT_SEL__CLUSTER3 GENMASK(23, 22) 430 + #define RK3588_OVL_PORT_SEL__CLUSTER2 GENMASK(21, 20) 485 431 #define RK3568_OVL_PORT_SEL__CLUSTER1 GENMASK(19, 18) 486 432 #define RK3568_OVL_PORT_SEL__CLUSTER0 GENMASK(17, 16) 487 433 #define RK3568_OVL_PORT_SET__PORT2_MUX GENMASK(11, 8) ··· 498 434 #define RK3568_CLUSTER_DLY_NUM__CLUSTER1_0 GENMASK(23, 16) 499 435 #define RK3568_CLUSTER_DLY_NUM__CLUSTER0_1 GENMASK(15, 8) 500 436 #define RK3568_CLUSTER_DLY_NUM__CLUSTER0_0 GENMASK(7, 0) 437 + 438 + #define RK3568_CLUSTER_WIN_CTRL0__WIN0_EN BIT(0) 439 + 440 + #define RK3568_SMART_REGION0_CTRL__WIN0_EN BIT(0) 501 441 502 442 #define RK3568_SMART_DLY_NUM__SMART1 GENMASK(31, 24) 503 443 #define RK3568_SMART_DLY_NUM__SMART0 GENMASK(23, 16)
-1
drivers/gpu/drm/rockchip/rockchip_lvds.c
··· 27 27 #include <drm/drm_simple_kms_helper.h> 28 28 29 29 #include "rockchip_drm_drv.h" 30 - #include "rockchip_drm_vop.h" 31 30 #include "rockchip_lvds.h" 32 31 33 32 #define DISPLAY_OUTPUT_RGB 0
-1
drivers/gpu/drm/rockchip/rockchip_rgb.c
··· 19 19 #include <drm/drm_simple_kms_helper.h> 20 20 21 21 #include "rockchip_drm_drv.h" 22 - #include "rockchip_drm_vop.h" 23 22 #include "rockchip_rgb.h" 24 23 25 24 struct rockchip_rgb {
+222 -1
drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
··· 34 34 DRM_FORMAT_Y210, /* yuv422_10bit non-Linear mode only */ 35 35 }; 36 36 37 + static const uint32_t formats_esmart[] = { 38 + DRM_FORMAT_XRGB8888, 39 + DRM_FORMAT_ARGB8888, 40 + DRM_FORMAT_XBGR8888, 41 + DRM_FORMAT_ABGR8888, 42 + DRM_FORMAT_RGB888, 43 + DRM_FORMAT_BGR888, 44 + DRM_FORMAT_RGB565, 45 + DRM_FORMAT_BGR565, 46 + DRM_FORMAT_NV12, /* yuv420_8bit linear mode, 2 plane */ 47 + DRM_FORMAT_NV21, /* yvu420_8bit linear mode, 2 plane */ 48 + DRM_FORMAT_NV16, /* yuv422_8bit linear mode, 2 plane */ 49 + DRM_FORMAT_NV61, /* yvu422_8bit linear mode, 2 plane */ 50 + DRM_FORMAT_NV20, /* yuv422_10bit linear mode, 2 plane, no padding */ 51 + DRM_FORMAT_NV24, /* yuv444_8bit linear mode, 2 plane */ 52 + DRM_FORMAT_NV42, /* yvu444_8bit linear mode, 2 plane */ 53 + DRM_FORMAT_NV30, /* yuv444_10bit linear mode, 2 plane, no padding */ 54 + DRM_FORMAT_NV15, /* yuv420_10bit linear mode, 2 plane, no padding */ 55 + DRM_FORMAT_YVYU, /* yuv422_8bit[YVYU] linear mode */ 56 + DRM_FORMAT_VYUY, /* yuv422_8bit[VYUY] linear mode */ 57 + DRM_FORMAT_YUYV, /* yuv422_8bit[YUYV] linear mode */ 58 + DRM_FORMAT_UYVY, /* yuv422_8bit[UYVY] linear mode */ 59 + }; 60 + 37 61 static const uint32_t formats_rk356x_esmart[] = { 38 62 DRM_FORMAT_XRGB8888, 39 63 DRM_FORMAT_ARGB8888, ··· 136 112 static const struct vop2_video_port_data rk3568_vop_video_ports[] = { 137 113 { 138 114 .id = 0, 139 - .feature = VOP_FEATURE_OUTPUT_10BIT, 115 + .feature = VOP2_VP_FEATURE_OUTPUT_10BIT, 140 116 .gamma_lut_len = 1024, 141 117 .cubic_lut_len = 9 * 9 * 9, 142 118 .max_output = { 4096, 2304 }, ··· 260 236 }, 261 237 }; 262 238 239 + static const struct vop2_video_port_data rk3588_vop_video_ports[] = { 240 + { 241 + .id = 0, 242 + .feature = VOP2_VP_FEATURE_OUTPUT_10BIT, 243 + .gamma_lut_len = 1024, 244 + .cubic_lut_len = 9 * 9 * 9, /* 9x9x9 */ 245 + .max_output = { 4096, 2304 }, 246 + /* hdr2sdr sdr2hdr hdr2hdr sdr2sdr */ 247 + .pre_scan_max_dly = { 76, 65, 65, 54 }, 248 + .offset = 0xc00, 249 + }, { 250 + .id = 1, 251 + .feature = VOP2_VP_FEATURE_OUTPUT_10BIT, 252 + .gamma_lut_len = 1024, 253 + .cubic_lut_len = 729, /* 9x9x9 */ 254 + .max_output = { 4096, 2304 }, 255 + .pre_scan_max_dly = { 76, 65, 65, 54 }, 256 + .offset = 0xd00, 257 + }, { 258 + .id = 2, 259 + .feature = VOP2_VP_FEATURE_OUTPUT_10BIT, 260 + .gamma_lut_len = 1024, 261 + .cubic_lut_len = 17 * 17 * 17, /* 17x17x17 */ 262 + .max_output = { 4096, 2304 }, 263 + .pre_scan_max_dly = { 52, 52, 52, 52 }, 264 + .offset = 0xe00, 265 + }, { 266 + .id = 3, 267 + .gamma_lut_len = 1024, 268 + .max_output = { 2048, 1536 }, 269 + .pre_scan_max_dly = { 52, 52, 52, 52 }, 270 + .offset = 0xf00, 271 + }, 272 + }; 273 + 274 + /* 275 + * rk3588 vop with 4 cluster, 4 esmart win. 276 + * Every cluster can work as 4K win or split into two win. 277 + * All win in cluster support AFBCD. 278 + * 279 + * Every esmart win and smart win support 4 Multi-region. 280 + * 281 + * Scale filter mode: 282 + * 283 + * * Cluster: bicubic for horizontal scale up, others use bilinear 284 + * * ESmart: 285 + * * nearest-neighbor/bilinear/bicubic for scale up 286 + * * nearest-neighbor/bilinear/average for scale down 287 + * 288 + * AXI Read ID assignment: 289 + * Two AXI bus: 290 + * AXI0 is a read/write bus with a higher performance. 291 + * AXI1 is a read only bus. 292 + * 293 + * Every window on a AXI bus must assigned two unique 294 + * read id(yrgb_id/uv_id, valid id are 0x1~0xe). 295 + * 296 + * AXI0: 297 + * Cluster0/1, Esmart0/1, WriteBack 298 + * 299 + * AXI 1: 300 + * Cluster2/3, Esmart2/3 301 + * 302 + */ 303 + static const struct vop2_win_data rk3588_vop_win_data[] = { 304 + { 305 + .name = "Cluster0-win0", 306 + .phys_id = ROCKCHIP_VOP2_CLUSTER0, 307 + .base = 0x1000, 308 + .formats = formats_cluster, 309 + .nformats = ARRAY_SIZE(formats_cluster), 310 + .format_modifiers = format_modifiers_afbc, 311 + .layer_sel_id = 0, 312 + .supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 | 313 + DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y, 314 + .max_upscale_factor = 4, 315 + .max_downscale_factor = 4, 316 + .dly = { 4, 26, 29 }, 317 + .type = DRM_PLANE_TYPE_PRIMARY, 318 + .feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER, 319 + }, { 320 + .name = "Cluster1-win0", 321 + .phys_id = ROCKCHIP_VOP2_CLUSTER1, 322 + .base = 0x1200, 323 + .formats = formats_cluster, 324 + .nformats = ARRAY_SIZE(formats_cluster), 325 + .format_modifiers = format_modifiers_afbc, 326 + .layer_sel_id = 1, 327 + .supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 | 328 + DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y, 329 + .type = DRM_PLANE_TYPE_PRIMARY, 330 + .max_upscale_factor = 4, 331 + .max_downscale_factor = 4, 332 + .dly = { 4, 26, 29 }, 333 + .feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER, 334 + }, { 335 + .name = "Cluster2-win0", 336 + .phys_id = ROCKCHIP_VOP2_CLUSTER2, 337 + .base = 0x1400, 338 + .formats = formats_cluster, 339 + .nformats = ARRAY_SIZE(formats_cluster), 340 + .format_modifiers = format_modifiers_afbc, 341 + .layer_sel_id = 4, 342 + .supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 | 343 + DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y, 344 + .type = DRM_PLANE_TYPE_PRIMARY, 345 + .max_upscale_factor = 4, 346 + .max_downscale_factor = 4, 347 + .dly = { 4, 26, 29 }, 348 + .feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER, 349 + }, { 350 + .name = "Cluster3-win0", 351 + .phys_id = ROCKCHIP_VOP2_CLUSTER3, 352 + .base = 0x1600, 353 + .formats = formats_cluster, 354 + .nformats = ARRAY_SIZE(formats_cluster), 355 + .format_modifiers = format_modifiers_afbc, 356 + .layer_sel_id = 5, 357 + .supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 | 358 + DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y, 359 + .type = DRM_PLANE_TYPE_PRIMARY, 360 + .max_upscale_factor = 4, 361 + .max_downscale_factor = 4, 362 + .dly = { 4, 26, 29 }, 363 + .feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER, 364 + }, { 365 + .name = "Esmart0-win0", 366 + .phys_id = ROCKCHIP_VOP2_ESMART0, 367 + .formats = formats_esmart, 368 + .nformats = ARRAY_SIZE(formats_esmart), 369 + .format_modifiers = format_modifiers, 370 + .base = 0x1800, 371 + .layer_sel_id = 2, 372 + .supported_rotations = DRM_MODE_REFLECT_Y, 373 + .type = DRM_PLANE_TYPE_OVERLAY, 374 + .max_upscale_factor = 8, 375 + .max_downscale_factor = 8, 376 + .dly = { 23, 45, 48 }, 377 + }, { 378 + .name = "Esmart1-win0", 379 + .phys_id = ROCKCHIP_VOP2_ESMART1, 380 + .formats = formats_esmart, 381 + .nformats = ARRAY_SIZE(formats_esmart), 382 + .format_modifiers = format_modifiers, 383 + .base = 0x1a00, 384 + .layer_sel_id = 3, 385 + .supported_rotations = DRM_MODE_REFLECT_Y, 386 + .type = DRM_PLANE_TYPE_OVERLAY, 387 + .max_upscale_factor = 8, 388 + .max_downscale_factor = 8, 389 + .dly = { 23, 45, 48 }, 390 + }, { 391 + .name = "Esmart2-win0", 392 + .phys_id = ROCKCHIP_VOP2_ESMART2, 393 + .base = 0x1c00, 394 + .formats = formats_esmart, 395 + .nformats = ARRAY_SIZE(formats_esmart), 396 + .format_modifiers = format_modifiers, 397 + .layer_sel_id = 6, 398 + .supported_rotations = DRM_MODE_REFLECT_Y, 399 + .type = DRM_PLANE_TYPE_OVERLAY, 400 + .max_upscale_factor = 8, 401 + .max_downscale_factor = 8, 402 + .dly = { 23, 45, 48 }, 403 + }, { 404 + .name = "Esmart3-win0", 405 + .phys_id = ROCKCHIP_VOP2_ESMART3, 406 + .formats = formats_esmart, 407 + .nformats = ARRAY_SIZE(formats_esmart), 408 + .format_modifiers = format_modifiers, 409 + .base = 0x1e00, 410 + .layer_sel_id = 7, 411 + .supported_rotations = DRM_MODE_REFLECT_Y, 412 + .type = DRM_PLANE_TYPE_OVERLAY, 413 + .max_upscale_factor = 8, 414 + .max_downscale_factor = 8, 415 + .dly = { 23, 45, 48 }, 416 + }, 417 + }; 418 + 263 419 static const struct vop2_data rk3566_vop = { 420 + .feature = VOP2_FEATURE_HAS_SYS_GRF, 264 421 .nr_vps = 3, 265 422 .max_input = { 4096, 2304 }, 266 423 .max_output = { 4096, 2304 }, ··· 452 247 }; 453 248 454 249 static const struct vop2_data rk3568_vop = { 250 + .feature = VOP2_FEATURE_HAS_SYS_GRF, 455 251 .nr_vps = 3, 456 252 .max_input = { 4096, 2304 }, 457 253 .max_output = { 4096, 2304 }, ··· 462 256 .soc_id = 3568, 463 257 }; 464 258 259 + static const struct vop2_data rk3588_vop = { 260 + .feature = VOP2_FEATURE_HAS_SYS_GRF | VOP2_FEATURE_HAS_VO1_GRF | 261 + VOP2_FEATURE_HAS_VOP_GRF | VOP2_FEATURE_HAS_SYS_PMU, 262 + .nr_vps = 4, 263 + .max_input = { 4096, 4320 }, 264 + .max_output = { 4096, 4320 }, 265 + .vp = rk3588_vop_video_ports, 266 + .win = rk3588_vop_win_data, 267 + .win_size = ARRAY_SIZE(rk3588_vop_win_data), 268 + .soc_id = 3588, 269 + }; 270 + 465 271 static const struct of_device_id vop2_dt_match[] = { 466 272 { 467 273 .compatible = "rockchip,rk3566-vop", ··· 481 263 }, { 482 264 .compatible = "rockchip,rk3568-vop", 483 265 .data = &rk3568_vop, 266 + }, { 267 + .compatible = "rockchip,rk3588-vop", 268 + .data = &rk3588_vop 484 269 }, { 485 270 }, 486 271 };
+11 -1
drivers/gpu/drm/vc4/vc4_hdmi.c
··· 672 672 return &new_state->base; 673 673 } 674 674 675 + static void vc4_hdmi_connector_destroy_state(struct drm_connector *connector, 676 + struct drm_connector_state *state) 677 + { 678 + struct vc4_hdmi_connector_state *vc4_state = 679 + conn_state_to_vc4_hdmi_conn_state(state); 680 + 681 + __drm_atomic_helper_connector_destroy_state(state); 682 + kfree(vc4_state); 683 + } 684 + 675 685 static const struct drm_connector_funcs vc4_hdmi_connector_funcs = { 676 686 .fill_modes = drm_helper_probe_single_connector_modes, 677 687 .reset = vc4_hdmi_connector_reset, 678 688 .atomic_duplicate_state = vc4_hdmi_connector_duplicate_state, 679 - .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 689 + .atomic_destroy_state = vc4_hdmi_connector_destroy_state, 680 690 .atomic_get_property = vc4_hdmi_connector_get_property, 681 691 .atomic_set_property = vc4_hdmi_connector_set_property, 682 692 };
+15 -10
drivers/gpu/drm/vkms/vkms_writeback.c
··· 30 30 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 31 31 }; 32 32 33 - static int vkms_wb_encoder_atomic_check(struct drm_encoder *encoder, 34 - struct drm_crtc_state *crtc_state, 35 - struct drm_connector_state *conn_state) 33 + static int vkms_wb_atomic_check(struct drm_connector *connector, 34 + struct drm_atomic_state *state) 36 35 { 36 + struct drm_connector_state *conn_state = 37 + drm_atomic_get_new_connector_state(state, connector); 38 + struct drm_crtc_state *crtc_state; 37 39 struct drm_framebuffer *fb; 38 - const struct drm_display_mode *mode = &crtc_state->mode; 40 + const struct drm_display_mode *mode; 39 41 int ret; 40 42 41 43 if (!conn_state->writeback_job || !conn_state->writeback_job->fb) 42 44 return 0; 45 + 46 + if (!conn_state->crtc) 47 + return 0; 48 + 49 + crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc); 50 + mode = &crtc_state->mode; 43 51 44 52 fb = conn_state->writeback_job->fb; 45 53 if (fb->width != mode->hdisplay || fb->height != mode->vdisplay) { ··· 56 48 return -EINVAL; 57 49 } 58 50 59 - ret = drm_atomic_helper_check_wb_encoder_state(encoder, conn_state); 51 + ret = drm_atomic_helper_check_wb_connector_state(connector, state); 60 52 if (ret < 0) 61 53 return ret; 62 54 63 55 return 0; 64 56 } 65 - 66 - static const struct drm_encoder_helper_funcs vkms_wb_encoder_helper_funcs = { 67 - .atomic_check = vkms_wb_encoder_atomic_check, 68 - }; 69 57 70 58 static int vkms_wb_connector_get_modes(struct drm_connector *connector) 71 59 { ··· 165 161 .prepare_writeback_job = vkms_wb_prepare_job, 166 162 .cleanup_writeback_job = vkms_wb_cleanup_job, 167 163 .atomic_commit = vkms_wb_atomic_commit, 164 + .atomic_check = vkms_wb_atomic_check, 168 165 }; 169 166 170 167 int vkms_enable_writeback_connector(struct vkms_device *vkmsdev) ··· 176 171 177 172 return drm_writeback_connector_init(&vkmsdev->drm, wb, 178 173 &vkms_wb_connector_funcs, 179 - &vkms_wb_encoder_helper_funcs, 174 + NULL, 180 175 vkms_wb_formats, 181 176 ARRAY_SIZE(vkms_wb_formats), 182 177 1);
+1 -1
drivers/usb/typec/mux/Kconfig
··· 40 40 tristate "On Semiconductor NB7VPQ904M Type-C redriver driver" 41 41 depends on I2C 42 42 depends on DRM || DRM=n 43 - select DRM_AUX_BRIDGE if DRM_BRIDGE 43 + select DRM_AUX_BRIDGE if DRM_BRIDGE && OF 44 44 select REGMAP_I2C 45 45 help 46 46 Say Y or M if your system has a On Semiconductor NB7VPQ904M Type-C
+1 -1
drivers/usb/typec/tcpm/Kconfig
··· 80 80 tristate "Qualcomm PMIC USB Type-C Port Controller Manager driver" 81 81 depends on ARCH_QCOM || COMPILE_TEST 82 82 depends on DRM || DRM=n 83 - select DRM_AUX_HPD_BRIDGE if DRM_BRIDGE 83 + select DRM_AUX_HPD_BRIDGE if DRM_BRIDGE && OF 84 84 help 85 85 A Type-C port and Power Delivery driver which aggregates two 86 86 discrete pieces of silicon in the PM8150b PMIC block: the
+1 -1
include/drm/bridge/aux-bridge.h
··· 26 26 static inline struct device *drm_dp_hpd_bridge_register(struct device *parent, 27 27 struct device_node *np) 28 28 { 29 - return 0; 29 + return NULL; 30 30 } 31 31 32 32 static inline void drm_aux_hpd_bridge_notify(struct device *dev, enum drm_connector_status status)
+2 -3
include/drm/drm_atomic_helper.h
··· 49 49 50 50 int drm_atomic_helper_check_modeset(struct drm_device *dev, 51 51 struct drm_atomic_state *state); 52 - int 53 - drm_atomic_helper_check_wb_encoder_state(struct drm_encoder *encoder, 54 - struct drm_connector_state *conn_state); 52 + int drm_atomic_helper_check_wb_connector_state(struct drm_connector *connector, 53 + struct drm_atomic_state *state); 55 54 int drm_atomic_helper_check_plane_state(struct drm_plane_state *plane_state, 56 55 const struct drm_crtc_state *crtc_state, 57 56 int min_scale,
+3 -3
include/drm/drm_modeset_helper_vtables.h
··· 134 134 * Since this function is both called from the check phase of an atomic 135 135 * commit, and the mode validation in the probe paths it is not allowed 136 136 * to look at anything else but the passed-in mode, and validate it 137 - * against configuration-invariant hardward constraints. Any further 137 + * against configuration-invariant hardware constraints. Any further 138 138 * limits which depend upon the configuration can only be checked in 139 139 * @mode_fixup or @atomic_check. 140 140 * ··· 550 550 * Since this function is both called from the check phase of an atomic 551 551 * commit, and the mode validation in the probe paths it is not allowed 552 552 * to look at anything else but the passed-in mode, and validate it 553 - * against configuration-invariant hardward constraints. Any further 553 + * against configuration-invariant hardware constraints. Any further 554 554 * limits which depend upon the configuration can only be checked in 555 555 * @mode_fixup or @atomic_check. 556 556 * ··· 1474 1474 * swapped into the various state pointers. The passed in state 1475 1475 * therefore contains copies of the old/previous state. This hook should 1476 1476 * commit the new state into hardware. Note that the helpers have 1477 - * already waited for preceeding atomic commits and fences, but drivers 1477 + * already waited for preceding atomic commits and fences, but drivers 1478 1478 * can add more waiting calls at the start of their implementation, e.g. 1479 1479 * to wait for driver-internal request for implicit syncing, before 1480 1480 * starting to commit the update to the hardware.
+4
include/dt-bindings/soc/rockchip,vop2.h
··· 10 10 #define ROCKCHIP_VOP2_EP_LVDS0 5 11 11 #define ROCKCHIP_VOP2_EP_MIPI1 6 12 12 #define ROCKCHIP_VOP2_EP_LVDS1 7 13 + #define ROCKCHIP_VOP2_EP_HDMI1 8 14 + #define ROCKCHIP_VOP2_EP_EDP1 9 15 + #define ROCKCHIP_VOP2_EP_DP0 10 16 + #define ROCKCHIP_VOP2_EP_DP1 11 13 17 14 18 #endif /* __DT_BINDINGS_ROCKCHIP_VOP2_H */
+5 -5
include/uapi/drm/drm_fourcc.h
··· 54 54 * Format modifiers may change any property of the buffer, including the number 55 55 * of planes and/or the required allocation size. Format modifiers are 56 56 * vendor-namespaced, and as such the relationship between a fourcc code and a 57 - * modifier is specific to the modifer being used. For example, some modifiers 57 + * modifier is specific to the modifier being used. For example, some modifiers 58 58 * may preserve meaning - such as number of planes - from the fourcc code, 59 59 * whereas others may not. 60 60 * ··· 79 79 * format. 80 80 * - Higher-level programs interfacing with KMS/GBM/EGL/Vulkan/etc: these users 81 81 * see modifiers as opaque tokens they can check for equality and intersect. 82 - * These users musn't need to know to reason about the modifier value 82 + * These users mustn't need to know to reason about the modifier value 83 83 * (i.e. they are not expected to extract information out of the modifier). 84 84 * 85 85 * Vendors should document their modifier usage in as much detail as ··· 540 540 * This is a tiled layout using 4Kb tiles in row-major layout. 541 541 * Within the tile pixels are laid out in 16 256 byte units / sub-tiles which 542 542 * are arranged in four groups (two wide, two high) with column-major layout. 543 - * Each group therefore consits out of four 256 byte units, which are also laid 543 + * Each group therefore consists out of four 256 byte units, which are also laid 544 544 * out as 2x2 column-major. 545 545 * 256 byte units are made out of four 64 byte blocks of pixels, producing 546 546 * either a square block or a 2:1 unit. ··· 1103 1103 */ 1104 1104 1105 1105 /* 1106 - * The top 4 bits (out of the 56 bits alloted for specifying vendor specific 1106 + * The top 4 bits (out of the 56 bits allotted for specifying vendor specific 1107 1107 * modifiers) denote the category for modifiers. Currently we have three 1108 1108 * categories of modifiers ie AFBC, MISC and AFRC. We can have a maximum of 1109 1109 * sixteen different categories. ··· 1419 1419 * Amlogic FBC Memory Saving mode 1420 1420 * 1421 1421 * Indicates the storage is packed when pixel size is multiple of word 1422 - * boudaries, i.e. 8bit should be stored in this mode to save allocation 1422 + * boundaries, i.e. 8bit should be stored in this mode to save allocation 1423 1423 * memory. 1424 1424 * 1425 1425 * This mode reduces body layout to 3072 bytes per 64x32 superblock with
+9 -9
include/uapi/drm/drm_mode.h
··· 36 36 /** 37 37 * DOC: overview 38 38 * 39 - * DRM exposes many UAPI and structure definition to have a consistent 40 - * and standardized interface with user. 39 + * DRM exposes many UAPI and structure definitions to have a consistent 40 + * and standardized interface with users. 41 41 * Userspace can refer to these structure definitions and UAPI formats 42 - * to communicate to driver 42 + * to communicate to drivers. 43 43 */ 44 44 45 45 #define DRM_CONNECTOR_NAME_LEN 32 ··· 540 540 /* the PROP_ATOMIC flag is used to hide properties from userspace that 541 541 * is not aware of atomic properties. This is mostly to work around 542 542 * older userspace (DDX drivers) that read/write each prop they find, 543 - * witout being aware that this could be triggering a lengthy modeset. 543 + * without being aware that this could be triggering a lengthy modeset. 544 544 */ 545 545 #define DRM_MODE_PROP_ATOMIC 0x80000000 546 546 ··· 664 664 }; 665 665 666 666 #define DRM_MODE_FB_INTERLACED (1<<0) /* for interlaced framebuffers */ 667 - #define DRM_MODE_FB_MODIFIERS (1<<1) /* enables ->modifer[] */ 667 + #define DRM_MODE_FB_MODIFIERS (1<<1) /* enables ->modifier[] */ 668 668 669 669 /** 670 670 * struct drm_mode_fb_cmd2 - Frame-buffer metadata. ··· 881 881 * These are coded as unsigned 16-bit values in units of 882 882 * 0.00002, where 0x0000 represents zero and 0xC350 883 883 * represents 1.0000. 884 - * @display_primaries.x: X cordinate of color primary. 885 - * @display_primaries.y: Y cordinate of color primary. 884 + * @display_primaries.x: X coordinate of color primary. 885 + * @display_primaries.y: Y coordinate of color primary. 886 886 */ 887 887 struct { 888 888 __u16 x, y; ··· 892 892 * These are coded as unsigned 16-bit values in units of 893 893 * 0.00002, where 0x0000 represents zero and 0xC350 894 894 * represents 1.0000. 895 - * @white_point.x: X cordinate of whitepoint of color primary. 896 - * @white_point.y: Y cordinate of whitepoint of color primary. 895 + * @white_point.x: X coordinate of whitepoint of color primary. 896 + * @white_point.y: Y coordinate of whitepoint of color primary. 897 897 */ 898 898 struct { 899 899 __u16 x, y;