We need commit f8f6ae5d077a ("mm: always have io_remap_pfn_range() set pgprot_decrypted()") to be able to merge Jason's cleanup patch.
Unified · Split
| @@ -1,29 +1,29 @@ | ||
| 1 | −What: sys/devices/pciXXXX:XX/0000:XX:XX.X/dma/dma<n>chan<n>/quickdata/cap | |
| 1 | +What: /sys/devices/pciXXXX:XX/0000:XX:XX.X/dma/dma<n>chan<n>/quickdata/cap | |
| 2 | 2 | Date: December 3, 2009 |
| 3 | 3 | KernelVersion: 2.6.32 |
| 4 | 4 | Contact: dmaengine@vger.kernel.org |
| 5 | 5 | Description: Capabilities the DMA supports.Currently there are DMA_PQ, DMA_PQ_VAL, |
| 6 | 6 | DMA_XOR,DMA_XOR_VAL,DMA_INTERRUPT. |
| 7 | 7 | |
| 8 | −What: sys/devices/pciXXXX:XX/0000:XX:XX.X/dma/dma<n>chan<n>/quickdata/ring_active | |
| 8 | +What: /sys/devices/pciXXXX:XX/0000:XX:XX.X/dma/dma<n>chan<n>/quickdata/ring_active | |
| 9 | 9 | Date: December 3, 2009 |
| 10 | 10 | KernelVersion: 2.6.32 |
| 11 | 11 | Contact: dmaengine@vger.kernel.org |
| 12 | 12 | Description: The number of descriptors active in the ring. |
| 13 | 13 | |
| 14 | −What: sys/devices/pciXXXX:XX/0000:XX:XX.X/dma/dma<n>chan<n>/quickdata/ring_size | |
| 14 | +What: /sys/devices/pciXXXX:XX/0000:XX:XX.X/dma/dma<n>chan<n>/quickdata/ring_size | |
| 15 | 15 | Date: December 3, 2009 |
| 16 | 16 | KernelVersion: 2.6.32 |
| 17 | 17 | Contact: dmaengine@vger.kernel.org |
| 18 | 18 | Description: Descriptor ring size, total number of descriptors available. |
| 19 | 19 | |
| 20 | −What: sys/devices/pciXXXX:XX/0000:XX:XX.X/dma/dma<n>chan<n>/quickdata/version | |
| 20 | +What: /sys/devices/pciXXXX:XX/0000:XX:XX.X/dma/dma<n>chan<n>/quickdata/version | |
| 21 | 21 | Date: December 3, 2009 |
| 22 | 22 | KernelVersion: 2.6.32 |
| 23 | 23 | Contact: dmaengine@vger.kernel.org |
| 24 | 24 | Description: Version of ioatdma device. |
| 25 | 25 | |
| 26 | −What: sys/devices/pciXXXX:XX/0000:XX:XX.X/dma/dma<n>chan<n>/quickdata/intr_coalesce | |
| 26 | +What: /sys/devices/pciXXXX:XX/0000:XX:XX.X/dma/dma<n>chan<n>/quickdata/intr_coalesce | |
| 27 | 27 | Date: August 8, 2017 |
| 28 | 28 | KernelVersion: 4.14 |
| 29 | 29 | Contact: dmaengine@vger.kernel.org |
| @@ -152,7 +152,7 @@ Description: · 151 unmodified lines | ||
| 152 | 152 | When an interface is under test, it cannot be expected |
| 153 | 153 | to pass packets as normal. |
| 154 | 154 | |
| 155 | −What: /sys/clas/net/<iface>/duplex | |
| 155 | +What: /sys/class/net/<iface>/duplex | |
| 156 | 156 | Date: October 2009 |
| 157 | 157 | KernelVersion: 2.6.33 |
| 158 | 158 | Contact: netdev@vger.kernel.org |
| @@ -26,6 +26,10 @@ BUILDDIR = $(obj)/output · 25 unmodified lines | ||
| 26 | 26 | PDFLATEX = xelatex |
| 27 | 27 | LATEXOPTS = -interaction=batchmode |
| 28 | 28 | |
| 29 | +ifeq ($(KBUILD_VERBOSE),0) | |
| 30 | +SPHINXOPTS += "-q" | |
| 31 | +endif | |
| 32 | + | |
| 29 | 33 | # User-friendly check for sphinx-build |
| 30 | 34 | HAVE_SPHINX := $(shell if which $(SPHINXBUILD) >/dev/null 2>&1; then echo 1; else echo 0; fi) |
| 31 | 35 | |
| @@ -107,7 +107,7 @@ for a UID/GID will prevent that UID/GID from obtaining auxiliary setid · 106 unmodified lines | ||
| 107 | 107 | privileges, such as allowing a user to set up user namespace UID/GID mappings. |
| 108 | 108 | |
| 109 | 109 | Note on GID policies and setgroups() |
| 110 | −================== | |
| 110 | +==================================== | |
| 111 | 111 | In v5.9 we are adding support for limiting CAP_SETGID privileges as was done |
| 112 | 112 | previously for CAP_SETUID. However, for compatibility with common sandboxing |
| 113 | 113 | related code conventions in userspace, we currently allow arbitrary |
| @@ -478,7 +478,7 @@ order to ask the hardware to enter that state. Also, for each · 477 unmodified lines | ||
| 478 | 478 | statistics of the given idle state. That information is exposed by the kernel |
| 479 | 479 | via ``sysfs``. |
| 480 | 480 | |
| 481 | −For each CPU in the system, there is a :file:`/sys/devices/system/cpu<N>/cpuidle/` | |
| 481 | +For each CPU in the system, there is a :file:`/sys/devices/system/cpu/cpu<N>/cpuidle/` | |
| 482 | 482 | directory in ``sysfs``, where the number ``<N>`` is assigned to the given |
| 483 | 483 | CPU at the initialization time. That directory contains a set of subdirectories |
| 484 | 484 | called :file:`state0`, :file:`state1` and so on, up to the number of idle state |
| @@ -494,7 +494,7 @@ object corresponding to it, as follows: · 9 unmodified lines | ||
| 494 | 494 | residency. |
| 495 | 495 | |
| 496 | 496 | ``below`` |
| 497 | − Total number of times this idle state had been asked for, but cerainly | |
| 497 | + Total number of times this idle state had been asked for, but certainly | |
| 498 | 498 | a deeper idle state would have been a better match for the observed idle |
| 499 | 499 | duration. |
| 500 | 500 | |
| @@ -300,6 +300,7 @@ Note: · 299 unmodified lines | ||
| 300 | 300 | 0: 0 1 2 3 4 5 6 7 |
| 301 | 301 | RSS hash key: |
| 302 | 302 | 84:50:f4:00:a8:15:d1:a7:e9:7f:1d:60:35:c7:47:25:42:97:74:ca:56:bb:b6:a1:d8:43:e3:c9:0c:fd:17:55:c2:3a:4d:69:ed:f1:42:89 |
| 303 | + | |
| 303 | 304 | netdev_tstamp_prequeue |
| 304 | 305 | ---------------------- |
| 305 | 306 | |
| @@ -148,3 +148,13 @@ SunXi family · 147 unmodified lines | ||
| 148 | 148 | * User Manual |
| 149 | 149 | |
| 150 | 150 | http://dl.linux-sunxi.org/A64/Allwinner%20A64%20User%20Manual%20v1.0.pdf |
| 151 | + | |
| 152 | + - Allwinner H6 | |
| 153 | + | |
| 154 | + * Datasheet | |
| 155 | + | |
| 156 | + https://linux-sunxi.org/images/5/5c/Allwinner_H6_V200_Datasheet_V1.1.pdf | |
| 157 | + | |
| 158 | + * User Manual | |
| 159 | + | |
| 160 | + https://linux-sunxi.org/images/4/46/Allwinner_H6_V200_User_Manual_V1.1.pdf | |
| @@ -51,7 +51,7 @@ if major >= 3: · 50 unmodified lines | ||
| 51 | 51 | support for Sphinx v3.0 and above is brand new. Be prepared for |
| 52 | 52 | possible issues in the generated output. |
| 53 | 53 | ''') |
| 54 | − if minor > 0 or patch >= 2: | |
| 54 | + if (major > 3) or (minor > 0 or patch >= 2): | |
| 55 | 55 | # Sphinx c function parser is more pedantic with regards to type |
| 56 | 56 | # checking. Due to that, having macros at c:function cause problems. |
| 57 | 57 | # Those needed to be scaped by using c_id_attributes[] array |
| @@ -295,11 +295,13 @@ print the number of the test and the status of the test: · 294 unmodified lines | ||
| 295 | 295 | pass:: |
| 296 | 296 | |
| 297 | 297 | ok 28 - kmalloc_double_kzfree |
| 298 | + | |
| 298 | 299 | or, if kmalloc failed:: |
| 299 | 300 | |
| 300 | 301 | # kmalloc_large_oob_right: ASSERTION FAILED at lib/test_kasan.c:163 |
| 301 | 302 | Expected ptr is not null, but is |
| 302 | 303 | not ok 4 - kmalloc_large_oob_right |
| 304 | + | |
| 303 | 305 | or, if a KASAN report was expected, but not found:: |
| 304 | 306 | |
| 305 | 307 | # kmalloc_double_kzfree: EXPECTATION FAILED at lib/test_kasan.c:629 |
| @@ -197,7 +197,7 @@ Now add the following to ``drivers/misc/Kconfig``: · 196 unmodified lines | ||
| 197 | 197 | |
| 198 | 198 | config MISC_EXAMPLE_TEST |
| 199 | 199 | bool "Test for my example" |
| 200 | − depends on MISC_EXAMPLE && KUNIT | |
| 200 | + depends on MISC_EXAMPLE && KUNIT=y | |
| 201 | 201 | |
| 202 | 202 | and the following to ``drivers/misc/Makefile``: |
| 203 | 203 | |
| @@ -561,6 +561,11 @@ Once the kernel is built and installed, a simple · 560 unmodified lines | ||
| 561 | 561 | |
| 562 | 562 | ...will run the tests. |
| 563 | 563 | |
| 564 | +.. note:: | |
| 565 | + Note that you should make sure your test depends on ``KUNIT=y`` in Kconfig | |
| 566 | + if the test does not support module build. Otherwise, it will trigger | |
| 567 | + compile errors if ``CONFIG_KUNIT`` is ``m``. | |
| 568 | + | |
| 564 | 569 | Writing new tests for other architectures |
| 565 | 570 | ----------------------------------------- |
| 566 | 571 | |
| @@ -4,7 +4,7 @@ Clock control registers reside in different Hi6220 system controllers, · 3 unmodified lines | ||
| 4 | 4 | please refer the following document to know more about the binding rules |
| 5 | 5 | for these system controllers: |
| 6 | 6 | |
| 7 | −Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt | |
| 7 | +Documentation/devicetree/bindings/arm/hisilicon/hisilicon.yaml | |
| 8 | 8 | |
| 9 | 9 | Required Properties: |
| 10 | 10 | |
| @@ -32,6 +32,11 @@ description: | · 31 unmodified lines | ||
| 32 | 32 | | | vint | bit | | 0 |.....|63| vintx | |
| 33 | 33 | | +--------------+ +------------+ | |
| 34 | 34 | | | |
| 35 | + | Unmap | | |
| 36 | + | +--------------+ | | |
| 37 | + Unmapped events ---->| | umapidx |-------------------------> Globalevents | |
| 38 | + | +--------------+ | | |
| 39 | + | | | |
| 35 | 40 | +-----------------------------------------+ |
| 36 | 41 | |
| 37 | 42 | Configuration of these Intmap registers that maps global events to vint is |
| @@ -70,6 +75,11 @@ properties: · 32 unmodified lines | ||
| 70 | 75 | - description: | |
| 71 | 76 | "limit" specifies the limit for translation |
| 72 | 77 | |
| 78 | + ti,unmapped-event-sources: | |
| 79 | + $ref: /schemas/types.yaml#definitions/phandle-array | |
| 80 | + description: | |
| 81 | + Array of phandles to DMA controllers where the unmapped events originate. | |
| 82 | + | |
| 73 | 83 | required: |
| 74 | 84 | - compatible |
| 75 | 85 | - reg |
| @@ -0,0 +1,18 @@ | ||
| 1 | +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/net/can/can-controller.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: CAN Controller Generic Binding | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Marc Kleine-Budde <mkl@pengutronix.de> | |
| 11 | + | |
| 12 | +properties: | |
| 13 | + $nodename: | |
| 14 | + pattern: "^can(@.*)?$" | |
| 15 | + | |
| 16 | +additionalProperties: true | |
| 17 | + | |
| 18 | +... | |
| @@ -0,0 +1,135 @@ | ||
| 1 | +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/net/can/fsl,flexcan.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: | |
| 8 | + Flexcan CAN controller on Freescale's ARM and PowerPC system-on-a-chip (SOC). | |
| 9 | + | |
| 10 | +maintainers: | |
| 11 | + - Marc Kleine-Budde <mkl@pengutronix.de> | |
| 12 | + | |
| 13 | +allOf: | |
| 14 | + - $ref: can-controller.yaml# | |
| 15 | + | |
| 16 | +properties: | |
| 17 | + compatible: | |
| 18 | + oneOf: | |
| 19 | + - enum: | |
| 20 | + - fsl,imx8qm-flexcan | |
| 21 | + - fsl,imx8mp-flexcan | |
| 22 | + - fsl,imx6q-flexcan | |
| 23 | + - fsl,imx53-flexcan | |
| 24 | + - fsl,imx35-flexcan | |
| 25 | + - fsl,imx28-flexcan | |
| 26 | + - fsl,imx25-flexcan | |
| 27 | + - fsl,p1010-flexcan | |
| 28 | + - fsl,vf610-flexcan | |
| 29 | + - fsl,ls1021ar2-flexcan | |
| 30 | + - fsl,lx2160ar1-flexcan | |
| 31 | + - items: | |
| 32 | + - enum: | |
| 33 | + - fsl,imx7d-flexcan | |
| 34 | + - fsl,imx6ul-flexcan | |
| 35 | + - fsl,imx6sx-flexcan | |
| 36 | + - const: fsl,imx6q-flexcan | |
| 37 | + - items: | |
| 38 | + - enum: | |
| 39 | + - fsl,ls1028ar1-flexcan | |
| 40 | + - const: fsl,lx2160ar1-flexcan | |
| 41 | + | |
| 42 | + reg: | |
| 43 | + maxItems: 1 | |
| 44 | + | |
| 45 | + interrupts: | |
| 46 | + maxItems: 1 | |
| 47 | + | |
| 48 | + clocks: | |
| 49 | + maxItems: 2 | |
| 50 | + | |
| 51 | + clock-names: | |
| 52 | + items: | |
| 53 | + - const: ipg | |
| 54 | + - const: per | |
| 55 | + | |
| 56 | + clock-frequency: | |
| 57 | + description: | | |
| 58 | + The oscillator frequency driving the flexcan device, filled in by the | |
| 59 | + boot loader. This property should only be used the used operating system | |
| 60 | + doesn't support the clocks and clock-names property. | |
| 61 | + | |
| 62 | + xceiver-supply: | |
| 63 | + description: Regulator that powers the CAN transceiver. | |
| 64 | + | |
| 65 | + big-endian: | |
| 66 | + $ref: /schemas/types.yaml#/definitions/flag | |
| 67 | + description: | | |
| 68 | + This means the registers of FlexCAN controller are big endian. This is | |
| 69 | + optional property.i.e. if this property is not present in device tree | |
| 70 | + node then controller is assumed to be little endian. If this property is | |
| 71 | + present then controller is assumed to be big endian. | |
| 72 | + | |
| 73 | + fsl,stop-mode: | |
| 74 | + description: | | |
| 75 | + Register bits of stop mode control. | |
| 76 | + | |
| 77 | + The format should be as follows: | |
| 78 | + <gpr req_gpr req_bit> | |
| 79 | + gpr is the phandle to general purpose register node. | |
| 80 | + req_gpr is the gpr register offset of CAN stop request. | |
| 81 | + req_bit is the bit offset of CAN stop request. | |
| 82 | + $ref: /schemas/types.yaml#/definitions/phandle-array | |
| 83 | + items: | |
| 84 | + - description: The 'gpr' is the phandle to general purpose register node. | |
| 85 | + - description: The 'req_gpr' is the gpr register offset of CAN stop request. | |
| 86 | + maximum: 0xff | |
| 87 | + - description: The 'req_bit' is the bit offset of CAN stop request. | |
| 88 | + maximum: 0x1f | |
| 89 | + | |
| 90 | + fsl,clk-source: | |
| 91 | + description: | | |
| 92 | + Select the clock source to the CAN Protocol Engine (PE). It's SoC | |
| 93 | + implementation dependent. Refer to RM for detailed definition. If this | |
| 94 | + property is not set in device tree node then driver selects clock source 1 | |
| 95 | + by default. | |
| 96 | + 0: clock source 0 (oscillator clock) | |
| 97 | + 1: clock source 1 (peripheral clock) | |
| 98 | + $ref: /schemas/types.yaml#/definitions/uint32 | |
| 99 | + default: 1 | |
| 100 | + minimum: 0 | |
| 101 | + maximum: 1 | |
| 102 | + | |
| 103 | + wakeup-source: | |
| 104 | + $ref: /schemas/types.yaml#/definitions/flag | |
| 105 | + description: | |
| 106 | + Enable CAN remote wakeup. | |
| 107 | + | |
| 108 | +required: | |
| 109 | + - compatible | |
| 110 | + - reg | |
| 111 | + - interrupts | |
| 112 | + | |
| 113 | +additionalProperties: false | |
| 114 | + | |
| 115 | +examples: | |
| 116 | + - | | |
| 117 | + can@1c000 { | |
| 118 | + compatible = "fsl,p1010-flexcan"; | |
| 119 | + reg = <0x1c000 0x1000>; | |
| 120 | + interrupts = <48 0x2>; | |
| 121 | + interrupt-parent = <&mpic>; | |
| 122 | + clock-frequency = <200000000>; | |
| 123 | + fsl,clk-source = <0>; | |
| 124 | + }; | |
| 125 | + - | | |
| 126 | + #include <dt-bindings/interrupt-controller/irq.h> | |
| 127 | + | |
| 128 | + can@2090000 { | |
| 129 | + compatible = "fsl,imx6q-flexcan"; | |
| 130 | + reg = <0x02090000 0x4000>; | |
| 131 | + interrupts = <0 110 IRQ_TYPE_LEVEL_HIGH>; | |
| 132 | + clocks = <&clks 1>, <&clks 2>; | |
| 133 | + clock-names = "ipg", "per"; | |
| 134 | + fsl,stop-mode = <&gpr 0x34 28>; | |
| 135 | + }; | |
| @@ -1,57 +0,0 @@ | ||
| 1 | −Flexcan CAN controller on Freescale's ARM and PowerPC system-on-a-chip (SOC). | |
| 2 | − | |
| 3 | −Required properties: | |
| 4 | − | |
| 5 | −- compatible : Should be "fsl,<processor>-flexcan" | |
| 6 | − | |
| 7 | − where <processor> is imx8qm, imx6q, imx28, imx53, imx35, imx25, p1010, | |
| 8 | − vf610, ls1021ar2, lx2160ar1, ls1028ar1. | |
| 9 | − | |
| 10 | − The ls1028ar1 must be followed by lx2160ar1, e.g. | |
| 11 | − - "fsl,ls1028ar1-flexcan", "fsl,lx2160ar1-flexcan" | |
| 12 | − | |
| 13 | − An implementation should also claim any of the following compatibles | |
| 14 | − that it is fully backwards compatible with: | |
| 15 | − | |
| 16 | − - fsl,p1010-flexcan | |
| 17 | − | |
| 18 | −- reg : Offset and length of the register set for this device | |
| 19 | −- interrupts : Interrupt tuple for this device | |
| 20 | − | |
| 21 | −Optional properties: | |
| 22 | − | |
| 23 | −- clock-frequency : The oscillator frequency driving the flexcan device | |
| 24 | − | |
| 25 | −- xceiver-supply: Regulator that powers the CAN transceiver | |
| 26 | − | |
| 27 | −- big-endian: This means the registers of FlexCAN controller are big endian. | |
| 28 | − This is optional property.i.e. if this property is not present in | |
| 29 | − device tree node then controller is assumed to be little endian. | |
| 30 | − if this property is present then controller is assumed to be big | |
| 31 | − endian. | |
| 32 | − | |
| 33 | −- fsl,stop-mode: register bits of stop mode control, the format is | |
| 34 | − <&gpr req_gpr req_bit>. | |
| 35 | − gpr is the phandle to general purpose register node. | |
| 36 | − req_gpr is the gpr register offset of CAN stop request. | |
| 37 | − req_bit is the bit offset of CAN stop request. | |
| 38 | − | |
| 39 | −- fsl,clk-source: Select the clock source to the CAN Protocol Engine (PE). | |
| 40 | − It's SoC Implementation dependent. Refer to RM for detailed | |
| 41 | − definition. If this property is not set in device tree node | |
| 42 | − then driver selects clock source 1 by default. | |
| 43 | − 0: clock source 0 (oscillator clock) | |
| 44 | − 1: clock source 1 (peripheral clock) | |
| 45 | − | |
| 46 | −- wakeup-source: enable CAN remote wakeup | |
| 47 | − | |
| 48 | −Example: | |
| 49 | − | |
| 50 | − can@1c000 { | |
| 51 | − compatible = "fsl,p1010-flexcan"; | |
| 52 | − reg = <0x1c000 0x1000>; | |
| 53 | − interrupts = <48 0x2>; | |
| 54 | − interrupt-parent = <&mpic>; | |
| 55 | − clock-frequency = <200000000>; // filled in by bootloader | |
| 56 | − fsl,clk-source = <0>; // select clock source 0 for PE | |
| 57 | − }; | |
| @@ -86,9 +86,6 @@ Other Functions · 85 unmodified lines | ||
| 86 | 86 | .. kernel-doc:: fs/dax.c |
| 87 | 87 | :export: |
| 88 | 88 | |
| 89 | −.. kernel-doc:: fs/direct-io.c | |
| 90 | − :export: | |
| 91 | − | |
| 92 | 89 | .. kernel-doc:: fs/libfs.c |
| 93 | 90 | :export: |
| 94 | 91 | |
| @@ -83,10 +83,6 @@ AMDGPU XGMI Support · 82 unmodified lines | ||
| 83 | 83 | =================== |
| 84 | 84 | |
| 85 | 85 | .. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c |
| 86 | − :doc: AMDGPU XGMI Support | |
| 87 | − | |
| 88 | −.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c | |
| 89 | − :internal: | |
| 90 | 86 | |
| 91 | 87 | AMDGPU RAS Support |
| 92 | 88 | ================== |
| @@ -124,9 +120,6 @@ RAS VRAM Bad Pages sysfs Interface · 31 unmodified lines | ||
| 124 | 120 | .. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c |
| 125 | 121 | :doc: AMDGPU RAS sysfs gpu_vram_bad_pages Interface |
| 126 | 122 | |
| 127 | −.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | |
| 128 | − :internal: | |
| 129 | − | |
| 130 | 123 | Sample Code |
| 131 | 124 | ----------- |
| 132 | 125 | Sample code for testing error injection can be found here: |
| @@ -118,6 +118,12 @@ Atomic Plane Helpers · 117 unmodified lines | ||
| 118 | 118 | .. kernel-doc:: drivers/gpu/drm/i915/display/intel_atomic_plane.c |
| 119 | 119 | :internal: |
| 120 | 120 | |
| 121 | +Asynchronous Page Flip | |
| 122 | +---------------------- | |
| 123 | + | |
| 124 | +.. kernel-doc:: drivers/gpu/drm/i915/display/intel_display.c | |
| 125 | + :doc: asynchronous flip implementation | |
| 126 | + | |
| 121 | 127 | Output Probing |
| 122 | 128 | -------------- |
| 123 | 129 | |
| @@ -20,7 +20,7 @@ ADM1266 is a sequencer that features voltage readback from 17 channels via an · 19 unmodified lines | ||
| 20 | 20 | integrated 12 bit SAR ADC, accessed using a PMBus interface. |
| 21 | 21 | |
| 22 | 22 | The driver is a client driver to the core PMBus driver. Please see |
| 23 | −Documentation/hwmon/pmbus for details on PMBus client drivers. | |
| 23 | +Documentation/hwmon/pmbus.rst for details on PMBus client drivers. | |
| 24 | 24 | |
| 25 | 25 | |
| 26 | 26 | Sysfs entries |
| @@ -132,6 +132,7 @@ Hardware Monitoring Kernel Drivers · 131 unmodified lines | ||
| 132 | 132 | mcp3021 |
| 133 | 133 | menf21bmc |
| 134 | 134 | mlxreg-fan |
| 135 | + mp2975 | |
| 135 | 136 | nct6683 |
| 136 | 137 | nct6775 |
| 137 | 138 | nct7802 |
| @@ -20,6 +20,7 @@ This driver implements support for Monolithic Power Systems, Inc. (MPS) · 19 unmodified lines | ||
| 20 | 20 | vendor dual-loop, digital, multi-phase controller MP2975. |
| 21 | 21 | |
| 22 | 22 | This device: |
| 23 | + | |
| 23 | 24 | - Supports up to two power rail. |
| 24 | 25 | - Provides 8 pulse-width modulations (PWMs), and can be configured up |
| 25 | 26 | to 8-phase operation for rail 1 and up to 4-phase operation for rail |
| @@ -32,10 +33,12 @@ This device: · 6 unmodified lines | ||
| 32 | 33 | 10-mV DAC, IMVP9 mode with 5-mV DAC. |
| 33 | 34 | |
| 34 | 35 | Device supports: |
| 36 | + | |
| 35 | 37 | - SVID interface. |
| 36 | 38 | - AVSBus interface. |
| 37 | 39 | |
| 38 | 40 | Device complaint with: |
| 41 | + | |
| 39 | 42 | - PMBus rev 1.3 interface. |
| 40 | 43 | |
| 41 | 44 | Device supports direct format for reading output current, output voltage, |
| @@ -45,11 +48,14 @@ Device supports VID and direct formats for reading output voltage. · 3 unmodified lines | ||
| 45 | 48 | The below VID modes are supported: VR12, VR13, IMVP9. |
| 46 | 49 | |
| 47 | 50 | The driver provides the next attributes for the current: |
| 51 | + | |
| 48 | 52 | - for current in: input, maximum alarm; |
| 49 | 53 | - for current out input, maximum alarm and highest values; |
| 50 | 54 | - for phase current: input and label. |
| 51 | −attributes. | |
| 55 | + attributes. | |
| 56 | + | |
| 52 | 57 | The driver exports the following attributes via the 'sysfs' files, where |
| 58 | + | |
| 53 | 59 | - 'n' is number of telemetry pages (from 1 to 2); |
| 54 | 60 | - 'k' is number of configured phases (from 1 to 8); |
| 55 | 61 | - indexes 1, 1*n for "iin"; |
| @@ -65,11 +71,14 @@ The driver exports the following attributes via the 'sysfs' files, where · 9 unmodified lines | ||
| 65 | 71 | **curr[1-{2n+k}]_label** |
| 66 | 72 | |
| 67 | 73 | The driver provides the next attributes for the voltage: |
| 74 | + | |
| 68 | 75 | - for voltage in: input, high critical threshold, high critical alarm, all only |
| 69 | 76 | from page 0; |
| 70 | 77 | - for voltage out: input, low and high critical thresholds, low and high |
| 71 | 78 | critical alarms, from pages 0 and 1; |
| 79 | + | |
| 72 | 80 | The driver exports the following attributes via the 'sysfs' files, where |
| 81 | + | |
| 73 | 82 | - 'n' is number of telemetry pages (from 1 to 2); |
| 74 | 83 | - indexes 1 for "iin"; |
| 75 | 84 | - indexes n+1, n+2 for "vout"; |
| @@ -87,9 +96,12 @@ The driver exports the following attributes via the 'sysfs' files, where · 11 unmodified lines | ||
| 87 | 96 | **in[2-{n+1}1_lcrit_alarm** |
| 88 | 97 | |
| 89 | 98 | The driver provides the next attributes for the power: |
| 99 | + | |
| 90 | 100 | - for power in alarm and input. |
| 91 | 101 | - for power out: highest and input. |
| 102 | + | |
| 92 | 103 | The driver exports the following attributes via the 'sysfs' files, where |
| 104 | + | |
| 93 | 105 | - 'n' is number of telemetry pages (from 1 to 2); |
| 94 | 106 | - indexes 1 for "pin"; |
| 95 | 107 | - indexes n+1, n+2 for "pout"; |
| @@ -25,3 +25,4 @@ LEDs · 24 unmodified lines | ||
| 25 | 25 | leds-lp5562 |
| 26 | 26 | leds-lp55xx |
| 27 | 27 | leds-mlxcpld |
| 28 | + leds-sc27xx | |
| @@ -42,6 +42,7 @@ The validator tracks lock-class usage history and divides the usage into · 41 unmodified lines | ||
| 42 | 42 | (4 usages * n STATEs + 1) categories: |
| 43 | 43 | |
| 44 | 44 | where the 4 usages can be: |
| 45 | + | |
| 45 | 46 | - 'ever held in STATE context' |
| 46 | 47 | - 'ever held as readlock in STATE context' |
| 47 | 48 | - 'ever held with STATE enabled' |
| @@ -49,10 +50,12 @@ where the 4 usages can be: · 1 unmodified line | ||
| 49 | 50 | |
| 50 | 51 | where the n STATEs are coded in kernel/locking/lockdep_states.h and as of |
| 51 | 52 | now they include: |
| 53 | + | |
| 52 | 54 | - hardirq |
| 53 | 55 | - softirq |
| 54 | 56 | |
| 55 | 57 | where the last 1 category is: |
| 58 | + | |
| 56 | 59 | - 'ever used' [ == !unused ] |
| 57 | 60 | |
| 58 | 61 | When locking rules are violated, these usage bits are presented in the |
| @@ -96,9 +99,9 @@ exact case is for the lock as of the reporting time. · 37 unmodified lines | ||
| 96 | 99 | +--------------+-------------+--------------+ |
| 97 | 100 | | | irq enabled | irq disabled | |
| 98 | 101 | +--------------+-------------+--------------+ |
| 99 | − | ever in irq | ? | - | | |
| 102 | + | ever in irq | '?' | '-' | | |
| 100 | 103 | +--------------+-------------+--------------+ |
| 101 | − | never in irq | + | . | | |
| 104 | + | never in irq | '+' | '.' | | |
| 102 | 105 | +--------------+-------------+--------------+ |
| 103 | 106 | |
| 104 | 107 | The character '-' suggests irq is disabled because if otherwise the |
| @@ -216,7 +219,7 @@ looks like this:: · 111 unmodified lines | ||
| 216 | 219 | BD_MUTEX_PARTITION |
| 217 | 220 | }; |
| 218 | 221 | |
| 219 | −mutex_lock_nested(&bdev->bd_contains->bd_mutex, BD_MUTEX_PARTITION); | |
| 222 | + mutex_lock_nested(&bdev->bd_contains->bd_mutex, BD_MUTEX_PARTITION); | |
| 220 | 223 | |
| 221 | 224 | In this case the locking is done on a bdev object that is known to be a |
| 222 | 225 | partition. |
| @@ -334,7 +337,7 @@ Troubleshooting: · 111 unmodified lines | ||
| 334 | 337 | ---------------- |
| 335 | 338 | |
| 336 | 339 | The validator tracks a maximum of MAX_LOCKDEP_KEYS number of lock classes. |
| 337 | −Exceeding this number will trigger the following lockdep warning: | |
| 340 | +Exceeding this number will trigger the following lockdep warning:: | |
| 338 | 341 | |
| 339 | 342 | (DEBUG_LOCKS_WARN_ON(id >= MAX_LOCKDEP_KEYS)) |
| 340 | 343 | |
| @@ -420,7 +423,8 @@ the critical section of another reader of the same lock instance. · 79 unmodified lines | ||
| 420 | 423 | |
| 421 | 424 | The difference between recursive readers and non-recursive readers is because: |
| 422 | 425 | recursive readers get blocked only by a write lock *holder*, while non-recursive |
| 423 | −readers could get blocked by a write lock *waiter*. Considering the follow example: | |
| 426 | +readers could get blocked by a write lock *waiter*. Considering the follow | |
| 427 | +example:: | |
| 424 | 428 | |
| 425 | 429 | TASK A: TASK B: |
| 426 | 430 | |
| @@ -448,20 +452,22 @@ There are simply four block conditions: · 21 unmodified lines | ||
| 448 | 452 | |
| 449 | 453 | Block condition matrix, Y means the row blocks the column, and N means otherwise. |
| 450 | 454 | |
| 451 | − | E | r | R | | |
| 452 | 455 | +---+---+---+---+ |
| 453 | − E | Y | Y | Y | | |
| 456 | + | | E | r | R | | |
| 457 | + +---+---+---+---+ | |
| 458 | + | E | Y | Y | Y | | |
| 459 | + +---+---+---+---+ | |
| 460 | + | r | Y | Y | N | | |
| 454 | 461 | +---+---+---+---+ |
| 455 | − r | Y | Y | N | | |
| 462 | + | R | Y | Y | N | | |
| 456 | 463 | +---+---+---+---+ |
| 457 | − R | Y | Y | N | | |
| 458 | 464 | |
| 459 | 465 | (W: writers, r: non-recursive readers, R: recursive readers) |
| 460 | 466 | |
| 461 | 467 | |
| 462 | 468 | acquired recursively. Unlike non-recursive read locks, recursive read locks |
| 463 | 469 | only get blocked by current write lock *holders* other than write lock |
| 464 | −*waiters*, for example: | |
| 470 | +*waiters*, for example:: | |
| 465 | 471 | |
| 466 | 472 | TASK A: TASK B: |
| 467 | 473 | |
| @@ -491,7 +497,7 @@ Recursive locks don't block each other, while non-recursive locks do (this is · 23 unmodified lines | ||
| 491 | 497 | even true for two non-recursive read locks). A non-recursive lock can block the |
| 492 | 498 | corresponding recursive lock, and vice versa. |
| 493 | 499 | |
| 494 | −A deadlock case with recursive locks involved is as follow: | |
| 500 | +A deadlock case with recursive locks involved is as follow:: | |
| 495 | 501 | |
| 496 | 502 | TASK A: TASK B: |
| 497 | 503 | |
| @@ -510,7 +516,7 @@ because there are 3 types for lockers, there are, in theory, 9 types of lock · 12 unmodified lines | ||
| 510 | 516 | dependencies, but we can show that 4 types of lock dependencies are enough for |
| 511 | 517 | deadlock detection. |
| 512 | 518 | |
| 513 | −For each lock dependency: | |
| 519 | +For each lock dependency:: | |
| 514 | 520 | |
| 515 | 521 | L1 -> L2 |
| 516 | 522 | |
| @@ -525,20 +531,25 @@ same types). · 8 unmodified lines | ||
| 525 | 531 | With the above combination for simplification, there are 4 types of dependency edges |
| 526 | 532 | in the lockdep graph: |
| 527 | 533 | |
| 528 | −1) -(ER)->: exclusive writer to recursive reader dependency, "X -(ER)-> Y" means | |
| 534 | +1) -(ER)->: | |
| 535 | + exclusive writer to recursive reader dependency, "X -(ER)-> Y" means | |
| 529 | 536 | X -> Y and X is a writer and Y is a recursive reader. |
| 530 | 537 | |
| 531 | −2) -(EN)->: exclusive writer to non-recursive locker dependency, "X -(EN)-> Y" means | |
| 538 | +2) -(EN)->: | |
| 539 | + exclusive writer to non-recursive locker dependency, "X -(EN)-> Y" means | |
| 532 | 540 | X -> Y and X is a writer and Y is either a writer or non-recursive reader. |
| 533 | 541 | |
| 534 | −3) -(SR)->: shared reader to recursive reader dependency, "X -(SR)-> Y" means | |
| 542 | +3) -(SR)->: | |
| 543 | + shared reader to recursive reader dependency, "X -(SR)-> Y" means | |
| 535 | 544 | X -> Y and X is a reader (recursive or not) and Y is a recursive reader. |
| 536 | 545 | |
| 537 | −4) -(SN)->: shared reader to non-recursive locker dependency, "X -(SN)-> Y" means | |
| 546 | +4) -(SN)->: | |
| 547 | + shared reader to non-recursive locker dependency, "X -(SN)-> Y" means | |
| 538 | 548 | X -> Y and X is a reader (recursive or not) and Y is either a writer or |
| 539 | 549 | non-recursive reader. |
| 540 | 550 | |
| 541 | −Note that given two locks, they may have multiple dependencies between them, for example: | |
| 551 | +Note that given two locks, they may have multiple dependencies between them, | |
| 552 | +for example:: | |
| 542 | 553 | |
| 543 | 554 | TASK A: |
| 544 | 555 | |
| @@ -592,11 +603,11 @@ circles that won't cause deadlocks. · 47 unmodified lines | ||
| 592 | 603 | |
| 593 | 604 | Proof for sufficiency (Lemma 1): |
| 594 | 605 | |
| 595 | −Let's say we have a strong circle: | |
| 606 | +Let's say we have a strong circle:: | |
| 596 | 607 | |
| 597 | 608 | L1 -> L2 ... -> Ln -> L1 |
| 598 | 609 | |
| 599 | −, which means we have dependencies: | |
| 610 | +, which means we have dependencies:: | |
| 600 | 611 | |
| 601 | 612 | L1 -> L2 |
| 602 | 613 | L2 -> L3 |
| @@ -633,7 +644,7 @@ a lock held by P2, and P2 is waiting for a lock held by P3, ... and Pn is waitin · 30 unmodified lines | ||
| 633 | 644 | for a lock held by P1. Let's name the lock Px is waiting as Lx, so since P1 is waiting |
| 634 | 645 | for L1 and holding Ln, so we will have Ln -> L1 in the dependency graph. Similarly, |
| 635 | 646 | we have L1 -> L2, L2 -> L3, ..., Ln-1 -> Ln in the dependency graph, which means we |
| 636 | −have a circle: | |
| 647 | +have a circle:: | |
| 637 | 648 | |
| 638 | 649 | Ln -> L1 -> L2 -> ... -> Ln |
| 639 | 650 | |
| @@ -24,7 +24,6 @@ fit into other categories. · 23 unmodified lines | ||
| 24 | 24 | isl29003 |
| 25 | 25 | lis3lv02d |
| 26 | 26 | max6875 |
| 27 | − mic/index | |
| 28 | 27 | pci-endpoint-test |
| 29 | 28 | spear-pcie-gadget |
| 30 | 29 | uacce |
| @@ -70,6 +70,7 @@ The ``ice`` driver reports the following versions · 69 unmodified lines | ||
| 70 | 70 | that both the name (as reported by ``fw.app.name``) and version are |
| 71 | 71 | required to uniquely identify the package. |
| 72 | 72 | * - ``fw.app.bundle_id`` |
| 73 | + - running | |
| 73 | 74 | - 0xc0000001 |
| 74 | 75 | - Unique identifier for the DDP package loaded in the device. Also |
| 75 | 76 | referred to as the DDP Track ID. Can be used to uniquely identify |
| @@ -10,9 +10,9 @@ Overview / What Is J1939 · 9 unmodified lines | ||
| 10 | 10 | SAE J1939 defines a higher layer protocol on CAN. It implements a more |
| 11 | 11 | sophisticated addressing scheme and extends the maximum packet size above 8 |
| 12 | 12 | bytes. Several derived specifications exist, which differ from the original |
| 13 | −J1939 on the application level, like MilCAN A, NMEA2000 and especially | |
| 13 | +J1939 on the application level, like MilCAN A, NMEA2000, and especially | |
| 14 | 14 | ISO-11783 (ISOBUS). This last one specifies the so-called ETP (Extended |
| 15 | −Transport Protocol) which is has been included in this implementation. This | |
| 15 | +Transport Protocol), which has been included in this implementation. This | |
| 16 | 16 | results in a maximum packet size of ((2 ^ 24) - 1) * 7 bytes == 111 MiB. |
| 17 | 17 | |
| 18 | 18 | Specifications used |
| @@ -32,15 +32,15 @@ sockets, we found some reasons to justify a kernel implementation for the · 13 unmodified lines | ||
| 32 | 32 | addressing and transport methods used by J1939. |
| 33 | 33 | |
| 34 | 34 | * **Addressing:** when a process on an ECU communicates via J1939, it should |
| 35 | − not necessarily know its source address. Although at least one process per | |
| 35 | + not necessarily know its source address. Although, at least one process per | |
| 36 | 36 | ECU should know the source address. Other processes should be able to reuse |
| 37 | 37 | that address. This way, address parameters for different processes |
| 38 | 38 | cooperating for the same ECU, are not duplicated. This way of working is |
| 39 | − closely related to the UNIX concept where programs do just one thing, and do | |
| 39 | + closely related to the UNIX concept, where programs do just one thing and do | |
| 40 | 40 | it well. |
| 41 | 41 | |
| 42 | 42 | * **Dynamic addressing:** Address Claiming in J1939 is time critical. |
| 43 | − Furthermore data transport should be handled properly during the address | |
| 43 | + Furthermore, data transport should be handled properly during the address | |
| 44 | 44 | negotiation. Putting this functionality in the kernel eliminates it as a |
| 45 | 45 | requirement for _every_ user space process that communicates via J1939. This |
| 46 | 46 | results in a consistent J1939 bus with proper addressing. |
| @@ -58,7 +58,7 @@ Therefore, these parts are left to user space. · 11 unmodified lines | ||
| 58 | 58 | |
| 59 | 59 | The J1939 sockets operate on CAN network devices (see SocketCAN). Any J1939 |
| 60 | 60 | user space library operating on CAN raw sockets will still operate properly. |
| 61 | −Since such library does not communicate with the in-kernel implementation, care | |
| 61 | +Since such a library does not communicate with the in-kernel implementation, care | |
| 62 | 62 | must be taken that these two do not interfere. In practice, this means they |
| 63 | 63 | cannot share ECU addresses. A single ECU (or virtual ECU) address is used by |
| 64 | 64 | the library exclusively, or by the in-kernel system exclusively. |
| @@ -77,13 +77,13 @@ is composed as follows: · 12 unmodified lines | ||
| 77 | 77 | 8 bits : PS (PDU Specific) |
| 78 | 78 | |
| 79 | 79 | In J1939-21 distinction is made between PDU1 format (where PF < 240) and PDU2 |
| 80 | −format (where PF >= 240). Furthermore, when using PDU2 format, the PS-field | |
| 80 | +format (where PF >= 240). Furthermore, when using the PDU2 format, the PS-field | |
| 81 | 81 | contains a so-called Group Extension, which is part of the PGN. When using PDU2 |
| 82 | 82 | format, the Group Extension is set in the PS-field. |
| 83 | 83 | |
| 84 | 84 | On the other hand, when using PDU1 format, the PS-field contains a so-called |
| 85 | 85 | Destination Address, which is _not_ part of the PGN. When communicating a PGN |
| 86 | −from user space to kernel (or visa versa) and PDU2 format is used, the PS-field | |
| 86 | +from user space to kernel (or vice versa) and PDU2 format is used, the PS-field | |
| 87 | 87 | of the PGN shall be set to zero. The Destination Address shall be set |
| 88 | 88 | elsewhere. |
| 89 | 89 | |
| @@ -96,15 +96,15 @@ Addressing · 6 unmodified lines | ||
| 96 | 96 | |
| 97 | 97 | Both static and dynamic addressing methods can be used. |
| 98 | 98 | |
| 99 | −For static addresses, no extra checks are made by the kernel, and provided | |
| 99 | +For static addresses, no extra checks are made by the kernel and provided | |
| 100 | 100 | addresses are considered right. This responsibility is for the OEM or system |
| 101 | 101 | integrator. |
| 102 | 102 | |
| 103 | 103 | For dynamic addressing, so-called Address Claiming, extra support is foreseen |
| 104 | −in the kernel. In J1939 any ECU is known by it's 64-bit NAME. At the moment of | |
| 104 | +in the kernel. In J1939 any ECU is known by its 64-bit NAME. At the moment of | |
| 105 | 105 | a successful address claim, the kernel keeps track of both NAME and source |
| 106 | 106 | address being claimed. This serves as a base for filter schemes. By default, |
| 107 | −packets with a destination that is not locally, will be rejected. | |
| 107 | +packets with a destination that is not locally will be rejected. | |
| 108 | 108 | |
| 109 | 109 | Mixed mode packets (from a static to a dynamic address or vice versa) are |
| 110 | 110 | allowed. The BSD sockets define separate API calls for getting/setting the |
| @@ -131,31 +131,31 @@ API Calls · 20 unmodified lines | ||
| 131 | 131 | --------- |
| 132 | 132 | |
| 133 | 133 | On CAN, you first need to open a socket for communicating over a CAN network. |
| 134 | −To use J1939, #include <linux/can/j1939.h>. From there, <linux/can.h> will be | |
| 134 | +To use J1939, ``#include <linux/can/j1939.h>``. From there, ``<linux/can.h>`` will be | |
| 135 | 135 | included too. To open a socket, use: |
| 136 | 136 | |
| 137 | 137 | .. code-block:: C |
| 138 | 138 | |
| 139 | 139 | s = socket(PF_CAN, SOCK_DGRAM, CAN_J1939); |
| 140 | 140 | |
| 141 | −J1939 does use SOCK_DGRAM sockets. In the J1939 specification, connections are | |
| 141 | +J1939 does use ``SOCK_DGRAM`` sockets. In the J1939 specification, connections are | |
| 142 | 142 | mentioned in the context of transport protocol sessions. These still deliver |
| 143 | −packets to the other end (using several CAN packets). SOCK_STREAM is not | |
| 143 | +packets to the other end (using several CAN packets). ``SOCK_STREAM`` is not | |
| 144 | 144 | supported. |
| 145 | 145 | |
| 146 | −After the successful creation of the socket, you would normally use the bind(2) | |
| 147 | −and/or connect(2) system call to bind the socket to a CAN interface. After | |
| 148 | −binding and/or connecting the socket, you can read(2) and write(2) from/to the | |
| 149 | −socket or use send(2), sendto(2), sendmsg(2) and the recv*() counterpart | |
| 146 | +After the successful creation of the socket, you would normally use the ``bind(2)`` | |
| 147 | +and/or ``connect(2)`` system call to bind the socket to a CAN interface. After | |
| 148 | +binding and/or connecting the socket, you can ``read(2)`` and ``write(2)`` from/to the | |
| 149 | +socket or use ``send(2)``, ``sendto(2)``, ``sendmsg(2)`` and the ``recv*()`` counterpart | |
| 150 | 150 | operations on the socket as usual. There are also J1939 specific socket options |
| 151 | 151 | described below. |
| 152 | 152 | |
| 153 | −In order to send data, a bind(2) must have been successful. bind(2) assigns a | |
| 153 | +In order to send data, a ``bind(2)`` must have been successful. ``bind(2)`` assigns a | |
| 154 | 154 | local address to a socket. |
| 155 | 155 | |
| 156 | −Different from CAN is that the payload data is just the data that get send, | |
| 157 | −without it's header info. The header info is derived from the sockaddr supplied | |
| 158 | −to bind(2), connect(2), sendto(2) and recvfrom(2). A write(2) with size 4 will | |
| 156 | +Different from CAN is that the payload data is just the data that get sends, | |
| 157 | +without its header info. The header info is derived from the sockaddr supplied | |
| 158 | +to ``bind(2)``, ``connect(2)``, ``sendto(2)`` and ``recvfrom(2)``. A ``write(2)`` with size 4 will | |
| 159 | 159 | result in a packet with 4 bytes. |
| 160 | 160 | |
| 161 | 161 | The sockaddr structure has extensions for use with J1939 as specified below: |
| @@ -180,47 +180,47 @@ The sockaddr structure has extensions for use with J1939 as specified below: · 18 unmodified lines | ||
| 180 | 180 | } can_addr; |
| 181 | 181 | } |
| 182 | 182 | |
| 183 | −can_family & can_ifindex serve the same purpose as for other SocketCAN sockets. | |
| 183 | +``can_family`` & ``can_ifindex`` serve the same purpose as for other SocketCAN sockets. | |
| 184 | 184 | |
| 185 | −can_addr.j1939.pgn specifies the PGN (max 0x3ffff). Individual bits are | |
| 185 | +``can_addr.j1939.pgn`` specifies the PGN (max 0x3ffff). Individual bits are | |
| 186 | 186 | specified above. |
| 187 | 187 | |
| 188 | −can_addr.j1939.name contains the 64-bit J1939 NAME. | |
| 188 | +``can_addr.j1939.name`` contains the 64-bit J1939 NAME. | |
| 189 | 189 | |
| 190 | −can_addr.j1939.addr contains the address. | |
| 190 | +``can_addr.j1939.addr`` contains the address. | |
| 191 | 191 | |
| 192 | −The bind(2) system call assigns the local address, i.e. the source address when | |
| 193 | −sending packages. If a PGN during bind(2) is set, it's used as a RX filter. | |
| 194 | −I.e. only packets with a matching PGN are received. If an ADDR or NAME is set | |
| 192 | +The ``bind(2)`` system call assigns the local address, i.e. the source address when | |
| 193 | +sending packages. If a PGN during ``bind(2)`` is set, it's used as a RX filter. | |
| 194 | +I.e. only packets with a matching PGN are received. If an ADDR or NAME is set | |
| 195 | 195 | it is used as a receive filter, too. It will match the destination NAME or ADDR |
| 196 | 196 | of the incoming packet. The NAME filter will work only if appropriate Address |
| 197 | 197 | Claiming for this name was done on the CAN bus and registered/cached by the |
| 198 | 198 | kernel. |
| 199 | 199 | |
| 200 | −On the other hand connect(2) assigns the remote address, i.e. the destination | |
| 201 | −address. The PGN from connect(2) is used as the default PGN when sending | |
| 200 | +On the other hand ``connect(2)`` assigns the remote address, i.e. the destination | |
| 201 | +address. The PGN from ``connect(2)`` is used as the default PGN when sending | |
| 202 | 202 | packets. If ADDR or NAME is set it will be used as the default destination ADDR |
| 203 | −or NAME. Further a set ADDR or NAME during connect(2) is used as a receive | |
| 203 | +or NAME. Further a set ADDR or NAME during ``connect(2)`` is used as a receive | |
| 204 | 204 | filter. It will match the source NAME or ADDR of the incoming packet. |
| 205 | 205 | |
| 206 | −Both write(2) and send(2) will send a packet with local address from bind(2) and | |
| 207 | −the remote address from connect(2). Use sendto(2) to overwrite the destination | |
| 206 | +Both ``write(2)`` and ``send(2)`` will send a packet with local address from ``bind(2)`` and the | |
| 207 | +remote address from ``connect(2)``. Use ``sendto(2)`` to overwrite the destination | |
| 208 | 208 | address. |
| 209 | 209 | |
| 210 | −If can_addr.j1939.name is set (!= 0) the NAME is looked up by the kernel and | |
| 211 | −the corresponding ADDR is used. If can_addr.j1939.name is not set (== 0), | |
| 212 | −can_addr.j1939.addr is used. | |
| 210 | +If ``can_addr.j1939.name`` is set (!= 0) the NAME is looked up by the kernel and | |
| 211 | +the corresponding ADDR is used. If ``can_addr.j1939.name`` is not set (== 0), | |
| 212 | +``can_addr.j1939.addr`` is used. | |
| 213 | 213 | |
| 214 | 214 | When creating a socket, reasonable defaults are set. Some options can be |
| 215 | −modified with setsockopt(2) & getsockopt(2). | |
| 215 | +modified with ``setsockopt(2)`` & ``getsockopt(2)``. | |
| 216 | 216 | |
| 217 | 217 | RX path related options: |
| 218 | 218 | |
| 219 | −- SO_J1939_FILTER - configure array of filters | |
| 220 | −- SO_J1939_PROMISC - disable filters set by bind(2) and connect(2) | |
| 219 | +- ``SO_J1939_FILTER`` - configure array of filters | |
| 220 | +- ``SO_J1939_PROMISC`` - disable filters set by ``bind(2)`` and ``connect(2)`` | |
| 221 | 221 | |
| 222 | 222 | By default no broadcast packets can be send or received. To enable sending or |
| 223 | −receiving broadcast packets use the socket option SO_BROADCAST: | |
| 223 | +receiving broadcast packets use the socket option ``SO_BROADCAST``: | |
| 224 | 224 | |
| 225 | 225 | .. code-block:: C |
| 226 | 226 | |
| @@ -261,26 +261,26 @@ The following diagram illustrates the RX path: · 34 unmodified lines | ||
| 261 | 261 | +---------------------------+ |
| 262 | 262 | |
| 263 | 263 | TX path related options: |
| 264 | −SO_J1939_SEND_PRIO - change default send priority for the socket | |
| 264 | +``SO_J1939_SEND_PRIO`` - change default send priority for the socket | |
| 265 | 265 | |
| 266 | 266 | Message Flags during send() and Related System Calls |
| 267 | 267 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 268 | 268 | |
| 269 | −send(2), sendto(2) and sendmsg(2) take a 'flags' argument. Currently | |
| 269 | +``send(2)``, ``sendto(2)`` and ``sendmsg(2)`` take a 'flags' argument. Currently | |
| 270 | 270 | supported flags are: |
| 271 | 271 | |
| 272 | −* MSG_DONTWAIT, i.e. non-blocking operation. | |
| 272 | +* ``MSG_DONTWAIT``, i.e. non-blocking operation. | |
| 273 | 273 | |
| 274 | 274 | recvmsg(2) |
| 275 | 275 | ^^^^^^^^^^ |
| 276 | 276 | |
| 277 | −In most cases recvmsg(2) is needed if you want to extract more information than | |
| 278 | −recvfrom(2) can provide. For example package priority and timestamp. The | |
| 277 | +In most cases ``recvmsg(2)`` is needed if you want to extract more information than | |
| 278 | +``recvfrom(2)`` can provide. For example package priority and timestamp. The | |
| 279 | 279 | Destination Address, name and packet priority (if applicable) are attached to |
| 280 | −the msghdr in the recvmsg(2) call. They can be extracted using cmsg(3) macros, | |
| 281 | −with cmsg_level == SOL_J1939 && cmsg_type == SCM_J1939_DEST_ADDR, | |
| 282 | −SCM_J1939_DEST_NAME or SCM_J1939_PRIO. The returned data is a uint8_t for | |
| 283 | −priority and dst_addr, and uint64_t for dst_name. | |
| 280 | +the msghdr in the ``recvmsg(2)`` call. They can be extracted using ``cmsg(3)`` macros, | |
| 281 | +with ``cmsg_level == SOL_J1939 && cmsg_type == SCM_J1939_DEST_ADDR``, | |
| 282 | +``SCM_J1939_DEST_NAME`` or ``SCM_J1939_PRIO``. The returned data is a ``uint8_t`` for | |
| 283 | +``priority`` and ``dst_addr``, and ``uint64_t`` for ``dst_name``. | |
| 284 | 284 | |
| 285 | 285 | .. code-block:: C |
| 286 | 286 | |
| @@ -305,12 +305,12 @@ Dynamic Addressing · 18 unmodified lines | ||
| 305 | 305 | |
| 306 | 306 | Distinction has to be made between using the claimed address and doing an |
| 307 | 307 | address claim. To use an already claimed address, one has to fill in the |
| 308 | −j1939.name member and provide it to bind(2). If the name had claimed an address | |
| 308 | +``j1939.name`` member and provide it to ``bind(2)``. If the name had claimed an address | |
| 309 | 309 | earlier, all further messages being sent will use that address. And the |
| 310 | −j1939.addr member will be ignored. | |
| 310 | +``j1939.addr`` member will be ignored. | |
| 311 | 311 | |
| 312 | 312 | An exception on this is PGN 0x0ee00. This is the "Address Claim/Cannot Claim |
| 313 | −Address" message and the kernel will use the j1939.addr member for that PGN if | |
| 313 | +Address" message and the kernel will use the ``j1939.addr`` member for that PGN if | |
| 314 | 314 | necessary. |
| 315 | 315 | |
| 316 | 316 | To claim an address following code example can be used: |
| @@ -371,12 +371,12 @@ NAME can send packets. · 54 unmodified lines | ||
| 371 | 371 | |
| 372 | 372 | If another ECU claims the address, the kernel will mark the NAME-SA expired. |
| 373 | 373 | No socket bound to the NAME can send packets (other than address claims). To |
| 374 | −claim another address, some socket bound to NAME, must bind(2) again, but with | |
| 375 | −only j1939.addr changed to the new SA, and must then send a valid address claim | |
| 374 | +claim another address, some socket bound to NAME, must ``bind(2)`` again, but with | |
| 375 | +only ``j1939.addr`` changed to the new SA, and must then send a valid address claim | |
| 376 | 376 | packet. This restarts the state machine in the kernel (and any other |
| 377 | 377 | participant on the bus) for this NAME. |
| 378 | 378 | |
| 379 | −can-utils also include the jacd tool, so it can be used as code example or as | |
| 379 | +``can-utils`` also include the ``j1939acd`` tool, so it can be used as code example or as | |
| 380 | 380 | default Address Claiming daemon. |
| 381 | 381 | |
| 382 | 382 | Send Examples |
| @@ -403,8 +403,8 @@ Bind: · 20 unmodified lines | ||
| 403 | 403 | |
| 404 | 404 | bind(sock, (struct sockaddr *)&baddr, sizeof(baddr)); |
| 405 | 405 | |
| 406 | −Now, the socket 'sock' is bound to the SA 0x20. Since no connect(2) was called, | |
| 407 | −at this point we can use only sendto(2) or sendmsg(2). | |
| 406 | +Now, the socket 'sock' is bound to the SA 0x20. Since no ``connect(2)`` was called, | |
| 407 | +at this point we can use only ``sendto(2)`` or ``sendmsg(2)``. | |
| 408 | 408 | |
| 409 | 409 | Send: |
| 410 | 410 | |
| @@ -414,8 +414,8 @@ Send: · 3 unmodified lines | ||
| 414 | 414 | .can_family = AF_CAN, |
| 415 | 415 | .can_addr.j1939 = { |
| 416 | 416 | .name = J1939_NO_NAME; |
| 417 | − .pgn = 0x30, | |
| 418 | − .addr = 0x12300, | |
| 417 | + .addr = 0x30, | |
| 418 | + .pgn = 0x12300, | |
| 419 | 419 | }, |
| 420 | 420 | }; |
| 421 | 421 | |
| @@ -175,5 +175,4 @@ The following structures are internal to the kernel, their members are · 174 unmodified lines | ||
| 175 | 175 | translated to netlink attributes when dumped. Drivers must not overwrite |
| 176 | 176 | the statistics they don't report with 0. |
| 177 | 177 | |
| 178 | −.. kernel-doc:: include/linux/ethtool.h | |
| 179 | − :identifiers: ethtool_pause_stats | |
| 178 | +- ethtool_pause_stats() | |
| @@ -15,6 +15,14 @@ else: · 14 unmodified lines | ||
| 15 | 15 | import re |
| 16 | 16 | from itertools import chain |
| 17 | 17 | |
| 18 | +# | |
| 19 | +# Python 2 lacks re.ASCII... | |
| 20 | +# | |
| 21 | +try: | |
| 22 | + ascii_p3 = re.ASCII | |
| 23 | +except AttributeError: | |
| 24 | + ascii_p3 = 0 | |
| 25 | + | |
| 18 | 26 | # |
| 19 | 27 | # Regex nastiness. Of course. |
| 20 | 28 | # Try to identify "function()" that's not already marked up some |
| @@ -22,22 +30,22 @@ from itertools import chain · 1 unmodified line | ||
| 22 | 30 | # :c:func: block (i.e. ":c:func:`mmap()`s" flakes out), so the last |
| 23 | 31 | # bit tries to restrict matches to things that won't create trouble. |
| 24 | 32 | # |
| 25 | −RE_function = re.compile(r'\b(([a-zA-Z_]\w+)\(\))', flags=re.ASCII) | |
| 33 | +RE_function = re.compile(r'\b(([a-zA-Z_]\w+)\(\))', flags=ascii_p3) | |
| 26 | 34 | |
| 27 | 35 | # |
| 28 | 36 | # Sphinx 2 uses the same :c:type role for struct, union, enum and typedef |
| 29 | 37 | # |
| 30 | 38 | RE_generic_type = re.compile(r'\b(struct|union|enum|typedef)\s+([a-zA-Z_]\w+)', |
| 31 | − flags=re.ASCII) | |
| 39 | + flags=ascii_p3) | |
| 32 | 40 | |
| 33 | 41 | # |
| 34 | 42 | # Sphinx 3 uses a different C role for each one of struct, union, enum and |
| 35 | 43 | # typedef |
| 36 | 44 | # |
| 37 | −RE_struct = re.compile(r'\b(struct)\s+([a-zA-Z_]\w+)', flags=re.ASCII) | |
| 38 | −RE_union = re.compile(r'\b(union)\s+([a-zA-Z_]\w+)', flags=re.ASCII) | |
| 39 | −RE_enum = re.compile(r'\b(enum)\s+([a-zA-Z_]\w+)', flags=re.ASCII) | |
| 40 | −RE_typedef = re.compile(r'\b(typedef)\s+([a-zA-Z_]\w+)', flags=re.ASCII) | |
| 45 | +RE_struct = re.compile(r'\b(struct)\s+([a-zA-Z_]\w+)', flags=ascii_p3) | |
| 46 | +RE_union = re.compile(r'\b(union)\s+([a-zA-Z_]\w+)', flags=ascii_p3) | |
| 47 | +RE_enum = re.compile(r'\b(enum)\s+([a-zA-Z_]\w+)', flags=ascii_p3) | |
| 48 | +RE_typedef = re.compile(r'\b(typedef)\s+([a-zA-Z_]\w+)', flags=ascii_p3) | |
| 41 | 49 | |
| 42 | 50 | # |
| 43 | 51 | # Detects a reference to a documentation page of the form Documentation/... with |
| @@ -22,6 +22,7 @@ place where this information is gathered. · 21 unmodified lines | ||
| 22 | 22 | spec_ctrl |
| 23 | 23 | accelerators/ocxl |
| 24 | 24 | ioctl/index |
| 25 | + iommu | |
| 25 | 26 | media/index |
| 26 | 27 | |
| 27 | 28 | .. only:: subproject and html |
| @@ -934,7 +934,7 @@ M: Evan Quan <evan.quan@amd.com> · 933 unmodified lines | ||
| 934 | 934 | L: amd-gfx@lists.freedesktop.org |
| 935 | 935 | S: Supported |
| 936 | 936 | T: git git://people.freedesktop.org/~agd5f/linux |
| 937 | −F: drivers/gpu/drm/amd/powerplay/ | |
| 937 | +F: drivers/gpu/drm/amd/pm/powerplay/ | |
| 938 | 938 | |
| 939 | 939 | AMD SEATTLE DEVICE TREE SUPPORT |
| 940 | 940 | M: Brijesh Singh <brijeshkumar.singh@amd.com> |
| @@ -978,7 +978,7 @@ M: Michael Hennerich <Michael.Hennerich@analog.com> · 37 unmodified lines | ||
| 978 | 978 | L: linux-iio@vger.kernel.org |
| 979 | 979 | S: Supported |
| 980 | 980 | W: http://ez.analog.com/community/linux-device-drivers |
| 981 | −F: Documentation/devicetree/bindings/iio/adc/adi,ad7768-1.txt | |
| 981 | +F: Documentation/devicetree/bindings/iio/adc/adi,ad7768-1.yaml | |
| 982 | 982 | F: drivers/iio/adc/ad7768-1.c |
| 983 | 983 | |
| 984 | 984 | ANALOG DEVICES INC AD7780 DRIVER |
| @@ -3857,7 +3857,7 @@ M: Roger Quadros <rogerq@ti.com> · 2872 unmodified lines | ||
| 3857 | 3857 | L: linux-usb@vger.kernel.org |
| 3858 | 3858 | S: Maintained |
| 3859 | 3859 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/peter.chen/usb.git |
| 3860 | −F: Documentation/devicetree/bindings/usb/cdns-usb3.txt | |
| 3860 | +F: Documentation/devicetree/bindings/usb/cdns,usb3.yaml | |
| 3861 | 3861 | F: drivers/usb/cdns3/ |
| 3862 | 3862 | |
| 3863 | 3863 | CADET FM/AM RADIO RECEIVER DRIVER |
| @@ -7923,7 +7923,7 @@ HISILICON LPC BUS DRIVER · 4059 unmodified lines | ||
| 7923 | 7923 | M: john.garry@huawei.com |
| 7924 | 7924 | S: Maintained |
| 7925 | 7925 | W: http://www.hisilicon.com |
| 7926 | −F: Documentation/devicetree/bindings/arm/hisilicon/hisilicon-low-pin-count.txt | |
| 7926 | +F: Documentation/devicetree/bindings/arm/hisilicon/low-pin-count.yaml | |
| 7927 | 7927 | F: drivers/bus/hisi_lpc.c |
| 7928 | 7928 | |
| 7929 | 7929 | HISILICON NETWORK SUBSYSTEM 3 DRIVER (HNS3) |
| @@ -11177,7 +11177,7 @@ F: Documentation/devicetree/bindings/input/touchscreen/melfas_mip4.txt · 3247 unmodified lines | ||
| 11177 | 11177 | F: drivers/input/touchscreen/melfas_mip4.c |
| 11178 | 11178 | |
| 11179 | 11179 | MELLANOX BLUEFIELD I2C DRIVER |
| 11180 | −M: Khalil Blaiech <kblaiech@mellanox.com> | |
| 11180 | +M: Khalil Blaiech <kblaiech@nvidia.com> | |
| 11181 | 11181 | L: linux-i2c@vger.kernel.org |
| 11182 | 11182 | S: Supported |
| 11183 | 11183 | F: drivers/i2c/busses/i2c-mlxbf.c |
| @@ -14541,6 +14541,14 @@ F: Documentation/devicetree/bindings/mailbox/qcom-ipcc.yaml · 3357 unmodified lines | ||
| 14541 | 14541 | F: drivers/mailbox/qcom-ipcc.c |
| 14542 | 14542 | F: include/dt-bindings/mailbox/qcom-ipcc.h |
| 14543 | 14543 | |
| 14544 | +QUALCOMM IPQ4019 VQMMC REGULATOR DRIVER | |
| 14545 | +M: Robert Marko <robert.marko@sartura.hr> | |
| 14546 | +M: Luka Perkov <luka.perkov@sartura.hr> | |
| 14547 | +L: linux-arm-msm@vger.kernel.org | |
| 14548 | +S: Maintained | |
| 14549 | +F: Documentation/devicetree/bindings/regulator/vqmmc-ipq4019-regulator.yaml | |
| 14550 | +F: drivers/regulator/vqmmc-ipq4019-regulator.c | |
| 14551 | + | |
| 14544 | 14552 | QUALCOMM RMNET DRIVER |
| 14545 | 14553 | M: Subash Abhinov Kasiviswanathan <subashab@codeaurora.org> |
| 14546 | 14554 | M: Sean Tranchetti <stranche@codeaurora.org> |
| @@ -14896,7 +14904,6 @@ RENESAS ETHERNET DRIVERS · 349 unmodified lines | ||
| 14896 | 14904 | R: Sergei Shtylyov <sergei.shtylyov@gmail.com> |
| 14897 | 14905 | L: netdev@vger.kernel.org |
| 14898 | 14906 | L: linux-renesas-soc@vger.kernel.org |
| 14899 | −F: Documentation/devicetree/bindings/net/renesas,*.txt | |
| 14900 | 14907 | F: Documentation/devicetree/bindings/net/renesas,*.yaml |
| 14901 | 14908 | F: drivers/net/ethernet/renesas/ |
| 14902 | 14909 | F: include/linux/sh_eth.h |
| @@ -18097,7 +18104,7 @@ M: Yu Chen <chenyu56@huawei.com> · 3194 unmodified lines | ||
| 18097 | 18104 | M: Binghui Wang <wangbinghui@hisilicon.com> |
| 18098 | 18105 | L: linux-usb@vger.kernel.org |
| 18099 | 18106 | S: Maintained |
| 18100 | −F: Documentation/devicetree/bindings/phy/phy-hi3660-usb3.txt | |
| 18107 | +F: Documentation/devicetree/bindings/phy/hisilicon,hi3660-usb3.yaml | |
| 18101 | 18108 | F: drivers/phy/hisilicon/phy-hi3660-usb3.c |
| 18102 | 18109 | |
| 18103 | 18110 | USB ISP116X DRIVER |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | VERSION = 5 |
| 3 | 3 | PATCHLEVEL = 10 |
| 4 | 4 | SUBLEVEL = 0 |
| 5 | −EXTRAVERSION = -rc2 | |
| 5 | +EXTRAVERSION = -rc3 | |
| 6 | 6 | NAME = Kleptomaniac Octopus |
| 7 | 7 | |
| 8 | 8 | # *DOCUMENTATION* |
| @@ -67,7 +67,22 @@ · 66 unmodified lines | ||
| 67 | 67 | sr r5, [ARC_REG_LPB_CTRL] |
| 68 | 68 | 1: |
| 69 | 69 | #endif /* CONFIG_ARC_LPB_DISABLE */ |
| 70 | −#endif | |
| 70 | + | |
| 71 | + /* On HSDK, CCMs need to remapped super early */ | |
| 72 | +#ifdef CONFIG_ARC_SOC_HSDK | |
| 73 | + mov r6, 0x60000000 | |
| 74 | + lr r5, [ARC_REG_ICCM_BUILD] | |
| 75 | + breq r5, 0, 1f | |
| 76 | + sr r6, [ARC_REG_AUX_ICCM] | |
| 77 | +1: | |
| 78 | + lr r5, [ARC_REG_DCCM_BUILD] | |
| 79 | + breq r5, 0, 2f | |
| 80 | + sr r6, [ARC_REG_AUX_DCCM] | |
| 81 | +2: | |
| 82 | +#endif /* CONFIG_ARC_SOC_HSDK */ | |
| 83 | + | |
| 84 | +#endif /* CONFIG_ISA_ARCV2 */ | |
| 85 | + | |
| 71 | 86 | ; Config DSP_CTRL properly, so kernel may use integer multiply, |
| 72 | 87 | ; multiply-accumulate, and divide operations |
| 73 | 88 | DSP_EARLY_INIT |
| @@ -112,7 +112,7 @@ arc_unwind_core(struct task_struct *tsk, struct pt_regs *regs, · 111 unmodified lines | ||
| 112 | 112 | int (*consumer_fn) (unsigned int, void *), void *arg) |
| 113 | 113 | { |
| 114 | 114 | #ifdef CONFIG_ARC_DW2_UNWIND |
| 115 | − int ret = 0; | |
| 115 | + int ret = 0, cnt = 0; | |
| 116 | 116 | unsigned int address; |
| 117 | 117 | struct unwind_frame_info frame_info; |
| 118 | 118 | |
| @@ -132,6 +132,11 @@ arc_unwind_core(struct task_struct *tsk, struct pt_regs *regs, · 13 unmodified lines | ||
| 132 | 132 | break; |
| 133 | 133 | |
| 134 | 134 | frame_info.regs.r63 = frame_info.regs.r31; |
| 135 | + | |
| 136 | + if (cnt++ > 128) { | |
| 137 | + printk("unwinder looping too long, aborting !\n"); | |
| 138 | + return 0; | |
| 139 | + } | |
| 135 | 140 | } |
| 136 | 141 | |
| 137 | 142 | return address; /* return the last address it saw */ |
| @@ -17,22 +17,6 @@ int arc_hsdk_axi_dmac_coherent __section(".data") = 0; · 16 unmodified lines | ||
| 17 | 17 | |
| 18 | 18 | #define ARC_CCM_UNUSED_ADDR 0x60000000 |
| 19 | 19 | |
| 20 | −static void __init hsdk_init_per_cpu(unsigned int cpu) | |
| 21 | −{ | |
| 22 | − /* | |
| 23 | − * By default ICCM is mapped to 0x7z while this area is used for | |
| 24 | − * kernel virtual mappings, so move it to currently unused area. | |
| 25 | − */ | |
| 26 | − if (cpuinfo_arc700[cpu].iccm.sz) | |
| 27 | − write_aux_reg(ARC_REG_AUX_ICCM, ARC_CCM_UNUSED_ADDR); | |
| 28 | − | |
| 29 | − /* | |
| 30 | − * By default DCCM is mapped to 0x8z while this area is used by kernel, | |
| 31 | − * so move it to currently unused area. | |
| 32 | − */ | |
| 33 | − if (cpuinfo_arc700[cpu].dccm.sz) | |
| 34 | − write_aux_reg(ARC_REG_AUX_DCCM, ARC_CCM_UNUSED_ADDR); | |
| 35 | −} | |
| 36 | 20 | |
| 37 | 21 | #define ARC_PERIPHERAL_BASE 0xf0000000 |
| 38 | 22 | #define CREG_BASE (ARC_PERIPHERAL_BASE + 0x1000) |
| @@ -339,5 +323,4 @@ static const char *hsdk_compat[] __initconst = { · 300 unmodified lines | ||
| 339 | 323 | MACHINE_START(SIMULATION, "hsdk") |
| 340 | 324 | .dt_compat = hsdk_compat, |
| 341 | 325 | .init_early = hsdk_init_early, |
| 342 | − .init_per_cpu = hsdk_init_per_cpu, | |
| 343 | 326 | MACHINE_END |
| @@ -354,8 +354,8 @@ static void __init free_highpages(void) · 353 unmodified lines | ||
| 354 | 354 | /* set highmem page free */ |
| 355 | 355 | for_each_free_mem_range(i, NUMA_NO_NODE, MEMBLOCK_NONE, |
| 356 | 356 | &range_start, &range_end, NULL) { |
| 357 | − unsigned long start = PHYS_PFN(range_start); | |
| 358 | − unsigned long end = PHYS_PFN(range_end); | |
| 357 | + unsigned long start = PFN_UP(range_start); | |
| 358 | + unsigned long end = PFN_DOWN(range_end); | |
| 359 | 359 | |
| 360 | 360 | /* Ignore complete lowmem entries */ |
| 361 | 361 | if (end <= max_low) |
| @@ -1002,7 +1002,7 @@ config NUMA · 1001 unmodified lines | ||
| 1002 | 1002 | config NODES_SHIFT |
| 1003 | 1003 | int "Maximum NUMA Nodes (as a power of 2)" |
| 1004 | 1004 | range 1 10 |
| 1005 | − default "2" | |
| 1005 | + default "4" | |
| 1006 | 1006 | depends on NEED_MULTIPLE_NODES |
| 1007 | 1007 | help |
| 1008 | 1008 | Specify the maximum number of NUMA Nodes available on the target |
| @@ -10,6 +10,7 @@ · 9 unmodified lines | ||
| 10 | 10 | * #imm16 values used for BRK instruction generation |
| 11 | 11 | * 0x004: for installing kprobes |
| 12 | 12 | * 0x005: for installing uprobes |
| 13 | + * 0x006: for kprobe software single-step | |
| 13 | 14 | * Allowed values for kgdb are 0x400 - 0x7ff |
| 14 | 15 | * 0x100: for triggering a fault on purpose (reserved) |
| 15 | 16 | * 0x400: for dynamic BRK instruction |
| @@ -19,6 +20,7 @@ · 3 unmodified lines | ||
| 19 | 20 | */ |
| 20 | 21 | #define KPROBES_BRK_IMM 0x004 |
| 21 | 22 | #define UPROBES_BRK_IMM 0x005 |
| 23 | +#define KPROBES_BRK_SS_IMM 0x006 | |
| 22 | 24 | #define FAULT_BRK_IMM 0x100 |
| 23 | 25 | #define KGDB_DYN_DBG_BRK_IMM 0x400 |
| 24 | 26 | #define KGDB_COMPILED_DBG_BRK_IMM 0x401 |
| @@ -53,6 +53,7 @@ · 52 unmodified lines | ||
| 53 | 53 | |
| 54 | 54 | /* kprobes BRK opcodes with ESR encoding */ |
| 55 | 55 | #define BRK64_OPCODE_KPROBES (AARCH64_BREAK_MON | (KPROBES_BRK_IMM << 5)) |
| 56 | +#define BRK64_OPCODE_KPROBES_SS (AARCH64_BREAK_MON | (KPROBES_BRK_SS_IMM << 5)) | |
| 56 | 57 | /* uprobes BRK opcodes with ESR encoding */ |
| 57 | 58 | #define BRK64_OPCODE_UPROBES (AARCH64_BREAK_MON | (UPROBES_BRK_IMM << 5)) |
| 58 | 59 | |
| @@ -16,7 +16,7 @@ · 15 unmodified lines | ||
| 16 | 16 | #include <linux/percpu.h> |
| 17 | 17 | |
| 18 | 18 | #define __ARCH_WANT_KPROBES_INSN_SLOT |
| 19 | −#define MAX_INSN_SIZE 1 | |
| 19 | +#define MAX_INSN_SIZE 2 | |
| 20 | 20 | |
| 21 | 21 | #define flush_insn_slot(p) do { } while (0) |
| 22 | 22 | #define kretprobe_blacklist_size 0 |
| @@ -43,7 +43,7 @@ static void *image_load(struct kimage *image, · 42 unmodified lines | ||
| 43 | 43 | u64 flags, value; |
| 44 | 44 | bool be_image, be_kernel; |
| 45 | 45 | struct kexec_buf kbuf; |
| 46 | − unsigned long text_offset; | |
| 46 | + unsigned long text_offset, kernel_segment_number; | |
| 47 | 47 | struct kexec_segment *kernel_segment; |
| 48 | 48 | int ret; |
| 49 | 49 | |
| @@ -88,11 +88,37 @@ static void *image_load(struct kimage *image, · 38 unmodified lines | ||
| 88 | 88 | /* Adjust kernel segment with TEXT_OFFSET */ |
| 89 | 89 | kbuf.memsz += text_offset; |
| 90 | 90 | |
| 91 | − ret = kexec_add_buffer(&kbuf); | |
| 92 | − if (ret) | |
| 91 | + kernel_segment_number = image->nr_segments; | |
| 92 | + | |
| 93 | + /* | |
| 94 | + * The location of the kernel segment may make it impossible to satisfy | |
| 95 | + * the other segment requirements, so we try repeatedly to find a | |
| 96 | + * location that will work. | |
| 97 | + */ | |
| 98 | + while ((ret = kexec_add_buffer(&kbuf)) == 0) { | |
| 99 | + /* Try to load additional data */ | |
| 100 | + kernel_segment = &image->segment[kernel_segment_number]; | |
| 101 | + ret = load_other_segments(image, kernel_segment->mem, | |
| 102 | + kernel_segment->memsz, initrd, | |
| 103 | + initrd_len, cmdline); | |
| 104 | + if (!ret) | |
| 105 | + break; | |
| 106 | + | |
| 107 | + /* | |
| 108 | + * We couldn't find space for the other segments; erase the | |
| 109 | + * kernel segment and try the next available hole. | |
| 110 | + */ | |
| 111 | + image->nr_segments -= 1; | |
| 112 | + kbuf.buf_min = kernel_segment->mem + kernel_segment->memsz; | |
| 113 | + kbuf.mem = KEXEC_BUF_MEM_UNKNOWN; | |
| 114 | + } | |
| 115 | + | |
| 116 | + if (ret) { | |
| 117 | + pr_err("Could not find any suitable kernel location!"); | |
| 93 | 118 | return ERR_PTR(ret); |
| 119 | + } | |
| 94 | 120 | |
| 95 | − kernel_segment = &image->segment[image->nr_segments - 1]; | |
| 121 | + kernel_segment = &image->segment[kernel_segment_number]; | |
| 96 | 122 | kernel_segment->mem += text_offset; |
| 97 | 123 | kernel_segment->memsz -= text_offset; |
| 98 | 124 | image->start = kernel_segment->mem; |
| @@ -101,12 +127,7 @@ static void *image_load(struct kimage *image, · 2 unmodified lines | ||
| 101 | 127 | kernel_segment->mem, kbuf.bufsz, |
| 102 | 128 | kernel_segment->memsz); |
| 103 | 129 | |
| 104 | − /* Load additional data */ | |
| 105 | − ret = load_other_segments(image, | |
| 106 | − kernel_segment->mem, kernel_segment->memsz, | |
| 107 | − initrd, initrd_len, cmdline); | |
| 108 | − | |
| 109 | − return ERR_PTR(ret); | |
| 130 | + return 0; | |
| 110 | 131 | } |
| 111 | 132 | |
| 112 | 133 | #ifdef CONFIG_KEXEC_IMAGE_VERIFY_SIG |
| @@ -240,6 +240,11 @@ static int prepare_elf_headers(void **addr, unsigned long *sz) · 239 unmodified lines | ||
| 240 | 240 | return ret; |
| 241 | 241 | } |
| 242 | 242 | |
| 243 | +/* | |
| 244 | + * Tries to add the initrd and DTB to the image. If it is not possible to find | |
| 245 | + * valid locations, this function will undo changes to the image and return non | |
| 246 | + * zero. | |
| 247 | + */ | |
| 243 | 248 | int load_other_segments(struct kimage *image, |
| 244 | 249 | unsigned long kernel_load_addr, |
| 245 | 250 | unsigned long kernel_size, |
| @@ -248,7 +253,8 @@ int load_other_segments(struct kimage *image, · 2 unmodified lines | ||
| 248 | 253 | { |
| 249 | 254 | struct kexec_buf kbuf; |
| 250 | 255 | void *headers, *dtb = NULL; |
| 251 | − unsigned long headers_sz, initrd_load_addr = 0, dtb_len; | |
| 256 | + unsigned long headers_sz, initrd_load_addr = 0, dtb_len, | |
| 257 | + orig_segments = image->nr_segments; | |
| 252 | 258 | int ret = 0; |
| 253 | 259 | |
| 254 | 260 | kbuf.image = image; |
| @@ -334,6 +340,7 @@ int load_other_segments(struct kimage *image, · 79 unmodified lines | ||
| 334 | 340 | return 0; |
| 335 | 341 | |
| 336 | 342 | out_err: |
| 343 | + image->nr_segments = orig_segments; | |
| 337 | 344 | vfree(dtb); |
| 338 | 345 | return ret; |
| 339 | 346 | } |
| @@ -36,25 +36,16 @@ DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); · 35 unmodified lines | ||
| 36 | 36 | static void __kprobes |
| 37 | 37 | post_kprobe_handler(struct kprobe_ctlblk *, struct pt_regs *); |
| 38 | 38 | |
| 39 | −static int __kprobes patch_text(kprobe_opcode_t *addr, u32 opcode) | |
| 40 | −{ | |
| 41 | − void *addrs[1]; | |
| 42 | − u32 insns[1]; | |
| 43 | − | |
| 44 | − addrs[0] = addr; | |
| 45 | − insns[0] = opcode; | |
| 46 | − | |
| 47 | − return aarch64_insn_patch_text(addrs, insns, 1); | |
| 48 | −} | |
| 49 | − | |
| 50 | 39 | static void __kprobes arch_prepare_ss_slot(struct kprobe *p) |
| 51 | 40 | { |
| 41 | + kprobe_opcode_t *addr = p->ainsn.api.insn; | |
| 42 | + void *addrs[] = {addr, addr + 1}; | |
| 43 | + u32 insns[] = {p->opcode, BRK64_OPCODE_KPROBES_SS}; | |
| 44 | + | |
| 52 | 45 | /* prepare insn slot */ |
| 53 | − patch_text(p->ainsn.api.insn, p->opcode); | |
| 46 | + aarch64_insn_patch_text(addrs, insns, 2); | |
| 54 | 47 | |
| 55 | − flush_icache_range((uintptr_t) (p->ainsn.api.insn), | |
| 56 | − (uintptr_t) (p->ainsn.api.insn) + | |
| 57 | − MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); | |
| 48 | + flush_icache_range((uintptr_t)addr, (uintptr_t)(addr + MAX_INSN_SIZE)); | |
| 58 | 49 | |
| 59 | 50 | /* |
| 60 | 51 | * Needs restoring of return address after stepping xol. |
| @@ -128,13 +119,18 @@ void *alloc_insn_page(void) · 67 unmodified lines | ||
| 128 | 119 | /* arm kprobe: install breakpoint in text */ |
| 129 | 120 | void __kprobes arch_arm_kprobe(struct kprobe *p) |
| 130 | 121 | { |
| 131 | − patch_text(p->addr, BRK64_OPCODE_KPROBES); | |
| 122 | + void *addr = p->addr; | |
| 123 | + u32 insn = BRK64_OPCODE_KPROBES; | |
| 124 | + | |
| 125 | + aarch64_insn_patch_text(&addr, &insn, 1); | |
| 132 | 126 | } |
| 133 | 127 | |
| 134 | 128 | /* disarm kprobe: remove breakpoint from text */ |
| 135 | 129 | void __kprobes arch_disarm_kprobe(struct kprobe *p) |
| 136 | 130 | { |
| 137 | − patch_text(p->addr, p->opcode); | |
| 131 | + void *addr = p->addr; | |
| 132 | + | |
| 133 | + aarch64_insn_patch_text(&addr, &p->opcode, 1); | |
| 138 | 134 | } |
| 139 | 135 | |
| 140 | 136 | void __kprobes arch_remove_kprobe(struct kprobe *p) |
| @@ -163,20 +159,15 @@ static void __kprobes set_current_kprobe(struct kprobe *p) · 22 unmodified lines | ||
| 163 | 159 | } |
| 164 | 160 | |
| 165 | 161 | /* |
| 166 | − * Interrupts need to be disabled before single-step mode is set, and not | |
| 167 | − * reenabled until after single-step mode ends. | |
| 168 | − * Without disabling interrupt on local CPU, there is a chance of | |
| 169 | − * interrupt occurrence in the period of exception return and start of | |
| 170 | − * out-of-line single-step, that result in wrongly single stepping | |
| 171 | − * into the interrupt handler. | |
| 162 | + * Mask all of DAIF while executing the instruction out-of-line, to keep things | |
| 163 | + * simple and avoid nesting exceptions. Interrupts do have to be disabled since | |
| 164 | + * the kprobe state is per-CPU and doesn't get migrated. | |
| 172 | 165 | */ |
| 173 | 166 | static void __kprobes kprobes_save_local_irqflag(struct kprobe_ctlblk *kcb, |
| 174 | 167 | struct pt_regs *regs) |
| 175 | 168 | { |
| 176 | 169 | kcb->saved_irqflag = regs->pstate & DAIF_MASK; |
| 177 | − regs->pstate |= PSR_I_BIT; | |
| 178 | − /* Unmask PSTATE.D for enabling software step exceptions. */ | |
| 179 | − regs->pstate &= ~PSR_D_BIT; | |
| 170 | + regs->pstate |= DAIF_MASK; | |
| 180 | 171 | } |
| 181 | 172 | |
| 182 | 173 | static void __kprobes kprobes_restore_local_irqflag(struct kprobe_ctlblk *kcb, |
| @@ -219,10 +210,7 @@ static void __kprobes setup_singlestep(struct kprobe *p, · 36 unmodified lines | ||
| 219 | 210 | slot = (unsigned long)p->ainsn.api.insn; |
| 220 | 211 | |
| 221 | 212 | set_ss_context(kcb, slot); /* mark pending ss */ |
| 222 | − | |
| 223 | − /* IRQs and single stepping do not mix well. */ | |
| 224 | 213 | kprobes_save_local_irqflag(kcb, regs); |
| 225 | − kernel_enable_single_step(regs); | |
| 226 | 214 | instruction_pointer_set(regs, slot); |
| 227 | 215 | } else { |
| 228 | 216 | /* insn simulation */ |
| @@ -273,12 +261,8 @@ post_kprobe_handler(struct kprobe_ctlblk *kcb, struct pt_regs *regs) · 44 unmodified lines | ||
| 273 | 261 | } |
| 274 | 262 | /* call post handler */ |
| 275 | 263 | kcb->kprobe_status = KPROBE_HIT_SSDONE; |
| 276 | − if (cur->post_handler) { | |
| 277 | − /* post_handler can hit breakpoint and single step | |
| 278 | − * again, so we enable D-flag for recursive exception. | |
| 279 | − */ | |
| 264 | + if (cur->post_handler) | |
| 280 | 265 | cur->post_handler(cur, regs, 0); |
| 281 | − } | |
| 282 | 266 | |
| 283 | 267 | reset_current_kprobe(); |
| 284 | 268 | } |
| @@ -302,8 +286,6 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr) · 17 unmodified lines | ||
| 302 | 286 | if (!instruction_pointer(regs)) |
| 303 | 287 | BUG(); |
| 304 | 288 | |
| 305 | − kernel_disable_single_step(); | |
| 306 | − | |
| 307 | 289 | if (kcb->kprobe_status == KPROBE_REENTER) |
| 308 | 290 | restore_previous_kprobe(kcb); |
| 309 | 291 | else |
| @@ -365,10 +347,6 @@ static void __kprobes kprobe_handler(struct pt_regs *regs) · 55 unmodified lines | ||
| 365 | 347 | * pre-handler and it returned non-zero, it will |
| 366 | 348 | * modify the execution path and no need to single |
| 367 | 349 | * stepping. Let's just reset current kprobe and exit. |
| 368 | − * | |
| 369 | − * pre_handler can hit a breakpoint and can step thru | |
| 370 | − * before return, keep PSTATE D-flag enabled until | |
| 371 | − * pre_handler return back. | |
| 372 | 350 | */ |
| 373 | 351 | if (!p->pre_handler || !p->pre_handler(p, regs)) { |
| 374 | 352 | setup_singlestep(p, regs, kcb, 0); |
| @@ -399,7 +377,7 @@ kprobe_ss_hit(struct kprobe_ctlblk *kcb, unsigned long addr) · 24 unmodified lines | ||
| 399 | 377 | } |
| 400 | 378 | |
| 401 | 379 | static int __kprobes |
| 402 | −kprobe_single_step_handler(struct pt_regs *regs, unsigned int esr) | |
| 380 | +kprobe_breakpoint_ss_handler(struct pt_regs *regs, unsigned int esr) | |
| 403 | 381 | { |
| 404 | 382 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
| 405 | 383 | int retval; |
| @@ -409,16 +387,15 @@ kprobe_single_step_handler(struct pt_regs *regs, unsigned int esr) · 3 unmodified lines | ||
| 409 | 387 | |
| 410 | 388 | if (retval == DBG_HOOK_HANDLED) { |
| 411 | 389 | kprobes_restore_local_irqflag(kcb, regs); |
| 412 | − kernel_disable_single_step(); | |
| 413 | − | |
| 414 | 390 | post_kprobe_handler(kcb, regs); |
| 415 | 391 | } |
| 416 | 392 | |
| 417 | 393 | return retval; |
| 418 | 394 | } |
| 419 | 395 | |
| 420 | −static struct step_hook kprobes_step_hook = { | |
| 421 | − .fn = kprobe_single_step_handler, | |
| 396 | +static struct break_hook kprobes_break_ss_hook = { | |
| 397 | + .imm = KPROBES_BRK_SS_IMM, | |
| 398 | + .fn = kprobe_breakpoint_ss_handler, | |
| 422 | 399 | }; |
| 423 | 400 | |
| 424 | 401 | static int __kprobes |
| @@ -486,7 +463,7 @@ int __kprobes arch_trampoline_kprobe(struct kprobe *p) · 61 unmodified lines | ||
| 486 | 463 | int __init arch_init_kprobes(void) |
| 487 | 464 | { |
| 488 | 465 | register_kernel_break_hook(&kprobes_break_hook); |
| 489 | − register_kernel_step_hook(&kprobes_step_hook); | |
| 466 | + register_kernel_break_hook(&kprobes_break_ss_hook); | |
| 490 | 467 | |
| 491 | 468 | return 0; |
| 492 | 469 | } |
| @@ -63,7 +63,7 @@ static inline void restore_user_access(unsigned long flags) · 62 unmodified lines | ||
| 63 | 63 | static inline bool |
| 64 | 64 | bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write) |
| 65 | 65 | { |
| 66 | − return WARN(!((regs->kuap ^ MD_APG_KUAP) & 0xf0000000), | |
| 66 | + return WARN(!((regs->kuap ^ MD_APG_KUAP) & 0xff000000), | |
| 67 | 67 | "Bug: fault blocked by AP register !"); |
| 68 | 68 | } |
| 69 | 69 | |
| @@ -33,19 +33,18 @@ · 32 unmodified lines | ||
| 33 | 33 | * respectively NA for All or X for Supervisor and no access for User. |
| 34 | 34 | * Then we use the APG to say whether accesses are according to Page rules or |
| 35 | 35 | * "all Supervisor" rules (Access to all) |
| 36 | − * Therefore, we define 2 APG groups. lsb is _PMD_USER | |
| 37 | − * 0 => Kernel => 01 (all accesses performed according to page definition) | |
| 38 | − * 1 => User => 00 (all accesses performed as supervisor iaw page definition) | |
| 39 | − * 2-15 => Not Used | |
| 40 | − */ | |
| 41 | −#define MI_APG_INIT 0x40000000 | |
| 42 | − | |
| 43 | −/* | |
| 44 | − * 0 => Kernel => 01 (all accesses performed according to page definition) | |
| 45 | − * 1 => User => 10 (all accesses performed according to swaped page definition) | |
| 46 | − * 2-15 => Not Used | |
| 47 | − */ | |
| 48 | −#define MI_APG_KUEP 0x60000000 | |
| 36 | + * _PAGE_ACCESSED is also managed via APG. When _PAGE_ACCESSED is not set, say | |
| 37 | + * "all User" rules, that will lead to NA for all. | |
| 38 | + * Therefore, we define 4 APG groups. lsb is _PAGE_ACCESSED | |
| 39 | + * 0 => Kernel => 11 (all accesses performed according as user iaw page definition) | |
| 40 | + * 1 => Kernel+Accessed => 01 (all accesses performed according to page definition) | |
| 41 | + * 2 => User => 11 (all accesses performed according as user iaw page definition) | |
| 42 | + * 3 => User+Accessed => 00 (all accesses performed as supervisor iaw page definition) for INIT | |
| 43 | + * => 10 (all accesses performed according to swaped page definition) for KUEP | |
| 44 | + * 4-15 => Not Used | |
| 45 | + */ | |
| 46 | +#define MI_APG_INIT 0xdc000000 | |
| 47 | +#define MI_APG_KUEP 0xde000000 | |
| 49 | 48 | |
| 50 | 49 | /* The effective page number register. When read, contains the information |
| 51 | 50 | * about the last instruction TLB miss. When MI_RPN is written, bits in |
| @@ -106,25 +105,9 @@ · 54 unmodified lines | ||
| 106 | 105 | #define MD_Ks 0x80000000 /* Should not be set */ |
| 107 | 106 | #define MD_Kp 0x40000000 /* Should always be set */ |
| 108 | 107 | |
| 109 | −/* | |
| 110 | − * All pages' PP data bits are set to either 000 or 011 or 001, which means | |
| 111 | − * respectively RW for Supervisor and no access for User, or RO for | |
| 112 | − * Supervisor and no access for user and NA for ALL. | |
| 113 | − * Then we use the APG to say whether accesses are according to Page rules or | |
| 114 | − * "all Supervisor" rules (Access to all) | |
| 115 | − * Therefore, we define 2 APG groups. lsb is _PMD_USER | |
| 116 | − * 0 => Kernel => 01 (all accesses performed according to page definition) | |
| 117 | − * 1 => User => 00 (all accesses performed as supervisor iaw page definition) | |
| 118 | − * 2-15 => Not Used | |
| 119 | − */ | |
| 120 | −#define MD_APG_INIT 0x40000000 | |
| 121 | − | |
| 122 | −/* | |
| 123 | − * 0 => No user => 01 (all accesses performed according to page definition) | |
| 124 | − * 1 => User => 10 (all accesses performed according to swaped page definition) | |
| 125 | − * 2-15 => Not Used | |
| 126 | − */ | |
| 127 | −#define MD_APG_KUAP 0x60000000 | |
| 108 | +/* See explanation above at the definition of MI_APG_INIT */ | |
| 109 | +#define MD_APG_INIT 0xdc000000 | |
| 110 | +#define MD_APG_KUAP 0xde000000 | |
| 128 | 111 | |
| 129 | 112 | /* The effective page number register. When read, contains the information |
| 130 | 113 | * about the last instruction TLB miss. When MD_RPN is written, bits in |
| @@ -39,9 +39,9 @@ · 38 unmodified lines | ||
| 39 | 39 | * into the TLB. |
| 40 | 40 | */ |
| 41 | 41 | #define _PAGE_GUARDED 0x0010 /* Copied to L1 G entry in DTLB */ |
| 42 | −#define _PAGE_SPECIAL 0x0020 /* SW entry */ | |
| 42 | +#define _PAGE_ACCESSED 0x0020 /* Copied to L1 APG 1 entry in I/DTLB */ | |
| 43 | 43 | #define _PAGE_EXEC 0x0040 /* Copied to PP (bit 21) in ITLB */ |
| 44 | −#define _PAGE_ACCESSED 0x0080 /* software: page referenced */ | |
| 44 | +#define _PAGE_SPECIAL 0x0080 /* SW entry */ | |
| 45 | 45 | |
| 46 | 46 | #define _PAGE_NA 0x0200 /* Supervisor NA, User no access */ |
| 47 | 47 | #define _PAGE_RO 0x0600 /* Supervisor RO, User no access */ |
| @@ -59,11 +59,12 @@ · 11 unmodified lines | ||
| 59 | 59 | |
| 60 | 60 | #define _PMD_PRESENT 0x0001 |
| 61 | 61 | #define _PMD_PRESENT_MASK _PMD_PRESENT |
| 62 | −#define _PMD_BAD 0x0fd0 | |
| 62 | +#define _PMD_BAD 0x0f90 | |
| 63 | 63 | #define _PMD_PAGE_MASK 0x000c |
| 64 | 64 | #define _PMD_PAGE_8M 0x000c |
| 65 | 65 | #define _PMD_PAGE_512K 0x0004 |
| 66 | −#define _PMD_USER 0x0020 /* APG 1 */ | |
| 66 | +#define _PMD_ACCESSED 0x0020 /* APG 1 */ | |
| 67 | +#define _PMD_USER 0x0040 /* APG 2 */ | |
| 67 | 68 | |
| 68 | 69 | #define _PTE_NONE_MASK 0 |
| 69 | 70 | |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | |
| 7 | 7 | struct device; |
| 8 | 8 | struct device_node; |
| 9 | +struct drmem_lmb; | |
| 9 | 10 | |
| 10 | 11 | #ifdef CONFIG_NUMA |
| 11 | 12 | |
| @@ -61,6 +62,9 @@ static inline int early_cpu_to_node(int cpu) · 49 unmodified lines | ||
| 61 | 62 | */ |
| 62 | 63 | return (nid < 0) ? 0 : nid; |
| 63 | 64 | } |
| 65 | + | |
| 66 | +int of_drconf_to_nid_single(struct drmem_lmb *lmb); | |
| 67 | + | |
| 64 | 68 | #else |
| 65 | 69 | |
| 66 | 70 | static inline int early_cpu_to_node(int cpu) { return 0; } |
| @@ -84,10 +88,12 @@ static inline int cpu_distance(__be32 *cpu1_assoc, __be32 *cpu2_assoc) · 17 unmodified lines | ||
| 84 | 88 | return 0; |
| 85 | 89 | } |
| 86 | 90 | |
| 87 | −#endif /* CONFIG_NUMA */ | |
| 91 | +static inline int of_drconf_to_nid_single(struct drmem_lmb *lmb) | |
| 92 | +{ | |
| 93 | + return first_online_node; | |
| 94 | +} | |
| 88 | 95 | |
| 89 | −struct drmem_lmb; | |
| 90 | −int of_drconf_to_nid_single(struct drmem_lmb *lmb); | |
| 96 | +#endif /* CONFIG_NUMA */ | |
| 91 | 97 | |
| 92 | 98 | #if defined(CONFIG_NUMA) && defined(CONFIG_PPC_SPLPAR) |
| 93 | 99 | extern int find_and_online_cpu_nid(int cpu); |
| @@ -178,7 +178,7 @@ do { \ · 177 unmodified lines | ||
| 178 | 178 | * are no aliasing issues. |
| 179 | 179 | */ |
| 180 | 180 | #define __put_user_asm_goto(x, addr, label, op) \ |
| 181 | − asm volatile goto( \ | |
| 181 | + asm_volatile_goto( \ | |
| 182 | 182 | "1: " op "%U1%X1 %0,%1 # put_user\n" \ |
| 183 | 183 | EX_TABLE(1b, %l2) \ |
| 184 | 184 | : \ |
| @@ -191,7 +191,7 @@ do { \ · 6 unmodified lines | ||
| 191 | 191 | __put_user_asm_goto(x, ptr, label, "std") |
| 192 | 192 | #else /* __powerpc64__ */ |
| 193 | 193 | #define __put_user_asm2_goto(x, addr, label) \ |
| 194 | − asm volatile goto( \ | |
| 194 | + asm_volatile_goto( \ | |
| 195 | 195 | "1: stw%X1 %0, %1\n" \ |
| 196 | 196 | "2: stw%X1 %L0, %L1\n" \ |
| 197 | 197 | EX_TABLE(1b, %l2) \ |
| @@ -264,8 +264,9 @@ static int eeh_addr_cache_show(struct seq_file *s, void *v) · 263 unmodified lines | ||
| 264 | 264 | { |
| 265 | 265 | struct pci_io_addr_range *piar; |
| 266 | 266 | struct rb_node *n; |
| 267 | + unsigned long flags; | |
| 267 | 268 | |
| 268 | − spin_lock(&pci_io_addr_cache_root.piar_lock); | |
| 269 | + spin_lock_irqsave(&pci_io_addr_cache_root.piar_lock, flags); | |
| 269 | 270 | for (n = rb_first(&pci_io_addr_cache_root.rb_root); n; n = rb_next(n)) { |
| 270 | 271 | piar = rb_entry(n, struct pci_io_addr_range, rb_node); |
| 271 | 272 | |
| @@ -273,7 +274,7 @@ static int eeh_addr_cache_show(struct seq_file *s, void *v) · 1 unmodified line | ||
| 273 | 274 | (piar->flags & IORESOURCE_IO) ? "i/o" : "mem", |
| 274 | 275 | &piar->addr_lo, &piar->addr_hi, pci_name(piar->pcidev)); |
| 275 | 276 | } |
| 276 | − spin_unlock(&pci_io_addr_cache_root.piar_lock); | |
| 277 | + spin_unlock_irqrestore(&pci_io_addr_cache_root.piar_lock, flags); | |
| 277 | 278 | |
| 278 | 279 | return 0; |
| 279 | 280 | } |
| @@ -284,11 +284,7 @@ _ENTRY(saved_ksp_limit) · 283 unmodified lines | ||
| 284 | 284 | |
| 285 | 285 | rlwimi r11, r10, 22, 20, 29 /* Compute PTE address */ |
| 286 | 286 | lwz r11, 0(r11) /* Get Linux PTE */ |
| 287 | −#ifdef CONFIG_SWAP | |
| 288 | 287 | li r9, _PAGE_PRESENT | _PAGE_ACCESSED |
| 289 | −#else | |
| 290 | − li r9, _PAGE_PRESENT | |
| 291 | −#endif | |
| 292 | 288 | andc. r9, r9, r11 /* Check permission */ |
| 293 | 289 | bne 5f |
| 294 | 290 | |
| @@ -369,11 +365,7 @@ _ENTRY(saved_ksp_limit) · 74 unmodified lines | ||
| 369 | 365 | |
| 370 | 366 | rlwimi r11, r10, 22, 20, 29 /* Compute PTE address */ |
| 371 | 367 | lwz r11, 0(r11) /* Get Linux PTE */ |
| 372 | −#ifdef CONFIG_SWAP | |
| 373 | 368 | li r9, _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC |
| 374 | −#else | |
| 375 | − li r9, _PAGE_PRESENT | _PAGE_EXEC | |
| 376 | −#endif | |
| 377 | 369 | andc. r9, r9, r11 /* Check permission */ |
| 378 | 370 | bne 5f |
| 379 | 371 | |
| @@ -202,9 +202,7 @@ SystemCall: · 201 unmodified lines | ||
| 202 | 202 | |
| 203 | 203 | InstructionTLBMiss: |
| 204 | 204 | mtspr SPRN_SPRG_SCRATCH0, r10 |
| 205 | −#if defined(ITLB_MISS_KERNEL) || defined(CONFIG_SWAP) || defined(CONFIG_HUGETLBFS) | |
| 206 | 205 | mtspr SPRN_SPRG_SCRATCH1, r11 |
| 207 | −#endif | |
| 208 | 206 | |
| 209 | 207 | /* If we are faulting a kernel address, we have to use the |
| 210 | 208 | * kernel page tables. |
| @@ -224,25 +222,13 @@ InstructionTLBMiss: · 13 unmodified lines | ||
| 224 | 222 | 3: |
| 225 | 223 | mtcr r11 |
| 226 | 224 | #endif |
| 227 | −#if defined(CONFIG_HUGETLBFS) || !defined(CONFIG_PIN_TLB_TEXT) | |
| 228 | 225 | lwz r11, (swapper_pg_dir-PAGE_OFFSET)@l(r10) /* Get level 1 entry */ |
| 229 | 226 | mtspr SPRN_MD_TWC, r11 |
| 230 | −#else | |
| 231 | − lwz r10, (swapper_pg_dir-PAGE_OFFSET)@l(r10) /* Get level 1 entry */ | |
| 232 | − mtspr SPRN_MI_TWC, r10 /* Set segment attributes */ | |
| 233 | − mtspr SPRN_MD_TWC, r10 | |
| 234 | −#endif | |
| 235 | 227 | mfspr r10, SPRN_MD_TWC |
| 236 | 228 | lwz r10, 0(r10) /* Get the pte */ |
| 237 | −#if defined(CONFIG_HUGETLBFS) || !defined(CONFIG_PIN_TLB_TEXT) | |
| 229 | + rlwimi r11, r10, 0, _PAGE_GUARDED | _PAGE_ACCESSED | |
| 238 | 230 | rlwimi r11, r10, 32 - 9, _PMD_PAGE_512K |
| 239 | 231 | mtspr SPRN_MI_TWC, r11 |
| 240 | −#endif | |
| 241 | −#ifdef CONFIG_SWAP | |
| 242 | − rlwinm r11, r10, 32-5, _PAGE_PRESENT | |
| 243 | − and r11, r11, r10 | |
| 244 | − rlwimi r10, r11, 0, _PAGE_PRESENT | |
| 245 | −#endif | |
| 246 | 232 | /* The Linux PTE won't go exactly into the MMU TLB. |
| 247 | 233 | * Software indicator bits 20 and 23 must be clear. |
| 248 | 234 | * Software indicator bits 22, 24, 25, 26, and 27 must be |
| @@ -256,9 +242,7 @@ InstructionTLBMiss: · 7 unmodified lines | ||
| 256 | 242 | |
| 257 | 243 | /* Restore registers */ |
| 258 | 244 | 0: mfspr r10, SPRN_SPRG_SCRATCH0 |
| 259 | −#if defined(ITLB_MISS_KERNEL) || defined(CONFIG_SWAP) || defined(CONFIG_HUGETLBFS) | |
| 260 | 245 | mfspr r11, SPRN_SPRG_SCRATCH1 |
| 261 | −#endif | |
| 262 | 246 | rfi |
| 263 | 247 | patch_site 0b, patch__itlbmiss_exit_1 |
| 264 | 248 | |
| @@ -268,9 +252,7 @@ InstructionTLBMiss: · 3 unmodified lines | ||
| 268 | 252 | addi r10, r10, 1 |
| 269 | 253 | stw r10, (itlb_miss_counter - PAGE_OFFSET)@l(0) |
| 270 | 254 | mfspr r10, SPRN_SPRG_SCRATCH0 |
| 271 | −#if defined(ITLB_MISS_KERNEL) || defined(CONFIG_SWAP) | |
| 272 | 255 | mfspr r11, SPRN_SPRG_SCRATCH1 |
| 273 | −#endif | |
| 274 | 256 | rfi |
| 275 | 257 | #endif |
| 276 | 258 | |
| @@ -297,30 +279,16 @@ DataStoreTLBMiss: · 20 unmodified lines | ||
| 297 | 279 | mfspr r10, SPRN_MD_TWC |
| 298 | 280 | lwz r10, 0(r10) /* Get the pte */ |
| 299 | 281 | |
| 300 | − /* Insert the Guarded flag into the TWC from the Linux PTE. | |
| 282 | + /* Insert Guarded and Accessed flags into the TWC from the Linux PTE. | |
| 301 | 283 | * It is bit 27 of both the Linux PTE and the TWC (at least |
| 302 | 284 | * I got that right :-). It will be better when we can put |
| 303 | 285 | * this into the Linux pgd/pmd and load it in the operation |
| 304 | 286 | * above. |
| 305 | 287 | */ |
| 306 | − rlwimi r11, r10, 0, _PAGE_GUARDED | |
| 288 | + rlwimi r11, r10, 0, _PAGE_GUARDED | _PAGE_ACCESSED | |
| 307 | 289 | rlwimi r11, r10, 32 - 9, _PMD_PAGE_512K |
| 308 | 290 | mtspr SPRN_MD_TWC, r11 |
| 309 | 291 | |
| 310 | − /* Both _PAGE_ACCESSED and _PAGE_PRESENT has to be set. | |
| 311 | − * We also need to know if the insn is a load/store, so: | |
| 312 | − * Clear _PAGE_PRESENT and load that which will | |
| 313 | − * trap into DTLB Error with store bit set accordinly. | |
| 314 | − */ | |
| 315 | − /* PRESENT=0x1, ACCESSED=0x20 | |
| 316 | − * r11 = ((r10 & PRESENT) & ((r10 & ACCESSED) >> 5)); | |
| 317 | − * r10 = (r10 & ~PRESENT) | r11; | |
| 318 | − */ | |
| 319 | −#ifdef CONFIG_SWAP | |
| 320 | − rlwinm r11, r10, 32-5, _PAGE_PRESENT | |
| 321 | − and r11, r11, r10 | |
| 322 | − rlwimi r10, r11, 0, _PAGE_PRESENT | |
| 323 | −#endif | |
| 324 | 292 | /* The Linux PTE won't go exactly into the MMU TLB. |
| 325 | 293 | * Software indicator bits 24, 25, 26, and 27 must be |
| 326 | 294 | * set. All other Linux PTE bits control the behavior |
| @@ -711,7 +679,7 @@ initial_mmu: · 384 unmodified lines | ||
| 711 | 679 | li r9, 4 /* up to 4 pages of 8M */ |
| 712 | 680 | mtctr r9 |
| 713 | 681 | lis r9, KERNELBASE@h /* Create vaddr for TLB */ |
| 714 | − li r10, MI_PS8MEG | MI_SVALID /* Set 8M byte page */ | |
| 682 | + li r10, MI_PS8MEG | _PMD_ACCESSED | MI_SVALID | |
| 715 | 683 | li r11, MI_BOOTINIT /* Create RPN for address 0 */ |
| 716 | 684 | 1: |
| 717 | 685 | mtspr SPRN_MI_CTR, r8 /* Set instruction MMU control */ |
| @@ -775,7 +743,7 @@ _GLOBAL(mmu_pin_tlb) · 57 unmodified lines | ||
| 775 | 743 | #ifdef CONFIG_PIN_TLB_TEXT |
| 776 | 744 | LOAD_REG_IMMEDIATE(r5, 28 << 8) |
| 777 | 745 | LOAD_REG_IMMEDIATE(r6, PAGE_OFFSET) |
| 778 | − LOAD_REG_IMMEDIATE(r7, MI_SVALID | MI_PS8MEG) | |
| 746 | + LOAD_REG_IMMEDIATE(r7, MI_SVALID | MI_PS8MEG | _PMD_ACCESSED) | |
| 779 | 747 | LOAD_REG_IMMEDIATE(r8, 0xf0 | _PAGE_RO | _PAGE_SPS | _PAGE_SH | _PAGE_PRESENT) |
| 780 | 748 | LOAD_REG_ADDR(r9, _sinittext) |
| 781 | 749 | li r0, 4 |
| @@ -797,7 +765,7 @@ _GLOBAL(mmu_pin_tlb) · 15 unmodified lines | ||
| 797 | 765 | LOAD_REG_IMMEDIATE(r5, 28 << 8 | MD_TWAM) |
| 798 | 766 | #ifdef CONFIG_PIN_TLB_DATA |
| 799 | 767 | LOAD_REG_IMMEDIATE(r6, PAGE_OFFSET) |
| 800 | − LOAD_REG_IMMEDIATE(r7, MI_SVALID | MI_PS8MEG) | |
| 768 | + LOAD_REG_IMMEDIATE(r7, MI_SVALID | MI_PS8MEG | _PMD_ACCESSED) | |
| 801 | 769 | #ifdef CONFIG_PIN_TLB_IMMR |
| 802 | 770 | li r0, 3 |
| 803 | 771 | #else |
| @@ -834,7 +802,7 @@ _GLOBAL(mmu_pin_tlb) · 30 unmodified lines | ||
| 834 | 802 | #endif |
| 835 | 803 | #ifdef CONFIG_PIN_TLB_IMMR |
| 836 | 804 | LOAD_REG_IMMEDIATE(r0, VIRT_IMMR_BASE | MD_EVALID) |
| 837 | − LOAD_REG_IMMEDIATE(r7, MD_SVALID | MD_PS512K | MD_GUARDED) | |
| 805 | + LOAD_REG_IMMEDIATE(r7, MD_SVALID | MD_PS512K | MD_GUARDED | _PMD_ACCESSED) | |
| 838 | 806 | mfspr r8, SPRN_IMMR |
| 839 | 807 | rlwinm r8, r8, 0, 0xfff80000 |
| 840 | 808 | ori r8, r8, 0xf0 | _PAGE_DIRTY | _PAGE_SPS | _PAGE_SH | \ |
| @@ -457,11 +457,7 @@ InstructionTLBMiss: · 456 unmodified lines | ||
| 457 | 457 | cmplw 0,r1,r3 |
| 458 | 458 | #endif |
| 459 | 459 | mfspr r2, SPRN_SPRG_PGDIR |
| 460 | −#ifdef CONFIG_SWAP | |
| 461 | 460 | li r1,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC |
| 462 | −#else | |
| 463 | − li r1,_PAGE_PRESENT | _PAGE_EXEC | |
| 464 | −#endif | |
| 465 | 461 | #if defined(CONFIG_MODULES) || defined(CONFIG_DEBUG_PAGEALLOC) |
| 466 | 462 | bgt- 112f |
| 467 | 463 | lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */ |
| @@ -523,11 +519,7 @@ DataLoadTLBMiss: · 55 unmodified lines | ||
| 523 | 519 | lis r1, TASK_SIZE@h /* check if kernel address */ |
| 524 | 520 | cmplw 0,r1,r3 |
| 525 | 521 | mfspr r2, SPRN_SPRG_PGDIR |
| 526 | −#ifdef CONFIG_SWAP | |
| 527 | 522 | li r1, _PAGE_PRESENT | _PAGE_ACCESSED |
| 528 | −#else | |
| 529 | − li r1, _PAGE_PRESENT | |
| 530 | −#endif | |
| 531 | 523 | bgt- 112f |
| 532 | 524 | lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */ |
| 533 | 525 | addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */ |
| @@ -603,11 +595,7 @@ DataStoreTLBMiss: · 69 unmodified lines | ||
| 603 | 595 | lis r1, TASK_SIZE@h /* check if kernel address */ |
| 604 | 596 | cmplw 0,r1,r3 |
| 605 | 597 | mfspr r2, SPRN_SPRG_PGDIR |
| 606 | −#ifdef CONFIG_SWAP | |
| 607 | 598 | li r1, _PAGE_RW | _PAGE_DIRTY | _PAGE_PRESENT | _PAGE_ACCESSED |
| 608 | −#else | |
| 609 | − li r1, _PAGE_RW | _PAGE_DIRTY | _PAGE_PRESENT | |
| 610 | −#endif | |
| 611 | 599 | bgt- 112f |
| 612 | 600 | lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */ |
| 613 | 601 | addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */ |
| @@ -1393,13 +1393,14 @@ static void add_cpu_to_masks(int cpu) · 1392 unmodified lines | ||
| 1393 | 1393 | /* Activate a secondary processor. */ |
| 1394 | 1394 | void start_secondary(void *unused) |
| 1395 | 1395 | { |
| 1396 | − unsigned int cpu = smp_processor_id(); | |
| 1396 | + unsigned int cpu = raw_smp_processor_id(); | |
| 1397 | 1397 | |
| 1398 | 1398 | mmgrab(&init_mm); |
| 1399 | 1399 | current->active_mm = &init_mm; |
| 1400 | 1400 | |
| 1401 | 1401 | smp_store_cpu_info(cpu); |
| 1402 | 1402 | set_dec(tb_ticks_per_jiffy); |
| 1403 | + rcu_cpu_starting(cpu); | |
| 1403 | 1404 | preempt_disable(); |
| 1404 | 1405 | cpu_callin_map[cpu] = 1; |
| 1405 | 1406 | |
| @@ -476,7 +476,7 @@ do { \ · 475 unmodified lines | ||
| 476 | 476 | do { \ |
| 477 | 477 | long __kr_err; \ |
| 478 | 478 | \ |
| 479 | − __put_user_nocheck(*((type *)(dst)), (type *)(src), __kr_err); \ | |
| 479 | + __put_user_nocheck(*((type *)(src)), (type *)(dst), __kr_err); \ | |
| 480 | 480 | if (unlikely(__kr_err)) \ |
| 481 | 481 | goto err_label; \ |
| 482 | 482 | } while (0) |
| @@ -1,4 +1,4 @@ | ||
| 1 | −/* SPDX-License-Identifier: GPL-2.0 */ | |
| 1 | +// SPDX-License-Identifier: GPL-2.0 | |
| 2 | 2 | /* |
| 3 | 3 | * Copyright (C) 2013 Linaro Limited |
| 4 | 4 | * Author: AKASHI Takahiro <takahiro.akashi@linaro.org> |
| @@ -35,12 +35,17 @@ ENTRY(_start) · 34 unmodified lines | ||
| 35 | 35 | .word 0 |
| 36 | 36 | #endif |
| 37 | 37 | .balign 8 |
| 38 | +#ifdef CONFIG_RISCV_M_MODE | |
| 39 | + /* Image load offset (0MB) from start of RAM for M-mode */ | |
| 40 | + .dword 0 | |
| 41 | +#else | |
| 38 | 42 | #if __riscv_xlen == 64 |
| 39 | 43 | /* Image load offset(2MB) from start of RAM */ |
| 40 | 44 | .dword 0x200000 |
| 41 | 45 | #else |
| 42 | 46 | /* Image load offset(4MB) from start of RAM */ |
| 43 | 47 | .dword 0x400000 |
| 48 | +#endif | |
| 44 | 49 | #endif |
| 45 | 50 | /* Effective size of kernel image */ |
| 46 | 51 | .dword _end - _start |
| @@ -1,3 +1,4 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: GPL-2.0-only |
| 2 | 2 | vdso.lds |
| 3 | 3 | *.tmp |
| 4 | +vdso-syms.S | |
| @@ -43,19 +43,14 @@ $(obj)/vdso.o: $(obj)/vdso.so · 42 unmodified lines | ||
| 43 | 43 | SYSCFLAGS_vdso.so.dbg = $(c_flags) |
| 44 | 44 | $(obj)/vdso.so.dbg: $(src)/vdso.lds $(obj-vdso) FORCE |
| 45 | 45 | $(call if_changed,vdsold) |
| 46 | +SYSCFLAGS_vdso.so.dbg = -shared -s -Wl,-soname=linux-vdso.so.1 \ | |
| 47 | + -Wl,--build-id -Wl,--hash-style=both | |
| 46 | 48 | |
| 47 | 49 | # We also create a special relocatable object that should mirror the symbol |
| 48 | 50 | # table and layout of the linked DSO. With ld --just-symbols we can then |
| 49 | 51 | # refer to these symbols in the kernel code rather than hand-coded addresses. |
| 50 | − | |
| 51 | −SYSCFLAGS_vdso.so.dbg = -shared -s -Wl,-soname=linux-vdso.so.1 \ | |
| 52 | − -Wl,--build-id=sha1 -Wl,--hash-style=both | |
| 53 | −$(obj)/vdso-dummy.o: $(src)/vdso.lds $(obj)/rt_sigreturn.o FORCE | |
| 54 | − $(call if_changed,vdsold) | |
| 55 | − | |
| 56 | −LDFLAGS_vdso-syms.o := -r --just-symbols | |
| 57 | −$(obj)/vdso-syms.o: $(obj)/vdso-dummy.o FORCE | |
| 58 | − $(call if_changed,ld) | |
| 52 | +$(obj)/vdso-syms.S: $(obj)/vdso.so FORCE | |
| 53 | + $(call if_changed,so2s) | |
| 59 | 54 | |
| 60 | 55 | # strip rule for the .so file |
| 61 | 56 | $(obj)/%.so: OBJCOPYFLAGS := -S |
| @@ -73,6 +68,11 @@ quiet_cmd_vdsold = VDSOLD $@ · 11 unmodified lines | ||
| 73 | 68 | $(patsubst %, -G __vdso_%, $(vdso-syms)) $@.tmp $@ && \ |
| 74 | 69 | rm $@.tmp |
| 75 | 70 | |
| 71 | +# Extracts symbol offsets from the VDSO, converting them into an assembly file | |
| 72 | +# that contains the same symbols at the same offsets. | |
| 73 | +quiet_cmd_so2s = SO2S $@ | |
| 74 | + cmd_so2s = $(NM) -D $< | $(srctree)/$(src)/so2s.sh > $@ | |
| 75 | + | |
| 76 | 76 | # install commands for the unstripped file |
| 77 | 77 | quiet_cmd_vdso_install = INSTALL $@ |
| 78 | 78 | cmd_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/vdso/$@ |
| @@ -0,0 +1,6 @@ | ||
| 1 | +#!/bin/sh | |
| 2 | +# SPDX-License-Identifier: GPL-2.0+ | |
| 3 | +# Copyright 2020 Palmer Dabbelt <palmerdabbelt@google.com> | |
| 4 | + | |
| 5 | +sed 's!\([0-9a-f]*\) T \([a-z0-9_]*\)\(@@LINUX_4.15\)*!.global \2\n.set \2,0x\1!' \ | |
| 6 | +| grep '^\.' | |
| @@ -86,6 +86,7 @@ static inline void vmalloc_fault(struct pt_regs *regs, int code, unsigned long a · 85 unmodified lines | ||
| 86 | 86 | pmd_t *pmd, *pmd_k; |
| 87 | 87 | pte_t *pte_k; |
| 88 | 88 | int index; |
| 89 | + unsigned long pfn; | |
| 89 | 90 | |
| 90 | 91 | /* User mode accesses just cause a SIGSEGV */ |
| 91 | 92 | if (user_mode(regs)) |
| @@ -100,7 +101,8 @@ static inline void vmalloc_fault(struct pt_regs *regs, int code, unsigned long a · 8 unmodified lines | ||
| 100 | 101 | * of a task switch. |
| 101 | 102 | */ |
| 102 | 103 | index = pgd_index(addr); |
| 103 | − pgd = (pgd_t *)pfn_to_virt(csr_read(CSR_SATP)) + index; | |
| 104 | + pfn = csr_read(CSR_SATP) & SATP_PPN; | |
| 105 | + pgd = (pgd_t *)pfn_to_virt(pfn) + index; | |
| 104 | 106 | pgd_k = init_mm.pgd + index; |
| 105 | 107 | |
| 106 | 108 | if (!pgd_present(*pgd_k)) { |
| @@ -154,9 +154,8 @@ disable: · 153 unmodified lines | ||
| 154 | 154 | |
| 155 | 155 | void __init setup_bootmem(void) |
| 156 | 156 | { |
| 157 | − phys_addr_t mem_size = 0; | |
| 158 | − phys_addr_t total_mem = 0; | |
| 159 | − phys_addr_t mem_start, start, end = 0; | |
| 157 | + phys_addr_t mem_start = 0; | |
| 158 | + phys_addr_t start, end = 0; | |
| 160 | 159 | phys_addr_t vmlinux_end = __pa_symbol(&_end); |
| 161 | 160 | phys_addr_t vmlinux_start = __pa_symbol(&_start); |
| 162 | 161 | u64 i; |
| @@ -164,21 +163,18 @@ void __init setup_bootmem(void) · 1 unmodified line | ||
| 164 | 163 | /* Find the memory region containing the kernel */ |
| 165 | 164 | for_each_mem_range(i, &start, &end) { |
| 166 | 165 | phys_addr_t size = end - start; |
| 167 | − if (!total_mem) | |
| 166 | + if (!mem_start) | |
| 168 | 167 | mem_start = start; |
| 169 | 168 | if (start <= vmlinux_start && vmlinux_end <= end) |
| 170 | 169 | BUG_ON(size == 0); |
| 171 | − total_mem = total_mem + size; | |
| 172 | 170 | } |
| 173 | 171 | |
| 174 | 172 | /* |
| 175 | − * Remove memblock from the end of usable area to the | |
| 176 | − * end of region | |
| 173 | + * The maximal physical memory size is -PAGE_OFFSET. | |
| 174 | + * Make sure that any memory beyond mem_start + (-PAGE_OFFSET) is removed | |
| 175 | + * as it is unusable by kernel. | |
| 177 | 176 | */ |
| 178 | − mem_size = min(total_mem, (phys_addr_t)-PAGE_OFFSET); | |
| 179 | − if (mem_start + mem_size < end) | |
| 180 | − memblock_remove(mem_start + mem_size, | |
| 181 | − end - mem_start - mem_size); | |
| 177 | + memblock_enforce_memory_limit(mem_start - PAGE_OFFSET); | |
| 182 | 178 | |
| 183 | 179 | /* Reserve from the start of the kernel to the end of the kernel */ |
| 184 | 180 | memblock_reserve(vmlinux_start, vmlinux_end - vmlinux_start); |
| @@ -297,6 +293,7 @@ pmd_t fixmap_pmd[PTRS_PER_PMD] __page_aligned_bss; · 112 unmodified lines | ||
| 297 | 293 | #define NUM_EARLY_PMDS (1UL + MAX_EARLY_MAPPING_SIZE / PGDIR_SIZE) |
| 298 | 294 | #endif |
| 299 | 295 | pmd_t early_pmd[PTRS_PER_PMD * NUM_EARLY_PMDS] __initdata __aligned(PAGE_SIZE); |
| 296 | +pmd_t early_dtb_pmd[PTRS_PER_PMD] __initdata __aligned(PAGE_SIZE); | |
| 300 | 297 | |
| 301 | 298 | static pmd_t *__init get_pmd_virt_early(phys_addr_t pa) |
| 302 | 299 | { |
| @@ -494,6 +491,18 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa) · 191 unmodified lines | ||
| 494 | 491 | load_pa + (va - PAGE_OFFSET), |
| 495 | 492 | map_size, PAGE_KERNEL_EXEC); |
| 496 | 493 | |
| 494 | +#ifndef __PAGETABLE_PMD_FOLDED | |
| 495 | + /* Setup early PMD for DTB */ | |
| 496 | + create_pgd_mapping(early_pg_dir, DTB_EARLY_BASE_VA, | |
| 497 | + (uintptr_t)early_dtb_pmd, PGDIR_SIZE, PAGE_TABLE); | |
| 498 | + /* Create two consecutive PMD mappings for FDT early scan */ | |
| 499 | + pa = dtb_pa & ~(PMD_SIZE - 1); | |
| 500 | + create_pmd_mapping(early_dtb_pmd, DTB_EARLY_BASE_VA, | |
| 501 | + pa, PMD_SIZE, PAGE_KERNEL); | |
| 502 | + create_pmd_mapping(early_dtb_pmd, DTB_EARLY_BASE_VA + PMD_SIZE, | |
| 503 | + pa + PMD_SIZE, PMD_SIZE, PAGE_KERNEL); | |
| 504 | + dtb_early_va = (void *)DTB_EARLY_BASE_VA + (dtb_pa & (PMD_SIZE - 1)); | |
| 505 | +#else | |
| 497 | 506 | /* Create two consecutive PGD mappings for FDT early scan */ |
| 498 | 507 | pa = dtb_pa & ~(PGDIR_SIZE - 1); |
| 499 | 508 | create_pgd_mapping(early_pg_dir, DTB_EARLY_BASE_VA, |
| @@ -501,6 +510,7 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa) · 1 unmodified line | ||
| 501 | 510 | create_pgd_mapping(early_pg_dir, DTB_EARLY_BASE_VA + PGDIR_SIZE, |
| 502 | 511 | pa + PGDIR_SIZE, PGDIR_SIZE, PAGE_KERNEL); |
| 503 | 512 | dtb_early_va = (void *)DTB_EARLY_BASE_VA + (dtb_pa & (PGDIR_SIZE - 1)); |
| 513 | +#endif | |
| 504 | 514 | dtb_early_pa = dtb_pa; |
| 505 | 515 | |
| 506 | 516 | /* |
| @@ -93,9 +93,10 @@ CONFIG_CLEANCACHE=y · 92 unmodified lines | ||
| 93 | 93 | CONFIG_FRONTSWAP=y |
| 94 | 94 | CONFIG_CMA_DEBUG=y |
| 95 | 95 | CONFIG_CMA_DEBUGFS=y |
| 96 | +CONFIG_CMA_AREAS=7 | |
| 96 | 97 | CONFIG_MEM_SOFT_DIRTY=y |
| 97 | 98 | CONFIG_ZSWAP=y |
| 98 | −CONFIG_ZSMALLOC=m | |
| 99 | +CONFIG_ZSMALLOC=y | |
| 99 | 100 | CONFIG_ZSMALLOC_STAT=y |
| 100 | 101 | CONFIG_DEFERRED_STRUCT_PAGE_INIT=y |
| 101 | 102 | CONFIG_IDLE_PAGE_TRACKING=y |
| @@ -378,7 +379,6 @@ CONFIG_NETLINK_DIAG=m · 276 unmodified lines | ||
| 378 | 379 | CONFIG_CGROUP_NET_PRIO=y |
| 379 | 380 | CONFIG_BPF_JIT=y |
| 380 | 381 | CONFIG_NET_PKTGEN=m |
| 381 | −# CONFIG_NET_DROP_MONITOR is not set | |
| 382 | 382 | CONFIG_PCI=y |
| 383 | 383 | # CONFIG_PCIEASPM is not set |
| 384 | 384 | CONFIG_PCI_DEBUG=y |
| @@ -386,7 +386,7 @@ CONFIG_HOTPLUG_PCI=y · 1 unmodified line | ||
| 386 | 386 | CONFIG_HOTPLUG_PCI_S390=y |
| 387 | 387 | CONFIG_DEVTMPFS=y |
| 388 | 388 | CONFIG_CONNECTOR=y |
| 389 | −CONFIG_ZRAM=m | |
| 389 | +CONFIG_ZRAM=y | |
| 390 | 390 | CONFIG_BLK_DEV_LOOP=m |
| 391 | 391 | CONFIG_BLK_DEV_CRYPTOLOOP=m |
| 392 | 392 | CONFIG_BLK_DEV_DRBD=m |
| @@ -689,6 +689,7 @@ CONFIG_CRYPTO_TEST=m · 296 unmodified lines | ||
| 689 | 689 | CONFIG_CRYPTO_DH=m |
| 690 | 690 | CONFIG_CRYPTO_ECDH=m |
| 691 | 691 | CONFIG_CRYPTO_ECRDSA=m |
| 692 | +CONFIG_CRYPTO_SM2=m | |
| 692 | 693 | CONFIG_CRYPTO_CURVE25519=m |
| 693 | 694 | CONFIG_CRYPTO_GCM=y |
| 694 | 695 | CONFIG_CRYPTO_CHACHA20POLY1305=m |
| @@ -709,7 +710,6 @@ CONFIG_CRYPTO_RMD160=m · 14 unmodified lines | ||
| 709 | 710 | CONFIG_CRYPTO_RMD256=m |
| 710 | 711 | CONFIG_CRYPTO_RMD320=m |
| 711 | 712 | CONFIG_CRYPTO_SHA3=m |
| 712 | −CONFIG_CRYPTO_SM3=m | |
| 713 | 713 | CONFIG_CRYPTO_TGR192=m |
| 714 | 714 | CONFIG_CRYPTO_WP512=m |
| 715 | 715 | CONFIG_CRYPTO_AES_TI=m |
| @@ -753,6 +753,7 @@ CONFIG_CRYPTO_DES_S390=m · 37 unmodified lines | ||
| 753 | 753 | CONFIG_CRYPTO_AES_S390=m |
| 754 | 754 | CONFIG_CRYPTO_GHASH_S390=m |
| 755 | 755 | CONFIG_CRYPTO_CRC32_S390=y |
| 756 | +CONFIG_CRYPTO_DEV_VIRTIO=m | |
| 756 | 757 | CONFIG_CORDIC=m |
| 757 | 758 | CONFIG_CRC32_SELFTEST=y |
| 758 | 759 | CONFIG_CRC4=m |
| @@ -829,6 +830,7 @@ CONFIG_NETDEV_NOTIFIER_ERROR_INJECT=m · 70 unmodified lines | ||
| 829 | 830 | CONFIG_FAULT_INJECTION=y |
| 830 | 831 | CONFIG_FAILSLAB=y |
| 831 | 832 | CONFIG_FAIL_PAGE_ALLOC=y |
| 833 | +CONFIG_FAULT_INJECTION_USERCOPY=y | |
| 832 | 834 | CONFIG_FAIL_MAKE_REQUEST=y |
| 833 | 835 | CONFIG_FAIL_IO_TIMEOUT=y |
| 834 | 836 | CONFIG_FAIL_FUTEX=y |
| @@ -87,9 +87,10 @@ CONFIG_KSM=y · 86 unmodified lines | ||
| 87 | 87 | CONFIG_TRANSPARENT_HUGEPAGE=y |
| 88 | 88 | CONFIG_CLEANCACHE=y |
| 89 | 89 | CONFIG_FRONTSWAP=y |
| 90 | +CONFIG_CMA_AREAS=7 | |
| 90 | 91 | CONFIG_MEM_SOFT_DIRTY=y |
| 91 | 92 | CONFIG_ZSWAP=y |
| 92 | −CONFIG_ZSMALLOC=m | |
| 93 | +CONFIG_ZSMALLOC=y | |
| 93 | 94 | CONFIG_ZSMALLOC_STAT=y |
| 94 | 95 | CONFIG_DEFERRED_STRUCT_PAGE_INIT=y |
| 95 | 96 | CONFIG_IDLE_PAGE_TRACKING=y |
| @@ -371,7 +372,6 @@ CONFIG_NETLINK_DIAG=m · 275 unmodified lines | ||
| 371 | 372 | CONFIG_CGROUP_NET_PRIO=y |
| 372 | 373 | CONFIG_BPF_JIT=y |
| 373 | 374 | CONFIG_NET_PKTGEN=m |
| 374 | −# CONFIG_NET_DROP_MONITOR is not set | |
| 375 | 375 | CONFIG_PCI=y |
| 376 | 376 | # CONFIG_PCIEASPM is not set |
| 377 | 377 | CONFIG_HOTPLUG_PCI=y |
| @@ -379,7 +379,7 @@ CONFIG_HOTPLUG_PCI_S390=y · 1 unmodified line | ||
| 379 | 379 | CONFIG_UEVENT_HELPER=y |
| 380 | 380 | CONFIG_DEVTMPFS=y |
| 381 | 381 | CONFIG_CONNECTOR=y |
| 382 | −CONFIG_ZRAM=m | |
| 382 | +CONFIG_ZRAM=y | |
| 383 | 383 | CONFIG_BLK_DEV_LOOP=m |
| 384 | 384 | CONFIG_BLK_DEV_CRYPTOLOOP=m |
| 385 | 385 | CONFIG_BLK_DEV_DRBD=m |
| @@ -680,6 +680,7 @@ CONFIG_CRYPTO_TEST=m · 294 unmodified lines | ||
| 680 | 680 | CONFIG_CRYPTO_DH=m |
| 681 | 681 | CONFIG_CRYPTO_ECDH=m |
| 682 | 682 | CONFIG_CRYPTO_ECRDSA=m |
| 683 | +CONFIG_CRYPTO_SM2=m | |
| 683 | 684 | CONFIG_CRYPTO_CURVE25519=m |
| 684 | 685 | CONFIG_CRYPTO_GCM=y |
| 685 | 686 | CONFIG_CRYPTO_CHACHA20POLY1305=m |
| @@ -701,7 +702,6 @@ CONFIG_CRYPTO_RMD160=m · 15 unmodified lines | ||
| 701 | 702 | CONFIG_CRYPTO_RMD256=m |
| 702 | 703 | CONFIG_CRYPTO_RMD320=m |
| 703 | 704 | CONFIG_CRYPTO_SHA3=m |
| 704 | −CONFIG_CRYPTO_SM3=m | |
| 705 | 705 | CONFIG_CRYPTO_TGR192=m |
| 706 | 706 | CONFIG_CRYPTO_WP512=m |
| 707 | 707 | CONFIG_CRYPTO_AES_TI=m |
| @@ -745,6 +745,7 @@ CONFIG_CRYPTO_DES_S390=m · 37 unmodified lines | ||
| 745 | 745 | CONFIG_CRYPTO_AES_S390=m |
| 746 | 746 | CONFIG_CRYPTO_GHASH_S390=m |
| 747 | 747 | CONFIG_CRYPTO_CRC32_S390=y |
| 748 | +CONFIG_CRYPTO_DEV_VIRTIO=m | |
| 748 | 749 | CONFIG_CORDIC=m |
| 749 | 750 | CONFIG_PRIME_NUMBERS=m |
| 750 | 751 | CONFIG_CRC4=m |
| @@ -17,11 +17,11 @@ CONFIG_HZ_100=y · 16 unmodified lines | ||
| 17 | 17 | # CONFIG_CHSC_SCH is not set |
| 18 | 18 | # CONFIG_SCM_BUS is not set |
| 19 | 19 | CONFIG_CRASH_DUMP=y |
| 20 | −# CONFIG_SECCOMP is not set | |
| 21 | 20 | # CONFIG_PFAULT is not set |
| 22 | 21 | # CONFIG_S390_HYPFS_FS is not set |
| 23 | 22 | # CONFIG_VIRTUALIZATION is not set |
| 24 | 23 | # CONFIG_S390_GUEST is not set |
| 24 | +# CONFIG_SECCOMP is not set | |
| 25 | 25 | CONFIG_PARTITION_ADVANCED=y |
| 26 | 26 | CONFIG_IBM_PARTITION=y |
| 27 | 27 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set |
| @@ -692,16 +692,6 @@ static inline int pud_large(pud_t pud) · 691 unmodified lines | ||
| 692 | 692 | return !!(pud_val(pud) & _REGION3_ENTRY_LARGE); |
| 693 | 693 | } |
| 694 | 694 | |
| 695 | −static inline unsigned long pud_pfn(pud_t pud) | |
| 696 | −{ | |
| 697 | − unsigned long origin_mask; | |
| 698 | − | |
| 699 | − origin_mask = _REGION_ENTRY_ORIGIN; | |
| 700 | − if (pud_large(pud)) | |
| 701 | − origin_mask = _REGION3_ENTRY_ORIGIN_LARGE; | |
| 702 | − return (pud_val(pud) & origin_mask) >> PAGE_SHIFT; | |
| 703 | −} | |
| 704 | − | |
| 705 | 695 | #define pmd_leaf pmd_large |
| 706 | 696 | static inline int pmd_large(pmd_t pmd) |
| 707 | 697 | { |
| @@ -747,16 +737,6 @@ static inline int pmd_none(pmd_t pmd) · 39 unmodified lines | ||
| 747 | 737 | return pmd_val(pmd) == _SEGMENT_ENTRY_EMPTY; |
| 748 | 738 | } |
| 749 | 739 | |
| 750 | −static inline unsigned long pmd_pfn(pmd_t pmd) | |
| 751 | −{ | |
| 752 | − unsigned long origin_mask; | |
| 753 | − | |
| 754 | − origin_mask = _SEGMENT_ENTRY_ORIGIN; | |
| 755 | − if (pmd_large(pmd)) | |
| 756 | − origin_mask = _SEGMENT_ENTRY_ORIGIN_LARGE; | |
| 757 | − return (pmd_val(pmd) & origin_mask) >> PAGE_SHIFT; | |
| 758 | −} | |
| 759 | − | |
| 760 | 740 | #define pmd_write pmd_write |
| 761 | 741 | static inline int pmd_write(pmd_t pmd) |
| 762 | 742 | { |
| @@ -1238,11 +1218,39 @@ static inline pte_t mk_pte(struct page *page, pgprot_t pgprot) · 475 unmodified lines | ||
| 1238 | 1218 | #define pud_index(address) (((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1)) |
| 1239 | 1219 | #define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1)) |
| 1240 | 1220 | |
| 1241 | −#define pmd_deref(pmd) (pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN) | |
| 1242 | −#define pud_deref(pud) (pud_val(pud) & _REGION_ENTRY_ORIGIN) | |
| 1243 | 1221 | #define p4d_deref(pud) (p4d_val(pud) & _REGION_ENTRY_ORIGIN) |
| 1244 | 1222 | #define pgd_deref(pgd) (pgd_val(pgd) & _REGION_ENTRY_ORIGIN) |
| 1245 | 1223 | |
| 1224 | +static inline unsigned long pmd_deref(pmd_t pmd) | |
| 1225 | +{ | |
| 1226 | + unsigned long origin_mask; | |
| 1227 | + | |
| 1228 | + origin_mask = _SEGMENT_ENTRY_ORIGIN; | |
| 1229 | + if (pmd_large(pmd)) | |
| 1230 | + origin_mask = _SEGMENT_ENTRY_ORIGIN_LARGE; | |
| 1231 | + return pmd_val(pmd) & origin_mask; | |
| 1232 | +} | |
| 1233 | + | |
| 1234 | +static inline unsigned long pmd_pfn(pmd_t pmd) | |
| 1235 | +{ | |
| 1236 | + return pmd_deref(pmd) >> PAGE_SHIFT; | |
| 1237 | +} | |
| 1238 | + | |
| 1239 | +static inline unsigned long pud_deref(pud_t pud) | |
| 1240 | +{ | |
| 1241 | + unsigned long origin_mask; | |
| 1242 | + | |
| 1243 | + origin_mask = _REGION_ENTRY_ORIGIN; | |
| 1244 | + if (pud_large(pud)) | |
| 1245 | + origin_mask = _REGION3_ENTRY_ORIGIN_LARGE; | |
| 1246 | + return pud_val(pud) & origin_mask; | |
| 1247 | +} | |
| 1248 | + | |
| 1249 | +static inline unsigned long pud_pfn(pud_t pud) | |
| 1250 | +{ | |
| 1251 | + return pud_deref(pud) >> PAGE_SHIFT; | |
| 1252 | +} | |
| 1253 | + | |
| 1246 | 1254 | /* |
| 1247 | 1255 | * The pgd_offset function *always* adds the index for the top-level |
| 1248 | 1256 | * region/segment table. This is done to get a sequence like the |
Empty file deleted.
| @@ -61,14 +61,6 @@ int main(void) · 60 unmodified lines | ||
| 61 | 61 | BLANK(); |
| 62 | 62 | OFFSET(__VDSO_GETCPU_VAL, vdso_per_cpu_data, getcpu_val); |
| 63 | 63 | BLANK(); |
| 64 | − /* constants used by the vdso */ | |
| 65 | − DEFINE(__CLOCK_REALTIME, CLOCK_REALTIME); | |
| 66 | − DEFINE(__CLOCK_MONOTONIC, CLOCK_MONOTONIC); | |
| 67 | − DEFINE(__CLOCK_REALTIME_COARSE, CLOCK_REALTIME_COARSE); | |
| 68 | − DEFINE(__CLOCK_MONOTONIC_COARSE, CLOCK_MONOTONIC_COARSE); | |
| 69 | − DEFINE(__CLOCK_THREAD_CPUTIME_ID, CLOCK_THREAD_CPUTIME_ID); | |
| 70 | − DEFINE(__CLOCK_COARSE_RES, LOW_RES_NSEC); | |
| 71 | − BLANK(); | |
| 72 | 64 | /* idle data offsets */ |
| 73 | 65 | OFFSET(__CLOCK_IDLE_ENTER, s390_idle_data, clock_idle_enter); |
| 74 | 66 | OFFSET(__CLOCK_IDLE_EXIT, s390_idle_data, clock_idle_exit); |
| @@ -855,13 +855,14 @@ void __init smp_detect_cpus(void) · 854 unmodified lines | ||
| 855 | 855 | |
| 856 | 856 | static void smp_init_secondary(void) |
| 857 | 857 | { |
| 858 | − int cpu = smp_processor_id(); | |
| 858 | + int cpu = raw_smp_processor_id(); | |
| 859 | 859 | |
| 860 | 860 | S390_lowcore.last_update_clock = get_tod_clock(); |
| 861 | 861 | restore_access_regs(S390_lowcore.access_regs_save_area); |
| 862 | 862 | set_cpu_flag(CIF_ASCE_PRIMARY); |
| 863 | 863 | set_cpu_flag(CIF_ASCE_SECONDARY); |
| 864 | 864 | cpu_init(); |
| 865 | + rcu_cpu_starting(cpu); | |
| 865 | 866 | preempt_disable(); |
| 866 | 867 | init_cpu_timer(); |
| 867 | 868 | vtime_init(); |
| @@ -101,6 +101,10 @@ static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf) · 100 unmodified lines | ||
| 101 | 101 | if (ret) |
| 102 | 102 | break; |
| 103 | 103 | |
| 104 | + /* the PCI function will be scanned once function 0 appears */ | |
| 105 | + if (!zdev->zbus->bus) | |
| 106 | + break; | |
| 107 | + | |
| 104 | 108 | pdev = pci_scan_single_device(zdev->zbus->bus, zdev->devfn); |
| 105 | 109 | if (!pdev) |
| 106 | 110 | break; |
| @@ -164,6 +164,7 @@ void initialize_identity_maps(void *rmode) · 163 unmodified lines | ||
| 164 | 164 | add_identity_map(cmdline, cmdline + COMMAND_LINE_SIZE); |
| 165 | 165 | |
| 166 | 166 | /* Load the new page-table. */ |
| 167 | + sev_verify_cbit(top_level_pgt); | |
| 167 | 168 | write_cr3(top_level_pgt); |
| 168 | 169 | } |
| 169 | 170 | |
| @@ -68,6 +68,9 @@ SYM_FUNC_START(get_sev_encryption_bit) · 67 unmodified lines | ||
| 68 | 68 | SYM_FUNC_END(get_sev_encryption_bit) |
| 69 | 69 | |
| 70 | 70 | .code64 |
| 71 | + | |
| 72 | +#include "../../kernel/sev_verify_cbit.S" | |
| 73 | + | |
| 71 | 74 | SYM_FUNC_START(set_sev_encryption_mask) |
| 72 | 75 | #ifdef CONFIG_AMD_MEM_ENCRYPT |
| 73 | 76 | push %rbp |
| @@ -81,6 +84,19 @@ SYM_FUNC_START(set_sev_encryption_mask) · 7 unmodified lines | ||
| 81 | 84 | |
| 82 | 85 | bts %rax, sme_me_mask(%rip) /* Create the encryption mask */ |
| 83 | 86 | |
| 87 | + /* | |
| 88 | + * Read MSR_AMD64_SEV again and store it to sev_status. Can't do this in | |
| 89 | + * get_sev_encryption_bit() because this function is 32-bit code and | |
| 90 | + * shared between 64-bit and 32-bit boot path. | |
| 91 | + */ | |
| 92 | + movl $MSR_AMD64_SEV, %ecx /* Read the SEV MSR */ | |
| 93 | + rdmsr | |
| 94 | + | |
| 95 | + /* Store MSR value in sev_status */ | |
| 96 | + shlq $32, %rdx | |
| 97 | + orq %rdx, %rax | |
| 98 | + movq %rax, sev_status(%rip) | |
| 99 | + | |
| 84 | 100 | .Lno_sev_mask: |
| 85 | 101 | movq %rbp, %rsp /* Restore original stack pointer */ |
| 86 | 102 | |
| @@ -96,5 +112,7 @@ SYM_FUNC_END(set_sev_encryption_mask) · 9 unmodified lines | ||
| 96 | 112 | |
| 97 | 113 | #ifdef CONFIG_AMD_MEM_ENCRYPT |
| 98 | 114 | .balign 8 |
| 99 | −SYM_DATA(sme_me_mask, .quad 0) | |
| 115 | +SYM_DATA(sme_me_mask, .quad 0) | |
| 116 | +SYM_DATA(sev_status, .quad 0) | |
| 117 | +SYM_DATA(sev_check_data, .quad 0) | |
| 100 | 118 | #endif |
| @@ -159,4 +159,6 @@ void boot_page_fault(void); · 158 unmodified lines | ||
| 159 | 159 | void boot_stage1_vc(void); |
| 160 | 160 | void boot_stage2_vc(void); |
| 161 | 161 | |
| 162 | +unsigned long sev_verify_cbit(unsigned long cr3); | |
| 163 | + | |
| 162 | 164 | #endif /* BOOT_COMPRESSED_MISC_H */ |
| @@ -273,11 +273,15 @@ void __init hv_apic_init(void) · 272 unmodified lines | ||
| 273 | 273 | pr_info("Hyper-V: Using enlightened APIC (%s mode)", |
| 274 | 274 | x2apic_enabled() ? "x2apic" : "xapic"); |
| 275 | 275 | /* |
| 276 | − * With x2apic, architectural x2apic MSRs are equivalent to the | |
| 277 | − * respective synthetic MSRs, so there's no need to override | |
| 278 | − * the apic accessors. The only exception is | |
| 279 | − * hv_apic_eoi_write, because it benefits from lazy EOI when | |
| 280 | − * available, but it works for both xapic and x2apic modes. | |
| 276 | + * When in x2apic mode, don't use the Hyper-V specific APIC | |
| 277 | + * accessors since the field layout in the ICR register is | |
| 278 | + * different in x2apic mode. Furthermore, the architectural | |
| 279 | + * x2apic MSRs function just as well as the Hyper-V | |
| 280 | + * synthetic APIC MSRs, so there's no benefit in having | |
| 281 | + * separate Hyper-V accessors for x2apic mode. The only | |
| 282 | + * exception is hv_apic_eoi_write, because it benefits from | |
| 283 | + * lazy EOI when available, but the same accessor works for | |
| 284 | + * both xapic and x2apic because the field layout is the same. | |
| 281 | 285 | */ |
| 282 | 286 | apic_set_eoi_write(hv_apic_eoi_write); |
| 283 | 287 | if (!x2apic_enabled()) { |
| @@ -290,6 +290,9 @@ static void __init uv_stringify(int len, char *to, char *from) · 289 unmodified lines | ||
| 290 | 290 | { |
| 291 | 291 | /* Relies on 'to' being NULL chars so result will be NULL terminated */ |
| 292 | 292 | strncpy(to, from, len-1); |
| 293 | + | |
| 294 | + /* Trim trailing spaces */ | |
| 295 | + (void)strim(to); | |
| 293 | 296 | } |
| 294 | 297 | |
| 295 | 298 | /* Find UV arch type entry in UVsystab */ |
| @@ -366,7 +369,7 @@ static int __init early_get_arch_type(void) · 70 unmodified lines | ||
| 366 | 369 | return ret; |
| 367 | 370 | } |
| 368 | 371 | |
| 369 | −static int __init uv_set_system_type(char *_oem_id) | |
| 372 | +static int __init uv_set_system_type(char *_oem_id, char *_oem_table_id) | |
| 370 | 373 | { |
| 371 | 374 | /* Save OEM_ID passed from ACPI MADT */ |
| 372 | 375 | uv_stringify(sizeof(oem_id), oem_id, _oem_id); |
| @@ -386,13 +389,23 @@ static int __init uv_set_system_type(char *_oem_id) · 13 unmodified lines | ||
| 386 | 389 | /* (Not hubless), not a UV */ |
| 387 | 390 | return 0; |
| 388 | 391 | |
| 392 | + /* Is UV hubless system */ | |
| 393 | + uv_hubless_system = 0x01; | |
| 394 | + | |
| 395 | + /* UV5 Hubless */ | |
| 396 | + if (strncmp(uv_archtype, "NSGI5", 5) == 0) | |
| 397 | + uv_hubless_system |= 0x20; | |
| 398 | + | |
| 389 | 399 | /* UV4 Hubless: CH */ |
| 390 | − if (strncmp(uv_archtype, "NSGI4", 5) == 0) | |
| 391 | − uv_hubless_system = 0x11; | |
| 400 | + else if (strncmp(uv_archtype, "NSGI4", 5) == 0) | |
| 401 | + uv_hubless_system |= 0x10; | |
| 392 | 402 | |
| 393 | 403 | /* UV3 Hubless: UV300/MC990X w/o hub */ |
| 394 | 404 | else |
| 395 | − uv_hubless_system = 0x9; | |
| 405 | + uv_hubless_system |= 0x8; | |
| 406 | + | |
| 407 | + /* Copy APIC type */ | |
| 408 | + uv_stringify(sizeof(oem_table_id), oem_table_id, _oem_table_id); | |
| 396 | 409 | |
| 397 | 410 | pr_info("UV: OEM IDs %s/%s, SystemType %d, HUBLESS ID %x\n", |
| 398 | 411 | oem_id, oem_table_id, uv_system_type, uv_hubless_system); |
| @@ -456,7 +469,7 @@ static int __init uv_acpi_madt_oem_check(char *_oem_id, char *_oem_table_id) · 57 unmodified lines | ||
| 456 | 469 | uv_cpu_info->p_uv_hub_info = &uv_hub_info_node0; |
| 457 | 470 | |
| 458 | 471 | /* If not UV, return. */ |
| 459 | − if (likely(uv_set_system_type(_oem_id) == 0)) | |
| 472 | + if (uv_set_system_type(_oem_id, _oem_table_id) == 0) | |
| 460 | 473 | return 0; |
| 461 | 474 | |
| 462 | 475 | /* Save and Decode OEM Table ID */ |
| @@ -1254,6 +1254,14 @@ static int ssb_prctl_set(struct task_struct *task, unsigned long ctrl) · 1253 unmodified lines | ||
| 1254 | 1254 | return 0; |
| 1255 | 1255 | } |
| 1256 | 1256 | |
| 1257 | +static bool is_spec_ib_user_controlled(void) | |
| 1258 | +{ | |
| 1259 | + return spectre_v2_user_ibpb == SPECTRE_V2_USER_PRCTL || | |
| 1260 | + spectre_v2_user_ibpb == SPECTRE_V2_USER_SECCOMP || | |
| 1261 | + spectre_v2_user_stibp == SPECTRE_V2_USER_PRCTL || | |
| 1262 | + spectre_v2_user_stibp == SPECTRE_V2_USER_SECCOMP; | |
| 1263 | +} | |
| 1264 | + | |
| 1257 | 1265 | static int ib_prctl_set(struct task_struct *task, unsigned long ctrl) |
| 1258 | 1266 | { |
| 1259 | 1267 | switch (ctrl) { |
| @@ -1261,16 +1269,26 @@ static int ib_prctl_set(struct task_struct *task, unsigned long ctrl) · 1 unmodified line | ||
| 1261 | 1269 | if (spectre_v2_user_ibpb == SPECTRE_V2_USER_NONE && |
| 1262 | 1270 | spectre_v2_user_stibp == SPECTRE_V2_USER_NONE) |
| 1263 | 1271 | return 0; |
| 1272 | + | |
| 1264 | 1273 | /* |
| 1265 | − * Indirect branch speculation is always disabled in strict | |
| 1266 | − * mode. It can neither be enabled if it was force-disabled | |
| 1267 | − * by a previous prctl call. | |
| 1274 | + * With strict mode for both IBPB and STIBP, the instruction | |
| 1275 | + * code paths avoid checking this task flag and instead, | |
| 1276 | + * unconditionally run the instruction. However, STIBP and IBPB | |
| 1277 | + * are independent and either can be set to conditionally | |
| 1278 | + * enabled regardless of the mode of the other. | |
| 1279 | + * | |
| 1280 | + * If either is set to conditional, allow the task flag to be | |
| 1281 | + * updated, unless it was force-disabled by a previous prctl | |
| 1282 | + * call. Currently, this is possible on an AMD CPU which has the | |
| 1283 | + * feature X86_FEATURE_AMD_STIBP_ALWAYS_ON. In this case, if the | |
| 1284 | + * kernel is booted with 'spectre_v2_user=seccomp', then | |
| 1285 | + * spectre_v2_user_ibpb == SPECTRE_V2_USER_SECCOMP and | |
| 1286 | + * spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT_PREFERRED. | |
| 1268 | 1287 | */ |
| 1269 | − if (spectre_v2_user_ibpb == SPECTRE_V2_USER_STRICT || | |
| 1270 | − spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT || | |
| 1271 | − spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT_PREFERRED || | |
| 1288 | + if (!is_spec_ib_user_controlled() || | |
| 1272 | 1289 | task_spec_ib_force_disable(task)) |
| 1273 | 1290 | return -EPERM; |
| 1291 | + | |
| 1274 | 1292 | task_clear_spec_ib_disable(task); |
| 1275 | 1293 | task_update_spec_tif(task); |
| 1276 | 1294 | break; |
| @@ -1283,10 +1301,10 @@ static int ib_prctl_set(struct task_struct *task, unsigned long ctrl) · 6 unmodified lines | ||
| 1283 | 1301 | if (spectre_v2_user_ibpb == SPECTRE_V2_USER_NONE && |
| 1284 | 1302 | spectre_v2_user_stibp == SPECTRE_V2_USER_NONE) |
| 1285 | 1303 | return -EPERM; |
| 1286 | − if (spectre_v2_user_ibpb == SPECTRE_V2_USER_STRICT || | |
| 1287 | − spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT || | |
| 1288 | − spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT_PREFERRED) | |
| 1304 | + | |
| 1305 | + if (!is_spec_ib_user_controlled()) | |
| 1289 | 1306 | return 0; |
| 1307 | + | |
| 1290 | 1308 | task_set_spec_ib_disable(task); |
| 1291 | 1309 | if (ctrl == PR_SPEC_FORCE_DISABLE) |
| 1292 | 1310 | task_set_spec_ib_force_disable(task); |
| @@ -1351,20 +1369,17 @@ static int ib_prctl_get(struct task_struct *task) · 58 unmodified lines | ||
| 1351 | 1369 | if (spectre_v2_user_ibpb == SPECTRE_V2_USER_NONE && |
| 1352 | 1370 | spectre_v2_user_stibp == SPECTRE_V2_USER_NONE) |
| 1353 | 1371 | return PR_SPEC_ENABLE; |
| 1354 | − else if (spectre_v2_user_ibpb == SPECTRE_V2_USER_STRICT || | |
| 1355 | − spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT || | |
| 1356 | − spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT_PREFERRED) | |
| 1357 | − return PR_SPEC_DISABLE; | |
| 1358 | − else if (spectre_v2_user_ibpb == SPECTRE_V2_USER_PRCTL || | |
| 1359 | − spectre_v2_user_ibpb == SPECTRE_V2_USER_SECCOMP || | |
| 1360 | − spectre_v2_user_stibp == SPECTRE_V2_USER_PRCTL || | |
| 1361 | − spectre_v2_user_stibp == SPECTRE_V2_USER_SECCOMP) { | |
| 1372 | + else if (is_spec_ib_user_controlled()) { | |
| 1362 | 1373 | if (task_spec_ib_force_disable(task)) |
| 1363 | 1374 | return PR_SPEC_PRCTL | PR_SPEC_FORCE_DISABLE; |
| 1364 | 1375 | if (task_spec_ib_disable(task)) |
| 1365 | 1376 | return PR_SPEC_PRCTL | PR_SPEC_DISABLE; |
| 1366 | 1377 | return PR_SPEC_PRCTL | PR_SPEC_ENABLE; |
| 1367 | − } else | |
| 1378 | + } else if (spectre_v2_user_ibpb == SPECTRE_V2_USER_STRICT || | |
| 1379 | + spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT || | |
| 1380 | + spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT_PREFERRED) | |
| 1381 | + return PR_SPEC_DISABLE; | |
| 1382 | + else | |
| 1368 | 1383 | return PR_SPEC_NOT_AFFECTED; |
| 1369 | 1384 | } |
| 1370 | 1385 | |
| @@ -161,6 +161,21 @@ SYM_INNER_LABEL(secondary_startup_64_no_verify, SYM_L_GLOBAL) · 160 unmodified lines | ||
| 161 | 161 | |
| 162 | 162 | /* Setup early boot stage 4-/5-level pagetables. */ |
| 163 | 163 | addq phys_base(%rip), %rax |
| 164 | + | |
| 165 | + /* | |
| 166 | + * For SEV guests: Verify that the C-bit is correct. A malicious | |
| 167 | + * hypervisor could lie about the C-bit position to perform a ROP | |
| 168 | + * attack on the guest by writing to the unencrypted stack and wait for | |
| 169 | + * the next RET instruction. | |
| 170 | + * %rsi carries pointer to realmode data and is callee-clobbered. Save | |
| 171 | + * and restore it. | |
| 172 | + */ | |
| 173 | + pushq %rsi | |
| 174 | + movq %rax, %rdi | |
| 175 | + call sev_verify_cbit | |
| 176 | + popq %rsi | |
| 177 | + | |
| 178 | + /* Switch to new page-table */ | |
| 164 | 179 | movq %rax, %cr3 |
| 165 | 180 | |
| 166 | 181 | /* Ensure I am executing from virtual addresses */ |
| @@ -279,6 +294,7 @@ SYM_INNER_LABEL(secondary_startup_64_no_verify, SYM_L_GLOBAL) · 112 unmodified lines | ||
| 279 | 294 | SYM_CODE_END(secondary_startup_64) |
| 280 | 295 | |
| 281 | 296 | #include "verify_cpu.S" |
| 297 | +#include "sev_verify_cbit.S" | |
| 282 | 298 | |
| 283 | 299 | #ifdef CONFIG_HOTPLUG_CPU |
| 284 | 300 | /* |
| @@ -178,6 +178,32 @@ void __init do_vc_no_ghcb(struct pt_regs *regs, unsigned long exit_code) · 177 unmodified lines | ||
| 178 | 178 | goto fail; |
| 179 | 179 | regs->dx = val >> 32; |
| 180 | 180 | |
| 181 | + /* | |
| 182 | + * This is a VC handler and the #VC is only raised when SEV-ES is | |
| 183 | + * active, which means SEV must be active too. Do sanity checks on the | |
| 184 | + * CPUID results to make sure the hypervisor does not trick the kernel | |
| 185 | + * into the no-sev path. This could map sensitive data unencrypted and | |
| 186 | + * make it accessible to the hypervisor. | |
| 187 | + * | |
| 188 | + * In particular, check for: | |
| 189 | + * - Hypervisor CPUID bit | |
| 190 | + * - Availability of CPUID leaf 0x8000001f | |
| 191 | + * - SEV CPUID bit. | |
| 192 | + * | |
| 193 | + * The hypervisor might still report the wrong C-bit position, but this | |
| 194 | + * can't be checked here. | |
| 195 | + */ | |
| 196 | + | |
| 197 | + if ((fn == 1 && !(regs->cx & BIT(31)))) | |
| 198 | + /* Hypervisor bit */ | |
| 199 | + goto fail; | |
| 200 | + else if (fn == 0x80000000 && (regs->ax < 0x8000001f)) | |
| 201 | + /* SEV leaf check */ | |
| 202 | + goto fail; | |
| 203 | + else if ((fn == 0x8000001f && !(regs->ax & BIT(1)))) | |
| 204 | + /* SEV bit */ | |
| 205 | + goto fail; | |
| 206 | + | |
| 181 | 207 | /* Skip over the CPUID two-byte opcode */ |
| 182 | 208 | regs->ip += 2; |
| 183 | 209 | |
| @@ -374,8 +374,8 @@ fault: · 373 unmodified lines | ||
| 374 | 374 | return ES_EXCEPTION; |
| 375 | 375 | } |
| 376 | 376 | |
| 377 | −static bool vc_slow_virt_to_phys(struct ghcb *ghcb, struct es_em_ctxt *ctxt, | |
| 378 | − unsigned long vaddr, phys_addr_t *paddr) | |
| 377 | +static enum es_result vc_slow_virt_to_phys(struct ghcb *ghcb, struct es_em_ctxt *ctxt, | |
| 378 | + unsigned long vaddr, phys_addr_t *paddr) | |
| 379 | 379 | { |
| 380 | 380 | unsigned long va = (unsigned long)vaddr; |
| 381 | 381 | unsigned int level; |
| @@ -394,15 +394,19 @@ static bool vc_slow_virt_to_phys(struct ghcb *ghcb, struct es_em_ctxt *ctxt, · 12 unmodified lines | ||
| 394 | 394 | if (user_mode(ctxt->regs)) |
| 395 | 395 | ctxt->fi.error_code |= X86_PF_USER; |
| 396 | 396 | |
| 397 | − return false; | |
| 397 | + return ES_EXCEPTION; | |
| 398 | 398 | } |
| 399 | 399 | |
| 400 | + if (WARN_ON_ONCE(pte_val(*pte) & _PAGE_ENC)) | |
| 401 | + /* Emulated MMIO to/from encrypted memory not supported */ | |
| 402 | + return ES_UNSUPPORTED; | |
| 403 | + | |
| 400 | 404 | pa = (phys_addr_t)pte_pfn(*pte) << PAGE_SHIFT; |
| 401 | 405 | pa |= va & ~page_level_mask(level); |
| 402 | 406 | |
| 403 | 407 | *paddr = pa; |
| 404 | 408 | |
| 405 | − return true; | |
| 409 | + return ES_OK; | |
| 406 | 410 | } |
| 407 | 411 | |
| 408 | 412 | /* Include code shared with pre-decompression boot stage */ |
| @@ -731,6 +735,7 @@ static enum es_result vc_do_mmio(struct ghcb *ghcb, struct es_em_ctxt *ctxt, · 322 unmodified lines | ||
| 731 | 735 | { |
| 732 | 736 | u64 exit_code, exit_info_1, exit_info_2; |
| 733 | 737 | unsigned long ghcb_pa = __pa(ghcb); |
| 738 | + enum es_result res; | |
| 734 | 739 | phys_addr_t paddr; |
| 735 | 740 | void __user *ref; |
| 736 | 741 | |
| @@ -740,11 +745,12 @@ static enum es_result vc_do_mmio(struct ghcb *ghcb, struct es_em_ctxt *ctxt, · 3 unmodified lines | ||
| 740 | 745 | |
| 741 | 746 | exit_code = read ? SVM_VMGEXIT_MMIO_READ : SVM_VMGEXIT_MMIO_WRITE; |
| 742 | 747 | |
| 743 | − if (!vc_slow_virt_to_phys(ghcb, ctxt, (unsigned long)ref, &paddr)) { | |
| 744 | − if (!read) | |
| 748 | + res = vc_slow_virt_to_phys(ghcb, ctxt, (unsigned long)ref, &paddr); | |
| 749 | + if (res != ES_OK) { | |
| 750 | + if (res == ES_EXCEPTION && !read) | |
| 745 | 751 | ctxt->fi.error_code |= X86_PF_WRITE; |
| 746 | 752 | |
| 747 | − return ES_EXCEPTION; | |
| 753 | + return res; | |
| 748 | 754 | } |
| 749 | 755 | |
| 750 | 756 | exit_info_1 = paddr; |
| @@ -0,0 +1,89 @@ | ||
| 1 | +/* SPDX-License-Identifier: GPL-2.0-only */ | |
| 2 | +/* | |
| 3 | + * sev_verify_cbit.S - Code for verification of the C-bit position reported | |
| 4 | + * by the Hypervisor when running with SEV enabled. | |
| 5 | + * | |
| 6 | + * Copyright (c) 2020 Joerg Roedel (jroedel@suse.de) | |
| 7 | + * | |
| 8 | + * sev_verify_cbit() is called before switching to a new long-mode page-table | |
| 9 | + * at boot. | |
| 10 | + * | |
| 11 | + * Verify that the C-bit position is correct by writing a random value to | |
| 12 | + * an encrypted memory location while on the current page-table. Then it | |
| 13 | + * switches to the new page-table to verify the memory content is still the | |
| 14 | + * same. After that it switches back to the current page-table and when the | |
| 15 | + * check succeeded it returns. If the check failed the code invalidates the | |
| 16 | + * stack pointer and goes into a hlt loop. The stack-pointer is invalidated to | |
| 17 | + * make sure no interrupt or exception can get the CPU out of the hlt loop. | |
| 18 | + * | |
| 19 | + * New page-table pointer is expected in %rdi (first parameter) | |
| 20 | + * | |
| 21 | + */ | |
| 22 | +SYM_FUNC_START(sev_verify_cbit) | |
| 23 | +#ifdef CONFIG_AMD_MEM_ENCRYPT | |
| 24 | + /* First check if a C-bit was detected */ | |
| 25 | + movq sme_me_mask(%rip), %rsi | |
| 26 | + testq %rsi, %rsi | |
| 27 | + jz 3f | |
| 28 | + | |
| 29 | + /* sme_me_mask != 0 could mean SME or SEV - Check also for SEV */ | |
| 30 | + movq sev_status(%rip), %rsi | |
| 31 | + testq %rsi, %rsi | |
| 32 | + jz 3f | |
| 33 | + | |
| 34 | + /* Save CR4 in %rsi */ | |
| 35 | + movq %cr4, %rsi | |
| 36 | + | |
| 37 | + /* Disable Global Pages */ | |
| 38 | + movq %rsi, %rdx | |
| 39 | + andq $(~X86_CR4_PGE), %rdx | |
| 40 | + movq %rdx, %cr4 | |
| 41 | + | |
| 42 | + /* | |
| 43 | + * Verified that running under SEV - now get a random value using | |
| 44 | + * RDRAND. This instruction is mandatory when running as an SEV guest. | |
| 45 | + * | |
| 46 | + * Don't bail out of the loop if RDRAND returns errors. It is better to | |
| 47 | + * prevent forward progress than to work with a non-random value here. | |
| 48 | + */ | |
| 49 | +1: rdrand %rdx | |
| 50 | + jnc 1b | |
| 51 | + | |
| 52 | + /* Store value to memory and keep it in %rdx */ | |
| 53 | + movq %rdx, sev_check_data(%rip) | |
| 54 | + | |
| 55 | + /* Backup current %cr3 value to restore it later */ | |
| 56 | + movq %cr3, %rcx | |
| 57 | + | |
| 58 | + /* Switch to new %cr3 - This might unmap the stack */ | |
| 59 | + movq %rdi, %cr3 | |
| 60 | + | |
| 61 | + /* | |
| 62 | + * Compare value in %rdx with memory location. If C-bit is incorrect | |
| 63 | + * this would read the encrypted data and make the check fail. | |
| 64 | + */ | |
| 65 | + cmpq %rdx, sev_check_data(%rip) | |
| 66 | + | |
| 67 | + /* Restore old %cr3 */ | |
| 68 | + movq %rcx, %cr3 | |
| 69 | + | |
| 70 | + /* Restore previous CR4 */ | |
| 71 | + movq %rsi, %cr4 | |
| 72 | + | |
| 73 | + /* Check CMPQ result */ | |
| 74 | + je 3f | |
| 75 | + | |
| 76 | + /* | |
| 77 | + * The check failed, prevent any forward progress to prevent ROP | |
| 78 | + * attacks, invalidate the stack and go into a hlt loop. | |
| 79 | + */ | |
| 80 | + xorq %rsp, %rsp | |
| 81 | + subq $0x1000, %rsp | |
| 82 | +2: hlt | |
| 83 | + jmp 2b | |
| 84 | +3: | |
| 85 | +#endif | |
| 86 | + /* Return page-table pointer */ | |
| 87 | + movq %rdi, %rax | |
| 88 | + ret | |
| 89 | +SYM_FUNC_END(sev_verify_cbit) | |
| @@ -16,8 +16,6 @@ · 15 unmodified lines | ||
| 16 | 16 | * to a jmp to memcpy_erms which does the REP; MOVSB mem copy. |
| 17 | 17 | */ |
| 18 | 18 | |
| 19 | −.weak memcpy | |
| 20 | − | |
| 21 | 19 | /* |
| 22 | 20 | * memcpy - Copy a memory block. |
| 23 | 21 | * |
| @@ -30,7 +28,7 @@ · 6 unmodified lines | ||
| 30 | 28 | * rax original destination |
| 31 | 29 | */ |
| 32 | 30 | SYM_FUNC_START_ALIAS(__memcpy) |
| 33 | −SYM_FUNC_START_LOCAL(memcpy) | |
| 31 | +SYM_FUNC_START_WEAK(memcpy) | |
| 34 | 32 | ALTERNATIVE_2 "jmp memcpy_orig", "", X86_FEATURE_REP_GOOD, \ |
| 35 | 33 | "jmp memcpy_erms", X86_FEATURE_ERMS |
| 36 | 34 | |
| @@ -24,9 +24,7 @@ · 23 unmodified lines | ||
| 24 | 24 | * Output: |
| 25 | 25 | * rax: dest |
| 26 | 26 | */ |
| 27 | −.weak memmove | |
| 28 | − | |
| 29 | −SYM_FUNC_START_ALIAS(memmove) | |
| 27 | +SYM_FUNC_START_WEAK(memmove) | |
| 30 | 28 | SYM_FUNC_START(__memmove) |
| 31 | 29 | |
| 32 | 30 | mov %rdi, %rax |
| @@ -6,8 +6,6 @@ · 5 unmodified lines | ||
| 6 | 6 | #include <asm/alternative-asm.h> |
| 7 | 7 | #include <asm/export.h> |
| 8 | 8 | |
| 9 | −.weak memset | |
| 10 | − | |
| 11 | 9 | /* |
| 12 | 10 | * ISO C memset - set a memory block to a byte value. This function uses fast |
| 13 | 11 | * string to get better performance than the original function. The code is |
| @@ -19,7 +17,7 @@ · 5 unmodified lines | ||
| 19 | 17 | * |
| 20 | 18 | * rax original destination |
| 21 | 19 | */ |
| 22 | −SYM_FUNC_START_ALIAS(memset) | |
| 20 | +SYM_FUNC_START_WEAK(memset) | |
| 23 | 21 | SYM_FUNC_START(__memset) |
| 24 | 22 | /* |
| 25 | 23 | * Some CPUs support enhanced REP MOVSB/STOSB feature. It is recommended |
| @@ -39,6 +39,7 @@ · 38 unmodified lines | ||
| 39 | 39 | */ |
| 40 | 40 | u64 sme_me_mask __section(".data") = 0; |
| 41 | 41 | u64 sev_status __section(".data") = 0; |
| 42 | +u64 sev_check_data __section(".data") = 0; | |
| 42 | 43 | EXPORT_SYMBOL(sme_me_mask); |
| 43 | 44 | DEFINE_STATIC_KEY_FALSE(sev_enable_key); |
| 44 | 45 | EXPORT_SYMBOL_GPL(sev_enable_key); |
| @@ -89,8 +89,8 @@ static void __init free_highpages(void) · 88 unmodified lines | ||
| 89 | 89 | /* set highmem page free */ |
| 90 | 90 | for_each_free_mem_range(i, NUMA_NO_NODE, MEMBLOCK_NONE, |
| 91 | 91 | &range_start, &range_end, NULL) { |
| 92 | − unsigned long start = PHYS_PFN(range_start); | |
| 93 | − unsigned long end = PHYS_PFN(range_end); | |
| 92 | + unsigned long start = PFN_UP(range_start); | |
| 93 | + unsigned long end = PFN_DOWN(range_end); | |
| 94 | 94 | |
| 95 | 95 | /* Ignore complete lowmem entries */ |
| 96 | 96 | if (end <= max_low) |
| @@ -773,8 +773,7 @@ static void __device_link_del(struct kref *kref) · 772 unmodified lines | ||
| 773 | 773 | dev_dbg(link->consumer, "Dropping the link to %s\n", |
| 774 | 774 | dev_name(link->supplier)); |
| 775 | 775 | |
| 776 | − if (link->flags & DL_FLAG_PM_RUNTIME) | |
| 777 | − pm_runtime_drop_link(link->consumer); | |
| 776 | + pm_runtime_drop_link(link); | |
| 778 | 777 | |
| 779 | 778 | list_del_rcu(&link->s_node); |
| 780 | 779 | list_del_rcu(&link->c_node); |
| @@ -788,8 +787,7 @@ static void __device_link_del(struct kref *kref) · 7 unmodified lines | ||
| 788 | 787 | dev_info(link->consumer, "Dropping the link to %s\n", |
| 789 | 788 | dev_name(link->supplier)); |
| 790 | 789 | |
| 791 | − if (link->flags & DL_FLAG_PM_RUNTIME) | |
| 792 | − pm_runtime_drop_link(link->consumer); | |
| 790 | + pm_runtime_drop_link(link); | |
| 793 | 791 | |
| 794 | 792 | list_del(&link->s_node); |
| 795 | 793 | list_del(&link->c_node); |
| @@ -1117,6 +1117,8 @@ static void __device_release_driver(struct device *dev, struct device *parent) · 1116 unmodified lines | ||
| 1117 | 1117 | |
| 1118 | 1118 | drv = dev->driver; |
| 1119 | 1119 | if (drv) { |
| 1120 | + pm_runtime_get_sync(dev); | |
| 1121 | + | |
| 1120 | 1122 | while (device_links_busy(dev)) { |
| 1121 | 1123 | __device_driver_unlock(dev, parent); |
| 1122 | 1124 | |
| @@ -1128,13 +1130,12 @@ static void __device_release_driver(struct device *dev, struct device *parent) · 5 unmodified lines | ||
| 1128 | 1130 | * have released the driver successfully while this one |
| 1129 | 1131 | * was waiting, so check for that. |
| 1130 | 1132 | */ |
| 1131 | − if (dev->driver != drv) | |
| 1133 | + if (dev->driver != drv) { | |
| 1134 | + pm_runtime_put(dev); | |
| 1132 | 1135 | return; |
| 1136 | + } | |
| 1133 | 1137 | } |
| 1134 | 1138 | |
| 1135 | − pm_runtime_get_sync(dev); | |
| 1136 | − pm_runtime_clean_up_links(dev); | |
| 1137 | − | |
| 1138 | 1139 | driver_sysfs_remove(dev); |
| 1139 | 1140 | |
| 1140 | 1141 | if (dev->bus) |
| @@ -1642,42 +1642,6 @@ void pm_runtime_remove(struct device *dev) · 1641 unmodified lines | ||
| 1642 | 1642 | pm_runtime_reinit(dev); |
| 1643 | 1643 | } |
| 1644 | 1644 | |
| 1645 | −/** | |
| 1646 | − * pm_runtime_clean_up_links - Prepare links to consumers for driver removal. | |
| 1647 | − * @dev: Device whose driver is going to be removed. | |
| 1648 | − * | |
| 1649 | − * Check links from this device to any consumers and if any of them have active | |
| 1650 | − * runtime PM references to the device, drop the usage counter of the device | |
| 1651 | − * (as many times as needed). | |
| 1652 | − * | |
| 1653 | − * Links with the DL_FLAG_MANAGED flag unset are ignored. | |
| 1654 | − * | |
| 1655 | − * Since the device is guaranteed to be runtime-active at the point this is | |
| 1656 | − * called, nothing else needs to be done here. | |
| 1657 | − * | |
| 1658 | − * Moreover, this is called after device_links_busy() has returned 'false', so | |
| 1659 | − * the status of each link is guaranteed to be DL_STATE_SUPPLIER_UNBIND and | |
| 1660 | − * therefore rpm_active can't be manipulated concurrently. | |
| 1661 | − */ | |
| 1662 | −void pm_runtime_clean_up_links(struct device *dev) | |
| 1663 | −{ | |
| 1664 | − struct device_link *link; | |
| 1665 | − int idx; | |
| 1666 | − | |
| 1667 | − idx = device_links_read_lock(); | |
| 1668 | − | |
| 1669 | − list_for_each_entry_rcu(link, &dev->links.consumers, s_node, | |
| 1670 | − device_links_read_lock_held()) { | |
| 1671 | − if (!(link->flags & DL_FLAG_MANAGED)) | |
| 1672 | − continue; | |
| 1673 | − | |
| 1674 | − while (refcount_dec_not_one(&link->rpm_active)) | |
| 1675 | − pm_runtime_put_noidle(dev); | |
| 1676 | − } | |
| 1677 | − | |
| 1678 | − device_links_read_unlock(idx); | |
| 1679 | −} | |
| 1680 | − | |
| 1681 | 1645 | /** |
| 1682 | 1646 | * pm_runtime_get_suppliers - Resume and reference-count supplier devices. |
| 1683 | 1647 | * @dev: Consumer device. |
| @@ -1729,7 +1693,7 @@ void pm_runtime_new_link(struct device *dev) · 45 unmodified lines | ||
| 1729 | 1693 | spin_unlock_irq(&dev->power.lock); |
| 1730 | 1694 | } |
| 1731 | 1695 | |
| 1732 | −void pm_runtime_drop_link(struct device *dev) | |
| 1696 | +static void pm_runtime_drop_link_count(struct device *dev) | |
| 1733 | 1697 | { |
| 1734 | 1698 | spin_lock_irq(&dev->power.lock); |
| 1735 | 1699 | WARN_ON(dev->power.links_count == 0); |
| @@ -1737,6 +1701,25 @@ void pm_runtime_drop_link(struct device *dev) · 1 unmodified line | ||
| 1737 | 1701 | spin_unlock_irq(&dev->power.lock); |
| 1738 | 1702 | } |
| 1739 | 1703 | |
| 1704 | +/** | |
| 1705 | + * pm_runtime_drop_link - Prepare for device link removal. | |
| 1706 | + * @link: Device link going away. | |
| 1707 | + * | |
| 1708 | + * Drop the link count of the consumer end of @link and decrement the supplier | |
| 1709 | + * device's runtime PM usage counter as many times as needed to drop all of the | |
| 1710 | + * PM runtime reference to it from the consumer. | |
| 1711 | + */ | |
| 1712 | +void pm_runtime_drop_link(struct device_link *link) | |
| 1713 | +{ | |
| 1714 | + if (!(link->flags & DL_FLAG_PM_RUNTIME)) | |
| 1715 | + return; | |
| 1716 | + | |
| 1717 | + pm_runtime_drop_link_count(link->consumer); | |
| 1718 | + | |
| 1719 | + while (refcount_dec_not_one(&link->rpm_active)) | |
| 1720 | + pm_runtime_put(link->supplier); | |
| 1721 | +} | |
| 1722 | + | |
| 1740 | 1723 | static bool pm_runtime_need_not_resume(struct device *dev) |
| 1741 | 1724 | { |
| 1742 | 1725 | return atomic_read(&dev->power.usage_count) <= 1 && |
| @@ -47,7 +47,7 @@ struct nullb_device { · 46 unmodified lines | ||
| 47 | 47 | unsigned int nr_zones_closed; |
| 48 | 48 | struct blk_zone *zones; |
| 49 | 49 | sector_t zone_size_sects; |
| 50 | − spinlock_t zone_dev_lock; | |
| 50 | + spinlock_t zone_lock; | |
| 51 | 51 | unsigned long *zone_locks; |
| 52 | 52 | |
| 53 | 53 | unsigned long size; /* device size in MB */ |
| @@ -46,11 +46,20 @@ int null_init_zoned_dev(struct nullb_device *dev, struct request_queue *q) · 45 unmodified lines | ||
| 46 | 46 | if (!dev->zones) |
| 47 | 47 | return -ENOMEM; |
| 48 | 48 | |
| 49 | − spin_lock_init(&dev->zone_dev_lock); | |
| 50 | − dev->zone_locks = bitmap_zalloc(dev->nr_zones, GFP_KERNEL); | |
| 51 | − if (!dev->zone_locks) { | |
| 52 | − kvfree(dev->zones); | |
| 53 | − return -ENOMEM; | |
| 49 | + /* | |
| 50 | + * With memory backing, the zone_lock spinlock needs to be temporarily | |
| 51 | + * released to avoid scheduling in atomic context. To guarantee zone | |
| 52 | + * information protection, use a bitmap to lock zones with | |
| 53 | + * wait_on_bit_lock_io(). Sleeping on the lock is OK as memory backing | |
| 54 | + * implies that the queue is marked with BLK_MQ_F_BLOCKING. | |
| 55 | + */ | |
| 56 | + spin_lock_init(&dev->zone_lock); | |
| 57 | + if (dev->memory_backed) { | |
| 58 | + dev->zone_locks = bitmap_zalloc(dev->nr_zones, GFP_KERNEL); | |
| 59 | + if (!dev->zone_locks) { | |
| 60 | + kvfree(dev->zones); | |
| 61 | + return -ENOMEM; | |
| 62 | + } | |
| 54 | 63 | } |
| 55 | 64 | |
| 56 | 65 | if (dev->zone_nr_conv >= dev->nr_zones) { |
| @@ -137,12 +146,17 @@ void null_free_zoned_dev(struct nullb_device *dev) · 80 unmodified lines | ||
| 137 | 146 | |
| 138 | 147 | static inline void null_lock_zone(struct nullb_device *dev, unsigned int zno) |
| 139 | 148 | { |
| 140 | − wait_on_bit_lock_io(dev->zone_locks, zno, TASK_UNINTERRUPTIBLE); | |
| 149 | + if (dev->memory_backed) | |
| 150 | + wait_on_bit_lock_io(dev->zone_locks, zno, TASK_UNINTERRUPTIBLE); | |
| 151 | + spin_lock_irq(&dev->zone_lock); | |
| 141 | 152 | } |
| 142 | 153 | |
| 143 | 154 | static inline void null_unlock_zone(struct nullb_device *dev, unsigned int zno) |
| 144 | 155 | { |
| 145 | − clear_and_wake_up_bit(zno, dev->zone_locks); | |
| 156 | + spin_unlock_irq(&dev->zone_lock); | |
| 157 | + | |
| 158 | + if (dev->memory_backed) | |
| 159 | + clear_and_wake_up_bit(zno, dev->zone_locks); | |
| 146 | 160 | } |
| 147 | 161 | |
| 148 | 162 | int null_report_zones(struct gendisk *disk, sector_t sector, |
| @@ -322,7 +336,6 @@ static blk_status_t null_zone_write(struct nullb_cmd *cmd, sector_t sector, · 173 unmodified lines | ||
| 322 | 336 | return null_process_cmd(cmd, REQ_OP_WRITE, sector, nr_sectors); |
| 323 | 337 | |
| 324 | 338 | null_lock_zone(dev, zno); |
| 325 | − spin_lock(&dev->zone_dev_lock); | |
| 326 | 339 | |
| 327 | 340 | switch (zone->cond) { |
| 328 | 341 | case BLK_ZONE_COND_FULL: |
| @@ -375,9 +388,17 @@ static blk_status_t null_zone_write(struct nullb_cmd *cmd, sector_t sector, · 46 unmodified lines | ||
| 375 | 388 | if (zone->cond != BLK_ZONE_COND_EXP_OPEN) |
| 376 | 389 | zone->cond = BLK_ZONE_COND_IMP_OPEN; |
| 377 | 390 | |
| 378 | − spin_unlock(&dev->zone_dev_lock); | |
| 391 | + /* | |
| 392 | + * Memory backing allocation may sleep: release the zone_lock spinlock | |
| 393 | + * to avoid scheduling in atomic context. Zone operation atomicity is | |
| 394 | + * still guaranteed through the zone_locks bitmap. | |
| 395 | + */ | |
| 396 | + if (dev->memory_backed) | |
| 397 | + spin_unlock_irq(&dev->zone_lock); | |
| 379 | 398 | ret = null_process_cmd(cmd, REQ_OP_WRITE, sector, nr_sectors); |
| 380 | − spin_lock(&dev->zone_dev_lock); | |
| 399 | + if (dev->memory_backed) | |
| 400 | + spin_lock_irq(&dev->zone_lock); | |
| 401 | + | |
| 381 | 402 | if (ret != BLK_STS_OK) |
| 382 | 403 | goto unlock; |
| 383 | 404 | |
| @@ -392,7 +413,6 @@ static blk_status_t null_zone_write(struct nullb_cmd *cmd, sector_t sector, · 8 unmodified lines | ||
| 392 | 413 | ret = BLK_STS_OK; |
| 393 | 414 | |
| 394 | 415 | unlock: |
| 395 | − spin_unlock(&dev->zone_dev_lock); | |
| 396 | 416 | null_unlock_zone(dev, zno); |
| 397 | 417 | |
| 398 | 418 | return ret; |
| @@ -516,9 +536,7 @@ static blk_status_t null_zone_mgmt(struct nullb_cmd *cmd, enum req_opf op, · 117 unmodified lines | ||
| 516 | 536 | null_lock_zone(dev, i); |
| 517 | 537 | zone = &dev->zones[i]; |
| 518 | 538 | if (zone->cond != BLK_ZONE_COND_EMPTY) { |
| 519 | − spin_lock(&dev->zone_dev_lock); | |
| 520 | 539 | null_reset_zone(dev, zone); |
| 521 | − spin_unlock(&dev->zone_dev_lock); | |
| 522 | 540 | trace_nullb_zone_op(cmd, i, zone->cond); |
| 523 | 541 | } |
| 524 | 542 | null_unlock_zone(dev, i); |
| @@ -530,7 +548,6 @@ static blk_status_t null_zone_mgmt(struct nullb_cmd *cmd, enum req_opf op, · 5 unmodified lines | ||
| 530 | 548 | zone = &dev->zones[zone_no]; |
| 531 | 549 | |
| 532 | 550 | null_lock_zone(dev, zone_no); |
| 533 | − spin_lock(&dev->zone_dev_lock); | |
| 534 | 551 | |
| 535 | 552 | switch (op) { |
| 536 | 553 | case REQ_OP_ZONE_RESET: |
| @@ -550,8 +567,6 @@ static blk_status_t null_zone_mgmt(struct nullb_cmd *cmd, enum req_opf op, · 13 unmodified lines | ||
| 550 | 567 | break; |
| 551 | 568 | } |
| 552 | 569 | |
| 553 | − spin_unlock(&dev->zone_dev_lock); | |
| 554 | − | |
| 555 | 570 | if (ret == BLK_STS_OK) |
| 556 | 571 | trace_nullb_zone_op(cmd, zone_no, zone->cond); |
| 557 | 572 | |
| @@ -41,6 +41,11 @@ int tpm_read_log_efi(struct tpm_chip *chip) · 40 unmodified lines | ||
| 41 | 41 | log_size = log_tbl->size; |
| 42 | 42 | memunmap(log_tbl); |
| 43 | 43 | |
| 44 | + if (!log_size) { | |
| 45 | + pr_warn("UEFI TPM log area empty\n"); | |
| 46 | + return -EIO; | |
| 47 | + } | |
| 48 | + | |
| 44 | 49 | log_tbl = memremap(efi.tpm_log, sizeof(*log_tbl) + log_size, |
| 45 | 50 | MEMREMAP_WB); |
| 46 | 51 | if (!log_tbl) { |
| @@ -27,6 +27,7 @@ · 26 unmodified lines | ||
| 27 | 27 | #include <linux/of.h> |
| 28 | 28 | #include <linux/of_device.h> |
| 29 | 29 | #include <linux/kernel.h> |
| 30 | +#include <linux/dmi.h> | |
| 30 | 31 | #include "tpm.h" |
| 31 | 32 | #include "tpm_tis_core.h" |
| 32 | 33 | |
| @@ -49,8 +50,8 @@ static inline struct tpm_tis_tcg_phy *to_tpm_tis_tcg_phy(struct tpm_tis_data *da · 16 unmodified lines | ||
| 49 | 50 | return container_of(data, struct tpm_tis_tcg_phy, priv); |
| 50 | 51 | } |
| 51 | 52 | |
| 52 | −static bool interrupts = true; | |
| 53 | −module_param(interrupts, bool, 0444); | |
| 53 | +static int interrupts = -1; | |
| 54 | +module_param(interrupts, int, 0444); | |
| 54 | 55 | MODULE_PARM_DESC(interrupts, "Enable interrupts"); |
| 55 | 56 | |
| 56 | 57 | static bool itpm; |
| @@ -63,6 +64,28 @@ module_param(force, bool, 0444); · 6 unmodified lines | ||
| 63 | 64 | MODULE_PARM_DESC(force, "Force device probe rather than using ACPI entry"); |
| 64 | 65 | #endif |
| 65 | 66 | |
| 67 | +static int tpm_tis_disable_irq(const struct dmi_system_id *d) | |
| 68 | +{ | |
| 69 | + if (interrupts == -1) { | |
| 70 | + pr_notice("tpm_tis: %s detected: disabling interrupts.\n", d->ident); | |
| 71 | + interrupts = 0; | |
| 72 | + } | |
| 73 | + | |
| 74 | + return 0; | |
| 75 | +} | |
| 76 | + | |
| 77 | +static const struct dmi_system_id tpm_tis_dmi_table[] = { | |
| 78 | + { | |
| 79 | + .callback = tpm_tis_disable_irq, | |
| 80 | + .ident = "ThinkPad T490s", | |
| 81 | + .matches = { | |
| 82 | + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | |
| 83 | + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T490s"), | |
| 84 | + }, | |
| 85 | + }, | |
| 86 | + {} | |
| 87 | +}; | |
| 88 | + | |
| 66 | 89 | #if defined(CONFIG_PNP) && defined(CONFIG_ACPI) |
| 67 | 90 | static int has_hid(struct acpi_device *dev, const char *hid) |
| 68 | 91 | { |
| @@ -192,6 +215,8 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info) · 123 unmodified lines | ||
| 192 | 215 | int irq = -1; |
| 193 | 216 | int rc; |
| 194 | 217 | |
| 218 | + dmi_check_system(tpm_tis_dmi_table); | |
| 219 | + | |
| 195 | 220 | rc = check_acpi_tpm2(dev); |
| 196 | 221 | if (rc) |
| 197 | 222 | return rc; |
| @@ -7,7 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | * |
| 8 | 8 | * This file add support for MD5 and SHA1/SHA224/SHA256/SHA384/SHA512. |
| 9 | 9 | * |
| 10 | − * You could find the datasheet in Documentation/arm/sunxi/README | |
| 10 | + * You could find the datasheet in Documentation/arm/sunxi.rst | |
| 11 | 11 | */ |
| 12 | 12 | #include <linux/dma-mapping.h> |
| 13 | 13 | #include <linux/pm_runtime.h> |
| @@ -7,7 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | * |
| 8 | 8 | * This file handle the PRNG |
| 9 | 9 | * |
| 10 | − * You could find a link for the datasheet in Documentation/arm/sunxi/README | |
| 10 | + * You could find a link for the datasheet in Documentation/arm/sunxi.rst | |
| 11 | 11 | */ |
| 12 | 12 | #include "sun8i-ce.h" |
| 13 | 13 | #include <linux/dma-mapping.h> |
| @@ -7,7 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | * |
| 8 | 8 | * This file handle the TRNG |
| 9 | 9 | * |
| 10 | − * You could find a link for the datasheet in Documentation/arm/sunxi/README | |
| 10 | + * You could find a link for the datasheet in Documentation/arm/sunxi.rst | |
| 11 | 11 | */ |
| 12 | 12 | #include "sun8i-ce.h" |
| 13 | 13 | #include <linux/dma-mapping.h> |
| @@ -55,7 +55,8 @@ amdgpu-y += amdgpu_device.o amdgpu_kms.o \ · 54 unmodified lines | ||
| 55 | 55 | amdgpu_vf_error.o amdgpu_sched.o amdgpu_debugfs.o amdgpu_ids.o \ |
| 56 | 56 | amdgpu_gmc.o amdgpu_mmhub.o amdgpu_xgmi.o amdgpu_csa.o amdgpu_ras.o amdgpu_vm_cpu.o \ |
| 57 | 57 | amdgpu_vm_sdma.o amdgpu_discovery.o amdgpu_ras_eeprom.o amdgpu_nbio.o \ |
| 58 | − amdgpu_umc.o smu_v11_0_i2c.o amdgpu_fru_eeprom.o amdgpu_rap.o | |
| 58 | + amdgpu_umc.o smu_v11_0_i2c.o amdgpu_fru_eeprom.o amdgpu_rap.o \ | |
| 59 | + amdgpu_fw_attestation.o | |
| 59 | 60 | |
| 60 | 61 | amdgpu-$(CONFIG_PERF_EVENTS) += amdgpu_pmu.o |
| 61 | 62 | |
| @@ -69,7 +70,8 @@ amdgpu-$(CONFIG_DRM_AMDGPU_SI)+= si.o gmc_v6_0.o gfx_v6_0.o si_ih.o si_dma.o dce · 7 unmodified lines | ||
| 69 | 70 | amdgpu-y += \ |
| 70 | 71 | vi.o mxgpu_vi.o nbio_v6_1.o soc15.o emu_soc.o mxgpu_ai.o nbio_v7_0.o vega10_reg_init.o \ |
| 71 | 72 | vega20_reg_init.o nbio_v7_4.o nbio_v2_3.o nv.o navi10_reg_init.o navi14_reg_init.o \ |
| 72 | − arct_reg_init.o navi12_reg_init.o mxgpu_nv.o sienna_cichlid_reg_init.o | |
| 73 | + arct_reg_init.o navi12_reg_init.o mxgpu_nv.o sienna_cichlid_reg_init.o vangogh_reg_init.o \ | |
| 74 | + nbio_v7_2.o dimgrey_cavefish_reg_init.o | |
| 73 | 75 | |
| 74 | 76 | # add DF block |
| 75 | 77 | amdgpu-y += \ |
| @@ -81,7 +83,7 @@ amdgpu-y += \ · 5 unmodified lines | ||
| 81 | 83 | gmc_v7_0.o \ |
| 82 | 84 | gmc_v8_0.o \ |
| 83 | 85 | gfxhub_v1_0.o mmhub_v1_0.o gmc_v9_0.o gfxhub_v1_1.o mmhub_v9_4.o \ |
| 84 | − gfxhub_v2_0.o mmhub_v2_0.o gmc_v10_0.o gfxhub_v2_1.o | |
| 86 | + gfxhub_v2_0.o mmhub_v2_0.o gmc_v10_0.o gfxhub_v2_1.o mmhub_v2_3.o | |
| 85 | 87 | |
| 86 | 88 | # add UMC block |
| 87 | 89 | amdgpu-y += \ |
| @@ -623,6 +623,8 @@ struct amdgpu_asic_funcs { · 622 unmodified lines | ||
| 623 | 623 | bool (*supports_baco)(struct amdgpu_device *adev); |
| 624 | 624 | /* pre asic_init quirks */ |
| 625 | 625 | void (*pre_asic_init)(struct amdgpu_device *adev); |
| 626 | + /* enter/exit umd stable pstate */ | |
| 627 | + int (*update_umd_stable_pstate)(struct amdgpu_device *adev, bool enter); | |
| 626 | 628 | }; |
| 627 | 629 | |
| 628 | 630 | /* |
| @@ -723,6 +725,45 @@ struct amd_powerplay { · 94 unmodified lines | ||
| 723 | 725 | const struct amd_pm_funcs *pp_funcs; |
| 724 | 726 | }; |
| 725 | 727 | |
| 728 | +/* polaris10 kickers */ | |
| 729 | +#define ASICID_IS_P20(did, rid) (((did == 0x67DF) && \ | |
| 730 | + ((rid == 0xE3) || \ | |
| 731 | + (rid == 0xE4) || \ | |
| 732 | + (rid == 0xE5) || \ | |
| 733 | + (rid == 0xE7) || \ | |
| 734 | + (rid == 0xEF))) || \ | |
| 735 | + ((did == 0x6FDF) && \ | |
| 736 | + ((rid == 0xE7) || \ | |
| 737 | + (rid == 0xEF) || \ | |
| 738 | + (rid == 0xFF)))) | |
| 739 | + | |
| 740 | +#define ASICID_IS_P30(did, rid) ((did == 0x67DF) && \ | |
| 741 | + ((rid == 0xE1) || \ | |
| 742 | + (rid == 0xF7))) | |
| 743 | + | |
| 744 | +/* polaris11 kickers */ | |
| 745 | +#define ASICID_IS_P21(did, rid) (((did == 0x67EF) && \ | |
| 746 | + ((rid == 0xE0) || \ | |
| 747 | + (rid == 0xE5))) || \ | |
| 748 | + ((did == 0x67FF) && \ | |
| 749 | + ((rid == 0xCF) || \ | |
| 750 | + (rid == 0xEF) || \ | |
| 751 | + (rid == 0xFF)))) | |
| 752 | + | |
| 753 | +#define ASICID_IS_P31(did, rid) ((did == 0x67EF) && \ | |
| 754 | + ((rid == 0xE2))) | |
| 755 | + | |
| 756 | +/* polaris12 kickers */ | |
| 757 | +#define ASICID_IS_P23(did, rid) (((did == 0x6987) && \ | |
| 758 | + ((rid == 0xC0) || \ | |
| 759 | + (rid == 0xC1) || \ | |
| 760 | + (rid == 0xC3) || \ | |
| 761 | + (rid == 0xC7))) || \ | |
| 762 | + ((did == 0x6981) && \ | |
| 763 | + ((rid == 0x00) || \ | |
| 764 | + (rid == 0x01) || \ | |
| 765 | + (rid == 0x10)))) | |
| 766 | + | |
| 726 | 767 | #define AMDGPU_RESET_MAGIC_NUM 64 |
| 727 | 768 | #define AMDGPU_MAX_DF_PERFMONS 4 |
| 728 | 769 | struct amdgpu_device { |
| @@ -1165,6 +1206,8 @@ int emu_soc_asic_init(struct amdgpu_device *adev); · 436 unmodified lines | ||
| 1165 | 1206 | #define amdgpu_asic_get_pcie_replay_count(adev) ((adev)->asic_funcs->get_pcie_replay_count((adev))) |
| 1166 | 1207 | #define amdgpu_asic_supports_baco(adev) (adev)->asic_funcs->supports_baco((adev)) |
| 1167 | 1208 | #define amdgpu_asic_pre_asic_init(adev) (adev)->asic_funcs->pre_asic_init((adev)) |
| 1209 | +#define amdgpu_asic_update_umd_stable_pstate(adev, enter) \ | |
| 1210 | + ((adev)->asic_funcs->update_umd_stable_pstate ? (adev)->asic_funcs->update_umd_stable_pstate((adev), (enter)) : 0) | |
| 1168 | 1211 | |
| 1169 | 1212 | #define amdgpu_inc_vram_lost(adev) atomic_inc(&((adev)->vram_lost_counter)); |
| 1170 | 1213 | |
| @@ -1294,19 +1337,6 @@ bool amdgpu_device_load_pci_state(struct pci_dev *pdev); · 123 unmodified lines | ||
| 1294 | 1337 | |
| 1295 | 1338 | #include "amdgpu_object.h" |
| 1296 | 1339 | |
| 1297 | −/* used by df_v3_6.c and amdgpu_pmu.c */ | |
| 1298 | −#define AMDGPU_PMU_ATTR(_name, _object) \ | |
| 1299 | −static ssize_t \ | |
| 1300 | −_name##_show(struct device *dev, \ | |
| 1301 | − struct device_attribute *attr, \ | |
| 1302 | − char *page) \ | |
| 1303 | −{ \ | |
| 1304 | − BUILD_BUG_ON(sizeof(_object) >= PAGE_SIZE - 1); \ | |
| 1305 | − return sprintf(page, _object "\n"); \ | |
| 1306 | −} \ | |
| 1307 | − \ | |
| 1308 | −static struct device_attribute pmu_attr_##_name = __ATTR_RO(_name) | |
| 1309 | − | |
| 1310 | 1340 | static inline bool amdgpu_is_tmz(struct amdgpu_device *adev) |
| 1311 | 1341 | { |
| 1312 | 1342 | return adev->gmc.tmz_enabled; |
| @@ -36,17 +36,17 @@ · 35 unmodified lines | ||
| 36 | 36 | |
| 37 | 37 | #include "acp_gfx_if.h" |
| 38 | 38 | |
| 39 | −#define ACP_TILE_ON_MASK 0x03 | |
| 40 | −#define ACP_TILE_OFF_MASK 0x02 | |
| 41 | −#define ACP_TILE_ON_RETAIN_REG_MASK 0x1f | |
| 42 | −#define ACP_TILE_OFF_RETAIN_REG_MASK 0x20 | |
| 39 | +#define ACP_TILE_ON_MASK 0x03 | |
| 40 | +#define ACP_TILE_OFF_MASK 0x02 | |
| 41 | +#define ACP_TILE_ON_RETAIN_REG_MASK 0x1f | |
| 42 | +#define ACP_TILE_OFF_RETAIN_REG_MASK 0x20 | |
| 43 | 43 | |
| 44 | −#define ACP_TILE_P1_MASK 0x3e | |
| 45 | −#define ACP_TILE_P2_MASK 0x3d | |
| 46 | −#define ACP_TILE_DSP0_MASK 0x3b | |
| 47 | −#define ACP_TILE_DSP1_MASK 0x37 | |
| 44 | +#define ACP_TILE_P1_MASK 0x3e | |
| 45 | +#define ACP_TILE_P2_MASK 0x3d | |
| 46 | +#define ACP_TILE_DSP0_MASK 0x3b | |
| 47 | +#define ACP_TILE_DSP1_MASK 0x37 | |
| 48 | 48 | |
| 49 | −#define ACP_TILE_DSP2_MASK 0x2f | |
| 49 | +#define ACP_TILE_DSP2_MASK 0x2f | |
| 50 | 50 | |
| 51 | 51 | #define ACP_DMA_REGS_END 0x146c0 |
| 52 | 52 | #define ACP_I2S_PLAY_REGS_START 0x14840 |
| @@ -75,8 +75,8 @@ · 22 unmodified lines | ||
| 75 | 75 | #define mmACP_CONTROL 0x5131 |
| 76 | 76 | #define mmACP_STATUS 0x5133 |
| 77 | 77 | #define mmACP_SOFT_RESET 0x5134 |
| 78 | −#define ACP_CONTROL__ClkEn_MASK 0x1 | |
| 79 | −#define ACP_SOFT_RESET__SoftResetAud_MASK 0x100 | |
| 78 | +#define ACP_CONTROL__ClkEn_MASK 0x1 | |
| 79 | +#define ACP_SOFT_RESET__SoftResetAud_MASK 0x100 | |
| 80 | 80 | #define ACP_SOFT_RESET__SoftResetAudDone_MASK 0x1000000 |
| 81 | 81 | #define ACP_CLOCK_EN_TIME_OUT_VALUE 0x000000FF |
| 82 | 82 | #define ACP_SOFT_RESET_DONE_TIME_OUT_VALUE 0x000000FF |
| @@ -390,23 +390,17 @@ void amdgpu_amdkfd_get_local_mem_info(struct kgd_dev *kgd, · 389 unmodified lines | ||
| 390 | 390 | struct kfd_local_mem_info *mem_info) |
| 391 | 391 | { |
| 392 | 392 | struct amdgpu_device *adev = (struct amdgpu_device *)kgd; |
| 393 | − uint64_t address_mask = adev->dev->dma_mask ? ~*adev->dev->dma_mask : | |
| 394 | − ~((1ULL << 32) - 1); | |
| 395 | − resource_size_t aper_limit = adev->gmc.aper_base + adev->gmc.aper_size; | |
| 396 | 393 | |
| 397 | 394 | memset(mem_info, 0, sizeof(*mem_info)); |
| 398 | − if (!(adev->gmc.aper_base & address_mask || aper_limit & address_mask)) { | |
| 399 | − mem_info->local_mem_size_public = adev->gmc.visible_vram_size; | |
| 400 | − mem_info->local_mem_size_private = adev->gmc.real_vram_size - | |
| 401 | − adev->gmc.visible_vram_size; | |
| 402 | − } else { | |
| 403 | − mem_info->local_mem_size_public = 0; | |
| 404 | − mem_info->local_mem_size_private = adev->gmc.real_vram_size; | |
| 405 | − } | |
| 395 | + | |
| 396 | + mem_info->local_mem_size_public = adev->gmc.visible_vram_size; | |
| 397 | + mem_info->local_mem_size_private = adev->gmc.real_vram_size - | |
| 398 | + adev->gmc.visible_vram_size; | |
| 399 | + | |
| 406 | 400 | mem_info->vram_width = adev->gmc.vram_width; |
| 407 | 401 | |
| 408 | − pr_debug("Address base: %pap limit %pap public 0x%llx private 0x%llx\n", | |
| 409 | − &adev->gmc.aper_base, &aper_limit, | |
| 402 | + pr_debug("Address base: %pap public 0x%llx private 0x%llx\n", | |
| 403 | + &adev->gmc.aper_base, | |
| 410 | 404 | mem_info->local_mem_size_public, |
| 411 | 405 | mem_info->local_mem_size_private); |
| 412 | 406 | |
| @@ -648,6 +642,13 @@ void amdgpu_amdkfd_set_compute_idle(struct kgd_dev *kgd, bool idle) · 235 unmodified lines | ||
| 648 | 642 | { |
| 649 | 643 | struct amdgpu_device *adev = (struct amdgpu_device *)kgd; |
| 650 | 644 | |
| 645 | + /* Temp workaround to fix the soft hang observed in certain compute | |
| 646 | + * applications if GFXOFF is enabled. | |
| 647 | + */ | |
| 648 | + if (adev->asic_type == CHIP_SIENNA_CICHLID) { | |
| 649 | + pr_debug("GFXOFF is %s\n", idle ? "enabled" : "disabled"); | |
| 650 | + amdgpu_gfx_off_ctrl(adev, idle); | |
| 651 | + } | |
| 651 | 652 | amdgpu_dpm_switch_power_profile(adev, |
| 652 | 653 | PP_SMC_POWER_PROFILE_COMPUTE, |
| 653 | 654 | !idle); |
| @@ -304,4 +304,5 @@ const struct kfd2kgd_calls arcturus_kfd2kgd = { · 303 unmodified lines | ||
| 304 | 304 | kgd_gfx_v9_get_atc_vmid_pasid_mapping_info, |
| 305 | 305 | .set_vm_context_page_table_base = |
| 306 | 306 | kgd_gfx_v9_set_vm_context_page_table_base, |
| 307 | + .get_cu_occupancy = kgd_gfx_v9_get_cu_occupancy | |
| 307 | 308 | }; |
| @@ -799,7 +799,7 @@ static void get_wave_count(struct amdgpu_device *adev, int queue_idx, · 798 unmodified lines | ||
| 799 | 799 | * |
| 800 | 800 | * Reading registers referenced above involves programming GRBM appropriately |
| 801 | 801 | */ |
| 802 | −static void kgd_gfx_v9_get_cu_occupancy(struct kgd_dev *kgd, int pasid, | |
| 802 | +void kgd_gfx_v9_get_cu_occupancy(struct kgd_dev *kgd, int pasid, | |
| 803 | 803 | int *pasid_wave_cnt, int *max_waves_per_cu) |
| 804 | 804 | { |
| 805 | 805 | int qidx; |
| @@ -63,3 +63,5 @@ bool kgd_gfx_v9_get_atc_vmid_pasid_mapping_info(struct kgd_dev *kgd, · 62 unmodified lines | ||
| 63 | 63 | |
| 64 | 64 | void kgd_gfx_v9_set_vm_context_page_table_base(struct kgd_dev *kgd, |
| 65 | 65 | uint32_t vmid, uint64_t page_table_base); |
| 66 | +void kgd_gfx_v9_get_cu_occupancy(struct kgd_dev *kgd, int pasid, | |
| 67 | + int *pasid_wave_cnt, int *max_waves_per_cu); | |
| @@ -239,8 +239,7 @@ static int amdgpu_amdkfd_remove_eviction_fence(struct amdgpu_bo *bo, · 238 unmodified lines | ||
| 239 | 239 | if (!old) |
| 240 | 240 | return 0; |
| 241 | 241 | |
| 242 | − new = kmalloc(offsetof(typeof(*new), shared[old->shared_max]), | |
| 243 | − GFP_KERNEL); | |
| 242 | + new = kmalloc(struct_size(new, shared, old->shared_max), GFP_KERNEL); | |
| 244 | 243 | if (!new) |
| 245 | 244 | return -ENOMEM; |
| 246 | 245 | |
| @@ -1115,19 +1114,19 @@ void amdgpu_amdkfd_gpuvm_destroy_process_vm(struct kgd_dev *kgd, void *vm) · 868 unmodified lines | ||
| 1115 | 1114 | void amdgpu_amdkfd_gpuvm_release_process_vm(struct kgd_dev *kgd, void *vm) |
| 1116 | 1115 | { |
| 1117 | 1116 | struct amdgpu_device *adev = get_amdgpu_device(kgd); |
| 1118 | − struct amdgpu_vm *avm = (struct amdgpu_vm *)vm; | |
| 1117 | + struct amdgpu_vm *avm = (struct amdgpu_vm *)vm; | |
| 1119 | 1118 | |
| 1120 | 1119 | if (WARN_ON(!kgd || !vm)) |
| 1121 | − return; | |
| 1120 | + return; | |
| 1122 | 1121 | |
| 1123 | − pr_debug("Releasing process vm %p\n", vm); | |
| 1122 | + pr_debug("Releasing process vm %p\n", vm); | |
| 1124 | 1123 | |
| 1125 | − /* The original pasid of amdgpu vm has already been | |
| 1126 | − * released during making a amdgpu vm to a compute vm | |
| 1127 | − * The current pasid is managed by kfd and will be | |
| 1128 | − * released on kfd process destroy. Set amdgpu pasid | |
| 1129 | − * to 0 to avoid duplicate release. | |
| 1130 | − */ | |
| 1124 | + /* The original pasid of amdgpu vm has already been | |
| 1125 | + * released during making a amdgpu vm to a compute vm | |
| 1126 | + * The current pasid is managed by kfd and will be | |
| 1127 | + * released on kfd process destroy. Set amdgpu pasid | |
| 1128 | + * to 0 to avoid duplicate release. | |
| 1129 | + */ | |
| 1131 | 1130 | amdgpu_vm_release_compute(adev, avm); |
| 1132 | 1131 | } |
| 1133 | 1132 | |
| @@ -1288,7 +1287,7 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu( · 154 unmodified lines | ||
| 1288 | 1287 | struct ttm_validate_buffer *bo_list_entry; |
| 1289 | 1288 | unsigned int mapped_to_gpu_memory; |
| 1290 | 1289 | int ret; |
| 1291 | − bool is_imported = 0; | |
| 1290 | + bool is_imported = false; | |
| 1292 | 1291 | |
| 1293 | 1292 | mutex_lock(&mem->lock); |
| 1294 | 1293 | mapped_to_gpu_memory = mem->mapped_to_gpu_memory; |
| @@ -1695,7 +1694,7 @@ int amdgpu_amdkfd_gpuvm_import_dmabuf(struct kgd_dev *kgd, · 400 unmodified lines | ||
| 1695 | 1694 | |
| 1696 | 1695 | INIT_LIST_HEAD(&(*mem)->bo_va_list); |
| 1697 | 1696 | mutex_init(&(*mem)->lock); |
| 1698 | − | |
| 1697 | + | |
| 1699 | 1698 | (*mem)->alloc_flags = |
| 1700 | 1699 | ((bo->preferred_domains & AMDGPU_GEM_DOMAIN_VRAM) ? |
| 1701 | 1700 | KFD_IOC_ALLOC_MEM_FLAGS_VRAM : KFD_IOC_ALLOC_MEM_FLAGS_GTT) |
| @@ -1401,7 +1401,7 @@ static ATOM_VOLTAGE_OBJECT_V3 *amdgpu_atombios_lookup_voltage_object_v3(ATOM_VOL · 1400 unmodified lines | ||
| 1401 | 1401 | { |
| 1402 | 1402 | u32 size = le16_to_cpu(v3->sHeader.usStructureSize); |
| 1403 | 1403 | u32 offset = offsetof(ATOM_VOLTAGE_OBJECT_INFO_V3_1, asVoltageObj[0]); |
| 1404 | − u8 *start = (u8*)v3; | |
| 1404 | + u8 *start = (u8 *)v3; | |
| 1405 | 1405 | |
| 1406 | 1406 | while (offset < size) { |
| 1407 | 1407 | ATOM_VOLTAGE_OBJECT_V3 *vo = (ATOM_VOLTAGE_OBJECT_V3 *)(start + offset); |
| @@ -70,7 +70,7 @@ int amdgpu_atomfirmware_allocate_fb_scratch(struct amdgpu_device *adev) · 69 unmodified lines | ||
| 70 | 70 | struct atom_context *ctx = adev->mode_info.atom_context; |
| 71 | 71 | int index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, |
| 72 | 72 | vram_usagebyfirmware); |
| 73 | − struct vram_usagebyfirmware_v2_1 * firmware_usage; | |
| 73 | + struct vram_usagebyfirmware_v2_1 *firmware_usage; | |
| 74 | 74 | uint32_t start_addr, size; |
| 75 | 75 | uint16_t data_offset; |
| 76 | 76 | int usage_bytes = 0; |
| @@ -149,6 +149,10 @@ static int convert_atom_mem_type_to_vram_type(struct amdgpu_device *adev, · 72 unmodified lines | ||
| 149 | 149 | case LpDdr4MemType: |
| 150 | 150 | vram_type = AMDGPU_VRAM_TYPE_DDR4; |
| 151 | 151 | break; |
| 152 | + case Ddr5MemType: | |
| 153 | + case LpDdr5MemType: | |
| 154 | + vram_type = AMDGPU_VRAM_TYPE_DDR5; | |
| 155 | + break; | |
| 152 | 156 | default: |
| 153 | 157 | vram_type = AMDGPU_VRAM_TYPE_UNKNOWN; |
| 154 | 158 | break; |
| @@ -544,6 +548,7 @@ int amdgpu_mem_train_support(struct amdgpu_device *adev) · 389 unmodified lines | ||
| 544 | 548 | case HW_REV(11, 0, 5): |
| 545 | 549 | case HW_REV(11, 0, 7): |
| 546 | 550 | case HW_REV(11, 0, 11): |
| 551 | + case HW_REV(11, 0, 12): | |
| 547 | 552 | ret = 1; |
| 548 | 553 | break; |
| 549 | 554 | default: |
| @@ -352,17 +352,10 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device, · 351 unmodified lines | ||
| 352 | 352 | break; |
| 353 | 353 | case CHIP_POLARIS11: |
| 354 | 354 | if (type == CGS_UCODE_ID_SMU) { |
| 355 | − if (((adev->pdev->device == 0x67ef) && | |
| 356 | − ((adev->pdev->revision == 0xe0) || | |
| 357 | − (adev->pdev->revision == 0xe5))) || | |
| 358 | − ((adev->pdev->device == 0x67ff) && | |
| 359 | − ((adev->pdev->revision == 0xcf) || | |
| 360 | − (adev->pdev->revision == 0xef) || | |
| 361 | − (adev->pdev->revision == 0xff)))) { | |
| 355 | + if (ASICID_IS_P21(adev->pdev->device, adev->pdev->revision)) { | |
| 362 | 356 | info->is_kicker = true; |
| 363 | 357 | strcpy(fw_name, "amdgpu/polaris11_k_smc.bin"); |
| 364 | − } else if ((adev->pdev->device == 0x67ef) && | |
| 365 | − (adev->pdev->revision == 0xe2)) { | |
| 358 | + } else if (ASICID_IS_P31(adev->pdev->device, adev->pdev->revision)) { | |
| 366 | 359 | info->is_kicker = true; |
| 367 | 360 | strcpy(fw_name, "amdgpu/polaris11_k2_smc.bin"); |
| 368 | 361 | } else { |
| @@ -374,21 +367,10 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device, · 5 unmodified lines | ||
| 374 | 367 | break; |
| 375 | 368 | case CHIP_POLARIS10: |
| 376 | 369 | if (type == CGS_UCODE_ID_SMU) { |
| 377 | − if (((adev->pdev->device == 0x67df) && | |
| 378 | − ((adev->pdev->revision == 0xe0) || | |
| 379 | − (adev->pdev->revision == 0xe3) || | |
| 380 | − (adev->pdev->revision == 0xe4) || | |
| 381 | − (adev->pdev->revision == 0xe5) || | |
| 382 | − (adev->pdev->revision == 0xe7) || | |
| 383 | − (adev->pdev->revision == 0xef))) || | |
| 384 | − ((adev->pdev->device == 0x6fdf) && | |
| 385 | − ((adev->pdev->revision == 0xef) || | |
| 386 | − (adev->pdev->revision == 0xff)))) { | |
| 370 | + if (ASICID_IS_P20(adev->pdev->device, adev->pdev->revision)) { | |
| 387 | 371 | info->is_kicker = true; |
| 388 | 372 | strcpy(fw_name, "amdgpu/polaris10_k_smc.bin"); |
| 389 | − } else if ((adev->pdev->device == 0x67df) && | |
| 390 | − ((adev->pdev->revision == 0xe1) || | |
| 391 | − (adev->pdev->revision == 0xf7))) { | |
| 373 | + } else if (ASICID_IS_P30(adev->pdev->device, adev->pdev->revision)) { | |
| 392 | 374 | info->is_kicker = true; |
| 393 | 375 | strcpy(fw_name, "amdgpu/polaris10_k2_smc.bin"); |
| 394 | 376 | } else { |
| @@ -399,13 +381,7 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device, · 4 unmodified lines | ||
| 399 | 381 | } |
| 400 | 382 | break; |
| 401 | 383 | case CHIP_POLARIS12: |
| 402 | − if (((adev->pdev->device == 0x6987) && | |
| 403 | − ((adev->pdev->revision == 0xc0) || | |
| 404 | − (adev->pdev->revision == 0xc3))) || | |
| 405 | − ((adev->pdev->device == 0x6981) && | |
| 406 | − ((adev->pdev->revision == 0x00) || | |
| 407 | − (adev->pdev->revision == 0x01) || | |
| 408 | − (adev->pdev->revision == 0x10)))) { | |
| 384 | + if (ASICID_IS_P23(adev->pdev->device, adev->pdev->revision)) { | |
| 409 | 385 | info->is_kicker = true; |
| 410 | 386 | strcpy(fw_name, "amdgpu/polaris12_k_smc.bin"); |
| 411 | 387 | } else { |
| @@ -326,7 +326,7 @@ static void amdgpu_cs_get_threshold_for_moves(struct amdgpu_device *adev, · 325 unmodified lines | ||
| 326 | 326 | increment_us = time_us - adev->mm_stats.last_update_us; |
| 327 | 327 | adev->mm_stats.last_update_us = time_us; |
| 328 | 328 | adev->mm_stats.accum_us = min(adev->mm_stats.accum_us + increment_us, |
| 329 | − us_upper_bound); | |
| 329 | + us_upper_bound); | |
| 330 | 330 | |
| 331 | 331 | /* This prevents the short period of low performance when the VRAM |
| 332 | 332 | * usage is low and the driver is in debt or doesn't have enough |
| @@ -1460,7 +1460,7 @@ int amdgpu_cs_fence_to_handle_ioctl(struct drm_device *dev, void *data, · 1127 unmodified lines | ||
| 1460 | 1460 | dma_fence_put(fence); |
| 1461 | 1461 | if (r) |
| 1462 | 1462 | return r; |
| 1463 | − r = drm_syncobj_get_fd(syncobj, (int*)&info->out.handle); | |
| 1463 | + r = drm_syncobj_get_fd(syncobj, (int *)&info->out.handle); | |
| 1464 | 1464 | drm_syncobj_put(syncobj); |
| 1465 | 1465 | return r; |
| 1466 | 1466 | |
| @@ -100,7 +100,7 @@ static int amdgpu_ctx_init_entity(struct amdgpu_ctx *ctx, u32 hw_ip, · 99 unmodified lines | ||
| 100 | 100 | enum drm_sched_priority priority; |
| 101 | 101 | int r; |
| 102 | 102 | |
| 103 | − entity = kcalloc(1, offsetof(typeof(*entity), fences[amdgpu_sched_jobs]), | |
| 103 | + entity = kzalloc(struct_size(entity, fences, amdgpu_sched_jobs), | |
| 104 | 104 | GFP_KERNEL); |
| 105 | 105 | if (!entity) |
| 106 | 106 | return -ENOMEM; |
| @@ -450,7 +450,7 @@ int amdgpu_ctx_put(struct amdgpu_ctx *ctx) · 343 unmodified lines | ||
| 450 | 450 | |
| 451 | 451 | void amdgpu_ctx_add_fence(struct amdgpu_ctx *ctx, |
| 452 | 452 | struct drm_sched_entity *entity, |
| 453 | − struct dma_fence *fence, uint64_t* handle) | |
| 453 | + struct dma_fence *fence, uint64_t *handle) | |
| 454 | 454 | { |
| 455 | 455 | struct amdgpu_ctx_entity *centity = to_amdgpu_ctx_entity(entity); |
| 456 | 456 | uint64_t seq = centity->sequence; |
| @@ -35,6 +35,7 @@ · 34 unmodified lines | ||
| 35 | 35 | #include "amdgpu_dm_debugfs.h" |
| 36 | 36 | #include "amdgpu_ras.h" |
| 37 | 37 | #include "amdgpu_rap.h" |
| 38 | +#include "amdgpu_fw_attestation.h" | |
| 38 | 39 | |
| 39 | 40 | /** |
| 40 | 41 | * amdgpu_debugfs_add_files - Add simple debugfs entries |
| @@ -169,14 +170,14 @@ static void amdgpu_debugfs_autodump_init(struct amdgpu_device *adev) · 128 unmodified lines | ||
| 169 | 170 | * |
| 170 | 171 | * Bit 62: Indicates a GRBM bank switch is needed |
| 171 | 172 | * Bit 61: Indicates a SRBM bank switch is needed (implies bit 62 is |
| 172 | − * zero) | |
| 173 | + * zero) | |
| 173 | 174 | * Bits 24..33: The SE or ME selector if needed |
| 174 | 175 | * Bits 34..43: The SH (or SA) or PIPE selector if needed |
| 175 | 176 | * Bits 44..53: The INSTANCE (or CU/WGP) or QUEUE selector if needed |
| 176 | 177 | * |
| 177 | 178 | * Bit 23: Indicates that the PM power gating lock should be held |
| 178 | − * This is necessary to read registers that might be | |
| 179 | − * unreliable during a power gating transistion. | |
| 179 | + * This is necessary to read registers that might be | |
| 180 | + * unreliable during a power gating transistion. | |
| 180 | 181 | * |
| 181 | 182 | * The lower bits are the BYTE offset of the register to read. This |
| 182 | 183 | * allows reading multiple registers in a single call and having |
| @@ -864,7 +865,7 @@ static ssize_t amdgpu_debugfs_wave_read(struct file *f, char __user *buf, · 681 unmodified lines | ||
| 864 | 865 | { |
| 865 | 866 | struct amdgpu_device *adev = f->f_inode->i_private; |
| 866 | 867 | int r, x; |
| 867 | − ssize_t result=0; | |
| 868 | + ssize_t result = 0; | |
| 868 | 869 | uint32_t offset, se, sh, cu, wave, simd, data[32]; |
| 869 | 870 | |
| 870 | 871 | if (size & 3 || *pos & 3) |
| @@ -1210,7 +1211,7 @@ static const char *debugfs_regs_names[] = { · 339 unmodified lines | ||
| 1210 | 1211 | |
| 1211 | 1212 | /** |
| 1212 | 1213 | * amdgpu_debugfs_regs_init - Initialize debugfs entries that provide |
| 1213 | − * register access. | |
| 1214 | + * register access. | |
| 1214 | 1215 | * |
| 1215 | 1216 | * @adev: The device to attach the debugfs entries to |
| 1216 | 1217 | */ |
| @@ -1338,11 +1339,41 @@ static int amdgpu_debugfs_evict_gtt(struct seq_file *m, void *data) · 121 unmodified lines | ||
| 1338 | 1339 | return 0; |
| 1339 | 1340 | } |
| 1340 | 1341 | |
| 1342 | +static int amdgpu_debugfs_vm_info(struct seq_file *m, void *data) | |
| 1343 | +{ | |
| 1344 | + struct drm_info_node *node = (struct drm_info_node *)m->private; | |
| 1345 | + struct drm_device *dev = node->minor->dev; | |
| 1346 | + struct drm_file *file; | |
| 1347 | + int r; | |
| 1348 | + | |
| 1349 | + r = mutex_lock_interruptible(&dev->filelist_mutex); | |
| 1350 | + if (r) | |
| 1351 | + return r; | |
| 1352 | + | |
| 1353 | + list_for_each_entry(file, &dev->filelist, lhead) { | |
| 1354 | + struct amdgpu_fpriv *fpriv = file->driver_priv; | |
| 1355 | + struct amdgpu_vm *vm = &fpriv->vm; | |
| 1356 | + | |
| 1357 | + seq_printf(m, "pid:%d\tProcess:%s ----------\n", | |
| 1358 | + vm->task_info.pid, vm->task_info.process_name); | |
| 1359 | + r = amdgpu_bo_reserve(vm->root.base.bo, true); | |
| 1360 | + if (r) | |
| 1361 | + break; | |
| 1362 | + amdgpu_debugfs_vm_bo_info(vm, m); | |
| 1363 | + amdgpu_bo_unreserve(vm->root.base.bo); | |
| 1364 | + } | |
| 1365 | + | |
| 1366 | + mutex_unlock(&dev->filelist_mutex); | |
| 1367 | + | |
| 1368 | + return r; | |
| 1369 | +} | |
| 1370 | + | |
| 1341 | 1371 | static const struct drm_info_list amdgpu_debugfs_list[] = { |
| 1342 | 1372 | {"amdgpu_vbios", amdgpu_debugfs_get_vbios_dump}, |
| 1343 | 1373 | {"amdgpu_test_ib", &amdgpu_debugfs_test_ib}, |
| 1344 | 1374 | {"amdgpu_evict_vram", &amdgpu_debugfs_evict_vram}, |
| 1345 | 1375 | {"amdgpu_evict_gtt", &amdgpu_debugfs_evict_gtt}, |
| 1376 | + {"amdgpu_vm_info", &amdgpu_debugfs_vm_info}, | |
| 1346 | 1377 | }; |
| 1347 | 1378 | |
| 1348 | 1379 | static void amdgpu_ib_preempt_fences_swap(struct amdgpu_ring *ring, |
| @@ -1638,6 +1669,8 @@ int amdgpu_debugfs_init(struct amdgpu_device *adev) · 289 unmodified lines | ||
| 1638 | 1669 | |
| 1639 | 1670 | amdgpu_rap_debugfs_init(adev); |
| 1640 | 1671 | |
| 1672 | + amdgpu_fw_attestation_debugfs_init(adev); | |
| 1673 | + | |
| 1641 | 1674 | return amdgpu_debugfs_add_files(adev, amdgpu_debugfs_list, |
| 1642 | 1675 | ARRAY_SIZE(amdgpu_debugfs_list)); |
| 1643 | 1676 | } |
| @@ -80,6 +80,8 @@ MODULE_FIRMWARE("amdgpu/renoir_gpu_info.bin"); · 79 unmodified lines | ||
| 80 | 80 | MODULE_FIRMWARE("amdgpu/navi10_gpu_info.bin"); |
| 81 | 81 | MODULE_FIRMWARE("amdgpu/navi14_gpu_info.bin"); |
| 82 | 82 | MODULE_FIRMWARE("amdgpu/navi12_gpu_info.bin"); |
| 83 | +MODULE_FIRMWARE("amdgpu/vangogh_gpu_info.bin"); | |
| 84 | +MODULE_FIRMWARE("amdgpu/green_sardine_gpu_info.bin"); | |
| 83 | 85 | |
| 84 | 86 | #define AMDGPU_RESUME_MS 2000 |
| 85 | 87 | |
| @@ -114,6 +116,8 @@ const char *amdgpu_asic_name[] = { · 28 unmodified lines | ||
| 114 | 116 | "NAVI12", |
| 115 | 117 | "SIENNA_CICHLID", |
| 116 | 118 | "NAVY_FLOUNDER", |
| 119 | + "VANGOGH", | |
| 120 | + "DIMGREY_CAVEFISH", | |
| 117 | 121 | "LAST", |
| 118 | 122 | }; |
| 119 | 123 | |
| @@ -239,9 +243,11 @@ bool amdgpu_device_supports_baco(struct drm_device *dev) · 119 unmodified lines | ||
| 239 | 243 | return amdgpu_asic_supports_baco(adev); |
| 240 | 244 | } |
| 241 | 245 | |
| 246 | +/* | |
| 247 | + * VRAM access helper functions | |
| 248 | + */ | |
| 249 | + | |
| 242 | 250 | /** |
| 243 | − * VRAM access helper functions. | |
| 244 | − * | |
| 245 | 251 | * amdgpu_device_vram_access - read/write a buffer in vram |
| 246 | 252 | * |
| 247 | 253 | * @adev: amdgpu_device pointer |
| @@ -705,7 +711,7 @@ void amdgpu_device_indirect_wreg64(struct amdgpu_device *adev, · 457 unmodified lines | ||
| 705 | 711 | /** |
| 706 | 712 | * amdgpu_invalid_rreg - dummy reg read function |
| 707 | 713 | * |
| 708 | − * @adev: amdgpu device pointer | |
| 714 | + * @adev: amdgpu_device pointer | |
| 709 | 715 | * @reg: offset of register |
| 710 | 716 | * |
| 711 | 717 | * Dummy register read function. Used for register blocks |
| @@ -722,7 +728,7 @@ static uint32_t amdgpu_invalid_rreg(struct amdgpu_device *adev, uint32_t reg) · 10 unmodified lines | ||
| 722 | 728 | /** |
| 723 | 729 | * amdgpu_invalid_wreg - dummy reg write function |
| 724 | 730 | * |
| 725 | − * @adev: amdgpu device pointer | |
| 731 | + * @adev: amdgpu_device pointer | |
| 726 | 732 | * @reg: offset of register |
| 727 | 733 | * @v: value to write to the register |
| 728 | 734 | * |
| @@ -739,7 +745,7 @@ static void amdgpu_invalid_wreg(struct amdgpu_device *adev, uint32_t reg, uint32 · 10 unmodified lines | ||
| 739 | 745 | /** |
| 740 | 746 | * amdgpu_invalid_rreg64 - dummy 64 bit reg read function |
| 741 | 747 | * |
| 742 | − * @adev: amdgpu device pointer | |
| 748 | + * @adev: amdgpu_device pointer | |
| 743 | 749 | * @reg: offset of register |
| 744 | 750 | * |
| 745 | 751 | * Dummy register read function. Used for register blocks |
| @@ -756,7 +762,7 @@ static uint64_t amdgpu_invalid_rreg64(struct amdgpu_device *adev, uint32_t reg) · 10 unmodified lines | ||
| 756 | 762 | /** |
| 757 | 763 | * amdgpu_invalid_wreg64 - dummy reg write function |
| 758 | 764 | * |
| 759 | − * @adev: amdgpu device pointer | |
| 765 | + * @adev: amdgpu_device pointer | |
| 760 | 766 | * @reg: offset of register |
| 761 | 767 | * @v: value to write to the register |
| 762 | 768 | * |
| @@ -773,7 +779,7 @@ static void amdgpu_invalid_wreg64(struct amdgpu_device *adev, uint32_t reg, uint · 10 unmodified lines | ||
| 773 | 779 | /** |
| 774 | 780 | * amdgpu_block_invalid_rreg - dummy reg read function |
| 775 | 781 | * |
| 776 | − * @adev: amdgpu device pointer | |
| 782 | + * @adev: amdgpu_device pointer | |
| 777 | 783 | * @block: offset of instance |
| 778 | 784 | * @reg: offset of register |
| 779 | 785 | * |
| @@ -793,7 +799,7 @@ static uint32_t amdgpu_block_invalid_rreg(struct amdgpu_device *adev, · 13 unmodified lines | ||
| 793 | 799 | /** |
| 794 | 800 | * amdgpu_block_invalid_wreg - dummy reg write function |
| 795 | 801 | * |
| 796 | − * @adev: amdgpu device pointer | |
| 802 | + * @adev: amdgpu_device pointer | |
| 797 | 803 | * @block: offset of instance |
| 798 | 804 | * @reg: offset of register |
| 799 | 805 | * @v: value to write to the register |
| @@ -813,7 +819,7 @@ static void amdgpu_block_invalid_wreg(struct amdgpu_device *adev, · 13 unmodified lines | ||
| 813 | 819 | /** |
| 814 | 820 | * amdgpu_device_asic_init - Wrapper for atom asic_init |
| 815 | 821 | * |
| 816 | − * @dev: drm_device pointer | |
| 822 | + * @adev: amdgpu_device pointer | |
| 817 | 823 | * |
| 818 | 824 | * Does any asic specific work and then calls atom asic init. |
| 819 | 825 | */ |
| @@ -827,7 +833,7 @@ static int amdgpu_device_asic_init(struct amdgpu_device *adev) · 7 unmodified lines | ||
| 827 | 833 | /** |
| 828 | 834 | * amdgpu_device_vram_scratch_init - allocate the VRAM scratch page |
| 829 | 835 | * |
| 830 | − * @adev: amdgpu device pointer | |
| 836 | + * @adev: amdgpu_device pointer | |
| 831 | 837 | * |
| 832 | 838 | * Allocates a scratch page of VRAM for use by various things in the |
| 833 | 839 | * driver. |
| @@ -844,7 +850,7 @@ static int amdgpu_device_vram_scratch_init(struct amdgpu_device *adev) · 10 unmodified lines | ||
| 844 | 850 | /** |
| 845 | 851 | * amdgpu_device_vram_scratch_fini - Free the VRAM scratch page |
| 846 | 852 | * |
| 847 | − * @adev: amdgpu device pointer | |
| 853 | + * @adev: amdgpu_device pointer | |
| 848 | 854 | * |
| 849 | 855 | * Frees the VRAM scratch page. |
| 850 | 856 | */ |
| @@ -1370,13 +1376,6 @@ static int amdgpu_device_check_arguments(struct amdgpu_device *adev) · 519 unmodified lines | ||
| 1370 | 1376 | |
| 1371 | 1377 | amdgpu_gmc_tmz_set(adev); |
| 1372 | 1378 | |
| 1373 | − if (amdgpu_num_kcq == -1) { | |
| 1374 | − amdgpu_num_kcq = 8; | |
| 1375 | − } else if (amdgpu_num_kcq > 8 || amdgpu_num_kcq < 0) { | |
| 1376 | − amdgpu_num_kcq = 8; | |
| 1377 | − dev_warn(adev->dev, "set kernel compute queue number to 8 due to invalid parameter provided by user\n"); | |
| 1378 | − } | |
| 1379 | − | |
| 1380 | 1379 | amdgpu_gmc_noretry_set(adev); |
| 1381 | 1380 | |
| 1382 | 1381 | return 0; |
| @@ -1783,6 +1782,7 @@ static int amdgpu_device_parse_gpu_info_fw(struct amdgpu_device *adev) · 400 unmodified lines | ||
| 1783 | 1782 | case CHIP_VEGA20: |
| 1784 | 1783 | case CHIP_SIENNA_CICHLID: |
| 1785 | 1784 | case CHIP_NAVY_FLOUNDER: |
| 1785 | + case CHIP_DIMGREY_CAVEFISH: | |
| 1786 | 1786 | default: |
| 1787 | 1787 | return 0; |
| 1788 | 1788 | case CHIP_VEGA10: |
| @@ -1803,7 +1803,10 @@ static int amdgpu_device_parse_gpu_info_fw(struct amdgpu_device *adev) · 14 unmodified lines | ||
| 1803 | 1803 | chip_name = "arcturus"; |
| 1804 | 1804 | break; |
| 1805 | 1805 | case CHIP_RENOIR: |
| 1806 | − chip_name = "renoir"; | |
| 1806 | + if (adev->apu_flags & AMD_APU_IS_RENOIR) | |
| 1807 | + chip_name = "renoir"; | |
| 1808 | + else | |
| 1809 | + chip_name = "green_sardine"; | |
| 1807 | 1810 | break; |
| 1808 | 1811 | case CHIP_NAVI10: |
| 1809 | 1812 | chip_name = "navi10"; |
| @@ -1814,6 +1817,9 @@ static int amdgpu_device_parse_gpu_info_fw(struct amdgpu_device *adev) · 4 unmodified lines | ||
| 1814 | 1817 | case CHIP_NAVI12: |
| 1815 | 1818 | chip_name = "navi12"; |
| 1816 | 1819 | break; |
| 1820 | + case CHIP_VANGOGH: | |
| 1821 | + chip_name = "vangogh"; | |
| 1822 | + break; | |
| 1817 | 1823 | } |
| 1818 | 1824 | |
| 1819 | 1825 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_gpu_info.bin", chip_name); |
| @@ -1988,7 +1994,12 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev) · 168 unmodified lines | ||
| 1988 | 1994 | case CHIP_NAVI12: |
| 1989 | 1995 | case CHIP_SIENNA_CICHLID: |
| 1990 | 1996 | case CHIP_NAVY_FLOUNDER: |
| 1991 | − adev->family = AMDGPU_FAMILY_NV; | |
| 1997 | + case CHIP_DIMGREY_CAVEFISH: | |
| 1998 | + case CHIP_VANGOGH: | |
| 1999 | + if (adev->asic_type == CHIP_VANGOGH) | |
| 2000 | + adev->family = AMDGPU_FAMILY_VGH; | |
| 2001 | + else | |
| 2002 | + adev->family = AMDGPU_FAMILY_NV; | |
| 1992 | 2003 | |
| 1993 | 2004 | r = nv_set_ip_blocks(adev); |
| 1994 | 2005 | if (r) |
| @@ -2993,10 +3004,10 @@ bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type) · 998 unmodified lines | ||
| 2993 | 3004 | case CHIP_NAVI14: |
| 2994 | 3005 | case CHIP_NAVI12: |
| 2995 | 3006 | case CHIP_RENOIR: |
| 2996 | −#endif | |
| 2997 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 2998 | 3007 | case CHIP_SIENNA_CICHLID: |
| 2999 | 3008 | case CHIP_NAVY_FLOUNDER: |
| 3009 | + case CHIP_DIMGREY_CAVEFISH: | |
| 3010 | + case CHIP_VANGOGH: | |
| 3000 | 3011 | #endif |
| 3001 | 3012 | return amdgpu_dc != 0; |
| 3002 | 3013 | #endif |
| @@ -3011,7 +3022,7 @@ bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type) · 8 unmodified lines | ||
| 3011 | 3022 | /** |
| 3012 | 3023 | * amdgpu_device_has_dc_support - check if dc is supported |
| 3013 | 3024 | * |
| 3014 | − * @adev: amdgpu_device_pointer | |
| 3025 | + * @adev: amdgpu_device pointer | |
| 3015 | 3026 | * |
| 3016 | 3027 | * Returns true for supported, false for not supported |
| 3017 | 3028 | */ |
| @@ -4045,7 +4056,7 @@ static int amdgpu_device_recover_vram(struct amdgpu_device *adev) · 1027 unmodified lines | ||
| 4045 | 4056 | /** |
| 4046 | 4057 | * amdgpu_device_reset_sriov - reset ASIC for SR-IOV vf |
| 4047 | 4058 | * |
| 4048 | − * @adev: amdgpu device pointer | |
| 4059 | + * @adev: amdgpu_device pointer | |
| 4049 | 4060 | * @from_hypervisor: request from hypervisor |
| 4050 | 4061 | * |
| 4051 | 4062 | * do VF FLR and reinitialize Asic |
| @@ -4100,7 +4111,7 @@ error: · 48 unmodified lines | ||
| 4100 | 4111 | /** |
| 4101 | 4112 | * amdgpu_device_has_job_running - check if there is any job in mirror list |
| 4102 | 4113 | * |
| 4103 | − * @adev: amdgpu device pointer | |
| 4114 | + * @adev: amdgpu_device pointer | |
| 4104 | 4115 | * |
| 4105 | 4116 | * check if there is any job in mirror list |
| 4106 | 4117 | */ |
| @@ -4128,7 +4139,7 @@ bool amdgpu_device_has_job_running(struct amdgpu_device *adev) · 21 unmodified lines | ||
| 4128 | 4139 | /** |
| 4129 | 4140 | * amdgpu_device_should_recover_gpu - check if we should try GPU recovery |
| 4130 | 4141 | * |
| 4131 | − * @adev: amdgpu device pointer | |
| 4142 | + * @adev: amdgpu_device pointer | |
| 4132 | 4143 | * |
| 4133 | 4144 | * Check amdgpu_gpu_recovery and SRIOV status to see if we should try to recover |
| 4134 | 4145 | * a hung GPU. |
| @@ -4477,7 +4488,7 @@ static int amdgpu_device_suspend_display_audio(struct amdgpu_device *adev) · 342 unmodified lines | ||
| 4477 | 4488 | /** |
| 4478 | 4489 | * amdgpu_device_gpu_recover - reset the asic and recover scheduler |
| 4479 | 4490 | * |
| 4480 | − * @adev: amdgpu device pointer | |
| 4491 | + * @adev: amdgpu_device pointer | |
| 4481 | 4492 | * @job: which job trigger hang |
| 4482 | 4493 | * |
| 4483 | 4494 | * Attempt to reset the GPU if it has hung (all asics). |
| @@ -4497,7 +4508,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, · 13 unmodified lines | ||
| 4497 | 4508 | bool need_emergency_restart = false; |
| 4498 | 4509 | bool audio_suspended = false; |
| 4499 | 4510 | |
| 4500 | − /** | |
| 4511 | + /* | |
| 4501 | 4512 | * Special case: RAS triggered and full reset isn't supported |
| 4502 | 4513 | */ |
| 4503 | 4514 | need_emergency_restart = amdgpu_ras_need_emergency_restart(adev); |
| @@ -44,11 +44,11 @@ struct amdgpu_df_funcs { · 43 unmodified lines | ||
| 44 | 44 | void (*enable_ecc_force_par_wr_rmw)(struct amdgpu_device *adev, |
| 45 | 45 | bool enable); |
| 46 | 46 | int (*pmc_start)(struct amdgpu_device *adev, uint64_t config, |
| 47 | − int is_add); | |
| 47 | + int counter_idx, int is_add); | |
| 48 | 48 | int (*pmc_stop)(struct amdgpu_device *adev, uint64_t config, |
| 49 | − int is_remove); | |
| 49 | + int counter_idx, int is_remove); | |
| 50 | 50 | void (*pmc_get_count)(struct amdgpu_device *adev, uint64_t config, |
| 51 | − uint64_t *count); | |
| 51 | + int counter_idx, uint64_t *count); | |
| 52 | 52 | uint64_t (*get_fica)(struct amdgpu_device *adev, uint32_t ficaa_val); |
| 53 | 53 | void (*set_fica)(struct amdgpu_device *adev, uint32_t ficaa_val, |
| 54 | 54 | uint32_t ficadl_val, uint32_t ficadh_val); |
| @@ -38,6 +38,7 @@ · 37 unmodified lines | ||
| 38 | 38 | #include <drm/drm_edid.h> |
| 39 | 39 | #include <drm/drm_gem_framebuffer_helper.h> |
| 40 | 40 | #include <drm/drm_fb_helper.h> |
| 41 | +#include <drm/drm_fourcc.h> | |
| 41 | 42 | #include <drm/drm_vblank.h> |
| 42 | 43 | |
| 43 | 44 | static void amdgpu_display_flip_callback(struct dma_fence *f, |
| @@ -524,6 +525,10 @@ uint32_t amdgpu_display_supported_domains(struct amdgpu_device *adev, · 480 unmodified lines | ||
| 524 | 525 | (adev->apu_flags & AMD_APU_IS_PICASSO)) |
| 525 | 526 | domain |= AMDGPU_GEM_DOMAIN_GTT; |
| 526 | 527 | break; |
| 528 | + case CHIP_RENOIR: | |
| 529 | + domain |= AMDGPU_GEM_DOMAIN_GTT; | |
| 530 | + break; | |
| 531 | + | |
| 527 | 532 | default: |
| 528 | 533 | break; |
| 529 | 534 | } |
| @@ -533,6 +538,154 @@ uint32_t amdgpu_display_supported_domains(struct amdgpu_device *adev, · 3 unmodified lines | ||
| 533 | 538 | return domain; |
| 534 | 539 | } |
| 535 | 540 | |
| 541 | +static int convert_tiling_flags_to_modifier(struct amdgpu_framebuffer *afb) | |
| 542 | +{ | |
| 543 | + struct amdgpu_device *adev = drm_to_adev(afb->base.dev); | |
| 544 | + uint64_t modifier = 0; | |
| 545 | + | |
| 546 | + if (!afb->tiling_flags || !AMDGPU_TILING_GET(afb->tiling_flags, SWIZZLE_MODE)) { | |
| 547 | + modifier = DRM_FORMAT_MOD_LINEAR; | |
| 548 | + } else { | |
| 549 | + int swizzle = AMDGPU_TILING_GET(afb->tiling_flags, SWIZZLE_MODE); | |
| 550 | + bool has_xor = swizzle >= 16; | |
| 551 | + int block_size_bits; | |
| 552 | + int version; | |
| 553 | + int pipe_xor_bits = 0; | |
| 554 | + int bank_xor_bits = 0; | |
| 555 | + int packers = 0; | |
| 556 | + uint32_t dcc_offset = AMDGPU_TILING_GET(afb->tiling_flags, DCC_OFFSET_256B); | |
| 557 | + | |
| 558 | + switch (swizzle >> 2) { | |
| 559 | + case 0: /* 256B */ | |
| 560 | + block_size_bits = 8; | |
| 561 | + break; | |
| 562 | + case 1: /* 4KiB */ | |
| 563 | + case 5: /* 4KiB _X */ | |
| 564 | + block_size_bits = 12; | |
| 565 | + break; | |
| 566 | + case 2: /* 64KiB */ | |
| 567 | + case 4: /* 64 KiB _T */ | |
| 568 | + case 6: /* 64 KiB _X */ | |
| 569 | + block_size_bits = 16; | |
| 570 | + break; | |
| 571 | + default: | |
| 572 | + /* RESERVED or VAR */ | |
| 573 | + return -EINVAL; | |
| 574 | + } | |
| 575 | + | |
| 576 | + if (adev->asic_type >= CHIP_SIENNA_CICHLID) | |
| 577 | + version = AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS; | |
| 578 | + else if (adev->family == AMDGPU_FAMILY_NV) | |
| 579 | + version = AMD_FMT_MOD_TILE_VER_GFX10; | |
| 580 | + else | |
| 581 | + version = AMD_FMT_MOD_TILE_VER_GFX9; | |
| 582 | + | |
| 583 | + switch (swizzle & 3) { | |
| 584 | + case 0: /* Z microtiling */ | |
| 585 | + return -EINVAL; | |
| 586 | + case 1: /* S microtiling */ | |
| 587 | + if (!has_xor) | |
| 588 | + version = AMD_FMT_MOD_TILE_VER_GFX9; | |
| 589 | + break; | |
| 590 | + case 2: | |
| 591 | + if (!has_xor && afb->base.format->cpp[0] != 4) | |
| 592 | + version = AMD_FMT_MOD_TILE_VER_GFX9; | |
| 593 | + break; | |
| 594 | + case 3: | |
| 595 | + break; | |
| 596 | + } | |
| 597 | + | |
| 598 | + if (has_xor) { | |
| 599 | + switch (version) { | |
| 600 | + case AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS: | |
| 601 | + pipe_xor_bits = min(block_size_bits - 8, | |
| 602 | + ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes)); | |
| 603 | + packers = min(block_size_bits - 8 - pipe_xor_bits, | |
| 604 | + ilog2(adev->gfx.config.gb_addr_config_fields.num_pkrs)); | |
| 605 | + break; | |
| 606 | + case AMD_FMT_MOD_TILE_VER_GFX10: | |
| 607 | + pipe_xor_bits = min(block_size_bits - 8, | |
| 608 | + ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes)); | |
| 609 | + break; | |
| 610 | + case AMD_FMT_MOD_TILE_VER_GFX9: | |
| 611 | + pipe_xor_bits = min(block_size_bits - 8, | |
| 612 | + ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes) + | |
| 613 | + ilog2(adev->gfx.config.gb_addr_config_fields.num_se)); | |
| 614 | + bank_xor_bits = min(block_size_bits - 8 - pipe_xor_bits, | |
| 615 | + ilog2(adev->gfx.config.gb_addr_config_fields.num_banks)); | |
| 616 | + break; | |
| 617 | + } | |
| 618 | + } | |
| 619 | + | |
| 620 | + modifier = AMD_FMT_MOD | | |
| 621 | + AMD_FMT_MOD_SET(TILE, AMDGPU_TILING_GET(afb->tiling_flags, SWIZZLE_MODE)) | | |
| 622 | + AMD_FMT_MOD_SET(TILE_VERSION, version) | | |
| 623 | + AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) | | |
| 624 | + AMD_FMT_MOD_SET(BANK_XOR_BITS, bank_xor_bits) | | |
| 625 | + AMD_FMT_MOD_SET(PACKERS, packers); | |
| 626 | + | |
| 627 | + if (dcc_offset != 0) { | |
| 628 | + bool dcc_i64b = AMDGPU_TILING_GET(afb->tiling_flags, DCC_INDEPENDENT_64B) != 0; | |
| 629 | + bool dcc_i128b = version >= AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS; | |
| 630 | + | |
| 631 | + /* Enable constant encode on RAVEN2 and later. */ | |
| 632 | + bool dcc_constant_encode = adev->asic_type > CHIP_RAVEN || | |
| 633 | + (adev->asic_type == CHIP_RAVEN && | |
| 634 | + adev->external_rev_id >= 0x81); | |
| 635 | + | |
| 636 | + int max_cblock_size = dcc_i64b ? AMD_FMT_MOD_DCC_BLOCK_64B : | |
| 637 | + dcc_i128b ? AMD_FMT_MOD_DCC_BLOCK_128B : | |
| 638 | + AMD_FMT_MOD_DCC_BLOCK_256B; | |
| 639 | + | |
| 640 | + modifier |= AMD_FMT_MOD_SET(DCC, 1) | | |
| 641 | + AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, dcc_constant_encode) | | |
| 642 | + AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, dcc_i64b) | | |
| 643 | + AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, dcc_i128b) | | |
| 644 | + AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, max_cblock_size); | |
| 645 | + | |
| 646 | + afb->base.offsets[1] = dcc_offset * 256 + afb->base.offsets[0]; | |
| 647 | + afb->base.pitches[1] = AMDGPU_TILING_GET(afb->tiling_flags, DCC_PITCH_MAX) + 1; | |
| 648 | + } | |
| 649 | + } | |
| 650 | + | |
| 651 | + afb->base.modifier = modifier; | |
| 652 | + afb->base.flags |= DRM_MODE_FB_MODIFIERS; | |
| 653 | + return 0; | |
| 654 | +} | |
| 655 | + | |
| 656 | +static int amdgpu_display_get_fb_info(const struct amdgpu_framebuffer *amdgpu_fb, | |
| 657 | + uint64_t *tiling_flags, bool *tmz_surface) | |
| 658 | +{ | |
| 659 | + struct amdgpu_bo *rbo; | |
| 660 | + int r; | |
| 661 | + | |
| 662 | + if (!amdgpu_fb) { | |
| 663 | + *tiling_flags = 0; | |
| 664 | + *tmz_surface = false; | |
| 665 | + return 0; | |
| 666 | + } | |
| 667 | + | |
| 668 | + rbo = gem_to_amdgpu_bo(amdgpu_fb->base.obj[0]); | |
| 669 | + r = amdgpu_bo_reserve(rbo, false); | |
| 670 | + | |
| 671 | + if (unlikely(r)) { | |
| 672 | + /* Don't show error message when returning -ERESTARTSYS */ | |
| 673 | + if (r != -ERESTARTSYS) | |
| 674 | + DRM_ERROR("Unable to reserve buffer: %d\n", r); | |
| 675 | + return r; | |
| 676 | + } | |
| 677 | + | |
| 678 | + if (tiling_flags) | |
| 679 | + amdgpu_bo_get_tiling_flags(rbo, tiling_flags); | |
| 680 | + | |
| 681 | + if (tmz_surface) | |
| 682 | + *tmz_surface = amdgpu_bo_encrypted(rbo); | |
| 683 | + | |
| 684 | + amdgpu_bo_unreserve(rbo); | |
| 685 | + | |
| 686 | + return r; | |
| 687 | +} | |
| 688 | + | |
| 536 | 689 | int amdgpu_display_framebuffer_init(struct drm_device *dev, |
| 537 | 690 | struct amdgpu_framebuffer *rfb, |
| 538 | 691 | const struct drm_mode_fb_cmd2 *mode_cmd, |
| @@ -542,11 +695,25 @@ int amdgpu_display_framebuffer_init(struct drm_device *dev, · 3 unmodified lines | ||
| 542 | 695 | rfb->base.obj[0] = obj; |
| 543 | 696 | drm_helper_mode_fill_fb_struct(dev, &rfb->base, mode_cmd); |
| 544 | 697 | ret = drm_framebuffer_init(dev, &rfb->base, &amdgpu_fb_funcs); |
| 545 | − if (ret) { | |
| 546 | − rfb->base.obj[0] = NULL; | |
| 547 | − return ret; | |
| 698 | + if (ret) | |
| 699 | + goto fail; | |
| 700 | + | |
| 701 | + ret = amdgpu_display_get_fb_info(rfb, &rfb->tiling_flags, &rfb->tmz_surface); | |
| 702 | + if (ret) | |
| 703 | + goto fail; | |
| 704 | + | |
| 705 | + if (dev->mode_config.allow_fb_modifiers && | |
| 706 | + !(rfb->base.flags & DRM_MODE_FB_MODIFIERS)) { | |
| 707 | + ret = convert_tiling_flags_to_modifier(rfb); | |
| 708 | + if (ret) | |
| 709 | + goto fail; | |
| 548 | 710 | } |
| 711 | + | |
| 549 | 712 | return 0; |
| 713 | + | |
| 714 | +fail: | |
| 715 | + rfb->base.obj[0] = NULL; | |
| 716 | + return ret; | |
| 550 | 717 | } |
| 551 | 718 | |
| 552 | 719 | struct drm_framebuffer * |
| @@ -95,16 +95,16 @@ · 94 unmodified lines | ||
| 95 | 95 | #define KMS_DRIVER_MINOR 40 |
| 96 | 96 | #define KMS_DRIVER_PATCHLEVEL 0 |
| 97 | 97 | |
| 98 | −int amdgpu_vram_limit = 0; | |
| 99 | −int amdgpu_vis_vram_limit = 0; | |
| 98 | +int amdgpu_vram_limit; | |
| 99 | +int amdgpu_vis_vram_limit; | |
| 100 | 100 | int amdgpu_gart_size = -1; /* auto */ |
| 101 | 101 | int amdgpu_gtt_size = -1; /* auto */ |
| 102 | 102 | int amdgpu_moverate = -1; /* auto */ |
| 103 | −int amdgpu_benchmarking = 0; | |
| 104 | −int amdgpu_testing = 0; | |
| 103 | +int amdgpu_benchmarking; | |
| 104 | +int amdgpu_testing; | |
| 105 | 105 | int amdgpu_audio = -1; |
| 106 | −int amdgpu_disp_priority = 0; | |
| 107 | −int amdgpu_hw_i2c = 0; | |
| 106 | +int amdgpu_disp_priority; | |
| 107 | +int amdgpu_hw_i2c; | |
| 108 | 108 | int amdgpu_pcie_gen2 = -1; |
| 109 | 109 | int amdgpu_msi = -1; |
| 110 | 110 | char amdgpu_lockup_timeout[AMDGPU_MAX_TIMEOUT_PARAM_LENGTH]; |
| @@ -114,19 +114,19 @@ int amdgpu_aspm = -1; · 3 unmodified lines | ||
| 114 | 114 | int amdgpu_runtime_pm = -1; |
| 115 | 115 | uint amdgpu_ip_block_mask = 0xffffffff; |
| 116 | 116 | int amdgpu_bapm = -1; |
| 117 | −int amdgpu_deep_color = 0; | |
| 117 | +int amdgpu_deep_color; | |
| 118 | 118 | int amdgpu_vm_size = -1; |
| 119 | 119 | int amdgpu_vm_fragment_size = -1; |
| 120 | 120 | int amdgpu_vm_block_size = -1; |
| 121 | −int amdgpu_vm_fault_stop = 0; | |
| 122 | −int amdgpu_vm_debug = 0; | |
| 121 | +int amdgpu_vm_fault_stop; | |
| 122 | +int amdgpu_vm_debug; | |
| 123 | 123 | int amdgpu_vm_update_mode = -1; |
| 124 | −int amdgpu_exp_hw_support = 0; | |
| 124 | +int amdgpu_exp_hw_support; | |
| 125 | 125 | int amdgpu_dc = -1; |
| 126 | 126 | int amdgpu_sched_jobs = 32; |
| 127 | 127 | int amdgpu_sched_hw_submission = 2; |
| 128 | −uint amdgpu_pcie_gen_cap = 0; | |
| 129 | −uint amdgpu_pcie_lane_cap = 0; | |
| 128 | +uint amdgpu_pcie_gen_cap; | |
| 129 | +uint amdgpu_pcie_lane_cap; | |
| 130 | 130 | uint amdgpu_cg_mask = 0xffffffff; |
| 131 | 131 | uint amdgpu_pg_mask = 0xffffffff; |
| 132 | 132 | uint amdgpu_sdma_phase_quantum = 32; |
| @@ -134,23 +134,31 @@ char *amdgpu_disable_cu = NULL; · 1 unmodified line | ||
| 134 | 134 | char *amdgpu_virtual_display = NULL; |
| 135 | 135 | /* OverDrive(bit 14) disabled by default*/ |
| 136 | 136 | uint amdgpu_pp_feature_mask = 0xffffbfff; |
| 137 | −uint amdgpu_force_long_training = 0; | |
| 138 | −int amdgpu_job_hang_limit = 0; | |
| 137 | +uint amdgpu_force_long_training; | |
| 138 | +int amdgpu_job_hang_limit; | |
| 139 | 139 | int amdgpu_lbpw = -1; |
| 140 | 140 | int amdgpu_compute_multipipe = -1; |
| 141 | 141 | int amdgpu_gpu_recovery = -1; /* auto */ |
| 142 | −int amdgpu_emu_mode = 0; | |
| 143 | −uint amdgpu_smu_memory_pool_size = 0; | |
| 144 | −/* FBC (bit 0) disabled by default*/ | |
| 145 | −uint amdgpu_dc_feature_mask = 0; | |
| 146 | −uint amdgpu_dc_debug_mask = 0; | |
| 142 | +int amdgpu_emu_mode; | |
| 143 | +uint amdgpu_smu_memory_pool_size; | |
| 144 | +/* | |
| 145 | + * FBC (bit 0) disabled by default | |
| 146 | + * MULTI_MON_PP_MCLK_SWITCH (bit 1) enabled by default | |
| 147 | + * - With this, for multiple monitors in sync(e.g. with the same model), | |
| 148 | + * mclk switching will be allowed. And the mclk will be not foced to the | |
| 149 | + * highest. That helps saving some idle power. | |
| 150 | + * DISABLE_FRACTIONAL_PWM (bit 2) disabled by default | |
| 151 | + * PSR (bit 3) disabled by default | |
| 152 | + */ | |
| 153 | +uint amdgpu_dc_feature_mask = 2; | |
| 154 | +uint amdgpu_dc_debug_mask; | |
| 147 | 155 | int amdgpu_async_gfx_ring = 1; |
| 148 | −int amdgpu_mcbp = 0; | |
| 156 | +int amdgpu_mcbp; | |
| 149 | 157 | int amdgpu_discovery = -1; |
| 150 | −int amdgpu_mes = 0; | |
| 158 | +int amdgpu_mes; | |
| 151 | 159 | int amdgpu_noretry = -1; |
| 152 | 160 | int amdgpu_force_asic_type = -1; |
| 153 | −int amdgpu_tmz = 0; | |
| 161 | +int amdgpu_tmz; | |
| 154 | 162 | int amdgpu_reset_method = -1; /* auto */ |
| 155 | 163 | int amdgpu_num_kcq = -1; |
| 156 | 164 | |
| @@ -272,7 +280,7 @@ module_param_string(lockup_timeout, amdgpu_lockup_timeout, sizeof(amdgpu_lockup_ · 115 unmodified lines | ||
| 272 | 280 | /** |
| 273 | 281 | * DOC: dpm (int) |
| 274 | 282 | * Override for dynamic power management setting |
| 275 | − * (0 = disable, 1 = enable, 2 = enable sw smu driver for vega20) | |
| 283 | + * (0 = disable, 1 = enable) | |
| 276 | 284 | * The default is -1 (auto). |
| 277 | 285 | */ |
| 278 | 286 | MODULE_PARM_DESC(dpm, "DPM support (1 = enable, 0 = disable, -1 = auto)"); |
| @@ -765,7 +773,7 @@ module_param_named(dcdebugmask, amdgpu_dc_debug_mask, uint, 0444); · 486 unmodified lines | ||
| 765 | 773 | * Defaults to 0, or disabled. Userspace can still override this level later |
| 766 | 774 | * after boot. |
| 767 | 775 | */ |
| 768 | −uint amdgpu_dm_abm_level = 0; | |
| 776 | +uint amdgpu_dm_abm_level; | |
| 769 | 777 | MODULE_PARM_DESC(abmlevel, "ABM level (0 = off (default), 1-4 = backlight reduction level) "); |
| 770 | 778 | module_param_named(abmlevel, amdgpu_dm_abm_level, uint, 0444); |
| 771 | 779 | |
| @@ -1090,6 +1098,9 @@ static const struct pci_device_id pciidlist[] = { · 318 unmodified lines | ||
| 1090 | 1098 | {0x1002, 0x73AE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SIENNA_CICHLID}, |
| 1091 | 1099 | {0x1002, 0x73BF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SIENNA_CICHLID}, |
| 1092 | 1100 | |
| 1101 | + /* Van Gogh */ | |
| 1102 | + {0x1002, 0x163F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VANGOGH|AMD_IS_APU}, | |
| 1103 | + | |
| 1093 | 1104 | {0, 0, 0} |
| 1094 | 1105 | }; |
| 1095 | 1106 | |
| @@ -1496,7 +1507,7 @@ static const struct file_operations amdgpu_driver_kms_fops = { · 400 unmodified lines | ||
| 1496 | 1507 | |
| 1497 | 1508 | int amdgpu_file_to_fpriv(struct file *filp, struct amdgpu_fpriv **fpriv) |
| 1498 | 1509 | { |
| 1499 | − struct drm_file *file; | |
| 1510 | + struct drm_file *file; | |
| 1500 | 1511 | |
| 1501 | 1512 | if (!filp) |
| 1502 | 1513 | return -EINVAL; |
| @@ -207,6 +207,7 @@ static int amdgpufb_create(struct drm_fb_helper *helper, · 206 unmodified lines | ||
| 207 | 207 | int ret; |
| 208 | 208 | unsigned long tmp; |
| 209 | 209 | |
| 210 | + memset(&mode_cmd, 0, sizeof(mode_cmd)); | |
| 210 | 211 | mode_cmd.width = sizes->surface_width; |
| 211 | 212 | mode_cmd.height = sizes->surface_height; |
| 212 | 213 | |
| @@ -0,0 +1,142 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2020 Advanced Micro Devices, Inc. | |
| 3 | + * | |
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a | |
| 5 | + * copy of this software and associated documentation files (the "Software"), | |
| 6 | + * to deal in the Software without restriction, including without limitation | |
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the | |
| 9 | + * Software is furnished to do so, subject to the following conditions: | |
| 10 | + * | |
| 11 | + * The above copyright notice and this permission notice shall be included in | |
| 12 | + * all copies or substantial portions of the Software. | |
| 13 | + * | |
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 17 | + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 18 | + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 19 | + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 20 | + * OTHER DEALINGS IN THE SOFTWARE. | |
| 21 | + * | |
| 22 | + */ | |
| 23 | + | |
| 24 | +#include <linux/debugfs.h> | |
| 25 | +#include <linux/firmware.h> | |
| 26 | +#include <linux/dma-mapping.h> | |
| 27 | + | |
| 28 | +#include "amdgpu.h" | |
| 29 | +#include "amdgpu_psp.h" | |
| 30 | +#include "amdgpu_ucode.h" | |
| 31 | +#include "soc15_common.h" | |
| 32 | + | |
| 33 | +#define FW_ATTESTATION_DB_COOKIE 0x143b6a37 | |
| 34 | +#define FW_ATTESTATION_RECORD_VALID 1 | |
| 35 | +#define FW_ATTESTATION_MAX_SIZE 4096 | |
| 36 | + | |
| 37 | +typedef struct FW_ATT_DB_HEADER | |
| 38 | +{ | |
| 39 | + uint32_t AttDbVersion; /* version of the fwar feature */ | |
| 40 | + uint32_t AttDbCookie; /* cookie as an extra check for corrupt data */ | |
| 41 | +} FW_ATT_DB_HEADER; | |
| 42 | + | |
| 43 | +typedef struct FW_ATT_RECORD | |
| 44 | +{ | |
| 45 | + uint16_t AttFwIdV1; /* Legacy FW Type field */ | |
| 46 | + uint16_t AttFwIdV2; /* V2 FW ID field */ | |
| 47 | + uint32_t AttFWVersion; /* FW Version */ | |
| 48 | + uint16_t AttFWActiveFunctionID; /* The VF ID (only in VF Attestation Table) */ | |
| 49 | + uint16_t AttSource; /* FW source indicator */ | |
| 50 | + uint16_t RecordValid; /* Indicates whether the record is a valid entry */ | |
| 51 | + uint8_t AttFwTaId; /* Ta ID (only in TA Attestation Table) */ | |
| 52 | + uint8_t Reserved; | |
| 53 | +} FW_ATT_RECORD; | |
| 54 | + | |
| 55 | +static ssize_t amdgpu_fw_attestation_debugfs_read(struct file *f, | |
| 56 | + char __user *buf, | |
| 57 | + size_t size, | |
| 58 | + loff_t *pos) | |
| 59 | +{ | |
| 60 | + struct amdgpu_device *adev = (struct amdgpu_device *)file_inode(f)->i_private; | |
| 61 | + uint64_t records_addr = 0; | |
| 62 | + uint64_t vram_pos = 0; | |
| 63 | + FW_ATT_DB_HEADER fw_att_hdr = {0}; | |
| 64 | + FW_ATT_RECORD fw_att_record = {0}; | |
| 65 | + | |
| 66 | + if (size < sizeof(FW_ATT_RECORD)) { | |
| 67 | + DRM_WARN("FW attestation input buffer not enough memory"); | |
| 68 | + return -EINVAL; | |
| 69 | + } | |
| 70 | + | |
| 71 | + if ((*pos + sizeof(FW_ATT_DB_HEADER)) >= FW_ATTESTATION_MAX_SIZE) { | |
| 72 | + DRM_WARN("FW attestation out of bounds"); | |
| 73 | + return 0; | |
| 74 | + } | |
| 75 | + | |
| 76 | + if (psp_get_fw_attestation_records_addr(&adev->psp, &records_addr)) { | |
| 77 | + DRM_WARN("Failed to get FW attestation record address"); | |
| 78 | + return -EINVAL; | |
| 79 | + } | |
| 80 | + | |
| 81 | + vram_pos = records_addr - adev->gmc.vram_start; | |
| 82 | + | |
| 83 | + if (*pos == 0) { | |
| 84 | + amdgpu_device_vram_access(adev, | |
| 85 | + vram_pos, | |
| 86 | + (uint32_t*)&fw_att_hdr, | |
| 87 | + sizeof(FW_ATT_DB_HEADER), | |
| 88 | + false); | |
| 89 | + | |
| 90 | + if (fw_att_hdr.AttDbCookie != FW_ATTESTATION_DB_COOKIE) { | |
| 91 | + DRM_WARN("Invalid FW attestation cookie"); | |
| 92 | + return -EINVAL; | |
| 93 | + } | |
| 94 | + | |
| 95 | + DRM_INFO("FW attestation version = 0x%X", fw_att_hdr.AttDbVersion); | |
| 96 | + } | |
| 97 | + | |
| 98 | + amdgpu_device_vram_access(adev, | |
| 99 | + vram_pos + sizeof(FW_ATT_DB_HEADER) + *pos, | |
| 100 | + (uint32_t*)&fw_att_record, | |
| 101 | + sizeof(FW_ATT_RECORD), | |
| 102 | + false); | |
| 103 | + | |
| 104 | + if (fw_att_record.RecordValid != FW_ATTESTATION_RECORD_VALID) | |
| 105 | + return 0; | |
| 106 | + | |
| 107 | + if (copy_to_user(buf, (void*)&fw_att_record, sizeof(FW_ATT_RECORD))) | |
| 108 | + return -EINVAL; | |
| 109 | + | |
| 110 | + *pos += sizeof(FW_ATT_RECORD); | |
| 111 | + | |
| 112 | + return sizeof(FW_ATT_RECORD); | |
| 113 | +} | |
| 114 | + | |
| 115 | +static const struct file_operations amdgpu_fw_attestation_debugfs_ops = { | |
| 116 | + .owner = THIS_MODULE, | |
| 117 | + .read = amdgpu_fw_attestation_debugfs_read, | |
| 118 | + .write = NULL, | |
| 119 | + .llseek = default_llseek | |
| 120 | +}; | |
| 121 | + | |
| 122 | +static int amdgpu_is_fw_attestation_supported(struct amdgpu_device *adev) | |
| 123 | +{ | |
| 124 | + if (adev->asic_type >= CHIP_SIENNA_CICHLID) | |
| 125 | + return 1; | |
| 126 | + | |
| 127 | + return 0; | |
| 128 | +} | |
| 129 | + | |
| 130 | +void amdgpu_fw_attestation_debugfs_init(struct amdgpu_device *adev) | |
| 131 | +{ | |
| 132 | +#if defined(CONFIG_DEBUG_FS) | |
| 133 | + if (!amdgpu_is_fw_attestation_supported(adev)) | |
| 134 | + return; | |
| 135 | + | |
| 136 | + debugfs_create_file("amdgpu_fw_attestation", | |
| 137 | + S_IRUSR, | |
| 138 | + adev_to_drm(adev)->primary->debugfs_root, | |
| 139 | + adev, | |
| 140 | + &amdgpu_fw_attestation_debugfs_ops); | |
| 141 | +#endif | |
| 142 | +} | |
| @@ -0,0 +1,30 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2020 Advanced Micro Devices, Inc. | |
| 3 | + * | |
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a | |
| 5 | + * copy of this software and associated documentation files (the "Software"), | |
| 6 | + * to deal in the Software without restriction, including without limitation | |
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the | |
| 9 | + * Software is furnished to do so, subject to the following conditions: | |
| 10 | + * | |
| 11 | + * The above copyright notice and this permission notice shall be included in | |
| 12 | + * all copies or substantial portions of the Software. | |
| 13 | + * | |
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 17 | + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 18 | + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 19 | + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 20 | + * OTHER DEALINGS IN THE SOFTWARE. | |
| 21 | + * | |
| 22 | + * | |
| 23 | + */ | |
| 24 | +#ifndef _AMDGPU_FW_ATTESTATION_H | |
| 25 | +#define _AMDGPU_FW_ATTESTATION_H | |
| 26 | + | |
| 27 | +#include "amdgpu.h" | |
| 28 | + | |
| 29 | +void amdgpu_fw_attestation_debugfs_init(struct amdgpu_device *adev); | |
| 30 | +#endif | |
| @@ -850,67 +850,6 @@ int amdgpu_mode_dumb_create(struct drm_file *file_priv, · 849 unmodified lines | ||
| 850 | 850 | } |
| 851 | 851 | |
| 852 | 852 | #if defined(CONFIG_DEBUG_FS) |
| 853 | − | |
| 854 | −#define amdgpu_debugfs_gem_bo_print_flag(m, bo, flag) \ | |
| 855 | − if (bo->flags & (AMDGPU_GEM_CREATE_ ## flag)) { \ | |
| 856 | − seq_printf((m), " " #flag); \ | |
| 857 | − } | |
| 858 | − | |
| 859 | −static int amdgpu_debugfs_gem_bo_info(int id, void *ptr, void *data) | |
| 860 | −{ | |
| 861 | − struct drm_gem_object *gobj = ptr; | |
| 862 | − struct amdgpu_bo *bo = gem_to_amdgpu_bo(gobj); | |
| 863 | − struct seq_file *m = data; | |
| 864 | − | |
| 865 | − struct dma_buf_attachment *attachment; | |
| 866 | − struct dma_buf *dma_buf; | |
| 867 | − unsigned domain; | |
| 868 | − const char *placement; | |
| 869 | − unsigned pin_count; | |
| 870 | − | |
| 871 | − domain = amdgpu_mem_type_to_domain(bo->tbo.mem.mem_type); | |
| 872 | − switch (domain) { | |
| 873 | − case AMDGPU_GEM_DOMAIN_VRAM: | |
| 874 | − placement = "VRAM"; | |
| 875 | − break; | |
| 876 | − case AMDGPU_GEM_DOMAIN_GTT: | |
| 877 | − placement = " GTT"; | |
| 878 | − break; | |
| 879 | − case AMDGPU_GEM_DOMAIN_CPU: | |
| 880 | − default: | |
| 881 | − placement = " CPU"; | |
| 882 | − break; | |
| 883 | − } | |
| 884 | − seq_printf(m, "\t0x%08x: %12ld byte %s", | |
| 885 | − id, amdgpu_bo_size(bo), placement); | |
| 886 | − | |
| 887 | − pin_count = READ_ONCE(bo->tbo.pin_count); | |
| 888 | − if (pin_count) | |
| 889 | − seq_printf(m, " pin count %d", pin_count); | |
| 890 | − | |
| 891 | − dma_buf = READ_ONCE(bo->tbo.base.dma_buf); | |
| 892 | − attachment = READ_ONCE(bo->tbo.base.import_attach); | |
| 893 | − | |
| 894 | − if (attachment) | |
| 895 | − seq_printf(m, " imported from %p%s", dma_buf, | |
| 896 | − attachment->peer2peer ? " P2P" : ""); | |
| 897 | − else if (dma_buf) | |
| 898 | − seq_printf(m, " exported as %p", dma_buf); | |
| 899 | − | |
| 900 | − amdgpu_debugfs_gem_bo_print_flag(m, bo, CPU_ACCESS_REQUIRED); | |
| 901 | − amdgpu_debugfs_gem_bo_print_flag(m, bo, NO_CPU_ACCESS); | |
| 902 | − amdgpu_debugfs_gem_bo_print_flag(m, bo, CPU_GTT_USWC); | |
| 903 | − amdgpu_debugfs_gem_bo_print_flag(m, bo, VRAM_CLEARED); | |
| 904 | − amdgpu_debugfs_gem_bo_print_flag(m, bo, SHADOW); | |
| 905 | − amdgpu_debugfs_gem_bo_print_flag(m, bo, VRAM_CONTIGUOUS); | |
| 906 | − amdgpu_debugfs_gem_bo_print_flag(m, bo, VM_ALWAYS_VALID); | |
| 907 | − amdgpu_debugfs_gem_bo_print_flag(m, bo, EXPLICIT_SYNC); | |
| 908 | − | |
| 909 | − seq_printf(m, "\n"); | |
| 910 | − | |
| 911 | − return 0; | |
| 912 | −} | |
| 913 | − | |
| 914 | 853 | static int amdgpu_debugfs_gem_info(struct seq_file *m, void *data) |
| 915 | 854 | { |
| 916 | 855 | struct drm_info_node *node = (struct drm_info_node *)m->private; |
| @@ -924,6 +863,8 @@ static int amdgpu_debugfs_gem_info(struct seq_file *m, void *data) · 7 unmodified lines | ||
| 924 | 863 | |
| 925 | 864 | list_for_each_entry(file, &dev->filelist, lhead) { |
| 926 | 865 | struct task_struct *task; |
| 866 | + struct drm_gem_object *gobj; | |
| 867 | + int id; | |
| 927 | 868 | |
| 928 | 869 | /* |
| 929 | 870 | * Although we have a valid reference on file->pid, that does |
| @@ -938,7 +879,11 @@ static int amdgpu_debugfs_gem_info(struct seq_file *m, void *data) · 8 unmodified lines | ||
| 938 | 879 | rcu_read_unlock(); |
| 939 | 880 | |
| 940 | 881 | spin_lock(&file->table_lock); |
| 941 | − idr_for_each(&file->object_idr, amdgpu_debugfs_gem_bo_info, m); | |
| 882 | + idr_for_each_entry(&file->object_idr, gobj, id) { | |
| 883 | + struct amdgpu_bo *bo = gem_to_amdgpu_bo(gobj); | |
| 884 | + | |
| 885 | + amdgpu_bo_print_info(id, bo, m); | |
| 886 | + } | |
| 942 | 887 | spin_unlock(&file->table_lock); |
| 943 | 888 | } |
| 944 | 889 | |
| @@ -804,3 +804,14 @@ failed_undo: · 803 unmodified lines | ||
| 804 | 804 | failed_kiq_write: |
| 805 | 805 | dev_err(adev->dev, "failed to write reg:%x\n", reg); |
| 806 | 806 | } |
| 807 | + | |
| 808 | +int amdgpu_gfx_get_num_kcq(struct amdgpu_device *adev) | |
| 809 | +{ | |
| 810 | + if (amdgpu_num_kcq == -1) { | |
| 811 | + return 8; | |
| 812 | + } else if (amdgpu_num_kcq > 8 || amdgpu_num_kcq < 0) { | |
| 813 | + dev_warn(adev->dev, "set kernel compute queue number to 8 due to invalid parameter provided by user\n"); | |
| 814 | + return 8; | |
| 815 | + } | |
| 816 | + return amdgpu_num_kcq; | |
| 817 | +} | |
| @@ -218,6 +218,7 @@ struct amdgpu_gfx_funcs { · 217 unmodified lines | ||
| 218 | 218 | void (*reset_ras_error_count) (struct amdgpu_device *adev); |
| 219 | 219 | void (*init_spm_golden)(struct amdgpu_device *adev); |
| 220 | 220 | void (*query_ras_error_status) (struct amdgpu_device *adev); |
| 221 | + void (*update_perfmon_mgcg)(struct amdgpu_device *adev, bool enable); | |
| 221 | 222 | }; |
| 222 | 223 | |
| 223 | 224 | struct sq_work { |
| @@ -392,4 +393,5 @@ int amdgpu_gfx_cp_ecc_error_irq(struct amdgpu_device *adev, · 168 unmodified lines | ||
| 392 | 393 | struct amdgpu_iv_entry *entry); |
| 393 | 394 | uint32_t amdgpu_kiq_rreg(struct amdgpu_device *adev, uint32_t reg); |
| 394 | 395 | void amdgpu_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v); |
| 396 | +int amdgpu_gfx_get_num_kcq(struct amdgpu_device *adev); | |
| 395 | 397 | #endif |
| @@ -389,6 +389,7 @@ void amdgpu_gmc_tmz_set(struct amdgpu_device *adev) · 388 unmodified lines | ||
| 389 | 389 | case CHIP_NAVI10: |
| 390 | 390 | case CHIP_NAVI14: |
| 391 | 391 | case CHIP_NAVI12: |
| 392 | + case CHIP_VANGOGH: | |
| 392 | 393 | /* Don't enable it by default yet. |
| 393 | 394 | */ |
| 394 | 395 | if (amdgpu_tmz < 1) { |
| @@ -421,20 +422,30 @@ void amdgpu_gmc_noretry_set(struct amdgpu_device *adev) · 26 unmodified lines | ||
| 421 | 422 | struct amdgpu_gmc *gmc = &adev->gmc; |
| 422 | 423 | |
| 423 | 424 | switch (adev->asic_type) { |
| 424 | − case CHIP_RAVEN: | |
| 425 | − /* Raven currently has issues with noretry | |
| 426 | − * regardless of what we decide for other | |
| 427 | − * asics, we should leave raven with | |
| 428 | − * noretry = 0 until we root cause the | |
| 429 | − * issues. | |
| 425 | + case CHIP_VEGA20: | |
| 426 | + case CHIP_NAVI10: | |
| 427 | + case CHIP_NAVI14: | |
| 428 | + case CHIP_SIENNA_CICHLID: | |
| 429 | + case CHIP_NAVY_FLOUNDER: | |
| 430 | + case CHIP_DIMGREY_CAVEFISH: | |
| 431 | + /* | |
| 432 | + * noretry = 0 will cause kfd page fault tests fail | |
| 433 | + * for some ASICs, so set default to 1 for these ASICs. | |
| 430 | 434 | */ |
| 431 | 435 | if (amdgpu_noretry == -1) |
| 432 | − gmc->noretry = 0; | |
| 436 | + gmc->noretry = 1; | |
| 433 | 437 | else |
| 434 | 438 | gmc->noretry = amdgpu_noretry; |
| 435 | 439 | break; |
| 440 | + case CHIP_RAVEN: | |
| 436 | 441 | default: |
| 437 | − /* default this to 0 for now, but we may want | |
| 442 | + /* Raven currently has issues with noretry | |
| 443 | + * regardless of what we decide for other | |
| 444 | + * asics, we should leave raven with | |
| 445 | + * noretry = 0 until we root cause the | |
| 446 | + * issues. | |
| 447 | + * | |
| 448 | + * default this to 0 for now, but we may want | |
| 438 | 449 | * to change this in the future for certain |
| 439 | 450 | * GPUs as it can increase performance in |
| 440 | 451 | * certain cases. |
| @@ -81,8 +81,8 @@ static const struct ttm_resource_manager_func amdgpu_gtt_mgr_func; · 80 unmodified lines | ||
| 81 | 81 | /** |
| 82 | 82 | * amdgpu_gtt_mgr_init - init GTT manager and DRM MM |
| 83 | 83 | * |
| 84 | − * @man: TTM memory type manager | |
| 85 | − * @p_size: maximum size of GTT | |
| 84 | + * @adev: amdgpu_device pointer | |
| 85 | + * @gtt_size: maximum size of GTT | |
| 86 | 86 | * |
| 87 | 87 | * Allocate and initialize the GTT manager. |
| 88 | 88 | */ |
| @@ -123,7 +123,7 @@ int amdgpu_gtt_mgr_init(struct amdgpu_device *adev, uint64_t gtt_size) · 34 unmodified lines | ||
| 123 | 123 | /** |
| 124 | 124 | * amdgpu_gtt_mgr_fini - free and destroy GTT manager |
| 125 | 125 | * |
| 126 | − * @man: TTM memory type manager | |
| 126 | + * @adev: amdgpu_device pointer | |
| 127 | 127 | * |
| 128 | 128 | * Destroy and free the GTT manager, returns -EBUSY if ranges are still |
| 129 | 129 | * allocated inside it. |
| @@ -324,6 +324,10 @@ static int amdgpu_firmware_info(struct drm_amdgpu_info_firmware *fw_info, · 323 unmodified lines | ||
| 324 | 324 | fw_info->ver = adev->dm.dmcub_fw_version; |
| 325 | 325 | fw_info->feature = 0; |
| 326 | 326 | break; |
| 327 | + case AMDGPU_INFO_FW_TOC: | |
| 328 | + fw_info->ver = adev->psp.toc_fw_version; | |
| 329 | + fw_info->feature = adev->psp.toc_feature_version; | |
| 330 | + break; | |
| 327 | 331 | default: |
| 328 | 332 | return -EINVAL; |
| 329 | 333 | } |
| @@ -1444,6 +1448,13 @@ static int amdgpu_debugfs_firmware_info(struct seq_file *m, void *data) · 1114 unmodified lines | ||
| 1444 | 1448 | seq_printf(m, "DMCUB feature version: %u, firmware version: 0x%08x\n", |
| 1445 | 1449 | fw_info.feature, fw_info.ver); |
| 1446 | 1450 | |
| 1451 | + /* TOC */ | |
| 1452 | + query_fw.fw_type = AMDGPU_INFO_FW_TOC; | |
| 1453 | + ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); | |
| 1454 | + if (ret) | |
| 1455 | + return ret; | |
| 1456 | + seq_printf(m, "TOC feature version: %u, firmware version: 0x%08x\n", | |
| 1457 | + fw_info.feature, fw_info.ver); | |
| 1447 | 1458 | |
| 1448 | 1459 | seq_printf(m, "VBIOS version: %s\n", ctx->vbios_version); |
| 1449 | 1460 | |
| @@ -302,6 +302,9 @@ struct amdgpu_display_funcs { · 301 unmodified lines | ||
| 302 | 302 | struct amdgpu_framebuffer { |
| 303 | 303 | struct drm_framebuffer base; |
| 304 | 304 | |
| 305 | + uint64_t tiling_flags; | |
| 306 | + bool tmz_surface; | |
| 307 | + | |
| 305 | 308 | /* caching for later use */ |
| 306 | 309 | uint64_t address; |
| 307 | 310 | }; |
| @@ -53,6 +53,8 @@ struct amdgpu_nbio_funcs { · 52 unmodified lines | ||
| 53 | 53 | u32 (*get_hdp_flush_done_offset)(struct amdgpu_device *adev); |
| 54 | 54 | u32 (*get_pcie_index_offset)(struct amdgpu_device *adev); |
| 55 | 55 | u32 (*get_pcie_data_offset)(struct amdgpu_device *adev); |
| 56 | + u32 (*get_pcie_port_index_offset)(struct amdgpu_device *adev); | |
| 57 | + u32 (*get_pcie_port_data_offset)(struct amdgpu_device *adev); | |
| 56 | 58 | u32 (*get_rev_id)(struct amdgpu_device *adev); |
| 57 | 59 | void (*mc_access_enable)(struct amdgpu_device *adev, bool enable); |
| 58 | 60 | void (*hdp_flush)(struct amdgpu_device *adev, struct amdgpu_ring *ring); |
| @@ -85,6 +87,8 @@ struct amdgpu_nbio_funcs { · 26 unmodified lines | ||
| 85 | 87 | void (*query_ras_error_count)(struct amdgpu_device *adev, |
| 86 | 88 | void *ras_error_status); |
| 87 | 89 | int (*ras_late_init)(struct amdgpu_device *adev); |
| 90 | + void (*enable_aspm)(struct amdgpu_device *adev, | |
| 91 | + bool enable); | |
| 88 | 92 | }; |
| 89 | 93 | |
| 90 | 94 | struct amdgpu_nbio { |
| @@ -1045,6 +1045,7 @@ static const char *amdgpu_vram_names[] = { · 1044 unmodified lines | ||
| 1045 | 1045 | "DDR3", |
| 1046 | 1046 | "DDR4", |
| 1047 | 1047 | "GDDR6", |
| 1048 | + "DDR5" | |
| 1048 | 1049 | }; |
| 1049 | 1050 | |
| 1050 | 1051 | /** |
| @@ -1507,3 +1508,77 @@ uint32_t amdgpu_bo_get_preferred_pin_domain(struct amdgpu_device *adev, · 456 unmodified lines | ||
| 1507 | 1508 | } |
| 1508 | 1509 | return domain; |
| 1509 | 1510 | } |
| 1511 | + | |
| 1512 | +#if defined(CONFIG_DEBUG_FS) | |
| 1513 | +#define amdgpu_bo_print_flag(m, bo, flag) \ | |
| 1514 | + do { \ | |
| 1515 | + if (bo->flags & (AMDGPU_GEM_CREATE_ ## flag)) { \ | |
| 1516 | + seq_printf((m), " " #flag); \ | |
| 1517 | + } \ | |
| 1518 | + } while (0) | |
| 1519 | + | |
| 1520 | +/** | |
| 1521 | + * amdgpu_debugfs_print_bo_info - print BO info in debugfs file | |
| 1522 | + * | |
| 1523 | + * @id: Index or Id of the BO | |
| 1524 | + * @bo: Requested BO for printing info | |
| 1525 | + * @m: debugfs file | |
| 1526 | + * | |
| 1527 | + * Print BO information in debugfs file | |
| 1528 | + * | |
| 1529 | + * Returns: | |
| 1530 | + * Size of the BO in bytes. | |
| 1531 | + */ | |
| 1532 | +u64 amdgpu_bo_print_info(int id, struct amdgpu_bo *bo, struct seq_file *m) | |
| 1533 | +{ | |
| 1534 | + struct dma_buf_attachment *attachment; | |
| 1535 | + struct dma_buf *dma_buf; | |
| 1536 | + unsigned int domain; | |
| 1537 | + const char *placement; | |
| 1538 | + unsigned int pin_count; | |
| 1539 | + u64 size; | |
| 1540 | + | |
| 1541 | + domain = amdgpu_mem_type_to_domain(bo->tbo.mem.mem_type); | |
| 1542 | + switch (domain) { | |
| 1543 | + case AMDGPU_GEM_DOMAIN_VRAM: | |
| 1544 | + placement = "VRAM"; | |
| 1545 | + break; | |
| 1546 | + case AMDGPU_GEM_DOMAIN_GTT: | |
| 1547 | + placement = " GTT"; | |
| 1548 | + break; | |
| 1549 | + case AMDGPU_GEM_DOMAIN_CPU: | |
| 1550 | + default: | |
| 1551 | + placement = " CPU"; | |
| 1552 | + break; | |
| 1553 | + } | |
| 1554 | + | |
| 1555 | + size = amdgpu_bo_size(bo); | |
| 1556 | + seq_printf(m, "\t\t0x%08x: %12lld byte %s", | |
| 1557 | + id, size, placement); | |
| 1558 | + | |
| 1559 | + pin_count = READ_ONCE(bo->tbo.pin_count); | |
| 1560 | + if (pin_count) | |
| 1561 | + seq_printf(m, " pin count %d", pin_count); | |
| 1562 | + | |
| 1563 | + dma_buf = READ_ONCE(bo->tbo.base.dma_buf); | |
| 1564 | + attachment = READ_ONCE(bo->tbo.base.import_attach); | |
| 1565 | + | |
| 1566 | + if (attachment) | |
| 1567 | + seq_printf(m, " imported from %p", dma_buf); | |
| 1568 | + else if (dma_buf) | |
| 1569 | + seq_printf(m, " exported as %p", dma_buf); | |
| 1570 | + | |
| 1571 | + amdgpu_bo_print_flag(m, bo, CPU_ACCESS_REQUIRED); | |
| 1572 | + amdgpu_bo_print_flag(m, bo, NO_CPU_ACCESS); | |
| 1573 | + amdgpu_bo_print_flag(m, bo, CPU_GTT_USWC); | |
| 1574 | + amdgpu_bo_print_flag(m, bo, VRAM_CLEARED); | |
| 1575 | + amdgpu_bo_print_flag(m, bo, SHADOW); | |
| 1576 | + amdgpu_bo_print_flag(m, bo, VRAM_CONTIGUOUS); | |
| 1577 | + amdgpu_bo_print_flag(m, bo, VM_ALWAYS_VALID); | |
| 1578 | + amdgpu_bo_print_flag(m, bo, EXPLICIT_SYNC); | |
| 1579 | + | |
| 1580 | + seq_puts(m, "\n"); | |
| 1581 | + | |
| 1582 | + return size; | |
| 1583 | +} | |
| 1584 | +#endif | |
| @@ -328,6 +328,7 @@ void amdgpu_sa_bo_free(struct amdgpu_device *adev, · 327 unmodified lines | ||
| 328 | 328 | #if defined(CONFIG_DEBUG_FS) |
| 329 | 329 | void amdgpu_sa_bo_dump_debug_info(struct amdgpu_sa_manager *sa_manager, |
| 330 | 330 | struct seq_file *m); |
| 331 | +u64 amdgpu_bo_print_info(int id, struct amdgpu_bo *bo, struct seq_file *m); | |
| 331 | 332 | #endif |
| 332 | 333 | int amdgpu_debugfs_sa_init(struct amdgpu_device *adev); |
| 333 | 334 | |
| @@ -19,17 +19,29 @@ · 18 unmodified lines | ||
| 19 | 19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
| 20 | 20 | * OTHER DEALINGS IN THE SOFTWARE. |
| 21 | 21 | * |
| 22 | − * Author: Jonathan Kim <jonathan.kim@amd.com> | |
| 23 | − * | |
| 24 | 22 | */ |
| 25 | 23 | |
| 26 | 24 | #include <linux/perf_event.h> |
| 27 | 25 | #include <linux/init.h> |
| 28 | 26 | #include "amdgpu.h" |
| 29 | 27 | #include "amdgpu_pmu.h" |
| 30 | −#include "df_v3_6.h" | |
| 31 | 28 | |
| 32 | 29 | #define PMU_NAME_SIZE 32 |
| 30 | +#define NUM_FORMATS_AMDGPU_PMU 4 | |
| 31 | +#define NUM_FORMATS_DF_VEGA20 3 | |
| 32 | +#define NUM_EVENTS_DF_VEGA20 8 | |
| 33 | +#define NUM_EVENT_TYPES_VEGA20 1 | |
| 34 | +#define NUM_EVENTS_VEGA20_XGMI 2 | |
| 35 | +#define NUM_EVENTS_VEGA20_MAX NUM_EVENTS_VEGA20_XGMI | |
| 36 | +#define NUM_EVENT_TYPES_ARCTURUS 1 | |
| 37 | +#define NUM_EVENTS_ARCTURUS_XGMI 6 | |
| 38 | +#define NUM_EVENTS_ARCTURUS_MAX NUM_EVENTS_ARCTURUS_XGMI | |
| 39 | + | |
| 40 | +struct amdgpu_pmu_event_attribute { | |
| 41 | + struct device_attribute attr; | |
| 42 | + const char *event_str; | |
| 43 | + unsigned int type; | |
| 44 | +}; | |
| 33 | 45 | |
| 34 | 46 | /* record to keep track of pmu entry per pmu type per device */ |
| 35 | 47 | struct amdgpu_pmu_entry { |
| @@ -37,11 +49,162 @@ struct amdgpu_pmu_entry { · 1 unmodified line | ||
| 37 | 49 | struct amdgpu_device *adev; |
| 38 | 50 | struct pmu pmu; |
| 39 | 51 | unsigned int pmu_perf_type; |
| 52 | + char *pmu_type_name; | |
| 53 | + char *pmu_file_prefix; | |
| 54 | + struct attribute_group fmt_attr_group; | |
| 55 | + struct amdgpu_pmu_event_attribute *fmt_attr; | |
| 56 | + struct attribute_group evt_attr_group; | |
| 57 | + struct amdgpu_pmu_event_attribute *evt_attr; | |
| 40 | 58 | }; |
| 41 | 59 | |
| 60 | +static ssize_t amdgpu_pmu_event_show(struct device *dev, | |
| 61 | + struct device_attribute *attr, char *buf) | |
| 62 | +{ | |
| 63 | + struct amdgpu_pmu_event_attribute *amdgpu_pmu_attr; | |
| 64 | + | |
| 65 | + amdgpu_pmu_attr = container_of(attr, struct amdgpu_pmu_event_attribute, | |
| 66 | + attr); | |
| 67 | + | |
| 68 | + if (!amdgpu_pmu_attr->type) | |
| 69 | + return sprintf(buf, "%s\n", amdgpu_pmu_attr->event_str); | |
| 70 | + | |
| 71 | + return sprintf(buf, "%s,type=0x%x\n", | |
| 72 | + amdgpu_pmu_attr->event_str, amdgpu_pmu_attr->type); | |
| 73 | +} | |
| 74 | + | |
| 42 | 75 | static LIST_HEAD(amdgpu_pmu_list); |
| 43 | 76 | |
| 44 | 77 | |
| 78 | +struct amdgpu_pmu_attr { | |
| 79 | + const char *name; | |
| 80 | + const char *config; | |
| 81 | +}; | |
| 82 | + | |
| 83 | +struct amdgpu_pmu_type { | |
| 84 | + const unsigned int type; | |
| 85 | + const unsigned int num_of_type; | |
| 86 | +}; | |
| 87 | + | |
| 88 | +struct amdgpu_pmu_config { | |
| 89 | + struct amdgpu_pmu_attr *formats; | |
| 90 | + unsigned int num_formats; | |
| 91 | + struct amdgpu_pmu_attr *events; | |
| 92 | + unsigned int num_events; | |
| 93 | + struct amdgpu_pmu_type *types; | |
| 94 | + unsigned int num_types; | |
| 95 | +}; | |
| 96 | + | |
| 97 | +/* | |
| 98 | + * Events fall under two categories: | |
| 99 | + * - PMU typed | |
| 100 | + * Events in /sys/bus/event_source/devices/amdgpu_<pmu_type>_<dev_num> have | |
| 101 | + * performance counter operations handled by one IP <pmu_type>. Formats and | |
| 102 | + * events should be defined by <pmu_type>_<asic_type>_formats and | |
| 103 | + * <pmu_type>_<asic_type>_events respectively. | |
| 104 | + * | |
| 105 | + * - Event config typed | |
| 106 | + * Events in /sys/bus/event_source/devices/amdgpu_<dev_num> have performance | |
| 107 | + * counter operations that can be handled by multiple IPs dictated by their | |
| 108 | + * "type" format field. Formats and events should be defined by | |
| 109 | + * amdgpu_pmu_formats and <asic_type>_events respectively. Format field | |
| 110 | + * "type" is generated in amdgpu_pmu_event_show and defined in | |
| 111 | + * <asic_type>_event_config_types. | |
| 112 | + */ | |
| 113 | + | |
| 114 | +static struct amdgpu_pmu_attr amdgpu_pmu_formats[NUM_FORMATS_AMDGPU_PMU] = { | |
| 115 | + { .name = "event", .config = "config:0-7" }, | |
| 116 | + { .name = "instance", .config = "config:8-15" }, | |
| 117 | + { .name = "umask", .config = "config:16-23"}, | |
| 118 | + { .name = "type", .config = "config:56-63"} | |
| 119 | +}; | |
| 120 | + | |
| 121 | +/* Vega20 events */ | |
| 122 | +static struct amdgpu_pmu_attr vega20_events[NUM_EVENTS_VEGA20_MAX] = { | |
| 123 | + { .name = "xgmi_link0_data_outbound", | |
| 124 | + .config = "event=0x7,instance=0x46,umask=0x2" }, | |
| 125 | + { .name = "xgmi_link1_data_outbound", | |
| 126 | + .config = "event=0x7,instance=0x47,umask=0x2" } | |
| 127 | +}; | |
| 128 | + | |
| 129 | +static struct amdgpu_pmu_type vega20_types[NUM_EVENT_TYPES_VEGA20] = { | |
| 130 | + { .type = AMDGPU_PMU_EVENT_CONFIG_TYPE_XGMI, | |
| 131 | + .num_of_type = NUM_EVENTS_VEGA20_XGMI } | |
| 132 | +}; | |
| 133 | + | |
| 134 | +static struct amdgpu_pmu_config vega20_config = { | |
| 135 | + .formats = amdgpu_pmu_formats, | |
| 136 | + .num_formats = ARRAY_SIZE(amdgpu_pmu_formats), | |
| 137 | + .events = vega20_events, | |
| 138 | + .num_events = ARRAY_SIZE(vega20_events), | |
| 139 | + .types = vega20_types, | |
| 140 | + .num_types = ARRAY_SIZE(vega20_types) | |
| 141 | +}; | |
| 142 | + | |
| 143 | +/* Vega20 data fabric (DF) events */ | |
| 144 | +static struct amdgpu_pmu_attr df_vega20_formats[NUM_FORMATS_DF_VEGA20] = { | |
| 145 | + { .name = "event", .config = "config:0-7" }, | |
| 146 | + { .name = "instance", .config = "config:8-15" }, | |
| 147 | + { .name = "umask", .config = "config:16-23"} | |
| 148 | +}; | |
| 149 | + | |
| 150 | +static struct amdgpu_pmu_attr df_vega20_events[NUM_EVENTS_DF_VEGA20] = { | |
| 151 | + { .name = "cake0_pcsout_txdata", | |
| 152 | + .config = "event=0x7,instance=0x46,umask=0x2" }, | |
| 153 | + { .name = "cake1_pcsout_txdata", | |
| 154 | + .config = "event=0x7,instance=0x47,umask=0x2" }, | |
| 155 | + { .name = "cake0_pcsout_txmeta", | |
| 156 | + .config = "event=0x7,instance=0x46,umask=0x4" }, | |
| 157 | + { .name = "cake1_pcsout_txmeta", | |
| 158 | + .config = "event=0x7,instance=0x47,umask=0x4" }, | |
| 159 | + { .name = "cake0_ftiinstat_reqalloc", | |
| 160 | + .config = "event=0xb,instance=0x46,umask=0x4" }, | |
| 161 | + { .name = "cake1_ftiinstat_reqalloc", | |
| 162 | + .config = "event=0xb,instance=0x47,umask=0x4" }, | |
| 163 | + { .name = "cake0_ftiinstat_rspalloc", | |
| 164 | + .config = "event=0xb,instance=0x46,umask=0x8" }, | |
| 165 | + { .name = "cake1_ftiinstat_rspalloc", | |
| 166 | + .config = "event=0xb,instance=0x47,umask=0x8" } | |
| 167 | +}; | |
| 168 | + | |
| 169 | +static struct amdgpu_pmu_config df_vega20_config = { | |
| 170 | + .formats = df_vega20_formats, | |
| 171 | + .num_formats = ARRAY_SIZE(df_vega20_formats), | |
| 172 | + .events = df_vega20_events, | |
| 173 | + .num_events = ARRAY_SIZE(df_vega20_events), | |
| 174 | + .types = NULL, | |
| 175 | + .num_types = 0 | |
| 176 | +}; | |
| 177 | + | |
| 178 | +/* Arcturus events */ | |
| 179 | +static struct amdgpu_pmu_attr arcturus_events[NUM_EVENTS_ARCTURUS_MAX] = { | |
| 180 | + { .name = "xgmi_link0_data_outbound", | |
| 181 | + .config = "event=0x7,instance=0x4b,umask=0x2" }, | |
| 182 | + { .name = "xgmi_link1_data_outbound", | |
| 183 | + .config = "event=0x7,instance=0x4c,umask=0x2" }, | |
| 184 | + { .name = "xgmi_link2_data_outbound", | |
| 185 | + .config = "event=0x7,instance=0x4d,umask=0x2" }, | |
| 186 | + { .name = "xgmi_link3_data_outbound", | |
| 187 | + .config = "event=0x7,instance=0x4e,umask=0x2" }, | |
| 188 | + { .name = "xgmi_link4_data_outbound", | |
| 189 | + .config = "event=0x7,instance=0x4f,umask=0x2" }, | |
| 190 | + { .name = "xgmi_link5_data_outbound", | |
| 191 | + .config = "event=0x7,instance=0x50,umask=0x2" } | |
| 192 | +}; | |
| 193 | + | |
| 194 | +static struct amdgpu_pmu_type arcturus_types[NUM_EVENT_TYPES_ARCTURUS] = { | |
| 195 | + { .type = AMDGPU_PMU_EVENT_CONFIG_TYPE_XGMI, | |
| 196 | + .num_of_type = NUM_EVENTS_ARCTURUS_XGMI } | |
| 197 | +}; | |
| 198 | + | |
| 199 | +static struct amdgpu_pmu_config arcturus_config = { | |
| 200 | + .formats = amdgpu_pmu_formats, | |
| 201 | + .num_formats = ARRAY_SIZE(amdgpu_pmu_formats), | |
| 202 | + .events = arcturus_events, | |
| 203 | + .num_events = ARRAY_SIZE(arcturus_events), | |
| 204 | + .types = arcturus_types, | |
| 205 | + .num_types = ARRAY_SIZE(arcturus_types) | |
| 206 | +}; | |
| 207 | + | |
| 45 | 208 | /* initialize perf counter */ |
| 46 | 209 | static int amdgpu_perf_event_init(struct perf_event *event) |
| 47 | 210 | { |
| @@ -53,6 +216,7 @@ static int amdgpu_perf_event_init(struct perf_event *event) · 5 unmodified lines | ||
| 53 | 216 | |
| 54 | 217 | /* update the hw_perf_event struct with config data */ |
| 55 | 218 | hwc->config = event->attr.config; |
| 219 | + hwc->config_base = AMDGPU_PMU_PERF_TYPE_NONE; | |
| 56 | 220 | |
| 57 | 221 | return 0; |
| 58 | 222 | } |
| @@ -64,6 +228,7 @@ static void amdgpu_perf_start(struct perf_event *event, int flags) · 5 unmodified lines | ||
| 64 | 228 | struct amdgpu_pmu_entry *pe = container_of(event->pmu, |
| 65 | 229 | struct amdgpu_pmu_entry, |
| 66 | 230 | pmu); |
| 231 | + int target_cntr = 0; | |
| 67 | 232 | |
| 68 | 233 | if (WARN_ON_ONCE(!(hwc->state & PERF_HES_STOPPED))) |
| 69 | 234 | return; |
| @@ -71,19 +236,27 @@ static void amdgpu_perf_start(struct perf_event *event, int flags) · 1 unmodified line | ||
| 71 | 236 | WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE)); |
| 72 | 237 | hwc->state = 0; |
| 73 | 238 | |
| 74 | − switch (pe->pmu_perf_type) { | |
| 75 | − case PERF_TYPE_AMDGPU_DF: | |
| 76 | − if (!(flags & PERF_EF_RELOAD)) | |
| 77 | − pe->adev->df.funcs->pmc_start(pe->adev, hwc->config, 1); | |
| 239 | + switch (hwc->config_base) { | |
| 240 | + case AMDGPU_PMU_EVENT_CONFIG_TYPE_DF: | |
| 241 | + case AMDGPU_PMU_EVENT_CONFIG_TYPE_XGMI: | |
| 242 | + if (!(flags & PERF_EF_RELOAD)) { | |
| 243 | + target_cntr = pe->adev->df.funcs->pmc_start(pe->adev, | |
| 244 | + hwc->config, 0 /* unused */, | |
| 245 | + 1 /* add counter */); | |
| 246 | + if (target_cntr < 0) | |
| 247 | + break; | |
| 248 | + | |
| 249 | + hwc->idx = target_cntr; | |
| 250 | + } | |
| 78 | 251 | |
| 79 | − pe->adev->df.funcs->pmc_start(pe->adev, hwc->config, 0); | |
| 252 | + pe->adev->df.funcs->pmc_start(pe->adev, hwc->config, | |
| 253 | + hwc->idx, 0); | |
| 80 | 254 | break; |
| 81 | 255 | default: |
| 82 | 256 | break; |
| 83 | 257 | } |
| 84 | 258 | |
| 85 | 259 | perf_event_update_userpage(event); |
| 86 | − | |
| 87 | 260 | } |
| 88 | 261 | |
| 89 | 262 | /* read perf counter */ |
| @@ -93,16 +266,16 @@ static void amdgpu_perf_read(struct perf_event *event) · 3 unmodified lines | ||
| 93 | 266 | struct amdgpu_pmu_entry *pe = container_of(event->pmu, |
| 94 | 267 | struct amdgpu_pmu_entry, |
| 95 | 268 | pmu); |
| 96 | − | |
| 97 | 269 | u64 count, prev; |
| 98 | 270 | |
| 99 | 271 | do { |
| 100 | 272 | prev = local64_read(&hwc->prev_count); |
| 101 | 273 | |
| 102 | − switch (pe->pmu_perf_type) { | |
| 103 | − case PERF_TYPE_AMDGPU_DF: | |
| 104 | − pe->adev->df.funcs->pmc_get_count(pe->adev, hwc->config, | |
| 105 | − &count); | |
| 274 | + switch (hwc->config_base) { | |
| 275 | + case AMDGPU_PMU_EVENT_CONFIG_TYPE_DF: | |
| 276 | + case AMDGPU_PMU_EVENT_CONFIG_TYPE_XGMI: | |
| 277 | + pe->adev->df.funcs->pmc_get_count(pe->adev, | |
| 278 | + hwc->config, hwc->idx, &count); | |
| 106 | 279 | break; |
| 107 | 280 | default: |
| 108 | 281 | count = 0; |
| @@ -124,9 +297,11 @@ static void amdgpu_perf_stop(struct perf_event *event, int flags) · 15 unmodified lines | ||
| 124 | 297 | if (hwc->state & PERF_HES_UPTODATE) |
| 125 | 298 | return; |
| 126 | 299 | |
| 127 | − switch (pe->pmu_perf_type) { | |
| 128 | − case PERF_TYPE_AMDGPU_DF: | |
| 129 | − pe->adev->df.funcs->pmc_stop(pe->adev, hwc->config, 0); | |
| 300 | + switch (hwc->config_base) { | |
| 301 | + case AMDGPU_PMU_EVENT_CONFIG_TYPE_DF: | |
| 302 | + case AMDGPU_PMU_EVENT_CONFIG_TYPE_XGMI: | |
| 303 | + pe->adev->df.funcs->pmc_stop(pe->adev, hwc->config, hwc->idx, | |
| 304 | + 0); | |
| 130 | 305 | break; |
| 131 | 306 | default: |
| 132 | 307 | break; |
| @@ -142,22 +317,39 @@ static void amdgpu_perf_stop(struct perf_event *event, int flags) · 9 unmodified lines | ||
| 142 | 317 | hwc->state |= PERF_HES_UPTODATE; |
| 143 | 318 | } |
| 144 | 319 | |
| 145 | −/* add perf counter */ | |
| 320 | +/* add perf counter */ | |
| 146 | 321 | static int amdgpu_perf_add(struct perf_event *event, int flags) |
| 147 | 322 | { |
| 148 | 323 | struct hw_perf_event *hwc = &event->hw; |
| 149 | − int retval; | |
| 150 | − | |
| 324 | + int retval = 0, target_cntr; | |
| 151 | 325 | struct amdgpu_pmu_entry *pe = container_of(event->pmu, |
| 152 | 326 | struct amdgpu_pmu_entry, |
| 153 | 327 | pmu); |
| 154 | 328 | |
| 329 | + switch (pe->pmu_perf_type) { | |
| 330 | + case AMDGPU_PMU_PERF_TYPE_DF: | |
| 331 | + hwc->config_base = AMDGPU_PMU_EVENT_CONFIG_TYPE_DF; | |
| 332 | + break; | |
| 333 | + case AMDGPU_PMU_PERF_TYPE_ALL: | |
| 334 | + hwc->config_base = (hwc->config >> | |
| 335 | + AMDGPU_PMU_EVENT_CONFIG_TYPE_SHIFT) & | |
| 336 | + AMDGPU_PMU_EVENT_CONFIG_TYPE_MASK; | |
| 337 | + break; | |
| 338 | + } | |
| 339 | + | |
| 155 | 340 | event->hw.state = PERF_HES_UPTODATE | PERF_HES_STOPPED; |
| 156 | 341 | |
| 157 | − switch (pe->pmu_perf_type) { | |
| 158 | − case PERF_TYPE_AMDGPU_DF: | |
| 159 | − retval = pe->adev->df.funcs->pmc_start(pe->adev, | |
| 160 | − hwc->config, 1); | |
| 342 | + switch (hwc->config_base) { | |
| 343 | + case AMDGPU_PMU_EVENT_CONFIG_TYPE_DF: | |
| 344 | + case AMDGPU_PMU_EVENT_CONFIG_TYPE_XGMI: | |
| 345 | + target_cntr = pe->adev->df.funcs->pmc_start(pe->adev, | |
| 346 | + hwc->config, 0 /* unused */, | |
| 347 | + 1 /* add counter */); | |
| 348 | + if (target_cntr < 0) | |
| 349 | + retval = target_cntr; | |
| 350 | + else | |
| 351 | + hwc->idx = target_cntr; | |
| 352 | + | |
| 161 | 353 | break; |
| 162 | 354 | default: |
| 163 | 355 | return 0; |
| @@ -170,7 +362,6 @@ static int amdgpu_perf_add(struct perf_event *event, int flags) · 6 unmodified lines | ||
| 170 | 362 | amdgpu_perf_start(event, PERF_EF_RELOAD); |
| 171 | 363 | |
| 172 | 364 | return retval; |
| 173 | − | |
| 174 | 365 | } |
| 175 | 366 | |
| 176 | 367 | /* delete perf counter */ |
| @@ -183,9 +374,11 @@ static void amdgpu_perf_del(struct perf_event *event, int flags) · 6 unmodified lines | ||
| 183 | 374 | |
| 184 | 375 | amdgpu_perf_stop(event, PERF_EF_UPDATE); |
| 185 | 376 | |
| 186 | − switch (pe->pmu_perf_type) { | |
| 187 | − case PERF_TYPE_AMDGPU_DF: | |
| 188 | − pe->adev->df.funcs->pmc_stop(pe->adev, hwc->config, 1); | |
| 377 | + switch (hwc->config_base) { | |
| 378 | + case AMDGPU_PMU_EVENT_CONFIG_TYPE_DF: | |
| 379 | + case AMDGPU_PMU_EVENT_CONFIG_TYPE_XGMI: | |
| 380 | + pe->adev->df.funcs->pmc_stop(pe->adev, hwc->config, hwc->idx, | |
| 381 | + 1); | |
| 189 | 382 | break; |
| 190 | 383 | default: |
| 191 | 384 | break; |
| @@ -194,25 +387,92 @@ static void amdgpu_perf_del(struct perf_event *event, int flags) · 2 unmodified lines | ||
| 194 | 387 | perf_event_update_userpage(event); |
| 195 | 388 | } |
| 196 | 389 | |
| 197 | −/* vega20 pmus */ | |
| 390 | +static void amdgpu_pmu_create_event_attrs_by_type( | |
| 391 | + struct attribute_group *attr_group, | |
| 392 | + struct amdgpu_pmu_event_attribute *pmu_attr, | |
| 393 | + struct amdgpu_pmu_attr events[], | |
| 394 | + int s_offset, | |
| 395 | + int e_offset, | |
| 396 | + unsigned int type) | |
| 397 | +{ | |
| 398 | + int i; | |
| 399 | + | |
| 400 | + pmu_attr += s_offset; | |
| 401 | + | |
| 402 | + for (i = s_offset; i < e_offset; i++) { | |
| 403 | + attr_group->attrs[i] = &pmu_attr->attr.attr; | |
| 404 | + sysfs_attr_init(&pmu_attr->attr.attr); | |
| 405 | + pmu_attr->attr.attr.name = events[i].name; | |
| 406 | + pmu_attr->attr.attr.mode = 0444; | |
| 407 | + pmu_attr->attr.show = amdgpu_pmu_event_show; | |
| 408 | + pmu_attr->event_str = events[i].config; | |
| 409 | + pmu_attr->type = type; | |
| 410 | + pmu_attr++; | |
| 411 | + } | |
| 412 | +} | |
| 198 | 413 | |
| 199 | −/* init pmu tracking per pmu type */ | |
| 200 | −static int init_pmu_by_type(struct amdgpu_device *adev, | |
| 201 | − const struct attribute_group *attr_groups[], | |
| 202 | − char *pmu_type_name, char *pmu_file_prefix, | |
| 203 | − unsigned int pmu_perf_type, | |
| 204 | − unsigned int num_counters) | |
| 414 | +static void amdgpu_pmu_create_attrs(struct attribute_group *attr_group, | |
| 415 | + struct amdgpu_pmu_event_attribute *pmu_attr, | |
| 416 | + struct amdgpu_pmu_attr events[], | |
| 417 | + int num_events) | |
| 205 | 418 | { |
| 206 | − char pmu_name[PMU_NAME_SIZE]; | |
| 207 | − struct amdgpu_pmu_entry *pmu_entry; | |
| 208 | − int ret = 0; | |
| 419 | + amdgpu_pmu_create_event_attrs_by_type(attr_group, pmu_attr, events, 0, | |
| 420 | + num_events, AMDGPU_PMU_EVENT_CONFIG_TYPE_NONE); | |
| 421 | +} | |
| 209 | 422 | |
| 210 | − pmu_entry = kzalloc(sizeof(struct amdgpu_pmu_entry), GFP_KERNEL); | |
| 211 | 423 | |
| 212 | − if (!pmu_entry) | |
| 424 | +static int amdgpu_pmu_alloc_pmu_attrs( | |
| 425 | + struct attribute_group *fmt_attr_group, | |
| 426 | + struct amdgpu_pmu_event_attribute **fmt_attr, | |
| 427 | + struct attribute_group *evt_attr_group, | |
| 428 | + struct amdgpu_pmu_event_attribute **evt_attr, | |
| 429 | + struct amdgpu_pmu_config *config) | |
| 430 | +{ | |
| 431 | + *fmt_attr = kcalloc(config->num_formats, sizeof(**fmt_attr), | |
| 432 | + GFP_KERNEL); | |
| 433 | + | |
| 434 | + if (!(*fmt_attr)) | |
| 213 | 435 | return -ENOMEM; |
| 214 | 436 | |
| 215 | − pmu_entry->adev = adev; | |
| 437 | + fmt_attr_group->attrs = kcalloc(config->num_formats + 1, | |
| 438 | + sizeof(*fmt_attr_group->attrs), GFP_KERNEL); | |
| 439 | + | |
| 440 | + if (!fmt_attr_group->attrs) | |
| 441 | + goto err_fmt_attr_grp; | |
| 442 | + | |
| 443 | + *evt_attr = kcalloc(config->num_events, sizeof(**evt_attr), GFP_KERNEL); | |
| 444 | + | |
| 445 | + if (!(*evt_attr)) | |
| 446 | + goto err_evt_attr; | |
| 447 | + | |
| 448 | + evt_attr_group->attrs = kcalloc(config->num_events + 1, | |
| 449 | + sizeof(*evt_attr_group->attrs), GFP_KERNEL); | |
| 450 | + | |
| 451 | + if (!evt_attr_group->attrs) | |
| 452 | + goto err_evt_attr_grp; | |
| 453 | + | |
| 454 | + return 0; | |
| 455 | +err_evt_attr_grp: | |
| 456 | + kfree(*evt_attr); | |
| 457 | +err_evt_attr: | |
| 458 | + kfree(fmt_attr_group->attrs); | |
| 459 | +err_fmt_attr_grp: | |
| 460 | + kfree(*fmt_attr); | |
| 461 | + return -ENOMEM; | |
| 462 | +} | |
| 463 | + | |
| 464 | +/* init pmu tracking per pmu type */ | |
| 465 | +static int init_pmu_entry_by_type_and_add(struct amdgpu_pmu_entry *pmu_entry, | |
| 466 | + struct amdgpu_pmu_config *config) | |
| 467 | +{ | |
| 468 | + const struct attribute_group *attr_groups[] = { | |
| 469 | + &pmu_entry->fmt_attr_group, | |
| 470 | + &pmu_entry->evt_attr_group, | |
| 471 | + NULL | |
| 472 | + }; | |
| 473 | + char pmu_name[PMU_NAME_SIZE]; | |
| 474 | + int ret = 0, total_num_events = 0; | |
| 475 | + | |
| 216 | 476 | pmu_entry->pmu = (struct pmu){ |
| 217 | 477 | .event_init = amdgpu_perf_event_init, |
| 218 | 478 | .add = amdgpu_perf_add, |
| @@ -223,59 +483,178 @@ static int init_pmu_by_type(struct amdgpu_device *adev, · 4 unmodified lines | ||
| 223 | 483 | .task_ctx_nr = perf_invalid_context, |
| 224 | 484 | }; |
| 225 | 485 | |
| 226 | − pmu_entry->pmu.attr_groups = attr_groups; | |
| 227 | − pmu_entry->pmu_perf_type = pmu_perf_type; | |
| 228 | − snprintf(pmu_name, PMU_NAME_SIZE, "%s_%d", | |
| 229 | − pmu_file_prefix, adev_to_drm(adev)->primary->index); | |
| 486 | + ret = amdgpu_pmu_alloc_pmu_attrs(&pmu_entry->fmt_attr_group, | |
| 487 | + &pmu_entry->fmt_attr, | |
| 488 | + &pmu_entry->evt_attr_group, | |
| 489 | + &pmu_entry->evt_attr, | |
| 490 | + config); | |
| 491 | + | |
| 492 | + if (ret) | |
| 493 | + goto err_out; | |
| 494 | + | |
| 495 | + amdgpu_pmu_create_attrs(&pmu_entry->fmt_attr_group, pmu_entry->fmt_attr, | |
| 496 | + config->formats, config->num_formats); | |
| 497 | + | |
| 498 | + if (pmu_entry->pmu_perf_type == AMDGPU_PMU_PERF_TYPE_ALL) { | |
| 499 | + int i; | |
| 500 | + | |
| 501 | + for (i = 0; i < config->num_types; i++) { | |
| 502 | + amdgpu_pmu_create_event_attrs_by_type( | |
| 503 | + &pmu_entry->evt_attr_group, | |
| 504 | + pmu_entry->evt_attr, | |
| 505 | + config->events, | |
| 506 | + total_num_events, | |
| 507 | + total_num_events + | |
| 508 | + config->types[i].num_of_type, | |
| 509 | + config->types[i].type); | |
| 510 | + total_num_events += config->types[i].num_of_type; | |
| 511 | + } | |
| 512 | + } else { | |
| 513 | + amdgpu_pmu_create_attrs(&pmu_entry->evt_attr_group, | |
| 514 | + pmu_entry->evt_attr, | |
| 515 | + config->events, config->num_events); | |
| 516 | + total_num_events = config->num_events; | |
| 517 | + } | |
| 518 | + | |
| 519 | + pmu_entry->pmu.attr_groups = kmemdup(attr_groups, sizeof(attr_groups), | |
| 520 | + GFP_KERNEL); | |
| 521 | + | |
| 522 | + if (!pmu_entry->pmu.attr_groups) | |
| 523 | + goto err_attr_group; | |
| 524 | + | |
| 525 | + snprintf(pmu_name, PMU_NAME_SIZE, "%s_%d", pmu_entry->pmu_file_prefix, | |
| 526 | + adev_to_drm(pmu_entry->adev)->primary->index); | |
| 230 | 527 | |
| 231 | 528 | ret = perf_pmu_register(&pmu_entry->pmu, pmu_name, -1); |
| 232 | 529 | |
| 233 | − if (ret) { | |
| 234 | − kfree(pmu_entry); | |
| 235 | − pr_warn("Error initializing AMDGPU %s PMUs.\n", pmu_type_name); | |
| 236 | − return ret; | |
| 237 | − } | |
| 530 | + if (ret) | |
| 531 | + goto err_register; | |
| 532 | + | |
| 533 | + if (pmu_entry->pmu_perf_type != AMDGPU_PMU_PERF_TYPE_ALL) | |
| 534 | + pr_info("Detected AMDGPU %s Counters. # of Counters = %d.\n", | |
| 535 | + pmu_entry->pmu_type_name, total_num_events); | |
| 536 | + else | |
| 537 | + pr_info("Detected AMDGPU %d Perf Events.\n", total_num_events); | |
| 238 | 538 | |
| 239 | − pr_info("Detected AMDGPU %s Counters. # of Counters = %d.\n", | |
| 240 | − pmu_type_name, num_counters); | |
| 241 | 539 | |
| 242 | 540 | list_add_tail(&pmu_entry->entry, &amdgpu_pmu_list); |
| 243 | 541 | |
| 244 | 542 | return 0; |
| 543 | +err_register: | |
| 544 | + kfree(pmu_entry->pmu.attr_groups); | |
| 545 | +err_attr_group: | |
| 546 | + kfree(pmu_entry->fmt_attr_group.attrs); | |
| 547 | + kfree(pmu_entry->fmt_attr); | |
| 548 | + kfree(pmu_entry->evt_attr_group.attrs); | |
| 549 | + kfree(pmu_entry->evt_attr); | |
| 550 | +err_out: | |
| 551 | + pr_warn("Error initializing AMDGPU %s PMUs.\n", | |
| 552 | + pmu_entry->pmu_type_name); | |
| 553 | + return ret; | |
| 554 | +} | |
| 555 | + | |
| 556 | +/* destroy all pmu data associated with target device */ | |
| 557 | +void amdgpu_pmu_fini(struct amdgpu_device *adev) | |
| 558 | +{ | |
| 559 | + struct amdgpu_pmu_entry *pe, *temp; | |
| 560 | + | |
| 561 | + list_for_each_entry_safe(pe, temp, &amdgpu_pmu_list, entry) { | |
| 562 | + if (pe->adev != adev) | |
| 563 | + continue; | |
| 564 | + list_del(&pe->entry); | |
| 565 | + perf_pmu_unregister(&pe->pmu); | |
| 566 | + kfree(pe->pmu.attr_groups); | |
| 567 | + kfree(pe->fmt_attr_group.attrs); | |
| 568 | + kfree(pe->fmt_attr); | |
| 569 | + kfree(pe->evt_attr_group.attrs); | |
| 570 | + kfree(pe->evt_attr); | |
| 571 | + kfree(pe); | |
| 572 | + } | |
| 573 | +} | |
| 574 | + | |
| 575 | +static struct amdgpu_pmu_entry *create_pmu_entry(struct amdgpu_device *adev, | |
| 576 | + unsigned int pmu_type, | |
| 577 | + char *pmu_type_name, | |
| 578 | + char *pmu_file_prefix) | |
| 579 | +{ | |
| 580 | + struct amdgpu_pmu_entry *pmu_entry; | |
| 581 | + | |
| 582 | + pmu_entry = kzalloc(sizeof(struct amdgpu_pmu_entry), GFP_KERNEL); | |
| 583 | + | |
| 584 | + if (!pmu_entry) | |
| 585 | + return pmu_entry; | |
| 586 | + | |
| 587 | + pmu_entry->adev = adev; | |
| 588 | + pmu_entry->fmt_attr_group.name = "format"; | |
| 589 | + pmu_entry->fmt_attr_group.attrs = NULL; | |
| 590 | + pmu_entry->evt_attr_group.name = "events"; | |
| 591 | + pmu_entry->evt_attr_group.attrs = NULL; | |
| 592 | + pmu_entry->pmu_perf_type = pmu_type; | |
| 593 | + pmu_entry->pmu_type_name = pmu_type_name; | |
| 594 | + pmu_entry->pmu_file_prefix = pmu_file_prefix; | |
| 595 | + | |
| 596 | + return pmu_entry; | |
| 245 | 597 | } |
| 246 | 598 | |
| 247 | 599 | /* init amdgpu_pmu */ |
| 248 | 600 | int amdgpu_pmu_init(struct amdgpu_device *adev) |
| 249 | 601 | { |
| 250 | 602 | int ret = 0; |
| 603 | + struct amdgpu_pmu_entry *pmu_entry, *pmu_entry_df; | |
| 251 | 604 | |
| 252 | 605 | switch (adev->asic_type) { |
| 253 | 606 | case CHIP_VEGA20: |
| 254 | − /* init df */ | |
| 255 | − ret = init_pmu_by_type(adev, df_v3_6_attr_groups, | |
| 256 | − "DF", "amdgpu_df", PERF_TYPE_AMDGPU_DF, | |
| 257 | − DF_V3_6_MAX_COUNTERS); | |
| 607 | + pmu_entry_df = create_pmu_entry(adev, AMDGPU_PMU_PERF_TYPE_DF, | |
| 608 | + "DF", "amdgpu_df"); | |
| 258 | 609 | |
| 259 | − /* other pmu types go here*/ | |
| 260 | − break; | |
| 261 | − default: | |
| 262 | − return 0; | |
| 263 | − } | |
| 610 | + if (!pmu_entry_df) | |
| 611 | + return -ENOMEM; | |
| 264 | 612 | |
| 265 | − return 0; | |
| 266 | −} | |
| 613 | + ret = init_pmu_entry_by_type_and_add(pmu_entry_df, | |
| 614 | + &df_vega20_config); | |
| 267 | 615 | |
| 616 | + if (ret) { | |
| 617 | + kfree(pmu_entry_df); | |
| 618 | + return ret; | |
| 619 | + } | |
| 268 | 620 | |
| 269 | −/* destroy all pmu data associated with target device */ | |
| 270 | −void amdgpu_pmu_fini(struct amdgpu_device *adev) | |
| 271 | −{ | |
| 272 | − struct amdgpu_pmu_entry *pe, *temp; | |
| 621 | + pmu_entry = create_pmu_entry(adev, AMDGPU_PMU_PERF_TYPE_ALL, | |
| 622 | + "", "amdgpu"); | |
| 273 | 623 | |
| 274 | − list_for_each_entry_safe(pe, temp, &amdgpu_pmu_list, entry) { | |
| 275 | − if (pe->adev == adev) { | |
| 276 | − list_del(&pe->entry); | |
| 277 | − perf_pmu_unregister(&pe->pmu); | |
| 278 | − kfree(pe); | |
| 624 | + if (!pmu_entry) { | |
| 625 | + amdgpu_pmu_fini(adev); | |
| 626 | + return -ENOMEM; | |
| 627 | + } | |
| 628 | + | |
| 629 | + ret = init_pmu_entry_by_type_and_add(pmu_entry, | |
| 630 | + &vega20_config); | |
| 631 | + | |
| 632 | + if (ret) { | |
| 633 | + kfree(pmu_entry); | |
| 634 | + amdgpu_pmu_fini(adev); | |
| 635 | + return ret; | |
| 636 | + } | |
| 637 | + | |
| 638 | + break; | |
| 639 | + case CHIP_ARCTURUS: | |
| 640 | + pmu_entry = create_pmu_entry(adev, AMDGPU_PMU_PERF_TYPE_ALL, | |
| 641 | + "", "amdgpu"); | |
| 642 | + if (!pmu_entry) | |
| 643 | + return -ENOMEM; | |
| 644 | + | |
| 645 | + ret = init_pmu_entry_by_type_and_add(pmu_entry, | |
| 646 | + &arcturus_config); | |
| 647 | + | |
| 648 | + if (ret) { | |
| 649 | + kfree(pmu_entry); | |
| 650 | + return -ENOMEM; | |
| 279 | 651 | } |
| 652 | + | |
| 653 | + break; | |
| 654 | + | |
| 655 | + default: | |
| 656 | + return 0; | |
| 280 | 657 | } |
| 658 | + | |
| 659 | + return ret; | |
| 281 | 660 | } |
| @@ -19,18 +19,38 @@ · 18 unmodified lines | ||
| 19 | 19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
| 20 | 20 | * OTHER DEALINGS IN THE SOFTWARE. |
| 21 | 21 | * |
| 22 | − * Author: Jonathan Kim <jonathan.kim@amd.com> | |
| 23 | − * | |
| 24 | 22 | */ |
| 25 | 23 | |
| 26 | 24 | #ifndef _AMDGPU_PMU_H_ |
| 27 | 25 | #define _AMDGPU_PMU_H_ |
| 28 | 26 | |
| 27 | +/* PMU types. */ | |
| 29 | 28 | enum amdgpu_pmu_perf_type { |
| 30 | − PERF_TYPE_AMDGPU_DF = 0, | |
| 31 | − PERF_TYPE_AMDGPU_MAX | |
| 29 | + AMDGPU_PMU_PERF_TYPE_NONE = 0, | |
| 30 | + AMDGPU_PMU_PERF_TYPE_DF, | |
| 31 | + AMDGPU_PMU_PERF_TYPE_ALL | |
| 32 | 32 | }; |
| 33 | 33 | |
| 34 | +/* | |
| 35 | + * PMU type AMDGPU_PMU_PERF_TYPE_ALL can hold events of different "type" | |
| 36 | + * configurations. Event config types are parsed from the 64-bit raw | |
| 37 | + * config (See EVENT_CONFIG_TYPE_SHIFT and EVENT_CONFIG_TYPE_MASK) and | |
| 38 | + * are registered into the HW perf events config_base. | |
| 39 | + * | |
| 40 | + * PMU types with only a single event configuration type | |
| 41 | + * (non-AMDGPU_PMU_PERF_TYPE_ALL) have their event config type auto generated | |
| 42 | + * when the performance counter is added. | |
| 43 | + */ | |
| 44 | +enum amdgpu_pmu_event_config_type { | |
| 45 | + AMDGPU_PMU_EVENT_CONFIG_TYPE_NONE = 0, | |
| 46 | + AMDGPU_PMU_EVENT_CONFIG_TYPE_DF, | |
| 47 | + AMDGPU_PMU_EVENT_CONFIG_TYPE_XGMI, | |
| 48 | + AMDGPU_PMU_EVENT_CONFIG_TYPE_MAX | |
| 49 | +}; | |
| 50 | + | |
| 51 | +#define AMDGPU_PMU_EVENT_CONFIG_TYPE_SHIFT 56 | |
| 52 | +#define AMDGPU_PMU_EVENT_CONFIG_TYPE_MASK 0xff | |
| 53 | + | |
| 34 | 54 | int amdgpu_pmu_init(struct amdgpu_device *adev); |
| 35 | 55 | void amdgpu_pmu_fini(struct amdgpu_device *adev); |
| 36 | 56 | |
| @@ -100,6 +100,8 @@ static int psp_early_init(void *handle) · 99 unmodified lines | ||
| 100 | 100 | case CHIP_NAVI12: |
| 101 | 101 | case CHIP_SIENNA_CICHLID: |
| 102 | 102 | case CHIP_NAVY_FLOUNDER: |
| 103 | + case CHIP_VANGOGH: | |
| 104 | + case CHIP_DIMGREY_CAVEFISH: | |
| 103 | 105 | psp_v11_0_set_psp_funcs(psp); |
| 104 | 106 | psp->autoload_supported = true; |
| 105 | 107 | break; |
| @@ -288,6 +290,8 @@ psp_cmd_submit_buf(struct psp_context *psp, · 182 unmodified lines | ||
| 288 | 290 | skip_unsupport = (psp->cmd_buf_mem->resp.status == TEE_ERROR_NOT_SUPPORTED || |
| 289 | 291 | psp->cmd_buf_mem->resp.status == PSP_ERR_UNKNOWN_COMMAND) && amdgpu_sriov_vf(psp->adev); |
| 290 | 292 | |
| 293 | + memcpy((void*)&cmd->resp, (void*)&psp->cmd_buf_mem->resp, sizeof(struct psp_gfx_resp)); | |
| 294 | + | |
| 291 | 295 | /* In some cases, psp response status is not 0 even there is no |
| 292 | 296 | * problem while the command is submitted. Some version of PSP FW |
| 293 | 297 | * doesn't write 0 to that field. |
| @@ -308,9 +312,6 @@ psp_cmd_submit_buf(struct psp_context *psp, · 14 unmodified lines | ||
| 308 | 312 | } |
| 309 | 313 | } |
| 310 | 314 | |
| 311 | − /* get xGMI session id from response buffer */ | |
| 312 | − cmd->resp.session_id = psp->cmd_buf_mem->resp.session_id; | |
| 313 | − | |
| 314 | 315 | if (ucode) { |
| 315 | 316 | ucode->tmr_mc_addr_lo = psp->cmd_buf_mem->resp.fw_addr_lo; |
| 316 | 317 | ucode->tmr_mc_addr_hi = psp->cmd_buf_mem->resp.fw_addr_hi; |
| @@ -509,6 +510,37 @@ static int psp_tmr_terminate(struct psp_context *psp) · 192 unmodified lines | ||
| 509 | 510 | return 0; |
| 510 | 511 | } |
| 511 | 512 | |
| 513 | +int psp_get_fw_attestation_records_addr(struct psp_context *psp, | |
| 514 | + uint64_t *output_ptr) | |
| 515 | +{ | |
| 516 | + int ret; | |
| 517 | + struct psp_gfx_cmd_resp *cmd; | |
| 518 | + | |
| 519 | + if (!output_ptr) | |
| 520 | + return -EINVAL; | |
| 521 | + | |
| 522 | + if (amdgpu_sriov_vf(psp->adev)) | |
| 523 | + return 0; | |
| 524 | + | |
| 525 | + cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL); | |
| 526 | + if (!cmd) | |
| 527 | + return -ENOMEM; | |
| 528 | + | |
| 529 | + cmd->cmd_id = GFX_CMD_ID_GET_FW_ATTESTATION; | |
| 530 | + | |
| 531 | + ret = psp_cmd_submit_buf(psp, NULL, cmd, | |
| 532 | + psp->fence_buf_mc_addr); | |
| 533 | + | |
| 534 | + if (!ret) { | |
| 535 | + *output_ptr = ((uint64_t)cmd->resp.uresp.fwar_db_info.fwar_db_addr_lo) + | |
| 536 | + ((uint64_t)cmd->resp.uresp.fwar_db_info.fwar_db_addr_hi << 32); | |
| 537 | + } | |
| 538 | + | |
| 539 | + kfree(cmd); | |
| 540 | + | |
| 541 | + return ret; | |
| 542 | +} | |
| 543 | + | |
| 512 | 544 | static void psp_prep_asd_load_cmd_buf(struct psp_gfx_cmd_resp *cmd, |
| 513 | 545 | uint64_t asd_mc, uint32_t size) |
| 514 | 546 | { |
| @@ -624,14 +656,14 @@ static void psp_prep_ta_load_cmd_buf(struct psp_gfx_cmd_resp *cmd, · 109 unmodified lines | ||
| 624 | 656 | uint64_t ta_shared_mc, |
| 625 | 657 | uint32_t ta_shared_size) |
| 626 | 658 | { |
| 627 | − cmd->cmd_id = GFX_CMD_ID_LOAD_TA; | |
| 659 | + cmd->cmd_id = GFX_CMD_ID_LOAD_TA; | |
| 628 | 660 | cmd->cmd.cmd_load_ta.app_phy_addr_lo = lower_32_bits(ta_bin_mc); |
| 629 | − cmd->cmd.cmd_load_ta.app_phy_addr_hi = upper_32_bits(ta_bin_mc); | |
| 630 | − cmd->cmd.cmd_load_ta.app_len = ta_bin_size; | |
| 661 | + cmd->cmd.cmd_load_ta.app_phy_addr_hi = upper_32_bits(ta_bin_mc); | |
| 662 | + cmd->cmd.cmd_load_ta.app_len = ta_bin_size; | |
| 631 | 663 | |
| 632 | 664 | cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_lo = lower_32_bits(ta_shared_mc); |
| 633 | 665 | cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_hi = upper_32_bits(ta_shared_mc); |
| 634 | − cmd->cmd.cmd_load_ta.cmd_buf_len = ta_shared_size; | |
| 666 | + cmd->cmd.cmd_load_ta.cmd_buf_len = ta_shared_size; | |
| 635 | 667 | } |
| 636 | 668 | |
| 637 | 669 | static int psp_xgmi_init_shared_buf(struct psp_context *psp) |
| @@ -655,9 +687,9 @@ static void psp_prep_ta_invoke_cmd_buf(struct psp_gfx_cmd_resp *cmd, · 17 unmodified lines | ||
| 655 | 687 | uint32_t ta_cmd_id, |
| 656 | 688 | uint32_t session_id) |
| 657 | 689 | { |
| 658 | − cmd->cmd_id = GFX_CMD_ID_INVOKE_CMD; | |
| 659 | − cmd->cmd.cmd_invoke_cmd.session_id = session_id; | |
| 660 | − cmd->cmd.cmd_invoke_cmd.ta_cmd_id = ta_cmd_id; | |
| 690 | + cmd->cmd_id = GFX_CMD_ID_INVOKE_CMD; | |
| 691 | + cmd->cmd.cmd_invoke_cmd.session_id = session_id; | |
| 692 | + cmd->cmd.cmd_invoke_cmd.ta_cmd_id = ta_cmd_id; | |
| 661 | 693 | } |
| 662 | 694 | |
| 663 | 695 | static int psp_ta_invoke(struct psp_context *psp, |
| @@ -806,7 +838,7 @@ int psp_xgmi_get_hive_id(struct psp_context *psp, uint64_t *hive_id) · 142 unmodified lines | ||
| 806 | 838 | struct ta_xgmi_shared_memory *xgmi_cmd; |
| 807 | 839 | int ret; |
| 808 | 840 | |
| 809 | − xgmi_cmd = (struct ta_xgmi_shared_memory*)psp->xgmi_context.xgmi_shared_buf; | |
| 841 | + xgmi_cmd = (struct ta_xgmi_shared_memory *)psp->xgmi_context.xgmi_shared_buf; | |
| 810 | 842 | memset(xgmi_cmd, 0, sizeof(struct ta_xgmi_shared_memory)); |
| 811 | 843 | |
| 812 | 844 | xgmi_cmd->cmd_id = TA_COMMAND_XGMI__GET_HIVE_ID; |
| @@ -826,7 +858,7 @@ int psp_xgmi_get_node_id(struct psp_context *psp, uint64_t *node_id) · 13 unmodified lines | ||
| 826 | 858 | struct ta_xgmi_shared_memory *xgmi_cmd; |
| 827 | 859 | int ret; |
| 828 | 860 | |
| 829 | − xgmi_cmd = (struct ta_xgmi_shared_memory*)psp->xgmi_context.xgmi_shared_buf; | |
| 861 | + xgmi_cmd = (struct ta_xgmi_shared_memory *)psp->xgmi_context.xgmi_shared_buf; | |
| 830 | 862 | memset(xgmi_cmd, 0, sizeof(struct ta_xgmi_shared_memory)); |
| 831 | 863 | |
| 832 | 864 | xgmi_cmd->cmd_id = TA_COMMAND_XGMI__GET_NODE_ID; |
| @@ -854,7 +886,7 @@ int psp_xgmi_get_topology_info(struct psp_context *psp, · 21 unmodified lines | ||
| 854 | 886 | if (!topology || topology->num_nodes > TA_XGMI__MAX_CONNECTED_NODES) |
| 855 | 887 | return -EINVAL; |
| 856 | 888 | |
| 857 | − xgmi_cmd = (struct ta_xgmi_shared_memory*)psp->xgmi_context.xgmi_shared_buf; | |
| 889 | + xgmi_cmd = (struct ta_xgmi_shared_memory *)psp->xgmi_context.xgmi_shared_buf; | |
| 858 | 890 | memset(xgmi_cmd, 0, sizeof(struct ta_xgmi_shared_memory)); |
| 859 | 891 | |
| 860 | 892 | /* Fill in the shared memory with topology information as input */ |
| @@ -898,7 +930,7 @@ int psp_xgmi_set_topology_info(struct psp_context *psp, · 37 unmodified lines | ||
| 898 | 930 | if (!topology || topology->num_nodes > TA_XGMI__MAX_CONNECTED_NODES) |
| 899 | 931 | return -EINVAL; |
| 900 | 932 | |
| 901 | − xgmi_cmd = (struct ta_xgmi_shared_memory*)psp->xgmi_context.xgmi_shared_buf; | |
| 933 | + xgmi_cmd = (struct ta_xgmi_shared_memory *)psp->xgmi_context.xgmi_shared_buf; | |
| 902 | 934 | memset(xgmi_cmd, 0, sizeof(struct ta_xgmi_shared_memory)); |
| 903 | 935 | |
| 904 | 936 | topology_info_input = &xgmi_cmd->xgmi_in_message.get_topology_info; |
| @@ -962,7 +994,7 @@ static int psp_ras_load(struct psp_context *psp) · 57 unmodified lines | ||
| 962 | 994 | ret = psp_cmd_submit_buf(psp, NULL, cmd, |
| 963 | 995 | psp->fence_buf_mc_addr); |
| 964 | 996 | |
| 965 | − ras_cmd = (struct ta_ras_shared_memory*)psp->ras.ras_shared_buf; | |
| 997 | + ras_cmd = (struct ta_ras_shared_memory *)psp->ras.ras_shared_buf; | |
| 966 | 998 | |
| 967 | 999 | if (!ret) { |
| 968 | 1000 | psp->ras.session_id = cmd->resp.session_id; |
| @@ -1884,7 +1916,7 @@ static int psp_execute_np_fw_load(struct psp_context *psp, · 915 unmodified lines | ||
| 1884 | 1916 | static int psp_load_smu_fw(struct psp_context *psp) |
| 1885 | 1917 | { |
| 1886 | 1918 | int ret; |
| 1887 | − struct amdgpu_device* adev = psp->adev; | |
| 1919 | + struct amdgpu_device *adev = psp->adev; | |
| 1888 | 1920 | struct amdgpu_firmware_info *ucode = |
| 1889 | 1921 | &adev->firmware.ucode[AMDGPU_UCODE_ID_SMC]; |
| 1890 | 1922 | struct amdgpu_ras *ras = psp->ras.ras; |
| @@ -1950,7 +1982,7 @@ static int psp_np_fw_load(struct psp_context *psp) · 59 unmodified lines | ||
| 1950 | 1982 | { |
| 1951 | 1983 | int i, ret; |
| 1952 | 1984 | struct amdgpu_firmware_info *ucode; |
| 1953 | − struct amdgpu_device* adev = psp->adev; | |
| 1985 | + struct amdgpu_device *adev = psp->adev; | |
| 1954 | 1986 | |
| 1955 | 1987 | if (psp->autoload_supported && |
| 1956 | 1988 | !psp->pmfw_centralized_cstate_management) { |
| @@ -1974,8 +2006,8 @@ static int psp_np_fw_load(struct psp_context *psp) · 17 unmodified lines | ||
| 1974 | 2006 | continue; |
| 1975 | 2007 | |
| 1976 | 2008 | if (psp->autoload_supported && |
| 1977 | − (adev->asic_type == CHIP_SIENNA_CICHLID || | |
| 1978 | − adev->asic_type == CHIP_NAVY_FLOUNDER) && | |
| 2009 | + (adev->asic_type >= CHIP_SIENNA_CICHLID && | |
| 2010 | + adev->asic_type <= CHIP_DIMGREY_CAVEFISH) && | |
| 1979 | 2011 | (ucode->ucode_id == AMDGPU_UCODE_ID_SDMA1 || |
| 1980 | 2012 | ucode->ucode_id == AMDGPU_UCODE_ID_SDMA2 || |
| 1981 | 2013 | ucode->ucode_id == AMDGPU_UCODE_ID_SDMA3)) |
| @@ -2390,7 +2422,7 @@ int psp_init_asd_microcode(struct psp_context *psp, · 408 unmodified lines | ||
| 2390 | 2422 | const char *chip_name) |
| 2391 | 2423 | { |
| 2392 | 2424 | struct amdgpu_device *adev = psp->adev; |
| 2393 | − char fw_name[30]; | |
| 2425 | + char fw_name[PSP_FW_NAME_LEN]; | |
| 2394 | 2426 | const struct psp_firmware_header_v1_0 *asd_hdr; |
| 2395 | 2427 | int err = 0; |
| 2396 | 2428 | |
| @@ -2422,11 +2454,47 @@ out: · 25 unmodified lines | ||
| 2422 | 2454 | return err; |
| 2423 | 2455 | } |
| 2424 | 2456 | |
| 2425 | −int psp_init_sos_microcode(struct psp_context *psp, | |
| 2457 | +int psp_init_toc_microcode(struct psp_context *psp, | |
| 2426 | 2458 | const char *chip_name) |
| 2427 | 2459 | { |
| 2428 | 2460 | struct amdgpu_device *adev = psp->adev; |
| 2429 | 2461 | char fw_name[30]; |
| 2462 | + const struct psp_firmware_header_v1_0 *toc_hdr; | |
| 2463 | + int err = 0; | |
| 2464 | + | |
| 2465 | + if (!chip_name) { | |
| 2466 | + dev_err(adev->dev, "invalid chip name for toc microcode\n"); | |
| 2467 | + return -EINVAL; | |
| 2468 | + } | |
| 2469 | + | |
| 2470 | + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_toc.bin", chip_name); | |
| 2471 | + err = request_firmware(&adev->psp.toc_fw, fw_name, adev->dev); | |
| 2472 | + if (err) | |
| 2473 | + goto out; | |
| 2474 | + | |
| 2475 | + err = amdgpu_ucode_validate(adev->psp.toc_fw); | |
| 2476 | + if (err) | |
| 2477 | + goto out; | |
| 2478 | + | |
| 2479 | + toc_hdr = (const struct psp_firmware_header_v1_0 *)adev->psp.toc_fw->data; | |
| 2480 | + adev->psp.toc_fw_version = le32_to_cpu(toc_hdr->header.ucode_version); | |
| 2481 | + adev->psp.toc_feature_version = le32_to_cpu(toc_hdr->ucode_feature_version); | |
| 2482 | + adev->psp.toc_bin_size = le32_to_cpu(toc_hdr->header.ucode_size_bytes); | |
| 2483 | + adev->psp.toc_start_addr = (uint8_t *)toc_hdr + | |
| 2484 | + le32_to_cpu(toc_hdr->header.ucode_array_offset_bytes); | |
| 2485 | + return 0; | |
| 2486 | +out: | |
| 2487 | + dev_err(adev->dev, "fail to request/validate toc microcode\n"); | |
| 2488 | + release_firmware(adev->psp.toc_fw); | |
| 2489 | + adev->psp.toc_fw = NULL; | |
| 2490 | + return err; | |
| 2491 | +} | |
| 2492 | + | |
| 2493 | +int psp_init_sos_microcode(struct psp_context *psp, | |
| 2494 | + const char *chip_name) | |
| 2495 | +{ | |
| 2496 | + struct amdgpu_device *adev = psp->adev; | |
| 2497 | + char fw_name[PSP_FW_NAME_LEN]; | |
| 2430 | 2498 | const struct psp_firmware_header_v1_0 *sos_hdr; |
| 2431 | 2499 | const struct psp_firmware_header_v1_1 *sos_hdr_v1_1; |
| 2432 | 2500 | const struct psp_firmware_header_v1_2 *sos_hdr_v1_2; |
| @@ -2520,10 +2588,11 @@ int parse_ta_bin_descriptor(struct psp_context *psp, · 87 unmodified lines | ||
| 2520 | 2588 | |
| 2521 | 2589 | switch (desc->fw_type) { |
| 2522 | 2590 | case TA_FW_TYPE_PSP_ASD: |
| 2523 | − psp->asd_fw_version = le32_to_cpu(desc->fw_version); | |
| 2591 | + psp->asd_fw_version = le32_to_cpu(desc->fw_version); | |
| 2524 | 2592 | psp->asd_feature_version = le32_to_cpu(desc->fw_version); |
| 2525 | − psp->asd_ucode_size = le32_to_cpu(desc->size_bytes); | |
| 2593 | + psp->asd_ucode_size = le32_to_cpu(desc->size_bytes); | |
| 2526 | 2594 | psp->asd_start_addr = ucode_start_addr; |
| 2595 | + psp->asd_fw = psp->ta_fw; | |
| 2527 | 2596 | break; |
| 2528 | 2597 | case TA_FW_TYPE_PSP_XGMI: |
| 2529 | 2598 | psp->ta_xgmi_ucode_version = le32_to_cpu(desc->fw_version); |
| @@ -41,6 +41,7 @@ · 40 unmodified lines | ||
| 41 | 41 | #define PSP_DTM_SHARED_MEM_SIZE 0x4000 |
| 42 | 42 | #define PSP_RAP_SHARED_MEM_SIZE 0x4000 |
| 43 | 43 | #define PSP_SHARED_MEM_SIZE 0x4000 |
| 44 | +#define PSP_FW_NAME_LEN 0x24 | |
| 44 | 45 | |
| 45 | 46 | struct psp_context; |
| 46 | 47 | struct psp_xgmi_node_info; |
| @@ -253,6 +254,11 @@ struct psp_context · 206 unmodified lines | ||
| 253 | 254 | uint32_t asd_ucode_size; |
| 254 | 255 | uint8_t *asd_start_addr; |
| 255 | 256 | |
| 257 | + /* toc firmware */ | |
| 258 | + const struct firmware *toc_fw; | |
| 259 | + uint32_t toc_fw_version; | |
| 260 | + uint32_t toc_feature_version; | |
| 261 | + | |
| 256 | 262 | /* fence buffer */ |
| 257 | 263 | struct amdgpu_bo *fence_buf_bo; |
| 258 | 264 | uint64_t fence_buf_mc_addr; |
| @@ -386,8 +392,12 @@ int psp_ring_cmd_submit(struct psp_context *psp, · 127 unmodified lines | ||
| 386 | 392 | int index); |
| 387 | 393 | int psp_init_asd_microcode(struct psp_context *psp, |
| 388 | 394 | const char *chip_name); |
| 395 | +int psp_init_toc_microcode(struct psp_context *psp, | |
| 396 | + const char *chip_name); | |
| 389 | 397 | int psp_init_sos_microcode(struct psp_context *psp, |
| 390 | 398 | const char *chip_name); |
| 391 | 399 | int psp_init_ta_microcode(struct psp_context *psp, |
| 392 | 400 | const char *chip_name); |
| 401 | +int psp_get_fw_attestation_records_addr(struct psp_context *psp, | |
| 402 | + uint64_t *output_ptr); | |
| 393 | 403 | #endif |
| @@ -80,6 +80,8 @@ enum amdgpu_ras_retire_page_reservation { · 79 unmodified lines | ||
| 80 | 80 | |
| 81 | 81 | atomic_t amdgpu_ras_in_intr = ATOMIC_INIT(0); |
| 82 | 82 | |
| 83 | +static bool amdgpu_ras_check_bad_page_unlock(struct amdgpu_ras *con, | |
| 84 | + uint64_t addr); | |
| 83 | 85 | static bool amdgpu_ras_check_bad_page(struct amdgpu_device *adev, |
| 84 | 86 | uint64_t addr); |
| 85 | 87 | |
| @@ -516,9 +518,9 @@ struct ras_manager *amdgpu_ras_find_obj(struct amdgpu_device *adev, · 430 unmodified lines | ||
| 516 | 518 | /* obj end */ |
| 517 | 519 | |
| 518 | 520 | static void amdgpu_ras_parse_status_code(struct amdgpu_device *adev, |
| 519 | − const char* invoke_type, | |
| 520 | − const char* block_name, | |
| 521 | − enum ta_ras_status ret) | |
| 521 | + const char* invoke_type, | |
| 522 | + const char* block_name, | |
| 523 | + enum ta_ras_status ret) | |
| 522 | 524 | { |
| 523 | 525 | switch (ret) { |
| 524 | 526 | case TA_RAS_STATUS__SUCCESS: |
| @@ -607,7 +609,7 @@ int amdgpu_ras_feature_enable(struct amdgpu_device *adev, · 82 unmodified lines | ||
| 607 | 609 | if (!con) |
| 608 | 610 | return -EINVAL; |
| 609 | 611 | |
| 610 | − info = kzalloc(sizeof(union ta_ras_cmd_input), GFP_KERNEL); | |
| 612 | + info = kzalloc(sizeof(union ta_ras_cmd_input), GFP_KERNEL); | |
| 611 | 613 | if (!info) |
| 612 | 614 | return -ENOMEM; |
| 613 | 615 | |
| @@ -953,7 +955,7 @@ static char *amdgpu_ras_badpage_flags_str(unsigned int flags) · 339 unmodified lines | ||
| 953 | 955 | case AMDGPU_RAS_RETIRE_PAGE_FAULT: |
| 954 | 956 | default: |
| 955 | 957 | return "F"; |
| 956 | − }; | |
| 958 | + } | |
| 957 | 959 | } |
| 958 | 960 | |
| 959 | 961 | /** |
| @@ -1551,10 +1553,12 @@ static int amdgpu_ras_badpages_read(struct amdgpu_device *adev, · 591 unmodified lines | ||
| 1551 | 1553 | .size = AMDGPU_GPU_PAGE_SIZE, |
| 1552 | 1554 | .flags = AMDGPU_RAS_RETIRE_PAGE_RESERVED, |
| 1553 | 1555 | }; |
| 1554 | − | |
| 1555 | − if (data->last_reserved <= i) | |
| 1556 | + ret = amdgpu_vram_mgr_query_page_status( | |
| 1557 | + ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM), | |
| 1558 | + data->bps[i].retired_page); | |
| 1559 | + if (ret == -EBUSY) | |
| 1556 | 1560 | (*bps)[i].flags = AMDGPU_RAS_RETIRE_PAGE_PENDING; |
| 1557 | − else if (data->bps_bo[i] == NULL) | |
| 1561 | + else if (ret == -ENOENT) | |
| 1558 | 1562 | (*bps)[i].flags = AMDGPU_RAS_RETIRE_PAGE_FAULT; |
| 1559 | 1563 | } |
| 1560 | 1564 | |
| @@ -1606,12 +1610,9 @@ static int amdgpu_ras_realloc_eh_data_space(struct amdgpu_device *adev, · 45 unmodified lines | ||
| 1606 | 1610 | unsigned int new_space = old_space + pages; |
| 1607 | 1611 | unsigned int align_space = ALIGN(new_space, 512); |
| 1608 | 1612 | void *bps = kmalloc(align_space * sizeof(*data->bps), GFP_KERNEL); |
| 1609 | − struct amdgpu_bo **bps_bo = | |
| 1610 | − kmalloc(align_space * sizeof(*data->bps_bo), GFP_KERNEL); | |
| 1611 | 1613 | |
| 1612 | − if (!bps || !bps_bo) { | |
| 1614 | + if (!bps) { | |
| 1613 | 1615 | kfree(bps); |
| 1614 | − kfree(bps_bo); | |
| 1615 | 1616 | return -ENOMEM; |
| 1616 | 1617 | } |
| 1617 | 1618 | |
| @@ -1620,14 +1621,8 @@ static int amdgpu_ras_realloc_eh_data_space(struct amdgpu_device *adev, · 2 unmodified lines | ||
| 1620 | 1621 | data->count * sizeof(*data->bps)); |
| 1621 | 1622 | kfree(data->bps); |
| 1622 | 1623 | } |
| 1623 | − if (data->bps_bo) { | |
| 1624 | − memcpy(bps_bo, data->bps_bo, | |
| 1625 | − data->count * sizeof(*data->bps_bo)); | |
| 1626 | − kfree(data->bps_bo); | |
| 1627 | − } | |
| 1628 | 1624 | |
| 1629 | 1625 | data->bps = bps; |
| 1630 | − data->bps_bo = bps_bo; | |
| 1631 | 1626 | data->space_left += align_space - old_space; |
| 1632 | 1627 | return 0; |
| 1633 | 1628 | } |
| @@ -1639,6 +1634,7 @@ int amdgpu_ras_add_bad_pages(struct amdgpu_device *adev, · 5 unmodified lines | ||
| 1639 | 1634 | struct amdgpu_ras *con = amdgpu_ras_get_context(adev); |
| 1640 | 1635 | struct ras_err_handler_data *data; |
| 1641 | 1636 | int ret = 0; |
| 1637 | + uint32_t i; | |
| 1642 | 1638 | |
| 1643 | 1639 | if (!con || !con->eh_data || !bps || pages <= 0) |
| 1644 | 1640 | return 0; |
| @@ -1648,16 +1644,26 @@ int amdgpu_ras_add_bad_pages(struct amdgpu_device *adev, · 3 unmodified lines | ||
| 1648 | 1644 | if (!data) |
| 1649 | 1645 | goto out; |
| 1650 | 1646 | |
| 1651 | − if (data->space_left <= pages) | |
| 1652 | − if (amdgpu_ras_realloc_eh_data_space(adev, data, pages)) { | |
| 1647 | + for (i = 0; i < pages; i++) { | |
| 1648 | + if (amdgpu_ras_check_bad_page_unlock(con, | |
| 1649 | + bps[i].retired_page << AMDGPU_GPU_PAGE_SHIFT)) | |
| 1650 | + continue; | |
| 1651 | + | |
| 1652 | + if (!data->space_left && | |
| 1653 | + amdgpu_ras_realloc_eh_data_space(adev, data, 256)) { | |
| 1653 | 1654 | ret = -ENOMEM; |
| 1654 | 1655 | goto out; |
| 1655 | 1656 | } |
| 1656 | 1657 | |
| 1657 | − memcpy(&data->bps[data->count], bps, pages * sizeof(*data->bps)); | |
| 1658 | − data->count += pages; | |
| 1659 | − data->space_left -= pages; | |
| 1658 | + amdgpu_vram_mgr_reserve_range( | |
| 1659 | + ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM), | |
| 1660 | + bps[i].retired_page << AMDGPU_GPU_PAGE_SHIFT, | |
| 1661 | + AMDGPU_GPU_PAGE_SIZE); | |
| 1660 | 1662 | |
| 1663 | + memcpy(&data->bps[data->count], &bps[i], sizeof(*data->bps)); | |
| 1664 | + data->count++; | |
| 1665 | + data->space_left--; | |
| 1666 | + } | |
| 1661 | 1667 | out: |
| 1662 | 1668 | mutex_unlock(&con->recovery_lock); |
| 1663 | 1669 | |
| @@ -1668,7 +1674,7 @@ out: · 4 unmodified lines | ||
| 1668 | 1674 | * write error record array to eeprom, the function should be |
| 1669 | 1675 | * protected by recovery_lock |
| 1670 | 1676 | */ |
| 1671 | −static int amdgpu_ras_save_bad_pages(struct amdgpu_device *adev) | |
| 1677 | +int amdgpu_ras_save_bad_pages(struct amdgpu_device *adev) | |
| 1672 | 1678 | { |
| 1673 | 1679 | struct amdgpu_ras *con = amdgpu_ras_get_context(adev); |
| 1674 | 1680 | struct ras_err_handler_data *data; |
| @@ -1730,6 +1736,20 @@ out: · 55 unmodified lines | ||
| 1730 | 1736 | return ret; |
| 1731 | 1737 | } |
| 1732 | 1738 | |
| 1739 | +static bool amdgpu_ras_check_bad_page_unlock(struct amdgpu_ras *con, | |
| 1740 | + uint64_t addr) | |
| 1741 | +{ | |
| 1742 | + struct ras_err_handler_data *data = con->eh_data; | |
| 1743 | + int i; | |
| 1744 | + | |
| 1745 | + addr >>= AMDGPU_GPU_PAGE_SHIFT; | |
| 1746 | + for (i = 0; i < data->count; i++) | |
| 1747 | + if (addr == data->bps[i].retired_page) | |
| 1748 | + return true; | |
| 1749 | + | |
| 1750 | + return false; | |
| 1751 | +} | |
| 1752 | + | |
| 1733 | 1753 | /* |
| 1734 | 1754 | * check if an address belongs to bad page |
| 1735 | 1755 | * |
| @@ -1739,26 +1759,13 @@ static bool amdgpu_ras_check_bad_page(struct amdgpu_device *adev, · 3 unmodified lines | ||
| 1739 | 1759 | uint64_t addr) |
| 1740 | 1760 | { |
| 1741 | 1761 | struct amdgpu_ras *con = amdgpu_ras_get_context(adev); |
| 1742 | − struct ras_err_handler_data *data; | |
| 1743 | − int i; | |
| 1744 | 1762 | bool ret = false; |
| 1745 | 1763 | |
| 1746 | 1764 | if (!con || !con->eh_data) |
| 1747 | 1765 | return ret; |
| 1748 | 1766 | |
| 1749 | 1767 | mutex_lock(&con->recovery_lock); |
| 1750 | − data = con->eh_data; | |
| 1751 | − if (!data) | |
| 1752 | − goto out; | |
| 1753 | − | |
| 1754 | − addr >>= AMDGPU_GPU_PAGE_SHIFT; | |
| 1755 | − for (i = 0; i < data->count; i++) | |
| 1756 | − if (addr == data->bps[i].retired_page) { | |
| 1757 | − ret = true; | |
| 1758 | − goto out; | |
| 1759 | − } | |
| 1760 | − | |
| 1761 | −out: | |
| 1768 | + ret = amdgpu_ras_check_bad_page_unlock(con, addr); | |
| 1762 | 1769 | mutex_unlock(&con->recovery_lock); |
| 1763 | 1770 | return ret; |
| 1764 | 1771 | } |
| @@ -1804,80 +1811,6 @@ static void amdgpu_ras_validate_threshold(struct amdgpu_device *adev, · 39 unmodified lines | ||
| 1804 | 1811 | } |
| 1805 | 1812 | } |
| 1806 | 1813 | |
| 1807 | −/* called in gpu recovery/init */ | |
| 1808 | −int amdgpu_ras_reserve_bad_pages(struct amdgpu_device *adev) | |
| 1809 | −{ | |
| 1810 | − struct amdgpu_ras *con = amdgpu_ras_get_context(adev); | |
| 1811 | − struct ras_err_handler_data *data; | |
| 1812 | − uint64_t bp; | |
| 1813 | − struct amdgpu_bo *bo = NULL; | |
| 1814 | − int i, ret = 0; | |
| 1815 | − | |
| 1816 | − /* Not reserve bad page when amdgpu_bad_page_threshold == 0. */ | |
| 1817 | − if (!con || !con->eh_data || (amdgpu_bad_page_threshold == 0)) | |
| 1818 | − return 0; | |
| 1819 | − | |
| 1820 | − mutex_lock(&con->recovery_lock); | |
| 1821 | − data = con->eh_data; | |
| 1822 | − if (!data) | |
| 1823 | − goto out; | |
| 1824 | − /* reserve vram at driver post stage. */ | |
| 1825 | − for (i = data->last_reserved; i < data->count; i++) { | |
| 1826 | − bp = data->bps[i].retired_page; | |
| 1827 | − | |
| 1828 | − /* There are two cases of reserve error should be ignored: | |
| 1829 | − * 1) a ras bad page has been allocated (used by someone); | |
| 1830 | − * 2) a ras bad page has been reserved (duplicate error injection | |
| 1831 | − * for one page); | |
| 1832 | − */ | |
| 1833 | − if (amdgpu_bo_create_kernel_at(adev, bp << AMDGPU_GPU_PAGE_SHIFT, | |
| 1834 | − AMDGPU_GPU_PAGE_SIZE, | |
| 1835 | − AMDGPU_GEM_DOMAIN_VRAM, | |
| 1836 | − &bo, NULL)) | |
| 1837 | − dev_warn(adev->dev, "RAS WARN: reserve vram for " | |
| 1838 | − "retired page %llx fail\n", bp); | |
| 1839 | − | |
| 1840 | − data->bps_bo[i] = bo; | |
| 1841 | − data->last_reserved = i + 1; | |
| 1842 | − bo = NULL; | |
| 1843 | − } | |
| 1844 | − | |
| 1845 | − /* continue to save bad pages to eeprom even reesrve_vram fails */ | |
| 1846 | − ret = amdgpu_ras_save_bad_pages(adev); | |
| 1847 | −out: | |
| 1848 | − mutex_unlock(&con->recovery_lock); | |
| 1849 | − return ret; | |
| 1850 | −} | |
| 1851 | − | |
| 1852 | −/* called when driver unload */ | |
| 1853 | −static int amdgpu_ras_release_bad_pages(struct amdgpu_device *adev) | |
| 1854 | −{ | |
| 1855 | − struct amdgpu_ras *con = amdgpu_ras_get_context(adev); | |
| 1856 | − struct ras_err_handler_data *data; | |
| 1857 | − struct amdgpu_bo *bo; | |
| 1858 | − int i; | |
| 1859 | − | |
| 1860 | − if (!con || !con->eh_data) | |
| 1861 | − return 0; | |
| 1862 | − | |
| 1863 | − mutex_lock(&con->recovery_lock); | |
| 1864 | − data = con->eh_data; | |
| 1865 | − if (!data) | |
| 1866 | − goto out; | |
| 1867 | − | |
| 1868 | − for (i = data->last_reserved - 1; i >= 0; i--) { | |
| 1869 | − bo = data->bps_bo[i]; | |
| 1870 | − | |
| 1871 | − amdgpu_bo_free_kernel(&bo, NULL, NULL); | |
| 1872 | − | |
| 1873 | − data->bps_bo[i] = bo; | |
| 1874 | − data->last_reserved = i; | |
| 1875 | − } | |
| 1876 | −out: | |
| 1877 | − mutex_unlock(&con->recovery_lock); | |
| 1878 | − return 0; | |
| 1879 | −} | |
| 1880 | − | |
| 1881 | 1814 | int amdgpu_ras_recovery_init(struct amdgpu_device *adev) |
| 1882 | 1815 | { |
| 1883 | 1816 | struct amdgpu_ras *con = amdgpu_ras_get_context(adev); |
| @@ -1917,18 +1850,12 @@ int amdgpu_ras_recovery_init(struct amdgpu_device *adev) · 33 unmodified lines | ||
| 1917 | 1850 | ret = amdgpu_ras_load_bad_pages(adev); |
| 1918 | 1851 | if (ret) |
| 1919 | 1852 | goto free; |
| 1920 | − ret = amdgpu_ras_reserve_bad_pages(adev); | |
| 1921 | − if (ret) | |
| 1922 | − goto release; | |
| 1923 | 1853 | } |
| 1924 | 1854 | |
| 1925 | 1855 | return 0; |
| 1926 | 1856 | |
| 1927 | −release: | |
| 1928 | − amdgpu_ras_release_bad_pages(adev); | |
| 1929 | 1857 | free: |
| 1930 | 1858 | kfree((*data)->bps); |
| 1931 | − kfree((*data)->bps_bo); | |
| 1932 | 1859 | kfree(*data); |
| 1933 | 1860 | con->eh_data = NULL; |
| 1934 | 1861 | out: |
| @@ -1956,12 +1883,10 @@ static int amdgpu_ras_recovery_fini(struct amdgpu_device *adev) · 21 unmodified lines | ||
| 1956 | 1883 | return 0; |
| 1957 | 1884 | |
| 1958 | 1885 | cancel_work_sync(&con->recovery_work); |
| 1959 | − amdgpu_ras_release_bad_pages(adev); | |
| 1960 | 1886 | |
| 1961 | 1887 | mutex_lock(&con->recovery_lock); |
| 1962 | 1888 | con->eh_data = NULL; |
| 1963 | 1889 | kfree(data->bps); |
| 1964 | − kfree(data->bps_bo); | |
| 1965 | 1890 | kfree(data); |
| 1966 | 1891 | mutex_unlock(&con->recovery_lock); |
| 1967 | 1892 | |
| @@ -2156,7 +2081,7 @@ void amdgpu_ras_late_fini(struct amdgpu_device *adev, · 188 unmodified lines | ||
| 2156 | 2081 | |
| 2157 | 2082 | amdgpu_ras_sysfs_remove(adev, ras_block); |
| 2158 | 2083 | if (ih_info->cb) |
| 2159 | − amdgpu_ras_interrupt_remove_handler(adev, ih_info); | |
| 2084 | + amdgpu_ras_interrupt_remove_handler(adev, ih_info); | |
| 2160 | 2085 | amdgpu_ras_feature_enable(adev, ras_block, 0); |
| 2161 | 2086 | } |
| 2162 | 2087 | |
| @@ -33,7 +33,6 @@ · 32 unmodified lines | ||
| 33 | 33 | |
| 34 | 34 | #define AMDGPU_RAS_FLAG_INIT_BY_VBIOS (0x1 << 0) |
| 35 | 35 | #define AMDGPU_RAS_FLAG_INIT_NEED_RESET (0x1 << 1) |
| 36 | −#define AMDGPU_RAS_FLAG_SKIP_BAD_PAGE_RESV (0x1 << 2) | |
| 37 | 36 | |
| 38 | 37 | enum amdgpu_ras_block { |
| 39 | 38 | AMDGPU_RAS_BLOCK__UMC = 0, |
| @@ -363,14 +362,10 @@ struct ras_err_data { · 323 unmodified lines | ||
| 363 | 362 | struct ras_err_handler_data { |
| 364 | 363 | /* point to bad page records array */ |
| 365 | 364 | struct eeprom_table_record *bps; |
| 366 | − /* point to reserved bo array */ | |
| 367 | − struct amdgpu_bo **bps_bo; | |
| 368 | 365 | /* the count of entries */ |
| 369 | 366 | int count; |
| 370 | 367 | /* the space can place new entries */ |
| 371 | 368 | int space_left; |
| 372 | − /* last reserved entry's index + 1 */ | |
| 373 | − int last_reserved; | |
| 374 | 369 | }; |
| 375 | 370 | |
| 376 | 371 | typedef int (*ras_ih_cb)(struct amdgpu_device *adev, |
| @@ -506,22 +501,12 @@ bool amdgpu_ras_check_err_threshold(struct amdgpu_device *adev); · 129 unmodified lines | ||
| 506 | 501 | int amdgpu_ras_add_bad_pages(struct amdgpu_device *adev, |
| 507 | 502 | struct eeprom_table_record *bps, int pages); |
| 508 | 503 | |
| 509 | −int amdgpu_ras_reserve_bad_pages(struct amdgpu_device *adev); | |
| 504 | +int amdgpu_ras_save_bad_pages(struct amdgpu_device *adev); | |
| 510 | 505 | |
| 511 | 506 | static inline int amdgpu_ras_reset_gpu(struct amdgpu_device *adev) |
| 512 | 507 | { |
| 513 | 508 | struct amdgpu_ras *ras = amdgpu_ras_get_context(adev); |
| 514 | 509 | |
| 515 | − /* | |
| 516 | − * Save bad page to eeprom before gpu reset, i2c may be unstable | |
| 517 | − * in gpu reset. | |
| 518 | − * | |
| 519 | − * Also, exclude the case when ras recovery issuer is | |
| 520 | − * eeprom page write itself. | |
| 521 | − */ | |
| 522 | − if (!(ras->flags & AMDGPU_RAS_FLAG_SKIP_BAD_PAGE_RESV) && in_task()) | |
| 523 | − amdgpu_ras_reserve_bad_pages(adev); | |
| 524 | − | |
| 525 | 510 | if (atomic_cmpxchg(&ras->in_recovery, 0, 1) == 0) |
| 526 | 511 | schedule_work(&ras->recovery_work); |
| 527 | 512 | return 0; |
| @@ -27,9 +27,9 @@ · 26 unmodified lines | ||
| 27 | 27 | #include <linux/bits.h> |
| 28 | 28 | #include "atom.h" |
| 29 | 29 | |
| 30 | −#define EEPROM_I2C_TARGET_ADDR_VEGA20 0xA0 | |
| 31 | −#define EEPROM_I2C_TARGET_ADDR_ARCTURUS 0xA8 | |
| 32 | −#define EEPROM_I2C_TARGET_ADDR_ARCTURUS_D342 0xA0 | |
| 30 | +#define EEPROM_I2C_TARGET_ADDR_VEGA20 0xA0 | |
| 31 | +#define EEPROM_I2C_TARGET_ADDR_ARCTURUS 0xA8 | |
| 32 | +#define EEPROM_I2C_TARGET_ADDR_ARCTURUS_D342 0xA0 | |
| 33 | 33 | |
| 34 | 34 | /* |
| 35 | 35 | * The 2 macros bellow represent the actual size in bytes that |
| @@ -124,11 +124,11 @@ static void __decode_table_header_from_buff(struct amdgpu_ras_eeprom_table_heade · 88 unmodified lines | ||
| 124 | 124 | { |
| 125 | 125 | uint32_t *pp = (uint32_t *)buff; |
| 126 | 126 | |
| 127 | − hdr->header = le32_to_cpu(pp[0]); | |
| 128 | − hdr->version = le32_to_cpu(pp[1]); | |
| 127 | + hdr->header = le32_to_cpu(pp[0]); | |
| 128 | + hdr->version = le32_to_cpu(pp[1]); | |
| 129 | 129 | hdr->first_rec_offset = le32_to_cpu(pp[2]); |
| 130 | − hdr->tbl_size = le32_to_cpu(pp[3]); | |
| 131 | − hdr->checksum = le32_to_cpu(pp[4]); | |
| 130 | + hdr->tbl_size = le32_to_cpu(pp[3]); | |
| 131 | + hdr->checksum = le32_to_cpu(pp[4]); | |
| 132 | 132 | } |
| 133 | 133 | |
| 134 | 134 | static int __update_table_header(struct amdgpu_ras_eeprom_control *control, |
| @@ -149,7 +149,11 @@ static int __update_table_header(struct amdgpu_ras_eeprom_control *control, · 14 unmodified lines | ||
| 149 | 149 | |
| 150 | 150 | msg.addr = control->i2c_address; |
| 151 | 151 | |
| 152 | + /* i2c may be unstable in gpu reset */ | |
| 153 | + down_read(&adev->reset_sem); | |
| 152 | 154 | ret = i2c_transfer(&adev->pm.smu_i2c, &msg, 1); |
| 155 | + up_read(&adev->reset_sem); | |
| 156 | + | |
| 153 | 157 | if (ret < 1) |
| 154 | 158 | DRM_ERROR("Failed to write EEPROM table header, ret:%d", ret); |
| 155 | 159 | |
| @@ -475,7 +479,6 @@ int amdgpu_ras_eeprom_process_recods(struct amdgpu_ras_eeprom_control *control, · 319 unmodified lines | ||
| 475 | 479 | int i, ret = 0; |
| 476 | 480 | struct i2c_msg *msgs, *msg; |
| 477 | 481 | unsigned char *buffs, *buff; |
| 478 | − bool sched_ras_recovery = false; | |
| 479 | 482 | struct eeprom_table_record *record; |
| 480 | 483 | struct amdgpu_device *adev = to_amdgpu_device(control); |
| 481 | 484 | struct amdgpu_ras *ras = amdgpu_ras_get_context(adev); |
| @@ -513,7 +516,6 @@ int amdgpu_ras_eeprom_process_recods(struct amdgpu_ras_eeprom_control *control, · 31 unmodified lines | ||
| 513 | 516 | "Saved bad pages(%d) reaches threshold value(%d).\n", |
| 514 | 517 | control->num_recs + num, ras->bad_page_cnt_threshold); |
| 515 | 518 | control->tbl_hdr.header = EEPROM_TABLE_HDR_BAD; |
| 516 | − sched_ras_recovery = true; | |
| 517 | 519 | } |
| 518 | 520 | |
| 519 | 521 | /* In case of overflow just start from beginning to not lose newest records */ |
| @@ -557,7 +559,11 @@ int amdgpu_ras_eeprom_process_recods(struct amdgpu_ras_eeprom_control *control, · 37 unmodified lines | ||
| 557 | 559 | control->next_addr += EEPROM_TABLE_RECORD_SIZE; |
| 558 | 560 | } |
| 559 | 561 | |
| 562 | + /* i2c may be unstable in gpu reset */ | |
| 563 | + down_read(&adev->reset_sem); | |
| 560 | 564 | ret = i2c_transfer(&adev->pm.smu_i2c, msgs, num); |
| 565 | + up_read(&adev->reset_sem); | |
| 566 | + | |
| 561 | 567 | if (ret < 1) { |
| 562 | 568 | DRM_ERROR("Failed to process EEPROM table records, ret:%d", ret); |
| 563 | 569 | |
| @@ -595,20 +601,6 @@ int amdgpu_ras_eeprom_process_recods(struct amdgpu_ras_eeprom_control *control, · 31 unmodified lines | ||
| 595 | 601 | __update_tbl_checksum(control, records, num, old_hdr_byte_sum); |
| 596 | 602 | |
| 597 | 603 | __update_table_header(control, buffs); |
| 598 | − | |
| 599 | − if (sched_ras_recovery) { | |
| 600 | − /* | |
| 601 | − * Before scheduling ras recovery, assert the related | |
| 602 | − * flag first, which shall bypass common bad page | |
| 603 | − * reservation execution in amdgpu_ras_reset_gpu. | |
| 604 | − */ | |
| 605 | − amdgpu_ras_get_context(adev)->flags |= | |
| 606 | − AMDGPU_RAS_FLAG_SKIP_BAD_PAGE_RESV; | |
| 607 | − | |
| 608 | − dev_warn(adev->dev, "Conduct ras recovery due to bad " | |
| 609 | − "page threshold reached.\n"); | |
| 610 | − amdgpu_ras_reset_gpu(adev); | |
| 611 | − } | |
| 612 | 604 | } else if (!__validate_tbl_checksum(control, records, num)) { |
| 613 | 605 | DRM_WARN("EEPROM Table checksum mismatch!"); |
| 614 | 606 | /* TODO Uncomment when EEPROM read/write is relliable */ |
| @@ -396,7 +396,7 @@ static ssize_t amdgpu_debugfs_ring_read(struct file *f, char __user *buf, · 395 unmodified lines | ||
| 396 | 396 | return result; |
| 397 | 397 | |
| 398 | 398 | value = ring->ring[(*pos - 12)/4]; |
| 399 | − r = put_user(value, (uint32_t*)buf); | |
| 399 | + r = put_user(value, (uint32_t *)buf); | |
| 400 | 400 | if (r) |
| 401 | 401 | return r; |
| 402 | 402 | buf += 4; |
| @@ -75,7 +75,7 @@ int amdgpu_sa_bo_manager_init(struct amdgpu_device *adev, · 74 unmodified lines | ||
| 75 | 75 | } |
| 76 | 76 | |
| 77 | 77 | void amdgpu_sa_bo_manager_fini(struct amdgpu_device *adev, |
| 78 | − struct amdgpu_sa_manager *sa_manager) | |
| 78 | + struct amdgpu_sa_manager *sa_manager) | |
| 79 | 79 | { |
| 80 | 80 | struct amdgpu_sa_bo *sa_bo, *tmp; |
| 81 | 81 | |
| @@ -126,7 +126,7 @@ int amdgpu_sdma_ras_late_init(struct amdgpu_device *adev, · 125 unmodified lines | ||
| 126 | 126 | goto free; |
| 127 | 127 | } |
| 128 | 128 | |
| 129 | − return 0; | |
| 129 | + return 0; | |
| 130 | 130 | |
| 131 | 131 | late_fini: |
| 132 | 132 | amdgpu_ras_late_fini(adev, adev->sdma.ras_if, ih_info); |
| @@ -157,10 +157,10 @@ static void amdgpu_do_test_moves(struct amdgpu_device *adev) · 156 unmodified lines | ||
| 157 | 157 | i, *vram_start, gart_start, |
| 158 | 158 | (unsigned long long) |
| 159 | 159 | (gart_addr - adev->gmc.gart_start + |
| 160 | − (void*)gart_start - gtt_map), | |
| 160 | + (void *)gart_start - gtt_map), | |
| 161 | 161 | (unsigned long long) |
| 162 | 162 | (vram_addr - adev->gmc.vram_start + |
| 163 | − (void*)gart_start - gtt_map)); | |
| 163 | + (void *)gart_start - gtt_map)); | |
| 164 | 164 | amdgpu_bo_kunmap(vram_obj); |
| 165 | 165 | goto out_lclean_unpin; |
| 166 | 166 | } |
| @@ -203,10 +203,10 @@ static void amdgpu_do_test_moves(struct amdgpu_device *adev) · 36 unmodified lines | ||
| 203 | 203 | i, *gart_start, vram_start, |
| 204 | 204 | (unsigned long long) |
| 205 | 205 | (vram_addr - adev->gmc.vram_start + |
| 206 | − (void*)vram_start - vram_map), | |
| 206 | + (void *)vram_start - vram_map), | |
| 207 | 207 | (unsigned long long) |
| 208 | 208 | (gart_addr - adev->gmc.gart_start + |
| 209 | − (void*)vram_start - vram_map)); | |
| 209 | + (void *)vram_start - vram_map)); | |
| 210 | 210 | amdgpu_bo_kunmap(gtt_obj[i]); |
| 211 | 211 | goto out_lclean_unpin; |
| 212 | 212 | } |
| @@ -70,10 +70,10 @@ static void amdgpu_ttm_backend_unbind(struct ttm_bo_device *bdev, · 69 unmodified lines | ||
| 70 | 70 | |
| 71 | 71 | static int amdgpu_ttm_init_on_chip(struct amdgpu_device *adev, |
| 72 | 72 | unsigned int type, |
| 73 | − uint64_t size) | |
| 73 | + uint64_t size_in_page) | |
| 74 | 74 | { |
| 75 | 75 | return ttm_range_man_init(&adev->mman.bdev, type, |
| 76 | − false, size >> PAGE_SHIFT); | |
| 76 | + false, size_in_page); | |
| 77 | 77 | } |
| 78 | 78 | |
| 79 | 79 | /** |
| @@ -1008,7 +1008,7 @@ void amdgpu_ttm_tt_set_user_pages(struct ttm_tt *ttm, struct page **pages) · 928 unmodified lines | ||
| 1008 | 1008 | } |
| 1009 | 1009 | |
| 1010 | 1010 | /** |
| 1011 | − * amdgpu_ttm_tt_pin_userptr - prepare the sg table with the user pages | |
| 1011 | + * amdgpu_ttm_tt_pin_userptr - prepare the sg table with the user pages | |
| 1012 | 1012 | * |
| 1013 | 1013 | * Called by amdgpu_ttm_backend_bind() |
| 1014 | 1014 | **/ |
| @@ -1198,7 +1198,7 @@ int amdgpu_ttm_alloc_gart(struct ttm_buffer_object *bo) · 183 unmodified lines | ||
| 1198 | 1198 | { |
| 1199 | 1199 | struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev); |
| 1200 | 1200 | struct ttm_operation_ctx ctx = { false, false }; |
| 1201 | − struct amdgpu_ttm_tt *gtt = (void*)bo->ttm; | |
| 1201 | + struct amdgpu_ttm_tt *gtt = (void *)bo->ttm; | |
| 1202 | 1202 | struct ttm_resource tmp; |
| 1203 | 1203 | struct ttm_placement placement; |
| 1204 | 1204 | struct ttm_place placements; |
| @@ -1449,7 +1449,7 @@ int amdgpu_ttm_tt_set_userptr(struct ttm_buffer_object *bo, · 244 unmodified lines | ||
| 1449 | 1449 | return -ENOMEM; |
| 1450 | 1450 | } |
| 1451 | 1451 | |
| 1452 | − gtt = (void*)bo->ttm; | |
| 1452 | + gtt = (void *)bo->ttm; | |
| 1453 | 1453 | gtt->userptr = addr; |
| 1454 | 1454 | gtt->userflags = flags; |
| 1455 | 1455 | |
| @@ -37,10 +37,17 @@ · 36 unmodified lines | ||
| 37 | 37 | |
| 38 | 38 | #define AMDGPU_POISON 0xd0bed0be |
| 39 | 39 | |
| 40 | +struct amdgpu_vram_reservation { | |
| 41 | + struct list_head node; | |
| 42 | + struct drm_mm_node mm_node; | |
| 43 | +}; | |
| 44 | + | |
| 40 | 45 | struct amdgpu_vram_mgr { |
| 41 | 46 | struct ttm_resource_manager manager; |
| 42 | 47 | struct drm_mm mm; |
| 43 | 48 | spinlock_t lock; |
| 49 | + struct list_head reservations_pending; | |
| 50 | + struct list_head reserved_pages; | |
| 44 | 51 | atomic64_t usage; |
| 45 | 52 | atomic64_t vis_usage; |
| 46 | 53 | }; |
| @@ -54,7 +61,6 @@ struct amdgpu_gtt_mgr { · 7 unmodified lines | ||
| 54 | 61 | |
| 55 | 62 | struct amdgpu_mman { |
| 56 | 63 | struct ttm_bo_device bdev; |
| 57 | − bool mem_global_referenced; | |
| 58 | 64 | bool initialized; |
| 59 | 65 | void __iomem *aper_base_kaddr; |
| 60 | 66 | |
| @@ -119,6 +125,10 @@ void amdgpu_vram_mgr_free_sgt(struct amdgpu_device *adev, · 58 unmodified lines | ||
| 119 | 125 | struct sg_table *sgt); |
| 120 | 126 | uint64_t amdgpu_vram_mgr_usage(struct ttm_resource_manager *man); |
| 121 | 127 | uint64_t amdgpu_vram_mgr_vis_usage(struct ttm_resource_manager *man); |
| 128 | +int amdgpu_vram_mgr_reserve_range(struct ttm_resource_manager *man, | |
| 129 | + uint64_t start, uint64_t size); | |
| 130 | +int amdgpu_vram_mgr_query_page_status(struct ttm_resource_manager *man, | |
| 131 | + uint64_t start); | |
| 122 | 132 | |
| 123 | 133 | int amdgpu_ttm_init(struct amdgpu_device *adev); |
| 124 | 134 | void amdgpu_ttm_late_init(struct amdgpu_device *adev); |
| @@ -391,6 +391,8 @@ amdgpu_ucode_get_load_type(struct amdgpu_device *adev, int load_type) · 390 unmodified lines | ||
| 391 | 391 | case CHIP_NAVI12: |
| 392 | 392 | case CHIP_SIENNA_CICHLID: |
| 393 | 393 | case CHIP_NAVY_FLOUNDER: |
| 394 | + case CHIP_VANGOGH: | |
| 395 | + case CHIP_DIMGREY_CAVEFISH: | |
| 394 | 396 | if (!load_type) |
| 395 | 397 | return AMDGPU_FW_LOAD_DIRECT; |
| 396 | 398 | else |
| @@ -586,8 +588,8 @@ static int amdgpu_ucode_patch_jt(struct amdgpu_firmware_info *ucode, · 189 unmodified lines | ||
| 586 | 588 | { |
| 587 | 589 | const struct gfx_firmware_header_v1_0 *header = NULL; |
| 588 | 590 | const struct common_firmware_header *comm_hdr = NULL; |
| 589 | − uint8_t* src_addr = NULL; | |
| 590 | − uint8_t* dst_addr = NULL; | |
| 591 | + uint8_t *src_addr = NULL; | |
| 592 | + uint8_t *dst_addr = NULL; | |
| 591 | 593 | |
| 592 | 594 | if (NULL == ucode->fw) |
| 593 | 595 | return 0; |
| @@ -126,10 +126,11 @@ int amdgpu_umc_process_ras_data_cb(struct amdgpu_device *adev, · 125 unmodified lines | ||
| 126 | 126 | err_data->ue_count); |
| 127 | 127 | |
| 128 | 128 | if ((amdgpu_bad_page_threshold != 0) && |
| 129 | − err_data->err_addr_cnt && | |
| 129 | + err_data->err_addr_cnt) { | |
| 130 | 130 | amdgpu_ras_add_bad_pages(adev, err_data->err_addr, |
| 131 | − err_data->err_addr_cnt)) | |
| 132 | − dev_warn(adev->dev, "Failed to add ras bad page!\n"); | |
| 131 | + err_data->err_addr_cnt); | |
| 132 | + amdgpu_ras_save_bad_pages(adev); | |
| 133 | + } | |
| 133 | 134 | |
| 134 | 135 | amdgpu_ras_reset_gpu(adev); |
| 135 | 136 | } |
| @@ -37,24 +37,30 @@ · 36 unmodified lines | ||
| 37 | 37 | #define FIRMWARE_RAVEN "amdgpu/raven_vcn.bin" |
| 38 | 38 | #define FIRMWARE_PICASSO "amdgpu/picasso_vcn.bin" |
| 39 | 39 | #define FIRMWARE_RAVEN2 "amdgpu/raven2_vcn.bin" |
| 40 | −#define FIRMWARE_ARCTURUS "amdgpu/arcturus_vcn.bin" | |
| 41 | −#define FIRMWARE_RENOIR "amdgpu/renoir_vcn.bin" | |
| 42 | −#define FIRMWARE_NAVI10 "amdgpu/navi10_vcn.bin" | |
| 43 | −#define FIRMWARE_NAVI14 "amdgpu/navi14_vcn.bin" | |
| 44 | −#define FIRMWARE_NAVI12 "amdgpu/navi12_vcn.bin" | |
| 45 | −#define FIRMWARE_SIENNA_CICHLID "amdgpu/sienna_cichlid_vcn.bin" | |
| 46 | −#define FIRMWARE_NAVY_FLOUNDER "amdgpu/navy_flounder_vcn.bin" | |
| 40 | +#define FIRMWARE_ARCTURUS "amdgpu/arcturus_vcn.bin" | |
| 41 | +#define FIRMWARE_RENOIR "amdgpu/renoir_vcn.bin" | |
| 42 | +#define FIRMWARE_GREEN_SARDINE "amdgpu/green_sardine_vcn.bin" | |
| 43 | +#define FIRMWARE_NAVI10 "amdgpu/navi10_vcn.bin" | |
| 44 | +#define FIRMWARE_NAVI14 "amdgpu/navi14_vcn.bin" | |
| 45 | +#define FIRMWARE_NAVI12 "amdgpu/navi12_vcn.bin" | |
| 46 | +#define FIRMWARE_SIENNA_CICHLID "amdgpu/sienna_cichlid_vcn.bin" | |
| 47 | +#define FIRMWARE_NAVY_FLOUNDER "amdgpu/navy_flounder_vcn.bin" | |
| 48 | +#define FIRMWARE_VANGOGH "amdgpu/vangogh_vcn.bin" | |
| 49 | +#define FIRMWARE_DIMGREY_CAVEFISH "amdgpu/dimgrey_cavefish_vcn.bin" | |
| 47 | 50 | |
| 48 | 51 | MODULE_FIRMWARE(FIRMWARE_RAVEN); |
| 49 | 52 | MODULE_FIRMWARE(FIRMWARE_PICASSO); |
| 50 | 53 | MODULE_FIRMWARE(FIRMWARE_RAVEN2); |
| 51 | 54 | MODULE_FIRMWARE(FIRMWARE_ARCTURUS); |
| 52 | 55 | MODULE_FIRMWARE(FIRMWARE_RENOIR); |
| 56 | +MODULE_FIRMWARE(FIRMWARE_GREEN_SARDINE); | |
| 53 | 57 | MODULE_FIRMWARE(FIRMWARE_NAVI10); |
| 54 | 58 | MODULE_FIRMWARE(FIRMWARE_NAVI14); |
| 55 | 59 | MODULE_FIRMWARE(FIRMWARE_NAVI12); |
| 56 | 60 | MODULE_FIRMWARE(FIRMWARE_SIENNA_CICHLID); |
| 57 | 61 | MODULE_FIRMWARE(FIRMWARE_NAVY_FLOUNDER); |
| 62 | +MODULE_FIRMWARE(FIRMWARE_VANGOGH); | |
| 63 | +MODULE_FIRMWARE(FIRMWARE_DIMGREY_CAVEFISH); | |
| 58 | 64 | |
| 59 | 65 | static void amdgpu_vcn_idle_work_handler(struct work_struct *work); |
| 60 | 66 | |
| @@ -89,7 +95,11 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev) · 28 unmodified lines | ||
| 89 | 95 | adev->vcn.indirect_sram = true; |
| 90 | 96 | break; |
| 91 | 97 | case CHIP_RENOIR: |
| 92 | − fw_name = FIRMWARE_RENOIR; | |
| 98 | + if (adev->apu_flags & AMD_APU_IS_RENOIR) | |
| 99 | + fw_name = FIRMWARE_RENOIR; | |
| 100 | + else | |
| 101 | + fw_name = FIRMWARE_GREEN_SARDINE; | |
| 102 | + | |
| 93 | 103 | if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) && |
| 94 | 104 | (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)) |
| 95 | 105 | adev->vcn.indirect_sram = true; |
| @@ -124,6 +134,15 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev) · 28 unmodified lines | ||
| 124 | 134 | (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)) |
| 125 | 135 | adev->vcn.indirect_sram = true; |
| 126 | 136 | break; |
| 137 | + case CHIP_VANGOGH: | |
| 138 | + fw_name = FIRMWARE_VANGOGH; | |
| 139 | + break; | |
| 140 | + case CHIP_DIMGREY_CAVEFISH: | |
| 141 | + fw_name = FIRMWARE_DIMGREY_CAVEFISH; | |
| 142 | + if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) && | |
| 143 | + (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)) | |
| 144 | + adev->vcn.indirect_sram = true; | |
| 145 | + break; | |
| 127 | 146 | default: |
| 128 | 147 | return -EINVAL; |
| 129 | 148 | } |
| @@ -313,6 +332,7 @@ static void amdgpu_vcn_idle_work_handler(struct work_struct *work) · 183 unmodified lines | ||
| 313 | 332 | container_of(work, struct amdgpu_device, vcn.idle_work.work); |
| 314 | 333 | unsigned int fences = 0, fence[AMDGPU_MAX_VCN_INSTANCES] = {0}; |
| 315 | 334 | unsigned int i, j; |
| 335 | + int r = 0; | |
| 316 | 336 | |
| 317 | 337 | for (j = 0; j < adev->vcn.num_vcn_inst; ++j) { |
| 318 | 338 | if (adev->vcn.harvest_config & (1 << j)) |
| @@ -339,8 +359,13 @@ static void amdgpu_vcn_idle_work_handler(struct work_struct *work) · 20 unmodified lines | ||
| 339 | 359 | } |
| 340 | 360 | |
| 341 | 361 | if (!fences && !atomic_read(&adev->vcn.total_submission_cnt)) { |
| 362 | + amdgpu_gfx_off_ctrl(adev, true); | |
| 342 | 363 | amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN, |
| 343 | 364 | AMD_PG_STATE_GATE); |
| 365 | + r = amdgpu_dpm_switch_power_profile(adev, PP_SMC_POWER_PROFILE_VIDEO, | |
| 366 | + false); | |
| 367 | + if (r) | |
| 368 | + dev_warn(adev->dev, "(%d) failed to disable video power profile mode\n", r); | |
| 344 | 369 | } else { |
| 345 | 370 | schedule_delayed_work(&adev->vcn.idle_work, VCN_IDLE_TIMEOUT); |
| 346 | 371 | } |
| @@ -349,9 +374,17 @@ static void amdgpu_vcn_idle_work_handler(struct work_struct *work) · 2 unmodified lines | ||
| 349 | 374 | void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring) |
| 350 | 375 | { |
| 351 | 376 | struct amdgpu_device *adev = ring->adev; |
| 377 | + int r = 0; | |
| 352 | 378 | |
| 353 | 379 | atomic_inc(&adev->vcn.total_submission_cnt); |
| 354 | − cancel_delayed_work_sync(&adev->vcn.idle_work); | |
| 380 | + | |
| 381 | + if (!cancel_delayed_work_sync(&adev->vcn.idle_work)) { | |
| 382 | + amdgpu_gfx_off_ctrl(adev, false); | |
| 383 | + r = amdgpu_dpm_switch_power_profile(adev, PP_SMC_POWER_PROFILE_VIDEO, | |
| 384 | + true); | |
| 385 | + if (r) | |
| 386 | + dev_warn(adev->dev, "(%d) failed to switch to video power profile mode\n", r); | |
| 387 | + } | |
| 355 | 388 | |
| 356 | 389 | mutex_lock(&adev->vcn.vcn_pg_lock); |
| 357 | 390 | amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN, |
| @@ -59,7 +59,7 @@ void amdgpu_vf_error_trans_all(struct amdgpu_device *adev) · 58 unmodified lines | ||
| 59 | 59 | return; |
| 60 | 60 | } |
| 61 | 61 | /* |
| 62 | − TODO: Enable these code when pv2vf_info is merged | |
| 62 | + TODO: Enable these code when pv2vf_info is merged | |
| 63 | 63 | AMDGPU_FW_VRAM_PF2VF_READ (adev, feature_flags, &pf2vf_flags); |
| 64 | 64 | if (!(pf2vf_flags & AMDGIM_FEATURE_ERROR_LOG_COLLECT)) { |
| 65 | 65 | return; |
| @@ -300,7 +300,7 @@ static void amdgpu_vm_bo_relocated(struct amdgpu_vm_bo_base *vm_bo) · 299 unmodified lines | ||
| 300 | 300 | static void amdgpu_vm_bo_done(struct amdgpu_vm_bo_base *vm_bo) |
| 301 | 301 | { |
| 302 | 302 | spin_lock(&vm_bo->vm->invalidated_lock); |
| 303 | − list_del_init(&vm_bo->vm_status); | |
| 303 | + list_move(&vm_bo->vm_status, &vm_bo->vm->done); | |
| 304 | 304 | spin_unlock(&vm_bo->vm->invalidated_lock); |
| 305 | 305 | } |
| 306 | 306 | |
| @@ -1570,7 +1570,8 @@ static int amdgpu_vm_update_ptes(struct amdgpu_vm_update_params *params, · 1263 unmodified lines | ||
| 1570 | 1570 | /** |
| 1571 | 1571 | * amdgpu_vm_bo_update_mapping - update a mapping in the vm page table |
| 1572 | 1572 | * |
| 1573 | − * @adev: amdgpu_device pointer | |
| 1573 | + * @adev: amdgpu_device pointer of the VM | |
| 1574 | + * @bo_adev: amdgpu_device pointer of the mapped BO | |
| 1574 | 1575 | * @vm: requested vm |
| 1575 | 1576 | * @immediate: immediate submission in a page fault |
| 1576 | 1577 | * @unlocked: unlocked invalidation during MM callback |
| @@ -1578,7 +1579,8 @@ static int amdgpu_vm_update_ptes(struct amdgpu_vm_update_params *params, · 1 unmodified line | ||
| 1578 | 1579 | * @start: start of mapped range |
| 1579 | 1580 | * @last: last mapped entry |
| 1580 | 1581 | * @flags: flags for the entries |
| 1581 | − * @addr: addr to set the area to | |
| 1582 | + * @offset: offset into nodes and pages_addr | |
| 1583 | + * @nodes: array of drm_mm_nodes with the MC addresses | |
| 1582 | 1584 | * @pages_addr: DMA addresses to use for mapping |
| 1583 | 1585 | * @fence: optional resulting fence |
| 1584 | 1586 | * |
| @@ -1588,15 +1590,18 @@ static int amdgpu_vm_update_ptes(struct amdgpu_vm_update_params *params, · 3 unmodified lines | ||
| 1588 | 1590 | * 0 for success, -EINVAL for failure. |
| 1589 | 1591 | */ |
| 1590 | 1592 | static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, |
| 1593 | + struct amdgpu_device *bo_adev, | |
| 1591 | 1594 | struct amdgpu_vm *vm, bool immediate, |
| 1592 | 1595 | bool unlocked, struct dma_resv *resv, |
| 1593 | 1596 | uint64_t start, uint64_t last, |
| 1594 | − uint64_t flags, uint64_t addr, | |
| 1597 | + uint64_t flags, uint64_t offset, | |
| 1598 | + struct drm_mm_node *nodes, | |
| 1595 | 1599 | dma_addr_t *pages_addr, |
| 1596 | 1600 | struct dma_fence **fence) |
| 1597 | 1601 | { |
| 1598 | 1602 | struct amdgpu_vm_update_params params; |
| 1599 | 1603 | enum amdgpu_sync_mode sync_mode; |
| 1604 | + uint64_t pfn; | |
| 1600 | 1605 | int r; |
| 1601 | 1606 | |
| 1602 | 1607 | memset(¶ms, 0, sizeof(params)); |
| @@ -1614,6 +1619,14 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, · 11 unmodified lines | ||
| 1614 | 1619 | else |
| 1615 | 1620 | sync_mode = AMDGPU_SYNC_EXPLICIT; |
| 1616 | 1621 | |
| 1622 | + pfn = offset >> PAGE_SHIFT; | |
| 1623 | + if (nodes) { | |
| 1624 | + while (pfn >= nodes->size) { | |
| 1625 | + pfn -= nodes->size; | |
| 1626 | + ++nodes; | |
| 1627 | + } | |
| 1628 | + } | |
| 1629 | + | |
| 1617 | 1630 | amdgpu_vm_eviction_lock(vm); |
| 1618 | 1631 | if (vm->evicting) { |
| 1619 | 1632 | r = -EBUSY; |
| @@ -1632,105 +1645,47 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, · 12 unmodified lines | ||
| 1632 | 1645 | if (r) |
| 1633 | 1646 | goto error_unlock; |
| 1634 | 1647 | |
| 1635 | − r = amdgpu_vm_update_ptes(¶ms, start, last + 1, addr, flags); | |
| 1636 | − if (r) | |
| 1637 | − goto error_unlock; | |
| 1638 | − | |
| 1639 | − r = vm->update_funcs->commit(¶ms, fence); | |
| 1640 | − | |
| 1641 | −error_unlock: | |
| 1642 | − amdgpu_vm_eviction_unlock(vm); | |
| 1643 | − return r; | |
| 1644 | −} | |
| 1645 | − | |
| 1646 | −/** | |
| 1647 | − * amdgpu_vm_bo_split_mapping - split a mapping into smaller chunks | |
| 1648 | − * | |
| 1649 | − * @adev: amdgpu_device pointer | |
| 1650 | − * @resv: fences we need to sync to | |
| 1651 | − * @pages_addr: DMA addresses to use for mapping | |
| 1652 | − * @vm: requested vm | |
| 1653 | − * @mapping: mapped range and flags to use for the update | |
| 1654 | − * @flags: HW flags for the mapping | |
| 1655 | − * @bo_adev: amdgpu_device pointer that bo actually been allocated | |
| 1656 | − * @nodes: array of drm_mm_nodes with the MC addresses | |
| 1657 | − * @fence: optional resulting fence | |
| 1658 | − * | |
| 1659 | − * Split the mapping into smaller chunks so that each update fits | |
| 1660 | − * into a SDMA IB. | |
| 1661 | − * | |
| 1662 | − * Returns: | |
| 1663 | − * 0 for success, -EINVAL for failure. | |
| 1664 | − */ | |
| 1665 | −static int amdgpu_vm_bo_split_mapping(struct amdgpu_device *adev, | |
| 1666 | − struct dma_resv *resv, | |
| 1667 | − dma_addr_t *pages_addr, | |
| 1668 | − struct amdgpu_vm *vm, | |
| 1669 | − struct amdgpu_bo_va_mapping *mapping, | |
| 1670 | − uint64_t flags, | |
| 1671 | − struct amdgpu_device *bo_adev, | |
| 1672 | − struct drm_mm_node *nodes, | |
| 1673 | − struct dma_fence **fence) | |
| 1674 | −{ | |
| 1675 | − unsigned min_linear_pages = 1 << adev->vm_manager.fragment_size; | |
| 1676 | − uint64_t pfn, start = mapping->start; | |
| 1677 | − int r; | |
| 1678 | − | |
| 1679 | − /* normally,bo_va->flags only contians READABLE and WIRTEABLE bit go here | |
| 1680 | − * but in case of something, we filter the flags in first place | |
| 1681 | − */ | |
| 1682 | − if (!(mapping->flags & AMDGPU_PTE_READABLE)) | |
| 1683 | − flags &= ~AMDGPU_PTE_READABLE; | |
| 1684 | − if (!(mapping->flags & AMDGPU_PTE_WRITEABLE)) | |
| 1685 | − flags &= ~AMDGPU_PTE_WRITEABLE; | |
| 1686 | − | |
| 1687 | − /* Apply ASIC specific mapping flags */ | |
| 1688 | − amdgpu_gmc_get_vm_pte(adev, mapping, &flags); | |
| 1689 | − | |
| 1690 | − trace_amdgpu_vm_bo_update(mapping); | |
| 1691 | − | |
| 1692 | − pfn = mapping->offset >> PAGE_SHIFT; | |
| 1693 | − if (nodes) { | |
| 1694 | − while (pfn >= nodes->size) { | |
| 1695 | − pfn -= nodes->size; | |
| 1696 | − ++nodes; | |
| 1697 | − } | |
| 1698 | − } | |
| 1699 | − | |
| 1700 | 1648 | do { |
| 1701 | − dma_addr_t *dma_addr = NULL; | |
| 1702 | − uint64_t max_entries; | |
| 1703 | − uint64_t addr, last; | |
| 1649 | + uint64_t tmp, num_entries, addr; | |
| 1650 | + | |
| 1704 | 1651 | |
| 1705 | − max_entries = mapping->last - start + 1; | |
| 1652 | + num_entries = last - start + 1; | |
| 1706 | 1653 | if (nodes) { |
| 1707 | 1654 | addr = nodes->start << PAGE_SHIFT; |
| 1708 | − max_entries = min((nodes->size - pfn) * | |
| 1709 | − AMDGPU_GPU_PAGES_IN_CPU_PAGE, max_entries); | |
| 1655 | + num_entries = min((nodes->size - pfn) * | |
| 1656 | + AMDGPU_GPU_PAGES_IN_CPU_PAGE, num_entries); | |
| 1710 | 1657 | } else { |
| 1711 | 1658 | addr = 0; |
| 1712 | 1659 | } |
| 1713 | 1660 | |
| 1714 | 1661 | if (pages_addr) { |
| 1715 | − uint64_t count; | |
| 1662 | + bool contiguous = true; | |
| 1716 | 1663 | |
| 1717 | − for (count = 1; | |
| 1718 | − count < max_entries / AMDGPU_GPU_PAGES_IN_CPU_PAGE; | |
| 1719 | − ++count) { | |
| 1720 | − uint64_t idx = pfn + count; | |
| 1664 | + if (num_entries > AMDGPU_GPU_PAGES_IN_CPU_PAGE) { | |
| 1665 | + uint64_t count; | |
| 1721 | 1666 | |
| 1722 | − if (pages_addr[idx] != | |
| 1723 | − (pages_addr[idx - 1] + PAGE_SIZE)) | |
| 1724 | − break; | |
| 1667 | + contiguous = pages_addr[pfn + 1] == | |
| 1668 | + pages_addr[pfn] + PAGE_SIZE; | |
| 1669 | + | |
| 1670 | + tmp = num_entries / | |
| 1671 | + AMDGPU_GPU_PAGES_IN_CPU_PAGE; | |
| 1672 | + for (count = 2; count < tmp; ++count) { | |
| 1673 | + uint64_t idx = pfn + count; | |
| 1674 | + | |
| 1675 | + if (contiguous != (pages_addr[idx] == | |
| 1676 | + pages_addr[idx - 1] + PAGE_SIZE)) | |
| 1677 | + break; | |
| 1678 | + } | |
| 1679 | + num_entries = count * | |
| 1680 | + AMDGPU_GPU_PAGES_IN_CPU_PAGE; | |
| 1725 | 1681 | } |
| 1726 | 1682 | |
| 1727 | − if (count < min_linear_pages) { | |
| 1683 | + if (!contiguous) { | |
| 1728 | 1684 | addr = pfn << PAGE_SHIFT; |
| 1729 | − dma_addr = pages_addr; | |
| 1685 | + params.pages_addr = pages_addr; | |
| 1730 | 1686 | } else { |
| 1731 | 1687 | addr = pages_addr[pfn]; |
| 1732 | − max_entries = count * | |
| 1733 | − AMDGPU_GPU_PAGES_IN_CPU_PAGE; | |
| 1688 | + params.pages_addr = NULL; | |
| 1734 | 1689 | } |
| 1735 | 1690 | |
| 1736 | 1691 | } else if (flags & (AMDGPU_PTE_VALID | AMDGPU_PTE_PRT)) { |
| @@ -1738,23 +1693,25 @@ static int amdgpu_vm_bo_split_mapping(struct amdgpu_device *adev, · 1 unmodified line | ||
| 1738 | 1693 | addr += pfn << PAGE_SHIFT; |
| 1739 | 1694 | } |
| 1740 | 1695 | |
| 1741 | − last = start + max_entries - 1; | |
| 1742 | − r = amdgpu_vm_bo_update_mapping(adev, vm, false, false, resv, | |
| 1743 | − start, last, flags, addr, | |
| 1744 | − dma_addr, fence); | |
| 1696 | + tmp = start + num_entries; | |
| 1697 | + r = amdgpu_vm_update_ptes(¶ms, start, tmp, addr, flags); | |
| 1745 | 1698 | if (r) |
| 1746 | − return r; | |
| 1699 | + goto error_unlock; | |
| 1747 | 1700 | |
| 1748 | − pfn += (last - start + 1) / AMDGPU_GPU_PAGES_IN_CPU_PAGE; | |
| 1701 | + pfn += num_entries / AMDGPU_GPU_PAGES_IN_CPU_PAGE; | |
| 1749 | 1702 | if (nodes && nodes->size == pfn) { |
| 1750 | 1703 | pfn = 0; |
| 1751 | 1704 | ++nodes; |
| 1752 | 1705 | } |
| 1753 | − start = last + 1; | |
| 1706 | + start = tmp; | |
| 1754 | 1707 | |
| 1755 | − } while (unlikely(start != mapping->last + 1)); | |
| 1708 | + } while (unlikely(start != last + 1)); | |
| 1756 | 1709 | |
| 1757 | − return 0; | |
| 1710 | + r = vm->update_funcs->commit(¶ms, fence); | |
| 1711 | + | |
| 1712 | +error_unlock: | |
| 1713 | + amdgpu_vm_eviction_unlock(vm); | |
| 1714 | + return r; | |
| 1758 | 1715 | } |
| 1759 | 1716 | |
| 1760 | 1717 | /** |
| @@ -1832,9 +1789,26 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va, · 71 unmodified lines | ||
| 1832 | 1789 | } |
| 1833 | 1790 | |
| 1834 | 1791 | list_for_each_entry(mapping, &bo_va->invalids, list) { |
| 1835 | − r = amdgpu_vm_bo_split_mapping(adev, resv, pages_addr, vm, | |
| 1836 | − mapping, flags, bo_adev, nodes, | |
| 1837 | − last_update); | |
| 1792 | + uint64_t update_flags = flags; | |
| 1793 | + | |
| 1794 | + /* normally,bo_va->flags only contians READABLE and WIRTEABLE bit go here | |
| 1795 | + * but in case of something, we filter the flags in first place | |
| 1796 | + */ | |
| 1797 | + if (!(mapping->flags & AMDGPU_PTE_READABLE)) | |
| 1798 | + update_flags &= ~AMDGPU_PTE_READABLE; | |
| 1799 | + if (!(mapping->flags & AMDGPU_PTE_WRITEABLE)) | |
| 1800 | + update_flags &= ~AMDGPU_PTE_WRITEABLE; | |
| 1801 | + | |
| 1802 | + /* Apply ASIC specific mapping flags */ | |
| 1803 | + amdgpu_gmc_get_vm_pte(adev, mapping, &update_flags); | |
| 1804 | + | |
| 1805 | + trace_amdgpu_vm_bo_update(mapping); | |
| 1806 | + | |
| 1807 | + r = amdgpu_vm_bo_update_mapping(adev, bo_adev, vm, false, false, | |
| 1808 | + resv, mapping->start, | |
| 1809 | + mapping->last, update_flags, | |
| 1810 | + mapping->offset, nodes, | |
| 1811 | + pages_addr, last_update); | |
| 1838 | 1812 | if (r) |
| 1839 | 1813 | return r; |
| 1840 | 1814 | } |
| @@ -2042,9 +2016,10 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev, · 201 unmodified lines | ||
| 2042 | 2016 | mapping->start < AMDGPU_GMC_HOLE_START) |
| 2043 | 2017 | init_pte_value = AMDGPU_PTE_DEFAULT_ATC; |
| 2044 | 2018 | |
| 2045 | − r = amdgpu_vm_bo_update_mapping(adev, vm, false, false, resv, | |
| 2046 | − mapping->start, mapping->last, | |
| 2047 | − init_pte_value, 0, NULL, &f); | |
| 2019 | + r = amdgpu_vm_bo_update_mapping(adev, adev, vm, false, false, | |
| 2020 | + resv, mapping->start, | |
| 2021 | + mapping->last, init_pte_value, | |
| 2022 | + 0, NULL, NULL, &f); | |
| 2048 | 2023 | amdgpu_vm_free_mapping(adev, vm, mapping, f); |
| 2049 | 2024 | if (r) { |
| 2050 | 2025 | dma_fence_put(f); |
| @@ -2163,7 +2138,7 @@ struct amdgpu_bo_va *amdgpu_vm_bo_add(struct amdgpu_device *adev, · 112 unmodified lines | ||
| 2163 | 2138 | |
| 2164 | 2139 | |
| 2165 | 2140 | /** |
| 2166 | − * amdgpu_vm_bo_insert_mapping - insert a new mapping | |
| 2141 | + * amdgpu_vm_bo_insert_map - insert a new mapping | |
| 2167 | 2142 | * |
| 2168 | 2143 | * @adev: amdgpu_device pointer |
| 2169 | 2144 | * @bo_va: bo_va to store the address |
| @@ -2820,7 +2795,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, · 650 unmodified lines | ||
| 2820 | 2795 | INIT_LIST_HEAD(&vm->invalidated); |
| 2821 | 2796 | spin_lock_init(&vm->invalidated_lock); |
| 2822 | 2797 | INIT_LIST_HEAD(&vm->freed); |
| 2823 | − | |
| 2798 | + INIT_LIST_HEAD(&vm->done); | |
| 2824 | 2799 | |
| 2825 | 2800 | /* create scheduler entities for page table updates */ |
| 2826 | 2801 | r = drm_sched_entity_init(&vm->immediate, DRM_SCHED_PRIORITY_NORMAL, |
| @@ -3372,8 +3347,9 @@ bool amdgpu_vm_handle_fault(struct amdgpu_device *adev, u32 pasid, · 545 unmodified lines | ||
| 3372 | 3347 | value = 0; |
| 3373 | 3348 | } |
| 3374 | 3349 | |
| 3375 | − r = amdgpu_vm_bo_update_mapping(adev, vm, true, false, NULL, addr, | |
| 3376 | − addr + 1, flags, value, NULL, NULL); | |
| 3350 | + r = amdgpu_vm_bo_update_mapping(adev, adev, vm, true, false, NULL, addr, | |
| 3351 | + addr, flags, value, NULL, NULL, | |
| 3352 | + NULL); | |
| 3377 | 3353 | if (r) |
| 3378 | 3354 | goto error_unlock; |
| 3379 | 3355 | |
| @@ -3389,3 +3365,99 @@ error_unref: · 9 unmodified lines | ||
| 3389 | 3365 | |
| 3390 | 3366 | return false; |
| 3391 | 3367 | } |
| 3368 | + | |
| 3369 | +#if defined(CONFIG_DEBUG_FS) | |
| 3370 | +/** | |
| 3371 | + * amdgpu_debugfs_vm_bo_info - print BO info for the VM | |
| 3372 | + * | |
| 3373 | + * @vm: Requested VM for printing BO info | |
| 3374 | + * @m: debugfs file | |
| 3375 | + * | |
| 3376 | + * Print BO information in debugfs file for the VM | |
| 3377 | + */ | |
| 3378 | +void amdgpu_debugfs_vm_bo_info(struct amdgpu_vm *vm, struct seq_file *m) | |
| 3379 | +{ | |
| 3380 | + struct amdgpu_bo_va *bo_va, *tmp; | |
| 3381 | + u64 total_idle = 0; | |
| 3382 | + u64 total_evicted = 0; | |
| 3383 | + u64 total_relocated = 0; | |
| 3384 | + u64 total_moved = 0; | |
| 3385 | + u64 total_invalidated = 0; | |
| 3386 | + u64 total_done = 0; | |
| 3387 | + unsigned int total_idle_objs = 0; | |
| 3388 | + unsigned int total_evicted_objs = 0; | |
| 3389 | + unsigned int total_relocated_objs = 0; | |
| 3390 | + unsigned int total_moved_objs = 0; | |
| 3391 | + unsigned int total_invalidated_objs = 0; | |
| 3392 | + unsigned int total_done_objs = 0; | |
| 3393 | + unsigned int id = 0; | |
| 3394 | + | |
| 3395 | + seq_puts(m, "\tIdle BOs:\n"); | |
| 3396 | + list_for_each_entry_safe(bo_va, tmp, &vm->idle, base.vm_status) { | |
| 3397 | + if (!bo_va->base.bo) | |
| 3398 | + continue; | |
| 3399 | + total_idle += amdgpu_bo_print_info(id++, bo_va->base.bo, m); | |
| 3400 | + } | |
| 3401 | + total_idle_objs = id; | |
| 3402 | + id = 0; | |
| 3403 | + | |
| 3404 | + seq_puts(m, "\tEvicted BOs:\n"); | |
| 3405 | + list_for_each_entry_safe(bo_va, tmp, &vm->evicted, base.vm_status) { | |
| 3406 | + if (!bo_va->base.bo) | |
| 3407 | + continue; | |
| 3408 | + total_evicted += amdgpu_bo_print_info(id++, bo_va->base.bo, m); | |
| 3409 | + } | |
| 3410 | + total_evicted_objs = id; | |
| 3411 | + id = 0; | |
| 3412 | + | |
| 3413 | + seq_puts(m, "\tRelocated BOs:\n"); | |
| 3414 | + list_for_each_entry_safe(bo_va, tmp, &vm->relocated, base.vm_status) { | |
| 3415 | + if (!bo_va->base.bo) | |
| 3416 | + continue; | |
| 3417 | + total_relocated += amdgpu_bo_print_info(id++, bo_va->base.bo, m); | |
| 3418 | + } | |
| 3419 | + total_relocated_objs = id; | |
| 3420 | + id = 0; | |
| 3421 | + | |
| 3422 | + seq_puts(m, "\tMoved BOs:\n"); | |
| 3423 | + list_for_each_entry_safe(bo_va, tmp, &vm->moved, base.vm_status) { | |
| 3424 | + if (!bo_va->base.bo) | |
| 3425 | + continue; | |
| 3426 | + total_moved += amdgpu_bo_print_info(id++, bo_va->base.bo, m); | |
| 3427 | + } | |
| 3428 | + total_moved_objs = id; | |
| 3429 | + id = 0; | |
| 3430 | + | |
| 3431 | + seq_puts(m, "\tInvalidated BOs:\n"); | |
| 3432 | + spin_lock(&vm->invalidated_lock); | |
| 3433 | + list_for_each_entry_safe(bo_va, tmp, &vm->invalidated, base.vm_status) { | |
| 3434 | + if (!bo_va->base.bo) | |
| 3435 | + continue; | |
| 3436 | + total_invalidated += amdgpu_bo_print_info(id++, bo_va->base.bo, m); | |
| 3437 | + } | |
| 3438 | + total_invalidated_objs = id; | |
| 3439 | + id = 0; | |
| 3440 | + | |
| 3441 | + seq_puts(m, "\tDone BOs:\n"); | |
| 3442 | + list_for_each_entry_safe(bo_va, tmp, &vm->done, base.vm_status) { | |
| 3443 | + if (!bo_va->base.bo) | |
| 3444 | + continue; | |
| 3445 | + total_done += amdgpu_bo_print_info(id++, bo_va->base.bo, m); | |
| 3446 | + } | |
| 3447 | + spin_unlock(&vm->invalidated_lock); | |
| 3448 | + total_done_objs = id; | |
| 3449 | + | |
| 3450 | + seq_printf(m, "\tTotal idle size: %12lld\tobjs:\t%d\n", total_idle, | |
| 3451 | + total_idle_objs); | |
| 3452 | + seq_printf(m, "\tTotal evicted size: %12lld\tobjs:\t%d\n", total_evicted, | |
| 3453 | + total_evicted_objs); | |
| 3454 | + seq_printf(m, "\tTotal relocated size: %12lld\tobjs:\t%d\n", total_relocated, | |
| 3455 | + total_relocated_objs); | |
| 3456 | + seq_printf(m, "\tTotal moved size: %12lld\tobjs:\t%d\n", total_moved, | |
| 3457 | + total_moved_objs); | |
| 3458 | + seq_printf(m, "\tTotal invalidated size: %12lld\tobjs:\t%d\n", total_invalidated, | |
| 3459 | + total_invalidated_objs); | |
| 3460 | + seq_printf(m, "\tTotal done size: %12lld\tobjs:\t%d\n", total_done, | |
| 3461 | + total_done_objs); | |
| 3462 | +} | |
| 3463 | +#endif | |
| @@ -76,6 +76,9 @@ struct amdgpu_bo_list_entry; · 75 unmodified lines | ||
| 76 | 76 | /* PTE is handled as PDE for VEGA10 (Translate Further) */ |
| 77 | 77 | #define AMDGPU_PTE_TF (1ULL << 56) |
| 78 | 78 | |
| 79 | +/* MALL noalloc for sienna_cichlid, reserved for older ASICs */ | |
| 80 | +#define AMDGPU_PTE_NOALLOC (1ULL << 58) | |
| 81 | + | |
| 79 | 82 | /* PDE Block Fragment Size for VEGA10 */ |
| 80 | 83 | #define AMDGPU_PDE_BFS(a) ((uint64_t)a << 59) |
| 81 | 84 | |
| @@ -274,6 +277,9 @@ struct amdgpu_vm { · 192 unmodified lines | ||
| 274 | 277 | /* BO mappings freed, but not yet updated in the PT */ |
| 275 | 278 | struct list_head freed; |
| 276 | 279 | |
| 280 | + /* BOs which are invalidated, has been updated in the PTs */ | |
| 281 | + struct list_head done; | |
| 282 | + | |
| 277 | 283 | /* contains the page directory */ |
| 278 | 284 | struct amdgpu_vm_pt root; |
| 279 | 285 | struct dma_fence *last_update; |
| @@ -441,4 +447,8 @@ void amdgpu_vm_move_to_lru_tail(struct amdgpu_device *adev, · 161 unmodified lines | ||
| 441 | 447 | struct amdgpu_vm *vm); |
| 442 | 448 | void amdgpu_vm_del_from_lru_notify(struct ttm_buffer_object *bo); |
| 443 | 449 | |
| 450 | +#if defined(CONFIG_DEBUG_FS) | |
| 451 | +void amdgpu_debugfs_vm_bo_info(struct amdgpu_vm *vm, struct seq_file *m); | |
| 452 | +#endif | |
| 453 | + | |
| 444 | 454 | #endif |
| @@ -168,8 +168,7 @@ static const struct ttm_resource_manager_func amdgpu_vram_mgr_func; · 167 unmodified lines | ||
| 168 | 168 | /** |
| 169 | 169 | * amdgpu_vram_mgr_init - init VRAM manager and DRM MM |
| 170 | 170 | * |
| 171 | − * @man: TTM memory type manager | |
| 172 | − * @p_size: maximum size of VRAM | |
| 171 | + * @adev: amdgpu_device pointer | |
| 173 | 172 | * |
| 174 | 173 | * Allocate and initialize the VRAM manager. |
| 175 | 174 | */ |
| @@ -185,6 +184,8 @@ int amdgpu_vram_mgr_init(struct amdgpu_device *adev) · 9 unmodified lines | ||
| 185 | 184 | |
| 186 | 185 | drm_mm_init(&mgr->mm, 0, man->size); |
| 187 | 186 | spin_lock_init(&mgr->lock); |
| 187 | + INIT_LIST_HEAD(&mgr->reservations_pending); | |
| 188 | + INIT_LIST_HEAD(&mgr->reserved_pages); | |
| 188 | 189 | |
| 189 | 190 | /* Add the two VRAM-related sysfs files */ |
| 190 | 191 | ret = sysfs_create_files(&adev->dev->kobj, amdgpu_vram_mgr_attributes); |
| @@ -199,7 +200,7 @@ int amdgpu_vram_mgr_init(struct amdgpu_device *adev) · 8 unmodified lines | ||
| 199 | 200 | /** |
| 200 | 201 | * amdgpu_vram_mgr_fini - free and destroy VRAM manager |
| 201 | 202 | * |
| 202 | − * @man: TTM memory type manager | |
| 203 | + * @adev: amdgpu_device pointer | |
| 203 | 204 | * |
| 204 | 205 | * Destroy and free the VRAM manager, returns -EBUSY if ranges are still |
| 205 | 206 | * allocated inside it. |
| @@ -209,6 +210,7 @@ void amdgpu_vram_mgr_fini(struct amdgpu_device *adev) · 3 unmodified lines | ||
| 209 | 210 | struct amdgpu_vram_mgr *mgr = &adev->mman.vram_mgr; |
| 210 | 211 | struct ttm_resource_manager *man = &mgr->manager; |
| 211 | 212 | int ret; |
| 213 | + struct amdgpu_vram_reservation *rsv, *temp; | |
| 212 | 214 | |
| 213 | 215 | ttm_resource_manager_set_used(man, false); |
| 214 | 216 | |
| @@ -217,6 +219,13 @@ void amdgpu_vram_mgr_fini(struct amdgpu_device *adev) · 2 unmodified lines | ||
| 217 | 219 | return; |
| 218 | 220 | |
| 219 | 221 | spin_lock(&mgr->lock); |
| 222 | + list_for_each_entry_safe(rsv, temp, &mgr->reservations_pending, node) | |
| 223 | + kfree(rsv); | |
| 224 | + | |
| 225 | + list_for_each_entry_safe(rsv, temp, &mgr->reserved_pages, node) { | |
| 226 | + drm_mm_remove_node(&rsv->mm_node); | |
| 227 | + kfree(rsv); | |
| 228 | + } | |
| 220 | 229 | drm_mm_takedown(&mgr->mm); |
| 221 | 230 | spin_unlock(&mgr->lock); |
| 222 | 231 | |
| @@ -229,7 +238,7 @@ void amdgpu_vram_mgr_fini(struct amdgpu_device *adev) · 6 unmodified lines | ||
| 229 | 238 | /** |
| 230 | 239 | * amdgpu_vram_mgr_vis_size - Calculate visible node size |
| 231 | 240 | * |
| 232 | − * @adev: amdgpu device structure | |
| 241 | + * @adev: amdgpu_device pointer | |
| 233 | 242 | * @node: MM node structure |
| 234 | 243 | * |
| 235 | 244 | * Calculate how many bytes of the MM node are inside visible VRAM |
| @@ -275,6 +284,101 @@ u64 amdgpu_vram_mgr_bo_visible_size(struct amdgpu_bo *bo) · 39 unmodified lines | ||
| 275 | 284 | return usage; |
| 276 | 285 | } |
| 277 | 286 | |
| 287 | +static void amdgpu_vram_mgr_do_reserve(struct ttm_resource_manager *man) | |
| 288 | +{ | |
| 289 | + struct amdgpu_vram_mgr *mgr = to_vram_mgr(man); | |
| 290 | + struct amdgpu_device *adev = to_amdgpu_device(mgr); | |
| 291 | + struct drm_mm *mm = &mgr->mm; | |
| 292 | + struct amdgpu_vram_reservation *rsv, *temp; | |
| 293 | + uint64_t vis_usage; | |
| 294 | + | |
| 295 | + list_for_each_entry_safe(rsv, temp, &mgr->reservations_pending, node) { | |
| 296 | + if (drm_mm_reserve_node(mm, &rsv->mm_node)) | |
| 297 | + continue; | |
| 298 | + | |
| 299 | + dev_dbg(adev->dev, "Reservation 0x%llx - %lld, Succeeded\n", | |
| 300 | + rsv->mm_node.start, rsv->mm_node.size); | |
| 301 | + | |
| 302 | + vis_usage = amdgpu_vram_mgr_vis_size(adev, &rsv->mm_node); | |
| 303 | + atomic64_add(vis_usage, &mgr->vis_usage); | |
| 304 | + atomic64_add(rsv->mm_node.size << PAGE_SHIFT, &mgr->usage); | |
| 305 | + list_move(&rsv->node, &mgr->reserved_pages); | |
| 306 | + } | |
| 307 | +} | |
| 308 | + | |
| 309 | +/** | |
| 310 | + * amdgpu_vram_mgr_reserve_range - Reserve a range from VRAM | |
| 311 | + * | |
| 312 | + * @man: TTM memory type manager | |
| 313 | + * @start: start address of the range in VRAM | |
| 314 | + * @size: size of the range | |
| 315 | + * | |
| 316 | + * Reserve memory from start addess with the specified size in VRAM | |
| 317 | + */ | |
| 318 | +int amdgpu_vram_mgr_reserve_range(struct ttm_resource_manager *man, | |
| 319 | + uint64_t start, uint64_t size) | |
| 320 | +{ | |
| 321 | + struct amdgpu_vram_mgr *mgr = to_vram_mgr(man); | |
| 322 | + struct amdgpu_vram_reservation *rsv; | |
| 323 | + | |
| 324 | + rsv = kzalloc(sizeof(*rsv), GFP_KERNEL); | |
| 325 | + if (!rsv) | |
| 326 | + return -ENOMEM; | |
| 327 | + | |
| 328 | + INIT_LIST_HEAD(&rsv->node); | |
| 329 | + rsv->mm_node.start = start >> PAGE_SHIFT; | |
| 330 | + rsv->mm_node.size = size >> PAGE_SHIFT; | |
| 331 | + | |
| 332 | + spin_lock(&mgr->lock); | |
| 333 | + list_add_tail(&mgr->reservations_pending, &rsv->node); | |
| 334 | + amdgpu_vram_mgr_do_reserve(man); | |
| 335 | + spin_unlock(&mgr->lock); | |
| 336 | + | |
| 337 | + return 0; | |
| 338 | +} | |
| 339 | + | |
| 340 | +/** | |
| 341 | + * amdgpu_vram_mgr_query_page_status - query the reservation status | |
| 342 | + * | |
| 343 | + * @man: TTM memory type manager | |
| 344 | + * @start: start address of a page in VRAM | |
| 345 | + * | |
| 346 | + * Returns: | |
| 347 | + * -EBUSY: the page is still hold and in pending list | |
| 348 | + * 0: the page has been reserved | |
| 349 | + * -ENOENT: the input page is not a reservation | |
| 350 | + */ | |
| 351 | +int amdgpu_vram_mgr_query_page_status(struct ttm_resource_manager *man, | |
| 352 | + uint64_t start) | |
| 353 | +{ | |
| 354 | + struct amdgpu_vram_mgr *mgr = to_vram_mgr(man); | |
| 355 | + struct amdgpu_vram_reservation *rsv; | |
| 356 | + int ret; | |
| 357 | + | |
| 358 | + spin_lock(&mgr->lock); | |
| 359 | + | |
| 360 | + list_for_each_entry(rsv, &mgr->reservations_pending, node) { | |
| 361 | + if ((rsv->mm_node.start <= start) && | |
| 362 | + (start < (rsv->mm_node.start + rsv->mm_node.size))) { | |
| 363 | + ret = -EBUSY; | |
| 364 | + goto out; | |
| 365 | + } | |
| 366 | + } | |
| 367 | + | |
| 368 | + list_for_each_entry(rsv, &mgr->reserved_pages, node) { | |
| 369 | + if ((rsv->mm_node.start <= start) && | |
| 370 | + (start < (rsv->mm_node.start + rsv->mm_node.size))) { | |
| 371 | + ret = 0; | |
| 372 | + goto out; | |
| 373 | + } | |
| 374 | + } | |
| 375 | + | |
| 376 | + ret = -ENOENT; | |
| 377 | +out: | |
| 378 | + spin_unlock(&mgr->lock); | |
| 379 | + return ret; | |
| 380 | +} | |
| 381 | + | |
| 278 | 382 | /** |
| 279 | 383 | * amdgpu_vram_mgr_virt_start - update virtual start address |
| 280 | 384 | * |
| @@ -445,6 +549,7 @@ static void amdgpu_vram_mgr_del(struct ttm_resource_manager *man, · 164 unmodified lines | ||
| 445 | 549 | vis_usage += amdgpu_vram_mgr_vis_size(adev, nodes); |
| 446 | 550 | ++nodes; |
| 447 | 551 | } |
| 552 | + amdgpu_vram_mgr_do_reserve(man); | |
| 448 | 553 | spin_unlock(&mgr->lock); |
| 449 | 554 | |
| 450 | 555 | atomic64_sub(usage, &mgr->usage); |
| @@ -529,7 +634,7 @@ error_free: · 78 unmodified lines | ||
| 529 | 634 | } |
| 530 | 635 | |
| 531 | 636 | /** |
| 532 | − * amdgpu_vram_mgr_alloc_sgt - allocate and fill a sg table | |
| 637 | + * amdgpu_vram_mgr_free_sgt - allocate and fill a sg table | |
| 533 | 638 | * |
| 534 | 639 | * @adev: amdgpu device pointer |
| 535 | 640 | * @sgt: sg table to free |
| @@ -246,7 +246,7 @@ static ssize_t amdgpu_xgmi_show_error(struct device *dev, · 245 unmodified lines | ||
| 246 | 246 | |
| 247 | 247 | adev->df.funcs->set_fica(adev, ficaa_pie_status_in, 0, 0); |
| 248 | 248 | |
| 249 | − return snprintf(buf, PAGE_SIZE, "%d\n", error_count); | |
| 249 | + return snprintf(buf, PAGE_SIZE, "%u\n", error_count); | |
| 250 | 250 | } |
| 251 | 251 | |
| 252 | 252 | |
| @@ -74,6 +74,7 @@ int athub_v2_1_set_clockgating(struct amdgpu_device *adev, · 73 unmodified lines | ||
| 74 | 74 | switch (adev->asic_type) { |
| 75 | 75 | case CHIP_SIENNA_CICHLID: |
| 76 | 76 | case CHIP_NAVY_FLOUNDER: |
| 77 | + case CHIP_DIMGREY_CAVEFISH: | |
| 77 | 78 | athub_v2_1_update_medium_grain_clock_gating(adev, |
| 78 | 79 | state == AMD_CG_STATE_GATE ? true : false); |
| 79 | 80 | athub_v2_1_update_medium_grain_light_sleep(adev, |
| @@ -66,13 +66,13 @@ typedef struct { · 65 unmodified lines | ||
| 66 | 66 | bool abort; |
| 67 | 67 | } atom_exec_context; |
| 68 | 68 | |
| 69 | −int amdgpu_atom_debug = 0; | |
| 70 | −static int amdgpu_atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params); | |
| 71 | −int amdgpu_atom_execute_table(struct atom_context *ctx, int index, uint32_t * params); | |
| 69 | +int amdgpu_atom_debug; | |
| 70 | +static int amdgpu_atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t *params); | |
| 71 | +int amdgpu_atom_execute_table(struct atom_context *ctx, int index, uint32_t *params); | |
| 72 | 72 | |
| 73 | 73 | static uint32_t atom_arg_mask[8] = |
| 74 | − { 0xFFFFFFFF, 0xFFFF, 0xFFFF00, 0xFFFF0000, 0xFF, 0xFF00, 0xFF0000, | |
| 75 | −0xFF000000 }; | |
| 74 | + { 0xFFFFFFFF, 0xFFFF, 0xFFFF00, 0xFFFF0000, 0xFF, 0xFF00, 0xFF0000, | |
| 75 | + 0xFF000000 }; | |
| 76 | 76 | static int atom_arg_shift[8] = { 0, 0, 8, 16, 0, 8, 16, 24 }; |
| 77 | 77 | |
| 78 | 78 | static int atom_dst_to_src[8][4] = { |
| @@ -88,7 +88,7 @@ static int atom_dst_to_src[8][4] = { · 9 unmodified lines | ||
| 88 | 88 | }; |
| 89 | 89 | static int atom_def_dst[8] = { 0, 0, 1, 2, 0, 1, 2, 3 }; |
| 90 | 90 | |
| 91 | −static int debug_depth = 0; | |
| 91 | +static int debug_depth; | |
| 92 | 92 | #ifdef ATOM_DEBUG |
| 93 | 93 | static void debug_print_spaces(int n) |
| 94 | 94 | { |
| @@ -1201,7 +1201,7 @@ static struct { · 1106 unmodified lines | ||
| 1201 | 1201 | atom_op_div32, ATOM_ARG_WS}, |
| 1202 | 1202 | }; |
| 1203 | 1203 | |
| 1204 | −static int amdgpu_atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params) | |
| 1204 | +static int amdgpu_atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t *params) | |
| 1205 | 1205 | { |
| 1206 | 1206 | int base = CU16(ctx->cmd_table + 4 + 2 * index); |
| 1207 | 1207 | int len, ws, ps, ptr; |
| @@ -1262,7 +1262,7 @@ free: · 54 unmodified lines | ||
| 1262 | 1262 | return ret; |
| 1263 | 1263 | } |
| 1264 | 1264 | |
| 1265 | −int amdgpu_atom_execute_table(struct atom_context *ctx, int index, uint32_t * params) | |
| 1265 | +int amdgpu_atom_execute_table(struct atom_context *ctx, int index, uint32_t *params) | |
| 1266 | 1266 | { |
| 1267 | 1267 | int r; |
| 1268 | 1268 | |
| @@ -1388,8 +1388,8 @@ void amdgpu_atom_destroy(struct atom_context *ctx) · 119 unmodified lines | ||
| 1388 | 1388 | } |
| 1389 | 1389 | |
| 1390 | 1390 | bool amdgpu_atom_parse_data_header(struct atom_context *ctx, int index, |
| 1391 | − uint16_t * size, uint8_t * frev, uint8_t * crev, | |
| 1392 | − uint16_t * data_start) | |
| 1391 | + uint16_t *size, uint8_t *frev, uint8_t *crev, | |
| 1392 | + uint16_t *data_start) | |
| 1393 | 1393 | { |
| 1394 | 1394 | int offset = index * 2 + 4; |
| 1395 | 1395 | int idx = CU16(ctx->data_table + offset); |
| @@ -1408,8 +1408,8 @@ bool amdgpu_atom_parse_data_header(struct atom_context *ctx, int index, · 12 unmodified lines | ||
| 1408 | 1408 | return true; |
| 1409 | 1409 | } |
| 1410 | 1410 | |
| 1411 | −bool amdgpu_atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t * frev, | |
| 1412 | − uint8_t * crev) | |
| 1411 | +bool amdgpu_atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t *frev, | |
| 1412 | + uint8_t *crev) | |
| 1413 | 1413 | { |
| 1414 | 1414 | int offset = index * 2 + 4; |
| 1415 | 1415 | int idx = CU16(ctx->cmd_table + offset); |
| @@ -499,10 +499,8 @@ int amdgpu_atombios_encoder_get_encoder_mode(struct drm_encoder *encoder) · 498 unmodified lines | ||
| 499 | 499 | } else { |
| 500 | 500 | return ATOM_ENCODER_MODE_DVI; |
| 501 | 501 | } |
| 502 | − break; | |
| 503 | 502 | case DRM_MODE_CONNECTOR_LVDS: |
| 504 | 503 | return ATOM_ENCODER_MODE_LVDS; |
| 505 | − break; | |
| 506 | 504 | case DRM_MODE_CONNECTOR_DisplayPort: |
| 507 | 505 | dig_connector = amdgpu_connector->con_priv; |
| 508 | 506 | if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || |
| @@ -519,20 +517,16 @@ int amdgpu_atombios_encoder_get_encoder_mode(struct drm_encoder *encoder) · 10 unmodified lines | ||
| 519 | 517 | } else { |
| 520 | 518 | return ATOM_ENCODER_MODE_DVI; |
| 521 | 519 | } |
| 522 | − break; | |
| 523 | 520 | case DRM_MODE_CONNECTOR_eDP: |
| 524 | 521 | return ATOM_ENCODER_MODE_DP; |
| 525 | 522 | case DRM_MODE_CONNECTOR_DVIA: |
| 526 | 523 | case DRM_MODE_CONNECTOR_VGA: |
| 527 | 524 | return ATOM_ENCODER_MODE_CRT; |
| 528 | − break; | |
| 529 | 525 | case DRM_MODE_CONNECTOR_Composite: |
| 530 | 526 | case DRM_MODE_CONNECTOR_SVIDEO: |
| 531 | 527 | case DRM_MODE_CONNECTOR_9PinDIN: |
| 532 | 528 | /* fix me */ |
| 533 | 529 | return ATOM_ENCODER_MODE_TV; |
| 534 | − /*return ATOM_ENCODER_MODE_CV;*/ | |
| 535 | − break; | |
| 536 | 530 | } |
| 537 | 531 | } |
| 538 | 532 | |
| @@ -159,7 +159,7 @@ u32 amdgpu_atombios_i2c_func(struct i2c_adapter *adap) · 158 unmodified lines | ||
| 159 | 159 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; |
| 160 | 160 | } |
| 161 | 161 | |
| 162 | −void amdgpu_atombios_i2c_channel_trans(struct amdgpu_device* adev, u8 slave_addr, u8 line_number, u8 offset, u8 data) | |
| 162 | +void amdgpu_atombios_i2c_channel_trans(struct amdgpu_device *adev, u8 slave_addr, u8 line_number, u8 offset, u8 data) | |
| 163 | 163 | { |
| 164 | 164 | PROCESS_I2C_CHANNEL_TRANSACTION_PS_ALLOCATION args; |
| 165 | 165 | int index = GetIndexIntoMasterTable(COMMAND, ProcessI2cChannelTransaction); |
| @@ -1336,11 +1336,13 @@ cik_asic_reset_method(struct amdgpu_device *adev) · 1335 unmodified lines | ||
| 1336 | 1336 | |
| 1337 | 1337 | switch (adev->asic_type) { |
| 1338 | 1338 | case CHIP_BONAIRE: |
| 1339 | − case CHIP_HAWAII: | |
| 1340 | 1339 | /* disable baco reset until it works */ |
| 1341 | 1340 | /* smu7_asic_get_baco_capability(adev, &baco_reset); */ |
| 1342 | 1341 | baco_reset = false; |
| 1343 | 1342 | break; |
| 1343 | + case CHIP_HAWAII: | |
| 1344 | + baco_reset = cik_asic_supports_baco(adev); | |
| 1345 | + break; | |
| 1344 | 1346 | default: |
| 1345 | 1347 | baco_reset = false; |
| 1346 | 1348 | break; |
| @@ -195,7 +195,7 @@ static void cik_sdma_ring_set_wptr(struct amdgpu_ring *ring) · 194 unmodified lines | ||
| 195 | 195 | struct amdgpu_device *adev = ring->adev; |
| 196 | 196 | |
| 197 | 197 | WREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[ring->me], |
| 198 | − (lower_32_bits(ring->wptr) << 2) & 0x3fffc); | |
| 198 | + (lower_32_bits(ring->wptr) << 2) & 0x3fffc); | |
| 199 | 199 | } |
| 200 | 200 | |
| 201 | 201 | static void cik_sdma_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count) |
| @@ -1071,22 +1071,19 @@ static int cik_sdma_soft_reset(void *handle) · 869 unmodified lines | ||
| 1071 | 1071 | { |
| 1072 | 1072 | u32 srbm_soft_reset = 0; |
| 1073 | 1073 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
| 1074 | − u32 tmp = RREG32(mmSRBM_STATUS2); | |
| 1074 | + u32 tmp; | |
| 1075 | 1075 | |
| 1076 | − if (tmp & SRBM_STATUS2__SDMA_BUSY_MASK) { | |
| 1077 | − /* sdma0 */ | |
| 1078 | − tmp = RREG32(mmSDMA0_F32_CNTL + SDMA0_REGISTER_OFFSET); | |
| 1079 | − tmp |= SDMA0_F32_CNTL__HALT_MASK; | |
| 1080 | − WREG32(mmSDMA0_F32_CNTL + SDMA0_REGISTER_OFFSET, tmp); | |
| 1081 | − srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_SDMA_MASK; | |
| 1082 | − } | |
| 1083 | − if (tmp & SRBM_STATUS2__SDMA1_BUSY_MASK) { | |
| 1084 | − /* sdma1 */ | |
| 1085 | − tmp = RREG32(mmSDMA0_F32_CNTL + SDMA1_REGISTER_OFFSET); | |
| 1086 | − tmp |= SDMA0_F32_CNTL__HALT_MASK; | |
| 1087 | − WREG32(mmSDMA0_F32_CNTL + SDMA1_REGISTER_OFFSET, tmp); | |
| 1088 | − srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_SDMA1_MASK; | |
| 1089 | − } | |
| 1076 | + /* sdma0 */ | |
| 1077 | + tmp = RREG32(mmSDMA0_F32_CNTL + SDMA0_REGISTER_OFFSET); | |
| 1078 | + tmp |= SDMA0_F32_CNTL__HALT_MASK; | |
| 1079 | + WREG32(mmSDMA0_F32_CNTL + SDMA0_REGISTER_OFFSET, tmp); | |
| 1080 | + srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_SDMA_MASK; | |
| 1081 | + | |
| 1082 | + /* sdma1 */ | |
| 1083 | + tmp = RREG32(mmSDMA0_F32_CNTL + SDMA1_REGISTER_OFFSET); | |
| 1084 | + tmp |= SDMA0_F32_CNTL__HALT_MASK; | |
| 1085 | + WREG32(mmSDMA0_F32_CNTL + SDMA1_REGISTER_OFFSET, tmp); | |
| 1086 | + srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_SDMA1_MASK; | |
| 1090 | 1087 | |
| 1091 | 1088 | if (srbm_soft_reset) { |
| 1092 | 1089 | tmp = RREG32(mmSRBM_SOFT_RESET); |
| @@ -2202,22 +2202,18 @@ static int dce_v10_0_pick_dig_encoder(struct drm_encoder *encoder) · 2201 unmodified lines | ||
| 2202 | 2202 | return 1; |
| 2203 | 2203 | else |
| 2204 | 2204 | return 0; |
| 2205 | − break; | |
| 2206 | 2205 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: |
| 2207 | 2206 | if (dig->linkb) |
| 2208 | 2207 | return 3; |
| 2209 | 2208 | else |
| 2210 | 2209 | return 2; |
| 2211 | − break; | |
| 2212 | 2210 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: |
| 2213 | 2211 | if (dig->linkb) |
| 2214 | 2212 | return 5; |
| 2215 | 2213 | else |
| 2216 | 2214 | return 4; |
| 2217 | − break; | |
| 2218 | 2215 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3: |
| 2219 | 2216 | return 6; |
| 2220 | − break; | |
| 2221 | 2217 | default: |
| 2222 | 2218 | DRM_ERROR("invalid encoder_id: 0x%x\n", amdgpu_encoder->encoder_id); |
| 2223 | 2219 | return 0; |
| @@ -2677,7 +2673,7 @@ static int dce_v10_0_crtc_set_base_atomic(struct drm_crtc *crtc, · 453 unmodified lines | ||
| 2677 | 2673 | struct drm_framebuffer *fb, |
| 2678 | 2674 | int x, int y, enum mode_set_atomic state) |
| 2679 | 2675 | { |
| 2680 | − return dce_v10_0_crtc_do_set_base(crtc, fb, x, y, 1); | |
| 2676 | + return dce_v10_0_crtc_do_set_base(crtc, fb, x, y, 1); | |
| 2681 | 2677 | } |
| 2682 | 2678 | |
| 2683 | 2679 | static const struct drm_crtc_helper_funcs dce_v10_0_crtc_helper_funcs = { |
| @@ -2235,22 +2235,18 @@ static int dce_v11_0_pick_dig_encoder(struct drm_encoder *encoder) · 2234 unmodified lines | ||
| 2235 | 2235 | return 1; |
| 2236 | 2236 | else |
| 2237 | 2237 | return 0; |
| 2238 | − break; | |
| 2239 | 2238 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: |
| 2240 | 2239 | if (dig->linkb) |
| 2241 | 2240 | return 3; |
| 2242 | 2241 | else |
| 2243 | 2242 | return 2; |
| 2244 | − break; | |
| 2245 | 2243 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: |
| 2246 | 2244 | if (dig->linkb) |
| 2247 | 2245 | return 5; |
| 2248 | 2246 | else |
| 2249 | 2247 | return 4; |
| 2250 | − break; | |
| 2251 | 2248 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3: |
| 2252 | 2249 | return 6; |
| 2253 | − break; | |
| 2254 | 2250 | default: |
| 2255 | 2251 | DRM_ERROR("invalid encoder_id: 0x%x\n", amdgpu_encoder->encoder_id); |
| 2256 | 2252 | return 0; |
| @@ -2304,19 +2300,16 @@ static u32 dce_v11_0_pick_pll(struct drm_crtc *crtc) · 47 unmodified lines | ||
| 2304 | 2300 | return ATOM_COMBOPHY_PLL1; |
| 2305 | 2301 | else |
| 2306 | 2302 | return ATOM_COMBOPHY_PLL0; |
| 2307 | − break; | |
| 2308 | 2303 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: |
| 2309 | 2304 | if (dig->linkb) |
| 2310 | 2305 | return ATOM_COMBOPHY_PLL3; |
| 2311 | 2306 | else |
| 2312 | 2307 | return ATOM_COMBOPHY_PLL2; |
| 2313 | − break; | |
| 2314 | 2308 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: |
| 2315 | 2309 | if (dig->linkb) |
| 2316 | 2310 | return ATOM_COMBOPHY_PLL5; |
| 2317 | 2311 | else |
| 2318 | 2312 | return ATOM_COMBOPHY_PLL4; |
| 2319 | − break; | |
| 2320 | 2313 | default: |
| 2321 | 2314 | DRM_ERROR("invalid encoder_id: 0x%x\n", amdgpu_encoder->encoder_id); |
| 2322 | 2315 | return ATOM_PPLL_INVALID; |
| @@ -2785,7 +2778,7 @@ static int dce_v11_0_crtc_set_base_atomic(struct drm_crtc *crtc, · 462 unmodified lines | ||
| 2785 | 2778 | struct drm_framebuffer *fb, |
| 2786 | 2779 | int x, int y, enum mode_set_atomic state) |
| 2787 | 2780 | { |
| 2788 | − return dce_v11_0_crtc_do_set_base(crtc, fb, x, y, 1); | |
| 2781 | + return dce_v11_0_crtc_do_set_base(crtc, fb, x, y, 1); | |
| 2789 | 2782 | } |
| 2790 | 2783 | |
| 2791 | 2784 | static const struct drm_crtc_helper_funcs dce_v11_0_crtc_helper_funcs = { |
| @@ -2567,7 +2567,7 @@ static int dce_v6_0_crtc_set_base_atomic(struct drm_crtc *crtc, · 2566 unmodified lines | ||
| 2567 | 2567 | struct drm_framebuffer *fb, |
| 2568 | 2568 | int x, int y, enum mode_set_atomic state) |
| 2569 | 2569 | { |
| 2570 | − return dce_v6_0_crtc_do_set_base(crtc, fb, x, y, 1); | |
| 2570 | + return dce_v6_0_crtc_do_set_base(crtc, fb, x, y, 1); | |
| 2571 | 2571 | } |
| 2572 | 2572 | |
| 2573 | 2573 | static const struct drm_crtc_helper_funcs dce_v6_0_crtc_helper_funcs = { |
| @@ -2498,7 +2498,7 @@ static void dce_v8_0_crtc_disable(struct drm_crtc *crtc) · 2497 unmodified lines | ||
| 2498 | 2498 | case ATOM_PPLL2: |
| 2499 | 2499 | /* disable the ppll */ |
| 2500 | 2500 | amdgpu_atombios_crtc_program_pll(crtc, amdgpu_crtc->crtc_id, amdgpu_crtc->pll_id, |
| 2501 | − 0, 0, ATOM_DISABLE, 0, 0, 0, 0, 0, false, &ss); | |
| 2501 | + 0, 0, ATOM_DISABLE, 0, 0, 0, 0, 0, false, &ss); | |
| 2502 | 2502 | break; |
| 2503 | 2503 | case ATOM_PPLL0: |
| 2504 | 2504 | /* disable the ppll */ |
| @@ -2585,7 +2585,7 @@ static int dce_v8_0_crtc_set_base_atomic(struct drm_crtc *crtc, · 80 unmodified lines | ||
| 2585 | 2585 | struct drm_framebuffer *fb, |
| 2586 | 2586 | int x, int y, enum mode_set_atomic state) |
| 2587 | 2587 | { |
| 2588 | − return dce_v8_0_crtc_do_set_base(crtc, fb, x, y, 1); | |
| 2588 | + return dce_v8_0_crtc_do_set_base(crtc, fb, x, y, 1); | |
| 2589 | 2589 | } |
| 2590 | 2590 | |
| 2591 | 2591 | static const struct drm_crtc_helper_funcs dce_v8_0_crtc_helper_funcs = { |
| @@ -41,7 +41,7 @@ static void df_v1_7_sw_fini(struct amdgpu_device *adev) · 40 unmodified lines | ||
| 41 | 41 | } |
| 42 | 42 | |
| 43 | 43 | static void df_v1_7_enable_broadcast_mode(struct amdgpu_device *adev, |
| 44 | − bool enable) | |
| 44 | + bool enable) | |
| 45 | 45 | { |
| 46 | 46 | u32 tmp; |
| 47 | 47 | |
| @@ -30,71 +30,17 @@ · 29 unmodified lines | ||
| 30 | 30 | #define DF_3_6_SMN_REG_INST_DIST 0x8 |
| 31 | 31 | #define DF_3_6_INST_CNT 8 |
| 32 | 32 | |
| 33 | −static u32 df_v3_6_channel_number[] = {1, 2, 0, 4, 0, 8, 0, | |
| 34 | − 16, 32, 0, 0, 0, 2, 4, 8}; | |
| 35 | − | |
| 36 | −/* init df format attrs */ | |
| 37 | −AMDGPU_PMU_ATTR(event, "config:0-7"); | |
| 38 | −AMDGPU_PMU_ATTR(instance, "config:8-15"); | |
| 39 | −AMDGPU_PMU_ATTR(umask, "config:16-23"); | |
| 40 | − | |
| 41 | −/* df format attributes */ | |
| 42 | −static struct attribute *df_v3_6_format_attrs[] = { | |
| 43 | − &pmu_attr_event.attr, | |
| 44 | − &pmu_attr_instance.attr, | |
| 45 | − &pmu_attr_umask.attr, | |
| 46 | − NULL | |
| 47 | −}; | |
| 48 | − | |
| 49 | −/* df format attribute group */ | |
| 50 | −static struct attribute_group df_v3_6_format_attr_group = { | |
| 51 | − .name = "format", | |
| 52 | − .attrs = df_v3_6_format_attrs, | |
| 53 | −}; | |
| 54 | − | |
| 55 | −/* df event attrs */ | |
| 56 | −AMDGPU_PMU_ATTR(cake0_pcsout_txdata, | |
| 57 | − "event=0x7,instance=0x46,umask=0x2"); | |
| 58 | −AMDGPU_PMU_ATTR(cake1_pcsout_txdata, | |
| 59 | − "event=0x7,instance=0x47,umask=0x2"); | |
| 60 | −AMDGPU_PMU_ATTR(cake0_pcsout_txmeta, | |
| 61 | − "event=0x7,instance=0x46,umask=0x4"); | |
| 62 | −AMDGPU_PMU_ATTR(cake1_pcsout_txmeta, | |
| 63 | − "event=0x7,instance=0x47,umask=0x4"); | |
| 64 | −AMDGPU_PMU_ATTR(cake0_ftiinstat_reqalloc, | |
| 65 | − "event=0xb,instance=0x46,umask=0x4"); | |
| 66 | −AMDGPU_PMU_ATTR(cake1_ftiinstat_reqalloc, | |
| 67 | − "event=0xb,instance=0x47,umask=0x4"); | |
| 68 | −AMDGPU_PMU_ATTR(cake0_ftiinstat_rspalloc, | |
| 69 | − "event=0xb,instance=0x46,umask=0x8"); | |
| 70 | −AMDGPU_PMU_ATTR(cake1_ftiinstat_rspalloc, | |
| 71 | − "event=0xb,instance=0x47,umask=0x8"); | |
| 72 | − | |
| 73 | −/* df event attributes */ | |
| 74 | −static struct attribute *df_v3_6_event_attrs[] = { | |
| 75 | − &pmu_attr_cake0_pcsout_txdata.attr, | |
| 76 | − &pmu_attr_cake1_pcsout_txdata.attr, | |
| 77 | − &pmu_attr_cake0_pcsout_txmeta.attr, | |
| 78 | − &pmu_attr_cake1_pcsout_txmeta.attr, | |
| 79 | − &pmu_attr_cake0_ftiinstat_reqalloc.attr, | |
| 80 | − &pmu_attr_cake1_ftiinstat_reqalloc.attr, | |
| 81 | − &pmu_attr_cake0_ftiinstat_rspalloc.attr, | |
| 82 | − &pmu_attr_cake1_ftiinstat_rspalloc.attr, | |
| 83 | − NULL | |
| 84 | −}; | |
| 33 | +/* Defined in global_features.h as FTI_PERFMON_VISIBLE */ | |
| 34 | +#define DF_V3_6_MAX_COUNTERS 4 | |
| 85 | 35 | |
| 86 | −/* df event attribute group */ | |
| 87 | −static struct attribute_group df_v3_6_event_attr_group = { | |
| 88 | − .name = "events", | |
| 89 | − .attrs = df_v3_6_event_attrs | |
| 90 | −}; | |
| 36 | +/* get flags from df perfmon config */ | |
| 37 | +#define DF_V3_6_GET_EVENT(x) (x & 0xFFUL) | |
| 38 | +#define DF_V3_6_GET_INSTANCE(x) ((x >> 8) & 0xFFUL) | |
| 39 | +#define DF_V3_6_GET_UNITMASK(x) ((x >> 16) & 0xFFUL) | |
| 40 | +#define DF_V3_6_PERFMON_OVERFLOW 0xFFFFFFFFFFFFULL | |
| 91 | 41 | |
| 92 | −/* df event attr groups */ | |
| 93 | −const struct attribute_group *df_v3_6_attr_groups[] = { | |
| 94 | − &df_v3_6_format_attr_group, | |
| 95 | − &df_v3_6_event_attr_group, | |
| 96 | − NULL | |
| 97 | −}; | |
| 42 | +static u32 df_v3_6_channel_number[] = {1, 2, 0, 4, 0, 8, 0, | |
| 43 | + 16, 32, 0, 0, 0, 2, 4, 8}; | |
| 98 | 44 | |
| 99 | 45 | static uint64_t df_v3_6_get_fica(struct amdgpu_device *adev, |
| 100 | 46 | uint32_t ficaa_val) |
| @@ -391,33 +337,28 @@ static void df_v3_6_get_clockgating_state(struct amdgpu_device *adev, · 290 unmodified lines | ||
| 391 | 337 | } |
| 392 | 338 | |
| 393 | 339 | /* get assigned df perfmon ctr as int */ |
| 394 | −static int df_v3_6_pmc_config_2_cntr(struct amdgpu_device *adev, | |
| 395 | − uint64_t config) | |
| 340 | +static bool df_v3_6_pmc_has_counter(struct amdgpu_device *adev, | |
| 341 | + uint64_t config, | |
| 342 | + int counter_idx) | |
| 396 | 343 | { |
| 397 | − int i; | |
| 398 | 344 | |
| 399 | − for (i = 0; i < DF_V3_6_MAX_COUNTERS; i++) { | |
| 400 | − if ((config & 0x0FFFFFFUL) == | |
| 401 | − adev->df_perfmon_config_assign_mask[i]) | |
| 402 | − return i; | |
| 403 | − } | |
| 345 | + return ((config & 0x0FFFFFFUL) == | |
| 346 | + adev->df_perfmon_config_assign_mask[counter_idx]); | |
| 404 | 347 | |
| 405 | − return -EINVAL; | |
| 406 | 348 | } |
| 407 | 349 | |
| 408 | 350 | /* get address based on counter assignment */ |
| 409 | 351 | static void df_v3_6_pmc_get_addr(struct amdgpu_device *adev, |
| 410 | 352 | uint64_t config, |
| 353 | + int counter_idx, | |
| 411 | 354 | int is_ctrl, |
| 412 | 355 | uint32_t *lo_base_addr, |
| 413 | 356 | uint32_t *hi_base_addr) |
| 414 | 357 | { |
| 415 | − int target_cntr = df_v3_6_pmc_config_2_cntr(adev, config); | |
| 416 | − | |
| 417 | − if (target_cntr < 0) | |
| 358 | + if (!df_v3_6_pmc_has_counter(adev, config, counter_idx)) | |
| 418 | 359 | return; |
| 419 | 360 | |
| 420 | − switch (target_cntr) { | |
| 361 | + switch (counter_idx) { | |
| 421 | 362 | |
| 422 | 363 | case 0: |
| 423 | 364 | *lo_base_addr = is_ctrl ? smnPerfMonCtlLo4 : smnPerfMonCtrLo4; |
| @@ -443,15 +384,18 @@ static void df_v3_6_pmc_get_addr(struct amdgpu_device *adev, · 19 unmodified lines | ||
| 443 | 384 | /* get read counter address */ |
| 444 | 385 | static void df_v3_6_pmc_get_read_settings(struct amdgpu_device *adev, |
| 445 | 386 | uint64_t config, |
| 387 | + int counter_idx, | |
| 446 | 388 | uint32_t *lo_base_addr, |
| 447 | 389 | uint32_t *hi_base_addr) |
| 448 | 390 | { |
| 449 | − df_v3_6_pmc_get_addr(adev, config, 0, lo_base_addr, hi_base_addr); | |
| 391 | + df_v3_6_pmc_get_addr(adev, config, counter_idx, 0, lo_base_addr, | |
| 392 | + hi_base_addr); | |
| 450 | 393 | } |
| 451 | 394 | |
| 452 | 395 | /* get control counter settings i.e. address and values to set */ |
| 453 | 396 | static int df_v3_6_pmc_get_ctrl_settings(struct amdgpu_device *adev, |
| 454 | 397 | uint64_t config, |
| 398 | + int counter_idx, | |
| 455 | 399 | uint32_t *lo_base_addr, |
| 456 | 400 | uint32_t *hi_base_addr, |
| 457 | 401 | uint32_t *lo_val, |
| @@ -462,7 +406,8 @@ static int df_v3_6_pmc_get_ctrl_settings(struct amdgpu_device *adev, · 4 unmodified lines | ||
| 462 | 406 | uint32_t eventsel, instance, unitmask; |
| 463 | 407 | uint32_t instance_10, instance_5432, instance_76; |
| 464 | 408 | |
| 465 | − df_v3_6_pmc_get_addr(adev, config, 1, lo_base_addr, hi_base_addr); | |
| 409 | + df_v3_6_pmc_get_addr(adev, config, counter_idx, 1, lo_base_addr, | |
| 410 | + hi_base_addr); | |
| 466 | 411 | |
| 467 | 412 | if ((*lo_base_addr == 0) || (*hi_base_addr == 0)) { |
| 468 | 413 | DRM_ERROR("[DF PMC] addressing not retrieved! Lo: %x, Hi: %x", |
| @@ -492,18 +437,13 @@ static int df_v3_6_pmc_get_ctrl_settings(struct amdgpu_device *adev, · 23 unmodified lines | ||
| 492 | 437 | static int df_v3_6_pmc_add_cntr(struct amdgpu_device *adev, |
| 493 | 438 | uint64_t config) |
| 494 | 439 | { |
| 495 | − int i, target_cntr; | |
| 496 | − | |
| 497 | − target_cntr = df_v3_6_pmc_config_2_cntr(adev, config); | |
| 498 | − | |
| 499 | − if (target_cntr >= 0) | |
| 500 | − return 0; | |
| 440 | + int i; | |
| 501 | 441 | |
| 502 | 442 | for (i = 0; i < DF_V3_6_MAX_COUNTERS; i++) { |
| 503 | 443 | if (adev->df_perfmon_config_assign_mask[i] == 0U) { |
| 504 | 444 | adev->df_perfmon_config_assign_mask[i] = |
| 505 | 445 | config & 0x0FFFFFFUL; |
| 506 | − return 0; | |
| 446 | + return i; | |
| 507 | 447 | } |
| 508 | 448 | } |
| 509 | 449 | |
| @@ -512,59 +452,50 @@ static int df_v3_6_pmc_add_cntr(struct amdgpu_device *adev, · 2 unmodified lines | ||
| 512 | 452 | |
| 513 | 453 | #define DEFERRED_ARM_MASK (1 << 31) |
| 514 | 454 | static int df_v3_6_pmc_set_deferred(struct amdgpu_device *adev, |
| 515 | − uint64_t config, bool is_deferred) | |
| 455 | + int counter_idx, uint64_t config, | |
| 456 | + bool is_deferred) | |
| 516 | 457 | { |
| 517 | − int target_cntr; | |
| 518 | 458 | |
| 519 | − target_cntr = df_v3_6_pmc_config_2_cntr(adev, config); | |
| 520 | − | |
| 521 | − if (target_cntr < 0) | |
| 459 | + if (!df_v3_6_pmc_has_counter(adev, config, counter_idx)) | |
| 522 | 460 | return -EINVAL; |
| 523 | 461 | |
| 524 | 462 | if (is_deferred) |
| 525 | − adev->df_perfmon_config_assign_mask[target_cntr] |= | |
| 463 | + adev->df_perfmon_config_assign_mask[counter_idx] |= | |
| 526 | 464 | DEFERRED_ARM_MASK; |
| 527 | 465 | else |
| 528 | − adev->df_perfmon_config_assign_mask[target_cntr] &= | |
| 466 | + adev->df_perfmon_config_assign_mask[counter_idx] &= | |
| 529 | 467 | ~DEFERRED_ARM_MASK; |
| 530 | 468 | |
| 531 | 469 | return 0; |
| 532 | 470 | } |
| 533 | 471 | |
| 534 | 472 | static bool df_v3_6_pmc_is_deferred(struct amdgpu_device *adev, |
| 473 | + int counter_idx, | |
| 535 | 474 | uint64_t config) |
| 536 | 475 | { |
| 537 | − int target_cntr; | |
| 538 | − | |
| 539 | − target_cntr = df_v3_6_pmc_config_2_cntr(adev, config); | |
| 540 | − | |
| 541 | − /* | |
| 542 | − * we never get target_cntr < 0 since this funciton is only called in | |
| 543 | − * pmc_count for now but we should check anyways. | |
| 544 | − */ | |
| 545 | − return (target_cntr >= 0 && | |
| 546 | − (adev->df_perfmon_config_assign_mask[target_cntr] | |
| 547 | − & DEFERRED_ARM_MASK)); | |
| 476 | + return (df_v3_6_pmc_has_counter(adev, config, counter_idx) && | |
| 477 | + (adev->df_perfmon_config_assign_mask[counter_idx] | |
| 478 | + & DEFERRED_ARM_MASK)); | |
| 548 | 479 | |
| 549 | 480 | } |
| 550 | 481 | |
| 551 | 482 | /* release performance counter */ |
| 552 | 483 | static void df_v3_6_pmc_release_cntr(struct amdgpu_device *adev, |
| 553 | − uint64_t config) | |
| 484 | + uint64_t config, | |
| 485 | + int counter_idx) | |
| 554 | 486 | { |
| 555 | − int target_cntr = df_v3_6_pmc_config_2_cntr(adev, config); | |
| 556 | − | |
| 557 | − if (target_cntr >= 0) | |
| 558 | − adev->df_perfmon_config_assign_mask[target_cntr] = 0ULL; | |
| 487 | + if (df_v3_6_pmc_has_counter(adev, config, counter_idx)) | |
| 488 | + adev->df_perfmon_config_assign_mask[counter_idx] = 0ULL; | |
| 559 | 489 | } |
| 560 | 490 | |
| 561 | 491 | |
| 562 | 492 | static void df_v3_6_reset_perfmon_cntr(struct amdgpu_device *adev, |
| 563 | − uint64_t config) | |
| 493 | + uint64_t config, | |
| 494 | + int counter_idx) | |
| 564 | 495 | { |
| 565 | 496 | uint32_t lo_base_addr = 0, hi_base_addr = 0; |
| 566 | 497 | |
| 567 | − df_v3_6_pmc_get_read_settings(adev, config, &lo_base_addr, | |
| 498 | + df_v3_6_pmc_get_read_settings(adev, config, counter_idx, &lo_base_addr, | |
| 568 | 499 | &hi_base_addr); |
| 569 | 500 | |
| 570 | 501 | if ((lo_base_addr == 0) || (hi_base_addr == 0)) |
| @@ -573,21 +504,22 @@ static void df_v3_6_reset_perfmon_cntr(struct amdgpu_device *adev, · 2 unmodified lines | ||
| 573 | 504 | df_v3_6_perfmon_wreg(adev, lo_base_addr, 0, hi_base_addr, 0); |
| 574 | 505 | } |
| 575 | 506 | |
| 507 | +/* return available counter if is_add == 1 otherwise return error status. */ | |
| 576 | 508 | static int df_v3_6_pmc_start(struct amdgpu_device *adev, uint64_t config, |
| 577 | − int is_add) | |
| 509 | + int counter_idx, int is_add) | |
| 578 | 510 | { |
| 579 | 511 | uint32_t lo_base_addr, hi_base_addr, lo_val, hi_val; |
| 580 | 512 | int err = 0, ret = 0; |
| 581 | 513 | |
| 582 | 514 | switch (adev->asic_type) { |
| 583 | 515 | case CHIP_VEGA20: |
| 516 | + case CHIP_ARCTURUS: | |
| 584 | 517 | if (is_add) |
| 585 | 518 | return df_v3_6_pmc_add_cntr(adev, config); |
| 586 | 519 | |
| 587 | − df_v3_6_reset_perfmon_cntr(adev, config); | |
| 588 | − | |
| 589 | 520 | ret = df_v3_6_pmc_get_ctrl_settings(adev, |
| 590 | 521 | config, |
| 522 | + counter_idx, | |
| 591 | 523 | &lo_base_addr, |
| 592 | 524 | &hi_base_addr, |
| 593 | 525 | &lo_val, |
| @@ -604,7 +536,8 @@ static int df_v3_6_pmc_start(struct amdgpu_device *adev, uint64_t config, · 10 unmodified lines | ||
| 604 | 536 | hi_val); |
| 605 | 537 | |
| 606 | 538 | if (err) |
| 607 | − ret = df_v3_6_pmc_set_deferred(adev, config, true); | |
| 539 | + ret = df_v3_6_pmc_set_deferred(adev, config, | |
| 540 | + counter_idx, true); | |
| 608 | 541 | |
| 609 | 542 | break; |
| 610 | 543 | default: |
| @@ -615,15 +548,17 @@ static int df_v3_6_pmc_start(struct amdgpu_device *adev, uint64_t config, · 4 unmodified lines | ||
| 615 | 548 | } |
| 616 | 549 | |
| 617 | 550 | static int df_v3_6_pmc_stop(struct amdgpu_device *adev, uint64_t config, |
| 618 | − int is_remove) | |
| 551 | + int counter_idx, int is_remove) | |
| 619 | 552 | { |
| 620 | 553 | uint32_t lo_base_addr, hi_base_addr, lo_val, hi_val; |
| 621 | 554 | int ret = 0; |
| 622 | 555 | |
| 623 | 556 | switch (adev->asic_type) { |
| 624 | 557 | case CHIP_VEGA20: |
| 558 | + case CHIP_ARCTURUS: | |
| 625 | 559 | ret = df_v3_6_pmc_get_ctrl_settings(adev, |
| 626 | 560 | config, |
| 561 | + counter_idx, | |
| 627 | 562 | &lo_base_addr, |
| 628 | 563 | &hi_base_addr, |
| 629 | 564 | &lo_val, |
| @@ -635,8 +570,8 @@ static int df_v3_6_pmc_stop(struct amdgpu_device *adev, uint64_t config, · 5 unmodified lines | ||
| 635 | 570 | |
| 636 | 571 | |
| 637 | 572 | if (is_remove) { |
| 638 | − df_v3_6_reset_perfmon_cntr(adev, config); | |
| 639 | − df_v3_6_pmc_release_cntr(adev, config); | |
| 573 | + df_v3_6_reset_perfmon_cntr(adev, config, counter_idx); | |
| 574 | + df_v3_6_pmc_release_cntr(adev, config, counter_idx); | |
| 640 | 575 | } |
| 641 | 576 | |
| 642 | 577 | break; |
| @@ -649,6 +584,7 @@ static int df_v3_6_pmc_stop(struct amdgpu_device *adev, uint64_t config, · 6 unmodified lines | ||
| 649 | 584 | |
| 650 | 585 | static void df_v3_6_pmc_get_count(struct amdgpu_device *adev, |
| 651 | 586 | uint64_t config, |
| 587 | + int counter_idx, | |
| 652 | 588 | uint64_t *count) |
| 653 | 589 | { |
| 654 | 590 | uint32_t lo_base_addr = 0, hi_base_addr = 0, lo_val = 0, hi_val = 0; |
| @@ -656,14 +592,15 @@ static void df_v3_6_pmc_get_count(struct amdgpu_device *adev, · 1 unmodified line | ||
| 656 | 592 | |
| 657 | 593 | switch (adev->asic_type) { |
| 658 | 594 | case CHIP_VEGA20: |
| 659 | − df_v3_6_pmc_get_read_settings(adev, config, &lo_base_addr, | |
| 660 | − &hi_base_addr); | |
| 595 | + case CHIP_ARCTURUS: | |
| 596 | + df_v3_6_pmc_get_read_settings(adev, config, counter_idx, | |
| 597 | + &lo_base_addr, &hi_base_addr); | |
| 661 | 598 | |
| 662 | 599 | if ((lo_base_addr == 0) || (hi_base_addr == 0)) |
| 663 | 600 | return; |
| 664 | 601 | |
| 665 | 602 | /* rearm the counter or throw away count value on failure */ |
| 666 | − if (df_v3_6_pmc_is_deferred(adev, config)) { | |
| 603 | + if (df_v3_6_pmc_is_deferred(adev, config, counter_idx)) { | |
| 667 | 604 | int rearm_err = df_v3_6_perfmon_arm_with_status(adev, |
| 668 | 605 | lo_base_addr, lo_val, |
| 669 | 606 | hi_base_addr, hi_val); |
| @@ -671,7 +608,8 @@ static void df_v3_6_pmc_get_count(struct amdgpu_device *adev, · 1 unmodified line | ||
| 671 | 608 | if (rearm_err) |
| 672 | 609 | return; |
| 673 | 610 | |
| 674 | − df_v3_6_pmc_set_deferred(adev, config, false); | |
| 611 | + df_v3_6_pmc_set_deferred(adev, config, counter_idx, | |
| 612 | + false); | |
| 675 | 613 | } |
| 676 | 614 | |
| 677 | 615 | df_v3_6_perfmon_rreg(adev, lo_base_addr, &lo_val, |
| @@ -35,15 +35,6 @@ enum DF_V3_6_MGCG { · 34 unmodified lines | ||
| 35 | 35 | DF_V3_6_MGCG_ENABLE_63_CYCLE_DELAY = 15 |
| 36 | 36 | }; |
| 37 | 37 | |
| 38 | −/* Defined in global_features.h as FTI_PERFMON_VISIBLE */ | |
| 39 | −#define DF_V3_6_MAX_COUNTERS 4 | |
| 40 | − | |
| 41 | −/* get flags from df perfmon config */ | |
| 42 | −#define DF_V3_6_GET_EVENT(x) (x & 0xFFUL) | |
| 43 | −#define DF_V3_6_GET_INSTANCE(x) ((x >> 8) & 0xFFUL) | |
| 44 | −#define DF_V3_6_GET_UNITMASK(x) ((x >> 16) & 0xFFUL) | |
| 45 | −#define DF_V3_6_PERFMON_OVERFLOW 0xFFFFFFFFFFFFULL | |
| 46 | − | |
| 47 | 38 | extern const struct attribute_group *df_v3_6_attr_groups[]; |
| 48 | 39 | extern const struct amdgpu_df_funcs df_v3_6_funcs; |
| 49 | 40 | |
| @@ -0,0 +1,54 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2020 Advanced Micro Devices, Inc. | |
| 3 | + * | |
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a | |
| 5 | + * copy of this software and associated documentation files (the "Software"), | |
| 6 | + * to deal in the Software without restriction, including without limitation | |
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the | |
| 9 | + * Software is furnished to do so, subject to the following conditions: | |
| 10 | + * | |
| 11 | + * The above copyright notice and this permission notice shall be included in | |
| 12 | + * all copies or substantial portions of the Software. | |
| 13 | + * | |
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 17 | + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 18 | + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 19 | + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 20 | + * OTHER DEALINGS IN THE SOFTWARE. | |
| 21 | + * | |
| 22 | + */ | |
| 23 | +#include "amdgpu.h" | |
| 24 | +#include "nv.h" | |
| 25 | + | |
| 26 | +#include "soc15_common.h" | |
| 27 | +#include "soc15_hw_ip.h" | |
| 28 | +#include "dimgrey_cavefish_ip_offset.h" | |
| 29 | + | |
| 30 | +int dimgrey_cavefish_reg_base_init(struct amdgpu_device *adev) | |
| 31 | +{ | |
| 32 | + /* HW has more IP blocks, only initialize the block needed by driver */ | |
| 33 | + uint32_t i; | |
| 34 | + for (i = 0 ; i < MAX_INSTANCE ; ++i) { | |
| 35 | + adev->reg_offset[GC_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i])); | |
| 36 | + adev->reg_offset[HDP_HWIP][i] = (uint32_t *)(&(HDP_BASE.instance[i])); | |
| 37 | + adev->reg_offset[MMHUB_HWIP][i] = (uint32_t *)(&(MMHUB_BASE.instance[i])); | |
| 38 | + adev->reg_offset[ATHUB_HWIP][i] = (uint32_t *)(&(ATHUB_BASE.instance[i])); | |
| 39 | + adev->reg_offset[NBIO_HWIP][i] = (uint32_t *)(&(NBIO_BASE.instance[i])); | |
| 40 | + adev->reg_offset[MP0_HWIP][i] = (uint32_t *)(&(MP0_BASE.instance[i])); | |
| 41 | + adev->reg_offset[MP1_HWIP][i] = (uint32_t *)(&(MP1_BASE.instance[i])); | |
| 42 | + adev->reg_offset[VCN_HWIP][i] = (uint32_t *)(&(VCN0_BASE.instance[i])); | |
| 43 | + adev->reg_offset[DF_HWIP][i] = (uint32_t *)(&(DF_BASE.instance[i])); | |
| 44 | + adev->reg_offset[DCE_HWIP][i] = (uint32_t *)(&(DCN_BASE.instance[i])); | |
| 45 | + adev->reg_offset[OSSSYS_HWIP][i] = (uint32_t *)(&(OSSSYS_BASE.instance[i])); | |
| 46 | + adev->reg_offset[SDMA0_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i])); | |
| 47 | + adev->reg_offset[SDMA1_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i])); | |
| 48 | + adev->reg_offset[SDMA2_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i])); | |
| 49 | + adev->reg_offset[SDMA3_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i])); | |
| 50 | + adev->reg_offset[SMUIO_HWIP][i] = (uint32_t *)(&(SMUIO_BASE.instance[i])); | |
| 51 | + adev->reg_offset[THM_HWIP][i] = (uint32_t *)(&(THM_BASE.instance[i])); | |
| 52 | + } | |
| 53 | + return 0; | |
| 54 | +} | |
| @@ -99,6 +99,23 @@ · 98 unmodified lines | ||
| 99 | 99 | #define mmGCR_GENERAL_CNTL_Sienna_Cichlid 0x1580 |
| 100 | 100 | #define mmGCR_GENERAL_CNTL_Sienna_Cichlid_BASE_IDX 0 |
| 101 | 101 | |
| 102 | +#define mmSPI_CONFIG_CNTL_1_Vangogh 0x2441 | |
| 103 | +#define mmSPI_CONFIG_CNTL_1_Vangogh_BASE_IDX 1 | |
| 104 | +#define mmVGT_TF_MEMORY_BASE_HI_Vangogh 0x2261 | |
| 105 | +#define mmVGT_TF_MEMORY_BASE_HI_Vangogh_BASE_IDX 1 | |
| 106 | +#define mmVGT_HS_OFFCHIP_PARAM_Vangogh 0x224f | |
| 107 | +#define mmVGT_HS_OFFCHIP_PARAM_Vangogh_BASE_IDX 1 | |
| 108 | +#define mmVGT_TF_RING_SIZE_Vangogh 0x224e | |
| 109 | +#define mmVGT_TF_RING_SIZE_Vangogh_BASE_IDX 1 | |
| 110 | +#define mmVGT_GSVS_RING_SIZE_Vangogh 0x2241 | |
| 111 | +#define mmVGT_GSVS_RING_SIZE_Vangogh_BASE_IDX 1 | |
| 112 | +#define mmVGT_TF_MEMORY_BASE_Vangogh 0x2250 | |
| 113 | +#define mmVGT_TF_MEMORY_BASE_Vangogh_BASE_IDX 1 | |
| 114 | +#define mmVGT_ESGS_RING_SIZE_Vangogh 0x2240 | |
| 115 | +#define mmVGT_ESGS_RING_SIZE_Vangogh_BASE_IDX 1 | |
| 116 | +#define mmSPI_CONFIG_CNTL_Vangogh 0x2440 | |
| 117 | +#define mmSPI_CONFIG_CNTL_Vangogh_BASE_IDX 1 | |
| 118 | + | |
| 102 | 119 | #define mmCP_HYP_PFP_UCODE_ADDR 0x5814 |
| 103 | 120 | #define mmCP_HYP_PFP_UCODE_ADDR_BASE_IDX 1 |
| 104 | 121 | #define mmCP_HYP_PFP_UCODE_DATA 0x5815 |
| @@ -112,6 +129,13 @@ · 7 unmodified lines | ||
| 112 | 129 | #define mmCP_HYP_ME_UCODE_DATA 0x5817 |
| 113 | 130 | #define mmCP_HYP_ME_UCODE_DATA_BASE_IDX 1 |
| 114 | 131 | |
| 132 | +#define mmCPG_PSP_DEBUG 0x5c10 | |
| 133 | +#define mmCPG_PSP_DEBUG_BASE_IDX 1 | |
| 134 | +#define mmCPC_PSP_DEBUG 0x5c11 | |
| 135 | +#define mmCPC_PSP_DEBUG_BASE_IDX 1 | |
| 136 | +#define CPC_PSP_DEBUG__GPA_OVERRIDE_MASK 0x00000008L | |
| 137 | +#define CPG_PSP_DEBUG__GPA_OVERRIDE_MASK 0x00000008L | |
| 138 | + | |
| 115 | 139 | //CC_GC_SA_UNIT_DISABLE |
| 116 | 140 | #define mmCC_GC_SA_UNIT_DISABLE 0x0fe9 |
| 117 | 141 | #define mmCC_GC_SA_UNIT_DISABLE_BASE_IDX 0 |
| @@ -128,6 +152,9 @@ · 10 unmodified lines | ||
| 128 | 152 | #define PA_SC_ENHANCE_3__FORCE_PBB_WORKLOAD_MODE_TO_ZERO__SHIFT 0x3 |
| 129 | 153 | #define PA_SC_ENHANCE_3__FORCE_PBB_WORKLOAD_MODE_TO_ZERO_MASK 0x00000008L |
| 130 | 154 | |
| 155 | +#define mmCGTT_SPI_CS_CLK_CTRL 0x507c | |
| 156 | +#define mmCGTT_SPI_CS_CLK_CTRL_BASE_IDX 1 | |
| 157 | + | |
| 131 | 158 | MODULE_FIRMWARE("amdgpu/navi10_ce.bin"); |
| 132 | 159 | MODULE_FIRMWARE("amdgpu/navi10_pfp.bin"); |
| 133 | 160 | MODULE_FIRMWARE("amdgpu/navi10_me.bin"); |
| @@ -168,6 +195,20 @@ MODULE_FIRMWARE("amdgpu/navy_flounder_mec.bin"); · 34 unmodified lines | ||
| 168 | 195 | MODULE_FIRMWARE("amdgpu/navy_flounder_mec2.bin"); |
| 169 | 196 | MODULE_FIRMWARE("amdgpu/navy_flounder_rlc.bin"); |
| 170 | 197 | |
| 198 | +MODULE_FIRMWARE("amdgpu/vangogh_ce.bin"); | |
| 199 | +MODULE_FIRMWARE("amdgpu/vangogh_pfp.bin"); | |
| 200 | +MODULE_FIRMWARE("amdgpu/vangogh_me.bin"); | |
| 201 | +MODULE_FIRMWARE("amdgpu/vangogh_mec.bin"); | |
| 202 | +MODULE_FIRMWARE("amdgpu/vangogh_mec2.bin"); | |
| 203 | +MODULE_FIRMWARE("amdgpu/vangogh_rlc.bin"); | |
| 204 | + | |
| 205 | +MODULE_FIRMWARE("amdgpu/dimgrey_cavefish_ce.bin"); | |
| 206 | +MODULE_FIRMWARE("amdgpu/dimgrey_cavefish_pfp.bin"); | |
| 207 | +MODULE_FIRMWARE("amdgpu/dimgrey_cavefish_me.bin"); | |
| 208 | +MODULE_FIRMWARE("amdgpu/dimgrey_cavefish_mec.bin"); | |
| 209 | +MODULE_FIRMWARE("amdgpu/dimgrey_cavefish_mec2.bin"); | |
| 210 | +MODULE_FIRMWARE("amdgpu/dimgrey_cavefish_rlc.bin"); | |
| 211 | + | |
| 171 | 212 | static const struct soc15_reg_golden golden_settings_gc_10_1[] = |
| 172 | 213 | { |
| 173 | 214 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmCB_HW_CONTROL_4, 0xffffffff, 0x00400014), |
| @@ -3094,6 +3135,7 @@ static const struct soc15_reg_golden golden_settings_gc_rlc_spm_10_1_2_nv12[] = · 2920 unmodified lines | ||
| 3094 | 3135 | |
| 3095 | 3136 | static const struct soc15_reg_golden golden_settings_gc_10_3[] = |
| 3096 | 3137 | { |
| 3138 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SPI_CS_CLK_CTRL, 0x78000000, 0x78000100), | |
| 3097 | 3139 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SPI_PS_CLK_CTRL, 0xff7f0fff, 0x78000100), |
| 3098 | 3140 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SPI_RA0_CLK_CTRL, 0xff7f0fff, 0x30000100), |
| 3099 | 3141 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SPI_RA1_CLK_CTRL, 0xff7f0fff, 0x7e000100), |
| @@ -3177,7 +3219,74 @@ static const struct soc15_reg_golden golden_settings_gc_10_3_2[] = · 77 unmodified lines | ||
| 3177 | 3219 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER9_SELECT, 0xf0f001ff, 0x00000000), |
| 3178 | 3220 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmTA_CNTL_AUX, 0xfff7ffff, 0x01030000), |
| 3179 | 3221 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmUTCL1_CTRL, 0xffbfffff, 0x00a00000), |
| 3180 | − SOC15_REG_GOLDEN_VALUE(GC, 0, mmVGT_GS_MAX_WAVE_ID, 0x00000fff, 0x000003ff) | |
| 3222 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmVGT_GS_MAX_WAVE_ID, 0x00000fff, 0x000003ff), | |
| 3223 | + | |
| 3224 | + /* This is not in GDB yet. Don't remove it. It fixes a GPU hang on Navy Flounder. */ | |
| 3225 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmLDS_CONFIG, 0x00000020, 0x00000020), | |
| 3226 | +}; | |
| 3227 | + | |
| 3228 | +static const struct soc15_reg_golden golden_settings_gc_10_3_vangogh[] = | |
| 3229 | +{ | |
| 3230 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SPI_RA0_CLK_CTRL, 0xff7f0fff, 0x30000100), | |
| 3231 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SPI_RA1_CLK_CTRL, 0xff7f0fff, 0x7e000100), | |
| 3232 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmCH_PIPE_STEER, 0x000000ff, 0x000000e4), | |
| 3233 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_DEBUG3, 0xffffffff, 0x00000200), | |
| 3234 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_DEBUG4, 0xffffffff, 0x00800000), | |
| 3235 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_EXCEPTION_CONTROL, 0x7fff0f1f, 0x00b80000), | |
| 3236 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmGB_ADDR_CONFIG, 0x0c1807ff, 0x00000142), | |
| 3237 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmGCR_GENERAL_CNTL, 0x1ff1ffff, 0x00000500), | |
| 3238 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL1_PIPE_STEER, 0x000000ff, 0x000000e4), | |
| 3239 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2_PIPE_STEER_0, 0x77777777, 0x32103210), | |
| 3240 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2_PIPE_STEER_1, 0x77777777, 0x32103210), | |
| 3241 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2A_ADDR_MATCH_MASK, 0xffffffff, 0xfffffff3), | |
| 3242 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2C_ADDR_MATCH_MASK, 0xffffffff, 0xfffffff3), | |
| 3243 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2C_CM_CTRL1, 0xff8fff0f, 0x580f1008), | |
| 3244 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2C_CTRL3, 0xf7ffffff, 0x00f80988), | |
| 3245 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_CL_ENHANCE, 0xf17fffff, 0x01200007), | |
| 3246 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_BINNER_TIMEOUT_COUNTER, 0xffffffff, 0x00000800), | |
| 3247 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_ENHANCE_2, 0xffffffbf, 0x00000020), | |
| 3248 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmSPI_CONFIG_CNTL_1_Vangogh, 0xffffffff, 0x00070103), | |
| 3249 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQG_CONFIG, 0x000017ff, 0x00001000), | |
| 3250 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmTA_CNTL_AUX, 0xfff7ffff, 0x01030000), | |
| 3251 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmUTCL1_CTRL, 0xffffffff, 0x00400000), | |
| 3252 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmVGT_GS_MAX_WAVE_ID, 0x00000fff, 0x000000ff), | |
| 3253 | +}; | |
| 3254 | + | |
| 3255 | +static const struct soc15_reg_golden golden_settings_gc_10_3_4[] = | |
| 3256 | +{ | |
| 3257 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SPI_RA0_CLK_CTRL, 0x30000000, 0x30000100), | |
| 3258 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SPI_RA1_CLK_CTRL, 0x7e000000, 0x7e000100), | |
| 3259 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmCPF_GCR_CNTL, 0x0007ffff, 0x0000c000), | |
| 3260 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_DEBUG3, 0x00000280, 0x00000280), | |
| 3261 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_DEBUG4, 0x07800000, 0x00800000), | |
| 3262 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmGCR_GENERAL_CNTL, 0x00001d00, 0x00000500), | |
| 3263 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmGE_PC_CNTL, 0x003c0000, 0x00280400), | |
| 3264 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2A_ADDR_MATCH_MASK, 0xffffffff, 0xffffffcf), | |
| 3265 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2C_ADDR_MATCH_MASK, 0xffffffff, 0xffffffcf), | |
| 3266 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2C_CM_CTRL1, 0x40000000, 0x580f1008), | |
| 3267 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2C_CTRL3, 0x00040000, 0x00f80988), | |
| 3268 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_CL_ENHANCE, 0x01000000, 0x01200007), | |
| 3269 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_BINNER_TIMEOUT_COUNTER, 0xffffffff, 0x00000800), | |
| 3270 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_ENHANCE_2, 0x00000800, 0x00000820), | |
| 3271 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_CONFIG, 0x0000001f, 0x00180070), | |
| 3272 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER0_SELECT, 0xf0f001ff, 0x00000000), | |
| 3273 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER1_SELECT, 0xf0f001ff, 0x00000000), | |
| 3274 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER10_SELECT, 0xf0f001ff, 0x00000000), | |
| 3275 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER11_SELECT, 0xf0f001ff, 0x00000000), | |
| 3276 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER12_SELECT, 0xf0f001ff, 0x00000000), | |
| 3277 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER13_SELECT, 0xf0f001ff, 0x00000000), | |
| 3278 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER14_SELECT, 0xf0f001ff, 0x00000000), | |
| 3279 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER15_SELECT, 0xf0f001ff, 0x00000000), | |
| 3280 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER2_SELECT, 0xf0f001ff, 0x00000000), | |
| 3281 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER3_SELECT, 0xf0f001ff, 0x00000000), | |
| 3282 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER4_SELECT, 0xf0f001ff, 0x00000000), | |
| 3283 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER5_SELECT, 0xf0f001ff, 0x00000000), | |
| 3284 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER6_SELECT, 0xf0f001ff, 0x00000000), | |
| 3285 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER7_SELECT, 0xf0f001ff, 0x00000000), | |
| 3286 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER8_SELECT, 0xf0f001ff, 0x00000000), | |
| 3287 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER9_SELECT, 0xf0f001ff, 0x00000000), | |
| 3288 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmTA_CNTL_AUX, 0x01030000, 0x01030000), | |
| 3289 | + SOC15_REG_GOLDEN_VALUE(GC, 0, mmUTCL1_CTRL, 0x03a00000, 0x00a00000) | |
| 3181 | 3290 | }; |
| 3182 | 3291 | |
| 3183 | 3292 | #define DEFAULT_SH_MEM_CONFIG \ |
| @@ -3192,7 +3301,7 @@ static void gfx_v10_0_set_irq_funcs(struct amdgpu_device *adev); · 8 unmodified lines | ||
| 3192 | 3301 | static void gfx_v10_0_set_gds_init(struct amdgpu_device *adev); |
| 3193 | 3302 | static void gfx_v10_0_set_rlc_funcs(struct amdgpu_device *adev); |
| 3194 | 3303 | static int gfx_v10_0_get_cu_info(struct amdgpu_device *adev, |
| 3195 | − struct amdgpu_cu_info *cu_info); | |
| 3304 | + struct amdgpu_cu_info *cu_info); | |
| 3196 | 3305 | static uint64_t gfx_v10_0_get_gpu_clock_counter(struct amdgpu_device *adev); |
| 3197 | 3306 | static void gfx_v10_0_select_se_sh(struct amdgpu_device *adev, u32 se_num, |
| 3198 | 3307 | u32 sh_num, u32 instance); |
| @@ -3389,7 +3498,16 @@ static void gfx_v10_0_init_golden_registers(struct amdgpu_device *adev) · 190 unmodified lines | ||
| 3389 | 3498 | golden_settings_gc_10_3_2, |
| 3390 | 3499 | (const u32)ARRAY_SIZE(golden_settings_gc_10_3_2)); |
| 3391 | 3500 | break; |
| 3392 | − | |
| 3501 | + case CHIP_VANGOGH: | |
| 3502 | + soc15_program_register_sequence(adev, | |
| 3503 | + golden_settings_gc_10_3_vangogh, | |
| 3504 | + (const u32)ARRAY_SIZE(golden_settings_gc_10_3_vangogh)); | |
| 3505 | + break; | |
| 3506 | + case CHIP_DIMGREY_CAVEFISH: | |
| 3507 | + soc15_program_register_sequence(adev, | |
| 3508 | + golden_settings_gc_10_3_4, | |
| 3509 | + (const u32)ARRAY_SIZE(golden_settings_gc_10_3_4)); | |
| 3510 | + break; | |
| 3393 | 3511 | default: |
| 3394 | 3512 | break; |
| 3395 | 3513 | } |
| @@ -3573,6 +3691,8 @@ static void gfx_v10_0_check_fw_write_wait(struct amdgpu_device *adev) · 177 unmodified lines | ||
| 3573 | 3691 | break; |
| 3574 | 3692 | case CHIP_SIENNA_CICHLID: |
| 3575 | 3693 | case CHIP_NAVY_FLOUNDER: |
| 3694 | + case CHIP_VANGOGH: | |
| 3695 | + case CHIP_DIMGREY_CAVEFISH: | |
| 3576 | 3696 | adev->gfx.cp_fw_write_wait = true; |
| 3577 | 3697 | break; |
| 3578 | 3698 | default: |
| @@ -3640,7 +3760,7 @@ static void gfx_v10_0_check_gfxoff_flag(struct amdgpu_device *adev) · 61 unmodified lines | ||
| 3640 | 3760 | if (!gfx_v10_0_navi10_gfxoff_should_enable(adev)) |
| 3641 | 3761 | adev->pm.pp_feature &= ~PP_GFXOFF_MASK; |
| 3642 | 3762 | break; |
| 3643 | − case CHIP_NAVY_FLOUNDER: | |
| 3763 | + case CHIP_VANGOGH: | |
| 3644 | 3764 | adev->pm.pp_feature &= ~PP_GFXOFF_MASK; |
| 3645 | 3765 | break; |
| 3646 | 3766 | default: |
| @@ -3685,6 +3805,12 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev) · 38 unmodified lines | ||
| 3685 | 3805 | case CHIP_NAVY_FLOUNDER: |
| 3686 | 3806 | chip_name = "navy_flounder"; |
| 3687 | 3807 | break; |
| 3808 | + case CHIP_VANGOGH: | |
| 3809 | + chip_name = "vangogh"; | |
| 3810 | + break; | |
| 3811 | + case CHIP_DIMGREY_CAVEFISH: | |
| 3812 | + chip_name = "dimgrey_cavefish"; | |
| 3813 | + break; | |
| 3688 | 3814 | default: |
| 3689 | 3815 | BUG(); |
| 3690 | 3816 | } |
| @@ -4200,11 +4326,26 @@ static void gfx_v10_0_read_wave_vgprs(struct amdgpu_device *adev, uint32_t simd, · 509 unmodified lines | ||
| 4200 | 4326 | } |
| 4201 | 4327 | |
| 4202 | 4328 | static void gfx_v10_0_select_me_pipe_q(struct amdgpu_device *adev, |
| 4203 | − u32 me, u32 pipe, u32 q, u32 vm) | |
| 4204 | − { | |
| 4205 | − nv_grbm_select(adev, me, pipe, q, vm); | |
| 4206 | − } | |
| 4329 | + u32 me, u32 pipe, u32 q, u32 vm) | |
| 4330 | +{ | |
| 4331 | + nv_grbm_select(adev, me, pipe, q, vm); | |
| 4332 | +} | |
| 4207 | 4333 | |
| 4334 | +static void gfx_v10_0_update_perfmon_mgcg(struct amdgpu_device *adev, | |
| 4335 | + bool enable) | |
| 4336 | +{ | |
| 4337 | + uint32_t data, def; | |
| 4338 | + | |
| 4339 | + data = def = RREG32_SOC15(GC, 0, mmRLC_PERFMON_CLK_CNTL); | |
| 4340 | + | |
| 4341 | + if (enable) | |
| 4342 | + data |= RLC_PERFMON_CLK_CNTL__PERFMON_CLOCK_STATE_MASK; | |
| 4343 | + else | |
| 4344 | + data &= ~RLC_PERFMON_CLK_CNTL__PERFMON_CLOCK_STATE_MASK; | |
| 4345 | + | |
| 4346 | + if (data != def) | |
| 4347 | + WREG32_SOC15(GC, 0, mmRLC_PERFMON_CLK_CNTL, data); | |
| 4348 | +} | |
| 4208 | 4349 | |
| 4209 | 4350 | static const struct amdgpu_gfx_funcs gfx_v10_0_gfx_funcs = { |
| 4210 | 4351 | .get_gpu_clock_counter = &gfx_v10_0_get_gpu_clock_counter, |
| @@ -4214,6 +4355,7 @@ static const struct amdgpu_gfx_funcs gfx_v10_0_gfx_funcs = { · 3 unmodified lines | ||
| 4214 | 4355 | .read_wave_vgprs = &gfx_v10_0_read_wave_vgprs, |
| 4215 | 4356 | .select_me_pipe_q = &gfx_v10_0_select_me_pipe_q, |
| 4216 | 4357 | .init_spm_golden = &gfx_v10_0_init_spm_golden_registers, |
| 4358 | + .update_perfmon_mgcg = &gfx_v10_0_update_perfmon_mgcg, | |
| 4217 | 4359 | }; |
| 4218 | 4360 | |
| 4219 | 4361 | static void gfx_v10_0_gpu_early_init(struct amdgpu_device *adev) |
| @@ -4235,6 +4377,8 @@ static void gfx_v10_0_gpu_early_init(struct amdgpu_device *adev) · 15 unmodified lines | ||
| 4235 | 4377 | break; |
| 4236 | 4378 | case CHIP_SIENNA_CICHLID: |
| 4237 | 4379 | case CHIP_NAVY_FLOUNDER: |
| 4380 | + case CHIP_VANGOGH: | |
| 4381 | + case CHIP_DIMGREY_CAVEFISH: | |
| 4238 | 4382 | adev->gfx.config.max_hw_contexts = 8; |
| 4239 | 4383 | adev->gfx.config.sc_prim_fifo_size_frontend = 0x20; |
| 4240 | 4384 | adev->gfx.config.sc_prim_fifo_size_backend = 0x100; |
| @@ -4358,6 +4502,8 @@ static int gfx_v10_0_sw_init(void *handle) · 117 unmodified lines | ||
| 4358 | 4502 | break; |
| 4359 | 4503 | case CHIP_SIENNA_CICHLID: |
| 4360 | 4504 | case CHIP_NAVY_FLOUNDER: |
| 4505 | + case CHIP_VANGOGH: | |
| 4506 | + case CHIP_DIMGREY_CAVEFISH: | |
| 4361 | 4507 | adev->gfx.me.num_me = 1; |
| 4362 | 4508 | adev->gfx.me.num_pipe_per_me = 1; |
| 4363 | 4509 | adev->gfx.me.num_queue_per_pipe = 1; |
| @@ -4617,8 +4763,7 @@ static u32 gfx_v10_0_init_pa_sc_tile_steering_override(struct amdgpu_device *ade · 253 unmodified lines | ||
| 4617 | 4763 | |
| 4618 | 4764 | /* for ASICs that integrates GFX v10.3 |
| 4619 | 4765 | * pa_sc_tile_steering_override should be set to 0 */ |
| 4620 | − if (adev->asic_type == CHIP_SIENNA_CICHLID || | |
| 4621 | − adev->asic_type == CHIP_NAVY_FLOUNDER) | |
| 4766 | + if (adev->asic_type >= CHIP_SIENNA_CICHLID) | |
| 4622 | 4767 | return 0; |
| 4623 | 4768 | |
| 4624 | 4769 | /* init num_sc */ |
| @@ -5855,6 +6000,8 @@ static void gfx_v10_0_cp_gfx_set_doorbell(struct amdgpu_device *adev, · 1230 unmodified lines | ||
| 5855 | 6000 | switch (adev->asic_type) { |
| 5856 | 6001 | case CHIP_SIENNA_CICHLID: |
| 5857 | 6002 | case CHIP_NAVY_FLOUNDER: |
| 6003 | + case CHIP_VANGOGH: | |
| 6004 | + case CHIP_DIMGREY_CAVEFISH: | |
| 5858 | 6005 | tmp = REG_SET_FIELD(0, CP_RB_DOORBELL_RANGE_LOWER, |
| 5859 | 6006 | DOORBELL_RANGE_LOWER_Sienna_Cichlid, ring->doorbell_index); |
| 5860 | 6007 | WREG32_SOC15(GC, 0, mmCP_RB_DOORBELL_RANGE_LOWER, tmp); |
| @@ -5988,6 +6135,8 @@ static void gfx_v10_0_cp_compute_enable(struct amdgpu_device *adev, bool enable) · 127 unmodified lines | ||
| 5988 | 6135 | switch (adev->asic_type) { |
| 5989 | 6136 | case CHIP_SIENNA_CICHLID: |
| 5990 | 6137 | case CHIP_NAVY_FLOUNDER: |
| 6138 | + case CHIP_VANGOGH: | |
| 6139 | + case CHIP_DIMGREY_CAVEFISH: | |
| 5991 | 6140 | WREG32_SOC15(GC, 0, mmCP_MEC_CNTL_Sienna_Cichlid, 0); |
| 5992 | 6141 | break; |
| 5993 | 6142 | default: |
| @@ -5998,6 +6147,8 @@ static void gfx_v10_0_cp_compute_enable(struct amdgpu_device *adev, bool enable) · 4 unmodified lines | ||
| 5998 | 6147 | switch (adev->asic_type) { |
| 5999 | 6148 | case CHIP_SIENNA_CICHLID: |
| 6000 | 6149 | case CHIP_NAVY_FLOUNDER: |
| 6150 | + case CHIP_VANGOGH: | |
| 6151 | + case CHIP_DIMGREY_CAVEFISH: | |
| 6001 | 6152 | WREG32_SOC15(GC, 0, mmCP_MEC_CNTL_Sienna_Cichlid, |
| 6002 | 6153 | (CP_MEC_CNTL__MEC_ME1_HALT_MASK | |
| 6003 | 6154 | CP_MEC_CNTL__MEC_ME2_HALT_MASK)); |
| @@ -6092,6 +6243,8 @@ static void gfx_v10_0_kiq_setting(struct amdgpu_ring *ring) · 88 unmodified lines | ||
| 6092 | 6243 | switch (adev->asic_type) { |
| 6093 | 6244 | case CHIP_SIENNA_CICHLID: |
| 6094 | 6245 | case CHIP_NAVY_FLOUNDER: |
| 6246 | + case CHIP_VANGOGH: | |
| 6247 | + case CHIP_DIMGREY_CAVEFISH: | |
| 6095 | 6248 | tmp = RREG32_SOC15(GC, 0, mmRLC_CP_SCHEDULERS_Sienna_Cichlid); |
| 6096 | 6249 | tmp &= 0xffffff00; |
| 6097 | 6250 | tmp |= (ring->me << 5) | (ring->pipe << 3) | (ring->queue); |
| @@ -6800,6 +6953,7 @@ static bool gfx_v10_0_check_grbm_cam_remapping(struct amdgpu_device *adev) · 702 unmodified lines | ||
| 6800 | 6953 | switch (adev->asic_type) { |
| 6801 | 6954 | case CHIP_SIENNA_CICHLID: |
| 6802 | 6955 | case CHIP_NAVY_FLOUNDER: |
| 6956 | + case CHIP_DIMGREY_CAVEFISH: | |
| 6803 | 6957 | data = RREG32_SOC15(GC, 0, mmVGT_ESGS_RING_SIZE_Sienna_Cichlid); |
| 6804 | 6958 | WREG32_SOC15(GC, 0, mmVGT_ESGS_RING_SIZE_Sienna_Cichlid, 0); |
| 6805 | 6959 | WREG32_SOC15(GC, 0, mmVGT_ESGS_RING_SIZE_UMD, pattern); |
| @@ -6812,6 +6966,8 @@ static bool gfx_v10_0_check_grbm_cam_remapping(struct amdgpu_device *adev) · 6 unmodified lines | ||
| 6812 | 6966 | return false; |
| 6813 | 6967 | } |
| 6814 | 6968 | break; |
| 6969 | + case CHIP_VANGOGH: | |
| 6970 | + return true; | |
| 6815 | 6971 | default: |
| 6816 | 6972 | data = RREG32_SOC15(GC, 0, mmVGT_ESGS_RING_SIZE); |
| 6817 | 6973 | WREG32_SOC15(GC, 0, mmVGT_ESGS_RING_SIZE, 0); |
| @@ -6839,6 +6995,8 @@ static void gfx_v10_0_setup_grbm_cam_remapping(struct amdgpu_device *adev) · 21 unmodified lines | ||
| 6839 | 6995 | switch (adev->asic_type) { |
| 6840 | 6996 | case CHIP_SIENNA_CICHLID: |
| 6841 | 6997 | case CHIP_NAVY_FLOUNDER: |
| 6998 | + case CHIP_VANGOGH: | |
| 6999 | + case CHIP_DIMGREY_CAVEFISH: | |
| 6842 | 7000 | /* mmVGT_TF_RING_SIZE_UMD -> mmVGT_TF_RING_SIZE */ |
| 6843 | 7001 | data = (SOC15_REG_OFFSET(GC, 0, mmVGT_TF_RING_SIZE_UMD) << |
| 6844 | 7002 | GRBM_CAM_DATA__CAM_ADDR__SHIFT) | |
| @@ -6954,6 +7112,18 @@ static void gfx_v10_0_setup_grbm_cam_remapping(struct amdgpu_device *adev) · 109 unmodified lines | ||
| 6954 | 7112 | WREG32_SOC15(GC, 0, mmGRBM_CAM_DATA, data); |
| 6955 | 7113 | } |
| 6956 | 7114 | |
| 7115 | +static void gfx_v10_0_disable_gpa_mode(struct amdgpu_device *adev) | |
| 7116 | +{ | |
| 7117 | + uint32_t data; | |
| 7118 | + data = RREG32_SOC15(GC, 0, mmCPC_PSP_DEBUG); | |
| 7119 | + data |= CPC_PSP_DEBUG__GPA_OVERRIDE_MASK; | |
| 7120 | + WREG32_SOC15(GC, 0, mmCPC_PSP_DEBUG, data); | |
| 7121 | + | |
| 7122 | + data = RREG32_SOC15(GC, 0, mmCPG_PSP_DEBUG); | |
| 7123 | + data |= CPG_PSP_DEBUG__GPA_OVERRIDE_MASK; | |
| 7124 | + WREG32_SOC15(GC, 0, mmCPG_PSP_DEBUG, data); | |
| 7125 | +} | |
| 7126 | + | |
| 6957 | 7127 | static int gfx_v10_0_hw_init(void *handle) |
| 6958 | 7128 | { |
| 6959 | 7129 | int r; |
| @@ -6968,7 +7138,7 @@ static int gfx_v10_0_hw_init(void *handle) · 8 unmodified lines | ||
| 6968 | 7138 | * loaded firstly, so in direct type, it has to load smc ucode |
| 6969 | 7139 | * here before rlc. |
| 6970 | 7140 | */ |
| 6971 | − if (adev->smu.ppt_funcs != NULL) { | |
| 7141 | + if (adev->smu.ppt_funcs != NULL && !(adev->flags & AMD_IS_APU)) { | |
| 6972 | 7142 | r = smu_load_microcode(&adev->smu); |
| 6973 | 7143 | if (r) |
| 6974 | 7144 | return r; |
| @@ -6979,6 +7149,7 @@ static int gfx_v10_0_hw_init(void *handle) · 4 unmodified lines | ||
| 6979 | 7149 | return r; |
| 6980 | 7150 | } |
| 6981 | 7151 | } |
| 7152 | + gfx_v10_0_disable_gpa_mode(adev); | |
| 6982 | 7153 | } |
| 6983 | 7154 | |
| 6984 | 7155 | /* if GRBM CAM not remapped, set up the remapping */ |
| @@ -7136,6 +7307,8 @@ static int gfx_v10_0_soft_reset(void *handle) · 151 unmodified lines | ||
| 7136 | 7307 | switch (adev->asic_type) { |
| 7137 | 7308 | case CHIP_SIENNA_CICHLID: |
| 7138 | 7309 | case CHIP_NAVY_FLOUNDER: |
| 7310 | + case CHIP_VANGOGH: | |
| 7311 | + case CHIP_DIMGREY_CAVEFISH: | |
| 7139 | 7312 | if (REG_GET_FIELD(tmp, GRBM_STATUS2, RLC_BUSY_Sienna_Cichlid)) |
| 7140 | 7313 | grbm_soft_reset = REG_SET_FIELD(grbm_soft_reset, |
| 7141 | 7314 | GRBM_SOFT_RESET, |
| @@ -7235,13 +7408,16 @@ static int gfx_v10_0_early_init(void *handle) · 93 unmodified lines | ||
| 7235 | 7408 | break; |
| 7236 | 7409 | case CHIP_SIENNA_CICHLID: |
| 7237 | 7410 | case CHIP_NAVY_FLOUNDER: |
| 7411 | + case CHIP_VANGOGH: | |
| 7412 | + case CHIP_DIMGREY_CAVEFISH: | |
| 7238 | 7413 | adev->gfx.num_gfx_rings = GFX10_NUM_GFX_RINGS_Sienna_Cichlid; |
| 7239 | 7414 | break; |
| 7240 | 7415 | default: |
| 7241 | 7416 | break; |
| 7242 | 7417 | } |
| 7243 | 7418 | |
| 7244 | − adev->gfx.num_compute_rings = amdgpu_num_kcq; | |
| 7419 | + adev->gfx.num_compute_rings = min(amdgpu_gfx_get_num_kcq(adev), | |
| 7420 | + AMDGPU_MAX_COMPUTE_RINGS); | |
| 7245 | 7421 | |
| 7246 | 7422 | gfx_v10_0_set_kiq_pm4_funcs(adev); |
| 7247 | 7423 | gfx_v10_0_set_ring_funcs(adev); |
| @@ -7288,6 +7464,8 @@ static void gfx_v10_0_set_safe_mode(struct amdgpu_device *adev) · 40 unmodified lines | ||
| 7288 | 7464 | switch (adev->asic_type) { |
| 7289 | 7465 | case CHIP_SIENNA_CICHLID: |
| 7290 | 7466 | case CHIP_NAVY_FLOUNDER: |
| 7467 | + case CHIP_VANGOGH: | |
| 7468 | + case CHIP_DIMGREY_CAVEFISH: | |
| 7291 | 7469 | WREG32_SOC15(GC, 0, mmRLC_SAFE_MODE_Sienna_Cichlid, data); |
| 7292 | 7470 | |
| 7293 | 7471 | /* wait for RLC_SAFE_MODE */ |
| @@ -7320,6 +7498,8 @@ static void gfx_v10_0_unset_safe_mode(struct amdgpu_device *adev) · 26 unmodified lines | ||
| 7320 | 7498 | switch (adev->asic_type) { |
| 7321 | 7499 | case CHIP_SIENNA_CICHLID: |
| 7322 | 7500 | case CHIP_NAVY_FLOUNDER: |
| 7501 | + case CHIP_VANGOGH: | |
| 7502 | + case CHIP_DIMGREY_CAVEFISH: | |
| 7323 | 7503 | WREG32_SOC15(GC, 0, mmRLC_SAFE_MODE_Sienna_Cichlid, data); |
| 7324 | 7504 | break; |
| 7325 | 7505 | default: |
| @@ -7344,6 +7524,7 @@ static void gfx_v10_0_update_medium_grain_clock_gating(struct amdgpu_device *ade · 18 unmodified lines | ||
| 7344 | 7524 | /* 1 - RLC_CGTT_MGCG_OVERRIDE */ |
| 7345 | 7525 | def = data = RREG32_SOC15(GC, 0, mmRLC_CGTT_MGCG_OVERRIDE); |
| 7346 | 7526 | data &= ~(RLC_CGTT_MGCG_OVERRIDE__GRBM_CGTT_SCLK_OVERRIDE_MASK | |
| 7527 | + RLC_CGTT_MGCG_OVERRIDE__RLC_CGTT_SCLK_OVERRIDE_MASK | | |
| 7347 | 7528 | RLC_CGTT_MGCG_OVERRIDE__GFXIP_MGCG_OVERRIDE_MASK | |
| 7348 | 7529 | RLC_CGTT_MGCG_OVERRIDE__GFXIP_MGLS_OVERRIDE_MASK | |
| 7349 | 7530 | RLC_CGTT_MGCG_OVERRIDE__ENABLE_CGTS_LEGACY_MASK); |
| @@ -7480,12 +7661,50 @@ static void gfx_v10_0_update_coarse_grain_clock_gating(struct amdgpu_device *ade · 130 unmodified lines | ||
| 7480 | 7661 | } |
| 7481 | 7662 | } |
| 7482 | 7663 | |
| 7664 | +static void gfx_v10_0_update_fine_grain_clock_gating(struct amdgpu_device *adev, | |
| 7665 | + bool enable) | |
| 7666 | +{ | |
| 7667 | + uint32_t def, data; | |
| 7668 | + | |
| 7669 | + if (enable && (adev->cg_flags & AMD_CG_SUPPORT_GFX_FGCG)) { | |
| 7670 | + def = data = RREG32_SOC15(GC, 0, mmRLC_CGTT_MGCG_OVERRIDE); | |
| 7671 | + /* unset FGCG override */ | |
| 7672 | + data &= ~RLC_CGTT_MGCG_OVERRIDE__GFXIP_FGCG_OVERRIDE_MASK; | |
| 7673 | + /* update FGCG override bits */ | |
| 7674 | + if (def != data) | |
| 7675 | + WREG32_SOC15(GC, 0, mmRLC_CGTT_MGCG_OVERRIDE, data); | |
| 7676 | + | |
| 7677 | + def = data = RREG32_SOC15(GC, 0, mmRLC_CLK_CNTL); | |
| 7678 | + /* unset RLC SRAM CLK GATER override */ | |
| 7679 | + data &= ~RLC_CLK_CNTL__RLC_SRAM_CLK_GATER_OVERRIDE_MASK; | |
| 7680 | + /* update RLC SRAM CLK GATER override bits */ | |
| 7681 | + if (def != data) | |
| 7682 | + WREG32_SOC15(GC, 0, mmRLC_CLK_CNTL, data); | |
| 7683 | + } else { | |
| 7684 | + def = data = RREG32_SOC15(GC, 0, mmRLC_CGTT_MGCG_OVERRIDE); | |
| 7685 | + /* reset FGCG bits */ | |
| 7686 | + data |= RLC_CGTT_MGCG_OVERRIDE__GFXIP_FGCG_OVERRIDE_MASK; | |
| 7687 | + /* disable FGCG*/ | |
| 7688 | + if (def != data) | |
| 7689 | + WREG32_SOC15(GC, 0, mmRLC_CGTT_MGCG_OVERRIDE, data); | |
| 7690 | + | |
| 7691 | + def = data = RREG32_SOC15(GC, 0, mmRLC_CLK_CNTL); | |
| 7692 | + /* reset RLC SRAM CLK GATER bits */ | |
| 7693 | + data |= RLC_CLK_CNTL__RLC_SRAM_CLK_GATER_OVERRIDE_MASK; | |
| 7694 | + /* disable RLC SRAM CLK*/ | |
| 7695 | + if (def != data) | |
| 7696 | + WREG32_SOC15(GC, 0, mmRLC_CLK_CNTL, data); | |
| 7697 | + } | |
| 7698 | +} | |
| 7699 | + | |
| 7483 | 7700 | static int gfx_v10_0_update_gfx_clock_gating(struct amdgpu_device *adev, |
| 7484 | 7701 | bool enable) |
| 7485 | 7702 | { |
| 7486 | 7703 | amdgpu_gfx_rlc_enter_safe_mode(adev); |
| 7487 | 7704 | |
| 7488 | 7705 | if (enable) { |
| 7706 | + /* enable FGCG firstly*/ | |
| 7707 | + gfx_v10_0_update_fine_grain_clock_gating(adev, enable); | |
| 7489 | 7708 | /* CGCG/CGLS should be enabled after MGCG/MGLS |
| 7490 | 7709 | * === MGCG + MGLS === |
| 7491 | 7710 | */ |
| @@ -7503,6 +7722,8 @@ static int gfx_v10_0_update_gfx_clock_gating(struct amdgpu_device *adev, · 11 unmodified lines | ||
| 7503 | 7722 | gfx_v10_0_update_3d_clock_gating(adev, enable); |
| 7504 | 7723 | /* === MGCG + MGLS === */ |
| 7505 | 7724 | gfx_v10_0_update_medium_grain_clock_gating(adev, enable); |
| 7725 | + /* disable fgcg at last*/ | |
| 7726 | + gfx_v10_0_update_fine_grain_clock_gating(adev, enable); | |
| 7506 | 7727 | } |
| 7507 | 7728 | |
| 7508 | 7729 | if (adev->cg_flags & |
| @@ -7564,6 +7785,27 @@ static bool gfx_v10_0_is_rlcg_access_range(struct amdgpu_device *adev, u32 offse · 55 unmodified lines | ||
| 7564 | 7785 | return gfx_v10_0_check_rlcg_range(adev, offset, NULL, 0); |
| 7565 | 7786 | } |
| 7566 | 7787 | |
| 7788 | +static void gfx_v10_cntl_power_gating(struct amdgpu_device *adev, bool enable) | |
| 7789 | +{ | |
| 7790 | + u32 data = RREG32_SOC15(GC, 0, mmRLC_PG_CNTL); | |
| 7791 | + | |
| 7792 | + if (enable && (adev->pg_flags & AMD_PG_SUPPORT_GFX_PG)) | |
| 7793 | + data |= RLC_PG_CNTL__GFX_POWER_GATING_ENABLE_MASK; | |
| 7794 | + else | |
| 7795 | + data &= ~RLC_PG_CNTL__GFX_POWER_GATING_ENABLE_MASK; | |
| 7796 | + | |
| 7797 | + WREG32_SOC15(GC, 0, mmRLC_PG_CNTL, data); | |
| 7798 | +} | |
| 7799 | + | |
| 7800 | +static void gfx_v10_cntl_pg(struct amdgpu_device *adev, bool enable) | |
| 7801 | +{ | |
| 7802 | + amdgpu_gfx_rlc_enter_safe_mode(adev); | |
| 7803 | + | |
| 7804 | + gfx_v10_cntl_power_gating(adev, enable); | |
| 7805 | + | |
| 7806 | + amdgpu_gfx_rlc_exit_safe_mode(adev); | |
| 7807 | +} | |
| 7808 | + | |
| 7567 | 7809 | static const struct amdgpu_rlc_funcs gfx_v10_0_rlc_funcs = { |
| 7568 | 7810 | .is_rlc_enabled = gfx_v10_0_is_rlc_enabled, |
| 7569 | 7811 | .set_safe_mode = gfx_v10_0_set_safe_mode, |
| @@ -7609,8 +7851,12 @@ static int gfx_v10_0_set_powergating_state(void *handle, · 39 unmodified lines | ||
| 7609 | 7851 | case CHIP_NAVI12: |
| 7610 | 7852 | case CHIP_SIENNA_CICHLID: |
| 7611 | 7853 | case CHIP_NAVY_FLOUNDER: |
| 7854 | + case CHIP_DIMGREY_CAVEFISH: | |
| 7612 | 7855 | amdgpu_gfx_off_ctrl(adev, enable); |
| 7613 | 7856 | break; |
| 7857 | + case CHIP_VANGOGH: | |
| 7858 | + gfx_v10_cntl_pg(adev, enable); | |
| 7859 | + break; | |
| 7614 | 7860 | default: |
| 7615 | 7861 | break; |
| 7616 | 7862 | } |
| @@ -7631,6 +7877,8 @@ static int gfx_v10_0_set_clockgating_state(void *handle, · 14 unmodified lines | ||
| 7631 | 7877 | case CHIP_NAVI12: |
| 7632 | 7878 | case CHIP_SIENNA_CICHLID: |
| 7633 | 7879 | case CHIP_NAVY_FLOUNDER: |
| 7880 | + case CHIP_VANGOGH: | |
| 7881 | + case CHIP_DIMGREY_CAVEFISH: | |
| 7634 | 7882 | gfx_v10_0_update_gfx_clock_gating(adev, |
| 7635 | 7883 | state == AMD_CG_STATE_GATE); |
| 7636 | 7884 | break; |
| @@ -7645,6 +7893,11 @@ static void gfx_v10_0_get_clockgating_state(void *handle, u32 *flags) · 8 unmodified lines | ||
| 7645 | 7893 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
| 7646 | 7894 | int data; |
| 7647 | 7895 | |
| 7896 | + /* AMD_CG_SUPPORT_GFX_FGCG */ | |
| 7897 | + data = RREG32_KIQ(SOC15_REG_OFFSET(GC, 0, mmRLC_CGTT_MGCG_OVERRIDE)); | |
| 7898 | + if (!(data & RLC_CGTT_MGCG_OVERRIDE__GFXIP_FGCG_OVERRIDE_MASK)) | |
| 7899 | + *flags |= AMD_CG_SUPPORT_GFX_FGCG; | |
| 7900 | + | |
| 7648 | 7901 | /* AMD_CG_SUPPORT_GFX_MGCG */ |
| 7649 | 7902 | data = RREG32_KIQ(SOC15_REG_OFFSET(GC, 0, mmRLC_CGTT_MGCG_OVERRIDE)); |
| 7650 | 7903 | if (!(data & RLC_CGTT_MGCG_OVERRIDE__GFXIP_MGCG_OVERRIDE_MASK)) |
| @@ -8733,6 +8986,8 @@ static void gfx_v10_0_set_rlc_funcs(struct amdgpu_device *adev) · 1082 unmodified lines | ||
| 8733 | 8986 | case CHIP_NAVI14: |
| 8734 | 8987 | case CHIP_SIENNA_CICHLID: |
| 8735 | 8988 | case CHIP_NAVY_FLOUNDER: |
| 8989 | + case CHIP_VANGOGH: | |
| 8990 | + case CHIP_DIMGREY_CAVEFISH: | |
| 8736 | 8991 | adev->gfx.rlc.funcs = &gfx_v10_0_rlc_funcs; |
| 8737 | 8992 | break; |
| 8738 | 8993 | case CHIP_NAVI12: |
| @@ -3064,7 +3064,8 @@ static int gfx_v6_0_early_init(void *handle) · 3063 unmodified lines | ||
| 3064 | 3064 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
| 3065 | 3065 | |
| 3066 | 3066 | adev->gfx.num_gfx_rings = GFX6_NUM_GFX_RINGS; |
| 3067 | − adev->gfx.num_compute_rings = GFX6_NUM_COMPUTE_RINGS; | |
| 3067 | + adev->gfx.num_compute_rings = min(amdgpu_gfx_get_num_kcq(adev), | |
| 3068 | + GFX6_NUM_COMPUTE_RINGS); | |
| 3068 | 3069 | adev->gfx.funcs = &gfx_v6_0_gfx_funcs; |
| 3069 | 3070 | adev->gfx.rlc.funcs = &gfx_v6_0_rlc_funcs; |
| 3070 | 3071 | gfx_v6_0_set_ring_funcs(adev); |
| @@ -4238,7 +4238,8 @@ static int gfx_v7_0_early_init(void *handle) · 4237 unmodified lines | ||
| 4238 | 4238 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
| 4239 | 4239 | |
| 4240 | 4240 | adev->gfx.num_gfx_rings = GFX7_NUM_GFX_RINGS; |
| 4241 | − adev->gfx.num_compute_rings = AMDGPU_MAX_COMPUTE_RINGS; | |
| 4241 | + adev->gfx.num_compute_rings = min(amdgpu_gfx_get_num_kcq(adev), | |
| 4242 | + AMDGPU_MAX_COMPUTE_RINGS); | |
| 4242 | 4243 | adev->gfx.funcs = &gfx_v7_0_gfx_funcs; |
| 4243 | 4244 | adev->gfx.rlc.funcs = &gfx_v7_0_rlc_funcs; |
| 4244 | 4245 | gfx_v7_0_set_ring_funcs(adev); |
| @@ -729,8 +729,13 @@ static void gfx_v8_0_get_cu_info(struct amdgpu_device *adev); · 728 unmodified lines | ||
| 729 | 729 | static void gfx_v8_0_ring_emit_ce_meta(struct amdgpu_ring *ring); |
| 730 | 730 | static void gfx_v8_0_ring_emit_de_meta(struct amdgpu_ring *ring); |
| 731 | 731 | |
| 732 | +#define CG_ACLK_CNTL__ACLK_DIVIDER_MASK 0x0000007fL | |
| 733 | +#define CG_ACLK_CNTL__ACLK_DIVIDER__SHIFT 0x00000000L | |
| 734 | + | |
| 732 | 735 | static void gfx_v8_0_init_golden_registers(struct amdgpu_device *adev) |
| 733 | 736 | { |
| 737 | + uint32_t data; | |
| 738 | + | |
| 734 | 739 | switch (adev->asic_type) { |
| 735 | 740 | case CHIP_TOPAZ: |
| 736 | 741 | amdgpu_device_program_register_sequence(adev, |
| @@ -790,11 +795,14 @@ static void gfx_v8_0_init_golden_registers(struct amdgpu_device *adev) · 53 unmodified lines | ||
| 790 | 795 | amdgpu_device_program_register_sequence(adev, |
| 791 | 796 | polaris10_golden_common_all, |
| 792 | 797 | ARRAY_SIZE(polaris10_golden_common_all)); |
| 793 | − WREG32_SMC(ixCG_ACLK_CNTL, 0x0000001C); | |
| 794 | − if (adev->pdev->revision == 0xc7 && | |
| 798 | + data = RREG32_SMC(ixCG_ACLK_CNTL); | |
| 799 | + data &= ~CG_ACLK_CNTL__ACLK_DIVIDER_MASK; | |
| 800 | + data |= 0x18 << CG_ACLK_CNTL__ACLK_DIVIDER__SHIFT; | |
| 801 | + WREG32_SMC(ixCG_ACLK_CNTL, data); | |
| 802 | + if ((adev->pdev->device == 0x67DF) && (adev->pdev->revision == 0xc7) && | |
| 795 | 803 | ((adev->pdev->subsystem_device == 0xb37 && adev->pdev->subsystem_vendor == 0x1002) || |
| 796 | 804 | (adev->pdev->subsystem_device == 0x4a8 && adev->pdev->subsystem_vendor == 0x1043) || |
| 797 | − (adev->pdev->subsystem_device == 0x9480 && adev->pdev->subsystem_vendor == 0x1682))) { | |
| 805 | + (adev->pdev->subsystem_device == 0x9480 && adev->pdev->subsystem_vendor == 0x1680))) { | |
| 798 | 806 | amdgpu_atombios_i2c_channel_trans(adev, 0x10, 0x96, 0x1E, 0xDD); |
| 799 | 807 | amdgpu_atombios_i2c_channel_trans(adev, 0x10, 0x96, 0x1F, 0xD0); |
| 800 | 808 | } |
| @@ -5058,7 +5066,7 @@ static int gfx_v8_0_pre_soft_reset(void *handle) · 4257 unmodified lines | ||
| 5058 | 5066 | gfx_v8_0_cp_compute_enable(adev, false); |
| 5059 | 5067 | } |
| 5060 | 5068 | |
| 5061 | − return 0; | |
| 5069 | + return 0; | |
| 5062 | 5070 | } |
| 5063 | 5071 | |
| 5064 | 5072 | static int gfx_v8_0_soft_reset(void *handle) |
| @@ -5295,7 +5303,8 @@ static int gfx_v8_0_early_init(void *handle) · 230 unmodified lines | ||
| 5295 | 5303 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
| 5296 | 5304 | |
| 5297 | 5305 | adev->gfx.num_gfx_rings = GFX8_NUM_GFX_RINGS; |
| 5298 | − adev->gfx.num_compute_rings = amdgpu_num_kcq; | |
| 5306 | + adev->gfx.num_compute_rings = min(amdgpu_gfx_get_num_kcq(adev), | |
| 5307 | + AMDGPU_MAX_COMPUTE_RINGS); | |
| 5299 | 5308 | adev->gfx.funcs = &gfx_v8_0_gfx_funcs; |
| 5300 | 5309 | gfx_v8_0_set_ring_funcs(adev); |
| 5301 | 5310 | gfx_v8_0_set_irq_funcs(adev); |
| @@ -117,6 +117,13 @@ MODULE_FIRMWARE("amdgpu/renoir_mec.bin"); · 116 unmodified lines | ||
| 117 | 117 | MODULE_FIRMWARE("amdgpu/renoir_mec2.bin"); |
| 118 | 118 | MODULE_FIRMWARE("amdgpu/renoir_rlc.bin"); |
| 119 | 119 | |
| 120 | +MODULE_FIRMWARE("amdgpu/green_sardine_ce.bin"); | |
| 121 | +MODULE_FIRMWARE("amdgpu/green_sardine_pfp.bin"); | |
| 122 | +MODULE_FIRMWARE("amdgpu/green_sardine_me.bin"); | |
| 123 | +MODULE_FIRMWARE("amdgpu/green_sardine_mec.bin"); | |
| 124 | +MODULE_FIRMWARE("amdgpu/green_sardine_mec2.bin"); | |
| 125 | +MODULE_FIRMWARE("amdgpu/green_sardine_rlc.bin"); | |
| 126 | + | |
| 120 | 127 | #define mmTCP_CHAN_STEER_0_ARCT 0x0b03 |
| 121 | 128 | #define mmTCP_CHAN_STEER_0_ARCT_BASE_IDX 0 |
| 122 | 129 | #define mmTCP_CHAN_STEER_1_ARCT 0x0b04 |
| @@ -787,7 +794,7 @@ static void gfx_v9_0_set_irq_funcs(struct amdgpu_device *adev); · 664 unmodified lines | ||
| 787 | 794 | static void gfx_v9_0_set_gds_init(struct amdgpu_device *adev); |
| 788 | 795 | static void gfx_v9_0_set_rlc_funcs(struct amdgpu_device *adev); |
| 789 | 796 | static int gfx_v9_0_get_cu_info(struct amdgpu_device *adev, |
| 790 | − struct amdgpu_cu_info *cu_info); | |
| 797 | + struct amdgpu_cu_info *cu_info); | |
| 791 | 798 | static uint64_t gfx_v9_0_get_gpu_clock_counter(struct amdgpu_device *adev); |
| 792 | 799 | static void gfx_v9_0_ring_emit_de_meta(struct amdgpu_ring *ring); |
| 793 | 800 | static u64 gfx_v9_0_ring_get_rptr_compute(struct amdgpu_ring *ring); |
| @@ -1630,7 +1637,10 @@ static int gfx_v9_0_init_microcode(struct amdgpu_device *adev) · 836 unmodified lines | ||
| 1630 | 1637 | chip_name = "arcturus"; |
| 1631 | 1638 | break; |
| 1632 | 1639 | case CHIP_RENOIR: |
| 1633 | − chip_name = "renoir"; | |
| 1640 | + if (adev->apu_flags & AMD_APU_IS_RENOIR) | |
| 1641 | + chip_name = "renoir"; | |
| 1642 | + else | |
| 1643 | + chip_name = "green_sardine"; | |
| 1634 | 1644 | break; |
| 1635 | 1645 | default: |
| 1636 | 1646 | BUG(); |
| @@ -4623,7 +4633,8 @@ static int gfx_v9_0_early_init(void *handle) · 2986 unmodified lines | ||
| 4623 | 4633 | adev->gfx.num_gfx_rings = 0; |
| 4624 | 4634 | else |
| 4625 | 4635 | adev->gfx.num_gfx_rings = GFX9_NUM_GFX_RINGS; |
| 4626 | − adev->gfx.num_compute_rings = amdgpu_num_kcq; | |
| 4636 | + adev->gfx.num_compute_rings = min(amdgpu_gfx_get_num_kcq(adev), | |
| 4637 | + AMDGPU_MAX_COMPUTE_RINGS); | |
| 4627 | 4638 | gfx_v9_0_set_kiq_pm4_funcs(adev); |
| 4628 | 4639 | gfx_v9_0_set_ring_funcs(adev); |
| 4629 | 4640 | gfx_v9_0_set_irq_funcs(adev); |
| @@ -5167,7 +5178,7 @@ static void gfx_v9_0_ring_set_wptr_gfx(struct amdgpu_ring *ring) · 537 unmodified lines | ||
| 5167 | 5178 | |
| 5168 | 5179 | if (ring->use_doorbell) { |
| 5169 | 5180 | /* XXX check if swapping is necessary on BE */ |
| 5170 | − atomic64_set((atomic64_t*)&adev->wb.wb[ring->wptr_offs], ring->wptr); | |
| 5181 | + atomic64_set((atomic64_t *)&adev->wb.wb[ring->wptr_offs], ring->wptr); | |
| 5171 | 5182 | WDOORBELL64(ring->doorbell_index, ring->wptr); |
| 5172 | 5183 | } else { |
| 5173 | 5184 | WREG32_SOC15(GC, 0, mmCP_RB0_WPTR, lower_32_bits(ring->wptr)); |
| @@ -5353,7 +5364,7 @@ static void gfx_v9_0_ring_set_wptr_compute(struct amdgpu_ring *ring) · 179 unmodified lines | ||
| 5353 | 5364 | |
| 5354 | 5365 | /* XXX check if swapping is necessary on BE */ |
| 5355 | 5366 | if (ring->use_doorbell) { |
| 5356 | − atomic64_set((atomic64_t*)&adev->wb.wb[ring->wptr_offs], ring->wptr); | |
| 5367 | + atomic64_set((atomic64_t *)&adev->wb.wb[ring->wptr_offs], ring->wptr); | |
| 5357 | 5368 | WDOORBELL64(ring->doorbell_index, ring->wptr); |
| 5358 | 5369 | } else{ |
| 5359 | 5370 | BUG(); /* only DOORBELL method supported on gfx9 now */ |
| @@ -22,6 +22,7 @@ · 21 unmodified lines | ||
| 22 | 22 | */ |
| 23 | 23 | #include "amdgpu.h" |
| 24 | 24 | #include "gfxhub_v1_0.h" |
| 25 | +#include "gfxhub_v1_1.h" | |
| 25 | 26 | |
| 26 | 27 | #include "gc/gc_9_0_offset.h" |
| 27 | 28 | #include "gc/gc_9_0_sh_mask.h" |
| @@ -412,4 +413,5 @@ const struct amdgpu_gfxhub_funcs gfxhub_v1_0_funcs = { · 384 unmodified lines | ||
| 412 | 413 | .gart_disable = gfxhub_v1_0_gart_disable, |
| 413 | 414 | .set_fault_enable_default = gfxhub_v1_0_set_fault_enable_default, |
| 414 | 415 | .init = gfxhub_v1_0_init, |
| 416 | + .get_xgmi_info = gfxhub_v1_1_get_xgmi_info, | |
| 415 | 417 | }; |
| @@ -21,7 +21,6 @@ · 20 unmodified lines | ||
| 21 | 21 | * |
| 22 | 22 | */ |
| 23 | 23 | #include "amdgpu.h" |
| 24 | −#include "gfxhub_v1_0.h" | |
| 25 | 24 | #include "gfxhub_v1_1.h" |
| 26 | 25 | |
| 27 | 26 | #include "gc/gc_9_2_1_offset.h" |
| @@ -29,7 +28,7 @@ · 1 unmodified line | ||
| 29 | 28 | |
| 30 | 29 | #include "soc15_common.h" |
| 31 | 30 | |
| 32 | −static int gfxhub_v1_1_get_xgmi_info(struct amdgpu_device *adev) | |
| 31 | +int gfxhub_v1_1_get_xgmi_info(struct amdgpu_device *adev) | |
| 33 | 32 | { |
| 34 | 33 | u32 xgmi_lfb_cntl = RREG32_SOC15(GC, 0, mmMC_VM_XGMI_LFB_CNTL); |
| 35 | 34 | u32 max_region = |
| @@ -67,13 +66,3 @@ static int gfxhub_v1_1_get_xgmi_info(struct amdgpu_device *adev) · 31 unmodified lines | ||
| 67 | 66 | |
| 68 | 67 | return 0; |
| 69 | 68 | } |
| 70 | − | |
| 71 | −const struct amdgpu_gfxhub_funcs gfxhub_v1_1_funcs = { | |
| 72 | − .get_mc_fb_offset = gfxhub_v1_0_get_mc_fb_offset, | |
| 73 | − .setup_vm_pt_regs = gfxhub_v1_0_setup_vm_pt_regs, | |
| 74 | − .gart_enable = gfxhub_v1_0_gart_enable, | |
| 75 | − .gart_disable = gfxhub_v1_0_gart_disable, | |
| 76 | − .set_fault_enable_default = gfxhub_v1_0_set_fault_enable_default, | |
| 77 | − .init = gfxhub_v1_0_init, | |
| 78 | − .get_xgmi_info = gfxhub_v1_1_get_xgmi_info, | |
| 79 | −}; | |
| @@ -24,6 +24,6 @@ · 23 unmodified lines | ||
| 24 | 24 | #ifndef __GFXHUB_V1_1_H__ |
| 25 | 25 | #define __GFXHUB_V1_1_H__ |
| 26 | 26 | |
| 27 | −extern const struct amdgpu_gfxhub_funcs gfxhub_v1_1_funcs; | |
| 27 | +int gfxhub_v1_1_get_xgmi_info(struct amdgpu_device *adev); | |
| 28 | 28 | |
| 29 | 29 | #endif |
| @@ -46,6 +46,7 @@ · 45 unmodified lines | ||
| 46 | 46 | #include "gfxhub_v2_0.h" |
| 47 | 47 | #include "gfxhub_v2_1.h" |
| 48 | 48 | #include "mmhub_v2_0.h" |
| 49 | +#include "mmhub_v2_3.h" | |
| 49 | 50 | #include "athub_v2_0.h" |
| 50 | 51 | #include "athub_v2_1.h" |
| 51 | 52 | |
| @@ -106,7 +107,8 @@ static int gmc_v10_0_process_interrupt(struct amdgpu_device *adev, · 54 unmodified lines | ||
| 106 | 107 | * be updated to avoid reading an incorrect value due to |
| 107 | 108 | * the new fast GRBM interface. |
| 108 | 109 | */ |
| 109 | − if (entry->vmid_src == AMDGPU_GFXHUB_0) | |
| 110 | + if ((entry->vmid_src == AMDGPU_GFXHUB_0) && | |
| 111 | + (adev->asic_type < CHIP_SIENNA_CICHLID)) | |
| 110 | 112 | RREG32(hub->vm_l2_pro_fault_status); |
| 111 | 113 | |
| 112 | 114 | status = RREG32(hub->vm_l2_pro_fault_status); |
| @@ -145,7 +147,7 @@ static const struct amdgpu_irq_src_funcs gmc_v10_0_ecc_funcs = { · 32 unmodified lines | ||
| 145 | 147 | .process = amdgpu_umc_process_ecc_irq, |
| 146 | 148 | }; |
| 147 | 149 | |
| 148 | − static void gmc_v10_0_set_irq_funcs(struct amdgpu_device *adev) | |
| 150 | +static void gmc_v10_0_set_irq_funcs(struct amdgpu_device *adev) | |
| 149 | 151 | { |
| 150 | 152 | adev->gmc.vm_fault.num_types = 1; |
| 151 | 153 | adev->gmc.vm_fault.funcs = &gmc_v10_0_irq_funcs; |
| @@ -231,7 +233,8 @@ static void gmc_v10_0_flush_vm_hub(struct amdgpu_device *adev, uint32_t vmid, · 79 unmodified lines | ||
| 231 | 233 | * Issue a dummy read to wait for the ACK register to be cleared |
| 232 | 234 | * to avoid a false ACK due to the new fast GRBM interface. |
| 233 | 235 | */ |
| 234 | − if (vmhub == AMDGPU_GFXHUB_0) | |
| 236 | + if ((vmhub == AMDGPU_GFXHUB_0) && | |
| 237 | + (adev->asic_type < CHIP_SIENNA_CICHLID)) | |
| 235 | 238 | RREG32_NO_KIQ(hub->vm_inv_eng0_req + hub->eng_distance * eng); |
| 236 | 239 | |
| 237 | 240 | /* Wait for ACK with a delay.*/ |
| @@ -483,7 +486,8 @@ static void gmc_v10_0_emit_pasid_mapping(struct amdgpu_ring *ring, unsigned vmid · 245 unmodified lines | ||
| 483 | 486 | /* |
| 484 | 487 | * PTE format on NAVI 10: |
| 485 | 488 | * 63:59 reserved |
| 486 | − * 58:57 reserved | |
| 489 | + * 58 reserved and for sienna_cichlid is used for MALL noalloc | |
| 490 | + * 57 reserved | |
| 487 | 491 | * 56 F |
| 488 | 492 | * 55 L |
| 489 | 493 | * 54 reserved |
| @@ -631,7 +635,14 @@ static void gmc_v10_0_set_umc_funcs(struct amdgpu_device *adev) · 141 unmodified lines | ||
| 631 | 635 | |
| 632 | 636 | static void gmc_v10_0_set_mmhub_funcs(struct amdgpu_device *adev) |
| 633 | 637 | { |
| 634 | − adev->mmhub.funcs = &mmhub_v2_0_funcs; | |
| 638 | + switch (adev->asic_type) { | |
| 639 | + case CHIP_VANGOGH: | |
| 640 | + adev->mmhub.funcs = &mmhub_v2_3_funcs; | |
| 641 | + break; | |
| 642 | + default: | |
| 643 | + adev->mmhub.funcs = &mmhub_v2_0_funcs; | |
| 644 | + break; | |
| 645 | + } | |
| 635 | 646 | } |
| 636 | 647 | |
| 637 | 648 | static void gmc_v10_0_set_gfxhub_funcs(struct amdgpu_device *adev) |
| @@ -639,6 +650,8 @@ static void gmc_v10_0_set_gfxhub_funcs(struct amdgpu_device *adev) · 1 unmodified line | ||
| 639 | 650 | switch (adev->asic_type) { |
| 640 | 651 | case CHIP_SIENNA_CICHLID: |
| 641 | 652 | case CHIP_NAVY_FLOUNDER: |
| 653 | + case CHIP_VANGOGH: | |
| 654 | + case CHIP_DIMGREY_CAVEFISH: | |
| 642 | 655 | adev->gfxhub.funcs = &gfxhub_v2_1_funcs; |
| 643 | 656 | break; |
| 644 | 657 | default: |
| @@ -733,6 +746,13 @@ static int gmc_v10_0_mc_init(struct amdgpu_device *adev) · 88 unmodified lines | ||
| 733 | 746 | adev->gmc.aper_base = pci_resource_start(adev->pdev, 0); |
| 734 | 747 | adev->gmc.aper_size = pci_resource_len(adev->pdev, 0); |
| 735 | 748 | |
| 749 | +#ifdef CONFIG_X86_64 | |
| 750 | + if (adev->flags & AMD_IS_APU) { | |
| 751 | + adev->gmc.aper_base = adev->gfxhub.funcs->get_mc_fb_offset(adev); | |
| 752 | + adev->gmc.aper_size = adev->gmc.real_vram_size; | |
| 753 | + } | |
| 754 | +#endif | |
| 755 | + | |
| 736 | 756 | /* In case the PCI BAR is larger than the actual amount of vram */ |
| 737 | 757 | adev->gmc.visible_vram_size = adev->gmc.aper_size; |
| 738 | 758 | if (adev->gmc.visible_vram_size > adev->gmc.real_vram_size) |
| @@ -746,6 +766,8 @@ static int gmc_v10_0_mc_init(struct amdgpu_device *adev) · 7 unmodified lines | ||
| 746 | 766 | case CHIP_NAVI12: |
| 747 | 767 | case CHIP_SIENNA_CICHLID: |
| 748 | 768 | case CHIP_NAVY_FLOUNDER: |
| 769 | + case CHIP_VANGOGH: | |
| 770 | + case CHIP_DIMGREY_CAVEFISH: | |
| 749 | 771 | default: |
| 750 | 772 | adev->gmc.gart_size = 512ULL << 20; |
| 751 | 773 | break; |
| @@ -790,7 +812,10 @@ static int gmc_v10_0_sw_init(void *handle) · 38 unmodified lines | ||
| 790 | 812 | |
| 791 | 813 | spin_lock_init(&adev->gmc.invalidate_lock); |
| 792 | 814 | |
| 793 | − if (adev->asic_type == CHIP_SIENNA_CICHLID && amdgpu_emu_mode == 1) { | |
| 815 | + if ((adev->flags & AMD_IS_APU) && amdgpu_emu_mode == 1) { | |
| 816 | + adev->gmc.vram_type = AMDGPU_VRAM_TYPE_DDR4; | |
| 817 | + adev->gmc.vram_width = 64; | |
| 818 | + } else if (amdgpu_emu_mode == 1) { | |
| 794 | 819 | adev->gmc.vram_type = AMDGPU_VRAM_TYPE_GDDR6; |
| 795 | 820 | adev->gmc.vram_width = 1 * 128; /* numchan * chansize */ |
| 796 | 821 | } else { |
| @@ -808,6 +833,8 @@ static int gmc_v10_0_sw_init(void *handle) · 11 unmodified lines | ||
| 808 | 833 | case CHIP_NAVI12: |
| 809 | 834 | case CHIP_SIENNA_CICHLID: |
| 810 | 835 | case CHIP_NAVY_FLOUNDER: |
| 836 | + case CHIP_VANGOGH: | |
| 837 | + case CHIP_DIMGREY_CAVEFISH: | |
| 811 | 838 | adev->num_vmhubs = 2; |
| 812 | 839 | /* |
| 813 | 840 | * To fulfill 4-level page support, |
| @@ -921,6 +948,8 @@ static void gmc_v10_0_init_golden_registers(struct amdgpu_device *adev) · 107 unmodified lines | ||
| 921 | 948 | case CHIP_NAVI12: |
| 922 | 949 | case CHIP_SIENNA_CICHLID: |
| 923 | 950 | case CHIP_NAVY_FLOUNDER: |
| 951 | + case CHIP_VANGOGH: | |
| 952 | + case CHIP_DIMGREY_CAVEFISH: | |
| 924 | 953 | break; |
| 925 | 954 | default: |
| 926 | 955 | break; |
| @@ -1081,8 +1110,8 @@ static int gmc_v10_0_set_clockgating_state(void *handle, · 154 unmodified lines | ||
| 1081 | 1110 | if (r) |
| 1082 | 1111 | return r; |
| 1083 | 1112 | |
| 1084 | − if (adev->asic_type == CHIP_SIENNA_CICHLID || | |
| 1085 | − adev->asic_type == CHIP_NAVY_FLOUNDER) | |
| 1113 | + if (adev->asic_type >= CHIP_SIENNA_CICHLID && | |
| 1114 | + adev->asic_type <= CHIP_DIMGREY_CAVEFISH) | |
| 1086 | 1115 | return athub_v2_1_set_clockgating(adev, state); |
| 1087 | 1116 | else |
| 1088 | 1117 | return athub_v2_0_set_clockgating(adev, state); |
| @@ -1094,8 +1123,8 @@ static void gmc_v10_0_get_clockgating_state(void *handle, u32 *flags) · 5 unmodified lines | ||
| 1094 | 1123 | |
| 1095 | 1124 | adev->mmhub.funcs->get_clockgating(adev, flags); |
| 1096 | 1125 | |
| 1097 | − if (adev->asic_type == CHIP_SIENNA_CICHLID || | |
| 1098 | − adev->asic_type == CHIP_NAVY_FLOUNDER) | |
| 1126 | + if (adev->asic_type >= CHIP_SIENNA_CICHLID && | |
| 1127 | + adev->asic_type <= CHIP_DIMGREY_CAVEFISH) | |
| 1099 | 1128 | athub_v2_1_get_clockgating(adev, flags); |
| 1100 | 1129 | else |
| 1101 | 1130 | athub_v2_0_get_clockgating(adev, flags); |
| @@ -230,36 +230,20 @@ static int gmc_v8_0_init_microcode(struct amdgpu_device *adev) · 229 unmodified lines | ||
| 230 | 230 | chip_name = "tonga"; |
| 231 | 231 | break; |
| 232 | 232 | case CHIP_POLARIS11: |
| 233 | − if (((adev->pdev->device == 0x67ef) && | |
| 234 | − ((adev->pdev->revision == 0xe0) || | |
| 235 | − (adev->pdev->revision == 0xe5))) || | |
| 236 | − ((adev->pdev->device == 0x67ff) && | |
| 237 | − ((adev->pdev->revision == 0xcf) || | |
| 238 | − (adev->pdev->revision == 0xef) || | |
| 239 | − (adev->pdev->revision == 0xff)))) | |
| 240 | − chip_name = "polaris11_k"; | |
| 241 | − else if ((adev->pdev->device == 0x67ef) && | |
| 242 | − (adev->pdev->revision == 0xe2)) | |
| 233 | + if (ASICID_IS_P21(adev->pdev->device, adev->pdev->revision) || | |
| 234 | + ASICID_IS_P31(adev->pdev->device, adev->pdev->revision)) | |
| 243 | 235 | chip_name = "polaris11_k"; |
| 244 | 236 | else |
| 245 | 237 | chip_name = "polaris11"; |
| 246 | 238 | break; |
| 247 | 239 | case CHIP_POLARIS10: |
| 248 | − if ((adev->pdev->device == 0x67df) && | |
| 249 | − ((adev->pdev->revision == 0xe1) || | |
| 250 | − (adev->pdev->revision == 0xf7))) | |
| 240 | + if (ASICID_IS_P30(adev->pdev->device, adev->pdev->revision)) | |
| 251 | 241 | chip_name = "polaris10_k"; |
| 252 | 242 | else |
| 253 | 243 | chip_name = "polaris10"; |
| 254 | 244 | break; |
| 255 | 245 | case CHIP_POLARIS12: |
| 256 | − if (((adev->pdev->device == 0x6987) && | |
| 257 | − ((adev->pdev->revision == 0xc0) || | |
| 258 | − (adev->pdev->revision == 0xc3))) || | |
| 259 | − ((adev->pdev->device == 0x6981) && | |
| 260 | − ((adev->pdev->revision == 0x00) || | |
| 261 | − (adev->pdev->revision == 0x01) || | |
| 262 | − (adev->pdev->revision == 0x10)))) | |
| 246 | + if (ASICID_IS_P23(adev->pdev->device, adev->pdev->revision)) | |
| 263 | 247 | chip_name = "polaris12_k"; |
| 264 | 248 | else |
| 265 | 249 | chip_name = "polaris12"; |
| @@ -510,15 +510,16 @@ static int gmc_v9_0_vm_fault_interrupt_state(struct amdgpu_device *adev, · 509 unmodified lines | ||
| 510 | 510 | } |
| 511 | 511 | |
| 512 | 512 | static int gmc_v9_0_process_interrupt(struct amdgpu_device *adev, |
| 513 | − struct amdgpu_irq_src *source, | |
| 514 | − struct amdgpu_iv_entry *entry) | |
| 513 | + struct amdgpu_irq_src *source, | |
| 514 | + struct amdgpu_iv_entry *entry) | |
| 515 | 515 | { |
| 516 | − struct amdgpu_vmhub *hub; | |
| 517 | 516 | bool retry_fault = !!(entry->src_data[1] & 0x80); |
| 518 | 517 | uint32_t status = 0, cid = 0, rw = 0; |
| 519 | − u64 addr; | |
| 520 | − char hub_name[10]; | |
| 518 | + struct amdgpu_task_info task_info; | |
| 519 | + struct amdgpu_vmhub *hub; | |
| 521 | 520 | const char *mmhub_cid; |
| 521 | + const char *hub_name; | |
| 522 | + u64 addr; | |
| 522 | 523 | |
| 523 | 524 | addr = (u64)entry->src_data[0] << 12; |
| 524 | 525 | addr |= ((u64)entry->src_data[1] & 0xf) << 44; |
| @@ -527,105 +528,103 @@ static int gmc_v9_0_process_interrupt(struct amdgpu_device *adev, · 2 unmodified lines | ||
| 527 | 528 | entry->timestamp)) |
| 528 | 529 | return 1; /* This also prevents sending it to KFD */ |
| 529 | 530 | |
| 531 | + /* If it's the first fault for this address, process it normally */ | |
| 532 | + if (retry_fault && !in_interrupt() && | |
| 533 | + amdgpu_vm_handle_fault(adev, entry->pasid, addr)) | |
| 534 | + return 1; /* This also prevents sending it to KFD */ | |
| 535 | + | |
| 536 | + if (!printk_ratelimit()) | |
| 537 | + return 0; | |
| 538 | + | |
| 530 | 539 | if (entry->client_id == SOC15_IH_CLIENTID_VMC) { |
| 531 | − snprintf(hub_name, sizeof(hub_name), "mmhub0"); | |
| 540 | + hub_name = "mmhub0"; | |
| 532 | 541 | hub = &adev->vmhub[AMDGPU_MMHUB_0]; |
| 533 | 542 | } else if (entry->client_id == SOC15_IH_CLIENTID_VMC1) { |
| 534 | − snprintf(hub_name, sizeof(hub_name), "mmhub1"); | |
| 543 | + hub_name = "mmhub1"; | |
| 535 | 544 | hub = &adev->vmhub[AMDGPU_MMHUB_1]; |
| 536 | 545 | } else { |
| 537 | − snprintf(hub_name, sizeof(hub_name), "gfxhub0"); | |
| 546 | + hub_name = "gfxhub0"; | |
| 538 | 547 | hub = &adev->vmhub[AMDGPU_GFXHUB_0]; |
| 539 | 548 | } |
| 540 | 549 | |
| 541 | − /* If it's the first fault for this address, process it normally */ | |
| 542 | − if (retry_fault && !in_interrupt() && | |
| 543 | − amdgpu_vm_handle_fault(adev, entry->pasid, addr)) | |
| 544 | − return 1; /* This also prevents sending it to KFD */ | |
| 550 | + memset(&task_info, 0, sizeof(struct amdgpu_task_info)); | |
| 551 | + amdgpu_vm_get_task_info(adev, entry->pasid, &task_info); | |
| 545 | 552 | |
| 546 | − if (!amdgpu_sriov_vf(adev)) { | |
| 547 | − /* | |
| 548 | − * Issue a dummy read to wait for the status register to | |
| 549 | − * be updated to avoid reading an incorrect value due to | |
| 550 | − * the new fast GRBM interface. | |
| 551 | − */ | |
| 552 | − if (entry->vmid_src == AMDGPU_GFXHUB_0) | |
| 553 | − RREG32(hub->vm_l2_pro_fault_status); | |
| 554 | − | |
| 555 | − status = RREG32(hub->vm_l2_pro_fault_status); | |
| 556 | − cid = REG_GET_FIELD(status, | |
| 557 | − VM_L2_PROTECTION_FAULT_STATUS, CID); | |
| 558 | − rw = REG_GET_FIELD(status, | |
| 559 | − VM_L2_PROTECTION_FAULT_STATUS, RW); | |
| 560 | − WREG32_P(hub->vm_l2_pro_fault_cntl, 1, ~1); | |
| 561 | − } | |
| 553 | + dev_err(adev->dev, | |
| 554 | + "[%s] %s page fault (src_id:%u ring:%u vmid:%u " | |
| 555 | + "pasid:%u, for process %s pid %d thread %s pid %d)\n", | |
| 556 | + hub_name, retry_fault ? "retry" : "no-retry", | |
| 557 | + entry->src_id, entry->ring_id, entry->vmid, | |
| 558 | + entry->pasid, task_info.process_name, task_info.tgid, | |
| 559 | + task_info.task_name, task_info.pid); | |
| 560 | + dev_err(adev->dev, " in page starting at address 0x%016llx from client %d\n", | |
| 561 | + addr, entry->client_id); | |
| 562 | 562 | |
| 563 | − if (printk_ratelimit()) { | |
| 564 | − struct amdgpu_task_info task_info; | |
| 565 | − | |
| 566 | − memset(&task_info, 0, sizeof(struct amdgpu_task_info)); | |
| 567 | − amdgpu_vm_get_task_info(adev, entry->pasid, &task_info); | |
| 568 | − | |
| 569 | − dev_err(adev->dev, | |
| 570 | − "[%s] %s page fault (src_id:%u ring:%u vmid:%u " | |
| 571 | − "pasid:%u, for process %s pid %d thread %s pid %d)\n", | |
| 572 | − hub_name, retry_fault ? "retry" : "no-retry", | |
| 573 | − entry->src_id, entry->ring_id, entry->vmid, | |
| 574 | − entry->pasid, task_info.process_name, task_info.tgid, | |
| 575 | − task_info.task_name, task_info.pid); | |
| 576 | − dev_err(adev->dev, " in page starting at address 0x%016llx from client %d\n", | |
| 577 | − addr, entry->client_id); | |
| 578 | − if (!amdgpu_sriov_vf(adev)) { | |
| 579 | − dev_err(adev->dev, | |
| 580 | − "VM_L2_PROTECTION_FAULT_STATUS:0x%08X\n", | |
| 581 | − status); | |
| 582 | − if (hub == &adev->vmhub[AMDGPU_GFXHUB_0]) { | |
| 583 | − dev_err(adev->dev, "\t Faulty UTCL2 client ID: %s (0x%x)\n", | |
| 584 | − cid >= ARRAY_SIZE(gfxhub_client_ids) ? "unknown" : gfxhub_client_ids[cid], | |
| 585 | − cid); | |
| 586 | − } else { | |
| 587 | − switch (adev->asic_type) { | |
| 588 | − case CHIP_VEGA10: | |
| 589 | − mmhub_cid = mmhub_client_ids_vega10[cid][rw]; | |
| 590 | − break; | |
| 591 | − case CHIP_VEGA12: | |
| 592 | − mmhub_cid = mmhub_client_ids_vega12[cid][rw]; | |
| 593 | − break; | |
| 594 | − case CHIP_VEGA20: | |
| 595 | − mmhub_cid = mmhub_client_ids_vega20[cid][rw]; | |
| 596 | − break; | |
| 597 | − case CHIP_ARCTURUS: | |
| 598 | − mmhub_cid = mmhub_client_ids_arcturus[cid][rw]; | |
| 599 | − break; | |
| 600 | − case CHIP_RAVEN: | |
| 601 | − mmhub_cid = mmhub_client_ids_raven[cid][rw]; | |
| 602 | − break; | |
| 603 | − case CHIP_RENOIR: | |
| 604 | − mmhub_cid = mmhub_client_ids_renoir[cid][rw]; | |
| 605 | − break; | |
| 606 | − default: | |
| 607 | − mmhub_cid = NULL; | |
| 608 | − break; | |
| 609 | − } | |
| 610 | − dev_err(adev->dev, "\t Faulty UTCL2 client ID: %s (0x%x)\n", | |
| 611 | − mmhub_cid ? mmhub_cid : "unknown", cid); | |
| 612 | − } | |
| 613 | − dev_err(adev->dev, "\t MORE_FAULTS: 0x%lx\n", | |
| 614 | − REG_GET_FIELD(status, | |
| 615 | − VM_L2_PROTECTION_FAULT_STATUS, MORE_FAULTS)); | |
| 616 | − dev_err(adev->dev, "\t WALKER_ERROR: 0x%lx\n", | |
| 617 | − REG_GET_FIELD(status, | |
| 618 | − VM_L2_PROTECTION_FAULT_STATUS, WALKER_ERROR)); | |
| 619 | − dev_err(adev->dev, "\t PERMISSION_FAULTS: 0x%lx\n", | |
| 620 | − REG_GET_FIELD(status, | |
| 621 | − VM_L2_PROTECTION_FAULT_STATUS, PERMISSION_FAULTS)); | |
| 622 | − dev_err(adev->dev, "\t MAPPING_ERROR: 0x%lx\n", | |
| 623 | − REG_GET_FIELD(status, | |
| 624 | − VM_L2_PROTECTION_FAULT_STATUS, MAPPING_ERROR)); | |
| 625 | − dev_err(adev->dev, "\t RW: 0x%x\n", rw); | |
| 563 | + if (amdgpu_sriov_vf(adev)) | |
| 564 | + return 0; | |
| 565 | + | |
| 566 | + /* | |
| 567 | + * Issue a dummy read to wait for the status register to | |
| 568 | + * be updated to avoid reading an incorrect value due to | |
| 569 | + * the new fast GRBM interface. | |
| 570 | + */ | |
| 571 | + if (entry->vmid_src == AMDGPU_GFXHUB_0) | |
| 572 | + RREG32(hub->vm_l2_pro_fault_status); | |
| 573 | + | |
| 574 | + status = RREG32(hub->vm_l2_pro_fault_status); | |
| 575 | + cid = REG_GET_FIELD(status, VM_L2_PROTECTION_FAULT_STATUS, CID); | |
| 576 | + rw = REG_GET_FIELD(status, VM_L2_PROTECTION_FAULT_STATUS, RW); | |
| 577 | + WREG32_P(hub->vm_l2_pro_fault_cntl, 1, ~1); | |
| 578 | + | |
| 579 | + | |
| 580 | + dev_err(adev->dev, | |
| 581 | + "VM_L2_PROTECTION_FAULT_STATUS:0x%08X\n", | |
| 582 | + status); | |
| 583 | + if (hub == &adev->vmhub[AMDGPU_GFXHUB_0]) { | |
| 584 | + dev_err(adev->dev, "\t Faulty UTCL2 client ID: %s (0x%x)\n", | |
| 585 | + cid >= ARRAY_SIZE(gfxhub_client_ids) ? "unknown" : | |
| 586 | + gfxhub_client_ids[cid], | |
| 587 | + cid); | |
| 588 | + } else { | |
| 589 | + switch (adev->asic_type) { | |
| 590 | + case CHIP_VEGA10: | |
| 591 | + mmhub_cid = mmhub_client_ids_vega10[cid][rw]; | |
| 592 | + break; | |
| 593 | + case CHIP_VEGA12: | |
| 594 | + mmhub_cid = mmhub_client_ids_vega12[cid][rw]; | |
| 595 | + break; | |
| 596 | + case CHIP_VEGA20: | |
| 597 | + mmhub_cid = mmhub_client_ids_vega20[cid][rw]; | |
| 598 | + break; | |
| 599 | + case CHIP_ARCTURUS: | |
| 600 | + mmhub_cid = mmhub_client_ids_arcturus[cid][rw]; | |
| 601 | + break; | |
| 602 | + case CHIP_RAVEN: | |
| 603 | + mmhub_cid = mmhub_client_ids_raven[cid][rw]; | |
| 604 | + break; | |
| 605 | + case CHIP_RENOIR: | |
| 606 | + mmhub_cid = mmhub_client_ids_renoir[cid][rw]; | |
| 607 | + break; | |
| 608 | + default: | |
| 609 | + mmhub_cid = NULL; | |
| 610 | + break; | |
| 626 | 611 | } |
| 612 | + dev_err(adev->dev, "\t Faulty UTCL2 client ID: %s (0x%x)\n", | |
| 613 | + mmhub_cid ? mmhub_cid : "unknown", cid); | |
| 627 | 614 | } |
| 628 | − | |
| 615 | + dev_err(adev->dev, "\t MORE_FAULTS: 0x%lx\n", | |
| 616 | + REG_GET_FIELD(status, | |
| 617 | + VM_L2_PROTECTION_FAULT_STATUS, MORE_FAULTS)); | |
| 618 | + dev_err(adev->dev, "\t WALKER_ERROR: 0x%lx\n", | |
| 619 | + REG_GET_FIELD(status, | |
| 620 | + VM_L2_PROTECTION_FAULT_STATUS, WALKER_ERROR)); | |
| 621 | + dev_err(adev->dev, "\t PERMISSION_FAULTS: 0x%lx\n", | |
| 622 | + REG_GET_FIELD(status, | |
| 623 | + VM_L2_PROTECTION_FAULT_STATUS, PERMISSION_FAULTS)); | |
| 624 | + dev_err(adev->dev, "\t MAPPING_ERROR: 0x%lx\n", | |
| 625 | + REG_GET_FIELD(status, | |
| 626 | + VM_L2_PROTECTION_FAULT_STATUS, MAPPING_ERROR)); | |
| 627 | + dev_err(adev->dev, "\t RW: 0x%x\n", rw); | |
| 629 | 628 | return 0; |
| 630 | 629 | } |
| 631 | 630 | |
| @@ -1166,15 +1165,7 @@ static void gmc_v9_0_set_mmhub_funcs(struct amdgpu_device *adev) · 534 unmodified lines | ||
| 1166 | 1165 | |
| 1167 | 1166 | static void gmc_v9_0_set_gfxhub_funcs(struct amdgpu_device *adev) |
| 1168 | 1167 | { |
| 1169 | − switch (adev->asic_type) { | |
| 1170 | − case CHIP_ARCTURUS: | |
| 1171 | − case CHIP_VEGA20: | |
| 1172 | − adev->gfxhub.funcs = &gfxhub_v1_1_funcs; | |
| 1173 | − break; | |
| 1174 | − default: | |
| 1175 | − adev->gfxhub.funcs = &gfxhub_v1_0_funcs; | |
| 1176 | − break; | |
| 1177 | − } | |
| 1168 | + adev->gfxhub.funcs = &gfxhub_v1_0_funcs; | |
| 1178 | 1169 | } |
| 1179 | 1170 | |
| 1180 | 1171 | static int gmc_v9_0_early_init(void *handle) |
| @@ -32,19 +32,19 @@ · 31 unmodified lines | ||
| 32 | 32 | #include "vcn/vcn_2_0_0_sh_mask.h" |
| 33 | 33 | #include "ivsrcid/vcn/irqsrcs_vcn_2_0.h" |
| 34 | 34 | |
| 35 | −#define mmUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET 0x1bfff | |
| 35 | +#define mmUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET 0x1bfff | |
| 36 | 36 | #define mmUVD_JPEG_GPCOM_CMD_INTERNAL_OFFSET 0x4029 |
| 37 | 37 | #define mmUVD_JPEG_GPCOM_DATA0_INTERNAL_OFFSET 0x402a |
| 38 | 38 | #define mmUVD_JPEG_GPCOM_DATA1_INTERNAL_OFFSET 0x402b |
| 39 | 39 | #define mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_LOW_INTERNAL_OFFSET 0x40ea |
| 40 | −#define mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_HIGH_INTERNAL_OFFSET 0x40eb | |
| 40 | +#define mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_HIGH_INTERNAL_OFFSET 0x40eb | |
| 41 | 41 | #define mmUVD_LMI_JRBC_IB_VMID_INTERNAL_OFFSET 0x40cf |
| 42 | 42 | #define mmUVD_LMI_JPEG_VMID_INTERNAL_OFFSET 0x40d1 |
| 43 | −#define mmUVD_LMI_JRBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET 0x40e8 | |
| 43 | +#define mmUVD_LMI_JRBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET 0x40e8 | |
| 44 | 44 | #define mmUVD_LMI_JRBC_IB_64BIT_BAR_HIGH_INTERNAL_OFFSET 0x40e9 |
| 45 | 45 | #define mmUVD_JRBC_IB_SIZE_INTERNAL_OFFSET 0x4082 |
| 46 | 46 | #define mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW_INTERNAL_OFFSET 0x40ec |
| 47 | −#define mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH_INTERNAL_OFFSET 0x40ed | |
| 47 | +#define mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH_INTERNAL_OFFSET 0x40ed | |
| 48 | 48 | #define mmUVD_JRBC_RB_COND_RD_TIMER_INTERNAL_OFFSET 0x4085 |
| 49 | 49 | #define mmUVD_JRBC_RB_REF_DATA_INTERNAL_OFFSET 0x4084 |
| 50 | 50 | #define mmUVD_JRBC_STATUS_INTERNAL_OFFSET 0x4089 |
| @@ -247,7 +247,7 @@ static int jpeg_v2_0_disable_power_gating(struct amdgpu_device *adev) · 196 unmodified lines | ||
| 247 | 247 | return 0; |
| 248 | 248 | } |
| 249 | 249 | |
| 250 | −static int jpeg_v2_0_enable_power_gating(struct amdgpu_device* adev) | |
| 250 | +static int jpeg_v2_0_enable_power_gating(struct amdgpu_device *adev) | |
| 251 | 251 | { |
| 252 | 252 | if (adev->pg_flags & AMD_PG_SUPPORT_JPEG) { |
| 253 | 253 | uint32_t data; |
| @@ -274,7 +274,7 @@ static int jpeg_v2_0_enable_power_gating(struct amdgpu_device* adev) · 20 unmodified lines | ||
| 274 | 274 | return 0; |
| 275 | 275 | } |
| 276 | 276 | |
| 277 | −static void jpeg_v2_0_disable_clock_gating(struct amdgpu_device* adev) | |
| 277 | +static void jpeg_v2_0_disable_clock_gating(struct amdgpu_device *adev) | |
| 278 | 278 | { |
| 279 | 279 | uint32_t data; |
| 280 | 280 | |
| @@ -297,7 +297,7 @@ static void jpeg_v2_0_disable_clock_gating(struct amdgpu_device* adev) · 16 unmodified lines | ||
| 297 | 297 | WREG32_SOC15(JPEG, 0, mmJPEG_CGC_GATE, data); |
| 298 | 298 | } |
| 299 | 299 | |
| 300 | −static void jpeg_v2_0_enable_clock_gating(struct amdgpu_device* adev) | |
| 300 | +static void jpeg_v2_0_enable_clock_gating(struct amdgpu_device *adev) | |
| 301 | 301 | { |
| 302 | 302 | uint32_t data; |
| 303 | 303 | |
| @@ -247,7 +247,7 @@ static int jpeg_v2_5_resume(void *handle) · 246 unmodified lines | ||
| 247 | 247 | return r; |
| 248 | 248 | } |
| 249 | 249 | |
| 250 | −static void jpeg_v2_5_disable_clock_gating(struct amdgpu_device* adev, int inst) | |
| 250 | +static void jpeg_v2_5_disable_clock_gating(struct amdgpu_device *adev, int inst) | |
| 251 | 251 | { |
| 252 | 252 | uint32_t data; |
| 253 | 253 | |
| @@ -276,7 +276,7 @@ static void jpeg_v2_5_disable_clock_gating(struct amdgpu_device* adev, int inst) · 22 unmodified lines | ||
| 276 | 276 | WREG32_SOC15(JPEG, inst, mmJPEG_CGC_CTRL, data); |
| 277 | 277 | } |
| 278 | 278 | |
| 279 | −static void jpeg_v2_5_enable_clock_gating(struct amdgpu_device* adev, int inst) | |
| 279 | +static void jpeg_v2_5_enable_clock_gating(struct amdgpu_device *adev, int inst) | |
| 280 | 280 | { |
| 281 | 281 | uint32_t data; |
| 282 | 282 | |
| @@ -213,7 +213,7 @@ static int jpeg_v3_0_resume(void *handle) · 212 unmodified lines | ||
| 213 | 213 | return r; |
| 214 | 214 | } |
| 215 | 215 | |
| 216 | −static void jpeg_v3_0_disable_clock_gating(struct amdgpu_device* adev) | |
| 216 | +static void jpeg_v3_0_disable_clock_gating(struct amdgpu_device *adev) | |
| 217 | 217 | { |
| 218 | 218 | uint32_t data = 0; |
| 219 | 219 | |
| @@ -243,7 +243,7 @@ static void jpeg_v3_0_disable_clock_gating(struct amdgpu_device* adev) · 23 unmodified lines | ||
| 243 | 243 | WREG32_SOC15(JPEG, 0, mmJPEG_CGC_CTRL, data); |
| 244 | 244 | } |
| 245 | 245 | |
| 246 | −static void jpeg_v3_0_enable_clock_gating(struct amdgpu_device* adev) | |
| 246 | +static void jpeg_v3_0_enable_clock_gating(struct amdgpu_device *adev) | |
| 247 | 247 | { |
| 248 | 248 | uint32_t data = 0; |
| 249 | 249 | |
| @@ -286,7 +286,7 @@ static int jpeg_v3_0_disable_static_power_gating(struct amdgpu_device *adev) · 36 unmodified lines | ||
| 286 | 286 | return 0; |
| 287 | 287 | } |
| 288 | 288 | |
| 289 | −static int jpeg_v3_0_enable_static_power_gating(struct amdgpu_device* adev) | |
| 289 | +static int jpeg_v3_0_enable_static_power_gating(struct amdgpu_device *adev) | |
| 290 | 290 | { |
| 291 | 291 | /* enable anti hang mechanism */ |
| 292 | 292 | WREG32_P(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_POWER_STATUS), |
| @@ -46,7 +46,7 @@ static void mes_v10_1_ring_set_wptr(struct amdgpu_ring *ring) · 45 unmodified lines | ||
| 46 | 46 | struct amdgpu_device *adev = ring->adev; |
| 47 | 47 | |
| 48 | 48 | if (ring->use_doorbell) { |
| 49 | − atomic64_set((atomic64_t*)&adev->wb.wb[ring->wptr_offs], | |
| 49 | + atomic64_set((atomic64_t *)&adev->wb.wb[ring->wptr_offs], | |
| 50 | 50 | ring->wptr); |
| 51 | 51 | WDOORBELL64(ring->doorbell_index, ring->wptr); |
| 52 | 52 | } else { |
| @@ -409,7 +409,7 @@ static void mmhub_v1_0_set_fault_enable_default(struct amdgpu_device *adev, bool · 408 unmodified lines | ||
| 409 | 409 | CRASH_ON_NO_RETRY_FAULT, 1); |
| 410 | 410 | tmp = REG_SET_FIELD(tmp, VM_L2_PROTECTION_FAULT_CNTL, |
| 411 | 411 | CRASH_ON_RETRY_FAULT, 1); |
| 412 | − } | |
| 412 | + } | |
| 413 | 413 | |
| 414 | 414 | WREG32_SOC15(MMHUB, 0, mmVM_L2_PROTECTION_FAULT_CNTL, tmp); |
| 415 | 415 | } |
| @@ -712,7 +712,7 @@ static int mmhub_v1_0_get_ras_error_count(struct amdgpu_device *adev, · 296 unmodified lines | ||
| 712 | 712 | uint32_t sec_cnt, ded_cnt; |
| 713 | 713 | |
| 714 | 714 | for (i = 0; i < ARRAY_SIZE(mmhub_v1_0_ras_fields); i++) { |
| 715 | − if(mmhub_v1_0_ras_fields[i].reg_offset != reg->reg_offset) | |
| 715 | + if (mmhub_v1_0_ras_fields[i].reg_offset != reg->reg_offset) | |
| 716 | 716 | continue; |
| 717 | 717 | |
| 718 | 718 | sec_cnt = (value & |
| @@ -543,6 +543,7 @@ static void mmhub_v2_0_update_medium_grain_clock_gating(struct amdgpu_device *ad · 542 unmodified lines | ||
| 543 | 543 | switch (adev->asic_type) { |
| 544 | 544 | case CHIP_SIENNA_CICHLID: |
| 545 | 545 | case CHIP_NAVY_FLOUNDER: |
| 546 | + case CHIP_DIMGREY_CAVEFISH: | |
| 546 | 547 | def = data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid); |
| 547 | 548 | def1 = data1 = RREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2_Sienna_Cichlid); |
| 548 | 549 | break; |
| @@ -576,6 +577,7 @@ static void mmhub_v2_0_update_medium_grain_clock_gating(struct amdgpu_device *ad · 27 unmodified lines | ||
| 576 | 577 | switch (adev->asic_type) { |
| 577 | 578 | case CHIP_SIENNA_CICHLID: |
| 578 | 579 | case CHIP_NAVY_FLOUNDER: |
| 580 | + case CHIP_DIMGREY_CAVEFISH: | |
| 579 | 581 | if (def != data) |
| 580 | 582 | WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid, data); |
| 581 | 583 | if (def1 != data1) |
| @@ -598,6 +600,7 @@ static void mmhub_v2_0_update_medium_grain_light_sleep(struct amdgpu_device *ade · 16 unmodified lines | ||
| 598 | 600 | switch (adev->asic_type) { |
| 599 | 601 | case CHIP_SIENNA_CICHLID: |
| 600 | 602 | case CHIP_NAVY_FLOUNDER: |
| 603 | + case CHIP_DIMGREY_CAVEFISH: | |
| 601 | 604 | def = data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid); |
| 602 | 605 | break; |
| 603 | 606 | default: |
| @@ -614,6 +617,7 @@ static void mmhub_v2_0_update_medium_grain_light_sleep(struct amdgpu_device *ade · 10 unmodified lines | ||
| 614 | 617 | switch (adev->asic_type) { |
| 615 | 618 | case CHIP_SIENNA_CICHLID: |
| 616 | 619 | case CHIP_NAVY_FLOUNDER: |
| 620 | + case CHIP_DIMGREY_CAVEFISH: | |
| 617 | 621 | WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid, data); |
| 618 | 622 | break; |
| 619 | 623 | default: |
| @@ -635,6 +639,7 @@ static int mmhub_v2_0_set_clockgating(struct amdgpu_device *adev, · 15 unmodified lines | ||
| 635 | 639 | case CHIP_NAVI12: |
| 636 | 640 | case CHIP_SIENNA_CICHLID: |
| 637 | 641 | case CHIP_NAVY_FLOUNDER: |
| 642 | + case CHIP_DIMGREY_CAVEFISH: | |
| 638 | 643 | mmhub_v2_0_update_medium_grain_clock_gating(adev, |
| 639 | 644 | state == AMD_CG_STATE_GATE); |
| 640 | 645 | mmhub_v2_0_update_medium_grain_light_sleep(adev, |
| @@ -657,6 +662,7 @@ static void mmhub_v2_0_get_clockgating(struct amdgpu_device *adev, u32 *flags) · 16 unmodified lines | ||
| 657 | 662 | switch (adev->asic_type) { |
| 658 | 663 | case CHIP_SIENNA_CICHLID: |
| 659 | 664 | case CHIP_NAVY_FLOUNDER: |
| 665 | + case CHIP_DIMGREY_CAVEFISH: | |
| 660 | 666 | data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid); |
| 661 | 667 | data1 = RREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2_Sienna_Cichlid); |
| 662 | 668 | break; |
| @@ -0,0 +1,589 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2019 Advanced Micro Devices, Inc. | |
| 3 | + * | |
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a | |
| 5 | + * copy of this software and associated documentation files (the "Software"), | |
| 6 | + * to deal in the Software without restriction, including without limitation | |
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the | |
| 9 | + * Software is furnished to do so, subject to the following conditions: | |
| 10 | + * | |
| 11 | + * The above copyright notice and this permission notice shall be included in | |
| 12 | + * all copies or substantial portions of the Software. | |
| 13 | + * | |
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 17 | + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 18 | + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 19 | + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 20 | + * OTHER DEALINGS IN THE SOFTWARE. | |
| 21 | + * | |
| 22 | + */ | |
| 23 | + | |
| 24 | +#include "amdgpu.h" | |
| 25 | +#include "mmhub_v2_3.h" | |
| 26 | + | |
| 27 | +#include "mmhub/mmhub_2_3_0_offset.h" | |
| 28 | +#include "mmhub/mmhub_2_3_0_sh_mask.h" | |
| 29 | +#include "mmhub/mmhub_2_3_0_default.h" | |
| 30 | +#include "navi10_enum.h" | |
| 31 | + | |
| 32 | +#include "soc15_common.h" | |
| 33 | + | |
| 34 | +static const char *mmhub_client_ids_vangogh[][2] = { | |
| 35 | + [0][0] = "MP0", | |
| 36 | + [1][0] = "MP1", | |
| 37 | + [2][0] = "DCEDMC", | |
| 38 | + [3][0] = "DCEVGA", | |
| 39 | + [13][0] = "UTCL2", | |
| 40 | + [26][0] = "OSS", | |
| 41 | + [27][0] = "HDP", | |
| 42 | + [28][0] = "VCN", | |
| 43 | + [29][0] = "VCNU", | |
| 44 | + [30][0] = "JPEG", | |
| 45 | + [0][1] = "MP0", | |
| 46 | + [1][1] = "MP1", | |
| 47 | + [2][1] = "DCEDMC", | |
| 48 | + [3][1] = "DCEVGA", | |
| 49 | + [4][1] = "DCEDWB", | |
| 50 | + [5][1] = "XDP", | |
| 51 | + [26][1] = "OSS", | |
| 52 | + [27][1] = "HDP", | |
| 53 | + [28][1] = "VCN", | |
| 54 | + [29][1] = "VCNU", | |
| 55 | + [30][1] = "JPEG", | |
| 56 | +}; | |
| 57 | + | |
| 58 | +static uint32_t mmhub_v2_3_get_invalidate_req(unsigned int vmid, | |
| 59 | + uint32_t flush_type) | |
| 60 | +{ | |
| 61 | + u32 req = 0; | |
| 62 | + | |
| 63 | + /* invalidate using legacy mode on vmid*/ | |
| 64 | + req = REG_SET_FIELD(req, MMVM_INVALIDATE_ENG0_REQ, | |
| 65 | + PER_VMID_INVALIDATE_REQ, 1 << vmid); | |
| 66 | + req = REG_SET_FIELD(req, MMVM_INVALIDATE_ENG0_REQ, FLUSH_TYPE, flush_type); | |
| 67 | + req = REG_SET_FIELD(req, MMVM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PTES, 1); | |
| 68 | + req = REG_SET_FIELD(req, MMVM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PDE0, 1); | |
| 69 | + req = REG_SET_FIELD(req, MMVM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PDE1, 1); | |
| 70 | + req = REG_SET_FIELD(req, MMVM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PDE2, 1); | |
| 71 | + req = REG_SET_FIELD(req, MMVM_INVALIDATE_ENG0_REQ, INVALIDATE_L1_PTES, 1); | |
| 72 | + req = REG_SET_FIELD(req, MMVM_INVALIDATE_ENG0_REQ, | |
| 73 | + CLEAR_PROTECTION_FAULT_STATUS_ADDR, 0); | |
| 74 | + | |
| 75 | + return req; | |
| 76 | +} | |
| 77 | + | |
| 78 | +static void | |
| 79 | +mmhub_v2_3_print_l2_protection_fault_status(struct amdgpu_device *adev, | |
| 80 | + uint32_t status) | |
| 81 | +{ | |
| 82 | + uint32_t cid, rw; | |
| 83 | + const char *mmhub_cid = NULL; | |
| 84 | + | |
| 85 | + cid = REG_GET_FIELD(status, | |
| 86 | + MMVM_L2_PROTECTION_FAULT_STATUS, CID); | |
| 87 | + rw = REG_GET_FIELD(status, | |
| 88 | + MMVM_L2_PROTECTION_FAULT_STATUS, RW); | |
| 89 | + | |
| 90 | + dev_err(adev->dev, | |
| 91 | + "MMVM_L2_PROTECTION_FAULT_STATUS:0x%08X\n", | |
| 92 | + status); | |
| 93 | + switch (adev->asic_type) { | |
| 94 | + case CHIP_VANGOGH: | |
| 95 | + mmhub_cid = mmhub_client_ids_vangogh[cid][rw]; | |
| 96 | + break; | |
| 97 | + default: | |
| 98 | + mmhub_cid = NULL; | |
| 99 | + break; | |
| 100 | + } | |
| 101 | + dev_err(adev->dev, "\t Faulty UTCL2 client ID: %s (0x%x)\n", | |
| 102 | + mmhub_cid ? mmhub_cid : "unknown", cid); | |
| 103 | + dev_err(adev->dev, "\t MORE_FAULTS: 0x%lx\n", | |
| 104 | + REG_GET_FIELD(status, | |
| 105 | + MMVM_L2_PROTECTION_FAULT_STATUS, MORE_FAULTS)); | |
| 106 | + dev_err(adev->dev, "\t WALKER_ERROR: 0x%lx\n", | |
| 107 | + REG_GET_FIELD(status, | |
| 108 | + MMVM_L2_PROTECTION_FAULT_STATUS, WALKER_ERROR)); | |
| 109 | + dev_err(adev->dev, "\t PERMISSION_FAULTS: 0x%lx\n", | |
| 110 | + REG_GET_FIELD(status, | |
| 111 | + MMVM_L2_PROTECTION_FAULT_STATUS, PERMISSION_FAULTS)); | |
| 112 | + dev_err(adev->dev, "\t MAPPING_ERROR: 0x%lx\n", | |
| 113 | + REG_GET_FIELD(status, | |
| 114 | + MMVM_L2_PROTECTION_FAULT_STATUS, MAPPING_ERROR)); | |
| 115 | + dev_err(adev->dev, "\t RW: 0x%x\n", rw); | |
| 116 | +} | |
| 117 | + | |
| 118 | +static void mmhub_v2_3_setup_vm_pt_regs(struct amdgpu_device *adev, | |
| 119 | + uint32_t vmid, | |
| 120 | + uint64_t page_table_base) | |
| 121 | +{ | |
| 122 | + struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_MMHUB_0]; | |
| 123 | + | |
| 124 | + WREG32_SOC15_OFFSET(MMHUB, 0, mmMMVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32, | |
| 125 | + hub->ctx_addr_distance * vmid, lower_32_bits(page_table_base)); | |
| 126 | + | |
| 127 | + WREG32_SOC15_OFFSET(MMHUB, 0, mmMMVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32, | |
| 128 | + hub->ctx_addr_distance * vmid, upper_32_bits(page_table_base)); | |
| 129 | +} | |
| 130 | + | |
| 131 | +static void mmhub_v2_3_init_gart_aperture_regs(struct amdgpu_device *adev) | |
| 132 | +{ | |
| 133 | + uint64_t pt_base = amdgpu_gmc_pd_addr(adev->gart.bo); | |
| 134 | + | |
| 135 | + mmhub_v2_3_setup_vm_pt_regs(adev, 0, pt_base); | |
| 136 | + | |
| 137 | + WREG32_SOC15(MMHUB, 0, mmMMVM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32, | |
| 138 | + (u32)(adev->gmc.gart_start >> 12)); | |
| 139 | + WREG32_SOC15(MMHUB, 0, mmMMVM_CONTEXT0_PAGE_TABLE_START_ADDR_HI32, | |
| 140 | + (u32)(adev->gmc.gart_start >> 44)); | |
| 141 | + | |
| 142 | + WREG32_SOC15(MMHUB, 0, mmMMVM_CONTEXT0_PAGE_TABLE_END_ADDR_LO32, | |
| 143 | + (u32)(adev->gmc.gart_end >> 12)); | |
| 144 | + WREG32_SOC15(MMHUB, 0, mmMMVM_CONTEXT0_PAGE_TABLE_END_ADDR_HI32, | |
| 145 | + (u32)(adev->gmc.gart_end >> 44)); | |
| 146 | +} | |
| 147 | + | |
| 148 | +static void mmhub_v2_3_init_system_aperture_regs(struct amdgpu_device *adev) | |
| 149 | +{ | |
| 150 | + uint64_t value; | |
| 151 | + uint32_t tmp; | |
| 152 | + | |
| 153 | + /* Disable AGP. */ | |
| 154 | + WREG32_SOC15(MMHUB, 0, mmMMMC_VM_AGP_BASE, 0); | |
| 155 | + WREG32_SOC15(MMHUB, 0, mmMMMC_VM_AGP_TOP, 0); | |
| 156 | + WREG32_SOC15(MMHUB, 0, mmMMMC_VM_AGP_BOT, 0x00FFFFFF); | |
| 157 | + | |
| 158 | + /* Program the system aperture low logical page number. */ | |
| 159 | + WREG32_SOC15(MMHUB, 0, mmMMMC_VM_SYSTEM_APERTURE_LOW_ADDR, | |
| 160 | + adev->gmc.vram_start >> 18); | |
| 161 | + WREG32_SOC15(MMHUB, 0, mmMMMC_VM_SYSTEM_APERTURE_HIGH_ADDR, | |
| 162 | + adev->gmc.vram_end >> 18); | |
| 163 | + | |
| 164 | + /* Set default page address. */ | |
| 165 | + value = adev->vram_scratch.gpu_addr - adev->gmc.vram_start + | |
| 166 | + adev->vm_manager.vram_base_offset; | |
| 167 | + WREG32_SOC15(MMHUB, 0, mmMMMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, | |
| 168 | + (u32)(value >> 12)); | |
| 169 | + WREG32_SOC15(MMHUB, 0, mmMMMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, | |
| 170 | + (u32)(value >> 44)); | |
| 171 | + | |
| 172 | + /* Program "protection fault". */ | |
| 173 | + WREG32_SOC15(MMHUB, 0, mmMMVM_L2_PROTECTION_FAULT_DEFAULT_ADDR_LO32, | |
| 174 | + (u32)(adev->dummy_page_addr >> 12)); | |
| 175 | + WREG32_SOC15(MMHUB, 0, mmMMVM_L2_PROTECTION_FAULT_DEFAULT_ADDR_HI32, | |
| 176 | + (u32)((u64)adev->dummy_page_addr >> 44)); | |
| 177 | + | |
| 178 | + tmp = RREG32_SOC15(MMHUB, 0, mmMMVM_L2_PROTECTION_FAULT_CNTL2); | |
| 179 | + tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL2, | |
| 180 | + ACTIVE_PAGE_MIGRATION_PTE_READ_RETRY, 1); | |
| 181 | + WREG32_SOC15(MMHUB, 0, mmMMVM_L2_PROTECTION_FAULT_CNTL2, tmp); | |
| 182 | +} | |
| 183 | + | |
| 184 | +static void mmhub_v2_3_init_tlb_regs(struct amdgpu_device *adev) | |
| 185 | +{ | |
| 186 | + uint32_t tmp; | |
| 187 | + | |
| 188 | + /* Setup TLB control */ | |
| 189 | + tmp = RREG32_SOC15(MMHUB, 0, mmMMMC_VM_MX_L1_TLB_CNTL); | |
| 190 | + | |
| 191 | + tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL, ENABLE_L1_TLB, 1); | |
| 192 | + tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL, SYSTEM_ACCESS_MODE, 3); | |
| 193 | + tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL, | |
| 194 | + ENABLE_ADVANCED_DRIVER_MODEL, 1); | |
| 195 | + tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL, | |
| 196 | + SYSTEM_APERTURE_UNMAPPED_ACCESS, 0); | |
| 197 | + tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL, ECO_BITS, 0); | |
| 198 | + tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL, | |
| 199 | + MTYPE, MTYPE_UC); /* UC, uncached */ | |
| 200 | + | |
| 201 | + WREG32_SOC15(MMHUB, 0, mmMMMC_VM_MX_L1_TLB_CNTL, tmp); | |
| 202 | +} | |
| 203 | + | |
| 204 | +static void mmhub_v2_3_init_cache_regs(struct amdgpu_device *adev) | |
| 205 | +{ | |
| 206 | + uint32_t tmp; | |
| 207 | + | |
| 208 | + /* Setup L2 cache */ | |
| 209 | + tmp = RREG32_SOC15(MMHUB, 0, mmMMVM_L2_CNTL); | |
| 210 | + tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL, ENABLE_L2_CACHE, 1); | |
| 211 | + tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL, ENABLE_L2_FRAGMENT_PROCESSING, 0); | |
| 212 | + tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL, | |
| 213 | + ENABLE_DEFAULT_PAGE_OUT_TO_SYSTEM_MEMORY, 1); | |
| 214 | + /* XXX for emulation, Refer to closed source code.*/ | |
| 215 | + tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL, L2_PDE0_CACHE_TAG_GENERATION_MODE, | |
| 216 | + 0); | |
| 217 | + tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL, PDE_FAULT_CLASSIFICATION, 0); | |
| 218 | + tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL, CONTEXT1_IDENTITY_ACCESS_MODE, 1); | |
| 219 | + tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL, IDENTITY_MODE_FRAGMENT_SIZE, 0); | |
| 220 | + WREG32_SOC15(MMHUB, 0, mmMMVM_L2_CNTL, tmp); | |
| 221 | + | |
| 222 | + tmp = RREG32_SOC15(MMHUB, 0, mmMMVM_L2_CNTL2); | |
| 223 | + tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS, 1); | |
| 224 | + tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL2, INVALIDATE_L2_CACHE, 1); | |
| 225 | + WREG32_SOC15(MMHUB, 0, mmMMVM_L2_CNTL2, tmp); | |
| 226 | + | |
| 227 | + tmp = mmMMVM_L2_CNTL3_DEFAULT; | |
| 228 | + if (adev->gmc.translate_further) { | |
| 229 | + tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL3, BANK_SELECT, 12); | |
| 230 | + tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL3, | |
| 231 | + L2_CACHE_BIGK_FRAGMENT_SIZE, 9); | |
| 232 | + } else { | |
| 233 | + tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL3, BANK_SELECT, 9); | |
| 234 | + tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL3, | |
| 235 | + L2_CACHE_BIGK_FRAGMENT_SIZE, 6); | |
| 236 | + } | |
| 237 | + WREG32_SOC15(MMHUB, 0, mmMMVM_L2_CNTL3, tmp); | |
| 238 | + | |
| 239 | + tmp = mmMMVM_L2_CNTL4_DEFAULT; | |
| 240 | + tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL4, VMC_TAP_PDE_REQUEST_PHYSICAL, 0); | |
| 241 | + tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL4, VMC_TAP_PTE_REQUEST_PHYSICAL, 0); | |
| 242 | + WREG32_SOC15(MMHUB, 0, mmMMVM_L2_CNTL4, tmp); | |
| 243 | + | |
| 244 | + tmp = mmMMVM_L2_CNTL5_DEFAULT; | |
| 245 | + tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL5, L2_CACHE_SMALLK_FRAGMENT_SIZE, 0); | |
| 246 | + WREG32_SOC15(GC, 0, mmMMVM_L2_CNTL5, tmp); | |
| 247 | +} | |
| 248 | + | |
| 249 | +static void mmhub_v2_3_enable_system_domain(struct amdgpu_device *adev) | |
| 250 | +{ | |
| 251 | + uint32_t tmp; | |
| 252 | + | |
| 253 | + tmp = RREG32_SOC15(MMHUB, 0, mmMMVM_CONTEXT0_CNTL); | |
| 254 | + tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT0_CNTL, ENABLE_CONTEXT, 1); | |
| 255 | + tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT0_CNTL, PAGE_TABLE_DEPTH, 0); | |
| 256 | + tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT0_CNTL, | |
| 257 | + RETRY_PERMISSION_OR_INVALID_PAGE_FAULT, 0); | |
| 258 | + WREG32_SOC15(MMHUB, 0, mmMMVM_CONTEXT0_CNTL, tmp); | |
| 259 | +} | |
| 260 | + | |
| 261 | +static void mmhub_v2_3_disable_identity_aperture(struct amdgpu_device *adev) | |
| 262 | +{ | |
| 263 | + WREG32_SOC15(MMHUB, 0, | |
| 264 | + mmMMVM_L2_CONTEXT1_IDENTITY_APERTURE_LOW_ADDR_LO32, | |
| 265 | + 0xFFFFFFFF); | |
| 266 | + WREG32_SOC15(MMHUB, 0, | |
| 267 | + mmMMVM_L2_CONTEXT1_IDENTITY_APERTURE_LOW_ADDR_HI32, | |
| 268 | + 0x0000000F); | |
| 269 | + | |
| 270 | + WREG32_SOC15(MMHUB, 0, | |
| 271 | + mmMMVM_L2_CONTEXT1_IDENTITY_APERTURE_HIGH_ADDR_LO32, 0); | |
| 272 | + WREG32_SOC15(MMHUB, 0, | |
| 273 | + mmMMVM_L2_CONTEXT1_IDENTITY_APERTURE_HIGH_ADDR_HI32, 0); | |
| 274 | + | |
| 275 | + WREG32_SOC15(MMHUB, 0, mmMMVM_L2_CONTEXT_IDENTITY_PHYSICAL_OFFSET_LO32, | |
| 276 | + 0); | |
| 277 | + WREG32_SOC15(MMHUB, 0, mmMMVM_L2_CONTEXT_IDENTITY_PHYSICAL_OFFSET_HI32, | |
| 278 | + 0); | |
| 279 | +} | |
| 280 | + | |
| 281 | +static void mmhub_v2_3_setup_vmid_config(struct amdgpu_device *adev) | |
| 282 | +{ | |
| 283 | + struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_MMHUB_0]; | |
| 284 | + int i; | |
| 285 | + uint32_t tmp; | |
| 286 | + | |
| 287 | + for (i = 0; i <= 14; i++) { | |
| 288 | + tmp = RREG32_SOC15_OFFSET(MMHUB, 0, mmMMVM_CONTEXT1_CNTL, i); | |
| 289 | + tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL, ENABLE_CONTEXT, 1); | |
| 290 | + tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL, PAGE_TABLE_DEPTH, | |
| 291 | + adev->vm_manager.num_level); | |
| 292 | + tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL, | |
| 293 | + RANGE_PROTECTION_FAULT_ENABLE_DEFAULT, 1); | |
| 294 | + tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL, | |
| 295 | + DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT, | |
| 296 | + 1); | |
| 297 | + tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL, | |
| 298 | + PDE0_PROTECTION_FAULT_ENABLE_DEFAULT, 1); | |
| 299 | + tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL, | |
| 300 | + VALID_PROTECTION_FAULT_ENABLE_DEFAULT, 1); | |
| 301 | + tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL, | |
| 302 | + READ_PROTECTION_FAULT_ENABLE_DEFAULT, 1); | |
| 303 | + tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL, | |
| 304 | + WRITE_PROTECTION_FAULT_ENABLE_DEFAULT, 1); | |
| 305 | + tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL, | |
| 306 | + EXECUTE_PROTECTION_FAULT_ENABLE_DEFAULT, 1); | |
| 307 | + tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL, | |
| 308 | + PAGE_TABLE_BLOCK_SIZE, | |
| 309 | + adev->vm_manager.block_size - 9); | |
| 310 | + /* Send no-retry XNACK on fault to suppress VM fault storm. */ | |
| 311 | + tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL, | |
| 312 | + RETRY_PERMISSION_OR_INVALID_PAGE_FAULT, | |
| 313 | + !amdgpu_noretry); | |
| 314 | + WREG32_SOC15_OFFSET(MMHUB, 0, mmMMVM_CONTEXT1_CNTL, | |
| 315 | + i * hub->ctx_distance, tmp); | |
| 316 | + WREG32_SOC15_OFFSET(MMHUB, 0, mmMMVM_CONTEXT1_PAGE_TABLE_START_ADDR_LO32, | |
| 317 | + i * hub->ctx_addr_distance, 0); | |
| 318 | + WREG32_SOC15_OFFSET(MMHUB, 0, mmMMVM_CONTEXT1_PAGE_TABLE_START_ADDR_HI32, | |
| 319 | + i * hub->ctx_addr_distance, 0); | |
| 320 | + WREG32_SOC15_OFFSET(MMHUB, 0, mmMMVM_CONTEXT1_PAGE_TABLE_END_ADDR_LO32, | |
| 321 | + i * hub->ctx_addr_distance, | |
| 322 | + lower_32_bits(adev->vm_manager.max_pfn - 1)); | |
| 323 | + WREG32_SOC15_OFFSET(MMHUB, 0, mmMMVM_CONTEXT1_PAGE_TABLE_END_ADDR_HI32, | |
| 324 | + i * hub->ctx_addr_distance, | |
| 325 | + upper_32_bits(adev->vm_manager.max_pfn - 1)); | |
| 326 | + } | |
| 327 | +} | |
| 328 | + | |
| 329 | +static void mmhub_v2_3_program_invalidation(struct amdgpu_device *adev) | |
| 330 | +{ | |
| 331 | + struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_MMHUB_0]; | |
| 332 | + unsigned i; | |
| 333 | + | |
| 334 | + for (i = 0; i < 18; ++i) { | |
| 335 | + WREG32_SOC15_OFFSET(MMHUB, 0, | |
| 336 | + mmMMVM_INVALIDATE_ENG0_ADDR_RANGE_LO32, | |
| 337 | + i * hub->eng_addr_distance, 0xffffffff); | |
| 338 | + WREG32_SOC15_OFFSET(MMHUB, 0, | |
| 339 | + mmMMVM_INVALIDATE_ENG0_ADDR_RANGE_HI32, | |
| 340 | + i * hub->eng_addr_distance, 0x1f); | |
| 341 | + } | |
| 342 | +} | |
| 343 | + | |
| 344 | +static int mmhub_v2_3_gart_enable(struct amdgpu_device *adev) | |
| 345 | +{ | |
| 346 | + if (amdgpu_sriov_vf(adev)) { | |
| 347 | + /* | |
| 348 | + * MMMC_VM_FB_LOCATION_BASE/TOP is NULL for VF, becuase they are | |
| 349 | + * VF copy registers so vbios post doesn't program them, for | |
| 350 | + * SRIOV driver need to program them | |
| 351 | + */ | |
| 352 | + WREG32_SOC15(MMHUB, 0, mmMMMC_VM_FB_LOCATION_BASE, | |
| 353 | + adev->gmc.vram_start >> 24); | |
| 354 | + WREG32_SOC15(MMHUB, 0, mmMMMC_VM_FB_LOCATION_TOP, | |
| 355 | + adev->gmc.vram_end >> 24); | |
| 356 | + } | |
| 357 | + | |
| 358 | + /* GART Enable. */ | |
| 359 | + mmhub_v2_3_init_gart_aperture_regs(adev); | |
| 360 | + mmhub_v2_3_init_system_aperture_regs(adev); | |
| 361 | + mmhub_v2_3_init_tlb_regs(adev); | |
| 362 | + mmhub_v2_3_init_cache_regs(adev); | |
| 363 | + | |
| 364 | + mmhub_v2_3_enable_system_domain(adev); | |
| 365 | + mmhub_v2_3_disable_identity_aperture(adev); | |
| 366 | + mmhub_v2_3_setup_vmid_config(adev); | |
| 367 | + mmhub_v2_3_program_invalidation(adev); | |
| 368 | + | |
| 369 | + return 0; | |
| 370 | +} | |
| 371 | + | |
| 372 | +static void mmhub_v2_3_gart_disable(struct amdgpu_device *adev) | |
| 373 | +{ | |
| 374 | + struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_MMHUB_0]; | |
| 375 | + u32 tmp; | |
| 376 | + u32 i; | |
| 377 | + | |
| 378 | + /* Disable all tables */ | |
| 379 | + for (i = 0; i < 16; i++) | |
| 380 | + WREG32_SOC15_OFFSET(MMHUB, 0, mmMMVM_CONTEXT0_CNTL, | |
| 381 | + i * hub->ctx_distance, 0); | |
| 382 | + | |
| 383 | + /* Setup TLB control */ | |
| 384 | + tmp = RREG32_SOC15(MMHUB, 0, mmMMMC_VM_MX_L1_TLB_CNTL); | |
| 385 | + tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL, ENABLE_L1_TLB, 0); | |
| 386 | + tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL, | |
| 387 | + ENABLE_ADVANCED_DRIVER_MODEL, 0); | |
| 388 | + WREG32_SOC15(MMHUB, 0, mmMMMC_VM_MX_L1_TLB_CNTL, tmp); | |
| 389 | + | |
| 390 | + /* Setup L2 cache */ | |
| 391 | + tmp = RREG32_SOC15(MMHUB, 0, mmMMVM_L2_CNTL); | |
| 392 | + tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL, ENABLE_L2_CACHE, 0); | |
| 393 | + WREG32_SOC15(MMHUB, 0, mmMMVM_L2_CNTL, tmp); | |
| 394 | + WREG32_SOC15(MMHUB, 0, mmMMVM_L2_CNTL3, 0); | |
| 395 | +} | |
| 396 | + | |
| 397 | +/** | |
| 398 | + * mmhub_v2_3_set_fault_enable_default - update GART/VM fault handling | |
| 399 | + * | |
| 400 | + * @adev: amdgpu_device pointer | |
| 401 | + * @value: true redirects VM faults to the default page | |
| 402 | + */ | |
| 403 | +static void mmhub_v2_3_set_fault_enable_default(struct amdgpu_device *adev, | |
| 404 | + bool value) | |
| 405 | +{ | |
| 406 | + u32 tmp; | |
| 407 | + tmp = RREG32_SOC15(MMHUB, 0, mmMMVM_L2_PROTECTION_FAULT_CNTL); | |
| 408 | + tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL, | |
| 409 | + RANGE_PROTECTION_FAULT_ENABLE_DEFAULT, value); | |
| 410 | + tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL, | |
| 411 | + PDE0_PROTECTION_FAULT_ENABLE_DEFAULT, value); | |
| 412 | + tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL, | |
| 413 | + PDE1_PROTECTION_FAULT_ENABLE_DEFAULT, value); | |
| 414 | + tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL, | |
| 415 | + PDE2_PROTECTION_FAULT_ENABLE_DEFAULT, value); | |
| 416 | + tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL, | |
| 417 | + TRANSLATE_FURTHER_PROTECTION_FAULT_ENABLE_DEFAULT, | |
| 418 | + value); | |
| 419 | + tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL, | |
| 420 | + NACK_PROTECTION_FAULT_ENABLE_DEFAULT, value); | |
| 421 | + tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL, | |
| 422 | + DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT, value); | |
| 423 | + tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL, | |
| 424 | + VALID_PROTECTION_FAULT_ENABLE_DEFAULT, value); | |
| 425 | + tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL, | |
| 426 | + READ_PROTECTION_FAULT_ENABLE_DEFAULT, value); | |
| 427 | + tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL, | |
| 428 | + WRITE_PROTECTION_FAULT_ENABLE_DEFAULT, value); | |
| 429 | + tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL, | |
| 430 | + EXECUTE_PROTECTION_FAULT_ENABLE_DEFAULT, value); | |
| 431 | + if (!value) { | |
| 432 | + tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL, | |
| 433 | + CRASH_ON_NO_RETRY_FAULT, 1); | |
| 434 | + tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL, | |
| 435 | + CRASH_ON_RETRY_FAULT, 1); | |
| 436 | + } | |
| 437 | + WREG32_SOC15(MMHUB, 0, mmMMVM_L2_PROTECTION_FAULT_CNTL, tmp); | |
| 438 | +} | |
| 439 | + | |
| 440 | +static const struct amdgpu_vmhub_funcs mmhub_v2_3_vmhub_funcs = { | |
| 441 | + .print_l2_protection_fault_status = mmhub_v2_3_print_l2_protection_fault_status, | |
| 442 | + .get_invalidate_req = mmhub_v2_3_get_invalidate_req, | |
| 443 | +}; | |
| 444 | + | |
| 445 | +static void mmhub_v2_3_init(struct amdgpu_device *adev) | |
| 446 | +{ | |
| 447 | + struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_MMHUB_0]; | |
| 448 | + | |
| 449 | + hub->ctx0_ptb_addr_lo32 = | |
| 450 | + SOC15_REG_OFFSET(MMHUB, 0, | |
| 451 | + mmMMVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32); | |
| 452 | + hub->ctx0_ptb_addr_hi32 = | |
| 453 | + SOC15_REG_OFFSET(MMHUB, 0, | |
| 454 | + mmMMVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32); | |
| 455 | + hub->vm_inv_eng0_sem = | |
| 456 | + SOC15_REG_OFFSET(MMHUB, 0, | |
| 457 | + mmMMVM_INVALIDATE_ENG0_SEM); | |
| 458 | + hub->vm_inv_eng0_req = | |
| 459 | + SOC15_REG_OFFSET(MMHUB, 0, mmMMVM_INVALIDATE_ENG0_REQ); | |
| 460 | + hub->vm_inv_eng0_ack = | |
| 461 | + SOC15_REG_OFFSET(MMHUB, 0, mmMMVM_INVALIDATE_ENG0_ACK); | |
| 462 | + hub->vm_context0_cntl = | |
| 463 | + SOC15_REG_OFFSET(MMHUB, 0, mmMMVM_CONTEXT0_CNTL); | |
| 464 | + hub->vm_l2_pro_fault_status = | |
| 465 | + SOC15_REG_OFFSET(MMHUB, 0, mmMMVM_L2_PROTECTION_FAULT_STATUS); | |
| 466 | + hub->vm_l2_pro_fault_cntl = | |
| 467 | + SOC15_REG_OFFSET(MMHUB, 0, mmMMVM_L2_PROTECTION_FAULT_CNTL); | |
| 468 | + | |
| 469 | + hub->ctx_distance = mmMMVM_CONTEXT1_CNTL - mmMMVM_CONTEXT0_CNTL; | |
| 470 | + hub->ctx_addr_distance = mmMMVM_CONTEXT1_PAGE_TABLE_BASE_ADDR_LO32 - | |
| 471 | + mmMMVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32; | |
| 472 | + hub->eng_distance = mmMMVM_INVALIDATE_ENG1_REQ - | |
| 473 | + mmMMVM_INVALIDATE_ENG0_REQ; | |
| 474 | + hub->eng_addr_distance = mmMMVM_INVALIDATE_ENG1_ADDR_RANGE_LO32 - | |
| 475 | + mmMMVM_INVALIDATE_ENG0_ADDR_RANGE_LO32; | |
| 476 | + | |
| 477 | + hub->vm_cntx_cntl_vm_fault = MMVM_CONTEXT1_CNTL__RANGE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK | | |
| 478 | + MMVM_CONTEXT1_CNTL__DUMMY_PAGE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK | | |
| 479 | + MMVM_CONTEXT1_CNTL__PDE0_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK | | |
| 480 | + MMVM_CONTEXT1_CNTL__VALID_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK | | |
| 481 | + MMVM_CONTEXT1_CNTL__READ_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK | | |
| 482 | + MMVM_CONTEXT1_CNTL__WRITE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK | | |
| 483 | + MMVM_CONTEXT1_CNTL__EXECUTE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK; | |
| 484 | + | |
| 485 | + hub->vmhub_funcs = &mmhub_v2_3_vmhub_funcs; | |
| 486 | +} | |
| 487 | + | |
| 488 | +static void | |
| 489 | +mmhub_v2_3_update_medium_grain_clock_gating(struct amdgpu_device *adev, | |
| 490 | + bool enable) | |
| 491 | +{ | |
| 492 | + uint32_t def, data, def1, data1; | |
| 493 | + | |
| 494 | + def = data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG); | |
| 495 | + def1 = data1 = RREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2); | |
| 496 | + | |
| 497 | + if (enable && (adev->cg_flags & AMD_CG_SUPPORT_MC_MGCG)) { | |
| 498 | + data |= MM_ATC_L2_MISC_CG__ENABLE_MASK; | |
| 499 | + | |
| 500 | + data1 &= ~(DAGB0_CNTL_MISC2__DISABLE_WRREQ_CG_MASK | | |
| 501 | + DAGB0_CNTL_MISC2__DISABLE_WRRET_CG_MASK | | |
| 502 | + DAGB0_CNTL_MISC2__DISABLE_RDREQ_CG_MASK | | |
| 503 | + DAGB0_CNTL_MISC2__DISABLE_RDRET_CG_MASK | | |
| 504 | + DAGB0_CNTL_MISC2__DISABLE_TLBWR_CG_MASK | | |
| 505 | + DAGB0_CNTL_MISC2__DISABLE_TLBRD_CG_MASK); | |
| 506 | + | |
| 507 | + } else { | |
| 508 | + data &= ~MM_ATC_L2_MISC_CG__ENABLE_MASK; | |
| 509 | + | |
| 510 | + data1 |= (DAGB0_CNTL_MISC2__DISABLE_WRREQ_CG_MASK | | |
| 511 | + DAGB0_CNTL_MISC2__DISABLE_WRRET_CG_MASK | | |
| 512 | + DAGB0_CNTL_MISC2__DISABLE_RDREQ_CG_MASK | | |
| 513 | + DAGB0_CNTL_MISC2__DISABLE_RDRET_CG_MASK | | |
| 514 | + DAGB0_CNTL_MISC2__DISABLE_TLBWR_CG_MASK | | |
| 515 | + DAGB0_CNTL_MISC2__DISABLE_TLBRD_CG_MASK); | |
| 516 | + } | |
| 517 | + | |
| 518 | + if (def != data) | |
| 519 | + WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG, data); | |
| 520 | + if (def1 != data1) | |
| 521 | + WREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2, data1); | |
| 522 | +} | |
| 523 | + | |
| 524 | +static void | |
| 525 | +mmhub_v2_3_update_medium_grain_light_sleep(struct amdgpu_device *adev, | |
| 526 | + bool enable) | |
| 527 | +{ | |
| 528 | + uint32_t def, data; | |
| 529 | + | |
| 530 | + def = data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG); | |
| 531 | + | |
| 532 | + if (enable && (adev->cg_flags & AMD_CG_SUPPORT_MC_LS)) | |
| 533 | + data |= MM_ATC_L2_MISC_CG__MEM_LS_ENABLE_MASK; | |
| 534 | + else | |
| 535 | + data &= ~MM_ATC_L2_MISC_CG__MEM_LS_ENABLE_MASK; | |
| 536 | + | |
| 537 | + if (def != data) | |
| 538 | + WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG, data); | |
| 539 | +} | |
| 540 | + | |
| 541 | +static int mmhub_v2_3_set_clockgating(struct amdgpu_device *adev, | |
| 542 | + enum amd_clockgating_state state) | |
| 543 | +{ | |
| 544 | + if (amdgpu_sriov_vf(adev)) | |
| 545 | + return 0; | |
| 546 | + | |
| 547 | + mmhub_v2_3_update_medium_grain_clock_gating(adev, | |
| 548 | + state == AMD_CG_STATE_GATE ? true : false); | |
| 549 | + mmhub_v2_3_update_medium_grain_light_sleep(adev, | |
| 550 | + state == AMD_CG_STATE_GATE ? true : false); | |
| 551 | + | |
| 552 | + return 0; | |
| 553 | +} | |
| 554 | + | |
| 555 | +static void mmhub_v2_3_get_clockgating(struct amdgpu_device *adev, u32 *flags) | |
| 556 | +{ | |
| 557 | + int data, data1; | |
| 558 | + | |
| 559 | + if (amdgpu_sriov_vf(adev)) | |
| 560 | + *flags = 0; | |
| 561 | + | |
| 562 | + data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG); | |
| 563 | + data1 = RREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2); | |
| 564 | + | |
| 565 | + /* AMD_CG_SUPPORT_MC_MGCG */ | |
| 566 | + if ((data & MM_ATC_L2_MISC_CG__ENABLE_MASK) && | |
| 567 | + !(data1 & (DAGB0_CNTL_MISC2__DISABLE_WRREQ_CG_MASK | | |
| 568 | + DAGB0_CNTL_MISC2__DISABLE_WRRET_CG_MASK | | |
| 569 | + DAGB0_CNTL_MISC2__DISABLE_RDREQ_CG_MASK | | |
| 570 | + DAGB0_CNTL_MISC2__DISABLE_RDRET_CG_MASK | | |
| 571 | + DAGB0_CNTL_MISC2__DISABLE_TLBWR_CG_MASK | | |
| 572 | + DAGB0_CNTL_MISC2__DISABLE_TLBRD_CG_MASK))) | |
| 573 | + *flags |= AMD_CG_SUPPORT_MC_MGCG; | |
| 574 | + | |
| 575 | + /* AMD_CG_SUPPORT_MC_LS */ | |
| 576 | + if (data & MM_ATC_L2_MISC_CG__MEM_LS_ENABLE_MASK) | |
| 577 | + *flags |= AMD_CG_SUPPORT_MC_LS; | |
| 578 | +} | |
| 579 | + | |
| 580 | +const struct amdgpu_mmhub_funcs mmhub_v2_3_funcs = { | |
| 581 | + .ras_late_init = amdgpu_mmhub_ras_late_init, | |
| 582 | + .init = mmhub_v2_3_init, | |
| 583 | + .gart_enable = mmhub_v2_3_gart_enable, | |
| 584 | + .set_fault_enable_default = mmhub_v2_3_set_fault_enable_default, | |
| 585 | + .gart_disable = mmhub_v2_3_gart_disable, | |
| 586 | + .set_clockgating = mmhub_v2_3_set_clockgating, | |
| 587 | + .get_clockgating = mmhub_v2_3_get_clockgating, | |
| 588 | + .setup_vm_pt_regs = mmhub_v2_3_setup_vm_pt_regs, | |
| 589 | +}; | |
| @@ -0,0 +1,28 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2019 Advanced Micro Devices, Inc. | |
| 3 | + * | |
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a | |
| 5 | + * copy of this software and associated documentation files (the "Software"), | |
| 6 | + * to deal in the Software without restriction, including without limitation | |
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the | |
| 9 | + * Software is furnished to do so, subject to the following conditions: | |
| 10 | + * | |
| 11 | + * The above copyright notice and this permission notice shall be included in | |
| 12 | + * all copies or substantial portions of the Software. | |
| 13 | + * | |
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 17 | + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 18 | + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 19 | + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 20 | + * OTHER DEALINGS IN THE SOFTWARE. | |
| 21 | + * | |
| 22 | + */ | |
| 23 | +#ifndef __MMHUB_V2_3_H__ | |
| 24 | +#define __MMHUB_V2_3_H__ | |
| 25 | + | |
| 26 | +extern const struct amdgpu_mmhub_funcs mmhub_v2_3_funcs; | |
| 27 | + | |
| 28 | +#endif | |
| @@ -314,6 +314,8 @@ static int navi10_ih_irq_init(struct amdgpu_device *adev) · 313 unmodified lines | ||
| 314 | 314 | switch (adev->asic_type) { |
| 315 | 315 | case CHIP_SIENNA_CICHLID: |
| 316 | 316 | case CHIP_NAVY_FLOUNDER: |
| 317 | + case CHIP_VANGOGH: | |
| 318 | + case CHIP_DIMGREY_CAVEFISH: | |
| 317 | 319 | ih_chicken = RREG32_SOC15(OSSSYS, 0, mmIH_CHICKEN_Sienna_Cichlid); |
| 318 | 320 | ih_chicken = REG_SET_FIELD(ih_chicken, |
| 319 | 321 | IH_CHICKEN, MC_SPACE_GPA_ENABLE, 1); |
| @@ -660,8 +662,11 @@ static int navi10_ih_sw_init(void *handle) · 340 unmodified lines | ||
| 660 | 662 | /* use gpu virtual address for ih ring |
| 661 | 663 | * until ih_checken is programmed to allow |
| 662 | 664 | * use bus address for ih ring by psp bl */ |
| 663 | − use_bus_addr = | |
| 664 | − (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) ? false : true; | |
| 665 | + if ((adev->flags & AMD_IS_APU) || | |
| 666 | + (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) | |
| 667 | + use_bus_addr = false; | |
| 668 | + else | |
| 669 | + use_bus_addr = true; | |
| 665 | 670 | r = amdgpu_ih_ring_init(adev, &adev->irq.ih, 256 * 1024, use_bus_addr); |
| 666 | 671 | if (r) |
| 667 | 672 | return r; |
| @@ -28,10 +28,12 @@ · 27 unmodified lines | ||
| 28 | 28 | #include "nbio/nbio_2_3_offset.h" |
| 29 | 29 | #include "nbio/nbio_2_3_sh_mask.h" |
| 30 | 30 | #include <uapi/linux/kfd_ioctl.h> |
| 31 | +#include <linux/pci.h> | |
| 31 | 32 | |
| 32 | 33 | #define smnPCIE_CONFIG_CNTL 0x11180044 |
| 33 | 34 | #define smnCPM_CONTROL 0x11180460 |
| 34 | 35 | #define smnPCIE_CNTL2 0x11180070 |
| 36 | +#define smnPCIE_LC_CNTL 0x11140280 | |
| 35 | 37 | |
| 36 | 38 | #define mmBIF_SDMA2_DOORBELL_RANGE 0x01d6 |
| 37 | 39 | #define mmBIF_SDMA2_DOORBELL_RANGE_BASE_IDX 2 |
| @@ -312,6 +314,42 @@ static void nbio_v2_3_init_registers(struct amdgpu_device *adev) · 274 unmodified lines | ||
| 312 | 314 | WREG32_PCIE(smnPCIE_CONFIG_CNTL, data); |
| 313 | 315 | } |
| 314 | 316 | |
| 317 | +#define NAVI10_PCIE__LC_L0S_INACTIVITY_DEFAULT 0x00000000 // off by default, no gains over L1 | |
| 318 | +#define NAVI10_PCIE__LC_L1_INACTIVITY_DEFAULT 0x00000009 // 1=1us, 9=1ms | |
| 319 | +#define NAVI10_PCIE__LC_L1_INACTIVITY_TBT_DEFAULT 0x0000000E // 4ms | |
| 320 | + | |
| 321 | +static void nbio_v2_3_enable_aspm(struct amdgpu_device *adev, | |
| 322 | + bool enable) | |
| 323 | +{ | |
| 324 | + uint32_t def, data; | |
| 325 | + | |
| 326 | + def = data = RREG32_PCIE(smnPCIE_LC_CNTL); | |
| 327 | + | |
| 328 | + if (enable) { | |
| 329 | + /* Disable ASPM L0s/L1 first */ | |
| 330 | + data &= ~(PCIE_LC_CNTL__LC_L0S_INACTIVITY_MASK | PCIE_LC_CNTL__LC_L1_INACTIVITY_MASK); | |
| 331 | + | |
| 332 | + data |= NAVI10_PCIE__LC_L0S_INACTIVITY_DEFAULT << PCIE_LC_CNTL__LC_L0S_INACTIVITY__SHIFT; | |
| 333 | + | |
| 334 | + if (pci_is_thunderbolt_attached(adev->pdev)) | |
| 335 | + data |= NAVI10_PCIE__LC_L1_INACTIVITY_TBT_DEFAULT << PCIE_LC_CNTL__LC_L1_INACTIVITY__SHIFT; | |
| 336 | + else | |
| 337 | + data |= NAVI10_PCIE__LC_L1_INACTIVITY_DEFAULT << PCIE_LC_CNTL__LC_L1_INACTIVITY__SHIFT; | |
| 338 | + | |
| 339 | + data &= ~PCIE_LC_CNTL__LC_PMI_TO_L1_DIS_MASK; | |
| 340 | + } else { | |
| 341 | + /* Disbale ASPM L1 */ | |
| 342 | + data &= ~PCIE_LC_CNTL__LC_L1_INACTIVITY_MASK; | |
| 343 | + /* Disable ASPM TxL0s */ | |
| 344 | + data &= ~PCIE_LC_CNTL__LC_L0S_INACTIVITY_MASK; | |
| 345 | + /* Disable ACPI L1 */ | |
| 346 | + data |= PCIE_LC_CNTL__LC_PMI_TO_L1_DIS_MASK; | |
| 347 | + } | |
| 348 | + | |
| 349 | + if (def != data) | |
| 350 | + WREG32_PCIE(smnPCIE_LC_CNTL, data); | |
| 351 | +} | |
| 352 | + | |
| 315 | 353 | const struct amdgpu_nbio_funcs nbio_v2_3_funcs = { |
| 316 | 354 | .get_hdp_flush_req_offset = nbio_v2_3_get_hdp_flush_req_offset, |
| 317 | 355 | .get_hdp_flush_done_offset = nbio_v2_3_get_hdp_flush_done_offset, |
| @@ -332,4 +370,5 @@ const struct amdgpu_nbio_funcs nbio_v2_3_funcs = { · 14 unmodified lines | ||
| 332 | 370 | .ih_control = nbio_v2_3_ih_control, |
| 333 | 371 | .init_registers = nbio_v2_3_init_registers, |
| 334 | 372 | .remap_hdp_registers = nbio_v2_3_remap_hdp_registers, |
| 373 | + .enable_aspm = nbio_v2_3_enable_aspm, | |
| 335 | 374 | }; |
| @@ -32,7 +32,7 @@ · 31 unmodified lines | ||
| 32 | 32 | |
| 33 | 33 | static u32 nbio_v6_1_get_rev_id(struct amdgpu_device *adev) |
| 34 | 34 | { |
| 35 | − u32 tmp = RREG32_SOC15(NBIO, 0, mmRCC_DEV0_EPF0_STRAP0); | |
| 35 | + u32 tmp = RREG32_SOC15(NBIO, 0, mmRCC_DEV0_EPF0_STRAP0); | |
| 36 | 36 | |
| 37 | 37 | tmp &= RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0_MASK; |
| 38 | 38 | tmp >>= RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0__SHIFT; |
| @@ -114,7 +114,7 @@ static void nbio_v6_1_enable_doorbell_selfring_aperture(struct amdgpu_device *ad · 75 unmodified lines | ||
| 114 | 114 | static void nbio_v6_1_ih_doorbell_range(struct amdgpu_device *adev, |
| 115 | 115 | bool use_doorbell, int doorbell_index) |
| 116 | 116 | { |
| 117 | − u32 ih_doorbell_range = RREG32_SOC15(NBIO, 0 , mmBIF_IH_DOORBELL_RANGE); | |
| 117 | + u32 ih_doorbell_range = RREG32_SOC15(NBIO, 0, mmBIF_IH_DOORBELL_RANGE); | |
| 118 | 118 | |
| 119 | 119 | if (use_doorbell) { |
| 120 | 120 | ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range, BIF_IH_DOORBELL_RANGE, OFFSET, doorbell_index); |
| @@ -43,7 +43,7 @@ static void nbio_v7_0_remap_hdp_registers(struct amdgpu_device *adev) · 42 unmodified lines | ||
| 43 | 43 | |
| 44 | 44 | static u32 nbio_v7_0_get_rev_id(struct amdgpu_device *adev) |
| 45 | 45 | { |
| 46 | − u32 tmp = RREG32_SOC15(NBIO, 0, mmRCC_DEV0_EPF0_STRAP0); | |
| 46 | + u32 tmp = RREG32_SOC15(NBIO, 0, mmRCC_DEV0_EPF0_STRAP0); | |
| 47 | 47 | |
| 48 | 48 | tmp &= RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0_MASK; |
| 49 | 49 | tmp >>= RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0__SHIFT; |
| @@ -126,7 +126,7 @@ static void nbio_v7_0_enable_doorbell_selfring_aperture(struct amdgpu_device *ad · 76 unmodified lines | ||
| 126 | 126 | static void nbio_v7_0_ih_doorbell_range(struct amdgpu_device *adev, |
| 127 | 127 | bool use_doorbell, int doorbell_index) |
| 128 | 128 | { |
| 129 | − u32 ih_doorbell_range = RREG32_SOC15(NBIO, 0 , mmBIF_IH_DOORBELL_RANGE); | |
| 129 | + u32 ih_doorbell_range = RREG32_SOC15(NBIO, 0, mmBIF_IH_DOORBELL_RANGE); | |
| 130 | 130 | |
| 131 | 131 | if (use_doorbell) { |
| 132 | 132 | ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range, BIF_IH_DOORBELL_RANGE, OFFSET, doorbell_index); |
| @@ -0,0 +1,341 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2020 Advanced Micro Devices, Inc. | |
| 3 | + * | |
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a | |
| 5 | + * copy of this software and associated documentation files (the "Software"), | |
| 6 | + * to deal in the Software without restriction, including without limitation | |
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the | |
| 9 | + * Software is furnished to do so, subject to the following conditions: | |
| 10 | + * | |
| 11 | + * The above copyright notice and this permission notice shall be included in | |
| 12 | + * all copies or substantial portions of the Software. | |
| 13 | + * | |
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 17 | + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 18 | + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 19 | + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 20 | + * OTHER DEALINGS IN THE SOFTWARE. | |
| 21 | + * | |
| 22 | + */ | |
| 23 | +#include "amdgpu.h" | |
| 24 | +#include "amdgpu_atombios.h" | |
| 25 | +#include "nbio_v7_2.h" | |
| 26 | + | |
| 27 | +#include "nbio/nbio_7_2_0_offset.h" | |
| 28 | +#include "nbio/nbio_7_2_0_sh_mask.h" | |
| 29 | +#include <uapi/linux/kfd_ioctl.h> | |
| 30 | + | |
| 31 | +static void nbio_v7_2_remap_hdp_registers(struct amdgpu_device *adev) | |
| 32 | +{ | |
| 33 | + WREG32_SOC15(NBIO, 0, regBIF_BX0_REMAP_HDP_MEM_FLUSH_CNTL, | |
| 34 | + adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL); | |
| 35 | + WREG32_SOC15(NBIO, 0, regBIF_BX0_REMAP_HDP_REG_FLUSH_CNTL, | |
| 36 | + adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_REG_FLUSH_CNTL); | |
| 37 | +} | |
| 38 | + | |
| 39 | +static u32 nbio_v7_2_get_rev_id(struct amdgpu_device *adev) | |
| 40 | +{ | |
| 41 | + u32 tmp = RREG32_SOC15(NBIO, 0, regRCC_STRAP0_RCC_DEV0_EPF0_STRAP0); | |
| 42 | + | |
| 43 | + tmp &= RCC_STRAP0_RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0_MASK; | |
| 44 | + tmp >>= RCC_STRAP0_RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0__SHIFT; | |
| 45 | + | |
| 46 | + return tmp; | |
| 47 | +} | |
| 48 | + | |
| 49 | +static void nbio_v7_2_mc_access_enable(struct amdgpu_device *adev, bool enable) | |
| 50 | +{ | |
| 51 | + if (enable) | |
| 52 | + WREG32_SOC15(NBIO, 0, regBIF_BX0_BIF_FB_EN, | |
| 53 | + BIF_BX0_BIF_FB_EN__FB_READ_EN_MASK | | |
| 54 | + BIF_BX0_BIF_FB_EN__FB_WRITE_EN_MASK); | |
| 55 | + else | |
| 56 | + WREG32_SOC15(NBIO, 0, regBIF_BX0_BIF_FB_EN, 0); | |
| 57 | +} | |
| 58 | + | |
| 59 | +static void nbio_v7_2_hdp_flush(struct amdgpu_device *adev, | |
| 60 | + struct amdgpu_ring *ring) | |
| 61 | +{ | |
| 62 | + if (!ring || !ring->funcs->emit_wreg) | |
| 63 | + WREG32_NO_KIQ((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0); | |
| 64 | + else | |
| 65 | + amdgpu_ring_emit_wreg(ring, (adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0); | |
| 66 | +} | |
| 67 | + | |
| 68 | +static u32 nbio_v7_2_get_memsize(struct amdgpu_device *adev) | |
| 69 | +{ | |
| 70 | + return RREG32_SOC15(NBIO, 0, regRCC_DEV0_EPF0_0_RCC_CONFIG_MEMSIZE); | |
| 71 | +} | |
| 72 | + | |
| 73 | +static void nbio_v7_2_sdma_doorbell_range(struct amdgpu_device *adev, int instance, | |
| 74 | + bool use_doorbell, int doorbell_index, | |
| 75 | + int doorbell_size) | |
| 76 | +{ | |
| 77 | + u32 reg = SOC15_REG_OFFSET(NBIO, 0, regGDC0_BIF_SDMA0_DOORBELL_RANGE); | |
| 78 | + u32 doorbell_range = RREG32_PCIE_PORT(reg); | |
| 79 | + | |
| 80 | + if (use_doorbell) { | |
| 81 | + doorbell_range = REG_SET_FIELD(doorbell_range, | |
| 82 | + GDC0_BIF_SDMA0_DOORBELL_RANGE, | |
| 83 | + OFFSET, doorbell_index); | |
| 84 | + doorbell_range = REG_SET_FIELD(doorbell_range, | |
| 85 | + GDC0_BIF_SDMA0_DOORBELL_RANGE, | |
| 86 | + SIZE, doorbell_size); | |
| 87 | + } else { | |
| 88 | + doorbell_range = REG_SET_FIELD(doorbell_range, | |
| 89 | + GDC0_BIF_SDMA0_DOORBELL_RANGE, | |
| 90 | + SIZE, 0); | |
| 91 | + } | |
| 92 | + | |
| 93 | + WREG32_PCIE_PORT(reg, doorbell_range); | |
| 94 | +} | |
| 95 | + | |
| 96 | +static void nbio_v7_2_vcn_doorbell_range(struct amdgpu_device *adev, bool use_doorbell, | |
| 97 | + int doorbell_index, int instance) | |
| 98 | +{ | |
| 99 | + u32 reg = SOC15_REG_OFFSET(NBIO, 0, regGDC0_BIF_VCN0_DOORBELL_RANGE); | |
| 100 | + u32 doorbell_range = RREG32_PCIE_PORT(reg); | |
| 101 | + | |
| 102 | + if (use_doorbell) { | |
| 103 | + doorbell_range = REG_SET_FIELD(doorbell_range, | |
| 104 | + GDC0_BIF_VCN0_DOORBELL_RANGE, OFFSET, | |
| 105 | + doorbell_index); | |
| 106 | + doorbell_range = REG_SET_FIELD(doorbell_range, | |
| 107 | + GDC0_BIF_VCN0_DOORBELL_RANGE, SIZE, 8); | |
| 108 | + } else { | |
| 109 | + doorbell_range = REG_SET_FIELD(doorbell_range, | |
| 110 | + GDC0_BIF_VCN0_DOORBELL_RANGE, SIZE, 0); | |
| 111 | + } | |
| 112 | + | |
| 113 | + WREG32_PCIE_PORT(reg, doorbell_range); | |
| 114 | +} | |
| 115 | + | |
| 116 | +static void nbio_v7_2_enable_doorbell_aperture(struct amdgpu_device *adev, | |
| 117 | + bool enable) | |
| 118 | +{ | |
| 119 | + u32 reg; | |
| 120 | + | |
| 121 | + reg = RREG32_SOC15(NBIO, 0, regRCC_DEV0_EPF0_0_RCC_DOORBELL_APER_EN); | |
| 122 | + reg = REG_SET_FIELD(reg, RCC_DEV0_EPF0_0_RCC_DOORBELL_APER_EN, | |
| 123 | + BIF_DOORBELL_APER_EN, enable ? 1 : 0); | |
| 124 | + | |
| 125 | + WREG32_SOC15(NBIO, 0, regRCC_DEV0_EPF0_0_RCC_DOORBELL_APER_EN, reg); | |
| 126 | +} | |
| 127 | + | |
| 128 | +static void nbio_v7_2_enable_doorbell_selfring_aperture(struct amdgpu_device *adev, | |
| 129 | + bool enable) | |
| 130 | +{ | |
| 131 | + u32 tmp = 0; | |
| 132 | + | |
| 133 | + if (enable) { | |
| 134 | + tmp = REG_SET_FIELD(tmp, BIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_CNTL, | |
| 135 | + DOORBELL_SELFRING_GPA_APER_EN, 1) | | |
| 136 | + REG_SET_FIELD(tmp, BIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_CNTL, | |
| 137 | + DOORBELL_SELFRING_GPA_APER_MODE, 1) | | |
| 138 | + REG_SET_FIELD(tmp, BIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_CNTL, | |
| 139 | + DOORBELL_SELFRING_GPA_APER_SIZE, 0); | |
| 140 | + | |
| 141 | + WREG32_SOC15(NBIO, 0, | |
| 142 | + regBIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_BASE_LOW, | |
| 143 | + lower_32_bits(adev->doorbell.base)); | |
| 144 | + WREG32_SOC15(NBIO, 0, | |
| 145 | + regBIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_BASE_HIGH, | |
| 146 | + upper_32_bits(adev->doorbell.base)); | |
| 147 | + } | |
| 148 | + | |
| 149 | + WREG32_SOC15(NBIO, 0, regBIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_CNTL, | |
| 150 | + tmp); | |
| 151 | +} | |
| 152 | + | |
| 153 | + | |
| 154 | +static void nbio_v7_2_ih_doorbell_range(struct amdgpu_device *adev, | |
| 155 | + bool use_doorbell, int doorbell_index) | |
| 156 | +{ | |
| 157 | + u32 ih_doorbell_range = RREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regGDC0_BIF_IH_DOORBELL_RANGE)); | |
| 158 | + | |
| 159 | + if (use_doorbell) { | |
| 160 | + ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range, | |
| 161 | + GDC0_BIF_IH_DOORBELL_RANGE, OFFSET, | |
| 162 | + doorbell_index); | |
| 163 | + ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range, | |
| 164 | + GDC0_BIF_IH_DOORBELL_RANGE, SIZE, | |
| 165 | + 2); | |
| 166 | + } else { | |
| 167 | + ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range, | |
| 168 | + GDC0_BIF_IH_DOORBELL_RANGE, SIZE, | |
| 169 | + 0); | |
| 170 | + } | |
| 171 | + | |
| 172 | + WREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regGDC0_BIF_IH_DOORBELL_RANGE), | |
| 173 | + ih_doorbell_range); | |
| 174 | +} | |
| 175 | + | |
| 176 | +static void nbio_v7_2_ih_control(struct amdgpu_device *adev) | |
| 177 | +{ | |
| 178 | + u32 interrupt_cntl; | |
| 179 | + | |
| 180 | + /* setup interrupt control */ | |
| 181 | + WREG32_SOC15(NBIO, 0, regBIF_BX0_INTERRUPT_CNTL2, | |
| 182 | + adev->dummy_page_addr >> 8); | |
| 183 | + | |
| 184 | + interrupt_cntl = RREG32_SOC15(NBIO, 0, regBIF_BX0_INTERRUPT_CNTL); | |
| 185 | + /* | |
| 186 | + * INTERRUPT_CNTL__IH_DUMMY_RD_OVERRIDE_MASK=0 - dummy read disabled with msi, enabled without msi | |
| 187 | + * INTERRUPT_CNTL__IH_DUMMY_RD_OVERRIDE_MASK=1 - dummy read controlled by IH_DUMMY_RD_EN | |
| 188 | + */ | |
| 189 | + interrupt_cntl = REG_SET_FIELD(interrupt_cntl, BIF_BX0_INTERRUPT_CNTL, | |
| 190 | + IH_DUMMY_RD_OVERRIDE, 0); | |
| 191 | + | |
| 192 | + /* INTERRUPT_CNTL__IH_REQ_NONSNOOP_EN_MASK=1 if ring is in non-cacheable memory, e.g., vram */ | |
| 193 | + interrupt_cntl = REG_SET_FIELD(interrupt_cntl, BIF_BX0_INTERRUPT_CNTL, | |
| 194 | + IH_REQ_NONSNOOP_EN, 0); | |
| 195 | + | |
| 196 | + WREG32_SOC15(NBIO, 0, regBIF_BX0_INTERRUPT_CNTL, interrupt_cntl); | |
| 197 | +} | |
| 198 | + | |
| 199 | +static void nbio_v7_2_update_medium_grain_clock_gating(struct amdgpu_device *adev, | |
| 200 | + bool enable) | |
| 201 | +{ | |
| 202 | + uint32_t def, data; | |
| 203 | + | |
| 204 | + def = data = RREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regCPM_CONTROL)); | |
| 205 | + if (enable && (adev->cg_flags & AMD_CG_SUPPORT_BIF_MGCG)) { | |
| 206 | + data |= (CPM_CONTROL__LCLK_DYN_GATE_ENABLE_MASK | | |
| 207 | + CPM_CONTROL__TXCLK_DYN_GATE_ENABLE_MASK | | |
| 208 | + CPM_CONTROL__TXCLK_LCNT_GATE_ENABLE_MASK | | |
| 209 | + CPM_CONTROL__TXCLK_REGS_GATE_ENABLE_MASK | | |
| 210 | + CPM_CONTROL__TXCLK_PRBS_GATE_ENABLE_MASK | | |
| 211 | + CPM_CONTROL__REFCLK_REGS_GATE_ENABLE_MASK); | |
| 212 | + } else { | |
| 213 | + data &= ~(CPM_CONTROL__LCLK_DYN_GATE_ENABLE_MASK | | |
| 214 | + CPM_CONTROL__TXCLK_DYN_GATE_ENABLE_MASK | | |
| 215 | + CPM_CONTROL__TXCLK_LCNT_GATE_ENABLE_MASK | | |
| 216 | + CPM_CONTROL__TXCLK_REGS_GATE_ENABLE_MASK | | |
| 217 | + CPM_CONTROL__TXCLK_PRBS_GATE_ENABLE_MASK | | |
| 218 | + CPM_CONTROL__REFCLK_REGS_GATE_ENABLE_MASK); | |
| 219 | + } | |
| 220 | + | |
| 221 | + if (def != data) | |
| 222 | + WREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regCPM_CONTROL), data); | |
| 223 | +} | |
| 224 | + | |
| 225 | +static void nbio_v7_2_update_medium_grain_light_sleep(struct amdgpu_device *adev, | |
| 226 | + bool enable) | |
| 227 | +{ | |
| 228 | + uint32_t def, data; | |
| 229 | + | |
| 230 | + def = data = RREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regPCIE_CNTL2)); | |
| 231 | + if (enable && (adev->cg_flags & AMD_CG_SUPPORT_BIF_LS)) { | |
| 232 | + data |= (PCIE_CNTL2__SLV_MEM_LS_EN_MASK | | |
| 233 | + PCIE_CNTL2__MST_MEM_LS_EN_MASK | | |
| 234 | + PCIE_CNTL2__REPLAY_MEM_LS_EN_MASK); | |
| 235 | + } else { | |
| 236 | + data &= ~(PCIE_CNTL2__SLV_MEM_LS_EN_MASK | | |
| 237 | + PCIE_CNTL2__MST_MEM_LS_EN_MASK | | |
| 238 | + PCIE_CNTL2__REPLAY_MEM_LS_EN_MASK); | |
| 239 | + } | |
| 240 | + | |
| 241 | + if (def != data) | |
| 242 | + WREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regPCIE_CNTL2), data); | |
| 243 | +} | |
| 244 | + | |
| 245 | +static void nbio_v7_2_get_clockgating_state(struct amdgpu_device *adev, | |
| 246 | + u32 *flags) | |
| 247 | +{ | |
| 248 | + int data; | |
| 249 | + | |
| 250 | + /* AMD_CG_SUPPORT_BIF_MGCG */ | |
| 251 | + data = RREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regCPM_CONTROL)); | |
| 252 | + if (data & CPM_CONTROL__LCLK_DYN_GATE_ENABLE_MASK) | |
| 253 | + *flags |= AMD_CG_SUPPORT_BIF_MGCG; | |
| 254 | + | |
| 255 | + /* AMD_CG_SUPPORT_BIF_LS */ | |
| 256 | + data = RREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regPCIE_CNTL2)); | |
| 257 | + if (data & PCIE_CNTL2__SLV_MEM_LS_EN_MASK) | |
| 258 | + *flags |= AMD_CG_SUPPORT_BIF_LS; | |
| 259 | +} | |
| 260 | + | |
| 261 | +static u32 nbio_v7_2_get_hdp_flush_req_offset(struct amdgpu_device *adev) | |
| 262 | +{ | |
| 263 | + return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX_PF0_GPU_HDP_FLUSH_REQ); | |
| 264 | +} | |
| 265 | + | |
| 266 | +static u32 nbio_v7_2_get_hdp_flush_done_offset(struct amdgpu_device *adev) | |
| 267 | +{ | |
| 268 | + return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX_PF0_GPU_HDP_FLUSH_DONE); | |
| 269 | +} | |
| 270 | + | |
| 271 | +static u32 nbio_v7_2_get_pcie_index_offset(struct amdgpu_device *adev) | |
| 272 | +{ | |
| 273 | + return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX0_PCIE_INDEX2); | |
| 274 | +} | |
| 275 | + | |
| 276 | +static u32 nbio_v7_2_get_pcie_data_offset(struct amdgpu_device *adev) | |
| 277 | +{ | |
| 278 | + return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX0_PCIE_DATA2); | |
| 279 | +} | |
| 280 | + | |
| 281 | +static u32 nbio_v7_2_get_pcie_port_index_offset(struct amdgpu_device *adev) | |
| 282 | +{ | |
| 283 | + return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX_PF0_RSMU_INDEX); | |
| 284 | +} | |
| 285 | + | |
| 286 | +static u32 nbio_v7_2_get_pcie_port_data_offset(struct amdgpu_device *adev) | |
| 287 | +{ | |
| 288 | + return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX_PF0_RSMU_DATA); | |
| 289 | +} | |
| 290 | + | |
| 291 | +const struct nbio_hdp_flush_reg nbio_v7_2_hdp_flush_reg = { | |
| 292 | + .ref_and_mask_cp0 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP0_MASK, | |
| 293 | + .ref_and_mask_cp1 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP1_MASK, | |
| 294 | + .ref_and_mask_cp2 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP2_MASK, | |
| 295 | + .ref_and_mask_cp3 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP3_MASK, | |
| 296 | + .ref_and_mask_cp4 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP4_MASK, | |
| 297 | + .ref_and_mask_cp5 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP5_MASK, | |
| 298 | + .ref_and_mask_cp6 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP6_MASK, | |
| 299 | + .ref_and_mask_cp7 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP7_MASK, | |
| 300 | + .ref_and_mask_cp8 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP8_MASK, | |
| 301 | + .ref_and_mask_cp9 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP9_MASK, | |
| 302 | + .ref_and_mask_sdma0 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__SDMA0_MASK, | |
| 303 | + .ref_and_mask_sdma1 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__SDMA1_MASK, | |
| 304 | +}; | |
| 305 | + | |
| 306 | +static void nbio_v7_2_init_registers(struct amdgpu_device *adev) | |
| 307 | +{ | |
| 308 | + uint32_t def, data; | |
| 309 | + | |
| 310 | + def = data = RREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regPCIE_CONFIG_CNTL)); | |
| 311 | + data = REG_SET_FIELD(data, PCIE_CONFIG_CNTL, CI_SWUS_MAX_READ_REQUEST_SIZE_MODE, 1); | |
| 312 | + data = REG_SET_FIELD(data, PCIE_CONFIG_CNTL, CI_SWUS_MAX_READ_REQUEST_SIZE_PRIV, 1); | |
| 313 | + | |
| 314 | + if (def != data) | |
| 315 | + WREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regPCIE_CONFIG_CNTL), | |
| 316 | + data); | |
| 317 | +} | |
| 318 | + | |
| 319 | +const struct amdgpu_nbio_funcs nbio_v7_2_funcs = { | |
| 320 | + .get_hdp_flush_req_offset = nbio_v7_2_get_hdp_flush_req_offset, | |
| 321 | + .get_hdp_flush_done_offset = nbio_v7_2_get_hdp_flush_done_offset, | |
| 322 | + .get_pcie_index_offset = nbio_v7_2_get_pcie_index_offset, | |
| 323 | + .get_pcie_data_offset = nbio_v7_2_get_pcie_data_offset, | |
| 324 | + .get_pcie_port_index_offset = nbio_v7_2_get_pcie_port_index_offset, | |
| 325 | + .get_pcie_port_data_offset = nbio_v7_2_get_pcie_port_data_offset, | |
| 326 | + .get_rev_id = nbio_v7_2_get_rev_id, | |
| 327 | + .mc_access_enable = nbio_v7_2_mc_access_enable, | |
| 328 | + .hdp_flush = nbio_v7_2_hdp_flush, | |
| 329 | + .get_memsize = nbio_v7_2_get_memsize, | |
| 330 | + .sdma_doorbell_range = nbio_v7_2_sdma_doorbell_range, | |
| 331 | + .vcn_doorbell_range = nbio_v7_2_vcn_doorbell_range, | |
| 332 | + .enable_doorbell_aperture = nbio_v7_2_enable_doorbell_aperture, | |
| 333 | + .enable_doorbell_selfring_aperture = nbio_v7_2_enable_doorbell_selfring_aperture, | |
| 334 | + .ih_doorbell_range = nbio_v7_2_ih_doorbell_range, | |
| 335 | + .update_medium_grain_clock_gating = nbio_v7_2_update_medium_grain_clock_gating, | |
| 336 | + .update_medium_grain_light_sleep = nbio_v7_2_update_medium_grain_light_sleep, | |
| 337 | + .get_clockgating_state = nbio_v7_2_get_clockgating_state, | |
| 338 | + .ih_control = nbio_v7_2_ih_control, | |
| 339 | + .init_registers = nbio_v7_2_init_registers, | |
| 340 | + .remap_hdp_registers = nbio_v7_2_remap_hdp_registers, | |
| 341 | +}; | |
| @@ -0,0 +1,32 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2020 Advanced Micro Devices, Inc. | |
| 3 | + * | |
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a | |
| 5 | + * copy of this software and associated documentation files (the "Software"), | |
| 6 | + * to deal in the Software without restriction, including without limitation | |
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the | |
| 9 | + * Software is furnished to do so, subject to the following conditions: | |
| 10 | + * | |
| 11 | + * The above copyright notice and this permission notice shall be included in | |
| 12 | + * all copies or substantial portions of the Software. | |
| 13 | + * | |
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 17 | + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 18 | + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 19 | + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 20 | + * OTHER DEALINGS IN THE SOFTWARE. | |
| 21 | + * | |
| 22 | + */ | |
| 23 | + | |
| 24 | +#ifndef __NBIO_V7_2_H__ | |
| 25 | +#define __NBIO_V7_2_H__ | |
| 26 | + | |
| 27 | +#include "soc15_common.h" | |
| 28 | + | |
| 29 | +extern const struct nbio_hdp_flush_reg nbio_v7_2_hdp_flush_reg; | |
| 30 | +extern const struct amdgpu_nbio_funcs nbio_v7_2_funcs; | |
| 31 | + | |
| 32 | +#endif | |
| @@ -49,6 +49,7 @@ · 48 unmodified lines | ||
| 49 | 49 | #include "gfxhub_v2_0.h" |
| 50 | 50 | #include "mmhub_v2_0.h" |
| 51 | 51 | #include "nbio_v2_3.h" |
| 52 | +#include "nbio_v7_2.h" | |
| 52 | 53 | #include "nv.h" |
| 53 | 54 | #include "navi10_ih.h" |
| 54 | 55 | #include "gfx_v10_0.h" |
| @@ -95,6 +96,21 @@ static u64 nv_pcie_rreg64(struct amdgpu_device *adev, u32 reg) · 40 unmodified lines | ||
| 95 | 96 | return amdgpu_device_indirect_rreg64(adev, address, data, reg); |
| 96 | 97 | } |
| 97 | 98 | |
| 99 | +static u32 nv_pcie_port_rreg(struct amdgpu_device *adev, u32 reg) | |
| 100 | +{ | |
| 101 | + unsigned long flags, address, data; | |
| 102 | + u32 r; | |
| 103 | + address = adev->nbio.funcs->get_pcie_port_index_offset(adev); | |
| 104 | + data = adev->nbio.funcs->get_pcie_port_data_offset(adev); | |
| 105 | + | |
| 106 | + spin_lock_irqsave(&adev->pcie_idx_lock, flags); | |
| 107 | + WREG32(address, reg * 4); | |
| 108 | + (void)RREG32(address); | |
| 109 | + r = RREG32(data); | |
| 110 | + spin_unlock_irqrestore(&adev->pcie_idx_lock, flags); | |
| 111 | + return r; | |
| 112 | +} | |
| 113 | + | |
| 98 | 114 | static void nv_pcie_wreg64(struct amdgpu_device *adev, u32 reg, u64 v) |
| 99 | 115 | { |
| 100 | 116 | unsigned long address, data; |
| @@ -105,6 +121,21 @@ static void nv_pcie_wreg64(struct amdgpu_device *adev, u32 reg, u64 v) · 4 unmodified lines | ||
| 105 | 121 | amdgpu_device_indirect_wreg64(adev, address, data, reg, v); |
| 106 | 122 | } |
| 107 | 123 | |
| 124 | +static void nv_pcie_port_wreg(struct amdgpu_device *adev, u32 reg, u32 v) | |
| 125 | +{ | |
| 126 | + unsigned long flags, address, data; | |
| 127 | + | |
| 128 | + address = adev->nbio.funcs->get_pcie_port_index_offset(adev); | |
| 129 | + data = adev->nbio.funcs->get_pcie_port_data_offset(adev); | |
| 130 | + | |
| 131 | + spin_lock_irqsave(&adev->pcie_idx_lock, flags); | |
| 132 | + WREG32(address, reg * 4); | |
| 133 | + (void)RREG32(address); | |
| 134 | + WREG32(data, v); | |
| 135 | + (void)RREG32(data); | |
| 136 | + spin_unlock_irqrestore(&adev->pcie_idx_lock, flags); | |
| 137 | +} | |
| 138 | + | |
| 108 | 139 | static u32 nv_didt_rreg(struct amdgpu_device *adev, u32 reg) |
| 109 | 140 | { |
| 110 | 141 | unsigned long flags, address, data; |
| @@ -254,7 +285,8 @@ static int nv_read_register(struct amdgpu_device *adev, u32 se_num, · 143 unmodified lines | ||
| 254 | 285 | *value = 0; |
| 255 | 286 | for (i = 0; i < ARRAY_SIZE(nv_allowed_read_registers); i++) { |
| 256 | 287 | en = &nv_allowed_read_registers[i]; |
| 257 | − if (reg_offset != | |
| 288 | + if ((i == 7 && (adev->sdma.num_instances == 1)) || /* some asics don't have SDMA1 */ | |
| 289 | + reg_offset != | |
| 258 | 290 | (adev->reg_offset[en->hwip][en->inst][en->seg] + en->reg_offset)) |
| 259 | 291 | continue; |
| 260 | 292 | |
| @@ -443,6 +475,12 @@ legacy_init: · 182 unmodified lines | ||
| 443 | 475 | case CHIP_NAVY_FLOUNDER: |
| 444 | 476 | sienna_cichlid_reg_base_init(adev); |
| 445 | 477 | break; |
| 478 | + case CHIP_VANGOGH: | |
| 479 | + vangogh_reg_base_init(adev); | |
| 480 | + break; | |
| 481 | + case CHIP_DIMGREY_CAVEFISH: | |
| 482 | + dimgrey_cavefish_reg_base_init(adev); | |
| 483 | + break; | |
| 446 | 484 | default: |
| 447 | 485 | return -EINVAL; |
| 448 | 486 | } |
| @@ -455,10 +493,11 @@ void nv_set_virt_ops(struct amdgpu_device *adev) · 6 unmodified lines | ||
| 455 | 493 | adev->virt.ops = &xgpu_nv_virt_ops; |
| 456 | 494 | } |
| 457 | 495 | |
| 458 | −static bool nv_is_blockchain_sku(struct pci_dev *pdev) | |
| 496 | +static bool nv_is_headless_sku(struct pci_dev *pdev) | |
| 459 | 497 | { |
| 460 | − if (pdev->device == 0x731E && | |
| 461 | − (pdev->revision == 0xC6 || pdev->revision == 0xC7)) | |
| 498 | + if ((pdev->device == 0x731E && | |
| 499 | + (pdev->revision == 0xC6 || pdev->revision == 0xC7)) || | |
| 500 | + (pdev->device == 0x7340 && pdev->revision == 0xC9)) | |
| 462 | 501 | return true; |
| 463 | 502 | return false; |
| 464 | 503 | } |
| @@ -467,8 +506,13 @@ int nv_set_ip_blocks(struct amdgpu_device *adev) · 2 unmodified lines | ||
| 467 | 506 | { |
| 468 | 507 | int r; |
| 469 | 508 | |
| 470 | − adev->nbio.funcs = &nbio_v2_3_funcs; | |
| 471 | − adev->nbio.hdp_flush_reg = &nbio_v2_3_hdp_flush_reg; | |
| 509 | + if (adev->flags & AMD_IS_APU) { | |
| 510 | + adev->nbio.funcs = &nbio_v7_2_funcs; | |
| 511 | + adev->nbio.hdp_flush_reg = &nbio_v7_2_hdp_flush_reg; | |
| 512 | + } else { | |
| 513 | + adev->nbio.funcs = &nbio_v2_3_funcs; | |
| 514 | + adev->nbio.hdp_flush_reg = &nbio_v2_3_hdp_flush_reg; | |
| 515 | + } | |
| 472 | 516 | |
| 473 | 517 | if (adev->asic_type == CHIP_SIENNA_CICHLID) |
| 474 | 518 | adev->gmc.xgmi.supported = true; |
| @@ -492,7 +536,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev) · 17 unmodified lines | ||
| 492 | 536 | amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block); |
| 493 | 537 | #if defined(CONFIG_DRM_AMD_DC) |
| 494 | 538 | else if (amdgpu_device_has_dc_support(adev) && |
| 495 | − !nv_is_blockchain_sku(adev->pdev)) | |
| 539 | + !nv_is_headless_sku(adev->pdev)) | |
| 496 | 540 | amdgpu_device_ip_block_add(adev, &dm_ip_block); |
| 497 | 541 | #endif |
| 498 | 542 | amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block); |
| @@ -500,7 +544,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev) · 1 unmodified line | ||
| 500 | 544 | if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT && |
| 501 | 545 | !amdgpu_sriov_vf(adev)) |
| 502 | 546 | amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block); |
| 503 | − if (!nv_is_blockchain_sku(adev->pdev)) | |
| 547 | + if (!nv_is_headless_sku(adev->pdev)) | |
| 504 | 548 | amdgpu_device_ip_block_add(adev, &vcn_v2_0_ip_block); |
| 505 | 549 | amdgpu_device_ip_block_add(adev, &jpeg_v2_0_ip_block); |
| 506 | 550 | if (adev->enable_mes) |
| @@ -575,6 +619,44 @@ int nv_set_ip_blocks(struct amdgpu_device *adev) · 68 unmodified lines | ||
| 575 | 619 | is_support_sw_smu(adev)) |
| 576 | 620 | amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block); |
| 577 | 621 | break; |
| 622 | + case CHIP_VANGOGH: | |
| 623 | + amdgpu_device_ip_block_add(adev, &nv_common_ip_block); | |
| 624 | + amdgpu_device_ip_block_add(adev, &gmc_v10_0_ip_block); | |
| 625 | + amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block); | |
| 626 | + if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) | |
| 627 | + amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block); | |
| 628 | + amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block); | |
| 629 | + if (adev->enable_virtual_display || amdgpu_sriov_vf(adev)) | |
| 630 | + amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block); | |
| 631 | +#if defined(CONFIG_DRM_AMD_DC) | |
| 632 | + else if (amdgpu_device_has_dc_support(adev)) | |
| 633 | + amdgpu_device_ip_block_add(adev, &dm_ip_block); | |
| 634 | +#endif | |
| 635 | + amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block); | |
| 636 | + amdgpu_device_ip_block_add(adev, &sdma_v5_2_ip_block); | |
| 637 | + amdgpu_device_ip_block_add(adev, &vcn_v3_0_ip_block); | |
| 638 | + amdgpu_device_ip_block_add(adev, &jpeg_v3_0_ip_block); | |
| 639 | + break; | |
| 640 | + case CHIP_DIMGREY_CAVEFISH: | |
| 641 | + amdgpu_device_ip_block_add(adev, &nv_common_ip_block); | |
| 642 | + amdgpu_device_ip_block_add(adev, &gmc_v10_0_ip_block); | |
| 643 | + amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block); | |
| 644 | + if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) | |
| 645 | + amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block); | |
| 646 | + if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP && | |
| 647 | + is_support_sw_smu(adev)) | |
| 648 | + amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block); | |
| 649 | + if (adev->enable_virtual_display || amdgpu_sriov_vf(adev)) | |
| 650 | + amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block); | |
| 651 | +#if defined(CONFIG_DRM_AMD_DC) | |
| 652 | + else if (amdgpu_device_has_dc_support(adev)) | |
| 653 | + amdgpu_device_ip_block_add(adev, &dm_ip_block); | |
| 654 | +#endif | |
| 655 | + amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block); | |
| 656 | + amdgpu_device_ip_block_add(adev, &sdma_v5_2_ip_block); | |
| 657 | + amdgpu_device_ip_block_add(adev, &vcn_v3_0_ip_block); | |
| 658 | + amdgpu_device_ip_block_add(adev, &jpeg_v3_0_ip_block); | |
| 659 | + break; | |
| 578 | 660 | default: |
| 579 | 661 | return -EINVAL; |
| 580 | 662 | } |
| @@ -671,6 +753,29 @@ static void nv_pre_asic_init(struct amdgpu_device *adev) · 90 unmodified lines | ||
| 671 | 753 | { |
| 672 | 754 | } |
| 673 | 755 | |
| 756 | +static int nv_update_umd_stable_pstate(struct amdgpu_device *adev, | |
| 757 | + bool enter) | |
| 758 | +{ | |
| 759 | + if (enter) | |
| 760 | + amdgpu_gfx_rlc_enter_safe_mode(adev); | |
| 761 | + else | |
| 762 | + amdgpu_gfx_rlc_exit_safe_mode(adev); | |
| 763 | + | |
| 764 | + if (adev->gfx.funcs->update_perfmon_mgcg) | |
| 765 | + adev->gfx.funcs->update_perfmon_mgcg(adev, !enter); | |
| 766 | + | |
| 767 | + /* | |
| 768 | + * The ASPM function is not fully enabled and verified on | |
| 769 | + * Navi yet. Temporarily skip this until ASPM enabled. | |
| 770 | + */ | |
| 771 | +#if 0 | |
| 772 | + if (adev->nbio.funcs->enable_aspm) | |
| 773 | + adev->nbio.funcs->enable_aspm(adev, !enter); | |
| 774 | +#endif | |
| 775 | + | |
| 776 | + return 0; | |
| 777 | +} | |
| 778 | + | |
| 674 | 779 | static const struct amdgpu_asic_funcs nv_asic_funcs = |
| 675 | 780 | { |
| 676 | 781 | .read_disabled_bios = &nv_read_disabled_bios, |
| @@ -691,6 +796,7 @@ static const struct amdgpu_asic_funcs nv_asic_funcs = · 14 unmodified lines | ||
| 691 | 796 | .get_pcie_replay_count = &nv_get_pcie_replay_count, |
| 692 | 797 | .supports_baco = &nv_asic_supports_baco, |
| 693 | 798 | .pre_asic_init = &nv_pre_asic_init, |
| 799 | + .update_umd_stable_pstate = &nv_update_umd_stable_pstate, | |
| 694 | 800 | }; |
| 695 | 801 | |
| 696 | 802 | static int nv_common_early_init(void *handle) |
| @@ -706,6 +812,8 @@ static int nv_common_early_init(void *handle) · 9 unmodified lines | ||
| 706 | 812 | adev->pcie_wreg = &nv_pcie_wreg; |
| 707 | 813 | adev->pcie_rreg64 = &nv_pcie_rreg64; |
| 708 | 814 | adev->pcie_wreg64 = &nv_pcie_wreg64; |
| 815 | + adev->pciep_rreg = &nv_pcie_port_rreg; | |
| 816 | + adev->pciep_wreg = &nv_pcie_port_wreg; | |
| 709 | 817 | |
| 710 | 818 | /* TODO: will add them during VCN v2 implementation */ |
| 711 | 819 | adev->uvd_ctx_rreg = NULL; |
| @@ -833,6 +941,46 @@ static int nv_common_early_init(void *handle) · 121 unmodified lines | ||
| 833 | 941 | adev->external_rev_id = adev->rev_id + 0x32; |
| 834 | 942 | break; |
| 835 | 943 | |
| 944 | + case CHIP_VANGOGH: | |
| 945 | + adev->apu_flags |= AMD_APU_IS_VANGOGH; | |
| 946 | + adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | | |
| 947 | + AMD_CG_SUPPORT_GFX_MGLS | | |
| 948 | + AMD_CG_SUPPORT_GFX_CP_LS | | |
| 949 | + AMD_CG_SUPPORT_GFX_RLC_LS | | |
| 950 | + AMD_CG_SUPPORT_GFX_CGCG | | |
| 951 | + AMD_CG_SUPPORT_GFX_CGLS | | |
| 952 | + AMD_CG_SUPPORT_GFX_3D_CGCG | | |
| 953 | + AMD_CG_SUPPORT_GFX_3D_CGLS | | |
| 954 | + AMD_CG_SUPPORT_MC_MGCG | | |
| 955 | + AMD_CG_SUPPORT_MC_LS | | |
| 956 | + AMD_CG_SUPPORT_GFX_FGCG | | |
| 957 | + AMD_CG_SUPPORT_VCN_MGCG | | |
| 958 | + AMD_CG_SUPPORT_JPEG_MGCG; | |
| 959 | + adev->pg_flags = AMD_PG_SUPPORT_GFX_PG | | |
| 960 | + AMD_PG_SUPPORT_VCN | | |
| 961 | + AMD_PG_SUPPORT_VCN_DPG | | |
| 962 | + AMD_PG_SUPPORT_JPEG; | |
| 963 | + if (adev->apu_flags & AMD_APU_IS_VANGOGH) | |
| 964 | + adev->external_rev_id = adev->rev_id + 0x01; | |
| 965 | + break; | |
| 966 | + case CHIP_DIMGREY_CAVEFISH: | |
| 967 | + adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | | |
| 968 | + AMD_CG_SUPPORT_GFX_CGCG | | |
| 969 | + AMD_CG_SUPPORT_GFX_3D_CGCG | | |
| 970 | + AMD_CG_SUPPORT_VCN_MGCG | | |
| 971 | + AMD_CG_SUPPORT_JPEG_MGCG | | |
| 972 | + AMD_CG_SUPPORT_MC_MGCG | | |
| 973 | + AMD_CG_SUPPORT_MC_LS | | |
| 974 | + AMD_CG_SUPPORT_HDP_MGCG | | |
| 975 | + AMD_CG_SUPPORT_HDP_LS | | |
| 976 | + AMD_CG_SUPPORT_IH_CG; | |
| 977 | + adev->pg_flags = AMD_PG_SUPPORT_VCN | | |
| 978 | + AMD_PG_SUPPORT_VCN_DPG | | |
| 979 | + AMD_PG_SUPPORT_JPEG | | |
| 980 | + AMD_PG_SUPPORT_ATHUB | | |
| 981 | + AMD_PG_SUPPORT_MMHUB; | |
| 982 | + adev->external_rev_id = adev->rev_id + 0x3c; | |
| 983 | + break; | |
| 836 | 984 | default: |
| 837 | 985 | /* FIXME: not supported yet */ |
| 838 | 986 | return -EINVAL; |
| @@ -1060,6 +1208,7 @@ static int nv_common_set_clockgating_state(void *handle, · 221 unmodified lines | ||
| 1060 | 1208 | case CHIP_NAVI12: |
| 1061 | 1209 | case CHIP_SIENNA_CICHLID: |
| 1062 | 1210 | case CHIP_NAVY_FLOUNDER: |
| 1211 | + case CHIP_DIMGREY_CAVEFISH: | |
| 1063 | 1212 | adev->nbio.funcs->update_medium_grain_clock_gating(adev, |
| 1064 | 1213 | state == AMD_CG_STATE_GATE); |
| 1065 | 1214 | adev->nbio.funcs->update_medium_grain_light_sleep(adev, |
| @@ -34,4 +34,6 @@ int navi10_reg_base_init(struct amdgpu_device *adev); · 33 unmodified lines | ||
| 34 | 34 | int navi14_reg_base_init(struct amdgpu_device *adev); |
| 35 | 35 | int navi12_reg_base_init(struct amdgpu_device *adev); |
| 36 | 36 | int sienna_cichlid_reg_base_init(struct amdgpu_device *adev); |
| 37 | +void vangogh_reg_base_init(struct amdgpu_device *adev); | |
| 38 | +int dimgrey_cavefish_reg_base_init(struct amdgpu_device *adev); | |
| 37 | 39 | #endif |
| @@ -86,21 +86,22 @@ struct psp_gfx_ctrl · 85 unmodified lines | ||
| 86 | 86 | /* TEE Gfx Command IDs for the ring buffer interface. */ |
| 87 | 87 | enum psp_gfx_cmd_id |
| 88 | 88 | { |
| 89 | − GFX_CMD_ID_LOAD_TA = 0x00000001, /* load TA */ | |
| 90 | − GFX_CMD_ID_UNLOAD_TA = 0x00000002, /* unload TA */ | |
| 91 | − GFX_CMD_ID_INVOKE_CMD = 0x00000003, /* send command to TA */ | |
| 92 | − GFX_CMD_ID_LOAD_ASD = 0x00000004, /* load ASD Driver */ | |
| 93 | − GFX_CMD_ID_SETUP_TMR = 0x00000005, /* setup TMR region */ | |
| 94 | − GFX_CMD_ID_LOAD_IP_FW = 0x00000006, /* load HW IP FW */ | |
| 95 | − GFX_CMD_ID_DESTROY_TMR = 0x00000007, /* destroy TMR region */ | |
| 96 | − GFX_CMD_ID_SAVE_RESTORE = 0x00000008, /* save/restore HW IP FW */ | |
| 97 | − GFX_CMD_ID_SETUP_VMR = 0x00000009, /* setup VMR region */ | |
| 98 | − GFX_CMD_ID_DESTROY_VMR = 0x0000000A, /* destroy VMR region */ | |
| 99 | − GFX_CMD_ID_PROG_REG = 0x0000000B, /* program regs */ | |
| 100 | − GFX_CMD_ID_CLEAR_VF_FW = 0x0000000D, /* Clear VF FW, to be used on VF shutdown. */ | |
| 89 | + GFX_CMD_ID_LOAD_TA = 0x00000001, /* load TA */ | |
| 90 | + GFX_CMD_ID_UNLOAD_TA = 0x00000002, /* unload TA */ | |
| 91 | + GFX_CMD_ID_INVOKE_CMD = 0x00000003, /* send command to TA */ | |
| 92 | + GFX_CMD_ID_LOAD_ASD = 0x00000004, /* load ASD Driver */ | |
| 93 | + GFX_CMD_ID_SETUP_TMR = 0x00000005, /* setup TMR region */ | |
| 94 | + GFX_CMD_ID_LOAD_IP_FW = 0x00000006, /* load HW IP FW */ | |
| 95 | + GFX_CMD_ID_DESTROY_TMR = 0x00000007, /* destroy TMR region */ | |
| 96 | + GFX_CMD_ID_SAVE_RESTORE = 0x00000008, /* save/restore HW IP FW */ | |
| 97 | + GFX_CMD_ID_SETUP_VMR = 0x00000009, /* setup VMR region */ | |
| 98 | + GFX_CMD_ID_DESTROY_VMR = 0x0000000A, /* destroy VMR region */ | |
| 99 | + GFX_CMD_ID_PROG_REG = 0x0000000B, /* program regs */ | |
| 100 | + GFX_CMD_ID_CLEAR_VF_FW = 0x0000000D, /* Clear VF FW, to be used on VF shutdown. */ | |
| 101 | + GFX_CMD_ID_GET_FW_ATTESTATION = 0x0000000F, /* Query GPUVA of the Fw Attestation DB */ | |
| 101 | 102 | /* IDs upto 0x1F are reserved for older programs (Raven, Vega 10/12/20) */ |
| 102 | − GFX_CMD_ID_LOAD_TOC = 0x00000020, /* Load TOC and obtain TMR size */ | |
| 103 | − GFX_CMD_ID_AUTOLOAD_RLC = 0x00000021, /* Indicates all graphics fw loaded, start RLC autoload */ | |
| 103 | + GFX_CMD_ID_LOAD_TOC = 0x00000020, /* Load TOC and obtain TMR size */ | |
| 104 | + GFX_CMD_ID_AUTOLOAD_RLC = 0x00000021, /* Indicates all graphics fw loaded, start RLC autoload */ | |
| 104 | 105 | }; |
| 105 | 106 | |
| 106 | 107 | /* Command to load Trusted Application binary into PSP OS. */ |
| @@ -285,6 +286,25 @@ union psp_gfx_commands · 178 unmodified lines | ||
| 285 | 286 | struct psp_gfx_cmd_load_toc cmd_load_toc; |
| 286 | 287 | }; |
| 287 | 288 | |
| 289 | +struct psp_gfx_uresp_reserved | |
| 290 | +{ | |
| 291 | + uint32_t reserved[8]; | |
| 292 | +}; | |
| 293 | + | |
| 294 | +/* Command-specific response for Fw Attestation Db */ | |
| 295 | +struct psp_gfx_uresp_fwar_db_info | |
| 296 | +{ | |
| 297 | + uint32_t fwar_db_addr_lo; | |
| 298 | + uint32_t fwar_db_addr_hi; | |
| 299 | +}; | |
| 300 | + | |
| 301 | +/* Union of command-specific responses for GPCOM ring. */ | |
| 302 | +union psp_gfx_uresp | |
| 303 | +{ | |
| 304 | + struct psp_gfx_uresp_reserved reserved; | |
| 305 | + struct psp_gfx_uresp_fwar_db_info fwar_db_info; | |
| 306 | +}; | |
| 307 | + | |
| 288 | 308 | /* Structure of GFX Response buffer. |
| 289 | 309 | * For GPCOM I/F it is part of GFX_CMD_RESP buffer, for RBI |
| 290 | 310 | * it is separate buffer. |
| @@ -297,9 +317,11 @@ struct psp_gfx_resp · 6 unmodified lines | ||
| 297 | 317 | uint32_t fw_addr_hi; /* +12 bits [63:32] of FW address within TMR (in response to cmd_load_ip_fw command) */ |
| 298 | 318 | uint32_t tmr_size; /* +16 size of the TMR to be reserved including MM fw and Gfx fw in response to cmd_load_toc command */ |
| 299 | 319 | |
| 300 | − uint32_t reserved[3]; | |
| 320 | + uint32_t reserved[11]; | |
| 321 | + | |
| 322 | + union psp_gfx_uresp uresp; /* +64 response union containing command-specific responses */ | |
| 301 | 323 | |
| 302 | − /* total 32 bytes */ | |
| 324 | + /* total 96 bytes */ | |
| 303 | 325 | }; |
| 304 | 326 | |
| 305 | 327 | /* Structure of Command buffer pointed by psp_gfx_rb_frame.cmd_buf_addr_hi |
| @@ -59,6 +59,10 @@ MODULE_FIRMWARE("amdgpu/sienna_cichlid_sos.bin"); · 58 unmodified lines | ||
| 59 | 59 | MODULE_FIRMWARE("amdgpu/sienna_cichlid_ta.bin"); |
| 60 | 60 | MODULE_FIRMWARE("amdgpu/navy_flounder_sos.bin"); |
| 61 | 61 | MODULE_FIRMWARE("amdgpu/navy_flounder_ta.bin"); |
| 62 | +MODULE_FIRMWARE("amdgpu/vangogh_asd.bin"); | |
| 63 | +MODULE_FIRMWARE("amdgpu/vangogh_toc.bin"); | |
| 64 | +MODULE_FIRMWARE("amdgpu/dimgrey_cavefish_sos.bin"); | |
| 65 | +MODULE_FIRMWARE("amdgpu/dimgrey_cavefish_asd.bin"); | |
| 62 | 66 | |
| 63 | 67 | /* address block */ |
| 64 | 68 | #define smnMP1_FIRMWARE_FLAGS 0x3010024 |
| @@ -77,7 +81,7 @@ static int psp_v11_0_init_microcode(struct psp_context *psp) · 12 unmodified lines | ||
| 77 | 81 | { |
| 78 | 82 | struct amdgpu_device *adev = psp->adev; |
| 79 | 83 | const char *chip_name; |
| 80 | − char fw_name[30]; | |
| 84 | + char fw_name[PSP_FW_NAME_LEN]; | |
| 81 | 85 | int err = 0; |
| 82 | 86 | const struct ta_firmware_header_v1_0 *ta_hdr; |
| 83 | 87 | |
| @@ -105,24 +109,26 @@ static int psp_v11_0_init_microcode(struct psp_context *psp) · 21 unmodified lines | ||
| 105 | 109 | case CHIP_NAVY_FLOUNDER: |
| 106 | 110 | chip_name = "navy_flounder"; |
| 107 | 111 | break; |
| 112 | + case CHIP_VANGOGH: | |
| 113 | + chip_name = "vangogh"; | |
| 114 | + break; | |
| 115 | + case CHIP_DIMGREY_CAVEFISH: | |
| 116 | + chip_name = "dimgrey_cavefish"; | |
| 117 | + break; | |
| 108 | 118 | default: |
| 109 | 119 | BUG(); |
| 110 | 120 | } |
| 111 | 121 | |
| 112 | − err = psp_init_sos_microcode(psp, chip_name); | |
| 113 | − if (err) | |
| 114 | − return err; | |
| 115 | − | |
| 116 | − if (adev->asic_type != CHIP_SIENNA_CICHLID && | |
| 117 | − adev->asic_type != CHIP_NAVY_FLOUNDER) { | |
| 118 | − err = psp_init_asd_microcode(psp, chip_name); | |
| 119 | − if (err) | |
| 120 | − return err; | |
| 121 | − } | |
| 122 | 122 | |
| 123 | 123 | switch (adev->asic_type) { |
| 124 | 124 | case CHIP_VEGA20: |
| 125 | 125 | case CHIP_ARCTURUS: |
| 126 | + err = psp_init_sos_microcode(psp, chip_name); | |
| 127 | + if (err) | |
| 128 | + return err; | |
| 129 | + err = psp_init_asd_microcode(psp, chip_name); | |
| 130 | + if (err) | |
| 131 | + return err; | |
| 126 | 132 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ta.bin", chip_name); |
| 127 | 133 | err = request_firmware(&adev->psp.ta_fw, fw_name, adev->dev); |
| 128 | 134 | if (err) { |
| @@ -150,6 +156,12 @@ static int psp_v11_0_init_microcode(struct psp_context *psp) · 21 unmodified lines | ||
| 150 | 156 | case CHIP_NAVI10: |
| 151 | 157 | case CHIP_NAVI14: |
| 152 | 158 | case CHIP_NAVI12: |
| 159 | + err = psp_init_sos_microcode(psp, chip_name); | |
| 160 | + if (err) | |
| 161 | + return err; | |
| 162 | + err = psp_init_asd_microcode(psp, chip_name); | |
| 163 | + if (err) | |
| 164 | + return err; | |
| 153 | 165 | if (amdgpu_sriov_vf(adev)) |
| 154 | 166 | break; |
| 155 | 167 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ta.bin", chip_name); |
| @@ -180,10 +192,26 @@ static int psp_v11_0_init_microcode(struct psp_context *psp) · 24 unmodified lines | ||
| 180 | 192 | break; |
| 181 | 193 | case CHIP_SIENNA_CICHLID: |
| 182 | 194 | case CHIP_NAVY_FLOUNDER: |
| 195 | + err = psp_init_sos_microcode(psp, chip_name); | |
| 196 | + if (err) | |
| 197 | + return err; | |
| 183 | 198 | err = psp_init_ta_microcode(&adev->psp, chip_name); |
| 184 | 199 | if (err) |
| 185 | 200 | return err; |
| 186 | 201 | break; |
| 202 | + case CHIP_DIMGREY_CAVEFISH: | |
| 203 | + err = psp_init_sos_microcode(psp, chip_name); | |
| 204 | + if (err) | |
| 205 | + return err; | |
| 206 | + break; | |
| 207 | + case CHIP_VANGOGH: | |
| 208 | + err = psp_init_asd_microcode(psp, chip_name); | |
| 209 | + if (err) | |
| 210 | + return err; | |
| 211 | + err = psp_init_toc_microcode(psp, chip_name); | |
| 212 | + if (err) | |
| 213 | + return err; | |
| 214 | + break; | |
| 187 | 215 | default: |
| 188 | 216 | BUG(); |
| 189 | 217 | } |
| @@ -407,8 +435,8 @@ static int psp_v11_0_ring_init(struct psp_context *psp, · 217 unmodified lines | ||
| 407 | 435 | struct amdgpu_device *adev = psp->adev; |
| 408 | 436 | |
| 409 | 437 | if ((!amdgpu_sriov_vf(adev)) && |
| 410 | − (adev->asic_type != CHIP_SIENNA_CICHLID) && | |
| 411 | − (adev->asic_type != CHIP_NAVY_FLOUNDER)) | |
| 438 | + !(adev->asic_type >= CHIP_SIENNA_CICHLID && | |
| 439 | + adev->asic_type <= CHIP_DIMGREY_CAVEFISH)) | |
| 412 | 440 | psp_v11_0_reroute_ih(psp); |
| 413 | 441 | |
| 414 | 442 | ring = &psp->km_ring; |
| @@ -615,7 +643,7 @@ static int psp_v11_0_memory_training_send_msg(struct psp_context *psp, int msg) · 200 unmodified lines | ||
| 615 | 643 | static int psp_v11_0_memory_training(struct psp_context *psp, uint32_t ops) |
| 616 | 644 | { |
| 617 | 645 | struct psp_memory_training_context *ctx = &psp->mem_train_ctx; |
| 618 | − uint32_t *pcache = (uint32_t*)ctx->sys_cache; | |
| 646 | + uint32_t *pcache = (uint32_t *)ctx->sys_cache; | |
| 619 | 647 | struct amdgpu_device *adev = psp->adev; |
| 620 | 648 | uint32_t p2c_header[4]; |
| 621 | 649 | uint32_t sz; |
| @@ -39,6 +39,7 @@ · 38 unmodified lines | ||
| 39 | 39 | |
| 40 | 40 | MODULE_FIRMWARE("amdgpu/renoir_asd.bin"); |
| 41 | 41 | MODULE_FIRMWARE("amdgpu/renoir_ta.bin"); |
| 42 | +MODULE_FIRMWARE("amdgpu/green_sardine_asd.bin"); | |
| 42 | 43 | |
| 43 | 44 | /* address block */ |
| 44 | 45 | #define smnMP1_FIRMWARE_FLAGS 0x3010024 |
| @@ -54,7 +55,10 @@ static int psp_v12_0_init_microcode(struct psp_context *psp) · 9 unmodified lines | ||
| 54 | 55 | |
| 55 | 56 | switch (adev->asic_type) { |
| 56 | 57 | case CHIP_RENOIR: |
| 57 | − chip_name = "renoir"; | |
| 58 | + if (adev->apu_flags & AMD_APU_IS_RENOIR) | |
| 59 | + chip_name = "renoir"; | |
| 60 | + else | |
| 61 | + chip_name = "green_sardine"; | |
| 58 | 62 | break; |
| 59 | 63 | default: |
| 60 | 64 | BUG(); |
| @@ -69,6 +69,7 @@ MODULE_FIRMWARE("amdgpu/picasso_sdma.bin"); · 68 unmodified lines | ||
| 69 | 69 | MODULE_FIRMWARE("amdgpu/raven2_sdma.bin"); |
| 70 | 70 | MODULE_FIRMWARE("amdgpu/arcturus_sdma.bin"); |
| 71 | 71 | MODULE_FIRMWARE("amdgpu/renoir_sdma.bin"); |
| 72 | +MODULE_FIRMWARE("amdgpu/green_sardine_sdma.bin"); | |
| 72 | 73 | |
| 73 | 74 | #define SDMA0_POWER_CNTL__ON_OFF_CONDITION_HOLD_TIME_MASK 0x000000F8L |
| 74 | 75 | #define SDMA0_POWER_CNTL__ON_OFF_STATUS_DURATION_TIME_MASK 0xFC000000L |
| @@ -568,7 +569,7 @@ static void sdma_v4_0_destroy_inst_ctx(struct amdgpu_device *adev) · 493 unmodified lines | ||
| 568 | 569 | break; |
| 569 | 570 | } |
| 570 | 571 | |
| 571 | − memset((void*)adev->sdma.instance, 0, | |
| 572 | + memset((void *)adev->sdma.instance, 0, | |
| 572 | 573 | sizeof(struct amdgpu_sdma_instance) * AMDGPU_MAX_SDMA_INSTANCES); |
| 573 | 574 | } |
| 574 | 575 | |
| @@ -619,7 +620,10 @@ static int sdma_v4_0_init_microcode(struct amdgpu_device *adev) · 44 unmodified lines | ||
| 619 | 620 | chip_name = "arcturus"; |
| 620 | 621 | break; |
| 621 | 622 | case CHIP_RENOIR: |
| 622 | − chip_name = "renoir"; | |
| 623 | + if (adev->apu_flags & AMD_APU_IS_RENOIR) | |
| 624 | + chip_name = "renoir"; | |
| 625 | + else | |
| 626 | + chip_name = "green_sardine"; | |
| 623 | 627 | break; |
| 624 | 628 | default: |
| 625 | 629 | BUG(); |
| @@ -639,8 +643,8 @@ static int sdma_v4_0_init_microcode(struct amdgpu_device *adev) · 13 unmodified lines | ||
| 639 | 643 | if (adev->asic_type == CHIP_ARCTURUS) { |
| 640 | 644 | /* Acturus will leverage the same FW memory |
| 641 | 645 | for every SDMA instance */ |
| 642 | − memcpy((void*)&adev->sdma.instance[i], | |
| 643 | − (void*)&adev->sdma.instance[0], | |
| 646 | + memcpy((void *)&adev->sdma.instance[i], | |
| 647 | + (void *)&adev->sdma.instance[0], | |
| 644 | 648 | sizeof(struct amdgpu_sdma_instance)); |
| 645 | 649 | } |
| 646 | 650 | else { |
| @@ -46,6 +46,9 @@ · 45 unmodified lines | ||
| 46 | 46 | |
| 47 | 47 | MODULE_FIRMWARE("amdgpu/sienna_cichlid_sdma.bin"); |
| 48 | 48 | MODULE_FIRMWARE("amdgpu/navy_flounder_sdma.bin"); |
| 49 | +MODULE_FIRMWARE("amdgpu/dimgrey_cavefish_sdma.bin"); | |
| 50 | + | |
| 51 | +MODULE_FIRMWARE("amdgpu/vangogh_sdma.bin"); | |
| 49 | 52 | |
| 50 | 53 | #define SDMA1_REG_OFFSET 0x600 |
| 51 | 54 | #define SDMA3_REG_OFFSET 0x400 |
| @@ -87,6 +90,8 @@ static void sdma_v5_2_init_golden_registers(struct amdgpu_device *adev) · 35 unmodified lines | ||
| 87 | 90 | switch (adev->asic_type) { |
| 88 | 91 | case CHIP_SIENNA_CICHLID: |
| 89 | 92 | case CHIP_NAVY_FLOUNDER: |
| 93 | + case CHIP_VANGOGH: | |
| 94 | + case CHIP_DIMGREY_CAVEFISH: | |
| 90 | 95 | break; |
| 91 | 96 | default: |
| 92 | 97 | break; |
| @@ -124,7 +129,7 @@ static void sdma_v5_2_destroy_inst_ctx(struct amdgpu_device *adev) · 31 unmodified lines | ||
| 124 | 129 | break; |
| 125 | 130 | } |
| 126 | 131 | |
| 127 | − memset((void*)adev->sdma.instance, 0, | |
| 132 | + memset((void *)adev->sdma.instance, 0, | |
| 128 | 133 | sizeof(struct amdgpu_sdma_instance) * AMDGPU_MAX_SDMA_INSTANCES); |
| 129 | 134 | } |
| 130 | 135 | |
| @@ -160,6 +165,12 @@ static int sdma_v5_2_init_microcode(struct amdgpu_device *adev) · 29 unmodified lines | ||
| 160 | 165 | case CHIP_NAVY_FLOUNDER: |
| 161 | 166 | chip_name = "navy_flounder"; |
| 162 | 167 | break; |
| 168 | + case CHIP_VANGOGH: | |
| 169 | + chip_name = "vangogh"; | |
| 170 | + break; | |
| 171 | + case CHIP_DIMGREY_CAVEFISH: | |
| 172 | + chip_name = "dimgrey_cavefish"; | |
| 173 | + break; | |
| 163 | 174 | default: |
| 164 | 175 | BUG(); |
| 165 | 176 | } |
| @@ -175,10 +186,10 @@ static int sdma_v5_2_init_microcode(struct amdgpu_device *adev) · 9 unmodified lines | ||
| 175 | 186 | goto out; |
| 176 | 187 | |
| 177 | 188 | for (i = 1; i < adev->sdma.num_instances; i++) { |
| 178 | − if (adev->asic_type == CHIP_SIENNA_CICHLID || | |
| 179 | − adev->asic_type == CHIP_NAVY_FLOUNDER) { | |
| 180 | − memcpy((void*)&adev->sdma.instance[i], | |
| 181 | − (void*)&adev->sdma.instance[0], | |
| 189 | + if (adev->asic_type >= CHIP_SIENNA_CICHLID && | |
| 190 | + adev->asic_type <= CHIP_DIMGREY_CAVEFISH) { | |
| 191 | + memcpy((void *)&adev->sdma.instance[i], | |
| 192 | + (void *)&adev->sdma.instance[0], | |
| 182 | 193 | sizeof(struct amdgpu_sdma_instance)); |
| 183 | 194 | } else { |
| 184 | 195 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_sdma%d.bin", chip_name, i); |
| @@ -696,7 +707,7 @@ static int sdma_v5_2_gfx_resume(struct amdgpu_device *adev) · 511 unmodified lines | ||
| 696 | 707 | temp &= 0xFF0FFF; |
| 697 | 708 | temp |= ((CACHE_READ_POLICY_L2__DEFAULT << 12) | |
| 698 | 709 | (CACHE_WRITE_POLICY_L2__DEFAULT << 14) | |
| 699 | − 0x01000000); | |
| 710 | + SDMA0_UTCL1_PAGE__LLC_NOALLOC_MASK); | |
| 700 | 711 | WREG32(sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_UTCL1_PAGE), temp); |
| 701 | 712 | |
| 702 | 713 | if (!amdgpu_sriov_vf(adev)) { |
| @@ -1169,8 +1180,12 @@ static int sdma_v5_2_early_init(void *handle) · 466 unmodified lines | ||
| 1169 | 1180 | adev->sdma.num_instances = 4; |
| 1170 | 1181 | break; |
| 1171 | 1182 | case CHIP_NAVY_FLOUNDER: |
| 1183 | + case CHIP_DIMGREY_CAVEFISH: | |
| 1172 | 1184 | adev->sdma.num_instances = 2; |
| 1173 | 1185 | break; |
| 1186 | + case CHIP_VANGOGH: | |
| 1187 | + adev->sdma.num_instances = 1; | |
| 1188 | + break; | |
| 1174 | 1189 | default: |
| 1175 | 1190 | break; |
| 1176 | 1191 | } |
| @@ -1567,6 +1582,8 @@ static int sdma_v5_2_set_clockgating_state(void *handle, · 390 unmodified lines | ||
| 1567 | 1582 | switch (adev->asic_type) { |
| 1568 | 1583 | case CHIP_SIENNA_CICHLID: |
| 1569 | 1584 | case CHIP_NAVY_FLOUNDER: |
| 1585 | + case CHIP_VANGOGH: | |
| 1586 | + case CHIP_DIMGREY_CAVEFISH: | |
| 1570 | 1587 | sdma_v5_2_update_medium_grain_clock_gating(adev, |
| 1571 | 1588 | state == AMD_CG_STATE_GATE ? true : false); |
| 1572 | 1589 | sdma_v5_2_update_medium_grain_light_sleep(adev, |
| @@ -1350,7 +1350,7 @@ static void si_vga_set_state(struct amdgpu_device *adev, bool state) · 1349 unmodified lines | ||
| 1350 | 1350 | |
| 1351 | 1351 | static u32 si_get_xclk(struct amdgpu_device *adev) |
| 1352 | 1352 | { |
| 1353 | − u32 reference_clock = adev->clock.spll.reference_freq; | |
| 1353 | + u32 reference_clock = adev->clock.spll.reference_freq; | |
| 1354 | 1354 | u32 tmp; |
| 1355 | 1355 | |
| 1356 | 1356 | tmp = RREG32(CG_CLKPIN_CNTL_2); |
| @@ -43,7 +43,7 @@ static void si_ih_enable_interrupts(struct amdgpu_device *adev) · 42 unmodified lines | ||
| 43 | 43 | WREG32(IH_RB_CNTL, ih_rb_cntl); |
| 44 | 44 | adev->irq.ih.enabled = true; |
| 45 | 45 | } |
| 46 | − | |
| 46 | + | |
| 47 | 47 | static void si_ih_disable_interrupts(struct amdgpu_device *adev) |
| 48 | 48 | { |
| 49 | 49 | u32 ih_rb_cntl = RREG32(IH_RB_CNTL); |
| @@ -62,6 +62,7 @@ · 61 unmodified lines | ||
| 62 | 62 | #include "nbio_v7_0.h" |
| 63 | 63 | #include "nbio_v7_4.h" |
| 64 | 64 | #include "vega10_ih.h" |
| 65 | +#include "navi10_ih.h" | |
| 65 | 66 | #include "sdma_v4_0.h" |
| 66 | 67 | #include "uvd_v7_0.h" |
| 67 | 68 | #include "vce_v4_0.h" |
| @@ -734,9 +735,15 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev) · 666 unmodified lines | ||
| 734 | 735 | else |
| 735 | 736 | amdgpu_device_ip_block_add(adev, &psp_v3_1_ip_block); |
| 736 | 737 | } |
| 737 | − amdgpu_device_ip_block_add(adev, &vega10_ih_ip_block); | |
| 738 | + if (adev->asic_type == CHIP_VEGA20) | |
| 739 | + amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block); | |
| 740 | + else | |
| 741 | + amdgpu_device_ip_block_add(adev, &vega10_ih_ip_block); | |
| 738 | 742 | } else { |
| 739 | − amdgpu_device_ip_block_add(adev, &vega10_ih_ip_block); | |
| 743 | + if (adev->asic_type == CHIP_VEGA20) | |
| 744 | + amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block); | |
| 745 | + else | |
| 746 | + amdgpu_device_ip_block_add(adev, &vega10_ih_ip_block); | |
| 740 | 747 | if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) { |
| 741 | 748 | if (adev->asic_type == CHIP_VEGA20) |
| 742 | 749 | amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block); |
| @@ -787,9 +794,9 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev) · 44 unmodified lines | ||
| 787 | 794 | if (amdgpu_sriov_vf(adev)) { |
| 788 | 795 | if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) |
| 789 | 796 | amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block); |
| 790 | − amdgpu_device_ip_block_add(adev, &vega10_ih_ip_block); | |
| 797 | + amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block); | |
| 791 | 798 | } else { |
| 792 | − amdgpu_device_ip_block_add(adev, &vega10_ih_ip_block); | |
| 799 | + amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block); | |
| 793 | 800 | if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) |
| 794 | 801 | amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block); |
| 795 | 802 | } |
| @@ -822,7 +829,7 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev) · 26 unmodified lines | ||
| 822 | 829 | amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block); |
| 823 | 830 | #if defined(CONFIG_DRM_AMD_DC) |
| 824 | 831 | else if (amdgpu_device_has_dc_support(adev)) |
| 825 | − amdgpu_device_ip_block_add(adev, &dm_ip_block); | |
| 832 | + amdgpu_device_ip_block_add(adev, &dm_ip_block); | |
| 826 | 833 | #endif |
| 827 | 834 | amdgpu_device_ip_block_add(adev, &vcn_v2_0_ip_block); |
| 828 | 835 | amdgpu_device_ip_block_add(adev, &jpeg_v2_0_ip_block); |
| @@ -1195,8 +1202,7 @@ static int soc15_common_early_init(void *handle) · 366 unmodified lines | ||
| 1195 | 1202 | |
| 1196 | 1203 | adev->pg_flags = AMD_PG_SUPPORT_SDMA | |
| 1197 | 1204 | AMD_PG_SUPPORT_MMHUB | |
| 1198 | − AMD_PG_SUPPORT_VCN | | |
| 1199 | − AMD_PG_SUPPORT_VCN_DPG; | |
| 1205 | + AMD_PG_SUPPORT_VCN; | |
| 1200 | 1206 | } else { |
| 1201 | 1207 | adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | |
| 1202 | 1208 | AMD_CG_SUPPORT_GFX_MGLS | |
| @@ -1243,7 +1249,15 @@ static int soc15_common_early_init(void *handle) · 40 unmodified lines | ||
| 1243 | 1249 | break; |
| 1244 | 1250 | case CHIP_RENOIR: |
| 1245 | 1251 | adev->asic_funcs = &soc15_asic_funcs; |
| 1246 | − adev->apu_flags |= AMD_APU_IS_RENOIR; | |
| 1252 | + if (adev->pdev->device == 0x1636) | |
| 1253 | + adev->apu_flags |= AMD_APU_IS_RENOIR; | |
| 1254 | + else | |
| 1255 | + adev->apu_flags |= AMD_APU_IS_GREEN_SARDINE; | |
| 1256 | + | |
| 1257 | + if (adev->apu_flags & AMD_APU_IS_RENOIR) | |
| 1258 | + adev->external_rev_id = adev->rev_id + 0x91; | |
| 1259 | + else | |
| 1260 | + adev->external_rev_id = adev->rev_id + 0xa1; | |
| 1247 | 1261 | adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | |
| 1248 | 1262 | AMD_CG_SUPPORT_GFX_MGLS | |
| 1249 | 1263 | AMD_CG_SUPPORT_GFX_3D_CGCG | |
| @@ -1268,7 +1282,6 @@ static int soc15_common_early_init(void *handle) · 18 unmodified lines | ||
| 1268 | 1282 | AMD_PG_SUPPORT_VCN | |
| 1269 | 1283 | AMD_PG_SUPPORT_JPEG | |
| 1270 | 1284 | AMD_PG_SUPPORT_VCN_DPG; |
| 1271 | − adev->external_rev_id = adev->rev_id + 0x91; | |
| 1272 | 1285 | break; |
| 1273 | 1286 | default: |
| 1274 | 1287 | /* FIXME: not supported yet */ |
| @@ -253,7 +253,7 @@ static void umc_v6_1_querry_uncorrectable_error_count(struct amdgpu_device *adev · 252 unmodified lines | ||
| 253 | 253 | static void umc_v6_1_query_ras_error_count(struct amdgpu_device *adev, |
| 254 | 254 | void *ras_error_status) |
| 255 | 255 | { |
| 256 | − struct ras_err_data* err_data = (struct ras_err_data*)ras_error_status; | |
| 256 | + struct ras_err_data *err_data = (struct ras_err_data *)ras_error_status; | |
| 257 | 257 | |
| 258 | 258 | uint32_t umc_inst = 0; |
| 259 | 259 | uint32_t ch_inst = 0; |
| @@ -368,7 +368,7 @@ static void umc_v6_1_query_error_address(struct amdgpu_device *adev, · 108 unmodified lines | ||
| 368 | 368 | static void umc_v6_1_query_ras_error_address(struct amdgpu_device *adev, |
| 369 | 369 | void *ras_error_status) |
| 370 | 370 | { |
| 371 | − struct ras_err_data* err_data = (struct ras_err_data*)ras_error_status; | |
| 371 | + struct ras_err_data *err_data = (struct ras_err_data *)ras_error_status; | |
| 372 | 372 | |
| 373 | 373 | uint32_t umc_inst = 0; |
| 374 | 374 | uint32_t ch_inst = 0; |
| @@ -170,7 +170,7 @@ static void umc_v8_7_querry_uncorrectable_error_count(struct amdgpu_device *adev · 169 unmodified lines | ||
| 170 | 170 | static void umc_v8_7_query_ras_error_count(struct amdgpu_device *adev, |
| 171 | 171 | void *ras_error_status) |
| 172 | 172 | { |
| 173 | − struct ras_err_data* err_data = (struct ras_err_data*)ras_error_status; | |
| 173 | + struct ras_err_data *err_data = (struct ras_err_data *)ras_error_status; | |
| 174 | 174 | |
| 175 | 175 | uint32_t umc_inst = 0; |
| 176 | 176 | uint32_t ch_inst = 0; |
| @@ -260,7 +260,7 @@ static void umc_v8_7_query_error_address(struct amdgpu_device *adev, · 83 unmodified lines | ||
| 260 | 260 | static void umc_v8_7_query_ras_error_address(struct amdgpu_device *adev, |
| 261 | 261 | void *ras_error_status) |
| 262 | 262 | { |
| 263 | − struct ras_err_data* err_data = (struct ras_err_data*)ras_error_status; | |
| 263 | + struct ras_err_data *err_data = (struct ras_err_data *)ras_error_status; | |
| 264 | 264 | |
| 265 | 265 | uint32_t umc_inst = 0; |
| 266 | 266 | uint32_t ch_inst = 0; |
| @@ -0,0 +1,50 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2019 Advanced Micro Devices, Inc. | |
| 3 | + * | |
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a | |
| 5 | + * copy of this software and associated documentation files (the "Software"), | |
| 6 | + * to deal in the Software without restriction, including without limitation | |
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the | |
| 9 | + * Software is furnished to do so, subject to the following conditions: | |
| 10 | + * | |
| 11 | + * The above copyright notice and this permission notice shall be included in | |
| 12 | + * all copies or substantial portions of the Software. | |
| 13 | + * | |
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 17 | + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 18 | + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 19 | + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 20 | + * OTHER DEALINGS IN THE SOFTWARE. | |
| 21 | + * | |
| 22 | + */ | |
| 23 | +#include "amdgpu.h" | |
| 24 | +#include "nv.h" | |
| 25 | + | |
| 26 | +#include "soc15_common.h" | |
| 27 | +#include "soc15_hw_ip.h" | |
| 28 | +#include "vangogh_ip_offset.h" | |
| 29 | + | |
| 30 | +void vangogh_reg_base_init(struct amdgpu_device *adev) | |
| 31 | +{ | |
| 32 | + /* HW has more IP blocks, only initialized the blocke needed by driver */ | |
| 33 | + uint32_t i; | |
| 34 | + for (i = 0 ; i < MAX_INSTANCE ; ++i) { | |
| 35 | + adev->reg_offset[GC_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i])); | |
| 36 | + adev->reg_offset[HDP_HWIP][i] = (uint32_t *)(&(HDP_BASE.instance[i])); | |
| 37 | + adev->reg_offset[MMHUB_HWIP][i] = (uint32_t *)(&(MMHUB_BASE.instance[i])); | |
| 38 | + adev->reg_offset[ATHUB_HWIP][i] = (uint32_t *)(&(ATHUB_BASE.instance[i])); | |
| 39 | + adev->reg_offset[NBIO_HWIP][i] = (uint32_t *)(&(NBIO_BASE.instance[i])); | |
| 40 | + adev->reg_offset[MP0_HWIP][i] = (uint32_t *)(&(MP0_BASE.instance[i])); | |
| 41 | + adev->reg_offset[MP1_HWIP][i] = (uint32_t *)(&(MP1_BASE.instance[i])); | |
| 42 | + adev->reg_offset[VCN_HWIP][i] = (uint32_t *)(&(VCN_BASE.instance[i])); | |
| 43 | + adev->reg_offset[DF_HWIP][i] = (uint32_t *)(&(DF_BASE.instance[i])); | |
| 44 | + adev->reg_offset[DCE_HWIP][i] = (uint32_t *)(&(DCN_BASE.instance[i])); | |
| 45 | + adev->reg_offset[OSSSYS_HWIP][i] = (uint32_t *)(&(OSSSYS_BASE.instance[i])); | |
| 46 | + adev->reg_offset[SDMA0_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i])); | |
| 47 | + adev->reg_offset[SMUIO_HWIP][i] = (uint32_t *)(&(SMUIO_BASE.instance[i])); | |
| 48 | + adev->reg_offset[THM_HWIP][i] = (uint32_t *)(&(THM_BASE.instance[i])); | |
| 49 | + } | |
| 50 | +} | |
| @@ -45,7 +45,7 @@ · 44 unmodified lines | ||
| 45 | 45 | #define mmUVD_SCRATCH9_INTERNAL_OFFSET 0xc01d |
| 46 | 46 | |
| 47 | 47 | #define mmUVD_LMI_RBC_IB_VMID_INTERNAL_OFFSET 0x1e1 |
| 48 | −#define mmUVD_LMI_RBC_IB_64BIT_BAR_HIGH_INTERNAL_OFFSET 0x5a6 | |
| 48 | +#define mmUVD_LMI_RBC_IB_64BIT_BAR_HIGH_INTERNAL_OFFSET 0x5a6 | |
| 49 | 49 | #define mmUVD_LMI_RBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET 0x5a7 |
| 50 | 50 | #define mmUVD_RBC_IB_SIZE_INTERNAL_OFFSET 0x1e2 |
| 51 | 51 | |
| @@ -800,7 +800,7 @@ static int vcn_v2_0_start_dpg_mode(struct amdgpu_device *adev, bool indirect) · 748 unmodified lines | ||
| 800 | 800 | WREG32_SOC15(UVD, 0, mmUVD_POWER_STATUS, tmp); |
| 801 | 801 | |
| 802 | 802 | if (indirect) |
| 803 | − adev->vcn.inst->dpg_sram_curr_addr = (uint32_t*)adev->vcn.inst->dpg_sram_cpu_addr; | |
| 803 | + adev->vcn.inst->dpg_sram_curr_addr = (uint32_t *)adev->vcn.inst->dpg_sram_cpu_addr; | |
| 804 | 804 | |
| 805 | 805 | /* enable clock gating */ |
| 806 | 806 | vcn_v2_0_clock_gating_dpg_mode(adev, 0, indirect); |
| @@ -45,7 +45,7 @@ · 44 unmodified lines | ||
| 45 | 45 | |
| 46 | 46 | #define mmUVD_LMI_RBC_IB_VMID_INTERNAL_OFFSET 0x431 |
| 47 | 47 | #define mmUVD_LMI_RBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET 0x3b4 |
| 48 | −#define mmUVD_LMI_RBC_IB_64BIT_BAR_HIGH_INTERNAL_OFFSET 0x3b5 | |
| 48 | +#define mmUVD_LMI_RBC_IB_64BIT_BAR_HIGH_INTERNAL_OFFSET 0x3b5 | |
| 49 | 49 | #define mmUVD_RBC_IB_SIZE_INTERNAL_OFFSET 0x25c |
| 50 | 50 | |
| 51 | 51 | #define VCN25_MAX_HW_INSTANCES_ARCTURUS 2 |
| @@ -777,7 +777,7 @@ static int vcn_v2_5_start_dpg_mode(struct amdgpu_device *adev, int inst_idx, boo · 725 unmodified lines | ||
| 777 | 777 | WREG32_SOC15(VCN, inst_idx, mmUVD_POWER_STATUS, tmp); |
| 778 | 778 | |
| 779 | 779 | if (indirect) |
| 780 | − adev->vcn.inst[inst_idx].dpg_sram_curr_addr = (uint32_t*)adev->vcn.inst[inst_idx].dpg_sram_cpu_addr; | |
| 780 | + adev->vcn.inst[inst_idx].dpg_sram_curr_addr = (uint32_t *)adev->vcn.inst[inst_idx].dpg_sram_cpu_addr; | |
| 781 | 781 | |
| 782 | 782 | /* enable clock gating */ |
| 783 | 783 | vcn_v2_5_clock_gating_dpg_mode(adev, 0, inst_idx, indirect); |
| @@ -44,10 +44,10 @@ · 43 unmodified lines | ||
| 44 | 44 | |
| 45 | 45 | #define mmUVD_LMI_RBC_IB_VMID_INTERNAL_OFFSET 0x431 |
| 46 | 46 | #define mmUVD_LMI_RBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET 0x3b4 |
| 47 | −#define mmUVD_LMI_RBC_IB_64BIT_BAR_HIGH_INTERNAL_OFFSET 0x3b5 | |
| 47 | +#define mmUVD_LMI_RBC_IB_64BIT_BAR_HIGH_INTERNAL_OFFSET 0x3b5 | |
| 48 | 48 | #define mmUVD_RBC_IB_SIZE_INTERNAL_OFFSET 0x25c |
| 49 | 49 | |
| 50 | −#define VCN_INSTANCES_SIENNA_CICHLID 2 | |
| 50 | +#define VCN_INSTANCES_SIENNA_CICHLID 2 | |
| 51 | 51 | |
| 52 | 52 | static int amdgpu_ih_clientid_vcns[] = { |
| 53 | 53 | SOC15_IH_CLIENTID_VCN, |
| @@ -55,8 +55,8 @@ static int amdgpu_ih_clientid_vcns[] = { · 1 unmodified line | ||
| 55 | 55 | }; |
| 56 | 56 | |
| 57 | 57 | static int amdgpu_ucode_id_vcns[] = { |
| 58 | − AMDGPU_UCODE_ID_VCN, | |
| 59 | − AMDGPU_UCODE_ID_VCN1 | |
| 58 | + AMDGPU_UCODE_ID_VCN, | |
| 59 | + AMDGPU_UCODE_ID_VCN1 | |
| 60 | 60 | }; |
| 61 | 61 | |
| 62 | 62 | static int vcn_v3_0_start_sriov(struct amdgpu_device *adev); |
| @@ -915,7 +915,7 @@ static int vcn_v3_0_start_dpg_mode(struct amdgpu_device *adev, int inst_idx, boo · 852 unmodified lines | ||
| 915 | 915 | WREG32_SOC15(VCN, inst_idx, mmUVD_POWER_STATUS, tmp); |
| 916 | 916 | |
| 917 | 917 | if (indirect) |
| 918 | − adev->vcn.inst[inst_idx].dpg_sram_curr_addr = (uint32_t*)adev->vcn.inst[inst_idx].dpg_sram_cpu_addr; | |
| 918 | + adev->vcn.inst[inst_idx].dpg_sram_curr_addr = (uint32_t *)adev->vcn.inst[inst_idx].dpg_sram_cpu_addr; | |
| 919 | 919 | |
| 920 | 920 | /* enable clock gating */ |
| 921 | 921 | vcn_v3_0_clock_gating_dpg_mode(adev, 0, inst_idx, indirect); |
| @@ -1371,7 +1371,7 @@ static int vcn_v3_0_start_sriov(struct amdgpu_device *adev) · 449 unmodified lines | ||
| 1371 | 1371 | } |
| 1372 | 1372 | |
| 1373 | 1373 | /* Update init table header in memory */ |
| 1374 | − size = sizeof(struct mmsch_v3_0_init_header); | |
| 1374 | + size = sizeof(struct mmsch_v3_0_init_header); | |
| 1375 | 1375 | table_loc = (uint32_t *)table->cpu_addr; |
| 1376 | 1376 | memcpy((void *)table_loc, &header, size); |
| 1377 | 1377 | |
| @@ -66,12 +66,12 @@ static bool cik_event_interrupt_isr(struct kfd_dev *dev, · 65 unmodified lines | ||
| 66 | 66 | vmid = (ihre->ring_id & 0x0000ff00) >> 8; |
| 67 | 67 | if (vmid < dev->vm_info.first_vmid_kfd || |
| 68 | 68 | vmid > dev->vm_info.last_vmid_kfd) |
| 69 | − return 0; | |
| 69 | + return false; | |
| 70 | 70 | |
| 71 | 71 | /* If there is no valid PASID, it's likely a firmware bug */ |
| 72 | 72 | pasid = (ihre->ring_id & 0xffff0000) >> 16; |
| 73 | 73 | if (WARN_ONCE(pasid == 0, "FW bug: No PASID in KFD interrupt")) |
| 74 | − return 0; | |
| 74 | + return false; | |
| 75 | 75 | |
| 76 | 76 | /* Interrupt types we care about: various signals and faults. |
| 77 | 77 | * They will be forwarded to a work queue (see below). |
| @@ -141,6 +141,7 @@ static struct kfd_gpu_cache_info carrizo_cache_info[] = { · 140 unmodified lines | ||
| 141 | 141 | #define renoir_cache_info carrizo_cache_info |
| 142 | 142 | /* TODO - check & update Navi10 cache details */ |
| 143 | 143 | #define navi10_cache_info carrizo_cache_info |
| 144 | +#define vangogh_cache_info carrizo_cache_info | |
| 144 | 145 | |
| 145 | 146 | static void kfd_populated_cu_info_cpu(struct kfd_topology_device *dev, |
| 146 | 147 | struct crat_subtype_computeunit *cu) |
| @@ -680,9 +681,14 @@ static int kfd_fill_gpu_cache_info(struct kfd_dev *kdev, · 533 unmodified lines | ||
| 680 | 681 | case CHIP_NAVI14: |
| 681 | 682 | case CHIP_SIENNA_CICHLID: |
| 682 | 683 | case CHIP_NAVY_FLOUNDER: |
| 684 | + case CHIP_DIMGREY_CAVEFISH: | |
| 683 | 685 | pcache_info = navi10_cache_info; |
| 684 | 686 | num_of_cache_types = ARRAY_SIZE(navi10_cache_info); |
| 685 | 687 | break; |
| 688 | + case CHIP_VANGOGH: | |
| 689 | + pcache_info = vangogh_cache_info; | |
| 690 | + num_of_cache_types = ARRAY_SIZE(vangogh_cache_info); | |
| 691 | + break; | |
| 686 | 692 | default: |
| 687 | 693 | return -EINVAL; |
| 688 | 694 | } |
| @@ -798,10 +804,10 @@ int kfd_create_crat_image_acpi(void **crat_image, size_t *size) · 109 unmodified lines | ||
| 798 | 804 | } |
| 799 | 805 | |
| 800 | 806 | pcrat_image = kvmalloc(crat_table->length, GFP_KERNEL); |
| 801 | − memcpy(pcrat_image, crat_table, crat_table->length); | |
| 802 | 807 | if (!pcrat_image) |
| 803 | 808 | return -ENOMEM; |
| 804 | 809 | |
| 810 | + memcpy(pcrat_image, crat_table, crat_table->length); | |
| 805 | 811 | *crat_image = pcrat_image; |
| 806 | 812 | *size = crat_table->length; |
| 807 | 813 | |
| @@ -76,6 +76,8 @@ static const struct kfd2kgd_calls *kfd2kgd_funcs[] = { · 75 unmodified lines | ||
| 76 | 76 | [CHIP_NAVI14] = &gfx_v10_kfd2kgd, |
| 77 | 77 | [CHIP_SIENNA_CICHLID] = &gfx_v10_3_kfd2kgd, |
| 78 | 78 | [CHIP_NAVY_FLOUNDER] = &gfx_v10_3_kfd2kgd, |
| 79 | + [CHIP_VANGOGH] = &gfx_v10_3_kfd2kgd, | |
| 80 | + [CHIP_DIMGREY_CAVEFISH] = &gfx_v10_3_kfd2kgd, | |
| 79 | 81 | }; |
| 80 | 82 | |
| 81 | 83 | #ifdef KFD_SUPPORT_IOMMU_V2 |
| @@ -498,6 +500,43 @@ static const struct kfd_device_info navy_flounder_device_info = { · 416 unmodified lines | ||
| 498 | 500 | .num_sdma_queues_per_engine = 8, |
| 499 | 501 | }; |
| 500 | 502 | |
| 503 | +static const struct kfd_device_info vangogh_device_info = { | |
| 504 | + .asic_family = CHIP_VANGOGH, | |
| 505 | + .asic_name = "vangogh", | |
| 506 | + .max_pasid_bits = 16, | |
| 507 | + .max_no_of_hqd = 24, | |
| 508 | + .doorbell_size = 8, | |
| 509 | + .ih_ring_entry_size = 8 * sizeof(uint32_t), | |
| 510 | + .event_interrupt_class = &event_interrupt_class_v9, | |
| 511 | + .num_of_watch_points = 4, | |
| 512 | + .mqd_size_aligned = MQD_SIZE_ALIGNED, | |
| 513 | + .needs_iommu_device = false, | |
| 514 | + .supports_cwsr = true, | |
| 515 | + .needs_pci_atomics = false, | |
| 516 | + .num_sdma_engines = 1, | |
| 517 | + .num_xgmi_sdma_engines = 0, | |
| 518 | + .num_sdma_queues_per_engine = 2, | |
| 519 | +}; | |
| 520 | + | |
| 521 | +static const struct kfd_device_info dimgrey_cavefish_device_info = { | |
| 522 | + .asic_family = CHIP_DIMGREY_CAVEFISH, | |
| 523 | + .asic_name = "dimgrey_cavefish", | |
| 524 | + .max_pasid_bits = 16, | |
| 525 | + .max_no_of_hqd = 24, | |
| 526 | + .doorbell_size = 8, | |
| 527 | + .ih_ring_entry_size = 8 * sizeof(uint32_t), | |
| 528 | + .event_interrupt_class = &event_interrupt_class_v9, | |
| 529 | + .num_of_watch_points = 4, | |
| 530 | + .mqd_size_aligned = MQD_SIZE_ALIGNED, | |
| 531 | + .needs_iommu_device = false, | |
| 532 | + .supports_cwsr = true, | |
| 533 | + .needs_pci_atomics = false, | |
| 534 | + .num_sdma_engines = 2, | |
| 535 | + .num_xgmi_sdma_engines = 0, | |
| 536 | + .num_sdma_queues_per_engine = 8, | |
| 537 | +}; | |
| 538 | + | |
| 539 | + | |
| 501 | 540 | /* For each entry, [0] is regular and [1] is virtualisation device. */ |
| 502 | 541 | static const struct kfd_device_info *kfd_supported_devices[][2] = { |
| 503 | 542 | #ifdef KFD_SUPPORT_IOMMU_V2 |
| @@ -522,6 +561,8 @@ static const struct kfd_device_info *kfd_supported_devices[][2] = { · 18 unmodified lines | ||
| 522 | 561 | [CHIP_NAVI14] = {&navi14_device_info, NULL}, |
| 523 | 562 | [CHIP_SIENNA_CICHLID] = {&sienna_cichlid_device_info, &sienna_cichlid_device_info}, |
| 524 | 563 | [CHIP_NAVY_FLOUNDER] = {&navy_flounder_device_info, &navy_flounder_device_info}, |
| 564 | + [CHIP_VANGOGH] = {&vangogh_device_info, NULL}, | |
| 565 | + [CHIP_DIMGREY_CAVEFISH] = {&dimgrey_cavefish_device_info, &dimgrey_cavefish_device_info}, | |
| 525 | 566 | }; |
| 526 | 567 | |
| 527 | 568 | static int kfd_gtt_sa_init(struct kfd_dev *kfd, unsigned int buf_size, |
| @@ -716,8 +757,6 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd, · 188 unmodified lines | ||
| 716 | 757 | |
| 717 | 758 | kfd->hive_id = amdgpu_amdkfd_get_hive_id(kfd->kgd); |
| 718 | 759 | |
| 719 | − kfd->unique_id = amdgpu_amdkfd_get_unique_id(kfd->kgd); | |
| 720 | − | |
| 721 | 760 | kfd->noretry = amdgpu_amdkfd_get_noretry(kfd->kgd); |
| 722 | 761 | |
| 723 | 762 | if (kfd_interrupt_init(kfd)) { |
| @@ -1925,6 +1925,8 @@ struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev) · 1924 unmodified lines | ||
| 1925 | 1925 | case CHIP_NAVI14: |
| 1926 | 1926 | case CHIP_SIENNA_CICHLID: |
| 1927 | 1927 | case CHIP_NAVY_FLOUNDER: |
| 1928 | + case CHIP_VANGOGH: | |
| 1929 | + case CHIP_DIMGREY_CAVEFISH: | |
| 1928 | 1930 | device_queue_manager_init_v10_navi10(&dqm->asic_ops); |
| 1929 | 1931 | break; |
| 1930 | 1932 | default: |
| @@ -417,6 +417,8 @@ int kfd_init_apertures(struct kfd_process *process) · 416 unmodified lines | ||
| 417 | 417 | case CHIP_NAVI14: |
| 418 | 418 | case CHIP_SIENNA_CICHLID: |
| 419 | 419 | case CHIP_NAVY_FLOUNDER: |
| 420 | + case CHIP_VANGOGH: | |
| 421 | + case CHIP_DIMGREY_CAVEFISH: | |
| 420 | 422 | kfd_init_apertures_v9(pdd, id); |
| 421 | 423 | break; |
| 422 | 424 | default: |
| @@ -247,6 +247,8 @@ int pm_init(struct packet_manager *pm, struct device_queue_manager *dqm) · 246 unmodified lines | ||
| 247 | 247 | case CHIP_NAVI14: |
| 248 | 248 | case CHIP_SIENNA_CICHLID: |
| 249 | 249 | case CHIP_NAVY_FLOUNDER: |
| 250 | + case CHIP_VANGOGH: | |
| 251 | + case CHIP_DIMGREY_CAVEFISH: | |
| 250 | 252 | pm->pmf = &kfd_v9_pm_funcs; |
| 251 | 253 | break; |
| 252 | 254 | default: |
| @@ -292,9 +292,6 @@ struct kfd_dev { · 291 unmodified lines | ||
| 292 | 292 | /* xGMI */ |
| 293 | 293 | uint64_t hive_id; |
| 294 | 294 | |
| 295 | − /* UUID */ | |
| 296 | − uint64_t unique_id; | |
| 297 | − | |
| 298 | 295 | bool pci_atomic_requested; |
| 299 | 296 | |
| 300 | 297 | /* Use IOMMU v2 flag */ |
| @@ -1340,7 +1340,7 @@ int kfd_topology_add_device(struct kfd_dev *gpu) · 1339 unmodified lines | ||
| 1340 | 1340 | dev->gpu->dqm->sched_policy != KFD_SCHED_POLICY_NO_HWS) ? |
| 1341 | 1341 | amdgpu_amdkfd_get_num_gws(dev->gpu->kgd) : 0; |
| 1342 | 1342 | dev->node_props.num_cp_queues = get_cp_queues_num(dev->gpu->dqm); |
| 1343 | − dev->node_props.unique_id = gpu->unique_id; | |
| 1343 | + dev->node_props.unique_id = amdgpu_amdkfd_get_unique_id(dev->gpu->kgd); | |
| 1344 | 1344 | |
| 1345 | 1345 | kfd_fill_mem_clk_max_info(dev); |
| 1346 | 1346 | kfd_fill_iolink_non_crat_info(dev); |
| @@ -1375,6 +1375,8 @@ int kfd_topology_add_device(struct kfd_dev *gpu) · 28 unmodified lines | ||
| 1375 | 1375 | case CHIP_NAVI14: |
| 1376 | 1376 | case CHIP_SIENNA_CICHLID: |
| 1377 | 1377 | case CHIP_NAVY_FLOUNDER: |
| 1378 | + case CHIP_VANGOGH: | |
| 1379 | + case CHIP_DIMGREY_CAVEFISH: | |
| 1378 | 1380 | dev->node_props.capability |= ((HSA_CAP_DOORBELL_TYPE_2_0 << |
| 1379 | 1381 | HSA_CAP_DOORBELL_TYPE_TOTALBITS_SHIFT) & |
| 1380 | 1382 | HSA_CAP_DOORBELL_TYPE_TOTALBITS_MASK); |
| @@ -15,15 +15,7 @@ config DRM_AMD_DC · 14 unmodified lines | ||
| 15 | 15 | config DRM_AMD_DC_DCN |
| 16 | 16 | def_bool n |
| 17 | 17 | help |
| 18 | − Raven, Navi and Renoir family support for display engine | |
| 19 | − | |
| 20 | −config DRM_AMD_DC_DCN3_0 | |
| 21 | − bool "DCN 3.0 family" | |
| 22 | − depends on DRM_AMD_DC && X86 | |
| 23 | − depends on DRM_AMD_DC_DCN | |
| 24 | − help | |
| 25 | − Choose this option if you want to have | |
| 26 | − sienna_cichlid support for display engine | |
| 18 | + Raven, Navi, and newer family support for display engine | |
| 27 | 19 | |
| 28 | 20 | config DRM_AMD_DC_HDCP |
| 29 | 21 | bool "Enable HDCP support in DC" |
| @@ -34,6 +34,7 @@ · 33 unmodified lines | ||
| 34 | 34 | #include "dc/inc/hw/dmcu.h" |
| 35 | 35 | #include "dc/inc/hw/abm.h" |
| 36 | 36 | #include "dc/dc_dmub_srv.h" |
| 37 | +#include "amdgpu_dm_trace.h" | |
| 37 | 38 | |
| 38 | 39 | #include "vid.h" |
| 39 | 40 | #include "amdgpu.h" |
| @@ -94,12 +95,16 @@ · 54 unmodified lines | ||
| 94 | 95 | |
| 95 | 96 | #define FIRMWARE_RENOIR_DMUB "amdgpu/renoir_dmcub.bin" |
| 96 | 97 | MODULE_FIRMWARE(FIRMWARE_RENOIR_DMUB); |
| 97 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 98 | 98 | #define FIRMWARE_SIENNA_CICHLID_DMUB "amdgpu/sienna_cichlid_dmcub.bin" |
| 99 | 99 | MODULE_FIRMWARE(FIRMWARE_SIENNA_CICHLID_DMUB); |
| 100 | 100 | #define FIRMWARE_NAVY_FLOUNDER_DMUB "amdgpu/navy_flounder_dmcub.bin" |
| 101 | 101 | MODULE_FIRMWARE(FIRMWARE_NAVY_FLOUNDER_DMUB); |
| 102 | −#endif | |
| 102 | +#define FIRMWARE_GREEN_SARDINE_DMUB "amdgpu/green_sardine_dmcub.bin" | |
| 103 | +MODULE_FIRMWARE(FIRMWARE_GREEN_SARDINE_DMUB); | |
| 104 | +#define FIRMWARE_VANGOGH_DMUB "amdgpu/vangogh_dmcub.bin" | |
| 105 | +MODULE_FIRMWARE(FIRMWARE_VANGOGH_DMUB); | |
| 106 | +#define FIRMWARE_DIMGREY_CAVEFISH_DMUB "amdgpu/dimgrey_cavefish_dmcub.bin" | |
| 107 | +MODULE_FIRMWARE(FIRMWARE_DIMGREY_CAVEFISH_DMUB); | |
| 103 | 108 | |
| 104 | 109 | #define FIRMWARE_RAVEN_DMCU "amdgpu/raven_dmcu.bin" |
| 105 | 110 | MODULE_FIRMWARE(FIRMWARE_RAVEN_DMCU); |
| @@ -209,6 +214,9 @@ static bool amdgpu_dm_link_setup_psr(struct dc_stream_state *stream); · 103 unmodified lines | ||
| 209 | 214 | static bool amdgpu_dm_psr_disable(struct dc_stream_state *stream); |
| 210 | 215 | static bool amdgpu_dm_psr_disable_all(struct amdgpu_display_manager *dm); |
| 211 | 216 | |
| 217 | +static const struct drm_format_info * | |
| 218 | +amd_get_format_info(const struct drm_mode_fb_cmd2 *cmd); | |
| 219 | + | |
| 212 | 220 | /* |
| 213 | 221 | * dm_vblank_get_counter |
| 214 | 222 | * |
| @@ -583,7 +591,7 @@ static void amdgpu_dm_fbc_init(struct drm_connector *connector) · 368 unmodified lines | ||
| 583 | 591 | { |
| 584 | 592 | struct drm_device *dev = connector->dev; |
| 585 | 593 | struct amdgpu_device *adev = drm_to_adev(dev); |
| 586 | − struct dm_comressor_info *compressor = &adev->dm.compressor; | |
| 594 | + struct dm_compressor_info *compressor = &adev->dm.compressor; | |
| 587 | 595 | struct amdgpu_dm_connector *aconn = to_amdgpu_dm_connector(connector); |
| 588 | 596 | struct drm_display_mode *mode; |
| 589 | 597 | unsigned long max_size = 0; |
| @@ -880,44 +888,60 @@ static int dm_dmub_hw_init(struct amdgpu_device *adev) · 290 unmodified lines | ||
| 880 | 888 | return 0; |
| 881 | 889 | } |
| 882 | 890 | |
| 883 | −static void amdgpu_check_debugfs_connector_property_change(struct amdgpu_device *adev, | |
| 884 | − struct drm_atomic_state *state) | |
| 891 | +#if defined(CONFIG_DRM_AMD_DC_DCN) | |
| 892 | +static void mmhub_read_system_context(struct amdgpu_device *adev, struct dc_phy_addr_space_config *pa_config) | |
| 885 | 893 | { |
| 886 | − struct drm_connector *connector; | |
| 887 | − struct drm_crtc *crtc; | |
| 888 | − struct amdgpu_dm_connector *amdgpu_dm_connector; | |
| 889 | − struct drm_connector_state *conn_state; | |
| 890 | − struct dm_crtc_state *acrtc_state; | |
| 891 | − struct drm_crtc_state *crtc_state; | |
| 892 | − struct dc_stream_state *stream; | |
| 893 | − struct drm_device *dev = adev_to_drm(adev); | |
| 894 | + uint64_t pt_base; | |
| 895 | + uint32_t logical_addr_low; | |
| 896 | + uint32_t logical_addr_high; | |
| 897 | + uint32_t agp_base, agp_bot, agp_top; | |
| 898 | + PHYSICAL_ADDRESS_LOC page_table_start, page_table_end, page_table_base; | |
| 894 | 899 | |
| 895 | − list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | |
| 900 | + logical_addr_low = min(adev->gmc.fb_start, adev->gmc.agp_start) >> 18; | |
| 901 | + pt_base = amdgpu_gmc_pd_addr(adev->gart.bo); | |
| 896 | 902 | |
| 897 | − amdgpu_dm_connector = to_amdgpu_dm_connector(connector); | |
| 898 | − conn_state = connector->state; | |
| 903 | + if (adev->apu_flags & AMD_APU_IS_RAVEN2) | |
| 904 | + /* | |
| 905 | + * Raven2 has a HW issue that it is unable to use the vram which | |
| 906 | + * is out of MC_VM_SYSTEM_APERTURE_HIGH_ADDR. So here is the | |
| 907 | + * workaround that increase system aperture high address (add 1) | |
| 908 | + * to get rid of the VM fault and hardware hang. | |
| 909 | + */ | |
| 910 | + logical_addr_high = max((adev->gmc.fb_end >> 18) + 0x1, adev->gmc.agp_end >> 18); | |
| 911 | + else | |
| 912 | + logical_addr_high = max(adev->gmc.fb_end, adev->gmc.agp_end) >> 18; | |
| 899 | 913 | |
| 900 | − if (!(conn_state && conn_state->crtc)) | |
| 901 | − continue; | |
| 914 | + agp_base = 0; | |
| 915 | + agp_bot = adev->gmc.agp_start >> 24; | |
| 916 | + agp_top = adev->gmc.agp_end >> 24; | |
| 902 | 917 | |
| 903 | − crtc = conn_state->crtc; | |
| 904 | − acrtc_state = to_dm_crtc_state(crtc->state); | |
| 905 | 918 | |
| 906 | − if (!(acrtc_state && acrtc_state->stream)) | |
| 907 | − continue; | |
| 919 | + page_table_start.high_part = (u32)(adev->gmc.gart_start >> 44) & 0xF; | |
| 920 | + page_table_start.low_part = (u32)(adev->gmc.gart_start >> 12); | |
| 921 | + page_table_end.high_part = (u32)(adev->gmc.gart_end >> 44) & 0xF; | |
| 922 | + page_table_end.low_part = (u32)(adev->gmc.gart_end >> 12); | |
| 923 | + page_table_base.high_part = upper_32_bits(pt_base) & 0xF; | |
| 924 | + page_table_base.low_part = lower_32_bits(pt_base); | |
| 908 | 925 | |
| 909 | − stream = acrtc_state->stream; | |
| 926 | + pa_config->system_aperture.start_addr = (uint64_t)logical_addr_low << 18; | |
| 927 | + pa_config->system_aperture.end_addr = (uint64_t)logical_addr_high << 18; | |
| 928 | + | |
| 929 | + pa_config->system_aperture.agp_base = (uint64_t)agp_base << 24 ; | |
| 930 | + pa_config->system_aperture.agp_bot = (uint64_t)agp_bot << 24; | |
| 931 | + pa_config->system_aperture.agp_top = (uint64_t)agp_top << 24; | |
| 932 | + | |
| 933 | + pa_config->system_aperture.fb_base = adev->gmc.fb_start; | |
| 934 | + pa_config->system_aperture.fb_offset = adev->gmc.aper_base; | |
| 935 | + pa_config->system_aperture.fb_top = adev->gmc.fb_end; | |
| 936 | + | |
| 937 | + pa_config->gart_config.page_table_start_addr = page_table_start.quad_part << 12; | |
| 938 | + pa_config->gart_config.page_table_end_addr = page_table_end.quad_part << 12; | |
| 939 | + pa_config->gart_config.page_table_base_addr = page_table_base.quad_part; | |
| 940 | + | |
| 941 | + pa_config->is_hvm_enabled = 0; | |
| 910 | 942 | |
| 911 | − if (amdgpu_dm_connector->dsc_settings.dsc_force_enable || | |
| 912 | − amdgpu_dm_connector->dsc_settings.dsc_num_slices_v || | |
| 913 | − amdgpu_dm_connector->dsc_settings.dsc_num_slices_h || | |
| 914 | − amdgpu_dm_connector->dsc_settings.dsc_bits_per_pixel) { | |
| 915 | − conn_state = drm_atomic_get_connector_state(state, connector); | |
| 916 | − crtc_state = drm_atomic_get_crtc_state(state, crtc); | |
| 917 | − crtc_state->mode_changed = true; | |
| 918 | − } | |
| 919 | − } | |
| 920 | 943 | } |
| 944 | +#endif | |
| 921 | 945 | |
| 922 | 946 | static int amdgpu_dm_init(struct amdgpu_device *adev) |
| 923 | 947 | { |
| @@ -973,6 +997,8 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) · 49 unmodified lines | ||
| 973 | 997 | case CHIP_RAVEN: |
| 974 | 998 | case CHIP_RENOIR: |
| 975 | 999 | init_data.flags.gpu_vm_support = true; |
| 1000 | + if (ASICREV_IS_GREEN_SARDINE(adev->external_rev_id)) | |
| 1001 | + init_data.flags.disable_dmcu = true; | |
| 976 | 1002 | break; |
| 977 | 1003 | default: |
| 978 | 1004 | break; |
| @@ -1026,6 +1052,17 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) · 47 unmodified lines | ||
| 1026 | 1052 | |
| 1027 | 1053 | dc_hardware_init(adev->dm.dc); |
| 1028 | 1054 | |
| 1055 | +#if defined(CONFIG_DRM_AMD_DC_DCN) | |
| 1056 | + if (adev->asic_type == CHIP_RENOIR) { | |
| 1057 | + struct dc_phy_addr_space_config pa_config; | |
| 1058 | + | |
| 1059 | + mmhub_read_system_context(adev, &pa_config); | |
| 1060 | + | |
| 1061 | + // Call the DC init_memory func | |
| 1062 | + dc_setup_system_context(adev->dm.dc, &pa_config); | |
| 1063 | + } | |
| 1064 | +#endif | |
| 1065 | + | |
| 1029 | 1066 | adev->dm.freesync_module = mod_freesync_create(adev->dm.dc); |
| 1030 | 1067 | if (!adev->dm.freesync_module) { |
| 1031 | 1068 | DRM_ERROR( |
| @@ -1072,6 +1109,7 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) · 40 unmodified lines | ||
| 1072 | 1109 | goto error; |
| 1073 | 1110 | } |
| 1074 | 1111 | |
| 1112 | + | |
| 1075 | 1113 | DRM_DEBUG_DRIVER("KMS initialized.\n"); |
| 1076 | 1114 | |
| 1077 | 1115 | return 0; |
| @@ -1168,10 +1206,10 @@ static int load_dmcu_fw(struct amdgpu_device *adev) · 90 unmodified lines | ||
| 1168 | 1206 | case CHIP_NAVI10: |
| 1169 | 1207 | case CHIP_NAVI14: |
| 1170 | 1208 | case CHIP_RENOIR: |
| 1171 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 1172 | 1209 | case CHIP_SIENNA_CICHLID: |
| 1173 | 1210 | case CHIP_NAVY_FLOUNDER: |
| 1174 | −#endif | |
| 1211 | + case CHIP_DIMGREY_CAVEFISH: | |
| 1212 | + case CHIP_VANGOGH: | |
| 1175 | 1213 | return 0; |
| 1176 | 1214 | case CHIP_NAVI12: |
| 1177 | 1215 | fw_name_dmcu = FIRMWARE_NAVI12_DMCU; |
| @@ -1267,8 +1305,9 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev) · 89 unmodified lines | ||
| 1267 | 1305 | case CHIP_RENOIR: |
| 1268 | 1306 | dmub_asic = DMUB_ASIC_DCN21; |
| 1269 | 1307 | fw_name_dmub = FIRMWARE_RENOIR_DMUB; |
| 1308 | + if (ASICREV_IS_GREEN_SARDINE(adev->external_rev_id)) | |
| 1309 | + fw_name_dmub = FIRMWARE_GREEN_SARDINE_DMUB; | |
| 1270 | 1310 | break; |
| 1271 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 1272 | 1311 | case CHIP_SIENNA_CICHLID: |
| 1273 | 1312 | dmub_asic = DMUB_ASIC_DCN30; |
| 1274 | 1313 | fw_name_dmub = FIRMWARE_SIENNA_CICHLID_DMUB; |
| @@ -1277,7 +1316,14 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev) · 2 unmodified lines | ||
| 1277 | 1316 | dmub_asic = DMUB_ASIC_DCN30; |
| 1278 | 1317 | fw_name_dmub = FIRMWARE_NAVY_FLOUNDER_DMUB; |
| 1279 | 1318 | break; |
| 1280 | −#endif | |
| 1319 | + case CHIP_VANGOGH: | |
| 1320 | + dmub_asic = DMUB_ASIC_DCN301; | |
| 1321 | + fw_name_dmub = FIRMWARE_VANGOGH_DMUB; | |
| 1322 | + break; | |
| 1323 | + case CHIP_DIMGREY_CAVEFISH: | |
| 1324 | + dmub_asic = DMUB_ASIC_DCN302; | |
| 1325 | + fw_name_dmub = FIRMWARE_DIMGREY_CAVEFISH_DMUB; | |
| 1326 | + break; | |
| 1281 | 1327 | |
| 1282 | 1328 | default: |
| 1283 | 1329 | /* ASIC doesn't support DMUB. */ |
| @@ -2095,6 +2141,7 @@ const struct amdgpu_ip_block_version dm_ip_block = · 811 unmodified lines | ||
| 2095 | 2141 | |
| 2096 | 2142 | static const struct drm_mode_config_funcs amdgpu_dm_mode_funcs = { |
| 2097 | 2143 | .fb_create = amdgpu_display_user_framebuffer_create, |
| 2144 | + .get_format_info = amd_get_format_info, | |
| 2098 | 2145 | .output_poll_changed = drm_fb_helper_output_poll_changed, |
| 2099 | 2146 | .atomic_check = amdgpu_dm_atomic_check, |
| 2100 | 2147 | .atomic_commit = amdgpu_dm_atomic_commit, |
| @@ -3396,10 +3443,10 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) · 1295 unmodified lines | ||
| 3396 | 3443 | case CHIP_NAVI10: |
| 3397 | 3444 | case CHIP_NAVI14: |
| 3398 | 3445 | case CHIP_RENOIR: |
| 3399 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 3400 | 3446 | case CHIP_SIENNA_CICHLID: |
| 3401 | 3447 | case CHIP_NAVY_FLOUNDER: |
| 3402 | −#endif | |
| 3448 | + case CHIP_DIMGREY_CAVEFISH: | |
| 3449 | + case CHIP_VANGOGH: | |
| 3403 | 3450 | if (dcn10_register_irq_handlers(dm->adev)) { |
| 3404 | 3451 | DRM_ERROR("DM: Failed to initialize IRQ\n"); |
| 3405 | 3452 | goto fail; |
| @@ -3558,31 +3605,27 @@ static int dm_early_init(void *handle) · 152 unmodified lines | ||
| 3558 | 3605 | break; |
| 3559 | 3606 | #if defined(CONFIG_DRM_AMD_DC_DCN) |
| 3560 | 3607 | case CHIP_RAVEN: |
| 3608 | + case CHIP_RENOIR: | |
| 3609 | + case CHIP_VANGOGH: | |
| 3561 | 3610 | adev->mode_info.num_crtc = 4; |
| 3562 | 3611 | adev->mode_info.num_hpd = 4; |
| 3563 | 3612 | adev->mode_info.num_dig = 4; |
| 3564 | 3613 | break; |
| 3565 | −#endif | |
| 3566 | 3614 | case CHIP_NAVI10: |
| 3567 | 3615 | case CHIP_NAVI12: |
| 3568 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 3569 | 3616 | case CHIP_SIENNA_CICHLID: |
| 3570 | 3617 | case CHIP_NAVY_FLOUNDER: |
| 3571 | −#endif | |
| 3572 | 3618 | adev->mode_info.num_crtc = 6; |
| 3573 | 3619 | adev->mode_info.num_hpd = 6; |
| 3574 | 3620 | adev->mode_info.num_dig = 6; |
| 3575 | 3621 | break; |
| 3576 | 3622 | case CHIP_NAVI14: |
| 3623 | + case CHIP_DIMGREY_CAVEFISH: | |
| 3577 | 3624 | adev->mode_info.num_crtc = 5; |
| 3578 | 3625 | adev->mode_info.num_hpd = 5; |
| 3579 | 3626 | adev->mode_info.num_dig = 5; |
| 3580 | 3627 | break; |
| 3581 | − case CHIP_RENOIR: | |
| 3582 | − adev->mode_info.num_crtc = 4; | |
| 3583 | − adev->mode_info.num_hpd = 4; | |
| 3584 | − adev->mode_info.num_dig = 4; | |
| 3585 | − break; | |
| 3628 | +#endif | |
| 3586 | 3629 | default: |
| 3587 | 3630 | DRM_ERROR("Unsupported ASIC type: 0x%X\n", adev->asic_type); |
| 3588 | 3631 | return -EINVAL; |
| @@ -3686,78 +3729,84 @@ static int fill_dc_scaling_info(const struct drm_plane_state *state, · 97 unmodified lines | ||
| 3686 | 3729 | return 0; |
| 3687 | 3730 | } |
| 3688 | 3731 | |
| 3689 | −static int get_fb_info(const struct amdgpu_framebuffer *amdgpu_fb, | |
| 3690 | − uint64_t *tiling_flags, bool *tmz_surface) | |
| 3732 | +static void | |
| 3733 | +fill_gfx8_tiling_info_from_flags(union dc_tiling_info *tiling_info, | |
| 3734 | + uint64_t tiling_flags) | |
| 3691 | 3735 | { |
| 3692 | − struct amdgpu_bo *rbo; | |
| 3693 | − int r; | |
| 3694 | − | |
| 3695 | − if (!amdgpu_fb) { | |
| 3696 | − *tiling_flags = 0; | |
| 3697 | − *tmz_surface = false; | |
| 3698 | − return 0; | |
| 3699 | − } | |
| 3736 | + /* Fill GFX8 params */ | |
| 3737 | + if (AMDGPU_TILING_GET(tiling_flags, ARRAY_MODE) == DC_ARRAY_2D_TILED_THIN1) { | |
| 3738 | + unsigned int bankw, bankh, mtaspect, tile_split, num_banks; | |
| 3700 | 3739 | |
| 3701 | − rbo = gem_to_amdgpu_bo(amdgpu_fb->base.obj[0]); | |
| 3702 | − r = amdgpu_bo_reserve(rbo, false); | |
| 3740 | + bankw = AMDGPU_TILING_GET(tiling_flags, BANK_WIDTH); | |
| 3741 | + bankh = AMDGPU_TILING_GET(tiling_flags, BANK_HEIGHT); | |
| 3742 | + mtaspect = AMDGPU_TILING_GET(tiling_flags, MACRO_TILE_ASPECT); | |
| 3743 | + tile_split = AMDGPU_TILING_GET(tiling_flags, TILE_SPLIT); | |
| 3744 | + num_banks = AMDGPU_TILING_GET(tiling_flags, NUM_BANKS); | |
| 3703 | 3745 | |
| 3704 | − if (unlikely(r)) { | |
| 3705 | − /* Don't show error message when returning -ERESTARTSYS */ | |
| 3706 | − if (r != -ERESTARTSYS) | |
| 3707 | − DRM_ERROR("Unable to reserve buffer: %d\n", r); | |
| 3708 | − return r; | |
| 3746 | + /* XXX fix me for VI */ | |
| 3747 | + tiling_info->gfx8.num_banks = num_banks; | |
| 3748 | + tiling_info->gfx8.array_mode = | |
| 3749 | + DC_ARRAY_2D_TILED_THIN1; | |
| 3750 | + tiling_info->gfx8.tile_split = tile_split; | |
| 3751 | + tiling_info->gfx8.bank_width = bankw; | |
| 3752 | + tiling_info->gfx8.bank_height = bankh; | |
| 3753 | + tiling_info->gfx8.tile_aspect = mtaspect; | |
| 3754 | + tiling_info->gfx8.tile_mode = | |
| 3755 | + DC_ADDR_SURF_MICRO_TILING_DISPLAY; | |
| 3756 | + } else if (AMDGPU_TILING_GET(tiling_flags, ARRAY_MODE) | |
| 3757 | + == DC_ARRAY_1D_TILED_THIN1) { | |
| 3758 | + tiling_info->gfx8.array_mode = DC_ARRAY_1D_TILED_THIN1; | |
| 3709 | 3759 | } |
| 3710 | 3760 | |
| 3711 | − if (tiling_flags) | |
| 3712 | − amdgpu_bo_get_tiling_flags(rbo, tiling_flags); | |
| 3713 | − | |
| 3714 | − if (tmz_surface) | |
| 3715 | − *tmz_surface = amdgpu_bo_encrypted(rbo); | |
| 3716 | − | |
| 3717 | − amdgpu_bo_unreserve(rbo); | |
| 3718 | − | |
| 3719 | − return r; | |
| 3761 | + tiling_info->gfx8.pipe_config = | |
| 3762 | + AMDGPU_TILING_GET(tiling_flags, PIPE_CONFIG); | |
| 3720 | 3763 | } |
| 3721 | 3764 | |
| 3722 | −static inline uint64_t get_dcc_address(uint64_t address, uint64_t tiling_flags) | |
| 3723 | −{ | |
| 3724 | − uint32_t offset = AMDGPU_TILING_GET(tiling_flags, DCC_OFFSET_256B); | |
| 3725 | − | |
| 3726 | − return offset ? (address + offset * 256) : 0; | |
| 3765 | +static void | |
| 3766 | +fill_gfx9_tiling_info_from_device(const struct amdgpu_device *adev, | |
| 3767 | + union dc_tiling_info *tiling_info) | |
| 3768 | +{ | |
| 3769 | + tiling_info->gfx9.num_pipes = | |
| 3770 | + adev->gfx.config.gb_addr_config_fields.num_pipes; | |
| 3771 | + tiling_info->gfx9.num_banks = | |
| 3772 | + adev->gfx.config.gb_addr_config_fields.num_banks; | |
| 3773 | + tiling_info->gfx9.pipe_interleave = | |
| 3774 | + adev->gfx.config.gb_addr_config_fields.pipe_interleave_size; | |
| 3775 | + tiling_info->gfx9.num_shader_engines = | |
| 3776 | + adev->gfx.config.gb_addr_config_fields.num_se; | |
| 3777 | + tiling_info->gfx9.max_compressed_frags = | |
| 3778 | + adev->gfx.config.gb_addr_config_fields.max_compress_frags; | |
| 3779 | + tiling_info->gfx9.num_rb_per_se = | |
| 3780 | + adev->gfx.config.gb_addr_config_fields.num_rb_per_se; | |
| 3781 | + tiling_info->gfx9.shaderEnable = 1; | |
| 3782 | + if (adev->asic_type == CHIP_SIENNA_CICHLID || | |
| 3783 | + adev->asic_type == CHIP_NAVY_FLOUNDER || | |
| 3784 | + adev->asic_type == CHIP_DIMGREY_CAVEFISH || | |
| 3785 | + adev->asic_type == CHIP_VANGOGH) | |
| 3786 | + tiling_info->gfx9.num_pkrs = adev->gfx.config.gb_addr_config_fields.num_pkrs; | |
| 3727 | 3787 | } |
| 3728 | 3788 | |
| 3729 | 3789 | static int |
| 3730 | −fill_plane_dcc_attributes(struct amdgpu_device *adev, | |
| 3731 | − const struct amdgpu_framebuffer *afb, | |
| 3732 | − const enum surface_pixel_format format, | |
| 3733 | − const enum dc_rotation_angle rotation, | |
| 3734 | − const struct plane_size *plane_size, | |
| 3735 | − const union dc_tiling_info *tiling_info, | |
| 3736 | − const uint64_t info, | |
| 3737 | − struct dc_plane_dcc_param *dcc, | |
| 3738 | − struct dc_plane_address *address, | |
| 3739 | − bool force_disable_dcc) | |
| 3790 | +validate_dcc(struct amdgpu_device *adev, | |
| 3791 | + const enum surface_pixel_format format, | |
| 3792 | + const enum dc_rotation_angle rotation, | |
| 3793 | + const union dc_tiling_info *tiling_info, | |
| 3794 | + const struct dc_plane_dcc_param *dcc, | |
| 3795 | + const struct dc_plane_address *address, | |
| 3796 | + const struct plane_size *plane_size) | |
| 3740 | 3797 | { |
| 3741 | 3798 | struct dc *dc = adev->dm.dc; |
| 3742 | 3799 | struct dc_dcc_surface_param input; |
| 3743 | 3800 | struct dc_surface_dcc_cap output; |
| 3744 | − uint32_t offset = AMDGPU_TILING_GET(info, DCC_OFFSET_256B); | |
| 3745 | − uint32_t i64b = AMDGPU_TILING_GET(info, DCC_INDEPENDENT_64B) != 0; | |
| 3746 | − uint64_t dcc_address; | |
| 3747 | 3801 | |
| 3748 | 3802 | memset(&input, 0, sizeof(input)); |
| 3749 | 3803 | memset(&output, 0, sizeof(output)); |
| 3750 | 3804 | |
| 3751 | − if (force_disable_dcc) | |
| 3805 | + if (!dcc->enable) | |
| 3752 | 3806 | return 0; |
| 3753 | 3807 | |
| 3754 | − if (!offset) | |
| 3755 | − return 0; | |
| 3756 | − | |
| 3757 | − if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) | |
| 3758 | − return 0; | |
| 3759 | − | |
| 3760 | − if (!dc->cap_funcs.get_dcc_compression_cap) | |
| 3808 | + if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN || | |
| 3809 | + !dc->cap_funcs.get_dcc_compression_cap) | |
| 3761 | 3810 | return -EINVAL; |
| 3762 | 3811 | |
| 3763 | 3812 | input.format = format; |
| @@ -3776,17 +3825,508 @@ fill_plane_dcc_attributes(struct amdgpu_device *adev, · 12 unmodified lines | ||
| 3776 | 3825 | if (!output.capable) |
| 3777 | 3826 | return -EINVAL; |
| 3778 | 3827 | |
| 3779 | − if (i64b == 0 && output.grph.rgb.independent_64b_blks != 0) | |
| 3828 | + if (dcc->independent_64b_blks == 0 && | |
| 3829 | + output.grph.rgb.independent_64b_blks != 0) | |
| 3780 | 3830 | return -EINVAL; |
| 3781 | 3831 | |
| 3782 | − dcc->enable = 1; | |
| 3783 | − dcc->meta_pitch = | |
| 3784 | − AMDGPU_TILING_GET(info, DCC_PITCH_MAX) + 1; | |
| 3785 | − dcc->independent_64b_blks = i64b; | |
| 3832 | + return 0; | |
| 3833 | +} | |
| 3834 | + | |
| 3835 | +static bool | |
| 3836 | +modifier_has_dcc(uint64_t modifier) | |
| 3837 | +{ | |
| 3838 | + return IS_AMD_FMT_MOD(modifier) && AMD_FMT_MOD_GET(DCC, modifier); | |
| 3839 | +} | |
| 3840 | + | |
| 3841 | +static unsigned | |
| 3842 | +modifier_gfx9_swizzle_mode(uint64_t modifier) | |
| 3843 | +{ | |
| 3844 | + if (modifier == DRM_FORMAT_MOD_LINEAR) | |
| 3845 | + return 0; | |
| 3846 | + | |
| 3847 | + return AMD_FMT_MOD_GET(TILE, modifier); | |
| 3848 | +} | |
| 3849 | + | |
| 3850 | +static const struct drm_format_info dcc_formats[] = { | |
| 3851 | + { .format = DRM_FORMAT_XRGB8888, .depth = 24, .num_planes = 2, | |
| 3852 | + .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 1, .vsub = 1, }, | |
| 3853 | + { .format = DRM_FORMAT_XBGR8888, .depth = 24, .num_planes = 2, | |
| 3854 | + .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 1, .vsub = 1, }, | |
| 3855 | + { .format = DRM_FORMAT_ARGB8888, .depth = 32, .num_planes = 2, | |
| 3856 | + .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 1, .vsub = 1, | |
| 3857 | + .has_alpha = true, }, | |
| 3858 | + { .format = DRM_FORMAT_ABGR8888, .depth = 32, .num_planes = 2, | |
| 3859 | + .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 1, .vsub = 1, | |
| 3860 | + .has_alpha = true, }, | |
| 3861 | + { .format = DRM_FORMAT_BGRA8888, .depth = 32, .num_planes = 2, | |
| 3862 | + .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 1, .vsub = 1, | |
| 3863 | + .has_alpha = true, }, | |
| 3864 | + { .format = DRM_FORMAT_XRGB2101010, .depth = 30, .num_planes = 2, | |
| 3865 | + .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 1, .vsub = 1, }, | |
| 3866 | + { .format = DRM_FORMAT_XBGR2101010, .depth = 30, .num_planes = 2, | |
| 3867 | + .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 1, .vsub = 1, }, | |
| 3868 | + { .format = DRM_FORMAT_ARGB2101010, .depth = 30, .num_planes = 2, | |
| 3869 | + .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 1, .vsub = 1, | |
| 3870 | + .has_alpha = true, }, | |
| 3871 | + { .format = DRM_FORMAT_ABGR2101010, .depth = 30, .num_planes = 2, | |
| 3872 | + .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 1, .vsub = 1, | |
| 3873 | + .has_alpha = true, }, | |
| 3874 | + { .format = DRM_FORMAT_RGB565, .depth = 16, .num_planes = 2, | |
| 3875 | + .cpp = { 2, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 1, .vsub = 1, }, | |
| 3876 | +}; | |
| 3877 | + | |
| 3878 | +static const struct drm_format_info dcc_retile_formats[] = { | |
| 3879 | + { .format = DRM_FORMAT_XRGB8888, .depth = 24, .num_planes = 3, | |
| 3880 | + .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 1, .vsub = 1, }, | |
| 3881 | + { .format = DRM_FORMAT_XBGR8888, .depth = 24, .num_planes = 3, | |
| 3882 | + .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 1, .vsub = 1, }, | |
| 3883 | + { .format = DRM_FORMAT_ARGB8888, .depth = 32, .num_planes = 3, | |
| 3884 | + .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 1, .vsub = 1, | |
| 3885 | + .has_alpha = true, }, | |
| 3886 | + { .format = DRM_FORMAT_ABGR8888, .depth = 32, .num_planes = 3, | |
| 3887 | + .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 1, .vsub = 1, | |
| 3888 | + .has_alpha = true, }, | |
| 3889 | + { .format = DRM_FORMAT_BGRA8888, .depth = 32, .num_planes = 3, | |
| 3890 | + .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 1, .vsub = 1, | |
| 3891 | + .has_alpha = true, }, | |
| 3892 | + { .format = DRM_FORMAT_XRGB2101010, .depth = 30, .num_planes = 3, | |
| 3893 | + .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 1, .vsub = 1, }, | |
| 3894 | + { .format = DRM_FORMAT_XBGR2101010, .depth = 30, .num_planes = 3, | |
| 3895 | + .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 1, .vsub = 1, }, | |
| 3896 | + { .format = DRM_FORMAT_ARGB2101010, .depth = 30, .num_planes = 3, | |
| 3897 | + .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 1, .vsub = 1, | |
| 3898 | + .has_alpha = true, }, | |
| 3899 | + { .format = DRM_FORMAT_ABGR2101010, .depth = 30, .num_planes = 3, | |
| 3900 | + .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 1, .vsub = 1, | |
| 3901 | + .has_alpha = true, }, | |
| 3902 | + { .format = DRM_FORMAT_RGB565, .depth = 16, .num_planes = 3, | |
| 3903 | + .cpp = { 2, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 1, .vsub = 1, }, | |
| 3904 | +}; | |
| 3905 | + | |
| 3906 | + | |
| 3907 | +static const struct drm_format_info * | |
| 3908 | +lookup_format_info(const struct drm_format_info formats[], | |
| 3909 | + int num_formats, u32 format) | |
| 3910 | +{ | |
| 3911 | + int i; | |
| 3912 | + | |
| 3913 | + for (i = 0; i < num_formats; i++) { | |
| 3914 | + if (formats[i].format == format) | |
| 3915 | + return &formats[i]; | |
| 3916 | + } | |
| 3917 | + | |
| 3918 | + return NULL; | |
| 3919 | +} | |
| 3920 | + | |
| 3921 | +static const struct drm_format_info * | |
| 3922 | +amd_get_format_info(const struct drm_mode_fb_cmd2 *cmd) | |
| 3923 | +{ | |
| 3924 | + uint64_t modifier = cmd->modifier[0]; | |
| 3925 | + | |
| 3926 | + if (!IS_AMD_FMT_MOD(modifier)) | |
| 3927 | + return NULL; | |
| 3928 | + | |
| 3929 | + if (AMD_FMT_MOD_GET(DCC_RETILE, modifier)) | |
| 3930 | + return lookup_format_info(dcc_retile_formats, | |
| 3931 | + ARRAY_SIZE(dcc_retile_formats), | |
| 3932 | + cmd->pixel_format); | |
| 3786 | 3933 | |
| 3787 | − dcc_address = get_dcc_address(afb->address, info); | |
| 3788 | − address->grph.meta_addr.low_part = lower_32_bits(dcc_address); | |
| 3789 | − address->grph.meta_addr.high_part = upper_32_bits(dcc_address); | |
| 3934 | + if (AMD_FMT_MOD_GET(DCC, modifier)) | |
| 3935 | + return lookup_format_info(dcc_formats, ARRAY_SIZE(dcc_formats), | |
| 3936 | + cmd->pixel_format); | |
| 3937 | + | |
| 3938 | + /* returning NULL will cause the default format structs to be used. */ | |
| 3939 | + return NULL; | |
| 3940 | +} | |
| 3941 | + | |
| 3942 | +static void | |
| 3943 | +fill_gfx9_tiling_info_from_modifier(const struct amdgpu_device *adev, | |
| 3944 | + union dc_tiling_info *tiling_info, | |
| 3945 | + uint64_t modifier) | |
| 3946 | +{ | |
| 3947 | + unsigned int mod_bank_xor_bits = AMD_FMT_MOD_GET(BANK_XOR_BITS, modifier); | |
| 3948 | + unsigned int mod_pipe_xor_bits = AMD_FMT_MOD_GET(PIPE_XOR_BITS, modifier); | |
| 3949 | + unsigned int pkrs_log2 = AMD_FMT_MOD_GET(PACKERS, modifier); | |
| 3950 | + unsigned int pipes_log2 = min(4u, mod_pipe_xor_bits); | |
| 3951 | + | |
| 3952 | + fill_gfx9_tiling_info_from_device(adev, tiling_info); | |
| 3953 | + | |
| 3954 | + if (!IS_AMD_FMT_MOD(modifier)) | |
| 3955 | + return; | |
| 3956 | + | |
| 3957 | + tiling_info->gfx9.num_pipes = 1u << pipes_log2; | |
| 3958 | + tiling_info->gfx9.num_shader_engines = 1u << (mod_pipe_xor_bits - pipes_log2); | |
| 3959 | + | |
| 3960 | + if (adev->family >= AMDGPU_FAMILY_NV) { | |
| 3961 | + tiling_info->gfx9.num_pkrs = 1u << pkrs_log2; | |
| 3962 | + } else { | |
| 3963 | + tiling_info->gfx9.num_banks = 1u << mod_bank_xor_bits; | |
| 3964 | + | |
| 3965 | + /* for DCC we know it isn't rb aligned, so rb_per_se doesn't matter. */ | |
| 3966 | + } | |
| 3967 | +} | |
| 3968 | + | |
| 3969 | +enum dm_micro_swizzle { | |
| 3970 | + MICRO_SWIZZLE_Z = 0, | |
| 3971 | + MICRO_SWIZZLE_S = 1, | |
| 3972 | + MICRO_SWIZZLE_D = 2, | |
| 3973 | + MICRO_SWIZZLE_R = 3 | |
| 3974 | +}; | |
| 3975 | + | |
| 3976 | +static bool dm_plane_format_mod_supported(struct drm_plane *plane, | |
| 3977 | + uint32_t format, | |
| 3978 | + uint64_t modifier) | |
| 3979 | +{ | |
| 3980 | + struct amdgpu_device *adev = drm_to_adev(plane->dev); | |
| 3981 | + const struct drm_format_info *info = drm_format_info(format); | |
| 3982 | + | |
| 3983 | + enum dm_micro_swizzle microtile = modifier_gfx9_swizzle_mode(modifier) & 3; | |
| 3984 | + | |
| 3985 | + if (!info) | |
| 3986 | + return false; | |
| 3987 | + | |
| 3988 | + /* | |
| 3989 | + * We always have to allow this modifier, because core DRM still | |
| 3990 | + * checks LINEAR support if userspace does not provide modifers. | |
| 3991 | + */ | |
| 3992 | + if (modifier == DRM_FORMAT_MOD_LINEAR) | |
| 3993 | + return true; | |
| 3994 | + | |
| 3995 | + /* | |
| 3996 | + * The arbitrary tiling support for multiplane formats has not been hooked | |
| 3997 | + * up. | |
| 3998 | + */ | |
| 3999 | + if (info->num_planes > 1) | |
| 4000 | + return false; | |
| 4001 | + | |
| 4002 | + /* | |
| 4003 | + * For D swizzle the canonical modifier depends on the bpp, so check | |
| 4004 | + * it here. | |
| 4005 | + */ | |
| 4006 | + if (AMD_FMT_MOD_GET(TILE_VERSION, modifier) == AMD_FMT_MOD_TILE_VER_GFX9 && | |
| 4007 | + adev->family >= AMDGPU_FAMILY_NV) { | |
| 4008 | + if (microtile == MICRO_SWIZZLE_D && info->cpp[0] == 4) | |
| 4009 | + return false; | |
| 4010 | + } | |
| 4011 | + | |
| 4012 | + if (adev->family >= AMDGPU_FAMILY_RV && microtile == MICRO_SWIZZLE_D && | |
| 4013 | + info->cpp[0] < 8) | |
| 4014 | + return false; | |
| 4015 | + | |
| 4016 | + if (modifier_has_dcc(modifier)) { | |
| 4017 | + /* Per radeonsi comments 16/64 bpp are more complicated. */ | |
| 4018 | + if (info->cpp[0] != 4) | |
| 4019 | + return false; | |
| 4020 | + } | |
| 4021 | + | |
| 4022 | + return true; | |
| 4023 | +} | |
| 4024 | + | |
| 4025 | +static void | |
| 4026 | +add_modifier(uint64_t **mods, uint64_t *size, uint64_t *cap, uint64_t mod) | |
| 4027 | +{ | |
| 4028 | + if (!*mods) | |
| 4029 | + return; | |
| 4030 | + | |
| 4031 | + if (*cap - *size < 1) { | |
| 4032 | + uint64_t new_cap = *cap * 2; | |
| 4033 | + uint64_t *new_mods = kmalloc(new_cap * sizeof(uint64_t), GFP_KERNEL); | |
| 4034 | + | |
| 4035 | + if (!new_mods) { | |
| 4036 | + kfree(*mods); | |
| 4037 | + *mods = NULL; | |
| 4038 | + return; | |
| 4039 | + } | |
| 4040 | + | |
| 4041 | + memcpy(new_mods, *mods, sizeof(uint64_t) * *size); | |
| 4042 | + kfree(*mods); | |
| 4043 | + *mods = new_mods; | |
| 4044 | + *cap = new_cap; | |
| 4045 | + } | |
| 4046 | + | |
| 4047 | + (*mods)[*size] = mod; | |
| 4048 | + *size += 1; | |
| 4049 | +} | |
| 4050 | + | |
| 4051 | +static void | |
| 4052 | +add_gfx9_modifiers(const struct amdgpu_device *adev, | |
| 4053 | + uint64_t **mods, uint64_t *size, uint64_t *capacity) | |
| 4054 | +{ | |
| 4055 | + int pipes = ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes); | |
| 4056 | + int pipe_xor_bits = min(8, pipes + | |
| 4057 | + ilog2(adev->gfx.config.gb_addr_config_fields.num_se)); | |
| 4058 | + int bank_xor_bits = min(8 - pipe_xor_bits, | |
| 4059 | + ilog2(adev->gfx.config.gb_addr_config_fields.num_banks)); | |
| 4060 | + int rb = ilog2(adev->gfx.config.gb_addr_config_fields.num_se) + | |
| 4061 | + ilog2(adev->gfx.config.gb_addr_config_fields.num_rb_per_se); | |
| 4062 | + | |
| 4063 | + | |
| 4064 | + if (adev->family == AMDGPU_FAMILY_RV) { | |
| 4065 | + /* Raven2 and later */ | |
| 4066 | + bool has_constant_encode = adev->asic_type > CHIP_RAVEN || adev->external_rev_id >= 0x81; | |
| 4067 | + | |
| 4068 | + /* | |
| 4069 | + * No _D DCC swizzles yet because we only allow 32bpp, which | |
| 4070 | + * doesn't support _D on DCN | |
| 4071 | + */ | |
| 4072 | + | |
| 4073 | + if (has_constant_encode) { | |
| 4074 | + add_modifier(mods, size, capacity, AMD_FMT_MOD | | |
| 4075 | + AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S_X) | | |
| 4076 | + AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9) | | |
| 4077 | + AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) | | |
| 4078 | + AMD_FMT_MOD_SET(BANK_XOR_BITS, bank_xor_bits) | | |
| 4079 | + AMD_FMT_MOD_SET(DCC, 1) | | |
| 4080 | + AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) | | |
| 4081 | + AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B) | | |
| 4082 | + AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1)); | |
| 4083 | + } | |
| 4084 | + | |
| 4085 | + add_modifier(mods, size, capacity, AMD_FMT_MOD | | |
| 4086 | + AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S_X) | | |
| 4087 | + AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9) | | |
| 4088 | + AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) | | |
| 4089 | + AMD_FMT_MOD_SET(BANK_XOR_BITS, bank_xor_bits) | | |
| 4090 | + AMD_FMT_MOD_SET(DCC, 1) | | |
| 4091 | + AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) | | |
| 4092 | + AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B) | | |
| 4093 | + AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 0)); | |
| 4094 | + | |
| 4095 | + if (has_constant_encode) { | |
| 4096 | + add_modifier(mods, size, capacity, AMD_FMT_MOD | | |
| 4097 | + AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S_X) | | |
| 4098 | + AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9) | | |
| 4099 | + AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) | | |
| 4100 | + AMD_FMT_MOD_SET(BANK_XOR_BITS, bank_xor_bits) | | |
| 4101 | + AMD_FMT_MOD_SET(DCC, 1) | | |
| 4102 | + AMD_FMT_MOD_SET(DCC_RETILE, 1) | | |
| 4103 | + AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) | | |
| 4104 | + AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B) | | |
| 4105 | + | |
| 4106 | + AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) | | |
| 4107 | + AMD_FMT_MOD_SET(RB, rb) | | |
| 4108 | + AMD_FMT_MOD_SET(PIPE, pipes)); | |
| 4109 | + } | |
| 4110 | + | |
| 4111 | + add_modifier(mods, size, capacity, AMD_FMT_MOD | | |
| 4112 | + AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S_X) | | |
| 4113 | + AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9) | | |
| 4114 | + AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) | | |
| 4115 | + AMD_FMT_MOD_SET(BANK_XOR_BITS, bank_xor_bits) | | |
| 4116 | + AMD_FMT_MOD_SET(DCC, 1) | | |
| 4117 | + AMD_FMT_MOD_SET(DCC_RETILE, 1) | | |
| 4118 | + AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) | | |
| 4119 | + AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B) | | |
| 4120 | + AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 0) | | |
| 4121 | + AMD_FMT_MOD_SET(RB, rb) | | |
| 4122 | + AMD_FMT_MOD_SET(PIPE, pipes)); | |
| 4123 | + } | |
| 4124 | + | |
| 4125 | + /* | |
| 4126 | + * Only supported for 64bpp on Raven, will be filtered on format in | |
| 4127 | + * dm_plane_format_mod_supported. | |
| 4128 | + */ | |
| 4129 | + add_modifier(mods, size, capacity, AMD_FMT_MOD | | |
| 4130 | + AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_D_X) | | |
| 4131 | + AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9) | | |
| 4132 | + AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) | | |
| 4133 | + AMD_FMT_MOD_SET(BANK_XOR_BITS, bank_xor_bits)); | |
| 4134 | + | |
| 4135 | + if (adev->family == AMDGPU_FAMILY_RV) { | |
| 4136 | + add_modifier(mods, size, capacity, AMD_FMT_MOD | | |
| 4137 | + AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S_X) | | |
| 4138 | + AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9) | | |
| 4139 | + AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) | | |
| 4140 | + AMD_FMT_MOD_SET(BANK_XOR_BITS, bank_xor_bits)); | |
| 4141 | + } | |
| 4142 | + | |
| 4143 | + /* | |
| 4144 | + * Only supported for 64bpp on Raven, will be filtered on format in | |
| 4145 | + * dm_plane_format_mod_supported. | |
| 4146 | + */ | |
| 4147 | + add_modifier(mods, size, capacity, AMD_FMT_MOD | | |
| 4148 | + AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_D) | | |
| 4149 | + AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9)); | |
| 4150 | + | |
| 4151 | + if (adev->family == AMDGPU_FAMILY_RV) { | |
| 4152 | + add_modifier(mods, size, capacity, AMD_FMT_MOD | | |
| 4153 | + AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S) | | |
| 4154 | + AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9)); | |
| 4155 | + } | |
| 4156 | +} | |
| 4157 | + | |
| 4158 | +static void | |
| 4159 | +add_gfx10_1_modifiers(const struct amdgpu_device *adev, | |
| 4160 | + uint64_t **mods, uint64_t *size, uint64_t *capacity) | |
| 4161 | +{ | |
| 4162 | + int pipe_xor_bits = ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes); | |
| 4163 | + | |
| 4164 | + add_modifier(mods, size, capacity, AMD_FMT_MOD | | |
| 4165 | + AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) | | |
| 4166 | + AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10) | | |
| 4167 | + AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) | | |
| 4168 | + AMD_FMT_MOD_SET(DCC, 1) | | |
| 4169 | + AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) | | |
| 4170 | + AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) | | |
| 4171 | + AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B)); | |
| 4172 | + | |
| 4173 | + add_modifier(mods, size, capacity, AMD_FMT_MOD | | |
| 4174 | + AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) | | |
| 4175 | + AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10) | | |
| 4176 | + AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) | | |
| 4177 | + AMD_FMT_MOD_SET(DCC, 1) | | |
| 4178 | + AMD_FMT_MOD_SET(DCC_RETILE, 1) | | |
| 4179 | + AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) | | |
| 4180 | + AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) | | |
| 4181 | + AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B)); | |
| 4182 | + | |
| 4183 | + add_modifier(mods, size, capacity, AMD_FMT_MOD | | |
| 4184 | + AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) | | |
| 4185 | + AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10) | | |
| 4186 | + AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits)); | |
| 4187 | + | |
| 4188 | + add_modifier(mods, size, capacity, AMD_FMT_MOD | | |
| 4189 | + AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S_X) | | |
| 4190 | + AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10) | | |
| 4191 | + AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits)); | |
| 4192 | + | |
| 4193 | + | |
| 4194 | + /* Only supported for 64bpp, will be filtered in dm_plane_format_mod_supported */ | |
| 4195 | + add_modifier(mods, size, capacity, AMD_FMT_MOD | | |
| 4196 | + AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_D) | | |
| 4197 | + AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9)); | |
| 4198 | + | |
| 4199 | + add_modifier(mods, size, capacity, AMD_FMT_MOD | | |
| 4200 | + AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S) | | |
| 4201 | + AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9)); | |
| 4202 | +} | |
| 4203 | + | |
| 4204 | +static void | |
| 4205 | +add_gfx10_3_modifiers(const struct amdgpu_device *adev, | |
| 4206 | + uint64_t **mods, uint64_t *size, uint64_t *capacity) | |
| 4207 | +{ | |
| 4208 | + int pipe_xor_bits = ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes); | |
| 4209 | + int pkrs = ilog2(adev->gfx.config.gb_addr_config_fields.num_pkrs); | |
| 4210 | + | |
| 4211 | + add_modifier(mods, size, capacity, AMD_FMT_MOD | | |
| 4212 | + AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) | | |
| 4213 | + AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) | | |
| 4214 | + AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) | | |
| 4215 | + AMD_FMT_MOD_SET(PACKERS, pkrs) | | |
| 4216 | + AMD_FMT_MOD_SET(DCC, 1) | | |
| 4217 | + AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) | | |
| 4218 | + AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) | | |
| 4219 | + AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) | | |
| 4220 | + AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_128B)); | |
| 4221 | + | |
| 4222 | + add_modifier(mods, size, capacity, AMD_FMT_MOD | | |
| 4223 | + AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) | | |
| 4224 | + AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) | | |
| 4225 | + AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) | | |
| 4226 | + AMD_FMT_MOD_SET(PACKERS, pkrs) | | |
| 4227 | + AMD_FMT_MOD_SET(DCC, 1) | | |
| 4228 | + AMD_FMT_MOD_SET(DCC_RETILE, 1) | | |
| 4229 | + AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) | | |
| 4230 | + AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) | | |
| 4231 | + AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) | | |
| 4232 | + AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_128B)); | |
| 4233 | + | |
| 4234 | + add_modifier(mods, size, capacity, AMD_FMT_MOD | | |
| 4235 | + AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) | | |
| 4236 | + AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) | | |
| 4237 | + AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) | | |
| 4238 | + AMD_FMT_MOD_SET(PACKERS, pkrs)); | |
| 4239 | + | |
| 4240 | + add_modifier(mods, size, capacity, AMD_FMT_MOD | | |
| 4241 | + AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S_X) | | |
| 4242 | + AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) | | |
| 4243 | + AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) | | |
| 4244 | + AMD_FMT_MOD_SET(PACKERS, pkrs)); | |
| 4245 | + | |
| 4246 | + /* Only supported for 64bpp, will be filtered in dm_plane_format_mod_supported */ | |
| 4247 | + add_modifier(mods, size, capacity, AMD_FMT_MOD | | |
| 4248 | + AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_D) | | |
| 4249 | + AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9)); | |
| 4250 | + | |
| 4251 | + add_modifier(mods, size, capacity, AMD_FMT_MOD | | |
| 4252 | + AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S) | | |
| 4253 | + AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9)); | |
| 4254 | +} | |
| 4255 | + | |
| 4256 | +static int | |
| 4257 | +get_plane_modifiers(const struct amdgpu_device *adev, unsigned int plane_type, uint64_t **mods) | |
| 4258 | +{ | |
| 4259 | + uint64_t size = 0, capacity = 128; | |
| 4260 | + *mods = NULL; | |
| 4261 | + | |
| 4262 | + /* We have not hooked up any pre-GFX9 modifiers. */ | |
| 4263 | + if (adev->family < AMDGPU_FAMILY_AI) | |
| 4264 | + return 0; | |
| 4265 | + | |
| 4266 | + *mods = kmalloc(capacity * sizeof(uint64_t), GFP_KERNEL); | |
| 4267 | + | |
| 4268 | + if (plane_type == DRM_PLANE_TYPE_CURSOR) { | |
| 4269 | + add_modifier(mods, &size, &capacity, DRM_FORMAT_MOD_LINEAR); | |
| 4270 | + add_modifier(mods, &size, &capacity, DRM_FORMAT_MOD_INVALID); | |
| 4271 | + return *mods ? 0 : -ENOMEM; | |
| 4272 | + } | |
| 4273 | + | |
| 4274 | + switch (adev->family) { | |
| 4275 | + case AMDGPU_FAMILY_AI: | |
| 4276 | + case AMDGPU_FAMILY_RV: | |
| 4277 | + add_gfx9_modifiers(adev, mods, &size, &capacity); | |
| 4278 | + break; | |
| 4279 | + case AMDGPU_FAMILY_NV: | |
| 4280 | + case AMDGPU_FAMILY_VGH: | |
| 4281 | + if (adev->asic_type >= CHIP_SIENNA_CICHLID) | |
| 4282 | + add_gfx10_3_modifiers(adev, mods, &size, &capacity); | |
| 4283 | + else | |
| 4284 | + add_gfx10_1_modifiers(adev, mods, &size, &capacity); | |
| 4285 | + break; | |
| 4286 | + } | |
| 4287 | + | |
| 4288 | + add_modifier(mods, &size, &capacity, DRM_FORMAT_MOD_LINEAR); | |
| 4289 | + | |
| 4290 | + /* INVALID marks the end of the list. */ | |
| 4291 | + add_modifier(mods, &size, &capacity, DRM_FORMAT_MOD_INVALID); | |
| 4292 | + | |
| 4293 | + if (!*mods) | |
| 4294 | + return -ENOMEM; | |
| 4295 | + | |
| 4296 | + return 0; | |
| 4297 | +} | |
| 4298 | + | |
| 4299 | +static int | |
| 4300 | +fill_gfx9_plane_attributes_from_modifiers(struct amdgpu_device *adev, | |
| 4301 | + const struct amdgpu_framebuffer *afb, | |
| 4302 | + const enum surface_pixel_format format, | |
| 4303 | + const enum dc_rotation_angle rotation, | |
| 4304 | + const struct plane_size *plane_size, | |
| 4305 | + union dc_tiling_info *tiling_info, | |
| 4306 | + struct dc_plane_dcc_param *dcc, | |
| 4307 | + struct dc_plane_address *address, | |
| 4308 | + const bool force_disable_dcc) | |
| 4309 | +{ | |
| 4310 | + const uint64_t modifier = afb->base.modifier; | |
| 4311 | + int ret; | |
| 4312 | + | |
| 4313 | + fill_gfx9_tiling_info_from_modifier(adev, tiling_info, modifier); | |
| 4314 | + tiling_info->gfx9.swizzle = modifier_gfx9_swizzle_mode(modifier); | |
| 4315 | + | |
| 4316 | + if (modifier_has_dcc(modifier) && !force_disable_dcc) { | |
| 4317 | + uint64_t dcc_address = afb->address + afb->base.offsets[1]; | |
| 4318 | + | |
| 4319 | + dcc->enable = 1; | |
| 4320 | + dcc->meta_pitch = afb->base.pitches[1]; | |
| 4321 | + dcc->independent_64b_blks = AMD_FMT_MOD_GET(DCC_INDEPENDENT_64B, modifier); | |
| 4322 | + | |
| 4323 | + address->grph.meta_addr.low_part = lower_32_bits(dcc_address); | |
| 4324 | + address->grph.meta_addr.high_part = upper_32_bits(dcc_address); | |
| 4325 | + } | |
| 4326 | + | |
| 4327 | + ret = validate_dcc(adev, format, rotation, tiling_info, dcc, address, plane_size); | |
| 4328 | + if (ret) | |
| 4329 | + return ret; | |
| 3790 | 4330 | |
| 3791 | 4331 | return 0; |
| 3792 | 4332 | } |
| @@ -3815,6 +4355,8 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev, · 22 unmodified lines | ||
| 3815 | 4355 | address->tmz_surface = tmz_surface; |
| 3816 | 4356 | |
| 3817 | 4357 | if (format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) { |
| 4358 | + uint64_t addr = afb->address + fb->offsets[0]; | |
| 4359 | + | |
| 3818 | 4360 | plane_size->surface_size.x = 0; |
| 3819 | 4361 | plane_size->surface_size.y = 0; |
| 3820 | 4362 | plane_size->surface_size.width = fb->width; |
| @@ -3823,9 +4365,10 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev, · 2 unmodified lines | ||
| 3823 | 4365 | fb->pitches[0] / fb->format->cpp[0]; |
| 3824 | 4366 | |
| 3825 | 4367 | address->type = PLN_ADDR_TYPE_GRAPHICS; |
| 3826 | − address->grph.addr.low_part = lower_32_bits(afb->address); | |
| 3827 | − address->grph.addr.high_part = upper_32_bits(afb->address); | |
| 4368 | + address->grph.addr.low_part = lower_32_bits(addr); | |
| 4369 | + address->grph.addr.high_part = upper_32_bits(addr); | |
| 3828 | 4370 | } else if (format < SURFACE_PIXEL_FORMAT_INVALID) { |
| 4371 | + uint64_t luma_addr = afb->address + fb->offsets[0]; | |
| 3829 | 4372 | uint64_t chroma_addr = afb->address + fb->offsets[1]; |
| 3830 | 4373 | |
| 3831 | 4374 | plane_size->surface_size.x = 0; |
| @@ -3846,83 +4389,25 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev, · 14 unmodified lines | ||
| 3846 | 4389 | |
| 3847 | 4390 | address->type = PLN_ADDR_TYPE_VIDEO_PROGRESSIVE; |
| 3848 | 4391 | address->video_progressive.luma_addr.low_part = |
| 3849 | − lower_32_bits(afb->address); | |
| 4392 | + lower_32_bits(luma_addr); | |
| 3850 | 4393 | address->video_progressive.luma_addr.high_part = |
| 3851 | − upper_32_bits(afb->address); | |
| 4394 | + upper_32_bits(luma_addr); | |
| 3852 | 4395 | address->video_progressive.chroma_addr.low_part = |
| 3853 | 4396 | lower_32_bits(chroma_addr); |
| 3854 | 4397 | address->video_progressive.chroma_addr.high_part = |
| 3855 | 4398 | upper_32_bits(chroma_addr); |
| 3856 | 4399 | } |
| 3857 | 4400 | |
| 3858 | − /* Fill GFX8 params */ | |
| 3859 | − if (AMDGPU_TILING_GET(tiling_flags, ARRAY_MODE) == DC_ARRAY_2D_TILED_THIN1) { | |
| 3860 | − unsigned int bankw, bankh, mtaspect, tile_split, num_banks; | |
| 3861 | − | |
| 3862 | − bankw = AMDGPU_TILING_GET(tiling_flags, BANK_WIDTH); | |
| 3863 | − bankh = AMDGPU_TILING_GET(tiling_flags, BANK_HEIGHT); | |
| 3864 | − mtaspect = AMDGPU_TILING_GET(tiling_flags, MACRO_TILE_ASPECT); | |
| 3865 | − tile_split = AMDGPU_TILING_GET(tiling_flags, TILE_SPLIT); | |
| 3866 | − num_banks = AMDGPU_TILING_GET(tiling_flags, NUM_BANKS); | |
| 3867 | − | |
| 3868 | − /* XXX fix me for VI */ | |
| 3869 | − tiling_info->gfx8.num_banks = num_banks; | |
| 3870 | − tiling_info->gfx8.array_mode = | |
| 3871 | − DC_ARRAY_2D_TILED_THIN1; | |
| 3872 | − tiling_info->gfx8.tile_split = tile_split; | |
| 3873 | − tiling_info->gfx8.bank_width = bankw; | |
| 3874 | − tiling_info->gfx8.bank_height = bankh; | |
| 3875 | − tiling_info->gfx8.tile_aspect = mtaspect; | |
| 3876 | − tiling_info->gfx8.tile_mode = | |
| 3877 | − DC_ADDR_SURF_MICRO_TILING_DISPLAY; | |
| 3878 | − } else if (AMDGPU_TILING_GET(tiling_flags, ARRAY_MODE) | |
| 3879 | − == DC_ARRAY_1D_TILED_THIN1) { | |
| 3880 | − tiling_info->gfx8.array_mode = DC_ARRAY_1D_TILED_THIN1; | |
| 3881 | − } | |
| 3882 | − | |
| 3883 | − tiling_info->gfx8.pipe_config = | |
| 3884 | − AMDGPU_TILING_GET(tiling_flags, PIPE_CONFIG); | |
| 3885 | − | |
| 3886 | − if (adev->asic_type == CHIP_VEGA10 || | |
| 3887 | − adev->asic_type == CHIP_VEGA12 || | |
| 3888 | − adev->asic_type == CHIP_VEGA20 || | |
| 3889 | − adev->asic_type == CHIP_NAVI10 || | |
| 3890 | − adev->asic_type == CHIP_NAVI14 || | |
| 3891 | − adev->asic_type == CHIP_NAVI12 || | |
| 3892 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 3893 | − adev->asic_type == CHIP_SIENNA_CICHLID || | |
| 3894 | − adev->asic_type == CHIP_NAVY_FLOUNDER || | |
| 3895 | −#endif | |
| 3896 | − adev->asic_type == CHIP_RENOIR || | |
| 3897 | − adev->asic_type == CHIP_RAVEN) { | |
| 3898 | − /* Fill GFX9 params */ | |
| 3899 | − tiling_info->gfx9.num_pipes = | |
| 3900 | − adev->gfx.config.gb_addr_config_fields.num_pipes; | |
| 3901 | − tiling_info->gfx9.num_banks = | |
| 3902 | − adev->gfx.config.gb_addr_config_fields.num_banks; | |
| 3903 | − tiling_info->gfx9.pipe_interleave = | |
| 3904 | − adev->gfx.config.gb_addr_config_fields.pipe_interleave_size; | |
| 3905 | − tiling_info->gfx9.num_shader_engines = | |
| 3906 | − adev->gfx.config.gb_addr_config_fields.num_se; | |
| 3907 | − tiling_info->gfx9.max_compressed_frags = | |
| 3908 | − adev->gfx.config.gb_addr_config_fields.max_compress_frags; | |
| 3909 | − tiling_info->gfx9.num_rb_per_se = | |
| 3910 | − adev->gfx.config.gb_addr_config_fields.num_rb_per_se; | |
| 3911 | − tiling_info->gfx9.swizzle = | |
| 3912 | − AMDGPU_TILING_GET(tiling_flags, SWIZZLE_MODE); | |
| 3913 | − tiling_info->gfx9.shaderEnable = 1; | |
| 3914 | − | |
| 3915 | −#ifdef CONFIG_DRM_AMD_DC_DCN3_0 | |
| 3916 | − if (adev->asic_type == CHIP_SIENNA_CICHLID || | |
| 3917 | − adev->asic_type == CHIP_NAVY_FLOUNDER) | |
| 3918 | − tiling_info->gfx9.num_pkrs = adev->gfx.config.gb_addr_config_fields.num_pkrs; | |
| 3919 | −#endif | |
| 3920 | − ret = fill_plane_dcc_attributes(adev, afb, format, rotation, | |
| 3921 | − plane_size, tiling_info, | |
| 3922 | − tiling_flags, dcc, address, | |
| 3923 | − force_disable_dcc); | |
| 4401 | + if (adev->family >= AMDGPU_FAMILY_AI) { | |
| 4402 | + ret = fill_gfx9_plane_attributes_from_modifiers(adev, afb, format, | |
| 4403 | + rotation, plane_size, | |
| 4404 | + tiling_info, dcc, | |
| 4405 | + address, | |
| 4406 | + force_disable_dcc); | |
| 3924 | 4407 | if (ret) |
| 3925 | 4408 | return ret; |
| 4409 | + } else { | |
| 4410 | + fill_gfx8_tiling_info_from_flags(tiling_info, tiling_flags); | |
| 3926 | 4411 | } |
| 3927 | 4412 | |
| 3928 | 4413 | return 0; |
| @@ -4122,7 +4607,7 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev, · 193 unmodified lines | ||
| 4122 | 4607 | struct drm_crtc_state *crtc_state) |
| 4123 | 4608 | { |
| 4124 | 4609 | struct dm_crtc_state *dm_crtc_state = to_dm_crtc_state(crtc_state); |
| 4125 | − struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state); | |
| 4610 | + struct amdgpu_framebuffer *afb = (struct amdgpu_framebuffer *)plane_state->fb; | |
| 4126 | 4611 | struct dc_scaling_info scaling_info; |
| 4127 | 4612 | struct dc_plane_info plane_info; |
| 4128 | 4613 | int ret; |
| @@ -4139,10 +4624,10 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev, · 10 unmodified lines | ||
| 4139 | 4624 | |
| 4140 | 4625 | force_disable_dcc = adev->asic_type == CHIP_RAVEN && adev->in_suspend; |
| 4141 | 4626 | ret = fill_dc_plane_info_and_addr(adev, plane_state, |
| 4142 | − dm_plane_state->tiling_flags, | |
| 4627 | + afb->tiling_flags, | |
| 4143 | 4628 | &plane_info, |
| 4144 | 4629 | &dc_plane_state->address, |
| 4145 | − dm_plane_state->tmz_surface, | |
| 4630 | + afb->tmz_surface, | |
| 4146 | 4631 | force_disable_dcc); |
| 4147 | 4632 | if (ret) |
| 4148 | 4633 | return ret; |
| @@ -4732,6 +5217,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, · 583 unmodified lines | ||
| 4732 | 5217 | if (dc_dsc_compute_config(aconnector->dc_link->ctx->dc->res_pool->dscs[0], |
| 4733 | 5218 | &dsc_caps, |
| 4734 | 5219 | aconnector->dc_link->ctx->dc->debug.dsc_min_slice_height_override, |
| 5220 | + 0, | |
| 4735 | 5221 | link_bandwidth_kbps, |
| 4736 | 5222 | &stream->timing, |
| 4737 | 5223 | &stream->timing.dsc_cfg)) |
| @@ -5310,7 +5796,8 @@ enum drm_mode_status amdgpu_dm_connector_mode_valid(struct drm_connector *connec · 572 unmodified lines | ||
| 5310 | 5796 | |
| 5311 | 5797 | dc_sink = to_amdgpu_dm_connector(connector)->dc_sink; |
| 5312 | 5798 | |
| 5313 | − if (dc_sink == NULL) { | |
| 5799 | + if (dc_sink == NULL && aconnector->base.force != DRM_FORCE_ON_DIGITAL && | |
| 5800 | + aconnector->base.force != DRM_FORCE_ON) { | |
| 5314 | 5801 | DRM_ERROR("dc_sink is NULL!\n"); |
| 5315 | 5802 | goto fail; |
| 5316 | 5803 | } |
| @@ -5416,6 +5903,8 @@ amdgpu_dm_connector_atomic_check(struct drm_connector *conn, · 99 unmodified lines | ||
| 5416 | 5903 | struct drm_crtc_state *new_crtc_state; |
| 5417 | 5904 | int ret; |
| 5418 | 5905 | |
| 5906 | + trace_amdgpu_dm_connector_atomic_check(new_con_state); | |
| 5907 | + | |
| 5419 | 5908 | if (!crtc) |
| 5420 | 5909 | return 0; |
| 5421 | 5910 | |
| @@ -5523,6 +6012,8 @@ static int dm_crtc_helper_atomic_check(struct drm_crtc *crtc, · 101 unmodified lines | ||
| 5523 | 6012 | struct dm_crtc_state *dm_crtc_state = to_dm_crtc_state(crtc_state); |
| 5524 | 6013 | int ret = -EINVAL; |
| 5525 | 6014 | |
| 6015 | + trace_amdgpu_dm_crtc_atomic_check(crtc_state); | |
| 6016 | + | |
| 5526 | 6017 | dm_update_crtc_active_planes(crtc, crtc_state); |
| 5527 | 6018 | |
| 5528 | 6019 | if (unlikely(!dm_crtc_state->stream && |
| @@ -5739,10 +6230,6 @@ dm_drm_plane_duplicate_state(struct drm_plane *plane) · 210 unmodified lines | ||
| 5739 | 6230 | dc_plane_state_retain(dm_plane_state->dc_state); |
| 5740 | 6231 | } |
| 5741 | 6232 | |
| 5742 | − /* Framebuffer hasn't been updated yet, so retain old flags. */ | |
| 5743 | − dm_plane_state->tiling_flags = old_dm_plane_state->tiling_flags; | |
| 5744 | − dm_plane_state->tmz_surface = old_dm_plane_state->tmz_surface; | |
| 5745 | − | |
| 5746 | 6233 | return &dm_plane_state->base; |
| 5747 | 6234 | } |
| 5748 | 6235 | |
| @@ -5764,6 +6251,7 @@ static const struct drm_plane_funcs dm_plane_funcs = { · 15 unmodified lines | ||
| 5764 | 6251 | .reset = dm_drm_plane_reset, |
| 5765 | 6252 | .atomic_duplicate_state = dm_drm_plane_duplicate_state, |
| 5766 | 6253 | .atomic_destroy_state = dm_drm_plane_destroy_state, |
| 6254 | + .format_mod_supported = dm_plane_format_mod_supported, | |
| 5767 | 6255 | }; |
| 5768 | 6256 | |
| 5769 | 6257 | static int dm_plane_helper_prepare_fb(struct drm_plane *plane, |
| @@ -5847,10 +6335,10 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane, · 77 unmodified lines | ||
| 5847 | 6335 | |
| 5848 | 6336 | fill_plane_buffer_attributes( |
| 5849 | 6337 | adev, afb, plane_state->format, plane_state->rotation, |
| 5850 | − dm_plane_state_new->tiling_flags, | |
| 6338 | + afb->tiling_flags, | |
| 5851 | 6339 | &plane_state->tiling_info, &plane_state->plane_size, |
| 5852 | 6340 | &plane_state->dcc, &plane_state->address, |
| 5853 | − dm_plane_state_new->tmz_surface, force_disable_dcc); | |
| 6341 | + afb->tmz_surface, force_disable_dcc); | |
| 5854 | 6342 | } |
| 5855 | 6343 | |
| 5856 | 6344 | return 0; |
| @@ -5898,6 +6386,8 @@ static int dm_plane_atomic_check(struct drm_plane *plane, · 41 unmodified lines | ||
| 5898 | 6386 | struct drm_crtc_state *new_crtc_state; |
| 5899 | 6387 | int ret; |
| 5900 | 6388 | |
| 6389 | + trace_amdgpu_dm_plane_atomic_check(state); | |
| 6390 | + | |
| 5901 | 6391 | dm_plane_state = to_dm_plane_state(state); |
| 5902 | 6392 | |
| 5903 | 6393 | if (!dm_plane_state->dc_state) |
| @@ -5938,6 +6428,8 @@ static void dm_plane_atomic_async_update(struct drm_plane *plane, · 34 unmodified lines | ||
| 5938 | 6428 | struct drm_plane_state *old_state = |
| 5939 | 6429 | drm_atomic_get_old_plane_state(new_state->state, plane); |
| 5940 | 6430 | |
| 6431 | + trace_amdgpu_dm_atomic_update_cursor(new_state); | |
| 6432 | + | |
| 5941 | 6433 | swap(plane->state->fb, new_state->fb); |
| 5942 | 6434 | |
| 5943 | 6435 | plane->state->src_x = new_state->src_x; |
| @@ -6056,13 +6548,19 @@ static int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm, · 112 unmodified lines | ||
| 6056 | 6548 | int num_formats; |
| 6057 | 6549 | int res = -EPERM; |
| 6058 | 6550 | unsigned int supported_rotations; |
| 6551 | + uint64_t *modifiers = NULL; | |
| 6059 | 6552 | |
| 6060 | 6553 | num_formats = get_plane_formats(plane, plane_cap, formats, |
| 6061 | 6554 | ARRAY_SIZE(formats)); |
| 6062 | 6555 | |
| 6556 | + res = get_plane_modifiers(dm->adev, plane->type, &modifiers); | |
| 6557 | + if (res) | |
| 6558 | + return res; | |
| 6559 | + | |
| 6063 | 6560 | res = drm_universal_plane_init(adev_to_drm(dm->adev), plane, possible_crtcs, |
| 6064 | 6561 | &dm_plane_funcs, formats, num_formats, |
| 6065 | − NULL, plane->type, NULL); | |
| 6562 | + modifiers, plane->type, NULL); | |
| 6563 | + kfree(modifiers); | |
| 6066 | 6564 | if (res) |
| 6067 | 6565 | return res; |
| 6068 | 6566 | |
| @@ -7109,6 +7607,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, · 1040 unmodified lines | ||
| 7109 | 7607 | struct drm_crtc *crtc = new_plane_state->crtc; |
| 7110 | 7608 | struct drm_crtc_state *new_crtc_state; |
| 7111 | 7609 | struct drm_framebuffer *fb = new_plane_state->fb; |
| 7610 | + struct amdgpu_framebuffer *afb = (struct amdgpu_framebuffer *)fb; | |
| 7112 | 7611 | bool plane_needs_flip; |
| 7113 | 7612 | struct dc_plane_state *dc_plane; |
| 7114 | 7613 | struct dm_plane_state *dm_new_plane_state = to_dm_plane_state(new_plane_state); |
| @@ -7163,10 +7662,10 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, · 48 unmodified lines | ||
| 7163 | 7662 | |
| 7164 | 7663 | fill_dc_plane_info_and_addr( |
| 7165 | 7664 | dm->adev, new_plane_state, |
| 7166 | − dm_new_plane_state->tiling_flags, | |
| 7665 | + afb->tiling_flags, | |
| 7167 | 7666 | &bundle->plane_infos[planes_count], |
| 7168 | 7667 | &bundle->flip_addrs[planes_count].address, |
| 7169 | − dm_new_plane_state->tmz_surface, false); | |
| 7668 | + afb->tmz_surface, false); | |
| 7170 | 7669 | |
| 7171 | 7670 | DRM_DEBUG_DRIVER("plane: id=%d dcc_en=%d\n", |
| 7172 | 7671 | new_plane_state->plane->index, |
| @@ -7501,6 +8000,8 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) · 328 unmodified lines | ||
| 7501 | 8000 | int crtc_disable_count = 0; |
| 7502 | 8001 | bool mode_set_reset_required = false; |
| 7503 | 8002 | |
| 8003 | + trace_amdgpu_dm_atomic_commit_tail_begin(state); | |
| 8004 | + | |
| 7504 | 8005 | drm_atomic_helper_update_legacy_modeset_state(dev, state); |
| 7505 | 8006 | drm_atomic_helper_calc_timestamping_constants(state); |
| 7506 | 8007 | |
| @@ -8306,8 +8807,7 @@ static bool should_reset_plane(struct drm_atomic_state *state, · 799 unmodified lines | ||
| 8306 | 8807 | * TODO: Come up with a more elegant solution for this. |
| 8307 | 8808 | */ |
| 8308 | 8809 | for_each_oldnew_plane_in_state(state, other, old_other_state, new_other_state, i) { |
| 8309 | − struct dm_plane_state *old_dm_plane_state, *new_dm_plane_state; | |
| 8310 | − | |
| 8810 | + struct amdgpu_framebuffer *old_afb, *new_afb; | |
| 8311 | 8811 | if (other->type == DRM_PLANE_TYPE_CURSOR) |
| 8312 | 8812 | continue; |
| 8313 | 8813 | |
| @@ -8351,12 +8851,12 @@ static bool should_reset_plane(struct drm_atomic_state *state, · 37 unmodified lines | ||
| 8351 | 8851 | if (old_other_state->fb->format != new_other_state->fb->format) |
| 8352 | 8852 | return true; |
| 8353 | 8853 | |
| 8354 | − old_dm_plane_state = to_dm_plane_state(old_other_state); | |
| 8355 | − new_dm_plane_state = to_dm_plane_state(new_other_state); | |
| 8854 | + old_afb = (struct amdgpu_framebuffer *)old_other_state->fb; | |
| 8855 | + new_afb = (struct amdgpu_framebuffer *)new_other_state->fb; | |
| 8356 | 8856 | |
| 8357 | 8857 | /* Tiling and DCC changes also require bandwidth updates. */ |
| 8358 | − if (old_dm_plane_state->tiling_flags != | |
| 8359 | − new_dm_plane_state->tiling_flags) | |
| 8858 | + if (old_afb->tiling_flags != new_afb->tiling_flags || | |
| 8859 | + old_afb->base.modifier != new_afb->base.modifier) | |
| 8360 | 8860 | return true; |
| 8361 | 8861 | } |
| 8362 | 8862 | |
| @@ -8587,8 +9087,9 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, · 224 unmodified lines | ||
| 8587 | 9087 | enum dc_status status; |
| 8588 | 9088 | int ret, i; |
| 8589 | 9089 | bool lock_and_validation_needed = false; |
| 9090 | + struct dm_crtc_state *dm_old_crtc_state; | |
| 8590 | 9091 | |
| 8591 | − amdgpu_check_debugfs_connector_property_change(adev, state); | |
| 9092 | + trace_amdgpu_dm_atomic_check_begin(state); | |
| 8592 | 9093 | |
| 8593 | 9094 | ret = drm_atomic_helper_check_modeset(dev, state); |
| 8594 | 9095 | if (ret) |
| @@ -8629,9 +9130,12 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, · 34 unmodified lines | ||
| 8629 | 9130 | } |
| 8630 | 9131 | #endif |
| 8631 | 9132 | for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { |
| 9133 | + dm_old_crtc_state = to_dm_crtc_state(old_crtc_state); | |
| 9134 | + | |
| 8632 | 9135 | if (!drm_atomic_crtc_needs_modeset(new_crtc_state) && |
| 8633 | 9136 | !new_crtc_state->color_mgmt_changed && |
| 8634 | − old_crtc_state->vrr_enabled == new_crtc_state->vrr_enabled) | |
| 9137 | + old_crtc_state->vrr_enabled == new_crtc_state->vrr_enabled && | |
| 9138 | + dm_old_crtc_state->dsc_force_changed == false) | |
| 8635 | 9139 | continue; |
| 8636 | 9140 | |
| 8637 | 9141 | if (!new_crtc_state->enable) |
| @@ -8682,17 +9186,6 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, · 44 unmodified lines | ||
| 8682 | 9186 | } |
| 8683 | 9187 | } |
| 8684 | 9188 | |
| 8685 | − /* Prepass for updating tiling flags on new planes. */ | |
| 8686 | − for_each_new_plane_in_state(state, plane, new_plane_state, i) { | |
| 8687 | − struct dm_plane_state *new_dm_plane_state = to_dm_plane_state(new_plane_state); | |
| 8688 | − struct amdgpu_framebuffer *new_afb = to_amdgpu_framebuffer(new_plane_state->fb); | |
| 8689 | − | |
| 8690 | − ret = get_fb_info(new_afb, &new_dm_plane_state->tiling_flags, | |
| 8691 | − &new_dm_plane_state->tmz_surface); | |
| 8692 | − if (ret) | |
| 8693 | − goto fail; | |
| 8694 | − } | |
| 8695 | − | |
| 8696 | 9189 | /* Remove exiting planes if they are modified */ |
| 8697 | 9190 | for_each_oldnew_plane_in_state_reverse(state, plane, old_plane_state, new_plane_state, i) { |
| 8698 | 9191 | ret = dm_update_plane_state(dc, state, plane, |
| @@ -8886,6 +9379,9 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, · 187 unmodified lines | ||
| 8886 | 9379 | |
| 8887 | 9380 | /* Must be success */ |
| 8888 | 9381 | WARN_ON(ret); |
| 9382 | + | |
| 9383 | + trace_amdgpu_dm_atomic_check_finish(state, ret); | |
| 9384 | + | |
| 8889 | 9385 | return ret; |
| 8890 | 9386 | |
| 8891 | 9387 | fail: |
| @@ -8896,6 +9392,8 @@ fail: · 4 unmodified lines | ||
| 8896 | 9392 | else |
| 8897 | 9393 | DRM_DEBUG_DRIVER("Atomic check failed with err: %d \n", ret); |
| 8898 | 9394 | |
| 9395 | + trace_amdgpu_dm_atomic_check_finish(state, ret); | |
| 9396 | + | |
| 8899 | 9397 | return ret; |
| 8900 | 9398 | } |
| 8901 | 9399 | |
| @@ -9160,3 +9658,41 @@ void amdgpu_dm_trigger_timing_sync(struct drm_device *dev) · 258 unmodified lines | ||
| 9160 | 9658 | } |
| 9161 | 9659 | mutex_unlock(&adev->dm.dc_lock); |
| 9162 | 9660 | } |
| 9661 | + | |
| 9662 | +void dm_write_reg_func(const struct dc_context *ctx, uint32_t address, | |
| 9663 | + uint32_t value, const char *func_name) | |
| 9664 | +{ | |
| 9665 | +#ifdef DM_CHECK_ADDR_0 | |
| 9666 | + if (address == 0) { | |
| 9667 | + DC_ERR("invalid register write. address = 0"); | |
| 9668 | + return; | |
| 9669 | + } | |
| 9670 | +#endif | |
| 9671 | + cgs_write_register(ctx->cgs_device, address, value); | |
| 9672 | + trace_amdgpu_dc_wreg(&ctx->perf_trace->write_count, address, value); | |
| 9673 | +} | |
| 9674 | + | |
| 9675 | +uint32_t dm_read_reg_func(const struct dc_context *ctx, uint32_t address, | |
| 9676 | + const char *func_name) | |
| 9677 | +{ | |
| 9678 | + uint32_t value; | |
| 9679 | +#ifdef DM_CHECK_ADDR_0 | |
| 9680 | + if (address == 0) { | |
| 9681 | + DC_ERR("invalid register read; address = 0\n"); | |
| 9682 | + return 0; | |
| 9683 | + } | |
| 9684 | +#endif | |
| 9685 | + | |
| 9686 | + if (ctx->dmub_srv && | |
| 9687 | + ctx->dmub_srv->reg_helper_offload.gather_in_progress && | |
| 9688 | + !ctx->dmub_srv->reg_helper_offload.should_burst_write) { | |
| 9689 | + ASSERT(false); | |
| 9690 | + return 0; | |
| 9691 | + } | |
| 9692 | + | |
| 9693 | + value = cgs_read_register(ctx->cgs_device, address); | |
| 9694 | + | |
| 9695 | + trace_amdgpu_dc_rreg(&ctx->perf_trace->read_count, address, value); | |
| 9696 | + | |
| 9697 | + return value; | |
| 9698 | +} | |
| @@ -86,7 +86,7 @@ struct irq_list_head { · 85 unmodified lines | ||
| 86 | 86 | * @bo_ptr: Pointer to the buffer object |
| 87 | 87 | * @gpu_addr: MMIO gpu addr |
| 88 | 88 | */ |
| 89 | −struct dm_comressor_info { | |
| 89 | +struct dm_compressor_info { | |
| 90 | 90 | void *cpu_addr; |
| 91 | 91 | struct amdgpu_bo *bo_ptr; |
| 92 | 92 | uint64_t gpu_addr; |
| @@ -148,7 +148,7 @@ struct amdgpu_dm_backlight_caps { · 55 unmodified lines | ||
| 148 | 148 | * @soc_bounding_box: SOC bounding box values provided by gpu_info FW |
| 149 | 149 | * @cached_state: Caches device atomic state for suspend/resume |
| 150 | 150 | * @cached_dc_state: Cached state of content streams |
| 151 | − * @compressor: Frame buffer compression buffer. See &struct dm_comressor_info | |
| 151 | + * @compressor: Frame buffer compression buffer. See &struct dm_compressor_info | |
| 152 | 152 | * @force_timing_sync: set via debugfs. When set, indicates that all connected |
| 153 | 153 | * displays will be forced to synchronize. |
| 154 | 154 | */ |
| @@ -324,7 +324,7 @@ struct amdgpu_display_manager { · 169 unmodified lines | ||
| 324 | 324 | struct drm_atomic_state *cached_state; |
| 325 | 325 | struct dc_state *cached_dc_state; |
| 326 | 326 | |
| 327 | − struct dm_comressor_info compressor; | |
| 327 | + struct dm_compressor_info compressor; | |
| 328 | 328 | |
| 329 | 329 | const struct firmware *fw_dmcu; |
| 330 | 330 | uint32_t dmcu_fw_version; |
| @@ -420,8 +420,6 @@ struct dc_plane_state; · 89 unmodified lines | ||
| 420 | 420 | struct dm_plane_state { |
| 421 | 421 | struct drm_plane_state base; |
| 422 | 422 | struct dc_plane_state *dc_state; |
| 423 | − uint64_t tiling_flags; | |
| 424 | − bool tmz_surface; | |
| 425 | 423 | }; |
| 426 | 424 | |
| 427 | 425 | struct dm_crtc_state { |
| @@ -440,6 +438,7 @@ struct dm_crtc_state { · 12 unmodified lines | ||
| 440 | 438 | bool freesync_timing_changed; |
| 441 | 439 | bool freesync_vrr_info_changed; |
| 442 | 440 | |
| 441 | + bool dsc_force_changed; | |
| 443 | 442 | bool vrr_supported; |
| 444 | 443 | struct mod_freesync_config freesync_config; |
| 445 | 444 | struct dc_info_packet vrr_infopacket; |
| @@ -115,7 +115,7 @@ int amdgpu_dm_crtc_configure_crc_source(struct drm_crtc *crtc, · 114 unmodified lines | ||
| 115 | 115 | /* Enable CRTC CRC generation if necessary. */ |
| 116 | 116 | if (dm_is_crc_source_crtc(source)) { |
| 117 | 117 | if (!dc_stream_configure_crc(stream_state->ctx->dc, |
| 118 | − stream_state, enable, enable)) { | |
| 118 | + stream_state, NULL, enable, enable)) { | |
| 119 | 119 | ret = -EINVAL; |
| 120 | 120 | goto unlock; |
| 121 | 121 | } |
| @@ -556,7 +556,7 @@ static ssize_t dp_phy_test_pattern_debugfs_write(struct file *f, const char __us · 555 unmodified lines | ||
| 556 | 556 | bool disable_hpd = false; |
| 557 | 557 | bool valid_test_pattern = false; |
| 558 | 558 | uint8_t param_nums = 0; |
| 559 | − /* init with defalut 80bit custom pattern */ | |
| 559 | + /* init with default 80bit custom pattern */ | |
| 560 | 560 | uint8_t custom_pattern[10] = { |
| 561 | 561 | 0x1f, 0x7c, 0xf0, 0xc1, 0x07, |
| 562 | 562 | 0x1f, 0x7c, 0xf0, 0xc1, 0x07 |
| @@ -1253,6 +1253,10 @@ static ssize_t dp_dsc_clock_en_write(struct file *f, const char __user *buf, · 690 unmodified lines | ||
| 1253 | 1253 | size_t size, loff_t *pos) |
| 1254 | 1254 | { |
| 1255 | 1255 | struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private; |
| 1256 | + struct drm_connector *connector = &aconnector->base; | |
| 1257 | + struct drm_device *dev = connector->dev; | |
| 1258 | + struct drm_crtc *crtc = NULL; | |
| 1259 | + struct dm_crtc_state *dm_crtc_state = NULL; | |
| 1256 | 1260 | struct pipe_ctx *pipe_ctx; |
| 1257 | 1261 | int i; |
| 1258 | 1262 | char *wr_buf = NULL; |
| @@ -1295,6 +1299,25 @@ static ssize_t dp_dsc_clock_en_write(struct file *f, const char __user *buf, · 36 unmodified lines | ||
| 1295 | 1299 | if (!pipe_ctx || !pipe_ctx->stream) |
| 1296 | 1300 | goto done; |
| 1297 | 1301 | |
| 1302 | + // Get CRTC state | |
| 1303 | + mutex_lock(&dev->mode_config.mutex); | |
| 1304 | + drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); | |
| 1305 | + | |
| 1306 | + if (connector->state == NULL) | |
| 1307 | + goto unlock; | |
| 1308 | + | |
| 1309 | + crtc = connector->state->crtc; | |
| 1310 | + if (crtc == NULL) | |
| 1311 | + goto unlock; | |
| 1312 | + | |
| 1313 | + drm_modeset_lock(&crtc->mutex, NULL); | |
| 1314 | + if (crtc->state == NULL) | |
| 1315 | + goto unlock; | |
| 1316 | + | |
| 1317 | + dm_crtc_state = to_dm_crtc_state(crtc->state); | |
| 1318 | + if (dm_crtc_state->stream == NULL) | |
| 1319 | + goto unlock; | |
| 1320 | + | |
| 1298 | 1321 | if (param[0] == 1) |
| 1299 | 1322 | aconnector->dsc_settings.dsc_force_enable = DSC_CLK_FORCE_ENABLE; |
| 1300 | 1323 | else if (param[0] == 2) |
| @@ -1302,6 +1325,14 @@ static ssize_t dp_dsc_clock_en_write(struct file *f, const char __user *buf, · 1 unmodified line | ||
| 1302 | 1325 | else |
| 1303 | 1326 | aconnector->dsc_settings.dsc_force_enable = DSC_CLK_FORCE_DEFAULT; |
| 1304 | 1327 | |
| 1328 | + dm_crtc_state->dsc_force_changed = true; | |
| 1329 | + | |
| 1330 | +unlock: | |
| 1331 | + if (crtc) | |
| 1332 | + drm_modeset_unlock(&crtc->mutex); | |
| 1333 | + drm_modeset_unlock(&dev->mode_config.connection_mutex); | |
| 1334 | + mutex_unlock(&dev->mode_config.mutex); | |
| 1335 | + | |
| 1305 | 1336 | done: |
| 1306 | 1337 | kfree(wr_buf); |
| 1307 | 1338 | return size; |
| @@ -1408,6 +1439,10 @@ static ssize_t dp_dsc_slice_width_write(struct file *f, const char __user *buf, · 100 unmodified lines | ||
| 1408 | 1439 | { |
| 1409 | 1440 | struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private; |
| 1410 | 1441 | struct pipe_ctx *pipe_ctx; |
| 1442 | + struct drm_connector *connector = &aconnector->base; | |
| 1443 | + struct drm_device *dev = connector->dev; | |
| 1444 | + struct drm_crtc *crtc = NULL; | |
| 1445 | + struct dm_crtc_state *dm_crtc_state = NULL; | |
| 1411 | 1446 | int i; |
| 1412 | 1447 | char *wr_buf = NULL; |
| 1413 | 1448 | uint32_t wr_buf_size = 42; |
| @@ -1449,6 +1484,25 @@ static ssize_t dp_dsc_slice_width_write(struct file *f, const char __user *buf, · 35 unmodified lines | ||
| 1449 | 1484 | if (!pipe_ctx || !pipe_ctx->stream) |
| 1450 | 1485 | goto done; |
| 1451 | 1486 | |
| 1487 | + // Safely get CRTC state | |
| 1488 | + mutex_lock(&dev->mode_config.mutex); | |
| 1489 | + drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); | |
| 1490 | + | |
| 1491 | + if (connector->state == NULL) | |
| 1492 | + goto unlock; | |
| 1493 | + | |
| 1494 | + crtc = connector->state->crtc; | |
| 1495 | + if (crtc == NULL) | |
| 1496 | + goto unlock; | |
| 1497 | + | |
| 1498 | + drm_modeset_lock(&crtc->mutex, NULL); | |
| 1499 | + if (crtc->state == NULL) | |
| 1500 | + goto unlock; | |
| 1501 | + | |
| 1502 | + dm_crtc_state = to_dm_crtc_state(crtc->state); | |
| 1503 | + if (dm_crtc_state->stream == NULL) | |
| 1504 | + goto unlock; | |
| 1505 | + | |
| 1452 | 1506 | if (param[0] > 0) |
| 1453 | 1507 | aconnector->dsc_settings.dsc_num_slices_h = DIV_ROUND_UP( |
| 1454 | 1508 | pipe_ctx->stream->timing.h_addressable, |
| @@ -1456,6 +1510,14 @@ static ssize_t dp_dsc_slice_width_write(struct file *f, const char __user *buf, · 1 unmodified line | ||
| 1456 | 1510 | else |
| 1457 | 1511 | aconnector->dsc_settings.dsc_num_slices_h = 0; |
| 1458 | 1512 | |
| 1513 | + dm_crtc_state->dsc_force_changed = true; | |
| 1514 | + | |
| 1515 | +unlock: | |
| 1516 | + if (crtc) | |
| 1517 | + drm_modeset_unlock(&crtc->mutex); | |
| 1518 | + drm_modeset_unlock(&dev->mode_config.connection_mutex); | |
| 1519 | + mutex_unlock(&dev->mode_config.mutex); | |
| 1520 | + | |
| 1459 | 1521 | done: |
| 1460 | 1522 | kfree(wr_buf); |
| 1461 | 1523 | return size; |
| @@ -1561,6 +1623,10 @@ static ssize_t dp_dsc_slice_height_write(struct file *f, const char __user *buf, · 99 unmodified lines | ||
| 1561 | 1623 | size_t size, loff_t *pos) |
| 1562 | 1624 | { |
| 1563 | 1625 | struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private; |
| 1626 | + struct drm_connector *connector = &aconnector->base; | |
| 1627 | + struct drm_device *dev = connector->dev; | |
| 1628 | + struct drm_crtc *crtc = NULL; | |
| 1629 | + struct dm_crtc_state *dm_crtc_state = NULL; | |
| 1564 | 1630 | struct pipe_ctx *pipe_ctx; |
| 1565 | 1631 | int i; |
| 1566 | 1632 | char *wr_buf = NULL; |
| @@ -1603,6 +1669,25 @@ static ssize_t dp_dsc_slice_height_write(struct file *f, const char __user *buf, · 36 unmodified lines | ||
| 1603 | 1669 | if (!pipe_ctx || !pipe_ctx->stream) |
| 1604 | 1670 | goto done; |
| 1605 | 1671 | |
| 1672 | + // Get CRTC state | |
| 1673 | + mutex_lock(&dev->mode_config.mutex); | |
| 1674 | + drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); | |
| 1675 | + | |
| 1676 | + if (connector->state == NULL) | |
| 1677 | + goto unlock; | |
| 1678 | + | |
| 1679 | + crtc = connector->state->crtc; | |
| 1680 | + if (crtc == NULL) | |
| 1681 | + goto unlock; | |
| 1682 | + | |
| 1683 | + drm_modeset_lock(&crtc->mutex, NULL); | |
| 1684 | + if (crtc->state == NULL) | |
| 1685 | + goto unlock; | |
| 1686 | + | |
| 1687 | + dm_crtc_state = to_dm_crtc_state(crtc->state); | |
| 1688 | + if (dm_crtc_state->stream == NULL) | |
| 1689 | + goto unlock; | |
| 1690 | + | |
| 1606 | 1691 | if (param[0] > 0) |
| 1607 | 1692 | aconnector->dsc_settings.dsc_num_slices_v = DIV_ROUND_UP( |
| 1608 | 1693 | pipe_ctx->stream->timing.v_addressable, |
| @@ -1610,6 +1695,14 @@ static ssize_t dp_dsc_slice_height_write(struct file *f, const char __user *buf, · 1 unmodified line | ||
| 1610 | 1695 | else |
| 1611 | 1696 | aconnector->dsc_settings.dsc_num_slices_v = 0; |
| 1612 | 1697 | |
| 1698 | + dm_crtc_state->dsc_force_changed = true; | |
| 1699 | + | |
| 1700 | +unlock: | |
| 1701 | + if (crtc) | |
| 1702 | + drm_modeset_unlock(&crtc->mutex); | |
| 1703 | + drm_modeset_unlock(&dev->mode_config.connection_mutex); | |
| 1704 | + mutex_unlock(&dev->mode_config.mutex); | |
| 1705 | + | |
| 1613 | 1706 | done: |
| 1614 | 1707 | kfree(wr_buf); |
| 1615 | 1708 | return size; |
| @@ -1708,6 +1801,10 @@ static ssize_t dp_dsc_bits_per_pixel_write(struct file *f, const char __user *bu · 92 unmodified lines | ||
| 1708 | 1801 | size_t size, loff_t *pos) |
| 1709 | 1802 | { |
| 1710 | 1803 | struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private; |
| 1804 | + struct drm_connector *connector = &aconnector->base; | |
| 1805 | + struct drm_device *dev = connector->dev; | |
| 1806 | + struct drm_crtc *crtc = NULL; | |
| 1807 | + struct dm_crtc_state *dm_crtc_state = NULL; | |
| 1711 | 1808 | struct pipe_ctx *pipe_ctx; |
| 1712 | 1809 | int i; |
| 1713 | 1810 | char *wr_buf = NULL; |
| @@ -1750,8 +1847,35 @@ static ssize_t dp_dsc_bits_per_pixel_write(struct file *f, const char __user *bu · 36 unmodified lines | ||
| 1750 | 1847 | if (!pipe_ctx || !pipe_ctx->stream) |
| 1751 | 1848 | goto done; |
| 1752 | 1849 | |
| 1850 | + // Get CRTC state | |
| 1851 | + mutex_lock(&dev->mode_config.mutex); | |
| 1852 | + drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); | |
| 1853 | + | |
| 1854 | + if (connector->state == NULL) | |
| 1855 | + goto unlock; | |
| 1856 | + | |
| 1857 | + crtc = connector->state->crtc; | |
| 1858 | + if (crtc == NULL) | |
| 1859 | + goto unlock; | |
| 1860 | + | |
| 1861 | + drm_modeset_lock(&crtc->mutex, NULL); | |
| 1862 | + if (crtc->state == NULL) | |
| 1863 | + goto unlock; | |
| 1864 | + | |
| 1865 | + dm_crtc_state = to_dm_crtc_state(crtc->state); | |
| 1866 | + if (dm_crtc_state->stream == NULL) | |
| 1867 | + goto unlock; | |
| 1868 | + | |
| 1753 | 1869 | aconnector->dsc_settings.dsc_bits_per_pixel = param[0]; |
| 1754 | 1870 | |
| 1871 | + dm_crtc_state->dsc_force_changed = true; | |
| 1872 | + | |
| 1873 | +unlock: | |
| 1874 | + if (crtc) | |
| 1875 | + drm_modeset_unlock(&crtc->mutex); | |
| 1876 | + drm_modeset_unlock(&dev->mode_config.connection_mutex); | |
| 1877 | + mutex_unlock(&dev->mode_config.mutex); | |
| 1878 | + | |
| 1755 | 1879 | done: |
| 1756 | 1880 | kfree(wr_buf); |
| 1757 | 1881 | return size; |
| @@ -627,7 +627,6 @@ void dm_set_dcn_clocks(struct dc_context *ctx, struct dc_clocks *clks) · 626 unmodified lines | ||
| 627 | 627 | { |
| 628 | 628 | /* TODO: something */ |
| 629 | 629 | } |
| 630 | −#ifdef CONFIG_DRM_AMD_DC_DCN3_0 | |
| 631 | 630 | |
| 632 | 631 | void *dm_helpers_allocate_gpu_mem( |
| 633 | 632 | struct dc_context *ctx, |
| @@ -646,4 +645,3 @@ void dm_helpers_free_gpu_mem( · 12 unmodified lines | ||
| 646 | 645 | { |
| 647 | 646 | // TODO |
| 648 | 647 | } |
| 649 | −#endif | |
| @@ -500,6 +500,7 @@ static void set_dsc_configs_from_fairness_vars(struct dsc_mst_fairness_params *p · 499 unmodified lines | ||
| 500 | 500 | ¶ms[i].sink->dsc_caps.dsc_dec_caps, |
| 501 | 501 | params[i].sink->ctx->dc->debug.dsc_min_slice_height_override, |
| 502 | 502 | 0, |
| 503 | + 0, | |
| 503 | 504 | params[i].timing, |
| 504 | 505 | ¶ms[i].timing->dsc_cfg)) { |
| 505 | 506 | params[i].timing->flags.DSC = 1; |
| @@ -530,6 +531,7 @@ static int bpp_x16_from_pbn(struct dsc_mst_fairness_params param, int pbn) · 24 unmodified lines | ||
| 530 | 531 | param.sink->ctx->dc->res_pool->dscs[0], |
| 531 | 532 | ¶m.sink->dsc_caps.dsc_dec_caps, |
| 532 | 533 | param.sink->ctx->dc->debug.dsc_min_slice_height_override, |
| 534 | + 0, | |
| 533 | 535 | (int) kbps, param.timing, &dsc_config); |
| 534 | 536 | |
| 535 | 537 | return dsc_config.bits_per_pixel; |
| @@ -734,7 +736,7 @@ static bool compute_mst_dsc_configs_for_link(struct drm_atomic_state *state, · 198 unmodified lines | ||
| 734 | 736 | params[count].num_slices_v = aconnector->dsc_settings.dsc_num_slices_v; |
| 735 | 737 | params[count].bpp_overwrite = aconnector->dsc_settings.dsc_bits_per_pixel; |
| 736 | 738 | params[count].compression_possible = stream->sink->dsc_caps.dsc_dec_caps.is_dsc_supported; |
| 737 | − dc_dsc_get_policy_for_timing(params[count].timing, &dsc_policy); | |
| 739 | + dc_dsc_get_policy_for_timing(params[count].timing, 0, &dsc_policy); | |
| 738 | 740 | if (!dc_dsc_compute_bandwidth_range( |
| 739 | 741 | stream->sink->ctx->dc->res_pool->dscs[0], |
| 740 | 742 | stream->sink->ctx->dc->debug.dsc_min_slice_height_override, |
| @@ -346,13 +346,6 @@ bool dm_pp_get_clock_levels_by_type( · 345 unmodified lines | ||
| 346 | 346 | get_default_clock_levels(clk_type, dc_clks); |
| 347 | 347 | return true; |
| 348 | 348 | } |
| 349 | − } else if (adev->smu.ppt_funcs && adev->smu.ppt_funcs->get_clock_by_type) { | |
| 350 | − if (smu_get_clock_by_type(&adev->smu, | |
| 351 | − dc_to_pp_clock_type(clk_type), | |
| 352 | − &pp_clks)) { | |
| 353 | − get_default_clock_levels(clk_type, dc_clks); | |
| 354 | − return true; | |
| 355 | − } | |
| 356 | 349 | } |
| 357 | 350 | |
| 358 | 351 | pp_to_dc_clock_levels(&pp_clks, dc_clks, clk_type); |
| @@ -366,13 +359,6 @@ bool dm_pp_get_clock_levels_by_type( · 7 unmodified lines | ||
| 366 | 359 | validation_clks.memory_max_clock = 80000; |
| 367 | 360 | validation_clks.level = 0; |
| 368 | 361 | } |
| 369 | − } else if (adev->smu.ppt_funcs && adev->smu.ppt_funcs->get_max_high_clocks) { | |
| 370 | − if (smu_get_max_high_clocks(&adev->smu, &validation_clks)) { | |
| 371 | − DRM_INFO("DM_PPLIB: Warning: using default validation clocks!\n"); | |
| 372 | − validation_clks.engine_max_clock = 72000; | |
| 373 | − validation_clks.memory_max_clock = 80000; | |
| 374 | − validation_clks.level = 0; | |
| 375 | − } | |
| 376 | 362 | } |
| 377 | 363 | |
| 378 | 364 | DRM_INFO("DM_PPLIB: Validation clocks:\n"); |
| @@ -461,11 +447,6 @@ bool dm_pp_get_clock_levels_by_type_with_voltage( · 82 unmodified lines | ||
| 461 | 447 | &pp_clk_info); |
| 462 | 448 | if (ret) |
| 463 | 449 | return false; |
| 464 | − } else if (adev->smu.ppt_funcs && adev->smu.ppt_funcs->get_clock_by_type_with_voltage) { | |
| 465 | − if (smu_get_clock_by_type_with_voltage(&adev->smu, | |
| 466 | − dc_to_pp_clock_type(clk_type), | |
| 467 | − &pp_clk_info)) | |
| 468 | − return false; | |
| 469 | 450 | } |
| 470 | 451 | |
| 471 | 452 | pp_to_dc_clock_levels_with_voltage(&pp_clk_info, clk_level_info, clk_type); |
| @@ -477,7 +458,21 @@ bool dm_pp_notify_wm_clock_changes( · 5 unmodified lines | ||
| 477 | 458 | const struct dc_context *ctx, |
| 478 | 459 | struct dm_pp_wm_sets_with_clock_ranges *wm_with_clock_ranges) |
| 479 | 460 | { |
| 480 | − /* TODO: to be implemented */ | |
| 461 | + struct amdgpu_device *adev = ctx->driver_context; | |
| 462 | + void *pp_handle = adev->powerplay.pp_handle; | |
| 463 | + const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; | |
| 464 | + | |
| 465 | + /* | |
| 466 | + * Limit this watermark setting for Polaris for now | |
| 467 | + * TODO: expand this to other ASICs | |
| 468 | + */ | |
| 469 | + if ((adev->asic_type >= CHIP_POLARIS10) && (adev->asic_type <= CHIP_VEGAM) | |
| 470 | + && pp_funcs && pp_funcs->set_watermarks_for_clocks_ranges) { | |
| 471 | + if (!pp_funcs->set_watermarks_for_clocks_ranges(pp_handle, | |
| 472 | + (void *)wm_with_clock_ranges)) | |
| 473 | + return true; | |
| 474 | + } | |
| 475 | + | |
| 481 | 476 | return false; |
| 482 | 477 | } |
| 483 | 478 | |
| @@ -528,8 +523,6 @@ bool dm_pp_get_static_clocks( · 44 unmodified lines | ||
| 528 | 523 | ret = adev->powerplay.pp_funcs->get_current_clocks( |
| 529 | 524 | adev->powerplay.pp_handle, |
| 530 | 525 | &pp_clk_info); |
| 531 | − else if (adev->smu.ppt_funcs) | |
| 532 | − ret = smu_get_current_clocks(&adev->smu, &pp_clk_info); | |
| 533 | 526 | else |
| 534 | 527 | return false; |
| 535 | 528 | if (ret) |
| @@ -603,8 +596,6 @@ void pp_rv_set_pme_wa_enable(struct pp_smu *pp) · 67 unmodified lines | ||
| 603 | 596 | |
| 604 | 597 | if (pp_funcs && pp_funcs->notify_smu_enable_pwe) |
| 605 | 598 | pp_funcs->notify_smu_enable_pwe(pp_handle); |
| 606 | − else if (adev->smu.ppt_funcs) | |
| 607 | − smu_notify_smu_enable_pwe(&adev->smu); | |
| 608 | 599 | } |
| 609 | 600 | |
| 610 | 601 | void pp_rv_set_active_display_count(struct pp_smu *pp, int count) |
| @@ -33,18 +33,23 @@ · 32 unmodified lines | ||
| 33 | 33 | #include "amdgpu_dm.h" |
| 34 | 34 | #include "amdgpu_dm_irq.h" |
| 35 | 35 | #include "amdgpu_pm.h" |
| 36 | +#include "amdgpu_dm_trace.h" | |
| 36 | 37 | |
| 37 | − | |
| 38 | − | |
| 39 | −unsigned long long dm_get_elapse_time_in_ns(struct dc_context *ctx, | |
| 40 | − unsigned long long current_time_stamp, | |
| 41 | − unsigned long long last_time_stamp) | |
| 38 | + unsigned long long | |
| 39 | + dm_get_elapse_time_in_ns(struct dc_context *ctx, | |
| 40 | + unsigned long long current_time_stamp, | |
| 41 | + unsigned long long last_time_stamp) | |
| 42 | 42 | { |
| 43 | 43 | return current_time_stamp - last_time_stamp; |
| 44 | 44 | } |
| 45 | 45 | |
| 46 | −void dm_perf_trace_timestamp(const char *func_name, unsigned int line) | |
| 46 | +void dm_perf_trace_timestamp(const char *func_name, unsigned int line, struct dc_context *ctx) | |
| 47 | 47 | { |
| 48 | + trace_amdgpu_dc_performance(ctx->perf_trace->read_count, | |
| 49 | + ctx->perf_trace->write_count, | |
| 50 | + &ctx->perf_trace->last_entry_read, | |
| 51 | + &ctx->perf_trace->last_entry_write, | |
| 52 | + func_name, line); | |
| 48 | 53 | } |
| 49 | 54 | |
| 50 | 55 | /**** power component interfaces ****/ |
| @@ -26,45 +26,46 @@ · 25 unmodified lines | ||
| 26 | 26 | #undef TRACE_SYSTEM |
| 27 | 27 | #define TRACE_SYSTEM amdgpu_dm |
| 28 | 28 | |
| 29 | −#if !defined(_AMDGPU_DM_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) | |
| 29 | +#if !defined(_AMDGPU_DM_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ) | |
| 30 | 30 | #define _AMDGPU_DM_TRACE_H_ |
| 31 | 31 | |
| 32 | 32 | #include <linux/tracepoint.h> |
| 33 | +#include <drm/drm_connector.h> | |
| 34 | +#include <drm/drm_crtc.h> | |
| 35 | +#include <drm/drm_plane.h> | |
| 36 | +#include <drm/drm_fourcc.h> | |
| 37 | +#include <drm/drm_encoder.h> | |
| 38 | +#include <drm/drm_atomic.h> | |
| 33 | 39 | |
| 34 | −TRACE_EVENT(amdgpu_dc_rreg, | |
| 35 | − TP_PROTO(unsigned long *read_count, uint32_t reg, uint32_t value), | |
| 36 | − TP_ARGS(read_count, reg, value), | |
| 37 | − TP_STRUCT__entry( | |
| 38 | − __field(uint32_t, reg) | |
| 39 | − __field(uint32_t, value) | |
| 40 | − ), | |
| 41 | − TP_fast_assign( | |
| 42 | − __entry->reg = reg; | |
| 43 | − __entry->value = value; | |
| 44 | − *read_count = *read_count + 1; | |
| 45 | − ), | |
| 46 | − TP_printk("reg=0x%08lx, value=0x%08lx", | |
| 47 | − (unsigned long)__entry->reg, | |
| 48 | − (unsigned long)__entry->value) | |
| 49 | −); | |
| 40 | +#include "dc/inc/core_types.h" | |
| 50 | 41 | |
| 51 | −TRACE_EVENT(amdgpu_dc_wreg, | |
| 52 | − TP_PROTO(unsigned long *write_count, uint32_t reg, uint32_t value), | |
| 53 | − TP_ARGS(write_count, reg, value), | |
| 54 | − TP_STRUCT__entry( | |
| 55 | − __field(uint32_t, reg) | |
| 56 | − __field(uint32_t, value) | |
| 57 | − ), | |
| 58 | − TP_fast_assign( | |
| 59 | − __entry->reg = reg; | |
| 60 | − __entry->value = value; | |
| 61 | − *write_count = *write_count + 1; | |
| 62 | − ), | |
| 63 | − TP_printk("reg=0x%08lx, value=0x%08lx", | |
| 64 | − (unsigned long)__entry->reg, | |
| 65 | − (unsigned long)__entry->value) | |
| 42 | +DECLARE_EVENT_CLASS(amdgpu_dc_reg_template, | |
| 43 | + TP_PROTO(unsigned long *count, uint32_t reg, uint32_t value), | |
| 44 | + TP_ARGS(count, reg, value), | |
| 45 | + | |
| 46 | + TP_STRUCT__entry( | |
| 47 | + __field(uint32_t, reg) | |
| 48 | + __field(uint32_t, value) | |
| 49 | + ), | |
| 50 | + | |
| 51 | + TP_fast_assign( | |
| 52 | + __entry->reg = reg; | |
| 53 | + __entry->value = value; | |
| 54 | + *count = *count + 1; | |
| 55 | + ), | |
| 56 | + | |
| 57 | + TP_printk("reg=0x%08lx, value=0x%08lx", | |
| 58 | + (unsigned long)__entry->reg, | |
| 59 | + (unsigned long)__entry->value) | |
| 66 | 60 | ); |
| 67 | 61 | |
| 62 | +DEFINE_EVENT(amdgpu_dc_reg_template, amdgpu_dc_rreg, | |
| 63 | + TP_PROTO(unsigned long *count, uint32_t reg, uint32_t value), | |
| 64 | + TP_ARGS(count, reg, value)); | |
| 65 | + | |
| 66 | +DEFINE_EVENT(amdgpu_dc_reg_template, amdgpu_dc_wreg, | |
| 67 | + TP_PROTO(unsigned long *count, uint32_t reg, uint32_t value), | |
| 68 | + TP_ARGS(count, reg, value)); | |
| 68 | 69 | |
| 69 | 70 | TRACE_EVENT(amdgpu_dc_performance, |
| 70 | 71 | TP_PROTO(unsigned long read_count, unsigned long write_count, |
| @@ -96,6 +97,506 @@ TRACE_EVENT(amdgpu_dc_performance, · 25 unmodified lines | ||
| 96 | 97 | (unsigned long)__entry->write_delta, |
| 97 | 98 | (unsigned long)__entry->writes) |
| 98 | 99 | ); |
| 100 | + | |
| 101 | +TRACE_EVENT(amdgpu_dm_connector_atomic_check, | |
| 102 | + TP_PROTO(const struct drm_connector_state *state), | |
| 103 | + TP_ARGS(state), | |
| 104 | + | |
| 105 | + TP_STRUCT__entry( | |
| 106 | + __field(uint32_t, conn_id) | |
| 107 | + __field(const struct drm_connector_state *, conn_state) | |
| 108 | + __field(const struct drm_atomic_state *, state) | |
| 109 | + __field(const struct drm_crtc_commit *, commit) | |
| 110 | + __field(uint32_t, crtc_id) | |
| 111 | + __field(uint32_t, best_encoder_id) | |
| 112 | + __field(enum drm_link_status, link_status) | |
| 113 | + __field(bool, self_refresh_aware) | |
| 114 | + __field(enum hdmi_picture_aspect, picture_aspect_ratio) | |
| 115 | + __field(unsigned int, content_type) | |
| 116 | + __field(unsigned int, hdcp_content_type) | |
| 117 | + __field(unsigned int, content_protection) | |
| 118 | + __field(unsigned int, scaling_mode) | |
| 119 | + __field(u32, colorspace) | |
| 120 | + __field(u8, max_requested_bpc) | |
| 121 | + __field(u8, max_bpc) | |
| 122 | + ), | |
| 123 | + | |
| 124 | + TP_fast_assign( | |
| 125 | + __entry->conn_id = state->connector->base.id; | |
| 126 | + __entry->conn_state = state; | |
| 127 | + __entry->state = state->state; | |
| 128 | + __entry->commit = state->commit; | |
| 129 | + __entry->crtc_id = state->crtc ? state->crtc->base.id : 0; | |
| 130 | + __entry->best_encoder_id = state->best_encoder ? | |
| 131 | + state->best_encoder->base.id : 0; | |
| 132 | + __entry->link_status = state->link_status; | |
| 133 | + __entry->self_refresh_aware = state->self_refresh_aware; | |
| 134 | + __entry->picture_aspect_ratio = state->picture_aspect_ratio; | |
| 135 | + __entry->content_type = state->content_type; | |
| 136 | + __entry->hdcp_content_type = state->hdcp_content_type; | |
| 137 | + __entry->content_protection = state->content_protection; | |
| 138 | + __entry->scaling_mode = state->scaling_mode; | |
| 139 | + __entry->colorspace = state->colorspace; | |
| 140 | + __entry->max_requested_bpc = state->max_requested_bpc; | |
| 141 | + __entry->max_bpc = state->max_bpc; | |
| 142 | + ), | |
| 143 | + | |
| 144 | + TP_printk("conn_id=%u conn_state=%p state=%p commit=%p crtc_id=%u " | |
| 145 | + "best_encoder_id=%u link_status=%d self_refresh_aware=%d " | |
| 146 | + "picture_aspect_ratio=%d content_type=%u " | |
| 147 | + "hdcp_content_type=%u content_protection=%u scaling_mode=%u " | |
| 148 | + "colorspace=%u max_requested_bpc=%u max_bpc=%u", | |
| 149 | + __entry->conn_id, __entry->conn_state, __entry->state, | |
| 150 | + __entry->commit, __entry->crtc_id, __entry->best_encoder_id, | |
| 151 | + __entry->link_status, __entry->self_refresh_aware, | |
| 152 | + __entry->picture_aspect_ratio, __entry->content_type, | |
| 153 | + __entry->hdcp_content_type, __entry->content_protection, | |
| 154 | + __entry->scaling_mode, __entry->colorspace, | |
| 155 | + __entry->max_requested_bpc, __entry->max_bpc) | |
| 156 | +); | |
| 157 | + | |
| 158 | +TRACE_EVENT(amdgpu_dm_crtc_atomic_check, | |
| 159 | + TP_PROTO(const struct drm_crtc_state *state), | |
| 160 | + TP_ARGS(state), | |
| 161 | + | |
| 162 | + TP_STRUCT__entry( | |
| 163 | + __field(const struct drm_atomic_state *, state) | |
| 164 | + __field(const struct drm_crtc_state *, crtc_state) | |
| 165 | + __field(const struct drm_crtc_commit *, commit) | |
| 166 | + __field(uint32_t, crtc_id) | |
| 167 | + __field(bool, enable) | |
| 168 | + __field(bool, active) | |
| 169 | + __field(bool, planes_changed) | |
| 170 | + __field(bool, mode_changed) | |
| 171 | + __field(bool, active_changed) | |
| 172 | + __field(bool, connectors_changed) | |
| 173 | + __field(bool, zpos_changed) | |
| 174 | + __field(bool, color_mgmt_changed) | |
| 175 | + __field(bool, no_vblank) | |
| 176 | + __field(bool, async_flip) | |
| 177 | + __field(bool, vrr_enabled) | |
| 178 | + __field(bool, self_refresh_active) | |
| 179 | + __field(u32, plane_mask) | |
| 180 | + __field(u32, connector_mask) | |
| 181 | + __field(u32, encoder_mask) | |
| 182 | + ), | |
| 183 | + | |
| 184 | + TP_fast_assign( | |
| 185 | + __entry->state = state->state; | |
| 186 | + __entry->crtc_state = state; | |
| 187 | + __entry->crtc_id = state->crtc->base.id; | |
| 188 | + __entry->commit = state->commit; | |
| 189 | + __entry->enable = state->enable; | |
| 190 | + __entry->active = state->active; | |
| 191 | + __entry->planes_changed = state->planes_changed; | |
| 192 | + __entry->mode_changed = state->mode_changed; | |
| 193 | + __entry->active_changed = state->active_changed; | |
| 194 | + __entry->connectors_changed = state->connectors_changed; | |
| 195 | + __entry->zpos_changed = state->zpos_changed; | |
| 196 | + __entry->color_mgmt_changed = state->color_mgmt_changed; | |
| 197 | + __entry->no_vblank = state->no_vblank; | |
| 198 | + __entry->async_flip = state->async_flip; | |
| 199 | + __entry->vrr_enabled = state->vrr_enabled; | |
| 200 | + __entry->self_refresh_active = state->self_refresh_active; | |
| 201 | + __entry->plane_mask = state->plane_mask; | |
| 202 | + __entry->connector_mask = state->connector_mask; | |
| 203 | + __entry->encoder_mask = state->encoder_mask; | |
| 204 | + ), | |
| 205 | + | |
| 206 | + TP_printk("crtc_id=%u crtc_state=%p state=%p commit=%p changed(" | |
| 207 | + "planes=%d mode=%d active=%d conn=%d zpos=%d color_mgmt=%d) " | |
| 208 | + "state(enable=%d active=%d async_flip=%d vrr_enabled=%d " | |
| 209 | + "self_refresh_active=%d no_vblank=%d) mask(plane=%x conn=%x " | |
| 210 | + "enc=%x)", | |
| 211 | + __entry->crtc_id, __entry->crtc_state, __entry->state, | |
| 212 | + __entry->commit, __entry->planes_changed, | |
| 213 | + __entry->mode_changed, __entry->active_changed, | |
| 214 | + __entry->connectors_changed, __entry->zpos_changed, | |
| 215 | + __entry->color_mgmt_changed, __entry->enable, __entry->active, | |
| 216 | + __entry->async_flip, __entry->vrr_enabled, | |
| 217 | + __entry->self_refresh_active, __entry->no_vblank, | |
| 218 | + __entry->plane_mask, __entry->connector_mask, | |
| 219 | + __entry->encoder_mask) | |
| 220 | +); | |
| 221 | + | |
| 222 | +DECLARE_EVENT_CLASS(amdgpu_dm_plane_state_template, | |
| 223 | + TP_PROTO(const struct drm_plane_state *state), | |
| 224 | + TP_ARGS(state), | |
| 225 | + TP_STRUCT__entry( | |
| 226 | + __field(uint32_t, plane_id) | |
| 227 | + __field(enum drm_plane_type, plane_type) | |
| 228 | + __field(const struct drm_plane_state *, plane_state) | |
| 229 | + __field(const struct drm_atomic_state *, state) | |
| 230 | + __field(uint32_t, crtc_id) | |
| 231 | + __field(uint32_t, fb_id) | |
| 232 | + __field(uint32_t, fb_format) | |
| 233 | + __field(uint8_t, fb_planes) | |
| 234 | + __field(uint64_t, fb_modifier) | |
| 235 | + __field(const struct dma_fence *, fence) | |
| 236 | + __field(int32_t, crtc_x) | |
| 237 | + __field(int32_t, crtc_y) | |
| 238 | + __field(uint32_t, crtc_w) | |
| 239 | + __field(uint32_t, crtc_h) | |
| 240 | + __field(uint32_t, src_x) | |
| 241 | + __field(uint32_t, src_y) | |
| 242 | + __field(uint32_t, src_w) | |
| 243 | + __field(uint32_t, src_h) | |
| 244 | + __field(u32, alpha) | |
| 245 | + __field(uint32_t, pixel_blend_mode) | |
| 246 | + __field(unsigned int, rotation) | |
| 247 | + __field(unsigned int, zpos) | |
| 248 | + __field(unsigned int, normalized_zpos) | |
| 249 | + __field(enum drm_color_encoding, color_encoding) | |
| 250 | + __field(enum drm_color_range, color_range) | |
| 251 | + __field(bool, visible) | |
| 252 | + ), | |
| 253 | + | |
| 254 | + TP_fast_assign( | |
| 255 | + __entry->plane_id = state->plane->base.id; | |
| 256 | + __entry->plane_type = state->plane->type; | |
| 257 | + __entry->plane_state = state; | |
| 258 | + __entry->state = state->state; | |
| 259 | + __entry->crtc_id = state->crtc ? state->crtc->base.id : 0; | |
| 260 | + __entry->fb_id = state->fb ? state->fb->base.id : 0; | |
| 261 | + __entry->fb_format = state->fb ? state->fb->format->format : 0; | |
| 262 | + __entry->fb_planes = state->fb ? state->fb->format->num_planes : 0; | |
| 263 | + __entry->fb_modifier = state->fb ? state->fb->modifier : 0; | |
| 264 | + __entry->fence = state->fence; | |
| 265 | + __entry->crtc_x = state->crtc_x; | |
| 266 | + __entry->crtc_y = state->crtc_y; | |
| 267 | + __entry->crtc_w = state->crtc_w; | |
| 268 | + __entry->crtc_h = state->crtc_h; | |
| 269 | + __entry->src_x = state->src_x >> 16; | |
| 270 | + __entry->src_y = state->src_y >> 16; | |
| 271 | + __entry->src_w = state->src_w >> 16; | |
| 272 | + __entry->src_h = state->src_h >> 16; | |
| 273 | + __entry->alpha = state->alpha; | |
| 274 | + __entry->pixel_blend_mode = state->pixel_blend_mode; | |
| 275 | + __entry->rotation = state->rotation; | |
| 276 | + __entry->zpos = state->zpos; | |
| 277 | + __entry->normalized_zpos = state->normalized_zpos; | |
| 278 | + __entry->color_encoding = state->color_encoding; | |
| 279 | + __entry->color_range = state->color_range; | |
| 280 | + __entry->visible = state->visible; | |
| 281 | + ), | |
| 282 | + | |
| 283 | + TP_printk("plane_id=%u plane_type=%d plane_state=%p state=%p " | |
| 284 | + "crtc_id=%u fb(id=%u fmt=%c%c%c%c planes=%u mod=%llu) " | |
| 285 | + "fence=%p crtc_x=%d crtc_y=%d crtc_w=%u crtc_h=%u " | |
| 286 | + "src_x=%u src_y=%u src_w=%u src_h=%u alpha=%u " | |
| 287 | + "pixel_blend_mode=%u rotation=%u zpos=%u " | |
| 288 | + "normalized_zpos=%u color_encoding=%d color_range=%d " | |
| 289 | + "visible=%d", | |
| 290 | + __entry->plane_id, __entry->plane_type, __entry->plane_state, | |
| 291 | + __entry->state, __entry->crtc_id, __entry->fb_id, | |
| 292 | + (__entry->fb_format & 0xff) ? (__entry->fb_format & 0xff) : 'N', | |
| 293 | + ((__entry->fb_format >> 8) & 0xff) ? ((__entry->fb_format >> 8) & 0xff) : 'O', | |
| 294 | + ((__entry->fb_format >> 16) & 0xff) ? ((__entry->fb_format >> 16) & 0xff) : 'N', | |
| 295 | + ((__entry->fb_format >> 24) & 0x7f) ? ((__entry->fb_format >> 24) & 0x7f) : 'E', | |
| 296 | + __entry->fb_planes, | |
| 297 | + __entry->fb_modifier, __entry->fence, __entry->crtc_x, | |
| 298 | + __entry->crtc_y, __entry->crtc_w, __entry->crtc_h, | |
| 299 | + __entry->src_x, __entry->src_y, __entry->src_w, __entry->src_h, | |
| 300 | + __entry->alpha, __entry->pixel_blend_mode, __entry->rotation, | |
| 301 | + __entry->zpos, __entry->normalized_zpos, | |
| 302 | + __entry->color_encoding, __entry->color_range, | |
| 303 | + __entry->visible) | |
| 304 | +); | |
| 305 | + | |
| 306 | +DEFINE_EVENT(amdgpu_dm_plane_state_template, amdgpu_dm_plane_atomic_check, | |
| 307 | + TP_PROTO(const struct drm_plane_state *state), | |
| 308 | + TP_ARGS(state)); | |
| 309 | + | |
| 310 | +DEFINE_EVENT(amdgpu_dm_plane_state_template, amdgpu_dm_atomic_update_cursor, | |
| 311 | + TP_PROTO(const struct drm_plane_state *state), | |
| 312 | + TP_ARGS(state)); | |
| 313 | + | |
| 314 | +TRACE_EVENT(amdgpu_dm_atomic_state_template, | |
| 315 | + TP_PROTO(const struct drm_atomic_state *state), | |
| 316 | + TP_ARGS(state), | |
| 317 | + | |
| 318 | + TP_STRUCT__entry( | |
| 319 | + __field(const struct drm_atomic_state *, state) | |
| 320 | + __field(bool, allow_modeset) | |
| 321 | + __field(bool, legacy_cursor_update) | |
| 322 | + __field(bool, async_update) | |
| 323 | + __field(bool, duplicated) | |
| 324 | + __field(int, num_connector) | |
| 325 | + __field(int, num_private_objs) | |
| 326 | + ), | |
| 327 | + | |
| 328 | + TP_fast_assign( | |
| 329 | + __entry->state = state; | |
| 330 | + __entry->allow_modeset = state->allow_modeset; | |
| 331 | + __entry->legacy_cursor_update = state->legacy_cursor_update; | |
| 332 | + __entry->async_update = state->async_update; | |
| 333 | + __entry->duplicated = state->duplicated; | |
| 334 | + __entry->num_connector = state->num_connector; | |
| 335 | + __entry->num_private_objs = state->num_private_objs; | |
| 336 | + ), | |
| 337 | + | |
| 338 | + TP_printk("state=%p allow_modeset=%d legacy_cursor_update=%d " | |
| 339 | + "async_update=%d duplicated=%d num_connector=%d " | |
| 340 | + "num_private_objs=%d", | |
| 341 | + __entry->state, __entry->allow_modeset, __entry->legacy_cursor_update, | |
| 342 | + __entry->async_update, __entry->duplicated, __entry->num_connector, | |
| 343 | + __entry->num_private_objs) | |
| 344 | +); | |
| 345 | + | |
| 346 | +DEFINE_EVENT(amdgpu_dm_atomic_state_template, amdgpu_dm_atomic_commit_tail_begin, | |
| 347 | + TP_PROTO(const struct drm_atomic_state *state), | |
| 348 | + TP_ARGS(state)); | |
| 349 | + | |
| 350 | +DEFINE_EVENT(amdgpu_dm_atomic_state_template, amdgpu_dm_atomic_commit_tail_finish, | |
| 351 | + TP_PROTO(const struct drm_atomic_state *state), | |
| 352 | + TP_ARGS(state)); | |
| 353 | + | |
| 354 | +DEFINE_EVENT(amdgpu_dm_atomic_state_template, amdgpu_dm_atomic_check_begin, | |
| 355 | + TP_PROTO(const struct drm_atomic_state *state), | |
| 356 | + TP_ARGS(state)); | |
| 357 | + | |
| 358 | +TRACE_EVENT(amdgpu_dm_atomic_check_finish, | |
| 359 | + TP_PROTO(const struct drm_atomic_state *state, int res), | |
| 360 | + TP_ARGS(state, res), | |
| 361 | + | |
| 362 | + TP_STRUCT__entry( | |
| 363 | + __field(const struct drm_atomic_state *, state) | |
| 364 | + __field(int, res) | |
| 365 | + __field(bool, async_update) | |
| 366 | + __field(bool, allow_modeset) | |
| 367 | + ), | |
| 368 | + | |
| 369 | + TP_fast_assign( | |
| 370 | + __entry->state = state; | |
| 371 | + __entry->res = res; | |
| 372 | + __entry->async_update = state->async_update; | |
| 373 | + __entry->allow_modeset = state->allow_modeset; | |
| 374 | + ), | |
| 375 | + | |
| 376 | + TP_printk("state=%p res=%d async_update=%d allow_modeset=%d", | |
| 377 | + __entry->state, __entry->res, | |
| 378 | + __entry->async_update, __entry->allow_modeset) | |
| 379 | +); | |
| 380 | + | |
| 381 | +TRACE_EVENT(amdgpu_dm_dc_pipe_state, | |
| 382 | + TP_PROTO(int pipe_idx, const struct dc_plane_state *plane_state, | |
| 383 | + const struct dc_stream_state *stream, | |
| 384 | + const struct plane_resource *plane_res, | |
| 385 | + int update_flags), | |
| 386 | + TP_ARGS(pipe_idx, plane_state, stream, plane_res, update_flags), | |
| 387 | + | |
| 388 | + TP_STRUCT__entry( | |
| 389 | + __field(int, pipe_idx) | |
| 390 | + __field(const void *, stream) | |
| 391 | + __field(int, stream_w) | |
| 392 | + __field(int, stream_h) | |
| 393 | + __field(int, dst_x) | |
| 394 | + __field(int, dst_y) | |
| 395 | + __field(int, dst_w) | |
| 396 | + __field(int, dst_h) | |
| 397 | + __field(int, src_x) | |
| 398 | + __field(int, src_y) | |
| 399 | + __field(int, src_w) | |
| 400 | + __field(int, src_h) | |
| 401 | + __field(int, clip_x) | |
| 402 | + __field(int, clip_y) | |
| 403 | + __field(int, clip_w) | |
| 404 | + __field(int, clip_h) | |
| 405 | + __field(int, recout_x) | |
| 406 | + __field(int, recout_y) | |
| 407 | + __field(int, recout_w) | |
| 408 | + __field(int, recout_h) | |
| 409 | + __field(int, viewport_x) | |
| 410 | + __field(int, viewport_y) | |
| 411 | + __field(int, viewport_w) | |
| 412 | + __field(int, viewport_h) | |
| 413 | + __field(int, flip_immediate) | |
| 414 | + __field(int, surface_pitch) | |
| 415 | + __field(int, format) | |
| 416 | + __field(int, swizzle) | |
| 417 | + __field(unsigned int, update_flags) | |
| 418 | + ), | |
| 419 | + | |
| 420 | + TP_fast_assign( | |
| 421 | + __entry->pipe_idx = pipe_idx; | |
| 422 | + __entry->stream = stream; | |
| 423 | + __entry->stream_w = stream->timing.h_addressable; | |
| 424 | + __entry->stream_h = stream->timing.v_addressable; | |
| 425 | + __entry->dst_x = plane_state->dst_rect.x; | |
| 426 | + __entry->dst_y = plane_state->dst_rect.y; | |
| 427 | + __entry->dst_w = plane_state->dst_rect.width; | |
| 428 | + __entry->dst_h = plane_state->dst_rect.height; | |
| 429 | + __entry->src_x = plane_state->src_rect.x; | |
| 430 | + __entry->src_y = plane_state->src_rect.y; | |
| 431 | + __entry->src_w = plane_state->src_rect.width; | |
| 432 | + __entry->src_h = plane_state->src_rect.height; | |
| 433 | + __entry->clip_x = plane_state->clip_rect.x; | |
| 434 | + __entry->clip_y = plane_state->clip_rect.y; | |
| 435 | + __entry->clip_w = plane_state->clip_rect.width; | |
| 436 | + __entry->clip_h = plane_state->clip_rect.height; | |
| 437 | + __entry->recout_x = plane_res->scl_data.recout.x; | |
| 438 | + __entry->recout_y = plane_res->scl_data.recout.y; | |
| 439 | + __entry->recout_w = plane_res->scl_data.recout.width; | |
| 440 | + __entry->recout_h = plane_res->scl_data.recout.height; | |
| 441 | + __entry->viewport_x = plane_res->scl_data.viewport.x; | |
| 442 | + __entry->viewport_y = plane_res->scl_data.viewport.y; | |
| 443 | + __entry->viewport_w = plane_res->scl_data.viewport.width; | |
| 444 | + __entry->viewport_h = plane_res->scl_data.viewport.height; | |
| 445 | + __entry->flip_immediate = plane_state->flip_immediate; | |
| 446 | + __entry->surface_pitch = plane_state->plane_size.surface_pitch; | |
| 447 | + __entry->format = plane_state->format; | |
| 448 | + __entry->swizzle = plane_state->tiling_info.gfx9.swizzle; | |
| 449 | + __entry->update_flags = update_flags; | |
| 450 | + ), | |
| 451 | + TP_printk("pipe_idx=%d stream=%p rct(%d,%d) dst=(%d,%d,%d,%d) " | |
| 452 | + "src=(%d,%d,%d,%d) clip=(%d,%d,%d,%d) recout=(%d,%d,%d,%d) " | |
| 453 | + "viewport=(%d,%d,%d,%d) flip_immediate=%d pitch=%d " | |
| 454 | + "format=%d swizzle=%d update_flags=%x", | |
| 455 | + __entry->pipe_idx, | |
| 456 | + __entry->stream, | |
| 457 | + __entry->stream_w, | |
| 458 | + __entry->stream_h, | |
| 459 | + __entry->dst_x, | |
| 460 | + __entry->dst_y, | |
| 461 | + __entry->dst_w, | |
| 462 | + __entry->dst_h, | |
| 463 | + __entry->src_x, | |
| 464 | + __entry->src_y, | |
| 465 | + __entry->src_w, | |
| 466 | + __entry->src_h, | |
| 467 | + __entry->clip_x, | |
| 468 | + __entry->clip_y, | |
| 469 | + __entry->clip_w, | |
| 470 | + __entry->clip_h, | |
| 471 | + __entry->recout_x, | |
| 472 | + __entry->recout_y, | |
| 473 | + __entry->recout_w, | |
| 474 | + __entry->recout_h, | |
| 475 | + __entry->viewport_x, | |
| 476 | + __entry->viewport_y, | |
| 477 | + __entry->viewport_w, | |
| 478 | + __entry->viewport_h, | |
| 479 | + __entry->flip_immediate, | |
| 480 | + __entry->surface_pitch, | |
| 481 | + __entry->format, | |
| 482 | + __entry->swizzle, | |
| 483 | + __entry->update_flags | |
| 484 | + ) | |
| 485 | +); | |
| 486 | + | |
| 487 | +TRACE_EVENT(amdgpu_dm_dc_clocks_state, | |
| 488 | + TP_PROTO(const struct dc_clocks *clk), | |
| 489 | + TP_ARGS(clk), | |
| 490 | + | |
| 491 | + TP_STRUCT__entry( | |
| 492 | + __field(int, dispclk_khz) | |
| 493 | + __field(int, dppclk_khz) | |
| 494 | + __field(int, disp_dpp_voltage_level_khz) | |
| 495 | + __field(int, dcfclk_khz) | |
| 496 | + __field(int, socclk_khz) | |
| 497 | + __field(int, dcfclk_deep_sleep_khz) | |
| 498 | + __field(int, fclk_khz) | |
| 499 | + __field(int, phyclk_khz) | |
| 500 | + __field(int, dramclk_khz) | |
| 501 | + __field(int, p_state_change_support) | |
| 502 | + __field(int, prev_p_state_change_support) | |
| 503 | + __field(int, pwr_state) | |
| 504 | + __field(int, dtm_level) | |
| 505 | + __field(int, max_supported_dppclk_khz) | |
| 506 | + __field(int, max_supported_dispclk_khz) | |
| 507 | + __field(int, bw_dppclk_khz) | |
| 508 | + __field(int, bw_dispclk_khz) | |
| 509 | + ), | |
| 510 | + TP_fast_assign( | |
| 511 | + __entry->dispclk_khz = clk->dispclk_khz; | |
| 512 | + __entry->dppclk_khz = clk->dppclk_khz; | |
| 513 | + __entry->dcfclk_khz = clk->dcfclk_khz; | |
| 514 | + __entry->socclk_khz = clk->socclk_khz; | |
| 515 | + __entry->dcfclk_deep_sleep_khz = clk->dcfclk_deep_sleep_khz; | |
| 516 | + __entry->fclk_khz = clk->fclk_khz; | |
| 517 | + __entry->phyclk_khz = clk->phyclk_khz; | |
| 518 | + __entry->dramclk_khz = clk->dramclk_khz; | |
| 519 | + __entry->p_state_change_support = clk->p_state_change_support; | |
| 520 | + __entry->prev_p_state_change_support = clk->prev_p_state_change_support; | |
| 521 | + __entry->pwr_state = clk->pwr_state; | |
| 522 | + __entry->prev_p_state_change_support = clk->prev_p_state_change_support; | |
| 523 | + __entry->dtm_level = clk->dtm_level; | |
| 524 | + __entry->max_supported_dppclk_khz = clk->max_supported_dppclk_khz; | |
| 525 | + __entry->max_supported_dispclk_khz = clk->max_supported_dispclk_khz; | |
| 526 | + __entry->bw_dppclk_khz = clk->bw_dppclk_khz; | |
| 527 | + __entry->bw_dispclk_khz = clk->bw_dispclk_khz; | |
| 528 | + ), | |
| 529 | + TP_printk("dispclk_khz=%d dppclk_khz=%d disp_dpp_voltage_level_khz=%d dcfclk_khz=%d socclk_khz=%d " | |
| 530 | + "dcfclk_deep_sleep_khz=%d fclk_khz=%d phyclk_khz=%d " | |
| 531 | + "dramclk_khz=%d p_state_change_support=%d " | |
| 532 | + "prev_p_state_change_support=%d pwr_state=%d prev_p_state_change_support=%d " | |
| 533 | + "dtm_level=%d max_supported_dppclk_khz=%d max_supported_dispclk_khz=%d " | |
| 534 | + "bw_dppclk_khz=%d bw_dispclk_khz=%d ", | |
| 535 | + __entry->dispclk_khz, | |
| 536 | + __entry->dppclk_khz, | |
| 537 | + __entry->disp_dpp_voltage_level_khz, | |
| 538 | + __entry->dcfclk_khz, | |
| 539 | + __entry->socclk_khz, | |
| 540 | + __entry->dcfclk_deep_sleep_khz, | |
| 541 | + __entry->fclk_khz, | |
| 542 | + __entry->phyclk_khz, | |
| 543 | + __entry->dramclk_khz, | |
| 544 | + __entry->p_state_change_support, | |
| 545 | + __entry->prev_p_state_change_support, | |
| 546 | + __entry->pwr_state, | |
| 547 | + __entry->prev_p_state_change_support, | |
| 548 | + __entry->dtm_level, | |
| 549 | + __entry->max_supported_dppclk_khz, | |
| 550 | + __entry->max_supported_dispclk_khz, | |
| 551 | + __entry->bw_dppclk_khz, | |
| 552 | + __entry->bw_dispclk_khz | |
| 553 | + ) | |
| 554 | +); | |
| 555 | + | |
| 556 | +TRACE_EVENT(amdgpu_dm_dce_clocks_state, | |
| 557 | + TP_PROTO(const struct dce_bw_output *clk), | |
| 558 | + TP_ARGS(clk), | |
| 559 | + | |
| 560 | + TP_STRUCT__entry( | |
| 561 | + __field(bool, cpuc_state_change_enable) | |
| 562 | + __field(bool, cpup_state_change_enable) | |
| 563 | + __field(bool, stutter_mode_enable) | |
| 564 | + __field(bool, nbp_state_change_enable) | |
| 565 | + __field(bool, all_displays_in_sync) | |
| 566 | + __field(int, sclk_khz) | |
| 567 | + __field(int, sclk_deep_sleep_khz) | |
| 568 | + __field(int, yclk_khz) | |
| 569 | + __field(int, dispclk_khz) | |
| 570 | + __field(int, blackout_recovery_time_us) | |
| 571 | + ), | |
| 572 | + TP_fast_assign( | |
| 573 | + __entry->cpuc_state_change_enable = clk->cpuc_state_change_enable; | |
| 574 | + __entry->cpup_state_change_enable = clk->cpup_state_change_enable; | |
| 575 | + __entry->stutter_mode_enable = clk->stutter_mode_enable; | |
| 576 | + __entry->nbp_state_change_enable = clk->nbp_state_change_enable; | |
| 577 | + __entry->all_displays_in_sync = clk->all_displays_in_sync; | |
| 578 | + __entry->sclk_khz = clk->sclk_khz; | |
| 579 | + __entry->sclk_deep_sleep_khz = clk->sclk_deep_sleep_khz; | |
| 580 | + __entry->yclk_khz = clk->yclk_khz; | |
| 581 | + __entry->dispclk_khz = clk->dispclk_khz; | |
| 582 | + __entry->blackout_recovery_time_us = clk->blackout_recovery_time_us; | |
| 583 | + ), | |
| 584 | + TP_printk("cpuc_state_change_enable=%d cpup_state_change_enable=%d stutter_mode_enable=%d " | |
| 585 | + "nbp_state_change_enable=%d all_displays_in_sync=%d sclk_khz=%d sclk_deep_sleep_khz=%d " | |
| 586 | + "yclk_khz=%d dispclk_khz=%d blackout_recovery_time_us=%d", | |
| 587 | + __entry->cpuc_state_change_enable, | |
| 588 | + __entry->cpup_state_change_enable, | |
| 589 | + __entry->stutter_mode_enable, | |
| 590 | + __entry->nbp_state_change_enable, | |
| 591 | + __entry->all_displays_in_sync, | |
| 592 | + __entry->sclk_khz, | |
| 593 | + __entry->sclk_deep_sleep_khz, | |
| 594 | + __entry->yclk_khz, | |
| 595 | + __entry->dispclk_khz, | |
| 596 | + __entry->blackout_recovery_time_us | |
| 597 | + ) | |
| 598 | +); | |
| 599 | + | |
| 99 | 600 | #endif /* _AMDGPU_DM_TRACE_H_ */ |
| 100 | 601 | |
| 101 | 602 | #undef TRACE_INCLUDE_PATH |
| @@ -30,10 +30,9 @@ DC_LIBS += dcn20 · 29 unmodified lines | ||
| 30 | 30 | DC_LIBS += dsc |
| 31 | 31 | DC_LIBS += dcn10 dml |
| 32 | 32 | DC_LIBS += dcn21 |
| 33 | −endif | |
| 34 | − | |
| 35 | −ifdef CONFIG_DRM_AMD_DC_DCN3_0 | |
| 36 | 33 | DC_LIBS += dcn30 |
| 34 | +DC_LIBS += dcn301 | |
| 35 | +DC_LIBS += dcn302 | |
| 37 | 36 | endif |
| 38 | 37 | |
| 39 | 38 | DC_LIBS += dce120 |
| @@ -1230,12 +1230,8 @@ static enum bp_result bios_parser_get_firmware_info( · 1229 unmodified lines | ||
| 1230 | 1230 | result = get_firmware_info_v3_1(bp, info); |
| 1231 | 1231 | break; |
| 1232 | 1232 | case 2: |
| 1233 | − result = get_firmware_info_v3_2(bp, info); | |
| 1234 | − break; | |
| 1235 | 1233 | case 3: |
| 1236 | −#ifdef CONFIG_DRM_AMD_DC_DCN3_0 | |
| 1237 | 1234 | case 4: |
| 1238 | −#endif | |
| 1239 | 1235 | result = get_firmware_info_v3_2(bp, info); |
| 1240 | 1236 | break; |
| 1241 | 1237 | default: |
| @@ -1743,6 +1739,165 @@ static enum bp_result get_integrated_info_v11( · 501 unmodified lines | ||
| 1743 | 1739 | return BP_RESULT_OK; |
| 1744 | 1740 | } |
| 1745 | 1741 | |
| 1742 | +static enum bp_result get_integrated_info_v2_1( | |
| 1743 | + struct bios_parser *bp, | |
| 1744 | + struct integrated_info *info) | |
| 1745 | +{ | |
| 1746 | + struct atom_integrated_system_info_v2_1 *info_v2_1; | |
| 1747 | + uint32_t i; | |
| 1748 | + | |
| 1749 | + info_v2_1 = GET_IMAGE(struct atom_integrated_system_info_v2_1, | |
| 1750 | + DATA_TABLES(integratedsysteminfo)); | |
| 1751 | + | |
| 1752 | + if (info_v2_1 == NULL) | |
| 1753 | + return BP_RESULT_BADBIOSTABLE; | |
| 1754 | + | |
| 1755 | + info->gpu_cap_info = | |
| 1756 | + le32_to_cpu(info_v2_1->gpucapinfo); | |
| 1757 | + /* | |
| 1758 | + * system_config: Bit[0] = 0 : PCIE power gating disabled | |
| 1759 | + * = 1 : PCIE power gating enabled | |
| 1760 | + * Bit[1] = 0 : DDR-PLL shut down disabled | |
| 1761 | + * = 1 : DDR-PLL shut down enabled | |
| 1762 | + * Bit[2] = 0 : DDR-PLL power down disabled | |
| 1763 | + * = 1 : DDR-PLL power down enabled | |
| 1764 | + */ | |
| 1765 | + info->system_config = le32_to_cpu(info_v2_1->system_config); | |
| 1766 | + info->cpu_cap_info = le32_to_cpu(info_v2_1->cpucapinfo); | |
| 1767 | + info->memory_type = info_v2_1->memorytype; | |
| 1768 | + info->ma_channel_number = info_v2_1->umachannelnumber; | |
| 1769 | + info->dp_ss_control = | |
| 1770 | + le16_to_cpu(info_v2_1->reserved1); | |
| 1771 | + | |
| 1772 | + for (i = 0; i < NUMBER_OF_UCHAR_FOR_GUID; ++i) { | |
| 1773 | + info->ext_disp_conn_info.gu_id[i] = | |
| 1774 | + info_v2_1->extdispconninfo.guid[i]; | |
| 1775 | + } | |
| 1776 | + | |
| 1777 | + for (i = 0; i < MAX_NUMBER_OF_EXT_DISPLAY_PATH; ++i) { | |
| 1778 | + info->ext_disp_conn_info.path[i].device_connector_id = | |
| 1779 | + object_id_from_bios_object_id( | |
| 1780 | + le16_to_cpu(info_v2_1->extdispconninfo.path[i].connectorobjid)); | |
| 1781 | + | |
| 1782 | + info->ext_disp_conn_info.path[i].ext_encoder_obj_id = | |
| 1783 | + object_id_from_bios_object_id( | |
| 1784 | + le16_to_cpu( | |
| 1785 | + info_v2_1->extdispconninfo.path[i].ext_encoder_objid)); | |
| 1786 | + | |
| 1787 | + info->ext_disp_conn_info.path[i].device_tag = | |
| 1788 | + le16_to_cpu( | |
| 1789 | + info_v2_1->extdispconninfo.path[i].device_tag); | |
| 1790 | + info->ext_disp_conn_info.path[i].device_acpi_enum = | |
| 1791 | + le16_to_cpu( | |
| 1792 | + info_v2_1->extdispconninfo.path[i].device_acpi_enum); | |
| 1793 | + info->ext_disp_conn_info.path[i].ext_aux_ddc_lut_index = | |
| 1794 | + info_v2_1->extdispconninfo.path[i].auxddclut_index; | |
| 1795 | + info->ext_disp_conn_info.path[i].ext_hpd_pin_lut_index = | |
| 1796 | + info_v2_1->extdispconninfo.path[i].hpdlut_index; | |
| 1797 | + info->ext_disp_conn_info.path[i].channel_mapping.raw = | |
| 1798 | + info_v2_1->extdispconninfo.path[i].channelmapping; | |
| 1799 | + info->ext_disp_conn_info.path[i].caps = | |
| 1800 | + le16_to_cpu(info_v2_1->extdispconninfo.path[i].caps); | |
| 1801 | + } | |
| 1802 | + | |
| 1803 | + info->ext_disp_conn_info.checksum = | |
| 1804 | + info_v2_1->extdispconninfo.checksum; | |
| 1805 | + info->dp0_ext_hdmi_slv_addr = info_v2_1->dp0_retimer_set.HdmiSlvAddr; | |
| 1806 | + info->dp0_ext_hdmi_reg_num = info_v2_1->dp0_retimer_set.HdmiRegNum; | |
| 1807 | + for (i = 0; i < info->dp0_ext_hdmi_reg_num; i++) { | |
| 1808 | + info->dp0_ext_hdmi_reg_settings[i].i2c_reg_index = | |
| 1809 | + info_v2_1->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegIndex; | |
| 1810 | + info->dp0_ext_hdmi_reg_settings[i].i2c_reg_val = | |
| 1811 | + info_v2_1->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegVal; | |
| 1812 | + } | |
| 1813 | + info->dp0_ext_hdmi_6g_reg_num = info_v2_1->dp0_retimer_set.Hdmi6GRegNum; | |
| 1814 | + for (i = 0; i < info->dp0_ext_hdmi_6g_reg_num; i++) { | |
| 1815 | + info->dp0_ext_hdmi_6g_reg_settings[i].i2c_reg_index = | |
| 1816 | + info_v2_1->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex; | |
| 1817 | + info->dp0_ext_hdmi_6g_reg_settings[i].i2c_reg_val = | |
| 1818 | + info_v2_1->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal; | |
| 1819 | + } | |
| 1820 | + info->dp1_ext_hdmi_slv_addr = info_v2_1->dp1_retimer_set.HdmiSlvAddr; | |
| 1821 | + info->dp1_ext_hdmi_reg_num = info_v2_1->dp1_retimer_set.HdmiRegNum; | |
| 1822 | + for (i = 0; i < info->dp1_ext_hdmi_reg_num; i++) { | |
| 1823 | + info->dp1_ext_hdmi_reg_settings[i].i2c_reg_index = | |
| 1824 | + info_v2_1->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegIndex; | |
| 1825 | + info->dp1_ext_hdmi_reg_settings[i].i2c_reg_val = | |
| 1826 | + info_v2_1->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegVal; | |
| 1827 | + } | |
| 1828 | + info->dp1_ext_hdmi_6g_reg_num = info_v2_1->dp1_retimer_set.Hdmi6GRegNum; | |
| 1829 | + for (i = 0; i < info->dp1_ext_hdmi_6g_reg_num; i++) { | |
| 1830 | + info->dp1_ext_hdmi_6g_reg_settings[i].i2c_reg_index = | |
| 1831 | + info_v2_1->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex; | |
| 1832 | + info->dp1_ext_hdmi_6g_reg_settings[i].i2c_reg_val = | |
| 1833 | + info_v2_1->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal; | |
| 1834 | + } | |
| 1835 | + info->dp2_ext_hdmi_slv_addr = info_v2_1->dp2_retimer_set.HdmiSlvAddr; | |
| 1836 | + info->dp2_ext_hdmi_reg_num = info_v2_1->dp2_retimer_set.HdmiRegNum; | |
| 1837 | + for (i = 0; i < info->dp2_ext_hdmi_reg_num; i++) { | |
| 1838 | + info->dp2_ext_hdmi_reg_settings[i].i2c_reg_index = | |
| 1839 | + info_v2_1->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegIndex; | |
| 1840 | + info->dp2_ext_hdmi_reg_settings[i].i2c_reg_val = | |
| 1841 | + info_v2_1->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegVal; | |
| 1842 | + } | |
| 1843 | + info->dp2_ext_hdmi_6g_reg_num = info_v2_1->dp2_retimer_set.Hdmi6GRegNum; | |
| 1844 | + for (i = 0; i < info->dp2_ext_hdmi_6g_reg_num; i++) { | |
| 1845 | + info->dp2_ext_hdmi_6g_reg_settings[i].i2c_reg_index = | |
| 1846 | + info_v2_1->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex; | |
| 1847 | + info->dp2_ext_hdmi_6g_reg_settings[i].i2c_reg_val = | |
| 1848 | + info_v2_1->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal; | |
| 1849 | + } | |
| 1850 | + info->dp3_ext_hdmi_slv_addr = info_v2_1->dp3_retimer_set.HdmiSlvAddr; | |
| 1851 | + info->dp3_ext_hdmi_reg_num = info_v2_1->dp3_retimer_set.HdmiRegNum; | |
| 1852 | + for (i = 0; i < info->dp3_ext_hdmi_reg_num; i++) { | |
| 1853 | + info->dp3_ext_hdmi_reg_settings[i].i2c_reg_index = | |
| 1854 | + info_v2_1->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegIndex; | |
| 1855 | + info->dp3_ext_hdmi_reg_settings[i].i2c_reg_val = | |
| 1856 | + info_v2_1->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegVal; | |
| 1857 | + } | |
| 1858 | + info->dp3_ext_hdmi_6g_reg_num = info_v2_1->dp3_retimer_set.Hdmi6GRegNum; | |
| 1859 | + for (i = 0; i < info->dp3_ext_hdmi_6g_reg_num; i++) { | |
| 1860 | + info->dp3_ext_hdmi_6g_reg_settings[i].i2c_reg_index = | |
| 1861 | + info_v2_1->dp3_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex; | |
| 1862 | + info->dp3_ext_hdmi_6g_reg_settings[i].i2c_reg_val = | |
| 1863 | + info_v2_1->dp3_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal; | |
| 1864 | + } | |
| 1865 | + | |
| 1866 | + info->edp1_info.edp_backlight_pwm_hz = | |
| 1867 | + le16_to_cpu(info_v2_1->edp1_info.edp_backlight_pwm_hz); | |
| 1868 | + info->edp1_info.edp_ss_percentage = | |
| 1869 | + le16_to_cpu(info_v2_1->edp1_info.edp_ss_percentage); | |
| 1870 | + info->edp1_info.edp_ss_rate_10hz = | |
| 1871 | + le16_to_cpu(info_v2_1->edp1_info.edp_ss_rate_10hz); | |
| 1872 | + info->edp1_info.edp_pwr_on_off_delay = | |
| 1873 | + info_v2_1->edp1_info.edp_pwr_on_off_delay; | |
| 1874 | + info->edp1_info.edp_pwr_on_vary_bl_to_blon = | |
| 1875 | + info_v2_1->edp1_info.edp_pwr_on_vary_bl_to_blon; | |
| 1876 | + info->edp1_info.edp_pwr_down_bloff_to_vary_bloff = | |
| 1877 | + info_v2_1->edp1_info.edp_pwr_down_bloff_to_vary_bloff; | |
| 1878 | + info->edp1_info.edp_panel_bpc = | |
| 1879 | + info_v2_1->edp1_info.edp_panel_bpc; | |
| 1880 | + info->edp1_info.edp_bootup_bl_level = | |
| 1881 | + | |
| 1882 | + info->edp2_info.edp_backlight_pwm_hz = | |
| 1883 | + le16_to_cpu(info_v2_1->edp2_info.edp_backlight_pwm_hz); | |
| 1884 | + info->edp2_info.edp_ss_percentage = | |
| 1885 | + le16_to_cpu(info_v2_1->edp2_info.edp_ss_percentage); | |
| 1886 | + info->edp2_info.edp_ss_rate_10hz = | |
| 1887 | + le16_to_cpu(info_v2_1->edp2_info.edp_ss_rate_10hz); | |
| 1888 | + info->edp2_info.edp_pwr_on_off_delay = | |
| 1889 | + info_v2_1->edp2_info.edp_pwr_on_off_delay; | |
| 1890 | + info->edp2_info.edp_pwr_on_vary_bl_to_blon = | |
| 1891 | + info_v2_1->edp2_info.edp_pwr_on_vary_bl_to_blon; | |
| 1892 | + info->edp2_info.edp_pwr_down_bloff_to_vary_bloff = | |
| 1893 | + info_v2_1->edp2_info.edp_pwr_down_bloff_to_vary_bloff; | |
| 1894 | + info->edp2_info.edp_panel_bpc = | |
| 1895 | + info_v2_1->edp2_info.edp_panel_bpc; | |
| 1896 | + info->edp2_info.edp_bootup_bl_level = | |
| 1897 | + info_v2_1->edp2_info.edp_bootup_bl_level; | |
| 1898 | + | |
| 1899 | + return BP_RESULT_OK; | |
| 1900 | +} | |
| 1746 | 1901 | |
| 1747 | 1902 | /* |
| 1748 | 1903 | * construct_integrated_info |
| @@ -1775,11 +1930,25 @@ static enum bp_result construct_integrated_info( · 26 unmodified lines | ||
| 1775 | 1930 | |
| 1776 | 1931 | get_atom_data_table_revision(header, &revision); |
| 1777 | 1932 | |
| 1778 | − /* Don't need to check major revision as they are all 1 */ | |
| 1779 | − switch (revision.minor) { | |
| 1780 | − case 11: | |
| 1781 | − case 12: | |
| 1782 | − result = get_integrated_info_v11(bp, info); | |
| 1933 | + switch (revision.major) { | |
| 1934 | + case 1: | |
| 1935 | + switch (revision.minor) { | |
| 1936 | + case 11: | |
| 1937 | + case 12: | |
| 1938 | + result = get_integrated_info_v11(bp, info); | |
| 1939 | + break; | |
| 1940 | + default: | |
| 1941 | + return result; | |
| 1942 | + } | |
| 1943 | + break; | |
| 1944 | + case 2: | |
| 1945 | + switch (revision.minor) { | |
| 1946 | + case 1: | |
| 1947 | + result = get_integrated_info_v2_1(bp, info); | |
| 1948 | + break; | |
| 1949 | + default: | |
| 1950 | + return result; | |
| 1951 | + } | |
| 1783 | 1952 | break; |
| 1784 | 1953 | default: |
| 1785 | 1954 | return result; |
| @@ -70,15 +70,12 @@ bool dal_bios_parser_init_cmd_tbl_helper2( · 69 unmodified lines | ||
| 70 | 70 | case DCN_VERSION_1_01: |
| 71 | 71 | case DCN_VERSION_2_0: |
| 72 | 72 | case DCN_VERSION_2_1: |
| 73 | − *h = dal_cmd_tbl_helper_dce112_get_table2(); | |
| 74 | − return true; | |
| 75 | −#endif | |
| 76 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 77 | 73 | case DCN_VERSION_3_0: |
| 74 | + case DCN_VERSION_3_01: | |
| 75 | + case DCN_VERSION_3_02: | |
| 78 | 76 | *h = dal_cmd_tbl_helper_dce112_get_table2(); |
| 79 | 77 | return true; |
| 80 | 78 | #endif |
| 81 | − | |
| 82 | 79 | default: |
| 83 | 80 | /* Unsupported DCE */ |
| 84 | 81 | BREAK_TO_DEBUGGER(); |
| @@ -388,43 +388,3 @@ const struct command_table_helper *dal_cmd_tbl_helper_dce112_get_table2(void) · 387 unmodified lines | ||
| 388 | 388 | { |
| 389 | 389 | return &command_table_helper_funcs; |
| 390 | 390 | } |
| 391 | − | |
| 392 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 393 | −/* function table */ | |
| 394 | −static const struct command_table_helper command_table_helper_funcs_dcn2x = { | |
| 395 | − .controller_id_to_atom = dal_cmd_table_helper_controller_id_to_atom2, | |
| 396 | − .encoder_action_to_atom = encoder_action_to_atom, | |
| 397 | − .engine_bp_to_atom = engine_bp_to_atom, | |
| 398 | − .clock_source_id_to_atom = clock_source_id_to_atom, | |
| 399 | − .clock_source_id_to_atom_phy_clk_src_id = | |
| 400 | − clock_source_id_to_atom_phy_clk_src_id, | |
| 401 | − .signal_type_to_atom_dig_mode = signal_type_to_atom_dig_mode, | |
| 402 | − .hpd_sel_to_atom = hpd_sel_to_atom, | |
| 403 | − .dig_encoder_sel_to_atom = dig_encoder_sel_to_atom, | |
| 404 | − .phy_id_to_atom = phy_id_to_atom, | |
| 405 | − .disp_power_gating_action_to_atom = disp_power_gating_action_to_atom, | |
| 406 | − .clock_source_id_to_ref_clk_src = NULL, | |
| 407 | − .transmitter_bp_to_atom = NULL, | |
| 408 | − .encoder_id_to_atom = dal_cmd_table_helper_encoder_id_to_atom2, | |
| 409 | − .encoder_mode_bp_to_atom = | |
| 410 | − dal_cmd_table_helper_encoder_mode_bp_to_atom2, | |
| 411 | − .dc_clock_type_to_atom = dc_clock_type_to_atom, | |
| 412 | − .transmitter_color_depth_to_atom = transmitter_color_depth_to_atom, | |
| 413 | − | |
| 414 | −}; | |
| 415 | − | |
| 416 | −/* | |
| 417 | − * dal_cmd_tbl_helper_dce110_get_table | |
| 418 | − * | |
| 419 | − * @brief | |
| 420 | − * Initialize command table helper functions | |
| 421 | − * | |
| 422 | − * @param | |
| 423 | − * const struct command_table_helper **h - [out] struct of functions | |
| 424 | − * | |
| 425 | − */ | |
| 426 | −const struct command_table_helper *dal_cmd_tbl_helper_dcn2_get_table2(void) | |
| 427 | −{ | |
| 428 | − return &command_table_helper_funcs_dcn2x; | |
| 429 | −} | |
| 430 | −#endif | |
| @@ -30,8 +30,5 @@ struct command_table_helper; · 29 unmodified lines | ||
| 30 | 30 | |
| 31 | 31 | /* Initialize command table helper functions */ |
| 32 | 32 | const struct command_table_helper *dal_cmd_tbl_helper_dce112_get_table2(void); |
| 33 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 34 | −const struct command_table_helper *dal_cmd_tbl_helper_dcn2_get_table2(void); | |
| 35 | −#endif | |
| 36 | 33 | |
| 37 | 34 | #endif /* __DAL_COMMAND_TABLE_HELPER_DCE110_H__ */ |
| @@ -1364,13 +1364,10 @@ static void calculate_bandwidth( · 1363 unmodified lines | ||
| 1364 | 1364 | /*if stutter and dram clock state change are gated before cursor then the cursor latency hiding does not limit stutter or dram clock state change*/ |
| 1365 | 1365 | for (i = 0; i <= maximum_number_of_surfaces - 1; i++) { |
| 1366 | 1366 | if (data->enable[i]) { |
| 1367 | − if (dceip->graphics_lb_nodownscaling_multi_line_prefetching == 1) { | |
| 1368 | − data->maximum_latency_hiding[i] = bw_add(data->minimum_latency_hiding[i], bw_mul(bw_frc_to_fixed(5, 10), data->total_dmifmc_urgent_latency)); | |
| 1369 | − } | |
| 1370 | − else { | |
| 1371 | − /*maximum_latency_hiding(i) = minimum_latency_hiding(i) + 1 / vsr(i) * h_total(i) / pixel_rate(i) + 0.5 * total_dmifmc_urgent_latency*/ | |
| 1372 | − data->maximum_latency_hiding[i] = bw_add(data->minimum_latency_hiding[i], bw_mul(bw_frc_to_fixed(5, 10), data->total_dmifmc_urgent_latency)); | |
| 1373 | − } | |
| 1367 | + /*maximum_latency_hiding(i) = minimum_latency_hiding(i) + 1 / vsr(i) **/ | |
| 1368 | + /* h_total(i) / pixel_rate(i) + 0.5 * total_dmifmc_urgent_latency*/ | |
| 1369 | + data->maximum_latency_hiding[i] = bw_add(data->minimum_latency_hiding[i], | |
| 1370 | + bw_mul(bw_frc_to_fixed(5, 10), data->total_dmifmc_urgent_latency)); | |
| 1374 | 1371 | data->maximum_latency_hiding_with_cursor[i] = bw_min2(data->maximum_latency_hiding[i], data->cursor_latency_hiding[i]); |
| 1375 | 1372 | } |
| 1376 | 1373 | } |
| @@ -1980,7 +1977,7 @@ static void calculate_bandwidth( · 603 unmodified lines | ||
| 1980 | 1977 | else { |
| 1981 | 1978 | data->latency_for_non_mcifwr_clients = bw_int_to_fixed(0); |
| 1982 | 1979 | } |
| 1983 | − /*dmif mc urgent latency suppported in high sclk and yclk*/ | |
| 1980 | + /*dmif mc urgent latency supported in high sclk and yclk*/ | |
| 1984 | 1981 | data->dmifmc_urgent_latency_supported_in_high_sclk_and_yclk = bw_div((bw_sub(data->min_read_buffer_size_in_time, data->dmif_burst_time[high][s_high])), data->total_dmifmc_urgent_trips); |
| 1985 | 1982 | /*dram speed/p-state change margin*/ |
| 1986 | 1983 | /*in the multi-display case the nb p-state change watermark cannot exceed the average lb size plus the dmif size or the cursor dcp buffer size*/ |
| @@ -381,13 +381,11 @@ static void pipe_ctx_to_e2e_pipe_params ( · 380 unmodified lines | ||
| 381 | 381 | input->src.viewport_width_c = input->src.viewport_width; |
| 382 | 382 | input->src.viewport_height_c = input->src.viewport_height; |
| 383 | 383 | break; |
| 384 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 385 | 384 | case SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA: |
| 386 | 385 | input->src.source_format = dm_rgbe_alpha; |
| 387 | 386 | input->src.viewport_width_c = input->src.viewport_width; |
| 388 | 387 | input->src.viewport_height_c = input->src.viewport_height; |
| 389 | 388 | break; |
| 390 | −#endif | |
| 391 | 389 | default: |
| 392 | 390 | input->src.source_format = dm_444_32; |
| 393 | 391 | input->src.viewport_width_c = input->src.viewport_width; |
| @@ -736,10 +734,11 @@ static void hack_bounding_box(struct dcn_bw_internal_vars *v, · 342 unmodified lines | ||
| 736 | 734 | hack_force_pipe_split(v, context->streams[0]->timing.pix_clk_100hz); |
| 737 | 735 | } |
| 738 | 736 | |
| 739 | −unsigned int get_highest_allowed_voltage_level(uint32_t hw_internal_rev, uint32_t pci_revision_id) | |
| 737 | +unsigned int get_highest_allowed_voltage_level(uint32_t chip_family, uint32_t hw_internal_rev, uint32_t pci_revision_id) | |
| 740 | 738 | { |
| 741 | 739 | /* for low power RV2 variants, the highest voltage level we want is 0 */ |
| 742 | − if (ASICREV_IS_RAVEN2(hw_internal_rev)) | |
| 740 | + if ((chip_family == FAMILY_RV) && | |
| 741 | + ASICREV_IS_RAVEN2(hw_internal_rev)) | |
| 743 | 742 | switch (pci_revision_id) { |
| 744 | 743 | case PRID_DALI_DE: |
| 745 | 744 | case PRID_DALI_DF: |
| @@ -1324,6 +1323,7 @@ bool dcn_validate_bandwidth( · 578 unmodified lines | ||
| 1324 | 1323 | BW_VAL_TRACE_FINISH(); |
| 1325 | 1324 | |
| 1326 | 1325 | if (bw_limit_pass && v->voltage_level <= get_highest_allowed_voltage_level( |
| 1326 | + dc->ctx->asic_id.chip_family, | |
| 1327 | 1327 | dc->ctx->asic_id.hw_internal_rev, |
| 1328 | 1328 | dc->ctx->asic_id.pci_revision_id)) |
| 1329 | 1329 | return true; |
| @@ -114,14 +114,46 @@ endif · 113 unmodified lines | ||
| 114 | 114 | AMD_DAL_CLK_MGR_DCN21 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dcn21/,$(CLK_MGR_DCN21)) |
| 115 | 115 | |
| 116 | 116 | AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN21) |
| 117 | −endif | |
| 118 | −ifdef CONFIG_DRM_AMD_DC_DCN3_0 | |
| 119 | 117 | ############################################################################### |
| 120 | 118 | # DCN30 |
| 121 | 119 | ############################################################################### |
| 122 | 120 | CLK_MGR_DCN30 = dcn30_clk_mgr.o dcn30_clk_mgr_smu_msg.o |
| 123 | 121 | |
| 122 | +# prevent build errors regarding soft-float vs hard-float FP ABI tags | |
| 123 | +# this code is currently unused on ppc64, as it applies to VanGogh APUs only | |
| 124 | +ifdef CONFIG_PPC64 | |
| 125 | +CFLAGS_$(AMDDALPATH)/dc/clk_mgr/dcn30/dcn30_clk_mgr.o := $(call cc-option,-mno-gnu-attribute) | |
| 126 | +endif | |
| 127 | + | |
| 128 | +# prevent build errors: | |
| 129 | +# ...: '-mgeneral-regs-only' is incompatible with the use of floating-point types | |
| 130 | +# this file is unused on arm64, just like on ppc64 | |
| 131 | +ifdef CONFIG_ARM64 | |
| 132 | +CFLAGS_REMOVE_$(AMDDALPATH)/dc/clk_mgr/dcn30/dcn30_clk_mgr.o := -mgeneral-regs-only | |
| 133 | +endif | |
| 134 | + | |
| 124 | 135 | AMD_DAL_CLK_MGR_DCN30 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dcn30/,$(CLK_MGR_DCN30)) |
| 125 | 136 | |
| 126 | 137 | AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN30) |
| 138 | +############################################################################### | |
| 139 | +# DCN301 | |
| 140 | +############################################################################### | |
| 141 | +CLK_MGR_DCN301 = vg_clk_mgr.o dcn301_smu.o | |
| 142 | + | |
| 143 | +# prevent build errors regarding soft-float vs hard-float FP ABI tags | |
| 144 | +# this code is currently unused on ppc64, as it applies to VanGogh APUs only | |
| 145 | +ifdef CONFIG_PPC64 | |
| 146 | +CFLAGS_$(AMDDALPATH)/dc/clk_mgr/dcn301/vg_clk_mgr.o := $(call cc-option,-mno-gnu-attribute) | |
| 147 | +endif | |
| 148 | + | |
| 149 | +# prevent build errors: | |
| 150 | +# ...: '-mgeneral-regs-only' is incompatible with the use of floating-point types | |
| 151 | +# this file is unused on arm64, just like on ppc64 | |
| 152 | +ifdef CONFIG_ARM64 | |
| 153 | +CFLAGS_REMOVE_$(AMDDALPATH)/dc/clk_mgr/dcn301/vg_clk_mgr.o := -mgeneral-regs-only | |
| 154 | +endif | |
| 155 | + | |
| 156 | +AMD_DAL_CLK_MGR_DCN301 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dcn301/,$(CLK_MGR_DCN301)) | |
| 157 | + | |
| 158 | +AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN301) | |
| 127 | 159 | endif |
| @@ -39,9 +39,8 @@ · 38 unmodified lines | ||
| 39 | 39 | #include "dcn10/rv2_clk_mgr.h" |
| 40 | 40 | #include "dcn20/dcn20_clk_mgr.h" |
| 41 | 41 | #include "dcn21/rn_clk_mgr.h" |
| 42 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 43 | 42 | #include "dcn30/dcn30_clk_mgr.h" |
| 44 | −#endif | |
| 43 | +#include "dcn301/vg_clk_mgr.h" | |
| 45 | 44 | |
| 46 | 45 | |
| 47 | 46 | int clk_mgr_helper_get_active_display_cnt( |
| @@ -166,6 +165,11 @@ struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *p · 118 unmodified lines | ||
| 166 | 165 | rn_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); |
| 167 | 166 | break; |
| 168 | 167 | } |
| 168 | + | |
| 169 | + if (ASICREV_IS_GREEN_SARDINE(asic_id.hw_internal_rev)) { | |
| 170 | + rn_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); | |
| 171 | + break; | |
| 172 | + } | |
| 169 | 173 | if (ASICREV_IS_RAVEN2(asic_id.hw_internal_rev)) { |
| 170 | 174 | rv2_clk_mgr_construct(ctx, clk_mgr, pp_smu); |
| 171 | 175 | break; |
| @@ -178,16 +182,22 @@ struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *p · 6 unmodified lines | ||
| 178 | 182 | break; |
| 179 | 183 | |
| 180 | 184 | case FAMILY_NV: |
| 181 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 182 | 185 | if (ASICREV_IS_SIENNA_CICHLID_P(asic_id.hw_internal_rev)) { |
| 183 | 186 | dcn3_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); |
| 184 | 187 | break; |
| 185 | 188 | } |
| 186 | −#endif | |
| 189 | + if (ASICREV_IS_DIMGREY_CAVEFISH_P(asic_id.hw_internal_rev)) { | |
| 190 | + dcn3_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); | |
| 191 | + break; | |
| 192 | + } | |
| 187 | 193 | dcn20_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); |
| 188 | 194 | break; |
| 189 | −#endif /* Family RV and NV*/ | |
| 190 | 195 | |
| 196 | + case FAMILY_VGH: | |
| 197 | + if (ASICREV_IS_VANGOGH(asic_id.hw_internal_rev)) | |
| 198 | + vg_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); | |
| 199 | + break; | |
| 200 | +#endif | |
| 191 | 201 | default: |
| 192 | 202 | ASSERT(0); /* Unknown Asic */ |
| 193 | 203 | break; |
| @@ -199,14 +209,22 @@ struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *p · 5 unmodified lines | ||
| 199 | 209 | void dc_destroy_clk_mgr(struct clk_mgr *clk_mgr_base) |
| 200 | 210 | { |
| 201 | 211 | struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); |
| 202 | −#ifdef CONFIG_DRM_AMD_DC_DCN3_0 | |
| 203 | 212 | |
| 213 | +#ifdef CONFIG_DRM_AMD_DC_DCN | |
| 204 | 214 | switch (clk_mgr_base->ctx->asic_id.chip_family) { |
| 205 | 215 | case FAMILY_NV: |
| 206 | 216 | if (ASICREV_IS_SIENNA_CICHLID_P(clk_mgr_base->ctx->asic_id.hw_internal_rev)) { |
| 207 | 217 | dcn3_clk_mgr_destroy(clk_mgr); |
| 208 | − break; | |
| 209 | 218 | } |
| 219 | + break; | |
| 220 | + | |
| 221 | + case FAMILY_VGH: | |
| 222 | + if (ASICREV_IS_VANGOGH(clk_mgr_base->ctx->asic_id.hw_internal_rev)) | |
| 223 | + vg_clk_mgr_destroy(clk_mgr); | |
| 224 | + break; | |
| 225 | + | |
| 226 | + default: | |
| 227 | + break; | |
| 210 | 228 | } |
| 211 | 229 | #endif |
| 212 | 230 | |
| @@ -195,7 +195,8 @@ void dce11_pplib_apply_display_requirements( · 194 unmodified lines | ||
| 195 | 195 | * , then change minimum memory clock based on real-time bandwidth |
| 196 | 196 | * limitation. |
| 197 | 197 | */ |
| 198 | − if (ASICREV_IS_VEGA20_P(dc->ctx->asic_id.hw_internal_rev) && (context->stream_count >= 2)) { | |
| 198 | + if ((dc->ctx->asic_id.chip_family == FAMILY_AI) && | |
| 199 | + ASICREV_IS_VEGA20_P(dc->ctx->asic_id.hw_internal_rev) && (context->stream_count >= 2)) { | |
| 199 | 200 | pp_display_cfg->min_memory_clock_khz = max(pp_display_cfg->min_memory_clock_khz, |
| 200 | 201 | (uint32_t) div64_s64( |
| 201 | 202 | div64_s64(dc->bw_vbios->high_yclk.value, |
| @@ -100,7 +100,9 @@ int dce112_set_clock(struct clk_mgr *clk_mgr_base, int requested_clk_khz) · 99 unmodified lines | ||
| 100 | 100 | /*VBIOS will determine DPREFCLK frequency, so we don't set it*/ |
| 101 | 101 | dce_clk_params.target_clock_frequency = 0; |
| 102 | 102 | dce_clk_params.clock_type = DCECLOCK_TYPE_DPREFCLK; |
| 103 | − if (!ASICREV_IS_VEGA20_P(clk_mgr_base->ctx->asic_id.hw_internal_rev)) | |
| 103 | + | |
| 104 | + if (!((clk_mgr_base->ctx->asic_id.chip_family == FAMILY_AI) && | |
| 105 | + ASICREV_IS_VEGA20_P(clk_mgr_base->ctx->asic_id.hw_internal_rev))) | |
| 104 | 106 | dce_clk_params.flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK = |
| 105 | 107 | (dce_clk_params.pll_id == |
| 106 | 108 | CLOCK_SOURCE_COMBO_DISPLAY_PLL0); |
| @@ -176,7 +178,8 @@ int dce112_set_dprefclk(struct clk_mgr_internal *clk_mgr) · 69 unmodified lines | ||
| 176 | 178 | dce_clk_params.target_clock_frequency = 0; |
| 177 | 179 | dce_clk_params.pll_id = CLOCK_SOURCE_ID_DFS; |
| 178 | 180 | dce_clk_params.clock_type = DCECLOCK_TYPE_DPREFCLK; |
| 179 | − if (!ASICREV_IS_VEGA20_P(clk_mgr->base.ctx->asic_id.hw_internal_rev)) | |
| 181 | + if (!((clk_mgr->base.ctx->asic_id.chip_family == FAMILY_AI) && | |
| 182 | + ASICREV_IS_VEGA20_P(clk_mgr->base.ctx->asic_id.hw_internal_rev))) | |
| 180 | 183 | dce_clk_params.flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK = |
| 181 | 184 | (dce_clk_params.pll_id == |
| 182 | 185 | CLOCK_SOURCE_COMBO_DISPLAY_PLL0); |
| @@ -187,6 +187,17 @@ static void ramp_up_dispclk_with_dpp( · 186 unmodified lines | ||
| 187 | 187 | clk_mgr->base.clks.max_supported_dppclk_khz = new_clocks->max_supported_dppclk_khz; |
| 188 | 188 | } |
| 189 | 189 | |
| 190 | +static bool is_mpo_enabled(struct dc_state *context) | |
| 191 | +{ | |
| 192 | + int i; | |
| 193 | + | |
| 194 | + for (i = 0; i < context->stream_count; i++) { | |
| 195 | + if (context->stream_status[i].plane_count > 1) | |
| 196 | + return true; | |
| 197 | + } | |
| 198 | + return false; | |
| 199 | +} | |
| 200 | + | |
| 190 | 201 | static void rv1_update_clocks(struct clk_mgr *clk_mgr_base, |
| 191 | 202 | struct dc_state *context, |
| 192 | 203 | bool safe_to_lower) |
| @@ -284,9 +295,22 @@ static void rv1_update_clocks(struct clk_mgr *clk_mgr_base, · 91 unmodified lines | ||
| 284 | 295 | if (pp_smu->set_hard_min_fclk_by_freq && |
| 285 | 296 | pp_smu->set_hard_min_dcfclk_by_freq && |
| 286 | 297 | pp_smu->set_min_deep_sleep_dcfclk) { |
| 287 | − pp_smu->set_hard_min_fclk_by_freq(&pp_smu->pp_smu, new_clocks->fclk_khz / 1000); | |
| 288 | − pp_smu->set_hard_min_dcfclk_by_freq(&pp_smu->pp_smu, new_clocks->dcfclk_khz / 1000); | |
| 289 | − pp_smu->set_min_deep_sleep_dcfclk(&pp_smu->pp_smu, (new_clocks->dcfclk_deep_sleep_khz + 999) / 1000); | |
| 298 | + // Only increase clocks when display is active and MPO is enabled | |
| 299 | + if (display_count && is_mpo_enabled(context)) { | |
| 300 | + pp_smu->set_hard_min_fclk_by_freq(&pp_smu->pp_smu, | |
| 301 | + ((new_clocks->fclk_khz / 1000) * 101) / 100); | |
| 302 | + pp_smu->set_hard_min_dcfclk_by_freq(&pp_smu->pp_smu, | |
| 303 | + ((new_clocks->dcfclk_khz / 1000) * 101) / 100); | |
| 304 | + pp_smu->set_min_deep_sleep_dcfclk(&pp_smu->pp_smu, | |
| 305 | + (new_clocks->dcfclk_deep_sleep_khz + 999) / 1000); | |
| 306 | + } else { | |
| 307 | + pp_smu->set_hard_min_fclk_by_freq(&pp_smu->pp_smu, | |
| 308 | + new_clocks->fclk_khz / 1000); | |
| 309 | + pp_smu->set_hard_min_dcfclk_by_freq(&pp_smu->pp_smu, | |
| 310 | + new_clocks->dcfclk_khz / 1000); | |
| 311 | + pp_smu->set_min_deep_sleep_dcfclk(&pp_smu->pp_smu, | |
| 312 | + (new_clocks->dcfclk_deep_sleep_khz + 999) / 1000); | |
| 313 | + } | |
| 290 | 314 | } |
| 291 | 315 | } |
| 292 | 316 | } |
| @@ -124,7 +124,7 @@ void rn_update_clocks(struct clk_mgr *clk_mgr_base, · 123 unmodified lines | ||
| 124 | 124 | * if it is safe to lower, but we are already in the lower state, we don't have to do anything |
| 125 | 125 | * also if safe to lower is false, we just go in the higher state |
| 126 | 126 | */ |
| 127 | − if (safe_to_lower) { | |
| 127 | + if (safe_to_lower && !dc->debug.disable_48mhz_pwrdwn) { | |
| 128 | 128 | /* check that we're not already in lower */ |
| 129 | 129 | if (clk_mgr_base->clks.pwr_state != DCN_PWR_STATE_LOW_POWER) { |
| 130 | 130 | |
| @@ -53,6 +53,7 @@ · 52 unmodified lines | ||
| 53 | 53 | #define DALSMC_MSG_GetDcModeMaxDpmFreq 0xC |
| 54 | 54 | #define DALSMC_MSG_SetMinDeepSleepDcefclk 0xD |
| 55 | 55 | #define DALSMC_MSG_NumOfDisplays 0xE |
| 56 | +#define DALSMC_MSG_SetDisplayRefreshFromMall 0xF | |
| 56 | 57 | #define DALSMC_MSG_SetExternalClientDfCstateAllow 0x10 |
| 57 | 58 | #define DALSMC_MSG_BacoAudioD3PME 0x11 |
| 58 | 59 | #define DALSMC_Message_Count 0x12 |
| @@ -104,7 +104,7 @@ static void dcn3_init_single_clock(struct clk_mgr_internal *clk_mgr, PPCLK_e clk · 103 unmodified lines | ||
| 104 | 104 | } |
| 105 | 105 | } |
| 106 | 106 | |
| 107 | −static void dcn3_build_wm_range_table(struct clk_mgr_internal *clk_mgr) | |
| 107 | +static noinline void dcn3_build_wm_range_table(struct clk_mgr_internal *clk_mgr) | |
| 108 | 108 | { |
| 109 | 109 | /* defaults */ |
| 110 | 110 | double pstate_latency_us = clk_mgr->base.ctx->dc->dml.soc.dram_clock_change_latency_us; |
| @@ -145,6 +145,16 @@ static void dcn3_build_wm_range_table(struct clk_mgr_internal *clk_mgr) · 34 unmodified lines | ||
| 145 | 145 | clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.min_uclk = min_uclk_mhz; |
| 146 | 146 | clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.max_uclk = 0xFFFF; |
| 147 | 147 | |
| 148 | + /* Set D - MALL - SR enter and exit times adjusted for MALL */ | |
| 149 | +// clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].valid = true; | |
| 150 | +// clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].dml_input.pstate_latency_us = pstate_latency_us; | |
| 151 | +// clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].dml_input.sr_exit_time_us = 2; | |
| 152 | +// clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].dml_input.sr_enter_plus_exit_time_us = 4; | |
| 153 | +// clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.wm_type = WATERMARKS_MALL; | |
| 154 | +// clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.min_dcfclk = 0; | |
| 155 | +// clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.max_dcfclk = 0xFFFF; | |
| 156 | +// clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.min_uclk = min_uclk_mhz; | |
| 157 | +// clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.max_uclk = 0xFFFF; | |
| 148 | 158 | } |
| 149 | 159 | |
| 150 | 160 | void dcn3_init_clocks(struct clk_mgr *clk_mgr_base) |
| @@ -201,7 +211,9 @@ void dcn3_init_clocks(struct clk_mgr *clk_mgr_base) · 50 unmodified lines | ||
| 201 | 211 | clk_mgr_base->funcs->get_memclk_states_from_smu(clk_mgr_base); |
| 202 | 212 | |
| 203 | 213 | /* WM range table */ |
| 214 | + DC_FP_START(); | |
| 204 | 215 | dcn3_build_wm_range_table(clk_mgr); |
| 216 | + DC_FP_END(); | |
| 205 | 217 | } |
| 206 | 218 | |
| 207 | 219 | static int dcn30_get_vco_frequency_from_reg(struct clk_mgr_internal *clk_mgr) |
| @@ -297,6 +297,15 @@ void dcn30_smu_set_num_of_displays(struct clk_mgr_internal *clk_mgr, uint32_t nu · 296 unmodified lines | ||
| 297 | 297 | DALSMC_MSG_NumOfDisplays, num_displays, NULL); |
| 298 | 298 | } |
| 299 | 299 | |
| 300 | +void dcn30_smu_set_display_refresh_from_mall(struct clk_mgr_internal *clk_mgr, bool enable, uint8_t cache_timer_delay, uint8_t cache_timer_scale) | |
| 301 | +{ | |
| 302 | + /* bits 8:7 for cache timer scale, bits 6:1 for cache timer delay, bit 0 = 1 for enable, = 0 for disable */ | |
| 303 | + uint32_t param = (cache_timer_scale << 7) | (cache_timer_delay << 1) | (enable ? 1 : 0); | |
| 304 | + | |
| 305 | + dcn30_smu_send_msg_with_param(clk_mgr, | |
| 306 | + DALSMC_MSG_SetDisplayRefreshFromMall, param, NULL); | |
| 307 | +} | |
| 308 | + | |
| 300 | 309 | void dcn30_smu_set_external_client_df_cstate_allow(struct clk_mgr_internal *clk_mgr, bool enable) |
| 301 | 310 | { |
| 302 | 311 | smu_print("SMU Set external client df cstate allow: enable = %d\n", enable); |
| @@ -70,6 +70,7 @@ typedef enum { · 69 unmodified lines | ||
| 70 | 70 | typedef enum { |
| 71 | 71 | WATERMARKS_CLOCK_RANGE = 0, |
| 72 | 72 | WATERMARKS_DUMMY_PSTATE, |
| 73 | + WATERMARKS_MALL, | |
| 73 | 74 | WATERMARKS_COUNT, |
| 74 | 75 | } WATERMARKS_FLAGS_e; |
| 75 | 76 | |
| @@ -102,6 +103,7 @@ unsigned int dcn30_smu_get_dpm_freq_by_index(struct clk_mgr_internal *clk_mgr, P · 26 unmodified lines | ||
| 102 | 103 | unsigned int dcn30_smu_get_dc_mode_max_dpm_freq(struct clk_mgr_internal *clk_mgr, PPCLK_e clk); |
| 103 | 104 | void dcn30_smu_set_min_deep_sleep_dcef_clk(struct clk_mgr_internal *clk_mgr, uint32_t freq_mhz); |
| 104 | 105 | void dcn30_smu_set_num_of_displays(struct clk_mgr_internal *clk_mgr, uint32_t num_displays); |
| 106 | +void dcn30_smu_set_display_refresh_from_mall(struct clk_mgr_internal *clk_mgr, bool enable, uint8_t cache_timer_delay, uint8_t cache_timer_scale); | |
| 105 | 107 | void dcn30_smu_set_external_client_df_cstate_allow(struct clk_mgr_internal *clk_mgr, bool enable); |
| 106 | 108 | void dcn30_smu_set_pme_workaround(struct clk_mgr_internal *clk_mgr); |
| 107 | 109 | |
| @@ -0,0 +1,241 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2020 Advanced Micro Devices, Inc. | |
| 3 | + * | |
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a | |
| 5 | + * copy of this software and associated documentation files (the "Software"), | |
| 6 | + * to deal in the Software without restriction, including without limitation | |
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the | |
| 9 | + * Software is furnished to do so, subject to the following conditions: | |
| 10 | + * | |
| 11 | + * The above copyright notice and this permission notice shall be included in | |
| 12 | + * all copies or substantial portions of the Software. | |
| 13 | + * | |
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 17 | + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 18 | + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 19 | + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 20 | + * OTHER DEALINGS IN THE SOFTWARE. | |
| 21 | + * | |
| 22 | + * Authors: AMD | |
| 23 | + * | |
| 24 | + */ | |
| 25 | + | |
| 26 | +#include "core_types.h" | |
| 27 | +#include "clk_mgr_internal.h" | |
| 28 | +#include "reg_helper.h" | |
| 29 | +#include <linux/delay.h> | |
| 30 | + | |
| 31 | +#include "dcn301_smu.h" | |
| 32 | + | |
| 33 | +#include "vangogh_ip_offset.h" | |
| 34 | + | |
| 35 | +#include "mp/mp_11_5_0_offset.h" | |
| 36 | +#include "mp/mp_11_5_0_sh_mask.h" | |
| 37 | + | |
| 38 | +#define REG(reg_name) \ | |
| 39 | + (MP0_BASE.instance[0].segment[mm ## reg_name ## _BASE_IDX] + mm ## reg_name) | |
| 40 | + | |
| 41 | +#define FN(reg_name, field) \ | |
| 42 | + FD(reg_name##__##field) | |
| 43 | + | |
| 44 | +#define VBIOSSMC_MSG_GetSmuVersion 0x2 | |
| 45 | +#define VBIOSSMC_MSG_SetDispclkFreq 0x4 | |
| 46 | +#define VBIOSSMC_MSG_SetDprefclkFreq 0x5 | |
| 47 | +#define VBIOSSMC_MSG_SetDppclkFreq 0x6 | |
| 48 | +#define VBIOSSMC_MSG_SetHardMinDcfclkByFreq 0x7 | |
| 49 | +#define VBIOSSMC_MSG_SetMinDeepSleepDcfclk 0x8 | |
| 50 | +//#define VBIOSSMC_MSG_SetPhyclkVoltageByFreq 0xA | |
| 51 | +#define VBIOSSMC_MSG_GetFclkFrequency 0xA | |
| 52 | +//#define VBIOSSMC_MSG_SetDisplayCount 0xC | |
| 53 | +//#define VBIOSSMC_MSG_EnableTmdp48MHzRefclkPwrDown 0xD | |
| 54 | +#define VBIOSSMC_MSG_UpdatePmeRestore 0xD | |
| 55 | +#define VBIOSSMC_MSG_SetVbiosDramAddrHigh 0xE //Used for WM table txfr | |
| 56 | +#define VBIOSSMC_MSG_SetVbiosDramAddrLow 0xF | |
| 57 | +#define VBIOSSMC_MSG_TransferTableSmu2Dram 0x10 | |
| 58 | +#define VBIOSSMC_MSG_TransferTableDram2Smu 0x11 | |
| 59 | +#define VBIOSSMC_MSG_SetDisplayIdleOptimizations 0x12 | |
| 60 | + | |
| 61 | +#define VBIOSSMC_Status_BUSY 0x0 | |
| 62 | +#define VBIOSSMC_Result_OK 0x1 | |
| 63 | +#define VBIOSSMC_Result_Failed 0xFF | |
| 64 | +#define VBIOSSMC_Result_UnknownCmd 0xFE | |
| 65 | +#define VBIOSSMC_Result_CmdRejectedPrereq 0xFD | |
| 66 | +#define VBIOSSMC_Result_CmdRejectedBusy 0xFC | |
| 67 | + | |
| 68 | +/* | |
| 69 | + * Function to be used instead of REG_WAIT macro because the wait ends when | |
| 70 | + * the register is NOT EQUAL to zero, and because the translation in msg_if.h | |
| 71 | + * won't work with REG_WAIT. | |
| 72 | + */ | |
| 73 | +static uint32_t dcn301_smu_wait_for_response(struct clk_mgr_internal *clk_mgr, unsigned int delay_us, unsigned int max_retries) | |
| 74 | +{ | |
| 75 | + uint32_t res_val = VBIOSSMC_Status_BUSY; | |
| 76 | + | |
| 77 | + do { | |
| 78 | + res_val = REG_READ(MP1_SMN_C2PMSG_91); | |
| 79 | + if (res_val != VBIOSSMC_Status_BUSY) | |
| 80 | + break; | |
| 81 | + | |
| 82 | + if (delay_us >= 1000) | |
| 83 | + msleep(delay_us/1000); | |
| 84 | + else if (delay_us > 0) | |
| 85 | + udelay(delay_us); | |
| 86 | + } while (max_retries--); | |
| 87 | + | |
| 88 | + return res_val; | |
| 89 | +} | |
| 90 | + | |
| 91 | +int dcn301_smu_send_msg_with_param( | |
| 92 | + struct clk_mgr_internal *clk_mgr, | |
| 93 | + unsigned int msg_id, unsigned int param) | |
| 94 | +{ | |
| 95 | + uint32_t result; | |
| 96 | + | |
| 97 | + /* First clear response register */ | |
| 98 | + REG_WRITE(MP1_SMN_C2PMSG_91, VBIOSSMC_Status_BUSY); | |
| 99 | + | |
| 100 | + /* Set the parameter register for the SMU message, unit is Mhz */ | |
| 101 | + REG_WRITE(MP1_SMN_C2PMSG_83, param); | |
| 102 | + | |
| 103 | + /* Trigger the message transaction by writing the message ID */ | |
| 104 | + REG_WRITE(MP1_SMN_C2PMSG_67, msg_id); | |
| 105 | + | |
| 106 | + result = dcn301_smu_wait_for_response(clk_mgr, 10, 1000); | |
| 107 | + | |
| 108 | + ASSERT(result == VBIOSSMC_Result_OK); | |
| 109 | + | |
| 110 | + /* Actual dispclk set is returned in the parameter register */ | |
| 111 | + return REG_READ(MP1_SMN_C2PMSG_83); | |
| 112 | +} | |
| 113 | + | |
| 114 | +int dcn301_smu_get_smu_version(struct clk_mgr_internal *clk_mgr) | |
| 115 | +{ | |
| 116 | + return dcn301_smu_send_msg_with_param( | |
| 117 | + clk_mgr, | |
| 118 | + VBIOSSMC_MSG_GetSmuVersion, | |
| 119 | + 0); | |
| 120 | +} | |
| 121 | + | |
| 122 | + | |
| 123 | +int dcn301_smu_set_dispclk(struct clk_mgr_internal *clk_mgr, int requested_dispclk_khz) | |
| 124 | +{ | |
| 125 | + int actual_dispclk_set_mhz = -1; | |
| 126 | + | |
| 127 | + /* Unit of SMU msg parameter is Mhz */ | |
| 128 | + actual_dispclk_set_mhz = dcn301_smu_send_msg_with_param( | |
| 129 | + clk_mgr, | |
| 130 | + VBIOSSMC_MSG_SetDispclkFreq, | |
| 131 | + requested_dispclk_khz / 1000); | |
| 132 | + | |
| 133 | + return actual_dispclk_set_mhz * 1000; | |
| 134 | +} | |
| 135 | + | |
| 136 | +int dcn301_smu_set_dprefclk(struct clk_mgr_internal *clk_mgr) | |
| 137 | +{ | |
| 138 | + int actual_dprefclk_set_mhz = -1; | |
| 139 | + | |
| 140 | + actual_dprefclk_set_mhz = dcn301_smu_send_msg_with_param( | |
| 141 | + clk_mgr, | |
| 142 | + VBIOSSMC_MSG_SetDprefclkFreq, | |
| 143 | + clk_mgr->base.dprefclk_khz / 1000); | |
| 144 | + | |
| 145 | + /* TODO: add code for programing DP DTO, currently this is down by command table */ | |
| 146 | + | |
| 147 | + return actual_dprefclk_set_mhz * 1000; | |
| 148 | +} | |
| 149 | + | |
| 150 | +int dcn301_smu_set_hard_min_dcfclk(struct clk_mgr_internal *clk_mgr, int requested_dcfclk_khz) | |
| 151 | +{ | |
| 152 | + int actual_dcfclk_set_mhz = -1; | |
| 153 | + | |
| 154 | + actual_dcfclk_set_mhz = dcn301_smu_send_msg_with_param( | |
| 155 | + clk_mgr, | |
| 156 | + VBIOSSMC_MSG_SetHardMinDcfclkByFreq, | |
| 157 | + requested_dcfclk_khz / 1000); | |
| 158 | + | |
| 159 | + return actual_dcfclk_set_mhz * 1000; | |
| 160 | +} | |
| 161 | + | |
| 162 | +int dcn301_smu_set_min_deep_sleep_dcfclk(struct clk_mgr_internal *clk_mgr, int requested_min_ds_dcfclk_khz) | |
| 163 | +{ | |
| 164 | + int actual_min_ds_dcfclk_mhz = -1; | |
| 165 | + | |
| 166 | + actual_min_ds_dcfclk_mhz = dcn301_smu_send_msg_with_param( | |
| 167 | + clk_mgr, | |
| 168 | + VBIOSSMC_MSG_SetMinDeepSleepDcfclk, | |
| 169 | + requested_min_ds_dcfclk_khz / 1000); | |
| 170 | + | |
| 171 | + return actual_min_ds_dcfclk_mhz * 1000; | |
| 172 | +} | |
| 173 | + | |
| 174 | +int dcn301_smu_set_dppclk(struct clk_mgr_internal *clk_mgr, int requested_dpp_khz) | |
| 175 | +{ | |
| 176 | + int actual_dppclk_set_mhz = -1; | |
| 177 | + | |
| 178 | + actual_dppclk_set_mhz = dcn301_smu_send_msg_with_param( | |
| 179 | + clk_mgr, | |
| 180 | + VBIOSSMC_MSG_SetDppclkFreq, | |
| 181 | + requested_dpp_khz / 1000); | |
| 182 | + | |
| 183 | + return actual_dppclk_set_mhz * 1000; | |
| 184 | +} | |
| 185 | + | |
| 186 | +void dcn301_smu_set_display_idle_optimization(struct clk_mgr_internal *clk_mgr, uint32_t idle_info) | |
| 187 | +{ | |
| 188 | + //TODO: Work with smu team to define optimization options. | |
| 189 | + | |
| 190 | + dcn301_smu_send_msg_with_param( | |
| 191 | + clk_mgr, | |
| 192 | + VBIOSSMC_MSG_SetDisplayIdleOptimizations, | |
| 193 | + idle_info); | |
| 194 | +} | |
| 195 | + | |
| 196 | +void dcn301_smu_enable_phy_refclk_pwrdwn(struct clk_mgr_internal *clk_mgr, bool enable) | |
| 197 | +{ | |
| 198 | + union display_idle_optimization_u idle_info = { 0 }; | |
| 199 | + | |
| 200 | + if (enable) { | |
| 201 | + idle_info.idle_info.df_request_disabled = 1; | |
| 202 | + idle_info.idle_info.phy_ref_clk_off = 1; | |
| 203 | + } | |
| 204 | + | |
| 205 | + dcn301_smu_send_msg_with_param( | |
| 206 | + clk_mgr, | |
| 207 | + VBIOSSMC_MSG_SetDisplayIdleOptimizations, | |
| 208 | + idle_info.data); | |
| 209 | +} | |
| 210 | + | |
| 211 | +void dcn301_smu_enable_pme_wa(struct clk_mgr_internal *clk_mgr) | |
| 212 | +{ | |
| 213 | + dcn301_smu_send_msg_with_param( | |
| 214 | + clk_mgr, | |
| 215 | + VBIOSSMC_MSG_UpdatePmeRestore, | |
| 216 | + 0); | |
| 217 | +} | |
| 218 | + | |
| 219 | +void dcn301_smu_set_dram_addr_high(struct clk_mgr_internal *clk_mgr, uint32_t addr_high) | |
| 220 | +{ | |
| 221 | + dcn301_smu_send_msg_with_param(clk_mgr, | |
| 222 | + VBIOSSMC_MSG_SetVbiosDramAddrHigh, addr_high); | |
| 223 | +} | |
| 224 | + | |
| 225 | +void dcn301_smu_set_dram_addr_low(struct clk_mgr_internal *clk_mgr, uint32_t addr_low) | |
| 226 | +{ | |
| 227 | + dcn301_smu_send_msg_with_param(clk_mgr, | |
| 228 | + VBIOSSMC_MSG_SetVbiosDramAddrLow, addr_low); | |
| 229 | +} | |
| 230 | + | |
| 231 | +void dcn301_smu_transfer_dpm_table_smu_2_dram(struct clk_mgr_internal *clk_mgr) | |
| 232 | +{ | |
| 233 | + dcn301_smu_send_msg_with_param(clk_mgr, | |
| 234 | + VBIOSSMC_MSG_TransferTableSmu2Dram, TABLE_DPMCLOCKS); | |
| 235 | +} | |
| 236 | + | |
| 237 | +void dcn301_smu_transfer_wm_table_dram_2_smu(struct clk_mgr_internal *clk_mgr) | |
| 238 | +{ | |
| 239 | + dcn301_smu_send_msg_with_param(clk_mgr, | |
| 240 | + VBIOSSMC_MSG_TransferTableDram2Smu, TABLE_WATERMARKS); | |
| 241 | +} | |
| @@ -0,0 +1,164 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2020 Advanced Micro Devices, Inc. | |
| 3 | + * | |
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a | |
| 5 | + * copy of this software and associated documentation files (the "Software"), | |
| 6 | + * to deal in the Software without restriction, including without limitation | |
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the | |
| 9 | + * Software is furnished to do so, subject to the following conditions: | |
| 10 | + * | |
| 11 | + * The above copyright notice and this permission notice shall be included in | |
| 12 | + * all copies or substantial portions of the Software. | |
| 13 | + * | |
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 17 | + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 18 | + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 19 | + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 20 | + * OTHER DEALINGS IN THE SOFTWARE. | |
| 21 | + * | |
| 22 | + * Authors: AMD | |
| 23 | + * | |
| 24 | + */ | |
| 25 | + | |
| 26 | +#ifndef DAL_DC_301_SMU_H_ | |
| 27 | +#define DAL_DC_301_SMU_H_ | |
| 28 | + | |
| 29 | +#define SMU13_DRIVER_IF_VERSION 2 | |
| 30 | + | |
| 31 | +typedef struct { | |
| 32 | + uint32_t fclk; | |
| 33 | + uint32_t memclk; | |
| 34 | + uint32_t voltage; | |
| 35 | +} df_pstate_t; | |
| 36 | + | |
| 37 | +typedef struct { | |
| 38 | + uint32_t vclk; | |
| 39 | + uint32_t dclk; | |
| 40 | +} vcn_clk_t; | |
| 41 | + | |
| 42 | +typedef enum { | |
| 43 | + DSPCLK_DCFCLK = 0, | |
| 44 | + DSPCLK_DISPCLK, | |
| 45 | + DSPCLK_PIXCLK, | |
| 46 | + DSPCLK_PHYCLK, | |
| 47 | + DSPCLK_COUNT, | |
| 48 | +} DSPCLK_e; | |
| 49 | + | |
| 50 | +typedef struct { | |
| 51 | + uint16_t Freq; // in MHz | |
| 52 | + uint16_t Vid; // min voltage in SVI2 VID | |
| 53 | +} DisplayClockTable_t; | |
| 54 | + | |
| 55 | +typedef struct { | |
| 56 | + uint16_t MinClock; // This is either DCFCLK or SOCCLK (in MHz) | |
| 57 | + uint16_t MaxClock; // This is either DCFCLK or SOCCLK (in MHz) | |
| 58 | + uint16_t MinMclk; | |
| 59 | + uint16_t MaxMclk; | |
| 60 | + | |
| 61 | + uint8_t WmSetting; | |
| 62 | + uint8_t WmType; // Used for normal pstate change or memory retraining | |
| 63 | + uint8_t Padding[2]; | |
| 64 | +} WatermarkRowGeneric_t; | |
| 65 | + | |
| 66 | + | |
| 67 | +#define NUM_WM_RANGES 4 | |
| 68 | + | |
| 69 | +typedef enum { | |
| 70 | + WM_SOCCLK = 0, | |
| 71 | + WM_DCFCLK, | |
| 72 | + WM_COUNT, | |
| 73 | +} WM_CLOCK_e; | |
| 74 | + | |
| 75 | +typedef struct { | |
| 76 | + // Watermarks | |
| 77 | + WatermarkRowGeneric_t WatermarkRow[WM_COUNT][NUM_WM_RANGES]; | |
| 78 | + | |
| 79 | + uint32_t MmHubPadding[7]; // SMU internal use | |
| 80 | +} Watermarks_t; | |
| 81 | + | |
| 82 | + | |
| 83 | +#define TABLE_WATERMARKS 1 | |
| 84 | +#define TABLE_DPMCLOCKS 4 // Called by Driver | |
| 85 | + | |
| 86 | + | |
| 87 | +#define VG_NUM_DCFCLK_DPM_LEVELS 7 | |
| 88 | +#define VG_NUM_DISPCLK_DPM_LEVELS 7 | |
| 89 | +#define VG_NUM_DPPCLK_DPM_LEVELS 7 | |
| 90 | +#define VG_NUM_SOCCLK_DPM_LEVELS 7 | |
| 91 | +#define VG_NUM_ISPICLK_DPM_LEVELS 7 | |
| 92 | +#define VG_NUM_ISPXCLK_DPM_LEVELS 7 | |
| 93 | +#define VG_NUM_VCN_DPM_LEVELS 5 | |
| 94 | +#define VG_NUM_FCLK_DPM_LEVELS 4 | |
| 95 | +#define VG_NUM_SOC_VOLTAGE_LEVELS 8 | |
| 96 | + | |
| 97 | +// copy from vgh/vangogh/pmfw_driver_if.h | |
| 98 | +struct vg_dpm_clocks { | |
| 99 | + uint32_t DcfClocks[VG_NUM_DCFCLK_DPM_LEVELS]; | |
| 100 | + uint32_t DispClocks[VG_NUM_DISPCLK_DPM_LEVELS]; | |
| 101 | + uint32_t DppClocks[VG_NUM_DPPCLK_DPM_LEVELS]; | |
| 102 | + uint32_t SocClocks[VG_NUM_SOCCLK_DPM_LEVELS]; | |
| 103 | + uint32_t IspiClocks[VG_NUM_ISPICLK_DPM_LEVELS]; | |
| 104 | + uint32_t IspxClocks[VG_NUM_ISPXCLK_DPM_LEVELS]; | |
| 105 | + vcn_clk_t VcnClocks[VG_NUM_VCN_DPM_LEVELS]; | |
| 106 | + | |
| 107 | + uint32_t SocVoltage[VG_NUM_SOC_VOLTAGE_LEVELS]; | |
| 108 | + | |
| 109 | + df_pstate_t DfPstateTable[VG_NUM_FCLK_DPM_LEVELS]; | |
| 110 | + | |
| 111 | + uint32_t MinGfxClk; | |
| 112 | + uint32_t MaxGfxClk; | |
| 113 | + | |
| 114 | + uint8_t NumDfPstatesEnabled; | |
| 115 | + uint8_t NumDcfclkLevelsEnabled; | |
| 116 | + uint8_t NumDispClkLevelsEnabled; //applies to both dispclk and dppclk | |
| 117 | + uint8_t NumSocClkLevelsEnabled; | |
| 118 | + | |
| 119 | + uint8_t IspClkLevelsEnabled; //applies to both ispiclk and ispxclk | |
| 120 | + uint8_t VcnClkLevelsEnabled; //applies to both vclk/dclk | |
| 121 | + uint8_t spare[2]; | |
| 122 | +}; | |
| 123 | + | |
| 124 | +struct smu_dpm_clks { | |
| 125 | + struct vg_dpm_clocks *dpm_clks; | |
| 126 | + union large_integer mc_address; | |
| 127 | +}; | |
| 128 | + | |
| 129 | +struct watermarks { | |
| 130 | + // Watermarks | |
| 131 | + WatermarkRowGeneric_t WatermarkRow[WM_COUNT][NUM_WM_RANGES]; | |
| 132 | + | |
| 133 | + uint32_t MmHubPadding[7]; // SMU internal use | |
| 134 | +}; | |
| 135 | + | |
| 136 | + | |
| 137 | +struct display_idle_optimization { | |
| 138 | + unsigned int df_request_disabled : 1; | |
| 139 | + unsigned int phy_ref_clk_off : 1; | |
| 140 | + unsigned int s0i2_rdy : 1; | |
| 141 | + unsigned int reserved : 29; | |
| 142 | +}; | |
| 143 | + | |
| 144 | +union display_idle_optimization_u { | |
| 145 | + struct display_idle_optimization idle_info; | |
| 146 | + uint32_t data; | |
| 147 | +}; | |
| 148 | + | |
| 149 | + | |
| 150 | +int dcn301_smu_get_smu_version(struct clk_mgr_internal *clk_mgr); | |
| 151 | +int dcn301_smu_set_dispclk(struct clk_mgr_internal *clk_mgr, int requested_dispclk_khz); | |
| 152 | +int dcn301_smu_set_dprefclk(struct clk_mgr_internal *clk_mgr); | |
| 153 | +int dcn301_smu_set_hard_min_dcfclk(struct clk_mgr_internal *clk_mgr, int requested_dcfclk_khz); | |
| 154 | +int dcn301_smu_set_min_deep_sleep_dcfclk(struct clk_mgr_internal *clk_mgr, int requested_min_ds_dcfclk_khz); | |
| 155 | +int dcn301_smu_set_dppclk(struct clk_mgr_internal *clk_mgr, int requested_dpp_khz); | |
| 156 | +void dcn301_smu_set_display_idle_optimization(struct clk_mgr_internal *clk_mgr, uint32_t idle_info); | |
| 157 | +void dcn301_smu_enable_phy_refclk_pwrdwn(struct clk_mgr_internal *clk_mgr, bool enable); | |
| 158 | +void dcn301_smu_enable_pme_wa(struct clk_mgr_internal *clk_mgr); | |
| 159 | +void dcn301_smu_set_dram_addr_high(struct clk_mgr_internal *clk_mgr, uint32_t addr_high); | |
| 160 | +void dcn301_smu_set_dram_addr_low(struct clk_mgr_internal *clk_mgr, uint32_t addr_low); | |
| 161 | +void dcn301_smu_transfer_dpm_table_smu_2_dram(struct clk_mgr_internal *clk_mgr); | |
| 162 | +void dcn301_smu_transfer_wm_table_dram_2_smu(struct clk_mgr_internal *clk_mgr); | |
| 163 | + | |
| 164 | +#endif /* DAL_DC_301_SMU_H_ */ | |
| @@ -0,0 +1,834 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2020 Advanced Micro Devices, Inc. | |
| 3 | + * | |
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a | |
| 5 | + * copy of this software and associated documentation files (the "Software"), | |
| 6 | + * to deal in the Software without restriction, including without limitation | |
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the | |
| 9 | + * Software is furnished to do so, subject to the following conditions: | |
| 10 | + * | |
| 11 | + * The above copyright notice and this permission notice shall be included in | |
| 12 | + * all copies or substantial portions of the Software. | |
| 13 | + * | |
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 17 | + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 18 | + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 19 | + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 20 | + * OTHER DEALINGS IN THE SOFTWARE. | |
| 21 | + * | |
| 22 | + * Authors: AMD | |
| 23 | + * | |
| 24 | + */ | |
| 25 | + | |
| 26 | +#include "dccg.h" | |
| 27 | +#include "clk_mgr_internal.h" | |
| 28 | + | |
| 29 | +// For dce12_get_dp_ref_freq_khz | |
| 30 | +#include "dce100/dce_clk_mgr.h" | |
| 31 | + | |
| 32 | +// For dcn20_update_clocks_update_dpp_dto | |
| 33 | +#include "dcn20/dcn20_clk_mgr.h" | |
| 34 | + | |
| 35 | +#include "vg_clk_mgr.h" | |
| 36 | + | |
| 37 | +#include "dcn301_smu.h" | |
| 38 | +#include "reg_helper.h" | |
| 39 | +#include "core_types.h" | |
| 40 | +#include "dm_helpers.h" | |
| 41 | + | |
| 42 | +#include "atomfirmware.h" | |
| 43 | +#include "vangogh_ip_offset.h" | |
| 44 | +#include "clk/clk_11_5_0_offset.h" | |
| 45 | +#include "clk/clk_11_5_0_sh_mask.h" | |
| 46 | + | |
| 47 | +/* Constants */ | |
| 48 | + | |
| 49 | +#define LPDDR_MEM_RETRAIN_LATENCY 4.977 /* Number obtained from LPDDR4 Training Counter Requirement doc */ | |
| 50 | + | |
| 51 | +/* Macros */ | |
| 52 | + | |
| 53 | +#define REG(reg_name) \ | |
| 54 | + (CLK_BASE.instance[0].segment[mm ## reg_name ## _BASE_IDX] + mm ## reg_name) | |
| 55 | + | |
| 56 | +/* TODO: evaluate how to lower or disable all dcn clocks in screen off case */ | |
| 57 | +int vg_get_active_display_cnt_wa( | |
| 58 | + struct dc *dc, | |
| 59 | + struct dc_state *context) | |
| 60 | +{ | |
| 61 | + int i, display_count; | |
| 62 | + bool tmds_present = false; | |
| 63 | + | |
| 64 | + display_count = 0; | |
| 65 | + for (i = 0; i < context->stream_count; i++) { | |
| 66 | + const struct dc_stream_state *stream = context->streams[i]; | |
| 67 | + | |
| 68 | + if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A || | |
| 69 | + stream->signal == SIGNAL_TYPE_DVI_SINGLE_LINK || | |
| 70 | + stream->signal == SIGNAL_TYPE_DVI_DUAL_LINK) | |
| 71 | + tmds_present = true; | |
| 72 | + } | |
| 73 | + | |
| 74 | + for (i = 0; i < dc->link_count; i++) { | |
| 75 | + const struct dc_link *link = dc->links[i]; | |
| 76 | + | |
| 77 | + /* | |
| 78 | + * Only notify active stream or virtual stream. | |
| 79 | + * Need to notify virtual stream to work around | |
| 80 | + * headless case. HPD does not fire when system is in | |
| 81 | + * S0i2. | |
| 82 | + */ | |
| 83 | + /* abusing the fact that the dig and phy are coupled to see if the phy is enabled */ | |
| 84 | + if (link->connector_signal == SIGNAL_TYPE_VIRTUAL || | |
| 85 | + link->link_enc->funcs->is_dig_enabled(link->link_enc)) | |
| 86 | + display_count++; | |
| 87 | + } | |
| 88 | + | |
| 89 | + /* WA for hang on HDMI after display off back back on*/ | |
| 90 | + if (display_count == 0 && tmds_present) | |
| 91 | + display_count = 1; | |
| 92 | + | |
| 93 | + return display_count; | |
| 94 | +} | |
| 95 | + | |
| 96 | +void vg_update_clocks(struct clk_mgr *clk_mgr_base, | |
| 97 | + struct dc_state *context, | |
| 98 | + bool safe_to_lower) | |
| 99 | +{ | |
| 100 | + struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); | |
| 101 | + struct dc_clocks *new_clocks = &context->bw_ctx.bw.dcn.clk; | |
| 102 | + struct dc *dc = clk_mgr_base->ctx->dc; | |
| 103 | + int display_count; | |
| 104 | + bool update_dppclk = false; | |
| 105 | + bool update_dispclk = false; | |
| 106 | + bool dpp_clock_lowered = false; | |
| 107 | + | |
| 108 | + if (dc->work_arounds.skip_clock_update) | |
| 109 | + return; | |
| 110 | + | |
| 111 | + /* | |
| 112 | + * if it is safe to lower, but we are already in the lower state, we don't have to do anything | |
| 113 | + * also if safe to lower is false, we just go in the higher state | |
| 114 | + */ | |
| 115 | + if (safe_to_lower) { | |
| 116 | + /* check that we're not already in lower */ | |
| 117 | + if (clk_mgr_base->clks.pwr_state != DCN_PWR_STATE_LOW_POWER) { | |
| 118 | + | |
| 119 | + display_count = vg_get_active_display_cnt_wa(dc, context); | |
| 120 | + /* if we can go lower, go lower */ | |
| 121 | + if (display_count == 0) { | |
| 122 | + union display_idle_optimization_u idle_info = { 0 }; | |
| 123 | + | |
| 124 | + idle_info.idle_info.df_request_disabled = 1; | |
| 125 | + idle_info.idle_info.phy_ref_clk_off = 1; | |
| 126 | + | |
| 127 | + dcn301_smu_set_display_idle_optimization(clk_mgr, idle_info.data); | |
| 128 | + /* update power state */ | |
| 129 | + clk_mgr_base->clks.pwr_state = DCN_PWR_STATE_LOW_POWER; | |
| 130 | + } | |
| 131 | + } | |
| 132 | + } else { | |
| 133 | + /* check that we're not already in D0 */ | |
| 134 | + if (clk_mgr_base->clks.pwr_state != DCN_PWR_STATE_MISSION_MODE) { | |
| 135 | + union display_idle_optimization_u idle_info = { 0 }; | |
| 136 | + | |
| 137 | + dcn301_smu_set_display_idle_optimization(clk_mgr, idle_info.data); | |
| 138 | + /* update power state */ | |
| 139 | + clk_mgr_base->clks.pwr_state = DCN_PWR_STATE_MISSION_MODE; | |
| 140 | + } | |
| 141 | + } | |
| 142 | + | |
| 143 | + if (should_set_clock(safe_to_lower, new_clocks->dcfclk_khz, clk_mgr_base->clks.dcfclk_khz)) { | |
| 144 | + clk_mgr_base->clks.dcfclk_khz = new_clocks->dcfclk_khz; | |
| 145 | + dcn301_smu_set_hard_min_dcfclk(clk_mgr, clk_mgr_base->clks.dcfclk_khz); | |
| 146 | + } | |
| 147 | + | |
| 148 | + if (should_set_clock(safe_to_lower, | |
| 149 | + new_clocks->dcfclk_deep_sleep_khz, clk_mgr_base->clks.dcfclk_deep_sleep_khz)) { | |
| 150 | + clk_mgr_base->clks.dcfclk_deep_sleep_khz = new_clocks->dcfclk_deep_sleep_khz; | |
| 151 | + dcn301_smu_set_min_deep_sleep_dcfclk(clk_mgr, clk_mgr_base->clks.dcfclk_deep_sleep_khz); | |
| 152 | + } | |
| 153 | + | |
| 154 | + // workaround: Limit dppclk to 100Mhz to avoid lower eDP panel switch to plus 4K monitor underflow. | |
| 155 | + if (!IS_DIAG_DC(dc->ctx->dce_environment)) { | |
| 156 | + if (new_clocks->dppclk_khz < 100000) | |
| 157 | + new_clocks->dppclk_khz = 100000; | |
| 158 | + } | |
| 159 | + | |
| 160 | + if (should_set_clock(safe_to_lower, new_clocks->dppclk_khz, clk_mgr->base.clks.dppclk_khz)) { | |
| 161 | + if (clk_mgr->base.clks.dppclk_khz > new_clocks->dppclk_khz) | |
| 162 | + dpp_clock_lowered = true; | |
| 163 | + clk_mgr_base->clks.dppclk_khz = new_clocks->dppclk_khz; | |
| 164 | + update_dppclk = true; | |
| 165 | + } | |
| 166 | + | |
| 167 | + if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz)) { | |
| 168 | + clk_mgr_base->clks.dispclk_khz = new_clocks->dispclk_khz; | |
| 169 | + dcn301_smu_set_dispclk(clk_mgr, clk_mgr_base->clks.dispclk_khz); | |
| 170 | + | |
| 171 | + update_dispclk = true; | |
| 172 | + } | |
| 173 | + | |
| 174 | + if (dpp_clock_lowered) { | |
| 175 | + // increase per DPP DTO before lowering global dppclk | |
| 176 | + dcn20_update_clocks_update_dpp_dto(clk_mgr, context, safe_to_lower); | |
| 177 | + dcn301_smu_set_dppclk(clk_mgr, clk_mgr_base->clks.dppclk_khz); | |
| 178 | + } else { | |
| 179 | + // increase global DPPCLK before lowering per DPP DTO | |
| 180 | + if (update_dppclk || update_dispclk) | |
| 181 | + dcn301_smu_set_dppclk(clk_mgr, clk_mgr_base->clks.dppclk_khz); | |
| 182 | + // always update dtos unless clock is lowered and not safe to lower | |
| 183 | + if (new_clocks->dppclk_khz >= dc->current_state->bw_ctx.bw.dcn.clk.dppclk_khz) | |
| 184 | + dcn20_update_clocks_update_dpp_dto(clk_mgr, context, safe_to_lower); | |
| 185 | + } | |
| 186 | +} | |
| 187 | + | |
| 188 | + | |
| 189 | +static int get_vco_frequency_from_reg(struct clk_mgr_internal *clk_mgr) | |
| 190 | +{ | |
| 191 | + /* get FbMult value */ | |
| 192 | + struct fixed31_32 pll_req; | |
| 193 | + unsigned int fbmult_frac_val = 0; | |
| 194 | + unsigned int fbmult_int_val = 0; | |
| 195 | + | |
| 196 | + | |
| 197 | + /* | |
| 198 | + * Register value of fbmult is in 8.16 format, we are converting to 31.32 | |
| 199 | + * to leverage the fix point operations available in driver | |
| 200 | + */ | |
| 201 | + | |
| 202 | + REG_GET(CLK1_0_CLK1_CLK_PLL_REQ, FbMult_frac, &fbmult_frac_val); /* 16 bit fractional part*/ | |
| 203 | + REG_GET(CLK1_0_CLK1_CLK_PLL_REQ, FbMult_int, &fbmult_int_val); /* 8 bit integer part */ | |
| 204 | + | |
| 205 | + pll_req = dc_fixpt_from_int(fbmult_int_val); | |
| 206 | + | |
| 207 | + /* | |
| 208 | + * since fractional part is only 16 bit in register definition but is 32 bit | |
| 209 | + * in our fix point definiton, need to shift left by 16 to obtain correct value | |
| 210 | + */ | |
| 211 | + pll_req.value |= fbmult_frac_val << 16; | |
| 212 | + | |
| 213 | + /* multiply by REFCLK period */ | |
| 214 | + pll_req = dc_fixpt_mul_int(pll_req, clk_mgr->dfs_ref_freq_khz); | |
| 215 | + | |
| 216 | + /* integer part is now VCO frequency in kHz */ | |
| 217 | + return dc_fixpt_floor(pll_req); | |
| 218 | +} | |
| 219 | + | |
| 220 | +static void vg_dump_clk_registers_internal(struct dcn301_clk_internal *internal, struct clk_mgr *clk_mgr_base) | |
| 221 | +{ | |
| 222 | + struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); | |
| 223 | + | |
| 224 | + internal->CLK1_CLK3_CURRENT_CNT = REG_READ(CLK1_0_CLK1_CLK3_CURRENT_CNT); | |
| 225 | + internal->CLK1_CLK3_BYPASS_CNTL = REG_READ(CLK1_0_CLK1_CLK3_BYPASS_CNTL); | |
| 226 | + | |
| 227 | + internal->CLK1_CLK3_DS_CNTL = REG_READ(CLK1_0_CLK1_CLK3_DS_CNTL); //dcf deep sleep divider | |
| 228 | + internal->CLK1_CLK3_ALLOW_DS = REG_READ(CLK1_0_CLK1_CLK3_ALLOW_DS); | |
| 229 | + | |
| 230 | + internal->CLK1_CLK1_CURRENT_CNT = REG_READ(CLK1_0_CLK1_CLK1_CURRENT_CNT); | |
| 231 | + internal->CLK1_CLK1_BYPASS_CNTL = REG_READ(CLK1_0_CLK1_CLK1_BYPASS_CNTL); | |
| 232 | + | |
| 233 | + internal->CLK1_CLK2_CURRENT_CNT = REG_READ(CLK1_0_CLK1_CLK2_CURRENT_CNT); | |
| 234 | + internal->CLK1_CLK2_BYPASS_CNTL = REG_READ(CLK1_0_CLK1_CLK2_BYPASS_CNTL); | |
| 235 | + | |
| 236 | + internal->CLK1_CLK0_CURRENT_CNT = REG_READ(CLK1_0_CLK1_CLK0_CURRENT_CNT); | |
| 237 | + internal->CLK1_CLK0_BYPASS_CNTL = REG_READ(CLK1_0_CLK1_CLK0_BYPASS_CNTL); | |
| 238 | +} | |
| 239 | + | |
| 240 | +/* This function collect raw clk register values */ | |
| 241 | +static void vg_dump_clk_registers(struct clk_state_registers_and_bypass *regs_and_bypass, | |
| 242 | + struct clk_mgr *clk_mgr_base, struct clk_log_info *log_info) | |
| 243 | +{ | |
| 244 | + struct dcn301_clk_internal internal = {0}; | |
| 245 | + char *bypass_clks[5] = {"0x0 DFS", "0x1 REFCLK", "0x2 ERROR", "0x3 400 FCH", "0x4 600 FCH"}; | |
| 246 | + unsigned int chars_printed = 0; | |
| 247 | + unsigned int remaining_buffer = log_info->bufSize; | |
| 248 | + | |
| 249 | + vg_dump_clk_registers_internal(&internal, clk_mgr_base); | |
| 250 | + | |
| 251 | + regs_and_bypass->dcfclk = internal.CLK1_CLK3_CURRENT_CNT / 10; | |
| 252 | + regs_and_bypass->dcf_deep_sleep_divider = internal.CLK1_CLK3_DS_CNTL / 10; | |
| 253 | + regs_and_bypass->dcf_deep_sleep_allow = internal.CLK1_CLK3_ALLOW_DS; | |
| 254 | + regs_and_bypass->dprefclk = internal.CLK1_CLK2_CURRENT_CNT / 10; | |
| 255 | + regs_and_bypass->dispclk = internal.CLK1_CLK0_CURRENT_CNT / 10; | |
| 256 | + regs_and_bypass->dppclk = internal.CLK1_CLK1_CURRENT_CNT / 10; | |
| 257 | + | |
| 258 | + regs_and_bypass->dppclk_bypass = internal.CLK1_CLK1_BYPASS_CNTL & 0x0007; | |
| 259 | + if (regs_and_bypass->dppclk_bypass < 0 || regs_and_bypass->dppclk_bypass > 4) | |
| 260 | + regs_and_bypass->dppclk_bypass = 0; | |
| 261 | + regs_and_bypass->dcfclk_bypass = internal.CLK1_CLK3_BYPASS_CNTL & 0x0007; | |
| 262 | + if (regs_and_bypass->dcfclk_bypass < 0 || regs_and_bypass->dcfclk_bypass > 4) | |
| 263 | + regs_and_bypass->dcfclk_bypass = 0; | |
| 264 | + regs_and_bypass->dispclk_bypass = internal.CLK1_CLK0_BYPASS_CNTL & 0x0007; | |
| 265 | + if (regs_and_bypass->dispclk_bypass < 0 || regs_and_bypass->dispclk_bypass > 4) | |
| 266 | + regs_and_bypass->dispclk_bypass = 0; | |
| 267 | + regs_and_bypass->dprefclk_bypass = internal.CLK1_CLK2_BYPASS_CNTL & 0x0007; | |
| 268 | + if (regs_and_bypass->dprefclk_bypass < 0 || regs_and_bypass->dprefclk_bypass > 4) | |
| 269 | + regs_and_bypass->dprefclk_bypass = 0; | |
| 270 | + | |
| 271 | + if (log_info->enabled) { | |
| 272 | + chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "clk_type,clk_value,deepsleep_cntl,deepsleep_allow,bypass\n"); | |
| 273 | + remaining_buffer -= chars_printed; | |
| 274 | + *log_info->sum_chars_printed += chars_printed; | |
| 275 | + log_info->pBuf += chars_printed; | |
| 276 | + | |
| 277 | + chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "dcfclk,%d,%d,%d,%s\n", | |
| 278 | + regs_and_bypass->dcfclk, | |
| 279 | + regs_and_bypass->dcf_deep_sleep_divider, | |
| 280 | + regs_and_bypass->dcf_deep_sleep_allow, | |
| 281 | + bypass_clks[(int) regs_and_bypass->dcfclk_bypass]); | |
| 282 | + remaining_buffer -= chars_printed; | |
| 283 | + *log_info->sum_chars_printed += chars_printed; | |
| 284 | + log_info->pBuf += chars_printed; | |
| 285 | + | |
| 286 | + chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "dprefclk,%d,N/A,N/A,%s\n", | |
| 287 | + regs_and_bypass->dprefclk, | |
| 288 | + bypass_clks[(int) regs_and_bypass->dprefclk_bypass]); | |
| 289 | + remaining_buffer -= chars_printed; | |
| 290 | + *log_info->sum_chars_printed += chars_printed; | |
| 291 | + log_info->pBuf += chars_printed; | |
| 292 | + | |
| 293 | + chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "dispclk,%d,N/A,N/A,%s\n", | |
| 294 | + regs_and_bypass->dispclk, | |
| 295 | + bypass_clks[(int) regs_and_bypass->dispclk_bypass]); | |
| 296 | + remaining_buffer -= chars_printed; | |
| 297 | + *log_info->sum_chars_printed += chars_printed; | |
| 298 | + log_info->pBuf += chars_printed; | |
| 299 | + | |
| 300 | + //split | |
| 301 | + chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "SPLIT\n"); | |
| 302 | + remaining_buffer -= chars_printed; | |
| 303 | + *log_info->sum_chars_printed += chars_printed; | |
| 304 | + log_info->pBuf += chars_printed; | |
| 305 | + | |
| 306 | + // REGISTER VALUES | |
| 307 | + chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "reg_name,value,clk_type\n"); | |
| 308 | + remaining_buffer -= chars_printed; | |
| 309 | + *log_info->sum_chars_printed += chars_printed; | |
| 310 | + log_info->pBuf += chars_printed; | |
| 311 | + | |
| 312 | + chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "CLK1_CLK3_CURRENT_CNT,%d,dcfclk\n", | |
| 313 | + internal.CLK1_CLK3_CURRENT_CNT); | |
| 314 | + remaining_buffer -= chars_printed; | |
| 315 | + *log_info->sum_chars_printed += chars_printed; | |
| 316 | + log_info->pBuf += chars_printed; | |
| 317 | + | |
| 318 | + chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "CLK1_CLK3_DS_CNTL,%d,dcf_deep_sleep_divider\n", | |
| 319 | + internal.CLK1_CLK3_DS_CNTL); | |
| 320 | + remaining_buffer -= chars_printed; | |
| 321 | + *log_info->sum_chars_printed += chars_printed; | |
| 322 | + log_info->pBuf += chars_printed; | |
| 323 | + | |
| 324 | + chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "CLK1_CLK3_ALLOW_DS,%d,dcf_deep_sleep_allow\n", | |
| 325 | + internal.CLK1_CLK3_ALLOW_DS); | |
| 326 | + remaining_buffer -= chars_printed; | |
| 327 | + *log_info->sum_chars_printed += chars_printed; | |
| 328 | + log_info->pBuf += chars_printed; | |
| 329 | + | |
| 330 | + chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "CLK1_CLK2_CURRENT_CNT,%d,dprefclk\n", | |
| 331 | + internal.CLK1_CLK2_CURRENT_CNT); | |
| 332 | + remaining_buffer -= chars_printed; | |
| 333 | + *log_info->sum_chars_printed += chars_printed; | |
| 334 | + log_info->pBuf += chars_printed; | |
| 335 | + | |
| 336 | + chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "CLK1_CLK0_CURRENT_CNT,%d,dispclk\n", | |
| 337 | + internal.CLK1_CLK0_CURRENT_CNT); | |
| 338 | + remaining_buffer -= chars_printed; | |
| 339 | + *log_info->sum_chars_printed += chars_printed; | |
| 340 | + log_info->pBuf += chars_printed; | |
| 341 | + | |
| 342 | + chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "CLK1_CLK1_CURRENT_CNT,%d,dppclk\n", | |
| 343 | + internal.CLK1_CLK1_CURRENT_CNT); | |
| 344 | + remaining_buffer -= chars_printed; | |
| 345 | + *log_info->sum_chars_printed += chars_printed; | |
| 346 | + log_info->pBuf += chars_printed; | |
| 347 | + | |
| 348 | + chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "CLK1_CLK3_BYPASS_CNTL,%d,dcfclk_bypass\n", | |
| 349 | + internal.CLK1_CLK3_BYPASS_CNTL); | |
| 350 | + remaining_buffer -= chars_printed; | |
| 351 | + *log_info->sum_chars_printed += chars_printed; | |
| 352 | + log_info->pBuf += chars_printed; | |
| 353 | + | |
| 354 | + chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "CLK1_CLK2_BYPASS_CNTL,%d,dprefclk_bypass\n", | |
| 355 | + internal.CLK1_CLK2_BYPASS_CNTL); | |
| 356 | + remaining_buffer -= chars_printed; | |
| 357 | + *log_info->sum_chars_printed += chars_printed; | |
| 358 | + log_info->pBuf += chars_printed; | |
| 359 | + | |
| 360 | + chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "CLK1_CLK0_BYPASS_CNTL,%d,dispclk_bypass\n", | |
| 361 | + internal.CLK1_CLK0_BYPASS_CNTL); | |
| 362 | + remaining_buffer -= chars_printed; | |
| 363 | + *log_info->sum_chars_printed += chars_printed; | |
| 364 | + log_info->pBuf += chars_printed; | |
| 365 | + | |
| 366 | + chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "CLK1_CLK1_BYPASS_CNTL,%d,dppclk_bypass\n", | |
| 367 | + internal.CLK1_CLK1_BYPASS_CNTL); | |
| 368 | + remaining_buffer -= chars_printed; | |
| 369 | + *log_info->sum_chars_printed += chars_printed; | |
| 370 | + log_info->pBuf += chars_printed; | |
| 371 | + } | |
| 372 | +} | |
| 373 | + | |
| 374 | +/* This function produce translated logical clk state values*/ | |
| 375 | +void vg_get_clk_states(struct clk_mgr *clk_mgr_base, struct clk_states *s) | |
| 376 | +{ | |
| 377 | + | |
| 378 | + struct clk_state_registers_and_bypass sb = { 0 }; | |
| 379 | + struct clk_log_info log_info = { 0 }; | |
| 380 | + | |
| 381 | + vg_dump_clk_registers(&sb, clk_mgr_base, &log_info); | |
| 382 | + | |
| 383 | + s->dprefclk_khz = sb.dprefclk * 1000; | |
| 384 | +} | |
| 385 | + | |
| 386 | +void vg_enable_pme_wa(struct clk_mgr *clk_mgr_base) | |
| 387 | +{ | |
| 388 | + struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); | |
| 389 | + | |
| 390 | + dcn301_smu_enable_pme_wa(clk_mgr); | |
| 391 | +} | |
| 392 | + | |
| 393 | +void vg_init_clocks(struct clk_mgr *clk_mgr) | |
| 394 | +{ | |
| 395 | + memset(&(clk_mgr->clks), 0, sizeof(struct dc_clocks)); | |
| 396 | + // Assumption is that boot state always supports pstate | |
| 397 | + clk_mgr->clks.p_state_change_support = true; | |
| 398 | + clk_mgr->clks.prev_p_state_change_support = true; | |
| 399 | + clk_mgr->clks.pwr_state = DCN_PWR_STATE_UNKNOWN; | |
| 400 | +} | |
| 401 | + | |
| 402 | +static void vg_build_watermark_ranges(struct clk_bw_params *bw_params, struct watermarks *table) | |
| 403 | +{ | |
| 404 | + int i, num_valid_sets; | |
| 405 | + | |
| 406 | + num_valid_sets = 0; | |
| 407 | + | |
| 408 | + for (i = 0; i < WM_SET_COUNT; i++) { | |
| 409 | + /* skip empty entries, the smu array has no holes*/ | |
| 410 | + if (!bw_params->wm_table.entries[i].valid) | |
| 411 | + continue; | |
| 412 | + | |
| 413 | + table->WatermarkRow[WM_DCFCLK][num_valid_sets].WmSetting = bw_params->wm_table.entries[i].wm_inst; | |
| 414 | + table->WatermarkRow[WM_DCFCLK][num_valid_sets].WmType = bw_params->wm_table.entries[i].wm_type; | |
| 415 | + /* We will not select WM based on fclk, so leave it as unconstrained */ | |
| 416 | + table->WatermarkRow[WM_DCFCLK][num_valid_sets].MinClock = 0; | |
| 417 | + table->WatermarkRow[WM_DCFCLK][num_valid_sets].MaxClock = 0xFFFF; | |
| 418 | + | |
| 419 | + if (table->WatermarkRow[WM_DCFCLK][num_valid_sets].WmType == WM_TYPE_PSTATE_CHG) { | |
| 420 | + if (i == 0) | |
| 421 | + table->WatermarkRow[WM_DCFCLK][num_valid_sets].MinMclk = 0; | |
| 422 | + else { | |
| 423 | + /* add 1 to make it non-overlapping with next lvl */ | |
| 424 | + table->WatermarkRow[WM_DCFCLK][num_valid_sets].MinMclk = | |
| 425 | + bw_params->clk_table.entries[i - 1].dcfclk_mhz + 1; | |
| 426 | + } | |
| 427 | + table->WatermarkRow[WM_DCFCLK][num_valid_sets].MaxMclk = | |
| 428 | + bw_params->clk_table.entries[i].dcfclk_mhz; | |
| 429 | + | |
| 430 | + } else { | |
| 431 | + /* unconstrained for memory retraining */ | |
| 432 | + table->WatermarkRow[WM_DCFCLK][num_valid_sets].MinClock = 0; | |
| 433 | + table->WatermarkRow[WM_DCFCLK][num_valid_sets].MaxClock = 0xFFFF; | |
| 434 | + | |
| 435 | + /* Modify previous watermark range to cover up to max */ | |
| 436 | + table->WatermarkRow[WM_DCFCLK][num_valid_sets - 1].MaxClock = 0xFFFF; | |
| 437 | + } | |
| 438 | + num_valid_sets++; | |
| 439 | + } | |
| 440 | + | |
| 441 | + ASSERT(num_valid_sets != 0); /* Must have at least one set of valid watermarks */ | |
| 442 | + | |
| 443 | + /* modify the min and max to make sure we cover the whole range*/ | |
| 444 | + table->WatermarkRow[WM_DCFCLK][0].MinMclk = 0; | |
| 445 | + table->WatermarkRow[WM_DCFCLK][0].MinClock = 0; | |
| 446 | + table->WatermarkRow[WM_DCFCLK][num_valid_sets - 1].MaxMclk = 0xFFFF; | |
| 447 | + table->WatermarkRow[WM_DCFCLK][num_valid_sets - 1].MaxClock = 0xFFFF; | |
| 448 | + | |
| 449 | + /* This is for writeback only, does not matter currently as no writeback support*/ | |
| 450 | + table->WatermarkRow[WM_SOCCLK][0].WmSetting = WM_A; | |
| 451 | + table->WatermarkRow[WM_SOCCLK][0].MinClock = 0; | |
| 452 | + table->WatermarkRow[WM_SOCCLK][0].MaxClock = 0xFFFF; | |
| 453 | + table->WatermarkRow[WM_SOCCLK][0].MinMclk = 0; | |
| 454 | + table->WatermarkRow[WM_SOCCLK][0].MaxMclk = 0xFFFF; | |
| 455 | +} | |
| 456 | + | |
| 457 | + | |
| 458 | +void vg_notify_wm_ranges(struct clk_mgr *clk_mgr_base) | |
| 459 | +{ | |
| 460 | + struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); | |
| 461 | + struct watermarks *table = clk_mgr_base->smu_wm_set.wm_set; | |
| 462 | + | |
| 463 | + if (!clk_mgr->smu_ver) | |
| 464 | + return; | |
| 465 | + | |
| 466 | + if (!table || clk_mgr_base->smu_wm_set.mc_address.quad_part == 0) | |
| 467 | + return; | |
| 468 | + | |
| 469 | + memset(table, 0, sizeof(*table)); | |
| 470 | + | |
| 471 | + vg_build_watermark_ranges(clk_mgr_base->bw_params, table); | |
| 472 | + | |
| 473 | + dcn301_smu_set_dram_addr_high(clk_mgr, | |
| 474 | + clk_mgr_base->smu_wm_set.mc_address.high_part); | |
| 475 | + dcn301_smu_set_dram_addr_low(clk_mgr, | |
| 476 | + clk_mgr_base->smu_wm_set.mc_address.low_part); | |
| 477 | + dcn301_smu_transfer_wm_table_dram_2_smu(clk_mgr); | |
| 478 | +} | |
| 479 | + | |
| 480 | +static bool vg_are_clock_states_equal(struct dc_clocks *a, | |
| 481 | + struct dc_clocks *b) | |
| 482 | +{ | |
| 483 | + if (a->dispclk_khz != b->dispclk_khz) | |
| 484 | + return false; | |
| 485 | + else if (a->dppclk_khz != b->dppclk_khz) | |
| 486 | + return false; | |
| 487 | + else if (a->dcfclk_khz != b->dcfclk_khz) | |
| 488 | + return false; | |
| 489 | + else if (a->dcfclk_deep_sleep_khz != b->dcfclk_deep_sleep_khz) | |
| 490 | + return false; | |
| 491 | + | |
| 492 | + return true; | |
| 493 | +} | |
| 494 | + | |
| 495 | + | |
| 496 | +static struct clk_mgr_funcs vg_funcs = { | |
| 497 | + .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz, | |
| 498 | + .update_clocks = vg_update_clocks, | |
| 499 | + .init_clocks = vg_init_clocks, | |
| 500 | + .enable_pme_wa = vg_enable_pme_wa, | |
| 501 | + .are_clock_states_equal = vg_are_clock_states_equal, | |
| 502 | + .notify_wm_ranges = vg_notify_wm_ranges | |
| 503 | +}; | |
| 504 | + | |
| 505 | +static struct clk_bw_params vg_bw_params = { | |
| 506 | + .vram_type = Ddr4MemType, | |
| 507 | + .num_channels = 1, | |
| 508 | + .clk_table = { | |
| 509 | + .entries = { | |
| 510 | + { | |
| 511 | + .voltage = 0, | |
| 512 | + .dcfclk_mhz = 400, | |
| 513 | + .fclk_mhz = 400, | |
| 514 | + .memclk_mhz = 800, | |
| 515 | + .socclk_mhz = 0, | |
| 516 | + }, | |
| 517 | + { | |
| 518 | + .voltage = 0, | |
| 519 | + .dcfclk_mhz = 483, | |
| 520 | + .fclk_mhz = 800, | |
| 521 | + .memclk_mhz = 1600, | |
| 522 | + .socclk_mhz = 0, | |
| 523 | + }, | |
| 524 | + { | |
| 525 | + .voltage = 0, | |
| 526 | + .dcfclk_mhz = 602, | |
| 527 | + .fclk_mhz = 1067, | |
| 528 | + .memclk_mhz = 1067, | |
| 529 | + .socclk_mhz = 0, | |
| 530 | + }, | |
| 531 | + { | |
| 532 | + .voltage = 0, | |
| 533 | + .dcfclk_mhz = 738, | |
| 534 | + .fclk_mhz = 1333, | |
| 535 | + .memclk_mhz = 1600, | |
| 536 | + .socclk_mhz = 0, | |
| 537 | + }, | |
| 538 | + }, | |
| 539 | + | |
| 540 | + .num_entries = 4, | |
| 541 | + }, | |
| 542 | + | |
| 543 | +}; | |
| 544 | + | |
| 545 | +static struct wm_table ddr4_wm_table = { | |
| 546 | + .entries = { | |
| 547 | + { | |
| 548 | + .wm_inst = WM_A, | |
| 549 | + .wm_type = WM_TYPE_PSTATE_CHG, | |
| 550 | + .pstate_latency_us = 11.72, | |
| 551 | + .sr_exit_time_us = 6.09, | |
| 552 | + .sr_enter_plus_exit_time_us = 7.14, | |
| 553 | + .valid = true, | |
| 554 | + }, | |
| 555 | + { | |
| 556 | + .wm_inst = WM_B, | |
| 557 | + .wm_type = WM_TYPE_PSTATE_CHG, | |
| 558 | + .pstate_latency_us = 11.72, | |
| 559 | + .sr_exit_time_us = 10.12, | |
| 560 | + .sr_enter_plus_exit_time_us = 11.48, | |
| 561 | + .valid = true, | |
| 562 | + }, | |
| 563 | + { | |
| 564 | + .wm_inst = WM_C, | |
| 565 | + .wm_type = WM_TYPE_PSTATE_CHG, | |
| 566 | + .pstate_latency_us = 11.72, | |
| 567 | + .sr_exit_time_us = 10.12, | |
| 568 | + .sr_enter_plus_exit_time_us = 11.48, | |
| 569 | + .valid = true, | |
| 570 | + }, | |
| 571 | + { | |
| 572 | + .wm_inst = WM_D, | |
| 573 | + .wm_type = WM_TYPE_PSTATE_CHG, | |
| 574 | + .pstate_latency_us = 11.72, | |
| 575 | + .sr_exit_time_us = 10.12, | |
| 576 | + .sr_enter_plus_exit_time_us = 11.48, | |
| 577 | + .valid = true, | |
| 578 | + }, | |
| 579 | + } | |
| 580 | +}; | |
| 581 | + | |
| 582 | +static struct wm_table lpddr5_wm_table = { | |
| 583 | + .entries = { | |
| 584 | + { | |
| 585 | + .wm_inst = WM_A, | |
| 586 | + .wm_type = WM_TYPE_PSTATE_CHG, | |
| 587 | + .pstate_latency_us = 11.65333, | |
| 588 | + .sr_exit_time_us = 5.32, | |
| 589 | + .sr_enter_plus_exit_time_us = 6.38, | |
| 590 | + .valid = true, | |
| 591 | + }, | |
| 592 | + { | |
| 593 | + .wm_inst = WM_B, | |
| 594 | + .wm_type = WM_TYPE_PSTATE_CHG, | |
| 595 | + .pstate_latency_us = 11.65333, | |
| 596 | + .sr_exit_time_us = 9.82, | |
| 597 | + .sr_enter_plus_exit_time_us = 11.196, | |
| 598 | + .valid = true, | |
| 599 | + }, | |
| 600 | + { | |
| 601 | + .wm_inst = WM_C, | |
| 602 | + .wm_type = WM_TYPE_PSTATE_CHG, | |
| 603 | + .pstate_latency_us = 11.65333, | |
| 604 | + .sr_exit_time_us = 9.89, | |
| 605 | + .sr_enter_plus_exit_time_us = 11.24, | |
| 606 | + .valid = true, | |
| 607 | + }, | |
| 608 | + { | |
| 609 | + .wm_inst = WM_D, | |
| 610 | + .wm_type = WM_TYPE_PSTATE_CHG, | |
| 611 | + .pstate_latency_us = 11.65333, | |
| 612 | + .sr_exit_time_us = 9.748, | |
| 613 | + .sr_enter_plus_exit_time_us = 11.102, | |
| 614 | + .valid = true, | |
| 615 | + }, | |
| 616 | + } | |
| 617 | +}; | |
| 618 | + | |
| 619 | + | |
| 620 | +static unsigned int find_dcfclk_for_voltage(const struct vg_dpm_clocks *clock_table, | |
| 621 | + unsigned int voltage) | |
| 622 | +{ | |
| 623 | + int i; | |
| 624 | + | |
| 625 | + for (i = 0; i < VG_NUM_SOC_VOLTAGE_LEVELS; i++) { | |
| 626 | + if (clock_table->SocVoltage[i] == voltage) | |
| 627 | + return clock_table->DcfClocks[i]; | |
| 628 | + } | |
| 629 | + | |
| 630 | + ASSERT(0); | |
| 631 | + return 0; | |
| 632 | +} | |
| 633 | + | |
| 634 | +static void vg_clk_mgr_helper_populate_bw_params( | |
| 635 | + struct clk_mgr_internal *clk_mgr, | |
| 636 | + struct integrated_info *bios_info, | |
| 637 | + const struct vg_dpm_clocks *clock_table) | |
| 638 | +{ | |
| 639 | + int i, j; | |
| 640 | + struct clk_bw_params *bw_params = clk_mgr->base.bw_params; | |
| 641 | + | |
| 642 | + j = -1; | |
| 643 | + | |
| 644 | + ASSERT(VG_NUM_FCLK_DPM_LEVELS <= MAX_NUM_DPM_LVL); | |
| 645 | + | |
| 646 | + /* Find lowest DPM, FCLK is filled in reverse order*/ | |
| 647 | + | |
| 648 | + for (i = VG_NUM_FCLK_DPM_LEVELS - 1; i >= 0; i--) { | |
| 649 | + if (clock_table->DfPstateTable[i].fclk != 0) { | |
| 650 | + j = i; | |
| 651 | + break; | |
| 652 | + } | |
| 653 | + } | |
| 654 | + | |
| 655 | + if (j == -1) { | |
| 656 | + /* clock table is all 0s, just use our own hardcode */ | |
| 657 | + ASSERT(0); | |
| 658 | + return; | |
| 659 | + } | |
| 660 | + | |
| 661 | + bw_params->clk_table.num_entries = j + 1; | |
| 662 | + | |
| 663 | + for (i = 0; i < bw_params->clk_table.num_entries; i++, j--) { | |
| 664 | + bw_params->clk_table.entries[i].fclk_mhz = clock_table->DfPstateTable[j].fclk; | |
| 665 | + bw_params->clk_table.entries[i].memclk_mhz = clock_table->DfPstateTable[j].memclk; | |
| 666 | + bw_params->clk_table.entries[i].voltage = clock_table->DfPstateTable[j].voltage; | |
| 667 | + bw_params->clk_table.entries[i].dcfclk_mhz = find_dcfclk_for_voltage(clock_table, clock_table->DfPstateTable[j].voltage); | |
| 668 | + } | |
| 669 | + | |
| 670 | + bw_params->vram_type = bios_info->memory_type; | |
| 671 | + bw_params->num_channels = bios_info->ma_channel_number; | |
| 672 | + | |
| 673 | + for (i = 0; i < WM_SET_COUNT; i++) { | |
| 674 | + bw_params->wm_table.entries[i].wm_inst = i; | |
| 675 | + | |
| 676 | + if (i >= bw_params->clk_table.num_entries) { | |
| 677 | + bw_params->wm_table.entries[i].valid = false; | |
| 678 | + continue; | |
| 679 | + } | |
| 680 | + | |
| 681 | + bw_params->wm_table.entries[i].wm_type = WM_TYPE_PSTATE_CHG; | |
| 682 | + bw_params->wm_table.entries[i].valid = true; | |
| 683 | + } | |
| 684 | + | |
| 685 | + if (bw_params->vram_type == LpDdr4MemType) { | |
| 686 | + /* | |
| 687 | + * WM set D will be re-purposed for memory retraining | |
| 688 | + */ | |
| 689 | + bw_params->wm_table.entries[WM_D].pstate_latency_us = LPDDR_MEM_RETRAIN_LATENCY; | |
| 690 | + bw_params->wm_table.entries[WM_D].wm_inst = WM_D; | |
| 691 | + bw_params->wm_table.entries[WM_D].wm_type = WM_TYPE_RETRAINING; | |
| 692 | + bw_params->wm_table.entries[WM_D].valid = true; | |
| 693 | + } | |
| 694 | + | |
| 695 | +} | |
| 696 | + | |
| 697 | +/* Temporary Place holder until we can get them from fuse */ | |
| 698 | +static struct vg_dpm_clocks dummy_clocks = { | |
| 699 | + .DcfClocks = { 201, 403, 403, 403, 403, 403, 403 }, | |
| 700 | + .SocClocks = { 400, 600, 600, 600, 600, 600, 600 }, | |
| 701 | + .SocVoltage = { 2800, 2860, 2860, 2860, 2860, 2860, 2860, 2860 }, | |
| 702 | + .DfPstateTable = { | |
| 703 | + { .fclk = 400, .memclk = 400, .voltage = 2800 }, | |
| 704 | + { .fclk = 400, .memclk = 400, .voltage = 2800 }, | |
| 705 | + { .fclk = 400, .memclk = 400, .voltage = 2800 }, | |
| 706 | + { .fclk = 400, .memclk = 400, .voltage = 2800 } | |
| 707 | + } | |
| 708 | +}; | |
| 709 | + | |
| 710 | +static struct watermarks dummy_wms = { 0 }; | |
| 711 | + | |
| 712 | +static void vg_get_dpm_table_from_smu(struct clk_mgr_internal *clk_mgr, | |
| 713 | + struct smu_dpm_clks *smu_dpm_clks) | |
| 714 | +{ | |
| 715 | + struct vg_dpm_clocks *table = smu_dpm_clks->dpm_clks; | |
| 716 | + | |
| 717 | + if (!clk_mgr->smu_ver) | |
| 718 | + return; | |
| 719 | + | |
| 720 | + if (!table || smu_dpm_clks->mc_address.quad_part == 0) | |
| 721 | + return; | |
| 722 | + | |
| 723 | + memset(table, 0, sizeof(*table)); | |
| 724 | + | |
| 725 | + dcn301_smu_set_dram_addr_high(clk_mgr, | |
| 726 | + smu_dpm_clks->mc_address.high_part); | |
| 727 | + dcn301_smu_set_dram_addr_low(clk_mgr, | |
| 728 | + smu_dpm_clks->mc_address.low_part); | |
| 729 | + dcn301_smu_transfer_dpm_table_smu_2_dram(clk_mgr); | |
| 730 | +} | |
| 731 | + | |
| 732 | +void vg_clk_mgr_construct( | |
| 733 | + struct dc_context *ctx, | |
| 734 | + struct clk_mgr_internal *clk_mgr, | |
| 735 | + struct pp_smu_funcs *pp_smu, | |
| 736 | + struct dccg *dccg) | |
| 737 | +{ | |
| 738 | + struct smu_dpm_clks smu_dpm_clks = { 0 }; | |
| 739 | + | |
| 740 | + clk_mgr->base.ctx = ctx; | |
| 741 | + clk_mgr->base.funcs = &vg_funcs; | |
| 742 | + | |
| 743 | + clk_mgr->pp_smu = pp_smu; | |
| 744 | + | |
| 745 | + clk_mgr->dccg = dccg; | |
| 746 | + clk_mgr->dfs_bypass_disp_clk = 0; | |
| 747 | + | |
| 748 | + clk_mgr->dprefclk_ss_percentage = 0; | |
| 749 | + clk_mgr->dprefclk_ss_divider = 1000; | |
| 750 | + clk_mgr->ss_on_dprefclk = false; | |
| 751 | + clk_mgr->dfs_ref_freq_khz = 48000; | |
| 752 | + | |
| 753 | + clk_mgr->base.smu_wm_set.wm_set = (struct watermarks *)dm_helpers_allocate_gpu_mem( | |
| 754 | + clk_mgr->base.ctx, | |
| 755 | + DC_MEM_ALLOC_TYPE_FRAME_BUFFER, | |
| 756 | + sizeof(struct watermarks), | |
| 757 | + &clk_mgr->base.smu_wm_set.mc_address.quad_part); | |
| 758 | + | |
| 759 | + if (clk_mgr->base.smu_wm_set.wm_set == 0) { | |
| 760 | + clk_mgr->base.smu_wm_set.wm_set = &dummy_wms; | |
| 761 | + clk_mgr->base.smu_wm_set.mc_address.quad_part = 0; | |
| 762 | + } | |
| 763 | + ASSERT(clk_mgr->base.smu_wm_set.wm_set); | |
| 764 | + | |
| 765 | + smu_dpm_clks.dpm_clks = (struct vg_dpm_clocks *)dm_helpers_allocate_gpu_mem( | |
| 766 | + clk_mgr->base.ctx, | |
| 767 | + DC_MEM_ALLOC_TYPE_FRAME_BUFFER, | |
| 768 | + sizeof(struct vg_dpm_clocks), | |
| 769 | + &smu_dpm_clks.mc_address.quad_part); | |
| 770 | + | |
| 771 | + if (smu_dpm_clks.dpm_clks == NULL) { | |
| 772 | + smu_dpm_clks.dpm_clks = &dummy_clocks; | |
| 773 | + smu_dpm_clks.mc_address.quad_part = 0; | |
| 774 | + } | |
| 775 | + | |
| 776 | + ASSERT(smu_dpm_clks.dpm_clks); | |
| 777 | + | |
| 778 | + if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment)) { | |
| 779 | + vg_funcs.update_clocks = dcn2_update_clocks_fpga; | |
| 780 | + clk_mgr->base.dentist_vco_freq_khz = 3600000; | |
| 781 | + } else { | |
| 782 | + struct clk_log_info log_info = {0}; | |
| 783 | + | |
| 784 | + clk_mgr->smu_ver = dcn301_smu_get_smu_version(clk_mgr); | |
| 785 | + | |
| 786 | + if (clk_mgr->smu_ver) | |
| 787 | + clk_mgr->smu_present = true; | |
| 788 | + | |
| 789 | + /* TODO: Check we get what we expect during bringup */ | |
| 790 | + clk_mgr->base.dentist_vco_freq_khz = get_vco_frequency_from_reg(clk_mgr); | |
| 791 | + | |
| 792 | + /* in case we don't get a value from the register, use default */ | |
| 793 | + if (clk_mgr->base.dentist_vco_freq_khz == 0) | |
| 794 | + clk_mgr->base.dentist_vco_freq_khz = 3600000; | |
| 795 | + | |
| 796 | + if (ctx->dc_bios->integrated_info->memory_type == LpDdr5MemType) { | |
| 797 | + vg_bw_params.wm_table = lpddr5_wm_table; | |
| 798 | + } else { | |
| 799 | + vg_bw_params.wm_table = ddr4_wm_table; | |
| 800 | + } | |
| 801 | + /* Saved clocks configured at boot for debug purposes */ | |
| 802 | + vg_dump_clk_registers(&clk_mgr->base.boot_snapshot, &clk_mgr->base, &log_info); | |
| 803 | + } | |
| 804 | + | |
| 805 | + clk_mgr->base.dprefclk_khz = 600000; | |
| 806 | + dce_clock_read_ss_info(clk_mgr); | |
| 807 | + | |
| 808 | + clk_mgr->base.bw_params = &vg_bw_params; | |
| 809 | + | |
| 810 | + vg_get_dpm_table_from_smu(clk_mgr, &smu_dpm_clks); | |
| 811 | + if (ctx->dc_bios && ctx->dc_bios->integrated_info) { | |
| 812 | + vg_clk_mgr_helper_populate_bw_params( | |
| 813 | + clk_mgr, | |
| 814 | + ctx->dc_bios->integrated_info, | |
| 815 | + smu_dpm_clks.dpm_clks); | |
| 816 | + } | |
| 817 | + | |
| 818 | + if (smu_dpm_clks.dpm_clks && smu_dpm_clks.mc_address.quad_part != 0) | |
| 819 | + dm_helpers_free_gpu_mem(clk_mgr->base.ctx, DC_MEM_ALLOC_TYPE_FRAME_BUFFER, | |
| 820 | + smu_dpm_clks.dpm_clks); | |
| 821 | +/* | |
| 822 | + if (!IS_FPGA_MAXIMUS_DC(ctx->dce_environment) && clk_mgr->smu_ver) { | |
| 823 | + enable powerfeatures when displaycount goes to 0 | |
| 824 | + dcn301_smu_enable_phy_refclk_pwrdwn(clk_mgr, !debug->disable_48mhz_pwrdwn); | |
| 825 | + } | |
| 826 | +*/ | |
| 827 | +} | |
| 828 | + | |
| 829 | +void vg_clk_mgr_destroy(struct clk_mgr_internal *clk_mgr) | |
| 830 | +{ | |
| 831 | + if (clk_mgr->base.smu_wm_set.wm_set && clk_mgr->base.smu_wm_set.mc_address.quad_part != 0) | |
| 832 | + dm_helpers_free_gpu_mem(clk_mgr->base.ctx, DC_MEM_ALLOC_TYPE_FRAME_BUFFER, | |
| 833 | + clk_mgr->base.smu_wm_set.wm_set); | |
| 834 | +} | |
| @@ -0,0 +1,43 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2020 Advanced Micro Devices, Inc. | |
| 3 | + * | |
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a | |
| 5 | + * copy of this software and associated documentation files (the "Software"), | |
| 6 | + * to deal in the Software without restriction, including without limitation | |
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the | |
| 9 | + * Software is furnished to do so, subject to the following conditions: | |
| 10 | + * | |
| 11 | + * The above copyright notice and this permission notice shall be included in | |
| 12 | + * all copies or substantial portions of the Software. | |
| 13 | + * | |
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 17 | + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 18 | + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 19 | + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 20 | + * OTHER DEALINGS IN THE SOFTWARE. | |
| 21 | + * | |
| 22 | + * Authors: AMD | |
| 23 | + * | |
| 24 | + */ | |
| 25 | + | |
| 26 | +#ifndef __VG_CLK_MGR_H__ | |
| 27 | +#define __VG_CLK_MGR_H__ | |
| 28 | + | |
| 29 | +int vg_get_active_display_cnt_wa( | |
| 30 | + struct dc *dc, | |
| 31 | + struct dc_state *context); | |
| 32 | + | |
| 33 | +void vg_enable_pme_wa(struct clk_mgr *clk_mgr_base); | |
| 34 | + | |
| 35 | +void vg_clk_mgr_construct(struct dc_context *ctx, | |
| 36 | + struct clk_mgr_internal *clk_mgr, | |
| 37 | + struct pp_smu_funcs *pp_smu, | |
| 38 | + struct dccg *dccg); | |
| 39 | + | |
| 40 | +void vg_clk_mgr_destroy(struct clk_mgr_internal *clk_mgr); | |
| 41 | + | |
| 42 | +void vg_notify_wm_ranges(struct clk_mgr *clk_mgr_base); | |
| 43 | +#endif //__VG_CLK_MGR_H__ | |
| @@ -70,6 +70,8 @@ · 69 unmodified lines | ||
| 70 | 70 | |
| 71 | 71 | #include "dce/dmub_hw_lock_mgr.h" |
| 72 | 72 | |
| 73 | +#include "dc_trace.h" | |
| 74 | + | |
| 73 | 75 | #define CTX \ |
| 74 | 76 | dc->ctx |
| 75 | 77 | |
| @@ -344,7 +346,7 @@ bool dc_stream_get_crtc_position(struct dc *dc, · 268 unmodified lines | ||
| 344 | 346 | * calculate the crc. |
| 345 | 347 | */ |
| 346 | 348 | bool dc_stream_configure_crc(struct dc *dc, struct dc_stream_state *stream, |
| 347 | − bool enable, bool continuous) | |
| 349 | + struct crc_params *crc_window, bool enable, bool continuous) | |
| 348 | 350 | { |
| 349 | 351 | int i; |
| 350 | 352 | struct pipe_ctx *pipe; |
| @@ -360,7 +362,7 @@ bool dc_stream_configure_crc(struct dc *dc, struct dc_stream_state *stream, · 9 unmodified lines | ||
| 360 | 362 | if (i == MAX_PIPES) |
| 361 | 363 | return false; |
| 362 | 364 | |
| 363 | − /* Always capture the full frame */ | |
| 365 | + /* By default, capture the full frame */ | |
| 364 | 366 | param.windowa_x_start = 0; |
| 365 | 367 | param.windowa_y_start = 0; |
| 366 | 368 | param.windowa_x_end = pipe->stream->timing.h_addressable; |
| @@ -370,6 +372,17 @@ bool dc_stream_configure_crc(struct dc *dc, struct dc_stream_state *stream, · 3 unmodified lines | ||
| 370 | 372 | param.windowb_x_end = pipe->stream->timing.h_addressable; |
| 371 | 373 | param.windowb_y_end = pipe->stream->timing.v_addressable; |
| 372 | 374 | |
| 375 | + if (crc_window) { | |
| 376 | + param.windowa_x_start = crc_window->windowa_x_start; | |
| 377 | + param.windowa_y_start = crc_window->windowa_y_start; | |
| 378 | + param.windowa_x_end = crc_window->windowa_x_end; | |
| 379 | + param.windowa_y_end = crc_window->windowa_y_end; | |
| 380 | + param.windowb_x_start = crc_window->windowb_x_start; | |
| 381 | + param.windowb_y_start = crc_window->windowb_y_start; | |
| 382 | + param.windowb_x_end = crc_window->windowb_x_end; | |
| 383 | + param.windowb_y_end = crc_window->windowb_y_end; | |
| 384 | + } | |
| 385 | + | |
| 373 | 386 | param.dsc_mode = pipe->stream->timing.flags.DSC ? 1:0; |
| 374 | 387 | param.odm_mode = pipe->next_odm_pipe ? 1:0; |
| 375 | 388 | |
| @@ -731,7 +744,7 @@ static bool dc_construct(struct dc *dc, · 355 unmodified lines | ||
| 731 | 744 | dc->clk_mgr = dc_clk_mgr_create(dc->ctx, dc->res_pool->pp_smu, dc->res_pool->dccg); |
| 732 | 745 | if (!dc->clk_mgr) |
| 733 | 746 | goto fail; |
| 734 | −#ifdef CONFIG_DRM_AMD_DC_DCN3_0 | |
| 747 | +#ifdef CONFIG_DRM_AMD_DC_DCN | |
| 735 | 748 | dc->clk_mgr->force_smu_not_present = init_params->force_smu_not_present; |
| 736 | 749 | #endif |
| 737 | 750 | |
| @@ -763,7 +776,7 @@ fail: · 25 unmodified lines | ||
| 763 | 776 | return false; |
| 764 | 777 | } |
| 765 | 778 | |
| 766 | −static bool disable_all_writeback_pipes_for_stream( | |
| 779 | +static void disable_all_writeback_pipes_for_stream( | |
| 767 | 780 | const struct dc *dc, |
| 768 | 781 | struct dc_stream_state *stream, |
| 769 | 782 | struct dc_state *context) |
| @@ -772,8 +785,6 @@ static bool disable_all_writeback_pipes_for_stream( · 2 unmodified lines | ||
| 772 | 785 | |
| 773 | 786 | for (i = 0; i < stream->num_wb_info; i++) |
| 774 | 787 | stream->writeback_info[i].wb_enabled = false; |
| 775 | − | |
| 776 | − return true; | |
| 777 | 788 | } |
| 778 | 789 | |
| 779 | 790 | void apply_ctx_interdependent_lock(struct dc *dc, struct dc_state *context, struct dc_stream_state *stream, bool lock) |
| @@ -861,12 +872,16 @@ static void disable_vbios_mode_if_required( · 81 unmodified lines | ||
| 861 | 872 | if (stream == NULL) |
| 862 | 873 | continue; |
| 863 | 874 | |
| 875 | + // only looking for first odm pipe | |
| 876 | + if (pipe->prev_odm_pipe) | |
| 877 | + continue; | |
| 878 | + | |
| 864 | 879 | if (stream->link->local_sink && |
| 865 | 880 | stream->link->local_sink->sink_signal == SIGNAL_TYPE_EDP) { |
| 866 | 881 | link = stream->link; |
| 867 | 882 | } |
| 868 | 883 | |
| 869 | − if (link != NULL) { | |
| 884 | + if (link != NULL && link->link_enc->funcs->is_dig_enabled(link->link_enc)) { | |
| 870 | 885 | unsigned int enc_inst, tg_inst = 0; |
| 871 | 886 | unsigned int pix_clk_100hz; |
| 872 | 887 | |
| @@ -1266,16 +1281,19 @@ bool dc_validate_seamless_boot_timing(const struct dc *dc, · 393 unmodified lines | ||
| 1266 | 1281 | return false; |
| 1267 | 1282 | } |
| 1268 | 1283 | |
| 1284 | + if (link->dpcd_caps.dprx_feature.bits.VSC_SDP_COLORIMETRY_SUPPORTED) { | |
| 1285 | + return false; | |
| 1286 | + } | |
| 1287 | + | |
| 1269 | 1288 | return true; |
| 1270 | 1289 | } |
| 1271 | 1290 | |
| 1272 | −bool dc_enable_stereo( | |
| 1291 | +void dc_enable_stereo( | |
| 1273 | 1292 | struct dc *dc, |
| 1274 | 1293 | struct dc_state *context, |
| 1275 | 1294 | struct dc_stream_state *streams[], |
| 1276 | 1295 | uint8_t stream_count) |
| 1277 | 1296 | { |
| 1278 | − bool ret = true; | |
| 1279 | 1297 | int i, j; |
| 1280 | 1298 | struct pipe_ctx *pipe; |
| 1281 | 1299 | |
| @@ -1290,8 +1308,6 @@ bool dc_enable_stereo( · 8 unmodified lines | ||
| 1290 | 1308 | dc->hwss.setup_stereo(pipe, dc); |
| 1291 | 1309 | } |
| 1292 | 1310 | } |
| 1293 | − | |
| 1294 | − return ret; | |
| 1295 | 1311 | } |
| 1296 | 1312 | |
| 1297 | 1313 | void dc_trigger_sync(struct dc *dc, struct dc_state *context) |
| @@ -1327,7 +1343,7 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c · 29 unmodified lines | ||
| 1327 | 1343 | int i, k, l; |
| 1328 | 1344 | struct dc_stream_state *dc_streams[MAX_STREAMS] = {0}; |
| 1329 | 1345 | |
| 1330 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 1346 | +#if defined(CONFIG_DRM_AMD_DC_DCN) | |
| 1331 | 1347 | dc_allow_idle_optimizations(dc, false); |
| 1332 | 1348 | #endif |
| 1333 | 1349 | |
| @@ -1434,6 +1450,11 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c · 100 unmodified lines | ||
| 1434 | 1450 | dc->hwss.optimize_bandwidth(dc, context); |
| 1435 | 1451 | } |
| 1436 | 1452 | |
| 1453 | + if (dc->ctx->dce_version >= DCE_VERSION_MAX) | |
| 1454 | + TRACE_DCN_CLOCK_STATE(&context->bw_ctx.bw.dcn.clk); | |
| 1455 | + else | |
| 1456 | + TRACE_DCE_CLOCK_STATE(&context->bw_ctx.bw.dce); | |
| 1457 | + | |
| 1437 | 1458 | context->stream_mask = get_stream_mask(dc, context); |
| 1438 | 1459 | |
| 1439 | 1460 | if (context->stream_mask != dc->current_state->stream_mask) |
| @@ -1473,7 +1494,7 @@ bool dc_commit_state(struct dc *dc, struct dc_state *context) · 33 unmodified lines | ||
| 1473 | 1494 | return (result == DC_OK); |
| 1474 | 1495 | } |
| 1475 | 1496 | |
| 1476 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 1497 | +#if defined(CONFIG_DRM_AMD_DC_DCN) | |
| 1477 | 1498 | bool dc_acquire_release_mpc_3dlut( |
| 1478 | 1499 | struct dc *dc, bool acquire, |
| 1479 | 1500 | struct dc_stream_state *stream, |
| @@ -1530,18 +1551,18 @@ static bool is_flip_pending_in_pipes(struct dc *dc, struct dc_state *context) · 50 unmodified lines | ||
| 1530 | 1551 | return false; |
| 1531 | 1552 | } |
| 1532 | 1553 | |
| 1533 | −bool dc_post_update_surfaces_to_stream(struct dc *dc) | |
| 1554 | +void dc_post_update_surfaces_to_stream(struct dc *dc) | |
| 1534 | 1555 | { |
| 1535 | 1556 | int i; |
| 1536 | 1557 | struct dc_state *context = dc->current_state; |
| 1537 | 1558 | |
| 1538 | 1559 | if ((!dc->optimized_required) || dc->optimize_seamless_boot_streams > 0) |
| 1539 | − return true; | |
| 1560 | + return; | |
| 1540 | 1561 | |
| 1541 | 1562 | post_surface_trace(dc); |
| 1542 | 1563 | |
| 1543 | 1564 | if (is_flip_pending_in_pipes(dc, context)) |
| 1544 | − return true; | |
| 1565 | + return; | |
| 1545 | 1566 | |
| 1546 | 1567 | for (i = 0; i < dc->res_pool->pipe_count; i++) |
| 1547 | 1568 | if (context->res_ctx.pipe_ctx[i].stream == NULL || |
| @@ -1554,8 +1575,6 @@ bool dc_post_update_surfaces_to_stream(struct dc *dc) · 6 unmodified lines | ||
| 1554 | 1575 | |
| 1555 | 1576 | dc->optimized_required = false; |
| 1556 | 1577 | dc->wm_optimized_required = false; |
| 1557 | − | |
| 1558 | − return true; | |
| 1559 | 1578 | } |
| 1560 | 1579 | |
| 1561 | 1580 | static void init_state(struct dc *dc, struct dc_state *context) |
| @@ -1929,7 +1948,7 @@ static enum surface_update_type check_update_surfaces_for_stream( · 367 unmodified lines | ||
| 1929 | 1948 | int i; |
| 1930 | 1949 | enum surface_update_type overall_type = UPDATE_TYPE_FAST; |
| 1931 | 1950 | |
| 1932 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 1951 | +#if defined(CONFIG_DRM_AMD_DC_DCN) | |
| 1933 | 1952 | if (dc->idle_optimizations_allowed) |
| 1934 | 1953 | overall_type = UPDATE_TYPE_FULL; |
| 1935 | 1954 | |
| @@ -2383,7 +2402,6 @@ static void commit_planes_for_stream(struct dc *dc, · 447 unmodified lines | ||
| 2383 | 2402 | enum surface_update_type update_type, |
| 2384 | 2403 | struct dc_state *context) |
| 2385 | 2404 | { |
| 2386 | − bool mpcc_disconnected = false; | |
| 2387 | 2405 | int i, j; |
| 2388 | 2406 | struct pipe_ctx *top_pipe_to_program = NULL; |
| 2389 | 2407 | |
| @@ -2404,7 +2422,7 @@ static void commit_planes_for_stream(struct dc *dc, · 14 unmodified lines | ||
| 2404 | 2422 | } |
| 2405 | 2423 | |
| 2406 | 2424 | if (update_type == UPDATE_TYPE_FULL) { |
| 2407 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 2425 | +#if defined(CONFIG_DRM_AMD_DC_DCN) | |
| 2408 | 2426 | dc_allow_idle_optimizations(dc, false); |
| 2409 | 2427 | |
| 2410 | 2428 | #endif |
| @@ -2414,15 +2432,6 @@ static void commit_planes_for_stream(struct dc *dc, · 3 unmodified lines | ||
| 2414 | 2432 | context_clock_trace(dc, context); |
| 2415 | 2433 | } |
| 2416 | 2434 | |
| 2417 | − if (update_type != UPDATE_TYPE_FAST && dc->hwss.interdependent_update_lock && | |
| 2418 | − dc->hwss.disconnect_pipes && dc->hwss.wait_for_pending_cleared){ | |
| 2419 | − dc->hwss.interdependent_update_lock(dc, context, true); | |
| 2420 | − mpcc_disconnected = dc->hwss.disconnect_pipes(dc, context); | |
| 2421 | − dc->hwss.interdependent_update_lock(dc, context, false); | |
| 2422 | − if (mpcc_disconnected) | |
| 2423 | − dc->hwss.wait_for_pending_cleared(dc, context); | |
| 2424 | − } | |
| 2425 | − | |
| 2426 | 2435 | for (j = 0; j < dc->res_pool->pipe_count; j++) { |
| 2427 | 2436 | struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j]; |
| 2428 | 2437 | |
| @@ -2461,7 +2470,6 @@ static void commit_planes_for_stream(struct dc *dc, · 32 unmodified lines | ||
| 2461 | 2470 | */ |
| 2462 | 2471 | dc->hwss.pipe_control_lock(dc, top_pipe_to_program, true); |
| 2463 | 2472 | |
| 2464 | − | |
| 2465 | 2473 | // Stream updates |
| 2466 | 2474 | if (stream_update) |
| 2467 | 2475 | commit_planes_do_stream_update(dc, stream, stream_update, update_type, context); |
| @@ -2641,9 +2649,8 @@ static void commit_planes_for_stream(struct dc *dc, · 173 unmodified lines | ||
| 2641 | 2649 | for (j = 0; j < dc->res_pool->pipe_count; j++) { |
| 2642 | 2650 | struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j]; |
| 2643 | 2651 | |
| 2644 | − if (pipe_ctx->bottom_pipe || | |
| 2645 | − !pipe_ctx->stream || | |
| 2646 | − pipe_ctx->stream != stream || | |
| 2652 | + if (pipe_ctx->bottom_pipe || pipe_ctx->next_odm_pipe || | |
| 2653 | + !pipe_ctx->stream || pipe_ctx->stream != stream || | |
| 2647 | 2654 | !pipe_ctx->plane_state->update_flags.bits.addr_update) |
| 2648 | 2655 | continue; |
| 2649 | 2656 | |
| @@ -2724,6 +2731,8 @@ void dc_commit_updates_for_stream(struct dc *dc, · 74 unmodified lines | ||
| 2724 | 2731 | } |
| 2725 | 2732 | } |
| 2726 | 2733 | |
| 2734 | + TRACE_DC_PIPE_STATE(pipe_ctx, i, MAX_PIPES); | |
| 2735 | + | |
| 2727 | 2736 | commit_planes_for_stream( |
| 2728 | 2737 | dc, |
| 2729 | 2738 | srf_updates, |
| @@ -2748,9 +2757,15 @@ void dc_commit_updates_for_stream(struct dc *dc, · 18 unmodified lines | ||
| 2748 | 2757 | } |
| 2749 | 2758 | } |
| 2750 | 2759 | /*let's use current_state to update watermark etc*/ |
| 2751 | − if (update_type >= UPDATE_TYPE_FULL) | |
| 2760 | + if (update_type >= UPDATE_TYPE_FULL) { | |
| 2752 | 2761 | dc_post_update_surfaces_to_stream(dc); |
| 2753 | 2762 | |
| 2763 | + if (dc_ctx->dce_version >= DCE_VERSION_MAX) | |
| 2764 | + TRACE_DCN_CLOCK_STATE(&context->bw_ctx.bw.dcn.clk); | |
| 2765 | + else | |
| 2766 | + TRACE_DCE_CLOCK_STATE(&context->bw_ctx.bw.dce); | |
| 2767 | + } | |
| 2768 | + | |
| 2754 | 2769 | return; |
| 2755 | 2770 | |
| 2756 | 2771 | } |
| @@ -3052,7 +3067,7 @@ bool dc_set_psr_allow_active(struct dc *dc, bool enable) · 295 unmodified lines | ||
| 3052 | 3067 | return true; |
| 3053 | 3068 | } |
| 3054 | 3069 | |
| 3055 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 3070 | +#if defined(CONFIG_DRM_AMD_DC_DCN) | |
| 3056 | 3071 | |
| 3057 | 3072 | void dc_allow_idle_optimizations(struct dc *dc, bool allow) |
| 3058 | 3073 | { |
| @@ -3104,4 +3119,11 @@ bool dc_is_plane_eligible_for_idle_optimizaitons(struct dc *dc, · 45 unmodified lines | ||
| 3104 | 3119 | { |
| 3105 | 3120 | return false; |
| 3106 | 3121 | } |
| 3122 | + | |
| 3123 | +/* cleanup on driver unload */ | |
| 3124 | +void dc_hardware_release(struct dc *dc) | |
| 3125 | +{ | |
| 3126 | + if (dc->hwss.hardware_release) | |
| 3127 | + dc->hwss.hardware_release(dc); | |
| 3128 | +} | |
| 3107 | 3129 | #endif |
| @@ -418,6 +418,10 @@ char *dc_status_to_str(enum dc_status status) · 417 unmodified lines | ||
| 418 | 418 | return "Fail clk below minimum"; |
| 419 | 419 | case DC_FAIL_CLK_BELOW_CFG_REQUIRED: |
| 420 | 420 | return "Fail clk below required CFG (hard_min in PPLIB)"; |
| 421 | + case DC_NOT_SUPPORTED: | |
| 422 | + return "The operation is not supported."; | |
| 423 | + case DC_UNSUPPORTED_VALUE: | |
| 424 | + return "The value specified is not supported."; | |
| 421 | 425 | case DC_ERROR_UNEXPECTED: |
| 422 | 426 | return "Unexpected error"; |
| 423 | 427 | } |
| @@ -854,6 +854,7 @@ static bool dc_link_detect_helper(struct dc_link *link, · 853 unmodified lines | ||
| 854 | 854 | struct dpcd_caps prev_dpcd_caps; |
| 855 | 855 | bool same_dpcd = true; |
| 856 | 856 | enum dc_connection_type new_connection_type = dc_connection_none; |
| 857 | + enum dc_connection_type pre_connection_type = dc_connection_none; | |
| 857 | 858 | bool perform_dp_seamless_boot = false; |
| 858 | 859 | const uint32_t post_oui_delay = 30; // 30ms |
| 859 | 860 | |
| @@ -889,6 +890,7 @@ static bool dc_link_detect_helper(struct dc_link *link, · 29 unmodified lines | ||
| 889 | 890 | |
| 890 | 891 | link_disconnect_sink(link); |
| 891 | 892 | if (new_connection_type != dc_connection_none) { |
| 893 | + pre_connection_type = link->type; | |
| 892 | 894 | link->type = new_connection_type; |
| 893 | 895 | link->link_state_valid = false; |
| 894 | 896 | |
| @@ -962,6 +964,12 @@ static bool dc_link_detect_helper(struct dc_link *link, · 67 unmodified lines | ||
| 962 | 964 | return true; |
| 963 | 965 | } |
| 964 | 966 | |
| 967 | + // link switch from MST to non-MST stop topology manager | |
| 968 | + if (pre_connection_type == dc_connection_mst_branch && | |
| 969 | + link->type != dc_connection_mst_branch) { | |
| 970 | + dm_helpers_dp_mst_stop_top_mgr(link->ctx, link); | |
| 971 | + } | |
| 972 | + | |
| 965 | 973 | if (link->type == dc_connection_mst_branch) { |
| 966 | 974 | LINK_INFO("link=%d, mst branch is now Connected\n", |
| 967 | 975 | link->link_index); |
| @@ -2732,7 +2740,8 @@ bool dc_link_setup_psr(struct dc_link *link, · 1764 unmodified lines | ||
| 2732 | 2740 | |
| 2733 | 2741 | #if defined(CONFIG_DRM_AMD_DC_DCN) |
| 2734 | 2742 | /*skip power down the single pipe since it blocks the cstate*/ |
| 2735 | − if (ASICREV_IS_RAVEN(link->ctx->asic_id.hw_internal_rev)) | |
| 2743 | + if ((link->ctx->asic_id.chip_family == FAMILY_RV) && | |
| 2744 | + ASICREV_IS_RAVEN(link->ctx->asic_id.hw_internal_rev)) | |
| 2736 | 2745 | psr_context->psr_level.bits.SKIP_CRTC_DISABLE = true; |
| 2737 | 2746 | #endif |
| 2738 | 2747 | |
| @@ -2943,6 +2952,10 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx) · 204 unmodified lines | ||
| 2943 | 2952 | |
| 2944 | 2953 | /* slot X.Y for only current stream */ |
| 2945 | 2954 | pbn_per_slot = get_pbn_per_slot(stream); |
| 2955 | + if (pbn_per_slot.value == 0) { | |
| 2956 | + DC_LOG_ERROR("Failure: pbn_per_slot==0 not allowed. Cannot continue, returning DC_UNSUPPORTED_VALUE.\n"); | |
| 2957 | + return DC_UNSUPPORTED_VALUE; | |
| 2958 | + } | |
| 2946 | 2959 | pbn = get_pbn_from_timing(pipe_ctx); |
| 2947 | 2960 | avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot); |
| 2948 | 2961 | |
| @@ -3106,7 +3119,7 @@ void core_link_enable_stream( · 157 unmodified lines | ||
| 3106 | 3119 | struct dc *dc = pipe_ctx->stream->ctx->dc; |
| 3107 | 3120 | struct dc_stream_state *stream = pipe_ctx->stream; |
| 3108 | 3121 | enum dc_status status; |
| 3109 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 3122 | +#if defined(CONFIG_DRM_AMD_DC_DCN) | |
| 3110 | 3123 | enum otg_out_mux_dest otg_out_dest = OUT_MUX_DIO; |
| 3111 | 3124 | #endif |
| 3112 | 3125 | DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger); |
| @@ -3142,7 +3155,7 @@ void core_link_enable_stream( · 29 unmodified lines | ||
| 3142 | 3155 | |
| 3143 | 3156 | pipe_ctx->stream->link->link_state_valid = true; |
| 3144 | 3157 | |
| 3145 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 3158 | +#if defined(CONFIG_DRM_AMD_DC_DCN) | |
| 3146 | 3159 | if (pipe_ctx->stream_res.tg->funcs->set_out_mux) |
| 3147 | 3160 | pipe_ctx->stream_res.tg->funcs->set_out_mux(pipe_ctx->stream_res.tg, otg_out_dest); |
| 3148 | 3161 | #endif |
| @@ -3283,8 +3296,9 @@ void core_link_disable_stream(struct pipe_ctx *pipe_ctx) · 134 unmodified lines | ||
| 3283 | 3296 | dc_is_virtual_signal(pipe_ctx->stream->signal)) |
| 3284 | 3297 | return; |
| 3285 | 3298 | |
| 3286 | − if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) { | |
| 3287 | − core_link_set_avmute(pipe_ctx, true); | |
| 3299 | + if (!pipe_ctx->stream->sink->edid_caps.panel_patch.skip_avmute) { | |
| 3300 | + if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) | |
| 3301 | + core_link_set_avmute(pipe_ctx, true); | |
| 3288 | 3302 | } |
| 3289 | 3303 | |
| 3290 | 3304 | #if defined(CONFIG_DRM_AMD_DC_HDCP) |
| @@ -39,6 +39,7 @@ · 38 unmodified lines | ||
| 39 | 39 | |
| 40 | 40 | #define AUX_POWER_UP_WA_DELAY 500 |
| 41 | 41 | #define I2C_OVER_AUX_DEFER_WA_DELAY 70 |
| 42 | +#define I2C_OVER_AUX_DEFER_WA_DELAY_1MS 1 | |
| 42 | 43 | |
| 43 | 44 | /* CV smart dongle slave address for retrieving supported HDTV modes*/ |
| 44 | 45 | #define CV_SMART_DONGLE_ADDRESS 0x20 |
| @@ -282,11 +283,17 @@ static uint32_t defer_delay_converter_wa( · 237 unmodified lines | ||
| 282 | 283 | struct dc_link *link = ddc->link; |
| 283 | 284 | |
| 284 | 285 | if (link->dpcd_caps.branch_dev_id == DP_BRANCH_DEVICE_ID_0080E1 && |
| 285 | − !memcmp(link->dpcd_caps.branch_dev_name, | |
| 286 | − DP_DVI_CONVERTER_ID_4, | |
| 287 | − sizeof(link->dpcd_caps.branch_dev_name))) | |
| 286 | + !memcmp(link->dpcd_caps.branch_dev_name, | |
| 287 | + DP_DVI_CONVERTER_ID_4, | |
| 288 | + sizeof(link->dpcd_caps.branch_dev_name))) | |
| 288 | 289 | return defer_delay > I2C_OVER_AUX_DEFER_WA_DELAY ? |
| 289 | 290 | defer_delay : I2C_OVER_AUX_DEFER_WA_DELAY; |
| 291 | + if (link->dpcd_caps.branch_dev_id == DP_BRANCH_DEVICE_ID_006037 && | |
| 292 | + !memcmp(link->dpcd_caps.branch_dev_name, | |
| 293 | + DP_DVI_CONVERTER_ID_5, | |
| 294 | + sizeof(link->dpcd_caps.branch_dev_name))) | |
| 295 | + return defer_delay > I2C_OVER_AUX_DEFER_WA_DELAY_1MS ? | |
| 296 | + I2C_OVER_AUX_DEFER_WA_DELAY_1MS : defer_delay; | |
| 290 | 297 | |
| 291 | 298 | return defer_delay; |
| 292 | 299 | } |
| @@ -17,16 +17,16 @@ · 16 unmodified lines | ||
| 17 | 17 | |
| 18 | 18 | #define DC_LOGGER \ |
| 19 | 19 | link->ctx->logger |
| 20 | − | |
| 20 | +#define DC_TRACE_LEVEL_MESSAGE(...) /* do nothing */ | |
| 21 | 21 | |
| 22 | 22 | #define DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE 0x50 |
| 23 | 23 | |
| 24 | −/* maximum pre emphasis level allowed for each voltage swing level*/ | |
| 25 | −static const enum dc_pre_emphasis voltage_swing_to_pre_emphasis[] = { | |
| 26 | − PRE_EMPHASIS_LEVEL3, | |
| 27 | − PRE_EMPHASIS_LEVEL2, | |
| 28 | − PRE_EMPHASIS_LEVEL1, | |
| 29 | − PRE_EMPHASIS_DISABLED }; | |
| 24 | + /* maximum pre emphasis level allowed for each voltage swing level*/ | |
| 25 | + static const enum dc_pre_emphasis | |
| 26 | + voltage_swing_to_pre_emphasis[] = { PRE_EMPHASIS_LEVEL3, | |
| 27 | + PRE_EMPHASIS_LEVEL2, | |
| 28 | + PRE_EMPHASIS_LEVEL1, | |
| 29 | + PRE_EMPHASIS_DISABLED }; | |
| 30 | 30 | |
| 31 | 31 | enum { |
| 32 | 32 | POST_LT_ADJ_REQ_LIMIT = 6, |
| @@ -183,6 +183,16 @@ static void dpcd_set_link_settings( · 150 unmodified lines | ||
| 183 | 183 | if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_14 && |
| 184 | 184 | lt_settings->link_settings.use_link_rate_set == true) { |
| 185 | 185 | rate = 0; |
| 186 | + /* WA for some MUX chips that will power down with eDP and lose supported | |
| 187 | + * link rate set for eDP 1.4. Source reads DPCD 0x010 again to ensure | |
| 188 | + * MUX chip gets link rate set back before link training. | |
| 189 | + */ | |
| 190 | + if (link->connector_signal == SIGNAL_TYPE_EDP) { | |
| 191 | + uint8_t supported_link_rates[16]; | |
| 192 | + | |
| 193 | + core_link_read_dpcd(link, DP_SUPPORTED_LINK_RATES, | |
| 194 | + supported_link_rates, sizeof(supported_link_rates)); | |
| 195 | + } | |
| 186 | 196 | core_link_write_dpcd(link, DP_LINK_BW_SET, &rate, 1); |
| 187 | 197 | core_link_write_dpcd(link, DP_LINK_RATE_SET, |
| 188 | 198 | <_settings->link_settings.link_rate_set, 1); |
| @@ -3848,7 +3858,7 @@ static void set_crtc_test_pattern(struct dc_link *link, · 3659 unmodified lines | ||
| 3848 | 3858 | if (pipe_ctx->stream_res.tg->funcs->set_test_pattern) |
| 3849 | 3859 | pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg, |
| 3850 | 3860 | controller_test_pattern, color_depth); |
| 3851 | − else if (opp->funcs->opp_set_disp_pattern_generator) { | |
| 3861 | + else if (link->dc->hwss.set_disp_pattern_generator) { | |
| 3852 | 3862 | struct pipe_ctx *odm_pipe; |
| 3853 | 3863 | enum controller_dp_color_space controller_color_space; |
| 3854 | 3864 | int opp_cnt = 1; |
| @@ -3878,26 +3888,29 @@ static void set_crtc_test_pattern(struct dc_link *link, · 23 unmodified lines | ||
| 3878 | 3888 | dpg_width = width / opp_cnt; |
| 3879 | 3889 | offset = dpg_width; |
| 3880 | 3890 | |
| 3881 | − opp->funcs->opp_set_disp_pattern_generator(opp, | |
| 3882 | − controller_test_pattern, | |
| 3883 | − controller_color_space, | |
| 3884 | − color_depth, | |
| 3885 | − NULL, | |
| 3886 | − dpg_width, | |
| 3887 | − height, | |
| 3888 | − 0); | |
| 3889 | − | |
| 3890 | − for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) { | |
| 3891 | − struct output_pixel_processor *odm_opp = odm_pipe->stream_res.opp; | |
| 3892 | − odm_opp->funcs->opp_program_bit_depth_reduction(odm_opp, ¶ms); | |
| 3893 | − odm_opp->funcs->opp_set_disp_pattern_generator(odm_opp, | |
| 3891 | + link->dc->hwss.set_disp_pattern_generator(link->dc, | |
| 3892 | + pipe_ctx, | |
| 3894 | 3893 | controller_test_pattern, |
| 3895 | 3894 | controller_color_space, |
| 3896 | 3895 | color_depth, |
| 3897 | 3896 | NULL, |
| 3898 | 3897 | dpg_width, |
| 3899 | 3898 | height, |
| 3900 | − offset); | |
| 3899 | + 0); | |
| 3900 | + | |
| 3901 | + for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) { | |
| 3902 | + struct output_pixel_processor *odm_opp = odm_pipe->stream_res.opp; | |
| 3903 | + | |
| 3904 | + odm_opp->funcs->opp_program_bit_depth_reduction(odm_opp, ¶ms); | |
| 3905 | + link->dc->hwss.set_disp_pattern_generator(link->dc, | |
| 3906 | + odm_pipe, | |
| 3907 | + controller_test_pattern, | |
| 3908 | + controller_color_space, | |
| 3909 | + color_depth, | |
| 3910 | + NULL, | |
| 3911 | + dpg_width, | |
| 3912 | + height, | |
| 3913 | + offset); | |
| 3901 | 3914 | offset += offset; |
| 3902 | 3915 | } |
| 3903 | 3916 | } |
| @@ -3913,7 +3926,7 @@ static void set_crtc_test_pattern(struct dc_link *link, · 9 unmodified lines | ||
| 3913 | 3926 | pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg, |
| 3914 | 3927 | CONTROLLER_DP_TEST_PATTERN_VIDEOMODE, |
| 3915 | 3928 | color_depth); |
| 3916 | − else if (opp->funcs->opp_set_disp_pattern_generator) { | |
| 3929 | + else if (link->dc->hwss.set_disp_pattern_generator) { | |
| 3917 | 3930 | struct pipe_ctx *odm_pipe; |
| 3918 | 3931 | int opp_cnt = 1; |
| 3919 | 3932 | int dpg_width = width; |
| @@ -3926,7 +3939,18 @@ static void set_crtc_test_pattern(struct dc_link *link, · 6 unmodified lines | ||
| 3926 | 3939 | struct output_pixel_processor *odm_opp = odm_pipe->stream_res.opp; |
| 3927 | 3940 | |
| 3928 | 3941 | odm_opp->funcs->opp_program_bit_depth_reduction(odm_opp, ¶ms); |
| 3929 | − odm_opp->funcs->opp_set_disp_pattern_generator(odm_opp, | |
| 3942 | + link->dc->hwss.set_disp_pattern_generator(link->dc, | |
| 3943 | + odm_pipe, | |
| 3944 | + CONTROLLER_DP_TEST_PATTERN_VIDEOMODE, | |
| 3945 | + CONTROLLER_DP_COLOR_SPACE_UDEFINED, | |
| 3946 | + color_depth, | |
| 3947 | + NULL, | |
| 3948 | + dpg_width, | |
| 3949 | + height, | |
| 3950 | + 0); | |
| 3951 | + } | |
| 3952 | + link->dc->hwss.set_disp_pattern_generator(link->dc, | |
| 3953 | + pipe_ctx, | |
| 3930 | 3954 | CONTROLLER_DP_TEST_PATTERN_VIDEOMODE, |
| 3931 | 3955 | CONTROLLER_DP_COLOR_SPACE_UDEFINED, |
| 3932 | 3956 | color_depth, |
| @@ -3934,15 +3958,6 @@ static void set_crtc_test_pattern(struct dc_link *link, · 1 unmodified line | ||
| 3934 | 3958 | dpg_width, |
| 3935 | 3959 | height, |
| 3936 | 3960 | 0); |
| 3937 | − } | |
| 3938 | − opp->funcs->opp_set_disp_pattern_generator(opp, | |
| 3939 | − CONTROLLER_DP_TEST_PATTERN_VIDEOMODE, | |
| 3940 | − CONTROLLER_DP_COLOR_SPACE_UDEFINED, | |
| 3941 | − color_depth, | |
| 3942 | − NULL, | |
| 3943 | − dpg_width, | |
| 3944 | − height, | |
| 3945 | − 0); | |
| 3946 | 3961 | } |
| 3947 | 3962 | } |
| 3948 | 3963 | break; |
| @@ -3977,10 +3992,7 @@ bool dc_link_dp_set_test_pattern( · 28 unmodified lines | ||
| 3977 | 3992 | } |
| 3978 | 3993 | } |
| 3979 | 3994 | |
| 3980 | − /* Reset CRTC Test Pattern if it is currently running and request | |
| 3981 | − * is VideoMode Reset DP Phy Test Pattern if it is currently running | |
| 3982 | − * and request is VideoMode | |
| 3983 | − */ | |
| 3995 | + /* Reset CRTC Test Pattern if it is currently running and request is VideoMode */ | |
| 3984 | 3996 | if (link->test_pattern_enabled && test_pattern == |
| 3985 | 3997 | DP_TEST_PATTERN_VIDEO_MODE) { |
| 3986 | 3998 | /* Set CRTC Test Pattern */ |
| @@ -4230,7 +4242,7 @@ void dp_set_panel_mode(struct dc_link *link, enum dp_panel_mode panel_mode) · 243 unmodified lines | ||
| 4230 | 4242 | |
| 4231 | 4243 | if (edp_config_set.bits.PANEL_MODE_EDP |
| 4232 | 4244 | != panel_mode_edp) { |
| 4233 | − enum ddc_result result = DDC_RESULT_UNKNOWN; | |
| 4245 | + enum dc_status result = DC_ERROR_UNEXPECTED; | |
| 4234 | 4246 | |
| 4235 | 4247 | edp_config_set.bits.PANEL_MODE_EDP = |
| 4236 | 4248 | panel_mode_edp; |
| @@ -4240,7 +4252,7 @@ void dp_set_panel_mode(struct dc_link *link, enum dp_panel_mode panel_mode) · 3 unmodified lines | ||
| 4240 | 4252 | &edp_config_set.raw, |
| 4241 | 4253 | sizeof(edp_config_set.raw)); |
| 4242 | 4254 | |
| 4243 | − ASSERT(result == DDC_RESULT_SUCESSFULL); | |
| 4255 | + ASSERT(result == DC_OK); | |
| 4244 | 4256 | } |
| 4245 | 4257 | } |
| 4246 | 4258 | DC_LOG_DETECTION_DP_CAPS("Link: %d eDP panel mode supported: %d " |
| @@ -4372,6 +4384,7 @@ void dp_set_fec_enable(struct dc_link *link, bool enable) · 125 unmodified lines | ||
| 4372 | 4384 | void dpcd_set_source_specific_data(struct dc_link *link) |
| 4373 | 4385 | { |
| 4374 | 4386 | if (!link->dc->vendor_signature.is_valid) { |
| 4387 | + enum dc_status result_write_min_hblank = DC_NOT_SUPPORTED; | |
| 4375 | 4388 | struct dpcd_amd_signature amd_signature; |
| 4376 | 4389 | amd_signature.AMD_IEEE_TxSignature_byte1 = 0x0; |
| 4377 | 4390 | amd_signature.AMD_IEEE_TxSignature_byte2 = 0x0; |
| @@ -4390,6 +4403,30 @@ void dpcd_set_source_specific_data(struct dc_link *link) · 12 unmodified lines | ||
| 4390 | 4403 | (uint8_t *)(&amd_signature), |
| 4391 | 4404 | sizeof(amd_signature)); |
| 4392 | 4405 | |
| 4406 | + if (link->ctx->dce_version >= DCN_VERSION_2_0 && | |
| 4407 | + link->dc->caps.min_horizontal_blanking_period != 0) { | |
| 4408 | + | |
| 4409 | + uint8_t hblank_size = (uint8_t)link->dc->caps.min_horizontal_blanking_period; | |
| 4410 | + | |
| 4411 | + result_write_min_hblank = core_link_write_dpcd(link, | |
| 4412 | + DP_SOURCE_MINIMUM_HBLANK_SUPPORTED, (uint8_t *)(&hblank_size), | |
| 4413 | + sizeof(hblank_size)); | |
| 4414 | + } | |
| 4415 | + DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_INFORMATION, | |
| 4416 | + WPP_BIT_FLAG_DC_DETECTION_DP_CAPS, | |
| 4417 | + "result=%u link_index=%u enum dce_version=%d DPCD=0x%04X min_hblank=%u branch_dev_id=0x%x branch_dev_name='%c%c%c%c%c%c'", | |
| 4418 | + result_write_min_hblank, | |
| 4419 | + link->link_index, | |
| 4420 | + link->ctx->dce_version, | |
| 4421 | + DP_SOURCE_MINIMUM_HBLANK_SUPPORTED, | |
| 4422 | + link->dc->caps.min_horizontal_blanking_period, | |
| 4423 | + link->dpcd_caps.branch_dev_id, | |
| 4424 | + link->dpcd_caps.branch_dev_name[0], | |
| 4425 | + link->dpcd_caps.branch_dev_name[1], | |
| 4426 | + link->dpcd_caps.branch_dev_name[2], | |
| 4427 | + link->dpcd_caps.branch_dev_name[3], | |
| 4428 | + link->dpcd_caps.branch_dev_name[4], | |
| 4429 | + link->dpcd_caps.branch_dev_name[5]); | |
| 4393 | 4430 | } else { |
| 4394 | 4431 | core_link_write_dpcd(link, DP_SOURCE_OUI, |
| 4395 | 4432 | link->dc->vendor_signature.data.raw, |
| @@ -156,6 +156,13 @@ void dp_enable_link_phy( · 155 unmodified lines | ||
| 156 | 156 | dp_receiver_power_ctrl(link, true); |
| 157 | 157 | } |
| 158 | 158 | |
| 159 | +void edp_add_delay_for_T9(struct dc_link *link) | |
| 160 | +{ | |
| 161 | + if (link->local_sink && | |
| 162 | + link->local_sink->edid_caps.panel_patch.extra_delay_backlight_off > 0) | |
| 163 | + udelay(link->local_sink->edid_caps.panel_patch.extra_delay_backlight_off * 1000); | |
| 164 | +} | |
| 165 | + | |
| 159 | 166 | bool edp_receiver_ready_T9(struct dc_link *link) |
| 160 | 167 | { |
| 161 | 168 | unsigned int tries = 0; |
| @@ -165,7 +172,7 @@ bool edp_receiver_ready_T9(struct dc_link *link) · 3 unmodified lines | ||
| 165 | 172 | |
| 166 | 173 | result = core_link_read_dpcd(link, DP_EDP_DPCD_REV, &edpRev, sizeof(edpRev)); |
| 167 | 174 | |
| 168 | − /* start from eDP version 1.2, SINK_STAUS indicate the sink is ready.*/ | |
| 175 | + /* start from eDP version 1.2, SINK_STAUS indicate the sink is ready.*/ | |
| 169 | 176 | if (result == DC_OK && edpRev >= DP_EDP_12) { |
| 170 | 177 | do { |
| 171 | 178 | sinkstatus = 1; |
| @@ -178,10 +185,6 @@ bool edp_receiver_ready_T9(struct dc_link *link) · 6 unmodified lines | ||
| 178 | 185 | } while (++tries < 50); |
| 179 | 186 | } |
| 180 | 187 | |
| 181 | − if (link->local_sink && | |
| 182 | − link->local_sink->edid_caps.panel_patch.extra_delay_backlight_off > 0) | |
| 183 | − udelay(link->local_sink->edid_caps.panel_patch.extra_delay_backlight_off * 1000); | |
| 184 | − | |
| 185 | 188 | return result; |
| 186 | 189 | } |
| 187 | 190 | bool edp_receiver_ready_T7(struct dc_link *link) |
| @@ -54,9 +54,9 @@ · 53 unmodified lines | ||
| 54 | 54 | #include "dcn10/dcn10_resource.h" |
| 55 | 55 | #include "dcn20/dcn20_resource.h" |
| 56 | 56 | #include "dcn21/dcn21_resource.h" |
| 57 | −#endif | |
| 58 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 59 | −#include "../dcn30/dcn30_resource.h" | |
| 57 | +#include "dcn30/dcn30_resource.h" | |
| 58 | +#include "dcn301/dcn301_resource.h" | |
| 59 | +#include "dcn302/dcn302_resource.h" | |
| 60 | 60 | #endif |
| 61 | 61 | |
| 62 | 62 | #define DC_LOGGER_INIT(logger) |
| @@ -120,16 +120,22 @@ enum dce_version resource_parse_asic_id(struct hw_asic_id asic_id) · 57 unmodified lines | ||
| 120 | 120 | dc_version = DCN_VERSION_1_01; |
| 121 | 121 | if (ASICREV_IS_RENOIR(asic_id.hw_internal_rev)) |
| 122 | 122 | dc_version = DCN_VERSION_2_1; |
| 123 | + if (ASICREV_IS_GREEN_SARDINE(asic_id.hw_internal_rev)) | |
| 124 | + dc_version = DCN_VERSION_2_1; | |
| 123 | 125 | break; |
| 124 | −#endif | |
| 125 | 126 | |
| 126 | 127 | case FAMILY_NV: |
| 127 | 128 | dc_version = DCN_VERSION_2_0; |
| 128 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 129 | 129 | if (ASICREV_IS_SIENNA_CICHLID_P(asic_id.hw_internal_rev)) |
| 130 | 130 | dc_version = DCN_VERSION_3_0; |
| 131 | −#endif | |
| 131 | + if (ASICREV_IS_DIMGREY_CAVEFISH_P(asic_id.hw_internal_rev)) | |
| 132 | + dc_version = DCN_VERSION_3_02; | |
| 132 | 133 | break; |
| 134 | + | |
| 135 | + case FAMILY_VGH: | |
| 136 | + dc_version = DCN_VERSION_3_01; | |
| 137 | + break; | |
| 138 | +#endif | |
| 133 | 139 | default: |
| 134 | 140 | dc_version = DCE_VERSION_UNKNOWN; |
| 135 | 141 | break; |
| @@ -195,21 +201,22 @@ struct resource_pool *dc_create_resource_pool(struct dc *dc, · 59 unmodified lines | ||
| 195 | 201 | case DCN_VERSION_1_01: |
| 196 | 202 | res_pool = dcn10_create_resource_pool(init_data, dc); |
| 197 | 203 | break; |
| 198 | − | |
| 199 | − | |
| 200 | 204 | case DCN_VERSION_2_0: |
| 201 | 205 | res_pool = dcn20_create_resource_pool(init_data, dc); |
| 202 | 206 | break; |
| 203 | 207 | case DCN_VERSION_2_1: |
| 204 | 208 | res_pool = dcn21_create_resource_pool(init_data, dc); |
| 205 | 209 | break; |
| 206 | −#endif | |
| 207 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 208 | 210 | case DCN_VERSION_3_0: |
| 209 | 211 | res_pool = dcn30_create_resource_pool(init_data, dc); |
| 210 | 212 | break; |
| 213 | + case DCN_VERSION_3_01: | |
| 214 | + res_pool = dcn301_create_resource_pool(init_data, dc); | |
| 215 | + break; | |
| 216 | + case DCN_VERSION_3_02: | |
| 217 | + res_pool = dcn302_create_resource_pool(init_data, dc); | |
| 218 | + break; | |
| 211 | 219 | #endif |
| 212 | − | |
| 213 | 220 | default: |
| 214 | 221 | break; |
| 215 | 222 | } |
| @@ -323,7 +330,7 @@ bool resource_construct( · 107 unmodified lines | ||
| 323 | 330 | } |
| 324 | 331 | } |
| 325 | 332 | |
| 326 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 333 | +#if defined(CONFIG_DRM_AMD_DC_DCN) | |
| 327 | 334 | for (i = 0; i < caps->num_mpc_3dlut; i++) { |
| 328 | 335 | pool->mpc_lut[i] = dc_create_3dlut_func(); |
| 329 | 336 | if (pool->mpc_lut[i] == NULL) |
| @@ -794,6 +801,8 @@ static void calculate_recout(struct pipe_ctx *pipe_ctx) · 464 unmodified lines | ||
| 794 | 801 | } else |
| 795 | 802 | data->recout.x = 0; |
| 796 | 803 | |
| 804 | + if (stream->src.x > surf_clip.x) | |
| 805 | + surf_clip.width -= stream->src.x - surf_clip.x; | |
| 797 | 806 | data->recout.width = surf_clip.width * stream->dst.width / stream->src.width; |
| 798 | 807 | if (data->recout.width + data->recout.x > stream->dst.x + stream->dst.width) |
| 799 | 808 | data->recout.width = stream->dst.x + stream->dst.width - data->recout.x; |
| @@ -802,6 +811,8 @@ static void calculate_recout(struct pipe_ctx *pipe_ctx) · 2 unmodified lines | ||
| 802 | 811 | if (stream->src.y < surf_clip.y) |
| 803 | 812 | data->recout.y += (surf_clip.y - stream->src.y) * stream->dst.height |
| 804 | 813 | / stream->src.height; |
| 814 | + else if (stream->src.y > surf_clip.y) | |
| 815 | + surf_clip.height -= stream->src.y - surf_clip.y; | |
| 805 | 816 | |
| 806 | 817 | data->recout.height = surf_clip.height * stream->dst.height / stream->src.height; |
| 807 | 818 | if (data->recout.height + data->recout.y > stream->dst.y + stream->dst.height) |
| @@ -1479,6 +1490,14 @@ bool dc_add_plane_to_context( · 671 unmodified lines | ||
| 1479 | 1490 | free_pipe->clock_source = tail_pipe->clock_source; |
| 1480 | 1491 | free_pipe->top_pipe = tail_pipe; |
| 1481 | 1492 | tail_pipe->bottom_pipe = free_pipe; |
| 1493 | + if (!free_pipe->next_odm_pipe && tail_pipe->next_odm_pipe && tail_pipe->next_odm_pipe->bottom_pipe) { | |
| 1494 | + free_pipe->next_odm_pipe = tail_pipe->next_odm_pipe->bottom_pipe; | |
| 1495 | + tail_pipe->next_odm_pipe->bottom_pipe->prev_odm_pipe = free_pipe; | |
| 1496 | + } | |
| 1497 | + if (!free_pipe->prev_odm_pipe && tail_pipe->prev_odm_pipe && tail_pipe->prev_odm_pipe->bottom_pipe) { | |
| 1498 | + free_pipe->prev_odm_pipe = tail_pipe->prev_odm_pipe->bottom_pipe; | |
| 1499 | + tail_pipe->prev_odm_pipe->bottom_pipe->next_odm_pipe = free_pipe; | |
| 1500 | + } | |
| 1482 | 1501 | } |
| 1483 | 1502 | head_pipe = head_pipe->next_odm_pipe; |
| 1484 | 1503 | } |
| @@ -2128,7 +2147,7 @@ enum dc_status resource_map_pool_resources( · 643 unmodified lines | ||
| 2128 | 2147 | |
| 2129 | 2148 | /* Add ABM to the resource if on EDP */ |
| 2130 | 2149 | if (pipe_ctx->stream && dc_is_embedded_signal(pipe_ctx->stream->signal)) { |
| 2131 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 2150 | +#if defined(CONFIG_DRM_AMD_DC_DCN) | |
| 2132 | 2151 | if (pool->abm) |
| 2133 | 2152 | pipe_ctx->stream_res.abm = pool->abm; |
| 2134 | 2153 | else |
| @@ -2953,7 +2972,7 @@ unsigned int resource_pixel_format_to_bpp(enum surface_pixel_format format) · 818 unmodified lines | ||
| 2953 | 2972 | case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010: |
| 2954 | 2973 | case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010: |
| 2955 | 2974 | case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS: |
| 2956 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 2975 | +#if defined(CONFIG_DRM_AMD_DC_DCN) | |
| 2957 | 2976 | case SURFACE_PIXEL_FORMAT_GRPH_RGBE: |
| 2958 | 2977 | case SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA: |
| 2959 | 2978 | #endif |
| @@ -54,7 +54,6 @@ static bool dc_sink_construct(struct dc_sink *sink, const struct dc_sink_init_da · 53 unmodified lines | ||
| 54 | 54 | sink->ctx = link->ctx; |
| 55 | 55 | sink->dongle_max_pix_clk = init_params->dongle_max_pix_clk; |
| 56 | 56 | sink->converter_disable_audio = init_params->converter_disable_audio; |
| 57 | − sink->is_mst_legacy = init_params->sink_is_legacy; | |
| 58 | 57 | sink->dc_container_id = NULL; |
| 59 | 58 | sink->sink_id = init_params->link->ctx->dc_sink_id_count; |
| 60 | 59 | // increment dc_sink_id_count because we don't want two sinks with same ID |
| @@ -272,7 +272,7 @@ bool dc_stream_set_cursor_attributes( · 271 unmodified lines | ||
| 272 | 272 | struct dc *dc; |
| 273 | 273 | struct resource_context *res_ctx; |
| 274 | 274 | struct pipe_ctx *pipe_to_program = NULL; |
| 275 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 275 | +#if defined(CONFIG_DRM_AMD_DC_DCN) | |
| 276 | 276 | bool reset_idle_optimizations = false; |
| 277 | 277 | #endif |
| 278 | 278 | |
| @@ -294,7 +294,7 @@ bool dc_stream_set_cursor_attributes( · 15 unmodified lines | ||
| 294 | 294 | res_ctx = &dc->current_state->res_ctx; |
| 295 | 295 | stream->cursor_attributes = *attributes; |
| 296 | 296 | |
| 297 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 297 | +#if defined(CONFIG_DRM_AMD_DC_DCN) | |
| 298 | 298 | /* disable idle optimizations while updating cursor */ |
| 299 | 299 | if (dc->idle_optimizations_allowed) { |
| 300 | 300 | dc_allow_idle_optimizations(dc, false); |
| @@ -322,7 +322,7 @@ bool dc_stream_set_cursor_attributes( · 21 unmodified lines | ||
| 322 | 322 | if (pipe_to_program) |
| 323 | 323 | dc->hwss.cursor_lock(dc, pipe_to_program, false); |
| 324 | 324 | |
| 325 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 325 | +#if defined(CONFIG_DRM_AMD_DC_DCN) | |
| 326 | 326 | /* re-enable idle optimizations if necessary */ |
| 327 | 327 | if (reset_idle_optimizations) |
| 328 | 328 | dc_allow_idle_optimizations(dc, true); |
| @@ -339,7 +339,7 @@ bool dc_stream_set_cursor_position( · 10 unmodified lines | ||
| 339 | 339 | struct dc *dc; |
| 340 | 340 | struct resource_context *res_ctx; |
| 341 | 341 | struct pipe_ctx *pipe_to_program = NULL; |
| 342 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 342 | +#if defined(CONFIG_DRM_AMD_DC_DCN) | |
| 343 | 343 | bool reset_idle_optimizations = false; |
| 344 | 344 | #endif |
| 345 | 345 | |
| @@ -355,7 +355,7 @@ bool dc_stream_set_cursor_position( · 9 unmodified lines | ||
| 355 | 355 | |
| 356 | 356 | dc = stream->ctx->dc; |
| 357 | 357 | res_ctx = &dc->current_state->res_ctx; |
| 358 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 358 | +#if defined(CONFIG_DRM_AMD_DC_DCN) | |
| 359 | 359 | |
| 360 | 360 | /* disable idle optimizations if enabling cursor */ |
| 361 | 361 | if (dc->idle_optimizations_allowed && !stream->cursor_position.enable && position->enable) { |
| @@ -387,7 +387,7 @@ bool dc_stream_set_cursor_position( · 25 unmodified lines | ||
| 387 | 387 | if (pipe_to_program) |
| 388 | 388 | dc->hwss.cursor_lock(dc, pipe_to_program, false); |
| 389 | 389 | |
| 390 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 390 | +#if defined(CONFIG_DRM_AMD_DC_DCN) | |
| 391 | 391 | /* re-enable idle optimizations if necessary */ |
| 392 | 392 | if (reset_idle_optimizations) |
| 393 | 393 | dc_allow_idle_optimizations(dc, true); |
| @@ -42,7 +42,7 @@ · 41 unmodified lines | ||
| 42 | 42 | #include "inc/hw/dmcu.h" |
| 43 | 43 | #include "dml/display_mode_lib.h" |
| 44 | 44 | |
| 45 | −#define DC_VER "3.2.104" | |
| 45 | +#define DC_VER "3.2.110" | |
| 46 | 46 | |
| 47 | 47 | #define MAX_SURFACES 3 |
| 48 | 48 | #define MAX_PLANES 6 |
| @@ -152,9 +152,11 @@ struct dc_caps { · 103 unmodified lines | ||
| 152 | 152 | uint32_t max_planes; |
| 153 | 153 | uint32_t max_downscale_ratio; |
| 154 | 154 | uint32_t i2c_speed_in_khz; |
| 155 | + uint32_t i2c_speed_in_khz_hdcp; | |
| 155 | 156 | uint32_t dmdata_alloc_size; |
| 156 | 157 | unsigned int max_cursor_size; |
| 157 | 158 | unsigned int max_video_width; |
| 159 | + unsigned int min_horizontal_blanking_period; | |
| 158 | 160 | int linear_pitch_alignment; |
| 159 | 161 | bool dcc_const_color; |
| 160 | 162 | bool dynamic_audio; |
| @@ -189,7 +191,7 @@ struct dc_dcc_setting { · 28 unmodified lines | ||
| 189 | 191 | unsigned int max_compressed_blk_size; |
| 190 | 192 | unsigned int max_uncompressed_blk_size; |
| 191 | 193 | bool independent_64b_blks; |
| 192 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 194 | +#if defined(CONFIG_DRM_AMD_DC_DCN) | |
| 193 | 195 | //These bitfields to be used starting with DCN 3.0 |
| 194 | 196 | struct { |
| 195 | 197 | uint32_t dcc_256_64_64 : 1;//available in ASICs before DCN 3.0 (the worst compression case) |
| @@ -290,7 +292,7 @@ struct dc_config { · 94 unmodified lines | ||
| 290 | 292 | bool multi_mon_pp_mclk_switch; |
| 291 | 293 | bool disable_dmcu; |
| 292 | 294 | bool enable_4to1MPC; |
| 293 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 295 | +#if defined(CONFIG_DRM_AMD_DC_DCN) | |
| 294 | 296 | bool clamp_min_dcfclk; |
| 295 | 297 | #endif |
| 296 | 298 | }; |
| @@ -412,6 +414,14 @@ struct dc_bw_validation_profile { · 115 unmodified lines | ||
| 412 | 414 | } \ |
| 413 | 415 | } |
| 414 | 416 | |
| 417 | +union mem_low_power_enable_options { | |
| 418 | + struct { | |
| 419 | + bool mpc: 1; | |
| 420 | + bool optc: 1; | |
| 421 | + } bits; | |
| 422 | + uint32_t u32All; | |
| 423 | +}; | |
| 424 | + | |
| 415 | 425 | struct dc_debug_options { |
| 416 | 426 | enum visual_confirm visual_confirm; |
| 417 | 427 | bool sanity_checks; |
| @@ -472,14 +482,14 @@ struct dc_debug_options { · 54 unmodified lines | ||
| 472 | 482 | bool edid_read_retry_times; |
| 473 | 483 | bool remove_disconnect_edp; |
| 474 | 484 | unsigned int force_odm_combine; //bit vector based on otg inst |
| 475 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 485 | +#if defined(CONFIG_DRM_AMD_DC_DCN) | |
| 476 | 486 | unsigned int force_odm_combine_4to1; //bit vector based on otg inst |
| 477 | 487 | #endif |
| 478 | 488 | unsigned int force_fclk_khz; |
| 479 | 489 | bool enable_tri_buf; |
| 480 | 490 | bool dmub_offload_enabled; |
| 481 | 491 | bool dmcub_emulation; |
| 482 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 492 | +#if defined(CONFIG_DRM_AMD_DC_DCN) | |
| 483 | 493 | bool disable_idle_power_optimizations; |
| 484 | 494 | #endif |
| 485 | 495 | bool dmub_command_table; /* for testing only */ |
| @@ -490,7 +500,7 @@ struct dc_debug_options { · 4 unmodified lines | ||
| 490 | 500 | * watermarks are not affected. |
| 491 | 501 | */ |
| 492 | 502 | unsigned int force_min_dcfclk_mhz; |
| 493 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 503 | +#if defined(CONFIG_DRM_AMD_DC_DCN) | |
| 494 | 504 | int dwb_fi_phase; |
| 495 | 505 | #endif |
| 496 | 506 | bool disable_timing_sync; |
| @@ -504,6 +514,7 @@ struct dc_debug_options { · 7 unmodified lines | ||
| 504 | 514 | bool disable_dsc; |
| 505 | 515 | bool enable_dram_clock_change_one_display_vactive; |
| 506 | 516 | bool force_ignore_link_settings; |
| 517 | + union mem_low_power_enable_options enable_mem_low_power; | |
| 507 | 518 | }; |
| 508 | 519 | |
| 509 | 520 | struct dc_debug_data { |
| @@ -599,7 +610,7 @@ struct dc { · 89 unmodified lines | ||
| 599 | 610 | /* Require to optimize clocks and bandwidth for added/removed planes */ |
| 600 | 611 | bool optimized_required; |
| 601 | 612 | bool wm_optimized_required; |
| 602 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 613 | +#if defined(CONFIG_DRM_AMD_DC_DCN) | |
| 603 | 614 | bool idle_optimizations_allowed; |
| 604 | 615 | #endif |
| 605 | 616 | |
| @@ -658,7 +669,7 @@ struct dc_init_data { · 52 unmodified lines | ||
| 658 | 669 | */ |
| 659 | 670 | const struct gpu_info_soc_bounding_box_v1_0 *soc_bounding_box; |
| 660 | 671 | struct dpcd_vendor_signature vendor_signature; |
| 661 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 672 | +#if defined(CONFIG_DRM_AMD_DC_DCN) | |
| 662 | 673 | bool force_smu_not_present; |
| 663 | 674 | #endif |
| 664 | 675 | bool force_ignore_link_settings; |
| @@ -853,7 +864,7 @@ struct dc_plane_state { · 188 unmodified lines | ||
| 853 | 864 | struct dc_transfer_func *in_shaper_func; |
| 854 | 865 | struct dc_transfer_func *blend_tf; |
| 855 | 866 | |
| 856 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 867 | +#if defined(CONFIG_DRM_AMD_DC_DCN) | |
| 857 | 868 | struct dc_transfer_func *gamcor_tf; |
| 858 | 869 | #endif |
| 859 | 870 | enum surface_pixel_format format; |
| @@ -962,7 +973,7 @@ struct dc_flip_addrs { · 102 unmodified lines | ||
| 962 | 973 | bool triplebuffer_flips; |
| 963 | 974 | }; |
| 964 | 975 | |
| 965 | −bool dc_post_update_surfaces_to_stream( | |
| 976 | +void dc_post_update_surfaces_to_stream( | |
| 966 | 977 | struct dc *dc); |
| 967 | 978 | |
| 968 | 979 | #include "dc_stream.h" |
| @@ -1001,7 +1012,7 @@ void dc_resource_state_construct( · 32 unmodified lines | ||
| 1001 | 1012 | const struct dc *dc, |
| 1002 | 1013 | struct dc_state *dst_ctx); |
| 1003 | 1014 | |
| 1004 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 1015 | +#if defined(CONFIG_DRM_AMD_DC_DCN) | |
| 1005 | 1016 | bool dc_acquire_release_mpc_3dlut( |
| 1006 | 1017 | struct dc *dc, bool acquire, |
| 1007 | 1018 | struct dc_stream_state *stream, |
| @@ -1129,7 +1140,7 @@ struct hdcp_caps { · 121 unmodified lines | ||
| 1129 | 1140 | |
| 1130 | 1141 | #include "dc_link.h" |
| 1131 | 1142 | |
| 1132 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 1143 | +#if defined(CONFIG_DRM_AMD_DC_DCN) | |
| 1133 | 1144 | uint32_t dc_get_opp_for_plane(struct dc *dc, struct dc_plane_state *plane); |
| 1134 | 1145 | |
| 1135 | 1146 | #endif |
| @@ -1173,7 +1184,7 @@ struct dc_sink { · 37 unmodified lines | ||
| 1173 | 1184 | void *priv; |
| 1174 | 1185 | struct stereo_3d_features features_3d[TIMING_3D_FORMAT_MAX]; |
| 1175 | 1186 | bool converter_disable_audio; |
| 1176 | − bool is_mst_legacy; | |
| 1187 | + | |
| 1177 | 1188 | struct dc_sink_dsc_caps dsc_caps; |
| 1178 | 1189 | struct dc_sink_fec_caps fec_caps; |
| 1179 | 1190 | |
| @@ -1200,7 +1211,6 @@ struct dc_sink_init_data { · 20 unmodified lines | ||
| 1200 | 1211 | struct dc_link *link; |
| 1201 | 1212 | uint32_t dongle_max_pix_clk; |
| 1202 | 1213 | bool converter_disable_audio; |
| 1203 | − bool sink_is_legacy; | |
| 1204 | 1214 | }; |
| 1205 | 1215 | |
| 1206 | 1216 | struct dc_sink *dc_sink_create(const struct dc_sink_init_data *init_params); |
| @@ -1248,7 +1258,7 @@ bool dc_is_dmcu_initialized(struct dc *dc); · 41 unmodified lines | ||
| 1248 | 1258 | |
| 1249 | 1259 | enum dc_status dc_set_clock(struct dc *dc, enum dc_clock_type clock_type, uint32_t clk_khz, uint32_t stepping); |
| 1250 | 1260 | void dc_get_clock(struct dc *dc, enum dc_clock_type clock_type, struct dc_clock_config *clock_cfg); |
| 1251 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 1261 | +#if defined(CONFIG_DRM_AMD_DC_DCN) | |
| 1252 | 1262 | |
| 1253 | 1263 | bool dc_is_plane_eligible_for_idle_optimizations(struct dc *dc, |
| 1254 | 1264 | struct dc_plane_state *plane); |
| @@ -1267,6 +1277,9 @@ void dc_unlock_memory_clock_frequency(struct dc *dc); · 12 unmodified lines | ||
| 1267 | 1277 | */ |
| 1268 | 1278 | void dc_lock_memory_clock_frequency(struct dc *dc); |
| 1269 | 1279 | |
| 1280 | +/* cleanup on driver unload */ | |
| 1281 | +void dc_hardware_release(struct dc *dc); | |
| 1282 | + | |
| 1270 | 1283 | #endif |
| 1271 | 1284 | |
| 1272 | 1285 | bool dc_set_psr_allow_active(struct dc *dc, bool enable); |
| @@ -61,9 +61,9 @@ bool dc_dsc_parse_dsc_dpcd(const struct dc *dc, · 60 unmodified lines | ||
| 61 | 61 | |
| 62 | 62 | bool dc_dsc_compute_bandwidth_range( |
| 63 | 63 | const struct display_stream_compressor *dsc, |
| 64 | − const uint32_t dsc_min_slice_height_override, | |
| 65 | − const uint32_t min_bpp, | |
| 66 | − const uint32_t max_bpp, | |
| 64 | + uint32_t dsc_min_slice_height_override, | |
| 65 | + uint32_t min_bpp, | |
| 66 | + uint32_t max_bpp, | |
| 67 | 67 | const struct dsc_dec_dpcd_caps *dsc_sink_caps, |
| 68 | 68 | const struct dc_crtc_timing *timing, |
| 69 | 69 | struct dc_dsc_bw_range *range); |
| @@ -71,12 +71,14 @@ bool dc_dsc_compute_bandwidth_range( · 1 unmodified line | ||
| 71 | 71 | bool dc_dsc_compute_config( |
| 72 | 72 | const struct display_stream_compressor *dsc, |
| 73 | 73 | const struct dsc_dec_dpcd_caps *dsc_sink_caps, |
| 74 | − const uint32_t dsc_min_slice_height_override, | |
| 74 | + uint32_t dsc_min_slice_height_override, | |
| 75 | + uint32_t max_target_bpp_limit_override, | |
| 75 | 76 | uint32_t target_bandwidth_kbps, |
| 76 | 77 | const struct dc_crtc_timing *timing, |
| 77 | 78 | struct dc_dsc_config *dsc_cfg); |
| 78 | 79 | |
| 79 | 80 | void dc_dsc_get_policy_for_timing(const struct dc_crtc_timing *timing, |
| 81 | + uint32_t max_target_bpp_limit_override, | |
| 80 | 82 | struct dc_dsc_policy *policy); |
| 81 | 83 | |
| 82 | 84 | void dc_dsc_policy_set_max_target_bpp_limit(uint32_t limit); |
| @@ -296,32 +296,6 @@ uint32_t generic_reg_set_ex(const struct dc_context *ctx, · 295 unmodified lines | ||
| 296 | 296 | return reg_val; |
| 297 | 297 | } |
| 298 | 298 | |
| 299 | −uint32_t dm_read_reg_func( | |
| 300 | − const struct dc_context *ctx, | |
| 301 | − uint32_t address, | |
| 302 | − const char *func_name) | |
| 303 | −{ | |
| 304 | − uint32_t value; | |
| 305 | −#ifdef DM_CHECK_ADDR_0 | |
| 306 | − if (address == 0) { | |
| 307 | − DC_ERR("invalid register read; address = 0\n"); | |
| 308 | − return 0; | |
| 309 | − } | |
| 310 | −#endif | |
| 311 | − | |
| 312 | − if (ctx->dmub_srv && | |
| 313 | − ctx->dmub_srv->reg_helper_offload.gather_in_progress && | |
| 314 | − !ctx->dmub_srv->reg_helper_offload.should_burst_write) { | |
| 315 | − ASSERT(false); | |
| 316 | − return 0; | |
| 317 | − } | |
| 318 | − | |
| 319 | − value = cgs_read_register(ctx->cgs_device, address); | |
| 320 | − trace_amdgpu_dc_rreg(&ctx->perf_trace->read_count, address, value); | |
| 321 | − | |
| 322 | − return value; | |
| 323 | −} | |
| 324 | − | |
| 325 | 299 | uint32_t generic_reg_get(const struct dc_context *ctx, uint32_t addr, |
| 326 | 300 | uint8_t shift, uint32_t mask, uint32_t *field_value) |
| 327 | 301 | { |
| @@ -62,9 +62,7 @@ enum dc_plane_addr_type { · 61 unmodified lines | ||
| 62 | 62 | PLN_ADDR_TYPE_GRAPHICS = 0, |
| 63 | 63 | PLN_ADDR_TYPE_GRPH_STEREO, |
| 64 | 64 | PLN_ADDR_TYPE_VIDEO_PROGRESSIVE, |
| 65 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 66 | 65 | PLN_ADDR_TYPE_RGBEA |
| 67 | −#endif | |
| 68 | 66 | }; |
| 69 | 67 | |
| 70 | 68 | struct dc_plane_address { |
| @@ -87,7 +85,6 @@ struct dc_plane_address { · 16 unmodified lines | ||
| 87 | 85 | PHYSICAL_ADDRESS_LOC right_meta_addr; |
| 88 | 86 | union large_integer right_dcc_const_color; |
| 89 | 87 | |
| 90 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 91 | 88 | PHYSICAL_ADDRESS_LOC left_alpha_addr; |
| 92 | 89 | PHYSICAL_ADDRESS_LOC left_alpha_meta_addr; |
| 93 | 90 | union large_integer left_alpha_dcc_const_color; |
| @@ -95,7 +92,6 @@ struct dc_plane_address { · 1 unmodified line | ||
| 95 | 92 | PHYSICAL_ADDRESS_LOC right_alpha_addr; |
| 96 | 93 | PHYSICAL_ADDRESS_LOC right_alpha_meta_addr; |
| 97 | 94 | union large_integer right_alpha_dcc_const_color; |
| 98 | −#endif | |
| 99 | 95 | |
| 100 | 96 | } grph_stereo; |
| 101 | 97 | |
| @@ -110,7 +106,6 @@ struct dc_plane_address { · 8 unmodified lines | ||
| 110 | 106 | union large_integer chroma_dcc_const_color; |
| 111 | 107 | } video_progressive; |
| 112 | 108 | |
| 113 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 114 | 109 | struct { |
| 115 | 110 | PHYSICAL_ADDRESS_LOC addr; |
| 116 | 111 | PHYSICAL_ADDRESS_LOC meta_addr; |
| @@ -120,7 +115,6 @@ struct dc_plane_address { · 3 unmodified lines | ||
| 120 | 115 | PHYSICAL_ADDRESS_LOC alpha_meta_addr; |
| 121 | 116 | union large_integer alpha_dcc_const_color; |
| 122 | 117 | } rgbea; |
| 123 | −#endif | |
| 124 | 118 | }; |
| 125 | 119 | |
| 126 | 120 | union large_integer page_table_base; |
| @@ -156,15 +150,11 @@ struct dc_plane_dcc_param { · 29 unmodified lines | ||
| 156 | 150 | |
| 157 | 151 | int meta_pitch; |
| 158 | 152 | bool independent_64b_blks; |
| 159 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 160 | 153 | uint8_t dcc_ind_blk; |
| 161 | −#endif | |
| 162 | 154 | |
| 163 | 155 | int meta_pitch_c; |
| 164 | 156 | bool independent_64b_blks_c; |
| 165 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 166 | 157 | uint8_t dcc_ind_blk_c; |
| 167 | −#endif | |
| 168 | 158 | }; |
| 169 | 159 | |
| 170 | 160 | /*Displayable pixel format in fb*/ |
| @@ -200,10 +190,8 @@ enum surface_pixel_format { · 29 unmodified lines | ||
| 200 | 190 | SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FIX, |
| 201 | 191 | SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FLOAT, |
| 202 | 192 | SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FLOAT, |
| 203 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 204 | 193 | SURFACE_PIXEL_FORMAT_GRPH_RGBE, |
| 205 | 194 | SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA, |
| 206 | −#endif | |
| 207 | 195 | SURFACE_PIXEL_FORMAT_VIDEO_BEGIN, |
| 208 | 196 | SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr = |
| 209 | 197 | SURFACE_PIXEL_FORMAT_VIDEO_BEGIN, |
| @@ -856,8 +844,6 @@ enum dwb_stereo_type { · 646 unmodified lines | ||
| 856 | 844 | DWB_STEREO_TYPE_FRAME_SEQUENTIAL = 3, /* Frame sequential */ |
| 857 | 845 | }; |
| 858 | 846 | |
| 859 | −#ifdef CONFIG_DRM_AMD_DC_DCN3_0 | |
| 860 | − | |
| 861 | 847 | enum dwb_out_format { |
| 862 | 848 | DWB_OUT_FORMAT_32BPP_ARGB = 0, |
| 863 | 849 | DWB_OUT_FORMAT_32BPP_RGBA = 1, |
| @@ -890,8 +876,6 @@ struct mcif_warmup_params { · 26 unmodified lines | ||
| 890 | 876 | unsigned int p_vmid; |
| 891 | 877 | }; |
| 892 | 878 | |
| 893 | −#endif | |
| 894 | − | |
| 895 | 879 | #define MCIF_BUF_COUNT 4 |
| 896 | 880 | |
| 897 | 881 | struct mcif_buf_params { |
| @@ -901,9 +885,7 @@ struct mcif_buf_params { · 3 unmodified lines | ||
| 901 | 885 | unsigned int chroma_pitch; |
| 902 | 886 | unsigned int warmup_pitch; |
| 903 | 887 | unsigned int swlock; |
| 904 | −#ifdef CONFIG_DRM_AMD_DC_DCN3_0 | |
| 905 | 888 | unsigned int p_vmid; |
| 906 | −#endif | |
| 907 | 889 | }; |
| 908 | 890 | |
| 909 | 891 | |
| @@ -45,6 +45,7 @@ struct dc_stream_status { · 44 unmodified lines | ||
| 45 | 45 | int audio_inst; |
| 46 | 46 | struct timing_sync_info timing_sync_info; |
| 47 | 47 | struct dc_plane_state *plane_states[MAX_SURFACE_NUM]; |
| 48 | + bool is_abm_supported; | |
| 48 | 49 | }; |
| 49 | 50 | |
| 50 | 51 | // TODO: References to this needs to be removed.. |
| @@ -87,13 +88,11 @@ struct dc_writeback_info { · 36 unmodified lines | ||
| 87 | 88 | int dwb_pipe_inst; |
| 88 | 89 | struct dc_dwb_params dwb_params; |
| 89 | 90 | struct mcif_buf_params mcif_buf_params; |
| 90 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 91 | 91 | struct mcif_warmup_params mcif_warmup_params; |
| 92 | 92 | /* the plane that is the input to TOP_MUX for MPCC that is the DWB source */ |
| 93 | 93 | struct dc_plane_state *writeback_source_plane; |
| 94 | 94 | /* source MPCC instance. for use by internally by dc */ |
| 95 | 95 | int mpcc_inst; |
| 96 | −#endif | |
| 97 | 96 | }; |
| 98 | 97 | |
| 99 | 98 | struct dc_writeback_update { |
| @@ -207,10 +206,8 @@ struct dc_stream_state { · 107 unmodified lines | ||
| 207 | 206 | /* writeback */ |
| 208 | 207 | unsigned int num_wb_info; |
| 209 | 208 | struct dc_writeback_info writeback_info[MAX_DWB_PIPES]; |
| 210 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 211 | 209 | const struct dc_transfer_func *func_shaper; |
| 212 | 210 | const struct dc_3dlut *lut3d_func; |
| 213 | −#endif | |
| 214 | 211 | /* Computed state bits */ |
| 215 | 212 | bool mode_changed : 1; |
| 216 | 213 | |
| @@ -262,10 +259,8 @@ struct dc_stream_update { · 45 unmodified lines | ||
| 262 | 259 | |
| 263 | 260 | struct dc_writeback_update *wb_update; |
| 264 | 261 | struct dc_dsc_config *dsc_config; |
| 265 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 266 | 262 | struct dc_transfer_func *func_shaper; |
| 267 | 263 | struct dc_3dlut *lut3d_func; |
| 268 | −#endif | |
| 269 | 264 | }; |
| 270 | 265 | |
| 271 | 266 | bool dc_is_stream_unchanged( |
| @@ -391,7 +386,7 @@ enum dc_status dc_validate_stream(struct dc *dc, struct dc_stream_state *stream) · 119 unmodified lines | ||
| 391 | 386 | * Enable stereo when commit_streams is not required, |
| 392 | 387 | * for example, frame alternate. |
| 393 | 388 | */ |
| 394 | −bool dc_enable_stereo( | |
| 389 | +void dc_enable_stereo( | |
| 395 | 390 | struct dc *dc, |
| 396 | 391 | struct dc_state *context, |
| 397 | 392 | struct dc_stream_state *streams[], |
| @@ -456,6 +451,7 @@ bool dc_stream_get_crtc_position(struct dc *dc, · 58 unmodified lines | ||
| 456 | 451 | |
| 457 | 452 | bool dc_stream_configure_crc(struct dc *dc, |
| 458 | 453 | struct dc_stream_state *stream, |
| 454 | + struct crc_params *crc_window, | |
| 459 | 455 | bool enable, |
| 460 | 456 | bool continuous); |
| 461 | 457 | |
| @@ -0,0 +1,39 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2020 Advanced Micro Devices, Inc. | |
| 3 | + * | |
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a | |
| 5 | + * copy of this software and associated documentation files (the "Software"), | |
| 6 | + * to deal in the Software without restriction, including without limitation | |
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the | |
| 9 | + * Software is furnished to do so, subject to the following conditions: | |
| 10 | + * | |
| 11 | + * The above copyright notice and this permission notice shall be included in | |
| 12 | + * all copies or substantial portions of the Software. | |
| 13 | + * | |
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 17 | + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 18 | + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 19 | + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 20 | + * OTHER DEALINGS IN THE SOFTWARE. | |
| 21 | + * | |
| 22 | + */ | |
| 23 | + | |
| 24 | +#include "amdgpu_dm_trace.h" | |
| 25 | + | |
| 26 | +#define TRACE_DC_PIPE_STATE(pipe_ctx, index, max_pipes) \ | |
| 27 | + for (index = 0; index < max_pipes; ++index) { \ | |
| 28 | + struct pipe_ctx *pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[index]; \ | |
| 29 | + if (pipe_ctx->plane_state) \ | |
| 30 | + trace_amdgpu_dm_dc_pipe_state(pipe_ctx->pipe_idx, pipe_ctx->plane_state, \ | |
| 31 | + pipe_ctx->stream, &pipe_ctx->plane_res, \ | |
| 32 | + pipe_ctx->update_flags.raw); \ | |
| 33 | + } | |
| 34 | + | |
| 35 | +#define TRACE_DCE_CLOCK_STATE(dce_clocks) \ | |
| 36 | + trace_amdgpu_dm_dce_clocks_state(dce_clocks) | |
| 37 | + | |
| 38 | +#define TRACE_DCN_CLOCK_STATE(dcn_clocks) \ | |
| 39 | + trace_amdgpu_dm_dc_clocks_state(dcn_clocks) | |
| @@ -234,6 +234,8 @@ struct dc_panel_patch { · 233 unmodified lines | ||
| 234 | 234 | unsigned int delay_ignore_msa; |
| 235 | 235 | unsigned int disable_fec; |
| 236 | 236 | unsigned int extra_t3_ms; |
| 237 | + unsigned int max_dsc_target_bpp_limit; | |
| 238 | + unsigned int skip_avmute; | |
| 237 | 239 | }; |
| 238 | 240 | |
| 239 | 241 | struct dc_edid_caps { |
| @@ -479,7 +481,6 @@ enum display_content_type { · 239 unmodified lines | ||
| 479 | 481 | DISPLAY_CONTENT_TYPE_GAME = 8 |
| 480 | 482 | }; |
| 481 | 483 | |
| 482 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 483 | 484 | enum cm_gamut_adjust_type { |
| 484 | 485 | CM_GAMUT_ADJUST_TYPE_BYPASS = 0, |
| 485 | 486 | CM_GAMUT_ADJUST_TYPE_HW, /* without adjustments */ |
| @@ -491,7 +492,7 @@ struct cm_grph_csc_adjustment { · 5 unmodified lines | ||
| 491 | 492 | enum cm_gamut_adjust_type gamut_adjust_type; |
| 492 | 493 | enum cm_gamut_coef_format gamut_coef_format; |
| 493 | 494 | }; |
| 494 | −#endif | |
| 495 | + | |
| 495 | 496 | /* writeback */ |
| 496 | 497 | struct dwb_stereo_params { |
| 497 | 498 | bool stereo_enabled; /* false: normal mode, true: 3D stereo */ |
| @@ -509,21 +510,17 @@ struct dc_dwb_cnv_params { · 11 unmodified lines | ||
| 509 | 510 | unsigned int crop_x; /* cropped window start x value at cnv output */ |
| 510 | 511 | unsigned int crop_y; /* cropped window start y value at cnv output */ |
| 511 | 512 | enum dwb_cnv_out_bpc cnv_out_bpc; /* cnv output pixel depth - 8bpc or 10bpc */ |
| 512 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 513 | 513 | enum dwb_out_format fc_out_format; /* dwb output pixel format - 2101010 or 16161616 and ARGB or RGBA */ |
| 514 | 514 | enum dwb_out_denorm out_denorm_mode;/* dwb output denormalization mode */ |
| 515 | 515 | unsigned int out_max_pix_val;/* pixel values greater than out_max_pix_val are clamped to out_max_pix_val */ |
| 516 | 516 | unsigned int out_min_pix_val;/* pixel values less than out_min_pix_val are clamped to out_min_pix_val */ |
| 517 | −#endif | |
| 518 | 517 | }; |
| 519 | 518 | |
| 520 | 519 | struct dc_dwb_params { |
| 521 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 522 | 520 | unsigned int dwbscl_black_color; /* must be in FP1.5.10 */ |
| 523 | 521 | unsigned int hdr_mult; /* must be in FP1.6.12 */ |
| 524 | 522 | struct cm_grph_csc_adjustment csc_params; |
| 525 | 523 | struct dwb_stereo_params stereo_params; |
| 526 | −#endif | |
| 527 | 524 | struct dc_dwb_cnv_params cnv_params; /* CNV source size and cropping window parameters */ |
| 528 | 525 | unsigned int dest_width; /* Destination width */ |
| 529 | 526 | unsigned int dest_height; /* Destination height */ |
| @@ -904,8 +901,6 @@ struct dc_golden_table { · 374 unmodified lines | ||
| 904 | 901 | uint32_t dc_gpio_aux_ctrl_5_val; |
| 905 | 902 | }; |
| 906 | 903 | |
| 907 | − | |
| 908 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 909 | 904 | enum dc_gpu_mem_alloc_type { |
| 910 | 905 | DC_MEM_ALLOC_TYPE_GART, |
| 911 | 906 | DC_MEM_ALLOC_TYPE_FRAME_BUFFER, |
| @@ -913,7 +908,6 @@ enum dc_gpu_mem_alloc_type { · 1 unmodified line | ||
| 913 | 908 | DC_MEM_ALLOC_TYPE_AGP |
| 914 | 909 | }; |
| 915 | 910 | |
| 916 | −#endif | |
| 917 | 911 | enum dc_psr_version { |
| 918 | 912 | DC_PSR_VERSION_1 = 0, |
| 919 | 913 | DC_PSR_VERSION_UNSUPPORTED = 0xFFFFFFFF, |
| @@ -82,7 +82,20 @@ · 81 unmodified lines | ||
| 82 | 82 | SR(DC_ABM1_ACE_THRES_12), \ |
| 83 | 83 | NBIO_SR(BIOS_SCRATCH_2) |
| 84 | 84 | |
| 85 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 85 | +#define ABM_DCN301_REG_LIST(id)\ | |
| 86 | + ABM_COMMON_REG_LIST_DCE_BASE(), \ | |
| 87 | + SRI(DC_ABM1_HG_SAMPLE_RATE, ABM, id), \ | |
| 88 | + SRI(DC_ABM1_LS_SAMPLE_RATE, ABM, id), \ | |
| 89 | + SRI(BL1_PWM_BL_UPDATE_SAMPLE_RATE, ABM, id), \ | |
| 90 | + SRI(DC_ABM1_HG_MISC_CTRL, ABM, id), \ | |
| 91 | + SRI(DC_ABM1_IPCSC_COEFF_SEL, ABM, id), \ | |
| 92 | + SRI(BL1_PWM_CURRENT_ABM_LEVEL, ABM, id), \ | |
| 93 | + SRI(BL1_PWM_TARGET_ABM_LEVEL, ABM, id), \ | |
| 94 | + SRI(BL1_PWM_USER_LEVEL, ABM, id), \ | |
| 95 | + SRI(DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES, ABM, id), \ | |
| 96 | + SRI(DC_ABM1_HGLS_REG_READ_PROGRESS, ABM, id), \ | |
| 97 | + NBIO_SR(BIOS_SCRATCH_2) | |
| 98 | + | |
| 86 | 99 | #define ABM_DCN30_REG_LIST(id)\ |
| 87 | 100 | ABM_COMMON_REG_LIST_DCE_BASE(), \ |
| 88 | 101 | SRI(DC_ABM1_HG_SAMPLE_RATE, ABM, id), \ |
| @@ -98,7 +111,6 @@ · 9 unmodified lines | ||
| 98 | 111 | SRI(DC_ABM1_ACE_OFFSET_SLOPE_0, ABM, id), \ |
| 99 | 112 | SRI(DC_ABM1_ACE_THRES_12, ABM, id), \ |
| 100 | 113 | NBIO_SR(BIOS_SCRATCH_2) |
| 101 | −#endif | |
| 102 | 114 | |
| 103 | 115 | #define ABM_SF(reg_name, field_name, post_fix)\ |
| 104 | 116 | .field_name = reg_name ## __ ## field_name ## post_fix |
| @@ -173,9 +185,7 @@ · 68 unmodified lines | ||
| 173 | 185 | |
| 174 | 186 | #define ABM_MASK_SH_LIST_DCN20(mask_sh) ABM_MASK_SH_LIST_DCE110(mask_sh) |
| 175 | 187 | |
| 176 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 177 | −#define ABM_MASK_SH_LIST_DCN301(mask_sh) ABM_MASK_SH_LIST_DCN10(mask_sh) | |
| 178 | −#endif | |
| 188 | +#define ABM_MASK_SH_LIST_DCN30(mask_sh) ABM_MASK_SH_LIST_DCN10(mask_sh) | |
| 179 | 189 | |
| 180 | 190 | #define ABM_REG_FIELD_LIST(type) \ |
| 181 | 191 | type ABM1_HG_NUM_OF_BINS_SEL; \ |
| @@ -652,8 +652,10 @@ bool dce_aux_transfer_with_retries(struct ddc_service *ddc, · 651 unmodified lines | ||
| 652 | 652 | } else { |
| 653 | 653 | if ((*payload->reply == AUX_TRANSACTION_REPLY_AUX_DEFER) || |
| 654 | 654 | (*payload->reply == AUX_TRANSACTION_REPLY_I2C_OVER_AUX_DEFER)) { |
| 655 | − if (payload->defer_delay > 0) | |
| 655 | + if (payload->defer_delay > 1) | |
| 656 | 656 | msleep(payload->defer_delay); |
| 657 | + else if (payload->defer_delay <= 1) | |
| 658 | + udelay(payload->defer_delay * 1000); | |
| 657 | 659 | } |
| 658 | 660 | } |
| 659 | 661 | break; |
| @@ -317,7 +317,9 @@ int dce112_set_clock(struct clk_mgr *clk_mgr, int requested_clk_khz) · 316 unmodified lines | ||
| 317 | 317 | /*VBIOS will determine DPREFCLK frequency, so we don't set it*/ |
| 318 | 318 | dce_clk_params.target_clock_frequency = 0; |
| 319 | 319 | dce_clk_params.clock_type = DCECLOCK_TYPE_DPREFCLK; |
| 320 | − if (!ASICREV_IS_VEGA20_P(clk_mgr->ctx->asic_id.hw_internal_rev)) | |
| 320 | + | |
| 321 | + if (!((clk_mgr->ctx->asic_id.chip_family == FAMILY_AI) && | |
| 322 | + ASICREV_IS_VEGA20_P(clk_mgr->ctx->asic_id.hw_internal_rev))) | |
| 321 | 323 | dce_clk_params.flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK = |
| 322 | 324 | (dce_clk_params.pll_id == |
| 323 | 325 | CLOCK_SOURCE_COMBO_DISPLAY_PLL0); |
| @@ -1004,7 +1004,7 @@ static bool get_pixel_clk_frequency_100hz( · 1003 unmodified lines | ||
| 1004 | 1004 | return false; |
| 1005 | 1005 | } |
| 1006 | 1006 | |
| 1007 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 1007 | +#if defined(CONFIG_DRM_AMD_DC_DCN) | |
| 1008 | 1008 | /* this table is use to find *1.001 and /1.001 pixel rates from non-precise pixel rate */ |
| 1009 | 1009 | const struct pixel_rate_range_table_entry video_optimized_pixel_rates[] = { |
| 1010 | 1010 | // /1.001 rates |
| @@ -1073,7 +1073,7 @@ static const struct clock_source_funcs dcn20_clk_src_funcs = { · 62 unmodified lines | ||
| 1073 | 1073 | .get_pixel_clk_frequency_100hz = get_pixel_clk_frequency_100hz |
| 1074 | 1074 | }; |
| 1075 | 1075 | |
| 1076 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 1076 | +#if defined(CONFIG_DRM_AMD_DC_DCN) | |
| 1077 | 1077 | static bool dcn3_program_pix_clk( |
| 1078 | 1078 | struct clock_source *clock_source, |
| 1079 | 1079 | struct pixel_clk_params *pix_clk_params, |
| @@ -1538,7 +1538,7 @@ bool dcn20_clk_src_construct( · 458 unmodified lines | ||
| 1538 | 1538 | return ret; |
| 1539 | 1539 | } |
| 1540 | 1540 | |
| 1541 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 1541 | +#if defined(CONFIG_DRM_AMD_DC_DCN) | |
| 1542 | 1542 | bool dcn3_clk_src_construct( |
| 1543 | 1543 | struct dce110_clk_src *clk_src, |
| 1544 | 1544 | struct dc_context *ctx, |
| @@ -1555,3 +1555,21 @@ bool dcn3_clk_src_construct( · 10 unmodified lines | ||
| 1555 | 1555 | return ret; |
| 1556 | 1556 | } |
| 1557 | 1557 | #endif |
| 1558 | + | |
| 1559 | +#if defined(CONFIG_DRM_AMD_DC_DCN) | |
| 1560 | +bool dcn301_clk_src_construct( | |
| 1561 | + struct dce110_clk_src *clk_src, | |
| 1562 | + struct dc_context *ctx, | |
| 1563 | + struct dc_bios *bios, | |
| 1564 | + enum clock_source_id id, | |
| 1565 | + const struct dce110_clk_src_regs *regs, | |
| 1566 | + const struct dce110_clk_src_shift *cs_shift, | |
| 1567 | + const struct dce110_clk_src_mask *cs_mask) | |
| 1568 | +{ | |
| 1569 | + bool ret = dce112_clk_src_construct(clk_src, ctx, bios, id, regs, cs_shift, cs_mask); | |
| 1570 | + | |
| 1571 | + clk_src->base.funcs = &dcn3_clk_src_funcs; | |
| 1572 | + | |
| 1573 | + return ret; | |
| 1574 | +} | |
| 1575 | +#endif | |
| @@ -91,7 +91,7 @@ · 90 unmodified lines | ||
| 91 | 91 | SRII(PIXEL_RATE_CNTL, OTG, 2),\ |
| 92 | 92 | SRII(PIXEL_RATE_CNTL, OTG, 3) |
| 93 | 93 | |
| 94 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 94 | +#if defined(CONFIG_DRM_AMD_DC_DCN) | |
| 95 | 95 | #define CS_COMMON_REG_LIST_DCN3_0(index, pllid) \ |
| 96 | 96 | SRI(PIXCLK_RESYNC_CNTL, PHYPLL, pllid),\ |
| 97 | 97 | SRII(PHASE, DP_DTO, 0),\ |
| @@ -106,8 +106,43 @@ · 8 unmodified lines | ||
| 106 | 106 | SRII(PIXEL_RATE_CNTL, OTG, 1),\ |
| 107 | 107 | SRII(PIXEL_RATE_CNTL, OTG, 2),\ |
| 108 | 108 | SRII(PIXEL_RATE_CNTL, OTG, 3) |
| 109 | + | |
| 110 | +#define CS_COMMON_REG_LIST_DCN3_01(index, pllid) \ | |
| 111 | + SRI(PIXCLK_RESYNC_CNTL, PHYPLL, pllid),\ | |
| 112 | + SRII(PHASE, DP_DTO, 0),\ | |
| 113 | + SRII(PHASE, DP_DTO, 1),\ | |
| 114 | + SRII(PHASE, DP_DTO, 2),\ | |
| 115 | + SRII(PHASE, DP_DTO, 3),\ | |
| 116 | + SRII(MODULO, DP_DTO, 0),\ | |
| 117 | + SRII(MODULO, DP_DTO, 1),\ | |
| 118 | + SRII(MODULO, DP_DTO, 2),\ | |
| 119 | + SRII(MODULO, DP_DTO, 3),\ | |
| 120 | + SRII(PIXEL_RATE_CNTL, OTG, 0),\ | |
| 121 | + SRII(PIXEL_RATE_CNTL, OTG, 1),\ | |
| 122 | + SRII(PIXEL_RATE_CNTL, OTG, 2),\ | |
| 123 | + SRII(PIXEL_RATE_CNTL, OTG, 3) | |
| 109 | 124 | #endif |
| 110 | 125 | |
| 126 | +#if defined(CONFIG_DRM_AMD_DC_DCN) | |
| 127 | +#define CS_COMMON_REG_LIST_DCN3_02(index, pllid) \ | |
| 128 | + SRI(PIXCLK_RESYNC_CNTL, PHYPLL, pllid),\ | |
| 129 | + SRII(PHASE, DP_DTO, 0),\ | |
| 130 | + SRII(PHASE, DP_DTO, 1),\ | |
| 131 | + SRII(PHASE, DP_DTO, 2),\ | |
| 132 | + SRII(PHASE, DP_DTO, 3),\ | |
| 133 | + SRII(PHASE, DP_DTO, 4),\ | |
| 134 | + SRII(MODULO, DP_DTO, 0),\ | |
| 135 | + SRII(MODULO, DP_DTO, 1),\ | |
| 136 | + SRII(MODULO, DP_DTO, 2),\ | |
| 137 | + SRII(MODULO, DP_DTO, 3),\ | |
| 138 | + SRII(MODULO, DP_DTO, 4),\ | |
| 139 | + SRII(PIXEL_RATE_CNTL, OTG, 0),\ | |
| 140 | + SRII(PIXEL_RATE_CNTL, OTG, 1),\ | |
| 141 | + SRII(PIXEL_RATE_CNTL, OTG, 2),\ | |
| 142 | + SRII(PIXEL_RATE_CNTL, OTG, 3),\ | |
| 143 | + SRII(PIXEL_RATE_CNTL, OTG, 4) | |
| 144 | + | |
| 145 | +#endif | |
| 111 | 146 | #define CS_COMMON_MASK_SH_LIST_DCN2_0(mask_sh)\ |
| 112 | 147 | CS_SF(DP_DTO0_PHASE, DP_DTO0_PHASE, mask_sh),\ |
| 113 | 148 | CS_SF(DP_DTO0_MODULO, DP_DTO0_MODULO, mask_sh),\ |
| @@ -221,7 +256,7 @@ bool dcn20_clk_src_construct( · 107 unmodified lines | ||
| 221 | 256 | const struct dce110_clk_src_shift *cs_shift, |
| 222 | 257 | const struct dce110_clk_src_mask *cs_mask); |
| 223 | 258 | |
| 224 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 259 | +#if defined(CONFIG_DRM_AMD_DC_DCN) | |
| 225 | 260 | bool dcn3_clk_src_construct( |
| 226 | 261 | struct dce110_clk_src *clk_src, |
| 227 | 262 | struct dc_context *ctx, |
| @@ -230,6 +265,15 @@ bool dcn3_clk_src_construct( · 2 unmodified lines | ||
| 230 | 265 | const struct dce110_clk_src_regs *regs, |
| 231 | 266 | const struct dce110_clk_src_shift *cs_shift, |
| 232 | 267 | const struct dce110_clk_src_mask *cs_mask); |
| 268 | + | |
| 269 | +bool dcn301_clk_src_construct( | |
| 270 | + struct dce110_clk_src *clk_src, | |
| 271 | + struct dc_context *ctx, | |
| 272 | + struct dc_bios *bios, | |
| 273 | + enum clock_source_id id, | |
| 274 | + const struct dce110_clk_src_regs *regs, | |
| 275 | + const struct dce110_clk_src_shift *cs_shift, | |
| 276 | + const struct dce110_clk_src_mask *cs_mask); | |
| 233 | 277 | #endif |
| 234 | 278 | |
| 235 | 279 | /* this table is use to find *1.001 and /1.001 pixel rates from non-precise pixel rate */ |
| @@ -241,9 +285,10 @@ struct pixel_rate_range_table_entry { · 5 unmodified lines | ||
| 241 | 285 | unsigned short div_factor; |
| 242 | 286 | }; |
| 243 | 287 | |
| 244 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 288 | +#if defined(CONFIG_DRM_AMD_DC_DCN) | |
| 245 | 289 | extern const struct pixel_rate_range_table_entry video_optimized_pixel_rates[]; |
| 246 | 290 | const struct pixel_rate_range_table_entry *look_up_in_video_optimized_rate_tlb( |
| 247 | 291 | unsigned int pixel_rate_khz); |
| 248 | 292 | #endif |
| 293 | + | |
| 249 | 294 | #endif |
| @@ -78,7 +78,6 @@ · 77 unmodified lines | ||
| 78 | 78 | SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 4), \ |
| 79 | 79 | SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 5) |
| 80 | 80 | |
| 81 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 82 | 81 | #define HWSEQ_PIXEL_RATE_REG_LIST_3(blk) \ |
| 83 | 82 | SRII(PIXEL_RATE_CNTL, blk, 0), \ |
| 84 | 83 | SRII(PIXEL_RATE_CNTL, blk, 1),\ |
| @@ -94,7 +93,6 @@ · 9 unmodified lines | ||
| 94 | 93 | SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 3), \ |
| 95 | 94 | SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 4), \ |
| 96 | 95 | SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 5) |
| 97 | −#endif | |
| 98 | 96 | |
| 99 | 97 | #define HWSEQ_DCE11_REG_LIST_BASE() \ |
| 100 | 98 | SR(DC_MEM_GLOBAL_PWR_REQ_CNTL), \ |
| @@ -224,28 +222,6 @@ · 123 unmodified lines | ||
| 224 | 222 | SR(VGA_TEST_CONTROL), \ |
| 225 | 223 | SR(DC_IP_REQUEST_CNTL) |
| 226 | 224 | |
| 227 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 228 | −#define HWSEQ_DCN30_REG_LIST()\ | |
| 229 | − HWSEQ_DCN2_REG_LIST(),\ | |
| 230 | − HWSEQ_DCN_REG_LIST(), \ | |
| 231 | − HWSEQ_PIXEL_RATE_REG_LIST_3(OTG), \ | |
| 232 | − HWSEQ_PHYPLL_REG_LIST_3(OTG), \ | |
| 233 | − SR(MICROSECOND_TIME_BASE_DIV), \ | |
| 234 | − SR(MILLISECOND_TIME_BASE_DIV), \ | |
| 235 | − SR(DISPCLK_FREQ_CHANGE_CNTL), \ | |
| 236 | − SR(RBBMIF_TIMEOUT_DIS), \ | |
| 237 | − SR(RBBMIF_TIMEOUT_DIS_2), \ | |
| 238 | − SR(DCHUBBUB_CRC_CTRL), \ | |
| 239 | − SR(DPP_TOP0_DPP_CRC_CTRL), \ | |
| 240 | − SR(DPP_TOP0_DPP_CRC_VAL_B_A), \ | |
| 241 | − SR(DPP_TOP0_DPP_CRC_VAL_R_G), \ | |
| 242 | − SR(MPC_CRC_CTRL), \ | |
| 243 | − SR(MPC_CRC_RESULT_GB), \ | |
| 244 | − SR(MPC_CRC_RESULT_C), \ | |
| 245 | − SR(MPC_CRC_RESULT_AR), \ | |
| 246 | − SR(AZALIA_AUDIO_DTO), \ | |
| 247 | − SR(AZALIA_CONTROLLER_CLOCK_GATING) | |
| 248 | −#endif | |
| 249 | 225 | #define HWSEQ_DCN2_REG_LIST()\ |
| 250 | 226 | HWSEQ_DCN_REG_LIST(), \ |
| 251 | 227 | HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 0), \ |
| @@ -361,6 +337,163 @@ · 109 unmodified lines | ||
| 361 | 337 | SR(D6VGA_CONTROL), \ |
| 362 | 338 | SR(DC_IP_REQUEST_CNTL) |
| 363 | 339 | |
| 340 | +#define HWSEQ_DCN30_REG_LIST()\ | |
| 341 | + HWSEQ_DCN2_REG_LIST(),\ | |
| 342 | + HWSEQ_DCN_REG_LIST(), \ | |
| 343 | + HWSEQ_PIXEL_RATE_REG_LIST_3(OTG), \ | |
| 344 | + HWSEQ_PHYPLL_REG_LIST_3(OTG), \ | |
| 345 | + SR(MICROSECOND_TIME_BASE_DIV), \ | |
| 346 | + SR(MILLISECOND_TIME_BASE_DIV), \ | |
| 347 | + SR(DISPCLK_FREQ_CHANGE_CNTL), \ | |
| 348 | + SR(RBBMIF_TIMEOUT_DIS), \ | |
| 349 | + SR(RBBMIF_TIMEOUT_DIS_2), \ | |
| 350 | + SR(DCHUBBUB_CRC_CTRL), \ | |
| 351 | + SR(DPP_TOP0_DPP_CRC_CTRL), \ | |
| 352 | + SR(DPP_TOP0_DPP_CRC_VAL_B_A), \ | |
| 353 | + SR(DPP_TOP0_DPP_CRC_VAL_R_G), \ | |
| 354 | + SR(MPC_CRC_CTRL), \ | |
| 355 | + SR(MPC_CRC_RESULT_GB), \ | |
| 356 | + SR(MPC_CRC_RESULT_C), \ | |
| 357 | + SR(MPC_CRC_RESULT_AR), \ | |
| 358 | + SR(AZALIA_AUDIO_DTO), \ | |
| 359 | + SR(AZALIA_CONTROLLER_CLOCK_GATING) | |
| 360 | + | |
| 361 | +#define HWSEQ_DCN301_REG_LIST()\ | |
| 362 | + SR(REFCLK_CNTL), \ | |
| 363 | + SR(DCHUBBUB_GLOBAL_TIMER_CNTL), \ | |
| 364 | + SR(DIO_MEM_PWR_CTRL), \ | |
| 365 | + SR(DCCG_GATE_DISABLE_CNTL), \ | |
| 366 | + SR(DCCG_GATE_DISABLE_CNTL2), \ | |
| 367 | + SR(DCFCLK_CNTL),\ | |
| 368 | + SR(DCFCLK_CNTL), \ | |
| 369 | + SR(DC_MEM_GLOBAL_PWR_REQ_CNTL), \ | |
| 370 | + SRII(PIXEL_RATE_CNTL, OTG, 0), \ | |
| 371 | + SRII(PIXEL_RATE_CNTL, OTG, 1),\ | |
| 372 | + SRII(PIXEL_RATE_CNTL, OTG, 2),\ | |
| 373 | + SRII(PIXEL_RATE_CNTL, OTG, 3),\ | |
| 374 | + SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 0),\ | |
| 375 | + SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 1),\ | |
| 376 | + SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 2),\ | |
| 377 | + SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 3),\ | |
| 378 | + SR(MICROSECOND_TIME_BASE_DIV), \ | |
| 379 | + SR(MILLISECOND_TIME_BASE_DIV), \ | |
| 380 | + SR(DISPCLK_FREQ_CHANGE_CNTL), \ | |
| 381 | + SR(RBBMIF_TIMEOUT_DIS), \ | |
| 382 | + SR(RBBMIF_TIMEOUT_DIS_2), \ | |
| 383 | + SR(DCHUBBUB_CRC_CTRL), \ | |
| 384 | + SR(DPP_TOP0_DPP_CRC_CTRL), \ | |
| 385 | + SR(DPP_TOP0_DPP_CRC_VAL_B_A), \ | |
| 386 | + SR(DPP_TOP0_DPP_CRC_VAL_R_G), \ | |
| 387 | + SR(MPC_CRC_CTRL), \ | |
| 388 | + SR(MPC_CRC_RESULT_GB), \ | |
| 389 | + SR(MPC_CRC_RESULT_C), \ | |
| 390 | + SR(MPC_CRC_RESULT_AR), \ | |
| 391 | + SR(DOMAIN0_PG_CONFIG), \ | |
| 392 | + SR(DOMAIN1_PG_CONFIG), \ | |
| 393 | + SR(DOMAIN2_PG_CONFIG), \ | |
| 394 | + SR(DOMAIN3_PG_CONFIG), \ | |
| 395 | + SR(DOMAIN4_PG_CONFIG), \ | |
| 396 | + SR(DOMAIN5_PG_CONFIG), \ | |
| 397 | + SR(DOMAIN6_PG_CONFIG), \ | |
| 398 | + SR(DOMAIN7_PG_CONFIG), \ | |
| 399 | + SR(DOMAIN16_PG_CONFIG), \ | |
| 400 | + SR(DOMAIN17_PG_CONFIG), \ | |
| 401 | + SR(DOMAIN18_PG_CONFIG), \ | |
| 402 | + SR(DOMAIN0_PG_STATUS), \ | |
| 403 | + SR(DOMAIN1_PG_STATUS), \ | |
| 404 | + SR(DOMAIN2_PG_STATUS), \ | |
| 405 | + SR(DOMAIN3_PG_STATUS), \ | |
| 406 | + SR(DOMAIN4_PG_STATUS), \ | |
| 407 | + SR(DOMAIN5_PG_STATUS), \ | |
| 408 | + SR(DOMAIN6_PG_STATUS), \ | |
| 409 | + SR(DOMAIN7_PG_STATUS), \ | |
| 410 | + SR(DOMAIN16_PG_STATUS), \ | |
| 411 | + SR(DOMAIN17_PG_STATUS), \ | |
| 412 | + SR(DOMAIN18_PG_STATUS), \ | |
| 413 | + SR(D1VGA_CONTROL), \ | |
| 414 | + SR(D2VGA_CONTROL), \ | |
| 415 | + SR(D3VGA_CONTROL), \ | |
| 416 | + SR(D4VGA_CONTROL), \ | |
| 417 | + SR(D5VGA_CONTROL), \ | |
| 418 | + SR(D6VGA_CONTROL), \ | |
| 419 | + SR(DC_IP_REQUEST_CNTL), \ | |
| 420 | + SR(AZALIA_AUDIO_DTO), \ | |
| 421 | + SR(AZALIA_CONTROLLER_CLOCK_GATING) | |
| 422 | + | |
| 423 | +#define HWSEQ_DCN302_REG_LIST()\ | |
| 424 | + HWSEQ_DCN_REG_LIST(), \ | |
| 425 | + HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 0), \ | |
| 426 | + HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 1), \ | |
| 427 | + HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 2), \ | |
| 428 | + HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 3), \ | |
| 429 | + HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 4), \ | |
| 430 | + SR(MICROSECOND_TIME_BASE_DIV), \ | |
| 431 | + SR(MILLISECOND_TIME_BASE_DIV), \ | |
| 432 | + SR(DISPCLK_FREQ_CHANGE_CNTL), \ | |
| 433 | + SR(RBBMIF_TIMEOUT_DIS), \ | |
| 434 | + SR(RBBMIF_TIMEOUT_DIS_2), \ | |
| 435 | + SR(DCHUBBUB_CRC_CTRL), \ | |
| 436 | + SR(DPP_TOP0_DPP_CRC_CTRL), \ | |
| 437 | + SR(DPP_TOP0_DPP_CRC_VAL_B_A), \ | |
| 438 | + SR(DPP_TOP0_DPP_CRC_VAL_R_G), \ | |
| 439 | + SR(MPC_CRC_CTRL), \ | |
| 440 | + SR(MPC_CRC_RESULT_GB), \ | |
| 441 | + SR(MPC_CRC_RESULT_C), \ | |
| 442 | + SR(MPC_CRC_RESULT_AR), \ | |
| 443 | + SR(DOMAIN0_PG_CONFIG), \ | |
| 444 | + SR(DOMAIN1_PG_CONFIG), \ | |
| 445 | + SR(DOMAIN2_PG_CONFIG), \ | |
| 446 | + SR(DOMAIN3_PG_CONFIG), \ | |
| 447 | + SR(DOMAIN4_PG_CONFIG), \ | |
| 448 | + SR(DOMAIN5_PG_CONFIG), \ | |
| 449 | + SR(DOMAIN6_PG_CONFIG), \ | |
| 450 | + SR(DOMAIN7_PG_CONFIG), \ | |
| 451 | + SR(DOMAIN8_PG_CONFIG), \ | |
| 452 | + SR(DOMAIN9_PG_CONFIG), \ | |
| 453 | + SR(DOMAIN16_PG_CONFIG), \ | |
| 454 | + SR(DOMAIN17_PG_CONFIG), \ | |
| 455 | + SR(DOMAIN18_PG_CONFIG), \ | |
| 456 | + SR(DOMAIN19_PG_CONFIG), \ | |
| 457 | + SR(DOMAIN20_PG_CONFIG), \ | |
| 458 | + SR(DOMAIN0_PG_STATUS), \ | |
| 459 | + SR(DOMAIN1_PG_STATUS), \ | |
| 460 | + SR(DOMAIN2_PG_STATUS), \ | |
| 461 | + SR(DOMAIN3_PG_STATUS), \ | |
| 462 | + SR(DOMAIN4_PG_STATUS), \ | |
| 463 | + SR(DOMAIN5_PG_STATUS), \ | |
| 464 | + SR(DOMAIN6_PG_STATUS), \ | |
| 465 | + SR(DOMAIN7_PG_STATUS), \ | |
| 466 | + SR(DOMAIN8_PG_STATUS), \ | |
| 467 | + SR(DOMAIN9_PG_STATUS), \ | |
| 468 | + SR(DOMAIN16_PG_STATUS), \ | |
| 469 | + SR(DOMAIN17_PG_STATUS), \ | |
| 470 | + SR(DOMAIN18_PG_STATUS), \ | |
| 471 | + SR(DOMAIN19_PG_STATUS), \ | |
| 472 | + SR(DOMAIN20_PG_STATUS), \ | |
| 473 | + SR(D1VGA_CONTROL), \ | |
| 474 | + SR(D2VGA_CONTROL), \ | |
| 475 | + SR(D3VGA_CONTROL), \ | |
| 476 | + SR(D4VGA_CONTROL), \ | |
| 477 | + SR(D5VGA_CONTROL), \ | |
| 478 | + SR(D6VGA_CONTROL), \ | |
| 479 | + SR(DC_IP_REQUEST_CNTL), \ | |
| 480 | + SR(AZALIA_AUDIO_DTO), \ | |
| 481 | + SR(AZALIA_CONTROLLER_CLOCK_GATING) | |
| 482 | + | |
| 483 | +#define HWSEQ_PIXEL_RATE_REG_LIST_302(blk) \ | |
| 484 | + SRII(PIXEL_RATE_CNTL, blk, 0), \ | |
| 485 | + SRII(PIXEL_RATE_CNTL, blk, 1),\ | |
| 486 | + SRII(PIXEL_RATE_CNTL, blk, 2),\ | |
| 487 | + SRII(PIXEL_RATE_CNTL, blk, 3), \ | |
| 488 | + SRII(PIXEL_RATE_CNTL, blk, 4) | |
| 489 | + | |
| 490 | +#define HWSEQ_PHYPLL_REG_LIST_302(blk) \ | |
| 491 | + SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 0), \ | |
| 492 | + SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 1),\ | |
| 493 | + SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 2),\ | |
| 494 | + SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 3), \ | |
| 495 | + SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 4) | |
| 496 | + | |
| 364 | 497 | struct dce_hwseq_registers { |
| 365 | 498 | uint32_t DCFE_CLOCK_CONTROL[6]; |
| 366 | 499 | uint32_t DCFEV_CLOCK_CONTROL; |
| @@ -462,6 +595,8 @@ struct dce_hwseq_registers { · 95 unmodified lines | ||
| 462 | 595 | uint32_t MC_VM_XGMI_LFB_CNTL; |
| 463 | 596 | uint32_t AZALIA_AUDIO_DTO; |
| 464 | 597 | uint32_t AZALIA_CONTROLLER_CLOCK_GATING; |
| 598 | + uint32_t HPO_TOP_CLOCK_CONTROL; | |
| 599 | + uint32_t ODM_MEM_PWR_CTRL3; | |
| 465 | 600 | }; |
| 466 | 601 | /* set field name */ |
| 467 | 602 | #define HWS_SF(blk_name, reg_name, field_name, post_fix)\ |
| @@ -598,12 +733,6 @@ struct dce_hwseq_registers { · 130 unmodified lines | ||
| 598 | 733 | HWS_SF(, VGA_TEST_CONTROL, VGA_TEST_ENABLE, mask_sh),\ |
| 599 | 734 | HWS_SF(, VGA_TEST_CONTROL, VGA_TEST_RENDER_START, mask_sh) |
| 600 | 735 | |
| 601 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 602 | −#define HWSEQ_DCN30_MASK_SH_LIST(mask_sh)\ | |
| 603 | − HWSEQ_DCN2_MASK_SH_LIST(mask_sh), \ | |
| 604 | − HWS_SF(, AZALIA_AUDIO_DTO, AZALIA_AUDIO_DTO_MODULE, mask_sh) | |
| 605 | −#endif | |
| 606 | − | |
| 607 | 736 | #define HWSEQ_DCN2_MASK_SH_LIST(mask_sh)\ |
| 608 | 737 | HWSEQ_DCN_MASK_SH_LIST(mask_sh), \ |
| 609 | 738 | HWS_SF(, DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, mask_sh), \ |
| @@ -703,6 +832,106 @@ struct dce_hwseq_registers { · 93 unmodified lines | ||
| 703 | 832 | HWS_SF(, DOMAIN18_PG_STATUS, DOMAIN18_PGFSM_PWR_STATUS, mask_sh), \ |
| 704 | 833 | HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh) |
| 705 | 834 | |
| 835 | +#define HWSEQ_DCN30_MASK_SH_LIST(mask_sh)\ | |
| 836 | + HWSEQ_DCN2_MASK_SH_LIST(mask_sh), \ | |
| 837 | + HWS_SF(, AZALIA_AUDIO_DTO, AZALIA_AUDIO_DTO_MODULE, mask_sh), \ | |
| 838 | + HWS_SF(, ODM_MEM_PWR_CTRL3, ODM_MEM_UNASSIGNED_PWR_MODE, mask_sh), \ | |
| 839 | + HWS_SF(, ODM_MEM_PWR_CTRL3, ODM_MEM_VBLANK_PWR_MODE, mask_sh) | |
| 840 | + | |
| 841 | +#define HWSEQ_DCN301_MASK_SH_LIST(mask_sh)\ | |
| 842 | + HWSEQ_DCN_MASK_SH_LIST(mask_sh), \ | |
| 843 | + HWS_SF(, DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, mask_sh), \ | |
| 844 | + HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_FORCEON, mask_sh), \ | |
| 845 | + HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_GATE, mask_sh), \ | |
| 846 | + HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_FORCEON, mask_sh), \ | |
| 847 | + HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_GATE, mask_sh), \ | |
| 848 | + HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_FORCEON, mask_sh), \ | |
| 849 | + HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_GATE, mask_sh), \ | |
| 850 | + HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_FORCEON, mask_sh), \ | |
| 851 | + HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_GATE, mask_sh), \ | |
| 852 | + HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_FORCEON, mask_sh), \ | |
| 853 | + HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_GATE, mask_sh), \ | |
| 854 | + HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_FORCEON, mask_sh), \ | |
| 855 | + HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_GATE, mask_sh), \ | |
| 856 | + HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_FORCEON, mask_sh), \ | |
| 857 | + HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_GATE, mask_sh), \ | |
| 858 | + HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_FORCEON, mask_sh), \ | |
| 859 | + HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_GATE, mask_sh), \ | |
| 860 | + HWS_SF(, DOMAIN16_PG_CONFIG, DOMAIN16_POWER_FORCEON, mask_sh), \ | |
| 861 | + HWS_SF(, DOMAIN16_PG_CONFIG, DOMAIN16_POWER_GATE, mask_sh), \ | |
| 862 | + HWS_SF(, DOMAIN17_PG_CONFIG, DOMAIN17_POWER_FORCEON, mask_sh), \ | |
| 863 | + HWS_SF(, DOMAIN17_PG_CONFIG, DOMAIN17_POWER_GATE, mask_sh), \ | |
| 864 | + HWS_SF(, DOMAIN18_PG_CONFIG, DOMAIN18_POWER_FORCEON, mask_sh), \ | |
| 865 | + HWS_SF(, DOMAIN18_PG_CONFIG, DOMAIN18_POWER_GATE, mask_sh), \ | |
| 866 | + HWS_SF(, DOMAIN0_PG_STATUS, DOMAIN0_PGFSM_PWR_STATUS, mask_sh), \ | |
| 867 | + HWS_SF(, DOMAIN1_PG_STATUS, DOMAIN1_PGFSM_PWR_STATUS, mask_sh), \ | |
| 868 | + HWS_SF(, DOMAIN2_PG_STATUS, DOMAIN2_PGFSM_PWR_STATUS, mask_sh), \ | |
| 869 | + HWS_SF(, DOMAIN3_PG_STATUS, DOMAIN3_PGFSM_PWR_STATUS, mask_sh), \ | |
| 870 | + HWS_SF(, DOMAIN4_PG_STATUS, DOMAIN4_PGFSM_PWR_STATUS, mask_sh), \ | |
| 871 | + HWS_SF(, DOMAIN5_PG_STATUS, DOMAIN5_PGFSM_PWR_STATUS, mask_sh), \ | |
| 872 | + HWS_SF(, DOMAIN6_PG_STATUS, DOMAIN6_PGFSM_PWR_STATUS, mask_sh), \ | |
| 873 | + HWS_SF(, DOMAIN7_PG_STATUS, DOMAIN7_PGFSM_PWR_STATUS, mask_sh), \ | |
| 874 | + HWS_SF(, DOMAIN16_PG_STATUS, DOMAIN16_PGFSM_PWR_STATUS, mask_sh), \ | |
| 875 | + HWS_SF(, DOMAIN17_PG_STATUS, DOMAIN17_PGFSM_PWR_STATUS, mask_sh), \ | |
| 876 | + HWS_SF(, DOMAIN18_PG_STATUS, DOMAIN18_PGFSM_PWR_STATUS, mask_sh), \ | |
| 877 | + HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \ | |
| 878 | + HWS_SF(, PANEL_PWRSEQ0_CNTL, PANEL_BLON, mask_sh),\ | |
| 879 | + HWS_SF(, PANEL_PWRSEQ0_CNTL, PANEL_DIGON, mask_sh),\ | |
| 880 | + HWS_SF(, PANEL_PWRSEQ0_CNTL, PANEL_DIGON_OVRD, mask_sh),\ | |
| 881 | + HWS_SF(, PANEL_PWRSEQ0_STATE, PANEL_PWRSEQ_TARGET_STATE_R, mask_sh),\ | |
| 882 | + HWS_SF(, AZALIA_AUDIO_DTO, AZALIA_AUDIO_DTO_MODULE, mask_sh) | |
| 883 | + | |
| 884 | +#define HWSEQ_DCN302_MASK_SH_LIST(mask_sh)\ | |
| 885 | + HWSEQ_DCN_MASK_SH_LIST(mask_sh), \ | |
| 886 | + HWS_SF(, DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, mask_sh), \ | |
| 887 | + HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_FORCEON, mask_sh), \ | |
| 888 | + HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_GATE, mask_sh), \ | |
| 889 | + HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_FORCEON, mask_sh), \ | |
| 890 | + HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_GATE, mask_sh), \ | |
| 891 | + HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_FORCEON, mask_sh), \ | |
| 892 | + HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_GATE, mask_sh), \ | |
| 893 | + HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_FORCEON, mask_sh), \ | |
| 894 | + HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_GATE, mask_sh), \ | |
| 895 | + HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_FORCEON, mask_sh), \ | |
| 896 | + HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_GATE, mask_sh), \ | |
| 897 | + HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_FORCEON, mask_sh), \ | |
| 898 | + HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_GATE, mask_sh), \ | |
| 899 | + HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_FORCEON, mask_sh), \ | |
| 900 | + HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_GATE, mask_sh), \ | |
| 901 | + HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_FORCEON, mask_sh), \ | |
| 902 | + HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_GATE, mask_sh), \ | |
| 903 | + HWS_SF(, DOMAIN8_PG_CONFIG, DOMAIN8_POWER_FORCEON, mask_sh), \ | |
| 904 | + HWS_SF(, DOMAIN8_PG_CONFIG, DOMAIN8_POWER_GATE, mask_sh), \ | |
| 905 | + HWS_SF(, DOMAIN9_PG_CONFIG, DOMAIN9_POWER_FORCEON, mask_sh), \ | |
| 906 | + HWS_SF(, DOMAIN9_PG_CONFIG, DOMAIN9_POWER_GATE, mask_sh), \ | |
| 907 | + HWS_SF(, DOMAIN16_PG_CONFIG, DOMAIN16_POWER_FORCEON, mask_sh), \ | |
| 908 | + HWS_SF(, DOMAIN16_PG_CONFIG, DOMAIN16_POWER_GATE, mask_sh), \ | |
| 909 | + HWS_SF(, DOMAIN17_PG_CONFIG, DOMAIN17_POWER_FORCEON, mask_sh), \ | |
| 910 | + HWS_SF(, DOMAIN17_PG_CONFIG, DOMAIN17_POWER_GATE, mask_sh), \ | |
| 911 | + HWS_SF(, DOMAIN18_PG_CONFIG, DOMAIN18_POWER_FORCEON, mask_sh), \ | |
| 912 | + HWS_SF(, DOMAIN18_PG_CONFIG, DOMAIN18_POWER_GATE, mask_sh), \ | |
| 913 | + HWS_SF(, DOMAIN19_PG_CONFIG, DOMAIN19_POWER_FORCEON, mask_sh), \ | |
| 914 | + HWS_SF(, DOMAIN19_PG_CONFIG, DOMAIN19_POWER_GATE, mask_sh), \ | |
| 915 | + HWS_SF(, DOMAIN20_PG_CONFIG, DOMAIN20_POWER_FORCEON, mask_sh), \ | |
| 916 | + HWS_SF(, DOMAIN20_PG_CONFIG, DOMAIN20_POWER_GATE, mask_sh), \ | |
| 917 | + HWS_SF(, DOMAIN0_PG_STATUS, DOMAIN0_PGFSM_PWR_STATUS, mask_sh), \ | |
| 918 | + HWS_SF(, DOMAIN1_PG_STATUS, DOMAIN1_PGFSM_PWR_STATUS, mask_sh), \ | |
| 919 | + HWS_SF(, DOMAIN2_PG_STATUS, DOMAIN2_PGFSM_PWR_STATUS, mask_sh), \ | |
| 920 | + HWS_SF(, DOMAIN3_PG_STATUS, DOMAIN3_PGFSM_PWR_STATUS, mask_sh), \ | |
| 921 | + HWS_SF(, DOMAIN4_PG_STATUS, DOMAIN4_PGFSM_PWR_STATUS, mask_sh), \ | |
| 922 | + HWS_SF(, DOMAIN5_PG_STATUS, DOMAIN5_PGFSM_PWR_STATUS, mask_sh), \ | |
| 923 | + HWS_SF(, DOMAIN6_PG_STATUS, DOMAIN6_PGFSM_PWR_STATUS, mask_sh), \ | |
| 924 | + HWS_SF(, DOMAIN7_PG_STATUS, DOMAIN7_PGFSM_PWR_STATUS, mask_sh), \ | |
| 925 | + HWS_SF(, DOMAIN8_PG_STATUS, DOMAIN8_PGFSM_PWR_STATUS, mask_sh), \ | |
| 926 | + HWS_SF(, DOMAIN9_PG_STATUS, DOMAIN9_PGFSM_PWR_STATUS, mask_sh), \ | |
| 927 | + HWS_SF(, DOMAIN16_PG_STATUS, DOMAIN16_PGFSM_PWR_STATUS, mask_sh), \ | |
| 928 | + HWS_SF(, DOMAIN17_PG_STATUS, DOMAIN17_PGFSM_PWR_STATUS, mask_sh), \ | |
| 929 | + HWS_SF(, DOMAIN18_PG_STATUS, DOMAIN18_PGFSM_PWR_STATUS, mask_sh), \ | |
| 930 | + HWS_SF(, DOMAIN19_PG_STATUS, DOMAIN19_PGFSM_PWR_STATUS, mask_sh), \ | |
| 931 | + HWS_SF(, DOMAIN20_PG_STATUS, DOMAIN20_PGFSM_PWR_STATUS, mask_sh), \ | |
| 932 | + HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \ | |
| 933 | + HWS_SF(, AZALIA_AUDIO_DTO, AZALIA_AUDIO_DTO_MODULE, mask_sh) | |
| 934 | + | |
| 706 | 935 | #define HWSEQ_REG_FIELD_LIST(type) \ |
| 707 | 936 | type DCFE_CLOCK_ENABLE; \ |
| 708 | 937 | type DCFEV_CLOCK_ENABLE; \ |
| @@ -815,16 +1044,31 @@ struct dce_hwseq_registers { · 106 unmodified lines | ||
| 815 | 1044 | type D2VGA_MODE_ENABLE; \ |
| 816 | 1045 | type D3VGA_MODE_ENABLE; \ |
| 817 | 1046 | type D4VGA_MODE_ENABLE; \ |
| 818 | − type AZALIA_AUDIO_DTO_MODULE; | |
| 1047 | + type AZALIA_AUDIO_DTO_MODULE; \ | |
| 1048 | + type ODM_MEM_UNASSIGNED_PWR_MODE; \ | |
| 1049 | + type ODM_MEM_VBLANK_PWR_MODE; | |
| 1050 | + | |
| 1051 | +#define HWSEQ_DCN3_REG_FIELD_LIST(type) \ | |
| 1052 | + type HPO_HDMISTREAMCLK_GATE_DIS; | |
| 1053 | + | |
| 1054 | +#define HWSEQ_DCN301_REG_FIELD_LIST(type) \ | |
| 1055 | + type PANEL_BLON;\ | |
| 1056 | + type PANEL_DIGON;\ | |
| 1057 | + type PANEL_DIGON_OVRD;\ | |
| 1058 | + type PANEL_PWRSEQ_TARGET_STATE_R; | |
| 819 | 1059 | |
| 820 | 1060 | struct dce_hwseq_shift { |
| 821 | 1061 | HWSEQ_REG_FIELD_LIST(uint8_t) |
| 822 | 1062 | HWSEQ_DCN_REG_FIELD_LIST(uint8_t) |
| 1063 | + HWSEQ_DCN3_REG_FIELD_LIST(uint8_t) | |
| 1064 | + HWSEQ_DCN301_REG_FIELD_LIST(uint8_t) | |
| 823 | 1065 | }; |
| 824 | 1066 | |
| 825 | 1067 | struct dce_hwseq_mask { |
| 826 | 1068 | HWSEQ_REG_FIELD_LIST(uint32_t) |
| 827 | 1069 | HWSEQ_DCN_REG_FIELD_LIST(uint32_t) |
| 1070 | + HWSEQ_DCN3_REG_FIELD_LIST(uint32_t) | |
| 1071 | + HWSEQ_DCN301_REG_FIELD_LIST(uint32_t) | |
| 828 | 1072 | }; |
| 829 | 1073 | |
| 830 | 1074 | |
| @@ -299,8 +299,12 @@ static bool setup_engine( · 298 unmodified lines | ||
| 299 | 299 | /* we have checked I2c not used by DMCU, set SW use I2C REQ to 1 to indicate SW using it*/ |
| 300 | 300 | REG_UPDATE(DC_I2C_ARBITRATION, DC_I2C_SW_USE_I2C_REG_REQ, 1); |
| 301 | 301 | |
| 302 | + /*set SW requested I2c speed to default, if API calls in it will be override later*/ | |
| 303 | + set_speed(dce_i2c_hw, dce_i2c_hw->ctx->dc->caps.i2c_speed_in_khz); | |
| 304 | + | |
| 302 | 305 | if (dce_i2c_hw->setup_limit != 0) |
| 303 | 306 | i2c_setup_limit = dce_i2c_hw->setup_limit; |
| 307 | + | |
| 304 | 308 | /* Program pin select */ |
| 305 | 309 | REG_UPDATE_6(DC_I2C_CONTROL, |
| 306 | 310 | DC_I2C_GO, 0, |
| @@ -339,8 +343,6 @@ static void release_engine( · 32 unmodified lines | ||
| 339 | 343 | { |
| 340 | 344 | bool safe_to_reset; |
| 341 | 345 | |
| 342 | − /* Restore original HW engine speed */ | |
| 343 | − set_speed(dce_i2c_hw, dce_i2c_hw->default_speed); | |
| 344 | 346 | |
| 345 | 347 | /* Reset HW engine */ |
| 346 | 348 | { |
| @@ -360,6 +362,9 @@ static void release_engine( · 13 unmodified lines | ||
| 360 | 362 | /* HW I2c engine - clock gating feature */ |
| 361 | 363 | if (!dce_i2c_hw->engine_keep_power_up_count) |
| 362 | 364 | REG_UPDATE_N(SETUP, 1, FN(SETUP, DC_I2C_DDC1_ENABLE), 0); |
| 365 | + | |
| 366 | + /*for HW HDCP Ri polling failure w/a test*/ | |
| 367 | + set_speed(dce_i2c_hw, dce_i2c_hw->ctx->dc->caps.i2c_speed_in_khz_hdcp); | |
| 363 | 368 | /* Release I2C after reset, so HW or DMCU could use it */ |
| 364 | 369 | REG_UPDATE_2(DC_I2C_ARBITRATION, DC_I2C_SW_DONE_USING_I2C_REG, 1, |
| 365 | 370 | DC_I2C_SW_USE_I2C_REG_REQ, 0); |
| @@ -1330,7 +1330,6 @@ static bool configure_graphics_mode( · 1329 unmodified lines | ||
| 1330 | 1330 | REG_SET(OUTPUT_CSC_CONTROL, 0, |
| 1331 | 1331 | OUTPUT_CSC_GRPH_MODE, 0); |
| 1332 | 1332 | break; |
| 1333 | − break; | |
| 1334 | 1333 | case COLOR_SPACE_SRGB_LIMITED: |
| 1335 | 1334 | /* TV RGB */ |
| 1336 | 1335 | REG_SET(OUTPUT_CSC_CONTROL, 0, |
| @@ -418,25 +418,18 @@ static int map_transmitter_id_to_phy_instance( · 417 unmodified lines | ||
| 418 | 418 | switch (transmitter) { |
| 419 | 419 | case TRANSMITTER_UNIPHY_A: |
| 420 | 420 | return 0; |
| 421 | − break; | |
| 422 | 421 | case TRANSMITTER_UNIPHY_B: |
| 423 | 422 | return 1; |
| 424 | − break; | |
| 425 | 423 | case TRANSMITTER_UNIPHY_C: |
| 426 | 424 | return 2; |
| 427 | − break; | |
| 428 | 425 | case TRANSMITTER_UNIPHY_D: |
| 429 | 426 | return 3; |
| 430 | − break; | |
| 431 | 427 | case TRANSMITTER_UNIPHY_E: |
| 432 | 428 | return 4; |
| 433 | − break; | |
| 434 | 429 | case TRANSMITTER_UNIPHY_F: |
| 435 | 430 | return 5; |
| 436 | − break; | |
| 437 | 431 | case TRANSMITTER_UNIPHY_G: |
| 438 | 432 | return 6; |
| 439 | − break; | |
| 440 | 433 | default: |
| 441 | 434 | ASSERT(0); |
| 442 | 435 | return 0; |
| @@ -1071,7 +1064,9 @@ static bool dce100_resource_construct( · 628 unmodified lines | ||
| 1071 | 1064 | pool->base.timing_generator_count = pool->base.res_cap->num_timing_generator; |
| 1072 | 1065 | dc->caps.max_downscale_ratio = 200; |
| 1073 | 1066 | dc->caps.i2c_speed_in_khz = 40; |
| 1067 | + dc->caps.i2c_speed_in_khz = 40; | |
| 1074 | 1068 | dc->caps.max_cursor_size = 128; |
| 1069 | + dc->caps.min_horizontal_blanking_period = 80; | |
| 1075 | 1070 | dc->caps.dual_link_dvi = true; |
| 1076 | 1071 | dc->caps.disable_dp_clk_share = true; |
| 1077 | 1072 | dc->caps.extended_aux_timeout_support = false; |
| @@ -992,8 +992,6 @@ void dce110_edp_backlight_control( · 991 unmodified lines | ||
| 992 | 992 | |
| 993 | 993 | link_transmitter_control(ctx->dc_bios, &cntl); |
| 994 | 994 | |
| 995 | − | |
| 996 | − | |
| 997 | 995 | if (enable && link->dpcd_sink_ext_caps.bits.oled) |
| 998 | 996 | msleep(OLED_POST_T7_DELAY); |
| 999 | 997 | |
| @@ -1004,7 +1002,7 @@ void dce110_edp_backlight_control( · 4 unmodified lines | ||
| 1004 | 1002 | |
| 1005 | 1003 | /*edp 1.2*/ |
| 1006 | 1004 | if (cntl.action == TRANSMITTER_CONTROL_BACKLIGHT_OFF) |
| 1007 | − edp_receiver_ready_T9(link); | |
| 1005 | + edp_add_delay_for_T9(link); | |
| 1008 | 1006 | |
| 1009 | 1007 | if (!enable && link->dpcd_sink_ext_caps.bits.oled) |
| 1010 | 1008 | msleep(OLED_PRE_T11_DELAY); |
| @@ -1145,12 +1143,14 @@ void dce110_blank_stream(struct pipe_ctx *pipe_ctx) · 134 unmodified lines | ||
| 1145 | 1143 | if (dc_is_dp_signal(pipe_ctx->stream->signal)) { |
| 1146 | 1144 | pipe_ctx->stream_res.stream_enc->funcs->dp_blank(pipe_ctx->stream_res.stream_enc); |
| 1147 | 1145 | |
| 1148 | − /* | |
| 1149 | − * After output is idle pattern some sinks need time to recognize the stream | |
| 1150 | − * has changed or they enter protection state and hang. | |
| 1151 | − */ | |
| 1152 | − if (!dc_is_embedded_signal(pipe_ctx->stream->signal)) | |
| 1146 | + if (!dc_is_embedded_signal(pipe_ctx->stream->signal)) { | |
| 1147 | + /* | |
| 1148 | + * After output is idle pattern some sinks need time to recognize the stream | |
| 1149 | + * has changed or they enter protection state and hang. | |
| 1150 | + */ | |
| 1153 | 1151 | msleep(60); |
| 1152 | + } else if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP) | |
| 1153 | + edp_receiver_ready_T9(link); | |
| 1154 | 1154 | } |
| 1155 | 1155 | |
| 1156 | 1156 | } |
| @@ -471,25 +471,18 @@ static int map_transmitter_id_to_phy_instance( · 470 unmodified lines | ||
| 471 | 471 | switch (transmitter) { |
| 472 | 472 | case TRANSMITTER_UNIPHY_A: |
| 473 | 473 | return 0; |
| 474 | − break; | |
| 475 | 474 | case TRANSMITTER_UNIPHY_B: |
| 476 | 475 | return 1; |
| 477 | − break; | |
| 478 | 476 | case TRANSMITTER_UNIPHY_C: |
| 479 | 477 | return 2; |
| 480 | − break; | |
| 481 | 478 | case TRANSMITTER_UNIPHY_D: |
| 482 | 479 | return 3; |
| 483 | − break; | |
| 484 | 480 | case TRANSMITTER_UNIPHY_E: |
| 485 | 481 | return 4; |
| 486 | − break; | |
| 487 | 482 | case TRANSMITTER_UNIPHY_F: |
| 488 | 483 | return 5; |
| 489 | − break; | |
| 490 | 484 | case TRANSMITTER_UNIPHY_G: |
| 491 | 485 | return 6; |
| 492 | − break; | |
| 493 | 486 | default: |
| 494 | 487 | ASSERT(0); |
| 495 | 488 | return 0; |
| @@ -1372,8 +1365,10 @@ static bool dce110_resource_construct( · 876 unmodified lines | ||
| 1372 | 1365 | pool->base.underlay_pipe_index = pool->base.pipe_count; |
| 1373 | 1366 | pool->base.timing_generator_count = pool->base.res_cap->num_timing_generator; |
| 1374 | 1367 | dc->caps.max_downscale_ratio = 150; |
| 1375 | − dc->caps.i2c_speed_in_khz = 100; | |
| 1368 | + dc->caps.i2c_speed_in_khz = 40; | |
| 1369 | + dc->caps.i2c_speed_in_khz_hdcp = 40; | |
| 1376 | 1370 | dc->caps.max_cursor_size = 128; |
| 1371 | + dc->caps.min_horizontal_blanking_period = 80; | |
| 1377 | 1372 | dc->caps.is_apu = true; |
| 1378 | 1373 | dc->caps.extended_aux_timeout_support = false; |
| 1379 | 1374 | |
| @@ -446,25 +446,18 @@ static int map_transmitter_id_to_phy_instance( · 445 unmodified lines | ||
| 446 | 446 | switch (transmitter) { |
| 447 | 447 | case TRANSMITTER_UNIPHY_A: |
| 448 | 448 | return 0; |
| 449 | − break; | |
| 450 | 449 | case TRANSMITTER_UNIPHY_B: |
| 451 | 450 | return 1; |
| 452 | − break; | |
| 453 | 451 | case TRANSMITTER_UNIPHY_C: |
| 454 | 452 | return 2; |
| 455 | − break; | |
| 456 | 453 | case TRANSMITTER_UNIPHY_D: |
| 457 | 454 | return 3; |
| 458 | − break; | |
| 459 | 455 | case TRANSMITTER_UNIPHY_E: |
| 460 | 456 | return 4; |
| 461 | − break; | |
| 462 | 457 | case TRANSMITTER_UNIPHY_F: |
| 463 | 458 | return 5; |
| 464 | − break; | |
| 465 | 459 | case TRANSMITTER_UNIPHY_G: |
| 466 | 460 | return 6; |
| 467 | − break; | |
| 468 | 461 | default: |
| 469 | 462 | ASSERT(0); |
| 470 | 463 | return 0; |
| @@ -865,7 +858,7 @@ static struct clock_source *find_matching_pll( · 394 unmodified lines | ||
| 865 | 858 | return pool->clock_sources[DCE112_CLK_SRC_PLL5]; |
| 866 | 859 | default: |
| 867 | 860 | return NULL; |
| 868 | − }; | |
| 861 | + } | |
| 869 | 862 | |
| 870 | 863 | return 0; |
| 871 | 864 | } |
| @@ -1240,7 +1233,9 @@ static bool dce112_resource_construct( · 368 unmodified lines | ||
| 1240 | 1233 | pool->base.timing_generator_count = pool->base.res_cap->num_timing_generator; |
| 1241 | 1234 | dc->caps.max_downscale_ratio = 200; |
| 1242 | 1235 | dc->caps.i2c_speed_in_khz = 100; |
| 1236 | + dc->caps.i2c_speed_in_khz_hdcp = 100; /*1.4 w/a not applied by default*/ | |
| 1243 | 1237 | dc->caps.max_cursor_size = 128; |
| 1238 | + dc->caps.min_horizontal_blanking_period = 80; | |
| 1244 | 1239 | dc->caps.dual_link_dvi = true; |
| 1245 | 1240 | dc->caps.extended_aux_timeout_support = false; |
| 1246 | 1241 | |
| @@ -383,25 +383,18 @@ static int map_transmitter_id_to_phy_instance( · 382 unmodified lines | ||
| 383 | 383 | switch (transmitter) { |
| 384 | 384 | case TRANSMITTER_UNIPHY_A: |
| 385 | 385 | return 0; |
| 386 | − break; | |
| 387 | 386 | case TRANSMITTER_UNIPHY_B: |
| 388 | 387 | return 1; |
| 389 | − break; | |
| 390 | 388 | case TRANSMITTER_UNIPHY_C: |
| 391 | 389 | return 2; |
| 392 | − break; | |
| 393 | 390 | case TRANSMITTER_UNIPHY_D: |
| 394 | 391 | return 3; |
| 395 | − break; | |
| 396 | 392 | case TRANSMITTER_UNIPHY_E: |
| 397 | 393 | return 4; |
| 398 | − break; | |
| 399 | 394 | case TRANSMITTER_UNIPHY_F: |
| 400 | 395 | return 5; |
| 401 | − break; | |
| 402 | 396 | case TRANSMITTER_UNIPHY_G: |
| 403 | 397 | return 6; |
| 404 | − break; | |
| 405 | 398 | default: |
| 406 | 399 | ASSERT(0); |
| 407 | 400 | return 0; |
| @@ -1080,7 +1073,9 @@ static bool dce120_resource_construct( · 672 unmodified lines | ||
| 1080 | 1073 | |
| 1081 | 1074 | dc->caps.max_downscale_ratio = 200; |
| 1082 | 1075 | dc->caps.i2c_speed_in_khz = 100; |
| 1076 | + dc->caps.i2c_speed_in_khz_hdcp = 100; /*1.4 w/a not applied by default*/ | |
| 1083 | 1077 | dc->caps.max_cursor_size = 128; |
| 1078 | + dc->caps.min_horizontal_blanking_period = 80; | |
| 1084 | 1079 | dc->caps.dual_link_dvi = true; |
| 1085 | 1080 | dc->caps.psp_setup_panel_mode = true; |
| 1086 | 1081 | dc->caps.extended_aux_timeout_support = false; |
| @@ -453,25 +453,18 @@ static int map_transmitter_id_to_phy_instance( · 452 unmodified lines | ||
| 453 | 453 | switch (transmitter) { |
| 454 | 454 | case TRANSMITTER_UNIPHY_A: |
| 455 | 455 | return 0; |
| 456 | − break; | |
| 457 | 456 | case TRANSMITTER_UNIPHY_B: |
| 458 | 457 | return 1; |
| 459 | − break; | |
| 460 | 458 | case TRANSMITTER_UNIPHY_C: |
| 461 | 459 | return 2; |
| 462 | − break; | |
| 463 | 460 | case TRANSMITTER_UNIPHY_D: |
| 464 | 461 | return 3; |
| 465 | − break; | |
| 466 | 462 | case TRANSMITTER_UNIPHY_E: |
| 467 | 463 | return 4; |
| 468 | − break; | |
| 469 | 464 | case TRANSMITTER_UNIPHY_F: |
| 470 | 465 | return 5; |
| 471 | − break; | |
| 472 | 466 | case TRANSMITTER_UNIPHY_G: |
| 473 | 467 | return 6; |
| 474 | − break; | |
| 475 | 468 | default: |
| 476 | 469 | ASSERT(0); |
| 477 | 470 | return 0; |
| @@ -458,25 +458,18 @@ static int map_transmitter_id_to_phy_instance( · 457 unmodified lines | ||
| 458 | 458 | switch (transmitter) { |
| 459 | 459 | case TRANSMITTER_UNIPHY_A: |
| 460 | 460 | return 0; |
| 461 | − break; | |
| 462 | 461 | case TRANSMITTER_UNIPHY_B: |
| 463 | 462 | return 1; |
| 464 | − break; | |
| 465 | 463 | case TRANSMITTER_UNIPHY_C: |
| 466 | 464 | return 2; |
| 467 | − break; | |
| 468 | 465 | case TRANSMITTER_UNIPHY_D: |
| 469 | 466 | return 3; |
| 470 | − break; | |
| 471 | 467 | case TRANSMITTER_UNIPHY_E: |
| 472 | 468 | return 4; |
| 473 | − break; | |
| 474 | 469 | case TRANSMITTER_UNIPHY_F: |
| 475 | 470 | return 5; |
| 476 | − break; | |
| 477 | 471 | case TRANSMITTER_UNIPHY_G: |
| 478 | 472 | return 6; |
| 479 | − break; | |
| 480 | 473 | default: |
| 481 | 474 | ASSERT(0); |
| 482 | 475 | return 0; |
| @@ -970,7 +963,9 @@ static bool dce80_construct( · 487 unmodified lines | ||
| 970 | 963 | pool->base.timing_generator_count = res_cap.num_timing_generator; |
| 971 | 964 | dc->caps.max_downscale_ratio = 200; |
| 972 | 965 | dc->caps.i2c_speed_in_khz = 40; |
| 966 | + dc->caps.i2c_speed_in_khz_hdcp = 40; | |
| 973 | 967 | dc->caps.max_cursor_size = 128; |
| 968 | + dc->caps.min_horizontal_blanking_period = 80; | |
| 974 | 969 | dc->caps.dual_link_dvi = true; |
| 975 | 970 | dc->caps.extended_aux_timeout_support = false; |
| 976 | 971 | |
| @@ -1168,7 +1163,9 @@ static bool dce81_construct( · 191 unmodified lines | ||
| 1168 | 1163 | pool->base.timing_generator_count = res_cap_81.num_timing_generator; |
| 1169 | 1164 | dc->caps.max_downscale_ratio = 200; |
| 1170 | 1165 | dc->caps.i2c_speed_in_khz = 40; |
| 1166 | + dc->caps.i2c_speed_in_khz_hdcp = 40; | |
| 1171 | 1167 | dc->caps.max_cursor_size = 128; |
| 1168 | + dc->caps.min_horizontal_blanking_period = 80; | |
| 1172 | 1169 | dc->caps.is_apu = true; |
| 1173 | 1170 | |
| 1174 | 1171 | /************************************************* |
| @@ -1365,7 +1362,9 @@ static bool dce83_construct( · 190 unmodified lines | ||
| 1365 | 1362 | pool->base.timing_generator_count = res_cap_83.num_timing_generator; |
| 1366 | 1363 | dc->caps.max_downscale_ratio = 200; |
| 1367 | 1364 | dc->caps.i2c_speed_in_khz = 40; |
| 1365 | + dc->caps.i2c_speed_in_khz_hdcp = 40; | |
| 1368 | 1366 | dc->caps.max_cursor_size = 128; |
| 1367 | + dc->caps.min_horizontal_blanking_period = 80; | |
| 1369 | 1368 | dc->caps.is_apu = true; |
| 1370 | 1369 | |
| 1371 | 1370 | /************************************************* |
| @@ -656,7 +656,7 @@ static void dpp1_dscl_set_recout( · 655 unmodified lines | ||
| 656 | 656 | RECOUT_WIDTH, recout->width, |
| 657 | 657 | /* Number of RECOUT vertical lines */ |
| 658 | 658 | RECOUT_HEIGHT, recout->height |
| 659 | − - visual_confirm_on * 4 * (dpp->base.inst + 1)); | |
| 659 | + - visual_confirm_on * 2 * (dpp->base.inst + 1)); | |
| 660 | 660 | } |
| 661 | 661 | |
| 662 | 662 | /* Main function to program scaler and line buffer in manual scaling mode */ |
| @@ -326,7 +326,6 @@ void hubp1_program_pixel_format( · 325 unmodified lines | ||
| 326 | 326 | REG_UPDATE(DCSURF_SURFACE_CONFIG, |
| 327 | 327 | SURFACE_PIXEL_FORMAT, 119); |
| 328 | 328 | break; |
| 329 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 330 | 329 | case SURFACE_PIXEL_FORMAT_GRPH_RGBE: |
| 331 | 330 | REG_UPDATE_2(DCSURF_SURFACE_CONFIG, |
| 332 | 331 | SURFACE_PIXEL_FORMAT, 116, |
| @@ -337,7 +336,6 @@ void hubp1_program_pixel_format( · 4 unmodified lines | ||
| 337 | 336 | SURFACE_PIXEL_FORMAT, 116, |
| 338 | 337 | ALPHA_PLANE_EN, 1); |
| 339 | 338 | break; |
| 340 | −#endif | |
| 341 | 339 | default: |
| 342 | 340 | BREAK_TO_DEBUGGER(); |
| 343 | 341 | break; |
| @@ -52,6 +52,7 @@ · 51 unmodified lines | ||
| 52 | 52 | #include "dpcd_defs.h" |
| 53 | 53 | #include "dsc.h" |
| 54 | 54 | #include "dce/dmub_hw_lock_mgr.h" |
| 55 | +#include "dc_trace.h" | |
| 55 | 56 | |
| 56 | 57 | #define DC_LOGGER_INIT(logger) |
| 57 | 58 | |
| @@ -1020,15 +1021,17 @@ static bool dcn10_hw_wa_force_recovery(struct dc *dc) · 962 unmodified lines | ||
| 1020 | 1021 | |
| 1021 | 1022 | } |
| 1022 | 1023 | |
| 1023 | − | |
| 1024 | 1024 | void dcn10_verify_allow_pstate_change_high(struct dc *dc) |
| 1025 | 1025 | { |
| 1026 | 1026 | static bool should_log_hw_state; /* prevent hw state log by default */ |
| 1027 | 1027 | |
| 1028 | 1028 | if (!hubbub1_verify_allow_pstate_change_high(dc->res_pool->hubbub)) { |
| 1029 | − if (should_log_hw_state) { | |
| 1029 | + int i = 0; | |
| 1030 | + | |
| 1031 | + if (should_log_hw_state) | |
| 1030 | 1032 | dcn10_log_hw_state(dc, NULL); |
| 1031 | − } | |
| 1033 | + | |
| 1034 | + TRACE_DC_PIPE_STATE(pipe_ctx, i, MAX_PIPES); | |
| 1032 | 1035 | BREAK_TO_DEBUGGER(); |
| 1033 | 1036 | if (dcn10_hw_wa_force_recovery(dc)) { |
| 1034 | 1037 | /*check again*/ |
| @@ -1434,12 +1437,6 @@ void dcn10_init_hw(struct dc *dc) · 399 unmodified lines | ||
| 1434 | 1437 | |
| 1435 | 1438 | if (dc->clk_mgr->funcs->notify_wm_ranges) |
| 1436 | 1439 | dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr); |
| 1437 | − | |
| 1438 | −#ifdef CONFIG_DRM_AMD_DC_DCN3_0 | |
| 1439 | − if (dc->clk_mgr->funcs->set_hard_max_memclk) | |
| 1440 | − dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr); | |
| 1441 | −#endif | |
| 1442 | − | |
| 1443 | 1440 | } |
| 1444 | 1441 | |
| 1445 | 1442 | /* In headless boot cases, DIG may be turned |
| @@ -1541,6 +1538,8 @@ static bool patch_address_for_sbs_tb_stereo( · 95 unmodified lines | ||
| 1541 | 1538 | plane_state->address.type = PLN_ADDR_TYPE_GRPH_STEREO; |
| 1542 | 1539 | plane_state->address.grph_stereo.right_addr = |
| 1543 | 1540 | plane_state->address.grph_stereo.left_addr; |
| 1541 | + plane_state->address.grph_stereo.right_meta_addr = | |
| 1542 | + plane_state->address.grph_stereo.left_meta_addr; | |
| 1544 | 1543 | } |
| 1545 | 1544 | } |
| 1546 | 1545 | return false; |
| @@ -1851,10 +1850,20 @@ void dcn10_enable_timing_synchronization( · 304 unmodified lines | ||
| 1851 | 1850 | struct pipe_ctx *grouped_pipes[]) |
| 1852 | 1851 | { |
| 1853 | 1852 | struct dc_context *dc_ctx = dc->ctx; |
| 1854 | − int i; | |
| 1853 | + struct output_pixel_processor *opp; | |
| 1854 | + struct timing_generator *tg; | |
| 1855 | + int i, width, height; | |
| 1855 | 1856 | |
| 1856 | 1857 | DC_SYNC_INFO("Setting up OTG reset trigger\n"); |
| 1857 | 1858 | |
| 1859 | + for (i = 1; i < group_size; i++) { | |
| 1860 | + opp = grouped_pipes[i]->stream_res.opp; | |
| 1861 | + tg = grouped_pipes[i]->stream_res.tg; | |
| 1862 | + tg->funcs->get_otg_active_size(tg, &width, &height); | |
| 1863 | + if (opp->funcs->opp_program_dpg_dimensions) | |
| 1864 | + opp->funcs->opp_program_dpg_dimensions(opp, width, 2*(height) + 1); | |
| 1865 | + } | |
| 1866 | + | |
| 1858 | 1867 | for (i = 1; i < group_size; i++) |
| 1859 | 1868 | grouped_pipes[i]->stream_res.tg->funcs->enable_reset_trigger( |
| 1860 | 1869 | grouped_pipes[i]->stream_res.tg, |
| @@ -1871,6 +1880,14 @@ void dcn10_enable_timing_synchronization( · 10 unmodified lines | ||
| 1871 | 1880 | grouped_pipes[i]->stream_res.tg->funcs->disable_reset_trigger( |
| 1872 | 1881 | grouped_pipes[i]->stream_res.tg); |
| 1873 | 1882 | |
| 1883 | + for (i = 1; i < group_size; i++) { | |
| 1884 | + opp = grouped_pipes[i]->stream_res.opp; | |
| 1885 | + tg = grouped_pipes[i]->stream_res.tg; | |
| 1886 | + tg->funcs->get_otg_active_size(tg, &width, &height); | |
| 1887 | + if (opp->funcs->opp_program_dpg_dimensions) | |
| 1888 | + opp->funcs->opp_program_dpg_dimensions(opp, width, height); | |
| 1889 | + } | |
| 1890 | + | |
| 1874 | 1891 | DC_SYNC_INFO("Sync complete\n"); |
| 1875 | 1892 | } |
| 1876 | 1893 | |
| @@ -2761,122 +2778,6 @@ static struct pipe_ctx *dcn10_find_top_pipe_for_stream( · 884 unmodified lines | ||
| 2761 | 2778 | return NULL; |
| 2762 | 2779 | } |
| 2763 | 2780 | |
| 2764 | −bool dcn10_disconnect_pipes( | |
| 2765 | − struct dc *dc, | |
| 2766 | − struct dc_state *context) | |
| 2767 | −{ | |
| 2768 | − bool found_pipe = false; | |
| 2769 | − int i, j; | |
| 2770 | − struct dce_hwseq *hws = dc->hwseq; | |
| 2771 | − struct dc_state *old_ctx = dc->current_state; | |
| 2772 | − bool mpcc_disconnected = false; | |
| 2773 | − struct pipe_ctx *old_pipe; | |
| 2774 | − struct pipe_ctx *new_pipe; | |
| 2775 | − DC_LOGGER_INIT(dc->ctx->logger); | |
| 2776 | − | |
| 2777 | − /* Set pipe update flags and lock pipes */ | |
| 2778 | − for (i = 0; i < dc->res_pool->pipe_count; i++) { | |
| 2779 | − old_pipe = &dc->current_state->res_ctx.pipe_ctx[i]; | |
| 2780 | − new_pipe = &context->res_ctx.pipe_ctx[i]; | |
| 2781 | − new_pipe->update_flags.raw = 0; | |
| 2782 | − | |
| 2783 | − if (!old_pipe->plane_state && !new_pipe->plane_state) | |
| 2784 | − continue; | |
| 2785 | − | |
| 2786 | − if (old_pipe->plane_state && !new_pipe->plane_state) | |
| 2787 | − new_pipe->update_flags.bits.disable = 1; | |
| 2788 | − | |
| 2789 | − /* Check for scl update */ | |
| 2790 | − if (memcmp(&old_pipe->plane_res.scl_data, &new_pipe->plane_res.scl_data, sizeof(struct scaler_data))) | |
| 2791 | − new_pipe->update_flags.bits.scaler = 1; | |
| 2792 | − | |
| 2793 | − /* Check for vp update */ | |
| 2794 | − if (memcmp(&old_pipe->plane_res.scl_data.viewport, &new_pipe->plane_res.scl_data.viewport, sizeof(struct rect)) | |
| 2795 | − || memcmp(&old_pipe->plane_res.scl_data.viewport_c, | |
| 2796 | − &new_pipe->plane_res.scl_data.viewport_c, sizeof(struct rect))) | |
| 2797 | − new_pipe->update_flags.bits.viewport = 1; | |
| 2798 | − | |
| 2799 | − } | |
| 2800 | − | |
| 2801 | − if (!IS_DIAG_DC(dc->ctx->dce_environment)) { | |
| 2802 | − /* Disconnect mpcc here only if losing pipe split*/ | |
| 2803 | − for (i = 0; i < dc->res_pool->pipe_count; i++) { | |
| 2804 | − if (context->res_ctx.pipe_ctx[i].update_flags.bits.disable && | |
| 2805 | − old_ctx->res_ctx.pipe_ctx[i].top_pipe) { | |
| 2806 | − | |
| 2807 | − /* Find the top pipe in the new ctx for the bottom pipe that we | |
| 2808 | − * want to remove by comparing the streams and planes. If both | |
| 2809 | − * pipes are being disabled then do it in the regular pipe | |
| 2810 | − * programming sequence | |
| 2811 | − */ | |
| 2812 | − for (j = 0; j < dc->res_pool->pipe_count; j++) { | |
| 2813 | − if (old_ctx->res_ctx.pipe_ctx[i].top_pipe->stream == context->res_ctx.pipe_ctx[j].stream && | |
| 2814 | − old_ctx->res_ctx.pipe_ctx[i].top_pipe->plane_state == context->res_ctx.pipe_ctx[j].plane_state && | |
| 2815 | − !context->res_ctx.pipe_ctx[j].top_pipe && | |
| 2816 | − !context->res_ctx.pipe_ctx[j].update_flags.bits.disable) { | |
| 2817 | − found_pipe = true; | |
| 2818 | − break; | |
| 2819 | − } | |
| 2820 | − } | |
| 2821 | − | |
| 2822 | − // Disconnect if the top pipe lost it's pipe split | |
| 2823 | − if (found_pipe && !context->res_ctx.pipe_ctx[j].bottom_pipe) { | |
| 2824 | − hws->funcs.plane_atomic_disconnect(dc, &dc->current_state->res_ctx.pipe_ctx[i]); | |
| 2825 | − DC_LOG_DC("Reset mpcc for pipe %d\n", dc->current_state->res_ctx.pipe_ctx[i].pipe_idx); | |
| 2826 | − mpcc_disconnected = true; | |
| 2827 | − } | |
| 2828 | − } | |
| 2829 | − found_pipe = false; | |
| 2830 | − } | |
| 2831 | − } | |
| 2832 | − | |
| 2833 | − if (mpcc_disconnected) { | |
| 2834 | − for (i = 0; i < dc->res_pool->pipe_count; i++) { | |
| 2835 | − struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; | |
| 2836 | − struct pipe_ctx *old_pipe = &dc->current_state->res_ctx.pipe_ctx[i]; | |
| 2837 | − struct dc_plane_state *plane_state = pipe_ctx->plane_state; | |
| 2838 | − struct hubp *hubp = pipe_ctx->plane_res.hubp; | |
| 2839 | − | |
| 2840 | − if (!pipe_ctx || !plane_state || !pipe_ctx->stream) | |
| 2841 | − continue; | |
| 2842 | − | |
| 2843 | − // Only update scaler and viewport here if we lose a pipe split. | |
| 2844 | − // This is to prevent half the screen from being black when we | |
| 2845 | − // unlock after disconnecting MPCC. | |
| 2846 | − if (!(old_pipe && !pipe_ctx->top_pipe && | |
| 2847 | − !pipe_ctx->bottom_pipe && old_pipe->bottom_pipe)) | |
| 2848 | − continue; | |
| 2849 | − | |
| 2850 | − if (pipe_ctx->update_flags.raw || pipe_ctx->plane_state->update_flags.raw || pipe_ctx->stream->update_flags.raw) { | |
| 2851 | − if (pipe_ctx->update_flags.bits.scaler || | |
| 2852 | − plane_state->update_flags.bits.scaling_change || | |
| 2853 | − plane_state->update_flags.bits.position_change || | |
| 2854 | − plane_state->update_flags.bits.per_pixel_alpha_change || | |
| 2855 | − pipe_ctx->stream->update_flags.bits.scaling) { | |
| 2856 | − | |
| 2857 | − pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->plane_state->per_pixel_alpha; | |
| 2858 | − ASSERT(pipe_ctx->plane_res.scl_data.lb_params.depth == LB_PIXEL_DEPTH_30BPP); | |
| 2859 | − /* scaler configuration */ | |
| 2860 | − pipe_ctx->plane_res.dpp->funcs->dpp_set_scaler( | |
| 2861 | − pipe_ctx->plane_res.dpp, &pipe_ctx->plane_res.scl_data); | |
| 2862 | − } | |
| 2863 | − | |
| 2864 | − if (pipe_ctx->update_flags.bits.viewport || | |
| 2865 | − (context == dc->current_state && plane_state->update_flags.bits.position_change) || | |
| 2866 | − (context == dc->current_state && plane_state->update_flags.bits.scaling_change) || | |
| 2867 | − (context == dc->current_state && pipe_ctx->stream->update_flags.bits.scaling)) { | |
| 2868 | − | |
| 2869 | − hubp->funcs->mem_program_viewport( | |
| 2870 | − hubp, | |
| 2871 | − &pipe_ctx->plane_res.scl_data.viewport, | |
| 2872 | − &pipe_ctx->plane_res.scl_data.viewport_c); | |
| 2873 | − } | |
| 2874 | − } | |
| 2875 | − } | |
| 2876 | − } | |
| 2877 | − return mpcc_disconnected; | |
| 2878 | −} | |
| 2879 | − | |
| 2880 | 2781 | void dcn10_wait_for_pending_cleared(struct dc *dc, |
| 2881 | 2782 | struct dc_state *context) |
| 2882 | 2783 | { |
| @@ -34,7 +34,6 @@ static const struct hw_sequencer_funcs dcn10_funcs = { · 33 unmodified lines | ||
| 34 | 34 | .apply_ctx_to_hw = dce110_apply_ctx_to_hw, |
| 35 | 35 | .apply_ctx_for_surface = dcn10_apply_ctx_for_surface, |
| 36 | 36 | .post_unlock_program_front_end = dcn10_post_unlock_program_front_end, |
| 37 | − .disconnect_pipes = dcn10_disconnect_pipes, | |
| 38 | 37 | .wait_for_pending_cleared = dcn10_wait_for_pending_cleared, |
| 39 | 38 | .update_plane_addr = dcn10_update_plane_addr, |
| 40 | 39 | .update_dchub = dcn10_update_dchub, |
| @@ -154,12 +154,10 @@ struct dcn10_link_enc_registers { · 153 unmodified lines | ||
| 154 | 154 | uint32_t RAWLANE2_DIG_PCS_XF_RX_OVRD_IN_3; |
| 155 | 155 | uint32_t RAWLANE3_DIG_PCS_XF_RX_OVRD_IN_2; |
| 156 | 156 | uint32_t RAWLANE3_DIG_PCS_XF_RX_OVRD_IN_3; |
| 157 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 158 | 157 | uint32_t TMDS_DCBALANCER_CONTROL; |
| 159 | 158 | uint32_t PHYA_LINK_CNTL2; |
| 160 | 159 | uint32_t PHYB_LINK_CNTL2; |
| 161 | 160 | uint32_t PHYC_LINK_CNTL2; |
| 162 | −#endif | |
| 163 | 161 | }; |
| 164 | 162 | |
| 165 | 163 | #define LE_SF(reg_name, field_name, post_fix)\ |
| @@ -449,14 +447,25 @@ struct dcn10_link_enc_registers { · 283 unmodified lines | ||
| 449 | 447 | type AUX_RX_TIMEOUT_LEN;\ |
| 450 | 448 | type AUX_RX_TIMEOUT_LEN_MUL |
| 451 | 449 | |
| 450 | +#define DCN30_LINK_ENCODER_REG_FIELD_LIST(type) \ | |
| 451 | + type TMDS_SYNC_DCBAL_EN;\ | |
| 452 | + type PHY_HPO_DIG_SRC_SEL;\ | |
| 453 | + type PHY_HPO_ENC_SRC_SEL;\ | |
| 454 | + type DPCS_TX_HDMI_FRL_MODE;\ | |
| 455 | + type DPCS_TX_DATA_SWAP_10_BIT;\ | |
| 456 | + type DPCS_TX_DATA_ORDER_INVERT_18_BIT;\ | |
| 457 | + type RDPCS_TX_CLK_EN | |
| 458 | + | |
| 452 | 459 | struct dcn10_link_enc_shift { |
| 453 | 460 | DCN_LINK_ENCODER_REG_FIELD_LIST(uint8_t); |
| 454 | 461 | DCN20_LINK_ENCODER_REG_FIELD_LIST(uint8_t); |
| 462 | + DCN30_LINK_ENCODER_REG_FIELD_LIST(uint8_t); | |
| 455 | 463 | }; |
| 456 | 464 | |
| 457 | 465 | struct dcn10_link_enc_mask { |
| 458 | 466 | DCN_LINK_ENCODER_REG_FIELD_LIST(uint32_t); |
| 459 | 467 | DCN20_LINK_ENCODER_REG_FIELD_LIST(uint32_t); |
| 468 | + DCN30_LINK_ENCODER_REG_FIELD_LIST(uint32_t); | |
| 460 | 469 | }; |
| 461 | 470 | |
| 462 | 471 | struct dcn10_link_encoder { |
| @@ -403,6 +403,7 @@ static const struct opp_funcs dcn10_opp_funcs = { · 402 unmodified lines | ||
| 403 | 403 | .opp_program_stereo = opp1_program_stereo, |
| 404 | 404 | .opp_pipe_clock_control = opp1_pipe_clock_control, |
| 405 | 405 | .opp_set_disp_pattern_generator = NULL, |
| 406 | + .opp_program_dpg_dimensions = NULL, | |
| 406 | 407 | .dpg_is_blanked = NULL, |
| 407 | 408 | .opp_destroy = opp1_destroy |
| 408 | 409 | }; |
| @@ -299,16 +299,13 @@ void optc1_program_timing( · 298 unmodified lines | ||
| 299 | 299 | REG_UPDATE(OPTC_DATA_FORMAT_CONTROL, OPTC_DATA_FORMAT, data_fmt); |
| 300 | 300 | } |
| 301 | 301 | |
| 302 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 303 | 302 | if (optc1->tg_mask->OTG_H_TIMING_DIV_MODE != 0) { |
| 304 | 303 | if (optc1->opp_count == 4) |
| 305 | 304 | h_div = H_TIMING_DIV_BY4; |
| 306 | 305 | |
| 307 | 306 | REG_UPDATE(OTG_H_TIMING_CNTL, |
| 308 | 307 | OTG_H_TIMING_DIV_MODE, h_div); |
| 309 | − } else | |
| 310 | −#endif | |
| 311 | − { | |
| 308 | + } else { | |
| 312 | 309 | REG_UPDATE(OTG_H_TIMING_CNTL, |
| 313 | 310 | OTG_H_TIMING_DIV_BY2, h_div); |
| 314 | 311 | } |
| @@ -171,7 +171,6 @@ struct dcn_optc_registers { · 170 unmodified lines | ||
| 171 | 171 | uint32_t OPTC_DATA_FORMAT_CONTROL; |
| 172 | 172 | uint32_t OPTC_BYTES_PER_PIXEL; |
| 173 | 173 | uint32_t OPTC_WIDTH_CONTROL; |
| 174 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 175 | 174 | uint32_t OTG_BLANK_DATA_COLOR; |
| 176 | 175 | uint32_t OTG_BLANK_DATA_COLOR_EXT; |
| 177 | 176 | uint32_t OTG_DRR_TRIGGER_WINDOW; |
| @@ -179,7 +178,6 @@ struct dcn_optc_registers { · 1 unmodified line | ||
| 179 | 178 | uint32_t OTG_M_CONST_DTO1; |
| 180 | 179 | uint32_t OTG_DRR_V_TOTAL_CHANGE; |
| 181 | 180 | uint32_t OTG_GLOBAL_CONTROL4; |
| 182 | −#endif | |
| 183 | 181 | }; |
| 184 | 182 | |
| 185 | 183 | #define TG_COMMON_MASK_SH_LIST_DCN(mask_sh)\ |
| @@ -474,8 +472,6 @@ struct dcn_optc_registers { · 288 unmodified lines | ||
| 474 | 472 | type MANUAL_FLOW_CONTROL;\ |
| 475 | 473 | type MANUAL_FLOW_CONTROL_SEL; |
| 476 | 474 | |
| 477 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 478 | − | |
| 479 | 475 | #define TG_REG_FIELD_LIST(type) \ |
| 480 | 476 | TG_REG_FIELD_LIST_DCN1_0(type)\ |
| 481 | 477 | type OTG_V_SYNC_MODE;\ |
| @@ -517,33 +513,6 @@ struct dcn_optc_registers { · 35 unmodified lines | ||
| 517 | 513 | type OTG_CRC_DATA_STREAM_COMBINE_MODE;\ |
| 518 | 514 | type OTG_CRC_DATA_STREAM_SPLIT_MODE;\ |
| 519 | 515 | type OTG_CRC_DATA_FORMAT; |
| 520 | −#else | |
| 521 | − | |
| 522 | −#define TG_REG_FIELD_LIST(type) \ | |
| 523 | − TG_REG_FIELD_LIST_DCN1_0(type)\ | |
| 524 | − type MASTER_UPDATE_LOCK_DB_X;\ | |
| 525 | − type MASTER_UPDATE_LOCK_DB_Y;\ | |
| 526 | − type MASTER_UPDATE_LOCK_DB_EN;\ | |
| 527 | − type GLOBAL_UPDATE_LOCK_EN;\ | |
| 528 | − type DIG_UPDATE_LOCATION;\ | |
| 529 | − type OTG_DSC_START_POSITION_X;\ | |
| 530 | − type OTG_DSC_START_POSITION_LINE_NUM;\ | |
| 531 | − type OPTC_NUM_OF_INPUT_SEGMENT;\ | |
| 532 | − type OPTC_SEG0_SRC_SEL;\ | |
| 533 | − type OPTC_SEG1_SRC_SEL;\ | |
| 534 | − type OPTC_MEM_SEL;\ | |
| 535 | − type OPTC_DATA_FORMAT;\ | |
| 536 | − type OPTC_DSC_MODE;\ | |
| 537 | − type OPTC_DSC_BYTES_PER_PIXEL;\ | |
| 538 | − type OPTC_DSC_SLICE_WIDTH;\ | |
| 539 | − type OPTC_SEGMENT_WIDTH;\ | |
| 540 | − type OPTC_DWB0_SOURCE_SELECT;\ | |
| 541 | − type OPTC_DWB1_SOURCE_SELECT;\ | |
| 542 | − type OTG_CRC_DSC_MODE;\ | |
| 543 | − type OTG_CRC_DATA_STREAM_COMBINE_MODE;\ | |
| 544 | − type OTG_CRC_DATA_STREAM_SPLIT_MODE;\ | |
| 545 | − type OTG_CRC_DATA_FORMAT; | |
| 546 | −#endif | |
| 547 | 516 | |
| 548 | 517 | |
| 549 | 518 | struct dcn_optc_shift { |
| @@ -1416,7 +1416,9 @@ static bool dcn10_resource_construct( · 1415 unmodified lines | ||
| 1416 | 1416 | dc->caps.max_video_width = 3840; |
| 1417 | 1417 | dc->caps.max_downscale_ratio = 200; |
| 1418 | 1418 | dc->caps.i2c_speed_in_khz = 100; |
| 1419 | + dc->caps.i2c_speed_in_khz_hdcp = 100; /*1.4 w/a not applied by default*/ | |
| 1419 | 1420 | dc->caps.max_cursor_size = 256; |
| 1421 | + dc->caps.min_horizontal_blanking_period = 80; | |
| 1420 | 1422 | dc->caps.max_slave_planes = 1; |
| 1421 | 1423 | dc->caps.is_apu = true; |
| 1422 | 1424 | dc->caps.post_blend_color_processing = false; |
| @@ -169,14 +169,12 @@ struct dcn10_stream_enc_registers { · 168 unmodified lines | ||
| 169 | 169 | uint32_t DP_SEC_METADATA_TRANSMISSION; |
| 170 | 170 | uint32_t HDMI_METADATA_PACKET_CONTROL; |
| 171 | 171 | uint32_t DP_SEC_FRAMING4; |
| 172 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 173 | 172 | uint32_t DP_GSP11_CNTL; |
| 174 | 173 | uint32_t HDMI_GENERIC_PACKET_CONTROL6; |
| 175 | 174 | uint32_t HDMI_GENERIC_PACKET_CONTROL7; |
| 176 | 175 | uint32_t HDMI_GENERIC_PACKET_CONTROL8; |
| 177 | 176 | uint32_t HDMI_GENERIC_PACKET_CONTROL9; |
| 178 | 177 | uint32_t HDMI_GENERIC_PACKET_CONTROL10; |
| 179 | −#endif | |
| 180 | 178 | uint32_t DIG_CLOCK_PATTERN; |
| 181 | 179 | }; |
| 182 | 180 | |
| @@ -505,7 +503,6 @@ struct dcn10_stream_enc_registers { · 322 unmodified lines | ||
| 505 | 503 | type DP_PIXEL_COMBINE;\ |
| 506 | 504 | type DP_SST_SDP_SPLITTING |
| 507 | 505 | |
| 508 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 509 | 506 | #define SE_REG_FIELD_LIST_DCN3_0(type) \ |
| 510 | 507 | type HDMI_GENERIC8_CONT;\ |
| 511 | 508 | type HDMI_GENERIC8_SEND;\ |
| @@ -531,22 +528,17 @@ struct dcn10_stream_enc_registers { · 19 unmodified lines | ||
| 531 | 528 | type DP_SEC_GSP11_PPS;\ |
| 532 | 529 | type DP_SEC_GSP11_ENABLE;\ |
| 533 | 530 | type DP_SEC_GSP11_LINE_NUM |
| 534 | −#endif | |
| 535 | 531 | |
| 536 | 532 | struct dcn10_stream_encoder_shift { |
| 537 | 533 | SE_REG_FIELD_LIST_DCN1_0(uint8_t); |
| 538 | 534 | SE_REG_FIELD_LIST_DCN2_0(uint8_t); |
| 539 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 540 | 535 | SE_REG_FIELD_LIST_DCN3_0(uint8_t); |
| 541 | −#endif | |
| 542 | 536 | }; |
| 543 | 537 | |
| 544 | 538 | struct dcn10_stream_encoder_mask { |
| 545 | 539 | SE_REG_FIELD_LIST_DCN1_0(uint32_t); |
| 546 | 540 | SE_REG_FIELD_LIST_DCN2_0(uint32_t); |
| 547 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 548 | 541 | SE_REG_FIELD_LIST_DCN3_0(uint32_t); |
| 549 | −#endif | |
| 550 | 542 | }; |
| 551 | 543 | |
| 552 | 544 | struct dcn10_stream_encoder { |
| @@ -76,7 +76,6 @@ · 75 unmodified lines | ||
| 76 | 76 | type REFCLK_CLOCK_EN;\ |
| 77 | 77 | type REFCLK_SRC_SEL; |
| 78 | 78 | |
| 79 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 80 | 79 | #define DCCG3_REG_FIELD_LIST(type) \ |
| 81 | 80 | type PHYASYMCLK_FORCE_EN;\ |
| 82 | 81 | type PHYASYMCLK_FORCE_SRC_SEL;\ |
| @@ -84,32 +83,25 @@ · 1 unmodified line | ||
| 84 | 83 | type PHYBSYMCLK_FORCE_SRC_SEL;\ |
| 85 | 84 | type PHYCSYMCLK_FORCE_EN;\ |
| 86 | 85 | type PHYCSYMCLK_FORCE_SRC_SEL; |
| 87 | −#endif | |
| 88 | 86 | |
| 89 | 87 | struct dccg_shift { |
| 90 | 88 | DCCG_REG_FIELD_LIST(uint8_t) |
| 91 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 92 | 89 | DCCG3_REG_FIELD_LIST(uint8_t) |
| 93 | −#endif | |
| 94 | 90 | }; |
| 95 | 91 | |
| 96 | 92 | struct dccg_mask { |
| 97 | 93 | DCCG_REG_FIELD_LIST(uint32_t) |
| 98 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 99 | 94 | DCCG3_REG_FIELD_LIST(uint32_t) |
| 100 | −#endif | |
| 101 | 95 | }; |
| 102 | 96 | |
| 103 | 97 | struct dccg_registers { |
| 104 | 98 | uint32_t DPPCLK_DTO_CTRL; |
| 105 | 99 | uint32_t DPPCLK_DTO_PARAM[6]; |
| 106 | 100 | uint32_t REFCLK_CNTL; |
| 107 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 108 | 101 | uint32_t HDMICHARCLK_CLOCK_CNTL[6]; |
| 109 | 102 | uint32_t PHYASYMCLK_CLOCK_CNTL; |
| 110 | 103 | uint32_t PHYBSYMCLK_CLOCK_CNTL; |
| 111 | 104 | uint32_t PHYCSYMCLK_CLOCK_CNTL; |
| 112 | −#endif | |
| 113 | 105 | }; |
| 114 | 106 | |
| 115 | 107 | struct dcn_dccg { |
| @@ -153,10 +153,8 @@ bool hubbub2_dcc_support_pixel_format( · 152 unmodified lines | ||
| 153 | 153 | case SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FIX: |
| 154 | 154 | case SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FLOAT: |
| 155 | 155 | case SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FLOAT: |
| 156 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 157 | 156 | case SURFACE_PIXEL_FORMAT_GRPH_RGBE: |
| 158 | 157 | case SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA: |
| 159 | −#endif | |
| 160 | 158 | *bytes_per_element = 4; |
| 161 | 159 | return true; |
| 162 | 160 | case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616: |
| @@ -343,11 +341,9 @@ static enum dcn_hubbub_page_table_block_size page_table_block_size_to_hw(unsigne · 180 unmodified lines | ||
| 343 | 341 | case 65536: |
| 344 | 342 | block_size = DCN_PAGE_TABLE_BLOCK_SIZE_64KB; |
| 345 | 343 | break; |
| 346 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 347 | 344 | case 32768: |
| 348 | 345 | block_size = DCN_PAGE_TABLE_BLOCK_SIZE_32KB; |
| 349 | 346 | break; |
| 350 | −#endif | |
| 351 | 347 | default: |
| 352 | 348 | ASSERT(false); |
| 353 | 349 | block_size = page_table_block_size; |
| @@ -336,10 +336,8 @@ void hubp2_program_size( · 335 unmodified lines | ||
| 336 | 336 | */ |
| 337 | 337 | use_pitch_c = format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN |
| 338 | 338 | && format < SURFACE_PIXEL_FORMAT_SUBSAMPLE_END; |
| 339 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 340 | 339 | use_pitch_c = use_pitch_c |
| 341 | 340 | || (format == SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA); |
| 342 | −#endif | |
| 343 | 341 | if (use_pitch_c) { |
| 344 | 342 | ASSERT(plane_size->chroma_pitch != 0); |
| 345 | 343 | /* Chroma pitch zero can cause system hang! */ |
| @@ -364,10 +362,8 @@ void hubp2_program_size( · 18 unmodified lines | ||
| 364 | 362 | PITCH, pitch, META_PITCH, meta_pitch); |
| 365 | 363 | |
| 366 | 364 | use_pitch_c = format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN; |
| 367 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 368 | 365 | use_pitch_c = use_pitch_c |
| 369 | 366 | || (format == SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA); |
| 370 | −#endif | |
| 371 | 367 | if (use_pitch_c) |
| 372 | 368 | REG_UPDATE_2(DCSURF_SURFACE_PITCH_C, |
| 373 | 369 | PITCH_C, pitch_c, META_PITCH_C, meta_pitch_c); |
| @@ -513,7 +509,6 @@ void hubp2_program_pixel_format( · 139 unmodified lines | ||
| 513 | 509 | REG_UPDATE(DCSURF_SURFACE_CONFIG, |
| 514 | 510 | SURFACE_PIXEL_FORMAT, 119); |
| 515 | 511 | break; |
| 516 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 517 | 512 | case SURFACE_PIXEL_FORMAT_GRPH_RGBE: |
| 518 | 513 | REG_UPDATE_2(DCSURF_SURFACE_CONFIG, |
| 519 | 514 | SURFACE_PIXEL_FORMAT, 116, |
| @@ -524,7 +519,6 @@ void hubp2_program_pixel_format( · 4 unmodified lines | ||
| 524 | 519 | SURFACE_PIXEL_FORMAT, 116, |
| 525 | 520 | ALPHA_PLANE_EN, 1); |
| 526 | 521 | break; |
| 527 | −#endif | |
| 528 | 522 | default: |
| 529 | 523 | BREAK_TO_DEBUGGER(); |
| 530 | 524 | break; |
| @@ -157,11 +157,9 @@ · 156 unmodified lines | ||
| 157 | 157 | uint32_t VBLANK_PARAMETERS_5;\ |
| 158 | 158 | uint32_t VBLANK_PARAMETERS_6 |
| 159 | 159 | |
| 160 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 161 | 160 | #define DCN30_HUBP_REG_COMMON_VARIABLE_LIST \ |
| 162 | 161 | DCN21_HUBP_REG_COMMON_VARIABLE_LIST;\ |
| 163 | 162 | uint32_t DCN_DMDATA_VM_CNTL |
| 164 | −#endif | |
| 165 | 163 | |
| 166 | 164 | #define DCN2_HUBP_REG_FIELD_VARIABLE_LIST(type) \ |
| 167 | 165 | DCN_HUBP_REG_FIELD_BASE_LIST(type); \ |
| @@ -198,7 +196,6 @@ · 30 unmodified lines | ||
| 198 | 196 | type REFCYC_PER_META_CHUNK_FLIP_C; \ |
| 199 | 197 | type VM_GROUP_SIZE |
| 200 | 198 | |
| 201 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 202 | 199 | #define DCN30_HUBP_REG_FIELD_VARIABLE_LIST(type) \ |
| 203 | 200 | DCN21_HUBP_REG_FIELD_VARIABLE_LIST(type);\ |
| 204 | 201 | type PRIMARY_SURFACE_DCC_IND_BLK;\ |
| @@ -218,32 +215,17 @@ · 13 unmodified lines | ||
| 218 | 215 | type PACK_3TO2_ELEMENT_DISABLE; \ |
| 219 | 216 | type ROW_TTU_MODE; \ |
| 220 | 217 | type NUM_PKRS |
| 221 | −#endif | |
| 222 | 218 | |
| 223 | 219 | struct dcn_hubp2_registers { |
| 224 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 225 | 220 | DCN30_HUBP_REG_COMMON_VARIABLE_LIST; |
| 226 | −#else | |
| 227 | − DCN21_HUBP_REG_COMMON_VARIABLE_LIST; | |
| 228 | −#endif | |
| 229 | 221 | }; |
| 230 | 222 | |
| 231 | 223 | struct dcn_hubp2_shift { |
| 232 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 233 | 224 | DCN30_HUBP_REG_FIELD_VARIABLE_LIST(uint8_t); |
| 234 | −#else | |
| 235 | − DCN21_HUBP_REG_FIELD_VARIABLE_LIST(uint8_t); | |
| 236 | −#endif | |
| 237 | − | |
| 238 | 225 | }; |
| 239 | 226 | |
| 240 | 227 | struct dcn_hubp2_mask { |
| 241 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 242 | 228 | DCN30_HUBP_REG_FIELD_VARIABLE_LIST(uint32_t); |
| 243 | −#else | |
| 244 | − DCN21_HUBP_REG_FIELD_VARIABLE_LIST(uint32_t); | |
| 245 | −#endif | |
| 246 | − | |
| 247 | 229 | }; |
| 248 | 230 | |
| 249 | 231 | struct dcn20_hubp { |
| @@ -611,7 +611,6 @@ void dcn20_disable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx) · 610 unmodified lines | ||
| 611 | 611 | pipe_ctx->pipe_idx); |
| 612 | 612 | } |
| 613 | 613 | |
| 614 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 615 | 614 | static int calc_mpc_flow_ctrl_cnt(const struct dc_stream_state *stream, |
| 616 | 615 | int opp_cnt) |
| 617 | 616 | { |
| @@ -634,7 +633,6 @@ static int calc_mpc_flow_ctrl_cnt(const struct dc_stream_state *stream, · 16 unmodified lines | ||
| 634 | 633 | |
| 635 | 634 | return flow_ctrl_cnt; |
| 636 | 635 | } |
| 637 | −#endif | |
| 638 | 636 | |
| 639 | 637 | enum dc_status dcn20_enable_stream_timing( |
| 640 | 638 | struct pipe_ctx *pipe_ctx, |
| @@ -648,16 +646,12 @@ enum dc_status dcn20_enable_stream_timing( · 7 unmodified lines | ||
| 648 | 646 | struct pipe_ctx *odm_pipe; |
| 649 | 647 | int opp_cnt = 1; |
| 650 | 648 | int opp_inst[MAX_PIPES] = { pipe_ctx->stream_res.opp->inst }; |
| 651 | − | |
| 652 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 653 | 649 | bool interlace = stream->timing.flags.INTERLACE; |
| 654 | 650 | int i; |
| 655 | − | |
| 656 | 651 | struct mpc_dwb_flow_control flow_control; |
| 657 | 652 | struct mpc *mpc = dc->res_pool->mpc; |
| 658 | 653 | bool rate_control_2x_pclk = (interlace || optc2_is_two_pixels_per_containter(&stream->timing)); |
| 659 | 654 | |
| 660 | −#endif | |
| 661 | 655 | /* by upper caller loop, pipe0 is parent pipe and be called first. |
| 662 | 656 | * back end is set up by for pipe0. Other children pipe share back end |
| 663 | 657 | * with pipe 0. No program is needed. |
| @@ -704,7 +698,6 @@ enum dc_status dcn20_enable_stream_timing( · 40 unmodified lines | ||
| 704 | 698 | pipe_ctx->stream->signal, |
| 705 | 699 | true); |
| 706 | 700 | |
| 707 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 708 | 701 | rate_control_2x_pclk = rate_control_2x_pclk || opp_cnt > 1; |
| 709 | 702 | flow_control.flow_ctrl_mode = 0; |
| 710 | 703 | flow_control.flow_ctrl_cnt0 = 0x80; |
| @@ -718,7 +711,7 @@ enum dc_status dcn20_enable_stream_timing( · 7 unmodified lines | ||
| 718 | 711 | &flow_control); |
| 719 | 712 | } |
| 720 | 713 | } |
| 721 | −#endif | |
| 714 | + | |
| 722 | 715 | for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) |
| 723 | 716 | odm_pipe->stream_res.opp->funcs->opp_pipe_clock_control( |
| 724 | 717 | odm_pipe->stream_res.opp, |
| @@ -1030,8 +1023,8 @@ void dcn20_blank_pixel_data( · 305 unmodified lines | ||
| 1030 | 1023 | test_pattern = CONTROLLER_DP_TEST_PATTERN_VIDEOMODE; |
| 1031 | 1024 | } |
| 1032 | 1025 | |
| 1033 | − stream_res->opp->funcs->opp_set_disp_pattern_generator( | |
| 1034 | − stream_res->opp, | |
| 1026 | + dc->hwss.set_disp_pattern_generator(dc, | |
| 1027 | + pipe_ctx, | |
| 1035 | 1028 | test_pattern, |
| 1036 | 1029 | test_pattern_color_space, |
| 1037 | 1030 | stream->timing.display_color_depth, |
| @@ -1041,8 +1034,8 @@ void dcn20_blank_pixel_data( · 3 unmodified lines | ||
| 1041 | 1034 | 0); |
| 1042 | 1035 | |
| 1043 | 1036 | for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) { |
| 1044 | − odm_pipe->stream_res.opp->funcs->opp_set_disp_pattern_generator( | |
| 1045 | − odm_pipe->stream_res.opp, | |
| 1037 | + dc->hwss.set_disp_pattern_generator(dc, | |
| 1038 | + odm_pipe, | |
| 1046 | 1039 | dc->debug.visual_confirm != VISUAL_CONFIRM_DISABLE && blank ? |
| 1047 | 1040 | CONTROLLER_DP_TEST_PATTERN_COLORRAMP : test_pattern, |
| 1048 | 1041 | test_pattern_color_space, |
| @@ -1158,6 +1151,7 @@ void dcn20_pipe_control_lock( · 109 unmodified lines | ||
| 1158 | 1151 | struct pipe_ctx *pipe, |
| 1159 | 1152 | bool lock) |
| 1160 | 1153 | { |
| 1154 | + struct pipe_ctx *temp_pipe; | |
| 1161 | 1155 | bool flip_immediate = false; |
| 1162 | 1156 | |
| 1163 | 1157 | /* use TG master update lock to lock everything on the TG |
| @@ -1169,6 +1163,13 @@ void dcn20_pipe_control_lock( · 5 unmodified lines | ||
| 1169 | 1163 | if (pipe->plane_state != NULL) |
| 1170 | 1164 | flip_immediate = pipe->plane_state->flip_immediate; |
| 1171 | 1165 | |
| 1166 | + temp_pipe = pipe->bottom_pipe; | |
| 1167 | + while (!flip_immediate && temp_pipe) { | |
| 1168 | + if (temp_pipe->plane_state != NULL) | |
| 1169 | + flip_immediate = temp_pipe->plane_state->flip_immediate; | |
| 1170 | + temp_pipe = temp_pipe->bottom_pipe; | |
| 1171 | + } | |
| 1172 | + | |
| 1172 | 1173 | if (flip_immediate && lock) { |
| 1173 | 1174 | const int TIMEOUT_FOR_FLIP_PENDING = 100000; |
| 1174 | 1175 | int i; |
| @@ -1191,11 +1192,25 @@ void dcn20_pipe_control_lock( · 16 unmodified lines | ||
| 1191 | 1192 | /* In flip immediate and pipe splitting case, we need to use GSL |
| 1192 | 1193 | * for synchronization. Only do setup on locking and on flip type change. |
| 1193 | 1194 | */ |
| 1194 | − if (lock && pipe->bottom_pipe != NULL) | |
| 1195 | + if (lock && (pipe->bottom_pipe != NULL || !flip_immediate)) | |
| 1195 | 1196 | if ((flip_immediate && pipe->stream_res.gsl_group == 0) || |
| 1196 | 1197 | (!flip_immediate && pipe->stream_res.gsl_group > 0)) |
| 1197 | 1198 | dcn20_setup_gsl_group_as_lock(dc, pipe, flip_immediate); |
| 1198 | 1199 | |
| 1200 | + if (pipe->plane_state != NULL) | |
| 1201 | + flip_immediate = pipe->plane_state->flip_immediate; | |
| 1202 | + | |
| 1203 | + temp_pipe = pipe->bottom_pipe; | |
| 1204 | + while (flip_immediate && temp_pipe) { | |
| 1205 | + if (temp_pipe->plane_state != NULL) | |
| 1206 | + flip_immediate = temp_pipe->plane_state->flip_immediate; | |
| 1207 | + temp_pipe = temp_pipe->bottom_pipe; | |
| 1208 | + } | |
| 1209 | + | |
| 1210 | + if (!lock && pipe->stream_res.gsl_group > 0 && pipe->plane_state && | |
| 1211 | + !flip_immediate) | |
| 1212 | + dcn20_setup_gsl_group_as_lock(dc, pipe, false); | |
| 1213 | + | |
| 1199 | 1214 | if (pipe->stream && should_use_dmub_lock(pipe->stream->link)) { |
| 1200 | 1215 | union dmub_hw_lock_flags hw_locks = { 0 }; |
| 1201 | 1216 | struct dmub_hw_lock_inst_flags inst_flags = { 0 }; |
| @@ -1478,7 +1493,6 @@ static void dcn20_update_dchubp_dpp( · 276 unmodified lines | ||
| 1478 | 1493 | if (pipe_ctx->update_flags.bits.enable || pipe_ctx->update_flags.bits.opp_changed |
| 1479 | 1494 | || pipe_ctx->stream->update_flags.bits.gamut_remap |
| 1480 | 1495 | || pipe_ctx->stream->update_flags.bits.out_csc) { |
| 1481 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 1482 | 1496 | struct mpc *mpc = pipe_ctx->stream_res.opp->ctx->dc->res_pool->mpc; |
| 1483 | 1497 | |
| 1484 | 1498 | if (mpc->funcs->set_gamut_remap) { |
| @@ -1509,7 +1523,6 @@ static void dcn20_update_dchubp_dpp( · 24 unmodified lines | ||
| 1509 | 1523 | } |
| 1510 | 1524 | mpc->funcs->set_gamut_remap(mpc, mpcc_id, &adjust); |
| 1511 | 1525 | } else |
| 1512 | −#endif | |
| 1513 | 1526 | /* dpp/cm gamut remap*/ |
| 1514 | 1527 | dc->hwss.program_gamut_remap(pipe_ctx); |
| 1515 | 1528 | |
| @@ -2034,6 +2047,8 @@ static bool patch_address_for_sbs_tb_stereo( · 518 unmodified lines | ||
| 2034 | 2047 | plane_state->address.type = PLN_ADDR_TYPE_GRPH_STEREO; |
| 2035 | 2048 | plane_state->address.grph_stereo.right_addr = |
| 2036 | 2049 | plane_state->address.grph_stereo.left_addr; |
| 2050 | + plane_state->address.grph_stereo.right_meta_addr = | |
| 2051 | + plane_state->address.grph_stereo.left_meta_addr; | |
| 2037 | 2052 | } |
| 2038 | 2053 | return false; |
| 2039 | 2054 | } |
| @@ -2282,11 +2297,9 @@ void dcn20_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx) · 242 unmodified lines | ||
| 2282 | 2297 | blnd_cfg.bottom_inside_gain = 0x1f000; |
| 2283 | 2298 | blnd_cfg.bottom_outside_gain = 0x1f000; |
| 2284 | 2299 | blnd_cfg.pre_multiplied_alpha = per_pixel_alpha; |
| 2285 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 2286 | 2300 | if (pipe_ctx->plane_state->format |
| 2287 | 2301 | == SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA) |
| 2288 | 2302 | blnd_cfg.pre_multiplied_alpha = false; |
| 2289 | −#endif | |
| 2290 | 2303 | |
| 2291 | 2304 | /* |
| 2292 | 2305 | * TODO: remove hack |
| @@ -2545,3 +2558,15 @@ bool dcn20_optimize_timing_for_fsft(struct dc *dc, · 252 unmodified lines | ||
| 2545 | 2558 | return true; |
| 2546 | 2559 | } |
| 2547 | 2560 | #endif |
| 2561 | + | |
| 2562 | +void dcn20_set_disp_pattern_generator(const struct dc *dc, | |
| 2563 | + struct pipe_ctx *pipe_ctx, | |
| 2564 | + enum controller_dp_test_pattern test_pattern, | |
| 2565 | + enum controller_dp_color_space color_space, | |
| 2566 | + enum dc_color_depth color_depth, | |
| 2567 | + const struct tg_color *solid_color, | |
| 2568 | + int width, int height, int offset) | |
| 2569 | +{ | |
| 2570 | + pipe_ctx->stream_res.opp->funcs->opp_set_disp_pattern_generator(pipe_ctx->stream_res.opp, test_pattern, | |
| 2571 | + color_space, color_depth, solid_color, width, height, offset); | |
| 2572 | +} | |
| @@ -137,5 +137,14 @@ bool dcn20_optimize_timing_for_fsft(struct dc *dc, · 136 unmodified lines | ||
| 137 | 137 | struct dc_crtc_timing *timing, |
| 138 | 138 | unsigned int max_input_rate_in_khz); |
| 139 | 139 | #endif |
| 140 | + | |
| 141 | +void dcn20_set_disp_pattern_generator(const struct dc *dc, | |
| 142 | + struct pipe_ctx *pipe_ctx, | |
| 143 | + enum controller_dp_test_pattern test_pattern, | |
| 144 | + enum controller_dp_color_space color_space, | |
| 145 | + enum dc_color_depth color_depth, | |
| 146 | + const struct tg_color *solid_color, | |
| 147 | + int width, int height, int offset); | |
| 148 | + | |
| 140 | 149 | #endif /* __DC_HWSS_DCN20_H__ */ |
| 141 | 150 | |
| @@ -34,7 +34,6 @@ static const struct hw_sequencer_funcs dcn20_funcs = { · 33 unmodified lines | ||
| 34 | 34 | .apply_ctx_to_hw = dce110_apply_ctx_to_hw, |
| 35 | 35 | .apply_ctx_for_surface = NULL, |
| 36 | 36 | .program_front_end_for_ctx = dcn20_program_front_end_for_ctx, |
| 37 | − .disconnect_pipes = dcn10_disconnect_pipes, | |
| 38 | 37 | .wait_for_pending_cleared = dcn10_wait_for_pending_cleared, |
| 39 | 38 | .post_unlock_program_front_end = dcn20_post_unlock_program_front_end, |
| 40 | 39 | .update_plane_addr = dcn20_update_plane_addr, |
| @@ -94,6 +93,7 @@ static const struct hw_sequencer_funcs dcn20_funcs = { · 53 unmodified lines | ||
| 94 | 93 | #ifndef TRIM_FSFT |
| 95 | 94 | .optimize_timing_for_fsft = dcn20_optimize_timing_for_fsft, |
| 96 | 95 | #endif |
| 96 | + .set_disp_pattern_generator = dcn20_set_disp_pattern_generator, | |
| 97 | 97 | }; |
| 98 | 98 | |
| 99 | 99 | static const struct hwseq_private_funcs dcn20_private_funcs = { |
| @@ -276,10 +276,8 @@ struct mpll_cfg { · 275 unmodified lines | ||
| 276 | 276 | bool dp_tx1_vergdrv_byp; |
| 277 | 277 | bool dp_tx2_vergdrv_byp; |
| 278 | 278 | bool dp_tx3_vergdrv_byp; |
| 279 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 280 | 279 | uint32_t tx_peaking_lvl; |
| 281 | 280 | uint32_t ctr_reqs_pll; |
| 282 | −#endif | |
| 283 | 281 | |
| 284 | 282 | |
| 285 | 283 | }; |
| @@ -290,6 +290,17 @@ void opp2_set_disp_pattern_generator( · 289 unmodified lines | ||
| 290 | 290 | } |
| 291 | 291 | } |
| 292 | 292 | |
| 293 | +void opp2_program_dpg_dimensions( | |
| 294 | + struct output_pixel_processor *opp, | |
| 295 | + int width, int height) | |
| 296 | +{ | |
| 297 | + struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp); | |
| 298 | + | |
| 299 | + REG_SET_2(DPG_DIMENSIONS, 0, | |
| 300 | + DPG_ACTIVE_WIDTH, width, | |
| 301 | + DPG_ACTIVE_HEIGHT, height); | |
| 302 | +} | |
| 303 | + | |
| 293 | 304 | void opp2_dpg_set_blank_color( |
| 294 | 305 | struct output_pixel_processor *opp, |
| 295 | 306 | const struct tg_color *color) |
| @@ -350,6 +361,7 @@ static struct opp_funcs dcn20_opp_funcs = { · 54 unmodified lines | ||
| 350 | 361 | .opp_program_stereo = opp1_program_stereo, |
| 351 | 362 | .opp_pipe_clock_control = opp1_pipe_clock_control, |
| 352 | 363 | .opp_set_disp_pattern_generator = opp2_set_disp_pattern_generator, |
| 364 | + .opp_program_dpg_dimensions = opp2_program_dpg_dimensions, | |
| 353 | 365 | .dpg_is_blanked = opp2_dpg_is_blanked, |
| 354 | 366 | .opp_dpg_set_blank_color = opp2_dpg_set_blank_color, |
| 355 | 367 | .opp_destroy = opp1_destroy, |
| @@ -153,6 +153,10 @@ void opp2_set_disp_pattern_generator( · 152 unmodified lines | ||
| 153 | 153 | int height, |
| 154 | 154 | int offset); |
| 155 | 155 | |
| 156 | +void opp2_program_dpg_dimensions( | |
| 157 | + struct output_pixel_processor *opp, | |
| 158 | + int width, int height); | |
| 159 | + | |
| 156 | 160 | bool opp2_dpg_is_blanked(struct output_pixel_processor *opp); |
| 157 | 161 | |
| 158 | 162 | void opp2_dpg_set_blank_color( |
| @@ -1882,9 +1882,16 @@ bool dcn20_split_stream_for_odm( · 1881 unmodified lines | ||
| 1882 | 1882 | next_odm_pipe->next_odm_pipe = prev_odm_pipe->next_odm_pipe; |
| 1883 | 1883 | next_odm_pipe->next_odm_pipe->prev_odm_pipe = next_odm_pipe; |
| 1884 | 1884 | } |
| 1885 | + if (prev_odm_pipe->top_pipe && prev_odm_pipe->top_pipe->next_odm_pipe) { | |
| 1886 | + prev_odm_pipe->top_pipe->next_odm_pipe->bottom_pipe = next_odm_pipe; | |
| 1887 | + next_odm_pipe->top_pipe = prev_odm_pipe->top_pipe->next_odm_pipe; | |
| 1888 | + } | |
| 1889 | + if (prev_odm_pipe->bottom_pipe && prev_odm_pipe->bottom_pipe->next_odm_pipe) { | |
| 1890 | + prev_odm_pipe->bottom_pipe->next_odm_pipe->top_pipe = next_odm_pipe; | |
| 1891 | + next_odm_pipe->bottom_pipe = prev_odm_pipe->bottom_pipe->next_odm_pipe; | |
| 1892 | + } | |
| 1885 | 1893 | prev_odm_pipe->next_odm_pipe = next_odm_pipe; |
| 1886 | 1894 | next_odm_pipe->prev_odm_pipe = prev_odm_pipe; |
| 1887 | − ASSERT(next_odm_pipe->top_pipe == NULL); | |
| 1888 | 1895 | |
| 1889 | 1896 | if (prev_odm_pipe->plane_state) { |
| 1890 | 1897 | struct scaler_data *sd = &prev_odm_pipe->plane_res.scl_data; |
| @@ -1922,7 +1929,10 @@ bool dcn20_split_stream_for_odm( · 31 unmodified lines | ||
| 1922 | 1929 | sd->ratios.horz_c, sd->h_active - sd->recout.x)); |
| 1923 | 1930 | sd->recout.x = 0; |
| 1924 | 1931 | } |
| 1925 | − next_odm_pipe->stream_res.opp = pool->opps[next_odm_pipe->pipe_idx]; | |
| 1932 | + if (!next_odm_pipe->top_pipe) | |
| 1933 | + next_odm_pipe->stream_res.opp = pool->opps[next_odm_pipe->pipe_idx]; | |
| 1934 | + else | |
| 1935 | + next_odm_pipe->stream_res.opp = next_odm_pipe->top_pipe->stream_res.opp; | |
| 1926 | 1936 | if (next_odm_pipe->stream->timing.flags.DSC == 1) { |
| 1927 | 1937 | dcn20_acquire_dsc(dc, res_ctx, &next_odm_pipe->stream_res.dsc, next_odm_pipe->pipe_idx); |
| 1928 | 1938 | ASSERT(next_odm_pipe->stream_res.dsc); |
| @@ -2033,10 +2043,8 @@ int dcn20_populate_dml_pipes_from_context( · 104 unmodified lines | ||
| 2033 | 2043 | unsigned int v_total; |
| 2034 | 2044 | unsigned int front_porch; |
| 2035 | 2045 | int output_bpc; |
| 2036 | − | |
| 2037 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 2038 | 2046 | struct audio_check aud_check = {0}; |
| 2039 | −#endif | |
| 2047 | + | |
| 2040 | 2048 | if (!res_ctx->pipe_ctx[i].stream) |
| 2041 | 2049 | continue; |
| 2042 | 2050 | |
| @@ -2091,11 +2099,9 @@ int dcn20_populate_dml_pipes_from_context( · 48 unmodified lines | ||
| 2091 | 2099 | case 1: |
| 2092 | 2100 | pipes[pipe_cnt].pipe.dest.odm_combine = dm_odm_combine_mode_2to1; |
| 2093 | 2101 | break; |
| 2094 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 2095 | 2102 | case 3: |
| 2096 | 2103 | pipes[pipe_cnt].pipe.dest.odm_combine = dm_odm_combine_mode_4to1; |
| 2097 | 2104 | break; |
| 2098 | −#endif | |
| 2099 | 2105 | default: |
| 2100 | 2106 | pipes[pipe_cnt].pipe.dest.odm_combine = dm_odm_combine_mode_disabled; |
| 2101 | 2107 | } |
| @@ -2201,11 +2207,9 @@ int dcn20_populate_dml_pipes_from_context( · 99 unmodified lines | ||
| 2201 | 2207 | |
| 2202 | 2208 | /* todo: default max for now, until there is logic reflecting this in dc*/ |
| 2203 | 2209 | pipes[pipe_cnt].dout.output_bpc = 12; |
| 2204 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 2205 | 2210 | /*fill up the audio sample rate (unit in kHz)*/ |
| 2206 | 2211 | get_audio_check(&res_ctx->pipe_ctx[i].stream->audio_info, &aud_check); |
| 2207 | 2212 | pipes[pipe_cnt].dout.max_audio_sample_rate = aud_check.max_audiosample_rate / 1000; |
| 2208 | −#endif | |
| 2209 | 2213 | /* |
| 2210 | 2214 | * For graphic plane, cursor number is 1, nv12 is 0 |
| 2211 | 2215 | * bw calculations due to cursor on/off |
| @@ -2252,13 +2256,10 @@ int dcn20_populate_dml_pipes_from_context( · 40 unmodified lines | ||
| 2252 | 2256 | if (pipes[pipe_cnt].pipe.dest.odm_combine == dm_odm_combine_mode_2to1) { |
| 2253 | 2257 | pipes[pipe_cnt].pipe.src.viewport_width /= 2; |
| 2254 | 2258 | pipes[pipe_cnt].pipe.dest.recout_width /= 2; |
| 2255 | − } | |
| 2256 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 2257 | − else if (pipes[pipe_cnt].pipe.dest.odm_combine == dm_odm_combine_mode_4to1) { | |
| 2259 | + } else if (pipes[pipe_cnt].pipe.dest.odm_combine == dm_odm_combine_mode_4to1) { | |
| 2258 | 2260 | pipes[pipe_cnt].pipe.src.viewport_width /= 4; |
| 2259 | 2261 | pipes[pipe_cnt].pipe.dest.recout_width /= 4; |
| 2260 | 2262 | } |
| 2261 | −#endif | |
| 2262 | 2263 | } else { |
| 2263 | 2264 | struct dc_plane_state *pln = res_ctx->pipe_ctx[i].plane_state; |
| 2264 | 2265 | struct scaler_data *scl = &res_ctx->pipe_ctx[i].plane_res.scl_data; |
| @@ -2287,12 +2288,8 @@ int dcn20_populate_dml_pipes_from_context( · 22 unmodified lines | ||
| 2287 | 2288 | pipes[pipe_cnt].pipe.src.surface_height_y = pln->plane_size.surface_size.height; |
| 2288 | 2289 | pipes[pipe_cnt].pipe.src.surface_width_c = pln->plane_size.chroma_size.width; |
| 2289 | 2290 | pipes[pipe_cnt].pipe.src.surface_height_c = pln->plane_size.chroma_size.height; |
| 2290 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 2291 | 2291 | if (pln->format == SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA |
| 2292 | 2292 | || pln->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) { |
| 2293 | −#else | |
| 2294 | − if (pln->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) { | |
| 2295 | −#endif | |
| 2296 | 2293 | pipes[pipe_cnt].pipe.src.data_pitch = pln->plane_size.surface_pitch; |
| 2297 | 2294 | pipes[pipe_cnt].pipe.src.data_pitch_c = pln->plane_size.chroma_pitch; |
| 2298 | 2295 | pipes[pipe_cnt].pipe.src.meta_pitch = pln->dcc.meta_pitch; |
| @@ -2308,10 +2305,8 @@ int dcn20_populate_dml_pipes_from_context( · 9 unmodified lines | ||
| 2308 | 2305 | pipes[pipe_cnt].pipe.dest.full_recout_width = scl->recout.width; |
| 2309 | 2306 | if (pipes[pipe_cnt].pipe.dest.odm_combine == dm_odm_combine_mode_2to1) |
| 2310 | 2307 | pipes[pipe_cnt].pipe.dest.full_recout_width *= 2; |
| 2311 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 2312 | 2308 | else if (pipes[pipe_cnt].pipe.dest.odm_combine == dm_odm_combine_mode_4to1) |
| 2313 | 2309 | pipes[pipe_cnt].pipe.dest.full_recout_width *= 4; |
| 2314 | −#endif | |
| 2315 | 2310 | else { |
| 2316 | 2311 | struct pipe_ctx *split_pipe = res_ctx->pipe_ctx[i].bottom_pipe; |
| 2317 | 2312 | |
| @@ -2368,11 +2363,9 @@ int dcn20_populate_dml_pipes_from_context( · 50 unmodified lines | ||
| 2368 | 2363 | case SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS: |
| 2369 | 2364 | pipes[pipe_cnt].pipe.src.source_format = dm_444_8; |
| 2370 | 2365 | break; |
| 2371 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 2372 | 2366 | case SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA: |
| 2373 | 2367 | pipes[pipe_cnt].pipe.src.source_format = dm_rgbe_alpha; |
| 2374 | 2368 | break; |
| 2375 | −#endif | |
| 2376 | 2369 | default: |
| 2377 | 2370 | pipes[pipe_cnt].pipe.src.source_format = dm_444_32; |
| 2378 | 2371 | break; |
| @@ -2582,7 +2575,7 @@ struct pipe_ctx *dcn20_find_secondary_pipe(struct dc *dc, · 203 unmodified lines | ||
| 2582 | 2575 | return secondary_pipe; |
| 2583 | 2576 | } |
| 2584 | 2577 | |
| 2585 | −static void dcn20_merge_pipes_for_validate( | |
| 2578 | +void dcn20_merge_pipes_for_validate( | |
| 2586 | 2579 | struct dc *dc, |
| 2587 | 2580 | struct dc_state *context) |
| 2588 | 2581 | { |
| @@ -2749,7 +2742,6 @@ int dcn20_validate_apply_pipe_split_flags( · 160 unmodified lines | ||
| 2749 | 2742 | split[i] = 2; |
| 2750 | 2743 | v->ODMCombineEnablePerState[vlevel][pipe_plane] = dm_odm_combine_mode_2to1; |
| 2751 | 2744 | } |
| 2752 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 2753 | 2745 | if (dc->debug.force_odm_combine_4to1 & (1 << pipe->stream_res.tg->inst)) { |
| 2754 | 2746 | split[i] = 4; |
| 2755 | 2747 | v->ODMCombineEnablePerState[vlevel][pipe_plane] = dm_odm_combine_mode_4to1; |
| @@ -2759,7 +2751,6 @@ int dcn20_validate_apply_pipe_split_flags( · 3 unmodified lines | ||
| 2759 | 2751 | pipe->stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420) { |
| 2760 | 2752 | split[i] = 4; |
| 2761 | 2753 | } |
| 2762 | −#endif | |
| 2763 | 2754 | v->ODMCombineEnabled[pipe_plane] = |
| 2764 | 2755 | v->ODMCombineEnablePerState[vlevel][pipe_plane]; |
| 2765 | 2756 | |
| @@ -3801,7 +3792,9 @@ static bool dcn20_resource_construct( · 1035 unmodified lines | ||
| 3801 | 3792 | |
| 3802 | 3793 | dc->caps.max_downscale_ratio = 200; |
| 3803 | 3794 | dc->caps.i2c_speed_in_khz = 100; |
| 3795 | + dc->caps.i2c_speed_in_khz_hdcp = 100; /*1.4 w/a not applied by default*/ | |
| 3804 | 3796 | dc->caps.max_cursor_size = 256; |
| 3797 | + dc->caps.min_horizontal_blanking_period = 80; | |
| 3805 | 3798 | dc->caps.dmdata_alloc_size = 2048; |
| 3806 | 3799 | |
| 3807 | 3800 | dc->caps.max_slave_planes = 1; |
| @@ -118,6 +118,9 @@ void dcn20_set_mcif_arb_params( · 117 unmodified lines | ||
| 118 | 118 | display_e2e_pipe_params_st *pipes, |
| 119 | 119 | int pipe_cnt); |
| 120 | 120 | bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context, bool fast_validate); |
| 121 | +void dcn20_merge_pipes_for_validate( | |
| 122 | + struct dc *dc, | |
| 123 | + struct dc_state *context); | |
| 121 | 124 | int dcn20_validate_apply_pipe_split_flags( |
| 122 | 125 | struct dc *dc, |
| 123 | 126 | struct dc_state *context, |
| @@ -223,3 +223,18 @@ bool dcn21_set_backlight_level(struct pipe_ctx *pipe_ctx, · 222 unmodified lines | ||
| 223 | 223 | return true; |
| 224 | 224 | } |
| 225 | 225 | |
| 226 | +bool dcn21_is_abm_supported(struct dc *dc, | |
| 227 | + struct dc_state *context, struct dc_stream_state *stream) | |
| 228 | +{ | |
| 229 | + int i; | |
| 230 | + | |
| 231 | + for (i = 0; i < dc->res_pool->pipe_count; i++) { | |
| 232 | + struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; | |
| 233 | + | |
| 234 | + if (pipe_ctx->stream == stream && | |
| 235 | + (pipe_ctx->prev_odm_pipe == NULL && pipe_ctx->next_odm_pipe == NULL)) | |
| 236 | + return true; | |
| 237 | + } | |
| 238 | + return false; | |
| 239 | +} | |
| 240 | + | |
| @@ -52,5 +52,7 @@ void dcn21_set_abm_immediate_disable(struct pipe_ctx *pipe_ctx); · 51 unmodified lines | ||
| 52 | 52 | bool dcn21_set_backlight_level(struct pipe_ctx *pipe_ctx, |
| 53 | 53 | uint32_t backlight_pwm_u16_16, |
| 54 | 54 | uint32_t frame_ramp); |
| 55 | +bool dcn21_is_abm_supported(struct dc *dc, | |
| 56 | + struct dc_state *context, struct dc_stream_state *stream); | |
| 55 | 57 | |
| 56 | 58 | #endif /* __DC_HWSS_DCN21_H__ */ |
| @@ -35,7 +35,6 @@ static const struct hw_sequencer_funcs dcn21_funcs = { · 34 unmodified lines | ||
| 35 | 35 | .apply_ctx_to_hw = dce110_apply_ctx_to_hw, |
| 36 | 36 | .apply_ctx_for_surface = NULL, |
| 37 | 37 | .program_front_end_for_ctx = dcn20_program_front_end_for_ctx, |
| 38 | − .disconnect_pipes = dcn10_disconnect_pipes, | |
| 39 | 38 | .wait_for_pending_cleared = dcn10_wait_for_pending_cleared, |
| 40 | 39 | .post_unlock_program_front_end = dcn20_post_unlock_program_front_end, |
| 41 | 40 | .update_plane_addr = dcn20_update_plane_addr, |
| @@ -98,6 +97,8 @@ static const struct hw_sequencer_funcs dcn21_funcs = { · 56 unmodified lines | ||
| 98 | 97 | #ifndef TRIM_FSFT |
| 99 | 98 | .optimize_timing_for_fsft = dcn20_optimize_timing_for_fsft, |
| 100 | 99 | #endif |
| 100 | + .is_abm_supported = dcn21_is_abm_supported, | |
| 101 | + .set_disp_pattern_generator = dcn20_set_disp_pattern_generator, | |
| 101 | 102 | }; |
| 102 | 103 | |
| 103 | 104 | static const struct hwseq_private_funcs dcn21_private_funcs = { |
| @@ -301,7 +301,9 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = { · 300 unmodified lines | ||
| 301 | 301 | .xfc_bus_transport_time_us = 4, |
| 302 | 302 | .xfc_xbuf_latency_tolerance_us = 4, |
| 303 | 303 | .use_urgent_burst_bw = 1, |
| 304 | − .num_states = 8 | |
| 304 | + .num_states = 8, | |
| 305 | + .allow_dram_self_refresh_or_dram_clock_change_in_vblank | |
| 306 | + = dm_allow_self_refresh_and_mclk_switch | |
| 305 | 307 | }; |
| 306 | 308 | |
| 307 | 309 | #ifndef MAX |
| @@ -1154,12 +1156,12 @@ void dcn21_calculate_wm( · 846 unmodified lines | ||
| 1154 | 1156 | &context->bw_ctx.dml, pipes, pipe_cnt); |
| 1155 | 1157 | /* WM Set C */ |
| 1156 | 1158 | table_entry = &bw_params->wm_table.entries[WM_C]; |
| 1157 | − vlevel = MIN(MAX(vlevel_req, 2), vlevel_max); | |
| 1159 | + vlevel = MIN(MAX(vlevel_req, 3), vlevel_max); | |
| 1158 | 1160 | calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.c, |
| 1159 | 1161 | &context->bw_ctx.dml, pipes, pipe_cnt); |
| 1160 | 1162 | /* WM Set B */ |
| 1161 | 1163 | table_entry = &bw_params->wm_table.entries[WM_B]; |
| 1162 | − vlevel = MIN(MAX(vlevel_req, 1), vlevel_max); | |
| 1164 | + vlevel = MIN(MAX(vlevel_req, 2), vlevel_max); | |
| 1163 | 1165 | calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.b, |
| 1164 | 1166 | &context->bw_ctx.dml, pipes, pipe_cnt); |
| 1165 | 1167 | |
| @@ -1171,6 +1173,138 @@ void dcn21_calculate_wm( · 5 unmodified lines | ||
| 1171 | 1173 | } |
| 1172 | 1174 | |
| 1173 | 1175 | |
| 1176 | +static bool dcn21_fast_validate_bw( | |
| 1177 | + struct dc *dc, | |
| 1178 | + struct dc_state *context, | |
| 1179 | + display_e2e_pipe_params_st *pipes, | |
| 1180 | + int *pipe_cnt_out, | |
| 1181 | + int *pipe_split_from, | |
| 1182 | + int *vlevel_out) | |
| 1183 | +{ | |
| 1184 | + bool out = false; | |
| 1185 | + int split[MAX_PIPES] = { 0 }; | |
| 1186 | + int pipe_cnt, i, pipe_idx, vlevel; | |
| 1187 | + | |
| 1188 | + ASSERT(pipes); | |
| 1189 | + if (!pipes) | |
| 1190 | + return false; | |
| 1191 | + | |
| 1192 | + dcn20_merge_pipes_for_validate(dc, context); | |
| 1193 | + | |
| 1194 | + pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc, context, pipes); | |
| 1195 | + | |
| 1196 | + *pipe_cnt_out = pipe_cnt; | |
| 1197 | + | |
| 1198 | + if (!pipe_cnt) { | |
| 1199 | + out = true; | |
| 1200 | + goto validate_out; | |
| 1201 | + } | |
| 1202 | + | |
| 1203 | + vlevel = dml_get_voltage_level(&context->bw_ctx.dml, pipes, pipe_cnt); | |
| 1204 | + | |
| 1205 | + if (vlevel > context->bw_ctx.dml.soc.num_states) | |
| 1206 | + goto validate_fail; | |
| 1207 | + | |
| 1208 | + vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, vlevel, split, NULL); | |
| 1209 | + | |
| 1210 | + for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) { | |
| 1211 | + struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; | |
| 1212 | + struct pipe_ctx *mpo_pipe = pipe->bottom_pipe; | |
| 1213 | + struct vba_vars_st *vba = &context->bw_ctx.dml.vba; | |
| 1214 | + | |
| 1215 | + if (!pipe->stream) | |
| 1216 | + continue; | |
| 1217 | + | |
| 1218 | + /* We only support full screen mpo with ODM */ | |
| 1219 | + if (vba->ODMCombineEnabled[vba->pipe_plane[pipe_idx]] != dm_odm_combine_mode_disabled | |
| 1220 | + && pipe->plane_state && mpo_pipe | |
| 1221 | + && memcmp(&mpo_pipe->plane_res.scl_data.recout, | |
| 1222 | + &pipe->plane_res.scl_data.recout, | |
| 1223 | + sizeof(struct rect)) != 0) { | |
| 1224 | + ASSERT(mpo_pipe->plane_state != pipe->plane_state); | |
| 1225 | + goto validate_fail; | |
| 1226 | + } | |
| 1227 | + pipe_idx++; | |
| 1228 | + } | |
| 1229 | + | |
| 1230 | + /*initialize pipe_just_split_from to invalid idx*/ | |
| 1231 | + for (i = 0; i < MAX_PIPES; i++) | |
| 1232 | + pipe_split_from[i] = -1; | |
| 1233 | + | |
| 1234 | + for (i = 0, pipe_idx = -1; i < dc->res_pool->pipe_count; i++) { | |
| 1235 | + struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; | |
| 1236 | + struct pipe_ctx *hsplit_pipe = pipe->bottom_pipe; | |
| 1237 | + | |
| 1238 | + if (!pipe->stream || pipe_split_from[i] >= 0) | |
| 1239 | + continue; | |
| 1240 | + | |
| 1241 | + pipe_idx++; | |
| 1242 | + | |
| 1243 | + if (!pipe->top_pipe && !pipe->plane_state && context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_idx]) { | |
| 1244 | + hsplit_pipe = dcn20_find_secondary_pipe(dc, &context->res_ctx, dc->res_pool, pipe); | |
| 1245 | + ASSERT(hsplit_pipe); | |
| 1246 | + if (!dcn20_split_stream_for_odm( | |
| 1247 | + dc, &context->res_ctx, | |
| 1248 | + pipe, hsplit_pipe)) | |
| 1249 | + goto validate_fail; | |
| 1250 | + pipe_split_from[hsplit_pipe->pipe_idx] = pipe_idx; | |
| 1251 | + dcn20_build_mapped_resource(dc, context, pipe->stream); | |
| 1252 | + } | |
| 1253 | + | |
| 1254 | + if (!pipe->plane_state) | |
| 1255 | + continue; | |
| 1256 | + /* Skip 2nd half of already split pipe */ | |
| 1257 | + if (pipe->top_pipe && pipe->plane_state == pipe->top_pipe->plane_state) | |
| 1258 | + continue; | |
| 1259 | + | |
| 1260 | + if (split[i] == 2) { | |
| 1261 | + if (!hsplit_pipe || hsplit_pipe->plane_state != pipe->plane_state) { | |
| 1262 | + /* pipe not split previously needs split */ | |
| 1263 | + hsplit_pipe = dcn20_find_secondary_pipe(dc, &context->res_ctx, dc->res_pool, pipe); | |
| 1264 | + ASSERT(hsplit_pipe); | |
| 1265 | + if (!hsplit_pipe) { | |
| 1266 | + context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx] *= 2; | |
| 1267 | + continue; | |
| 1268 | + } | |
| 1269 | + if (context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_idx]) { | |
| 1270 | + if (!dcn20_split_stream_for_odm( | |
| 1271 | + dc, &context->res_ctx, | |
| 1272 | + pipe, hsplit_pipe)) | |
| 1273 | + goto validate_fail; | |
| 1274 | + dcn20_build_mapped_resource(dc, context, pipe->stream); | |
| 1275 | + } else { | |
| 1276 | + dcn20_split_stream_for_mpc( | |
| 1277 | + &context->res_ctx, dc->res_pool, | |
| 1278 | + pipe, hsplit_pipe); | |
| 1279 | + resource_build_scaling_params(pipe); | |
| 1280 | + resource_build_scaling_params(hsplit_pipe); | |
| 1281 | + } | |
| 1282 | + pipe_split_from[hsplit_pipe->pipe_idx] = pipe_idx; | |
| 1283 | + } | |
| 1284 | + } else if (hsplit_pipe && hsplit_pipe->plane_state == pipe->plane_state) { | |
| 1285 | + /* merge should already have been done */ | |
| 1286 | + ASSERT(0); | |
| 1287 | + } | |
| 1288 | + } | |
| 1289 | + /* Actual dsc count per stream dsc validation*/ | |
| 1290 | + if (!dcn20_validate_dsc(dc, context)) { | |
| 1291 | + context->bw_ctx.dml.vba.ValidationStatus[context->bw_ctx.dml.vba.soc.num_states] = | |
| 1292 | + DML_FAIL_DSC_VALIDATION_FAILURE; | |
| 1293 | + goto validate_fail; | |
| 1294 | + } | |
| 1295 | + | |
| 1296 | + *vlevel_out = vlevel; | |
| 1297 | + | |
| 1298 | + out = true; | |
| 1299 | + goto validate_out; | |
| 1300 | + | |
| 1301 | +validate_fail: | |
| 1302 | + out = false; | |
| 1303 | + | |
| 1304 | +validate_out: | |
| 1305 | + return out; | |
| 1306 | +} | |
| 1307 | + | |
| 1174 | 1308 | bool dcn21_validate_bandwidth(struct dc *dc, struct dc_state *context, |
| 1175 | 1309 | bool fast_validate) |
| 1176 | 1310 | { |
| @@ -1189,7 +1323,7 @@ bool dcn21_validate_bandwidth(struct dc *dc, struct dc_state *context, · 12 unmodified lines | ||
| 1189 | 1323 | /*Unsafe due to current pipe merge and split logic*/ |
| 1190 | 1324 | ASSERT(context != dc->current_state); |
| 1191 | 1325 | |
| 1192 | − out = dcn20_fast_validate_bw(dc, context, pipes, &pipe_cnt, pipe_split_from, &vlevel); | |
| 1326 | + out = dcn21_fast_validate_bw(dc, context, pipes, &pipe_cnt, pipe_split_from, &vlevel); | |
| 1193 | 1327 | |
| 1194 | 1328 | if (pipe_cnt == 0) |
| 1195 | 1329 | goto validate_out; |
| @@ -1385,95 +1519,89 @@ struct display_stream_compressor *dcn21_dsc_create( · 189 unmodified lines | ||
| 1385 | 1519 | return &dsc->base; |
| 1386 | 1520 | } |
| 1387 | 1521 | |
| 1522 | +static struct _vcs_dpi_voltage_scaling_st construct_low_pstate_lvl(struct clk_limit_table *clk_table, unsigned int high_voltage_lvl) | |
| 1523 | +{ | |
| 1524 | + struct _vcs_dpi_voltage_scaling_st low_pstate_lvl; | |
| 1525 | + int i; | |
| 1526 | + | |
| 1527 | + low_pstate_lvl.state = 1; | |
| 1528 | + low_pstate_lvl.dcfclk_mhz = clk_table->entries[0].dcfclk_mhz; | |
| 1529 | + low_pstate_lvl.fabricclk_mhz = clk_table->entries[0].fclk_mhz; | |
| 1530 | + low_pstate_lvl.socclk_mhz = clk_table->entries[0].socclk_mhz; | |
| 1531 | + low_pstate_lvl.dram_speed_mts = clk_table->entries[0].memclk_mhz * 2; | |
| 1532 | + | |
| 1533 | + low_pstate_lvl.dispclk_mhz = dcn2_1_soc.clock_limits[high_voltage_lvl].dispclk_mhz; | |
| 1534 | + low_pstate_lvl.dppclk_mhz = dcn2_1_soc.clock_limits[high_voltage_lvl].dppclk_mhz; | |
| 1535 | + low_pstate_lvl.dram_bw_per_chan_gbps = dcn2_1_soc.clock_limits[high_voltage_lvl].dram_bw_per_chan_gbps; | |
| 1536 | + low_pstate_lvl.dscclk_mhz = dcn2_1_soc.clock_limits[high_voltage_lvl].dscclk_mhz; | |
| 1537 | + low_pstate_lvl.dtbclk_mhz = dcn2_1_soc.clock_limits[high_voltage_lvl].dtbclk_mhz; | |
| 1538 | + low_pstate_lvl.phyclk_d18_mhz = dcn2_1_soc.clock_limits[high_voltage_lvl].phyclk_d18_mhz; | |
| 1539 | + low_pstate_lvl.phyclk_mhz = dcn2_1_soc.clock_limits[high_voltage_lvl].phyclk_mhz; | |
| 1540 | + | |
| 1541 | + for (i = clk_table->num_entries; i > 1; i--) | |
| 1542 | + clk_table->entries[i] = clk_table->entries[i-1]; | |
| 1543 | + clk_table->entries[1] = clk_table->entries[0]; | |
| 1544 | + clk_table->num_entries++; | |
| 1545 | + | |
| 1546 | + return low_pstate_lvl; | |
| 1547 | +} | |
| 1548 | + | |
| 1388 | 1549 | static void update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params) |
| 1389 | 1550 | { |
| 1390 | 1551 | struct dcn21_resource_pool *pool = TO_DCN21_RES_POOL(dc->res_pool); |
| 1391 | 1552 | struct clk_limit_table *clk_table = &bw_params->clk_table; |
| 1392 | 1553 | struct _vcs_dpi_voltage_scaling_st clock_limits[DC__VOLTAGE_STATES]; |
| 1393 | − unsigned int i, closest_clk_lvl; | |
| 1554 | + unsigned int i, closest_clk_lvl = 0, k = 0; | |
| 1394 | 1555 | int j; |
| 1395 | 1556 | |
| 1396 | − // Default clock levels are used for diags, which may lead to overclocking. | |
| 1397 | − if (!IS_DIAG_DC(dc->ctx->dce_environment)) { | |
| 1398 | − dcn2_1_ip.max_num_otg = pool->base.res_cap->num_timing_generator; | |
| 1399 | − dcn2_1_ip.max_num_dpp = pool->base.pipe_count; | |
| 1400 | − dcn2_1_soc.num_chans = bw_params->num_channels; | |
| 1401 | − | |
| 1402 | − ASSERT(clk_table->num_entries); | |
| 1403 | − for (i = 0; i < clk_table->num_entries; i++) { | |
| 1404 | − /* loop backwards*/ | |
| 1405 | − for (closest_clk_lvl = 0, j = dcn2_1_soc.num_states - 1; j >= 0; j--) { | |
| 1406 | − if ((unsigned int) dcn2_1_soc.clock_limits[j].dcfclk_mhz <= clk_table->entries[i].dcfclk_mhz) { | |
| 1407 | − closest_clk_lvl = j; | |
| 1408 | − break; | |
| 1409 | − } | |
| 1557 | + dcn2_1_ip.max_num_otg = pool->base.res_cap->num_timing_generator; | |
| 1558 | + dcn2_1_ip.max_num_dpp = pool->base.pipe_count; | |
| 1559 | + dcn2_1_soc.num_chans = bw_params->num_channels; | |
| 1560 | + | |
| 1561 | + ASSERT(clk_table->num_entries); | |
| 1562 | + for (i = 0; i < clk_table->num_entries; i++) { | |
| 1563 | + /* loop backwards*/ | |
| 1564 | + for (closest_clk_lvl = 0, j = dcn2_1_soc.num_states - 1; j >= 0; j--) { | |
| 1565 | + if ((unsigned int) dcn2_1_soc.clock_limits[j].dcfclk_mhz <= clk_table->entries[i].dcfclk_mhz) { | |
| 1566 | + closest_clk_lvl = j; | |
| 1567 | + break; | |
| 1410 | 1568 | } |
| 1411 | − | |
| 1412 | − clock_limits[i].state = i; | |
| 1413 | − clock_limits[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz; | |
| 1414 | − clock_limits[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz; | |
| 1415 | − clock_limits[i].socclk_mhz = clk_table->entries[i].socclk_mhz; | |
| 1416 | − clock_limits[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2; | |
| 1417 | − | |
| 1418 | − clock_limits[i].dispclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dispclk_mhz; | |
| 1419 | − clock_limits[i].dppclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dppclk_mhz; | |
| 1420 | − clock_limits[i].dram_bw_per_chan_gbps = dcn2_1_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps; | |
| 1421 | − clock_limits[i].dscclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dscclk_mhz; | |
| 1422 | − clock_limits[i].dtbclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dtbclk_mhz; | |
| 1423 | − clock_limits[i].phyclk_d18_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz; | |
| 1424 | − clock_limits[i].phyclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_mhz; | |
| 1425 | − } | |
| 1426 | − for (i = 0; i < clk_table->num_entries; i++) | |
| 1427 | − dcn2_1_soc.clock_limits[i] = clock_limits[i]; | |
| 1428 | − if (clk_table->num_entries) { | |
| 1429 | − dcn2_1_soc.num_states = clk_table->num_entries; | |
| 1430 | − /* duplicate last level */ | |
| 1431 | − dcn2_1_soc.clock_limits[dcn2_1_soc.num_states] = dcn2_1_soc.clock_limits[dcn2_1_soc.num_states - 1]; | |
| 1432 | − dcn2_1_soc.clock_limits[dcn2_1_soc.num_states].state = dcn2_1_soc.num_states; | |
| 1433 | 1569 | } |
| 1570 | + | |
| 1571 | + /* clk_table[1] is reserved for min DF PState. skip here to fill in later. */ | |
| 1572 | + if (i == 1) | |
| 1573 | + k++; | |
| 1574 | + | |
| 1575 | + clock_limits[k].state = k; | |
| 1576 | + clock_limits[k].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz; | |
| 1577 | + clock_limits[k].fabricclk_mhz = clk_table->entries[i].fclk_mhz; | |
| 1578 | + clock_limits[k].socclk_mhz = clk_table->entries[i].socclk_mhz; | |
| 1579 | + clock_limits[k].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2; | |
| 1580 | + | |
| 1581 | + clock_limits[k].dispclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dispclk_mhz; | |
| 1582 | + clock_limits[k].dppclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dppclk_mhz; | |
| 1583 | + clock_limits[k].dram_bw_per_chan_gbps = dcn2_1_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps; | |
| 1584 | + clock_limits[k].dscclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dscclk_mhz; | |
| 1585 | + clock_limits[k].dtbclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dtbclk_mhz; | |
| 1586 | + clock_limits[k].phyclk_d18_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz; | |
| 1587 | + clock_limits[k].phyclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_mhz; | |
| 1588 | + | |
| 1589 | + k++; | |
| 1590 | + } | |
| 1591 | + for (i = 0; i < clk_table->num_entries + 1; i++) | |
| 1592 | + dcn2_1_soc.clock_limits[i] = clock_limits[i]; | |
| 1593 | + if (clk_table->num_entries) { | |
| 1594 | + dcn2_1_soc.num_states = clk_table->num_entries + 1; | |
| 1595 | + /* duplicate last level */ | |
| 1596 | + dcn2_1_soc.clock_limits[dcn2_1_soc.num_states] = dcn2_1_soc.clock_limits[dcn2_1_soc.num_states - 1]; | |
| 1597 | + dcn2_1_soc.clock_limits[dcn2_1_soc.num_states].state = dcn2_1_soc.num_states; | |
| 1598 | + /* fill in min DF PState */ | |
| 1599 | + dcn2_1_soc.clock_limits[1] = construct_low_pstate_lvl(clk_table, closest_clk_lvl); | |
| 1434 | 1600 | } |
| 1435 | 1601 | |
| 1436 | 1602 | dml_init_instance(&dc->dml, &dcn2_1_soc, &dcn2_1_ip, DML_PROJECT_DCN21); |
| 1437 | 1603 | } |
| 1438 | 1604 | |
| 1439 | −/* Temporary Place holder until we can get them from fuse */ | |
| 1440 | −static struct dpm_clocks dummy_clocks = { | |
| 1441 | − .DcfClocks = { | |
| 1442 | − {.Freq = 400, .Vol = 1}, | |
| 1443 | − {.Freq = 483, .Vol = 1}, | |
| 1444 | − {.Freq = 602, .Vol = 1}, | |
| 1445 | − {.Freq = 738, .Vol = 1} }, | |
| 1446 | − .SocClocks = { | |
| 1447 | − {.Freq = 300, .Vol = 1}, | |
| 1448 | − {.Freq = 400, .Vol = 1}, | |
| 1449 | − {.Freq = 400, .Vol = 1}, | |
| 1450 | − {.Freq = 400, .Vol = 1} }, | |
| 1451 | − .FClocks = { | |
| 1452 | − {.Freq = 400, .Vol = 1}, | |
| 1453 | − {.Freq = 800, .Vol = 1}, | |
| 1454 | − {.Freq = 1067, .Vol = 1}, | |
| 1455 | − {.Freq = 1600, .Vol = 1} }, | |
| 1456 | − .MemClocks = { | |
| 1457 | − {.Freq = 800, .Vol = 1}, | |
| 1458 | − {.Freq = 1600, .Vol = 1}, | |
| 1459 | − {.Freq = 1067, .Vol = 1}, | |
| 1460 | − {.Freq = 1600, .Vol = 1} }, | |
| 1461 | − | |
| 1462 | −}; | |
| 1463 | − | |
| 1464 | −static enum pp_smu_status dummy_set_wm_ranges(struct pp_smu *pp, | |
| 1465 | − struct pp_smu_wm_range_sets *ranges) | |
| 1466 | −{ | |
| 1467 | − return PP_SMU_RESULT_OK; | |
| 1468 | −} | |
| 1469 | − | |
| 1470 | −static enum pp_smu_status dummy_get_dpm_clock_table(struct pp_smu *pp, | |
| 1471 | − struct dpm_clocks *clock_table) | |
| 1472 | −{ | |
| 1473 | − *clock_table = dummy_clocks; | |
| 1474 | − return PP_SMU_RESULT_OK; | |
| 1475 | −} | |
| 1476 | − | |
| 1477 | 1605 | static struct pp_smu_funcs *dcn21_pp_smu_create(struct dc_context *ctx) |
| 1478 | 1606 | { |
| 1479 | 1607 | struct pp_smu_funcs *pp_smu = kzalloc(sizeof(*pp_smu), GFP_KERNEL); |
| @@ -1481,17 +1609,11 @@ static struct pp_smu_funcs *dcn21_pp_smu_create(struct dc_context *ctx) · 1 unmodified line | ||
| 1481 | 1609 | if (!pp_smu) |
| 1482 | 1610 | return pp_smu; |
| 1483 | 1611 | |
| 1484 | − if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment) || IS_DIAG_DC(ctx->dce_environment)) { | |
| 1485 | − pp_smu->ctx.ver = PP_SMU_VER_RN; | |
| 1486 | − pp_smu->rn_funcs.get_dpm_clock_table = dummy_get_dpm_clock_table; | |
| 1487 | − pp_smu->rn_funcs.set_wm_ranges = dummy_set_wm_ranges; | |
| 1488 | − } else { | |
| 1612 | + dm_pp_get_funcs(ctx, pp_smu); | |
| 1489 | 1613 | |
| 1490 | − dm_pp_get_funcs(ctx, pp_smu); | |
| 1614 | + if (pp_smu->ctx.ver != PP_SMU_VER_RN) | |
| 1615 | + pp_smu = memset(pp_smu, 0, sizeof(struct pp_smu_funcs)); | |
| 1491 | 1616 | |
| 1492 | − if (pp_smu->ctx.ver != PP_SMU_VER_RN) | |
| 1493 | − pp_smu = memset(pp_smu, 0, sizeof(struct pp_smu_funcs)); | |
| 1494 | − } | |
| 1495 | 1617 | |
| 1496 | 1618 | return pp_smu; |
| 1497 | 1619 | } |
| @@ -1808,7 +1930,9 @@ static bool dcn21_resource_construct( · 310 unmodified lines | ||
| 1808 | 1930 | |
| 1809 | 1931 | dc->caps.max_downscale_ratio = 200; |
| 1810 | 1932 | dc->caps.i2c_speed_in_khz = 100; |
| 1933 | + dc->caps.i2c_speed_in_khz_hdcp = 5; /*1.4 w/a applied by default*/ | |
| 1811 | 1934 | dc->caps.max_cursor_size = 256; |
| 1935 | + dc->caps.min_horizontal_blanking_period = 80; | |
| 1812 | 1936 | dc->caps.dmdata_alloc_size = 2048; |
| 1813 | 1937 | |
| 1814 | 1938 | dc->caps.max_slave_planes = 1; |
| @@ -52,6 +52,7 @@ IS_OLD_GCC = 1 · 51 unmodified lines | ||
| 52 | 52 | endif |
| 53 | 53 | endif |
| 54 | 54 | |
| 55 | +ifdef CONFIG_X86 | |
| 55 | 56 | ifdef IS_OLD_GCC |
| 56 | 57 | # Stack alignment mismatch, proceed with caution. |
| 57 | 58 | # GCC < 7.1 cannot compile code using `double` and -mpreferred-stack-boundary=3 |
| @@ -62,6 +63,7 @@ else · 4 unmodified lines | ||
| 62 | 63 | CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_resource.o += -msse2 |
| 63 | 64 | CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_optc.o += -msse2 |
| 64 | 65 | endif |
| 66 | +endif | |
| 65 | 67 | |
| 66 | 68 | AMD_DAL_DCN30 = $(addprefix $(AMDDALPATH)/dc/dcn30/,$(DCN30)) |
| 67 | 69 | |
| @@ -1358,16 +1358,9 @@ static struct dpp_funcs dcn30_dpp_funcs = { · 1357 unmodified lines | ||
| 1358 | 1358 | .dpp_program_degamma_pwl = NULL, |
| 1359 | 1359 | .dpp_program_cm_dealpha = dpp3_program_cm_dealpha, |
| 1360 | 1360 | .dpp_program_cm_bias = dpp3_program_cm_bias, |
| 1361 | −#if defined(CONFIG_DRM_AMD_DC_DCN3_0) | |
| 1362 | 1361 | .dpp_program_blnd_lut = dpp3_program_blnd_lut, |
| 1363 | 1362 | .dpp_program_shaper_lut = dpp3_program_shaper, |
| 1364 | 1363 | .dpp_program_3dlut = dpp3_program_3dlut, |
| 1365 | −#else | |
| 1366 | − .dpp_program_blnd_lut = NULL, | |
| 1367 | − .dpp_program_shaper_lut = NULL, | |
| 1368 | − .dpp_program_3dlut = NULL, | |
| 1369 | −#endif | |
| 1370 | − | |
| 1371 | 1364 | .dpp_program_bias_and_scale = NULL, |
| 1372 | 1365 | .dpp_cnv_set_alpha_keyer = dpp2_cnv_set_alpha_keyer, |
| 1373 | 1366 | .set_cursor_attributes = dpp3_set_cursor_attributes, |
| @@ -585,7 +585,7 @@ void dpp3_cm_set_gamut_remap( · 584 unmodified lines | ||
| 585 | 585 | const struct dpp_grph_csc_adjustment *adjust); |
| 586 | 586 | |
| 587 | 587 | void dpp3_set_pre_degam(struct dpp *dpp_base, |
| 588 | − uint32_t degamma_lut_selection); | |
| 588 | + enum dc_transfer_func_predefined tr); | |
| 589 | 589 | |
| 590 | 590 | void dpp3_set_cursor_attributes( |
| 591 | 591 | struct dpp *dpp_base, |
| @@ -384,6 +384,58 @@ void hubbub3_force_wm_propagate_to_pipes(struct hubbub *hubbub) · 383 unmodified lines | ||
| 384 | 384 | DCHUBBUB_ARB_VM_ROW_URGENCY_WATERMARK_A, prog_wm_value); |
| 385 | 385 | } |
| 386 | 386 | |
| 387 | +void hubbub3_force_pstate_change_control(struct hubbub *hubbub, | |
| 388 | + bool force, bool allow) | |
| 389 | +{ | |
| 390 | + struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); | |
| 391 | + | |
| 392 | + REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL, | |
| 393 | + DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, allow, | |
| 394 | + DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, force); | |
| 395 | +} | |
| 396 | + | |
| 397 | +/* Copy values from WM set A to all other sets */ | |
| 398 | +void hubbub3_init_watermarks(struct hubbub *hubbub) | |
| 399 | +{ | |
| 400 | + struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); | |
| 401 | + uint32_t reg; | |
| 402 | + | |
| 403 | + reg = REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A); | |
| 404 | + REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, reg); | |
| 405 | + REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, reg); | |
| 406 | + REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, reg); | |
| 407 | + | |
| 408 | + reg = REG_READ(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_A); | |
| 409 | + REG_WRITE(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_B, reg); | |
| 410 | + REG_WRITE(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_C, reg); | |
| 411 | + REG_WRITE(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_D, reg); | |
| 412 | + | |
| 413 | + reg = REG_READ(DCHUBBUB_ARB_FRAC_URG_BW_NOM_A); | |
| 414 | + REG_WRITE(DCHUBBUB_ARB_FRAC_URG_BW_NOM_B, reg); | |
| 415 | + REG_WRITE(DCHUBBUB_ARB_FRAC_URG_BW_NOM_C, reg); | |
| 416 | + REG_WRITE(DCHUBBUB_ARB_FRAC_URG_BW_NOM_D, reg); | |
| 417 | + | |
| 418 | + reg = REG_READ(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A); | |
| 419 | + REG_WRITE(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B, reg); | |
| 420 | + REG_WRITE(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C, reg); | |
| 421 | + REG_WRITE(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, reg); | |
| 422 | + | |
| 423 | + reg = REG_READ(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A); | |
| 424 | + REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, reg); | |
| 425 | + REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, reg); | |
| 426 | + REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, reg); | |
| 427 | + | |
| 428 | + reg = REG_READ(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A); | |
| 429 | + REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, reg); | |
| 430 | + REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, reg); | |
| 431 | + REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, reg); | |
| 432 | + | |
| 433 | + reg = REG_READ(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A); | |
| 434 | + REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, reg); | |
| 435 | + REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, reg); | |
| 436 | + REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, reg); | |
| 437 | +} | |
| 438 | + | |
| 387 | 439 | static const struct hubbub_funcs hubbub30_funcs = { |
| 388 | 440 | .update_dchub = hubbub2_update_dchub, |
| 389 | 441 | .init_dchub_sys_ctx = hubbub3_init_dchub_sys_ctx, |
| @@ -397,6 +449,8 @@ static const struct hubbub_funcs hubbub30_funcs = { · 7 unmodified lines | ||
| 397 | 449 | .allow_self_refresh_control = hubbub1_allow_self_refresh_control, |
| 398 | 450 | .is_allow_self_refresh_enabled = hubbub1_is_allow_self_refresh_enabled, |
| 399 | 451 | .force_wm_propagate_to_pipes = hubbub3_force_wm_propagate_to_pipes, |
| 452 | + .force_pstate_change_control = hubbub3_force_pstate_change_control, | |
| 453 | + .init_watermarks = hubbub3_init_watermarks, | |
| 400 | 454 | }; |
| 401 | 455 | |
| 402 | 456 | void hubbub3_construct(struct dcn20_hubbub *hubbub3, |
| @@ -116,4 +116,9 @@ bool hubbub3_program_watermarks( · 115 unmodified lines | ||
| 116 | 116 | unsigned int refclk_mhz, |
| 117 | 117 | bool safe_to_lower); |
| 118 | 118 | |
| 119 | +void hubbub3_force_pstate_change_control(struct hubbub *hubbub, | |
| 120 | + bool force, bool allow); | |
| 121 | + | |
| 122 | +void hubbub3_init_watermarks(struct hubbub *hubbub); | |
| 123 | + | |
| 119 | 124 | #endif |
| @@ -251,6 +251,9 @@ bool hubp3_construct( · 250 unmodified lines | ||
| 251 | 251 | const struct dcn_hubp2_shift *hubp_shift, |
| 252 | 252 | const struct dcn_hubp2_mask *hubp_mask); |
| 253 | 253 | |
| 254 | +void hubp3_set_vm_system_aperture_settings(struct hubp *hubp, | |
| 255 | + struct vm_system_aperture_param *apt); | |
| 256 | + | |
| 254 | 257 | bool hubp3_program_surface_flip_and_addr( |
| 255 | 258 | struct hubp *hubp, |
| 256 | 259 | const struct dc_plane_address *address, |
| @@ -462,6 +462,12 @@ void dcn30_init_hw(struct dc *dc) · 461 unmodified lines | ||
| 462 | 462 | hws->funcs.disable_vga(dc->hwseq); |
| 463 | 463 | } |
| 464 | 464 | |
| 465 | + // Set default OPTC memory power states | |
| 466 | + if (dc->debug.enable_mem_low_power.bits.optc) { | |
| 467 | + // Shutdown when unassigned and light sleep in VBLANK | |
| 468 | + REG_SET_2(ODM_MEM_PWR_CTRL3, 0, ODM_MEM_UNASSIGNED_PWR_MODE, 3, ODM_MEM_VBLANK_PWR_MODE, 1); | |
| 469 | + } | |
| 470 | + | |
| 465 | 471 | if (dc->ctx->dc_bios->fw_info_valid) { |
| 466 | 472 | res_pool->ref_clocks.xtalin_clock_inKhz = |
| 467 | 473 | dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency; |
| @@ -617,11 +623,18 @@ void dcn30_init_hw(struct dc *dc) · 149 unmodified lines | ||
| 617 | 623 | if (hws->funcs.enable_power_gating_plane) |
| 618 | 624 | hws->funcs.enable_power_gating_plane(dc->hwseq, true); |
| 619 | 625 | |
| 626 | + if (!dcb->funcs->is_accelerated_mode(dcb) && dc->res_pool->hubbub->funcs->init_watermarks) | |
| 627 | + dc->res_pool->hubbub->funcs->init_watermarks(dc->res_pool->hubbub); | |
| 628 | + | |
| 620 | 629 | if (dc->clk_mgr->funcs->notify_wm_ranges) |
| 621 | 630 | dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr); |
| 622 | 631 | |
| 623 | 632 | if (dc->clk_mgr->funcs->set_hard_max_memclk) |
| 624 | 633 | dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr); |
| 634 | + | |
| 635 | + if (dc->res_pool->hubbub->funcs->force_pstate_change_control) | |
| 636 | + dc->res_pool->hubbub->funcs->force_pstate_change_control( | |
| 637 | + dc->res_pool->hubbub, false, false); | |
| 625 | 638 | } |
| 626 | 639 | |
| 627 | 640 | void dcn30_set_avmute(struct pipe_ctx *pipe_ctx, bool enable) |
| @@ -689,6 +702,10 @@ void dcn30_program_dmdata_engine(struct pipe_ctx *pipe_ctx) · 61 unmodified lines | ||
| 689 | 702 | |
| 690 | 703 | bool dcn30_apply_idle_power_optimizations(struct dc *dc, bool enable) |
| 691 | 704 | { |
| 705 | + union dmub_rb_cmd cmd; | |
| 706 | + unsigned int surface_size, refresh_hz, denom; | |
| 707 | + uint32_t tmr_delay = 0, tmr_scale = 0; | |
| 708 | + | |
| 692 | 709 | if (!dc->ctx->dmub_srv) |
| 693 | 710 | return false; |
| 694 | 711 | |
| @@ -703,11 +720,110 @@ bool dcn30_apply_idle_power_optimizations(struct dc *dc, bool enable) · 8 unmodified lines | ||
| 703 | 720 | /* Fail eligibility on a visible stream */ |
| 704 | 721 | break; |
| 705 | 722 | } |
| 723 | + | |
| 724 | + if (dc->current_state->stream_count == 1 // single display only | |
| 725 | + && dc->current_state->stream_status[0].plane_count == 1 // single surface only | |
| 726 | + && dc->current_state->stream_status[0].plane_states[0]->address.page_table_base.quad_part == 0 // no VM | |
| 727 | + // Only 8 and 16 bit formats | |
| 728 | + && dc->current_state->stream_status[0].plane_states[0]->format <= SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F | |
| 729 | + && dc->current_state->stream_status[0].plane_states[0]->format >= SURFACE_PIXEL_FORMAT_GRPH_ARGB8888) { | |
| 730 | + surface_size = dc->current_state->stream_status[0].plane_states[0]->plane_size.surface_pitch * | |
| 731 | + dc->current_state->stream_status[0].plane_states[0]->plane_size.surface_size.height * | |
| 732 | + (dc->current_state->stream_status[0].plane_states[0]->format >= SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616 ? | |
| 733 | + 8 : 4); | |
| 734 | + } else { | |
| 735 | + // TODO: remove hard code size | |
| 736 | + surface_size = 128 * 1024 * 1024; | |
| 737 | + } | |
| 738 | + | |
| 739 | + // TODO: remove hard code size | |
| 740 | + if (surface_size < 128 * 1024 * 1024) { | |
| 741 | + refresh_hz = div_u64((unsigned long long) dc->current_state->streams[0]->timing.pix_clk_100hz * | |
| 742 | + 100LL, | |
| 743 | + (dc->current_state->streams[0]->timing.v_total * | |
| 744 | + dc->current_state->streams[0]->timing.h_total)); | |
| 745 | + | |
| 746 | + /* | |
| 747 | + * Delay_Us = 65.28 * (64 + MallFrameCacheTmrDly) * 2^MallFrameCacheTmrScale | |
| 748 | + * Delay_Us / 65.28 = (64 + MallFrameCacheTmrDly) * 2^MallFrameCacheTmrScale | |
| 749 | + * (Delay_Us / 65.28) / 2^MallFrameCacheTmrScale = 64 + MallFrameCacheTmrDly | |
| 750 | + * MallFrameCacheTmrDly = ((Delay_Us / 65.28) / 2^MallFrameCacheTmrScale) - 64 | |
| 751 | + * = (1000000 / refresh) / 65.28 / 2^MallFrameCacheTmrScale - 64 | |
| 752 | + * = 1000000 / (refresh * 65.28 * 2^MallFrameCacheTmrScale) - 64 | |
| 753 | + * = (1000000 * 100) / (refresh * 6528 * 2^MallFrameCacheTmrScale) - 64 | |
| 754 | + * | |
| 755 | + * need to round up the result of the division before the subtraction | |
| 756 | + */ | |
| 757 | + denom = refresh_hz * 6528; | |
| 758 | + tmr_delay = div_u64((100000000LL + denom - 1), denom) - 64LL; | |
| 759 | + | |
| 760 | + /* scale should be increased until it fits into 6 bits */ | |
| 761 | + while (tmr_delay & ~0x3F) { | |
| 762 | + tmr_scale++; | |
| 763 | + | |
| 764 | + if (tmr_scale > 3) { | |
| 765 | + /* The delay exceeds the range of the hystersis timer */ | |
| 766 | + ASSERT(false); | |
| 767 | + return false; | |
| 768 | + } | |
| 769 | + | |
| 770 | + denom *= 2; | |
| 771 | + tmr_delay = div_u64((100000000LL + denom - 1), denom) - 64LL; | |
| 772 | + } | |
| 773 | + | |
| 774 | + /* Enable MALL */ | |
| 775 | + memset(&cmd, 0, sizeof(cmd)); | |
| 776 | + cmd.mall.header.type = DMUB_CMD__MALL; | |
| 777 | + cmd.mall.header.sub_type = | |
| 778 | + DMUB_CMD__MALL_ACTION_ALLOW; | |
| 779 | + cmd.mall.header.payload_bytes = | |
| 780 | + sizeof(cmd.mall) - | |
| 781 | + sizeof(cmd.mall.header); | |
| 782 | + cmd.mall.tmr_delay = tmr_delay; | |
| 783 | + cmd.mall.tmr_scale = tmr_scale; | |
| 784 | + | |
| 785 | + dc_dmub_srv_cmd_queue(dc->ctx->dmub_srv, &cmd); | |
| 786 | + dc_dmub_srv_cmd_execute(dc->ctx->dmub_srv); | |
| 787 | + | |
| 788 | + return true; | |
| 789 | + } | |
| 706 | 790 | } |
| 707 | 791 | |
| 708 | 792 | /* No applicable optimizations */ |
| 709 | 793 | return false; |
| 710 | 794 | } |
| 711 | 795 | |
| 796 | + /* Disable MALL */ | |
| 797 | + memset(&cmd, 0, sizeof(cmd)); | |
| 798 | + cmd.mall.header.type = DMUB_CMD__MALL; | |
| 799 | + cmd.mall.header.sub_type = DMUB_CMD__MALL_ACTION_DISALLOW; | |
| 800 | + cmd.mall.header.payload_bytes = | |
| 801 | + sizeof(cmd.mall) - sizeof(cmd.mall.header); | |
| 802 | + | |
| 803 | + dc_dmub_srv_cmd_queue(dc->ctx->dmub_srv, &cmd); | |
| 804 | + dc_dmub_srv_cmd_execute(dc->ctx->dmub_srv); | |
| 805 | + dc_dmub_srv_wait_idle(dc->ctx->dmub_srv); | |
| 806 | + | |
| 712 | 807 | return true; |
| 713 | 808 | } |
| 809 | + | |
| 810 | +void dcn30_hardware_release(struct dc *dc) | |
| 811 | +{ | |
| 812 | + /* if pstate unsupported, force it supported */ | |
| 813 | + if (!dc->clk_mgr->clks.p_state_change_support && | |
| 814 | + dc->res_pool->hubbub->funcs->force_pstate_change_control) | |
| 815 | + dc->res_pool->hubbub->funcs->force_pstate_change_control( | |
| 816 | + dc->res_pool->hubbub, true, true); | |
| 817 | +} | |
| 818 | + | |
| 819 | +void dcn30_set_disp_pattern_generator(const struct dc *dc, | |
| 820 | + struct pipe_ctx *pipe_ctx, | |
| 821 | + enum controller_dp_test_pattern test_pattern, | |
| 822 | + enum controller_dp_color_space color_space, | |
| 823 | + enum dc_color_depth color_depth, | |
| 824 | + const struct tg_color *solid_color, | |
| 825 | + int width, int height, int offset) | |
| 826 | +{ | |
| 827 | + pipe_ctx->stream_res.opp->funcs->opp_set_disp_pattern_generator(pipe_ctx->stream_res.opp, test_pattern, | |
| 828 | + color_space, color_depth, solid_color, width, height, 0); | |
| 829 | +} | |
| @@ -67,4 +67,14 @@ void dcn30_program_dmdata_engine(struct pipe_ctx *pipe_ctx); · 66 unmodified lines | ||
| 67 | 67 | |
| 68 | 68 | bool dcn30_apply_idle_power_optimizations(struct dc *dc, bool enable); |
| 69 | 69 | |
| 70 | +void dcn30_hardware_release(struct dc *dc); | |
| 71 | + | |
| 72 | +void dcn30_set_disp_pattern_generator(const struct dc *dc, | |
| 73 | + struct pipe_ctx *pipe_ctx, | |
| 74 | + enum controller_dp_test_pattern test_pattern, | |
| 75 | + enum controller_dp_color_space color_space, | |
| 76 | + enum dc_color_depth color_depth, | |
| 77 | + const struct tg_color *solid_color, | |
| 78 | + int width, int height, int offset); | |
| 79 | + | |
| 70 | 80 | #endif /* __DC_HWSS_DCN30_H__ */ |
| @@ -35,7 +35,6 @@ static const struct hw_sequencer_funcs dcn30_funcs = { · 34 unmodified lines | ||
| 35 | 35 | .apply_ctx_to_hw = dce110_apply_ctx_to_hw, |
| 36 | 36 | .apply_ctx_for_surface = NULL, |
| 37 | 37 | .program_front_end_for_ctx = dcn20_program_front_end_for_ctx, |
| 38 | − .disconnect_pipes = dcn10_disconnect_pipes, | |
| 39 | 38 | .wait_for_pending_cleared = dcn10_wait_for_pending_cleared, |
| 40 | 39 | .post_unlock_program_front_end = dcn20_post_unlock_program_front_end, |
| 41 | 40 | .update_plane_addr = dcn20_update_plane_addr, |
| @@ -90,9 +89,13 @@ static const struct hw_sequencer_funcs dcn30_funcs = { · 48 unmodified lines | ||
| 90 | 89 | .init_vm_ctx = dcn20_init_vm_ctx, |
| 91 | 90 | .set_flip_control_gsl = dcn20_set_flip_control_gsl, |
| 92 | 91 | .get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync, |
| 92 | + .calc_vupdate_position = dcn10_calc_vupdate_position, | |
| 93 | 93 | .apply_idle_power_optimizations = dcn30_apply_idle_power_optimizations, |
| 94 | 94 | .set_backlight_level = dcn21_set_backlight_level, |
| 95 | 95 | .set_abm_immediate_disable = dcn21_set_abm_immediate_disable, |
| 96 | + .hardware_release = dcn30_hardware_release, | |
| 97 | + .set_pipe = dcn21_set_pipe, | |
| 98 | + .set_disp_pattern_generator = dcn30_set_disp_pattern_generator, | |
| 96 | 99 | }; |
| 97 | 100 | |
| 98 | 101 | static const struct hwseq_private_funcs dcn30_private_funcs = { |
| @@ -143,8 +143,16 @@ static void mpc3_power_on_ogam_lut( · 142 unmodified lines | ||
| 143 | 143 | { |
| 144 | 144 | struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); |
| 145 | 145 | |
| 146 | − REG_SET(MPCC_MEM_PWR_CTRL[mpcc_id], 0, | |
| 147 | − MPCC_OGAM_MEM_PWR_FORCE, power_on == true ? 0:1); | |
| 146 | + if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) { | |
| 147 | + // Force power on | |
| 148 | + REG_UPDATE(MPCC_MEM_PWR_CTRL[mpcc_id], MPCC_OGAM_MEM_PWR_DIS, power_on == true ? 1:0); | |
| 149 | + // Wait for confirmation when powering on | |
| 150 | + if (power_on) | |
| 151 | + REG_WAIT(MPCC_MEM_PWR_CTRL[mpcc_id], MPCC_OGAM_MEM_PWR_STATE, 0, 10, 10); | |
| 152 | + } else { | |
| 153 | + REG_SET(MPCC_MEM_PWR_CTRL[mpcc_id], 0, | |
| 154 | + MPCC_OGAM_MEM_PWR_FORCE, power_on == true ? 0 : 1); | |
| 155 | + } | |
| 148 | 156 | } |
| 149 | 157 | |
| 150 | 158 | static void mpc3_configure_ogam_lut( |
| @@ -360,6 +368,9 @@ void mpc3_set_output_gamma( · 209 unmodified lines | ||
| 360 | 368 | /*we need to program 2 fields here as apposed to 1*/ |
| 361 | 369 | REG_UPDATE(MPCC_OGAM_CONTROL[mpcc_id], |
| 362 | 370 | MPCC_OGAM_SELECT, next_mode == LUT_RAM_A ? 0:1); |
| 371 | + | |
| 372 | + if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) | |
| 373 | + mpc3_power_on_ogam_lut(mpc, mpcc_id, false); | |
| 363 | 374 | } |
| 364 | 375 | |
| 365 | 376 | void mpc3_set_denorm( |
| @@ -801,16 +812,28 @@ static void mpc3_power_on_shaper_3dlut( · 435 unmodified lines | ||
| 801 | 812 | uint32_t power_status_shaper = 2; |
| 802 | 813 | uint32_t power_status_3dlut = 2; |
| 803 | 814 | struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); |
| 815 | + int max_retries = 10; | |
| 804 | 816 | |
| 805 | 817 | if (rmu_idx == 0) { |
| 806 | 818 | REG_SET(MPC_RMU_MEM_PWR_CTRL, 0, |
| 807 | 819 | MPC_RMU0_MEM_PWR_DIS, power_on == true ? 1:0); |
| 820 | + /* wait for memory to fully power up */ | |
| 821 | + if (power_on && mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) { | |
| 822 | + REG_WAIT(MPC_RMU_MEM_PWR_CTRL, MPC_RMU0_SHAPER_MEM_PWR_STATE, 0, 1, max_retries); | |
| 823 | + REG_WAIT(MPC_RMU_MEM_PWR_CTRL, MPC_RMU0_3DLUT_MEM_PWR_STATE, 0, 1, max_retries); | |
| 824 | + } | |
| 825 | + | |
| 808 | 826 | /*read status is not mandatory, it is just for debugging*/ |
| 809 | 827 | REG_GET(MPC_RMU_MEM_PWR_CTRL, MPC_RMU0_SHAPER_MEM_PWR_STATE, &power_status_shaper); |
| 810 | 828 | REG_GET(MPC_RMU_MEM_PWR_CTRL, MPC_RMU0_3DLUT_MEM_PWR_STATE, &power_status_3dlut); |
| 811 | 829 | } else if (rmu_idx == 1) { |
| 812 | 830 | REG_SET(MPC_RMU_MEM_PWR_CTRL, 0, |
| 813 | 831 | MPC_RMU1_MEM_PWR_DIS, power_on == true ? 1:0); |
| 832 | + if (power_on && mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) { | |
| 833 | + REG_WAIT(MPC_RMU_MEM_PWR_CTRL, MPC_RMU1_SHAPER_MEM_PWR_STATE, 0, 1, max_retries); | |
| 834 | + REG_WAIT(MPC_RMU_MEM_PWR_CTRL, MPC_RMU1_3DLUT_MEM_PWR_STATE, 0, 1, max_retries); | |
| 835 | + } | |
| 836 | + | |
| 814 | 837 | REG_GET(MPC_RMU_MEM_PWR_CTRL, MPC_RMU1_SHAPER_MEM_PWR_STATE, &power_status_shaper); |
| 815 | 838 | REG_GET(MPC_RMU_MEM_PWR_CTRL, MPC_RMU1_3DLUT_MEM_PWR_STATE, &power_status_3dlut); |
| 816 | 839 | } |
| @@ -838,6 +861,10 @@ bool mpc3_program_shaper( · 21 unmodified lines | ||
| 838 | 861 | REG_SET(SHAPER_CONTROL[rmu_idx], 0, MPC_RMU_SHAPER_LUT_MODE, 0); |
| 839 | 862 | return false; |
| 840 | 863 | } |
| 864 | + | |
| 865 | + if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) | |
| 866 | + mpc3_power_on_shaper_3dlut(mpc, rmu_idx, true); | |
| 867 | + | |
| 841 | 868 | current_mode = mpc3_get_shaper_current(mpc, rmu_idx); |
| 842 | 869 | |
| 843 | 870 | if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_A) |
| @@ -1196,6 +1223,9 @@ bool mpc3_program_3dlut( · 352 unmodified lines | ||
| 1196 | 1223 | mpc3_set_3dlut_mode(mpc, mode, is_12bits_color_channel, |
| 1197 | 1224 | is_17x17x17, rmu_idx); |
| 1198 | 1225 | |
| 1226 | + if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) | |
| 1227 | + mpc3_power_on_shaper_3dlut(mpc, rmu_idx, false); | |
| 1228 | + | |
| 1199 | 1229 | return true; |
| 1200 | 1230 | } |
| 1201 | 1231 | |
| @@ -1349,11 +1379,31 @@ int mpcc3_release_rmu(struct mpc *mpc, int mpcc_id) · 147 unmodified lines | ||
| 1349 | 1379 | |
| 1350 | 1380 | } |
| 1351 | 1381 | |
| 1382 | +static void mpc3_mpc_init(struct mpc *mpc) | |
| 1383 | +{ | |
| 1384 | + struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); | |
| 1385 | + int mpcc_id; | |
| 1386 | + | |
| 1387 | + mpc1_mpc_init(mpc); | |
| 1388 | + | |
| 1389 | + if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) { | |
| 1390 | + if (mpc30->mpc_mask->MPC_RMU0_MEM_LOW_PWR_MODE && mpc30->mpc_mask->MPC_RMU1_MEM_LOW_PWR_MODE) { | |
| 1391 | + REG_UPDATE(MPC_RMU_MEM_PWR_CTRL, MPC_RMU0_MEM_LOW_PWR_MODE, 3); | |
| 1392 | + REG_UPDATE(MPC_RMU_MEM_PWR_CTRL, MPC_RMU1_MEM_LOW_PWR_MODE, 3); | |
| 1393 | + } | |
| 1394 | + | |
| 1395 | + if (mpc30->mpc_mask->MPCC_OGAM_MEM_LOW_PWR_MODE) { | |
| 1396 | + for (mpcc_id = 0; mpcc_id < mpc30->num_mpcc; mpcc_id++) | |
| 1397 | + REG_UPDATE(MPCC_MEM_PWR_CTRL[mpcc_id], MPCC_OGAM_MEM_LOW_PWR_MODE, 3); | |
| 1398 | + } | |
| 1399 | + } | |
| 1400 | +} | |
| 1401 | + | |
| 1352 | 1402 | const struct mpc_funcs dcn30_mpc_funcs = { |
| 1353 | 1403 | .read_mpcc_state = mpc1_read_mpcc_state, |
| 1354 | 1404 | .insert_plane = mpc1_insert_plane, |
| 1355 | 1405 | .remove_mpcc = mpc1_remove_mpcc, |
| 1356 | − .mpc_init = mpc1_mpc_init, | |
| 1406 | + .mpc_init = mpc3_mpc_init, | |
| 1357 | 1407 | .mpc_init_single_inst = mpc1_mpc_init_single_inst, |
| 1358 | 1408 | .update_blending = mpc2_update_blending, |
| 1359 | 1409 | .cursor_lock = mpc1_cursor_lock, |
| @@ -300,6 +300,7 @@ · 299 unmodified lines | ||
| 300 | 300 | SF(MPCC0_MPCC_STATUS, MPCC_DISABLED, mask_sh),\ |
| 301 | 301 | SF(MPCC0_MPCC_MEM_PWR_CTRL, MPCC_OGAM_MEM_PWR_FORCE, mask_sh),\ |
| 302 | 302 | SF(MPCC0_MPCC_MEM_PWR_CTRL, MPCC_OGAM_MEM_PWR_DIS, mask_sh),\ |
| 303 | + SF(MPCC0_MPCC_MEM_PWR_CTRL, MPCC_OGAM_MEM_PWR_STATE, mask_sh),\ | |
| 303 | 304 | SF(MPC_OUT0_DENORM_CONTROL, MPC_OUT_DENORM_MODE, mask_sh),\ |
| 304 | 305 | SF(MPC_OUT0_DENORM_CONTROL, MPC_OUT_DENORM_CLAMP_MAX_R_CR, mask_sh),\ |
| 305 | 306 | SF(MPC_OUT0_DENORM_CONTROL, MPC_OUT_DENORM_CLAMP_MIN_R_CR, mask_sh),\ |
| @@ -406,6 +407,8 @@ · 100 unmodified lines | ||
| 406 | 407 | SF(MPCC0_MPCC_STATUS, MPCC_DISABLED, mask_sh),\ |
| 407 | 408 | SF(MPCC0_MPCC_MEM_PWR_CTRL, MPCC_OGAM_MEM_PWR_FORCE, mask_sh),\ |
| 408 | 409 | SF(MPCC0_MPCC_MEM_PWR_CTRL, MPCC_OGAM_MEM_PWR_DIS, mask_sh),\ |
| 410 | + SF(MPCC0_MPCC_MEM_PWR_CTRL, MPCC_OGAM_MEM_LOW_PWR_MODE, mask_sh),\ | |
| 411 | + SF(MPCC0_MPCC_MEM_PWR_CTRL, MPCC_OGAM_MEM_PWR_STATE, mask_sh),\ | |
| 409 | 412 | SF(MPC_OUT0_DENORM_CONTROL, MPC_OUT_DENORM_MODE, mask_sh),\ |
| 410 | 413 | SF(MPC_OUT0_DENORM_CONTROL, MPC_OUT_DENORM_CLAMP_MAX_R_CR, mask_sh),\ |
| 411 | 414 | SF(MPC_OUT0_DENORM_CONTROL, MPC_OUT_DENORM_CLAMP_MIN_R_CR, mask_sh),\ |
| @@ -492,10 +495,12 @@ · 80 unmodified lines | ||
| 492 | 495 | SF(MPC_RMU_MEM_PWR_CTRL, MPC_RMU0_MEM_PWR_DIS, mask_sh),\ |
| 493 | 496 | SF(MPC_RMU_MEM_PWR_CTRL, MPC_RMU0_SHAPER_MEM_PWR_STATE, mask_sh),\ |
| 494 | 497 | SF(MPC_RMU_MEM_PWR_CTRL, MPC_RMU0_3DLUT_MEM_PWR_STATE, mask_sh),\ |
| 498 | + SF(MPC_RMU_MEM_PWR_CTRL, MPC_RMU0_MEM_LOW_PWR_MODE, mask_sh),\ | |
| 495 | 499 | SF(MPC_RMU_MEM_PWR_CTRL, MPC_RMU1_MEM_PWR_FORCE, mask_sh),\ |
| 496 | 500 | SF(MPC_RMU_MEM_PWR_CTRL, MPC_RMU1_MEM_PWR_DIS, mask_sh),\ |
| 497 | 501 | SF(MPC_RMU_MEM_PWR_CTRL, MPC_RMU1_SHAPER_MEM_PWR_STATE, mask_sh),\ |
| 498 | 502 | SF(MPC_RMU_MEM_PWR_CTRL, MPC_RMU1_3DLUT_MEM_PWR_STATE, mask_sh),\ |
| 503 | + SF(MPC_RMU_MEM_PWR_CTRL, MPC_RMU1_MEM_LOW_PWR_MODE, mask_sh),\ | |
| 499 | 504 | SF(MPC_RMU0_SHAPER_CONTROL, MPC_RMU_SHAPER_MODE_CURRENT, mask_sh),\ |
| 500 | 505 | SF(CUR_VUPDATE_LOCK_SET0, CUR_VUPDATE_LOCK_SET, mask_sh) |
| 501 | 506 | |
| @@ -519,10 +524,12 @@ · 17 unmodified lines | ||
| 519 | 524 | type MPC_RMU1_MUX_STATUS; \ |
| 520 | 525 | type MPC_RMU0_MEM_PWR_FORCE;\ |
| 521 | 526 | type MPC_RMU0_MEM_PWR_DIS;\ |
| 527 | + type MPC_RMU0_MEM_LOW_PWR_MODE;\ | |
| 522 | 528 | type MPC_RMU0_SHAPER_MEM_PWR_STATE;\ |
| 523 | 529 | type MPC_RMU0_3DLUT_MEM_PWR_STATE;\ |
| 524 | 530 | type MPC_RMU1_MEM_PWR_FORCE;\ |
| 525 | 531 | type MPC_RMU1_MEM_PWR_DIS;\ |
| 532 | + type MPC_RMU1_MEM_LOW_PWR_MODE;\ | |
| 526 | 533 | type MPC_RMU1_SHAPER_MEM_PWR_STATE;\ |
| 527 | 534 | type MPC_RMU1_3DLUT_MEM_PWR_STATE;\ |
| 528 | 535 | type MPCC_OGAM_RAMA_EXP_REGION_START_SLOPE_B; \ |
| @@ -541,6 +548,8 @@ · 12 unmodified lines | ||
| 541 | 548 | type MPCC_OGAM_LUT_CONFIG_MODE; \ |
| 542 | 549 | type MPCC_OGAM_LUT_STATUS; \ |
| 543 | 550 | type MPCC_OGAM_RAMA_START_BASE_CNTL_B;\ |
| 551 | + type MPCC_OGAM_MEM_LOW_PWR_MODE;\ | |
| 552 | + type MPCC_OGAM_MEM_PWR_STATE;\ | |
| 544 | 553 | type MPC_RMU_3DLUT_MODE; \ |
| 545 | 554 | type MPC_RMU_3DLUT_SIZE; \ |
| 546 | 555 | type MPC_RMU_3DLUT_MODE_CURRENT; \ |
| @@ -60,6 +60,7 @@ · 59 unmodified lines | ||
| 60 | 60 | #include "dml/display_mode_vba.h" |
| 61 | 61 | #include "dcn30/dcn30_dccg.h" |
| 62 | 62 | #include "dcn10/dcn10_resource.h" |
| 63 | +#include "dc_link_ddc.h" | |
| 63 | 64 | #include "dce/dce_panel_cntl.h" |
| 64 | 65 | |
| 65 | 66 | #include "dcn30/dcn30_dwb.h" |
| @@ -354,11 +355,11 @@ static const struct dce_abm_registers abm_regs[] = { · 288 unmodified lines | ||
| 354 | 355 | }; |
| 355 | 356 | |
| 356 | 357 | static const struct dce_abm_shift abm_shift = { |
| 357 | − ABM_MASK_SH_LIST_DCN301(__SHIFT) | |
| 358 | + ABM_MASK_SH_LIST_DCN30(__SHIFT) | |
| 358 | 359 | }; |
| 359 | 360 | |
| 360 | 361 | static const struct dce_abm_mask abm_mask = { |
| 361 | − ABM_MASK_SH_LIST_DCN301(_MASK) | |
| 362 | + ABM_MASK_SH_LIST_DCN30(_MASK) | |
| 362 | 363 | }; |
| 363 | 364 | |
| 364 | 365 | |
| @@ -1321,6 +1322,9 @@ static void dcn30_resource_destruct(struct dcn30_resource_pool *pool) · 956 unmodified lines | ||
| 1321 | 1322 | |
| 1322 | 1323 | if (pool->base.dccg != NULL) |
| 1323 | 1324 | dcn_dccg_destroy(&pool->base.dccg); |
| 1325 | + | |
| 1326 | + if (pool->base.oem_device != NULL) | |
| 1327 | + dal_ddc_service_destroy(&pool->base.oem_device); | |
| 1324 | 1328 | } |
| 1325 | 1329 | |
| 1326 | 1330 | static struct hubp *dcn30_hubp_create( |
| @@ -1465,7 +1469,19 @@ int dcn30_populate_dml_pipes_from_context( · 138 unmodified lines | ||
| 1465 | 1469 | return pipe_cnt; |
| 1466 | 1470 | } |
| 1467 | 1471 | |
| 1468 | −void dcn30_populate_dml_writeback_from_context( | |
| 1472 | +/* | |
| 1473 | + * This must be noinline to ensure anything that deals with FP registers | |
| 1474 | + * is contained within this call; previously our compiling with hard-float | |
| 1475 | + * would result in fp instructions being emitted outside of the boundaries | |
| 1476 | + * of the DC_FP_START/END macros, which makes sense as the compiler has no | |
| 1477 | + * idea about what is wrapped and what is not | |
| 1478 | + * | |
| 1479 | + * This is largely just a workaround to avoid breakage introduced with 5.6, | |
| 1480 | + * ideally all fp-using code should be moved into its own file, only that | |
| 1481 | + * should be compiled with hard-float, and all code exported from there | |
| 1482 | + * should be strictly wrapped with DC_FP_START/END | |
| 1483 | + */ | |
| 1484 | +static noinline void dcn30_populate_dml_writeback_from_context_fp( | |
| 1469 | 1485 | struct dc *dc, struct resource_context *res_ctx, display_e2e_pipe_params_st *pipes) |
| 1470 | 1486 | { |
| 1471 | 1487 | int pipe_cnt, i, j; |
| @@ -1554,6 +1570,14 @@ void dcn30_populate_dml_writeback_from_context( · 82 unmodified lines | ||
| 1554 | 1570 | |
| 1555 | 1571 | } |
| 1556 | 1572 | |
| 1573 | +void dcn30_populate_dml_writeback_from_context( | |
| 1574 | + struct dc *dc, struct resource_context *res_ctx, display_e2e_pipe_params_st *pipes) | |
| 1575 | +{ | |
| 1576 | + DC_FP_START(); | |
| 1577 | + dcn30_populate_dml_writeback_from_context_fp(dc, res_ctx, pipes); | |
| 1578 | + DC_FP_END(); | |
| 1579 | +} | |
| 1580 | + | |
| 1557 | 1581 | unsigned int dcn30_calc_max_scaled_time( |
| 1558 | 1582 | unsigned int time_per_pixel, |
| 1559 | 1583 | enum mmhubbub_wbif_mode mode, |
| @@ -1873,11 +1897,22 @@ static bool dcn30_split_stream_for_mpc_or_odm( · 313 unmodified lines | ||
| 1873 | 1897 | sec_pipe->next_odm_pipe = pri_pipe->next_odm_pipe; |
| 1874 | 1898 | sec_pipe->next_odm_pipe->prev_odm_pipe = sec_pipe; |
| 1875 | 1899 | } |
| 1900 | + if (pri_pipe->top_pipe && pri_pipe->top_pipe->next_odm_pipe) { | |
| 1901 | + pri_pipe->top_pipe->next_odm_pipe->bottom_pipe = sec_pipe; | |
| 1902 | + sec_pipe->top_pipe = pri_pipe->top_pipe->next_odm_pipe; | |
| 1903 | + } | |
| 1904 | + if (pri_pipe->bottom_pipe && pri_pipe->bottom_pipe->next_odm_pipe) { | |
| 1905 | + pri_pipe->bottom_pipe->next_odm_pipe->top_pipe = sec_pipe; | |
| 1906 | + sec_pipe->bottom_pipe = pri_pipe->bottom_pipe->next_odm_pipe; | |
| 1907 | + } | |
| 1876 | 1908 | pri_pipe->next_odm_pipe = sec_pipe; |
| 1877 | 1909 | sec_pipe->prev_odm_pipe = pri_pipe; |
| 1878 | 1910 | ASSERT(sec_pipe->top_pipe == NULL); |
| 1879 | 1911 | |
| 1880 | − sec_pipe->stream_res.opp = pool->opps[pipe_idx]; | |
| 1912 | + if (!sec_pipe->top_pipe) | |
| 1913 | + sec_pipe->stream_res.opp = pool->opps[pipe_idx]; | |
| 1914 | + else | |
| 1915 | + sec_pipe->stream_res.opp = sec_pipe->top_pipe->stream_res.opp; | |
| 1881 | 1916 | if (sec_pipe->stream->timing.flags.DSC == 1) { |
| 1882 | 1917 | dcn20_acquire_dsc(dc, res_ctx, &sec_pipe->stream_res.dsc, pipe_idx); |
| 1883 | 1918 | ASSERT(sec_pipe->stream_res.dsc); |
| @@ -2005,20 +2040,6 @@ static bool dcn30_internal_validate_bw( · 121 unmodified lines | ||
| 2005 | 2040 | |
| 2006 | 2041 | dml_log_mode_support_params(&context->bw_ctx.dml); |
| 2007 | 2042 | |
| 2008 | − /* TODO: Need to check calculated vlevel why that fails validation of below resolutions */ | |
| 2009 | − if (context->res_ctx.pipe_ctx[0].stream != NULL) { | |
| 2010 | − if (context->res_ctx.pipe_ctx[0].stream->timing.h_addressable == 640 && context->res_ctx.pipe_ctx[0].stream->timing.v_addressable == 480) | |
| 2011 | − vlevel = 0; | |
| 2012 | − if (context->res_ctx.pipe_ctx[0].stream->timing.h_addressable == 1280 && context->res_ctx.pipe_ctx[0].stream->timing.v_addressable == 800) | |
| 2013 | − vlevel = 0; | |
| 2014 | − if (context->res_ctx.pipe_ctx[0].stream->timing.h_addressable == 1280 && context->res_ctx.pipe_ctx[0].stream->timing.v_addressable == 768) | |
| 2015 | − vlevel = 0; | |
| 2016 | − if (context->res_ctx.pipe_ctx[0].stream->timing.h_addressable == 1280 && context->res_ctx.pipe_ctx[0].stream->timing.v_addressable == 1024) | |
| 2017 | − vlevel = 0; | |
| 2018 | − if (context->res_ctx.pipe_ctx[0].stream->timing.h_addressable == 2048 && context->res_ctx.pipe_ctx[0].stream->timing.v_addressable == 1536) | |
| 2019 | − vlevel = 0; | |
| 2020 | − } | |
| 2021 | − | |
| 2022 | 2043 | if (vlevel == context->bw_ctx.dml.soc.num_states) |
| 2023 | 2044 | goto validate_fail; |
| 2024 | 2045 | |
| @@ -2203,7 +2224,19 @@ validate_out: · 178 unmodified lines | ||
| 2203 | 2224 | return out; |
| 2204 | 2225 | } |
| 2205 | 2226 | |
| 2206 | −void dcn30_calculate_wm_and_dlg( | |
| 2227 | +/* | |
| 2228 | + * This must be noinline to ensure anything that deals with FP registers | |
| 2229 | + * is contained within this call; previously our compiling with hard-float | |
| 2230 | + * would result in fp instructions being emitted outside of the boundaries | |
| 2231 | + * of the DC_FP_START/END macros, which makes sense as the compiler has no | |
| 2232 | + * idea about what is wrapped and what is not | |
| 2233 | + * | |
| 2234 | + * This is largely just a workaround to avoid breakage introduced with 5.6, | |
| 2235 | + * ideally all fp-using code should be moved into its own file, only that | |
| 2236 | + * should be compiled with hard-float, and all code exported from there | |
| 2237 | + * should be strictly wrapped with DC_FP_START/END | |
| 2238 | + */ | |
| 2239 | +static noinline void dcn30_calculate_wm_and_dlg_fp( | |
| 2207 | 2240 | struct dc *dc, struct dc_state *context, |
| 2208 | 2241 | display_e2e_pipe_params_st *pipes, |
| 2209 | 2242 | int pipe_cnt, |
| @@ -2249,7 +2282,7 @@ void dcn30_calculate_wm_and_dlg( · 39 unmodified lines | ||
| 2249 | 2282 | /* Set D: |
| 2250 | 2283 | * DCFCLK: Min Required |
| 2251 | 2284 | * FCLK(proportional to UCLK): 1GHz or Max |
| 2252 | − * sr_enter_exit = 4, sr_exit = 2us | |
| 2285 | + * MALL stutter, sr_enter_exit = 4, sr_exit = 2us | |
| 2253 | 2286 | */ |
| 2254 | 2287 | /* |
| 2255 | 2288 | if (dc->clk_mgr->bw_params->wm_table.nv_entries[WM_D].valid) { |
| @@ -2304,7 +2337,7 @@ void dcn30_calculate_wm_and_dlg( · 48 unmodified lines | ||
| 2304 | 2337 | * calculate DLG based on dummy p-state latency, and max out the set A p-state watermark |
| 2305 | 2338 | */ |
| 2306 | 2339 | context->bw_ctx.bw.dcn.watermarks.a = context->bw_ctx.bw.dcn.watermarks.c; |
| 2307 | − context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = 0x13FFFF; | |
| 2340 | + context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = 0; | |
| 2308 | 2341 | } else { |
| 2309 | 2342 | /* Set A: |
| 2310 | 2343 | * DCFCLK: Min Required |
| @@ -2359,7 +2392,18 @@ void dcn30_calculate_wm_and_dlg( · 48 unmodified lines | ||
| 2359 | 2392 | dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.pstate_latency_us; |
| 2360 | 2393 | } |
| 2361 | 2394 | |
| 2362 | −bool dcn30_validate_bandwidth(struct dc *dc, | |
| 2395 | +void dcn30_calculate_wm_and_dlg( | |
| 2396 | + struct dc *dc, struct dc_state *context, | |
| 2397 | + display_e2e_pipe_params_st *pipes, | |
| 2398 | + int pipe_cnt, | |
| 2399 | + int vlevel) | |
| 2400 | +{ | |
| 2401 | + DC_FP_START(); | |
| 2402 | + dcn30_calculate_wm_and_dlg_fp(dc, context, pipes, pipe_cnt, vlevel); | |
| 2403 | + DC_FP_END(); | |
| 2404 | +} | |
| 2405 | + | |
| 2406 | +static noinline bool dcn30_validate_bandwidth_fp(struct dc *dc, | |
| 2363 | 2407 | struct dc_state *context, |
| 2364 | 2408 | bool fast_validate) |
| 2365 | 2409 | { |
| @@ -2410,7 +2454,20 @@ validate_out: · 44 unmodified lines | ||
| 2410 | 2454 | return out; |
| 2411 | 2455 | } |
| 2412 | 2456 | |
| 2413 | −static void get_optimal_dcfclk_fclk_for_uclk(unsigned int uclk_mts, | |
| 2457 | +bool dcn30_validate_bandwidth(struct dc *dc, | |
| 2458 | + struct dc_state *context, | |
| 2459 | + bool fast_validate) | |
| 2460 | +{ | |
| 2461 | + bool out; | |
| 2462 | + | |
| 2463 | + DC_FP_START(); | |
| 2464 | + out = dcn30_validate_bandwidth_fp(dc, context, fast_validate); | |
| 2465 | + DC_FP_END(); | |
| 2466 | + | |
| 2467 | + return out; | |
| 2468 | +} | |
| 2469 | + | |
| 2470 | +static noinline void get_optimal_dcfclk_fclk_for_uclk(unsigned int uclk_mts, | |
| 2414 | 2471 | unsigned int *optimal_dcfclk, |
| 2415 | 2472 | unsigned int *optimal_fclk) |
| 2416 | 2473 | { |
| @@ -2477,8 +2534,10 @@ void dcn30_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params · 60 unmodified lines | ||
| 2477 | 2534 | |
| 2478 | 2535 | // Calculate optimal dcfclk for each uclk |
| 2479 | 2536 | for (i = 0; i < num_uclk_states; i++) { |
| 2537 | + DC_FP_START(); | |
| 2480 | 2538 | get_optimal_dcfclk_fclk_for_uclk(bw_params->clk_table.entries[i].memclk_mhz * 16, |
| 2481 | 2539 | &optimal_dcfclk_for_uclk[i], NULL); |
| 2540 | + DC_FP_END(); | |
| 2482 | 2541 | if (optimal_dcfclk_for_uclk[i] < bw_params->clk_table.entries[0].dcfclk_mhz) { |
| 2483 | 2542 | optimal_dcfclk_for_uclk[i] = bw_params->clk_table.entries[0].dcfclk_mhz; |
| 2484 | 2543 | } |
| @@ -2580,6 +2639,9 @@ static bool dcn30_resource_construct( · 95 unmodified lines | ||
| 2580 | 2639 | int i; |
| 2581 | 2640 | struct dc_context *ctx = dc->ctx; |
| 2582 | 2641 | struct irq_service_init_data init_data; |
| 2642 | + struct ddc_service_init_data ddc_init_data; | |
| 2643 | + | |
| 2644 | + DC_FP_START(); | |
| 2583 | 2645 | |
| 2584 | 2646 | ctx->dc_bios->regs = &bios_regs; |
| 2585 | 2647 | |
| @@ -2595,7 +2657,9 @@ static bool dcn30_resource_construct( · 9 unmodified lines | ||
| 2595 | 2657 | pool->base.mpcc_count = pool->base.res_cap->num_timing_generator; |
| 2596 | 2658 | dc->caps.max_downscale_ratio = 600; |
| 2597 | 2659 | dc->caps.i2c_speed_in_khz = 100; |
| 2660 | + dc->caps.i2c_speed_in_khz_hdcp = 100; /*1.4 w/a not applied by default*/ | |
| 2598 | 2661 | dc->caps.max_cursor_size = 256; |
| 2662 | + dc->caps.min_horizontal_blanking_period = 80; | |
| 2599 | 2663 | dc->caps.dmdata_alloc_size = 2048; |
| 2600 | 2664 | |
| 2601 | 2665 | dc->caps.max_slave_planes = 1; |
| @@ -2845,10 +2909,24 @@ static bool dcn30_resource_construct( · 243 unmodified lines | ||
| 2845 | 2909 | |
| 2846 | 2910 | dc->cap_funcs = cap_funcs; |
| 2847 | 2911 | |
| 2912 | + if (dc->ctx->dc_bios->fw_info.oem_i2c_present) { | |
| 2913 | + ddc_init_data.ctx = dc->ctx; | |
| 2914 | + ddc_init_data.link = NULL; | |
| 2915 | + ddc_init_data.id.id = dc->ctx->dc_bios->fw_info.oem_i2c_obj_id; | |
| 2916 | + ddc_init_data.id.enum_id = 0; | |
| 2917 | + ddc_init_data.id.type = OBJECT_TYPE_GENERIC; | |
| 2918 | + pool->base.oem_device = dal_ddc_service_create(&ddc_init_data); | |
| 2919 | + } else { | |
| 2920 | + pool->base.oem_device = NULL; | |
| 2921 | + } | |
| 2922 | + | |
| 2923 | + DC_FP_END(); | |
| 2924 | + | |
| 2848 | 2925 | return true; |
| 2849 | 2926 | |
| 2850 | 2927 | create_fail: |
| 2851 | 2928 | |
| 2929 | + DC_FP_END(); | |
| 2852 | 2930 | dcn30_resource_destruct(pool); |
| 2853 | 2931 | |
| 2854 | 2932 | return false; |
| @@ -0,0 +1,47 @@ | ||
| 1 | +# | |
| 2 | +# (c) Copyright 2020 Advanced Micro Devices, Inc. All the rights reserved | |
| 3 | +# | |
| 4 | +# All rights reserved. This notice is intended as a precaution against | |
| 5 | +# inadvertent publication and does not imply publication or any waiver | |
| 6 | +# of confidentiality. The year included in the foregoing notice is the | |
| 7 | +# year of creation of the work. | |
| 8 | +# | |
| 9 | +# Authors: AMD | |
| 10 | +# | |
| 11 | +# Makefile for dcn30. | |
| 12 | + | |
| 13 | +DCN301 = dcn301_init.o dcn301_resource.o dcn301_dccg.o \ | |
| 14 | + dcn301_dio_link_encoder.o dcn301_hwseq.o dcn301_panel_cntl.o dcn301_hubbub.o | |
| 15 | + | |
| 16 | +ifdef CONFIG_X86 | |
| 17 | +CFLAGS_$(AMDDALPATH)/dc/dcn301/dcn301_resource.o := -mhard-float -msse | |
| 18 | +endif | |
| 19 | + | |
| 20 | +ifdef CONFIG_PPC64 | |
| 21 | +CFLAGS_$(AMDDALPATH)/dc/dcn301/dcn301_resource.o := -mhard-float -maltivec | |
| 22 | +endif | |
| 23 | + | |
| 24 | +ifdef CONFIG_ARM64 | |
| 25 | +CFLAGS_REMOVE_$(AMDDALPATH)/dc/dcn301/dcn301_resource.o := -mgeneral-regs-only | |
| 26 | +endif | |
| 27 | + | |
| 28 | +ifdef CONFIG_CC_IS_GCC | |
| 29 | +ifeq ($(call cc-ifversion, -lt, 0701, y), y) | |
| 30 | +IS_OLD_GCC = 1 | |
| 31 | +endif | |
| 32 | +endif | |
| 33 | + | |
| 34 | +ifdef CONFIG_X86 | |
| 35 | +ifdef IS_OLD_GCC | |
| 36 | +# Stack alignment mismatch, proceed with caution. | |
| 37 | +# GCC < 7.1 cannot compile code using `double` and -mpreferred-stack-boundary=3 | |
| 38 | +# (8B stack alignment). | |
| 39 | +CFLAGS_$(AMDDALPATH)/dc/dcn301/dcn301_resource.o += -mpreferred-stack-boundary=4 | |
| 40 | +else | |
| 41 | +CFLAGS_$(AMDDALPATH)/dc/dcn301/dcn301_resource.o += -msse2 | |
| 42 | +endif | |
| 43 | +endif | |
| 44 | + | |
| 45 | +AMD_DAL_DCN301 = $(addprefix $(AMDDALPATH)/dc/dcn301/,$(DCN301)) | |
| 46 | + | |
| 47 | +AMD_DISPLAY_FILES += $(AMD_DAL_DCN301) | |
| @@ -0,0 +1,75 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2020 Advanced Micro Devices, Inc. | |
| 3 | + * | |
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a | |
| 5 | + * copy of this software and associated documentation files (the "Software"), | |
| 6 | + * to deal in the Software without restriction, including without limitation | |
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the | |
| 9 | + * Software is furnished to do so, subject to the following conditions: | |
| 10 | + * | |
| 11 | + * The above copyright notice and this permission notice shall be included in | |
| 12 | + * all copies or substantial portions of the Software. | |
| 13 | + * | |
62 more lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 193 lines aren’t shown here.
This diff is large: its 83 lines aren’t shown here.
This diff is large: its 82 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 146 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 219 lines aren’t shown here.
This diff is large: its 98 lines aren’t shown here.
This diff is large: its 2012 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 234 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 1564 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 77 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 80 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 117 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 94 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 345 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 134 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 77 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 306 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 181 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 13272 lines aren’t shown here.
This diff is large: its 53358 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 166 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 1254 lines aren’t shown here.
This diff is larger than a page shows: the files after these aren’t listed. Clone the repository to see all of it.