mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 12:28:41 +08:00
Merge drm/drm-next into drm-intel-next
Sync the drm-intel-gt-next changes back to drm-intel-next via drm-next. Signed-off-by: Jani Nikula <jani.nikula@intel.com>
This commit is contained in:
commit
e2a9f0a324
@ -18,7 +18,6 @@ Block
|
||||
kyber-iosched
|
||||
null_blk
|
||||
pr
|
||||
request
|
||||
stat
|
||||
switching-sched
|
||||
writeback_cache_control
|
||||
|
@ -1,99 +0,0 @@
|
||||
============================
|
||||
struct request documentation
|
||||
============================
|
||||
|
||||
Jens Axboe <jens.axboe@oracle.com> 27/05/02
|
||||
|
||||
|
||||
.. FIXME:
|
||||
No idea about what does mean - seems just some noise, so comment it
|
||||
|
||||
1.0
|
||||
Index
|
||||
|
||||
2.0 Struct request members classification
|
||||
|
||||
2.1 struct request members explanation
|
||||
|
||||
3.0
|
||||
|
||||
|
||||
2.0
|
||||
|
||||
|
||||
|
||||
Short explanation of request members
|
||||
====================================
|
||||
|
||||
Classification flags:
|
||||
|
||||
= ====================
|
||||
D driver member
|
||||
B block layer member
|
||||
I I/O scheduler member
|
||||
= ====================
|
||||
|
||||
Unless an entry contains a D classification, a device driver must not access
|
||||
this member. Some members may contain D classifications, but should only be
|
||||
access through certain macros or functions (eg ->flags).
|
||||
|
||||
<linux/blkdev.h>
|
||||
|
||||
=============================== ======= =======================================
|
||||
Member Flag Comment
|
||||
=============================== ======= =======================================
|
||||
struct list_head queuelist BI Organization on various internal
|
||||
queues
|
||||
|
||||
``void *elevator_private`` I I/O scheduler private data
|
||||
|
||||
unsigned char cmd[16] D Driver can use this for setting up
|
||||
a cdb before execution, see
|
||||
blk_queue_prep_rq
|
||||
|
||||
unsigned long flags DBI Contains info about data direction,
|
||||
request type, etc.
|
||||
|
||||
int rq_status D Request status bits
|
||||
|
||||
kdev_t rq_dev DBI Target device
|
||||
|
||||
int errors DB Error counts
|
||||
|
||||
sector_t sector DBI Target location
|
||||
|
||||
unsigned long hard_nr_sectors B Used to keep sector sane
|
||||
|
||||
unsigned long nr_sectors DBI Total number of sectors in request
|
||||
|
||||
unsigned long hard_nr_sectors B Used to keep nr_sectors sane
|
||||
|
||||
unsigned short nr_phys_segments DB Number of physical scatter gather
|
||||
segments in a request
|
||||
|
||||
unsigned short nr_hw_segments DB Number of hardware scatter gather
|
||||
segments in a request
|
||||
|
||||
unsigned int current_nr_sectors DB Number of sectors in first segment
|
||||
of request
|
||||
|
||||
unsigned int hard_cur_sectors B Used to keep current_nr_sectors sane
|
||||
|
||||
int tag DB TCQ tag, if assigned
|
||||
|
||||
``void *special`` D Free to be used by driver
|
||||
|
||||
``char *buffer`` D Map of first segment, also see
|
||||
section on bouncing SECTION
|
||||
|
||||
``struct completion *waiting`` D Can be used by driver to get signalled
|
||||
on request completion
|
||||
|
||||
``struct bio *bio`` DBI First bio in request
|
||||
|
||||
``struct bio *biotail`` DBI Last bio in request
|
||||
|
||||
``struct request_queue *q`` DB Request queue this request belongs to
|
||||
|
||||
``struct request_list *rl`` B Request list this request came from
|
||||
=============================== ======= =======================================
|
@ -17,6 +17,7 @@ description: |
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- fsl,imx6sx-ldb
|
||||
- fsl,imx8mp-ldb
|
||||
- fsl,imx93-ldb
|
||||
|
||||
@ -64,7 +65,9 @@ allOf:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: fsl,imx93-ldb
|
||||
enum:
|
||||
- fsl,imx6sx-ldb
|
||||
- fsl,imx93-ldb
|
||||
then:
|
||||
properties:
|
||||
ports:
|
||||
|
@ -105,6 +105,29 @@ properties:
|
||||
DSI output port node to the panel or the next bridge
|
||||
in the chain.
|
||||
|
||||
properties:
|
||||
endpoint:
|
||||
$ref: /schemas/media/video-interfaces.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
properties:
|
||||
data-lanes:
|
||||
minItems: 1
|
||||
maxItems: 4
|
||||
uniqueItems: true
|
||||
items:
|
||||
enum: [ 1, 2, 3, 4 ]
|
||||
|
||||
lane-polarities:
|
||||
minItems: 1
|
||||
maxItems: 5
|
||||
description:
|
||||
The Samsung MIPI DSI IP requires that all the data lanes have
|
||||
the same polarity.
|
||||
|
||||
dependencies:
|
||||
lane-polarities: [data-lanes]
|
||||
|
||||
required:
|
||||
- clock-names
|
||||
- clocks
|
||||
|
@ -4,16 +4,24 @@
|
||||
$id: http://devicetree.org/schemas/display/bridge/toshiba,tc358767.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Toshiba TC358767 eDP bridge
|
||||
title: Toshiba TC358767/TC358867/TC9595 DSI/DPI/eDP bridge
|
||||
|
||||
maintainers:
|
||||
- Andrey Gusakov <andrey.gusakov@cogentembedded.com>
|
||||
|
||||
description: The TC358767 is bridge device which converts DSI/DPI to eDP/DP
|
||||
description: |
|
||||
The TC358767/TC358867/TC9595 is bridge device which
|
||||
converts DSI/DPI to eDP/DP .
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: toshiba,tc358767
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
- toshiba,tc358867
|
||||
- toshiba,tc9595
|
||||
- const: toshiba,tc358767
|
||||
- const: toshiba,tc358767
|
||||
|
||||
reg:
|
||||
enum:
|
||||
|
@ -19,11 +19,16 @@ allOf:
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- xiaomi,elish-boe-nt36523
|
||||
- xiaomi,elish-csot-nt36523
|
||||
- const: novatek,nt36523
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
- xiaomi,elish-boe-nt36523
|
||||
- xiaomi,elish-csot-nt36523
|
||||
- const: novatek,nt36523
|
||||
- items:
|
||||
- enum:
|
||||
- lenovo,j606f-boe-nt36523w
|
||||
- const: novatek,nt36523w
|
||||
|
||||
reset-gpios:
|
||||
maxItems: 1
|
||||
@ -34,6 +39,7 @@ properties:
|
||||
|
||||
reg: true
|
||||
ports: true
|
||||
rotation: true
|
||||
backlight: true
|
||||
|
||||
required:
|
||||
|
@ -77,6 +77,8 @@ properties:
|
||||
- auo,t215hvn01
|
||||
# Shanghai AVIC Optoelectronics 7" 1024x600 color TFT-LCD panel
|
||||
- avic,tm070ddh03
|
||||
# BOE EV121WXM-N10-1850 12.1" WXGA (1280x800) TFT LCD panel
|
||||
- boe,ev121wxm-n10-1850
|
||||
# BOE HV070WSA-100 7.01" WSVGA TFT LCD panel
|
||||
- boe,hv070wsa-100
|
||||
# BOE OPTOELECTRONICS TECHNOLOGY 10.1" WXGA TFT LCD panel
|
||||
@ -174,6 +176,8 @@ properties:
|
||||
- innolux,at043tn24
|
||||
# Innolux AT070TN92 7.0" WQVGA TFT LCD panel
|
||||
- innolux,at070tn92
|
||||
# Innolux G070ACE-L01 7" WVGA (800x480) TFT LCD panel
|
||||
- innolux,g070ace-l01
|
||||
# Innolux G070Y2-L01 7" WVGA (800x480) TFT LCD panel
|
||||
- innolux,g070y2-l01
|
||||
# Innolux G070Y2-T02 7" WVGA (800x480) TFT LCD TTL panel
|
||||
|
@ -20,6 +20,8 @@ allOf:
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
# Anberic RG353V-V2 5.0" 640x480 TFT LCD panel
|
||||
- anbernic,rg353v-panel-v2
|
||||
# Rocktech JH057N00900 5.5" 720x1440 TFT LCD panel
|
||||
- rocktech,jh057n00900
|
||||
# Xingbangda XBD599 5.99" 720x1440 TFT LCD panel
|
||||
|
@ -0,0 +1,70 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/panel/samsung,s6d7aa0.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Samsung S6D7AA0 MIPI-DSI LCD panel controller
|
||||
|
||||
maintainers:
|
||||
- Artur Weber <aweber.kernel@gmail.com>
|
||||
|
||||
allOf:
|
||||
- $ref: panel-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
# 1280x800 LSL080AL02 panel
|
||||
- samsung,lsl080al02
|
||||
# 1024x768 LSL080AL03 panel
|
||||
- samsung,lsl080al03
|
||||
# 1024x768 LTL101AT01 panel
|
||||
- samsung,ltl101at01
|
||||
- const: samsung,s6d7aa0
|
||||
|
||||
reg: true
|
||||
|
||||
backlight:
|
||||
description:
|
||||
Backlight to use for the panel. If this property is set on panels
|
||||
that have DSI-based backlight control (LSL080AL03 and LTL101AT01),
|
||||
it overrides the DSI-based backlight.
|
||||
|
||||
reset-gpios:
|
||||
description: Reset GPIO pin, usually GPIO_ACTIVE_LOW.
|
||||
|
||||
power-supply:
|
||||
description:
|
||||
Main power supply for the panel; the exact voltage differs between
|
||||
panels, and is usually somewhere around 3.3-5v.
|
||||
|
||||
vmipi-supply:
|
||||
description: VMIPI supply, usually 1.8v.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reset-gpios
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
dsi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
panel@0 {
|
||||
compatible = "samsung,lsl080al02", "samsung,s6d7aa0";
|
||||
reg = <0>;
|
||||
power-supply = <&display_3v3_supply>;
|
||||
reset-gpios = <&gpf0 4 GPIO_ACTIVE_LOW>;
|
||||
backlight = <&backlight>;
|
||||
};
|
||||
};
|
||||
|
||||
...
|
@ -49,6 +49,7 @@ properties:
|
||||
|
||||
properties:
|
||||
data-lanes:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
required:
|
||||
|
@ -17,20 +17,11 @@ description:
|
||||
properties:
|
||||
clocks:
|
||||
minItems: 3
|
||||
items:
|
||||
- description: PCIe bridge clock.
|
||||
- description: PCIe bus clock.
|
||||
- description: PCIe PHY clock.
|
||||
- description: Additional required clock entry for imx6sx-pcie,
|
||||
imx6sx-pcie-ep, imx8mq-pcie, imx8mq-pcie-ep.
|
||||
maxItems: 4
|
||||
|
||||
clock-names:
|
||||
minItems: 3
|
||||
items:
|
||||
- const: pcie
|
||||
- const: pcie_bus
|
||||
- enum: [ pcie_phy, pcie_aux ]
|
||||
- enum: [ pcie_inbound_axi, pcie_aux ]
|
||||
maxItems: 4
|
||||
|
||||
num-lanes:
|
||||
const: 1
|
||||
|
@ -31,6 +31,19 @@ properties:
|
||||
- const: dbi
|
||||
- const: addr_space
|
||||
|
||||
clocks:
|
||||
minItems: 3
|
||||
items:
|
||||
- description: PCIe bridge clock.
|
||||
- description: PCIe bus clock.
|
||||
- description: PCIe PHY clock.
|
||||
- description: Additional required clock entry for imx6sx-pcie,
|
||||
imx6sx-pcie-ep, imx8mq-pcie, imx8mq-pcie-ep.
|
||||
|
||||
clock-names:
|
||||
minItems: 3
|
||||
maxItems: 4
|
||||
|
||||
interrupts:
|
||||
items:
|
||||
- description: builtin eDMA interrupter.
|
||||
@ -49,6 +62,31 @@ required:
|
||||
allOf:
|
||||
- $ref: /schemas/pci/snps,dw-pcie-ep.yaml#
|
||||
- $ref: /schemas/pci/fsl,imx6q-pcie-common.yaml#
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- fsl,imx8mq-pcie-ep
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
minItems: 4
|
||||
clock-names:
|
||||
items:
|
||||
- const: pcie
|
||||
- const: pcie_bus
|
||||
- const: pcie_phy
|
||||
- const: pcie_aux
|
||||
else:
|
||||
properties:
|
||||
clocks:
|
||||
maxItems: 3
|
||||
clock-names:
|
||||
items:
|
||||
- const: pcie
|
||||
- const: pcie_bus
|
||||
- const: pcie_aux
|
||||
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
|
@ -40,6 +40,19 @@ properties:
|
||||
- const: dbi
|
||||
- const: config
|
||||
|
||||
clocks:
|
||||
minItems: 3
|
||||
items:
|
||||
- description: PCIe bridge clock.
|
||||
- description: PCIe bus clock.
|
||||
- description: PCIe PHY clock.
|
||||
- description: Additional required clock entry for imx6sx-pcie,
|
||||
imx6sx-pcie-ep, imx8mq-pcie, imx8mq-pcie-ep.
|
||||
|
||||
clock-names:
|
||||
minItems: 3
|
||||
maxItems: 4
|
||||
|
||||
interrupts:
|
||||
items:
|
||||
- description: builtin MSI controller.
|
||||
@ -77,6 +90,70 @@ required:
|
||||
allOf:
|
||||
- $ref: /schemas/pci/snps,dw-pcie.yaml#
|
||||
- $ref: /schemas/pci/fsl,imx6q-pcie-common.yaml#
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- fsl,imx6sx-pcie
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
minItems: 4
|
||||
clock-names:
|
||||
items:
|
||||
- const: pcie
|
||||
- const: pcie_bus
|
||||
- const: pcie_phy
|
||||
- const: pcie_inbound_axi
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- fsl,imx8mq-pcie
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
minItems: 4
|
||||
clock-names:
|
||||
items:
|
||||
- const: pcie
|
||||
- const: pcie_bus
|
||||
- const: pcie_phy
|
||||
- const: pcie_aux
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- fsl,imx6q-pcie
|
||||
- fsl,imx6qp-pcie
|
||||
- fsl,imx7d-pcie
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
maxItems: 3
|
||||
clock-names:
|
||||
items:
|
||||
- const: pcie
|
||||
- const: pcie_bus
|
||||
- const: pcie_phy
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- fsl,imx8mm-pcie
|
||||
- fsl,imx8mp-pcie
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
maxItems: 3
|
||||
clock-names:
|
||||
items:
|
||||
- const: pcie
|
||||
- const: pcie_bus
|
||||
- const: pcie_aux
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
|
@ -31,3 +31,7 @@ host such documentation:
|
||||
.. toctree::
|
||||
|
||||
i915_vm_bind.rst
|
||||
|
||||
.. toctree::
|
||||
|
||||
xe.rst
|
||||
|
235
Documentation/gpu/rfc/xe.rst
Normal file
235
Documentation/gpu/rfc/xe.rst
Normal file
@ -0,0 +1,235 @@
|
||||
==========================
|
||||
Xe – Merge Acceptance Plan
|
||||
==========================
|
||||
Xe is a new driver for Intel GPUs that supports both integrated and
|
||||
discrete platforms starting with Tiger Lake (first Intel Xe Architecture).
|
||||
|
||||
This document aims to establish a merge plan for the Xe, by writing down clear
|
||||
pre-merge goals, in order to avoid unnecessary delays.
|
||||
|
||||
Xe – Overview
|
||||
=============
|
||||
The main motivation of Xe is to have a fresh base to work from that is
|
||||
unencumbered by older platforms, whilst also taking the opportunity to
|
||||
rearchitect our driver to increase sharing across the drm subsystem, both
|
||||
leveraging and allowing us to contribute more towards other shared components
|
||||
like TTM and drm/scheduler.
|
||||
|
||||
This is also an opportunity to start from the beginning with a clean uAPI that is
|
||||
extensible by design and already aligned with the modern userspace needs. For
|
||||
this reason, the memory model is solely based on GPU Virtual Address space
|
||||
bind/unbind (‘VM_BIND’) of GEM buffer objects (BOs) and execution only supporting
|
||||
explicit synchronization. With persistent mapping across the execution, the
|
||||
userspace does not need to provide a list of all required mappings during each
|
||||
submission.
|
||||
|
||||
The new driver leverages a lot from i915. As for display, the intent is to share
|
||||
the display code with the i915 driver so that there is maximum reuse there.
|
||||
|
||||
As for the power management area, the goal is to have a much-simplified support
|
||||
for the system suspend states (S-states), PCI device suspend states (D-states),
|
||||
GPU/Render suspend states (R-states) and frequency management. It should leverage
|
||||
as much as possible all the existent PCI-subsystem infrastructure (pm and
|
||||
runtime_pm) and underlying firmware components such PCODE and GuC for the power
|
||||
states and frequency decisions.
|
||||
|
||||
Repository:
|
||||
|
||||
https://gitlab.freedesktop.org/drm/xe/kernel (branch drm-xe-next)
|
||||
|
||||
Xe – Platforms
|
||||
==============
|
||||
Currently, Xe is already functional and has experimental support for multiple
|
||||
platforms starting from Tiger Lake, with initial support in userspace implemented
|
||||
in Mesa (for Iris and Anv, our OpenGL and Vulkan drivers), as well as in NEO
|
||||
(for OpenCL and Level0).
|
||||
|
||||
During a transition period, platforms will be supported by both Xe and i915.
|
||||
However, the force_probe mechanism existent in both drivers will allow only one
|
||||
official and by-default probe at a given time.
|
||||
|
||||
For instance, in order to probe a DG2 which PCI ID is 0x5690 by Xe instead of
|
||||
i915, the following set of parameters need to be used:
|
||||
|
||||
```
|
||||
i915.force_probe=!5690 xe.force_probe=5690
|
||||
```
|
||||
|
||||
In both drivers, the ‘.require_force_probe’ protection forces the user to use the
|
||||
force_probe parameter while the driver is under development. This protection is
|
||||
only removed when the support for the platform and the uAPI are stable. Stability
|
||||
which needs to be demonstrated by CI results.
|
||||
|
||||
In order to avoid user space regressions, i915 will continue to support all the
|
||||
current platforms that are already out of this protection. Xe support will be
|
||||
forever experimental and dependent on the usage of force_probe for these
|
||||
platforms.
|
||||
|
||||
When the time comes for Xe, the protection will be lifted on Xe and kept in i915.
|
||||
|
||||
Xe driver will be protected with both STAGING Kconfig and force_probe. Changes in
|
||||
the uAPI are expected while the driver is behind these protections. STAGING will
|
||||
be removed when the driver uAPI gets to a mature state where we can guarantee the
|
||||
‘no regression’ rule. Then force_probe will be lifted only for future platforms
|
||||
that will be productized with Xe driver, but not with i915.
|
||||
|
||||
Xe – Pre-Merge Goals
|
||||
====================
|
||||
|
||||
Drm_scheduler
|
||||
-------------
|
||||
Xe primarily uses Firmware based scheduling (GuC FW). However, it will use
|
||||
drm_scheduler as the scheduler ‘frontend’ for userspace submission in order to
|
||||
resolve syncobj and dma-buf implicit sync dependencies. However, drm_scheduler is
|
||||
not yet prepared to handle the 1-to-1 relationship between drm_gpu_scheduler and
|
||||
drm_sched_entity.
|
||||
|
||||
Deeper changes to drm_scheduler should *not* be required to get Xe accepted, but
|
||||
some consensus needs to be reached between Xe and other community drivers that
|
||||
could also benefit from this work, for coupling FW based/assisted submission such
|
||||
as the ARM’s new Mali GPU driver, and others.
|
||||
|
||||
As a key measurable result, the patch series introducing Xe itself shall not
|
||||
depend on any other patch touching drm_scheduler itself that was not yet merged
|
||||
through drm-misc. This, by itself, already includes the reach of an agreement for
|
||||
uniform 1 to 1 relationship implementation / usage across drivers.
|
||||
|
||||
GPU VA
|
||||
------
|
||||
Two main goals of Xe are meeting together here:
|
||||
|
||||
1) Have an uAPI that aligns with modern UMD needs.
|
||||
|
||||
2) Early upstream engagement.
|
||||
|
||||
RedHat engineers working on Nouveau proposed a new DRM feature to handle keeping
|
||||
track of GPU virtual address mappings. This is still not merged upstream, but
|
||||
this aligns very well with our goals and with our VM_BIND. The engagement with
|
||||
upstream and the port of Xe towards GPUVA is already ongoing.
|
||||
|
||||
As a key measurable result, Xe needs to be aligned with the GPU VA and working in
|
||||
our tree. Missing Nouveau patches should *not* block Xe and any needed GPUVA
|
||||
related patch should be independent and present on dri-devel or acked by
|
||||
maintainers to go along with the first Xe pull request towards drm-next.
|
||||
|
||||
DRM_VM_BIND
|
||||
-----------
|
||||
Nouveau, and Xe are all implementing ‘VM_BIND’ and new ‘Exec’ uAPIs in order to
|
||||
fulfill the needs of the modern uAPI. Xe merge should *not* be blocked on the
|
||||
development of a common new drm_infrastructure. However, the Xe team needs to
|
||||
engage with the community to explore the options of a common API.
|
||||
|
||||
As a key measurable result, the DRM_VM_BIND needs to be documented in this file
|
||||
below, or this entire block deleted if the consensus is for independent drivers
|
||||
vm_bind ioctls.
|
||||
|
||||
Although having a common DRM level IOCTL for VM_BIND is not a requirement to get
|
||||
Xe merged, it is mandatory to enforce the overall locking scheme for all major
|
||||
structs and list (so vm and vma). So, a consensus is needed, and possibly some
|
||||
common helpers. If helpers are needed, they should be also documented in this
|
||||
document.
|
||||
|
||||
ASYNC VM_BIND
|
||||
-------------
|
||||
Although having a common DRM level IOCTL for VM_BIND is not a requirement to get
|
||||
Xe merged, it is mandatory to have a consensus with other drivers and Mesa.
|
||||
It needs to be clear how to handle async VM_BIND and interactions with userspace
|
||||
memory fences. Ideally with helper support so people don't get it wrong in all
|
||||
possible ways.
|
||||
|
||||
As a key measurable result, the benefits of ASYNC VM_BIND and a discussion of
|
||||
various flavors, error handling and a sample API should be documented here or in
|
||||
a separate document pointed to by this document.
|
||||
|
||||
Userptr integration and vm_bind
|
||||
-------------------------------
|
||||
Different drivers implement different ways of dealing with execution of userptr.
|
||||
With multiple drivers currently introducing support to VM_BIND, the goal is to
|
||||
aim for a DRM consensus on what’s the best way to have that support. To some
|
||||
extent this is already getting addressed itself with the GPUVA where likely the
|
||||
userptr will be a GPUVA with a NULL GEM call VM bind directly on the userptr.
|
||||
However, there are more aspects around the rules for that and the usage of
|
||||
mmu_notifiers, locking and other aspects.
|
||||
|
||||
This task here has the goal of introducing a documentation of the basic rules.
|
||||
|
||||
The documentation *needs* to first live in this document (API session below) and
|
||||
then moved to another more specific document or at Xe level or at DRM level.
|
||||
|
||||
Documentation should include:
|
||||
|
||||
* The userptr part of the VM_BIND api.
|
||||
|
||||
* Locking, including the page-faulting case.
|
||||
|
||||
* O(1) complexity under VM_BIND.
|
||||
|
||||
Some parts of userptr like mmu_notifiers should become GPUVA or DRM helpers when
|
||||
the second driver supporting VM_BIND+userptr appears. Details to be defined when
|
||||
the time comes.
|
||||
|
||||
Long running compute: minimal data structure/scaffolding
|
||||
--------------------------------------------------------
|
||||
The generic scheduler code needs to include the handling of endless compute
|
||||
contexts, with the minimal scaffolding for preempt-ctx fences (probably on the
|
||||
drm_sched_entity) and making sure drm_scheduler can cope with the lack of job
|
||||
completion fence.
|
||||
|
||||
The goal is to achieve a consensus ahead of Xe initial pull-request, ideally with
|
||||
this minimal drm/scheduler work, if needed, merged to drm-misc in a way that any
|
||||
drm driver, including Xe, could re-use and add their own individual needs on top
|
||||
in a next stage. However, this should not block the initial merge.
|
||||
|
||||
This is a non-blocker item since the driver without the support for the long
|
||||
running compute enabled is not a showstopper.
|
||||
|
||||
Display integration with i915
|
||||
-----------------------------
|
||||
In order to share the display code with the i915 driver so that there is maximum
|
||||
reuse, the i915/display/ code is built twice, once for i915.ko and then for
|
||||
xe.ko. Currently, the i915/display code in Xe tree is polluted with many 'ifdefs'
|
||||
depending on the build target. The goal is to refactor both Xe and i915/display
|
||||
code simultaneously in order to get a clean result before they land upstream, so
|
||||
that display can already be part of the initial pull request towards drm-next.
|
||||
|
||||
However, display code should not gate the acceptance of Xe in upstream. Xe
|
||||
patches will be refactored in a way that display code can be removed, if needed,
|
||||
from the first pull request of Xe towards drm-next. The expectation is that when
|
||||
both drivers are part of the drm-tip, the introduction of cleaner patches will be
|
||||
easier and speed up.
|
||||
|
||||
Drm_exec
|
||||
--------
|
||||
Helper to make dma_resv locking for a big number of buffers is getting removed in
|
||||
the drm_exec series proposed in https://patchwork.freedesktop.org/patch/524376/
|
||||
If that happens, Xe needs to change and incorporate the changes in the driver.
|
||||
The goal is to engage with the Community to understand if the best approach is to
|
||||
move that to the drivers that are using it or if we should keep the helpers in
|
||||
place waiting for Xe to get merged.
|
||||
|
||||
This item ties into the GPUVA, VM_BIND, and even long-running compute support.
|
||||
|
||||
As a key measurable result, we need to have a community consensus documented in
|
||||
this document and the Xe driver prepared for the changes, if necessary.
|
||||
|
||||
Dev_coredump
|
||||
------------
|
||||
|
||||
Xe needs to align with other drivers on the way that the error states are
|
||||
dumped, avoiding a Xe only error_state solution. The goal is to use devcoredump
|
||||
infrastructure to report error states, since it produces a standardized way
|
||||
by exposing a virtual and temporary /sys/class/devcoredump device.
|
||||
|
||||
As the key measurable result, Xe driver needs to provide GPU snapshots captured
|
||||
at hang time through devcoredump, but without depending on any core modification
|
||||
of devcoredump infrastructure itself.
|
||||
|
||||
Later, when we are in-tree, the goal is to collaborate with devcoredump
|
||||
infrastructure with overall possible improvements, like multiple file support
|
||||
for better organization of the dumps, snapshot support, dmesg extra print,
|
||||
and whatever may make sense and help the overall infrastructure.
|
||||
|
||||
Xe – uAPI high level overview
|
||||
=============================
|
||||
|
||||
...Warning: To be done in follow up patches after/when/where the main consensus in various items are individually reached.
|
@ -276,11 +276,8 @@ Various hold-ups:
|
||||
- Need to switch to drm_fbdev_generic_setup(), otherwise a lot of the custom fb
|
||||
setup code can't be deleted.
|
||||
|
||||
- Many drivers wrap drm_gem_fb_create() only to check for valid formats. For
|
||||
atomic drivers we could check for valid formats by calling
|
||||
drm_plane_check_pixel_format() against all planes, and pass if any plane
|
||||
supports the format. For non-atomic that's not possible since like the format
|
||||
list for the primary plane is fake and we'd therefor reject valid formats.
|
||||
- Need to switch to drm_gem_fb_create(), as now drm_gem_fb_create() checks for
|
||||
valid formats for atomic drivers.
|
||||
|
||||
- Many drivers subclass drm_framebuffer, we'd need a embedding compatible
|
||||
version of the varios drm_gem_fb_create functions. Maybe called
|
||||
|
@ -118,14 +118,9 @@ Add Plane Features
|
||||
|
||||
There's lots of plane features we could add support for:
|
||||
|
||||
- ARGB format on primary plane: blend the primary plane into background with
|
||||
translucent alpha.
|
||||
|
||||
- Add background color KMS property[Good to get started].
|
||||
|
||||
- Full alpha blending on all planes.
|
||||
|
||||
- Rotation, scaling.
|
||||
- Scaling.
|
||||
|
||||
- Additional buffer formats, especially YUV formats for video like NV12.
|
||||
Low/high bpp RGB formats would also be interesting.
|
||||
|
@ -776,10 +776,11 @@ peer_notif_delay
|
||||
Specify the delay, in milliseconds, between each peer
|
||||
notification (gratuitous ARP and unsolicited IPv6 Neighbor
|
||||
Advertisement) when they are issued after a failover event.
|
||||
This delay should be a multiple of the link monitor interval
|
||||
(arp_interval or miimon, whichever is active). The default
|
||||
value is 0 which means to match the value of the link monitor
|
||||
interval.
|
||||
This delay should be a multiple of the MII link monitor interval
|
||||
(miimon).
|
||||
|
||||
The valid range is 0 - 300000. The default value is 0, which means
|
||||
to match the value of the MII link monitor interval.
|
||||
|
||||
prio
|
||||
Slave priority. A higher number means higher priority.
|
||||
|
@ -116,8 +116,8 @@ Contents:
|
||||
udplite
|
||||
vrf
|
||||
vxlan
|
||||
x25-iface
|
||||
x25
|
||||
x25-iface
|
||||
xfrm_device
|
||||
xfrm_proc
|
||||
xfrm_sync
|
||||
|
@ -1,8 +1,7 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
============================-
|
||||
X.25 Device Driver Interface
|
||||
============================-
|
||||
============================
|
||||
|
||||
Version 1.1
|
||||
|
||||
|
2256
MAINTAINERS
2256
MAINTAINERS
File diff suppressed because it is too large
Load Diff
2
Makefile
2
Makefile
@ -2,7 +2,7 @@
|
||||
VERSION = 6
|
||||
PATCHLEVEL = 4
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc1
|
||||
EXTRAVERSION = -rc2
|
||||
NAME = Hurr durr I'ma ninja sloth
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
@ -1,20 +1,8 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
|
||||
#ifndef _ASM_FB_H_
|
||||
#define _ASM_FB_H_
|
||||
|
||||
#include <linux/fb.h>
|
||||
#include <linux/fs.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
|
||||
unsigned long off)
|
||||
{
|
||||
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
|
||||
}
|
||||
|
||||
static inline int fb_is_primary_device(struct fb_info *info)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#include <asm-generic/fb.h>
|
||||
|
||||
#endif /* _ASM_FB_H_ */
|
||||
|
@ -1,19 +1,6 @@
|
||||
#ifndef _ASM_FB_H_
|
||||
#define _ASM_FB_H_
|
||||
|
||||
#include <linux/fb.h>
|
||||
#include <linux/fs.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
|
||||
unsigned long off)
|
||||
{
|
||||
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
|
||||
}
|
||||
|
||||
static inline int fb_is_primary_device(struct fb_info *info)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#include <asm-generic/fb.h>
|
||||
|
||||
#endif /* _ASM_FB_H_ */
|
||||
|
@ -308,6 +308,29 @@ static int unwind_exec_pop_subset_r0_to_r3(struct unwind_ctrl_block *ctrl,
|
||||
return URC_OK;
|
||||
}
|
||||
|
||||
static unsigned long unwind_decode_uleb128(struct unwind_ctrl_block *ctrl)
|
||||
{
|
||||
unsigned long bytes = 0;
|
||||
unsigned long insn;
|
||||
unsigned long result = 0;
|
||||
|
||||
/*
|
||||
* unwind_get_byte() will advance `ctrl` one instruction at a time, so
|
||||
* loop until we get an instruction byte where bit 7 is not set.
|
||||
*
|
||||
* Note: This decodes a maximum of 4 bytes to output 28 bits data where
|
||||
* max is 0xfffffff: that will cover a vsp increment of 1073742336, hence
|
||||
* it is sufficient for unwinding the stack.
|
||||
*/
|
||||
do {
|
||||
insn = unwind_get_byte(ctrl);
|
||||
result |= (insn & 0x7f) << (bytes * 7);
|
||||
bytes++;
|
||||
} while (!!(insn & 0x80) && (bytes != sizeof(result)));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute the current unwind instruction.
|
||||
*/
|
||||
@ -361,7 +384,7 @@ static int unwind_exec_insn(struct unwind_ctrl_block *ctrl)
|
||||
if (ret)
|
||||
goto error;
|
||||
} else if (insn == 0xb2) {
|
||||
unsigned long uleb128 = unwind_get_byte(ctrl);
|
||||
unsigned long uleb128 = unwind_decode_uleb128(ctrl);
|
||||
|
||||
ctrl->vrs[SP] += 0x204 + (uleb128 << 2);
|
||||
} else {
|
||||
|
@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/**
|
||||
/*
|
||||
* arch/arm/mac-sa1100/jornada720_ssp.c
|
||||
*
|
||||
* Copyright (C) 2006/2007 Kristoffer Ericson <Kristoffer.Ericson@gmail.com>
|
||||
@ -26,6 +26,7 @@ static unsigned long jornada_ssp_flags;
|
||||
|
||||
/**
|
||||
* jornada_ssp_reverse - reverses input byte
|
||||
* @byte: input byte to reverse
|
||||
*
|
||||
* we need to reverse all data we receive from the mcu due to its physical location
|
||||
* returns : 01110111 -> 11101110
|
||||
@ -46,6 +47,7 @@ EXPORT_SYMBOL(jornada_ssp_reverse);
|
||||
|
||||
/**
|
||||
* jornada_ssp_byte - waits for ready ssp bus and sends byte
|
||||
* @byte: input byte to transmit
|
||||
*
|
||||
* waits for fifo buffer to clear and then transmits, if it doesn't then we will
|
||||
* timeout after <timeout> rounds. Needs mcu running before its called.
|
||||
@ -77,6 +79,7 @@ EXPORT_SYMBOL(jornada_ssp_byte);
|
||||
|
||||
/**
|
||||
* jornada_ssp_inout - decide if input is command or trading byte
|
||||
* @byte: input byte to send (may be %TXDUMMY)
|
||||
*
|
||||
* returns : (jornada_ssp_byte(byte)) on success
|
||||
* : %-ETIMEDOUT on timeout failure
|
||||
|
@ -23,6 +23,9 @@
|
||||
@
|
||||
ENTRY(do_vfp)
|
||||
mov r1, r10
|
||||
mov r3, r9
|
||||
b vfp_entry
|
||||
str lr, [sp, #-8]!
|
||||
add r3, sp, #4
|
||||
str r9, [r3]
|
||||
bl vfp_entry
|
||||
ldr pc, [sp], #8
|
||||
ENDPROC(do_vfp)
|
||||
|
@ -172,13 +172,14 @@ vfp_hw_state_valid:
|
||||
@ out before setting an FPEXC that
|
||||
@ stops us reading stuff
|
||||
VFPFMXR FPEXC, r1 @ Restore FPEXC last
|
||||
mov sp, r3 @ we think we have handled things
|
||||
pop {lr}
|
||||
sub r2, r2, #4 @ Retry current instruction - if Thumb
|
||||
str r2, [sp, #S_PC] @ mode it's two 16-bit instructions,
|
||||
@ else it's one 32-bit instruction, so
|
||||
@ always subtract 4 from the following
|
||||
@ instruction address.
|
||||
|
||||
mov lr, r3 @ we think we have handled things
|
||||
local_bh_enable_and_ret:
|
||||
adr r0, .
|
||||
mov r1, #SOFTIRQ_DISABLE_OFFSET
|
||||
@ -209,8 +210,9 @@ skip:
|
||||
|
||||
process_exception:
|
||||
DBGSTR "bounce"
|
||||
mov sp, r3 @ setup for a return to the user code.
|
||||
pop {lr}
|
||||
mov r2, sp @ nothing stacked - regdump is at TOS
|
||||
mov lr, r3 @ setup for a return to the user code.
|
||||
|
||||
@ Now call the C code to package up the bounce to the support code
|
||||
@ r0 holds the trigger instruction
|
||||
|
@ -5,19 +5,6 @@
|
||||
#ifndef __ASM_FB_H_
|
||||
#define __ASM_FB_H_
|
||||
|
||||
#include <linux/fb.h>
|
||||
#include <linux/fs.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
|
||||
unsigned long off)
|
||||
{
|
||||
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
|
||||
}
|
||||
|
||||
static inline int fb_is_primary_device(struct fb_info *info)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#include <asm-generic/fb.h>
|
||||
|
||||
#endif /* __ASM_FB_H_ */
|
||||
|
@ -2,11 +2,14 @@
|
||||
#ifndef _ASM_FB_H_
|
||||
#define _ASM_FB_H_
|
||||
|
||||
#include <linux/fb.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/efi.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
#include <asm/page.h>
|
||||
|
||||
struct file;
|
||||
|
||||
static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
|
||||
unsigned long off)
|
||||
{
|
||||
@ -15,10 +18,26 @@ static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
|
||||
else
|
||||
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
|
||||
}
|
||||
#define fb_pgprotect fb_pgprotect
|
||||
|
||||
static inline int fb_is_primary_device(struct fb_info *info)
|
||||
static inline void fb_memcpy_fromio(void *to, const volatile void __iomem *from, size_t n)
|
||||
{
|
||||
return 0;
|
||||
memcpy(to, (void __force *)from, n);
|
||||
}
|
||||
#define fb_memcpy_fromio fb_memcpy_fromio
|
||||
|
||||
static inline void fb_memcpy_toio(volatile void __iomem *to, const void *from, size_t n)
|
||||
{
|
||||
memcpy((void __force *)to, from, n);
|
||||
}
|
||||
#define fb_memcpy_toio fb_memcpy_toio
|
||||
|
||||
static inline void fb_memset_io(volatile void __iomem *addr, int c, size_t n)
|
||||
{
|
||||
memset((void __force *)addr, c, n);
|
||||
}
|
||||
#define fb_memset fb_memset_io
|
||||
|
||||
#include <asm-generic/fb.h>
|
||||
|
||||
#endif /* _ASM_FB_H_ */
|
||||
|
@ -5,19 +5,27 @@
|
||||
#ifndef _ASM_FB_H_
|
||||
#define _ASM_FB_H_
|
||||
|
||||
#include <linux/fb.h>
|
||||
#include <linux/fs.h>
|
||||
#include <asm/page.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
|
||||
unsigned long off)
|
||||
static inline void fb_memcpy_fromio(void *to, const volatile void __iomem *from, size_t n)
|
||||
{
|
||||
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
|
||||
memcpy(to, (void __force *)from, n);
|
||||
}
|
||||
#define fb_memcpy_fromio fb_memcpy_fromio
|
||||
|
||||
static inline int fb_is_primary_device(struct fb_info *info)
|
||||
static inline void fb_memcpy_toio(volatile void __iomem *to, const void *from, size_t n)
|
||||
{
|
||||
return 0;
|
||||
memcpy((void __force *)to, from, n);
|
||||
}
|
||||
#define fb_memcpy_toio fb_memcpy_toio
|
||||
|
||||
static inline void fb_memset_io(volatile void __iomem *addr, int c, size_t n)
|
||||
{
|
||||
memset((void __force *)addr, c, n);
|
||||
}
|
||||
#define fb_memset fb_memset_io
|
||||
|
||||
#include <asm-generic/fb.h>
|
||||
|
||||
#endif /* _ASM_FB_H_ */
|
||||
|
@ -2,22 +2,18 @@
|
||||
#ifndef _ASM_FB_H_
|
||||
#define _ASM_FB_H_
|
||||
|
||||
#include <linux/fb.h>
|
||||
#include <linux/fs.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/setup.h>
|
||||
|
||||
struct file;
|
||||
|
||||
static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
|
||||
unsigned long off)
|
||||
{
|
||||
#ifdef CONFIG_MMU
|
||||
#ifdef CONFIG_SUN3
|
||||
static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
|
||||
unsigned long off)
|
||||
{
|
||||
pgprot_val(vma->vm_page_prot) |= SUN3_PAGE_NOCACHE;
|
||||
}
|
||||
#else
|
||||
static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
|
||||
unsigned long off)
|
||||
{
|
||||
if (CPU_IS_020_OR_030)
|
||||
pgprot_val(vma->vm_page_prot) |= _PAGE_NOCACHE030;
|
||||
if (CPU_IS_040_OR_060) {
|
||||
@ -25,15 +21,11 @@ static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
|
||||
/* Use no-cache mode, serialized */
|
||||
pgprot_val(vma->vm_page_prot) |= _PAGE_NOCACHE_S;
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_SUN3 */
|
||||
#else
|
||||
#define fb_pgprotect(...) do {} while (0)
|
||||
#endif /* CONFIG_MMU */
|
||||
|
||||
static inline int fb_is_primary_device(struct fb_info *info)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#define fb_pgprotect fb_pgprotect
|
||||
|
||||
#include <asm-generic/fb.h>
|
||||
|
||||
#endif /* _ASM_FB_H_ */
|
||||
|
@ -1,19 +1,39 @@
|
||||
#ifndef _ASM_FB_H_
|
||||
#define _ASM_FB_H_
|
||||
|
||||
#include <linux/fb.h>
|
||||
#include <linux/fs.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
struct file;
|
||||
|
||||
static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
|
||||
unsigned long off)
|
||||
{
|
||||
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
|
||||
}
|
||||
#define fb_pgprotect fb_pgprotect
|
||||
|
||||
static inline int fb_is_primary_device(struct fb_info *info)
|
||||
/*
|
||||
* MIPS doesn't define __raw_ I/O macros, so the helpers
|
||||
* in <asm-generic/fb.h> don't generate fb_readq() and
|
||||
* fb_write(). We have to provide them here.
|
||||
*
|
||||
* TODO: Convert MIPS to generic I/O. The helpers below can
|
||||
* then be removed.
|
||||
*/
|
||||
#ifdef CONFIG_64BIT
|
||||
static inline u64 fb_readq(const volatile void __iomem *addr)
|
||||
{
|
||||
return 0;
|
||||
return __raw_readq(addr);
|
||||
}
|
||||
#define fb_readq fb_readq
|
||||
|
||||
static inline void fb_writeq(u64 b, volatile void __iomem *addr)
|
||||
{
|
||||
__raw_writeq(b, addr);
|
||||
}
|
||||
#define fb_writeq fb_writeq
|
||||
#endif
|
||||
|
||||
#include <asm-generic/fb.h>
|
||||
|
||||
#endif /* _ASM_FB_H_ */
|
||||
|
@ -11,7 +11,7 @@
|
||||
# Copyright (C) 1994 by Linus Torvalds
|
||||
# Portions Copyright (C) 1999 The Puffin Group
|
||||
#
|
||||
# Modified for PA-RISC Linux by Paul Lahaie, Alex deVries,
|
||||
# Modified for PA-RISC Linux by Paul Lahaie, Alex deVries,
|
||||
# Mike Shaver, Helge Deller and Martin K. Petersen
|
||||
#
|
||||
|
||||
@ -119,6 +119,8 @@ export LIBGCC
|
||||
|
||||
libs-y += arch/parisc/lib/ $(LIBGCC)
|
||||
|
||||
drivers-y += arch/parisc/video/
|
||||
|
||||
boot := arch/parisc/boot
|
||||
|
||||
PALO := $(shell if (which palo 2>&1); then : ; \
|
||||
|
@ -2,23 +2,13 @@
|
||||
#ifndef _ASM_FB_H_
|
||||
#define _ASM_FB_H_
|
||||
|
||||
#include <linux/fb.h>
|
||||
#include <linux/fs.h>
|
||||
#include <asm/page.h>
|
||||
struct fb_info;
|
||||
|
||||
static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
|
||||
unsigned long off)
|
||||
{
|
||||
pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_FB_STI)
|
||||
#if defined(CONFIG_STI_CORE)
|
||||
int fb_is_primary_device(struct fb_info *info);
|
||||
#else
|
||||
static inline int fb_is_primary_device(struct fb_info *info)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#define fb_is_primary_device fb_is_primary_device
|
||||
#endif
|
||||
|
||||
#include <asm-generic/fb.h>
|
||||
|
||||
#endif /* _ASM_FB_H_ */
|
||||
|
@ -413,12 +413,12 @@ extern void paging_init (void);
|
||||
* For the 64bit version, the offset is extended by 32bit.
|
||||
*/
|
||||
#define __swp_type(x) ((x).val & 0x1f)
|
||||
#define __swp_offset(x) ( (((x).val >> 6) & 0x7) | \
|
||||
(((x).val >> 8) & ~0x7) )
|
||||
#define __swp_offset(x) ( (((x).val >> 5) & 0x7) | \
|
||||
(((x).val >> 10) << 3) )
|
||||
#define __swp_entry(type, offset) ((swp_entry_t) { \
|
||||
((type) & 0x1f) | \
|
||||
((offset & 0x7) << 6) | \
|
||||
((offset & ~0x7) << 8) })
|
||||
((offset & 0x7) << 5) | \
|
||||
((offset >> 3) << 10) })
|
||||
#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
|
||||
#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
|
||||
|
||||
|
@ -4,6 +4,8 @@
|
||||
#include <linux/console.h>
|
||||
#include <linux/kexec.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/reboot.h>
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/sections.h>
|
||||
|
||||
|
3
arch/parisc/video/Makefile
Normal file
3
arch/parisc/video/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
obj-$(CONFIG_STI_CORE) += fbdev.o
|
26
arch/parisc/video/fbdev.c
Normal file
26
arch/parisc/video/fbdev.c
Normal file
@ -0,0 +1,26 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
|
||||
* Copyright (C) 2001-2020 Helge Deller <deller@gmx.de>
|
||||
* Copyright (C) 2001-2002 Thomas Bogendoerfer <tsbogend@alpha.franken.de>
|
||||
*/
|
||||
|
||||
#include <linux/fb.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <video/sticore.h>
|
||||
|
||||
int fb_is_primary_device(struct fb_info *info)
|
||||
{
|
||||
struct sti_struct *sti;
|
||||
|
||||
sti = sti_get_rom(0);
|
||||
|
||||
/* if no built-in graphics card found, allow any fb driver as default */
|
||||
if (!sti)
|
||||
return true;
|
||||
|
||||
/* return true if it's the default built-in framebuffer driver */
|
||||
return (sti->info == info);
|
||||
}
|
||||
EXPORT_SYMBOL(fb_is_primary_device);
|
@ -2,8 +2,8 @@
|
||||
#ifndef _ASM_FB_H_
|
||||
#define _ASM_FB_H_
|
||||
|
||||
#include <linux/fb.h>
|
||||
#include <linux/fs.h>
|
||||
|
||||
#include <asm/page.h>
|
||||
|
||||
static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
|
||||
@ -13,10 +13,8 @@ static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
|
||||
vma->vm_end - vma->vm_start,
|
||||
vma->vm_page_prot);
|
||||
}
|
||||
#define fb_pgprotect fb_pgprotect
|
||||
|
||||
static inline int fb_is_primary_device(struct fb_info *info)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#include <asm-generic/fb.h>
|
||||
|
||||
#endif /* _ASM_FB_H_ */
|
||||
|
@ -22,7 +22,7 @@ KCOV_INSTRUMENT := n
|
||||
|
||||
$(obj)/%.pi.o: OBJCOPYFLAGS := --prefix-symbols=__pi_ \
|
||||
--remove-section=.note.gnu.property \
|
||||
--prefix-alloc-sections=.init
|
||||
--prefix-alloc-sections=.init.pi
|
||||
$(obj)/%.pi.o: $(obj)/%.o FORCE
|
||||
$(call if_changed,objcopy)
|
||||
|
||||
|
@ -84,11 +84,8 @@ SECTIONS
|
||||
__init_data_begin = .;
|
||||
INIT_DATA_SECTION(16)
|
||||
|
||||
/* Those sections result from the compilation of kernel/pi/string.c */
|
||||
.init.pidata : {
|
||||
*(.init.srodata.cst8*)
|
||||
*(.init__bug_table*)
|
||||
*(.init.sdata*)
|
||||
.init.pi : {
|
||||
*(.init.pi*)
|
||||
}
|
||||
|
||||
.init.bss : {
|
||||
|
@ -2,19 +2,6 @@
|
||||
#ifndef _ASM_FB_H_
|
||||
#define _ASM_FB_H_
|
||||
|
||||
#include <linux/fb.h>
|
||||
#include <linux/fs.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
|
||||
unsigned long off)
|
||||
{
|
||||
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
|
||||
}
|
||||
|
||||
static inline int fb_is_primary_device(struct fb_info *info)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#include <asm-generic/fb.h>
|
||||
|
||||
#endif /* _ASM_FB_H_ */
|
||||
|
@ -60,6 +60,7 @@ libs-y += arch/sparc/prom/
|
||||
libs-y += arch/sparc/lib/
|
||||
|
||||
drivers-$(CONFIG_PM) += arch/sparc/power/
|
||||
drivers-$(CONFIG_FB) += arch/sparc/video/
|
||||
|
||||
boot := arch/sparc/boot
|
||||
|
||||
|
@ -1,34 +1,41 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _SPARC_FB_H_
|
||||
#define _SPARC_FB_H_
|
||||
#include <linux/console.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/fs.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/prom.h>
|
||||
|
||||
#include <linux/io.h>
|
||||
|
||||
struct fb_info;
|
||||
struct file;
|
||||
struct vm_area_struct;
|
||||
|
||||
#ifdef CONFIG_SPARC32
|
||||
static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
|
||||
unsigned long off)
|
||||
{
|
||||
#ifdef CONFIG_SPARC64
|
||||
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
|
||||
{ }
|
||||
#define fb_pgprotect fb_pgprotect
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline int fb_is_primary_device(struct fb_info *info)
|
||||
int fb_is_primary_device(struct fb_info *info);
|
||||
#define fb_is_primary_device fb_is_primary_device
|
||||
|
||||
static inline void fb_memcpy_fromio(void *to, const volatile void __iomem *from, size_t n)
|
||||
{
|
||||
struct device *dev = info->device;
|
||||
struct device_node *node;
|
||||
|
||||
if (console_set_on_cmdline)
|
||||
return 0;
|
||||
|
||||
node = dev->of_node;
|
||||
if (node &&
|
||||
node == of_console_device)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
sbus_memcpy_fromio(to, from, n);
|
||||
}
|
||||
#define fb_memcpy_fromio fb_memcpy_fromio
|
||||
|
||||
static inline void fb_memcpy_toio(volatile void __iomem *to, const void *from, size_t n)
|
||||
{
|
||||
sbus_memcpy_toio(to, from, n);
|
||||
}
|
||||
#define fb_memcpy_toio fb_memcpy_toio
|
||||
|
||||
static inline void fb_memset_io(volatile void __iomem *addr, int c, size_t n)
|
||||
{
|
||||
sbus_memset_io(addr, c, n);
|
||||
}
|
||||
#define fb_memset fb_memset_io
|
||||
|
||||
#include <asm-generic/fb.h>
|
||||
|
||||
#endif /* _SPARC_FB_H_ */
|
||||
|
3
arch/sparc/video/Makefile
Normal file
3
arch/sparc/video/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
obj-$(CONFIG_FB) += fbdev.o
|
23
arch/sparc/video/fbdev.c
Normal file
23
arch/sparc/video/fbdev.c
Normal file
@ -0,0 +1,23 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
#include <linux/console.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <asm/prom.h>
|
||||
|
||||
int fb_is_primary_device(struct fb_info *info)
|
||||
{
|
||||
struct device *dev = info->device;
|
||||
struct device_node *node;
|
||||
|
||||
if (console_set_on_cmdline)
|
||||
return 0;
|
||||
|
||||
node = dev->of_node;
|
||||
if (node && node == of_console_device)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(fb_is_primary_device);
|
@ -1703,10 +1703,8 @@ int x86_pmu_handle_irq(struct pt_regs *regs)
|
||||
|
||||
perf_sample_data_init(&data, 0, event->hw.last_period);
|
||||
|
||||
if (has_branch_stack(event)) {
|
||||
data.br_stack = &cpuc->lbr_stack;
|
||||
data.sample_flags |= PERF_SAMPLE_BRANCH_STACK;
|
||||
}
|
||||
if (has_branch_stack(event))
|
||||
perf_sample_save_brstack(&data, event, &cpuc->lbr_stack);
|
||||
|
||||
if (perf_event_overflow(event, &data, regs))
|
||||
x86_pmu_stop(event, 0);
|
||||
|
@ -1229,12 +1229,14 @@ pebs_update_state(bool needed_cb, struct cpu_hw_events *cpuc,
|
||||
struct perf_event *event, bool add)
|
||||
{
|
||||
struct pmu *pmu = event->pmu;
|
||||
|
||||
/*
|
||||
* Make sure we get updated with the first PEBS
|
||||
* event. It will trigger also during removal, but
|
||||
* that does not hurt:
|
||||
*/
|
||||
bool update = cpuc->n_pebs == 1;
|
||||
if (cpuc->n_pebs == 1)
|
||||
cpuc->pebs_data_cfg = PEBS_UPDATE_DS_SW;
|
||||
|
||||
if (needed_cb != pebs_needs_sched_cb(cpuc)) {
|
||||
if (!needed_cb)
|
||||
@ -1242,7 +1244,7 @@ pebs_update_state(bool needed_cb, struct cpu_hw_events *cpuc,
|
||||
else
|
||||
perf_sched_cb_dec(pmu);
|
||||
|
||||
update = true;
|
||||
cpuc->pebs_data_cfg |= PEBS_UPDATE_DS_SW;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1252,24 +1254,13 @@ pebs_update_state(bool needed_cb, struct cpu_hw_events *cpuc,
|
||||
if (x86_pmu.intel_cap.pebs_baseline && add) {
|
||||
u64 pebs_data_cfg;
|
||||
|
||||
/* Clear pebs_data_cfg and pebs_record_size for first PEBS. */
|
||||
if (cpuc->n_pebs == 1) {
|
||||
cpuc->pebs_data_cfg = 0;
|
||||
cpuc->pebs_record_size = sizeof(struct pebs_basic);
|
||||
}
|
||||
|
||||
pebs_data_cfg = pebs_update_adaptive_cfg(event);
|
||||
|
||||
/* Update pebs_record_size if new event requires more data. */
|
||||
if (pebs_data_cfg & ~cpuc->pebs_data_cfg) {
|
||||
cpuc->pebs_data_cfg |= pebs_data_cfg;
|
||||
adaptive_pebs_record_size_update();
|
||||
update = true;
|
||||
}
|
||||
/*
|
||||
* Be sure to update the thresholds when we change the record.
|
||||
*/
|
||||
if (pebs_data_cfg & ~cpuc->pebs_data_cfg)
|
||||
cpuc->pebs_data_cfg |= pebs_data_cfg | PEBS_UPDATE_DS_SW;
|
||||
}
|
||||
|
||||
if (update)
|
||||
pebs_update_threshold(cpuc);
|
||||
}
|
||||
|
||||
void intel_pmu_pebs_add(struct perf_event *event)
|
||||
@ -1326,9 +1317,17 @@ static void intel_pmu_pebs_via_pt_enable(struct perf_event *event)
|
||||
wrmsrl(base + idx, value);
|
||||
}
|
||||
|
||||
static inline void intel_pmu_drain_large_pebs(struct cpu_hw_events *cpuc)
|
||||
{
|
||||
if (cpuc->n_pebs == cpuc->n_large_pebs &&
|
||||
cpuc->n_pebs != cpuc->n_pebs_via_pt)
|
||||
intel_pmu_drain_pebs_buffer();
|
||||
}
|
||||
|
||||
void intel_pmu_pebs_enable(struct perf_event *event)
|
||||
{
|
||||
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
|
||||
u64 pebs_data_cfg = cpuc->pebs_data_cfg & ~PEBS_UPDATE_DS_SW;
|
||||
struct hw_perf_event *hwc = &event->hw;
|
||||
struct debug_store *ds = cpuc->ds;
|
||||
unsigned int idx = hwc->idx;
|
||||
@ -1344,11 +1343,22 @@ void intel_pmu_pebs_enable(struct perf_event *event)
|
||||
|
||||
if (x86_pmu.intel_cap.pebs_baseline) {
|
||||
hwc->config |= ICL_EVENTSEL_ADAPTIVE;
|
||||
if (cpuc->pebs_data_cfg != cpuc->active_pebs_data_cfg) {
|
||||
wrmsrl(MSR_PEBS_DATA_CFG, cpuc->pebs_data_cfg);
|
||||
cpuc->active_pebs_data_cfg = cpuc->pebs_data_cfg;
|
||||
if (pebs_data_cfg != cpuc->active_pebs_data_cfg) {
|
||||
/*
|
||||
* drain_pebs() assumes uniform record size;
|
||||
* hence we need to drain when changing said
|
||||
* size.
|
||||
*/
|
||||
intel_pmu_drain_large_pebs(cpuc);
|
||||
adaptive_pebs_record_size_update();
|
||||
wrmsrl(MSR_PEBS_DATA_CFG, pebs_data_cfg);
|
||||
cpuc->active_pebs_data_cfg = pebs_data_cfg;
|
||||
}
|
||||
}
|
||||
if (cpuc->pebs_data_cfg & PEBS_UPDATE_DS_SW) {
|
||||
cpuc->pebs_data_cfg = pebs_data_cfg;
|
||||
pebs_update_threshold(cpuc);
|
||||
}
|
||||
|
||||
if (idx >= INTEL_PMC_IDX_FIXED) {
|
||||
if (x86_pmu.intel_cap.pebs_format < 5)
|
||||
@ -1391,9 +1401,7 @@ void intel_pmu_pebs_disable(struct perf_event *event)
|
||||
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
|
||||
struct hw_perf_event *hwc = &event->hw;
|
||||
|
||||
if (cpuc->n_pebs == cpuc->n_large_pebs &&
|
||||
cpuc->n_pebs != cpuc->n_pebs_via_pt)
|
||||
intel_pmu_drain_pebs_buffer();
|
||||
intel_pmu_drain_large_pebs(cpuc);
|
||||
|
||||
cpuc->pebs_enabled &= ~(1ULL << hwc->idx);
|
||||
|
||||
|
@ -2,21 +2,16 @@
|
||||
#ifndef _ASM_X86_FB_H
|
||||
#define _ASM_X86_FB_H
|
||||
|
||||
#include <linux/fb.h>
|
||||
#include <linux/fs.h>
|
||||
#include <asm/page.h>
|
||||
struct fb_info;
|
||||
struct file;
|
||||
struct vm_area_struct;
|
||||
|
||||
static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
|
||||
unsigned long off)
|
||||
{
|
||||
unsigned long prot;
|
||||
void fb_pgprotect(struct file *file, struct vm_area_struct *vma, unsigned long off);
|
||||
#define fb_pgprotect fb_pgprotect
|
||||
|
||||
prot = pgprot_val(vma->vm_page_prot) & ~_PAGE_CACHE_MASK;
|
||||
if (boot_cpu_data.x86 > 3)
|
||||
pgprot_val(vma->vm_page_prot) =
|
||||
prot | cachemode2protval(_PAGE_CACHE_MODE_UC_MINUS);
|
||||
}
|
||||
int fb_is_primary_device(struct fb_info *info);
|
||||
#define fb_is_primary_device fb_is_primary_device
|
||||
|
||||
extern int fb_is_primary_device(struct fb_info *info);
|
||||
#include <asm-generic/fb.h>
|
||||
|
||||
#endif /* _ASM_X86_FB_H */
|
||||
|
@ -121,6 +121,9 @@
|
||||
#define PEBS_DATACFG_LBRS BIT_ULL(3)
|
||||
#define PEBS_DATACFG_LBR_SHIFT 24
|
||||
|
||||
/* Steal the highest bit of pebs_data_cfg for SW usage */
|
||||
#define PEBS_UPDATE_DS_SW BIT_ULL(63)
|
||||
|
||||
/*
|
||||
* Intel "Architectural Performance Monitoring" CPUID
|
||||
* detection/enumeration details:
|
||||
|
@ -36,6 +36,7 @@
|
||||
#define PCI_DEVICE_ID_AMD_19H_M50H_DF_F4 0x166e
|
||||
#define PCI_DEVICE_ID_AMD_19H_M60H_DF_F4 0x14e4
|
||||
#define PCI_DEVICE_ID_AMD_19H_M70H_DF_F4 0x14f4
|
||||
#define PCI_DEVICE_ID_AMD_19H_M78H_DF_F4 0x12fc
|
||||
|
||||
/* Protect the PCI config register pairs used for SMN. */
|
||||
static DEFINE_MUTEX(smn_mutex);
|
||||
@ -79,6 +80,7 @@ static const struct pci_device_id amd_nb_misc_ids[] = {
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M50H_DF_F3) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M60H_DF_F3) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M70H_DF_F3) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M78H_DF_F3) },
|
||||
{}
|
||||
};
|
||||
|
||||
|
@ -144,8 +144,8 @@ SYM_CODE_END(__x86_indirect_jump_thunk_array)
|
||||
*/
|
||||
.align 64
|
||||
.skip 63, 0xcc
|
||||
SYM_FUNC_START_NOALIGN(zen_untrain_ret);
|
||||
|
||||
SYM_START(zen_untrain_ret, SYM_L_GLOBAL, SYM_A_NONE)
|
||||
ANNOTATE_NOENDBR
|
||||
/*
|
||||
* As executed from zen_untrain_ret, this is:
|
||||
*
|
||||
|
@ -6,35 +6,37 @@
|
||||
* for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/fb.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/vgaarb.h>
|
||||
|
||||
void fb_pgprotect(struct file *file, struct vm_area_struct *vma, unsigned long off)
|
||||
{
|
||||
unsigned long prot;
|
||||
|
||||
prot = pgprot_val(vma->vm_page_prot) & ~_PAGE_CACHE_MASK;
|
||||
if (boot_cpu_data.x86 > 3)
|
||||
pgprot_val(vma->vm_page_prot) =
|
||||
prot | cachemode2protval(_PAGE_CACHE_MODE_UC_MINUS);
|
||||
}
|
||||
EXPORT_SYMBOL(fb_pgprotect);
|
||||
|
||||
int fb_is_primary_device(struct fb_info *info)
|
||||
{
|
||||
struct device *device = info->device;
|
||||
struct pci_dev *default_device = vga_default_device();
|
||||
struct pci_dev *pci_dev;
|
||||
struct resource *res;
|
||||
|
||||
if (!device || !dev_is_pci(device))
|
||||
return 0;
|
||||
|
||||
pci_dev = to_pci_dev(device);
|
||||
|
||||
if (default_device) {
|
||||
if (pci_dev == default_device)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
res = pci_dev->resource + PCI_ROM_RESOURCE;
|
||||
|
||||
if (res->flags & IORESOURCE_ROM_SHADOW)
|
||||
if (pci_dev == vga_default_device())
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(fb_is_primary_device);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -72,7 +72,7 @@ static int cfag12864bfb_probe(struct platform_device *device)
|
||||
if (!info)
|
||||
goto none;
|
||||
|
||||
info->screen_base = (char __iomem *) cfag12864b_buffer;
|
||||
info->screen_buffer = cfag12864b_buffer;
|
||||
info->screen_size = CFAG12864B_SIZE;
|
||||
info->fbops = &cfag12864bfb_ops;
|
||||
info->fix = cfag12864bfb_fix;
|
||||
|
@ -640,7 +640,7 @@ static int ht16k33_fbdev_probe(struct device *dev, struct ht16k33_priv *priv,
|
||||
|
||||
INIT_DELAYED_WORK(&priv->work, ht16k33_fb_update);
|
||||
fbdev->info->fbops = &ht16k33_fb_ops;
|
||||
fbdev->info->screen_base = (char __iomem *) fbdev->buffer;
|
||||
fbdev->info->screen_buffer = fbdev->buffer;
|
||||
fbdev->info->screen_size = HT16K33_FB_SIZE;
|
||||
fbdev->info->fix = ht16k33_fb_fix;
|
||||
fbdev->info->var = ht16k33_fb_var;
|
||||
|
@ -1666,7 +1666,7 @@ static int nbd_dev_dbg_init(struct nbd_device *nbd)
|
||||
return -EIO;
|
||||
|
||||
dir = debugfs_create_dir(nbd_name(nbd), nbd_dbg_dir);
|
||||
if (!dir) {
|
||||
if (IS_ERR(dir)) {
|
||||
dev_err(nbd_to_dev(nbd), "Failed to create debugfs dir for '%s'\n",
|
||||
nbd_name(nbd));
|
||||
return -EIO;
|
||||
@ -1692,7 +1692,7 @@ static int nbd_dbg_init(void)
|
||||
struct dentry *dbg_dir;
|
||||
|
||||
dbg_dir = debugfs_create_dir("nbd", NULL);
|
||||
if (!dbg_dir)
|
||||
if (IS_ERR(dbg_dir))
|
||||
return -EIO;
|
||||
|
||||
nbd_dbg_dir = dbg_dir;
|
||||
|
@ -241,7 +241,7 @@ static inline blk_opf_t rnbd_to_bio_flags(u32 rnbd_opf)
|
||||
bio_opf = REQ_OP_WRITE;
|
||||
break;
|
||||
case RNBD_OP_FLUSH:
|
||||
bio_opf = REQ_OP_FLUSH | REQ_PREFLUSH;
|
||||
bio_opf = REQ_OP_WRITE | REQ_PREFLUSH;
|
||||
break;
|
||||
case RNBD_OP_DISCARD:
|
||||
bio_opf = REQ_OP_DISCARD;
|
||||
|
@ -1281,7 +1281,7 @@ static inline int ublk_check_cmd_op(u32 cmd_op)
|
||||
{
|
||||
u32 ioc_type = _IOC_TYPE(cmd_op);
|
||||
|
||||
if (IS_ENABLED(CONFIG_BLKDEV_UBLK_LEGACY_OPCODES) && ioc_type != 'u')
|
||||
if (!IS_ENABLED(CONFIG_BLKDEV_UBLK_LEGACY_OPCODES) && ioc_type != 'u')
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (ioc_type != 'u' && ioc_type != 0)
|
||||
|
@ -571,6 +571,7 @@ void read_cdat_data(struct cxl_port *port)
|
||||
/* Don't leave table data allocated on error */
|
||||
devm_kfree(dev, cdat_table);
|
||||
dev_err(dev, "CDAT data read error\n");
|
||||
return;
|
||||
}
|
||||
|
||||
port->cdat.table = cdat_table + sizeof(__le32);
|
||||
|
@ -660,7 +660,7 @@ EXPORT_SYMBOL_GPL(dma_resv_get_singleton);
|
||||
* dma_resv_lock() already
|
||||
* RETURNS
|
||||
* Returns -ERESTARTSYS if interrupted, 0 if the wait timed out, or
|
||||
* greater than zer on success.
|
||||
* greater than zero on success.
|
||||
*/
|
||||
long dma_resv_wait_timeout(struct dma_resv *obj, enum dma_resv_usage usage,
|
||||
bool intr, unsigned long timeout)
|
||||
|
@ -85,7 +85,7 @@ static struct sync_timeline *sync_timeline_create(const char *name)
|
||||
|
||||
kref_init(&obj->kref);
|
||||
obj->context = dma_fence_context_alloc(1);
|
||||
strlcpy(obj->name, name, sizeof(obj->name));
|
||||
strscpy(obj->name, name, sizeof(obj->name));
|
||||
|
||||
obj->pt_tree = RB_ROOT;
|
||||
INIT_LIST_HEAD(&obj->pt_list);
|
||||
|
@ -706,21 +706,22 @@ static void fwnet_receive_packet(struct fw_card *card, struct fw_request *r,
|
||||
int rcode;
|
||||
|
||||
if (destination == IEEE1394_ALL_NODES) {
|
||||
kfree(r);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (offset != dev->handler.offset)
|
||||
// Although the response to the broadcast packet is not necessarily required, the
|
||||
// fw_send_response() function should still be called to maintain the reference
|
||||
// counting of the object. In the case, the call of function just releases the
|
||||
// object as a result to decrease the reference counting.
|
||||
rcode = RCODE_COMPLETE;
|
||||
} else if (offset != dev->handler.offset) {
|
||||
rcode = RCODE_ADDRESS_ERROR;
|
||||
else if (tcode != TCODE_WRITE_BLOCK_REQUEST)
|
||||
} else if (tcode != TCODE_WRITE_BLOCK_REQUEST) {
|
||||
rcode = RCODE_TYPE_ERROR;
|
||||
else if (fwnet_incoming_packet(dev, payload, length,
|
||||
source, generation, false) != 0) {
|
||||
} else if (fwnet_incoming_packet(dev, payload, length,
|
||||
source, generation, false) != 0) {
|
||||
dev_err(&dev->netdev->dev, "incoming packet failure\n");
|
||||
rcode = RCODE_CONFLICT_ERROR;
|
||||
} else
|
||||
} else {
|
||||
rcode = RCODE_COMPLETE;
|
||||
}
|
||||
|
||||
fw_send_response(card, r, rcode);
|
||||
}
|
||||
|
@ -128,4 +128,4 @@ unlock_mutex:
|
||||
}
|
||||
|
||||
/* must execute after PCI subsystem for EFI quirks */
|
||||
device_initcall(sysfb_init);
|
||||
subsys_initcall_sync(sysfb_init);
|
||||
|
@ -51,7 +51,8 @@ __init bool sysfb_parse_mode(const struct screen_info *si,
|
||||
*
|
||||
* It's not easily possible to fix this in struct screen_info,
|
||||
* as this could break UAPI. The best solution is to compute
|
||||
* bits_per_pixel here and ignore lfb_depth. In the loop below,
|
||||
* bits_per_pixel from the color bits, reserved bits and
|
||||
* reported lfb_depth, whichever is highest. In the loop below,
|
||||
* ignore simplefb formats with alpha bits, as EFI and VESA
|
||||
* don't specify alpha channels.
|
||||
*/
|
||||
@ -60,6 +61,7 @@ __init bool sysfb_parse_mode(const struct screen_info *si,
|
||||
si->green_size + si->green_pos,
|
||||
si->blue_size + si->blue_pos),
|
||||
si->rsvd_size + si->rsvd_pos);
|
||||
bits_per_pixel = max_t(u32, bits_per_pixel, si->lfb_depth);
|
||||
} else {
|
||||
bits_per_pixel = si->lfb_depth;
|
||||
}
|
||||
|
@ -3757,6 +3757,12 @@ int amdgpu_device_init(struct amdgpu_device *adev,
|
||||
adev->have_atomics_support = ((struct amd_sriov_msg_pf2vf_info *)
|
||||
adev->virt.fw_reserve.p_pf2vf)->pcie_atomic_ops_support_flags ==
|
||||
(PCI_EXP_DEVCAP2_ATOMIC_COMP32 | PCI_EXP_DEVCAP2_ATOMIC_COMP64);
|
||||
/* APUs w/ gfx9 onwards doesn't reply on PCIe atomics, rather it is a
|
||||
* internal path natively support atomics, set have_atomics_support to true.
|
||||
*/
|
||||
else if ((adev->flags & AMD_IS_APU) &&
|
||||
(adev->ip_versions[GC_HWIP][0] > IP_VERSION(9, 0, 0)))
|
||||
adev->have_atomics_support = true;
|
||||
else
|
||||
adev->have_atomics_support =
|
||||
!pci_enable_atomic_ops_to_root(adev->pdev,
|
||||
@ -4506,7 +4512,11 @@ static int amdgpu_device_recover_vram(struct amdgpu_device *adev)
|
||||
dev_info(adev->dev, "recover vram bo from shadow start\n");
|
||||
mutex_lock(&adev->shadow_list_lock);
|
||||
list_for_each_entry(vmbo, &adev->shadow_list, shadow_list) {
|
||||
shadow = &vmbo->bo;
|
||||
/* If vm is compute context or adev is APU, shadow will be NULL */
|
||||
if (!vmbo->shadow)
|
||||
continue;
|
||||
shadow = vmbo->shadow;
|
||||
|
||||
/* No need to recover an evicted BO */
|
||||
if (shadow->tbo.resource->mem_type != TTM_PL_TT ||
|
||||
shadow->tbo.resource->start == AMDGPU_BO_INVALID_OFFSET ||
|
||||
|
@ -687,9 +687,11 @@ int amdgpu_gfx_ras_late_init(struct amdgpu_device *adev, struct ras_common_if *r
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = amdgpu_irq_get(adev, &adev->gfx.cp_ecc_error_irq, 0);
|
||||
if (r)
|
||||
goto late_fini;
|
||||
if (adev->gfx.cp_ecc_error_irq.funcs) {
|
||||
r = amdgpu_irq_get(adev, &adev->gfx.cp_ecc_error_irq, 0);
|
||||
if (r)
|
||||
goto late_fini;
|
||||
}
|
||||
} else {
|
||||
amdgpu_ras_feature_enable_on_boot(adev, ras_block, 0);
|
||||
}
|
||||
|
@ -1315,13 +1315,6 @@ static int gfx_v11_0_sw_init(void *handle)
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* ECC error */
|
||||
r = amdgpu_irq_add_id(adev, SOC21_IH_CLIENTID_GRBM_CP,
|
||||
GFX_11_0_0__SRCID__CP_ECC_ERROR,
|
||||
&adev->gfx.cp_ecc_error_irq);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* FED error */
|
||||
r = amdgpu_irq_add_id(adev, SOC21_IH_CLIENTID_GFX,
|
||||
GFX_11_0_0__SRCID__RLC_GC_FED_INTERRUPT,
|
||||
@ -4444,7 +4437,6 @@ static int gfx_v11_0_hw_fini(void *handle)
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int r;
|
||||
|
||||
amdgpu_irq_put(adev, &adev->gfx.cp_ecc_error_irq, 0);
|
||||
amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
|
||||
amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
|
||||
|
||||
@ -5897,36 +5889,6 @@ static void gfx_v11_0_set_compute_eop_interrupt_state(struct amdgpu_device *adev
|
||||
}
|
||||
}
|
||||
|
||||
#define CP_ME1_PIPE_INST_ADDR_INTERVAL 0x1
|
||||
#define SET_ECC_ME_PIPE_STATE(reg_addr, state) \
|
||||
do { \
|
||||
uint32_t tmp = RREG32_SOC15_IP(GC, reg_addr); \
|
||||
tmp = REG_SET_FIELD(tmp, CP_ME1_PIPE0_INT_CNTL, CP_ECC_ERROR_INT_ENABLE, state); \
|
||||
WREG32_SOC15_IP(GC, reg_addr, tmp); \
|
||||
} while (0)
|
||||
|
||||
static int gfx_v11_0_set_cp_ecc_error_state(struct amdgpu_device *adev,
|
||||
struct amdgpu_irq_src *source,
|
||||
unsigned type,
|
||||
enum amdgpu_interrupt_state state)
|
||||
{
|
||||
uint32_t ecc_irq_state = 0;
|
||||
uint32_t pipe0_int_cntl_addr = 0;
|
||||
int i = 0;
|
||||
|
||||
ecc_irq_state = (state == AMDGPU_IRQ_STATE_ENABLE) ? 1 : 0;
|
||||
|
||||
pipe0_int_cntl_addr = SOC15_REG_OFFSET(GC, 0, regCP_ME1_PIPE0_INT_CNTL);
|
||||
|
||||
WREG32_FIELD15_PREREG(GC, 0, CP_INT_CNTL_RING0, CP_ECC_ERROR_INT_ENABLE, ecc_irq_state);
|
||||
|
||||
for (i = 0; i < adev->gfx.mec.num_pipe_per_mec; i++)
|
||||
SET_ECC_ME_PIPE_STATE(pipe0_int_cntl_addr + i * CP_ME1_PIPE_INST_ADDR_INTERVAL,
|
||||
ecc_irq_state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gfx_v11_0_set_eop_interrupt_state(struct amdgpu_device *adev,
|
||||
struct amdgpu_irq_src *src,
|
||||
unsigned type,
|
||||
@ -6341,11 +6303,6 @@ static const struct amdgpu_irq_src_funcs gfx_v11_0_priv_inst_irq_funcs = {
|
||||
.process = gfx_v11_0_priv_inst_irq,
|
||||
};
|
||||
|
||||
static const struct amdgpu_irq_src_funcs gfx_v11_0_cp_ecc_error_irq_funcs = {
|
||||
.set = gfx_v11_0_set_cp_ecc_error_state,
|
||||
.process = amdgpu_gfx_cp_ecc_error_irq,
|
||||
};
|
||||
|
||||
static const struct amdgpu_irq_src_funcs gfx_v11_0_rlc_gc_fed_irq_funcs = {
|
||||
.process = gfx_v11_0_rlc_gc_fed_irq,
|
||||
};
|
||||
@ -6361,9 +6318,6 @@ static void gfx_v11_0_set_irq_funcs(struct amdgpu_device *adev)
|
||||
adev->gfx.priv_inst_irq.num_types = 1;
|
||||
adev->gfx.priv_inst_irq.funcs = &gfx_v11_0_priv_inst_irq_funcs;
|
||||
|
||||
adev->gfx.cp_ecc_error_irq.num_types = 1; /* CP ECC error */
|
||||
adev->gfx.cp_ecc_error_irq.funcs = &gfx_v11_0_cp_ecc_error_irq_funcs;
|
||||
|
||||
adev->gfx.rlc_gc_fed_irq.num_types = 1; /* 0x80 FED error */
|
||||
adev->gfx.rlc_gc_fed_irq.funcs = &gfx_v11_0_rlc_gc_fed_irq_funcs;
|
||||
|
||||
|
@ -3764,7 +3764,8 @@ static int gfx_v9_0_hw_fini(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
amdgpu_irq_put(adev, &adev->gfx.cp_ecc_error_irq, 0);
|
||||
if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__GFX))
|
||||
amdgpu_irq_put(adev, &adev->gfx.cp_ecc_error_irq, 0);
|
||||
amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
|
||||
amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
|
||||
|
||||
|
@ -54,6 +54,7 @@ static int jpeg_v3_0_early_init(void *handle)
|
||||
|
||||
switch (adev->ip_versions[UVD_HWIP][0]) {
|
||||
case IP_VERSION(3, 1, 1):
|
||||
case IP_VERSION(3, 1, 2):
|
||||
break;
|
||||
default:
|
||||
harvest = RREG32_SOC15(JPEG, 0, mmCC_UVD_HARVESTING);
|
||||
|
@ -98,6 +98,16 @@ static const struct amdgpu_video_codecs nv_video_codecs_decode =
|
||||
};
|
||||
|
||||
/* Sienna Cichlid */
|
||||
static const struct amdgpu_video_codec_info sc_video_codecs_encode_array[] = {
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 2160, 0)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 7680, 4352, 0)},
|
||||
};
|
||||
|
||||
static const struct amdgpu_video_codecs sc_video_codecs_encode = {
|
||||
.codec_count = ARRAY_SIZE(sc_video_codecs_encode_array),
|
||||
.codec_array = sc_video_codecs_encode_array,
|
||||
};
|
||||
|
||||
static const struct amdgpu_video_codec_info sc_video_codecs_decode_array_vcn0[] =
|
||||
{
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)},
|
||||
@ -136,8 +146,8 @@ static const struct amdgpu_video_codecs sc_video_codecs_decode_vcn1 =
|
||||
/* SRIOV Sienna Cichlid, not const since data is controlled by host */
|
||||
static struct amdgpu_video_codec_info sriov_sc_video_codecs_encode_array[] =
|
||||
{
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 2304, 0)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 2304, 0)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 2160, 0)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 7680, 4352, 0)},
|
||||
};
|
||||
|
||||
static struct amdgpu_video_codec_info sriov_sc_video_codecs_decode_array_vcn0[] =
|
||||
@ -237,12 +247,12 @@ static int nv_query_video_codecs(struct amdgpu_device *adev, bool encode,
|
||||
} else {
|
||||
if (adev->vcn.harvest_config & AMDGPU_VCN_HARVEST_VCN0) {
|
||||
if (encode)
|
||||
*codecs = &nv_video_codecs_encode;
|
||||
*codecs = &sc_video_codecs_encode;
|
||||
else
|
||||
*codecs = &sc_video_codecs_decode_vcn1;
|
||||
} else {
|
||||
if (encode)
|
||||
*codecs = &nv_video_codecs_encode;
|
||||
*codecs = &sc_video_codecs_encode;
|
||||
else
|
||||
*codecs = &sc_video_codecs_decode_vcn0;
|
||||
}
|
||||
@ -251,14 +261,14 @@ static int nv_query_video_codecs(struct amdgpu_device *adev, bool encode,
|
||||
case IP_VERSION(3, 0, 16):
|
||||
case IP_VERSION(3, 0, 2):
|
||||
if (encode)
|
||||
*codecs = &nv_video_codecs_encode;
|
||||
*codecs = &sc_video_codecs_encode;
|
||||
else
|
||||
*codecs = &sc_video_codecs_decode_vcn0;
|
||||
return 0;
|
||||
case IP_VERSION(3, 1, 1):
|
||||
case IP_VERSION(3, 1, 2):
|
||||
if (encode)
|
||||
*codecs = &nv_video_codecs_encode;
|
||||
*codecs = &sc_video_codecs_encode;
|
||||
else
|
||||
*codecs = &yc_video_codecs_decode;
|
||||
return 0;
|
||||
|
@ -1917,9 +1917,11 @@ static int sdma_v4_0_hw_fini(void *handle)
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
amdgpu_irq_put(adev, &adev->sdma.ecc_irq,
|
||||
AMDGPU_SDMA_IRQ_INSTANCE0 + i);
|
||||
if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__SDMA)) {
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
amdgpu_irq_put(adev, &adev->sdma.ecc_irq,
|
||||
AMDGPU_SDMA_IRQ_INSTANCE0 + i);
|
||||
}
|
||||
}
|
||||
|
||||
sdma_v4_0_ctx_switch_enable(adev, false);
|
||||
|
@ -711,7 +711,7 @@ static int soc21_common_early_init(void *handle)
|
||||
AMD_PG_SUPPORT_VCN_DPG |
|
||||
AMD_PG_SUPPORT_GFX_PG |
|
||||
AMD_PG_SUPPORT_JPEG;
|
||||
adev->external_rev_id = adev->rev_id + 0x1;
|
||||
adev->external_rev_id = adev->rev_id + 0x80;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -423,3 +423,68 @@ void dcn314_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool
|
||||
|
||||
PERF_TRACE();
|
||||
}
|
||||
static void apply_symclk_on_tx_off_wa(struct dc_link *link)
|
||||
{
|
||||
/* There are use cases where SYMCLK is referenced by OTG. For instance
|
||||
* for TMDS signal, OTG relies SYMCLK even if TX video output is off.
|
||||
* However current link interface will power off PHY when disabling link
|
||||
* output. This will turn off SYMCLK generated by PHY. The workaround is
|
||||
* to identify such case where SYMCLK is still in use by OTG when we
|
||||
* power off PHY. When this is detected, we will temporarily power PHY
|
||||
* back on and move PHY's SYMCLK state to SYMCLK_ON_TX_OFF by calling
|
||||
* program_pix_clk interface. When OTG is disabled, we will then power
|
||||
* off PHY by calling disable link output again.
|
||||
*
|
||||
* In future dcn generations, we plan to rework transmitter control
|
||||
* interface so that we could have an option to set SYMCLK ON TX OFF
|
||||
* state in one step without this workaround
|
||||
*/
|
||||
|
||||
struct dc *dc = link->ctx->dc;
|
||||
struct pipe_ctx *pipe_ctx = NULL;
|
||||
uint8_t i;
|
||||
|
||||
if (link->phy_state.symclk_ref_cnts.otg > 0) {
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe_ctx->stream && pipe_ctx->stream->link == link && pipe_ctx->top_pipe == NULL) {
|
||||
pipe_ctx->clock_source->funcs->program_pix_clk(
|
||||
pipe_ctx->clock_source,
|
||||
&pipe_ctx->stream_res.pix_clk_params,
|
||||
dc->link_srv->dp_get_encoding_format(
|
||||
&pipe_ctx->link_config.dp_link_settings),
|
||||
&pipe_ctx->pll_settings);
|
||||
link->phy_state.symclk_state = SYMCLK_ON_TX_OFF;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dcn314_disable_link_output(struct dc_link *link,
|
||||
const struct link_resource *link_res,
|
||||
enum signal_type signal)
|
||||
{
|
||||
struct dc *dc = link->ctx->dc;
|
||||
const struct link_hwss *link_hwss = get_link_hwss(link, link_res);
|
||||
struct dmcu *dmcu = dc->res_pool->dmcu;
|
||||
|
||||
if (signal == SIGNAL_TYPE_EDP &&
|
||||
link->dc->hwss.edp_backlight_control)
|
||||
link->dc->hwss.edp_backlight_control(link, false);
|
||||
else if (dmcu != NULL && dmcu->funcs->lock_phy)
|
||||
dmcu->funcs->lock_phy(dmcu);
|
||||
|
||||
link_hwss->disable_link_output(link, link_res, signal);
|
||||
link->phy_state.symclk_state = SYMCLK_OFF_TX_OFF;
|
||||
/*
|
||||
* Add the logic to extract BOTH power up and power down sequences
|
||||
* from enable/disable link output and only call edp panel control
|
||||
* in enable_link_dp and disable_link_dp once.
|
||||
*/
|
||||
if (dmcu != NULL && dmcu->funcs->lock_phy)
|
||||
dmcu->funcs->unlock_phy(dmcu);
|
||||
dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY);
|
||||
|
||||
apply_symclk_on_tx_off_wa(link);
|
||||
}
|
||||
|
@ -45,4 +45,6 @@ void dcn314_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool
|
||||
|
||||
void dcn314_dpp_root_clock_control(struct dce_hwseq *hws, unsigned int dpp_inst, bool clock_on);
|
||||
|
||||
void dcn314_disable_link_output(struct dc_link *link, const struct link_resource *link_res, enum signal_type signal);
|
||||
|
||||
#endif /* __DC_HWSS_DCN314_H__ */
|
||||
|
@ -105,7 +105,7 @@ static const struct hw_sequencer_funcs dcn314_funcs = {
|
||||
.enable_lvds_link_output = dce110_enable_lvds_link_output,
|
||||
.enable_tmds_link_output = dce110_enable_tmds_link_output,
|
||||
.enable_dp_link_output = dce110_enable_dp_link_output,
|
||||
.disable_link_output = dce110_disable_link_output,
|
||||
.disable_link_output = dcn314_disable_link_output,
|
||||
.z10_restore = dcn31_z10_restore,
|
||||
.z10_save_init = dcn31_z10_save_init,
|
||||
.set_disp_pattern_generator = dcn30_set_disp_pattern_generator,
|
||||
|
@ -810,7 +810,8 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman
|
||||
v->SwathHeightY[k],
|
||||
v->SwathHeightC[k],
|
||||
TWait,
|
||||
v->DRAMSpeedPerState[mode_lib->vba.VoltageLevel] <= MEM_STROBE_FREQ_MHZ ?
|
||||
(v->DRAMSpeedPerState[mode_lib->vba.VoltageLevel] <= MEM_STROBE_FREQ_MHZ ||
|
||||
v->DCFCLKPerState[mode_lib->vba.VoltageLevel] <= MIN_DCFCLK_FREQ_MHZ) ?
|
||||
mode_lib->vba.ip.min_prefetch_in_strobe_us : 0,
|
||||
/* Output */
|
||||
&v->DSTXAfterScaler[k],
|
||||
@ -3310,7 +3311,7 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
v->swath_width_chroma_ub_this_state[k],
|
||||
v->SwathHeightYThisState[k],
|
||||
v->SwathHeightCThisState[k], v->TWait,
|
||||
v->DRAMSpeedPerState[i] <= MEM_STROBE_FREQ_MHZ ?
|
||||
(v->DRAMSpeedPerState[i] <= MEM_STROBE_FREQ_MHZ || v->DCFCLKState[i][j] <= MIN_DCFCLK_FREQ_MHZ) ?
|
||||
mode_lib->vba.ip.min_prefetch_in_strobe_us : 0,
|
||||
|
||||
/* Output */
|
||||
|
@ -53,6 +53,7 @@
|
||||
#define BPP_BLENDED_PIPE 0xffffffff
|
||||
|
||||
#define MEM_STROBE_FREQ_MHZ 1600
|
||||
#define MIN_DCFCLK_FREQ_MHZ 200
|
||||
#define MEM_STROBE_MAX_DELIVERY_TIME_US 60.0
|
||||
|
||||
struct display_mode_lib;
|
||||
|
@ -36,6 +36,8 @@
|
||||
#define amdgpu_dpm_enable_bapm(adev, e) \
|
||||
((adev)->powerplay.pp_funcs->enable_bapm((adev)->powerplay.pp_handle, (e)))
|
||||
|
||||
#define amdgpu_dpm_is_legacy_dpm(adev) ((adev)->powerplay.pp_handle == (adev))
|
||||
|
||||
int amdgpu_dpm_get_sclk(struct amdgpu_device *adev, bool low)
|
||||
{
|
||||
const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
|
||||
@ -1460,15 +1462,24 @@ int amdgpu_dpm_get_smu_prv_buf_details(struct amdgpu_device *adev,
|
||||
|
||||
int amdgpu_dpm_is_overdrive_supported(struct amdgpu_device *adev)
|
||||
{
|
||||
struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle;
|
||||
struct smu_context *smu = adev->powerplay.pp_handle;
|
||||
if (is_support_sw_smu(adev)) {
|
||||
struct smu_context *smu = adev->powerplay.pp_handle;
|
||||
|
||||
if ((is_support_sw_smu(adev) && smu->od_enabled) ||
|
||||
(is_support_sw_smu(adev) && smu->is_apu) ||
|
||||
(!is_support_sw_smu(adev) && hwmgr->od_enabled))
|
||||
return true;
|
||||
return (smu->od_enabled || smu->is_apu);
|
||||
} else {
|
||||
struct pp_hwmgr *hwmgr;
|
||||
|
||||
return false;
|
||||
/*
|
||||
* dpm on some legacy asics don't carry od_enabled member
|
||||
* as its pp_handle is casted directly from adev.
|
||||
*/
|
||||
if (amdgpu_dpm_is_legacy_dpm(adev))
|
||||
return false;
|
||||
|
||||
hwmgr = (struct pp_hwmgr *)adev->powerplay.pp_handle;
|
||||
|
||||
return hwmgr->od_enabled;
|
||||
}
|
||||
}
|
||||
|
||||
int amdgpu_dpm_set_pp_table(struct amdgpu_device *adev,
|
||||
|
@ -285,7 +285,7 @@ static int hdlcd_drm_bind(struct device *dev)
|
||||
*/
|
||||
if (hdlcd_read(hdlcd, HDLCD_REG_COMMAND)) {
|
||||
hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 0);
|
||||
drm_aperture_remove_framebuffers(false, &hdlcd_driver);
|
||||
drm_aperture_remove_framebuffers(&hdlcd_driver);
|
||||
}
|
||||
|
||||
drm_mode_config_reset(drm);
|
||||
|
@ -1,7 +1,8 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
armada-y := armada_crtc.o armada_drv.o armada_fb.o armada_fbdev.o \
|
||||
armada-y := armada_crtc.o armada_drv.o armada_fb.o \
|
||||
armada_gem.o armada_overlay.o armada_plane.o armada_trace.o
|
||||
armada-y += armada_510.o
|
||||
armada-$(CONFIG_DEBUG_FS) += armada_debugfs.o
|
||||
armada-$(CONFIG_DRM_FBDEV_EMULATION) += armada_fbdev.o
|
||||
|
||||
obj-$(CONFIG_DRM_ARMADA) := armada.o
|
||||
|
@ -16,7 +16,6 @@ struct armada_crtc;
|
||||
struct armada_gem_object;
|
||||
struct clk;
|
||||
struct drm_display_mode;
|
||||
struct drm_fb_helper;
|
||||
|
||||
static inline void
|
||||
armada_updatel(uint32_t val, uint32_t mask, void __iomem *ptr)
|
||||
@ -55,7 +54,6 @@ extern const struct armada_variant armada510_ops;
|
||||
|
||||
struct armada_private {
|
||||
struct drm_device drm;
|
||||
struct drm_fb_helper *fbdev;
|
||||
struct armada_crtc *dcrtc[2];
|
||||
struct drm_mm linear; /* protected by linear_lock */
|
||||
struct mutex linear_lock;
|
||||
@ -75,8 +73,12 @@ struct armada_private {
|
||||
|
||||
#define drm_to_armada_dev(dev) container_of(dev, struct armada_private, drm)
|
||||
|
||||
int armada_fbdev_init(struct drm_device *);
|
||||
void armada_fbdev_fini(struct drm_device *);
|
||||
#if defined(CONFIG_DRM_FBDEV_EMULATION)
|
||||
void armada_fbdev_setup(struct drm_device *dev);
|
||||
#else
|
||||
static inline void armada_fbdev_setup(struct drm_device *dev)
|
||||
{ }
|
||||
#endif
|
||||
|
||||
int armada_overlay_plane_create(struct drm_device *, unsigned long);
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <linux/clk.h>
|
||||
#include <linux/component.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_graph.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
@ -16,7 +17,6 @@
|
||||
#include <drm/drm_managed.h>
|
||||
#include <drm/drm_prime.h>
|
||||
#include <drm/drm_probe_helper.h>
|
||||
#include <drm/drm_fb_helper.h>
|
||||
#include <drm/drm_of.h>
|
||||
#include <drm/drm_vblank.h>
|
||||
|
||||
@ -37,7 +37,6 @@ static const struct drm_ioctl_desc armada_ioctls[] = {
|
||||
DEFINE_DRM_GEM_FOPS(armada_drm_fops);
|
||||
|
||||
static const struct drm_driver armada_drm_driver = {
|
||||
.lastclose = drm_fb_helper_lastclose,
|
||||
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
|
||||
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
|
||||
.gem_prime_import = armada_gem_prime_import,
|
||||
@ -55,7 +54,6 @@ static const struct drm_driver armada_drm_driver = {
|
||||
|
||||
static const struct drm_mode_config_funcs armada_drm_mode_config_funcs = {
|
||||
.fb_create = armada_fb_create,
|
||||
.output_poll_changed = drm_fb_helper_output_poll_changed,
|
||||
.atomic_check = drm_atomic_helper_check,
|
||||
.atomic_commit = drm_atomic_helper_commit,
|
||||
};
|
||||
@ -95,7 +93,7 @@ static int armada_drm_bind(struct device *dev)
|
||||
}
|
||||
|
||||
/* Remove early framebuffers */
|
||||
ret = drm_aperture_remove_framebuffers(false, &armada_drm_driver);
|
||||
ret = drm_aperture_remove_framebuffers(&armada_drm_driver);
|
||||
if (ret) {
|
||||
dev_err(dev, "[" DRM_NAME ":%s] can't kick out simple-fb: %d\n",
|
||||
__func__, ret);
|
||||
@ -131,10 +129,6 @@ static int armada_drm_bind(struct device *dev)
|
||||
|
||||
drm_mode_config_reset(&priv->drm);
|
||||
|
||||
ret = armada_fbdev_init(&priv->drm);
|
||||
if (ret)
|
||||
goto err_comp;
|
||||
|
||||
drm_kms_helper_poll_init(&priv->drm);
|
||||
|
||||
ret = drm_dev_register(&priv->drm, 0);
|
||||
@ -145,11 +139,12 @@ static int armada_drm_bind(struct device *dev)
|
||||
armada_drm_debugfs_init(priv->drm.primary);
|
||||
#endif
|
||||
|
||||
armada_fbdev_setup(&priv->drm);
|
||||
|
||||
return 0;
|
||||
|
||||
err_poll:
|
||||
drm_kms_helper_poll_fini(&priv->drm);
|
||||
armada_fbdev_fini(&priv->drm);
|
||||
err_comp:
|
||||
component_unbind_all(dev, &priv->drm);
|
||||
err_kms:
|
||||
@ -164,7 +159,6 @@ static void armada_drm_unbind(struct device *dev)
|
||||
struct armada_private *priv = drm_to_armada_dev(drm);
|
||||
|
||||
drm_kms_helper_poll_fini(&priv->drm);
|
||||
armada_fbdev_fini(&priv->drm);
|
||||
|
||||
drm_dev_unregister(&priv->drm);
|
||||
|
||||
|
@ -4,7 +4,6 @@
|
||||
*/
|
||||
|
||||
#include <drm/drm_modeset_helper.h>
|
||||
#include <drm/drm_fb_helper.h>
|
||||
#include <drm/drm_fourcc.h>
|
||||
#include <drm/drm_gem_framebuffer_helper.h>
|
||||
|
||||
|
@ -8,6 +8,8 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <drm/drm_crtc_helper.h>
|
||||
#include <drm/drm_drv.h>
|
||||
#include <drm/drm_fb_helper.h>
|
||||
#include <drm/drm_fourcc.h>
|
||||
|
||||
@ -16,6 +18,19 @@
|
||||
#include "armada_fb.h"
|
||||
#include "armada_gem.h"
|
||||
|
||||
static void armada_fbdev_fb_destroy(struct fb_info *info)
|
||||
{
|
||||
struct drm_fb_helper *fbh = info->par;
|
||||
|
||||
drm_fb_helper_fini(fbh);
|
||||
|
||||
fbh->fb->funcs->destroy(fbh->fb);
|
||||
|
||||
drm_client_release(&fbh->client);
|
||||
drm_fb_helper_unprepare(fbh);
|
||||
kfree(fbh);
|
||||
}
|
||||
|
||||
static const struct fb_ops armada_fb_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
DRM_FB_HELPER_DEFAULT_OPS,
|
||||
@ -24,6 +39,7 @@ static const struct fb_ops armada_fb_ops = {
|
||||
.fb_fillrect = drm_fb_helper_cfb_fillrect,
|
||||
.fb_copyarea = drm_fb_helper_cfb_copyarea,
|
||||
.fb_imageblit = drm_fb_helper_cfb_imageblit,
|
||||
.fb_destroy = armada_fbdev_fb_destroy,
|
||||
};
|
||||
|
||||
static int armada_fbdev_create(struct drm_fb_helper *fbh,
|
||||
@ -117,56 +133,95 @@ static const struct drm_fb_helper_funcs armada_fb_helper_funcs = {
|
||||
.fb_probe = armada_fb_probe,
|
||||
};
|
||||
|
||||
int armada_fbdev_init(struct drm_device *dev)
|
||||
/*
|
||||
* Fbdev client and struct drm_client_funcs
|
||||
*/
|
||||
|
||||
static void armada_fbdev_client_unregister(struct drm_client_dev *client)
|
||||
{
|
||||
struct armada_private *priv = drm_to_armada_dev(dev);
|
||||
struct drm_fb_helper *fbh;
|
||||
int ret;
|
||||
struct drm_fb_helper *fbh = drm_fb_helper_from_client(client);
|
||||
|
||||
fbh = devm_kzalloc(dev->dev, sizeof(*fbh), GFP_KERNEL);
|
||||
if (!fbh)
|
||||
return -ENOMEM;
|
||||
|
||||
priv->fbdev = fbh;
|
||||
|
||||
drm_fb_helper_prepare(dev, fbh, 32, &armada_fb_helper_funcs);
|
||||
|
||||
ret = drm_fb_helper_init(dev, fbh);
|
||||
if (ret) {
|
||||
DRM_ERROR("failed to initialize drm fb helper\n");
|
||||
goto err_fb_helper;
|
||||
if (fbh->info) {
|
||||
drm_fb_helper_unregister_info(fbh);
|
||||
} else {
|
||||
drm_client_release(&fbh->client);
|
||||
drm_fb_helper_unprepare(fbh);
|
||||
kfree(fbh);
|
||||
}
|
||||
}
|
||||
|
||||
ret = drm_fb_helper_initial_config(fbh);
|
||||
if (ret) {
|
||||
DRM_ERROR("failed to set initial config\n");
|
||||
goto err_fb_setup;
|
||||
}
|
||||
static int armada_fbdev_client_restore(struct drm_client_dev *client)
|
||||
{
|
||||
drm_fb_helper_lastclose(client->dev);
|
||||
|
||||
return 0;
|
||||
err_fb_setup:
|
||||
}
|
||||
|
||||
static int armada_fbdev_client_hotplug(struct drm_client_dev *client)
|
||||
{
|
||||
struct drm_fb_helper *fbh = drm_fb_helper_from_client(client);
|
||||
struct drm_device *dev = client->dev;
|
||||
int ret;
|
||||
|
||||
if (dev->fb_helper)
|
||||
return drm_fb_helper_hotplug_event(dev->fb_helper);
|
||||
|
||||
ret = drm_fb_helper_init(dev, fbh);
|
||||
if (ret)
|
||||
goto err_drm_err;
|
||||
|
||||
if (!drm_drv_uses_atomic_modeset(dev))
|
||||
drm_helper_disable_unused_functions(dev);
|
||||
|
||||
ret = drm_fb_helper_initial_config(fbh);
|
||||
if (ret)
|
||||
goto err_drm_fb_helper_fini;
|
||||
|
||||
return 0;
|
||||
|
||||
err_drm_fb_helper_fini:
|
||||
drm_fb_helper_fini(fbh);
|
||||
err_fb_helper:
|
||||
drm_fb_helper_unprepare(fbh);
|
||||
priv->fbdev = NULL;
|
||||
err_drm_err:
|
||||
drm_err(dev, "armada: Failed to setup fbdev emulation (ret=%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void armada_fbdev_fini(struct drm_device *dev)
|
||||
static const struct drm_client_funcs armada_fbdev_client_funcs = {
|
||||
.owner = THIS_MODULE,
|
||||
.unregister = armada_fbdev_client_unregister,
|
||||
.restore = armada_fbdev_client_restore,
|
||||
.hotplug = armada_fbdev_client_hotplug,
|
||||
};
|
||||
|
||||
void armada_fbdev_setup(struct drm_device *dev)
|
||||
{
|
||||
struct armada_private *priv = drm_to_armada_dev(dev);
|
||||
struct drm_fb_helper *fbh = priv->fbdev;
|
||||
struct drm_fb_helper *fbh;
|
||||
int ret;
|
||||
|
||||
if (fbh) {
|
||||
drm_fb_helper_unregister_info(fbh);
|
||||
drm_WARN(dev, !dev->registered, "Device has not been registered.\n");
|
||||
drm_WARN(dev, dev->fb_helper, "fb_helper is already set!\n");
|
||||
|
||||
drm_fb_helper_fini(fbh);
|
||||
fbh = kzalloc(sizeof(*fbh), GFP_KERNEL);
|
||||
if (!fbh)
|
||||
return;
|
||||
drm_fb_helper_prepare(dev, fbh, 32, &armada_fb_helper_funcs);
|
||||
|
||||
if (fbh->fb)
|
||||
fbh->fb->funcs->destroy(fbh->fb);
|
||||
|
||||
drm_fb_helper_unprepare(fbh);
|
||||
|
||||
priv->fbdev = NULL;
|
||||
ret = drm_client_init(dev, &fbh->client, "fbdev", &armada_fbdev_client_funcs);
|
||||
if (ret) {
|
||||
drm_err(dev, "Failed to register client: %d\n", ret);
|
||||
goto err_drm_client_init;
|
||||
}
|
||||
|
||||
ret = armada_fbdev_client_hotplug(&fbh->client);
|
||||
if (ret)
|
||||
drm_dbg_kms(dev, "client hotplug ret=%d\n", ret);
|
||||
|
||||
drm_client_register(&fbh->client);
|
||||
|
||||
return;
|
||||
|
||||
err_drm_client_init:
|
||||
drm_fb_helper_unprepare(fbh);
|
||||
kfree(fbh);
|
||||
return;
|
||||
}
|
||||
|
@ -425,11 +425,12 @@ struct ast_device *ast_device_create(const struct drm_driver *drv,
|
||||
return ERR_PTR(-EIO);
|
||||
|
||||
/*
|
||||
* If we don't have IO space at all, use MMIO now and
|
||||
* assume the chip has MMIO enabled by default (rev 0x20
|
||||
* and higher).
|
||||
* After AST2500, MMIO is enabled by default, and it should be adopted
|
||||
* to be compatible with Arm.
|
||||
*/
|
||||
if (!(pci_resource_flags(pdev, 2) & IORESOURCE_IO)) {
|
||||
if (pdev->revision >= 0x40) {
|
||||
ast->ioregs = ast->regs + AST_IO_MM_OFFSET;
|
||||
} else if (!(pci_resource_flags(pdev, 2) & IORESOURCE_IO)) {
|
||||
drm_info(dev, "platform has no IO space, trying MMIO\n");
|
||||
ast->ioregs = ast->regs + AST_IO_MM_OFFSET;
|
||||
}
|
||||
|
@ -17,7 +17,6 @@
|
||||
#include <linux/types.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/of_graph.h>
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
@ -1687,6 +1686,14 @@ static int anx7625_parse_dt(struct device *dev,
|
||||
if (of_property_read_bool(np, "analogix,audio-enable"))
|
||||
pdata->audio_en = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int anx7625_parse_dt_panel(struct device *dev,
|
||||
struct anx7625_platform_data *pdata)
|
||||
{
|
||||
struct device_node *np = dev->of_node;
|
||||
|
||||
pdata->panel_bridge = devm_drm_of_get_bridge(dev, np, 1, 0);
|
||||
if (IS_ERR(pdata->panel_bridge)) {
|
||||
if (PTR_ERR(pdata->panel_bridge) == -ENODEV) {
|
||||
@ -2032,7 +2039,7 @@ static int anx7625_register_audio(struct device *dev, struct anx7625_data *ctx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int anx7625_attach_dsi(struct anx7625_data *ctx)
|
||||
static int anx7625_setup_dsi_device(struct anx7625_data *ctx)
|
||||
{
|
||||
struct mipi_dsi_device *dsi;
|
||||
struct device *dev = &ctx->client->dev;
|
||||
@ -2042,9 +2049,6 @@ static int anx7625_attach_dsi(struct anx7625_data *ctx)
|
||||
.channel = 0,
|
||||
.node = NULL,
|
||||
};
|
||||
int ret;
|
||||
|
||||
DRM_DEV_DEBUG_DRIVER(dev, "attach dsi\n");
|
||||
|
||||
host = of_find_mipi_dsi_host_by_node(ctx->pdata.mipi_host_node);
|
||||
if (!host) {
|
||||
@ -2065,14 +2069,24 @@ static int anx7625_attach_dsi(struct anx7625_data *ctx)
|
||||
MIPI_DSI_MODE_VIDEO_HSE |
|
||||
MIPI_DSI_HS_PKT_END_ALIGNED;
|
||||
|
||||
ret = devm_mipi_dsi_attach(dev, dsi);
|
||||
ctx->dsi = dsi;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int anx7625_attach_dsi(struct anx7625_data *ctx)
|
||||
{
|
||||
struct device *dev = &ctx->client->dev;
|
||||
int ret;
|
||||
|
||||
DRM_DEV_DEBUG_DRIVER(dev, "attach dsi\n");
|
||||
|
||||
ret = devm_mipi_dsi_attach(dev, ctx->dsi);
|
||||
if (ret) {
|
||||
DRM_DEV_ERROR(dev, "fail to attach dsi to host.\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ctx->dsi = dsi;
|
||||
|
||||
DRM_DEV_DEBUG_DRIVER(dev, "attach dsi succeeded.\n");
|
||||
|
||||
return 0;
|
||||
@ -2560,6 +2574,40 @@ static void anx7625_runtime_disable(void *data)
|
||||
pm_runtime_disable(data);
|
||||
}
|
||||
|
||||
static int anx7625_link_bridge(struct drm_dp_aux *aux)
|
||||
{
|
||||
struct anx7625_data *platform = container_of(aux, struct anx7625_data, aux);
|
||||
struct device *dev = aux->dev;
|
||||
int ret;
|
||||
|
||||
ret = anx7625_parse_dt_panel(dev, &platform->pdata);
|
||||
if (ret) {
|
||||
DRM_DEV_ERROR(dev, "fail to parse DT for panel : %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
platform->bridge.funcs = &anx7625_bridge_funcs;
|
||||
platform->bridge.of_node = dev->of_node;
|
||||
if (!anx7625_of_panel_on_aux_bus(dev))
|
||||
platform->bridge.ops |= DRM_BRIDGE_OP_EDID;
|
||||
if (!platform->pdata.panel_bridge)
|
||||
platform->bridge.ops |= DRM_BRIDGE_OP_HPD |
|
||||
DRM_BRIDGE_OP_DETECT;
|
||||
platform->bridge.type = platform->pdata.panel_bridge ?
|
||||
DRM_MODE_CONNECTOR_eDP :
|
||||
DRM_MODE_CONNECTOR_DisplayPort;
|
||||
|
||||
drm_bridge_add(&platform->bridge);
|
||||
|
||||
if (!platform->pdata.is_dpi) {
|
||||
ret = anx7625_attach_dsi(platform);
|
||||
if (ret)
|
||||
drm_bridge_remove(&platform->bridge);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int anx7625_i2c_probe(struct i2c_client *client)
|
||||
{
|
||||
struct anx7625_data *platform;
|
||||
@ -2634,6 +2682,24 @@ static int anx7625_i2c_probe(struct i2c_client *client)
|
||||
platform->aux.wait_hpd_asserted = anx7625_wait_hpd_asserted;
|
||||
drm_dp_aux_init(&platform->aux);
|
||||
|
||||
ret = anx7625_parse_dt(dev, pdata);
|
||||
if (ret) {
|
||||
if (ret != -EPROBE_DEFER)
|
||||
DRM_DEV_ERROR(dev, "fail to parse DT : %d\n", ret);
|
||||
goto free_wq;
|
||||
}
|
||||
|
||||
if (!platform->pdata.is_dpi) {
|
||||
ret = anx7625_setup_dsi_device(platform);
|
||||
if (ret < 0)
|
||||
goto free_wq;
|
||||
}
|
||||
|
||||
/*
|
||||
* Registering the i2c devices will retrigger deferred probe, so it
|
||||
* needs to be done after calls that might return EPROBE_DEFER,
|
||||
* otherwise we can get an infinite loop.
|
||||
*/
|
||||
if (anx7625_register_i2c_dummy_clients(platform, client) != 0) {
|
||||
ret = -ENOMEM;
|
||||
DRM_DEV_ERROR(dev, "fail to reserve I2C bus.\n");
|
||||
@ -2648,13 +2714,21 @@ static int anx7625_i2c_probe(struct i2c_client *client)
|
||||
if (ret)
|
||||
goto free_wq;
|
||||
|
||||
devm_of_dp_aux_populate_ep_devices(&platform->aux);
|
||||
|
||||
ret = anx7625_parse_dt(dev, pdata);
|
||||
/*
|
||||
* Populating the aux bus will retrigger deferred probe, so it needs to
|
||||
* be done after calls that might return EPROBE_DEFER, otherwise we can
|
||||
* get an infinite loop.
|
||||
*/
|
||||
ret = devm_of_dp_aux_populate_bus(&platform->aux, anx7625_link_bridge);
|
||||
if (ret) {
|
||||
if (ret != -EPROBE_DEFER)
|
||||
DRM_DEV_ERROR(dev, "fail to parse DT : %d\n", ret);
|
||||
goto free_wq;
|
||||
if (ret != -ENODEV) {
|
||||
DRM_DEV_ERROR(dev, "failed to populate aux bus : %d\n", ret);
|
||||
goto free_wq;
|
||||
}
|
||||
|
||||
ret = anx7625_link_bridge(&platform->aux);
|
||||
if (ret)
|
||||
goto free_wq;
|
||||
}
|
||||
|
||||
if (!platform->pdata.low_power_mode) {
|
||||
@ -2667,27 +2741,6 @@ static int anx7625_i2c_probe(struct i2c_client *client)
|
||||
if (platform->pdata.intp_irq)
|
||||
queue_work(platform->workqueue, &platform->work);
|
||||
|
||||
platform->bridge.funcs = &anx7625_bridge_funcs;
|
||||
platform->bridge.of_node = client->dev.of_node;
|
||||
if (!anx7625_of_panel_on_aux_bus(&client->dev))
|
||||
platform->bridge.ops |= DRM_BRIDGE_OP_EDID;
|
||||
if (!platform->pdata.panel_bridge)
|
||||
platform->bridge.ops |= DRM_BRIDGE_OP_HPD |
|
||||
DRM_BRIDGE_OP_DETECT;
|
||||
platform->bridge.type = platform->pdata.panel_bridge ?
|
||||
DRM_MODE_CONNECTOR_eDP :
|
||||
DRM_MODE_CONNECTOR_DisplayPort;
|
||||
|
||||
drm_bridge_add(&platform->bridge);
|
||||
|
||||
if (!platform->pdata.is_dpi) {
|
||||
ret = anx7625_attach_dsi(platform);
|
||||
if (ret) {
|
||||
DRM_DEV_ERROR(dev, "Fail to attach to dsi : %d\n", ret);
|
||||
goto unregister_bridge;
|
||||
}
|
||||
}
|
||||
|
||||
if (platform->pdata.audio_en)
|
||||
anx7625_register_audio(dev, platform);
|
||||
|
||||
@ -2695,12 +2748,6 @@ static int anx7625_i2c_probe(struct i2c_client *client)
|
||||
|
||||
return 0;
|
||||
|
||||
unregister_bridge:
|
||||
drm_bridge_remove(&platform->bridge);
|
||||
|
||||
if (!platform->pdata.low_power_mode)
|
||||
pm_runtime_put_sync_suspend(&client->dev);
|
||||
|
||||
free_wq:
|
||||
if (platform->workqueue)
|
||||
destroy_workqueue(platform->workqueue);
|
||||
|
@ -56,6 +56,7 @@
|
||||
#define LVDS_CTRL_VBG_ADJ_MASK GENMASK(19, 17)
|
||||
|
||||
enum fsl_ldb_devtype {
|
||||
IMX6SX_LDB,
|
||||
IMX8MP_LDB,
|
||||
IMX93_LDB,
|
||||
};
|
||||
@ -64,9 +65,14 @@ struct fsl_ldb_devdata {
|
||||
u32 ldb_ctrl;
|
||||
u32 lvds_ctrl;
|
||||
bool lvds_en_bit;
|
||||
bool single_ctrl_reg;
|
||||
};
|
||||
|
||||
static const struct fsl_ldb_devdata fsl_ldb_devdata[] = {
|
||||
[IMX6SX_LDB] = {
|
||||
.ldb_ctrl = 0x18,
|
||||
.single_ctrl_reg = true,
|
||||
},
|
||||
[IMX8MP_LDB] = {
|
||||
.ldb_ctrl = 0x5c,
|
||||
.lvds_ctrl = 0x128,
|
||||
@ -201,6 +207,9 @@ static void fsl_ldb_atomic_enable(struct drm_bridge *bridge,
|
||||
|
||||
regmap_write(fsl_ldb->regmap, fsl_ldb->devdata->ldb_ctrl, reg);
|
||||
|
||||
if (fsl_ldb->devdata->single_ctrl_reg)
|
||||
return;
|
||||
|
||||
/* Program LVDS_CTRL */
|
||||
reg = LVDS_CTRL_CC_ADJ(2) | LVDS_CTRL_PRE_EMPH_EN |
|
||||
LVDS_CTRL_PRE_EMPH_ADJ(3) | LVDS_CTRL_VBG_EN;
|
||||
@ -226,7 +235,8 @@ static void fsl_ldb_atomic_disable(struct drm_bridge *bridge,
|
||||
regmap_write(fsl_ldb->regmap, fsl_ldb->devdata->lvds_ctrl,
|
||||
LVDS_CTRL_LVDS_EN);
|
||||
else
|
||||
regmap_write(fsl_ldb->regmap, fsl_ldb->devdata->lvds_ctrl, 0);
|
||||
if (!fsl_ldb->devdata->single_ctrl_reg)
|
||||
regmap_write(fsl_ldb->regmap, fsl_ldb->devdata->lvds_ctrl, 0);
|
||||
regmap_write(fsl_ldb->regmap, fsl_ldb->devdata->ldb_ctrl, 0);
|
||||
|
||||
clk_disable_unprepare(fsl_ldb->clk);
|
||||
@ -372,6 +382,8 @@ static void fsl_ldb_remove(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
static const struct of_device_id fsl_ldb_match[] = {
|
||||
{ .compatible = "fsl,imx6sx-ldb",
|
||||
.data = &fsl_ldb_devdata[IMX6SX_LDB], },
|
||||
{ .compatible = "fsl,imx8mp-ldb",
|
||||
.data = &fsl_ldb_devdata[IMX8MP_LDB], },
|
||||
{ .compatible = "fsl,imx93-ldb",
|
||||
|
@ -3207,7 +3207,7 @@ static ssize_t receive_timing_debugfs_show(struct file *file, char __user *buf,
|
||||
size_t len, loff_t *ppos)
|
||||
{
|
||||
struct it6505 *it6505 = file->private_data;
|
||||
struct drm_display_mode *vid = &it6505->video_info;
|
||||
struct drm_display_mode *vid;
|
||||
u8 read_buf[READ_BUFFER_SIZE];
|
||||
u8 *str = read_buf, *end = read_buf + READ_BUFFER_SIZE;
|
||||
ssize_t ret, count;
|
||||
@ -3216,6 +3216,7 @@ static ssize_t receive_timing_debugfs_show(struct file *file, char __user *buf,
|
||||
return -ENODEV;
|
||||
|
||||
it6505_calc_video_info(it6505);
|
||||
vid = &it6505->video_info;
|
||||
str += scnprintf(str, end - str, "---video timing---\n");
|
||||
str += scnprintf(str, end - str, "PCLK:%d.%03dMHz\n",
|
||||
vid->clock / 1000, vid->clock % 1000);
|
||||
|
@ -709,7 +709,9 @@ static int lt9211_host_attach(struct lt9211 *ctx)
|
||||
dsi->lanes = dsi_lanes;
|
||||
dsi->format = MIPI_DSI_FMT_RGB888;
|
||||
dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
|
||||
MIPI_DSI_MODE_VIDEO_HSE;
|
||||
MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO_NO_HSA |
|
||||
MIPI_DSI_MODE_VIDEO_NO_HFP | MIPI_DSI_MODE_VIDEO_NO_HBP |
|
||||
MIPI_DSI_MODE_NO_EOT_PACKET;
|
||||
|
||||
ret = devm_mipi_dsi_attach(dev, dsi);
|
||||
if (ret < 0) {
|
||||
|
@ -774,7 +774,9 @@ static struct mipi_dsi_device *lt9611_attach_dsi(struct lt9611 *lt9611,
|
||||
dsi->lanes = 4;
|
||||
dsi->format = MIPI_DSI_FMT_RGB888;
|
||||
dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
|
||||
MIPI_DSI_MODE_VIDEO_HSE;
|
||||
MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO_NO_HSA |
|
||||
MIPI_DSI_MODE_VIDEO_NO_HFP | MIPI_DSI_MODE_VIDEO_NO_HBP |
|
||||
MIPI_DSI_MODE_NO_EOT_PACKET;
|
||||
|
||||
ret = devm_mipi_dsi_attach(dev, dsi);
|
||||
if (ret < 0) {
|
||||
|
@ -183,6 +183,8 @@
|
||||
#define DSIM_AFC_CTL(x) (((x) & 0x7) << 5)
|
||||
|
||||
/* DSIM_PLLCTRL */
|
||||
#define DSIM_PLL_DPDNSWAP_CLK (1 << 25)
|
||||
#define DSIM_PLL_DPDNSWAP_DAT (1 << 24)
|
||||
#define DSIM_FREQ_BAND(x) ((x) << 24)
|
||||
#define DSIM_PLL_EN BIT(23)
|
||||
#define DSIM_PLL_P(x, offset) ((x) << (offset))
|
||||
@ -622,6 +624,11 @@ static unsigned long samsung_dsim_set_pll(struct samsung_dsim *dsi,
|
||||
reg |= DSIM_FREQ_BAND(band);
|
||||
}
|
||||
|
||||
if (dsi->swap_dn_dp_clk)
|
||||
reg |= DSIM_PLL_DPDNSWAP_CLK;
|
||||
if (dsi->swap_dn_dp_data)
|
||||
reg |= DSIM_PLL_DPDNSWAP_DAT;
|
||||
|
||||
samsung_dsim_write(dsi, DSIM_PLLCTRL_REG, reg);
|
||||
|
||||
timeout = 1000;
|
||||
@ -1696,7 +1703,9 @@ static int samsung_dsim_parse_dt(struct samsung_dsim *dsi)
|
||||
{
|
||||
struct device *dev = dsi->dev;
|
||||
struct device_node *node = dev->of_node;
|
||||
int ret;
|
||||
u32 lane_polarities[5] = { 0 };
|
||||
struct device_node *endpoint;
|
||||
int i, nr_lanes, ret;
|
||||
|
||||
ret = samsung_dsim_of_read_u32(node, "samsung,pll-clock-frequency",
|
||||
&dsi->pll_clk_rate);
|
||||
@ -1713,6 +1722,22 @@ static int samsung_dsim_parse_dt(struct samsung_dsim *dsi)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
endpoint = of_graph_get_endpoint_by_regs(node, 1, -1);
|
||||
nr_lanes = of_property_count_u32_elems(endpoint, "data-lanes");
|
||||
if (nr_lanes > 0 && nr_lanes <= 4) {
|
||||
/* Polarity 0 is clock lane, 1..4 are data lanes. */
|
||||
of_property_read_u32_array(endpoint, "lane-polarities",
|
||||
lane_polarities, nr_lanes + 1);
|
||||
for (i = 1; i <= nr_lanes; i++) {
|
||||
if (lane_polarities[1] != lane_polarities[i])
|
||||
DRM_DEV_ERROR(dsi->dev, "Data lanes polarities do not match");
|
||||
}
|
||||
if (lane_polarities[0])
|
||||
dsi->swap_dn_dp_clk = true;
|
||||
if (lane_polarities[1])
|
||||
dsi->swap_dn_dp_data = true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1954,7 +1979,6 @@ static struct platform_driver samsung_dsim_driver = {
|
||||
.remove = samsung_dsim_remove,
|
||||
.driver = {
|
||||
.name = "samsung-dsim",
|
||||
.owner = THIS_MODULE,
|
||||
.pm = &samsung_dsim_pm_ops,
|
||||
.of_match_table = samsung_dsim_of_match,
|
||||
},
|
||||
|
@ -533,7 +533,7 @@ static struct i2c_adapter *dw_hdmi_i2c_adapter(struct dw_hdmi *hdmi)
|
||||
adap->owner = THIS_MODULE;
|
||||
adap->dev.parent = hdmi->dev;
|
||||
adap->algo = &dw_hdmi_algorithm;
|
||||
strlcpy(adap->name, "DesignWare HDMI", sizeof(adap->name));
|
||||
strscpy(adap->name, "DesignWare HDMI", sizeof(adap->name));
|
||||
i2c_set_adapdata(adap, hdmi);
|
||||
|
||||
ret = i2c_add_adapter(adap);
|
||||
|
@ -1890,7 +1890,7 @@ static int tc_mipi_dsi_host_attach(struct tc_data *tc)
|
||||
if (dsi_lanes < 0)
|
||||
return dsi_lanes;
|
||||
|
||||
dsi = mipi_dsi_device_register_full(host, &info);
|
||||
dsi = devm_mipi_dsi_device_register_full(dev, host, &info);
|
||||
if (IS_ERR(dsi))
|
||||
return dev_err_probe(dev, PTR_ERR(dsi),
|
||||
"failed to create dsi device\n");
|
||||
@ -1901,7 +1901,7 @@ static int tc_mipi_dsi_host_attach(struct tc_data *tc)
|
||||
dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
|
||||
MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS;
|
||||
|
||||
ret = mipi_dsi_attach(dsi);
|
||||
ret = devm_mipi_dsi_attach(dev, dsi);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed to attach dsi to host: %d\n", ret);
|
||||
return ret;
|
||||
|
@ -9,6 +9,8 @@
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/media-bus-format.h>
|
||||
#include <linux/minmax.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
@ -146,6 +148,7 @@ struct tc358768_priv {
|
||||
|
||||
u32 pd_lines; /* number of Parallel Port Input Data Lines */
|
||||
u32 dsi_lanes; /* number of DSI Lanes */
|
||||
u32 dsi_bpp; /* number of Bits Per Pixel over DSI */
|
||||
|
||||
/* Parameters for PLL programming */
|
||||
u32 fbd; /* PLL feedback divider */
|
||||
@ -284,12 +287,12 @@ static void tc358768_hw_disable(struct tc358768_priv *priv)
|
||||
|
||||
static u32 tc358768_pll_to_pclk(struct tc358768_priv *priv, u32 pll_clk)
|
||||
{
|
||||
return (u32)div_u64((u64)pll_clk * priv->dsi_lanes, priv->pd_lines);
|
||||
return (u32)div_u64((u64)pll_clk * priv->dsi_lanes, priv->dsi_bpp);
|
||||
}
|
||||
|
||||
static u32 tc358768_pclk_to_pll(struct tc358768_priv *priv, u32 pclk)
|
||||
{
|
||||
return (u32)div_u64((u64)pclk * priv->pd_lines, priv->dsi_lanes);
|
||||
return (u32)div_u64((u64)pclk * priv->dsi_bpp, priv->dsi_lanes);
|
||||
}
|
||||
|
||||
static int tc358768_calc_pll(struct tc358768_priv *priv,
|
||||
@ -334,13 +337,17 @@ static int tc358768_calc_pll(struct tc358768_priv *priv,
|
||||
u32 fbd;
|
||||
|
||||
for (fbd = 0; fbd < 512; ++fbd) {
|
||||
u32 pll, diff;
|
||||
u32 pll, diff, pll_in;
|
||||
|
||||
pll = (u32)div_u64((u64)refclk * (fbd + 1), divisor);
|
||||
|
||||
if (pll >= max_pll || pll < min_pll)
|
||||
continue;
|
||||
|
||||
pll_in = (u32)div_u64((u64)refclk, prd + 1);
|
||||
if (pll_in < 4000000)
|
||||
continue;
|
||||
|
||||
diff = max(pll, target_pll) - min(pll, target_pll);
|
||||
|
||||
if (diff < best_diff) {
|
||||
@ -422,6 +429,7 @@ static int tc358768_dsi_host_attach(struct mipi_dsi_host *host,
|
||||
priv->output.panel = panel;
|
||||
|
||||
priv->dsi_lanes = dev->lanes;
|
||||
priv->dsi_bpp = mipi_dsi_pixel_format_to_bpp(dev->format);
|
||||
|
||||
/* get input ep (port0/endpoint0) */
|
||||
ret = -EINVAL;
|
||||
@ -433,7 +441,7 @@ static int tc358768_dsi_host_attach(struct mipi_dsi_host *host,
|
||||
}
|
||||
|
||||
if (ret)
|
||||
priv->pd_lines = mipi_dsi_pixel_format_to_bpp(dev->format);
|
||||
priv->pd_lines = priv->dsi_bpp;
|
||||
|
||||
drm_bridge_add(&priv->bridge);
|
||||
|
||||
@ -632,8 +640,9 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)
|
||||
struct mipi_dsi_device *dsi_dev = priv->output.dev;
|
||||
unsigned long mode_flags = dsi_dev->mode_flags;
|
||||
u32 val, val2, lptxcnt, hact, data_type;
|
||||
s32 raw_val;
|
||||
const struct drm_display_mode *mode;
|
||||
u32 dsibclk_nsk, dsiclk_nsk, ui_nsk, phy_delay_nsk;
|
||||
u32 dsibclk_nsk, dsiclk_nsk, ui_nsk;
|
||||
u32 dsiclk, dsibclk, video_start;
|
||||
const u32 internal_delay = 40;
|
||||
int ret, i;
|
||||
@ -717,11 +726,9 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)
|
||||
dsibclk);
|
||||
dsiclk_nsk = (u32)div_u64((u64)1000000000 * TC358768_PRECISION, dsiclk);
|
||||
ui_nsk = dsiclk_nsk / 2;
|
||||
phy_delay_nsk = dsibclk_nsk + 2 * dsiclk_nsk;
|
||||
dev_dbg(priv->dev, "dsiclk_nsk: %u\n", dsiclk_nsk);
|
||||
dev_dbg(priv->dev, "ui_nsk: %u\n", ui_nsk);
|
||||
dev_dbg(priv->dev, "dsibclk_nsk: %u\n", dsibclk_nsk);
|
||||
dev_dbg(priv->dev, "phy_delay_nsk: %u\n", phy_delay_nsk);
|
||||
|
||||
/* LP11 > 100us for D-PHY Rx Init */
|
||||
val = tc358768_ns_to_cnt(100 * 1000, dsibclk_nsk) - 1;
|
||||
@ -736,25 +743,26 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)
|
||||
|
||||
/* 38ns < TCLK_PREPARE < 95ns */
|
||||
val = tc358768_ns_to_cnt(65, dsibclk_nsk) - 1;
|
||||
/* TCLK_PREPARE > 300ns */
|
||||
val2 = tc358768_ns_to_cnt(300 + tc358768_to_ns(3 * ui_nsk),
|
||||
dsibclk_nsk);
|
||||
val |= (val2 - tc358768_to_ns(phy_delay_nsk - dsibclk_nsk)) << 8;
|
||||
/* TCLK_PREPARE + TCLK_ZERO > 300ns */
|
||||
val2 = tc358768_ns_to_cnt(300 - tc358768_to_ns(2 * ui_nsk),
|
||||
dsibclk_nsk) - 2;
|
||||
val |= val2 << 8;
|
||||
dev_dbg(priv->dev, "TCLK_HEADERCNT: 0x%x\n", val);
|
||||
tc358768_write(priv, TC358768_TCLK_HEADERCNT, val);
|
||||
|
||||
/* TCLK_TRAIL > 60ns + 3*UI */
|
||||
val = 60 + tc358768_to_ns(3 * ui_nsk);
|
||||
val = tc358768_ns_to_cnt(val, dsibclk_nsk) - 5;
|
||||
/* TCLK_TRAIL > 60ns AND TEOT <= 105 ns + 12*UI */
|
||||
raw_val = tc358768_ns_to_cnt(60 + tc358768_to_ns(2 * ui_nsk), dsibclk_nsk) - 5;
|
||||
val = clamp(raw_val, 0, 127);
|
||||
dev_dbg(priv->dev, "TCLK_TRAILCNT: 0x%x\n", val);
|
||||
tc358768_write(priv, TC358768_TCLK_TRAILCNT, val);
|
||||
|
||||
/* 40ns + 4*UI < THS_PREPARE < 85ns + 6*UI */
|
||||
val = 50 + tc358768_to_ns(4 * ui_nsk);
|
||||
val = tc358768_ns_to_cnt(val, dsibclk_nsk) - 1;
|
||||
/* THS_ZERO > 145ns + 10*UI */
|
||||
val2 = tc358768_ns_to_cnt(145 - tc358768_to_ns(ui_nsk), dsibclk_nsk);
|
||||
val |= (val2 - tc358768_to_ns(phy_delay_nsk)) << 8;
|
||||
/* THS_PREPARE + THS_ZERO > 145ns + 10*UI */
|
||||
raw_val = tc358768_ns_to_cnt(145 - tc358768_to_ns(3 * ui_nsk), dsibclk_nsk) - 10;
|
||||
val2 = clamp(raw_val, 0, 127);
|
||||
val |= val2 << 8;
|
||||
dev_dbg(priv->dev, "THS_HEADERCNT: 0x%x\n", val);
|
||||
tc358768_write(priv, TC358768_THS_HEADERCNT, val);
|
||||
|
||||
@ -770,9 +778,10 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)
|
||||
dev_dbg(priv->dev, "TCLK_POSTCNT: 0x%x\n", val);
|
||||
tc358768_write(priv, TC358768_TCLK_POSTCNT, val);
|
||||
|
||||
/* 60ns + 4*UI < THS_PREPARE < 105ns + 12*UI */
|
||||
val = tc358768_ns_to_cnt(60 + tc358768_to_ns(15 * ui_nsk),
|
||||
dsibclk_nsk) - 5;
|
||||
/* max(60ns + 4*UI, 8*UI) < THS_TRAILCNT < 105ns + 12*UI */
|
||||
raw_val = tc358768_ns_to_cnt(60 + tc358768_to_ns(18 * ui_nsk),
|
||||
dsibclk_nsk) - 4;
|
||||
val = clamp(raw_val, 0, 15);
|
||||
dev_dbg(priv->dev, "THS_TRAILCNT: 0x%x\n", val);
|
||||
tc358768_write(priv, TC358768_THS_TRAILCNT, val);
|
||||
|
||||
@ -786,7 +795,7 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)
|
||||
|
||||
/* TXTAGOCNT[26:16] RXTASURECNT[10:0] */
|
||||
val = tc358768_to_ns((lptxcnt + 1) * dsibclk_nsk * 4);
|
||||
val = tc358768_ns_to_cnt(val, dsibclk_nsk) - 1;
|
||||
val = tc358768_ns_to_cnt(val, dsibclk_nsk) / 4 - 1;
|
||||
val2 = tc358768_ns_to_cnt(tc358768_to_ns((lptxcnt + 1) * dsibclk_nsk),
|
||||
dsibclk_nsk) - 2;
|
||||
val = val << 16 | val2;
|
||||
@ -866,8 +875,7 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)
|
||||
val = TC358768_DSI_CONFW_MODE_SET | TC358768_DSI_CONFW_ADDR_DSI_CONTROL;
|
||||
val |= (dsi_dev->lanes - 1) << 1;
|
||||
|
||||
if (!(dsi_dev->mode_flags & MIPI_DSI_MODE_LPM))
|
||||
val |= TC358768_DSI_CONTROL_TXMD;
|
||||
val |= TC358768_DSI_CONTROL_TXMD;
|
||||
|
||||
if (!(mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS))
|
||||
val |= TC358768_DSI_CONTROL_HSCKMD;
|
||||
@ -913,6 +921,44 @@ static void tc358768_bridge_enable(struct drm_bridge *bridge)
|
||||
}
|
||||
}
|
||||
|
||||
#define MAX_INPUT_SEL_FORMATS 1
|
||||
|
||||
static u32 *
|
||||
tc358768_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
|
||||
struct drm_bridge_state *bridge_state,
|
||||
struct drm_crtc_state *crtc_state,
|
||||
struct drm_connector_state *conn_state,
|
||||
u32 output_fmt,
|
||||
unsigned int *num_input_fmts)
|
||||
{
|
||||
struct tc358768_priv *priv = bridge_to_tc358768(bridge);
|
||||
u32 *input_fmts;
|
||||
|
||||
*num_input_fmts = 0;
|
||||
|
||||
input_fmts = kcalloc(MAX_INPUT_SEL_FORMATS, sizeof(*input_fmts),
|
||||
GFP_KERNEL);
|
||||
if (!input_fmts)
|
||||
return NULL;
|
||||
|
||||
switch (priv->pd_lines) {
|
||||
case 16:
|
||||
input_fmts[0] = MEDIA_BUS_FMT_RGB565_1X16;
|
||||
break;
|
||||
case 18:
|
||||
input_fmts[0] = MEDIA_BUS_FMT_RGB666_1X18;
|
||||
break;
|
||||
default:
|
||||
case 24:
|
||||
input_fmts[0] = MEDIA_BUS_FMT_RGB888_1X24;
|
||||
break;
|
||||
}
|
||||
|
||||
*num_input_fmts = MAX_INPUT_SEL_FORMATS;
|
||||
|
||||
return input_fmts;
|
||||
}
|
||||
|
||||
static const struct drm_bridge_funcs tc358768_bridge_funcs = {
|
||||
.attach = tc358768_bridge_attach,
|
||||
.mode_valid = tc358768_bridge_mode_valid,
|
||||
@ -920,6 +966,11 @@ static const struct drm_bridge_funcs tc358768_bridge_funcs = {
|
||||
.enable = tc358768_bridge_enable,
|
||||
.disable = tc358768_bridge_disable,
|
||||
.post_disable = tc358768_bridge_post_disable,
|
||||
|
||||
.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
|
||||
.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
|
||||
.atomic_reset = drm_atomic_helper_bridge_reset,
|
||||
.atomic_get_input_bus_fmts = tc358768_atomic_get_input_bus_fmts,
|
||||
};
|
||||
|
||||
static const struct drm_bridge_timings default_tc358768_timings = {
|
||||
|
@ -478,6 +478,7 @@ static void sn65dsi83_atomic_enable(struct drm_bridge *bridge,
|
||||
dev_err(ctx->dev, "failed to lock PLL, ret=%i\n", ret);
|
||||
/* On failure, disable PLL again and exit. */
|
||||
regmap_write(ctx->regmap, REG_RC_PLL_EN, 0x00);
|
||||
regulator_disable(ctx->vcc);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -618,6 +618,24 @@ exit:
|
||||
return len;
|
||||
}
|
||||
|
||||
static int ti_sn_aux_wait_hpd_asserted(struct drm_dp_aux *aux, unsigned long wait_us)
|
||||
{
|
||||
/*
|
||||
* The HPD in this chip is a bit useless (See comment in
|
||||
* ti_sn65dsi86_enable_comms) so if our driver is expected to wait
|
||||
* for HPD, we just assume it's asserted after the wait_us delay.
|
||||
*
|
||||
* In case we are asked to wait forever (wait_us=0) take conservative
|
||||
* 500ms delay.
|
||||
*/
|
||||
if (wait_us == 0)
|
||||
wait_us = 500000;
|
||||
|
||||
usleep_range(wait_us, wait_us + 1000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ti_sn_aux_probe(struct auxiliary_device *adev,
|
||||
const struct auxiliary_device_id *id)
|
||||
{
|
||||
@ -627,6 +645,7 @@ static int ti_sn_aux_probe(struct auxiliary_device *adev,
|
||||
pdata->aux.name = "ti-sn65dsi86-aux";
|
||||
pdata->aux.dev = &adev->dev;
|
||||
pdata->aux.transfer = ti_sn_aux_transfer;
|
||||
pdata->aux.wait_hpd_asserted = ti_sn_aux_wait_hpd_asserted;
|
||||
drm_dp_aux_init(&pdata->aux);
|
||||
|
||||
ret = devm_of_dp_aux_populate_ep_devices(&pdata->aux);
|
||||
|
@ -32,17 +32,13 @@
|
||||
*
|
||||
* static int remove_conflicting_framebuffers(struct pci_dev *pdev)
|
||||
* {
|
||||
* bool primary = false;
|
||||
* resource_size_t base, size;
|
||||
* int ret;
|
||||
*
|
||||
* base = pci_resource_start(pdev, 0);
|
||||
* size = pci_resource_len(pdev, 0);
|
||||
* #ifdef CONFIG_X86
|
||||
* primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
|
||||
* #endif
|
||||
*
|
||||
* return drm_aperture_remove_conflicting_framebuffers(base, size, primary,
|
||||
* return drm_aperture_remove_conflicting_framebuffers(base, size,
|
||||
* &example_driver);
|
||||
* }
|
||||
*
|
||||
@ -161,7 +157,6 @@ EXPORT_SYMBOL(devm_aperture_acquire_from_firmware);
|
||||
* drm_aperture_remove_conflicting_framebuffers - remove existing framebuffers in the given range
|
||||
* @base: the aperture's base address in physical memory
|
||||
* @size: aperture size in bytes
|
||||
* @primary: also kick vga16fb if present
|
||||
* @req_driver: requesting DRM driver
|
||||
*
|
||||
* This function removes graphics device drivers which use the memory range described by
|
||||
@ -171,9 +166,9 @@ EXPORT_SYMBOL(devm_aperture_acquire_from_firmware);
|
||||
* 0 on success, or a negative errno code otherwise
|
||||
*/
|
||||
int drm_aperture_remove_conflicting_framebuffers(resource_size_t base, resource_size_t size,
|
||||
bool primary, const struct drm_driver *req_driver)
|
||||
const struct drm_driver *req_driver)
|
||||
{
|
||||
return aperture_remove_conflicting_devices(base, size, primary, req_driver->name);
|
||||
return aperture_remove_conflicting_devices(base, size, req_driver->name);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_aperture_remove_conflicting_framebuffers);
|
||||
|
||||
|
@ -1209,7 +1209,16 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state)
|
||||
continue;
|
||||
|
||||
ret = drm_crtc_vblank_get(crtc);
|
||||
WARN_ONCE(ret != -EINVAL, "driver forgot to call drm_crtc_vblank_off()\n");
|
||||
/*
|
||||
* Self-refresh is not a true "disable"; ensure vblank remains
|
||||
* enabled.
|
||||
*/
|
||||
if (new_crtc_state->self_refresh_active)
|
||||
WARN_ONCE(ret != 0,
|
||||
"driver disabled vblank in self-refresh\n");
|
||||
else
|
||||
WARN_ONCE(ret != -EINVAL,
|
||||
"driver forgot to call drm_crtc_vblank_off()\n");
|
||||
if (ret == 0)
|
||||
drm_crtc_vblank_put(crtc);
|
||||
}
|
||||
@ -3145,7 +3154,7 @@ fail:
|
||||
EXPORT_SYMBOL(drm_atomic_helper_update_plane);
|
||||
|
||||
/**
|
||||
* drm_atomic_helper_disable_plane - Helper for primary plane disable using * atomic
|
||||
* drm_atomic_helper_disable_plane - Helper for primary plane disable using atomic
|
||||
* @plane: plane to disable
|
||||
* @ctx: lock acquire context
|
||||
*
|
||||
|
@ -969,7 +969,9 @@ EXPORT_SYMBOL(drm_dev_register);
|
||||
*
|
||||
* Unregister the DRM device from the system. This does the reverse of
|
||||
* drm_dev_register() but does not deallocate the device. The caller must call
|
||||
* drm_dev_put() to drop their final reference.
|
||||
* drm_dev_put() to drop their final reference, unless it is managed with devres
|
||||
* (as devices allocated with devm_drm_dev_alloc() are), in which case there is
|
||||
* already an unwind action registered.
|
||||
*
|
||||
* A special form of unregistering for hotpluggable devices is drm_dev_unplug(),
|
||||
* which can be called while there are still open users of @dev.
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user