diff options
author | Dave Airlie <airlied@redhat.com> | 2023-10-31 01:47:49 +0100 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2023-10-31 01:47:50 +0100 |
commit | 915b6d034b54425b42705c8772ddb7a121759eb1 (patch) | |
tree | ce5ee56eeed1f482a9b872b8472f5edf9269baca | |
parent | usb: typec: altmodes/displayport: fixup drm internal api change vs new user. (diff) | |
parent | drm/amdgpu: move buffer funcs setting up a level (diff) | |
download | linux-915b6d034b54425b42705c8772ddb7a121759eb1.tar.xz linux-915b6d034b54425b42705c8772ddb7a121759eb1.zip |
Merge tag 'drm-misc-next-2023-10-27' of git://anongit.freedesktop.org/drm/drm-misc into drm-next
drm-misc-next for v6.7-rc1:
drm-misc-next-2023-10-19 + following:
UAPI Changes:
Cross-subsystem Changes:
- Convert fbdev drivers to use fbdev i/o mem helpers.
Core Changes:
- Use cross-references for macros in docs.
- Make drm_client_buffer_addb use addfb2.
- Add NV20 and NV30 YUV formats.
- Documentation updates for create_dumb ioctl.
- CI fixes.
- Allow variable number of run-queues in scheduler.
Driver Changes:
- Rename drm/ast constants.
- Make ili9882t its own driver.
- Assorted fixes in ivpu, vc4, bridge/synopsis, amdgpu.
- Add planar formats to rockchip.
Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/3d92fae8-9b1b-4165-9ca8-5fda11ee146b@linux.intel.com
192 files changed, 4684 insertions, 1675 deletions
diff --git a/Documentation/devicetree/bindings/display/bridge/fsl,imx93-mipi-dsi.yaml b/Documentation/devicetree/bindings/display/bridge/fsl,imx93-mipi-dsi.yaml new file mode 100644 index 000000000000..d6e51d0cf546 --- /dev/null +++ b/Documentation/devicetree/bindings/display/bridge/fsl,imx93-mipi-dsi.yaml @@ -0,0 +1,115 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/bridge/fsl,imx93-mipi-dsi.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Freescale i.MX93 specific extensions to Synopsys Designware MIPI DSI + +maintainers: + - Liu Ying <victor.liu@nxp.com> + +description: | + There is a Synopsys Designware MIPI DSI Host Controller and a Synopsys + Designware MIPI DPHY embedded in Freescale i.MX93 SoC. Some configurations + and extensions to them are controlled by i.MX93 media blk-ctrl. + +allOf: + - $ref: snps,dw-mipi-dsi.yaml# + +properties: + compatible: + const: fsl,imx93-mipi-dsi + + clocks: + items: + - description: apb clock + - description: pixel clock + - description: PHY configuration clock + - description: PHY reference clock + + clock-names: + items: + - const: pclk + - const: pix + - const: phy_cfg + - const: phy_ref + + interrupts: + maxItems: 1 + + fsl,media-blk-ctrl: + $ref: /schemas/types.yaml#/definitions/phandle + description: + i.MX93 media blk-ctrl, as a syscon, controls pixel component bit map + configurations from LCDIF display controller to the MIPI DSI host + controller and MIPI DPHY PLL related configurations through PLL SoC + interface. + + power-domains: + maxItems: 1 + +required: + - compatible + - interrupts + - fsl,media-blk-ctrl + - power-domains + +unevaluatedProperties: false + +examples: + - | + #include <dt-bindings/clock/imx93-clock.h> + #include <dt-bindings/gpio/gpio.h> + #include <dt-bindings/interrupt-controller/arm-gic.h> + #include <dt-bindings/power/fsl,imx93-power.h> + + dsi@4ae10000 { + compatible = "fsl,imx93-mipi-dsi"; + reg = <0x4ae10000 0x10000>; + interrupts = <GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX93_CLK_MIPI_DSI_GATE>, + <&clk IMX93_CLK_MEDIA_DISP_PIX>, + <&clk IMX93_CLK_MIPI_PHY_CFG>, + <&clk IMX93_CLK_24M>; + clock-names = "pclk", "pix", "phy_cfg", "phy_ref"; + fsl,media-blk-ctrl = <&media_blk_ctrl>; + power-domains = <&media_blk_ctrl IMX93_MEDIABLK_PD_MIPI_DSI>; + #address-cells = <1>; + #size-cells = <0>; + + panel@0 { + compatible = "raydium,rm67191"; + reg = <0>; + reset-gpios = <&adp5585gpio 6 GPIO_ACTIVE_LOW>; + dsi-lanes = <4>; + video-mode = <2>; + + port { + panel_in: endpoint { + remote-endpoint = <&dsi_out>; + }; + }; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + dsi_to_lcdif: endpoint { + remote-endpoint = <&lcdif_to_dsi>; + }; + }; + + port@1 { + reg = <1>; + + dsi_out: endpoint { + remote-endpoint = <&panel_in>; + }; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/display/panel/rocktech,jh057n00900.yaml b/Documentation/devicetree/bindings/display/panel/rocktech,jh057n00900.yaml index 5ea74426b1d5..97cccd8a8479 100644 --- a/Documentation/devicetree/bindings/display/panel/rocktech,jh057n00900.yaml +++ b/Documentation/devicetree/bindings/display/panel/rocktech,jh057n00900.yaml @@ -22,6 +22,8 @@ properties: enum: # Anberic RG353V-V2 5.0" 640x480 TFT LCD panel - anbernic,rg353v-panel-v2 + # Powkiddy RGB30 3.0" 720x720 TFT LCD panel + - powkiddy,rgb30-panel # Rocktech JH057N00900 5.5" 720x1440 TFT LCD panel - rocktech,jh057n00900 # Xingbangda XBD599 5.99" 720x1440 TFT LCD panel diff --git a/Documentation/devicetree/bindings/display/solomon,ssd-common.yaml b/Documentation/devicetree/bindings/display/solomon,ssd-common.yaml new file mode 100644 index 000000000000..3e6998481a75 --- /dev/null +++ b/Documentation/devicetree/bindings/display/solomon,ssd-common.yaml @@ -0,0 +1,42 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/solomon,ssd-common.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Common properties for Solomon OLED Display Controllers + +maintainers: + - Javier Martinez Canillas <javierm@redhat.com> + +properties: + reg: + maxItems: 1 + + reset-gpios: + maxItems: 1 + + # Only required for SPI + dc-gpios: + description: + GPIO connected to the controller's D/C# (Data/Command) pin, + that is needed for 4-wire SPI to tell the controller if the + data sent is for a command register or the display data RAM + maxItems: 1 + + solomon,height: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Height in pixel of the screen driven by the controller. + The default value is controller-dependent. + + solomon,width: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Width in pixel of the screen driven by the controller. + The default value is controller-dependent. + +allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml# + +additionalProperties: true diff --git a/Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml b/Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml index 20e2bd15d4d2..3afbb52d1b7f 100644 --- a/Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml +++ b/Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml @@ -27,38 +27,12 @@ properties: - solomon,ssd1307 - solomon,ssd1309 - reg: - maxItems: 1 - pwms: maxItems: 1 - reset-gpios: - maxItems: 1 - - # Only required for SPI - dc-gpios: - description: - GPIO connected to the controller's D/C# (Data/Command) pin, - that is needed for 4-wire SPI to tell the controller if the - data sent is for a command register or the display data RAM - maxItems: 1 - vbat-supply: description: The supply for VBAT - solomon,height: - $ref: /schemas/types.yaml#/definitions/uint32 - description: - Height in pixel of the screen driven by the controller. - The default value is controller-dependent. - - solomon,width: - $ref: /schemas/types.yaml#/definitions/uint32 - description: - Width in pixel of the screen driven by the controller. - The default value is controller-dependent. - solomon,page-offset: $ref: /schemas/types.yaml#/definitions/uint32 default: 1 @@ -148,7 +122,7 @@ required: - reg allOf: - - $ref: /schemas/spi/spi-peripheral-props.yaml# + - $ref: solomon,ssd-common.yaml# - if: properties: diff --git a/Documentation/devicetree/bindings/display/solomon,ssd132x.yaml b/Documentation/devicetree/bindings/display/solomon,ssd132x.yaml new file mode 100644 index 000000000000..0aa41bd9ddca --- /dev/null +++ b/Documentation/devicetree/bindings/display/solomon,ssd132x.yaml @@ -0,0 +1,89 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/solomon,ssd132x.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Solomon SSD132x OLED Display Controllers + +maintainers: + - Javier Martinez Canillas <javierm@redhat.com> + +properties: + compatible: + - enum: + - solomon,ssd1322 + - solomon,ssd1325 + - solomon,ssd1327 + +required: + - compatible + - reg + +allOf: + - $ref: solomon,ssd-common.yaml# + + - if: + properties: + compatible: + contains: + const: solomon,ssd1322 + then: + properties: + width: + default: 480 + height: + default: 128 + + - if: + properties: + compatible: + contains: + const: solomon,ssd1325 + then: + properties: + width: + default: 128 + height: + default: 80 + + - if: + properties: + compatible: + contains: + const: solomon,ssd1327 + then: + properties: + width: + default: 128 + height: + default: 128 + +unevaluatedProperties: false + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + oled@3c { + compatible = "solomon,ssd1327"; + reg = <0x3c>; + reset-gpios = <&gpio2 7>; + }; + + }; + - | + spi { + #address-cells = <1>; + #size-cells = <0>; + + oled@0 { + compatible = "solomon,ssd1327"; + reg = <0x0>; + reset-gpios = <&gpio2 7>; + dc-gpios = <&gpio2 8>; + spi-max-frequency = <10000000>; + }; + }; diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index 573578db9509..25fd2dc378f5 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -1081,6 +1081,8 @@ patternProperties: description: Powertip Tech. Corp. "^powervr,.*": description: PowerVR (deprecated, use img) + "^powkiddy,.*": + description: Powkiddy "^primux,.*": description: Primux Trading, S.L. "^probox2,.*": diff --git a/Documentation/gpu/automated_testing.rst b/Documentation/gpu/automated_testing.rst index 469b6fb65c30..240e29d5ba68 100644 --- a/Documentation/gpu/automated_testing.rst +++ b/Documentation/gpu/automated_testing.rst @@ -67,6 +67,19 @@ Lists the tests that for a given driver on a specific hardware revision are known to behave unreliably. These tests won't cause a job to fail regardless of the result. They will still be run. +Each new flake entry must be associated with a link to the email reporting the +bug to the author of the affected driver, the board name or Device Tree name of +the board, the first kernel version affected, and an approximation of the +failure rate. + +They should be provided under the following format:: + + # Bug Report: $LORE_OR_PATCHWORK_URL + # Board Name: broken-board.dtb + # Version: 6.6-rc1 + # Failure Rate: 100 + flaky-test + drivers/gpu/drm/ci/${DRIVER_NAME}-${HW_REVISION}-skips.txt ----------------------------------------------------------- @@ -86,10 +99,13 @@ https://gitlab.freedesktop.org/janedoe/linux/-/settings/ci_cd), change the CI/CD configuration file from .gitlab-ci.yml to drivers/gpu/drm/ci/gitlab-ci.yml. -3. Next time you push to this repository, you will see a CI pipeline being +3. Request to be added to the drm/ci-ok group so that your user has the +necessary privileges to run the CI on https://gitlab.freedesktop.org/drm/ci-ok + +4. Next time you push to this repository, you will see a CI pipeline being created (eg. https://gitlab.freedesktop.org/janedoe/linux/-/pipelines) -4. The various jobs will be run and when the pipeline is finished, all jobs +5. The various jobs will be run and when the pipeline is finished, all jobs should be green unless a regression has been found. diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst index a0c83fc48126..270d320407c7 100644 --- a/Documentation/gpu/drm-kms.rst +++ b/Documentation/gpu/drm-kms.rst @@ -360,6 +360,8 @@ Format Functions Reference .. kernel-doc:: drivers/gpu/drm/drm_fourcc.c :export: +.. _kms_dumb_buffer_objects: + Dumb Buffer Objects =================== diff --git a/Documentation/gpu/drm-uapi.rst b/Documentation/gpu/drm-uapi.rst index 632989df3727..370d820be248 100644 --- a/Documentation/gpu/drm-uapi.rst +++ b/Documentation/gpu/drm-uapi.rst @@ -527,12 +527,12 @@ VBlank event handling The DRM core exposes two vertical blank related ioctls: -DRM_IOCTL_WAIT_VBLANK +:c:macro:`DRM_IOCTL_WAIT_VBLANK` This takes a struct drm_wait_vblank structure as its argument, and it is used to block or request a signal when a specified vblank event occurs. -DRM_IOCTL_MODESET_CTL +:c:macro:`DRM_IOCTL_MODESET_CTL` This was only used for user-mode-settind drivers around modesetting changes to allow the kernel to update the vblank interrupt after mode setting, since on many devices the vertical blank counter is @@ -555,8 +555,8 @@ The index is used in cases where a densely packed identifier for a CRTC is needed, for instance a bitmask of CRTC's. The member possible_crtcs of struct drm_mode_get_plane is an example. -DRM_IOCTL_MODE_GETRESOURCES populates a structure with an array of CRTC ID's, -and the CRTC index is its position in this array. +:c:macro:`DRM_IOCTL_MODE_GETRESOURCES` populates a structure with an array of +CRTC ID's, and the CRTC index is its position in this array. .. kernel-doc:: include/uapi/drm/drm.h :internal: diff --git a/Documentation/gpu/drm-vm-bind-async.rst b/Documentation/gpu/drm-vm-bind-async.rst new file mode 100644 index 000000000000..3d709d02099c --- /dev/null +++ b/Documentation/gpu/drm-vm-bind-async.rst @@ -0,0 +1,309 @@ +.. SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +==================== +Asynchronous VM_BIND +==================== + +Nomenclature: +============= + +* ``VRAM``: On-device memory. Sometimes referred to as device local memory. + +* ``gpu_vm``: A virtual GPU address space. Typically per process, but + can be shared by multiple processes. + +* ``VM_BIND``: An operation or a list of operations to modify a gpu_vm using + an IOCTL. The operations include mapping and unmapping system- or + VRAM memory. + +* ``syncobj``: A container that abstracts synchronization objects. The + synchronization objects can be either generic, like dma-fences or + driver specific. A syncobj typically indicates the type of the + underlying synchronization object. + +* ``in-syncobj``: Argument to a VM_BIND IOCTL, the VM_BIND operation waits + for these before starting. + +* ``out-syncobj``: Argument to a VM_BIND_IOCTL, the VM_BIND operation + signals these when the bind operation is complete. + +* ``dma-fence``: A cross-driver synchronization object. A basic + understanding of dma-fences is required to digest this + document. Please refer to the ``DMA Fences`` section of the + :doc:`dma-buf doc </driver-api/dma-buf>`. + +* ``memory fence``: A synchronization object, different from a dma-fence. + A memory fence uses the value of a specified memory location to determine + signaled status. A memory fence can be awaited and signaled by both + the GPU and CPU. Memory fences are sometimes referred to as + user-fences, userspace-fences or gpu futexes and do not necessarily obey + the dma-fence rule of signaling within a "reasonable amount of time". + The kernel should thus avoid waiting for memory fences with locks held. + +* ``long-running workload``: A workload that may take more than the + current stipulated dma-fence maximum signal delay to complete and + which therefore needs to set the gpu_vm or the GPU execution context in + a certain mode that disallows completion dma-fences. + +* ``exec function``: An exec function is a function that revalidates all + affected gpu_vmas, submits a GPU command batch and registers the + dma_fence representing the GPU command's activity with all affected + dma_resvs. For completeness, although not covered by this document, + it's worth mentioning that an exec function may also be the + revalidation worker that is used by some drivers in compute / + long-running mode. + +* ``bind context``: A context identifier used for the VM_BIND + operation. VM_BIND operations that use the same bind context can be + assumed, where it matters, to complete in order of submission. No such + assumptions can be made for VM_BIND operations using separate bind contexts. + +* ``UMD``: User-mode driver. + +* ``KMD``: Kernel-mode driver. + + +Synchronous / Asynchronous VM_BIND operation +============================================ + +Synchronous VM_BIND +___________________ +With Synchronous VM_BIND, the VM_BIND operations all complete before the +IOCTL returns. A synchronous VM_BIND takes neither in-fences nor +out-fences. Synchronous VM_BIND may block and wait for GPU operations; +for example swap-in or clearing, or even previous binds. + +Asynchronous VM_BIND +____________________ +Asynchronous VM_BIND accepts both in-syncobjs and out-syncobjs. While the +IOCTL may return immediately, the VM_BIND operations wait for the in-syncobjs +before modifying the GPU page-tables, and signal the out-syncobjs when +the modification is done in the sense that the next exec function that +awaits for the out-syncobjs will see the change. Errors are reported +synchronously. +In low-memory situations the implementation may block, performing the +VM_BIND synchronously, because there might not be enough memory +immediately available for preparing the asynchronous operation. + +If the VM_BIND IOCTL takes a list or an array of operations as an argument, +the in-syncobjs needs to signal before the first operation starts to +execute, and the out-syncobjs signal after the last operation +completes. Operations in the operation list can be assumed, where it +matters, to complete in order. + +Since asynchronous VM_BIND operations may use dma-fences embedded in +out-syncobjs and internally in KMD to signal bind completion, any +memory fences given as VM_BIND in-fences need to be awaited +synchronously before the VM_BIND ioctl returns, since dma-fences, +required to signal in a reasonable amount of time, can never be made +to depend on memory fences that don't have such a restriction. + +The purpose of an Asynchronous VM_BIND operation is for user-mode +drivers to be able to pipeline interleaved gpu_vm modifications and +exec functions. For long-running workloads, such pipelining of a bind +operation is not allowed and any in-fences need to be awaited +synchronously. The reason for this is twofold. First, any memory +fences gated by a long-running workload and used as in-syncobjs for the +VM_BIND operation will need to be awaited synchronously anyway (see +above). Second, any dma-fences used as in-syncobjs for VM_BIND +operations for long-running workloads will not allow for pipelining +anyway since long-running workloads don't allow for dma-fences as +out-syncobjs, so while theoretically possible the use of them is +questionable and should be rejected until there is a valuable use-case. +Note that this is not a limitation imposed by dma-fence rules, but +rather a limitation imposed to keep KMD implementation simple. It does +not affect using dma-fences as dependencies for the long-running +workload itself, which is allowed by dma-fence rules, but rather for +the VM_BIND operation only. + +An asynchronous VM_BIND operation may take substantial time to +complete and signal the out_fence. In particular if the operation is +deeply pipelined behind other VM_BIND operations and workloads +submitted using exec functions. In that case, UMD might want to avoid a +subsequent VM_BIND operation to be queued behind the first one if +there are no explicit dependencies. In order to circumvent such a queue-up, a +VM_BIND implementation may allow for VM_BIND contexts to be +created. For each context, VM_BIND operations will be guaranteed to +complete in the order they were submitted, but that is not the case +for VM_BIND operations executing on separate VM_BIND contexts. Instead +KMD will attempt to execute such VM_BIND operations in parallel but +leaving no guarantee that they will actually be executed in +parallel. There may be internal implicit dependencies that only KMD knows +about, for example page-table structure changes. A way to attempt +to avoid such internal dependencies is to have different VM_BIND +contexts use separate regions of a VM. + +Also for VM_BINDS for long-running gpu_vms the user-mode driver should typically +select memory fences as out-fences since that gives greater flexibility for +the kernel mode driver to inject other operations into the bind / +unbind operations. Like for example inserting breakpoints into batch +buffers. The workload execution can then easily be pipelined behind +the bind completion using the memory out-fence as the signal condition +for a GPU semaphore embedded by UMD in the workload. + +There is no difference in the operations supported or in +multi-operation support between asynchronous VM_BIND and synchronous VM_BIND. + +Multi-operation VM_BIND IOCTL error handling and interrupts +=========================================================== + +The VM_BIND operations of the IOCTL may error for various reasons, for +example due to lack of resources to complete and due to interrupted +waits. +In these situations UMD should preferably restart the IOCTL after +taking suitable action. +If UMD has over-committed a memory resource, an -ENOSPC error will be +returned, and UMD may then unbind resources that are not used at the +moment and rerun the IOCTL. On -EINTR, UMD should simply rerun the +IOCTL and on -ENOMEM user-space may either attempt to free known +system memory resources or fail. In case of UMD deciding to fail a +bind operation, due to an error return, no additional action is needed +to clean up the failed operation, and the VM is left in the same state +as it was before the failing IOCTL. +Unbind operations are guaranteed not to return any errors due to +resource constraints, but may return errors due to, for example, +invalid arguments or the gpu_vm being banned. +In the case an unexpected error happens during the asynchronous bind +process, the gpu_vm will be banned, and attempts to use it after banning +will return -ENOENT. + +Example: The Xe VM_BIND uAPI +============================ + +Starting with the VM_BIND operation struct, the IOCTL call can take +zero, one or many such operations. A zero number means only the +synchronization part of the IOCTL is carried out: an asynchronous +VM_BIND updates the syncobjects, whereas a sync VM_BIND waits for the +implicit dependencies to be fulfilled. + +.. code-block:: c + + struct drm_xe_vm_bind_op { + /** + * @obj: GEM object to operate on, MBZ for MAP_USERPTR, MBZ for UNMAP + */ + __u32 obj; + + /** @pad: MBZ */ + __u32 pad; + + union { + /** + * @obj_offset: Offset into the object for MAP. + */ + __u64 obj_offset; + + /** @userptr: user virtual address for MAP_USERPTR */ + __u64 userptr; + }; + + /** + * @range: Number of bytes from the object to bind to addr, MBZ for UNMAP_ALL + */ + __u64 range; + + /** @addr: Address to operate on, MBZ for UNMAP_ALL */ + __u64 addr; + + /** + * @tile_mask: Mask for which tiles to create binds for, 0 == All tiles, + * only applies to creating new VMAs + */ + __u64 tile_mask; + + /* Map (parts of) an object into the GPU virtual address range. + #define XE_VM_BIND_OP_MAP 0x0 + /* Unmap a GPU virtual address range */ + #define XE_VM_BIND_OP_UNMAP 0x1 + /* + * Map a CPU virtual address range into a GPU virtual + * address range. + */ + #define XE_VM_BIND_OP_MAP_USERPTR 0x2 + /* Unmap a gem object from the VM. */ + #define XE_VM_BIND_OP_UNMAP_ALL 0x3 + /* + * Make the backing memory of an address range resident if + * possible. Note that this doesn't pin backing memory. + */ + #define XE_VM_BIND_OP_PREFETCH 0x4 + + /* Make the GPU map readonly. */ + #define XE_VM_BIND_FLAG_READONLY (0x1 << 16) + /* + * Valid on a faulting VM only, do the MAP operation immediately rather + * than deferring the MAP to the page fault handler. + */ + #define XE_VM_BIND_FLAG_IMMEDIATE (0x1 << 17) + /* + * When the NULL flag is set, the page tables are setup with a special + * bit which indicates writes are dropped and all reads return zero. In + * the future, the NULL flags will only be valid for XE_VM_BIND_OP_MAP + * operations, the BO handle MBZ, and the BO offset MBZ. This flag is + * intended to implement VK sparse bindings. + */ + #define XE_VM_BIND_FLAG_NULL (0x1 << 18) + /** @op: Operation to perform (lower 16 bits) and flags (upper 16 bits) */ + __u32 op; + + /** @mem_region: Memory region to prefetch VMA to, instance not a mask */ + __u32 region; + + /** @reserved: Reserved */ + __u64 reserved[2]; + }; + + +The VM_BIND IOCTL argument itself, looks like follows. Note that for +synchronous VM_BIND, the num_syncs and syncs fields must be zero. Here +the ``exec_queue_id`` field is the VM_BIND context discussed previously +that is used to facilitate out-of-order VM_BINDs. + +.. code-block:: c + + struct drm_xe_vm_bind { + /** @extensions: Pointer to the first extension struct, if any */ + __u64 extensions; + + /** @vm_id: The ID of the VM to bind to */ + __u32 vm_id; + + /** + * @exec_queue_id: exec_queue_id, must be of class DRM_XE_ENGINE_CLASS_VM_BIND + * and exec queue must have same vm_id. If zero, the default VM bind engine + * is used. + */ + __u32 exec_queue_id; + + /** @num_binds: number of binds in this IOCTL */ + __u32 num_binds; + + /* If set, perform an async VM_BIND, if clear a sync VM_BIND */ + #define XE_VM_BIND_IOCTL_FLAG_ASYNC (0x1 << 0) + + /** @flag: Flags controlling all operations in this ioctl. */ + __u32 flags; + + union { + /** @bind: used if num_binds == 1 */ + struct drm_xe_vm_bind_op bind; + + /** + * @vector_of_binds: userptr to array of struct + * drm_xe_vm_bind_op if num_binds > 1 + */ + __u64 vector_of_binds; + }; + + /** @num_syncs: amount of syncs to wait for or to signal on completion. */ + __u32 num_syncs; + + /** @pad2: MBZ */ + __u32 pad2; + + /** @syncs: pointer to struct drm_xe_sync array */ + __u64 syncs; + + /** @reserved: Reserved */ + __u64 reserved[2]; + }; diff --git a/Documentation/gpu/implementation_guidelines.rst b/Documentation/gpu/implementation_guidelines.rst new file mode 100644 index 000000000000..138e637dcc6b --- /dev/null +++ b/Documentation/gpu/implementation_guidelines.rst @@ -0,0 +1,9 @@ +.. SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +=========================================================== +Misc DRM driver uAPI- and feature implementation guidelines +=========================================================== + +.. toctree:: + + drm-vm-bind-async diff --git a/Documentation/gpu/index.rst b/Documentation/gpu/index.rst index e45ff0915246..37e383ccf73f 100644 --- a/Documentation/gpu/index.rst +++ b/Documentation/gpu/index.rst @@ -18,6 +18,7 @@ GPU Driver Developer's Guide vga-switcheroo vgaarbiter automated_testing + implementation_guidelines todo rfc/index diff --git a/Documentation/gpu/rfc/xe.rst b/Documentation/gpu/rfc/xe.rst index b67f8e6a1825..c29113a0ac30 100644 --- a/Documentation/gpu/rfc/xe.rst +++ b/Documentation/gpu/rfc/xe.rst @@ -97,8 +97,8 @@ memory fences. Ideally with helper support so people don't get it wrong in all possible ways. As a key measurable result, the benefits of ASYNC VM_BIND and a discussion of -various flavors, error handling and a sample API should be documented here or in -a separate document pointed to by this document. +various flavors, error handling and sample API suggestions are documented in +:doc:`The ASYNC VM_BIND document </gpu/drm-vm-bind-async>`. Userptr integration and vm_bind ------------------------------- diff --git a/MAINTAINERS b/MAINTAINERS index 8297b9198612..78f2a91e6a1d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6632,6 +6632,7 @@ S: Maintained B: https://gitlab.freedesktop.org/drm/msm/-/issues T: git https://gitlab.freedesktop.org/drm/msm.git F: Documentation/devicetree/bindings/display/msm/ +F: drivers/gpu/drm/ci/xfails/msm* F: drivers/gpu/drm/msm/ F: include/uapi/drm/msm_drm.h @@ -6783,7 +6784,8 @@ DRM DRIVER FOR SOLOMON SSD130X OLED DISPLAYS M: Javier Martinez Canillas <javierm@redhat.com> S: Maintained T: git git://anongit.freedesktop.org/drm/drm-misc -F: Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml +F: Documentation/devicetree/bindings/display/solomon,ssd-common.yaml +F: Documentation/devicetree/bindings/display/solomon,ssd13*.yaml F: drivers/gpu/drm/solomon/ssd130x* DRM DRIVER FOR ST-ERICSSON MCDE @@ -6918,6 +6920,7 @@ T: git git://anongit.freedesktop.org/drm/drm-misc F: Documentation/devicetree/bindings/display/amlogic,meson-dw-hdmi.yaml F: Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml F: Documentation/gpu/meson.rst +F: drivers/gpu/drm/ci/xfails/meson* F: drivers/gpu/drm/meson/ DRM DRIVERS FOR ATMEL HLCDC @@ -7030,6 +7033,7 @@ L: dri-devel@lists.freedesktop.org L: linux-mediatek@lists.infradead.org (moderated for non-subscribers) S: Supported F: Documentation/devicetree/bindings/display/mediatek/ +F: drivers/gpu/drm/ci/xfails/mediatek* F: drivers/gpu/drm/mediatek/ F: drivers/phy/mediatek/phy-mtk-dp.c F: drivers/phy/mediatek/phy-mtk-hdmi* @@ -7070,6 +7074,7 @@ L: dri-devel@lists.freedesktop.org S: Maintained T: git git://anongit.freedesktop.org/drm/drm-misc F: Documentation/devicetree/bindings/display/rockchip/ +F: drivers/gpu/drm/ci/xfails/rockchip* F: drivers/gpu/drm/rockchip/ DRM DRIVERS FOR STI @@ -7166,7 +7171,7 @@ F: Documentation/devicetree/bindings/display/xlnx/ F: drivers/gpu/drm/xlnx/ DRM GPU SCHEDULER -M: Luben Tuikov <luben.tuikov@amd.com> +M: Luben Tuikov <ltuikov89@gmail.com> L: dri-devel@lists.freedesktop.org S: Maintained T: git git://anongit.freedesktop.org/drm/drm-misc @@ -10512,6 +10517,7 @@ C: irc://irc.oftc.net/intel-gfx T: git git://anongit.freedesktop.org/drm-intel F: Documentation/ABI/testing/sysfs-driver-intel-i915-hwmon F: Documentation/gpu/i915.rst +F: drivers/gpu/drm/ci/xfails/i915* F: drivers/gpu/drm/i915/ F: include/drm/i915* F: include/uapi/drm/i915_drm.h @@ -13544,7 +13550,7 @@ F: drivers/usb/mtu3/ MEGACHIPS STDPXXXX-GE-B850V3-FW LVDS/DP++ BRIDGES M: Peter Senna Tschudin <peter.senna@gmail.com> -M: Martin Donnelly <martin.donnelly@ge.com> +M: Ian Ray <ian.ray@ge.com> M: Martyn Welch <martyn.welch@collabora.co.uk> S: Maintained F: Documentation/devicetree/bindings/display/bridge/megachips-stdpxxxx-ge-b850v3-fw.txt @@ -17885,6 +17891,7 @@ C: irc://irc.oftc.net/radeon T: git https://gitlab.freedesktop.org/agd5f/linux.git F: Documentation/gpu/amdgpu/ F: drivers/gpu/drm/amd/ +F: drivers/gpu/drm/ci/xfails/amd* F: drivers/gpu/drm/radeon/ F: include/uapi/drm/amdgpu_drm.h F: include/uapi/drm/radeon_drm.h @@ -22864,6 +22871,7 @@ L: dri-devel@lists.freedesktop.org L: virtualization@lists.linux-foundation.org S: Maintained T: git git://anongit.freedesktop.org/drm/drm-misc +F: drivers/gpu/drm/ci/xfails/virtio* F: drivers/gpu/drm/virtio/ F: include/uapi/linux/virtio_gpu.h diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index a789119e6483..424429c3053a 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -835,6 +835,7 @@ CONFIG_DRM_PANEL_BOE_TV101WUM_NL6=m CONFIG_DRM_PANEL_LVDS=m CONFIG_DRM_PANEL_SIMPLE=m CONFIG_DRM_PANEL_EDP=m +CONFIG_DRM_PANEL_ILITEK_ILI9882T=m CONFIG_DRM_PANEL_MANTIX_MLAF057WE51=m CONFIG_DRM_PANEL_RAYDIUM_RM67191=m CONFIG_DRM_PANEL_SITRONIX_ST7703=m diff --git a/drivers/accel/ivpu/TODO b/drivers/accel/ivpu/TODO deleted file mode 100644 index 9077217ae10f..000000000000 --- a/drivers/accel/ivpu/TODO +++ /dev/null @@ -1,11 +0,0 @@ -- Move to threaded_irqs to mitigate potential infinite loop in ivpu_ipc_irq_handler() -- Implement support for BLOB IDs -- Add debugfs support to improve debugging and testing -- Add tracing events for performance debugging -- Implement HW based scheduling support -- Use syncobjs for submit/sync -- Refactor IPC protocol to improve message latency -- Implement BO cache and MADVISE IOCTL -- Add support for user allocated buffers using prime import and dma-buf heaps -- Refactor struct ivpu_bo to use struct drm_gem_shmem_object -- Add driver/device documentation diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index ad44f7f331ca..790603017653 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -131,6 +131,22 @@ static int ivpu_get_capabilities(struct ivpu_device *vdev, struct drm_ivpu_param return 0; } +static int ivpu_get_core_clock_rate(struct ivpu_device *vdev, u64 *clk_rate) +{ + int ret; + + ret = ivpu_rpm_get_if_active(vdev); + if (ret < 0) + return ret; + + *clk_rate = ret ? ivpu_hw_reg_pll_freq_get(vdev) : 0; + + if (ret) + ivpu_rpm_put(vdev); + + return 0; +} + static int ivpu_get_param_ioctl(struct drm_device *dev, void *data, struct drm_file *file) { struct ivpu_file_priv *file_priv = file->driver_priv; @@ -154,7 +170,7 @@ static int ivpu_get_param_ioctl(struct drm_device *dev, void *data, struct drm_f args->value = vdev->platform; break; case DRM_IVPU_PARAM_CORE_CLOCK_RATE: - args->value = ivpu_hw_reg_pll_freq_get(vdev); + ret = ivpu_get_core_clock_rate(vdev, &args->value); break; case DRM_IVPU_PARAM_NUM_CONTEXTS: args->value = ivpu_get_context_count(vdev); diff --git a/drivers/accel/ivpu/ivpu_fw.c b/drivers/accel/ivpu/ivpu_fw.c index f33614110d57..691da521dde5 100644 --- a/drivers/accel/ivpu/ivpu_fw.c +++ b/drivers/accel/ivpu/ivpu_fw.c @@ -321,13 +321,13 @@ void ivpu_fw_load(struct ivpu_device *vdev) struct ivpu_fw_info *fw = vdev->fw; u64 image_end_offset = fw->image_load_offset + fw->image_size; - memset(fw->mem->kvaddr, 0, fw->image_load_offset); - memcpy(fw->mem->kvaddr + fw->image_load_offset, + memset(ivpu_bo_vaddr(fw->mem), 0, fw->image_load_offset); + memcpy(ivpu_bo_vaddr(fw->mem) + fw->image_load_offset, fw->file->data + FW_FILE_IMAGE_OFFSET, fw->image_size); if (IVPU_WA(clear_runtime_mem)) { - u8 *start = fw->mem->kvaddr + image_end_offset; - u64 size = fw->mem->base.size - image_end_offset; + u8 *start = ivpu_bo_vaddr(fw->mem) + image_end_offset; + u64 size = ivpu_bo_size(fw->mem) - image_end_offset; memset(start, 0, size); } @@ -451,10 +451,10 @@ void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params vdev->hw->ranges.global.start; boot_params->ipc_header_area_start = ipc_mem_rx->vpu_addr; - boot_params->ipc_header_area_size = ipc_mem_rx->base.size / 2; + boot_params->ipc_header_area_size = ivpu_bo_size(ipc_mem_rx) / 2; - boot_params->ipc_payload_area_start = ipc_mem_rx->vpu_addr + ipc_mem_rx->base.size / 2; - boot_params->ipc_payload_area_size = ipc_mem_rx->base.size / 2; + boot_params->ipc_payload_area_start = ipc_mem_rx->vpu_addr + ivpu_bo_size(ipc_mem_rx) / 2; + boot_params->ipc_payload_area_size = ivpu_bo_size(ipc_mem_rx) / 2; boot_params->global_aliased_pio_base = vdev->hw->ranges.user.start; boot_params->global_aliased_pio_size = ivpu_hw_range_size(&vdev->hw->ranges.user); @@ -486,9 +486,9 @@ void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params boot_params->trace_destination_mask = vdev->fw->trace_destination_mask; boot_params->trace_hw_component_mask = vdev->fw->trace_hw_component_mask; boot_params->crit_tracing_buff_addr = vdev->fw->mem_log_crit->vpu_addr; - boot_params->crit_tracing_buff_size = vdev->fw->mem_log_crit->base.size; + boot_params->crit_tracing_buff_size = ivpu_bo_size(vdev->fw->mem_log_crit); boot_params->verbose_tracing_buff_addr = vdev->fw->mem_log_verb->vpu_addr; - boot_params->verbose_tracing_buff_size = vdev->fw->mem_log_verb->base.size; + boot_params->verbose_tracing_buff_size = ivpu_bo_size(vdev->fw->mem_log_verb); boot_params->punit_telemetry_sram_base = ivpu_hw_reg_telemetry_offset_get(vdev); boot_params->punit_telemetry_sram_size = ivpu_hw_reg_telemetry_size_get(vdev); diff --git a/drivers/accel/ivpu/ivpu_fw_log.c b/drivers/accel/ivpu/ivpu_fw_log.c index 95065cac9fbd..f6770f5e82a2 100644 --- a/drivers/accel/ivpu/ivpu_fw_log.c +++ b/drivers/accel/ivpu/ivpu_fw_log.c @@ -31,10 +31,10 @@ static int fw_log_ptr(struct ivpu_device *vdev, struct ivpu_bo *bo, u32 *offset, { struct vpu_tracing_buffer_header *log; - if ((*offset + sizeof(*log)) > bo->base.size) + if ((*offset + sizeof(*log)) > ivpu_bo_size(bo)) return -EINVAL; - log = bo->kvaddr + *offset; + log = ivpu_bo_vaddr(bo) + *offset; if (log->vpu_canary_start != VPU_TRACING_BUFFER_CANARY) return -EINVAL; @@ -43,7 +43,7 @@ static int fw_log_ptr(struct ivpu_device *vdev, struct ivpu_bo *bo, u32 *offset, ivpu_dbg(vdev, FW_BOOT, "Invalid header size 0x%x\n", log->header_size); return -EINVAL; } - if ((char *)log + log->size > (char *)bo->kvaddr + bo->base.size) { + if ((char *)log + log->size > (char *)ivpu_bo_vaddr(bo) + ivpu_bo_size(bo)) { ivpu_dbg(vdev, FW_BOOT, "Invalid log size 0x%x\n", log->size); return -EINVAL; } diff --git a/drivers/accel/ivpu/ivpu_gem.c b/drivers/accel/ivpu/ivpu_gem.c index d09f13b35902..c91852f2edc8 100644 --- a/drivers/accel/ivpu/ivpu_gem.c +++ b/drivers/accel/ivpu/ivpu_gem.c @@ -69,7 +69,7 @@ static const struct ivpu_bo_ops prime_ops = { static int __must_check shmem_alloc_pages_locked(struct ivpu_bo *bo) { - int npages = bo->base.size >> PAGE_SHIFT; + int npages = ivpu_bo_size(bo) >> PAGE_SHIFT; struct page **pages; pages = drm_gem_get_pages(&bo->base); @@ -88,7 +88,7 @@ static int __must_check shmem_alloc_pages_locked(struct ivpu_bo *bo) static void shmem_free_pages_locked(struct ivpu_bo *bo) { if (ivpu_bo_cache_mode(bo) != DRM_IVPU_BO_CACHED) - set_pages_array_wb(bo->pages, bo->base.size >> PAGE_SHIFT); + set_pages_array_wb(bo->pages, ivpu_bo_size(bo) >> PAGE_SHIFT); drm_gem_put_pages(&bo->base, bo->pages, true, false); bo->pages = NULL; @@ -96,7 +96,7 @@ static void shmem_free_pages_locked(struct ivpu_bo *bo) static int ivpu_bo_map_pages_locked(struct ivpu_bo *bo) { - int npages = bo->base.size >> PAGE_SHIFT; + int npages = ivpu_bo_size(bo) >> PAGE_SHIFT; struct ivpu_device *vdev = ivpu_bo_to_vdev(bo); struct sg_table *sgt; int ret; @@ -142,7 +142,7 @@ static const struct ivpu_bo_ops shmem_ops = { static int __must_check internal_alloc_pages_locked(struct ivpu_bo *bo) { - unsigned int i, npages = bo->base.size >> PAGE_SHIFT; + unsigned int i, npages = ivpu_bo_size(bo) >> PAGE_SHIFT; struct page **pages; int ret; @@ -171,10 +171,10 @@ err_free_pages: static void internal_free_pages_locked(struct ivpu_bo *bo) { - unsigned int i, npages = bo->base.size >> PAGE_SHIFT; + unsigned int i, npages = ivpu_bo_size(bo) >> PAGE_SHIFT; if (ivpu_bo_cache_mode(bo) != DRM_IVPU_BO_CACHED) - set_pages_array_wb(bo->pages, bo->base.size >> PAGE_SHIFT); + set_pages_array_wb(bo->pages, ivpu_bo_size(bo) >> PAGE_SHIFT); for (i = 0; i < npages; i++) put_page(bo->pages[i]); @@ -291,7 +291,7 @@ ivpu_bo_alloc_vpu_addr(struct ivpu_bo *bo, struct ivpu_mmu_context *ctx, } mutex_lock(&ctx->lock); - ret = ivpu_mmu_context_insert_node_locked(ctx, range, bo->base.size, &bo->mm_node); + ret = ivpu_mmu_context_insert_node_locked(ctx, range, ivpu_bo_size(bo), &bo->mm_node); if (!ret) { bo->ctx = ctx; bo->vpu_addr = bo->mm_node.start; @@ -438,7 +438,7 @@ static int ivpu_bo_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) struct ivpu_device *vdev = ivpu_bo_to_vdev(bo); ivpu_dbg(vdev, BO, "mmap: ctx %u handle %u vpu_addr 0x%llx size %zu type %s", - bo->ctx->id, bo->handle, bo->vpu_addr, bo->base.size, bo->ops->name); + bo->ctx->id, bo->handle, bo->vpu_addr, ivpu_bo_size(bo), bo->ops->name); if (obj->import_attach) { /* Drop the reference drm_gem_mmap_obj() acquired.*/ @@ -553,7 +553,7 @@ ivpu_bo_create_ioctl(struct drm_device *dev, void *data, struct drm_file *file) drm_gem_object_put(&bo->base); ivpu_dbg(vdev, BO, "alloc shmem: ctx %u vpu_addr 0x%llx size %zu flags 0x%x\n", - file_priv->ctx.id, bo->vpu_addr, bo->base.size, bo->flags); + file_priv->ctx.id, bo->vpu_addr, ivpu_bo_size(bo), bo->flags); return ret; } @@ -590,22 +590,22 @@ ivpu_bo_alloc_internal(struct ivpu_device *vdev, u64 vpu_addr, u64 size, u32 fla goto err_put; if (ivpu_bo_cache_mode(bo) != DRM_IVPU_BO_CACHED) - drm_clflush_pages(bo->pages, bo->base.size >> PAGE_SHIFT); + drm_clflush_pages(bo->pages, ivpu_bo_size(bo) >> PAGE_SHIFT); if (bo->flags & DRM_IVPU_BO_WC) - set_pages_array_wc(bo->pages, bo->base.size >> PAGE_SHIFT); + set_pages_array_wc(bo->pages, ivpu_bo_size(bo) >> PAGE_SHIFT); else if (bo->flags & DRM_IVPU_BO_UNCACHED) - set_pages_array_uc(bo->pages, bo->base.size >> PAGE_SHIFT); + set_pages_array_uc(bo->pages, ivpu_bo_size(bo) >> PAGE_SHIFT); prot = ivpu_bo_pgprot(bo, PAGE_KERNEL); - bo->kvaddr = vmap(bo->pages, bo->base.size >> PAGE_SHIFT, VM_MAP, prot); + bo->kvaddr = vmap(bo->pages, ivpu_bo_size(bo) >> PAGE_SHIFT, VM_MAP, prot); if (!bo->kvaddr) { ivpu_err(vdev, "Failed to map BO into kernel virtual memory\n"); goto err_put; } ivpu_dbg(vdev, BO, "alloc internal: ctx 0 vpu_addr 0x%llx size %zu flags 0x%x\n", - bo->vpu_addr, bo->base.size, flags); + bo->vpu_addr, ivpu_bo_size(bo), flags); return bo; @@ -718,7 +718,7 @@ static void ivpu_bo_print_info(struct ivpu_bo *bo, struct drm_printer *p) dma_refcount = atomic_long_read(&bo->base.dma_buf->file->f_count); drm_printf(p, "%5u %6d %16llx %10lu %10u %12lu %14s\n", - bo->ctx->id, bo->handle, bo->vpu_addr, bo->base.size, + bo->ctx->id, bo->handle, bo->vpu_addr, ivpu_bo_size(bo), kref_read(&bo->base.refcount), dma_refcount, bo->ops->name); } diff --git a/drivers/accel/ivpu/ivpu_gem.h b/drivers/accel/ivpu/ivpu_gem.h index 6b0ceda5f253..a0b4d4a32b3b 100644 --- a/drivers/accel/ivpu/ivpu_gem.h +++ b/drivers/accel/ivpu/ivpu_gem.h @@ -68,9 +68,19 @@ static inline struct ivpu_bo *to_ivpu_bo(struct drm_gem_object *obj) return container_of(obj, struct ivpu_bo, base); } +static inline void *ivpu_bo_vaddr(struct ivpu_bo *bo) +{ + return bo->kvaddr; +} + +static inline size_t ivpu_bo_size(struct ivpu_bo *bo) +{ + return bo->base.size; +} + static inline struct page *ivpu_bo_get_page(struct ivpu_bo *bo, u64 offset) { - if (offset > bo->base.size || !bo->pages) + if (offset > ivpu_bo_size(bo) || !bo->pages) return NULL; return bo->pages[offset / PAGE_SIZE]; @@ -107,21 +117,21 @@ static inline void *ivpu_to_cpu_addr(struct ivpu_bo *bo, u32 vpu_addr) if (vpu_addr < bo->vpu_addr) return NULL; - if (vpu_addr >= (bo->vpu_addr + bo->base.size)) + if (vpu_addr >= (bo->vpu_addr + ivpu_bo_size(bo))) return NULL; - return bo->kvaddr + (vpu_addr - bo->vpu_addr); + return ivpu_bo_vaddr(bo) + (vpu_addr - bo->vpu_addr); } static inline u32 cpu_to_vpu_addr(struct ivpu_bo *bo, void *cpu_addr) { - if (cpu_addr < bo->kvaddr) + if (cpu_addr < ivpu_bo_vaddr(bo)) return 0; - if (cpu_addr >= (bo->kvaddr + bo->base.size)) + if (cpu_addr >= (ivpu_bo_vaddr(bo) + ivpu_bo_size(bo))) return 0; - return bo->vpu_addr + (cpu_addr - bo->kvaddr); + return bo->vpu_addr + (cpu_addr - ivpu_bo_vaddr(bo)); } #endif /* __IVPU_GEM_H__ */ diff --git a/drivers/accel/ivpu/ivpu_hw_37xx.c b/drivers/accel/ivpu/ivpu_hw_37xx.c index 1e842739e937..7e4e87aa7602 100644 --- a/drivers/accel/ivpu/ivpu_hw_37xx.c +++ b/drivers/accel/ivpu/ivpu_hw_37xx.c @@ -68,37 +68,9 @@ (REG_FLD(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, MSS_MBI)) | \ (REG_FLD(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, MSS_MBI_CMX))) -static char *ivpu_platform_to_str(u32 platform) -{ - switch (platform) { - case IVPU_PLATFORM_SILICON: - return "IVPU_PLATFORM_SILICON"; - case IVPU_PLATFORM_SIMICS: - return "IVPU_PLATFORM_SIMICS"; - case IVPU_PLATFORM_FPGA: - return "IVPU_PLATFORM_FPGA"; - default: - return "Invalid platform"; - } -} - -static void ivpu_hw_read_platform(struct ivpu_device *vdev) -{ - u32 gen_ctrl = REGV_RD32(VPU_37XX_HOST_SS_GEN_CTRL); - u32 platform = REG_GET_FLD(VPU_37XX_HOST_SS_GEN_CTRL, PS, gen_ctrl); - - if (platform == IVPU_PLATFORM_SIMICS || platform == IVPU_PLATFORM_FPGA) - vdev->platform = platform; - else - vdev->platform = IVPU_PLATFORM_SILICON; - - ivpu_dbg(vdev, MISC, "Platform type: %s (%d)\n", - ivpu_platform_to_str(vdev->platform), vdev->platform); -} - static void ivpu_hw_wa_init(struct ivpu_device *vdev) { - vdev->wa.punit_disabled = ivpu_is_fpga(vdev); + vdev->wa.punit_disabled = false; vdev->wa.clear_runtime_mem = false; vdev->wa.d3hot_after_power_off = true; @@ -113,19 +85,11 @@ static void ivpu_hw_wa_init(struct ivpu_device *vdev) static void ivpu_hw_timeouts_init(struct ivpu_device *vdev) { - if (ivpu_is_simics(vdev) || ivpu_is_fpga(vdev)) { - vdev->timeout.boot = 100000; - vdev->timeout.jsm = 50000; - vdev->timeout.tdr = 2000000; - vdev->timeout.reschedule_suspend = 1000; - vdev->timeout.autosuspend = -1; - } else { - vdev->timeout.boot = 1000; - vdev->timeout.jsm = 500; - vdev->timeout.tdr = 2000; - vdev->timeout.reschedule_suspend = 10; - vdev->timeout.autosuspend = 10; - } + vdev->timeout.boot = 1000; + vdev->timeout.jsm = 500; + vdev->timeout.tdr = 2000; + vdev->timeout.reschedule_suspend = 10; + vdev->timeout.autosuspend = 10; } static int ivpu_pll_wait_for_cmd_send(struct ivpu_device *vdev) @@ -220,8 +184,7 @@ static int ivpu_pll_drive(struct ivpu_device *vdev, bool enable) int ret; if (IVPU_WA(punit_disabled)) { - ivpu_dbg(vdev, PM, "Skipping PLL request on %s\n", - ivpu_platform_to_str(vdev->platform)); + ivpu_dbg(vdev, PM, "Skipping PLL request\n"); return 0; } @@ -484,10 +447,6 @@ static void ivpu_boot_pwr_island_drive(struct ivpu_device *vdev, bool enable) static int ivpu_boot_wait_for_pwr_island_status(struct ivpu_device *vdev, u32 exp_val) { - /* FPGA model (UPF) is not power aware, skipped Power Island polling */ - if (ivpu_is_fpga(vdev)) - return 0; - return REGV_POLL_FLD(VPU_37XX_HOST_SS_AON_PWR_ISLAND_STATUS0, MSS_CPU, exp_val, PWR_ISLAND_STATUS_TIMEOUT_US); } @@ -632,6 +591,10 @@ static int ivpu_hw_37xx_info_init(struct ivpu_device *vdev) ivpu_hw_init_range(&hw->ranges.shave, 0x180000000, SZ_2G); ivpu_hw_init_range(&hw->ranges.dma, 0x200000000, SZ_8G); + vdev->platform = IVPU_PLATFORM_SILICON; + ivpu_hw_wa_init(vdev); + ivpu_hw_timeouts_init(vdev); + return 0; } @@ -688,10 +651,6 @@ static int ivpu_hw_37xx_power_up(struct ivpu_device *vdev) { int ret; - ivpu_hw_read_platform(vdev); - ivpu_hw_wa_init(vdev); - ivpu_hw_timeouts_init(vdev); - ret = ivpu_hw_37xx_reset(vdev); if (ret) ivpu_warn(vdev, "Failed to reset HW: %d\n", ret); diff --git a/drivers/accel/ivpu/ivpu_hw_40xx.c b/drivers/accel/ivpu/ivpu_hw_40xx.c index d7b8ec0410af..e691c49c9841 100644 --- a/drivers/accel/ivpu/ivpu_hw_40xx.c +++ b/drivers/accel/ivpu/ivpu_hw_40xx.c @@ -735,6 +735,10 @@ static int ivpu_hw_40xx_info_init(struct ivpu_device *vdev) ivpu_hw_init_range(&vdev->hw->ranges.shave, 0x80000000 + SZ_256M, SZ_2G - SZ_256M); ivpu_hw_init_range(&vdev->hw->ranges.dma, 0x200000000, SZ_8G); + ivpu_hw_read_platform(vdev); + ivpu_hw_wa_init(vdev); + ivpu_hw_timeouts_init(vdev); + return 0; } @@ -826,10 +830,6 @@ static int ivpu_hw_40xx_power_up(struct ivpu_device *vdev) return ret; } - ivpu_hw_read_platform(vdev); - ivpu_hw_wa_init(vdev); - ivpu_hw_timeouts_init(vdev); - ret = ivpu_hw_40xx_d0i3_disable(vdev); if (ret) ivpu_warn(vdev, "Failed to disable D0I3: %d\n", ret); diff --git a/drivers/accel/ivpu/ivpu_hw_reg_io.h b/drivers/accel/ivpu/ivpu_hw_reg_io.h index 43c2c0c2d050..79b3f441eac4 100644 --- a/drivers/accel/ivpu/ivpu_hw_reg_io.h +++ b/drivers/accel/ivpu/ivpu_hw_reg_io.h @@ -47,22 +47,30 @@ #define REG_TEST_FLD_NUM(REG, FLD, num, val) \ ((num) == FIELD_GET(REG##_##FLD##_MASK, val)) -#define REGB_POLL(reg, var, cond, timeout_us) \ - read_poll_timeout(REGB_RD32_SILENT, var, cond, REG_POLL_SLEEP_US, timeout_us, false, reg) - -#define REGV_POLL(reg, var, cond, timeout_us) \ - read_poll_timeout(REGV_RD32_SILENT, var, cond, REG_POLL_SLEEP_US, timeout_us, false, reg) - #define REGB_POLL_FLD(reg, fld, val, timeout_us) \ ({ \ u32 var; \ - REGB_POLL(reg, var, (FIELD_GET(reg##_##fld##_MASK, var) == (val)), timeout_us); \ + int r; \ + ivpu_dbg(vdev, REG, "%s : %s (0x%08x) Polling field %s started (expected 0x%x)\n", \ + __func__, #reg, reg, #fld, val); \ + r = read_poll_timeout(REGB_RD32_SILENT, var, (FIELD_GET(reg##_##fld##_MASK, var) == (val)),\ + REG_POLL_SLEEP_US, timeout_us, false, (reg)); \ + ivpu_dbg(vdev, REG, "%s : %s (0x%08x) Polling field %s %s (reg val 0x%08x)\n", \ + __func__, #reg, reg, #fld, r ? "ETIMEDOUT" : "OK", var); \ + r; \ }) #define REGV_POLL_FLD(reg, fld, val, timeout_us) \ ({ \ u32 var; \ - REGV_POLL(reg, var, (FIELD_GET(reg##_##fld##_MASK, var) == (val)), timeout_us); \ + int r; \ + ivpu_dbg(vdev, REG, "%s : %s (0x%08x) Polling field %s started (expected 0x%x)\n", \ + __func__, #reg, reg, #fld, val); \ + r = read_poll_timeout(REGV_RD32_SILENT, var, (FIELD_GET(reg##_##fld##_MASK, var) == (val)),\ + REG_POLL_SLEEP_US, timeout_us, false, (reg)); \ + ivpu_dbg(vdev, REG, "%s : %s (0x%08x) Polling field %s %s (reg val 0x%08x)\n", \ + __func__, #reg, reg, #fld, r ? "ETIMEDOUT" : "OK", var); \ + r; \ }) static inline u32 @@ -71,7 +79,7 @@ ivpu_hw_reg_rd32(struct ivpu_device *vdev, void __iomem *base, u32 reg, { u32 val = readl(base + reg); - ivpu_dbg(vdev, REG, "%s RD: %s (0x%08x) => 0x%08x\n", func, name, reg, val); + ivpu_dbg(vdev, REG, "%s : %s (0x%08x) RD: 0x%08x\n", func, name, reg, val); return val; } @@ -81,7 +89,7 @@ ivpu_hw_reg_rd64(struct ivpu_device *vdev, void __iomem *base, u32 reg, { u64 val = readq(base + reg); - ivpu_dbg(vdev, REG, "%s RD: %s (0x%08x) => 0x%016llx\n", func, name, reg, val); + ivpu_dbg(vdev, REG, "%s : %s (0x%08x) RD: 0x%016llx\n", func, name, reg, val); return val; } @@ -89,7 +97,7 @@ static inline void ivpu_hw_reg_wr32(struct ivpu_device *vdev, void __iomem *base, u32 reg, u32 val, const char *name, const char *func) { - ivpu_dbg(vdev, REG, "%s WR: %s (0x%08x) <= 0x%08x\n", func, name, reg, val); + ivpu_dbg(vdev, REG, "%s : %s (0x%08x) WR: 0x%08x\n", func, name, reg, val); writel(val, base + reg); } @@ -97,7 +105,7 @@ static inline void ivpu_hw_reg_wr64(struct ivpu_device *vdev, void __iomem *base, u32 reg, u64 val, const char *name, const char *func) { - ivpu_dbg(vdev, REG, "%s WR: %s (0x%08x) <= 0x%016llx\n", func, name, reg, val); + ivpu_dbg(vdev, REG, "%s : %s (0x%08x) WR: 0x%016llx\n", func, name, reg, val); writeq(val, base + reg); } diff --git a/drivers/accel/ivpu/ivpu_ipc.c b/drivers/accel/ivpu/ivpu_ipc.c index ce14b02a7462..a4ca40b184d4 100644 --- a/drivers/accel/ivpu/ivpu_ipc.c +++ b/drivers/accel/ivpu/ivpu_ipc.c @@ -45,8 +45,9 @@ static void ivpu_jsm_msg_dump(struct ivpu_device *vdev, char *c, u32 *payload = (u32 *)&jsm_msg->payload; ivpu_dbg(vdev, JSM, - "%s: vpu:0x%08x (type:0x%x, status:0x%x, id: 0x%x, result: 0x%x, payload:0x%x 0x%x 0x%x 0x%x 0x%x)\n", - c, vpu_addr, jsm_msg->type, jsm_msg->status, jsm_msg->request_id, jsm_msg->result, + "%s: vpu:0x%08x (type:%s, status:0x%x, id: 0x%x, result: 0x%x, payload:0x%x 0x%x 0x%x 0x%x 0x%x)\n", + c, vpu_addr, ivpu_jsm_msg_type_to_str(jsm_msg->type), + jsm_msg->status, jsm_msg->request_id, jsm_msg->result, payload[0], payload[1], payload[2], payload[3], payload[4]); } @@ -79,8 +80,8 @@ ivpu_ipc_tx_prepare(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons, tx_buf_vpu_addr = gen_pool_alloc(ipc->mm_tx, sizeof(*tx_buf)); if (!tx_buf_vpu_addr) { - ivpu_err(vdev, "Failed to reserve IPC buffer, size %ld\n", - sizeof(*tx_buf)); + ivpu_err_ratelimited(vdev, "Failed to reserve IPC buffer, size %ld\n", + sizeof(*tx_buf)); return -ENOMEM; } @@ -93,12 +94,12 @@ ivpu_ipc_tx_prepare(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons, jsm_vpu_addr = tx_buf_vpu_addr + offsetof(struct ivpu_ipc_tx_buf, jsm); if (tx_buf->ipc.status != IVPU_IPC_HDR_FREE) - ivpu_warn(vdev, "IPC message vpu:0x%x not released by firmware\n", - tx_buf_vpu_addr); + ivpu_warn_ratelimited(vdev, "IPC message vpu:0x%x not released by firmware\n", + tx_buf_vpu_addr); if (tx_buf->jsm.status != VPU_JSM_MSG_FREE) - ivpu_warn(vdev, "JSM message vpu:0x%x not released by firmware\n", - jsm_vpu_addr); + ivpu_warn_ratelimited(vdev, "JSM message vpu:0x%x not released by firmware\n", + jsm_vpu_addr); memset(tx_buf, 0, sizeof(*tx_buf)); tx_buf->ipc.data_addr = jsm_vpu_addr; @@ -263,18 +264,19 @@ ivpu_ipc_send_receive_internal(struct ivpu_device *vdev, struct vpu_jsm_msg *req ret = ivpu_ipc_send(vdev, &cons, req); if (ret) { - ivpu_warn(vdev, "IPC send failed: %d\n", ret); + ivpu_warn_ratelimited(vdev, "IPC send failed: %d\n", ret); goto consumer_del; } ret = ivpu_ipc_receive(vdev, &cons, NULL, resp, timeout_ms); if (ret) { - ivpu_warn(vdev, "IPC receive failed: type 0x%x, ret %d\n", req->type, ret); + ivpu_warn_ratelimited(vdev, "IPC receive failed: type %s, ret %d\n", + ivpu_jsm_msg_type_to_str(req->type), ret); goto consumer_del; } if (resp->type != expected_resp_type) { - ivpu_warn(vdev, "Invalid JSM response type: 0x%x\n", resp->type); + ivpu_warn_ratelimited(vdev, "Invalid JSM response type: 0x%x\n", resp->type); ret = -EBADE; } @@ -372,13 +374,13 @@ int ivpu_ipc_irq_handler(struct ivpu_device *vdev) while (ivpu_hw_reg_ipc_rx_count_get(vdev)) { vpu_addr = ivpu_hw_reg_ipc_rx_addr_get(vdev); if (vpu_addr == REG_IO_ERROR) { - ivpu_err(vdev, "Failed to read IPC rx addr register\n"); + ivpu_err_ratelimited(vdev, "Failed to read IPC rx addr register\n"); return -EIO; } ipc_hdr = ivpu_to_cpu_addr(ipc->mem_rx, vpu_addr); if (!ipc_hdr) { - ivpu_warn(vdev, "IPC msg 0x%x out of range\n", vpu_addr); + ivpu_warn_ratelimited(vdev, "IPC msg 0x%x out of range\n", vpu_addr); continue; } ivpu_ipc_msg_dump(vdev, "RX", ipc_hdr, vpu_addr); @@ -387,7 +389,8 @@ int ivpu_ipc_irq_handler(struct ivpu_device *vdev) if (ipc_hdr->channel != IVPU_IPC_CHAN_BOOT_MSG) { jsm_msg = ivpu_to_cpu_addr(ipc->mem_rx, ipc_hdr->data_addr); if (!jsm_msg) { - ivpu_warn(vdev, "JSM msg 0x%x out of range\n", ipc_hdr->data_addr); + ivpu_warn_ratelimited(vdev, "JSM msg 0x%x out of range\n", + ipc_hdr->data_addr); ivpu_ipc_rx_mark_free(vdev, ipc_hdr, NULL); continue; } @@ -395,7 +398,8 @@ int ivpu_ipc_irq_handler(struct ivpu_device *vdev) } if (atomic_read(&ipc->rx_msg_count) > IPC_MAX_RX_MSG) { - ivpu_warn(vdev, "IPC RX msg dropped, msg count %d\n", IPC_MAX_RX_MSG); + ivpu_warn_ratelimited(vdev, "IPC RX msg dropped, msg count %d\n", + IPC_MAX_RX_MSG); ivpu_ipc_rx_mark_free(vdev, ipc_hdr, jsm_msg); continue; } @@ -446,7 +450,7 @@ int ivpu_ipc_init(struct ivpu_device *vdev) goto err_free_rx; } - ret = gen_pool_add(ipc->mm_tx, ipc->mem_tx->vpu_addr, ipc->mem_tx->base.size, -1); + ret = gen_pool_add(ipc->mm_tx, ipc->mem_tx->vpu_addr, ivpu_bo_size(ipc->mem_tx), -1); if (ret) { ivpu_err(vdev, "gen_pool_add failed, ret %d\n", ret); goto err_free_rx; @@ -502,8 +506,8 @@ void ivpu_ipc_reset(struct ivpu_device *vdev) mutex_lock(&ipc->lock); - memset(ipc->mem_tx->kvaddr, 0, ipc->mem_tx->base.size); - memset(ipc->mem_rx->kvaddr, 0, ipc->mem_rx->base.size); + memset(ivpu_bo_vaddr(ipc->mem_tx), 0, ivpu_bo_size(ipc->mem_tx)); + memset(ivpu_bo_vaddr(ipc->mem_rx), 0, ivpu_bo_size(ipc->mem_rx)); wmb(); /* Flush WC buffers for TX and RX rings */ mutex_unlock(&ipc->lock); diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index de9e69f70af7..689dc0d13b8f 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -48,10 +48,10 @@ static struct ivpu_cmdq *ivpu_cmdq_alloc(struct ivpu_file_priv *file_priv, u16 e goto cmdq_free; cmdq->db_id = file_priv->ctx.id + engine * ivpu_get_context_count(vdev); - cmdq->entry_count = (u32)((cmdq->mem->base.size - sizeof(struct vpu_job_queue_header)) / + cmdq->entry_count = (u32)((ivpu_bo_size(cmdq->mem) - sizeof(struct vpu_job_queue_header)) / sizeof(struct vpu_job_queue_entry)); - cmdq->jobq = (struct vpu_job_queue *)cmdq->mem->kvaddr; + cmdq->jobq = (struct vpu_job_queue *)ivpu_bo_vaddr(cmdq->mem); jobq_header = &cmdq->jobq->header; jobq_header->engine_idx = engine; jobq_header->head = 0; @@ -93,7 +93,7 @@ static struct ivpu_cmdq *ivpu_cmdq_acquire(struct ivpu_file_priv *file_priv, u16 return cmdq; ret = ivpu_jsm_register_db(vdev, file_priv->ctx.id, cmdq->db_id, - cmdq->mem->vpu_addr, cmdq->mem->base.size); + cmdq->mem->vpu_addr, ivpu_bo_size(cmdq->mem)); if (ret) return NULL; @@ -453,7 +453,7 @@ ivpu_job_prepare_bos_for_submit(struct drm_file *file, struct ivpu_job *job, u32 return -EBUSY; } - if (commands_offset >= bo->base.size) { + if (commands_offset >= ivpu_bo_size(bo)) { ivpu_warn(vdev, "Invalid command buffer offset %u\n", commands_offset); return -EINVAL; } diff --git a/drivers/accel/ivpu/ivpu_jsm_msg.c b/drivers/accel/ivpu/ivpu_jsm_msg.c index bdddef2c59ee..0c2fe7142024 100644 --- a/drivers/accel/ivpu/ivpu_jsm_msg.c +++ b/drivers/accel/ivpu/ivpu_jsm_msg.c @@ -7,6 +7,70 @@ #include "ivpu_ipc.h" #include "ivpu_jsm_msg.h" +const char *ivpu_jsm_msg_type_to_str(enum vpu_ipc_msg_type type) +{ + #define IVPU_CASE_TO_STR(x) case x: return #x + switch (type) { + IVPU_CASE_TO_STR(VPU_JSM_MSG_UNKNOWN); + IVPU_CASE_TO_STR(VPU_JSM_MSG_ENGINE_RESET); + IVPU_CASE_TO_STR(VPU_JSM_MSG_ENGINE_PREEMPT); + IVPU_CASE_TO_STR(VPU_JSM_MSG_REGISTER_DB); + IVPU_CASE_TO_STR(VPU_JSM_MSG_UNREGISTER_DB); + IVPU_CASE_TO_STR(VPU_JSM_MSG_QUERY_ENGINE_HB); + IVPU_CASE_TO_STR(VPU_JSM_MSG_GET_POWER_LEVEL_COUNT); + IVPU_CASE_TO_STR(VPU_JSM_MSG_GET_POWER_LEVEL); + IVPU_CASE_TO_STR(VPU_JSM_MSG_SET_POWER_LEVEL); + IVPU_CASE_TO_STR(VPU_JSM_MSG_METRIC_STREAMER_OPEN); + IVPU_CASE_TO_STR(VPU_JSM_MSG_METRIC_STREAMER_CLOSE); + IVPU_CASE_TO_STR(VPU_JSM_MSG_TRACE_SET_CONFIG); + IVPU_CASE_TO_STR(VPU_JSM_MSG_TRACE_GET_CONFIG); + IVPU_CASE_TO_STR(VPU_JSM_MSG_TRACE_GET_CAPABILITY); + IVPU_CASE_TO_STR(VPU_JSM_MSG_TRACE_GET_NAME); + IVPU_CASE_TO_STR(VPU_JSM_MSG_SSID_RELEASE); + IVPU_CASE_TO_STR(VPU_JSM_MSG_METRIC_STREAMER_START); + IVPU_CASE_TO_STR(VPU_JSM_MSG_METRIC_STREAMER_STOP); + IVPU_CASE_TO_STR(VPU_JSM_MSG_METRIC_STREAMER_UPDATE); + IVPU_CASE_TO_STR(VPU_JSM_MSG_METRIC_STREAMER_INFO); + IVPU_CASE_TO_STR(VPU_JSM_MSG_SET_PRIORITY_BAND_SETUP); + IVPU_CASE_TO_STR(VPU_JSM_MSG_CREATE_CMD_QUEUE); + IVPU_CASE_TO_STR(VPU_JSM_MSG_DESTROY_CMD_QUEUE); + IVPU_CASE_TO_STR(VPU_JSM_MSG_SET_CONTEXT_SCHED_PROPERTIES); + IVPU_CASE_TO_STR(VPU_JSM_MSG_HWS_REGISTER_DB); + IVPU_CASE_TO_STR(VPU_JSM_MSG_BLOB_DEINIT); + IVPU_CASE_TO_STR(VPU_JSM_MSG_DYNDBG_CONTROL); + IVPU_CASE_TO_STR(VPU_JSM_MSG_JOB_DONE); + IVPU_CASE_TO_STR(VPU_JSM_MSG_ENGINE_RESET_DONE); + IVPU_CASE_TO_STR(VPU_JSM_MSG_ENGINE_PREEMPT_DONE); + IVPU_CASE_TO_STR(VPU_JSM_MSG_REGISTER_DB_DONE); + IVPU_CASE_TO_STR(VPU_JSM_MSG_UNREGISTER_DB_DONE); + IVPU_CASE_TO_STR(VPU_JSM_MSG_QUERY_ENGINE_HB_DONE); + IVPU_CASE_TO_STR(VPU_JSM_MSG_GET_POWER_LEVEL_COUNT_DONE); + IVPU_CASE_TO_STR(VPU_JSM_MSG_GET_POWER_LEVEL_DONE); + IVPU_CASE_TO_STR(VPU_JSM_MSG_SET_POWER_LEVEL_DONE); + IVPU_CASE_TO_STR(VPU_JSM_MSG_METRIC_STREAMER_OPEN_DONE); + IVPU_CASE_TO_STR(VPU_JSM_MSG_METRIC_STREAMER_CLOSE_DONE); + IVPU_CASE_TO_STR(VPU_JSM_MSG_TRACE_SET_CONFIG_RSP); + IVPU_CASE_TO_STR(VPU_JSM_MSG_TRACE_GET_CONFIG_RSP); + IVPU_CASE_TO_STR(VPU_JSM_MSG_TRACE_GET_CAPABILITY_RSP); + IVPU_CASE_TO_STR(VPU_JSM_MSG_TRACE_GET_NAME_RSP); + IVPU_CASE_TO_STR(VPU_JSM_MSG_SSID_RELEASE_DONE); + IVPU_CASE_TO_STR(VPU_JSM_MSG_METRIC_STREAMER_START_DONE); + IVPU_CASE_TO_STR(VPU_JSM_MSG_METRIC_STREAMER_STOP_DONE); + IVPU_CASE_TO_STR(VPU_JSM_MSG_METRIC_STREAMER_UPDATE_DONE); + IVPU_CASE_TO_STR(VPU_JSM_MSG_METRIC_STREAMER_INFO_DONE); + IVPU_CASE_TO_STR(VPU_JSM_MSG_METRIC_STREAMER_NOTIFICATION); + IVPU_CASE_TO_STR(VPU_JSM_MSG_SET_PRIORITY_BAND_SETUP_RSP); + IVPU_CASE_TO_STR(VPU_JSM_MSG_CREATE_CMD_QUEUE_RSP); + IVPU_CASE_TO_STR(VPU_JSM_MSG_DESTROY_CMD_QUEUE_RSP); + IVPU_CASE_TO_STR(VPU_JSM_MSG_SET_CONTEXT_SCHED_PROPERTIES_RSP); + IVPU_CASE_TO_STR(VPU_JSM_MSG_BLOB_DEINIT_DONE); + IVPU_CASE_TO_STR(VPU_JSM_MSG_DYNDBG_CONTROL_RSP); + } + #undef IVPU_CASE_TO_STR + + return "Unknown JSM message type"; +} + int ivpu_jsm_register_db(struct ivpu_device *vdev, u32 ctx_id, u32 db_id, u64 jobq_base, u32 jobq_size) { @@ -22,7 +86,7 @@ int ivpu_jsm_register_db(struct ivpu_device *vdev, u32 ctx_id, u32 db_id, ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_REGISTER_DB_DONE, &resp, VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); if (ret) { - ivpu_err(vdev, "Failed to register doorbell %d: %d\n", db_id, ret); + ivpu_err_ratelimited(vdev, "Failed to register doorbell %d: %d\n", db_id, ret); return ret; } @@ -42,7 +106,7 @@ int ivpu_jsm_unregister_db(struct ivpu_device *vdev, u32 db_id) ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_UNREGISTER_DB_DONE, &resp, VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); if (ret) { - ivpu_warn(vdev, "Failed to unregister doorbell %d: %d\n", db_id, ret); + ivpu_warn_ratelimited(vdev, "Failed to unregister doorbell %d: %d\n", db_id, ret); return ret; } @@ -65,7 +129,8 @@ int ivpu_jsm_get_heartbeat(struct ivpu_device *vdev, u32 engine, u64 *heartbeat) ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_QUERY_ENGINE_HB_DONE, &resp, VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); if (ret) { - ivpu_err(vdev, "Failed to get heartbeat from engine %d: %d\n", engine, ret); + ivpu_err_ratelimited(vdev, "Failed to get heartbeat from engine %d: %d\n", + engine, ret); return ret; } @@ -87,7 +152,7 @@ int ivpu_jsm_reset_engine(struct ivpu_device *vdev, u32 engine) ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_ENGINE_RESET_DONE, &resp, VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); if (ret) - ivpu_err(vdev, "Failed to reset engine %d: %d\n", engine, ret); + ivpu_err_ratelimited(vdev, "Failed to reset engine %d: %d\n", engine, ret); return ret; } @@ -107,7 +172,7 @@ int ivpu_jsm_preempt_engine(struct ivpu_device *vdev, u32 engine, u32 preempt_id ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_ENGINE_PREEMPT_DONE, &resp, VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); if (ret) - ivpu_err(vdev, "Failed to preempt engine %d: %d\n", engine, ret); + ivpu_err_ratelimited(vdev, "Failed to preempt engine %d: %d\n", engine, ret); return ret; } @@ -123,7 +188,8 @@ int ivpu_jsm_dyndbg_control(struct ivpu_device *vdev, char *command, size_t size ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_DYNDBG_CONTROL_RSP, &resp, VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); if (ret) - ivpu_warn(vdev, "Failed to send command \"%s\": ret %d\n", command, ret); + ivpu_warn_ratelimited(vdev, "Failed to send command \"%s\": ret %d\n", + command, ret); return ret; } @@ -138,7 +204,7 @@ int ivpu_jsm_trace_get_capability(struct ivpu_device *vdev, u32 *trace_destinati ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_TRACE_GET_CAPABILITY_RSP, &resp, VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); if (ret) { - ivpu_warn(vdev, "Failed to get trace capability: %d\n", ret); + ivpu_warn_ratelimited(vdev, "Failed to get trace capability: %d\n", ret); return ret; } @@ -162,7 +228,7 @@ int ivpu_jsm_trace_set_config(struct ivpu_device *vdev, u32 trace_level, u32 tra ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_TRACE_SET_CONFIG_RSP, &resp, VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); if (ret) - ivpu_warn(vdev, "Failed to set config: %d\n", ret); + ivpu_warn_ratelimited(vdev, "Failed to set config: %d\n", ret); return ret; } diff --git a/drivers/accel/ivpu/ivpu_jsm_msg.h b/drivers/accel/ivpu/ivpu_jsm_msg.h index ab50d7b017c1..66979a948c7c 100644 --- a/drivers/accel/ivpu/ivpu_jsm_msg.h +++ b/drivers/accel/ivpu/ivpu_jsm_msg.h @@ -8,6 +8,8 @@ #include "vpu_jsm_api.h" +const char *ivpu_jsm_msg_type_to_str(enum vpu_ipc_msg_type type); + int ivpu_jsm_register_db(struct ivpu_device *vdev, u32 ctx_id, u32 db_id, u64 jobq_base, u32 jobq_size); int ivpu_jsm_unregister_db(struct ivpu_device *vdev, u32 db_id); diff --git a/drivers/accel/ivpu/ivpu_mmu.c b/drivers/accel/ivpu/ivpu_mmu.c index 473e1fc686a7..2538c78fbebe 100644 --- a/drivers/accel/ivpu/ivpu_mmu.c +++ b/drivers/accel/ivpu/ivpu_mmu.c @@ -18,10 +18,12 @@ #define IVPU_MMU_REG_IDR5 0x00200014u #define IVPU_MMU_REG_CR0 0x00200020u #define IVPU_MMU_REG_CR0ACK 0x00200024u +#define IVPU_MMU_REG_CR0ACK_VAL_MASK GENMASK(31, 0) #define IVPU_MMU_REG_CR1 0x00200028u #define IVPU_MMU_REG_CR2 0x0020002cu #define IVPU_MMU_REG_IRQ_CTRL 0x00200050u #define IVPU_MMU_REG_IRQ_CTRLACK 0x00200054u +#define IVPU_MMU_REG_IRQ_CTRLACK_VAL_MASK GENMASK(31, 0) #define IVPU_MMU_REG_GERROR 0x00200060u #define IVPU_MMU_REG_GERROR_CMDQ_MASK BIT_MASK(0) @@ -39,12 +41,13 @@ #define IVPU_MMU_REG_CMDQ_BASE 0x00200090u #define IVPU_MMU_REG_CMDQ_PROD 0x00200098u #define IVPU_MMU_REG_CMDQ_CONS 0x0020009cu +#define IVPU_MMU_REG_CMDQ_CONS_VAL_MASK GENMASK(23, 0) +#define IVPU_MMU_REG_CMDQ_CONS_ERR_MASK GENMASK(30, 24) #define IVPU_MMU_REG_EVTQ_BASE 0x002000a0u #define IVPU_MMU_REG_EVTQ_PROD 0x002000a8u #define IVPU_MMU_REG_EVTQ_CONS 0x002000acu #define IVPU_MMU_REG_EVTQ_PROD_SEC (0x002000a8u + SZ_64K) #define IVPU_MMU_REG_EVTQ_CONS_SEC (0x002000acu + SZ_64K) -#define IVPU_MMU_REG_CMDQ_CONS_ERR_MASK GENMASK(30, 24) #define IVPU_MMU_IDR0_REF 0x080f3e0f #define IVPU_MMU_IDR0_REF_SIMICS 0x080f3e1f @@ -409,19 +412,18 @@ static int ivpu_mmu_structs_alloc(struct ivpu_device *vdev) return ret; } -static int ivpu_mmu_reg_write(struct ivpu_device *vdev, u32 reg, u32 val) +static int ivpu_mmu_reg_write_cr0(struct ivpu_device *vdev, u32 val) { - u32 reg_ack = reg + 4; /* ACK register is 4B after base register */ - u32 val_ack; - int ret; + REGV_WR32(IVPU_MMU_REG_CR0, val); - REGV_WR32(reg, val); + return REGV_POLL_FLD(IVPU_MMU_REG_CR0ACK, VAL, val, IVPU_MMU_REG_TIMEOUT_US); +} - ret = REGV_POLL(reg_ack, val_ack, (val == val_ack), IVPU_MMU_REG_TIMEOUT_US); - if (ret) - ivpu_err(vdev, "Failed to write register 0x%x\n", reg); +static int ivpu_mmu_reg_write_irq_ctrl(struct ivpu_device *vdev, u32 val) +{ + REGV_WR32(IVPU_MMU_REG_IRQ_CTRL, val); - return ret; + return REGV_POLL_FLD(IVPU_MMU_REG_IRQ_CTRLACK, VAL, val, IVPU_MMU_REG_TIMEOUT_US); } static int ivpu_mmu_irqs_setup(struct ivpu_device *vdev) @@ -429,19 +431,26 @@ static int ivpu_mmu_irqs_setup(struct ivpu_device *vdev) u32 irq_ctrl = IVPU_MMU_IRQ_EVTQ_EN | IVPU_MMU_IRQ_GERROR_EN; int ret; - ret = ivpu_mmu_reg_write(vdev, IVPU_MMU_REG_IRQ_CTRL, 0); + ret = ivpu_mmu_reg_write_irq_ctrl(vdev, 0); if (ret) return ret; - return ivpu_mmu_reg_write(vdev, IVPU_MMU_REG_IRQ_CTRL, irq_ctrl); + return ivpu_mmu_reg_write_irq_ctrl(vdev, irq_ctrl); } static int ivpu_mmu_cmdq_wait_for_cons(struct ivpu_device *vdev) { struct ivpu_mmu_queue *cmdq = &vdev->mmu->cmdq; + int ret; + + ret = REGV_POLL_FLD(IVPU_MMU_REG_CMDQ_CONS, VAL, cmdq->prod, + IVPU_MMU_QUEUE_TIMEOUT_US); + if (ret) + return ret; + + cmdq->cons = cmdq->prod; - return REGV_POLL(IVPU_MMU_REG_CMDQ_CONS, cmdq->cons, (cmdq->prod == cmdq->cons), - IVPU_MMU_QUEUE_TIMEOUT_US); + return 0; } static int ivpu_mmu_cmdq_cmd_write(struct ivpu_device *vdev, const char *name, u64 data0, u64 data1) @@ -528,7 +537,7 @@ static int ivpu_mmu_reset(struct ivpu_device *vdev) mmu->evtq.prod = 0; mmu->evtq.cons = 0; - ret = ivpu_mmu_reg_write(vdev, IVPU_MMU_REG_CR0, 0); + ret = ivpu_mmu_reg_write_cr0(vdev, 0); if (ret) return ret; @@ -548,7 +557,7 @@ static int ivpu_mmu_reset(struct ivpu_device *vdev) REGV_WR32(IVPU_MMU_REG_CMDQ_CONS, 0); val = IVPU_MMU_CR0_CMDQEN; - ret = ivpu_mmu_reg_write(vdev, IVPU_MMU_REG_CR0, val); + ret = ivpu_mmu_reg_write_cr0(vdev, val); if (ret) return ret; @@ -569,12 +578,12 @@ static int ivpu_mmu_reset(struct ivpu_device *vdev) REGV_WR32(IVPU_MMU_REG_EVTQ_CONS_SEC, 0); val |= IVPU_MMU_CR0_EVTQEN; - ret = ivpu_mmu_reg_write(vdev, IVPU_MMU_REG_CR0, val); + ret = ivpu_mmu_reg_write_cr0(vdev, val); if (ret) return ret; val |= IVPU_MMU_CR0_ATSCHK; - ret = ivpu_mmu_reg_write(vdev, IVPU_MMU_REG_CR0, val); + ret = ivpu_mmu_reg_write_cr0(vdev, val); if (ret) return ret; @@ -583,7 +592,7 @@ static int ivpu_mmu_reset(struct ivpu_device *vdev) return ret; val |= IVPU_MMU_CR0_SMMUEN; - return ivpu_mmu_reg_write(vdev, IVPU_MMU_REG_CR0, val); + return ivpu_mmu_reg_write_cr0(vdev, val); } static void ivpu_mmu_strtab_link_cd(struct ivpu_device *vdev, u32 sid) diff --git a/drivers/accel/ivpu/ivpu_pm.c b/drivers/accel/ivpu/ivpu_pm.c index da46f95b008a..0ace218783c8 100644 --- a/drivers/accel/ivpu/ivpu_pm.c +++ b/drivers/accel/ivpu/ivpu_pm.c @@ -37,7 +37,7 @@ static void ivpu_pm_prepare_cold_boot(struct ivpu_device *vdev) static void ivpu_pm_prepare_warm_boot(struct ivpu_device *vdev) { struct ivpu_fw_info *fw = vdev->fw; - struct vpu_boot_params *bp = fw->mem->kvaddr; + struct vpu_boot_params *bp = ivpu_bo_vaddr(fw->mem); if (!bp->save_restore_ret_address) { ivpu_pm_prepare_cold_boot(vdev); @@ -246,6 +246,19 @@ int ivpu_rpm_get(struct ivpu_device *vdev) return ret; } +int ivpu_rpm_get_if_active(struct ivpu_device *vdev) +{ + int ret; + + ivpu_dbg(vdev, RPM, "rpm_get_if_active count %d\n", + atomic_read(&vdev->drm.dev->power.usage_count)); + + ret = pm_runtime_get_if_active(vdev->drm.dev, false); + drm_WARN_ON(&vdev->drm, ret < 0); + + return ret; +} + void ivpu_rpm_put(struct ivpu_device *vdev) { pm_runtime_mark_last_busy(vdev->drm.dev); diff --git a/drivers/accel/ivpu/ivpu_pm.h b/drivers/accel/ivpu/ivpu_pm.h index f41c30a14a40..044db150be07 100644 --- a/drivers/accel/ivpu/ivpu_pm.h +++ b/drivers/accel/ivpu/ivpu_pm.h @@ -33,6 +33,7 @@ void ivpu_pm_reset_prepare_cb(struct pci_dev *pdev); void ivpu_pm_reset_done_cb(struct pci_dev *pdev); int __must_check ivpu_rpm_get(struct ivpu_device *vdev); +int __must_check ivpu_rpm_get_if_active(struct ivpu_device *vdev); void ivpu_rpm_put(struct ivpu_device *vdev); void ivpu_pm_schedule_recovery(struct ivpu_device *vdev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 9340e8dc0413..186c06756a2c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -2492,6 +2492,7 @@ static int amdgpu_device_init_schedulers(struct amdgpu_device *adev) } r = drm_sched_init(&ring->sched, &amdgpu_sched_ops, + DRM_SCHED_PRIORITY_COUNT, ring->num_hw_submission, 0, timeout, adev->reset_domain->wq, ring->sched_score, ring->name, @@ -2661,6 +2662,9 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev) if (r) goto init_failed; + if (adev->mman.buffer_funcs_ring->sched.ready) + amdgpu_ttm_set_buffer_funcs_status(adev, true); + /* Don't init kfd if whole hive need to be reset during init */ if (!adev->gmc.xgmi.pending_reset) { kgd2kfd_init_zone_device(adev); @@ -3258,6 +3262,8 @@ int amdgpu_device_ip_suspend(struct amdgpu_device *adev) amdgpu_virt_request_full_gpu(adev, false); } + amdgpu_ttm_set_buffer_funcs_status(adev, false); + r = amdgpu_device_ip_suspend_phase1(adev); if (r) return r; @@ -3447,6 +3453,9 @@ static int amdgpu_device_ip_resume(struct amdgpu_device *adev) r = amdgpu_device_ip_resume_phase2(adev); + if (adev->mman.buffer_funcs_ring->sched.ready) + amdgpu_ttm_set_buffer_funcs_status(adev, true); + return r; } @@ -4234,6 +4243,8 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev) /* disable ras feature must before hw fini */ amdgpu_ras_pre_fini(adev); + amdgpu_ttm_set_buffer_funcs_status(adev, false); + amdgpu_device_ip_fini_early(adev); amdgpu_irq_fini_hw(adev); @@ -4405,6 +4416,8 @@ int amdgpu_device_suspend(struct drm_device *dev, bool fbcon) amdgpu_ras_suspend(adev); + amdgpu_ttm_set_buffer_funcs_status(adev, false); + amdgpu_device_ip_suspend_phase1(adev); if (!adev->in_s0ix) @@ -5176,6 +5189,9 @@ int amdgpu_do_asic_reset(struct list_head *device_list_handle, if (r) goto out; + if (tmp_adev->mman.buffer_funcs_ring->sched.ready) + amdgpu_ttm_set_buffer_funcs_status(tmp_adev, true); + if (vram_lost) amdgpu_device_fill_reset_magic(tmp_adev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c index 78476bc75b4e..1f357198533f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c @@ -325,8 +325,8 @@ void amdgpu_job_stop_all_jobs_on_sched(struct drm_gpu_scheduler *sched) int i; /* Signal all jobs not yet scheduled */ - for (i = DRM_SCHED_PRIORITY_COUNT - 1; i >= DRM_SCHED_PRIORITY_MIN; i--) { - struct drm_sched_rq *rq = &sched->sched_rq[i]; + for (i = sched->num_rqs - 1; i >= DRM_SCHED_PRIORITY_MIN; i--) { + struct drm_sched_rq *rq = sched->sched_rq[i]; spin_lock(&rq->lock); list_for_each_entry(s_entity, &rq->entities, list) { while ((s_job = to_drm_sched_job(spsc_queue_pop(&s_entity->job_queue)))) { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c index e8cbc4142d80..1d9d187de6ee 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c @@ -292,27 +292,6 @@ out: return err; } -void amdgpu_sdma_unset_buffer_funcs_helper(struct amdgpu_device *adev) -{ - struct amdgpu_ring *sdma; - int i; - - for (i = 0; i < adev->sdma.num_instances; i++) { - if (adev->sdma.has_page_queue) { - sdma = &adev->sdma.instance[i].page; - if (adev->mman.buffer_funcs_ring == sdma) { - amdgpu_ttm_set_buffer_funcs_status(adev, false); - break; - } - } - sdma = &adev->sdma.instance[i].ring; - if (adev->mman.buffer_funcs_ring == sdma) { - amdgpu_ttm_set_buffer_funcs_status(adev, false); - break; - } - } -} - int amdgpu_sdma_ras_sw_init(struct amdgpu_device *adev) { int err = 0; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h index 513ac22120c1..173a2a308078 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h @@ -169,7 +169,6 @@ int amdgpu_sdma_init_microcode(struct amdgpu_device *adev, u32 instance, bool duplicate); void amdgpu_sdma_destroy_inst_ctx(struct amdgpu_device *adev, bool duplicate); -void amdgpu_sdma_unset_buffer_funcs_helper(struct amdgpu_device *adev); int amdgpu_sdma_ras_sw_init(struct amdgpu_device *adev); #endif diff --git a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c index ee5dce6f6043..a3fccc4c1f43 100644 --- a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c +++ b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c @@ -308,8 +308,6 @@ static void cik_sdma_gfx_stop(struct amdgpu_device *adev) u32 rb_cntl; int i; - amdgpu_sdma_unset_buffer_funcs_helper(adev); - for (i = 0; i < adev->sdma.num_instances; i++) { rb_cntl = RREG32(mmSDMA0_GFX_RB_CNTL + sdma_offsets[i]); rb_cntl &= ~SDMA0_GFX_RB_CNTL__RB_ENABLE_MASK; @@ -498,9 +496,6 @@ static int cik_sdma_gfx_resume(struct amdgpu_device *adev) r = amdgpu_ring_test_helper(ring); if (r) return r; - - if (adev->mman.buffer_funcs_ring == ring) - amdgpu_ttm_set_buffer_funcs_status(adev, true); } return 0; diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c index b58a13bd75db..45377a175250 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c @@ -339,8 +339,6 @@ static void sdma_v2_4_gfx_stop(struct amdgpu_device *adev) u32 rb_cntl, ib_cntl; int i; - amdgpu_sdma_unset_buffer_funcs_helper(adev); - for (i = 0; i < adev->sdma.num_instances; i++) { rb_cntl = RREG32(mmSDMA0_GFX_RB_CNTL + sdma_offsets[i]); rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_ENABLE, 0); @@ -474,9 +472,6 @@ static int sdma_v2_4_gfx_resume(struct amdgpu_device *adev) r = amdgpu_ring_test_helper(ring); if (r) return r; - - if (adev->mman.buffer_funcs_ring == ring) - amdgpu_ttm_set_buffer_funcs_status(adev, true); } return 0; diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c index c5ea32687eb5..2ad615be4bb3 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c @@ -513,8 +513,6 @@ static void sdma_v3_0_gfx_stop(struct amdgpu_device *adev) u32 rb_cntl, ib_cntl; int i; - amdgpu_sdma_unset_buffer_funcs_helper(adev); - for (i = 0; i < adev->sdma.num_instances; i++) { rb_cntl = RREG32(mmSDMA0_GFX_RB_CNTL + sdma_offsets[i]); rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_ENABLE, 0); @@ -746,9 +744,6 @@ static int sdma_v3_0_gfx_resume(struct amdgpu_device *adev) r = amdgpu_ring_test_helper(ring); if (r) return r; - - if (adev->mman.buffer_funcs_ring == ring) - amdgpu_ttm_set_buffer_funcs_status(adev, true); } return 0; diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c index 683d51ae4bf1..3d68dd5523c6 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c @@ -877,8 +877,6 @@ static void sdma_v4_0_gfx_enable(struct amdgpu_device *adev, bool enable) u32 rb_cntl, ib_cntl; int i; - amdgpu_sdma_unset_buffer_funcs_helper(adev); - for (i = 0; i < adev->sdma.num_instances; i++) { rb_cntl = RREG32_SDMA(i, mmSDMA0_GFX_RB_CNTL); rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_ENABLE, enable ? 1 : 0); @@ -913,8 +911,6 @@ static void sdma_v4_0_page_stop(struct amdgpu_device *adev) u32 rb_cntl, ib_cntl; int i; - amdgpu_sdma_unset_buffer_funcs_helper(adev); - for (i = 0; i < adev->sdma.num_instances; i++) { rb_cntl = RREG32_SDMA(i, mmSDMA0_PAGE_RB_CNTL); rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_PAGE_RB_CNTL, @@ -1402,13 +1398,7 @@ static int sdma_v4_0_start(struct amdgpu_device *adev) r = amdgpu_ring_test_helper(page); if (r) return r; - - if (adev->mman.buffer_funcs_ring == page) - amdgpu_ttm_set_buffer_funcs_status(adev, true); } - - if (adev->mman.buffer_funcs_ring == ring) - amdgpu_ttm_set_buffer_funcs_status(adev, true); } return r; @@ -1921,11 +1911,8 @@ static int sdma_v4_0_hw_fini(void *handle) struct amdgpu_device *adev = (struct amdgpu_device *)handle; int i; - if (amdgpu_sriov_vf(adev)) { - /* disable the scheduler for SDMA */ - amdgpu_sdma_unset_buffer_funcs_helper(adev); + if (amdgpu_sriov_vf(adev)) return 0; - } if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__SDMA)) { for (i = 0; i < adev->sdma.num_instances; i++) { @@ -1964,7 +1951,6 @@ static int sdma_v4_0_resume(void *handle) if (adev->in_s0ix) { sdma_v4_0_enable(adev, true); sdma_v4_0_gfx_enable(adev, true); - amdgpu_ttm_set_buffer_funcs_status(adev, true); return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c index c1ff5eda8961..3c485e5a531a 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c @@ -559,8 +559,6 @@ static void sdma_v5_0_gfx_stop(struct amdgpu_device *adev) u32 rb_cntl, ib_cntl; int i; - amdgpu_sdma_unset_buffer_funcs_helper(adev); - for (i = 0; i < adev->sdma.num_instances; i++) { rb_cntl = RREG32_SOC15_IP(GC, sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_GFX_RB_CNTL)); rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_ENABLE, 0); @@ -825,9 +823,6 @@ static int sdma_v5_0_gfx_resume(struct amdgpu_device *adev) r = amdgpu_ring_test_helper(ring); if (r) return r; - - if (adev->mman.buffer_funcs_ring == ring) - amdgpu_ttm_set_buffer_funcs_status(adev, true); } return 0; @@ -1426,11 +1421,8 @@ static int sdma_v5_0_hw_fini(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; - if (amdgpu_sriov_vf(adev)) { - /* disable the scheduler for SDMA */ - amdgpu_sdma_unset_buffer_funcs_helper(adev); + if (amdgpu_sriov_vf(adev)) return 0; - } sdma_v5_0_ctx_switch_enable(adev, false); sdma_v5_0_enable(adev, false); diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c index 7d1e57189c8c..83c240f741b5 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c @@ -364,8 +364,6 @@ static void sdma_v5_2_gfx_stop(struct amdgpu_device *adev) u32 rb_cntl, ib_cntl; int i; - amdgpu_sdma_unset_buffer_funcs_helper(adev); - for (i = 0; i < adev->sdma.num_instances; i++) { rb_cntl = RREG32_SOC15_IP(GC, sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_GFX_RB_CNTL)); rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_ENABLE, 0); @@ -625,9 +623,6 @@ static int sdma_v5_2_gfx_resume(struct amdgpu_device *adev) r = amdgpu_ring_test_helper(ring); if (r) return r; - - if (adev->mman.buffer_funcs_ring == ring) - amdgpu_ttm_set_buffer_funcs_status(adev, true); } return 0; @@ -1284,11 +1279,8 @@ static int sdma_v5_2_hw_fini(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; - if (amdgpu_sriov_vf(adev)) { - /* disable the scheduler for SDMA */ - amdgpu_sdma_unset_buffer_funcs_helper(adev); + if (amdgpu_sriov_vf(adev)) return 0; - } sdma_v5_2_ctx_switch_enable(adev, false); sdma_v5_2_enable(adev, false); diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c index 7e4d5188cbfa..3c7ddd219de8 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c @@ -348,8 +348,6 @@ static void sdma_v6_0_gfx_stop(struct amdgpu_device *adev) u32 rb_cntl, ib_cntl; int i; - amdgpu_sdma_unset_buffer_funcs_helper(adev); - for (i = 0; i < adev->sdma.num_instances; i++) { rb_cntl = RREG32_SOC15_IP(GC, sdma_v6_0_get_reg_offset(adev, i, regSDMA0_QUEUE0_RB_CNTL)); rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_QUEUE0_RB_CNTL, RB_ENABLE, 0); @@ -561,9 +559,6 @@ static int sdma_v6_0_gfx_resume(struct amdgpu_device *adev) r = amdgpu_ring_test_helper(ring); if (r) return r; - - if (adev->mman.buffer_funcs_ring == ring) - amdgpu_ttm_set_buffer_funcs_status(adev, true); } return 0; @@ -1308,11 +1303,8 @@ static int sdma_v6_0_hw_fini(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; - if (amdgpu_sriov_vf(adev)) { - /* disable the scheduler for SDMA */ - amdgpu_sdma_unset_buffer_funcs_helper(adev); + if (amdgpu_sriov_vf(adev)) return 0; - } sdma_v6_0_ctxempty_int_enable(adev, false); sdma_v6_0_enable(adev, false); diff --git a/drivers/gpu/drm/amd/amdgpu/si_dma.c b/drivers/gpu/drm/amd/amdgpu/si_dma.c index 42c4547f32ec..9aa0e11ee673 100644 --- a/drivers/gpu/drm/amd/amdgpu/si_dma.c +++ b/drivers/gpu/drm/amd/amdgpu/si_dma.c @@ -115,8 +115,6 @@ static void si_dma_stop(struct amdgpu_device *adev) u32 rb_cntl; unsigned i; - amdgpu_sdma_unset_buffer_funcs_helper(adev); - for (i = 0; i < adev->sdma.num_instances; i++) { /* dma0 */ rb_cntl = RREG32(DMA_RB_CNTL + sdma_offsets[i]); @@ -177,9 +175,6 @@ static int si_dma_start(struct amdgpu_device *adev) r = amdgpu_ring_test_helper(ring); if (r) return r; - - if (adev->mman.buffer_funcs_ring == ring) - amdgpu_ttm_set_buffer_funcs_status(adev, true); } return 0; diff --git a/drivers/gpu/drm/ast/ast_dp.c b/drivers/gpu/drm/ast/ast_dp.c index fdd9a493aa9c..ebb6d8ebd44e 100644 --- a/drivers/gpu/drm/ast/ast_dp.c +++ b/drivers/gpu/drm/ast/ast_dp.c @@ -9,11 +9,11 @@ bool ast_astdp_is_connected(struct ast_device *ast) { - if (!ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1, ASTDP_MCU_FW_EXECUTING)) + if (!ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xD1, ASTDP_MCU_FW_EXECUTING)) return false; - if (!ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDF, ASTDP_HPD)) + if (!ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDF, ASTDP_HPD)) return false; - if (!ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDC, ASTDP_LINK_SUCCESS)) + if (!ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDC, ASTDP_LINK_SUCCESS)) return false; return true; } @@ -29,22 +29,22 @@ int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata) * CRDF[b0]: DP HPD * CRE5[b0]: Host reading EDID process is done */ - if (!(ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1, ASTDP_MCU_FW_EXECUTING) && - ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDC, ASTDP_LINK_SUCCESS) && - ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDF, ASTDP_HPD) && - ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE5, + if (!(ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xD1, ASTDP_MCU_FW_EXECUTING) && + ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDC, ASTDP_LINK_SUCCESS) && + ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDF, ASTDP_HPD) && + ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xE5, ASTDP_HOST_EDID_READ_DONE_MASK))) { goto err_astdp_edid_not_ready; } - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE5, (u8) ~ASTDP_HOST_EDID_READ_DONE_MASK, + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE5, (u8) ~ASTDP_HOST_EDID_READ_DONE_MASK, 0x00); for (i = 0; i < 32; i++) { /* * CRE4[7:0]: Read-Pointer for EDID (Unit: 4bytes); valid range: 0~64 */ - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE4, + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE4, ASTDP_AND_CLEAR_MASK, (u8)i); j = 0; @@ -52,9 +52,9 @@ int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata) * CRD7[b0]: valid flag for EDID * CRD6[b0]: mirror read pointer for EDID */ - while ((ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD7, + while ((ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xD7, ASTDP_EDID_VALID_FLAG_MASK) != 0x01) || - (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD6, + (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xD6, ASTDP_EDID_READ_POINTER_MASK) != i)) { /* * Delay are getting longer with each retry. @@ -64,11 +64,11 @@ int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata) */ mdelay(j+1); - if (!(ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1, + if (!(ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xD1, ASTDP_MCU_FW_EXECUTING) && - ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDC, + ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDC, ASTDP_LINK_SUCCESS) && - ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDF, ASTDP_HPD))) { + ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDF, ASTDP_HPD))) { goto err_astdp_jump_out_loop_of_edid; } @@ -77,13 +77,13 @@ int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata) goto err_astdp_jump_out_loop_of_edid; } - *(ediddata) = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, + *(ediddata) = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xD8, ASTDP_EDID_READ_DATA_MASK); - *(ediddata + 1) = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD9, + *(ediddata + 1) = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xD9, ASTDP_EDID_READ_DATA_MASK); - *(ediddata + 2) = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDA, + *(ediddata + 2) = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDA, ASTDP_EDID_READ_DATA_MASK); - *(ediddata + 3) = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDB, + *(ediddata + 3) = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDB, ASTDP_EDID_READ_DATA_MASK); if (i == 31) { @@ -103,25 +103,25 @@ int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata) ediddata += 4; } - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE5, (u8) ~ASTDP_HOST_EDID_READ_DONE_MASK, + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE5, (u8) ~ASTDP_HOST_EDID_READ_DONE_MASK, ASTDP_HOST_EDID_READ_DONE); return 0; err_astdp_jump_out_loop_of_edid: - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE5, + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE5, (u8) ~ASTDP_HOST_EDID_READ_DONE_MASK, ASTDP_HOST_EDID_READ_DONE); return (~(j+256) + 1); err_astdp_edid_not_ready: - if (!(ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1, ASTDP_MCU_FW_EXECUTING))) + if (!(ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xD1, ASTDP_MCU_FW_EXECUTING))) return (~0xD1 + 1); - if (!(ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDC, ASTDP_LINK_SUCCESS))) + if (!(ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDC, ASTDP_LINK_SUCCESS))) return (~0xDC + 1); - if (!(ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDF, ASTDP_HPD))) + if (!(ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDF, ASTDP_HPD))) return (~0xDF + 1); - if (!(ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE5, ASTDP_HOST_EDID_READ_DONE_MASK))) + if (!(ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xE5, ASTDP_HOST_EDID_READ_DONE_MASK))) return (~0xE5 + 1); return 0; @@ -137,7 +137,7 @@ void ast_dp_launch(struct drm_device *dev) struct ast_device *ast = to_ast_device(dev); // Wait one second then timeout. - while (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1, ASTDP_MCU_FW_EXECUTING) != + while (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xD1, ASTDP_MCU_FW_EXECUTING) != ASTDP_MCU_FW_EXECUTING) { i++; // wait 100 ms @@ -153,7 +153,7 @@ void ast_dp_launch(struct drm_device *dev) if (!bDPExecute) drm_err(dev, "Wait DPMCU executing timeout\n"); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE5, + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE5, (u8) ~ASTDP_HOST_EDID_READ_DONE_MASK, ASTDP_HOST_EDID_READ_DONE); } @@ -164,14 +164,14 @@ void ast_dp_power_on_off(struct drm_device *dev, bool on) { struct ast_device *ast = to_ast_device(dev); // Read and Turn off DP PHY sleep - u8 bE3 = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE3, AST_DP_VIDEO_ENABLE); + u8 bE3 = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xE3, AST_DP_VIDEO_ENABLE); // Turn on DP PHY sleep if (!on) bE3 |= AST_DP_PHY_SLEEP; // DP Power on/off - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE3, (u8) ~AST_DP_PHY_SLEEP, bE3); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE3, (u8) ~AST_DP_PHY_SLEEP, bE3); } @@ -182,13 +182,13 @@ void ast_dp_set_on_off(struct drm_device *dev, bool on) u8 video_on_off = on; // Video On/Off - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE3, (u8) ~AST_DP_VIDEO_ENABLE, on); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE3, (u8) ~AST_DP_VIDEO_ENABLE, on); // If DP plug in and link successful then check video on / off status - if (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDC, ASTDP_LINK_SUCCESS) && - ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDF, ASTDP_HPD)) { + if (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDC, ASTDP_LINK_SUCCESS) && + ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDF, ASTDP_HPD)) { video_on_off <<= 4; - while (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDF, + while (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDF, ASTDP_MIRROR_VIDEO_ENABLE) != video_on_off) { // wait 1 ms mdelay(1); @@ -264,8 +264,8 @@ void ast_dp_set_mode(struct drm_crtc *crtc, struct ast_vbios_mode_info *vbios_mo * CRE1[7:0]: MISC1 (default: 0x00) * CRE2[7:0]: video format index (0x00 ~ 0x20 or 0x40 ~ 0x50) */ - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE0, ASTDP_AND_CLEAR_MASK, + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE0, ASTDP_AND_CLEAR_MASK, ASTDP_MISC0_24bpp); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE1, ASTDP_AND_CLEAR_MASK, ASTDP_MISC1); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE2, ASTDP_AND_CLEAR_MASK, ModeIdx); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE1, ASTDP_AND_CLEAR_MASK, ASTDP_MISC1); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE2, ASTDP_AND_CLEAR_MASK, ModeIdx); } diff --git a/drivers/gpu/drm/ast/ast_dp501.c b/drivers/gpu/drm/ast/ast_dp501.c index f10d53b0c94f..9a4c3a0963f9 100644 --- a/drivers/gpu/drm/ast/ast_dp501.c +++ b/drivers/gpu/drm/ast/ast_dp501.c @@ -31,17 +31,17 @@ static int ast_load_dp501_microcode(struct drm_device *dev) static void send_ack(struct ast_device *ast) { u8 sendack; - sendack = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, 0xff); + sendack = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0x9b, 0xff); sendack |= 0x80; - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, 0x00, sendack); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x9b, 0x00, sendack); } static void send_nack(struct ast_device *ast) { u8 sendack; - sendack = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, 0xff); + sendack = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0x9b, 0xff); sendack &= ~0x80; - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, 0x00, sendack); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x9b, 0x00, sendack); } static bool wait_ack(struct ast_device *ast) @@ -49,7 +49,7 @@ static bool wait_ack(struct ast_device *ast) u8 waitack; u32 retry = 0; do { - waitack = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd2, 0xff); + waitack = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd2, 0xff); waitack &= 0x80; udelay(100); } while ((!waitack) && (retry++ < 1000)); @@ -65,7 +65,7 @@ static bool wait_nack(struct ast_device *ast) u8 waitack; u32 retry = 0; do { - waitack = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd2, 0xff); + waitack = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd2, 0xff); waitack &= 0x80; udelay(100); } while ((waitack) && (retry++ < 1000)); @@ -78,12 +78,12 @@ static bool wait_nack(struct ast_device *ast) static void set_cmd_trigger(struct ast_device *ast) { - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, ~0x40, 0x40); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x9b, ~0x40, 0x40); } static void clear_cmd_trigger(struct ast_device *ast) { - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, ~0x40, 0x00); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x9b, ~0x40, 0x00); } #if 0 @@ -92,7 +92,7 @@ static bool wait_fw_ready(struct ast_device *ast) u8 waitready; u32 retry = 0; do { - waitready = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd2, 0xff); + waitready = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd2, 0xff); waitready &= 0x40; udelay(100); } while ((!waitready) && (retry++ < 1000)); @@ -110,7 +110,7 @@ static bool ast_write_cmd(struct drm_device *dev, u8 data) int retry = 0; if (wait_nack(ast)) { send_nack(ast); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9a, 0x00, data); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x9a, 0x00, data); send_ack(ast); set_cmd_trigger(ast); do { @@ -132,7 +132,7 @@ static bool ast_write_data(struct drm_device *dev, u8 data) if (wait_nack(ast)) { send_nack(ast); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9a, 0x00, data); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x9a, 0x00, data); send_ack(ast); if (wait_ack(ast)) { send_nack(ast); @@ -153,7 +153,7 @@ static bool ast_read_data(struct drm_device *dev, u8 *data) if (wait_ack(ast) == false) return false; - tmp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd3, 0xff); + tmp = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd3, 0xff); *data = tmp; if (wait_nack(ast) == false) { send_nack(ast); @@ -166,7 +166,7 @@ static bool ast_read_data(struct drm_device *dev, u8 *data) static void clear_cmd(struct ast_device *ast) { send_nack(ast); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9a, 0x00, 0x00); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x9a, 0x00, 0x00); } #endif @@ -265,9 +265,9 @@ static bool ast_launch_m68k(struct drm_device *dev) data |= 0x800; ast_moutdwm(ast, 0x1e6e2040, data); - jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x99, 0xfc); /* D[1:0]: Reserved Video Buffer */ + jreg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0x99, 0xfc); /* D[1:0]: Reserved Video Buffer */ jreg |= 0x02; - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x99, jreg); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x99, jreg); } return true; } @@ -354,7 +354,7 @@ static bool ast_init_dvo(struct drm_device *dev) ast_write32(ast, 0xf000, 0x1); ast_write32(ast, 0x12000, 0x1688a8a8); - jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); + jreg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff); if (!(jreg & 0x80)) { /* Init SCU DVO Settings */ data = ast_read32(ast, 0x12008); @@ -413,7 +413,7 @@ static bool ast_init_dvo(struct drm_device *dev) ast_write32(ast, 0x1202c, data); /* Init VGA DVO Settings */ - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xcf, 0x80); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xa3, 0xcf, 0x80); return true; } @@ -442,7 +442,7 @@ static void ast_init_analog(struct drm_device *dev) ast_write32(ast, 0, data); /* Disable DVO */ - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xcf, 0x00); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xa3, 0xcf, 0x00); } void ast_init_3rdtx(struct drm_device *dev) @@ -451,7 +451,7 @@ void ast_init_3rdtx(struct drm_device *dev) u8 jreg; if (IS_AST_GEN4(ast) || IS_AST_GEN5(ast)) { - jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff); + jreg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd1, 0xff); switch (jreg & 0x0e) { case 0x04: ast_init_dvo(dev); diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index 848a9f1403e8..2aee32344f4a 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -39,6 +39,8 @@ #include <drm/drm_mode.h> #include <drm/drm_framebuffer.h> +#include "ast_reg.h" + #define DRIVER_AUTHOR "Dave Airlie" #define DRIVER_NAME "ast" @@ -259,25 +261,6 @@ static inline bool __ast_gen_is_eq(struct ast_device *ast, unsigned long gen) #define IS_AST_GEN6(__ast) __ast_gen_is_eq(__ast, 6) #define IS_AST_GEN7(__ast) __ast_gen_is_eq(__ast, 7) -#define AST_IO_AR_PORT_WRITE (0x40) -#define AST_IO_MISC_PORT_WRITE (0x42) -#define AST_IO_VGA_ENABLE_PORT (0x43) -#define AST_IO_SEQ_PORT (0x44) -#define AST_IO_DAC_INDEX_READ (0x47) -#define AST_IO_DAC_INDEX_WRITE (0x48) -#define AST_IO_DAC_DATA (0x49) -#define AST_IO_GR_PORT (0x4E) -#define AST_IO_CRTC_PORT (0x54) -#define AST_IO_INPUT_STATUS1_READ (0x5A) -#define AST_IO_MISC_PORT_READ (0x4C) - -#define AST_IO_MM_OFFSET (0x380) - -#define AST_IO_VGAIR1_VREFRESH BIT(3) - -#define AST_IO_VGACRCB_HWC_ENABLED BIT(1) -#define AST_IO_VGACRCB_HWC_16BPP BIT(0) /* set: ARGB4444, cleared: 2bpp palette */ - static inline u32 ast_read32(struct ast_device *ast, u32 reg) { return ioread32(ast->regs + reg); @@ -399,72 +382,10 @@ int ast_mode_config_init(struct ast_device *ast); #define AST_DP501_LINKRATE 0xf014 #define AST_DP501_EDID_DATA 0xf020 -/* - * Display Transmitter Type: - */ -#define TX_TYPE_MASK GENMASK(3, 1) -#define NO_TX (0 << 1) -#define ITE66121_VBIOS_TX (1 << 1) -#define SI164_VBIOS_TX (2 << 1) -#define CH7003_VBIOS_TX (3 << 1) -#define DP501_VBIOS_TX (4 << 1) -#define ANX9807_VBIOS_TX (5 << 1) -#define TX_FW_EMBEDDED_FW_TX (6 << 1) -#define ASTDP_DPMCU_TX (7 << 1) - -#define AST_VRAM_INIT_STATUS_MASK GENMASK(7, 6) -//#define AST_VRAM_INIT_BY_BMC BIT(7) -//#define AST_VRAM_INIT_READY BIT(6) - -/* Define for Soc scratched reg used on ASTDP */ -#define AST_DP_PHY_SLEEP BIT(4) -#define AST_DP_VIDEO_ENABLE BIT(0) - #define AST_DP_POWER_ON true #define AST_DP_POWER_OFF false /* - * CRD1[b5]: DP MCU FW is executing - * CRDC[b0]: DP link success - * CRDF[b0]: DP HPD - * CRE5[b0]: Host reading EDID process is done - */ -#define ASTDP_MCU_FW_EXECUTING BIT(5) -#define ASTDP_LINK_SUCCESS BIT(0) -#define ASTDP_HPD BIT(0) -#define ASTDP_HOST_EDID_READ_DONE BIT(0) -#define ASTDP_HOST_EDID_READ_DONE_MASK GENMASK(0, 0) - -/* - * CRB8[b1]: Enable VSYNC off - * CRB8[b0]: Enable HSYNC off - */ -#define AST_DPMS_VSYNC_OFF BIT(1) -#define AST_DPMS_HSYNC_OFF BIT(0) - -/* - * CRDF[b4]: Mirror of AST_DP_VIDEO_ENABLE - * Precondition: A. ~AST_DP_PHY_SLEEP && - * B. DP_HPD && - * C. DP_LINK_SUCCESS - */ -#define ASTDP_MIRROR_VIDEO_ENABLE BIT(4) - -#define ASTDP_EDID_READ_POINTER_MASK GENMASK(7, 0) -#define ASTDP_EDID_VALID_FLAG_MASK GENMASK(0, 0) -#define ASTDP_EDID_READ_DATA_MASK GENMASK(7, 0) - -/* - * ASTDP setmode registers: - * CRE0[7:0]: MISC0 ((0x00: 18-bpp) or (0x20: 24-bpp) - * CRE1[7:0]: MISC1 (default: 0x00) - * CRE2[7:0]: video format index (0x00 ~ 0x20 or 0x40 ~ 0x50) - */ -#define ASTDP_MISC0_24bpp BIT(5) -#define ASTDP_MISC1 0 -#define ASTDP_AND_CLEAR_MASK 0x00 - -/* * ASTDP resoultion table: * EX: ASTDP_A_B_C: * A: Resolution diff --git a/drivers/gpu/drm/ast/ast_i2c.c b/drivers/gpu/drm/ast/ast_i2c.c index d64045c0b849..0e845e7acd9b 100644 --- a/drivers/gpu/drm/ast/ast_i2c.c +++ b/drivers/gpu/drm/ast/ast_i2c.c @@ -35,8 +35,8 @@ static void ast_i2c_setsda(void *i2c_priv, int data) for (i = 0; i < 0x10000; i++) { ujcrb7 = ((data & 0x01) ? 0 : 1) << 2; - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xf1, ujcrb7); - jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x04); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0xf1, ujcrb7); + jtemp = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0x04); if (ujcrb7 == jtemp) break; } @@ -51,8 +51,8 @@ static void ast_i2c_setscl(void *i2c_priv, int clock) for (i = 0; i < 0x10000; i++) { ujcrb7 = ((clock & 0x01) ? 0 : 1); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xf4, ujcrb7); - jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x01); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0xf4, ujcrb7); + jtemp = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0x01); if (ujcrb7 == jtemp) break; } @@ -66,14 +66,14 @@ static int ast_i2c_getsda(void *i2c_priv) count = 0; pass = 0; - val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01; + val = (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0x20) >> 5) & 0x01; do { - val2 = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01; + val2 = (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0x20) >> 5) & 0x01; if (val == val2) { pass++; } else { pass = 0; - val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01; + val = (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0x20) >> 5) & 0x01; } } while ((pass < 5) && (count++ < 0x10000)); @@ -88,14 +88,14 @@ static int ast_i2c_getscl(void *i2c_priv) count = 0; pass = 0; - val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01; + val = (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0x10) >> 4) & 0x01; do { - val2 = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01; + val2 = (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0x10) >> 4) & 0x01; if (val == val2) { pass++; } else { pass = 0; - val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01; + val = (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0x10) >> 4) & 0x01; } } while ((pass < 5) && (count++ < 0x10000)); diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c index dae365ed3969..f4ab40e22cea 100644 --- a/drivers/gpu/drm/ast/ast_main.c +++ b/drivers/gpu/drm/ast/ast_main.c @@ -40,7 +40,7 @@ static bool ast_is_vga_enabled(struct drm_device *dev) struct ast_device *ast = to_ast_device(dev); u8 ch; - ch = ast_io_read8(ast, AST_IO_VGA_ENABLE_PORT); + ch = ast_io_read8(ast, AST_IO_VGAER); return !!(ch & 0x01); } @@ -49,8 +49,8 @@ static void ast_enable_vga(struct drm_device *dev) { struct ast_device *ast = to_ast_device(dev); - ast_io_write8(ast, AST_IO_VGA_ENABLE_PORT, 0x01); - ast_io_write8(ast, AST_IO_MISC_PORT_WRITE, 0x01); + ast_io_write8(ast, AST_IO_VGAER, 0x01); + ast_io_write8(ast, AST_IO_VGAMR_W, 0x01); } /* @@ -62,21 +62,21 @@ static void ast_enable_mmio_release(void *data) struct ast_device *ast = data; /* enable standard VGA decode */ - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x04); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xa1, 0x04); } static int ast_enable_mmio(struct ast_device *ast) { struct drm_device *dev = &ast->base; - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x06); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xa1, 0x06); return devm_add_action_or_reset(dev->dev, ast_enable_mmio_release, ast); } static void ast_open_key(struct ast_device *ast) { - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x80, 0xA8); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x80, 0xA8); } static int ast_device_config_init(struct ast_device *ast) @@ -105,8 +105,8 @@ static int ast_device_config_init(struct ast_device *ast) * is disabled. We force using P2A if VGA only mode bit * is set D[7] */ - jregd0 = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); - jregd1 = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff); + jregd0 = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff); + jregd1 = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd1, 0xff); if (!(jregd0 & 0x80) || !(jregd1 & 0x10)) { /* @@ -219,7 +219,7 @@ static void ast_detect_widescreen(struct ast_device *ast) ast->support_wide_screen = false; break; default: - jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); + jreg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff); if (!(jreg & 0x80)) ast->support_wide_screen = true; else if (jreg & 0x01) @@ -256,7 +256,7 @@ static void ast_detect_tx_chip(struct ast_device *ast, bool need_post) * SIL164 when there is none. */ if (!need_post) { - jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xff); + jreg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xa3, 0xff); if (jreg & 0x80) ast->tx_chip_types = AST_TX_SIL164_BIT; } @@ -267,7 +267,7 @@ static void ast_detect_tx_chip(struct ast_device *ast, bool need_post) * the SOC scratch register #1 bits 11:8 (interestingly marked * as "reserved" in the spec) */ - jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff); + jreg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd1, 0xff); switch (jreg) { case 0x04: ast->tx_chip_types = AST_TX_SIL164_BIT; @@ -286,7 +286,7 @@ static void ast_detect_tx_chip(struct ast_device *ast, bool need_post) ast->tx_chip_types = AST_TX_DP501_BIT; } } else if (IS_AST_GEN7(ast)) { - if (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1, TX_TYPE_MASK) == + if (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xD1, TX_TYPE_MASK) == ASTDP_DPMCU_TX) { ast->tx_chip_types = AST_TX_ASTDP_BIT; ast_dp_launch(&ast->base); diff --git a/drivers/gpu/drm/ast/ast_mm.c b/drivers/gpu/drm/ast/ast_mm.c index bc174bd933b9..6dfe6d9777d4 100644 --- a/drivers/gpu/drm/ast/ast_mm.c +++ b/drivers/gpu/drm/ast/ast_mm.c @@ -39,7 +39,7 @@ static u32 ast_get_vram_size(struct ast_device *ast) u32 vram_size; vram_size = AST_VIDMEM_DEFAULT_SIZE; - jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xaa, 0xff); + jreg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xaa, 0xff); switch (jreg & 3) { case 0: vram_size = AST_VIDMEM_SIZE_8M; @@ -55,7 +55,7 @@ static u32 ast_get_vram_size(struct ast_device *ast) break; } - jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x99, 0xff); + jreg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0x99, 0xff); switch (jreg & 0x03) { case 1: vram_size -= 0x100000; diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 32f04ec6c386..cb9614984285 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -55,14 +55,14 @@ static inline void ast_load_palette_index(struct ast_device *ast, u8 index, u8 red, u8 green, u8 blue) { - ast_io_write8(ast, AST_IO_DAC_INDEX_WRITE, index); - ast_io_read8(ast, AST_IO_SEQ_PORT); - ast_io_write8(ast, AST_IO_DAC_DATA, red); - ast_io_read8(ast, AST_IO_SEQ_PORT); - ast_io_write8(ast, AST_IO_DAC_DATA, green); - ast_io_read8(ast, AST_IO_SEQ_PORT); - ast_io_write8(ast, AST_IO_DAC_DATA, blue); - ast_io_read8(ast, AST_IO_SEQ_PORT); + ast_io_write8(ast, AST_IO_VGADWR, index); + ast_io_read8(ast, AST_IO_VGASRI); + ast_io_write8(ast, AST_IO_VGAPDR, red); + ast_io_read8(ast, AST_IO_VGASRI); + ast_io_write8(ast, AST_IO_VGAPDR, green); + ast_io_read8(ast, AST_IO_VGASRI); + ast_io_write8(ast, AST_IO_VGAPDR, blue); + ast_io_read8(ast, AST_IO_VGASRI); } static void ast_crtc_set_gamma_linear(struct ast_device *ast, @@ -253,13 +253,13 @@ static void ast_set_vbios_color_reg(struct ast_device *ast, return; } - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8c, (u8)((color_index & 0x0f) << 4)); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x8c, (u8)((color_index & 0x0f) << 4)); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0x00); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x91, 0x00); if (vbios_mode->enh_table->flags & NewModeInfo) { - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0xa8); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x92, format->cpp[0] * 8); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x91, 0xa8); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x92, format->cpp[0] * 8); } } @@ -272,18 +272,18 @@ static void ast_set_vbios_mode_reg(struct ast_device *ast, refresh_rate_index = vbios_mode->enh_table->refresh_rate_index; mode_id = vbios_mode->enh_table->mode_id; - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8d, refresh_rate_index & 0xff); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8e, mode_id & 0xff); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x8d, refresh_rate_index & 0xff); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x8e, mode_id & 0xff); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0x00); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x91, 0x00); if (vbios_mode->enh_table->flags & NewModeInfo) { - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0xa8); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x93, adjusted_mode->clock / 1000); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x94, adjusted_mode->crtc_hdisplay); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x95, adjusted_mode->crtc_hdisplay >> 8); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x96, adjusted_mode->crtc_vdisplay); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x97, adjusted_mode->crtc_vdisplay >> 8); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x91, 0xa8); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x93, adjusted_mode->clock / 1000); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x94, adjusted_mode->crtc_hdisplay); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x95, adjusted_mode->crtc_hdisplay >> 8); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x96, adjusted_mode->crtc_vdisplay); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x97, adjusted_mode->crtc_vdisplay >> 8); } } @@ -298,41 +298,41 @@ static void ast_set_std_reg(struct ast_device *ast, stdtable = vbios_mode->std_table; jreg = stdtable->misc; - ast_io_write8(ast, AST_IO_MISC_PORT_WRITE, jreg); + ast_io_write8(ast, AST_IO_VGAMR_W, jreg); /* Set SEQ; except Screen Disable field */ - ast_set_index_reg(ast, AST_IO_SEQ_PORT, 0x00, 0x03); - ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x01, 0xdf, stdtable->seq[0]); + ast_set_index_reg(ast, AST_IO_VGASRI, 0x00, 0x03); + ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x01, 0xdf, stdtable->seq[0]); for (i = 1; i < 4; i++) { jreg = stdtable->seq[i]; - ast_set_index_reg(ast, AST_IO_SEQ_PORT, (i + 1), jreg); + ast_set_index_reg(ast, AST_IO_VGASRI, (i + 1), jreg); } /* Set CRTC; except base address and offset */ - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x7f, 0x00); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x11, 0x7f, 0x00); for (i = 0; i < 12; i++) - ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, stdtable->crtc[i]); + ast_set_index_reg(ast, AST_IO_VGACRI, i, stdtable->crtc[i]); for (i = 14; i < 19; i++) - ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, stdtable->crtc[i]); + ast_set_index_reg(ast, AST_IO_VGACRI, i, stdtable->crtc[i]); for (i = 20; i < 25; i++) - ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, stdtable->crtc[i]); + ast_set_index_reg(ast, AST_IO_VGACRI, i, stdtable->crtc[i]); /* set AR */ - jreg = ast_io_read8(ast, AST_IO_INPUT_STATUS1_READ); + jreg = ast_io_read8(ast, AST_IO_VGAIR1_R); for (i = 0; i < 20; i++) { jreg = stdtable->ar[i]; - ast_io_write8(ast, AST_IO_AR_PORT_WRITE, (u8)i); - ast_io_write8(ast, AST_IO_AR_PORT_WRITE, jreg); + ast_io_write8(ast, AST_IO_VGAARI_W, (u8)i); + ast_io_write8(ast, AST_IO_VGAARI_W, jreg); } - ast_io_write8(ast, AST_IO_AR_PORT_WRITE, 0x14); - ast_io_write8(ast, AST_IO_AR_PORT_WRITE, 0x00); + ast_io_write8(ast, AST_IO_VGAARI_W, 0x14); + ast_io_write8(ast, AST_IO_VGAARI_W, 0x00); - jreg = ast_io_read8(ast, AST_IO_INPUT_STATUS1_READ); - ast_io_write8(ast, AST_IO_AR_PORT_WRITE, 0x20); + jreg = ast_io_read8(ast, AST_IO_VGAIR1_R); + ast_io_write8(ast, AST_IO_VGAARI_W, 0x20); /* Set GR */ for (i = 0; i < 9; i++) - ast_set_index_reg(ast, AST_IO_GR_PORT, i, stdtable->gr[i]); + ast_set_index_reg(ast, AST_IO_VGAGRI, i, stdtable->gr[i]); } static void ast_set_crtc_reg(struct ast_device *ast, @@ -346,48 +346,48 @@ static void ast_set_crtc_reg(struct ast_device *ast, (vbios_mode->enh_table->flags & AST2500PreCatchCRT)) precache = 40; - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x7f, 0x00); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x11, 0x7f, 0x00); temp = (mode->crtc_htotal >> 3) - 5; if (temp & 0x100) jregAC |= 0x01; /* HT D[8] */ - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x00, 0x00, temp); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x00, 0x00, temp); temp = (mode->crtc_hdisplay >> 3) - 1; if (temp & 0x100) jregAC |= 0x04; /* HDE D[8] */ - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x01, 0x00, temp); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x01, 0x00, temp); temp = (mode->crtc_hblank_start >> 3) - 1; if (temp & 0x100) jregAC |= 0x10; /* HBS D[8] */ - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x02, 0x00, temp); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x02, 0x00, temp); temp = ((mode->crtc_hblank_end >> 3) - 1) & 0x7f; if (temp & 0x20) jreg05 |= 0x80; /* HBE D[5] */ if (temp & 0x40) jregAD |= 0x01; /* HBE D[5] */ - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x03, 0xE0, (temp & 0x1f)); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x03, 0xE0, (temp & 0x1f)); temp = ((mode->crtc_hsync_start-precache) >> 3) - 1; if (temp & 0x100) jregAC |= 0x40; /* HRS D[5] */ - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x04, 0x00, temp); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x04, 0x00, temp); temp = (((mode->crtc_hsync_end-precache) >> 3) - 1) & 0x3f; if (temp & 0x20) jregAD |= 0x04; /* HRE D[5] */ - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x05, 0x60, (u8)((temp & 0x1f) | jreg05)); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x05, 0x60, (u8)((temp & 0x1f) | jreg05)); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xAC, 0x00, jregAC); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xAD, 0x00, jregAD); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xAC, 0x00, jregAC); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xAD, 0x00, jregAD); // Workaround for HSync Time non octave pixels (1920x1080@60Hz HSync 44 pixels); if (IS_AST_GEN7(ast) && (mode->crtc_vdisplay == 1080)) - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xFC, 0xFD, 0x02); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xFC, 0xFD, 0x02); else - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xFC, 0xFD, 0x00); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xFC, 0xFD, 0x00); /* vert timings */ temp = (mode->crtc_vtotal) - 2; @@ -397,7 +397,7 @@ static void ast_set_crtc_reg(struct ast_device *ast, jreg07 |= 0x20; if (temp & 0x400) jregAE |= 0x01; - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x06, 0x00, temp); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x06, 0x00, temp); temp = (mode->crtc_vsync_start) - 1; if (temp & 0x100) @@ -406,14 +406,14 @@ static void ast_set_crtc_reg(struct ast_device *ast, jreg07 |= 0x80; if (temp & 0x400) jregAE |= 0x08; - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x10, 0x00, temp); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x10, 0x00, temp); temp = (mode->crtc_vsync_end - 1) & 0x3f; if (temp & 0x10) jregAE |= 0x20; if (temp & 0x20) jregAE |= 0x40; - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x70, temp & 0xf); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x11, 0x70, temp & 0xf); temp = mode->crtc_vdisplay - 1; if (temp & 0x100) @@ -422,7 +422,7 @@ static void ast_set_crtc_reg(struct ast_device *ast, jreg07 |= 0x40; if (temp & 0x400) jregAE |= 0x02; - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x12, 0x00, temp); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x12, 0x00, temp); temp = mode->crtc_vblank_start - 1; if (temp & 0x100) @@ -431,23 +431,23 @@ static void ast_set_crtc_reg(struct ast_device *ast, jreg09 |= 0x20; if (temp & 0x400) jregAE |= 0x04; - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x15, 0x00, temp); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x15, 0x00, temp); temp = mode->crtc_vblank_end - 1; if (temp & 0x100) jregAE |= 0x10; - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x16, 0x00, temp); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x16, 0x00, temp); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x07, 0x00, jreg07); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x09, 0xdf, jreg09); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xAE, 0x00, (jregAE | 0x80)); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x07, 0x00, jreg07); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x09, 0xdf, jreg09); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xAE, 0x00, (jregAE | 0x80)); if (precache) - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0x3f, 0x80); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0x3f, 0x80); else - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0x3f, 0x00); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0x3f, 0x00); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x7f, 0x80); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x11, 0x7f, 0x80); } static void ast_set_offset_reg(struct ast_device *ast, @@ -456,8 +456,8 @@ static void ast_set_offset_reg(struct ast_device *ast, u16 offset; offset = fb->pitches[0] >> 3; - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x13, (offset & 0xff)); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xb0, (offset >> 8) & 0x3f); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x13, (offset & 0xff)); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xb0, (offset >> 8) & 0x3f); } static void ast_set_dclk_reg(struct ast_device *ast, @@ -471,9 +471,9 @@ static void ast_set_dclk_reg(struct ast_device *ast, else clk_info = &dclk_table[vbios_mode->enh_table->dclk_index]; - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xc0, 0x00, clk_info->param1); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xc1, 0x00, clk_info->param2); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xbb, 0x0f, + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xc0, 0x00, clk_info->param1); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xc1, 0x00, clk_info->param2); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xbb, 0x0f, (clk_info->param3 & 0xc0) | ((clk_info->param3 & 0x3) << 4)); } @@ -502,26 +502,26 @@ static void ast_set_color_reg(struct ast_device *ast, break; } - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa0, 0x8f, jregA0); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xf0, jregA3); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa8, 0xfd, jregA8); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xa0, 0x8f, jregA0); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xa3, 0xf0, jregA3); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xa8, 0xfd, jregA8); } static void ast_set_crtthd_reg(struct ast_device *ast) { /* Set Threshold */ if (IS_AST_GEN7(ast)) { - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0xe0); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0xa0); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xa7, 0xe0); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xa6, 0xa0); } else if (IS_AST_GEN6(ast) || IS_AST_GEN5(ast) || IS_AST_GEN4(ast)) { - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x78); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x60); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xa7, 0x78); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xa6, 0x60); } else if (IS_AST_GEN3(ast) || IS_AST_GEN2(ast)) { - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x3f); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x2f); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xa7, 0x3f); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xa6, 0x2f); } else { - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x2f); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x1f); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xa7, 0x2f); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xa6, 0x1f); } } @@ -531,13 +531,13 @@ static void ast_set_sync_reg(struct ast_device *ast, { u8 jreg; - jreg = ast_io_read8(ast, AST_IO_MISC_PORT_READ); + jreg = ast_io_read8(ast, AST_IO_VGAMR_R); jreg &= ~0xC0; if (vbios_mode->enh_table->flags & NVSync) jreg |= 0x80; if (vbios_mode->enh_table->flags & NHSync) jreg |= 0x40; - ast_io_write8(ast, AST_IO_MISC_PORT_WRITE, jreg); + ast_io_write8(ast, AST_IO_VGAMR_W, jreg); } static void ast_set_start_address_crt1(struct ast_device *ast, @@ -546,9 +546,9 @@ static void ast_set_start_address_crt1(struct ast_device *ast, u32 addr; addr = offset >> 2; - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x0d, (u8)(addr & 0xff)); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x0c, (u8)((addr >> 8) & 0xff)); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xaf, (u8)((addr >> 16) & 0xff)); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x0d, (u8)(addr & 0xff)); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x0c, (u8)((addr >> 8) & 0xff)); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xaf, (u8)((addr >> 16) & 0xff)); } @@ -558,7 +558,7 @@ static void ast_wait_for_vretrace(struct ast_device *ast) u8 vgair1; do { - vgair1 = ast_io_read8(ast, AST_IO_INPUT_STATUS1_READ); + vgair1 = ast_io_read8(ast, AST_IO_VGAIR1_R); } while (!(vgair1 & AST_IO_VGAIR1_VREFRESH) && time_before(jiffies, timeout)); } @@ -689,7 +689,7 @@ static void ast_primary_plane_helper_atomic_enable(struct drm_plane *plane, * Therefore only reprogram the address after enabling the plane. */ ast_set_start_address_crt1(ast, (u32)ast_plane->offset); - ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x1, 0xdf, 0x00); + ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x1, 0xdf, 0x00); } static void ast_primary_plane_helper_atomic_disable(struct drm_plane *plane, @@ -697,7 +697,7 @@ static void ast_primary_plane_helper_atomic_disable(struct drm_plane *plane, { struct ast_device *ast = to_ast_device(plane->dev); - ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x1, 0xdf, 0x20); + ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x1, 0xdf, 0x20); } static const struct drm_plane_helper_funcs ast_primary_plane_helper_funcs = { @@ -814,9 +814,9 @@ static void ast_set_cursor_base(struct ast_device *ast, u64 address) u8 addr1 = (address >> 11) & 0xff; u8 addr2 = (address >> 19) & 0xff; - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc8, addr0); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc9, addr1); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xca, addr2); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xc8, addr0); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xc9, addr1); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xca, addr2); } static void ast_set_cursor_location(struct ast_device *ast, u16 x, u16 y, @@ -827,12 +827,12 @@ static void ast_set_cursor_location(struct ast_device *ast, u16 x, u16 y, u8 y0 = (y & 0x00ff); u8 y1 = (y & 0x0700) >> 8; - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc2, x_offset); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc3, y_offset); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc4, x0); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc5, x1); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc6, y0); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc7, y1); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xc2, x_offset); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xc3, y_offset); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xc4, x0); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xc5, x1); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xc6, y0); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xc7, y1); } static void ast_set_cursor_enabled(struct ast_device *ast, bool enabled) @@ -845,7 +845,7 @@ static void ast_set_cursor_enabled(struct ast_device *ast, bool enabled) if (enabled) vgacrcb |= AST_IO_VGACRCB_HWC_ENABLED; - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xcb, mask, vgacrcb); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xcb, mask, vgacrcb); } static const uint32_t ast_cursor_plane_formats[] = { @@ -1014,8 +1014,8 @@ static void ast_crtc_dpms(struct drm_crtc *crtc, int mode) */ switch (mode) { case DRM_MODE_DPMS_ON: - ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x01, 0xdf, 0); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xfc, 0); + ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x01, 0xdf, 0); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0xfc, 0); if (ast->tx_chip_types & AST_TX_DP501_BIT) ast_set_dp501_video_output(crtc->dev, 1); @@ -1051,8 +1051,8 @@ static void ast_crtc_dpms(struct drm_crtc *crtc, int mode) ast_dp_power_on_off(crtc->dev, AST_DP_POWER_OFF); } - ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x01, 0xdf, 0x20); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xfc, ch); + ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x01, 0xdf, 0x20); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0xfc, ch); break; } } @@ -1086,7 +1086,7 @@ ast_crtc_helper_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode return MODE_OK; if ((mode->hdisplay == 1920) && (mode->vdisplay == 1200)) { - jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff); + jtemp = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd1, 0xff); if (jtemp & 0x01) return MODE_NOMODE; else @@ -1219,7 +1219,7 @@ static void ast_crtc_helper_atomic_enable(struct drm_crtc *crtc, struct drm_atom struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode; ast_set_vbios_mode_reg(ast, adjusted_mode, vbios_mode_info); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x06); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xa1, 0x06); ast_set_std_reg(ast, adjusted_mode, vbios_mode_info); ast_set_crtc_reg(ast, adjusted_mode, vbios_mode_info); ast_set_dclk_reg(ast, adjusted_mode, vbios_mode_info); diff --git a/drivers/gpu/drm/ast/ast_post.c b/drivers/gpu/drm/ast/ast_post.c index 13e15173f2c5..7a993a384314 100644 --- a/drivers/gpu/drm/ast/ast_post.c +++ b/drivers/gpu/drm/ast/ast_post.c @@ -49,7 +49,7 @@ ast_set_def_ext_reg(struct drm_device *dev) /* reset scratch */ for (i = 0x81; i <= 0x9f; i++) - ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, 0x00); + ast_set_index_reg(ast, AST_IO_VGACRI, i, 0x00); if (IS_AST_GEN4(ast) || IS_AST_GEN5(ast) || IS_AST_GEN6(ast)) ext_reg_info = extreginfo_ast2300; @@ -58,23 +58,23 @@ ast_set_def_ext_reg(struct drm_device *dev) index = 0xa0; while (*ext_reg_info != 0xff) { - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, index, 0x00, *ext_reg_info); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, index, 0x00, *ext_reg_info); index++; ext_reg_info++; } /* disable standard IO/MEM decode if secondary */ - /* ast_set_index_reg-mask(ast, AST_IO_CRTC_PORT, 0xa1, 0xff, 0x3); */ + /* ast_set_index_reg-mask(ast, AST_IO_VGACRI, 0xa1, 0xff, 0x3); */ /* Set Ext. Default */ - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x8c, 0x00, 0x01); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x00, 0x00); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x8c, 0x00, 0x01); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0x00, 0x00); /* Enable RAMDAC for A1 */ reg = 0x04; if (IS_AST_GEN4(ast) || IS_AST_GEN5(ast) || IS_AST_GEN6(ast)) reg |= 0x20; - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xff, reg); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0xff, reg); } u32 ast_mindwm(struct ast_device *ast, u32 r) @@ -245,7 +245,7 @@ static void ast_init_dram_reg(struct drm_device *dev) u32 data, temp, i; const struct ast_dramstruct *dram_reg_info; - j = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); + j = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff); if ((j & 0x80) == 0) { /* VGA only */ if (IS_AST_GEN1(ast)) { @@ -325,7 +325,7 @@ static void ast_init_dram_reg(struct drm_device *dev) /* wait ready */ do { - j = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); + j = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff); } while ((j & 0x40) == 0); } @@ -349,7 +349,7 @@ void ast_post_gpu(struct drm_device *dev) ast_init_3rdtx(dev); } else { if (ast->tx_chip_types & AST_TX_SIL164_BIT) - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xcf, 0x80); /* Enable DVO */ + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xa3, 0xcf, 0x80); /* Enable DVO */ } } @@ -1562,7 +1562,7 @@ static void ast_post_chip_2300(struct drm_device *dev) u32 temp; u8 reg; - reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); + reg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff); if ((reg & 0x80) == 0) {/* vga only */ ast_write32(ast, 0xf004, 0x1e6e0000); ast_write32(ast, 0xf000, 0x1); @@ -1634,7 +1634,7 @@ static void ast_post_chip_2300(struct drm_device *dev) /* wait ready */ do { - reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); + reg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff); } while ((reg & 0x40) == 0); } @@ -2027,7 +2027,7 @@ void ast_post_chip_2500(struct drm_device *dev) u32 temp; u8 reg; - reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); + reg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff); if ((reg & AST_VRAM_INIT_STATUS_MASK) == 0) {/* vga only */ /* Clear bus lock condition */ ast_patch_ahb_2500(ast); @@ -2075,6 +2075,6 @@ void ast_post_chip_2500(struct drm_device *dev) /* wait ready */ do { - reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); + reg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff); } while ((reg & 0x40) == 0); } diff --git a/drivers/gpu/drm/ast/ast_reg.h b/drivers/gpu/drm/ast/ast_reg.h new file mode 100644 index 000000000000..555286ecf520 --- /dev/null +++ b/drivers/gpu/drm/ast/ast_reg.h @@ -0,0 +1,99 @@ +/* SPDX-License-Identifier: MIT */ + +#ifndef __AST_REG_H__ +#define __AST_REG_H__ + +#include <linux/bits.h> + +/* + * Modesetting + */ + +#define AST_IO_MM_OFFSET (0x380) + +#define AST_IO_VGAARI_W (0x40) +#define AST_IO_VGAMR_W (0x42) +#define AST_IO_VGAER (0x43) +#define AST_IO_VGASRI (0x44) +#define AST_IO_VGADRR (0x47) +#define AST_IO_VGADWR (0x48) +#define AST_IO_VGAPDR (0x49) +#define AST_IO_VGAGRI (0x4E) + +#define AST_IO_VGACRI (0x54) +#define AST_IO_VGACRCB_HWC_16BPP BIT(0) /* set: ARGB4444, cleared: 2bpp palette */ +#define AST_IO_VGACRCB_HWC_ENABLED BIT(1) + +#define AST_IO_VGAIR1_R (0x5A) +#define AST_IO_VGAIR1_VREFRESH BIT(3) + +#define AST_IO_VGAMR_R (0x4C) + +/* + * Display Transmitter Type + */ + +#define TX_TYPE_MASK GENMASK(3, 1) +#define NO_TX (0 << 1) +#define ITE66121_VBIOS_TX (1 << 1) +#define SI164_VBIOS_TX (2 << 1) +#define CH7003_VBIOS_TX (3 << 1) +#define DP501_VBIOS_TX (4 << 1) +#define ANX9807_VBIOS_TX (5 << 1) +#define TX_FW_EMBEDDED_FW_TX (6 << 1) +#define ASTDP_DPMCU_TX (7 << 1) + +#define AST_VRAM_INIT_STATUS_MASK GENMASK(7, 6) +//#define AST_VRAM_INIT_BY_BMC BIT(7) +//#define AST_VRAM_INIT_READY BIT(6) + +/* + * AST DisplayPort + */ + +/* Define for Soc scratched reg used on ASTDP */ +#define AST_DP_PHY_SLEEP BIT(4) +#define AST_DP_VIDEO_ENABLE BIT(0) + +/* + * CRD1[b5]: DP MCU FW is executing + * CRDC[b0]: DP link success + * CRDF[b0]: DP HPD + * CRE5[b0]: Host reading EDID process is done + */ +#define ASTDP_MCU_FW_EXECUTING BIT(5) +#define ASTDP_LINK_SUCCESS BIT(0) +#define ASTDP_HPD BIT(0) +#define ASTDP_HOST_EDID_READ_DONE BIT(0) +#define ASTDP_HOST_EDID_READ_DONE_MASK GENMASK(0, 0) + +/* + * CRB8[b1]: Enable VSYNC off + * CRB8[b0]: Enable HSYNC off + */ +#define AST_DPMS_VSYNC_OFF BIT(1) +#define AST_DPMS_HSYNC_OFF BIT(0) + +/* + * CRDF[b4]: Mirror of AST_DP_VIDEO_ENABLE + * Precondition: A. ~AST_DP_PHY_SLEEP && + * B. DP_HPD && + * C. DP_LINK_SUCCESS + */ +#define ASTDP_MIRROR_VIDEO_ENABLE BIT(4) + +#define ASTDP_EDID_READ_POINTER_MASK GENMASK(7, 0) +#define ASTDP_EDID_VALID_FLAG_MASK GENMASK(0, 0) +#define ASTDP_EDID_READ_DATA_MASK GENMASK(7, 0) + +/* + * ASTDP setmode registers: + * CRE0[7:0]: MISC0 ((0x00: 18-bpp) or (0x20: 24-bpp) + * CRE1[7:0]: MISC1 (default: 0x00) + * CRE2[7:0]: video format index (0x00 ~ 0x20 or 0x40 ~ 0x50) + */ +#define ASTDP_MISC0_24bpp BIT(5) +#define ASTDP_MISC1 0 +#define ASTDP_AND_CLEAR_MASK 0x00 + +#endif diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h index 17445800248d..39c9ece373b0 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h @@ -333,6 +333,18 @@ enum adv7511_type { #define ADV7511_MAX_ADDRS 3 +struct adv7511_chip_info { + enum adv7511_type type; + unsigned int max_mode_clock_khz; + unsigned int max_lane_freq_khz; + const char * const *supply_names; + unsigned int num_supplies; + unsigned int reg_cec_offset; + bool has_dsi; + bool link_config; + bool hpd_override_enable; +}; + struct adv7511 { struct i2c_client *i2c_main; struct i2c_client *i2c_edid; @@ -341,7 +353,6 @@ struct adv7511 { struct regmap *regmap; struct regmap *regmap_cec; - unsigned int reg_cec_offset; enum drm_connector_status status; bool powered; @@ -369,7 +380,6 @@ struct adv7511 { struct gpio_desc *gpio_pd; struct regulator_bulk_data *supplies; - unsigned int num_supplies; /* ADV7533 DSI RX related params */ struct device_node *host_node; @@ -377,7 +387,7 @@ struct adv7511 { u8 num_dsi_lanes; bool use_timing_gen; - enum adv7511_type type; + const struct adv7511_chip_info *info; struct platform_device *audio_pdev; struct cec_adapter *cec_adap; diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c b/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c index 2a6b91f752cb..44451a9658a3 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c @@ -33,7 +33,7 @@ static const u8 ADV7511_REG_CEC_RX_FRAME_LEN[] = { static void adv_cec_tx_raw_status(struct adv7511 *adv7511, u8 tx_raw_status) { - unsigned int offset = adv7511->reg_cec_offset; + unsigned int offset = adv7511->info->reg_cec_offset; unsigned int val; if (regmap_read(adv7511->regmap_cec, @@ -84,7 +84,7 @@ static void adv_cec_tx_raw_status(struct adv7511 *adv7511, u8 tx_raw_status) static void adv7511_cec_rx(struct adv7511 *adv7511, int rx_buf) { - unsigned int offset = adv7511->reg_cec_offset; + unsigned int offset = adv7511->info->reg_cec_offset; struct cec_msg msg = {}; unsigned int len; unsigned int val; @@ -121,7 +121,7 @@ static void adv7511_cec_rx(struct adv7511 *adv7511, int rx_buf) void adv7511_cec_irq_process(struct adv7511 *adv7511, unsigned int irq1) { - unsigned int offset = adv7511->reg_cec_offset; + unsigned int offset = adv7511->info->reg_cec_offset; const u32 irq_tx_mask = ADV7511_INT1_CEC_TX_READY | ADV7511_INT1_CEC_TX_ARBIT_LOST | ADV7511_INT1_CEC_TX_RETRY_TIMEOUT; @@ -177,7 +177,7 @@ void adv7511_cec_irq_process(struct adv7511 *adv7511, unsigned int irq1) static int adv7511_cec_adap_enable(struct cec_adapter *adap, bool enable) { struct adv7511 *adv7511 = cec_get_drvdata(adap); - unsigned int offset = adv7511->reg_cec_offset; + unsigned int offset = adv7511->info->reg_cec_offset; if (adv7511->i2c_cec == NULL) return -EIO; @@ -223,7 +223,7 @@ static int adv7511_cec_adap_enable(struct cec_adapter *adap, bool enable) static int adv7511_cec_adap_log_addr(struct cec_adapter *adap, u8 addr) { struct adv7511 *adv7511 = cec_get_drvdata(adap); - unsigned int offset = adv7511->reg_cec_offset; + unsigned int offset = adv7511->info->reg_cec_offset; unsigned int i, free_idx = ADV7511_MAX_ADDRS; if (!adv7511->cec_enabled_adap) @@ -292,7 +292,7 @@ static int adv7511_cec_adap_transmit(struct cec_adapter *adap, u8 attempts, u32 signal_free_time, struct cec_msg *msg) { struct adv7511 *adv7511 = cec_get_drvdata(adap); - unsigned int offset = adv7511->reg_cec_offset; + unsigned int offset = adv7511->info->reg_cec_offset; u8 len = msg->len; unsigned int i; @@ -345,7 +345,7 @@ static int adv7511_cec_parse_dt(struct device *dev, struct adv7511 *adv7511) int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511) { - unsigned int offset = adv7511->reg_cec_offset; + unsigned int offset = adv7511->info->reg_cec_offset; int ret = adv7511_cec_parse_dt(dev, adv7511); if (ret) diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index d518de88b5c3..8be235144f6d 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -354,7 +354,7 @@ static void __adv7511_power_on(struct adv7511 *adv7511) * first few seconds after enabling the output. On the other hand * adv7535 require to enable HPD Override bit for proper HPD. */ - if (adv7511->type == ADV7535) + if (adv7511->info->hpd_override_enable) regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2, ADV7535_REG_POWER2_HPD_OVERRIDE, ADV7535_REG_POWER2_HPD_OVERRIDE); @@ -373,7 +373,7 @@ static void adv7511_power_on(struct adv7511 *adv7511) */ regcache_sync(adv7511->regmap); - if (adv7511->type == ADV7533 || adv7511->type == ADV7535) + if (adv7511->info->has_dsi) adv7533_dsi_power_on(adv7511); adv7511->powered = true; } @@ -381,7 +381,7 @@ static void adv7511_power_on(struct adv7511 *adv7511) static void __adv7511_power_off(struct adv7511 *adv7511) { /* TODO: setup additional power down modes */ - if (adv7511->type == ADV7535) + if (adv7511->info->hpd_override_enable) regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2, ADV7535_REG_POWER2_HPD_OVERRIDE, 0); @@ -397,7 +397,7 @@ static void __adv7511_power_off(struct adv7511 *adv7511) static void adv7511_power_off(struct adv7511 *adv7511) { __adv7511_power_off(adv7511); - if (adv7511->type == ADV7533 || adv7511->type == ADV7535) + if (adv7511->info->has_dsi) adv7533_dsi_power_off(adv7511); adv7511->powered = false; } @@ -682,7 +682,7 @@ adv7511_detect(struct adv7511 *adv7511, struct drm_connector *connector) status = connector_status_disconnected; } else { /* Renable HPD sensing */ - if (adv7511->type == ADV7535) + if (adv7511->info->hpd_override_enable) regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2, ADV7535_REG_POWER2_HPD_OVERRIDE, ADV7535_REG_POWER2_HPD_OVERRIDE); @@ -786,7 +786,7 @@ static void adv7511_mode_set(struct adv7511 *adv7511, else low_refresh_rate = ADV7511_LOW_REFRESH_RATE_NONE; - if (adv7511->type == ADV7511) + if (adv7511->info->type == ADV7511) regmap_update_bits(adv7511->regmap, 0xfb, 0x6, low_refresh_rate << 1); else @@ -921,7 +921,7 @@ static enum drm_mode_status adv7511_bridge_mode_valid(struct drm_bridge *bridge, { struct adv7511 *adv = bridge_to_adv7511(bridge); - if (adv->type == ADV7533 || adv->type == ADV7535) + if (adv->info->has_dsi) return adv7533_mode_valid(adv, mode); else return adv7511_mode_valid(adv, mode); @@ -1004,37 +1004,30 @@ static const char * const adv7533_supply_names[] = { static int adv7511_init_regulators(struct adv7511 *adv) { + const char * const *supply_names = adv->info->supply_names; + unsigned int num_supplies = adv->info->num_supplies; struct device *dev = &adv->i2c_main->dev; - const char * const *supply_names; unsigned int i; int ret; - if (adv->type == ADV7511) { - supply_names = adv7511_supply_names; - adv->num_supplies = ARRAY_SIZE(adv7511_supply_names); - } else { - supply_names = adv7533_supply_names; - adv->num_supplies = ARRAY_SIZE(adv7533_supply_names); - } - - adv->supplies = devm_kcalloc(dev, adv->num_supplies, + adv->supplies = devm_kcalloc(dev, num_supplies, sizeof(*adv->supplies), GFP_KERNEL); if (!adv->supplies) return -ENOMEM; - for (i = 0; i < adv->num_supplies; i++) + for (i = 0; i < num_supplies; i++) adv->supplies[i].supply = supply_names[i]; - ret = devm_regulator_bulk_get(dev, adv->num_supplies, adv->supplies); + ret = devm_regulator_bulk_get(dev, num_supplies, adv->supplies); if (ret) return ret; - return regulator_bulk_enable(adv->num_supplies, adv->supplies); + return regulator_bulk_enable(num_supplies, adv->supplies); } static void adv7511_uninit_regulators(struct adv7511 *adv) { - regulator_bulk_disable(adv->num_supplies, adv->supplies); + regulator_bulk_disable(adv->info->num_supplies, adv->supplies); } static bool adv7511_cec_register_volatile(struct device *dev, unsigned int reg) @@ -1042,7 +1035,7 @@ static bool adv7511_cec_register_volatile(struct device *dev, unsigned int reg) struct i2c_client *i2c = to_i2c_client(dev); struct adv7511 *adv7511 = i2c_get_clientdata(i2c); - reg -= adv7511->reg_cec_offset; + reg -= adv7511->info->reg_cec_offset; switch (reg) { case ADV7511_REG_CEC_RX1_FRAME_HDR: @@ -1093,12 +1086,10 @@ static int adv7511_init_cec_regmap(struct adv7511 *adv) goto err; } - if (adv->type == ADV7533 || adv->type == ADV7535) { + if (adv->info->reg_cec_offset == ADV7533_REG_CEC_OFFSET) { ret = adv7533_patch_cec_registers(adv); if (ret) goto err; - - adv->reg_cec_offset = ADV7533_REG_CEC_OFFSET; } return 0; @@ -1192,7 +1183,6 @@ static int adv7511_parse_dt(struct device_node *np, static int adv7511_probe(struct i2c_client *i2c) { - const struct i2c_device_id *id = i2c_client_get_device_id(i2c); struct adv7511_link_config link_config; struct adv7511 *adv7511; struct device *dev = &i2c->dev; @@ -1209,15 +1199,11 @@ static int adv7511_probe(struct i2c_client *i2c) adv7511->i2c_main = i2c; adv7511->powered = false; adv7511->status = connector_status_disconnected; - - if (dev->of_node) - adv7511->type = (enum adv7511_type)of_device_get_match_data(dev); - else - adv7511->type = id->driver_data; + adv7511->info = i2c_get_match_data(i2c); memset(&link_config, 0, sizeof(link_config)); - if (adv7511->type == ADV7511) + if (adv7511->info->link_config) ret = adv7511_parse_dt(dev->of_node, &link_config); else ret = adv7533_parse_dt(dev->of_node, adv7511); @@ -1254,7 +1240,7 @@ static int adv7511_probe(struct i2c_client *i2c) goto uninit_regulators; dev_dbg(dev, "Rev. %d\n", val); - if (adv7511->type == ADV7511) + if (adv7511->info->type == ADV7511) ret = regmap_register_patch(adv7511->regmap, adv7511_fixed_registers, ARRAY_SIZE(adv7511_fixed_registers)); @@ -1306,7 +1292,7 @@ static int adv7511_probe(struct i2c_client *i2c) i2c_set_clientdata(i2c, adv7511); - if (adv7511->type == ADV7511) + if (adv7511->info->link_config) adv7511_set_link_config(adv7511, &link_config); ret = adv7511_cec_init(dev, adv7511); @@ -1325,7 +1311,7 @@ static int adv7511_probe(struct i2c_client *i2c) adv7511_audio_init(dev, adv7511); - if (adv7511->type == ADV7533 || adv7511->type == ADV7535) { + if (adv7511->info->has_dsi) { ret = adv7533_attach_dsi(adv7511); if (ret) goto err_unregister_audio; @@ -1368,22 +1354,50 @@ static void adv7511_remove(struct i2c_client *i2c) i2c_unregister_device(adv7511->i2c_edid); } +static const struct adv7511_chip_info adv7511_chip_info = { + .type = ADV7511, + .supply_names = adv7511_supply_names, + .num_supplies = ARRAY_SIZE(adv7511_supply_names), + .link_config = true, +}; + +static const struct adv7511_chip_info adv7533_chip_info = { + .type = ADV7533, + .max_mode_clock_khz = 80000, + .max_lane_freq_khz = 800000, + .supply_names = adv7533_supply_names, + .num_supplies = ARRAY_SIZE(adv7533_supply_names), + .reg_cec_offset = ADV7533_REG_CEC_OFFSET, + .has_dsi = true, +}; + +static const struct adv7511_chip_info adv7535_chip_info = { + .type = ADV7535, + .max_mode_clock_khz = 148500, + .max_lane_freq_khz = 891000, + .supply_names = adv7533_supply_names, + .num_supplies = ARRAY_SIZE(adv7533_supply_names), + .reg_cec_offset = ADV7533_REG_CEC_OFFSET, + .has_dsi = true, + .hpd_override_enable = true, +}; + static const struct i2c_device_id adv7511_i2c_ids[] = { - { "adv7511", ADV7511 }, - { "adv7511w", ADV7511 }, - { "adv7513", ADV7511 }, - { "adv7533", ADV7533 }, - { "adv7535", ADV7535 }, + { "adv7511", (kernel_ulong_t)&adv7511_chip_info }, + { "adv7511w", (kernel_ulong_t)&adv7511_chip_info }, + { "adv7513", (kernel_ulong_t)&adv7511_chip_info }, + { "adv7533", (kernel_ulong_t)&adv7533_chip_info }, + { "adv7535", (kernel_ulong_t)&adv7535_chip_info }, { } }; MODULE_DEVICE_TABLE(i2c, adv7511_i2c_ids); static const struct of_device_id adv7511_of_ids[] = { - { .compatible = "adi,adv7511", .data = (void *)ADV7511 }, - { .compatible = "adi,adv7511w", .data = (void *)ADV7511 }, - { .compatible = "adi,adv7513", .data = (void *)ADV7511 }, - { .compatible = "adi,adv7533", .data = (void *)ADV7533 }, - { .compatible = "adi,adv7535", .data = (void *)ADV7535 }, + { .compatible = "adi,adv7511", .data = &adv7511_chip_info }, + { .compatible = "adi,adv7511w", .data = &adv7511_chip_info }, + { .compatible = "adi,adv7513", .data = &adv7511_chip_info }, + { .compatible = "adi,adv7533", .data = &adv7533_chip_info }, + { .compatible = "adi,adv7535", .data = &adv7535_chip_info }, { } }; MODULE_DEVICE_TABLE(of, adv7511_of_ids); diff --git a/drivers/gpu/drm/bridge/adv7511/adv7533.c b/drivers/gpu/drm/bridge/adv7511/adv7533.c index 7e3e56441aed..4481489aaf5e 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7533.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7533.c @@ -103,18 +103,15 @@ void adv7533_dsi_power_off(struct adv7511 *adv) enum drm_mode_status adv7533_mode_valid(struct adv7511 *adv, const struct drm_display_mode *mode) { - unsigned long max_lane_freq; struct mipi_dsi_device *dsi = adv->dsi; u8 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format); /* Check max clock for either 7533 or 7535 */ - if (mode->clock > (adv->type == ADV7533 ? 80000 : 148500)) + if (mode->clock > adv->info->max_mode_clock_khz) return MODE_CLOCK_HIGH; /* Check max clock for each lane */ - max_lane_freq = (adv->type == ADV7533 ? 800000 : 891000); - - if (mode->clock * bpp > max_lane_freq * adv->num_dsi_lanes) + if (mode->clock * bpp > adv->info->max_lane_freq_khz * adv->num_dsi_lanes) return MODE_CLOCK_HIGH; return MODE_OK; diff --git a/drivers/gpu/drm/bridge/imx/Kconfig b/drivers/gpu/drm/bridge/imx/Kconfig index 9fae28db6aa7..5a4f3d58501e 100644 --- a/drivers/gpu/drm/bridge/imx/Kconfig +++ b/drivers/gpu/drm/bridge/imx/Kconfig @@ -49,4 +49,15 @@ config DRM_IMX8QXP_PIXEL_LINK_TO_DPI Choose this to enable pixel link to display pixel interface(PXL2DPI) found in Freescale i.MX8qxp processor. +config DRM_IMX93_MIPI_DSI + tristate "Freescale i.MX93 specific extensions for Synopsys DW MIPI DSI" + depends on OF + depends on COMMON_CLK + select DRM_DW_MIPI_DSI + select GENERIC_PHY + select GENERIC_PHY_MIPI_DPHY + help + Choose this to enable MIPI DSI controller found in Freescale i.MX93 + processor. + endif # ARCH_MXC || COMPILE_TEST diff --git a/drivers/gpu/drm/bridge/imx/Makefile b/drivers/gpu/drm/bridge/imx/Makefile index 8e2ebf3399a1..2b0c2e44aa1b 100644 --- a/drivers/gpu/drm/bridge/imx/Makefile +++ b/drivers/gpu/drm/bridge/imx/Makefile @@ -4,3 +4,4 @@ obj-$(CONFIG_DRM_IMX8QXP_LDB) += imx8qxp-ldb.o obj-$(CONFIG_DRM_IMX8QXP_PIXEL_COMBINER) += imx8qxp-pixel-combiner.o obj-$(CONFIG_DRM_IMX8QXP_PIXEL_LINK) += imx8qxp-pixel-link.o obj-$(CONFIG_DRM_IMX8QXP_PIXEL_LINK_TO_DPI) += imx8qxp-pxl2dpi.o +obj-$(CONFIG_DRM_IMX93_MIPI_DSI) += imx93-mipi-dsi.o diff --git a/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c b/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c new file mode 100644 index 000000000000..3ff30ce80c5b --- /dev/null +++ b/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c @@ -0,0 +1,917 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/* + * Copyright 2022,2023 NXP + */ + +#include <linux/bitfield.h> +#include <linux/bits.h> +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/math.h> +#include <linux/media-bus-format.h> +#include <linux/mfd/syscon.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/phy/phy.h> +#include <linux/phy/phy-mipi-dphy.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> + +#include <drm/bridge/dw_mipi_dsi.h> +#include <drm/drm_bridge.h> +#include <drm/drm_mipi_dsi.h> +#include <drm/drm_modes.h> + +/* DPHY PLL configuration registers */ +#define DSI_REG 0x4c +#define CFGCLKFREQRANGE_MASK GENMASK(5, 0) +#define CFGCLKFREQRANGE(x) FIELD_PREP(CFGCLKFREQRANGE_MASK, (x)) +#define CLKSEL_MASK GENMASK(7, 6) +#define CLKSEL_STOP FIELD_PREP(CLKSEL_MASK, 0) +#define CLKSEL_GEN FIELD_PREP(CLKSEL_MASK, 1) +#define CLKSEL_EXT FIELD_PREP(CLKSEL_MASK, 2) +#define HSFREQRANGE_MASK GENMASK(14, 8) +#define HSFREQRANGE(x) FIELD_PREP(HSFREQRANGE_MASK, (x)) +#define UPDATE_PLL BIT(17) +#define SHADOW_CLR BIT(18) +#define CLK_EXT BIT(19) + +#define DSI_WRITE_REG0 0x50 +#define M_MASK GENMASK(9, 0) +#define M(x) FIELD_PREP(M_MASK, ((x) - 2)) +#define N_MASK GENMASK(13, 10) +#define N(x) FIELD_PREP(N_MASK, ((x) - 1)) +#define VCO_CTRL_MASK GENMASK(19, 14) +#define VCO_CTRL(x) FIELD_PREP(VCO_CTRL_MASK, (x)) +#define PROP_CTRL_MASK GENMASK(25, 20) +#define PROP_CTRL(x) FIELD_PREP(PROP_CTRL_MASK, (x)) +#define INT_CTRL_MASK GENMASK(31, 26) +#define INT_CTRL(x) FIELD_PREP(INT_CTRL_MASK, (x)) + +#define DSI_WRITE_REG1 0x54 +#define GMP_CTRL_MASK GENMASK(1, 0) +#define GMP_CTRL(x) FIELD_PREP(GMP_CTRL_MASK, (x)) +#define CPBIAS_CTRL_MASK GENMASK(8, 2) +#define CPBIAS_CTRL(x) FIELD_PREP(CPBIAS_CTRL_MASK, (x)) +#define PLL_SHADOW_CTRL BIT(9) + +/* display mux control register */ +#define DISPLAY_MUX 0x60 +#define MIPI_DSI_RGB666_MAP_CFG GENMASK(7, 6) +#define RGB666_CONFIG1 FIELD_PREP(MIPI_DSI_RGB666_MAP_CFG, 0) +#define RGB666_CONFIG2 FIELD_PREP(MIPI_DSI_RGB666_MAP_CFG, 1) +#define MIPI_DSI_RGB565_MAP_CFG GENMASK(5, 4) +#define RGB565_CONFIG1 FIELD_PREP(MIPI_DSI_RGB565_MAP_CFG, 0) +#define RGB565_CONFIG2 FIELD_PREP(MIPI_DSI_RGB565_MAP_CFG, 1) +#define RGB565_CONFIG3 FIELD_PREP(MIPI_DSI_RGB565_MAP_CFG, 2) +#define LCDIF_CROSS_LINE_PATTERN GENMASK(3, 0) +#define RGB888_TO_RGB888 FIELD_PREP(LCDIF_CROSS_LINE_PATTERN, 0) +#define RGB888_TO_RGB666 FIELD_PREP(LCDIF_CROSS_LINE_PATTERN, 6) +#define RGB565_TO_RGB565 FIELD_PREP(LCDIF_CROSS_LINE_PATTERN, 7) + +#define MHZ(x) ((x) * 1000000UL) + +#define REF_CLK_RATE_MAX MHZ(64) +#define REF_CLK_RATE_MIN MHZ(2) +#define FOUT_MAX MHZ(1250) +#define FOUT_MIN MHZ(40) +#define FVCO_DIV_FACTOR MHZ(80) + +#define MBPS(x) ((x) * 1000000UL) + +#define DATA_RATE_MAX_SPEED MBPS(2500) +#define DATA_RATE_MIN_SPEED MBPS(80) + +#define M_MAX 625UL +#define M_MIN 64UL + +#define N_MAX 16U +#define N_MIN 1U + +struct imx93_dsi { + struct device *dev; + struct regmap *regmap; + struct clk *clk_pixel; + struct clk *clk_ref; + struct clk *clk_cfg; + struct dw_mipi_dsi *dmd; + struct dw_mipi_dsi_plat_data pdata; + union phy_configure_opts phy_cfg; + unsigned long ref_clk_rate; + u32 format; +}; + +struct dphy_pll_cfg { + u32 m; /* PLL Feedback Multiplication Ratio */ + u32 n; /* PLL Input Frequency Division Ratio */ +}; + +struct dphy_pll_vco_prop { + unsigned long max_fout; + u8 vco_cntl; + u8 prop_cntl; +}; + +struct dphy_pll_hsfreqrange { + unsigned long max_mbps; + u8 hsfreqrange; +}; + +/* DPHY Databook Table 3-13 Charge-pump Programmability */ +static const struct dphy_pll_vco_prop vco_prop_map[] = { + { 55, 0x3f, 0x0d }, + { 82, 0x37, 0x0d }, + { 110, 0x2f, 0x0d }, + { 165, 0x27, 0x0d }, + { 220, 0x1f, 0x0d }, + { 330, 0x17, 0x0d }, + { 440, 0x0f, 0x0d }, + { 660, 0x07, 0x0d }, + { 1149, 0x03, 0x0d }, + { 1152, 0x01, 0x0d }, + { 1250, 0x01, 0x0e }, +}; + +/* DPHY Databook Table 5-7 Frequency Ranges and Defaults */ +static const struct dphy_pll_hsfreqrange hsfreqrange_map[] = { + { 89, 0x00 }, + { 99, 0x10 }, + { 109, 0x20 }, + { 119, 0x30 }, + { 129, 0x01 }, + { 139, 0x11 }, + { 149, 0x21 }, + { 159, 0x31 }, + { 169, 0x02 }, + { 179, 0x12 }, + { 189, 0x22 }, + { 204, 0x32 }, + { 219, 0x03 }, + { 234, 0x13 }, + { 249, 0x23 }, + { 274, 0x33 }, + { 299, 0x04 }, + { 324, 0x14 }, + { 349, 0x25 }, + { 399, 0x35 }, + { 449, 0x05 }, + { 499, 0x16 }, + { 549, 0x26 }, + { 599, 0x37 }, + { 649, 0x07 }, + { 699, 0x18 }, + { 749, 0x28 }, + { 799, 0x39 }, + { 849, 0x09 }, + { 899, 0x19 }, + { 949, 0x29 }, + { 999, 0x3a }, + { 1049, 0x0a }, + { 1099, 0x1a }, + { 1149, 0x2a }, + { 1199, 0x3b }, + { 1249, 0x0b }, + { 1299, 0x1b }, + { 1349, 0x2b }, + { 1399, 0x3c }, + { 1449, 0x0c }, + { 1499, 0x1c }, + { 1549, 0x2c }, + { 1599, 0x3d }, + { 1649, 0x0d }, + { 1699, 0x1d }, + { 1749, 0x2e }, + { 1799, 0x3e }, + { 1849, 0x0e }, + { 1899, 0x1e }, + { 1949, 0x2f }, + { 1999, 0x3f }, + { 2049, 0x0f }, + { 2099, 0x40 }, + { 2149, 0x41 }, + { 2199, 0x42 }, + { 2249, 0x43 }, + { 2299, 0x44 }, + { 2349, 0x45 }, + { 2399, 0x46 }, + { 2449, 0x47 }, + { 2499, 0x48 }, + { 2500, 0x49 }, +}; + +static void dphy_pll_write(struct imx93_dsi *dsi, unsigned int reg, u32 value) +{ + int ret; + + ret = regmap_write(dsi->regmap, reg, value); + if (ret < 0) + dev_err(dsi->dev, "failed to write 0x%08x to pll reg 0x%x: %d\n", + value, reg, ret); +} + +static inline unsigned long data_rate_to_fout(unsigned long data_rate) +{ + /* Fout is half of data rate */ + return data_rate / 2; +} + +static int +dphy_pll_get_configure_from_opts(struct imx93_dsi *dsi, + struct phy_configure_opts_mipi_dphy *dphy_opts, + struct dphy_pll_cfg *cfg) +{ + struct device *dev = dsi->dev; + unsigned long fin = dsi->ref_clk_rate; + unsigned long fout; + unsigned long best_fout = 0; + unsigned int fvco_div; + unsigned int min_n, max_n, n, best_n; + unsigned long m, best_m; + unsigned long min_delta = ULONG_MAX; + unsigned long delta; + u64 tmp; + + if (dphy_opts->hs_clk_rate < DATA_RATE_MIN_SPEED || + dphy_opts->hs_clk_rate > DATA_RATE_MAX_SPEED) { + dev_dbg(dev, "invalid data rate per lane: %lu\n", + dphy_opts->hs_clk_rate); + return -EINVAL; + } + + fout = data_rate_to_fout(dphy_opts->hs_clk_rate); + + /* DPHY Databook 3.3.6.1 Output Frequency */ + /* Fout = Fvco / Fvco_div = (Fin * M) / (Fvco_div * N) */ + /* Fvco_div could be 1/2/4/8 according to Fout range. */ + fvco_div = 8UL / min(DIV_ROUND_UP(fout, FVCO_DIV_FACTOR), 8UL); + + /* limitation: 2MHz <= Fin / N <= 8MHz */ + min_n = DIV_ROUND_UP_ULL((u64)fin, MHZ(8)); + max_n = DIV_ROUND_DOWN_ULL((u64)fin, MHZ(2)); + + /* clamp possible N(s) */ + min_n = clamp(min_n, N_MIN, N_MAX); + max_n = clamp(max_n, N_MIN, N_MAX); + + dev_dbg(dev, "Fout = %lu, Fvco_div = %u, n_range = [%u, %u]\n", + fout, fvco_div, min_n, max_n); + + for (n = min_n; n <= max_n; n++) { + /* M = (Fout * N * Fvco_div) / Fin */ + m = DIV_ROUND_CLOSEST(fout * n * fvco_div, fin); + + /* check M range */ + if (m < M_MIN || m > M_MAX) + continue; + + /* calculate temporary Fout */ + tmp = m * fin; + do_div(tmp, n * fvco_div); + if (tmp < FOUT_MIN || tmp > FOUT_MAX) + continue; + + delta = abs(fout - tmp); + if (delta < min_delta) { + best_n = n; + best_m = m; + min_delta = delta; + best_fout = tmp; + } + } + + if (best_fout) { + cfg->m = best_m; + cfg->n = best_n; + dev_dbg(dev, "best Fout = %lu, m = %u, n = %u\n", + best_fout, cfg->m, cfg->n); + } else { + dev_dbg(dev, "failed to find best Fout\n"); + return -EINVAL; + } + + return 0; +} + +static void dphy_pll_clear_shadow(struct imx93_dsi *dsi) +{ + /* Reference DPHY Databook Figure 3-3 Initialization Timing Diagram. */ + /* Select clock generation first. */ + dphy_pll_write(dsi, DSI_REG, CLKSEL_GEN); + + /* Clear shadow after clock selection is done a while. */ + fsleep(1); + dphy_pll_write(dsi, DSI_REG, CLKSEL_GEN | SHADOW_CLR); + + /* A minimum pulse of 5ns on shadow_clear signal. */ + fsleep(1); + dphy_pll_write(dsi, DSI_REG, CLKSEL_GEN); +} + +static unsigned long dphy_pll_get_cfgclkrange(struct imx93_dsi *dsi) +{ + /* + * DPHY Databook Table 4-4 System Control Signals mentions an equation + * for cfgclkfreqrange[5:0]. + */ + return (clk_get_rate(dsi->clk_cfg) / MHZ(1) - 17) * 4; +} + +static u8 +dphy_pll_get_hsfreqrange(struct phy_configure_opts_mipi_dphy *dphy_opts) +{ + unsigned long mbps = dphy_opts->hs_clk_rate / MHZ(1); + int i; + + for (i = 0; i < ARRAY_SIZE(hsfreqrange_map); i++) + if (mbps <= hsfreqrange_map[i].max_mbps) + return hsfreqrange_map[i].hsfreqrange; + + return 0; +} + +static u8 dphy_pll_get_vco(struct phy_configure_opts_mipi_dphy *dphy_opts) +{ + unsigned long fout = data_rate_to_fout(dphy_opts->hs_clk_rate) / MHZ(1); + int i; + + for (i = 0; i < ARRAY_SIZE(vco_prop_map); i++) + if (fout <= vco_prop_map[i].max_fout) + return vco_prop_map[i].vco_cntl; + + return 0; +} + +static u8 dphy_pll_get_prop(struct phy_configure_opts_mipi_dphy *dphy_opts) +{ + unsigned long fout = data_rate_to_fout(dphy_opts->hs_clk_rate) / MHZ(1); + int i; + + for (i = 0; i < ARRAY_SIZE(vco_prop_map); i++) + if (fout <= vco_prop_map[i].max_fout) + return vco_prop_map[i].prop_cntl; + + return 0; +} + +static int dphy_pll_update(struct imx93_dsi *dsi) +{ + int ret; + + ret = regmap_update_bits(dsi->regmap, DSI_REG, UPDATE_PLL, UPDATE_PLL); + if (ret < 0) { + dev_err(dsi->dev, "failed to set UPDATE_PLL: %d\n", ret); + return ret; + } + + /* + * The updatepll signal should be asserted for a minimum of four clkin + * cycles, according to DPHY Databook Figure 3-3 Initialization Timing + * Diagram. + */ + fsleep(10); + + ret = regmap_update_bits(dsi->regmap, DSI_REG, UPDATE_PLL, 0); + if (ret < 0) { + dev_err(dsi->dev, "failed to clear UPDATE_PLL: %d\n", ret); + return ret; + } + + return 0; +} + +static int dphy_pll_configure(struct imx93_dsi *dsi, union phy_configure_opts *opts) +{ + struct dphy_pll_cfg cfg = { 0 }; + u32 val; + int ret; + + ret = dphy_pll_get_configure_from_opts(dsi, &opts->mipi_dphy, &cfg); + if (ret) { + dev_err(dsi->dev, "failed to get phy pll cfg %d\n", ret); + return ret; + } + + dphy_pll_clear_shadow(dsi); + + /* DSI_REG */ + val = CLKSEL_GEN | + CFGCLKFREQRANGE(dphy_pll_get_cfgclkrange(dsi)) | + HSFREQRANGE(dphy_pll_get_hsfreqrange(&opts->mipi_dphy)); + dphy_pll_write(dsi, DSI_REG, val); + + /* DSI_WRITE_REG0 */ + val = M(cfg.m) | N(cfg.n) | INT_CTRL(0) | + VCO_CTRL(dphy_pll_get_vco(&opts->mipi_dphy)) | + PROP_CTRL(dphy_pll_get_prop(&opts->mipi_dphy)); + dphy_pll_write(dsi, DSI_WRITE_REG0, val); + + /* DSI_WRITE_REG1 */ + dphy_pll_write(dsi, DSI_WRITE_REG1, GMP_CTRL(1) | CPBIAS_CTRL(0x10)); + + ret = clk_prepare_enable(dsi->clk_ref); + if (ret < 0) { + dev_err(dsi->dev, "failed to enable ref clock: %d\n", ret); + return ret; + } + + /* + * At least 10 refclk cycles are required before updatePLL assertion, + * according to DPHY Databook Figure 3-3 Initialization Timing Diagram. + */ + fsleep(10); + + ret = dphy_pll_update(dsi); + if (ret < 0) { + clk_disable_unprepare(dsi->clk_ref); + return ret; + } + + return 0; +} + +static void dphy_pll_clear_reg(struct imx93_dsi *dsi) +{ + dphy_pll_write(dsi, DSI_REG, 0); + dphy_pll_write(dsi, DSI_WRITE_REG0, 0); + dphy_pll_write(dsi, DSI_WRITE_REG1, 0); +} + +static int dphy_pll_init(struct imx93_dsi *dsi) +{ + int ret; + + ret = clk_prepare_enable(dsi->clk_cfg); + if (ret < 0) { + dev_err(dsi->dev, "failed to enable config clock: %d\n", ret); + return ret; + } + + dphy_pll_clear_reg(dsi); + + return 0; +} + +static void dphy_pll_uninit(struct imx93_dsi *dsi) +{ + dphy_pll_clear_reg(dsi); + clk_disable_unprepare(dsi->clk_cfg); +} + +static void dphy_pll_power_off(struct imx93_dsi *dsi) +{ + dphy_pll_clear_reg(dsi); + clk_disable_unprepare(dsi->clk_ref); +} + +static int imx93_dsi_get_phy_configure_opts(struct imx93_dsi *dsi, + const struct drm_display_mode *mode, + union phy_configure_opts *phy_cfg, + u32 lanes, u32 format) +{ + struct device *dev = dsi->dev; + int bpp; + int ret; + + bpp = mipi_dsi_pixel_format_to_bpp(format); + if (bpp < 0) { + dev_dbg(dev, "failed to get bpp for pixel format %d\n", format); + return -EINVAL; + } + + ret = phy_mipi_dphy_get_default_config(mode->clock * MSEC_PER_SEC, bpp, + lanes, &phy_cfg->mipi_dphy); + if (ret < 0) { + dev_dbg(dev, "failed to get default phy cfg %d\n", ret); + return ret; + } + + return 0; +} + +static enum drm_mode_status +imx93_dsi_validate_mode(struct imx93_dsi *dsi, const struct drm_display_mode *mode) +{ + struct drm_bridge *bridge = dw_mipi_dsi_get_bridge(dsi->dmd); + + /* Get the last bridge */ + while (drm_bridge_get_next_bridge(bridge)) + bridge = drm_bridge_get_next_bridge(bridge); + + if ((bridge->ops & DRM_BRIDGE_OP_DETECT) && + (bridge->ops & DRM_BRIDGE_OP_EDID)) { + unsigned long pixel_clock_rate = mode->clock * 1000; + unsigned long rounded_rate; + + /* Allow +/-0.5% pixel clock rate deviation */ + rounded_rate = clk_round_rate(dsi->clk_pixel, pixel_clock_rate); + if (rounded_rate < pixel_clock_rate * 995 / 1000 || + rounded_rate > pixel_clock_rate * 1005 / 1000) { + dev_dbg(dsi->dev, "failed to round clock for mode " DRM_MODE_FMT "\n", + DRM_MODE_ARG(mode)); + return MODE_NOCLOCK; + } + } + + return MODE_OK; +} + +static enum drm_mode_status +imx93_dsi_validate_phy(struct imx93_dsi *dsi, const struct drm_display_mode *mode, + unsigned long mode_flags, u32 lanes, u32 format) +{ + union phy_configure_opts phy_cfg; + struct dphy_pll_cfg cfg = { 0 }; + struct device *dev = dsi->dev; + int ret; + + ret = imx93_dsi_get_phy_configure_opts(dsi, mode, &phy_cfg, lanes, + format); + if (ret < 0) { + dev_dbg(dev, "failed to get phy cfg opts %d\n", ret); + return MODE_ERROR; + } + + ret = dphy_pll_get_configure_from_opts(dsi, &phy_cfg.mipi_dphy, &cfg); + if (ret < 0) { + dev_dbg(dev, "failed to get phy pll cfg %d\n", ret); + return MODE_NOCLOCK; + } + + return MODE_OK; +} + +static enum drm_mode_status +imx93_dsi_mode_valid(void *priv_data, const struct drm_display_mode *mode, + unsigned long mode_flags, u32 lanes, u32 format) +{ + struct imx93_dsi *dsi = priv_data; + struct device *dev = dsi->dev; + enum drm_mode_status ret; + + ret = imx93_dsi_validate_mode(dsi, mode); + if (ret != MODE_OK) { + dev_dbg(dev, "failed to validate mode " DRM_MODE_FMT "\n", + DRM_MODE_ARG(mode)); + return ret; + } + + ret = imx93_dsi_validate_phy(dsi, mode, mode_flags, lanes, format); + if (ret != MODE_OK) { + dev_dbg(dev, "failed to validate phy for mode " DRM_MODE_FMT "\n", + DRM_MODE_ARG(mode)); + return ret; + } + + return MODE_OK; +} + +static bool imx93_dsi_mode_fixup(void *priv_data, + const struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + struct imx93_dsi *dsi = priv_data; + unsigned long pixel_clock_rate; + unsigned long rounded_rate; + + pixel_clock_rate = mode->clock * 1000; + rounded_rate = clk_round_rate(dsi->clk_pixel, pixel_clock_rate); + + memcpy(adjusted_mode, mode, sizeof(*mode)); + adjusted_mode->clock = rounded_rate / 1000; + + dev_dbg(dsi->dev, "adj clock %d for mode " DRM_MODE_FMT "\n", + adjusted_mode->clock, DRM_MODE_ARG(mode)); + + return true; +} + +static u32 *imx93_dsi_get_input_bus_fmts(void *priv_data, + struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state, + u32 output_fmt, + unsigned int *num_input_fmts) +{ + u32 *input_fmts, input_fmt; + + *num_input_fmts = 0; + + switch (output_fmt) { + case MEDIA_BUS_FMT_RGB888_1X24: + case MEDIA_BUS_FMT_RGB666_1X18: + case MEDIA_BUS_FMT_FIXED: + input_fmt = MEDIA_BUS_FMT_RGB888_1X24; + break; + case MEDIA_BUS_FMT_RGB565_1X16: + input_fmt = output_fmt; + break; + default: + return NULL; + } + + input_fmts = kmalloc(sizeof(*input_fmts), GFP_KERNEL); + if (!input_fmts) + return NULL; + input_fmts[0] = input_fmt; + *num_input_fmts = 1; + + return input_fmts; +} + +static int imx93_dsi_phy_init(void *priv_data) +{ + struct imx93_dsi *dsi = priv_data; + unsigned int fmt = 0; + int ret; + + switch (dsi->format) { + case MIPI_DSI_FMT_RGB888: + fmt = RGB888_TO_RGB888; + break; + case MIPI_DSI_FMT_RGB666: + fmt = RGB888_TO_RGB666; + regmap_update_bits(dsi->regmap, DISPLAY_MUX, + MIPI_DSI_RGB666_MAP_CFG, RGB666_CONFIG2); + break; + case MIPI_DSI_FMT_RGB666_PACKED: + fmt = RGB888_TO_RGB666; + regmap_update_bits(dsi->regmap, DISPLAY_MUX, + MIPI_DSI_RGB666_MAP_CFG, RGB666_CONFIG1); + break; + case MIPI_DSI_FMT_RGB565: + fmt = RGB565_TO_RGB565; + regmap_update_bits(dsi->regmap, DISPLAY_MUX, + MIPI_DSI_RGB565_MAP_CFG, RGB565_CONFIG1); + break; + } + + regmap_update_bits(dsi->regmap, DISPLAY_MUX, LCDIF_CROSS_LINE_PATTERN, fmt); + + ret = dphy_pll_init(dsi); + if (ret < 0) { + dev_err(dsi->dev, "failed to init phy pll: %d\n", ret); + return ret; + } + + ret = dphy_pll_configure(dsi, &dsi->phy_cfg); + if (ret < 0) { + dev_err(dsi->dev, "failed to configure phy pll: %d\n", ret); + dphy_pll_uninit(dsi); + return ret; + } + + return 0; +} + +static void imx93_dsi_phy_power_off(void *priv_data) +{ + struct imx93_dsi *dsi = priv_data; + + dphy_pll_power_off(dsi); + dphy_pll_uninit(dsi); +} + +static int +imx93_dsi_get_lane_mbps(void *priv_data, const struct drm_display_mode *mode, + unsigned long mode_flags, u32 lanes, u32 format, + unsigned int *lane_mbps) +{ + struct imx93_dsi *dsi = priv_data; + union phy_configure_opts phy_cfg; + struct device *dev = dsi->dev; + int ret; + + ret = imx93_dsi_get_phy_configure_opts(dsi, mode, &phy_cfg, lanes, + format); + if (ret < 0) { + dev_dbg(dev, "failed to get phy cfg opts %d\n", ret); + return ret; + } + + *lane_mbps = DIV_ROUND_UP(phy_cfg.mipi_dphy.hs_clk_rate, USEC_PER_SEC); + + memcpy(&dsi->phy_cfg, &phy_cfg, sizeof(phy_cfg)); + + dev_dbg(dev, "get lane_mbps %u for mode " DRM_MODE_FMT "\n", + *lane_mbps, DRM_MODE_ARG(mode)); + + return 0; +} + +/* High-Speed Transition Times */ +struct hstt { + unsigned int maxfreq; + struct dw_mipi_dsi_dphy_timing timing; +}; + +#define HSTT(_maxfreq, _c_lp2hs, _c_hs2lp, _d_lp2hs, _d_hs2lp) \ +{ \ + .maxfreq = (_maxfreq), \ + .timing = { \ + .clk_lp2hs = (_c_lp2hs), \ + .clk_hs2lp = (_c_hs2lp), \ + .data_lp2hs = (_d_lp2hs), \ + .data_hs2lp = (_d_hs2lp), \ + } \ +} + +/* DPHY Databook Table A-4 High-Speed Transition Times */ +static const struct hstt hstt_table[] = { + HSTT(80, 21, 17, 15, 10), + HSTT(90, 23, 17, 16, 10), + HSTT(100, 22, 17, 16, 10), + HSTT(110, 25, 18, 17, 11), + HSTT(120, 26, 20, 18, 11), + HSTT(130, 27, 19, 19, 11), + HSTT(140, 27, 19, 19, 11), + HSTT(150, 28, 20, 20, 12), + HSTT(160, 30, 21, 22, 13), + HSTT(170, 30, 21, 23, 13), + HSTT(180, 31, 21, 23, 13), + HSTT(190, 32, 22, 24, 13), + HSTT(205, 35, 22, 25, 13), + HSTT(220, 37, 26, 27, 15), + HSTT(235, 38, 28, 27, 16), + HSTT(250, 41, 29, 30, 17), + HSTT(275, 43, 29, 32, 18), + HSTT(300, 45, 32, 35, 19), + HSTT(325, 48, 33, 36, 18), + HSTT(350, 51, 35, 40, 20), + HSTT(400, 59, 37, 44, 21), + HSTT(450, 65, 40, 49, 23), + HSTT(500, 71, 41, 54, 24), + HSTT(550, 77, 44, 57, 26), + HSTT(600, 82, 46, 64, 27), + HSTT(650, 87, 48, 67, 28), + HSTT(700, 94, 52, 71, 29), + HSTT(750, 99, 52, 75, 31), + HSTT(800, 105, 55, 82, 32), + HSTT(850, 110, 58, 85, 32), + HSTT(900, 115, 58, 88, 35), + HSTT(950, 120, 62, 93, 36), + HSTT(1000, 128, 63, 99, 38), + HSTT(1050, 132, 65, 102, 38), + HSTT(1100, 138, 67, 106, 39), + HSTT(1150, 146, 69, 112, 42), + HSTT(1200, 151, 71, 117, 43), + HSTT(1250, 153, 74, 120, 45), + HSTT(1300, 160, 73, 124, 46), + HSTT(1350, 165, 76, 130, 47), + HSTT(1400, 172, 78, 134, 49), + HSTT(1450, 177, 80, 138, 49), + HSTT(1500, 183, 81, 143, 52), + HSTT(1550, 191, 84, 147, 52), + HSTT(1600, 194, 85, 152, 52), + HSTT(1650, 201, 86, 155, 53), + HSTT(1700, 208, 88, 161, 53), + HSTT(1750, 212, 89, 165, 53), + HSTT(1800, 220, 90, 171, 54), + HSTT(1850, 223, 92, 175, 54), + HSTT(1900, 231, 91, 180, 55), + HSTT(1950, 236, 95, 185, 56), + HSTT(2000, 243, 97, 190, 56), + HSTT(2050, 248, 99, 194, 58), + HSTT(2100, 252, 100, 199, 59), + HSTT(2150, 259, 102, 204, 61), + HSTT(2200, 266, 105, 210, 62), + HSTT(2250, 269, 109, 213, 63), + HSTT(2300, 272, 109, 217, 65), + HSTT(2350, 281, 112, 225, 66), + HSTT(2400, 283, 115, 226, 66), + HSTT(2450, 282, 115, 226, 67), + HSTT(2500, 281, 118, 227, 67), +}; + +static int imx93_dsi_phy_get_timing(void *priv_data, unsigned int lane_mbps, + struct dw_mipi_dsi_dphy_timing *timing) +{ + struct imx93_dsi *dsi = priv_data; + struct device *dev = dsi->dev; + int i; + + for (i = 0; i < ARRAY_SIZE(hstt_table); i++) + if (lane_mbps <= hstt_table[i].maxfreq) + break; + + if (i == ARRAY_SIZE(hstt_table)) { + dev_err(dev, "failed to get phy timing for lane_mbps %u\n", + lane_mbps); + return -EINVAL; + } + + *timing = hstt_table[i].timing; + + dev_dbg(dev, "get phy timing for %u <= %u (lane_mbps)\n", + lane_mbps, hstt_table[i].maxfreq); + + return 0; +} + +static const struct dw_mipi_dsi_phy_ops imx93_dsi_phy_ops = { + .init = imx93_dsi_phy_init, + .power_off = imx93_dsi_phy_power_off, + .get_lane_mbps = imx93_dsi_get_lane_mbps, + .get_timing = imx93_dsi_phy_get_timing, +}; + +static int imx93_dsi_host_attach(void *priv_data, struct mipi_dsi_device *device) +{ + struct imx93_dsi *dsi = priv_data; + + dsi->format = device->format; + + return 0; +} + +static const struct dw_mipi_dsi_host_ops imx93_dsi_host_ops = { + .attach = imx93_dsi_host_attach, +}; + +static int imx93_dsi_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct imx93_dsi *dsi; + int ret; + + dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL); + if (!dsi) + return -ENOMEM; + + dsi->regmap = syscon_regmap_lookup_by_phandle(np, "fsl,media-blk-ctrl"); + if (IS_ERR(dsi->regmap)) { + ret = PTR_ERR(dsi->regmap); + dev_err(dev, "failed to get block ctrl regmap: %d\n", ret); + return ret; + } + + dsi->clk_pixel = devm_clk_get(dev, "pix"); + if (IS_ERR(dsi->clk_pixel)) + return dev_err_probe(dev, PTR_ERR(dsi->clk_pixel), + "failed to get pixel clock\n"); + + dsi->clk_cfg = devm_clk_get(dev, "phy_cfg"); + if (IS_ERR(dsi->clk_cfg)) + return dev_err_probe(dev, PTR_ERR(dsi->clk_cfg), + "failed to get phy cfg clock\n"); + + dsi->clk_ref = devm_clk_get(dev, "phy_ref"); + if (IS_ERR(dsi->clk_ref)) + return dev_err_probe(dev, PTR_ERR(dsi->clk_ref), + "failed to get phy ref clock\n"); + + dsi->ref_clk_rate = clk_get_rate(dsi->clk_ref); + if (dsi->ref_clk_rate < REF_CLK_RATE_MIN || + dsi->ref_clk_rate > REF_CLK_RATE_MAX) { + dev_err(dev, "invalid phy ref clock rate %lu\n", + dsi->ref_clk_rate); + return -EINVAL; + } + dev_dbg(dev, "phy ref clock rate: %lu\n", dsi->ref_clk_rate); + + dsi->dev = dev; + dsi->pdata.max_data_lanes = 4; + dsi->pdata.mode_valid = imx93_dsi_mode_valid; + dsi->pdata.mode_fixup = imx93_dsi_mode_fixup; + dsi->pdata.get_input_bus_fmts = imx93_dsi_get_input_bus_fmts; + dsi->pdata.phy_ops = &imx93_dsi_phy_ops; + dsi->pdata.host_ops = &imx93_dsi_host_ops; + dsi->pdata.priv_data = dsi; + platform_set_drvdata(pdev, dsi); + + dsi->dmd = dw_mipi_dsi_probe(pdev, &dsi->pdata); + if (IS_ERR(dsi->dmd)) + return dev_err_probe(dev, PTR_ERR(dsi->dmd), + "failed to probe dw_mipi_dsi\n"); + + return 0; +} + +static void imx93_dsi_remove(struct platform_device *pdev) +{ + struct imx93_dsi *dsi = platform_get_drvdata(pdev); + + dw_mipi_dsi_remove(dsi->dmd); +} + +static const struct of_device_id imx93_dsi_dt_ids[] = { + { .compatible = "fsl,imx93-mipi-dsi", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, imx93_dsi_dt_ids); + +static struct platform_driver imx93_dsi_driver = { + .probe = imx93_dsi_probe, + .remove_new = imx93_dsi_remove, + .driver = { + .of_match_table = imx93_dsi_dt_ids, + .name = "imx93_mipi_dsi", + }, +}; +module_platform_driver(imx93_dsi_driver); + +MODULE_DESCRIPTION("Freescale i.MX93 MIPI DSI driver"); +MODULE_AUTHOR("Liu Ying <victor.liu@nxp.com>"); +MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c index 7835738a532e..e971b75e90ad 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c +++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c @@ -929,9 +929,9 @@ retry: init_waitqueue_head(<9611uxc->wq); INIT_WORK(<9611uxc->work, lt9611uxc_hpd_work); - ret = devm_request_threaded_irq(dev, client->irq, NULL, - lt9611uxc_irq_thread_handler, - IRQF_ONESHOT, "lt9611uxc", lt9611uxc); + ret = request_threaded_irq(client->irq, NULL, + lt9611uxc_irq_thread_handler, + IRQF_ONESHOT, "lt9611uxc", lt9611uxc); if (ret) { dev_err(dev, "failed to request irq\n"); goto err_disable_regulators; @@ -967,6 +967,8 @@ retry: return lt9611uxc_audio_init(dev, lt9611uxc); err_remove_bridge: + free_irq(client->irq, lt9611uxc); + cancel_work_sync(<9611uxc->work); drm_bridge_remove(<9611uxc->bridge); err_disable_regulators: @@ -983,7 +985,7 @@ static void lt9611uxc_remove(struct i2c_client *client) { struct lt9611uxc *lt9611uxc = i2c_get_clientdata(client); - disable_irq(client->irq); + free_irq(client->irq, lt9611uxc); cancel_work_sync(<9611uxc->work); lt9611uxc_audio_exit(lt9611uxc); drm_bridge_remove(<9611uxc->bridge); diff --git a/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c b/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c index 460db3c8a08c..e93083bbec9d 100644 --- a/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c +++ b/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c @@ -65,12 +65,11 @@ struct ge_b850v3_lvds { static struct ge_b850v3_lvds *ge_b850v3_lvds_ptr; -static u8 *stdp2690_get_edid(struct i2c_client *client) +static int stdp2690_read_block(void *context, u8 *buf, unsigned int block, size_t len) { + struct i2c_client *client = context; struct i2c_adapter *adapter = client->adapter; - unsigned char start = 0x00; - unsigned int total_size; - u8 *block = kmalloc(EDID_LENGTH, GFP_KERNEL); + unsigned char start = block * EDID_LENGTH; struct i2c_msg msgs[] = { { @@ -81,53 +80,15 @@ static u8 *stdp2690_get_edid(struct i2c_client *client) }, { .addr = client->addr, .flags = I2C_M_RD, - .len = EDID_LENGTH, - .buf = block, + .len = len, + .buf = buf, } }; - if (!block) - return NULL; + if (i2c_transfer(adapter, msgs, 2) != 2) + return -1; - if (i2c_transfer(adapter, msgs, 2) != 2) { - DRM_ERROR("Unable to read EDID.\n"); - goto err; - } - - if (!drm_edid_block_valid(block, 0, false, NULL)) { - DRM_ERROR("Invalid EDID data\n"); - goto err; - } - - total_size = (block[EDID_EXT_BLOCK_CNT] + 1) * EDID_LENGTH; - if (total_size > EDID_LENGTH) { - kfree(block); - block = kmalloc(total_size, GFP_KERNEL); - if (!block) - return NULL; - - /* Yes, read the entire buffer, and do not skip the first - * EDID_LENGTH bytes. - */ - start = 0x00; - msgs[1].len = total_size; - msgs[1].buf = block; - - if (i2c_transfer(adapter, msgs, 2) != 2) { - DRM_ERROR("Unable to read EDID extension blocks.\n"); - goto err; - } - if (!drm_edid_block_valid(block, 1, false, NULL)) { - DRM_ERROR("Invalid EDID data\n"); - goto err; - } - } - - return block; - -err: - kfree(block); - return NULL; + return 0; } static struct edid *ge_b850v3_lvds_get_edid(struct drm_bridge *bridge, @@ -137,7 +98,7 @@ static struct edid *ge_b850v3_lvds_get_edid(struct drm_bridge *bridge, client = ge_b850v3_lvds_ptr->stdp2690_i2c; - return (struct edid *)stdp2690_get_edid(client); + return drm_do_get_edid(connector, stdp2690_read_block, client); } static int ge_b850v3_lvds_get_modes(struct drm_connector *connector) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c index a8dd2a2e7c7b..824fb3c65742 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c @@ -12,6 +12,8 @@ #include <linux/component.h> #include <linux/debugfs.h> #include <linux/iopoll.h> +#include <linux/math64.h> +#include <linux/media-bus-format.h> #include <linux/module.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> @@ -22,6 +24,7 @@ #include <drm/bridge/dw_mipi_dsi.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_bridge.h> +#include <drm/drm_connector.h> #include <drm/drm_crtc.h> #include <drm/drm_mipi_dsi.h> #include <drm/drm_modes.h> @@ -538,6 +541,59 @@ static const struct mipi_dsi_host_ops dw_mipi_dsi_host_ops = { .transfer = dw_mipi_dsi_host_transfer, }; +static u32 * +dw_mipi_dsi_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state, + u32 output_fmt, + unsigned int *num_input_fmts) +{ + struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge); + const struct dw_mipi_dsi_plat_data *pdata = dsi->plat_data; + u32 *input_fmts; + + if (pdata->get_input_bus_fmts) + return pdata->get_input_bus_fmts(pdata->priv_data, + bridge, bridge_state, + crtc_state, conn_state, + output_fmt, num_input_fmts); + + /* Fall back to MEDIA_BUS_FMT_FIXED as the only input format. */ + input_fmts = kmalloc(sizeof(*input_fmts), GFP_KERNEL); + if (!input_fmts) + return NULL; + input_fmts[0] = MEDIA_BUS_FMT_FIXED; + *num_input_fmts = 1; + + return input_fmts; +} + +static int dw_mipi_dsi_bridge_atomic_check(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state) +{ + struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge); + const struct dw_mipi_dsi_plat_data *pdata = dsi->plat_data; + bool ret; + + bridge_state->input_bus_cfg.flags = + DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE; + + if (pdata->mode_fixup) { + ret = pdata->mode_fixup(pdata->priv_data, &crtc_state->mode, + &crtc_state->adjusted_mode); + if (!ret) { + DRM_DEBUG_DRIVER("failed to fixup mode " DRM_MODE_FMT "\n", + DRM_MODE_ARG(&crtc_state->mode)); + return -EINVAL; + } + } + + return 0; +} + static void dw_mipi_dsi_video_mode_config(struct dw_mipi_dsi *dsi) { u32 val; @@ -630,7 +686,7 @@ static void dw_mipi_dsi_init(struct dw_mipi_dsi *dsi) * timeout clock division should be computed with the * high speed transmission counter timeout and byte lane... */ - dsi_write(dsi, DSI_CLKMGR_CFG, TO_CLK_DIVISION(10) | + dsi_write(dsi, DSI_CLKMGR_CFG, TO_CLK_DIVISION(0) | TX_ESC_CLK_DIVISION(esc_clk_division)); } @@ -693,7 +749,7 @@ static void dw_mipi_dsi_command_mode_config(struct dw_mipi_dsi *dsi) * compute high speed transmission counter timeout according * to the timeout clock division (TO_CLK_DIVISION) and byte lane... */ - dsi_write(dsi, DSI_TO_CNT_CFG, HSTX_TO_CNT(1000) | LPRX_TO_CNT(1000)); + dsi_write(dsi, DSI_TO_CNT_CFG, HSTX_TO_CNT(0) | LPRX_TO_CNT(0)); /* * TODO dw drv improvements * the Bus-Turn-Around Timeout Counter should be computed @@ -703,20 +759,45 @@ static void dw_mipi_dsi_command_mode_config(struct dw_mipi_dsi *dsi) dsi_write(dsi, DSI_MODE_CFG, ENABLE_CMD_MODE); } +static const u32 minimum_lbccs[] = {10, 5, 4, 3}; + +static inline u32 dw_mipi_dsi_get_minimum_lbcc(struct dw_mipi_dsi *dsi) +{ + return minimum_lbccs[dsi->lanes - 1]; +} + /* Get lane byte clock cycles. */ static u32 dw_mipi_dsi_get_hcomponent_lbcc(struct dw_mipi_dsi *dsi, const struct drm_display_mode *mode, u32 hcomponent) { - u32 frac, lbcc; + u32 frac, lbcc, minimum_lbcc; + int bpp; - lbcc = hcomponent * dsi->lane_mbps * MSEC_PER_SEC / 8; + if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) { + /* lbcc based on lane_mbps */ + lbcc = hcomponent * dsi->lane_mbps * MSEC_PER_SEC / 8; + } else { + /* lbcc based on pixel clock rate */ + bpp = mipi_dsi_pixel_format_to_bpp(dsi->format); + if (bpp < 0) { + dev_err(dsi->dev, "failed to get bpp\n"); + return 0; + } + + lbcc = div_u64((u64)hcomponent * mode->clock * bpp, dsi->lanes * 8); + } frac = lbcc % mode->clock; lbcc = lbcc / mode->clock; if (frac) lbcc++; + minimum_lbcc = dw_mipi_dsi_get_minimum_lbcc(dsi); + + if (lbcc < minimum_lbcc) + lbcc = minimum_lbcc; + return lbcc; } @@ -1006,6 +1087,8 @@ static int dw_mipi_dsi_bridge_attach(struct drm_bridge *bridge, static const struct drm_bridge_funcs dw_mipi_dsi_bridge_funcs = { .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_get_input_bus_fmts = dw_mipi_dsi_bridge_atomic_get_input_bus_fmts, + .atomic_check = dw_mipi_dsi_bridge_atomic_check, .atomic_reset = drm_atomic_helper_bridge_reset, .atomic_pre_enable = dw_mipi_dsi_bridge_atomic_pre_enable, .atomic_enable = dw_mipi_dsi_bridge_atomic_enable, @@ -1209,6 +1292,12 @@ void dw_mipi_dsi_set_slave(struct dw_mipi_dsi *dsi, struct dw_mipi_dsi *slave) } EXPORT_SYMBOL_GPL(dw_mipi_dsi_set_slave); +struct drm_bridge *dw_mipi_dsi_get_bridge(struct dw_mipi_dsi *dsi) +{ + return &dsi->bridge; +} +EXPORT_SYMBOL_GPL(dw_mipi_dsi_get_bridge); + /* * Probe/remove API, used from platforms based on the DRM bridge API. */ diff --git a/drivers/gpu/drm/ci/arm.config b/drivers/gpu/drm/ci/arm.config index 871f4de063ad..411e814819a8 100644 --- a/drivers/gpu/drm/ci/arm.config +++ b/drivers/gpu/drm/ci/arm.config @@ -24,6 +24,7 @@ CONFIG_DRM_LIMA=y CONFIG_DRM_PANEL_SIMPLE=y CONFIG_PWM_CROS_EC=y CONFIG_BACKLIGHT_PWM=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y CONFIG_ROCKCHIP_CDN_DP=n diff --git a/drivers/gpu/drm/ci/arm64.config b/drivers/gpu/drm/ci/arm64.config index 817e18ddfd4f..b4f653417883 100644 --- a/drivers/gpu/drm/ci/arm64.config +++ b/drivers/gpu/drm/ci/arm64.config @@ -26,6 +26,7 @@ CONFIG_DRM_ETNAVIV=y CONFIG_DRM_I2C_ADV7511=y CONFIG_PWM_CROS_EC=y CONFIG_BACKLIGHT_PWM=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y CONFIG_ROCKCHIP_CDN_DP=n @@ -61,6 +62,7 @@ CONFIG_PHY_QCOM_QUSB2=y CONFIG_PHY_QCOM_QMP=y CONFIG_MSM_GCC_8996=y CONFIG_QCOM_CLK_APCC_MSM8996=y +CONFIG_MSM_MMCC_8996=y CONFIG_QCOM_LLCC=y CONFIG_QCOM_LMH=y CONFIG_QCOM_SPMI_TEMP_ALARM=y diff --git a/drivers/gpu/drm/ci/build.sh b/drivers/gpu/drm/ci/build.sh index 7b014287a041..e5c5dcedd108 100644 --- a/drivers/gpu/drm/ci/build.sh +++ b/drivers/gpu/drm/ci/build.sh @@ -35,7 +35,7 @@ elif [[ "$KERNEL_ARCH" = "arm" ]]; then apt-get install -y libssl-dev:armhf else GCC_ARCH="x86_64-linux-gnu" - DEBIAN_ARCH="x86_64" + DEBIAN_ARCH="amd64" DEVICE_TREES="" fi @@ -64,10 +64,15 @@ if [ "$(git ls-remote --exit-code --heads ${UPSTREAM_REPO} ${TARGET_BRANCH}-exte fi # Try to merge fixes from local repo if this isn't a merge request +# otherwise try merging the fixes from the merge target if [ -z "$CI_MERGE_REQUEST_PROJECT_PATH" ]; then if [ "$(git ls-remote --exit-code --heads origin ${TARGET_BRANCH}-external-fixes)" ]; then git pull origin ${TARGET_BRANCH}-external-fixes fi +else + if [ "$(git ls-remote --exit-code --heads ${CI_MERGE_REQUEST_PROJECT_URL} ${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}-external-fixes)" ]; then + git pull ${CI_MERGE_REQUEST_PROJECT_URL} ${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}-external-fixes + fi fi for opt in $ENABLE_KCONFIGS; do @@ -148,6 +153,7 @@ mkdir -p artifacts/install/lib mv install/* artifacts/install/. rm -rf artifacts/install/modules ln -s common artifacts/install/ci-common +cp .config artifacts/${CI_JOB_NAME}_config for image in ${KERNEL_IMAGE_NAME}; do cp /lava-files/$image artifacts/install/. diff --git a/drivers/gpu/drm/ci/build.yml b/drivers/gpu/drm/ci/build.yml index e6503f1c5927..17ab38304885 100644 --- a/drivers/gpu/drm/ci/build.yml +++ b/drivers/gpu/drm/ci/build.yml @@ -1,6 +1,7 @@ .build: extends: - .build-rules + - .container+build-rules stage: build artifacts: paths: diff --git a/drivers/gpu/drm/ci/gitlab-ci.yml b/drivers/gpu/drm/ci/gitlab-ci.yml index 2c4df53f5dfe..aeb9bab1b069 100644 --- a/drivers/gpu/drm/ci/gitlab-ci.yml +++ b/drivers/gpu/drm/ci/gitlab-ci.yml @@ -1,11 +1,11 @@ variables: DRM_CI_PROJECT_PATH: &drm-ci-project-path mesa/mesa - DRM_CI_COMMIT_SHA: &drm-ci-commit-sha 0dc961645c4f0241f8512cb0ec3ad59635842072 + DRM_CI_COMMIT_SHA: &drm-ci-commit-sha edfbf74df1d4d6ce54ffe24566108be0e1a98c3d UPSTREAM_REPO: git://anongit.freedesktop.org/drm/drm TARGET_BRANCH: drm-next - IGT_VERSION: 471bfababd070e1dac0ebb87470ac4f2ae85e663 + IGT_VERSION: d1db7333d9c5fbbb05e50b0804123950d9dc1c46 DEQP_RUNNER_GIT_URL: https://gitlab.freedesktop.org/anholt/deqp-runner.git DEQP_RUNNER_GIT_TAG: v0.15.0 @@ -24,7 +24,9 @@ variables: PIPELINE_ARTIFACTS_BASE: ${S3_HOST}/artifacts/${CI_PROJECT_PATH}/${CI_PIPELINE_ID} # per-job artifact storage on MinIO JOB_ARTIFACTS_BASE: ${PIPELINE_ARTIFACTS_BASE}/${CI_JOB_ID} - + # default kernel for rootfs before injecting the current kernel tree + KERNEL_IMAGE_BASE: https://${S3_HOST}/mesa-lava/gfx-ci/linux/v6.4.12-for-mesa-ci-f6b4ad45f48d + LAVA_TAGS: subset-1-gfx LAVA_JOB_PRIORITY: 30 default: @@ -53,20 +55,6 @@ default: export CI_JOB_JWT="$(<${CI_JOB_JWT_FILE})" && rm "${CI_JOB_JWT_FILE}" - # Retry when job fails. - retry: - max: 1 - # Ignore runner_unsupported, stale_schedule, archived_failure, or - # unmet_prerequisites - when: - - api_failure - - runner_system_failure - - script_failure - - job_execution_timeout - - scheduler_failure - - data_integrity_failure - - unknown_failure - include: - project: 'freedesktop/ci-templates' ref: 16bc29078de5e0a067ff84a1a199a3760d3b3811 @@ -86,6 +74,17 @@ include: - '/.gitlab-ci/container/gitlab-ci.yml' - '/.gitlab-ci/test/gitlab-ci.yml' - '/.gitlab-ci/lava/lava-gitlab-ci.yml' + - '/src/microsoft/ci/gitlab-ci-inc.yml' + - '/src/gallium/drivers/zink/ci/gitlab-ci-inc.yml' + - '/src/gallium/drivers/crocus/ci/gitlab-ci-inc.yml' + - '/src/gallium/drivers/softpipe/ci/gitlab-ci-inc.yml' + - '/src/gallium/drivers/llvmpipe/ci/gitlab-ci-inc.yml' + - '/src/gallium/drivers/virgl/ci/gitlab-ci-inc.yml' + - '/src/gallium/drivers/nouveau/ci/gitlab-ci-inc.yml' + - '/src/gallium/frontends/lavapipe/ci/gitlab-ci-inc.yml' + - '/src/intel/ci/gitlab-ci-inc.yml' + - '/src/freedreno/ci/gitlab-ci-inc.yml' + - '/src/amd/ci/gitlab-ci-inc.yml' - drivers/gpu/drm/ci/image-tags.yml - drivers/gpu/drm/ci/container.yml - drivers/gpu/drm/ci/static-checks.yml @@ -154,6 +153,11 @@ stages: # Run automatically once all dependency jobs have passed - when: on_success +# When to automatically run the CI for container jobs +.container+build-rules: + rules: + - !reference [.no_scheduled_pipelines-rules, rules] + - when: manual .ci-deqp-artifacts: artifacts: diff --git a/drivers/gpu/drm/ci/igt_runner.sh b/drivers/gpu/drm/ci/igt_runner.sh index 2bb759165063..2f815ee3a8a3 100755 --- a/drivers/gpu/drm/ci/igt_runner.sh +++ b/drivers/gpu/drm/ci/igt_runner.sh @@ -20,11 +20,16 @@ set +e cat /sys/kernel/debug/dri/*/state set -e -# Cannot use HWCI_KERNEL_MODULES as at that point we don't have the module in /lib -if [ "$IGT_FORCE_DRIVER" = "amdgpu" ]; then - mv /install/modules/lib/modules/* /lib/modules/. - modprobe amdgpu -fi +case "$DRIVER_NAME" in + rockchip|mediatek|meson) + export IGT_FORCE_DRIVER="panfrost" + ;; + amdgpu) + # Cannot use HWCI_KERNEL_MODULES as at that point we don't have the module in /lib + mv /install/modules/lib/modules/* /lib/modules/. + modprobe amdgpu + ;; +esac if [ -e "/install/xfails/$DRIVER_NAME-$GPU_VERSION-skips.txt" ]; then IGT_SKIPS="--skips /install/xfails/$DRIVER_NAME-$GPU_VERSION-skips.txt" @@ -48,6 +53,20 @@ fi curl -L --retry 4 -f --retry-all-errors --retry-delay 60 -s ${FDO_HTTP_CACHE_URI:-}$PIPELINE_ARTIFACTS_BASE/$ARCH/igt.tar.gz | tar --zstd -v -x -C / + +# If the job is parallel at the gitab job level, take the corresponding fraction +# of the caselist. +if [ -n "$CI_NODE_INDEX" ]; then + sed -ni $CI_NODE_INDEX~$CI_NODE_TOTAL"p" /install/testlist.txt +fi + +# core_getversion checks if the driver is loaded and probed correctly +# so run it in all shards +if ! grep -q "core_getversion" /install/testlist.txt; then + # Add the line to the file + echo "core_getversion" >> /install/testlist.txt +fi + set +e igt-runner \ run \ @@ -57,8 +76,6 @@ igt-runner \ $IGT_SKIPS \ $IGT_FLAKES \ $IGT_FAILS \ - --fraction-start $CI_NODE_INDEX \ - --fraction $CI_NODE_TOTAL \ --jobs 1 ret=$? set -e diff --git a/drivers/gpu/drm/ci/image-tags.yml b/drivers/gpu/drm/ci/image-tags.yml index f051b6c547c5..7ab4f2514da8 100644 --- a/drivers/gpu/drm/ci/image-tags.yml +++ b/drivers/gpu/drm/ci/image-tags.yml @@ -1,12 +1,12 @@ variables: - CONTAINER_TAG: "2023-08-10-mesa-uprev" + CONTAINER_TAG: "2023-10-11-mesa-uprev" DEBIAN_X86_64_BUILD_BASE_IMAGE: "debian/x86_64_build-base" DEBIAN_BASE_TAG: "${CONTAINER_TAG}" DEBIAN_X86_64_BUILD_IMAGE_PATH: "debian/x86_64_build" - DEBIAN_BUILD_TAG: "${CONTAINER_TAG}" + DEBIAN_BUILD_TAG: "2023-10-08-config" - KERNEL_ROOTFS_TAG: "${CONTAINER_TAG}" + KERNEL_ROOTFS_TAG: "2023-10-06-amd" DEBIAN_X86_64_TEST_BASE_IMAGE: "debian/x86_64_test-base" DEBIAN_X86_64_TEST_IMAGE_GL_PATH: "debian/x86_64_test-gl" diff --git a/drivers/gpu/drm/ci/lava-submit.sh b/drivers/gpu/drm/ci/lava-submit.sh index 0c4456b21b0f..3d39b0c916a8 100755 --- a/drivers/gpu/drm/ci/lava-submit.sh +++ b/drivers/gpu/drm/ci/lava-submit.sh @@ -22,7 +22,7 @@ cp "$SCRIPTS_DIR"/setup-test-env.sh results/job-rootfs-overlay/ # Prepare env vars for upload. section_start variables "Variables passed through:" -KERNEL_IMAGE_BASE_URL="https://${BASE_SYSTEM_HOST_PATH}" \ +KERNEL_IMAGE_BASE="https://${BASE_SYSTEM_HOST_PATH}" \ artifacts/ci-common/generate-env.sh | tee results/job-rootfs-overlay/set-job-env-vars.sh section_end variables @@ -37,8 +37,8 @@ PYTHONPATH=artifacts/ artifacts/lava/lava_job_submitter.py \ --dump-yaml \ --pipeline-info "$CI_JOB_NAME: $CI_PIPELINE_URL on $CI_COMMIT_REF_NAME ${CI_NODE_INDEX}/${CI_NODE_TOTAL}" \ --rootfs-url-prefix "https://${BASE_SYSTEM_HOST_PATH}" \ - --kernel-url-prefix "https://${PIPELINE_ARTIFACTS_BASE}/${ARCH}" \ - --build-url "${FDO_HTTP_CACHE_URI:-}https://${PIPELINE_ARTIFACTS_BASE}/${ARCH}/kernel-files.tar.zst" \ + --kernel-url-prefix "https://${PIPELINE_ARTIFACTS_BASE}/${DEBIAN_ARCH}" \ + --build-url "${FDO_HTTP_CACHE_URI:-}https://${PIPELINE_ARTIFACTS_BASE}/${DEBIAN_ARCH}/kernel-files.tar.zst" \ --job-rootfs-overlay-url "${FDO_HTTP_CACHE_URI:-}https://${JOB_ROOTFS_OVERLAY_PATH}" \ --job-timeout-min ${JOB_TIMEOUT:-80} \ --first-stage-init artifacts/ci-common/init-stage1.sh \ diff --git a/drivers/gpu/drm/ci/test.yml b/drivers/gpu/drm/ci/test.yml index 6473cddaa7a9..f285ed67eb3d 100644 --- a/drivers/gpu/drm/ci/test.yml +++ b/drivers/gpu/drm/ci/test.yml @@ -23,7 +23,7 @@ - .lava-test:arm32 variables: HWCI_TEST_SCRIPT: "/install/igt_runner.sh" - ARCH: "armhf" + DEBIAN_ARCH: "armhf" dependencies: - testing:arm32 needs: @@ -38,7 +38,7 @@ - .lava-test:arm64 variables: HWCI_TEST_SCRIPT: "/install/igt_runner.sh" - ARCH: "arm64" + DEBIAN_ARCH: "arm64" dependencies: - testing:arm64 needs: @@ -53,7 +53,7 @@ - .lava-test:x86_64 variables: HWCI_TEST_SCRIPT: "/install/igt_runner.sh" - ARCH: "x86_64" + DEBIAN_ARCH: "amd64" dependencies: - testing:x86_64 needs: @@ -86,7 +86,7 @@ msm:sc7180: extends: - .lava-igt:arm64 stage: msm - parallel: 2 + parallel: 4 variables: DRIVER_NAME: msm DEVICE_TYPE: sc7180-trogdor-lazor-limozeen @@ -155,7 +155,7 @@ rockchip:rk3399: extends: - .lava-igt:arm64 stage: rockchip - parallel: 3 + parallel: 2 variables: DRIVER_NAME: rockchip DEVICE_TYPE: rk3399-gru-kevin @@ -178,7 +178,8 @@ rockchip:rk3399: i915:apl: extends: - .i915 - parallel: 12 + parallel: 3 + timeout: "1h30m" variables: DEVICE_TYPE: asus-C523NA-A20057-coral GPU_VERSION: apl @@ -187,7 +188,8 @@ i915:apl: i915:glk: extends: - .i915 - parallel: 5 + parallel: 2 + timeout: "1h30m" variables: DEVICE_TYPE: hp-x360-12b-ca0010nr-n4020-octopus GPU_VERSION: glk @@ -196,7 +198,8 @@ i915:glk: i915:amly: extends: - .i915 - parallel: 8 + parallel: 2 + timeout: "1h30m" variables: DEVICE_TYPE: asus-C433TA-AJ0005-rammus GPU_VERSION: amly @@ -205,7 +208,7 @@ i915:amly: i915:kbl: extends: - .i915 - parallel: 5 + parallel: 3 variables: DEVICE_TYPE: hp-x360-14-G1-sona GPU_VERSION: kbl @@ -214,7 +217,8 @@ i915:kbl: i915:whl: extends: - .i915 - parallel: 8 + parallel: 2 + timeout: "1h30m" variables: DEVICE_TYPE: dell-latitude-5400-8665U-sarien GPU_VERSION: whl @@ -223,7 +227,8 @@ i915:whl: i915:cml: extends: - .i915 - parallel: 6 + parallel: 2 + timeout: "1h30m" variables: DEVICE_TYPE: asus-C436FA-Flip-hatch GPU_VERSION: cml @@ -232,7 +237,7 @@ i915:cml: i915:tgl: extends: - .i915 - parallel: 6 + parallel: 8 variables: DEVICE_TYPE: asus-cx9400-volteer GPU_VERSION: tgl @@ -251,6 +256,7 @@ i915:tgl: amdgpu:stoney: extends: - .amdgpu + parallel: 2 variables: DEVICE_TYPE: hp-11A-G6-EE-grunt GPU_VERSION: stoney @@ -269,6 +275,7 @@ amdgpu:stoney: mediatek:mt8173: extends: - .mediatek + parallel: 4 variables: DEVICE_TYPE: mt8173-elm-hana GPU_VERSION: mt8173 @@ -280,6 +287,7 @@ mediatek:mt8173: mediatek:mt8183: extends: - .mediatek + parallel: 3 variables: DEVICE_TYPE: mt8183-kukui-jacuzzi-juniper-sku16 GPU_VERSION: mt8183 @@ -289,6 +297,7 @@ mediatek:mt8183: .mediatek:mt8192: extends: - .mediatek + parallel: 3 variables: DEVICE_TYPE: mt8192-asurada-spherion-r0 GPU_VERSION: mt8192 @@ -307,6 +316,7 @@ mediatek:mt8183: meson:g12b: extends: - .meson + parallel: 3 variables: DEVICE_TYPE: meson-g12b-a311d-khadas-vim3 GPU_VERSION: g12b diff --git a/drivers/gpu/drm/ci/xfails/amdgpu-stoney-fails.txt b/drivers/gpu/drm/ci/xfails/amdgpu-stoney-fails.txt index bd9392536e7c..ea87dc46bc2b 100644 --- a/drivers/gpu/drm/ci/xfails/amdgpu-stoney-fails.txt +++ b/drivers/gpu/drm/ci/xfails/amdgpu-stoney-fails.txt @@ -1,8 +1,14 @@ kms_addfb_basic@bad-pitch-65536,Fail kms_addfb_basic@bo-too-small,Fail +kms_addfb_basic@too-high,Fail +kms_async_flips@async-flip-with-page-flip-events,Fail +kms_async_flips@crc,Fail kms_async_flips@invalid-async-flip,Fail -kms_atomic@plane-immutable-zpos,Fail +kms_atomic_transition@plane-all-modeset-transition-internal-panels,Fail +kms_atomic_transition@plane-all-transition,Fail +kms_atomic_transition@plane-all-transition-nonblocking,Fail kms_atomic_transition@plane-toggle-modeset-transition,Fail +kms_atomic_transition@plane-use-after-nonblocking-unbind,Fail kms_bw@linear-tiling-1-displays-2560x1440p,Fail kms_bw@linear-tiling-1-displays-3840x2160p,Fail kms_bw@linear-tiling-2-displays-3840x2160p,Fail @@ -11,9 +17,11 @@ kms_color@degamma,Fail kms_cursor_crc@cursor-size-change,Fail kms_cursor_crc@pipe-A-cursor-size-change,Fail kms_cursor_crc@pipe-B-cursor-size-change,Fail -kms_cursor_legacy@forked-move,Fail +kms_flip@flip-vs-modeset-vs-hang,Fail +kms_flip@flip-vs-panning-vs-hang,Fail kms_hdr@bpc-switch,Fail kms_hdr@bpc-switch-dpms,Fail +kms_plane@pixel-format,Fail kms_plane_multiple@atomic-pipe-A-tiling-none,Fail kms_rmfb@close-fd,Fail kms_rotation_crc@primary-rotation-180,Fail diff --git a/drivers/gpu/drm/ci/xfails/amdgpu-stoney-flakes.txt b/drivers/gpu/drm/ci/xfails/amdgpu-stoney-flakes.txt index f8defa0f9e67..6faf75e667d3 100644 --- a/drivers/gpu/drm/ci/xfails/amdgpu-stoney-flakes.txt +++ b/drivers/gpu/drm/ci/xfails/amdgpu-stoney-flakes.txt @@ -1,21 +1 @@ -kms_addfb_basic@too-high -kms_async_flips@alternate-sync-async-flip kms_async_flips@async-flip-with-page-flip-events -kms_async_flips@crc -kms_async_flips@test-cursor -kms_async_flips@test-time-stamp -kms_atomic_transition@plane-all-modeset-transition-internal-panels -kms_atomic_transition@plane-all-transition -kms_atomic_transition@plane-use-after-nonblocking-unbind -kms_bw@linear-tiling-1-displays-1920x1080p -kms_bw@linear-tiling-2-displays-1920x1080p -kms_bw@linear-tiling-2-displays-2560x1440p -kms_bw@linear-tiling-3-displays-2560x1440p -kms_bw@linear-tiling-3-displays-3840x2160p -kms_cursor_crc@pipe-A-cursor-alpha-opaque -kms_cursor_crc@pipe-B-cursor-alpha-opaque -kms_plane@pixel-format -kms_plane_multiple@atomic-pipe-B-tiling-none -kms_plane_scaling@downscale-with-rotation-factor-0-5 -kms_universal_plane@disable-primary-vs-flip-pipe-A -kms_universal_plane@disable-primary-vs-flip-pipe-B diff --git a/drivers/gpu/drm/ci/xfails/i915-amly-fails.txt b/drivers/gpu/drm/ci/xfails/i915-amly-fails.txt index 5f513c638beb..59438e4df86e 100644 --- a/drivers/gpu/drm/ci/xfails/i915-amly-fails.txt +++ b/drivers/gpu/drm/ci/xfails/i915-amly-fails.txt @@ -2,6 +2,10 @@ kms_flip_scaled_crc@flip-32bpp-linear-to-64bpp-linear-downscaling,Fail kms_flip_scaled_crc@flip-32bpp-linear-to-64bpp-linear-upscaling,Fail kms_flip_scaled_crc@flip-32bpp-xtile-to-64bpp-xtile-downscaling,Fail kms_flip_scaled_crc@flip-32bpp-xtile-to-64bpp-xtile-upscaling,Fail +kms_flip_scaled_crc@flip-32bpp-ytile-to-64bpp-ytile-downscaling,Fail +kms_flip_scaled_crc@flip-32bpp-ytile-to-64bpp-ytile-upscaling,Fail +kms_flip_scaled_crc@flip-32bpp-ytileccs-to-64bpp-ytile-downscaling,Fail +kms_flip_scaled_crc@flip-32bpp-ytileccs-to-64bpp-ytile-upscaling,Fail kms_flip_scaled_crc@flip-64bpp-linear-to-16bpp-linear-downscaling,Fail kms_flip_scaled_crc@flip-64bpp-linear-to-16bpp-linear-upscaling,Fail kms_flip_scaled_crc@flip-64bpp-linear-to-32bpp-linear-downscaling,Fail @@ -10,7 +14,12 @@ kms_flip_scaled_crc@flip-64bpp-xtile-to-16bpp-xtile-downscaling,Fail kms_flip_scaled_crc@flip-64bpp-xtile-to-16bpp-xtile-upscaling,Fail kms_flip_scaled_crc@flip-64bpp-xtile-to-32bpp-xtile-downscaling,Fail kms_flip_scaled_crc@flip-64bpp-xtile-to-32bpp-xtile-upscaling,Fail +kms_flip_scaled_crc@flip-64bpp-ytile-to-16bpp-ytile-downscaling,Fail +kms_flip_scaled_crc@flip-64bpp-ytile-to-16bpp-ytile-upscaling,Fail +kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-downscaling,Fail +kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-upscaling,Fail kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilegen12rcccs-upscaling,Fail +kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilercccs-downscaling,Fail kms_plane_alpha_blend@alpha-basic,Fail kms_plane_alpha_blend@alpha-opaque-fb,Fail kms_plane_alpha_blend@alpha-transparent-fb,Fail diff --git a/drivers/gpu/drm/ci/xfails/i915-amly-flakes.txt b/drivers/gpu/drm/ci/xfails/i915-amly-flakes.txt deleted file mode 100644 index d5000515a315..000000000000 --- a/drivers/gpu/drm/ci/xfails/i915-amly-flakes.txt +++ /dev/null @@ -1,32 +0,0 @@ -kms_bw@linear-tiling-2-displays-1920x1080p -kms_bw@linear-tiling-2-displays-2560x1440p -kms_bw@linear-tiling-2-displays-3840x2160p -kms_bw@linear-tiling-3-displays-1920x1080p -kms_bw@linear-tiling-3-displays-2560x1440p -kms_bw@linear-tiling-3-displays-3840x2160p -kms_bw@linear-tiling-4-displays-1920x1080p -kms_bw@linear-tiling-4-displays-2560x1440p -kms_bw@linear-tiling-4-displays-3840x2160p -kms_flip_scaled_crc@flip-32bpp-ytile-to-64bpp-ytile-downscaling -kms_flip_scaled_crc@flip-32bpp-ytile-to-64bpp-ytile-upscaling -kms_flip_scaled_crc@flip-32bpp-ytileccs-to-64bpp-ytile-downscaling -kms_flip_scaled_crc@flip-32bpp-ytileccs-to-64bpp-ytile-upscaling -kms_flip_scaled_crc@flip-64bpp-ytile-to-16bpp-ytile-downscaling -kms_flip_scaled_crc@flip-64bpp-ytile-to-16bpp-ytile-upscaling -kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-downscaling -kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-upscaling -kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilercccs-downscaling -kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilercccs-upscaling -kms_plane_alpha_blend@pipe-A-alpha-basic -kms_plane_alpha_blend@pipe-A-alpha-opaque-fb -kms_plane_alpha_blend@pipe-A-alpha-transparent-fb -kms_plane_alpha_blend@pipe-A-constant-alpha-max -kms_plane_alpha_blend@pipe-B-alpha-basic -kms_plane_alpha_blend@pipe-B-alpha-opaque-fb -kms_plane_alpha_blend@pipe-B-alpha-transparent-fb -kms_plane_alpha_blend@pipe-B-constant-alpha-max -kms_plane_alpha_blend@pipe-C-alpha-basic -kms_plane_alpha_blend@pipe-C-alpha-opaque-fb -kms_plane_alpha_blend@pipe-C-alpha-transparent-fb -kms_plane_alpha_blend@pipe-C-constant-alpha-max -kms_sysfs_edid_timing diff --git a/drivers/gpu/drm/ci/xfails/i915-apl-fails.txt b/drivers/gpu/drm/ci/xfails/i915-apl-fails.txt index 46397ce38d5a..2e3b7c5dac3c 100644 --- a/drivers/gpu/drm/ci/xfails/i915-apl-fails.txt +++ b/drivers/gpu/drm/ci/xfails/i915-apl-fails.txt @@ -8,13 +8,6 @@ kms_bw@linear-tiling-3-displays-3840x2160p,Fail kms_bw@linear-tiling-4-displays-1920x1080p,Fail kms_bw@linear-tiling-4-displays-2560x1440p,Fail kms_bw@linear-tiling-4-displays-3840x2160p,Fail -kms_color@ctm-0-25,Fail -kms_color@ctm-0-50,Fail -kms_color@ctm-0-75,Fail -kms_color@ctm-max,Fail -kms_color@ctm-negative,Fail -kms_color@ctm-red-to-blue,Fail -kms_color@ctm-signed,Fail kms_flip_scaled_crc@flip-32bpp-linear-to-64bpp-linear-downscaling,Fail kms_flip_scaled_crc@flip-32bpp-linear-to-64bpp-linear-upscaling,Fail kms_flip_scaled_crc@flip-32bpp-xtile-to-64bpp-xtile-downscaling,Fail @@ -38,8 +31,6 @@ kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-upscaling,Fail kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilegen12rcccs-upscaling,Fail kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilercccs-downscaling,Fail kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilercccs-upscaling,Fail -kms_hdmi_inject@inject-4k,Timeout -kms_plane@plane-position-hole,Timeout kms_plane_alpha_blend@alpha-basic,Fail kms_plane_alpha_blend@alpha-opaque-fb,Fail kms_plane_alpha_blend@alpha-transparent-fb,Fail @@ -53,6 +44,4 @@ kms_plane_alpha_blend@pipe-B-constant-alpha-max,Fail kms_plane_alpha_blend@pipe-C-alpha-opaque-fb,Fail kms_plane_alpha_blend@pipe-C-alpha-transparent-fb,Fail kms_plane_alpha_blend@pipe-C-constant-alpha-max,Fail -kms_plane_multiple@tiling-y,Timeout -kms_pwrite_crc,Timeout kms_sysfs_edid_timing,Fail diff --git a/drivers/gpu/drm/ci/xfails/i915-apl-flakes.txt b/drivers/gpu/drm/ci/xfails/i915-apl-flakes.txt deleted file mode 100644 index 331c5841bb41..000000000000 --- a/drivers/gpu/drm/ci/xfails/i915-apl-flakes.txt +++ /dev/null @@ -1 +0,0 @@ -kms_frontbuffer_tracking@fbc-tiling-linear diff --git a/drivers/gpu/drm/ci/xfails/i915-cml-fails.txt b/drivers/gpu/drm/ci/xfails/i915-cml-fails.txt index 6139b410e767..240ef8467c26 100644 --- a/drivers/gpu/drm/ci/xfails/i915-cml-fails.txt +++ b/drivers/gpu/drm/ci/xfails/i915-cml-fails.txt @@ -1,8 +1,11 @@ -kms_color@ctm-0-25,Fail kms_flip_scaled_crc@flip-32bpp-linear-to-64bpp-linear-downscaling,Fail kms_flip_scaled_crc@flip-32bpp-linear-to-64bpp-linear-upscaling,Fail kms_flip_scaled_crc@flip-32bpp-xtile-to-64bpp-xtile-downscaling,Fail kms_flip_scaled_crc@flip-32bpp-xtile-to-64bpp-xtile-upscaling,Fail +kms_flip_scaled_crc@flip-32bpp-ytile-to-64bpp-ytile-downscaling,Fail +kms_flip_scaled_crc@flip-32bpp-ytile-to-64bpp-ytile-upscaling,Fail +kms_flip_scaled_crc@flip-32bpp-ytileccs-to-64bpp-ytile-downscaling,Fail +kms_flip_scaled_crc@flip-32bpp-ytileccs-to-64bpp-ytile-upscaling,Fail kms_flip_scaled_crc@flip-64bpp-linear-to-16bpp-linear-downscaling,Fail kms_flip_scaled_crc@flip-64bpp-linear-to-16bpp-linear-upscaling,Fail kms_flip_scaled_crc@flip-64bpp-linear-to-32bpp-linear-downscaling,Fail @@ -11,8 +14,17 @@ kms_flip_scaled_crc@flip-64bpp-xtile-to-16bpp-xtile-downscaling,Fail kms_flip_scaled_crc@flip-64bpp-xtile-to-16bpp-xtile-upscaling,Fail kms_flip_scaled_crc@flip-64bpp-xtile-to-32bpp-xtile-downscaling,Fail kms_flip_scaled_crc@flip-64bpp-xtile-to-32bpp-xtile-upscaling,Fail +kms_flip_scaled_crc@flip-64bpp-ytile-to-16bpp-ytile-downscaling,Fail +kms_flip_scaled_crc@flip-64bpp-ytile-to-16bpp-ytile-upscaling,Fail +kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-downscaling,Fail +kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-upscaling,Fail kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilegen12rcccs-upscaling,Fail +kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilercccs-downscaling,Fail kms_plane_alpha_blend@alpha-basic,Fail kms_plane_alpha_blend@alpha-opaque-fb,Fail kms_plane_alpha_blend@alpha-transparent-fb,Fail kms_plane_alpha_blend@constant-alpha-max,Fail +kms_plane_alpha_blend@constant-alpha-min,Fail +kms_psr2_su@page_flip-NV12,Fail +kms_psr2_su@page_flip-P010,Fail +kms_setmode@basic,Fail diff --git a/drivers/gpu/drm/ci/xfails/i915-cml-flakes.txt b/drivers/gpu/drm/ci/xfails/i915-cml-flakes.txt deleted file mode 100644 index 0514a7b3fdb0..000000000000 --- a/drivers/gpu/drm/ci/xfails/i915-cml-flakes.txt +++ /dev/null @@ -1,38 +0,0 @@ -kms_bw@linear-tiling-2-displays-1920x1080p -kms_bw@linear-tiling-2-displays-2560x1440p -kms_bw@linear-tiling-2-displays-3840x2160p -kms_bw@linear-tiling-3-displays-1920x1080p -kms_bw@linear-tiling-3-displays-2560x1440p -kms_bw@linear-tiling-3-displays-3840x2160p -kms_bw@linear-tiling-4-displays-1920x1080p -kms_bw@linear-tiling-4-displays-2560x1440p -kms_bw@linear-tiling-4-displays-3840x2160p -kms_draw_crc@draw-method-xrgb8888-render-xtiled -kms_flip@flip-vs-suspend -kms_flip_scaled_crc@flip-32bpp-ytile-to-64bpp-ytile-downscaling -kms_flip_scaled_crc@flip-32bpp-ytile-to-64bpp-ytile-upscaling -kms_flip_scaled_crc@flip-32bpp-ytileccs-to-64bpp-ytile-downscaling -kms_flip_scaled_crc@flip-32bpp-ytileccs-to-64bpp-ytile-upscaling -kms_flip_scaled_crc@flip-64bpp-ytile-to-16bpp-ytile-downscaling -kms_flip_scaled_crc@flip-64bpp-ytile-to-16bpp-ytile-upscaling -kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-downscaling -kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-upscaling -kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilercccs-downscaling -kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilercccs-upscaling -kms_hdr@bpc-switch-suspend -kms_plane_alpha_blend@constant-alpha-min -kms_plane_alpha_blend@pipe-A-alpha-basic -kms_plane_alpha_blend@pipe-A-alpha-opaque-fb -kms_plane_alpha_blend@pipe-A-alpha-transparent-fb -kms_plane_alpha_blend@pipe-A-constant-alpha-max -kms_plane_alpha_blend@pipe-B-alpha-basic -kms_plane_alpha_blend@pipe-B-alpha-opaque-fb -kms_plane_alpha_blend@pipe-B-alpha-transparent-fb -kms_plane_alpha_blend@pipe-B-constant-alpha-max -kms_plane_alpha_blend@pipe-C-alpha-basic -kms_plane_alpha_blend@pipe-C-alpha-opaque-fb -kms_plane_alpha_blend@pipe-C-alpha-transparent-fb -kms_plane_alpha_blend@pipe-C-constant-alpha-max -kms_psr2_su@page_flip-NV12 -kms_psr2_su@page_flip-P010 -kms_setmode@basic diff --git a/drivers/gpu/drm/ci/xfails/i915-glk-fails.txt b/drivers/gpu/drm/ci/xfails/i915-glk-fails.txt index 5bd432e78129..4596055d7e5e 100644 --- a/drivers/gpu/drm/ci/xfails/i915-glk-fails.txt +++ b/drivers/gpu/drm/ci/xfails/i915-glk-fails.txt @@ -1,8 +1,15 @@ kms_fbcon_fbt@fbc,Fail +kms_flip@blocking-wf_vblank,Fail +kms_flip@wf_vblank-ts-check,Fail +kms_flip@wf_vblank-ts-check-interruptible,Fail kms_flip_scaled_crc@flip-32bpp-linear-to-64bpp-linear-downscaling,Fail kms_flip_scaled_crc@flip-32bpp-linear-to-64bpp-linear-upscaling,Fail kms_flip_scaled_crc@flip-32bpp-xtile-to-64bpp-xtile-downscaling,Fail kms_flip_scaled_crc@flip-32bpp-xtile-to-64bpp-xtile-upscaling,Fail +kms_flip_scaled_crc@flip-32bpp-ytile-to-64bpp-ytile-downscaling,Fail +kms_flip_scaled_crc@flip-32bpp-ytile-to-64bpp-ytile-upscaling,Fail +kms_flip_scaled_crc@flip-32bpp-ytileccs-to-64bpp-ytile-downscaling,Fail +kms_flip_scaled_crc@flip-32bpp-ytileccs-to-64bpp-ytile-upscaling,Fail kms_flip_scaled_crc@flip-64bpp-linear-to-16bpp-linear-downscaling,Fail kms_flip_scaled_crc@flip-64bpp-linear-to-16bpp-linear-upscaling,Fail kms_flip_scaled_crc@flip-64bpp-linear-to-32bpp-linear-downscaling,Fail @@ -11,9 +18,19 @@ kms_flip_scaled_crc@flip-64bpp-xtile-to-16bpp-xtile-downscaling,Fail kms_flip_scaled_crc@flip-64bpp-xtile-to-16bpp-xtile-upscaling,Fail kms_flip_scaled_crc@flip-64bpp-xtile-to-32bpp-xtile-downscaling,Fail kms_flip_scaled_crc@flip-64bpp-xtile-to-32bpp-xtile-upscaling,Fail +kms_flip_scaled_crc@flip-64bpp-ytile-to-16bpp-ytile-downscaling,Fail +kms_flip_scaled_crc@flip-64bpp-ytile-to-16bpp-ytile-upscaling,Fail +kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-downscaling,Fail +kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-upscaling,Fail kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilegen12rcccs-upscaling,Fail +kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilercccs-downscaling,Fail +kms_frontbuffer_tracking@fbc-tiling-linear,Fail kms_frontbuffer_tracking@fbcdrrs-tiling-linear,Fail kms_plane_alpha_blend@alpha-basic,Fail kms_plane_alpha_blend@alpha-opaque-fb,Fail kms_plane_alpha_blend@alpha-transparent-fb,Fail kms_plane_alpha_blend@constant-alpha-max,Fail +kms_rotation_crc@multiplane-rotation,Fail +kms_rotation_crc@multiplane-rotation-cropping-bottom,Fail +kms_rotation_crc@multiplane-rotation-cropping-top,Fail +kms_setmode@basic,Fail diff --git a/drivers/gpu/drm/ci/xfails/i915-glk-flakes.txt b/drivers/gpu/drm/ci/xfails/i915-glk-flakes.txt deleted file mode 100644 index fc41d13a2d56..000000000000 --- a/drivers/gpu/drm/ci/xfails/i915-glk-flakes.txt +++ /dev/null @@ -1,41 +0,0 @@ -kms_bw@linear-tiling-1-displays-3840x2160p -kms_bw@linear-tiling-2-displays-1920x1080p -kms_bw@linear-tiling-2-displays-2560x1440p -kms_bw@linear-tiling-2-displays-3840x2160p -kms_bw@linear-tiling-3-displays-1920x1080p -kms_bw@linear-tiling-3-displays-2560x1440p -kms_bw@linear-tiling-3-displays-3840x2160p -kms_bw@linear-tiling-4-displays-1920x1080p -kms_bw@linear-tiling-4-displays-2560x1440p -kms_bw@linear-tiling-4-displays-3840x2160p -kms_flip@blocking-wf_vblank -kms_flip@wf_vblank-ts-check -kms_flip@wf_vblank-ts-check-interruptible -kms_flip_scaled_crc@flip-32bpp-ytile-to-64bpp-ytile-downscaling -kms_flip_scaled_crc@flip-32bpp-ytile-to-64bpp-ytile-upscaling -kms_flip_scaled_crc@flip-32bpp-ytileccs-to-64bpp-ytile-downscaling -kms_flip_scaled_crc@flip-32bpp-ytileccs-to-64bpp-ytile-upscaling -kms_flip_scaled_crc@flip-64bpp-ytile-to-16bpp-ytile-downscaling -kms_flip_scaled_crc@flip-64bpp-ytile-to-16bpp-ytile-upscaling -kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-downscaling -kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-upscaling -kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilercccs-downscaling -kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilercccs-upscaling -kms_frontbuffer_tracking@fbc-tiling-linear -kms_plane_alpha_blend@pipe-A-alpha-basic -kms_plane_alpha_blend@pipe-A-alpha-opaque-fb -kms_plane_alpha_blend@pipe-A-alpha-transparent-fb -kms_plane_alpha_blend@pipe-A-constant-alpha-max -kms_plane_alpha_blend@pipe-B-alpha-basic -kms_plane_alpha_blend@pipe-B-alpha-opaque-fb -kms_plane_alpha_blend@pipe-B-alpha-transparent-fb -kms_plane_alpha_blend@pipe-B-constant-alpha-max -kms_plane_alpha_blend@pipe-C-alpha-basic -kms_plane_alpha_blend@pipe-C-alpha-opaque-fb -kms_plane_alpha_blend@pipe-C-alpha-transparent-fb -kms_plane_alpha_blend@pipe-C-constant-alpha-max -kms_prop_blob@invalid-set-prop-any -kms_rotation_crc@multiplane-rotation -kms_rotation_crc@multiplane-rotation-cropping-bottom -kms_rotation_crc@multiplane-rotation-cropping-top -kms_setmode@basic diff --git a/drivers/gpu/drm/ci/xfails/i915-kbl-fails.txt b/drivers/gpu/drm/ci/xfails/i915-kbl-fails.txt index 56ec021a7679..dab202716909 100644 --- a/drivers/gpu/drm/ci/xfails/i915-kbl-fails.txt +++ b/drivers/gpu/drm/ci/xfails/i915-kbl-fails.txt @@ -4,7 +4,10 @@ kms_flip_scaled_crc@flip-32bpp-linear-to-64bpp-linear-downscaling,Fail kms_flip_scaled_crc@flip-32bpp-linear-to-64bpp-linear-upscaling,Fail kms_flip_scaled_crc@flip-32bpp-xtile-to-64bpp-xtile-downscaling,Fail kms_flip_scaled_crc@flip-32bpp-xtile-to-64bpp-xtile-upscaling,Fail +kms_flip_scaled_crc@flip-32bpp-ytile-to-64bpp-ytile-downscaling,Fail kms_flip_scaled_crc@flip-32bpp-ytile-to-64bpp-ytile-upscaling,Fail +kms_flip_scaled_crc@flip-32bpp-ytileccs-to-64bpp-ytile-downscaling,Fail +kms_flip_scaled_crc@flip-32bpp-ytileccs-to-64bpp-ytile-upscaling,Fail kms_flip_scaled_crc@flip-64bpp-linear-to-16bpp-linear-downscaling,Fail kms_flip_scaled_crc@flip-64bpp-linear-to-16bpp-linear-upscaling,Fail kms_flip_scaled_crc@flip-64bpp-linear-to-32bpp-linear-downscaling,Fail @@ -13,8 +16,12 @@ kms_flip_scaled_crc@flip-64bpp-xtile-to-16bpp-xtile-downscaling,Fail kms_flip_scaled_crc@flip-64bpp-xtile-to-16bpp-xtile-upscaling,Fail kms_flip_scaled_crc@flip-64bpp-xtile-to-32bpp-xtile-downscaling,Fail kms_flip_scaled_crc@flip-64bpp-xtile-to-32bpp-xtile-upscaling,Fail +kms_flip_scaled_crc@flip-64bpp-ytile-to-16bpp-ytile-downscaling,Fail +kms_flip_scaled_crc@flip-64bpp-ytile-to-16bpp-ytile-upscaling,Fail kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-downscaling,Fail +kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-upscaling,Fail kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilegen12rcccs-upscaling,Fail +kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilercccs-downscaling,Fail kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilercccs-upscaling,Fail kms_plane_alpha_blend@alpha-basic,Fail kms_plane_alpha_blend@alpha-opaque-fb,Fail diff --git a/drivers/gpu/drm/ci/xfails/i915-kbl-flakes.txt b/drivers/gpu/drm/ci/xfails/i915-kbl-flakes.txt index f3ba1c4c5d46..a12f888530dd 100644 --- a/drivers/gpu/drm/ci/xfails/i915-kbl-flakes.txt +++ b/drivers/gpu/drm/ci/xfails/i915-kbl-flakes.txt @@ -1,26 +1 @@ kms_async_flips@crc -kms_bw@linear-tiling-2-displays-1920x1080p -kms_bw@linear-tiling-2-displays-3840x2160p -kms_bw@linear-tiling-3-displays-1920x1080p -kms_bw@linear-tiling-3-displays-2560x1440p -kms_bw@linear-tiling-3-displays-3840x2160p -kms_bw@linear-tiling-4-displays-1920x1080p -kms_bw@linear-tiling-4-displays-3840x2160p -kms_color@ctm-0-25 -kms_flip_scaled_crc@flip-32bpp-ytile-to-64bpp-ytile-downscaling -kms_flip_scaled_crc@flip-32bpp-ytileccs-to-64bpp-ytile-downscaling -kms_flip_scaled_crc@flip-32bpp-ytileccs-to-64bpp-ytile-upscaling -kms_flip_scaled_crc@flip-64bpp-ytile-to-16bpp-ytile-downscaling -kms_flip_scaled_crc@flip-64bpp-ytile-to-16bpp-ytile-upscaling -kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-upscaling -kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilercccs-downscaling -kms_plane_alpha_blend@pipe-A-alpha-basic -kms_plane_alpha_blend@pipe-A-alpha-opaque-fb -kms_plane_alpha_blend@pipe-A-alpha-transparent-fb -kms_plane_alpha_blend@pipe-B-alpha-basic -kms_plane_alpha_blend@pipe-B-alpha-transparent-fb -kms_plane_alpha_blend@pipe-B-constant-alpha-max -kms_plane_alpha_blend@pipe-C-alpha-basic -kms_plane_alpha_blend@pipe-C-alpha-opaque-fb -kms_plane_alpha_blend@pipe-C-alpha-transparent-fb -kms_sysfs_edid_timing diff --git a/drivers/gpu/drm/ci/xfails/i915-tgl-fails.txt b/drivers/gpu/drm/ci/xfails/i915-tgl-fails.txt index a6da5544e198..27bfca1c6f2c 100644 --- a/drivers/gpu/drm/ci/xfails/i915-tgl-fails.txt +++ b/drivers/gpu/drm/ci/xfails/i915-tgl-fails.txt @@ -8,7 +8,6 @@ kms_bw@linear-tiling-4-displays-3840x2160p,Fail kms_bw@linear-tiling-5-displays-1920x1080p,Fail kms_bw@linear-tiling-5-displays-2560x1440p,Fail kms_bw@linear-tiling-5-displays-3840x2160p,Fail -kms_color@ctm-0-25,Fail kms_flip@flip-vs-panning-vs-hang,Timeout kms_flip_scaled_crc@flip-32bpp-linear-to-64bpp-linear-downscaling,Fail kms_flip_scaled_crc@flip-32bpp-linear-to-64bpp-linear-upscaling,Fail diff --git a/drivers/gpu/drm/ci/xfails/i915-tgl-flakes.txt b/drivers/gpu/drm/ci/xfails/i915-tgl-flakes.txt deleted file mode 100644 index 1cd910ee06df..000000000000 --- a/drivers/gpu/drm/ci/xfails/i915-tgl-flakes.txt +++ /dev/null @@ -1,5 +0,0 @@ -kms_draw_crc@.* -kms_flip@blocking-absolute-wf_vblank -kms_flip@bo-too-big-interruptible -kms_flip@busy-flip -kms_flip@flip-vs-rmfb-interruptible diff --git a/drivers/gpu/drm/ci/xfails/i915-whl-flakes.txt b/drivers/gpu/drm/ci/xfails/i915-whl-flakes.txt deleted file mode 100644 index c33202e7e2a1..000000000000 --- a/drivers/gpu/drm/ci/xfails/i915-whl-flakes.txt +++ /dev/null @@ -1 +0,0 @@ -kms_flip@flip-vs-suspend diff --git a/drivers/gpu/drm/ci/xfails/mediatek-mt8173-flakes.txt b/drivers/gpu/drm/ci/xfails/mediatek-mt8173-flakes.txt deleted file mode 100644 index e69de29bb2d1..000000000000 --- a/drivers/gpu/drm/ci/xfails/mediatek-mt8173-flakes.txt +++ /dev/null diff --git a/drivers/gpu/drm/ci/xfails/mediatek-mt8183-fails.txt b/drivers/gpu/drm/ci/xfails/mediatek-mt8183-fails.txt index 6ff81d00e84e..67d690fc4037 100644 --- a/drivers/gpu/drm/ci/xfails/mediatek-mt8183-fails.txt +++ b/drivers/gpu/drm/ci/xfails/mediatek-mt8183-fails.txt @@ -6,5 +6,8 @@ kms_bw@linear-tiling-2-displays-3840x2160p,Fail kms_bw@linear-tiling-3-displays-2560x1440p,Fail kms_bw@linear-tiling-3-displays-3840x2160p,Fail kms_color@pipe-A-invalid-gamma-lut-sizes,Fail +kms_plane_cursor@overlay,Fail +kms_plane_cursor@primary,Fail +kms_plane_cursor@viewport,Fail kms_plane_scaling@upscale-with-rotation-20x20,Fail -kms_rmfb@close-fd,Fail
\ No newline at end of file +kms_rmfb@close-fd,Fail diff --git a/drivers/gpu/drm/ci/xfails/mediatek-mt8183-flakes.txt b/drivers/gpu/drm/ci/xfails/mediatek-mt8183-flakes.txt deleted file mode 100644 index 208890b79eb0..000000000000 --- a/drivers/gpu/drm/ci/xfails/mediatek-mt8183-flakes.txt +++ /dev/null @@ -1,14 +0,0 @@ -core_setmaster_vs_auth -kms_bw@linear-tiling-1-displays-1920x1080p -kms_bw@linear-tiling-1-displays-3840x2160p -kms_bw@linear-tiling-3-displays-1920x1080p -kms_cursor_legacy@cursor-vs-flip-atomic -kms_plane_scaling@invalid-num-scalers -kms_plane_scaling@planes-upscale-20x20 -kms_plane_scaling@planes-upscale-20x20-downscale-factor-0-5 -kms_plane_scaling@upscale-with-modifier-20x20 -kms_plane_scaling@upscale-with-pixel-format-20x20 -kms_prop_blob@invalid-set-prop-any -kms_properties@get_properties-sanity-atomic -kms_properties@plane-properties-atomic -kms_properties@plane-properties-legacy
\ No newline at end of file diff --git a/drivers/gpu/drm/ci/xfails/meson-g12b-fails.txt b/drivers/gpu/drm/ci/xfails/meson-g12b-fails.txt index 860e702091e2..56a2ae7047b4 100644 --- a/drivers/gpu/drm/ci/xfails/meson-g12b-fails.txt +++ b/drivers/gpu/drm/ci/xfails/meson-g12b-fails.txt @@ -1,12 +1,16 @@ kms_3d,Fail -kms_properties@connector-properties-atomic,Fail -kms_properties@get_properties-sanity-atomic,Fail -kms_properties@get_properties-sanity-non-atomic,Fail -kms_properties@connector-properties-legacy,Fail kms_cursor_legacy@forked-bo,Fail kms_cursor_legacy@forked-move,Fail kms_cursor_legacy@single-bo,Fail kms_cursor_legacy@single-move,Fail kms_cursor_legacy@torture-bo,Fail kms_cursor_legacy@torture-move,Fail -kms_hdmi_inject@inject-4k,Fail
\ No newline at end of file +kms_force_connector_basic@force-edid,Fail +kms_hdmi_inject@inject-4k,Fail +kms_plane_cursor@overlay,Fail +kms_plane_cursor@primary,Fail +kms_plane_cursor@viewport,Fail +kms_properties@connector-properties-atomic,Fail +kms_properties@connector-properties-legacy,Fail +kms_properties@get_properties-sanity-atomic,Fail +kms_properties@get_properties-sanity-non-atomic,Fail diff --git a/drivers/gpu/drm/ci/xfails/meson-g12b-flakes.txt b/drivers/gpu/drm/ci/xfails/meson-g12b-flakes.txt deleted file mode 100644 index b63329d06767..000000000000 --- a/drivers/gpu/drm/ci/xfails/meson-g12b-flakes.txt +++ /dev/null @@ -1,4 +0,0 @@ -kms_force_connector_basic@force-connector-state -kms_force_connector_basic@force-edid -kms_force_connector_basic@force-load-detect -kms_force_connector_basic@prune-stale-modes
\ No newline at end of file diff --git a/drivers/gpu/drm/ci/xfails/msm-apq8016-flakes.txt b/drivers/gpu/drm/ci/xfails/msm-apq8016-flakes.txt deleted file mode 100644 index 0e3b60d3fade..000000000000 --- a/drivers/gpu/drm/ci/xfails/msm-apq8016-flakes.txt +++ /dev/null @@ -1,4 +0,0 @@ -kms_force_connector_basic@force-connector-state -kms_force_connector_basic@force-edid -kms_force_connector_basic@force-load-detect -kms_force_connector_basic@prune-stale-modes diff --git a/drivers/gpu/drm/ci/xfails/msm-apq8096-fails.txt b/drivers/gpu/drm/ci/xfails/msm-apq8096-fails.txt index 88a1fc0a3b0d..2cd49e8ee47f 100644 --- a/drivers/gpu/drm/ci/xfails/msm-apq8096-fails.txt +++ b/drivers/gpu/drm/ci/xfails/msm-apq8096-fails.txt @@ -1,2 +1,4 @@ kms_3d,Fail kms_addfb_basic@addfb25-bad-modifier,Fail +kms_force_connector_basic@force-edid,Fail +kms_hdmi_inject@inject-4k,Fail diff --git a/drivers/gpu/drm/ci/xfails/msm-apq8096-flakes.txt b/drivers/gpu/drm/ci/xfails/msm-apq8096-flakes.txt deleted file mode 100644 index 0e3b60d3fade..000000000000 --- a/drivers/gpu/drm/ci/xfails/msm-apq8096-flakes.txt +++ /dev/null @@ -1,4 +0,0 @@ -kms_force_connector_basic@force-connector-state -kms_force_connector_basic@force-edid -kms_force_connector_basic@force-load-detect -kms_force_connector_basic@prune-stale-modes diff --git a/drivers/gpu/drm/ci/xfails/msm-sc7180-fails.txt b/drivers/gpu/drm/ci/xfails/msm-sc7180-fails.txt index 14adeba3b62d..f71166a57731 100644 --- a/drivers/gpu/drm/ci/xfails/msm-sc7180-fails.txt +++ b/drivers/gpu/drm/ci/xfails/msm-sc7180-fails.txt @@ -1,12 +1,17 @@ +kms_color@ctm-0-25,Fail +kms_color@ctm-0-50,Fail +kms_color@ctm-0-75,Fail +kms_color@ctm-blue-to-red,Fail +kms_color@ctm-green-to-red,Fail +kms_color@ctm-negative,Fail +kms_color@ctm-red-to-blue,Fail +kms_color@ctm-signed,Fail kms_cursor_legacy@cursor-vs-flip-toggle,Fail kms_cursor_legacy@cursor-vs-flip-varying-size,Fail kms_cursor_legacy@cursorA-vs-flipA-atomic-transitions,Crash +kms_flip@flip-vs-modeset-vs-hang,Fail +kms_flip@flip-vs-panning-vs-hang,Fail kms_pipe_crc_basic@compare-crc-sanitycheck-nv12,Fail -kms_plane@pixel-format,Fail -kms_plane@pixel-format-source-clamping,Fail -kms_plane@plane-position-covered,Fail -kms_plane@plane-position-hole,Fail -kms_plane@plane-position-hole-dpms,Fail kms_plane_alpha_blend@alpha-7efc,Fail kms_plane_alpha_blend@coverage-7efc,Fail kms_plane_alpha_blend@coverage-vs-premult-vs-constant,Fail diff --git a/drivers/gpu/drm/ci/xfails/msm-sc7180-flakes.txt b/drivers/gpu/drm/ci/xfails/msm-sc7180-flakes.txt index 636563d3e59a..04730044ed12 100644 --- a/drivers/gpu/drm/ci/xfails/msm-sc7180-flakes.txt +++ b/drivers/gpu/drm/ci/xfails/msm-sc7180-flakes.txt @@ -1,7 +1,17 @@ - -# Test ends up reading CRC from frame before cursor update -# bug -# sometimes.. tbd if this is a kernel CRC bug or a test -kms_cursor_crc@.* -kms_plane_multiple@atomic-pipe-A-tiling-none -kms_atomic_transition@modeset-transition-nonblocking-fencing,Fail
\ No newline at end of file +kms_color@ctm-0-25 +kms_color@ctm-0-50 +kms_color@ctm-0-75 +kms_color@ctm-blue-to-red +kms_color@ctm-green-to-red +kms_color@ctm-negative +kms_color@ctm-red-to-blue +kms_color@ctm-signed +kms_flip@flip-vs-modeset-vs-hang +kms_flip@flip-vs-panning-vs-hang +kms_plane@pixel-format +kms_plane@pixel-format-source-clamping +kms_plane@plane-position-covered +kms_plane@plane-position-hole +kms_plane@plane-position-hole-dpms +kms_writeback@writeback-fb-id +kms_writeback@writeback-invalid-parameters diff --git a/drivers/gpu/drm/ci/xfails/msm-sc7180-skips.txt b/drivers/gpu/drm/ci/xfails/msm-sc7180-skips.txt index 410e0eeb3161..e59a2fddfde0 100644 --- a/drivers/gpu/drm/ci/xfails/msm-sc7180-skips.txt +++ b/drivers/gpu/drm/ci/xfails/msm-sc7180-skips.txt @@ -4,20 +4,4 @@ # Test incorrectly assumes that CTM support implies gamma/degamma # LUT support. None of the subtests handle the case of only having # CTM support -kms_color.* - -# 4k@60 is not supported on this hw, but driver doesn't handle it -# too gracefully.. https://gitlab.freedesktop.org/drm/msm/-/issues/15 -kms_bw@linear-tiling-.*-displays-3840x2160p - -# Until igt fix lands: https://patchwork.freedesktop.org/patch/493175/ -kms_bw@linear-tiling-2.* -kms_bw@linear-tiling-3.* -kms_bw@linear-tiling-4.* -kms_bw@linear-tiling-5.* -kms_bw@linear-tiling-6.* - -# igt fix posted: https://patchwork.freedesktop.org/patch/499926/ -# failure mode is flakey due to randomization but fails frequently -# enough to be detected as a Crash or occasionally UnexpectedPass. -kms_plane_multiple@atomic-pipe-A-tiling-none +#kms_color.* diff --git a/drivers/gpu/drm/ci/xfails/msm-sdm845-fails.txt b/drivers/gpu/drm/ci/xfails/msm-sdm845-fails.txt index 09c0c623cd75..c55baa2d18c1 100644 --- a/drivers/gpu/drm/ci/xfails/msm-sdm845-fails.txt +++ b/drivers/gpu/drm/ci/xfails/msm-sdm845-fails.txt @@ -15,19 +15,16 @@ kms_color@pipe-A-ctm-max,Fail kms_color@pipe-A-ctm-negative,Fail kms_color@pipe-A-ctm-red-to-blue,Fail kms_color@pipe-A-legacy-gamma,Fail -kms_cursor_legacy@basic-flip-after-cursor-atomic,Fail kms_cursor_legacy@basic-flip-after-cursor-legacy,Fail kms_cursor_legacy@basic-flip-after-cursor-varying-size,Fail kms_cursor_legacy@basic-flip-before-cursor-atomic,Fail kms_cursor_legacy@basic-flip-before-cursor-legacy,Fail -kms_cursor_legacy@basic-flip-before-cursor-varying-size,Fail kms_cursor_legacy@cursor-vs-flip-atomic,Fail kms_cursor_legacy@cursor-vs-flip-atomic-transitions,Fail kms_cursor_legacy@cursor-vs-flip-atomic-transitions-varying-size,Fail kms_cursor_legacy@cursor-vs-flip-legacy,Fail kms_cursor_legacy@cursor-vs-flip-toggle,Fail kms_cursor_legacy@cursor-vs-flip-varying-size,Fail -kms_cursor_legacy@cursorA-vs-flipA-toggle,Fail kms_cursor_legacy@flip-vs-cursor-atomic,Fail kms_cursor_legacy@flip-vs-cursor-crc-atomic,Fail kms_cursor_legacy@flip-vs-cursor-crc-legacy,Fail @@ -35,11 +32,9 @@ kms_cursor_legacy@flip-vs-cursor-legacy,Fail kms_cursor_legacy@short-flip-after-cursor-atomic-transitions,Fail kms_cursor_legacy@short-flip-after-cursor-atomic-transitions-varying-size,Fail kms_cursor_legacy@short-flip-after-cursor-toggle,Fail -kms_cursor_legacy@short-flip-before-cursor-atomic-transitions,Fail -kms_cursor_legacy@short-flip-before-cursor-atomic-transitions-varying-size,Fail +kms_flip@flip-vs-modeset-vs-hang,Fail +kms_flip@flip-vs-panning-vs-hang,Fail kms_pipe_crc_basic@compare-crc-sanitycheck-nv12,Fail -kms_plane@pixel-format,Fail -kms_plane@pixel-format-source-clamping,Fail kms_plane_alpha_blend@alpha-7efc,Fail kms_plane_alpha_blend@coverage-7efc,Fail kms_plane_alpha_blend@coverage-vs-premult-vs-constant,Fail diff --git a/drivers/gpu/drm/ci/xfails/msm-sdm845-flakes.txt b/drivers/gpu/drm/ci/xfails/msm-sdm845-flakes.txt index 5b3aaab7ac3f..16d205c04cbb 100644 --- a/drivers/gpu/drm/ci/xfails/msm-sdm845-flakes.txt +++ b/drivers/gpu/drm/ci/xfails/msm-sdm845-flakes.txt @@ -1,11 +1,12 @@ - - -# Test ends up reading CRC from frame before cursor update -# bug -# sometimes.. tbd if this is a kernel CRC bug or a test -kms_cursor_crc@.* +kms_cursor_legacy@basic-flip-after-cursor-atomic +kms_cursor_legacy@basic-flip-before-cursor-varying-size +kms_cursor_legacy@cursorA-vs-flipA-toggle +kms_cursor_legacy@flip-vs-cursor-atomic-transitions kms_cursor_legacy@flip-vs-cursor-toggle -kms_cursor_legacy@pipe-A-forked-bo -kms_cursor_legacy@pipe-A-forked-move +kms_cursor_legacy@flip-vs-cursor-varying-size +kms_cursor_legacy@short-flip-before-cursor-atomic-transitions kms_cursor_legacy@short-flip-before-cursor-toggle -kms_flip@dpms-vs-vblank-race-interruptible +kms_flip@flip-vs-modeset-vs-hang +kms_flip@flip-vs-panning-vs-hang +kms_plane@pixel-format +kms_plane@pixel-format-source-clamping diff --git a/drivers/gpu/drm/ci/xfails/requirements.txt b/drivers/gpu/drm/ci/xfails/requirements.txt new file mode 100644 index 000000000000..d8856d1581fd --- /dev/null +++ b/drivers/gpu/drm/ci/xfails/requirements.txt @@ -0,0 +1,17 @@ +git+https://gitlab.freedesktop.org/gfx-ci/ci-collate@09e7142715c16f54344ddf97013331ba063b162b +termcolor==2.3.0 + +# ci-collate dependencies +certifi==2023.7.22 +charset-normalizer==3.2.0 +idna==3.4 +pip==23.2.1 +python-gitlab==3.15.0 +requests==2.31.0 +requests-toolbelt==1.0.0 +ruamel.yaml==0.17.32 +ruamel.yaml.clib==0.2.7 +setuptools==68.0.0 +tenacity==8.2.3 +urllib3==2.0.4 +wheel==0.41.1
\ No newline at end of file diff --git a/drivers/gpu/drm/ci/xfails/rockchip-rk3288-fails.txt b/drivers/gpu/drm/ci/xfails/rockchip-rk3288-fails.txt index 2a1baa948e12..90c63f519e9e 100644 --- a/drivers/gpu/drm/ci/xfails/rockchip-rk3288-fails.txt +++ b/drivers/gpu/drm/ci/xfails/rockchip-rk3288-fails.txt @@ -5,8 +5,13 @@ kms_bw@linear-tiling-2-displays-3840x2160p,Fail kms_bw@linear-tiling-3-displays-1920x1080p,Fail kms_bw@linear-tiling-3-displays-2560x1440p,Fail kms_bw@linear-tiling-3-displays-3840x2160p,Fail +kms_flip@flip-vs-modeset-vs-hang,Crash +kms_flip@flip-vs-panning-vs-hang,Crash kms_force_connector_basic@force-load-detect,Fail kms_invalid_mode@int-max-clock,Crash +kms_pipe_crc_basic@compare-crc-sanitycheck-nv12,Crash +kms_pipe_crc_basic@nonblocking-crc-frame-sequence,Crash +kms_pipe_crc_basic@read-crc-frame-sequence,Crash kms_plane@pixel-format,Crash kms_plane@pixel-format-source-clamping,Crash kms_plane@plane-position-hole,Crash @@ -45,4 +50,5 @@ kms_properties@connector-properties-atomic,Crash kms_properties@connector-properties-legacy,Crash kms_properties@get_properties-sanity-atomic,Crash kms_properties@get_properties-sanity-non-atomic,Crash +kms_rmfb@close-fd,Crash kms_setmode@invalid-clone-single-crtc,Crash diff --git a/drivers/gpu/drm/ci/xfails/rockchip-rk3288-flakes.txt b/drivers/gpu/drm/ci/xfails/rockchip-rk3288-flakes.txt deleted file mode 100644 index 45c54c75c899..000000000000 --- a/drivers/gpu/drm/ci/xfails/rockchip-rk3288-flakes.txt +++ /dev/null @@ -1,9 +0,0 @@ -kms_addfb_basic@addfb25-bad-modifier -kms_cursor_crc@.* -kms_flip@basic-flip-vs-wf_vblank -kms_invalid_mode@int-max-clock,Crash -kms_pipe_crc_basic@.* -kms_properties@connector-properties-atomic,Crash -kms_properties@get_properties-sanity-atomic,Crash -kms_properties@get_properties-sanity-non-atomic,Crash -kms_rmfb@close-fd diff --git a/drivers/gpu/drm/ci/xfails/rockchip-rk3399-fails.txt b/drivers/gpu/drm/ci/xfails/rockchip-rk3399-fails.txt index 6db08ba6b008..d516d9c1d546 100644 --- a/drivers/gpu/drm/ci/xfails/rockchip-rk3399-fails.txt +++ b/drivers/gpu/drm/ci/xfails/rockchip-rk3399-fails.txt @@ -1,15 +1,40 @@ +kms_color@gamma,Fail kms_color@legacy-gamma,Fail kms_color@pipe-A-legacy-gamma,Fail kms_color@pipe-B-legacy-gamma,Fail +kms_cursor_crc@cursor-alpha-opaque,Fail +kms_cursor_crc@cursor-alpha-transparent,Fail +kms_cursor_crc@cursor-dpms,Fail +kms_cursor_crc@cursor-offscreen-32x10,Fail +kms_cursor_crc@cursor-offscreen-32x32,Fail +kms_cursor_crc@cursor-offscreen-64x64,Fail +kms_cursor_crc@cursor-onscreen-32x10,Fail +kms_cursor_crc@cursor-onscreen-32x32,Fail +kms_cursor_crc@cursor-onscreen-64x21,Fail +kms_cursor_crc@cursor-onscreen-64x64,Fail +kms_cursor_crc@cursor-random-32x10,Fail +kms_cursor_crc@cursor-random-32x32,Fail +kms_cursor_crc@cursor-random-64x21,Fail +kms_cursor_crc@cursor-random-64x64,Fail +kms_cursor_crc@cursor-rapid-movement-32x32,Fail +kms_cursor_crc@cursor-rapid-movement-64x21,Fail +kms_cursor_crc@cursor-rapid-movement-64x64,Fail +kms_cursor_crc@cursor-size-change,Fail +kms_cursor_crc@cursor-sliding-32x10,Fail +kms_cursor_crc@cursor-sliding-32x32,Fail +kms_cursor_crc@cursor-sliding-64x21,Fail +kms_cursor_crc@cursor-sliding-64x64,Fail kms_flip@basic-flip-vs-wf_vblank,Fail kms_flip@blocking-wf_vblank,Fail kms_flip@dpms-vs-vblank-race,Fail kms_flip@flip-vs-absolute-wf_vblank,Fail kms_flip@flip-vs-absolute-wf_vblank-interruptible,Fail kms_flip@flip-vs-blocking-wf-vblank,Fail +kms_flip@flip-vs-modeset-vs-hang,Fail kms_flip@flip-vs-panning,Fail kms_flip@flip-vs-panning-interruptible,Fail -kms_flip@flip-vs-wf_vblank-interruptible,Fail +kms_flip@flip-vs-panning-vs-hang,Fail +kms_flip@modeset-vs-vblank-race,Fail kms_flip@plain-flip-fb-recreate,Fail kms_flip@plain-flip-fb-recreate-interruptible,Fail kms_flip@plain-flip-ts-check,Fail @@ -17,11 +42,21 @@ kms_flip@plain-flip-ts-check-interruptible,Fail kms_flip@wf_vblank-ts-check,Fail kms_flip@wf_vblank-ts-check-interruptible,Fail kms_invalid_mode@int-max-clock,Fail +kms_pipe_crc_basic@compare-crc-sanitycheck-nv12,Fail +kms_pipe_crc_basic@compare-crc-sanitycheck-xr24,Fail +kms_pipe_crc_basic@disable-crc-after-crtc,Fail +kms_pipe_crc_basic@nonblocking-crc,Fail +kms_pipe_crc_basic@nonblocking-crc-frame-sequence,Fail +kms_pipe_crc_basic@read-crc,Fail +kms_pipe_crc_basic@read-crc-frame-sequence,Fail kms_plane@pixel-format,Fail kms_plane@pixel-format-source-clamping,Fail kms_plane@plane-panning-bottom-right,Fail kms_plane@plane-panning-top-left,Fail kms_plane@plane-position-covered,Fail +kms_plane@plane-position-hole,Fail +kms_plane@plane-position-hole-dpms,Fail +kms_plane_cursor@overlay,Fail kms_plane_cursor@pipe-B-overlay-size-128,Fail kms_plane_cursor@pipe-B-overlay-size-256,Fail kms_plane_cursor@pipe-B-overlay-size-64,Fail @@ -31,7 +66,10 @@ kms_plane_cursor@pipe-B-primary-size-64,Fail kms_plane_cursor@pipe-B-viewport-size-128,Fail kms_plane_cursor@pipe-B-viewport-size-256,Fail kms_plane_cursor@pipe-B-viewport-size-64,Fail +kms_plane_cursor@primary,Fail +kms_plane_cursor@viewport,Fail kms_plane_multiple@atomic-pipe-B-tiling-none,Fail kms_plane_multiple@tiling-none,Fail kms_prime@basic-crc,Fail kms_rmfb@close-fd,Fail +kms_universal_plane@universal-plane-pipe-B-functional,Fail diff --git a/drivers/gpu/drm/ci/xfails/rockchip-rk3399-flakes.txt b/drivers/gpu/drm/ci/xfails/rockchip-rk3399-flakes.txt index 4c0539b4beaf..c9fdc623ab91 100644 --- a/drivers/gpu/drm/ci/xfails/rockchip-rk3399-flakes.txt +++ b/drivers/gpu/drm/ci/xfails/rockchip-rk3399-flakes.txt @@ -1,23 +1,7 @@ - -kms_cursor_crc@.* +kms_bw@linear-tiling-2-displays-1920x1080p +kms_cursor_crc@cursor-offscreen-64x21 kms_flip@dpms-vs-vblank-race-interruptible -kms_flip@flip-vs-expired-vblank -kms_flip@modeset-vs-vblank-race-interruptible -kms_pipe_crc_basic@.* -kms_pipe_crc_basic@compare-crc-sanitycheck-pipe-A -kms_pipe_crc_basic@compare-crc-sanitycheck-pipe-B -kms_plane@plane-position-hole -kms_plane_multiple@atomic-pipe-A-tiling-none -kms_plane_multiple@atomic-pipe-B-tiling-none -kms_sequence@get-forked -kms_sequence@get-forked-busy -kms_setmode@basic -kms_universal_plane@universal-plane-pipe-B-functional,UnexpectedPass -kms_vblank@pipe-A-accuracy-idle -kms_vblank@pipe-A-query-busy -kms_vblank@pipe-A-query-forked-busy -kms_vblank@pipe-A-wait-idle -kms_vblank@pipe-B-accuracy-idle -kms_vblank@pipe-B-query-busy -kms_vblank@pipe-B-query-forked-busy -kms_vblank@pipe-B-wait-idle +kms_flip@flip-vs-wf_vblank-interruptible +kms_plane_cursor@overlay +kms_plane_cursor@primary +kms_plane_cursor@viewport diff --git a/drivers/gpu/drm/ci/xfails/update-xfails.py b/drivers/gpu/drm/ci/xfails/update-xfails.py new file mode 100755 index 000000000000..e9f0ec7fed8d --- /dev/null +++ b/drivers/gpu/drm/ci/xfails/update-xfails.py @@ -0,0 +1,204 @@ +#!/usr/bin/env python3 + +import argparse +from collections import defaultdict +import difflib +import os +import re +from glcollate import Collate +from termcolor import colored +from urllib.parse import urlparse + + +def get_canonical_name(job_name): + return re.split(r" \d+/\d+", job_name)[0] + + +def get_xfails_file_path(job_name, suffix): + canonical_name = get_canonical_name(job_name) + name = canonical_name.replace(":", "-") + script_dir = os.path.dirname(os.path.abspath(__file__)) + return os.path.join(script_dir, f"{name}-{suffix}.txt") + + +def get_unit_test_name_and_results(unit_test): + if "Artifact results/failures.csv not found" in unit_test or '' == unit_test: + return None, None + unit_test_name, unit_test_result = unit_test.strip().split(",") + return unit_test_name, unit_test_result + + +def read_file(file_path): + try: + with open(file_path, "r") as file: + f = file.readlines() + if len(f): + f[-1] = f[-1].strip() + "\n" + return f + except FileNotFoundError: + return [] + + +def save_file(content, file_path): + # delete file is content is empty + if not content or not any(content): + if os.path.exists(file_path): + os.remove(file_path) + return + + with open(file_path, "w") as file: + file.writelines(content) + + +def is_test_present_on_file(file_content, unit_test_name): + return any(unit_test_name in line for line in file_content) + + +def is_unit_test_present_in_other_jobs(unit_test, job_ids): + return all(unit_test in job_ids[job_id] for job_id in job_ids) + + +def remove_unit_test_if_present(lines, unit_test_name): + if not is_test_present_on_file(lines, unit_test_name): + return + lines[:] = [line for line in lines if unit_test_name not in line] + + +def add_unit_test_if_not_present(lines, unit_test_name, file_name): + # core_getversion is mandatory + if "core_getversion" in unit_test_name: + print("WARNING: core_getversion should pass, not adding it to", os.path.basename(file_name)) + elif all(unit_test_name not in line for line in lines): + lines.append(unit_test_name + "\n") + + +def update_unit_test_result_in_fails_txt(fails_txt, unit_test): + unit_test_name, unit_test_result = get_unit_test_name_and_results(unit_test) + for i, line in enumerate(fails_txt): + if unit_test_name in line: + _, current_result = get_unit_test_name_and_results(line) + fails_txt[i] = unit_test + "\n" + return + + +def add_unit_test_or_update_result_to_fails_if_present(fails_txt, unit_test, fails_txt_path): + unit_test_name, _ = get_unit_test_name_and_results(unit_test) + if not is_test_present_on_file(fails_txt, unit_test_name): + add_unit_test_if_not_present(fails_txt, unit_test, fails_txt_path) + # if it is present but not with the same result + elif not is_test_present_on_file(fails_txt, unit_test): + update_unit_test_result_in_fails_txt(fails_txt, unit_test) + + +def split_unit_test_from_collate(xfails): + for job_name in xfails.keys(): + for job_id in xfails[job_name].copy().keys(): + if "not found" in xfails[job_name][job_id]: + del xfails[job_name][job_id] + continue + xfails[job_name][job_id] = xfails[job_name][job_id].strip().split("\n") + + +def get_xfails_from_pipeline_url(pipeline_url): + parsed_url = urlparse(pipeline_url) + path_components = parsed_url.path.strip("/").split("/") + + namespace = path_components[0] + project = path_components[1] + pipeline_id = path_components[-1] + + print("Collating from:", namespace, project, pipeline_id) + xfails = ( + Collate(namespace=namespace, project=project) + .from_pipeline(pipeline_id) + .get_artifact("results/failures.csv") + ) + + split_unit_test_from_collate(xfails) + return xfails + + +def get_xfails_from_pipeline_urls(pipelines_urls): + xfails = defaultdict(dict) + + for url in pipelines_urls: + new_xfails = get_xfails_from_pipeline_url(url) + for key in new_xfails: + xfails[key].update(new_xfails[key]) + + return xfails + + +def print_diff(old_content, new_content, file_name): + diff = difflib.unified_diff(old_content, new_content, lineterm="", fromfile=file_name, tofile=file_name) + diff = [colored(line, "green") if line.startswith("+") else + colored(line, "red") if line.startswith("-") else line for line in diff] + print("\n".join(diff[:3])) + print("".join(diff[3:])) + + +def main(pipelines_urls, only_flakes): + xfails = get_xfails_from_pipeline_urls(pipelines_urls) + + for job_name in xfails.keys(): + fails_txt_path = get_xfails_file_path(job_name, "fails") + flakes_txt_path = get_xfails_file_path(job_name, "flakes") + + fails_txt = read_file(fails_txt_path) + flakes_txt = read_file(flakes_txt_path) + + fails_txt_original = fails_txt.copy() + flakes_txt_original = flakes_txt.copy() + + for job_id in xfails[job_name].keys(): + for unit_test in xfails[job_name][job_id]: + unit_test_name, unit_test_result = get_unit_test_name_and_results(unit_test) + + if not unit_test_name: + continue + + if only_flakes: + remove_unit_test_if_present(fails_txt, unit_test_name) + add_unit_test_if_not_present(flakes_txt, unit_test_name, flakes_txt_path) + continue + + # drop it from flakes if it is present to analyze it again + remove_unit_test_if_present(flakes_txt, unit_test_name) + + if unit_test_result == "UnexpectedPass": + remove_unit_test_if_present(fails_txt, unit_test_name) + # flake result + if not is_unit_test_present_in_other_jobs(unit_test, xfails[job_name]): + add_unit_test_if_not_present(flakes_txt, unit_test_name, flakes_txt_path) + continue + + # flake result + if not is_unit_test_present_in_other_jobs(unit_test, xfails[job_name]): + remove_unit_test_if_present(fails_txt, unit_test_name) + add_unit_test_if_not_present(flakes_txt, unit_test_name, flakes_txt_path) + continue + + # consistent result + add_unit_test_or_update_result_to_fails_if_present(fails_txt, unit_test, + fails_txt_path) + + fails_txt.sort() + flakes_txt.sort() + + if fails_txt != fails_txt_original: + save_file(fails_txt, fails_txt_path) + print_diff(fails_txt_original, fails_txt, os.path.basename(fails_txt_path)) + if flakes_txt != flakes_txt_original: + save_file(flakes_txt, flakes_txt_path) + print_diff(flakes_txt_original, flakes_txt, os.path.basename(flakes_txt_path)) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Update xfails from a given pipeline.") + parser.add_argument("pipeline_urls", nargs="+", type=str, help="URLs to the pipelines to analyze the failures.") + parser.add_argument("--only-flakes", action="store_true", help="Treat every detected failure as a flake, edit *-flakes.txt only.") + + args = parser.parse_args() + + main(args.pipeline_urls, args.only_flakes) + print("Done.") diff --git a/drivers/gpu/drm/ci/xfails/virtio_gpu-none-flakes.txt b/drivers/gpu/drm/ci/xfails/virtio_gpu-none-flakes.txt deleted file mode 100644 index e69de29bb2d1..000000000000 --- a/drivers/gpu/drm/ci/xfails/virtio_gpu-none-flakes.txt +++ /dev/null diff --git a/drivers/gpu/drm/drm_client.c b/drivers/gpu/drm/drm_client.c index 2762572f286e..c3027115d055 100644 --- a/drivers/gpu/drm/drm_client.c +++ b/drivers/gpu/drm/drm_client.c @@ -395,19 +395,16 @@ static int drm_client_buffer_addfb(struct drm_client_buffer *buffer, u32 handle) { struct drm_client_dev *client = buffer->client; - struct drm_mode_fb_cmd fb_req = { }; - const struct drm_format_info *info; + struct drm_mode_fb_cmd2 fb_req = { }; int ret; - info = drm_format_info(format); - fb_req.bpp = drm_format_info_bpp(info, 0); - fb_req.depth = info->depth; fb_req.width = width; fb_req.height = height; - fb_req.handle = handle; - fb_req.pitch = buffer->pitch; + fb_req.pixel_format = format; + fb_req.handles[0] = handle; + fb_req.pitches[0] = buffer->pitch; - ret = drm_mode_addfb(client->dev, &fb_req, client->file); + ret = drm_mode_addfb2(client->dev, &fb_req, client->file); if (ret) return ret; diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c index 0f17dfa8702b..193cf8ed7912 100644 --- a/drivers/gpu/drm/drm_fourcc.c +++ b/drivers/gpu/drm/drm_fourcc.c @@ -299,6 +299,14 @@ const struct drm_format_info *__drm_format_info(u32 format) .num_planes = 2, .char_per_block = { 5, 5, 0 }, .block_w = { 4, 2, 0 }, .block_h = { 1, 1, 0 }, .hsub = 2, .vsub = 2, .is_yuv = true }, + { .format = DRM_FORMAT_NV20, .depth = 0, + .num_planes = 2, .char_per_block = { 5, 5, 0 }, + .block_w = { 4, 2, 0 }, .block_h = { 1, 1, 0 }, .hsub = 2, + .vsub = 1, .is_yuv = true }, + { .format = DRM_FORMAT_NV30, .depth = 0, + .num_planes = 2, .char_per_block = { 5, 5, 0 }, + .block_w = { 4, 2, 0 }, .block_h = { 1, 1, 0 }, .hsub = 1, + .vsub = 1, .is_yuv = true }, { .format = DRM_FORMAT_Q410, .depth = 0, .num_planes = 3, .char_per_block = { 2, 2, 2 }, .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 1, diff --git a/drivers/gpu/drm/drm_gpuvm.c b/drivers/gpu/drm/drm_gpuvm.c index 02ce6baacdad..08c088319652 100644 --- a/drivers/gpu/drm/drm_gpuvm.c +++ b/drivers/gpu/drm/drm_gpuvm.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0-only +// SPDX-License-Identifier: GPL-2.0 OR MIT /* * Copyright (c) 2022 Red Hat. * diff --git a/drivers/gpu/drm/etnaviv/etnaviv_sched.c b/drivers/gpu/drm/etnaviv/etnaviv_sched.c index 345fec6cb1a4..9b79f218e21a 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_sched.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_sched.c @@ -135,6 +135,7 @@ int etnaviv_sched_init(struct etnaviv_gpu *gpu) int ret; ret = drm_sched_init(&gpu->sched, &etnaviv_sched_ops, + DRM_SCHED_PRIORITY_COUNT, etnaviv_hw_jobs_limit, etnaviv_job_hang_limit, msecs_to_jiffies(500), NULL, NULL, dev_name(gpu->dev), gpu->dev); diff --git a/drivers/gpu/drm/lima/lima_sched.c b/drivers/gpu/drm/lima/lima_sched.c index ffd91a5ee299..295f0353a02e 100644 --- a/drivers/gpu/drm/lima/lima_sched.c +++ b/drivers/gpu/drm/lima/lima_sched.c @@ -488,7 +488,9 @@ int lima_sched_pipe_init(struct lima_sched_pipe *pipe, const char *name) INIT_WORK(&pipe->recover_work, lima_sched_recover_work); - return drm_sched_init(&pipe->base, &lima_sched_ops, 1, + return drm_sched_init(&pipe->base, &lima_sched_ops, + DRM_SCHED_PRIORITY_COUNT, + 1, lima_job_hang_limit, msecs_to_jiffies(timeout), NULL, NULL, name, pipe->ldev->dev); diff --git a/drivers/gpu/drm/msm/msm_ringbuffer.c b/drivers/gpu/drm/msm/msm_ringbuffer.c index 40c0bc35a44c..95257ab0185d 100644 --- a/drivers/gpu/drm/msm/msm_ringbuffer.c +++ b/drivers/gpu/drm/msm/msm_ringbuffer.c @@ -95,8 +95,9 @@ struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int id, sched_timeout = MAX_SCHEDULE_TIMEOUT; ret = drm_sched_init(&ring->sched, &msm_sched_ops, - num_hw_submissions, 0, sched_timeout, - NULL, NULL, to_msm_bo(ring->bo)->name, gpu->dev->dev); + DRM_SCHED_PRIORITY_COUNT, + num_hw_submissions, 0, sched_timeout, + NULL, NULL, to_msm_bo(ring->bo)->name, gpu->dev->dev); if (ret) { goto fail; } diff --git a/drivers/gpu/drm/nouveau/nouveau_sched.c b/drivers/gpu/drm/nouveau/nouveau_sched.c index 3b7ea5221226..7c376c4ccdcf 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sched.c +++ b/drivers/gpu/drm/nouveau/nouveau_sched.c @@ -436,6 +436,7 @@ int nouveau_sched_init(struct nouveau_drm *drm) return -ENOMEM; return drm_sched_init(sched, &nouveau_sched_ops, + DRM_SCHED_PRIORITY_COUNT, NOUVEAU_SCHED_HW_SUBMISSIONS, 0, job_hang_limit, NULL, NULL, "nouveau_sched", drm->dev->dev); } diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index ecb22ea326cb..99e14dc212ec 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -203,6 +203,15 @@ config DRM_PANEL_ILITEK_ILI9881C Say Y if you want to enable support for panels based on the Ilitek ILI9881c controller. +config DRM_PANEL_ILITEK_ILI9882T + tristate "Ilitek ILI9882t-based panels" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + help + Say Y if you want to enable support for panels based on the + Ilitek ILI9882t controller. + config DRM_PANEL_INNOLUX_EJ030NA tristate "Innolux EJ030NA 320x480 LCD panel" depends on OF && SPI diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index e14ce55a0875..d10c3de51c6d 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_DRM_PANEL_HIMAX_HX8394) += panel-himax-hx8394.o obj-$(CONFIG_DRM_PANEL_ILITEK_IL9322) += panel-ilitek-ili9322.o obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9341) += panel-ilitek-ili9341.o obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9881C) += panel-ilitek-ili9881c.o +obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9882T) += panel-ilitek-ili9882t.o obj-$(CONFIG_DRM_PANEL_INNOLUX_EJ030NA) += panel-innolux-ej030na.o obj-$(CONFIG_DRM_PANEL_INNOLUX_P079ZCA) += panel-innolux-p079zca.o obj-$(CONFIG_DRM_PANEL_JADARD_JD9365DA_H3) += panel-jadard-jd9365da-h3.o diff --git a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c index c9087f474cbc..9323e7b9e384 100644 --- a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c +++ b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c @@ -1368,346 +1368,6 @@ static const struct panel_init_cmd starry_himax83102_j02_init_cmd[] = { {}, }; -static const struct panel_init_cmd starry_ili9882t_init_cmd[] = { - _INIT_DELAY_CMD(5), - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x01), - _INIT_DCS_CMD(0x00, 0x42), - _INIT_DCS_CMD(0x01, 0x11), - _INIT_DCS_CMD(0x02, 0x00), - _INIT_DCS_CMD(0x03, 0x00), - - _INIT_DCS_CMD(0x04, 0x01), - _INIT_DCS_CMD(0x05, 0x11), - _INIT_DCS_CMD(0x06, 0x00), - _INIT_DCS_CMD(0x07, 0x00), - - _INIT_DCS_CMD(0x08, 0x80), - _INIT_DCS_CMD(0x09, 0x81), - _INIT_DCS_CMD(0x0A, 0x71), - _INIT_DCS_CMD(0x0B, 0x00), - - _INIT_DCS_CMD(0x0C, 0x00), - _INIT_DCS_CMD(0x0E, 0x1A), - - _INIT_DCS_CMD(0x24, 0x00), - _INIT_DCS_CMD(0x25, 0x00), - _INIT_DCS_CMD(0x26, 0x00), - _INIT_DCS_CMD(0x27, 0x00), - - _INIT_DCS_CMD(0x2C, 0xD4), - _INIT_DCS_CMD(0xB9, 0x40), - - _INIT_DCS_CMD(0xB0, 0x11), - - _INIT_DCS_CMD(0xE6, 0x32), - _INIT_DCS_CMD(0xD1, 0x30), - - _INIT_DCS_CMD(0xD6, 0x55), - - _INIT_DCS_CMD(0xD0, 0x01), - _INIT_DCS_CMD(0xE3, 0x93), - _INIT_DCS_CMD(0xE4, 0x00), - _INIT_DCS_CMD(0xE5, 0x80), - - _INIT_DCS_CMD(0x31, 0x07), - _INIT_DCS_CMD(0x32, 0x07), - _INIT_DCS_CMD(0x33, 0x07), - _INIT_DCS_CMD(0x34, 0x07), - _INIT_DCS_CMD(0x35, 0x07), - _INIT_DCS_CMD(0x36, 0x01), - _INIT_DCS_CMD(0x37, 0x00), - _INIT_DCS_CMD(0x38, 0x28), - _INIT_DCS_CMD(0x39, 0x29), - _INIT_DCS_CMD(0x3A, 0x11), - _INIT_DCS_CMD(0x3B, 0x13), - _INIT_DCS_CMD(0x3C, 0x15), - _INIT_DCS_CMD(0x3D, 0x17), - _INIT_DCS_CMD(0x3E, 0x09), - _INIT_DCS_CMD(0x3F, 0x0D), - _INIT_DCS_CMD(0x40, 0x02), - _INIT_DCS_CMD(0x41, 0x02), - _INIT_DCS_CMD(0x42, 0x02), - _INIT_DCS_CMD(0x43, 0x02), - _INIT_DCS_CMD(0x44, 0x02), - _INIT_DCS_CMD(0x45, 0x02), - _INIT_DCS_CMD(0x46, 0x02), - - _INIT_DCS_CMD(0x47, 0x07), - _INIT_DCS_CMD(0x48, 0x07), - _INIT_DCS_CMD(0x49, 0x07), - _INIT_DCS_CMD(0x4A, 0x07), - _INIT_DCS_CMD(0x4B, 0x07), - _INIT_DCS_CMD(0x4C, 0x01), - _INIT_DCS_CMD(0x4D, 0x00), - _INIT_DCS_CMD(0x4E, 0x28), - _INIT_DCS_CMD(0x4F, 0x29), - _INIT_DCS_CMD(0x50, 0x10), - _INIT_DCS_CMD(0x51, 0x12), - _INIT_DCS_CMD(0x52, 0x14), - _INIT_DCS_CMD(0x53, 0x16), - _INIT_DCS_CMD(0x54, 0x08), - _INIT_DCS_CMD(0x55, 0x0C), - _INIT_DCS_CMD(0x56, 0x02), - _INIT_DCS_CMD(0x57, 0x02), - _INIT_DCS_CMD(0x58, 0x02), - _INIT_DCS_CMD(0x59, 0x02), - _INIT_DCS_CMD(0x5A, 0x02), - _INIT_DCS_CMD(0x5B, 0x02), - _INIT_DCS_CMD(0x5C, 0x02), - - _INIT_DCS_CMD(0x61, 0x07), - _INIT_DCS_CMD(0x62, 0x07), - _INIT_DCS_CMD(0x63, 0x07), - _INIT_DCS_CMD(0x64, 0x07), - _INIT_DCS_CMD(0x65, 0x07), - _INIT_DCS_CMD(0x66, 0x01), - _INIT_DCS_CMD(0x67, 0x00), - _INIT_DCS_CMD(0x68, 0x28), - _INIT_DCS_CMD(0x69, 0x29), - _INIT_DCS_CMD(0x6A, 0x16), - _INIT_DCS_CMD(0x6B, 0x14), - _INIT_DCS_CMD(0x6C, 0x12), - _INIT_DCS_CMD(0x6D, 0x10), - _INIT_DCS_CMD(0x6E, 0x0C), - _INIT_DCS_CMD(0x6F, 0x08), - _INIT_DCS_CMD(0x70, 0x02), - _INIT_DCS_CMD(0x71, 0x02), - _INIT_DCS_CMD(0x72, 0x02), - _INIT_DCS_CMD(0x73, 0x02), - _INIT_DCS_CMD(0x74, 0x02), - _INIT_DCS_CMD(0x75, 0x02), - _INIT_DCS_CMD(0x76, 0x02), - - _INIT_DCS_CMD(0x77, 0x07), - _INIT_DCS_CMD(0x78, 0x07), - _INIT_DCS_CMD(0x79, 0x07), - _INIT_DCS_CMD(0x7A, 0x07), - _INIT_DCS_CMD(0x7B, 0x07), - _INIT_DCS_CMD(0x7C, 0x01), - _INIT_DCS_CMD(0x7D, 0x00), - _INIT_DCS_CMD(0x7E, 0x28), - _INIT_DCS_CMD(0x7F, 0x29), - _INIT_DCS_CMD(0x80, 0x17), - _INIT_DCS_CMD(0x81, 0x15), - _INIT_DCS_CMD(0x82, 0x13), - _INIT_DCS_CMD(0x83, 0x11), - _INIT_DCS_CMD(0x84, 0x0D), - _INIT_DCS_CMD(0x85, 0x09), - _INIT_DCS_CMD(0x86, 0x02), - _INIT_DCS_CMD(0x87, 0x07), - _INIT_DCS_CMD(0x88, 0x07), - _INIT_DCS_CMD(0x89, 0x07), - _INIT_DCS_CMD(0x8A, 0x07), - _INIT_DCS_CMD(0x8B, 0x07), - _INIT_DCS_CMD(0x8C, 0x07), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x02), - _INIT_DCS_CMD(0x29, 0x3A), - _INIT_DCS_CMD(0x2A, 0x3B), - - _INIT_DCS_CMD(0x06, 0x01), - _INIT_DCS_CMD(0x07, 0x01), - _INIT_DCS_CMD(0x08, 0x0C), - _INIT_DCS_CMD(0x09, 0x44), - - _INIT_DCS_CMD(0x3C, 0x0A), - _INIT_DCS_CMD(0x39, 0x11), - _INIT_DCS_CMD(0x3D, 0x00), - _INIT_DCS_CMD(0x3A, 0x0C), - _INIT_DCS_CMD(0x3B, 0x44), - - _INIT_DCS_CMD(0x53, 0x1F), - _INIT_DCS_CMD(0x5E, 0x40), - _INIT_DCS_CMD(0x84, 0x00), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x03), - _INIT_DCS_CMD(0x20, 0x01), - _INIT_DCS_CMD(0x21, 0x3C), - _INIT_DCS_CMD(0x22, 0xFA), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x0A), - _INIT_DCS_CMD(0xE0, 0x01), - _INIT_DCS_CMD(0xE2, 0x01), - _INIT_DCS_CMD(0xE5, 0x91), - _INIT_DCS_CMD(0xE6, 0x3C), - _INIT_DCS_CMD(0xE7, 0x00), - _INIT_DCS_CMD(0xE8, 0xFA), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x12), - _INIT_DCS_CMD(0x87, 0x2C), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x05), - _INIT_DCS_CMD(0x73, 0xE5), - _INIT_DCS_CMD(0x7F, 0x6B), - _INIT_DCS_CMD(0x6D, 0xA4), - _INIT_DCS_CMD(0x79, 0x54), - _INIT_DCS_CMD(0x69, 0x97), - _INIT_DCS_CMD(0x6A, 0x97), - _INIT_DCS_CMD(0xA5, 0x3F), - _INIT_DCS_CMD(0x61, 0xDA), - _INIT_DCS_CMD(0xA7, 0xF1), - _INIT_DCS_CMD(0x5F, 0x01), - _INIT_DCS_CMD(0x62, 0x3F), - _INIT_DCS_CMD(0x1D, 0x90), - _INIT_DCS_CMD(0x86, 0x87), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x06), - _INIT_DCS_CMD(0xC0, 0x80), - _INIT_DCS_CMD(0xC1, 0x07), - _INIT_DCS_CMD(0xCA, 0x58), - _INIT_DCS_CMD(0xCB, 0x02), - _INIT_DCS_CMD(0xCE, 0x58), - _INIT_DCS_CMD(0xCF, 0x02), - _INIT_DCS_CMD(0x67, 0x60), - _INIT_DCS_CMD(0x10, 0x00), - _INIT_DCS_CMD(0x92, 0x22), - _INIT_DCS_CMD(0xD3, 0x08), - _INIT_DCS_CMD(0xD6, 0x55), - _INIT_DCS_CMD(0xDC, 0x38), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x08), - _INIT_DCS_CMD(0xE0, 0x00, 0x10, 0x2A, 0x4D, 0x61, 0x56, 0x6A, 0x6E, 0x79, 0x76, 0x8F, 0x95, 0x98, 0xAE, 0xAA, 0xB2, 0xBB, 0xCE, 0xC6, 0xBD, 0xD5, 0xE2, 0xE8), - _INIT_DCS_CMD(0xE1, 0x00, 0x10, 0x2A, 0x4D, 0x61, 0x56, 0x6A, 0x6E, 0x79, 0x76, 0x8F, 0x95, 0x98, 0xAE, 0xAA, 0xB2, 0xBB, 0xCE, 0xC6, 0xBD, 0xD5, 0xE2, 0xE8), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x04), - _INIT_DCS_CMD(0xBA, 0x81), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x0C), - _INIT_DCS_CMD(0x00, 0x02), - _INIT_DCS_CMD(0x01, 0x00), - _INIT_DCS_CMD(0x02, 0x03), - _INIT_DCS_CMD(0x03, 0x01), - _INIT_DCS_CMD(0x04, 0x03), - _INIT_DCS_CMD(0x05, 0x02), - _INIT_DCS_CMD(0x06, 0x04), - _INIT_DCS_CMD(0x07, 0x03), - _INIT_DCS_CMD(0x08, 0x03), - _INIT_DCS_CMD(0x09, 0x04), - _INIT_DCS_CMD(0x0A, 0x04), - _INIT_DCS_CMD(0x0B, 0x05), - _INIT_DCS_CMD(0x0C, 0x04), - _INIT_DCS_CMD(0x0D, 0x06), - _INIT_DCS_CMD(0x0E, 0x05), - _INIT_DCS_CMD(0x0F, 0x07), - _INIT_DCS_CMD(0x10, 0x04), - _INIT_DCS_CMD(0x11, 0x08), - _INIT_DCS_CMD(0x12, 0x05), - _INIT_DCS_CMD(0x13, 0x09), - _INIT_DCS_CMD(0x14, 0x05), - _INIT_DCS_CMD(0x15, 0x0A), - _INIT_DCS_CMD(0x16, 0x06), - _INIT_DCS_CMD(0x17, 0x0B), - _INIT_DCS_CMD(0x18, 0x05), - _INIT_DCS_CMD(0x19, 0x0C), - _INIT_DCS_CMD(0x1A, 0x06), - _INIT_DCS_CMD(0x1B, 0x0D), - _INIT_DCS_CMD(0x1C, 0x06), - _INIT_DCS_CMD(0x1D, 0x0E), - _INIT_DCS_CMD(0x1E, 0x07), - _INIT_DCS_CMD(0x1F, 0x0F), - _INIT_DCS_CMD(0x20, 0x06), - _INIT_DCS_CMD(0x21, 0x10), - _INIT_DCS_CMD(0x22, 0x07), - _INIT_DCS_CMD(0x23, 0x11), - _INIT_DCS_CMD(0x24, 0x07), - _INIT_DCS_CMD(0x25, 0x12), - _INIT_DCS_CMD(0x26, 0x08), - _INIT_DCS_CMD(0x27, 0x13), - _INIT_DCS_CMD(0x28, 0x07), - _INIT_DCS_CMD(0x29, 0x14), - _INIT_DCS_CMD(0x2A, 0x08), - _INIT_DCS_CMD(0x2B, 0x15), - _INIT_DCS_CMD(0x2C, 0x08), - _INIT_DCS_CMD(0x2D, 0x16), - _INIT_DCS_CMD(0x2E, 0x09), - _INIT_DCS_CMD(0x2F, 0x17), - _INIT_DCS_CMD(0x30, 0x08), - _INIT_DCS_CMD(0x31, 0x18), - _INIT_DCS_CMD(0x32, 0x09), - _INIT_DCS_CMD(0x33, 0x19), - _INIT_DCS_CMD(0x34, 0x09), - _INIT_DCS_CMD(0x35, 0x1A), - _INIT_DCS_CMD(0x36, 0x0A), - _INIT_DCS_CMD(0x37, 0x1B), - _INIT_DCS_CMD(0x38, 0x0A), - _INIT_DCS_CMD(0x39, 0x1C), - _INIT_DCS_CMD(0x3A, 0x0A), - _INIT_DCS_CMD(0x3B, 0x1D), - _INIT_DCS_CMD(0x3C, 0x0A), - _INIT_DCS_CMD(0x3D, 0x1E), - _INIT_DCS_CMD(0x3E, 0x0A), - _INIT_DCS_CMD(0x3F, 0x1F), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x04), - _INIT_DCS_CMD(0xBA, 0x01), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x0E), - _INIT_DCS_CMD(0x02, 0x0C), - _INIT_DCS_CMD(0x20, 0x10), - _INIT_DCS_CMD(0x25, 0x16), - _INIT_DCS_CMD(0x26, 0xE0), - _INIT_DCS_CMD(0x27, 0x00), - _INIT_DCS_CMD(0x29, 0x71), - _INIT_DCS_CMD(0x2A, 0x46), - _INIT_DCS_CMD(0x2B, 0x1F), - _INIT_DCS_CMD(0x2D, 0xC7), - _INIT_DCS_CMD(0x31, 0x02), - _INIT_DCS_CMD(0x32, 0xDF), - _INIT_DCS_CMD(0x33, 0x5A), - _INIT_DCS_CMD(0x34, 0xC0), - _INIT_DCS_CMD(0x35, 0x5A), - _INIT_DCS_CMD(0x36, 0xC0), - _INIT_DCS_CMD(0x38, 0x65), - _INIT_DCS_CMD(0x80, 0x3E), - _INIT_DCS_CMD(0x81, 0xA0), - _INIT_DCS_CMD(0xB0, 0x01), - _INIT_DCS_CMD(0xB1, 0xCC), - _INIT_DCS_CMD(0xC0, 0x12), - _INIT_DCS_CMD(0xC2, 0xCC), - _INIT_DCS_CMD(0xC3, 0xCC), - _INIT_DCS_CMD(0xC4, 0xCC), - _INIT_DCS_CMD(0xC5, 0xCC), - _INIT_DCS_CMD(0xC6, 0xCC), - _INIT_DCS_CMD(0xC7, 0xCC), - _INIT_DCS_CMD(0xC8, 0xCC), - _INIT_DCS_CMD(0xC9, 0xCC), - _INIT_DCS_CMD(0x30, 0x00), - _INIT_DCS_CMD(0x00, 0x81), - _INIT_DCS_CMD(0x08, 0x02), - _INIT_DCS_CMD(0x09, 0x00), - _INIT_DCS_CMD(0x07, 0x21), - _INIT_DCS_CMD(0x04, 0x10), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x1E), - _INIT_DCS_CMD(0x60, 0x00), - _INIT_DCS_CMD(0x64, 0x00), - _INIT_DCS_CMD(0x6D, 0x00), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x0B), - _INIT_DCS_CMD(0xA6, 0x44), - _INIT_DCS_CMD(0xA7, 0xB6), - _INIT_DCS_CMD(0xA8, 0x03), - _INIT_DCS_CMD(0xA9, 0x03), - _INIT_DCS_CMD(0xAA, 0x51), - _INIT_DCS_CMD(0xAB, 0x51), - _INIT_DCS_CMD(0xAC, 0x04), - _INIT_DCS_CMD(0xBD, 0x92), - _INIT_DCS_CMD(0xBE, 0xA1), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x05), - _INIT_DCS_CMD(0x86, 0x87), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x06), - _INIT_DCS_CMD(0x92, 0x22), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x00), - _INIT_DCS_CMD(0x11), - _INIT_DELAY_CMD(120), - _INIT_DCS_CMD(0x29), - _INIT_DELAY_CMD(20), - {}, -}; - static inline struct boe_panel *to_boe_panel(struct drm_panel *panel) { return container_of(panel, struct boe_panel, base); @@ -2133,34 +1793,6 @@ static const struct panel_desc starry_himax83102_j02_desc = { .lp11_before_reset = true, }; -static const struct drm_display_mode starry_ili9882t_default_mode = { - .clock = 165280, - .hdisplay = 1200, - .hsync_start = 1200 + 72, - .hsync_end = 1200 + 72 + 30, - .htotal = 1200 + 72 + 30 + 72, - .vdisplay = 1920, - .vsync_start = 1920 + 68, - .vsync_end = 1920 + 68 + 2, - .vtotal = 1920 + 68 + 2 + 10, - .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, -}; - -static const struct panel_desc starry_ili9882t_desc = { - .modes = &starry_ili9882t_default_mode, - .bpc = 8, - .size = { - .width_mm = 141, - .height_mm = 226, - }, - .lanes = 4, - .format = MIPI_DSI_FMT_RGB888, - .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE | - MIPI_DSI_MODE_LPM, - .init_cmds = starry_ili9882t_init_cmd, - .lp11_before_reset = true, -}; - static int boe_panel_get_modes(struct drm_panel *panel, struct drm_connector *connector) { @@ -2337,9 +1969,6 @@ static const struct of_device_id boe_of_match[] = { { .compatible = "starry,himax83102-j02", .data = &starry_himax83102_j02_desc }, - { .compatible = "starry,ili9882t", - .data = &starry_ili9882t_desc - }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, boe_of_match); diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c b/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c new file mode 100644 index 000000000000..267a5307041c --- /dev/null +++ b/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c @@ -0,0 +1,779 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Panels based on the Ilitek ILI9882T display controller. + */ +#include <linux/delay.h> +#include <linux/gpio/consumer.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/regulator/consumer.h> + +#include <drm/drm_connector.h> +#include <drm/drm_crtc.h> +#include <drm/drm_mipi_dsi.h> +#include <drm/drm_panel.h> + +#include <video/mipi_display.h> + +/* + * Use this descriptor struct to describe different panels using the + * Ilitek ILI9882T display controller. + */ +struct panel_desc { + const struct drm_display_mode *modes; + unsigned int bpc; + + /** + * @width_mm: width of the panel's active display area + * @height_mm: height of the panel's active display area + */ + struct { + unsigned int width_mm; + unsigned int height_mm; + } size; + + unsigned long mode_flags; + enum mipi_dsi_pixel_format format; + const struct panel_init_cmd *init_cmds; + unsigned int lanes; +}; + +struct ili9882t { + struct drm_panel base; + struct mipi_dsi_device *dsi; + + const struct panel_desc *desc; + + enum drm_panel_orientation orientation; + struct regulator *pp3300; + struct regulator *pp1800; + struct regulator *avee; + struct regulator *avdd; + struct gpio_desc *enable_gpio; +}; + +enum dsi_cmd_type { + INIT_DCS_CMD, + DELAY_CMD, +}; + +struct panel_init_cmd { + enum dsi_cmd_type type; + size_t len; + const char *data; +}; + +#define _INIT_DCS_CMD(...) { \ + .type = INIT_DCS_CMD, \ + .len = sizeof((char[]){__VA_ARGS__}), \ + .data = (char[]){__VA_ARGS__} } + +#define _INIT_DELAY_CMD(...) { \ + .type = DELAY_CMD,\ + .len = sizeof((char[]){__VA_ARGS__}), \ + .data = (char[]){__VA_ARGS__} } + +/* ILI9882-specific commands, add new commands as you decode them */ +#define ILI9882T_DCS_SWITCH_PAGE 0xFF + +#define _INIT_SWITCH_PAGE_CMD(page) \ + _INIT_DCS_CMD(ILI9882T_DCS_SWITCH_PAGE, 0x98, 0x82, (page)) + +static const struct panel_init_cmd starry_ili9882t_init_cmd[] = { + _INIT_DELAY_CMD(5), + _INIT_SWITCH_PAGE_CMD(0x01), + _INIT_DCS_CMD(0x00, 0x42), + _INIT_DCS_CMD(0x01, 0x11), + _INIT_DCS_CMD(0x02, 0x00), + _INIT_DCS_CMD(0x03, 0x00), + + _INIT_DCS_CMD(0x04, 0x01), + _INIT_DCS_CMD(0x05, 0x11), + _INIT_DCS_CMD(0x06, 0x00), + _INIT_DCS_CMD(0x07, 0x00), + + _INIT_DCS_CMD(0x08, 0x80), + _INIT_DCS_CMD(0x09, 0x81), + _INIT_DCS_CMD(0x0A, 0x71), + _INIT_DCS_CMD(0x0B, 0x00), + + _INIT_DCS_CMD(0x0C, 0x00), + _INIT_DCS_CMD(0x0E, 0x1A), + + _INIT_DCS_CMD(0x24, 0x00), + _INIT_DCS_CMD(0x25, 0x00), + _INIT_DCS_CMD(0x26, 0x00), + _INIT_DCS_CMD(0x27, 0x00), + + _INIT_DCS_CMD(0x2C, 0xD4), + _INIT_DCS_CMD(0xB9, 0x40), + + _INIT_DCS_CMD(0xB0, 0x11), + + _INIT_DCS_CMD(0xE6, 0x32), + _INIT_DCS_CMD(0xD1, 0x30), + + _INIT_DCS_CMD(0xD6, 0x55), + + _INIT_DCS_CMD(0xD0, 0x01), + _INIT_DCS_CMD(0xE3, 0x93), + _INIT_DCS_CMD(0xE4, 0x00), + _INIT_DCS_CMD(0xE5, 0x80), + + _INIT_DCS_CMD(0x31, 0x07), + _INIT_DCS_CMD(0x32, 0x07), + _INIT_DCS_CMD(0x33, 0x07), + _INIT_DCS_CMD(0x34, 0x07), + _INIT_DCS_CMD(0x35, 0x07), + _INIT_DCS_CMD(0x36, 0x01), + _INIT_DCS_CMD(0x37, 0x00), + _INIT_DCS_CMD(0x38, 0x28), + _INIT_DCS_CMD(0x39, 0x29), + _INIT_DCS_CMD(0x3A, 0x11), + _INIT_DCS_CMD(0x3B, 0x13), + _INIT_DCS_CMD(0x3C, 0x15), + _INIT_DCS_CMD(0x3D, 0x17), + _INIT_DCS_CMD(0x3E, 0x09), + _INIT_DCS_CMD(0x3F, 0x0D), + _INIT_DCS_CMD(0x40, 0x02), + _INIT_DCS_CMD(0x41, 0x02), + _INIT_DCS_CMD(0x42, 0x02), + _INIT_DCS_CMD(0x43, 0x02), + _INIT_DCS_CMD(0x44, 0x02), + _INIT_DCS_CMD(0x45, 0x02), + _INIT_DCS_CMD(0x46, 0x02), + + _INIT_DCS_CMD(0x47, 0x07), + _INIT_DCS_CMD(0x48, 0x07), + _INIT_DCS_CMD(0x49, 0x07), + _INIT_DCS_CMD(0x4A, 0x07), + _INIT_DCS_CMD(0x4B, 0x07), + _INIT_DCS_CMD(0x4C, 0x01), + _INIT_DCS_CMD(0x4D, 0x00), + _INIT_DCS_CMD(0x4E, 0x28), + _INIT_DCS_CMD(0x4F, 0x29), + _INIT_DCS_CMD(0x50, 0x10), + _INIT_DCS_CMD(0x51, 0x12), + _INIT_DCS_CMD(0x52, 0x14), + _INIT_DCS_CMD(0x53, 0x16), + _INIT_DCS_CMD(0x54, 0x08), + _INIT_DCS_CMD(0x55, 0x0C), + _INIT_DCS_CMD(0x56, 0x02), + _INIT_DCS_CMD(0x57, 0x02), + _INIT_DCS_CMD(0x58, 0x02), + _INIT_DCS_CMD(0x59, 0x02), + _INIT_DCS_CMD(0x5A, 0x02), + _INIT_DCS_CMD(0x5B, 0x02), + _INIT_DCS_CMD(0x5C, 0x02), + + _INIT_DCS_CMD(0x61, 0x07), + _INIT_DCS_CMD(0x62, 0x07), + _INIT_DCS_CMD(0x63, 0x07), + _INIT_DCS_CMD(0x64, 0x07), + _INIT_DCS_CMD(0x65, 0x07), + _INIT_DCS_CMD(0x66, 0x01), + _INIT_DCS_CMD(0x67, 0x00), + _INIT_DCS_CMD(0x68, 0x28), + _INIT_DCS_CMD(0x69, 0x29), + _INIT_DCS_CMD(0x6A, 0x16), + _INIT_DCS_CMD(0x6B, 0x14), + _INIT_DCS_CMD(0x6C, 0x12), + _INIT_DCS_CMD(0x6D, 0x10), + _INIT_DCS_CMD(0x6E, 0x0C), + _INIT_DCS_CMD(0x6F, 0x08), + _INIT_DCS_CMD(0x70, 0x02), + _INIT_DCS_CMD(0x71, 0x02), + _INIT_DCS_CMD(0x72, 0x02), + _INIT_DCS_CMD(0x73, 0x02), + _INIT_DCS_CMD(0x74, 0x02), + _INIT_DCS_CMD(0x75, 0x02), + _INIT_DCS_CMD(0x76, 0x02), + + _INIT_DCS_CMD(0x77, 0x07), + _INIT_DCS_CMD(0x78, 0x07), + _INIT_DCS_CMD(0x79, 0x07), + _INIT_DCS_CMD(0x7A, 0x07), + _INIT_DCS_CMD(0x7B, 0x07), + _INIT_DCS_CMD(0x7C, 0x01), + _INIT_DCS_CMD(0x7D, 0x00), + _INIT_DCS_CMD(0x7E, 0x28), + _INIT_DCS_CMD(0x7F, 0x29), + _INIT_DCS_CMD(0x80, 0x17), + _INIT_DCS_CMD(0x81, 0x15), + _INIT_DCS_CMD(0x82, 0x13), + _INIT_DCS_CMD(0x83, 0x11), + _INIT_DCS_CMD(0x84, 0x0D), + _INIT_DCS_CMD(0x85, 0x09), + _INIT_DCS_CMD(0x86, 0x02), + _INIT_DCS_CMD(0x87, 0x07), + _INIT_DCS_CMD(0x88, 0x07), + _INIT_DCS_CMD(0x89, 0x07), + _INIT_DCS_CMD(0x8A, 0x07), + _INIT_DCS_CMD(0x8B, 0x07), + _INIT_DCS_CMD(0x8C, 0x07), + + _INIT_SWITCH_PAGE_CMD(0x02), + _INIT_DCS_CMD(0x29, 0x3A), + _INIT_DCS_CMD(0x2A, 0x3B), + + _INIT_DCS_CMD(0x06, 0x01), + _INIT_DCS_CMD(0x07, 0x01), + _INIT_DCS_CMD(0x08, 0x0C), + _INIT_DCS_CMD(0x09, 0x44), + + _INIT_DCS_CMD(0x3C, 0x0A), + _INIT_DCS_CMD(0x39, 0x11), + _INIT_DCS_CMD(0x3D, 0x00), + _INIT_DCS_CMD(0x3A, 0x0C), + _INIT_DCS_CMD(0x3B, 0x44), + + _INIT_DCS_CMD(0x53, 0x1F), + _INIT_DCS_CMD(0x5E, 0x40), + _INIT_DCS_CMD(0x84, 0x00), + + _INIT_SWITCH_PAGE_CMD(0x03), + _INIT_DCS_CMD(0x20, 0x01), + _INIT_DCS_CMD(0x21, 0x3C), + _INIT_DCS_CMD(0x22, 0xFA), + + _INIT_SWITCH_PAGE_CMD(0x0A), + _INIT_DCS_CMD(0xE0, 0x01), + _INIT_DCS_CMD(0xE2, 0x01), + _INIT_DCS_CMD(0xE5, 0x91), + _INIT_DCS_CMD(0xE6, 0x3C), + _INIT_DCS_CMD(0xE7, 0x00), + _INIT_DCS_CMD(0xE8, 0xFA), + + _INIT_SWITCH_PAGE_CMD(0x12), + _INIT_DCS_CMD(0x87, 0x2C), + + _INIT_SWITCH_PAGE_CMD(0x05), + _INIT_DCS_CMD(0x73, 0xE5), + _INIT_DCS_CMD(0x7F, 0x6B), + _INIT_DCS_CMD(0x6D, 0xA4), + _INIT_DCS_CMD(0x79, 0x54), + _INIT_DCS_CMD(0x69, 0x97), + _INIT_DCS_CMD(0x6A, 0x97), + _INIT_DCS_CMD(0xA5, 0x3F), + _INIT_DCS_CMD(0x61, 0xDA), + _INIT_DCS_CMD(0xA7, 0xF1), + _INIT_DCS_CMD(0x5F, 0x01), + _INIT_DCS_CMD(0x62, 0x3F), + _INIT_DCS_CMD(0x1D, 0x90), + _INIT_DCS_CMD(0x86, 0x87), + + _INIT_SWITCH_PAGE_CMD(0x06), + _INIT_DCS_CMD(0xC0, 0x80), + _INIT_DCS_CMD(0xC1, 0x07), + _INIT_DCS_CMD(0xCA, 0x58), + _INIT_DCS_CMD(0xCB, 0x02), + _INIT_DCS_CMD(0xCE, 0x58), + _INIT_DCS_CMD(0xCF, 0x02), + _INIT_DCS_CMD(0x67, 0x60), + _INIT_DCS_CMD(0x10, 0x00), + _INIT_DCS_CMD(0x92, 0x22), + _INIT_DCS_CMD(0xD3, 0x08), + _INIT_DCS_CMD(0xD6, 0x55), + _INIT_DCS_CMD(0xDC, 0x38), + + _INIT_SWITCH_PAGE_CMD(0x08), + _INIT_DCS_CMD(0xE0, 0x00, 0x10, 0x2A, 0x4D, 0x61, 0x56, 0x6A, 0x6E, 0x79, 0x76, 0x8F, 0x95, 0x98, 0xAE, 0xAA, 0xB2, 0xBB, 0xCE, 0xC6, 0xBD, 0xD5, 0xE2, 0xE8), + _INIT_DCS_CMD(0xE1, 0x00, 0x10, 0x2A, 0x4D, 0x61, 0x56, 0x6A, 0x6E, 0x79, 0x76, 0x8F, 0x95, 0x98, 0xAE, 0xAA, 0xB2, 0xBB, 0xCE, 0xC6, 0xBD, 0xD5, 0xE2, 0xE8), + + _INIT_SWITCH_PAGE_CMD(0x04), + _INIT_DCS_CMD(0xBA, 0x81), + + _INIT_SWITCH_PAGE_CMD(0x0C), + _INIT_DCS_CMD(0x00, 0x02), + _INIT_DCS_CMD(0x01, 0x00), + _INIT_DCS_CMD(0x02, 0x03), + _INIT_DCS_CMD(0x03, 0x01), + _INIT_DCS_CMD(0x04, 0x03), + _INIT_DCS_CMD(0x05, 0x02), + _INIT_DCS_CMD(0x06, 0x04), + _INIT_DCS_CMD(0x07, 0x03), + _INIT_DCS_CMD(0x08, 0x03), + _INIT_DCS_CMD(0x09, 0x04), + _INIT_DCS_CMD(0x0A, 0x04), + _INIT_DCS_CMD(0x0B, 0x05), + _INIT_DCS_CMD(0x0C, 0x04), + _INIT_DCS_CMD(0x0D, 0x06), + _INIT_DCS_CMD(0x0E, 0x05), + _INIT_DCS_CMD(0x0F, 0x07), + _INIT_DCS_CMD(0x10, 0x04), + _INIT_DCS_CMD(0x11, 0x08), + _INIT_DCS_CMD(0x12, 0x05), + _INIT_DCS_CMD(0x13, 0x09), + _INIT_DCS_CMD(0x14, 0x05), + _INIT_DCS_CMD(0x15, 0x0A), + _INIT_DCS_CMD(0x16, 0x06), + _INIT_DCS_CMD(0x17, 0x0B), + _INIT_DCS_CMD(0x18, 0x05), + _INIT_DCS_CMD(0x19, 0x0C), + _INIT_DCS_CMD(0x1A, 0x06), + _INIT_DCS_CMD(0x1B, 0x0D), + _INIT_DCS_CMD(0x1C, 0x06), + _INIT_DCS_CMD(0x1D, 0x0E), + _INIT_DCS_CMD(0x1E, 0x07), + _INIT_DCS_CMD(0x1F, 0x0F), + _INIT_DCS_CMD(0x20, 0x06), + _INIT_DCS_CMD(0x21, 0x10), + _INIT_DCS_CMD(0x22, 0x07), + _INIT_DCS_CMD(0x23, 0x11), + _INIT_DCS_CMD(0x24, 0x07), + _INIT_DCS_CMD(0x25, 0x12), + _INIT_DCS_CMD(0x26, 0x08), + _INIT_DCS_CMD(0x27, 0x13), + _INIT_DCS_CMD(0x28, 0x07), + _INIT_DCS_CMD(0x29, 0x14), + _INIT_DCS_CMD(0x2A, 0x08), + _INIT_DCS_CMD(0x2B, 0x15), + _INIT_DCS_CMD(0x2C, 0x08), + _INIT_DCS_CMD(0x2D, 0x16), + _INIT_DCS_CMD(0x2E, 0x09), + _INIT_DCS_CMD(0x2F, 0x17), + _INIT_DCS_CMD(0x30, 0x08), + _INIT_DCS_CMD(0x31, 0x18), + _INIT_DCS_CMD(0x32, 0x09), + _INIT_DCS_CMD(0x33, 0x19), + _INIT_DCS_CMD(0x34, 0x09), + _INIT_DCS_CMD(0x35, 0x1A), + _INIT_DCS_CMD(0x36, 0x0A), + _INIT_DCS_CMD(0x37, 0x1B), + _INIT_DCS_CMD(0x38, 0x0A), + _INIT_DCS_CMD(0x39, 0x1C), + _INIT_DCS_CMD(0x3A, 0x0A), + _INIT_DCS_CMD(0x3B, 0x1D), + _INIT_DCS_CMD(0x3C, 0x0A), + _INIT_DCS_CMD(0x3D, 0x1E), + _INIT_DCS_CMD(0x3E, 0x0A), + _INIT_DCS_CMD(0x3F, 0x1F), + + _INIT_SWITCH_PAGE_CMD(0x04), + _INIT_DCS_CMD(0xBA, 0x01), + + _INIT_SWITCH_PAGE_CMD(0x0E), + _INIT_DCS_CMD(0x02, 0x0C), + _INIT_DCS_CMD(0x20, 0x10), + _INIT_DCS_CMD(0x25, 0x16), + _INIT_DCS_CMD(0x26, 0xE0), + _INIT_DCS_CMD(0x27, 0x00), + _INIT_DCS_CMD(0x29, 0x71), + _INIT_DCS_CMD(0x2A, 0x46), + _INIT_DCS_CMD(0x2B, 0x1F), + _INIT_DCS_CMD(0x2D, 0xC7), + _INIT_DCS_CMD(0x31, 0x02), + _INIT_DCS_CMD(0x32, 0xDF), + _INIT_DCS_CMD(0x33, 0x5A), + _INIT_DCS_CMD(0x34, 0xC0), + _INIT_DCS_CMD(0x35, 0x5A), + _INIT_DCS_CMD(0x36, 0xC0), + _INIT_DCS_CMD(0x38, 0x65), + _INIT_DCS_CMD(0x80, 0x3E), + _INIT_DCS_CMD(0x81, 0xA0), + _INIT_DCS_CMD(0xB0, 0x01), + _INIT_DCS_CMD(0xB1, 0xCC), + _INIT_DCS_CMD(0xC0, 0x12), + _INIT_DCS_CMD(0xC2, 0xCC), + _INIT_DCS_CMD(0xC3, 0xCC), + _INIT_DCS_CMD(0xC4, 0xCC), + _INIT_DCS_CMD(0xC5, 0xCC), + _INIT_DCS_CMD(0xC6, 0xCC), + _INIT_DCS_CMD(0xC7, 0xCC), + _INIT_DCS_CMD(0xC8, 0xCC), + _INIT_DCS_CMD(0xC9, 0xCC), + _INIT_DCS_CMD(0x30, 0x00), + _INIT_DCS_CMD(0x00, 0x81), + _INIT_DCS_CMD(0x08, 0x02), + _INIT_DCS_CMD(0x09, 0x00), + _INIT_DCS_CMD(0x07, 0x21), + _INIT_DCS_CMD(0x04, 0x10), + + _INIT_SWITCH_PAGE_CMD(0x1E), + _INIT_DCS_CMD(0x60, 0x00), + _INIT_DCS_CMD(0x64, 0x00), + _INIT_DCS_CMD(0x6D, 0x00), + + _INIT_SWITCH_PAGE_CMD(0x0B), + _INIT_DCS_CMD(0xA6, 0x44), + _INIT_DCS_CMD(0xA7, 0xB6), + _INIT_DCS_CMD(0xA8, 0x03), + _INIT_DCS_CMD(0xA9, 0x03), + _INIT_DCS_CMD(0xAA, 0x51), + _INIT_DCS_CMD(0xAB, 0x51), + _INIT_DCS_CMD(0xAC, 0x04), + _INIT_DCS_CMD(0xBD, 0x92), + _INIT_DCS_CMD(0xBE, 0xA1), + + _INIT_SWITCH_PAGE_CMD(0x05), + _INIT_DCS_CMD(0x86, 0x87), + + _INIT_SWITCH_PAGE_CMD(0x06), + _INIT_DCS_CMD(0x92, 0x22), + + _INIT_SWITCH_PAGE_CMD(0x00), + _INIT_DCS_CMD(MIPI_DCS_EXIT_SLEEP_MODE), + _INIT_DELAY_CMD(120), + _INIT_DCS_CMD(MIPI_DCS_SET_DISPLAY_ON), + _INIT_DELAY_CMD(20), + {}, +}; + +static inline struct ili9882t *to_ili9882t(struct drm_panel *panel) +{ + return container_of(panel, struct ili9882t, base); +} + +static int ili9882t_init_dcs_cmd(struct ili9882t *ili) +{ + struct mipi_dsi_device *dsi = ili->dsi; + struct drm_panel *panel = &ili->base; + int i, err = 0; + + if (ili->desc->init_cmds) { + const struct panel_init_cmd *init_cmds = ili->desc->init_cmds; + + for (i = 0; init_cmds[i].len != 0; i++) { + const struct panel_init_cmd *cmd = &init_cmds[i]; + + switch (cmd->type) { + case DELAY_CMD: + msleep(cmd->data[0]); + err = 0; + break; + + case INIT_DCS_CMD: + err = mipi_dsi_dcs_write(dsi, cmd->data[0], + cmd->len <= 1 ? NULL : + &cmd->data[1], + cmd->len - 1); + break; + + default: + err = -EINVAL; + } + + if (err < 0) { + dev_err(panel->dev, + "failed to write command %u\n", i); + return err; + } + } + } + return 0; +} + +static int ili9882t_switch_page(struct mipi_dsi_device *dsi, u8 page) +{ + int ret; + const struct panel_init_cmd cmd = _INIT_SWITCH_PAGE_CMD(page); + + ret = mipi_dsi_dcs_write(dsi, cmd.data[0], + cmd.len <= 1 ? NULL : + &cmd.data[1], + cmd.len - 1); + if (ret) { + dev_err(&dsi->dev, + "error switching panel controller page (%d)\n", ret); + return ret; + } + + return 0; +} + +static int ili9882t_enter_sleep_mode(struct ili9882t *ili) +{ + struct mipi_dsi_device *dsi = ili->dsi; + int ret; + + dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; + + ret = mipi_dsi_dcs_set_display_off(dsi); + if (ret < 0) + return ret; + + ret = mipi_dsi_dcs_enter_sleep_mode(dsi); + if (ret < 0) + return ret; + + return 0; +} + +static int ili9882t_disable(struct drm_panel *panel) +{ + struct ili9882t *ili = to_ili9882t(panel); + struct mipi_dsi_device *dsi = ili->dsi; + int ret; + + ili9882t_switch_page(dsi, 0x00); + ret = ili9882t_enter_sleep_mode(ili); + if (ret < 0) { + dev_err(panel->dev, "failed to set panel off: %d\n", ret); + return ret; + } + + msleep(150); + + return 0; +} + +static int ili9882t_unprepare(struct drm_panel *panel) +{ + struct ili9882t *ili = to_ili9882t(panel); + + gpiod_set_value(ili->enable_gpio, 0); + usleep_range(1000, 2000); + regulator_disable(ili->avee); + regulator_disable(ili->avdd); + usleep_range(5000, 7000); + regulator_disable(ili->pp1800); + regulator_disable(ili->pp3300); + + return 0; +} + +static int ili9882t_prepare(struct drm_panel *panel) +{ + struct ili9882t *ili = to_ili9882t(panel); + int ret; + + gpiod_set_value(ili->enable_gpio, 0); + usleep_range(1000, 1500); + + ret = regulator_enable(ili->pp3300); + if (ret < 0) + return ret; + + ret = regulator_enable(ili->pp1800); + if (ret < 0) + return ret; + + usleep_range(3000, 5000); + + ret = regulator_enable(ili->avdd); + if (ret < 0) + goto poweroff1v8; + ret = regulator_enable(ili->avee); + if (ret < 0) + goto poweroffavdd; + + usleep_range(10000, 11000); + + // MIPI needs to keep the LP11 state before the lcm_reset pin is pulled high + mipi_dsi_dcs_nop(ili->dsi); + usleep_range(1000, 2000); + + gpiod_set_value(ili->enable_gpio, 1); + usleep_range(1000, 2000); + gpiod_set_value(ili->enable_gpio, 0); + msleep(50); + gpiod_set_value(ili->enable_gpio, 1); + usleep_range(6000, 10000); + + ret = ili9882t_init_dcs_cmd(ili); + if (ret < 0) { + dev_err(panel->dev, "failed to init panel: %d\n", ret); + goto poweroff; + } + + return 0; + +poweroff: + regulator_disable(ili->avee); +poweroffavdd: + regulator_disable(ili->avdd); +poweroff1v8: + usleep_range(5000, 7000); + regulator_disable(ili->pp1800); + gpiod_set_value(ili->enable_gpio, 0); + + return ret; +} + +static int ili9882t_enable(struct drm_panel *panel) +{ + msleep(130); + return 0; +} + +static const struct drm_display_mode starry_ili9882t_default_mode = { + .clock = 165280, + .hdisplay = 1200, + .hsync_start = 1200 + 72, + .hsync_end = 1200 + 72 + 30, + .htotal = 1200 + 72 + 30 + 72, + .vdisplay = 1920, + .vsync_start = 1920 + 68, + .vsync_end = 1920 + 68 + 2, + .vtotal = 1920 + 68 + 2 + 10, + .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, +}; + +static const struct panel_desc starry_ili9882t_desc = { + .modes = &starry_ili9882t_default_mode, + .bpc = 8, + .size = { + .width_mm = 141, + .height_mm = 226, + }, + .lanes = 4, + .format = MIPI_DSI_FMT_RGB888, + .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE | + MIPI_DSI_MODE_LPM, + .init_cmds = starry_ili9882t_init_cmd, +}; + +static int ili9882t_get_modes(struct drm_panel *panel, + struct drm_connector *connector) +{ + struct ili9882t *ili = to_ili9882t(panel); + const struct drm_display_mode *m = ili->desc->modes; + struct drm_display_mode *mode; + + mode = drm_mode_duplicate(connector->dev, m); + if (!mode) { + dev_err(panel->dev, "failed to add mode %ux%u@%u\n", + m->hdisplay, m->vdisplay, drm_mode_vrefresh(m)); + return -ENOMEM; + } + + mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; + drm_mode_set_name(mode); + drm_mode_probed_add(connector, mode); + + connector->display_info.width_mm = ili->desc->size.width_mm; + connector->display_info.height_mm = ili->desc->size.height_mm; + connector->display_info.bpc = ili->desc->bpc; + + return 1; +} + +static enum drm_panel_orientation ili9882t_get_orientation(struct drm_panel *panel) +{ + struct ili9882t *ili = to_ili9882t(panel); + + return ili->orientation; +} + +static const struct drm_panel_funcs ili9882t_funcs = { + .disable = ili9882t_disable, + .unprepare = ili9882t_unprepare, + .prepare = ili9882t_prepare, + .enable = ili9882t_enable, + .get_modes = ili9882t_get_modes, + .get_orientation = ili9882t_get_orientation, +}; + +static int ili9882t_add(struct ili9882t *ili) +{ + struct device *dev = &ili->dsi->dev; + int err; + + ili->avdd = devm_regulator_get(dev, "avdd"); + if (IS_ERR(ili->avdd)) + return PTR_ERR(ili->avdd); + + ili->avee = devm_regulator_get(dev, "avee"); + if (IS_ERR(ili->avee)) + return PTR_ERR(ili->avee); + + ili->pp3300 = devm_regulator_get(dev, "pp3300"); + if (IS_ERR(ili->pp3300)) + return PTR_ERR(ili->pp3300); + + ili->pp1800 = devm_regulator_get(dev, "pp1800"); + if (IS_ERR(ili->pp1800)) + return PTR_ERR(ili->pp1800); + + ili->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW); + if (IS_ERR(ili->enable_gpio)) { + dev_err(dev, "cannot get reset-gpios %ld\n", + PTR_ERR(ili->enable_gpio)); + return PTR_ERR(ili->enable_gpio); + } + + gpiod_set_value(ili->enable_gpio, 0); + + drm_panel_init(&ili->base, dev, &ili9882t_funcs, + DRM_MODE_CONNECTOR_DSI); + err = of_drm_get_panel_orientation(dev->of_node, &ili->orientation); + if (err < 0) { + dev_err(dev, "%pOF: failed to get orientation %d\n", dev->of_node, err); + return err; + } + + err = drm_panel_of_backlight(&ili->base); + if (err) + return err; + + ili->base.funcs = &ili9882t_funcs; + ili->base.dev = &ili->dsi->dev; + + drm_panel_add(&ili->base); + + return 0; +} + +static int ili9882t_probe(struct mipi_dsi_device *dsi) +{ + struct ili9882t *ili; + int ret; + const struct panel_desc *desc; + + ili = devm_kzalloc(&dsi->dev, sizeof(*ili), GFP_KERNEL); + if (!ili) + return -ENOMEM; + + desc = of_device_get_match_data(&dsi->dev); + dsi->lanes = desc->lanes; + dsi->format = desc->format; + dsi->mode_flags = desc->mode_flags; + ili->desc = desc; + ili->dsi = dsi; + ret = ili9882t_add(ili); + if (ret < 0) + return ret; + + mipi_dsi_set_drvdata(dsi, ili); + + ret = mipi_dsi_attach(dsi); + if (ret) + drm_panel_remove(&ili->base); + + return ret; +} + +static void ili9882t_remove(struct mipi_dsi_device *dsi) +{ + struct ili9882t *ili = mipi_dsi_get_drvdata(dsi); + int ret; + + ret = mipi_dsi_detach(dsi); + if (ret < 0) + dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", ret); + + if (ili->base.dev) + drm_panel_remove(&ili->base); +} + +static const struct of_device_id ili9882t_of_match[] = { + { .compatible = "starry,ili9882t", + .data = &starry_ili9882t_desc + }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, ili9882t_of_match); + +static struct mipi_dsi_driver ili9882t_driver = { + .driver = { + .name = "panel-ili9882t", + .of_match_table = ili9882t_of_match, + }, + .probe = ili9882t_probe, + .remove = ili9882t_remove, +}; +module_mipi_dsi_driver(ili9882t_driver); + +MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>"); +MODULE_DESCRIPTION("Ilitek ILI9882T-based panels driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/panel/panel-sitronix-st7703.c b/drivers/gpu/drm/panel/panel-sitronix-st7703.c index 6a3945639535..b55bafd1a8be 100644 --- a/drivers/gpu/drm/panel/panel-sitronix-st7703.c +++ b/drivers/gpu/drm/panel/panel-sitronix-st7703.c @@ -130,6 +130,7 @@ static int jh057n_init_sequence(struct st7703 *ctx) 0x18, 0x00, 0x09, 0x0E, 0x29, 0x2D, 0x3C, 0x41, 0x37, 0x07, 0x0B, 0x0D, 0x10, 0x11, 0x0F, 0x10, 0x11, 0x18); + msleep(20); return 0; } @@ -276,7 +277,6 @@ static int xbd599_init_sequence(struct st7703 *ctx) mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETBGP, 0x07, /* VREF_SEL = 4.2V */ 0x07 /* NVREF_SEL = 4.2V */); - msleep(20); mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETVCOM, 0x2C, /* VCOMDC_F = -0.67V */ @@ -433,6 +433,94 @@ static const struct st7703_panel_desc rg353v2_desc = { .init_sequence = rg353v2_init_sequence, }; +static int rgb30panel_init_sequence(struct st7703 *ctx) +{ + struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); + + /* Init sequence extracted from Powkiddy RGB30 BSP kernel. */ + + /* + * For some reason this specific panel must be taken out of sleep + * before the full init sequence, or else it will not display. + */ + mipi_dsi_dcs_exit_sleep_mode(dsi); + msleep(250); + + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETEXTC, 0xf1, 0x12, 0x83); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETMIPI, 0x33, 0x81, 0x05, 0xf9, + 0x0e, 0x0e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x44, 0x25, 0x00, 0x90, 0x0a, 0x00, + 0x00, 0x01, 0x4f, 0x01, 0x00, 0x00, 0x37); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETPOWER_EXT, 0x25, 0x22, 0xf0, + 0x63); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_UNKNOWN_BF, 0x02, 0x11, 0x00); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETRGBIF, 0x10, 0x10, 0x28, + 0x28, 0x03, 0xff, 0x00, 0x00, 0x00, 0x00); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETSCR, 0x73, 0x73, 0x50, 0x50, + 0x00, 0x00, 0x12, 0x70, 0x00); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETVDC, 0x46); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETPANEL, 0x0b); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETCYC, 0x80); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETDISP, 0x3c, 0x12, 0x30); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETEQ, 0x07, 0x07, 0x0b, 0x0b, + 0x03, 0x0b, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, + 0xc0, 0x10); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETPOWER, 0x36, 0x00, 0x32, + 0x32, 0x77, 0xf1, 0xcc, 0xcc, 0x77, 0x77, 0x33, + 0x33); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETBGP, 0x0a, 0x0a); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETVCOM, 0x88, 0x88); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETGIP1, 0xc8, 0x10, 0x0a, 0x10, + 0x0f, 0xa1, 0x80, 0x12, 0x31, 0x23, 0x47, 0x86, + 0xa1, 0x80, 0x47, 0x08, 0x00, 0x00, 0x0d, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x48, 0x02, 0x8b, 0xaf, 0x46, 0x02, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x48, 0x13, 0x8b, 0xaf, 0x57, + 0x13, 0x88, 0x88, 0x88, 0x88, 0x88, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETGIP2, 0x96, 0x12, 0x01, 0x01, + 0x01, 0x78, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x4f, 0x31, 0x8b, 0xa8, 0x31, 0x75, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x4f, 0x20, 0x8b, 0xa8, 0x20, + 0x64, 0x88, 0x88, 0x88, 0x88, 0x88, 0x23, 0x00, + 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x40, 0xa1, 0x80, 0x00, 0x00, 0x00, + 0x00); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETGAMMA, 0x00, 0x0a, 0x0f, + 0x29, 0x3b, 0x3f, 0x42, 0x39, 0x06, 0x0d, 0x10, + 0x13, 0x15, 0x14, 0x15, 0x10, 0x17, 0x00, 0x0a, + 0x0f, 0x29, 0x3b, 0x3f, 0x42, 0x39, 0x06, 0x0d, + 0x10, 0x13, 0x15, 0x14, 0x15, 0x10, 0x17); + + return 0; +} + +static const struct drm_display_mode rgb30panel_mode = { + .hdisplay = 720, + .hsync_start = 720 + 45, + .hsync_end = 720 + 45 + 4, + .htotal = 720 + 45 + 4 + 45, + .vdisplay = 720, + .vsync_start = 720 + 15, + .vsync_end = 720 + 15 + 3, + .vtotal = 720 + 15 + 3 + 11, + .clock = 36570, + .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, + .width_mm = 76, + .height_mm = 76, +}; + +static const struct st7703_panel_desc rgb30panel_desc = { + .mode = &rgb30panel_mode, + .lanes = 4, + .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | + MIPI_DSI_MODE_NO_EOT_PACKET | MIPI_DSI_MODE_LPM, + .format = MIPI_DSI_FMT_RGB888, + .init_sequence = rgb30panel_init_sequence, +}; + static int st7703_enable(struct drm_panel *panel) { struct st7703 *ctx = panel_to_st7703(panel); @@ -445,16 +533,14 @@ static int st7703_enable(struct drm_panel *panel) return ret; } - msleep(20); - ret = mipi_dsi_dcs_exit_sleep_mode(dsi); if (ret < 0) { dev_err(ctx->dev, "Failed to exit sleep mode: %d\n", ret); return ret; } - /* Panel is operational 120 msec after reset */ - msleep(60); + /* It takes the controller 120 msec to wake up after sleep. */ + msleep(120); ret = mipi_dsi_dcs_set_display_on(dsi); if (ret) @@ -479,6 +565,9 @@ static int st7703_disable(struct drm_panel *panel) if (ret < 0) dev_err(ctx->dev, "Failed to enter sleep mode: %d\n", ret); + /* It takes the controller 120 msec to enter sleep mode. */ + msleep(120); + return 0; } @@ -506,29 +595,30 @@ static int st7703_prepare(struct drm_panel *panel) return 0; dev_dbg(ctx->dev, "Resetting the panel\n"); - ret = regulator_enable(ctx->vcc); + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + + ret = regulator_enable(ctx->iovcc); if (ret < 0) { - dev_err(ctx->dev, "Failed to enable vcc supply: %d\n", ret); + dev_err(ctx->dev, "Failed to enable iovcc supply: %d\n", ret); return ret; } - ret = regulator_enable(ctx->iovcc); + + ret = regulator_enable(ctx->vcc); if (ret < 0) { - dev_err(ctx->dev, "Failed to enable iovcc supply: %d\n", ret); - goto disable_vcc; + dev_err(ctx->dev, "Failed to enable vcc supply: %d\n", ret); + regulator_disable(ctx->iovcc); + return ret; } - gpiod_set_value_cansleep(ctx->reset_gpio, 1); - usleep_range(20, 40); + /* Give power supplies time to stabilize before deasserting reset. */ + usleep_range(10000, 20000); + gpiod_set_value_cansleep(ctx->reset_gpio, 0); - msleep(20); + usleep_range(15000, 20000); ctx->prepared = true; return 0; - -disable_vcc: - regulator_disable(ctx->vcc); - return ret; } static const u32 mantix_bus_formats[] = { @@ -694,6 +784,7 @@ static void st7703_remove(struct mipi_dsi_device *dsi) static const struct of_device_id st7703_of_match[] = { { .compatible = "anbernic,rg353v-panel-v2", .data = &rg353v2_desc }, + { .compatible = "powkiddy,rgb30-panel", .data = &rgb30panel_desc }, { .compatible = "rocktech,jh057n00900", .data = &jh057n00900_panel_desc }, { .compatible = "xingbangda,xbd599", .data = &xbd599_desc }, { /* sentinel */ } diff --git a/drivers/gpu/drm/panfrost/panfrost_job.c b/drivers/gpu/drm/panfrost/panfrost_job.c index fb16de2d0420..ecd2e035147f 100644 --- a/drivers/gpu/drm/panfrost/panfrost_job.c +++ b/drivers/gpu/drm/panfrost/panfrost_job.c @@ -853,6 +853,7 @@ int panfrost_job_init(struct panfrost_device *pfdev) ret = drm_sched_init(&js->queue[j].sched, &panfrost_sched_ops, + DRM_SCHED_PRIORITY_COUNT, nentries, 0, msecs_to_jiffies(JOB_TIMEOUT_MS), pfdev->reset.wq, diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c index b8f8b45ebf59..93ed841f5dce 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c @@ -40,7 +40,7 @@ static int rockchip_gem_iommu_map(struct rockchip_gem_object *rk_obj) ret = iommu_map_sgtable(private->domain, rk_obj->dma_addr, rk_obj->sgt, prot); - if (ret < rk_obj->base.size) { + if (ret < (ssize_t)rk_obj->base.size) { DRM_ERROR("failed to map buffer: size=%zd request_size=%zd\n", ret, rk_obj->base.size); ret = -ENOMEM; diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index e1ea50c8fd39..066299894d04 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -272,6 +272,18 @@ static bool has_uv_swapped(uint32_t format) } } +static bool is_fmt_10(uint32_t format) +{ + switch (format) { + case DRM_FORMAT_NV15: + case DRM_FORMAT_NV20: + case DRM_FORMAT_NV30: + return true; + default: + return false; + } +} + static enum vop_data_format vop_convert_format(uint32_t format) { switch (format) { @@ -287,12 +299,15 @@ static enum vop_data_format vop_convert_format(uint32_t format) case DRM_FORMAT_BGR565: return VOP_FMT_RGB565; case DRM_FORMAT_NV12: + case DRM_FORMAT_NV15: case DRM_FORMAT_NV21: return VOP_FMT_YUV420SP; case DRM_FORMAT_NV16: + case DRM_FORMAT_NV20: case DRM_FORMAT_NV61: return VOP_FMT_YUV422SP; case DRM_FORMAT_NV24: + case DRM_FORMAT_NV30: case DRM_FORMAT_NV42: return VOP_FMT_YUV444SP; default: @@ -939,7 +954,12 @@ static void vop_plane_atomic_update(struct drm_plane *plane, dsp_sty = dest->y1 + crtc->mode.vtotal - crtc->mode.vsync_start; dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff); - offset = (src->x1 >> 16) * fb->format->cpp[0]; + if (fb->format->char_per_block[0]) + offset = drm_format_info_min_pitch(fb->format, 0, + src->x1 >> 16); + else + offset = (src->x1 >> 16) * fb->format->cpp[0]; + offset += (src->y1 >> 16) * fb->pitches[0]; dma_addr = rk_obj->dma_addr + offset + fb->offsets[0]; @@ -965,6 +985,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane, } VOP_WIN_SET(vop, win, format, format); + VOP_WIN_SET(vop, win, fmt_10, is_fmt_10(fb->format->format)); VOP_WIN_SET(vop, win, yrgb_vir, DIV_ROUND_UP(fb->pitches[0], 4)); VOP_WIN_SET(vop, win, yrgb_mst, dma_addr); VOP_WIN_YUV2YUV_SET(vop, win_yuv2yuv, y2r_en, is_yuv); @@ -974,15 +995,16 @@ static void vop_plane_atomic_update(struct drm_plane *plane, (new_state->rotation & DRM_MODE_REFLECT_X) ? 1 : 0); if (is_yuv) { - int hsub = fb->format->hsub; - int vsub = fb->format->vsub; - int bpp = fb->format->cpp[1]; - uv_obj = fb->obj[1]; rk_uv_obj = to_rockchip_obj(uv_obj); - offset = (src->x1 >> 16) * bpp / hsub; - offset += (src->y1 >> 16) * fb->pitches[1] / vsub; + if (fb->format->char_per_block[1]) + offset = drm_format_info_min_pitch(fb->format, 1, + src->x1 >> 16); + else + offset = (src->x1 >> 16) * fb->format->cpp[1]; + offset /= fb->format->hsub; + offset += (src->y1 >> 16) * fb->pitches[1] / fb->format->vsub; dma_addr = rk_uv_obj->dma_addr + offset + fb->offsets[1]; VOP_WIN_SET(vop, win, uv_vir, DIV_ROUND_UP(fb->pitches[1], 4)); diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h index 5f56e0597df8..4b2daefeb8c1 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h @@ -186,6 +186,7 @@ struct vop_win_phy { struct vop_reg enable; struct vop_reg gate; struct vop_reg format; + struct vop_reg fmt_10; struct vop_reg rb_swap; struct vop_reg uv_swap; struct vop_reg act_info; diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index ec7e0e6149af..6862fb146ace 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -160,7 +160,6 @@ struct vop2_video_port { struct vop2 *vop2; struct clk *dclk; unsigned int id; - const struct vop2_video_port_regs *regs; const struct vop2_video_port_data *data; struct completion dsp_hold_completion; @@ -283,9 +282,28 @@ static void vop2_win_disable(struct vop2_win *win) vop2_win_write(win, VOP2_WIN_CLUSTER_ENABLE, 0); } +static u32 vop2_get_bpp(const struct drm_format_info *format) +{ + switch (format->format) { + case DRM_FORMAT_YUV420_8BIT: + return 12; + case DRM_FORMAT_YUV420_10BIT: + return 15; + case DRM_FORMAT_VUY101010: + return 30; + default: + return drm_format_info_bpp(format, 0); + } +} + static enum vop2_data_format vop2_convert_format(u32 format) { switch (format) { + case DRM_FORMAT_XRGB2101010: + case DRM_FORMAT_ARGB2101010: + case DRM_FORMAT_XBGR2101010: + case DRM_FORMAT_ABGR2101010: + return VOP2_FMT_XRGB101010; case DRM_FORMAT_XRGB8888: case DRM_FORMAT_ARGB8888: case DRM_FORMAT_XBGR8888: @@ -298,10 +316,19 @@ static enum vop2_data_format vop2_convert_format(u32 format) case DRM_FORMAT_BGR565: return VOP2_FMT_RGB565; case DRM_FORMAT_NV12: + case DRM_FORMAT_NV21: + case DRM_FORMAT_YUV420_8BIT: return VOP2_FMT_YUV420SP; + case DRM_FORMAT_NV15: + case DRM_FORMAT_YUV420_10BIT: + return VOP2_FMT_YUV420SP_10; case DRM_FORMAT_NV16: + case DRM_FORMAT_NV61: return VOP2_FMT_YUV422SP; + case DRM_FORMAT_Y210: + return VOP2_FMT_YUV422SP_10; case DRM_FORMAT_NV24: + case DRM_FORMAT_NV42: return VOP2_FMT_YUV444SP; case DRM_FORMAT_YUYV: case DRM_FORMAT_YVYU: @@ -318,6 +345,11 @@ static enum vop2_data_format vop2_convert_format(u32 format) static enum vop2_afbc_format vop2_convert_afbc_format(u32 format) { switch (format) { + case DRM_FORMAT_XRGB2101010: + case DRM_FORMAT_ARGB2101010: + case DRM_FORMAT_XBGR2101010: + case DRM_FORMAT_ABGR2101010: + return VOP2_AFBC_FMT_ARGB2101010; case DRM_FORMAT_XRGB8888: case DRM_FORMAT_ARGB8888: case DRM_FORMAT_XBGR8888: @@ -329,10 +361,17 @@ static enum vop2_afbc_format vop2_convert_afbc_format(u32 format) case DRM_FORMAT_RGB565: case DRM_FORMAT_BGR565: return VOP2_AFBC_FMT_RGB565; - case DRM_FORMAT_NV12: + case DRM_FORMAT_YUV420_8BIT: return VOP2_AFBC_FMT_YUV420; - case DRM_FORMAT_NV16: + case DRM_FORMAT_YUV420_10BIT: + return VOP2_AFBC_FMT_YUV420_10BIT; + case DRM_FORMAT_YVYU: + case DRM_FORMAT_YUYV: + case DRM_FORMAT_VYUY: + case DRM_FORMAT_UYVY: return VOP2_AFBC_FMT_YUV422; + case DRM_FORMAT_Y210: + return VOP2_AFBC_FMT_YUV422_10BIT; default: return VOP2_AFBC_FMT_INVALID; } @@ -343,6 +382,8 @@ static enum vop2_afbc_format vop2_convert_afbc_format(u32 format) static bool vop2_win_rb_swap(u32 format) { switch (format) { + case DRM_FORMAT_XBGR2101010: + case DRM_FORMAT_ABGR2101010: case DRM_FORMAT_XBGR8888: case DRM_FORMAT_ABGR8888: case DRM_FORMAT_BGR888: @@ -353,21 +394,13 @@ static bool vop2_win_rb_swap(u32 format) } } -static bool vop2_afbc_rb_swap(u32 format) -{ - switch (format) { - case DRM_FORMAT_NV24: - return true; - default: - return false; - } -} - static bool vop2_afbc_uv_swap(u32 format) { switch (format) { - case DRM_FORMAT_NV12: - case DRM_FORMAT_NV16: + case DRM_FORMAT_YUYV: + case DRM_FORMAT_Y210: + case DRM_FORMAT_YUV420_8BIT: + case DRM_FORMAT_YUV420_10BIT: return true; default: return false; @@ -380,6 +413,9 @@ static bool vop2_win_uv_swap(u32 format) case DRM_FORMAT_NV12: case DRM_FORMAT_NV16: case DRM_FORMAT_NV24: + case DRM_FORMAT_NV15: + case DRM_FORMAT_YUYV: + case DRM_FORMAT_UYVY: return true; default: return false; @@ -483,7 +519,7 @@ static u32 vop2_afbc_transform_offset(struct drm_plane_state *pstate, { struct drm_rect *src = &pstate->src; struct drm_framebuffer *fb = pstate->fb; - u32 bpp = fb->format->cpp[0] * 8; + u32 bpp = vop2_get_bpp(fb->format); u32 vir_width = (fb->pitches[0] << 3) / bpp; u32 width = drm_rect_width(src) >> 16; u32 height = drm_rect_height(src) >> 16; @@ -1081,7 +1117,7 @@ static void vop2_plane_atomic_update(struct drm_plane *plane, struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode; struct vop2 *vop2 = win->vop2; struct drm_framebuffer *fb = pstate->fb; - u32 bpp = fb->format->cpp[0] * 8; + u32 bpp = vop2_get_bpp(fb->format); u32 actual_w, actual_h, dsp_w, dsp_h; u32 act_info, dsp_info; u32 format; @@ -1219,7 +1255,6 @@ static void vop2_plane_atomic_update(struct drm_plane *plane, drm_err(vop2->drm, "vp%d %s stride[%d] not 64 pixel aligned\n", vp->id, win->data->name, stride); - rb_swap = vop2_afbc_rb_swap(fb->format->format); uv_swap = vop2_afbc_uv_swap(fb->format->format); /* * This is a workaround for crazy IC design, Cluster @@ -1236,7 +1271,6 @@ static void vop2_plane_atomic_update(struct drm_plane *plane, if (vop2_cluster_window(win)) vop2_win_write(win, VOP2_WIN_AFBC_ENABLE, 1); vop2_win_write(win, VOP2_WIN_AFBC_FORMAT, afbc_format); - vop2_win_write(win, VOP2_WIN_AFBC_RB_SWAP, rb_swap); vop2_win_write(win, VOP2_WIN_AFBC_UV_SWAP, uv_swap); vop2_win_write(win, VOP2_WIN_AFBC_AUTO_GATING_EN, 0); vop2_win_write(win, VOP2_WIN_AFBC_BLOCK_SPLIT_EN, 0); @@ -2251,8 +2285,6 @@ static struct vop2_video_port *find_vp_without_primary(struct vop2 *vop2) return NULL; } -#define NR_LAYERS 6 - static int vop2_create_crtcs(struct vop2 *vop2) { const struct vop2_data *vop2_data = vop2->data; @@ -2273,7 +2305,6 @@ static int vop2_create_crtcs(struct vop2 *vop2) vp = &vop2->vps[i]; vp->vop2 = vop2; vp->id = vp_data->id; - vp->regs = vp_data->regs; vp->data = vp_data; snprintf(dclk_name, sizeof(dclk_name), "dclk_vp%d", vp->id); @@ -2372,7 +2403,7 @@ static int vop2_create_crtcs(struct vop2 *vop2) struct vop2_video_port *vp = &vop2->vps[i]; if (vp->crtc.port) - vp->nlayers = NR_LAYERS / nvps; + vp->nlayers = vop2_data->win_size / nvps; } return 0; diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h index f1234a151130..56fd31e05238 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h @@ -134,16 +134,13 @@ struct vop2_video_port_data { u16 cubic_lut_len; struct vop_rect max_output; const u8 pre_scan_max_dly[4]; - const struct vop2_video_port_regs *regs; unsigned int offset; }; struct vop2_data { u8 nr_vps; - const struct vop2_ctrl *ctrl; const struct vop2_win_data *win; const struct vop2_video_port_data *vp; - const struct vop_csc_table *csc_table; struct vop_rect max_input; struct vop_rect max_output; diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c index fcd4cf3072cd..22288ad7f326 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c @@ -15,7 +15,11 @@ #include "rockchip_drm_vop2.h" -static const uint32_t formats_win_full_10bit[] = { +static const uint32_t formats_cluster[] = { + DRM_FORMAT_XRGB2101010, + DRM_FORMAT_ARGB2101010, + DRM_FORMAT_XBGR2101010, + DRM_FORMAT_ABGR2101010, DRM_FORMAT_XRGB8888, DRM_FORMAT_ARGB8888, DRM_FORMAT_XBGR8888, @@ -24,12 +28,13 @@ static const uint32_t formats_win_full_10bit[] = { DRM_FORMAT_BGR888, DRM_FORMAT_RGB565, DRM_FORMAT_BGR565, - DRM_FORMAT_NV12, - DRM_FORMAT_NV16, - DRM_FORMAT_NV24, + DRM_FORMAT_YUV420_8BIT, /* yuv420_8bit non-Linear mode only */ + DRM_FORMAT_YUV420_10BIT, /* yuv420_10bit non-Linear mode only */ + DRM_FORMAT_YUYV, /* yuv422_8bit non-Linear mode only*/ + DRM_FORMAT_Y210, /* yuv422_10bit non-Linear mode only */ }; -static const uint32_t formats_win_full_10bit_yuyv[] = { +static const uint32_t formats_rk356x_esmart[] = { DRM_FORMAT_XRGB8888, DRM_FORMAT_ARGB8888, DRM_FORMAT_XBGR8888, @@ -38,14 +43,18 @@ static const uint32_t formats_win_full_10bit_yuyv[] = { DRM_FORMAT_BGR888, DRM_FORMAT_RGB565, DRM_FORMAT_BGR565, - DRM_FORMAT_NV12, - DRM_FORMAT_NV16, - DRM_FORMAT_NV24, - DRM_FORMAT_YVYU, - DRM_FORMAT_VYUY, + DRM_FORMAT_NV12, /* yuv420_8bit linear mode, 2 plane */ + DRM_FORMAT_NV21, /* yuv420_8bit linear mode, 2 plane */ + DRM_FORMAT_NV15, /* yuv420_10bit linear mode, 2 plane, no padding */ + DRM_FORMAT_NV16, /* yuv422_8bit linear mode, 2 plane */ + DRM_FORMAT_NV61, /* yuv422_8bit linear mode, 2 plane */ + DRM_FORMAT_NV24, /* yuv444_8bit linear mode, 2 plane */ + DRM_FORMAT_NV42, /* yuv444_8bit linear mode, 2 plane */ + DRM_FORMAT_YVYU, /* yuv422_8bit[YVYU] linear mode */ + DRM_FORMAT_VYUY, /* yuv422_8bit[VYUY] linear mode */ }; -static const uint32_t formats_win_lite[] = { +static const uint32_t formats_smart[] = { DRM_FORMAT_XRGB8888, DRM_FORMAT_ARGB8888, DRM_FORMAT_XBGR8888, @@ -144,8 +153,8 @@ static const struct vop2_win_data rk3568_vop_win_data[] = { .name = "Smart0-win0", .phys_id = ROCKCHIP_VOP2_SMART0, .base = 0x1c00, - .formats = formats_win_lite, - .nformats = ARRAY_SIZE(formats_win_lite), + .formats = formats_smart, + .nformats = ARRAY_SIZE(formats_smart), .format_modifiers = format_modifiers, .layer_sel_id = 3, .supported_rotations = DRM_MODE_REFLECT_Y, @@ -156,8 +165,8 @@ static const struct vop2_win_data rk3568_vop_win_data[] = { }, { .name = "Smart1-win0", .phys_id = ROCKCHIP_VOP2_SMART1, - .formats = formats_win_lite, - .nformats = ARRAY_SIZE(formats_win_lite), + .formats = formats_smart, + .nformats = ARRAY_SIZE(formats_smart), .format_modifiers = format_modifiers, .base = 0x1e00, .layer_sel_id = 7, @@ -169,8 +178,8 @@ static const struct vop2_win_data rk3568_vop_win_data[] = { }, { .name = "Esmart1-win0", .phys_id = ROCKCHIP_VOP2_ESMART1, - .formats = formats_win_full_10bit_yuyv, - .nformats = ARRAY_SIZE(formats_win_full_10bit_yuyv), + .formats = formats_rk356x_esmart, + .nformats = ARRAY_SIZE(formats_rk356x_esmart), .format_modifiers = format_modifiers, .base = 0x1a00, .layer_sel_id = 6, @@ -182,8 +191,8 @@ static const struct vop2_win_data rk3568_vop_win_data[] = { }, { .name = "Esmart0-win0", .phys_id = ROCKCHIP_VOP2_ESMART0, - .formats = formats_win_full_10bit_yuyv, - .nformats = ARRAY_SIZE(formats_win_full_10bit_yuyv), + .formats = formats_rk356x_esmart, + .nformats = ARRAY_SIZE(formats_rk356x_esmart), .format_modifiers = format_modifiers, .base = 0x1800, .layer_sel_id = 2, @@ -196,8 +205,8 @@ static const struct vop2_win_data rk3568_vop_win_data[] = { .name = "Cluster0-win0", .phys_id = ROCKCHIP_VOP2_CLUSTER0, .base = 0x1000, - .formats = formats_win_full_10bit, - .nformats = ARRAY_SIZE(formats_win_full_10bit), + .formats = formats_cluster, + .nformats = ARRAY_SIZE(formats_cluster), .format_modifiers = format_modifiers_afbc, .layer_sel_id = 0, .supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 | @@ -211,8 +220,8 @@ static const struct vop2_win_data rk3568_vop_win_data[] = { .name = "Cluster1-win0", .phys_id = ROCKCHIP_VOP2_CLUSTER1, .base = 0x1200, - .formats = formats_win_full_10bit, - .nformats = ARRAY_SIZE(formats_win_full_10bit), + .formats = formats_cluster, + .nformats = ARRAY_SIZE(formats_cluster), .format_modifiers = format_modifiers_afbc, .layer_sel_id = 1, .supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 | diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c index d053ef027552..c51ca82320cb 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c @@ -53,6 +53,26 @@ static const uint32_t formats_win_full[] = { DRM_FORMAT_NV42, }; +static const uint32_t formats_win_full_10[] = { + DRM_FORMAT_XRGB8888, + DRM_FORMAT_ARGB8888, + DRM_FORMAT_XBGR8888, + DRM_FORMAT_ABGR8888, + DRM_FORMAT_RGB888, + DRM_FORMAT_BGR888, + DRM_FORMAT_RGB565, + DRM_FORMAT_BGR565, + DRM_FORMAT_NV12, + DRM_FORMAT_NV21, + DRM_FORMAT_NV16, + DRM_FORMAT_NV61, + DRM_FORMAT_NV24, + DRM_FORMAT_NV42, + DRM_FORMAT_NV15, + DRM_FORMAT_NV20, + DRM_FORMAT_NV30, +}; + static const uint64_t format_modifiers_win_full[] = { DRM_FORMAT_MOD_LINEAR, DRM_FORMAT_MOD_INVALID, @@ -627,11 +647,12 @@ static const struct vop_scl_regs rk3288_win_full_scl = { static const struct vop_win_phy rk3288_win01_data = { .scl = &rk3288_win_full_scl, - .data_formats = formats_win_full, - .nformats = ARRAY_SIZE(formats_win_full), + .data_formats = formats_win_full_10, + .nformats = ARRAY_SIZE(formats_win_full_10), .format_modifiers = format_modifiers_win_full, .enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0), .format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1), + .fmt_10 = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 4), .rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12), .uv_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 15), .act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0), @@ -936,13 +957,38 @@ static const struct vop_win_yuv2yuv_data rk3399_vop_big_win_yuv2yuv_data[] = { }; -static const struct vop_win_phy rk3399_win01_data = { +static const struct vop_win_phy rk3399_win0_data = { .scl = &rk3288_win_full_scl, - .data_formats = formats_win_full, - .nformats = ARRAY_SIZE(formats_win_full), + .data_formats = formats_win_full_10, + .nformats = ARRAY_SIZE(formats_win_full_10), .format_modifiers = format_modifiers_win_full_afbc, .enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0), .format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1), + .fmt_10 = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 4), + .rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12), + .uv_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 15), + .x_mir_en = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 21), + .y_mir_en = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 22), + .act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0), + .dsp_info = VOP_REG(RK3288_WIN0_DSP_INFO, 0x0fff0fff, 0), + .dsp_st = VOP_REG(RK3288_WIN0_DSP_ST, 0x1fff1fff, 0), + .yrgb_mst = VOP_REG(RK3288_WIN0_YRGB_MST, 0xffffffff, 0), + .uv_mst = VOP_REG(RK3288_WIN0_CBR_MST, 0xffffffff, 0), + .yrgb_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 0), + .uv_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 16), + .src_alpha_ctl = VOP_REG(RK3288_WIN0_SRC_ALPHA_CTRL, 0xff, 0), + .dst_alpha_ctl = VOP_REG(RK3288_WIN0_DST_ALPHA_CTRL, 0xff, 0), + .channel = VOP_REG(RK3288_WIN0_CTRL2, 0xff, 0), +}; + +static const struct vop_win_phy rk3399_win1_data = { + .scl = &rk3288_win_full_scl, + .data_formats = formats_win_full_10, + .nformats = ARRAY_SIZE(formats_win_full_10), + .format_modifiers = format_modifiers_win_full, + .enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0), + .format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1), + .fmt_10 = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 4), .rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12), .uv_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 15), .x_mir_en = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 21), @@ -965,9 +1011,9 @@ static const struct vop_win_phy rk3399_win01_data = { * AFBC on the primary plane. */ static const struct vop_win_data rk3399_vop_win_data[] = { - { .base = 0x00, .phy = &rk3399_win01_data, + { .base = 0x00, .phy = &rk3399_win0_data, .type = DRM_PLANE_TYPE_PRIMARY }, - { .base = 0x40, .phy = &rk3368_win01_data, + { .base = 0x40, .phy = &rk3399_win1_data, .type = DRM_PLANE_TYPE_OVERLAY }, { .base = 0x00, .phy = &rk3368_win23_data, .type = DRM_PLANE_TYPE_OVERLAY }, @@ -1099,11 +1145,11 @@ static const struct vop_intr rk3328_vop_intr = { }; static const struct vop_win_data rk3328_vop_win_data[] = { - { .base = 0xd0, .phy = &rk3368_win01_data, + { .base = 0xd0, .phy = &rk3399_win1_data, .type = DRM_PLANE_TYPE_PRIMARY }, - { .base = 0x1d0, .phy = &rk3368_win01_data, + { .base = 0x1d0, .phy = &rk3399_win1_data, .type = DRM_PLANE_TYPE_OVERLAY }, - { .base = 0x2d0, .phy = &rk3368_win01_data, + { .base = 0x2d0, .phy = &rk3399_win1_data, .type = DRM_PLANE_TYPE_CURSOR }, }; diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c index a42763e1429d..409e4256f6e7 100644 --- a/drivers/gpu/drm/scheduler/sched_entity.c +++ b/drivers/gpu/drm/scheduler/sched_entity.c @@ -75,8 +75,20 @@ int drm_sched_entity_init(struct drm_sched_entity *entity, RCU_INIT_POINTER(entity->last_scheduled, NULL); RB_CLEAR_NODE(&entity->rb_tree_node); - if(num_sched_list) - entity->rq = &sched_list[0]->sched_rq[entity->priority]; + if (!sched_list[0]->sched_rq) { + /* Warn drivers not to do this and to fix their DRM + * calling order. + */ + pr_warn("%s: called with uninitialized scheduler\n", __func__); + } else if (num_sched_list) { + /* The "priority" of an entity cannot exceed the number + * of run-queues of a scheduler. + */ + if (entity->priority >= sched_list[0]->num_rqs) + entity->priority = max_t(u32, sched_list[0]->num_rqs, + DRM_SCHED_PRIORITY_MIN); + entity->rq = sched_list[0]->sched_rq[entity->priority]; + } init_completion(&entity->entity_idle); @@ -533,7 +545,7 @@ void drm_sched_entity_select_rq(struct drm_sched_entity *entity) spin_lock(&entity->rq_lock); sched = drm_sched_pick_best(entity->sched_list, entity->num_sched_list); - rq = sched ? &sched->sched_rq[entity->priority] : NULL; + rq = sched ? sched->sched_rq[entity->priority] : NULL; if (rq != entity->rq) { drm_sched_rq_remove_entity(entity->rq, entity); entity->rq = rq; diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c index 5a3a622fc672..99797a8c836a 100644 --- a/drivers/gpu/drm/scheduler/sched_main.c +++ b/drivers/gpu/drm/scheduler/sched_main.c @@ -632,8 +632,14 @@ int drm_sched_job_init(struct drm_sched_job *job, struct drm_sched_entity *entity, void *owner) { - if (!entity->rq) + if (!entity->rq) { + /* This will most likely be followed by missing frames + * or worse--a blank screen--leave a trail in the + * logs, so this can be debugged easier. + */ + drm_err(job->sched, "%s: entity has no rq!\n", __func__); return -ENOENT; + } job->entity = entity; job->s_fence = drm_sched_fence_alloc(entity, owner); @@ -671,7 +677,7 @@ void drm_sched_job_arm(struct drm_sched_job *job) sched = entity->rq->sched; job->sched = sched; - job->s_priority = entity->rq - sched->sched_rq; + job->s_priority = entity->priority; job->id = atomic64_inc_return(&sched->job_id_count); drm_sched_fence_init(job->s_fence, job->entity); @@ -888,10 +894,10 @@ drm_sched_select_entity(struct drm_gpu_scheduler *sched) return NULL; /* Kernel run queue has higher priority than normal run queue*/ - for (i = DRM_SCHED_PRIORITY_COUNT - 1; i >= DRM_SCHED_PRIORITY_MIN; i--) { + for (i = sched->num_rqs - 1; i >= DRM_SCHED_PRIORITY_MIN; i--) { entity = drm_sched_policy == DRM_SCHED_POLICY_FIFO ? - drm_sched_rq_select_entity_fifo(&sched->sched_rq[i]) : - drm_sched_rq_select_entity_rr(&sched->sched_rq[i]); + drm_sched_rq_select_entity_fifo(sched->sched_rq[i]) : + drm_sched_rq_select_entity_rr(sched->sched_rq[i]); if (entity) break; } @@ -1071,6 +1077,7 @@ static int drm_sched_main(void *param) * * @sched: scheduler instance * @ops: backend operations for this scheduler + * @num_rqs: number of runqueues, one for each priority, up to DRM_SCHED_PRIORITY_COUNT * @hw_submission: number of hw submissions that can be in flight * @hang_limit: number of times to allow a job to hang before dropping it * @timeout: timeout value in jiffies for the scheduler @@ -1084,11 +1091,12 @@ static int drm_sched_main(void *param) */ int drm_sched_init(struct drm_gpu_scheduler *sched, const struct drm_sched_backend_ops *ops, - unsigned hw_submission, unsigned hang_limit, + u32 num_rqs, uint32_t hw_submission, unsigned int hang_limit, long timeout, struct workqueue_struct *timeout_wq, atomic_t *score, const char *name, struct device *dev) { int i, ret; + sched->ops = ops; sched->hw_submission_limit = hw_submission; sched->name = name; @@ -1097,8 +1105,36 @@ int drm_sched_init(struct drm_gpu_scheduler *sched, sched->hang_limit = hang_limit; sched->score = score ? score : &sched->_score; sched->dev = dev; - for (i = DRM_SCHED_PRIORITY_MIN; i < DRM_SCHED_PRIORITY_COUNT; i++) - drm_sched_rq_init(sched, &sched->sched_rq[i]); + + if (num_rqs > DRM_SCHED_PRIORITY_COUNT) { + /* This is a gross violation--tell drivers what the problem is. + */ + drm_err(sched, "%s: num_rqs cannot be greater than DRM_SCHED_PRIORITY_COUNT\n", + __func__); + return -EINVAL; + } else if (sched->sched_rq) { + /* Not an error, but warn anyway so drivers can + * fine-tune their DRM calling order, and return all + * is good. + */ + drm_warn(sched, "%s: scheduler already initialized!\n", __func__); + return 0; + } + + sched->sched_rq = kmalloc_array(num_rqs, sizeof(*sched->sched_rq), + GFP_KERNEL | __GFP_ZERO); + if (!sched->sched_rq) { + drm_err(sched, "%s: out of memory for sched_rq\n", __func__); + return -ENOMEM; + } + sched->num_rqs = num_rqs; + ret = -ENOMEM; + for (i = DRM_SCHED_PRIORITY_MIN; i < sched->num_rqs; i++) { + sched->sched_rq[i] = kzalloc(sizeof(*sched->sched_rq[i]), GFP_KERNEL); + if (!sched->sched_rq[i]) + goto Out_unroll; + drm_sched_rq_init(sched, sched->sched_rq[i]); + } init_waitqueue_head(&sched->wake_up_worker); init_waitqueue_head(&sched->job_scheduled); @@ -1115,11 +1151,18 @@ int drm_sched_init(struct drm_gpu_scheduler *sched, ret = PTR_ERR(sched->thread); sched->thread = NULL; DRM_DEV_ERROR(sched->dev, "Failed to create scheduler for %s.\n", name); - return ret; + goto Out_unroll; } sched->ready = true; return 0; +Out_unroll: + for (--i ; i >= DRM_SCHED_PRIORITY_MIN; i--) + kfree(sched->sched_rq[i]); + kfree(sched->sched_rq); + sched->sched_rq = NULL; + drm_err(sched, "%s: Failed to setup GPU scheduler--out of memory\n", __func__); + return ret; } EXPORT_SYMBOL(drm_sched_init); @@ -1138,8 +1181,8 @@ void drm_sched_fini(struct drm_gpu_scheduler *sched) if (sched->thread) kthread_stop(sched->thread); - for (i = DRM_SCHED_PRIORITY_COUNT - 1; i >= DRM_SCHED_PRIORITY_MIN; i--) { - struct drm_sched_rq *rq = &sched->sched_rq[i]; + for (i = sched->num_rqs - 1; i >= DRM_SCHED_PRIORITY_MIN; i--) { + struct drm_sched_rq *rq = sched->sched_rq[i]; spin_lock(&rq->lock); list_for_each_entry(s_entity, &rq->entities, list) @@ -1150,7 +1193,7 @@ void drm_sched_fini(struct drm_gpu_scheduler *sched) */ s_entity->stopped = true; spin_unlock(&rq->lock); - + kfree(sched->sched_rq[i]); } /* Wakeup everyone stuck in drm_sched_entity_flush for this scheduler */ @@ -1160,6 +1203,8 @@ void drm_sched_fini(struct drm_gpu_scheduler *sched) cancel_delayed_work_sync(&sched->work_tdr); sched->ready = false; + kfree(sched->sched_rq); + sched->sched_rq = NULL; } EXPORT_SYMBOL(drm_sched_fini); @@ -1186,9 +1231,10 @@ void drm_sched_increase_karma(struct drm_sched_job *bad) if (bad->s_priority != DRM_SCHED_PRIORITY_KERNEL) { atomic_inc(&bad->karma); - for (i = DRM_SCHED_PRIORITY_MIN; i < DRM_SCHED_PRIORITY_KERNEL; + for (i = DRM_SCHED_PRIORITY_MIN; + i < min_t(typeof(sched->num_rqs), sched->num_rqs, DRM_SCHED_PRIORITY_KERNEL); i++) { - struct drm_sched_rq *rq = &sched->sched_rq[i]; + struct drm_sched_rq *rq = sched->sched_rq[i]; spin_lock(&rq->lock); list_for_each_entry_safe(entity, tmp, &rq->entities, list) { diff --git a/drivers/gpu/drm/solomon/Kconfig b/drivers/gpu/drm/solomon/Kconfig index e170716d976b..c3ee956c2bb9 100644 --- a/drivers/gpu/drm/solomon/Kconfig +++ b/drivers/gpu/drm/solomon/Kconfig @@ -1,31 +1,31 @@ config DRM_SSD130X - tristate "DRM support for Solomon SSD130x OLED displays" + tristate "DRM support for Solomon SSD13xx OLED displays" depends on DRM && MMU select BACKLIGHT_CLASS_DEVICE select DRM_GEM_SHMEM_HELPER select DRM_KMS_HELPER help - DRM driver for the SSD130x Solomon and SINO WEALTH SH110x OLED + DRM driver for the SSD13xx Solomon and SINO WEALTH SH110x OLED controllers. This is only for the core driver, a driver for the appropriate bus transport in your chip also must be selected. If M is selected the module will be called ssd130x. config DRM_SSD130X_I2C - tristate "DRM support for Solomon SSD130x OLED displays (I2C bus)" + tristate "DRM support for Solomon SSD13xx OLED displays (I2C bus)" depends on DRM_SSD130X && I2C select REGMAP_I2C help - Say Y here if the SSD130x or SH110x OLED display is connected via + Say Y here if the SSD13xx or SH110x OLED display is connected via I2C bus. If M is selected the module will be called ssd130x-i2c. config DRM_SSD130X_SPI - tristate "DRM support for Solomon SSD130X OLED displays (SPI bus)" + tristate "DRM support for Solomon SSD13xx OLED displays (SPI bus)" depends on DRM_SSD130X && SPI select REGMAP help - Say Y here if the SSD130x OLED display is connected via SPI bus. + Say Y here if the SSD13xx OLED display is connected via SPI bus. If M is selected the module will be called ssd130x-spi. diff --git a/drivers/gpu/drm/solomon/ssd130x-i2c.c b/drivers/gpu/drm/solomon/ssd130x-i2c.c index b4eb2d64bf6e..f2ccab9c06d9 100644 --- a/drivers/gpu/drm/solomon/ssd130x-i2c.c +++ b/drivers/gpu/drm/solomon/ssd130x-i2c.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * DRM driver for Solomon SSD130x OLED displays (I2C bus) + * DRM driver for Solomon SSD13xx OLED displays (I2C bus) * * Copyright 2022 Red Hat Inc. * Author: Javier Martinez Canillas <javierm@redhat.com> @@ -14,7 +14,7 @@ #include "ssd130x.h" #define DRIVER_NAME "ssd130x-i2c" -#define DRIVER_DESC "DRM driver for Solomon SSD130x OLED displays (I2C)" +#define DRIVER_DESC "DRM driver for Solomon SSD13xx OLED displays (I2C)" static const struct regmap_config ssd130x_i2c_regmap_config = { .reg_bits = 8, @@ -54,6 +54,7 @@ static void ssd130x_i2c_shutdown(struct i2c_client *client) } static const struct of_device_id ssd130x_of_match[] = { + /* ssd130x family */ { .compatible = "sinowealth,sh1106", .data = &ssd130x_variants[SH1106_ID], @@ -91,6 +92,19 @@ static const struct of_device_id ssd130x_of_match[] = { .compatible = "solomon,ssd1309fb-i2c", .data = &ssd130x_variants[SSD1309_ID], }, + /* ssd132x family */ + { + .compatible = "solomon,ssd1322", + .data = &ssd130x_variants[SSD1322_ID], + }, + { + .compatible = "solomon,ssd1325", + .data = &ssd130x_variants[SSD1325_ID], + }, + { + .compatible = "solomon,ssd1327", + .data = &ssd130x_variants[SSD1327_ID], + }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, ssd130x_of_match); diff --git a/drivers/gpu/drm/solomon/ssd130x-spi.c b/drivers/gpu/drm/solomon/ssd130x-spi.c index 19ab4942cb33..84e035a7ab3f 100644 --- a/drivers/gpu/drm/solomon/ssd130x-spi.c +++ b/drivers/gpu/drm/solomon/ssd130x-spi.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * DRM driver for Solomon SSD130X OLED displays (SPI bus) + * DRM driver for Solomon SSD13xx OLED displays (SPI bus) * * Copyright 2022 Red Hat Inc. * Authors: Javier Martinez Canillas <javierm@redhat.com> @@ -11,7 +11,7 @@ #include "ssd130x.h" #define DRIVER_NAME "ssd130x-spi" -#define DRIVER_DESC "DRM driver for Solomon SSD130X OLED displays (SPI)" +#define DRIVER_DESC "DRM driver for Solomon SSD13xx OLED displays (SPI)" struct ssd130x_spi_transport { struct spi_device *spi; @@ -34,10 +34,10 @@ static int ssd130x_spi_write(void *context, const void *data, size_t count) struct spi_device *spi = t->spi; const u8 *reg = data; - if (*reg == SSD130X_COMMAND) + if (*reg == SSD13XX_COMMAND) gpiod_set_value_cansleep(t->dc, 0); - if (*reg == SSD130X_DATA) + if (*reg == SSD13XX_DATA) gpiod_set_value_cansleep(t->dc, 1); /* Remove control byte since is not used in a 4-wire SPI interface */ @@ -108,6 +108,7 @@ static void ssd130x_spi_shutdown(struct spi_device *spi) } static const struct of_device_id ssd130x_of_match[] = { + /* ssd130x family */ { .compatible = "sinowealth,sh1106", .data = &ssd130x_variants[SH1106_ID], @@ -128,6 +129,19 @@ static const struct of_device_id ssd130x_of_match[] = { .compatible = "solomon,ssd1309", .data = &ssd130x_variants[SSD1309_ID], }, + /* ssd132x family */ + { + .compatible = "solomon,ssd1322", + .data = &ssd130x_variants[SSD1322_ID], + }, + { + .compatible = "solomon,ssd1325", + .data = &ssd130x_variants[SSD1325_ID], + }, + { + .compatible = "solomon,ssd1327", + .data = &ssd130x_variants[SSD1327_ID], + }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, ssd130x_of_match); @@ -142,11 +156,16 @@ MODULE_DEVICE_TABLE(of, ssd130x_of_match); * not be needed for this driver to match the registered SPI devices. */ static const struct spi_device_id ssd130x_spi_table[] = { + /* ssd130x family */ { "sh1106", SH1106_ID }, { "ssd1305", SSD1305_ID }, { "ssd1306", SSD1306_ID }, { "ssd1307", SSD1307_ID }, { "ssd1309", SSD1309_ID }, + /* ssd132x family */ + { "ssd1322", SSD1322_ID }, + { "ssd1325", SSD1325_ID }, + { "ssd1327", SSD1327_ID }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(spi, ssd130x_spi_table); diff --git a/drivers/gpu/drm/solomon/ssd130x.c b/drivers/gpu/drm/solomon/ssd130x.c index 6dcf3e041113..32f0857aec9f 100644 --- a/drivers/gpu/drm/solomon/ssd130x.c +++ b/drivers/gpu/drm/solomon/ssd130x.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * DRM driver for Solomon SSD130x OLED displays + * DRM driver for Solomon SSD13xx OLED displays * * Copyright 2022 Red Hat Inc. * Author: Javier Martinez Canillas <javierm@redhat.com> @@ -37,23 +37,33 @@ #include "ssd130x.h" #define DRIVER_NAME "ssd130x" -#define DRIVER_DESC "DRM driver for Solomon SSD130x OLED displays" +#define DRIVER_DESC "DRM driver for Solomon SSD13xx OLED displays" #define DRIVER_DATE "20220131" #define DRIVER_MAJOR 1 #define DRIVER_MINOR 0 +#define SSD130X_PAGE_HEIGHT 8 + +#define SSD132X_SEGMENT_WIDTH 2 + +/* ssd13xx commands */ +#define SSD13XX_CONTRAST 0x81 +#define SSD13XX_SET_SEG_REMAP 0xa0 +#define SSD13XX_SET_MULTIPLEX_RATIO 0xa8 +#define SSD13XX_DISPLAY_OFF 0xae +#define SSD13XX_DISPLAY_ON 0xaf + +#define SSD13XX_SET_SEG_REMAP_MASK GENMASK(0, 0) +#define SSD13XX_SET_SEG_REMAP_SET(val) FIELD_PREP(SSD13XX_SET_SEG_REMAP_MASK, (val)) + +/* ssd130x commands */ #define SSD130X_PAGE_COL_START_LOW 0x00 #define SSD130X_PAGE_COL_START_HIGH 0x10 #define SSD130X_SET_ADDRESS_MODE 0x20 #define SSD130X_SET_COL_RANGE 0x21 #define SSD130X_SET_PAGE_RANGE 0x22 -#define SSD130X_CONTRAST 0x81 #define SSD130X_SET_LOOKUP_TABLE 0x91 #define SSD130X_CHARGE_PUMP 0x8d -#define SSD130X_SET_SEG_REMAP 0xa0 -#define SSD130X_DISPLAY_OFF 0xae -#define SSD130X_SET_MULTIPLEX_RATIO 0xa8 -#define SSD130X_DISPLAY_ON 0xaf #define SSD130X_START_PAGE_ADDRESS 0xb0 #define SSD130X_SET_COM_SCAN_DIR 0xc0 #define SSD130X_SET_DISPLAY_OFFSET 0xd3 @@ -63,13 +73,12 @@ #define SSD130X_SET_COM_PINS_CONFIG 0xda #define SSD130X_SET_VCOMH 0xdb +/* ssd130x commands accessors */ #define SSD130X_PAGE_COL_START_MASK GENMASK(3, 0) #define SSD130X_PAGE_COL_START_HIGH_SET(val) FIELD_PREP(SSD130X_PAGE_COL_START_MASK, (val) >> 4) #define SSD130X_PAGE_COL_START_LOW_SET(val) FIELD_PREP(SSD130X_PAGE_COL_START_MASK, (val)) #define SSD130X_START_PAGE_ADDRESS_MASK GENMASK(2, 0) #define SSD130X_START_PAGE_ADDRESS_SET(val) FIELD_PREP(SSD130X_START_PAGE_ADDRESS_MASK, (val)) -#define SSD130X_SET_SEG_REMAP_MASK GENMASK(0, 0) -#define SSD130X_SET_SEG_REMAP_SET(val) FIELD_PREP(SSD130X_SET_SEG_REMAP_MASK, (val)) #define SSD130X_SET_COM_SCAN_DIR_MASK GENMASK(3, 3) #define SSD130X_SET_COM_SCAN_DIR_SET(val) FIELD_PREP(SSD130X_SET_COM_SCAN_DIR_MASK, (val)) #define SSD130X_SET_CLOCK_DIV_MASK GENMASK(3, 0) @@ -92,6 +101,24 @@ #define SSD130X_SET_AREA_COLOR_MODE_ENABLE 0x1e #define SSD130X_SET_AREA_COLOR_MODE_LOW_POWER 0x05 +/* ssd132x commands */ +#define SSD132X_SET_COL_RANGE 0x15 +#define SSD132X_SET_DEACTIVATE_SCROLL 0x2e +#define SSD132X_SET_ROW_RANGE 0x75 +#define SSD132X_SET_DISPLAY_START 0xa1 +#define SSD132X_SET_DISPLAY_OFFSET 0xa2 +#define SSD132X_SET_DISPLAY_NORMAL 0xa4 +#define SSD132X_SET_FUNCTION_SELECT_A 0xab +#define SSD132X_SET_PHASE_LENGTH 0xb1 +#define SSD132X_SET_CLOCK_FREQ 0xb3 +#define SSD132X_SET_GPIO 0xb5 +#define SSD132X_SET_PRECHARGE_PERIOD 0xb6 +#define SSD132X_SET_GRAY_SCALE_TABLE 0xb8 +#define SSD132X_SELECT_DEFAULT_TABLE 0xb9 +#define SSD132X_SET_PRECHARGE_VOLTAGE 0xbc +#define SSD130X_SET_VCOMH_VOLTAGE 0xbe +#define SSD132X_SET_FUNCTION_SELECT_B 0xd5 + #define MAX_CONTRAST 255 const struct ssd130x_deviceinfo ssd130x_variants[] = { @@ -102,7 +129,7 @@ const struct ssd130x_deviceinfo ssd130x_variants[] = { .default_width = 132, .default_height = 64, .page_mode_only = 1, - .page_height = 8, + .family_id = SSD130X_FAMILY, }, [SSD1305_ID] = { .default_vcomh = 0x34, @@ -110,7 +137,7 @@ const struct ssd130x_deviceinfo ssd130x_variants[] = { .default_dclk_frq = 7, .default_width = 132, .default_height = 64, - .page_height = 8, + .family_id = SSD130X_FAMILY, }, [SSD1306_ID] = { .default_vcomh = 0x20, @@ -119,7 +146,7 @@ const struct ssd130x_deviceinfo ssd130x_variants[] = { .need_chargepump = 1, .default_width = 128, .default_height = 64, - .page_height = 8, + .family_id = SSD130X_FAMILY, }, [SSD1307_ID] = { .default_vcomh = 0x20, @@ -128,7 +155,7 @@ const struct ssd130x_deviceinfo ssd130x_variants[] = { .need_pwm = 1, .default_width = 128, .default_height = 39, - .page_height = 8, + .family_id = SSD130X_FAMILY, }, [SSD1309_ID] = { .default_vcomh = 0x34, @@ -136,7 +163,23 @@ const struct ssd130x_deviceinfo ssd130x_variants[] = { .default_dclk_frq = 10, .default_width = 128, .default_height = 64, - .page_height = 8, + .family_id = SSD130X_FAMILY, + }, + /* ssd132x family */ + [SSD1322_ID] = { + .default_width = 480, + .default_height = 128, + .family_id = SSD132X_FAMILY, + }, + [SSD1325_ID] = { + .default_width = 128, + .default_height = 80, + .family_id = SSD132X_FAMILY, + }, + [SSD1327_ID] = { + .default_width = 128, + .default_height = 128, + .family_id = SSD132X_FAMILY, } }; EXPORT_SYMBOL_NS_GPL(ssd130x_variants, DRM_SSD130X); @@ -169,20 +212,20 @@ static inline struct ssd130x_device *drm_to_ssd130x(struct drm_device *drm) } /* - * Helper to write data (SSD130X_DATA) to the device. + * Helper to write data (SSD13XX_DATA) to the device. */ static int ssd130x_write_data(struct ssd130x_device *ssd130x, u8 *values, int count) { - return regmap_bulk_write(ssd130x->regmap, SSD130X_DATA, values, count); + return regmap_bulk_write(ssd130x->regmap, SSD13XX_DATA, values, count); } /* - * Helper to write command (SSD130X_COMMAND). The fist variadic argument + * Helper to write command (SSD13XX_COMMAND). The fist variadic argument * is the command to write and the following are the command options. * - * Note that the ssd130x protocol requires each command and option to be - * written as a SSD130X_COMMAND device register value. That is why a call - * to regmap_write(..., SSD130X_COMMAND, ...) is done for each argument. + * Note that the ssd13xx protocol requires each command and option to be + * written as a SSD13XX_COMMAND device register value. That is why a call + * to regmap_write(..., SSD13XX_COMMAND, ...) is done for each argument. */ static int ssd130x_write_cmd(struct ssd130x_device *ssd130x, int count, /* u8 cmd, u8 option, ... */...) @@ -195,7 +238,7 @@ static int ssd130x_write_cmd(struct ssd130x_device *ssd130x, int count, do { value = va_arg(ap, int); - ret = regmap_write(ssd130x->regmap, SSD130X_COMMAND, value); + ret = regmap_write(ssd130x->regmap, SSD13XX_COMMAND, value); if (ret) goto out_end; } while (--count); @@ -339,13 +382,13 @@ static int ssd130x_init(struct ssd130x_device *ssd130x) int ret; /* Set initial contrast */ - ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_CONTRAST, ssd130x->contrast); + ret = ssd130x_write_cmd(ssd130x, 2, SSD13XX_CONTRAST, ssd130x->contrast); if (ret < 0) return ret; /* Set segment re-map */ - seg_remap = (SSD130X_SET_SEG_REMAP | - SSD130X_SET_SEG_REMAP_SET(ssd130x->seg_remap)); + seg_remap = (SSD13XX_SET_SEG_REMAP | + SSD13XX_SET_SEG_REMAP_SET(ssd130x->seg_remap)); ret = ssd130x_write_cmd(ssd130x, 1, seg_remap); if (ret < 0) return ret; @@ -358,7 +401,7 @@ static int ssd130x_init(struct ssd130x_device *ssd130x) return ret; /* Set multiplex ratio value */ - ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_MULTIPLEX_RATIO, ssd130x->height - 1); + ret = ssd130x_write_cmd(ssd130x, 2, SSD13XX_SET_MULTIPLEX_RATIO, ssd130x->height - 1); if (ret < 0) return ret; @@ -456,6 +499,96 @@ static int ssd130x_init(struct ssd130x_device *ssd130x) SSD130X_SET_ADDRESS_MODE_HORIZONTAL); } +static int ssd132x_init(struct ssd130x_device *ssd130x) +{ + int ret; + + /* Set initial contrast */ + ret = ssd130x_write_cmd(ssd130x, 2, SSD13XX_CONTRAST, 0x80); + if (ret < 0) + return ret; + + /* Set column start and end */ + ret = ssd130x_write_cmd(ssd130x, 3, SSD132X_SET_COL_RANGE, 0x00, + ssd130x->width / SSD132X_SEGMENT_WIDTH - 1); + if (ret < 0) + return ret; + + /* Set row start and end */ + ret = ssd130x_write_cmd(ssd130x, 3, SSD132X_SET_ROW_RANGE, 0x00, ssd130x->height - 1); + if (ret < 0) + return ret; + /* + * Horizontal Address Increment + * Re-map for Column Address, Nibble and COM + * COM Split Odd Even + */ + ret = ssd130x_write_cmd(ssd130x, 2, SSD13XX_SET_SEG_REMAP, 0x53); + if (ret < 0) + return ret; + + /* Set display start and offset */ + ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_DISPLAY_START, 0x00); + if (ret < 0) + return ret; + + ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_DISPLAY_OFFSET, 0x00); + if (ret < 0) + return ret; + + /* Set display mode normal */ + ret = ssd130x_write_cmd(ssd130x, 1, SSD132X_SET_DISPLAY_NORMAL); + if (ret < 0) + return ret; + + /* Set multiplex ratio value */ + ret = ssd130x_write_cmd(ssd130x, 2, SSD13XX_SET_MULTIPLEX_RATIO, ssd130x->height - 1); + if (ret < 0) + return ret; + + /* Set phase length */ + ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_PHASE_LENGTH, 0x55); + if (ret < 0) + return ret; + + /* Select default linear gray scale table */ + ret = ssd130x_write_cmd(ssd130x, 1, SSD132X_SELECT_DEFAULT_TABLE); + if (ret < 0) + return ret; + + /* Set clock frequency */ + ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_CLOCK_FREQ, 0x01); + if (ret < 0) + return ret; + + /* Enable internal VDD regulator */ + ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_FUNCTION_SELECT_A, 0x1); + if (ret < 0) + return ret; + + /* Set pre-charge period */ + ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_PRECHARGE_PERIOD, 0x01); + if (ret < 0) + return ret; + + /* Set pre-charge voltage */ + ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_PRECHARGE_VOLTAGE, 0x08); + if (ret < 0) + return ret; + + /* Set VCOMH voltage */ + ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_VCOMH_VOLTAGE, 0x07); + if (ret < 0) + return ret; + + /* Enable second pre-charge and internal VSL */ + ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_FUNCTION_SELECT_B, 0x62); + if (ret < 0) + return ret; + + return 0; +} + static int ssd130x_update_rect(struct ssd130x_device *ssd130x, struct drm_rect *rect, u8 *buf, u8 *data_array) @@ -465,13 +598,13 @@ static int ssd130x_update_rect(struct ssd130x_device *ssd130x, unsigned int width = drm_rect_width(rect); unsigned int height = drm_rect_height(rect); unsigned int line_length = DIV_ROUND_UP(width, 8); - unsigned int page_height = ssd130x->device_info->page_height; + unsigned int page_height = SSD130X_PAGE_HEIGHT; unsigned int pages = DIV_ROUND_UP(height, page_height); struct drm_device *drm = &ssd130x->drm; u32 array_idx = 0; int ret, i, j, k; - drm_WARN_ONCE(drm, y % 8 != 0, "y must be aligned to screen page\n"); + drm_WARN_ONCE(drm, y % page_height != 0, "y must be aligned to screen page\n"); /* * The screen is divided in pages, each having a height of 8 @@ -503,27 +636,32 @@ static int ssd130x_update_rect(struct ssd130x_device *ssd130x, */ if (!ssd130x->page_address_mode) { + u8 page_start; + /* Set address range for horizontal addressing mode */ ret = ssd130x_set_col_range(ssd130x, ssd130x->col_offset + x, width); if (ret < 0) return ret; - ret = ssd130x_set_page_range(ssd130x, ssd130x->page_offset + y / 8, pages); + page_start = ssd130x->page_offset + y / page_height; + ret = ssd130x_set_page_range(ssd130x, page_start, pages); if (ret < 0) return ret; } for (i = 0; i < pages; i++) { - int m = 8; + int m = page_height; /* Last page may be partial */ - if (8 * (y / 8 + i + 1) > ssd130x->height) - m = ssd130x->height % 8; + if (page_height * (y / page_height + i + 1) > ssd130x->height) + m = ssd130x->height % page_height; + for (j = 0; j < width; j++) { u8 data = 0; for (k = 0; k < m; k++) { - u8 byte = buf[(8 * i + k) * line_length + j / 8]; + u32 idx = (page_height * i + k) * line_length + j / 8; + u8 byte = buf[idx]; u8 bit = (byte >> (j % 8)) & 1; data |= bit << k; @@ -557,10 +695,67 @@ static int ssd130x_update_rect(struct ssd130x_device *ssd130x, return ret; } +static int ssd132x_update_rect(struct ssd130x_device *ssd130x, + struct drm_rect *rect, u8 *buf, + u8 *data_array) +{ + unsigned int x = rect->x1; + unsigned int y = rect->y1; + unsigned int segment_width = SSD132X_SEGMENT_WIDTH; + unsigned int width = drm_rect_width(rect); + unsigned int height = drm_rect_height(rect); + unsigned int columns = DIV_ROUND_UP(width, segment_width); + unsigned int rows = height; + struct drm_device *drm = &ssd130x->drm; + u32 array_idx = 0; + unsigned int i, j; + int ret; + + drm_WARN_ONCE(drm, x % segment_width != 0, "x must be aligned to screen segment\n"); + + /* + * The screen is divided in Segment and Common outputs, where + * COM0 to COM[N - 1] are the rows and SEG0 to SEG[M - 1] are + * the columns. + * + * Each Segment has a 4-bit pixel and each Common output has a + * row of pixels. When using the (default) horizontal address + * increment mode, each byte of data sent to the controller has + * two Segments (e.g: SEG0 and SEG1) that are stored in the lower + * and higher nibbles of a single byte representing one column. + * That is, the first byte are SEG0 (D0[3:0]) and SEG1 (D0[7:4]), + * the second byte are SEG2 (D1[3:0]) and SEG3 (D1[7:4]) and so on. + */ + + /* Set column start and end */ + ret = ssd130x_write_cmd(ssd130x, 3, SSD132X_SET_COL_RANGE, x / segment_width, columns - 1); + if (ret < 0) + return ret; + + /* Set row start and end */ + ret = ssd130x_write_cmd(ssd130x, 3, SSD132X_SET_ROW_RANGE, y, rows - 1); + if (ret < 0) + return ret; + + for (i = 0; i < height; i++) { + /* Process pair of pixels and combine them into a single byte */ + for (j = 0; j < width; j += segment_width) { + u8 n1 = buf[i * width + j]; + u8 n2 = buf[i * width + j + 1]; + + data_array[array_idx++] = (n2 << 4) | n1; + } + } + + /* Write out update in one go since horizontal addressing mode is used */ + ret = ssd130x_write_data(ssd130x, data_array, columns * rows); + + return ret; +} + static void ssd130x_clear_screen(struct ssd130x_device *ssd130x, u8 *data_array) { - unsigned int page_height = ssd130x->device_info->page_height; - unsigned int pages = DIV_ROUND_UP(ssd130x->height, page_height); + unsigned int pages = DIV_ROUND_UP(ssd130x->height, SSD130X_PAGE_HEIGHT); unsigned int width = ssd130x->width; int ret, i; @@ -599,20 +794,30 @@ static void ssd130x_clear_screen(struct ssd130x_device *ssd130x, u8 *data_array) } } +static void ssd132x_clear_screen(struct ssd130x_device *ssd130x, u8 *data_array) +{ + unsigned int columns = DIV_ROUND_UP(ssd130x->height, SSD132X_SEGMENT_WIDTH); + unsigned int height = ssd130x->height; + + memset(data_array, 0, columns * height); + + /* Write out update in one go since horizontal addressing mode is used */ + ssd130x_write_data(ssd130x, data_array, columns * height); +} + static int ssd130x_fb_blit_rect(struct drm_framebuffer *fb, const struct iosys_map *vmap, struct drm_rect *rect, u8 *buf, u8 *data_array) { struct ssd130x_device *ssd130x = drm_to_ssd130x(fb->dev); - unsigned int page_height = ssd130x->device_info->page_height; struct iosys_map dst; unsigned int dst_pitch; int ret = 0; /* Align y to display page boundaries */ - rect->y1 = round_down(rect->y1, page_height); - rect->y2 = min_t(unsigned int, round_up(rect->y2, page_height), ssd130x->height); + rect->y1 = round_down(rect->y1, SSD130X_PAGE_HEIGHT); + rect->y2 = min_t(unsigned int, round_up(rect->y2, SSD130X_PAGE_HEIGHT), ssd130x->height); dst_pitch = DIV_ROUND_UP(drm_rect_width(rect), 8); @@ -630,6 +835,35 @@ static int ssd130x_fb_blit_rect(struct drm_framebuffer *fb, return ret; } +static int ssd132x_fb_blit_rect(struct drm_framebuffer *fb, + const struct iosys_map *vmap, + struct drm_rect *rect, u8 *buf, + u8 *data_array) +{ + struct ssd130x_device *ssd130x = drm_to_ssd130x(fb->dev); + unsigned int dst_pitch = drm_rect_width(rect); + struct iosys_map dst; + int ret = 0; + + /* Align x to display segment boundaries */ + rect->x1 = round_down(rect->x1, SSD132X_SEGMENT_WIDTH); + rect->x2 = min_t(unsigned int, round_up(rect->x2, SSD132X_SEGMENT_WIDTH), + ssd130x->width); + + ret = drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE); + if (ret) + return ret; + + iosys_map_set_vaddr(&dst, buf); + drm_fb_xrgb8888_to_gray8(&dst, &dst_pitch, vmap, fb, rect); + + drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE); + + ssd132x_update_rect(ssd130x, rect, buf, data_array); + + return ret; +} + static int ssd130x_primary_plane_atomic_check(struct drm_plane *plane, struct drm_atomic_state *state) { @@ -638,23 +872,62 @@ static int ssd130x_primary_plane_atomic_check(struct drm_plane *plane, struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane); struct ssd130x_plane_state *ssd130x_state = to_ssd130x_plane_state(plane_state); struct drm_crtc *crtc = plane_state->crtc; - struct drm_crtc_state *crtc_state; + struct drm_crtc_state *crtc_state = NULL; const struct drm_format_info *fi; unsigned int pitch; int ret; - if (!crtc) + if (crtc) + crtc_state = drm_atomic_get_new_crtc_state(state, crtc); + + ret = drm_atomic_helper_check_plane_state(plane_state, crtc_state, + DRM_PLANE_NO_SCALING, + DRM_PLANE_NO_SCALING, + false, false); + if (ret) + return ret; + else if (!plane_state->visible) + return 0; + + fi = drm_format_info(DRM_FORMAT_R1); + if (!fi) return -EINVAL; - crtc_state = drm_atomic_get_crtc_state(state, crtc); - if (IS_ERR(crtc_state)) - return PTR_ERR(crtc_state); + pitch = drm_format_info_min_pitch(fi, 0, ssd130x->width); + + ssd130x_state->buffer = kcalloc(pitch, ssd130x->height, GFP_KERNEL); + if (!ssd130x_state->buffer) + return -ENOMEM; + + return 0; +} + +static int ssd132x_primary_plane_atomic_check(struct drm_plane *plane, + struct drm_atomic_state *state) +{ + struct drm_device *drm = plane->dev; + struct ssd130x_device *ssd130x = drm_to_ssd130x(drm); + struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane); + struct ssd130x_plane_state *ssd130x_state = to_ssd130x_plane_state(plane_state); + struct drm_crtc *crtc = plane_state->crtc; + struct drm_crtc_state *crtc_state; + const struct drm_format_info *fi; + unsigned int pitch; + int ret; + + if (crtc) + crtc_state = drm_atomic_get_new_crtc_state(state, crtc); - ret = drm_plane_helper_atomic_check(plane, state); + ret = drm_atomic_helper_check_plane_state(plane_state, crtc_state, + DRM_PLANE_NO_SCALING, + DRM_PLANE_NO_SCALING, + false, false); if (ret) return ret; + else if (!plane_state->visible) + return 0; - fi = drm_format_info(DRM_FORMAT_R1); + fi = drm_format_info(DRM_FORMAT_R8); if (!fi) return -EINVAL; @@ -701,6 +974,40 @@ static void ssd130x_primary_plane_atomic_update(struct drm_plane *plane, drm_dev_exit(idx); } +static void ssd132x_primary_plane_atomic_update(struct drm_plane *plane, + struct drm_atomic_state *state) +{ + struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane); + struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane); + struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state); + struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, plane_state->crtc); + struct ssd130x_crtc_state *ssd130x_crtc_state = to_ssd130x_crtc_state(crtc_state); + struct ssd130x_plane_state *ssd130x_plane_state = to_ssd130x_plane_state(plane_state); + struct drm_framebuffer *fb = plane_state->fb; + struct drm_atomic_helper_damage_iter iter; + struct drm_device *drm = plane->dev; + struct drm_rect dst_clip; + struct drm_rect damage; + int idx; + + if (!drm_dev_enter(drm, &idx)) + return; + + drm_atomic_helper_damage_iter_init(&iter, old_plane_state, plane_state); + drm_atomic_for_each_plane_damage(&iter, &damage) { + dst_clip = plane_state->dst; + + if (!drm_rect_intersect(&dst_clip, &damage)) + continue; + + ssd132x_fb_blit_rect(fb, &shadow_plane_state->data[0], &dst_clip, + ssd130x_plane_state->buffer, + ssd130x_crtc_state->data_array); + } + + drm_dev_exit(idx); +} + static void ssd130x_primary_plane_atomic_disable(struct drm_plane *plane, struct drm_atomic_state *state) { @@ -725,6 +1032,30 @@ static void ssd130x_primary_plane_atomic_disable(struct drm_plane *plane, drm_dev_exit(idx); } +static void ssd132x_primary_plane_atomic_disable(struct drm_plane *plane, + struct drm_atomic_state *state) +{ + struct drm_device *drm = plane->dev; + struct ssd130x_device *ssd130x = drm_to_ssd130x(drm); + struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane); + struct drm_crtc_state *crtc_state; + struct ssd130x_crtc_state *ssd130x_crtc_state; + int idx; + + if (!plane_state->crtc) + return; + + crtc_state = drm_atomic_get_new_crtc_state(state, plane_state->crtc); + ssd130x_crtc_state = to_ssd130x_crtc_state(crtc_state); + + if (!drm_dev_enter(drm, &idx)) + return; + + ssd132x_clear_screen(ssd130x, ssd130x_crtc_state->data_array); + + drm_dev_exit(idx); +} + /* Called during init to allocate the plane's atomic state. */ static void ssd130x_primary_plane_reset(struct drm_plane *plane) { @@ -775,11 +1106,19 @@ static void ssd130x_primary_plane_destroy_state(struct drm_plane *plane, kfree(ssd130x_state); } -static const struct drm_plane_helper_funcs ssd130x_primary_plane_helper_funcs = { - DRM_GEM_SHADOW_PLANE_HELPER_FUNCS, - .atomic_check = ssd130x_primary_plane_atomic_check, - .atomic_update = ssd130x_primary_plane_atomic_update, - .atomic_disable = ssd130x_primary_plane_atomic_disable, +static const struct drm_plane_helper_funcs ssd130x_primary_plane_helper_funcs[] = { + [SSD130X_FAMILY] = { + DRM_GEM_SHADOW_PLANE_HELPER_FUNCS, + .atomic_check = ssd130x_primary_plane_atomic_check, + .atomic_update = ssd130x_primary_plane_atomic_update, + .atomic_disable = ssd130x_primary_plane_atomic_disable, + }, + [SSD132X_FAMILY] = { + DRM_GEM_SHADOW_PLANE_HELPER_FUNCS, + .atomic_check = ssd132x_primary_plane_atomic_check, + .atomic_update = ssd132x_primary_plane_atomic_update, + .atomic_disable = ssd132x_primary_plane_atomic_disable, + } }; static const struct drm_plane_funcs ssd130x_primary_plane_funcs = { @@ -814,8 +1153,7 @@ static int ssd130x_crtc_atomic_check(struct drm_crtc *crtc, struct ssd130x_device *ssd130x = drm_to_ssd130x(drm); struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc); struct ssd130x_crtc_state *ssd130x_state = to_ssd130x_crtc_state(crtc_state); - unsigned int page_height = ssd130x->device_info->page_height; - unsigned int pages = DIV_ROUND_UP(ssd130x->height, page_height); + unsigned int pages = DIV_ROUND_UP(ssd130x->height, SSD130X_PAGE_HEIGHT); int ret; ret = drm_crtc_helper_atomic_check(crtc, state); @@ -829,6 +1167,27 @@ static int ssd130x_crtc_atomic_check(struct drm_crtc *crtc, return 0; } +static int ssd132x_crtc_atomic_check(struct drm_crtc *crtc, + struct drm_atomic_state *state) +{ + struct drm_device *drm = crtc->dev; + struct ssd130x_device *ssd130x = drm_to_ssd130x(drm); + struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc); + struct ssd130x_crtc_state *ssd130x_state = to_ssd130x_crtc_state(crtc_state); + unsigned int columns = DIV_ROUND_UP(ssd130x->width, SSD132X_SEGMENT_WIDTH); + int ret; + + ret = drm_crtc_helper_atomic_check(crtc, state); + if (ret) + return ret; + + ssd130x_state->data_array = kmalloc(columns * ssd130x->height, GFP_KERNEL); + if (!ssd130x_state->data_array) + return -ENOMEM; + + return 0; +} + /* Called during init to allocate the CRTC's atomic state. */ static void ssd130x_crtc_reset(struct drm_crtc *crtc) { @@ -881,9 +1240,15 @@ static void ssd130x_crtc_destroy_state(struct drm_crtc *crtc, * the primary plane's atomic_update function. Disabling clears * the screen in the primary plane's atomic_disable function. */ -static const struct drm_crtc_helper_funcs ssd130x_crtc_helper_funcs = { - .mode_valid = ssd130x_crtc_mode_valid, - .atomic_check = ssd130x_crtc_atomic_check, +static const struct drm_crtc_helper_funcs ssd130x_crtc_helper_funcs[] = { + [SSD130X_FAMILY] = { + .mode_valid = ssd130x_crtc_mode_valid, + .atomic_check = ssd130x_crtc_atomic_check, + }, + [SSD132X_FAMILY] = { + .mode_valid = ssd130x_crtc_mode_valid, + .atomic_check = ssd132x_crtc_atomic_check, + }, }; static const struct drm_crtc_funcs ssd130x_crtc_funcs = { @@ -910,7 +1275,7 @@ static void ssd130x_encoder_atomic_enable(struct drm_encoder *encoder, if (ret) goto power_off; - ssd130x_write_cmd(ssd130x, 1, SSD130X_DISPLAY_ON); + ssd130x_write_cmd(ssd130x, 1, SSD13XX_DISPLAY_ON); backlight_enable(ssd130x->bl_dev); @@ -921,6 +1286,31 @@ power_off: return; } +static void ssd132x_encoder_atomic_enable(struct drm_encoder *encoder, + struct drm_atomic_state *state) +{ + struct drm_device *drm = encoder->dev; + struct ssd130x_device *ssd130x = drm_to_ssd130x(drm); + int ret; + + ret = ssd130x_power_on(ssd130x); + if (ret) + return; + + ret = ssd132x_init(ssd130x); + if (ret) + goto power_off; + + ssd130x_write_cmd(ssd130x, 1, SSD13XX_DISPLAY_ON); + + backlight_enable(ssd130x->bl_dev); + + return; + +power_off: + ssd130x_power_off(ssd130x); +} + static void ssd130x_encoder_atomic_disable(struct drm_encoder *encoder, struct drm_atomic_state *state) { @@ -929,14 +1319,20 @@ static void ssd130x_encoder_atomic_disable(struct drm_encoder *encoder, backlight_disable(ssd130x->bl_dev); - ssd130x_write_cmd(ssd130x, 1, SSD130X_DISPLAY_OFF); + ssd130x_write_cmd(ssd130x, 1, SSD13XX_DISPLAY_OFF); ssd130x_power_off(ssd130x); } -static const struct drm_encoder_helper_funcs ssd130x_encoder_helper_funcs = { - .atomic_enable = ssd130x_encoder_atomic_enable, - .atomic_disable = ssd130x_encoder_atomic_disable, +static const struct drm_encoder_helper_funcs ssd130x_encoder_helper_funcs[] = { + [SSD130X_FAMILY] = { + .atomic_enable = ssd130x_encoder_atomic_enable, + .atomic_disable = ssd130x_encoder_atomic_disable, + }, + [SSD132X_FAMILY] = { + .atomic_enable = ssd132x_encoder_atomic_enable, + .atomic_disable = ssd130x_encoder_atomic_disable, + } }; static const struct drm_encoder_funcs ssd130x_encoder_funcs = { @@ -1005,7 +1401,7 @@ static int ssd130x_update_bl(struct backlight_device *bdev) ssd130x->contrast = brightness; - ret = ssd130x_write_cmd(ssd130x, 1, SSD130X_CONTRAST); + ret = ssd130x_write_cmd(ssd130x, 1, SSD13XX_CONTRAST); if (ret < 0) return ret; @@ -1070,6 +1466,7 @@ static void ssd130x_parse_properties(struct ssd130x_device *ssd130x) static int ssd130x_init_modeset(struct ssd130x_device *ssd130x) { + enum ssd130x_family_ids family_id = ssd130x->device_info->family_id; struct drm_display_mode *mode = &ssd130x->mode; struct device *dev = ssd130x->dev; struct drm_device *drm = &ssd130x->drm; @@ -1120,7 +1517,7 @@ static int ssd130x_init_modeset(struct ssd130x_device *ssd130x) return ret; } - drm_plane_helper_add(primary_plane, &ssd130x_primary_plane_helper_funcs); + drm_plane_helper_add(primary_plane, &ssd130x_primary_plane_helper_funcs[family_id]); drm_plane_enable_fb_damage_clips(primary_plane); @@ -1134,7 +1531,7 @@ static int ssd130x_init_modeset(struct ssd130x_device *ssd130x) return ret; } - drm_crtc_helper_add(crtc, &ssd130x_crtc_helper_funcs); + drm_crtc_helper_add(crtc, &ssd130x_crtc_helper_funcs[family_id]); /* Encoder */ @@ -1146,7 +1543,7 @@ static int ssd130x_init_modeset(struct ssd130x_device *ssd130x) return ret; } - drm_encoder_helper_add(encoder, &ssd130x_encoder_helper_funcs); + drm_encoder_helper_add(encoder, &ssd130x_encoder_helper_funcs[family_id]); encoder->possible_crtcs = drm_crtc_mask(crtc); diff --git a/drivers/gpu/drm/solomon/ssd130x.h b/drivers/gpu/drm/solomon/ssd130x.h index aa39b13615eb..acf7cedf0c1a 100644 --- a/drivers/gpu/drm/solomon/ssd130x.h +++ b/drivers/gpu/drm/solomon/ssd130x.h @@ -21,15 +21,25 @@ #include <linux/regmap.h> -#define SSD130X_DATA 0x40 -#define SSD130X_COMMAND 0x80 +#define SSD13XX_DATA 0x40 +#define SSD13XX_COMMAND 0x80 + +enum ssd130x_family_ids { + SSD130X_FAMILY, + SSD132X_FAMILY +}; enum ssd130x_variants { + /* ssd130x family */ SH1106_ID, SSD1305_ID, SSD1306_ID, SSD1307_ID, SSD1309_ID, + /* ssd132x family */ + SSD1322_ID, + SSD1325_ID, + SSD1327_ID, NR_SSD130X_VARIANTS }; @@ -39,10 +49,11 @@ struct ssd130x_deviceinfo { u32 default_dclk_frq; u32 default_width; u32 default_height; - u32 page_height; bool need_pwm; bool need_chargepump; bool page_mode_only; + + enum ssd130x_family_ids family_id; }; struct ssd130x_device { diff --git a/drivers/gpu/drm/v3d/v3d_sched.c b/drivers/gpu/drm/v3d/v3d_sched.c index 06238e6d7f5c..038e1ae589c7 100644 --- a/drivers/gpu/drm/v3d/v3d_sched.c +++ b/drivers/gpu/drm/v3d/v3d_sched.c @@ -389,6 +389,7 @@ v3d_sched_init(struct v3d_dev *v3d) ret = drm_sched_init(&v3d->queue[V3D_BIN].sched, &v3d_bin_sched_ops, + DRM_SCHED_PRIORITY_COUNT, hw_jobs_limit, job_hang_limit, msecs_to_jiffies(hang_limit_ms), NULL, NULL, "v3d_bin", v3d->drm.dev); @@ -397,6 +398,7 @@ v3d_sched_init(struct v3d_dev *v3d) ret = drm_sched_init(&v3d->queue[V3D_RENDER].sched, &v3d_render_sched_ops, + DRM_SCHED_PRIORITY_COUNT, hw_jobs_limit, job_hang_limit, msecs_to_jiffies(hang_limit_ms), NULL, NULL, "v3d_render", v3d->drm.dev); @@ -405,6 +407,7 @@ v3d_sched_init(struct v3d_dev *v3d) ret = drm_sched_init(&v3d->queue[V3D_TFU].sched, &v3d_tfu_sched_ops, + DRM_SCHED_PRIORITY_COUNT, hw_jobs_limit, job_hang_limit, msecs_to_jiffies(hang_limit_ms), NULL, NULL, "v3d_tfu", v3d->drm.dev); @@ -414,6 +417,7 @@ v3d_sched_init(struct v3d_dev *v3d) if (v3d_has_csd(v3d)) { ret = drm_sched_init(&v3d->queue[V3D_CSD].sched, &v3d_csd_sched_ops, + DRM_SCHED_PRIORITY_COUNT, hw_jobs_limit, job_hang_limit, msecs_to_jiffies(hang_limit_ms), NULL, NULL, "v3d_csd", v3d->drm.dev); @@ -422,6 +426,7 @@ v3d_sched_init(struct v3d_dev *v3d) ret = drm_sched_init(&v3d->queue[V3D_CACHE_CLEAN].sched, &v3d_cache_clean_sched_ops, + DRM_SCHED_PRIORITY_COUNT, hw_jobs_limit, job_hang_limit, msecs_to_jiffies(hang_limit_ms), NULL, NULL, "v3d_cache_clean", v3d->drm.dev); diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h index f3763bd600f6..8ac9515554f8 100644 --- a/drivers/gpu/drm/vc4/vc4_regs.h +++ b/drivers/gpu/drm/vc4/vc4_regs.h @@ -588,7 +588,7 @@ enum { # define VC4_HDMI_HORZA_HAP_MASK VC4_MASK(12, 0) # define VC4_HDMI_HORZA_HAP_SHIFT 0 -/* Horizontal pack porch (htotal - hsync_end). */ +/* Horizontal back porch (htotal - hsync_end). */ # define VC4_HDMI_HORZB_HBP_MASK VC4_MASK(29, 20) # define VC4_HDMI_HORZB_HBP_SHIFT 20 /* Horizontal sync pulse (hsync_end - hsync_start). */ diff --git a/drivers/video/fbdev/68328fb.c b/drivers/video/fbdev/68328fb.c index 956dd2399cc0..c24156eb3d0f 100644 --- a/drivers/video/fbdev/68328fb.c +++ b/drivers/video/fbdev/68328fb.c @@ -95,13 +95,12 @@ static int mc68x328fb_mmap(struct fb_info *info, struct vm_area_struct *vma); static const struct fb_ops mc68x328fb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = mc68x328fb_check_var, .fb_set_par = mc68x328fb_set_par, .fb_setcolreg = mc68x328fb_setcolreg, .fb_pan_display = mc68x328fb_pan_display, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, + __FB_DEFAULT_IOMEM_OPS_DRAW, .fb_mmap = mc68x328fb_mmap, }; diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index e142b15862cb..20e0167bf20c 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -74,6 +74,7 @@ config FB_CIRRUS select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS select VIDEO_NOMODESET help This enables support for Cirrus Logic GD542x/543x based boards on @@ -93,6 +94,7 @@ config FB_PM2 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS select VIDEO_NOMODESET help This is the frame buffer device driver for cards based on @@ -118,9 +120,7 @@ config FB_ARMCLCD tristate "ARM PrimeCell PL110 support" depends on ARM || ARM64 || COMPILE_TEST depends on FB && ARM_AMBA && HAS_IOMEM - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT + select FB_IOMEM_HELPERS select FB_MODE_HELPERS if OF select VIDEOMODE_HELPERS if OF select BACKLIGHT_CLASS_DEVICE if OF @@ -159,9 +159,7 @@ config FB_CLPS711X config FB_SA1100 bool "SA-1100 LCD support" depends on (FB = y) && ARM && ARCH_SA1100 - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT + select FB_IOMEM_HELPERS help This is a framebuffer device for the SA-1100 LCD Controller. See <http://www.linux-fbdev.org/> for information on framebuffer @@ -185,6 +183,7 @@ config FB_CYBER2000 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS select VIDEO_NOMODESET help This enables support for the Integraphics CyberPro 20x0 and 5000 @@ -217,6 +216,7 @@ config FB_APOLLO default y select FB_CFB_FILLRECT select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS config FB_Q40 bool @@ -227,6 +227,7 @@ config FB_Q40 config FB_AMIGA tristate "Amiga native chipset support" depends on FB && AMIGA + select FB_IOMEM_FOPS help This is the frame buffer device driver for the builtin graphics chipset found in Amigas. @@ -290,6 +291,7 @@ config FB_ATARI select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS help This is the frame buffer device driver for the builtin graphics chipset found in Ataris. @@ -308,9 +310,7 @@ config FB_OF config FB_CONTROL bool "Apple \"control\" display support" depends on (FB = y) && ((PPC_PMAC && PPC32) || COMPILE_TEST) - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT + select FB_IOMEM_HELPERS select FB_MACMODES help This driver supports a frame buffer for the graphics adapter in the @@ -355,6 +355,7 @@ config FB_IMSTT bool "IMS Twin Turbo display support" depends on (FB = y) && PCI select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS select FB_MACMODES if PPC_PMAC select VIDEO_NOMODESET help @@ -368,6 +369,7 @@ config FB_VGA16 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS select VGASTATE select FONT_8x16 if FRAMEBUFFER_CONSOLE help @@ -383,6 +385,7 @@ config FB_STI select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS select STI_CORE default y help @@ -406,6 +409,7 @@ config FB_HP300 bool depends on (FB = y) && DIO select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS default y config FB_TGA @@ -413,10 +417,11 @@ config FB_TGA depends on FB depends on PCI || TC depends on ALPHA || TC + select BITREVERSE select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select BITREVERSE + select FB_IOMEM_FOPS select VIDEO_NOMODESET help This is the frame buffer device driver for generic TGA and SFB+ @@ -484,6 +489,7 @@ config FB_N411 config FB_HGA tristate "Hercules mono graphics support" depends on FB && X86 + select FB_IOMEM_FOPS help Say Y here if you have a Hercules mono graphics card. @@ -497,9 +503,7 @@ config FB_GBE bool "SGI Graphics Backend frame buffer support" depends on (FB = y) && HAS_IOMEM depends on SGI_IP32 || COMPILE_TEST - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT + select FB_IOMEM_HELPERS help This is the frame buffer device driver for SGI Graphics Backend. This chip is used in SGI O2 and Visual Workstation 320/540. @@ -594,6 +598,7 @@ config FB_XVR500 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS select VIDEO_NOMODESET help This is the framebuffer device for the Sun XVR-500 and similar @@ -631,6 +636,7 @@ config FB_PVR2 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS select VIDEO_NOMODESET help Say Y here if you have a PowerVR 2 card in your box. If you plan to @@ -667,6 +673,7 @@ config FB_S1D13XXX select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS help Support for S1D13XXX framebuffer device family (currently only working with S1D13806). Product specs at @@ -687,10 +694,10 @@ config FB_NVIDIA tristate "nVidia Framebuffer Support" depends on FB && PCI select FB_BACKLIGHT if FB_NVIDIA_BACKLIGHT - select FB_MODE_HELPERS select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS select BITREVERSE select VGASTATE select VIDEO_NOMODESET @@ -735,10 +742,11 @@ config FB_RIVA tristate "nVidia Riva support" depends on FB && PCI select FB_BACKLIGHT if FB_RIVA_BACKLIGHT - select FB_MODE_HELPERS select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS + select FB_MODE_HELPERS select BITREVERSE select VGASTATE select VIDEO_NOMODESET @@ -792,10 +800,8 @@ config FB_I740 config FB_I810 tristate "Intel 810/815 support" depends on FB && PCI && X86_32 && AGP_INTEL + select FB_IOMEM_FOPS select FB_MODE_HELPERS - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT select VGASTATE select VIDEO_NOMODESET help @@ -844,10 +850,8 @@ config FB_I810_I2C config FB_LE80578 tristate "Intel LE80578 (Vermilion) support" depends on FB && PCI && X86 + select FB_IOMEM_HELPERS select FB_MODE_HELPERS - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT select VIDEO_NOMODESET help This driver supports the LE80578 (Vermilion Range) chipset @@ -861,10 +865,11 @@ config FB_CARILLO_RANCH config FB_INTEL tristate "Intel 830M/845G/852GM/855GM/865G/915G/945G/945GM/965G/965GM support" depends on FB && PCI && X86 && AGP_INTEL && EXPERT - select FB_MODE_HELPERS select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS + select FB_MODE_HELPERS select BOOT_VESA_SUPPORT if FB_INTEL = y select VIDEO_NOMODESET depends on !DRM_I915 @@ -902,6 +907,7 @@ config FB_MATROX select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS select FB_TILEBLITTING select FB_MACMODES if PPC_PMAC select VIDEO_NOMODESET @@ -988,6 +994,7 @@ config FB_MATROX_I2C config FB_MATROX_MAVEN tristate "G400 second head support" depends on FB_MATROX_G && FB_MATROX_I2C + select FB_IOMEM_HELPERS help WARNING !!! This support does not work with G450 !!! @@ -1020,11 +1027,12 @@ config FB_RADEON tristate "ATI Radeon display support" depends on FB && PCI select FB_BACKLIGHT if FB_RADEON_BACKLIGHT - select FB_MODE_HELPERS select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS select FB_MACMODES if PPC + select FB_MODE_HELPERS select VIDEO_NOMODESET help Choose this option if you want to use an ATI Radeon graphics card as @@ -1086,6 +1094,7 @@ config FB_ATY select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT select FB_BACKLIGHT if FB_ATY_BACKLIGHT + select FB_IOMEM_FOPS select FB_MACMODES if PPC select FB_ATY_CT if SPARC64 && PCI select VIDEO_NOMODESET @@ -1136,6 +1145,7 @@ config FB_S3 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS select FB_TILEBLITTING select FB_SVGALIB select VGASTATE @@ -1155,10 +1165,11 @@ config FB_S3_DDC config FB_SAVAGE tristate "S3 Savage support" depends on FB && PCI - select FB_MODE_HELPERS select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS + select FB_MODE_HELPERS select VGASTATE select VIDEO_NOMODESET help @@ -1194,10 +1205,11 @@ config FB_SAVAGE_ACCEL config FB_SIS tristate "SiS/XGI display support" depends on FB && PCI + select BOOT_VESA_SUPPORT if FB_SIS = y select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select BOOT_VESA_SUPPORT if FB_SIS = y + select FB_IOMEM_FOPS select FB_SIS_300 if !FB_SIS_315 select VIDEO_NOMODESET help @@ -1228,6 +1240,7 @@ config FB_VIA select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS select I2C_ALGOBIT select VIDEO_NOMODESET help @@ -1264,10 +1277,11 @@ endif config FB_NEOMAGIC tristate "NeoMagic display support" depends on FB && PCI - select FB_MODE_HELPERS select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS + select FB_MODE_HELPERS select VGASTATE select VIDEO_NOMODESET help @@ -1292,9 +1306,10 @@ config FB_KYRO config FB_3DFX tristate "3Dfx Banshee/Voodoo3/Voodoo5 display support" depends on FB && PCI - select FB_CFB_IMAGEBLIT select FB_CFB_FILLRECT select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS select FB_MODE_HELPERS select VIDEO_NOMODESET help @@ -1344,6 +1359,7 @@ config FB_VT8623 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS select FB_TILEBLITTING select FB_SVGALIB select VGASTATE @@ -1360,6 +1376,7 @@ config FB_TRIDENT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT select FB_DDC + select FB_IOMEM_FOPS select FB_MODE_HELPERS select VIDEO_NOMODESET help @@ -1382,6 +1399,7 @@ config FB_ARK select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS select FB_TILEBLITTING select FB_SVGALIB select VGASTATE @@ -1397,6 +1415,7 @@ config FB_PM3 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS select VIDEO_NOMODESET help This is the frame buffer device driver for the 3DLabs Permedia3 @@ -1432,9 +1451,7 @@ endchoice config FB_AU1100 bool "Au1100 LCD Driver" depends on (FB = y) && MIPS_ALCHEMY - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT + select FB_IOMEM_HELPERS help This is the framebuffer driver for the AMD Au1100 SOC. It can drive various panels and CRTs by passing in kernel cmd line option @@ -1490,8 +1507,8 @@ config FB_HIT tristate "HD64461 Frame Buffer support" depends on FB && HD64461 select FB_CFB_FILLRECT - select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS help This is the frame buffer device driver for the Hitachi HD64461 LCD frame buffer card. @@ -1541,9 +1558,7 @@ config FB_G364 config FB_68328 bool "Motorola 68328 native frame buffer support" depends on (FB = y) && (M68328 || M68EZ328 || M68VZ328) - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT + select FB_IOMEM_HELPERS help Say Y here if you want to support the built-in frame buffer of the Motorola 68328 CPU family. @@ -1658,6 +1673,7 @@ config FB_SM501 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS help Frame buffer driver for the CRT and LCD controllers in the Silicon Motion SM501. @@ -1753,6 +1769,7 @@ config FB_GOLDFISH config FB_COBALT tristate "Cobalt server LCD frame buffer support" depends on FB && MIPS_COBALT + select FB_IOMEM_HELPERS config FB_SH7760 bool "SH7760/SH7763/SH7720/SH7721 LCDC support" @@ -1866,9 +1883,7 @@ config FB_MB862XX_I2C config FB_EP93XX tristate "EP93XX frame buffer support" depends on FB && ARCH_EP93XX - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT + select FB_IOMEM_HELPERS help Framebuffer driver for the Cirrus Logic EP93XX series of processors. This driver is also available as a module. The module will be called @@ -1929,9 +1944,7 @@ config FB_SSD1307 config FB_SM712 tristate "Silicon Motion SM712 framebuffer support" depends on FB && PCI - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT + select FB_IOMEM_HELPERS select VIDEO_NOMODESET help Frame buffer driver for the Silicon Motion SM710, SM712, SM721 diff --git a/drivers/video/fbdev/amba-clcd.c b/drivers/video/fbdev/amba-clcd.c index 24d89e6fb780..0399db369e70 100644 --- a/drivers/video/fbdev/amba-clcd.c +++ b/drivers/video/fbdev/amba-clcd.c @@ -412,13 +412,12 @@ static int clcdfb_mmap(struct fb_info *info, static const struct fb_ops clcdfb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = clcdfb_check_var, .fb_set_par = clcdfb_set_par, .fb_setcolreg = clcdfb_setcolreg, .fb_blank = clcdfb_blank, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, + __FB_DEFAULT_IOMEM_OPS_DRAW, .fb_mmap = clcdfb_mmap, }; diff --git a/drivers/video/fbdev/amifb.c b/drivers/video/fbdev/amifb.c index 441e7a8dbe58..b18c6b4f129a 100644 --- a/drivers/video/fbdev/amifb.c +++ b/drivers/video/fbdev/amifb.c @@ -3488,6 +3488,7 @@ static irqreturn_t amifb_interrupt(int irq, void *dev_id) static const struct fb_ops amifb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = amifb_check_var, .fb_set_par = amifb_set_par, .fb_setcolreg = amifb_setcolreg, @@ -3497,6 +3498,7 @@ static const struct fb_ops amifb_ops = { .fb_copyarea = amifb_copyarea, .fb_imageblit = amifb_imageblit, .fb_ioctl = amifb_ioctl, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; diff --git a/drivers/video/fbdev/arkfb.c b/drivers/video/fbdev/arkfb.c index 60a96fdb5dd8..dca9c0325b3f 100644 --- a/drivers/video/fbdev/arkfb.c +++ b/drivers/video/fbdev/arkfb.c @@ -924,6 +924,7 @@ static const struct fb_ops arkfb_ops = { .owner = THIS_MODULE, .fb_open = arkfb_open, .fb_release = arkfb_release, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = arkfb_check_var, .fb_set_par = arkfb_set_par, .fb_setcolreg = arkfb_setcolreg, @@ -932,6 +933,7 @@ static const struct fb_ops arkfb_ops = { .fb_fillrect = arkfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = arkfb_imageblit, + __FB_DEFAULT_IOMEM_OPS_MMAP, .fb_get_caps = svga_get_caps, }; diff --git a/drivers/video/fbdev/atafb.c b/drivers/video/fbdev/atafb.c index c4a420b791b9..b8ed1c537293 100644 --- a/drivers/video/fbdev/atafb.c +++ b/drivers/video/fbdev/atafb.c @@ -2665,6 +2665,7 @@ static int atafb_set_par(struct fb_info *info) static struct fb_ops atafb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = atafb_check_var, .fb_set_par = atafb_set_par, .fb_blank = atafb_blank, @@ -2673,6 +2674,7 @@ static struct fb_ops atafb_ops = { .fb_copyarea = atafb_copyarea, .fb_imageblit = atafb_imageblit, .fb_ioctl = atafb_ioctl, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; static void check_default_par(int detected_mode) diff --git a/drivers/video/fbdev/aty/atyfb_base.c b/drivers/video/fbdev/aty/atyfb_base.c index 3dcf83f5e7b4..a6dd1cd27125 100644 --- a/drivers/video/fbdev/aty/atyfb_base.c +++ b/drivers/video/fbdev/aty/atyfb_base.c @@ -301,6 +301,7 @@ static struct fb_ops atyfb_ops = { .owner = THIS_MODULE, .fb_open = atyfb_open, .fb_release = atyfb_release, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = atyfb_check_var, .fb_set_par = atyfb_set_par, .fb_setcolreg = atyfb_setcolreg, @@ -315,6 +316,8 @@ static struct fb_ops atyfb_ops = { .fb_imageblit = atyfb_imageblit, #ifdef __sparc__ .fb_mmap = atyfb_mmap, +#else + __FB_DEFAULT_IOMEM_OPS_MMAP, #endif .fb_sync = atyfb_sync, }; diff --git a/drivers/video/fbdev/aty/radeon_base.c b/drivers/video/fbdev/aty/radeon_base.c index 93fd1773402c..36bfb6deb8ab 100644 --- a/drivers/video/fbdev/aty/radeon_base.c +++ b/drivers/video/fbdev/aty/radeon_base.c @@ -1952,6 +1952,7 @@ static int radeonfb_set_par(struct fb_info *info) static const struct fb_ops radeonfb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = radeonfb_check_var, .fb_set_par = radeonfb_set_par, .fb_setcolreg = radeonfb_setcolreg, @@ -1963,6 +1964,7 @@ static const struct fb_ops radeonfb_ops = { .fb_fillrect = radeonfb_fillrect, .fb_copyarea = radeonfb_copyarea, .fb_imageblit = radeonfb_imageblit, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; diff --git a/drivers/video/fbdev/au1100fb.c b/drivers/video/fbdev/au1100fb.c index 648d6cac86e8..a9c8d33a6ef7 100644 --- a/drivers/video/fbdev/au1100fb.c +++ b/drivers/video/fbdev/au1100fb.c @@ -348,15 +348,13 @@ int au1100fb_fb_mmap(struct fb_info *fbi, struct vm_area_struct *vma) fbdev->fb_len); } -static const struct fb_ops au1100fb_ops = -{ +static const struct fb_ops au1100fb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_setcolreg = au1100fb_fb_setcolreg, .fb_blank = au1100fb_fb_blank, .fb_pan_display = au1100fb_fb_pan_display, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, + __FB_DEFAULT_IOMEM_OPS_DRAW, .fb_mmap = au1100fb_fb_mmap, }; diff --git a/drivers/video/fbdev/cirrusfb.c b/drivers/video/fbdev/cirrusfb.c index 9d369b6a4dcc..e29217e476ea 100644 --- a/drivers/video/fbdev/cirrusfb.c +++ b/drivers/video/fbdev/cirrusfb.c @@ -1961,6 +1961,7 @@ static const struct fb_ops cirrusfb_ops = { .owner = THIS_MODULE, .fb_open = cirrusfb_open, .fb_release = cirrusfb_release, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_setcolreg = cirrusfb_setcolreg, .fb_check_var = cirrusfb_check_var, .fb_set_par = cirrusfb_set_par, @@ -1970,6 +1971,7 @@ static const struct fb_ops cirrusfb_ops = { .fb_copyarea = cirrusfb_copyarea, .fb_sync = cirrusfb_sync, .fb_imageblit = cirrusfb_imageblit, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; static int cirrusfb_set_fbinfo(struct fb_info *info) diff --git a/drivers/video/fbdev/cobalt_lcdfb.c b/drivers/video/fbdev/cobalt_lcdfb.c index b94e7c97264c..c2b8f894799c 100644 --- a/drivers/video/fbdev/cobalt_lcdfb.c +++ b/drivers/video/fbdev/cobalt_lcdfb.c @@ -280,7 +280,9 @@ static const struct fb_ops cobalt_lcd_fbops = { .fb_read = cobalt_lcdfb_read, .fb_write = cobalt_lcdfb_write, .fb_blank = cobalt_lcdfb_blank, + __FB_DEFAULT_IOMEM_OPS_DRAW, .fb_cursor = cobalt_lcdfb_cursor, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; static int cobalt_lcdfb_probe(struct platform_device *dev) diff --git a/drivers/video/fbdev/controlfb.c b/drivers/video/fbdev/controlfb.c index 717134c141ff..5c5284e8ae0e 100644 --- a/drivers/video/fbdev/controlfb.c +++ b/drivers/video/fbdev/controlfb.c @@ -755,15 +755,14 @@ static int controlfb_mmap(struct fb_info *info, static const struct fb_ops controlfb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = controlfb_check_var, .fb_set_par = controlfb_set_par, .fb_setcolreg = controlfb_setcolreg, .fb_pan_display = controlfb_pan_display, .fb_blank = controlfb_blank, + __FB_DEFAULT_IOMEM_OPS_DRAW, .fb_mmap = controlfb_mmap, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, }; /* diff --git a/drivers/video/fbdev/core/Kconfig b/drivers/video/fbdev/core/Kconfig index 756c8603cf39..7a3ed13bed70 100644 --- a/drivers/video/fbdev/core/Kconfig +++ b/drivers/video/fbdev/core/Kconfig @@ -4,6 +4,7 @@ # config FB_CORE + select FB_IOMEM_FOPS select VIDEO_CMDLINE tristate @@ -144,12 +145,17 @@ config FB_DMAMEM_HELPERS select FB_SYS_FOPS select FB_SYS_IMAGEBLIT +config FB_IOMEM_FOPS + tristate + depends on FB_CORE + config FB_IOMEM_HELPERS bool depends on FB_CORE select FB_CFB_COPYAREA select FB_CFB_FILLRECT select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS config FB_IOMEM_HELPERS_DEFERRED bool diff --git a/drivers/video/fbdev/core/Makefile b/drivers/video/fbdev/core/Makefile index 36d3156dc759..c1d657601b2b 100644 --- a/drivers/video/fbdev/core/Makefile +++ b/drivers/video/fbdev/core/Makefile @@ -3,7 +3,7 @@ obj-$(CONFIG_FB_NOTIFY) += fb_notify.o obj-$(CONFIG_FB_CORE) += fb.o fb-y := fb_info.o \ fbmem.o fbcmap.o \ - modedb.o fbcvt.o fb_cmdline.o fb_io_fops.o + modedb.o fbcvt.o fb_cmdline.o ifdef CONFIG_FB fb-y += fb_backlight.o fbmon.o endif @@ -28,6 +28,7 @@ fb-$(CONFIG_LOGO) += fb_logo.o obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o obj-$(CONFIG_FB_CFB_COPYAREA) += cfbcopyarea.o obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o +obj-$(CONFIG_FB_IOMEM_FOPS) += fb_io_fops.o obj-$(CONFIG_FB_SYS_FILLRECT) += sysfillrect.o obj-$(CONFIG_FB_SYS_COPYAREA) += syscopyarea.o obj-$(CONFIG_FB_SYS_IMAGEBLIT) += sysimgblt.o diff --git a/drivers/video/fbdev/core/fb_io_fops.c b/drivers/video/fbdev/core/fb_io_fops.c index 5985e5e1b040..871b829521af 100644 --- a/drivers/video/fbdev/core/fb_io_fops.c +++ b/drivers/video/fbdev/core/fb_io_fops.c @@ -131,3 +131,6 @@ ssize_t fb_io_write(struct fb_info *info, const char __user *buf, size_t count, return (cnt) ? cnt : err; } EXPORT_SYMBOL(fb_io_write); + +MODULE_DESCRIPTION("Fbdev helpers for framebuffers in I/O memory"); +MODULE_LICENSE("GPL"); diff --git a/drivers/video/fbdev/cyber2000fb.c b/drivers/video/fbdev/cyber2000fb.c index 98ea56a9abf1..52105dc1a72f 100644 --- a/drivers/video/fbdev/cyber2000fb.c +++ b/drivers/video/fbdev/cyber2000fb.c @@ -1061,6 +1061,7 @@ static int cyber2000fb_blank(int blank, struct fb_info *info) static const struct fb_ops cyber2000fb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = cyber2000fb_check_var, .fb_set_par = cyber2000fb_set_par, .fb_setcolreg = cyber2000fb_setcolreg, @@ -1070,6 +1071,7 @@ static const struct fb_ops cyber2000fb_ops = { .fb_copyarea = cyber2000fb_copyarea, .fb_imageblit = cyber2000fb_imageblit, .fb_sync = cyber2000fb_sync, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; /* diff --git a/drivers/video/fbdev/dnfb.c b/drivers/video/fbdev/dnfb.c index 18405c402ec1..c4d24540d9ef 100644 --- a/drivers/video/fbdev/dnfb.c +++ b/drivers/video/fbdev/dnfb.c @@ -110,10 +110,12 @@ static void dnfb_copyarea(struct fb_info *info, const struct fb_copyarea *area); static const struct fb_ops dn_fb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_blank = dnfb_blank, .fb_fillrect = cfb_fillrect, .fb_copyarea = dnfb_copyarea, .fb_imageblit = cfb_imageblit, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; static const struct fb_var_screeninfo dnfb_var = { diff --git a/drivers/video/fbdev/ep93xx-fb.c b/drivers/video/fbdev/ep93xx-fb.c index d94e3e8d14a1..cae00deee001 100644 --- a/drivers/video/fbdev/ep93xx-fb.c +++ b/drivers/video/fbdev/ep93xx-fb.c @@ -404,12 +404,11 @@ static int ep93xxfb_setcolreg(unsigned int regno, unsigned int red, static const struct fb_ops ep93xxfb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = ep93xxfb_check_var, .fb_set_par = ep93xxfb_set_par, .fb_blank = ep93xxfb_blank, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, + __FB_DEFAULT_IOMEM_OPS_DRAW, .fb_setcolreg = ep93xxfb_setcolreg, .fb_mmap = ep93xxfb_mmap, }; diff --git a/drivers/video/fbdev/gbefb.c b/drivers/video/fbdev/gbefb.c index 4fccdccbc364..e89e5579258e 100644 --- a/drivers/video/fbdev/gbefb.c +++ b/drivers/video/fbdev/gbefb.c @@ -1044,14 +1044,13 @@ static int gbefb_mmap(struct fb_info *info, static const struct fb_ops gbefb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = gbefb_check_var, .fb_set_par = gbefb_set_par, .fb_setcolreg = gbefb_setcolreg, - .fb_mmap = gbefb_mmap, .fb_blank = gbefb_blank, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, + __FB_DEFAULT_IOMEM_OPS_DRAW, + .fb_mmap = gbefb_mmap, }; /* diff --git a/drivers/video/fbdev/hgafb.c b/drivers/video/fbdev/hgafb.c index 6a64e6d7255e..10728259dac2 100644 --- a/drivers/video/fbdev/hgafb.c +++ b/drivers/video/fbdev/hgafb.c @@ -532,12 +532,14 @@ static const struct fb_ops hgafb_ops = { .owner = THIS_MODULE, .fb_open = hgafb_open, .fb_release = hgafb_release, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_setcolreg = hgafb_setcolreg, .fb_pan_display = hgafb_pan_display, .fb_blank = hgafb_blank, .fb_fillrect = hgafb_fillrect, .fb_copyarea = hgafb_copyarea, .fb_imageblit = hgafb_imageblit, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; /* ------------------------------------------------------------------------- * diff --git a/drivers/video/fbdev/hitfb.c b/drivers/video/fbdev/hitfb.c index 17715eaf0673..b64b74b76c71 100644 --- a/drivers/video/fbdev/hitfb.c +++ b/drivers/video/fbdev/hitfb.c @@ -328,8 +328,9 @@ static int hitfb_set_par(struct fb_info *info) static const struct fb_ops hitfb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = hitfb_check_var, - .fb_set_par = hitfb_set_par, + .fb_set_par = hitfb_set_par, .fb_setcolreg = hitfb_setcolreg, .fb_blank = hitfb_blank, .fb_sync = hitfb_sync, @@ -337,6 +338,7 @@ static const struct fb_ops hitfb_ops = { .fb_fillrect = hitfb_fillrect, .fb_copyarea = hitfb_copyarea, .fb_imageblit = cfb_imageblit, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; static int hitfb_probe(struct platform_device *dev) diff --git a/drivers/video/fbdev/hpfb.c b/drivers/video/fbdev/hpfb.c index 406c1383cbda..66fac8e5393e 100644 --- a/drivers/video/fbdev/hpfb.c +++ b/drivers/video/fbdev/hpfb.c @@ -186,12 +186,14 @@ static int hpfb_sync(struct fb_info *info) static const struct fb_ops hpfb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_setcolreg = hpfb_setcolreg, .fb_blank = hpfb_blank, .fb_fillrect = hpfb_fillrect, .fb_copyarea = hpfb_copyarea, .fb_imageblit = cfb_imageblit, .fb_sync = hpfb_sync, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; /* Common to all HP framebuffers */ diff --git a/drivers/video/fbdev/i810/i810_main.c b/drivers/video/fbdev/i810/i810_main.c index f5511bb4fadc..d73a795fe1be 100644 --- a/drivers/video/fbdev/i810/i810_main.c +++ b/drivers/video/fbdev/i810/i810_main.c @@ -1547,6 +1547,7 @@ static const struct fb_ops i810fb_ops = { .owner = THIS_MODULE, .fb_open = i810fb_open, .fb_release = i810fb_release, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = i810fb_check_var, .fb_set_par = i810fb_set_par, .fb_setcolreg = i810fb_setcolreg, @@ -1557,6 +1558,7 @@ static const struct fb_ops i810fb_ops = { .fb_imageblit = i810fb_imageblit, .fb_cursor = i810fb_cursor, .fb_sync = i810fb_sync, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; /*********************************************************************** diff --git a/drivers/video/fbdev/imsttfb.c b/drivers/video/fbdev/imsttfb.c index f4c8677488fb..e7e03e920729 100644 --- a/drivers/video/fbdev/imsttfb.c +++ b/drivers/video/fbdev/imsttfb.c @@ -1336,6 +1336,7 @@ static struct pci_driver imsttfb_pci_driver = { static const struct fb_ops imsttfb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = imsttfb_check_var, .fb_set_par = imsttfb_set_par, .fb_setcolreg = imsttfb_setcolreg, @@ -1345,6 +1346,7 @@ static const struct fb_ops imsttfb_ops = { .fb_copyarea = imsttfb_copyarea, .fb_imageblit = cfb_imageblit, .fb_ioctl = imsttfb_ioctl, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; static int init_imstt(struct fb_info *info) diff --git a/drivers/video/fbdev/intelfb/intelfbdrv.c b/drivers/video/fbdev/intelfb/intelfbdrv.c index 3d334f171959..d29d80a16295 100644 --- a/drivers/video/fbdev/intelfb/intelfbdrv.c +++ b/drivers/video/fbdev/intelfb/intelfbdrv.c @@ -198,6 +198,7 @@ static const struct fb_ops intel_fb_ops = { .owner = THIS_MODULE, .fb_open = intelfb_open, .fb_release = intelfb_release, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = intelfb_check_var, .fb_set_par = intelfb_set_par, .fb_setcolreg = intelfb_setcolreg, @@ -208,7 +209,8 @@ static const struct fb_ops intel_fb_ops = { .fb_imageblit = intelfb_imageblit, .fb_cursor = intelfb_cursor, .fb_sync = intelfb_sync, - .fb_ioctl = intelfb_ioctl + .fb_ioctl = intelfb_ioctl, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; /* PCI driver module table */ diff --git a/drivers/video/fbdev/matrox/matroxfb_base.c b/drivers/video/fbdev/matrox/matroxfb_base.c index a043a737ea9f..81603ce05a22 100644 --- a/drivers/video/fbdev/matrox/matroxfb_base.c +++ b/drivers/video/fbdev/matrox/matroxfb_base.c @@ -1204,6 +1204,7 @@ static const struct fb_ops matroxfb_ops = { .owner = THIS_MODULE, .fb_open = matroxfb_open, .fb_release = matroxfb_release, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = matroxfb_check_var, .fb_set_par = matroxfb_set_par, .fb_setcolreg = matroxfb_setcolreg, @@ -1214,6 +1215,7 @@ static const struct fb_ops matroxfb_ops = { /* .fb_copyarea = <set by matrox_cfbX_init>, */ /* .fb_imageblit = <set by matrox_cfbX_init>, */ /* .fb_cursor = <set by matrox_cfbX_init>, */ + __FB_DEFAULT_IOMEM_OPS_MMAP, }; #define RSDepth(X) (((X) >> 8) & 0x0F) diff --git a/drivers/video/fbdev/matrox/matroxfb_crtc2.c b/drivers/video/fbdev/matrox/matroxfb_crtc2.c index 372197c124de..417fc692468d 100644 --- a/drivers/video/fbdev/matrox/matroxfb_crtc2.c +++ b/drivers/video/fbdev/matrox/matroxfb_crtc2.c @@ -567,15 +567,13 @@ static const struct fb_ops matroxfb_dh_ops = { .owner = THIS_MODULE, .fb_open = matroxfb_dh_open, .fb_release = matroxfb_dh_release, + FB_DEFAULT_IOMEM_OPS, .fb_check_var = matroxfb_dh_check_var, .fb_set_par = matroxfb_dh_set_par, .fb_setcolreg = matroxfb_dh_setcolreg, .fb_pan_display =matroxfb_dh_pan_display, .fb_blank = matroxfb_dh_blank, .fb_ioctl = matroxfb_dh_ioctl, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, }; static struct fb_var_screeninfo matroxfb_dh_defined = { diff --git a/drivers/video/fbdev/neofb.c b/drivers/video/fbdev/neofb.c index b58b11015c0c..632ba2455913 100644 --- a/drivers/video/fbdev/neofb.c +++ b/drivers/video/fbdev/neofb.c @@ -1614,6 +1614,7 @@ static const struct fb_ops neofb_ops = { .owner = THIS_MODULE, .fb_open = neofb_open, .fb_release = neofb_release, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = neofb_check_var, .fb_set_par = neofb_set_par, .fb_setcolreg = neofb_setcolreg, @@ -1623,6 +1624,7 @@ static const struct fb_ops neofb_ops = { .fb_fillrect = neofb_fillrect, .fb_copyarea = neofb_copyarea, .fb_imageblit = neofb_imageblit, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; /* --------------------------------------------------------------------- */ diff --git a/drivers/video/fbdev/nvidia/nvidia.c b/drivers/video/fbdev/nvidia/nvidia.c index 907c22408652..8900f181f195 100644 --- a/drivers/video/fbdev/nvidia/nvidia.c +++ b/drivers/video/fbdev/nvidia/nvidia.c @@ -1028,6 +1028,7 @@ static struct fb_ops nvidia_fb_ops = { .owner = THIS_MODULE, .fb_open = nvidiafb_open, .fb_release = nvidiafb_release, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = nvidiafb_check_var, .fb_set_par = nvidiafb_set_par, .fb_setcolreg = nvidiafb_setcolreg, @@ -1038,6 +1039,7 @@ static struct fb_ops nvidia_fb_ops = { .fb_imageblit = nvidiafb_imageblit, .fb_cursor = nvidiafb_cursor, .fb_sync = nvidiafb_sync, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; static int nvidiafb_suspend_late(struct device *dev, pm_message_t mesg) diff --git a/drivers/video/fbdev/omap2/omapfb/Kconfig b/drivers/video/fbdev/omap2/omapfb/Kconfig index 21069fdb7cc2..f4cdf999a080 100644 --- a/drivers/video/fbdev/omap2/omapfb/Kconfig +++ b/drivers/video/fbdev/omap2/omapfb/Kconfig @@ -10,9 +10,7 @@ menuconfig FB_OMAP2 depends on GPIOLIB select FB_OMAP2_DSS select OMAP2_VRFB if ARCH_OMAP2 || ARCH_OMAP3 - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT + select FB_IOMEM_HELPERS help Frame buffer driver for OMAP2+ based boards. diff --git a/drivers/video/fbdev/omap2/omapfb/omapfb-main.c b/drivers/video/fbdev/omap2/omapfb/omapfb-main.c index b5acad8eb279..c9fd0ad352d7 100644 --- a/drivers/video/fbdev/omap2/omapfb/omapfb-main.c +++ b/drivers/video/fbdev/omap2/omapfb/omapfb-main.c @@ -1280,10 +1280,9 @@ static const struct fb_ops omapfb_ops = { .owner = THIS_MODULE, .fb_open = omapfb_open, .fb_release = omapfb_release, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_blank = omapfb_blank, + __FB_DEFAULT_IOMEM_OPS_DRAW, .fb_ioctl = omapfb_ioctl, .fb_check_var = omapfb_check_var, .fb_set_par = omapfb_set_par, diff --git a/drivers/video/fbdev/pm2fb.c b/drivers/video/fbdev/pm2fb.c index 5a79a12efd8e..f34429829b7d 100644 --- a/drivers/video/fbdev/pm2fb.c +++ b/drivers/video/fbdev/pm2fb.c @@ -1492,6 +1492,7 @@ static int pm2fb_cursor(struct fb_info *info, struct fb_cursor *cursor) static const struct fb_ops pm2fb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = pm2fb_check_var, .fb_set_par = pm2fb_set_par, .fb_setcolreg = pm2fb_setcolreg, @@ -1502,6 +1503,7 @@ static const struct fb_ops pm2fb_ops = { .fb_imageblit = pm2fb_imageblit, .fb_sync = pm2fb_sync, .fb_cursor = pm2fb_cursor, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; /* diff --git a/drivers/video/fbdev/pm3fb.c b/drivers/video/fbdev/pm3fb.c index 16577d0e41b1..6e55e42514d6 100644 --- a/drivers/video/fbdev/pm3fb.c +++ b/drivers/video/fbdev/pm3fb.c @@ -1203,6 +1203,7 @@ static int pm3fb_blank(int blank_mode, struct fb_info *info) static const struct fb_ops pm3fb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = pm3fb_check_var, .fb_set_par = pm3fb_set_par, .fb_setcolreg = pm3fb_setcolreg, @@ -1213,6 +1214,7 @@ static const struct fb_ops pm3fb_ops = { .fb_blank = pm3fb_blank, .fb_sync = pm3fb_sync, .fb_cursor = pm3fb_cursor, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; /* ------------------------------------------------------------------------- */ diff --git a/drivers/video/fbdev/pvr2fb.c b/drivers/video/fbdev/pvr2fb.c index 6307364e4a49..cbdb1caf61bd 100644 --- a/drivers/video/fbdev/pvr2fb.c +++ b/drivers/video/fbdev/pvr2fb.c @@ -725,16 +725,18 @@ out_unmap: static const struct fb_ops pvr2fb_ops = { .owner = THIS_MODULE, +#ifdef CONFIG_PVR2_DMA + .fb_read = fb_io_read, + .fb_write = pvr2fb_write, +#else + __FB_DEFAULT_IOMEM_OPS_RDWR, +#endif .fb_setcolreg = pvr2fb_setcolreg, .fb_blank = pvr2fb_blank, + __FB_DEFAULT_IOMEM_OPS_DRAW, .fb_check_var = pvr2fb_check_var, .fb_set_par = pvr2fb_set_par, -#ifdef CONFIG_PVR2_DMA - .fb_write = pvr2fb_write, -#endif - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; #ifndef MODULE diff --git a/drivers/video/fbdev/riva/fbdev.c b/drivers/video/fbdev/riva/fbdev.c index 99576ba3ce6e..237db738af13 100644 --- a/drivers/video/fbdev/riva/fbdev.c +++ b/drivers/video/fbdev/riva/fbdev.c @@ -1670,6 +1670,7 @@ static const struct fb_ops riva_fb_ops = { .owner = THIS_MODULE, .fb_open = rivafb_open, .fb_release = rivafb_release, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = rivafb_check_var, .fb_set_par = rivafb_set_par, .fb_setcolreg = rivafb_setcolreg, @@ -1680,6 +1681,7 @@ static const struct fb_ops riva_fb_ops = { .fb_imageblit = rivafb_imageblit, .fb_cursor = rivafb_cursor, .fb_sync = rivafb_sync, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; static int riva_set_fbinfo(struct fb_info *info) diff --git a/drivers/video/fbdev/s1d13xxxfb.c b/drivers/video/fbdev/s1d13xxxfb.c index c7d221cce06d..0e871197c6de 100644 --- a/drivers/video/fbdev/s1d13xxxfb.c +++ b/drivers/video/fbdev/s1d13xxxfb.c @@ -596,18 +596,26 @@ s1d13xxxfb_bitblt_solidfill(struct fb_info *info, const struct fb_fillrect *rect } /* framebuffer information structures */ -static struct fb_ops s1d13xxxfb_fbops = { +static const struct fb_ops s1d13xxxfb_fbops = { .owner = THIS_MODULE, + FB_DEFAULT_IOMEM_OPS, .fb_set_par = s1d13xxxfb_set_par, .fb_setcolreg = s1d13xxxfb_setcolreg, .fb_blank = s1d13xxxfb_blank, - .fb_pan_display = s1d13xxxfb_pan_display, +}; - /* gets replaced at chip detection time */ - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, +static const struct fb_ops s1d13xxxfb_fbops_s1d13506 = { + .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, + .fb_set_par = s1d13xxxfb_set_par, + .fb_setcolreg = s1d13xxxfb_setcolreg, + .fb_blank = s1d13xxxfb_blank, + .fb_pan_display = s1d13xxxfb_pan_display, + .fb_fillrect = s1d13xxxfb_bitblt_solidfill, + .fb_copyarea = s1d13xxxfb_bitblt_copyarea, .fb_imageblit = cfb_imageblit, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; static int s1d13xxxfb_width_tab[2][4] = { @@ -869,17 +877,16 @@ static int s1d13xxxfb_probe(struct platform_device *pdev) default_par->regs, info->fix.smem_len / 1024, info->screen_base); info->par = default_par; - info->flags = FBINFO_HWACCEL_YPAN; - info->fbops = &s1d13xxxfb_fbops; switch(prod_id) { case S1D13506_PROD_ID: /* activate acceleration */ - s1d13xxxfb_fbops.fb_fillrect = s1d13xxxfb_bitblt_solidfill; - s1d13xxxfb_fbops.fb_copyarea = s1d13xxxfb_bitblt_copyarea; info->flags = FBINFO_HWACCEL_YPAN | FBINFO_HWACCEL_FILLRECT | FBINFO_HWACCEL_COPYAREA; + info->fbops = &s1d13xxxfb_fbops_s1d13506; break; default: + info->flags = FBINFO_HWACCEL_YPAN; + info->fbops = &s1d13xxxfb_fbops; break; } diff --git a/drivers/video/fbdev/s3fb.c b/drivers/video/fbdev/s3fb.c index 7d257489edcc..589b349cb63e 100644 --- a/drivers/video/fbdev/s3fb.c +++ b/drivers/video/fbdev/s3fb.c @@ -1047,6 +1047,7 @@ static const struct fb_ops s3fb_ops = { .owner = THIS_MODULE, .fb_open = s3fb_open, .fb_release = s3fb_release, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = s3fb_check_var, .fb_set_par = s3fb_set_par, .fb_setcolreg = s3fb_setcolreg, @@ -1055,6 +1056,7 @@ static const struct fb_ops s3fb_ops = { .fb_fillrect = s3fb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = s3fb_imageblit, + __FB_DEFAULT_IOMEM_OPS_MMAP, .fb_get_caps = svga_get_caps, }; diff --git a/drivers/video/fbdev/sa1100fb.c b/drivers/video/fbdev/sa1100fb.c index cf0f706762b4..befd3fe2f659 100644 --- a/drivers/video/fbdev/sa1100fb.c +++ b/drivers/video/fbdev/sa1100fb.c @@ -575,14 +575,13 @@ static int sa1100fb_mmap(struct fb_info *info, static const struct fb_ops sa1100fb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = sa1100fb_check_var, .fb_set_par = sa1100fb_set_par, // .fb_set_cmap = sa1100fb_set_cmap, .fb_setcolreg = sa1100fb_setcolreg, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, .fb_blank = sa1100fb_blank, + __FB_DEFAULT_IOMEM_OPS_DRAW, .fb_mmap = sa1100fb_mmap, }; diff --git a/drivers/video/fbdev/savage/savagefb_driver.c b/drivers/video/fbdev/savage/savagefb_driver.c index b5f84bd4804b..dddd6afcb972 100644 --- a/drivers/video/fbdev/savage/savagefb_driver.c +++ b/drivers/video/fbdev/savage/savagefb_driver.c @@ -1641,6 +1641,7 @@ static const struct fb_ops savagefb_ops = { .owner = THIS_MODULE, .fb_open = savagefb_open, .fb_release = savagefb_release, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = savagefb_check_var, .fb_set_par = savagefb_set_par, .fb_setcolreg = savagefb_setcolreg, @@ -1652,10 +1653,9 @@ static const struct fb_ops savagefb_ops = { .fb_imageblit = savagefb_imageblit, .fb_sync = savagefb_sync, #else - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, + __FB_DEFAULT_IOMEM_OPS_DRAW, #endif + __FB_DEFAULT_IOMEM_OPS_MMAP, }; /* --------------------------------------------------------------------- */ diff --git a/drivers/video/fbdev/sis/sis_main.c b/drivers/video/fbdev/sis/sis_main.c index 0f5374f6ef05..6ad47b6b6004 100644 --- a/drivers/video/fbdev/sis/sis_main.c +++ b/drivers/video/fbdev/sis/sis_main.c @@ -1911,6 +1911,7 @@ static const struct fb_ops sisfb_ops = { .owner = THIS_MODULE, .fb_open = sisfb_open, .fb_release = sisfb_release, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = sisfb_check_var, .fb_set_par = sisfb_set_par, .fb_setcolreg = sisfb_setcolreg, @@ -1923,7 +1924,8 @@ static const struct fb_ops sisfb_ops = { #ifdef SIS_NEW_CONFIG_COMPAT .fb_compat_ioctl= sisfb_ioctl, #endif - .fb_ioctl = sisfb_ioctl + .fb_ioctl = sisfb_ioctl, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; /* ---------------- Chip generation dependent routines ---------------- */ diff --git a/drivers/video/fbdev/sm501fb.c b/drivers/video/fbdev/sm501fb.c index 65c799ac5604..d6fdc1737cd2 100644 --- a/drivers/video/fbdev/sm501fb.c +++ b/drivers/video/fbdev/sm501fb.c @@ -1452,6 +1452,7 @@ static void sm501fb_fillrect(struct fb_info *info, const struct fb_fillrect *rec static struct fb_ops sm501fb_ops_crt = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = sm501fb_check_var_crt, .fb_set_par = sm501fb_set_par_crt, .fb_blank = sm501fb_blank_crt, @@ -1462,10 +1463,12 @@ static struct fb_ops sm501fb_ops_crt = { .fb_copyarea = sm501fb_copyarea, .fb_imageblit = cfb_imageblit, .fb_sync = sm501fb_sync, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; static struct fb_ops sm501fb_ops_pnl = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = sm501fb_check_var_pnl, .fb_set_par = sm501fb_set_par_pnl, .fb_pan_display = sm501fb_pan_pnl, @@ -1476,6 +1479,7 @@ static struct fb_ops sm501fb_ops_pnl = { .fb_copyarea = sm501fb_copyarea, .fb_imageblit = cfb_imageblit, .fb_sync = sm501fb_sync, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; /* sm501_init_cursor diff --git a/drivers/video/fbdev/sm712fb.c b/drivers/video/fbdev/sm712fb.c index db129ed3b2f7..3f8ef50e3209 100644 --- a/drivers/video/fbdev/sm712fb.c +++ b/drivers/video/fbdev/sm712fb.c @@ -1347,6 +1347,7 @@ static int smtc_set_par(struct fb_info *info) static const struct fb_ops smtcfb_ops = { .owner = THIS_MODULE, + FB_DEFAULT_IOMEM_OPS, .fb_check_var = smtc_check_var, .fb_set_par = smtc_set_par, .fb_setcolreg = smtc_setcolreg, diff --git a/drivers/video/fbdev/stifb.c b/drivers/video/fbdev/stifb.c index c746deb79afc..548d992f8cb1 100644 --- a/drivers/video/fbdev/stifb.c +++ b/drivers/video/fbdev/stifb.c @@ -1167,12 +1167,14 @@ stifb_init_display(struct stifb_info *fb) static const struct fb_ops stifb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = stifb_check_var, .fb_setcolreg = stifb_setcolreg, .fb_blank = stifb_blank, .fb_fillrect = stifb_fillrect, .fb_copyarea = stifb_copyarea, .fb_imageblit = cfb_imageblit, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; diff --git a/drivers/video/fbdev/sunxvr500.c b/drivers/video/fbdev/sunxvr500.c index 3b7dcdae9f83..fef008b728dd 100644 --- a/drivers/video/fbdev/sunxvr500.c +++ b/drivers/video/fbdev/sunxvr500.c @@ -189,10 +189,12 @@ static void e3d_copyarea(struct fb_info *info, const struct fb_copyarea *area) static const struct fb_ops e3d_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_setcolreg = e3d_setcolreg, .fb_fillrect = e3d_fillrect, .fb_copyarea = e3d_copyarea, .fb_imageblit = e3d_imageblit, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; static int e3d_set_fbinfo(struct e3d_info *ep) diff --git a/drivers/video/fbdev/tdfxfb.c b/drivers/video/fbdev/tdfxfb.c index 68e2a82220f3..22aa953138b0 100644 --- a/drivers/video/fbdev/tdfxfb.c +++ b/drivers/video/fbdev/tdfxfb.c @@ -1142,6 +1142,7 @@ static int tdfxfb_cursor(struct fb_info *info, struct fb_cursor *cursor) static const struct fb_ops tdfxfb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = tdfxfb_check_var, .fb_set_par = tdfxfb_set_par, .fb_setcolreg = tdfxfb_setcolreg, @@ -1154,10 +1155,9 @@ static const struct fb_ops tdfxfb_ops = { .fb_copyarea = tdfxfb_copyarea, .fb_imageblit = tdfxfb_imageblit, #else - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, + __FB_DEFAULT_IOMEM_OPS_DRAW, #endif + __FB_DEFAULT_IOMEM_OPS_MMAP, }; #ifdef CONFIG_FB_3DFX_I2C diff --git a/drivers/video/fbdev/tgafb.c b/drivers/video/fbdev/tgafb.c index fc2d08dd1b45..ca43774f3156 100644 --- a/drivers/video/fbdev/tgafb.c +++ b/drivers/video/fbdev/tgafb.c @@ -73,6 +73,7 @@ static struct tc_driver tgafb_tc_driver; static const struct fb_ops tgafb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = tgafb_check_var, .fb_set_par = tgafb_set_par, .fb_setcolreg = tgafb_setcolreg, @@ -81,6 +82,7 @@ static const struct fb_ops tgafb_ops = { .fb_fillrect = tgafb_fillrect, .fb_copyarea = tgafb_copyarea, .fb_imageblit = tgafb_imageblit, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; diff --git a/drivers/video/fbdev/tridentfb.c b/drivers/video/fbdev/tridentfb.c index 1ba157530af2..816d40b6f689 100644 --- a/drivers/video/fbdev/tridentfb.c +++ b/drivers/video/fbdev/tridentfb.c @@ -1444,6 +1444,7 @@ static int tridentfb_blank(int blank_mode, struct fb_info *info) static const struct fb_ops tridentfb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_setcolreg = tridentfb_setcolreg, .fb_pan_display = tridentfb_pan_display, .fb_blank = tridentfb_blank, @@ -1453,6 +1454,7 @@ static const struct fb_ops tridentfb_ops = { .fb_copyarea = tridentfb_copyarea, .fb_imageblit = tridentfb_imageblit, .fb_sync = tridentfb_sync, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; static int trident_pci_probe(struct pci_dev *dev, diff --git a/drivers/video/fbdev/vermilion/vermilion.c b/drivers/video/fbdev/vermilion/vermilion.c index 71584c775efd..840ead69654b 100644 --- a/drivers/video/fbdev/vermilion/vermilion.c +++ b/drivers/video/fbdev/vermilion/vermilion.c @@ -1024,13 +1024,12 @@ static struct fb_ops vmlfb_ops = { .owner = THIS_MODULE, .fb_open = vmlfb_open, .fb_release = vmlfb_release, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = vmlfb_check_var, .fb_set_par = vmlfb_set_par, .fb_blank = vmlfb_blank, .fb_pan_display = vmlfb_pan_display, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, + __FB_DEFAULT_IOMEM_OPS_DRAW, .fb_cursor = vmlfb_cursor, .fb_sync = vmlfb_sync, .fb_mmap = vmlfb_mmap, diff --git a/drivers/video/fbdev/vga16fb.c b/drivers/video/fbdev/vga16fb.c index b43c874c199f..ac21942d5311 100644 --- a/drivers/video/fbdev/vga16fb.c +++ b/drivers/video/fbdev/vga16fb.c @@ -1291,6 +1291,7 @@ static const struct fb_ops vga16fb_ops = { .owner = THIS_MODULE, .fb_open = vga16fb_open, .fb_release = vga16fb_release, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_destroy = vga16fb_destroy, .fb_check_var = vga16fb_check_var, .fb_set_par = vga16fb_set_par, @@ -1300,6 +1301,7 @@ static const struct fb_ops vga16fb_ops = { .fb_fillrect = vga16fb_fillrect, .fb_copyarea = vga16fb_copyarea, .fb_imageblit = vga16fb_imageblit, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; static int vga16fb_probe(struct platform_device *dev) diff --git a/drivers/video/fbdev/via/viafbdev.c b/drivers/video/fbdev/via/viafbdev.c index 190fddee62e6..58868f8880d6 100644 --- a/drivers/video/fbdev/via/viafbdev.c +++ b/drivers/video/fbdev/via/viafbdev.c @@ -2054,6 +2054,7 @@ static struct fb_ops viafb_ops = { .owner = THIS_MODULE, .fb_open = viafb_open, .fb_release = viafb_release, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = viafb_check_var, .fb_set_par = viafb_set_par, .fb_setcolreg = viafb_setcolreg, @@ -2065,6 +2066,7 @@ static struct fb_ops viafb_ops = { .fb_cursor = viafb_cursor, .fb_ioctl = viafb_ioctl, .fb_sync = viafb_sync, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; diff --git a/drivers/video/fbdev/vt8623fb.c b/drivers/video/fbdev/vt8623fb.c index 034333ee6e45..f8d022cb61e8 100644 --- a/drivers/video/fbdev/vt8623fb.c +++ b/drivers/video/fbdev/vt8623fb.c @@ -644,6 +644,7 @@ static const struct fb_ops vt8623fb_ops = { .owner = THIS_MODULE, .fb_open = vt8623fb_open, .fb_release = vt8623fb_release, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = vt8623fb_check_var, .fb_set_par = vt8623fb_set_par, .fb_setcolreg = vt8623fb_setcolreg, @@ -652,6 +653,7 @@ static const struct fb_ops vt8623fb_ops = { .fb_fillrect = vt8623fb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = vt8623fb_imageblit, + __FB_DEFAULT_IOMEM_OPS_MMAP, .fb_get_caps = svga_get_caps, }; diff --git a/include/drm/bridge/dw_mipi_dsi.h b/include/drm/bridge/dw_mipi_dsi.h index 5286a53a1875..65d5e68065e3 100644 --- a/include/drm/bridge/dw_mipi_dsi.h +++ b/include/drm/bridge/dw_mipi_dsi.h @@ -11,6 +11,10 @@ #include <linux/types.h> +#include <drm/drm_atomic.h> +#include <drm/drm_bridge.h> +#include <drm/drm_connector.h> +#include <drm/drm_crtc.h> #include <drm/drm_modes.h> struct drm_display_mode; @@ -55,6 +59,17 @@ struct dw_mipi_dsi_plat_data { unsigned long mode_flags, u32 lanes, u32 format); + bool (*mode_fixup)(void *priv_data, const struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode); + + u32 *(*get_input_bus_fmts)(void *priv_data, + struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state, + u32 output_fmt, + unsigned int *num_input_fmts); + const struct dw_mipi_dsi_phy_ops *phy_ops; const struct dw_mipi_dsi_host_ops *host_ops; @@ -68,5 +83,6 @@ void dw_mipi_dsi_remove(struct dw_mipi_dsi *dsi); int dw_mipi_dsi_bind(struct dw_mipi_dsi *dsi, struct drm_encoder *encoder); void dw_mipi_dsi_unbind(struct dw_mipi_dsi *dsi); void dw_mipi_dsi_set_slave(struct dw_mipi_dsi *dsi, struct dw_mipi_dsi *slave); +struct drm_bridge *dw_mipi_dsi_get_bridge(struct dw_mipi_dsi *dsi); #endif /* __DW_MIPI_DSI__ */ diff --git a/include/drm/drm_gpuvm.h b/include/drm/drm_gpuvm.h index c7ed6bf441d4..bdfafc4a7705 100644 --- a/include/drm/drm_gpuvm.h +++ b/include/drm/drm_gpuvm.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0 OR MIT */ #ifndef __DRM_GPUVM_H__ #define __DRM_GPUVM_H__ diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h index ac65f0626cfc..d2fb81e34174 100644 --- a/include/drm/gpu_scheduler.h +++ b/include/drm/gpu_scheduler.h @@ -471,7 +471,9 @@ struct drm_sched_backend_ops { * @hw_submission_limit: the max size of the hardware queue. * @timeout: the time after which a job is removed from the scheduler. * @name: name of the ring for which this scheduler is being used. - * @sched_rq: priority wise array of run queues. + * @num_rqs: Number of run-queues. This is at most DRM_SCHED_PRIORITY_COUNT, + * as there's usually one run-queue per priority, but could be less. + * @sched_rq: An allocated array of run-queues of size @num_rqs; * @wake_up_worker: the wait queue on which the scheduler sleeps until a job * is ready to be scheduled. * @job_scheduled: once @drm_sched_entity_do_release is called the scheduler @@ -500,7 +502,8 @@ struct drm_gpu_scheduler { uint32_t hw_submission_limit; long timeout; const char *name; - struct drm_sched_rq sched_rq[DRM_SCHED_PRIORITY_COUNT]; + u32 num_rqs; + struct drm_sched_rq **sched_rq; wait_queue_head_t wake_up_worker; wait_queue_head_t job_scheduled; atomic_t hw_rq_count; @@ -520,7 +523,7 @@ struct drm_gpu_scheduler { int drm_sched_init(struct drm_gpu_scheduler *sched, const struct drm_sched_backend_ops *ops, - uint32_t hw_submission, unsigned hang_limit, + u32 num_rqs, uint32_t hw_submission, unsigned int hang_limit, long timeout, struct workqueue_struct *timeout_wq, atomic_t *score, const char *name, struct device *dev); diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h index 794c1d857677..de723566c5ae 100644 --- a/include/uapi/drm/drm.h +++ b/include/uapi/drm/drm.h @@ -1134,6 +1134,26 @@ extern "C" { #define DRM_IOCTL_MODE_PAGE_FLIP DRM_IOWR(0xB0, struct drm_mode_crtc_page_flip) #define DRM_IOCTL_MODE_DIRTYFB DRM_IOWR(0xB1, struct drm_mode_fb_dirty_cmd) +/** + * DRM_IOCTL_MODE_CREATE_DUMB - Create a new dumb buffer object. + * + * KMS dumb buffers provide a very primitive way to allocate a buffer object + * suitable for scanout and map it for software rendering. KMS dumb buffers are + * not suitable for hardware-accelerated rendering nor video decoding. KMS dumb + * buffers are not suitable to be displayed on any other device than the KMS + * device where they were allocated from. Also see + * :ref:`kms_dumb_buffer_objects`. + * + * The IOCTL argument is a struct drm_mode_create_dumb. + * + * User-space is expected to create a KMS dumb buffer via this IOCTL, then add + * it as a KMS framebuffer via &DRM_IOCTL_MODE_ADDFB and map it via + * &DRM_IOCTL_MODE_MAP_DUMB. + * + * &DRM_CAP_DUMB_BUFFER indicates whether this IOCTL is supported. + * &DRM_CAP_DUMB_PREFERRED_DEPTH and &DRM_CAP_DUMB_PREFER_SHADOW indicate + * driver preferences for dumb buffers. + */ #define DRM_IOCTL_MODE_CREATE_DUMB DRM_IOWR(0xB2, struct drm_mode_create_dumb) #define DRM_IOCTL_MODE_MAP_DUMB DRM_IOWR(0xB3, struct drm_mode_map_dumb) #define DRM_IOCTL_MODE_DESTROY_DUMB DRM_IOWR(0xB4, struct drm_mode_destroy_dumb) diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h index 8db7fd3f743e..3151f1fc7ebb 100644 --- a/include/uapi/drm/drm_fourcc.h +++ b/include/uapi/drm/drm_fourcc.h @@ -323,6 +323,8 @@ extern "C" { * index 1 = Cr:Cb plane, [39:0] Cr1:Cb1:Cr0:Cb0 little endian */ #define DRM_FORMAT_NV15 fourcc_code('N', 'V', '1', '5') /* 2x2 subsampled Cr:Cb plane */ +#define DRM_FORMAT_NV20 fourcc_code('N', 'V', '2', '0') /* 2x1 subsampled Cr:Cb plane */ +#define DRM_FORMAT_NV30 fourcc_code('N', 'V', '3', '0') /* non-subsampled Cr:Cb plane */ /* * 2 plane YCbCr MSB aligned diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index ea1b639bcb28..128d09138ceb 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -1032,13 +1032,25 @@ struct drm_mode_crtc_page_flip_target { __u64 user_data; }; -/* create a dumb scanout buffer */ +/** + * struct drm_mode_create_dumb - Create a KMS dumb buffer for scanout. + * @height: buffer height in pixels + * @width: buffer width in pixels + * @bpp: bits per pixel + * @flags: must be zero + * @handle: buffer object handle + * @pitch: number of bytes between two consecutive lines + * @size: size of the whole buffer in bytes + * + * User-space fills @height, @width, @bpp and @flags. If the IOCTL succeeds, + * the kernel fills @handle, @pitch and @size. + */ struct drm_mode_create_dumb { __u32 height; __u32 width; __u32 bpp; __u32 flags; - /* handle, pitch, size will be returned */ + __u32 handle; __u32 pitch; __u64 size; |